{"model_name":"gpt-5","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Heuristic rectangle growth with spatial hashing.\n// Compile with -O2 -std=gnu++20\n\nstruct Rect {\n    int a,b,c,d; // [a,c) x [b,d), integers, a<c, b<d\n    long long area() const { return 1LL*(c-a)*(d-b); }\n};\n\nstatic inline bool overlap_pos(const Rect& A, const Rect& B) {\n    // positive-area overlap\n    if (A.c <= B.a || B.c <= A.a) return false;\n    if (A.d <= B.b || B.d <= A.b) return false;\n    // edges touching only -> not counted as overlap; this function returns true only if positive overlap\n    return true;\n}\n\nstruct Hasher {\n    size_t operator()(const pair<int,int>& p) const noexcept {\n        return (size_t)p.first * 1000003u ^ (size_t)p.second;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n;\n    if (!(cin >> n)) return 0;\n    vector<int> x(n), y(n);\n    vector<long long> r(n);\n    for (int i=0;i<n;i++){\n        cin >> x[i] >> y[i] >> r[i];\n    }\n\n    // Initialize rectangles as 1x1 including (xi+0.5, yi+0.5): [xi,xi+1) x [yi,yi+1)\n    vector<Rect> rect(n);\n    for (int i=0;i<n;i++){\n        int xi = x[i], yi = y[i];\n        int a = xi, b = yi, c = xi+1, d = yi+1;\n        // Clamp just in case inputs are 0..9999 so +1 within 1..10000\n        a = max(0, min(9999, a));\n        b = max(0, min(9999, b));\n        c = min(10000, max(a+1, min(10000, c)));\n        d = min(10000, max(b+1, min(10000, d)));\n        rect[i] = {a,b,c,d};\n    }\n\n    // Spatial hash\n    const int G = 100; // coarse cell size\n    const int GRID = 10000 / G; // 100\n    vector<vector<int>> buckets(GRID*GRID);\n    auto cell_id = [&](int gx, int gy){ return gy*GRID + gx; };\n    auto gx_from_x = [&](int X){ return min(GRID-1, max(0, X / G)); };\n    auto gy_from_y = [&](int Y){ return min(GRID-1, max(0, Y / G)); };\n\n    auto add_rect = [&](int id){\n        auto &R = rect[id];\n        int gx0 = gx_from_x(R.a);\n        int gx1 = gx_from_x(max(0,R.c-1));\n        int gy0 = gy_from_y(R.b);\n        int gy1 = gy_from_y(max(0,R.d-1));\n        for (int gy=gy0; gy<=gy1; ++gy)\n            for (int gx=gx0; gx<=gx1; ++gx)\n                buckets[cell_id(gx,gy)].push_back(id);\n    };\n    auto remove_rect = [&](int id){\n        auto &R = rect[id];\n        int gx0 = gx_from_x(R.a);\n        int gx1 = gx_from_x(max(0,R.c-1));\n        int gy0 = gy_from_y(R.b);\n        int gy1 = gy_from_y(max(0,R.d-1));\n        for (int gy=gy0; gy<=gy1; ++gy)\n            for (int gx=gx0; gx<=gx1; ++gx) {\n                auto &v = buckets[cell_id(gx,gy)];\n                // remove id from v (v is small)\n                for (size_t k=0;k<v.size();++k){\n                    if (v[k]==id){ v[k]=v.back(); v.pop_back(); break; }\n                }\n            }\n    };\n\n    for (int i=0;i<n;i++) add_rect(i);\n\n    // Random engine with time seed\n    uint64_t seed = chrono::high_resolution_clock::now().time_since_epoch().count();\n    mt19937_64 rng(seed);\n\n    auto now = [&](){ return chrono::high_resolution_clock::now(); };\n    auto start_time = now();\n    const double TIME_LIMIT = 4.7; // seconds\n    auto elapsed_sec = [&](){\n        return chrono::duration<double>(now() - start_time).count();\n    };\n\n    vector<int> order(n);\n    iota(order.begin(), order.end(), 0);\n\n    // Helper: check if expanding rect i by one unit on side s is feasible (no overlap and within bounds)\n    // s: 0=left,1=right,2=down,3=up\n    auto can_expand = [&](int i, int s)->bool{\n        const Rect &R = rect[i];\n        if (s==0) { // left\n            if (R.a <= 0) return false;\n            Rect NR = R; NR.a = R.a - 1;\n            // band is [R.a-1,R.a) x [R.b,R.d)\n            int x0 = NR.a, x1 = R.a;\n            int y0 = R.b, y1 = R.d;\n            int gx0 = gx_from_x(x0);\n            int gx1 = gx_from_x(max(0,x1-1));\n            int gy0 = gy_from_y(y0);\n            int gy1 = gy_from_y(max(0,y1-1));\n            for (int gy=gy0; gy<=gy1; ++gy)\n                for (int gx=gx0; gx<=gx1; ++gx){\n                    for (int id : buckets[cell_id(gx,gy)]) {\n                        if (id==i) continue;\n                        if (overlap_pos(NR, rect[id])) return false;\n                    }\n                }\n            return true;\n        } else if (s==1) { // right\n            if (R.c >= 10000) return false;\n            Rect NR = R; NR.c = R.c + 1;\n            int x0 = R.c, x1 = NR.c;\n            int y0 = R.b, y1 = R.d;\n            int gx0 = gx_from_x(x0);\n            int gx1 = gx_from_x(max(0,x1-1));\n            int gy0 = gy_from_y(y0);\n            int gy1 = gy_from_y(max(0,y1-1));\n            for (int gy=gy0; gy<=gy1; ++gy)\n                for (int gx=gx0; gx<=gx1; ++gx){\n                    for (int id : buckets[cell_id(gx,gy)]) {\n                        if (id==i) continue;\n                        if (overlap_pos(NR, rect[id])) return false;\n                    }\n                }\n            return true;\n        } else if (s==2) { // down\n            if (R.b <= 0) return false;\n            Rect NR = R; NR.b = R.b - 1;\n            int x0 = R.a, x1 = R.c;\n            int y0 = NR.b, y1 = R.b;\n            int gx0 = gx_from_x(x0);\n            int gx1 = gx_from_x(max(0,x1-1));\n            int gy0 = gy_from_y(y0);\n            int gy1 = gy_from_y(max(0,y1-1));\n            for (int gy=gy0; gy<=gy1; ++gy)\n                for (int gx=gx0; gx<=gx1; ++gx){\n                    for (int id : buckets[cell_id(gx,gy)]) {\n                        if (id==i) continue;\n                        if (overlap_pos(NR, rect[id])) return false;\n                    }\n                }\n            return true;\n        } else { // up\n            if (R.d >= 10000) return false;\n            Rect NR = R; NR.d = R.d + 1;\n            int x0 = R.a, x1 = R.c;\n            int y0 = R.d, y1 = NR.d;\n            int gx0 = gx_from_x(x0);\n            int gx1 = gx_from_x(max(0,x1-1));\n            int gy0 = gy_from_y(y0);\n            int gy1 = gy_from_y(max(0,y1-1));\n            for (int gy=gy0; gy<=gy1; ++gy)\n                for (int gx=gx0; gx<=gx1; ++gx){\n                    for (int id : buckets[cell_id(gx,gy)]) {\n                        if (id==i) continue;\n                        if (overlap_pos(NR, rect[id])) return false;\n                    }\n                }\n            return true;\n        }\n    };\n\n    auto do_expand = [&](int i, int s){\n        remove_rect(i);\n        if (s==0) rect[i].a--;\n        else if (s==1) rect[i].c++;\n        else if (s==2) rect[i].b--;\n        else rect[i].d++;\n        add_rect(i);\n    };\n\n    // Main loop\n    // Prioritize deficit\n    vector<int> dirs = {0,1,2,3};\n    size_t stagnation = 0;\n    while (elapsed_sec() < TIME_LIMIT) {\n        // Sort by deficit descending\n        vector<pair<long long,int>> order_def;\n        order_def.reserve(n);\n        for (int i=0;i<n;i++){\n            long long si = rect[i].area();\n            long long deficit = r[i] - si;\n            // Prefer those under target; slight preference over extremely overshot\n            long long key = (deficit >= 0 ? deficit : deficit/4); // discourage overshot\n            order_def.emplace_back(key, i);\n        }\n        sort(order_def.begin(), order_def.end(), [&](auto& L, auto& R){\n            if (L.first != R.first) return L.first > R.first;\n            return L.second < R.second;\n        });\n\n        bool any = false;\n        for (auto &pr : order_def) {\n            if (elapsed_sec() >= TIME_LIMIT) break;\n            int i = pr.second;\n            long long si = rect[i].area();\n            long long ri = r[i];\n\n            // Over-expansion allowance factor based on time: early more, late less\n            double t = elapsed_sec() / TIME_LIMIT;\n            double over_factor = 1.2 - 0.5 * t; // from 1.2 down to 0.7\n            long long cap = (long long) llround(ri * over_factor);\n            if (cap < (long long)ri) cap = ri; // never below ri\n\n            // Try a few random directions with slight bias towards aspect balancing\n            array<int,4> tries;\n            // shuffle dirs\n            tries = {0,1,2,3};\n            shuffle(tries.begin(), tries.end(), rng);\n\n            // Aspect bias: if width << height and target wants larger area, prefer left/right\n            int w = rect[i].c - rect[i].a;\n            int h = rect[i].d - rect[i].b;\n\n            int best_dir = -1;\n            long double best_gain = -1e100;\n\n            for (int dtry : tries) {\n                if (!can_expand(i, dtry)) continue;\n                long long newS = si + (dtry<=1 ? h : w);\n                if (newS > cap) continue;\n                // Evaluate p_i gain\n                auto score = [&](long long s)->long double{\n                    long double mn = min<long double>(ri, s);\n                    long double mx = max<long double>(ri, s);\n                    long double ratio = mn / mx;\n                    long double val = 1.0L - (1.0L - ratio)*(1.0L - ratio);\n                    return val;\n                };\n                long double cur = score(si);\n                long double nxt = score(newS);\n                long double gain = nxt - cur;\n                // bias directions to balance aspect ratio (try to get closer to square)\n                int nw = w + ((dtry==0||dtry==1)?1:0);\n                int nh = h + ((dtry==2||dtry==3)?1:0);\n                long double aspect_pen = fabsl((long double)nw/nh - 1.0L);\n                gain -= 0.00001L * aspect_pen; // small penalty\n                if (gain > best_gain + 1e-18) {\n                    best_gain = gain;\n                    best_dir = dtry;\n                }\n            }\n            if (best_dir != -1 && best_gain > -1e-18) {\n                do_expand(i, best_dir);\n                any = true;\n            }\n        }\n        if (!any) {\n            stagnation++;\n            if (stagnation > 3) break;\n        } else stagnation = 0;\n    }\n\n    // Output rectangles\n    for (int i=0;i<n;i++){\n        cout << rect[i].a << ' ' << rect[i].b << ' ' << rect[i].c << ' ' << rect[i].d << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si, sj;\n    if(!(cin>>si>>sj)) return 0;\n    const int H=50, W=50;\n    vector<vector<int>> t(H, vector<int>(W));\n    for(int i=0;i<H;i++) for(int j=0;j<W;j++) cin>>t[i][j];\n    vector<vector<int>> p(H, vector<int>(W));\n    for(int i=0;i<H;i++) for(int j=0;j<W;j++) cin>>p[i][j];\n\n    int M = 0;\n    for(int i=0;i<H;i++) for(int j=0;j<W;j++) M = max(M, t[i][j]+1);\n    vector<vector<pair<int,int>>> tiles(M);\n    tiles.reserve(M);\n    for(int i=0;i<H;i++) for(int j=0;j<W;j++) tiles[t[i][j]].push_back({i,j});\n\n    vector<vector<char>> preferred(H, vector<char>(W, 0));\n    for(int id=0; id<M; id++){\n        auto &cells = tiles[id];\n        if(cells.empty()) continue;\n        int bestk = 0;\n        int bestv = -1;\n        for(int k=0;k<(int)cells.size();k++){\n            auto [i,j]=cells[k];\n            if(p[i][j] > bestv){\n                bestv = p[i][j];\n                bestk = k;\n            }\n        }\n        for(int k=0;k<(int)cells.size();k++){\n            auto [i,j]=cells[k];\n            preferred[i][j] = (k==bestk) ? 1 : 0;\n        }\n    }\n\n    // Serpentine index\n    vector<vector<int>> sidx(H, vector<int>(W, -1));\n    int idx=0;\n    for(int i=0;i<H;i++){\n        if(i%2==0){\n            for(int j=0;j<W;j++) sidx[i][j] = idx++;\n        }else{\n            for(int j=W-1;j>=0;j--) sidx[i][j] = idx++;\n        }\n    }\n    auto inb = [&](int i,int j)->bool{ return (0<=i && i<H && 0<=j && j<W);};\n\n    vector<char> ans;\n    ans.reserve(H*W);\n    vector<char> visited_tile(M, 0);\n    vector<vector<char>> visited_cell(H, vector<char>(W, 0));\n\n    int ci=si, cj=sj;\n    int startTile = t[ci][cj];\n    visited_tile[startTile] = 1;\n    visited_cell[ci][cj] = 1;\n\n    // Precompute degrees quickly function\n    auto tile_not_visited = [&](int i,int j)->bool{\n        return !visited_tile[t[i][j]];\n    };\n    auto local_deg = [&](int i,int j)->int{\n        static int di[4]={-1,1,0,0};\n        static int dj[4]={0,0,-1,1};\n        int d=0;\n        for(int k=0;k<4;k++){\n            int ni=i+di[k], nj=j+dj[k];\n            if(!inb(ni,nj)) continue;\n            if(!visited_tile[t[ni][nj]]) d++;\n        }\n        return d;\n    };\n\n    // Movement\n    static int di[4]={-1,1,0,0};\n    static int dj[4]={0,0,-1,1};\n    static char dc[4]={'U','D','L','R'};\n\n    // We will loop until stuck or a safety iteration limit\n    for(int step=0; step < H*W; step++){\n        // Collect candidate neighbors\n        struct Cand{\n            int k, ni, nj;\n            long long score;\n            int pval;\n            int deg;\n            bool is_pref;\n            int sdiff;\n        };\n        vector<Cand> cands;\n        cands.reserve(4);\n        for(int k=0;k<4;k++){\n            int ni=ci+di[k], nj=cj+dj[k];\n            if(!inb(ni,nj)) continue;\n            int tid = t[ni][nj];\n            if(visited_tile[tid]) continue; // cannot revisit any tile\n            int pval = p[ni][nj];\n            int deg = local_deg(ni,nj);\n            bool is_pref = preferred[ni][nj];\n            int diff = sidx[ni][nj] - sidx[ci][cj];\n            // Heuristic score\n            long long sc = 0;\n            // weights\n            const int w_p = 100;\n            const int w_pref = 30;\n            const int w_flow = 10;\n            const int w_deg = 3;\n            sc += 1LL*w_p * pval;\n            sc += 1LL*w_pref * (is_pref ? 1 : 0);\n            // flow bonus: prefer increasing serp idx by small positive numbers\n            int flow = 0;\n            if(diff >= 1 && diff <= 3) flow = 2;\n            else if(diff == 0) flow = -2;\n            else if(diff < 0 && diff >= -3) flow = 1;\n            else if(diff < -3) flow = -1;\n            sc += 1LL*w_flow * flow;\n            sc += 1LL*w_deg * deg;\n            cands.push_back({k,ni,nj,sc,pval,deg,is_pref,diff});\n        }\n        if(cands.empty()) break;\n\n        // Optional shallow lookahead: pick among top few by score, break ties by next move availability\n        // Sort by score desc, then is_pref, then deg, then pval\n        sort(cands.begin(), cands.end(), [&](const Cand& a, const Cand& b){\n            if(a.score != b.score) return a.score > b.score;\n            if(a.is_pref != b.is_pref) return a.is_pref > b.is_pref;\n            if(a.deg != b.deg) return a.deg > b.deg;\n            if(a.pval != b.pval) return a.pval > b.pval;\n            return a.sdiff > b.sdiff;\n        });\n\n        // Choose best\n        auto best = cands[0];\n        // Move\n        ans.push_back(dc[best.k]);\n        ci = best.ni; cj = best.nj;\n        int tid = t[ci][cj];\n        visited_tile[tid] = 1;\n        visited_cell[ci][cj] = 1;\n    }\n\n    // Output\n    string s(ans.begin(), ans.end());\n    cout<<s<<\"\\n\";\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastIO {\n    static void flush() { cout.flush(); }\n};\n\nstruct GridRouter {\n    static constexpr int HN = 30;\n    static constexpr int WN = 30;\n    static constexpr int HHE = HN * (WN - 1); // horizontal edges count 30*29=870\n    static constexpr int HVE = (HN - 1) * WN; // vertical edges count 29*30=870\n    static constexpr int E = HHE + HVE;       // 1740\n\n    // map edge ids\n    static int idH(int i, int j) { return i * (WN - 1) + j; }\n    static int idV(int i, int j) { return HHE + i * WN + j; }\n    static bool inb(int i, int j) { return 0 <= i && i < HN && 0 <= j && j < WN; }\n\n    vector<double> w; // edge weights\n    vector<pair<int,int>> adjIdx[HN][WN]; // (neighbor node index, edge id)\n    mt19937 rng;\n\n    GridRouter() : w(E, 5000.0) {\n        rng.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());\n        buildGraph();\n    }\n\n    int nodeId(int i, int j) const { return i * WN + j; }\n    pair<int,int> nodePos(int id) const { return {id / WN, id % WN}; }\n\n    void buildGraph() {\n        for (int i = 0; i < HN; ++i) for (int j = 0; j < WN; ++j) adjIdx[i][j].clear();\n        for (int i = 0; i < HN; ++i) {\n            for (int j = 0; j < WN - 1; ++j) {\n                int e = idH(i,j);\n                int u = nodeId(i,j), v = nodeId(i,j+1);\n                adjIdx[i][j].push_back({v, e});\n                adjIdx[i][j+1].push_back({u, e});\n            }\n        }\n        for (int i = 0; i < HN - 1; ++i) {\n            for (int j = 0; j < WN; ++j) {\n                int e = idV(i,j);\n                int u = nodeId(i,j), v = nodeId(i+1,j);\n                adjIdx[i][j].push_back({v, e});\n                adjIdx[i+1][j].push_back({u, e});\n            }\n        }\n    }\n\n    struct DRes {\n        vector<int> prevNode;\n        vector<int> prevEdge;\n        vector<int> pathEdges;\n        string pathMoves;\n        double pathCost;\n    };\n\n    // Dijkstra with optional per-query randomization factor on edges to encourage exploration\n    DRes shortestPath(pair<int,int> s, pair<int,int> t, double randEps, uint64_t randSeed) {\n        int N = HN * WN;\n        vector<double> dist(N, numeric_limits<double>::infinity());\n        vector<int> prevN(N, -1), prevE(N, -1);\n        int sId = nodeId(s.first, s.second);\n        int tId = nodeId(t.first, t.second);\n\n        // prepare random multipliers if needed\n        vector<float> mult;\n        if (randEps > 0) {\n            mult.assign(E, 1.0f);\n            // Use a simple hash PRNG based on seed for determinism per query\n            uint64_t x = randSeed ? randSeed : rng();\n            auto nextRand = [&]() {\n                x ^= x << 13; x ^= x >> 7; x ^= x << 17;\n                return x;\n            };\n            for (int e = 0; e < E; ++e) {\n                // uniform in [-1,1]\n                uint64_t r = nextRand();\n                double u = ((r >> 11) & 0xFFFFFFFFull) / double(0xFFFFFFFFull);\n                double z = 2.0*u - 1.0;\n                mult[e] = float(1.0 + randEps * z);\n            }\n        }\n\n        using P = pair<double,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[sId] = 0.0;\n        pq.emplace(0.0, sId);\n\n        while (!pq.empty()) {\n            auto [d,u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == tId) break;\n            auto [ui, uj] = nodePos(u);\n            for (auto [v, e] : adjIdx[ui][uj]) {\n                double ew = w[e];\n                if (!mult.empty()) ew *= mult[e];\n                // safety clamp\n                if (ew < 100.0) ew = 100.0;\n                if (ew > 20000.0) ew = 20000.0;\n                double nd = d + ew;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prevN[v] = u;\n                    prevE[v] = e;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n\n        DRes res;\n        res.prevNode = move(prevN);\n        res.prevEdge = move(prevE);\n        res.pathCost = dist[tId];\n\n        // reconstruct path edges and moves\n        vector<int> edges;\n        string moves;\n        int cur = tId;\n        while (cur != sId && res.prevEdge[cur] != -1) {\n            int e = res.prevEdge[cur];\n            edges.push_back(e);\n            auto [pi, pj] = nodePos(res.prevNode[cur]);\n            auto [ci, cj] = nodePos(cur);\n            if (ci == pi) {\n                // horizontal\n                if (cj == pj + 1) moves.push_back('R');\n                else moves.push_back('L');\n            } else {\n                // vertical\n                if (ci == pi + 1) moves.push_back('D');\n                else moves.push_back('U');\n            }\n            cur = res.prevNode[cur];\n        }\n        reverse(edges.begin(), edges.end());\n        reverse(moves.begin(), moves.end());\n        res.pathEdges = move(edges);\n        res.pathMoves = move(moves);\n        return res;\n    }\n\n    void updateWeights(const vector<int>& pathEdges, long long observed, int qIndex) {\n        if (pathEdges.empty()) return;\n        double pred = 0.0;\n        for (int e : pathEdges) pred += w[e];\n        if (pred <= 1e-6) return;\n\n        double y = (double)observed;\n        // Compute scaling, clipped\n        double s = y / pred;\n        s = max(0.9, min(1.1, s));\n\n        // Learning rate schedule: start higher, decay\n        double eta0 = 0.35;\n        double eta1 = 0.05;\n        double progress = (double)qIndex / 999.0;\n        double eta = eta0 * (1.0 - progress) + eta1 * progress;\n\n        // Update multiplicatively on used edges\n        double factor = 1.0 + eta * (s - 1.0);\n        // Clamp factor slightly to be safe\n        factor = max(0.95, min(1.05, factor));\n\n        for (int e : pathEdges) {\n            w[e] *= factor;\n        }\n\n        // Mild smoothing to neighbors of same row/col to reduce variance\n        double beta = 0.02;\n        // Horizontal neighbors: for each horizontal edge used, nudge adjacent horizontal edges in same row\n        for (int e : pathEdges) {\n            if (e < HHE) {\n                int i = e / (WN - 1);\n                int j = e % (WN - 1);\n                // left neighbor\n                if (j - 1 >= 0) {\n                    int ne = idH(i, j - 1);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n                // right neighbor\n                if (j + 1 < WN - 1) {\n                    int ne = idH(i, j + 1);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n            } else {\n                int ve = e - HHE;\n                int i = ve / WN;\n                int j = ve % WN;\n                // up neighbor\n                if (i - 1 >= 0) {\n                    int ne = idV(i - 1, j);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n                // down neighbor\n                if (i + 1 < HN - 1) {\n                    int ne = idV(i + 1, j);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n            }\n        }\n\n        // Global clipping\n        for (int e : pathEdges) {\n            if (w[e] < 500.0) w[e] = 500.0;\n            if (w[e] > 15000.0) w[e] = 15000.0;\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    GridRouter gr;\n\n    long long prev_result = 0; // not used for first query but we will read after output\n\n    for (int q = 0; q < 1000; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) {\n            return 0;\n        }\n\n        // Exploration epsilon schedule: decay over first 200 queries\n        double eps_start = 0.05;\n        double eps = 0.0;\n        if (q < 200) {\n            double t = (double)q / 200.0;\n            eps = eps_start * (1.0 - t);\n        }\n\n        uint64_t seed = ((uint64_t)si<<48) ^ ((uint64_t)sj<<32) ^ ((uint64_t)ti<<16) ^ (uint64_t)tj ^ (uint64_t)q*1469598103934665603ull;\n\n        auto res = gr.shortestPath({si,sj},{ti,tj}, eps, seed);\n\n        // Fallback: if something went wrong (no path), output a simple Manhattan path\n        string path = res.pathMoves;\n        if ((int)path.size() == 0) {\n            // Construct naive Manhattan path\n            int di = ti - si;\n            int dj = tj - sj;\n            string tmp;\n            if (di > 0) tmp.append(di, 'D'); else tmp.append(-di, 'U');\n            if (dj > 0) tmp.append(dj, 'R'); else tmp.append(-dj, 'L');\n            path = tmp;\n            // Note: our graph ensures connectivity; this fallback is just for safety\n        }\n\n        cout << path << \"\\n\";\n        FastIO::flush();\n\n        long long observed;\n        if (!(cin >> observed)) {\n            return 0;\n        }\n\n        // Update weights with observation\n        gr.updateWeights(res.pathEdges, observed, q);\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic inline int ch2i(char c){ return c - 'A'; }\nstatic inline char i2ch(int x){ return char('A' + x); }\n\nstruct Placement {\n    uint8_t dir; // 0=hor,1=ver\n    uint8_t fixed; // row for hor, col for ver\n    uint8_t start; // start index\n};\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    vector<string> s(M);\n    for(int i=0;i<M;i++) cin >> s[i];\n\n    // Encode strings\n    vector<vector<uint8_t>> enc(M);\n    int maxLen=0;\n    array<int,8> globalCnt{}; globalCnt.fill(0);\n    for(int i=0;i<M;i++){\n        enc[i].resize(s[i].size());\n        for(size_t k=0;k<s[i].size();k++){\n            enc[i][k] = (uint8_t)ch2i(s[i][k]);\n            globalCnt[enc[i][k]]++;\n        }\n        maxLen = max<int>(maxLen, s[i].size());\n    }\n    int fillChar = int(max_element(globalCnt.begin(), globalCnt.end()) - globalCnt.begin());\n\n    // Precompute all placements per string (we can keep all: 2*N*N)\n    vector<vector<Placement>> placements(M);\n    placements.reserve(M);\n    for(int i=0;i<M;i++){\n        vector<Placement> ps;\n        ps.reserve(2*N*N);\n        int k = (int)enc[i].size();\n        // Horizontal\n        for(int r=0;r<N;r++){\n            for(int c0=0;c0<N;c0++){\n                ps.push_back(Placement{0,(uint8_t)r,(uint8_t)c0});\n            }\n        }\n        // Vertical\n        for(int c=0;c<N;c++){\n            for(int r0=0;r0<N;r0++){\n                ps.push_back(Placement{1,(uint8_t)c,(uint8_t)r0});\n            }\n        }\n        placements[i] = move(ps);\n    }\n\n    // Grid: -1 unknown, 0..7\n    const int UNKNOWN = -1;\n    vector<int8_t> grid(N*N, UNKNOWN);\n\n    auto checkGain = [&](int si, const Placement& pl)->int{\n        const auto& e = enc[si];\n        int k = (int)e.size();\n        int gain = 0;\n        if(pl.dir==0){\n            int r = pl.fixed;\n            int c0 = pl.start;\n            int base = r*N;\n            for(int p=0;p<k;p++){\n                int c = (c0 + p) % N;\n                int idx = base + c;\n                int8_t v = grid[idx];\n                if(v==UNKNOWN) gain++;\n                else if(v != (int)e[p]) return -1;\n            }\n        }else{\n            int c = pl.fixed;\n            int r0 = pl.start;\n            for(int p=0;p<k;p++){\n                int r = (r0 + p) % N;\n                int idx = r*N + c;\n                int8_t v = grid[idx];\n                if(v==UNKNOWN) gain++;\n                else if(v != (int)e[p]) return -1;\n            }\n        }\n        return gain;\n    };\n\n    auto applyPlacement = [&](int si, const Placement& pl){\n        const auto& e = enc[si];\n        int k = (int)e.size();\n        if(pl.dir==0){\n            int r = pl.fixed;\n            int c0 = pl.start;\n            int base = r*N;\n            for(int p=0;p<k;p++){\n                int c = (c0 + p) % N;\n                int idx = base + c;\n                grid[idx] = (int8_t)e[p];\n            }\n        }else{\n            int c = pl.fixed;\n            int r0 = pl.start;\n            for(int p=0;p<k;p++){\n                int r = (r0 + p) % N;\n                int idx = r*N + c;\n                grid[idx] = (int8_t)e[p];\n            }\n        }\n    };\n\n    // Flags\n    vector<char> satisfied(M, 0);\n\n    // Greedy loop: repeatedly apply the single best positive-gain placement\n    // until no positive-gain placement exists or time budget reached.\n    // To limit time, cap total iterations.\n    const int maxGlobalIters = 20000; // generous but safe\n    int applied = 0;\n    for(int iter=0; iter<maxGlobalIters; iter++){\n        int bestGain = 0;\n        int bestSi = -1;\n        Placement bestPl{};\n        // Track zero-gain satisfied strings in this pass\n        int newlySatisfiedZero = 0;\n\n        for(int i=0;i<M;i++){\n            if(satisfied[i]) continue;\n            int bestGain_i = -1;\n            Placement bestPl_i{};\n            bool hasZeroSat = false;\n            for(const auto& pl: placements[i]){\n                int g = checkGain(i, pl);\n                if(g < 0) continue;\n                if(g == 0){\n                    hasZeroSat = true;\n                    // we can stop early; but keep scanning for positive gain in case available\n                }\n                if(g > bestGain_i){\n                    bestGain_i = g;\n                    bestPl_i = pl;\n                    if(g == (int)enc[i].size()){\n                        // perfect fresh placement, good enough\n                        // keep but continue; we still might find equal\n                    }\n                }\n            }\n            if(bestGain_i >= 0){\n                if(bestGain_i == 0 && hasZeroSat){\n                    satisfied[i] = 1;\n                    newlySatisfiedZero++;\n                }else if(bestGain_i > bestGain){\n                    bestGain = bestGain_i;\n                    bestSi = i;\n                    bestPl = bestPl_i;\n                }\n            }\n        }\n\n        if(bestSi == -1){\n            // No positive-gain moves left; we only possibly marked zero-gain strings.\n            break;\n        }\n        applyPlacement(bestSi, bestPl);\n        satisfied[bestSi] = 1;\n        applied++;\n    }\n\n    // Final pass: mark any remaining satisfied by zero-gain\n    for(int i=0;i<M;i++){\n        if(satisfied[i]) continue;\n        bool ok = false;\n        for(const auto& pl: placements[i]){\n            int g = checkGain(i, pl);\n            if(g == 0){ ok = true; break; }\n        }\n        if(ok) satisfied[i] = 1;\n    }\n\n    // Fill remaining unknowns with globally frequent character\n    for(int idx=0; idx<N*N; idx++){\n        if(grid[idx] == UNKNOWN) grid[idx] = (int8_t)fillChar;\n    }\n\n    // Output\n    for(int r=0;r<N;r++){\n        string line;\n        line.resize(N);\n        for(int c=0;c<N;c++){\n            line[c] = i2ch(grid[r*N + c]);\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() { st = chrono::steady_clock::now(); }\n    double elapsed() const {\n        using namespace chrono;\n        return duration<double>(steady_clock::now() - st).count();\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    auto inb = [&](int i, int j){ return 0<=i && i<N && 0<=j && j<N; };\n    auto isRoad = [&](int i, int j){ return inb(i,j) && g[i][j] != '#'; };\n    // Map road cells to compact indices [0,R)\n    int R = 0;\n    vector<int> id(N*N, -1);\n    vector<pair<int,int>> pos; pos.reserve(N*N);\n    for (int i=0;i<N;++i) for (int j=0;j<N;++j) if (isRoad(i,j)) {\n        id[i*N+j] = R++;\n        pos.emplace_back(i,j);\n    }\n    if (id[si*N+sj] < 0) {\n        // Should not happen per statement, but guard\n        cout << \"\\n\";\n        return 0;\n    }\n    // Precompute visibility bitsets for each road cell\n    int W = (R + 63) >> 6;\n    vector<vector<uint64_t>> vis(R, vector<uint64_t>(W, 0));\n    // Helper to set bits in a run [k0,k1] of ids stored in a tmp vector\n    // Build mapping from (i,j) road to compact idx\n    // Row runs\n    for (int i=0;i<N;++i) {\n        int j=0;\n        while (j<N) {\n            while (j<N && !isRoad(i,j)) ++j;\n            if (j>=N) break;\n            int k=j;\n            vector<int> runIds;\n            while (k<N && isRoad(i,k)) {\n                runIds.push_back(id[i*N+k]);\n                ++k;\n            }\n            // For each cell in run, set all bits of run (row visibility)\n            for (int t=0;t<(int)runIds.size();++t) {\n                int idx = runIds[t];\n                auto &b = vis[idx];\n                for (int u=0;u<(int)runIds.size();++u) {\n                    int rid = runIds[u];\n                    b[rid>>6] |= (1ULL << (rid & 63));\n                }\n            }\n            j = k;\n        }\n    }\n    // Column runs\n    for (int j=0;j<N;++j) {\n        int i=0;\n        while (i<N) {\n            while (i<N && !isRoad(i,j)) ++i;\n            if (i>=N) break;\n            int k=i;\n            vector<int> runIds;\n            while (k<N && isRoad(k,j)) {\n                runIds.push_back(id[k*N+j]);\n                ++k;\n            }\n            // For each cell in run, set all bits of run (column visibility)\n            for (int t=0;t<(int)runIds.size();++t) {\n                int idx = runIds[t];\n                auto &b = vis[idx];\n                for (int u=0;u<(int)runIds.size();++u) {\n                    int rid = runIds[u];\n                    b[rid>>6] |= (1ULL << (rid & 63));\n                }\n            }\n            i = k;\n        }\n    }\n    // Precompute neighbors and weights\n    vector<array<int,4>> neigh(R); // neighbor ids or -1\n    vector<array<int,4>> moveCost(R);\n    for (int r=0;r<R;++r){\n        auto [i,j] = pos[r];\n        int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};\n        for (int d=0; d<4; ++d) {\n            int ni=i+dirs[d][0], nj=j+dirs[d][1];\n            if (isRoad(ni,nj)) {\n                int nid = id[ni*N+nj];\n                neigh[r][d] = nid;\n                moveCost[r][d] = g[ni][nj]-'0';\n            } else {\n                neigh[r][d] = -1;\n                moveCost[r][d] = 0;\n            }\n        }\n    }\n    // Covered bitset\n    vector<uint64_t> covered(W, 0);\n    auto or_into = [&](vector<uint64_t>& a, const vector<uint64_t>& b){\n        for (int k=0;k<W;++k) a[k] |= b[k];\n    };\n    auto popcount_and_not = [&](const vector<uint64_t>& a, const vector<uint64_t>& cov)->int{\n        int s=0;\n        for (int k=0;k<W;++k) {\n            uint64_t x = a[k] & ~cov[k];\n            s += (int)__builtin_popcountll(x);\n        }\n        return s;\n    };\n    int startId = id[si*N+sj];\n    or_into(covered, vis[startId]);\n    int coveredCount = popcount_and_not(covered, vector<uint64_t>(W,0)); // popcount(covered)\n    // Dijkstra buffers\n    const int INF = 1e9;\n    vector<int> dist(R), prevId(R, -1), prevDir(R,-1);\n    auto dijkstra_from = [&](int src){\n        // Reset\n        fill(dist.begin(), dist.end(), INF);\n        fill(prevId.begin(), prevId.end(), -1);\n        fill(prevDir.begin(), prevDir.end(), -1);\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[src]=0; pq.emplace(0, src);\n        while (!pq.empty()){\n            auto [cd,u] = pq.top(); pq.pop();\n            if (cd!=dist[u]) continue;\n            for (int d=0; d<4; ++d) {\n                int v = neigh[u][d];\n                if (v<0) continue;\n                int w = moveCost[u][d];\n                int nd = cd + w;\n                if (nd < dist[v]) {\n                    dist[v]=nd; prevId[v]=u; prevDir[v]=d;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n    };\n    // Build moves along path given target\n    auto reconstruct_moves = [&](int cur, int tgt){\n        string s;\n        if (cur==tgt) return s;\n        vector<int> seq;\n        int x = tgt;\n        while (x != -1 && x != cur) {\n            seq.push_back(x);\n            x = prevId[x];\n        }\n        if (x != cur) {\n            // disconnected? shouldn't happen\n            return s;\n        }\n        reverse(seq.begin(), seq.end());\n        for (int v: seq) {\n            int u = prevId[v];\n            auto [ui,uj] = pos[u];\n            auto [vi,vj] = pos[v];\n            if (vi==ui-1 && vj==uj) s.push_back('U');\n            else if (vi==ui+1 && vj==uj) s.push_back('D');\n            else if (vi==ui && vj==uj-1) s.push_back('L');\n            else if (vi==ui && vj==uj+1) s.push_back('R');\n            else {\n                // Should not happen\n            }\n        }\n        return s;\n    };\n    string answer;\n    Timer timer;\n    int cur = startId;\n    // Main greedy loop\n    const double timeLimit = 2.85; // seconds\n    const double beta = 1.1;\n    // Precompute list of candidate ids (all roads)\n    vector<int> cand(R);\n    iota(cand.begin(), cand.end(), 0);\n    // Track coverage count cheaply\n    auto popcount_bits = [&](const vector<uint64_t>& a)->int{\n        int s=0; for (int k=0;k<W;++k) s += (int)__builtin_popcountll(a[k]); return s;\n    };\n    int totalRoads = R;\n    coveredCount = popcount_bits(covered);\n    int iterations = 0;\n    while (coveredCount < totalRoads) {\n        if (timer.elapsed() > timeLimit) break;\n        dijkstra_from(cur);\n        // Find best target by dist / gain^beta\n        int bestT = -1;\n        double bestScore = 1e100;\n        int bestGain = 0;\n        // For a small boost, skip candidates with dist very large to speed up comparison\n        for (int t : cand) {\n            int d = dist[t];\n            if (d >= INF) continue;\n            int gain = popcount_and_not(vis[t], covered);\n            if (gain <= 0) continue;\n            // score function\n            double sc = (double)d / pow((double)gain, beta);\n            if (sc < bestScore - 1e-12 || (abs(sc - bestScore) <= 1e-12 && gain > bestGain)) {\n                bestScore = sc;\n                bestT = t;\n                bestGain = gain;\n            }\n        }\n        if (bestT == -1) {\n            // No progress from here (shouldn't happen unless covered); try move towards start and break\n            break;\n        }\n        // Append path to bestT\n        string mv = reconstruct_moves(cur, bestT);\n        answer += mv;\n        // Update current\n        cur = bestT;\n        // Update covered\n        or_into(covered, vis[cur]);\n        coveredCount = popcount_bits(covered);\n        ++iterations;\n        // Optional: early return when very close to finishing time\n        if (timer.elapsed() > timeLimit) break;\n        // Additional small heuristic: if bestGain is huge relative to remaining, maybe try return check later\n    }\n    // Ensure we return to start\n    if (cur != startId) {\n        dijkstra_from(cur);\n        string mv = reconstruct_moves(cur, startId);\n        answer += mv;\n        cur = startId;\n    }\n    // Output\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct RNG {\n    uint64_t x=88172645463393265ull;\n    uint32_t next() { x ^= x<<7; x ^= x>>9; return uint32_t(x); }\n    double drand() { return (next()>>8) * (1.0/16777216.0); }\n} rng;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,K,R;\n    if(!(cin>>N>>M>>K>>R)) return 0;\n    vector<vector<int>> d(N, vector<int>(K));\n    for(int i=0;i<N;i++) for(int k=0;k<K;k++) cin>>d[i][k];\n    vector<vector<int>> g(N);\n    vector<int> indeg(N,0);\n    for(int i=0;i<R;i++){\n        int u,v; cin>>u>>v; --u;--v;\n        g[u].push_back(v);\n        indeg[v]++;\n    }\n    // compute \"height\" (distance to sink) via reverse DP: longest path length estimate\n    vector<int> topo;\n    {\n        vector<int> indeg2 = indeg;\n        queue<int> q;\n        for(int i=0;i<N;i++) if(indeg2[i]==0) q.push(i);\n        while(!q.empty()){\n            int u=q.front(); q.pop();\n            topo.push_back(u);\n            for(int v: g[u]){\n                if(--indeg2[v]==0) q.push(v);\n            }\n        }\n        if((int)topo.size()!=N){\n            // Shouldn't happen but guard\n            topo.clear();\n            for(int i=0;i<N;i++) topo.push_back(i);\n        }\n    }\n    vector<vector<int>> rg(N);\n    for(int u=0;u<N;u++) for(int v: g[u]) rg[v].push_back(u);\n    vector<int> height(N,0);\n    // reverse topo to compute longest path to end (in terms of edges)\n    for(int idx=N-1; idx>=0; --idx){\n        int u = topo[idx];\n        int best=0;\n        for(int v: g[u]) best = max(best, 1 + height[v]);\n        height[u]=best;\n    }\n    // Also compute number of descendants approximate via DP (could be heavy to exact), skip.\n\n    // Estimations\n    vector<vector<double>> est(M, vector<double>(K, 10.0));\n    vector<vector<int>> lb(M, vector<int>(K, 0));\n\n    // Task status: 0 not started, 1 started, 2 done\n    vector<int> tstat(N,0);\n    vector<int> started_by(N, -1);\n    vector<int> start_day(N, -1);\n\n    // Member status: -1 idle, else task index\n    vector<int> mtask(M, -1);\n\n    // Current indegree mutable\n    vector<int> cur_indeg = indeg;\n    vector<char> in_ready(N, 0);\n    deque<int> ready;\n    // initialize ready tasks (no deps)\n    for(int i=0;i<N;i++) if(cur_indeg[i]==0){ ready.push_back(i); in_ready[i]=1; }\n\n    auto predicted_time = [&](int task, int mem)->double{\n        double w=0.0;\n        for(int k=0;k<K;k++){\n            double def = (double)d[task][k] - est[mem][k];\n            if(def>0) w += def;\n        }\n        // r mean ~0, but add small bias\n        if(w<1.0) return 1.0;\n        return max(1.0, w);\n    };\n\n    auto assign_task = [&](int mem, int task, int day){\n        mtask[mem]=task;\n        tstat[task]=1;\n        started_by[task]=mem;\n        start_day[task]=day;\n        // remove from ready if present\n        if(in_ready[task]){\n            in_ready[task]=0;\n            // we won't remove efficiently from deque; will skip when popping\n        }\n    };\n\n    int day=0;\n    const double alpha = 1.0;\n    const double beta = 0.3;\n    const double eps = 0.05;\n\n    while(true){\n        day++;\n        // Build list of idle members\n        vector<int> idle;\n        for(int j=0;j<M;j++) if(mtask[j]==-1) idle.push_back(j);\n\n        // Prepare candidates list of ready tasks (clean deque)\n        vector<int> rlist;\n        // Rebuild rlist from flags to avoid stale entries\n        rlist.reserve(ready.size());\n        for(int i=0;i<N;i++){\n            if(in_ready[i] && tstat[i]==0) rlist.push_back(i);\n        }\n\n        // Greedy assignment\n        vector<pair<int,int>> out; out.reserve(idle.size());\n        // To limit cost, consider up to topL by height\n        int topL = 300; // cap candidates\n        if((int)rlist.size()>topL){\n            // pick top by height\n            nth_element(rlist.begin(), rlist.begin()+topL, rlist.end(), [&](int a,int b){\n                return height[a] > height[b];\n            });\n            rlist.resize(topL);\n        }\n        // Keep a set to avoid assigning same task twice\n        vector<char> taken(N, 0);\n        for(int mem: idle){\n            int bestTask = -1;\n            double bestScore = 1e100;\n            // exploration?\n            bool doExplore = (rng.drand() < eps);\n            if(doExplore){\n                // pick task with largest uncertainty: sum(est-lb gaps near d)\n                double bestU = -1.0;\n                for(int t: rlist){\n                    if(taken[t]) continue;\n                    double unc=0.0;\n                    for(int k=0;k<K;k++){\n                        if(d[t][k]>lb[mem][k]){\n                            double gap = max(0.0, est[mem][k] - (double)lb[mem][k]);\n                            // uncertainty where d is near est\n                            double closeness = max(0.0, est[mem][k] - d[t][k]);\n                            unc += gap - 0.5*closeness;\n                        }\n                    }\n                    unc += 0.1*height[t];\n                    if(unc>bestU){\n                        bestU=unc; bestTask=t;\n                    }\n                }\n            } else {\n                for(int t: rlist){\n                    if(taken[t]) continue;\n                    double tp = predicted_time(t, mem);\n                    double score = alpha*tp - beta*height[t];\n                    if(score < bestScore){\n                        bestScore=score; bestTask=t;\n                    }\n                }\n            }\n            if(bestTask!=-1){\n                taken[bestTask]=1;\n                out.emplace_back(mem, bestTask);\n            }\n        }\n\n        // Output\n        cout<<out.size();\n        for(auto &p: out){\n            int mem = p.first;\n            int task = p.second;\n            cout<<\" \"<<(mem+1)<<\" \"<<(task+1);\n            assign_task(mem, task, day);\n        }\n        cout<<\"\\n\";\n        cout.flush();\n\n        // Read feedback\n        int nfin;\n        if(!(cin>>nfin)) return 0;\n        if(nfin==-1) return 0;\n        vector<int> fins(nfin);\n        for(int i=0;i<nfin;i++){ cin>>fins[i]; fins[i]--; }\n\n        // Process finishes: mark tasks done, update estimates, update ready\n        for(int mem: fins){\n            int task = mtask[mem];\n            if(task<0) continue; // safety\n            int dur = day - start_day[task] + 1;\n            // Update estimates\n            if(dur<=1){\n                // strict implication w=0 -> s >= d\n                for(int k=0;k<K;k++){\n                    lb[mem][k] = max(lb[mem][k], d[task][k]);\n                    est[mem][k] = max(est[mem][k], (double)d[task][k]);\n                }\n            } else {\n                // For t>1, adjust est upwards to reduce predicted deficit towards T\n                // Compute current deficit\n                vector<double> def(K,0.0);\n                double W=0.0;\n                for(int k=0;k<K;k++){\n                    double df = (double)d[task][k] - est[mem][k];\n                    if(df>0){ def[k]=df; W+=df; }\n                }\n                // Target T ~ dur, clamp\n                double T = (double)dur;\n                if(W > T){\n                    // reduce W by increasing on positive def dims\n                    double sumdef = W;\n                    if(sumdef>1e-9){\n                        double delta = min(W - T, 3.0); // cautious step\n                        for(int k=0;k<K;k++){\n                            if(def[k]>0){\n                                double inc = delta * (def[k]/sumdef);\n                                est[mem][k] += inc;\n                                est[mem][k] = max(est[mem][k], (double)lb[mem][k]);\n                            } else {\n                                est[mem][k] = max(est[mem][k], (double)lb[mem][k]);\n                            }\n                        }\n                    }\n                } else {\n                    // W <= T, maybe we overestimate somewhere; lightly pull down non-lb dims\n                    double delta = min(T - W, 1.0);\n                    for(int k=0;k<K;k++){\n                        if(est[mem][k] > lb[mem][k]){\n                            est[mem][k] = max((double)lb[mem][k], est[mem][k] - delta*0.05);\n                        }\n                    }\n                }\n            }\n            // free member and mark task done\n            mtask[mem] = -1;\n            tstat[task]=2;\n            // unlock successors\n            for(int v: g[task]){\n                cur_indeg[v]--;\n                if(cur_indeg[v]==0 && tstat[v]==0){\n                    in_ready[v]=1;\n                }\n            }\n        }\n\n        // Compact ready deque representation not necessary; we rebuild rlist each day from flags.\n        // Loop continues\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int ax, ay, cx, cy, idx;\n    double score;\n    double ang_pick, ang_drop;\n};\n\nstatic inline int manh(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int DEPX=400, DEPY=400;\n    vector<Order> all;\n    all.reserve(1000);\n    for(int i=0;i<1000;i++){\n        int a,b,c,d;\n        if(!(cin>>a>>b>>c>>d)) return 0;\n        Order o; o.ax=a;o.ay=b;o.cx=c;o.cy=d;o.idx=i+1;\n        all.push_back(o);\n    }\n    // Compute scores\n    const double alpha=1.0, beta=1.0, gamma=0.7; // weights\n    const double angle_penalty = 10.0; // mild\n    for(auto &o: all){\n        int da = manh(DEPX,DEPY,o.ax,o.ay);\n        int ac = manh(o.ax,o.ay,o.cx,o.cy);\n        int cd = manh(o.cx,o.cy,DEPX,DEPY);\n        // angle from depot (for pickup and drop)\n        double angp = atan2((double)o.ay - DEPY, (double)o.ax - DEPX);\n        double angd = atan2((double)o.cy - DEPY, (double)o.cx - DEPX);\n        o.ang_pick = angp; o.ang_drop = angd;\n        double dang = fabs(angp - angd);\n        while(dang > M_PI) dang = fabs(dang - 2*M_PI);\n        o.score = alpha*da + beta*ac + gamma*cd + angle_penalty * dang;\n    }\n    // Sort by score and pick top 50\n    sort(all.begin(), all.end(), [](const Order& A, const Order& B){\n        if (A.score != B.score) return A.score < B.score;\n        return A.idx < B.idx;\n    });\n    int m = 50;\n    vector<Order> sel(all.begin(), all.begin()+m);\n    // Greedy route construction with precedence\n    struct Node { int x,y; int ordIdx; bool isPickup; };\n    // Map from idx to order data\n    unordered_map<int, Order> omap;\n    omap.reserve(m*2);\n    for (auto &o: sel) omap[o.idx]=o;\n\n    // Sets\n    vector<int> unpicked, carrying;\n    unpicked.reserve(m);\n    for (auto &o: sel) unpicked.push_back(o.idx);\n    vector<Node> route;\n    route.push_back({DEPX,DEPY,-1,false}); // start\n\n    int curx=DEPX, cury=DEPY;\n    // simple structure for lookup location\n    auto getPick = [&](int id)->pair<int,int>{\n        auto &o = omap[id]; return {o.ax,o.ay};\n    };\n    auto getDrop = [&](int id)->pair<int,int>{\n        auto &o = omap[id]; return {o.cx,o.cy};\n    };\n\n    for(int step=0; step<2*m; ++step){\n        // find best pickup\n        int bestPid=-1; int bestPdist=INT_MAX; int px=0,py=0;\n        for(int id: unpicked){\n            auto p = getPick(id);\n            int d = manh(curx,cury,p.first,p.second);\n            if(d < bestPdist){\n                bestPdist = d; bestPid=id; px=p.first; py=p.second;\n            }\n        }\n        // find best drop\n        int bestDid=-1; int bestDdist=INT_MAX; int dx=0,dy=0;\n        for(int id: carrying){\n            auto p = getDrop(id);\n            int d = manh(curx,cury,p.first,p.second);\n            if(d < bestDdist){\n                bestDdist = d; bestDid=id; dx=p.first; dy=p.second;\n            }\n        }\n        // choose\n        bool doPickup = false;\n        if(bestPid==-1 && bestDid!=-1) doPickup=false;\n        else if(bestPid!=-1 && bestDid==-1) doPickup=true;\n        else {\n            // bias against picking when carrying many\n            double bias = 1.05 + 0.02 * (int)carrying.size();\n            doPickup = (bestPdist * bias <= bestDdist + 1e-9);\n        }\n        if(doPickup){\n            // move to pickup\n            route.push_back({px,py,bestPid,true});\n            curx=px; cury=py;\n            // update sets\n            // remove from unpicked\n            auto it = find(unpicked.begin(), unpicked.end(), bestPid);\n            if(it!=unpicked.end()) unpicked.erase(it);\n            carrying.push_back(bestPid);\n        }else{\n            // move to drop\n            route.push_back({dx,dy,bestDid,false});\n            curx=dx; cury=dy;\n            // remove from carrying\n            auto it = find(carrying.begin(), carrying.end(), bestDid);\n            if(it!=carrying.end()) carrying.erase(it);\n        }\n    }\n    // return to depot\n    route.push_back({DEPX,DEPY,-1,false});\n\n    // Build mapping of order to first/second occurrence indices\n    int n = (int)route.size();\n    vector<int> firstIdx(1001,-1), secondIdx(1001,-1);\n    for(int i=0;i<n;i++){\n        if(route[i].ordIdx==-1) continue;\n        int id = route[i].ordIdx;\n        if(route[i].isPickup){\n            if(firstIdx[id]==-1) firstIdx[id]=i;\n        }else{\n            if(secondIdx[id]==-1) secondIdx[id]=i;\n        }\n    }\n    auto routeDist = [&](const vector<Node>& R)->long long{\n        long long t=0;\n        for(size_t i=0;i+1<R.size();++i) t += manh(R[i].x,R[i].y,R[i+1].x,R[i+1].y);\n        return t;\n    };\n\n    // Local search: 2-opt with precedence check\n    auto violates = [&](int i, int j, const vector<Node>& R)->bool{\n        // check for each order where pickup or drop falls in [i..j], whether pickup index < drop index\n        // First collect indices for orders affected\n        // For simplicity, recompute full positions\n        vector<int> pidx(1001,-1), didx(1001,-1);\n        for(int k=0;k<(int)R.size();++k){\n            int id=R[k].ordIdx;\n            if(id==-1) continue;\n            if(R[k].isPickup){ if(pidx[id]==-1) pidx[id]=k; }\n            else { if(didx[id]==-1) didx[id]=k; }\n        }\n        for (auto &o: sel){\n            int pid = pidx[o.idx];\n            int did = didx[o.idx];\n            if(pid==-1 || did==-1) continue;\n            if(pid >= did) return true;\n        }\n        return false;\n    };\n\n    auto try_two_opt = [&](vector<Node>& R){\n        bool improved=true;\n        int iter=0;\n        while(improved && iter<200){\n            improved=false; iter++;\n            long long bestGain=0;\n            int bi=-1,bj=-1;\n            for(int i=1;i+2<(int)R.size();++i){\n                for(int j=i+1;j+1<(int)R.size();++j){\n                    // endpoints fixed\n                    long long d0 = manh(R[i-1].x,R[i-1].y,R[i].x,R[i].y)\n                                  + manh(R[j].x,R[j].y,R[j+1].x,R[j+1].y);\n                    long long d1 = manh(R[i-1].x,R[i-1].y,R[j].x,R[j].y)\n                                  + manh(R[i].x,R[i].y,R[j+1].x,R[j+1].y);\n                    long long gain = d0 - d1;\n                    if(gain > bestGain){\n                        // simulate reversal and check precedence\n                        // We can avoid full recomputation by temporarily reverse and check\n                        reverse(R.begin()+i, R.begin()+j+1);\n                        if(!violates(0,0,R)){\n                            bestGain = gain;\n                            bi=i; bj=j;\n                        }\n                        reverse(R.begin()+i, R.begin()+j+1);\n                    }\n                }\n            }\n            if(bestGain > 0 && bi!=-1){\n                reverse(R.begin()+bi, R.begin()+bj+1);\n                improved=true;\n            }\n        }\n    };\n\n    try_two_opt(route);\n\n    // Simple paired relocate: move a pickup-drop pair closer together\n    auto index_of = [&](const vector<Node>& R, int id, bool pickup)->int{\n        for(int i=0;i<(int)R.size();++i){\n            if(R[i].ordIdx==id && R[i].isPickup==pickup) return i;\n        }\n        return -1;\n    };\n    auto relocate_pair = [&](vector<Node>& R){\n        bool improved=true;\n        int attempts=0;\n        while(improved && attempts<50){\n            improved=false; attempts++;\n            long long bestDelta=0;\n            int bid=-1, insertPos=-1;\n            // compute current length\n            long long curL = routeDist(R);\n            for(auto &o: sel){\n                int pid = index_of(R,o.idx,true);\n                int did = index_of(R,o.idx,false);\n                if(pid==-1 || did==-1 || pid>=did) continue;\n                // Remove both nodes; try reinsert pickup at pos p, and drop at some q>p\n                // To keep it cheap, try a few candidate positions around pid and did\n                vector<int> candP;\n                for(int t=max(1,pid-3); t<=min((int)R.size()-2,pid+3); ++t) candP.push_back(t);\n                for(int p: candP){\n                    if(p==pid) continue;\n                    // Build list of candidate q near did adjusted for shift\n                    for(int q=max(p+1, did-3); q<=min((int)R.size()-1, did+3); ++q){\n                        // Simulate cost delta cheaply by rebuilding a temporary vector for small sizes\n                        vector<Node> T = R;\n                        // extract nodes\n                        Node P = T[pid];\n                        Node D = T[did];\n                        if(pid<did){\n                            T.erase(T.begin()+did);\n                            T.erase(T.begin()+pid);\n                        }else{\n                            T.erase(T.begin()+pid);\n                            T.erase(T.begin()+did);\n                        }\n                        // insert pickup at p, drop at q (note indices shift after first insert)\n                        T.insert(T.begin()+p, P);\n                        int qpos = q;\n                        if(p<=qpos) qpos++; // after inserting P, subsequent indices shift\n                        T.insert(T.begin()+qpos, D);\n                        long long newL = routeDist(T);\n                        long long delta = (long long)curL - newL;\n                        if(delta > bestDelta){\n                            bestDelta = delta;\n                            bid = o.idx;\n                            insertPos = p;\n                            // Apply immediately for speed\n                            R.swap(T);\n                            improved=true;\n                            break;\n                        }\n                    }\n                    if(improved) break;\n                }\n                if(improved) break;\n            }\n        }\n    };\n\n    relocate_pair(route);\n    try_two_opt(route);\n\n    // Output\n    cout<<m;\n    for(auto &o: sel) cout<<\" \"<<o.idx;\n    cout<<\"\\n\";\n    cout<<route.size();\n    for(auto &nd: route){\n        cout<<\" \"<<nd.x<<\" \"<<nd.y\";\n    }\n    cout<<\"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    int comps;\n    DSU(int n=0): n(n), p(n), r(n,0), comps(n) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool same(int a,int b){ return find(a)==find(b); }\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        comps--;\n        return true;\n    }\n};\n\nstruct Edge {\n    int idx;\n    int u,v;\n    int d; // prior 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    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++){\n        if(!(cin>>x[i]>>y[i])) return 0;\n    }\n    vector<int> U(M), V(M);\n    for(int i=0;i<M;i++){\n        cin>>U[i]>>V[i];\n    }\n\n    auto rd = [&](int i)->int{\n        long long dx = x[U[i]] - x[V[i]];\n        long long dy = y[U[i]] - y[V[i]];\n        double dist = sqrt((double)(dx*dx + dy*dy));\n        int di = (int)llround(dist);\n        return di;\n    };\n\n    vector<Edge> edges(M);\n    for(int i=0;i<M;i++){\n        edges[i] = {i, U[i], V[i], rd(i)};\n    }\n\n    // Build 5 disjoint MST layers using d as weight\n    vector<int> layer(M, -1);\n    vector<char> removed(M, 0);\n    // We'll make a list of remaining edge indices\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n\n    for(int lay=0; lay<5; lay++){\n        // Prepare list of available edges\n        vector<int> avail;\n        avail.reserve(M);\n        for(int ei=0; ei<M; ei++){\n            if(layer[ei]==-1) avail.push_back(ei);\n        }\n        // Sort by d\n        sort(avail.begin(), avail.end(), [&](int a, int b){\n            if(edges[a].d != edges[b].d) return edges[a].d < edges[b].d;\n            if(edges[a].u != edges[b].u) return edges[a].u < edges[b].u;\n            return edges[a].v < edges[b].v;\n        });\n        DSU dsu(N);\n        int taken = 0;\n        for(int eid: avail){\n            int u = edges[eid].u, v = edges[eid].v;\n            if(!dsu.same(u,v)){\n                dsu.unite(u,v);\n                layer[eid] = lay;\n                taken++;\n                if(taken == N-1) break;\n            }\n        }\n        // As per generation, there should be exactly N-1 per layer\n    }\n\n    // Online phase\n    DSU cur(N);\n    long long totalA = 0;\n    int comps = N;\n\n    // thresholds per layer; tuned values\n    // Lower layer index => more confident to accept at higher cost\n    array<double,5> alpha;\n    // base values\n    alpha[0]=1.60; alpha[1]=1.50; alpha[2]=1.40; alpha[3]=1.30; alpha[4]=1.20;\n\n    for(int i=0;i<M;i++){\n        int l_i;\n        if(!(cin>>l_i)) return 0;\n        int u = U[i], v = V[i];\n        int d = edges[i].d;\n        int lay = layer[i];\n        if(lay<0 || lay>4) lay = 4; // fallback\n\n        int R = M - i - 1;\n        int C = cur.comps;\n\n        bool accept = false;\n        if(cur.same(u,v)){\n            accept = false;\n        }else{\n            if(C-1 <= 1) {\n                // only one connection needed, still be cautious\n            }\n            // safety relaxations\n            double mul = alpha[lay];\n            if(R <= 3*(C-1)) mul += 0.30;\n            if(R <= 2*(C-1)) {\n                // To guarantee connectivity, accept any connecting edge\n                accept = true;\n            } else {\n                // Normal threshold decision\n                // Also quick absolute cap: accept if l is very small compared to global scale\n                // but primarily use l <= mul * d\n                if((double)l_i <= mul * (double)d) accept = true;\n            }\n        }\n\n        if(accept){\n            if(!cur.same(u,v)){\n                cur.unite(u,v);\n                totalA += l_i;\n            }\n            cout << 1 << '\\n' << flush;\n        }else{\n            cout << 0 << '\\n' << flush;\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Constants\nstatic const int H = 30, W = 30;\nstruct Pet {\n    int x, y;\n    int t;\n};\nstruct Human {\n    int x, y;\n    int wallRow;    // target wall row (6,12,18,24)\n    int standRow;   // row we stand on to place block (wallRow-1 or wallRow+1)\n    int L, R;       // sweep column range inclusive\n    int dir;        // +1 to sweep increasing y, -1 decreasing\n    int targetCol;  // current sweep target column\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<Pet> pets(N);\n    for(int i=0;i<N;i++){\n        int px,py,pt; cin>>px>>py>>pt;\n        pets[i]={px,py,pt};\n    }\n    int M; cin>>M;\n    vector<Human> humans(M);\n    vector<pair<int,int>> initH(M);\n    for(int i=0;i<M;i++){\n        int hx,hy; cin>>hx>>hy;\n        humans[i].x=hx; humans[i].y=hy;\n        initH[i]={hx,hy};\n    }\n    // Grid state\n    vector<vector<bool>> blocked(H+1, vector<bool>(W+1,false));\n    vector<vector<int>> petCnt(H+1, vector<int>(W+1,0));\n    auto inb=[&](int x,int y){ return 1<=x && x<=H && 1<=y && y<=W; };\n    // Initialize pet counts\n    for(auto &p: pets) petCnt[p.x][p.y]++;\n\n    // Assign walls rows cycling among 6,12,18,24\n    vector<int> wallRowsBase = {6,12,18,24};\n    for(int i=0;i<M;i++){\n        int wr = wallRowsBase[i % (int)wallRowsBase.size()];\n        humans[i].wallRow = wr;\n        int stand = wr-1;\n        if(stand<1){ stand = wr+1; }\n        humans[i].standRow = stand;\n    }\n    // Assign column segments\n    // Split 1..W into M segments roughly equal\n    for(int i=0;i<M;i++){\n        int L = (long long)i * W / M + 1;\n        int R = (long long)(i+1) * W / M;\n        humans[i].L = L;\n        humans[i].R = R;\n        // Start sweeping from nearest boundary to current position to reduce travel\n        int hy = humans[i].y;\n        if (abs(hy - L) <= abs(hy - R)) {\n            humans[i].dir = +1;\n            humans[i].targetCol = max(L, min(hy, R));\n        } else {\n            humans[i].dir = -1;\n            humans[i].targetCol = max(L, min(hy, R));\n        }\n    }\n\n    auto safe_to_block = [&](int tx,int ty, const vector<Human>& hs)->bool{\n        if(!inb(tx,ty)) return false;\n        if(blocked[tx][ty]) return false;\n        if(petCnt[tx][ty]>0) return false;\n        // cannot choose a square that contains humans at the start of the turn\n        for(const auto& h: hs){\n            if(h.x==tx && h.y==ty) return false;\n        }\n        // cannot choose a square whose adjacent square contains a pet\n        static const int dx[4]={-1,1,0,0};\n        static const int dy[4]={0,0,-1,1};\n        for(int k=0;k<4;k++){\n            int nx=tx+dx[k], ny=ty+dy[k];\n            if(inb(nx,ny) && petCnt[nx][ny]>0) return false;\n        }\n        return true;\n    };\n\n    auto human_at = [&](int x,int y,const vector<Human>& hs)->bool{\n        for(auto &h: hs) if(h.x==x && h.y==y) return true;\n        return false;\n    };\n\n    // Main 300 turns\n    for(int turn=0; turn<300; turn++){\n        string actions(M, '.');\n        // Decide actions per human\n        for(int i=0;i<M;i++){\n            auto &h = humans[i];\n            int wr = h.wallRow;\n            int sr = h.standRow;\n            // Step 1: move to standRow\n            if(h.x != sr){\n                if(h.x > sr){\n                    // move up\n                    if(inb(h.x-1,h.y) && !blocked[h.x-1][h.y]){\n                        actions[i] = 'U';\n                        continue;\n                    }\n                }else{\n                    if(inb(h.x+1,h.y) && !blocked[h.x+1][h.y]){\n                        actions[i] = 'D';\n                        continue;\n                    }\n                }\n                // fallback do nothing if blocked\n                actions[i]='.';\n                continue;\n            }\n            // Step 2: move to targetCol within [L,R]\n            if(h.y < h.L){ \n                if(inb(h.x, h.y+1) && !blocked[h.x][h.y+1]) { actions[i]='R'; continue; }\n            }\n            if(h.y > h.R){\n                if(inb(h.x, h.y-1) && !blocked[h.x][h.y-1]) { actions[i]='L'; continue; }\n            }\n            // Now inside range [L,R]; aim to sweep\n            // Try to place a block into the wall row at current column if possible\n            int tx = wr;\n            int ty = h.y;\n            char place = (sr < wr ? 'd' : 'u');\n            if(safe_to_block(tx,ty, humans)){\n                actions[i] = place;\n                continue;\n            }\n            // If not safe or already blocked, move horizontally to keep sweeping\n            // Ensure we stay within [L,R], bouncing at ends\n            if(h.dir > 0){\n                if(h.y < h.R){\n                    if(!blocked[h.x][h.y+1]) actions[i]='R';\n                    else actions[i]='.';\n                }else{\n                    h.dir = -1;\n                    if(h.y > h.L && !blocked[h.x][h.y-1]) actions[i]='L';\n                    else actions[i]='.';\n                }\n            }else{\n                if(h.y > h.L){\n                    if(!blocked[h.x][h.y-1]) actions[i]='L';\n                    else actions[i]='.';\n                }else{\n                    h.dir = +1;\n                    if(h.y < h.R && !blocked[h.x][h.y+1]) actions[i]='R';\n                    else actions[i]='.';\n                }\n            }\n        }\n\n        // Output actions\n        cout<<actions<<\"\\n\";\n        cout.flush();\n\n        // Apply human actions to update human positions and blocks for our internal state\n        // But note: moves and blocks are simultaneous, with restriction that a move cannot go into a cell blocked this turn by another human.\n        // To approximate safely, process blocks first, then invalidate moves that attempt to move into newly blocked cells.\n        vector<pair<int,int>> newBlocks;\n        for(int i=0;i<M;i++){\n            char c = actions[i];\n            auto &h = humans[i];\n            if(c=='.' || c=='U' || c=='D' || c=='L' || c=='R') continue;\n            int tx=h.x, ty=h.y;\n            if(c=='u') tx-=1;\n            else if(c=='d') tx+=1;\n            else if(c=='l') ty-=1;\n            else if(c=='r') ty+=1;\n            if(inb(tx,ty)){\n                // Re-check safety superficially; we already did\n                newBlocks.emplace_back(tx,ty);\n            }\n        }\n        // Place blocks (if multiple place same, it's fine)\n        for(auto &b: newBlocks){\n            blocked[b.first][b.second] = true;\n        }\n        // Apply moves ensuring not moving into a newly blocked cell\n        for(int i=0;i<M;i++){\n            char c = actions[i];\n            auto &h = humans[i];\n            int nx=h.x, ny=h.y;\n            if(c=='U') nx--;\n            else if(c=='D') nx++;\n            else if(c=='L') ny--;\n            else if(c=='R') ny++;\n            if(nx==h.x && ny==h.y) continue;\n            if(inb(nx,ny) && !blocked[nx][ny]){\n                h.x=nx; h.y=ny;\n            }\n        }\n\n        // Read pets moves\n        vector<string> pm(N);\n        for(int i=0;i<N;i++){\n            cin>>pm[i];\n        }\n        // Clear pet counts, then update\n        for(int x=1;x<=H;x++) for(int y=1;y<=W;y++) petCnt[x][y]=0;\n        for(int i=0;i<N;i++){\n            for(char c: pm[i]){\n                int nx=pets[i].x, ny=pets[i].y;\n                if(c=='U') nx--;\n                else if(c=='D') nx++;\n                else if(c=='L') ny--;\n                else if(c=='R') ny++;\n                // assume the pet movement is valid (passable); but ensure bounds\n                if(inb(nx,ny)) { pets[i].x=nx; pets[i].y=ny; }\n            }\n            petCnt[pets[i].x][pets[i].y] ++;\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si,sj,ti,tj;\n    double p;\n    if(!(cin>>si>>sj>>ti>>tj>>p)) return 0;\n    vector<string> h(20), v(19);\n    for(int i=0;i<20;i++){\n        cin>>h[i];\n    }\n    for(int i=0;i<19;i++){\n        cin>>v[i];\n    }\n    auto inb = [](int x,int y){ return 0<=x && x<20 && 0<=y && y<20; };\n    auto can_move = [&](int x,int y,int nx,int ny)->bool{\n        if(!inb(nx,ny)) return false;\n        if(nx==x && ny==y+1){\n            return h[x][y]=='0';\n        }\n        if(nx==x && ny==y-1){\n            return h[x][y-1]=='0';\n        }\n        if(nx==x+1 && ny==y){\n            return v[x][y]=='0';\n        }\n        if(nx==x-1 && ny==y){\n            return v[x-1][y]=='0';\n        }\n        return false;\n    };\n    // BFS shortest path\n    const int N=20;\n    vector<vector<int>> dist(N, vector<int>(N, INT_MAX));\n    vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj]=0;\n    q.push({si,sj});\n    int dx[4]={-1,1,0,0};\n    int dy[4]={0,0,-1,1};\n    char dc[4] = {'U','D','L','R'};\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        if(x==ti && y==tj) break;\n        for(int d=0;d<4;d++){\n            int nx=x+dx[d], ny=y+dy[d];\n            if(!inb(nx,ny)) continue;\n            if(!can_move(x,y,nx,ny)) continue;\n            if(dist[nx][ny] > dist[x][y] + 1){\n                dist[nx][ny] = dist[x][y] + 1;\n                par[nx][ny] = {x,y};\n                q.push({nx,ny});\n            }\n        }\n    }\n    // Reconstruct path\n    vector<pair<int,int>> path;\n    int cx=ti, cy=tj;\n    while(!(cx==si && cy==sj) && cx!=-1){\n        path.push_back({cx,cy});\n        auto pr = par[cx][cy];\n        cx = pr.first; cy = pr.second;\n    }\n    path.push_back({si,sj});\n    reverse(path.begin(), path.end());\n    // If BFS somehow fails (shouldn't), fallback to simple greedy without walls\n    vector<char> dirs;\n    if((int)path.size()>=2){\n        for(size_t k=1;k<path.size();k++){\n            int x0=path[k-1].first, y0=path[k-1].second;\n            int x1=path[k].first, y1=path[k].second;\n            if(x1==x0-1 && y1==y0) dirs.push_back('U');\n            else if(x1==x0+1 && y1==y0) dirs.push_back('D');\n            else if(x1==x0 && y1==y0-1) dirs.push_back('L');\n            else if(x1==x0 && y1==y0+1) dirs.push_back('R');\n        }\n    }else{\n        // fallback: straight moves\n        int x=si,y=sj;\n        while(x>ti) { dirs.push_back('U'); x--; }\n        while(x<ti) { dirs.push_back('D'); x++; }\n        while(y>tj) { dirs.push_back('L'); y--; }\n        while(y<tj) { dirs.push_back('R'); y++; }\n    }\n    int D = (int)dirs.size();\n    if(D==0){\n        cout << \"\\n\";\n        return 0;\n    }\n    // Choose repetition factor r\n    // target epsilon for failing to advance on a block: p^r <= 0.02\n    auto safe_ceil = [](double x)->int{\n        int k = (int)ceil(x - 1e-12);\n        return k;\n    };\n    int r_cap;\n    if(p>=1.0-1e-12) r_cap = 8;\n    else {\n        double num = log(0.02);\n        double den = log(p);\n        int rc = safe_ceil(num/den); // since den<0, this is positive\n        r_cap = max(2, min(8, rc));\n    }\n    int r_max = max(1, 200 / max(1, D));\n    int r = min(r_max, r_cap);\n    // Build output\n    string out;\n    out.reserve(200);\n    auto append_repeats = [&](const vector<char>& P, int rep){\n        for(char c: P){\n            for(int k=0;k<rep;k++){\n                if((int)out.size()<200) out.push_back(c);\n            }\n        }\n    };\n    append_repeats(dirs, r);\n    // Add extra full-path copies (unrepeated) to fill up to near 200\n    while((int)out.size() + D <= 200){\n        for(char c: dirs){\n            if((int)out.size()<200) out.push_back(c);\n        }\n    }\n    // If still too short and we have a bit of space, add prefix of path\n    int rem = 200 - (int)out.size();\n    for(int i=0;i<rem && i<D;i++) out.push_back(dirs[i]);\n\n    cout << out << \"\\n\";\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int H = 30, W = 30;\nstatic const int di4[4] = {0,-1,0,1};\nstatic const int dj4[4] = {-1,0,1,0};\n\n// Base to mapping for tile types 0..7 as per statement.\nint base_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// to_rot[t][r][d]: with tile type t rotated r times CCW, entering from direction d, output direction or -1.\nint to_rot[8][4][4];\n\ninline int mod4(int x){ x%=4; if(x<0)x+=4; return x; }\n\nstruct Solver {\n    array<array<int, W>, H> t;\n    array<array<int, W>, H> r;         // current rotations\n    array<array<int, W>, H> best_r;\n    // desired outgoing direction for each entering direction\n    array<array<array<int,4>, W>, H> desired_to;\n\n    int proxyScore = 0;\n\n    Solver() {}\n\n    void precompute_to_rot() {\n        for(int tt=0; tt<8; ++tt){\n            for(int rot=0; rot<4; ++rot){\n                for(int d=0; d<4; ++d){\n                    int din = mod4(d - rot);\n                    int e = base_to_[tt][din];\n                    if(e==-1) to_rot[tt][rot][d] = -1;\n                    else to_rot[tt][rot][d] = mod4(e + rot);\n                }\n            }\n        }\n    }\n\n    void read_input() {\n        for(int i=0;i<H;++i){\n            string s; cin>>s;\n            for(int j=0;j<W;++j){\n                t[i][j] = s[j]-'0';\n            }\n        }\n    }\n\n    void build_desired() {\n        // Two centers: left and right halves\n        double c1i = 14.5, c1j = 7.5;\n        double c2i = 14.5, c2j = 22.5;\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                double ci, cj;\n                if(j < W/2) { ci=c1i; cj=c1j; }\n                else { ci=c2i; cj=c2j; }\n                double pi = i+0.5, pj=j+0.5;\n                double ui = pi - ci, uj = pj - cj;\n                // Tangent vector for CCW around center: rotate by +90 degrees\n                double ti = -uj, tj = ui;\n                // pick cardinal direction closest to (ti,tj)\n                int bestd = 0;\n                double bestdot = -1e100;\n                static const int vx[4] = {0,-1,0,1};\n                static const int vy[4] = {-1,0,1,0}; // (i increases down), (j increases right). Our directions are L(0): (0,-1), U(1):(-1,0), R(2):(0,1), D(3):(1,0)\n                for(int d=0; d<4; ++d){\n                    double dot = ti*vx[d] + tj*vy[d];\n                    if(dot > bestdot){ bestdot=dot; bestd=d; }\n                }\n                for(int d=0; d<4; ++d){\n                    desired_to[i][j][d] = bestd;\n                }\n            }\n        }\n    }\n\n    int tile_local_score(int i,int j,int rot){\n        int sc = 0;\n        for(int d=0; d<4; ++d){\n            int e = to_rot[t[i][j]][rot][d];\n            if(e==-1){ sc -= 2; continue; }\n            if(e == desired_to[i][j][d]) sc += 1;\n            int ni = i + di4[e], nj = j + dj4[e];\n            if(ni<0||ni>=H||nj<0||nj>=W) sc -= 3;\n        }\n        return sc;\n    }\n\n    void initial_assignment() {\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                int bestRot=0, bestSc = INT_MIN;\n                for(int rot=0; rot<4; ++rot){\n                    int sc = tile_local_score(i,j,rot);\n                    if(sc > bestSc){\n                        bestSc = sc; bestRot = rot;\n                    }\n                }\n                r[i][j] = bestRot;\n            }\n        }\n    }\n\n    // Check if the edge between (i,j) and (i+di[d], j+dj[d]) is matched (undirected) under current r\n    inline int edge_match_at(int i,int j,int d) {\n        int ni = i + di4[d], nj = j + dj4[d];\n        if(ni<0||ni>=H||nj<0||nj>=W) return 0;\n        int Ato = to_rot[t[i][j]][r[i][j]][(d+2)&3];\n        if(Ato != d) return 0;\n        int Bd = (d+2)&3;\n        int Bto = to_rot[t[ni][nj]][r[ni][nj]][Bd];\n        if(Bto != Bd) return 0;\n        return 1;\n    }\n\n    int compute_proxy_score() {\n        int total = 0;\n        // horizontal edges\n        for(int i=0;i<H;++i){\n            for(int j=0;j+1<W;++j){\n                // edge (i,j) -- (i,j+1) corresponds to dir R from left cell (2)\n                total += edge_match_at(i,j,2);\n            }\n        }\n        // vertical edges\n        for(int i=0;i+1<H;++i){\n            for(int j=0;j<W;++j){\n                // edge (i,j) -- (i+1,j) corresponds to dir D from top cell (3)\n                total += edge_match_at(i,j,3);\n            }\n        }\n        return total;\n    }\n\n    // delta proxy for changing r[i][j] to newRot: recompute only edges touching (i,j) and neighbor reciprocity\n    int local_proxy_contrib_cell(int i,int j){\n        int sum=0;\n        // left edge if j>0 is counted at (i,j-1, R)\n        if(j>0) sum += edge_match_at(i,j-1,2);\n        // right edge if j<W-1 at (i,j, R)\n        if(j<W-1) sum += edge_match_at(i,j,2);\n        // up edge if i>0 at (i-1,j, D)\n        if(i>0) sum += edge_match_at(i-1,j,3);\n        // down edge if i<H-1 at (i,j, D)\n        if(i<H-1) sum += edge_match_at(i,j,3);\n        return sum;\n    }\n\n    // Compute lengths of all cycles (using the directed state graph (i,j,d))\n    pair<int,int> compute_top2_loops() {\n        // visited states: -1 unvisited, >=0 timestamp or component id\n        // We can simply do standard functional graph cycle detection by stepping, but we need to start from all states.\n        vector<vector<array<char,4>>> vis(H, vector<array<char,4>>(W, {0,0,0,0}));\n        int best1=0, best2=0;\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                for(int d=0; d<4; ++d){\n                    if(vis[i][j][d]) continue;\n                    // follow path\n                    int si=i, sj=j, sd=d;\n                    int ci=i, cj=j, cd=d;\n                    int steps=0;\n                    unordered_map<long long,int> seen; seen.reserve(32);\n                    while(true){\n                        if(vis[ci][cj][cd]){ // already processed; no new cycle counted\n                            // mark visited along this walk\n                            ci=si; cj=sj; cd=sd;\n                            while(true){\n                                if(vis[ci][cj][cd]) break;\n                                vis[ci][cj][cd] = 1;\n                                int e = to_rot[t[ci][cj]][r[ci][cj]][cd];\n                                if(e==-1) break;\n                                int ni = ci + di4[e], nj = cj + dj4[e];\n                                if(ni<0||ni>=H||nj<0||nj>=W) break;\n                                int nd = (e+2)&3;\n                                ci=ni; cj=nj; cd=nd;\n                                if(ci==si && cj==sj && cd==sd) break;\n                            }\n                            break;\n                        }\n                        // step\n                        long long key = (((long long)ci*W + cj)<<2) | cd;\n                        if(seen.find(key)!=seen.end()){\n                            int cyc_start = seen[key];\n                            int cyc_len = steps - cyc_start;\n                            // update best two\n                            if(cyc_len >= best1){ best2=best1; best1=cyc_len; }\n                            else if(cyc_len > best2){ best2=cyc_len; }\n                            // mark visited\n                            ci=si; cj=sj; cd=sd;\n                            while(true){\n                                if(vis[ci][cj][cd]) break;\n                                vis[ci][cj][cd]=1;\n                                int e = to_rot[t[ci][cj]][r[ci][cj]][cd];\n                                if(e==-1) break;\n                                int ni = ci + di4[e], nj = cj + dj4[e];\n                                if(ni<0||ni>=H||nj<0||nj>=W) break;\n                                int nd = (e+2)&3;\n                                ci=ni; cj=nj; cd=nd;\n                                if(ci==si && cj==sj && cd==sd) break;\n                            }\n                            break;\n                        }\n                        seen.emplace(key, steps);\n                        int e = to_rot[t[ci][cj]][r[ci][cj]][cd];\n                        if(e==-1){\n                            // mark visited along the walk\n                            ci=si; cj=sj; cd=sd;\n                            while(true){\n                                if(vis[ci][cj][cd]) break;\n                                vis[ci][cj][cd]=1;\n                                int e2 = to_rot[t[ci][cj]][r[ci][cj]][cd];\n                                if(e2==-1) break;\n                                int ni = ci + di4[e2], nj = cj + dj4[e2];\n                                if(ni<0||ni>=H||nj<0||nj>=W) break;\n                                int nd = (e2+2)&3;\n                                ci=ni; cj=nj; cd=nd;\n                                if(ci==si && cj==sj && cd==sd) break;\n                            }\n                            break;\n                        }\n                        int ni = ci + di4[e], nj = cj + dj4[e];\n                        if(ni<0||ni>=H||nj<0||nj>=W){\n                            // mark visited along the walk\n                            ci=si; cj=sj; cd=sd;\n                            while(true){\n                                if(vis[ci][cj][cd]) break;\n                                vis[ci][cj][cd]=1;\n                                int e2 = to_rot[t[ci][cj]][r[ci][cj]][cd];\n                                if(e2==-1) break;\n                                int nni = ci + di4[e2], nnj = cj + dj4[e2];\n                                if(nni<0||nni>=H||nnj<0||nnj>=W) break;\n                                int nd = (e2+2)&3;\n                                ci=nni; cj=nnj; cd=nd;\n                                if(ci==si && cj==sj && cd==sd) break;\n                            }\n                            break;\n                        }\n                        ci=ni; cj=nj; cd=(e+2)&3;\n                        steps++;\n                    }\n                }\n            }\n        }\n        return {best1,best2};\n    }\n\n    void solve() {\n        precompute_to_rot();\n        read_input();\n        build_desired();\n        initial_assignment();\n\n        // compute initial proxy and best\n        proxyScore = compute_proxy_score();\n        best_r = r;\n        auto top2 = compute_top2_loops();\n        long long bestScore = 1LL*top2.first*top2.second;\n\n        // Simulated annealing / hill climb\n        std::mt19937 rng(712367);\n        auto start = chrono::high_resolution_clock::now();\n        const double TIME_LIMIT = 1.95; // seconds\n        int iter=0, accepted=0;\n        while(true){\n            iter++;\n            if((iter & 0x3FFF)==0){\n                auto now = chrono::high_resolution_clock::now();\n                double t = chrono::duration<double>(now - start).count();\n                if(t > TIME_LIMIT) break;\n            }\n            int i = rng()%H;\n            int j = rng()%W;\n            int cur = r[i][j];\n            int before = local_proxy_contrib_cell(i,j);\n            int bestRot = cur;\n            int bestLocal = before;\n            for(int rot=0; rot<4; ++rot){\n                if(rot==cur) continue;\n                int old = r[i][j];\n                r[i][j] = rot;\n                int after = local_proxy_contrib_cell(i,j);\n                if(after > bestLocal){\n                    bestLocal = after; bestRot = rot;\n                }\n                r[i][j] = old;\n            }\n            int gain = bestLocal - before;\n            bool take = false;\n            if(gain > 0) take = true;\n            else {\n                // mild SA\n                double temp = 0.5; // constant small temperature\n                double prob = exp(gain / max(1.0, temp));\n                uniform_real_distribution<double> urd(0.0,1.0);\n                if(urd(rng) < prob) take = true;\n            }\n            if(take){\n                r[i][j] = bestRot;\n                proxyScore += gain;\n                accepted++;\n                if((accepted % 500)==0){\n                    // Evaluate exact\n                    auto p = compute_top2_loops();\n                    long long sc = 1LL*p.first*p.second;\n                    if(sc > bestScore){\n                        bestScore = sc;\n                        best_r = r;\n                    }\n                }\n            }\n        }\n        // Final evaluation checkpoint\n        auto p = compute_top2_loops();\n        long long sc = 1LL*p.first*p.second;\n        if(sc > bestScore){\n            bestScore = sc;\n            best_r = r;\n        }\n\n        // Output best rotations as a single line of 900 digits\n        string out; out.reserve(H*W);\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                out.push_back(char('0' + (best_r[i][j] & 3)));\n            }\n        }\n        cout << out << \"\\n\";\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver s;\n    s.solve();\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction masks: bit 0=left(1), bit1=up(2), bit2=right(4), bit3=down(8)\nstatic inline bool matchLR(int a, int b){ // a right with b left\n    return (a & 4) && (b & 1);\n}\nstatic inline bool matchUD(int a, int b){ // a down with b up\n    return (a & 8) && (b & 2);\n}\n\nstruct RNG {\n    uint64_t x;\n    RNG(uint64_t seed=712367821) : x(seed) {}\n    uint32_t next() { x ^= x<<7; x ^= x>>9; return (uint32_t)x; }\n    int randint(int l, int r){ return l + (int)(next() % (uint32_t)(r-l+1)); }\n    bool prob(double p){ return (next() / (double)UINT32_MAX) < p; }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; int Tlimit;\n    if(!(cin>>N>>Tlimit)) {\n        return 0;\n    }\n    vector<string> rows(N);\n    for(int i=0;i<N;i++) cin>>rows[i];\n    vector<int> a(N*N);\n    int emptyPos=-1;\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            char c = rows[i][j];\n            int v;\n            if(c>='0' && c<='9') v = c-'0';\n            else v = 10 + (c-'a');\n            a[i*N+j]=v;\n            if(v==0) emptyPos=i*N+j;\n        }\n    }\n\n    RNG rng(123456789 ^ (uint64_t)chrono::high_resolution_clock::now().time_since_epoch().count());\n\n    auto inb = [&](int r,int c){ return r>=0 && r<N && c>=0 && c<N; };\n\n    // Precompute adjacency matched array\n    // horiz[i][j] is match between (i,j) and (i,j+1)\n    vector<char> horiz(N*(N-1),0), vert((N-1)*N,0);\n    auto idxH = [&](int i,int j){ return i*(N-1)+j; };\n    auto idxV = [&](int i,int j){ return i*N+j; };\n\n    auto recompute_local_edges = [&](int r,int c){\n        // Update matches around (r,c): edges to left/right/up/down if exist\n        int p = r*N+c;\n        if(a[p]==0){\n            // empty contributes no edges, but neighbors matching is only defined on non-empty squares\n            // However matched edges definition is between non-empty squares; empty breaks edges.\n        }\n        // Horizontal edges with (r,c-1)-(r,c) and (r,c)-(r,c+1)\n        if(c-1>=0){\n            int L = a[r*N+(c-1)], Rv = a[r*N+c];\n            horiz[idxH(r,c-1)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n        if(c<N-1){\n            int L = a[r*N+c], Rv = a[r*N+(c+1)];\n            horiz[idxH(r,c)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n        // Vertical edges with (r-1,c)-(r,c) and (r,c)-(r+1,c)\n        if(r-1>=0){\n            int U = a[(r-1)*N+c], Dv = a[r*N+c];\n            vert[idxV(r-1,c)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n        if(r<N-1){\n            int U = a[r*N+c], Dv = a[(r+1)*N+c];\n            vert[idxV(r,c)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n    };\n    // Initialize all matches\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N-1;j++){\n            int L=a[i*N+j], Rv=a[i*N+j+1];\n            horiz[idxH(i,j)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n    }\n    for(int i=0;i<N-1;i++){\n        for(int j=0;j<N;j++){\n            int U=a[i*N+j], Dv=a[(i+1)*N+j];\n            vert[idxV(i,j)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n    }\n    auto totalE = [&](){\n        int s=0;\n        for(char v: horiz) s+=v;\n        for(char v: vert) s+=v;\n        return s;\n    };\n    int E = totalE();\n\n    // Helpers to compute local delta for a tentative swap between empty at (er,ec) and neighbor (nr,nc)\n    auto delta_for_move = [&](int er,int ec,int nr,int nc)->int{\n        // collect set of affected edges indices before and after; easiest is to sum contributions around the two cells\n        int before=0, after=0;\n        auto add_edges = [&](int r,int c,int &acc){\n            if(c-1>=0) acc += horiz[idxH(r,c-1)];\n            if(c<N-1) acc += horiz[idxH(r,c)];\n            if(r-1>=0) acc += vert[idxV(r-1,c)];\n            if(r<N-1) acc += vert[idxV(r,c)];\n        };\n        add_edges(er,ec,before);\n        add_edges(nr,nc,before);\n\n        // simulate swap\n        int pe = er*N+ec, pn = nr*N+nc;\n        int ve = a[pe], vn = a[pn]; // ve == 0\n        // Temporarily swap in thought: a'[pe]=vn, a'[pn]=0\n        // compute edges after by recomputing these positions\u2019 edges on the fly\n        auto contrib_cell = [&](int r,int c, int val_at_rc)->int{\n            int s=0;\n            // left edge (r,c-1)-(r,c)\n            if(c-1>=0){\n                int L = (r*N + c-1 == pe ? vn : (r*N + c-1 == pn ? 0 : a[r*N + c-1]));\n                int Rv = val_at_rc;\n                s += (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n            }\n            // right edge (r,c)-(r,c+1)\n            if(c<N-1){\n                int L = val_at_rc;\n                int Rv = (r*N + c+1 == pe ? vn : (r*N + c+1 == pn ? 0 : a[r*N + c+1]));\n                s += (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n            }\n            // up edge (r-1,c)-(r,c)\n            if(r-1>=0){\n                int U = ( (r-1)*N + c == pe ? vn : ((r-1)*N + c == pn ? 0 : a[(r-1)*N + c]) );\n                int Dv = val_at_rc;\n                s += (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n            }\n            // down edge (r,c)-(r+1,c)\n            if(r<N-1){\n                int U = val_at_rc;\n                int Dv = ( (r+1)*N + c == pe ? vn : ((r+1)*N + c == pn ? 0 : a[(r+1)*N + c]) );\n                s += (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n            }\n            return s;\n        };\n        after += contrib_cell(er,ec, vn);\n        after += contrib_cell(nr,nc, 0);\n        return after - before;\n    };\n\n    string moves;\n    moves.reserve(Tlimit);\n\n    // Direction arrays\n    const int dr[4]={-1,1,0,0};\n    const int dc[4]={0,0,-1,1};\n    const char dch[4] = {'U','D','L','R'};\n    const int revdir[4] = {1,0,3,2};\n\n    int er = emptyPos / N, ec = emptyPos % N;\n    int last_dir = -1;\n\n    auto apply_move = [&](int dir){\n        int nr = er + dr[dir], nc = ec + dc[dir];\n        // compute delta and apply\n        int pe = er*N+ec, pn = nr*N+nc;\n        int delta = 0;\n        // remove before from E by recomputing local, then recompute after with actual update and patch horiz/vert\n        // For robustness, compute delta via delta_for_move\n        delta = delta_for_move(er,ec,nr,nc);\n        // swap\n        swap(a[pe], a[pn]);\n        // update local edges arrays around affected cells (and neighbors; recompute around both cells)\n        recompute_local_edges(er,ec);\n        recompute_local_edges(nr,nc);\n        E += delta;\n        er = nr; ec = nc;\n        moves.push_back(dch[dir]);\n        last_dir = dir;\n    };\n\n    // Main loop: up to Tlimit moves or time\n    auto t_start = chrono::high_resolution_clock::now();\n    double time_limit_ms = 2800.0;\n\n    for(int step=0; step<Tlimit; ++step){\n        // time guard\n        if((step & 255) == 0){\n            auto now = chrono::high_resolution_clock::now();\n            double ms = chrono::duration<double, milli>(now - t_start).count();\n            if(ms > time_limit_ms) break;\n        }\n        // evaluate candidates\n        struct Cand{ int dir; int delta; int tie; };\n        vector<Cand> cands;\n        for(int d=0; d<4; d++){\n            int nr = er + dr[d], nc = ec + dc[d];\n            if(!inb(nr,nc)) continue;\n            if(last_dir != -1 && revdir[d]==last_dir){\n                // consider but downweight; we'll keep it but mark tie worse unless strictly good\n            }\n            int del = delta_for_move(er,ec,nr,nc);\n            int tie = 0;\n            // tie-breaker: prefer central positions for the empty after move\n            int cen_bias = - (abs((N-1)/2 - nr) + abs((N-1)/2 - nc));\n            tie += cen_bias;\n            // small random jitter\n            tie += rng.randint(-2,2);\n            cands.push_back({d, del, tie});\n        }\n        if(cands.empty()) break;\n        // choose best\n        sort(cands.begin(), cands.end(), [&](const Cand& A, const Cand& B){\n            if(A.delta != B.delta) return A.delta > B.delta;\n            return A.tie > B.tie;\n        });\n        int chosen = 0;\n        // If best delta <= 0, allow some randomness to escape local minima\n        if(cands[0].delta <= 0){\n            // with small probability pick a random candidate\n            if(rng.prob(0.15)){\n                chosen = rng.randint(0, (int)cands.size()-1);\n            }else{\n                // avoid immediate reversal if not improving\n                if(last_dir != -1 && revdir[cands[0].dir]==last_dir && cands.size()>=2){\n                    if(cands[1].delta == cands[0].delta || rng.prob(0.5)) chosen = 1;\n                }\n            }\n        }else{\n            // improving move, but avoid immediate reversal when tie\n            if(last_dir != -1 && revdir[cands[0].dir]==last_dir && cands.size()>=2 && cands[1].delta==cands[0].delta){\n                if(rng.prob(0.5)) chosen = 1;\n            }\n        }\n        apply_move(cands[chosen].dir);\n    }\n\n    // Output\n    cout<<moves<<\"\\n\";\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Sig {\n    uint64_t a=0, b=0;\n    bool operator==(Sig const& o) const { return a==o.a && b==o.b; }\n};\nstruct SigHash {\n    size_t operator()(Sig const& s) const noexcept {\n        uint64_t x = s.a * 0x9E3779B97F4A7C15ULL ^ (s.b + 0x9E3779B97F4A7C15ULL + (s.a<<6) + (s.a>>2));\n        return (size_t)x;\n    }\n};\n\nstruct LineParam {\n    // Integer normal (A,B) with gcd=1, threshold T between projections.\n    int A, B;\n    long long T;\n};\n\nstruct Point { int x,y; };\n\nstatic inline long long dotAB(int A,int B,int x,int y){ return (long long)A*x + (long long)B*y; }\n\nstatic long long egcd(long long a, long long b, long long &x, long long &y){\n    if(b==0){ x = (a>=0?1:-1); y=0; return llabs(a); }\n    long long x1,y1;\n    long long g = egcd(b, a%b, x1, y1);\n    x = y1;\n    y = x1 - (a/b) * y1;\n    return g;\n}\n\nstatic pair<long long,long long> line_two_points(int A,int B,long long T){\n    // Find integer solution to A*x + B*y = T, with gcd(A,B)=1.\n    long long x0,y0;\n    long long g = egcd(A,B,x0,y0);\n    // g should be 1 or -1; adjust\n    if(g < 0){ g = -g; x0 = -x0; y0 = -y0; }\n    // Ensure T divisible by g (it is since g=1).\n    long long mul = T / g;\n    __int128 xi = (__int128)x0 * mul;\n    __int128 yi = (__int128)y0 * mul;\n    long long x = (long long)xi;\n    long long y = (long long)yi;\n    // Generate second point by adding k*(B, -A).\n    // Choose k so both points within [-1e9,1e9].\n    auto inb = [](long long v){ return v>=-1000000000LL && v<=1000000000LL; };\n    long long k = 1000000; // large separation\n    // Clamp k by bounds\n    auto clamp_k = [&](long long x,long long y)->long long{\n        // Need to keep |x + B*k| <= 1e9 and |y - A*k| <= 1e9\n        long long k1 = k;\n        // reduce if exceeding\n        auto fit = [&](long long &kref){\n            if(B!=0){\n                // compute max |k| bound for x\n                long double maxdx = (1000000000.0L - fabsl((long double)x)) / fabsl((long double)B);\n                kref = min<long long>(kref, (long long)maxdx);\n            }\n            if(A!=0){\n                long double maxdy = (1000000000.0L - fabsl((long double)y)) / fabsl((long double)A);\n                kref = min<long long>(kref, (long long)maxdy);\n            }\n            if(kref<=0) kref=1;\n        };\n        fit(k1);\n        return max(1LL, k1);\n    };\n    long long kk = clamp_k(x,y);\n    long long x2 = x + (long long)B * kk;\n    long long y2 = y - (long long)A * kk;\n    // Ensure first point also in bounds; if not, adjust by shifting k to move closer to zero\n    if(!inb(x) || !inb(y)){\n        // adjust by shifting with k to bring closer\n        long long kshift = 0;\n        if(B!=0) kshift = -x / B;\n        // try some kshift values\n        for(long long u = kshift-5; u<=kshift+5; ++u){\n            long long xt = x + (long long)B * u;\n            long long yt = y - (long long)A * u;\n            if(inb(xt) && inb(yt)){ x=xt; y=yt; break; }\n        }\n    }\n    // If still out of bounds, clamp to +/-1e9 by choosing big k\n    if(!inb(x) || !inb(y)){\n        // Fallback to simple two points using parameter with kk\n        // set base near origin by taking k bringing to origin-ish\n        long long k0 = 0;\n        if(B!=0) k0 = -x / B;\n        x = x + (long long)B * k0;\n        y = y - (long long)A * k0;\n        if(!inb(x) || !inb(y)){\n            // fallback set x=0 solution: if B divides T\n            if(B!=0){\n                if(T % B == 0){\n                    y = T / B; x = 0;\n                }else{\n                    // set y=0 solution if A divides T\n                    if(A!=0 && T % A == 0){\n                        x = T / A; y = 0;\n                    }else{\n                        // leave as is; values should still be small given small A,B,T\n                    }\n                }\n            }\n        }\n    }\n    // recompute second point after possibly changed x,y\n    kk = 1;\n    long long x3 = x + (long long)B * kk;\n    long long y3 = y - (long long)A * kk;\n    // Final ensure distinct\n    if(x3==x && y3==y){\n        kk = 2;\n        x3 = x + (long long)B * kk;\n        y3 = y - (long long)A * kk;\n    }\n    // Clip to bounds if needed\n    auto clip = [](long long v){\n        if(v < -1000000000LL) return -1000000000LL;\n        if(v > 1000000000LL) return 1000000000LL;\n        return v;\n    };\n    x = clip(x); y = clip(y);\n    x3 = clip(x3); y3 = clip(y3);\n    return {x, y}; // We'll output both points: (x,y) and (x3,y3)\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, K;\n    if(!(cin>>N>>K)) return 0;\n    vector<int> a(11);\n    for(int d=1; d<=10; ++d) cin>>a[d];\n    vector<Point> pts(N);\n    for(int i=0;i<N;++i){ cin>>pts[i].x>>pts[i].y; }\n\n    // Predefine normals (A,B), coprime pairs\n    vector<pair<int,int>> normals = {\n        {1,0},{0,1},{1,1},{1,-1},{2,1},{1,2},{2,-1},{1,-2},\n        {3,1},{1,3},{3,2},{2,3},{3,-1},{1,-3},{3,-2},{2,-3}\n    };\n    auto reduce_gcd = [](int &A,int &B){\n        if(A==0 && B==0){ A=1; B=0; return; }\n        if(A==0){ B = (B>0?1:-1); return; }\n        if(B==0){ A = (A>0?1:-1); return; }\n        int g = std::gcd(abs(A),abs(B));\n        A/=g; B/=g;\n        if(A<0){ A=-A; B=-B; }\n        else if(A==0 && B<0){ B=-B; }\n    };\n    for(auto &p : normals){ reduce_gcd(p.first, p.second); }\n    // Remove duplicates\n    sort(normals.begin(), normals.end());\n    normals.erase(unique(normals.begin(), normals.end()), normals.end());\n\n    // Signatures\n    vector<Sig> sig(N);\n    vector<LineParam> lines;\n    lines.reserve(K);\n\n    // Helper to compute b_d from current signatures\n    auto compute_bd = [&](vector<int>& bd, unordered_map<Sig, vector<int>, SigHash>& cells){\n        cells.clear();\n        cells.reserve(N*2);\n        for(int i=0;i<N;++i) cells[sig[i]].push_back(i);\n        fill(bd.begin(), bd.end(), 0);\n        for(auto &kv : cells){\n            int s = (int)kv.second.size();\n            if(s<=10) bd[s]++;\n        }\n    };\n\n    vector<int> bd(11,0);\n    unordered_map<Sig, vector<int>, SigHash> cells;\n    compute_bd(bd, cells);\n\n    int cutsLeft = K;\n    // Main loop\n    while(cutsLeft > 0){\n        // Needs\n        vector<int> need(11,0);\n        bool anyNeed = false;\n        for(int d=1; d<=10; ++d){ need[d] = max(0, a[d] - bd[d]); if(need[d]>0) anyNeed=true; }\n        // Select candidate cells: top by size\n        vector<pair<int, Sig>> candidates; // (size, sig)\n        candidates.reserve(cells.size());\n        for(auto &kv : cells){\n            candidates.emplace_back((int)kv.second.size(), kv.first);\n        }\n        sort(candidates.begin(), candidates.end(), [](auto &l, auto &r){ return l.first>r.first; });\n        if(candidates.empty()) break;\n        int consider = min<int>((int)candidates.size(), 8);\n\n        long long bestDelta = LLONG_MIN;\n        LineParam bestLine{0,0,0};\n        bool found = false;\n\n        for(int ci=0; ci<consider; ++ci){\n            int s = candidates[ci].first;\n            Sig ss = candidates[ci].second;\n            auto &idxs = cells[ss];\n            if(s <= 1){ continue; }\n            // If we already need this size heavily and s<=10, maybe skip splitting it unless no other choices\n            if(s <= 10 && need[s] > 0 && ci >= 2) {\n                // keep some resistance to splitting needed sizes unless not in top 2\n                continue;\n            }\n            // Pre-collect points\n            vector<long long> proj;\n            proj.reserve(s);\n\n            // For each normal\n            for(auto [A,B] : normals){\n                proj.clear();\n                proj.resize(s);\n                for(int i=0;i<s;++i){\n                    const auto &p = pts[idxs[i]];\n                    proj[i] = dotAB(A,B,p.x,p.y);\n                }\n                // Sort and keep sorted with original indices not needed because we only need counts\n                sort(proj.begin(), proj.end());\n                // Prepare candidate cut positions\n                // Prefer splits to sizes close to demand. We'll choose a set of target left sizes Lcand.\n                vector<int> Lcand;\n                // median split\n                Lcand.push_back(s/2);\n                // aim for most needed d\n                int bestd=1, bestNeed=0;\n                for(int d=1; d<=10; ++d){ if(need[d]>bestNeed){ bestNeed=need[d]; bestd=d; } }\n                if(bestNeed>0) Lcand.push_back(bestd);\n                // neighbors\n                if(bestd+1 < s) Lcand.push_back(bestd+1);\n                if(bestd>1) Lcand.push_back(bestd-1);\n                // ensure within [1..s-1]\n                for(int &v: Lcand){ if(v<1) v=1; if(v>s-1) v=s-1; }\n                // dedup\n                sort(Lcand.begin(), Lcand.end());\n                Lcand.erase(unique(Lcand.begin(), Lcand.end()), Lcand.end());\n\n                // For each target count l, choose the cut between positions l-1 and l (0-index)\n                for(int l : Lcand){\n                    int i = l-1;\n                    if(i<0 || i+1>=s) continue;\n                    long long vL = proj[i];\n                    long long vR = proj[i+1];\n                    if(vL == vR){\n                        // if duplicates at border, we can move to nearest gap by expanding\n                        int il=i, ir=i+1;\n                        while(il>=0 && proj[il]==vL) --il;\n                        while(ir<s && proj[ir]==vR) ++ir;\n                        if(il>=0 && ir<s){\n                            // choose side closer to target l\n                            int leftCountOption = il+1;\n                            int rightCountOption = s - (ir);\n                            // pick the one closer to l\n                            int l1 = leftCountOption;\n                            int l2 = il+1 + (ir - (i+1)); // not meaningful; fallback: skip\n                            // Instead, move to il (gap between il and il+1)\n                            if(il>=0){\n                                vL = proj[il]; vR = proj[il+1];\n                                l = il+1;\n                            }else if(ir<s-1){\n                                vL = proj[ir-1]; vR = proj[ir];\n                                l = ir;\n                            }else{\n                                continue;\n                            }\n                        }else{\n                            continue;\n                        }\n                    }\n                    long long T = (vL + vR) / 2; // strictly between since integers and vL<vR\n                    int leftSize = l;\n                    int rightSize = s - l;\n                    // compute delta using current bd\n                    auto calc_min = [&](int d, int b){ return min(a[d], b); };\n                    long long delta = 0;\n                    if(leftSize<=10){\n                        delta += calc_min(leftSize, bd[leftSize]+1) - calc_min(leftSize, bd[leftSize]);\n                    }\n                    if(rightSize<=10){\n                        delta += calc_min(rightSize, bd[rightSize]+1) - calc_min(rightSize, bd[rightSize]);\n                    }\n                    if(s<=10){\n                        delta += calc_min(s, bd[s]-1) - calc_min(s, bd[s]);\n                    }\n                    // tie-break: prefer creating smaller max piece\n                    long long balanceScore = - llabs(leftSize - rightSize);\n                    long long score = (delta<<20) + balanceScore; // weight delta strongly\n                    if(score > bestDelta){\n                        bestDelta = score;\n                        bestLine = {A,B,T};\n                        found = true;\n                    }\n                }\n            }\n        }\n\n        if(!found){\n            // Fallback: simple median split of largest cell with A,B=(1,0)\n            auto &idxs = cells[candidates[0].second];\n            int s = (int)idxs.size();\n            vector<long long> proj(s);\n            int A=1,B=0;\n            for(int i=0;i<s;++i) proj[i] = pts[idxs[i]].x;\n            sort(proj.begin(), proj.end());\n            long long T = (proj[s/2 - 1] + proj[s/2]) / 2;\n            bestLine = {A,B,T};\n        }\n\n        // Commit line\n        int m = (int)lines.size();\n        lines.push_back(bestLine);\n        // Update signatures and bd/cells\n        int bitIndex = m; // 0-based\n        for(int i=0;i<N;++i){\n            long long v = dotAB(bestLine.A, bestLine.B, pts[i].x, pts[i].y);\n            bool left = (v <= bestLine.T);\n            if(bitIndex < 64){\n                if(left) sig[i].a |= (1ULL<<bitIndex);\n            }else{\n                int bi = bitIndex-64;\n                if(left) sig[i].b |= (1ULL<<bi);\n            }\n        }\n        compute_bd(bd, cells);\n        cutsLeft--;\n        // Early stop if no more need improvements possible with remaining large cells\n        bool allSizesSatisfied = true;\n        for(int d=1; d<=10; ++d) if(a[d] > bd[d]) { allSizesSatisfied=false; break; }\n        if(allSizesSatisfied) break;\n    }\n\n    // Output lines converted to two integer points each\n    cout << (int)lines.size() << \"\\n\";\n    for(auto &L : lines){\n        // Get two points\n        long long x0,y0;\n        long long xa, ya;\n        // get base solution and a second point\n        long long x1,y1;\n        {\n            long long xx, yy;\n            long long g = egcd(L.A, L.B, xx, yy);\n            if(g<0){ g=-g; xx=-xx; yy=-yy; }\n            long long mul = L.T / g;\n            x0 = xx * mul;\n            y0 = yy * mul;\n            long long kk = 100000; // moderate\n            x1 = x0 + (long long)L.B * kk;\n            y1 = y0 - (long long)L.A * kk;\n            auto clip = [](long long v){\n                if(v < -1000000000LL) return -1000000000LL;\n                if(v > 1000000000LL) return 1000000000LL;\n                return v;\n            };\n            x0 = clip(x0); y0 = clip(y0);\n            x1 = clip(x1); y1 = clip(y1);\n            if(x1==x0 && y1==y0){\n                kk = 1;\n                x1 = x0 + (long long)L.B * kk;\n                y1 = y0 - (long long)L.A * kk;\n                x1 = clip(x1); y1 = clip(y1);\n            }\n        }\n        cout << x0 << \" \" << y0 << \" \" << x1 << \" \" << y1 << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct P { int x,y; };\n\nstatic inline int64_t w_of(int x,int y,int c){\n    int dx=x-c, dy=y-c;\n    return int64_t(dx)*dx + int64_t(dy)*dy + 1;\n}\n\nstruct Candidate{\n    // rectangle in order: p1=new point, then others around perimeter\n    P p1,p2,p3,p4;\n    int64_t score;\n};\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    vector<P> init(M);\n    for(int i=0;i<M;i++){ cin>>init[i].x>>init[i].y; }\n    int c=(N-1)/2;\n\n    // Occupancy grid\n    vector<vector<char>> occ(N, vector<char>(N, 0));\n    for(auto &p:init) occ[p.x][p.y]=1;\n\n    // Edge usage: used horizontal edges H[y][x] for (x,y)-(x+1,y), x in [0..N-2], y in [0..N-1]\n    vector<vector<char>> usedH(N, vector<char>(N-1, 0));\n    // Vertical edges V[x][y] for (x,y)-(x,y+1), x in [0..N-1], y in [0..N-2]\n    vector<vector<char>> usedV(N, vector<char>(N-1, 0));\n    // We skip diagonal edges in this baseline.\n\n    // Maintain list of occupied points per row/col for faster enumeration\n    vector<vector<int>> rows(N), cols(N);\n    auto rebuild_index = [&](){\n        for(int y=0;y<N;y++){ rows[y].clear(); }\n        for(int x=0;x<N;x++){ cols[x].clear(); }\n        for(int x=0;x<N;x++) for(int y=0;y<N;y++) if(occ[x][y]){\n            rows[y].push_back(x);\n            cols[x].push_back(y);\n        }\n        for(int y=0;y<N;y++) sort(rows[y].begin(), rows[y].end());\n        for(int x=0;x<N;x++) sort(cols[x].begin(), cols[x].end());\n    };\n    rebuild_index();\n\n    auto perimeter_edges_free_and_mark = [&](const P& a,const P& b,const P& c,const P& d, bool mark)->bool{\n        // axis-aligned rectangle with corners a,b,c,d in order around\n        // Iterate unit edges on each side and check used arrays\n        auto check_edge = [&](int x1,int y1,int x2,int y2)->bool{\n            if(x1==x2){\n                int x=x1;\n                int ylo=min(y1,y2), yhi=max(y1,y2);\n                for(int y=ylo; y<yhi; y++){\n                    if(usedV[x][y]) return false;\n                }\n            }else if(y1==y2){\n                int y=y1;\n                int xlo=min(x1,x2), xhi=max(x1,x2);\n                for(int x=xlo; x<xhi; x++){\n                    if(usedH[y][x]) return false;\n                }\n            }else{\n                // not axis aligned\n                return false;\n            }\n            return true;\n        };\n        if(!check_edge(a.x,a.y,b.x,b.y)) return false;\n        if(!check_edge(b.x,b.y,c.x,c.y)) return false;\n        if(!check_edge(c.x,c.y,d.x,d.y)) return false;\n        if(!check_edge(d.x,d.y,a.x,a.y)) return false;\n        if(mark){\n            auto mark_edge = [&](int x1,int y1,int x2,int y2){\n                if(x1==x2){\n                    int x=x1;\n                    int ylo=min(y1,y2), yhi=max(y1,y2);\n                    for(int y=ylo; y<yhi; y++) usedV[x][y]=1;\n                }else{\n                    int y=y1;\n                    int xlo=min(x1,x2), xhi=max(x1,x2);\n                    for(int x=xlo; x<xhi; x++) usedH[y][x]=1;\n                }\n            };\n            mark_edge(a.x,a.y,b.x,b.y);\n            mark_edge(b.x,b.y,c.x,c.y);\n            mark_edge(c.x,c.y,d.x,d.y);\n            mark_edge(d.x,d.y,a.x,a.y);\n        }\n        return true;\n    };\n\n    auto perimeter_points_clean = [&](const P& a,const P& b,const P& c,const P& d)->bool{\n        // iterate lattice points along sides; allow exactly the three existing corners among perimeter points; new corner a must be empty initially.\n        // We assume axis-aligned rectangle with sides parallel to axes.\n        auto ok_line = [&](int x1,int y1,int x2,int y2)->bool{\n            if(x1==x2){\n                int x=x1;\n                int ylo=min(y1,y2), yhi=max(y1,y2);\n                for(int y=ylo; y<=yhi; y++){\n                    if((x==a.x && y==a.y) || (x==b.x && y==b.y) || (x==c.x && y==c.y) || (x==d.x && y==d.y)) continue;\n                    if(occ[x][y]) return false;\n                }\n            }else{\n                int y=y1;\n                int xlo=min(x1,x2), xhi=max(x1,x2);\n                for(int x=xlo; x<=xhi; x++){\n                    if((x==a.x && y==a.y) || (x==b.x && y==b.y) || (x==c.x && y==c.y) || (x==d.x && y==d.y)) continue;\n                    if(occ[x][y]) return false;\n                }\n            }\n            return true;\n        };\n        if(!ok_line(a.x,a.y,b.x,b.y)) return false;\n        if(!ok_line(b.x,b.y,c.x,c.y)) return false;\n        if(!ok_line(c.x,c.y,d.x,d.y)) return false;\n        if(!ok_line(d.x,d.y(a.x),(a.y))) return false; // fix after writing\n        return true;\n    };\n\n    // The previous lambda had a minor syntactic issue; we will implement perimeter_points_clean inline later.\n\n    // Candidate generation full enumeration (axis-aligned):\n    auto build_candidates = [&](vector<Candidate>& out){\n        out.clear();\n        // For performance, cap number of candidates\n        const size_t CAP = 40000;\n        // Enumerate pivot B over all occupied\n        for(int xb=0; xb<N; xb++){\n            for(int yb=0; yb<N; yb++){\n                if(!occ[xb][yb]) continue;\n                const auto& row = rows[yb];\n                const auto& col = cols[xb];\n                if(row.empty() || col.empty()) continue;\n                for(int xa : row){\n                    if(xa==xb) continue;\n                    for(int yc : col){\n                        if(yc==yb) continue;\n                        int xd = xa;\n                        int yd = yc;\n                        if(xd<0||xd>=N||yd<0||yd>=N) continue;\n                        if(occ[xd][yd]) continue;\n                        // define rectangle order p1=D, p2=A, p3=B, p4=C:\n                        P D{xd,yd}, A{xa,yb}, B{xb,yb}, C{xb,yc};\n                        // perimeter dot check\n                        // Implement perimeter_points_clean inline:\n                        auto ok_line = [&](int x1,int y1,int x2,int y2)->bool{\n                            if(x1==x2){\n                                int x=x1;\n                                int ylo=min(y1,y2), yhi=max(y1,y2);\n                                for(int y=ylo; y<=yhi; y++){\n                                    if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                                    if(occ[x][y]) return false;\n                                }\n                            }else if(y1==y2){\n                                int y=y1;\n                                int xlo=min(x1,x2), xhi=max(x1,x2);\n                                for(int x=xlo; x<=xhi; x++){\n                                    if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                                    if(occ[x][y]) return false;\n                                }\n                            }else{\n                                return false;\n                            }\n                            return true;\n                        };\n                        if(!ok_line(D.x,D.y,A.x,A.y)) continue;\n                        if(!ok_line(A.x,A.y,B.x,B.y)) continue;\n                        if(!ok_line(B.x,B.y,C.x,C.y)) continue;\n                        if(!ok_line(C.x,C.y,D.x,D.y)) continue;\n                        // edge overlap check without marking now\n                        auto edges_free = [&]()->bool{\n                            auto check_edge = [&](int x1,int y1,int x2,int y2)->bool{\n                                if(x1==x2){\n                                    int x=x1;\n                                    int ylo=min(y1,y2), yhi=max(y1,y2);\n                                    for(int y=ylo; y<yhi; y++) if(usedV[x][y]) return false;\n                                }else{\n                                    int y=y1;\n                                    int xlo=min(x1,x2), xhi=max(x1,x2);\n                                    for(int x=xlo; x<xhi; x++) if(usedH[y][x]) return false;\n                                }\n                                return true;\n                            };\n                            return check_edge(D.x,D.y,A.x,A.y) && check_edge(A.x,A.y,B.x,B.y)\n                                && check_edge(B.x,B.y,C.x,C.y) && check_edge(C.x,C.y,D.x,D.y);\n                        };\n                        if(!edges_free()) continue;\n                        Candidate cand;\n                        cand.p1=D; cand.p2=A; cand.p3=B; cand.p4=C;\n                        cand.score = w_of(D.x,D.y,c);\n                        out.push_back(cand);\n                        if(out.size() >= CAP) return;\n                    }\n                }\n            }\n        }\n    };\n\n    vector<array<int,8>> answer;\n    answer.reserve(100000);\n\n    auto apply_rect = [&](const Candidate& cand){\n        const P &D=cand.p1, &A=cand.p2, &B=cand.p3, &C=cand.p4;\n        // Mark edges\n        auto mark_edge = [&](int x1,int y1,int x2,int y2){\n            if(x1==x2){\n                int x=x1;\n                int ylo=min(y1,y2), yhi=max(y1,y2);\n                for(int y=ylo; y<yhi; y++) usedV[x][y]=1;\n            }else{\n                int y=y1;\n                int xlo=min(x1,x2), xhi=max(x1,x2);\n                for(int x=xlo; x<xhi; x++) usedH[y][x]=1;\n            }\n        };\n        mark_edge(D.x,D.y,A.x,A.y);\n        mark_edge(A.x,A.y,B.x,B.y);\n        mark_edge(B.x,B.y,C.x,C.y);\n        mark_edge(C.x,C.y,D.x,D.y);\n        // Place dot\n        occ[D.x][D.y]=1;\n        rows[D.y].push_back(D.x);\n        cols[D.x].push_back(D.y);\n        // maintain sorted small overhead\n        // We can skip sort each time and sort on rebuild; but we rely on iteration through rows/cols. Let's keep them unsorted but iteration doesn't need sorted.\n        // Our build enumerates by iterating rows[y] and cols[x]; sort is not required. For cleanliness, we won't sort after incremental updates.\n        // Record\n        array<int,8> op = {D.x,D.y, A.x,A.y, B.x,B.y, C.x,C.y};\n        answer.push_back(op);\n    };\n\n    // Main greedy loop\n    auto t_start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.8; // seconds\n    int iter = 0;\n    while(true){\n        // Time check\n        if(iter % 10 == 0){\n            auto t_now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(t_now - t_start).count();\n            if(elapsed > TIME_LIMIT) break;\n        }\n        // Rebuild indices occasionally to keep rows/cols sane (sorted not required)\n        if(iter % 50 == 0) rebuild_index();\n\n        vector<Candidate> cands;\n        build_candidates(cands);\n        if(cands.empty()) break;\n        // sort by score descending, minor tiebreaker by perimeter length\n        stable_sort(cands.begin(), cands.end(), [&](const Candidate& a, const Candidate& b){\n            if(a.score != b.score) return a.score > b.score;\n            int per_a = abs(a.p1.x - a.p3.x) + abs(a.p1.y - a.p3.y) + abs(a.p2.x - a.p4.x) + abs(a.p2.y - a.p4.y);\n            int per_b = abs(b.p1.x - b.p3.x) + abs(b.p1.y - b.p3.y) + abs(b.p2.x - b.p4.x) + abs(b.p2.y - b.p4.y);\n            return per_a > per_b;\n        });\n        bool placed = false;\n        for(const auto& cand : cands){\n            const P &D=cand.p1, &A=cand.p2, &B=cand.p3, &C=cand.p4;\n            if(D.x<0||D.x>=N||D.y<0||D.y>=N) continue;\n            if(occ[D.x][D.y]) continue;\n            // recheck perimeter cleanliness and edge free (state may have changed)\n            auto ok_line = [&](int x1,int y1,int x2,int y2)->bool{\n                if(x1==x2){\n                    int x=x1;\n                    int ylo=min(y1,y2), yhi=max(y1,y2);\n                    for(int y=ylo; y<=yhi; y++){\n                        if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                        if(occ[x][y]) return false;\n                    }\n                }else if(y1==y2){\n                    int y=y1;\n                    int xlo=min(x1,x2), xhi=max(x1,x2);\n                    for(int x=xlo; x<=xhi; x++){\n                        if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                        if(occ[x][y]) return false;\n                    }\n                }else{\n                    return false;\n                }\n                return true;\n            };\n            if(!ok_line(D.x,D.y,A.x,A.y)) continue;\n            if(!ok_line(A.x,A.y,B.x,B.y)) continue;\n            if(!ok_line(B.x,B.y,C.x,C.y)) continue;\n            if(!ok_line(C.x,C.y,D.x,D.y)) continue;\n\n            auto edges_free = [&]()->bool{\n                auto check_edge = [&](int x1,int y1,int x2,int y2)->bool{\n                    if(x1==x2){\n                        int x=x1;\n                        int ylo=min(y1,y2), yhi=max(y1,y2);\n                        for(int y=ylo; y<yhi; y++) if(usedV[x][y]) return false;\n                    }else{\n                        int y=y1;\n                        int xlo=min(x1,x2), xhi=max(x1,x2);\n                        for(int x=xlo; x<xhi; x++) if(usedH[y][x]) return false;\n                    }\n                    return true;\n                };\n                return check_edge(D.x,D.y,A.x,A.y) && check_edge(A.x,A.y,B.x,B.y)\n                    && check_edge(B.x,B.y,C.x,C.y) && check_edge(C.x,C.y,D.x,D.y);\n            };\n            if(!edges_free()) continue;\n\n            apply_rect(cand);\n            placed = true;\n            break;\n        }\n        if(!placed) break;\n        iter++;\n    }\n\n    cout<< (int)answer.size() << \"\\n\";\n    for(auto &op: answer){\n        for(int i=0;i<8;i++){\n            if(i) cout<<' ';\n            cout<<op[i];\n        }\n        cout<<\"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct RNG {\n    uint64_t x;\n    RNG(uint64_t s=88172645463393265ull){ seed(s); }\n    void seed(uint64_t s){ x = s ? s : 88172645463393265ull; }\n    uint32_t next_u32(){\n        x ^= x << 7; x ^= x >> 9;\n        return uint32_t(x & 0xffffffffu);\n    }\n    double next_double(){\n        return (next_u32() + 0.5) / 4294967296.0;\n    }\n};\n\nstruct Board {\n    static constexpr int H=10, W=10;\n    array<array<int,W>,H> g{}; // 0 empty, 1..3 flavors\n    void clear(){ for(int i=0;i<H;i++) for(int j=0;j<W;j++) g[i][j]=0; }\n\n    // place flavor f at p-th empty (1-indexed) scanning row-major\n    // returns placed coordinates\n    pair<int,int> place_by_index(int p, int f){\n        int cnt=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                if(g[i][j]==0){\n                    cnt++;\n                    if(cnt==p){\n                        g[i][j]=f;\n                        return {i,j};\n                    }\n                }\n            }\n        }\n        // should not happen\n        return {-1,-1};\n    }\n\n    // simulate tilt dir: 'F','B','L','R'\n    Board tilt(char dir) const {\n        Board b=*this;\n        if(dir=='F'){ // move up: i increasing means towards i=0\n            for(int j=0;j<W;j++){\n                int write=0;\n                for(int i=0;i<H;i++){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        b.g[i][j]=0;\n                        b.g[write][j]=v;\n                        write++;\n                    }\n                }\n            }\n        } else if(dir=='B'){ // move down to i=H-1\n            for(int j=0;j<W;j++){\n                int write=H-1;\n                for(int i=H-1;i>=0;i--){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        b.g[i][j]=0;\n                        b.g[write][j]=v;\n                        write--;\n                    }\n                }\n            }\n        } else if(dir=='L'){ // move left to j=0\n            for(int i=0;i<H;i++){\n                int write=0;\n                for(int j=0;j<W;j++){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        b.g[i][j]=0;\n                        b.g[i][write]=v;\n                        write++;\n                    }\n                }\n            }\n        } else if(dir=='R'){ // move right to j=W-1\n            for(int i=0;i<H;i++){\n                int write=W-1;\n                for(int j=W-1;j>=0;j--){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        b.g[i][j]=0;\n                        b.g[i][write]=v;\n                        write--;\n                    }\n                }\n            }\n        }\n        return b;\n    }\n\n    bool equals(const Board& other) const {\n        for(int i=0;i<H;i++) for(int j=0;j<W;j++) if(g[i][j]!=other.g[i][j]) return false;\n        return true;\n    }\n};\n\nstruct Heuristic {\n    // anchors for flavors 1..3\n    array<pair<int,int>,4> anchor; // 1-based index used\n    int wa=5, wd=2, wdist=1;\n    RNG rng;\n    Heuristic(){\n        // set anchors\n        anchor[1] = {0,0};   // flavor 1 -> top-left\n        anchor[2] = {0,9};   // flavor 2 -> top-right\n        anchor[3] = {9,4};   // flavor 3 -> bottom middle\n        rng.seed(123456789u);\n    }\n\n    int adj_score(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int bonus=0, penalty=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                if(i+1<H){\n                    int u=b.g[i+1][j];\n                    if(u){\n                        if(u==v) bonus++;\n                        else penalty++;\n                    }\n                }\n                if(j+1<W){\n                    int u=b.g[i][j+1];\n                    if(u){\n                        if(u==v) bonus++;\n                        else penalty++;\n                    }\n                }\n            }\n        }\n        return wa*bonus - wd*penalty;\n    }\n\n    int dist_score(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                auto [ai,aj]=anchor[v];\n                sc -= wdist * (abs(i-ai)+abs(j-aj));\n            }\n        }\n        return sc;\n    }\n\n    int score(const Board& b) const {\n        // combine\n        int s1 = adj_score(b);\n        int s2 = dist_score(b);\n        return s1 + s2;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> f(100);\n    for(int i=0;i<100;i++){\n        if(!(cin>>f[i])) return 0;\n    }\n    Board board;\n    board.clear();\n    Heuristic H;\n    char lastMove = 'F';\n\n    const array<char,4> dirs = {'F','B','L','R'};\n\n    for(int t=0;t<100;t++){\n        int p;\n        if(!(cin>>p)) return 0;\n        // place the candy\n        board.place_by_index(p, f[t]);\n\n        if(t==99){\n            // last tilt does nothing; can skip output per statement\n            // But to be safe, output a default move\n            // We'll skip to avoid unnecessary I/O\n            continue;\n        }\n\n        int bestScore = INT_MIN;\n        char bestDir = 'F';\n        Board bestBoard = board;\n\n        for(char d: dirs){\n            Board nb = board.tilt(d);\n            int sc = H.score(nb);\n            // prefer actual-changing moves slightly\n            if(nb.equals(board)){\n                sc -= 1;\n            }\n            // small tie-breaking inertia\n            if(d == lastMove) sc += 0;\n            if(sc > bestScore || (sc==bestScore && d==lastMove)){\n                bestScore = sc;\n                bestDir = d;\n                bestBoard = nb;\n            }\n        }\n\n        cout << bestDir << '\\n' << flush;\n        lastMove = bestDir;\n        board = bestBoard; // maintain internal state consistent with our output\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\nusing ull = unsigned long long;\nstruct XorShift64 {\n    uint64_t x;\n    XorShift64(uint64_t s=88172645463393265ull){ if(!s) s=1; x=s; }\n    uint64_t rng(){ uint64_t y=x; y^=y<<7; y^=y>>9; return x=y; }\n    double drand(){ return (rng() >> 11) * (1.0/9007199254740992.0); } // [0,1)\n    int irand(int L,int R){ return L + (int)(rng() % (uint64_t)(R-L+1)); }\n};\nstruct Graph {\n    int N;\n    vector<uint8_t> adj; // upper triangle packed? For building use matrix\n};\nstatic inline int idx_pair(int N,int i,int j){ // i<j\n    return i*N - i*(i+1)/2 + (j - i - 1);\n}\nstruct Features {\n    vector<double> deg_hist; // size N\n    vector<int> deg_sorted;  // size N\n    vector<double> eig; // top T eigenvalues (descending by abs)\n    vector<double> nbrdeg_hist; // binned histogram\n};\nstruct Template {\n    vector<uint8_t> bits; // length N(N-1)/2\n    vector<int> deg;\n    Features feat;\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    double eps;\n    if(!(cin>>M>>eps)) return 0;\n\n    // Choose N\n    int N = 64;\n    if (M >= 90 && eps <= 0.08) N = 48; // slightly smaller to improve 1/N when easy\n    if (eps >= 0.3) N = 80;            // harder noise => more vertices for robustness\n    if (N > 100) N = 100;\n    if (N < 4) N = 4;\n\n    // RNG for constructing templates: deterministic from M, eps\n    uint64_t seed = 1469598103934665603ull ^ (uint64_t)M * 1099511628211ull ^ (uint64_t)llround(eps*100.0+0.5);\n    XorShift64 gen(seed);\n\n    int B = 4; // blocks\n    vector<int> block(N);\n    // Split N into B almost equal parts\n    for(int i=0;i<N;i++) block[i] = (long long)i * B / N;\n\n    auto build_template = [&](int k)->Template{\n        // derive parameters from k deterministically\n        XorShift64 g(seed ^ (uint64_t)(0x9e3779b97f4a7c15ull * (k+1)));\n        // base block density matrix P[b][c] in [pmin, pmax]\n        double pmin = 0.08 + 0.02 * (g.drand()); // slight variation\n        double pmax = 0.92 - 0.02 * (g.drand());\n        vector<vector<double>> P(B, vector<double>(B, 0.0));\n        for(int b=0;b<B;b++){\n            for(int c=b;c<B;c++){\n                double r = g.drand();\n                // skew by k to diversify\n                double val = pmin + (pmax - pmin) * fmod(r + 0.13*(b+1) + 0.07*(c+2) + 0.037*k, 1.0);\n                // amplify diagonal difference\n                if(b==c) val = 0.5*(val + min(0.98, max(0.02, val + (g.drand()-0.5)*0.4)));\n                P[b][c]=P[c][b]=min(0.98, max(0.02, val));\n            }\n        }\n        // per-vertex biases by block: add small shift per vertex index for diversity\n        vector<double> biasB(B);\n        for(int b=0;b<B;b++){\n            biasB[b] = (g.drand()-0.5)*0.2; // [-0.1,0.1]\n        }\n\n        // build adjacency matrix upper triangle bits\n        int Ebits = N*(N-1)/2;\n        vector<uint8_t> bits(Ebits, 0);\n        vector<int> deg(N,0);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                int bi = block[i], bj = block[j];\n                double p = P[bi][bj];\n                // vertex biases\n                double vbi = biasB[bi] + 0.06 * sin((i+1)*(k+3)*0.13);\n                double vbj = biasB[bj] + 0.06 * cos((j+3)*(k+5)*0.17);\n                double adjp = p + 0.15*(vbi+vbj); // could move a bit\n                if(adjp < 0.01) adjp = 0.01;\n                if(adjp > 0.99) adjp = 0.99;\n                if (g.drand() < adjp){\n                    bits[idx_pair(N,i,j)] = 1;\n                    deg[i]++; deg[j]++;\n                }\n            }\n        }\n        // ensure connectedness is not required; leave as is\n        Template T;\n        T.bits = move(bits);\n        T.deg = move(deg);\n        return T;\n    };\n\n    // Build templates\n    vector<Template> temps(M);\n    for(int k=0;k<M;k++){\n        temps[k] = build_template(k);\n    }\n\n    // feature computation helpers\n    auto compute_features = [&](const vector<uint8_t>& bits)->pair<vector<int>, Features>{\n        // build adjacency matrix for Eigen\n        Eigen::MatrixXd A(N, N);\n        A.setZero();\n        vector<int> deg(N,0);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                uint8_t v = bits[idx_pair(N,i,j)];\n                if(v){\n                    A(i,j)=A(j,i)=1.0;\n                    deg[i]++; deg[j]++;\n                }\n            }\n        }\n\n        // degree histogram\n        vector<double> dh(N, 0.0);\n        for(int d:deg) dh[d] += 1.0;\n        for(double &x:dh) x /= N;\n\n        // sorted degrees\n        vector<int> dsort = deg;\n        sort(dsort.begin(), dsort.end());\n\n        // neighbor degree sums per vertex\n        vector<int> degNbrSum(N,0);\n        for(int i=0;i<N;i++){\n            int s=0;\n            for(int j=0;j<N;j++) if(A(i,j)>0.5) s += deg[j];\n            degNbrSum[i]=s;\n        }\n        // histogram of neighbor degree sums binned into H bins\n        int Hbins = 16;\n        int minv = *min_element(degNbrSum.begin(), degNbrSum.end());\n        int maxv = *max_element(degNbrSum.begin(), degNbrSum.end());\n        if (maxv==minv) maxv=minv+1;\n        vector<double> ndh(Hbins,0.0);\n        for(int v:degNbrSum){\n            int b = (int)((long long)(v - minv) * Hbins / (long long)(maxv - minv + 1));\n            if(b<0) b=0;\n            if(b>=Hbins) b=Hbins-1;\n            ndh[b] += 1.0;\n        }\n        for(double &x:ndh) x/=N;\n\n        // eigenvalues: top T by absolute value\n        int Ttop = min(16, N);\n        vector<double> eigv;\n        {\n            // Use SelfAdjoint since A is symmetric\n            Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(A, Eigen::ComputeEigenvalues);\n            auto evals = es.eigenvalues(); // ascending\n            eigv.resize(Ttop);\n            // collect absolute values and pick top T\n            vector<double> all(N);\n            for(int i=0;i<N;i++) all[i] = evals(i);\n            // sort by absolute descending\n            vector<int> idx(N); iota(idx.begin(), idx.end(), 0);\n            sort(idx.begin(), idx.end(), [&](int a,int b){\n                return fabs(all[a]) > fabs(all[b]);\n            });\n            for(int t=0;t<Ttop;t++){\n                double v = all[idx[t]];\n                // normalize by sqrt(max(deg)) to reduce scale variance\n                double scale = sqrt(max(1, *max_element(deg.begin(), deg.end())));\n                eigv[t] = v / (scale>0?scale:1.0);\n            }\n        }\n\n        Features F;\n        F.deg_hist = move(dh);\n        F.deg_sorted = dsort;\n        F.eig = move(eigv);\n        F.nbrdeg_hist = move(ndh);\n        return {deg, F};\n    };\n\n    // Precompute features for templates\n    for(int k=0;k<M;k++){\n        auto [deg, F] = compute_features(temps[k].bits);\n        temps[k].deg = move(deg);\n        temps[k].feat = move(F);\n    }\n\n    auto dist_deg_fast = [&](const Features& A, const Features& B)->double{\n        // mix histogram L2 and sorted L1\n        double s=0.0;\n        for(int i=0;i<N;i++){\n            double d=A.deg_hist[i]-B.deg_hist[i];\n            s += d*d;\n        }\n        double t=0.0;\n        for(int i=0;i<N;i++){\n            t += abs(A.deg_sorted[i]-B.deg_sorted[i]);\n        }\n        // normalize t by N\n        t /= (double)N;\n        return 0.7*sqrt(s) + 0.3*t;\n    };\n    auto dist_full = [&](const Features& A, const Features& B)->double{\n        double d1=0.0;\n        for(int i=0;i<N;i++){ double d=A.deg_hist[i]-B.deg_hist[i]; d1+=d*d; }\n        d1 = sqrt(d1);\n        double d2=0.0;\n        int Ttop = (int)min(A.eig.size(), B.eig.size());\n        for(int i=0;i<Ttop;i++){ double d=A.eig[i]-B.eig[i]; d2+=d*d; }\n        d2 = sqrt(d2);\n        double d3=0.0;\n        int Hbins = (int)min(A.nbrdeg_hist.size(), B.nbrdeg_hist.size());\n        for(int i=0;i<Hbins;i++){ double d=A.nbrdeg_hist[i]-B.nbrdeg_hist[i]; d3+=d*d; }\n        d3 = sqrt(d3);\n        double d4=0.0;\n        for(int i=0;i<N;i++){ d4 += abs(A.deg_sorted[i]-B.deg_sorted[i]); }\n        d4 /= (double)N;\n        // weights\n        return 0.35*d1 + 0.30*d2 + 0.20*d3 + 0.15*d4;\n    };\n\n    // Output\n    cout<<N<<\"\\n\";\n    for(int k=0;k<M;k++){\n        // print bits as string\n        int L = N*(N-1)/2;\n        string s; s.resize(L);\n        for(int i=0;i<L;i++) s[i] = temps[k].bits[i] ? '1':'0';\n        cout<<s<<\"\\n\";\n    }\n    cout.flush();\n\n    // Process queries\n    for(int q=0;q<100;q++){\n        string Hs;\n        if(!(cin>>Hs)) return 0;\n        // Parse H bits into vector\n        int L = N*(N-1)/2;\n        vector<uint8_t> Hbits(L,0);\n        for(int i=0;i<L;i++) Hbits[i] = (Hs[i]=='1');\n        // Compute features for H\n        auto [Hdeg, HF] = compute_features(Hbits);\n\n        // shortlist by fast degree distance\n        int S = min(12, M);\n        vector<pair<double,int>> cand;\n        cand.reserve(M);\n        for(int k=0;k<M;k++){\n            double d = dist_deg_fast(HF, temps[k].feat);\n            cand.emplace_back(d, k);\n        }\n        nth_element(cand.begin(), cand.begin()+S, cand.end());\n        cand.resize(S);\n        // refine\n        int bestk = cand[0].second;\n        double bestd = 1e100;\n        for(auto &pr : cand){\n            int k = pr.second;\n            double d = dist_full(HF, temps[k].feat);\n            if(d < bestd){\n                bestd = d; bestk = k;\n            }\n        }\n        cout<<bestk<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int id;\n    int u, v;\n    long long w;\n};\n\nstruct AdjEdge {\n    int to;\n    int eid;\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)) {\n        return 0;\n    }\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u,v; long long w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {i,u,v,w};\n    }\n    // read coordinates but ignore\n    for (int i = 0; i < N; ++i) {\n        int x,y; cin >> x >> y;\n    }\n\n    // Build adjacency\n    vector<vector<AdjEdge>> g(N);\n    vector<int> deg(N,0);\n    for (auto &e: edges) {\n        g[e.u].push_back({e.v, e.id, e.w});\n        g[e.v].push_back({e.u, e.id, e.w});\n        deg[e.u]++; deg[e.v]++;\n    }\n\n    // Importance components\n    vector<double> imp_w(M, 0.0);\n    vector<double> imp_deg(M, 0.0);\n    vector<double> imp_bet(M, 0.0);\n\n    // Weight normalization\n    long long wmin = LLONG_MAX, wmax = 0;\n    for (auto &e: edges) {\n        wmin = min(wmin, e.w);\n        wmax = max(wmax, e.w);\n    }\n    double denom_w = (wmax > wmin ? double(wmax - wmin) : 1.0);\n    for (auto &e: edges) {\n        imp_w[e.id] = (double)(e.w - wmin) / denom_w;\n    }\n\n    // Degree penalty: smaller degrees -> higher penalty\n    for (auto &e: edges) {\n        // deg >=2 guaranteed; subtract 1 to represent alt edges.\n        double pu = 1.0 / max(1, deg[e.u]-1);\n        double pv = 1.0 / max(1, deg[e.v]-1);\n        imp_deg[e.id] = (pu + pv) * 0.5;\n    }\n\n    // Betweenness proxy: SSSP tree edge usage from sampled sources\n    int S = 32;\n    if (N < 800) S = 24;\n    if (N < 600) S = 20;\n    if (N < 400) S = 16;\n    S = min(S, max(12, N / 40));\n    // Sample sources uniformly at random but deterministic: use mt19937 with fixed seed\n    mt19937 rng(712367);\n    vector<int> nodes(N);\n    iota(nodes.begin(), nodes.end(), 0);\n    shuffle(nodes.begin(), nodes.end(), rng);\n    vector<int> sources;\n    sources.reserve(S);\n    for (int i = 0; i < S && i < N; ++i) sources.push_back(nodes[i]);\n\n    vector<int> parent_edge(N, -1);\n    vector<long long> dist(N);\n    vector<char> used(N, 0);\n    vector<int> heap_idx; // unused, using priority_queue\n\n    struct State { long long d; int v; };\n    struct Cmp { bool operator()(const State& a, const State& b) const { return a.d > b.d; } };\n\n    vector<long long> bet_count(M, 0);\n    for (int s : sources) {\n        // Dijkstra\n        fill(dist.begin(), dist.end(), (long long)4e18);\n        fill(parent_edge.begin(), parent_edge.end(), -1);\n        priority_queue<State, vector<State>, Cmp> pq;\n        dist[s] = 0;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [dcur, v] = pq.top(); pq.pop();\n            if (dcur != dist[v]) continue;\n            for (auto &ae : g[v]) {\n                int to = ae.to;\n                long long nd = dcur + ae.w;\n                if (nd < dist[to]) {\n                    dist[to] = nd;\n                    parent_edge[to] = ae.eid;\n                    pq.push({nd, to});\n                }\n            }\n        }\n        for (int v = 0; v < N; ++v) {\n            int pe = parent_edge[v];\n            if (pe >= 0) bet_count[pe] += 1;\n        }\n    }\n    long long betmin = LLONG_MAX, betmax = 0;\n    for (int i = 0; i < M; ++i) {\n        betmin = min(betmin, bet_count[i]);\n        betmax = max(betmax, bet_count[i]);\n    }\n    double denom_b = (betmax > betmin ? double(betmax - betmin) : 1.0);\n    for (int i = 0; i < M; ++i) {\n        imp_bet[i] = (double)(bet_count[i] - betmin) / denom_b;\n    }\n\n    // Combine: tune weights\n    double a_w = 0.5;\n    double b_deg = 0.6;\n    double c_bet = 1.0;\n    vector<double> score(M, 0.0);\n    for (int i = 0; i < M; ++i) {\n        score[i] = a_w * imp_w[i] + b_deg * imp_deg[i] + c_bet * imp_bet[i];\n    }\n\n    // Sort edges by score descending\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j){\n        if (score[i] != score[j]) return score[i] > score[j];\n        return i < j;\n    });\n\n    // Assignment\n    vector<int> day_of_edge(M, -1);\n    vector<int> load(D, 0);\n    vector<double> day_importance(D, 0.0);\n    vector<vector<int>> incid_on_day(N, vector<int>(D, 0));\n\n    // To keep balancing total count across days, compute target capacities roughly balanced: no strict need, but helps spread\n    vector<int> target_cap(D, K);\n    // we can allow less than K; we aim to distribute M across D nearly evenly\n    int base = M / D;\n    int rem = M % D;\n    for (int d = 0; d < D; ++d) target_cap[d] = min(K, base + (d < rem ? 1 : 0));\n\n    // penalties coefficients\n    double alpha = 1.0; // adjacency penalty per incident edge same day\n    double beta = 0.7;  // importance balance cost\n\n    for (int ei : order) {\n        int u = edges[ei].u, v = edges[ei].v;\n        int best_d = -1;\n        double best_cost = 1e100;\n\n        // Prefer days under their soft target; but allow any under K\n        for (int d = 0; d < D; ++d) {\n            if (load[d] >= K) continue;\n            // Soft capacity encourage\n            double soft = (load[d] < target_cap[d] ? 0.0 : 0.5 * (load[d] - target_cap[d] + 1));\n            double pen = alpha * (incid_on_day[u][d] + incid_on_day[v][d]);\n            double bal = beta * day_importance[d];\n            double cost = pen + bal + soft * 0.2;\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_d = d;\n            }\n        }\n        if (best_d == -1) {\n            // All days at K? Shouldn't happen since sum K*D >= M typically. But be safe: pick minimal load day\n            int md = 0;\n            for (int d = 1; d < D; ++d) if (load[d] < load[md]) md = d;\n            best_d = md;\n        }\n        day_of_edge[ei] = best_d;\n        load[best_d] += 1;\n        day_importance[best_d] += score[ei];\n        incid_on_day[u][best_d] += 1;\n        incid_on_day[v][best_d] += 1;\n    }\n\n    // Simple refinement: try moving some edges to reduce (adjacency + imbalance). Limited iterations/time.\n    auto now = chrono::high_resolution_clock::now();\n    auto time_limit = now + chrono::milliseconds(1200); // ~1.2s refinement budget\n    int iterations = 0;\n    while (chrono::high_resolution_clock::now() < time_limit && iterations < 200000) {\n        ++iterations;\n        int ei = rng() % M;\n        int curd = day_of_edge[ei];\n        int u = edges[ei].u, v = edges[ei].v;\n        // evaluate current cost\n        double cur_pen = alpha * (incid_on_day[u][curd] + incid_on_day[v][curd] - 2); // subtract this edge's own incidence\n        double cur_bal = beta * day_importance[curd];\n        double cur_cost = cur_pen + cur_bal;\n\n        int best_d = curd;\n        double best_gain = 0.0;\n        for (int d = 0; d < D; ++d) {\n            if (d == curd) continue;\n            if (load[d] >= K) continue;\n            double pen = alpha * (incid_on_day[u][d] + incid_on_day[v][d]);\n            double bal = beta * (day_importance[d]);\n            double new_cost_sum = pen + bal;\n            double gain = cur_cost - new_cost_sum - beta * score[ei] + beta * 0.0; \n            // Explanation: moving edge decreases day_importance[curd] by score, increases day_importance[d] by score\n            // Our approximate delta for balance part between days is:\n            // delta_bal = beta*(day_imp[curd]-score) + beta*(day_imp[d]+score) - (beta*day_imp[curd] + beta*day_imp[d]) = 0\n            // So we already accounted bal with current snapshot; for speed, we keep the above simple gain using pen terms mostly.\n            // Use heuristic: prefer less adjacency; ignore bal change to keep evaluation O(1).\n\n            // Better compute gain more explicitly: using only adjacency changes\n            gain = alpha * ((incid_on_day[u][curd] + incid_on_day[v][curd] - 2) - (incid_on_day[u][d] + incid_on_day[v][d]));\n            // And a weak push to balance importance:\n            gain += 0.2 * ( (day_importance[curd]) - (day_importance[d]) );\n\n            if (gain > best_gain + 1e-9) {\n                best_gain = gain;\n                best_d = d;\n            }\n        }\n        if (best_d != curd) {\n            // commit move\n            day_of_edge[ei] = best_d;\n            load[curd] -= 1;\n            load[best_d] += 1;\n            incid_on_day[u][curd] -= 1;\n            incid_on_day[v][curd] -= 1;\n            incid_on_day[u][best_d] += 1;\n            incid_on_day[v][best_d] += 1;\n            day_importance[curd] -= score[ei];\n            day_importance[best_d] += score[ei];\n        }\n    }\n\n    // Output days 1..D\n    for (int i = 0; i < M; ++i) {\n        int d = day_of_edge[i];\n        if (d < 0) d = 0;\n        cout << (d+1) << (i+1==M?'\\n':' ');\n    }\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D;\n    if (!(cin >> D)) return 0;\n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    for (int i = 0; i < 2; ++i) {\n        for (int z = 0; z < D; ++z) cin >> f[i][z];\n        for (int z = 0; z < D; ++z) cin >> r[i][z];\n    }\n    int N = D*D*D;\n    auto idx = [&](int x,int y,int z){ return x*D*D + y*D + z; };\n    vector<char> M1(N,0), M2(N,0);\n    for (int x=0;x<D;++x){\n        for (int y=0;y<D;++y){\n            for (int z=0;z<D;++z){\n                if (f[0][z][x]=='1' && r[0][z][y]=='1') M1[idx(x,y,z)]=1;\n                if (f[1][z][x]=='1' && r[1][z][y]=='1') M2[idx(x,y,z)]=1;\n            }\n        }\n    }\n    vector<char> C(N,0), O1(N,0), O2(N,0);\n    for (int i=0;i<N;++i){\n        if (M1[i] && M2[i]) C[i]=1;\n        else if (M1[i]) O1[i]=1;\n        else if (M2[i]) O2[i]=1;\n    }\n\n    // BFS for components\n    auto neighbors = [&](int x,int y,int z, array<int,6>& out)->int{\n        // We'll store as packed ints separately; but for BFS we can compute inline\n        return 0;\n    };\n\n    vector<int> b1(N,0), b2(N,0);\n    int nBlocks = 0;\n\n    auto process_components = [&](vector<char>& mark, bool place1, bool place2){\n        vector<char> vis(N,0);\n        int dx[6]={1,-1,0,0,0,0};\n        int dy[6]={0,0,1,-1,0,0};\n        int dz[6]={0,0,0,0,1,-1};\n        for (int x=0;x<D;++x){\n            for (int y=0;y<D;++y){\n                for (int z=0;z<D;++z){\n                    int s = idx(x,y,z);\n                    if (!mark[s] || vis[s]) continue;\n                    // start new component\n                    ++nBlocks;\n                    queue<int> q;\n                    q.push(s);\n                    vis[s]=1;\n                    // assign\n                    if (place1) b1[s]=nBlocks;\n                    if (place2) b2[s]=nBlocks;\n                    while(!q.empty()){\n                        int v=q.front(); q.pop();\n                        int vx = v/(D*D);\n                        int rem = v%(D*D);\n                        int vy = rem/D;\n                        int vz = rem% D;\n                        for (int dir=0;dir<6;++dir){\n                            int nx = vx+dx[dir], ny=vy+dy[dir], nz=vz+dz[dir];\n                            if (nx<0||nx>=D||ny<0||ny>=D||nz<0||nz>=D) continue;\n                            int u = idx(nx,ny,nz);\n                            if (mark[u] && !vis[u]){\n                                vis[u]=1;\n                                q.push(u);\n                                if (place1) b1[u]=nBlocks;\n                                if (place2) b2[u]=nBlocks;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    };\n\n    // Common components used in both\n    process_components(C, true, true);\n    // Only1 components used in b1 only\n    process_components(O1, true, false);\n    // Only2 components used in b2 only\n    process_components(O2, false, true);\n\n    cout << nBlocks << \"\\n\";\n    for (int i=0;i<N;++i){\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << \"\\n\";\n    for (int i=0;i<N;++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};\nstruct AdjEdge { int to, id; long long w; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K;\n    if(!(cin>>N>>M>>K)) return 0;\n    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n    vector<Edge> edges(M);\n    vector<vector<AdjEdge>> g(N);\n    for(int j=0;j<M;j++){\n        int u,v; long long w;\n        cin>>u>>v>>w; --u;--v;\n        edges[j]={u,v,w};\n        g[u].push_back({v,j,w});\n        g[v].push_back({u,j,w});\n    }\n    vector<int> ax(K), ay(K);\n    for(int k=0;k<K;k++) cin>>ax[k]>>ay[k];\n\n    auto dist_int = [&](int xi,int yi,int a,int b)->int{\n        long double dx = (long double)xi - a;\n        long double dy = (long double)yi - b;\n        long double d = sqrt((double)(dx*dx + dy*dy));\n        // ceil to ensure coverage\n        int id = (int)ceil(d - 1e-12);\n        if(id>5000) id=5000;\n        if(id<0) id=0;\n        return id;\n    };\n\n    // Precompute station-resident distances\n    vector<vector<int>> res_order(N);\n    vector<vector<int>> res_dist(N);\n    for(int i=0;i<N;i++){\n        res_order[i].resize(K);\n        iota(res_order[i].begin(), res_order[i].end(), 0);\n        vector<int> tmpd(K);\n        for(int k=0;k<K;k++){\n            tmpd[k] = dist_int(x[i],y[i],ax[k],ay[k]);\n        }\n        // sort indices by distance\n        stable_sort(res_order[i].begin(), res_order[i].end(), [&](int a,int b){\n            return tmpd[a] < tmpd[b];\n        });\n        res_dist[i].resize(K);\n        for(int idx=0; idx<K; ++idx){\n            int rk = res_order[i][idx];\n            res_dist[i][idx] = tmpd[rk];\n        }\n    }\n\n    // Dijkstra from 0 to get shortest path tree\n    const long long INFLL = (1LL<<62);\n    vector<long long> dist(N, INFLL);\n    vector<int> parE(N, -1), parV(N, -1);\n    struct Node { long long d; int v;};\n    struct Cmp { bool operator()(const Node& a, const Node& b) const { return a.d>b.d; } };\n    priority_queue<Node, vector<Node>, Cmp> pq;\n    dist[0]=0; pq.push({0,0});\n    while(!pq.empty()){\n        auto [d,u]=pq.top(); pq.pop();\n        if(d!=dist[u]) continue;\n        for(auto &e: g[u]){\n            int v=e.to; long long nd = d + e.w;\n            if(nd < dist[v]){\n                dist[v]=nd; parE[v]=e.id; parV[v]=u;\n                pq.push({nd,v});\n            }\n        }\n    }\n    // Build SPT edges set\n    vector<int> tree_parent_edge(N,-1);\n    for(int v=1; v<N; v++){\n        tree_parent_edge[v]=parE[v];\n    }\n\n    // Baseline: assign each resident to nearest station (by Euclidean distance, not connectivity)\n    vector<int> P(N,0);\n    vector<int> req(N,0);\n    for(int k=0;k<K;k++){\n        int besti=0; int bestd = dist_int(x[0],y[0],ax[k],ay[k]);\n        for(int i=1;i<N;i++){\n            int d = dist_int(x[i],y[i],ax[k],ay[k]);\n            if(d < bestd){\n                bestd = d; besti=i;\n            }\n        }\n        if(bestd>req[besti]) req[besti]=bestd;\n    }\n    for(int i=0;i<N;i++) P[i]=req[i];\n\n    // Determine set of broadcasting stations (terminals)\n    vector<char> is_terminal(N,false);\n    int terminals=0;\n    for(int i=0;i<N;i++){\n        if(P[i]>0){ is_terminal[i]=true; terminals++; }\n    }\n    is_terminal[0] = is_terminal[0] || (P[0]>0); // ensure 0 marked if broadcasting\n\n    // Determine which tree edges are needed to connect terminals to root in the SPT\n    vector<char> need_edge(M,false);\n    vector<int> used(N,0);\n    // Mark all terminals and propagate to root\n    vector<int> degree_in_subtree(N,0);\n    for(int v=0; v<N; v++){\n        if(!is_terminal[v]) continue;\n        int u=v;\n        while(u!=0){\n            int e = tree_parent_edge[u];\n            if(e<0) break;\n            if(need_edge[e]) { // already marked\n                u = edges[e].u==u ? edges[e].v : edges[e].u;\n                continue;\n            }\n            need_edge[e]=true;\n            degree_in_subtree[edges[e].u]++;\n            degree_in_subtree[edges[e].v]++;\n            u = edges[e].u==u ? edges[e].v : edges[e].u;\n        }\n    }\n\n    // Optional: try to reduce broadcasting set by reassigning to currently broadcasting stations\n    // Build list of broadcasters\n    vector<int> broadcasters;\n    broadcasters.reserve(N);\n    for(int i=0;i<N;i++) if(P[i]>0) broadcasters.push_back(i);\n    if(broadcasters.empty()){\n        // If somehow no broadcasters (shouldn't happen as K>=2000), ensure station 1 covers nearest residents\n        // Set P[0] to max distance to all residents (capped)\n        int mx=0;\n        for(int k=0;k<K;k++){ mx = max(mx, dist_int(x[0],y[0],ax[k],ay[k])); }\n        P[0]=mx;\n        is_terminal[0]=true;\n        // no edges needed\n        fill(need_edge.begin(), need_edge.end(), false);\n    } else {\n        // Reassign residents to nearest broadcaster and recompute P\n        vector<int> newP(N,0);\n        for(int k=0;k<K;k++){\n            int besti = broadcasters[0];\n            int bestd = dist_int(x[besti],y[besti],ax[k],ay[k]);\n            for(size_t t=1;t<broadcasters.size();t++){\n                int i = broadcasters[t];\n                int d = dist_int(x[i],y[i],ax[k],ay[k]);\n                if(d < bestd){ bestd=d; besti=i; }\n            }\n            if(bestd > newP[besti]) newP[besti]=bestd;\n        }\n        P.swap(newP);\n        // update terminals\n        fill(is_terminal.begin(), is_terminal.end(), false);\n        broadcasters.clear();\n        for(int i=0;i<N;i++) if(P[i]>0){ is_terminal[i]=true; broadcasters.push_back(i); }\n        // recompute needed edges on SPT\n        fill(need_edge.begin(), need_edge.end(), false);\n        for(int v=0; v<N; v++){\n            if(!is_terminal[v]) continue;\n            int u=v;\n            while(u!=0){\n                int e = tree_parent_edge[u];\n                if(e<0) break;\n                if(need_edge[e]){\n                    u = edges[e].u==u ? edges[e].v : edges[e].u;\n                    continue;\n                }\n                need_edge[e]=true;\n                u = edges[e].u==u ? edges[e].v : edges[e].u;\n            }\n        }\n    }\n\n    // Final small tightening: try to reduce P[i] by trimming unnecessary slack.\n    // For each broadcaster i, compute max distance among residents to i when residents choose nearest broadcaster.\n    // Already done; but do a quick pass: for each i, try lowering to the next smaller actual distance in its assigned set.\n    // To keep it simple and fast, we skip recalculating assignments; the previous calculation already set P exactly.\n\n    // Build B array\n    vector<int> B(M,0);\n    for(int j=0;j<M;j++) if(need_edge[j]) B[j]=1;\n\n    // Output\n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << P[i];\n    }\n    cout << '\\n';\n    for(int j=0;j<M;j++){\n        if(j) cout << ' ';\n        cout << B[j];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    const int NN = N*(N+1)/2; // 465\n\n    auto id_of = [&](int x, int y)->int {\n        return x*(x+1)/2 + y;\n    };\n    vector<int> x_of(NN), y_of(NN);\n    for (int x=0, id=0; x<N; ++x) {\n        for (int y=0; y<=x; ++y, ++id) {\n            x_of[id]=x; y_of[id]=y;\n        }\n    }\n\n    vector<int> A(NN);\n    for (int x=0; x<N; ++x) {\n        for (int y=0; y<=x; ++y) {\n            int v; if(!(cin>>v)) return 0;\n            A[id_of(x,y)] = v;\n        }\n    }\n\n    // Precompute children and parents for each id\n    const int NONE = -1;\n    vector<array<int,2>> child(NN, {NONE, NONE});\n    vector<array<int,2>> parent(NN, {NONE, NONE});\n    for (int x=0; x<N; ++x) {\n        for (int y=0; y<=x; ++y) {\n            int id = id_of(x,y);\n            if (x < N-1) {\n                int c0 = id_of(x+1, y);\n                int c1 = id_of(x+1, y+1);\n                child[id][0] = c0;\n                child[id][1] = c1;\n                // set parents\n                if (parent[c0][0] == NONE) parent[c0][0] = id;\n                else parent[c0][1] = id;\n                if (parent[c1][0] == NONE) parent[c1][0] = id;\n                else parent[c1][1] = id;\n            }\n        }\n    }\n\n    // Work queue of internal nodes (ids with children)\n    deque<int> dq;\n    vector<char> inq(NN, 0);\n    for (int x=0; x<N-1; ++x) {\n        for (int y=0; y<=x; ++y) {\n            int id = id_of(x,y);\n            dq.push_back(id);\n            inq[id]=1;\n        }\n    }\n\n    struct Move { int x1,y1,x2,y2; };\n    vector<Move> moves;\n    moves.reserve(10000);\n\n    auto push_id = [&](int id){\n        if (id==NONE) return;\n        if (child[id][0]==NONE) return; // leaf, no need\n        if (!inq[id]) { dq.push_back(id); inq[id]=1; }\n    };\n\n    auto do_swap = [&](int id1, int id2){\n        // swap values at two adjacent ids\n        swap(A[id1], A[id2]);\n        int x1=x_of[id1], y1=y_of[id1], x2=x_of[id2], y2=y_of[id2];\n        moves.push_back({x1,y1,x2,y2});\n    };\n\n    const int K_LIMIT = 10000;\n\n    while (!dq.empty() && (int)moves.size() < K_LIMIT) {\n        int id = dq.front(); dq.pop_front(); inq[id]=0;\n        // try push down once\n        int c0 = child[id][0];\n        int c1 = child[id][1];\n        if (c0==NONE) continue; // leaf\n        int v = A[id];\n        int mchild = c0;\n        if (A[c1] < A[mchild]) mchild = c1;\n        if (v > A[mchild]) {\n            // swap with smaller child\n            do_swap(id, mchild);\n            if ((int)moves.size() >= K_LIMIT) break;\n            // After swap, potential violations around: parents of id (now has smaller value), and the child subtree\n            // Enqueue parents of id (because id's value decreased, could violate upwards? Actually parent might be > id fixed; but we keep to down-heapify; still enqueue parents to allow them to push down potentially)\n            push_id(parent[id][0]);\n            push_id(parent[id][1]);\n            // Enqueue id again to continue pushing down if needed\n            push_id(id);\n            // Enqueue the child we swapped into (the larger value moved there)\n            push_id(mchild);\n            // Also enqueue sibling parent nodes of mchild (their parents)\n            push_id(parent[mchild][0]);\n            push_id(parent[mchild][1]);\n        } else {\n            // Optional: small sift-up step to speed convergence\n            // If this node is smaller than any parent, swap up with the larger violating parent (one step).\n            // We choose the parent with larger value among those violating to move small up faster.\n            int p0 = parent[id][0], p1 = parent[id][1];\n            int pick = NONE;\n            if (p0!=NONE && A[p0] > A[id]) pick = p0;\n            if (p1!=NONE && A[p1] > A[id]) {\n                if (pick==NONE || A[p1] > A[pick]) pick = p1;\n            }\n            if (pick != NONE) {\n                // swap up\n                do_swap(pick, id);\n                if ((int)moves.size() >= K_LIMIT) break;\n                // Enqueue neighborhoods\n                push_id(parent[pick][0]);\n                push_id(parent[pick][1]);\n                push_id(pick);\n                push_id(id);\n                push_id(parent[id][0]);\n                push_id(parent[id][1]);\n            }\n        }\n    }\n\n    // Output\n    cout << moves.size() << '\\n';\n    for (auto &mv : moves) {\n        cout << mv.x1 << ' ' << mv.y1 << ' ' << mv.x2 << ' ' << mv.y2 << '\\n';\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D,N;\n    if(!(cin>>D>>N)) return 0;\n    vector<vector<int>> obs(D, vector<int>(D, 0));\n    for(int k=0;k<N;k++){\n        int r,c; cin>>r>>c;\n        obs[r][c]=1;\n    }\n    // Entrance\n    int ei = 0, ej = (D-1)/2;\n    // Build list of free cells excluding entrance\n    vector<Pos> cells; cells.reserve(D*D-1-N);\n    // Snake order by rows, skipping obstacles and entrance\n    for(int i=0;i<D;i++){\n        if(i%2==0){\n            for(int j=0;j<D;j++){\n                if(i==ei && j==ej) continue;\n                if(obs[i][j]) continue;\n                cells.push_back({i,j});\n            }\n        }else{\n            for(int jj=D-1;jj>=0;jj--){\n                int j=jj;\n                if(i==ei && j==ej) continue;\n                if(obs[i][j]) continue;\n                cells.push_back({i,j});\n            }\n        }\n    }\n    int M = (int)cells.size(); // should be D*D-1-N\n    // Map position index for quick lookup\n    vector<vector<int>> posIndex(D, vector<int>(D, -1));\n    for(int idx=0; idx<M; idx++){\n        posIndex[cells[idx].i][cells[idx].j] = idx;\n    }\n    // Occupancy grid: 0 empty, 1 occupied (container), -1 obstacle, -2 entrance (treated as empty for BFS)\n    vector<vector<int>> occ(D, vector<int>(D, 0));\n    for(int i=0;i<D;i++) for(int j=0;j<D;j++){\n        if(obs[i][j]) occ[i][j] = -1;\n    }\n    occ[ei][ej] = -2;\n\n    // For recording where each t is placed\n    vector<Pos> loc_of_id(M, {-1,-1});\n    vector<int> id_at_cell(M, -1); // by path index\n    vector<int> free_pos(M, 1);\n\n    auto bfs_reach = [&](){\n        vector<vector<char>> vis(D, vector<char>(D, 0));\n        queue<Pos> q;\n        q.push({ei,ej});\n        vis[ei][ej]=1;\n        int di[4]={-1,1,0,0};\n        int dj[4]={0,0,-1,1};\n        while(!q.empty()){\n            auto p=q.front(); q.pop();\n            for(int k=0;k<4;k++){\n                int ni=p.i+di[k], nj=p.j+dj[k];\n                if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                if(vis[ni][nj]) continue;\n                if(occ[ni][nj]==0 || occ[ni][nj]==-2){ // empty or entrance\n                    vis[ni][nj]=1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n        return vis;\n    };\n\n    // Online placement\n    for(int d=0; d<M; d++){\n        int t; cin>>t;\n        // compute reachable empty cells mask\n        auto vis = bfs_reach();\n        int ideal = t; if(ideal<0) ideal=0; if(ideal>=M) ideal=M-1;\n        int chosen_idx = -1;\n        // search window expanding\n        int W = 12;\n        int maxW = M;\n        for(int w=W; w<=maxW && chosen_idx==-1; w+=12){\n            int L = max(0, ideal - w);\n            int R = min(M-1, ideal + w);\n            // Collect reachable free candidates with minimal |pos-ideal|\n            int bestScore = INT_MAX;\n            int bestIdx = -1;\n            for(int pos=L; pos<=R; pos++){\n                if(!free_pos[pos]) continue;\n                Pos p = cells[pos];\n                if(!vis[p.i][p.j]) continue;\n                int score = abs(pos - ideal);\n                if(score < bestScore){\n                    bestScore = score;\n                    bestIdx = pos;\n                }else if(score == bestScore && bestIdx!=-1){\n                    // tie-break: for larger t, prefer larger pos; for smaller t, prefer smaller pos\n                    if(t*2 >= M){\n                        if(pos > bestIdx) bestIdx = pos;\n                    }else{\n                        if(pos < bestIdx) bestIdx = pos;\n                    }\n                }\n            }\n            if(bestIdx!=-1) chosen_idx = bestIdx;\n        }\n        if(chosen_idx==-1){\n            // Fallback: pick any reachable free cell, prefer towards ideal direction\n            int bestIdx=-1, bestScore=INT_MAX;\n            for(int pos=0; pos<M; pos++){\n                if(!free_pos[pos]) continue;\n                Pos p=cells[pos];\n                if(!vis[p.i][p.j]) continue;\n                int score = abs(pos - ideal);\n                if(score < bestScore){\n                    bestScore=score; bestIdx=pos;\n                }\n            }\n            if(bestIdx!=-1) chosen_idx=bestIdx;\n        }\n        if(chosen_idx==-1){\n            // As a last resort, pick any free (shouldn't happen because all free cells are reachable by guarantee if empty)\n            for(int pos=0; pos<M; pos++){\n                if(free_pos[pos]){\n                    chosen_idx=pos; break;\n                }\n            }\n        }\n        // Place\n        Pos place = cells[chosen_idx];\n        cout<<place.i<<\" \"<<place.j<<\"\\n\"<<flush;\n        occ[place.i][place.j] = 1;\n        free_pos[chosen_idx]=0;\n        id_at_cell[chosen_idx]=t;\n        loc_of_id[t]=place;\n    }\n\n    // Extraction: repeatedly remove smallest-ID reachable\n    // Build a map from (i,j) to ID\n    vector<vector<int>> id_grid(D, vector<int>(D, -1));\n    for(int pos=0; pos<M; pos++){\n        if(id_at_cell[pos]>=0){\n            Pos p = cells[pos];\n            id_grid[p.i][p.j] = id_at_cell[pos];\n        }\n    }\n\n    vector<pair<int,int>> output_order;\n    output_order.reserve(M);\n\n    auto bfs_reach_cells = [&](){\n        vector<vector<char>> vis(D, vector<char>(D, 0));\n        queue<Pos> q;\n        q.push({ei,ej});\n        vis[ei][ej]=1;\n        int di[4]={-1,1,0,0};\n        int dj[4]={0,0,-1,1};\n        while(!q.empty()){\n            auto p=q.front(); q.pop();\n            for(int k=0;k<4;k++){\n                int ni=p.i+di[k], nj=p.j+dj[k];\n                if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                if(vis[ni][nj]) continue;\n                // reachable through empty cells only\n                if(occ[ni][nj]==0 || occ[ni][nj]==-2){\n                    vis[ni][nj]=1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n        return vis;\n    };\n\n    for(int removed=0; removed<M; removed++){\n        // compute which occupied cells are currently reachable: cell must be adjacent via empty path to entrance\n        // A container is removable if its cell is reachable from entrance through empty cells; i.e., the container's cell must itself be marked reachable when considering it as occupied? The definition says:\n        // \"The square containing the container to be transported out must be reachable from the entrance by only passing through adjacent empty squares\"\n        // That implies the path does not include the container square (since it's not empty). Typically the last step into its square would require the square to be empty, which is impossible. Usually interpretation is: there exists a path of empty cells to a neighbor of the target, and then we can remove it. However AtCoder's typical definition here counts the container square as allowed at endpoint.\n        // The common approach is to allow reaching its cell if we treat it as empty for reachability test of candidate. We'll check neighbors.\n        auto vis = bfs_reach_cells();\n        int bestID = INT_MAX;\n        Pos bestP{-1,-1};\n        for(int i=0;i<D;i++){\n            for(int j=0;j<D;j++){\n                if(id_grid[i][j] < 0) continue;\n                // check if reachable: there exists a path of empty cells from entrance to a neighbor of (i,j)\n                bool reachable = false;\n                int di[4]={-1,1,0,0};\n                int dj[4]={0,0,-1,1};\n                for(int k=0;k<4;k++){\n                    int ni=i+di[k], nj=j+dj[k];\n                    if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                    if(vis[ni][nj]) { reachable=true; break; }\n                }\n                if(!reachable) continue;\n                int curID = id_grid[i][j];\n                if(curID < bestID){\n                    bestID = curID;\n                    bestP = {i,j};\n                }\n            }\n        }\n        if(bestID==INT_MAX){\n            // Fallback: if none reachable by neighbor method, allow cells that themselves are marked reachable if we consider them empty\n            // Temporarily mark all occupied as walls; vis marks empty reachables. None found -> choose any with minimal ID that is adjacent via zero? We'll pick minimal ID anywhere.\n            for(int i=0;i<D;i++){\n                for(int j=0;j<D;j++){\n                    if(id_grid[i][j] >= 0){\n                        int curID = id_grid[i][j];\n                        if(curID < bestID){\n                            bestID=curID; bestP={i,j};\n                        }\n                    }\n                }\n            }\n        }\n        // Output and remove\n        cout<<bestP.i<<\" \"<<bestP.j<<\"\\n\";\n        // Mark empty now\n        occ[bestP.i][bestP.j] = 0;\n        id_grid[bestP.i][bestP.j] = -1;\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int DX[4] = {1,-1,0,0};\nstatic const int DY[4] = {0,0,1,-1};\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    vector<int> d(n*n);\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            int c; cin >> c;\n            d[i*n+j] = c;\n        }\n    }\n    int C = m+1;\n    auto idxOf = [&](int i,int j){ return i*n+j; };\n    auto inb = [&](int i,int j){ return (unsigned)i < (unsigned)n && (unsigned)j < (unsigned)n; };\n\n    // Build adjacency matrix from input grid\n    vector<vector<char>> A(C, vector<char>(C, 0));\n    // Internal adjacencies\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            int u = d[i*n+j];\n            if(i+1<n){\n                int v = d[(i+1)*n+j];\n                if(u!=v){ A[u][v]=A[v][u]=1; }\n            }\n            if(j+1<n){\n                int v = d[i*n+(j+1)];\n                if(u!=v){ A[u][v]=A[v][u]=1; }\n            }\n        }\n    }\n    // Zero adjacency through boundary\n    for(int i=0;i<n;i++){\n        int c1 = d[i*n+0];\n        int c2 = d[i*n+(n-1)];\n        A[0][c1]=A[c1][0]=1;\n        A[0][c2]=A[c2][0]=1;\n    }\n    for(int j=0;j<n;j++){\n        int c1 = d[0*n+j];\n        int c2 = d[(n-1)*n+j];\n        A[0][c1]=A[c1][0]=1;\n        A[0][c2]=A[c2][0]=1;\n    }\n\n    // adjCnt counts edges between colors in current d\n    vector<vector<int>> adjCnt(C, vector<int>(C, 0));\n    auto recomputeAdjCnt = [&](){\n        for(int u=0;u<C;u++) fill(adjCnt[u].begin(), adjCnt[u].end(), 0);\n        // internal edges\n        for(int i=0;i<n;i++){\n            for(int j=0;j<n;j++){\n                int u = d[i*n+j];\n                if(i+1<n){\n                    int v = d[(i+1)*n+j];\n                    if(u!=v){ adjCnt[u][v]++; adjCnt[v][u]++; }\n                }\n                if(j+1<n){\n                    int v = d[i*n+(j+1)];\n                    if(u!=v){ adjCnt[u][v]++; adjCnt[v][u]++; }\n                }\n            }\n        }\n        // boundary with 0\n        for(int i=0;i<n;i++){\n            int c1 = d[i*n+0];\n            int c2 = d[i*n+(n-1)];\n            if(c1!=0){ adjCnt[0][c1]++; adjCnt[c1][0]++; }\n            if(c2!=0){ adjCnt[0][c2]++; adjCnt[c2][0]++; }\n        }\n        for(int j=0;j<n;j++){\n            int c1 = d[0*n+j];\n            int c2 = d[(n-1)*n+j];\n            if(c1!=0){ adjCnt[0][c1]++; adjCnt[c1][0]++; }\n            if(c2!=0){ adjCnt[0][c2]++; adjCnt[c2][0]++; }\n        }\n    };\n    recomputeAdjCnt();\n\n    vector<int> totalCells(C, 0);\n    for(int v : d) totalCells[v]++;\n\n    vector<char> allowZeroAdj(C, 0);\n    for(int c=0;c<C;c++) allowZeroAdj[c] = A[0][c];\n\n    // Pre-group cells per color (dynamic updates will be lazy; we can just iterate all cells)\n    // Time guard\n    auto t0 = chrono::high_resolution_clock::now();\n    const double TIME_LIMIT = 1.80;\n\n    // Helper: connectivity check for color c if removing cell p\n    vector<char> vis(n*n, 0);\n    auto connectedAfterRemoval = [&](int c, int p)->bool{\n        if(totalCells[c] <= 1) return true; // removing last cell ok? Actually color must remain connected; empty set is connected by convention? Problem says squares of color c must be connected; if zero squares, arguably connected vacuously. But input guarantees at least one cell per color; created map allows zero? The problem states 0<=d_{i,j}<=m and for every color c squares must be connected; if a color has zero squares, empty is connected? Typically empty set is connected; however safer to keep at least one cell. We avoid removing the last cell by other logic: removing makes totalCells[c]-1 >= 1 should hold ideally. We'll enforce not to remove if totalCells[c]==1.\n        if(totalCells[c] == 1) return false; // don't delete the last cell\n        int pi = p / n, pj = p % n;\n        int neighCount = 0;\n        int start = -1;\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            int q = ni*n+nj;\n            if(d[q] == c){ neighCount++; start = q; }\n        }\n        if(neighCount <= 1) return true; // removing leaf or isolated won't disconnect\n        // BFS over c cells excluding p\n        fill(vis.begin(), vis.end(), 0);\n        deque<int> dq;\n        dq.push_back(start);\n        vis[start] = 1;\n        int reach = 1;\n        while(!dq.empty()){\n            int v = dq.front(); dq.pop_front();\n            int vi = v / n, vj = v % n;\n            for(int dir=0;dir<4;dir++){\n                int ni = vi + DX[dir], nj = vj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int u = ni*n+nj;\n                if(u==p) continue;\n                if(!vis[u] && d[u]==c){\n                    vis[u]=1; dq.push_back(u); reach++;\n                }\n            }\n        }\n        return reach == totalCells[c]-1;\n    };\n\n    // Attempt iterative greedy removals\n    std::mt19937 rng(712367);\n    bool improved = true;\n    int iter = 0;\n    while(improved){\n        improved = false;\n        iter++;\n        // Candidate order: shuffle all indices to spread work\n        vector<int> order(n*n);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n\n        for(int p : order){\n            int c = d[p];\n            if(c==0) continue;\n            if(!allowZeroAdj[c]) continue; // cannot remove cells of colors not adjacent to 0 originally\n            if(totalCells[c] <= 1) continue; // keep at least one cell per color\n            // Local neighbor colors\n            int pi = p / n, pj = p % n;\n            // Check neighbor colors constraints for 0 adjacency\n            bool ok = true;\n            int sameNeigh = 0;\n            array<int,4> neighColors;\n            int neighColorsCnt = 0;\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int q = ni*n+nj;\n                int y = d[q];\n                neighColors[neighColorsCnt++] = y;\n                if(y == c){ sameNeigh++; continue; }\n                if(!allowZeroAdj[y]){ ok = false; break; } // would create forbidden 0-y adjacency\n            }\n            if(!ok) continue;\n\n            // Preserve required adjacencies c-d\n            // For each neighbor y!=c in 4-neigh, compute k edges between c and y contributed by p\n            // If adjCnt[c][y] == k then removing would break adjacency c-y entirely: forbid\n            for(int idx=0; idx<neighColorsCnt; idx++){\n                int y = neighColors[idx];\n                if(y==c) continue;\n                if(A[c][y]){\n                    int k = 0;\n                    // Count contributions of p to c-y edges: each side where neighbor y contributes 1\n                    for(int dir=0;dir<4;dir++){\n                        int ni = pi + DX[dir], nj = pj + DY[dir];\n                        if(!inb(ni,nj)) continue;\n                        int q = ni*n+nj;\n                        if(d[q]==y) k++;\n                    }\n                    if(adjCnt[c][y] == k){ ok = false; break; }\n                }\n            }\n            if(!ok) continue;\n\n            // Preserve c-0 adjacency if originally required. Since allowZeroAdj[c] is true, we must ensure adjCnt[0][c] stays > 0.\n            // Removing this cell may increase c-0 adjacency if neighbors are 0? Actually we turn c to 0; that removes some c-0 edges if p was at boundary having 0 outside edges counted via boundary.\n            // We need to check if removing p would eliminate the last 0-c adjacency. Compute contributions of p to 0-c adjacency:\n            int k0 = 0;\n            // boundary contributions: if p is at boundary, there is at least one edge to outside 0.\n            if(pi==0) k0++;\n            if(pi==n-1) k0++;\n            if(pj==0) k0++;\n            if(pj==n-1) k0++;\n            // Also if any neighbor is 0 currently (internal 0), counts too.\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                if(d[ni*n+nj]==0) k0++;\n            }\n            if(A[0][c]){ // must keep adjacency\n                if(adjCnt[0][c] == k0){\n                    ok = false;\n                }\n            }\n            if(!ok) continue;\n\n            // Connectivity of c\n            if(!connectedAfterRemoval(c, p)) continue;\n\n            // Perform removal: update d, counts, adjCnt\n            // First, adjust adjCnt for edges affected\n            // Subtract edges between p and its neighbors (c-y or c-0 if neighbor outside or 0)\n            // Internal neighbors: if neighbor color y != c, adjCnt[c][y]-- for each such edge\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(inb(ni,nj)){\n                    int y = d[ni*n+nj];\n                    if(y != c){\n                        adjCnt[c][y]--; adjCnt[y][c]--;\n                    }\n                    // Later we will add 0-y edges after setting p to 0\n                }else{\n                    // Edge to outside 0\n                    adjCnt[0][c]--; adjCnt[c][0]--;\n                }\n            }\n            // Now set cell to 0\n            d[p] = 0;\n            totalCells[c]--;\n\n            // Add new edges between 0 and neighbors y (including c) and boundary\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(inb(ni,nj)){\n                    int y = d[ni*n+nj];\n                    if(y != 0){\n                        adjCnt[0][y]++; adjCnt[y][0]++;\n                    }\n                }else{\n                    // boundary 0 with cell p now 0 doesn't add any 0-0 count; no need\n                }\n            }\n\n            improved = true;\n\n            // Optional: early exit on time\n            auto t1 = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(t1 - t0).count();\n            if(elapsed > TIME_LIMIT) break;\n        }\n        auto t1 = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(t1 - t0).count();\n        if(elapsed > TIME_LIMIT) break;\n    }\n\n    // Output grid\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            if(j) cout << ' ';\n            cout << d[i*n+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    // Random generator\n    uint64_t seed = chrono::high_resolution_clock::now().time_since_epoch().count();\n    mt19937_64 rng(seed);\n    uniform_int_distribution<int> coin(0, 1);\n\n    // Parameters\n    int K = max(2, N / 2); // items per query\n    K = min(K, N); // ensure <= N\n\n    vector<long long> score(N, 0); // correlation scores\n\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n\n    // We will store last used L,R to allow safe dummy if needed (not necessary here)\n    for (int q = 0; q < Q; q++) {\n        // Choose K distinct indices by shuffling\n        shuffle(idx.begin(), idx.end(), rng);\n        int k = K;\n        if (k > N) k = N;\n        if (k < 2) k = 2; // must have both sides non-empty\n\n        vector<int> L, R;\n        L.reserve(k/2+1);\n        R.reserve(k/2+1);\n\n        // Alternate split to balance sizes\n        for (int t = 0; t < k; t++) {\n            if (t % 2 == 0) L.push_back(idx[t]);\n            else R.push_back(idx[t]);\n        }\n        // Edge case: if R ended up empty due to k==1 (we enforced k>=2), so safe.\n\n        // Output query\n        cout << (int)L.size() << \" \" << (int)R.size();\n        for (int v : L) cout << \" \" << v;\n        for (int v : R) cout << \" \" << v;\n        cout << \"\\n\" << flush;\n\n        // Read response\n        string s;\n        if (!(cin >> s)) return 0;\n        int y = 0;\n        if (s == \"<\") y = -1;\n        else if (s == \">\") y = +1;\n        else y = 0; // \"=\"\n\n        if (y != 0) {\n            // Update scores\n            for (int v : L) score[v] += y;     // +1 if '>' (L heavier), -1 if '<'\n            for (int v : R) score[v] -= y;     // inverse\n        }\n    }\n\n    // Build estimated weights from scores\n    long long mn = *min_element(score.begin(), score.end());\n    vector<double> est(N);\n    for (int i = 0; i < N; i++) {\n        long long s = score[i] - mn + 1; // >=1\n        double x = (double)s;\n        // power transform to accentuate differences\n        double e = pow(x, 1.5);\n        if (!isfinite(e) || e <= 0) e = 1.0;\n        est[i] = e;\n    }\n\n    // Order items by estimated weight descending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    stable_sort(order.begin(), order.end(), [&](int a, int b){\n        if (est[a] != est[b]) return est[a] > est[b];\n        return a < b;\n    });\n\n    // Greedy LPT assignment\n    vector<int> assign(N, 0);\n    vector<double> bins(D, 0.0);\n    // min-heap of (binsum, bin_id)\n    using P = pair<double,int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    for (int d = 0; d < D; d++) pq.emplace(0.0, d);\n\n    for (int v : order) {\n        auto [sumv, d] = pq.top(); pq.pop();\n        assign[v] = d;\n        sumv += est[v];\n        bins[d] = sumv;\n        pq.emplace(sumv, d);\n    }\n\n    // Local search on estimates\n    auto compute_var = [&](const vector<double>& bs)->double{\n        double mean = 0;\n        for (double x : bs) mean += x;\n        mean /= D;\n        double var = 0;\n        for (double x : bs) { double d = x - mean; var += d*d; }\n        return var / D;\n    };\n\n    // Build bin -> items\n    vector<vector<int>> binItems(D);\n    for (int i = 0; i < N; i++) binItems[assign[i]].push_back(i);\n\n    // Helper to update after moves\n    auto move_item = [&](int i, int from, int to){\n        if (from == to) return;\n        bins[from] -= est[i];\n        bins[to]   += est[i];\n        assign[i] = to;\n        auto &vf = binItems[from];\n        for (size_t p = 0; p < vf.size(); ++p) if (vf[p]==i){ vf[p]=vf.back(); vf.pop_back(); break; }\n        binItems[to].push_back(i);\n    };\n\n    int LS_ITERS = 2000;\n    for (int it = 0; it < LS_ITERS; it++) {\n        // Find heaviest and lightest\n        int h = max_element(bins.begin(), bins.end()) - bins.begin();\n        int l = min_element(bins.begin(), bins.end()) - bins.begin();\n        if (h == l) break;\n        double bestGain = 0.0;\n        int bestI = -1, bestJ = -1;\n        // Try move a single item from h to l\n        for (int i : binItems[h]) {\n            double dh = est[i];\n            double new_h = bins[h] - dh;\n            double new_l = bins[l] + dh;\n            double old_var = 0; // compute delta only for two bins approximate\n            // Use approximate improvement: reduce spread\n            double spread_before = bins[h] - bins[l];\n            double spread_after  = new_h - new_l;\n            double gain = spread_before - spread_after; // positive is good\n            if (gain > bestGain) { bestGain = gain; bestI = i; bestJ = -1; }\n        }\n        // Try swap one from h with one from l\n        int limH = (int)binItems[h].size();\n        int limL = (int)binItems[l].size();\n        // Limit checks to keep runtime bounded\n        int sampH = min(limH, 20);\n        int sampL = min(limL, 20);\n        // sample some items\n        vector<int> candH = binItems[h];\n        vector<int> candL = binItems[l];\n        if ((int)candH.size() > sampH) {\n            shuffle(candH.begin(), candH.end(), rng);\n            candH.resize(sampH);\n        }\n        if ((int)candL.size() > sampL) {\n            shuffle(candL.begin(), candL.end(), rng);\n            candL.resize(sampL);\n        }\n        for (int i : candH) for (int j : candL) {\n            double dh = est[i], dl = est[j];\n            double new_h = bins[h] - dh + dl;\n            double new_l = bins[l] - dl + dh;\n            double spread_before = bins[h] - bins[l];\n            double spread_after  = new_h - new_l;\n            double gain = spread_before - spread_after;\n            if (gain > bestGain) { bestGain = gain; bestI = i; bestJ = j; }\n        }\n        if (bestGain <= 1e-9) break;\n        if (bestJ == -1) {\n            move_item(bestI, h, l);\n        } else {\n            int i = bestI, j = bestJ;\n            // swap i in h with j in l\n            // implement as two moves\n            move_item(i, h, l);\n            move_item(j, l, h);\n        }\n    }\n\n    // Output final assignment\n    for (int i = 0; i < N; i++) {\n        if (i) cout << ' ';\n        cout << assign[i];\n    }\n    cout << \"\\n\" << flush;\n\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Heuristic solver for AHC026-like problem\n// n=200, m=10 fixed in tests, but code keeps generality.\n\nstruct Solver {\n    int n, m, H;\n    vector<vector<int>> st; // stacks: bottom -> top\n    vector<int> whereS; // stack index (0..m-1) for each box (1..n)\n    vector<int> whereIdx; // index in stack vector\n    vector<pair<int,int>> ops; // (v,i) with i in [0..m]\n    vector<char> removed;\n\n    void read_input() {\n        cin >> n >> m;\n        H = n / m;\n        st.assign(m, {});\n        whereS.assign(n+1, -1);\n        whereIdx.assign(n+1, -1);\n        removed.assign(n+1, 0);\n        for (int i = 0; i < m; ++i) {\n            st[i].resize(H);\n            for (int j = 0; j < H; ++j) {\n                int v; cin >> v;\n                st[i][j] = v;\n                whereS[v] = i;\n                whereIdx[v] = j;\n            }\n        }\n    }\n\n    inline int top_value(int i) const {\n        if (st[i].empty()) return INT_MAX/4; // treat empty as very large top for preference\n        return st[i].back();\n    }\n\n    void do_move(int v, int dest) {\n        // Operation 1: move suffix starting at v from its current stack to top of dest (1-based output dest+1)\n        int s = whereS[v];\n        if (s == dest) {\n            // avoid self-move; but spec allows it; however it's wasteful. We should not call this.\n            // To be safe, don't perform and don't record.\n            return;\n        }\n        int idx = whereIdx[v];\n        int k = (int)st[s].size() - idx; // number of boxes moved\n        // record op\n        ops.emplace_back(v, dest+1);\n        // move elements\n        // append to dest\n        st[dest].reserve(st[dest].size() + k);\n        for (int i = idx; i < (int)st[s].size(); ++i) {\n            int x = st[s][i];\n            st[dest].push_back(x);\n            whereS[x] = dest;\n            whereIdx[x] = (int)st[dest].size() - 1;\n        }\n        // erase from source\n        st[s].resize(idx);\n    }\n\n    void do_carry(int v) {\n        // Operation 2: carry out v; it must be top of its stack and be the smallest remaining.\n        int s = whereS[v];\n        if (s == -1) return; // already removed\n        // record op\n        ops.emplace_back(v, 0);\n        // pop\n        int topv = st[s].back();\n        if (topv != v) {\n            // Shouldn't happen; guard\n            // Find v and remove it (fallback)\n            auto it = find(st[s].begin(), st[s].end(), v);\n            if (it != st[s].end()) {\n                st[s].erase(it);\n                // rebuild indices in this stack\n                for (int i = 0; i < (int)st[s].size(); ++i) whereIdx[st[s][i]] = i;\n            }\n        } else {\n            st[s].pop_back();\n        }\n        whereS[v] = -1;\n        whereIdx[v] = -1;\n        removed[v] = 1;\n    }\n\n    int choose_dest(int v) {\n        int s = whereS[v];\n        // Preferred bin stack\n        int bin = (v - 1) / H; // 0-based\n        int d_pref = min(bin, m-1); // guard\n        if (d_pref != s) return d_pref;\n        // choose another stack:\n        int best = -1;\n        int bestTop = -1;\n        int bestHeight = INT_MAX;\n        for (int i = 0; i < m; ++i) if (i != s) {\n            int tv = top_value(i);\n            // prefer larger top value; empty stack has INT_MAX/4 which is largest\n            if (tv > bestTop) {\n                bestTop = tv;\n                bestHeight = (int)st[i].size();\n                best = i;\n            } else if (tv == bestTop) {\n                int h = (int)st[i].size();\n                if (h < bestHeight) {\n                    bestHeight = h;\n                    best = i;\n                }\n            }\n        }\n        if (best == -1) best = (s+1)%m;\n        return best;\n    }\n\n    void solve() {\n        // Process in ascending order\n        for (int t = 1; t <= n; ++t) {\n            if (removed[t]) continue;\n            int s = whereS[t];\n            // while t not at top of its stack, move suffix including t to chosen destination\n            if (st[s].empty()) continue; // shouldn't\n            if (st[s].back() == t) {\n                do_carry(t);\n                continue;\n            }\n            int dest = choose_dest(t);\n            // perform move so that t becomes top of dest\n            do_move(t, dest);\n            // Now t should be top at dest\n            do_carry(t);\n            // No further consolidation to keep it simple\n            if ((int)ops.size() >= 4999) {\n                // fallback: carry remaining if possible when already on top\n                for (int u = t+1; u <= n && (int)ops.size() < 5000; ++u) {\n                    if (!removed[u]) {\n                        int su = whereS[u];\n                        if (su != -1 && !st[su].empty() && st[su].back() == u) {\n                            do_carry(u);\n                        } else {\n                            // cannot finish, break\n                            break;\n                        }\n                    }\n                }\n                break;\n            }\n        }\n    }\n\n    void output() {\n        int K = (int)ops.size();\n        for (auto &p : ops) {\n            cout << p.first << \" \" << p.second << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver solver;\n    solver.read_input();\n    solver.solve();\n    solver.output();\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin>>N)) return 0;\n    vector<string> h(N-1), v(N);\n    for(int i=0;i<N-1;i++) cin>>h[i];\n    for(int i=0;i<N;i++) cin>>v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++) cin>>d[i][j];\n    }\n\n    auto inb = [&](int i,int j){ return 0<=i && i<N && 0<=j && j<N; };\n    auto canMove = [&](int i,int j,int dir)->bool{\n        // 0:R,1:D,2:L,3:U\n        if(dir==0){ if(j+1>=N) return false; return v[i][j]=='0'; }\n        if(dir==2){ if(j-1<0) return false; return v[i][j-1]=='0'; }\n        if(dir==1){ if(i+1>=N) return false; return h[i][j]=='0'; }\n        if(dir==3){ if(i-1<0) return false; return h[i-1][j]=='0'; }\n        return false;\n    };\n    auto step = [&](int &i,int &j,int dir){\n        if(dir==0) j++;\n        else if(dir==2) j--;\n        else if(dir==1) i++;\n        else if(dir==3) i--;\n    };\n    string DIR = \"RDLU\";\n    const int di[4]={0,1,0,-1};\n    const int dj[4]={1,0,-1,0};\n\n    // Build adjacency list for spanning tree\n    vector<vector<array<int,2>>> nbr(N, vector<array<int,2>>());\n    // not used; we will get neighbors on the fly\n\n    // Spanning tree DFS with neighbor order by descending d\n    vector<vector<int>> visited(N, vector<int>(N,0));\n    vector<vector<int>> parentDir(N, vector<int>(N,-1)); // direction from parent to node\n    vector<Pos> order; order.reserve(N*N*2);\n    string baseMoves;\n    baseMoves.reserve(2*N*N);\n\n    function<void(int,int)> dfs = [&](int i,int j){\n        visited[i][j]=1;\n        // prepare neighbors sorted by heuristic score (prefer higher d)\n        vector<pair<int,int>> cand; cand.reserve(4);\n        for(int dir=0;dir<4;dir++){\n            int ni=i+di[dir], nj=j+dj[dir];\n            if(!inb(ni,nj)) continue;\n            if(!canMove(i,j,dir)) continue;\n            if(visited[ni][nj]) continue;\n            cand.emplace_back(-(d[ni][nj]), dir);\n        }\n        sort(cand.begin(), cand.end());\n        for(auto [negw, dir]: cand){\n            int ni=i+di[dir], nj=j+dj[dir];\n            // move\n            baseMoves.push_back(DIR[dir]);\n            dfs(ni,nj);\n            // backtrack\n            baseMoves.push_back(DIR[(dir+2)%4]);\n        }\n    };\n    dfs(0,0);\n\n    // base path nodes reconstruction to know positions along moves\n    vector<Pos> baseNodes;\n    baseNodes.reserve(baseMoves.size()+1);\n    {\n        int i=0,j=0;\n        baseNodes.push_back({i,j});\n        for(char c: baseMoves){\n            int dir = (c=='R'?0: c=='D'?1: c=='L'?2:3);\n            if(!canMove(i,j,dir)){\n                // Should not happen\n            }\n            step(i,j,dir);\n            baseNodes.push_back({i,j});\n        }\n        // ends at (0,0) by DFS tree property\n    }\n\n    // Ensure coverage: DFS tree covers all nodes; but double-check\n    // If somehow some nodes not visited due to walls mistakes, we would need correction, but the neighbor guard ensures feasibility.\n\n    // Precompute local loops for each cell\n    struct Loop {\n        vector<int> dirs; // sequence of dirs to execute starting at cell, ends at same cell\n    };\n    vector<vector<Loop>> loopOf(N, vector<Loop>(N));\n    auto tryAddLoopAt = [&](int i,int j)->Loop{\n        // Try 4-cycles in four orientations using (R,D), (D,L), (L,U), (U,R)\n        // For each orientation, check the square exists and all 4 edges are open.\n        // Orientation 0: R then D: sequence R D L U\n        // Start at (i,j), need cells (i,j+1), (i+1,j+1), (i+1,j)\n        // Check within bounds\n        // We'll try all four and pick the one maximizing sum of d over the 4 nodes (as heuristic)\n        struct Cand { int score; vector<int> dirs; };\n        vector<Cand> cands;\n        // helper to evaluate a 4-cycle given two orthogonal dirs a and b, sequence a, b, opposite(a), opposite(b)\n        auto add4 = [&](int a, int b){\n            int i0=i, j0=j;\n            if(!canMove(i0,j0,a)) return;\n            int i1=i0+di[a], j1=j0+dj[a];\n            if(!canMove(i1,j1,b)) return;\n            int i2=i1+di[b], j2=j1+dj[b];\n            int a2 = (a+2)%4, b2=(b+2)%4;\n            if(!canMove(i2,j2,a2)) return;\n            int i3=i2+di[a2], j3=j2+dj[a2];\n            if(i3!=i1 || j3!=j1) return; // safety\n            if(!canMove(i3,j3,b2)) return;\n            int i4=i3+di[b2], j4=j3+dj[b2];\n            if(i4!=i || j4!=j) return;\n            int score = d[i][j] + d[i1][j1] + d[i2][j2] + d[i3][j3];\n            cands.push_back({score, {a,b,a2,b2}});\n        };\n        add4(0,1); // R,D\n        add4(1,2); // D,L\n        add4(2,3); // L,U\n        add4(3,0); // U,R\n        if(!cands.empty()){\n            // pick best score\n            auto best = *max_element(cands.begin(), cands.end(), [](const Cand&x,const Cand&y){return x.score<y.score;});\n            return Loop{best.dirs};\n        }\n        // Fallback: 2-step ping-pong to best neighbor by d\n        int bestDir=-1, bestScore=-1;\n        for(int dir=0;dir<4;dir++){\n            if(!canMove(i,j,dir)) continue;\n            int ni=i+di[dir], nj=j+dj[dir];\n            int sc = d[i][j] + d[ni][nj];\n            if(sc>bestScore){ bestScore=sc; bestDir=dir; }\n        }\n        if(bestDir!=-1){\n            return Loop{ vector<int>{bestDir, (bestDir+2)%4} };\n        }\n        // Isolated (should not happen), empty loop\n        return Loop{ vector<int>() };\n    };\n\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) loopOf[i][j]=tryAddLoopAt(i,j);\n\n    // Choose hotspots\n    struct Cell { int i,j,w; };\n    vector<Cell> cells; cells.reserve(N*N);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cells.push_back({i,j,d[i][j]});\n    sort(cells.begin(), cells.end(), [](const Cell&a,const Cell&b){ return a.w>b.w; });\n    int M = (int)cells.size()/10; if(M<1) M=1; if(M>200) M=200;\n    vector<vector<int>> isHot(N, vector<int>(N,0));\n    for(int k=0;k<M && k<(int)cells.size();k++){\n        isHot[cells[k].i][cells[k].j]=1;\n    }\n\n    // Budget allocation\n    long long L0 = (long long)baseMoves.size();\n    long long B = 100000LL - L0;\n    if(B<0) B=0;\n\n    // Gather hotspot weights and loop costs\n    struct Hot { int i,j; int w; int cost; };\n    vector<Hot> hots;\n    hots.reserve(M);\n    for(auto &c: cells){\n        if((int)hots.size()>=M) break;\n        int i=c.i,j=c.j;\n        int cost = (int)loopOf[i][j].dirs.size();\n        if(cost==0) continue;\n        hots.push_back({i,j,c.w,cost});\n    }\n    if(hots.empty()){\n        // No loops possible anywhere (unlikely). Output base path.\n        cout<<baseMoves<<\"\\n\";\n        return 0;\n    }\n    // Compute total weight factor\n    long double totalScore=0;\n    for(auto &hcell: hots){\n        // Using score proportional to w / cost (more efficient loops get more repeats)\n        totalScore += (long double)hcell.w / (long double)max(1,hcell.cost);\n    }\n    // Count how many times each hotspot appears in base path (to cap repeats per occurrence)\n    unordered_map<long long, int> countInPath; countInPath.reserve(hots.size()*4);\n    auto keyOf = [&](int i,int j)->long long{ return ((long long)i<<20) ^ j; };\n    for(auto &hc: hots) countInPath[keyOf(hc.i,hc.j)] = 0;\n    for(auto &p: baseNodes){\n        long long key = keyOf(p.i,p.j);\n        auto it = countInPath.find(key);\n        if(it!=countInPath.end()) it->second++;\n    }\n    // Plan repeats per hotspot total\n    vector<long long> repeats(hots.size(), 0);\n    long long used=0;\n    for(size_t idx=0; idx<hots.size(); idx++){\n        auto &hc = hots[idx];\n        long double frac = ((long double)hc.w / (long double)max(1,hc.cost)) / totalScore;\n        long long targetCost = (long long) floor(frac * (long double)B);\n        long long rep = targetCost / hc.cost;\n        // Cap by occurrences * a per-visit cap to avoid overly long dwell per visit\n        int occ = countInPath[keyOf(hc.i,hc.j)];\n        long long perVisitCap = 50; // heuristic: up to 50 loops each time we pass\n        long long cap = (long long)occ * perVisitCap;\n        if(rep > cap) rep = cap;\n        repeats[idx]=rep;\n        used += rep * hc.cost;\n    }\n    if(used > B){\n        // Scale down\n        long double scale = (long double)B / (long double)max(1LL,used);\n        used = 0;\n        for(size_t idx=0; idx<hots.size(); idx++){\n            long long rep = (long long) floor(repeats[idx] * scale);\n            repeats[idx]=rep;\n            used += rep * hots[idx].cost;\n        }\n    }\n    // We might have residual budget; optionally distribute greedily\n    long long rem = B - used;\n    if(rem > 0){\n        // min-heap by efficiency inverse: cost/weight\n        struct Cand { long double score; int idx; };\n        // Greedy add one loop at a time until rem exhausted or some cap\n        // But to keep time small, add in chunks per hotspot occurrence\n        // We'll just do a simple round-robin on sorted by w/cost\n        vector<int> ord(hots.size());\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a,int b){\n            long double A = (long double)hots[a].w / hots[a].cost;\n            long double Bv= (long double)hots[b].w / hots[b].cost;\n            return A>Bv;\n        });\n        // allow a small extra per-visit cap\n        for(int pass=0; pass<2 && rem>0; pass++){\n            for(int id: ord){\n                if(rem<=0) break;\n                int cost = hots[id].cost;\n                if(cost==0) continue;\n                long long occ = countInPath[keyOf(hots[id].i,hots[id].j)];\n                long long capMore = occ * 10; // add up to 10 more per visit\n                long long canAdd = min(capMore, rem / cost);\n                if(canAdd<=0) continue;\n                repeats[id] += canAdd;\n                rem -= canAdd * cost;\n                if(rem<=0) break;\n            }\n        }\n    }\n\n    // Build a quick map from cell to which hotspot index and remaining repeats to inject\n    struct RepInfo { int idx; long long left; };\n    unordered_map<long long, RepInfo> repMap; repMap.reserve(hots.size()*2);\n    for(size_t idx=0; idx<hots.size(); idx++){\n        if(repeats[idx]==0) continue;\n        repMap[keyOf(hots[idx].i, hots[idx].j)] = {(int)idx, repeats[idx]};\n    }\n\n    // Inject loops along the base path\n    string out; out.reserve(min(100000LL, L0 + B));\n    int ci=0, cj=0;\n    out.push_back('\\0'); // placeholder to simplify logic? Better not. We'll build by iterating nodes.\n    out.clear();\n    auto emitLoop = [&](int i,int j, const Loop& lp, long long &budgetMoves){\n        for(int dir: lp.dirs){\n            if(budgetMoves==0) break;\n            out.push_back(DIR[dir]);\n            budgetMoves--;\n        }\n    };\n    long long budgetMoves = 100000LL; // enforce length limit during emission\n    // We'll iterate over base moves and: at each node before taking next base move, if it's a hotspot with remaining repeats, insert one loop, repeat until either no repeats or budget tight, but keep enough budget to finish remaining base moves.\n    // To ensure we can still output the rest of baseMoves, we track remaining base moves and avoid spending beyond 100000.\n    long long remainingBase = (long long)baseMoves.size();\n    ci = 0; cj = 0;\n    for(size_t t=0; t<baseNodes.size(); t++){\n        int i = baseNodes[t].i, j = baseNodes[t].j;\n        long long key = keyOf(i,j);\n        auto it = repMap.find(key);\n        if(it != repMap.end()){\n            int idx = it->second.idx;\n            long long &left = it->second.left;\n            const Loop &lp = loopOf[i][j];\n            int cost = (int)lp.dirs.size();\n            // Inject as many as possible while preserving budget for remaining base moves\n            while(left>0 && cost>0){\n                // Ensure we have budget after loop for remaining base moves\n                if(budgetMoves <= (long long)remainingBase) break;\n                long long free = budgetMoves - remainingBase;\n                if(free < cost) break;\n                emitLoop(i,j,lp,budgetMoves);\n                left--;\n            }\n            if(left==0) repMap.erase(it);\n        }\n        if(t < baseMoves.size()){\n            // emit next base move\n            char mv = baseMoves[t];\n            if(budgetMoves==0){\n                // Should not happen since base length <= 1e5 and we reserved, but guard\n                break;\n            }\n            out.push_back(mv);\n            budgetMoves--;\n            remainingBase--;\n        }\n    }\n    // Ensure closed at (0,0). The base path ends at (0,0). Injected loops are closed, so final position is also (0,0).\n    // Output\n    cout<<out<<\"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nlong long manh(const Pos& a, const Pos& b){\n    return llabs(a.i - b.i) + llabs(a.j - b.j);\n}\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 si, sj;\n    cin >> si >> sj;\n    vector<string> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\n    vector<string> t(M);\n    for(int k=0;k<M;k++) cin >> t[k];\n\n    // Positions for each letter\n    vector<vector<Pos>> pos(26);\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            int c = A[i][j]-'A';\n            pos[c].push_back({i,j});\n        }\n    }\n\n    // Remaining targets\n    vector<int> idxs(M);\n    iota(idxs.begin(), idxs.end(), 0);\n    vector<pair<int,int>> ops;\n    ops.reserve(5000);\n\n    Pos cur{si,sj};\n\n    // Pre-allocate buffers to reduce allocations\n    // We'll reuse dp arrays per candidate\n    for(int iter=0; iter<M; iter++){\n        // Select best next target index from idxs\n        long long bestCost = (1LL<<60);\n        int bestIdxPos = -1;\n        // For backtrack selection, we also want to remember first-step chosen index for quicker recompute\n        // But we'll recompute best path after selection for simplicity.\n        for(int p=0;p<(int)idxs.size();p++){\n            int k = idxs[p];\n            const string &s = t[k];\n            // Levels\n            const auto &L0 = pos[s[0]-'A'];\n            const auto &L1 = pos[s[1]-'A'];\n            const auto &L2 = pos[s[2]-'A'];\n            const auto &L3 = pos[s[3]-'A'];\n            const auto &L4 = pos[s[4]-'A'];\n            if(L0.empty()||L1.empty()||L2.empty()||L3.empty()||L4.empty()){\n                continue; // shouldn't happen, each letter exists\n            }\n            // DP forward costs only (no need to store parents here for selection)\n            int n0=L0.size(), n1=L1.size(), n2=L2.size(), n3=L3.size(), n4=L4.size();\n            static vector<long long> d0, d1, d2, d3, d4;\n            d0.assign(n0, (long long)4e18);\n            for(int i0=0;i0<n0;i0++) d0[i0] = manh(cur, L0[i0]);\n            d1.assign(n1, (long long)4e18);\n            for(int i1=0;i1<n1;i1++){\n                long long best = (long long)4e18;\n                for(int i0=0;i0<n0;i0++){\n                    long long v = d0[i0] + manh(L0[i0], L1[i1]);\n                    if(v < best) best = v;\n                }\n                d1[i1] = best;\n            }\n            d2.assign(n2, (long long)4e18);\n            for(int i2=0;i2<n2;i2++){\n                long long best = (long long)4e18;\n                for(int i1_=0;i1_<n1;i1_++){\n                    long long v = d1[i1_] + manh(L1[i1_], L2[i2]);\n                    if(v < best) best = v;\n                }\n                d2[i2] = best;\n            }\n            d3.assign(n3, (long long)4e18);\n            for(int i3=0;i3<n3;i3++){\n                long long best = (long long)4e18;\n                for(int i2_=0;i2_<n2;i2_++){\n                    long long v = d2[i2_] + manh(L2[i2_], L3[i3]);\n                    if(v < best) best = v;\n                }\n                d3[i3] = best;\n            }\n            d4.assign(n4, (long long)4e18);\n            for(int i4=0;i4<n4;i4++){\n                long long best = (long long)4e18;\n                for(int i3_=0;i3_<n3;i3_++){\n                    long long v = d3[i3_] + manh(L3[i3_], L4[i4]);\n                    if(v < best) best = v;\n                }\n                d4[i4] = best;\n            }\n            long long cand = *min_element(d4.begin(), d4.end());\n            if(cand < bestCost){\n                bestCost = cand;\n                bestIdxPos = p;\n            }\n        }\n        if(bestIdxPos == -1){\n            // Fallback: if something went wrong, break\n            break;\n        }\n        // Recompute path for selected target and output operations\n        int k = idxs[bestIdxPos];\n        const string &s = t[k];\n        const auto &L0 = pos[s[0]-'A'];\n        const auto &L1 = pos[s[1]-'A'];\n        const auto &L2 = pos[s[2]-'A'];\n        const auto &L3 = pos[s[3]-'A'];\n        const auto &L4 = pos[s[4]-'A'];\n        int n0=L0.size(), n1=L1.size(), n2=L2.size(), n3=L3.size(), n4=L4.size();\n        vector<long long> d0(n0), d1(n1), d2(n2), d3(n3), d4(n4);\n        vector<int> p0(n1,-1), p1(n2,-1), p2(n3,-1), p3(n4,-1);\n        for(int i0=0;i0<n0;i0++) d0[i0] = manh(cur, L0[i0]);\n        for(int i1=0;i1<n1;i1++){\n            long long best = (long long)4e18; int arg=-1;\n            for(int i0=0;i0<n0;i0++){\n                long long v = d0[i0] + manh(L0[i0], L1[i1]);\n                if(v < best){best = v; arg = i0;}\n            }\n            d1[i1] = best; p0[i1]=arg;\n        }\n        for(int i2=0;i2<n2;i2++){\n            long long best = (long long)4e18; int arg=-1;\n            for(int i1_=0;i1_<n1;i1_++){\n                long long v = d1[i1_] + manh(L1[i1_], L2[i2]);\n                if(v < best){best = v; arg = i1_;}\n            }\n            d2[i2] = best; p1[i2]=arg;\n        }\n        for(int i3=0;i3<n3;i3++){\n            long long best = (long long)4e18; int arg=-1;\n            for(int i2_=0;i2_<n2;i2_++){\n                long long v = d2[i2_] + manh(L2[i2_], L3[i3]);\n                if(v < best){best = v; arg = i2_;}\n            }\n            d3[i3] = best; p2[i3]=arg;\n        }\n        int best_i4=0;\n        {\n            long long best = (long long)4e18; int arg=-1;\n            for(int i4=0;i4<n4;i4++){\n                long long v = d3[0]; // placeholder\n                // Need transition from some i3\n            }\n        }\n        // compute d4 and p3 properly\n        long long bestVal = (long long)4e18;\n        int arg4 = -1;\n        for(int i4=0;i4<n4;i4++){\n            long long best = (long long)4e18; int arg=-1;\n            for(int i3_=0;i3_<n3;i3_++){\n                long long v = d3[i3_] + manh(L3[i3_], L4[i4]);\n                if(v < best){best = v; arg = i3_;}\n            }\n            d4[i4] = best; p3[i4]=arg;\n            if(d4[i4] < bestVal){bestVal = d4[i4]; arg4 = i4;}\n        }\n        // Backtrack indices\n        int i4 = arg4;\n        int i3 = p3[i4];\n        int i2 = p2[i3];\n        int i1 = p1[i2];\n        int i0 = p0[i1];\n\n        // Emit the 5 positions in order, updating cur\n        // Also ensure operation limit not exceeded (though we won't exceed)\n        array<Pos,5> seq = {L0[i0], L1[i1], L2[i2], L3[i3], L4[i4]};\n        for(int z=0; z<5; z++){\n            ops.emplace_back(seq[z].i, seq[z].j);\n            cur = seq[z];\n        }\n        // Remove this target from remaining\n        idxs.erase(idxs.begin() + bestIdxPos);\n    }\n\n    // Output\n    for(auto &p : ops){\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int di, dj;\n    vector<int> cells; // linear indices covered\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n    if (!(cin >> N >> M >> eps)) return 0;\n    vector<vector<pair<int,int>>> shapes(M);\n    vector<int> shape_h(M), shape_w(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        int min_i = INT_MAX, min_j = INT_MAX, max_i = INT_MIN, max_j = INT_MIN;\n        for (int t = 0; t < d; ++t) {\n            int i,j; cin >> i >> j;\n            shapes[k][t] = {i,j};\n            min_i = min(min_i, i);\n            min_j = min(min_j, j);\n            max_i = max(max_i, i);\n            max_j = max(max_j, j);\n        }\n        // Shapes are already translated so min is 0 per statement, but keep robust\n        shape_h[k] = max_i - min_i + 1;\n        shape_w[k] = max_j - min_j + 1;\n    }\n\n    int G = N*N;\n    auto idx = [N](int i,int j){ return i*N + j; };\n    auto ij = [N](int p){ return pair<int,int>(p/N, p%N); };\n\n    // Generate candidate placements per shape\n    vector<vector<Placement>> candidates(M);\n    for (int k = 0; k < M; ++k) {\n        int h = shape_h[k], w = shape_w[k];\n        for (int di = 0; di + h <= N; ++di) {\n            for (int dj = 0; dj + w <= N; ++dj) {\n                Placement P; P.di = di; P.dj = dj;\n                P.cells.reserve(shapes[k].size());\n                bool ok = true;\n                for (auto [oi, oj] : shapes[k]) {\n                    int i = di + oi;\n                    int j = dj + oj;\n                    if (i < 0 || i >= N || j < 0 || j >= N) { ok = false; break; }\n                    P.cells.push_back(idx(i,j));\n                }\n                if (ok) candidates[k].push_back(move(P));\n            }\n        }\n    }\n\n    // Build reverse index: for each cell, list of (k, t) candidates covering it\n    vector<vector<pair<int,int>>> cell_covers(G);\n    int total_candidates = 0;\n    for (int k = 0; k < M; ++k) {\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            ++total_candidates;\n            for (int p : candidates[k][t].cells) {\n                cell_covers[p].push_back({k,t});\n            }\n        }\n    }\n\n    // Alive flags and counts\n    vector<vector<char>> alive(M);\n    vector<int> alive_count(M);\n    for (int k = 0; k < M; ++k) {\n        int sz = candidates[k].size();\n        alive[k].assign(sz, 1);\n        alive_count[k] = sz;\n    }\n\n    // cover_count per cell among alive candidates (across all shapes)\n    vector<int> cover_count(G, 0);\n    for (int p = 0; p < G; ++p) {\n        cover_count[p] = (int)cell_covers[p].size();\n    }\n\n    // cell states: -1 unknown, 0 zero, 1 positive (observed or inferred)\n    vector<int> state(G, -1);\n\n    // helper to eliminate a candidate\n    auto kill_candidate = [&](int k, int t, deque<pair<int,int>> &singleton_queue) {\n        if (!alive[k][t]) return;\n        alive[k][t] = 0;\n        alive_count[k]--;\n        for (int p : candidates[k][t].cells) {\n            cover_count[p]--;\n        }\n        if (alive_count[k] == 1) {\n            singleton_queue.emplace_back(k, -1);\n        }\n    };\n\n    // when a shape becomes singleton, mark its cells positive\n    auto commit_singleton = [&](int k) {\n        if (alive_count[k] != 1) return;\n        int tstar = -1;\n        for (int t = 0; t < (int)alive[k].size(); ++t) if (alive[k][t]) { tstar = t; break; }\n        if (tstar == -1) return;\n        for (int p : candidates[k][tstar].cells) {\n            if (state[p] == -1) state[p] = 1;\n        }\n    };\n\n    int ops_used = 0;\n    int max_ops = 2 * N * N;\n\n    auto flushout = [](){ cout.flush(); };\n\n    // selection: pick unknown cell with maximum cover_count\n    auto select_next = [&]() -> int {\n        int bestp = -1;\n        int bestv = -1;\n        for (int p = 0; p < G; ++p) {\n            if (state[p] != -1) continue;\n            int v = cover_count[p];\n            if (v > bestv) { bestv = v; bestp = p; }\n        }\n        if (bestp == -1) {\n            // fallback: any unknown\n            for (int p = 0; p < G; ++p) if (state[p]==-1) return p;\n        }\n        return bestp;\n    };\n\n    auto all_singleton = [&]() -> bool {\n        for (int k = 0; k < M; ++k) if (alive_count[k] != 1) return false;\n        return true;\n    };\n\n    // Main loop: elimination via zeros\n    while (ops_used < max_ops) {\n        // Check if solved by singleton placements\n        if (all_singleton()) break;\n\n        int p = select_next();\n        if (p == -1) break; // nothing left unknown\n        auto [i,j] = ij(p);\n        cout << \"q 1 \" << i << ' ' << j << '\\n';\n        flushout();\n        ops_used++;\n        int vresp;\n        if (!(cin >> vresp)) return 0;\n        if (vresp == 0) {\n            state[p] = 0;\n            // eliminate all candidates covering this cell\n            deque<pair<int,int>> singleton_queue;\n            for (auto [k,t] : cell_covers[p]) {\n                if (alive[k][t]) kill_candidate(k,t, singleton_queue);\n            }\n            // process singletons\n            while (!singleton_queue.empty()) {\n                auto [k, dummy] = singleton_queue.front(); singleton_queue.pop_front();\n                if (alive_count[k] == 1) {\n                    commit_singleton(k);\n                }\n            }\n        } else {\n            // positive\n            state[p] = 1;\n            // no elimination here because overlaps allow multiple coverage\n        }\n        // If we are close to op limit, plan to fallback\n        if (ops_used >= max_ops) break;\n    }\n\n    // If not all shapes singleton, ensure exactness by drilling remaining unknown cells\n    for (int p = 0; p < G && ops_used < max_ops; ++p) {\n        if (state[p] == -1) {\n            auto [i,j] = ij(p);\n            cout << \"q 1 \" << i << ' ' << j << '\\n';\n            flushout();\n            ops_used++;\n            int vresp;\n            if (!(cin >> vresp)) return 0;\n            state[p] = (vresp > 0) ? 1 : 0;\n        }\n    }\n\n    // Build final answer set: all cells with state==1; if some remain -1 due to op cap, conservatively include none of them (but we ensured drilling all unknown unless ops exhausted).\n    vector<pair<int,int>> ans;\n    ans.reserve(G);\n    for (int p = 0; p < G; ++p) if (state[p] == 1) ans.push_back(ij(p));\n\n    cout << \"a \" << ans.size();\n    for (auto [i,j] : ans) {\n        cout << ' ' << i << ' ' << j;\n    }\n    cout << '\\n';\n    flushout();\n    int ok;\n    if (!(cin >> ok)) return 0;\n    // If incorrect (shouldn't happen), we could try more, but op budget likely exhausted; end.\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect { int i0,j0,i1,j1; long long area() const { return 1LL*(i1-i0)*(j1-j0); } };\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++) for(int k=0; k<N; k++) cin>>a[d][k];\n\n    // Compute rank-wise maxima M_r\n    vector<int> M(N,0);\n    vector<int> tmp;\n    tmp.reserve(N);\n    for(int d=0; d<D; d++){\n        tmp = a[d];\n        sort(tmp.begin(), tmp.end());\n        for(int r=0; r<N; r++) M[r] = max(M[r], tmp[r]);\n    }\n    // sort M ascending\n    vector<long long> B(N);\n    for(int i=0;i<N;i++) B[i]=M[i];\n    sort(B.begin(), B.end());\n\n    auto build_grid = [&](int R, int C, vector<Rect>& cells, vector<long long>& cellAreas)->bool{\n        int cellsCount = R*C;\n        vector<long long> cap(cellsCount, 0);\n        for(int idx=0; idx<N; idx++) cap[idx] = B[idx]; // row-major\n        vector<long long> Sr(R,0), Sc(C,0);\n        long long S=0;\n        for(int i=0;i<R;i++){\n            for(int j=0;j<C;j++){\n                long long v = cap[i*C+j];\n                Sr[i]+=v; Sc[j]+=v; S+=v;\n            }\n        }\n        if(S==0){\n            // trivial: make equal grid\n            vector<int> h(R, W/R), w(C, W/C);\n            int remH = W - accumulate(h.begin(), h.end(), 0);\n            for(int i=0;i<remH;i++) h[i%R]++;\n            int remW = W - accumulate(w.begin(), w.end(), 0);\n            for(int j=0;j<remW;j++) w[j%C]++;\n            vector<int> hi(R+1,0), wj(C+1,0);\n            for(int i=0;i<R;i++) hi[i+1]=hi[i]+h[i];\n            for(int j=0;j<C;j++) wj[j+1]=wj[j]+w[j];\n            cells.clear(); cellAreas.clear();\n            for(int i=0;i<R;i++)for(int j=0;j<C;j++){\n                Rect r{hi[i], wj[j], hi[i+1], wj[j+1]};\n                cells.push_back(r);\n                cellAreas.push_back(r.area());\n            }\n            return true;\n        }\n        // fractional targets\n        vector<double> hr(R), wc(C);\n        for(int i=0;i<R;i++) hr[i] = (double)W * (double)Sr[i] / (double)S;\n        for(int j=0;j<C;j++) wc[j] = (double)W * (double)Sc[j] / (double)S;\n        vector<int> h(R), w(C);\n        vector<double> frh(R), frw(C);\n        for(int i=0;i<R;i++){\n            double x = hr[i];\n            int ci = (Sr[i]==0?1:(int)ceil(x));\n            if(ci<1) ci=1;\n            h[i]=ci;\n            frh[i] = ci - x;\n        }\n        for(int j=0;j<C;j++){\n            double x = wc[j];\n            int cj = (Sc[j]==0?1:(int)ceil(x));\n            if(cj<1) cj=1;\n            w[j]=cj;\n            frw[j] = cj - x;\n        }\n        auto safe_reduce_row = [&](int i)->bool{\n            if(h[i]<=1) return false;\n            for(int j=0;j<C;j++){\n                long long capij = cap[i*C+j];\n                if(capij==0) continue;\n                long long Aij = 1LL*(h[i]-1)*w[j];\n                if(Aij < capij) return false;\n            }\n            return true;\n        };\n        auto safe_reduce_col = [&](int j)->bool{\n            if(w[j]<=1) return false;\n            for(int i=0;i<R;i++){\n                long long capij = cap[i*C+j];\n                if(capij==0) continue;\n                long long Aij = 1LL*h[i]*(w[j]-1);\n                if(Aij < capij) return false;\n            }\n            return true;\n        };\n        // Trim to W\n        int sumh = accumulate(h.begin(), h.end(), 0);\n        int sumw = accumulate(w.begin(), w.end(), 0);\n        int guard=0;\n        while(sumh > W && guard<100000){\n            int pick=-1;\n            double best = 1e100;\n            for(int i=0;i<R;i++){\n                if(!safe_reduce_row(i)) continue;\n                // prefer rows with largest surplus (frh large), but we used ceil, so frh in [0,1)\n                // minimize harm: pick largest frh to reduce first\n                double score = frh[i];\n                if(score < best){ best=score; pick=i; }\n            }\n            if(pick==-1) break;\n            h[pick]--; sumh--;\n        }\n        guard=0;\n        while(sumw > W && guard<100000){\n            int pick=-1;\n            double best = 1e100;\n            for(int j=0;j<C;j++){\n                if(!safe_reduce_col(j)) continue;\n                double score = frw[j];\n                if(score < best){ best=score; pick=j; }\n            }\n            if(pick==-1) break;\n            w[pick]--; sumw--;\n        }\n        // If below W, we can add to any row/col to reach exactly W (adding never hurts)\n        while(sumh < W){\n            int pick = max_element(Sr.begin(), Sr.end()) - Sr.begin();\n            h[pick]++; sumh++;\n        }\n        while(sumw < W){\n            int pick = max_element(Sc.begin(), Sc.end()) - Sc.begin();\n            w[pick]++; sumw++;\n        }\n        // Verify feasibility\n        for(int i=0;i<R;i++) for(int j=0;j<C;j++){\n            long long capij = cap[i*C+j];\n            if(capij==0) continue;\n            long long Aij = 1LL*h[i]*w[j];\n            if(Aij < capij){\n                // failed\n                return false;\n            }\n        }\n        // Build cells\n        vector<int> hi(R+1,0), wj(C+1,0);\n        for(int i=0;i<R;i++) hi[i+1]=hi[i]+h[i];\n        for(int j=0;j<C;j++) wj[j+1]=wj[j]+w[j];\n        cells.clear(); cellAreas.clear();\n        for(int i=0;i<R;i++)for(int j=0;j<C;j++){\n            Rect r{hi[i], wj[j], hi[i+1], wj[j+1]};\n            cells.push_back(r);\n            cellAreas.push_back(r.area());\n        }\n        return true;\n    };\n\n    // Try grid constructions in a few shapes\n    vector<Rect> cells;\n    vector<long long> cellAreas;\n    bool ok=false;\n    {\n        int C = (int)ceil(sqrt((double)N));\n        int R = (N + C - 1)/C;\n        ok = build_grid(R,C,cells,cellAreas);\n    }\n    if(!ok){\n        int R = (int)ceil(sqrt((double)N));\n        int C = (N + R - 1)/R;\n        ok = build_grid(R,C,cells,cellAreas);\n    }\n    if(!ok){\n        // try pure stripes: R=N, C=1\n        ok = build_grid(N,1,cells,cellAreas);\n    }\n    if(!ok){\n        // last resort: equal grid ignoring capacities; we may incur penalties but very unlikely\n        int C = (int)ceil(sqrt((double)N));\n        int R = (N + C - 1)/C;\n        vector<int> h(R, W/R), w(C, W/C);\n        int remH = W - accumulate(h.begin(), h.end(), 0);\n        for(int i=0;i<remH;i++) h[i%R]++;\n        int remW = W - accumulate(w.begin(), w.end(), 0);\n        for(int j=0;j<remW;j++) w[j%C]++;\n        vector<int> hi(R+1,0), wj(C+1,0);\n        for(int i=0;i<R;i++) hi[i+1]=hi[i]+h[i];\n        for(int j=0;j<C;j++) wj[j+1]=wj[j]+w[j];\n        cells.clear(); cellAreas.clear();\n        for(int i=0;i<R;i++)for(int j=0;j<C;j++){\n            Rect r{hi[i], wj[j], hi[i+1], wj[j+1]};\n            cells.push_back(r);\n            cellAreas.push_back(r.area());\n        }\n        ok=true;\n    }\n\n    // Select first N cells and sort them by area ascending to match rank\n    vector<int> idx(cells.size());\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int x, int y){\n        if(cellAreas[x]!=cellAreas[y]) return cellAreas[x] < cellAreas[y];\n        return x<y;\n    });\n    vector<Rect> blocks(N);\n    vector<long long> blockArea(N);\n    for(int k=0;k<N;k++){\n        blocks[k]=cells[idx[k]];\n        blockArea[k]=blocks[k].area();\n    }\n    // For safety, ensure blockArea[k] >= B[k]; if not, we proceed anyway (rare), undersupply penalty may happen.\n\n    // Per day assignment: match ascending demands to ascending blocks\n    vector<vector<Rect>> out(D, vector<Rect>(N));\n    vector<int> ord(N);\n    for(int d=0; d<D; d++){\n        ord.resize(N);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int x,int y){ return a[d][x] < a[d][y]; });\n        // blocks are in ascending order already\n        vector<int> inv(N);\n        for(int r=0;r<N;r++){\n            int k = ord[r];\n            out[d][k] = blocks[r];\n        }\n    }\n\n    // Output\n    for(int d=0; d<D; d++){\n        for(int k=0; k<N; k++){\n            Rect r = out[d][k];\n            cout<<r.i0<<\" \"<<r.j0<<\" \"<<r.i1<<\" \"<<r.j1<<\"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const long long MOD = 998244353LL;\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<long long>> w(N, vector<long long>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            long long x; cin >> x;\n            w[i][j] = x % MOD;\n        }\n    }\n    // stamps[m][i][j]\n    vector<array<long long, 9>> stamps(M);\n    for (int m = 0; m < M; ++m) {\n        int idx = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                long long s; cin >> s;\n                stamps[m][idx++] = s % MOD;\n            }\n        }\n    }\n\n    struct Move { int m, p, q; long long gain; };\n    vector<tuple<int,int,int>> ops; ops.reserve(K);\n\n    auto compute_gain = [&](int m, int p, int q)->long long{\n        long long g = 0;\n        int idx = 0;\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj, ++idx) {\n                int r = p + di, c = q + dj;\n                long long v = w[r][c];\n                long long s = stamps[m][idx];\n                long long nv = v + s;\n                if (nv >= MOD) nv -= MOD;\n                g += (nv - v);\n            }\n        }\n        return g;\n    };\n\n    int maxOps = K;\n    for (int t = 0; t < maxOps; ++t) {\n        Move best{-1, -1, -1, LLONG_MIN};\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                    long long g = compute_gain(m, p, q);\n                    if (g > best.gain) {\n                        best = {m, p, q, g};\n                    }\n                }\n            }\n        }\n        if (best.gain <= 0) break;\n        // apply best\n        int m = best.m, p = best.p, q = best.q;\n        int idx = 0;\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj, ++idx) {\n                int r = p + di, c = q + dj;\n                long long s = stamps[m][idx];\n                long long nv = w[r][c] + s;\n                if (nv >= MOD) nv -= MOD;\n                w[r][c] = nv;\n            }\n        }\n        ops.emplace_back(m, p, q);\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto &op : ops) {\n        int m, p, q;\n        tie(m, p, q) = op;\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Planner {\n    static const int N = 5;\n    vector<vector<int>> A; // A[r][k]\n    // Output strings for 5 cranes\n    vector<string> S;\n    // Large crane state\n    int cr, cc; // position\n    bool holding;\n    int held_id;\n\n    // Storage management: interior cells (j=1..3)\n    // occupancy grid for storage (true if occupied by a container)\n    bool occ[N][N];\n    // map container id -> position (r,c) if stored (interior), or special markers\n    unordered_map<int, pair<int,int>> loc; // only for stored interior cells\n\n    int next_needed[N];\n    int idx_head[N]; // next index at each source row (0..5)\n    int dispatched; // count dispatched\n    int rr; // round-robin source pointer\n\n    Planner(const vector<vector<int>>& Ain): A(Ain) {\n        S.assign(N, \"\");\n        // Bomb small cranes\n        for (int i = 1; i < N; ++i) S[i].push_back('B');\n        cr = 0; cc = 0; holding = false; held_id = -1;\n        memset(occ, 0, sizeof(occ));\n        for (int i=0;i<N;i++){ next_needed[i] = N*i; idx_head[i]=0; }\n        dispatched = 0;\n        rr = 0;\n    }\n\n    void appendLarge(char ch) {\n        S[0].push_back(ch);\n        // pad others with '.'\n        for (int i=1;i<N;i++){\n            if ((int)S[i].size() < (int)S[0].size()) S[i].push_back('.');\n        }\n    }\n    // Move one step towards target\n    void moveTo(int tr, int tc) {\n        while (cr != tr) {\n            if (tr < cr) { cr--; appendLarge('U'); }\n            else { cr++; appendLarge('D'); }\n        }\n        while (cc != tc) {\n            if (tc < cc) { cc--; appendLarge('L'); }\n            else { cc++; appendLarge('R'); }\n        }\n    }\n    // Pick at current\n    void pick() {\n        // assume valid\n        holding = true;\n        appendLarge('P');\n        // we don't update held_id here; caller sets it\n    }\n    // Drop at current\n    void drop() {\n        holding = false;\n        appendLarge('Q');\n    }\n    // Try to flush deliveries for any row where needed is present in storage\n    bool flush_one() {\n        for (int d = 0; d < N; ++d) {\n            int need = next_needed[d];\n            if (need >= N*d + N) continue;\n            auto it = loc.find(need);\n            if (it != loc.end()) {\n                // fetch from its storage pos\n                int sr = it->second.first, sc = it->second.second;\n                moveTo(sr, sc);\n                // pick it\n                held_id = need;\n                pick();\n                // free occupancy\n                occ[sr][sc] = false;\n                loc.erase(it);\n                // move to dispatch gate\n                moveTo(d, N-1);\n                drop();\n                // dispatch occurs at end of turn; we assume success\n                next_needed[d]++;\n                dispatched++;\n                return true;\n            }\n        }\n        return false;\n    }\n    // Flush as much as possible\n    void flush_all() {\n        while (flush_one()) {\n            // loop\n        }\n    }\n    // Find nearest free storage cell\n    pair<int,int> nearest_free_cell() {\n        int best = 1e9;\n        pair<int,int> bestpos = {-1,-1};\n        for (int r=0;r<N;r++){\n            for (int c=1;c<=3;c++){\n                if (!occ[r][c]) {\n                    int dist = abs(cr - r) + abs(cc - c);\n                    if (dist < best) { best = dist; bestpos = {r,c}; }\n                }\n            }\n        }\n        return bestpos;\n    }\n    // Choose next source row with available container\n    int choose_source_row() {\n        for (int k=0;k<N;k++){\n            int r = (rr + k) % N;\n            if (idx_head[r] < N) return r;\n        }\n        return -1;\n    }\n    // Main plan\n    void run() {\n        // First, move off (0,0) to (0,1) to not sit on receiving gate while holding later\n        if (cc == 0) {\n            cc = 1;\n            appendLarge('R');\n        }\n        // Main loop\n        int maxTurns = 9000;\n        while (dispatched < N*N && (int)S[0].size() < maxTurns) {\n            // Try flush while possible\n            flush_all();\n            if (dispatched >= N*N) break;\n\n            // If holding something (shouldn't happen between operations), place appropriately\n            if (holding) {\n                // If at dispatch for its row and it's the needed, drop; otherwise store\n                int d = held_id / N;\n                if (next_needed[d] == held_id && cr == d && cc == N-1) {\n                    drop();\n                    next_needed[d]++;\n                    dispatched++;\n                    continue;\n                } else {\n                    // store\n                    auto pos = nearest_free_cell();\n                    if (pos.first == -1) {\n                        // storage full: try to move towards its row dispatch and wait one step\n                        // As fallback, just move one step towards (d, N-1)\n                        int tr = d, tc = N-1;\n                        if (cr != tr) {\n                            cr += (tr > cr ? 1 : -1);\n                            appendLarge(tr > cr ? 'D' : 'U'); // careful we modified cr already; but this is fallback; to avoid mistakes:\n                        } else if (cc != tc) {\n                            cc += (tc > cc ? 1 : -1);\n                            appendLarge(tc > cc ? 'R' : 'L');\n                        } else {\n                            // at gate but not needed; we cannot drop; just wait\n                            appendLarge('.');\n                        }\n                        continue;\n                    } else {\n                        moveTo(pos.first, pos.second);\n                        drop();\n                        occ[pos.first][pos.second] = true;\n                        loc[held_id] = pos;\n                        continue;\n                    }\n                }\n            }\n\n            // Choose next source row\n            int r = choose_source_row();\n            if (r == -1) {\n                // nothing to pick, just flush maybe or end\n                if (!flush_one()) {\n                    appendLarge('.');\n                }\n                continue;\n            }\n            // Move to (r,0)\n            moveTo(r, 0);\n            // Pick current head A[r][idx]\n            int b = A[r][idx_head[r]];\n            idx_head[r]++;\n            held_id = b;\n            pick();\n            // Deliver or store\n            int d = b / N;\n            if (next_needed[d] == b) {\n                moveTo(d, N-1);\n                drop();\n                next_needed[d]++;\n                dispatched++;\n            } else {\n                auto pos = nearest_free_cell();\n                if (pos.first == -1) {\n                    // Try to flush one to free space, then find again\n                    if (!flush_one()) {\n                        // move towards its row to be near future work\n                        moveTo(d, 2);\n                        // attempt again\n                    }\n                    pos = nearest_free_cell();\n                }\n                if (pos.first != -1) {\n                    moveTo(pos.first, pos.second);\n                    drop();\n                    occ[pos.first][pos.second] = true;\n                    loc[b] = pos;\n                } else {\n                    // As last resort, move somewhere and wait\n                    appendLarge('.');\n                }\n            }\n            // advance round-robin pointer\n            rr = (r + 1) % N;\n        }\n        // Final padding: ensure all strings same length\n        size_t L = S[0].size();\n        for (int i=1;i<N;i++){\n            while (S[i].size() < L) S[i].push_back('.');\n        }\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i=0;i<N;i++){\n        for (int j=0;j<N;j++){\n            cin >> A[i][j];\n        }\n    }\n    Planner planner(A);\n    planner.run();\n    for (int i=0;i<N;i++){\n        cout << planner.S[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<long long>> h(N, vector<long long>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) cin >> h[i][j];\n    }\n    // Build snake order\n    vector<pair<int,int>> order;\n    order.reserve(N*N);\n    for (int i = 0; i < N; ++i) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < N; ++j) order.emplace_back(i,j);\n        } else {\n            for (int j = N-1; j >= 0; --j) order.emplace_back(i,j);\n        }\n    }\n    auto move_step = [&](pair<int,int> from, pair<int,int> to, vector<string>& ops) {\n        int dr = to.first - from.first;\n        int dc = to.second - from.second;\n        if (dr == 1 && dc == 0) ops.emplace_back(\"D\");\n        else if (dr == -1 && dc == 0) ops.emplace_back(\"U\");\n        else if (dr == 0 && dc == 1) ops.emplace_back(\"R\");\n        else if (dr == 0 && dc == -1) ops.emplace_back(\"L\");\n        else {\n            // Should not happen in snake consecutive neighbors\n        }\n    };\n    vector<string> ops;\n    long long load = 0;\n    // Start at order[0] which is (0,0)\n    pair<int,int> cur = order[0];\n    for (int idx = 0; idx+1 < (int)order.size(); ++idx) {\n        auto p = order[idx];\n        auto q = order[idx+1];\n        // cur should be at p\n        // Transfer entire h[p] to q\n        long long x = h[p.first][p.second];\n        if (x >= 0) {\n            if (x > 0) {\n                // load x at p\n                ops.emplace_back(\"+\" + to_string(x));\n                load += x;\n            }\n            // move to q with load\n            move_step(p, q, ops);\n            // unload x at q\n            if (x > 0) {\n                ops.emplace_back(\"-\" + to_string(x));\n                load -= x;\n                h[q.first][q.second] += x;\n            }\n            h[p.first][p.second] = 0;\n            cur = q;\n        } else {\n            long long d = -x; // need to bring from q to p\n            // move to q empty (should be load==0 here always? load is zero after each segment)\n            move_step(p, q, ops);\n            cur = q;\n            // load d at q\n            if (d > 0) {\n                ops.emplace_back(\"+\" + to_string(d));\n                load += d;\n            }\n            // move back to p carrying\n            move_step(q, p, ops);\n            cur = p;\n            // unload d at p\n            if (d > 0) {\n                ops.emplace_back(\"-\" + to_string(d));\n                load -= d;\n            }\n            // heights update\n            h[p.first][p.second] += d; // becomes 0\n            h[q.first][q.second] -= d;\n            // move again to q empty to continue\n            move_step(p, q, ops);\n            cur = q;\n        }\n        // after each edge, load should be 0\n        // assert(load == 0);\n    }\n    // Optionally, ensure last cell is zero (it should be)\n    // No additional ops needed.\n    // Output\n    for (auto &s : ops) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Seed {\n    int id;\n    array<int,15> x;\n    int V;\n    double score;\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,T;\n    if(!(cin>>N>>M>>T)) return 0;\n    const int S = 2*N*(N-1); // 60\n    vector<Seed> seeds(S);\n    for(int i=0;i<S;i++){\n        seeds[i].id = i;\n        int sum=0;\n        for(int l=0;l<M;l++){\n            int v; cin>>v;\n            seeds[i].x[l]=v;\n            sum+=v;\n        }\n        seeds[i].V=sum;\n        seeds[i].score=sum;\n    }\n\n    auto cellDegree = [&](int i,int j)->int{\n        int d=0;\n        if(i>0) d++;\n        if(i+1<N) d++;\n        if(j>0) d++;\n        if(j+1<N) d++;\n        return d;\n    };\n\n    // Precompute placement order of grid cells: higher degree first, checkerboard within degree\n    vector<pair<int,int>> cells;\n    cells.reserve(N*N);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cells.emplace_back(i,j);\n    // Checkerboard color preference: put black (i+j)%2==0 first to maximize edges between selected highs\n    stable_sort(cells.begin(), cells.end(), [&](const pair<int,int>& a, const pair<int,int>& b){\n        int da = cellDegree(a.first,a.second);\n        int db = cellDegree(b.first,b.second);\n        if(da!=db) return da>db;\n        int ca = (a.first + a.second) & 1;\n        int cb = (b.first + b.second) & 1;\n        if(ca!=cb) return ca<cb; // black first\n        if(a.first!=b.first) return a.first<b.first;\n        return a.second<b.second;\n    });\n\n    // helper to compute scores\n    auto compute_scores = [&](vector<Seed>& pool){\n        array<int,15> xmax{};\n        xmax.fill(1);\n        for(int l=0;l<M;l++){\n            int mx=0;\n            for(auto &s: pool) mx = max(mx, s.x[l]);\n            xmax[l]=max(1,mx);\n        }\n        // constants\n        const double alpha = 5.0;\n        const double beta = 2.0;\n        for(auto &s: pool){\n            double bonus = 0.0;\n            for(int l=0;l<M;l++){\n                double r = (double)s.x[l] / (double)xmax[l];\n                bonus += pow(r, beta);\n            }\n            s.V = 0;\n            for(int l=0;l<M;l++) s.V += s.x[l];\n            s.score = (double)s.V + alpha * bonus;\n        }\n    };\n\n    for(int t=0;t<T;t++){\n        // compute scores on current pool of 60 seeds\n        compute_scores(seeds);\n\n        // select top 36 by score\n        vector<int> idx(S);\n        iota(idx.begin(), idx.end(), 0);\n        nth_element(idx.begin(), idx.begin()+N*N, idx.end(), [&](int a, int b){\n            if(seeds[a].score!=seeds[b].score) return seeds[a].score>seeds[b].score;\n            return seeds[a].V>seeds[b].V;\n        });\n        idx.resize(N*N);\n        sort(idx.begin(), idx.end(), [&](int a, int b){\n            if(seeds[a].score!=seeds[b].score) return seeds[a].score>seeds[b].score;\n            return seeds[a].V>seeds[b].V;\n        });\n\n        // Arrange selected seeds onto grid cells in cells order\n        vector<vector<int>> A(N, vector<int>(N, -1));\n        for(int k=0;k<N*N;k++){\n            auto [i,j] = cells[k];\n            A[i][j] = seeds[idx[k]].id;\n        }\n\n        // Output placement\n        for(int i=0;i<N;i++){\n            for(int j=0;j<N;j++){\n                if(j) cout << ' ';\n                cout << A[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // Read next 60 seeds (children)\n        vector<Seed> next(S);\n        for(int i=0;i<S;i++){\n            next[i].id = i;\n            int sum=0;\n            for(int l=0;l<M;l++){\n                int v; cin>>v;\n                next[i].x[l]=v;\n                sum+=v;\n            }\n            next[i].V=sum;\n            next[i].score=sum;\n        }\n        seeds.swap(next);\n    }\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Task {\n    // pick at s, drop at t\n    int sx, sy, tx, ty;\n    // chosen directions and root positions\n    int dir_pick; // 0:R,1:D,2:L,3:U\n    int rpx, rpy;\n    int dir_drop;\n    int rdx, rdy;\n};\n\n// Manhattan distance\ninline int manh(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\n\n// choose a direction so that root = (x - dx, y - dy) is inside\nint choose_dir_for_cell(int x,int y,int N, int prefer_dir = -1){\n    static const int dx[4]={0,1,0,-1};\n    static const int dy[4]={1,0,-1,0};\n    // try preferred first if valid\n    if(prefer_dir!=-1){\n        int rx = x - dx[prefer_dir], ry = y - dy[prefer_dir];\n        if(0<=rx && rx<N && 0<=ry && ry<N) return prefer_dir;\n    }\n    for(int k=0;k<4;k++){\n        int rx = x - dx[k], ry = y - dy[k];\n        if(0<=rx && rx<N && 0<=ry && ry<N) return k;\n    }\n    // should never happen\n    return 0;\n}\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    // Build sets S (surplus) and D (deficit)\n    vector<pair<int,int>> S, D;\n    vector<vector<int>> occ(N, vector<int>(N,0));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            int si = s[i][j]-'0';\n            int ti = t[i][j]-'0';\n            occ[i][j]=si;\n            if(si==1 && ti==0) S.emplace_back(i,j);\n            if(si==0 && ti==1) D.emplace_back(i,j);\n        }\n    }\n\n    // Greedy source->nearest target matching\n    // We'll remove matched targets from D\n    vector<char> usedD(D.size(), 0);\n    vector<pair<pair<int,int>, pair<int,int>>> pairs; // (s,t)\n    pairs.reserve(S.size());\n    for (auto &sp : S){\n        int bestIdx=-1, bestDist=1e9;\n        for(size_t j=0;j<D.size();j++){\n            if(usedD[j]) continue;\n            int d = manh(sp.first, sp.second, D[j].first, D[j].second);\n            if(d < bestDist){\n                bestDist = d; bestIdx = (int)j;\n            }\n        }\n        if(bestIdx==-1){\n            // Shouldn't happen if counts match, but guard\n            continue;\n        }\n        usedD[bestIdx]=1;\n        pairs.push_back({sp, D[bestIdx]});\n    }\n\n    // Build tasks with chosen directions and root positions\n    vector<Task> tasks;\n    tasks.reserve(pairs.size());\n    int current_leaf_dir = 0; // initially right\n    for (auto &pr : pairs){\n        Task tk;\n        tk.sx = pr.first.first; tk.sy = pr.first.second;\n        tk.tx = pr.second.first; tk.ty = pr.second.second;\n        // prefer current leaf dir to reduce rotations at pick\n        int dirp = choose_dir_for_cell(tk.sx, tk.sy, N, current_leaf_dir);\n        static const int dx[4]={0,1,0,-1};\n        static const int dy[4]={1,0,-1,0};\n        tk.dir_pick = dirp;\n        tk.rpx = tk.sx - dx[dirp];\n        tk.rpy = tk.sy - dy[dirp];\n        // For drop, prefer same dir to possibly avoid rotation later\n        int dird = choose_dir_for_cell(tk.tx, tk.ty, N, dirp);\n        tk.dir_drop = dird;\n        tk.rdx = tk.tx - dx[dird];\n        tk.rdy = tk.ty - dy[dird];\n        // update current_leaf_dir hint for next pick\n        current_leaf_dir = dird;\n        tasks.push_back(tk);\n    }\n\n    // Reorder tasks to reduce travel: greedy nearest neighbor from current root at (0,0)\n    int rx=0, ry=0;\n    vector<int> order;\n    order.reserve(tasks.size());\n    vector<char> used(tasks.size(), 0);\n    for(size_t it=0; it<tasks.size(); it++){\n        int best=-1, bd=1e9;\n        for(size_t i=0;i<tasks.size();i++){\n            if(used[i]) continue;\n            int d = manh(rx,ry,tasks[i].rpx,tasks[i].rpy);\n            if(d<bd){ bd=d; best=(int)i; }\n        }\n        if(best==-1) break;\n        used[best]=1;\n        order.push_back(best);\n        // Update current position to that pick root to guide next selection\n        rx = tasks[best].rpx; ry = tasks[best].rpy;\n    }\n\n    // Reset for actual execution\n    rx=0; ry=0;\n    int leaf_dir = 0; // 0:R,1:D,2:L,3:U\n    bool holding=false;\n\n    vector<string> out;\n    out.reserve(200000);\n\n    auto add_move = [&](char mv){\n        string Sturn(4, '.');\n        Sturn[0]=mv;\n        out.push_back(Sturn);\n        // update root position\n        if(mv=='U') rx--;\n        else if(mv=='D') rx++;\n        else if(mv=='L') ry--;\n        else if(mv=='R') ry++;\n    };\n    auto add_rotate = [&](int delta){ // delta positive means rotate clockwise by 90 per step? In problem 'R' is clockwise\n        // delta in {-3,-2,-1,0,1,2,3}\n        if(delta<0){\n            for(int k=0;k<-delta;k++){\n                string Sturn(4, '.');\n                Sturn[1]='L';\n                out.push_back(Sturn);\n                leaf_dir = (leaf_dir + 3) % 4;\n            }\n        }else{\n            for(int k=0;k<delta;k++){\n                string Sturn(4, '.');\n                Sturn[1]='R';\n                out.push_back(Sturn);\n                leaf_dir = (leaf_dir + 1) % 4;\n            }\n        }\n    };\n    auto add_pickdrop = [&](){\n        string Sturn(4, '.');\n        Sturn[3]='P';\n        out.push_back(Sturn);\n    };\n\n    auto move_root_to = [&](int tx,int ty){\n        while(rx<tx) add_move('D');\n        while(rx>tx) add_move('U');\n        while(ry<ty) add_move('R');\n        while(ry>ty) add_move('L');\n    };\n\n    // Safety cap\n    const int TURN_LIMIT = 100000;\n\n    // Execute tasks\n    static const int dx4[4]={0,1,0,-1};\n    static const int dy4[4]={1,0,-1,0};\n\n    for(int idx : order){\n        if((int)out.size() >= TURN_LIMIT) break;\n        Task &tk = tasks[idx];\n\n        // Go to pick root\n        move_root_to(tk.rpx, tk.rpy);\n        if((int)out.size() >= TURN_LIMIT) break;\n\n        // Rotate to pick dir\n        int delta = (tk.dir_pick - leaf_dir + 4) % 4;\n        if(delta==3) delta = -1;\n        else if(delta==2) {\n            // choose either 2 R or 2 L; pick R for simplicity\n        }\n        add_rotate(delta);\n        if((int)out.size() >= TURN_LIMIT) break;\n\n        // Now fingertip is at s\n        int fx = rx + dx4[leaf_dir];\n        int fy = ry + dy4[leaf_dir];\n        // Pick if available and not holding\n        if(0<=fx && fx<N && 0<=fy && fy<N && !holding && occ[fx][fy]==1){\n            add_pickdrop();\n            holding=true;\n            occ[fx][fy]=0;\n        }else{\n            // If cannot pick (due to previous changes), skip\n        }\n        if((int)out.size() >= TURN_LIMIT) break;\n\n        // Go to drop root\n        move_root_to(tk.rdx, tk.rdy);\n        if((int)out.size() >= TURN_LIMIT) break;\n\n        // Rotate to drop dir\n        delta = (tk.dir_drop - leaf_dir + 4) % 4;\n        if(delta==3) delta = -1;\n        add_rotate(delta);\n        if((int)out.size() >= TURN_LIMIT) break;\n\n        // Fingertip at t\n        fx = rx + dx4[leaf_dir];\n        fy = ry + dy4[leaf_dir];\n        if(0<=fx && fx<N && 0<=fy && fy<N && holding && occ[fx][fy]==0){\n            add_pickdrop();\n            holding=false;\n            occ[fx][fy]=1;\n        }else{\n            // If already occupied or not holding, skip\n        }\n        if((int)out.size() >= TURN_LIMIT) break;\n    }\n\n    // Output arm design\n    // Use 2 vertices: 0 root, 1 leaf with length 1\n    cout<<2<<\"\\n\";\n    cout<<0<<\" \"<<1<<\"\\n\";\n    cout<<0<<\" \"<<0<<\"\\n\";\n    // Output operations\n    for(auto &row : out){\n        cout<<row<<\"\\n\";\n    }\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    int w; // +1 mackerel, -1 sardine\n};\nstruct Rect {\n    int x1,y1,x2,y2; // inclusive bounds: x1<=x<=x2, y1<=y<=y2\n    long long score = LLONG_MIN;\n    int a=0,b=0; // counts\n};\n\nstatic inline long long rect_perimeter(int x1,int y1,int x2,int y2){\n    long long w = (long long)(x2 - x1);\n    long long h = (long long)(y2 - y1);\n    if (w < 0) w = -w; if (h < 0) h = -h;\n    return 2*(w + h);\n}\n\nstruct Grid {\n    int G;\n    int B; // bin size\n    int maxCoord = 100000;\n    int W,H;\n    vector<int> a; // GxG\n    vector<long long> ps; // (G+1)x(G+1)\n    Grid(int G_): G(G_) {\n        B = (maxCoord + G - 1) / G; // ceil\n        W = G; H = G;\n        a.assign(W*H, 0);\n        ps.assign((W+1)*(H+1), 0);\n    }\n    inline int idx(int ix,int iy) const { return iy*W + ix; }\n    inline pair<int,int> clampCell(int ix,int iy) const {\n        ix = max(0, min(W-1, ix));\n        iy = max(0, min(H-1, iy));\n        return {ix,iy};\n    }\n    inline void addPoint(int x,int y,int w){\n        int ix = min(W-1, x / B);\n        int iy = min(H-1, y / B);\n        a[idx(ix,iy)] += w;\n    }\n    void buildPS(){\n        // ps[(iy)*(W+1) + ix]\n        for(int iy=0; iy<=H; ++iy){\n            ps[iy*(W+1)+0] = 0;\n        }\n        for(int ix=0; ix<=W; ++ix){\n            ps[0*(W+1)+ix] = 0;\n        }\n        for(int iy=1; iy<=H; ++iy){\n            long long run = 0;\n            for(int ix=1; ix<=W; ++ix){\n                run += a[idx(ix-1,iy-1)];\n                ps[iy*(W+1)+ix] = ps[(iy-1)*(W+1)+ix] + run;\n            }\n        }\n    }\n    inline long long sumRectCells(int lx,int ly,int rx,int ry) const {\n        // inclusive cell indices [lx..rx], [ly..ry]\n        if (lx>rx || ly>ry) return 0;\n        lx = max(0,lx); ly = max(0,ly);\n        rx = min(W-1,rx); ry = min(H-1,ry);\n        if (lx>rx || ly>ry) return 0;\n        int x1=lx, y1=ly, x2=rx, y2=ry;\n        long long s = ps[(y2+1)*(W+1)+(x2+1)]\n                    - ps[(y1)*(W+1)+(x2+1)]\n                    - ps[(y2+1)*(W+1)+(x1)]\n                    + ps[(y1)*(W+1)+(x1)];\n        return s;\n    }\n    inline int cellX1(int ix) const { return max(0, ix * B); }\n    inline int cellX2(int ix) const { return min(maxCoord, (ix+1)*B); }\n    inline int cellY1(int iy) const { return max(0, iy * B); }\n    inline int cellY2(int iy) const { return min(maxCoord, (iy+1)*B); }\n};\n\nstatic inline bool insideRectInclusive(const Rect& r, int x, int y){\n    return (x >= r.x1 && x <= r.x2 && y >= r.y1 && y <= r.y2);\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin>>N)) {\n        return 0;\n    }\n    vector<Point> pts;\n    pts.reserve(2*N);\n    for(int i=0;i<N;i++){\n        int x,y; cin>>x>>y;\n        pts.push_back({x,y, +1});\n    }\n    for(int i=0;i<N;i++){\n        int x,y; cin>>x>>y;\n        pts.push_back({x,y, -1});\n    }\n\n    const long long PERIM_LIMIT = 400000;\n    // Build grids\n    vector<int> Gsizes = {256, 384};\n    vector<Grid> grids;\n    grids.reserve(Gsizes.size());\n    for(int g: Gsizes) grids.emplace_back(g);\n    for (auto &p: pts){\n        for (auto &gr: grids) gr.addPoint(p.x, p.y, p.w);\n    }\n    for (auto &gr: grids) gr.buildPS();\n\n    // Find top seed cells by weight per grid\n    vector<Rect> candidates;\n    candidates.reserve(512);\n\n    auto add_candidate = [&](const Rect& r){\n        // Ensure non-empty, within bounds\n        Rect rr = r;\n        rr.x1 = max(0, min(100000, rr.x1));\n        rr.y1 = max(0, min(100000, rr.y1));\n        rr.x2 = max(0, min(100000, rr.x2));\n        rr.y2 = max(0, min(100000, rr.y2));\n        if (rr.x1 > rr.x2) swap(rr.x1, rr.x2);\n        if (rr.y1 > rr.y2) swap(rr.y1, rr.y2);\n        if (rr.x1==rr.x2 || rr.y1==rr.y2){\n            // allow zero-width/height? That gives perimeter 0 and counts points on line; but polygon needs area to be non-degenerate; safer to require at least 1.\n            // Expand by 1 if possible\n            if (rr.x1==rr.x2 && rr.x2<100000) rr.x2++;\n            else if (rr.x1==rr.x2 && rr.x1>0) rr.x1--;\n            if (rr.y1==rr.y2 && rr.y2<100000) rr.y2++;\n            else if (rr.y1==rr.y2 && rr.y1>0) rr.y1--;\n        }\n        if (rect_perimeter(rr.x1,rr.y1,rr.x2,rr.y2) > PERIM_LIMIT) {\n            // shrink proportionally to fit\n            long long w = rr.x2 - rr.x1;\n            long long h = rr.y2 - rr.y1;\n            if (w + h == 0) return;\n            long long max_sum = PERIM_LIMIT/2;\n            double scale = (double)max_sum / (double)(w + h);\n            if (scale <= 0) return;\n            long long nw = max(1LL, (long long)(w*scale));\n            long long nh = max(1LL, (long long)(h*scale));\n            // center keep\n            long long cx = (rr.x1 + rr.x2)/2;\n            long long cy = (rr.y1 + rr.y2)/2;\n            long long nx1 = max(0LL, cx - nw/2);\n            long long nx2 = min(100000LL, nx1 + nw);\n            nx1 = max(0LL, nx2 - nw);\n            long long ny1 = max(0LL, cy - nh/2);\n            long long ny2 = min(100000LL, ny1 + nh);\n            ny1 = max(0LL, ny2 - nh);\n            rr.x1 = (int)nx1; rr.x2 = (int)nx2;\n            rr.y1 = (int)ny1; rr.y2 = (int)ny2;\n        }\n        candidates.push_back(rr);\n    };\n\n    for (auto &gr: grids){\n        int W=gr.W, H=gr.H;\n        struct Cell { int ix,iy; int val; };\n        vector<Cell> cells;\n        cells.reserve(W*H);\n        for(int iy=0; iy<H; ++iy){\n            for(int ix=0; ix<W; ++ix){\n                cells.push_back({ix,iy, gr.a[gr.idx(ix,iy)]});\n            }\n        }\n        // Top T seeds by value\n        int T = min(200, (int)cells.size());\n        nth_element(cells.begin(), cells.begin()+T, cells.end(), [](const Cell& a, const Cell& b){\n            return a.val > b.val;\n        });\n        cells.resize(T);\n        // Local search from each seed\n        for (const auto &c: cells){\n            int lx = c.ix, rx = c.ix;\n            int ly = c.iy, ry = c.iy;\n            // optionally start larger by 1\n            // hill climb\n            auto rectCoord = [&](int lx,int ly,int rx,int ry)->Rect{\n                int x1 = gr.cellX1(lx);\n                int x2 = gr.cellX2(rx);\n                int y1 = gr.cellY1(ly);\n                int y2 = gr.cellY2(ry);\n                Rect r{ x1, y1, x2, y2, 0 };\n                return r;\n            };\n            // Bound expansion by perimeter\n            auto perim_ok = [&](int lx,int ly,int rx,int ry)->bool{\n                Rect r = rectCoord(lx,ly,rx,ry);\n                return rect_perimeter(r.x1,r.y1,r.x2,r.y2) <= PERIM_LIMIT;\n            };\n            // Greedy improve on grid sum\n            long long bestSum = gr.sumRectCells(lx,ly,rx,ry);\n            bool improved = true;\n            int iter=0;\n            while(improved && iter < 10000){\n                ++iter;\n                improved = false;\n                int blx=lx, bly=ly, brx=rx, bry=ry;\n                long long bestLocal = bestSum;\n                // 8 moves: expand/shrink each side\n                // expand right\n                if (rx+1 < W && perim_ok(lx,ly,rx+1,ry)){\n                    long long s = gr.sumRectCells(lx,ly,rx+1,ry);\n                    if (s > bestLocal){ bestLocal=s; blx=lx; bly=ly; brx=rx+1; bry=ry; }\n                }\n                // expand left\n                if (lx-1 >= 0 && perim_ok(lx-1,ly,rx,ry)){\n                    long long s = gr.sumRectCells(lx-1,ly,rx,ry);\n                    if (s > bestLocal){ bestLocal=s; blx=lx-1; bly=ly; brx=rx; bry=ry; }\n                }\n                // expand up\n                if (ry+1 < H && perim_ok(lx,ly,rx,ry+1)){\n                    long long s = gr.sumRectCells(lx,ly,rx,ry+1);\n                    if (s > bestLocal){ bestLocal=s; blx=lx; bly=ly; brx=rx; bry=ry+1; }\n                }\n                // expand down\n                if (ly-1 >= 0 && perim_ok(lx,ly-1,rx,ry)){\n                    long long s = gr.sumRectCells(lx,ly-1,rx,ry);\n                    if (s > bestLocal){ bestLocal=s; blx=lx; bly=ly-1; brx=rx; bry=ry; }\n                }\n                // shrink moves (keep rectangle non-empty)\n                if (rx-1 >= lx && perim_ok(lx,ly,rx-1,ry)){\n                    long long s = gr.sumRectCells(lx,ly,rx-1,ry);\n                    if (s > bestLocal){ bestLocal=s; blx=lx; bly=ly; brx=rx-1; bry=ry; }\n                }\n                if (lx+1 <= rx && perim_ok(lx+1,ly,rx,ry)){\n                    long long s = gr.sumRectCells(lx+1,ly,rx,ry);\n                    if (s > bestLocal){ bestLocal=s; blx=lx+1; bly=ly; brx=rx; bry=ry; }\n                }\n                if (ry-1 >= ly && perim_ok(lx,ly,rx,ry-1)){\n                    long long s = gr.sumRectCells(lx,ly,rx,ry-1);\n                    if (s > bestLocal){ bestLocal=s; blx=lx; bly=ly; brx=rx; bry=ry-1; }\n                }\n                if (ly+1 <= ry && perim_ok(lx,ly+1,rx,ry)){\n                    long long s = gr.sumRectCells(lx,ly+1,rx,ry);\n                    if (s > bestLocal){ bestLocal=s; blx=lx; bly=ly+1; brx=rx; bry=ry; }\n                }\n                if (bestLocal > bestSum){\n                    bestSum = bestLocal;\n                    lx=blx; ly=bly; rx=brx; ry=bry;\n                    improved = true;\n                }\n            }\n            Rect r = rectCoord(lx,ly,rx,ry);\n            add_candidate(r);\n        }\n    }\n\n    // Random sampling using real coordinates\n    // Sample subsets of x and y coordinates from points, propose rectangles\n    vector<int> xs, ys;\n    xs.reserve(pts.size()); ys.reserve(pts.size());\n    for (auto &p: pts){ xs.push_back(p.x); ys.push_back(p.y); }\n    // Deduplicate sampled sets for bounds selection\n    auto sample_unique = [&](const vector<int>& v, int k){\n        int M = v.size();\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        static std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n        shuffle(idx.begin(), idx.end(), rng);\n        unordered_set<int> seen;\n        vector<int> out;\n        out.reserve(k);\n        for(int i=0;i<M && (int)out.size()<k;i++){\n            int val = v[idx[i]];\n            if (seen.insert(val).second) out.push_back(val);\n        }\n        sort(out.begin(), out.end());\n        return out;\n    };\n    vector<int> sx = sample_unique(xs, 200);\n    vector<int> sy = sample_unique(ys, 200);\n    // Also add 0 and 100000 to allow edge anchoring\n    sx.push_back(0); sx.push_back(100000);\n    sy.push_back(0); sy.push_back(100000);\n    sort(sx.begin(), sx.end()); sx.erase(unique(sx.begin(), sx.end()), sx.end());\n    sort(sy.begin(), sy.end()); sy.erase(unique(sy.begin(), sy.end()), sy.end());\n\n    // Random pairs\n    std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto randint = [&](int L, int R){ std::uniform_int_distribution<int> dist(L,R); return dist(rng); };\n\n    int S = 1500; // number of random rectangles to try\n    int Xn = (int)sx.size();\n    int Yn = (int)sy.size();\n    for(int t=0;t<S;t++){\n        int i1 = randint(0, Xn-1);\n        int i2 = randint(0, Xn-1);\n        if (i1==i2){ if (i2+1<Xn) i2++; else if (i1>0) i1--; }\n        int j1 = randint(0, Yn-1);\n        int j2 = randint(0, Yn-1);\n        if (j1==j2){ if (j2+1<Yn) j2++; else if (j1>0) j1--; }\n        int xl = min(sx[i1], sx[i2]);\n        int xr = max(sx[i1], sx[i2]);\n        int yl = min(sy[j1], sy[j2]);\n        int yr = max(sy[j1], sy[j2]);\n        // Expand to include bounds (inclusive); ensure at least width/height >=1\n        if (xl==xr){ if (xr<100000) xr++; else if (xl>0) xl--; }\n        if (yl==yr){ if (yr<100000) yr++; else if (yl>0) yl--; }\n        Rect r{xl,yl,xr,yr,0};\n        if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) <= PERIM_LIMIT) add_candidate(r);\n    }\n\n    // Evaluate candidates exactly and keep best\n    Rect best;\n    best.score = LLONG_MIN;\n    auto evaluate = [&](Rect &r){\n        int a=0,b=0;\n        for (auto &p: pts){\n            if (insideRectInclusive(r, p.x, p.y)){\n                if (p.w==1) a++; else b++;\n            }\n        }\n        r.a = a; r.b = b;\n        r.score = (long long)a - (long long)b;\n    };\n\n    // Keep top T by rough proxy? We didn't have proxy except grid sum; candidates from grid had none; we could evaluate all; number ~ up to 200*2 + 1500 ~ 1900, fine.\n    for (auto &r: candidates){\n        evaluate(r);\n        if (r.score > best.score || (r.score==best.score && r.a > best.a)){\n            best = r;\n        }\n    }\n\n    // Fallback: if nothing produced (shouldn't happen), output full square\n    if (best.score==LLONG_MIN){\n        best = {0,0,100000,100000, 0};\n        evaluate(best);\n    }\n\n    // Output rectangle polygon (counterclockwise)\n    // Ensure perimeter limit (it should be)\n    // Ensure vertices distinct and within bounds\n    int x1 = max(0, min(100000, best.x1));\n    int y1 = max(0, min(100000, best.y1));\n    int x2 = max(0, min(100000, best.x2));\n    int y2 = max(0, min(100000, best.y2));\n    if (x1==x2) { if (x2<100000) x2++; else if (x1>0) x1--; }\n    if (y1==y2) { if (y2<100000) y2++; else if (y1>0) y1--; }\n    // final perimeter check\n    if (rect_perimeter(x1,y1,x2,y2) > 400000){\n        // shrink slightly\n        while (rect_perimeter(x1,y1,x2,y2) > 400000){\n            if (x2-x1 >= y2-y1){\n                if (x2-x1>1) x2--;\n                else if (y2-y1>1) y2--;\n                else break;\n            } else {\n                if (y2-y1>1) y2--;\n                else if (x2-x1>1) x2--;\n                else break;\n            }\n        }\n    }\n\n    cout << 4 << \"\\n\";\n    // CCW: (x1,y1)->(x2,y1)->(x2,y2)->(x1,y2)\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<long long> wp(N), hp(N);\n    for (int i = 0; i < N; i++) cin >> wp[i] >> hp[i];\n\n    // Decide rotation: rotate to make stacking height = min(w', h')\n    vector<int> rot(N, 0);\n    for (int i = 0; i < N; i++) {\n        // r=0 means no rotation: height = hp[i]\n        // r=1 means rotated: height = wp[i]\n        // choose the smaller as stacking height\n        rot[i] = (hp[i] <= wp[i]) ? 0 : 1;\n    }\n\n    for (int t = 0; t < T; t++) {\n        cout << N << '\\n';\n        for (int i = 0; i < N; i++) {\n            // Place all at x=0 stacking upward\n            // p, r, d, b\n            cout << i << ' ' << rot[i] << ' ' << 'U' << ' ' << -1 << '\\n';\n        }\n        cout.flush();\n        long long Wp, Hp;\n        if (!(cin >> Wp >> Hp)) return 0;\n        // Optionally print a comment line with observed values\n        // cerr << \"# turn \" << t << \" observed \" << Wp << \" \" << Hp << \"\\n\";\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Heuristic: choose a set of roots so that every vertex is within H hops of some root,\n// preferring low A as roots. Then multi-source BFS to assign parents and depths.\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, H;\n    if(!(cin >> N >> M >> H)) {\n        return 0;\n    }\n    vector<int> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\n    vector<vector<int>> adj(N);\n    vector<pair<int,int>> edges(M);\n    for(int i=0;i<M;i++){\n        int u,v; cin >> u >> v;\n        edges[i] = {u,v};\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    // read coordinates but not used\n    vector<pair<int,int>> coord(N);\n    for(int i=0;i<N;i++){\n        int x,y; cin >> x >> y;\n        coord[i] = {x,y};\n    }\n\n    // Helper to compute distances from multi-source roots up to full\n    auto multi_source_bfs = [&](const vector<int>& roots,\n                                vector<int>& dist,\n                                vector<int>& parent,\n                                vector<int>& root_of){\n        dist.assign(N, INT_MAX);\n        parent.assign(N, -2); // -2 indicates unassigned yet\n        root_of.assign(N, -1);\n        deque<int> dq;\n        for(int r: roots){\n            dist[r] = 0;\n            parent[r] = -1;\n            root_of[r] = r;\n            dq.push_back(r);\n        }\n        while(!dq.empty()){\n            int u = dq.front(); dq.pop_front();\n            int du = dist[u];\n            for(int v: adj[u]){\n                if(dist[v] == INT_MAX){\n                    dist[v] = du + 1;\n                    parent[v] = u;\n                    root_of[v] = root_of[u];\n                    dq.push_back(v);\n                }else if(dist[v] == du + 1){\n                    // tie: optional better parent selection, we can keep existing\n                    // Could prefer path that gives higher A deeper, but depth is same anyway.\n                }\n            }\n        }\n    };\n\n    // Build roots greedily to ensure all nodes within H\n    vector<int> dist(N), parent(N), root_of(N);\n    vector<int> roots;\n    // Start from the minimal A vertex\n    int start = int(min_element(A.begin(), A.end()) - A.begin());\n    roots.push_back(start);\n\n    multi_source_bfs(roots, dist, parent, root_of);\n\n    // While some vertices have dist > H, add a new root among them: pick with minimal A, tie-break by max dist\n    // To avoid O(K*N*(M)) worst-case with repeated full BFS, we will recompute BFS after each added root; K should be small (~N/(ball size)).\n    while(true){\n        int far_v = -1;\n        int bestA = INT_MAX;\n        int bestDist = -1;\n        for(int v=0; v<N; v++){\n            if(dist[v] > H){\n                if(A[v] < bestA){\n                    bestA = A[v];\n                    bestDist = dist[v];\n                    far_v = v;\n                }else if(A[v] == bestA && dist[v] > bestDist){\n                    bestDist = dist[v];\n                    far_v = v;\n                }\n            }\n        }\n        if(far_v == -1) break;\n        roots.push_back(far_v);\n        multi_source_bfs(roots, dist, parent, root_of);\n    }\n\n    // Final parent array is from the BFS above; ensure all have dist <= H (by construction)\n    vector<int> p = parent;\n    // Safety: If any dist == INT_MAX (shouldn't happen since graph connected), set as root.\n    for(int i=0;i<N;i++){\n        if(p[i] == -2 || dist[i] == INT_MAX){\n            p[i] = -1;\n        }\n        // Also ensure depth constraint: if any dist > H (should not), force root.\n        if(dist[i] > H){\n            p[i] = -1;\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    return 0;\n}","ahc042":"#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<string> C(N);\n    for (int i = 0; i < N; ++i) cin >> C[i];\n\n    // Collect positions and precompute Fukunokami positions.\n    vector<vector<bool>> hasF(N, vector<bool>(N, false));\n    vector<pair<int,int>> oni;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (C[i][j] == 'o') hasF[i][j] = true;\n            else if (C[i][j] == 'x') oni.emplace_back(i, j);\n        }\n    }\n\n    // Precompute prefix counts of Fukunokami per row/column to check rays quickly.\n    vector<vector<int>> rowPref(N, vector<int>(N+1, 0));\n    vector<vector<int>> colPref(N, vector<int>(N+1, 0));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            rowPref[i][j+1] = rowPref[i][j] + (hasF[i][j] ? 1 : 0);\n            colPref[j][i+1] = colPref[j][i] + (hasF[i][j] ? 1 : 0);\n        }\n    }\n\n    auto safe_up = [&](int i, int j)->bool {\n        // No Fukunokami above (rows 0..i-1) in column j\n        if (i == 0) return true;\n        return colPref[j][i] - colPref[j][0] == 0;\n    };\n    auto safe_down = [&](int i, int j)->bool {\n        // No Fukunokami below (rows i+1..N-1) in column j\n        if (i == N-1) return true;\n        return colPref[j][N] - colPref[j][i+1] == 0;\n    };\n    auto safe_left = [&](int i, int j)->bool {\n        if (j == 0) return true;\n        return rowPref[i][j] - rowPref[i][0] == 0;\n    };\n    auto safe_right = [&](int i, int j)->bool {\n        if (j == N-1) return true;\n        return rowPref[i][N] - rowPref[i][j+1] == 0;\n    };\n\n    struct Op { char d; int p; };\n    vector<Op> ops;\n    ops.reserve(1600);\n\n    // For each Oni, pick minimal cost safe direction and emit.\n    for (auto [i, j] : oni) {\n        // Determine available safe directions and their costs.\n        int bestCost = INT_MAX;\n        char bestDir = 0;\n        int param = -1; // row/col index\n\n        // Up\n        if (safe_up(i, j)) {\n            int k = i; // distance to top edge\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'U'; param = j; }\n        }\n        // Down\n        if (safe_down(i, j)) {\n            int k = (N - 1 - i);\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'D'; param = j; }\n        }\n        // Left\n        if (safe_left(i, j)) {\n            int k = j;\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'L'; param = i; }\n        }\n        // Right\n        if (safe_right(i, j)) {\n            int k = (N - 1 - j);\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'R'; param = i; }\n        }\n\n        // Per problem guarantee, at least one is safe.\n        if (bestDir == 0) {\n            // Fallback: should not happen; do nothing to avoid WA.\n            continue;\n        }\n\n        // Emit k+1 pushes toward bestDir, then k+1 pushes back.\n        int k;\n        char backDir;\n        if (bestDir == 'U') { k = i; backDir = 'D'; }\n        else if (bestDir == 'D') { k = (N - 1 - i); backDir = 'U'; }\n        else if (bestDir == 'L') { k = j; backDir = 'R'; }\n        else { // 'R'\n            k = (N - 1 - j); backDir = 'L';\n        }\n\n        // Ensure we do not exceed 4N^2 operations; with guarantees this should hold.\n        // But add a safety break.\n        if ((int)ops.size() + 2 * (k + 1) > 4 * N * N) break;\n\n        for (int t = 0; t < k + 1; ++t) ops.push_back({bestDir, param});\n        for (int t = 0; t < k + 1; ++t) ops.push_back({backDir, param});\n    }\n\n    // Output\n    for (auto &op : ops) {\n        cout << op.d << ' ' << op.p << '\\n';\n    }\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::high_resolution_clock::time_point st;\n    Timer() { reset(); }\n    void reset() { st = chrono::high_resolution_clock::now(); }\n    double elapsed() const {\n        auto ed = chrono::high_resolution_clock::now();\n        return chrono::duration<double>(ed - st).count();\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; long long L;\n    if(!(cin>>N>>L)) return 0;\n    vector<int> T(N);\n    for(int i=0;i<N;i++) cin>>T[i];\n\n    // Parameters\n    const int targetM = 20000; // target period length\n    int q = max(1, int( (long long) ( (L + targetM/2) / targetM ) ));\n    // initial weights\n    vector<int> w(N);\n    long long M = 0;\n    for(int i=0;i<N;i++){\n        long long wi = (T[i] + q/2) / q;\n        if(wi < 1) wi = 1;\n        w[i] = (int)wi;\n        M += w[i];\n    }\n    // Adjust sum w to be even (for 2M period it's fine regardless, but even helps)\n    // Also adjust to keep M not too big\n    // Try to bring M close to L/q\n    long long targetSum = L / q;\n    // record fractional parts to refine: compute exact fractional T/q\n    vector<pair<double,int>> frac(N);\n    for(int i=0;i<N;i++){\n        double x = double(T[i]) / double(q);\n        frac[i] = { x - floor(x), i };\n    }\n    if(M > targetSum){\n        // reduce some w by 1 but keep >=1\n        sort(frac.begin(), frac.end(), greater<>());\n        long long need = M - targetSum;\n        for(int k=0;k<N && need>0;k++){\n            int i = frac[k].second;\n            if(w[i] > 1){\n                w[i]--; need--;\n            }\n        }\n        M -= (L / q - targetSum); // ignore; we'll recompute M below\n        M = 0; for(int i=0;i<N;i++) M += w[i];\n    }else if(M < targetSum){\n        // increase some w by 1\n        sort(frac.begin(), frac.end());\n        long long need = targetSum - M;\n        for(int k=0;k<N && need>0;k++){\n            int i = frac[k].second;\n            w[i]++; need--;\n        }\n        M = 0; for(int i=0;i<N;i++) M += w[i];\n    }\n    // Ensure M >= N and small enough\n    if(M < N){\n        for(int i=0;i<N && M<N;i++){ w[i]++; M++; }\n    }\n    // departure counts per port: a (odd) first, then b (even)\n    vector<int> d1(N), d0(N);\n    for(int i=0;i<N;i++){\n        d1[i] = (w[i]+1)/2;\n        d0[i] = w[i]/2;\n    }\n    // destination remaining demand\n    vector<int> r = w;\n\n    // Order sources by descending w\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a,int b){\n        if(w[a]!=w[b]) return w[a]>w[b];\n        return a<b;\n    });\n\n    // Max-heap of destinations by remaining r\n    struct Node { int r, id; };\n    struct Cmp { bool operator()(const Node& a, const Node& b) const {\n        if(a.r!=b.r) return a.r < b.r;\n        return a.id > b.id;\n    } };\n    priority_queue<Node, vector<Node>, Cmp> pq;\n\n    auto rebuild_pq = [&](){\n        while(!pq.empty()) pq.pop();\n        for(int j=0;j<N;j++) pq.push({r[j], j});\n    };\n    rebuild_pq();\n\n    vector<int> f1(N,-1), f0(N,-1);\n    // Greedy assignments\n    for(int si=0; si<N; si++){\n        int s = ord[si];\n        // assign for bigger port first\n        int need1 = d1[s], need0 = d0[s];\n        // we will pick best remaining nodes\n        // fetch top two distinct nodes with sufficient capacity if possible\n        // We'll try a few attempts to find sufficient capacity; otherwise take best anyway.\n        // Copy pq to vector of candidates (top K)\n        vector<Node> cand;\n        int K = min(N, 10); // look at top 10\n        for(int k=0;k<K && !pq.empty();k++){\n            cand.push_back(pq.top()); pq.pop();\n        }\n        auto restore = [&](){\n            for(auto &nd: cand) pq.push(nd);\n            cand.clear();\n        };\n        // pick for port1\n        int pick1 = -1, idx1=-1;\n        int best_idx=-1;\n        int best_r=-1;\n        for(int i=0;i<(int)cand.size();i++){\n            if(cand[i].r >= need1){ pick1 = cand[i].id; idx1=i; break; }\n            if(cand[i].r > best_r){ best_r=cand[i].r; best_idx=i; }\n        }\n        if(pick1==-1){\n            // take the best anyway\n            if(best_idx==-1){ // should not happen\n                restore();\n                rebuild_pq();\n                // fallback to ring\n                for(int i=0;i<N;i++){ cout<< (i+1)%N <<\" \"<< (i+1)%N <<\"\\n\"; }\n                return 0;\n            }\n            pick1 = cand[best_idx].id; idx1 = best_idx;\n        }\n        // reduce r\n        cand[idx1].r -= need1;\n        f1[s] = pick1;\n\n        // pick for port0, avoid same as pick1 if possible\n        int pick0 = -1, idx0=-1;\n        best_idx=-1; best_r=-1;\n        for(int i=0;i<(int)cand.size();i++){\n            if(cand[i].id==pick1) continue;\n            if(cand[i].r >= need0){ pick0 = cand[i].id; idx0=i; break; }\n            if(cand[i].r > best_r){ best_r=cand[i].r; best_idx=i; }\n        }\n        if(pick0==-1){\n            // allow same as pick1 if needed\n            if(need0>0){\n                if(cand[idx1].r >= need0){\n                    pick0 = pick1; idx0 = idx1;\n                }else{\n                    // take best available even if insufficient\n                    if(best_idx==-1){\n                        // pick same\n                        pick0 = pick1; idx0 = idx1;\n                    }else{\n                        pick0 = cand[best_idx].id; idx0 = best_idx;\n                    }\n                }\n            }else{\n                // need0==0\n                pick0 = pick1; idx0 = idx1;\n            }\n        }\n        cand[idx0].r -= need0;\n        f0[s] = pick0;\n\n        // write back candidates\n        for(auto &nd: cand) pq.push(nd);\n        // update r array too (for book-keeping)\n        r[pick1] -= need1;\n        r[pick0] -= need0;\n    }\n\n    // If due to greediness some r[j] != 0, try to repair by swapping some sources' assignments between f0/f1\n    // Simple repair: while exists j with r[j]>0 and k with r[k]<0, move some source's port pointing to k to j, favor small impact.\n    vector<int> surplus, deficit;\n    for(int j=0;j<N;j++){\n        if(r[j]>0) surplus.push_back(j);\n        else if(r[j]<0) deficit.push_back(j);\n    }\n    // Build reverse maps: which ports point to a destination\n    vector<vector<pair<int,int>>> rev(N); // dest -> list of (s,port) where port 1=a, 0=b\n    for(int s=0;s<N;s++){\n        if(d1[s]>0) rev[f1[s]].push_back({s,1});\n        if(d0[s]>0) rev[f0[s]].push_back({s,0});\n    }\n    // Attempt repairs\n    int attempts = 0;\n    while(!surplus.empty() && !deficit.empty() && attempts < 10000){\n        attempts++;\n        int j_pos = surplus.back();\n        int j_neg = deficit.back();\n        // find a source s and port p that currently points to j_neg and can be switched to j_pos without breaking alternation counts\n        bool moved=false;\n        auto &lst = rev[j_neg];\n        for(size_t idx=0; idx<lst.size(); idx++){\n            int s = lst[idx].first;\n            int p = lst[idx].second;\n            // capacity to move: how many departures on that port\n            int cap = (p==1? d1[s] : d0[s]);\n            if(cap<=0) continue;\n            // switch destination of this port from j_neg to j_pos\n            // apply\n            if(p==1) f1[s]=j_pos; else f0[s]=j_pos;\n            r[j_pos]--; r[j_neg]++;\n            // update rev lists\n            lst.erase(lst.begin()+idx);\n            rev[j_pos].push_back({s,p});\n            moved=true;\n            break;\n        }\n        if(!moved){\n            // cannot move; pop one and continue\n            if(r[j_pos]==0) surplus.pop_back();\n            else if(r[j_neg]==0) deficit.pop_back();\n            else {\n                // try another pair\n                if(surplus.size()>1) rotate(surplus.begin(), surplus.begin()+1, surplus.end());\n                if(deficit.size()>1) rotate(deficit.begin(), deficit.begin()+1, deficit.end());\n            }\n        }else{\n            if(r[j_pos]==0) surplus.pop_back();\n            if(r[j_neg]==0) deficit.pop_back();\n        }\n    }\n    // If still imbalance remains, ignore; the sequence builder may still work, and final simulation decides counts anyway.\n\n    // Build period P of length M using alternation counts\n    vector<int> rem1 = d1, rem0 = d0;\n    vector<int> next_port(N, 1); // first departure uses a (odd)\n    vector<int> P; P.reserve((size_t)M);\n    // We'll construct a walk that uses exactly w[x] appearances of each x.\n    vector<int> used_vis(N, 0);\n\n    auto take_next = [&](int cur)->int{\n        int p = next_port[cur];\n        int to = (p==1? f1[cur] : f0[cur]);\n        if(p==1){\n            if(rem1[cur]>0){\n                rem1[cur]--;\n                next_port[cur] = 0;\n                return to;\n            }else if(rem0[cur]>0){\n                // forced flip, will break strict alternation but recover\n                rem0[cur]--;\n                next_port[cur] = 1;\n                return f0[cur];\n            }else{\n                return -1;\n            }\n        }else{\n            if(rem0[cur]>0){\n                rem0[cur]--;\n                next_port[cur] = 1;\n                return to;\n            }else if(rem1[cur]>0){\n                rem1[cur]--;\n                next_port[cur] = 0;\n                return f1[cur];\n            }else{\n                return -1;\n            }\n        }\n    };\n\n    int cur = 0;\n    P.push_back(cur);\n    used_vis[cur]++;\n    for(long long step=1; step<M; step++){\n        int nx = take_next(cur);\n        if(nx==-1){\n            // find a node with remaining outdegree to jump\n            int best=-1;\n            for(int i=0;i<N;i++){\n                if(rem0[i]>0 || rem1[i]>0){ best=i; break; }\n            }\n            if(best==-1) break;\n            cur = best;\n            // first time we visit best? next_port is already set; okay\n            P.push_back(cur);\n            used_vis[cur]++;\n            continue;\n        }else{\n            cur = nx;\n            P.push_back(cur);\n            used_vis[cur]++;\n        }\n    }\n    // If P shorter than M, fill by appending nodes with remaining needed counts arbitrarily\n    for(int i=0;i<N;i++){\n        while((long long)used_vis[i] < w[i]){\n            P.push_back(i);\n            used_vis[i]++;\n        }\n    }\n    // Now define edges a_i, b_i\n    vector<int> a(N), b(N);\n    for(int i=0;i<N;i++){ a[i]=f1[i]; b[i]=f0[i]; }\n    // As a safety if any a_i or b_i out of range, clamp\n    for(int i=0;i<N;i++){\n        if(a[i]<0 || a[i]>=N) a[i]=(i+1)%N;\n        if(b[i]<0 || b[i]>=N) b[i]=(i+1)%N;\n    }\n\n    // Simulate full L to get t_i\n    vector<int> t(N,0);\n    int x = 0;\n    for(long long week=0; week<L; week++){\n        t[x]++;\n        int tx = t[x];\n        int nx = ( (tx%2)==1 ? a[x] : b[x] );\n        x = nx;\n    }\n\n    // Quick local improvement: try swapping a or b targets for random sources to reduce error\n    auto error_of = [&](const vector<int>& tt)->long long{\n        long long e=0;\n        for(int i=0;i<N;i++) e += llabs((long long)tt[i]-T[i]);\n        return e;\n    };\n    long long bestE = error_of(t);\n    vector<int> bestA=a, bestB=b;\n    Timer tim;\n    std::mt19937 rng(712367);\n    // limit time ~0.3s for improvement\n    while(tim.elapsed() < 0.3){\n        int s = rng()%N;\n        bool flipA = (rng()&1);\n        int old = flipA ? a[s] : b[s];\n        int cand = rng()%N;\n        if(cand==old) continue;\n        if(flipA) a[s]=cand; else b[s]=cand;\n        // simulate quickly\n        vector<int> tt(N,0);\n        int y=0;\n        for(long long wkk=0; wkk<L; wkk++){\n            tt[y]++;\n            int ty=tt[y];\n            int ny = ( (ty%2)==1 ? a[y] : b[y] );\n            y = ny;\n        }\n        long long E = error_of(tt);\n        if(E < bestE){\n            bestE = E; bestA=a; bestB=b; t.swap(tt);\n        }else{\n            // revert\n            if(flipA) a[s]=old; else b[s]=old;\n        }\n    }\n    a = bestA; b = bestB;\n\n    // Output\n    for(int i=0;i<N;i++){\n        cout<<a[i]<<\" \"<<b[i]<<\"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    DSU(int n=0): n(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){ a=find(a); b=find(b); if(a==b) return false; if(r[a]<r[b]) swap(a,b); p[b]=a; if(r[a]==r[b]) r[a]++; return true; }\n};\n\nstatic inline uint32_t part1by1(uint32_t x){\n    x &= 0x0000ffff;\n    x = (x | (x << 8)) & 0x00FF00FF;\n    x = (x | (x << 4)) & 0x0F0F0F0F;\n    x = (x | (x << 2)) & 0x33333333;\n    x = (x | (x << 1)) & 0x55555555;\n    return x;\n}\nstatic inline uint32_t morton2D(uint32_t x, uint32_t y){\n    return (part1by1(y) << 1) | part1by1(x);\n}\n\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    // centers\n    vector<int> cx(N), cy(N);\n    for(int i=0;i<N;i++){\n        cx[i] = (lx[i]+rx[i])>>1;\n        cy[i] = (ly[i]+ry[i])>>1;\n    }\n    // Morton order\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    // scale to 14 bits [0,16383]\n    auto codeOf = [&](int i)->uint32_t{\n        uint32_t xs = (uint32_t) min(16383, max(0, cx[i]*16383/10000));\n        uint32_t ys = (uint32_t) min(16383, max(0, cy[i]*16383/10000));\n        return morton2D(xs, ys);\n    };\n    sort(idx.begin(), idx.end(), [&](int a, int b){\n        uint32_t ca = codeOf(a), cb = codeOf(b);\n        if(ca!=cb) return ca<cb;\n        if(cx[a]!=cx[b]) return cx[a]<cx[b];\n        if(cy[a]!=cy[b]) return cy[a]<cy[b];\n        return a<b;\n    });\n\n    // Build groups by slicing idx per G\n    vector<vector<int>> groups(M);\n    int pos=0;\n    for(int k=0;k<M;k++){\n        groups[k].reserve(G[k]);\n        for(int t=0;t<G[k];t++) groups[k].push_back(idx[pos++]);\n    }\n\n    int queries_left = Q;\n\n    // Prepare output containers\n    vector<vector<pair<int,int>>> group_edges(M);\n    group_edges.assign(M, {});\n    // Helper to query MST for a set C (size between 2 and L). Returns edges as pairs (u,v) with u<v.\n    auto do_query = [&](const vector<int>& C)->vector<pair<int,int>>{\n        int l = (int)C.size();\n        cout<<\"? \"<<l;\n        for(int v: C) cout<<\" \"<<v;\n        cout<<\"\\n\"<<flush;\n        vector<pair<int,int>> ret;\n        ret.reserve(max(0,l-1));\n        for(int i=0;i<l-1;i++){\n            int a,b; cin>>a>>b;\n            if(a>b) swap(a,b);\n            ret.emplace_back(a,b);\n        }\n        return ret;\n    };\n\n    // Build approximate MST using k-NN over Morton window for a set of vertices ids (global city indices)\n    auto approx_mst = [&](const vector<int>& vs)->vector<pair<int,int>>{\n        int n = (int)vs.size();\n        vector<int> order(n);\n        iota(order.begin(), order.end(), 0);\n        // Sort vs by Morton locally\n        vector<pair<uint32_t,int>> arr(n);\n        for(int i=0;i<n;i++){\n            arr[i] = {codeOf(vs[i]), i};\n        }\n        sort(arr.begin(), arr.end());\n        vector<int> ordidx(n);\n        for(int i=0;i<n;i++) ordidx[i] = arr[i].second;\n        // Map position to node index\n        vector<int> seq(n);\n        for(int i=0;i<n;i++) seq[i] = vs[ordidx[i]];\n\n        // Build candidate edges\n        const int Wwin = 40; // window size in Morton order\n        const int K = 8;     // neighbors to connect\n        struct Edge { int u,v; int w; };\n        vector<Edge> edges;\n        edges.reserve(n * K);\n        // For distance estimation, use floor of Euclidean between centers\n        auto distC = [&](int a, int b)->int{\n            long dx = cx[a]-cx[b];\n            long dy = cy[a]-cy[b];\n            long long d2 = dx*dx + dy*dy;\n            return (int)floor(sqrt((long double)d2)); // ok\n        };\n        for(int i=0;i<n;i++){\n            int u = seq[i];\n            // collect candidates in window\n            vector<pair<int,int>> cands; cands.reserve(2*Wwin);\n            for(int d=-Wwin; d<=Wwin; d++){\n                if(d==0) continue;\n                int j=i+d;\n                if(j<0||j>=n) continue;\n                int v = seq[j];\n                int w = distC(u,v);\n                cands.emplace_back(w, v);\n            }\n            // pick K smallest\n            nth_element(cands.begin(), cands.begin()+min((int)cands.size(), K), cands.end(),\n                        [](const auto& A, const auto& B){ return A.first < B.first; });\n            int take = min((int)cands.size(), K);\n            for(int t=0;t<take;t++){\n                int v = cands[t].second;\n                int w = cands[t].first;\n                int a=u,b=v; if(a>b) swap(a,b);\n                edges.push_back({a,b,w});\n            }\n        }\n        // deduplicate edges\n        sort(edges.begin(), edges.end(), [](const Edge& A, const Edge& B){\n            if(A.u!=B.u) return A.u<B.u;\n            if(A.v!=B.v) return A.v<B.v;\n            return A.w<B.w;\n        });\n        edges.erase(unique(edges.begin(), edges.end(), [](const Edge& A, const Edge& B){\n            return A.u==B.u && A.v==B.v;\n        }), edges.end());\n        // Kruskal\n        DSU dsu(N);\n        vector<pair<int,int>> res;\n        res.reserve(max(0, n-1));\n        sort(edges.begin(), edges.end(), [](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        int added=0;\n        for(auto &e: edges){\n            if(dsu.unite(e.u, e.v)){\n                res.emplace_back(e.u, e.v);\n                if(++added == n-1) break;\n            }\n        }\n        // If graph not connected due to sparse edges, fallback by connecting chain in Morton order\n        if((int)res.size() < n-1){\n            // connect remaining with chain (seq order)\n            for(int i=0;i<n-1;i++){\n                int a = seq[i], b = seq[i+1];\n                if(dsu.unite(a,b)){\n                    if(a>b) swap(a,b);\n                    res.emplace_back(a,b);\n                }\n            }\n            // If still less (shouldn't happen), add arbitrary links\n            int root = seq[0];\n            for(int i=1;i<n && (int)res.size()<n-1;i++){\n                int a=root, b=seq[i];\n                if(dsu.unite(a,b)){\n                    if(a>b) swap(a,b);\n                    res.emplace_back(a,b);\n                }\n            }\n        }\n        // sort pairs u<v as required order arbitrary is fine\n        return res;\n    };\n\n    // Decide which groups to query: small groups first\n    vector<pair<int,int>> orderGroups; // (Gi, k)\n    orderGroups.reserve(M);\n    for(int k=0;k<M;k++) orderGroups.emplace_back(G[k], k);\n    sort(orderGroups.begin(), orderGroups.end());\n    vector<char> willQuery(M, 0);\n    for(auto [sz,k]: orderGroups){\n        if(sz<=L && queries_left>=1){\n            willQuery[k]=1;\n            queries_left -= 1;\n        }\n    }\n    // Construct edges per group\n    for(int k=0;k<M;k++){\n        const auto& g = groups[k];\n        int sz = (int)g.size();\n        if(sz==1){\n            group_edges[k] = {};\n            continue;\n        }\n        if(willQuery[k]){\n            // Query whole group\n            auto edges = do_query(g);\n            group_edges[k] = edges;\n        }else{\n            // Approximate MST using centers\n            auto edges = approx_mst(g);\n            // Ensure we have exactly sz-1 edges; approx_mst ensures connectivity\n            if((int)edges.size() > sz-1) edges.resize(sz-1);\n            group_edges[k] = edges;\n        }\n    }\n\n    // Output final answer\n    cout<<\"!\"<<\"\\n\";\n    for(int k=0;k<M;k++){\n        const auto& g = groups[k];\n        for(int i=0;i<(int)g.size();i++){\n            if(i) cout<<\" \";\n            cout<<g[i];\n        }\n        cout<<\"\\n\";\n        for(auto &e: group_edges[k]){\n            cout<<e.first<<\" \"<<e.second<<\"\\n\";\n        }\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint N, M;\nvector<Pos> targets;\nvector<string> out_actions;\n\ninline bool inb(int i,int j){ return 0<=i && i<N && 0<=j && j<N; }\n\nenum Dir {U=0,D=1,L=2,R=3};\nconst int di[4] = {-1,1,0,0};\nconst int dj[4] = {0,0,-1,1};\nchar dirChar(Dir d){ return d==U?'U':d==D?'D':d==L?'L':'R'; }\n\nstruct Grid {\n    int N;\n    vector<uint8_t> blk; // N*N\n    Grid(int N):N(N),blk(N*N,0){}\n    inline bool isBlock(int i,int j) const { return blk[i*N+j]; }\n    inline void toggle(int i,int j){ blk[i*N+j]^=1; }\n    inline void set(int i,int j,bool v){ blk[i*N+j]=v; }\n};\n\nGrid grid(20);\n\nvoid emit(char act, Dir d){\n    string s; s+=act; s+=' '; s+=dirChar(d);\n    out_actions.push_back(s);\n}\n\n// Try to move one step if free\nbool try_move(Pos &p, Dir d){\n    int ni=p.i+di[d], nj=p.j+dj[d];\n    if(!inb(ni,nj)) return false;\n    if(grid.isBlock(ni,nj)) return false;\n    emit('M', d);\n    p.i=ni; p.j=nj;\n    return true;\n}\n\n// Slide in dir until blocked (or border). Return landing.\nPos simulate_slide(const Pos &p, Dir d){\n    int i=p.i, j=p.j;\n    while(true){\n        int ni=i+di[d], nj=j+dj[d];\n        if(!inb(ni,nj)) break;\n        if(grid.isBlock(ni,nj)) break;\n        i=ni; j=nj;\n    }\n    return {i,j};\n}\nvoid do_slide(Pos &p, Dir d){\n    emit('S', d);\n    p = simulate_slide(p,d);\n}\n\n// Place temp block at cell (ci,cj): do Alter towards that cell from adjacent cell?\n// But Alter operation is relative to current position. We cannot alter arbitrary cells!\n// Important correction: Alter toggles the adjacent square in the specified direction FROM CURRENT POSITION. So to place a block somewhere, we must stand adjacent to it and issue A towards it.\n// This changes the design: we cannot place arbitrary stopper remotely. We must navigate to adjacent cell to place/remove blocks.\n\n// Therefore, strategy must avoid heavy block placement, or place only blocks adjacent to our path. Simple baseline: use Moves mostly, slides aided by borders only. Additionally, we can sometimes place a stopper right before a slide by moving adjacent to the intended stopper location.\n\n// Revised plan:\n// - Use Moves primarily, occasionally use slides leveraging borders, no remote stoppers.\n// - Because remote altering is impossible, temporary stopper placement is expensive (requires path to be adjacent), often negating benefit.\n// - So we will implement a safe and simple mover: greedy Manhattan path using Moves, with opportunistic Slides when aligned with border stopping at target row/col.\n\n// Heuristic with borders only:\n// From p to t:\n// - If same row: try to slide horizontally towards t: check landing equals t if border or a block stops at t; initially no blocks, border stops at edge, so landing will be at border, not t unless t is at border. So only helpful when target lies on border in that direction.\n// - Similarly for same column.\n// Given constraint, slides are rarely useful without blocks. Therefore, the robust baseline is pure Moves with a dash of slides when target is on border alignment. This will still succeed within 1600 actions for M=40 and N=20 because worst-case per leg ~ 38 moves, total ~ < 1500 average. This is acceptable and guarantees full visitation. It won't rank high but is safe.\n\n// We'll implement:\n// - Simple obstacle-aware BFS using Moves only (since blocks may exist if we accidentally placed some; but we won't place any). BFS in 20x20 is trivial. However, dynamic obstacles none, so Manhattan greedy is fine and faster.\n// - But to avoid getting stuck when we do slides, we won't place any blocks, and we will avoid sliding except when we can land exactly on target (same row/col and target on the border in that direction).\n\n// Implementation now reverts to Move-only with rare slides.\n\nbool can_land_by_slide_to_target(const Pos &p, const Pos &t, Dir &d_out){\n    if(p.i==t.i){\n        if(t.j==0 && t.j<p.j){ d_out = L; return true; }\n        if(t.j==N-1 && t.j>p.j){ d_out = R; return true; }\n    }\n    if(p.j==t.j){\n        if(t.i==0 && t.i<p.i){ d_out = U; return true; }\n        if(t.i==N-1 && t.i>p.i){ d_out = D; return true; }\n    }\n    return false;\n}\n\nvoid move_greedy(Pos &p, const Pos &t){\n    // simple Manhattan greedy avoiding blocks (there are none if we never alter)\n    while(!(p.i==t.i && p.j==t.j)){\n        Dir d;\n        if(p.i < t.i) d=D;\n        else if(p.i > t.i) d=U;\n        else if(p.j < t.j) d=R;\n        else d=L;\n        // try move preferred, else try orthogonal alternatives\n        if(try_move(p,d)) continue;\n        // try other three directions to detour minimally\n        bool moved=false;\n        for(int k=0;k<4;k++){\n            if(try_move(p, (Dir)k)){ moved=true; break; }\n        }\n        if(!moved){\n            // grid fully blocked around, should not happen with our no-block policy\n            break;\n        }\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if(!(cin>>N>>M)) return 0;\n    targets.resize(M);\n    for(int k=0;k<M;k++){\n        cin>>targets[k].i>>targets[k].j;\n    }\n    grid = Grid(N);\n    Pos cur = targets[0];\n    for(int k=1;k<M;k++){\n        Pos t = targets[k];\n        // try border slide if possible\n        Dir d;\n        if(can_land_by_slide_to_target(cur, t, d)){\n            // Ensure slide path has no internal blocks; we have none, so safe\n            do_slide(cur, d);\n        }else{\n            move_greedy(cur, t);\n        }\n    }\n    // Output\n    for(auto &s: out_actions) cout<<s<<\"\\n\";\n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Heuristic rectangle growth with spatial hashing and micro-shrinks.\n\nstruct Rect {\n    int a,b,c,d; // [a,c) x [b,d)\n    long long area;\n    inline int w() const { return c - a; }\n    inline int h() const { return d - b; }\n    inline void recompute_area() { area = 1LL * (c - a) * (d - b); }\n};\n\nstatic inline bool overlap_pos(const Rect& A, const Rect& B) {\n    if (A.c <= B.a || B.c <= A.a) return false;\n    if (A.d <= B.b || B.d <= A.b) return false;\n    return true;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n;\n    if(!(cin>>n)) return 0;\n    vector<int> x(n), y(n);\n    vector<long long> r(n);\n    for(int i=0;i<n;i++) cin>>x[i]>>y[i]>>r[i];\n\n    vector<Rect> rect(n);\n    for(int i=0;i<n;i++){\n        int a=x[i], b=y[i], c=x[i]+1, d=y[i]+1;\n        a = max(0, min(9999, a));\n        b = max(0, min(9999, b));\n        c = min(10000, max(a+1, min(10000, c)));\n        d = min(10000, max(b+1, min(10000, d)));\n        rect[i] = {a,b,c,d,0};\n        rect[i].recompute_area();\n    }\n\n    // Spatial hash with finer grid\n    const int G = 64;\n    const int GRID = (10000 + G - 1) / G; // 157\n    vector<vector<int>> buckets(GRID*GRID);\n    auto cell_id = [&](int gx, int gy){ return gy*GRID + gx; };\n    auto gx_from_x = [&](int X){ return min(GRID-1, max(0, X / G)); };\n    auto gy_from_y = [&](int Y){ return min(GRID-1, max(0, Y / G)); };\n\n    auto add_rect = [&](int id){\n        auto &R = rect[id];\n        int gx0 = gx_from_x(R.a);\n        int gx1 = gx_from_x(max(0, R.c-1));\n        int gy0 = gy_from_y(R.b);\n        int gy1 = gy_from_y(max(0, R.d-1));\n        for(int gy=gy0; gy<=gy1; ++gy)\n            for(int gx=gx0; gx<=gx1; ++gx)\n                buckets[cell_id(gx,gy)].push_back(id);\n    };\n    auto remove_rect = [&](int id){\n        auto &R = rect[id];\n        int gx0 = gx_from_x(R.a);\n        int gx1 = gx_from_x(max(0, R.c-1));\n        int gy0 = gy_from_y(R.b);\n        int gy1 = gy_from_y(max(0, R.d-1));\n        for(int gy=gy0; gy<=gy1; ++gy)\n            for(int gx=gx0; gx<=gx1; ++gx){\n                auto &v = buckets[cell_id(gx,gy)];\n                for(size_t k=0;k<v.size();++k){\n                    if(v[k]==id){ v[k]=v.back(); v.pop_back(); break; }\n                }\n            }\n    };\n    auto check_band = [&](const Rect& NR, int x0, int x1, int y0, int y1, int self)->bool{\n        int gx0 = gx_from_x(x0);\n        int gx1 = gx_from_x(max(0,x1-1));\n        int gy0 = gy_from_y(y0);\n        int gy1 = gy_from_y(max(0,y1-1));\n        for (int gy=gy0; gy<=gy1; ++gy)\n            for (int gx=gx0; gx<=gx1; ++gx){\n                const auto &v = buckets[cell_id(gx,gy)];\n                for (int id : v) {\n                    if (id==self) continue;\n                    if (overlap_pos(NR, rect[id])) return false;\n                }\n            }\n        return true;\n    };\n\n    auto can_expand = [&](int i, int s)->bool{\n        const Rect &R = rect[i];\n        if (s==0) {\n            if (R.a <= 0) return false;\n            Rect NR = R; NR.a = R.a - 1;\n            return check_band(NR, NR.a, R.a, R.b, R.d, i);\n        } else if (s==1) {\n            if (R.c >= 10000) return false;\n            Rect NR = R; NR.c = R.c + 1;\n            return check_band(NR, R.c, NR.c, R.b, R.d, i);\n        } else if (s==2) {\n            if (R.b <= 0) return false;\n            Rect NR = R; NR.b = R.b - 1;\n            return check_band(NR, R.a, R.c, NR.b, R.b, i);\n        } else {\n            if (R.d >= 10000) return false;\n            Rect NR = R; NR.d = R.d + 1;\n            return check_band(NR, R.a, R.c, R.d, NR.d, i);\n        }\n    };\n    auto do_expand = [&](int i, int s){\n        remove_rect(i);\n        if (s==0) rect[i].a--;\n        else if (s==1) rect[i].c++;\n        else if (s==2) rect[i].b--;\n        else rect[i].d++;\n        rect[i].recompute_area();\n        add_rect(i);\n    };\n    auto can_shrink = [&](int i, int s)->bool{\n        const Rect &R = rect[i];\n        if (s==0) { // move left side right by 1\n            if (R.c - (R.a+1) <= 0) return false;\n            return true;\n        } else if (s==1) {\n            if ((R.c-1) - R.a <= 0) return false;\n            return true;\n        } else if (s==2) {\n            if (R.d - (R.b+1) <= 0) return false;\n            return true;\n        } else {\n            if ((R.d-1) - R.b <= 0) return false;\n            return true;\n        }\n    };\n    auto do_shrink = [&](int i, int s){\n        remove_rect(i);\n        if (s==0) rect[i].a++;\n        else if (s==1) rect[i].c--;\n        else if (s==2) rect[i].b++;\n        else rect[i].d--;\n        rect[i].recompute_area();\n        add_rect(i);\n    };\n\n    auto score = [&](long long si, long long ri)->long double{\n        long double mn = min<long double>(ri, si);\n        long double mx = max<long double>(ri, si);\n        long double t = mn / mx;\n        long double val = 1.0L - (1.0L - t)*(1.0L - t);\n        return val;\n    };\n\n    // RNG\n    uint64_t seed = chrono::high_resolution_clock::now().time_since_epoch().count();\n    mt19937_64 rng(seed);\n    auto now = [&](){ return chrono::high_resolution_clock::now(); };\n    auto start_time = now();\n    const double TIME_LIMIT = 4.75;\n    auto elapsed_sec = [&](){ return chrono::duration<double>(now() - start_time).count(); };\n\n    for(int i=0;i<n;i++) add_rect(i);\n\n    vector<int> tries = {0,1,2,3};\n    vector<pair<long long,int>> ord(n);\n\n    // Helper: estimate free steps possible in a direction before collision\n    auto free_steps = [&](int i, int s, int cap_steps)->int{\n        const Rect &R = rect[i];\n        int steps = 0;\n        Rect NR = R;\n        while (steps < cap_steps) {\n            if (s==0) {\n                if (NR.a <= 0) break;\n                Rect test = NR; test.a--;\n                if (!check_band(test, test.a, NR.a, NR.b, NR.d, i)) break;\n                NR.a--; \n            } else if (s==1) {\n                if (NR.c >= 10000) break;\n                Rect test = NR; test.c++;\n                if (!check_band(test, NR.c, test.c, NR.b, NR.d, i)) break;\n                NR.c++;\n            } else if (s==2) {\n                if (NR.b <= 0) break;\n                Rect test = NR; test.b--;\n                if (!check_band(test, NR.a, NR.c, test.b, NR.b, i)) break;\n                NR.b--;\n            } else {\n                if (NR.d >= 10000) break;\n                Rect test = NR; test.d++;\n                if (!check_band(test, NR.a, NR.c, NR.d, test.d, i)) break;\n                NR.d++;\n            }\n            steps++;\n        }\n        return steps;\n    };\n\n    // Main growth rounds\n    int rounds = 0;\n    while (elapsed_sec() < TIME_LIMIT * 0.78) {\n        for (int i=0;i<n;i++){\n            long long deficit = r[i] - rect[i].area;\n            // Penalize overshoot more\n            long long key = (deficit >= 0 ? deficit : deficit - llabs(deficit));\n            ord[i] = {key, i};\n        }\n        sort(ord.begin(), ord.end(), [&](auto &L, auto &R){\n            if (L.first != R.first) return L.first > R.first;\n            return L.second < R.second;\n        });\n\n        bool any=false;\n        for (int k=0;k<n && elapsed_sec() < TIME_LIMIT * 0.78; ++k) {\n            int i = ord[k].second;\n            long long si = rect[i].area;\n            long long ri = r[i];\n\n            // Hard cap: generally avoid overshoot\n            bool allow_overshoot = false;\n            long long cap = ri;\n            if (si < ri) {\n                cap = ri; // can grow to target\n            } else {\n                // allow tiny overshoot only if extremely small band and we might help later shape\n                // but we don't grow overshoot in this phase\n                continue;\n            }\n\n            // Try up to two successful expansions per visit to prevent hogging\n            int success = 0;\n            for (int att=0; att<8; ++att) {\n                if (elapsed_sec() >= TIME_LIMIT * 0.78) break;\n                // Direction selection: combine immediate gain and available space\n                array<int,4> ds = {0,1,2,3};\n                shuffle(ds.begin(), ds.end(), rng);\n\n                int w = rect[i].w(), h = rect[i].h();\n                int best_dir = -1;\n                long double best_score = -1e100;\n\n                for (int d : ds) {\n                    if (!can_expand(i, d)) continue;\n                    long long inc = (d<=1 ? h : w);\n                    long long newS = si + inc;\n                    if (newS > cap) continue;\n\n                    // potential extra steps available in direction d (limited)\n                    int max_steps_considered = 16; // small lookahead\n                    int free_d = free_steps(i, d, max_steps_considered);\n                    long double gain_now = (double)(score(newS, ri) - score(si, ri));\n                    // heuristics: potential gain by lookahead (rough)\n                    long double potential_band = 0.0L;\n                    if (free_d > 0) {\n                        long long s2 = si;\n                        int tw = w, th = h;\n                        for (int t=0;t<free_d; ++t) {\n                            if (d<=1) { s2 += th; tw++; }\n                            else { s2 += tw; th++; }\n                        }\n                        long double pot = (double)(score(min<long long>(s2, cap), ri) - score(si, ri));\n                        potential_band = pot;\n                    }\n                    // aspect encouragement\n                    int nw = w + ((d<=1)?1:0);\n                    int nh = h + ((d>=2)?1:0);\n                    long double aspect_pen = fabsl((long double)nw/nh - 1.0L);\n                    long double val = gain_now + 0.15L * potential_band - 0.00002L * aspect_pen;\n                    if (val > best_score) { best_score = val; best_dir = d; }\n                }\n                if (best_dir == -1 || best_score <= 1e-18) break;\n                do_expand(i, best_dir);\n                si = rect[i].area;\n                success++;\n                any = true;\n                if (success >= 2) break;\n            }\n        }\n        if (!any) break;\n        rounds++;\n    }\n\n    // Micro-shrink local improvement phase (time budget ~20% of remaining)\n    auto PI = vector<long double>(n);\n    for (int i=0;i<n;i++) PI[i] = score(rect[i].area, r[i]);\n\n    auto try_coop = [&](int a, int side)->bool{\n        // shrink a on side if it is oversized and neighbor can expand and improve total\n        if (!can_shrink(a, side)) return false;\n        if (rect[a].area <= r[a]) return false; // only shrink if oversized\n        // Try virtually shrinking\n        remove_rect(a);\n        Rect old = rect[a];\n        if (side==0) rect[a].a++;\n        else if (side==1) rect[a].c--;\n        else if (side==2) rect[a].b++;\n        else rect[a].d--;\n        rect[a].recompute_area();\n        add_rect(a);\n        long double oldPa = PI[a];\n        long double newPa = score(rect[a].area, r[a]);\n        // allow multiple neighbors near the freed band to expand once\n        // Scan small neighborhood cells and find candidates\n        int x0 = min(old.a, rect[a].a), x1 = max(old.c, rect[a].c);\n        int y0 = min(old.b, rect[a].b), y1 = max(old.d, rect[a].d);\n        int gx0 = gx_from_x(x0), gx1 = gx_from_x(max(0,x1-1));\n        int gy0 = gy_from_y(y0), gy1 = gy_from_y(max(0,y1-1));\n\n        struct Cand { int id, dir; long double gain; };\n        vector<Cand> cands;\n        auto consider_expand = [&](int b, int dir){\n            if (!can_expand(b, dir)) return;\n            long long si = rect[b].area;\n            long long ri = r[b];\n            long long inc = (dir<=1 ? rect[b].h() : rect[b].w());\n            long long newS = si + inc;\n            // do not overshoot much in coop; allow reaching ri only\n            if (si >= ri) return;\n            if (newS > ri) return;\n            long double gain = (double)(score(newS, ri) - score(si, ri));\n            if (gain > 1e-12) cands.push_back({b, dir, gain});\n        };\n\n        // Determine which side was freed and corresponding neighbor expand dir\n        int opposite_dir = -1;\n        if (side==0) opposite_dir = 0; // we moved left side right: freed column on left; neighbors left can expand right? Actually we freed to right side? To be safe allow all four for candidates around band.\n        else if (side==1) opposite_dir = 1;\n        else if (side==2) opposite_dir = 2;\n        else opposite_dir = 3;\n\n        // Collect neighbors in the vicinity\n        unordered_set<int> seen;\n        seen.reserve(64);\n        for (int gy=gy0; gy<=gy1; ++gy)\n            for (int gx=gx0; gx<=gx1; ++gx){\n                for (int b : buckets[cell_id(gx,gy)]) {\n                    if (b==a) continue;\n                    if (!seen.insert(b).second) continue;\n                    // Try all dirs; this is small\n                    for (int d=0; d<4; ++d) consider_expand(b, d);\n                }\n            }\n\n        // Pick the best single neighbor move\n        if (!cands.empty()) {\n            auto best = max_element(cands.begin(), cands.end(), [](const Cand& A, const Cand& B){ return A.gain < B.gain; });\n            long double total_gain = (newPa - oldPa) + best->gain;\n            if (total_gain > 1e-12) {\n                // Commit neighbor expansion\n                int b = best->id, d = best->dir;\n                do_expand(b, d);\n                PI[a] = newPa;\n                PI[b] = score(rect[b].area, r[b]);\n                return true;\n            }\n        }\n        // Revert shrink if not beneficial\n        remove_rect(a);\n        rect[a] = old;\n        rect[a].recompute_area();\n        add_rect(a);\n        return false;\n    };\n\n    double coop_end = TIME_LIMIT;\n    // Try a bounded number of cooperative moves\n    int coop_moves = 0, coop_attempts = 0;\n    vector<int> idx(n);\n    iota(idx.begin(), idx.end(), 0);\n    while (elapsed_sec() < coop_end && coop_attempts < 20000) {\n        shuffle(idx.begin(), idx.end(), rng);\n        bool any=false;\n        for (int i : idx) {\n            if (elapsed_sec() >= coop_end) break;\n            if (rect[i].area <= r[i]) continue;\n            // Try shrinking side that causes minimal self-harm: test sides in order of smaller dimension\n            array<pair<int,int>,4> sides = {{\n                {rect[i].w(), 0}, {rect[i].w(), 1}, {rect[i].h(), 2}, {rect[i].h(), 3}\n            }};\n            // Prefer shrinking longer side (less relative harm)\n            sort(sides.begin(), sides.end(), [&](auto &A, auto &B){ return A.first > B.first; });\n            for (auto [_, s] : sides) {\n                coop_attempts++;\n                if (try_coop(i, s)) { coop_moves++; any=true; break; }\n                if (elapsed_sec() >= coop_end) break;\n            }\n        }\n        if (!any) break;\n    }\n\n    // Output final rectangles\n    for (int i=0;i<n;i++){\n        cout << rect[i].a << ' ' << rect[i].b << ' ' << rect[i].c << ' ' << rect[i].d << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Heuristic pathfinder with degree-aware 2-step lookahead and relaxed preferred-cell handling.\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int H = 50, W = 50;\n    int si, sj;\n    if (!(cin >> si >> sj)) return 0;\n    vector<vector<int>> t(H, vector<int>(W));\n    for (int i = 0; i < H; i++) for (int j = 0; j < W; j++) cin >> t[i][j];\n    vector<vector<int>> p(H, vector<int>(W));\n    for (int i = 0; i < H; i++) for (int j = 0; j < W; j++) cin >> p[i][j];\n\n    int M = 0;\n    for (int i = 0; i < H; i++) for (int j = 0; j < W; j++) M = max(M, t[i][j] + 1);\n    vector<vector<pair<int,int>>> tiles(M);\n    tiles.reserve(M);\n    for (int i = 0; i < H; i++) for (int j = 0; j < W; j++) tiles[t[i][j]].push_back({i,j});\n\n    // Preferred endpoint per tile (max p)\n    vector<vector<char>> preferred(H, vector<char>(W, 0));\n    for (int id = 0; id < M; id++) {\n        auto &cells = tiles[id];\n        if (cells.empty()) continue;\n        int bestk = 0, bestv = -1;\n        for (int k = 0; k < (int)cells.size(); k++) {\n            auto [i, j] = cells[k];\n            if (p[i][j] > bestv) { bestv = p[i][j]; bestk = k; }\n        }\n        for (int k = 0; k < (int)cells.size(); k++) {\n            auto [i, j] = cells[k];\n            preferred[i][j] = (k == bestk);\n        }\n    }\n\n    // Serpentine index\n    vector<vector<int>> sidx(H, vector<int>(W, -1));\n    int idx = 0;\n    for (int i = 0; i < H; i++) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < W; j++) sidx[i][j] = idx++;\n        } else {\n            for (int j = W - 1; j >= 0; j--) sidx[i][j] = idx++;\n        }\n    }\n\n    auto inb = [&](int i, int j) -> bool { return 0 <= i && i < H && 0 <= j && j < W; };\n    static int di[4] = {-1,1,0,0};\n    static int dj[4] = {0,0,-1,1};\n    static char dc[4] = {'U','D','L','R'};\n\n    vector<char> visited_tile(M, 0);\n    vector<vector<char>> visited_cell(H, vector<char>(W, 0));\n\n    int ci = si, cj = sj;\n    visited_tile[t[ci][cj]] = 1;\n    visited_cell[ci][cj] = 1;\n\n    // RNG for minor tie-breaking but deterministic per input\n    uint64_t seed = 1469598103934665603ull ^ (uint64_t)(si*131 + cj*911);\n    auto rng64 = [&]() {\n        seed ^= seed << 7; seed ^= seed >> 9; seed ^= 0x9e3779b97f4a7c15ull;\n        return seed;\n    };\n\n    auto local_deg = [&](int i, int j) -> int {\n        int d = 0;\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (!inb(ni, nj)) continue;\n            if (!visited_tile[t[ni][nj]]) d++;\n        }\n        return d;\n    };\n\n    // Lookahead: given moving into (i,j), compute the max degree among its next valid moves\n    auto second_step_deg = [&](int i, int j) -> int {\n        int best = -1;\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (!inb(ni, nj)) continue;\n            int tid = t[ni][nj];\n            if (visited_tile[tid]) continue;\n            // degree if we move to (ni,nj) next\n            int d2 = 0;\n            for (int k2 = 0; k2 < 4; k2++) {\n                int xi = ni + di[k2], xj = nj + dj[k2];\n                if (!inb(xi, xj)) continue;\n                int tid2 = t[xi][xj];\n                if (tid2 == t[i][j]) continue; // would be visited after stepping into (i,j)\n                if (visited_tile[tid2]) continue;\n                d2++;\n            }\n            best = max(best, d2);\n        }\n        return best; // -1 means dead-end (no second step)\n    };\n\n    vector<char> ans;\n    ans.reserve(H*W);\n\n    // Heuristic weights tuned a bit\n    const int W_P = 90;\n    const int W_PREF = 20;\n    const int W_FLOW = 12;\n    const int W_DEG = 8;\n    const int W_LK1 = 10; // lookahead degree weight\n    const int W_SAFE = 50; // avoid dead-end bonus\n\n    for (int step = 0; step < H*W; step++) {\n        struct Cand {\n            int dir, ni, nj, tid;\n            long long score;\n            int pval, deg, flowTag, lkdeg;\n            bool pref;\n        };\n        vector<Cand> cands;\n        cands.reserve(4);\n\n        int curIdx = sidx[ci][cj];\n\n        for (int k = 0; k < 4; k++) {\n            int ni = ci + di[k], nj = cj + dj[k];\n            if (!inb(ni, nj)) continue;\n            int tid = t[ni][nj];\n            if (visited_tile[tid]) continue;\n\n            int pv = p[ni][nj];\n            int deg = local_deg(ni, nj);\n            bool pref = preferred[ni][nj];\n\n            int diff = sidx[ni][nj] - curIdx;\n            int flow = 0;\n            if (diff >= 1 && diff <= 2) flow = 3;\n            else if (diff == 3) flow = 2;\n            else if (diff == 0) flow = -3;\n            else if (diff < 0 && diff >= -2) flow = 1;\n            else flow = 0;\n\n            // Simulate lookahead deg\n            visited_tile[tid] = 1; // simulate stepping onto neighbor\n            int lkdeg = second_step_deg(ni, nj);\n            visited_tile[tid] = 0;\n\n            long long sc = 0;\n            sc += 1LL*W_P * pv;\n            sc += 1LL*W_PREF * (pref ? 1 : 0);\n            sc += 1LL*W_FLOW * flow;\n            sc += 1LL*W_DEG * deg;\n            if (lkdeg >= 0) sc += 1LL*W_LK1 * lkdeg;\n            else sc -= 1LL*W_SAFE; // discourage dead-ends\n            // Small noise to break ties\n            sc += (rng64() & 15);\n\n            cands.push_back({k, ni, nj, tid, sc, pv, deg, flow, lkdeg, pref});\n        }\n\n        if (cands.empty()) break;\n\n        // Prefer candidates that are not dead-ends when possible\n        bool hasSafe = false;\n        for (auto &c : cands) if (c.lkdeg >= 0) { hasSafe = true; break; }\n\n        // Sort by score with safety emphasis\n        sort(cands.begin(), cands.end(), [&](const Cand& a, const Cand& b){\n            auto sa = a.score + ((hasSafe && a.lkdeg < 0) ? -1000000LL : 0LL);\n            auto sb = b.score + ((hasSafe && b.lkdeg < 0) ? -1000000LL : 0LL);\n            if (sa != sb) return sa > sb;\n            if (a.pref != b.pref) return a.pref > b.pref;\n            if (a.deg != b.deg) return a.deg > b.deg;\n            if (a.pval != b.pval) return a.pval > b.pval;\n            return a.flowTag > b.flowTag;\n        });\n\n        auto best = cands[0];\n\n        // Move\n        ans.push_back(dc[best.dir]);\n        ci = best.ni; cj = best.nj;\n        visited_tile[best.tid] = 1;\n        visited_cell[ci][cj] = 1;\n    }\n\n    cout << string(ans.begin(), ans.end()) << \"\\n\";\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastIO {\n    static void flush() { cout.flush(); }\n};\n\nstruct GridRouter {\n    static constexpr int HN = 30;\n    static constexpr int WN = 30;\n    static constexpr int HHE = HN * (WN - 1); // horizontal edges count 30*29=870\n    static constexpr int HVE = (HN - 1) * WN; // vertical edges count 29*30=870\n    static constexpr int E = HHE + HVE;       // 1740\n\n    // map edge ids\n    static int idH(int i, int j) { return i * (WN - 1) + j; }\n    static int idV(int i, int j) { return HHE + i * WN + j; }\n    static bool inb(int i, int j) { return 0 <= i && i < HN && 0 <= j && j < WN; }\n\n    vector<double> w; // edge weights\n    vector<pair<int,int>> adjIdx[HN][WN]; // (neighbor node index, edge id)\n    mt19937 rng;\n\n    GridRouter() : w(E, 5000.0) {\n        rng.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());\n        buildGraph();\n    }\n\n    int nodeId(int i, int j) const { return i * WN + j; }\n    pair<int,int> nodePos(int id) const { return {id / WN, id % WN}; }\n\n    void buildGraph() {\n        for (int i = 0; i < HN; ++i) for (int j = 0; j < WN; ++j) adjIdx[i][j].clear();\n        for (int i = 0; i < HN; ++i) {\n            for (int j = 0; j < WN - 1; ++j) {\n                int e = idH(i,j);\n                int u = nodeId(i,j), v = nodeId(i,j+1);\n                adjIdx[i][j].push_back({v, e});\n                adjIdx[i][j+1].push_back({u, e});\n            }\n        }\n        for (int i = 0; i < HN - 1; ++i) {\n            for (int j = 0; j < WN; ++j) {\n                int e = idV(i,j);\n                int u = nodeId(i,j), v = nodeId(i+1,j);\n                adjIdx[i][j].push_back({v, e});\n                adjIdx[i+1][j].push_back({u, e});\n            }\n        }\n    }\n\n    struct DRes {\n        vector<int> prevNode;\n        vector<int> prevEdge;\n        vector<int> pathEdges;\n        string pathMoves;\n        double pathCost;\n    };\n\n    // Dijkstra with optional per-query randomization factor on edges to encourage exploration\n    DRes shortestPath(pair<int,int> s, pair<int,int> t, double randEps, uint64_t randSeed) {\n        int N = HN * WN;\n        vector<double> dist(N, numeric_limits<double>::infinity());\n        vector<int> prevN(N, -1), prevE(N, -1);\n        int sId = nodeId(s.first, s.second);\n        int tId = nodeId(t.first, t.second);\n\n        // prepare random multipliers if needed\n        vector<float> mult;\n        if (randEps > 0) {\n            mult.assign(E, 1.0f);\n            // Use a simple hash PRNG based on seed for determinism per query\n            uint64_t x = randSeed ? randSeed : rng();\n            auto nextRand = [&]() {\n                x ^= x << 13; x ^= x >> 7; x ^= x << 17;\n                return x;\n            };\n            for (int e = 0; e < E; ++e) {\n                // uniform in [-1,1]\n                uint64_t r = nextRand();\n                double u = ((r >> 11) & 0xFFFFFFFFull) / double(0xFFFFFFFFull);\n                double z = 2.0*u - 1.0;\n                mult[e] = float(1.0 + randEps * z);\n            }\n        }\n\n        using P = pair<double,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[sId] = 0.0;\n        pq.emplace(0.0, sId);\n\n        while (!pq.empty()) {\n            auto [d,u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == tId) break;\n            auto [ui, uj] = nodePos(u);\n            for (auto [v, e] : adjIdx[ui][uj]) {\n                double ew = w[e];\n                if (!mult.empty()) ew *= mult[e];\n                // safety clamp\n                if (ew < 100.0) ew = 100.0;\n                if (ew > 20000.0) ew = 20000.0;\n                double nd = d + ew;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prevN[v] = u;\n                    prevE[v] = e;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n\n        DRes res;\n        res.prevNode = move(prevN);\n        res.prevEdge = move(prevE);\n        res.pathCost = dist[tId];\n\n        // reconstruct path edges and moves\n        vector<int> edges;\n        string moves;\n        int cur = tId;\n        while (cur != sId && res.prevEdge[cur] != -1) {\n            int e = res.prevEdge[cur];\n            edges.push_back(e);\n            auto [pi, pj] = nodePos(res.prevNode[cur]);\n            auto [ci, cj] = nodePos(cur);\n            if (ci == pi) {\n                // horizontal\n                if (cj == pj + 1) moves.push_back('R');\n                else moves.push_back('L');\n            } else {\n                // vertical\n                if (ci == pi + 1) moves.push_back('D');\n                else moves.push_back('U');\n            }\n            cur = res.prevNode[cur];\n        }\n        reverse(edges.begin(), edges.end());\n        reverse(moves.begin(), moves.end());\n        res.pathEdges = move(edges);\n        res.pathMoves = move(moves);\n        return res;\n    }\n\n    void updateWeights(const vector<int>& pathEdges, long long observed, int qIndex) {\n        if (pathEdges.empty()) return;\n        double pred = 0.0;\n        for (int e : pathEdges) pred += w[e];\n        if (pred <= 1e-6) return;\n\n        double y = (double)observed;\n        // Compute scaling, clipped\n        double s = y / pred;\n        s = max(0.9, min(1.1, s));\n\n        // Learning rate schedule: start higher, decay\n        double eta0 = 0.35;\n        double eta1 = 0.05;\n        double progress = (double)qIndex / 999.0;\n        double eta = eta0 * (1.0 - progress) + eta1 * progress;\n\n        // Update multiplicatively on used edges\n        double factor = 1.0 + eta * (s - 1.0);\n        // Clamp factor slightly to be safe\n        factor = max(0.95, min(1.05, factor));\n\n        for (int e : pathEdges) {\n            w[e] *= factor;\n        }\n\n        // Mild smoothing to neighbors of same row/col to reduce variance\n        double beta = 0.02;\n        // Horizontal neighbors: for each horizontal edge used, nudge adjacent horizontal edges in same row\n        for (int e : pathEdges) {\n            if (e < HHE) {\n                int i = e / (WN - 1);\n                int j = e % (WN - 1);\n                // left neighbor\n                if (j - 1 >= 0) {\n                    int ne = idH(i, j - 1);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n                // right neighbor\n                if (j + 1 < WN - 1) {\n                    int ne = idH(i, j + 1);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n            } else {\n                int ve = e - HHE;\n                int i = ve / WN;\n                int j = ve % WN;\n                // up neighbor\n                if (i - 1 >= 0) {\n                    int ne = idV(i - 1, j);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n                // down neighbor\n                if (i + 1 < HN - 1) {\n                    int ne = idV(i + 1, j);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n            }\n        }\n\n        // Global clipping\n        for (int e : pathEdges) {\n            if (w[e] < 500.0) w[e] = 500.0;\n            if (w[e] > 15000.0) w[e] = 15000.0;\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    GridRouter gr;\n\n    long long prev_result = 0; // not used for first query but we will read after output\n\n    for (int q = 0; q < 1000; ++q) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) {\n            return 0;\n        }\n\n        // Exploration epsilon schedule: decay over first 200 queries\n        double eps_start = 0.05;\n        double eps = 0.0;\n        if (q < 200) {\n            double t = (double)q / 200.0;\n            eps = eps_start * (1.0 - t);\n        }\n\n        uint64_t seed = ((uint64_t)si<<48) ^ ((uint64_t)sj<<32) ^ ((uint64_t)ti<<16) ^ (uint64_t)tj ^ (uint64_t)q*1469598103934665603ull;\n\n        auto res = gr.shortestPath({si,sj},{ti,tj}, eps, seed);\n\n        // Fallback: if something went wrong (no path), output a simple Manhattan path\n        string path = res.pathMoves;\n        if ((int)path.size() == 0) {\n            // Construct naive Manhattan path\n            int di = ti - si;\n            int dj = tj - sj;\n            string tmp;\n            if (di > 0) tmp.append(di, 'D'); else tmp.append(-di, 'U');\n            if (dj > 0) tmp.append(dj, 'R'); else tmp.append(-dj, 'L');\n            path = tmp;\n            // Note: our graph ensures connectivity; this fallback is just for safety\n        }\n\n        cout << path << \"\\n\";\n        FastIO::flush();\n\n        long long observed;\n        if (!(cin >> observed)) {\n            return 0;\n        }\n\n        // Update weights with observation\n        gr.updateWeights(res.pathEdges, observed, q);\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic inline int ch2i(char c){ return c - 'A'; }\nstatic inline char i2ch(int x){ return char('A' + x); }\n\nstruct Placement {\n    uint8_t dir; // 0=hor,1=ver\n    uint8_t fixed; // row for hor, col for ver\n    uint8_t start; // start index\n};\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    vector<string> s(M);\n    for(int i=0;i<M;i++) cin >> s[i];\n\n    // Encode strings\n    vector<vector<uint8_t>> enc(M);\n    int maxLen=0;\n    array<int,8> globalCnt{}; globalCnt.fill(0);\n    for(int i=0;i<M;i++){\n        enc[i].resize(s[i].size());\n        for(size_t k=0;k<s[i].size();k++){\n            enc[i][k] = (uint8_t)ch2i(s[i][k]);\n            globalCnt[enc[i][k]]++;\n        }\n        maxLen = max<int>(maxLen, s[i].size());\n    }\n    int fillChar = int(max_element(globalCnt.begin(), globalCnt.end()) - globalCnt.begin());\n\n    // Precompute all placements per string (we can keep all: 2*N*N)\n    vector<vector<Placement>> placements(M);\n    placements.reserve(M);\n    for(int i=0;i<M;i++){\n        vector<Placement> ps;\n        ps.reserve(2*N*N);\n        int k = (int)enc[i].size();\n        // Horizontal\n        for(int r=0;r<N;r++){\n            for(int c0=0;c0<N;c0++){\n                ps.push_back(Placement{0,(uint8_t)r,(uint8_t)c0});\n            }\n        }\n        // Vertical\n        for(int c=0;c<N;c++){\n            for(int r0=0;r0<N;r0++){\n                ps.push_back(Placement{1,(uint8_t)c,(uint8_t)r0});\n            }\n        }\n        placements[i] = move(ps);\n    }\n\n    // Grid: -1 unknown, 0..7\n    const int UNKNOWN = -1;\n    vector<int8_t> grid(N*N, UNKNOWN);\n\n    auto checkGain = [&](int si, const Placement& pl)->int{\n        const auto& e = enc[si];\n        int k = (int)e.size();\n        int gain = 0;\n        if(pl.dir==0){\n            int r = pl.fixed;\n            int c0 = pl.start;\n            int base = r*N;\n            for(int p=0;p<k;p++){\n                int c = (c0 + p) % N;\n                int idx = base + c;\n                int8_t v = grid[idx];\n                if(v==UNKNOWN) gain++;\n                else if(v != (int)e[p]) return -1;\n            }\n        }else{\n            int c = pl.fixed;\n            int r0 = pl.start;\n            for(int p=0;p<k;p++){\n                int r = (r0 + p) % N;\n                int idx = r*N + c;\n                int8_t v = grid[idx];\n                if(v==UNKNOWN) gain++;\n                else if(v != (int)e[p]) return -1;\n            }\n        }\n        return gain;\n    };\n\n    auto applyPlacement = [&](int si, const Placement& pl){\n        const auto& e = enc[si];\n        int k = (int)e.size();\n        if(pl.dir==0){\n            int r = pl.fixed;\n            int c0 = pl.start;\n            int base = r*N;\n            for(int p=0;p<k;p++){\n                int c = (c0 + p) % N;\n                int idx = base + c;\n                grid[idx] = (int8_t)e[p];\n            }\n        }else{\n            int c = pl.fixed;\n            int r0 = pl.start;\n            for(int p=0;p<k;p++){\n                int r = (r0 + p) % N;\n                int idx = r*N + c;\n                grid[idx] = (int8_t)e[p];\n            }\n        }\n    };\n\n    // Flags\n    vector<char> satisfied(M, 0);\n\n    // Greedy loop: repeatedly apply the single best positive-gain placement\n    // until no positive-gain placement exists or time budget reached.\n    // To limit time, cap total iterations.\n    const int maxGlobalIters = 20000; // generous but safe\n    int applied = 0;\n    for(int iter=0; iter<maxGlobalIters; iter++){\n        int bestGain = 0;\n        int bestSi = -1;\n        Placement bestPl{};\n        // Track zero-gain satisfied strings in this pass\n        int newlySatisfiedZero = 0;\n\n        for(int i=0;i<M;i++){\n            if(satisfied[i]) continue;\n            int bestGain_i = -1;\n            Placement bestPl_i{};\n            bool hasZeroSat = false;\n            for(const auto& pl: placements[i]){\n                int g = checkGain(i, pl);\n                if(g < 0) continue;\n                if(g == 0){\n                    hasZeroSat = true;\n                    // we can stop early; but keep scanning for positive gain in case available\n                }\n                if(g > bestGain_i){\n                    bestGain_i = g;\n                    bestPl_i = pl;\n                    if(g == (int)enc[i].size()){\n                        // perfect fresh placement, good enough\n                        // keep but continue; we still might find equal\n                    }\n                }\n            }\n            if(bestGain_i >= 0){\n                if(bestGain_i == 0 && hasZeroSat){\n                    satisfied[i] = 1;\n                    newlySatisfiedZero++;\n                }else if(bestGain_i > bestGain){\n                    bestGain = bestGain_i;\n                    bestSi = i;\n                    bestPl = bestPl_i;\n                }\n            }\n        }\n\n        if(bestSi == -1){\n            // No positive-gain moves left; we only possibly marked zero-gain strings.\n            break;\n        }\n        applyPlacement(bestSi, bestPl);\n        satisfied[bestSi] = 1;\n        applied++;\n    }\n\n    // Final pass: mark any remaining satisfied by zero-gain\n    for(int i=0;i<M;i++){\n        if(satisfied[i]) continue;\n        bool ok = false;\n        for(const auto& pl: placements[i]){\n            int g = checkGain(i, pl);\n            if(g == 0){ ok = true; break; }\n        }\n        if(ok) satisfied[i] = 1;\n    }\n\n    // Fill remaining unknowns with globally frequent character\n    for(int idx=0; idx<N*N; idx++){\n        if(grid[idx] == UNKNOWN) grid[idx] = (int8_t)fillChar;\n    }\n\n    // Output\n    for(int r=0;r<N;r++){\n        string line;\n        line.resize(N);\n        for(int c=0;c<N;c++){\n            line[c] = i2ch(grid[r*N + c]);\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() { st = chrono::steady_clock::now(); }\n    double elapsed() const {\n        using namespace chrono;\n        return duration<double>(steady_clock::now() - st).count();\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    auto inb = [&](int i, int j){ return 0<=i && i<N && 0<=j && j<N; };\n    auto isRoad = [&](int i, int j){ return inb(i,j) && g[i][j] != '#'; };\n\n    // Compress road cells\n    int R = 0;\n    vector<int> id(N*N, -1);\n    vector<pair<int,int>> pos; pos.reserve(N*N);\n    for (int i=0;i<N;++i) for (int j=0;j<N;++j) if (isRoad(i,j)) {\n        id[i*N+j] = R++;\n        pos.emplace_back(i,j);\n    }\n    int startId = id[si*N+sj];\n    if (startId < 0) { cout << \"\\n\"; return 0; }\n\n    // Neighbors and weights\n    vector<array<int,4>> neigh(R);\n    vector<array<int,4>> moveCost(R);\n    for (int r=0;r<R;++r){\n        auto [i,j] = pos[r];\n        int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};\n        for (int d=0; d<4; ++d) {\n            int ni=i+dirs[d][0], nj=j+dirs[d][1];\n            if (isRoad(ni,nj)) {\n                int nid = id[ni*N+nj];\n                neigh[r][d] = nid;\n                moveCost[r][d] = g[ni][nj]-'0';\n            } else {\n                neigh[r][d] = -1;\n                moveCost[r][d] = 0;\n            }\n        }\n    }\n\n    // Bitset settings\n    int W = (R + 63) >> 6;\n    using BVec = vector<uint64_t>;\n    auto or_into = [&](BVec& a, const BVec& b){ for (int k=0;k<W;++k) a[k] |= b[k]; };\n    auto and_into = [&](BVec& a, const BVec& b){ for (int k=0;k<W;++k) a[k] &= b[k]; };\n    auto popcount_bits = [&](const BVec& a)->int{\n        int s=0; for (int k=0;k<W;++k) s += (int)__builtin_popcountll(a[k]); return s;\n    };\n    auto marginal_gain = [&](const BVec& visBits, const BVec& rem)->int{\n        int s=0; for (int k=0;k<W;++k) s += (int)__builtin_popcountll(visBits[k] & rem[k]); return s;\n    };\n\n    // Precompute visibility bitsets per cell\n    vector<BVec> vis(R, BVec(W, 0));\n    // Row runs\n    for (int i=0;i<N;++i) {\n        int j=0;\n        while (j<N) {\n            while (j<N && !isRoad(i,j)) ++j;\n            if (j>=N) break;\n            int k=j;\n            vector<int> run;\n            while (k<N && isRoad(i,k)) { run.push_back(id[i*N+k]); ++k; }\n            // set run bits\n            for (int idx : run) {\n                auto &b = vis[idx];\n                for (int rid : run) b[rid>>6] |= (1ULL << (rid&63));\n            }\n            j = k;\n        }\n    }\n    // Column runs\n    for (int j=0;j<N;++j) {\n        int i=0;\n        while (i<N) {\n            while (i<N && !isRoad(i,j)) ++i;\n            if (i>=N) break;\n            int k=i;\n            vector<int> run;\n            while (k<N && isRoad(k,j)) { run.push_back(id[k*N+j]); ++k; }\n            // set run bits\n            for (int idx : run) {\n                auto &b = vis[idx];\n                for (int rid : run) b[rid>>6] |= (1ULL << (rid&63));\n            }\n            i = k;\n        }\n    }\n\n    // Identify POIs: degree != 2 (junctions and endpoints) + start\n    vector<int> deg(R,0);\n    for (int r=0;r<R;++r){\n        for (int d=0; d<4; ++d) if (neigh[r][d] >= 0) deg[r]++;\n    }\n    vector<int> poi;\n    poi.reserve(R);\n    for (int r=0;r<R;++r) if (deg[r] != 2) poi.push_back(r);\n    if (find(poi.begin(), poi.end(), startId) == poi.end()) poi.push_back(startId);\n\n    // Also add representative cells for long straight runs to ensure coverage options\n    // We add midpoints of runs longer than Lmin\n    const int Lmin = 5;\n    // Rows\n    for (int i=0;i<N;++i) {\n        int j=0;\n        while (j<N) {\n            while (j<N && !isRoad(i,j)) ++j;\n            if (j>=N) break;\n            int k=j;\n            vector<int> run;\n            while (k<N && isRoad(i,k)) { run.push_back(id[i*N+k]); ++k; }\n            if ((int)run.size() >= Lmin) {\n                int mid = run[run.size()/2];\n                poi.push_back(mid);\n            }\n            j = k;\n        }\n    }\n    // Columns\n    for (int j=0;j<N;++j) {\n        int i=0;\n        while (i<N) {\n            while (i<N && !isRoad(i,j)) ++i;\n            if (i>=N) break;\n            int k=i;\n            vector<int> run;\n            while (k<N && isRoad(k,j)) { run.push_back(id[k*N+j]); ++k; }\n            if ((int)run.size() >= Lmin) {\n                int mid = run[run.size()/2];\n                poi.push_back(mid);\n            }\n            i = k;\n        }\n    }\n    // Deduplicate POIs\n    sort(poi.begin(), poi.end());\n    poi.erase(unique(poi.begin(), poi.end()), poi.end());\n\n    // Dijkstra utils\n    const int INF = 1e9;\n    vector<int> dist(R), prevId(R, -1);\n    auto dijkstra = [&](int src, vector<int>& distOut, vector<int>* prevOut){\n        fill(distOut.begin(), distOut.end(), INF);\n        if (prevOut) { fill(prevOut->begin(), prevOut->end(), -1); }\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        distOut[src] = 0;\n        pq.emplace(0, src);\n        while (!pq.empty()) {\n            auto [cd, u] = pq.top(); pq.pop();\n            if (cd != distOut[u]) continue;\n            for (int d=0; d<4; ++d) {\n                int v = neigh[u][d];\n                if (v < 0) continue;\n                int w = moveCost[u][d];\n                int nd = cd + w;\n                if (nd < distOut[v]) {\n                    distOut[v] = nd;\n                    if (prevOut) (*prevOut)[v] = u;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n    };\n    auto reconstruct_moves = [&](int curId, int tgtId, const vector<int>& prev)->string{\n        string s;\n        if (curId == tgtId) return s;\n        vector<int> seq;\n        int x = tgtId;\n        while (x != -1 && x != curId) { seq.push_back(x); x = prev[x]; }\n        if (x != curId) return s;\n        reverse(seq.begin(), seq.end());\n        for (int v: seq) {\n            int u = prev[v];\n            auto [ui,uj] = pos[u];\n            auto [vi,vj] = pos[v];\n            if (vi==ui-1 && vj==uj) s.push_back('U');\n            else if (vi==ui+1 && vj==uj) s.push_back('D');\n            else if (vi==ui && vj==uj-1) s.push_back('L');\n            else if (vi==ui && vj==uj+1) s.push_back('R');\n        }\n        return s;\n    };\n\n    // Precompute dist_to_start once\n    vector<int> dist_to_start(R);\n    dijkstra(startId, dist_to_start, nullptr);\n\n    // Coverage tracking\n    BVec covered(W, 0);\n    BVec remaining(W, 0);\n    // Set remaining = all road cells initially\n    for (int r=0;r<R;++r) remaining[r>>6] |= (1ULL << (r&63));\n    auto see_from = [&](int node){\n        // covered |= vis[node]; remaining &= ~vis[node]\n        for (int k=0;k<W;++k) {\n            uint64_t bits = vis[node][k];\n            covered[k] |= bits;\n            remaining[k] &= ~bits;\n        }\n    };\n    see_from(startId);\n    int remCount = popcount_bits(remaining);\n\n    string answer;\n    Timer timer;\n    double timeLimit = 2.85;\n\n    int cur = startId;\n\n    int iterations = 0;\n    while (remCount > 0) {\n        if (timer.elapsed() > timeLimit) break;\n\n        // Dijkstra from current\n        dijkstra(cur, dist, &prevId);\n\n        // dynamic parameters\n        double ratio = 1.0 - (double)remCount / (double)R;\n        double beta = (ratio < 0.8 ? 1.05 : 1.25); // favor bigger gains more when late\n        double lambda = (ratio < 0.7 ? 0.02 : 0.0); // include slight pull to start in the late phase\n        if (ratio > 0.9) lambda = 0.05;\n\n        // Select best target among POIs first; if none yields gain, fall back to all nodes\n        int bestT = -1;\n        double bestScore = 1e100;\n        int bestGain = 0;\n\n        auto consider_candidates = [&](const vector<int>& candList){\n            int localBestT = bestT;\n            double localBestScore = bestScore;\n            int localBestGain = bestGain;\n            for (int t : candList) {\n                int d0 = dist[t];\n                if (d0 >= INF) continue;\n                int gain = marginal_gain(vis[t], remaining);\n                if (gain <= 0) continue;\n                double eff = (double)d0 + lambda * (double)dist_to_start[t];\n                double sc = eff / pow((double)gain, beta);\n                if (sc < localBestScore - 1e-12 || (abs(sc - localBestScore) <= 1e-12 && gain > localBestGain)) {\n                    localBestScore = sc;\n                    localBestT = t;\n                    localBestGain = gain;\n                }\n            }\n            bestT = localBestT;\n            bestScore = localBestScore;\n            bestGain = localBestGain;\n        };\n\n        consider_candidates(poi);\n\n        if (bestT == -1) {\n            // fallback: consider all nodes, but stop early if time tight\n            vector<int> all(R);\n            iota(all.begin(), all.end(), 0);\n            consider_candidates(all);\n        }\n\n        // Late-stage finishing: if remaining small, choose nearest with any gain (minimize eff cost)\n        if (bestT == -1 || remCount <= 64) {\n            int bestT2 = -1;\n            int bestEff = INF;\n            int bestG2 = 0;\n            for (int t = 0; t < R; ++t) {\n                int d0 = dist[t];\n                if (d0 >= INF) continue;\n                int gain = marginal_gain(vis[t], remaining);\n                if (gain <= 0) continue;\n                int eff = d0 + (int)(lambda * dist_to_start[t]);\n                if (eff < bestEff || (eff == bestEff && gain > bestG2)) {\n                    bestEff = eff; bestT2 = t; bestG2 = gain;\n                }\n            }\n            if (bestT2 != -1) {\n                bestT = bestT2;\n            }\n        }\n\n        if (bestT == -1) {\n            // No reachable gain (shouldn't happen), break\n            break;\n        }\n\n        // Reconstruct and move\n        string mv = reconstruct_moves(cur, bestT, prevId);\n        answer += mv;\n        cur = bestT;\n        // Update coverage\n        see_from(cur);\n        remCount = popcount_bits(remaining);\n\n        ++iterations;\n\n        if (timer.elapsed() > timeLimit) break;\n    }\n\n    // Return to start\n    if (cur != startId) {\n        dijkstra(cur, dist, &prevId);\n        string mv = reconstruct_moves(cur, startId, prevId);\n        answer += mv;\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct RNG {\n    uint64_t x=88172645463393265ull;\n    uint32_t next() { x ^= x<<7; x ^= x>>9; return uint32_t(x); }\n    double drand() { return (next()>>8) * (1.0/16777216.0); }\n} rng;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,K,R;\n    if(!(cin>>N>>M>>K>>R)) return 0;\n    vector<vector<int>> d(N, vector<int>(K));\n    for(int i=0;i<N;i++) for(int k=0;k<K;k++) cin>>d[i][k];\n    vector<vector<int>> g(N);\n    vector<int> indeg(N,0);\n    for(int i=0;i<R;i++){\n        int u,v; cin>>u>>v; --u;--v;\n        g[u].push_back(v);\n        indeg[v]++;\n    }\n    // compute \"height\" (distance to sink) via reverse DP: longest path length estimate\n    vector<int> topo;\n    {\n        vector<int> indeg2 = indeg;\n        queue<int> q;\n        for(int i=0;i<N;i++) if(indeg2[i]==0) q.push(i);\n        while(!q.empty()){\n            int u=q.front(); q.pop();\n            topo.push_back(u);\n            for(int v: g[u]){\n                if(--indeg2[v]==0) q.push(v);\n            }\n        }\n        if((int)topo.size()!=N){\n            // Shouldn't happen but guard\n            topo.clear();\n            for(int i=0;i<N;i++) topo.push_back(i);\n        }\n    }\n    vector<vector<int>> rg(N);\n    for(int u=0;u<N;u++) for(int v: g[u]) rg[v].push_back(u);\n    vector<int> height(N,0);\n    // reverse topo to compute longest path to end (in terms of edges)\n    for(int idx=N-1; idx>=0; --idx){\n        int u = topo[idx];\n        int best=0;\n        for(int v: g[u]) best = max(best, 1 + height[v]);\n        height[u]=best;\n    }\n    // Also compute number of descendants approximate via DP (could be heavy to exact), skip.\n\n    // Estimations\n    vector<vector<double>> est(M, vector<double>(K, 10.0));\n    vector<vector<int>> lb(M, vector<int>(K, 0));\n\n    // Task status: 0 not started, 1 started, 2 done\n    vector<int> tstat(N,0);\n    vector<int> started_by(N, -1);\n    vector<int> start_day(N, -1);\n\n    // Member status: -1 idle, else task index\n    vector<int> mtask(M, -1);\n\n    // Current indegree mutable\n    vector<int> cur_indeg = indeg;\n    vector<char> in_ready(N, 0);\n    deque<int> ready;\n    // initialize ready tasks (no deps)\n    for(int i=0;i<N;i++) if(cur_indeg[i]==0){ ready.push_back(i); in_ready[i]=1; }\n\n    auto predicted_time = [&](int task, int mem)->double{\n        double w=0.0;\n        for(int k=0;k<K;k++){\n            double def = (double)d[task][k] - est[mem][k];\n            if(def>0) w += def;\n        }\n        // r mean ~0, but add small bias\n        if(w<1.0) return 1.0;\n        return max(1.0, w);\n    };\n\n    auto assign_task = [&](int mem, int task, int day){\n        mtask[mem]=task;\n        tstat[task]=1;\n        started_by[task]=mem;\n        start_day[task]=day;\n        // remove from ready if present\n        if(in_ready[task]){\n            in_ready[task]=0;\n            // we won't remove efficiently from deque; will skip when popping\n        }\n    };\n\n    int day=0;\n    const double alpha = 1.0;\n    const double beta = 0.3;\n    const double eps = 0.05;\n\n    while(true){\n        day++;\n        // Build list of idle members\n        vector<int> idle;\n        for(int j=0;j<M;j++) if(mtask[j]==-1) idle.push_back(j);\n\n        // Prepare candidates list of ready tasks (clean deque)\n        vector<int> rlist;\n        // Rebuild rlist from flags to avoid stale entries\n        rlist.reserve(ready.size());\n        for(int i=0;i<N;i++){\n            if(in_ready[i] && tstat[i]==0) rlist.push_back(i);\n        }\n\n        // Greedy assignment\n        vector<pair<int,int>> out; out.reserve(idle.size());\n        // To limit cost, consider up to topL by height\n        int topL = 300; // cap candidates\n        if((int)rlist.size()>topL){\n            // pick top by height\n            nth_element(rlist.begin(), rlist.begin()+topL, rlist.end(), [&](int a,int b){\n                return height[a] > height[b];\n            });\n            rlist.resize(topL);\n        }\n        // Keep a set to avoid assigning same task twice\n        vector<char> taken(N, 0);\n        for(int mem: idle){\n            int bestTask = -1;\n            double bestScore = 1e100;\n            // exploration?\n            bool doExplore = (rng.drand() < eps);\n            if(doExplore){\n                // pick task with largest uncertainty: sum(est-lb gaps near d)\n                double bestU = -1.0;\n                for(int t: rlist){\n                    if(taken[t]) continue;\n                    double unc=0.0;\n                    for(int k=0;k<K;k++){\n                        if(d[t][k]>lb[mem][k]){\n                            double gap = max(0.0, est[mem][k] - (double)lb[mem][k]);\n                            // uncertainty where d is near est\n                            double closeness = max(0.0, est[mem][k] - d[t][k]);\n                            unc += gap - 0.5*closeness;\n                        }\n                    }\n                    unc += 0.1*height[t];\n                    if(unc>bestU){\n                        bestU=unc; bestTask=t;\n                    }\n                }\n            } else {\n                for(int t: rlist){\n                    if(taken[t]) continue;\n                    double tp = predicted_time(t, mem);\n                    double score = alpha*tp - beta*height[t];\n                    if(score < bestScore){\n                        bestScore=score; bestTask=t;\n                    }\n                }\n            }\n            if(bestTask!=-1){\n                taken[bestTask]=1;\n                out.emplace_back(mem, bestTask);\n            }\n        }\n\n        // Output\n        cout<<out.size();\n        for(auto &p: out){\n            int mem = p.first;\n            int task = p.second;\n            cout<<\" \"<<(mem+1)<<\" \"<<(task+1);\n            assign_task(mem, task, day);\n        }\n        cout<<\"\\n\";\n        cout.flush();\n\n        // Read feedback\n        int nfin;\n        if(!(cin>>nfin)) return 0;\n        if(nfin==-1) return 0;\n        vector<int> fins(nfin);\n        for(int i=0;i<nfin;i++){ cin>>fins[i]; fins[i]--; }\n\n        // Process finishes: mark tasks done, update estimates, update ready\n        for(int mem: fins){\n            int task = mtask[mem];\n            if(task<0) continue; // safety\n            int dur = day - start_day[task] + 1;\n            // Update estimates\n            if(dur<=1){\n                // strict implication w=0 -> s >= d\n                for(int k=0;k<K;k++){\n                    lb[mem][k] = max(lb[mem][k], d[task][k]);\n                    est[mem][k] = max(est[mem][k], (double)d[task][k]);\n                }\n            } else {\n                // For t>1, adjust est upwards to reduce predicted deficit towards T\n                // Compute current deficit\n                vector<double> def(K,0.0);\n                double W=0.0;\n                for(int k=0;k<K;k++){\n                    double df = (double)d[task][k] - est[mem][k];\n                    if(df>0){ def[k]=df; W+=df; }\n                }\n                // Target T ~ dur, clamp\n                double T = (double)dur;\n                if(W > T){\n                    // reduce W by increasing on positive def dims\n                    double sumdef = W;\n                    if(sumdef>1e-9){\n                        double delta = min(W - T, 3.0); // cautious step\n                        for(int k=0;k<K;k++){\n                            if(def[k]>0){\n                                double inc = delta * (def[k]/sumdef);\n                                est[mem][k] += inc;\n                                est[mem][k] = max(est[mem][k], (double)lb[mem][k]);\n                            } else {\n                                est[mem][k] = max(est[mem][k], (double)lb[mem][k]);\n                            }\n                        }\n                    }\n                } else {\n                    // W <= T, maybe we overestimate somewhere; lightly pull down non-lb dims\n                    double delta = min(T - W, 1.0);\n                    for(int k=0;k<K;k++){\n                        if(est[mem][k] > lb[mem][k]){\n                            est[mem][k] = max((double)lb[mem][k], est[mem][k] - delta*0.05);\n                        }\n                    }\n                }\n            }\n            // free member and mark task done\n            mtask[mem] = -1;\n            tstat[task]=2;\n            // unlock successors\n            for(int v: g[task]){\n                cur_indeg[v]--;\n                if(cur_indeg[v]==0 && tstat[v]==0){\n                    in_ready[v]=1;\n                }\n            }\n        }\n\n        // Compact ready deque representation not necessary; we rebuild rlist each day from flags.\n        // Loop continues\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int ax, ay, cx, cy, idx;\n    double score;\n};\n\nstatic inline int manh(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int DEPX=400, DEPY=400;\n    vector<Order> all;\n    all.reserve(1000);\n    for(int i=0;i<1000;i++){\n        int a,b,c,d;\n        if(!(cin>>a>>b>>c>>d)) return 0;\n        Order o; o.ax=a;o.ay=b;o.cx=c;o.cy=d;o.idx=i+1;o.score=0;\n        all.push_back(o);\n    }\n    if(all.size()!=1000){\n        // In case of partial input, just output trivial solution\n        cout<<\"0\\n1 400 400\\n\";\n        return 0;\n    }\n\n    // Compute scores for selection\n    const double alpha=1.0, beta=1.0, gamma=0.7; // weights for depot->pickup, pickup->drop, drop->depot\n    const double angle_penalty = 5.0; // mild penalty on pickup-drop direction difference\n    for(auto &o: all){\n        int da = manh(DEPX,DEPY,o.ax,o.ay);\n        int ac = manh(o.ax,o.ay,o.cx,o.cy);\n        int cd = manh(o.cx,o.cy,DEPX,DEPY);\n        double angp = atan2((double)o.ay - DEPY, (double)o.ax - DEPX);\n        double angd = atan2((double)o.cy - DEPY, (double)o.cx - DEPX);\n        double dang = fabs(angp - angd);\n        while(dang > M_PI) dang = fabs(dang - 2*M_PI);\n        o.score = alpha*da + beta*ac + gamma*cd + angle_penalty * dang;\n    }\n    sort(all.begin(), all.end(), [](const Order& A, const Order& B){\n        if (A.score != B.score) return A.score < B.score;\n        return A.idx < B.idx;\n    });\n    int m = 50;\n    vector<Order> sel(all.begin(), all.begin()+m);\n\n    // Greedy route construction with precedence\n    struct Node { int x,y; int ordIdx; bool isPickup; };\n    unordered_map<int, Order> omap;\n    omap.reserve(m*2);\n    for (auto &o: sel) omap[o.idx]=o;\n\n    vector<int> unpicked, carrying;\n    unpicked.reserve(m);\n    for (auto &o: sel) unpicked.push_back(o.idx);\n    vector<Node> route;\n    route.push_back({DEPX,DEPY,-1,false}); // start\n\n    int curx=DEPX, cury=DEPY;\n    auto getPick = [&](int id)->pair<int,int>{\n        auto &o = omap[id]; return {o.ax,o.ay};\n    };\n    auto getDrop = [&](int id)->pair<int,int>{\n        auto &o = omap[id]; return {o.cx,o.cy};\n    };\n\n    for(int step=0; step<2*m; ++step){\n        // find best pickup\n        int bestPid=-1; int bestPdist=INT_MAX; int px=0,py=0;\n        for(int id: unpicked){\n            auto p = getPick(id);\n            int d = manh(curx,cury,p.first,p.second);\n            if(d < bestPdist){\n                bestPdist = d; bestPid=id; px=p.first; py=p.second;\n            }\n        }\n        // find best drop\n        int bestDid=-1; int bestDdist=INT_MAX; int dx=0,dy=0;\n        for(int id: carrying){\n            auto p = getDrop(id);\n            int d = manh(curx,cury,p.first,p.second);\n            if(d < bestDdist){\n                bestDdist = d; bestDid=id; dx=p.first; dy=p.second;\n            }\n        }\n        // choose\n        bool doPickup = false;\n        if(bestPid==-1 && bestDid!=-1) doPickup=false;\n        else if(bestPid!=-1 && bestDid==-1) doPickup=true;\n        else {\n            // bias against picking when carrying many\n            double bias = 1.05 + 0.02 * (int)carrying.size();\n            doPickup = (bestPdist * bias <= bestDdist + 1e-9);\n        }\n        if(doPickup){\n            // move to pickup\n            route.push_back({px,py,bestPid,true});\n            curx=px; cury=py;\n            auto it = find(unpicked.begin(), unpicked.end(), bestPid);\n            if(it!=unpicked.end()) unpicked.erase(it);\n            carrying.push_back(bestPid);\n        }else{\n            // move to drop\n            route.push_back({dx,dy,bestDid,false});\n            curx=dx; cury=dy;\n            auto it = find(carrying.begin(), carrying.end(), bestDid);\n            if(it!=carrying.end()) carrying.erase(it);\n        }\n    }\n\n    // If any remain (safety), finish remaining drops then return\n    while(!carrying.empty()){\n        // go to nearest remaining drop\n        int bestDid=-1, bestDdist=INT_MAX, dx=0, dy=0;\n        for(int id: carrying){\n            auto p = getDrop(id);\n            int d = manh(curx, cury, p.first, p.second);\n            if(d < bestDdist){ bestDdist=d; bestDid=id; dx=p.first; dy=p.second; }\n        }\n        route.push_back({dx,dy,bestDid,false});\n        curx=dx; cury=dy;\n        auto it = find(carrying.begin(), carrying.end(), bestDid);\n        if(it!=carrying.end()) carrying.erase(it);\n    }\n    // If some pickups are left (shouldn't happen), pick and drop them immediately\n    while(!unpicked.empty()){\n        int id = unpicked.back(); unpicked.pop_back();\n        auto p = getPick(id);\n        if(p.first!=curx || p.second!=cury){\n            route.push_back({p.first,p.second,id,true});\n            curx=p.first; cury=p.second;\n        }else{\n            route.push_back({p.first,p.second,id,true});\n        }\n        auto q = getDrop(id);\n        route.push_back({q.first,q.second,id,false});\n        curx=q.first; cury=q.second;\n    }\n\n    route.push_back({DEPX,DEPY,-1,false});\n\n    auto routeDist = [&](const vector<Node>& R)->long long{\n        long long t=0;\n        for(size_t i=0;i+1<R.size();++i) t += manh(R[i].x,R[i].y,R[i+1].x,R[i+1].y);\n        return t;\n    };\n\n    // Precedence check: ensure for each order pickup index < drop index\n    auto violates = [&](const vector<Node>& R)->bool{\n        vector<int> pidx(1001,-1), didx(1001,-1);\n        for(int k=0;k<(int)R.size();++k){\n            int id=R[k].ordIdx;\n            if(id==-1) continue;\n            if(R[k].isPickup){ if(pidx[id]==-1) pidx[id]=k; }\n            else { if(didx[id]==-1) didx[id]=k; }\n        }\n        for (auto &o: sel){\n            int pid = pidx[o.idx];\n            int did = didx[o.idx];\n            if(pid==-1 || did==-1) continue;\n            if(pid >= did) return true;\n        }\n        return false;\n    };\n\n    // Local search: 2-opt with precedence\n    auto try_two_opt = [&](vector<Node>& R){\n        bool improved=true;\n        int iter=0;\n        while(improved && iter<200){\n            improved=false; iter++;\n            long long bestGain=0;\n            int bi=-1,bj=-1;\n            for(int i=1;i+2<(int)R.size();++i){\n                for(int j=i+1;j+1<(int)R.size();++j){\n                    long long d0 = manh(R[i-1].x,R[i-1].y,R[i].x,R[i].y)\n                                  + manh(R[j].x,R[j].y,R[j+1].x,R[j+1].y);\n                    long long d1 = manh(R[i-1].x,R[i-1].y,R[j].x,R[j].y)\n                                  + manh(R[i].x,R[i].y,R[j+1].x,R[j+1].y);\n                    long long gain = d0 - d1;\n                    if(gain > bestGain){\n                        reverse(R.begin()+i, R.begin()+j+1);\n                        if(!violates(R)){\n                            bestGain = gain;\n                            bi=i; bj=j;\n                        }\n                        reverse(R.begin()+i, R.begin()+j+1);\n                    }\n                }\n            }\n            if(bestGain > 0 && bi!=-1){\n                reverse(R.begin()+bi, R.begin()+bj+1);\n                improved=true;\n            }\n        }\n    };\n\n    try_two_opt(route);\n\n    // Paired relocate: move pickup and drop of an order together\n    auto index_of = [&](const vector<Node>& R, int id, bool pickup)->int{\n        for(int i=0;i<(int)R.size();++i){\n            if(R[i].ordIdx==id && R[i].isPickup==pickup) return i;\n        }\n        return -1;\n    };\n    auto relocate_pair = [&](vector<Node>& R){\n        bool improved=true;\n        int attempts=0;\n        while(improved && attempts<50){\n            improved=false; attempts++;\n            long long curL = routeDist(R);\n            bool applied=false;\n            for(auto &o: sel){\n                int pid = index_of(R,o.idx,true);\n                int did = index_of(R,o.idx,false);\n                if(pid==-1 || did==-1 || pid>=did) continue;\n                vector<int> candP;\n                for(int t=max(1,pid-3); t<=min((int)R.size()-2,pid+3); ++t) candP.push_back(t);\n                for(int p: candP){\n                    if(p==pid) continue;\n                    for(int q=max(p+1, did-3); q<=min((int)R.size()-1, did+3); ++q){\n                        vector<Node> T = R;\n                        Node P = T[pid];\n                        Node D = T[did];\n                        if(pid<did){\n                            T.erase(T.begin()+did);\n                            T.erase(T.begin()+pid);\n                        }else{\n                            T.erase(T.begin()+pid);\n                            T.erase(T.begin()+did);\n                        }\n                        T.insert(T.begin()+p, P);\n                        int qpos = q;\n                        if(p<=qpos) qpos++;\n                        qpos = max(qpos, p+1);\n                        qpos = min(qpos, (int)T.size()-1);\n                        T.insert(T.begin()+qpos, D);\n                        if(violates(T)) continue;\n                        long long newL = routeDist(T);\n                        if(newL + 0 < curL){\n                            R.swap(T);\n                            improved=true;\n                            applied=true;\n                            break;\n                        }\n                    }\n                    if(applied) break;\n                }\n                if(applied) break;\n            }\n        }\n    };\n\n    relocate_pair(route);\n    try_two_opt(route);\n\n    // Output\n    cout<<m;\n    for(auto &o: sel) cout<<\" \"<<o.idx;\n    cout<<\"\\n\";\n    cout<<route.size();\n    for(auto &nd: route){\n        cout<<\" \"<<nd.x<<\" \"<<nd.y;\n    }\n    cout<<\"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    int comps;\n    DSU(int n=0): n(n), p(n), r(n,0), comps(n) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool same(int a,int b){ return find(a)==find(b); }\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        comps--;\n        return true;\n    }\n};\n\nstruct Edge {\n    int idx;\n    int u,v;\n    int d; // prior 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    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++){\n        if(!(cin>>x[i]>>y[i])) return 0;\n    }\n    vector<int> U(M), V(M);\n    for(int i=0;i<M;i++){\n        cin>>U[i]>>V[i];\n    }\n\n    auto rd = [&](int i)->int{\n        long long dx = x[U[i]] - x[V[i]];\n        long long dy = y[U[i]] - y[V[i]];\n        double dist = sqrt((double)(dx*dx + dy*dy));\n        int di = (int)llround(dist);\n        return di;\n    };\n\n    vector<Edge> edges(M);\n    for(int i=0;i<M;i++){\n        edges[i] = {i, U[i], V[i], rd(i)};\n    }\n\n    // Build 5 disjoint MST layers using d as weight\n    vector<int> layer(M, -1);\n    vector<char> removed(M, 0);\n    // We'll make a list of remaining edge indices\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n\n    for(int lay=0; lay<5; lay++){\n        // Prepare list of available edges\n        vector<int> avail;\n        avail.reserve(M);\n        for(int ei=0; ei<M; ei++){\n            if(layer[ei]==-1) avail.push_back(ei);\n        }\n        // Sort by d\n        sort(avail.begin(), avail.end(), [&](int a, int b){\n            if(edges[a].d != edges[b].d) return edges[a].d < edges[b].d;\n            if(edges[a].u != edges[b].u) return edges[a].u < edges[b].u;\n            return edges[a].v < edges[b].v;\n        });\n        DSU dsu(N);\n        int taken = 0;\n        for(int eid: avail){\n            int u = edges[eid].u, v = edges[eid].v;\n            if(!dsu.same(u,v)){\n                dsu.unite(u,v);\n                layer[eid] = lay;\n                taken++;\n                if(taken == N-1) break;\n            }\n        }\n        // As per generation, there should be exactly N-1 per layer\n    }\n\n    // Online phase\n    DSU cur(N);\n    long long totalA = 0;\n    int comps = N;\n\n    // thresholds per layer; tuned values\n    // Lower layer index => more confident to accept at higher cost\n    array<double,5> alpha;\n    // base values\n    alpha[0]=1.60; alpha[1]=1.50; alpha[2]=1.40; alpha[3]=1.30; alpha[4]=1.20;\n\n    for(int i=0;i<M;i++){\n        int l_i;\n        if(!(cin>>l_i)) return 0;\n        int u = U[i], v = V[i];\n        int d = edges[i].d;\n        int lay = layer[i];\n        if(lay<0 || lay>4) lay = 4; // fallback\n\n        int R = M - i - 1;\n        int C = cur.comps;\n\n        bool accept = false;\n        if(cur.same(u,v)){\n            accept = false;\n        }else{\n            if(C-1 <= 1) {\n                // only one connection needed, still be cautious\n            }\n            // safety relaxations\n            double mul = alpha[lay];\n            if(R <= 3*(C-1)) mul += 0.30;\n            if(R <= 2*(C-1)) {\n                // To guarantee connectivity, accept any connecting edge\n                accept = true;\n            } else {\n                // Normal threshold decision\n                // Also quick absolute cap: accept if l is very small compared to global scale\n                // but primarily use l <= mul * d\n                if((double)l_i <= mul * (double)d) accept = true;\n            }\n        }\n\n        if(accept){\n            if(!cur.same(u,v)){\n                cur.unite(u,v);\n                totalA += l_i;\n            }\n            cout << 1 << '\\n' << flush;\n        }else{\n            cout << 0 << '\\n' << flush;\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int H = 30, W = 30;\n\nstruct Pet {\n    int x, y;\n    int t;\n};\nstruct Human {\n    int x, y;\n    int wallRow;\n    int standRow;\n    int L, R;\n    int dir; // +1 right, -1 left\n    int targetCol;\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<Pet> pets(N);\n    for (int i = 0; i < N; i++) {\n        int px, py, pt; cin >> px >> py >> pt;\n        pets[i] = {px, py, pt};\n    }\n    int M; cin >> M;\n    vector<Human> humans(M);\n    for (int i = 0; i < M; i++) {\n        int hx, hy; cin >> hx >> hy;\n        humans[i].x = hx; humans[i].y = hy;\n    }\n\n    auto inb = [&](int x,int y){ return 1<=x && x<=H && 1<=y && y<=W; };\n\n    vector<vector<bool>> blocked(H+1, vector<bool>(W+1,false));\n    vector<vector<int>> petCnt(H+1, vector<int>(W+1,0));\n    for (auto &p: pets) petCnt[p.x][p.y]++;\n\n    // Assign wall rows and standing rows\n    vector<int> wallRowsBase = {6,12,18,24};\n    for (int i = 0; i < M; i++) {\n        int wr = wallRowsBase[i % (int)wallRowsBase.size()];\n        humans[i].wallRow = wr;\n        int stand = wr - 1;\n        if (stand < 1) stand = wr + 1;\n        humans[i].standRow = stand;\n    }\n    // Assign column segments\n    for (int i = 0; i < M; i++) {\n        int L = (long long)i * W / M + 1;\n        int R = (long long)(i+1) * W / M;\n        humans[i].L = L; humans[i].R = R;\n        int hy = humans[i].y;\n        humans[i].targetCol = max(L, min(hy, R));\n        // Choose dir toward nearest boundary for quicker coverage\n        if (abs(hy - L) <= abs(hy - R)) humans[i].dir = -1; else humans[i].dir = +1;\n        if (humans[i].targetCol == L) humans[i].dir = +1;\n        if (humans[i].targetCol == R) humans[i].dir = -1;\n    }\n\n    auto safe_to_block = [&](int tx,int ty, const vector<Human>& hs)->bool{\n        if (!inb(tx,ty)) return false;\n        if (blocked[tx][ty]) return false;\n        if (petCnt[tx][ty] > 0) return false;\n        // cannot choose a square that contains humans at the start of the turn\n        for (const auto& h: hs) if (h.x==tx && h.y==ty) return false;\n        // cannot choose a square whose adjacent square contains a pet\n        static const int dx[4]={-1,1,0,0};\n        static const int dy[4]={0,0,-1,1};\n        for (int k=0;k<4;k++){\n            int nx=tx+dx[k], ny=ty+dy[k];\n            if (inb(nx,ny) && petCnt[nx][ny]>0) return false;\n        }\n        return true;\n    };\n\n    for (int turn = 0; turn < 300; turn++) {\n        // Phase 1: propose actions\n        string actions(M, '.');\n\n        for (int i = 0; i < M; i++) {\n            auto &h = humans[i];\n            int wr = h.wallRow;\n            int sr = h.standRow;\n\n            // Move vertically to standing row\n            if (h.x != sr) {\n                if (h.x > sr) {\n                    if (inb(h.x-1,h.y) && !blocked[h.x-1][h.y]) actions[i]='U';\n                    else actions[i]='.';\n                } else {\n                    if (inb(h.x+1,h.y) && !blocked[h.x+1][h.y]) actions[i]='D';\n                    else actions[i]='.';\n                }\n                continue;\n            }\n            // Move horizontally into assigned segment if outside\n            if (h.y < h.L) {\n                if (inb(h.x,h.y+1) && !blocked[h.x][h.y+1]) actions[i]='R';\n                else actions[i]='.';\n                continue;\n            }\n            if (h.y > h.R) {\n                if (inb(h.x,h.y-1) && !blocked[h.x][h.y-1]) actions[i]='L';\n                else actions[i]='.';\n                continue;\n            }\n            // Within segment: try to place block into wall row at current column\n            int tx = wr, ty = h.y;\n            char place = (sr < wr ? 'd' : 'u');\n            if (safe_to_block(tx,ty, humans)) {\n                actions[i] = place;\n                continue;\n            }\n            // Otherwise sweep horizontally\n            if (h.dir > 0) {\n                if (h.y < h.R && !blocked[h.x][h.y+1]) actions[i]='R';\n                else {\n                    h.dir = -1;\n                    if (h.y > h.L && !blocked[h.x][h.y-1]) actions[i]='L';\n                    else actions[i]='.';\n                }\n            } else {\n                if (h.y > h.L && !blocked[h.x][h.y-1]) actions[i]='L';\n                else {\n                    h.dir = +1;\n                    if (h.y < h.R && !blocked[h.x][h.y+1]) actions[i]='R';\n                    else actions[i]='.';\n                }\n            }\n        }\n\n        // Phase 2: prevent move-into-newly-blocked conflicts\n        // Compute set of cells that will be blocked by any human this turn\n        vector<vector<bool>> willBlock(H+1, vector<bool>(W+1,false));\n        for (int i = 0; i < M; i++) {\n            if (actions[i]=='.' || actions[i]=='U' || actions[i]=='D' || actions[i]=='L' || actions[i]=='R') continue;\n            int tx = humans[i].x, ty = humans[i].y;\n            if (actions[i]=='u') tx--;\n            else if (actions[i]=='d') tx++;\n            else if (actions[i]=='l') ty--;\n            else if (actions[i]=='r') ty++;\n            if (inb(tx,ty)) {\n                // It might be illegal per rules, but we already checked safe_to_block. Mark it here anyway.\n                willBlock[tx][ty] = true;\n            }\n        }\n        // Cancel moves that would step into a to-be-blocked cell\n        for (int i = 0; i < M; i++) {\n            char c = actions[i];\n            if (c=='U' || c=='D' || c=='L' || c=='R') {\n                int nx = humans[i].x, ny = humans[i].y;\n                if (c=='U') nx--;\n                else if (c=='D') nx++;\n                else if (c=='L') ny--;\n                else if (c=='R') ny++;\n                if (inb(nx,ny) && willBlock[nx][ny]) {\n                    actions[i] = '.'; // stay to avoid illegal move\n                }\n            }\n        }\n\n        // Output actions\n        cout << actions << \"\\n\";\n        cout.flush();\n\n        // Apply blocks locally\n        for (int i = 0; i < M; i++) {\n            char c = actions[i];\n            if (c=='.' || c=='U' || c=='D' || c=='L' || c=='R') continue;\n            int tx = humans[i].x, ty = humans[i].y;\n            if (c=='u') tx--;\n            else if (c=='d') tx++;\n            else if (c=='l') ty--;\n            else if (c=='r') ty++;\n            if (inb(tx,ty)) blocked[tx][ty] = true;\n        }\n        // Apply moves locally (avoid stepping into any blocked cell)\n        for (int i = 0; i < M; i++) {\n            char c = actions[i];\n            int nx = humans[i].x, ny = humans[i].y;\n            if (c=='U') nx--;\n            else if (c=='D') nx++;\n            else if (c=='L') ny--;\n            else if (c=='R') ny++;\n            if (inb(nx,ny) && !blocked[nx][ny]) {\n                humans[i].x = nx; humans[i].y = ny;\n            }\n        }\n\n        // Read pets moves and update positions\n        vector<string> pm(N);\n        for (int i = 0; i < N; i++) cin >> pm[i];\n        for (int x=1;x<=H;x++) for (int y=1;y<=W;y++) petCnt[x][y]=0;\n        for (int i = 0; i < N; i++) {\n            for (char c: pm[i]) {\n                int nx = pets[i].x, ny = pets[i].y;\n                if (c=='U') nx--;\n                else if (c=='D') nx++;\n                else if (c=='L') ny--;\n                else if (c=='R') ny++;\n                if (inb(nx,ny)) { pets[i].x=nx; pets[i].y=ny; }\n            }\n            petCnt[pets[i].x][pets[i].y] ++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si,sj,ti,tj;\n    double p;\n    if(!(cin>>si>>sj>>ti>>tj>>p)) return 0;\n    vector<string> h(20), v(19);\n    for(int i=0;i<20;i++){\n        cin>>h[i];\n    }\n    for(int i=0;i<19;i++){\n        cin>>v[i];\n    }\n    auto inb = [](int x,int y){ return 0<=x && x<20 && 0<=y && y<20; };\n    auto can_move = [&](int x,int y,int nx,int ny)->bool{\n        if(!inb(nx,ny)) return false;\n        if(nx==x && ny==y+1){\n            return h[x][y]=='0';\n        }\n        if(nx==x && ny==y-1){\n            return h[x][y-1]=='0';\n        }\n        if(nx==x+1 && ny==y){\n            return v[x][y]=='0';\n        }\n        if(nx==x-1 && ny==y){\n            return v[x-1][y]=='0';\n        }\n        return false;\n    };\n    // BFS shortest path\n    const int N=20;\n    vector<vector<int>> dist(N, vector<int>(N, INT_MAX));\n    vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj]=0;\n    q.push({si,sj});\n    int dx[4]={-1,1,0,0};\n    int dy[4]={0,0,-1,1};\n    char dc[4] = {'U','D','L','R'};\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        if(x==ti && y==tj) break;\n        for(int d=0;d<4;d++){\n            int nx=x+dx[d], ny=y+dy[d];\n            if(!inb(nx,ny)) continue;\n            if(!can_move(x,y,nx,ny)) continue;\n            if(dist[nx][ny] > dist[x][y] + 1){\n                dist[nx][ny] = dist[x][y] + 1;\n                par[nx][ny] = {x,y};\n                q.push({nx,ny});\n            }\n        }\n    }\n    // Reconstruct path\n    vector<pair<int,int>> path;\n    int cx=ti, cy=tj;\n    while(!(cx==si && cy==sj) && cx!=-1){\n        path.push_back({cx,cy});\n        auto pr = par[cx][cy];\n        cx = pr.first; cy = pr.second;\n    }\n    path.push_back({si,sj});\n    reverse(path.begin(), path.end());\n    // If BFS somehow fails (shouldn't), fallback to simple greedy without walls\n    vector<char> dirs;\n    if((int)path.size()>=2){\n        for(size_t k=1;k<path.size();k++){\n            int x0=path[k-1].first, y0=path[k-1].second;\n            int x1=path[k].first, y1=path[k].second;\n            if(x1==x0-1 && y1==y0) dirs.push_back('U');\n            else if(x1==x0+1 && y1==y0) dirs.push_back('D');\n            else if(x1==x0 && y1==y0-1) dirs.push_back('L');\n            else if(x1==x0 && y1==y0+1) dirs.push_back('R');\n        }\n    }else{\n        // fallback: straight moves\n        int x=si,y=sj;\n        while(x>ti) { dirs.push_back('U'); x--; }\n        while(x<ti) { dirs.push_back('D'); x++; }\n        while(y>tj) { dirs.push_back('L'); y--; }\n        while(y<tj) { dirs.push_back('R'); y++; }\n    }\n    int D = (int)dirs.size();\n    if(D==0){\n        cout << \"\\n\";\n        return 0;\n    }\n    // Choose repetition factor r\n    // target epsilon for failing to advance on a block: p^r <= 0.02\n    auto safe_ceil = [](double x)->int{\n        int k = (int)ceil(x - 1e-12);\n        return k;\n    };\n    int r_cap;\n    if(p>=1.0-1e-12) r_cap = 8;\n    else {\n        double num = log(0.02);\n        double den = log(p);\n        int rc = safe_ceil(num/den); // since den<0, this is positive\n        r_cap = max(2, min(8, rc));\n    }\n    int r_max = max(1, 200 / max(1, D));\n    int r = min(r_max, r_cap);\n    // Build output\n    string out;\n    out.reserve(200);\n    auto append_repeats = [&](const vector<char>& P, int rep){\n        for(char c: P){\n            for(int k=0;k<rep;k++){\n                if((int)out.size()<200) out.push_back(c);\n            }\n        }\n    };\n    append_repeats(dirs, r);\n    // Add extra full-path copies (unrepeated) to fill up to near 200\n    while((int)out.size() + D <= 200){\n        for(char c: dirs){\n            if((int)out.size()<200) out.push_back(c);\n        }\n    }\n    // If still too short and we have a bit of space, add prefix of path\n    int rem = 200 - (int)out.size();\n    for(int i=0;i<rem && i<D;i++) out.push_back(dirs[i]);\n\n    cout << out << \"\\n\";\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int H = 30, W = 30;\nstatic const int di4[4] = {0,-1,0,1};\nstatic const int dj4[4] = {-1,0,1,0};\n\n// Base to mapping for tile types 0..7 as per statement.\nint base_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// to_rot[t][r][d]: with tile type t rotated r times CCW, entering from direction d, output direction or -1.\nint to_rot[8][4][4];\n\ninline int mod4(int x){ x%=4; if(x<0)x+=4; return x; }\n\nstruct Solver {\n    array<array<int, W>, H> t;\n    array<array<int, W>, H> r;         // current rotations\n    array<array<int, W>, H> best_r;\n    array<array<int, W>, H> tmp_r;\n\n    // desired outgoing direction for each entering direction\n    array<array<array<int,4>, W>, H> desired_to;\n\n    int proxyScore = 0;\n\n    mt19937 rng;\n\n    Solver(): rng(712367) {}\n\n    void precompute_to_rot() {\n        for(int tt=0; tt<8; ++tt){\n            for(int rot=0; rot<4; ++rot){\n                for(int d=0; d<4; ++d){\n                    int din = mod4(d - rot);\n                    int e = base_to_[tt][din];\n                    if(e==-1) to_rot[tt][rot][d] = -1;\n                    else to_rot[tt][rot][d] = mod4(e + rot);\n                }\n            }\n        }\n    }\n\n    void read_input() {\n        for(int i=0;i<H;++i){\n            string s; cin>>s;\n            for(int j=0;j<W;++j){\n                t[i][j] = s[j]-'0';\n            }\n        }\n    }\n\n    // Build desired_to by selecting a pattern id\n    // pattern 0: two vortices (left/right)\n    // pattern 1: single center vortex\n    // pattern 2: horizontal ring (prefer left/right flow loop)\n    // pattern 3: vertical ring\n    // pattern 4: four quadrants vortices\n    // pattern 5: serpentine sweeping rows\n    void build_desired(int pattern) {\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                for(int d=0; d<4; ++d) desired_to[i][j][d]=2; // default right\n            }\n        }\n        auto pick_card = [&](double ti, double tj)->int{\n            static const int vx[4] = {0,-1,0,1};\n            static const int vy[4] = {-1,0,1,0};\n            int bestd = 0;\n            double bestdot = -1e100;\n            for(int d=0; d<4; ++d){\n                double dot = ti*vx[d] + tj*vy[d];\n                if(dot > bestdot){ bestdot=dot; bestd=d; }\n            }\n            return bestd;\n        };\n        if(pattern==0){ // two vortices\n            double c1i = 14.5, c1j = 7.5;\n            double c2i = 14.5, c2j = 22.5;\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    double ci, cj;\n                    if(j < W/2) { ci=c1i; cj=c1j; }\n                    else { ci=c2i; cj=c2j; }\n                    double pi = i+0.5, pj=j+0.5;\n                    double ui = pi - ci, uj = pj - cj;\n                    double ti = -uj, tj = ui; // CCW tangent\n                    int dsel = pick_card(ti,tj);\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else if(pattern==1){ // single center vortex\n            double ci = 14.5, cj = 14.5;\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    double pi = i+0.5, pj=j+0.5;\n                    double ui = pi - ci, uj = pj - cj;\n                    double ti = -uj, tj = ui;\n                    int dsel = pick_card(ti,tj);\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else if(pattern==2){ // horizontal ring\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int dsel = (i%2==0)?2:0; // even rows go right, odd left\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else if(pattern==3){ // vertical ring\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int dsel = (j%2==0)?3:1; // even cols go down, odd up\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else if(pattern==4){ // four quadrants vortices\n            double ci1=7.5,cj1=7.5, ci2=7.5,cj2=21.5, ci3=21.5,cj3=7.5, ci4=21.5,cj4=21.5;\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    double ci, cj;\n                    if(i<15 && j<15){ ci=ci1; cj=cj1; }\n                    else if(i<15){ ci=ci2; cj=cj2; }\n                    else if(j<15){ ci=ci3; cj=cj3; }\n                    else { ci=ci4; cj=cj4; }\n                    double pi = i+0.5, pj=j+0.5;\n                    double ui = pi - ci, uj = pj - cj;\n                    double ti = -uj, tj = ui;\n                    int dsel = pick_card(ti,tj);\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else { // serpentine with bias to loop around borders\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int dsel;\n                    if(i==0) dsel = 2;\n                    else if(i==H-1) dsel = 0;\n                    else dsel = (i%2==0)?2:0;\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        }\n    }\n\n    int tile_local_score(int i,int j,int rot, const array<array<int,W>,H>& rotAssign){\n        int sc = 0;\n        for(int d=0; d<4; ++d){\n            int e = to_rot[t[i][j]][rot][d];\n            if(e==-1){ sc -= 2; continue; }\n            if(e == desired_to[i][j][d]) sc += 1;\n            int ni = i + di4[e], nj = j + dj4[e];\n            if(ni<0||ni>=H||nj<0||nj>=W) sc -= 3;\n            else {\n                // neighbor tentative consistency\n                int need = (e+2)&3;\n                int ne = to_rot[t[ni][nj]][rotAssign[ni][nj]][need];\n                if(ne == need) sc += 1;\n            }\n        }\n        return sc;\n    }\n\n    void initial_assignment() {\n        // simple greedy with a couple of sweeps to incorporate neighbor consistency\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                int bestRot=0, bestSc = INT_MIN;\n                for(int rot=0; rot<4; ++rot){\n                    int sc = 0;\n                    for(int d=0; d<4; ++d){\n                        int e = to_rot[t[i][j]][rot][d];\n                        if(e==-1){ sc -= 2; continue; }\n                        if(e == desired_to[i][j][d]) sc += 1;\n                        int ni = i + di4[e], nj = j + dj4[e];\n                        if(ni<0||ni>=H||nj<0||nj>=W) sc -= 3;\n                    }\n                    if(sc > bestSc){\n                        bestSc = sc; bestRot = rot;\n                    }\n                }\n                r[i][j] = bestRot;\n            }\n        }\n        // a few refinement sweeps\n        for(int it=0; it<2; ++it){\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int cur = r[i][j];\n                    int bestRot = cur, bestSc = tile_local_score(i,j,cur,r);\n                    for(int rot=0; rot<4; ++rot){\n                        if(rot==cur) continue;\n                        int sc = tile_local_score(i,j,rot,r);\n                        if(sc > bestSc){ bestSc = sc; bestRot = rot; }\n                    }\n                    r[i][j] = bestRot;\n                }\n            }\n        }\n    }\n\n    // Edge match proxy: bidirectional usability across an edge\n    inline int edge_match_at(int i,int j,int d) {\n        int ni = i + di4[d], nj = j + dj4[d];\n        if(ni<0||ni>=H||nj<0||nj>=W) return 0;\n        // A entering from opposite of edge, out to the edge\n        int Ato = to_rot[t[i][j]][r[i][j]][(d+2)&3];\n        if(Ato != d) return 0;\n        // B entering from its opposite of edge, out back along the edge\n        int Bd = (d+2)&3;\n        int Bto = to_rot[t[ni][nj]][r[ni][nj]][(Bd+2)&3]; // careful: entering from opposite of the edge at B is actually d (from A to B). For symmetric, use:\n        // Correct: for B, entering from opposite direction of edge from its perspective is d (from its neighbor). The pair that forms the straight across the shared edge is:\n        // If we cross edge between A and B, then at B the entering direction is (d+2)%4. To continue across back to A, B should output (d+2)%4 (backwards), but for a loop we need B to accept from (d+2) and send back (d+2). However, to ensure the edge can be traversed both ways by trains coming from both sides, we check both A->B and B->A. We'll implement that fully below outside this function for accuracy.\n        (void)Bto;\n        return 1; // placeholder, not used\n    }\n\n    // Proper undirected edge usability: both directions usable\n    inline int edge_bidirected_usable(int ai,int aj,int d){\n        int bi = ai + di4[d], bj = aj + dj4[d];\n        if(bi<0||bi>=H||bj<0||bj>=W) return 0;\n        // A->B\n        int eA = to_rot[t[ai][aj]][r[ai][aj]][(d+2)&3];\n        if(eA != d) return 0;\n        int eB = to_rot[t[bi][bj]][r[bi][bj]][(d+2)&3];\n        if(eB != (d+2)&3) return 0;\n        // B->A\n        int eB2 = to_rot[t[bi][bj]][r[bi][bj]][(d)&3];\n        if(eB2 != (d+2)&3) return 0;\n        int eA2 = to_rot[t[ai][aj]][r[ai][aj]][(d)&3];\n        if(eA2 != d) return 0;\n        return 1;\n    }\n\n    int compute_proxy_score() {\n        int total = 0;\n        for(int i=0;i<H;++i){\n            for(int j=0;j+1<W;++j){\n                total += edge_bidirected_usable(i,j,2);\n            }\n        }\n        for(int i=0;i+1<H;++i){\n            for(int j=0;j<W;++j){\n                total += edge_bidirected_usable(i,j,3);\n            }\n        }\n        return total;\n    }\n\n    int local_proxy_contrib_cell(int i,int j){\n        int sum=0;\n        if(j>0) sum += edge_bidirected_usable(i,j-1,2);\n        if(j<W-1) sum += edge_bidirected_usable(i,j,2);\n        if(i>0) sum += edge_bidirected_usable(i-1,j,3);\n        if(i<H-1) sum += edge_bidirected_usable(i,j,3);\n        return sum;\n    }\n\n    // Compute top two loop lengths and optionally record states of the loops\n    pair<int,int> compute_top2_loops(vector<pair<int,int>>* bestLoopCells = nullptr, vector<pair<int,int>>* secondLoopCells = nullptr) {\n        vector<vector<array<char,4>>> vis(H, vector<array<char,4>>(W, {0,0,0,0}));\n        int best1=0, best2=0;\n        vector<pair<int,int>> loop1cells, loop2cells;\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                for(int d=0; d<4; ++d){\n                    if(vis[i][j][d]) continue;\n                    int ci=i, cj=j, cd=d;\n                    int steps=0;\n                    // map state to step index\n                    // use array for performance: 3600 states, but we need per-walk storage. Use unordered_map reserved small.\n                    unordered_map<int,int> seen;\n                    seen.reserve(32);\n                    auto enc = [&](int x,int y,int dd){ return ((x*W + y)<<2) | dd; };\n                    vector<tuple<int,int,int>> walk;\n                    while(true){\n                        int key = enc(ci,cj,cd);\n                        if(seen.find(key)!=seen.end()){\n                            int st = seen[key];\n                            int cyc_len = steps - st;\n                            if(cyc_len >= best1){\n                                best2 = best1; loop2cells = loop1cells;\n                                best1 = cyc_len;\n                                loop1cells.clear();\n                                for(int k=st;k<(int)walk.size();++k){\n                                    auto [x,y,dd] = walk[k];\n                                    loop1cells.emplace_back(x,y);\n                                }\n                            } else if(cyc_len > best2){\n                                best2 = cyc_len;\n                                loop2cells.clear();\n                                for(int k=st;k<(int)walk.size();++k){\n                                    auto [x,y,dd] = walk[k];\n                                    loop2cells.emplace_back(x,y);\n                                }\n                            }\n                            break;\n                        }\n                        if(vis[ci][cj][cd]) break;\n                        seen[key] = steps;\n                        walk.emplace_back(ci,cj,cd);\n                        int e = to_rot[t[ci][cj]][r[ci][cj]][cd];\n                        if(e==-1) break;\n                        int ni = ci + di4[e], nj = cj + dj4[e];\n                        if(ni<0||ni>=H||nj<0||nj>=W) break;\n                        int nd = (e+2)&3;\n                        ci=ni; cj=nj; cd=nd;\n                        steps++;\n                    }\n                    // mark visited\n                    for(auto &tp: walk){\n                        int x,y,dd; tie(x,y,dd)=tp;\n                        vis[x][y][dd]=1;\n                    }\n                }\n            }\n        }\n        if(bestLoopCells) *bestLoopCells = loop1cells;\n        if(secondLoopCells) *secondLoopCells = loop2cells;\n        return {best1,best2};\n    }\n\n    // Reinforce tiles along loop cells by choosing rotation that maximizes participation edges\n    void reinforce_along_loops(const vector<pair<int,int>>& loopCells){\n        if(loopCells.empty()) return;\n        // mark cells\n        vector<vector<char>> mark(H, vector<char>(W, 0));\n        for(auto &p: loopCells) mark[p.first][p.second]=1;\n        // try improving rotations on marked cells\n        for(auto &p: loopCells){\n            int i=p.first, j=p.second;\n            int cur = r[i][j];\n            int bestRot = cur;\n            int bestLoc = local_proxy_contrib_cell(i,j);\n            for(int rot=0; rot<4; ++rot){\n                if(rot==cur) continue;\n                int old = r[i][j];\n                r[i][j]=rot;\n                int val = local_proxy_contrib_cell(i,j);\n                if(val > bestLoc){ bestLoc=val; bestRot=rot; }\n                r[i][j]=old;\n            }\n            r[i][j]=bestRot;\n        }\n    }\n\n    // Hill climb / SA\n    void optimize(double timeLimitSec, long long &bestScoreAll, array<array<int,W>,H> &bestRAll){\n        proxyScore = compute_proxy_score();\n        auto top2 = compute_top2_loops();\n        long long bestScore = 1LL*top2.first*top2.second;\n        best_r = r;\n\n        auto start = chrono::high_resolution_clock::now();\n        int iter=0, accepted=0;\n        uniform_real_distribution<double> urd(0.0,1.0);\n\n        while(true){\n            iter++;\n            if((iter & 0x1FFF)==0){\n                auto now = chrono::high_resolution_clock::now();\n                double t = chrono::duration<double>(now - start).count();\n                if(t > timeLimitSec) break;\n            }\n            int i = rng()%H;\n            int j = rng()%W;\n            int cur = r[i][j];\n            int before = local_proxy_contrib_cell(i,j);\n            int bestRot = cur;\n            int bestLocal = before;\n            for(int rot=0; rot<4; ++rot){\n                if(rot==cur) continue;\n                int old = r[i][j];\n                r[i][j] = rot;\n                int after = local_proxy_contrib_cell(i,j);\n                if(after > bestLocal){\n                    bestLocal = after; bestRot = rot;\n                }\n                r[i][j] = old;\n            }\n            int gain = bestLocal - before;\n            // SA acceptance with cooling\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            double frac = min(1.0, elapsed / timeLimitSec);\n            double T0 = 0.5, T1 = 0.02;\n            double temp = T0 * (1.0 - frac) + T1 * frac;\n            bool take = false;\n            if(gain > 0) take = true;\n            else {\n                double prob = exp(gain / max(1e-9, temp));\n                if(urd(rng) < prob) take = true;\n            }\n            if(take){\n                r[i][j] = bestRot;\n                proxyScore += gain;\n                accepted++;\n                if((accepted % 200)==0){\n                    auto p = compute_top2_loops();\n                    long long sc = 1LL*p.first*p.second;\n                    if(sc > bestScore){\n                        bestScore = sc;\n                        best_r = r;\n                    }\n                }\n            }\n        }\n        // Final evaluation and reinforcement\n        auto cells1 = vector<pair<int,int>>(), cells2 = vector<pair<int,int>>();\n        auto p = compute_top2_loops(&cells1, &cells2);\n        long long sc = 1LL*p.first*p.second;\n        if(sc > bestScore){ bestScore = sc; best_r = r; }\n        // reinforce along the two best loops and re-evaluate\n        r = best_r;\n        reinforce_along_loops(cells1);\n        reinforce_along_loops(cells2);\n        auto p2 = compute_top2_loops();\n        long long sc2 = 1LL*p2.first*p2.second;\n        if(sc2 > bestScore){ bestScore = sc2; best_r = r; }\n\n        if(bestScore > bestScoreAll){\n            bestScoreAll = bestScore;\n            bestRAll = best_r;\n        }\n        // restore best for further usage\n        r = best_r;\n    }\n\n    void solve() {\n        precompute_to_rot();\n        read_input();\n\n        long long globalBestScore = -1;\n        array<array<int,W>,H> globalBestR;\n\n        // Try several patterns with limited time shares\n        const int PATTERNS[6] = {0,1,2,3,4,5};\n        double totalTime = 1.95;\n        double initShare = 0.15; // time for initialization refinements\n        double perPatternTime = (totalTime - initShare) / 6.0;\n\n        auto tstart = chrono::high_resolution_clock::now();\n\n        for(int pid = 0; pid < 6; ++pid){\n            build_desired(PATTERNS[pid]);\n            initial_assignment();\n            // Use a portion of time for this pattern\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - tstart).count();\n            double remaining = max(0.0, totalTime - elapsed);\n            double budget = min(perPatternTime, remaining);\n            if(budget <= 0.0) break;\n            optimize(budget, globalBestScore, globalBestR);\n        }\n\n        // As fallback, if nothing ran (shouldn't happen), compute once\n        if(globalBestScore < 0){\n            build_desired(0);\n            initial_assignment();\n            auto p = compute_top2_loops();\n            globalBestR = r;\n        }\n\n        // Output best rotations as a single line of 900 digits\n        string out; out.reserve(H*W);\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                out.push_back(char('0' + (globalBestR[i][j] & 3)));\n            }\n        }\n        cout << out << \"\\n\";\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver s;\n    s.solve();\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction masks: bit 0=left(1), bit1=up(2), bit2=right(4), bit3=down(8)\nstatic inline bool matchLR(int a, int b){ // a right with b left\n    return (a & 4) && (b & 1);\n}\nstatic inline bool matchUD(int a, int b){ // a down with b up\n    return (a & 8) && (b & 2);\n}\n\nstruct RNG {\n    uint64_t x;\n    RNG(uint64_t seed=712367821) : x(seed) {}\n    uint32_t next() { x ^= x<<7; x ^= x>>9; return (uint32_t)x; }\n    int randint(int l, int r){ return l + (int)(next() % (uint32_t)(r-l+1)); }\n    bool prob(double p){ return (next() / (double)UINT32_MAX) < p; }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; int Tlimit;\n    if(!(cin>>N>>Tlimit)) {\n        return 0;\n    }\n    vector<string> rows(N);\n    for(int i=0;i<N;i++) cin>>rows[i];\n    vector<int> a(N*N);\n    int emptyPos=-1;\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            char c = rows[i][j];\n            int v;\n            if(c>='0' && c<='9') v = c-'0';\n            else v = 10 + (c-'a');\n            a[i*N+j]=v;\n            if(v==0) emptyPos=i*N+j;\n        }\n    }\n\n    RNG rng(123456789 ^ (uint64_t)chrono::high_resolution_clock::now().time_since_epoch().count());\n\n    auto inb = [&](int r,int c){ return r>=0 && r<N && c>=0 && c<N; };\n\n    // Precompute adjacency matched array\n    // horiz[i][j] is match between (i,j) and (i,j+1)\n    vector<char> horiz(N*(N-1),0), vert((N-1)*N,0);\n    auto idxH = [&](int i,int j){ return i*(N-1)+j; };\n    auto idxV = [&](int i,int j){ return i*N+j; };\n\n    auto recompute_local_edges = [&](int r,int c){\n        // Update matches around (r,c): edges to left/right/up/down if exist\n        int p = r*N+c;\n        if(a[p]==0){\n            // empty contributes no edges, but neighbors matching is only defined on non-empty squares\n            // However matched edges definition is between non-empty squares; empty breaks edges.\n        }\n        // Horizontal edges with (r,c-1)-(r,c) and (r,c)-(r,c+1)\n        if(c-1>=0){\n            int L = a[r*N+(c-1)], Rv = a[r*N+c];\n            horiz[idxH(r,c-1)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n        if(c<N-1){\n            int L = a[r*N+c], Rv = a[r*N+(c+1)];\n            horiz[idxH(r,c)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n        // Vertical edges with (r-1,c)-(r,c) and (r,c)-(r+1,c)\n        if(r-1>=0){\n            int U = a[(r-1)*N+c], Dv = a[r*N+c];\n            vert[idxV(r-1,c)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n        if(r<N-1){\n            int U = a[r*N+c], Dv = a[(r+1)*N+c];\n            vert[idxV(r,c)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n    };\n    // Initialize all matches\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N-1;j++){\n            int L=a[i*N+j], Rv=a[i*N+j+1];\n            horiz[idxH(i,j)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n    }\n    for(int i=0;i<N-1;i++){\n        for(int j=0;j<N;j++){\n            int U=a[i*N+j], Dv=a[(i+1)*N+j];\n            vert[idxV(i,j)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n    }\n    auto totalE = [&](){\n        int s=0;\n        for(char v: horiz) s+=v;\n        for(char v: vert) s+=v;\n        return s;\n    };\n    int E = totalE();\n\n    // Helpers to compute local delta for a tentative swap between empty at (er,ec) and neighbor (nr,nc)\n    auto delta_for_move = [&](int er,int ec,int nr,int nc)->int{\n        // collect set of affected edges indices before and after; easiest is to sum contributions around the two cells\n        int before=0, after=0;\n        auto add_edges = [&](int r,int c,int &acc){\n            if(c-1>=0) acc += horiz[idxH(r,c-1)];\n            if(c<N-1) acc += horiz[idxH(r,c)];\n            if(r-1>=0) acc += vert[idxV(r-1,c)];\n            if(r<N-1) acc += vert[idxV(r,c)];\n        };\n        add_edges(er,ec,before);\n        add_edges(nr,nc,before);\n\n        // simulate swap\n        int pe = er*N+ec, pn = nr*N+nc;\n        int ve = a[pe], vn = a[pn]; // ve == 0\n        // Temporarily swap in thought: a'[pe]=vn, a'[pn]=0\n        // compute edges after by recomputing these positions\u2019 edges on the fly\n        auto contrib_cell = [&](int r,int c, int val_at_rc)->int{\n            int s=0;\n            // left edge (r,c-1)-(r,c)\n            if(c-1>=0){\n                int L = (r*N + c-1 == pe ? vn : (r*N + c-1 == pn ? 0 : a[r*N + c-1]));\n                int Rv = val_at_rc;\n                s += (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n            }\n            // right edge (r,c)-(r,c+1)\n            if(c<N-1){\n                int L = val_at_rc;\n                int Rv = (r*N + c+1 == pe ? vn : (r*N + c+1 == pn ? 0 : a[r*N + c+1]));\n                s += (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n            }\n            // up edge (r-1,c)-(r,c)\n            if(r-1>=0){\n                int U = ( (r-1)*N + c == pe ? vn : ((r-1)*N + c == pn ? 0 : a[(r-1)*N + c]) );\n                int Dv = val_at_rc;\n                s += (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n            }\n            // down edge (r,c)-(r+1,c)\n            if(r<N-1){\n                int U = val_at_rc;\n                int Dv = ( (r+1)*N + c == pe ? vn : ((r+1)*N + c == pn ? 0 : a[(r+1)*N + c]) );\n                s += (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n            }\n            return s;\n        };\n        after += contrib_cell(er,ec, vn);\n        after += contrib_cell(nr,nc, 0);\n        return after - before;\n    };\n\n    string moves;\n    moves.reserve(Tlimit);\n\n    // Direction arrays\n    const int dr[4]={-1,1,0,0};\n    const int dc[4]={0,0,-1,1};\n    const char dch[4] = {'U','D','L','R'};\n    const int revdir[4] = {1,0,3,2};\n\n    int er = emptyPos / N, ec = emptyPos % N;\n    int last_dir = -1;\n\n    auto apply_move = [&](int dir){\n        int nr = er + dr[dir], nc = ec + dc[dir];\n        // compute delta and apply\n        int pe = er*N+ec, pn = nr*N+nc;\n        int delta = 0;\n        // remove before from E by recomputing local, then recompute after with actual update and patch horiz/vert\n        // For robustness, compute delta via delta_for_move\n        delta = delta_for_move(er,ec,nr,nc);\n        // swap\n        swap(a[pe], a[pn]);\n        // update local edges arrays around affected cells (and neighbors; recompute around both cells)\n        recompute_local_edges(er,ec);\n        recompute_local_edges(nr,nc);\n        E += delta;\n        er = nr; ec = nc;\n        moves.push_back(dch[dir]);\n        last_dir = dir;\n    };\n\n    // Main loop: up to Tlimit moves or time\n    auto t_start = chrono::high_resolution_clock::now();\n    double time_limit_ms = 2800.0;\n\n    for(int step=0; step<Tlimit; ++step){\n        // time guard\n        if((step & 255) == 0){\n            auto now = chrono::high_resolution_clock::now();\n            double ms = chrono::duration<double, milli>(now - t_start).count();\n            if(ms > time_limit_ms) break;\n        }\n        // evaluate candidates\n        struct Cand{ int dir; int delta; int tie; };\n        vector<Cand> cands;\n        for(int d=0; d<4; d++){\n            int nr = er + dr[d], nc = ec + dc[d];\n            if(!inb(nr,nc)) continue;\n            if(last_dir != -1 && revdir[d]==last_dir){\n                // consider but downweight; we'll keep it but mark tie worse unless strictly good\n            }\n            int del = delta_for_move(er,ec,nr,nc);\n            int tie = 0;\n            // tie-breaker: prefer central positions for the empty after move\n            int cen_bias = - (abs((N-1)/2 - nr) + abs((N-1)/2 - nc));\n            tie += cen_bias;\n            // small random jitter\n            tie += rng.randint(-2,2);\n            cands.push_back({d, del, tie});\n        }\n        if(cands.empty()) break;\n        // choose best\n        sort(cands.begin(), cands.end(), [&](const Cand& A, const Cand& B){\n            if(A.delta != B.delta) return A.delta > B.delta;\n            return A.tie > B.tie;\n        });\n        int chosen = 0;\n        // If best delta <= 0, allow some randomness to escape local minima\n        if(cands[0].delta <= 0){\n            // with small probability pick a random candidate\n            if(rng.prob(0.15)){\n                chosen = rng.randint(0, (int)cands.size()-1);\n            }else{\n                // avoid immediate reversal if not improving\n                if(last_dir != -1 && revdir[cands[0].dir]==last_dir && cands.size()>=2){\n                    if(cands[1].delta == cands[0].delta || rng.prob(0.5)) chosen = 1;\n                }\n            }\n        }else{\n            // improving move, but avoid immediate reversal when tie\n            if(last_dir != -1 && revdir[cands[0].dir]==last_dir && cands.size()>=2 && cands[1].delta==cands[0].delta){\n                if(rng.prob(0.5)) chosen = 1;\n            }\n        }\n        apply_move(cands[chosen].dir);\n    }\n\n    // Output\n    cout<<moves<<\"\\n\";\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Sig {\n    uint64_t a=0, b=0;\n    bool operator==(Sig const& o) const { return a==o.a && b==o.b; }\n};\nstruct SigHash {\n    size_t operator()(Sig const& s) const noexcept {\n        uint64_t x = s.a * 0x9E3779B97F4A7C15ULL ^ (s.b + 0x9E3779B97F4A7C15ULL + (s.a<<6) + (s.a>>2));\n        return (size_t)x;\n    }\n};\n\nstruct Point { int x,y; };\n\nstruct LineParam {\n    int A, B;         // gcd=1\n    long long T;      // threshold strictly between projections\n};\n\nstatic inline long long dotAB(int A,int B,int x,int y){ return (long long)A*x + (long long)B*y; }\n\nstatic long long egcd(long long a, long long b, long long &x, long long &y){\n    if(b==0){ x = (a>=0?1:-1); y=0; return llabs(a); }\n    long long x1,y1;\n    long long g = egcd(b, a%b, x1, y1);\n    x = y1;\n    y = x1 - (a/b) * y1;\n    return g;\n}\n\nstatic inline void reduce_coprime(int &A, int &B){\n    if(A==0 && B==0){ A=1; B=0; return; }\n    if(A==0){ B = (B>0?1:-1); return; }\n    if(B==0){ A = (A>0?1:-1); return; }\n    int g = std::gcd(abs(A),abs(B));\n    A/=g; B/=g;\n    if(A<0){ A=-A; B=-B; }\n    else if(A==0 && B<0){ B=-B; }\n}\n\nstatic inline pair<long long,long long> clip2(long long x, long long y){\n    auto clip = [](long long v){\n        if(v < -1000000000LL) return -1000000000LL;\n        if(v > 1000000000LL) return 1000000000LL;\n        return v;\n    };\n    return {clip(x), clip(y)};\n}\n\n// Get two integer points on line A x + B y = T.\nstatic inline pair<pair<long long,long long>, pair<long long,long long>>\ntwo_points_on_line(int A, int B, long long T){\n    long long x0,y0;\n    long long g = egcd(A,B,x0,y0);\n    if(g<0){ g=-g; x0=-x0; y0=-y0; }\n    // gcd should be 1 for our construction, but handle anyway:\n    long long mul = T / g;\n    __int128 xi = (__int128)x0 * mul;\n    __int128 yi = (__int128)y0 * mul;\n    long long X = (long long)xi;\n    long long Y = (long long)yi;\n\n    // second point by parameter k\n    // choose moderate k to avoid overflow\n    long long kk = 100000; // 1e5\n    long long X2 = X + (long long)B * kk;\n    long long Y2 = Y - (long long)A * kk;\n\n    auto p1 = clip2(X,Y);\n    auto p2 = clip2(X2,Y2);\n    if(p1==p2){\n        kk = 1;\n        X2 = X + (long long)B * kk;\n        Y2 = Y - (long long)A * kk;\n        p2 = clip2(X2,Y2);\n        if(p1==p2){\n            kk = 2;\n            X2 = X + (long long)B * kk;\n            Y2 = Y - (long long)A * kk;\n            p2 = clip2(X2,Y2);\n        }\n    }\n    return {p1,p2};\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, K;\n    if(!(cin>>N>>K)) return 0;\n    vector<int> a(11);\n    for(int d=1; d<=10; ++d) cin>>a[d];\n    vector<Point> pts(N);\n    for(int i=0;i<N;++i){ cin>>pts[i].x>>pts[i].y; }\n\n    // Base normals: small coprime pairs\n    vector<pair<int,int>> baseNormals = {\n        {1,0},{0,1},{1,1},{1,-1},{2,1},{1,2},{2,-1},{1,-2},\n        {3,1},{1,3},{3,2},{2,3},{3,-1},{1,-3},{3,-2},{2,-3},\n        {4,1},{1,4},{4,3},{3,4},{5,2},{2,5}\n    };\n    for(auto &p: baseNormals) reduce_coprime(p.first, p.second);\n    sort(baseNormals.begin(), baseNormals.end());\n    baseNormals.erase(unique(baseNormals.begin(), baseNormals.end()), baseNormals.end());\n\n    // signatures and containers\n    vector<Sig> sig(N);\n    unordered_map<Sig, vector<int>, SigHash> cells;\n    vector<int> bd(11,0);\n\n    auto recompute_cells = [&](){\n        cells.clear();\n        cells.reserve(N*2);\n        for(int i=0;i<N;++i) cells[sig[i]].push_back(i);\n        fill(bd.begin(), bd.end(), 0);\n        for(auto &kv: cells){\n            int s = (int)kv.second.size();\n            if(s<=10) bd[s]++;\n        }\n    };\n    recompute_cells();\n\n    vector<LineParam> lines;\n    lines.reserve(K);\n\n    int cutsLeft = K;\n    vector<long long> proj; proj.reserve(N);\n\n    auto all_satisfied = [&](){\n        for(int d=1; d<=10; ++d) if(bd[d] < a[d]) return false;\n        return true;\n    };\n\n    // main loop\n    while(cutsLeft > 0){\n        if(all_satisfied()) break;\n\n        vector<int> need(11,0);\n        int totalNeed=0;\n        for(int d=1; d<=10; ++d){ need[d] = max(0, a[d]-bd[d]); totalNeed += need[d]; }\n\n        // Gather candidate cells: top by size\n        vector<pair<int,Sig>> cands;\n        cands.reserve(cells.size());\n        for(auto &kv: cells){\n            cands.emplace_back((int)kv.second.size(), kv.first);\n        }\n        if(cands.empty()) break;\n        sort(cands.begin(), cands.end(), [](auto &L, auto &R){ return L.first > R.first; });\n        int consider = min<int>((int)cands.size(), 12);\n\n        long long bestScore = LLONG_MIN;\n        LineParam bestLine{1,0,0};\n        bool found = false;\n\n        for(int ci=0; ci<consider; ++ci){\n            int s = cands[ci].first;\n            const Sig &ss = cands[ci].second;\n            auto &idxs = cells[ss];\n            if(s<=1) continue;\n\n            // compute PCA-based normals for this cell\n            long double meanx=0, meany=0;\n            for(int id: idxs){ meanx += pts[id].x; meany += pts[id].y; }\n            meanx /= s; meany /= s;\n            long double cxx=0, cxy=0, cyy=0;\n            for(int id: idxs){\n                long double dx = (long double)pts[id].x - meanx;\n                long double dy = (long double)pts[id].y - meany;\n                cxx += dx*dx; cxy += dx*dy; cyy += dy*dy;\n            }\n            // principal axis via eigenvector of covariance matrix\n            long double tr = cxx + cyy;\n            long double det = cxx*cyy - cxy*cxy;\n            long double tmp = max((long double)0.0L, tr*tr/4 - det);\n            long double l1 = tr/2 + sqrtl(tmp); // largest eigenvalue\n            long double vx, vy;\n            if(fabsl(cxy) > 1e-12L){\n                vx = l1 - cyy;\n                vy = cxy;\n            } else {\n                // covariance nearly diagonal\n                if(cxx >= cyy){ vx = 1; vy = 0; }\n                else { vx = 0; vy = 1; }\n            }\n            long double normv = sqrtl(vx*vx + vy*vy);\n            if(normv < 1e-18L){ vx=1; vy=0; normv=1; }\n            vx /= normv; vy /= normv;\n            // normals are perpendicular to direction vector\n            long double nx1 = -vy, ny1 = vx;\n            long double nx2 = vy, ny2 = -vx;\n            auto to_small_int = [&](long double nx, long double ny)->pair<int,int>{\n                // Scale and round to small integers then reduce\n                long double sscale = 10.0L; // limit components roughly within 10\n                int A = (int)llround(nx*sscale);\n                int B = (int)llround(ny*sscale);\n                if(A==0 && B==0){\n                    if(fabsl(nx) > fabsl(ny)) A = (nx>=0?1:-1);\n                    else B = (ny>=0?1:-1);\n                }\n                reduce_coprime(A,B);\n                // Cap to max |A|,|B| <= 20\n                if(abs(A)>20 || abs(B)>20){\n                    // scale down to within cap by dividing\n                    int g = max(abs(A),abs(B));\n                    int k = (g+19)/20;\n                    A /= k; B /= k; if(A==0 && B==0){ A=1; B=0; }\n                    reduce_coprime(A,B);\n                }\n                return {A,B};\n            };\n            pair<int,int> pcaN1 = to_small_int(nx1, ny1);\n            pair<int,int> pcaN2 = to_small_int(nx2, ny2);\n\n            // Build normals to try: base + two PCA normals\n            static vector<pair<int,int>> normals;\n            normals.clear();\n            normals.insert(normals.end(), baseNormals.begin(), baseNormals.end());\n            normals.push_back(pcaN1);\n            normals.push_back(pcaN2);\n            // dedup\n            sort(normals.begin(), normals.end());\n            normals.erase(unique(normals.begin(), normals.end()), normals.end());\n\n            // Prepare demanded sizes list\n            vector<int> demandSizes;\n            demandSizes.reserve(16);\n            for(int d=1; d<=10; ++d) if(need[d]>0) demandSizes.push_back(d);\n            if(demandSizes.empty()){\n                for(int d=1; d<=10; ++d) demandSizes.push_back(d); // fallback\n            }\n\n            // Evaluate each normal\n            for(auto [A,B] : normals){\n                proj.resize(s);\n                for(int i=0;i<s;++i){\n                    const auto &p = pts[idxs[i]];\n                    proj[i] = dotAB(A,B,p.x,p.y);\n                }\n                sort(proj.begin(), proj.end());\n                // Build candidate left sizes\n                vector<int> Lcand;\n                // median\n                Lcand.push_back(s/2);\n                // quantiles\n                Lcand.push_back(max(1, s/3));\n                Lcand.push_back(max(1, (2*s)/3));\n                // sizes from demand\n                for(int d: demandSizes){\n                    if(d < s) Lcand.push_back(d);\n                    if(s-d >= 1 && s-d < s) Lcand.push_back(s-d);\n                }\n                // bounds\n                for(int &v: Lcand){ if(v<1) v=1; if(v>s-1) v=s-1; }\n                sort(Lcand.begin(), Lcand.end());\n                Lcand.erase(unique(Lcand.begin(), Lcand.end()), Lcand.end());\n\n                for(int l : Lcand){\n                    int i = l-1;\n                    if(i<0 || i+1>=s) continue;\n                    long long vL = proj[i], vR = proj[i+1];\n                    if(vL >= vR){\n                        // find nearest gap\n                        int il=i, ir=i+1;\n                        while(il>=0 && proj[il]==vL) --il;\n                        while(ir<s && proj[ir]==vR) ++ir;\n                        bool moved=false;\n                        if(il>=0 && proj[il] < proj[il+1]){ vL = proj[il]; vR = proj[il+1]; l = il+1; moved=true; }\n                        if(!moved && ir<s && proj[ir-1] < proj[ir]){ vL = proj[ir-1]; vR = proj[ir]; l = ir; moved=true; }\n                        if(!moved) continue;\n                    }\n                    long long T = (vL + vR) / 2;\n                    int leftSize = l;\n                    int rightSize = s - l;\n\n                    // compute local delta\n                    auto minA = [&](int d, int b){ return min(a[d], b); };\n                    long long delta = 0;\n                    if(leftSize<=10) delta += minA(leftSize, bd[leftSize]+1) - minA(leftSize, bd[leftSize]);\n                    else delta += -1; // penalize creation of >10 slightly\n\n                    if(rightSize<=10) delta += minA(rightSize, bd[rightSize]+1) - minA(rightSize, bd[rightSize]);\n                    else delta += -1;\n\n                    if(s<=10) delta += minA(s, bd[s]-1) - minA(s, bd[s]);\n\n                    // extra penalties: avoid oversupply sizes\n                    long long overs = 0;\n                    if(leftSize<=10 && bd[leftSize] >= a[leftSize]) overs -= 1;\n                    if(rightSize<=10 && bd[rightSize] >= a[rightSize]) overs -= 1;\n\n                    long long balanceScore = - llabs(leftSize - rightSize);\n                    long long score = (delta<<24) + (overs<<10) + balanceScore;\n\n                    if(score > bestScore){\n                        bestScore = score;\n                        bestLine = {A,B,T};\n                        found = true;\n                    }\n                }\n            }\n        }\n\n        if(!found){\n            // Fallback: split largest cell by x-median\n            auto &idxs = cells[cands[0].second];\n            int s = (int)idxs.size();\n            proj.resize(s);\n            int A=1,B=0;\n            for(int i=0;i<s;++i) proj[i] = pts[idxs[i]].x;\n            sort(proj.begin(), proj.end());\n            long long T = (proj[s/2 - 1] + proj[s/2]) / 2;\n            bestLine = {A,B,T};\n        }\n\n        // Commit line\n        int bitIndex = (int)lines.size();\n        lines.push_back(bestLine);\n        for(int i=0;i<N;++i){\n            long long v = dotAB(bestLine.A, bestLine.B, pts[i].x, pts[i].y);\n            bool left = (v <= bestLine.T);\n            if(bitIndex < 64){\n                if(left) sig[i].a |= (1ULL<<bitIndex);\n            }else{\n                int bi = bitIndex-64;\n                if(left) sig[i].b |= (1ULL<<bi);\n            }\n        }\n        recompute_cells();\n        cutsLeft--;\n    }\n\n    // Output\n    cout << (int)lines.size() << \"\\n\";\n    for(auto &L : lines){\n        auto pp = two_points_on_line(L.A, L.B, L.T);\n        auto [p0, p1] = pp;\n        cout << p0.first << \" \" << p0.second << \" \" << p1.first << \" \" << p1.second << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct P { int x,y; };\n\nstatic inline int64_t w_of(int x,int y,int c){\n    int dx=x-c, dy=y-c;\n    return int64_t(dx)*dx + int64_t(dy)*dy + 1;\n}\n\nstruct Candidate{\n    // rectangle in order: p1=new point, then others around perimeter\n    P p1,p2,p3,p4;\n    int64_t score;\n};\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    vector<P> init(M);\n    for(int i=0;i<M;i++){ cin>>init[i].x>>init[i].y; }\n    int c=(N-1)/2;\n\n    // Occupancy grid\n    vector<vector<char>> occ(N, vector<char>(N, 0));\n    for(auto &p:init) occ[p.x][p.y]=1;\n\n    // Edge usage: used horizontal edges H[y][x] for (x,y)-(x+1,y), x in [0..N-2], y in [0..N-1]\n    vector<vector<char>> usedH(N, vector<char>(N-1, 0));\n    // Vertical edges V[x][y] for (x,y)-(x,y+1), x in [0..N-1], y in [0..N-2]\n    vector<vector<char>> usedV(N, vector<char>(N-1, 0));\n\n    // Maintain list of occupied points per row/col for faster enumeration\n    vector<vector<int>> rows(N), cols(N);\n    auto rebuild_index = [&](){\n        for(int y=0;y<N;y++){ rows[y].clear(); }\n        for(int x=0;x<N;x++){ cols[x].clear(); }\n        for(int x=0;x<N;x++) for(int y=0;y<N;y++) if(occ[x][y]){\n            rows[y].push_back(x);\n            cols[x].push_back(y);\n        }\n        for(int y=0;y<N;y++) sort(rows[y].begin(), rows[y].end());\n        for(int x=0;x<N;x++) sort(cols[x].begin(), cols[x].end());\n    };\n    rebuild_index();\n\n    // Candidate generation full enumeration (axis-aligned):\n    auto build_candidates = [&](vector<Candidate>& out){\n        out.clear();\n        const size_t CAP = 40000;\n        for(int xb=0; xb<N; xb++){\n            for(int yb=0; yb<N; yb++){\n                if(!occ[xb][yb]) continue;\n                const auto& row = rows[yb];\n                const auto& col = cols[xb];\n                if(row.empty() || col.empty()) continue;\n                for(int xa : row){\n                    if(xa==xb) continue;\n                    for(int yc : col){\n                        if(yc==yb) continue;\n                        int xd = xa;\n                        int yd = yc;\n                        if(occ[xd][yd]) continue;\n                        // define rectangle order p1=D, p2=A, p3=B, p4=C:\n                        P D{xd,yd}, A{xa,yb}, B{xb,yb}, C{xb,yc};\n                        // perimeter dot check\n                        auto ok_line = [&](int x1,int y1,int x2,int y2)->bool{\n                            if(x1==x2){\n                                int x=x1;\n                                int ylo=min(y1,y2), yhi=max(y1,y2);\n                                for(int y=ylo; y<=yhi; y++){\n                                    if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                                    if(occ[x][y]) return false;\n                                }\n                            }else if(y1==y2){\n                                int y=y1;\n                                int xlo=min(x1,x2), xhi=max(x1,x2);\n                                for(int x=xlo; x<=xhi; x++){\n                                    if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                                    if(occ[x][y]) return false;\n                                }\n                            }else{\n                                return false;\n                            }\n                            return true;\n                        };\n                        if(!ok_line(D.x,D.y,A.x,A.y)) continue;\n                        if(!ok_line(A.x,A.y,B.x,B.y)) continue;\n                        if(!ok_line(B.x,B.y,C.x,C.y)) continue;\n                        if(!ok_line(C.x,C.y,D.x,D.y)) continue;\n                        // edge overlap check without marking now\n                        auto edges_free = [&]()->bool{\n                            auto check_edge = [&](int x1,int y1,int x2,int y2)->bool{\n                                if(x1==x2){\n                                    int x=x1;\n                                    int ylo=min(y1,y2), yhi=max(y1,y2);\n                                    for(int y=ylo; y<yhi; y++) if(usedV[x][y]) return false;\n                                }else{\n                                    int y=y1;\n                                    int xlo=min(x1,x2), xhi=max(x1,x2);\n                                    for(int x=xlo; x<xhi; x++) if(usedH[y][x]) return false;\n                                }\n                                return true;\n                            };\n                            return check_edge(D.x,D.y,A.x,A.y) && check_edge(A.x,A.y,B.x,B.y)\n                                && check_edge(B.x,B.y,C.x,C.y) && check_edge(C.x,C.y,D.x,D.y);\n                        };\n                        if(!edges_free()) continue;\n                        Candidate cand;\n                        cand.p1=D; cand.p2=A; cand.p3=B; cand.p4=C;\n                        cand.score = w_of(D.x,D.y,c);\n                        out.push_back(cand);\n                        if(out.size() >= CAP) return;\n                    }\n                }\n            }\n        }\n    };\n\n    vector<array<int,8>> answer;\n    answer.reserve(100000);\n\n    auto apply_rect = [&](const Candidate& cand){\n        const P &D=cand.p1, &A=cand.p2, &B=cand.p3, &C=cand.p4;\n        // Mark edges\n        auto mark_edge = [&](int x1,int y1,int x2,int y2){\n            if(x1==x2){\n                int x=x1;\n                int ylo=min(y1,y2), yhi=max(y1,y2);\n                for(int y=ylo; y<yhi; y++) usedV[x][y]=1;\n            }else{\n                int y=y1;\n                int xlo=min(x1,x2), xhi=max(x1,x2);\n                for(int x=xlo; x<xhi; x++) usedH[y][x]=1;\n            }\n        };\n        mark_edge(D.x,D.y,A.x,A.y);\n        mark_edge(A.x,A.y,B.x,B.y);\n        mark_edge(B.x,B.y,C.x,C.y);\n        mark_edge(C.x,C.y,D.x,D.y);\n        // Place dot\n        occ[D.x][D.y]=1;\n        rows[D.y].push_back(D.x);\n        cols[D.x].push_back(D.y);\n        // Record\n        array<int,8> op = {D.x,D.y, A.x,A.y, B.x,B.y, C.x,C.y};\n        answer.push_back(op);\n    };\n\n    // Main greedy loop\n    auto t_start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.8; // seconds\n    int iter = 0;\n    while(true){\n        if(iter % 10 == 0){\n            auto t_now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(t_now - t_start).count();\n            if(elapsed > TIME_LIMIT) break;\n        }\n        if(iter % 50 == 0) rebuild_index();\n\n        vector<Candidate> cands;\n        build_candidates(cands);\n        if(cands.empty()) break;\n        // sort by score descending, minor tiebreaker by perimeter length\n        stable_sort(cands.begin(), cands.end(), [&](const Candidate& a, const Candidate& b){\n            if(a.score != b.score) return a.score > b.score;\n            int per_a = abs(a.p1.x - a.p3.x) + abs(a.p1.y - a.p3.y) + abs(a.p2.x - a.p4.x) + abs(a.p2.y - a.p4.y);\n            int per_b = abs(b.p1.x - b.p3.x) + abs(b.p1.y - b.p3.y) + abs(b.p2.x - b.p4.x) + abs(b.p2.y - b.p4.y);\n            return per_a > per_b;\n        });\n        bool placed = false;\n        for(const auto& cand : cands){\n            const P &D=cand.p1, &A=cand.p2, &B=cand.p3, &C=cand.p4;\n            if(occ[D.x][D.y]) continue;\n            // recheck perimeter cleanliness and edges\n            auto ok_line = [&](int x1,int y1,int x2,int y2)->bool{\n                if(x1==x2){\n                    int x=x1;\n                    int ylo=min(y1,y2), yhi=max(y1,y2);\n                    for(int y=ylo; y<=yhi; y++){\n                        if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                        if(occ[x][y]) return false;\n                    }\n                }else if(y1==y2){\n                    int y=y1;\n                    int xlo=min(x1,x2), xhi=max(x1,x2);\n                    for(int x=xlo; x<=xhi; x++){\n                        if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                        if(occ[x][y]) return false;\n                    }\n                }else{\n                    return false;\n                }\n                return true;\n            };\n            if(!ok_line(D.x,D.y,A.x,A.y)) continue;\n            if(!ok_line(A.x,A.y,B.x,B.y)) continue;\n            if(!ok_line(B.x,B.y,C.x,C.y)) continue;\n            if(!ok_line(C.x,C.y,D.x,D.y)) continue;\n\n            auto edges_free = [&]()->bool{\n                auto check_edge = [&](int x1,int y1,int x2,int y2)->bool{\n                    if(x1==x2){\n                        int x=x1;\n                        int ylo=min(y1,y2), yhi=max(y1,y2);\n                        for(int y=ylo; y<yhi; y++) if(usedV[x][y]) return false;\n                    }else{\n                        int y=y1;\n                        int xlo=min(x1,x2), xhi=max(x1,x2);\n                        for(int x=xlo; x<xhi; x++) if(usedH[y][x]) return false;\n                    }\n                    return true;\n                };\n                return check_edge(D.x,D.y,A.x,A.y) && check_edge(A.x,A.y,B.x,B.y)\n                    && check_edge(B.x,B.y,C.x,C.y) && check_edge(C.x,C.y,D.x,D.y);\n            };\n            if(!edges_free()) continue;\n\n            apply_rect(cand);\n            placed = true;\n            break;\n        }\n        if(!placed) break;\n        iter++;\n    }\n\n    cout<< (int)answer.size() << \"\\n\";\n    for(auto &op: answer){\n        for(int i=0;i<8;i++){\n            if(i) cout<<' ';\n            cout<<op[i];\n        }\n        cout<<\"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Board {\n    static constexpr int H=10, W=10;\n    array<array<int,W>,H> g{};\n    void clear(){ for(int i=0;i<H;i++) for(int j=0;j<W;j++) g[i][j]=0; }\n\n    pair<int,int> place_by_index(int p, int f){\n        int cnt=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                if(g[i][j]==0){\n                    ++cnt;\n                    if(cnt==p){\n                        g[i][j]=f;\n                        return {i,j};\n                    }\n                }\n            }\n        }\n        return {-1,-1};\n    }\n\n    Board tilt(char dir) const {\n        Board b=*this;\n        if(dir=='F'){ // up\n            for(int j=0;j<W;j++){\n                int w=0;\n                for(int i=0;i<H;i++){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        b.g[i][j]=0;\n                        b.g[w][j]=v;\n                        ++w;\n                    }\n                }\n            }\n        } else if(dir=='B'){ // down\n            for(int j=0;j<W;j++){\n                int w=H-1;\n                for(int i=H-1;i>=0;i--){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        b.g[i][j]=0;\n                        b.g[w][j]=v;\n                        --w;\n                    }\n                }\n            }\n        } else if(dir=='L'){ // left\n            for(int i=0;i<H;i++){\n                int w=0;\n                for(int j=0;j<W;j++){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        b.g[i][j]=0;\n                        b.g[i][w]=v;\n                        ++w;\n                    }\n                }\n            }\n        } else { // 'R' right\n            for(int i=0;i<H;i++){\n                int w=W-1;\n                for(int j=W-1;j>=0;j--){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        b.g[i][j]=0;\n                        b.g[i][w]=v;\n                        --w;\n                    }\n                }\n            }\n        }\n        return b;\n    }\n\n    bool equals(const Board& o) const {\n        for(int i=0;i<H;i++) for(int j=0;j<W;j++) if(g[i][j]!=o.g[i][j]) return false;\n        return true;\n    }\n};\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    DSU(int n=0): n(n), p(n), r(n,0){ iota(p.begin(), p.end(), 0); }\n    int find(int a){ return p[a]==a?a:p[a]=find(p[a]); }\n    void unite(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a; if(r[a]==r[b]) r[a]++;\n    }\n};\n\nstruct Heuristic {\n    // anchors per flavor 1..3\n    array<pair<int,int>,4> anchor;\n    // edge preference masks per flavor: want proximity to these edges\n    // store desired edges as booleans for top, bottom, left, right\n    array<array<int,4>,4> edgePref{}; // weights for edges [T,B,L,R]\n    // weights\n    int w_adj_same = 6;\n    int w_adj_diff = 3;\n    int w_dist = 1;\n    int w_boundaries = 4;   // penalize number of color boundaries per line\n    int w_cc = 15;          // penalize number of connected components per flavor\n    int w_edge = 2;         // reward presence on preferred edges\n    int w_corner = 1;       // slight bonus near anchor radius small\n\n    Heuristic() {\n        // default anchors; will be overridden by setup\n        anchor[1] = {0,0};\n        anchor[2] = {0,9};\n        anchor[3] = {9,4};\n        // default edge prefs: f1 top+left, f2 top+right, f3 bottom\n        edgePref[1] = {1,0,1,0};\n        edgePref[2] = {1,0,0,1};\n        edgePref[3] = {0,1,0,0};\n    }\n\n    void setup_anchors_by_counts(const array<int,4>& cnt){\n        // Sort flavors by count descending, assign to corners:\n        // largest -> top-left, 2nd -> top-right, 3rd -> bottom (center)\n        array<int,3> ids = {1,2,3};\n        sort(ids.begin(), ids.end(), [&](int a,int b){ return cnt[a]>cnt[b]; });\n        int fA=ids[0], fB=ids[1], fC=ids[2];\n        anchor[fA] = {0,0};\n        anchor[fB] = {0,9};\n        anchor[fC] = {9,4};\n        edgePref[fA] = {1,0,1,0};\n        edgePref[fB] = {1,0,0,1};\n        edgePref[fC] = {0,1,0,0};\n    }\n\n    int adj_score(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int same=0, diff=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                if(i+1<H && b.g[i+1][j]){\n                    if(b.g[i+1][j]==v) same++; else diff++;\n                }\n                if(j+1<W && b.g[i][j+1]){\n                    if(b.g[i][j+1]==v) same++; else diff++;\n                }\n            }\n        }\n        return w_adj_same*same - w_adj_diff*diff;\n    }\n\n    int distance_score(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                auto [ai,aj]=anchor[v];\n                sc -= w_dist * (abs(i-ai)+abs(j-aj));\n                // small corner bonus for being near anchor\n                int d = abs(i-ai)+abs(j-aj);\n                if(d<=2) sc += w_corner*(3-d);\n            }\n        }\n        return sc;\n    }\n\n    int boundaries_penalty(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int boundaries=0;\n        // rows\n        for(int i=0;i<H;i++){\n            int prev = 0;\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(prev && v && v!=prev) boundaries++;\n                if(v) prev=v;\n            }\n        }\n        // cols\n        for(int j=0;j<W;j++){\n            int prev = 0;\n            for(int i=0;i<H;i++){\n                int v=b.g[i][j];\n                if(prev && v && v!=prev) boundaries++;\n                if(v) prev=v;\n            }\n        }\n        return -w_boundaries * boundaries;\n    }\n\n    int cc_penalty(const Board& b) const {\n        // compute connected components per flavor\n        int H=Board::H, W=Board::W;\n        int F=H*W;\n        DSU dsu(F);\n        auto id = [&](int i,int j){ return i*W + j; };\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                if(i+1<H && b.g[i+1][j]==v) dsu.unite(id(i,j), id(i+1,j));\n                if(j+1<W && b.g[i][j+1]==v) dsu.unite(id(i,j), id(i,j+1));\n            }\n        }\n        array<unordered_set<int>,4> reps;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                reps[v].insert(dsu.find(id(i,j)));\n            }\n        }\n        int cc = (int)reps[1].size() + (int)reps[2].size() + (int)reps[3].size();\n        return -w_cc * cc;\n    }\n\n    int edge_reward(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                auto pref = edgePref[v];\n                if(i==0) sc += w_edge * pref[0];\n                if(i==H-1) sc += w_edge * pref[1];\n                if(j==0) sc += w_edge * pref[2];\n                if(j==W-1) sc += w_edge * pref[3];\n            }\n        }\n        return sc;\n    }\n\n    int score(const Board& b) const {\n        int s = 0;\n        s += adj_score(b);\n        s += distance_score(b);\n        s += boundaries_penalty(b);\n        s += cc_penalty(b);\n        s += edge_reward(b);\n        return s;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> f(100);\n    for(int i=0;i<100;i++){\n        if(!(cin>>f[i])) return 0;\n    }\n    // Estimate total counts per flavor\n    array<int,4> cnt{}; cnt.fill(0);\n    for(int i=0;i<100;i++) cnt[f[i]]++;\n    Board board; board.clear();\n    Heuristic H;\n    H.setup_anchors_by_counts(cnt);\n\n    const array<char,4> dirs = {'F','B','L','R'};\n    char lastMove = 'F';\n\n    for(int t=0;t<100;t++){\n        int p;\n        if(!(cin>>p)) return 0;\n        board.place_by_index(p, f[t]);\n\n        if(t==99){\n            // last tilt optional; skip\n            continue;\n        }\n\n        // 2-ply lookahead: choose first move maximizing heuristic after 2 moves\n        int bestFirstIdx = 0;\n        int bestScore = INT_MIN;\n        char bestDir = 'F';\n        Board bestBoard = board;\n\n        for(int a=0;a<4;a++){\n            char d1 = dirs[a];\n            Board b1 = board.tilt(d1);\n            int s1 = H.score(b1);\n            // if board doesn't change, we still evaluate second move\n            int bestSecond = INT_MIN;\n            for(int b=0;b<4;b++){\n                char d2 = dirs[b];\n                Board b2 = b1.tilt(d2);\n                int s2 = H.score(b2);\n                bestSecond = max(bestSecond, s2);\n            }\n            // combine: emphasize the lookahead but keep immediate value small\n            int combined = bestSecond + (s1 / 8); // small immediate term\n            // prefer inertia if tie\n            int tieBias = (d1==lastMove ? 1 : 0);\n            if(combined > bestScore || (combined==bestScore && tieBias)){\n                bestScore = combined;\n                bestDir = d1;\n                bestBoard = b1;\n                bestFirstIdx = a;\n            }\n        }\n\n        cout << bestDir << '\\n' << flush;\n        lastMove = bestDir;\n        board = bestBoard;\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\n\nusing ull = unsigned long long;\n\nstruct XorShift64 {\n    uint64_t x;\n    XorShift64(uint64_t s=88172645463393265ull){ if(!s) s=1; x=s; }\n    uint64_t rng(){ uint64_t y=x; y^=y<<7; y^=y>>9; return x=y; }\n    double drand(){ return (rng() >> 11) * (1.0/9007199254740992.0); } // [0,1)\n    int irand(int L,int R){ return L + (int)(rng() % (uint64_t)(R-L+1)); }\n};\n\nstatic inline int idx_pair(int N,int i,int j){ // i<j\n    return i*N - i*(i+1)/2 + (j - i - 1);\n}\n\nstruct Features {\n    vector<double> deg_hist; // size N, normalized\n    vector<int> deg_sorted;  // size N\n    vector<double> eig; // top T eigenvalues (by abs, normalized)\n    vector<double> nbrdeg_hist; // histogram bins\n};\n\nstruct Template {\n    vector<uint8_t> bits; // length N(N-1)/2\n    vector<int> deg;\n    Features feat;\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double eps;\n    if(!(cin>>M>>eps)) return 0;\n\n    // Choose N heuristically\n    int N = 64;\n    if (M >= 90 && eps <= 0.08) N = 48;\n    if (eps >= 0.30) N = 80;\n    if (N > 100) N = 100;\n    if (N < 4) N = 4;\n\n    // Deterministic seed from M and eps\n    uint64_t seed = 1469598103934665603ull ^ (uint64_t)M * 1099511628211ull ^ (uint64_t)llround(eps*100.0+0.5);\n    XorShift64 gen(seed);\n\n    // Blocks for SBM-like graph generation\n    int B = 4;\n    vector<int> block(N);\n    for(int i=0;i<N;i++) block[i] = (long long)i * B / N;\n\n    auto build_template = [&](int k)->Template{\n        XorShift64 g(seed ^ (uint64_t)(0x9e3779b97f4a7c15ull * (k+1)));\n        double pmin = 0.08 + 0.02 * (g.drand());\n        double pmax = 0.92 - 0.02 * (g.drand());\n        vector<vector<double>> P(B, vector<double>(B, 0.0));\n        for(int b=0;b<B;b++){\n            for(int c=b;c<B;c++){\n                double r = g.drand();\n                double val = pmin + (pmax - pmin) * fmod(r + 0.13*(b+1) + 0.07*(c+2) + 0.037*k, 1.0);\n                if(b==c) val = 0.5*(val + min(0.98, max(0.02, val + (g.drand()-0.5)*0.4)));\n                P[b][c]=P[c][b]=min(0.98, max(0.02, val));\n            }\n        }\n        vector<double> biasB(B);\n        for(int b=0;b<B;b++){\n            biasB[b] = (g.drand()-0.5)*0.2; // [-0.1,0.1]\n        }\n\n        int Ebits = N*(N-1)/2;\n        vector<uint8_t> bits(Ebits, 0);\n        vector<int> deg(N,0);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                int bi = block[i], bj = block[j];\n                double p = P[bi][bj];\n                double vbi = biasB[bi] + 0.06 * sin((i+1)*(k+3)*0.13);\n                double vbj = biasB[bj] + 0.06 * cos((j+3)*(k+5)*0.17);\n                double adjp = p + 0.15*(vbi+vbj);\n                if(adjp < 0.01) adjp = 0.01;\n                if(adjp > 0.99) adjp = 0.99;\n                if (g.drand() < adjp){\n                    bits[idx_pair(N,i,j)] = 1;\n                    deg[i]++; deg[j]++;\n                }\n            }\n        }\n        Template T;\n        T.bits = move(bits);\n        T.deg = move(deg);\n        return T;\n    };\n\n    vector<Template> temps(M);\n    for(int k=0;k<M;k++){\n        temps[k] = build_template(k);\n    }\n\n    auto compute_features = [&](const vector<uint8_t>& bits)->pair<vector<int>, Features>{\n        Eigen::MatrixXd A(N, N);\n        A.setZero();\n        vector<int> deg(N,0);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                uint8_t v = bits[idx_pair(N,i,j)];\n                if(v){\n                    A(i,j)=A(j,i)=1.0;\n                    deg[i]++; deg[j]++;\n                }\n            }\n        }\n\n        vector<double> dh(N, 0.0);\n        for(int d:deg) dh[d] += 1.0;\n        for(double &x:dh) x /= N;\n\n        vector<int> dsort = deg;\n        sort(dsort.begin(), dsort.end());\n\n        vector<int> degNbrSum(N,0);\n        for(int i=0;i<N;i++){\n            int s=0;\n            for(int j=0;j<N;j++) if(A(i,j)>0.5) s += deg[j];\n            degNbrSum[i]=s;\n        }\n        int Hbins = 16;\n        int minv = *min_element(degNbrSum.begin(), degNbrSum.end());\n        int maxv = *max_element(degNbrSum.begin(), degNbrSum.end());\n        if (maxv==minv) maxv=minv+1;\n        vector<double> ndh(Hbins,0.0);\n        for(int v:degNbrSum){\n            int b = (int)((long long)(v - minv) * Hbins / (long long)(maxv - minv + 1));\n            if(b<0) b=0;\n            if(b>=Hbins) b=Hbins-1;\n            ndh[b] += 1.0;\n        }\n        for(double &x:ndh) x/=N;\n\n        // Eigenvalues\n        int Ttop = min(16, N);\n        vector<double> eigv;\n        eigv.reserve(Ttop);\n        {\n            Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(A); // compute eigenvalues (and vectors if requested)\n            if (es.info() == Eigen::Success) {\n                auto evals = es.eigenvalues(); // ascending\n                vector<double> all(N);\n                for(int i=0;i<N;i++) all[i] = evals(i);\n                vector<int> idx(N); iota(idx.begin(), idx.end(), 0);\n                sort(idx.begin(), idx.end(), [&](int a,int b){\n                    return fabs(all[a]) > fabs(all[b]);\n                });\n                int maxdeg = 1;\n                for(int d:deg) if(d>maxdeg) maxdeg=d;\n                double scale = sqrt((double)maxdeg);\n                if(scale == 0.0) scale = 1.0;\n                for(int t=0;t<Ttop;t++){\n                    double v = all[idx[t]] / scale;\n                    eigv.push_back(v);\n                }\n            } else {\n                // Fallback: zero eigenfeatures if solver failed\n                eigv.assign(Ttop, 0.0);\n            }\n        }\n\n        Features F;\n        F.deg_hist = move(dh);\n        F.deg_sorted = move(dsort);\n        F.eig = move(eigv);\n        F.nbrdeg_hist = move(ndh);\n        return {deg, F};\n    };\n\n    for(int k=0;k<M;k++){\n        auto [deg, F] = compute_features(temps[k].bits);\n        temps[k].deg = move(deg);\n        temps[k].feat = move(F);\n    }\n\n    auto dist_deg_fast = [&](const Features& A, const Features& B)->double{\n        double s=0.0;\n        for(size_t i=0;i<A.deg_hist.size();i++){\n            double d=A.deg_hist[i]-B.deg_hist[i];\n            s += d*d;\n        }\n        double t=0.0;\n        for(size_t i=0;i<A.deg_sorted.size();i++){\n            t += abs(A.deg_sorted[i]-B.deg_sorted[i]);\n        }\n        t /= (double)A.deg_sorted.size();\n        return 0.7*sqrt(s) + 0.3*t;\n    };\n\n    auto dist_full = [&](const Features& A, const Features& B)->double{\n        double d1=0.0;\n        for(size_t i=0;i<A.deg_hist.size();i++){ double d=A.deg_hist[i]-B.deg_hist[i]; d1+=d*d; }\n        d1 = sqrt(d1);\n        double d2=0.0;\n        size_t Ttop = min(A.eig.size(), B.eig.size());\n        for(size_t i=0;i<Ttop;i++){ double d=A.eig[i]-B.eig[i]; d2+=d*d; }\n        d2 = sqrt(d2);\n        double d3=0.0;\n        size_t Hbins = min(A.nbrdeg_hist.size(), B.nbrdeg_hist.size());\n        for(size_t i=0;i<Hbins;i++){ double d=A.nbrdeg_hist[i]-B.nbrdeg_hist[i]; d3+=d*d; }\n        d3 = sqrt(d3);\n        double d4=0.0;\n        for(size_t i=0;i<A.deg_sorted.size();i++){ d4 += abs(A.deg_sorted[i]-B.deg_sorted[i]); }\n        d4 /= (double)A.deg_sorted.size();\n        return 0.35*d1 + 0.30*d2 + 0.20*d3 + 0.15*d4;\n    };\n\n    // Output templates\n    cout<<N<<\"\\n\";\n    for(int k=0;k<M;k++){\n        int L = N*(N-1)/2;\n        string s; s.resize(L);\n        for(int i=0;i<L;i++) s[i] = temps[k].bits[i] ? '1':'0';\n        cout<<s<<\"\\n\";\n    }\n    cout.flush();\n\n    // Answer queries\n    for(int q=0;q<100;q++){\n        string Hs;\n        if(!(cin>>Hs)) return 0;\n        int L = N*(N-1)/2;\n        vector<uint8_t> Hbits(L,0);\n        for(int i=0;i<L;i++) Hbits[i] = (Hs[i]=='1');\n        auto [Hdeg, HF] = compute_features(Hbits);\n\n        int S = min(12, M);\n        vector<pair<double,int>> cand;\n        cand.reserve(M);\n        for(int k=0;k<M;k++){\n            double d = dist_deg_fast(HF, temps[k].feat);\n            cand.emplace_back(d, k);\n        }\n        nth_element(cand.begin(), cand.begin()+S, cand.end());\n        cand.resize(S);\n\n        int bestk = cand[0].second;\n        double bestd = 1e100;\n        for(auto &pr : cand){\n            int k = pr.second;\n            double d = dist_full(HF, temps[k].feat);\n            if(d < bestd){\n                bestd = d; bestk = k;\n            }\n        }\n        cout<<bestk<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge { int id, u, v; int w; };\nstruct Adj { int to, eid, w; };\n\nstruct Timer {\n    chrono::high_resolution_clock::time_point st;\n    Timer(){ reset(); }\n    void reset(){ st = chrono::high_resolution_clock::now(); }\n    double elapsed_ms() const {\n        auto now = chrono::high_resolution_clock::now();\n        return chrono::duration<double, std::milli>(now - st).count();\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Timer timer;\n    int N, M, D, K;\n    if(!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u,v,w; cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {i,u,v,w};\n    }\n    // read coordinates and ignore\n    for (int i = 0; i < N; ++i) { int x,y; cin >> x >> y; }\n\n    vector<vector<Adj>> g(N);\n    vector<int> deg(N,0);\n    for (auto &e: edges) {\n        g[e.u].push_back({e.v, e.id, e.w});\n        g[e.v].push_back({e.u, e.id, e.w});\n        deg[e.u]++; deg[e.v]++;\n    }\n\n    // Importance components\n    long long wmin = LLONG_MAX, wmax = 0;\n    for (auto &e: edges) { wmin = min<long long>(wmin, e.w); wmax = max<long long>(wmax, e.w); }\n    double denom_w = (wmax > wmin ? double(wmax - wmin) : 1.0);\n    vector<double> imp_w(M,0.0), imp_deg(M,0.0);\n    for (auto &e: edges) imp_w[e.id] = (double)(e.w - wmin) / denom_w;\n    for (auto &e: edges) {\n        double pu = 1.0 / max(1, deg[e.u]-1);\n        double pv = 1.0 / max(1, deg[e.v]-1);\n        imp_deg[e.id] = 0.5*(pu+pv);\n    }\n\n    // Betweenness-like via sampled shortest paths\n    mt19937 rng(1234567);\n    vector<int> nodes(N); iota(nodes.begin(), nodes.end(), 0);\n    shuffle(nodes.begin(), nodes.end(), rng);\n\n    int S = 28;\n    if (N <= 900) S = 26;\n    if (N <= 750) S = 24;\n    if (N <= 600) S = 22;\n    if (N <= 500) S = 20;\n    S = min(S, max(14, N/45));\n    int T = 16; // targets per source\n    if (N < 700) T = 14;\n    if (N < 550) T = 12;\n\n    vector<long long> dist(N);\n    vector<int> parent_edge(N, -1);\n    struct QN{ long long d; int v; };\n    struct Cmp{ bool operator()(const QN&a,const QN&b)const{return a.d>b.d;}};\n\n    vector<long long> bet_count(M,0);\n\n    // Sparse co-occurrence per edge\n    // We will keep at most L entries per edge with highest co-occurrence counts.\n    const int L = 12;\n    vector<unordered_map<int,int>> co_occur(M);\n    auto push_co = [&](int e1, int e2){\n        if (e1==e2) return;\n        auto &mp = co_occur[e1];\n        auto it = mp.find(e2);\n        if (it==mp.end()){\n            if ((int)mp.size() < L) {\n                mp.emplace(e2,1);\n            } else {\n                // replace smallest\n                int min_k=-1, min_v=INT_MAX;\n                for (auto &kv: mp) if (kv.second < min_v) { min_v = kv.second; min_k = kv.first; }\n                if (min_v < 2) {\n                    mp.erase(min_k);\n                    mp.emplace(e2, 1);\n                }\n                // otherwise ignore\n            }\n        } else {\n            it->second++;\n        }\n    };\n\n    vector<int> order_nodes = nodes;\n    // Pre-generate random targets\n    vector<int> targets; targets.reserve(T);\n    vector<int> path_edges; path_edges.reserve(N);\n\n    for (int si = 0; si < S && si < N; ++si) {\n        int s = order_nodes[si];\n        // Dijkstra\n        fill(dist.begin(), dist.end(), (long long)4e18);\n        fill(parent_edge.begin(), parent_edge.end(), -1);\n        priority_queue<QN, vector<QN>, Cmp> pq;\n        dist[s] = 0; pq.push({0,s});\n        while(!pq.empty()){\n            auto [dcur,v] = pq.top(); pq.pop();\n            if (dcur != dist[v]) continue;\n            for (auto &ae: g[v]){\n                int to = ae.to;\n                long long nd = dcur + ae.w;\n                if (nd < dist[to]){\n                    dist[to] = nd;\n                    parent_edge[to] = ae.eid;\n                    pq.push({nd,to});\n                }\n            }\n        }\n        // Collect tree-edge usage\n        for (int v=0; v<N; ++v) if (v!=s) {\n            int pe = parent_edge[v];\n            if (pe >= 0) bet_count[pe] += 1;\n        }\n        // Sample targets for path backtracking\n        targets.clear();\n        for (int t = 0; t < T; ++t) {\n            int v = nodes[(si*131 + t*977) % N];\n            if (v == s) v = (v+1)%N;\n            targets.push_back(v);\n        }\n        for (int tnode : targets){\n            path_edges.clear();\n            int cur = tnode;\n            int steps = 0;\n            while (cur != s && steps < N){\n                int pe = parent_edge[cur];\n                if (pe < 0) break;\n                path_edges.push_back(pe);\n                // move to parent vertex\n                int u = edges[pe].u, v = edges[pe].v;\n                cur = (cur == u ? v : u);\n                steps++;\n            }\n            int Lp = (int)path_edges.size();\n            for (int i = 0; i < Lp; ++i) {\n                int e1 = path_edges[i];\n                bet_count[e1] += 1;\n                // co-occurrence with a window to limit quadratic cost\n                for (int j = max(0, i-6); j < min(Lp, i+7); ++j) {\n                    if (i==j) continue;\n                    int e2 = path_edges[j];\n                    push_co(e1, e2);\n                }\n            }\n        }\n        if (timer.elapsed_ms() > 3500.0) break; // safety\n    }\n\n    long long betmin = LLONG_MAX, betmax = 0;\n    for (int i=0;i<M;++i){ betmin=min(betmin, bet_count[i]); betmax=max(betmax, bet_count[i]); }\n    double denom_b = (betmax>betmin? double(betmax-betmin):1.0);\n    vector<double> imp_bet(M,0.0);\n    for (int i=0;i<M;++i) imp_bet[i] = (double)(bet_count[i]-betmin)/denom_b;\n\n    // Combined score\n    double a_w = 0.35, b_dg = 0.55, c_bt = 1.15;\n    vector<double> score(M,0.0);\n    for (int i=0;i<M;++i) score[i] = a_w*imp_w[i] + b_dg*imp_deg[i] + c_bt*imp_bet[i];\n\n    vector<int> ord(M); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int i, int j){\n        if (score[i] != score[j]) return score[i] > score[j];\n        return i < j;\n    });\n\n    // Assignment with enhanced penalties\n    vector<int> day_of_edge(M, -1);\n    vector<int> load(D, 0);\n    vector<double> day_imp(D, 0.0);\n    vector<double> day_imp2(D, 0.0); // sum of squares, to penalize variance\n    vector<vector<int>> incid_on_day(N, vector<int>(D, 0));\n\n    // soft target per day\n    vector<int> target(D);\n    int base = M / D, rem = M % D;\n    for (int d=0; d<D; ++d) target[d] = min(K, base + (d<rem?1:0));\n\n    // Precompute per-vertex soft threshold\n    vector<int> v_soft(N);\n    for (int v=0; v<N; ++v) v_soft[v] = (deg[v]+D-1)/D + 1;\n\n    // coefficients\n    double alpha_adj = 1.1;\n    double beta_bal1 = 0.20;   // linear importance sum\n    double beta_bal2 = 0.20;   // quadratic to reduce variance\n    double gamma_co = 0.35;    // co-occurrence penalty\n    double soft_cap_pen = 0.25;\n\n    for (int ei : ord) {\n        int u = edges[ei].u, v = edges[ei].v;\n        int bestd = -1; double bestc = 1e100;\n        for (int d=0; d<D; ++d) {\n            if (load[d] >= K) continue;\n            // adjacency and vertex soft threshold\n            int iu = incid_on_day[u][d], iv = incid_on_day[v][d];\n            double pen_adj = alpha_adj * (iu + iv);\n            double pen_vsoft = 0.0;\n            if (iu >= v_soft[u]) pen_vsoft += (iu - v_soft[u] + 1);\n            if (iv >= v_soft[v]) pen_vsoft += (iv - v_soft[v] + 1);\n            pen_vsoft *= 0.4;\n\n            // importance balance\n            double bal = beta_bal1 * day_imp[d] + beta_bal2 * (day_imp2[d]);\n\n            // co-occurrence penalty: sum of co-occurrence with edges already placed on day d (approximate by counting incident matches via vertices)\n            double pen_co = 0.0;\n            // To avoid scanning all edges on day d, approximate by checking only co-occur map and whether those edges are assigned to d.\n            // We'll need a quick check: maintain day_of_edge; OK.\n            auto &mp = co_occur[ei];\n            int seen = 0;\n            for (auto &kv : mp) {\n                int ej = kv.first;\n                int dj = (ej < M ? day_of_edge[ej] : -1);\n                if (dj == d) {\n                    pen_co += gamma_co * kv.second;\n                    if (++seen >= 8) break; // cap\n                }\n            }\n\n            double cap_soft = (load[d] < target[d] ? 0.0 : soft_cap_pen * (load[d] - target[d] + 1));\n            double cost = pen_adj + pen_vsoft + bal + pen_co + cap_soft;\n            if (cost < bestc) { bestc = cost; bestd = d; }\n        }\n        if (bestd < 0) {\n            // pick min load day\n            int md = 0; for (int d=1; d<D; ++d) if (load[d] < load[md]) md = d;\n            bestd = md;\n        }\n        day_of_edge[ei] = bestd;\n        load[bestd]++; day_imp[bestd] += score[ei]; day_imp2[bestd] += score[ei]*score[ei];\n        incid_on_day[u][bestd]++; incid_on_day[v][bestd]++;\n    }\n\n    // Refinement: try random moves/swaps using adjacency + co-occurrence + day balance\n    auto eval_edge_on_day = [&](int ei, int d)->double{\n        int u = edges[ei].u, v = edges[ei].v;\n        double pen_adj = alpha_adj * (incid_on_day[u][d] + incid_on_day[v][d] - (day_of_edge[ei]==d?2:0));\n        double pen_vsoft = 0.0;\n        int iu = incid_on_day[u][d] - (day_of_edge[ei]==d?1:0);\n        int iv = incid_on_day[v][d] - (day_of_edge[ei]==d?1:0);\n        if (iu >= v_soft[u]) pen_vsoft += (iu - v_soft[u] + 1)*0.4;\n        if (iv >= v_soft[v]) pen_vsoft += (iv - v_soft[v] + 1)*0.4;\n        double bal = beta_bal1 * day_imp[d] + beta_bal2 * day_imp2[d];\n        double pen_co = 0.0;\n        auto &mp = co_occur[ei];\n        int seen=0;\n        for (auto &kv: mp){\n            int ej = kv.first; int dj = (ej<M? day_of_edge[ej] : -1);\n            if (dj == d) { pen_co += gamma_co * kv.second; if (++seen>=8) break; }\n        }\n        return pen_adj + pen_vsoft + bal + pen_co;\n    };\n\n    double refine_budget_ms = 1800.0;\n    if (timer.elapsed_ms() > 4200.0) refine_budget_ms = 800.0;\n    Timer t2;\n    int iters = 0;\n    uniform_int_distribution<int> distE(0, M-1);\n    while (t2.elapsed_ms() < refine_budget_ms && iters < 300000) {\n        ++iters;\n        int ei = distE(rng);\n        int di = day_of_edge[ei];\n        double cur_cost_i = eval_edge_on_day(ei, di);\n        int bestd = di;\n        double best_gain = 0.0;\n        for (int d=0; d<D; ++d) {\n            if (d==di) continue;\n            if (load[d] >= K) continue;\n            double new_cost = eval_edge_on_day(ei, d);\n            // approximate day balance change for both days with score effect\n            double delta_bal = 0.0;\n            // Remove from di\n            double impi = score[ei];\n            double old_di = beta_bal1 * day_imp[di] + beta_bal2 * day_imp2[di];\n            double new_di = beta_bal1 * (day_imp[di] - impi) + beta_bal2 * (day_imp2[di] - impi*impi);\n            // Add to d\n            double old_d = beta_bal1 * day_imp[d] + beta_bal2 * day_imp2[d];\n            double new_d = beta_bal1 * (day_imp[d] + impi) + beta_bal2 * (day_imp2[d] + impi*impi);\n            delta_bal = (new_di + new_d) - (old_di + old_d);\n            double gain = (cur_cost_i - new_cost) + (-delta_bal);\n            if (gain > best_gain) { best_gain = gain; bestd = d; }\n        }\n        if (bestd != di && best_gain > 1e-9) {\n            int u = edges[ei].u, v = edges[ei].v;\n            // commit move\n            // update structures\n            incid_on_day[u][di]--; incid_on_day[v][di]--;\n            incid_on_day[u][bestd]++; incid_on_day[v][bestd]++;\n            load[di]--; load[bestd]++;\n            day_imp[di] -= score[ei]; day_imp2[di] -= score[ei]*score[ei];\n            day_imp[bestd] += score[ei]; day_imp2[bestd] += score[ei]*score[ei];\n            day_of_edge[ei] = bestd;\n        }\n    }\n\n    // Output 1-based days\n    for (int i=0;i<M;++i){\n        int d = day_of_edge[i];\n        if (d<0) d = i % D;\n        cout << (d+1) << (i+1==M?'\\n':' ');\n    }\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D;\n    if (!(cin >> D)) return 0;\n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    for (int i = 0; i < 2; ++i) {\n        for (int z = 0; z < D; ++z) cin >> f[i][z];\n        for (int z = 0; z < D; ++z) cin >> r[i][z];\n    }\n    int N = D*D*D;\n    auto idx = [&](int x,int y,int z){ return x*D*D + y*D + z; };\n    vector<char> M1(N,0), M2(N,0);\n    for (int x=0;x<D;++x){\n        for (int y=0;y<D;++y){\n            for (int z=0;z<D;++z){\n                if (f[0][z][x]=='1' && r[0][z][y]=='1') M1[idx(x,y,z)]=1;\n                if (f[1][z][x]=='1' && r[1][z][y]=='1') M2[idx(x,y,z)]=1;\n            }\n        }\n    }\n    vector<char> C(N,0), O1(N,0), O2(N,0);\n    for (int i=0;i<N;++i){\n        if (M1[i] && M2[i]) C[i]=1;\n        else if (M1[i]) O1[i]=1;\n        else if (M2[i]) O2[i]=1;\n    }\n\n    // BFS for components\n    auto neighbors = [&](int x,int y,int z, array<int,6>& out)->int{\n        // We'll store as packed ints separately; but for BFS we can compute inline\n        return 0;\n    };\n\n    vector<int> b1(N,0), b2(N,0);\n    int nBlocks = 0;\n\n    auto process_components = [&](vector<char>& mark, bool place1, bool place2){\n        vector<char> vis(N,0);\n        int dx[6]={1,-1,0,0,0,0};\n        int dy[6]={0,0,1,-1,0,0};\n        int dz[6]={0,0,0,0,1,-1};\n        for (int x=0;x<D;++x){\n            for (int y=0;y<D;++y){\n                for (int z=0;z<D;++z){\n                    int s = idx(x,y,z);\n                    if (!mark[s] || vis[s]) continue;\n                    // start new component\n                    ++nBlocks;\n                    queue<int> q;\n                    q.push(s);\n                    vis[s]=1;\n                    // assign\n                    if (place1) b1[s]=nBlocks;\n                    if (place2) b2[s]=nBlocks;\n                    while(!q.empty()){\n                        int v=q.front(); q.pop();\n                        int vx = v/(D*D);\n                        int rem = v%(D*D);\n                        int vy = rem/D;\n                        int vz = rem% D;\n                        for (int dir=0;dir<6;++dir){\n                            int nx = vx+dx[dir], ny=vy+dy[dir], nz=vz+dz[dir];\n                            if (nx<0||nx>=D||ny<0||ny>=D||nz<0||nz>=D) continue;\n                            int u = idx(nx,ny,nz);\n                            if (mark[u] && !vis[u]){\n                                vis[u]=1;\n                                q.push(u);\n                                if (place1) b1[u]=nBlocks;\n                                if (place2) b2[u]=nBlocks;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    };\n\n    // Common components used in both\n    process_components(C, true, true);\n    // Only1 components used in b1 only\n    process_components(O1, true, false);\n    // Only2 components used in b2 only\n    process_components(O2, false, true);\n\n    cout << nBlocks << \"\\n\";\n    for (int i=0;i<N;++i){\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << \"\\n\";\n    for (int i=0;i<N;++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};\nstruct AdjEdge { int to, id; long long w; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K;\n    if(!(cin>>N>>M>>K)) return 0;\n    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n    vector<Edge> edges(M);\n    vector<vector<AdjEdge>> g(N);\n    for(int j=0;j<M;j++){\n        int u,v; long long w;\n        cin>>u>>v>>w; --u;--v;\n        edges[j]={u,v,w};\n        g[u].push_back({v,j,w});\n        g[v].push_back({u,j,w});\n    }\n    vector<int> ax(K), ay(K);\n    for(int k=0;k<K;k++) cin>>ax[k]>>ay[k];\n\n    auto dist_int = [&](int xi,int yi,int a,int b)->int{\n        long double dx = (long double)xi - a;\n        long double dy = (long double)yi - b;\n        long double d = sqrt((double)(dx*dx + dy*dy));\n        // ceil to ensure coverage\n        int id = (int)ceil(d - 1e-12);\n        if(id>5000) id=5000;\n        if(id<0) id=0;\n        return id;\n    };\n\n    // Precompute station-resident distances\n    vector<vector<int>> res_order(N);\n    vector<vector<int>> res_dist(N);\n    for(int i=0;i<N;i++){\n        res_order[i].resize(K);\n        iota(res_order[i].begin(), res_order[i].end(), 0);\n        vector<int> tmpd(K);\n        for(int k=0;k<K;k++){\n            tmpd[k] = dist_int(x[i],y[i],ax[k],ay[k]);\n        }\n        // sort indices by distance\n        stable_sort(res_order[i].begin(), res_order[i].end(), [&](int a,int b){\n            return tmpd[a] < tmpd[b];\n        });\n        res_dist[i].resize(K);\n        for(int idx=0; idx<K; ++idx){\n            int rk = res_order[i][idx];\n            res_dist[i][idx] = tmpd[rk];\n        }\n    }\n\n    // Dijkstra from 0 to get shortest path tree\n    const long long INFLL = (1LL<<62);\n    vector<long long> dist(N, INFLL);\n    vector<int> parE(N, -1), parV(N, -1);\n    struct Node { long long d; int v;};\n    struct Cmp { bool operator()(const Node& a, const Node& b) const { return a.d>b.d; } };\n    priority_queue<Node, vector<Node>, Cmp> pq;\n    dist[0]=0; pq.push({0,0});\n    while(!pq.empty()){\n        auto [d,u]=pq.top(); pq.pop();\n        if(d!=dist[u]) continue;\n        for(auto &e: g[u]){\n            int v=e.to; long long nd = d + e.w;\n            if(nd < dist[v]){\n                dist[v]=nd; parE[v]=e.id; parV[v]=u;\n                pq.push({nd,v});\n            }\n        }\n    }\n    // Build SPT edges set\n    vector<int> tree_parent_edge(N,-1);\n    for(int v=1; v<N; v++){\n        tree_parent_edge[v]=parE[v];\n    }\n\n    // Baseline: assign each resident to nearest station (by Euclidean distance, not connectivity)\n    vector<int> P(N,0);\n    vector<int> req(N,0);\n    for(int k=0;k<K;k++){\n        int besti=0; int bestd = dist_int(x[0],y[0],ax[k],ay[k]);\n        for(int i=1;i<N;i++){\n            int d = dist_int(x[i],y[i],ax[k],ay[k]);\n            if(d < bestd){\n                bestd = d; besti=i;\n            }\n        }\n        if(bestd>req[besti]) req[besti]=bestd;\n    }\n    for(int i=0;i<N;i++) P[i]=req[i];\n\n    // Determine set of broadcasting stations (terminals)\n    vector<char> is_terminal(N,false);\n    int terminals=0;\n    for(int i=0;i<N;i++){\n        if(P[i]>0){ is_terminal[i]=true; terminals++; }\n    }\n    is_terminal[0] = is_terminal[0] || (P[0]>0); // ensure 0 marked if broadcasting\n\n    // Determine which tree edges are needed to connect terminals to root in the SPT\n    vector<char> need_edge(M,false);\n    vector<int> used(N,0);\n    // Mark all terminals and propagate to root\n    vector<int> degree_in_subtree(N,0);\n    for(int v=0; v<N; v++){\n        if(!is_terminal[v]) continue;\n        int u=v;\n        while(u!=0){\n            int e = tree_parent_edge[u];\n            if(e<0) break;\n            if(need_edge[e]) { // already marked\n                u = edges[e].u==u ? edges[e].v : edges[e].u;\n                continue;\n            }\n            need_edge[e]=true;\n            degree_in_subtree[edges[e].u]++;\n            degree_in_subtree[edges[e].v]++;\n            u = edges[e].u==u ? edges[e].v : edges[e].u;\n        }\n    }\n\n    // Optional: try to reduce broadcasting set by reassigning to currently broadcasting stations\n    // Build list of broadcasters\n    vector<int> broadcasters;\n    broadcasters.reserve(N);\n    for(int i=0;i<N;i++) if(P[i]>0) broadcasters.push_back(i);\n    if(broadcasters.empty()){\n        // If somehow no broadcasters (shouldn't happen as K>=2000), ensure station 1 covers nearest residents\n        // Set P[0] to max distance to all residents (capped)\n        int mx=0;\n        for(int k=0;k<K;k++){ mx = max(mx, dist_int(x[0],y[0],ax[k],ay[k])); }\n        P[0]=mx;\n        is_terminal[0]=true;\n        // no edges needed\n        fill(need_edge.begin(), need_edge.end(), false);\n    } else {\n        // Reassign residents to nearest broadcaster and recompute P\n        vector<int> newP(N,0);\n        for(int k=0;k<K;k++){\n            int besti = broadcasters[0];\n            int bestd = dist_int(x[besti],y[besti],ax[k],ay[k]);\n            for(size_t t=1;t<broadcasters.size();t++){\n                int i = broadcasters[t];\n                int d = dist_int(x[i],y[i],ax[k],ay[k]);\n                if(d < bestd){ bestd=d; besti=i; }\n            }\n            if(bestd > newP[besti]) newP[besti]=bestd;\n        }\n        P.swap(newP);\n        // update terminals\n        fill(is_terminal.begin(), is_terminal.end(), false);\n        broadcasters.clear();\n        for(int i=0;i<N;i++) if(P[i]>0){ is_terminal[i]=true; broadcasters.push_back(i); }\n        // recompute needed edges on SPT\n        fill(need_edge.begin(), need_edge.end(), false);\n        for(int v=0; v<N; v++){\n            if(!is_terminal[v]) continue;\n            int u=v;\n            while(u!=0){\n                int e = tree_parent_edge[u];\n                if(e<0) break;\n                if(need_edge[e]){\n                    u = edges[e].u==u ? edges[e].v : edges[e].u;\n                    continue;\n                }\n                need_edge[e]=true;\n                u = edges[e].u==u ? edges[e].v : edges[e].u;\n            }\n        }\n    }\n\n    // Final small tightening: try to reduce P[i] by trimming unnecessary slack.\n    // For each broadcaster i, compute max distance among residents to i when residents choose nearest broadcaster.\n    // Already done; but do a quick pass: for each i, try lowering to the next smaller actual distance in its assigned set.\n    // To keep it simple and fast, we skip recalculating assignments; the previous calculation already set P exactly.\n\n    // Build B array\n    vector<int> B(M,0);\n    for(int j=0;j<M;j++) if(need_edge[j]) B[j]=1;\n\n    // Output\n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << P[i];\n    }\n    cout << '\\n';\n    for(int j=0;j<M;j++){\n        if(j) cout << ' ';\n        cout << B[j];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    const int NN = N * (N + 1) / 2;\n\n    auto id_of = [&](int x, int y)->int { return x*(x+1)/2 + y; };\n    vector<int> x_of(NN), y_of(NN);\n    for (int x=0, id=0; x<N; ++x) {\n        for (int y=0; y<=x; ++y, ++id) {\n            x_of[id]=x; y_of[id]=y;\n        }\n    }\n\n    vector<int> A(NN);\n    for (int x=0; x<N; ++x) for (int y=0; y<=x; ++y) cin >> A[id_of(x,y)];\n\n    // Precompute children\n    const int NONE = -1;\n    vector<array<int,2>> child(NN, {NONE, NONE});\n    for (int x=0; x<N-1; ++x) {\n        for (int y=0; y<=x; ++y) {\n            int id = id_of(x,y);\n            child[id][0] = id_of(x+1, y);\n            child[id][1] = id_of(x+1, y+1);\n        }\n    }\n\n    struct Move { int x1,y1,x2,y2; };\n    vector<Move> moves;\n    moves.reserve(10000);\n    auto do_swap = [&](int id1, int id2){\n        swap(A[id1], A[id2]);\n        moves.push_back({x_of[id1], y_of[id1], x_of[id2], y_of[id2]});\n    };\n\n    const int K_LIMIT = 10000;\n\n    // Siftdown function: push value at id down along smaller-child path\n    auto siftdown = [&](int start_id)->int {\n        int swaps = 0;\n        int id = start_id;\n        while (child[id][0] != NONE) {\n            int c0 = child[id][0], c1 = child[id][1];\n            int mc = (A[c0] <= A[c1] ? c0 : c1);\n            if (A[id] <= A[mc]) break;\n            do_swap(id, mc);\n            ++swaps;\n            id = mc;\n            if ((int)moves.size() >= K_LIMIT) break;\n        }\n        return swaps;\n    };\n\n    // Perform bottom-up heapify passes. Repeat until stable or budget.\n    int pass = 0;\n    const int MAX_PASS = 8; // usually few passes suffice\n    while ((int)moves.size() < K_LIMIT && pass < MAX_PASS) {\n        ++pass;\n        int swaps_this_pass = 0;\n        // Process from second last row up to root\n        for (int x=N-2; x>=0; --x) {\n            for (int y=0; y<=x; ++y) {\n                int id = id_of(x,y);\n                // Full siftdown\n                swaps_this_pass += siftdown(id);\n                if ((int)moves.size() >= K_LIMIT) break;\n            }\n            if ((int)moves.size() >= K_LIMIT) break;\n        }\n        if (swaps_this_pass == 0) break; // already heap\n    }\n\n    // Optional light top-down correction pass to fix any residual local violations if budget remains.\n    if ((int)moves.size() < K_LIMIT) {\n        bool changed = true;\n        int guard_iters = 2; // very few iterations just to polish\n        while (changed && guard_iters-- && (int)moves.size() < K_LIMIT) {\n            changed = false;\n            for (int x=0; x<N-1; ++x) {\n                for (int y=0; y<=x; ++y) {\n                    int id = id_of(x,y);\n                    int c0 = child[id][0], c1 = child[id][1];\n                    int mc = (A[c0] <= A[c1] ? c0 : c1);\n                    if (A[id] > A[mc]) {\n                        do_swap(id, mc);\n                        changed = true;\n                        if ((int)moves.size() >= K_LIMIT) break;\n                        // continue sifting down locally\n                        int cur = mc;\n                        while (child[cur][0] != NONE) {\n                            int d0 = child[cur][0], d1 = child[cur][1];\n                            int md = (A[d0] <= A[d1] ? d0 : d1);\n                            if (A[cur] > A[md]) {\n                                do_swap(cur, md);\n                                cur = md;\n                                if ((int)moves.size() >= K_LIMIT) break;\n                            } else break;\n                        }\n                    }\n                }\n                if ((int)moves.size() >= K_LIMIT) break;\n            }\n        }\n    }\n\n    cout << moves.size() << '\\n';\n    for (auto &mv : moves) {\n        cout << mv.x1 << ' ' << mv.y1 << ' ' << mv.x2 << ' ' << mv.y2 << '\\n';\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D,N;\n    if(!(cin>>D>>N)) return 0;\n    vector<vector<int>> obs(D, vector<int>(D, 0));\n    for(int k=0;k<N;k++){\n        int r,c; cin>>r>>c;\n        obs[r][c]=1;\n    }\n    // Entrance\n    int ei = 0, ej = (D-1)/2;\n    // Build list of free cells excluding entrance\n    vector<Pos> cells; cells.reserve(D*D-1-N);\n    // Snake order by rows, skipping obstacles and entrance\n    for(int i=0;i<D;i++){\n        if(i%2==0){\n            for(int j=0;j<D;j++){\n                if(i==ei && j==ej) continue;\n                if(obs[i][j]) continue;\n                cells.push_back({i,j});\n            }\n        }else{\n            for(int jj=D-1;jj>=0;jj--){\n                int j=jj;\n                if(i==ei && j==ej) continue;\n                if(obs[i][j]) continue;\n                cells.push_back({i,j});\n            }\n        }\n    }\n    int M = (int)cells.size(); // should be D*D-1-N\n    // Map position index for quick lookup\n    vector<vector<int>> posIndex(D, vector<int>(D, -1));\n    for(int idx=0; idx<M; idx++){\n        posIndex[cells[idx].i][cells[idx].j] = idx;\n    }\n    // Occupancy grid: 0 empty, 1 occupied (container), -1 obstacle, -2 entrance (treated as empty for BFS)\n    vector<vector<int>> occ(D, vector<int>(D, 0));\n    for(int i=0;i<D;i++) for(int j=0;j<D;j++){\n        if(obs[i][j]) occ[i][j] = -1;\n    }\n    occ[ei][ej] = -2;\n\n    // For recording where each t is placed\n    vector<Pos> loc_of_id(M, {-1,-1});\n    vector<int> id_at_cell(M, -1); // by path index\n    vector<int> free_pos(M, 1);\n\n    auto bfs_reach = [&](){\n        vector<vector<char>> vis(D, vector<char>(D, 0));\n        queue<Pos> q;\n        q.push({ei,ej});\n        vis[ei][ej]=1;\n        int di[4]={-1,1,0,0};\n        int dj[4]={0,0,-1,1};\n        while(!q.empty()){\n            auto p=q.front(); q.pop();\n            for(int k=0;k<4;k++){\n                int ni=p.i+di[k], nj=p.j+dj[k];\n                if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                if(vis[ni][nj]) continue;\n                if(occ[ni][nj]==0 || occ[ni][nj]==-2){ // empty or entrance\n                    vis[ni][nj]=1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n        return vis;\n    };\n\n    // Online placement\n    for(int d=0; d<M; d++){\n        int t; cin>>t;\n        // compute reachable empty cells mask\n        auto vis = bfs_reach();\n        int ideal = t; if(ideal<0) ideal=0; if(ideal>=M) ideal=M-1;\n        int chosen_idx = -1;\n        // search window expanding\n        int W = 12;\n        int maxW = M;\n        for(int w=W; w<=maxW && chosen_idx==-1; w+=12){\n            int L = max(0, ideal - w);\n            int R = min(M-1, ideal + w);\n            // Collect reachable free candidates with minimal |pos-ideal|\n            int bestScore = INT_MAX;\n            int bestIdx = -1;\n            for(int pos=L; pos<=R; pos++){\n                if(!free_pos[pos]) continue;\n                Pos p = cells[pos];\n                if(!vis[p.i][p.j]) continue;\n                int score = abs(pos - ideal);\n                if(score < bestScore){\n                    bestScore = score;\n                    bestIdx = pos;\n                }else if(score == bestScore && bestIdx!=-1){\n                    // tie-break: for larger t, prefer larger pos; for smaller t, prefer smaller pos\n                    if(t*2 >= M){\n                        if(pos > bestIdx) bestIdx = pos;\n                    }else{\n                        if(pos < bestIdx) bestIdx = pos;\n                    }\n                }\n            }\n            if(bestIdx!=-1) chosen_idx = bestIdx;\n        }\n        if(chosen_idx==-1){\n            // Fallback: pick any reachable free cell, prefer towards ideal direction\n            int bestIdx=-1, bestScore=INT_MAX;\n            for(int pos=0; pos<M; pos++){\n                if(!free_pos[pos]) continue;\n                Pos p=cells[pos];\n                if(!vis[p.i][p.j]) continue;\n                int score = abs(pos - ideal);\n                if(score < bestScore){\n                    bestScore=score; bestIdx=pos;\n                }\n            }\n            if(bestIdx!=-1) chosen_idx=bestIdx;\n        }\n        if(chosen_idx==-1){\n            // As a last resort, pick any free (shouldn't happen because all free cells are reachable by guarantee if empty)\n            for(int pos=0; pos<M; pos++){\n                if(free_pos[pos]){\n                    chosen_idx=pos; break;\n                }\n            }\n        }\n        // Place\n        Pos place = cells[chosen_idx];\n        cout<<place.i<<\" \"<<place.j<<\"\\n\"<<flush;\n        occ[place.i][place.j] = 1;\n        free_pos[chosen_idx]=0;\n        id_at_cell[chosen_idx]=t;\n        loc_of_id[t]=place;\n    }\n\n    // Extraction: repeatedly remove smallest-ID reachable\n    // Build a map from (i,j) to ID\n    vector<vector<int>> id_grid(D, vector<int>(D, -1));\n    for(int pos=0; pos<M; pos++){\n        if(id_at_cell[pos]>=0){\n            Pos p = cells[pos];\n            id_grid[p.i][p.j] = id_at_cell[pos];\n        }\n    }\n\n    vector<pair<int,int>> output_order;\n    output_order.reserve(M);\n\n    auto bfs_reach_cells = [&](){\n        vector<vector<char>> vis(D, vector<char>(D, 0));\n        queue<Pos> q;\n        q.push({ei,ej});\n        vis[ei][ej]=1;\n        int di[4]={-1,1,0,0};\n        int dj[4]={0,0,-1,1};\n        while(!q.empty()){\n            auto p=q.front(); q.pop();\n            for(int k=0;k<4;k++){\n                int ni=p.i+di[k], nj=p.j+dj[k];\n                if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                if(vis[ni][nj]) continue;\n                // reachable through empty cells only\n                if(occ[ni][nj]==0 || occ[ni][nj]==-2){\n                    vis[ni][nj]=1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n        return vis;\n    };\n\n    for(int removed=0; removed<M; removed++){\n        // compute which occupied cells are currently reachable: cell must be adjacent via empty path to entrance\n        // A container is removable if its cell is reachable from entrance through empty cells; i.e., the container's cell must itself be marked reachable when considering it as occupied? The definition says:\n        // \"The square containing the container to be transported out must be reachable from the entrance by only passing through adjacent empty squares\"\n        // That implies the path does not include the container square (since it's not empty). Typically the last step into its square would require the square to be empty, which is impossible. Usually interpretation is: there exists a path of empty cells to a neighbor of the target, and then we can remove it. However AtCoder's typical definition here counts the container square as allowed at endpoint.\n        // The common approach is to allow reaching its cell if we treat it as empty for reachability test of candidate. We'll check neighbors.\n        auto vis = bfs_reach_cells();\n        int bestID = INT_MAX;\n        Pos bestP{-1,-1};\n        for(int i=0;i<D;i++){\n            for(int j=0;j<D;j++){\n                if(id_grid[i][j] < 0) continue;\n                // check if reachable: there exists a path of empty cells from entrance to a neighbor of (i,j)\n                bool reachable = false;\n                int di[4]={-1,1,0,0};\n                int dj[4]={0,0,-1,1};\n                for(int k=0;k<4;k++){\n                    int ni=i+di[k], nj=j+dj[k];\n                    if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                    if(vis[ni][nj]) { reachable=true; break; }\n                }\n                if(!reachable) continue;\n                int curID = id_grid[i][j];\n                if(curID < bestID){\n                    bestID = curID;\n                    bestP = {i,j};\n                }\n            }\n        }\n        if(bestID==INT_MAX){\n            // Fallback: if none reachable by neighbor method, allow cells that themselves are marked reachable if we consider them empty\n            // Temporarily mark all occupied as walls; vis marks empty reachables. None found -> choose any with minimal ID that is adjacent via zero? We'll pick minimal ID anywhere.\n            for(int i=0;i<D;i++){\n                for(int j=0;j<D;j++){\n                    if(id_grid[i][j] >= 0){\n                        int curID = id_grid[i][j];\n                        if(curID < bestID){\n                            bestID=curID; bestP={i,j};\n                        }\n                    }\n                }\n            }\n        }\n        // Output and remove\n        cout<<bestP.i<<\" \"<<bestP.j<<\"\\n\";\n        // Mark empty now\n        occ[bestP.i][bestP.j] = 0;\n        id_grid[bestP.i][bestP.j] = -1;\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int DX[4] = {1,-1,0,0};\nstatic const int DY[4] = {0,0,1,-1};\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    vector<int> d(n*n);\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            int c; cin >> c;\n            d[i*n+j] = c;\n        }\n    }\n    int C = m+1;\n    auto inb = [&](int i,int j){ return (unsigned)i < (unsigned)n && (unsigned)j < (unsigned)n; };\n\n    // Build adjacency matrix from input grid (including 0 via boundary)\n    vector<vector<char>> A(C, vector<char>(C, 0));\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            int u = d[i*n+j];\n            if(i+1<n){\n                int v = d[(i+1)*n+j];\n                if(u!=v){ A[u][v]=A[v][u]=1; }\n            }\n            if(j+1<n){\n                int v = d[i*n+(j+1)];\n                if(u!=v){ A[u][v]=A[v][u]=1; }\n            }\n        }\n    }\n    for(int i=0;i<n;i++){\n        int c1 = d[i*n+0];\n        int c2 = d[i*n+(n-1)];\n        A[0][c1]=A[c1][0]=1;\n        A[0][c2]=A[c2][0]=1;\n    }\n    for(int j=0;j<n;j++){\n        int c1 = d[0*n+j];\n        int c2 = d[(n-1)*n+j];\n        A[0][c1]=A[c1][0]=1;\n        A[0][c2]=A[c2][0]=1;\n    }\n\n    // adjCnt counts edges between colors in current d\n    vector<vector<int>> adjCnt(C, vector<int>(C, 0));\n    auto recomputeAdjCnt = [&](){\n        for(int u=0;u<C;u++) fill(adjCnt[u].begin(), adjCnt[u].end(), 0);\n        for(int i=0;i<n;i++){\n            for(int j=0;j<n;j++){\n                int u = d[i*n+j];\n                if(i+1<n){\n                    int v = d[(i+1)*n+j];\n                    if(u!=v){ adjCnt[u][v]++; adjCnt[v][u]++; }\n                }\n                if(j+1<n){\n                    int v = d[i*n+(j+1)];\n                    if(u!=v){ adjCnt[u][v]++; adjCnt[v][u]++; }\n                }\n            }\n        }\n        for(int i=0;i<n;i++){\n            int c1 = d[i*n+0];\n            int c2 = d[i*n+(n-1)];\n            if(c1!=0){ adjCnt[0][c1]++; adjCnt[c1][0]++; }\n            if(c2!=0){ adjCnt[0][c2]++; adjCnt[c2][0]++; }\n        }\n        for(int j=0;j<n;j++){\n            int c1 = d[0*n+j];\n            int c2 = d[(n-1)*n+j];\n            if(c1!=0){ adjCnt[0][c1]++; adjCnt[c1][0]++; }\n            if(c2!=0){ adjCnt[0][c2]++; adjCnt[c2][0]++; }\n        }\n    };\n    recomputeAdjCnt();\n\n    vector<int> totalCells(C, 0);\n    for(int v : d) totalCells[v]++;\n\n    vector<char> allowZeroAdj(C, 0);\n    for(int c=0;c<C;c++) allowZeroAdj[c] = A[0][c];\n\n    // Track 0-cells connected to boundary\n    vector<char> zeroConn(n*n, 0);\n    // Initially no internal zeros. If there were, we should flood from boundary zeros to mark; not needed here.\n\n    auto t0 = chrono::high_resolution_clock::now();\n    const double TIME_LIMIT = 1.60;\n\n    // Connectivity check for color c if removing cell p\n    vector<char> vis(n*n, 0);\n    auto connectedAfterRemoval = [&](int c, int p)->bool{\n        if(totalCells[c] <= 1) return false; // keep at least one\n        int pi = p / n, pj = p % n;\n        int neighCount = 0;\n        int start = -1;\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            int q = ni*n+nj;\n            if(d[q] == c){ neighCount++; start = q; }\n        }\n        if(neighCount <= 1) return true;\n        fill(vis.begin(), vis.end(), 0);\n        deque<int> dq;\n        dq.push_back(start);\n        vis[start] = 1;\n        int reach = 1;\n        while(!dq.empty()){\n            int v = dq.front(); dq.pop_front();\n            int vi = v / n, vj = v % n;\n            for(int dir=0;dir<4;dir++){\n                int ni = vi + DX[dir], nj = vj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int u = ni*n+nj;\n                if(u==p) continue;\n                if(!vis[u] && d[u]==c){\n                    vis[u]=1; dq.push_back(u); reach++;\n                }\n            }\n        }\n        return reach == totalCells[c]-1;\n    };\n\n    std::mt19937 rng(1234567);\n    bool improved = true;\n    int iter = 0;\n    while(improved){\n        improved = false;\n        iter++;\n        // Build candidate list: cells of colors with allowZeroAdj, and which will keep 0 connected (boundary or adj to zeroConn)\n        vector<int> cand;\n        cand.reserve(n*n);\n        for(int i=0;i<n;i++){\n            for(int j=0;j<n;j++){\n                int p = i*n+j;\n                int c = d[p];\n                if(c==0) continue;\n                if(!allowZeroAdj[c]) continue;\n                if(totalCells[c] <= 1) continue;\n                bool canConnectZero = (i==0 || i==n-1 || j==0 || j==n-1);\n                if(!canConnectZero){\n                    for(int dir=0;dir<4;dir++){\n                        int ni = i + DX[dir], nj = j + DY[dir];\n                        if(!inb(ni,nj)) continue;\n                        int q = ni*n+nj;\n                        if(d[q]==0 && zeroConn[q]){ canConnectZero = true; break; }\n                    }\n                }\n                if(!canConnectZero) continue;\n                cand.push_back(p);\n            }\n        }\n        shuffle(cand.begin(), cand.end(), rng);\n\n        for(int p : cand){\n            int c = d[p];\n            if(c==0) continue;\n            if(!allowZeroAdj[c]) continue;\n            if(totalCells[c] <= 1) continue;\n            int pi = p / n, pj = p % n;\n\n            // Check zero connectivity feasibility now (again in case neighbors changed)\n            bool canConnectZero = (pi==0 || pi==n-1 || pj==0 || pj==n-1);\n            if(!canConnectZero){\n                for(int dir=0;dir<4;dir++){\n                    int ni = pi + DX[dir], nj = pj + DY[dir];\n                    if(!inb(ni,nj)) continue;\n                    int q = ni*n+nj;\n                    if(d[q]==0 && zeroConn[q]){ canConnectZero = true; break; }\n                }\n            }\n            if(!canConnectZero) continue;\n\n            bool ok = true;\n\n            // Neighbor colors constraint: any neighbor y becomes adjacent to 0 via this new 0 cell; y must allow zero adjacency\n            int neighColorsCnt = 0;\n            int neighSame = 0;\n            int neighArr[4];\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int y = d[ni*n+nj];\n                neighArr[neighColorsCnt++] = y;\n                if(y==c){ neighSame++; continue; }\n                if(!allowZeroAdj[y]){ ok = false; break; }\n            }\n            if(!ok) continue;\n\n            // Preserve required adjacencies c-y\n            for(int k=0;k<neighColorsCnt;k++){\n                int y = neighArr[k];\n                if(y==c) continue;\n                if(A[c][y]){\n                    int contrib = 0;\n                    for(int dir=0;dir<4;dir++){\n                        int ni = pi + DX[dir], nj = pj + DY[dir];\n                        if(!inb(ni,nj)) continue;\n                        int y2 = d[ni*n+nj];\n                        if(y2==y) contrib++;\n                    }\n                    if(adjCnt[c][y] == contrib){ ok = false; break; }\n                }\n            }\n            if(!ok) continue;\n\n            // Preserve c-0 adjacency if required\n            int k0 = 0;\n            if(pi==0) k0++;\n            if(pi==n-1) k0++;\n            if(pj==0) k0++;\n            if(pj==n-1) k0++;\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                if(d[ni*n+nj]==0) k0++;\n            }\n            if(A[0][c]){\n                if(adjCnt[0][c] == k0){ ok = false; }\n            }\n            if(!ok) continue;\n\n            // Connectivity of c\n            if(!connectedAfterRemoval(c, p)) continue;\n\n            // Update adjCnt: remove edges adjacent to p\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(inb(ni,nj)){\n                    int y = d[ni*n+nj];\n                    if(y != c){\n                        adjCnt[c][y]--; adjCnt[y][c]--;\n                    }\n                }else{\n                    adjCnt[0][c]--; adjCnt[c][0]--;\n                }\n            }\n            // Set to 0\n            d[p] = 0;\n            totalCells[c]--;\n\n            // Mark 0 connectivity\n            zeroConn[p] = 1;\n\n            // Add new edges between 0 and neighbors\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int y = d[ni*n+nj];\n                if(y != 0){\n                    adjCnt[0][y]++; adjCnt[y][0]++;\n                }\n            }\n\n            improved = true;\n\n            auto t1 = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(t1 - t0).count();\n            if(elapsed > TIME_LIMIT) break;\n        }\n        auto t1 = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(t1 - t0).count();\n        if(elapsed > TIME_LIMIT) break;\n    }\n\n    // Output\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            if(j) cout << ' ';\n            cout << d[i*n+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    // Random generator\n    uint64_t seed = chrono::high_resolution_clock::now().time_since_epoch().count();\n    mt19937_64 rng(seed);\n    uniform_int_distribution<int> coin(0, 1);\n\n    // Parameters\n    int K = max(2, N / 2); // items per query\n    K = min(K, N); // ensure <= N\n\n    vector<long long> score(N, 0); // correlation scores\n\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n\n    // We will store last used L,R to allow safe dummy if needed (not necessary here)\n    for (int q = 0; q < Q; q++) {\n        // Choose K distinct indices by shuffling\n        shuffle(idx.begin(), idx.end(), rng);\n        int k = K;\n        if (k > N) k = N;\n        if (k < 2) k = 2; // must have both sides non-empty\n\n        vector<int> L, R;\n        L.reserve(k/2+1);\n        R.reserve(k/2+1);\n\n        // Alternate split to balance sizes\n        for (int t = 0; t < k; t++) {\n            if (t % 2 == 0) L.push_back(idx[t]);\n            else R.push_back(idx[t]);\n        }\n        // Edge case: if R ended up empty due to k==1 (we enforced k>=2), so safe.\n\n        // Output query\n        cout << (int)L.size() << \" \" << (int)R.size();\n        for (int v : L) cout << \" \" << v;\n        for (int v : R) cout << \" \" << v;\n        cout << \"\\n\" << flush;\n\n        // Read response\n        string s;\n        if (!(cin >> s)) return 0;\n        int y = 0;\n        if (s == \"<\") y = -1;\n        else if (s == \">\") y = +1;\n        else y = 0; // \"=\"\n\n        if (y != 0) {\n            // Update scores\n            for (int v : L) score[v] += y;     // +1 if '>' (L heavier), -1 if '<'\n            for (int v : R) score[v] -= y;     // inverse\n        }\n    }\n\n    // Build estimated weights from scores\n    long long mn = *min_element(score.begin(), score.end());\n    vector<double> est(N);\n    for (int i = 0; i < N; i++) {\n        long long s = score[i] - mn + 1; // >=1\n        double x = (double)s;\n        // power transform to accentuate differences\n        double e = pow(x, 1.5);\n        if (!isfinite(e) || e <= 0) e = 1.0;\n        est[i] = e;\n    }\n\n    // Order items by estimated weight descending\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    stable_sort(order.begin(), order.end(), [&](int a, int b){\n        if (est[a] != est[b]) return est[a] > est[b];\n        return a < b;\n    });\n\n    // Greedy LPT assignment\n    vector<int> assign(N, 0);\n    vector<double> bins(D, 0.0);\n    // min-heap of (binsum, bin_id)\n    using P = pair<double,int>;\n    priority_queue<P, vector<P>, greater<P>> pq;\n    for (int d = 0; d < D; d++) pq.emplace(0.0, d);\n\n    for (int v : order) {\n        auto [sumv, d] = pq.top(); pq.pop();\n        assign[v] = d;\n        sumv += est[v];\n        bins[d] = sumv;\n        pq.emplace(sumv, d);\n    }\n\n    // Local search on estimates\n    auto compute_var = [&](const vector<double>& bs)->double{\n        double mean = 0;\n        for (double x : bs) mean += x;\n        mean /= D;\n        double var = 0;\n        for (double x : bs) { double d = x - mean; var += d*d; }\n        return var / D;\n    };\n\n    // Build bin -> items\n    vector<vector<int>> binItems(D);\n    for (int i = 0; i < N; i++) binItems[assign[i]].push_back(i);\n\n    // Helper to update after moves\n    auto move_item = [&](int i, int from, int to){\n        if (from == to) return;\n        bins[from] -= est[i];\n        bins[to]   += est[i];\n        assign[i] = to;\n        auto &vf = binItems[from];\n        for (size_t p = 0; p < vf.size(); ++p) if (vf[p]==i){ vf[p]=vf.back(); vf.pop_back(); break; }\n        binItems[to].push_back(i);\n    };\n\n    int LS_ITERS = 2000;\n    for (int it = 0; it < LS_ITERS; it++) {\n        // Find heaviest and lightest\n        int h = max_element(bins.begin(), bins.end()) - bins.begin();\n        int l = min_element(bins.begin(), bins.end()) - bins.begin();\n        if (h == l) break;\n        double bestGain = 0.0;\n        int bestI = -1, bestJ = -1;\n        // Try move a single item from h to l\n        for (int i : binItems[h]) {\n            double dh = est[i];\n            double new_h = bins[h] - dh;\n            double new_l = bins[l] + dh;\n            double old_var = 0; // compute delta only for two bins approximate\n            // Use approximate improvement: reduce spread\n            double spread_before = bins[h] - bins[l];\n            double spread_after  = new_h - new_l;\n            double gain = spread_before - spread_after; // positive is good\n            if (gain > bestGain) { bestGain = gain; bestI = i; bestJ = -1; }\n        }\n        // Try swap one from h with one from l\n        int limH = (int)binItems[h].size();\n        int limL = (int)binItems[l].size();\n        // Limit checks to keep runtime bounded\n        int sampH = min(limH, 20);\n        int sampL = min(limL, 20);\n        // sample some items\n        vector<int> candH = binItems[h];\n        vector<int> candL = binItems[l];\n        if ((int)candH.size() > sampH) {\n            shuffle(candH.begin(), candH.end(), rng);\n            candH.resize(sampH);\n        }\n        if ((int)candL.size() > sampL) {\n            shuffle(candL.begin(), candL.end(), rng);\n            candL.resize(sampL);\n        }\n        for (int i : candH) for (int j : candL) {\n            double dh = est[i], dl = est[j];\n            double new_h = bins[h] - dh + dl;\n            double new_l = bins[l] - dl + dh;\n            double spread_before = bins[h] - bins[l];\n            double spread_after  = new_h - new_l;\n            double gain = spread_before - spread_after;\n            if (gain > bestGain) { bestGain = gain; bestI = i; bestJ = j; }\n        }\n        if (bestGain <= 1e-9) break;\n        if (bestJ == -1) {\n            move_item(bestI, h, l);\n        } else {\n            int i = bestI, j = bestJ;\n            // swap i in h with j in l\n            // implement as two moves\n            move_item(i, h, l);\n            move_item(j, l, h);\n        }\n    }\n\n    // Output final assignment\n    for (int i = 0; i < N; i++) {\n        if (i) cout << ' ';\n        cout << assign[i];\n    }\n    cout << \"\\n\" << flush;\n\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Heuristic solver for AHC026-like problem\n// n=200, m=10 fixed in tests, but code keeps generality.\n\nstruct Solver {\n    int n, m, H;\n    vector<vector<int>> st; // stacks: bottom -> top\n    vector<int> whereS; // stack index (0..m-1) for each box (1..n)\n    vector<int> whereIdx; // index in stack vector\n    vector<pair<int,int>> ops; // (v,i) with i in [0..m]\n    vector<char> removed;\n\n    void read_input() {\n        cin >> n >> m;\n        H = n / m;\n        st.assign(m, {});\n        whereS.assign(n+1, -1);\n        whereIdx.assign(n+1, -1);\n        removed.assign(n+1, 0);\n        for (int i = 0; i < m; ++i) {\n            st[i].resize(H);\n            for (int j = 0; j < H; ++j) {\n                int v; cin >> v;\n                st[i][j] = v;\n                whereS[v] = i;\n                whereIdx[v] = j;\n            }\n        }\n    }\n\n    inline int top_value(int i) const {\n        if (st[i].empty()) return INT_MAX/4; // treat empty as very large top for preference\n        return st[i].back();\n    }\n\n    void do_move(int v, int dest) {\n        // Operation 1: move suffix starting at v from its current stack to top of dest (1-based output dest+1)\n        int s = whereS[v];\n        if (s == dest) {\n            // avoid self-move; but spec allows it; however it's wasteful. We should not call this.\n            // To be safe, don't perform and don't record.\n            return;\n        }\n        int idx = whereIdx[v];\n        int k = (int)st[s].size() - idx; // number of boxes moved\n        // record op\n        ops.emplace_back(v, dest+1);\n        // move elements\n        // append to dest\n        st[dest].reserve(st[dest].size() + k);\n        for (int i = idx; i < (int)st[s].size(); ++i) {\n            int x = st[s][i];\n            st[dest].push_back(x);\n            whereS[x] = dest;\n            whereIdx[x] = (int)st[dest].size() - 1;\n        }\n        // erase from source\n        st[s].resize(idx);\n    }\n\n    void do_carry(int v) {\n        // Operation 2: carry out v; it must be top of its stack and be the smallest remaining.\n        int s = whereS[v];\n        if (s == -1) return; // already removed\n        // record op\n        ops.emplace_back(v, 0);\n        // pop\n        int topv = st[s].back();\n        if (topv != v) {\n            // Shouldn't happen; guard\n            // Find v and remove it (fallback)\n            auto it = find(st[s].begin(), st[s].end(), v);\n            if (it != st[s].end()) {\n                st[s].erase(it);\n                // rebuild indices in this stack\n                for (int i = 0; i < (int)st[s].size(); ++i) whereIdx[st[s][i]] = i;\n            }\n        } else {\n            st[s].pop_back();\n        }\n        whereS[v] = -1;\n        whereIdx[v] = -1;\n        removed[v] = 1;\n    }\n\n    int choose_dest(int v) {\n        int s = whereS[v];\n        // Preferred bin stack\n        int bin = (v - 1) / H; // 0-based\n        int d_pref = min(bin, m-1); // guard\n        if (d_pref != s) return d_pref;\n        // choose another stack:\n        int best = -1;\n        int bestTop = -1;\n        int bestHeight = INT_MAX;\n        for (int i = 0; i < m; ++i) if (i != s) {\n            int tv = top_value(i);\n            // prefer larger top value; empty stack has INT_MAX/4 which is largest\n            if (tv > bestTop) {\n                bestTop = tv;\n                bestHeight = (int)st[i].size();\n                best = i;\n            } else if (tv == bestTop) {\n                int h = (int)st[i].size();\n                if (h < bestHeight) {\n                    bestHeight = h;\n                    best = i;\n                }\n            }\n        }\n        if (best == -1) best = (s+1)%m;\n        return best;\n    }\n\n    void solve() {\n        // Process in ascending order\n        for (int t = 1; t <= n; ++t) {\n            if (removed[t]) continue;\n            int s = whereS[t];\n            // while t not at top of its stack, move suffix including t to chosen destination\n            if (st[s].empty()) continue; // shouldn't\n            if (st[s].back() == t) {\n                do_carry(t);\n                continue;\n            }\n            int dest = choose_dest(t);\n            // perform move so that t becomes top of dest\n            do_move(t, dest);\n            // Now t should be top at dest\n            do_carry(t);\n            // No further consolidation to keep it simple\n            if ((int)ops.size() >= 4999) {\n                // fallback: carry remaining if possible when already on top\n                for (int u = t+1; u <= n && (int)ops.size() < 5000; ++u) {\n                    if (!removed[u]) {\n                        int su = whereS[u];\n                        if (su != -1 && !st[su].empty() && st[su].back() == u) {\n                            do_carry(u);\n                        } else {\n                            // cannot finish, break\n                            break;\n                        }\n                    }\n                }\n                break;\n            }\n        }\n    }\n\n    void output() {\n        int K = (int)ops.size();\n        for (auto &p : ops) {\n            cout << p.first << \" \" << p.second << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver solver;\n    solver.read_input();\n    solver.solve();\n    solver.output();\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin>>N)) return 0;\n    vector<string> h(N-1), v(N);\n    for(int i=0;i<N-1;i++) cin>>h[i];\n    for(int i=0;i<N;i++) cin>>v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>d[i][j];\n\n    auto inb = [&](int i,int j){ return 0<=i && i<N && 0<=j && j<N; };\n    auto canMoveDir = [&](int i,int j,int dir)->bool{\n        // 0:R,1:D,2:L,3:U\n        if(dir==0){ if(j+1>=N) return false; return v[i][j]=='0'; }\n        if(dir==2){ if(j-1<0)   return false; return v[i][j-1]=='0'; }\n        if(dir==1){ if(i+1>=N) return false; return h[i][j]=='0'; }\n        if(dir==3){ if(i-1<0)   return false; return h[i-1][j]=='0'; }\n        return false;\n    };\n    const int di[4]={0,1,0,-1};\n    const int dj[4]={1,0,-1,0};\n    string DIR = \"RDLU\";\n\n    auto bfs_path = [&](Pos s, Pos t)->vector<int>{\n        if(s.i==t.i && s.j==t.j) return {};\n        int H=N, W=N;\n        vector<int> prevDir(H*W, -1);\n        vector<int> vis(H*W, 0);\n        deque<Pos> q;\n        auto idx = [&](int i,int j){ return i*W + j; };\n        q.push_back(s);\n        vis[idx(s.i,s.j)] = 1;\n        while(!q.empty()){\n            auto p = q.front(); q.pop_front();\n            if(p.i==t.i && p.j==t.j) break;\n            for(int dir=0; dir<4; dir++){\n                int ni=p.i+di[dir], nj=p.j+dj[dir];\n                if(!inb(ni,nj)) continue;\n                if(!canMoveDir(p.i,p.j,dir)) continue;\n                int id = idx(ni,nj);\n                if(vis[id]) continue;\n                vis[id]=1;\n                prevDir[id] = dir;\n                q.push_back({ni,nj});\n            }\n        }\n        vector<int> path_dirs;\n        int curi=t.i, curj=t.j;\n        if(!vis[idx(curi,curj)]){\n            // Should not happen due to connectivity, but fallback: empty\n            return path_dirs;\n        }\n        while(!(curi==s.i && curj==s.j)){\n            int dir = prevDir[idx(curi,curj)];\n            path_dirs.push_back(dir);\n            // move backward along reverse of dir\n            int rev = (dir+2)%4;\n            curi += di[rev];\n            curj += dj[rev];\n        }\n        reverse(path_dirs.begin(), path_dirs.end());\n        return path_dirs;\n    };\n\n    // Build serpentine order of all cells\n    vector<Pos> targetOrder;\n    targetOrder.reserve(N*N);\n    for(int i=0;i<N;i++){\n        if(i%2==0){\n            for(int j=0;j<N;j++) targetOrder.push_back({i,j});\n        }else{\n            for(int j=N-1;j>=0;j--) targetOrder.push_back({i,j});\n        }\n    }\n    // Ensure start is (0,0); targetOrder[0] is (0,0), good.\n\n    // Build base moves by chaining shortest paths\n    string baseMoves;\n    baseMoves.reserve(N*N*2);\n    Pos cur = targetOrder[0];\n    for(size_t k=1;k<targetOrder.size();k++){\n        auto seg = bfs_path(cur, targetOrder[k]);\n        for(int dir: seg) baseMoves.push_back(DIR[dir]);\n        cur = targetOrder[k];\n    }\n    // Return to (0,0)\n    {\n        auto seg = bfs_path(cur, {0,0});\n        for(int dir: seg) baseMoves.push_back(DIR[dir]);\n        cur = {0,0};\n    }\n\n    // Reconstruct nodes along baseMoves\n    vector<Pos> baseNodes;\n    baseNodes.reserve(baseMoves.size()+1);\n    {\n        int i=0,j=0;\n        baseNodes.push_back({i,j});\n        for(char c: baseMoves){\n            int dir = (c=='R'?0: c=='D'?1: c=='L'?2:3);\n            // trust canMoveDir\n            i += di[dir]; j += dj[dir];\n            baseNodes.push_back({i,j});\n        }\n        // Should be back at (0,0)\n    }\n\n    // Precompute best local loop per cell\n    struct Loop { vector<int> dirs; };\n    vector<vector<Loop>> loopOf(N, vector<Loop>(N));\n    auto makeLoopAt = [&](int i,int j)->Loop{\n        struct Cand { int score; vector<int> dirs; };\n        vector<Cand> cands;\n        auto add4 = [&](int a, int b){\n            int i0=i, j0=j;\n            if(!canMoveDir(i0,j0,a)) return;\n            int i1=i0+di[a], j1=j0+dj[a];\n            if(!canMoveDir(i1,j1,b)) return;\n            int i2=i1+di[b], j2=j1+dj[b];\n            int a2=(a+2)%4, b2=(b+2)%4;\n            if(!canMoveDir(i2,j2,a2)) return;\n            int i3=i2+di[a2], j3=j2+dj[a2];\n            if(!(i3==i1 && j3==j1)) return;\n            if(!canMoveDir(i3,j3,b2)) return;\n            int i4=i3+di[b2], j4=j3+dj[b2];\n            if(!(i4==i && j4==j)) return;\n            int score = d[i][j] + d[i1][j1] + d[i2][j2] + d[i3][j3];\n            cands.push_back({score, {a,b,a2,b2}});\n        };\n        add4(0,1); add4(1,2); add4(2,3); add4(3,0);\n        if(!cands.empty()){\n            auto best = *max_element(cands.begin(), cands.end(), [](const Cand&a,const Cand&b){return a.score<b.score;});\n            return Loop{best.dirs};\n        }\n        // Fallback 2-step ping-pong\n        int bestDir=-1, bestScore=-1;\n        for(int dir=0; dir<4; dir++){\n            if(!canMoveDir(i,j,dir)) continue;\n            int ni=i+di[dir], nj=j+dj[dir];\n            int sc = d[i][j] + d[ni][nj];\n            if(sc>bestScore){ bestScore=sc; bestDir=dir; }\n        }\n        if(bestDir!=-1) return Loop{ vector<int>{bestDir, (bestDir+2)%4} };\n        return Loop{ vector<int>() };\n    };\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) loopOf[i][j]=makeLoopAt(i,j);\n\n    // For each cell, record visit times along baseNodes\n    int L0 = (int)baseMoves.size();\n    vector<vector<vector<int>>> visits(N, vector<vector<int>>(N));\n    for(int t=0;t<(int)baseNodes.size();t++){\n        auto p = baseNodes[t];\n        visits[p.i][p.j].push_back(t);\n    }\n    // Compute gap estimate per cell (average steps between consecutive visits in base cycle)\n    vector<vector<double>> gapEst(N, vector<double>(N, 0.0));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            auto &vec = visits[i][j];\n            if(vec.size()<=1){\n                gapEst[i][j] = (double)L0; // visited once; approximate large gap\n            }else{\n                long long sumGap = 0;\n                for(size_t k=1;k<vec.size();k++) sumGap += (vec[k]-vec[k-1]);\n                // cycle wrap: from last to first across end\n                sumGap += ( (int)baseNodes.size()-1 - vec.back() ) + vec.front();\n                double avgGap = (double)sumGap / (double)vec.size();\n                gapEst[i][j] = max(1.0, avgGap);\n            }\n        }\n    }\n\n    // Build candidate hotspots with priority = d * gap / cost\n    struct Hot { int i,j; int cost; double pr; };\n    vector<Hot> hots;\n    hots.reserve(N*N);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        int cost = (int)loopOf[i][j].dirs.size();\n        if(cost==0) continue;\n        double pr = (double)d[i][j] * gapEst[i][j] / (double)cost;\n        hots.push_back({i,j,cost,pr});\n    }\n    if(hots.empty()){\n        cout<<baseMoves<<\"\\n\";\n        return 0;\n    }\n    sort(hots.begin(), hots.end(), [](const Hot&a,const Hot&b){ return a.pr > b.pr; });\n    // Limit to top K to keep structures small\n    int K = min((int)hots.size(), max(50, (N*N)/8)); // keep enough\n    hots.resize(K);\n\n    // Budget\n    long long budgetMax = 100000LL;\n    long long B = budgetMax - (long long)L0;\n    if(B < 0) B = 0;\n\n    // For each hot cell, plan total repeats proportional to priority and also bounded by number of occurrences\n    double totalPr = 0.0;\n    for(auto &hcell : hots) totalPr += max(1e-9, hcell.pr);\n    vector<long long> repeats(K, 0);\n    long long used = 0;\n    // Build occurrences list per hot\n    vector<vector<int>> occIdx(K);\n    occIdx.reserve(K);\n    unordered_map<long long,int> hotIndex; hotIndex.reserve(K*2);\n    auto keyOf = [&](int i,int j)->long long{ return ((long long)i<<20) ^ j; };\n    for(int idx=0; idx<K; idx++){\n        hotIndex[keyOf(hots[idx].i, hots[idx].j)] = idx;\n        // take indices where we are at the cell (node index), we can inject before emitting subsequent move\n        occIdx[idx] = visits[hots[idx].i][hots[idx].j];\n    }\n    // Allocate\n    for(int idx=0; idx<K; idx++){\n        auto &hc = hots[idx];\n        double frac = max(1e-12, hc.pr) / totalPr;\n        long long targetCost = (long long) floor(frac * (double)B);\n        long long rep = targetCost / hc.cost;\n        // distribute across occurrences: limit per-visit loops to small number\n        long long perVisitCap = 20; // tighter cap to avoid burst\n        long long cap = (long long)occIdx[idx].size() * perVisitCap;\n        if(rep > cap) rep = cap;\n        repeats[idx] = rep;\n        used += rep * hc.cost;\n    }\n    if(used > B){\n        double scale = (double)B / (double)max(1LL, used);\n        used = 0;\n        for(int idx=0; idx<K; idx++){\n            long long rep = (long long) floor(repeats[idx] * scale);\n            repeats[idx]=rep;\n            used += rep * hots[idx].cost;\n        }\n    }\n    long long rem = B - used;\n    // Greedy distribute residual to best efficiency w/cost\n    if(rem > 0){\n        vector<int> ord(K);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a,int b){\n            double ea = (double)d[hots[a].i][hots[a].j] / hots[a].cost;\n            double eb = (double)d[hots[b].i][hots[b].j] / hots[b].cost;\n            return ea>eb;\n        });\n        for(int round=0; round<3 && rem>0; round++){\n            for(int id: ord){\n                if(rem<=0) break;\n                int cost = hots[id].cost;\n                if(cost==0) continue;\n                long long occ = (long long)occIdx[id].size();\n                long long extraCap = occ * 5; // small extra\n                long long can = min(extraCap, rem / cost);\n                if(can<=0) continue;\n                repeats[id] += can;\n                rem -= can * cost;\n                if(rem<=0) break;\n            }\n        }\n    }\n\n    // Build per-occurrence distribution: spread repeats evenly over occurrence indices for each hot\n    struct Plan { int idx; int occCount; vector<long long> perOcc; };\n    vector<Plan> plans(K);\n    for(int idx=0; idx<K; idx++){\n        auto &occ = occIdx[idx];\n        int m = (int)occ.size();\n        plans[idx].idx = idx;\n        plans[idx].occCount = m;\n        plans[idx].perOcc.assign(m, 0);\n        long long R = repeats[idx];\n        if(m>0 && R>0){\n            // spread round-robin\n            for(long long r=0; r<R; r++){\n                plans[idx].perOcc[r % m]++;\n            }\n            // cap per-visit\n            long long cap = 25;\n            for(int t=0;t<m;t++){\n                if(plans[idx].perOcc[t] > cap) plans[idx].perOcc[t]=cap;\n            }\n        }\n    }\n\n    // Create a map from node index t to a list of loops to inject there (counts)\n    vector<long long> injectCount(baseNodes.size(), 0);\n    vector<const Loop*> injectLoop(baseNodes.size(), nullptr); // loop used at that cell\n    for(int idx=0; idx<K; idx++){\n        auto &occ = occIdx[idx];\n        auto &per = plans[idx].perOcc;\n        for(int k=0;k<(int)occ.size();k++){\n            int t = occ[k];\n            if(per[k] > 0){\n                injectCount[t] += per[k];\n                injectLoop[t] = &loopOf[ hots[idx].i ][ hots[idx].j ];\n            }\n        }\n    }\n\n    // Emit final moves with injection, while respecting total length \u2264 1e5\n    string out;\n    out.reserve( min(100000LL, (long long)L0 + B) );\n    long long budgetMoves = 100000LL;\n    long long remainingBase = (long long)baseMoves.size();\n    // Iterate over node indices; at node t, inject its loops as much as possible while keeping enough budget for remaining base moves\n    for(size_t t=0; t<baseNodes.size(); t++){\n        long long cnt = injectCount[t];\n        const Loop* lp = injectLoop[t];\n        if(cnt>0 && lp && !lp->dirs.empty()){\n            int cost = (int)lp->dirs.size();\n            // available free budget beyond remaining base moves\n            while(cnt>0){\n                if(budgetMoves <= remainingBase) break;\n                long long free = budgetMoves - remainingBase;\n                if(free < cost) break;\n                for(int dir: lp->dirs){\n                    out.push_back(DIR[dir]);\n                    budgetMoves--;\n                }\n                cnt--;\n            }\n            // update remaining count in case we want to continue later; but we won't revisit same t\n        }\n        if(t < baseMoves.size()){\n            // emit base move\n            if(budgetMoves==0) break;\n            out.push_back(baseMoves[t]);\n            budgetMoves--;\n            remainingBase--;\n        }\n    }\n    cout<<out<<\"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nlong long manh(const Pos& a, const Pos& b){\n    return llabs(a.i - b.i) + llabs(a.j - b.j);\n}\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 si, sj;\n    cin >> si >> sj;\n    vector<string> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\n    vector<string> t(M);\n    for(int k=0;k<M;k++) cin >> t[k];\n\n    // Positions for each letter\n    vector<vector<Pos>> pos(26);\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            int c = A[i][j]-'A';\n            pos[c].push_back({i,j});\n        }\n    }\n\n    // Remaining targets\n    vector<int> idxs(M);\n    iota(idxs.begin(), idxs.end(), 0);\n    vector<pair<int,int>> ops;\n    ops.reserve(5000);\n\n    Pos cur{si,sj};\n\n    // Pre-allocate buffers to reduce allocations\n    // We'll reuse dp arrays per candidate\n    for(int iter=0; iter<M; iter++){\n        // Select best next target index from idxs\n        long long bestCost = (1LL<<60);\n        int bestIdxPos = -1;\n        // For backtrack selection, we also want to remember first-step chosen index for quicker recompute\n        // But we'll recompute best path after selection for simplicity.\n        for(int p=0;p<(int)idxs.size();p++){\n            int k = idxs[p];\n            const string &s = t[k];\n            // Levels\n            const auto &L0 = pos[s[0]-'A'];\n            const auto &L1 = pos[s[1]-'A'];\n            const auto &L2 = pos[s[2]-'A'];\n            const auto &L3 = pos[s[3]-'A'];\n            const auto &L4 = pos[s[4]-'A'];\n            if(L0.empty()||L1.empty()||L2.empty()||L3.empty()||L4.empty()){\n                continue; // shouldn't happen, each letter exists\n            }\n            // DP forward costs only (no need to store parents here for selection)\n            int n0=L0.size(), n1=L1.size(), n2=L2.size(), n3=L3.size(), n4=L4.size();\n            static vector<long long> d0, d1, d2, d3, d4;\n            d0.assign(n0, (long long)4e18);\n            for(int i0=0;i0<n0;i0++) d0[i0] = manh(cur, L0[i0]);\n            d1.assign(n1, (long long)4e18);\n            for(int i1=0;i1<n1;i1++){\n                long long best = (long long)4e18;\n                for(int i0=0;i0<n0;i0++){\n                    long long v = d0[i0] + manh(L0[i0], L1[i1]);\n                    if(v < best) best = v;\n                }\n                d1[i1] = best;\n            }\n            d2.assign(n2, (long long)4e18);\n            for(int i2=0;i2<n2;i2++){\n                long long best = (long long)4e18;\n                for(int i1_=0;i1_<n1;i1_++){\n                    long long v = d1[i1_] + manh(L1[i1_], L2[i2]);\n                    if(v < best) best = v;\n                }\n                d2[i2] = best;\n            }\n            d3.assign(n3, (long long)4e18);\n            for(int i3=0;i3<n3;i3++){\n                long long best = (long long)4e18;\n                for(int i2_=0;i2_<n2;i2_++){\n                    long long v = d2[i2_] + manh(L2[i2_], L3[i3]);\n                    if(v < best) best = v;\n                }\n                d3[i3] = best;\n            }\n            d4.assign(n4, (long long)4e18);\n            for(int i4=0;i4<n4;i4++){\n                long long best = (long long)4e18;\n                for(int i3_=0;i3_<n3;i3_++){\n                    long long v = d3[i3_] + manh(L3[i3_], L4[i4]);\n                    if(v < best) best = v;\n                }\n                d4[i4] = best;\n            }\n            long long cand = *min_element(d4.begin(), d4.end());\n            if(cand < bestCost){\n                bestCost = cand;\n                bestIdxPos = p;\n            }\n        }\n        if(bestIdxPos == -1){\n            // Fallback: if something went wrong, break\n            break;\n        }\n        // Recompute path for selected target and output operations\n        int k = idxs[bestIdxPos];\n        const string &s = t[k];\n        const auto &L0 = pos[s[0]-'A'];\n        const auto &L1 = pos[s[1]-'A'];\n        const auto &L2 = pos[s[2]-'A'];\n        const auto &L3 = pos[s[3]-'A'];\n        const auto &L4 = pos[s[4]-'A'];\n        int n0=L0.size(), n1=L1.size(), n2=L2.size(), n3=L3.size(), n4=L4.size();\n        vector<long long> d0(n0), d1(n1), d2(n2), d3(n3), d4(n4);\n        vector<int> p0(n1,-1), p1(n2,-1), p2(n3,-1), p3(n4,-1);\n        for(int i0=0;i0<n0;i0++) d0[i0] = manh(cur, L0[i0]);\n        for(int i1=0;i1<n1;i1++){\n            long long best = (long long)4e18; int arg=-1;\n            for(int i0=0;i0<n0;i0++){\n                long long v = d0[i0] + manh(L0[i0], L1[i1]);\n                if(v < best){best = v; arg = i0;}\n            }\n            d1[i1] = best; p0[i1]=arg;\n        }\n        for(int i2=0;i2<n2;i2++){\n            long long best = (long long)4e18; int arg=-1;\n            for(int i1_=0;i1_<n1;i1_++){\n                long long v = d1[i1_] + manh(L1[i1_], L2[i2]);\n                if(v < best){best = v; arg = i1_;}\n            }\n            d2[i2] = best; p1[i2]=arg;\n        }\n        for(int i3=0;i3<n3;i3++){\n            long long best = (long long)4e18; int arg=-1;\n            for(int i2_=0;i2_<n2;i2_++){\n                long long v = d2[i2_] + manh(L2[i2_], L3[i3]);\n                if(v < best){best = v; arg = i2_;}\n            }\n            d3[i3] = best; p2[i3]=arg;\n        }\n        int best_i4=0;\n        {\n            long long best = (long long)4e18; int arg=-1;\n            for(int i4=0;i4<n4;i4++){\n                long long v = d3[0]; // placeholder\n                // Need transition from some i3\n            }\n        }\n        // compute d4 and p3 properly\n        long long bestVal = (long long)4e18;\n        int arg4 = -1;\n        for(int i4=0;i4<n4;i4++){\n            long long best = (long long)4e18; int arg=-1;\n            for(int i3_=0;i3_<n3;i3_++){\n                long long v = d3[i3_] + manh(L3[i3_], L4[i4]);\n                if(v < best){best = v; arg = i3_;}\n            }\n            d4[i4] = best; p3[i4]=arg;\n            if(d4[i4] < bestVal){bestVal = d4[i4]; arg4 = i4;}\n        }\n        // Backtrack indices\n        int i4 = arg4;\n        int i3 = p3[i4];\n        int i2 = p2[i3];\n        int i1 = p1[i2];\n        int i0 = p0[i1];\n\n        // Emit the 5 positions in order, updating cur\n        // Also ensure operation limit not exceeded (though we won't exceed)\n        array<Pos,5> seq = {L0[i0], L1[i1], L2[i2], L3[i3], L4[i4]};\n        for(int z=0; z<5; z++){\n            ops.emplace_back(seq[z].i, seq[z].j);\n            cur = seq[z];\n        }\n        // Remove this target from remaining\n        idxs.erase(idxs.begin() + bestIdxPos);\n    }\n\n    // Output\n    for(auto &p : ops){\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int di, dj;\n    vector<int> cells;\n    bitset<400> mask; // up to 20*20\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n    if (!(cin >> N >> M >> eps)) return 0;\n    int G = N*N;\n    auto idx = [N](int i,int j){ return i*N + j; };\n    auto ij = [N](int p){ return pair<int,int>(p/N, p%N); };\n\n    vector<vector<pair<int,int>>> shapes(M);\n    vector<int> shape_h(M), shape_w(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        int min_i = INT_MAX, min_j = INT_MAX, max_i = INT_MIN, max_j = INT_MIN;\n        for (int t = 0; t < d; ++t) {\n            int i,j; cin >> i >> j;\n            shapes[k][t] = {i,j};\n            min_i = min(min_i, i);\n            min_j = min(min_j, j);\n            max_i = max(max_i, i);\n            max_j = max(max_j, j);\n        }\n        shape_h[k] = max_i - min_i + 1;\n        shape_w[k] = max_j - min_j + 1;\n    }\n\n    // Generate candidates\n    vector<vector<Placement>> candidates(M);\n    for (int k = 0; k < M; ++k) {\n        int h = shape_h[k], w = shape_w[k];\n        for (int di = 0; di + h <= N; ++di) {\n            for (int dj = 0; dj + w <= N; ++dj) {\n                Placement P; P.di = di; P.dj = dj;\n                P.mask.reset();\n                bool ok = true;\n                for (auto [oi,oj] : shapes[k]) {\n                    int i = di + oi, j = dj + oj;\n                    if (i<0||i>=N||j<0||j>=N) { ok=false; break; }\n                    int p = idx(i,j);\n                    P.cells.push_back(p);\n                    P.mask.set(p);\n                }\n                if (ok) candidates[k].push_back(move(P));\n            }\n        }\n    }\n\n    // Reverse index (k,t) covering p\n    vector<vector<pair<int,int>>> cell_covers(G);\n    for (int k = 0; k < M; ++k) {\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            for (int p : candidates[k][t].cells) {\n                cell_covers[p].push_back({k,t});\n            }\n        }\n    }\n\n    // Alive flags and counts\n    vector<vector<char>> alive(M);\n    vector<int> alive_count(M);\n    for (int k = 0; k < M; ++k) {\n        alive[k].assign(candidates[k].size(), 1);\n        alive_count[k] = (int)candidates[k].size();\n    }\n\n    // Per-shape per-cell count of alive candidates covering p\n    vector<vector<int>> cnt_cover(M, vector<int>(G, 0));\n    // For each cell, total number of alive candidates covering it (across shapes)\n    vector<int> cover_count(G, 0);\n    // Per cell, number of shapes that can cover it (have at least one alive candidate covering it)\n    vector<int> S_can(G, 0);\n    for (int k = 0; k < M; ++k) {\n        vector<char> can(N*N, 0);\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            for (int p : candidates[k][t].cells) {\n                cnt_cover[k][p]++;\n                cover_count[p]++;\n                can[p] = 1;\n            }\n        }\n        for (int p = 0; p < G; ++p) if (can[p]) S_can[p]++;\n    }\n\n    // Forced coverage constraints: for shape k, set of cells that must be covered by its placement\n    vector<bitset<400>> forced_cover(M);\n    for (int k = 0; k < M; ++k) forced_cover[k].reset();\n\n    // cell state: -1 unknown, 0 zero, 1 positive\n    vector<int> state(G, -1);\n\n    auto flushout = [](){ cout.flush(); };\n\n    deque<int> shapes_to_commit;\n\n    auto kill_candidate = [&](int k, int t) {\n        if (!alive[k][t]) return;\n        alive[k][t] = 0;\n        alive_count[k]--;\n        // update counts\n        const bitset<400>& m = candidates[k][t].mask;\n        for (int p = m._Find_first(); p < G; p = m._Find_next(p)) {\n            cnt_cover[k][p]--;\n            cover_count[p]--;\n            if (cnt_cover[k][p] == 0) {\n                S_can[p]--;\n            }\n        }\n        if (alive_count[k] == 1) shapes_to_commit.push_back(k);\n    };\n\n    // Apply forced constraints for shape k: eliminate any candidate not covering all forced cells\n    auto enforce_forced = [&](int k) {\n        const bitset<400>& fc = forced_cover[k];\n        if (fc.none()) return;\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            if (!alive[k][t]) continue;\n            // candidate must include all forced bits\n            // Check (mask & fc) == fc\n            bitset<400> tmp = candidates[k][t].mask;\n            tmp &= fc;\n            if (tmp != fc) {\n                kill_candidate(k,t);\n            }\n        }\n    };\n\n    auto commit_singletons = [&]() {\n        while (!shapes_to_commit.empty()) {\n            int k = shapes_to_commit.front(); shapes_to_commit.pop_front();\n            if (alive_count[k] != 1) continue;\n            int tstar = -1;\n            for (int t = 0; t < (int)alive[k].size(); ++t) if (alive[k][t]) { tstar = t; break; }\n            if (tstar == -1) continue;\n            // Mark its cells as positive\n            for (int p : candidates[k][tstar].cells) {\n                if (state[p] == -1) state[p] = 1;\n            }\n            // Also, its forced constraints are trivially satisfied; no further eliminations needed here.\n        }\n    };\n\n    auto all_singleton = [&]() -> bool {\n        for (int k = 0; k < M; ++k) if (alive_count[k] != 1) return false;\n        return true;\n    };\n\n    auto select_next = [&]() -> int {\n        int bestp = -1;\n        long long bestScore = LLONG_MIN;\n        for (int p = 0; p < G; ++p) {\n            if (state[p] != -1) continue;\n            if (S_can[p] == 0) {\n                // can already mark zero; skip drilling\n                continue;\n            }\n            // composite score: prioritize high cover_count and small S_can\n            long long score = 2LL * cover_count[p] + (10 - S_can[p]);\n            if (score > bestScore) {\n                bestScore = score;\n                bestp = p;\n            }\n        }\n        if (bestp == -1) {\n            // fallback any unknown\n            for (int p = 0; p < G; ++p) if (state[p]==-1) return p;\n        }\n        return bestp;\n    };\n\n    int ops_used = 0, max_ops = 2*N*N;\n\n    // Propagate zeros for S_can==0\n    auto propagate_zero_cells = [&]() {\n        for (int p = 0; p < G; ++p) {\n            if (state[p] == -1 && S_can[p] == 0) state[p] = 0;\n        }\n    };\n    propagate_zero_cells();\n\n    while (ops_used < max_ops) {\n        if (all_singleton()) break;\n\n        // If all remaining unknowns are determinable as zero without drilling, stop loop\n        bool undecidedNeedsDrill = false;\n        for (int p = 0; p < G; ++p) {\n            if (state[p] == -1 && S_can[p] > 0) { undecidedNeedsDrill = true; break; }\n        }\n        if (!undecidedNeedsDrill) break;\n\n        int p = select_next();\n        if (p == -1) break;\n        auto [i,j] = ij(p);\n        cout << \"q 1 \" << i << ' ' << j << '\\n';\n        flushout();\n        ops_used++;\n        int vresp;\n        if (!(cin >> vresp)) return 0;\n        if (vresp == 0) {\n            state[p] = 0;\n            // eliminate all candidates covering p\n            // Iterate current list; but some entries might already be dead\n            for (auto [k,t] : cell_covers[p]) {\n                if (alive[k][t]) kill_candidate(k,t);\n            }\n            commit_singletons();\n            propagate_zero_cells();\n        } else {\n            state[p] = 1;\n            // Positive constraints\n            int x = vresp;\n            int Sc = S_can[p];\n            // If Sc == 0 this contradicts, but shouldn't happen.\n            if (Sc > 0) {\n                // If exactly x shapes can possibly cover p, then each of those must cover p\n                // In both this case and the more general case below, we enforce for some shapes that they must cover p\n                // Determine shapes where they must cover p\n                for (int k = 0; k < M; ++k) {\n                    if (cnt_cover[k][p] > 0) {\n                        int others = Sc - 1;\n                        if (others < x) {\n                            // shape k must cover p\n                            if (!forced_cover[k].test(p)) {\n                                forced_cover[k].set(p);\n                                enforce_forced(k);\n                            }\n                        }\n                    }\n                }\n                // Special case Sc==x: all shapes that can cover must cover\n                if (Sc == x) {\n                    for (int k = 0; k < M; ++k) {\n                        if (cnt_cover[k][p] > 0) {\n                            if (!forced_cover[k].test(p)) {\n                                forced_cover[k].set(p);\n                                enforce_forced(k);\n                            }\n                        }\n                    }\n                }\n                commit_singletons();\n                propagate_zero_cells();\n            }\n        }\n        if (ops_used >= max_ops) break;\n    }\n\n    // If still undecided cells, drill remaining unknowns to guarantee correctness\n    for (int p = 0; p < G && ops_used < max_ops; ++p) {\n        if (state[p] == -1) {\n            auto [i,j] = ij(p);\n            cout << \"q 1 \" << i << ' ' << j << '\\n';\n            flushout();\n            ops_used++;\n            int vresp;\n            if (!(cin >> vresp)) return 0;\n            state[p] = (vresp > 0) ? 1 : 0;\n            if (vresp == 0) {\n                // optional: could prune, but near end it doesn't matter\n            }\n        }\n    }\n\n    // Build answer: all cells with state==1\n    vector<pair<int,int>> ans;\n    ans.reserve(G);\n    for (int p = 0; p < G; ++p) if (state[p] == 1) ans.push_back(ij(p));\n\n    cout << \"a \" << ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n';\n    flushout();\n\n    int ok;\n    if (!(cin >> ok)) return 0;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect { int i0,j0,i1,j1; long long area() const { return 1LL*(i1-i0)*(j1-j0); } };\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++) for(int k=0; k<N; k++) cin>>a[d][k];\n\n    // Compute rank-wise maxima M_r\n    vector<int> M(N,0);\n    vector<int> tmp;\n    tmp.reserve(N);\n    for(int d=0; d<D; d++){\n        tmp = a[d];\n        sort(tmp.begin(), tmp.end());\n        for(int r=0; r<N; r++) M[r] = max(M[r], tmp[r]);\n    }\n    // sort M ascending\n    vector<long long> B(N);\n    for(int i=0;i<N;i++) B[i]=M[i];\n    sort(B.begin(), B.end());\n\n    auto build_grid = [&](int R, int C, vector<Rect>& cells, vector<long long>& cellAreas)->bool{\n        int cellsCount = R*C;\n        vector<long long> cap(cellsCount, 0);\n        for(int idx=0; idx<N; idx++) cap[idx] = B[idx]; // row-major\n        vector<long long> Sr(R,0), Sc(C,0);\n        long long S=0;\n        for(int i=0;i<R;i++){\n            for(int j=0;j<C;j++){\n                long long v = cap[i*C+j];\n                Sr[i]+=v; Sc[j]+=v; S+=v;\n            }\n        }\n        if(S==0){\n            // trivial: make equal grid\n            vector<int> h(R, W/R), w(C, W/C);\n            int remH = W - accumulate(h.begin(), h.end(), 0);\n            for(int i=0;i<remH;i++) h[i%R]++;\n            int remW = W - accumulate(w.begin(), w.end(), 0);\n            for(int j=0;j<remW;j++) w[j%C]++;\n            vector<int> hi(R+1,0), wj(C+1,0);\n            for(int i=0;i<R;i++) hi[i+1]=hi[i]+h[i];\n            for(int j=0;j<C;j++) wj[j+1]=wj[j]+w[j];\n            cells.clear(); cellAreas.clear();\n            for(int i=0;i<R;i++)for(int j=0;j<C;j++){\n                Rect r{hi[i], wj[j], hi[i+1], wj[j+1]};\n                cells.push_back(r);\n                cellAreas.push_back(r.area());\n            }\n            return true;\n        }\n        // fractional targets\n        vector<double> hr(R), wc(C);\n        for(int i=0;i<R;i++) hr[i] = (double)W * (double)Sr[i] / (double)S;\n        for(int j=0;j<C;j++) wc[j] = (double)W * (double)Sc[j] / (double)S;\n        vector<int> h(R), w(C);\n        vector<double> frh(R), frw(C);\n        for(int i=0;i<R;i++){\n            double x = hr[i];\n            int ci = (Sr[i]==0?1:(int)ceil(x));\n            if(ci<1) ci=1;\n            h[i]=ci;\n            frh[i] = ci - x;\n        }\n        for(int j=0;j<C;j++){\n            double x = wc[j];\n            int cj = (Sc[j]==0?1:(int)ceil(x));\n            if(cj<1) cj=1;\n            w[j]=cj;\n            frw[j] = cj - x;\n        }\n        auto safe_reduce_row = [&](int i)->bool{\n            if(h[i]<=1) return false;\n            for(int j=0;j<C;j++){\n                long long capij = cap[i*C+j];\n                if(capij==0) continue;\n                long long Aij = 1LL*(h[i]-1)*w[j];\n                if(Aij < capij) return false;\n            }\n            return true;\n        };\n        auto safe_reduce_col = [&](int j)->bool{\n            if(w[j]<=1) return false;\n            for(int i=0;i<R;i++){\n                long long capij = cap[i*C+j];\n                if(capij==0) continue;\n                long long Aij = 1LL*h[i]*(w[j]-1);\n                if(Aij < capij) return false;\n            }\n            return true;\n        };\n        // Trim to W\n        int sumh = accumulate(h.begin(), h.end(), 0);\n        int sumw = accumulate(w.begin(), w.end(), 0);\n        int guard=0;\n        while(sumh > W && guard<100000){\n            int pick=-1;\n            double best = 1e100;\n            for(int i=0;i<R;i++){\n                if(!safe_reduce_row(i)) continue;\n                // prefer rows with largest surplus (frh large), but we used ceil, so frh in [0,1)\n                // minimize harm: pick largest frh to reduce first\n                double score = frh[i];\n                if(score < best){ best=score; pick=i; }\n            }\n            if(pick==-1) break;\n            h[pick]--; sumh--;\n        }\n        guard=0;\n        while(sumw > W && guard<100000){\n            int pick=-1;\n            double best = 1e100;\n            for(int j=0;j<C;j++){\n                if(!safe_reduce_col(j)) continue;\n                double score = frw[j];\n                if(score < best){ best=score; pick=j; }\n            }\n            if(pick==-1) break;\n            w[pick]--; sumw--;\n        }\n        // If below W, we can add to any row/col to reach exactly W (adding never hurts)\n        while(sumh < W){\n            int pick = max_element(Sr.begin(), Sr.end()) - Sr.begin();\n            h[pick]++; sumh++;\n        }\n        while(sumw < W){\n            int pick = max_element(Sc.begin(), Sc.end()) - Sc.begin();\n            w[pick]++; sumw++;\n        }\n        // Verify feasibility\n        for(int i=0;i<R;i++) for(int j=0;j<C;j++){\n            long long capij = cap[i*C+j];\n            if(capij==0) continue;\n            long long Aij = 1LL*h[i]*w[j];\n            if(Aij < capij){\n                // failed\n                return false;\n            }\n        }\n        // Build cells\n        vector<int> hi(R+1,0), wj(C+1,0);\n        for(int i=0;i<R;i++) hi[i+1]=hi[i]+h[i];\n        for(int j=0;j<C;j++) wj[j+1]=wj[j]+w[j];\n        cells.clear(); cellAreas.clear();\n        for(int i=0;i<R;i++)for(int j=0;j<C;j++){\n            Rect r{hi[i], wj[j], hi[i+1], wj[j+1]};\n            cells.push_back(r);\n            cellAreas.push_back(r.area());\n        }\n        return true;\n    };\n\n    // Try grid constructions in a few shapes\n    vector<Rect> cells;\n    vector<long long> cellAreas;\n    bool ok=false;\n    {\n        int C = (int)ceil(sqrt((double)N));\n        int R = (N + C - 1)/C;\n        ok = build_grid(R,C,cells,cellAreas);\n    }\n    if(!ok){\n        int R = (int)ceil(sqrt((double)N));\n        int C = (N + R - 1)/R;\n        ok = build_grid(R,C,cells,cellAreas);\n    }\n    if(!ok){\n        // try pure stripes: R=N, C=1\n        ok = build_grid(N,1,cells,cellAreas);\n    }\n    if(!ok){\n        // last resort: equal grid ignoring capacities; we may incur penalties but very unlikely\n        int C = (int)ceil(sqrt((double)N));\n        int R = (N + C - 1)/C;\n        vector<int> h(R, W/R), w(C, W/C);\n        int remH = W - accumulate(h.begin(), h.end(), 0);\n        for(int i=0;i<remH;i++) h[i%R]++;\n        int remW = W - accumulate(w.begin(), w.end(), 0);\n        for(int j=0;j<remW;j++) w[j%C]++;\n        vector<int> hi(R+1,0), wj(C+1,0);\n        for(int i=0;i<R;i++) hi[i+1]=hi[i]+h[i];\n        for(int j=0;j<C;j++) wj[j+1]=wj[j]+w[j];\n        cells.clear(); cellAreas.clear();\n        for(int i=0;i<R;i++)for(int j=0;j<C;j++){\n            Rect r{hi[i], wj[j], hi[i+1], wj[j+1]};\n            cells.push_back(r);\n            cellAreas.push_back(r.area());\n        }\n        ok=true;\n    }\n\n    // Select first N cells and sort them by area ascending to match rank\n    vector<int> idx(cells.size());\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int x, int y){\n        if(cellAreas[x]!=cellAreas[y]) return cellAreas[x] < cellAreas[y];\n        return x<y;\n    });\n    vector<Rect> blocks(N);\n    vector<long long> blockArea(N);\n    for(int k=0;k<N;k++){\n        blocks[k]=cells[idx[k]];\n        blockArea[k]=blocks[k].area();\n    }\n    // For safety, ensure blockArea[k] >= B[k]; if not, we proceed anyway (rare), undersupply penalty may happen.\n\n    // Per day assignment: match ascending demands to ascending blocks\n    vector<vector<Rect>> out(D, vector<Rect>(N));\n    vector<int> ord(N);\n    for(int d=0; d<D; d++){\n        ord.resize(N);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int x,int y){ return a[d][x] < a[d][y]; });\n        // blocks are in ascending order already\n        vector<int> inv(N);\n        for(int r=0;r<N;r++){\n            int k = ord[r];\n            out[d][k] = blocks[r];\n        }\n    }\n\n    // Output\n    for(int d=0; d<D; d++){\n        for(int k=0; k<N; k++){\n            Rect r = out[d][k];\n            cout<<r.i0<<\" \"<<r.j0<<\" \"<<r.i1<<\" \"<<r.j1<<\"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const long long MOD = 998244353LL;\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<long long>> w(N, vector<long long>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            long long x; cin >> x;\n            w[i][j] = x % MOD;\n        }\n    }\n    // stamps[m][i][j]\n    vector<array<long long, 9>> stamps(M);\n    for (int m = 0; m < M; ++m) {\n        int idx = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                long long s; cin >> s;\n                stamps[m][idx++] = s % MOD;\n            }\n        }\n    }\n\n    struct Move { int m, p, q; long long gain; };\n    vector<tuple<int,int,int>> ops; ops.reserve(K);\n\n    auto compute_gain = [&](int m, int p, int q)->long long{\n        long long g = 0;\n        int idx = 0;\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj, ++idx) {\n                int r = p + di, c = q + dj;\n                long long v = w[r][c];\n                long long s = stamps[m][idx];\n                long long nv = v + s;\n                if (nv >= MOD) nv -= MOD;\n                g += (nv - v);\n            }\n        }\n        return g;\n    };\n\n    int maxOps = K;\n    for (int t = 0; t < maxOps; ++t) {\n        Move best{-1, -1, -1, LLONG_MIN};\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                    long long g = compute_gain(m, p, q);\n                    if (g > best.gain) {\n                        best = {m, p, q, g};\n                    }\n                }\n            }\n        }\n        if (best.gain <= 0) break;\n        // apply best\n        int m = best.m, p = best.p, q = best.q;\n        int idx = 0;\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj, ++idx) {\n                int r = p + di, c = q + dj;\n                long long s = stamps[m][idx];\n                long long nv = w[r][c] + s;\n                if (nv >= MOD) nv -= MOD;\n                w[r][c] = nv;\n            }\n        }\n        ops.emplace_back(m, p, q);\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto &op : ops) {\n        int m, p, q;\n        tie(m, p, q) = op;\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Planner {\n    static const int N = 5;\n    vector<vector<int>> A; // input sequences\n    vector<string> S; // commands per crane\n\n    // Large crane state\n    int cr=0, cc=0;\n    bool holding=false;\n    int held_id=-1;\n\n    // Storage: interior cells columns 1..3\n    bool occ[N][N]; // occupied by a container (interior only used; others kept false except during moves we don't mark)\n    unordered_map<int, pair<int,int>> loc; // container id -> stored cell (r,c)\n\n    int next_needed[N];\n    int idx_head[N]; // index head at each left gate\n    int dispatched=0;\n\n    int rr=0;\n\n    Planner(const vector<vector<int>>& Ain): A(Ain) {\n        S.assign(N, \"\");\n        for (int i=1;i<N;i++) S[i].push_back('B'); // bomb small cranes\n        memset(occ, 0, sizeof(occ));\n        for (int i=0;i<N;i++){ next_needed[i]=N*i; idx_head[i]=0; }\n    }\n\n    void appendLarge(char ch){\n        S[0].push_back(ch);\n        for (int i=1;i<N;i++){\n            if ((int)S[i].size() < (int)S[0].size()) S[i].push_back('.');\n        }\n    }\n    void moveTo(int tr, int tc){\n        while (cr != tr) {\n            if (tr < cr) { cr--; appendLarge('U'); }\n            else { cr++; appendLarge('D'); }\n        }\n        while (cc != tc) {\n            if (tc < cc) { cc--; appendLarge('L'); }\n            else { cc++; appendLarge('R'); }\n        }\n    }\n    void pickAtCurrent(int cid){\n        held_id = cid;\n        holding = true;\n        appendLarge('P');\n    }\n    void dropAtCurrent(){\n        holding = false;\n        appendLarge('Q');\n    }\n    // Find nearest free storage cell from current pos\n    pair<int,int> nearestFree(){\n        int best=1e9; pair<int,int> ans{-1,-1};\n        for (int r=0;r<N;r++){\n            for (int c=1;c<=3;c++){\n                if (!occ[r][c]){\n                    int d = abs(cr-r)+abs(cc-c);\n                    if (d < best){ best=d; ans={r,c}; }\n                }\n            }\n        }\n        return ans;\n    }\n    // Try to flush next-needed for any row from storage or left head\n    bool flush_one(){\n        for (int d=0; d<N; d++){\n            int need = next_needed[d];\n            if (need >= N*d + N) continue;\n            // in storage?\n            auto it = loc.find(need);\n            if (it != loc.end()){\n                auto [sr, sc] = it->second;\n                moveTo(sr, sc);\n                pickAtCurrent(need);\n                occ[sr][sc] = false;\n                loc.erase(it);\n                moveTo(d, N-1);\n                dropAtCurrent();\n                next_needed[d]++; dispatched++;\n                return true;\n            }\n        }\n        // Try from left gate head if available\n        for (int d=0; d<N; d++){\n            int need = next_needed[d];\n            if (need >= N*d + N) continue;\n            for (int r=0;r<N;r++){\n                if (idx_head[r] < N && A[r][idx_head[r]] == need){\n                    // go pick and dispatch\n                    moveTo(r, 0);\n                    pickAtCurrent(need);\n                    idx_head[r]++;\n                    moveTo(d, N-1);\n                    dropAtCurrent();\n                    next_needed[d]++; dispatched++;\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n    void flush_all(){\n        while (flush_one()){}\n    }\n    // Prefer rows whose head is immediately dispatchable; else choose nearest with remaining\n    int choose_source_row(){\n        // Prefer immediate need\n        for (int r=0;r<N;r++){\n            if (idx_head[r] >= N) continue;\n            int b = A[r][idx_head[r]];\n            int d = b / N;\n            if (next_needed[d] == b) return r;\n        }\n        // Otherwise closest\n        int best=1e9, bestr=-1;\n        for (int r=0;r<N;r++){\n            if (idx_head[r] >= N) continue;\n            int d = abs(cr - r) + abs(cc - 0);\n            if (d < best){ best=d; bestr=r; }\n        }\n        return bestr;\n    }\n\n    void ensureLargeNotBlockingStart(){\n        // move from (0,0) to (0,1) initially to avoid occasional arrival blocking while holding\n        if (cr==0 && cc==0){\n            cc=1; appendLarge('R');\n        }\n    }\n\n    void run(){\n        ensureLargeNotBlockingStart();\n        int maxTurns = 9500;\n\n        while (dispatched < N*N && (int)S[0].size() < maxTurns){\n            // Aggressive flush first\n            if (flush_one()) continue;\n\n            // If holding something not needed, try to store it\n            if (holding){\n                int d = held_id / N;\n                if (next_needed[d] == held_id){\n                    moveTo(d, N-1);\n                    dropAtCurrent();\n                    next_needed[d]++; dispatched++;\n                    continue;\n                } else {\n                    auto pos = nearestFree();\n                    if (pos.first == -1){\n                        // No space: try flush to free\n                        if (flush_one()) continue;\n                        // As fallback, move around but do not deadlock: circle within row d columns 2-3 if free\n                        // Try to drop to any free interior cell by scanning all\n                        bool placed=false;\n                        for (int r=0;r<N && !placed;r++){\n                            for (int c=1;c<=3;c++){\n                                if (!occ[r][c]){\n                                    moveTo(r,c);\n                                    dropAtCurrent();\n                                    occ[r][c]=true; loc[held_id]={r,c};\n                                    placed=true; break;\n                                }\n                            }\n                        }\n                        if (!placed){\n                            // absolute fallback: wait\n                            appendLarge('.');\n                        }\n                        continue;\n                    } else {\n                        moveTo(pos.first, pos.second);\n                        dropAtCurrent();\n                        occ[pos.first][pos.second]=true; loc[held_id]=pos;\n                        continue;\n                    }\n                }\n            }\n\n            // Choose next source row\n            int r = choose_source_row();\n            if (r == -1){\n                // nothing left to pick, try flush all\n                if (!flush_one()){\n                    appendLarge('.');\n                }\n                continue;\n            }\n\n            // Before picking a non-needed item, ensure storage space exists\n            int b = A[r][idx_head[r]];\n            int d = b / N;\n            bool immediate = (next_needed[d] == b);\n            if (!immediate){\n                // If storage almost full (no free), try flush until we get space or progress stalls\n                auto pos = nearestFree();\n                if (pos.first == -1){\n                    // flush cycle\n                    bool progressed=false;\n                    while (flush_one()){ progressed=true; }\n                    pos = nearestFree();\n                    if (pos.first == -1 && !progressed){\n                        // avoid picking, just idle one turn to allow arrivals and maybe new immediate opportunities\n                        appendLarge('.');\n                        continue;\n                    }\n                }\n            }\n\n            // Go pick\n            moveTo(r, 0);\n            // Ensure that between last pick from this row and now, at least one turn has passed for arrival; our moves guarantee it, but safe.\n            pickAtCurrent(b);\n            idx_head[r]++;\n\n            if (next_needed[d] == b){\n                moveTo(d, N-1);\n                dropAtCurrent();\n                next_needed[d]++; dispatched++;\n            } else {\n                auto pos = nearestFree();\n                if (pos.first == -1){\n                    // Try flush once more to free then store\n                    if (flush_one()){\n                        pos = nearestFree();\n                    }\n                }\n                if (pos.first != -1){\n                    moveTo(pos.first, pos.second);\n                    dropAtCurrent();\n                    occ[pos.first][pos.second]=true; loc[b]=pos;\n                } else {\n                    // As last resort, put it near its row in some cell that is free (scan again)\n                    bool placed=false;\n                    for (int rr=0; rr<N && !placed; rr++){\n                        for (int cc2=1; cc2<=3; cc2++){\n                            if (!occ[rr][cc2]){\n                                moveTo(rr,cc2);\n                                dropAtCurrent();\n                                occ[rr][cc2]=true; loc[b]={rr,cc2};\n                                placed=true; break;\n                            }\n                        }\n                    }\n                    if (!placed){\n                        // wait holding (risk arrival block if at column 0; we are at interior generally)\n                        appendLarge('.');\n                    }\n                }\n            }\n            rr = (r+1)%N;\n        }\n\n        // Pad others\n        size_t L = S[0].size();\n        for (int i=1;i<N;i++){\n            while (S[i].size() < L) S[i].push_back('.');\n        }\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i=0;i<N;i++){\n        for (int j=0;j<N;j++){\n            cin >> A[i][j];\n        }\n    }\n    Planner planner(A);\n    planner.run();\n    for (int i=0;i<N;i++){\n        cout << planner.S[i] << \"\\n\";\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Plan {\n    vector<string> ops;\n    long long cost = (long long)4e18;\n};\n\nstatic inline void append_move(pair<int,int> from, pair<int,int> to, vector<string>& ops, long long& cost, long long load) {\n    int dr = to.first - from.first;\n    int dc = to.second - from.second;\n    char ch = 0;\n    if (dr == 1 && dc == 0) ch = 'D';\n    else if (dr == -1 && dc == 0) ch = 'U';\n    else if (dr == 0 && dc == 1) ch = 'R';\n    else if (dr == 0 && dc == -1) ch = 'L';\n    else {\n        // Non-adjacent: move step by step Manhattan\n        int r = from.first, c = from.second;\n        while (r < to.first) { ops.emplace_back(\"D\"); cost += 100 + load; ++r; }\n        while (r > to.first) { ops.emplace_back(\"U\"); cost += 100 + load; --r; }\n        while (c < to.second) { ops.emplace_back(\"R\"); cost += 100 + load; ++c; }\n        while (c > to.second) { ops.emplace_back(\"L\"); cost += 100 + load; --c; }\n        return;\n    }\n    ops.emplace_back(string(1, ch));\n    cost += 100 + load;\n}\n\nstatic inline void add_load(long long d, vector<string>& ops, long long& cost, long long& load) {\n    if (d <= 0) return;\n    ops.emplace_back(\"+\" + to_string(d));\n    cost += d;\n    load += d;\n}\nstatic inline void sub_load(long long d, vector<string>& ops, long long& cost, long long& load) {\n    if (d <= 0) return;\n    ops.emplace_back(\"-\" + to_string(d));\n    cost += d;\n    load -= d;\n}\n\nvector<pair<int,int>> build_snake(int N) {\n    vector<pair<int,int>> ord;\n    ord.reserve(N*N);\n    for (int i = 0; i < N; ++i) {\n        if (i % 2 == 0) {\n            for (int j = 0; j < N; ++j) ord.emplace_back(i,j);\n        } else {\n            for (int j = N-1; j >= 0; --j) ord.emplace_back(i,j);\n        }\n    }\n    return ord;\n}\n\n// Hilbert curve mapping based on known algorithm\nvoid rot(int n, int &x, int &y, int rx, int ry) {\n    if (ry == 0) {\n        if (rx == 1) {\n            x = n-1 - x;\n            y = n-1 - y;\n        }\n        // Swap x and y\n        int t = x; x = y; y = t;\n    }\n}\n// d in [0, n*n), map to (x,y) in Hilbert order of size n=2^k\npair<int,int> d2xy(int n, int d) {\n    int x = 0, y = 0;\n    int t = d;\n    for (int s = 1; s < n; s <<= 1) {\n        int rx = 1 & (t >> 1);\n        int ry = 1 & (t ^ rx);\n        rot(s, x, y, rx, ry);\n        x += s * rx;\n        y += s * ry;\n        t >>= 2;\n    }\n    return {y, x}; // we can choose orientation; swap as desired\n}\n\nvector<pair<int,int>> build_hilbert(int N) {\n    int n = 1;\n    while (n < N) n <<= 1; // power of two\n    int total = n * n;\n    vector<pair<int,int>> ord;\n    ord.reserve(N*N);\n    for (int d = 0; d < total; ++d) {\n        auto p = d2xy(n, d);\n        if (p.first >= 0 && p.first < N && p.second >= 0 && p.second < N) {\n            ord.push_back(p);\n            if ((int)ord.size() == N*N) break;\n        }\n    }\n    return ord;\n}\n\nPlan build_plan(int N, const vector<vector<long long>>& h0, const vector<pair<int,int>>& order) {\n    vector<vector<long long>> h = h0;\n    vector<string> ops;\n    ops.reserve(5000);\n    long long cost = 0;\n    long long load = 0;\n    // ensure starting pos is order[0]; initial pos is (0,0). Move there if needed.\n    pair<int,int> cur = {0,0};\n    if (cur != order[0]) {\n        // move empty to order[0]\n        int r = cur.first, c = cur.second;\n        // use Manhattan path\n        while (r < order[0].first) { ops.emplace_back(\"D\"); cost += 100 + load; ++r; }\n        while (r > order[0].first) { ops.emplace_back(\"U\"); cost += 100 + load; --r; }\n        while (c < order[0].second) { ops.emplace_back(\"R\"); cost += 100 + load; ++c; }\n        while (c > order[0].second) { ops.emplace_back(\"L\"); cost += 100 + load; --c; }\n        cur = order[0];\n    }\n    int SZ = (int)order.size();\n    for (int idx = 0; idx + 1 < SZ; ++idx) {\n        auto p = order[idx];\n        auto q = order[idx+1];\n        // Move cur to p if needed (should be at p)\n        if (cur != p) {\n            // move empty to p\n            int r = cur.first, c = cur.second;\n            while (r < p.first) { ops.emplace_back(\"D\"); cost += 100 + load; ++r; }\n            while (r > p.first) { ops.emplace_back(\"U\"); cost += 100 + load; --r; }\n            while (c < p.second) { ops.emplace_back(\"R\"); cost += 100 + load; ++c; }\n            while (c > p.second) { ops.emplace_back(\"L\"); cost += 100 + load; --c; }\n            cur = p;\n        }\n        long long x = h[p.first][p.second];\n        if (x >= 0) {\n            if (x > 0) add_load(x, ops, cost, load);\n            append_move(p, q, ops, cost, load);\n            cur = q;\n            if (x > 0) sub_load(x, ops, cost, load);\n            h[q.first][q.second] += x;\n            h[p.first][p.second] = 0;\n        } else {\n            long long d = -x;\n            // move to q empty\n            append_move(p, q, ops, cost, load);\n            cur = q;\n            add_load(d, ops, cost, load);\n            // move back to p carrying\n            append_move(q, p, ops, cost, load);\n            cur = p;\n            sub_load(d, ops, cost, load);\n            // update heights\n            h[p.first][p.second] = 0;\n            h[q.first][q.second] -= d;\n            // move to q empty to continue\n            append_move(p, q, ops, cost, load);\n            cur = q;\n        }\n        // load should be zero after each edge\n        // if (load != 0) cerr << \"Invariant broken\\n\";\n    }\n    // No need to adjust last cell; it should be zero.\n    Plan res;\n    res.ops = move(ops);\n    res.cost = cost;\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<long long>> h(N, vector<long long>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> h[i][j];\n\n    // Build candidates\n    auto snake = build_snake(N);\n    auto hil = build_hilbert(N);\n\n    Plan plan_snake = build_plan(N, h, snake);\n    Plan plan_hil = build_plan(N, h, hil);\n\n    const Plan* best = &plan_snake;\n    if (plan_hil.cost < plan_snake.cost) best = &plan_hil;\n\n    // Output best plan\n    for (const auto& s : best->ops) {\n        cout << s << '\\n';\n    }\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Seed {\n    int id;\n    array<int,15> x{};\n    int V=0;\n    double score=0;\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,T;\n    if(!(cin>>N>>M>>T)) return 0;\n    const int S = 2*N*(N-1); // 60\n    vector<Seed> seeds(S);\n    for(int i=0;i<S;i++){\n        seeds[i].id = i;\n        int sum=0;\n        for(int l=0;l<M;l++){\n            int v; cin>>v;\n            seeds[i].x[l]=v;\n            sum+=v;\n        }\n        seeds[i].V=sum;\n        seeds[i].score=sum;\n    }\n\n    // Precompute grid structure\n    const int H = N;\n    const int W = N;\n    const int P = H*W; // 36\n    auto pid = [&](int r,int c){ return r*W + c; };\n    vector<vector<int>> adj(P);\n    vector<pair<int,int>> pos_of(P);\n    for(int r=0;r<H;r++){\n        for(int c=0;c<W;c++){\n            int u = pid(r,c);\n            pos_of[u] = {r,c};\n            if(r>0) adj[u].push_back(pid(r-1,c));\n            if(r+1<H) adj[u].push_back(pid(r+1,c));\n            if(c>0) adj[u].push_back(pid(r,c-1));\n            if(c+1<W) adj[u].push_back(pid(r,c+1));\n        }\n    }\n    // Order positions by degree desc then checkerboard preference\n    vector<int> cell_order(P);\n    iota(cell_order.begin(), cell_order.end(), 0);\n    auto degree = [&](int u){ return (int)adj[u].size(); };\n    stable_sort(cell_order.begin(), cell_order.end(), [&](int a, int b){\n        int da = degree(a), db = degree(b);\n        if(da!=db) return da>db;\n        auto [ra,ca] = pos_of[a];\n        auto [rb,cb] = pos_of[b];\n        int caColor = (ra+ca)&1;\n        int cbColor = (rb+cb)&1;\n        if(caColor!=cbColor) return caColor<cbColor; // black first\n        if(ra!=rb) return ra<rb;\n        return ca<cb;\n    });\n\n    auto compute_scores = [&](vector<Seed>& pool){\n        // per-dimension ranks\n        vector<array<int,15>> rankIdx; rankIdx.reserve(pool.size());\n        // For each dimension, sort indices by value to assign rank bonuses\n        vector<int> idx(pool.size());\n        iota(idx.begin(), idx.end(), 0);\n        vector<vector<int>> ranks(M, vector<int>(pool.size(), 0));\n        for(int l=0;l<M;l++){\n            sort(idx.begin(), idx.end(), [&](int a, int b){\n                if(pool[a].x[l]!=pool[b].x[l]) return pool[a].x[l]>pool[b].x[l];\n                return pool[a].V>pool[b].V;\n            });\n            for(int r=0;r<(int)pool.size();r++){\n                ranks[l][idx[r]] = r+1; // 1-based rank\n            }\n        }\n        for(auto &s: pool){\n            s.V = 0;\n            for(int l=0;l<M;l++) s.V += s.x[l];\n        }\n        // scoring: base V + per-dim rank bonuses\n        // bonuses: top1 +3, top3 +2, top6 +1\n        for(int i=0;i<(int)pool.size();i++){\n            double bonus = 0.0;\n            for(int l=0;l<M;l++){\n                int r = ranks[l][i];\n                if(r==1) bonus += 3.0;\n                else if(r<=3) bonus += 2.0;\n                else if(r<=6) bonus += 1.0;\n            }\n            // slight weight to V to not ignore overall sum\n            pool[i].score = pool[i].V + 8.0*bonus;\n        }\n    };\n\n    // Edge fitness proxy: sum of per-dim max over two seeds\n    auto edge_fitness = [&](const Seed& a, const Seed& b)->int{\n        int s=0;\n        for(int l=0;l<M;l++) s += max(a.x[l], b.x[l]);\n        return s;\n    };\n\n    // placement improvement via local search swaps\n    auto improve_layout = [&](vector<int>& seedIds, const vector<Seed>& pool){\n        // seedIds: size P mapping position index -> pool index (in pool vector)\n        // Precompute neighbors list once\n        int E = 0;\n        vector<pair<int,int>> undirectedEdges; undirectedEdges.reserve(P*2);\n        vector<vector<int>> posEdgeIdx(P);\n        // Build undirected edges list without duplicates\n        vector<char> seen(P*P, 0);\n        auto enc = [&](int a,int b){ return a*P + b; };\n        for(int u=0;u<P;u++){\n            for(int v: adj[u]){\n                if(u<v && !seen[enc(u,v)]){\n                    seen[enc(u,v)]=1;\n                    undirectedEdges.emplace_back(u,v);\n                    posEdgeIdx[u].push_back((int)undirectedEdges.size()-1);\n                    posEdgeIdx[v].push_back((int)undirectedEdges.size()-1);\n                    E++;\n                }\n            }\n        }\n        // Compute current total fitness\n        vector<int> edgeVal(E,0);\n        long long total = 0;\n        for(int e=0;e<E;e++){\n            int u = undirectedEdges[e].first;\n            int v = undirectedEdges[e].second;\n            const Seed& A = pool[ seedIds[u] ];\n            const Seed& B = pool[ seedIds[v] ];\n            int val = edge_fitness(A,B);\n            edgeVal[e]=val;\n            total += val;\n        }\n        // Greedy random local search\n        // Limit iterations to keep under time; per-turn budget small\n        // Try both random and best-improvement among few candidates\n        mt19937 rng(1234567u + (unsigned)chrono::high_resolution_clock::now().time_since_epoch().count());\n        int ITER = 4000;\n        uniform_int_distribution<int> distPos(0, P-1);\n        for(int it=0; it<ITER; it++){\n            int a = distPos(rng);\n            int b = distPos(rng);\n            if(a==b) continue;\n            // compute delta if swap seedIds[a] <-> seedIds[b]\n            long long delta = 0;\n            // affected edges are edges adjacent to a or b\n            // subtract old, add new\n            // to avoid double counting, we can sum over their incident edges, but be careful not to recompute edges touching both (rare unless adjacent)\n            // We'll mark processed edges\n            static array<int,256> mark; // enough, E <= 60\n            static int stamp = 1;\n            stamp++;\n            if(stamp==INT_MAX){ fill(mark.begin(), mark.end(), 0); stamp=1; }\n            auto account = [&](int pos, int newSeedIdx){\n                for(int ei: posEdgeIdx[pos]){\n                    if(mark[ei]==stamp) continue;\n                    mark[ei]=stamp;\n                    int u = undirectedEdges[ei].first;\n                    int v = undirectedEdges[ei].second;\n                    int sid_u = seedIds[u];\n                    int sid_v = seedIds[v];\n                    // current value\n                    int oldv = edgeVal[ei];\n                    delta -= oldv;\n                    // after swap: if pos==u use newSeedIdx, else keep sid_u; similarly for b handled by second call\n                    int su = (u==a? newSeedIdx : (u==b? seedIds[a] : sid_u));\n                    int sv = (v==a? newSeedIdx : (v==b? seedIds[a] : sid_v));\n                    // Wait: we call account twice; to compute properly, we should apply both new assignments simultaneously.\n                }\n            };\n            // Recompute delta more straightforwardly: iterate affected edges set and compute new values explicitly with swapped assignment.\n            vector<int> affected;\n            affected.reserve(posEdgeIdx[a].size()+posEdgeIdx[b].size()+2);\n            for(int ei: posEdgeIdx[a]) affected.push_back(ei);\n            for(int ei: posEdgeIdx[b]) affected.push_back(ei);\n            sort(affected.begin(), affected.end());\n            affected.erase(unique(affected.begin(), affected.end()), affected.end());\n            long long newSum = 0, oldSum = 0;\n            for(int ei: affected){\n                int u = undirectedEdges[ei].first;\n                int v = undirectedEdges[ei].second;\n                oldSum += edgeVal[ei];\n                int su = seedIds[u];\n                int sv = seedIds[v];\n                if(u==a) su = seedIds[b];\n                else if(u==b) su = seedIds[a];\n                if(v==a) sv = seedIds[b];\n                else if(v==b) sv = seedIds[a];\n                int val = edge_fitness( pool[su], pool[sv] );\n                newSum += val;\n            }\n            delta = newSum - oldSum;\n            if(delta > 0){\n                // accept swap\n                swap(seedIds[a], seedIds[b]);\n                total += delta;\n                for(int ei: affected){\n                    int u = undirectedEdges[ei].first;\n                    int v = undirectedEdges[ei].second;\n                    int su = seedIds[u];\n                    int sv = seedIds[v];\n                    edgeVal[ei] = edge_fitness(pool[su], pool[sv]);\n                }\n            }\n        }\n        // done\n    };\n\n    for(int t=0;t<T;t++){\n        compute_scores(seeds);\n\n        // select top 36\n        vector<int> order(S);\n        iota(order.begin(), order.end(), 0);\n        nth_element(order.begin(), order.begin()+N*N, order.end(), [&](int a, int b){\n            if(seeds[a].score!=seeds[b].score) return seeds[a].score>seeds[b].score;\n            return seeds[a].V>seeds[b].V;\n        });\n        order.resize(N*N);\n        sort(order.begin(), order.end(), [&](int a, int b){\n            if(seeds[a].score!=seeds[b].score) return seeds[a].score>seeds[b].score;\n            return seeds[a].V>seeds[b].V;\n        });\n\n        // Build selected pool (indices into seeds)\n        vector<int> sel = order; // size P\n        // Initial placement by cell_order\n        vector<int> pos2poolIdx(P, -1);\n        for(int k=0;k<P;k++){\n            pos2poolIdx[ cell_order[k] ] = sel[k];\n        }\n\n        // Improve layout via local search maximizing sum over edges of sum(max per-dim)\n        improve_layout(pos2poolIdx, seeds);\n\n        // Output placement grid with seed IDs\n        vector<vector<int>> A(N, vector<int>(N,-1));\n        for(int pos=0;pos<P;pos++){\n            auto [r,c] = pos_of[pos];\n            A[r][c] = seeds[ pos2poolIdx[pos] ].id;\n        }\n        for(int i=0;i<N;i++){\n            for(int j=0;j<N;j++){\n                if(j) cout << ' ';\n                cout << A[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // Read next generation\n        vector<Seed> next(S);\n        for(int i=0;i<S;i++){\n            next[i].id = i;\n            int sum=0;\n            for(int l=0;l<M;l++){\n                int v; cin>>v;\n                next[i].x[l]=v;\n                sum+=v;\n            }\n            next[i].V = sum;\n            next[i].score = sum;\n        }\n        seeds.swap(next);\n    }\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Task {\n    int sx, sy, tx, ty;\n    int dir_pick; // 0:R,1:D,2:L,3:U\n    int rpx, rpy;\n    int dir_drop;\n    int rdx, rdy;\n};\n\ninline int manh(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\n\nint choose_dir_for_cell(int x,int y,int N,int prefer_dir=-1){\n    static const int dx[4]={0,1,0,-1};\n    static const int dy[4]={1,0,-1,0};\n    if(prefer_dir!=-1){\n        int rx = x - dx[prefer_dir], ry = y - dy[prefer_dir];\n        if(0<=rx && rx<N && 0<=ry && ry<N) return prefer_dir;\n    }\n    // Prefer directions in a fixed order to be stable: Right, Down, Left, Up\n    for(int k=0;k<4;k++){\n        int rx = x - dx[k], ry = y - dy[k];\n        if(0<=rx && rx<N && 0<=ry && ry<N) return k;\n    }\n    return 0;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\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    vector<pair<int,int>> S, D;\n    vector<vector<int>> occ(N, vector<int>(N,0));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            int si = s[i][j]-'0';\n            int ti = t[i][j]-'0';\n            occ[i][j]=si;\n            if(si==1 && ti==0) S.emplace_back(i,j);\n            if(si==0 && ti==1) D.emplace_back(i,j);\n        }\n    }\n\n    // Multi-start greedy matching to reduce sum of |s-t|\n    vector<pair<pair<int,int>, pair<int,int>>> best_pairs;\n    long long best_cost = (1LL<<60);\n    vector<int> idxS(S.size());\n    iota(idxS.begin(), idxS.end(), 0);\n    mt19937 rng(712367);\n    int attempts = 8; // small number for speed\n    for(int att=0; att<attempts; ++att){\n        if(att) shuffle(idxS.begin(), idxS.end(), rng);\n        vector<char> usedD(D.size(), 0);\n        vector<pair<pair<int,int>, pair<int,int>>> pairs;\n        pairs.reserve(S.size());\n        long long cost = 0;\n        for(int idS : idxS){\n            auto sp = S[idS];\n            int bestIdx=-1, bestDist=INT_MAX;\n            // small heuristic: limit search radius gradually? For simplicity full scan.\n            for(size_t j=0;j<D.size();j++){\n                if(usedD[j]) continue;\n                int d = manh(sp.first, sp.second, D[j].first, D[j].second);\n                if(d < bestDist){\n                    bestDist = d; bestIdx = (int)j;\n                }\n            }\n            if(bestIdx==-1) continue;\n            usedD[bestIdx]=1;\n            pairs.push_back({sp, D[bestIdx]});\n            cost += bestDist;\n        }\n        if(cost < best_cost){\n            best_cost = cost;\n            best_pairs.swap(pairs);\n        }\n    }\n\n    // Build tasks (directions chosen to minimize rotations progressively)\n    vector<Task> tasks;\n    tasks.reserve(best_pairs.size());\n    int hint_dir = 0; // initial leaf direction: Right\n    static const int dx4[4]={0,1,0,-1};\n    static const int dy4[4]={1,0,-1,0};\n    for(auto &pr : best_pairs){\n        Task tk;\n        tk.sx = pr.first.first; tk.sy = pr.first.second;\n        tk.tx = pr.second.first; tk.ty = pr.second.second;\n        // Choose pick dir close to hint_dir\n        int dirp = choose_dir_for_cell(tk.sx, tk.sy, N, hint_dir);\n        tk.dir_pick = dirp;\n        tk.rpx = tk.sx - dx4[dirp];\n        tk.rpy = tk.sy - dy4[dirp];\n        // Choose drop dir close to pick dir (to reduce rotations between pick and drop)\n        int dird = choose_dir_for_cell(tk.tx, tk.ty, N, dirp);\n        tk.dir_drop = dird;\n        tk.rdx = tk.tx - dx4[dird];\n        tk.rdy = tk.ty - dy4[dird];\n        hint_dir = dird;\n        tasks.push_back(tk);\n    }\n\n    // Order tasks: greedy NN + a light 2-opt\n    int rx=0, ry=0;\n    vector<int> order;\n    order.reserve(tasks.size());\n    vector<char> used(tasks.size(), 0);\n    for(size_t it=0; it<tasks.size(); it++){\n        int best=-1, bd=INT_MAX;\n        for(size_t i=0;i<tasks.size();i++){\n            if(used[i]) continue;\n            int d = manh(rx,ry,tasks[i].rpx,tasks[i].rpy);\n            if(d<bd){ bd=d; best=(int)i; }\n        }\n        if(best==-1) break;\n        used[best]=1;\n        order.push_back(best);\n        rx = tasks[best].rpx; ry = tasks[best].rpy;\n    }\n\n    // 2-opt on order to reduce travel between rpx waypoints\n    auto path_cost = [&](const vector<int>& ord)->long long{\n        int crx=0, cry=0;\n        long long cost=0;\n        for(int id: ord){\n            cost += manh(crx,cry,tasks[id].rpx,tasks[id].rpy);\n            crx = tasks[id].rpx; cry = tasks[id].rpy;\n        }\n        return cost;\n    };\n    long long curr_cost = path_cost(order);\n    // limited time budget: small number of random 2-opt attempts\n    uniform_int_distribution<int> distIdx(0, (int)order.size()-1);\n    for(int iter=0; iter<2000 && (int)order.size()>=4; ++iter){\n        int a = distIdx(rng);\n        int b = distIdx(rng);\n        if(a>b) swap(a,b);\n        if(b-a<2) continue;\n        // compute delta if reversing (a..b-1)\n        auto getX = [&](int pos)->pair<int,int>{\n            if(pos<0) return {0,0};\n            return {tasks[order[pos]].rpx, tasks[order[pos]].rpy};\n        };\n        int Aprevx, Aprevy, Ax, Ay, Bx, By, Bnextx, Bnexty;\n        tie(Ax,Ay) = getX(a);\n        tie(Bx,By) = getX(b-1);\n        tie(Aprevx,Aprevy) = (a==0? make_pair(0,0) : make_pair(tasks[order[a-1]].rpx, tasks[order[a-1]].rpy));\n        tie(Bnextx,Bnexty) = (b==(int)order.size()? make_pair(Bx,By) : make_pair(tasks[order[b]].rpx, tasks[order[b]].rpy));\n        long long before = manh(Aprevx,Aprevy,Ax,Ay) + manh(Bx,By,Bnextx,Bnexty);\n        long long after  = manh(Aprevx,Aprevy,Bx,By) + manh(Ax,Ay,Bnextx,Bnexty);\n        if(after + 0 < before){\n            reverse(order.begin()+a, order.begin()+b);\n            curr_cost += (after - before);\n        }\n    }\n\n    // Execution\n    rx=0; ry=0;\n    int leaf_dir = 0; // Right\n    bool holding=false;\n\n    vector<string> out;\n    out.reserve(200000);\n    const int TURN_LIMIT = 100000;\n\n    auto emit_turn = [&](char moveChar, char rotChar, bool doP)->void{\n        string st(4,'.');\n        if(moveChar) st[0]=moveChar;\n        if(rotChar) st[1]=rotChar;\n        if(doP) st[3]='P';\n        out.push_back(st);\n    };\n\n    auto step_move = [&](int tx,int ty, int &pendingRotCW, int &pendingRotCCW){\n        // Move one step towards (tx,ty), combining at most one rotation in the same turn if pending\n        char mv='.';\n        if(rx<tx){ mv='D'; rx++; }\n        else if(rx>tx){ mv='U'; rx--; }\n        else if(ry<ty){ mv='R'; ry++; }\n        else if(ry>ty){ mv='L'; ry--; }\n        char rot='.';\n        if(pendingRotCW>0){\n            rot='R'; pendingRotCW--; leaf_dir=(leaf_dir+1)&3;\n        }else if(pendingRotCCW>0){\n            rot='L'; pendingRotCCW--; leaf_dir=(leaf_dir+3)&3;\n        }\n        emit_turn(mv, rot, false);\n    };\n\n    auto move_root_to = [&](int tx,int ty, int &pendingRotCW, int &pendingRotCCW){\n        while((rx!=tx || ry!=ty) && (int)out.size()<TURN_LIMIT){\n            step_move(tx,ty,pendingRotCW,pendingRotCCW);\n        }\n    };\n\n    for(int idx : order){\n        if((int)out.size() >= TURN_LIMIT) break;\n        Task &tk = tasks[idx];\n\n        // Determine rotations needed to align for pick, and for drop\n        auto rot_delta = [&](int fromDir,int toDir){\n            int d = (toDir - fromDir + 4) % 4;\n            // choose CW if d in {1,2}; CCW if d in {3}\n            int cw=0, ccw=0;\n            if(d==1){ cw=1; }\n            else if(d==2){ cw=2; } // or ccw=2; CW chosen\n            else if(d==3){ ccw=1; }\n            return pair<int,int>(cw,ccw);\n        };\n\n        // Plan to go to pick root while consuming needed rotations to reach dir_pick\n        int pendCW=0, pendCCW=0;\n        tie(pendCW, pendCCW) = rot_delta(leaf_dir, tk.dir_pick);\n        move_root_to(tk.rpx, tk.rpy, pendCW, pendCCW);\n        // If rotations remain after arriving, finish them with idle moves (no move, just rotate)\n        while((pendCW>0 || pendCCW>0) && (int)out.size()<TURN_LIMIT){\n            char rot='.';\n            if(pendCW>0){ rot='R'; pendCW--; leaf_dir=(leaf_dir+1)&3; }\n            else { rot='L'; pendCCW--; leaf_dir=(leaf_dir+3)&3; }\n            emit_turn('.', rot, false);\n        }\n        if((int)out.size() >= TURN_LIMIT) break;\n\n        // Pick\n        int fx = rx + dx4[leaf_dir];\n        int fy = ry + dy4[leaf_dir];\n        bool canPick = (0<=fx && fx<N && 0<=fy && fy<N && !holding && occ[fx][fy]==1);\n        emit_turn('.', '.', canPick);\n        if(canPick){ holding=true; occ[fx][fy]=0; }\n        if((int)out.size() >= TURN_LIMIT) break;\n\n        // Plan rotations toward drop dir while moving to drop root\n        tie(pendCW, pendCCW) = rot_delta(leaf_dir, tk.dir_drop);\n        move_root_to(tk.rdx, tk.rdy, pendCW, pendCCW);\n        while((pendCW>0 || pendCCW>0) && (int)out.size()<TURN_LIMIT){\n            char rot='.';\n            if(pendCW>0){ rot='R'; pendCW--; leaf_dir=(leaf_dir+1)&3; }\n            else { rot='L'; pendCCW--; leaf_dir=(leaf_dir+3)&3; }\n            emit_turn('.', rot, false);\n        }\n        if((int)out.size() >= TURN_LIMIT) break;\n\n        // Drop\n        fx = rx + dx4[leaf_dir];\n        fy = ry + dy4[leaf_dir];\n        bool canDrop = (0<=fx && fx<N && 0<=fy && fy<N && holding && occ[fx][fy]==0);\n        emit_turn('.', '.', canDrop);\n        if(canDrop){ holding=false; occ[fx][fy]=1; }\n        if((int)out.size() >= TURN_LIMIT) break;\n    }\n\n    // Output arm design: 2 vertices, edge length 1, root at (0,0)\n    cout<<2<<\"\\n\";\n    cout<<0<<\" \"<<1<<\"\\n\";\n    cout<<0<<\" \"<<0<<\"\\n\";\n    for(auto &row : out) cout<<row<<\"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    int w; // +1 mackerel, -1 sardine\n};\nstruct Rect {\n    int x1,y1,x2,y2; // inclusive\n    long long score = LLONG_MIN;\n    int a=0,b=0;\n};\n\nstatic inline long long rect_perimeter(int x1,int y1,int x2,int y2){\n    long long w = llabs((long long)x2 - x1);\n    long long h = llabs((long long)y2 - y1);\n    return 2*(w + h);\n}\nstatic inline bool insideRectInclusive(const Rect& r, int x, int y){\n    return (x >= r.x1 && x <= r.x2 && y >= r.y1 && y <= r.y2);\n}\n\nstruct Grid {\n    int G;\n    int B; // bin size\n    int maxCoord = 100000;\n    int W,H;\n    vector<int> a; // W*H\n    vector<long long> ps; // (W+1)*(H+1)\n    Grid(int G_): G(G_) {\n        B = (maxCoord + G - 1) / G; // ceil division\n        W = G; H = G;\n        a.assign(W*H, 0);\n        ps.assign((W+1)*(H+1), 0);\n    }\n    inline int idx(int ix,int iy) const { return iy*W + ix; }\n    inline void addPoint(int x,int y,int w){\n        int ix = min(W-1, x / B);\n        int iy = min(H-1, y / B);\n        a[idx(ix,iy)] += w;\n    }\n    void buildPS(){\n        for(int iy=0; iy<=H; ++iy){\n            for(int ix=0; ix<=W; ++ix){\n                if (ix==0 || iy==0) { ps[iy*(W+1)+ix] = 0; }\n            }\n        }\n        for(int iy=1; iy<=H; ++iy){\n            long long run = 0;\n            for(int ix=1; ix<=W; ++ix){\n                run += a[idx(ix-1,iy-1)];\n                ps[iy*(W+1)+ix] = ps[(iy-1)*(W+1)+ix] + run;\n            }\n        }\n    }\n    inline long long sumRectCells(int lx,int ly,int rx,int ry) const {\n        if (lx>rx || ly>ry) return 0;\n        lx = max(0,lx); ly = max(0,ly);\n        rx = min(W-1,rx); ry = min(H-1,ry);\n        if (lx>rx || ly>ry) return 0;\n        long long s = ps[(ry+1)*(W+1)+(rx+1)]\n                    - ps[(ly)*(W+1)+(rx+1)]\n                    - ps[(ry+1)*(W+1)+(lx)]\n                    + ps[(ly)*(W+1)+(lx)];\n        return s;\n    }\n    inline int cellX1(int ix) const { return max(0, ix * B); }\n    inline int cellX2(int ix) const { return min(maxCoord, (ix+1)*B); }\n    inline int cellY1(int iy) const { return max(0, iy * B); }\n    inline int cellY2(int iy) const { return min(maxCoord, (iy+1)*B); }\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    for(int i=0;i<N;i++){ int x,y; cin>>x>>y; pts.push_back({x,y,+1}); }\n    for(int i=0;i<N;i++){ int x,y; cin>>x>>y; pts.push_back({x,y,-1}); }\n\n    const long long PERIM_LIMIT = 400000;\n    const int MAXC = 100000;\n\n    // Build multiple grids\n    vector<int> Gsizes = {256, 384, 512};\n    vector<Grid> grids;\n    grids.reserve(Gsizes.size());\n    for(int g: Gsizes) grids.emplace_back(g);\n    for (auto &p: pts)\n        for (auto &gr: grids) gr.addPoint(p.x, p.y, p.w);\n    for (auto &gr: grids) gr.buildPS();\n\n    // Candidate pool\n    vector<Rect> candidates;\n    candidates.reserve(4000);\n\n    auto clamp_rect = [&](Rect r)->Rect{\n        r.x1 = max(0, min(MAXC, r.x1));\n        r.x2 = max(0, min(MAXC, r.x2));\n        r.y1 = max(0, min(MAXC, r.y1));\n        r.y2 = max(0, min(MAXC, r.y2));\n        if (r.x1 > r.x2) swap(r.x1, r.x2);\n        if (r.y1 > r.y2) swap(r.y1, r.y2);\n        if (r.x1==r.x2) { if (r.x2<MAXC) r.x2++; else if (r.x1>0) r.x1--; }\n        if (r.y1==r.y2) { if (r.y2<MAXC) r.y2++; else if (r.y1>0) r.y1--; }\n        if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) > PERIM_LIMIT){\n            // shrink around center\n            long long w = r.x2 - r.x1;\n            long long h = r.y2 - r.y1;\n            if (w + h == 0) return r;\n            long long max_sum = PERIM_LIMIT/2;\n            double scale = (double)max_sum / (double)(w + h);\n            long long nw = max(1LL, (long long)(w*scale));\n            long long nh = max(1LL, (long long)(h*scale));\n            long long cx = (r.x1 + r.x2)/2;\n            long long cy = (r.y1 + r.y2)/2;\n            long long nx1 = max(0LL, cx - nw/2);\n            long long nx2 = min((long long)MAXC, nx1 + nw);\n            nx1 = max(0LL, nx2 - nw);\n            long long ny1 = max(0LL, cy - nh/2);\n            long long ny2 = min((long long)MAXC, ny1 + nh);\n            ny1 = max(0LL, ny2 - nh);\n            r.x1 = (int)nx1; r.x2 = (int)nx2;\n            r.y1 = (int)ny1; r.y2 = (int)ny2;\n        }\n        return r;\n    };\n    auto add_candidate = [&](Rect r){\n        r = clamp_rect(r);\n        candidates.push_back(r);\n    };\n\n    // Grid-based candidates with multi-step expansions (binary search per side)\n    for (auto &gr: grids){\n        int W=gr.W, H=gr.H;\n        struct Cell { int ix,iy; int val; };\n        vector<Cell> cells;\n        cells.reserve(W*H);\n        for(int iy=0; iy<H; ++iy)\n            for(int ix=0; ix<W; ++ix)\n                cells.push_back({ix,iy, gr.a[gr.idx(ix,iy)]});\n        int T = min(300, (int)cells.size());\n        nth_element(cells.begin(), cells.begin()+T, cells.end(), [](const Cell& a, const Cell& b){ return a.val > b.val; });\n        cells.resize(T);\n\n        auto rectFromCells = [&](int lx,int ly,int rx,int ry)->Rect{\n            return Rect{ gr.cellX1(lx), gr.cellY1(ly), gr.cellX2(rx), gr.cellY2(ry), 0 };\n        };\n        auto perim_ok_cells = [&](int lx,int ly,int rx,int ry)->bool{\n            Rect r = rectFromCells(lx,ly,rx,ry);\n            return rect_perimeter(r.x1,r.y1,r.x2,r.y2) <= PERIM_LIMIT;\n        };\n        for (const auto &c: cells){\n            int lx=c.ix, rx=c.ix, ly=c.iy, ry=c.iy;\n            long long bestS = gr.sumRectCells(lx,ly,rx,ry);\n            bool improved = true;\n            int iter=0;\n            while (improved && iter<200){\n                ++iter;\n                improved = false;\n                int blx=lx, bly=ly, brx=rx, bry=ry;\n                long long bS = bestS;\n\n                // For each direction, try to expand by multiple cells using exponential then binary search\n                auto try_expand = [&](int &lx,int &ly,int &rx,int &ry, int dir)->void{\n                    // dir: 0 expand left, 1 right, 2 down, 3 up\n                    int Lx=lx, Ly=ly, Rx=rx, Ry=ry;\n                    int lo=0, hi=0;\n                    auto sumHere = [&](int Lx,int Ly,int Rx,int Ry){ return gr.sumRectCells(Lx,Ly,Rx,Ry); };\n                    auto ok = [&](int Lx,int Ly,int Rx,int Ry){ return perim_ok_cells(Lx,Ly,Rx,Ry); };\n                    // prepare movement limits\n                    auto advance = [&](int step)->bool{\n                        int nlx=Lx, nly=Ly, nrx=Rx, nry=Ry;\n                        if (dir==0) nlx = Lx - step;\n                        else if (dir==1) nrx = Rx + step;\n                        else if (dir==2) nly = Ly - step;\n                        else nry = Ry + step;\n                        if (nlx<0 || nly<0 || nrx>=W || nry>=H) return false;\n                        if (!ok(nlx,nly,nrx,nry)) return false;\n                        long long s = sumHere(nlx,nly,nrx,nry);\n                        if (s > bS){ bS = s; blx=nlx; bly=nly; brx=nrx; bry=nry; return true; }\n                        return false;\n                    };\n                    // exponential search for hi\n                    int step = 1;\n                    int lastGood = 0;\n                    while (true){\n                        int nlx=Lx, nly=Ly, nrx=Rx, nry=Ry;\n                        if (dir==0) nlx = Lx - step;\n                        else if (dir==1) nrx = Rx + step;\n                        else if (dir==2) nly = Ly - step;\n                        else nry = Ry + step;\n                        if (nlx<0 || nly<0 || nrx>=W || nry>=H) break;\n                        if (!ok(nlx,nly,nrx,nry)) break;\n                        lastGood = step;\n                        step <<= 1;\n                        if (step <= 0) break;\n                    }\n                    if (lastGood==0) return;\n                    // binary search in [1..lastGood] for best sum (not necessarily monotonic, but we will sample midpoints improving only; to stay simple, we can just try a few splits)\n                    int loStep = 1, hiStep = lastGood;\n                    // Instead of true binary search, try few trial steps: quarter, half, three-quarter, and lastGood\n                    vector<int> trials = { hiStep, hiStep*3/4, hiStep/2, hiStep/4 };\n                    sort(trials.begin(), trials.end());\n                    trials.erase(unique(trials.begin(), trials.end()), trials.end());\n                    for (int s: trials){\n                        int nlx=Lx, nly=Ly, nrx=Rx, nry=Ry;\n                        if (dir==0) nlx = Lx - s;\n                        else if (dir==1) nrx = Rx + s;\n                        else if (dir==2) nly = Ly - s;\n                        else nry = Ry + s;\n                        if (nlx<0 || nly<0 || nrx>=W || nry>=H) continue;\n                        if (!ok(nlx,nly,nrx,nry)) continue;\n                        long long val = sumHere(nlx,nly,nrx,nry);\n                        if (val > bS){ bS=val; blx=nlx; bly=nly; brx=nrx; bry=nry; }\n                    }\n                };\n\n                try_expand(lx,ly,rx,ry,0);\n                try_expand(lx,ly,rx,ry,1);\n                try_expand(lx,ly,rx,ry,2);\n                try_expand(lx,ly,rx,ry,3);\n\n                // Small shrinks might help if sardine-heavy margins got included\n                auto try_shrink = [&](int dir)->void{\n                    int nlx=lx, nly=ly, nrx=rx, nry=ry;\n                    if (dir==0 && lx<rx) nlx=lx+1;\n                    if (dir==1 && lx<rx) nrx=rx-1;\n                    if (dir==2 && ly<ry) nly=ly+1;\n                    if (dir==3 && ly<ry) nry=ry-1;\n                    if (nlx>nrx || nly>nry) return;\n                    long long s = gr.sumRectCells(nlx,nly,nrx,nry);\n                    if (s > bS){ bS=s; blx=nlx; bly=nly; brx=nrx; bry=nry; }\n                };\n                try_shrink(0); try_shrink(1); try_shrink(2); try_shrink(3);\n\n                if (bS > bestS){\n                    bestS = bS;\n                    lx=blx; ly=bly; rx=brx; ry=bry;\n                    improved = true;\n                }\n            }\n            Rect r = rectFromCells(lx,ly,rx,ry);\n            add_candidate(r);\n\n            // Add a few variants: small expansions if within perimeter\n            int variants = 3;\n            for(int t=1;t<=variants;t++){\n                int elx = max(0, lx - t);\n                int erx = min(W-1, rx + t);\n                int ely = max(0, ly - t);\n                int ery = min(H-1, ry + t);\n                Rect r2 = rectFromCells(elx,ly,rx,ry); add_candidate(r2);\n                r2 = rectFromCells(lx,ely,rx,ry); add_candidate(r2);\n                r2 = rectFromCells(lx,ly,erx,ry); add_candidate(r2);\n                r2 = rectFromCells(lx,ly,rx,ery); add_candidate(r2);\n            }\n        }\n    }\n\n    // Random sampling using biased coordinates\n    vector<int> xs_all, ys_all, xs_m, ys_m;\n    xs_all.reserve(pts.size()); ys_all.reserve(pts.size());\n    xs_m.reserve(pts.size()); ys_m.reserve(pts.size());\n    for (auto &p: pts){\n        xs_all.push_back(p.x); ys_all.push_back(p.y);\n        if (p.w==+1){ xs_m.push_back(p.x); ys_m.push_back(p.y); }\n    }\n    auto sample_unique = [&](const vector<int>& v, int k){\n        int M = v.size();\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        static std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n        shuffle(idx.begin(), idx.end(), rng);\n        unordered_set<int> seen;\n        seen.reserve(k*2);\n        vector<int> out; out.reserve(k);\n        for(int i=0;i<M && (int)out.size()<k;i++){\n            int val = v[idx[i]];\n            if (seen.insert(val).second) out.push_back(val);\n        }\n        sort(out.begin(), out.end());\n        return out;\n    };\n    vector<int> sx_all = sample_unique(xs_all, 250);\n    vector<int> sy_all = sample_unique(ys_all, 250);\n    vector<int> sx_m = sample_unique(xs_m, 250);\n    vector<int> sy_m = sample_unique(ys_m, 250);\n    auto merge_coords = [&](vector<int> a, vector<int> b){\n        a.insert(a.end(), b.begin(), b.end());\n        a.push_back(0); a.push_back(MAXC);\n        sort(a.begin(), a.end());\n        a.erase(unique(a.begin(), a.end()), a.end());\n        return a;\n    };\n    vector<int> sx = merge_coords(sx_all, sx_m);\n    vector<int> sy = merge_coords(sy_all, sy_m);\n\n    std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto randint = [&](int L, int R){ std::uniform_int_distribution<int> dist(L,R); return dist(rng); };\n\n    int Xn = (int)sx.size();\n    int Yn = (int)sy.size();\n\n    auto add_rect_from_bounds = [&](int xl,int xr,int yl,int yr){\n        if (xl==xr){ if (xr<MAXC) xr++; else if (xl>0) xl--; }\n        if (yl==yr){ if (yr<MAXC) yr++; else if (yl>0) yl--; }\n        Rect r{xl,yl,xr,yr,0};\n        if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) <= PERIM_LIMIT) add_candidate(r);\n    };\n\n    // Uniform random pairs\n    int S = 2000;\n    for(int t=0;t<S;t++){\n        int i1 = randint(0, Xn-1), i2 = randint(0, Xn-1);\n        int j1 = randint(0, Yn-1), j2 = randint(0, Yn-1);\n        if (i1==i2){ if (i2+1<Xn) i2++; else if (i1>0) i1--; }\n        if (j1==j2){ if (j2+1<Yn) j2++; else if (j1>0) j1--; }\n        int xl = min(sx[i1], sx[i2]);\n        int xr = max(sx[i1], sx[i2]);\n        int yl = min(sy[j1], sy[j2]);\n        int yr = max(sy[j1], sy[j2]);\n        add_rect_from_bounds(xl,xr,yl,yr);\n    }\n    // Biased rectangles: use mackerel coords for one axis\n    int Sb = 1000;\n    for(int t=0;t<Sb;t++){\n        int i1 = randint(0, (int)sx_m.size()-1);\n        int i2 = randint(0, (int)sx_m.size()-1);\n        int j1 = randint(0, Yn-1);\n        int j2 = randint(0, Yn-1);\n        if (i1==i2){ if (i2+1<(int)sx_m.size()) i2++; else if (i1>0) i1--; }\n        if (j1==j2){ if (j2+1<Yn) j2++; else if (j1>0) j1--; }\n        int xl = min(sx_m[i1], sx_m[i2]);\n        int xr = max(sx_m[i1], sx_m[i2]);\n        int yl = min(sy[j1], sy[j2]);\n        int yr = max(sy[j1], sy[j2]);\n        add_rect_from_bounds(xl,xr,yl,yr);\n    }\n    // Anchored rectangles\n    for(int t=0;t<400;t++){\n        int i = randint(0, Xn-1);\n        int j = randint(0, Yn-1);\n        int xl = min(sx[i], MAXC/2);\n        int xr = MAXC;\n        int yl = min(sy[j], MAXC/2);\n        int yr = MAXC;\n        add_rect_from_bounds(xl,xr,yl,yr);\n        add_rect_from_bounds(0, sx[i], 0, sy[j]);\n    }\n\n    // Exact evaluation function\n    auto evaluate = [&](Rect &r){\n        int a=0,b=0;\n        for (auto &p: pts){\n            if (insideRectInclusive(r, p.x, p.y)){\n                if (p.w==1) a++; else b++;\n            }\n        }\n        r.a = a; r.b = b;\n        r.score = (long long)a - (long long)b;\n    };\n\n    // Evaluate all candidates and keep top K\n    for (auto &r: candidates){\n        // ensure within limits\n        r = clamp_rect(r);\n    }\n    // Deduplicate rough by hashing bounds to reduce repeated evals\n    sort(candidates.begin(), candidates.end(), [](const Rect& A, const Rect& B){\n        if (A.x1!=B.x1) return A.x1<B.x1;\n        if (A.y1!=B.y1) return A.y1<B.y1;\n        if (A.x2!=B.x2) return A.x2<B.x2;\n        return A.y2<B.y2;\n    });\n    candidates.erase(unique(candidates.begin(), candidates.end(), [](const Rect& A, const Rect& B){\n        return A.x1==B.x1 && A.y1==B.y1 && A.x2==B.x2 && A.y2==B.y2;\n    }), candidates.end());\n\n    // Evaluate, keep top M\n    int Mkeep = 80;\n    vector<Rect> top;\n    top.reserve(Mkeep);\n    Rect best; best.score = LLONG_MIN;\n    for (auto &r: candidates){\n        evaluate(r);\n        if ((int)top.size() < Mkeep){\n            top.push_back(r);\n        }else{\n            // keep if better than worst\n            int worst = 0;\n            for (int i=1;i<Mkeep;i++) if (top[i].score < top[worst].score) worst = i;\n            if (r.score > top[worst].score || (r.score==top[worst].score && r.a > top[worst].a)){\n                top[worst] = r;\n            }\n        }\n        if (r.score > best.score || (r.score==best.score && r.a > best.a)) best = r;\n    }\n    if (top.empty()){\n        Rect r{0,0,MAXC,MAXC,0}; evaluate(r); best=r; top.push_back(r);\n    }\n\n    // Exact coordinate-descent refinement on top K\n    // Prepare candidate coordinate sets (unique x,y from points near the rectangle)\n    vector<int> xs_pts, ys_pts;\n    xs_pts.reserve(pts.size()); ys_pts.reserve(pts.size());\n    for (auto &p: pts){ xs_pts.push_back(p.x); ys_pts.push_back(p.y); }\n    sort(xs_pts.begin(), xs_pts.end()); xs_pts.erase(unique(xs_pts.begin(), xs_pts.end()), xs_pts.end());\n    sort(ys_pts.begin(), ys_pts.end()); ys_pts.erase(unique(ys_pts.begin(), ys_pts.end()), ys_pts.end());\n\n    auto refine_rect = [&](Rect r){\n        // Limit candidate positions to around current bounds to keep complexity reasonable\n        auto gather_candidates = [&](const vector<int>& v, int low, int high, int k)->vector<int>{\n            // collect indices near low and high\n            vector<int> cand;\n            cand.reserve(k*2 + 10);\n            int iLow = lower_bound(v.begin(), v.end(), low) - v.begin();\n            int iHigh = lower_bound(v.begin(), v.end(), high) - v.begin();\n            // add window around iLow and iHigh\n            for (int d=-k; d<=k; ++d){\n                int i = iLow + d;\n                if (0<=i && i<(int)v.size()) cand.push_back(v[i]);\n                i = iHigh + d;\n                if (0<=i && i<(int)v.size()) cand.push_back(v[i]);\n            }\n            cand.push_back(0); cand.push_back(MAXC);\n            sort(cand.begin(), cand.end());\n            cand.erase(unique(cand.begin(), cand.end()), cand.end());\n            return cand;\n        };\n        vector<int> candX1 = gather_candidates(xs_pts, r.x1, r.x2, 30);\n        vector<int> candX2 = candX1; // reuse\n        vector<int> candY1 = gather_candidates(ys_pts, r.y1, r.y2, 30);\n        vector<int> candY2 = candY1;\n\n        bool improved = true;\n        int iter=0;\n        while (improved && iter<5){\n            ++iter; improved = false;\n            // Move left side\n            Rect bestLoc = r;\n            for (int nx1: candX1){\n                if (nx1 > r.x2) break;\n                if (nx1==r.x1) continue;\n                Rect t{nx1, r.y1, r.x2, r.y2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n            // Move right side\n            bestLoc = r;\n            for (int nx2: candX2){\n                if (nx2 < r.x1) continue;\n                if (nx2==r.x2) continue;\n                Rect t{r.x1, r.y1, nx2, r.y2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n            // Move bottom\n            bestLoc = r;\n            for (int ny1: candY1){\n                if (ny1 > r.y2) break;\n                if (ny1==r.y1) continue;\n                Rect t{r.x1, ny1, r.x2, r.y2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n            // Move top\n            bestLoc = r;\n            for (int ny2: candY2){\n                if (ny2 < r.y1) continue;\n                if (ny2==r.y2) continue;\n                Rect t{r.x1, r.y1, r.x2, ny2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n        }\n        return r;\n    };\n\n    int refineK = min(30, (int)top.size());\n    // Select top refineK by current exact score\n    sort(top.begin(), top.end(), [](const Rect& A, const Rect& B){\n        if (A.score!=B.score) return A.score>B.score;\n        return A.a>B.a;\n    });\n    top.resize(refineK);\n\n    for (int i=0;i<refineK;i++){\n        Rect r = top[i];\n        Rect rr = refine_rect(r);\n        if (rr.score==LLONG_MIN) evaluate(rr);\n        if (rr.score > best.score || (rr.score==best.score && rr.a > best.a)) best = rr;\n    }\n\n    // Final small random nudges around best\n    {\n        std::uniform_int_distribution<int> d(-1000, 1000);\n        for (int t=0;t<200;t++){\n            int dx1 = d(rng), dx2 = d(rng), dy1 = d(rng), dy2 = d(rng);\n            Rect r{\n                max(0, min(MAXC, best.x1 + dx1)),\n                max(0, min(MAXC, best.y1 + dy1)),\n                max(0, min(MAXC, best.x2 + dx2)),\n                max(0, min(MAXC, best.y2 + dy2)),\n                0\n            };\n            if (r.x1>r.x2) swap(r.x1,r.x2);\n            if (r.y1>r.y2) swap(r.y1,r.y2);\n            if (r.x1==r.x2) { if (r.x2<MAXC) r.x2++; else if (r.x1>0) r.x1--; }\n            if (r.y1==r.y2) { if (r.y2<MAXC) r.y2++; else if (r.y1>0) r.y1--; }\n            if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) > PERIM_LIMIT) continue;\n            evaluate(r);\n            if (r.score > best.score || (r.score==best.score && r.a > best.a)) best = r;\n        }\n    }\n\n    // Output rectangle polygon\n    int x1 = max(0, min(MAXC, best.x1));\n    int y1 = max(0, min(MAXC, best.y1));\n    int x2 = max(0, min(MAXC, best.x2));\n    int y2 = max(0, min(MAXC, best.y2));\n    if (x1==x2){ if (x2<MAXC) x2++; else if (x1>0) x1--; }\n    if (y1==y2){ if (y2<MAXC) y2++; else if (y1>0) y1--; }\n    while (rect_perimeter(x1,y1,x2,y2) > PERIM_LIMIT){\n        if ((x2-x1) >= (y2-y1)){\n            if (x2-x1>1) x2--;\n            else if (y2-y1>1) y2--;\n            else break;\n        } else {\n            if (y2-y1>1) y2--;\n            else if (x2-x1>1) x2--;\n            else break;\n        }\n    }\n    cout << 4 << \"\\n\";\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Column {\n    vector<int> items;         // indices\n    long long sumH = 0;        // sum of heights\n    long long maxW = 0;        // max width\n    int anchor = -1;           // min index in items\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<long long> wp(N), hp(N);\n    for (int i = 0; i < N; i++) cin >> wp[i] >> hp[i];\n\n    // Precompute orientation and per-item dims for vertical stacking\n    vector<int> rot(N, 0);\n    vector<long long> hmin(N), wmax(N);\n    for (int i = 0; i < N; i++) {\n        if (hp[i] <= wp[i]) {\n            rot[i] = 0; // height = hp[i], width = wp[i]\n            hmin[i] = hp[i];\n            wmax[i] = wp[i];\n        } else {\n            rot[i] = 1; // rotated: height = wp[i], width = hp[i]\n            hmin[i] = wp[i];\n            wmax[i] = hp[i];\n        }\n    }\n\n    auto build_columns = [&](int K, vector<int>& col_of, vector<int>& col_anchor_sorted, vector<int>& anchor_of_col, vector<int>& prev_anchor_for_col, long long& estW, long long& estH) {\n        // Initialize columns\n        vector<Column> cols(K);\n        // Sort items by height descending (greedy LPT)\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b){\n            if (hmin[a] != hmin[b]) return hmin[a] > hmin[b];\n            return a < b;\n        });\n        // Min-heap by current sumH\n        // We'll just linearly find min for small K; K up to ~10 so O(N*K) fine.\n        for (int idx : order) {\n            // find column with minimum sumH, tie-break by smaller maxW then smaller anchor index (unused yet)\n            int best = 0;\n            long long bestH = cols[0].sumH;\n            long long bestW = cols[0].maxW;\n            for (int c = 1; c < K; c++) {\n                if (cols[c].sumH < bestH || (cols[c].sumH == bestH && cols[c].maxW < bestW)) {\n                    best = c;\n                    bestH = cols[c].sumH;\n                    bestW = cols[c].maxW;\n                }\n            }\n            cols[best].items.push_back(idx);\n            cols[best].sumH += hmin[idx];\n            cols[best].maxW = max(cols[best].maxW, wmax[idx]);\n        }\n        // Determine anchors (min index per column)\n        for (int c = 0; c < K; c++) {\n            if (cols[c].items.empty()) continue;\n            int mn = cols[c].items[0];\n            for (int v : cols[c].items) mn = min(mn, v);\n            cols[c].anchor = mn;\n        }\n        // Sort columns by anchor\n        vector<int> col_order(K);\n        iota(col_order.begin(), col_order.end(), 0);\n        sort(col_order.begin(), col_order.end(), [&](int a, int b){\n            // empty columns should go last to avoid referencing invalid anchor; but K will be <= N, still safe\n            int aa = cols[a].anchor, bb = cols[b].anchor;\n            if (aa == -1) return false;\n            if (bb == -1) return true;\n            if (aa != bb) return aa < bb;\n            return a < b;\n        });\n        // Map original column id to position in sorted-by-anchor order\n        vector<int> col_rank(K, K); // default K for empty\n        for (int pos = 0; pos < K; pos++) {\n            col_rank[col_order[pos]] = pos;\n        }\n        // Build outputs: col_of[i] gives the rank (0..K-1)\n        col_of.assign(N, -1);\n        anchor_of_col.assign(K, -1);\n        prev_anchor_for_col.assign(K, -1);\n        col_anchor_sorted.assign(K, -1);\n        for (int pos = 0; pos < K; pos++) {\n            int c = col_order[pos];\n            col_anchor_sorted[pos] = cols[c].anchor;\n            anchor_of_col[pos] = cols[c].anchor;\n            if (pos > 0) prev_anchor_for_col[pos] = cols[col_order[pos-1]].anchor;\n            for (int v : cols[c].items) {\n                col_of[v] = pos;\n            }\n        }\n        // Estimate W and H\n        estW = 0;\n        estH = 0;\n        for (int pos = 0; pos < K; pos++) {\n            int c = col_order[pos];\n            if (cols[c].items.empty()) continue;\n            estW += cols[c].maxW;\n            estH = max(estH, cols[c].sumH);\n        }\n    };\n\n    // Candidate K list\n    vector<int> Ks;\n    // Build a reasonable set relative to N\n    // e.g., 1,2,3,4,5,6,8,10,12,16 but not exceeding N and not too many\n    vector<int> base = {1,2,3,4,5,6,8,10,12,16,20};\n    for (int k : base) if (k <= N) Ks.push_back(k);\n    // Limit count by T\n    if ((int)Ks.size() > T) Ks.resize(T);\n\n    // For remaining turns, repeat the best K so far\n    int bestK = -1;\n    long long bestScoreProxy = LLONG_MAX;\n\n    // Precompute global increasing index order once\n    vector<int> incOrder(N);\n    iota(incOrder.begin(), incOrder.end(), 0);\n\n    int turn = 0;\n    for (; turn < T; turn++) {\n        int K;\n        if (turn < (int)Ks.size()) K = Ks[turn];\n        else K = (bestK == -1 ? 1 : bestK);\n\n        vector<int> col_of, col_anchor_sorted, anchor_of_col, prev_anchor_for_col;\n        long long estW=0, estH=0;\n        build_columns(K, col_of, col_anchor_sorted, anchor_of_col, prev_anchor_for_col, estW, estH);\n\n        long long proxy = estW + estH;\n        if (turn < (int)Ks.size()) {\n            if (proxy < bestScoreProxy) {\n                bestScoreProxy = proxy;\n                bestK = K;\n            }\n        }\n\n        cout << N << '\\n';\n        for (int i = 0; i < N; i++) {\n            int c = col_of[i];\n            int b = -1;\n            if (c > 0) b = prev_anchor_for_col[c];\n            cout << i << ' ' << rot[i] << ' ' << 'U' << ' ' << b << '\\n';\n        }\n        cout.flush();\n\n        long long Wp, Hp;\n        if (!(cin >> Wp >> Hp)) return 0;\n        // optional comment for local debugging\n        // cerr << \"# turn \" << turn << \" K=\" << K << \" est=\" << estW+estH << \" obs=\" << Wp+Hp << \"\\n\";\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Improved heuristic:\n// - Multi-start root selection from several low-A seeds\n// - Greedy add roots to ensure dist<=H, prefer minimal A and larger distance\n// - Layered multi-source BFS processing nodes in ascending A within each layer\n// - Keep the best forest by true score\n\nstruct RunResult {\n    vector<int> parent;\n    vector<int> depth;\n    long long score;\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    vector<int> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\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    // coords not used\n    for(int i=0;i<N;i++){\n        int x,y; cin >> x >> y;\n        (void)x; (void)y;\n    }\n\n    // Precompute order of vertices by ascending A\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j){\n        if(A[i]!=A[j]) return A[i] < A[j];\n        return i < j;\n    });\n\n    auto layered_bfs = [&](const vector<int>& roots, vector<int>& parent, vector<int>& depth, vector<int>& root_of){\n        const int INF = 1e9;\n        parent.assign(N, -2);\n        depth.assign(N, INF);\n        root_of.assign(N, -1);\n        // For layered processing, maintain current frontier list, sort by A\n        deque<int> dq; // not used directly\n        vector<int> current, next;\n        current.reserve(N);\n        next.reserve(N);\n        for(int r: roots){\n            depth[r] = 0;\n            parent[r] = -1;\n            root_of[r] = r;\n            current.push_back(r);\n        }\n        // sort initial roots by A ascending\n        sort(current.begin(), current.end(), [&](int i, int j){\n            if(A[i]!=A[j]) return A[i] < A[j];\n            return i<j;\n        });\n        int d = 0;\n        while(!current.empty()){\n            // process current layer nodes in ascending A\n            for(int u: current){\n                for(int v: adj[u]){\n                    if(depth[v] == INF){\n                        depth[v] = d + 1;\n                        parent[v] = u;\n                        root_of[v] = root_of[u];\n                        next.push_back(v);\n                    }else if(depth[v] == d + 1){\n                        // tie at same depth: prefer parent with lower A to keep heavy deeper subtrees\n                        if(A[u] < A[parent[v]]){\n                            parent[v] = u;\n                            root_of[v] = root_of[u];\n                        }\n                    }\n                }\n            }\n            // advance layer\n            d++;\n            if(next.empty()) break;\n            // sort next by A ascending\n            sort(next.begin(), next.end(), [&](int i, int j){\n                if(A[i]!=A[j]) return A[i] < A[j];\n                return i<j;\n            });\n            current.clear();\n            current.swap(next);\n        }\n    };\n\n    auto compute_score = [&](const vector<int>& depth)-> long long {\n        long long s = 1; // base +1 per problem, but since they sum 1 + sum_T a(T), and a(T)=sum (h+1)A, we can include base 1; comparisons unaffected.\n        for(int i=0;i<N;i++){\n            int d = depth[i];\n            if(d < 0 || d > 100000000) d = 0;\n            s += 1LL * (d + 1) * A[i];\n        }\n        return s;\n    };\n\n    // Root-building function\n    auto build_roots = [&](int seed)-> vector<int> {\n        vector<int> roots;\n        roots.push_back(seed);\n        vector<int> parent, depth, root_of;\n        layered_bfs(roots, parent, depth, root_of);\n        // add roots until all depth <= H\n        while(true){\n            int far_v = -1;\n            int bestA = INT_MAX;\n            int bestDist = -1;\n            for(int v=0; v<N; v++){\n                if(depth[v] > H){\n                    if(A[v] < bestA){\n                        bestA = A[v];\n                        bestDist = depth[v];\n                        far_v = v;\n                    }else if(A[v] == bestA && depth[v] > bestDist){\n                        bestDist = depth[v];\n                        far_v = v;\n                    }\n                }\n            }\n            if(far_v == -1) break;\n            roots.push_back(far_v);\n            layered_bfs(roots, parent, depth, root_of);\n        }\n        return roots;\n    };\n\n    // Try multiple seeds\n    int L_low = min(N, 50); // consider first 50 lowest-A as possible seeds\n    int S_runs = min(16, L_low); // number of runs\n    RunResult best;\n    best.score = LLONG_MIN;\n\n    // We distribute seeds among the bottom L_low vertices; also try a couple of spatially spread picks by index stepping\n    for(int si = 0; si < S_runs; si++){\n        int seed = order[si];\n        vector<int> roots = build_roots(seed);\n\n        vector<int> parent, depth, root_of;\n        layered_bfs(roots, parent, depth, root_of);\n\n        // Safety: enforce constraints\n        for(int i=0;i<N;i++){\n            if(depth[i] > H || parent[i] == -2){\n                parent[i] = -1;\n                depth[i] = 0;\n            }\n        }\n\n        long long sc = compute_score(depth);\n        if(sc > best.score){\n            best.score = sc;\n            best.parent = move(parent);\n            best.depth = move(depth);\n        }\n    }\n\n    // Output best parent array\n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << best.parent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<string> C(N);\n    for (int i = 0; i < N; ++i) cin >> C[i];\n\n    // Collect positions and precompute Fukunokami positions.\n    vector<vector<bool>> hasF(N, vector<bool>(N, false));\n    vector<pair<int,int>> oni;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (C[i][j] == 'o') hasF[i][j] = true;\n            else if (C[i][j] == 'x') oni.emplace_back(i, j);\n        }\n    }\n\n    // Precompute prefix counts of Fukunokami per row/column to check rays quickly.\n    vector<vector<int>> rowPref(N, vector<int>(N+1, 0));\n    vector<vector<int>> colPref(N, vector<int>(N+1, 0));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            rowPref[i][j+1] = rowPref[i][j] + (hasF[i][j] ? 1 : 0);\n            colPref[j][i+1] = colPref[j][i] + (hasF[i][j] ? 1 : 0);\n        }\n    }\n\n    auto safe_up = [&](int i, int j)->bool {\n        // No Fukunokami above (rows 0..i-1) in column j\n        if (i == 0) return true;\n        return colPref[j][i] - colPref[j][0] == 0;\n    };\n    auto safe_down = [&](int i, int j)->bool {\n        // No Fukunokami below (rows i+1..N-1) in column j\n        if (i == N-1) return true;\n        return colPref[j][N] - colPref[j][i+1] == 0;\n    };\n    auto safe_left = [&](int i, int j)->bool {\n        if (j == 0) return true;\n        return rowPref[i][j] - rowPref[i][0] == 0;\n    };\n    auto safe_right = [&](int i, int j)->bool {\n        if (j == N-1) return true;\n        return rowPref[i][N] - rowPref[i][j+1] == 0;\n    };\n\n    struct Op { char d; int p; };\n    vector<Op> ops;\n    ops.reserve(1600);\n\n    // For each Oni, pick minimal cost safe direction and emit.\n    for (auto [i, j] : oni) {\n        // Determine available safe directions and their costs.\n        int bestCost = INT_MAX;\n        char bestDir = 0;\n        int param = -1; // row/col index\n\n        // Up\n        if (safe_up(i, j)) {\n            int k = i; // distance to top edge\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'U'; param = j; }\n        }\n        // Down\n        if (safe_down(i, j)) {\n            int k = (N - 1 - i);\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'D'; param = j; }\n        }\n        // Left\n        if (safe_left(i, j)) {\n            int k = j;\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'L'; param = i; }\n        }\n        // Right\n        if (safe_right(i, j)) {\n            int k = (N - 1 - j);\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'R'; param = i; }\n        }\n\n        // Per problem guarantee, at least one is safe.\n        if (bestDir == 0) {\n            // Fallback: should not happen; do nothing to avoid WA.\n            continue;\n        }\n\n        // Emit k+1 pushes toward bestDir, then k+1 pushes back.\n        int k;\n        char backDir;\n        if (bestDir == 'U') { k = i; backDir = 'D'; }\n        else if (bestDir == 'D') { k = (N - 1 - i); backDir = 'U'; }\n        else if (bestDir == 'L') { k = j; backDir = 'R'; }\n        else { // 'R'\n            k = (N - 1 - j); backDir = 'L';\n        }\n\n        // Ensure we do not exceed 4N^2 operations; with guarantees this should hold.\n        // But add a safety break.\n        if ((int)ops.size() + 2 * (k + 1) > 4 * N * N) break;\n\n        for (int t = 0; t < k + 1; ++t) ops.push_back({bestDir, param});\n        for (int t = 0; t < k + 1; ++t) ops.push_back({backDir, param});\n    }\n\n    // Output\n    for (auto &op : ops) {\n        cout << op.d << ' ' << op.p << '\\n';\n    }\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::high_resolution_clock::time_point st;\n    Timer() { reset(); }\n    void reset() { st = chrono::high_resolution_clock::now(); }\n    double elapsed() const {\n        auto ed = chrono::high_resolution_clock::now();\n        return chrono::duration<double>(ed - st).count();\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; long long L;\n    if(!(cin>>N>>L)) return 0;\n    vector<int> T(N);\n    for(int i=0;i<N;i++) cin>>T[i];\n\n    // Parameters\n    const int targetM = 20000; // target period length\n    int q = max(1, int( (long long) ( (L + targetM/2) / targetM ) ));\n    // initial weights\n    vector<int> w(N);\n    long long M = 0;\n    for(int i=0;i<N;i++){\n        long long wi = (T[i] + q/2) / q;\n        if(wi < 1) wi = 1;\n        w[i] = (int)wi;\n        M += w[i];\n    }\n    // Adjust sum w to be even (for 2M period it's fine regardless, but even helps)\n    // Also adjust to keep M not too big\n    // Try to bring M close to L/q\n    long long targetSum = L / q;\n    // record fractional parts to refine: compute exact fractional T/q\n    vector<pair<double,int>> frac(N);\n    for(int i=0;i<N;i++){\n        double x = double(T[i]) / double(q);\n        frac[i] = { x - floor(x), i };\n    }\n    if(M > targetSum){\n        // reduce some w by 1 but keep >=1\n        sort(frac.begin(), frac.end(), greater<>());\n        long long need = M - targetSum;\n        for(int k=0;k<N && need>0;k++){\n            int i = frac[k].second;\n            if(w[i] > 1){\n                w[i]--; need--;\n            }\n        }\n        M -= (L / q - targetSum); // ignore; we'll recompute M below\n        M = 0; for(int i=0;i<N;i++) M += w[i];\n    }else if(M < targetSum){\n        // increase some w by 1\n        sort(frac.begin(), frac.end());\n        long long need = targetSum - M;\n        for(int k=0;k<N && need>0;k++){\n            int i = frac[k].second;\n            w[i]++; need--;\n        }\n        M = 0; for(int i=0;i<N;i++) M += w[i];\n    }\n    // Ensure M >= N and small enough\n    if(M < N){\n        for(int i=0;i<N && M<N;i++){ w[i]++; M++; }\n    }\n    // departure counts per port: a (odd) first, then b (even)\n    vector<int> d1(N), d0(N);\n    for(int i=0;i<N;i++){\n        d1[i] = (w[i]+1)/2;\n        d0[i] = w[i]/2;\n    }\n    // destination remaining demand\n    vector<int> r = w;\n\n    // Order sources by descending w\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a,int b){\n        if(w[a]!=w[b]) return w[a]>w[b];\n        return a<b;\n    });\n\n    // Max-heap of destinations by remaining r\n    struct Node { int r, id; };\n    struct Cmp { bool operator()(const Node& a, const Node& b) const {\n        if(a.r!=b.r) return a.r < b.r;\n        return a.id > b.id;\n    } };\n    priority_queue<Node, vector<Node>, Cmp> pq;\n\n    auto rebuild_pq = [&](){\n        while(!pq.empty()) pq.pop();\n        for(int j=0;j<N;j++) pq.push({r[j], j});\n    };\n    rebuild_pq();\n\n    vector<int> f1(N,-1), f0(N,-1);\n    // Greedy assignments\n    for(int si=0; si<N; si++){\n        int s = ord[si];\n        // assign for bigger port first\n        int need1 = d1[s], need0 = d0[s];\n        // we will pick best remaining nodes\n        // fetch top two distinct nodes with sufficient capacity if possible\n        // We'll try a few attempts to find sufficient capacity; otherwise take best anyway.\n        // Copy pq to vector of candidates (top K)\n        vector<Node> cand;\n        int K = min(N, 10); // look at top 10\n        for(int k=0;k<K && !pq.empty();k++){\n            cand.push_back(pq.top()); pq.pop();\n        }\n        auto restore = [&](){\n            for(auto &nd: cand) pq.push(nd);\n            cand.clear();\n        };\n        // pick for port1\n        int pick1 = -1, idx1=-1;\n        int best_idx=-1;\n        int best_r=-1;\n        for(int i=0;i<(int)cand.size();i++){\n            if(cand[i].r >= need1){ pick1 = cand[i].id; idx1=i; break; }\n            if(cand[i].r > best_r){ best_r=cand[i].r; best_idx=i; }\n        }\n        if(pick1==-1){\n            // take the best anyway\n            if(best_idx==-1){ // should not happen\n                restore();\n                rebuild_pq();\n                // fallback to ring\n                for(int i=0;i<N;i++){ cout<< (i+1)%N <<\" \"<< (i+1)%N <<\"\\n\"; }\n                return 0;\n            }\n            pick1 = cand[best_idx].id; idx1 = best_idx;\n        }\n        // reduce r\n        cand[idx1].r -= need1;\n        f1[s] = pick1;\n\n        // pick for port0, avoid same as pick1 if possible\n        int pick0 = -1, idx0=-1;\n        best_idx=-1; best_r=-1;\n        for(int i=0;i<(int)cand.size();i++){\n            if(cand[i].id==pick1) continue;\n            if(cand[i].r >= need0){ pick0 = cand[i].id; idx0=i; break; }\n            if(cand[i].r > best_r){ best_r=cand[i].r; best_idx=i; }\n        }\n        if(pick0==-1){\n            // allow same as pick1 if needed\n            if(need0>0){\n                if(cand[idx1].r >= need0){\n                    pick0 = pick1; idx0 = idx1;\n                }else{\n                    // take best available even if insufficient\n                    if(best_idx==-1){\n                        // pick same\n                        pick0 = pick1; idx0 = idx1;\n                    }else{\n                        pick0 = cand[best_idx].id; idx0 = best_idx;\n                    }\n                }\n            }else{\n                // need0==0\n                pick0 = pick1; idx0 = idx1;\n            }\n        }\n        cand[idx0].r -= need0;\n        f0[s] = pick0;\n\n        // write back candidates\n        for(auto &nd: cand) pq.push(nd);\n        // update r array too (for book-keeping)\n        r[pick1] -= need1;\n        r[pick0] -= need0;\n    }\n\n    // If due to greediness some r[j] != 0, try to repair by swapping some sources' assignments between f0/f1\n    // Simple repair: while exists j with r[j]>0 and k with r[k]<0, move some source's port pointing to k to j, favor small impact.\n    vector<int> surplus, deficit;\n    for(int j=0;j<N;j++){\n        if(r[j]>0) surplus.push_back(j);\n        else if(r[j]<0) deficit.push_back(j);\n    }\n    // Build reverse maps: which ports point to a destination\n    vector<vector<pair<int,int>>> rev(N); // dest -> list of (s,port) where port 1=a, 0=b\n    for(int s=0;s<N;s++){\n        if(d1[s]>0) rev[f1[s]].push_back({s,1});\n        if(d0[s]>0) rev[f0[s]].push_back({s,0});\n    }\n    // Attempt repairs\n    int attempts = 0;\n    while(!surplus.empty() && !deficit.empty() && attempts < 10000){\n        attempts++;\n        int j_pos = surplus.back();\n        int j_neg = deficit.back();\n        // find a source s and port p that currently points to j_neg and can be switched to j_pos without breaking alternation counts\n        bool moved=false;\n        auto &lst = rev[j_neg];\n        for(size_t idx=0; idx<lst.size(); idx++){\n            int s = lst[idx].first;\n            int p = lst[idx].second;\n            // capacity to move: how many departures on that port\n            int cap = (p==1? d1[s] : d0[s]);\n            if(cap<=0) continue;\n            // switch destination of this port from j_neg to j_pos\n            // apply\n            if(p==1) f1[s]=j_pos; else f0[s]=j_pos;\n            r[j_pos]--; r[j_neg]++;\n            // update rev lists\n            lst.erase(lst.begin()+idx);\n            rev[j_pos].push_back({s,p});\n            moved=true;\n            break;\n        }\n        if(!moved){\n            // cannot move; pop one and continue\n            if(r[j_pos]==0) surplus.pop_back();\n            else if(r[j_neg]==0) deficit.pop_back();\n            else {\n                // try another pair\n                if(surplus.size()>1) rotate(surplus.begin(), surplus.begin()+1, surplus.end());\n                if(deficit.size()>1) rotate(deficit.begin(), deficit.begin()+1, deficit.end());\n            }\n        }else{\n            if(r[j_pos]==0) surplus.pop_back();\n            if(r[j_neg]==0) deficit.pop_back();\n        }\n    }\n    // If still imbalance remains, ignore; the sequence builder may still work, and final simulation decides counts anyway.\n\n    // Build period P of length M using alternation counts\n    vector<int> rem1 = d1, rem0 = d0;\n    vector<int> next_port(N, 1); // first departure uses a (odd)\n    vector<int> P; P.reserve((size_t)M);\n    // We'll construct a walk that uses exactly w[x] appearances of each x.\n    vector<int> used_vis(N, 0);\n\n    auto take_next = [&](int cur)->int{\n        int p = next_port[cur];\n        int to = (p==1? f1[cur] : f0[cur]);\n        if(p==1){\n            if(rem1[cur]>0){\n                rem1[cur]--;\n                next_port[cur] = 0;\n                return to;\n            }else if(rem0[cur]>0){\n                // forced flip, will break strict alternation but recover\n                rem0[cur]--;\n                next_port[cur] = 1;\n                return f0[cur];\n            }else{\n                return -1;\n            }\n        }else{\n            if(rem0[cur]>0){\n                rem0[cur]--;\n                next_port[cur] = 1;\n                return to;\n            }else if(rem1[cur]>0){\n                rem1[cur]--;\n                next_port[cur] = 0;\n                return f1[cur];\n            }else{\n                return -1;\n            }\n        }\n    };\n\n    int cur = 0;\n    P.push_back(cur);\n    used_vis[cur]++;\n    for(long long step=1; step<M; step++){\n        int nx = take_next(cur);\n        if(nx==-1){\n            // find a node with remaining outdegree to jump\n            int best=-1;\n            for(int i=0;i<N;i++){\n                if(rem0[i]>0 || rem1[i]>0){ best=i; break; }\n            }\n            if(best==-1) break;\n            cur = best;\n            // first time we visit best? next_port is already set; okay\n            P.push_back(cur);\n            used_vis[cur]++;\n            continue;\n        }else{\n            cur = nx;\n            P.push_back(cur);\n            used_vis[cur]++;\n        }\n    }\n    // If P shorter than M, fill by appending nodes with remaining needed counts arbitrarily\n    for(int i=0;i<N;i++){\n        while((long long)used_vis[i] < w[i]){\n            P.push_back(i);\n            used_vis[i]++;\n        }\n    }\n    // Now define edges a_i, b_i\n    vector<int> a(N), b(N);\n    for(int i=0;i<N;i++){ a[i]=f1[i]; b[i]=f0[i]; }\n    // As a safety if any a_i or b_i out of range, clamp\n    for(int i=0;i<N;i++){\n        if(a[i]<0 || a[i]>=N) a[i]=(i+1)%N;\n        if(b[i]<0 || b[i]>=N) b[i]=(i+1)%N;\n    }\n\n    // Simulate full L to get t_i\n    vector<int> t(N,0);\n    int x = 0;\n    for(long long week=0; week<L; week++){\n        t[x]++;\n        int tx = t[x];\n        int nx = ( (tx%2)==1 ? a[x] : b[x] );\n        x = nx;\n    }\n\n    // Quick local improvement: try swapping a or b targets for random sources to reduce error\n    auto error_of = [&](const vector<int>& tt)->long long{\n        long long e=0;\n        for(int i=0;i<N;i++) e += llabs((long long)tt[i]-T[i]);\n        return e;\n    };\n    long long bestE = error_of(t);\n    vector<int> bestA=a, bestB=b;\n    Timer tim;\n    std::mt19937 rng(712367);\n    // limit time ~0.3s for improvement\n    while(tim.elapsed() < 0.3){\n        int s = rng()%N;\n        bool flipA = (rng()&1);\n        int old = flipA ? a[s] : b[s];\n        int cand = rng()%N;\n        if(cand==old) continue;\n        if(flipA) a[s]=cand; else b[s]=cand;\n        // simulate quickly\n        vector<int> tt(N,0);\n        int y=0;\n        for(long long wkk=0; wkk<L; wkk++){\n            tt[y]++;\n            int ty=tt[y];\n            int ny = ( (ty%2)==1 ? a[y] : b[y] );\n            y = ny;\n        }\n        long long E = error_of(tt);\n        if(E < bestE){\n            bestE = E; bestA=a; bestB=b; t.swap(tt);\n        }else{\n            // revert\n            if(flipA) a[s]=old; else b[s]=old;\n        }\n    }\n    a = bestA; b = bestB;\n\n    // Output\n    for(int i=0;i<N;i++){\n        cout<<a[i]<<\" \"<<b[i]<<\"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    DSU(int n=0): n(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){ a=find(a); b=find(b); if(a==b) return false; if(r[a]<r[b]) swap(a,b); p[b]=a; if(r[a]==r[b]) r[a]++; return true; }\n};\n\nstatic inline uint32_t part1by1(uint32_t x){\n    x &= 0x0000ffff;\n    x = (x | (x << 8)) & 0x00FF00FF;\n    x = (x | (x << 4)) & 0x0F0F0F0F;\n    x = (x | (x << 2)) & 0x33333333;\n    x = (x | (x << 1)) & 0x55555555;\n    return x;\n}\nstatic inline uint32_t morton2D(uint32_t x, uint32_t y){\n    return (part1by1(y) << 1) | part1by1(x);\n}\n\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    // centers\n    vector<int> cx(N), cy(N);\n    for(int i=0;i<N;i++){\n        cx[i] = (lx[i]+rx[i])>>1;\n        cy[i] = (ly[i]+ry[i])>>1;\n    }\n    // Morton order\n    vector<int> idx(N);\n    iota(idx.begin(), idx.end(), 0);\n    auto codeOf = [&](int i)->uint32_t{\n        uint32_t xs = (uint32_t) min(16383, max(0, cx[i]*16383/10000));\n        uint32_t ys = (uint32_t) min(16383, max(0, cy[i]*16383/10000));\n        return morton2D(xs, ys);\n    };\n    sort(idx.begin(), idx.end(), [&](int a, int b){\n        uint32_t ca = codeOf(a), cb = codeOf(b);\n        if(ca!=cb) return ca<cb;\n        if(cx[a]!=cx[b]) return cx[a]<cx[b];\n        if(cy[a]!=cy[b]) return cy[a]<cy[b];\n        return a<b;\n    });\n\n    // slice into groups by G\n    vector<vector<int>> groups(M);\n    int pos=0;\n    for(int k=0;k<M;k++){\n        groups[k].reserve(G[k]);\n        for(int t=0;t<G[k];t++) groups[k].push_back(idx[pos++]);\n    }\n\n    int queries_left = Q;\n\n    auto do_query = [&](const vector<int>& C)->vector<pair<int,int>>{\n        int l = (int)C.size();\n        cout<<\"? \"<<l;\n        for(int v: C) cout<<\" \"<<v;\n        cout<<\"\\n\"<<flush;\n        vector<pair<int,int>> ret;\n        ret.reserve(max(0,l-1));\n        for(int i=0;i<l-1;i++){\n            int a,b; cin>>a>>b;\n            if(a>b) swap(a,b);\n            ret.emplace_back(a,b);\n        }\n        return ret;\n    };\n\n    auto centerDist = [&](int a, int b)->int{\n        long dx = cx[a]-cx[b];\n        long dy = cy[a]-cy[b];\n        long long d2 = dx*dx + dy*dy;\n        return (int)floor(sqrt((long double)d2));\n    };\n\n    // Build approximate MST using richer candidate set:\n    // - Morton window neighbors\n    // - k nearest in x-sorted local order\n    // - k nearest in y-sorted local order\n    auto approx_mst = [&](const vector<int>& vs)->vector<pair<int,int>>{\n        int n = (int)vs.size();\n        if(n<=1) return {};\n        struct Edge{int u,v,w;};\n        vector<Edge> edges;\n        edges.reserve(n*20);\n\n        // Morton local order\n        vector<pair<uint32_t,int>> marr(n);\n        for(int i=0;i<n;i++) marr[i] = {codeOf(vs[i]), vs[i]};\n        sort(marr.begin(), marr.end());\n        vector<int> mseq(n);\n        for(int i=0;i<n;i++) mseq[i] = marr[i].second;\n\n        // x-sorted and y-sorted orders\n        vector<int> xseq = vs, yseq = vs;\n        sort(xseq.begin(), xseq.end(), [&](int a,int b){\n            if(cx[a]!=cx[b]) return cx[a]<cx[b];\n            if(cy[a]!=cy[b]) return cy[a]<cy[b];\n            return a<b;\n        });\n        sort(yseq.begin(), yseq.end(), [&](int a,int b){\n            if(cy[a]!=cy[b]) return cy[a]<cy[b];\n            if(cx[a]!=cx[b]) return cx[a]<cx[b];\n            return a<b;\n        });\n\n        auto add_seq_neighbors = [&](const vector<int>& seq, int window, int capK){\n            for(int i=0;i<(int)seq.size();i++){\n                int u = seq[i];\n                // neighbors within +/- window\n                vector<pair<int,int>> cand;\n                cand.reserve(2*window);\n                for(int d=1; d<=window; d++){\n                    int j=i-d; if(j>=0){ int v=seq[j]; cand.emplace_back(centerDist(u,v), v); }\n                    j=i+d; if(j<(int)seq.size()){ int v=seq[j]; cand.emplace_back(centerDist(u,v), v); }\n                }\n                if((int)cand.size()>capK){\n                    nth_element(cand.begin(), cand.begin()+capK, cand.end(),\n                                [](const auto& A, const auto& B){ return A.first < B.first; });\n                    cand.resize(capK);\n                }\n                for(auto &p: cand){\n                    int a=u,b=p.second; if(a>b) swap(a,b);\n                    edges.push_back({a,b,p.first});\n                }\n            }\n        };\n\n        const int mortonWindow = 60;\n        const int mortonK = 12;\n        const int axisWindow = 12;\n        const int axisK = 6;\n\n        // Morton: pick best K from window\n        for(int i=0;i<n;i++){\n            int u = mseq[i];\n            vector<pair<int,int>> cand; cand.reserve(2*mortonWindow);\n            for(int d=1; d<=mortonWindow; d++){\n                int j=i-d; if(j>=0){ int v=mseq[j]; cand.emplace_back(centerDist(u,v), v); }\n                j=i+d; if(j<n){ int v=mseq[j]; cand.emplace_back(centerDist(u,v), v); }\n            }\n            if((int)cand.size()>mortonK){\n                nth_element(cand.begin(), cand.begin()+mortonK, cand.end(),\n                            [](const auto& A, const auto& B){ return A.first < B.first; });\n                cand.resize(mortonK);\n            }\n            for(auto &p: cand){\n                int a=u,b=p.second; if(a>b) swap(a,b);\n                edges.push_back({a,b,p.first});\n            }\n        }\n        // axis sequences\n        add_seq_neighbors(xseq, axisWindow, axisK);\n        add_seq_neighbors(yseq, axisWindow, axisK);\n\n        // dedup by (u,v) with min weight\n        sort(edges.begin(), edges.end(), [&](const Edge& A, const Edge& B){\n            if(A.u!=B.u) return A.u<B.u;\n            if(A.v!=B.v) return A.v<B.v;\n            return A.w<B.w;\n        });\n        edges.erase(unique(edges.begin(), edges.end(), [&](const Edge& A, const Edge& B){\n            return A.u==B.u && A.v==B.v;\n        }), edges.end());\n\n        // Kruskal\n        DSU dsu(N);\n        sort(edges.begin(), edges.end(), [&](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        vector<pair<int,int>> res;\n        res.reserve(n-1);\n        for(const auto &e: edges){\n            if(dsu.unite(e.u, e.v)){\n                res.emplace_back(e.u, e.v);\n                if((int)res.size()==n-1) break;\n            }\n        }\n        // fallback if needed: connect by Morton chain\n        if((int)res.size()<n-1){\n            for(int i=0;i<n-1;i++){\n                int a=mseq[i], b=mseq[i+1];\n                if(dsu.unite(a,b)){\n                    if(a>b) swap(a,b);\n                    res.emplace_back(a,b);\n                }\n            }\n        }\n        if((int)res.size()>n-1) res.resize(n-1);\n        return res;\n    };\n\n    // Block-MST strategy: split vs into blocks of up to L (by Morton order), query each to get exact intra-block MST,\n    // then connect blocks by approximate center edges using their closest boundary nodes.\n    auto block_mst = [&](const vector<int>& vs, int maxQueriesAvail)->pair<vector<pair<int,int>>, int>{\n        int n = (int)vs.size();\n        if(n<=1) return {{},0};\n        // sort by Morton locally\n        vector<pair<uint32_t,int>> marr(n);\n        for(int i=0;i<n;i++) marr[i] = {codeOf(vs[i]), vs[i]};\n        sort(marr.begin(), marr.end());\n        vector<int> order(n);\n        for(int i=0;i<n;i++) order[i]=marr[i].second;\n\n        // split to blocks\n        vector<vector<int>> blocks;\n        for(int i=0;i<n;i+=L){\n            int r=min(n, i+L);\n            vector<int> blk; blk.reserve(r-i);\n            for(int j=i;j<r;j++) blk.push_back(order[j]);\n            blocks.push_back(move(blk));\n        }\n        int B = (int)blocks.size();\n        int neededQueries = B;\n        vector<pair<int,int>> allEdges;\n        // if not enough queries, bail out\n        if(neededQueries > maxQueriesAvail){\n            return {approx_mst(vs), 0};\n        }\n        // intra-block queries\n        for(int b=0;b<B;b++){\n            if((int)blocks[b].size()==1) continue;\n            auto e = do_query(blocks[b]);\n            for(auto &p: e) allEdges.push_back(p);\n        }\n        // now connect blocks approximately: connect last of block b to first of block b+1, plus a few extra candidates\n        // Build candidates between neighboring blocks based on closest pair by center distances\n        struct Edge {int u,v,w;};\n        vector<Edge> inter;\n        auto add_best_between = [&](const vector<int>& A, const vector<int>& B, int capPairs){\n            // capPairs few closest pairs by checking subset: ends and k nearest by x order\n            // Simple: compare a subset of size min(6,|A|) from ends and evenly spaced\n            vector<int> aCand, bCand;\n            int ca = min(6, (int)A.size());\n            int cb = min(6, (int)B.size());\n            for(int t=0;t<ca;t++){\n                int idx = (int)((1.0*t/(ca-1+1e-9))*(A.size()-1));\n                aCand.push_back(A[idx]);\n            }\n            for(int t=0;t<cb;t++){\n                int idx = (int)((1.0*t/(cb-1+1e-9))*(B.size()-1));\n                bCand.push_back(B[idx]);\n            }\n            vector<Edge> local;\n            for(int a: aCand) for(int b: bCand){\n                int w=centerDist(a,b);\n                int u=a,v=b; if(u>v) swap(u,v);\n                local.push_back({u,v,w});\n            }\n            sort(local.begin(), local.end(), [](const Edge& A, const Edge& B){\n                return A.w<B.w || (A.w==B.w && (A.u<B.u || (A.u==B.u && A.v<B.v)));\n            });\n            int take = min((int)local.size(), capPairs);\n            for(int i=0;i<take;i++) inter.push_back(local[i]);\n        };\n        for(int b=0;b<B-1;b++){\n            add_best_between(blocks[b], blocks[b+1], 3);\n        }\n        // also connect block b to b+2 lightly to improve connectivity\n        for(int b=0;b<B-2;b++){\n            add_best_between(blocks[b], blocks[b+2], 1);\n        }\n        // dedup\n        sort(inter.begin(), inter.end(), [](const Edge& A, const Edge& B){\n            if(A.u!=B.u) return A.u<B.u;\n            if(A.v!=B.v) return A.v<B.v;\n            return A.w<B.w;\n        });\n        inter.erase(unique(inter.begin(), inter.end(), [](const Edge& A, const Edge& B){\n            return A.u==B.u && A.v==B.v;\n        }), inter.end());\n\n        // Kruskal on combined edges (assign weight 0 to intra-block? we don't have weights; treat as low w)\n        // For intra-block edges, we don't know true weights, but they are MST edges by true metric.\n        // We can set their estimated weight via center distance; good enough ordering.\n        vector<tuple<int,int,int>> all; all.reserve(allEdges.size()+inter.size());\n        for(auto &p: allEdges){\n            int w=centerDist(p.first, p.second);\n            all.emplace_back(w, min(p.first,p.second), max(p.first,p.second));\n        }\n        for(auto &e: inter){\n            all.emplace_back(e.w, e.u, e.v);\n        }\n        sort(all.begin(), all.end());\n        DSU dsu(N);\n        vector<pair<int,int>> res;\n        res.reserve(n-1);\n        for(auto &t: all){\n            int u = get<1>(t), v = get<2>(t);\n            if(dsu.unite(u,v)){\n                res.emplace_back(u,v);\n                if((int)res.size()==n-1) break;\n            }\n        }\n        // if still not enough (rare), add Morton chain over all vs\n        if((int)res.size()<n-1){\n            // build Morton sequence again\n            vector<pair<uint32_t,int>> arr(n);\n            for(int i=0;i<n;i++) arr[i]={codeOf(vs[i]), vs[i]};\n            sort(arr.begin(), arr.end());\n            for(int i=0;i<n-1;i++){\n                int a=arr[i].second, b=arr[i+1].second;\n                if(dsu.unite(a,b)){\n                    if(a>b) swap(a,b);\n                    res.emplace_back(a,b);\n                }\n            }\n        }\n        if((int)res.size()>n-1) res.resize(n-1);\n        return {res, neededQueries};\n    };\n\n    // Decide querying strategy\n    vector<vector<pair<int,int>>> group_edges(M);\n    vector<int> groupQueryPlan(M, 0); // 0=no query, 1=whole group, 2=block\n    // First pass: whole-group queries for Gi <= L\n    vector<int> orderSmall, orderMed, orderLarge;\n    for(int k=0;k<M;k++){\n        if(G[k]<=L) orderSmall.push_back(k);\n        else if(G[k] <= 3*L) orderMed.push_back(k);\n        else orderLarge.push_back(k);\n    }\n    // Small groups\n    for(int k: orderSmall){\n        if(queries_left>=1) { groupQueryPlan[k]=1; queries_left--; }\n    }\n    // Medium groups: block MST if possible\n    for(int k: orderMed){\n        int need = (G[k]+L-1)/L;\n        if(queries_left >= need){\n            groupQueryPlan[k]=2;\n            queries_left -= need;\n        }\n    }\n    // If still budget remains, try a few blocks for large groups, capped\n    for(int k: orderLarge){\n        int need = (G[k]+L-1)/L;\n        // limit per large group to at most 2 queries to spread budget\n        int allow = min(need, 2);\n        if(queries_left >= allow && allow>0){\n            // We'll still use full block_mst with allow==need? We can't partially query easily; so only if allow==need we proceed.\n            // Since allow<need usually, skip partial complexity; instead skip here.\n            // Keep budget for others or leave.\n            continue;\n        }\n    }\n\n    // Build edges per group according to plan\n    for(int k=0;k<M;k++){\n        const auto& g = groups[k];\n        int sz = (int)g.size();\n        if(sz<=1){ group_edges[k] = {}; continue; }\n        if(groupQueryPlan[k]==1){\n            auto e = do_query(g);\n            group_edges[k] = e;\n        }else if(groupQueryPlan[k]==2){\n            auto pr = block_mst(g, (int)1e9); // already decremented budget\n            group_edges[k] = pr.first;\n        }else{\n            group_edges[k] = approx_mst(g);\n        }\n        if((int)group_edges[k].size() > sz-1) group_edges[k].resize(sz-1);\n    }\n\n    // Output final answer\n    cout<<\"!\"<<\"\\n\";\n    for(int k=0;k<M;k++){\n        const auto& g = groups[k];\n        for(int i=0;i<(int)g.size();i++){\n            if(i) cout<<\" \";\n            cout<<g[i];\n        }\n        cout<<\"\\n\";\n        for(auto &e: group_edges[k]){\n            cout<<e.first<<\" \"<<e.second<<\"\\n\";\n        }\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint N, M;\nvector<Pos> targets;\nvector<string> out_actions;\n\ninline bool inb(int i,int j){ return 0<=i && i<N && 0<=j && j<N; }\n\nenum Dir {U=0,D=1,L=2,R=3};\nconst int di[4] = {-1,1,0,0};\nconst int dj[4] = {0,0,-1,1};\nchar dirChar(Dir d){ return d==U?'U':d==D?'D':d==L?'L':'R'; }\n\nstruct Grid {\n    int N;\n    vector<uint8_t> blk; // N*N\n    Grid(int N):N(N),blk(N*N,0){}\n    inline bool isBlock(int i,int j) const { return blk[i*N+j]; }\n    inline void toggle(int i,int j){ blk[i*N+j]^=1; }\n    inline void set(int i,int j,bool v){ blk[i*N+j]=v; }\n};\n\nGrid grid(20);\n\nvoid emit(char act, Dir d){\n    string s; s+=act; s+=' '; s+=dirChar(d);\n    out_actions.push_back(s);\n}\n\n// Try to move one step if free\nbool try_move(Pos &p, Dir d){\n    int ni=p.i+di[d], nj=p.j+dj[d];\n    if(!inb(ni,nj)) return false;\n    if(grid.isBlock(ni,nj)) return false;\n    emit('M', d);\n    p.i=ni; p.j=nj;\n    return true;\n}\n\n// Slide in dir until blocked (or border). Return landing.\nPos simulate_slide(const Pos &p, Dir d){\n    int i=p.i, j=p.j;\n    while(true){\n        int ni=i+di[d], nj=j+dj[d];\n        if(!inb(ni,nj)) break;\n        if(grid.isBlock(ni,nj)) break;\n        i=ni; j=nj;\n    }\n    return {i,j};\n}\nvoid do_slide(Pos &p, Dir d){\n    emit('S', d);\n    p = simulate_slide(p,d);\n}\n\n// Place temp block at cell (ci,cj): do Alter towards that cell from adjacent cell?\n// But Alter operation is relative to current position. We cannot alter arbitrary cells!\n// Important correction: Alter toggles the adjacent square in the specified direction FROM CURRENT POSITION. So to place a block somewhere, we must stand adjacent to it and issue A towards it.\n// This changes the design: we cannot place arbitrary stopper remotely. We must navigate to adjacent cell to place/remove blocks.\n\n// Therefore, strategy must avoid heavy block placement, or place only blocks adjacent to our path. Simple baseline: use Moves mostly, slides aided by borders only. Additionally, we can sometimes place a stopper right before a slide by moving adjacent to the intended stopper location.\n\n// Revised plan:\n// - Use Moves primarily, occasionally use slides leveraging borders, no remote stoppers.\n// - Because remote altering is impossible, temporary stopper placement is expensive (requires path to be adjacent), often negating benefit.\n// - So we will implement a safe and simple mover: greedy Manhattan path using Moves, with opportunistic Slides when aligned with border stopping at target row/col.\n\n// Heuristic with borders only:\n// From p to t:\n// - If same row: try to slide horizontally towards t: check landing equals t if border or a block stops at t; initially no blocks, border stops at edge, so landing will be at border, not t unless t is at border. So only helpful when target lies on border in that direction.\n// - Similarly for same column.\n// Given constraint, slides are rarely useful without blocks. Therefore, the robust baseline is pure Moves with a dash of slides when target is on border alignment. This will still succeed within 1600 actions for M=40 and N=20 because worst-case per leg ~ 38 moves, total ~ < 1500 average. This is acceptable and guarantees full visitation. It won't rank high but is safe.\n\n// We'll implement:\n// - Simple obstacle-aware BFS using Moves only (since blocks may exist if we accidentally placed some; but we won't place any). BFS in 20x20 is trivial. However, dynamic obstacles none, so Manhattan greedy is fine and faster.\n// - But to avoid getting stuck when we do slides, we won't place any blocks, and we will avoid sliding except when we can land exactly on target (same row/col and target on the border in that direction).\n\n// Implementation now reverts to Move-only with rare slides.\n\nbool can_land_by_slide_to_target(const Pos &p, const Pos &t, Dir &d_out){\n    if(p.i==t.i){\n        if(t.j==0 && t.j<p.j){ d_out = L; return true; }\n        if(t.j==N-1 && t.j>p.j){ d_out = R; return true; }\n    }\n    if(p.j==t.j){\n        if(t.i==0 && t.i<p.i){ d_out = U; return true; }\n        if(t.i==N-1 && t.i>p.i){ d_out = D; return true; }\n    }\n    return false;\n}\n\nvoid move_greedy(Pos &p, const Pos &t){\n    // simple Manhattan greedy avoiding blocks (there are none if we never alter)\n    while(!(p.i==t.i && p.j==t.j)){\n        Dir d;\n        if(p.i < t.i) d=D;\n        else if(p.i > t.i) d=U;\n        else if(p.j < t.j) d=R;\n        else d=L;\n        // try move preferred, else try orthogonal alternatives\n        if(try_move(p,d)) continue;\n        // try other three directions to detour minimally\n        bool moved=false;\n        for(int k=0;k<4;k++){\n            if(try_move(p, (Dir)k)){ moved=true; break; }\n        }\n        if(!moved){\n            // grid fully blocked around, should not happen with our no-block policy\n            break;\n        }\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if(!(cin>>N>>M)) return 0;\n    targets.resize(M);\n    for(int k=0;k<M;k++){\n        cin>>targets[k].i>>targets[k].j;\n    }\n    grid = Grid(N);\n    Pos cur = targets[0];\n    for(int k=1;k<M;k++){\n        Pos t = targets[k];\n        // try border slide if possible\n        Dir d;\n        if(can_land_by_slide_to_target(cur, t, d)){\n            // Ensure slide path has no internal blocks; we have none, so safe\n            do_slide(cur, d);\n        }else{\n            move_greedy(cur, t);\n        }\n    }\n    // Output\n    for(auto &s: out_actions) cout<<s<<\"\\n\";\n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int a,b,c,d; // [a,c) x [b,d)\n    long long area;\n    inline int w() const { return c - a; }\n    inline int h() const { return d - b; }\n    inline void recompute_area() { area = 1LL * (c - a) * (d - b); }\n};\n\nstatic inline bool overlap_pos(const Rect& A, const Rect& B){\n    if (A.c <= B.a || B.c <= A.a) return false;\n    if (A.d <= B.b || B.d <= A.b) return false;\n    return true;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n;\n    if(!(cin>>n)) return 0;\n    vector<int> x(n), y(n);\n    vector<long long> r(n);\n    for(int i=0;i<n;i++) cin>>x[i]>>y[i]>>r[i];\n\n    vector<Rect> rect(n);\n    for(int i=0;i<n;i++){\n        int a=x[i], b=y[i], c=x[i]+1, d=y[i]+1;\n        a = max(0, min(9999, a));\n        b = max(0, min(9999, b));\n        c = min(10000, max(a+1, min(10000, c)));\n        d = min(10000, max(b+1, min(10000, d)));\n        rect[i] = {a,b,c,d,0};\n        rect[i].recompute_area();\n    }\n\n    // Spatial grid\n    const int G = 64;\n    const int GRID = (10000 + G - 1) / G;\n    vector<vector<int>> buckets(GRID * GRID);\n    auto cell_id = [&](int gx, int gy){ return gy*GRID + gx; };\n    auto gx_from_x = [&](int X){ return min(GRID-1, max(0, X / G)); };\n    auto gy_from_y = [&](int Y){ return min(GRID-1, max(0, Y / G)); };\n\n    auto add_rect = [&](int id){\n        const Rect &R = rect[id];\n        int gx0 = gx_from_x(R.a), gx1 = gx_from_x(max(0, R.c-1));\n        int gy0 = gy_from_y(R.b), gy1 = gy_from_y(max(0, R.d-1));\n        for(int gy=gy0; gy<=gy1; ++gy)\n            for(int gx=gx0; gx<=gx1; ++gx)\n                buckets[cell_id(gx,gy)].push_back(id);\n    };\n    auto remove_rect = [&](int id){\n        const Rect &R = rect[id];\n        int gx0 = gx_from_x(R.a), gx1 = gx_from_x(max(0, R.c-1));\n        int gy0 = gy_from_y(R.b), gy1 = gy_from_y(max(0, R.d-1));\n        for(int gy=gy0; gy<=gy1; ++gy)\n            for(int gx=gx0; gx<=gx1; ++gx){\n                auto &v = buckets[cell_id(gx,gy)];\n                for(size_t k=0;k<v.size();++k){\n                    if(v[k]==id){ v[k]=v.back(); v.pop_back(); break; }\n                }\n            }\n    };\n\n    auto check_band = [&](const Rect& NR, int x0, int x1, int y0, int y1, int self)->bool{\n        int gx0 = gx_from_x(x0);\n        int gx1 = gx_from_x(max(0,x1-1));\n        int gy0 = gy_from_y(y0);\n        int gy1 = gy_from_y(max(0,y1-1));\n        for (int gy=gy0; gy<=gy1; ++gy)\n            for (int gx=gx0; gx<=gx1; ++gx){\n                const auto &v = buckets[cell_id(gx,gy)];\n                for (int id : v) {\n                    if (id==self) continue;\n                    if (overlap_pos(NR, rect[id])) return false;\n                }\n            }\n        return true;\n    };\n\n    auto can_expand = [&](int i, int s)->bool{\n        const Rect &R = rect[i];\n        if (s==0) {\n            if (R.a <= 0) return false;\n            Rect NR = R; NR.a = R.a - 1;\n            return check_band(NR, NR.a, R.a, R.b, R.d, i);\n        } else if (s==1) {\n            if (R.c >= 10000) return false;\n            Rect NR = R; NR.c = R.c + 1;\n            return check_band(NR, R.c, NR.c, R.b, R.d, i);\n        } else if (s==2) {\n            if (R.b <= 0) return false;\n            Rect NR = R; NR.b = R.b - 1;\n            return check_band(NR, R.a, R.c, NR.b, R.b, i);\n        } else {\n            if (R.d >= 10000) return false;\n            Rect NR = R; NR.d = R.d + 1;\n            return check_band(NR, R.a, R.c, R.d, NR.d, i);\n        }\n    };\n\n    auto do_expand = [&](int i, int s){\n        remove_rect(i);\n        if (s==0) rect[i].a--;\n        else if (s==1) rect[i].c++;\n        else if (s==2) rect[i].b--;\n        else rect[i].d++;\n        rect[i].recompute_area();\n        add_rect(i);\n    };\n\n    auto can_shrink = [&](int i, int s)->bool{\n        const Rect &R = rect[i];\n        if (s==0) { if (R.c - (R.a+1) <= 0) return false; }\n        else if (s==1) { if ((R.c-1) - R.a <= 0) return false; }\n        else if (s==2) { if (R.d - (R.b+1) <= 0) return false; }\n        else { if ((R.d-1) - R.b <= 0) return false; }\n        return true;\n    };\n    auto do_shrink = [&](int i, int s){\n        remove_rect(i);\n        if (s==0) rect[i].a++;\n        else if (s==1) rect[i].c--;\n        else if (s==2) rect[i].b++;\n        else rect[i].d--;\n        rect[i].recompute_area();\n        add_rect(i);\n    };\n\n    auto score = [&](long long si, long long ri)->long double{\n        long double mn = min<long double>(ri, si);\n        long double mx = max<long double>(ri, si);\n        long double t = mn / mx;\n        return 1.0L - (1.0L - t)*(1.0L - t);\n    };\n\n    // RNG and timer\n    uint64_t seed = chrono::high_resolution_clock::now().time_since_epoch().count();\n    mt19937_64 rng(seed);\n    auto now = [&](){ return chrono::high_resolution_clock::now(); };\n    auto start_time = now();\n    const double TIME_LIMIT = 4.9; // be safe\n    auto elapsed_sec = [&](){ return chrono::duration<double>(now() - start_time).count(); };\n\n    for(int i=0;i<n;i++) add_rect(i);\n\n    vector<pair<long long,int>> ord(n);\n    vector<long double> PI(n);\n    for (int i=0;i<n;i++) PI[i] = score(rect[i].area, r[i]);\n\n    // Binary search maximum steps to expand in direction s without collision and within bounds\n    auto max_expand_steps = [&](int i, int s, int maxSteps)->int{\n        const Rect &R = rect[i];\n        int lo = 0, hi = maxSteps;\n        auto feasible = [&](int steps)->bool{\n            if (steps==0) return true;\n            Rect NR = R;\n            if (s==0) {\n                if (R.a - steps < 0) return false;\n                NR.a = R.a - steps;\n                // check band chunk by chunk using the band at the final state; still safe to check entire added area via bands per row of cells\n                // We check union as: for k in 1..steps, band [R.a-k, R.a-k+1) x [R.b, R.d)\n                // Approximate by checking the whole slab [R.a-steps, R.a)\n                return check_band(NR, R.a - steps, R.a, R.b, R.d, i);\n            } else if (s==1) {\n                if (R.c + steps > 10000) return false;\n                NR.c = R.c + steps;\n                return check_band(NR, R.c, R.c + steps, R.b, R.d, i);\n            } else if (s==2) {\n                if (R.b - steps < 0) return false;\n                NR.b = R.b - steps;\n                return check_band(NR, R.a, R.c, R.b - steps, R.b, i);\n            } else {\n                if (R.d + steps > 10000) return false;\n                NR.d = R.d + steps;\n                return check_band(NR, R.a, R.c, R.d, R.d + steps, i);\n            }\n        };\n        while (lo < hi) {\n            int mid = (lo + hi + 1) >> 1;\n            if (feasible(mid)) lo = mid;\n            else hi = mid - 1;\n        }\n        return lo;\n    };\n\n    // Phase A: strict growth to target\n    while (elapsed_sec() < TIME_LIMIT * 0.6) {\n        for (int i=0;i<n;i++){\n            long long deficit = r[i] - rect[i].area;\n            ord[i] = {deficit, i}; // overshoot negative => go later\n        }\n        sort(ord.begin(), ord.end(), [&](auto &L, auto &R){\n            if (L.first != R.first) return L.first > R.first;\n            return L.second < R.second;\n        });\n        bool any=false;\n        for (int kk=0; kk<n && elapsed_sec() < TIME_LIMIT * 0.6; ++kk){\n            int i = ord[kk].second;\n            if (rect[i].area >= r[i]) continue;\n            // Try pick best direction with multi-step\n            int w = rect[i].w(), h = rect[i].h();\n            int best_dir = -1, best_steps = 0;\n            long double best_gain = 0.0L;\n            for (int d=0; d<4; ++d){\n                int step_cap = 32; // moderate chunk\n                int steps = max_expand_steps(i, d, step_cap);\n                if (steps <= 0) continue;\n                // limit by reaching target area\n                long long si = rect[i].area;\n                long long ri_ = r[i];\n                long long inc_per = (d<=1 ? h : w);\n                // when stepping k times, inc area is k*(inc_per + (k-1)*(d<=1?0:0)? Actually width/height increases after each step for perpendicular expansions.\n                // Precisely: for horizontal (left/right): area inc after t steps: t*h\n                // For vertical (up/down): t*w\n                // So linear, good.\n                long long maxk = min<long long>(steps, (ri_ - si + inc_per - 1) / inc_per);\n                if (maxk <= 0) continue;\n                long long newS = si + maxk * inc_per;\n                long double gain = score(newS, ri_) - score(si, ri_);\n                // slight aspect balance encouragement\n                int nw = w + ((d<=1)?maxk:0);\n                int nh = h + ((d>=2)?maxk:0);\n                long double aspect_pen = fabsl((long double)nw/nh - 1.0L);\n                gain -= 0.00002L * aspect_pen;\n                if (gain > best_gain + 1e-18) {\n                    best_gain = gain;\n                    best_dir = d;\n                    best_steps = (int)maxk;\n                }\n            }\n            if (best_dir != -1 && best_steps > 0) {\n                // apply steps one by one (to maintain collision invariant reliably)\n                for (int t=0; t<best_steps; ++t) {\n                    if (!can_expand(i, best_dir)) break;\n                    do_expand(i, best_dir);\n                }\n                PI[i] = score(rect[i].area, r[i]);\n                any = true;\n            }\n        }\n        if (!any) break;\n    }\n\n    // Phase B: selective controlled overshoot in isolated areas\n    // Estimate isolation: sum of free steps in four directions\n    auto isolation_score = [&](int i)->int{\n        int total = 0;\n        // use small caps to estimate\n        total += max_expand_steps(i, 0, 64);\n        total += max_expand_steps(i, 1, 64);\n        total += max_expand_steps(i, 2, 64);\n        total += max_expand_steps(i, 3, 64);\n        return total;\n    };\n    vector<int> iso(n);\n    for (int i=0;i<n;i++) iso[i] = isolation_score(i);\n\n    // Allow slight overshoot based on isolation\n    while (elapsed_sec() < TIME_LIMIT * 0.8) {\n        // Sort by isolation descending, then deficit (still prefer underfilled)\n        vector<tuple<int,long long,int>> order2;\n        order2.reserve(n);\n        for (int i=0;i<n;i++) {\n            long long deficit = r[i] - rect[i].area;\n            order2.emplace_back(iso[i], deficit, i);\n        }\n        sort(order2.begin(), order2.end(), [&](auto &A, auto &B){\n            if (get<0>(A) != get<0>(B)) return get<0>(A) > get<0>(B);\n            if (get<1>(A) != get<1>(B)) return get<1>(A) > get<1>(B);\n            return get<2>(A) < get<2>(B);\n        });\n        bool any=false;\n        for (auto &tp : order2){\n            if (elapsed_sec() >= TIME_LIMIT * 0.8) break;\n            int i = get<2>(tp);\n            long long si = rect[i].area, ri_ = r[i];\n            // define overshoot factor\n            double f = 1.0 + min(0.10, 0.02 + 0.0005 * get<0>(tp)); // between ~1.02 and 1.10\n            long long cap = (long long)floor(ri_ * f + 1e-9);\n            if (si >= cap) continue;\n            int w = rect[i].w(), h = rect[i].h();\n            int best_dir=-1, best_steps=0;\n            long double best_gain = 0.0L;\n            for (int d=0; d<4; ++d){\n                int steps = max_expand_steps(i, d, 32);\n                if (steps<=0) continue;\n                long long inc_per = (d<=1 ? h : w);\n                long long maxk = min<long long>(steps, (cap - si) / inc_per);\n                if (maxk <= 0) continue;\n                long long newS = si + maxk * inc_per;\n                long double gain = score(newS, ri_) - score(si, ri_);\n                int nw = w + ((d<=1)?maxk:0);\n                int nh = h + ((d>=2)?maxk:0);\n                long double aspect_pen = fabsl((long double)nw/nh - 1.0L);\n                gain -= 0.00001L * aspect_pen;\n                if (gain > best_gain + 1e-18) {\n                    best_gain = gain;\n                    best_dir = d;\n                    best_steps = (int)maxk;\n                }\n            }\n            if (best_dir!=-1 && best_steps>0 && best_gain > 1e-12) {\n                for (int t=0;t<best_steps; ++t) {\n                    if (!can_expand(i, best_dir)) break;\n                    do_expand(i, best_dir);\n                }\n                PI[i] = score(rect[i].area, r[i]);\n                any=true;\n            }\n        }\n        if (!any) break;\n        // update isolation sparsely\n        for (int i=0;i<n;i++) if ((i&7)==0) iso[i] = isolation_score(i);\n    }\n\n    // Cooperative micro-shrink with multi-step neighbor expansion\n    auto try_coop = [&](int a, int side)->bool{\n        if (!can_shrink(a, side)) return false;\n        if (rect[a].area <= r[a]) return false;\n        // virtually shrink a by 1\n        Rect oldA = rect[a];\n        remove_rect(a);\n        if (side==0) rect[a].a++;\n        else if (side==1) rect[a].c--;\n        else if (side==2) rect[a].b++;\n        else rect[a].d--;\n        rect[a].recompute_area();\n        add_rect(a);\n        long double oldPa = PI[a];\n        long double newPa = score(rect[a].area, r[a]);\n\n        // collect neighbors near the freed band\n        int x0 = min(oldA.a, rect[a].a), x1 = max(oldA.c, rect[a].c);\n        int y0 = min(oldA.b, rect[a].b), y1 = max(oldA.d, rect[a].d);\n        int gx0 = gx_from_x(x0), gx1 = gx_from_x(max(0,x1-1));\n        int gy0 = gy_from_y(y0), gy1 = gy_from_y(max(0,y1-1));\n        unordered_set<int> candset; candset.reserve(64);\n        for (int gy=gy0; gy<=gy1; ++gy)\n            for (int gx=gx0; gx<=gx1; ++gx){\n                for (int b : buckets[cell_id(gx,gy)]) if (b!=a) candset.insert(b);\n            }\n\n        struct Move { int id, dir, k; long double gain; };\n        Move best = {-1,-1,0,0.0L};\n        for (int b : candset) {\n            if (rect[b].area >= r[b]) continue;\n            // try all directions\n            for (int d=0; d<4; ++d){\n                // quick steps\n                int steps = max_expand_steps(b, d, 32);\n                if (steps<=0) continue;\n                long long si = rect[b].area, ri_ = r[b];\n                long long inc_per = (d<=1 ? rect[b].h() : rect[b].w());\n                long long maxk = min<long long>(steps, (ri_ - si) / inc_per);\n                if (maxk<=0) continue;\n                long long newS = si + maxk * inc_per;\n                long double gain = score(newS, ri_) - score(si, ri_);\n                if (gain > best.gain + 1e-12) best = {b, d, (int)maxk, gain};\n            }\n        }\n        long double total_gain = (newPa - oldPa) + best.gain;\n        if (best.id != -1 && total_gain > 1e-12) {\n            // commit neighbor move\n            for (int t=0; t<best.k; ++t) {\n                if (!can_expand(best.id, best.dir)) break;\n                do_expand(best.id, best.dir);\n            }\n            PI[a] = newPa;\n            PI[best.id] = score(rect[best.id].area, r[best.id]);\n            return true;\n        } else {\n            // revert\n            remove_rect(a);\n            rect[a] = oldA;\n            rect[a].recompute_area();\n            add_rect(a);\n            return false;\n        }\n    };\n\n    double coop_budget_end = TIME_LIMIT * 0.95;\n    vector<int> idx(n); iota(idx.begin(), idx.end(), 0);\n    int coop_attempts = 0, coop_success = 0;\n    while (elapsed_sec() < coop_budget_end && coop_attempts < 30000){\n        shuffle(idx.begin(), idx.end(), rng);\n        bool any=false;\n        for (int i : idx){\n            if (elapsed_sec() >= coop_budget_end) break;\n            if (rect[i].area <= r[i]) continue;\n            array<pair<int,int>,4> sides = {{\n                {rect[i].w(), 0}, {rect[i].w(), 1}, {rect[i].h(), 2}, {rect[i].h(), 3}\n            }};\n            sort(sides.begin(), sides.end(), [&](auto&A, auto&B){ return A.first > B.first; });\n            for (auto [__, s] : sides){\n                coop_attempts++;\n                if (try_coop(i, s)) { any=true; coop_success++; break; }\n                if (elapsed_sec() >= coop_budget_end) break;\n            }\n        }\n        if (!any) break;\n    }\n\n    // Final polish: fill underfilled rectangles with greedy small expansions to reach ri if possible\n    while (elapsed_sec() < TIME_LIMIT) {\n        bool any=false;\n        for (int i=0;i<n && elapsed_sec()<TIME_LIMIT; ++i){\n            if (rect[i].area >= r[i]) continue;\n            int best_dir=-1;\n            long double best_gain=0.0L;\n            for (int d=0; d<4; ++d){\n                if (!can_expand(i,d)) continue;\n                long long si = rect[i].area;\n                long long inc = (d<=1 ? rect[i].h() : rect[i].w());\n                long long ri_ = r[i];\n                if (si + inc > ri_) continue;\n                long double gain = score(si + inc, ri_) - score(si, ri_);\n                if (gain > best_gain + 1e-18) { best_gain=gain; best_dir=d; }\n            }\n            if (best_dir!=-1 && best_gain > 1e-18) {\n                do_expand(i, best_dir);\n                PI[i] = score(rect[i].area, r[i]);\n                any=true;\n            }\n        }\n        if (!any) break;\n    }\n\n    // Output\n    for (int i=0;i<n;i++){\n        cout << rect[i].a << ' ' << rect[i].b << ' ' << rect[i].c << ' ' << rect[i].d << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    static constexpr int H = 50, W = 50;\n    int si, sj;\n    vector<vector<int>> t, p;\n    int M;\n    vector<vector<pair<int,int>>> tiles;\n    vector<vector<char>> preferred;\n    vector<vector<int>> sidx;\n\n    vector<char> visited_tile;\n    vector<vector<char>> visited_cell;\n    vector<char> path;\n    int ci, cj;\n\n    uint64_t seed;\n    inline uint64_t rng64() {\n        seed ^= seed << 7; seed ^= seed >> 9; seed ^= 0x9e3779b97f4a7c15ull;\n        return seed;\n    }\n\n    static inline bool inb(int i, int j) {\n        return 0 <= i && i < H && 0 <= j && j < W;\n    }\n    static constexpr int di[4] = {-1,1,0,0};\n    static constexpr int dj[4] = {0,0,-1,1};\n    static constexpr char dc[4] = {'U','D','L','R'};\n\n    Solver(int si_, int sj_, vector<vector<int>>&& t_, vector<vector<int>>&& p_)\n        : si(si_), sj(sj_), t(move(t_)), p(move(p_)) {\n        M = 0;\n        for (int i=0;i<H;i++) for (int j=0;j<W;j++) M = max(M, t[i][j]+1);\n        tiles.assign(M, {});\n        for (int i=0;i<H;i++) for (int j=0;j<W;j++) tiles[t[i][j]].push_back({i,j});\n\n        preferred.assign(H, vector<char>(W, 0));\n        for (int id=0; id<M; id++){\n            auto &cells = tiles[id];\n            if (cells.empty()) continue;\n            int bestk = 0, bestv = -1;\n            for (int k=0;k<(int)cells.size();k++){\n                auto [i,j] = cells[k];\n                if (p[i][j] > bestv){ bestv = p[i][j]; bestk = k; }\n            }\n            for (int k=0;k<(int)cells.size();k++){\n                auto [i,j] = cells[k];\n                preferred[i][j] = (k==bestk);\n            }\n        }\n\n        sidx.assign(H, vector<int>(W, -1));\n        int idx=0;\n        for (int i=0;i<H;i++){\n            if (i%2==0){\n                for (int j=0;j<W;j++) sidx[i][j]=idx++;\n            }else{\n                for (int j=W-1;j>=0;j--) sidx[i][j]=idx++;\n            }\n        }\n    }\n\n    inline int local_deg(int i, int j) {\n        int d=0;\n        for (int k=0;k<4;k++){\n            int ni=i+di[k], nj=j+dj[k];\n            if (!inb(ni,nj)) continue;\n            if (!visited_tile[t[ni][nj]]) d++;\n        }\n        return d;\n    }\n\n    // Estimate number of distinct unvisited tiles reachable within a window after stepping into (i,j)\n    int local_reach_after_step(int i, int j, int window_rad=3) {\n        int tid0 = t[i][j];\n        int rmin = max(0, i - window_rad);\n        int rmax = min(H-1, i + window_rad);\n        int cmin = max(0, j - window_rad);\n        int cmax = min(W-1, j + window_rad);\n        vector<vector<char>> vis(H, vector<char>(W, 0));\n        deque<pair<int,int>> dq;\n        vector<char> seen_tile(M, 0);\n        int cnt = 0;\n        for (int k=0;k<4;k++){\n            int ni=i+di[k], nj=j+dj[k];\n            if (!inb(ni,nj)) continue;\n            if (ni < rmin || ni > rmax || nj < cmin || nj > cmax) continue;\n            int tid = t[ni][nj];\n            if (tid == tid0) continue;\n            if (visited_tile[tid]) continue;\n            if (vis[ni][nj]) continue;\n            vis[ni][nj]=1;\n            dq.emplace_back(ni,nj);\n        }\n        while(!dq.empty()){\n            auto [x,y]=dq.front(); dq.pop_front();\n            int tid = t[x][y];\n            if (!seen_tile[tid]) { seen_tile[tid]=1; cnt++; }\n            for (int k=0;k<4;k++){\n                int nx=x+di[k], ny=y+dj[k];\n                if (!inb(nx,ny)) continue;\n                if (nx < rmin || nx > rmax || ny < cmin || ny > cmax) continue;\n                int tnx = t[nx][ny];\n                if (tnx == tid0) continue;\n                if (visited_tile[tnx]) continue;\n                if (!vis[nx][ny]) { vis[nx][ny]=1; dq.emplace_back(nx,ny); }\n            }\n        }\n        return cnt;\n    }\n\n    // Rough global frontier count: count unvisited tiles that are adjacent to any visited cell.\n    int global_frontier_count() {\n        // For speed, only approximate: look at neighbors of current cell within radius 5 BFS\n        // and count unique tiles adjacent to any visited cell in that region.\n        // This keeps O(window) time.\n        const int R = 5;\n        vector<vector<char>> vis(H, vector<char>(W, 0));\n        deque<pair<int,int>> dq;\n        dq.emplace_back(ci, cj);\n        vis[ci][cj]=1;\n        int steps = 0;\n        vector<char> seen(M, 0);\n        int count = 0;\n        while(!dq.empty() && steps < 500){ // limit\n            auto [x,y]=dq.front(); dq.pop_front();\n            steps++;\n            for (int k=0;k<4;k++){\n                int nx = x+di[k], ny = y+dj[k];\n                if (!inb(nx,ny)) continue;\n                if (!vis[nx][ny]){\n                    if (abs(nx-ci)+abs(ny-cj) <= R){\n                        vis[nx][ny]=1;\n                        dq.emplace_back(nx,ny);\n                    }\n                }\n                int tid = t[nx][ny];\n                if (!visited_tile[tid] && !seen[tid]) { seen[tid]=1; count++; }\n            }\n        }\n        return count;\n    }\n\n    long long run_with_weights(int W_P, int W_PREF, int W_FLOW, int W_DEG, int W_LK1, int W_SAFE, int W_REGION, int W_FRON,\n                               vector<char>& outPath, uint64_t seed0) {\n        visited_tile.assign(M, 0);\n        visited_cell.assign(H, vector<char>(W, 0));\n        path.clear();\n        ci = si; cj = sj;\n        visited_tile[t[ci][cj]] = 1;\n        visited_cell[ci][cj] = 1;\n        seed = seed0;\n\n        long long totalScore = p[ci][cj];\n        int anchor = sidx[ci][cj];\n\n        int baseFrontier = global_frontier_count();\n\n        for (int step=0; step < H*W; step++){\n            struct Cand {\n                int dir, ni, nj, tid;\n                long long sc;\n                int pval, deg, lkdeg, diff, region, frdelta;\n                bool pref;\n                bool dead;\n            };\n            vector<Cand> cands;\n            cands.reserve(4);\n\n            int curIdx = sidx[ci][cj];\n\n            for (int k=0;k<4;k++){\n                int ni=ci+di[k], nj=cj+dj[k];\n                if (!inb(ni,nj)) continue;\n                int tid = t[ni][nj];\n                if (visited_tile[tid]) continue;\n\n                int pv = p[ni][nj];\n                int deg = local_deg(ni,nj);\n                bool pref = preferred[ni][nj];\n\n                int diff = sidx[ni][nj] - curIdx;\n                int flow = 0;\n                if (sidx[ni][nj] >= anchor) {\n                    if (diff >= 1 && diff <= 2) flow = 3;\n                    else if (diff == 3) flow = 2;\n                    else if (diff == 0) flow = -3;\n                    else if (diff < 0 && diff >= -2) flow = 0;\n                } else {\n                    if (diff < 0) flow = -2;\n                    else if (diff == 0) flow = -3;\n                    else flow = 1;\n                }\n\n                // simulate: lookahead degree and local region and frontier delta\n                visited_tile[tid] = 1;\n                // lkdeg\n                int bestd2 = -1;\n                for (int k2=0;k2<4;k2++){\n                    int xi=ni+di[k2], xj=nj+dj[k2];\n                    if (!inb(xi,xj)) continue;\n                    int tid2 = t[xi][xj];\n                    if (visited_tile[tid2]) continue;\n                    int d2 = 0;\n                    for (int k3=0;k3<4;k3++){\n                        int yi=xi+di[k3], yj=xj+dj[k3];\n                        if (!inb(yi,yj)) continue;\n                        int tid3 = t[yi][yj];\n                        if (tid3 == tid) continue;\n                        if (visited_tile[tid3]) continue;\n                        d2++;\n                    }\n                    bestd2 = max(bestd2, d2);\n                }\n                int lkdeg = bestd2;\n                int region = local_reach_after_step(ni, nj, 3);\n\n                // rough frontier delta: recompute local frontier around the simulated position\n                int old_ci = ci, old_cj = cj;\n                int old_baseFrontier = baseFrontier;\n                // Temporarily switch current pos to neighbor for estimate\n                ci = ni; cj = nj;\n                int newFrontier = global_frontier_count();\n                int frdelta = newFrontier - old_baseFrontier;\n                // restore\n                ci = old_ci; cj = old_cj;\n\n                visited_tile[tid] = 0;\n\n                bool dead = (lkdeg < 0);\n\n                long long sc = 0;\n                sc += 1LL*W_P * pv;\n                // Adaptive preference: if non-preferred but region is much larger, soften penalty\n                int pref_bonus = (pref ? W_PREF : max(0, W_PREF - max(0, 5 - region)));\n                sc += pref_bonus;\n                sc += 1LL*W_FLOW * flow;\n                sc += 1LL*W_DEG * deg;\n                if (!dead) sc += 1LL*W_LK1 * lkdeg;\n                else sc -= 1LL*W_SAFE;\n                sc += 1LL*W_REGION * region;\n                sc += 1LL*W_FRON * frdelta;\n                sc += (rng64() & 7);\n\n                cands.push_back({k,ni,nj,tid,sc,pv,deg,lkdeg,diff,region,frdelta,pref,dead});\n            }\n\n            if (cands.empty()) break;\n\n            bool hasSafe = false;\n            for (auto &c: cands) if (!c.dead) { hasSafe = true; break; }\n\n            sort(cands.begin(), cands.end(), [&](const Cand& a, const Cand& b){\n                long long sa = a.sc + ((hasSafe && a.dead) ? -1000000000LL : 0LL);\n                long long sb = b.sc + ((hasSafe && b.dead) ? -1000000000LL : 0LL);\n                if (sa != sb) return sa > sb;\n                if (a.region != b.region) return a.region > b.region;\n                if (a.deg != b.deg) return a.deg > b.deg;\n                if (a.pval != b.pval) return a.pval > b.pval;\n                return a.diff > b.diff;\n            });\n\n            // Micro backtracking: if top choice is risky (lkdeg<=0 or region small) and second choice is safer, switch\n            auto best = cands[0];\n            if (cands.size() >= 2) {\n                auto alt = cands[1];\n                bool riskyBest = (best.lkdeg <= 0) || (best.region <= 2 && best.frdelta < 0);\n                bool saferAlt = (alt.lkdeg >= 1 && alt.region >= max(3, best.region)) || (alt.frdelta > best.frdelta+1);\n                if (riskyBest && saferAlt) {\n                    best = alt;\n                }\n            }\n\n            if (sidx[best.ni][best.nj] >= anchor) {\n                anchor = max(anchor, sidx[best.ni][best.nj] - 1);\n            }\n\n            path.push_back(dc[best.dir]);\n            ci = best.ni; cj = best.nj;\n            visited_tile[best.tid] = 1;\n            visited_cell[ci][cj] = 1;\n            totalScore += p[ci][cj];\n            baseFrontier = max(baseFrontier, baseFrontier + best.frdelta);\n        }\n\n        outPath = path;\n        return totalScore;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si, sj;\n    if (!(cin>>si>>sj)) return 0;\n    const int H=50, W=50;\n    vector<vector<int>> t(H, vector<int>(W));\n    for (int i=0;i<H;i++) for (int j=0;j<W;j++) cin>>t[i][j];\n    vector<vector<int>> p(H, vector<int>(W));\n    for (int i=0;i<H;i++) for (int j=0;j<W;j++) cin>>p[i][j];\n\n    Solver solver(si, sj, move(t), move(p));\n\n    vector<char> bestPath, tmpPath;\n    long long bestScore = -1;\n    uint64_t seedBase = 1469598103934665603ull ^ (uint64_t)(si*131 + sj*911);\n\n    // Preset A: balanced with mild frontier emphasis\n    long long scA = solver.run_with_weights(\n        /*W_P*/ 92, /*W_PREF*/ 16, /*W_FLOW*/ 10, /*W_DEG*/ 8, /*W_LK1*/ 10, /*W_SAFE*/ 70, /*W_REGION*/ 2, /*W_FRON*/ 2,\n        tmpPath, seedBase ^ 0xA5A5A5A5A5A5A5A5ull\n    );\n    bestScore = scA; bestPath = tmpPath;\n\n    // Preset B: connectivity-first\n    long long scB = solver.run_with_weights(\n        /*W_P*/ 78, /*W_PREF*/ 10, /*W_FLOW*/ 12, /*W_DEG*/ 12, /*W_LK1*/ 16, /*W_SAFE*/ 90, /*W_REGION*/ 3, /*W_FRON*/ 3,\n        tmpPath, seedBase ^ 0x5A5A5A5A5A5A5A5Aull\n    );\n    if (scB > bestScore) { bestScore = scB; bestPath = tmpPath; }\n\n    cout << string(bestPath.begin(), bestPath.end()) << \"\\n\";\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct GridRouter {\n    static constexpr int HN = 30;\n    static constexpr int WN = 30;\n    static constexpr int HHE = HN * (WN - 1); // horizontal edges count 30*29=870\n    static constexpr int HVE = (HN - 1) * WN; // vertical edges count 29*30=870\n    static constexpr int E = HHE + HVE;       // 1740\n\n    vector<double> w; // per-edge weights\n    vector<pair<int,int>> adjIdx[HN][WN]; // (neighbor node index, edge id)\n    mt19937_64 rng;\n\n    GridRouter() : w(E, 5000.0) {\n        rng.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());\n        buildGraph();\n    }\n\n    static int idH(int i, int j) { return i * (WN - 1) + j; }\n    static int idV(int i, int j) { return HHE + i * WN + j; }\n    int nodeId(int i, int j) const { return i * WN + j; }\n    pair<int,int> nodePos(int id) const { return {id / WN, id % WN}; }\n\n    void buildGraph() {\n        for (int i = 0; i < HN; ++i) for (int j = 0; j < WN; ++j) adjIdx[i][j].clear();\n        for (int i = 0; i < HN; ++i) {\n            for (int j = 0; j < WN - 1; ++j) {\n                int e = idH(i,j);\n                int u = nodeId(i,j), v = nodeId(i,j+1);\n                adjIdx[i][j].push_back({v, e});\n                adjIdx[i][j+1].push_back({u, e});\n            }\n        }\n        for (int i = 0; i < HN - 1; ++i) {\n            for (int j = 0; j < WN; ++j) {\n                int e = idV(i,j);\n                int u = nodeId(i,j), v = nodeId(i+1,j);\n                adjIdx[i][j].push_back({v, e});\n                adjIdx[i+1][j].push_back({u, e});\n            }\n        }\n    }\n\n    struct DRes {\n        vector<int> prevNode;\n        vector<int> prevEdge;\n        vector<int> pathEdges;\n        string pathMoves;\n        double pathCost;\n    };\n\n    // Dijkstra with optional per-query randomization on edges to encourage exploration\n    DRes shortestPath(pair<int,int> s, pair<int,int> t, double randEps, uint64_t randSeed) {\n        int N = HN * WN;\n        vector<double> dist(N, numeric_limits<double>::infinity());\n        vector<int> prevN(N, -1), prevE(N, -1);\n        int sId = nodeId(s.first, s.second);\n        int tId = nodeId(t.first, t.second);\n\n        vector<float> mult;\n        if (randEps > 0) {\n            mult.assign(E, 1.0f);\n            uint64_t x = randSeed ? randSeed : rng();\n            auto nextRand = [&]() {\n                x ^= x << 13; x ^= x >> 7; x ^= x << 17;\n                return x;\n            };\n            for (int e = 0; e < E; ++e) {\n                uint64_t r = nextRand();\n                double u = ((r >> 11) & 0xFFFFFFFFull) / double(0xFFFFFFFFull);\n                double z = 2.0*u - 1.0;\n                mult[e] = float(1.0 + randEps * z);\n            }\n        }\n\n        using P = pair<double,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[sId] = 0.0;\n        pq.emplace(0.0, sId);\n\n        while (!pq.empty()) {\n            auto [d,u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == tId) break;\n            auto [ui, uj] = nodePos(u);\n            for (auto [v, e] : adjIdx[ui][uj]) {\n                double ew = w[e];\n                if (!mult.empty()) ew *= mult[e];\n                ew = max(100.0, min(20000.0, ew));\n                double nd = d + ew;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prevN[v] = u;\n                    prevE[v] = e;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n\n        DRes res;\n        res.prevNode = move(prevN);\n        res.prevEdge = move(prevE);\n        res.pathCost = dist[tId];\n\n        vector<int> edges;\n        string moves;\n        int cur = tId;\n        while (cur != sId && res.prevEdge[cur] != -1) {\n            int e = res.prevEdge[cur];\n            edges.push_back(e);\n            auto [pi, pj] = nodePos(res.prevNode[cur]);\n            auto [ci, cj] = nodePos(cur);\n            if (ci == pi) {\n                moves.push_back(cj == pj + 1 ? 'R' : 'L');\n            } else {\n                moves.push_back(ci == pi + 1 ? 'D' : 'U');\n            }\n            cur = res.prevNode[cur];\n        }\n        reverse(edges.begin(), edges.end());\n        reverse(moves.begin(), moves.end());\n        res.pathEdges = move(edges);\n        res.pathMoves = move(moves);\n        return res;\n    }\n\n    void updateWeights(const vector<int>& pathEdges, long long observed, int qIndex) {\n        if (pathEdges.empty()) return;\n        double pred = 0.0;\n        for (int e : pathEdges) pred += w[e];\n        if (pred <= 1e-9) return;\n\n        double y = (double)observed;\n        double s = y / pred;\n        // wider but safe clip, as noise is in [0.9,1.1]\n        s = max(0.88, min(1.12, s));\n\n        double progress = (double)qIndex / 999.0;\n        double eta0 = 0.35;\n        double eta1 = 0.06;\n        double eta = eta0 * (1.0 - progress) + eta1 * progress;\n\n        double factor = 1.0 + eta * (s - 1.0);\n        factor = max(0.95, min(1.05, factor));\n\n        for (int e : pathEdges) {\n            w[e] *= factor;\n        }\n\n        // Mild smoothing to same-orientation neighbors (1 step)\n        double beta = 0.02 * (1.0 - progress) + 0.01 * progress;\n        for (int e : pathEdges) {\n            if (e < HHE) {\n                int i = e / (WN - 1);\n                int j = e % (WN - 1);\n                if (j - 1 >= 0) {\n                    int ne = idH(i, j - 1);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n                if (j + 1 < WN - 1) {\n                    int ne = idH(i, j + 1);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n            } else {\n                int ve = e - HHE;\n                int i = ve / WN;\n                int j = ve % WN;\n                if (i - 1 >= 0) {\n                    int ne = idV(i - 1, j);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n                if (i + 1 < HN - 1) {\n                    int ne = idV(i + 1, j);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n            }\n        }\n\n        // Clip updated edges\n        for (int e : pathEdges) {\n            if (w[e] < 500.0) w[e] = 500.0;\n            if (w[e] > 15000.0) w[e] = 15000.0;\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    GridRouter gr;\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        // Exploration epsilon: small and decay over first 200 queries\n        double eps_start = 0.05;\n        double eps = 0.0;\n        if (q < 200) {\n            double t = (double)q / 200.0;\n            eps = eps_start * (1.0 - t);\n        }\n\n        uint64_t seed = ((uint64_t)si<<48) ^ ((uint64_t)sj<<32) ^ ((uint64_t)ti<<16) ^ (uint64_t)tj ^ (uint64_t)(q*11400714819323198485ull);\n\n        auto res = gr.shortestPath({si,sj},{ti,tj}, eps, seed);\n\n        string path = res.pathMoves;\n        if (path.empty()) {\n            int di = ti - si;\n            int dj = tj - sj;\n            if (di > 0) path.append(di, 'D'); else path.append(-di, 'U');\n            if (dj > 0) path.append(dj, 'R'); else path.append(-dj, 'L');\n        }\n\n        cout << path << \"\\n\";\n        cout.flush();\n\n        long long observed;\n        if (!(cin >> observed)) return 0;\n\n        gr.updateWeights(res.pathEdges, observed, q);\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic inline int ch2i(char c){ return c - 'A'; }\nstatic inline char i2ch(int x){ return char('A' + x); }\n\nstruct Placement {\n    uint8_t dir; // 0=hor,1=ver\n    uint8_t fixed; // row for hor, col for ver\n    uint8_t start; // start index\n};\nstruct PlCover {\n    vector<uint16_t> idxs;\n};\nstruct RNG {\n    uint64_t x;\n    RNG(uint64_t seed=88172645463393265ull){ x=seed; }\n    inline uint64_t rng() { x ^= x<<7; x ^= x>>9; return x; }\n    inline int randint(int l, int r){ return int(l + rng() % (uint64_t)(r - l + 1)); }\n    inline double rand01(){ return (rng() >> 11) * (1.0/9007199254740992.0); }\n};\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    vector<string> s(M);\n    for(int i=0;i<M;i++) cin >> s[i];\n\n    // Encode strings and stats\n    vector<vector<uint8_t>> enc(M);\n    vector<int> slen(M);\n    array<int,8> globalCnt{}; globalCnt.fill(0);\n    for(int i=0;i<M;i++){\n        int k = (int)s[i].size();\n        slen[i]=k;\n        enc[i].resize(k);\n        for(int p=0;p<k;p++){\n            int v = ch2i(s[i][p]);\n            enc[i][p]=(uint8_t)v;\n            globalCnt[v]++;\n        }\n    }\n    int totalChars=0; for(int v:globalCnt) totalChars+=v;\n    array<double,8> invFreq;\n    for(int c=0;c<8;c++) invFreq[c] = globalCnt[c] ? (double)totalChars / (double)globalCnt[c] : 2.0*totalChars;\n\n    // Slight rarity weight\n    vector<double> sWeight(M,0.0);\n    for(int i=0;i<M;i++){\n        double r=0.0;\n        for(uint8_t v:enc[i]) r += invFreq[v];\n        sWeight[i] = 0.05 * (r / max(1,slen[i])); // small effect\n    }\n\n    // Precompute placements and covers\n    vector<vector<Placement>> placements(M);\n    vector<vector<PlCover>> covers(M);\n    for(int i=0;i<M;i++){\n        vector<Placement> ps;\n        ps.reserve(2*N*N);\n        for(int r=0;r<N;r++) for(int c0=0;c0<N;c0++) ps.push_back(Placement{0,(uint8_t)r,(uint8_t)c0});\n        for(int c=0;c<N;c++) for(int r0=0;r0<N;r0++) ps.push_back(Placement{1,(uint8_t)c,(uint8_t)r0});\n        placements[i]=move(ps);\n        vector<PlCover> cv(placements[i].size());\n        for(size_t pi=0; pi<placements[i].size(); ++pi){\n            const auto& pl = placements[i][pi];\n            int k = slen[i];\n            cv[pi].idxs.resize(k);\n            if(pl.dir==0){\n                int r=pl.fixed, c0=pl.start, base=r*N;\n                for(int p=0;p<k;p++){ int c=(c0+p)%N; cv[pi].idxs[p]=(uint16_t)(base+c); }\n            }else{\n                int c=pl.fixed, r0=pl.start;\n                for(int p=0;p<k;p++){ int r=(r0+p)%N; cv[pi].idxs[p]=(uint16_t)(r*N+c); }\n            }\n        }\n        covers[i]=move(cv);\n    }\n\n    auto solver_once = [&](RNG& rng, double time_budget_ms){\n        const int UNKNOWN = -1;\n        vector<int8_t> grid(N*N, UNKNOWN);\n        vector<char> satisfied(M, 0);\n\n        // Precompute order\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        stable_sort(order.begin(), order.end(), [&](int a, int b){\n            if(slen[a] != slen[b]) return slen[a] > slen[b];\n            return sWeight[a] > sWeight[b];\n        });\n\n        auto t0 = chrono::high_resolution_clock::now();\n\n        auto checkGainAgree = [&](int si, const PlCover& cv)->pair<int,int>{\n            // returns {gain, agreements}; -1 gain if invalid\n            const auto& e = enc[si];\n            int k = slen[si];\n            int gain=0, agree=0;\n            for(int p=0;p<k;p++){\n                int idx = cv.idxs[p];\n                int8_t v = grid[idx];\n                if(v==UNKNOWN) gain++;\n                else if(v == (int)e[p]) agree++;\n                else return {-1, 0};\n            }\n            return {gain, agree};\n        };\n        auto applyPl = [&](int si, const PlCover& cv){\n            const auto& e = enc[si];\n            int k = slen[si];\n            for(int p=0;p<k;p++){\n                grid[ cv.idxs[p] ] = (int8_t)e[p];\n            }\n        };\n\n        int iterations = 0;\n        while(true){\n            auto now = chrono::high_resolution_clock::now();\n            double ms = chrono::duration<double, std::milli>(now - t0).count();\n            if(ms > time_budget_ms) break;\n            iterations++;\n            if(rng.rand01() < 0.15){\n                int a=rng.randint(0,M-1), b=rng.randint(0,M-1);\n                if(a!=b) swap(order[a], order[b]);\n            }\n\n            // Collect candidates\n            struct Cand { int si; int pi; int gain; int agree; double score; };\n            vector<Cand> cands;\n            cands.reserve(64);\n            int zeroSat=0;\n\n            for(int oi=0; oi<M; ++oi){\n                int i = order[oi];\n                if(satisfied[i]) continue;\n                const auto& cvs = covers[i];\n                int totalP = (int)cvs.size();\n                int k = slen[i];\n                int sampleTarget = (k<=4 ? 200 : totalP); // sample up to 200 placements for very short strings\n                int step = max(1, totalP / max(1, sampleTarget));\n                int bestGain=-1, bestAgree=-1, bestPi=-1;\n                for(int pi=0; pi<totalP; pi+=step){\n                    auto ga = checkGainAgree(i, cvs[pi]);\n                    int g = ga.first;\n                    if(g < 0) continue;\n                    int a = ga.second;\n                    if(g==0){ // zero-gain candidate exists\n                        zeroSat++;\n                        satisfied[i]=1;\n                        bestGain=-2; // mark to skip adding\n                        break;\n                    }\n                    if(g > bestGain || (g==bestGain && a>bestAgree)){\n                        bestGain=g; bestAgree=a; bestPi=pi;\n                    }\n                }\n                if(bestGain > 0){\n                    double score = bestGain + 0.02*bestAgree + 0.01*sWeight[i] + 0.001*k;\n                    cands.push_back(Cand{i,bestPi,bestGain,bestAgree,score});\n                    if((int)cands.size() > 64) {\n                        // keep top 64\n                        nth_element(cands.begin(), cands.begin()+32, cands.end(),\n                            [](const Cand& A, const Cand& B){ return A.score > B.score; });\n                        cands.resize(32);\n                    }\n                }\n            }\n\n            if(cands.empty()) break;\n            // Select best candidate with small randomness among top few\n            sort(cands.begin(), cands.end(), [](const Cand& A, const Cand& B){\n                if(A.score != B.score) return A.score > B.score;\n                if(A.gain != B.gain) return A.gain > B.gain;\n                return A.agree > B.agree;\n            });\n            int pickIdx = 0;\n            int topk = min(6, (int)cands.size());\n            if(topk>1 && rng.rand01() < 0.25){\n                pickIdx = rng.randint(0, topk-1);\n            }\n            int si = cands[pickIdx].si;\n            int pi = cands[pickIdx].pi;\n            auto ga2 = checkGainAgree(si, covers[si][pi]);\n            if(ga2.first > 0){\n                applyPl(si, covers[si][pi]);\n                satisfied[si] = 1;\n            }else if(ga2.first == 0){\n                satisfied[si] = 1;\n            }else{\n                // invalidated; continue to next loop\n            }\n        }\n\n        // Final zero-gain marking\n        for(int i=0;i<M;i++){\n            if(satisfied[i]) continue;\n            const auto& cvs = covers[i];\n            const auto& e = enc[i];\n            int k = slen[i];\n            bool ok=false;\n            for(size_t pi=0; pi<cvs.size(); ++pi){\n                bool match=true;\n                for(int p=0;p<k;p++){\n                    int idx = cvs[pi].idxs[p];\n                    int8_t v = grid[idx];\n                    if(v==-1 || v != (int)e[p]){ match=false; break; }\n                }\n                if(match){ ok=true; break; }\n            }\n            if(ok) satisfied[i]=1;\n        }\n\n        // Consistent vote-based fill\n        vector<array<int,8>> votes(N*N);\n        for(int i=0;i<N*N;i++) votes[i].fill(0);\n        for(int i=0;i<M;i++){\n            const auto& cvs = covers[i];\n            const auto& e = enc[i];\n            int k = slen[i];\n            for(size_t pi=0; pi<cvs.size(); ++pi){\n                bool ok=true;\n                for(int p=0;p<k;p++){\n                    int idx=cvs[pi].idxs[p];\n                    int8_t v=grid[idx];\n                    if(v!=-1 && v!=(int)e[p]){ ok=false; break; }\n                }\n                if(!ok) continue;\n                for(int p=0;p<k;p++){\n                    int idx=cvs[pi].idxs[p];\n                    if(grid[idx]==-1) votes[idx][ e[p] ]++;\n                }\n            }\n        }\n        int fillGlobal = int(max_element(globalCnt.begin(), globalCnt.end()) - globalCnt.begin());\n        for(int idx=0; idx<N*N; ++idx){\n            if(grid[idx]==-1){\n                int bestL=fillGlobal, bestV=-1;\n                for(int c=0;c<8;c++){\n                    if(votes[idx][c] > bestV){ bestV=votes[idx][c]; bestL=c; }\n                }\n                grid[idx]=(int8_t)bestL;\n            }\n        }\n\n        // Post-fill quick absorption pass\n        for(int i=0;i<M;i++){\n            // if not satisfied, try to find zero-gain (now fully fixed grid)\n            // and nothing to apply since grid is fixed; just count later\n        }\n\n        // Final count\n        int satisfiedCount=0;\n        for(int i=0;i<M;i++){\n            bool ok=false;\n            const auto& cvs = covers[i];\n            const auto& e = enc[i];\n            int k = slen[i];\n            for(size_t pi=0; pi<cvs.size(); ++pi){\n                bool match=true;\n                for(int p=0;p<k;p++){\n                    int idx = cvs[pi].idxs[p];\n                    if(grid[idx] != (int)e[p]){ match=false; break; }\n                }\n                if(match){ ok=true; break; }\n            }\n            if(ok) satisfiedCount++;\n        }\n        return pair<vector<int8_t>, int>(move(grid), satisfiedCount);\n    };\n\n    RNG rng((uint64_t)chrono::high_resolution_clock::now().time_since_epoch().count());\n    auto start = chrono::high_resolution_clock::now();\n    double total_budget_ms = 2700.0;\n\n    vector<int8_t> bestGrid;\n    int bestC = -1;\n    int restarts = 0;\n    while(true){\n        auto now = chrono::high_resolution_clock::now();\n        double used = chrono::duration<double, std::milli>(now - start).count();\n        if(used > total_budget_ms) break;\n        double remain = total_budget_ms - used;\n        double per = max(280.0, remain / 2.0);\n        auto res = solver_once(rng, per);\n        if(res.second > bestC){\n            bestC = res.second;\n            bestGrid = move(res.first);\n        }\n        restarts++;\n        if(restarts >= 6) break;\n    }\n    if(bestGrid.empty()) bestGrid.assign(N*N, 0);\n\n    // Output\n    for(int r=0;r<N;r++){\n        string line(N,'A');\n        for(int c=0;c<N;c++){\n            line[c] = i2ch(bestGrid[r*N + c]);\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() { st = chrono::steady_clock::now(); }\n    double elapsed() const {\n        using namespace chrono;\n        return duration<double>(steady_clock::now() - st).count();\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    auto inb = [&](int i, int j){ return 0<=i && i<N && 0<=j && j<N; };\n    auto isRoad = [&](int i, int j){ return inb(i,j) && g[i][j] != '#'; };\n\n    // Compress road cells\n    int R = 0;\n    vector<int> id(N*N, -1);\n    vector<pair<int,int>> pos; pos.reserve(N*N);\n    for (int i=0;i<N;++i) for (int j=0;j<N;++j) if (isRoad(i,j)) {\n        id[i*N+j] = R++;\n        pos.emplace_back(i,j);\n    }\n    int startId = id[si*N+sj];\n    if (startId < 0) { cout << \"\\n\"; return 0; }\n\n    // Neighbors and weights\n    vector<array<int,4>> neigh(R);\n    vector<array<int,4>> moveCost(R);\n    for (int r=0;r<R;++r){\n        auto [i,j] = pos[r];\n        int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};\n        for (int d=0; d<4; ++d) {\n            int ni=i+dirs[d][0], nj=j+dirs[d][1];\n            if (isRoad(ni,nj)) {\n                int nid = id[ni*N+nj];\n                neigh[r][d] = nid;\n                moveCost[r][d] = g[ni][nj]-'0';\n            } else {\n                neigh[r][d] = -1;\n                moveCost[r][d] = 0;\n            }\n        }\n    }\n\n    // Bitset utils\n    int W = (R + 63) >> 6;\n    using BVec = vector<uint64_t>;\n    auto or_into = [&](BVec& a, const BVec& b){ for (int k=0;k<W;++k) a[k] |= b[k]; };\n    auto popcount_bits = [&](const BVec& a)->int{\n        int s=0; for (int k=0;k<W;++k) s += (int)__builtin_popcountll(a[k]); return s;\n    };\n    auto marginal_gain = [&](const BVec& v, const BVec& rem)->int{\n        int s=0; for (int k=0;k<W;++k) s += (int)__builtin_popcountll(v[k] & rem[k]); return s;\n    };\n\n    // Precompute visibility bitsets per cell\n    vector<BVec> vis(R, BVec(W, 0));\n    // Row runs and collect runs\n    vector<vector<int>> rowRuns; rowRuns.reserve(N*2);\n    for (int i=0;i<N;++i) {\n        int j=0;\n        while (j<N) {\n            while (j<N && !isRoad(i,j)) ++j;\n            if (j>=N) break;\n            int k=j;\n            vector<int> run;\n            while (k<N && isRoad(i,k)) { run.push_back(id[i*N+k]); ++k; }\n            for (int idx : run) {\n                auto &b = vis[idx];\n                for (int rid : run) b[rid>>6] |= (1ULL << (rid&63));\n            }\n            rowRuns.push_back(run);\n            j = k;\n        }\n    }\n    // Column runs\n    vector<vector<int>> colRuns; colRuns.reserve(N*2);\n    for (int j=0;j<N;++j) {\n        int i=0;\n        while (i<N) {\n            while (i<N && !isRoad(i,j)) ++i;\n            if (i>=N) break;\n            int k=i;\n            vector<int> run;\n            while (k<N && isRoad(k,j)) { run.push_back(id[k*N+j]); ++k; }\n            for (int idx : run) {\n                auto &b = vis[idx];\n                for (int rid : run) b[rid>>6] |= (1ULL << (rid&63));\n            }\n            colRuns.push_back(run);\n            i = k;\n        }\n    }\n\n    // Degree for POIs\n    vector<int> deg(R,0);\n    for (int r=0;r<R;++r) for (int d=0; d<4; ++d) if (neigh[r][d] >= 0) deg[r]++;\n\n    // Build candidate vantage points: junctions/endpoints + K reps per run\n    vector<int> cand;\n    cand.reserve(R/2);\n    for (int r=0;r<R;++r) if (deg[r] != 2) cand.push_back(r);\n    if (find(cand.begin(), cand.end(), startId) == cand.end()) cand.push_back(startId);\n\n    auto add_reps = [&](const vector<vector<int>>& runs){\n        const int K = 2;\n        for (const auto& run : runs) {\n            int m = (int)run.size();\n            if (m == 0) continue;\n            if (m <= 3) {\n                cand.insert(cand.end(), run.begin(), run.end());\n            } else {\n                for (int k=0; k<K; ++k) {\n                    int idx = (int)llround((double)(k+1) * (m+1) / (K+1)) - 1;\n                    idx = max(0, min(m-1, idx));\n                    cand.push_back(run[idx]);\n                }\n            }\n        }\n    };\n    add_reps(rowRuns);\n    add_reps(colRuns);\n\n    sort(cand.begin(), cand.end());\n    cand.erase(unique(cand.begin(), cand.end()), cand.end());\n\n    // Dijkstra utils\n    const int INF = 1e9;\n    vector<int> dist(R), prevIdArr(R,-1);\n    auto dijkstra = [&](int src, vector<int>& distOut, vector<int>* prevOut){\n        fill(distOut.begin(), distOut.end(), INF);\n        if (prevOut) fill(prevOut->begin(), prevOut->end(), -1);\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        distOut[src] = 0;\n        pq.emplace(0, src);\n        while (!pq.empty()){\n            auto [cd,u] = pq.top(); pq.pop();\n            if (cd != distOut[u]) continue;\n            for (int d=0; d<4; ++d) {\n                int v = neigh[u][d];\n                if (v < 0) continue;\n                int w = moveCost[u][d];\n                int nd = cd + w;\n                if (nd < distOut[v]) {\n                    distOut[v] = nd;\n                    if (prevOut) (*prevOut)[v] = u;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n    };\n    auto reconstruct_seq = [&](int curId, int tgtId, const vector<int>& prev)->vector<int>{\n        vector<int> seq;\n        if (curId == tgtId) return seq;\n        int x = tgtId;\n        while (x != -1 && x != curId) { seq.push_back(x); x = prev[x]; }\n        if (x != curId) { seq.clear(); return seq; }\n        reverse(seq.begin(), seq.end());\n        return seq;\n    };\n\n    // Precompute dist_to_start\n    vector<int> dist_to_start(R);\n    dijkstra(startId, dist_to_start, nullptr);\n    long long sumd = 0; int cntd = 0;\n    for (int r=0;r<R;++r) if (dist_to_start[r] < INF) { sumd += dist_to_start[r]; cntd++; }\n    double avgDistToStart = (cntd ? (double)sumd / cntd : 1.0);\n\n    // Coverage tracking\n    BVec covered(W, 0), remaining(W, 0);\n    for (int r=0;r<R;++r) remaining[r>>6] |= (1ULL << (r&63));\n    auto see_from_apply = [&](int node, int &remCount){\n        for (int k=0;k<W;++k) {\n            uint64_t bits = vis[node][k];\n            uint64_t newbits = bits & ~covered[k];\n            int add = (int)__builtin_popcountll(newbits);\n            covered[k] |= bits;\n            remaining[k] &= ~bits;\n            remCount -= add;\n        }\n    };\n\n    int remCount = R;\n    see_from_apply(startId, remCount);\n\n    string answer;\n    Timer timer;\n    double timeLimit = 2.85;\n    int cur = startId;\n\n    // Buffers\n    vector<int> dist_cur(R), prev_cur(R);\n\n    while (remCount > 0) {\n        if (timer.elapsed() > timeLimit) break;\n\n        dijkstra(cur, dist_cur, &prev_cur);\n\n        double coveredRatio = 1.0 - (double)remCount / (double)R;\n        double curToStart = (dist_to_start[cur] < INF ? dist_to_start[cur] : avgDistToStart);\n        double lambda = 0.0;\n        if (coveredRatio > 0.6) {\n            lambda = 0.04 * (curToStart / max(1.0, avgDistToStart));\n            if (coveredRatio > 0.9) lambda *= 1.5;\n        }\n\n        enum Phase { EARLY, MID, LATE };\n        Phase phase = EARLY;\n        if (remCount <= R / 4) phase = MID;\n        if (remCount <= max(32, R / 12)) phase = LATE;\n\n        int bestT = -1, bestGain = 0;\n        double bestScore = (phase==MID ? -1e300 : 1e300);\n        int bestEffInt = INT_MAX;\n\n        auto consider_list = [&](const vector<int>& list){\n            for (int t : list) {\n                int d0 = dist_cur[t];\n                if (d0 >= INF) continue;\n                int gain = marginal_gain(vis[t], remaining);\n                if (gain <= 0) continue;\n                double eff = (double)d0 + lambda * (double)dist_to_start[t];\n                if (phase == EARLY) {\n                    double beta = 1.12;\n                    double sc = eff / pow((double)gain, beta);\n                    if (sc < bestScore - 1e-12 || (abs(sc - bestScore) <= 1e-12 && gain > bestGain)) {\n                        bestScore = sc; bestT = t; bestGain = gain;\n                    }\n                } else if (phase == MID) {\n                    double alpha = 0.02;\n                    double prof = (double)gain - alpha * eff;\n                    if (bestT == -1 || prof > bestScore + 1e-12 || (abs(prof - bestScore) <= 1e-12 && eff < bestEffInt)) {\n                        bestScore = prof; bestT = t; bestEffInt = (int)eff; bestGain = gain;\n                    }\n                } else {\n                    int effi = (int)llround(eff);\n                    int minGainReq = (remCount > 8 ? 2 : 1);\n                    if (gain < minGainReq) continue;\n                    double sc = (double)effi / (double)gain;\n                    if (sc < bestScore - 1e-12 || (abs(sc - bestScore) <= 1e-12 && effi < bestEffInt)) {\n                        bestScore = sc; bestT = t; bestEffInt = effi; bestGain = gain;\n                    }\n                }\n            }\n        };\n\n        consider_list(cand);\n\n        if (bestT == -1) {\n            vector<pair<int,int>> gain_nodes; gain_nodes.reserve(min(R, 512));\n            for (int t=0; t<R; ++t) {\n                int d0 = dist_cur[t];\n                if (d0 >= INF) continue;\n                int gain = marginal_gain(vis[t], remaining);\n                if (gain > 0) gain_nodes.emplace_back(-gain, t);\n            }\n            if (!gain_nodes.empty()) {\n                int sampleK = min((int)gain_nodes.size(), 600);\n                nth_element(gain_nodes.begin(), gain_nodes.begin()+sampleK, gain_nodes.end());\n                vector<int> sample; sample.reserve(sampleK);\n                for (int i=0;i<sampleK;++i) sample.push_back(gain_nodes[i].second);\n                consider_list(sample);\n            }\n        }\n\n        if (bestT == -1) {\n            int bestT2 = -1, bestEff2 = INT_MAX, bestG2 = 0;\n            for (int t=0; t<R; ++t) {\n                int d0 = dist_cur[t];\n                if (d0 >= INF) continue;\n                int gain = marginal_gain(vis[t], remaining);\n                if (gain <= 0) continue;\n                int effi = d0 + (int)llround(lambda * (double)dist_to_start[t]);\n                if (effi < bestEff2 || (effi == bestEff2 && gain > bestG2)) {\n                    bestEff2 = effi; bestT2 = t; bestG2 = gain;\n                }\n            }\n            bestT = bestT2;\n        }\n\n        if (bestT == -1) break;\n\n        vector<int> seq = reconstruct_seq(cur, bestT, prev_cur);\n        if (seq.empty() && cur != bestT) {\n            // Should not happen\n            break;\n        }\n\n        // Walk and apply visibility; track actual last visited node\n        string mv;\n        int prevNode = cur;\n        for (int v : seq) {\n            auto [ui,uj] = pos[prevNode];\n            auto [vi,vj] = pos[v];\n            if (vi==ui-1 && vj==uj) mv.push_back('U');\n            else if (vi==ui+1 && vj==uj) mv.push_back('D');\n            else if (vi==ui && vj==uj-1) mv.push_back('L');\n            else if (vi==ui && vj==uj+1) mv.push_back('R');\n            // apply visibility at v\n            see_from_apply(v, remCount);\n            prevNode = v;\n            if (remCount == 0) break;\n        }\n        answer += mv;\n        // Critical fix: set current node to the last actually visited node (prevNode),\n        // not blindly to seq.back() which could be farther if we broke early.\n        cur = prevNode;\n\n        if (timer.elapsed() > timeLimit) break;\n    }\n\n    // Return to start\n    if (cur != startId) {\n        vector<int> dist_back(R), prev_back(R);\n        auto dijkstra2 = [&](int src){\n            fill(dist_back.begin(), dist_back.end(), INF);\n            fill(prev_back.begin(), prev_back.end(), -1);\n            using P = pair<int,int>;\n            priority_queue<P, vector<P>, greater<P>> pq;\n            dist_back[src] = 0; pq.emplace(0, src);\n            while (!pq.empty()) {\n                auto [cd,u] = pq.top(); pq.pop();\n                if (cd != dist_back[u]) continue;\n                for (int d=0; d<4; ++d) {\n                    int v = neigh[u][d];\n                    if (v < 0) continue;\n                    int w = moveCost[u][d];\n                    int nd = cd + w;\n                    if (nd < dist_back[v]) {\n                        dist_back[v] = nd; prev_back[v] = u;\n                        pq.emplace(nd, v);\n                    }\n                }\n            }\n        };\n        dijkstra2(cur);\n        // reconstruct\n        vector<int> seq;\n        if (dist_back[startId] < INF) {\n            int x = startId;\n            while (x != -1 && x != cur) { seq.push_back(x); x = prev_back[x]; }\n            if (x == cur) reverse(seq.begin(), seq.end());\n            else seq.clear();\n        }\n        // translate to moves\n        string mv;\n        int prevNode = cur;\n        for (int v : seq) {\n            auto [ui,uj] = pos[prevNode];\n            auto [vi,vj] = pos[v];\n            if (vi==ui-1 && vj==uj) mv.push_back('U');\n            else if (vi==ui+1 && vj==uj) mv.push_back('D');\n            else if (vi==ui && vj==uj-1) mv.push_back('L');\n            else if (vi==ui && vj==uj+1) mv.push_back('R');\n            prevNode = v;\n        }\n        answer += mv;\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct RNG {\n    uint64_t x=88172645463393265ull;\n    uint32_t next() { x ^= x<<7; x ^= x>>9; return uint32_t(x); }\n    double drand() { return (next()>>8) * (1.0/16777216.0); }\n} rng;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,K,R;\n    if(!(cin>>N>>M>>K>>R)) return 0;\n    vector<vector<int>> d(N, vector<int>(K));\n    for(int i=0;i<N;i++) for(int k=0;k<K;k++) cin>>d[i][k];\n    vector<vector<int>> g(N);\n    vector<int> indeg(N,0);\n    for(int i=0;i<R;i++){\n        int u,v; cin>>u>>v; --u;--v;\n        g[u].push_back(v);\n        indeg[v]++;\n    }\n    // Topological order\n    vector<int> topo;\n    {\n        vector<int> indeg2 = indeg;\n        queue<int> q;\n        for(int i=0;i<N;i++) if(indeg2[i]==0) q.push(i);\n        while(!q.empty()){\n            int u=q.front(); q.pop();\n            topo.push_back(u);\n            for(int v: g[u]) if(--indeg2[v]==0) q.push(v);\n        }\n        if((int)topo.size()!=N){\n            topo.clear();\n            for(int i=0;i<N;i++) topo.push_back(i);\n        }\n    }\n    // Height (longest path to sink)\n    vector<int> height(N,0);\n    for(int idx=N-1; idx>=0; --idx){\n        int u=topo[idx];\n        int best=0;\n        for(int v: g[u]) best = max(best, 1 + height[v]);\n        height[u]=best;\n    }\n    // Out-degree for priority\n    vector<int> outdeg(N,0);\n    for(int u=0;u<N;u++) outdeg[u] = (int)g[u].size();\n\n    // Priority score: height + lambda*outdeg\n    const double lambda = 0.15;\n    vector<double> prio(N);\n    for(int i=0;i<N;i++) prio[i] = height[i] + lambda * outdeg[i];\n\n    // Estimates\n    vector<vector<double>> est(M, vector<double>(K, 10.0));\n    vector<vector<int>> lb(M, vector<int>(K, 0));\n\n    // States\n    vector<int> tstat(N,0); // 0 not started, 1 started, 2 done\n    vector<int> started_by(N,-1), start_day(N,-1);\n    vector<int> mtask(M,-1);\n    vector<int> cur_indeg = indeg;\n    vector<char> ready_flag(N,0);\n    for(int i=0;i<N;i++) if(cur_indeg[i]==0) ready_flag[i]=1;\n\n    auto predicted_w = [&](int task, int mem)->double{\n        double w=0.0;\n        for(int k=0;k<K;k++){\n            double df = (double)d[task][k] - est[mem][k];\n            if(df>0) w += df;\n        }\n        return w;\n    };\n    auto predicted_time = [&](int task, int mem)->double{\n        double w = predicted_w(task, mem);\n        if(w<1.0) return 1.0;\n        return max(1.0, w);\n    };\n\n    auto assign_task = [&](int mem, int task, int day){\n        mtask[mem]=task;\n        tstat[task]=1;\n        started_by[task]=mem;\n        start_day[task]=day;\n        ready_flag[task]=0;\n    };\n\n    int day=0;\n    const double beta = 0.22;\n    const double eps = 0.05;\n\n    while(true){\n        day++;\n\n        // Idle members\n        vector<int> idle;\n        idle.reserve(M);\n        for(int j=0;j<M;j++) if(mtask[j]==-1) idle.push_back(j);\n\n        // Ready tasks\n        vector<int> rlist;\n        rlist.reserve(512);\n        for(int i=0;i<N;i++){\n            if(ready_flag[i] && tstat[i]==0) rlist.push_back(i);\n        }\n        // Cap by priority (height+outdeg)\n        int cap = 320;\n        if((int)rlist.size()>cap){\n            nth_element(rlist.begin(), rlist.begin()+cap, rlist.end(), [&](int a,int b){\n                return prio[a] > prio[b];\n            });\n            rlist.resize(cap);\n        }\n\n        vector<pair<int,int>> out;\n        out.reserve(idle.size());\n\n        if(!idle.empty() && !rlist.empty()){\n            size_t U = idle.size(), L = rlist.size();\n            vector<char> taskTaken(L, 0);\n            vector<char> memTaken(U, 0);\n\n            // Precompute predicted w for all pairs in candidate set\n            vector<vector<double>> pw(U, vector<double>(L, 0.0));\n            for(size_t ui=0; ui<U; ++ui){\n                int mem = idle[ui];\n                for(size_t li=0; li<L; ++li){\n                    int t = rlist[li];\n                    pw[ui][li] = predicted_w(t, mem);\n                }\n            }\n\n            // Phase 1: perfect-fit assignments (w<1)\n            for(size_t ui=0; ui<U; ++ui){\n                if(memTaken[ui]) continue;\n                int mem = idle[ui];\n                int bestIdx=-1;\n                double bestSc=-1e100;\n                for(size_t li=0; li<L; ++li){\n                    if(taskTaken[li]) continue;\n                    if(pw[ui][li] < 1.0 - 1e-9){\n                        double sc = prio[rlist[li]];\n                        if(sc > bestSc){\n                            bestSc = sc;\n                            bestIdx = (int)li;\n                        }\n                    }\n                }\n                if(bestIdx!=-1){\n                    taskTaken[bestIdx]=1;\n                    memTaken[ui]=1;\n                    out.emplace_back(mem, rlist[bestIdx]);\n                }\n            }\n\n            // Phase 2: near-perfect tasks (1 <= w <= 3), choose member with minimal predicted w\n            // Build for each task best member if both free\n            vector<int> bestMemForTask(L, -1);\n            for(size_t li=0; li<L; ++li){\n                if(taskTaken[li]) continue;\n                int t = rlist[li];\n                double bestW = 1e100;\n                int bestUI = -1;\n                for(size_t ui=0; ui<U; ++ui){\n                    if(memTaken[ui]) continue;\n                    double w = pw[ui][li];\n                    if(w >= 1.0 - 1e-9 && w <= 3.0 + 1e-9){\n                        double tie = -0.001 * prio[t]; // prefer higher prio on tie\n                        if(w + tie < bestW){\n                            bestW = w + tie;\n                            bestUI = (int)ui;\n                        }\n                    }\n                }\n                bestMemForTask[li] = bestUI;\n            }\n            // Assign these tasks by descending priority to reduce conflicts\n            vector<int> order(L);\n            iota(order.begin(), order.end(), 0);\n            sort(order.begin(), order.end(), [&](int a,int b){\n                return prio[rlist[a]] > prio[rlist[b]];\n            });\n            for(int li: order){\n                if(taskTaken[li]) continue;\n                int ui = bestMemForTask[li];\n                if(ui>=0 && !memTaken[ui]){\n                    taskTaken[li]=1;\n                    memTaken[ui]=1;\n                    out.emplace_back(idle[ui], rlist[li]);\n                }\n            }\n\n            // Phase 3: remaining greedy by predicted time - beta*prio\n            for(size_t ui=0; ui<U; ++ui){\n                if(memTaken[ui]) continue;\n                int mem = idle[ui];\n                bool explore = (rng.drand() < eps);\n                int bestIdx=-1;\n                double bestScore = 1e100;\n                if(explore){\n                    // pick near-boundary with smallest predicted w\n                    for(size_t li=0; li<L; ++li){\n                        if(taskTaken[li]) continue;\n                        double w = pw[ui][li];\n                        // Encourage exploring small w\n                        double score = fabs(w-1.8) - 0.05*prio[rlist[li]];\n                        if(score < bestScore){\n                            bestScore = score;\n                            bestIdx = (int)li;\n                        }\n                    }\n                }else{\n                    for(size_t li=0; li<L; ++li){\n                        if(taskTaken[li]) continue;\n                        int t = rlist[li];\n                        double tp = (pw[ui][li] < 1.0 ? 1.0 : pw[ui][li]);\n                        // Small tie-break on priority\n                        double score = tp - beta * prio[t];\n                        if(score < bestScore){\n                            bestScore = score;\n                            bestIdx = (int)li;\n                        }\n                    }\n                }\n                if(bestIdx!=-1){\n                    taskTaken[bestIdx]=1;\n                    out.emplace_back(mem, rlist[bestIdx]);\n                }\n            }\n        }\n\n        // Output\n        cout<<out.size();\n        for(auto &p: out){\n            cout<<\" \"<<(p.first+1)<<\" \"<<(p.second+1);\n            assign_task(p.first, p.second, day);\n        }\n        cout<<\"\\n\";\n        cout.flush();\n\n        // Feedback\n        int nfin;\n        if(!(cin>>nfin)) return 0;\n        if(nfin==-1) return 0;\n        vector<int> fins(nfin);\n        for(int i=0;i<nfin;i++){ cin>>fins[i]; fins[i]--; }\n\n        // Process finishes\n        for(int mem: fins){\n            int task = mtask[mem];\n            if(task<0) continue;\n            int dur = day - start_day[task] + 1;\n\n            if(dur<=1){\n                for(int k=0;k<K;k++){\n                    lb[mem][k] = max(lb[mem][k], d[task][k]);\n                    est[mem][k] = max(est[mem][k], (double)d[task][k]);\n                }\n            }else{\n                // Compute deficits\n                vector<double> def(K, 0.0);\n                double W=0.0;\n                for(int k=0;k<K;k++){\n                    double df = (double)d[task][k] - est[mem][k];\n                    if(df>0){ def[k]=df; W+=df; }\n                }\n                double high = dur + 3.0;\n                if(W > high + 1e-9){\n                    double delta = W - high;\n                    // adaptive learning rate\n                    double lr = min(0.6, 0.2 + 0.02 * max(0.0, W - high));\n                    double step = min(delta, 8.0) * lr;\n                    double sumdef = W;\n                    if(sumdef>1e-9){\n                        for(int k=0;k<K;k++){\n                            if(def[k]>1e-12){\n                                double inc = step * (def[k]/sumdef);\n                                double capInc = max(0.0, (double)d[task][k] - est[mem][k]);\n                                if(inc > capInc) inc = capInc;\n                                est[mem][k] += inc;\n                            }\n                            if(est[mem][k] < lb[mem][k]) est[mem][k] = lb[mem][k];\n                        }\n                    }else{\n                        for(int k=0;k<K;k++){\n                            if(est[mem][k] < lb[mem][k]) est[mem][k] = lb[mem][k];\n                        }\n                    }\n                }else{\n                    // Enforce lb only\n                    for(int k=0;k<K;k++){\n                        if(est[mem][k] < lb[mem][k]) est[mem][k] = lb[mem][k];\n                    }\n                }\n            }\n\n            // Mark done and unlock successors\n            mtask[mem] = -1;\n            tstat[task]=2;\n            for(int v: g[task]){\n                if(--cur_indeg[v]==0 && tstat[v]==0){\n                    ready_flag[v]=1;\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int ax, ay, cx, cy, idx;\n    double score;\n};\n\nstatic inline int manh(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int DEPX=400, DEPY=400;\n    vector<Order> all;\n    all.reserve(1000);\n    for(int i=0;i<1000;i++){\n        int a,b,c,d;\n        if(!(cin>>a>>b>>c>>d)) return 0;\n        Order o; o.ax=a;o.ay=b;o.cx=c;o.cy=d;o.idx=i+1;o.score=0;\n        all.push_back(o);\n    }\n    if(all.size()!=1000){\n        // In case of partial input, just output trivial solution\n        cout<<\"0\\n1 400 400\\n\";\n        return 0;\n    }\n\n    // Compute scores for selection\n    const double alpha=1.0, beta=1.0, gamma=0.7; // weights for depot->pickup, pickup->drop, drop->depot\n    const double angle_penalty = 5.0; // mild penalty on pickup-drop direction difference\n    for(auto &o: all){\n        int da = manh(DEPX,DEPY,o.ax,o.ay);\n        int ac = manh(o.ax,o.ay,o.cx,o.cy);\n        int cd = manh(o.cx,o.cy,DEPX,DEPY);\n        double angp = atan2((double)o.ay - DEPY, (double)o.ax - DEPX);\n        double angd = atan2((double)o.cy - DEPY, (double)o.cx - DEPX);\n        double dang = fabs(angp - angd);\n        while(dang > M_PI) dang = fabs(dang - 2*M_PI);\n        o.score = alpha*da + beta*ac + gamma*cd + angle_penalty * dang;\n    }\n    sort(all.begin(), all.end(), [](const Order& A, const Order& B){\n        if (A.score != B.score) return A.score < B.score;\n        return A.idx < B.idx;\n    });\n    int m = 50;\n    vector<Order> sel(all.begin(), all.begin()+m);\n\n    // Greedy route construction with precedence\n    struct Node { int x,y; int ordIdx; bool isPickup; };\n    unordered_map<int, Order> omap;\n    omap.reserve(m*2);\n    for (auto &o: sel) omap[o.idx]=o;\n\n    vector<int> unpicked, carrying;\n    unpicked.reserve(m);\n    for (auto &o: sel) unpicked.push_back(o.idx);\n    vector<Node> route;\n    route.push_back({DEPX,DEPY,-1,false}); // start\n\n    int curx=DEPX, cury=DEPY;\n    auto getPick = [&](int id)->pair<int,int>{\n        auto &o = omap[id]; return {o.ax,o.ay};\n    };\n    auto getDrop = [&](int id)->pair<int,int>{\n        auto &o = omap[id]; return {o.cx,o.cy};\n    };\n\n    for(int step=0; step<2*m; ++step){\n        // find best pickup\n        int bestPid=-1; int bestPdist=INT_MAX; int px=0,py=0;\n        for(int id: unpicked){\n            auto p = getPick(id);\n            int d = manh(curx,cury,p.first,p.second);\n            if(d < bestPdist){\n                bestPdist = d; bestPid=id; px=p.first; py=p.second;\n            }\n        }\n        // find best drop\n        int bestDid=-1; int bestDdist=INT_MAX; int dx=0,dy=0;\n        for(int id: carrying){\n            auto p = getDrop(id);\n            int d = manh(curx,cury,p.first,p.second);\n            if(d < bestDdist){\n                bestDdist = d; bestDid=id; dx=p.first; dy=p.second;\n            }\n        }\n        // choose\n        bool doPickup = false;\n        if(bestPid==-1 && bestDid!=-1) doPickup=false;\n        else if(bestPid!=-1 && bestDid==-1) doPickup=true;\n        else {\n            // bias against picking when carrying many\n            double bias = 1.05 + 0.02 * (int)carrying.size();\n            doPickup = (bestPdist * bias <= bestDdist + 1e-9);\n        }\n        if(doPickup){\n            // move to pickup\n            route.push_back({px,py,bestPid,true});\n            curx=px; cury=py;\n            auto it = find(unpicked.begin(), unpicked.end(), bestPid);\n            if(it!=unpicked.end()) unpicked.erase(it);\n            carrying.push_back(bestPid);\n        }else{\n            // move to drop\n            route.push_back({dx,dy,bestDid,false});\n            curx=dx; cury=dy;\n            auto it = find(carrying.begin(), carrying.end(), bestDid);\n            if(it!=carrying.end()) carrying.erase(it);\n        }\n    }\n\n    // If any remain (safety), finish remaining drops then return\n    while(!carrying.empty()){\n        // go to nearest remaining drop\n        int bestDid=-1, bestDdist=INT_MAX, dx=0, dy=0;\n        for(int id: carrying){\n            auto p = getDrop(id);\n            int d = manh(curx, cury, p.first, p.second);\n            if(d < bestDdist){ bestDdist=d; bestDid=id; dx=p.first; dy=p.second; }\n        }\n        route.push_back({dx,dy,bestDid,false});\n        curx=dx; cury=dy;\n        auto it = find(carrying.begin(), carrying.end(), bestDid);\n        if(it!=carrying.end()) carrying.erase(it);\n    }\n    // If some pickups are left (shouldn't happen), pick and drop them immediately\n    while(!unpicked.empty()){\n        int id = unpicked.back(); unpicked.pop_back();\n        auto p = getPick(id);\n        if(p.first!=curx || p.second!=cury){\n            route.push_back({p.first,p.second,id,true});\n            curx=p.first; cury=p.second;\n        }else{\n            route.push_back({p.first,p.second,id,true});\n        }\n        auto q = getDrop(id);\n        route.push_back({q.first,q.second,id,false});\n        curx=q.first; cury=q.second;\n    }\n\n    route.push_back({DEPX,DEPY,-1,false});\n\n    auto routeDist = [&](const vector<Node>& R)->long long{\n        long long t=0;\n        for(size_t i=0;i+1<R.size();++i) t += manh(R[i].x,R[i].y,R[i+1].x,R[i+1].y);\n        return t;\n    };\n\n    // Precedence check: ensure for each order pickup index < drop index\n    auto violates = [&](const vector<Node>& R)->bool{\n        vector<int> pidx(1001,-1), didx(1001,-1);\n        for(int k=0;k<(int)R.size();++k){\n            int id=R[k].ordIdx;\n            if(id==-1) continue;\n            if(R[k].isPickup){ if(pidx[id]==-1) pidx[id]=k; }\n            else { if(didx[id]==-1) didx[id]=k; }\n        }\n        for (auto &o: sel){\n            int pid = pidx[o.idx];\n            int did = didx[o.idx];\n            if(pid==-1 || did==-1) continue;\n            if(pid >= did) return true;\n        }\n        return false;\n    };\n\n    // Local search: 2-opt with precedence\n    auto try_two_opt = [&](vector<Node>& R){\n        bool improved=true;\n        int iter=0;\n        while(improved && iter<200){\n            improved=false; iter++;\n            long long bestGain=0;\n            int bi=-1,bj=-1;\n            for(int i=1;i+2<(int)R.size();++i){\n                for(int j=i+1;j+1<(int)R.size();++j){\n                    long long d0 = manh(R[i-1].x,R[i-1].y,R[i].x,R[i].y)\n                                  + manh(R[j].x,R[j].y,R[j+1].x,R[j+1].y);\n                    long long d1 = manh(R[i-1].x,R[i-1].y,R[j].x,R[j].y)\n                                  + manh(R[i].x,R[i].y,R[j+1].x,R[j+1].y);\n                    long long gain = d0 - d1;\n                    if(gain > bestGain){\n                        reverse(R.begin()+i, R.begin()+j+1);\n                        if(!violates(R)){\n                            bestGain = gain;\n                            bi=i; bj=j;\n                        }\n                        reverse(R.begin()+i, R.begin()+j+1);\n                    }\n                }\n            }\n            if(bestGain > 0 && bi!=-1){\n                reverse(R.begin()+bi, R.begin()+bj+1);\n                improved=true;\n            }\n        }\n    };\n\n    try_two_opt(route);\n\n    // Paired relocate: move pickup and drop of an order together\n    auto index_of = [&](const vector<Node>& R, int id, bool pickup)->int{\n        for(int i=0;i<(int)R.size();++i){\n            if(R[i].ordIdx==id && R[i].isPickup==pickup) return i;\n        }\n        return -1;\n    };\n    auto relocate_pair = [&](vector<Node>& R){\n        bool improved=true;\n        int attempts=0;\n        while(improved && attempts<50){\n            improved=false; attempts++;\n            long long curL = routeDist(R);\n            bool applied=false;\n            for(auto &o: sel){\n                int pid = index_of(R,o.idx,true);\n                int did = index_of(R,o.idx,false);\n                if(pid==-1 || did==-1 || pid>=did) continue;\n                vector<int> candP;\n                for(int t=max(1,pid-3); t<=min((int)R.size()-2,pid+3); ++t) candP.push_back(t);\n                for(int p: candP){\n                    if(p==pid) continue;\n                    for(int q=max(p+1, did-3); q<=min((int)R.size()-1, did+3); ++q){\n                        vector<Node> T = R;\n                        Node P = T[pid];\n                        Node D = T[did];\n                        if(pid<did){\n                            T.erase(T.begin()+did);\n                            T.erase(T.begin()+pid);\n                        }else{\n                            T.erase(T.begin()+pid);\n                            T.erase(T.begin()+did);\n                        }\n                        T.insert(T.begin()+p, P);\n                        int qpos = q;\n                        if(p<=qpos) qpos++;\n                        qpos = max(qpos, p+1);\n                        qpos = min(qpos, (int)T.size()-1);\n                        T.insert(T.begin()+qpos, D);\n                        if(violates(T)) continue;\n                        long long newL = routeDist(T);\n                        if(newL + 0 < curL){\n                            R.swap(T);\n                            improved=true;\n                            applied=true;\n                            break;\n                        }\n                    }\n                    if(applied) break;\n                }\n                if(applied) break;\n            }\n        }\n    };\n\n    relocate_pair(route);\n    try_two_opt(route);\n\n    // Output\n    cout<<m;\n    for(auto &o: sel) cout<<\" \"<<o.idx;\n    cout<<\"\\n\";\n    cout<<route.size();\n    for(auto &nd: route){\n        cout<<\" \"<<nd.x<<\" \"<<nd.y;\n    }\n    cout<<\"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    int comps;\n    DSU(int n=0): n(n), p(n), r(n,0), comps(n) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool same(int a,int b){ return find(a)==find(b); }\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        comps--;\n        return true;\n    }\n};\n\nstruct Edge {\n    int idx;\n    int u,v;\n    int d; // prior rounded Euclidean 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    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++){\n        if(!(cin>>x[i]>>y[i])) return 0;\n    }\n    vector<int> U(M), V(M);\n    for(int i=0;i<M;i++){\n        cin>>U[i]>>V[i];\n    }\n\n    auto rd = [&](int i)->int{\n        long long dx = x[U[i]] - x[V[i]];\n        long long dy = y[U[i]] - y[V[i]];\n        double dist = sqrt((double)(dx*dx + dy*dy));\n        return (int)llround(dist);\n    };\n\n    vector<Edge> edges(M);\n    for(int i=0;i<M;i++){\n        edges[i] = {i, U[i], V[i], rd(i)};\n    }\n\n    // Build 5 disjoint MST layers using d as weight\n    vector<int> layer(M, -1);\n    for(int lay=0; lay<5; lay++){\n        vector<int> avail;\n        avail.reserve(M);\n        for(int ei=0; ei<M; ei++){\n            if(layer[ei]==-1) avail.push_back(ei);\n        }\n        sort(avail.begin(), avail.end(), [&](int a, int b){\n            if(edges[a].d != edges[b].d) return edges[a].d < edges[b].d;\n            if(edges[a].u != edges[b].u) return edges[a].u < edges[b].u;\n            return edges[a].v < edges[b].v;\n        });\n        DSU dsu(N);\n        int taken = 0;\n        for(int eid: avail){\n            int u = edges[eid].u, v = edges[eid].v;\n            if(!dsu.same(u,v)){\n                dsu.unite(u,v);\n                layer[eid] = lay;\n                taken++;\n                if(taken == N-1) break;\n            }\n        }\n        // As per generation, this will assign exactly N-1 edges per layer\n    }\n\n    // Online phase with guaranteed connectivity via backup layer\n    DSU cur(N);\n\n    int backup_layer = 0; // rely on the base MST layer by d as guaranteed backbone\n\n    // Strict acceptance multipliers for non-backup layers (prefer very good edges only)\n    array<double,5> beta;\n    beta[0]=1.25; beta[1]=1.20; beta[2]=1.15; beta[3]=1.10; beta[4]=1.05;\n\n    for(int i=0;i<M;i++){\n        int l_i;\n        if(!(cin>>l_i)) return 0;\n\n        int u = U[i], v = V[i];\n        int d = edges[i].d;\n        int lay = layer[i];\n        if(lay < 0 || lay > 4) lay = 4; // fallback, shouldn't happen\n\n        bool accept = false;\n        if(cur.same(u,v)){\n            accept = false;\n        }else{\n            if(lay == backup_layer){\n                // Unconditional acceptance for backup layer cross edges ensures connectivity\n                accept = true;\n            }else{\n                // Only accept clearly cheap edges from other layers\n                double mul = beta[lay];\n                if((double)l_i <= mul * (double)d) accept = true;\n            }\n        }\n\n        if(accept){\n            if(!cur.same(u,v)) cur.unite(u,v);\n            cout << 1 << '\\n';\n        }else{\n            cout << 0 << '\\n';\n        }\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int H = 30, W = 30;\n\nstruct Pet {\n    int x, y;\n    int t;\n};\nstruct Human {\n    int x, y;\n    int wallRow;\n    int standRow;\n    int L, R;\n    int dir; // +1 right, -1 left\n    int targetCol;\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<Pet> pets(N);\n    for (int i = 0; i < N; i++) {\n        int px, py, pt; cin >> px >> py >> pt;\n        pets[i] = {px, py, pt};\n    }\n    int M; cin >> M;\n    vector<Human> humans(M);\n    for (int i = 0; i < M; i++) {\n        int hx, hy; cin >> hx >> hy;\n        humans[i].x = hx; humans[i].y = hy;\n    }\n\n    auto inb = [&](int x,int y){ return 1<=x && x<=H && 1<=y && y<=W; };\n\n    vector<vector<bool>> blocked(H+1, vector<bool>(W+1,false));\n    vector<vector<int>> petCnt(H+1, vector<int>(W+1,0));\n    for (auto &p: pets) petCnt[p.x][p.y]++;\n\n    // Assign wall rows and standing rows\n    vector<int> wallRowsBase = {6,12,18,24};\n    for (int i = 0; i < M; i++) {\n        int wr = wallRowsBase[i % (int)wallRowsBase.size()];\n        humans[i].wallRow = wr;\n        int stand = wr - 1;\n        if (stand < 1) stand = wr + 1;\n        humans[i].standRow = stand;\n    }\n    // Assign column segments\n    for (int i = 0; i < M; i++) {\n        int L = (long long)i * W / M + 1;\n        int R = (long long)(i+1) * W / M;\n        humans[i].L = L; humans[i].R = R;\n        int hy = humans[i].y;\n        humans[i].targetCol = max(L, min(hy, R));\n        // Choose dir toward nearest boundary for quicker coverage\n        if (abs(hy - L) <= abs(hy - R)) humans[i].dir = -1; else humans[i].dir = +1;\n        if (humans[i].targetCol == L) humans[i].dir = +1;\n        if (humans[i].targetCol == R) humans[i].dir = -1;\n    }\n\n    auto safe_to_block = [&](int tx,int ty, const vector<Human>& hs)->bool{\n        if (!inb(tx,ty)) return false;\n        if (blocked[tx][ty]) return false;\n        if (petCnt[tx][ty] > 0) return false;\n        // cannot choose a square that contains humans at the start of the turn\n        for (const auto& h: hs) if (h.x==tx && h.y==ty) return false;\n        // cannot choose a square whose adjacent square contains a pet\n        static const int dx[4]={-1,1,0,0};\n        static const int dy[4]={0,0,-1,1};\n        for (int k=0;k<4;k++){\n            int nx=tx+dx[k], ny=ty+dy[k];\n            if (inb(nx,ny) && petCnt[nx][ny]>0) return false;\n        }\n        return true;\n    };\n\n    for (int turn = 0; turn < 300; turn++) {\n        // Phase 1: propose actions\n        string actions(M, '.');\n\n        for (int i = 0; i < M; i++) {\n            auto &h = humans[i];\n            int wr = h.wallRow;\n            int sr = h.standRow;\n\n            // Move vertically to standing row\n            if (h.x != sr) {\n                if (h.x > sr) {\n                    if (inb(h.x-1,h.y) && !blocked[h.x-1][h.y]) actions[i]='U';\n                    else actions[i]='.';\n                } else {\n                    if (inb(h.x+1,h.y) && !blocked[h.x+1][h.y]) actions[i]='D';\n                    else actions[i]='.';\n                }\n                continue;\n            }\n            // Move horizontally into assigned segment if outside\n            if (h.y < h.L) {\n                if (inb(h.x,h.y+1) && !blocked[h.x][h.y+1]) actions[i]='R';\n                else actions[i]='.';\n                continue;\n            }\n            if (h.y > h.R) {\n                if (inb(h.x,h.y-1) && !blocked[h.x][h.y-1]) actions[i]='L';\n                else actions[i]='.';\n                continue;\n            }\n            // Within segment: try to place block into wall row at current column\n            int tx = wr, ty = h.y;\n            char place = (sr < wr ? 'd' : 'u');\n            if (safe_to_block(tx,ty, humans)) {\n                actions[i] = place;\n                continue;\n            }\n            // Otherwise sweep horizontally\n            if (h.dir > 0) {\n                if (h.y < h.R && !blocked[h.x][h.y+1]) actions[i]='R';\n                else {\n                    h.dir = -1;\n                    if (h.y > h.L && !blocked[h.x][h.y-1]) actions[i]='L';\n                    else actions[i]='.';\n                }\n            } else {\n                if (h.y > h.L && !blocked[h.x][h.y-1]) actions[i]='L';\n                else {\n                    h.dir = +1;\n                    if (h.y < h.R && !blocked[h.x][h.y+1]) actions[i]='R';\n                    else actions[i]='.';\n                }\n            }\n        }\n\n        // Phase 2: prevent move-into-newly-blocked conflicts\n        // Compute set of cells that will be blocked by any human this turn\n        vector<vector<bool>> willBlock(H+1, vector<bool>(W+1,false));\n        for (int i = 0; i < M; i++) {\n            if (actions[i]=='.' || actions[i]=='U' || actions[i]=='D' || actions[i]=='L' || actions[i]=='R') continue;\n            int tx = humans[i].x, ty = humans[i].y;\n            if (actions[i]=='u') tx--;\n            else if (actions[i]=='d') tx++;\n            else if (actions[i]=='l') ty--;\n            else if (actions[i]=='r') ty++;\n            if (inb(tx,ty)) {\n                // It might be illegal per rules, but we already checked safe_to_block. Mark it here anyway.\n                willBlock[tx][ty] = true;\n            }\n        }\n        // Cancel moves that would step into a to-be-blocked cell\n        for (int i = 0; i < M; i++) {\n            char c = actions[i];\n            if (c=='U' || c=='D' || c=='L' || c=='R') {\n                int nx = humans[i].x, ny = humans[i].y;\n                if (c=='U') nx--;\n                else if (c=='D') nx++;\n                else if (c=='L') ny--;\n                else if (c=='R') ny++;\n                if (inb(nx,ny) && willBlock[nx][ny]) {\n                    actions[i] = '.'; // stay to avoid illegal move\n                }\n            }\n        }\n\n        // Output actions\n        cout << actions << \"\\n\";\n        cout.flush();\n\n        // Apply blocks locally\n        for (int i = 0; i < M; i++) {\n            char c = actions[i];\n            if (c=='.' || c=='U' || c=='D' || c=='L' || c=='R') continue;\n            int tx = humans[i].x, ty = humans[i].y;\n            if (c=='u') tx--;\n            else if (c=='d') tx++;\n            else if (c=='l') ty--;\n            else if (c=='r') ty++;\n            if (inb(tx,ty)) blocked[tx][ty] = true;\n        }\n        // Apply moves locally (avoid stepping into any blocked cell)\n        for (int i = 0; i < M; i++) {\n            char c = actions[i];\n            int nx = humans[i].x, ny = humans[i].y;\n            if (c=='U') nx--;\n            else if (c=='D') nx++;\n            else if (c=='L') ny--;\n            else if (c=='R') ny++;\n            if (inb(nx,ny) && !blocked[nx][ny]) {\n                humans[i].x = nx; humans[i].y = ny;\n            }\n        }\n\n        // Read pets moves and update positions\n        vector<string> pm(N);\n        for (int i = 0; i < N; i++) cin >> pm[i];\n        for (int x=1;x<=H;x++) for (int y=1;y<=W;y++) petCnt[x][y]=0;\n        for (int i = 0; i < N; i++) {\n            for (char c: pm[i]) {\n                int nx = pets[i].x, ny = pets[i].y;\n                if (c=='U') nx--;\n                else if (c=='D') nx++;\n                else if (c=='L') ny--;\n                else if (c=='R') ny++;\n                if (inb(nx,ny)) { pets[i].x=nx; pets[i].y=ny; }\n            }\n            petCnt[pets[i].x][pets[i].y] ++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si,sj,ti,tj;\n    double p;\n    if(!(cin>>si>>sj>>ti>>tj>>p)) return 0;\n    vector<string> h(20), v(19);\n    for(int i=0;i<20;i++){\n        cin>>h[i];\n    }\n    for(int i=0;i<19;i++){\n        cin>>v[i];\n    }\n    auto inb = [](int x,int y){ return 0<=x && x<20 && 0<=y && y<20; };\n    auto can_move = [&](int x,int y,int nx,int ny)->bool{\n        if(!inb(nx,ny)) return false;\n        if(nx==x && ny==y+1){\n            return h[x][y]=='0';\n        }\n        if(nx==x && ny==y-1){\n            return h[x][y-1]=='0';\n        }\n        if(nx==x+1 && ny==y){\n            return v[x][y]=='0';\n        }\n        if(nx==x-1 && ny==y){\n            return v[x-1][y]=='0';\n        }\n        return false;\n    };\n    // BFS shortest path\n    const int N=20;\n    vector<vector<int>> dist(N, vector<int>(N, INT_MAX));\n    vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj]=0;\n    q.push({si,sj});\n    int dx[4]={-1,1,0,0};\n    int dy[4]={0,0,-1,1};\n    char dc[4] = {'U','D','L','R'};\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        if(x==ti && y==tj) break;\n        for(int d=0;d<4;d++){\n            int nx=x+dx[d], ny=y+dy[d];\n            if(!inb(nx,ny)) continue;\n            if(!can_move(x,y,nx,ny)) continue;\n            if(dist[nx][ny] > dist[x][y] + 1){\n                dist[nx][ny] = dist[x][y] + 1;\n                par[nx][ny] = {x,y};\n                q.push({nx,ny});\n            }\n        }\n    }\n    // Reconstruct path\n    vector<pair<int,int>> path;\n    int cx=ti, cy=tj;\n    while(!(cx==si && cy==sj) && cx!=-1){\n        path.push_back({cx,cy});\n        auto pr = par[cx][cy];\n        cx = pr.first; cy = pr.second;\n    }\n    path.push_back({si,sj});\n    reverse(path.begin(), path.end());\n    // If BFS somehow fails (shouldn't), fallback to simple greedy without walls\n    vector<char> dirs;\n    if((int)path.size()>=2){\n        for(size_t k=1;k<path.size();k++){\n            int x0=path[k-1].first, y0=path[k-1].second;\n            int x1=path[k].first, y1=path[k].second;\n            if(x1==x0-1 && y1==y0) dirs.push_back('U');\n            else if(x1==x0+1 && y1==y0) dirs.push_back('D');\n            else if(x1==x0 && y1==y0-1) dirs.push_back('L');\n            else if(x1==x0 && y1==y0+1) dirs.push_back('R');\n        }\n    }else{\n        // fallback: straight moves\n        int x=si,y=sj;\n        while(x>ti) { dirs.push_back('U'); x--; }\n        while(x<ti) { dirs.push_back('D'); x++; }\n        while(y>tj) { dirs.push_back('L'); y--; }\n        while(y<tj) { dirs.push_back('R'); y++; }\n    }\n    int D = (int)dirs.size();\n    if(D==0){\n        cout << \"\\n\";\n        return 0;\n    }\n    // Choose repetition factor r\n    // target epsilon for failing to advance on a block: p^r <= 0.02\n    auto safe_ceil = [](double x)->int{\n        int k = (int)ceil(x - 1e-12);\n        return k;\n    };\n    int r_cap;\n    if(p>=1.0-1e-12) r_cap = 8;\n    else {\n        double num = log(0.02);\n        double den = log(p);\n        int rc = safe_ceil(num/den); // since den<0, this is positive\n        r_cap = max(2, min(8, rc));\n    }\n    int r_max = max(1, 200 / max(1, D));\n    int r = min(r_max, r_cap);\n    // Build output\n    string out;\n    out.reserve(200);\n    auto append_repeats = [&](const vector<char>& P, int rep){\n        for(char c: P){\n            for(int k=0;k<rep;k++){\n                if((int)out.size()<200) out.push_back(c);\n            }\n        }\n    };\n    append_repeats(dirs, r);\n    // Add extra full-path copies (unrepeated) to fill up to near 200\n    while((int)out.size() + D <= 200){\n        for(char c: dirs){\n            if((int)out.size()<200) out.push_back(c);\n        }\n    }\n    // If still too short and we have a bit of space, add prefix of path\n    int rem = 200 - (int)out.size();\n    for(int i=0;i<rem && i<D;i++) out.push_back(dirs[i]);\n\n    cout << out << \"\\n\";\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int H = 30, W = 30;\nstatic const int di4[4] = {0,-1,0,1};\nstatic const int dj4[4] = {-1,0,1,0};\n\n// Base to mapping for tile types 0..7 as per statement.\nint base_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// to_rot[t][r][d]: with tile type t rotated r times CCW, entering from direction d, output direction or -1.\nint to_rot[8][4][4];\n\ninline int mod4(int x){ x%=4; if(x<0)x+=4; return x; }\n\nstruct Solver {\n    array<array<int, W>, H> t;\n    array<array<int, W>, H> r;         // current rotations\n    array<array<int, W>, H> best_r;\n    array<array<int, W>, H> tmp_r;\n\n    // desired outgoing direction for each entering direction\n    array<array<array<int,4>, W>, H> desired_to;\n\n    int proxyScore = 0;\n\n    mt19937 rng;\n\n    Solver(): rng(712367) {}\n\n    void precompute_to_rot() {\n        for(int tt=0; tt<8; ++tt){\n            for(int rot=0; rot<4; ++rot){\n                for(int d=0; d<4; ++d){\n                    int din = mod4(d - rot);\n                    int e = base_to_[tt][din];\n                    if(e==-1) to_rot[tt][rot][d] = -1;\n                    else to_rot[tt][rot][d] = mod4(e + rot);\n                }\n            }\n        }\n    }\n\n    void read_input() {\n        for(int i=0;i<H;++i){\n            string s; cin>>s;\n            for(int j=0;j<W;++j){\n                t[i][j] = s[j]-'0';\n            }\n        }\n    }\n\n    // Build desired_to by selecting a pattern id\n    // pattern 0: two vortices (left/right)\n    // pattern 1: single center vortex\n    // pattern 2: horizontal ring (prefer left/right flow loop)\n    // pattern 3: vertical ring\n    // pattern 4: four quadrants vortices\n    // pattern 5: serpentine sweeping rows\n    void build_desired(int pattern) {\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                for(int d=0; d<4; ++d) desired_to[i][j][d]=2; // default right\n            }\n        }\n        auto pick_card = [&](double ti, double tj)->int{\n            static const int vx[4] = {0,-1,0,1};\n            static const int vy[4] = {-1,0,1,0};\n            int bestd = 0;\n            double bestdot = -1e100;\n            for(int d=0; d<4; ++d){\n                double dot = ti*vx[d] + tj*vy[d];\n                if(dot > bestdot){ bestdot=dot; bestd=d; }\n            }\n            return bestd;\n        };\n        if(pattern==0){ // two vortices\n            double c1i = 14.5, c1j = 7.5;\n            double c2i = 14.5, c2j = 22.5;\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    double ci, cj;\n                    if(j < W/2) { ci=c1i; cj=c1j; }\n                    else { ci=c2i; cj=c2j; }\n                    double pi = i+0.5, pj=j+0.5;\n                    double ui = pi - ci, uj = pj - cj;\n                    double ti = -uj, tj = ui; // CCW tangent\n                    int dsel = pick_card(ti,tj);\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else if(pattern==1){ // single center vortex\n            double ci = 14.5, cj = 14.5;\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    double pi = i+0.5, pj=j+0.5;\n                    double ui = pi - ci, uj = pj - cj;\n                    double ti = -uj, tj = ui;\n                    int dsel = pick_card(ti,tj);\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else if(pattern==2){ // horizontal ring\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int dsel = (i%2==0)?2:0; // even rows go right, odd left\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else if(pattern==3){ // vertical ring\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int dsel = (j%2==0)?3:1; // even cols go down, odd up\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else if(pattern==4){ // four quadrants vortices\n            double ci1=7.5,cj1=7.5, ci2=7.5,cj2=21.5, ci3=21.5,cj3=7.5, ci4=21.5,cj4=21.5;\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    double ci, cj;\n                    if(i<15 && j<15){ ci=ci1; cj=cj1; }\n                    else if(i<15){ ci=ci2; cj=cj2; }\n                    else if(j<15){ ci=ci3; cj=cj3; }\n                    else { ci=ci4; cj=cj4; }\n                    double pi = i+0.5, pj=j+0.5;\n                    double ui = pi - ci, uj = pj - cj;\n                    double ti = -uj, tj = ui;\n                    int dsel = pick_card(ti,tj);\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else { // serpentine with bias to loop around borders\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int dsel;\n                    if(i==0) dsel = 2;\n                    else if(i==H-1) dsel = 0;\n                    else dsel = (i%2==0)?2:0;\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        }\n    }\n\n    int tile_local_score(int i,int j,int rot, const array<array<int,W>,H>& rotAssign){\n        int sc = 0;\n        for(int d=0; d<4; ++d){\n            int e = to_rot[t[i][j]][rot][d];\n            if(e==-1){ sc -= 2; continue; }\n            if(e == desired_to[i][j][d]) sc += 1;\n            int ni = i + di4[e], nj = j + dj4[e];\n            if(ni<0||ni>=H||nj<0||nj>=W) sc -= 3;\n            else {\n                // neighbor tentative consistency\n                int need = (e+2)&3;\n                int ne = to_rot[t[ni][nj]][rotAssign[ni][nj]][need];\n                if(ne == need) sc += 1;\n            }\n        }\n        return sc;\n    }\n\n    void initial_assignment() {\n        // simple greedy with a couple of sweeps to incorporate neighbor consistency\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                int bestRot=0, bestSc = INT_MIN;\n                for(int rot=0; rot<4; ++rot){\n                    int sc = 0;\n                    for(int d=0; d<4; ++d){\n                        int e = to_rot[t[i][j]][rot][d];\n                        if(e==-1){ sc -= 2; continue; }\n                        if(e == desired_to[i][j][d]) sc += 1;\n                        int ni = i + di4[e], nj = j + dj4[e];\n                        if(ni<0||ni>=H||nj<0||nj>=W) sc -= 3;\n                    }\n                    if(sc > bestSc){\n                        bestSc = sc; bestRot = rot;\n                    }\n                }\n                r[i][j] = bestRot;\n            }\n        }\n        // a few refinement sweeps\n        for(int it=0; it<2; ++it){\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int cur = r[i][j];\n                    int bestRot = cur, bestSc = tile_local_score(i,j,cur,r);\n                    for(int rot=0; rot<4; ++rot){\n                        if(rot==cur) continue;\n                        int sc = tile_local_score(i,j,rot,r);\n                        if(sc > bestSc){ bestSc = sc; bestRot = rot; }\n                    }\n                    r[i][j] = bestRot;\n                }\n            }\n        }\n    }\n\n    // Edge match proxy: bidirectional usability across an edge\n    inline int edge_match_at(int i,int j,int d) {\n        int ni = i + di4[d], nj = j + dj4[d];\n        if(ni<0||ni>=H||nj<0||nj>=W) return 0;\n        // A entering from opposite of edge, out to the edge\n        int Ato = to_rot[t[i][j]][r[i][j]][(d+2)&3];\n        if(Ato != d) return 0;\n        // B entering from its opposite of edge, out back along the edge\n        int Bd = (d+2)&3;\n        int Bto = to_rot[t[ni][nj]][r[ni][nj]][(Bd+2)&3]; // careful: entering from opposite of the edge at B is actually d (from A to B). For symmetric, use:\n        // Correct: for B, entering from opposite direction of edge from its perspective is d (from its neighbor). The pair that forms the straight across the shared edge is:\n        // If we cross edge between A and B, then at B the entering direction is (d+2)%4. To continue across back to A, B should output (d+2)%4 (backwards), but for a loop we need B to accept from (d+2) and send back (d+2). However, to ensure the edge can be traversed both ways by trains coming from both sides, we check both A->B and B->A. We'll implement that fully below outside this function for accuracy.\n        (void)Bto;\n        return 1; // placeholder, not used\n    }\n\n    // Proper undirected edge usability: both directions usable\n    inline int edge_bidirected_usable(int ai,int aj,int d){\n        int bi = ai + di4[d], bj = aj + dj4[d];\n        if(bi<0||bi>=H||bj<0||bj>=W) return 0;\n        // A->B\n        int eA = to_rot[t[ai][aj]][r[ai][aj]][(d+2)&3];\n        if(eA != d) return 0;\n        int eB = to_rot[t[bi][bj]][r[bi][bj]][(d+2)&3];\n        if(eB != (d+2)&3) return 0;\n        // B->A\n        int eB2 = to_rot[t[bi][bj]][r[bi][bj]][(d)&3];\n        if(eB2 != (d+2)&3) return 0;\n        int eA2 = to_rot[t[ai][aj]][r[ai][aj]][(d)&3];\n        if(eA2 != d) return 0;\n        return 1;\n    }\n\n    int compute_proxy_score() {\n        int total = 0;\n        for(int i=0;i<H;++i){\n            for(int j=0;j+1<W;++j){\n                total += edge_bidirected_usable(i,j,2);\n            }\n        }\n        for(int i=0;i+1<H;++i){\n            for(int j=0;j<W;++j){\n                total += edge_bidirected_usable(i,j,3);\n            }\n        }\n        return total;\n    }\n\n    int local_proxy_contrib_cell(int i,int j){\n        int sum=0;\n        if(j>0) sum += edge_bidirected_usable(i,j-1,2);\n        if(j<W-1) sum += edge_bidirected_usable(i,j,2);\n        if(i>0) sum += edge_bidirected_usable(i-1,j,3);\n        if(i<H-1) sum += edge_bidirected_usable(i,j,3);\n        return sum;\n    }\n\n    // Compute top two loop lengths and optionally record states of the loops\n    pair<int,int> compute_top2_loops(vector<pair<int,int>>* bestLoopCells = nullptr, vector<pair<int,int>>* secondLoopCells = nullptr) {\n        vector<vector<array<char,4>>> vis(H, vector<array<char,4>>(W, {0,0,0,0}));\n        int best1=0, best2=0;\n        vector<pair<int,int>> loop1cells, loop2cells;\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                for(int d=0; d<4; ++d){\n                    if(vis[i][j][d]) continue;\n                    int ci=i, cj=j, cd=d;\n                    int steps=0;\n                    // map state to step index\n                    // use array for performance: 3600 states, but we need per-walk storage. Use unordered_map reserved small.\n                    unordered_map<int,int> seen;\n                    seen.reserve(32);\n                    auto enc = [&](int x,int y,int dd){ return ((x*W + y)<<2) | dd; };\n                    vector<tuple<int,int,int>> walk;\n                    while(true){\n                        int key = enc(ci,cj,cd);\n                        if(seen.find(key)!=seen.end()){\n                            int st = seen[key];\n                            int cyc_len = steps - st;\n                            if(cyc_len >= best1){\n                                best2 = best1; loop2cells = loop1cells;\n                                best1 = cyc_len;\n                                loop1cells.clear();\n                                for(int k=st;k<(int)walk.size();++k){\n                                    auto [x,y,dd] = walk[k];\n                                    loop1cells.emplace_back(x,y);\n                                }\n                            } else if(cyc_len > best2){\n                                best2 = cyc_len;\n                                loop2cells.clear();\n                                for(int k=st;k<(int)walk.size();++k){\n                                    auto [x,y,dd] = walk[k];\n                                    loop2cells.emplace_back(x,y);\n                                }\n                            }\n                            break;\n                        }\n                        if(vis[ci][cj][cd]) break;\n                        seen[key] = steps;\n                        walk.emplace_back(ci,cj,cd);\n                        int e = to_rot[t[ci][cj]][r[ci][cj]][cd];\n                        if(e==-1) break;\n                        int ni = ci + di4[e], nj = cj + dj4[e];\n                        if(ni<0||ni>=H||nj<0||nj>=W) break;\n                        int nd = (e+2)&3;\n                        ci=ni; cj=nj; cd=nd;\n                        steps++;\n                    }\n                    // mark visited\n                    for(auto &tp: walk){\n                        int x,y,dd; tie(x,y,dd)=tp;\n                        vis[x][y][dd]=1;\n                    }\n                }\n            }\n        }\n        if(bestLoopCells) *bestLoopCells = loop1cells;\n        if(secondLoopCells) *secondLoopCells = loop2cells;\n        return {best1,best2};\n    }\n\n    // Reinforce tiles along loop cells by choosing rotation that maximizes participation edges\n    void reinforce_along_loops(const vector<pair<int,int>>& loopCells){\n        if(loopCells.empty()) return;\n        // mark cells\n        vector<vector<char>> mark(H, vector<char>(W, 0));\n        for(auto &p: loopCells) mark[p.first][p.second]=1;\n        // try improving rotations on marked cells\n        for(auto &p: loopCells){\n            int i=p.first, j=p.second;\n            int cur = r[i][j];\n            int bestRot = cur;\n            int bestLoc = local_proxy_contrib_cell(i,j);\n            for(int rot=0; rot<4; ++rot){\n                if(rot==cur) continue;\n                int old = r[i][j];\n                r[i][j]=rot;\n                int val = local_proxy_contrib_cell(i,j);\n                if(val > bestLoc){ bestLoc=val; bestRot=rot; }\n                r[i][j]=old;\n            }\n            r[i][j]=bestRot;\n        }\n    }\n\n    // Hill climb / SA\n    void optimize(double timeLimitSec, long long &bestScoreAll, array<array<int,W>,H> &bestRAll){\n        proxyScore = compute_proxy_score();\n        auto top2 = compute_top2_loops();\n        long long bestScore = 1LL*top2.first*top2.second;\n        best_r = r;\n\n        auto start = chrono::high_resolution_clock::now();\n        int iter=0, accepted=0;\n        uniform_real_distribution<double> urd(0.0,1.0);\n\n        while(true){\n            iter++;\n            if((iter & 0x1FFF)==0){\n                auto now = chrono::high_resolution_clock::now();\n                double t = chrono::duration<double>(now - start).count();\n                if(t > timeLimitSec) break;\n            }\n            int i = rng()%H;\n            int j = rng()%W;\n            int cur = r[i][j];\n            int before = local_proxy_contrib_cell(i,j);\n            int bestRot = cur;\n            int bestLocal = before;\n            for(int rot=0; rot<4; ++rot){\n                if(rot==cur) continue;\n                int old = r[i][j];\n                r[i][j] = rot;\n                int after = local_proxy_contrib_cell(i,j);\n                if(after > bestLocal){\n                    bestLocal = after; bestRot = rot;\n                }\n                r[i][j] = old;\n            }\n            int gain = bestLocal - before;\n            // SA acceptance with cooling\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            double frac = min(1.0, elapsed / timeLimitSec);\n            double T0 = 0.5, T1 = 0.02;\n            double temp = T0 * (1.0 - frac) + T1 * frac;\n            bool take = false;\n            if(gain > 0) take = true;\n            else {\n                double prob = exp(gain / max(1e-9, temp));\n                if(urd(rng) < prob) take = true;\n            }\n            if(take){\n                r[i][j] = bestRot;\n                proxyScore += gain;\n                accepted++;\n                if((accepted % 200)==0){\n                    auto p = compute_top2_loops();\n                    long long sc = 1LL*p.first*p.second;\n                    if(sc > bestScore){\n                        bestScore = sc;\n                        best_r = r;\n                    }\n                }\n            }\n        }\n        // Final evaluation and reinforcement\n        auto cells1 = vector<pair<int,int>>(), cells2 = vector<pair<int,int>>();\n        auto p = compute_top2_loops(&cells1, &cells2);\n        long long sc = 1LL*p.first*p.second;\n        if(sc > bestScore){ bestScore = sc; best_r = r; }\n        // reinforce along the two best loops and re-evaluate\n        r = best_r;\n        reinforce_along_loops(cells1);\n        reinforce_along_loops(cells2);\n        auto p2 = compute_top2_loops();\n        long long sc2 = 1LL*p2.first*p2.second;\n        if(sc2 > bestScore){ bestScore = sc2; best_r = r; }\n\n        if(bestScore > bestScoreAll){\n            bestScoreAll = bestScore;\n            bestRAll = best_r;\n        }\n        // restore best for further usage\n        r = best_r;\n    }\n\n    void solve() {\n        precompute_to_rot();\n        read_input();\n\n        long long globalBestScore = -1;\n        array<array<int,W>,H> globalBestR;\n\n        // Try several patterns with limited time shares\n        const int PATTERNS[6] = {0,1,2,3,4,5};\n        double totalTime = 1.95;\n        double initShare = 0.15; // time for initialization refinements\n        double perPatternTime = (totalTime - initShare) / 6.0;\n\n        auto tstart = chrono::high_resolution_clock::now();\n\n        for(int pid = 0; pid < 6; ++pid){\n            build_desired(PATTERNS[pid]);\n            initial_assignment();\n            // Use a portion of time for this pattern\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - tstart).count();\n            double remaining = max(0.0, totalTime - elapsed);\n            double budget = min(perPatternTime, remaining);\n            if(budget <= 0.0) break;\n            optimize(budget, globalBestScore, globalBestR);\n        }\n\n        // As fallback, if nothing ran (shouldn't happen), compute once\n        if(globalBestScore < 0){\n            build_desired(0);\n            initial_assignment();\n            auto p = compute_top2_loops();\n            globalBestR = r;\n        }\n\n        // Output best rotations as a single line of 900 digits\n        string out; out.reserve(H*W);\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                out.push_back(char('0' + (globalBestR[i][j] & 3)));\n            }\n        }\n        cout << out << \"\\n\";\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver s;\n    s.solve();\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction masks: bit 0=left(1), bit1=up(2), bit2=right(4), bit3=down(8)\nstatic inline bool matchLR(int a, int b){ // a right with b left\n    return (a & 4) && (b & 1);\n}\nstatic inline bool matchUD(int a, int b){ // a down with b up\n    return (a & 8) && (b & 2);\n}\n\nstruct RNG {\n    uint64_t x;\n    RNG(uint64_t seed=712367821) : x(seed) {}\n    uint32_t next() { x ^= x<<7; x ^= x>>9; return (uint32_t)x; }\n    int randint(int l, int r){ return l + (int)(next() % (uint32_t)(r-l+1)); }\n    bool prob(double p){ return (next() / (double)UINT32_MAX) < p; }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; int Tlimit;\n    if(!(cin>>N>>Tlimit)) {\n        return 0;\n    }\n    vector<string> rows(N);\n    for(int i=0;i<N;i++) cin>>rows[i];\n    vector<int> a(N*N);\n    int emptyPos=-1;\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            char c = rows[i][j];\n            int v;\n            if(c>='0' && c<='9') v = c-'0';\n            else v = 10 + (c-'a');\n            a[i*N+j]=v;\n            if(v==0) emptyPos=i*N+j;\n        }\n    }\n\n    RNG rng(123456789 ^ (uint64_t)chrono::high_resolution_clock::now().time_since_epoch().count());\n\n    auto inb = [&](int r,int c){ return r>=0 && r<N && c>=0 && c<N; };\n\n    // Precompute adjacency matched array\n    // horiz[i][j] is match between (i,j) and (i,j+1)\n    vector<char> horiz(N*(N-1),0), vert((N-1)*N,0);\n    auto idxH = [&](int i,int j){ return i*(N-1)+j; };\n    auto idxV = [&](int i,int j){ return i*N+j; };\n\n    auto recompute_local_edges = [&](int r,int c){\n        // Update matches around (r,c): edges to left/right/up/down if exist\n        int p = r*N+c;\n        if(a[p]==0){\n            // empty contributes no edges, but neighbors matching is only defined on non-empty squares\n            // However matched edges definition is between non-empty squares; empty breaks edges.\n        }\n        // Horizontal edges with (r,c-1)-(r,c) and (r,c)-(r,c+1)\n        if(c-1>=0){\n            int L = a[r*N+(c-1)], Rv = a[r*N+c];\n            horiz[idxH(r,c-1)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n        if(c<N-1){\n            int L = a[r*N+c], Rv = a[r*N+(c+1)];\n            horiz[idxH(r,c)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n        // Vertical edges with (r-1,c)-(r,c) and (r,c)-(r+1,c)\n        if(r-1>=0){\n            int U = a[(r-1)*N+c], Dv = a[r*N+c];\n            vert[idxV(r-1,c)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n        if(r<N-1){\n            int U = a[r*N+c], Dv = a[(r+1)*N+c];\n            vert[idxV(r,c)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n    };\n    // Initialize all matches\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N-1;j++){\n            int L=a[i*N+j], Rv=a[i*N+j+1];\n            horiz[idxH(i,j)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n    }\n    for(int i=0;i<N-1;i++){\n        for(int j=0;j<N;j++){\n            int U=a[i*N+j], Dv=a[(i+1)*N+j];\n            vert[idxV(i,j)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n    }\n    auto totalE = [&](){\n        int s=0;\n        for(char v: horiz) s+=v;\n        for(char v: vert) s+=v;\n        return s;\n    };\n    int E = totalE();\n\n    // Helpers to compute local delta for a tentative swap between empty at (er,ec) and neighbor (nr,nc)\n    auto delta_for_move = [&](int er,int ec,int nr,int nc)->int{\n        // collect set of affected edges indices before and after; easiest is to sum contributions around the two cells\n        int before=0, after=0;\n        auto add_edges = [&](int r,int c,int &acc){\n            if(c-1>=0) acc += horiz[idxH(r,c-1)];\n            if(c<N-1) acc += horiz[idxH(r,c)];\n            if(r-1>=0) acc += vert[idxV(r-1,c)];\n            if(r<N-1) acc += vert[idxV(r,c)];\n        };\n        add_edges(er,ec,before);\n        add_edges(nr,nc,before);\n\n        // simulate swap\n        int pe = er*N+ec, pn = nr*N+nc;\n        int ve = a[pe], vn = a[pn]; // ve == 0\n        // Temporarily swap in thought: a'[pe]=vn, a'[pn]=0\n        // compute edges after by recomputing these positions\u2019 edges on the fly\n        auto contrib_cell = [&](int r,int c, int val_at_rc)->int{\n            int s=0;\n            // left edge (r,c-1)-(r,c)\n            if(c-1>=0){\n                int L = (r*N + c-1 == pe ? vn : (r*N + c-1 == pn ? 0 : a[r*N + c-1]));\n                int Rv = val_at_rc;\n                s += (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n            }\n            // right edge (r,c)-(r,c+1)\n            if(c<N-1){\n                int L = val_at_rc;\n                int Rv = (r*N + c+1 == pe ? vn : (r*N + c+1 == pn ? 0 : a[r*N + c+1]));\n                s += (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n            }\n            // up edge (r-1,c)-(r,c)\n            if(r-1>=0){\n                int U = ( (r-1)*N + c == pe ? vn : ((r-1)*N + c == pn ? 0 : a[(r-1)*N + c]) );\n                int Dv = val_at_rc;\n                s += (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n            }\n            // down edge (r,c)-(r+1,c)\n            if(r<N-1){\n                int U = val_at_rc;\n                int Dv = ( (r+1)*N + c == pe ? vn : ((r+1)*N + c == pn ? 0 : a[(r+1)*N + c]) );\n                s += (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n            }\n            return s;\n        };\n        after += contrib_cell(er,ec, vn);\n        after += contrib_cell(nr,nc, 0);\n        return after - before;\n    };\n\n    string moves;\n    moves.reserve(Tlimit);\n\n    // Direction arrays\n    const int dr[4]={-1,1,0,0};\n    const int dc[4]={0,0,-1,1};\n    const char dch[4] = {'U','D','L','R'};\n    const int revdir[4] = {1,0,3,2};\n\n    int er = emptyPos / N, ec = emptyPos % N;\n    int last_dir = -1;\n\n    auto apply_move = [&](int dir){\n        int nr = er + dr[dir], nc = ec + dc[dir];\n        // compute delta and apply\n        int pe = er*N+ec, pn = nr*N+nc;\n        int delta = 0;\n        // remove before from E by recomputing local, then recompute after with actual update and patch horiz/vert\n        // For robustness, compute delta via delta_for_move\n        delta = delta_for_move(er,ec,nr,nc);\n        // swap\n        swap(a[pe], a[pn]);\n        // update local edges arrays around affected cells (and neighbors; recompute around both cells)\n        recompute_local_edges(er,ec);\n        recompute_local_edges(nr,nc);\n        E += delta;\n        er = nr; ec = nc;\n        moves.push_back(dch[dir]);\n        last_dir = dir;\n    };\n\n    // Main loop: up to Tlimit moves or time\n    auto t_start = chrono::high_resolution_clock::now();\n    double time_limit_ms = 2800.0;\n\n    for(int step=0; step<Tlimit; ++step){\n        // time guard\n        if((step & 255) == 0){\n            auto now = chrono::high_resolution_clock::now();\n            double ms = chrono::duration<double, milli>(now - t_start).count();\n            if(ms > time_limit_ms) break;\n        }\n        // evaluate candidates\n        struct Cand{ int dir; int delta; int tie; };\n        vector<Cand> cands;\n        for(int d=0; d<4; d++){\n            int nr = er + dr[d], nc = ec + dc[d];\n            if(!inb(nr,nc)) continue;\n            if(last_dir != -1 && revdir[d]==last_dir){\n                // consider but downweight; we'll keep it but mark tie worse unless strictly good\n            }\n            int del = delta_for_move(er,ec,nr,nc);\n            int tie = 0;\n            // tie-breaker: prefer central positions for the empty after move\n            int cen_bias = - (abs((N-1)/2 - nr) + abs((N-1)/2 - nc));\n            tie += cen_bias;\n            // small random jitter\n            tie += rng.randint(-2,2);\n            cands.push_back({d, del, tie});\n        }\n        if(cands.empty()) break;\n        // choose best\n        sort(cands.begin(), cands.end(), [&](const Cand& A, const Cand& B){\n            if(A.delta != B.delta) return A.delta > B.delta;\n            return A.tie > B.tie;\n        });\n        int chosen = 0;\n        // If best delta <= 0, allow some randomness to escape local minima\n        if(cands[0].delta <= 0){\n            // with small probability pick a random candidate\n            if(rng.prob(0.15)){\n                chosen = rng.randint(0, (int)cands.size()-1);\n            }else{\n                // avoid immediate reversal if not improving\n                if(last_dir != -1 && revdir[cands[0].dir]==last_dir && cands.size()>=2){\n                    if(cands[1].delta == cands[0].delta || rng.prob(0.5)) chosen = 1;\n                }\n            }\n        }else{\n            // improving move, but avoid immediate reversal when tie\n            if(last_dir != -1 && revdir[cands[0].dir]==last_dir && cands.size()>=2 && cands[1].delta==cands[0].delta){\n                if(rng.prob(0.5)) chosen = 1;\n            }\n        }\n        apply_move(cands[chosen].dir);\n    }\n\n    // Output\n    cout<<moves<<\"\\n\";\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Sig {\n    uint64_t a=0, b=0;\n    bool operator==(Sig const& o) const { return a==o.a && b==o.b; }\n};\nstruct SigHash {\n    size_t operator()(Sig const& s) const noexcept {\n        // 128-bit-like mixing\n        uint64_t x = s.a ^ (s.b + 0x9E3779B97F4A7C15ULL + (s.a<<6) + (s.a>>2));\n        x ^= (x >> 27);\n        x *= 0x3C79AC492BA7B653ULL;\n        x ^= (x >> 33);\n        x *= 0x1C69B3F74AC4AE35ULL;\n        x ^= (x >> 27);\n        return (size_t)x;\n    }\n};\n\nstruct Point { int x,y; };\nstruct LineParam { int A,B; long long T; };\n\nstatic inline long long dotAB(int A,int B,int x,int y){ return (long long)A*x + (long long)B*y; }\n\nstatic long long egcd(long long a, long long b, long long &x, long long &y){\n    if(b==0){ x = (a>=0?1:-1); y=0; return llabs(a); }\n    long long x1,y1;\n    long long g = egcd(b, a%b, x1, y1);\n    x = y1;\n    y = x1 - (a/b) * y1;\n    return g;\n}\n\nstatic inline void reduce_coprime(int &A, int &B){\n    if(A==0 && B==0){ A=1; B=0; return; }\n    if(A==0){ B = (B>0?1:-1); return; }\n    if(B==0){ A = (A>0?1:-1); return; }\n    int g = std::gcd(abs(A),abs(B));\n    A/=g; B/=g;\n    if(A<0){ A=-A; B=-B; }\n    else if(A==0 && B<0){ B=-B; }\n}\n\nstatic inline pair<long long,long long> clip2(long long x, long long y){\n    auto clip = [](long long v){\n        if(v < -1000000000LL) return -1000000000LL;\n        if(v > 1000000000LL) return 1000000000LL;\n        return v;\n    };\n    return {clip(x), clip(y)};\n}\n\nstatic inline pair<pair<long long,long long>, pair<long long,long long>>\ntwo_points_on_line(int A, int B, long long T){\n    long long x0,y0;\n    long long g = egcd(A,B,x0,y0);\n    if(g<0){ g=-g; x0=-x0; y0=-y0; }\n    long long mul = T / g;\n    __int128 xi = (__int128)x0 * mul;\n    __int128 yi = (__int128)y0 * mul;\n    long long X = (long long)xi;\n    long long Y = (long long)yi;\n    long long kk = 100000;\n    long long X2 = X + (long long)B * kk;\n    long long Y2 = Y - (long long)A * kk;\n    auto p1 = clip2(X,Y);\n    auto p2 = clip2(X2,Y2);\n    if(p1==p2){\n        kk = 1;\n        X2 = X + (long long)B * kk;\n        Y2 = Y - (long long)A * kk;\n        p2 = clip2(X2,Y2);\n        if(p1==p2){\n            kk = 2;\n            X2 = X + (long long)B * kk;\n            Y2 = Y - (long long)A * kk;\n            p2 = clip2(X2,Y2);\n        }\n    }\n    return {p1,p2};\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, K;\n    if(!(cin>>N>>K)) return 0;\n    vector<int> a(11);\n    for(int d=1; d<=10; ++d) cin>>a[d];\n    vector<Point> pts(N);\n    for(int i=0;i<N;++i) cin>>pts[i].x >> pts[i].y;\n\n    // Base normals\n    vector<pair<int,int>> baseNormals = {\n        {1,0},{0,1},{1,1},{1,-1},{2,1},{1,2},{2,-1},{1,-2},\n        {3,1},{1,3},{3,2},{2,3},{3,-1},{1,-3},{3,-2},{2,-3},\n        {4,1},{1,4},{4,3},{3,4},{5,2},{2,5},{5,1},{1,5}\n    };\n    for(auto &p: baseNormals) reduce_coprime(p.first, p.second);\n    sort(baseNormals.begin(), baseNormals.end());\n    baseNormals.erase(unique(baseNormals.begin(), baseNormals.end()), baseNormals.end());\n\n    vector<Sig> sig(N);\n    unordered_map<Sig, vector<int>, SigHash> cells;\n    vector<int> bd(11,0);\n\n    auto recompute = [&](){\n        cells.clear();\n        cells.reserve(N*2);\n        for(int i=0;i<N;++i) cells[sig[i]].push_back(i);\n        fill(bd.begin(), bd.end(), 0);\n        for(auto &kv : cells){\n            int s = (int)kv.second.size();\n            if(s<=10) bd[s]++;\n        }\n    };\n    recompute();\n\n    vector<LineParam> lines; lines.reserve(K);\n\n    auto all_satisfied = [&](){\n        for(int d=1; d<=10; ++d) if(bd[d] < a[d]) return false;\n        return true;\n    };\n\n    vector<long long> proj; proj.reserve(N);\n\n    int cutsLeft = K;\n    while(cutsLeft>0){\n        if(all_satisfied()) break;\n\n        vector<int> need(11,0);\n        int totalNeed=0;\n        for(int d=1; d<=10; ++d){ need[d] = max(0, a[d]-bd[d]); totalNeed += need[d]; }\n\n        // Candidate cells: top M\n        vector<pair<int,Sig>> cands;\n        cands.reserve(cells.size());\n        for(auto &kv : cells) cands.emplace_back((int)kv.second.size(), kv.first);\n        if(cands.empty()) break;\n        sort(cands.begin(), cands.end(), [](auto &L, auto &R){ return L.first > R.first; });\n        int consider = min<int>((int)cands.size(), 14);\n\n        long long bestScore = LLONG_MIN;\n        LineParam bestLine{1,0,0};\n        bool found = false;\n\n        // Helper: get list of demanded sizes sorted by need desc, then by size asc\n        vector<int> demandList;\n        for(int d=1; d<=10; ++d) if(need[d]>0) demandList.push_back(d);\n        sort(demandList.begin(), demandList.end(), [&](int u,int v){\n            if(need[u]!=need[v]) return need[u]>need[v];\n            return u < v;\n        });\n        if(demandList.empty()){\n            for(int d=1; d<=10; ++d) demandList.push_back(d);\n        }\n\n        for(int ci=0; ci<consider; ++ci){\n            int s = cands[ci].first;\n            if(s<=1) continue;\n            auto &idxs = cells[cands[ci].second];\n\n            // PCA normals\n            long double meanx=0, meany=0;\n            for(int id : idxs){ meanx += pts[id].x; meany += pts[id].y; }\n            meanx /= s; meany /= s;\n            long double cxx=0,cxy=0,cyy=0;\n            for(int id : idxs){\n                long double dx = (long double)pts[id].x - meanx;\n                long double dy = (long double)pts[id].y - meany;\n                cxx += dx*dx; cxy += dx*dy; cyy += dy*dy;\n            }\n            long double tr = cxx + cyy;\n            long double det = cxx*cyy - cxy*cxy;\n            long double tmp = max((long double)0.0L, tr*tr/4 - det);\n            long double l1 = tr/2 + sqrtl(tmp);\n            long double vx,vy;\n            if(fabsl(cxy) > 1e-14L){ vx = l1 - cyy; vy = cxy; }\n            else { if(cxx >= cyy){ vx=1; vy=0; } else { vx=0; vy=1; } }\n            long double normv = sqrtl(vx*vx + vy*vy);\n            if(normv < 1e-18L){ vx=1; vy=0; normv=1; }\n            vx/=normv; vy/=normv;\n            long double nx1=-vy, ny1=vx;\n            long double nx2= vy, ny2=-vx;\n            auto to_small_int = [&](long double nx,long double ny)->pair<int,int>{\n                long double scale = 12.0L;\n                int A = (int)llround(nx*scale);\n                int B = (int)llround(ny*scale);\n                if(A==0 && B==0){\n                    if(fabsl(nx) >= fabsl(ny)) A = (nx>=0?1:-1);\n                    else B = (ny>=0?1:-1);\n                }\n                reduce_coprime(A,B);\n                if(abs(A)>20 || abs(B)>20){\n                    int g = max(abs(A),abs(B));\n                    int k = (g+19)/20;\n                    if(k==0) k=1;\n                    A/=k; B/=k;\n                    if(A==0 && B==0){ A=1; B=0; }\n                    reduce_coprime(A,B);\n                }\n                return {A,B};\n            };\n            pair<int,int> pca1 = to_small_int(nx1,ny1);\n            pair<int,int> pca2 = to_small_int(nx2,ny2);\n\n            // Build normals to try\n            static vector<pair<int,int>> normals;\n            normals.clear();\n            normals.insert(normals.end(), baseNormals.begin(), baseNormals.end());\n            normals.push_back(pca1);\n            normals.push_back(pca2);\n            sort(normals.begin(), normals.end());\n            normals.erase(unique(normals.begin(), normals.end()), normals.end());\n\n            // Prepare L-candidates builder\n            auto build_Lcands = [&](int s)->vector<int>{\n                vector<int> Lc;\n                if(s>=2){\n                    Lc.push_back(s/2);\n                    Lc.push_back(max(1, s/3));\n                    Lc.push_back(max(1, (2*s)/3));\n                }\n                // Demand sizes target\n                int take = min(4, (int)demandList.size());\n                for(int i=0;i<take;++i){\n                    int d = demandList[i];\n                    if(d < s) Lc.push_back(d);\n                    if(s-d >= 1 && s-d < s) Lc.push_back(s-d);\n                }\n                // Also try sum of top two needs\n                if(demandList.size()>=2){\n                    int d1=demandList[0], d2=demandList[1];\n                    if(d1 < s) Lc.push_back(d1);\n                    if(s-d2 >= 1 && s-d2 < s) Lc.push_back(s-d2);\n                }\n                for(int &v: Lc){ if(v<1) v=1; if(v>s-1) v=s-1; }\n                sort(Lc.begin(), Lc.end());\n                Lc.erase(unique(Lc.begin(), Lc.end()), Lc.end());\n                return Lc;\n            };\n\n            auto Lcands = build_Lcands(s);\n\n            // Evaluate normals\n            for(auto [A,B] : normals){\n                proj.resize(s);\n                for(int i=0;i<s;++i){\n                    const auto &p = pts[idxs[i]];\n                    proj[i] = dotAB(A,B,p.x,p.y);\n                }\n                sort(proj.begin(), proj.end());\n\n                for(int l : Lcands){\n                    int i = l-1;\n                    if(i<0 || i+1>=s) continue;\n                    long long vL = proj[i], vR = proj[i+1];\n                    if(vL >= vR){\n                        // find nearest gap to match l as close as possible\n                        int il = i;\n                        while(il>=0 && proj[il]==vL) --il;\n                        int ir = i+1;\n                        while(ir<s && proj[ir]==vR) ++ir;\n                        // choose side closer to desired l\n                        int candL1 = il+1; // split between il and il+1\n                        int candL2 = ir;   // split between ir-1 and ir\n                        int chooseL;\n                        if(il>=0 && ir<s){\n                            if(abs(candL1 - l) <= abs(candL2 - l)){\n                                chooseL = candL1; vL = proj[il]; vR = proj[il+1];\n                            }else{\n                                chooseL = candL2; vL = proj[ir-1]; vR = proj[ir];\n                            }\n                        }else if(il>=0){\n                            chooseL = candL1; vL = proj[il]; vR = proj[il+1];\n                        }else if(ir<s){\n                            chooseL = candL2; vL = proj[ir-1]; vR = proj[ir];\n                        }else{\n                            continue;\n                        }\n                        l = chooseL;\n                    }\n                    long long T = (vL + vR) / 2;\n                    int leftSize = l;\n                    int rightSize = s - l;\n\n                    // delta and scoring\n                    auto minA = [&](int d, int b){ return min(a[d], b); };\n                    long long delta = 0;\n                    // Adaptive penalty for >10: lower penalty early, higher later\n                    auto overPenalty = [&](int size)->long long{\n                        if(size <= 10) return 0;\n                        // if many cuts left or size large, small penalty (-1), else stronger (-2)\n                        if(cutsLeft > 50 || size > 20) return -1;\n                        return -2;\n                    };\n                    if(leftSize<=10) delta += minA(leftSize, bd[leftSize]+1) - minA(leftSize, bd[leftSize]);\n                    else delta += overPenalty(leftSize);\n                    if(rightSize<=10) delta += minA(rightSize, bd[rightSize]+1) - minA(rightSize, bd[rightSize]);\n                    else delta += overPenalty(rightSize);\n                    if(s<=10) delta += minA(s, bd[s]-1) - minA(s, bd[s]);\n\n                    // Oversupply penalty\n                    long long overs = 0;\n                    if(leftSize<=10 && bd[leftSize] >= a[leftSize]) overs -= 1;\n                    if(rightSize<=10 && bd[rightSize] >= a[rightSize]) overs -= 1;\n\n                    // Bonus if we exactly hit needed sizes\n                    long long bonus = 0;\n                    if(leftSize<=10 && need[leftSize]>0) bonus += 1;\n                    if(rightSize<=10 && need[rightSize]>0) bonus += 1;\n\n                    long long balance = - llabs(leftSize - rightSize);\n\n                    long long score = (delta<<24) + (bonus<<16) + (overs<<12) + balance;\n\n                    if(score > bestScore){\n                        bestScore = score;\n                        bestLine = {A,B,T};\n                        found = true;\n                    }\n                }\n            }\n        }\n\n        if(!found){\n            // Tail strategy: pick largest cell and cut toward the highest need size\n            auto &idxs = cells[cands[0].second];\n            int s = (int)idxs.size();\n            int target = 1;\n            int bestNeed=0;\n            for(int d=1; d<=10; ++d){ if(need[d]>bestNeed){ bestNeed=need[d]; target=d; } }\n            int l = min(max(1, target), s-1);\n            // Use PCA-derived or x-axis if not available\n            int A=1,B=0;\n            // try x first\n            proj.resize(s);\n            for(int i=0;i<s;++i) proj[i] = pts[idxs[i]].x;\n            sort(proj.begin(), proj.end());\n            long long vL = proj[l-1], vR = proj[l];\n            if(vL == vR){\n                // fallback to y\n                for(int i=0;i<s;++i) proj[i] = pts[idxs[i]].y;\n                sort(proj.begin(), proj.end());\n                vL = proj[l-1]; vR = proj[l];\n                if(vL==vR){\n                    // use slight shift in l\n                    int i = l-1;\n                    while(i>0 && proj[i-1]==proj[i]) --i;\n                    l = i;\n                    vL = proj[l-1]; vR = proj[l];\n                    if(l<=0){ // final fallback: median\n                        l = s/2; vL=proj[l-1]; vR=proj[l];\n                    }\n                }else{\n                    A=0; B=1;\n                }\n            }\n            long long T = (vL + vR) / 2;\n            bestLine = {A,B,T};\n        }\n\n        // Commit line\n        int bitIndex = (int)lines.size();\n        lines.push_back(bestLine);\n        for(int i=0;i<N;++i){\n            long long v = dotAB(bestLine.A, bestLine.B, pts[i].x, pts[i].y);\n            bool left = (v <= bestLine.T);\n            if(bitIndex < 64){\n                if(left) sig[i].a |= (1ULL<<bitIndex);\n            }else{\n                int bi = bitIndex-64;\n                if(left) sig[i].b |= (1ULL<<bi);\n            }\n        }\n        recompute();\n        cutsLeft--;\n    }\n\n    // Output\n    cout << (int)lines.size() << \"\\n\";\n    for(auto &L : lines){\n        auto pp = two_points_on_line(L.A, L.B, L.T);\n        auto [p0, p1] = pp;\n        cout << p0.first << \" \" << p0.second << \" \" << p1.first << \" \" << p1.second << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct P { int x,y; };\n\nstatic inline int64_t w_of(int x,int y,int c){\n    int dx=x-c, dy=y-c;\n    return int64_t(dx)*dx + int64_t(dy)*dy + 1;\n}\n\nstruct Candidate{\n    // rectangle in order: p1=new point, then others around perimeter\n    P p1,p2,p3,p4;\n    int64_t score;\n};\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    vector<P> init(M);\n    for(int i=0;i<M;i++){ cin>>init[i].x>>init[i].y; }\n    int c=(N-1)/2;\n\n    // Occupancy grid\n    vector<vector<char>> occ(N, vector<char>(N, 0));\n    for(auto &p:init) occ[p.x][p.y]=1;\n\n    // Edge usage: used horizontal edges H[y][x] for (x,y)-(x+1,y), x in [0..N-2], y in [0..N-1]\n    vector<vector<char>> usedH(N, vector<char>(N-1, 0));\n    // Vertical edges V[x][y] for (x,y)-(x,y+1), x in [0..N-1], y in [0..N-2]\n    vector<vector<char>> usedV(N, vector<char>(N-1, 0));\n\n    // Maintain list of occupied points per row/col for faster enumeration\n    vector<vector<int>> rows(N), cols(N);\n    auto rebuild_index = [&](){\n        for(int y=0;y<N;y++){ rows[y].clear(); }\n        for(int x=0;x<N;x++){ cols[x].clear(); }\n        for(int x=0;x<N;x++) for(int y=0;y<N;y++) if(occ[x][y]){\n            rows[y].push_back(x);\n            cols[x].push_back(y);\n        }\n        for(int y=0;y<N;y++) sort(rows[y].begin(), rows[y].end());\n        for(int x=0;x<N;x++) sort(cols[x].begin(), cols[x].end());\n    };\n    rebuild_index();\n\n    // Candidate generation full enumeration (axis-aligned):\n    auto build_candidates = [&](vector<Candidate>& out){\n        out.clear();\n        const size_t CAP = 40000;\n        for(int xb=0; xb<N; xb++){\n            for(int yb=0; yb<N; yb++){\n                if(!occ[xb][yb]) continue;\n                const auto& row = rows[yb];\n                const auto& col = cols[xb];\n                if(row.empty() || col.empty()) continue;\n                for(int xa : row){\n                    if(xa==xb) continue;\n                    for(int yc : col){\n                        if(yc==yb) continue;\n                        int xd = xa;\n                        int yd = yc;\n                        if(occ[xd][yd]) continue;\n                        // define rectangle order p1=D, p2=A, p3=B, p4=C:\n                        P D{xd,yd}, A{xa,yb}, B{xb,yb}, C{xb,yc};\n                        // perimeter dot check\n                        auto ok_line = [&](int x1,int y1,int x2,int y2)->bool{\n                            if(x1==x2){\n                                int x=x1;\n                                int ylo=min(y1,y2), yhi=max(y1,y2);\n                                for(int y=ylo; y<=yhi; y++){\n                                    if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                                    if(occ[x][y]) return false;\n                                }\n                            }else if(y1==y2){\n                                int y=y1;\n                                int xlo=min(x1,x2), xhi=max(x1,x2);\n                                for(int x=xlo; x<=xhi; x++){\n                                    if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                                    if(occ[x][y]) return false;\n                                }\n                            }else{\n                                return false;\n                            }\n                            return true;\n                        };\n                        if(!ok_line(D.x,D.y,A.x,A.y)) continue;\n                        if(!ok_line(A.x,A.y,B.x,B.y)) continue;\n                        if(!ok_line(B.x,B.y,C.x,C.y)) continue;\n                        if(!ok_line(C.x,C.y,D.x,D.y)) continue;\n                        // edge overlap check without marking now\n                        auto edges_free = [&]()->bool{\n                            auto check_edge = [&](int x1,int y1,int x2,int y2)->bool{\n                                if(x1==x2){\n                                    int x=x1;\n                                    int ylo=min(y1,y2), yhi=max(y1,y2);\n                                    for(int y=ylo; y<yhi; y++) if(usedV[x][y]) return false;\n                                }else{\n                                    int y=y1;\n                                    int xlo=min(x1,x2), xhi=max(x1,x2);\n                                    for(int x=xlo; x<xhi; x++) if(usedH[y][x]) return false;\n                                }\n                                return true;\n                            };\n                            return check_edge(D.x,D.y,A.x,A.y) && check_edge(A.x,A.y,B.x,B.y)\n                                && check_edge(B.x,B.y,C.x,C.y) && check_edge(C.x,C.y,D.x,D.y);\n                        };\n                        if(!edges_free()) continue;\n                        Candidate cand;\n                        cand.p1=D; cand.p2=A; cand.p3=B; cand.p4=C;\n                        cand.score = w_of(D.x,D.y,c);\n                        out.push_back(cand);\n                        if(out.size() >= CAP) return;\n                    }\n                }\n            }\n        }\n    };\n\n    vector<array<int,8>> answer;\n    answer.reserve(100000);\n\n    auto apply_rect = [&](const Candidate& cand){\n        const P &D=cand.p1, &A=cand.p2, &B=cand.p3, &C=cand.p4;\n        // Mark edges\n        auto mark_edge = [&](int x1,int y1,int x2,int y2){\n            if(x1==x2){\n                int x=x1;\n                int ylo=min(y1,y2), yhi=max(y1,y2);\n                for(int y=ylo; y<yhi; y++) usedV[x][y]=1;\n            }else{\n                int y=y1;\n                int xlo=min(x1,x2), xhi=max(x1,x2);\n                for(int x=xlo; x<xhi; x++) usedH[y][x]=1;\n            }\n        };\n        mark_edge(D.x,D.y,A.x,A.y);\n        mark_edge(A.x,A.y,B.x,B.y);\n        mark_edge(B.x,B.y,C.x,C.y);\n        mark_edge(C.x,C.y,D.x,D.y);\n        // Place dot\n        occ[D.x][D.y]=1;\n        rows[D.y].push_back(D.x);\n        cols[D.x].push_back(D.y);\n        // Record\n        array<int,8> op = {D.x,D.y, A.x,A.y, B.x,B.y, C.x,C.y};\n        answer.push_back(op);\n    };\n\n    // Main greedy loop\n    auto t_start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.8; // seconds\n    int iter = 0;\n    while(true){\n        if(iter % 10 == 0){\n            auto t_now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(t_now - t_start).count();\n            if(elapsed > TIME_LIMIT) break;\n        }\n        if(iter % 50 == 0) rebuild_index();\n\n        vector<Candidate> cands;\n        build_candidates(cands);\n        if(cands.empty()) break;\n        // sort by score descending, minor tiebreaker by perimeter length\n        stable_sort(cands.begin(), cands.end(), [&](const Candidate& a, const Candidate& b){\n            if(a.score != b.score) return a.score > b.score;\n            int per_a = abs(a.p1.x - a.p3.x) + abs(a.p1.y - a.p3.y) + abs(a.p2.x - a.p4.x) + abs(a.p2.y - a.p4.y);\n            int per_b = abs(b.p1.x - b.p3.x) + abs(b.p1.y - b.p3.y) + abs(b.p2.x - b.p4.x) + abs(b.p2.y - b.p4.y);\n            return per_a > per_b;\n        });\n        bool placed = false;\n        for(const auto& cand : cands){\n            const P &D=cand.p1, &A=cand.p2, &B=cand.p3, &C=cand.p4;\n            if(occ[D.x][D.y]) continue;\n            // recheck perimeter cleanliness and edges\n            auto ok_line = [&](int x1,int y1,int x2,int y2)->bool{\n                if(x1==x2){\n                    int x=x1;\n                    int ylo=min(y1,y2), yhi=max(y1,y2);\n                    for(int y=ylo; y<=yhi; y++){\n                        if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                        if(occ[x][y]) return false;\n                    }\n                }else if(y1==y2){\n                    int y=y1;\n                    int xlo=min(x1,x2), xhi=max(x1,x2);\n                    for(int x=xlo; x<=xhi; x++){\n                        if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                        if(occ[x][y]) return false;\n                    }\n                }else{\n                    return false;\n                }\n                return true;\n            };\n            if(!ok_line(D.x,D.y,A.x,A.y)) continue;\n            if(!ok_line(A.x,A.y,B.x,B.y)) continue;\n            if(!ok_line(B.x,B.y,C.x,C.y)) continue;\n            if(!ok_line(C.x,C.y,D.x,D.y)) continue;\n\n            auto edges_free = [&]()->bool{\n                auto check_edge = [&](int x1,int y1,int x2,int y2)->bool{\n                    if(x1==x2){\n                        int x=x1;\n                        int ylo=min(y1,y2), yhi=max(y1,y2);\n                        for(int y=ylo; y<yhi; y++) if(usedV[x][y]) return false;\n                    }else{\n                        int y=y1;\n                        int xlo=min(x1,x2), xhi=max(x1,x2);\n                        for(int x=xlo; x<xhi; x++) if(usedH[y][x]) return false;\n                    }\n                    return true;\n                };\n                return check_edge(D.x,D.y,A.x,A.y) && check_edge(A.x,A.y,B.x,B.y)\n                    && check_edge(B.x,B.y,C.x,C.y) && check_edge(C.x,C.y,D.x,D.y);\n            };\n            if(!edges_free()) continue;\n\n            apply_rect(cand);\n            placed = true;\n            break;\n        }\n        if(!placed) break;\n        iter++;\n    }\n\n    cout<< (int)answer.size() << \"\\n\";\n    for(auto &op: answer){\n        for(int i=0;i<8;i++){\n            if(i) cout<<' ';\n            cout<<op[i];\n        }\n        cout<<\"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Board {\n    static constexpr int H=10, W=10;\n    array<array<int,W>,H> g{};\n    void clear(){ for(int i=0;i<H;i++) for(int j=0;j<W;j++) g[i][j]=0; }\n\n    pair<int,int> place_by_index(int p, int f){\n        int cnt=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                if(g[i][j]==0){\n                    ++cnt;\n                    if(cnt==p){\n                        g[i][j]=f;\n                        return {i,j};\n                    }\n                }\n            }\n        }\n        return {-1,-1};\n    }\n\n    Board tilt(char dir) const {\n        Board b=*this;\n        if(dir=='F'){ // up\n            for(int j=0;j<W;j++){\n                int w=0;\n                for(int i=0;i<H;i++){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        if(i!=w){ b.g[i][j]=0; b.g[w][j]=v; }\n                        ++w;\n                    }\n                }\n            }\n        } else if(dir=='B'){ // down\n            for(int j=0;j<W;j++){\n                int w=H-1;\n                for(int i=H-1;i>=0;i--){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        if(i!=w){ b.g[i][j]=0; b.g[w][j]=v; }\n                        --w;\n                    }\n                }\n            }\n        } else if(dir=='L'){ // left\n            for(int i=0;i<H;i++){\n                int w=0;\n                for(int j=0;j<W;j++){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        if(j!=w){ b.g[i][j]=0; b.g[i][w]=v; }\n                        ++w;\n                    }\n                }\n            }\n        } else { // 'R' right\n            for(int i=0;i<H;i++){\n                int w=W-1;\n                for(int j=W-1;j>=0;j--){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        if(j!=w){ b.g[i][j]=0; b.g[i][w]=v; }\n                        --w;\n                    }\n                }\n            }\n        }\n        return b;\n    }\n\n    bool equals(const Board& o) const {\n        for(int i=0;i<H;i++) for(int j=0;j<W;j++) if(g[i][j]!=o.g[i][j]) return false;\n        return true;\n    }\n};\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    DSU(int n=0): n(n), p(n), r(n,0){ iota(p.begin(), p.end(), 0); }\n    int find(int a){ return p[a]==a?a:p[a]=find(p[a]); }\n    void unite(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a; if(r[a]==r[b]) r[a]++;\n    }\n};\n\nstruct Heuristic {\n    array<pair<int,int>,4> anchor;\n    array<array<int,4>,4> edgePref{}; // preferred edges [T,B,L,R]\n\n    // weights (rebalanced)\n    int w_adj_same = 7;\n    int w_adj_diff = 2;\n    int w_dist = 1;\n    int w_boundaries = 2;   // smaller than before\n    int w_cc = 16;          // strong, but single metric for fragmentation\n    int w_edge = 2;\n    int w_corner = 1;\n    int w_line_seg = 2;\n\n    Heuristic(){\n        anchor[1]={0,0};\n        anchor[2]={0,9};\n        anchor[3]={9,0};\n        edgePref[1]={1,0,1,0};\n        edgePref[2]={1,0,0,1};\n        edgePref[3]={0,1,1,0};\n    }\n\n    void setup_anchors_by_counts_and_early(const array<int,4>& cnt, const vector<int>& early){\n        // Sort by total counts\n        array<int,3> ids = {1,2,3};\n        sort(ids.begin(), ids.end(), [&](int a,int b){ return cnt[a]>cnt[b]; });\n        int A=ids[0], B=ids[1], C=ids[2];\n        // Assign A->top-left, B->top-right\n        anchor[A]={0,0}; edgePref[A]={1,0,1,0};\n        anchor[B]={0,9}; edgePref[B]={1,0,0,1};\n        // Decide bottom side for C based on early stream bias of A vs B\n        int earlyTake = min<int>(20, early.size());\n        int earlyA=0, earlyB=0;\n        for(int i=0;i<earlyTake;i++){\n            if(early[i]==A) earlyA++;\n            else if(early[i]==B) earlyB++;\n        }\n        // Place C far from the more frequent early top-corner flavor\n        if(earlyB > earlyA){\n            // B (top-right) appears more early -> use bottom-left to avoid right side congestion\n            anchor[C]={9,0}; edgePref[C]={0,1,1,0};\n        }else{\n            anchor[C]={9,9}; edgePref[C]={0,1,0,1};\n        }\n    }\n\n    int adj_score(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int same=0, diff=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                if(i+1<H && b.g[i+1][j]){\n                    if(b.g[i+1][j]==v) same++; else diff++;\n                }\n                if(j+1<W && b.g[i][j+1]){\n                    if(b.g[i][j+1]==v) same++; else diff++;\n                }\n            }\n        }\n        return w_adj_same*same - w_adj_diff*diff;\n    }\n\n    int distance_score(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                auto [ai,aj]=anchor[v];\n                sc -= w_dist * (abs(i-ai)+abs(j-aj));\n                int d = abs(i-ai)+abs(j-aj);\n                if(d<=2) sc += w_corner*(3-d);\n            }\n        }\n        return sc;\n    }\n\n    int boundaries_penalty(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int boundaries=0;\n        for(int i=0;i<H;i++){\n            int prev = 0;\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(prev && v && v!=prev) boundaries++;\n                if(v) prev=v;\n            }\n        }\n        for(int j=0;j<W;j++){\n            int prev = 0;\n            for(int i=0;i<H;i++){\n                int v=b.g[i][j];\n                if(prev && v && v!=prev) boundaries++;\n                if(v) prev=v;\n            }\n        }\n        return -w_boundaries * boundaries;\n    }\n\n    int cc_penalty(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int F=H*W;\n        DSU dsu(F);\n        auto id = [&](int i,int j){ return i*W + j; };\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                if(i+1<H && b.g[i+1][j]==v) dsu.unite(id(i,j), id(i+1,j));\n                if(j+1<W && b.g[i][j+1]==v) dsu.unite(id(i,j), id(i,j+1));\n            }\n        }\n        array<unordered_set<int>,4> reps;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                reps[v].insert(dsu.find(id(i,j)));\n            }\n        }\n        int cc = (int)reps[1].size() + (int)reps[2].size() + (int)reps[3].size();\n        return -w_cc * cc;\n    }\n\n    int edge_reward(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                auto pref = edgePref[v];\n                if(i==0) sc += w_edge * pref[0];\n                if(i==H-1) sc += w_edge * pref[1];\n                if(j==0) sc += w_edge * pref[2];\n                if(j==W-1) sc += w_edge * pref[3];\n            }\n        }\n        return sc;\n    }\n\n    int line_segment_reward(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        // rows\n        for(int i=0;i<H;i++){\n            int len=0, col=0;\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(v && v==col) len++;\n                else{\n                    if(col && len>=2) sc += w_line_seg * (len-1);\n                    col=v; len = (v?1:0);\n                }\n            }\n            if(col && len>=2) sc += w_line_seg * (len-1);\n        }\n        // cols\n        for(int j=0;j<W;j++){\n            int len=0, col=0;\n            for(int i=0;i<H;i++){\n                int v=b.g[i][j];\n                if(v && v==col) len++;\n                else{\n                    if(col && len>=2) sc += w_line_seg * (len-1);\n                    col=v; len = (v?1:0);\n                }\n            }\n            if(col && len>=2) sc += w_line_seg * (len-1);\n        }\n        return sc;\n    }\n\n    int score(const Board& b) const {\n        int s=0;\n        s += adj_score(b);\n        s += distance_score(b);\n        s += boundaries_penalty(b);\n        s += cc_penalty(b);\n        s += edge_reward(b);\n        s += line_segment_reward(b);\n        // tiny deterministic tie-breaker\n        uint32_t h=2166136261u;\n        for(int i=0;i<Board::H;i++) for(int j=0;j<Board::W;j++){\n            h ^= uint32_t(b.g[i][j]+1); h *= 16777619u;\n        }\n        s += int(h%3)-1;\n        return s;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> f(100);\n    for(int i=0;i<100;i++){\n        if(!(cin>>f[i])) return 0;\n    }\n    array<int,4> cnt{}; cnt.fill(0);\n    for(int x: f) cnt[x]++;\n\n    Board board; board.clear();\n    Heuristic H;\n    // Use first 20 arrivals to adapt bottom side selection\n    vector<int> early = f;\n    H.setup_anchors_by_counts_and_early(cnt, early);\n\n    const array<char,4> dirs = {'F','B','L','R'};\n    char lastMove = 'F';\n\n    for(int t=0;t<100;t++){\n        int p;\n        if(!(cin>>p)) return 0;\n        board.place_by_index(p, f[t]);\n\n        if(t==99){\n            // skip final tilt\n            continue;\n        }\n\n        int bestScore = INT_MIN;\n        char bestDir = 'F';\n        Board bestBoard = board;\n\n        // 2-ply with a bit stronger immediate term\n        for(char d1 : dirs){\n            Board b1 = board.tilt(d1);\n            int s1 = H.score(b1);\n            int bestSecond = INT_MIN;\n            for(char d2 : dirs){\n                Board b2 = b1.tilt(d2);\n                int s2 = H.score(b2);\n                if(s2 > bestSecond) bestSecond = s2;\n            }\n            int combined = bestSecond + s1/4; // stronger immediate term than before\n            if(b1.equals(board)) combined -= 1; // avoid pure no-op unless best\n            if(d1==lastMove) combined += 0;     // no momentum, but neutral tie\n\n            if(combined > bestScore || (combined==bestScore && d1==lastMove)){\n                bestScore = combined;\n                bestDir = d1;\n                bestBoard = b1;\n            }\n        }\n\n        cout << bestDir << '\\n' << flush;\n        lastMove = bestDir;\n        board = bestBoard;\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\n\nusing ull = unsigned long long;\n\nstruct XorShift64 {\n    uint64_t x;\n    XorShift64(uint64_t s=88172645463393265ull){ if(!s) s=1; x=s; }\n    uint64_t rng(){ uint64_t y=x; y^=y<<7; y^=y>>9; return x=y; }\n    double drand(){ return (rng() >> 11) * (1.0/9007199254740992.0); } // [0,1)\n    int irand(int L,int R){ return L + (int)(rng() % (uint64_t)(R-L+1)); }\n};\n\nstatic inline int idx_pair(int N,int i,int j){ // i<j\n    return i*N - i*(i+1)/2 + (j - i - 1);\n}\n\nstruct Features {\n    vector<double> deg_hist;      // size N normalized\n    vector<int> deg_sorted;       // size N\n    vector<double> deg_buckets;   // size DB (e.g., 16)\n    vector<double> eigA;          // top T eigenvalues of adjacency\n    vector<double> eigL;          // top T eigenvalues of Laplacian\n    vector<double> nbrdeg_hist;   // histogram of neighbor-degree sums\n    vector<double> nbr_deg_buck;  // histogram of neighbor degree buckets\n};\n\nstruct TemplateG {\n    vector<uint8_t> bits; // length N(N-1)/2\n    vector<int> deg;\n    Features feat;\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double eps;\n    if(!(cin>>M>>eps)) return 0;\n\n    // Adaptive N by eps\n    int N;\n    if (eps <= 0.06) N = 40;\n    else if (eps <= 0.18) N = 56;\n    else if (eps <= 0.30) N = 72;\n    else N = 88;\n\n    // Slight adjust by M: if many templates and low eps, can reduce N a bit\n    if (M >= 90 && eps <= 0.06) N = 36;\n    if (N < 4) N = 4;\n    if (N > 100) N = 100;\n\n    // Deterministic seed from M and eps\n    uint64_t seed = 1469598103934665603ull ^ (uint64_t)M * 1099511628211ull ^ (uint64_t)llround(eps*100.0+0.5);\n    XorShift64 gen(seed);\n\n    // Blocks for SBM-like graph generation\n    int B = 4;\n    vector<int> block(N);\n    for(int i=0;i<N;i++) block[i] = (long long)i * B / N;\n\n    auto add_backbone = [&](vector<uint8_t>& bits, int k){\n        // Add a sparse backbone 8-cycle over evenly spaced vertices and a few chords\n        if (N < 10) return;\n        int step = max(1, N / 8);\n        vector<int> cyc;\n        cyc.reserve(8);\n        int pos = (k*7 + 3) % N;\n        for(int t=0;t<8;t++){\n            cyc.push_back(pos);\n            pos = (pos + step) % N;\n        }\n        for(int t=0;t<8;t++){\n            int u = cyc[t];\n            int v = cyc[(t+1)%8];\n            if (u==v) continue;\n            int i=min(u,v), j=max(u,v);\n            bits[idx_pair(N,i,j)] = 1;\n        }\n        // chords depending on k\n        for(int t=0;t<4;t++){\n            int u = cyc[t];\n            int widx = (t+2 + (k+t)%3) % 8;\n            int v = cyc[widx];\n            if (u==v) continue;\n            int i=min(u,v), j=max(u,v);\n            bits[idx_pair(N,i,j)] = 1;\n        }\n    };\n\n    auto compute_features = [&](const vector<uint8_t>& bits)->pair<vector<int>, Features>{\n        Eigen::MatrixXd A(N, N);\n        A.setZero();\n        vector<int> deg(N,0);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                uint8_t v = bits[idx_pair(N,i,j)];\n                if(v){\n                    A(i,j)=A(j,i)=1.0;\n                    deg[i]++; deg[j]++;\n                }\n            }\n        }\n\n        // degree features\n        vector<double> dh(N, 0.0);\n        for(int d:deg) dh[d] += 1.0;\n        for(double &x:dh) x /= N;\n\n        vector<int> dsort = deg;\n        sort(dsort.begin(), dsort.end());\n\n        // degree buckets\n        const int DB = 16;\n        vector<double> db(DB, 0.0);\n        int dmax = 0;\n        for(int d:deg) dmax = max(dmax, d);\n        int span = max(1, dmax+1);\n        for(int d:deg){\n            int b = d * DB / span;\n            if(b>=DB) b=DB-1;\n            db[b] += 1.0;\n        }\n        for(double &x:db) x/=N;\n\n        // neighbor degree sums and neighbor degree bucket histogram\n        vector<int> degNbrSum(N,0);\n        vector<int> nbrDegCounts(DB, 0);\n        for(int i=0;i<N;i++){\n            int s=0;\n            for(int j=0;j<N;j++) if (A(i,j)>0.5) {\n                s += deg[j];\n                int b = deg[j] * DB / span;\n                if(b>=DB) b=DB-1;\n                nbrDegCounts[b] += 1;\n            }\n            degNbrSum[i]=s;\n        }\n        int Hbins = 16;\n        int minv = *min_element(degNbrSum.begin(), degNbrSum.end());\n        int maxv = *max_element(degNbrSum.begin(), degNbrSum.end());\n        if (maxv==minv) maxv=minv+1;\n        vector<double> ndh(Hbins,0.0);\n        for(int v:degNbrSum){\n            int b = (int)((long long)(v - minv) * Hbins / (long long)(maxv - minv + 1));\n            if(b<0) b=0;\n            if(b>=Hbins) b=Hbins-1;\n            ndh[b] += 1.0;\n        }\n        for(double &x:ndh) x/=N;\n\n        vector<double> ndb(DB, 0.0);\n        double totNbr = 0.0;\n        for(int b=0;b<DB;b++) totNbr += nbrDegCounts[b];\n        if (totNbr < 1.0) totNbr = 1.0;\n        for(int b=0;b<DB;b++) ndb[b] = nbrDegCounts[b] / totNbr;\n\n        // Spectra: adjacency and Laplacian\n        int Ttop = min(16, N);\n        vector<double> eigA, eigL;\n        eigA.reserve(Ttop); eigL.reserve(Ttop);\n        // adjacency\n        {\n            Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(A);\n            if (es.info() == Eigen::Success) {\n                auto evals = es.eigenvalues(); // ascending\n                vector<double> all(N);\n                for(int i=0;i<N;i++) all[i] = evals(i);\n                vector<int> idx(N); iota(idx.begin(), idx.end(), 0);\n                sort(idx.begin(), idx.end(), [&](int a,int b){\n                    return fabs(all[a]) > fabs(all[b]);\n                });\n                int maxdeg = 1;\n                for(int d:deg) if(d>maxdeg) maxdeg=d;\n                double scale = sqrt((double)maxdeg);\n                if(scale == 0.0) scale = 1.0;\n                for(int t=0;t<Ttop;t++){\n                    eigA.push_back(all[idx[t]] / scale);\n                }\n            } else {\n                eigA.assign(Ttop, 0.0);\n            }\n        }\n        // Laplacian L = D - A\n        {\n            Eigen::MatrixXd L = -A;\n            for(int i=0;i<N;i++) L(i,i) += deg[i];\n            Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(L);\n            if (es.info() == Eigen::Success) {\n                auto evals = es.eigenvalues(); // ascending\n                vector<double> all(N);\n                for(int i=0;i<N;i++) all[i] = evals(i);\n                vector<int> idx(N); iota(idx.begin(), idx.end(), 0);\n                sort(idx.begin(), idx.end(), [&](int a,int b){\n                    return fabs(all[a]) > fabs(all[b]);\n                });\n                double scale = sqrt( max(1, *max_element(deg.begin(), deg.end())) );\n                if (scale == 0.0) scale = 1.0;\n                for(int t=0;t<Ttop;t++){\n                    eigL.push_back(all[idx[t]] / scale);\n                }\n            } else {\n                eigL.assign(Ttop, 0.0);\n            }\n        }\n\n        Features F;\n        F.deg_hist = move(dh);\n        F.deg_sorted = move(dsort);\n        F.deg_buckets = move(db);\n        F.eigA = move(eigA);\n        F.eigL = move(eigL);\n        F.nbrdeg_hist = move(ndh);\n        F.nbr_deg_buck = move(ndb);\n        return {deg, F};\n    };\n\n    // Build templates and features\n    vector<TemplateG> temps(M);\n    for(int k=0;k<M;k++){\n        // Randomly remap block labels for diversity\n        XorShift64 g(seed ^ (uint64_t)(0x9e3779b97f4a7c15ull * (k+1)));\n        array<int,4> mapB = {0,1,2,3};\n        for(int i=0;i<4;i++){ int j = g.irand(0,3); swap(mapB[i], mapB[j]); }\n        vector<int> blk(N);\n        for(int i=0;i<N;i++) blk[i] = mapB[ block[i] ];\n\n        // Create P matrix with enhanced diagonal/off-diagonal contrast varying per k\n        double base = 0.25 + 0.4 * ( (k*0.1234567) - floor(k*0.1234567) );\n        double diag_boost = 0.20 + 0.15 * (g.drand());\n        double off_var = 0.15 + 0.10 * (g.drand());\n        vector<vector<double>> P(B, vector<double>(B, 0.0));\n        for(int b=0;b<B;b++){\n            for(int c=b;c<B;c++){\n                double val = base + off_var * (g.drand()-0.5);\n                if (b==c) val = base + diag_boost * (g.drand()-0.5) + 0.35;\n                val = min(0.98, max(0.02, val));\n                P[b][c]=P[c][b]=val;\n            }\n        }\n        vector<double> biasB(B);\n        for(int b=0;b<B;b++) biasB[b] = (g.drand()-0.5)*0.25;\n\n        int Ebits = N*(N-1)/2;\n        vector<uint8_t> bits(Ebits, 0);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                int bi = blk[i], bj = blk[j];\n                double p = P[bi][bj];\n                double vbi = biasB[bi] + 0.06 * sin((i+1)*(k+3)*0.13);\n                double vbj = biasB[bj] + 0.06 * cos((j+3)*(k+5)*0.17);\n                double adjp = p + 0.15*(vbi+vbj);\n                if(adjp < 0.01) adjp = 0.01;\n                if(adjp > 0.99) adjp = 0.99;\n                if (g.drand() < adjp){\n                    bits[idx_pair(N,i,j)] = 1;\n                }\n            }\n        }\n        // Superimpose backbone\n        add_backbone(bits, k);\n\n        // Compute features (also computes degrees)\n        auto [deg, F] = compute_features(bits);\n        temps[k].bits = move(bits);\n        temps[k].deg = move(deg);\n        temps[k].feat = move(F);\n    }\n\n    auto dist_deg_fast = [&](const Features& A, const Features& B)->double{\n        double s=0.0;\n        for(size_t i=0;i<A.deg_buckets.size();i++){\n            double d=A.deg_buckets[i]-B.deg_buckets[i];\n            s += d*d;\n        }\n        double t=0.0;\n        for(size_t i=0;i<A.deg_sorted.size();i++){\n            t += abs(A.deg_sorted[i]-B.deg_sorted[i]);\n        }\n        t /= (double)A.deg_sorted.size();\n        double u=0.0;\n        for(size_t i=0;i<A.nbr_deg_buck.size();i++){\n            double d = A.nbr_deg_buck[i]-B.nbr_deg_buck[i];\n            u += d*d;\n        }\n        u = sqrt(u);\n        return 0.55*sqrt(s) + 0.30*t + 0.15*u;\n    };\n\n    auto dist_full = [&](const Features& A, const Features& B)->double{\n        auto l2 = [](const vector<double>& x, const vector<double>& y){\n            double s=0; size_t n=min(x.size(), y.size());\n            for(size_t i=0;i<n;i++){ double d=x[i]-y[i]; s+=d*d; }\n            return sqrt(s);\n        };\n        auto l1sorted = [](const vector<int>& x, const vector<int>& y){\n            double s=0; size_t n=min(x.size(), y.size());\n            for(size_t i=0;i<n;i++){ s += abs(x[i]-y[i]); }\n            return s / (double)n;\n        };\n        double d_deg_hist = l2(A.deg_hist, B.deg_hist);\n        double d_deg_buck = l2(A.deg_buckets, B.deg_buckets);\n        double d_nbr_sum  = l2(A.nbrdeg_hist, B.nbrdeg_hist);\n        double d_nbr_buck = l2(A.nbr_deg_buck, B.nbr_deg_buck);\n        double d_eigA     = l2(A.eigA, B.eigA);\n        double d_eigL     = l2(A.eigL, B.eigL);\n        double d_sorted   = l1sorted(A.deg_sorted, B.deg_sorted);\n        // weights tuned coarsely\n        return 0.18*d_deg_hist + 0.20*d_deg_buck + 0.15*d_nbr_sum + 0.07*d_nbr_buck\n             + 0.22*d_eigA + 0.10*d_eigL + 0.08*d_sorted;\n    };\n\n    // Output templates\n    cout<<N<<\"\\n\";\n    for(int k=0;k<M;k++){\n        int L = N*(N-1)/2;\n        string s; s.resize(L);\n        for(int i=0;i<L;i++) s[i] = temps[k].bits[i] ? '1':'0';\n        cout<<s<<\"\\n\";\n    }\n    cout.flush();\n\n    // Answer queries\n    for(int q=0;q<100;q++){\n        string Hs;\n        if(!(cin>>Hs)) return 0;\n        int L = N*(N-1)/2;\n        vector<uint8_t> Hbits(L,0);\n        for(int i=0;i<L;i++) Hbits[i] = (Hs[i]=='1');\n        auto [Hdeg, HF] = compute_features(Hbits);\n\n        int S = (eps >= 0.25 ? min(20, M) : min(12, M));\n        vector<pair<double,int>> cand;\n        cand.reserve(M);\n        for(int k=0;k<M;k++){\n            double d = dist_deg_fast(HF, temps[k].feat);\n            cand.emplace_back(d, k);\n        }\n        nth_element(cand.begin(), cand.begin()+S, cand.end());\n        cand.resize(S);\n\n        int bestk = cand[0].second;\n        double bestd = 1e100;\n        for(auto &pr : cand){\n            int k = pr.second;\n            double d = dist_full(HF, temps[k].feat);\n            if(d < bestd){\n                bestd = d; bestk = k;\n            }\n        }\n        cout<<bestk<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge { int id, u, v; int w; };\nstruct Adj { int to, eid, w; };\n\nstruct Timer {\n    chrono::high_resolution_clock::time_point st;\n    Timer(){ reset(); }\n    void reset(){ st = chrono::high_resolution_clock::now(); }\n    double ms() const { return chrono::duration<double, std::milli>(chrono::high_resolution_clock::now()-st).count(); }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Timer timer;\n    int N,M,D,K;\n    if(!(cin>>N>>M>>D>>K)) return 0;\n    vector<Edge> edges(M);\n    for(int i=0;i<M;++i){\n        int u,v,w; cin>>u>>v>>w; --u;--v; edges[i]={i,u,v,w};\n    }\n    vector<pair<int,int>> coords(N);\n    for(int i=0;i<N;++i){ int x,y; cin>>x>>y; coords[i]={x,y}; }\n\n    vector<vector<Adj>> g(N);\n    vector<int> deg(N,0);\n    for(auto &e: edges){\n        g[e.u].push_back({e.v,e.id,e.w});\n        g[e.v].push_back({e.u,e.id,e.w});\n        deg[e.u]++; deg[e.v]++;\n    }\n\n    // Basic importance components\n    long long wmin=LLONG_MAX,wmax=0;\n    for(auto &e: edges){ wmin=min<long long>(wmin,e.w); wmax=max<long long>(wmax,e.w); }\n    double denom_w = (wmax>wmin? double(wmax-wmin):1.0);\n    vector<double> imp_w(M), imp_deg(M);\n    for(auto &e: edges) imp_w[e.id] = (double)(e.w - wmin)/denom_w;\n    for(auto &e: edges){\n        double pu = 1.0 / max(1,deg[e.u]-1);\n        double pv = 1.0 / max(1,deg[e.v]-1);\n        imp_deg[e.id] = 0.5*(pu+pv);\n    }\n\n    // Prepare betweenness-like via sampled shortest paths and co-occurrence\n    mt19937 rng(20250915);\n    vector<int> nodes(N); iota(nodes.begin(), nodes.end(), 0);\n    shuffle(nodes.begin(), nodes.end(), rng);\n\n    int S = 28; if(N<=900) S=26; if(N<=750) S=24; if(N<=600) S=22; if(N<=500) S=20; S = min(S, max(16, N/45));\n    int T = 18; if(N<800) T=16; if(N<650) T=14; if(N<520) T=12;\n\n    vector<long long> dist(N);\n    vector<int> parent_edge(N,-1);\n    struct QN{ long long d; int v; };\n    struct Cmp{ bool operator()(const QN&a,const QN&b)const{return a.d>b.d;}};\n    vector<long long> bet_count(M,0);\n\n    // Keep top-L co-occurring edges per edge with counts\n    const int L = 24;\n    vector<unordered_map<int,int>> co_occur(M);\n    auto push_co = [&](int e1,int e2){\n        if(e1==e2) return;\n        auto &mp = co_occur[e1];\n        auto it = mp.find(e2);\n        if(it!=mp.end()){ it->second++; return; }\n        if((int)mp.size() < L){ mp.emplace(e2,1); return; }\n        // replace lowest\n        int min_k=-1, min_v=INT_MAX;\n        for(auto &kv: mp) if(kv.second < min_v){ min_v=kv.second; min_k=kv.first; }\n        if(min_v <= 1){ mp.erase(min_k); mp.emplace(e2,1); }\n        else {\n            // probabilistic replace to diversify\n            if((rng() & 7)==0){ mp.erase(min_k); mp.emplace(e2,1); }\n        }\n    };\n\n    vector<int> target_list; target_list.reserve(T);\n    vector<int> path_edges; path_edges.reserve(N);\n\n    for(int si=0; si<S && si<N; ++si){\n        if(timer.ms() > 2500.0) break;\n        int s = nodes[si];\n        // Dijkstra\n        fill(dist.begin(), dist.end(), (long long)4e18);\n        fill(parent_edge.begin(), parent_edge.end(), -1);\n        priority_queue<QN, vector<QN>, Cmp> pq;\n        dist[s]=0; pq.push({0,s});\n        while(!pq.empty()){\n            auto [d,v]=pq.top(); pq.pop();\n            if(d!=dist[v]) continue;\n            for(auto &ae: g[v]){\n                int to=ae.to; long long nd=d+ae.w;\n                if(nd<dist[to]){\n                    dist[to]=nd; parent_edge[to]=ae.eid; pq.push({nd,to});\n                }\n            }\n        }\n        for(int v=0; v<N; ++v) if(v!=s){\n            int pe=parent_edge[v]; if(pe>=0) bet_count[pe] += 1;\n        }\n        // sample targets\n        target_list.clear();\n        for(int t=0; t<T; ++t){\n            int idx = (si*911 + t*811 + (rng()&0x7fffffff)) % N;\n            int v=nodes[idx]; if(v==s) v=(v+1)%N;\n            target_list.push_back(v);\n        }\n        for(int tnode: target_list){\n            path_edges.clear();\n            int cur=tnode, steps=0;\n            while(cur!=s && steps<N){\n                int pe=parent_edge[cur];\n                if(pe<0) break;\n                path_edges.push_back(pe);\n                int a=edges[pe].u, b=edges[pe].v;\n                cur = (cur==a? b: a);\n                steps++;\n            }\n            int Lp = (int)path_edges.size();\n            for(int i=0;i<Lp;++i){\n                int e1 = path_edges[i];\n                bet_count[e1] += 1;\n                // co-occurrence window\n                int wwin = 8;\n                int l = max(0, i-wwin), r = min(Lp-1, i+wwin);\n                for(int j=l;j<=r;++j){\n                    if(j==i) continue;\n                    push_co(e1, path_edges[j]);\n                }\n            }\n        }\n    }\n\n    long long betmin=LLONG_MAX, betmax=0;\n    for(int i=0;i<M;++i){ betmin=min(betmin, bet_count[i]); betmax=max(betmax, bet_count[i]); }\n    double denom_b = (betmax>betmin? double(betmax-betmin):1.0);\n    vector<double> imp_bet(M);\n    for(int i=0;i<M;++i) imp_bet[i] = (double)(bet_count[i]-betmin)/denom_b;\n\n    // Sectorization around centroid to discourage aligning a cut\n    double cx=0, cy=0;\n    for(auto &p: coords){ cx += p.first; cy += p.second; }\n    cx /= N; cy /= N;\n    int SECT = 12;\n    vector<int> edge_sect(M,0);\n    for(auto &e: edges){\n        double mx = 0.5*(coords[e.u].first + coords[e.v].first);\n        double my = 0.5*(coords[e.u].second + coords[e.v].second);\n        double ang = atan2(my - cy, mx - cx);\n        if(ang < 0) ang += 2*M_PI;\n        int s = int(SECT * (ang/(2*M_PI)));\n        if(s<0) s=0; if(s>=SECT) s=SECT-1;\n        edge_sect[e.id] = s;\n    }\n\n    // Combine score\n    double a_w = 0.30, b_dg = 0.50, c_bt = 1.25;\n    vector<double> score(M);\n    for(int i=0;i<M;++i) score[i] = a_w*imp_w[i] + b_dg*imp_deg[i] + c_bt*imp_bet[i];\n\n    vector<int> order(M); iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i,int j){\n        if(score[i]!=score[j]) return score[i] > score[j];\n        return i<j;\n    });\n\n    // Assignment\n    vector<int> day_of_edge(M, -1);\n    vector<int> load(D,0);\n    vector<double> day_imp(D,0.0), day_imp2(D,0.0);\n    vector<vector<int>> incid_on_day(N, vector<int>(D,0));\n    vector<vector<int>> sect_on_day(D, vector<int>(SECT,0));\n\n    vector<int> target(D);\n    int base=M/D, rem=M%D;\n    for(int d=0; d<D; ++d) target[d] = min(K, base + (d<rem?1:0));\n    vector<int> v_soft(N);\n    for(int v=0; v<N; ++v) v_soft[v] = (deg[v] + D - 1)/D + 1;\n\n    double alpha_adj = 1.15;\n    double beta_bal1 = 0.18;\n    double beta_bal2 = 0.28;\n    double gamma_co = 0.40;\n    double delta_sect = 0.15;\n    double soft_cap_pen = 0.26;\n\n    for(int ei: order){\n        int u=edges[ei].u, v=edges[ei].v;\n        int sec = edge_sect[ei];\n        int bestd=-1; double bestc=1e100;\n        for(int d=0; d<D; ++d){\n            if(load[d] >= K) continue;\n            int iu=incid_on_day[u][d], iv=incid_on_day[v][d];\n            double pen_adj = alpha_adj * (iu + iv);\n            double pen_vsoft = 0.0;\n            if(iu >= v_soft[u]) pen_vsoft += (iu - v_soft[u] + 1)*0.5;\n            if(iv >= v_soft[v]) pen_vsoft += (iv - v_soft[v] + 1)*0.5;\n            double bal = beta_bal1 * day_imp[d] + beta_bal2 * day_imp2[d];\n            // co-occurrence with already assigned edges on day d\n            double pen_co = 0.0;\n            auto &mp = co_occur[ei];\n            int seen=0;\n            for(auto &kv: mp){\n                int ej = kv.first;\n                int dj = (unsigned)ej < (unsigned)M ? day_of_edge[ej] : -1;\n                if(dj==d){ pen_co += gamma_co * kv.second; if(++seen>=12) break; }\n            }\n            // sector penalty\n            double pen_sec = delta_sect * sect_on_day[d][sec];\n\n            double cap_soft = (load[d] < target[d] ? 0.0 : soft_cap_pen * (load[d] - target[d] + 1));\n            double cost = pen_adj + pen_vsoft + bal + pen_co + pen_sec + cap_soft;\n            if(cost < bestc){ bestc=cost; bestd=d; }\n        }\n        if(bestd<0){\n            int md=0; for(int d=1; d<D; ++d) if(load[d] < load[md]) md=d;\n            bestd=md;\n        }\n        day_of_edge[ei]=bestd;\n        load[bestd]++; day_imp[bestd]+=score[ei]; day_imp2[bestd]+=score[ei]*score[ei];\n        incid_on_day[u][bestd]++; incid_on_day[v][bestd]++;\n        sect_on_day[bestd][sec]++;\n    }\n\n    // Refinement: single moves + limited two-edge swaps\n    auto eval_day_cost_partial = [&](int ei, int d)->double{\n        int u=edges[ei].u, v=edges[ei].v;\n        int sec = edge_sect[ei];\n        int iu = incid_on_day[u][d] - (day_of_edge[ei]==d?1:0);\n        int iv = incid_on_day[v][d] - (day_of_edge[ei]==d?1:0);\n        double pen_adj = alpha_adj * (iu + iv);\n        double pen_vsoft = 0.0;\n        if(iu >= v_soft[u]) pen_vsoft += (iu - v_soft[u] + 1)*0.5;\n        if(iv >= v_soft[v]) pen_vsoft += (iv - v_soft[v] + 1)*0.5;\n        double bal = beta_bal1 * day_imp[d] + beta_bal2 * day_imp2[d];\n        double pen_co = 0.0;\n        auto &mp = co_occur[ei];\n        int seen=0;\n        for(auto &kv: mp){\n            int ej=kv.first; int dj = day_of_edge[ej];\n            if(dj==d){ pen_co += gamma_co * kv.second; if(++seen>=12) break; }\n        }\n        double pen_sec = delta_sect * (sect_on_day[d][sec] - (day_of_edge[ei]==d?1:0));\n        return pen_adj + pen_vsoft + bal + pen_co + pen_sec;\n    };\n\n    auto move_edge = [&](int ei, int dfrom, int dto){\n        int u=edges[ei].u, v=edges[ei].v, sec=edge_sect[ei];\n        // update counts\n        incid_on_day[u][dfrom]--; incid_on_day[v][dfrom]--;\n        incid_on_day[u][dto]++; incid_on_day[v][dto]++;\n        sect_on_day[dfrom][sec]--; sect_on_day[dto][sec]++;\n        load[dfrom]--; load[dto]++;\n        day_imp[dfrom] -= score[ei]; day_imp2[dfrom] -= score[ei]*score[ei];\n        day_imp[dto] += score[ei]; day_imp2[dto] += score[ei]*score[ei];\n        day_of_edge[ei]=dto;\n    };\n\n    double refine_ms = 2200.0;\n    if(timer.ms() > 4300.0) refine_ms = 900.0;\n    Timer t2;\n    uniform_int_distribution<int> distE(0, M-1);\n    int iters=0;\n\n    // Single-edge moves\n    while(t2.ms() < refine_ms*0.6 && iters < 250000){\n        ++iters;\n        int ei = distE(rng);\n        int di = day_of_edge[ei];\n        double cur = eval_day_cost_partial(ei, di);\n        int bestd = di; double best_gain = 0.0;\n        for(int d=0; d<D; ++d){\n            if(d==di) continue;\n            if(load[d] >= K) continue;\n            double newc = eval_day_cost_partial(ei, d);\n            // balance delta for both days due to moving score\n            double impi = score[ei];\n            double old_bal = (beta_bal1*day_imp[di] + beta_bal2*day_imp2[di]) + (beta_bal1*day_imp[d] + beta_bal2*day_imp2[d]);\n            double new_bal = (beta_bal1*(day_imp[di]-impi) + beta_bal2*(day_imp2[di]-impi*impi))\n                           + (beta_bal1*(day_imp[d]+impi) + beta_bal2*(day_imp2[d]+impi*impi));\n            double gain = (cur - newc) + (old_bal - new_bal);\n            if(gain > best_gain){ best_gain=gain; bestd=d; }\n        }\n        if(bestd != di && best_gain > 1e-9){\n            move_edge(ei, di, bestd);\n        }\n    }\n\n    // Two-edge swaps between days\n    Timer t3;\n    int swaps=0;\n    while(t3.ms() < refine_ms*0.4 && swaps < 60000){\n        ++swaps;\n        int e1 = distE(rng);\n        int e2 = distE(rng);\n        if(e1==e2) continue;\n        int d1 = day_of_edge[e1];\n        int d2 = day_of_edge[e2];\n        if(d1==d2) continue;\n\n        // capacity unaffected by swap\n        double c11 = eval_day_cost_partial(e1, d1);\n        double c22 = eval_day_cost_partial(e2, d2);\n        double c12 = eval_day_cost_partial(e1, d2);\n        double c21 = eval_day_cost_partial(e2, d1);\n\n        // balance delta\n        double s1 = score[e1], s2=score[e2];\n        double old_bal = (beta_bal1*day_imp[d1] + beta_bal2*day_imp2[d1]) + (beta_bal1*day_imp[d2] + beta_bal2*day_imp2[d2]);\n        double new_imp_d1 = day_imp[d1] - s1 + s2;\n        double new_imp2_d1 = day_imp2[d1] - s1*s1 + s2*s2;\n        double new_imp_d2 = day_imp[d2] - s2 + s1;\n        double new_imp2_d2 = day_imp2[d2] - s2*s2 + s1*s1;\n        double new_bal = (beta_bal1*new_imp_d1 + beta_bal2*new_imp2_d1) + (beta_bal1*new_imp_d2 + beta_bal2*new_imp2_d2);\n\n        double gain = (c11 + c22) - (c12 + c21) + (old_bal - new_bal);\n        if(gain > 1e-9){\n            // commit swap\n            int u1=edges[e1].u, v1=edges[e1].v, sct1=edge_sect[e1];\n            int u2=edges[e2].u, v2=edges[e2].v, sct2=edge_sect[e2];\n            // remove e1 from d1, add to d2\n            incid_on_day[u1][d1]--; incid_on_day[v1][d1]--; sect_on_day[d1][sct1]--;\n            incid_on_day[u1][d2]++; incid_on_day[v1][d2]++; sect_on_day[d2][sct1]++;\n            // remove e2 from d2, add to d1\n            incid_on_day[u2][d2]--; incid_on_day[v2][d2]--; sect_on_day[d2][sct2]--;\n            incid_on_day[u2][d1]++; incid_on_day[v2][d1]++; sect_on_day[d1][sct2]++;\n            day_imp[d1] = new_imp_d1; day_imp2[d1] = new_imp2_d1;\n            day_imp[d2] = new_imp_d2; day_imp2[d2] = new_imp2_d2;\n            day_of_edge[e1]=d2; day_of_edge[e2]=d1;\n        }\n    }\n\n    // Output\n    for(int i=0;i<M;++i){\n        int d=day_of_edge[i]; if(d<0) d=i%D;\n        cout << (d+1) << (i+1==M?'\\n':' ');\n    }\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct RNG {\n    uint64_t x;\n    RNG(uint64_t seed=88172645463393265ull){ x=seed; }\n    inline uint64_t next() { x ^= x<<7; x ^= x>>9; return x; }\n    inline int randint(int l,int r){ return l + (int)(next() % (uint64_t)(r-l+1)); }\n    inline double rand01(){ return (next() >> 11) * (1.0/9007199254740992.0); }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D;\n    if(!(cin>>D)) return 0;\n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    for(int i=0;i<2;++i){\n        for(int z=0;z<D;++z) cin>>f[i][z];\n        for(int z=0;z<D;++z) cin>>r[i][z];\n    }\n    const int N = D*D*D;\n    auto idx = [&](int x,int y,int z){ return x*D*D + y*D + z; };\n    auto unidx = [&](int id, int &x,int &y,int &z){\n        x = id/(D*D);\n        int rem = id%(D*D);\n        y = rem/D;\n        z = rem% D;\n    };\n\n    // Build Mi masks\n    vector<char> A1(N,0), A2(N,0);\n    for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z){\n        if (f[0][z][x]=='1' && r[0][z][y]=='1') A1[idx(x,y,z)]=1;\n        if (f[1][z][x]=='1' && r[1][z][y]=='1') A2[idx(x,y,z)]=1;\n    }\n\n    // We will construct blocks: some shared cuboids, then leftovers as components (shared intersection also can be components)\n    vector<int> b1(N,0), b2(N,0);\n    int nBlocks = 0;\n\n    auto now = [&]()->double{\n        static chrono::high_resolution_clock::time_point start = chrono::high_resolution_clock::now();\n        chrono::duration<double> diff = chrono::high_resolution_clock::now()-start;\n        return diff.count();\n    };\n    RNG rng(123456789);\n\n    // Helper to check cuboid validity in mask\n    auto can_place = [&](const vector<char>& M, int x0,int y0,int z0,int dx,int dy,int dz)->bool{\n        if (x0<0 || y0<0 || z0<0 || x0+dx>D || y0+dy>D || z0+dz>D) return false;\n        for(int x=x0;x<x0+dx;++x)\n            for(int y=y0;y<y0+dy;++y)\n                for(int z=z0;z<z0+dz;++z)\n                    if (!M[idx(x,y,z)]) return false;\n        return true;\n    };\n    auto place_block = [&](vector<char>& M, vector<int>& Bout, int bid, int x0,int y0,int z0,int dx,int dy,int dz){\n        for(int x=x0;x<x0+dx;++x)\n            for(int y=y0;y<y0+dy;++y)\n                for(int z=z0;z<z0+dz;++z){\n                    int id = idx(x,y,z);\n                    M[id]=0;\n                    Bout[id]=bid;\n                }\n    };\n\n    // Collect free voxels list for sampling\n    auto collect_free = [&](const vector<char>& M){\n        vector<int> v;\n        v.reserve(N);\n        for(int i=0;i<N;++i) if (M[i]) v.push_back(i);\n        return v;\n    };\n\n    // Greedy shared cuboid packing loop with time budget\n    double time_limit = 1.2; // seconds\n    int trials = 0, successes = 0;\n    while (now() < time_limit) {\n        auto free1 = collect_free(A1);\n        auto free2 = collect_free(A2);\n        if (free1.empty() || free2.empty()) break;\n        // sample seed in A1\n        int seedId = free1[rng.randint(0, (int)free1.size()-1)];\n        int sx,sy,sz; unidx(seedId,sx,sy,sz);\n        // random target dimensions\n        int dx = 1, dy = 1, dz = 1;\n        // Try to grow along axes within small bounds\n        int maxGrow = min(6, D); // cap dimensions to limit search\n        // Random growth order\n        int order[3] = {0,1,2};\n        if (rng.rand01() < 0.5) swap(order[0], order[1]);\n        if (rng.rand01() < 0.5) swap(order[1], order[2]);\n\n        // Choose random extents by expanding positive direction where possible\n        // First determine maximal extents locally (bounded)\n        int maxDx = 1, maxDy = 1, maxDz = 1;\n        // Compute maxDx\n        for(int ex=1; ex<=maxGrow && sx+ex<=D; ++ex){\n            bool ok=true;\n            for(int x=sx; x<sx+ex; ++x)\n                for(int y=sy; y<sy+maxDy; ++y)\n                    for(int z=sz; z<sz+maxDz; ++z){\n                        if (!A1[idx(x,y,z)]) { ok=false; break; }\n                    }\n            if (!ok) break;\n            maxDx = ex;\n        }\n        // To be simpler and faster, we try randomized dims up to min(available to boundary, cap)\n        auto randDim = [&](int start, int limit)->int{\n            int m = min(limit, D - start);\n            int val = 1 + rng.randint(0, m-1);\n            return val;\n        };\n        dx = randDim(sx, min(6, D - sx));\n        dy = randDim(sy, min(6, D - sy));\n        dz = randDim(sz, min(6, D - sz));\n        // Adjust to ensure A1 support\n        auto adjust_to_fit = [&](int &dx,int &dy,int &dz)->bool{\n            dx = min(dx, D - sx);\n            dy = min(dy, D - sy);\n            dz = min(dz, D - sz);\n            // shrink until fits\n            while (dx>0 && dy>0 && dz>0 && !can_place(A1, sx,sy,sz, dx,dy,dz)) {\n                // shrink the largest dimension\n                if (dx>=dy && dx>=dz) --dx;\n                else if (dy>=dx && dy>=dz) --dy;\n                else --dz;\n            }\n            return dx>0 && dy>0 && dz>0;\n        };\n        if (!adjust_to_fit(dx,dy,dz)) { ++trials; continue; }\n\n        // Now try to find a matching placement in A2 with same dims\n        bool found2 = false;\n        int tx=0,ty=0,tz=0;\n        // Try a few random attempts to place same-size cuboid in A2\n        int attempts2 = 60;\n        for(int t=0;t<attempts2;++t){\n            if (free2.empty()) break;\n            int sid2 = free2[rng.randint(0, (int)free2.size()-1)];\n            int ux,uy,uz; unidx(sid2,ux,uy,uz);\n            // random offset adjustments to fit dims within bounds\n            if (ux+dx > D) ux = D - dx;\n            if (uy+dy > D) uy = D - dy;\n            if (uz+dz > D) uz = D - dz;\n            if (ux<0||uy<0||uz<0) continue;\n            if (can_place(A2, ux,uy,uz, dx,dy,dz)) {\n                found2 = true; tx=ux; ty=uy; tz=uz; break;\n            }\n        }\n        if (!found2) { ++trials; continue; }\n\n        // Create shared block\n        ++nBlocks;\n        place_block(A1, b1, nBlocks, sx,sy,sz, dx,dy,dz);\n        place_block(A2, b2, nBlocks, tx,ty,tz, dx,dy,dz);\n        ++successes;\n        // continue loop\n        ++trials;\n        // small break control\n        if (successes % 100 == 0 && now() > time_limit) break;\n    }\n\n    // After shared cuboids, there may remain shared voxels (both A1 and A2 still 1 in same positions). We can also add them as shared components to reduce r1+r2? Note: sharing reduces 1/vi vs leaving them as only blocks. But we can still safely share identical coordinates intersection.\n    vector<char> rem1 = A1, rem2 = A2;\n    vector<char> Cmin(N,0);\n    for(int i=0;i<N;++i) if (rem1[i] && rem2[i]) Cmin[i]=1;\n\n    auto mark_components = [&](const vector<char>& mask, bool place_in_1, bool place_in_2){\n        vector<char> vis(N,0);\n        const int dxs[6]={1,-1,0,0,0,0};\n        const int dys[6]={0,0,1,-1,0,0};\n        const int dzs[6]={0,0,0,0,1,-1};\n        for(int x=0;x<D;++x)for(int y=0;y<D;++y)for(int z=0;z<D;++z){\n            int s = idx(x,y,z);\n            if (!mask[s] || vis[s]) continue;\n            ++nBlocks;\n            queue<int> q;\n            q.push(s);\n            vis[s]=1;\n            if (place_in_1) b1[s]=nBlocks;\n            if (place_in_2) b2[s]=nBlocks;\n            while(!q.empty()){\n                int v=q.front(); q.pop();\n                int vx = v/(D*D);\n                int rem = v%(D*D);\n                int vy = rem/D;\n                int vz = rem% D;\n                for(int d=0; d<6; ++d){\n                    int nx=vx+dxs[d], ny=vy+dys[d], nz=vz+dzs[d];\n                    if (nx<0||nx>=D||ny<0||ny>=D||nz<0||nz>=D) continue;\n                    int u = idx(nx,ny,nz);\n                    if (mask[u] && !vis[u]){\n                        vis[u]=1;\n                        q.push(u);\n                        if (place_in_1) b1[u]=nBlocks;\n                        if (place_in_2) b2[u]=nBlocks;\n                    }\n                }\n            }\n        }\n    };\n\n    // Place shared remaining identical coordinates\n    mark_components(Cmin, true, true);\n    // Update A1, A2 to remove those cells\n    for(int i=0;i<N;++i){\n        if (Cmin[i]) { rem1[i]=0; rem2[i]=0; }\n    }\n    // Remaining are exclusive\n    mark_components(rem1, true, false);\n    mark_components(rem2, false, true);\n\n    cout << nBlocks << \"\\n\";\n    for(int i=0;i<N;++i){\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << \"\\n\";\n    for(int i=0;i<N;++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};\nstruct AdjEdge { int to, id; long long w; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K;\n    if(!(cin>>N>>M>>K)) return 0;\n    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n    vector<Edge> edges(M);\n    vector<vector<AdjEdge>> g(N);\n    for(int j=0;j<M;j++){\n        int u,v; long long w;\n        cin>>u>>v>>w; --u;--v;\n        edges[j]={u,v,w};\n        g[u].push_back({v,j,w});\n        g[v].push_back({u,j,w});\n    }\n    vector<int> ax(K), ay(K);\n    for(int k=0;k<K;k++) cin>>ax[k]>>ay[k];\n\n    auto dist_int = [&](int xi,int yi,int a,int b)->int{\n        long double dx = (long double)xi - a;\n        long double dy = (long double)yi - b;\n        long double d = sqrt((double)(dx*dx + dy*dy));\n        // ceil to ensure coverage\n        int id = (int)ceil(d - 1e-12);\n        if(id>5000) id=5000;\n        if(id<0) id=0;\n        return id;\n    };\n\n    // Precompute station-resident distances\n    vector<vector<int>> res_order(N);\n    vector<vector<int>> res_dist(N);\n    for(int i=0;i<N;i++){\n        res_order[i].resize(K);\n        iota(res_order[i].begin(), res_order[i].end(), 0);\n        vector<int> tmpd(K);\n        for(int k=0;k<K;k++){\n            tmpd[k] = dist_int(x[i],y[i],ax[k],ay[k]);\n        }\n        // sort indices by distance\n        stable_sort(res_order[i].begin(), res_order[i].end(), [&](int a,int b){\n            return tmpd[a] < tmpd[b];\n        });\n        res_dist[i].resize(K);\n        for(int idx=0; idx<K; ++idx){\n            int rk = res_order[i][idx];\n            res_dist[i][idx] = tmpd[rk];\n        }\n    }\n\n    // Dijkstra from 0 to get shortest path tree\n    const long long INFLL = (1LL<<62);\n    vector<long long> dist(N, INFLL);\n    vector<int> parE(N, -1), parV(N, -1);\n    struct Node { long long d; int v;};\n    struct Cmp { bool operator()(const Node& a, const Node& b) const { return a.d>b.d; } };\n    priority_queue<Node, vector<Node>, Cmp> pq;\n    dist[0]=0; pq.push({0,0});\n    while(!pq.empty()){\n        auto [d,u]=pq.top(); pq.pop();\n        if(d!=dist[u]) continue;\n        for(auto &e: g[u]){\n            int v=e.to; long long nd = d + e.w;\n            if(nd < dist[v]){\n                dist[v]=nd; parE[v]=e.id; parV[v]=u;\n                pq.push({nd,v});\n            }\n        }\n    }\n    // Build SPT edges set\n    vector<int> tree_parent_edge(N,-1);\n    for(int v=1; v<N; v++){\n        tree_parent_edge[v]=parE[v];\n    }\n\n    // Baseline: assign each resident to nearest station (by Euclidean distance, not connectivity)\n    vector<int> P(N,0);\n    vector<int> req(N,0);\n    for(int k=0;k<K;k++){\n        int besti=0; int bestd = dist_int(x[0],y[0],ax[k],ay[k]);\n        for(int i=1;i<N;i++){\n            int d = dist_int(x[i],y[i],ax[k],ay[k]);\n            if(d < bestd){\n                bestd = d; besti=i;\n            }\n        }\n        if(bestd>req[besti]) req[besti]=bestd;\n    }\n    for(int i=0;i<N;i++) P[i]=req[i];\n\n    // Determine set of broadcasting stations (terminals)\n    vector<char> is_terminal(N,false);\n    int terminals=0;\n    for(int i=0;i<N;i++){\n        if(P[i]>0){ is_terminal[i]=true; terminals++; }\n    }\n    is_terminal[0] = is_terminal[0] || (P[0]>0); // ensure 0 marked if broadcasting\n\n    // Determine which tree edges are needed to connect terminals to root in the SPT\n    vector<char> need_edge(M,false);\n    vector<int> used(N,0);\n    // Mark all terminals and propagate to root\n    vector<int> degree_in_subtree(N,0);\n    for(int v=0; v<N; v++){\n        if(!is_terminal[v]) continue;\n        int u=v;\n        while(u!=0){\n            int e = tree_parent_edge[u];\n            if(e<0) break;\n            if(need_edge[e]) { // already marked\n                u = edges[e].u==u ? edges[e].v : edges[e].u;\n                continue;\n            }\n            need_edge[e]=true;\n            degree_in_subtree[edges[e].u]++;\n            degree_in_subtree[edges[e].v]++;\n            u = edges[e].u==u ? edges[e].v : edges[e].u;\n        }\n    }\n\n    // Optional: try to reduce broadcasting set by reassigning to currently broadcasting stations\n    // Build list of broadcasters\n    vector<int> broadcasters;\n    broadcasters.reserve(N);\n    for(int i=0;i<N;i++) if(P[i]>0) broadcasters.push_back(i);\n    if(broadcasters.empty()){\n        // If somehow no broadcasters (shouldn't happen as K>=2000), ensure station 1 covers nearest residents\n        // Set P[0] to max distance to all residents (capped)\n        int mx=0;\n        for(int k=0;k<K;k++){ mx = max(mx, dist_int(x[0],y[0],ax[k],ay[k])); }\n        P[0]=mx;\n        is_terminal[0]=true;\n        // no edges needed\n        fill(need_edge.begin(), need_edge.end(), false);\n    } else {\n        // Reassign residents to nearest broadcaster and recompute P\n        vector<int> newP(N,0);\n        for(int k=0;k<K;k++){\n            int besti = broadcasters[0];\n            int bestd = dist_int(x[besti],y[besti],ax[k],ay[k]);\n            for(size_t t=1;t<broadcasters.size();t++){\n                int i = broadcasters[t];\n                int d = dist_int(x[i],y[i],ax[k],ay[k]);\n                if(d < bestd){ bestd=d; besti=i; }\n            }\n            if(bestd > newP[besti]) newP[besti]=bestd;\n        }\n        P.swap(newP);\n        // update terminals\n        fill(is_terminal.begin(), is_terminal.end(), false);\n        broadcasters.clear();\n        for(int i=0;i<N;i++) if(P[i]>0){ is_terminal[i]=true; broadcasters.push_back(i); }\n        // recompute needed edges on SPT\n        fill(need_edge.begin(), need_edge.end(), false);\n        for(int v=0; v<N; v++){\n            if(!is_terminal[v]) continue;\n            int u=v;\n            while(u!=0){\n                int e = tree_parent_edge[u];\n                if(e<0) break;\n                if(need_edge[e]){\n                    u = edges[e].u==u ? edges[e].v : edges[e].u;\n                    continue;\n                }\n                need_edge[e]=true;\n                u = edges[e].u==u ? edges[e].v : edges[e].u;\n            }\n        }\n    }\n\n    // Final small tightening: try to reduce P[i] by trimming unnecessary slack.\n    // For each broadcaster i, compute max distance among residents to i when residents choose nearest broadcaster.\n    // Already done; but do a quick pass: for each i, try lowering to the next smaller actual distance in its assigned set.\n    // To keep it simple and fast, we skip recalculating assignments; the previous calculation already set P exactly.\n\n    // Build B array\n    vector<int> B(M,0);\n    for(int j=0;j<M;j++) if(need_edge[j]) B[j]=1;\n\n    // Output\n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << P[i];\n    }\n    cout << '\\n';\n    for(int j=0;j<M;j++){\n        if(j) cout << ' ';\n        cout << B[j];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    const int NN = N * (N + 1) / 2;\n\n    auto id_of = [&](int x, int y)->int { return x*(x+1)/2 + y; };\n    vector<int> x_of(NN), y_of(NN);\n    for (int x=0, id=0; x<N; ++x) for (int y=0; y<=x; ++y, ++id) { x_of[id]=x; y_of[id]=y; }\n\n    vector<int> A(NN);\n    for (int x=0; x<N; ++x) for (int y=0; y<=x; ++y) cin >> A[id_of(x,y)];\n\n    const int NONE = -1;\n    vector<array<int,2>> child(NN, {NONE, NONE});\n    for (int x=0; x<N-1; ++x) {\n        for (int y=0; y<=x; ++y) {\n            int id = id_of(x,y);\n            child[id][0] = id_of(x+1, y);\n            child[id][1] = id_of(x+1, y+1);\n        }\n    }\n\n    struct Move { int x1,y1,x2,y2; };\n    vector<Move> moves;\n    moves.reserve(10000);\n    auto do_swap = [&](int id1, int id2){\n        swap(A[id1], A[id2]);\n        moves.push_back({x_of[id1], y_of[id1], x_of[id2], y_of[id2]});\n    };\n\n    const int K_LIMIT = 10000;\n\n    // Single-pass bottom-up siftdown for all internal nodes\n    auto siftdown = [&](int start_id){\n        int id = start_id;\n        while (child[id][0] != NONE) {\n            int c0 = child[id][0], c1 = child[id][1];\n            int mc = (A[c0] < A[c1] ? c0 : c1);\n            if (A[id] <= A[mc]) break;\n            do_swap(id, mc);\n            if ((int)moves.size() >= K_LIMIT) return;\n            id = mc;\n        }\n    };\n\n    for (int x=N-2; x>=0; --x) {\n        // alternate direction per row can slightly reduce conflicts; try left-to-right for even x, right-to-left for odd x\n        if ((x & 1) == 0) {\n            for (int y=0; y<=x; ++y) {\n                siftdown(id_of(x,y));\n                if ((int)moves.size() >= K_LIMIT) break;\n            }\n        } else {\n            for (int y=x; y>=0; --y) {\n                siftdown(id_of(x,y));\n                if ((int)moves.size() >= K_LIMIT) break;\n            }\n        }\n        if ((int)moves.size() >= K_LIMIT) break;\n    }\n\n    // Safety polish: if any violations remain and we have budget, do one light pass to fix them.\n    if ((int)moves.size() < K_LIMIT) {\n        bool has_violation = false;\n        for (int x=0; x<N-1 && !has_violation; ++x) {\n            for (int y=0; y<=x; ++y) {\n                int id = id_of(x,y);\n                int c0 = child[id][0], c1 = child[id][1];\n                int mc = (A[c0] < A[c1] ? c0 : c1);\n                if (A[id] > A[mc]) { has_violation = true; break; }\n            }\n        }\n        if (has_violation) {\n            // One pass: for each violation, swap and continue siftdown locally\n            for (int x=0; x<N-1 && (int)moves.size() < K_LIMIT; ++x) {\n                for (int y=0; y<=x && (int)moves.size() < K_LIMIT; ++y) {\n                    int id = id_of(x,y);\n                    while (child[id][0] != NONE) {\n                        int c0 = child[id][0], c1 = child[id][1];\n                        int mc = (A[c0] < A[c1] ? c0 : c1);\n                        if (A[id] > A[mc]) {\n                            do_swap(id, mc);\n                            id = mc;\n                            if ((int)moves.size() >= K_LIMIT) break;\n                        } else break;\n                    }\n                }\n            }\n        }\n    }\n\n    cout << moves.size() << '\\n';\n    for (auto &mv : moves) {\n        cout << mv.x1 << ' ' << mv.y1 << ' ' << mv.x2 << ' ' << mv.y2 << '\\n';\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D,N;\n    if(!(cin>>D>>N)) return 0;\n    vector<vector<int>> obs(D, vector<int>(D, 0));\n    for(int k=0;k<N;k++){\n        int r,c; cin>>r>>c;\n        obs[r][c]=1;\n    }\n    // Entrance\n    int ei = 0, ej = (D-1)/2;\n    // Build list of free cells excluding entrance\n    vector<Pos> cells; cells.reserve(D*D-1-N);\n    // Snake order by rows, skipping obstacles and entrance\n    for(int i=0;i<D;i++){\n        if(i%2==0){\n            for(int j=0;j<D;j++){\n                if(i==ei && j==ej) continue;\n                if(obs[i][j]) continue;\n                cells.push_back({i,j});\n            }\n        }else{\n            for(int jj=D-1;jj>=0;jj--){\n                int j=jj;\n                if(i==ei && j==ej) continue;\n                if(obs[i][j]) continue;\n                cells.push_back({i,j});\n            }\n        }\n    }\n    int M = (int)cells.size(); // should be D*D-1-N\n    // Map position index for quick lookup\n    vector<vector<int>> posIndex(D, vector<int>(D, -1));\n    for(int idx=0; idx<M; idx++){\n        posIndex[cells[idx].i][cells[idx].j] = idx;\n    }\n    // Occupancy grid: 0 empty, 1 occupied (container), -1 obstacle, -2 entrance (treated as empty for BFS)\n    vector<vector<int>> occ(D, vector<int>(D, 0));\n    for(int i=0;i<D;i++) for(int j=0;j<D;j++){\n        if(obs[i][j]) occ[i][j] = -1;\n    }\n    occ[ei][ej] = -2;\n\n    // For recording where each t is placed\n    vector<Pos> loc_of_id(M, {-1,-1});\n    vector<int> id_at_cell(M, -1); // by path index\n    vector<int> free_pos(M, 1);\n\n    auto bfs_reach = [&](){\n        vector<vector<char>> vis(D, vector<char>(D, 0));\n        queue<Pos> q;\n        q.push({ei,ej});\n        vis[ei][ej]=1;\n        int di[4]={-1,1,0,0};\n        int dj[4]={0,0,-1,1};\n        while(!q.empty()){\n            auto p=q.front(); q.pop();\n            for(int k=0;k<4;k++){\n                int ni=p.i+di[k], nj=p.j+dj[k];\n                if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                if(vis[ni][nj]) continue;\n                if(occ[ni][nj]==0 || occ[ni][nj]==-2){ // empty or entrance\n                    vis[ni][nj]=1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n        return vis;\n    };\n\n    // Online placement\n    for(int d=0; d<M; d++){\n        int t; cin>>t;\n        // compute reachable empty cells mask\n        auto vis = bfs_reach();\n        int ideal = t; if(ideal<0) ideal=0; if(ideal>=M) ideal=M-1;\n        int chosen_idx = -1;\n        // search window expanding\n        int W = 12;\n        int maxW = M;\n        for(int w=W; w<=maxW && chosen_idx==-1; w+=12){\n            int L = max(0, ideal - w);\n            int R = min(M-1, ideal + w);\n            // Collect reachable free candidates with minimal |pos-ideal|\n            int bestScore = INT_MAX;\n            int bestIdx = -1;\n            for(int pos=L; pos<=R; pos++){\n                if(!free_pos[pos]) continue;\n                Pos p = cells[pos];\n                if(!vis[p.i][p.j]) continue;\n                int score = abs(pos - ideal);\n                if(score < bestScore){\n                    bestScore = score;\n                    bestIdx = pos;\n                }else if(score == bestScore && bestIdx!=-1){\n                    // tie-break: for larger t, prefer larger pos; for smaller t, prefer smaller pos\n                    if(t*2 >= M){\n                        if(pos > bestIdx) bestIdx = pos;\n                    }else{\n                        if(pos < bestIdx) bestIdx = pos;\n                    }\n                }\n            }\n            if(bestIdx!=-1) chosen_idx = bestIdx;\n        }\n        if(chosen_idx==-1){\n            // Fallback: pick any reachable free cell, prefer towards ideal direction\n            int bestIdx=-1, bestScore=INT_MAX;\n            for(int pos=0; pos<M; pos++){\n                if(!free_pos[pos]) continue;\n                Pos p=cells[pos];\n                if(!vis[p.i][p.j]) continue;\n                int score = abs(pos - ideal);\n                if(score < bestScore){\n                    bestScore=score; bestIdx=pos;\n                }\n            }\n            if(bestIdx!=-1) chosen_idx=bestIdx;\n        }\n        if(chosen_idx==-1){\n            // As a last resort, pick any free (shouldn't happen because all free cells are reachable by guarantee if empty)\n            for(int pos=0; pos<M; pos++){\n                if(free_pos[pos]){\n                    chosen_idx=pos; break;\n                }\n            }\n        }\n        // Place\n        Pos place = cells[chosen_idx];\n        cout<<place.i<<\" \"<<place.j<<\"\\n\"<<flush;\n        occ[place.i][place.j] = 1;\n        free_pos[chosen_idx]=0;\n        id_at_cell[chosen_idx]=t;\n        loc_of_id[t]=place;\n    }\n\n    // Extraction: repeatedly remove smallest-ID reachable\n    // Build a map from (i,j) to ID\n    vector<vector<int>> id_grid(D, vector<int>(D, -1));\n    for(int pos=0; pos<M; pos++){\n        if(id_at_cell[pos]>=0){\n            Pos p = cells[pos];\n            id_grid[p.i][p.j] = id_at_cell[pos];\n        }\n    }\n\n    vector<pair<int,int>> output_order;\n    output_order.reserve(M);\n\n    auto bfs_reach_cells = [&](){\n        vector<vector<char>> vis(D, vector<char>(D, 0));\n        queue<Pos> q;\n        q.push({ei,ej});\n        vis[ei][ej]=1;\n        int di[4]={-1,1,0,0};\n        int dj[4]={0,0,-1,1};\n        while(!q.empty()){\n            auto p=q.front(); q.pop();\n            for(int k=0;k<4;k++){\n                int ni=p.i+di[k], nj=p.j+dj[k];\n                if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                if(vis[ni][nj]) continue;\n                // reachable through empty cells only\n                if(occ[ni][nj]==0 || occ[ni][nj]==-2){\n                    vis[ni][nj]=1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n        return vis;\n    };\n\n    for(int removed=0; removed<M; removed++){\n        // compute which occupied cells are currently reachable: cell must be adjacent via empty path to entrance\n        // A container is removable if its cell is reachable from entrance through empty cells; i.e., the container's cell must itself be marked reachable when considering it as occupied? The definition says:\n        // \"The square containing the container to be transported out must be reachable from the entrance by only passing through adjacent empty squares\"\n        // That implies the path does not include the container square (since it's not empty). Typically the last step into its square would require the square to be empty, which is impossible. Usually interpretation is: there exists a path of empty cells to a neighbor of the target, and then we can remove it. However AtCoder's typical definition here counts the container square as allowed at endpoint.\n        // The common approach is to allow reaching its cell if we treat it as empty for reachability test of candidate. We'll check neighbors.\n        auto vis = bfs_reach_cells();\n        int bestID = INT_MAX;\n        Pos bestP{-1,-1};\n        for(int i=0;i<D;i++){\n            for(int j=0;j<D;j++){\n                if(id_grid[i][j] < 0) continue;\n                // check if reachable: there exists a path of empty cells from entrance to a neighbor of (i,j)\n                bool reachable = false;\n                int di[4]={-1,1,0,0};\n                int dj[4]={0,0,-1,1};\n                for(int k=0;k<4;k++){\n                    int ni=i+di[k], nj=j+dj[k];\n                    if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                    if(vis[ni][nj]) { reachable=true; break; }\n                }\n                if(!reachable) continue;\n                int curID = id_grid[i][j];\n                if(curID < bestID){\n                    bestID = curID;\n                    bestP = {i,j};\n                }\n            }\n        }\n        if(bestID==INT_MAX){\n            // Fallback: if none reachable by neighbor method, allow cells that themselves are marked reachable if we consider them empty\n            // Temporarily mark all occupied as walls; vis marks empty reachables. None found -> choose any with minimal ID that is adjacent via zero? We'll pick minimal ID anywhere.\n            for(int i=0;i<D;i++){\n                for(int j=0;j<D;j++){\n                    if(id_grid[i][j] >= 0){\n                        int curID = id_grid[i][j];\n                        if(curID < bestID){\n                            bestID=curID; bestP={i,j};\n                        }\n                    }\n                }\n            }\n        }\n        // Output and remove\n        cout<<bestP.i<<\" \"<<bestP.j<<\"\\n\";\n        // Mark empty now\n        occ[bestP.i][bestP.j] = 0;\n        id_grid[bestP.i][bestP.j] = -1;\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int DX[4] = {1,-1,0,0};\nstatic const int DY[4] = {0,0,1,-1};\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    vector<int> d(n*n);\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            int c; cin >> c;\n            d[i*n+j] = c;\n        }\n    }\n    int C = m+1;\n    auto inb = [&](int i,int j){ return (unsigned)i < (unsigned)n && (unsigned)j < (unsigned)n; };\n\n    // Build original adjacency matrix A (including 0 via boundary)\n    vector<vector<char>> A(C, vector<char>(C, 0));\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            int u = d[i*n+j];\n            if(i+1<n){\n                int v = d[(i+1)*n+j];\n                if(u!=v){ A[u][v]=A[v][u]=1; }\n            }\n            if(j+1<n){\n                int v = d[i*n+(j+1)];\n                if(u!=v){ A[u][v]=A[v][u]=1; }\n            }\n        }\n    }\n    for(int i=0;i<n;i++){\n        int c1 = d[i*n+0];\n        int c2 = d[i*n+(n-1)];\n        A[0][c1]=A[c1][0]=1;\n        A[0][c2]=A[c2][0]=1;\n    }\n    for(int j=0;j<n;j++){\n        int c1 = d[0*n+j];\n        int c2 = d[(n-1)*n+j];\n        A[0][c1]=A[c1][0]=1;\n        A[0][c2]=A[c2][0]=1;\n    }\n\n    // Current adjacency counts\n    vector<vector<int>> adjCnt(C, vector<int>(C, 0));\n    auto recomputeAdjCnt = [&](){\n        for(int u=0;u<C;u++) fill(adjCnt[u].begin(), adjCnt[u].end(), 0);\n        for(int i=0;i<n;i++){\n            for(int j=0;j<n;j++){\n                int u = d[i*n+j];\n                if(i+1<n){\n                    int v = d[(i+1)*n+j];\n                    if(u!=v){ adjCnt[u][v]++; adjCnt[v][u]++; }\n                }\n                if(j+1<n){\n                    int v = d[i*n+(j+1)];\n                    if(u!=v){ adjCnt[u][v]++; adjCnt[v][u]++; }\n                }\n            }\n        }\n        for(int i=0;i<n;i++){\n            int c1 = d[i*n+0];\n            int c2 = d[i*n+(n-1)];\n            if(c1!=0){ adjCnt[0][c1]++; adjCnt[c1][0]++; }\n            if(c2!=0){ adjCnt[0][c2]++; adjCnt[c2][0]++; }\n        }\n        for(int j=0;j<n;j++){\n            int c1 = d[0*n+j];\n            int c2 = d[(n-1)*n+j];\n            if(c1!=0){ adjCnt[0][c1]++; adjCnt[c1][0]++; }\n            if(c2!=0){ adjCnt[0][c2]++; adjCnt[c2][0]++; }\n        }\n    };\n    recomputeAdjCnt();\n\n    vector<int> totalCells(C, 0);\n    for(int v : d) totalCells[v]++;\n\n    vector<char> allowZeroAdj(C, 0);\n    for(int c=0;c<C;c++) allowZeroAdj[c] = A[0][c];\n\n    // Track 0-cells connected to boundary\n    vector<char> zeroConn(n*n, 0);\n\n    auto t0 = chrono::high_resolution_clock::now();\n    const double TIME_LIMIT = 1.70;\n\n    // Connectivity check for color c if removing cell p\n    vector<char> vis(n*n, 0);\n    auto connectedAfterRemoval = [&](int c, int p)->bool{\n        if(totalCells[c] <= 1) return false; // keep at least one\n        int pi = p / n, pj = p % n;\n        int neighCount = 0;\n        int start = -1;\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            int q = ni*n+nj;\n            if(d[q] == c){ neighCount++; start = q; }\n        }\n        if(neighCount <= 1) return true;\n        fill(vis.begin(), vis.end(), 0);\n        deque<int> dq;\n        dq.push_back(start);\n        vis[start] = 1;\n        int reach = 1;\n        while(!dq.empty()){\n            int v = dq.front(); dq.pop_front();\n            int vi = v / n, vj = v % n;\n            for(int dir=0;dir<4;dir++){\n                int ni = vi + DX[dir], nj = vj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int u = ni*n+nj;\n                if(u==p) continue;\n                if(!vis[u] && d[u]==c){\n                    vis[u]=1; dq.push_back(u); reach++;\n                }\n            }\n        }\n        return reach == totalCells[c]-1;\n    };\n\n    // Flood zero connectivity from a starting zero cell\n    auto floodZeroFrom = [&](int sIdx){\n        if(d[sIdx] != 0) return;\n        if(zeroConn[sIdx]) return;\n        deque<int> dq;\n        if(zeroConn[sIdx]) return;\n        // Only start if it touches boundary or a zeroConn neighbor; call site ensures this\n        dq.push_back(sIdx);\n        zeroConn[sIdx] = 1;\n        while(!dq.empty()){\n            int v = dq.front(); dq.pop_front();\n            int vi = v / n, vj = v % n;\n            for(int dir=0;dir<4;dir++){\n                int ni = vi + DX[dir], nj = vj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int u = ni*n+nj;\n                if(d[u]==0 && !zeroConn[u]){\n                    zeroConn[u]=1;\n                    dq.push_back(u);\n                }\n            }\n        }\n    };\n\n    std::mt19937 rng(890123);\n\n    bool improved = true;\n    while(improved){\n        improved = false;\n\n        // Build candidates with scores\n        struct Cand { int p; int score; };\n        vector<Cand> cand;\n        cand.reserve(n*n);\n\n        for(int i=0;i<n;i++){\n            for(int j=0;j<n;j++){\n                int p = i*n+j;\n                int c = d[p];\n                if(c==0) continue;\n                if(!allowZeroAdj[c]) continue;\n                if(totalCells[c] <= 1) continue;\n                bool canConnectZero = (i==0 || i==n-1 || j==0 || j==n-1);\n                if(!canConnectZero){\n                    for(int dir=0;dir<4;dir++){\n                        int ni = i + DX[dir], nj = j + DY[dir];\n                        if(!inb(ni,nj)) continue;\n                        int q = ni*n+nj;\n                        if(d[q]==0 && zeroConn[q]){ canConnectZero = true; break; }\n                    }\n                }\n                if(!canConnectZero) continue;\n\n                // Compute heuristic score\n                int same = 0, reqAdjContrib = 0, boundaryContrib = 0, badNbr = 0;\n                for(int dir=0;dir<4;dir++){\n                    int ni = i + DX[dir], nj = j + DY[dir];\n                    if(inb(ni,nj)){\n                        int y = d[ni*n+nj];\n                        if(y==c) same++;\n                        else{\n                            if(!allowZeroAdj[y]) badNbr++; // will be filtered later, but penalize\n                            if(A[c][y]) reqAdjContrib++;\n                        }\n                    }else{\n                        boundaryContrib++;\n                    }\n                }\n                // Higher same is better; lower reqAdjContrib and boundaryContrib are better; badNbr penalizes\n                int score = same*10 - reqAdjContrib*3 - boundaryContrib*2 - badNbr*50;\n                cand.push_back({p, score});\n            }\n        }\n        // Sort by descending score\n        sort(cand.begin(), cand.end(), [&](const Cand& a, const Cand& b){\n            if(a.score != b.score) return a.score > b.score;\n            return a.p < b.p;\n        });\n\n        for(const auto& ca : cand){\n            auto t1 = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(t1 - t0).count();\n            if(elapsed > TIME_LIMIT) break;\n\n            int p = ca.p;\n            int c = d[p];\n            if(c==0) continue;\n            if(!allowZeroAdj[c]) continue;\n            if(totalCells[c] <= 1) continue;\n            int pi = p / n, pj = p % n;\n\n            // zero connectivity condition\n            bool canConnectZero = (pi==0 || pi==n-1 || pj==0 || pj==n-1);\n            if(!canConnectZero){\n                for(int dir=0;dir<4;dir++){\n                    int ni = pi + DX[dir], nj = pj + DY[dir];\n                    if(!inb(ni,nj)) continue;\n                    int q = ni*n+nj;\n                    if(d[q]==0 && zeroConn[q]){ canConnectZero = true; break; }\n                }\n            }\n            if(!canConnectZero) continue;\n\n            bool ok = true;\n\n            // Neighbor colors constraint\n            int neighColorsCnt = 0;\n            int neighArr[4];\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int y = d[ni*n+nj];\n                neighArr[neighColorsCnt++] = y;\n                if(y!=c && !allowZeroAdj[y]){ ok = false; break; }\n            }\n            if(!ok) continue;\n\n            // Preserve required adjacencies c-y\n            for(int k=0;k<neighColorsCnt;k++){\n                int y = neighArr[k];\n                if(y==c) continue;\n                if(A[c][y]){\n                    int contrib = 0;\n                    for(int dir=0;dir<4;dir++){\n                        int ni = pi + DX[dir], nj = pj + DY[dir];\n                        if(!inb(ni,nj)) continue;\n                        if(d[ni*n+nj]==y) contrib++;\n                    }\n                    if(adjCnt[c][y] == contrib){ ok = false; break; }\n                }\n            }\n            if(!ok) continue;\n\n            // Preserve c-0 adjacency if required\n            int k0 = 0;\n            if(pi==0) k0++;\n            if(pi==n-1) k0++;\n            if(pj==0) k0++;\n            if(pj==n-1) k0++;\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                if(d[ni*n+nj]==0) k0++;\n            }\n            if(A[0][c] && adjCnt[0][c] == k0){ continue; }\n\n            // Connectivity of c\n            if(!connectedAfterRemoval(c, p)) continue;\n\n            // Update adjCnt: remove edges adjacent to p\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(inb(ni,nj)){\n                    int y = d[ni*n+nj];\n                    if(y != c){\n                        adjCnt[c][y]--; adjCnt[y][c]--;\n                    }\n                }else{\n                    adjCnt[0][c]--; adjCnt[c][0]--;\n                }\n            }\n            // Set to 0\n            d[p] = 0;\n            totalCells[c]--;\n\n            // Mark/flood 0 connectivity\n            if(pi==0 || pi==n-1 || pj==0 || pj==n-1){\n                floodZeroFrom(p);\n            }else{\n                bool neighZeroConn = false;\n                for(int dir=0;dir<4;dir++){\n                    int ni = pi + DX[dir], nj = pj + DY[dir];\n                    if(!inb(ni,nj)) continue;\n                    int q = ni*n+nj;\n                    if(d[q]==0 && zeroConn[q]){ neighZeroConn = true; break; }\n                }\n                if(neighZeroConn) floodZeroFrom(p);\n                else{\n                    // Should not happen due to canConnectZero check\n                    zeroConn[p] = 0;\n                }\n            }\n\n            // Add new edges between 0 and neighbors\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int y = d[ni*n+nj];\n                if(y != 0){\n                    adjCnt[0][y]++; adjCnt[y][0]++;\n                }\n            }\n\n            improved = true;\n        }\n        auto t1 = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(t1 - t0).count();\n        if(elapsed > TIME_LIMIT) break;\n    }\n\n    // Output final grid\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            if(j) cout << ' ';\n            cout << d[i*n+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    uint64_t seed = chrono::high_resolution_clock::now().time_since_epoch().count();\n    mt19937_64 rng(seed);\n\n    // Budgets\n    int Q_duel = max(0, Q / 5);           // 20% for duels focusing on top items\n    int Q_corr = Q - Q_duel;              // rest for correlation\n    // Correlation parameters: three K values\n    int Ks[3];\n    Ks[0] = max(2, N / 2);\n    Ks[1] = max(2, N / 3);\n    Ks[2] = max(2, N / 4);\n\n    // Data\n    vector<long long> corr(N, 0);\n    vector<int> appear(N, 0);\n    vector<int> idx(N); iota(idx.begin(), idx.end(), 0);\n\n    auto do_query = [&](const vector<int>& L, const vector<int>& R)->int{\n        cout << (int)L.size() << \" \" << (int)R.size();\n        for (int v : L) cout << \" \" << v;\n        for (int v : R) cout << \" \" << v;\n        cout << \"\\n\" << flush;\n        string s; if (!(cin >> s)) exit(0);\n        if (s == \"<\") return -1;\n        if (s == \">\") return +1;\n        return 0;\n    };\n\n    // Helper: pick k distinct indices biased toward low appearance count\n    auto pick_k_biased = [&](int k)->vector<int>{\n        // Build weights inversely proportional to 1+appear\n        vector<double> w(N);\n        double sumw = 0;\n        for (int i = 0; i < N; i++) { w[i] = 1.0 / (1.0 + appear[i]); sumw += w[i]; }\n        vector<int> chosen;\n        chosen.reserve(k);\n        vector<char> used(N, 0);\n        for (int t = 0; t < k && t < N; t++) {\n            // sample index by roulette wheel\n            double r = uniform_real_distribution<double>(0, sumw)(rng);\n            int pick = -1;\n            double acc = 0;\n            for (int i = 0; i < N; i++) if (!used[i]) {\n                acc += w[i];\n                if (acc >= r) { pick = i; break; }\n            }\n            if (pick == -1) {\n                // fallback: choose first unused\n                for (int i = 0; i < N; i++) if (!used[i]) { pick = i; break; }\n            }\n            if (pick == -1) break;\n            used[pick] = 1;\n            chosen.push_back(pick);\n            sumw -= w[pick];\n        }\n        return chosen;\n    };\n\n    // Phase: correlation queries with mixed K and balanced participation\n    int kc = 0;\n    for (int q = 0; q < Q_corr; q++) {\n        int K = Ks[kc];\n        kc = (kc + 1) % 3;\n        K = min(K, N);\n        if (K < 2) K = 2;\n        vector<int> sel = pick_k_biased(K);\n        int k = (int)sel.size();\n        if (k < 2) {\n            // fallback: pick 2 random distinct\n            int a = uniform_int_distribution<int>(0, N-1)(rng);\n            int b = uniform_int_distribution<int>(0, N-1)(rng);\n            while (b == a) b = uniform_int_distribution<int>(0, N-1)(rng);\n            sel = {a, b};\n            k = 2;\n        }\n        // shuffle sel and split alternately\n        shuffle(sel.begin(), sel.end(), rng);\n        vector<int> L, R;\n        L.reserve(k/2+1); R.reserve(k/2+1);\n        for (int t = 0; t < k; t++) {\n            if (t & 1) R.push_back(sel[t]); else L.push_back(sel[t]);\n            appear[sel[t]]++;\n        }\n        int y = do_query(L, R);\n        if (y != 0) {\n            for (int v : L) corr[v] += y;\n            for (int v : R) corr[v] -= y;\n        }\n    }\n\n    // Build initial ranking by correlation\n    long long mnCorr = *min_element(corr.begin(), corr.end());\n    vector<double> corrScore(N);\n    for (int i = 0; i < N; i++) {\n        long long s = corr[i] - mnCorr + 1;\n        corrScore[i] = pow((double)s, 1.3); // slightly accentuate\n    }\n    // Normalize corrScore to [0,1]\n    double cmin = *min_element(corrScore.begin(), corrScore.end());\n    double cmax = *max_element(corrScore.begin(), corrScore.end());\n    if (cmax - cmin < 1e-12) cmax = cmin + 1.0;\n    for (int i = 0; i < N; i++) corrScore[i] = (corrScore[i] - cmin) / (cmax - cmin);\n\n    // Select top M for duels\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    stable_sort(ord.begin(), ord.end(), [&](int a, int b){\n        if (corrScore[a] != corrScore[b]) return corrScore[a] > corrScore[b];\n        return a < b;\n    });\n    int M = min(N, max(10, N / 2)); // duel among top half\n    vector<int> top(ord.begin(), ord.begin() + M);\n\n    // Duels among top to refine order\n    vector<int> wins(N, 0), games(N, 0);\n    for (int q = 0; q < Q_duel; q++) {\n        int ia = uniform_int_distribution<int>(0, M-1)(rng);\n        int ib = uniform_int_distribution<int>(0, M-1)(rng);\n        while (ib == ia) ib = uniform_int_distribution<int>(0, M-1)(rng);\n        int i = top[ia], j = top[ib];\n        int y = do_query(vector<int>{i}, vector<int>{j});\n        if (y > 0) wins[i]++; else if (y < 0) wins[j]++;\n        games[i]++; games[j]++;\n    }\n    vector<double> wr(N, 0.5);\n    for (int i = 0; i < N; i++) wr[i] = games[i] ? (double)wins[i]/games[i] : 0.5;\n    // Normalize wr to [0,1]\n    double wrMin = 1.0, wrMax = 0.0;\n    for (double x : wr) { wrMin = min(wrMin, x); wrMax = max(wrMax, x); }\n    if (wrMax - wrMin < 1e-12) wrMax = wrMin + 1.0;\n    vector<double> wrScaled(N);\n    for (int i = 0; i < N; i++) wrScaled[i] = (wr[i] - wrMin) / (wrMax - wrMin);\n\n    // Combine into final estimates and apply isotonic smoothing over corr order\n    vector<double> est(N);\n    double a_corr = 1.0, a_wr = 0.3;\n    for (int i = 0; i < N; i++) {\n        double v = a_corr * (1.0 + 9.0 * corrScore[i]) + a_wr * (1.0 + 4.0 * wrScaled[i]);\n        if (!isfinite(v) || v <= 0) v = 1.0;\n        est[i] = v;\n    }\n    // Isotonic smoothing along corr order to enforce non-increasing estimated weights\n    // Pool Adjacent Violators Algorithm (PAVA)\n    vector<double> smooth(N);\n    vector<int> block_sz(N, 1);\n    for (int p = 0; p < N; p++) smooth[p] = est[ord[p]];\n    for (int p = 1; p < N; p++) {\n        if (smooth[p] > smooth[p-1]) {\n            int q = p;\n            while (q > 0 && smooth[q] > smooth[q-1]) {\n                double s = smooth[q]*block_sz[q] + smooth[q-1]*block_sz[q-1];\n                int b = block_sz[q] + block_sz[q-1];\n                double avg = s / b;\n                smooth[q-1] = avg;\n                block_sz[q-1] = b;\n                // shift left by removing q\n                for (int t = q; t < N; t++) { smooth[t] = (t+1 < N ? smooth[t+1] : smooth[t]); block_sz[t] = (t+1 < N ? block_sz[t+1] : block_sz[t]); }\n                p--; // adjust due to shift\n                q--;\n            }\n        }\n    }\n    // Map smoothed back to items\n    vector<double> est_smooth(N);\n    for (int i = 0; i < N; i++) est_smooth[ord[i]] = smooth[i];\n\n    // Final ordering for packing\n    vector<int> order(N); iota(order.begin(), order.end(), 0);\n    stable_sort(order.begin(), order.end(), [&](int a, int b){\n        if (est_smooth[a] != est_smooth[b]) return est_smooth[a] > est_smooth[b];\n        return a < b;\n    });\n\n    // LPT packing\n    vector<int> assign(N, 0);\n    vector<double> bins(D, 0.0);\n    using PDI = pair<double,int>;\n    priority_queue<PDI, vector<PDI>, greater<PDI>> pq;\n    for (int d = 0; d < D; d++) pq.emplace(0.0, d);\n    for (int v : order) {\n        auto [s, d] = pq.top(); pq.pop();\n        assign[v] = d;\n        s += est_smooth[v];\n        bins[d] = s;\n        pq.emplace(s, d);\n    }\n\n    // Local search: focus on extremes with limited trials\n    vector<vector<int>> binItems(D);\n    for (int i = 0; i < N; i++) binItems[assign[i]].push_back(i);\n\n    auto variance = [&](const vector<double>& bs)->double{\n        double mean = 0; for (double x : bs) mean += x; mean /= D;\n        double v = 0; for (double x : bs){ double d = x-mean; v += d*d; }\n        return v / D;\n    };\n    int iters = 600;\n    for (int it = 0; it < iters; it++) {\n        int h = int(max_element(bins.begin(), bins.end()) - bins.begin());\n        int l = int(min_element(bins.begin(), bins.end()) - bins.begin());\n        if (h == l) break;\n        double baseVar = variance(bins);\n        double bestDelta = 0.0;\n        int bi = -1, bj = -1, bestType = 0;\n\n        // Candidates\n        vector<int> candH = binItems[h], candL = binItems[l];\n        int tryH = min((int)candH.size(), 24);\n        int tryL = min((int)candL.size(), 24);\n        if ((int)candH.size() > tryH) { shuffle(candH.begin(), candH.end(), rng); candH.resize(tryH); }\n        if ((int)candL.size() > tryL) { shuffle(candL.begin(), candL.end(), rng); candL.resize(tryL); }\n\n        // Single move\n        for (int i : candH) {\n            bins[h] -= est_smooth[i]; bins[l] += est_smooth[i];\n            double vnew = variance(bins);\n            double delta = baseVar - vnew;\n            bins[h] += est_smooth[i]; bins[l] -= est_smooth[i];\n            if (delta > bestDelta + 1e-12) { bestDelta = delta; bestType = 1; bi = i; }\n        }\n        // Swap\n        for (int i : candH) for (int j : candL) {\n            bins[h] = bins[h] - est_smooth[i] + est_smooth[j];\n            bins[l] = bins[l] - est_smooth[j] + est_smooth[i];\n            double vnew = variance(bins);\n            double delta = baseVar - vnew;\n            bins[h] = bins[h] + est_smooth[i] - est_smooth[j];\n            bins[l] = bins[l] + est_smooth[j] - est_smooth[i];\n            if (delta > bestDelta + 1e-12) { bestDelta = delta; bestType = 2; bi = i; bj = j; }\n        }\n        if (bestType == 0 || bestDelta <= 1e-12) break;\n\n        auto remove_from = [&](vector<int>& v, int x){\n            for (size_t p = 0; p < v.size(); ++p) if (v[p]==x){ v[p]=v.back(); v.pop_back(); return; }\n        };\n        if (bestType == 1) {\n            remove_from(binItems[h], bi);\n            binItems[l].push_back(bi);\n            bins[h] -= est_smooth[bi]; bins[l] += est_smooth[bi];\n        } else {\n            remove_from(binItems[h], bi);\n            remove_from(binItems[l], bj);\n            binItems[h].push_back(bj);\n            binItems[l].push_back(bi);\n            bins[h] = bins[h] - est_smooth[bi] + est_smooth[bj];\n            bins[l] = bins[l] - est_smooth[bj] + est_smooth[bi];\n        }\n    }\n\n    // Output final assignment\n    vector<int> finalAssign(N);\n    for (int d = 0; d < D; d++) for (int i : binItems[d]) finalAssign[i] = d;\n\n    for (int i = 0; i < N; i++) {\n        if (i) cout << ' ';\n        cout << finalAssign[i];\n    }\n    cout << \"\\n\" << flush;\n\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Heuristic solver for AHC026-like problem\n// n=200, m=10 fixed in tests, but code keeps generality.\n\nstruct Solver {\n    int n, m, H;\n    vector<vector<int>> st; // stacks: bottom -> top\n    vector<int> whereS; // stack index (0..m-1) for each box (1..n)\n    vector<int> whereIdx; // index in stack vector\n    vector<pair<int,int>> ops; // (v,i) with i in [0..m]\n    vector<char> removed;\n\n    void read_input() {\n        cin >> n >> m;\n        H = n / m;\n        st.assign(m, {});\n        whereS.assign(n+1, -1);\n        whereIdx.assign(n+1, -1);\n        removed.assign(n+1, 0);\n        for (int i = 0; i < m; ++i) {\n            st[i].resize(H);\n            for (int j = 0; j < H; ++j) {\n                int v; cin >> v;\n                st[i][j] = v;\n                whereS[v] = i;\n                whereIdx[v] = j;\n            }\n        }\n    }\n\n    inline int top_value(int i) const {\n        if (st[i].empty()) return INT_MAX/4; // treat empty as very large top for preference\n        return st[i].back();\n    }\n\n    void do_move(int v, int dest) {\n        // Operation 1: move suffix starting at v from its current stack to top of dest (1-based output dest+1)\n        int s = whereS[v];\n        if (s == dest) {\n            // avoid self-move; but spec allows it; however it's wasteful. We should not call this.\n            // To be safe, don't perform and don't record.\n            return;\n        }\n        int idx = whereIdx[v];\n        int k = (int)st[s].size() - idx; // number of boxes moved\n        // record op\n        ops.emplace_back(v, dest+1);\n        // move elements\n        // append to dest\n        st[dest].reserve(st[dest].size() + k);\n        for (int i = idx; i < (int)st[s].size(); ++i) {\n            int x = st[s][i];\n            st[dest].push_back(x);\n            whereS[x] = dest;\n            whereIdx[x] = (int)st[dest].size() - 1;\n        }\n        // erase from source\n        st[s].resize(idx);\n    }\n\n    void do_carry(int v) {\n        // Operation 2: carry out v; it must be top of its stack and be the smallest remaining.\n        int s = whereS[v];\n        if (s == -1) return; // already removed\n        // record op\n        ops.emplace_back(v, 0);\n        // pop\n        int topv = st[s].back();\n        if (topv != v) {\n            // Shouldn't happen; guard\n            // Find v and remove it (fallback)\n            auto it = find(st[s].begin(), st[s].end(), v);\n            if (it != st[s].end()) {\n                st[s].erase(it);\n                // rebuild indices in this stack\n                for (int i = 0; i < (int)st[s].size(); ++i) whereIdx[st[s][i]] = i;\n            }\n        } else {\n            st[s].pop_back();\n        }\n        whereS[v] = -1;\n        whereIdx[v] = -1;\n        removed[v] = 1;\n    }\n\n    int choose_dest(int v) {\n        int s = whereS[v];\n        // Preferred bin stack\n        int bin = (v - 1) / H; // 0-based\n        int d_pref = min(bin, m-1); // guard\n        if (d_pref != s) return d_pref;\n        // choose another stack:\n        int best = -1;\n        int bestTop = -1;\n        int bestHeight = INT_MAX;\n        for (int i = 0; i < m; ++i) if (i != s) {\n            int tv = top_value(i);\n            // prefer larger top value; empty stack has INT_MAX/4 which is largest\n            if (tv > bestTop) {\n                bestTop = tv;\n                bestHeight = (int)st[i].size();\n                best = i;\n            } else if (tv == bestTop) {\n                int h = (int)st[i].size();\n                if (h < bestHeight) {\n                    bestHeight = h;\n                    best = i;\n                }\n            }\n        }\n        if (best == -1) best = (s+1)%m;\n        return best;\n    }\n\n    void solve() {\n        // Process in ascending order\n        for (int t = 1; t <= n; ++t) {\n            if (removed[t]) continue;\n            int s = whereS[t];\n            // while t not at top of its stack, move suffix including t to chosen destination\n            if (st[s].empty()) continue; // shouldn't\n            if (st[s].back() == t) {\n                do_carry(t);\n                continue;\n            }\n            int dest = choose_dest(t);\n            // perform move so that t becomes top of dest\n            do_move(t, dest);\n            // Now t should be top at dest\n            do_carry(t);\n            // No further consolidation to keep it simple\n            if ((int)ops.size() >= 4999) {\n                // fallback: carry remaining if possible when already on top\n                for (int u = t+1; u <= n && (int)ops.size() < 5000; ++u) {\n                    if (!removed[u]) {\n                        int su = whereS[u];\n                        if (su != -1 && !st[su].empty() && st[su].back() == u) {\n                            do_carry(u);\n                        } else {\n                            // cannot finish, break\n                            break;\n                        }\n                    }\n                }\n                break;\n            }\n        }\n    }\n\n    void output() {\n        int K = (int)ops.size();\n        for (auto &p : ops) {\n            cout << p.first << \" \" << p.second << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver solver;\n    solver.read_input();\n    solver.solve();\n    solver.output();\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin>>N)) return 0;\n    vector<string> h(N-1), v(N);\n    for(int i=0;i<N-1;i++) cin>>h[i];\n    for(int i=0;i<N;i++) cin>>v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>d[i][j];\n\n    auto inb = [&](int i,int j){ return 0<=i && i<N && 0<=j && j<N; };\n    auto canMoveDir = [&](int i,int j,int dir)->bool{\n        // 0:R,1:D,2:L,3:U\n        if(dir==0){ if(j+1>=N) return false; return v[i][j]=='0'; }\n        if(dir==2){ if(j-1<0)   return false; return v[i][j-1]=='0'; }\n        if(dir==1){ if(i+1>=N) return false; return h[i][j]=='0'; }\n        if(dir==3){ if(i-1<0)   return false; return h[i-1][j]=='0'; }\n        return false;\n    };\n    const int di[4]={0,1,0,-1};\n    const int dj[4]={1,0,-1,0};\n    string DIR = \"RDLU\";\n\n    auto bfs_path = [&](Pos s, Pos t)->vector<int>{\n        if(s.i==t.i && s.j==t.j) return {};\n        int H=N, W=N;\n        vector<int> prevDir(H*W, -1);\n        vector<int> vis(H*W, 0);\n        deque<Pos> q;\n        auto idx = [&](int i,int j){ return i*W + j; };\n        q.push_back(s);\n        vis[idx(s.i,s.j)] = 1;\n        while(!q.empty()){\n            auto p = q.front(); q.pop_front();\n            if(p.i==t.i && p.j==t.j) break;\n            for(int dir=0; dir<4; dir++){\n                int ni=p.i+di[dir], nj=p.j+dj[dir];\n                if(!inb(ni,nj)) continue;\n                if(!canMoveDir(p.i,p.j,dir)) continue;\n                int id = idx(ni,nj);\n                if(vis[id]) continue;\n                vis[id]=1;\n                prevDir[id] = dir;\n                q.push_back({ni,nj});\n            }\n        }\n        vector<int> path_dirs;\n        int curi=t.i, curj=t.j;\n        if(!vis[idx(curi,curj)]){\n            // Should not happen due to connectivity, but fallback: empty\n            return path_dirs;\n        }\n        while(!(curi==s.i && curj==s.j)){\n            int dir = prevDir[idx(curi,curj)];\n            path_dirs.push_back(dir);\n            // move backward along reverse of dir\n            int rev = (dir+2)%4;\n            curi += di[rev];\n            curj += dj[rev];\n        }\n        reverse(path_dirs.begin(), path_dirs.end());\n        return path_dirs;\n    };\n\n    // Build serpentine order of all cells\n    vector<Pos> targetOrder;\n    targetOrder.reserve(N*N);\n    for(int i=0;i<N;i++){\n        if(i%2==0){\n            for(int j=0;j<N;j++) targetOrder.push_back({i,j});\n        }else{\n            for(int j=N-1;j>=0;j--) targetOrder.push_back({i,j});\n        }\n    }\n    // Ensure start is (0,0); targetOrder[0] is (0,0), good.\n\n    // Build base moves by chaining shortest paths\n    string baseMoves;\n    baseMoves.reserve(N*N*2);\n    Pos cur = targetOrder[0];\n    for(size_t k=1;k<targetOrder.size();k++){\n        auto seg = bfs_path(cur, targetOrder[k]);\n        for(int dir: seg) baseMoves.push_back(DIR[dir]);\n        cur = targetOrder[k];\n    }\n    // Return to (0,0)\n    {\n        auto seg = bfs_path(cur, {0,0});\n        for(int dir: seg) baseMoves.push_back(DIR[dir]);\n        cur = {0,0};\n    }\n\n    // Reconstruct nodes along baseMoves\n    vector<Pos> baseNodes;\n    baseNodes.reserve(baseMoves.size()+1);\n    {\n        int i=0,j=0;\n        baseNodes.push_back({i,j});\n        for(char c: baseMoves){\n            int dir = (c=='R'?0: c=='D'?1: c=='L'?2:3);\n            // trust canMoveDir\n            i += di[dir]; j += dj[dir];\n            baseNodes.push_back({i,j});\n        }\n        // Should be back at (0,0)\n    }\n\n    // Precompute best local loop per cell\n    struct Loop { vector<int> dirs; };\n    vector<vector<Loop>> loopOf(N, vector<Loop>(N));\n    auto makeLoopAt = [&](int i,int j)->Loop{\n        struct Cand { int score; vector<int> dirs; };\n        vector<Cand> cands;\n        auto add4 = [&](int a, int b){\n            int i0=i, j0=j;\n            if(!canMoveDir(i0,j0,a)) return;\n            int i1=i0+di[a], j1=j0+dj[a];\n            if(!canMoveDir(i1,j1,b)) return;\n            int i2=i1+di[b], j2=j1+dj[b];\n            int a2=(a+2)%4, b2=(b+2)%4;\n            if(!canMoveDir(i2,j2,a2)) return;\n            int i3=i2+di[a2], j3=j2+dj[a2];\n            if(!(i3==i1 && j3==j1)) return;\n            if(!canMoveDir(i3,j3,b2)) return;\n            int i4=i3+di[b2], j4=j3+dj[b2];\n            if(!(i4==i && j4==j)) return;\n            int score = d[i][j] + d[i1][j1] + d[i2][j2] + d[i3][j3];\n            cands.push_back({score, {a,b,a2,b2}});\n        };\n        add4(0,1); add4(1,2); add4(2,3); add4(3,0);\n        if(!cands.empty()){\n            auto best = *max_element(cands.begin(), cands.end(), [](const Cand&a,const Cand&b){return a.score<b.score;});\n            return Loop{best.dirs};\n        }\n        // Fallback 2-step ping-pong\n        int bestDir=-1, bestScore=-1;\n        for(int dir=0; dir<4; dir++){\n            if(!canMoveDir(i,j,dir)) continue;\n            int ni=i+di[dir], nj=j+dj[dir];\n            int sc = d[i][j] + d[ni][nj];\n            if(sc>bestScore){ bestScore=sc; bestDir=dir; }\n        }\n        if(bestDir!=-1) return Loop{ vector<int>{bestDir, (bestDir+2)%4} };\n        return Loop{ vector<int>() };\n    };\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) loopOf[i][j]=makeLoopAt(i,j);\n\n    // For each cell, record visit times along baseNodes\n    int L0 = (int)baseMoves.size();\n    vector<vector<vector<int>>> visits(N, vector<vector<int>>(N));\n    for(int t=0;t<(int)baseNodes.size();t++){\n        auto p = baseNodes[t];\n        visits[p.i][p.j].push_back(t);\n    }\n    // Compute gap estimate per cell (average steps between consecutive visits in base cycle)\n    vector<vector<double>> gapEst(N, vector<double>(N, 0.0));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            auto &vec = visits[i][j];\n            if(vec.size()<=1){\n                gapEst[i][j] = (double)L0; // visited once; approximate large gap\n            }else{\n                long long sumGap = 0;\n                for(size_t k=1;k<vec.size();k++) sumGap += (vec[k]-vec[k-1]);\n                // cycle wrap: from last to first across end\n                sumGap += ( (int)baseNodes.size()-1 - vec.back() ) + vec.front();\n                double avgGap = (double)sumGap / (double)vec.size();\n                gapEst[i][j] = max(1.0, avgGap);\n            }\n        }\n    }\n\n    // Build candidate hotspots with priority = d * gap / cost\n    struct Hot { int i,j; int cost; double pr; };\n    vector<Hot> hots;\n    hots.reserve(N*N);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        int cost = (int)loopOf[i][j].dirs.size();\n        if(cost==0) continue;\n        double pr = (double)d[i][j] * gapEst[i][j] / (double)cost;\n        hots.push_back({i,j,cost,pr});\n    }\n    if(hots.empty()){\n        cout<<baseMoves<<\"\\n\";\n        return 0;\n    }\n    sort(hots.begin(), hots.end(), [](const Hot&a,const Hot&b){ return a.pr > b.pr; });\n    // Limit to top K to keep structures small\n    int K = min((int)hots.size(), max(50, (N*N)/8)); // keep enough\n    hots.resize(K);\n\n    // Budget\n    long long budgetMax = 100000LL;\n    long long B = budgetMax - (long long)L0;\n    if(B < 0) B = 0;\n\n    // For each hot cell, plan total repeats proportional to priority and also bounded by number of occurrences\n    double totalPr = 0.0;\n    for(auto &hcell : hots) totalPr += max(1e-9, hcell.pr);\n    vector<long long> repeats(K, 0);\n    long long used = 0;\n    // Build occurrences list per hot\n    vector<vector<int>> occIdx(K);\n    occIdx.reserve(K);\n    unordered_map<long long,int> hotIndex; hotIndex.reserve(K*2);\n    auto keyOf = [&](int i,int j)->long long{ return ((long long)i<<20) ^ j; };\n    for(int idx=0; idx<K; idx++){\n        hotIndex[keyOf(hots[idx].i, hots[idx].j)] = idx;\n        // take indices where we are at the cell (node index), we can inject before emitting subsequent move\n        occIdx[idx] = visits[hots[idx].i][hots[idx].j];\n    }\n    // Allocate\n    for(int idx=0; idx<K; idx++){\n        auto &hc = hots[idx];\n        double frac = max(1e-12, hc.pr) / totalPr;\n        long long targetCost = (long long) floor(frac * (double)B);\n        long long rep = targetCost / hc.cost;\n        // distribute across occurrences: limit per-visit loops to small number\n        long long perVisitCap = 20; // tighter cap to avoid burst\n        long long cap = (long long)occIdx[idx].size() * perVisitCap;\n        if(rep > cap) rep = cap;\n        repeats[idx] = rep;\n        used += rep * hc.cost;\n    }\n    if(used > B){\n        double scale = (double)B / (double)max(1LL, used);\n        used = 0;\n        for(int idx=0; idx<K; idx++){\n            long long rep = (long long) floor(repeats[idx] * scale);\n            repeats[idx]=rep;\n            used += rep * hots[idx].cost;\n        }\n    }\n    long long rem = B - used;\n    // Greedy distribute residual to best efficiency w/cost\n    if(rem > 0){\n        vector<int> ord(K);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a,int b){\n            double ea = (double)d[hots[a].i][hots[a].j] / hots[a].cost;\n            double eb = (double)d[hots[b].i][hots[b].j] / hots[b].cost;\n            return ea>eb;\n        });\n        for(int round=0; round<3 && rem>0; round++){\n            for(int id: ord){\n                if(rem<=0) break;\n                int cost = hots[id].cost;\n                if(cost==0) continue;\n                long long occ = (long long)occIdx[id].size();\n                long long extraCap = occ * 5; // small extra\n                long long can = min(extraCap, rem / cost);\n                if(can<=0) continue;\n                repeats[id] += can;\n                rem -= can * cost;\n                if(rem<=0) break;\n            }\n        }\n    }\n\n    // Build per-occurrence distribution: spread repeats evenly over occurrence indices for each hot\n    struct Plan { int idx; int occCount; vector<long long> perOcc; };\n    vector<Plan> plans(K);\n    for(int idx=0; idx<K; idx++){\n        auto &occ = occIdx[idx];\n        int m = (int)occ.size();\n        plans[idx].idx = idx;\n        plans[idx].occCount = m;\n        plans[idx].perOcc.assign(m, 0);\n        long long R = repeats[idx];\n        if(m>0 && R>0){\n            // spread round-robin\n            for(long long r=0; r<R; r++){\n                plans[idx].perOcc[r % m]++;\n            }\n            // cap per-visit\n            long long cap = 25;\n            for(int t=0;t<m;t++){\n                if(plans[idx].perOcc[t] > cap) plans[idx].perOcc[t]=cap;\n            }\n        }\n    }\n\n    // Create a map from node index t to a list of loops to inject there (counts)\n    vector<long long> injectCount(baseNodes.size(), 0);\n    vector<const Loop*> injectLoop(baseNodes.size(), nullptr); // loop used at that cell\n    for(int idx=0; idx<K; idx++){\n        auto &occ = occIdx[idx];\n        auto &per = plans[idx].perOcc;\n        for(int k=0;k<(int)occ.size();k++){\n            int t = occ[k];\n            if(per[k] > 0){\n                injectCount[t] += per[k];\n                injectLoop[t] = &loopOf[ hots[idx].i ][ hots[idx].j ];\n            }\n        }\n    }\n\n    // Emit final moves with injection, while respecting total length \u2264 1e5\n    string out;\n    out.reserve( min(100000LL, (long long)L0 + B) );\n    long long budgetMoves = 100000LL;\n    long long remainingBase = (long long)baseMoves.size();\n    // Iterate over node indices; at node t, inject its loops as much as possible while keeping enough budget for remaining base moves\n    for(size_t t=0; t<baseNodes.size(); t++){\n        long long cnt = injectCount[t];\n        const Loop* lp = injectLoop[t];\n        if(cnt>0 && lp && !lp->dirs.empty()){\n            int cost = (int)lp->dirs.size();\n            // available free budget beyond remaining base moves\n            while(cnt>0){\n                if(budgetMoves <= remainingBase) break;\n                long long free = budgetMoves - remainingBase;\n                if(free < cost) break;\n                for(int dir: lp->dirs){\n                    out.push_back(DIR[dir]);\n                    budgetMoves--;\n                }\n                cnt--;\n            }\n            // update remaining count in case we want to continue later; but we won't revisit same t\n        }\n        if(t < baseMoves.size()){\n            // emit base move\n            if(budgetMoves==0) break;\n            out.push_back(baseMoves[t]);\n            budgetMoves--;\n            remainingBase--;\n        }\n    }\n    cout<<out<<\"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\nstatic inline long long manh(const Pos& a, const Pos& b){\n    return llabs(a.i - b.i) + llabs(a.j - b.j);\n}\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 si, sj;\n    cin >> si >> sj;\n    vector<string> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\n    vector<string> t(M);\n    for(int k=0;k<M;k++) cin >> t[k];\n\n    // Positions per letter\n    vector<vector<Pos>> pos(26);\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            pos[A[i][j]-'A'].push_back({i,j});\n        }\n    }\n\n    // Precompute per-word data\n    struct WordData {\n        array<vector<Pos>,5> L;\n        vector<long long> back1;     // on L1\n        vector<long long> tailCost0; // per L0 index: min cost from that first to finish\n    };\n    vector<WordData> W(M);\n    for(int k=0;k<M;k++){\n        const string &s = t[k];\n        for(int d=0; d<5; d++) W[k].L[d] = pos[s[d]-'A'];\n        // backward DP to compute back1 and tailCost0\n        const auto &L0 = W[k].L[0];\n        const auto &L1 = W[k].L[1];\n        const auto &L2 = W[k].L[2];\n        const auto &L3 = W[k].L[3];\n        const auto &L4 = W[k].L[4];\n        int n1=L1.size(), n2=L2.size(), n3=L3.size(), n4=L4.size();\n\n        vector<long long> back3(n3, (long long)4e18);\n        for(int j=0;j<n3;j++){\n            long long best=(long long)4e18;\n            for(int i4=0;i4<n4;i4++){\n                best = min(best, manh(L3[j], L4[i4]));\n            }\n            back3[j]=best;\n        }\n        vector<long long> back2(n2, (long long)4e18);\n        for(int j=0;j<n2;j++){\n            long long best=(long long)4e18;\n            for(int i3=0;i3<n3;i3++){\n                best = min(best, manh(L2[j], L3[i3]) + back3[i3]);\n            }\n            back2[j]=best;\n        }\n        W[k].back1.assign(n1, (long long)4e18);\n        for(int j=0;j<n1;j++){\n            long long best=(long long)4e18;\n            for(int i2=0;i2<n2;i2++){\n                best = min(best, manh(L1[j], L2[i2]) + back2[i2]);\n            }\n            W[k].back1[j]=best;\n        }\n        int n0 = L0.size();\n        W[k].tailCost0.assign(n0, (long long)4e18);\n        for(int i0=0;i0<n0;i0++){\n            long long best=(long long)4e18;\n            for(int i1=0;i1<n1;i1++){\n                best = min(best, manh(L0[i0], L1[i1]) + W[k].back1[i1]);\n            }\n            W[k].tailCost0[i0]=best;\n        }\n    }\n\n    vector<int> rem(M);\n    iota(rem.begin(), rem.end(), 0);\n    vector<pair<int,int>> ops;\n    ops.reserve(200*5);\n    Pos cur{si,sj};\n\n    const double BETA = 0.3;\n    const int K_END = 4; // number of end candidates per word\n\n    while(!rem.empty()){\n        long long bestCost = (1LL<<60);\n        double bestAug = 1e100;\n        int bestIdxPos = -1;\n        array<int,5> bestIdxInLevels = {-1,-1,-1,-1,-1};\n\n        // Evaluate each remaining word\n        for(int p=0; p<(int)rem.size(); p++){\n            int a = rem[p];\n            auto &wd = W[a];\n            const auto &L0 = wd.L[0];\n            const auto &L1 = wd.L[1];\n            const auto &L2 = wd.L[2];\n            const auto &L3 = wd.L[3];\n            const auto &L4 = wd.L[4];\n            int n0=L0.size(), n1=L1.size(), n2=L2.size(), n3=L3.size(), n4=L4.size();\n            if(n0==0||n1==0||n2==0||n3==0||n4==0) continue;\n\n            // Exact DP from cur, but collect top-K ends\n            vector<long long> d0(n0), d1(n1,(long long)4e18), d2(n2,(long long)4e18), d3(n3,(long long)4e18), d4(n4,(long long)4e18);\n            for(int i0=0;i0<n0;i0++) d0[i0] = manh(cur, L0[i0]);\n            vector<int> p0(n1,-1), p1(n2,-1), p2(n3,-1), p3(n4,-1);\n            for(int i1=0;i1<n1;i1++){\n                long long best=(long long)4e18; int arg=-1;\n                for(int i0=0;i0<n0;i0++){\n                    long long v = d0[i0] + manh(L0[i0], L1[i1]);\n                    if(v<best){best=v; arg=i0;}\n                }\n                d1[i1]=best; p0[i1]=arg;\n            }\n            for(int i2=0;i2<n2;i2++){\n                long long best=(long long)4e18; int arg=-1;\n                for(int i1=0;i1<n1;i1++){\n                    long long v = d1[i1] + manh(L1[i1], L2[i2]);\n                    if(v<best){best=v; arg=i1;}\n                }\n                d2[i2]=best; p1[i2]=arg;\n            }\n            for(int i3=0;i3<n3;i3++){\n                long long best=(long long)4e18; int arg=-1;\n                for(int i2=0;i2<n2;i2++){\n                    long long v = d2[i2] + manh(L2[i2], L3[i3]);\n                    if(v<best){best=v; arg=i2;}\n                }\n                d3[i3]=best; p2[i3]=arg;\n            }\n            // Compute costs to each i4\n            for(int i4=0;i4<n4;i4++){\n                long long bestv=(long long)4e18; int arg=-1;\n                for(int i3=0;i3<n3;i3++){\n                    long long v = d3[i3] + manh(L3[i3], L4[i4]);\n                    if(v<bestv){bestv=v; arg=i3;}\n                }\n                d4[i4]=bestv; p3[i4]=arg;\n            }\n            // Select top-K_END ends\n            vector<int> order4(n4);\n            iota(order4.begin(), order4.end(), 0);\n            int take = min(K_END, n4);\n            nth_element(order4.begin(), order4.begin()+take-1, order4.end(), [&](int aIdx, int bIdx){\n                return d4[aIdx] < d4[bIdx];\n            });\n            partial_sort(order4.begin(), order4.begin()+take, order4.end(), [&](int aIdx, int bIdx){\n                return d4[aIdx] < d4[bIdx];\n            });\n\n            // For each end candidate, compute best next cost and augmented score\n            for(int rk=0; rk<take; rk++){\n                int i4 = order4[rk];\n                long long costA = d4[i4];\n\n                // Backtrack the chain indices\n                int i3 = p3[i4];\n                int i2 = p2[i3];\n                int i1 = p1[i2];\n                int i0 = p0[i1];\n                Pos endA = L4[i4];\n\n                // Estimate cheapest next word from endA using precomputed tail costs\n                long long bestNext = (long long)4e18;\n                if(rem.size()>1){\n                    for(int q=0; q<(int)rem.size(); q++){\n                        if(q==p) continue;\n                        int b = rem[q];\n                        auto &wb = W[b];\n                        const auto &LB0 = wb.L[0];\n                        const auto &tail = wb.tailCost0;\n                        int m0 = LB0.size();\n                        // simple lower bound: min tail\n                        long long minTail = (long long)4e18;\n                        for(long long v: tail) if(v < minTail) minTail = v;\n                        if(minTail >= bestNext) {\n                            // Even with zero distance, can't beat current best\n                            // continue to next word\n                        }\n                        for(int j0=0;j0<m0;j0++){\n                            long long v = manh(endA, LB0[j0]) + tail[j0];\n                            if(v < bestNext) bestNext = v;\n                        }\n                    }\n                    if(bestNext == (long long)4e18) bestNext = 0;\n                } else {\n                    bestNext = 0;\n                }\n\n                double aug = (double)costA + BETA * (double)bestNext;\n\n                if(aug < bestAug || (abs(aug - bestAug) < 1e-9 && costA < bestCost)){\n                    bestAug = aug;\n                    bestCost = costA;\n                    bestIdxPos = p;\n                    bestIdxInLevels = {i0, i1, i2, i3, i4};\n                }\n            }\n        }\n\n        if(bestIdxPos == -1) break;\n\n        int chosen = rem[bestIdxPos];\n        auto &wd = W[chosen];\n        array<Pos,5> seq = {\n            wd.L[0][bestIdxInLevels[0]],\n            wd.L[1][bestIdxInLevels[1]],\n            wd.L[2][bestIdxInLevels[2]],\n            wd.L[3][bestIdxInLevels[3]],\n            wd.L[4][bestIdxInLevels[4]]\n        };\n        for(int z=0; z<5; z++){\n            ops.emplace_back(seq[z].i, seq[z].j);\n            cur = seq[z];\n        }\n        rem.erase(rem.begin() + bestIdxPos);\n    }\n\n    for(auto &p : ops){\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int di, dj;\n    vector<int> cells;\n    bitset<400> mask; // up to 20*20\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n    if (!(cin >> N >> M >> eps)) return 0;\n    int G = N*N;\n    auto idx = [N](int i,int j){ return i*N + j; };\n    auto ij = [N](int p){ return pair<int,int>(p/N, p%N); };\n\n    vector<vector<pair<int,int>>> shapes(M);\n    vector<int> shape_h(M), shape_w(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        int min_i = INT_MAX, min_j = INT_MAX, max_i = INT_MIN, max_j = INT_MIN;\n        for (int t = 0; t < d; ++t) {\n            int i,j; cin >> i >> j;\n            shapes[k][t] = {i,j};\n            min_i = min(min_i, i);\n            min_j = min(min_j, j);\n            max_i = max(max_i, i);\n            max_j = max(max_j, j);\n        }\n        shape_h[k] = max_i - min_i + 1;\n        shape_w[k] = max_j - min_j + 1;\n    }\n\n    // Generate candidates\n    vector<vector<Placement>> candidates(M);\n    for (int k = 0; k < M; ++k) {\n        int h = shape_h[k], w = shape_w[k];\n        for (int di = 0; di + h <= N; ++di) {\n            for (int dj = 0; dj + w <= N; ++dj) {\n                Placement P; P.di = di; P.dj = dj;\n                P.mask.reset();\n                bool ok = true;\n                for (auto [oi,oj] : shapes[k]) {\n                    int i = di + oi, j = dj + oj;\n                    if (i<0||i>=N||j<0||j>=N) { ok=false; break; }\n                    int p = idx(i,j);\n                    P.cells.push_back(p);\n                    P.mask.set(p);\n                }\n                if (ok) candidates[k].push_back(move(P));\n            }\n        }\n    }\n\n    // Reverse index (k,t) covering p\n    vector<vector<pair<int,int>>> cell_covers(G);\n    for (int k = 0; k < M; ++k) {\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            for (int p : candidates[k][t].cells) {\n                cell_covers[p].push_back({k,t});\n            }\n        }\n    }\n\n    // Alive flags and counts\n    vector<vector<char>> alive(M);\n    vector<int> alive_count(M);\n    for (int k = 0; k < M; ++k) {\n        alive[k].assign(candidates[k].size(), 1);\n        alive_count[k] = (int)candidates[k].size();\n    }\n\n    // Per-shape per-cell count of alive candidates covering p\n    vector<vector<int>> cnt_cover(M, vector<int>(G, 0));\n    // For each cell, total number of alive candidates covering it (across shapes)\n    vector<int> cover_count(G, 0);\n    // Per cell, number of shapes that can cover it (have at least one alive candidate covering it)\n    vector<int> S_can(G, 0);\n    for (int k = 0; k < M; ++k) {\n        vector<char> can(N*N, 0);\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            for (int p : candidates[k][t].cells) {\n                cnt_cover[k][p]++;\n                cover_count[p]++;\n                can[p] = 1;\n            }\n        }\n        for (int p = 0; p < G; ++p) if (can[p]) S_can[p]++;\n    }\n\n    // Forced coverage constraints: for shape k, set of cells that must be covered by its placement\n    vector<bitset<400>> forced_cover(M);\n    for (int k = 0; k < M; ++k) forced_cover[k].reset();\n\n    // cell state: -1 unknown, 0 zero, 1 positive\n    vector<int> state(G, -1);\n\n    auto flushout = [](){ cout.flush(); };\n\n    deque<int> shapes_to_commit;\n\n    auto kill_candidate = [&](int k, int t) {\n        if (!alive[k][t]) return;\n        alive[k][t] = 0;\n        alive_count[k]--;\n        // update counts\n        const bitset<400>& m = candidates[k][t].mask;\n        for (int p = m._Find_first(); p < G; p = m._Find_next(p)) {\n            cnt_cover[k][p]--;\n            cover_count[p]--;\n            if (cnt_cover[k][p] == 0) {\n                S_can[p]--;\n            }\n        }\n        if (alive_count[k] == 1) shapes_to_commit.push_back(k);\n    };\n\n    // Apply forced constraints for shape k: eliminate any candidate not covering all forced cells\n    auto enforce_forced = [&](int k) {\n        const bitset<400>& fc = forced_cover[k];\n        if (fc.none()) return;\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            if (!alive[k][t]) continue;\n            // candidate must include all forced bits\n            // Check (mask & fc) == fc\n            bitset<400> tmp = candidates[k][t].mask;\n            tmp &= fc;\n            if (tmp != fc) {\n                kill_candidate(k,t);\n            }\n        }\n    };\n\n    auto commit_singletons = [&]() {\n        while (!shapes_to_commit.empty()) {\n            int k = shapes_to_commit.front(); shapes_to_commit.pop_front();\n            if (alive_count[k] != 1) continue;\n            int tstar = -1;\n            for (int t = 0; t < (int)alive[k].size(); ++t) if (alive[k][t]) { tstar = t; break; }\n            if (tstar == -1) continue;\n            // Mark its cells as positive\n            for (int p : candidates[k][tstar].cells) {\n                if (state[p] == -1) state[p] = 1;\n            }\n            // Also, its forced constraints are trivially satisfied; no further eliminations needed here.\n        }\n    };\n\n    auto all_singleton = [&]() -> bool {\n        for (int k = 0; k < M; ++k) if (alive_count[k] != 1) return false;\n        return true;\n    };\n\n    auto select_next = [&]() -> int {\n        int bestp = -1;\n        long long bestScore = LLONG_MIN;\n        for (int p = 0; p < G; ++p) {\n            if (state[p] != -1) continue;\n            if (S_can[p] == 0) {\n                // can already mark zero; skip drilling\n                continue;\n            }\n            // composite score: prioritize high cover_count and small S_can\n            long long score = 2LL * cover_count[p] + (10 - S_can[p]);\n            if (score > bestScore) {\n                bestScore = score;\n                bestp = p;\n            }\n        }\n        if (bestp == -1) {\n            // fallback any unknown\n            for (int p = 0; p < G; ++p) if (state[p]==-1) return p;\n        }\n        return bestp;\n    };\n\n    int ops_used = 0, max_ops = 2*N*N;\n\n    // Propagate zeros for S_can==0\n    auto propagate_zero_cells = [&]() {\n        for (int p = 0; p < G; ++p) {\n            if (state[p] == -1 && S_can[p] == 0) state[p] = 0;\n        }\n    };\n    propagate_zero_cells();\n\n    while (ops_used < max_ops) {\n        if (all_singleton()) break;\n\n        // If all remaining unknowns are determinable as zero without drilling, stop loop\n        bool undecidedNeedsDrill = false;\n        for (int p = 0; p < G; ++p) {\n            if (state[p] == -1 && S_can[p] > 0) { undecidedNeedsDrill = true; break; }\n        }\n        if (!undecidedNeedsDrill) break;\n\n        int p = select_next();\n        if (p == -1) break;\n        auto [i,j] = ij(p);\n        cout << \"q 1 \" << i << ' ' << j << '\\n';\n        flushout();\n        ops_used++;\n        int vresp;\n        if (!(cin >> vresp)) return 0;\n        if (vresp == 0) {\n            state[p] = 0;\n            // eliminate all candidates covering p\n            // Iterate current list; but some entries might already be dead\n            for (auto [k,t] : cell_covers[p]) {\n                if (alive[k][t]) kill_candidate(k,t);\n            }\n            commit_singletons();\n            propagate_zero_cells();\n        } else {\n            state[p] = 1;\n            // Positive constraints\n            int x = vresp;\n            int Sc = S_can[p];\n            // If Sc == 0 this contradicts, but shouldn't happen.\n            if (Sc > 0) {\n                // If exactly x shapes can possibly cover p, then each of those must cover p\n                // In both this case and the more general case below, we enforce for some shapes that they must cover p\n                // Determine shapes where they must cover p\n                for (int k = 0; k < M; ++k) {\n                    if (cnt_cover[k][p] > 0) {\n                        int others = Sc - 1;\n                        if (others < x) {\n                            // shape k must cover p\n                            if (!forced_cover[k].test(p)) {\n                                forced_cover[k].set(p);\n                                enforce_forced(k);\n                            }\n                        }\n                    }\n                }\n                // Special case Sc==x: all shapes that can cover must cover\n                if (Sc == x) {\n                    for (int k = 0; k < M; ++k) {\n                        if (cnt_cover[k][p] > 0) {\n                            if (!forced_cover[k].test(p)) {\n                                forced_cover[k].set(p);\n                                enforce_forced(k);\n                            }\n                        }\n                    }\n                }\n                commit_singletons();\n                propagate_zero_cells();\n            }\n        }\n        if (ops_used >= max_ops) break;\n    }\n\n    // If still undecided cells, drill remaining unknowns to guarantee correctness\n    for (int p = 0; p < G && ops_used < max_ops; ++p) {\n        if (state[p] == -1) {\n            auto [i,j] = ij(p);\n            cout << \"q 1 \" << i << ' ' << j << '\\n';\n            flushout();\n            ops_used++;\n            int vresp;\n            if (!(cin >> vresp)) return 0;\n            state[p] = (vresp > 0) ? 1 : 0;\n            if (vresp == 0) {\n                // optional: could prune, but near end it doesn't matter\n            }\n        }\n    }\n\n    // Build answer: all cells with state==1\n    vector<pair<int,int>> ans;\n    ans.reserve(G);\n    for (int p = 0; p < G; ++p) if (state[p] == 1) ans.push_back(ij(p));\n\n    cout << \"a \" << ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n';\n    flushout();\n\n    int ok;\n    if (!(cin >> ok)) return 0;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int i0, j0, i1, j1;\n    long long area() const { return 1LL*(i1-i0)*(j1-j0); }\n};\n\nstatic inline long long ceil_div(long long a, long long b){\n    return (a + b - 1) / b;\n}\n\nstruct ShelfRow {\n    int h; // for horizontal shelves\n    int rem_w;\n    vector<pair<int,int>> items; // width, rankIndex\n};\nstruct ShelfCol {\n    int w; // for vertical shelves\n    int rem_h;\n    vector<pair<int,int>> items; // height, rankIndex\n};\n\n// Try horizontal shelf packing: rows with heights, items as widths in rows.\nbool pack_horizontal(int W, const vector<long long>& B_sorted_asc, vector<Rect>& blocks_out){\n    int N = (int)B_sorted_asc.size();\n    vector<long long> Bd = B_sorted_asc;\n    sort(Bd.begin(), Bd.end(), greater<long long>());\n\n    // map Bd index back to rank index in ascending list\n    unordered_map<long long, vector<int>> pos;\n    pos.reserve(N*2);\n    for(int i=0;i<N;i++) pos[B_sorted_asc[i]].push_back(i);\n    for(auto &kv: pos) {\n        // use back as stack\n    }\n    vector<int> rank_of_bd(N,-1);\n    for(int t=0;t<N;t++){\n        long long x = Bd[t];\n        auto &vec = pos[x];\n        int idx = vec.back(); vec.pop_back();\n        rank_of_bd[t] = idx;\n    }\n\n    vector<ShelfRow> rows;\n    rows.reserve(N);\n    int usedH = 0;\n\n    for(int t=0;t<N;t++){\n        long long x = Bd[t];\n\n        // try fit into existing rows\n        int bestRow=-1;\n        int bestSlack=INT_MAX;\n        for(int r=0;r<(int)rows.size(); r++){\n            int h = rows[r].h;\n            long long wr_ll = ceil_div(x, (long long)h);\n            if (wr_ll > W) continue;\n            int wr = (int)wr_ll;\n            if (wr <= rows[r].rem_w){\n                int slack = rows[r].rem_w - wr;\n                if (slack < bestSlack){\n                    bestSlack = slack;\n                    bestRow = r;\n                }\n            }\n        }\n        if(bestRow==-1){\n            int remH = W - usedH;\n            if (remH <= 0) return false;\n            int h_min = (int)ceil_div(x, (long long)W);\n            int h_guess = (int)floor(sqrt((double)max(1.0, (double)x)));\n            int h_new = max(h_min, min(remH, max(1, h_guess)));\n            if (h_new < h_min) h_new = h_min;\n            if (h_new > remH) h_new = remH;\n            long long wr_ll = ceil_div(x, (long long)h_new);\n            if (wr_ll > W){\n                // increase h_new if possible\n                int need = (int)ceil_div(x, (long long)W);\n                if (need > remH) return false;\n                h_new = need;\n                wr_ll = ceil_div(x, (long long)h_new);\n                if (wr_ll > W) return false;\n            }\n            rows.push_back(ShelfRow{h_new, W, {}});\n            usedH += h_new;\n            bestRow = (int)rows.size()-1;\n            if (usedH > W) return false;\n        }\n        int h = rows[bestRow].h;\n        int wr = (int)ceil_div(x, (long long)h);\n        if (wr > rows[bestRow].rem_w) return false; // should not happen\n        rows[bestRow].items.emplace_back(wr, rank_of_bd[t]);\n        rows[bestRow].rem_w -= wr;\n    }\n\n    // Build rectangles\n    blocks_out.assign(N, Rect{0,0,0,0});\n    int cur_i = 0;\n    for(auto &row : rows){\n        int i0 = cur_i;\n        int i1 = i0 + row.h;\n        int cur_j = 0;\n        for(auto &it : row.items){\n            int w = it.first;\n            int j0 = cur_j;\n            int j1 = j0 + w;\n            int rankIdx = it.second;\n            blocks_out[rankIdx] = Rect{i0, j0, i1, j1};\n            cur_j = j1;\n        }\n        cur_i = i1;\n    }\n    // Validate\n    for(int r=0;r<N;r++){\n        if (blocks_out[r].area() < B_sorted_asc[r]) return false;\n    }\n    return true;\n}\n\n// Try vertical shelf packing: columns with widths, items as heights in columns.\nbool pack_vertical(int W, const vector<long long>& B_sorted_asc, vector<Rect>& blocks_out){\n    int N = (int)B_sorted_asc.size();\n    vector<long long> Bd = B_sorted_asc;\n    sort(Bd.begin(), Bd.end(), greater<long long>());\n\n    unordered_map<long long, vector<int>> pos;\n    pos.reserve(N*2);\n    for(int i=0;i<N;i++) pos[B_sorted_asc[i]].push_back(i);\n    vector<int> rank_of_bd(N,-1);\n    for(int t=0;t<N;t++){\n        long long x = Bd[t];\n        auto &vec = pos[x];\n        int idx = vec.back(); vec.pop_back();\n        rank_of_bd[t] = idx;\n    }\n\n    vector<ShelfCol> cols;\n    cols.reserve(N);\n    int usedW = 0;\n\n    for(int t=0;t<N;t++){\n        long long x = Bd[t];\n\n        int bestCol=-1;\n        int bestSlack=INT_MAX;\n        for(int c=0;c<(int)cols.size(); c++){\n            int w = cols[c].w;\n            long long hr_ll = ceil_div(x, (long long)w);\n            if (hr_ll > W) continue;\n            int hr = (int)hr_ll;\n            if (hr <= cols[c].rem_h){\n                int slack = cols[c].rem_h - hr;\n                if (slack < bestSlack){\n                    bestSlack = slack;\n                    bestCol = c;\n                }\n            }\n        }\n        if(bestCol==-1){\n            int remW = W - usedW;\n            if (remW <= 0) return false;\n            int w_min = (int)ceil_div(x, (long long)W);\n            int w_guess = (int)floor(sqrt((double)max(1.0, (double)x)));\n            int w_new = max(w_min, min(remW, max(1, w_guess)));\n            if (w_new < w_min) w_new = w_min;\n            if (w_new > remW) w_new = remW;\n            long long hr_ll = ceil_div(x, (long long)w_new);\n            if (hr_ll > W){\n                int need = (int)ceil_div(x, (long long)W);\n                if (need > remW) return false;\n                w_new = need;\n                hr_ll = ceil_div(x, (long long)w_new);\n                if (hr_ll > W) return false;\n            }\n            cols.push_back(ShelfCol{w_new, W, {}});\n            usedW += w_new;\n            bestCol = (int)cols.size()-1;\n            if (usedW > W) return false;\n        }\n        int w = cols[bestCol].w;\n        int hr = (int)ceil_div(x, (long long)w);\n        if (hr > cols[bestCol].rem_h) return false;\n        cols[bestCol].items.emplace_back(hr, rank_of_bd[t]);\n        cols[bestCol].rem_h -= hr;\n    }\n\n    // Build rectangles\n    blocks_out.assign(N, Rect{0,0,0,0});\n    int cur_j = 0;\n    for(auto &col : cols){\n        int j0 = cur_j;\n        int j1 = j0 + col.w;\n        int cur_i = 0;\n        for(auto &it : col.items){\n            int h = it.first;\n            int i0 = cur_i;\n            int i1 = i0 + h;\n            int rankIdx = it.second;\n            blocks_out[rankIdx] = Rect{i0, j0, i1, j1};\n            cur_i = i1;\n        }\n        cur_j = j1;\n    }\n    // Validate\n    for(int r=0;r<N;r++){\n        if (blocks_out[r].area() < B_sorted_asc[r]) return false;\n    }\n    return true;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W,D,N;\n    if(!(cin>>W>>D>>N)) return 0;\n    vector<vector<int>> a(D, vector<int>(N));\n    for(int d=0; d<D; d++) for(int k=0; k<N; k++) cin>>a[d][k];\n\n    // Compute rank-wise maxima M_r and B ascending\n    vector<int> M(N,0);\n    vector<int> tmp;\n    tmp.reserve(N);\n    for(int d=0; d<D; d++){\n        tmp = a[d];\n        sort(tmp.begin(), tmp.end());\n        for(int r=0;r<N;r++) M[r]=max(M[r], tmp[r]);\n    }\n    vector<long long> B(N);\n    for(int i=0;i<N;i++) B[i]=M[i];\n    sort(B.begin(), B.end());\n\n    // Try horizontal then vertical packing\n    vector<Rect> blocks(N);\n    bool ok = pack_horizontal(W, B, blocks);\n    if(!ok) ok = pack_vertical(W, B, blocks);\n\n    if(!ok){\n        // Very unlikely fallback: place N equal stripes by height; may cause penalties but ensures validity.\n        int h = max(1, W / max(1, N));\n        int sum = h * N;\n        int extra = W - sum;\n        int cur = 0;\n        for(int i=0;i<N;i++){\n            int hh = h + (i < extra ? 1 : 0);\n            blocks[i] = Rect{cur, 0, cur+hh, W};\n            cur += hh;\n        }\n    }\n\n    // Sort blocks by area ascending for assignment each day\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int x,int y){\n        long long ax = blocks[x].area(), ay = blocks[y].area();\n        if(ax!=ay) return ax<ay;\n        return x<y;\n    });\n    vector<Rect> blocksAsc(N);\n    for(int r=0;r<N;r++) blocksAsc[r]=blocks[order[r]];\n\n    // Output per day: assign ascending demands to ascending blocks\n    for(int d=0; d<D; d++){\n        vector<int> idx(N);\n        iota(idx.begin(), idx.end(), 0);\n        sort(idx.begin(), idx.end(), [&](int x,int y){ return a[d][x] < a[d][y]; });\n        vector<Rect> out(N);\n        for(int r=0;r<N;r++){\n            out[idx[r]] = blocksAsc[r];\n        }\n        for(int k=0;k<N;k++){\n            auto &r = out[k];\n            cout<<r.i0<<\" \"<<r.j0<<\" \"<<r.i1<<\" \"<<r.j1<<\"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const long long MOD = 998244353LL;\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<long long>> w(N, vector<long long>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            long long x; cin >> x;\n            w[i][j] = x % MOD;\n        }\n    }\n    // stamps[m][i][j]\n    vector<array<long long, 9>> stamps(M);\n    for (int m = 0; m < M; ++m) {\n        int idx = 0;\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                long long s; cin >> s;\n                stamps[m][idx++] = s % MOD;\n            }\n        }\n    }\n\n    struct Move { int m, p, q; long long gain; };\n    vector<tuple<int,int,int>> ops; ops.reserve(K);\n\n    auto compute_gain = [&](int m, int p, int q)->long long{\n        long long g = 0;\n        int idx = 0;\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj, ++idx) {\n                int r = p + di, c = q + dj;\n                long long v = w[r][c];\n                long long s = stamps[m][idx];\n                long long nv = v + s;\n                if (nv >= MOD) nv -= MOD;\n                g += (nv - v);\n            }\n        }\n        return g;\n    };\n\n    int maxOps = K;\n    for (int t = 0; t < maxOps; ++t) {\n        Move best{-1, -1, -1, LLONG_MIN};\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                    long long g = compute_gain(m, p, q);\n                    if (g > best.gain) {\n                        best = {m, p, q, g};\n                    }\n                }\n            }\n        }\n        if (best.gain <= 0) break;\n        // apply best\n        int m = best.m, p = best.p, q = best.q;\n        int idx = 0;\n        for (int di = 0; di < 3; ++di) {\n            for (int dj = 0; dj < 3; ++dj, ++idx) {\n                int r = p + di, c = q + dj;\n                long long s = stamps[m][idx];\n                long long nv = w[r][c] + s;\n                if (nv >= MOD) nv -= MOD;\n                w[r][c] = nv;\n            }\n        }\n        ops.emplace_back(m, p, q);\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto &op : ops) {\n        int m, p, q;\n        tie(m, p, q) = op;\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Planner {\n    static const int N = 5;\n    vector<vector<int>> A;\n    vector<string> S;\n\n    int cr=0, cc=0;\n    bool holding=false;\n    int held_id=-1;\n\n    bool occ[N][N]; // only maintain for interior j=1..3\n    unordered_map<int, pair<int,int>> loc; // stored positions\n\n    int next_needed[N];\n    int idx_head[N];\n    int dispatched=0;\n\n    int dtgt = -1; // current batching destination row, -1 means none\n\n    Planner(const vector<vector<int>>& Ain): A(Ain) {\n        S.assign(N, \"\");\n        for (int i=1;i<N;i++) S[i].push_back('B'); // bomb small cranes\n        memset(occ, 0, sizeof(occ));\n        for (int i=0;i<N;i++){ next_needed[i]=N*i; idx_head[i]=0; }\n    }\n\n    void appendLarge(char ch){\n        S[0].push_back(ch);\n        for (int i=1;i<N;i++){\n            if ((int)S[i].size() < (int)S[0].size()) S[i].push_back('.');\n        }\n    }\n    void moveTo(int tr, int tc){\n        while (cr != tr) {\n            if (tr < cr) { cr--; appendLarge('U'); }\n            else { cr++; appendLarge('D'); }\n        }\n        while (cc != tc) {\n            if (tc < cc) { cc--; appendLarge('L'); }\n            else { cc++; appendLarge('R'); }\n        }\n    }\n    void pickAtCurrent(int cid){\n        held_id = cid; holding = true; appendLarge('P');\n    }\n    void dropAtCurrent(){\n        holding = false; appendLarge('Q');\n    }\n\n    // Prefer dest row cells, closer to gate (c=3,2,1), then nearest anywhere\n    pair<int,int> preferredFreeInRow(int drow){\n        for (int c=3;c>=1;c--){\n            if (!occ[drow][c]) return {drow,c};\n        }\n        // fallback nearest anywhere\n        int best=1e9; pair<int,int> ans{-1,-1};\n        for (int r=0;r<N;r++){\n            for (int c=1;c<=3;c++){\n                if (!occ[r][c]){\n                    int d = abs(cr-r)+abs(cc-c);\n                    if (d < best){ best=d; ans={r,c}; }\n                }\n            }\n        }\n        return ans;\n    }\n    pair<int,int> nearestFree(){\n        int best=1e9; pair<int,int> ans{-1,-1};\n        for (int r=0;r<N;r++){\n            for (int c=1;c<=3;c++){\n                if (!occ[r][c]){\n                    int d = abs(cr-r)+abs(cc-c);\n                    if (d < best){ best=d; ans={r,c}; }\n                }\n            }\n        }\n        return ans;\n    }\n\n    // Flush for row d: from storage then left head\n    bool flush_one_for_row(int d){\n        int need = next_needed[d];\n        if (need >= N*d + N) return false;\n        auto it = loc.find(need);\n        if (it != loc.end()){\n            auto [sr, sc] = it->second;\n            moveTo(sr, sc);\n            pickAtCurrent(need);\n            occ[sr][sc] = false;\n            loc.erase(it);\n            moveTo(d, N-1);\n            dropAtCurrent();\n            next_needed[d]++; dispatched++;\n            dtgt = d;\n            return true;\n        }\n        for (int r=0;r<N;r++){\n            if (idx_head[r] < N && A[r][idx_head[r]] == need){\n                moveTo(r, 0);\n                pickAtCurrent(need);\n                idx_head[r]++;\n                moveTo(d, N-1);\n                dropAtCurrent();\n                next_needed[d]++; dispatched++;\n                dtgt = d;\n                return true;\n            }\n        }\n        return false;\n    }\n    // General flush (all rows)\n    bool flush_one(){\n        for (int d=0; d<N; d++){\n            if (flush_one_for_row(d)) return true;\n        }\n        return false;\n    }\n    // Extended chain at gate d: keep dispatching need, and optionally pre-stage future items for d\n    void flush_chain_at_row(int d){\n        dtgt = d;\n        // First, keep dispatching as long as available\n        while (flush_one_for_row(d)) { /* continue */ }\n        // Optional pre-stage: pull heads destined to d and store in d row to reduce future travel\n        // Do limited pre-stage to avoid starving others\n        int prestage_limit = 2; // small cap\n        int pulled = 0;\n        for (int loop=0; loop<prestage_limit; ++loop){\n            // find a source row with head destined to d but not equal to need (since equal would have been handled)\n            int best_r = -1, best_cost = 1e9;\n            for (int r=0;r<N;r++){\n                if (idx_head[r] >= N) continue;\n                int b = A[r][idx_head[r]];\n                if (b/N != d) continue;\n                if (b == next_needed[d]) continue;\n                // cost: move to pick + move to a preferred free cell in row d\n                int cost = abs(cr - r) + abs(cc - 0) + abs(r - d) + abs(0 - 2); // approx to mid cell\n                if (cost < best_cost){ best_cost=cost; best_r=r; }\n            }\n            if (best_r == -1) break;\n            // Ensure there is space in row d\n            bool hasSpace = false;\n            for (int c=1;c<=3;c++) if (!occ[d][c]) { hasSpace=true; break; }\n            if (!hasSpace) break;\n            // pick and store\n            int b = A[best_r][idx_head[best_r]];\n            moveTo(best_r, 0);\n            pickAtCurrent(b);\n            idx_head[best_r]++;\n            auto pos = preferredFreeInRow(d);\n            if (pos.first == -1) {\n                // fallback to nearest\n                pos = nearestFree();\n            }\n            if (pos.first != -1){\n                moveTo(pos.first, pos.second);\n                dropAtCurrent();\n                occ[pos.first][pos.second]=true; loc[b]=pos;\n                pulled++;\n            } else {\n                // no space, back off\n                appendLarge('.');\n                break;\n            }\n        }\n    }\n\n    void ensureLargeNotBlockingStart(){\n        if (cr==0 && cc==0){\n            cc=1; appendLarge('R');\n        }\n    }\n\n    // Choose next source row:\n    // 1) any immediate need\n    // 2) prefer dtgt destination heads\n    // 3) lowest cost pick -> store/deliver\n    int choose_source_row(){\n        // 1) immediate need\n        for (int r=0;r<N;r++){\n            if (idx_head[r] >= N) continue;\n            int b = A[r][idx_head[r]];\n            int d = b / N;\n            if (next_needed[d] == b) return r;\n        }\n        // 2) prefer dtgt\n        if (dtgt != -1){\n            int best=-1, bestd=1e9;\n            for (int r=0;r<N;r++){\n                if (idx_head[r] >= N) continue;\n                int b = A[r][idx_head[r]];\n                if (b / N != dtgt) continue;\n                int cost = abs(cr - r) + abs(cc - 0);\n                if (cost < bestd){ bestd=cost; best=r; }\n            }\n            if (best != -1) return best;\n        }\n        // 3) general cost\n        int best= -1;\n        int bestCost = 1e9;\n        for (int r=0;r<N;r++){\n            if (idx_head[r] >= N) continue;\n            int b = A[r][idx_head[r]];\n            int drow = b / N;\n            // estimate: pick + (to gate if immediate else to closest storage in dest row)\n            int pickCost = abs(cr - r) + abs(cc - 0);\n            int afterCost = abs(r - drow) + abs(0 - (N-1)); // rough\n            int cost = pickCost + afterCost;\n            if (cost < bestCost){ bestCost=cost; best=r; }\n        }\n        return best;\n    }\n\n    void run(){\n        ensureLargeNotBlockingStart();\n        int maxTurns = 9500;\n\n        while (dispatched < N*N && (int)S[0].size() < maxTurns){\n            // If holding, resolve it\n            if (holding){\n                int d = held_id / N;\n                if (next_needed[d] == held_id){\n                    moveTo(d, N-1);\n                    dropAtCurrent();\n                    next_needed[d]++; dispatched++;\n                    flush_chain_at_row(d);\n                    continue;\n                } else {\n                    auto pos = preferredFreeInRow(d);\n                    if (pos.first == -1){\n                        // try to flush to free space\n                        if (flush_one()) continue;\n                        // fallback scan anywhere\n                        for (int r=0;r<N;r++){\n                            for (int c=1;c<=3;c++){\n                                if (!occ[r][c]){\n                                    moveTo(r,c);\n                                    dropAtCurrent();\n                                    occ[r][c]=true; loc[held_id]={r,c};\n                                    goto stored_ok;\n                                }\n                            }\n                        }\n                        // no space: wait\n                        appendLarge('.');\nstored_ok:\n                        ;\n                    } else {\n                        moveTo(pos.first, pos.second);\n                        dropAtCurrent();\n                        occ[pos.first][pos.second]=true; loc[held_id]=pos;\n                    }\n                    continue;\n                }\n            }\n\n            // Try to flush immediate items\n            if (dtgt != -1){\n                if (flush_one_for_row(dtgt)) continue;\n            }\n            if (flush_one()) continue;\n\n            // Choose next source\n            int r = choose_source_row();\n            if (r == -1){\n                appendLarge('.');\n                continue;\n            }\n\n            int b = A[r][idx_head[r]];\n            int d = b / N;\n            bool immediate = (next_needed[d] == b);\n\n            // Pre-check storage availability if not immediate\n            if (!immediate){\n                bool hasSpace = false;\n                for (int c=1;c<=3;c++) if (!occ[d][c]) { hasSpace=true; break; }\n                if (!hasSpace){\n                    // try general flush to free space\n                    if (flush_one()) continue;\n                    // still no, look anywhere\n                    auto pos = nearestFree();\n                    if (pos.first == -1){\n                        appendLarge('.');\n                        continue;\n                    }\n                }\n            }\n\n            // Go pick\n            moveTo(r, 0);\n            pickAtCurrent(b);\n            idx_head[r]++;\n\n            if (immediate){\n                moveTo(d, N-1);\n                dropAtCurrent();\n                next_needed[d]++; dispatched++;\n                flush_chain_at_row(d);\n            } else {\n                auto pos = preferredFreeInRow(d);\n                if (pos.first == -1) pos = nearestFree();\n                if (pos.first != -1){\n                    moveTo(pos.first, pos.second);\n                    dropAtCurrent();\n                    occ[pos.first][pos.second]=true; loc[b]=pos;\n                } else {\n                    // unlikely fallback\n                    appendLarge('.');\n                }\n            }\n        }\n\n        // Pad\n        size_t L = S[0].size();\n        for (int i=1;i<N;i++){\n            while (S[i].size() < L) S[i].push_back('.');\n        }\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i=0;i<N;i++){\n        for (int j=0;j<N;j++){\n            cin >> A[i][j];\n        }\n    }\n    Planner planner(A);\n    planner.run();\n    for (int i=0;i<N;i++){\n        cout << planner.S[i] << \"\\n\";\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Plan {\n    vector<string> ops;\n    long long cost = (long long)4e18;\n};\n\nstatic inline void add_load(long long d, vector<string>& ops, long long& cost, long long& load) {\n    if (d <= 0) return;\n    ops.emplace_back(\"+\" + to_string(d));\n    cost += d;\n    load += d;\n}\nstatic inline void sub_load(long long d, vector<string>& ops, long long& cost, long long& load) {\n    if (d <= 0) return;\n    ops.emplace_back(\"-\" + to_string(d));\n    cost += d;\n    load -= d;\n}\n\nstatic inline void move_manhattan(pair<int,int> from, pair<int,int> to, vector<string>& ops, long long& cost, long long load) {\n    int r = from.first, c = from.second;\n    while (r < to.first) { ops.emplace_back(\"D\"); cost += 100 + load; ++r; }\n    while (r > to.first) { ops.emplace_back(\"U\"); cost += 100 + load; --r; }\n    while (c < to.second) { ops.emplace_back(\"R\"); cost += 100 + load; ++c; }\n    while (c > to.second) { ops.emplace_back(\"L\"); cost += 100 + load; --c; }\n}\n\nstatic inline void append_adjacent_move(pair<int,int> from, pair<int,int> to, vector<string>& ops, long long& cost, long long load) {\n    int dr = to.first - from.first;\n    int dc = to.second - from.second;\n    if (dr == 1 && dc == 0) { ops.emplace_back(\"D\"); cost += 100 + load; }\n    else if (dr == -1 && dc == 0) { ops.emplace_back(\"U\"); cost += 100 + load; }\n    else if (dr == 0 && dc == 1) { ops.emplace_back(\"R\"); cost += 100 + load; }\n    else if (dr == 0 && dc == -1) { ops.emplace_back(\"L\"); cost += 100 + load; }\n    else {\n        move_manhattan(from, to, ops, cost, load);\n    }\n}\n\nvector<pair<int,int>> build_snake_rows(int N, bool reverse_start=false) {\n    vector<pair<int,int>> ord;\n    ord.reserve(N*N);\n    if (!reverse_start) {\n        for (int i = 0; i < N; ++i) {\n            if (i % 2 == 0) for (int j = 0; j < N; ++j) ord.emplace_back(i,j);\n            else for (int j = N-1; j >= 0; --j) ord.emplace_back(i,j);\n        }\n    } else {\n        for (int i = N-1; i >= 0; --i) {\n            if ((N-1 - i) % 2 == 0) for (int j = N-1; j >= 0; --j) ord.emplace_back(i,j);\n            else for (int j = 0; j < N; ++j) ord.emplace_back(i,j);\n        }\n    }\n    return ord;\n}\nvector<pair<int,int>> build_snake_cols(int N, bool reverse_start=false) {\n    vector<pair<int,int>> ord;\n    ord.reserve(N*N);\n    if (!reverse_start) {\n        for (int j = 0; j < N; ++j) {\n            if (j % 2 == 0) for (int i = 0; i < N; ++i) ord.emplace_back(i,j);\n            else for (int i = N-1; i >= 0; --i) ord.emplace_back(i,j);\n        }\n    } else {\n        for (int j = N-1; j >= 0; --j) {\n            if ((N-1 - j) % 2 == 0) for (int i = N-1; i >= 0; --i) ord.emplace_back(i,j);\n            else for (int i = 0; i < N; ++i) ord.emplace_back(i,j);\n        }\n    }\n    return ord;\n}\n\n// Hilbert helpers\nvoid rot(int n, int &x, int &y, int rx, int ry) {\n    if (ry == 0) {\n        if (rx == 1) {\n            x = n-1 - x;\n            y = n-1 - y;\n        }\n        int t = x; x = y; y = t;\n    }\n}\npair<int,int> d2xy(int n, int d) {\n    int x = 0, y = 0;\n    int t = d;\n    for (int s = 1; s < n; s <<= 1) {\n        int rx = 1 & (t >> 1);\n        int ry = 1 & (t ^ rx);\n        rot(s, x, y, rx, ry);\n        x += s * rx;\n        y += s * ry;\n        t >>= 2;\n    }\n    return {x, y};\n}\n\nvector<pair<int,int>> build_hilbert_base(int N) {\n    int n = 1;\n    while (n < N) n <<= 1;\n    vector<pair<int,int>> pts;\n    pts.reserve(N*N);\n    for (int d = 0; d < n*n; ++d) {\n        auto p = d2xy(n, d); // (x,y)\n        if (p.first < N && p.second < N) {\n            pts.emplace_back(p.second, p.first); // map to (r,c) = (y,x)\n            if ((int)pts.size() == N*N) break;\n        }\n    }\n    return pts;\n}\n\nvector<pair<int,int>> transform_points_rc(const vector<pair<int,int>>& pts, int N, int rotk, bool reflect) {\n    // rotate around center of NxN and optional mirror horizontally\n    vector<pair<int,int>> out; out.reserve(pts.size());\n    for (auto p : pts) {\n        int r = p.first, c = p.second;\n        if (reflect) c = N-1 - c;\n        for (int k = 0; k < rotk; ++k) {\n            int nr = c;\n            int nc = N-1 - r;\n            r = nr; c = nc;\n        }\n        out.emplace_back(r,c);\n    }\n    return out;\n}\n\n// Morton/Z-order traversal on NxN where N is arbitrary\nvoid morton_rec(int r0, int c0, int h, int w, vector<pair<int,int>>& out) {\n    if (h <= 0 || w <= 0) return;\n    if (h == 1 && w == 1) {\n        out.emplace_back(r0, c0);\n        return;\n    }\n    int h1 = (h+1)/2, h2 = h - h1;\n    int w1 = (w+1)/2, w2 = w - w1;\n    // Quadrants in Z-order: TL, TR, BL, BR\n    morton_rec(r0, c0, h1, w1, out);\n    morton_rec(r0, c0 + w1, h1, w2, out);\n    morton_rec(r0 + h1, c0, h2, w1, out);\n    morton_rec(r0 + h1, c0 + w1, h2, w2, out);\n}\nvector<pair<int,int>> build_morton(int N) {\n    vector<pair<int,int>> out;\n    out.reserve(N*N);\n    morton_rec(0,0,N,N,out);\n    return out;\n}\n\nvector<pair<int,int>> build_spiral(int N, int sr, int sc, bool cw=true) {\n    // spiral from starting corner (sr,sc) where each is 0 or N-1\n    // cw: clockwise\n    int top = 0, left = 0, bottom = N-1, right = N-1;\n    vector<pair<int,int>> ord; ord.reserve(N*N);\n    int phase = 0;\n    // Determine initial direction based on start corner and cw\n    // We'll generate layers and order sides accordingly to start at given corner\n    // Easier: generate a full spiral from top-left clockwise, then transform by rotations/reflections\n    // But we'll implement a straightforward generator for the given start.\n    // To keep it simple, generate base from (0,0) CW, then rotate/reflect to match (sr,sc) and cw.\n    // Here we implement base and then transform outside, for simplicity we only build base here.\n    // We'll return base spiral (0,0) clockwise; callers will transform via transform_points_rc.\n    while (top <= bottom && left <= right) {\n        for (int j = left; j <= right; ++j) ord.emplace_back(top, j);\n        for (int i = top+1; i <= bottom; ++i) ord.emplace_back(i, right);\n        if (top < bottom) {\n            for (int j = right-1; j >= left; --j) ord.emplace_back(bottom, j);\n        }\n        if (left < right) {\n            for (int i = bottom-1; i > top; --i) ord.emplace_back(i, left);\n        }\n        ++top; ++left; --bottom; --right;\n    }\n    // ord is base; transformation will be done by transform_points_rc\n    return ord;\n}\n\nvector<pair<int,int>> build_block_snake(int N, int BS) {\n    // Traverse tiles in snake order, inside each tile snake order\n    vector<pair<int,int>> ord; ord.reserve(N*N);\n    int TR = (N + BS - 1)/BS;\n    int TC = (N + BS - 1)/BS;\n    for (int tr = 0; tr < TR; ++tr) {\n        if (tr % 2 == 0) {\n            for (int tc = 0; tc < TC; ++tc) {\n                int r0 = tr*BS, c0 = tc*BS;\n                int r1 = min(N, r0 + BS);\n                int c1 = min(N, c0 + BS);\n                for (int r = r0; r < r1; ++r) {\n                    if ((r - r0) % 2 == 0) {\n                        for (int c = c0; c < c1; ++c) ord.emplace_back(r,c);\n                    } else {\n                        for (int c = c1-1; c >= c0; --c) ord.emplace_back(r,c);\n                    }\n                }\n            }\n        } else {\n            for (int tc = TC-1; tc >= 0; --tc) {\n                int r0 = tr*BS, c0 = tc*BS;\n                int r1 = min(N, r0 + BS);\n                int c1 = min(N, c0 + BS);\n                for (int r = r0; r < r1; ++r) {\n                    if ((r - r0) % 2 == 0) {\n                        for (int c = c0; c < c1; ++c) ord.emplace_back(r,c);\n                    } else {\n                        for (int c = c1-1; c >= c0; --c) ord.emplace_back(r,c);\n                    }\n                }\n            }\n        }\n    }\n    return ord;\n}\n\nbool is_adjacent_path(const vector<pair<int,int>>& ord) {\n    int SZ = (int)ord.size();\n    for (int i = 0; i + 1 < SZ; ++i) {\n        int dr = abs(ord[i+1].first - ord[i].first);\n        int dc = abs(ord[i+1].second - ord[i].second);\n        if (dr + dc != 1) return false;\n    }\n    return true;\n}\n\nPlan build_plan(int N, const vector<vector<long long>>& h0, const vector<pair<int,int>>& order) {\n    vector<vector<long long>> h = h0;\n    vector<string> ops;\n    ops.reserve(12000);\n    long long cost = 0;\n    long long load = 0;\n\n    pair<int,int> cur = {0,0};\n    if (cur != order[0]) {\n        move_manhattan(cur, order[0], ops, cost, load);\n        cur = order[0];\n    }\n    int SZ = (int)order.size();\n    for (int idx = 0; idx + 1 < SZ; ++idx) {\n        auto p = order[idx];\n        auto q = order[idx+1];\n        if (cur != p) {\n            move_manhattan(cur, p, ops, cost, load);\n            cur = p;\n        }\n        long long x = h[p.first][p.second];\n        if (x >= 0) {\n            if (x > 0) add_load(x, ops, cost, load);\n            append_adjacent_move(p, q, ops, cost, load);\n            cur = q;\n            if (x > 0) sub_load(x, ops, cost, load);\n            h[q.first][q.second] += x;\n            h[p.first][p.second] = 0;\n        } else {\n            long long d = -x;\n            append_adjacent_move(p, q, ops, cost, load); // move empty to q\n            cur = q;\n            add_load(d, ops, cost, load);               // load at q\n            append_adjacent_move(q, p, ops, cost, load); // move back with load\n            cur = p;\n            sub_load(d, ops, cost, load);               // unload at p\n            h[p.first][p.second] = 0;\n            h[q.first][q.second] -= d;\n            append_adjacent_move(p, q, ops, cost, load); // move to q to continue\n            cur = q;\n        }\n    }\n    Plan res;\n    res.ops = move(ops);\n    res.cost = cost;\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<long long>> h(N, vector<long long>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> h[i][j];\n\n    vector<vector<pair<int,int>>> candidates;\n\n    // Row and column snakes\n    candidates.push_back(build_snake_rows(N, false));\n    candidates.push_back(build_snake_rows(N, true));\n    candidates.push_back(build_snake_cols(N, false));\n    candidates.push_back(build_snake_cols(N, true));\n\n    // Hilbert base (r,c)\n    auto hil_base = build_hilbert_base(N);\n    for (int rotk = 0; rotk < 4; ++rotk) {\n        for (int refl = 0; refl < 2; ++refl) {\n            auto ord = transform_points_rc(hil_base, N, rotk, refl);\n            if (is_adjacent_path(ord)) {\n                candidates.push_back(ord);\n                auto rord = ord; reverse(rord.begin(), rord.end());\n                candidates.push_back(rord);\n            }\n        }\n    }\n\n    // Morton/Z-order and variants via rotation/reflection\n    auto mort = build_morton(N);\n    for (int rotk = 0; rotk < 4; ++rotk) {\n        for (int refl = 0; refl < 2; ++refl) {\n            auto ord = transform_points_rc(mort, N, rotk, refl);\n            // Morton order is not strictly adjacent; skip non-adjacent to avoid long manhattan jumps\n            if (is_adjacent_path(ord)) {\n                candidates.push_back(ord);\n                auto rord = ord; reverse(rord.begin(), rord.end());\n                candidates.push_back(rord);\n            }\n        }\n    }\n\n    // Block snakes with different block sizes\n    for (int bs : {3,4,5}) {\n        auto b = build_block_snake(N, bs);\n        if (is_adjacent_path(b)) {\n            candidates.push_back(b);\n            auto rb = b; reverse(rb.begin(), rb.end());\n            candidates.push_back(rb);\n        }\n        // also rotated/reflected\n        for (int rotk = 1; rotk < 4; ++rotk) {\n            auto ord = transform_points_rc(b, N, rotk, false);\n            if (is_adjacent_path(ord)) {\n                candidates.push_back(ord);\n                auto rord = ord; reverse(rord.begin(), rord.end());\n                candidates.push_back(rord);\n            }\n        }\n    }\n\n    // Spiral from TL CW; then rotate/reflect to cover 8 variants and reverses\n    auto spiral_base = build_spiral(N, 0, 0, true);\n    for (int rotk = 0; rotk < 4; ++rotk) {\n        for (int refl = 0; refl < 2; ++refl) {\n            auto ord = transform_points_rc(spiral_base, N, rotk, refl);\n            if (is_adjacent_path(ord)) {\n                candidates.push_back(ord);\n                auto rord = ord; reverse(rord.begin(), rord.end());\n                candidates.push_back(rord);\n            }\n        }\n    }\n\n    // Deduplicate\n    sort(candidates.begin(), candidates.end(), [](const auto& a, const auto& b){\n        if (a.size() != b.size()) return a.size() < b.size();\n        return a < b;\n    });\n    candidates.erase(unique(candidates.begin(), candidates.end()), candidates.end());\n\n    Plan best;\n    for (const auto& ord : candidates) {\n        Plan p = build_plan(N, h, ord);\n        if (p.cost < best.cost) best = move(p);\n    }\n\n    for (const auto& s : best.ops) {\n        cout << s << '\\n';\n    }\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Seed {\n    int id;\n    array<int,15> x{};\n    int V=0;\n    double baseScore=0; // score before diversity\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,T;\n    if(!(cin>>N>>M>>T)) return 0;\n    const int S = 2*N*(N-1); // 60\n    vector<Seed> seeds(S);\n    for(int i=0;i<S;i++){\n        seeds[i].id = i;\n        int sum=0;\n        for(int l=0;l<M;l++){\n            int v; cin>>v;\n            seeds[i].x[l]=v;\n            sum+=v;\n        }\n        seeds[i].V=sum;\n        seeds[i].baseScore=sum;\n    }\n\n    // Grid precomputation\n    const int H = N, W = N, P = H*W;\n    auto pid = [&](int r,int c){ return r*W + c; };\n    vector<vector<int>> adj(P);\n    vector<pair<int,int>> pos_of(P);\n    for(int r=0;r<H;r++){\n        for(int c=0;c<W;c++){\n            int u = pid(r,c);\n            pos_of[u] = {r,c};\n            if(r>0) adj[u].push_back(pid(r-1,c));\n            if(r+1<H) adj[u].push_back(pid(r+1,c));\n            if(c>0) adj[u].push_back(pid(r,c-1));\n            if(c+1<W) adj[u].push_back(pid(r,c+1));\n        }\n    }\n    auto degree = [&](int u){ return (int)adj[u].size(); };\n\n    // Two cell orders to multi-start\n    vector<int> cell_order1(P), cell_order2(P);\n    iota(cell_order1.begin(), cell_order1.end(), 0);\n    iota(cell_order2.begin(), cell_order2.end(), 0);\n\n    stable_sort(cell_order1.begin(), cell_order1.end(), [&](int a, int b){\n        int da = degree(a), db = degree(b);\n        if(da!=db) return da>db;\n        auto [ra,ca] = pos_of[a];\n        auto [rb,cb] = pos_of[b];\n        int caColor = (ra+ca)&1;\n        int cbColor = (rb+cb)&1;\n        if(caColor!=cbColor) return caColor<cbColor; // black first\n        if(ra!=rb) return ra<rb;\n        return ca<cb;\n    });\n    // Reverse checkerboard preference for second\n    stable_sort(cell_order2.begin(), cell_order2.end(), [&](int a, int b){\n        int da = degree(a), db = degree(b);\n        if(da!=db) return da>db;\n        auto [ra,ca] = pos_of[a];\n        auto [rb,cb] = pos_of[b];\n        int caColor = (ra+ca)&1;\n        int cbColor = (rb+cb)&1;\n        if(caColor!=cbColor) return caColor>cbColor; // white first\n        if(ra!=rb) return ra<rb;\n        return ca<cb;\n    });\n\n    // Compute per-dimension ranks and base scores\n    auto compute_base_scores = [&](vector<Seed>& pool){\n        int n = pool.size();\n        vector<int> idx(n);\n        iota(idx.begin(), idx.end(), 0);\n        vector<vector<int>> rank(M, vector<int>(n, 0));\n        for(int l=0;l<M;l++){\n            sort(idx.begin(), idx.end(), [&](int a, int b){\n                if(pool[a].x[l]!=pool[b].x[l]) return pool[a].x[l]>pool[b].x[l];\n                return pool[a].V>pool[b].V;\n            });\n            for(int r=0;r<n;r++){\n                rank[l][idx[r]] = r+1;\n            }\n        }\n        for(int i=0;i<n;i++){\n            pool[i].V = 0;\n            for(int l=0;l<M;l++) pool[i].V += pool[i].x[l];\n        }\n        for(int i=0;i<n;i++){\n            double bonus = 0.0;\n            for(int l=0;l<M;l++){\n                int r = rank[l][i];\n                if(r==1) bonus += 3.0;\n                else if(r<=3) bonus += 2.0;\n                else if(r<=6) bonus += 1.0;\n            }\n            // Slightly upweight V\n            pool[i].baseScore = pool[i].V + 8.5*bonus;\n        }\n    };\n\n    // Cosine similarity between seeds\n    auto cosine_sim = [&](const Seed& a, const Seed& b)->double{\n        double dot=0, na=0, nb=0;\n        for(int l=0;l<M;l++){\n            double xa=a.x[l], xb=b.x[l];\n            dot += xa*xb;\n            na += xa*xa;\n            nb += xb*xb;\n        }\n        if(na==0 || nb==0) return 0.0;\n        return dot / (sqrt(na)*sqrt(nb));\n    };\n\n    // Diversity-aware selection of top P seeds\n    auto select_diverse = [&](const vector<Seed>& pool, int tTurn)->vector<int>{\n        int n = pool.size();\n        vector<int> order(n);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b){\n            if(pool[a].baseScore!=pool[b].baseScore) return pool[a].baseScore>pool[b].baseScore;\n            return pool[a].V>pool[b].V;\n        });\n        vector<int> selected;\n        selected.reserve(P);\n        // Precompute similarity to speed up\n        static double simMat[60][60];\n        for(int i=0;i<n;i++){\n            for(int j=i;j<n;j++){\n                double s = cosine_sim(pool[i], pool[j]);\n                simMat[i][j]=simMat[j][i]=s;\n            }\n        }\n        // Diversity penalty strength; reduce near final turns\n        double lambda = (tTurn >= T-3 ? 0.2 : 0.45);\n        vector<char> used(n, 0);\n        for(int it=0; it<n && (int)selected.size()<P; it++){\n            int bestIdx = -1;\n            double bestScore = -1e100;\n            // Consider top candidates but allow some tail to inject diversity\n            int limit = min(n, 50);\n            for(int k=0;k<limit;k++){\n                int c = order[k];\n                if(used[c]) continue;\n                // penalize by max similarity to already selected\n                double penalty = 0.0;\n                for(int sidx: selected){\n                    penalty = max(penalty, simMat[c][sidx]);\n                }\n                double sc = pool[c].baseScore - lambda * 1000.0 * penalty; // scale penalty\n                if(sc > bestScore){\n                    bestScore = sc;\n                    bestIdx = c;\n                }\n            }\n            if(bestIdx==-1){\n                // fallback any unused\n                for(int k=0;k<n;k++){ if(!used[order[k]]){ bestIdx=order[k]; break; } }\n            }\n            used[bestIdx]=1;\n            selected.push_back(bestIdx);\n        }\n        return selected;\n    };\n\n    // Edge fitness: sum of per-dim max + small complementarity bonus\n    auto edge_fitness = [&](const Seed& a, const Seed& b)->int{\n        int s=0;\n        int split=0;\n        for(int l=0;l<M;l++){\n            if(a.x[l]>b.x[l]) { s += a.x[l]; split++; }\n            else if(b.x[l]>a.x[l]) { s += b.x[l]; split++; }\n            else { s += a.x[l]; }\n        }\n        // Complementarity bonus scaled small\n        return s + split; // adding up to 15\n    };\n\n    struct LayoutResult{\n        vector<int> pos2idx; // position -> pool index\n        long long totalFitness=0;\n    };\n\n    auto build_edges = [&](){\n        vector<pair<int,int>> edges;\n        vector<vector<int>> posEdgeIdx(P);\n        vector<char> seen(P*P, 0);\n        auto enc = [&](int a,int b){ return a*P + b; };\n        for(int u=0;u<P;u++){\n            for(int v: adj[u]){\n                if(u<v && !seen[enc(u,v)]){\n                    seen[enc(u,v)]=1;\n                    edges.emplace_back(u,v);\n                    posEdgeIdx[u].push_back((int)edges.size()-1);\n                    posEdgeIdx[v].push_back((int)edges.size()-1);\n                }\n            }\n        }\n        return pair{edges, posEdgeIdx};\n    };\n    auto [edges, posEdgeIdx] = build_edges();\n    int E = (int)edges.size();\n\n    auto evaluate_layout = [&](const vector<int>& pos2poolIdx, const vector<Seed>& pool, vector<int>& edgeVal)->long long{\n        long long total=0;\n        for(int e=0;e<E;e++){\n            int u = edges[e].first;\n            int v = edges[e].second;\n            int su = pos2poolIdx[u];\n            int sv = pos2poolIdx[v];\n            int val = edge_fitness(pool[su], pool[sv]);\n            edgeVal[e]=val;\n            total += val;\n        }\n        return total;\n    };\n\n    mt19937 rng(1234567u + (unsigned)chrono::high_resolution_clock::now().time_since_epoch().count());\n\n    auto local_search = [&](vector<int>& pos2poolIdx, const vector<Seed>& pool, vector<int>& edgeVal, long long& total, int budgetIters){\n        uniform_int_distribution<int> distPos(0, P-1);\n        // mixture of random swaps and sampled best swaps\n        for(int it=0; it<budgetIters; it++){\n            int a = distPos(rng);\n            // sample k candidates for b\n            int bestB = -1;\n            long long bestDelta = 0;\n            int K = 6;\n            for(int s=0;s<K;s++){\n                int b = distPos(rng);\n                if(b==a) continue;\n                // compute delta for swapping a and b\n                long long oldSum=0, newSum=0;\n                // collect affected edges\n                // at most deg(a)+deg(b) <= 8 edges\n                static int buf[16];\n                int cnt=0;\n                auto add_edge = [&](int ei){\n                    for(int t=0;t<cnt;t++) if(buf[t]==ei) return;\n                    buf[cnt++]=ei;\n                };\n                for(int ei: posEdgeIdx[a]) add_edge(ei);\n                for(int ei: posEdgeIdx[b]) add_edge(ei);\n                for(int t=0;t<cnt;t++){\n                    int ei = buf[t];\n                    oldSum += edgeVal[ei];\n                    int u = edges[ei].first;\n                    int v = edges[ei].second;\n                    int su = pos2poolIdx[u];\n                    int sv = pos2poolIdx[v];\n                    if(u==a) su = pos2poolIdx[b];\n                    else if(u==b) su = pos2poolIdx[a];\n                    if(v==a) sv = pos2poolIdx[b];\n                    else if(v==b) sv = pos2poolIdx[a];\n                    newSum += edge_fitness(pool[su], pool[sv]);\n                }\n                long long delta = newSum - oldSum;\n                if(delta > bestDelta){\n                    bestDelta = delta;\n                    bestB = b;\n                }\n            }\n            if(bestB!=-1 && bestDelta>0){\n                int b = bestB;\n                // apply swap\n                swap(pos2poolIdx[a], pos2poolIdx[b]);\n                total += bestDelta;\n                // update edgeVal\n                static int buf[16];\n                int cnt=0;\n                auto add_edge = [&](int ei){\n                    for(int t=0;t<cnt;t++) if(buf[t]==ei) return;\n                    buf[cnt++]=ei;\n                };\n                for(int ei: posEdgeIdx[a]) add_edge(ei);\n                for(int ei: posEdgeIdx[b]) add_edge(ei);\n                for(int t=0;t<cnt;t++){\n                    int ei = buf[t];\n                    int u = edges[ei].first;\n                    int v = edges[ei].second;\n                    int su = pos2poolIdx[u];\n                    int sv = pos2poolIdx[v];\n                    edgeVal[ei] = edge_fitness(pool[su], pool[sv]);\n                }\n            }\n        }\n    };\n\n    for(int t=0;t<T;t++){\n        compute_base_scores(seeds);\n\n        // Select diverse top P seeds\n        vector<int> selIdx = select_diverse(seeds, t);\n\n        // Build initial layouts (two starts)\n        vector<LayoutResult> candidates;\n        candidates.reserve(2);\n\n        auto build_and_improve = [&](const vector<int>& orderCells, int iterBudget)->LayoutResult{\n            vector<int> pos2poolIdx(P, -1);\n            for(int k=0;k<P;k++){\n                pos2poolIdx[ orderCells[k] ] = selIdx[k];\n            }\n            vector<int> edgeVal(E,0);\n            long long total = evaluate_layout(pos2poolIdx, seeds, edgeVal);\n            // local search\n            local_search(pos2poolIdx, seeds, edgeVal, total, iterBudget);\n            return LayoutResult{pos2poolIdx, total};\n        };\n\n        int baseIter = 2800;\n        int iterBudget = (t>=T-3 ? baseIter + 1000 : baseIter); // more effort late\n        candidates.push_back(build_and_improve(cell_order1, iterBudget));\n        candidates.push_back(build_and_improve(cell_order2, iterBudget/2)); // light second start\n\n        // pick best layout\n        LayoutResult best = candidates[0];\n        if(candidates[1].totalFitness > best.totalFitness) best = candidates[1];\n\n        // Output placement grid with seed IDs\n        vector<vector<int>> A(N, vector<int>(N,-1));\n        for(int pos=0;pos<P;pos++){\n            auto [r,c] = pos_of[pos];\n            A[r][c] = seeds[ best.pos2idx[pos] ].id;\n        }\n        for(int i=0;i<N;i++){\n            for(int j=0;j<N;j++){\n                if(j) cout << ' ';\n                cout << A[i][j];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // Read next generation\n        vector<Seed> next(S);\n        for(int i=0;i<S;i++){\n            next[i].id = i;\n            int sum=0;\n            for(int l=0;l<M;l++){\n                int v; cin>>v;\n                next[i].x[l]=v;\n                sum+=v;\n            }\n            next[i].V = sum;\n            next[i].baseScore = sum;\n        }\n        seeds.swap(next);\n    }\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Task {\n    int sx, sy, tx, ty;\n    int dir_pick=0, rpx=0, rpy=0;\n    int dir_drop=0, rdx=0, rdy=0;\n};\n\ninline int manh(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\ninline bool inb(int x,int y,int N){ return 0<=x && x<N && 0<=y && y<N; }\nstatic const int dx4[4]={0,1,0,-1};\nstatic const int dy4[4]={1,0,-1,0};\n\ninline pair<int,int> rot_need(int fromDir,int toDir){\n    int d = (toDir - fromDir + 4) % 4;\n    if(d==0) return {0,0};\n    if(d==1) return {1,0};\n    if(d==2) return {2,0};\n    return {0,1}; // d==3\n}\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    vector<pair<int,int>> S, D;\n    vector<vector<int>> occ(N, vector<int>(N,0));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            int si = s[i][j]-'0';\n            int ti = t[i][j]-'0';\n            occ[i][j]=si;\n            if(si==1 && ti==0) S.emplace_back(i,j);\n            if(si==0 && ti==1) D.emplace_back(i,j);\n        }\n    }\n\n    int nS = (int)S.size(), nD = (int)D.size();\n    if(nS==0){\n        // trivial: no moves\n        cout<<2<<\"\\n\";\n        cout<<0<<\" \"<<1<<\"\\n\";\n        cout<<0<<\" \"<<0<<\"\\n\";\n        return 0;\n    }\n\n    mt19937 rng(20250915);\n\n    // Initial multi-start greedy assignment\n    vector<int> idxS(nS);\n    iota(idxS.begin(), idxS.end(), 0);\n    long long best_cost = (1LL<<60);\n    vector<int> assign_best(nS, -1);\n    int attempts = 12;\n    for(int att=0; att<attempts; ++att){\n        if(att) shuffle(idxS.begin(), idxS.end(), rng);\n        vector<char> usedD(nD, 0);\n        vector<int> assign(nS, -1);\n        long long cost=0;\n        for(int idS : idxS){\n            auto [sx,sy] = S[idS];\n            int bj=-1, bd=INT_MAX;\n            for(int j=0;j<nD;++j){\n                if(usedD[j]) continue;\n                int d = manh(sx,sy,D[j].first,D[j].second);\n                if(d<bd){ bd=d; bj=j; }\n            }\n            if(bj==-1) continue;\n            usedD[bj]=1;\n            assign[idS]=bj;\n            cost += bd;\n        }\n        if(cost < best_cost){\n            best_cost = cost;\n            assign_best = assign;\n        }\n    }\n\n    // 2-swap and 3-cycle local improvements\n    uniform_int_distribution<int> distS(0, nS-1);\n    int twoSwapIters = min(80000, nS*300);\n    for(int it=0; it<twoSwapIters; ++it){\n        int a = distS(rng), b = distS(rng);\n        if(a==b) continue;\n        int da = assign_best[a], db = assign_best[b];\n        if(da<0 || db<0) continue;\n        auto [ax,ay]=S[a]; auto [bx,by]=S[b];\n        auto [tax,tay]=D[da]; auto [tbx,tby]=D[db];\n        int before = manh(ax,ay,tax,tay) + manh(bx,by,tbx,tby);\n        int after  = manh(ax,ay,tbx,tby) + manh(bx,by,tax,tay);\n        if(after < before){\n            assign_best[a]=db;\n            assign_best[b]=da;\n        }\n    }\n    // 3-cycle: a->b, b->c, c->a\n    int threeCycleIters = min(20000, nS*100);\n    for(int it=0; it<threeCycleIters; ++it){\n        int a = distS(rng), b = distS(rng), c = distS(rng);\n        if(a==b || b==c || a==c) continue;\n        int da = assign_best[a], db = assign_best[b], dc = assign_best[c];\n        if(da<0 || db<0 || dc<0) continue;\n        auto [ax,ay]=S[a]; auto [bx,by]=S[b]; auto [cx,cy]=S[c];\n        auto [tax,tay]=D[da]; auto [tbx,tby]=D[db]; auto [tcx,tcy]=D[dc];\n        int before = manh(ax,ay,tax,tay) + manh(bx,by,tbx,tby) + manh(cx,cy,tcx,tcy);\n        // try both cycle directions\n        int after1 = manh(ax,ay,tbx,tby) + manh(bx,by,tcx,tcy) + manh(cx,cy,tax,tay);\n        int after2 = manh(ax,ay,tcx,tcy) + manh(bx,by,tax,tay) + manh(cx,cy,tbx,tby);\n        if(after1 < before && after1 <= after2){\n            assign_best[a]=db; assign_best[b]=dc; assign_best[c]=da;\n        }else if(after2 < before){\n            assign_best[a]=dc; assign_best[b]=da; assign_best[c]=db;\n        }\n    }\n\n    // Build tasks\n    vector<Task> tasks;\n    tasks.reserve(nS);\n    for(int i=0;i<nS;i++){\n        int j = assign_best[i];\n        if(j<0) continue;\n        tasks.push_back({S[i].first, S[i].second, D[j].first, D[j].second});\n    }\n    int Tn = (int)tasks.size();\n    if(Tn==0){\n        cout<<2<<\"\\n\";\n        cout<<0<<\" \"<<1<<\"\\n\";\n        cout<<0<<\" \"<<0<<\"\\n\";\n        return 0;\n    }\n\n    // Order tasks via clustering (k-means on pick positions), then greedy within clusters\n    int K = min(6, max(2, Tn/80)); // choose number of clusters\n    vector<pair<int,int>> cent(K);\n    // init centers by sampling\n    for(int k=0;k<K;k++){\n        int id = (int)((1.0*k/(K-1+1e-9))*(Tn-1));\n        cent[k] = {tasks[id].sx, tasks[id].sy};\n    }\n    vector<int> belong(Tn, 0);\n    for(int iter=0; iter<8; ++iter){\n        // assign\n        for(int i=0;i<Tn;i++){\n            int bestk=0, bd=INT_MAX;\n            for(int k=0;k<K;k++){\n                int d = manh(tasks[i].sx, tasks[i].sy, cent[k].first, cent[k].second);\n                if(d<bd){ bd=d; bestk=k; }\n            }\n            belong[i]=bestk;\n        }\n        // update\n        vector<long long> sx(K,0), sy(K,0), cnt(K,0);\n        for(int i=0;i<Tn;i++){\n            int k=belong[i];\n            sx[k]+=tasks[i].sx; sy[k]+=tasks[i].sy; cnt[k]++;\n        }\n        for(int k=0;k<K;k++){\n            if(cnt[k]){\n                cent[k] = {(int)(sx[k]/cnt[k]), (int)(sy[k]/cnt[k])};\n            }\n        }\n    }\n    // Build order: sort clusters by centroid NN, then within each cluster do NN\n    vector<int> clusters(K);\n    iota(clusters.begin(), clusters.end(), 0);\n    // order clusters by NN from (0,0)\n    int cx=0, cy=0;\n    vector<int> clusterOrder;\n    vector<char> usedC(K,0);\n    for(int it=0; it<K; ++it){\n        int best=-1, bd=INT_MAX;\n        for(int k=0;k<K;k++){\n            if(usedC[k]) continue;\n            int d = manh(cx,cy,cent[k].first, cent[k].second);\n            if(d<bd){ bd=d; best=k; }\n        }\n        usedC[best]=1; clusterOrder.push_back(best);\n        cx=cent[best].first; cy=cent[best].second;\n    }\n    // collect indices per cluster\n    vector<vector<int>> perC(K);\n    for(int i=0;i<Tn;i++) perC[belong[i]].push_back(i);\n\n    // within-cluster NN ordering using pick-root approx\n    vector<int> order;\n    order.reserve(Tn);\n    int rx_est=0, ry_est=0;\n    for(int ck : clusterOrder){\n        auto &vec = perC[ck];\n        vector<char> usedL(vec.size(), 0);\n        for(size_t step=0; step<vec.size(); ++step){\n            int bestIdx=-1, bd=INT_MAX;\n            for(size_t z=0; z<vec.size(); ++z){\n                if(usedL[z]) continue;\n                int i = vec[z];\n                int bdloc=INT_MAX;\n                for(int k=0;k<4;k++){\n                    int rpx = tasks[i].sx - dx4[k];\n                    int rpy = tasks[i].sy - dy4[k];\n                    if(!inb(rpx,rpy,N)) continue;\n                    bdloc = min(bdloc, manh(rx_est,ry_est,rpx,rpy));\n                }\n                if(bdloc<bd){ bd=bdloc; bestIdx=(int)z; }\n            }\n            if(bestIdx==-1) break;\n            int i = vec[bestIdx];\n            usedL[bestIdx]=1;\n            order.push_back(i);\n            // update estimate\n            int brx=rx_est, bry=ry_est, bestd=INT_MAX;\n            for(int k=0;k<4;k++){\n                int rpx = tasks[i].sx - dx4[k];\n                int rpy = tasks[i].sy - dy4[k];\n                if(!inb(rpx,rpy,N)) continue;\n                int d=manh(rx_est,ry_est,rpx,rpy);\n                if(d<bestd){ bestd=d; brx=rpx; bry=rpy; }\n            }\n            rx_est=brx; ry_est=bry;\n        }\n    }\n\n    // Light 2-opt on order with approximate cost (consider pick->drop and transitions)\n    auto best_pick_dir = [&](const Task& tk, int crx, int cry){\n        int bk=0; int bd=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rpx = tk.sx - dx4[k], rpy = tk.sy - dy4[k];\n            if(!inb(rpx,rpy,N)) continue;\n            int d=manh(crx,cry,rpx,rpy);\n            if(d<bd){ bd=d; bk=k; }\n        }\n        return bk;\n    };\n    auto best_drop_dir_from_pick = [&](const Task& tk, int pd){\n        int bk=pd; int bd=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rdx = tk.tx - dx4[k], rdy = tk.ty - dy4[k];\n            if(!inb(rdx,rdy,N)) continue;\n            int d=manh(tk.sx - dx4[pd], tk.sy - dy4[pd], rdx, rdy) + (k==pd?0:1);\n            if(d<bd){ bd=d; bk=k; }\n        }\n        return bk;\n    };\n    auto route_cost = [&](const vector<int>& ord)->long long{\n        long long c=0;\n        int crx=0, cry=0;\n        for(int id: ord){\n            const Task &tk = tasks[id];\n            int pd = best_pick_dir(tk, crx, cry);\n            int prx = tk.sx - dx4[pd], pry = tk.sy - dy4[pd];\n            int dd = best_drop_dir_from_pick(tk, pd);\n            int drx = tk.tx - dx4[dd], dry = tk.ty - dy4[dd];\n            c += manh(crx,cry,prx,pry);\n            c += manh(prx,pry,drx,dry);\n            crx=drx; cry=dry;\n        }\n        return c;\n    };\n    long long curc = route_cost(order);\n    uniform_int_distribution<int> distI(0, (int)order.size()-1);\n    for(int iter=0; iter<2000 && order.size()>=4; ++iter){\n        int a = distI(rng), b = distI(rng);\n        if(a>b) swap(a,b);\n        if(b-a<2) continue;\n        vector<int> tmp = order;\n        reverse(tmp.begin()+a, tmp.begin()+b);\n        long long nc = route_cost(tmp);\n        if(nc < curc){\n            order.swap(tmp);\n            curc = nc;\n        }\n    }\n\n    // Execution with dynamic direction choice and overlapping rotations; also lookahead to next pick\n    int rx=0, ry=0;\n    int leaf_dir=0; // Right initially\n    bool holding=false;\n    vector<string> out;\n    out.reserve(200000);\n    const int TURN_LIMIT = 100000;\n\n    auto emit_turn = [&](char mv, char rot, bool P){\n        string st(4,'.');\n        st[0]=mv?mv:'.';\n        st[1]=rot?rot:'.';\n        st[3]=P?'P':'.';\n        out.push_back(st);\n    };\n    auto move_step = [&](int tx,int ty, int &cw,int &ccw){\n        char mv='.';\n        if(rx<tx){ mv='D'; rx++; }\n        else if(rx>tx){ mv='U'; rx--; }\n        else if(ry<ty){ mv='R'; ry++; }\n        else if(ry>ty){ mv='L'; ry--; }\n        char rot='.';\n        if(cw>0){ rot='R'; cw--; leaf_dir=(leaf_dir+1)&3; }\n        else if(ccw>0){ rot='L'; ccw--; leaf_dir=(leaf_dir+3)&3; }\n        emit_turn(mv, rot, false);\n    };\n    auto move_to = [&](int tx,int ty, int &cw,int &ccw){\n        while((rx!=tx || ry!=ty) && (int)out.size()<TURN_LIMIT){\n            move_step(tx,ty,cw,ccw);\n        }\n    };\n\n    auto plan_dir_choice = [&](int crx,int cry, int fromDir, int cx,int cy, int nx=-1,int ny=-1)->tuple<int,int,int,int,int>{\n        // choose dir minimizing distance+rot, with small lookahead to next pick-root (nx,ny) if given\n        int bestDir=-1, brx=crx, bry=cry, bcw=0, bccw=0;\n        int bestScore=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rpx = cx - dx4[k], rpy = cy - dy4[k];\n            if(!inb(rpx,rpy,N)) continue;\n            auto [cw,ccw] = rot_need(fromDir,k);\n            int score = manh(crx,cry,rpx,rpy) + (cw+ccw);\n            if(nx!=-1){ // lookahead cost to next pick-root estimate\n                score += manh(rpx,rpy,nx,ny);\n            }\n            if(score<bestScore){\n                bestScore=score; bestDir=k; brx=rpx; bry=rpy; bcw=cw; bccw=ccw;\n            }\n        }\n        return {bestDir, brx, bry, bcw, bccw};\n    };\n\n    for(size_t oi=0; oi<order.size(); ++oi){\n        if((int)out.size()>=TURN_LIMIT) break;\n        Task &tk = tasks[order[oi]];\n        // Estimate next pick-root for lookahead\n        int nx=-1, ny=-1;\n        if(oi+1<order.size()){\n            Task &nxt = tasks[order[oi+1]];\n            // approximate best neighbor\n            int bd=INT_MAX;\n            for(int k=0;k<4;k++){\n                int rpx = nxt.sx - dx4[k], rpy = nxt.sy - dy4[k];\n                if(!inb(rpx,rpy,N)) continue;\n                int d = manh(0,0,0,0); // placeholder to pick minimum absolute movement later; we just set to 0\n                // Choose the closest to current drop later; for pick planning, use simple center\n                // We can't know current drop yet; leave as neutral. But we can bias to the most interior neighbor: choose center-most\n                int centerScore = manh(rpx, rpy, N/2, N/2);\n                if(centerScore < bd){ bd=centerScore; nx=rpx; ny=rpy; }\n            }\n            if(nx==-1){ nx=0; ny=0; }\n        }\n\n        // Choose pick dir with lookahead\n        int dirp, prx, pry, pcw, pccw;\n        tie(dirp, prx, pry, pcw, pccw) = plan_dir_choice(rx, ry, leaf_dir, tk.sx, tk.sy, -1, -1);\n        tk.dir_pick=dirp; tk.rpx=prx; tk.rpy=pry;\n\n        move_to(tk.rpx, tk.rpy, pcw, pccw);\n        while((pcw>0 || pccw>0) && (int)out.size()<TURN_LIMIT){\n            char rot='.';\n            if(pcw>0){ rot='R'; pcw--; leaf_dir=(leaf_dir+1)&3; }\n            else { rot='L'; pccw--; leaf_dir=(leaf_dir+3)&3; }\n            emit_turn('.', rot, false);\n        }\n        if((int)out.size()>=TURN_LIMIT) break;\n\n        // Pick\n        int fx = rx + dx4[leaf_dir];\n        int fy = ry + dy4[leaf_dir];\n        bool canPick = inb(fx,fy,N) && !holding && occ[fx][fy]==1;\n        emit_turn('.', '.', canPick);\n        if(canPick){ holding=true; occ[fx][fy]=0; }\n        if((int)out.size()>=TURN_LIMIT) break;\n\n        // Choose drop dir; for lookahead, bias to next pick-root nx,ny if known\n        int dird, drx, dry, dcw, dccw;\n        if(nx!=-1){\n            // prefer drop root closer to next pick-root\n            int bestDir=-1, bd=INT_MAX;\n            for(int k=0;k<4;k++){\n                int rdx = tk.tx - dx4[k], rdy = tk.ty - dy4[k];\n                if(!inb(rdx,rdy,N)) continue;\n                int d = manh(rdx,rdy,nx,ny);\n                if(d<bd){ bd=d; bestDir=k; drx=rdx; dry=rdy; }\n            }\n            tie(dcw, dccw) = rot_need(leaf_dir, bestDir);\n            dird=bestDir;\n        }else{\n            tie(dird, drx, dry, dcw, dccw) = plan_dir_choice(rx, ry, leaf_dir, tk.tx, tk.ty);\n        }\n        tk.dir_drop=dird; tk.rdx=drx; tk.rdy=dry;\n\n        move_to(tk.rdx, tk.rdy, dcw, dccw);\n        while((dcw>0 || dccw>0) && (int)out.size()<TURN_LIMIT){\n            char rot='.';\n            if(dcw>0){ rot='R'; dcw--; leaf_dir=(leaf_dir+1)&3; }\n            else { rot='L'; dccw--; leaf_dir=(leaf_dir+3)&3; }\n            emit_turn('.', rot, false);\n        }\n        if((int)out.size()>=TURN_LIMIT) break;\n\n        // Drop\n        fx = rx + dx4[leaf_dir];\n        fy = ry + dy4[leaf_dir];\n        bool canDrop = inb(fx,fy,N) && holding && occ[fx][fy]==0;\n        emit_turn('.', '.', canDrop);\n        if(canDrop){ holding=false; occ[fx][fy]=1; }\n        if((int)out.size()>=TURN_LIMIT) break;\n\n        // Pre-rotate toward next pick while moving there will be handled in next iteration via plan_dir_choice.\n    }\n\n    // Output arm design: 2 vertices, edge length 1, root at (0,0)\n    cout<<2<<\"\\n\";\n    cout<<0<<\" \"<<1<<\"\\n\";\n    cout<<0<<\" \"<<0<<\"\\n\";\n    for(auto &row : out) cout<<row<<\"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    int w; // +1 mackerel, -1 sardine\n};\nstruct Rect {\n    int x1,y1,x2,y2; // inclusive\n    long long score = LLONG_MIN;\n    int a=0,b=0;\n};\n\nstatic inline long long rect_perimeter(int x1,int y1,int x2,int y2){\n    long long w = llabs((long long)x2 - x1);\n    long long h = llabs((long long)y2 - y1);\n    return 2*(w + h);\n}\nstatic inline bool insideRectInclusive(const Rect& r, int x, int y){\n    return (x >= r.x1 && x <= r.x2 && y >= r.y1 && y <= r.y2);\n}\n\nstruct Grid {\n    int G;\n    int B; // bin size\n    int maxCoord = 100000;\n    int W,H;\n    vector<int> a; // W*H\n    vector<long long> ps; // (W+1)*(H+1)\n    Grid(int G_): G(G_) {\n        B = (maxCoord + G - 1) / G; // ceil division\n        W = G; H = G;\n        a.assign(W*H, 0);\n        ps.assign((W+1)*(H+1), 0);\n    }\n    inline int idx(int ix,int iy) const { return iy*W + ix; }\n    inline void addPoint(int x,int y,int w){\n        int ix = min(W-1, x / B);\n        int iy = min(H-1, y / B);\n        a[idx(ix,iy)] += w;\n    }\n    void buildPS(){\n        for(int iy=0; iy<=H; ++iy){\n            for(int ix=0; ix<=W; ++ix){\n                if (ix==0 || iy==0) { ps[iy*(W+1)+ix] = 0; }\n            }\n        }\n        for(int iy=1; iy<=H; ++iy){\n            long long run = 0;\n            for(int ix=1; ix<=W; ++ix){\n                run += a[idx(ix-1,iy-1)];\n                ps[iy*(W+1)+ix] = ps[(iy-1)*(W+1)+ix] + run;\n            }\n        }\n    }\n    inline long long sumRectCells(int lx,int ly,int rx,int ry) const {\n        if (lx>rx || ly>ry) return 0;\n        lx = max(0,lx); ly = max(0,ly);\n        rx = min(W-1,rx); ry = min(H-1,ry);\n        if (lx>rx || ly>ry) return 0;\n        long long s = ps[(ry+1)*(W+1)+(rx+1)]\n                    - ps[(ly)*(W+1)+(rx+1)]\n                    - ps[(ry+1)*(W+1)+(lx)]\n                    + ps[(ly)*(W+1)+(lx)];\n        return s;\n    }\n    inline int cellX1(int ix) const { return max(0, ix * B); }\n    inline int cellX2(int ix) const { return min(maxCoord, (ix+1)*B); }\n    inline int cellY1(int iy) const { return max(0, iy * B); }\n    inline int cellY2(int iy) const { return min(maxCoord, (iy+1)*B); }\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    for(int i=0;i<N;i++){ int x,y; cin>>x>>y; pts.push_back({x,y,+1}); }\n    for(int i=0;i<N;i++){ int x,y; cin>>x>>y; pts.push_back({x,y,-1}); }\n\n    const long long PERIM_LIMIT = 400000;\n    const int MAXC = 100000;\n\n    // Build multiple grids\n    vector<int> Gsizes = {256, 384, 512};\n    vector<Grid> grids;\n    grids.reserve(Gsizes.size());\n    for(int g: Gsizes) grids.emplace_back(g);\n    for (auto &p: pts)\n        for (auto &gr: grids) gr.addPoint(p.x, p.y, p.w);\n    for (auto &gr: grids) gr.buildPS();\n\n    // Candidate pool\n    vector<Rect> candidates;\n    candidates.reserve(4000);\n\n    auto clamp_rect = [&](Rect r)->Rect{\n        r.x1 = max(0, min(MAXC, r.x1));\n        r.x2 = max(0, min(MAXC, r.x2));\n        r.y1 = max(0, min(MAXC, r.y1));\n        r.y2 = max(0, min(MAXC, r.y2));\n        if (r.x1 > r.x2) swap(r.x1, r.x2);\n        if (r.y1 > r.y2) swap(r.y1, r.y2);\n        if (r.x1==r.x2) { if (r.x2<MAXC) r.x2++; else if (r.x1>0) r.x1--; }\n        if (r.y1==r.y2) { if (r.y2<MAXC) r.y2++; else if (r.y1>0) r.y1--; }\n        if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) > PERIM_LIMIT){\n            // shrink around center\n            long long w = r.x2 - r.x1;\n            long long h = r.y2 - r.y1;\n            if (w + h == 0) return r;\n            long long max_sum = PERIM_LIMIT/2;\n            double scale = (double)max_sum / (double)(w + h);\n            long long nw = max(1LL, (long long)(w*scale));\n            long long nh = max(1LL, (long long)(h*scale));\n            long long cx = (r.x1 + r.x2)/2;\n            long long cy = (r.y1 + r.y2)/2;\n            long long nx1 = max(0LL, cx - nw/2);\n            long long nx2 = min((long long)MAXC, nx1 + nw);\n            nx1 = max(0LL, nx2 - nw);\n            long long ny1 = max(0LL, cy - nh/2);\n            long long ny2 = min((long long)MAXC, ny1 + nh);\n            ny1 = max(0LL, ny2 - nh);\n            r.x1 = (int)nx1; r.x2 = (int)nx2;\n            r.y1 = (int)ny1; r.y2 = (int)ny2;\n        }\n        return r;\n    };\n    auto add_candidate = [&](Rect r){\n        r = clamp_rect(r);\n        candidates.push_back(r);\n    };\n\n    // Grid-based candidates with multi-step expansions (binary search per side)\n    for (auto &gr: grids){\n        int W=gr.W, H=gr.H;\n        struct Cell { int ix,iy; int val; };\n        vector<Cell> cells;\n        cells.reserve(W*H);\n        for(int iy=0; iy<H; ++iy)\n            for(int ix=0; ix<W; ++ix)\n                cells.push_back({ix,iy, gr.a[gr.idx(ix,iy)]});\n        int T = min(300, (int)cells.size());\n        nth_element(cells.begin(), cells.begin()+T, cells.end(), [](const Cell& a, const Cell& b){ return a.val > b.val; });\n        cells.resize(T);\n\n        auto rectFromCells = [&](int lx,int ly,int rx,int ry)->Rect{\n            return Rect{ gr.cellX1(lx), gr.cellY1(ly), gr.cellX2(rx), gr.cellY2(ry), 0 };\n        };\n        auto perim_ok_cells = [&](int lx,int ly,int rx,int ry)->bool{\n            Rect r = rectFromCells(lx,ly,rx,ry);\n            return rect_perimeter(r.x1,r.y1,r.x2,r.y2) <= PERIM_LIMIT;\n        };\n        for (const auto &c: cells){\n            int lx=c.ix, rx=c.ix, ly=c.iy, ry=c.iy;\n            long long bestS = gr.sumRectCells(lx,ly,rx,ry);\n            bool improved = true;\n            int iter=0;\n            while (improved && iter<200){\n                ++iter;\n                improved = false;\n                int blx=lx, bly=ly, brx=rx, bry=ry;\n                long long bS = bestS;\n\n                // For each direction, try to expand by multiple cells using exponential then binary search\n                auto try_expand = [&](int &lx,int &ly,int &rx,int &ry, int dir)->void{\n                    // dir: 0 expand left, 1 right, 2 down, 3 up\n                    int Lx=lx, Ly=ly, Rx=rx, Ry=ry;\n                    int lo=0, hi=0;\n                    auto sumHere = [&](int Lx,int Ly,int Rx,int Ry){ return gr.sumRectCells(Lx,Ly,Rx,Ry); };\n                    auto ok = [&](int Lx,int Ly,int Rx,int Ry){ return perim_ok_cells(Lx,Ly,Rx,Ry); };\n                    // prepare movement limits\n                    auto advance = [&](int step)->bool{\n                        int nlx=Lx, nly=Ly, nrx=Rx, nry=Ry;\n                        if (dir==0) nlx = Lx - step;\n                        else if (dir==1) nrx = Rx + step;\n                        else if (dir==2) nly = Ly - step;\n                        else nry = Ry + step;\n                        if (nlx<0 || nly<0 || nrx>=W || nry>=H) return false;\n                        if (!ok(nlx,nly,nrx,nry)) return false;\n                        long long s = sumHere(nlx,nly,nrx,nry);\n                        if (s > bS){ bS = s; blx=nlx; bly=nly; brx=nrx; bry=nry; return true; }\n                        return false;\n                    };\n                    // exponential search for hi\n                    int step = 1;\n                    int lastGood = 0;\n                    while (true){\n                        int nlx=Lx, nly=Ly, nrx=Rx, nry=Ry;\n                        if (dir==0) nlx = Lx - step;\n                        else if (dir==1) nrx = Rx + step;\n                        else if (dir==2) nly = Ly - step;\n                        else nry = Ry + step;\n                        if (nlx<0 || nly<0 || nrx>=W || nry>=H) break;\n                        if (!ok(nlx,nly,nrx,nry)) break;\n                        lastGood = step;\n                        step <<= 1;\n                        if (step <= 0) break;\n                    }\n                    if (lastGood==0) return;\n                    // binary search in [1..lastGood] for best sum (not necessarily monotonic, but we will sample midpoints improving only; to stay simple, we can just try a few splits)\n                    int loStep = 1, hiStep = lastGood;\n                    // Instead of true binary search, try few trial steps: quarter, half, three-quarter, and lastGood\n                    vector<int> trials = { hiStep, hiStep*3/4, hiStep/2, hiStep/4 };\n                    sort(trials.begin(), trials.end());\n                    trials.erase(unique(trials.begin(), trials.end()), trials.end());\n                    for (int s: trials){\n                        int nlx=Lx, nly=Ly, nrx=Rx, nry=Ry;\n                        if (dir==0) nlx = Lx - s;\n                        else if (dir==1) nrx = Rx + s;\n                        else if (dir==2) nly = Ly - s;\n                        else nry = Ry + s;\n                        if (nlx<0 || nly<0 || nrx>=W || nry>=H) continue;\n                        if (!ok(nlx,nly,nrx,nry)) continue;\n                        long long val = sumHere(nlx,nly,nrx,nry);\n                        if (val > bS){ bS=val; blx=nlx; bly=nly; brx=nrx; bry=nry; }\n                    }\n                };\n\n                try_expand(lx,ly,rx,ry,0);\n                try_expand(lx,ly,rx,ry,1);\n                try_expand(lx,ly,rx,ry,2);\n                try_expand(lx,ly,rx,ry,3);\n\n                // Small shrinks might help if sardine-heavy margins got included\n                auto try_shrink = [&](int dir)->void{\n                    int nlx=lx, nly=ly, nrx=rx, nry=ry;\n                    if (dir==0 && lx<rx) nlx=lx+1;\n                    if (dir==1 && lx<rx) nrx=rx-1;\n                    if (dir==2 && ly<ry) nly=ly+1;\n                    if (dir==3 && ly<ry) nry=ry-1;\n                    if (nlx>nrx || nly>nry) return;\n                    long long s = gr.sumRectCells(nlx,nly,nrx,nry);\n                    if (s > bS){ bS=s; blx=nlx; bly=nly; brx=nrx; bry=nry; }\n                };\n                try_shrink(0); try_shrink(1); try_shrink(2); try_shrink(3);\n\n                if (bS > bestS){\n                    bestS = bS;\n                    lx=blx; ly=bly; rx=brx; ry=bry;\n                    improved = true;\n                }\n            }\n            Rect r = rectFromCells(lx,ly,rx,ry);\n            add_candidate(r);\n\n            // Add a few variants: small expansions if within perimeter\n            int variants = 3;\n            for(int t=1;t<=variants;t++){\n                int elx = max(0, lx - t);\n                int erx = min(W-1, rx + t);\n                int ely = max(0, ly - t);\n                int ery = min(H-1, ry + t);\n                Rect r2 = rectFromCells(elx,ly,rx,ry); add_candidate(r2);\n                r2 = rectFromCells(lx,ely,rx,ry); add_candidate(r2);\n                r2 = rectFromCells(lx,ly,erx,ry); add_candidate(r2);\n                r2 = rectFromCells(lx,ly,rx,ery); add_candidate(r2);\n            }\n        }\n    }\n\n    // Random sampling using biased coordinates\n    vector<int> xs_all, ys_all, xs_m, ys_m;\n    xs_all.reserve(pts.size()); ys_all.reserve(pts.size());\n    xs_m.reserve(pts.size()); ys_m.reserve(pts.size());\n    for (auto &p: pts){\n        xs_all.push_back(p.x); ys_all.push_back(p.y);\n        if (p.w==+1){ xs_m.push_back(p.x); ys_m.push_back(p.y); }\n    }\n    auto sample_unique = [&](const vector<int>& v, int k){\n        int M = v.size();\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        static std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n        shuffle(idx.begin(), idx.end(), rng);\n        unordered_set<int> seen;\n        seen.reserve(k*2);\n        vector<int> out; out.reserve(k);\n        for(int i=0;i<M && (int)out.size()<k;i++){\n            int val = v[idx[i]];\n            if (seen.insert(val).second) out.push_back(val);\n        }\n        sort(out.begin(), out.end());\n        return out;\n    };\n    vector<int> sx_all = sample_unique(xs_all, 250);\n    vector<int> sy_all = sample_unique(ys_all, 250);\n    vector<int> sx_m = sample_unique(xs_m, 250);\n    vector<int> sy_m = sample_unique(ys_m, 250);\n    auto merge_coords = [&](vector<int> a, vector<int> b){\n        a.insert(a.end(), b.begin(), b.end());\n        a.push_back(0); a.push_back(MAXC);\n        sort(a.begin(), a.end());\n        a.erase(unique(a.begin(), a.end()), a.end());\n        return a;\n    };\n    vector<int> sx = merge_coords(sx_all, sx_m);\n    vector<int> sy = merge_coords(sy_all, sy_m);\n\n    std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto randint = [&](int L, int R){ std::uniform_int_distribution<int> dist(L,R); return dist(rng); };\n\n    int Xn = (int)sx.size();\n    int Yn = (int)sy.size();\n\n    auto add_rect_from_bounds = [&](int xl,int xr,int yl,int yr){\n        if (xl==xr){ if (xr<MAXC) xr++; else if (xl>0) xl--; }\n        if (yl==yr){ if (yr<MAXC) yr++; else if (yl>0) yl--; }\n        Rect r{xl,yl,xr,yr,0};\n        if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) <= PERIM_LIMIT) add_candidate(r);\n    };\n\n    // Uniform random pairs\n    int S = 2000;\n    for(int t=0;t<S;t++){\n        int i1 = randint(0, Xn-1), i2 = randint(0, Xn-1);\n        int j1 = randint(0, Yn-1), j2 = randint(0, Yn-1);\n        if (i1==i2){ if (i2+1<Xn) i2++; else if (i1>0) i1--; }\n        if (j1==j2){ if (j2+1<Yn) j2++; else if (j1>0) j1--; }\n        int xl = min(sx[i1], sx[i2]);\n        int xr = max(sx[i1], sx[i2]);\n        int yl = min(sy[j1], sy[j2]);\n        int yr = max(sy[j1], sy[j2]);\n        add_rect_from_bounds(xl,xr,yl,yr);\n    }\n    // Biased rectangles: use mackerel coords for one axis\n    int Sb = 1000;\n    for(int t=0;t<Sb;t++){\n        int i1 = randint(0, (int)sx_m.size()-1);\n        int i2 = randint(0, (int)sx_m.size()-1);\n        int j1 = randint(0, Yn-1);\n        int j2 = randint(0, Yn-1);\n        if (i1==i2){ if (i2+1<(int)sx_m.size()) i2++; else if (i1>0) i1--; }\n        if (j1==j2){ if (j2+1<Yn) j2++; else if (j1>0) j1--; }\n        int xl = min(sx_m[i1], sx_m[i2]);\n        int xr = max(sx_m[i1], sx_m[i2]);\n        int yl = min(sy[j1], sy[j2]);\n        int yr = max(sy[j1], sy[j2]);\n        add_rect_from_bounds(xl,xr,yl,yr);\n    }\n    // Anchored rectangles\n    for(int t=0;t<400;t++){\n        int i = randint(0, Xn-1);\n        int j = randint(0, Yn-1);\n        int xl = min(sx[i], MAXC/2);\n        int xr = MAXC;\n        int yl = min(sy[j], MAXC/2);\n        int yr = MAXC;\n        add_rect_from_bounds(xl,xr,yl,yr);\n        add_rect_from_bounds(0, sx[i], 0, sy[j]);\n    }\n\n    // Exact evaluation function\n    auto evaluate = [&](Rect &r){\n        int a=0,b=0;\n        for (auto &p: pts){\n            if (insideRectInclusive(r, p.x, p.y)){\n                if (p.w==1) a++; else b++;\n            }\n        }\n        r.a = a; r.b = b;\n        r.score = (long long)a - (long long)b;\n    };\n\n    // Evaluate all candidates and keep top K\n    for (auto &r: candidates){\n        // ensure within limits\n        r = clamp_rect(r);\n    }\n    // Deduplicate rough by hashing bounds to reduce repeated evals\n    sort(candidates.begin(), candidates.end(), [](const Rect& A, const Rect& B){\n        if (A.x1!=B.x1) return A.x1<B.x1;\n        if (A.y1!=B.y1) return A.y1<B.y1;\n        if (A.x2!=B.x2) return A.x2<B.x2;\n        return A.y2<B.y2;\n    });\n    candidates.erase(unique(candidates.begin(), candidates.end(), [](const Rect& A, const Rect& B){\n        return A.x1==B.x1 && A.y1==B.y1 && A.x2==B.x2 && A.y2==B.y2;\n    }), candidates.end());\n\n    // Evaluate, keep top M\n    int Mkeep = 80;\n    vector<Rect> top;\n    top.reserve(Mkeep);\n    Rect best; best.score = LLONG_MIN;\n    for (auto &r: candidates){\n        evaluate(r);\n        if ((int)top.size() < Mkeep){\n            top.push_back(r);\n        }else{\n            // keep if better than worst\n            int worst = 0;\n            for (int i=1;i<Mkeep;i++) if (top[i].score < top[worst].score) worst = i;\n            if (r.score > top[worst].score || (r.score==top[worst].score && r.a > top[worst].a)){\n                top[worst] = r;\n            }\n        }\n        if (r.score > best.score || (r.score==best.score && r.a > best.a)) best = r;\n    }\n    if (top.empty()){\n        Rect r{0,0,MAXC,MAXC,0}; evaluate(r); best=r; top.push_back(r);\n    }\n\n    // Exact coordinate-descent refinement on top K\n    // Prepare candidate coordinate sets (unique x,y from points near the rectangle)\n    vector<int> xs_pts, ys_pts;\n    xs_pts.reserve(pts.size()); ys_pts.reserve(pts.size());\n    for (auto &p: pts){ xs_pts.push_back(p.x); ys_pts.push_back(p.y); }\n    sort(xs_pts.begin(), xs_pts.end()); xs_pts.erase(unique(xs_pts.begin(), xs_pts.end()), xs_pts.end());\n    sort(ys_pts.begin(), ys_pts.end()); ys_pts.erase(unique(ys_pts.begin(), ys_pts.end()), ys_pts.end());\n\n    auto refine_rect = [&](Rect r){\n        // Limit candidate positions to around current bounds to keep complexity reasonable\n        auto gather_candidates = [&](const vector<int>& v, int low, int high, int k)->vector<int>{\n            // collect indices near low and high\n            vector<int> cand;\n            cand.reserve(k*2 + 10);\n            int iLow = lower_bound(v.begin(), v.end(), low) - v.begin();\n            int iHigh = lower_bound(v.begin(), v.end(), high) - v.begin();\n            // add window around iLow and iHigh\n            for (int d=-k; d<=k; ++d){\n                int i = iLow + d;\n                if (0<=i && i<(int)v.size()) cand.push_back(v[i]);\n                i = iHigh + d;\n                if (0<=i && i<(int)v.size()) cand.push_back(v[i]);\n            }\n            cand.push_back(0); cand.push_back(MAXC);\n            sort(cand.begin(), cand.end());\n            cand.erase(unique(cand.begin(), cand.end()), cand.end());\n            return cand;\n        };\n        vector<int> candX1 = gather_candidates(xs_pts, r.x1, r.x2, 30);\n        vector<int> candX2 = candX1; // reuse\n        vector<int> candY1 = gather_candidates(ys_pts, r.y1, r.y2, 30);\n        vector<int> candY2 = candY1;\n\n        bool improved = true;\n        int iter=0;\n        while (improved && iter<5){\n            ++iter; improved = false;\n            // Move left side\n            Rect bestLoc = r;\n            for (int nx1: candX1){\n                if (nx1 > r.x2) break;\n                if (nx1==r.x1) continue;\n                Rect t{nx1, r.y1, r.x2, r.y2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n            // Move right side\n            bestLoc = r;\n            for (int nx2: candX2){\n                if (nx2 < r.x1) continue;\n                if (nx2==r.x2) continue;\n                Rect t{r.x1, r.y1, nx2, r.y2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n            // Move bottom\n            bestLoc = r;\n            for (int ny1: candY1){\n                if (ny1 > r.y2) break;\n                if (ny1==r.y1) continue;\n                Rect t{r.x1, ny1, r.x2, r.y2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n            // Move top\n            bestLoc = r;\n            for (int ny2: candY2){\n                if (ny2 < r.y1) continue;\n                if (ny2==r.y2) continue;\n                Rect t{r.x1, r.y1, r.x2, ny2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n        }\n        return r;\n    };\n\n    int refineK = min(30, (int)top.size());\n    // Select top refineK by current exact score\n    sort(top.begin(), top.end(), [](const Rect& A, const Rect& B){\n        if (A.score!=B.score) return A.score>B.score;\n        return A.a>B.a;\n    });\n    top.resize(refineK);\n\n    for (int i=0;i<refineK;i++){\n        Rect r = top[i];\n        Rect rr = refine_rect(r);\n        if (rr.score==LLONG_MIN) evaluate(rr);\n        if (rr.score > best.score || (rr.score==best.score && rr.a > best.a)) best = rr;\n    }\n\n    // Final small random nudges around best\n    {\n        std::uniform_int_distribution<int> d(-1000, 1000);\n        for (int t=0;t<200;t++){\n            int dx1 = d(rng), dx2 = d(rng), dy1 = d(rng), dy2 = d(rng);\n            Rect r{\n                max(0, min(MAXC, best.x1 + dx1)),\n                max(0, min(MAXC, best.y1 + dy1)),\n                max(0, min(MAXC, best.x2 + dx2)),\n                max(0, min(MAXC, best.y2 + dy2)),\n                0\n            };\n            if (r.x1>r.x2) swap(r.x1,r.x2);\n            if (r.y1>r.y2) swap(r.y1,r.y2);\n            if (r.x1==r.x2) { if (r.x2<MAXC) r.x2++; else if (r.x1>0) r.x1--; }\n            if (r.y1==r.y2) { if (r.y2<MAXC) r.y2++; else if (r.y1>0) r.y1--; }\n            if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) > PERIM_LIMIT) continue;\n            evaluate(r);\n            if (r.score > best.score || (r.score==best.score && r.a > best.a)) best = r;\n        }\n    }\n\n    // Output rectangle polygon\n    int x1 = max(0, min(MAXC, best.x1));\n    int y1 = max(0, min(MAXC, best.y1));\n    int x2 = max(0, min(MAXC, best.x2));\n    int y2 = max(0, min(MAXC, best.y2));\n    if (x1==x2){ if (x2<MAXC) x2++; else if (x1>0) x1--; }\n    if (y1==y2){ if (y2<MAXC) y2++; else if (y1>0) y1--; }\n    while (rect_perimeter(x1,y1,x2,y2) > PERIM_LIMIT){\n        if ((x2-x1) >= (y2-y1)){\n            if (x2-x1>1) x2--;\n            else if (y2-y1>1) y2--;\n            else break;\n        } else {\n            if (y2-y1>1) y2--;\n            else if (x2-x1>1) x2--;\n            else break;\n        }\n    }\n    cout << 4 << \"\\n\";\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct ColumnState {\n    long long sumH = 0;   // sum of heights in column\n    long long maxW = 0;   // max width in column\n    vector<int> items;    // indices assigned\n};\n\nstruct BuiltLayout {\n    vector<int> col_of;           // column rank (sorted by anchor) for each item\n    vector<int> rot;              // rotation chosen per item (0/1)\n    vector<int> anchor_of_col;    // anchor index per column rank\n    vector<int> prev_anchor;      // previous column's anchor per column rank\n    long long estW = 0, estH = 0;\n    int K = 1;\n};\n\n// Try to build columns with width-aware assignment and rotation choice\nstatic BuiltLayout build_columns_width_aware(\n    int N, int K,\n    const vector<long long>& w0, const vector<long long>& h0,\n    double alpha, double beta, uint64_t seedJitter = 0\n) {\n    // Precompute both orientations per item\n    vector<long long> hA(N), wA(N), hB(N), wB(N); // A: r=0, B: r=1\n    for (int i = 0; i < N; i++) {\n        hA[i] = h0[i]; wA[i] = w0[i];\n        hB[i] = w0[i]; wB[i] = h0[i];\n    }\n    // Order items by \"base height\" = min(h,w) descending; jitter to diversify\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    vector<double> key(N);\n    std::mt19937_64 rng(seedJitter ^ 0x9e3779b97f4a7c15ULL);\n    for (int i = 0; i < N; i++) {\n        double base = (double)min(h0[i], w0[i]);\n        double jit = (seedJitter ? (double)(rng() % 1000) * 1e-6 : 0.0);\n        key[i] = -base + jit; // negative for descending\n    }\n    sort(ord.begin(), ord.end(), [&](int a, int b){\n        if (key[a] != key[b]) return key[a] < key[b];\n        return a < b;\n    });\n\n    vector<ColumnState> cols(K);\n    vector<int> col_of(N, -1);\n    vector<int> rot(N, 0);\n\n    // Assign items\n    for (int idx : ord) {\n        int bestC = 0, bestR = 0;\n        long double bestScore = numeric_limits<long double>::infinity();\n        for (int c = 0; c < K; c++) {\n            // try r=0\n            {\n                long long newH = cols[c].sumH + hA[idx];\n                long long newMaxW = max(cols[c].maxW, wA[idx]);\n                long long sumW_if = 0;\n                for (int cc = 0; cc < K; cc++) {\n                    if (cc == c) sumW_if += newMaxW;\n                    else sumW_if += cols[cc].maxW;\n                }\n                long double sc = alpha * (long double)newH + beta * (long double)sumW_if;\n                if (sc < bestScore) {\n                    bestScore = sc; bestC = c; bestR = 0;\n                }\n            }\n            // try r=1\n            {\n                long long newH = cols[c].sumH + hB[idx];\n                long long newMaxW = max(cols[c].maxW, wB[idx]);\n                long long sumW_if = 0;\n                for (int cc = 0; cc < K; cc++) {\n                    if (cc == c) sumW_if += newMaxW;\n                    else sumW_if += cols[cc].maxW;\n                }\n                long double sc = alpha * (long double)newH + beta * (long double)sumW_if;\n                if (sc < bestScore) {\n                    bestScore = sc; bestC = c; bestR = 1;\n                }\n            }\n        }\n        // commit\n        if (bestR == 0) {\n            cols[bestC].sumH += hA[idx];\n            cols[bestC].maxW = max(cols[bestC].maxW, wA[idx]);\n        } else {\n            cols[bestC].sumH += hB[idx];\n            cols[bestC].maxW = max(cols[bestC].maxW, wB[idx]);\n        }\n        cols[bestC].items.push_back(idx);\n        col_of[idx] = bestC;\n        rot[idx] = bestR;\n    }\n\n    // Determine anchors (min index per original column)\n    vector<int> anchor_orig(K, -1);\n    for (int c = 0; c < K; c++) {\n        if (cols[c].items.empty()) continue;\n        int mn = cols[c].items[0];\n        for (int v : cols[c].items) mn = min(mn, v);\n        anchor_orig[c] = mn;\n    }\n    // Sort columns by anchor index (empty go last)\n    vector<int> col_order(K);\n    iota(col_order.begin(), col_order.end(), 0);\n    sort(col_order.begin(), col_order.end(), [&](int a, int b){\n        int aa = anchor_orig[a], bb = anchor_orig[b];\n        if (aa == -1) return false;\n        if (bb == -1) return true;\n        if (aa != bb) return aa < bb;\n        return a < b;\n    });\n    // Map to rank order\n    vector<int> col_rank(K, K);\n    for (int pos = 0; pos < K; pos++) col_rank[col_order[pos]] = pos;\n\n    // Build outputs\n    BuiltLayout out;\n    out.K = K;\n    out.col_of.assign(N, -1);\n    out.rot = rot;\n    out.anchor_of_col.assign(K, -1);\n    out.prev_anchor.assign(K, -1);\n    long long estW = 0, estH = 0;\n    for (int pos = 0; pos < K; pos++) {\n        int c = col_order[pos];\n        if (anchor_orig[c] != -1) out.anchor_of_col[pos] = anchor_orig[c];\n        if (pos > 0) out.prev_anchor[pos] = anchor_orig[col_order[pos-1]];\n        // map items to ranked column\n        for (int v : cols[c].items) out.col_of[v] = pos;\n        if (!cols[c].items.empty()) {\n            estW += cols[c].maxW;\n            estH = max(estH, cols[c].sumH);\n        }\n    }\n    out.estW = estW; out.estH = estH;\n    return out;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<long long> wp(N), hp(N);\n    for (int i = 0; i < N; i++) cin >> wp[i] >> hp[i];\n\n    // Candidate K and (alpha,beta) pairs\n    vector<int> Ks;\n    vector<int> baseK = {1,2,3,4,5,6,8,10,12,16,20};\n    for (int k : baseK) if (k <= N) Ks.push_back(k);\n    if ((int)Ks.size() > T) Ks.resize(T);\n\n    vector<pair<double,double>> AB = {\n        {1.0, 1.0},\n        {2.0, 1.0},\n        {1.0, 2.0}\n    };\n\n    // Plan turns: iterate over combinations of K and AB, also add some jitter seeds\n    struct Plan { int K; double a, b; uint64_t jitter; };\n    vector<Plan> plans;\n    // Deterministic passes\n    for (int k : Ks) {\n        for (auto [a,b] : AB) plans.push_back({k,a,b,0});\n    }\n    // Add a few randomized variants if time allows\n    std::mt19937_64 rng(123456789);\n    int extra = max(0, T - (int)plans.size());\n    for (int e = 0; e < extra; e++) {\n        int k = Ks[min<int>(e % (int)Ks.size(), (int)Ks.size()-1)];\n        auto [a,b] = AB[e % (int)AB.size()];\n        uint64_t jit = rng();\n        plans.push_back({k,a,b,jit});\n    }\n    if ((int)plans.size() > T) plans.resize(T);\n\n    long long bestProxy = (1LL<<62);\n    int bestPlanIdx = 0;\n\n    for (int t = 0; t < T; t++) {\n        Plan pl = plans[t];\n        auto layout = build_columns_width_aware(N, pl.K, wp, hp, pl.a, pl.b, pl.jitter);\n        long long proxy = layout.estW + layout.estH;\n        if (proxy < bestProxy) {\n            bestProxy = proxy;\n            bestPlanIdx = t;\n        }\n        // Emit placement in increasing index order\n        cout << N << '\\n';\n        for (int i = 0; i < N; i++) {\n            int c = layout.col_of[i];\n            int b = -1;\n            if (c > 0) b = layout.prev_anchor[c];\n            // direction U, rotation as decided in layout.rot\n            cout << i << ' ' << layout.rot[i] << ' ' << 'U' << ' ' << b << '\\n';\n        }\n        cout.flush();\n        long long Wp, Hp;\n        if (!(cin >> Wp >> Hp)) return 0;\n        // Optional debug:\n        // cerr << \"# t=\"<<t<<\" K=\"<<pl.K<<\" a=\"<<pl.a<<\" b=\"<<pl.b<<\" proxy=\"<<proxy<<\" obs=\"<<(Wp+Hp)<<\"\\n\";\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct RunResult {\n    vector<int> parent;\n    vector<int> depth;\n    long long score;\n};\n\nstatic inline uint64_t get_time_us() {\n    using namespace std::chrono;\n    return duration_cast<microseconds>(steady_clock::now().time_since_epoch()).count();\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    vector<int> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\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    // coords not used\n    for(int i=0;i<N;i++){ int x,y; cin >> x >> y; (void)x; (void)y; }\n\n    // Sort vertices by ascending A\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j){\n        if(A[i]!=A[j]) return A[i] < A[j];\n        return i < j;\n    });\n\n    // Layered multi-source BFS with A-ascending within each layer and tie-break by smaller-A parent\n    auto layered_bfs = [&](const vector<int>& roots, vector<int>& parent, vector<int>& depth, vector<int>& root_of){\n        const int INF = 1e9;\n        parent.assign(N, -2);\n        depth.assign(N, INF);\n        root_of.assign(N, -1);\n        vector<int> cur, nxt;\n        cur.reserve(N);\n        nxt.reserve(N);\n        for(int r: roots){\n            depth[r] = 0;\n            parent[r] = -1;\n            root_of[r] = r;\n            cur.push_back(r);\n        }\n        sort(cur.begin(), cur.end(), [&](int i, int j){\n            if(A[i]!=A[j]) return A[i] < A[j];\n            return i<j;\n        });\n        int d = 0;\n        while(!cur.empty()){\n            for(int u: cur){\n                for(int v: adj[u]){\n                    if(depth[v] == INF){\n                        depth[v] = d + 1;\n                        parent[v] = u;\n                        root_of[v] = root_of[u];\n                        nxt.push_back(v);\n                    }else if(depth[v] == d + 1){\n                        if(A[u] < A[parent[v]]){\n                            parent[v] = u;\n                            root_of[v] = root_of[u];\n                        }\n                    }\n                }\n            }\n            d++;\n            if(nxt.empty()) break;\n            sort(nxt.begin(), nxt.end(), [&](int i, int j){\n                if(A[i]!=A[j]) return A[i] < A[j];\n                return i<j;\n            });\n            cur.clear();\n            cur.swap(nxt);\n        }\n    };\n\n    // Post-process: choose minimal-A parent among neighbors at depth-1\n    auto refine_parents_minA = [&](vector<int>& parent, const vector<int>& depth){\n        for(int v=0; v<N; v++){\n            int d = depth[v];\n            if(d <= 0) continue;\n            int bestp = parent[v];\n            int bestA = (bestp>=0 ? A[bestp] : INT_MAX);\n            for(int u: adj[v]){\n                if(depth[u] == d-1){\n                    if(A[u] < bestA){\n                        bestA = A[u];\n                        bestp = u;\n                    }\n                }\n            }\n            parent[v] = bestp;\n        }\n    };\n\n    auto compute_score = [&](const vector<int>& depth)-> long long {\n        long long s = 1;\n        for(int i=0;i<N;i++){\n            int d = depth[i];\n            if(d < 0 || d > 100000000) d = 0;\n            s += 1LL * (d + 1) * A[i];\n        }\n        return s;\n    };\n\n    // Estimate coverage: number of nodes with depth>H within H steps from cand\n    auto estimate_coverage = [&](int cand, const vector<int>& depth)-> int {\n        vector<int> dist(N, INT_MAX);\n        deque<int> dq;\n        dist[cand] = 0;\n        dq.push_back(cand);\n        int covered = 0;\n        while(!dq.empty()){\n            int u = dq.front(); dq.pop_front();\n            if(depth[u] > H) covered++;\n            if(dist[u] == H) continue;\n            for(int v: adj[u]){\n                if(dist[v] == INT_MAX){\n                    dist[v] = dist[u] + 1;\n                    dq.push_back(v);\n                }\n            }\n        }\n        return covered;\n    };\n\n    // Build roots with enhanced selection: farthest band + coverage-aware + low A\n    auto build_roots = [&](int seed)-> vector<int> {\n        vector<int> roots;\n        roots.push_back(seed);\n        vector<int> parent, depth, root_of;\n        layered_bfs(roots, parent, depth, root_of);\n        while(true){\n            int Dmax = -1;\n            for(int v=0; v<N; v++) if(depth[v] > H && depth[v] < INT_MAX) Dmax = max(Dmax, depth[v]);\n            if(Dmax == -1) break;\n            int band_low = max(H+1, Dmax - 2);\n            // Collect candidate pool\n            struct Cand { int v; int a; int d; int deg; int cov; };\n            vector<Cand> cands;\n            cands.reserve(64);\n            for(int v=0; v<N; v++){\n                if(depth[v] >= band_low && depth[v] > H){\n                    cands.push_back({v, A[v], depth[v], (int)adj[v].size(), 0});\n                }\n            }\n            if(cands.empty()){\n                for(int v=0; v<N; v++){\n                    if(depth[v] > H){\n                        cands.push_back({v, A[v], depth[v], (int)adj[v].size(), 0});\n                    }\n                }\n            }\n            if(cands.empty()) break;\n            // Sort by A asc, then depth desc\n            sort(cands.begin(), cands.end(), [&](const Cand& x, const Cand& y){\n                if(x.a != y.a) return x.a < y.a;\n                if(x.d != y.d) return x.d > y.d;\n                return x.deg > y.deg;\n            });\n            // Evaluate coverage for top K candidates\n            int K = min<int>(32, cands.size());\n            int bestIdx = 0;\n            int bestA = INT_MAX, bestCov = -1, bestD = -1, bestDeg = -1;\n            for(int i=0;i<K;i++){\n                int v = cands[i].v;\n                int cov = estimate_coverage(v, depth);\n                cands[i].cov = cov;\n                int a = cands[i].a;\n                int d = cands[i].d;\n                int deg = cands[i].deg;\n                if(a < bestA ||\n                   (a==bestA && cov > bestCov) ||\n                   (a==bestA && cov==bestCov && d > bestD) ||\n                   (a==bestA && cov==bestCov && d==bestD && deg > bestDeg)){\n                    bestA = a; bestCov = cov; bestD = d; bestDeg = deg; bestIdx = i;\n                }\n            }\n            int pick = cands[bestIdx].v;\n            roots.push_back(pick);\n            layered_bfs(roots, parent, depth, root_of);\n        }\n        return roots;\n    };\n\n    // Prepare candidate seeds: bottom L_low by A, and farthest-spread among them\n    int L_low = min(N, 120);\n    vector<int> lowA(order.begin(), order.begin()+L_low);\n\n    auto farthest_sampling = [&](int k)-> vector<int> {\n        vector<int> seeds;\n        if(lowA.empty() || k<=0) return seeds;\n        seeds.push_back(lowA[0]);\n        vector<int> dist(N, INT_MAX);\n        while((int)seeds.size() < k){\n            // distances from seeds\n            deque<int> dq;\n            fill(dist.begin(), dist.end(), INT_MAX);\n            for(int s: seeds){\n                dist[s] = 0;\n                dq.push_back(s);\n            }\n            while(!dq.empty()){\n                int u = dq.front(); dq.pop_front();\n                for(int v: adj[u]){\n                    if(dist[v] == INT_MAX){\n                        dist[v] = dist[u] + 1;\n                        dq.push_back(v);\n                    }\n                }\n            }\n            int bestv = -1, bestd = -1, besta = INT_MAX;\n            for(int v: lowA){\n                if(dist[v] > bestd || (dist[v]==bestd && A[v] < besta)){\n                    bestd = dist[v];\n                    besta = A[v];\n                    bestv = v;\n                }\n            }\n            if(bestv == -1) break;\n            if(find(seeds.begin(), seeds.end(), bestv) != seeds.end()) break;\n            seeds.push_back(bestv);\n        }\n        return seeds;\n    };\n\n    // Multi-start runs under time budget\n    uint64_t start_us = get_time_us();\n    uint64_t time_budget_us = 1900000; // ~1.9s\n    vector<int> seed_list;\n    int K_byA = min(14, L_low);\n    for(int i=0;i<K_byA;i++) seed_list.push_back(lowA[i]);\n    vector<int> spread = farthest_sampling(6);\n    for(int s: spread) seed_list.push_back(s);\n    sort(seed_list.begin(), seed_list.end());\n    seed_list.erase(unique(seed_list.begin(), seed_list.end()), seed_list.end());\n\n    RunResult best; best.score = LLONG_MIN;\n\n    for(size_t si=0; si<seed_list.size(); si++){\n        if(get_time_us() - start_us > time_budget_us) break;\n        int seed = seed_list[si];\n        vector<int> roots = build_roots(seed);\n        vector<int> parent, depth, root_of;\n        layered_bfs(roots, parent, depth, root_of);\n\n        // Safety and refinement\n        for(int i=0;i<N;i++){\n            if(depth[i] == INT_MAX){ parent[i] = -1; depth[i] = 0; }\n            if(depth[i] > H){ parent[i] = -1; depth[i] = 0; }\n            if(parent[i] == -2){ parent[i] = -1; if(depth[i] == INT_MAX) depth[i] = 0; }\n        }\n        refine_parents_minA(parent, depth);\n\n        long long sc = compute_score(depth);\n        if(sc > best.score){\n            best.score = sc;\n            best.parent = parent;\n            best.depth = depth;\n        }\n    }\n\n    // Fallback if no run executed\n    if(best.parent.empty()){\n        vector<int> parent(N, -1);\n        for(int i=0;i<N;i++){\n            if(i) cout << ' ';\n            cout << parent[i];\n        }\n        cout << '\\n';\n        return 0;\n    }\n\n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << best.parent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<string> C(N);\n    for (int i = 0; i < N; ++i) cin >> C[i];\n\n    // Collect positions and precompute Fukunokami positions.\n    vector<vector<bool>> hasF(N, vector<bool>(N, false));\n    vector<pair<int,int>> oni;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (C[i][j] == 'o') hasF[i][j] = true;\n            else if (C[i][j] == 'x') oni.emplace_back(i, j);\n        }\n    }\n\n    // Precompute prefix counts of Fukunokami per row/column to check rays quickly.\n    vector<vector<int>> rowPref(N, vector<int>(N+1, 0));\n    vector<vector<int>> colPref(N, vector<int>(N+1, 0));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            rowPref[i][j+1] = rowPref[i][j] + (hasF[i][j] ? 1 : 0);\n            colPref[j][i+1] = colPref[j][i] + (hasF[i][j] ? 1 : 0);\n        }\n    }\n\n    auto safe_up = [&](int i, int j)->bool {\n        // No Fukunokami above (rows 0..i-1) in column j\n        if (i == 0) return true;\n        return colPref[j][i] - colPref[j][0] == 0;\n    };\n    auto safe_down = [&](int i, int j)->bool {\n        // No Fukunokami below (rows i+1..N-1) in column j\n        if (i == N-1) return true;\n        return colPref[j][N] - colPref[j][i+1] == 0;\n    };\n    auto safe_left = [&](int i, int j)->bool {\n        if (j == 0) return true;\n        return rowPref[i][j] - rowPref[i][0] == 0;\n    };\n    auto safe_right = [&](int i, int j)->bool {\n        if (j == N-1) return true;\n        return rowPref[i][N] - rowPref[i][j+1] == 0;\n    };\n\n    struct Op { char d; int p; };\n    vector<Op> ops;\n    ops.reserve(1600);\n\n    // For each Oni, pick minimal cost safe direction and emit.\n    for (auto [i, j] : oni) {\n        // Determine available safe directions and their costs.\n        int bestCost = INT_MAX;\n        char bestDir = 0;\n        int param = -1; // row/col index\n\n        // Up\n        if (safe_up(i, j)) {\n            int k = i; // distance to top edge\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'U'; param = j; }\n        }\n        // Down\n        if (safe_down(i, j)) {\n            int k = (N - 1 - i);\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'D'; param = j; }\n        }\n        // Left\n        if (safe_left(i, j)) {\n            int k = j;\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'L'; param = i; }\n        }\n        // Right\n        if (safe_right(i, j)) {\n            int k = (N - 1 - j);\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'R'; param = i; }\n        }\n\n        // Per problem guarantee, at least one is safe.\n        if (bestDir == 0) {\n            // Fallback: should not happen; do nothing to avoid WA.\n            continue;\n        }\n\n        // Emit k+1 pushes toward bestDir, then k+1 pushes back.\n        int k;\n        char backDir;\n        if (bestDir == 'U') { k = i; backDir = 'D'; }\n        else if (bestDir == 'D') { k = (N - 1 - i); backDir = 'U'; }\n        else if (bestDir == 'L') { k = j; backDir = 'R'; }\n        else { // 'R'\n            k = (N - 1 - j); backDir = 'L';\n        }\n\n        // Ensure we do not exceed 4N^2 operations; with guarantees this should hold.\n        // But add a safety break.\n        if ((int)ops.size() + 2 * (k + 1) > 4 * N * N) break;\n\n        for (int t = 0; t < k + 1; ++t) ops.push_back({bestDir, param});\n        for (int t = 0; t < k + 1; ++t) ops.push_back({backDir, param});\n    }\n\n    // Output\n    for (auto &op : ops) {\n        cout << op.d << ' ' << op.p << '\\n';\n    }\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::high_resolution_clock::time_point st;\n    Timer(){ reset(); }\n    void reset(){ st = chrono::high_resolution_clock::now(); }\n    double elapsed() const {\n        auto ed = chrono::high_resolution_clock::now();\n        return chrono::duration<double>(ed - st).count();\n    }\n};\n\nstatic inline long long llabsll(long long x){ return x<0?-x:x; }\n\nstruct Solution {\n    vector<int> a, b;\n    vector<int> t;\n    long long error = (1LL<<60);\n};\n\nstatic inline long long compute_error(const vector<int>& t, const vector<int>& T){\n    long long e=0;\n    int N = (int)T.size();\n    for(int i=0;i<N;i++) e += llabsll((long long)t[i]-T[i]);\n    return e;\n}\n\nstatic inline vector<int> simulate_counts(const vector<int>& a, const vector<int>& b, long long L){\n    int N = (int)a.size();\n    vector<int> t(N,0);\n    int x = 0;\n    for(long long week=0; week<L; week++){\n        t[x]++;\n        int nx = ((t[x] & 1) ? a[x] : b[x]);\n        x = nx;\n    }\n    return t;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N; long long L;\n    if(!(cin>>N>>L)) return 0;\n    vector<int> T(N);\n    for(int i=0;i<N;i++) cin>>T[i];\n\n    Timer tim;\n    std::mt19937 rng(123456789);\n\n    // Backbone ring for b\n    vector<int> base_b(N);\n    for(int i=0;i<N;i++) base_b[i] = (i+1)%N;\n\n    // Approximate port usage by targets\n    vector<int> d1(N), d0(N);\n    for(int i=0;i<N;i++){\n        d1[i] = (T[i]+1)/2;\n        d0[i] = T[i]/2;\n    }\n    // b-inflow per node\n    vector<int> b_in(N,0);\n    for(int i=0;i<N;i++){\n        int j = base_b[i];\n        b_in[j] += d0[i];\n    }\n    // a-demand per destination\n    vector<long long> a_demand0(N,0);\n    for(int j=0;j<N;j++){\n        long long need = (long long)T[j] - (long long)b_in[j];\n        if(need < 0) need = 0;\n        a_demand0[j] = need;\n    }\n    vector<int> a_supply0 = d1;\n\n    auto build_candidate_a = [&](int variant_seed)->vector<int>{\n        vector<int> a(N,-1);\n        vector<long long> a_demand = a_demand0;\n        vector<int> a_supply = a_supply0;\n        // Sources order: by supply desc, tie by rotation offset\n        vector<int> src(N);\n        iota(src.begin(), src.end(), 0);\n        int rot = variant_seed % N;\n        sort(src.begin(), src.end(), [&](int x, int y){\n            if(a_supply[x] != a_supply[y]) return a_supply[x] > a_supply[y];\n            int rx = (x - rot + N) % N;\n            int ry = (y - rot + N) % N;\n            return rx < ry;\n        });\n        // Destination priority queue\n        struct Dest { long long rem; int id; };\n        struct Cmp { bool operator()(const Dest& a, const Dest& b) const {\n            if(a.rem != b.rem) return a.rem < b.rem;\n            return a.id > b.id;\n        } };\n        priority_queue<Dest, vector<Dest>, Cmp> pq;\n        for(int j=0;j<N;j++) pq.push({a_demand[j], j});\n\n        for(int s_idx=0; s_idx<N; s_idx++){\n            int s = src[s_idx];\n            int sup = a_supply[s];\n            if(sup<=0){\n                // choose something not equal to b[s] or self\n                int cand = (base_b[s]+2) % N;\n                if(cand==s) cand = (cand+1)%N;\n                if(cand==base_b[s]) cand = (cand+1)%N;\n                a[s] = cand;\n                continue;\n            }\n            // Pull top K candidates\n            vector<Dest> cand;\n            int K = min(N, 12);\n            for(int k=0; k<K && !pq.empty(); k++){\n                cand.push_back(pq.top()); pq.pop();\n            }\n            // Scoring function with penalties\n            auto score_dest = [&](int dest)->long long{\n                long long rem = a_demand[dest];\n                // Penalize equality to b[s] and self to avoid 2-cycles/self loops\n                if(dest == base_b[s]) rem -= sup/2 + 1;\n                if(dest == s) rem -= sup + 2;\n                // Penalize picking same as neighbors' a to spread\n                int prev = (s+N-1)%N, next = (s+1)%N;\n                // no direct info of neighbors' a yet; skip\n                return rem;\n            };\n            int pick = -1, pick_idx=-1;\n            long long bestScore = LLONG_MIN/4;\n            for(int i=0;i<(int)cand.size();i++){\n                long long sc = score_dest(cand[i].id);\n                if(cand[i].rem >= sup) sc += sup/4; // reward fit\n                if(sc > bestScore){\n                    bestScore = sc; pick = cand[i].id; pick_idx = i;\n                }\n            }\n            if(pick==-1){\n                // fallback to largest rem not equal to b[s]\n                int alt = -1, idx=-1; long long mx=-1;\n                for(int i=0;i<(int)cand.size();i++){\n                    if(cand[i].id==base_b[s] || cand[i].id==s) continue;\n                    if(cand[i].rem > mx){ mx=cand[i].rem; alt=cand[i].id; idx=i; }\n                }\n                if(alt==-1){\n                    // truly fallback\n                    alt = (base_b[s]+2)%N;\n                }\n                pick = alt; pick_idx = -1;\n            }\n            a[s] = pick;\n            if(pick_idx>=0) cand[pick_idx].rem -= sup;\n            a_demand[pick] -= sup;\n            for(auto &dn: cand) pq.push(dn);\n        }\n\n        // Fix invalid or equal to b/self\n        for(int i=0;i<N;i++){\n            if(a[i] < 0 || a[i] >= N) a[i] = (base_b[i]+2)%N;\n            if(a[i] == base_b[i]){\n                int alt = (base_b[i]+2)%N;\n                if(alt==i) alt = (alt+1)%N;\n                a[i] = alt;\n            }\n            if(a[i] == i){\n                int alt = (i+2)%N;\n                if(alt==base_b[i]) alt=(alt+1)%N;\n                if(alt==i) alt=(alt+1)%N;\n                a[i] = alt;\n            }\n        }\n        return a;\n    };\n\n    auto evaluate = [&](const vector<int>& a, const vector<int>& b)->Solution{\n        Solution sol;\n        sol.a = a; sol.b = b;\n        sol.t = simulate_counts(sol.a, sol.b, L);\n        sol.error = compute_error(sol.t, T);\n        return sol;\n    };\n\n    // Generate multiple candidates and pick the best\n    int num_inits = 8;\n    Solution best;\n    best.error = (1LL<<60);\n    vector<int> bestA, bestB;\n    for(int v=0; v<num_inits; v++){\n        auto a0 = build_candidate_a(v*17 + 3);\n        auto b0 = base_b;\n        auto sol = evaluate(a0, b0);\n        if(sol.error < best.error){\n            best = sol;\n            bestA = sol.a; bestB = sol.b;\n        }\n        if(tim.elapsed() > 0.6) break;\n    }\n\n    vector<int> a = bestA;\n    vector<int> b = bestB;\n    vector<int> t = best.t;\n    long long bestE = best.error;\n\n    // Local search\n    auto recompute_lists = [&](const vector<int>& t, vector<pair<long long,int>>& over, vector<pair<long long,int>>& under){\n        over.clear(); under.clear();\n        for(int i=0;i<N;i++){\n            long long diff = (long long)t[i] - T[i];\n            if(diff > 0) over.push_back({diff, i});\n            else if(diff < 0) under.push_back({-diff, i});\n        }\n        sort(over.begin(), over.end(), greater<>());\n        sort(under.begin(), under.end(), greater<>());\n    };\n\n    auto try_redirect = [&](int s, int new_dest)->bool{\n        if(new_dest==b[s] || new_dest==s) return false;\n        int old = a[s];\n        if(old==new_dest) return false;\n        a[s] = new_dest;\n        auto tt = simulate_counts(a,b,L);\n        long long E = compute_error(tt, T);\n        if(E < bestE){\n            bestE = E; t.swap(tt);\n            return true;\n        }else{\n            a[s] = old;\n            return false;\n        }\n    };\n\n    auto try_swap = [&](int s1, int s2)->bool{\n        if(s1==s2) return false;\n        int a1=a[s1], a2=a[s2];\n        if(a1==a2) return false;\n        if(a2==b[s1] || a1==b[s2] || a2==s1 || a1==s2) return false;\n        swap(a[s1], a[s2]);\n        auto tt = simulate_counts(a,b,L);\n        long long E = compute_error(tt, T);\n        if(E < bestE){\n            bestE = E; t.swap(tt);\n            return true;\n        }else{\n            swap(a[s1], a[s2]);\n            return false;\n        }\n    };\n\n    double time_budget = 1.7;\n    vector<pair<long long,int>> over, under;\n    recompute_lists(t, over, under);\n\n    // Focused iterations\n    int outer_iters = 0;\n    while(tim.elapsed() < time_budget){\n        outer_iters++;\n        if(over.empty() || under.empty()) break;\n\n        // Try a batch of moves\n        bool improved = false;\n\n        // 1) Redirect from sources contributing to overfull nodes\n        int topk = min(8, (int)over.size());\n        int topu = min(8, (int)under.size());\n        for(int oi=0; oi<topk && tim.elapsed()<time_budget; oi++){\n            int dst_over = over[oi].second;\n            // find sources whose a maps to dst_over\n            vector<int> cand_s;\n            cand_s.reserve(N/4);\n            for(int s=0;s<N;s++) if(a[s]==dst_over) cand_s.push_back(s);\n            if(cand_s.empty()) continue;\n            // for each, try redirect to one of top under\n            shuffle(cand_s.begin(), cand_s.end(), rng);\n            for(int si=0; si<(int)cand_s.size() && tim.elapsed()<time_budget; si++){\n                int s = cand_s[si];\n                for(int ui=0; ui<topu; ui++){\n                    int dst_under = under[ui].second;\n                    if(try_redirect(s, dst_under)){\n                        improved = true;\n                        recompute_lists(t, over, under);\n                        break;\n                    }\n                }\n                if(improved) break;\n            }\n            if(improved) break;\n        }\n\n        // 2) Try swapping two sources' a to transfer flow\n        if(!improved && tim.elapsed()<time_budget){\n            // pick one source mapping to top over, another mapping to some other destination, and swap\n            if(!over.empty()){\n                int dst_over = over[0].second;\n                vector<int> s_over;\n                for(int s=0;s<N;s++) if(a[s]==dst_over) s_over.push_back(s);\n                if(!s_over.empty()){\n                    int s1 = s_over[rng()%s_over.size()];\n                    // choose s2 mapping to a destination which is over-supplied less or under-supplied\n                    int s2 = -1;\n                    // Prefer sources whose a maps to a node with deficit\n                    unordered_set<int> deficit_set;\n                    for(int i=0;i<(int)under.size() && i<12;i++) deficit_set.insert(under[i].second);\n                    for(int s=0;s<N;s++){\n                        if(s==s1) continue;\n                        if(deficit_set.count(a[s])){ s2 = s; break; }\n                    }\n                    if(s2==-1){\n                        // any different destination\n                        for(int s=0;s<N;s++){ if(s!=s1 && a[s]!=a[s1]){ s2=s; break; } }\n                    }\n                    if(s2!=-1){\n                        if(try_swap(s1, s2)){\n                            improved = true;\n                            recompute_lists(t, over, under);\n                        }\n                    }\n                }\n            }\n        }\n\n        if(!improved){\n            // Random perturbation\n            int s = rng()%N;\n            int dest = rng()%N;\n            if(try_redirect(s, dest)){\n                recompute_lists(t, over, under);\n            }else{\n                // give up this round\n                break;\n            }\n        }else{\n            // continue improving\n            continue;\n        }\n    }\n\n    // Output best found\n    for(int i=0;i<N;i++){\n        cout<<a[i]<<\" \"<<b[i]<<\"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    DSU(int n=0): n(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){ a=find(a); b=find(b); if(a==b) return false; if(r[a]<r[b]) swap(a,b); p[b]=a; if(r[a]==r[b]) r[a]++; return true; }\n};\n\nstatic inline uint32_t part1by1(uint32_t x){\n    x &= 0x0000ffff;\n    x = (x | (x << 8)) & 0x00FF00FF;\n    x = (x | (x << 4)) & 0x0F0F0F0F;\n    x = (x | (x << 2)) & 0x33333333;\n    x = (x | (x << 1)) & 0x55555555;\n    return x;\n}\nstatic inline uint32_t morton2D(uint32_t x, uint32_t y){\n    return (part1by1(y) << 1) | part1by1(x);\n}\n\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    vector<int> cx(N), cy(N);\n    for(int i=0;i<N;i++){\n        cx[i] = (lx[i]+rx[i])>>1;\n        cy[i] = (ly[i]+ry[i])>>1;\n    }\n    auto codeOf = [&](int i)->uint32_t{\n        uint32_t xs = (uint32_t) min(16383, max(0, cx[i]*16383/10000));\n        uint32_t ys = (uint32_t) min(16383, max(0, cy[i]*16383/10000));\n        return morton2D(xs, ys);\n    };\n    auto centerDist = [&](int a, int b)->int{\n        long dx = cx[a]-cx[b];\n        long dy = cy[a]-cy[b];\n        long long d2 = dx*dx + dy*dy;\n        return (int)floor(sqrt((long double)d2));\n    };\n\n    // initial Morton ordering\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a,int b){\n        uint32_t ca=codeOf(a), cb=codeOf(b);\n        if(ca!=cb) return ca<cb;\n        if(cx[a]!=cx[b]) return cx[a]<cx[b];\n        if(cy[a]!=cy[b]) return cy[a]<cy[b];\n        return a<b;\n    });\n\n    // Build boundary cuts with small local optimization without modifying ord array:\n    vector<int> cuts(M+1, 0);\n    for(int i=1;i<=M;i++) cuts[i] = cuts[i-1] + G[i-1];\n    const int S = 5;\n    for(int b=1;b<M;b++){\n        int base = cuts[b];\n        int bestCut = base;\n        long bestScore = LLONG_MAX;\n        for(int cut = base - S; cut <= base + S; cut++){\n            if(cut <= cuts[b-1]) continue;\n            if(cut >= cuts[b+1]) continue;\n            auto safeDist = [&](int i, int j)->int{\n                if(i<0||j<0||i>=N||j>=N) return 1000000;\n                return centerDist(ord[i], ord[j]);\n            };\n            long sc = 0;\n            sc += safeDist(cut-1, cut);\n            sc += safeDist(cut-2, cut);\n            sc += safeDist(cut-1, cut+1);\n            if(sc < bestScore){ bestScore=sc; bestCut=cut; }\n        }\n        int delta = bestCut - base;\n        // apply this delta to all subsequent cuts\n        for(int t=b; t<=M; t++) cuts[t] += delta;\n    }\n    // Build groups by ord and cuts\n    vector<vector<int>> groups(M);\n    for(int k=0;k<M;k++){\n        int l = cuts[k], r = cuts[k+1];\n        l = max(l, 0); r = min(r, N);\n        if(r<l) r=l;\n        groups[k].assign(ord.begin()+l, ord.begin()+r);\n        // if due to constraints it became wrong size, fix by simple fallback slicing from ord\n        if((int)groups[k].size() != G[k]){\n            groups.clear(); groups.resize(M);\n            int p=0;\n            for(int i=0;i<M;i++){\n                for(int t=0;t<G[i];t++) groups[i].push_back(ord[p++]);\n            }\n            break;\n        }\n    }\n\n    int queries_left = Q;\n\n    auto do_query = [&](const vector<int>& C)->vector<pair<int,int>>{\n        int l = (int)C.size();\n        if(l<2) return {};\n        if(l>L) l=L; // safety cap, but we only call with l<=L\n        cout<<\"? \"<<l;\n        for(int i=0;i<l;i++) cout<<\" \"<<C[i];\n        cout<<\"\\n\"<<flush;\n        vector<pair<int,int>> ret;\n        ret.reserve(max(0,l-1));\n        for(int i=0;i<l-1;i++){\n            int a,b; cin>>a>>b;\n            if(a>b) swap(a,b);\n            ret.emplace_back(a,b);\n        }\n        return ret;\n    };\n\n    struct Edge {int u,v,w;};\n\n    // grid-based candidate edges\n    auto grid_candidates = [&](const vector<int>& vs, int cell)->vector<Edge>{\n        int n = (int)vs.size();\n        if(n<=1) return {};\n        unordered_map<long long, vector<int>> bucket;\n        bucket.reserve(n*2);\n        auto key = [&](int x, int y)->long long{\n            long long gx = x / cell;\n            long long gy = y / cell;\n            return (gx<<20) ^ gy;\n        };\n        for(int u: vs){\n            bucket[key(cx[u], cy[u])].push_back(u);\n        }\n        vector<Edge> edges;\n        edges.reserve(n*8);\n        int dxs[9] = {-1,0,1,-1,0,1,-1,0,1};\n        int dys[9] = {-1,-1,-1,0,0,0,1,1,1};\n        for(int u: vs){\n            long long gx = cx[u] / cell;\n            long long gy = cy[u] / cell;\n            vector<pair<int,int>> cand;\n            cand.reserve(24);\n            for(int d=0; d<9; d++){\n                long long nx = gx + dxs[d];\n                long long ny = gy + dys[d];\n                long long k = (nx<<20) ^ ny;\n                auto it = bucket.find(k);\n                if(it==bucket.end()) continue;\n                for(int v: it->second){\n                    if(v==u) continue;\n                    cand.emplace_back(centerDist(u,v), v);\n                }\n            }\n            int take = min((int)cand.size(), 8);\n            if(take>0){\n                nth_element(cand.begin(), cand.begin()+take, cand.end(),\n                            [](const auto& A, const auto& B){ return A.first < B.first; });\n                for(int i=0;i<take;i++){\n                    int a=u,b=cand[i].second; if(a>b) swap(a,b);\n                    edges.push_back({a,b,cand[i].first});\n                }\n            }\n        }\n        sort(edges.begin(), edges.end(), [](const Edge& A,const Edge& B){\n            if(A.u!=B.u) return A.u<B.u;\n            if(A.v!=B.v) return A.v<B.v;\n            return A.w<B.w;\n        });\n        edges.erase(unique(edges.begin(), edges.end(), [](const Edge& A,const Edge& B){\n            return A.u==B.u && A.v==B.v;\n        }), edges.end());\n        return edges;\n    };\n\n    // approximate MST with rich candidates\n    auto approx_mst = [&](const vector<int>& vs)->vector<pair<int,int>>{\n        int n=(int)vs.size();\n        if(n<=1) return {};\n        vector<Edge> edges;\n        edges.reserve(n*28);\n        // Morton\n        vector<pair<uint32_t,int>> marr(n);\n        for(int i=0;i<n;i++) marr[i]={codeOf(vs[i]), vs[i]};\n        sort(marr.begin(), marr.end());\n        vector<int> mseq(n);\n        for(int i=0;i<n;i++) mseq[i]=marr[i].second;\n        // axis\n        vector<int> xseq = vs, yseq = vs;\n        sort(xseq.begin(), xseq.end(), [&](int a,int b){\n            if(cx[a]!=cx[b]) return cx[a]<cx[b];\n            if(cy[a]!=cy[b]) return cy[a]<cy[b];\n            return a<b;\n        });\n        sort(yseq.begin(), yseq.end(), [&](int a,int b){\n            if(cy[a]!=cy[b]) return cy[a]<cy[b];\n            if(cx[a]!=cx[b]) return cx[a]<cx[b];\n            return a<b;\n        });\n        const int mortonWindow=70, mortonK=14, axisWindow=14, axisK=8;\n        for(int i=0;i<n;i++){\n            int u=mseq[i];\n            vector<pair<int,int>> cand; cand.reserve(2*mortonWindow);\n            for(int d=1; d<=mortonWindow; d++){\n                int j=i-d; if(j>=0){ int v=mseq[j]; cand.emplace_back(centerDist(u,v), v); }\n                j=i+d; if(j<n){ int v=mseq[j]; cand.emplace_back(centerDist(u,v), v); }\n            }\n            int take=min((int)cand.size(), mortonK);\n            if(take>0){\n                nth_element(cand.begin(), cand.begin()+take, cand.end(),\n                            [](const auto& A,const auto& B){ return A.first < B.first; });\n                for(int t=0;t<take;t++){\n                    int v=cand[t].second, w=cand[t].first;\n                    int a=u,b=v; if(a>b) swap(a,b);\n                    edges.push_back({a,b,w});\n                }\n            }\n        }\n        auto add_seq = [&](const vector<int>& seq){\n            for(int i=0;i<(int)seq.size();i++){\n                int u=seq[i];\n                vector<pair<int,int>> cand; cand.reserve(2*axisWindow);\n                for(int d=1; d<=axisWindow; d++){\n                    int j=i-d; if(j>=0){ int v=seq[j]; cand.emplace_back(centerDist(u,v), v); }\n                    j=i+d; if(j<(int)seq.size()){ int v=seq[j]; cand.emplace_back(centerDist(u,v), v); }\n                }\n                int take=min((int)cand.size(), axisK);\n                if(take>0){\n                    nth_element(cand.begin(), cand.begin()+take, cand.end(),\n                                [](const auto& A,const auto& B){ return A.first < B.first; });\n                    for(int t=0;t<take;t++){\n                        int v=cand[t].second, w=cand[t].first;\n                        int a=u,b=v; if(a>b) swap(a,b);\n                        edges.push_back({a,b,w});\n                    }\n                }\n            }\n        };\n        add_seq(xseq);\n        add_seq(yseq);\n        int cell = max(400, min(1200, W));\n        auto gridE = grid_candidates(vs, cell);\n        edges.insert(edges.end(), gridE.begin(), gridE.end());\n\n        sort(edges.begin(), edges.end(), [&](const Edge& A,const Edge& B){\n            if(A.u!=B.u) return A.u<B.u;\n            if(A.v!=B.v) return A.v<B.v;\n            return A.w<B.w;\n        });\n        edges.erase(unique(edges.begin(), edges.end(), [&](const Edge& A,const Edge& B){\n            return A.u==B.u && A.v==B.v;\n        }), edges.end());\n\n        DSU dsu(N);\n        sort(edges.begin(), edges.end(), [&](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        vector<pair<int,int>> res; res.reserve(n-1);\n        for(const auto &e: edges){\n            if(dsu.unite(e.u,e.v)){\n                res.emplace_back(e.u,e.v);\n                if((int)res.size()==n-1) break;\n            }\n        }\n        if((int)res.size()<n-1){\n            for(int i=0;i<n-1;i++){\n                int a=mseq[i], b=mseq[i+1];\n                if(dsu.unite(a,b)){\n                    if(a>b) swap(a,b);\n                    res.emplace_back(a,b);\n                }\n            }\n        }\n        if((int)res.size()>n-1) res.resize(n-1);\n        return res;\n    };\n\n    // Block MST with strict query accounting: will only query if queries_left >= blocks\n    auto block_mst = [&](const vector<int>& vs, int &queries_left_ref)->vector<pair<int,int>>{\n        int n=(int)vs.size();\n        if(n<=1) return {};\n        vector<pair<uint32_t,int>> marr(n);\n        for(int i=0;i<n;i++) marr[i]={codeOf(vs[i]), vs[i]};\n        sort(marr.begin(), marr.end());\n        vector<int> orderLoc(n);\n        for(int i=0;i<n;i++) orderLoc[i]=marr[i].second;\n        vector<vector<int>> blocks;\n        for(int i=0;i<n;i+=L){\n            int r=min(n, i+L);\n            vector<int> blk; blk.reserve(r-i);\n            for(int j=i;j<r;j++) blk.push_back(orderLoc[j]);\n            blocks.push_back(move(blk));\n        }\n        int B=(int)blocks.size();\n        if(B<=queries_left_ref){\n            vector<pair<int,int>> intra;\n            for(int b=0;b<B;b++){\n                if((int)blocks[b].size()<=1) continue;\n                auto e = do_query(blocks[b]);\n                queries_left_ref--; // consume here\n                intra.insert(intra.end(), e.begin(), e.end());\n            }\n            // connect blocks approximately\n            struct Edge{int u,v,w;};\n            vector<Edge> inter;\n            auto add_best_between = [&](const vector<int>& A, const vector<int>& B, int capPairs){\n                vector<int> aCand, bCand;\n                int ca=min(6,(int)A.size()), cb=min(6,(int)B.size());\n                for(int t=0;t<ca;t++){\n                    int idx = (int)llround((double)t*(A.size()-1)/max(1,ca-1));\n                    aCand.push_back(A[idx]);\n                }\n                for(int t=0;t<cb;t++){\n                    int idx = (int)llround((double)t*(B.size()-1)/max(1,cb-1));\n                    bCand.push_back(B[idx]);\n                }\n                vector<Edge> local;\n                for(int a: aCand) for(int b: bCand){\n                    int w=centerDist(a,b);\n                    int u=a,v=b; if(u>v) swap(u,v);\n                    local.push_back({u,v,w});\n                }\n                sort(local.begin(), local.end(), [](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                int take=min((int)local.size(), capPairs);\n                for(int i=0;i<take;i++) inter.push_back(local[i]);\n            };\n            for(int b=0;b<B-1;b++) add_best_between(blocks[b], blocks[b+1], 3);\n            for(int b=0;b<B-2;b++) add_best_between(blocks[b], blocks[b+2], 1);\n\n            vector<tuple<int,int,int>> edges; edges.reserve(intra.size()+inter.size());\n            for(auto &p: intra){\n                int w=centerDist(p.first,p.second);\n                edges.emplace_back(w, min(p.first,p.second), max(p.first,p.second));\n            }\n            for(auto &e: inter){\n                edges.emplace_back(e.w, e.u, e.v);\n            }\n            sort(edges.begin(), edges.end());\n            DSU dsu(N);\n            vector<pair<int,int>> res; res.reserve(n-1);\n            for(auto &t: edges){\n                int u=get<1>(t), v=get<2>(t);\n                if(dsu.unite(u,v)){\n                    res.emplace_back(u,v);\n                    if((int)res.size()==n-1) break;\n                }\n            }\n            if((int)res.size()<n-1){\n                for(int i=0;i<n-1;i++){\n                    int a=orderLoc[i], b=orderLoc[i+1];\n                    if(dsu.unite(a,b)){\n                        if(a>b) swap(a,b);\n                        res.emplace_back(a,b);\n                    }\n                }\n            }\n            if((int)res.size()>n-1) res.resize(n-1);\n            return res;\n        }else{\n            return approx_mst(vs);\n        }\n    };\n\n    // Micro-queries: t subsets of size L; consume queries_left accordingly and return anchors\n    auto micro_queries = [&](const vector<int>& vs, int t, int &queries_left_ref)->vector<pair<int,int>>{\n        vector<pair<int,int>> anchors;\n        int n=(int)vs.size();\n        if(n<=1 || t<=0) return anchors;\n        vector<pair<uint32_t,int>> marr(n);\n        for(int i=0;i<n;i++) marr[i]={codeOf(vs[i]), vs[i]};\n        sort(marr.begin(), marr.end());\n        vector<int> seq(n);\n        for(int i=0;i<n;i++) seq[i]=marr[i].second;\n        t = min(t, queries_left_ref);\n        for(int s=0; s<t; s++){\n            vector<int> subset; subset.reserve(L);\n            long long start = (long long)s * n / t;\n            for(int j=0;j<L;j++){\n                long long idx = (start + (long long)j * n / L) % n;\n                subset.push_back(seq[(int)idx]);\n            }\n            auto e = do_query(subset);\n            queries_left_ref--;\n            anchors.insert(anchors.end(), e.begin(), e.end());\n        }\n        return anchors;\n    };\n\n    // Query planning strictly with per-group counts\n    vector<int> plan(M, 0); // 0=approx, 1=whole, 2=block, 3=approx+micro\n    vector<int> micro_cnt(M, 0);\n\n    // First: whole-group for small\n    for(int k=0;k<M;k++){\n        if((int)groups[k].size()<=L && queries_left>=1){\n            plan[k]=1;\n            queries_left -= 1; // reserve\n        }\n    }\n    // Medium: block if affordable now\n    for(int k=0;k<M;k++){\n        if(plan[k]!=0) continue;\n        int sz = (int)groups[k].size();\n        if(sz>L && sz<=3*L){\n            int need = (sz+L-1)/L;\n            if(queries_left>=need){\n                plan[k]=2;\n                queries_left -= need; // reserve\n            }\n        }\n    }\n    // Distribute remaining queries to large groups as micro anchors, 1 each in round-robin\n    vector<int> largeIdx;\n    for(int k=0;k<M;k++){\n        if(plan[k]==0 && (int)groups[k].size()>3*L) largeIdx.push_back(k);\n    }\n    int ptr=0;\n    while(queries_left>0 && !largeIdx.empty()){\n        int k = largeIdx[ptr];\n        micro_cnt[k] += 1;\n        queries_left -= 1;\n        ptr++; if(ptr>=(int)largeIdx.size()) ptr=0;\n    }\n    // Note: We reserved queries in planning; during construction we will not consume again. To keep accounting consistent,\n    // we introduce a local variable local_queries_left = planned_reserved + remaining actual Q at construction time\n    int local_queries_left = Q;\n\n    // Build edges per group\n    vector<vector<pair<int,int>>> group_edges(M);\n    for(int k=0;k<M;k++){\n        const auto& g = groups[k];\n        int sz = (int)g.size();\n        if(sz<=1){ group_edges[k]={}; continue; }\n        if(plan[k]==1){\n            // whole group query\n            // consume one query from local_queries_left (must be >=1)\n            if(local_queries_left>=1){\n                auto e = do_query(g);\n                local_queries_left -= 1;\n                group_edges[k]=e;\n            }else{\n                group_edges[k]=approx_mst(g);\n            }\n        }else if(plan[k]==2){\n            // block queries\n            group_edges[k] = block_mst(g, local_queries_left);\n        }else if(micro_cnt[k]>0){\n            auto anchors = micro_queries(g, micro_cnt[k], local_queries_left);\n            auto approx = approx_mst(g);\n            struct T {int w,u,v,t;};\n            vector<T> E; E.reserve(anchors.size()+approx.size());\n            for(auto &p: anchors){\n                int w=centerDist(p.first,p.second);\n                E.push_back({w, min(p.first,p.second), max(p.first,p.second), 0});\n            }\n            for(auto &p: approx){\n                int w=centerDist(p.first,p.second);\n                E.push_back({w, min(p.first,p.second), max(p.first,p.second), 1});\n            }\n            sort(E.begin(), E.end(), [](const T& A,const T& B){\n                if(A.w!=B.w) return A.w<B.w;\n                if(A.t!=B.t) return A.t<B.t;\n                if(A.u!=B.u) return A.u<B.u;\n                return A.v<B.v;\n            });\n            DSU dsu(N);\n            vector<pair<int,int>> res; res.reserve(sz-1);\n            for(auto &e: E){\n                if(dsu.unite(e.u,e.v)){\n                    res.emplace_back(e.u,e.v);\n                    if((int)res.size()==sz-1) break;\n                }\n            }\n            if((int)res.size()<sz-1){\n                // fallback simple chain within group order g (which is contiguous in ord)\n                for(int i=0;i<sz-1;i++){\n                    int a=g[i], b=g[i+1];\n                    if(dsu.unite(a,b)){\n                        if(a>b) swap(a,b);\n                        res.emplace_back(a,b);\n                    }\n                }\n            }\n            if((int)res.size()>sz-1) res.resize(sz-1);\n            group_edges[k]=res;\n        }else{\n            group_edges[k]=approx_mst(g);\n        }\n        // safety: enforce endpoints belong to group and count exact sz-1\n        if((int)group_edges[k].size() < sz-1){\n            // fill with chain\n            DSU dsu2(N);\n            for(auto &e: group_edges[k]) dsu2.unite(e.first, e.second);\n            for(int i=0;i<sz-1 && (int)group_edges[k].size()<sz-1;i++){\n                int a=g[i], b=g[i+1];\n                if(dsu2.unite(a,b)){\n                    if(a>b) swap(a,b);\n                    group_edges[k].push_back({a,b});\n                }\n            }\n        }else if((int)group_edges[k].size() > sz-1){\n            group_edges[k].resize(sz-1);\n        }\n    }\n\n    // Final output\n    cout<<\"!\"<<\"\\n\";\n    for(int k=0;k<M;k++){\n        const auto& g = groups[k];\n        for(int i=0;i<(int)g.size();i++){\n            if(i) cout<<\" \";\n            cout<<g[i];\n        }\n        cout<<\"\\n\";\n        for(auto &e: group_edges[k]){\n            cout<<e.first<<\" \"<<e.second<<\"\\n\";\n        }\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint N, M;\nvector<Pos> targets;\nvector<string> out_actions;\n\ninline bool inb(int i,int j){ return 0<=i && i<N && 0<=j && j<N; }\n\nenum Dir {U=0,D=1,L=2,R=3};\nconst int di[4] = {-1,1,0,0};\nconst int dj[4] = {0,0,-1,1};\nchar dirChar(Dir d){ return d==U?'U':d==D?'D':d==L?'L':'R'; }\n\nstruct Grid {\n    int N;\n    vector<uint8_t> blk; // N*N\n    Grid(int N):N(N),blk(N*N,0){}\n    inline bool isBlock(int i,int j) const { return blk[i*N+j]; }\n    inline void toggle(int i,int j){ blk[i*N+j]^=1; }\n    inline void set(int i,int j,bool v){ blk[i*N+j]=v; }\n};\n\nGrid grid(20);\n\nvoid emit(char act, Dir d){\n    string s; s+=act; s+=' '; s+=dirChar(d);\n    out_actions.push_back(s);\n}\n\n// Try to move one step if free\nbool try_move(Pos &p, Dir d){\n    int ni=p.i+di[d], nj=p.j+dj[d];\n    if(!inb(ni,nj)) return false;\n    if(grid.isBlock(ni,nj)) return false;\n    emit('M', d);\n    p.i=ni; p.j=nj;\n    return true;\n}\n\n// Slide in dir until blocked (or border). Return landing.\nPos simulate_slide(const Pos &p, Dir d){\n    int i=p.i, j=p.j;\n    while(true){\n        int ni=i+di[d], nj=j+dj[d];\n        if(!inb(ni,nj)) break;\n        if(grid.isBlock(ni,nj)) break;\n        i=ni; j=nj;\n    }\n    return {i,j};\n}\nvoid do_slide(Pos &p, Dir d){\n    emit('S', d);\n    p = simulate_slide(p,d);\n}\n\n// Place temp block at cell (ci,cj): do Alter towards that cell from adjacent cell?\n// But Alter operation is relative to current position. We cannot alter arbitrary cells!\n// Important correction: Alter toggles the adjacent square in the specified direction FROM CURRENT POSITION. So to place a block somewhere, we must stand adjacent to it and issue A towards it.\n// This changes the design: we cannot place arbitrary stopper remotely. We must navigate to adjacent cell to place/remove blocks.\n\n// Therefore, strategy must avoid heavy block placement, or place only blocks adjacent to our path. Simple baseline: use Moves mostly, slides aided by borders only. Additionally, we can sometimes place a stopper right before a slide by moving adjacent to the intended stopper location.\n\n// Revised plan:\n// - Use Moves primarily, occasionally use slides leveraging borders, no remote stoppers.\n// - Because remote altering is impossible, temporary stopper placement is expensive (requires path to be adjacent), often negating benefit.\n// - So we will implement a safe and simple mover: greedy Manhattan path using Moves, with opportunistic Slides when aligned with border stopping at target row/col.\n\n// Heuristic with borders only:\n// From p to t:\n// - If same row: try to slide horizontally towards t: check landing equals t if border or a block stops at t; initially no blocks, border stops at edge, so landing will be at border, not t unless t is at border. So only helpful when target lies on border in that direction.\n// - Similarly for same column.\n// Given constraint, slides are rarely useful without blocks. Therefore, the robust baseline is pure Moves with a dash of slides when target is on border alignment. This will still succeed within 1600 actions for M=40 and N=20 because worst-case per leg ~ 38 moves, total ~ < 1500 average. This is acceptable and guarantees full visitation. It won't rank high but is safe.\n\n// We'll implement:\n// - Simple obstacle-aware BFS using Moves only (since blocks may exist if we accidentally placed some; but we won't place any). BFS in 20x20 is trivial. However, dynamic obstacles none, so Manhattan greedy is fine and faster.\n// - But to avoid getting stuck when we do slides, we won't place any blocks, and we will avoid sliding except when we can land exactly on target (same row/col and target on the border in that direction).\n\n// Implementation now reverts to Move-only with rare slides.\n\nbool can_land_by_slide_to_target(const Pos &p, const Pos &t, Dir &d_out){\n    if(p.i==t.i){\n        if(t.j==0 && t.j<p.j){ d_out = L; return true; }\n        if(t.j==N-1 && t.j>p.j){ d_out = R; return true; }\n    }\n    if(p.j==t.j){\n        if(t.i==0 && t.i<p.i){ d_out = U; return true; }\n        if(t.i==N-1 && t.i>p.i){ d_out = D; return true; }\n    }\n    return false;\n}\n\nvoid move_greedy(Pos &p, const Pos &t){\n    // simple Manhattan greedy avoiding blocks (there are none if we never alter)\n    while(!(p.i==t.i && p.j==t.j)){\n        Dir d;\n        if(p.i < t.i) d=D;\n        else if(p.i > t.i) d=U;\n        else if(p.j < t.j) d=R;\n        else d=L;\n        // try move preferred, else try orthogonal alternatives\n        if(try_move(p,d)) continue;\n        // try other three directions to detour minimally\n        bool moved=false;\n        for(int k=0;k<4;k++){\n            if(try_move(p, (Dir)k)){ moved=true; break; }\n        }\n        if(!moved){\n            // grid fully blocked around, should not happen with our no-block policy\n            break;\n        }\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if(!(cin>>N>>M)) return 0;\n    targets.resize(M);\n    for(int k=0;k<M;k++){\n        cin>>targets[k].i>>targets[k].j;\n    }\n    grid = Grid(N);\n    Pos cur = targets[0];\n    for(int k=1;k<M;k++){\n        Pos t = targets[k];\n        // try border slide if possible\n        Dir d;\n        if(can_land_by_slide_to_target(cur, t, d)){\n            // Ensure slide path has no internal blocks; we have none, so safe\n            do_slide(cur, d);\n        }else{\n            move_greedy(cur, t);\n        }\n    }\n    // Output\n    for(auto &s: out_actions) cout<<s<<\"\\n\";\n    return 0;\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int a,b,c,d; // [a,c) x [b,d)\n    long long area;\n    inline int w() const { return c - a; }\n    inline int h() const { return d - b; }\n    inline void recompute_area() { area = 1LL * (c - a) * (d - b); }\n};\n\nstatic inline bool overlap_pos(const Rect& A, const Rect& B){\n    if (A.c <= B.a || B.c <= A.a) return false;\n    if (A.d <= B.b || B.d <= A.b) return false;\n    return true;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n;\n    if(!(cin>>n)) return 0;\n    vector<int> x(n), y(n);\n    vector<long long> r(n);\n    for(int i=0;i<n;i++) cin>>x[i]>>y[i]>>r[i];\n\n    vector<Rect> rect(n);\n\n    // Spatial grid\n    const int G = 64;\n    const int GRID = (10000 + G - 1) / G;\n    vector<vector<int>> buckets(GRID * GRID);\n    auto cell_id = [&](int gx, int gy){ return gy*GRID + gx; };\n    auto gx_from_x = [&](int X){ return min(GRID-1, max(0, X / G)); };\n    auto gy_from_y = [&](int Y){ return min(GRID-1, max(0, Y / G)); };\n\n    auto add_rect = [&](int id){\n        const Rect &R = rect[id];\n        int gx0 = gx_from_x(R.a), gx1 = gx_from_x(max(0, R.c-1));\n        int gy0 = gy_from_y(R.b), gy1 = gy_from_y(max(0, R.d-1));\n        for(int gy=gy0; gy<=gy1; ++gy)\n            for(int gx=gx0; gx<=gx1; ++gx)\n                buckets[cell_id(gx,gy)].push_back(id);\n    };\n    auto remove_rect = [&](int id){\n        const Rect &R = rect[id];\n        int gx0 = gx_from_x(R.a), gx1 = gx_from_x(max(0, R.c-1));\n        int gy0 = gy_from_y(R.b), gy1 = gy_from_y(max(0, R.d-1));\n        for(int gy=gy0; gy<=gy1; ++gy)\n            for(int gx=gx0; gx<=gx1; ++gx){\n                auto &v = buckets[cell_id(gx,gy)];\n                for(size_t k=0;k<v.size();++k){\n                    if(v[k]==id){ v[k]=v.back(); v.pop_back(); break; }\n                }\n            }\n    };\n    auto check_band = [&](const Rect& NR, int x0, int x1, int y0, int y1, int self)->bool{\n        int gx0 = gx_from_x(x0);\n        int gx1 = gx_from_x(max(0,x1-1));\n        int gy0 = gy_from_y(y0);\n        int gy1 = gy_from_y(max(0,y1-1));\n        for (int gy=gy0; gy<=gy1; ++gy)\n            for (int gx=gx0; gx<=gx1; ++gx){\n                const auto &v = buckets[cell_id(gx,gy)];\n                for (int id : v) {\n                    if (id==self) continue;\n                    if (overlap_pos(NR, rect[id])) return false;\n                }\n            }\n        return true;\n    };\n    auto can_expand = [&](int i, int s)->bool{\n        const Rect &R = rect[i];\n        if (s==0) { if (R.a <= 0) return false; Rect NR=R; NR.a=R.a-1; return check_band(NR, NR.a, R.a, R.b, R.d, i); }\n        if (s==1) { if (R.c >= 10000) return false; Rect NR=R; NR.c=R.c+1; return check_band(NR, R.c, NR.c, R.b, R.d, i); }\n        if (s==2) { if (R.b <= 0) return false; Rect NR=R; NR.b=R.b-1; return check_band(NR, R.a, R.c, NR.b, R.b, i); }\n        // s==3\n        if (R.d >= 10000) return false; Rect NR=R; NR.d=R.d+1; return check_band(NR, R.a, R.c, R.d, NR.d, i);\n    };\n    auto do_expand = [&](int i, int s){\n        remove_rect(i);\n        if (s==0) rect[i].a--;\n        else if (s==1) rect[i].c++;\n        else if (s==2) rect[i].b--;\n        else rect[i].d++;\n        rect[i].recompute_area();\n        add_rect(i);\n    };\n    auto contains_seed = [&](int i, const Rect& R)->bool{\n        // ensure [xi,xi+1) x [yi,yi+1) inside R\n        return (R.a <= x[i] && x[i]+1 <= R.c && R.b <= y[i] && y[i]+1 <= R.d);\n    };\n    auto can_shrink = [&](int i, int s)->bool{\n        const Rect &R = rect[i];\n        Rect NR = R;\n        if (s==0) { if (R.c - (R.a+1) <= 0) return false; NR.a++; }\n        else if (s==1) { if ((R.c-1) - R.a <= 0) return false; NR.c--; }\n        else if (s==2) { if (R.d - (R.b+1) <= 0) return false; NR.b++; }\n        else { if ((R.d-1) - R.b <= 0) return false; NR.d--; }\n        // keep seed cell inside\n        if (!contains_seed(i, NR)) return false;\n        return true;\n    };\n    auto do_shrink = [&](int i, int s){\n        remove_rect(i);\n        if (s==0) rect[i].a++;\n        else if (s==1) rect[i].c--;\n        else if (s==2) rect[i].b++;\n        else rect[i].d--;\n        rect[i].recompute_area();\n        add_rect(i);\n    };\n    auto score = [&](long long si, long long ri)->long double{\n        long double mn = min<long double>(ri, si);\n        long double mx = max<long double>(ri, si);\n        long double t = mn / mx;\n        return 1.0L - (1.0L - t)*(1.0L - t);\n    };\n\n    // RNG and timer\n    uint64_t seed = chrono::high_resolution_clock::now().time_since_epoch().count();\n    mt19937_64 rng(seed);\n    auto now = [&](){ return chrono::high_resolution_clock::now(); };\n    auto start_time = now();\n    const double TIME_LIMIT = 4.9;\n    auto elapsed_sec = [&](){ return chrono::duration<double>(now() - start_time).count(); };\n\n    // Safe initialization: 1x1 seeds at (x,y)\n    for (int i=0;i<n;i++){\n        Rect R = {x[i], y[i], x[i]+1, y[i]+1, 0};\n        R.recompute_area();\n        rect[i]=R;\n        add_rect(i);\n    }\n\n    vector<long double> PI(n);\n    for (int i=0;i<n;i++) PI[i] = score(rect[i].area, r[i]);\n\n    auto max_expand_steps = [&](int i, int s, int maxSteps)->int{\n        const Rect &R = rect[i];\n        int lo = 0, hi = maxSteps;\n        auto feasible = [&](int steps)->bool{\n            if (steps==0) return true;\n            Rect NR = R;\n            if (s==0) { if (R.a - steps < 0) return false; NR.a = R.a - steps; return check_band(NR, R.a - steps, R.a, R.b, R.d, i); }\n            if (s==1) { if (R.c + steps > 10000) return false; NR.c = R.c + steps; return check_band(NR, R.c, R.c + steps, R.b, R.d, i); }\n            if (s==2) { if (R.b - steps < 0) return false; NR.b = R.b - steps; return check_band(NR, R.a, R.c, R.b - steps, R.b, i); }\n            // s==3\n            if (R.d + steps > 10000) return false; NR.d = R.d + steps; return check_band(NR, R.a, R.c, R.d, R.d + steps, i);\n        };\n        while (lo < hi) {\n            int mid = (lo + hi + 1) >> 1;\n            if (feasible(mid)) lo = mid; else hi = mid - 1;\n        }\n        return lo;\n    };\n\n    auto aspect_bias = [&](int i, int dir, long long k)->long double{\n        long double target = sqrt((long double)r[i]);\n        long double w = rect[i].w(), h = rect[i].h();\n        if (dir<=1) w += k; else h += k;\n        long double aerr = fabsl(w/h - 1.0L);\n        long double aw = fabsl(w - target);\n        long double ah = fabsl(h - target);\n        return -0.00002L * aerr - 0.000002L * (aw + ah);\n    };\n\n    // Phase A: grow up to target\n    while (elapsed_sec() < TIME_LIMIT * 0.6) {\n        vector<pair<long long,int>> ord(n);\n        for (int i=0;i<n;i++){\n            long long deficit = r[i] - rect[i].area;\n            ord[i] = {deficit, i};\n        }\n        sort(ord.begin(), ord.end(), [&](auto &L, auto &R){\n            if (L.first != R.first) return L.first > R.first;\n            return L.second < R.second;\n        });\n        bool any=false;\n        for (int kk=0; kk<n && elapsed_sec() < TIME_LIMIT * 0.6; ++kk){\n            int i = ord[kk].second;\n            if (rect[i].area >= r[i]) continue;\n            int w0 = rect[i].w(), h0 = rect[i].h();\n            int best_dir = -1, best_steps = 0;\n            long double best_gain = 0.0L;\n            for (int d=0; d<4; ++d){\n                int steps = max_expand_steps(i, d, 48);\n                if (steps <= 0) continue;\n                long long inc_per = (d<=1 ? h0 : w0);\n                long long need = r[i] - rect[i].area;\n                long long k = min<long long>(steps, max(0LL, need) / max(1LL, inc_per));\n                if (k <= 0) k = min<long long>(steps, 1);\n                long long si = rect[i].area;\n                long long newS = si + k * inc_per;\n                if (newS > r[i]) continue;\n                long double gain = (score(newS, r[i]) - score(si, r[i])) + aspect_bias(i, d, k);\n                if (gain > best_gain + 1e-18) { best_gain=gain; best_dir=d; best_steps=(int)k; }\n            }\n            if (best_dir != -1 && best_steps > 0) {\n                for (int t=0; t<best_steps; ++t) {\n                    if (!can_expand(i, best_dir)) break;\n                    do_expand(i, best_dir);\n                }\n                PI[i] = score(rect[i].area, r[i]);\n                any=true;\n            }\n        }\n        if (!any) break;\n    }\n\n    // Isolation-based overshoot\n    auto isolation_score = [&](int i)->int{\n        int total = 0;\n        total += max_expand_steps(i, 0, 64);\n        total += max_expand_steps(i, 1, 64);\n        total += max_expand_steps(i, 2, 64);\n        total += max_expand_steps(i, 3, 64);\n        return total;\n    };\n    vector<int> iso(n);\n    for (int i=0;i<n;i++) iso[i] = isolation_score(i);\n\n    while (elapsed_sec() < TIME_LIMIT * 0.78) {\n        vector<tuple<int,long long,int>> order2;\n        order2.reserve(n);\n        for (int i=0;i<n;i++) order2.emplace_back(iso[i], r[i]-rect[i].area, i);\n        sort(order2.begin(), order2.end(), [&](auto&A, auto&B){\n            if (get<0>(A)!=get<0>(B)) return get<0>(A)>get<0>(B);\n            if (get<1>(A)!=get<1>(B)) return get<1>(A)>get<1>(B);\n            return get<2>(A)<get<2>(B);\n        });\n        bool any=false;\n        for (auto &tp: order2){\n            if (elapsed_sec() >= TIME_LIMIT * 0.78) break;\n            int i = get<2>(tp);\n            long long si = rect[i].area, ri_ = r[i];\n            double f = 1.0 + min(0.10, 0.02 + 0.0005 * get<0>(tp));\n            long long cap = (long long)floor(ri_ * f + 1e-9);\n            if (si >= cap) continue;\n            int w0 = rect[i].w(), h0 = rect[i].h();\n            int best_dir=-1, best_steps=0;\n            long double best_gain=0.0L;\n            for (int d=0; d<4; ++d){\n                int steps = max_expand_steps(i, d, 32);\n                if (steps<=0) continue;\n                long long inc_per = (d<=1 ? h0 : w0);\n                long long k = min<long long>(steps, (cap - si) / max(1LL, inc_per));\n                if (k<=0) continue;\n                long long newS = si + k * inc_per;\n                long double gain = (score(newS, ri_) - score(si, ri_)) + 0.5L*aspect_bias(i, d, k);\n                if (gain > best_gain + 1e-18) { best_gain=gain; best_dir=d; best_steps=(int)k; }\n            }\n            if (best_dir!=-1 && best_steps>0 && best_gain > 1e-12) {\n                for (int t=0;t<best_steps;++t){ if (!can_expand(i,best_dir)) break; do_expand(i,best_dir); }\n                PI[i]=score(rect[i].area, r[i]);\n                any=true;\n            }\n        }\n        if (!any) break;\n        for (int i=0;i<n;i++) if ((i&7)==0) iso[i]=isolation_score(i);\n    }\n\n    // Cooperative micro-shrink with seed preservation\n    auto try_coop = [&](int a, int side)->bool{\n        if (rect[a].area <= r[a]) return false;\n        if (!can_shrink(a, side)) return false;\n        Rect oldA = rect[a];\n        remove_rect(a);\n        if (side==0) rect[a].a++;\n        else if (side==1) rect[a].c--;\n        else if (side==2) rect[a].b++;\n        else rect[a].d--;\n        rect[a].recompute_area();\n        add_rect(a);\n        long double dSelf = score(rect[a].area, r[a]) - PI[a];\n\n        int x0 = min(oldA.a, rect[a].a), x1 = max(oldA.c, rect[a].c);\n        int y0 = min(oldA.b, rect[a].b), y1 = max(oldA.d, rect[a].d);\n        int gx0 = gx_from_x(x0), gx1 = gx_from_x(max(0,x1-1));\n        int gy0 = gy_from_y(y0), gy1 = gy_from_y(max(0,y1-1));\n        unordered_set<int> candset; candset.reserve(64);\n        for (int gy=gy0; gy<=gy1; ++gy)\n            for (int gx=gx0; gx<=gx1; ++gx)\n                for (int b : buckets[cell_id(gx,gy)]) if (b!=a) candset.insert(b);\n\n        struct Move { int id, dir, k; long double gain; };\n        Move best = {-1,-1,0,0.0L};\n        for (int b : candset) {\n            if (rect[b].area >= r[b]) continue;\n            int w0 = rect[b].w(), h0 = rect[b].h();\n            for (int d=0; d<4; ++d){\n                int steps =  max(1, max_expand_steps(b, d, 32));\n                if (steps<=0) continue;\n                long long inc_per = (d<=1 ? h0 : w0);\n                long long need = r[b] - rect[b].area;\n                long long k = min<long long>(steps, need / max(1LL, inc_per));\n                if (k<=0) k = min(steps, 1);\n                long long si = rect[b].area;\n                long long newS = si + k * inc_per;\n                if (newS > r[b]) continue;\n                long double gain = score(newS, r[b]) - score(si, r[b]);\n                if (gain > best.gain + 1e-12) best = {b, d, (int)k, gain};\n            }\n        }\n        long double total_gain = dSelf + best.gain;\n        if (best.id != -1 && total_gain > 1e-12) {\n            for (int t=0;t<best.k;++t){ if (!can_expand(best.id,best.dir)) break; do_expand(best.id,best.dir); }\n            PI[a] += dSelf;\n            PI[best.id] = score(rect[best.id].area, r[best.id]);\n            return true;\n        } else {\n            // revert\n            remove_rect(a);\n            rect[a] = oldA;\n            rect[a].recompute_area();\n            add_rect(a);\n            return false;\n        }\n    };\n\n    double coop_budget_end = TIME_LIMIT * 0.93;\n    vector<int> order(n); iota(order.begin(), order.end(), 0);\n    int coop_attempts = 0;\n    while (elapsed_sec() < coop_budget_end && coop_attempts < 30000){\n        shuffle(order.begin(), order.end(), rng);\n        bool any=false;\n        for (int i : order){\n            if (elapsed_sec() >= coop_budget_end) break;\n            if (rect[i].area <= r[i]) continue;\n            array<pair<int,int>,4> sides = {{\n                {rect[i].w(), 0}, {rect[i].w(), 1}, {rect[i].h(), 2}, {rect[i].h(), 3}\n            }};\n            sort(sides.begin(), sides.end(), [&](auto&A, auto&B){ return A.first > B.first; });\n            for (auto [__, s] : sides){\n                coop_attempts++;\n                if (try_coop(i, s)) { any=true; break; }\n                if (elapsed_sec() >= coop_budget_end) break;\n            }\n        }\n        if (!any) break;\n    }\n\n    // Final polish\n    while (elapsed_sec() < TIME_LIMIT) {\n        bool any=false;\n        for (int i=0;i<n && elapsed_sec() < TIME_LIMIT; ++i){\n            if (rect[i].area >= r[i]) continue;\n            int best_dir=-1; long double best_gain=0.0L;\n            for (int d=0; d<4; ++d){\n                if (!can_expand(i,d)) continue;\n                long long inc = (d<=1 ? rect[i].h() : rect[i].w());\n                if (rect[i].area + inc > r[i]) continue;\n                long double gain = score(rect[i].area + inc, r[i]) - score(rect[i].area, r[i]);\n                if (gain > best_gain + 1e-18) { best_gain=gain; best_dir=d; }\n            }\n            if (best_dir!=-1) { do_expand(i, best_dir); any=true; }\n        }\n        if (!any) break;\n    }\n\n    // Safety: ensure seed containment\n    for (int i=0;i<n;i++){\n        if (!contains_seed(i, rect[i])) {\n            // reset to 1x1\n            remove_rect(i);\n            rect[i] = {x[i], y[i], x[i]+1, y[i]+1, 0};\n            rect[i].recompute_area();\n            add_rect(i);\n        }\n    }\n\n    // Safety: resolve any overlaps by shrinking oversized rects\n    auto has_overlap_pair = [&](int &u, int &v)->bool{\n        for (int i=0;i<n;i++){\n            for (int j=i+1;j<n;j++){\n                if (overlap_pos(rect[i], rect[j])) { u=i; v=j; return true; }\n            }\n        }\n        return false;\n    };\n    int u,v;\n    int guard = 200000;\n    while (guard-- > 0 && has_overlap_pair(u,v)) {\n        // shrink the more oversized one, otherwise the larger area one\n        int t = u;\n        long long over_u = rect[u].area - r[u];\n        long long over_v = rect[v].area - r[v];\n        if (over_v > over_u) t = v;\n        else if (over_v == over_u && rect[v].area > rect[u].area) t = v;\n\n        // pick a side to shrink that reduces overlap and preserves seed\n        bool shrunk=false;\n        // try to shrink the side towards the other rectangle\n        if (!shrunk) {\n            // horizontal\n            if (rect[t].a < rect[(t==u)?v:u].c && rect[(t==u)?v:u].a < rect[t].c) {\n                // overlap horizontally; shrink left or right depending\n                if (rect[(t==u)?v:u].a <= rect[t].a) {\n                    if (can_shrink(t, 0)) { do_shrink(t,0); shrunk=true; }\n                }\n                if (!shrunk && rect[(t==u)?v:u].c >= rect[t].c) {\n                    if (can_shrink(t, 1)) { do_shrink(t,1); shrunk=true; }\n                }\n            }\n        }\n        if (!shrunk) {\n            // vertical shrink\n            if (rect[t].b < rect[(t==u)?v:u].d && rect[(t==u)?v:u].b < rect[t].d) {\n                if (rect[(t==u)?v:u].b <= rect[t].b) {\n                    if (can_shrink(t, 2)) { do_shrink(t,2); shrunk=true; }\n                }\n                if (!shrunk && rect[(t==u)?v:u].d >= rect[t].d) {\n                    if (can_shrink(t, 3)) { do_shrink(t,3); shrunk=true; }\n                }\n            }\n        }\n        if (!shrunk) {\n            // fallback: try any side that preserves seed\n            for (int s=0;s<4 && !shrunk; ++s) {\n                if (can_shrink(t,s)) { do_shrink(t,s); shrunk=true; }\n            }\n        }\n        if (!shrunk) {\n            // ultimate fallback: reset one rect to 1x1\n            remove_rect(t);\n            rect[t] = {x[t], y[t], x[t]+1, y[t]+1, 0};\n            rect[t].recompute_area();\n            add_rect(t);\n        }\n    }\n\n    // Output\n    for (int i=0;i<n;i++){\n        cout << rect[i].a << ' ' << rect[i].b << ' ' << rect[i].c << ' ' << rect[i].d << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic constexpr int H = 50, W = 50;\nstatic constexpr int di[4] = {-1,1,0,0};\nstatic constexpr int dj[4] = {0,0,-1,1};\nstatic constexpr char dc[4] = {'U','D','L','R'};\n\nstruct Solver {\n    int si, sj;\n    vector<vector<int>> t, p;\n    int M;\n    vector<vector<pair<int,int>>> tiles;\n    vector<vector<char>> preferred;\n    vector<vector<int>> sidx;\n\n    vector<char> visited_tile;\n    vector<vector<char>> visited_cell;\n\n    uint64_t seed;\n    inline uint64_t rng64() {\n        seed ^= seed << 7; seed ^= seed >> 9; seed ^= 0x9e3779b97f4a7c15ull;\n        return seed;\n    }\n\n    Solver(int si_, int sj_, const vector<vector<int>>& t_, const vector<vector<int>>& p_)\n        : si(si_), sj(sj_), t(t_), p(p_) {\n        M = 0;\n        for (int i=0;i<H;i++) for (int j=0;j<W;j++) M = max(M, t[i][j]+1);\n        tiles.assign(M, {});\n        for (int i=0;i<H;i++) for (int j=0;j<W;j++) tiles[t[i][j]].push_back({i,j});\n\n        preferred.assign(H, vector<char>(W, 0));\n        for (int id=0; id<M; id++){\n            auto &cells = tiles[id];\n            if (cells.empty()) continue;\n            int bestk = 0, bestv = -1;\n            for (int k=0;k<(int)cells.size();k++){\n                auto [i,j] = cells[k];\n                if (p[i][j] > bestv) { bestv = p[i][j]; bestk = k; }\n            }\n            for (int k=0;k<(int)cells.size();k++){\n                auto [i,j] = cells[k];\n                preferred[i][j] = (k==bestk);\n            }\n        }\n\n        sidx.assign(H, vector<int>(W, -1));\n        int idx=0;\n        for (int i=0;i<H;i++){\n            if (i%2==0){\n                for (int j=0;j<W;j++) sidx[i][j]=idx++;\n            }else{\n                for (int j=W-1;j>=0;j--) sidx[i][j]=idx++;\n            }\n        }\n    }\n\n    inline bool inb(int i,int j){ return 0<=i && i<H && 0<=j && j<W; }\n\n    vector<pair<int,int>> build_rail_targets() {\n        vector<pair<int,int>> order;\n        order.reserve(H*W);\n        for (int i=0;i<H;i++){\n            if (i%2==0) for (int j=0;j<W;j++) order.push_back({i,j});\n            else for (int j=W-1;j>=0;j--) order.push_back({i,j});\n        }\n        vector<pair<int,int>> targets;\n        targets.reserve(H*W);\n        vector<char> seenTile(M, 0);\n        for (auto [i,j]: order){\n            int id = t[i][j];\n            if (seenTile[id]) continue;\n            pair<int,int> rep = {i,j};\n            if (!preferred[i][j]) {\n                for (auto &c: tiles[id]) if (preferred[c.first][c.second]) { rep=c; break; }\n            }\n            seenTile[id]=1;\n            targets.push_back(rep);\n        }\n        return targets;\n    }\n\n    pair<vector<char>, bool> bfs_path(pair<int,int> start, pair<int,int> target) {\n        if (start == target) return {{}, true};\n        static char vis[H][W];\n        static int preDir[H][W];\n        static pair<int,int> prevCell[H][W];\n        memset(vis, 0, sizeof(vis));\n        deque<pair<int,int>> dq;\n        dq.emplace_back(start);\n        vis[start.first][start.second]=1;\n        bool found=false;\n        while(!dq.empty()){\n            auto [i,j]=dq.front(); dq.pop_front();\n            for (int k=0;k<4;k++){\n                int ni=i+di[k], nj=j+dj[k];\n                if (!inb(ni,nj)) continue;\n                int tid = t[ni][nj];\n                if (visited_tile[tid]) continue;\n                if (vis[ni][nj]) continue;\n                vis[ni][nj]=1;\n                preDir[ni][nj]=k;\n                prevCell[ni][nj]={i,j};\n                if (ni==target.first && nj==target.second){ found=true; dq.clear(); break; }\n                dq.emplace_back(ni,nj);\n            }\n        }\n        if (!found) return {{}, false};\n        vector<char> rev;\n        int ci=target.first, cj=target.second;\n        while(!(ci==start.first && cj==start.second)){\n            int k = preDir[ci][cj];\n            rev.push_back(dc[k]);\n            auto pr = prevCell[ci][cj];\n            ci=pr.first; cj=pr.second;\n        }\n        reverse(rev.begin(), rev.end());\n        return {rev, true};\n    }\n\n    int local_region_after(int i,int j, int rad=3){\n        int tid0 = t[i][j];\n        int rmin=max(0,i-rad), rmax=min(H-1,i+rad);\n        int cmin=max(0,j-rad), cmax=min(W-1,j+rad);\n        static char vis[H][W];\n        memset(vis, 0, sizeof(vis));\n        deque<pair<int,int>> dq;\n        vector<char> seen(M, 0);\n        int cnt=0;\n        for (int k=0;k<4;k++){\n            int ni=i+di[k], nj=j+dj[k];\n            if (!inb(ni,nj)) continue;\n            if (ni<rmin||ni>rmax||nj<cmin||nj>cmax) continue;\n            int tid=t[ni][nj];\n            if (tid==tid0) continue;\n            if (visited_tile[tid]) continue;\n            if (vis[ni][nj]) continue;\n            vis[ni][nj]=1; dq.emplace_back(ni,nj);\n        }\n        while(!dq.empty()){\n            auto [x,y]=dq.front(); dq.pop_front();\n            int tid=t[x][y];\n            if (!seen[tid]){ seen[tid]=1; cnt++; }\n            for (int k=0;k<4;k++){\n                int nx=x+di[k], ny=y+dj[k];\n                if (!inb(nx,ny)) continue;\n                if (nx<rmin||nx>rmax||ny<cmin||ny>cmax) continue;\n                int tnx=t[nx][ny];\n                if (tnx==tid0) continue;\n                if (visited_tile[tnx]) continue;\n                if (!vis[nx][ny]){ vis[nx][ny]=1; dq.emplace_back(nx,ny); }\n            }\n        }\n        return cnt;\n    }\n\n    int local_deg(int i,int j){\n        int d=0;\n        for (int k=0;k<4;k++){\n            int ni=i+di[k], nj=j+dj[k];\n            if (!inb(ni,nj)) continue;\n            if (!visited_tile[t[ni][nj]]) d++;\n        }\n        return d;\n    }\n\n    // Try detour: current target only, plus local region/degree constraints\n    int try_detour(pair<int,int> cur, pair<int,int> target, int topK, int regMin, int degMin) {\n        int i=cur.first, j=cur.second;\n        struct Cand { int k, ni, nj, val, deg; bool pref; };\n        vector<Cand> neigh;\n        for (int k=0;k<4;k++){\n            int ni=i+di[k], nj=j+dj[k];\n            if (!inb(ni,nj)) continue;\n            int tid=t[ni][nj];\n            if (visited_tile[tid]) continue;\n            int val=p[ni][nj];\n            int deg=local_deg(ni,nj);\n            neigh.push_back({k,ni,nj,val,deg,(bool)preferred[ni][nj]});\n        }\n        if (neigh.empty()) return -1;\n        sort(neigh.begin(), neigh.end(), [&](const Cand& a, const Cand& b){\n            if (a.val!=b.val) return a.val>b.val;\n            if (a.pref!=b.pref) return a.pref>b.pref;\n            return a.deg>b.deg;\n        });\n        int trials=min(topK,(int)neigh.size());\n        for (int idx=0; idx<trials; idx++){\n            auto c=neigh[idx];\n            if (c.deg < degMin) continue;\n            if (local_region_after(c.ni, c.nj, 3) < regMin) continue;\n            int tid=t[c.ni][c.nj];\n            visited_tile[tid]=1;\n            auto [mv, ok]=bfs_path({c.ni,c.nj}, target);\n            visited_tile[tid]=0;\n            if (ok) return c.k;\n        }\n        return -1;\n    }\n\n    void robust_greedy_finish(int &ci, int &cj, string &ans, long long &score) {\n        for (int step=0; step<H*W; step++){\n            struct C { int k, ni, nj, pv, deg, lkdeg; long long sc; bool pref; };\n            vector<C> cands;\n            for (int k=0;k<4;k++){\n                int ni=ci+di[k], nj=cj+dj[k];\n                if (!inb(ni,nj)) continue;\n                int tid=t[ni][nj];\n                if (visited_tile[tid]) continue;\n                int pv=p[ni][nj];\n                int deg=local_deg(ni,nj);\n                visited_tile[tid]=1;\n                int bestd2=-1;\n                for (int k2=0;k2<4;k2++){\n                    int xi=ni+di[k2], xj=nj+dj[k2];\n                    if (!inb(xi,xj)) continue;\n                    int tid2=t[xi][xj];\n                    if (visited_tile[tid2]) continue;\n                    int d2=0;\n                    for (int k3=0;k3<4;k3++){\n                        int yi=xi+di[k3], yj=xj+dj[k3];\n                        if (!inb(yi,yj)) continue;\n                        int tid3=t[yi][yj];\n                        if (tid3==tid) continue;\n                        if (visited_tile[tid3]) continue;\n                        d2++;\n                    }\n                    bestd2=max(bestd2,d2);\n                }\n                visited_tile[tid]=0;\n                long long sc = 90LL*pv + 10LL*deg + 12LL*max(bestd2,0) + (preferred[ni][nj]?8:0) + (rng64()&3);\n                cands.push_back({k,ni,nj,pv,deg,bestd2,sc,(bool)preferred[ni][nj]});\n            }\n            if (cands.empty()) break;\n            sort(cands.begin(), cands.end(), [&](const C&a,const C&b){\n                if (a.sc!=b.sc) return a.sc>b.sc;\n                if (a.deg!=b.deg) return a.deg>b.deg;\n                if (a.pv!=b.pv) return a.pv>b.pv;\n                return a.pref>b.pref;\n            });\n            auto best=cands[0];\n            ci=best.ni; cj=best.nj;\n            ans.push_back(dc[best.k]);\n            visited_tile[t[ci][cj]]=1;\n            visited_cell[ci][cj]=1;\n            score += p[ci][cj];\n        }\n    }\n\n    struct Preset {\n        int detourTopK;\n        int detourThresholdStart;\n        int detourThresholdEnd;\n        int regMinStart, regMinEnd;\n        int degMinStart, degMinEnd;\n        int targetSearchWindow; // how many next targets to consider\n        int maxRailStepDist;    // if path to target longer than this, skip target\n    };\n\n    pair<long long, string> run(const Preset& pr, uint64_t seed0, double time_limit_ms = 1.8e3) {\n        seed = seed0;\n        visited_tile.assign(M, 0);\n        visited_cell.assign(H, vector<char>(W, 0));\n        int ci=si, cj=sj;\n        visited_tile[t[ci][cj]]=1;\n        visited_cell[ci][cj]=1;\n        long long score = p[ci][cj];\n        string ans;\n\n        auto targets = build_rail_targets();\n        int ti = 0;\n        if (!targets.empty() && targets[0] == make_pair(si, sj)) ti = 1;\n\n        auto tstart = chrono::high_resolution_clock::now();\n\n        int stepsDone = 0;\n\n        while (ti < (int)targets.size()) {\n            // time guard\n            if (stepsDone % 200 == 0) {\n                auto now = chrono::high_resolution_clock::now();\n                double ms = chrono::duration<double, std::milli>(now - tstart).count();\n                if (ms > time_limit_ms) break;\n            }\n\n            if (visited_tile[t[targets[ti].first][targets[ti].second]]) { ti++; continue; }\n\n            // search next reachable target in small window\n            int chosen = -1;\n            vector<char> bestPathMoves;\n            int bestDist = INT_MAX;\n            int L = min((int)targets.size(), ti + pr.targetSearchWindow);\n            for (int tj=ti; tj<L; tj++){\n                if (visited_tile[t[targets[tj].first][targets[tj].second]]) continue;\n                auto [moves, ok] = bfs_path({ci,cj}, targets[tj]);\n                if (!ok) continue;\n                if ((int)moves.size() < bestDist) {\n                    bestDist = (int)moves.size();\n                    chosen = tj;\n                    bestPathMoves = moves;\n                    if (bestDist <= 4) break; // good enough\n                }\n            }\n            if (chosen == -1) break;\n            if (chosen != ti) ti = chosen;\n\n            // if too long path to target, skip it to keep momentum\n            if (bestDist > pr.maxRailStepDist) { ti++; continue; }\n\n            size_t pos = 0;\n            while (pos < bestPathMoves.size()) {\n                // dynamic detour thresholds\n                int detThreshold = pr.detourThresholdStart + (pr.detourThresholdEnd - pr.detourThresholdStart) * stepsDone / (H*W);\n                int regMin = pr.regMinStart + (pr.regMinEnd - pr.regMinStart) * stepsDone / (H*W);\n                int degMin = pr.degMinStart + (pr.degMinEnd - pr.degMinStart) * stepsDone / (H*W);\n\n                // detour consideration\n                int maxNei = -1;\n                for (int k=0;k<4;k++){\n                    int ni=ci+di[k], nj=cj+dj[k];\n                    if (!inb(ni,nj)) continue;\n                    if (visited_tile[t[ni][nj]]) continue;\n                    maxNei = max(maxNei, p[ni][nj]);\n                }\n                if (maxNei >= detThreshold) {\n                    int dd = try_detour({ci,cj}, targets[ti], pr.detourTopK, regMin, degMin);\n                    if (dd != -1) {\n                        ci += di[dd]; cj += dj[dd];\n                        ans.push_back(dc[dd]);\n                        visited_tile[t[ci][cj]] = 1;\n                        visited_cell[ci][cj] = 1;\n                        score += p[ci][cj];\n                        stepsDone++;\n                        auto [moves2, ok] = bfs_path({ci,cj}, targets[ti]);\n                        if (!ok) break;\n                        bestPathMoves = moves2;\n                        pos = 0;\n                        continue;\n                    }\n                }\n\n                // execute rail step\n                char mv = bestPathMoves[pos++];\n                int dir=-1;\n                for (int k=0;k<4;k++) if (dc[k]==mv) { dir = k; break; }\n                int ni=ci+di[dir], nj=cj+dj[dir];\n                if (!inb(ni,nj) || visited_tile[t[ni][nj]]) {\n                    auto [moves2, ok] = bfs_path({ci,cj}, targets[ti]);\n                    if (!ok) break;\n                    bestPathMoves = moves2;\n                    pos = 0;\n                    continue;\n                }\n                ci=ni; cj=nj;\n                ans.push_back(mv);\n                visited_tile[t[ci][cj]] = 1;\n                visited_cell[ci][cj] = 1;\n                score += p[ci][cj];\n                stepsDone++;\n            }\n            ti++;\n        }\n\n        robust_greedy_finish(ci, cj, ans, score);\n\n        return {score, ans};\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj;\n    if (!(cin>>si>>sj)) return 0;\n    vector<vector<int>> t(H, vector<int>(W));\n    vector<vector<int>> p(H, vector<int>(W));\n    for (int i=0;i<H;i++) for (int j=0;j<W;j++) cin>>t[i][j];\n    for (int i=0;i<H;i++) for (int j=0;j<W;j++) cin>>p[i][j];\n\n    Solver solver(si, sj, t, p);\n    uint64_t seedBase = 1469598103934665603ull ^ (uint64_t)(si*131 + sj*911);\n\n    // Presets tuned to be robust and not too strict\n    vector<Solver::Preset> presets = {\n        // detK, thrStart, thrEnd, regStart, regEnd, degStart, degEnd, targetWindow, maxRailDist\n        {2, 85, 70, 4, 2, 2, 1, 10, 120}, // balanced\n        {1, 92, 78, 5, 3, 3, 2, 12, 100}, // conservative early\n        {2, 78, 65, 3, 2, 1, 1, 8, 140},  // aggressive detours\n        {1, 95, 85, 6, 4, 3, 2, 14, 90},  // very conservative\n    };\n\n    long long bestScore = -1;\n    string bestAns;\n    for (int r=0; r<(int)presets.size(); r++){\n        auto [sc, ans] = solver.run(presets[r], seedBase ^ (0x9e3779b97f4a7c15ull * (r+1)));\n        if (sc > bestScore) { bestScore = sc; bestAns = move(ans); }\n    }\n\n    cout << bestAns << \"\\n\";\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct GridRouter {\n    static constexpr int HN = 30;\n    static constexpr int WN = 30;\n    static constexpr int HHE = HN * (WN - 1); // horizontal edges count 30*29=870\n    static constexpr int HVE = (HN - 1) * WN; // vertical edges count 29*30=870\n    static constexpr int E = HHE + HVE;       // 1740\n\n    vector<double> w; // per-edge weights\n    vector<pair<int,int>> adjIdx[HN][WN]; // (neighbor node index, edge id)\n    mt19937_64 rng;\n\n    GridRouter() : w(E, 5000.0) {\n        rng.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());\n        buildGraph();\n    }\n\n    static int idH(int i, int j) { return i * (WN - 1) + j; }\n    static int idV(int i, int j) { return HHE + i * WN + j; }\n    int nodeId(int i, int j) const { return i * WN + j; }\n    pair<int,int> nodePos(int id) const { return {id / WN, id % WN}; }\n\n    void buildGraph() {\n        for (int i = 0; i < HN; ++i) for (int j = 0; j < WN; ++j) adjIdx[i][j].clear();\n        for (int i = 0; i < HN; ++i) {\n            for (int j = 0; j < WN - 1; ++j) {\n                int e = idH(i,j);\n                int u = nodeId(i,j), v = nodeId(i,j+1);\n                adjIdx[i][j].push_back({v, e});\n                adjIdx[i][j+1].push_back({u, e});\n            }\n        }\n        for (int i = 0; i < HN - 1; ++i) {\n            for (int j = 0; j < WN; ++j) {\n                int e = idV(i,j);\n                int u = nodeId(i,j), v = nodeId(i+1,j);\n                adjIdx[i][j].push_back({v, e});\n                adjIdx[i+1][j].push_back({u, e});\n            }\n        }\n    }\n\n    struct DRes {\n        vector<int> prevNode;\n        vector<int> prevEdge;\n        vector<int> pathEdges;\n        string pathMoves;\n        double pathCost;\n    };\n\n    // Dijkstra with optional per-edge randomization for exploration\n    DRes shortestPath(pair<int,int> s, pair<int,int> t, double randEps, uint64_t randSeed) {\n        int N = HN * WN;\n        vector<double> dist(N, numeric_limits<double>::infinity());\n        vector<int> prevN(N, -1), prevE(N, -1);\n        int sId = nodeId(s.first, s.second);\n        int tId = nodeId(t.first, t.second);\n\n        vector<float> mult;\n        if (randEps > 0) {\n            mult.assign(E, 1.0f);\n            uint64_t x = randSeed ? randSeed : rng();\n            auto nextRand = [&]() {\n                x ^= x << 13; x ^= x >> 7; x ^= x << 17;\n                return x;\n            };\n            for (int e = 0; e < E; ++e) {\n                uint64_t r = nextRand();\n                double u = ((r >> 11) & 0xFFFFFFFFull) / double(0xFFFFFFFFull);\n                double z = 2.0*u - 1.0;\n                mult[e] = float(1.0 + randEps * z);\n            }\n        }\n\n        using P = pair<double,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[sId] = 0.0;\n        pq.emplace(0.0, sId);\n\n        while (!pq.empty()) {\n            auto [d,u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == tId) break;\n            auto [ui, uj] = nodePos(u);\n            for (auto [v, e] : adjIdx[ui][uj]) {\n                double ew = w[e];\n                if (!mult.empty()) ew *= mult[e];\n                ew = max(100.0, min(20000.0, ew));\n                double nd = d + ew;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prevN[v] = u;\n                    prevE[v] = e;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n\n        DRes res;\n        res.prevNode = move(prevN);\n        res.prevEdge = move(prevE);\n        res.pathCost = dist[tId];\n\n        vector<int> edges;\n        string moves;\n        int cur = tId;\n        while (cur != sId && res.prevEdge[cur] != -1) {\n            int e = res.prevEdge[cur];\n            edges.push_back(e);\n            auto [pi, pj] = nodePos(res.prevNode[cur]);\n            auto [ci, cj] = nodePos(cur);\n            if (ci == pi) {\n                moves.push_back(cj == pj + 1 ? 'R' : 'L');\n            } else {\n                moves.push_back(ci == pi + 1 ? 'D' : 'U');\n            }\n            cur = res.prevNode[cur];\n        }\n        reverse(edges.begin(), edges.end());\n        reverse(moves.begin(), moves.end());\n        res.pathEdges = move(edges);\n        res.pathMoves = move(moves);\n        return res;\n    }\n\n    double predictSum(const vector<int>& pathEdges) const {\n        double s = 0.0;\n        for (int e : pathEdges) s += w[e];\n        return s;\n    }\n\n    void updateWeights(const vector<int>& pathEdges, long long observed, int qIndex) {\n        if (pathEdges.empty()) return;\n        double pred = 0.0;\n        for (int e : pathEdges) pred += w[e];\n        if (pred <= 1e-9) return;\n\n        double y = (double)observed;\n        double s = y / pred;\n        // Clip scaling to handle noise\n        s = max(0.88, min(1.12, s));\n\n        // Learning rate: slightly higher early and higher floor to adapt throughout\n        double progress = (double)qIndex / 999.0;\n        double eta0 = 0.36;\n        double eta1 = 0.08;\n        double eta = eta0 * (1.0 - progress) + eta1 * progress;\n\n        double factor = 1.0 + eta * (s - 1.0);\n        factor = max(0.95, min(1.05, factor));\n\n        for (int e : pathEdges) {\n            w[e] *= factor;\n        }\n\n        // Tiny L2 pull toward global mean to avoid drift on rarely used edges (only for used edges' neighbors)\n        double meanW = 0.0;\n        // Estimate mean using a small sample of edges to keep cost low\n        for (int i = 0; i < 100; ++i) {\n            int idx = (i * 17) % E;\n            meanW += w[idx];\n        }\n        meanW /= 100.0;\n\n        // Adaptive smoothing to neighbors\n        double plen = (double)pathEdges.size();\n        double baseBeta = 0.015 * (1.0 - progress) + 0.009 * progress;\n        double beta = baseBeta * min(2.0, 0.5 + plen / 50.0);\n\n        for (int e : pathEdges) {\n            if (e < HHE) {\n                int i = e / (WN - 1);\n                int j = e % (WN - 1);\n                if (j - 1 >= 0) {\n                    int ne = idH(i, j - 1);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n                if (j + 1 < WN - 1) {\n                    int ne = idH(i, j + 1);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n            } else {\n                int ve = e - HHE;\n                int i = ve / WN;\n                int j = ve % WN;\n                if (i - 1 >= 0) {\n                    int ne = idV(i - 1, j);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n                if (i + 1 < HN - 1) {\n                    int ne = idV(i + 1, j);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n            }\n        }\n\n        // Light regularization for used edges towards mean\n        double reg = 0.002; // very small\n        for (int e : pathEdges) {\n            w[e] += reg * (meanW - w[e]);\n        }\n\n        // Clip updated edges\n        for (int e : pathEdges) {\n            if (w[e] < 500.0) w[e] = 500.0;\n            if (w[e] > 15000.0) w[e] = 15000.0;\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    GridRouter gr;\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        // Small exploration for first 300 queries\n        double eps = 0.0;\n        if (q < 300) {\n            double t = (double)q / 300.0;\n            eps = 0.03 * (1.0 - t);\n        }\n\n        // Two candidate runs with different seeds early, otherwise single deterministic run\n        uint64_t seed1 = ((uint64_t)si<<48) ^ ((uint64_t)sj<<32) ^ ((uint64_t)ti<<16) ^ (uint64_t)tj ^ (uint64_t)(q*11400714819323198485ull);\n        uint64_t seed2 = seed1 ^ 0x9e3779b97f4a7c15ull;\n\n        GridRouter::DRes r1, r2;\n        if (eps > 0.0) {\n            r1 = gr.shortestPath({si,sj},{ti,tj}, eps, seed1);\n            r2 = gr.shortestPath({si,sj},{ti,tj}, eps, seed2);\n        } else {\n            r1 = gr.shortestPath({si,sj},{ti,tj}, 0.0, 0);\n        }\n\n        GridRouter::DRes res;\n        if (eps > 0.0) {\n            double p1 = gr.predictSum(r1.pathEdges);\n            double p2 = gr.predictSum(r2.pathEdges);\n            if (!r2.pathEdges.empty() && p2 + 1e-6 < p1 - 1e-6) {\n                res = move(r2);\n            } else if (!r1.pathEdges.empty() && !r2.pathEdges.empty()) {\n                double ratio = (p1 > p2) ? (p1 / max(1e-6, p2)) : (p2 / max(1e-6, p1));\n                if (ratio < 1.015) {\n                    // diversify when extremely close\n                    res = ((seed1 & 1ull) ? move(r1) : move(r2));\n                } else {\n                    res = (p1 <= p2 ? move(r1) : move(r2));\n                }\n            } else {\n                res = move(r1.pathEdges.empty() ? r2 : r1);\n            }\n        } else {\n            res = move(r1);\n        }\n\n        string path = res.pathMoves;\n        if (path.empty()) {\n            int di = ti - si;\n            int dj = tj - sj;\n            if (di > 0) path.append(di, 'D'); else path.append(-di, 'U');\n            if (dj > 0) path.append(dj, 'R'); else path.append(-dj, 'L');\n        }\n\n        cout << path << \"\\n\";\n        cout.flush();\n\n        long long observed;\n        if (!(cin >> observed)) return 0;\n\n        gr.updateWeights(res.pathEdges, observed, q);\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic inline int ch2i(char c){ return c - 'A'; }\nstatic inline char i2ch(int x){ return char('A' + x); }\n\nstruct Placement {\n    uint8_t dir; // 0=hor,1=ver\n    uint8_t fixed; // row for hor, col for ver\n    uint8_t start; // start index\n};\nstruct PlCover {\n    vector<uint16_t> idxs; // linear indices\n};\n\nstruct Occ { // occurrence of a placement cell in global grid\n    int si;   // string index\n    int pi;   // placement index\n    int pos;  // position within the string\n};\n\nstruct RNG {\n    uint64_t x;\n    RNG(uint64_t seed=88172645463393265ull){ x=seed; }\n    inline uint64_t rng() { x ^= x<<7; x ^= x>>9; return x; }\n    inline int randint(int l, int r){ return int(l + rng() % (uint64_t)(r - l + 1)); }\n    inline double rand01(){ return (rng() >> 11) * (1.0/9007199254740992.0); }\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    vector<string> s(M);\n    for(int i=0;i<M;i++) cin >> s[i];\n\n    // Encode and stats\n    vector<vector<uint8_t>> enc(M);\n    vector<int> slen(M);\n    array<int,8> globalCnt{}; globalCnt.fill(0);\n    for(int i=0;i<M;i++){\n        int k = (int)s[i].size();\n        slen[i]=k;\n        enc[i].resize(k);\n        for(int p=0;p<k;p++){\n            int v = ch2i(s[i][p]);\n            enc[i][p] = (uint8_t)v;\n            globalCnt[v]++;\n        }\n    }\n    int totalChars=0; for(int v:globalCnt) totalChars+=v;\n    array<double,8> invFreq;\n    for(int c=0;c<8;c++) invFreq[c] = globalCnt[c] ? (double)totalChars / (double)globalCnt[c] : 2.0*totalChars;\n    vector<double> sWeight(M,0.0);\n    for(int i=0;i<M;i++){\n        double r=0.0;\n        for(uint8_t v: enc[i]) r += invFreq[v];\n        sWeight[i] = 0.03 * (r / max(1,slen[i]));\n    }\n\n    // Precompute placements and covers\n    vector<vector<Placement>> placements(M);\n    vector<vector<PlCover>> covers(M);\n    for(int i=0;i<M;i++){\n        vector<Placement> ps;\n        ps.reserve(2*N*N);\n        for(int r=0;r<N;r++) for(int c0=0;c0<N;c0++) ps.push_back(Placement{0,(uint8_t)r,(uint8_t)c0});\n        for(int c=0;c<N;c++) for(int r0=0;r0<N;r0++) ps.push_back(Placement{1,(uint8_t)c,(uint8_t)r0});\n        placements[i] = move(ps);\n        vector<PlCover> cv(placements[i].size());\n        for(size_t pi=0; pi<placements[i].size(); ++pi){\n            const auto& pl = placements[i][pi];\n            int k = slen[i];\n            cv[pi].idxs.resize(k);\n            if(pl.dir==0){\n                int r=pl.fixed, c0=pl.start, base=r*N;\n                for(int p=0;p<k;p++){ int c=(c0+p)%N; cv[pi].idxs[p]=(uint16_t)(base+c); }\n            }else{\n                int c=pl.fixed, r0=pl.start;\n                for(int p=0;p<k;p++){ int r=(r0+p)%N; cv[pi].idxs[p]=(uint16_t)(r*N + c); }\n            }\n        }\n        covers[i] = move(cv);\n    }\n\n    // Inverted index: for each cell, which (string, placement, pos) cover it\n    int G = N*N;\n    vector<vector<Occ>> occ(G);\n    for(int i=0;i<M;i++){\n        int k = slen[i];\n        int P = (int)covers[i].size();\n        for(int pi=0; pi<P; ++pi){\n            const auto& cv = covers[i][pi];\n            for(int p=0;p<k;p++){\n                occ[ cv.idxs[p] ].push_back(Occ{i,pi,p});\n            }\n        }\n    }\n\n    auto solve_once = [&](RNG& rng, double time_ms){\n        const int UNKNOWN = -1;\n        vector<int8_t> grid(G, UNKNOWN);\n\n        // Alive placements tracking\n        vector<vector<char>> alive(M); // per string per placement alive?\n        vector<int> aliveCnt(M, 0);\n        for(int i=0;i<M;i++){\n            int P = (int)covers[i].size();\n            alive[i].assign(P, 1);\n            aliveCnt[i] = P;\n        }\n        vector<char> satisfied(M, 0);\n\n        // function to invalidate a placement\n        auto kill = [&](int i, int pi){\n            if(alive[i][pi]){\n                alive[i][pi] = 0;\n                aliveCnt[i]--;\n            }\n        };\n\n        // Upon fixing a cell, update alive placements that conflict\n        auto on_fix_cell = [&](int idx){\n            int8_t val = grid[idx];\n            for(const auto& oc : occ[idx]){\n                if(!alive[oc.si][oc.pi]) continue;\n                if(enc[oc.si][oc.pos] != val){\n                    kill(oc.si, oc.pi);\n                }\n            }\n        };\n\n        // Check zero-gain placement exists for string i (with current grid), and optionally mark satisfied\n        auto check_zero_gain_and_mark = [&](int i)->bool{\n            if(satisfied[i]) return true;\n            if(aliveCnt[i] == 0) return false;\n            const auto& e = enc[i];\n            int P = (int)covers[i].size();\n            for(int pi=0; pi<P; ++pi){\n                if(!alive[i][pi]) continue;\n                const auto& cv = covers[i][pi];\n                bool ok = true;\n                for(int p=0;p<slen[i];++p){\n                    int idx = cv.idxs[p];\n                    if(grid[idx] == UNKNOWN || grid[idx] != (int)e[p]){ ok=false; break; }\n                }\n                if(ok){ satisfied[i]=1; return true; }\n            }\n            return false;\n        };\n\n        // Try to evaluate a placement (by index): returns {gain, agreements} or {-1,0} if invalid\n        auto eval_placement = [&](int i, int pi)->pair<int,int>{\n            if(!alive[i][pi]) return {-1,0};\n            const auto& e = enc[i];\n            const auto& cv = covers[i][pi];\n            int g=0, a=0;\n            for(int p=0;p<slen[i];++p){\n                int idx = cv.idxs[p];\n                int8_t v = grid[idx];\n                if(v==UNKNOWN) g++;\n                else if(v == (int)e[p]) a++;\n                else return make_pair(-1,0);\n            }\n            return make_pair(g,a);\n        };\n        auto apply_placement = [&](int i, int pi){\n            const auto& e = enc[i];\n            const auto& cv = covers[i][pi];\n            bool changed=false;\n            for(int p=0;p<slen[i];++p){\n                int idx = cv.idxs[p];\n                if(grid[idx] == UNKNOWN){\n                    grid[idx] = (int8_t)e[p];\n                    changed=true;\n                    on_fix_cell(idx);\n                }\n            }\n            satisfied[i]=1;\n            return changed;\n        };\n\n        // Preorder strings: prefer long, then rarity\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        stable_sort(order.begin(), order.end(), [&](int a, int b){\n            if(slen[a] != slen[b]) return slen[a] > slen[b];\n            return sWeight[a] > sWeight[b];\n        });\n\n        // Time control\n        auto t0 = chrono::high_resolution_clock::now();\n\n        // Unit propagation queue: strings with aliveCnt==1\n        deque<int> q;\n        vector<char> inq(M, 0);\n        for(int i=0;i<M;i++) if(aliveCnt[i]==1) { q.push_back(i); inq[i]=1; }\n\n        auto process_forced = [&](){\n            bool progress=false;\n            while(!q.empty()){\n                int i = q.front(); q.pop_front(); inq[i]=0;\n                if(satisfied[i]) continue;\n                if(aliveCnt[i] != 1) continue;\n                // find the only alive placement\n                int onlyPi=-1;\n                int P = (int)alive[i].size();\n                for(int pi=0; pi<P; ++pi) if(alive[i][pi]){ onlyPi=pi; break; }\n                if(onlyPi==-1) continue;\n                auto ga = eval_placement(i, onlyPi);\n                if(ga.first < 0) continue; // became invalid\n                if(ga.first==0){\n                    satisfied[i]=1;\n                    continue;\n                }\n                bool changed = apply_placement(i, onlyPi);\n                progress = progress || changed;\n                // after fixing cells, some placements elsewhere die; if some strings now have aliveCnt==1, push\n                for(int p=0; p<slen[i]; ++p){\n                    int idx = covers[i][onlyPi].idxs[p];\n                    for(const auto& oc: occ[idx]){\n                        int j = oc.si;\n                        if(!inq[j] && !satisfied[j] && aliveCnt[j]==1) { q.push_back(j); inq[j]=1; }\n                    }\n                }\n            }\n            return progress;\n        };\n\n        // Initial trivial zero-gain marking\n        for(int i=0;i<M;i++) check_zero_gain_and_mark(i);\n        process_forced();\n\n        // Main loop: pick one best candidate each iteration\n        while(true){\n            auto now = chrono::high_resolution_clock::now();\n            if(chrono::duration<double, std::milli>(now - t0).count() > time_ms) break;\n\n            // collect candidates\n            struct Cand { int si, pi, gain, agree; double score; };\n            vector<Cand> cands;\n            cands.reserve(48);\n\n            // small random swaps in order\n            if(rng.rand01() < 0.12){\n                int a = rng.randint(0,M-1), b=rng.randint(0,M-1);\n                if(a!=b) swap(order[a], order[b]);\n            }\n\n            for(int oi=0; oi<M; ++oi){\n                int i = order[oi];\n                if(satisfied[i]) continue;\n                if(aliveCnt[i]==0) continue;\n\n                // quick zero-gain marking\n                if(check_zero_gain_and_mark(i)) continue;\n\n                int P = (int)covers[i].size();\n                // sample for short ones\n                int k = slen[i];\n                int target = (k<=4 ? 200 : P);\n                int step = max(1, P / max(1,target));\n                int bestPi=-1, bestG=-1, bestA=-1;\n                for(int pi=0; pi<P; pi+=step){\n                    if(!alive[i][pi]) continue;\n                    auto ga = eval_placement(i, pi);\n                    int g = ga.first;\n                    if(g <= 0) continue; // skip zero-gain here; already handled\n                    int a = ga.second;\n                    if(g > bestG || (g==bestG && a > bestA)){\n                        bestG=g; bestA=a; bestPi=pi;\n                    }\n                }\n                if(bestPi != -1){\n                    // heuristic bonus: how many alive placements cover the cells we would fix\n                    int bonus = 0;\n                    const auto& cv = covers[i][bestPi];\n                    for(int p=0;p<k;p++){\n                        int idx = cv.idxs[p];\n                        if(grid[idx] == -1){\n                            int cnt=0, cap=16;\n                            for(const auto& oc: occ[idx]){\n                                if(cnt>=cap) break;\n                                if(!satisfied[oc.si] && alive[oc.si][oc.pi]) cnt++;\n                            }\n                            bonus += min(cnt, cap);\n                        }\n                    }\n                    double score = bestG + 0.02*bestA + 0.002*bonus + 0.005*sWeight[i] + 0.001*k;\n                    cands.push_back(Cand{i,bestPi,bestG,bestA,score});\n                    if((int)cands.size() > 64){\n                        nth_element(cands.begin(), cands.begin()+48, cands.end(),\n                            [](const Cand& A, const Cand& B){ return A.score > B.score; });\n                        cands.resize(48);\n                    }\n                }\n            }\n\n            if(cands.empty()){\n                if(!process_forced()) break;\n                else continue;\n            }\n            sort(cands.begin(), cands.end(), [](const Cand& A, const Cand& B){\n                if(A.score != B.score) return A.score > B.score;\n                if(A.gain != B.gain) return A.gain > B.gain;\n                return A.agree > B.agree;\n            });\n            int pick = 0;\n            int topk = min(6, (int)cands.size());\n            if(topk>1 && rng.rand01() < 0.25) pick = rng.randint(0, topk-1);\n\n            int si = cands[pick].si;\n            int pi = cands[pick].pi;\n\n            auto ga2 = eval_placement(si, pi);\n            if(ga2.first > 0){\n                apply_placement(si, pi);\n                // after application, update forced queue for affected cells\n                const auto& cv = covers[si][pi];\n                for(int p=0;p<slen[si];++p){\n                    int idx = cv.idxs[p];\n                    for(const auto& oc: occ[idx]){\n                        int j = oc.si;\n                        if(!satisfied[j] && aliveCnt[j]==1 && !inq[j]){ q.push_back(j); inq[j]=1; }\n                    }\n                }\n                process_forced();\n            }else if(ga2.first == 0){\n                satisfied[si] = 1;\n            }else{\n                // invalidated; loop continues\n            }\n        }\n\n        // Final zero-gain check on fixed grid\n        for(int i=0;i<M;i++){\n            if(satisfied[i]) continue;\n            const auto& e = enc[i];\n            int P = (int)covers[i].size();\n            for(int pi=0; pi<P; ++pi){\n                if(!alive[i][pi]) continue;\n                const auto& cv = covers[i][pi];\n                bool ok=true;\n                for(int p=0;p<slen[i];++p){\n                    if(grid[ cv.idxs[p] ] != (int)e[p]){ ok=false; break; }\n                }\n                if(ok){ satisfied[i]=1; break; }\n            }\n        }\n\n        // Fill unknowns using votes from alive placements only\n        vector<array<int,8>> votes(G);\n        for(int idx=0; idx<G; ++idx) votes[idx].fill(0);\n        for(int i=0;i<M;i++){\n            const auto& e = enc[i];\n            int P = (int)covers[i].size();\n            for(int pi=0; pi<P; ++pi){\n                if(!alive[i][pi]) continue;\n                const auto& cv = covers[i][pi];\n                bool ok=true;\n                for(int p=0;p<slen[i];++p){\n                    int idx = cv.idxs[p];\n                    int8_t v = grid[idx];\n                    if(v != -1 && v != (int)e[p]){ ok=false; break; }\n                }\n                if(!ok) continue;\n                for(int p=0;p<slen[i];++p){\n                    int idx = cv.idxs[p];\n                    if(grid[idx]==-1) votes[idx][ e[p] ]++;\n                }\n            }\n        }\n        int fillGlobal = int(max_element(globalCnt.begin(), globalCnt.end()) - globalCnt.begin());\n        for(int idx=0; idx<G; ++idx){\n            if(grid[idx]==-1){\n                int bestL=fillGlobal, bestV=-1;\n                for(int c=0;c<8;c++){\n                    if(votes[idx][c] > bestV){ bestV=votes[idx][c]; bestL=c; }\n                }\n                grid[idx] = (int8_t)bestL;\n            }\n        }\n\n        // Final count\n        int satisfiedCount=0;\n        for(int i=0;i<M;i++){\n            const auto& e = enc[i];\n            int P = (int)covers[i].size();\n            bool ok=false;\n            for(int pi=0; pi<P; ++pi){\n                const auto& cv = covers[i][pi];\n                bool match=true;\n                for(int p=0;p<slen[i];++p){\n                    if(grid[ cv.idxs[p] ] != (int)e[p]){ match=false; break; }\n                }\n                if(match){ ok=true; break; }\n            }\n            if(ok) satisfiedCount++;\n        }\n\n        return pair<vector<int8_t>, int>(move(grid), satisfiedCount);\n    };\n\n    RNG rng((uint64_t)chrono::high_resolution_clock::now().time_since_epoch().count());\n    auto start = chrono::high_resolution_clock::now();\n    double total_budget_ms = 2700.0;\n\n    vector<int8_t> bestGrid;\n    int bestC = -1;\n    int restarts = 0;\n    while(true){\n        auto now = chrono::high_resolution_clock::now();\n        double used = chrono::duration<double, std::milli>(now - start).count();\n        if(used > total_budget_ms) break;\n        double remain = total_budget_ms - used;\n        double per = max(320.0, remain / 2.2);\n        auto res = solve_once(rng, per);\n        if(res.second > bestC){\n            bestC = res.second;\n            bestGrid = move(res.first);\n        }\n        restarts++;\n        if(restarts >= 5) break;\n    }\n    if(bestGrid.empty()) bestGrid.assign(N*N, 0);\n\n    // Output\n    for(int r=0;r<N;r++){\n        string line(N, 'A');\n        for(int c=0;c<N;c++){\n            line[c] = i2ch(bestGrid[r*N + c]);\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() { st = chrono::steady_clock::now(); }\n    double elapsed() const {\n        using namespace chrono;\n        return duration<double>(steady_clock::now() - st).count();\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    auto inb = [&](int i, int j){ return 0<=i && i<N && 0<=j && j<N; };\n    auto isRoad = [&](int i, int j){ return inb(i,j) && g[i][j] != '#'; };\n\n    // Compress road cells\n    int R = 0;\n    vector<int> id(N*N, -1);\n    vector<pair<int,int>> pos; pos.reserve(N*N);\n    for (int i=0;i<N;++i) for (int j=0;j<N;++j) if (isRoad(i,j)) {\n        id[i*N+j] = R++;\n        pos.emplace_back(i,j);\n    }\n    int startId = id[si*N+sj];\n    if (startId < 0) { cout << \"\\n\"; return 0; }\n\n    // Neighbors and weights\n    vector<array<int,4>> neigh(R);\n    vector<array<int,4>> moveCost(R);\n    for (int r=0;r<R;++r){\n        auto [i,j] = pos[r];\n        int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};\n        for (int d=0; d<4; ++d) {\n            int ni=i+dirs[d][0], nj=j+dirs[d][1];\n            if (isRoad(ni,nj)) {\n                int nid = id[ni*N+nj];\n                neigh[r][d] = nid;\n                moveCost[r][d] = g[ni][nj]-'0';\n            } else {\n                neigh[r][d] = -1;\n                moveCost[r][d] = 0;\n            }\n        }\n    }\n\n    // Bitset utils\n    int W = (R + 63) >> 6;\n    using BVec = vector<uint64_t>;\n    auto popcount_bits = [&](const BVec& a)->int{\n        int s=0; for (int k=0;k<W;++k) s += (int)__builtin_popcountll(a[k]); return s;\n    };\n    auto marginal_gain = [&](const BVec& v, const BVec& rem)->int{\n        int s=0; for (int k=0;k<W;++k) s += (int)__builtin_popcountll(v[k] & rem[k]); return s;\n    };\n\n    // Precompute visibility per cell; row/col runs and ids\n    vector<BVec> vis(R, BVec(W, 0));\n    vector<vector<int>> rowRuns; rowRuns.reserve(N*2);\n    vector<int> rowRunId(R, -1), colRunId(R, -1);\n    int rowRunCnt = 0, colRunCnt = 0;\n    for (int i=0;i<N;++i) {\n        int j=0;\n        while (j<N) {\n            while (j<N && !isRoad(i,j)) ++j;\n            if (j>=N) break;\n            int k=j;\n            vector<int> run;\n            while (k<N && isRoad(i,k)) { run.push_back(id[i*N+k]); ++k; }\n            for (int idx : run) {\n                rowRunId[idx] = rowRunCnt;\n                auto &b = vis[idx];\n                for (int rid : run) b[rid>>6] |= (1ULL << (rid&63));\n            }\n            rowRuns.push_back(run);\n            rowRunCnt++;\n            j = k;\n        }\n    }\n    vector<vector<int>> colRuns; colRuns.reserve(N*2);\n    for (int j=0;j<N;++j) {\n        int i=0;\n        while (i<N) {\n            while (i<N && !isRoad(i,j)) ++i;\n            if (i>=N) break;\n            int k=i;\n            vector<int> run;\n            while (k<N && isRoad(k,j)) { run.push_back(id[k*N+j]); ++k; }\n            for (int idx : run) {\n                colRunId[idx] = colRunCnt;\n                auto &b = vis[idx];\n                for (int rid : run) b[rid>>6] |= (1ULL << (rid&63));\n            }\n            colRuns.push_back(run);\n            colRunCnt++;\n            i = k;\n        }\n    }\n\n    // Degree for POIs\n    vector<int> deg(R,0);\n    for (int r=0;r<R;++r) for (int d=0; d<4; ++d) if (neigh[r][d] >= 0) deg[r]++;\n\n    // Candidate vantage points: junctions/endpoints + reps per run\n    vector<int> cand;\n    cand.reserve(R/2);\n    for (int r=0;r<R;++r) if (deg[r] != 2) cand.push_back(r);\n    if (find(cand.begin(), cand.end(), startId) == cand.end()) cand.push_back(startId);\n    auto add_reps = [&](const vector<vector<int>>& runs){\n        const int K = 2;\n        for (const auto& run : runs) {\n            int m = (int)run.size();\n            if (m == 0) continue;\n            if (m <= 3) {\n                cand.insert(cand.end(), run.begin(), run.end());\n            } else {\n                for (int k=0; k<K; ++k) {\n                    int idx = (int)llround((double)(k+1) * (m+1) / (K+1)) - 1;\n                    idx = max(0, min(m-1, idx));\n                    cand.push_back(run[idx]);\n                }\n            }\n        }\n    };\n    add_reps(rowRuns);\n    add_reps(colRuns);\n    sort(cand.begin(), cand.end());\n    cand.erase(unique(cand.begin(), cand.end()), cand.end());\n\n    // Potential cost per node (normalized)\n    vector<double> pot(R, 0.0);\n    for (int r=0;r<R;++r){\n        int cnt=0, sum=0;\n        for (int d=0; d<4; ++d) if (neigh[r][d] >= 0) { sum += moveCost[r][d]; cnt++; }\n        if (cnt>0) pot[r] = (double)sum / cnt;\n        else {\n            auto [i,j] = pos[r];\n            pot[r] = g[i][j]-'0';\n        }\n    }\n    double minP=*min_element(pot.begin(), pot.end());\n    double maxP=*max_element(pot.begin(), pot.end());\n    double spanP = max(1e-9, maxP - minP);\n    for (int r=0;r<R;++r) pot[r] = (pot[r] - minP) / spanP;\n\n    // Centrality\n    double ci = (N-1)/2.0, cj = (N-1)/2.0;\n    vector<double> centrality(R);\n    double maxC = 0.0;\n    for (int r=0;r<R;++r){\n        auto [i,j] = pos[r];\n        double c = fabs(i - ci) + fabs(j - cj);\n        centrality[r] = c;\n        maxC = max(maxC, c);\n    }\n    for (int r=0;r<R;++r) centrality[r] = 1.0 - (centrality[r] / (maxC>0?maxC:1.0));\n\n    // Dijkstra utils\n    const int INF = 1e9;\n    vector<int> dist(R), prevArr(R,-1);\n    auto dijkstra = [&](int src, vector<int>& distOut, vector<int>* prevOut){\n        fill(distOut.begin(), distOut.end(), INF);\n        if (prevOut) fill(prevOut->begin(), prevOut->end(), -1);\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        distOut[src] = 0;\n        pq.emplace(0, src);\n        while (!pq.empty()){\n            auto [cd,u] = pq.top(); pq.pop();\n            if (cd != distOut[u]) continue;\n            for (int d=0; d<4; ++d) {\n                int v = neigh[u][d];\n                if (v < 0) continue;\n                int w = moveCost[u][d];\n                int nd = cd + w;\n                if (nd < distOut[v]) {\n                    distOut[v] = nd;\n                    if (prevOut) (*prevOut)[v] = u;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n    };\n    auto reconstruct_seq = [&](int curId, int tgtId, const vector<int>& prev)->vector<int>{\n        vector<int> seq;\n        if (curId == tgtId) return seq;\n        int x = tgtId;\n        while (x != -1 && x != curId) { seq.push_back(x); x = prev[x]; }\n        if (x != curId) { seq.clear(); return seq; }\n        reverse(seq.begin(), seq.end());\n        return seq;\n    };\n\n    // Precompute dist_to_start and average\n    vector<int> dist_to_start(R);\n    dijkstra(startId, dist_to_start, nullptr);\n    long long sumd = 0; int cntd = 0;\n    for (int r=0;r<R;++r) if (dist_to_start[r] < INF) { sumd += dist_to_start[r]; cntd++; }\n    double avgDistToStart = (cntd ? (double)sumd / cntd : 1.0);\n\n    // Coverage tracking\n    BVec covered(W, 0), remaining(W, 0);\n    for (int r=0;r<R;++r) remaining[r>>6] |= (1ULL << (r&63));\n    auto see_from_apply = [&](int node, int &remCount){\n        for (int k=0;k<W;++k) {\n            uint64_t bits = vis[node][k];\n            uint64_t newbits = bits & ~covered[k];\n            int add = (int)__builtin_popcountll(newbits);\n            covered[k] |= bits;\n            remaining[k] &= ~bits;\n            remCount -= add;\n        }\n    };\n\n    // Uncovered mass per run\n    vector<int> rowRem(rowRunCnt, 0), colRem(colRunCnt, 0);\n    for (int r=0;r<R;++r) { rowRem[rowRunId[r]]++; colRem[colRunId[r]]++; }\n    auto update_run_mass_after_see = [&](int node){\n        for (int k=0;k<W;++k) {\n            uint64_t newbits = vis[node][k] & ~covered[k];\n            uint64_t bits = newbits;\n            while (bits) {\n                uint64_t b = bits & -bits;\n                int idx = (k<<6) + __builtin_ctzll(bits);\n                if (idx < R) {\n                    int rr = rowRunId[idx], cc = colRunId[idx];\n                    if (rr >= 0) rowRem[rr]--;\n                    if (cc >= 0) colRem[cc]--;\n                }\n                bits ^= b;\n            }\n        }\n    };\n\n    int remCount = R;\n    update_run_mass_after_see(startId);\n    see_from_apply(startId, remCount);\n\n    string answer;\n    Timer timer;\n    double timeLimit = 2.85;\n    int cur = startId;\n\n    vector<int> dist_cur(R), prev_cur(R);\n\n    auto compute_lambda = [&](double coveredRatio, int curNode)->double{\n        double curToStart = (dist_to_start[curNode] < INF ? dist_to_start[curNode] : avgDistToStart);\n        double lambda = 0.0;\n        if (coveredRatio > 0.6) {\n            lambda = 0.05 * (curToStart / max(1.0, avgDistToStart));\n            if (coveredRatio > 0.9) lambda *= 1.6;\n            if (coveredRatio > 0.95) lambda *= 1.4;\n        }\n        if (coveredRatio > 0.95 && curToStart > 1.5*avgDistToStart) lambda *= 1.3;\n        return lambda;\n    };\n\n    auto score_candidate = [&](int t, double lambda, int remCount, const BVec& remaining,\n                               int phase)->optional<double>{\n        int d0 = dist_cur[t];\n        if (d0 >= INF) return nullopt;\n        int gain = marginal_gain(vis[t], remaining);\n        if (gain <= 0) return nullopt;\n\n        int rr = rowRunId[t], cc = colRunId[t];\n        int mass = 0;\n        if (rr >= 0) mass += max(0, rowRem[rr]);\n        if (cc >= 0) mass += max(0, colRem[cc]);\n        double massBoost = 1.0 + 0.15 * tanh(mass / 20.0);\n        double potPen = 1.0 + 0.1 * pot[t];\n        double centBoost = 1.0 + 0.1 * centrality[t];\n\n        double eff = ((double)d0 + lambda * (double)dist_to_start[t]) * potPen;\n        if (phase == 0) { // EARLY\n            double beta = 1.08;\n            return (eff / pow((double)gain, beta)) / (massBoost * centBoost);\n        } else if (phase == 1) { // MID\n            double alpha = 0.02;\n            return -(((double)gain*massBoost*centBoost) - alpha * eff);\n        } else { // LATE\n            int minGainReq = (remCount > 8 ? 2 : 1);\n            if (gain < minGainReq) return nullopt;\n            return (eff / (double)gain) / (0.7*massBoost + 0.3*centBoost);\n        }\n    };\n\n    while (remCount > 0) {\n        if (timer.elapsed() > timeLimit) break;\n\n        dijkstra(cur, dist_cur, &prev_cur);\n\n        double coveredRatio = 1.0 - (double)remCount / (double)R;\n        double lambda = compute_lambda(coveredRatio, cur);\n        int phase = 0;\n        if (remCount <= R / 4) phase = 1;\n        if (remCount <= max(32, R / 12)) phase = 2;\n\n        // Select shortlist\n        struct CandScore { int t; int gain; double eff; double score; };\n        vector<CandScore> cs; cs.reserve(min((int)cand.size(), 256));\n\n        auto eval_primary = [&](int t)->optional<CandScore>{\n            int d0 = dist_cur[t];\n            if (d0 >= INF) return nullopt;\n            int gain = marginal_gain(vis[t], remaining);\n            if (gain <= 0) return nullopt;\n\n            int rr = rowRunId[t], cc = colRunId[t];\n            int mass = 0;\n            if (rr >= 0) mass += max(0, rowRem[rr]);\n            if (cc >= 0) mass += max(0, colRem[cc]);\n            double massBoost = 1.0 + 0.15 * tanh(mass / 20.0);\n            double potPen = 1.0 + 0.1 * pot[t];\n            double centBoost = 1.0 + 0.1 * centrality[t];\n\n            double eff = ((double)d0 + lambda * (double)dist_to_start[t]) * potPen;\n            double sc;\n            if (phase == 0) {\n                double beta = 1.08;\n                sc = (eff / pow((double)gain, beta)) / (massBoost * centBoost);\n            } else if (phase == 1) {\n                double alpha = 0.02;\n                sc = -(((double)gain*massBoost*centBoost) - alpha * eff);\n            } else {\n                int minGainReq = (remCount > 8 ? 2 : 1);\n                if (gain < minGainReq) return nullopt;\n                sc = (eff / (double)gain) / (0.7*massBoost + 0.3*centBoost);\n            }\n            return CandScore{t, gain, eff, sc};\n        };\n\n        for (int t : cand) {\n            auto r = eval_primary(t);\n            if (r) cs.push_back(*r);\n        }\n        if (cs.empty()) {\n            vector<pair<int,int>> gain_nodes; gain_nodes.reserve(600);\n            for (int t=0;t<R;++t) {\n                if (dist_cur[t] >= INF) continue;\n                int gain = marginal_gain(vis[t], remaining);\n                if (gain > 0) gain_nodes.emplace_back(-gain, t);\n            }\n            if (!gain_nodes.empty()) {\n                int K = min((int)gain_nodes.size(), 600);\n                nth_element(gain_nodes.begin(), gain_nodes.begin()+K, gain_nodes.end());\n                for (int i=0;i<K;++i) {\n                    auto r = eval_primary(gain_nodes[i].second);\n                    if (r) cs.push_back(*r);\n                }\n            }\n        }\n        if (cs.empty()) break;\n\n        int BEAM = 10;\n        if (timer.elapsed() > timeLimit*0.9) BEAM = 6;\n        nth_element(cs.begin(), cs.begin()+min(BEAM,(int)cs.size())-1, cs.end(),\n                    [&](const CandScore& a, const CandScore& b){ return a.score < b.score; });\n        int beamSize = min(BEAM, (int)cs.size());\n        cs.resize(beamSize);\n\n        // Two-step lookahead\n        int bestFirst = -1;\n        double bestPlanScore = 1e300;\n        vector<int> dist_tmp(R), prev_tmp(R);\n        int SEC_K_BASE = 60;\n        if (timer.elapsed() > timeLimit*0.9) SEC_K_BASE = 40;\n\n        for (int bi=0; bi<beamSize; ++bi) {\n            int t1 = cs[bi].t;\n            vector<pair<int,int>> secPool;\n            secPool.reserve(150);\n            for (int c : cand) {\n                int g2 = marginal_gain(vis[c], remaining);\n                if (g2 > 0) secPool.emplace_back(-g2, c);\n            }\n            if (!secPool.empty()) {\n                int SEC_K = min((int)secPool.size(), SEC_K_BASE);\n                nth_element(secPool.begin(), secPool.begin()+SEC_K, secPool.end());\n                secPool.resize(SEC_K);\n                dijkstra(t1, dist_tmp, &prev_tmp);\n                double bestSecondScore = cs[bi].score;\n                for (auto [negGain, c2] : secPool) {\n                    int d1 = dist_cur[t1];\n                    int d12 = dist_tmp[c2];\n                    if (d1 >= INF || d12 >= INF) continue;\n                    // marginal second gain after t1\n                    int secGain = 0;\n                    for (int k=0;k<W;++k) {\n                        uint64_t remk = remaining[k] & ~vis[t1][k];\n                        secGain += (int)__builtin_popcountll(remk & vis[c2][k]);\n                    }\n                    if (secGain <= 0) continue;\n\n                    int rr2 = rowRunId[c2], cc2 = colRunId[c2];\n                    int mass2 = 0;\n                    if (rr2 >= 0) mass2 += max(0, rowRem[rr2]);\n                    if (cc2 >= 0) mass2 += max(0, colRem[cc2]);\n                    double massBoost2 = 1.0 + 0.15 * tanh(mass2 / 20.0);\n                    double potPen2 = 1.0 + 0.1 * pot[c2];\n                    double centBoost2 = 1.0 + 0.1 * centrality[c2];\n\n                    double eff1 = ((double)d1 + lambda * (double)dist_to_start[t1]) * (1.0 + 0.1 * pot[t1]);\n                    double eff2 = ((double)d12 + lambda * (double)dist_to_start[c2]) * potPen2;\n\n                    double planScore;\n                    if (phase == 0) {\n                        double beta = 1.08;\n                        planScore = (eff1 / pow((double)cs[bi].gain, beta))\n                                    + 0.8 * ((eff2 / pow((double)secGain, beta)) / (massBoost2 * centBoost2));\n                    } else if (phase == 1) {\n                        double alpha = 0.02;\n                        double p1 = ((double)cs[bi].gain) - alpha * eff1;\n                        double p2 = (double)secGain * (massBoost2 * centBoost2) - alpha * eff2;\n                        planScore = -(p1 + 0.8*p2);\n                    } else {\n                        planScore = (eff1 / max(1, cs[bi].gain))\n                                    + 0.8 * ((eff2 / max(1, secGain)) / (0.7*massBoost2 + 0.3*centBoost2));\n                    }\n                    if (planScore < bestSecondScore) bestSecondScore = planScore;\n                }\n                if (bestSecondScore < bestPlanScore) {\n                    bestPlanScore = bestSecondScore;\n                    bestFirst = t1;\n                }\n            } else {\n                if (cs[bi].score < bestPlanScore) {\n                    bestPlanScore = cs[bi].score;\n                    bestFirst = t1;\n                }\n            }\n            if (timer.elapsed() > timeLimit) break;\n        }\n        if (bestFirst == -1) bestFirst = cs[0].t;\n\n        // Build path to bestFirst\n        vector<int> seq = reconstruct_seq(cur, bestFirst, prev_cur);\n        if (seq.empty() && cur != bestFirst) break;\n\n        string mv;\n        int prevNode = cur;\n        int gainedAlong = 0;\n        int reevaluateThreshold = max(12, remCount / 60);\n        // Opportunistic on-path replanning parameters\n        int stepCount = 0;\n        for (int v : seq) {\n            auto [ui,uj] = pos[prevNode];\n            auto [vi,vj] = pos[v];\n            if (vi==ui-1 && vj==uj) mv.push_back('U');\n            else if (vi==ui+1 && vj==uj) mv.push_back('D');\n            else if (vi==ui && vj==uj-1) mv.push_back('L');\n            else if (vi==ui && vj==uj+1) mv.push_back('R');\n\n            // Before applying, compute run mass update\n            update_run_mass_after_see(v);\n            int before = popcount_bits(remaining);\n            see_from_apply(v, remCount);\n            int after = popcount_bits(remaining);\n            gainedAlong += before - after;\n\n            prevNode = v;\n            stepCount++;\n            if (remCount == 0) break;\n\n            // Opportunistic local re-evaluation: every few steps, check if a nearby candidate now is much better\n            if (stepCount % 3 == 0 && timer.elapsed() < timeLimit*0.95) {\n                // Dijkstra from current small check\n                dijkstra(prevNode, dist_cur, &prev_cur);\n                double newLambda = compute_lambda(1.0 - (double)remCount / (double)R, prevNode);\n                double bestSc = 1e300;\n                int bestLoc = -1;\n                int checks = 0;\n                for (int t : cand) {\n                    if (checks >= 12) break;\n                    auto sc = score_candidate(t, newLambda, remCount, remaining, phase);\n                    if (!sc) continue;\n                    double val = *sc;\n                    if (val < bestSc) { bestSc = val; bestLoc = t; }\n                    checks++;\n                }\n                // If local best significantly better than committing to original endpoint, break\n                if (bestLoc != -1) {\n                    // heuristic: if after progress, any candidate beats continuation, replan\n                    break;\n                }\n            }\n\n            if (gainedAlong >= reevaluateThreshold) break;\n            if (timer.elapsed() > timeLimit) break;\n        }\n        answer += mv;\n        cur = prevNode;\n\n        if (timer.elapsed() > timeLimit) break;\n    }\n\n    // Return to start\n    if (cur != startId) {\n        vector<int> dist_back(R), prev_back(R);\n        auto dijkstra2 = [&](int src){\n            fill(dist_back.begin(), dist_back.end(), 1e9);\n            fill(prev_back.begin(), prev_back.end(), -1);\n            using P = pair<int,int>;\n            priority_queue<P, vector<P>, greater<P>> pq;\n            dist_back[src] = 0; pq.emplace(0, src);\n            while (!pq.empty()) {\n                auto [cd,u] = pq.top(); pq.pop();\n                if (cd != dist_back[u]) continue;\n                for (int d=0; d<4; ++d) {\n                    int v = neigh[u][d];\n                    if (v < 0) continue;\n                    int w = moveCost[u][d];\n                    int nd = cd + w;\n                    if (nd < dist_back[v]) {\n                        dist_back[v] = nd; prev_back[v] = u;\n                        pq.emplace(nd, v);\n                    }\n                }\n            }\n        };\n        dijkstra2(cur);\n        vector<int> seq;\n        if (dist_back[startId] < 1e9) {\n            int x = startId;\n            while (x != -1 && x != cur) { seq.push_back(x); x = prev_back[x]; }\n            if (x == cur) reverse(seq.begin(), seq.end());\n            else seq.clear();\n        }\n        string mv;\n        int prevNode = cur;\n        for (int v : seq) {\n            auto [ui,uj] = pos[prevNode];\n            auto [vi,vj] = pos[v];\n            if (vi==ui-1 && vj==uj) mv.push_back('U');\n            else if (vi==ui+1 && vj==uj) mv.push_back('D');\n            else if (vi==ui && vj==uj-1) mv.push_back('L');\n            else if (vi==ui && vj==uj+1) mv.push_back('R');\n            prevNode = v;\n        }\n        answer += mv;\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct RNG {\n    uint64_t x=88172645463393265ull;\n    uint32_t next() { x ^= x<<7; x ^= x>>9; return uint32_t(x); }\n    double drand() { return (next()>>8) * (1.0/16777216.0); }\n} rng;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,K,R;\n    if(!(cin>>N>>M>>K>>R)) return 0;\n    vector<vector<int>> d(N, vector<int>(K));\n    for(int i=0;i<N;i++) for(int k=0;k<K;k++) cin>>d[i][k];\n    vector<vector<int>> g(N);\n    vector<int> indeg(N,0);\n    for(int i=0;i<R;i++){\n        int u,v; cin>>u>>v; --u;--v;\n        g[u].push_back(v);\n        indeg[v]++;\n    }\n    // Topological order\n    vector<int> topo;\n    {\n        vector<int> indeg2 = indeg;\n        queue<int> q;\n        for(int i=0;i<N;i++) if(indeg2[i]==0) q.push(i);\n        while(!q.empty()){\n            int u=q.front(); q.pop();\n            topo.push_back(u);\n            for(int v: g[u]) if(--indeg2[v]==0) q.push(v);\n        }\n        if((int)topo.size()!=N){\n            topo.clear();\n            for(int i=0;i<N;i++) topo.push_back(i);\n        }\n    }\n    // Height (longest path to sink)\n    vector<int> height(N,0);\n    for(int idx=N-1; idx>=0; --idx){\n        int u=topo[idx];\n        int best=0;\n        for(int v: g[u]) best = max(best, 1 + height[v]);\n        height[u]=best;\n    }\n    // Out-degree and priority\n    vector<int> outdeg(N,0);\n    for(int u=0;u<N;u++) outdeg[u] = (int)g[u].size();\n    const double lambda = 0.15;\n    vector<double> prio(N);\n    for(int i=0;i<N;i++) prio[i] = height[i] + lambda * outdeg[i];\n\n    // Estimates\n    vector<vector<double>> est(M, vector<double>(K, 10.0));\n    vector<vector<int>> lb(M, vector<int>(K, 0));\n\n    // States\n    vector<int> tstat(N,0); // 0 not started, 1 started, 2 done\n    vector<int> started_by(N,-1), start_day(N,-1);\n    vector<int> mtask(M,-1);\n    vector<int> cur_indeg = indeg;\n    vector<char> ready_flag(N,0);\n    for(int i=0;i<N;i++) if(cur_indeg[i]==0) ready_flag[i]=1;\n\n    int done_cnt = 0;\n\n    // Global calibration bias for t prediction\n    double bias_b = 0.3; // start with small positive\n    int bias_cnt = 0;\n\n    auto predicted_w = [&](int task, int mem)->double{\n        double w=0.0;\n        for(int k=0;k<K;k++){\n            double df = (double)d[task][k] - est[mem][k];\n            if(df>0) w += df;\n        }\n        return w;\n    };\n    auto predicted_time = [&](int task, int mem)->double{\n        double w = predicted_w(task, mem);\n        if(w<1.0) return 1.0;\n        return max(1.0, w + bias_b);\n    };\n\n    auto assign_task = [&](int mem, int task, int day){\n        mtask[mem]=task;\n        tstat[task]=1;\n        started_by[task]=mem;\n        start_day[task]=day;\n        ready_flag[task]=0;\n    };\n\n    int day=0;\n    const double base_beta = 0.22;\n    const double eps = 0.05;\n\n    while(true){\n        day++;\n\n        // Idle members\n        vector<int> idle;\n        idle.reserve(M);\n        for(int j=0;j<M;j++) if(mtask[j]==-1) idle.push_back(j);\n\n        // Ready tasks\n        vector<int> ready_all;\n        ready_all.reserve(1024);\n        for(int i=0;i<N;i++){\n            if(ready_flag[i] && tstat[i]==0) ready_all.push_back(i);\n        }\n\n        vector<int> rlist = ready_all;\n        // Dynamic priority weight: later stages reduce priority emphasis\n        int remaining_tasks = 0;\n        for(int i=0;i<N;i++) if(tstat[i]!=2) remaining_tasks++;\n        double beta = base_beta * (remaining_tasks > 300 ? 1.0 : (0.6 + 0.4 * (double)remaining_tasks / 300.0));\n\n        // Cap by priority but also include best-fit pool\n        int cap_prio = 320;\n        if((int)rlist.size()>cap_prio){\n            nth_element(rlist.begin(), rlist.begin()+cap_prio, rlist.end(), [&](int a,int b){\n                return prio[a] > prio[b];\n            });\n            rlist.resize(cap_prio);\n        }\n        // Add best-fit pool: tasks with minimal predicted w across idle members\n        if(!idle.empty()){\n            vector<pair<double,int>> bestfit;\n            bestfit.reserve(256);\n            for(int t : ready_all){\n                // skip if already in rlist\n                // mark in set for O(1)\n            }\n            vector<char> inR(N, 0);\n            for(int t: rlist) inR[t]=1;\n            for(int t: ready_all){\n                if(inR[t]) continue;\n                double minw = 1e100;\n                for(int mem: idle){\n                    double w = predicted_w(t, mem);\n                    if(w < minw) minw = w;\n                }\n                bestfit.emplace_back(minw, t);\n            }\n            int cap_fit = 80;\n            if((int)bestfit.size() > cap_fit){\n                nth_element(bestfit.begin(), bestfit.begin()+cap_fit, bestfit.end(),\n                            [&](const auto& A, const auto& B){ return A.first < B.first; });\n                bestfit.resize(cap_fit);\n            }\n            for(auto &p: bestfit) rlist.push_back(p.second);\n        }\n\n        // Remove duplicates in rlist\n        sort(rlist.begin(), rlist.end());\n        rlist.erase(unique(rlist.begin(), rlist.end()), rlist.end());\n\n        vector<pair<int,int>> out;\n        out.reserve(idle.size());\n\n        if(!idle.empty() && !rlist.empty()){\n            size_t U = idle.size(), L = rlist.size();\n            vector<char> taskTaken(L, 0);\n            vector<char> memTaken(U, 0);\n\n            // Precompute predicted w\n            vector<vector<double>> pw(U, vector<double>(L, 0.0));\n            for(size_t ui=0; ui<U; ++ui){\n                int mem = idle[ui];\n                for(size_t li=0; li<L; ++li){\n                    int t = rlist[li];\n                    pw[ui][li] = predicted_w(t, mem);\n                }\n            }\n\n            // Phase 1: perfect-fit w<1\n            for(size_t ui=0; ui<U; ++ui){\n                if(memTaken[ui]) continue;\n                int mem = idle[ui];\n                int bestIdx=-1; double bestSc=-1e100;\n                for(size_t li=0; li<L; ++li){\n                    if(taskTaken[li]) continue;\n                    if(pw[ui][li] < 1.0 - 1e-9){\n                        double sc = prio[rlist[li]];\n                        if(sc > bestSc){\n                            bestSc = sc; bestIdx = (int)li;\n                        }\n                    }\n                }\n                if(bestIdx!=-1){\n                    taskTaken[bestIdx]=1;\n                    memTaken[ui]=1;\n                    out.emplace_back(mem, rlist[bestIdx]);\n                }\n            }\n\n            // Phase 2: near-perfect (1..3], assign to best member, prioritize by prio\n            vector<int> bestMemForTask(L, -1);\n            for(size_t li=0; li<L; ++li){\n                if(taskTaken[li]) continue;\n                double bestW = 1e100; int bestUI=-1;\n                for(size_t ui=0; ui<U; ++ui){\n                    if(memTaken[ui]) continue;\n                    double w = pw[ui][li];\n                    if(w >= 1.0 - 1e-9 && w <= 3.0 + 1e-9){\n                        if(w < bestW - 1e-12){\n                            bestW = w; bestUI=(int)ui;\n                        }\n                    }\n                }\n                bestMemForTask[li]=bestUI;\n            }\n            vector<int> order(L);\n            iota(order.begin(), order.end(), 0);\n            sort(order.begin(), order.end(), [&](int a,int b){\n                return prio[rlist[a]] > prio[rlist[b]];\n            });\n            for(int li: order){\n                if(taskTaken[li]) continue;\n                int ui = bestMemForTask[li];\n                if(ui>=0 && !memTaken[ui]){\n                    taskTaken[li]=1;\n                    memTaken[ui]=1;\n                    out.emplace_back(idle[ui], rlist[li]);\n                }\n            }\n\n            // Phase 3: greedy fill by predicted time - beta*prio\n            for(size_t ui=0; ui<U; ++ui){\n                if(memTaken[ui]) continue;\n                int mem = idle[ui];\n                bool explore = (rng.drand() < eps);\n                int bestIdx=-1; double bestScore=1e100;\n                if(explore){\n                    for(size_t li=0; li<L; ++li){\n                        if(taskTaken[li]) continue;\n                        int t = rlist[li];\n                        double w = pw[ui][li];\n                        double score = fabs(w-1.8) - 0.05*prio[t];\n                        if(score < bestScore){\n                            bestScore = score; bestIdx=(int)li;\n                        }\n                    }\n                }else{\n                    for(size_t li=0; li<L; ++li){\n                        if(taskTaken[li]) continue;\n                        int t = rlist[li];\n                        double tp = (pw[ui][li] < 1.0 ? 1.0 : pw[ui][li] + bias_b);\n                        double score = tp - beta * prio[t];\n                        if(score < bestScore){\n                            bestScore = score; bestIdx=(int)li;\n                        }\n                    }\n                }\n                if(bestIdx!=-1){\n                    taskTaken[bestIdx]=1;\n                    out.emplace_back(mem, rlist[bestIdx]);\n                }\n            }\n\n            // Phase 4: if still idle and ready set small, search globally among all ready tasks\n            if(!ready_all.empty() && ready_all.size() <= 200){\n                for(size_t ui=0; ui<U; ++ui){\n                    if(memTaken[ui]) continue; // only truly idle if not assigned; however memTaken tracks internal, we check actual out assignments\n                }\n                // build set of already assigned tasks\n                vector<char> assignedT(N, 0);\n                for(auto &p: out) assignedT[p.second]=1;\n                for(int mem : idle){\n                    bool already=false;\n                    for(auto &p: out) if(p.first==mem){ already=true; break; }\n                    if(already) continue;\n                    int bestT=-1; double bestVal=1e100;\n                    for(int t : ready_all){\n                        if(assignedT[t]) continue;\n                        double tp = predicted_time(t, mem);\n                        double val = tp - beta * prio[t];\n                        if(val < bestVal){\n                            bestVal = val; bestT = t;\n                        }\n                    }\n                    if(bestT!=-1){\n                        assignedT[bestT]=1;\n                        out.emplace_back(mem, bestT);\n                    }\n                }\n            }\n        }\n\n        // Output\n        cout<<out.size();\n        for(auto &p: out){\n            cout<<\" \"<<(p.first+1)<<\" \"<<(p.second+1);\n            assign_task(p.first, p.second, day);\n        }\n        cout<<\"\\n\";\n        cout.flush();\n\n        // Feedback\n        int nfin;\n        if(!(cin>>nfin)) return 0;\n        if(nfin==-1) return 0;\n        vector<int> fins(nfin);\n        for(int i=0;i<nfin;i++){ cin>>fins[i]; fins[i]--; }\n\n        // Process finishes\n        for(int mem: fins){\n            int task = mtask[mem];\n            if(task<0) continue;\n            int dur = day - start_day[task] + 1;\n            done_cnt++;\n\n            // Update global bias from this observation if dur>1\n            {\n                double w0 = 0.0;\n                for(int k=0;k<K;k++){\n                    double df = (double)d[task][k] - est[mem][k];\n                    if(df>0) w0 += df;\n                }\n                if(dur>1){\n                    double resid = (double)dur - w0;\n                    resid = max(-3.0, min(3.0, resid));\n                    // running average with clipping to [-1,1]\n                    bias_cnt++;\n                    double lr_b = 1.0 / min(500, bias_cnt);\n                    bias_b = (1.0 - lr_b) * bias_b + lr_b * resid;\n                    bias_b = max(-1.0, min(1.0, bias_b));\n                }\n            }\n\n            if(dur<=1){\n                for(int k=0;k<K;k++){\n                    lb[mem][k] = max(lb[mem][k], d[task][k]);\n                    est[mem][k] = max(est[mem][k], (double)d[task][k]);\n                }\n            }else{\n                // Compute deficits\n                vector<double> def(K, 0.0);\n                double W=0.0;\n                for(int k=0;k<K;k++){\n                    double df = (double)d[task][k] - est[mem][k];\n                    if(df>0){ def[k]=df; W+=df; }\n                }\n                double high = dur + 3.0;\n                if(W > high + 1e-9){\n                    double delta = W - high;\n                    // adaptive learning rate; boost when dur small (e.g., 2 or 3) and W is much larger\n                    double lr = min(0.7, 0.25 + 0.03 * max(0.0, W - high));\n                    if(dur<=3) lr = min(0.8, lr + 0.1);\n                    double step = min(delta, 8.0) * lr;\n                    double sumdef = W;\n                    if(sumdef>1e-9){\n                        for(int k=0;k<K;k++){\n                            if(def[k]>1e-12){\n                                double inc = step * (def[k]/sumdef);\n                                double capInc = max(0.0, (double)d[task][k] - est[mem][k]);\n                                if(inc > capInc) inc = capInc;\n                                est[mem][k] += inc;\n                            }\n                            if(est[mem][k] < lb[mem][k]) est[mem][k] = lb[mem][k];\n                        }\n                    }else{\n                        for(int k=0;k<K;k++){\n                            if(est[mem][k] < lb[mem][k]) est[mem][k] = lb[mem][k];\n                        }\n                    }\n                }else{\n                    // Enforce lb only\n                    for(int k=0;k<K;k++){\n                        if(est[mem][k] < lb[mem][k]) est[mem][k] = lb[mem][k];\n                    }\n                }\n            }\n\n            // Mark done and unlock successors\n            mtask[mem] = -1;\n            tstat[task]=2;\n            for(int v: g[task]){\n                if(--cur_indeg[v]==0 && tstat[v]==0){\n                    ready_flag[v]=1;\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int ax, ay, cx, cy, idx;\n    double base_score;\n};\n\nstruct Node { int x,y; int ordIdx; bool isPickup; };\n\nstatic inline int manh(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\n\nstatic inline long long routeDist(const vector<Node>& R){\n    long long t=0;\n    for(size_t i=0;i+1<R.size();++i) t += manh(R[i].x,R[i].y,R[i+1].x,R[i+1].y);\n    return t;\n}\n\nstatic inline bool precedence_ok(const vector<Node>& R, const vector<int>& selectedIdx){\n    vector<int> pidx(1001,-1), didx(1001,-1);\n    for(int k=0;k<(int)R.size();++k){\n        int id=R[k].ordIdx;\n        if(id==-1) continue;\n        if(R[k].isPickup){ if(pidx[id]==-1) pidx[id]=k; }\n        else { if(didx[id]==-1) didx[id]=k; }\n    }\n    for(int id: selectedIdx){\n        int pid = pidx[id];\n        int did = didx[id];\n        if(pid==-1 || did==-1) continue;\n        if(pid >= did) return false;\n    }\n    return true;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int DEPX=400, DEPY=400;\n    vector<Order> all;\n    all.reserve(1000);\n    for(int i=0;i<1000;i++){\n        int a,b,c,d;\n        if(!(cin>>a>>b>>c>>d)) return 0;\n        Order o; o.ax=a;o.ay=b;o.cx=c;o.cy=d;o.idx=i+1;o.base_score=0;\n        all.push_back(o);\n    }\n    if(all.size()!=1000){\n        cout<<\"0\\n1 400 400\\n\";\n        return 0;\n    }\n\n    // Base scores\n    for(auto &o: all){\n        int da = manh(DEPX,DEPY,o.ax,o.ay);\n        int ac = manh(o.ax,o.ay,o.cx,o.cy);\n        int cd = manh(o.cx,o.cy,DEPX,DEPY);\n        o.base_score = da + ac + 0.6*cd;\n    }\n\n    auto select_orders = [&](double lambda)->vector<Order>{\n        int m = 50;\n        vector<int> used(1000,0);\n        vector<Order> chosen;\n        chosen.reserve(m);\n        // initial pick\n        int besti=-1; double bestv=1e100;\n        for(int i=0;i<1000;i++){\n            double v = all[i].base_score + 0.2 * (manh(DEPX,DEPY,all[i].ax,all[i].ay) + manh(DEPX,DEPY,all[i].cx,all[i].cy));\n            if(v < bestv){ bestv=v; besti=i; }\n        }\n        used[besti]=1; chosen.push_back(all[besti]);\n\n        auto mindist_to_cluster = [&](const Order& o)->int{\n            int md = INT_MAX;\n            for(auto &c: chosen){\n                md = min(md, manh(o.ax,o.ay,c.ax,c.ay));\n                md = min(md, manh(o.ax,o.ay,c.cx,c.cy));\n                md = min(md, manh(o.cx,o.cy,c.ax,c.ay));\n                md = min(md, manh(o.cx,o.cy,c.cx,c.cy));\n            }\n            return md;\n        };\n\n        for(int k=1;k<m;k++){\n            int pick=-1; double best=1e100;\n            for(int i=0;i<1000;i++){\n                if(used[i]) continue;\n                int md = mindist_to_cluster(all[i]);\n                double val = all[i].base_score + lambda * md;\n                if(val < best){\n                    best=val; pick=i;\n                }\n            }\n            used[pick]=1; chosen.push_back(all[pick]);\n        }\n        return chosen;\n    };\n\n    auto build_greedy_pd = [&](const vector<Order>& sel)->vector<Node>{\n        unordered_map<int, Order> om;\n        om.reserve(sel.size()*2);\n        for(auto &o: sel) om[o.idx]=o;\n        vector<int> unpicked, carrying;\n        for(auto &o: sel) unpicked.push_back(o.idx);\n        int curx=DEPX, cury=DEPY;\n        vector<Node> R;\n        R.push_back({DEPX,DEPY,-1,false});\n        while(!unpicked.empty()){\n            int bestDid=-1, bestDdist=INT_MAX, dx=0,dy=0;\n            for(int id: carrying){\n                auto &o = om[id];\n                int d = manh(curx,cury,o.cx,o.cy);\n                if(d < bestDdist){ bestDdist=d; bestDid=id; dx=o.cx; dy=o.cy; }\n            }\n            int bestPid=-1, bestPdist=INT_MAX, px=0,py=0;\n            for(int id: unpicked){\n                auto &o = om[id];\n                int d = manh(curx,cury,o.ax,o.ay);\n                if(d < bestPdist){ bestPdist=d; bestPid=id; px=o.ax; py=o.ay; }\n            }\n            if(bestDid!=-1 && bestDdist <= bestPdist/3){\n                R.push_back({dx,dy,bestDid,false});\n                curx=dx; cury=dy;\n                auto it = find(carrying.begin(), carrying.end(), bestDid);\n                if(it!=carrying.end()) carrying.erase(it);\n            }else{\n                R.push_back({px,py,bestPid,true});\n                curx=px; cury=py;\n                auto it = find(unpicked.begin(), unpicked.end(), bestPid);\n                if(it!=unpicked.end()) unpicked.erase(it);\n                carrying.push_back(bestPid);\n            }\n        }\n        while(!carrying.empty()){\n            int bestDid=-1, bestDdist=INT_MAX, dx=0,dy=0;\n            for(int id: carrying){\n                auto &o = om[id];\n                int d = manh(curx,cury,o.cx,o.cy);\n                if(d < bestDdist){ bestDdist=d; bestDid=id; dx=o.cx; dy=o.cy; }\n            }\n            R.push_back({dx,dy,bestDid,false});\n            curx=dx; cury=dy;\n            auto it = find(carrying.begin(), carrying.end(), bestDid);\n            if(it!=carrying.end()) carrying.erase(it);\n        }\n        R.push_back({DEPX,DEPY,-1,false});\n        return R;\n    };\n\n    auto build_insertion = [&](const vector<Order>& sel)->vector<Node>{\n        vector<Node> R;\n        R.push_back({DEPX,DEPY,-1,false});\n        R.push_back({DEPX,DEPY,-1,false});\n        // insert pickups\n        for(auto &o: sel){\n            Node P{ o.ax, o.ay, o.idx, true };\n            long long bestInc = (1LL<<60);\n            int bestPos = 1;\n            for(int pos=1; pos<(int)R.size(); ++pos){\n                long long d0 = manh(R[pos-1].x,R[pos-1].y,R[pos].x,R[pos].y);\n                long long d1 = manh(R[pos-1].x,R[pos-1].y,P.x,P.y) + manh(P.x,P.y,R[pos].x,R[pos].y);\n                long long inc = d1 - d0;\n                if(inc < bestInc){\n                    bestInc = inc; bestPos = pos;\n                }\n            }\n            R.insert(R.begin()+bestPos, P);\n        }\n        // insert drops\n        for(auto &o: sel){\n            Node D{ o.cx, o.cy, o.idx, false };\n            int pidx=-1;\n            for(int i=0;i<(int)R.size();++i){\n                if(R[i].ordIdx==o.idx && R[i].isPickup){ pidx=i; break; }\n            }\n            long long bestInc = (1LL<<60);\n            int bestPos = pidx+1;\n            for(int pos=pidx+1; pos<(int)R.size(); ++pos){\n                long long d0 = manh(R[pos-1].x,R[pos-1].y,R[pos].x,R[pos].y);\n                long long d1 = manh(R[pos-1].x,R[pos-1].y,D.x,D.y) + manh(D.x,D.y,R[pos].x,R[pos].y);\n                long long inc = d1 - d0;\n                if(inc < bestInc){\n                    bestInc = inc; bestPos = pos;\n                }\n            }\n            R.insert(R.begin()+bestPos, D);\n        }\n        // ensure ends\n        if(!(R.front().x==DEPX && R.front().y==DEPY)) R.insert(R.begin(), {DEPX,DEPY,-1,false});\n        if(!(R.back().x==DEPX && R.back().y==DEPY)) R.push_back({DEPX,DEPY,-1,false});\n        return R;\n    };\n\n    auto two_opt = [&](vector<Node>& R, const vector<int>& ids){\n        bool improved=true;\n        int iter=0;\n        while(improved && iter<200){\n            improved=false; iter++;\n            long long bestGain=0;\n            int bi=-1,bj=-1;\n            for(int i=1;i+2<(int)R.size();++i){\n                for(int j=i+1;j+1<(int)R.size();++j){\n                    long long d0 = manh(R[i-1].x,R[i-1].y,R[i].x,R[i].y)\n                                  + manh(R[j].x,R[j].y,R[j+1].x,R[j+1].y);\n                    long long d1 = manh(R[i-1].x,R[i-1].y,R[j].x,R[j].y)\n                                  + manh(R[i].x,R[i].y,R[j+1].x,R[j+1].y);\n                    long long gain = d0 - d1;\n                    if(gain > bestGain){\n                        reverse(R.begin()+i, R.begin()+j+1);\n                        if(precedence_ok(R, ids)){\n                            bestGain = gain;\n                            bi=i; bj=j;\n                        }\n                        reverse(R.begin()+i, R.begin()+j+1);\n                    }\n                }\n            }\n            if(bestGain > 0 && bi!=-1){\n                reverse(R.begin()+bi, R.begin()+bj+1);\n                improved=true;\n            }\n        }\n    };\n\n    auto or_opt12 = [&](vector<Node>& R, const vector<int>& ids){\n        bool improved=true;\n        int iter=0;\n        while(improved && iter<120){\n            improved=false; iter++;\n            long long curL = routeDist(R);\n            int N = (int)R.size();\n            for(int len=1; len<=2; ++len){\n                bool applied=false;\n                for(int i=1; i+len <= N-1; ++i){\n                    if(i <= 0 || i+len-1 >= N-1) continue; // avoid endpoints\n                    vector<Node> seg(R.begin()+i, R.begin()+i+len);\n                    vector<Node> T;\n                    T.reserve(N);\n                    T.insert(T.end(), R.begin(), R.begin()+i);\n                    T.insert(T.end(), R.begin()+i+len, R.end());\n                    for(int j=1; j <= (int)T.size()-1; ++j){\n                        if(j==i) continue;\n                        if(j >= (int)T.size()) break;\n                        if(j > (int)T.size()-1) continue;\n                        vector<Node> W=T;\n                        int jj = min(j, (int)W.size()-1);\n                        W.insert(W.begin()+jj, seg.begin(), seg.end());\n                        if(!precedence_ok(W, ids)) continue;\n                        if(!(W.front().x==DEPX && W.front().y==DEPY)) continue;\n                        if(!(W.back().x==DEPX && W.back().y==DEPY)) continue;\n                        long long newL = routeDist(W);\n                        if(newL < curL){\n                            R.swap(W);\n                            improved=true; applied=true;\n                            N = (int)R.size();\n                            break;\n                        }\n                    }\n                    if(applied) break;\n                }\n                if(improved) break;\n            }\n        }\n    };\n\n    auto relocate_pair = [&](vector<Node>& R, const vector<int>& ids){\n        bool improved=true;\n        int attempts=0;\n        while(improved && attempts<80){\n            improved=false; attempts++;\n            long long curL = routeDist(R);\n            bool applied=false;\n            int N = (int)R.size();\n            for(int id: ids){\n                int pid=-1,did=-1;\n                for(int i=0;i<N;i++){\n                    if(R[i].ordIdx==id){\n                        if(R[i].isPickup) pid=i;\n                        else did=i;\n                    }\n                }\n                if(pid==-1 || did==-1 || pid>=did) continue;\n                for(int dp=-3; dp<=3; ++dp){\n                    int ppos = min(max(1, pid+dp), N-2); // keep pickup away from endpoints\n                    for(int dd=-3; dd<=3; ++dd){\n                        int dposRaw = did+dd;\n                        vector<Node> T = R;\n                        Node P = T[pid], D=T[did];\n                        if(pid<did){\n                            T.erase(T.begin()+did);\n                            T.erase(T.begin()+pid);\n                        }else{\n                            T.erase(T.begin()+pid);\n                            T.erase(T.begin()+did);\n                        }\n                        int Np = (int)T.size();\n                        int pposClamped = min(max(1, ppos), Np-1); // insert before last depot\n                        T.insert(T.begin()+pposClamped, P);\n                        int Nq = (int)T.size();\n                        int dbase = min(max(pposClamped+1, dposRaw), Nq-1);\n                        int dpos = dbase;\n                        if(dpos <= pposClamped) dpos = pposClamped+1;\n                        if(dpos >= Nq) dpos = Nq-1; // avoid last depot\n                        T.insert(T.begin()+dpos, D);\n                        if(!(T.front().x==DEPX && T.front().y==DEPY)) continue;\n                        if(!(T.back().x==DEPX && T.back().y==DEPY)) continue;\n                        if(!precedence_ok(T, ids)) continue;\n                        long long newL = routeDist(T);\n                        if(newL < curL){\n                            R.swap(T);\n                            improved=true; applied=true;\n                            N = (int)R.size();\n                            break;\n                        }\n                    }\n                    if(applied) break;\n                }\n                if(applied) break;\n            }\n        }\n    };\n\n    const int tries = 3;\n    vector<double> lambdas = {-0.8, -0.5, -0.2};\n    long long bestLen = (1LL<<60);\n    vector<Node> bestRoute;\n    vector<int> bestIds;\n\n    for(int t=0;t<tries;t++){\n        auto sel = select_orders(lambdas[t%lambdas.size()]);\n        vector<int> ids; ids.reserve(sel.size());\n        for(auto &o: sel) ids.push_back(o.idx);\n\n        auto R1 = build_greedy_pd(sel);\n        auto R2 = build_insertion(sel);\n        if(!precedence_ok(R2, ids)) R2 = R1;\n\n        auto refine = [&](vector<Node>& R){\n            if(!(R.front().x==DEPX && R.front().y==DEPY)) R.insert(R.begin(), {DEPX,DEPY,-1,false});\n            if(!(R.back().x==DEPX && R.back().y==DEPY)) R.push_back({DEPX,DEPY,-1,false});\n            two_opt(R, ids);\n            or_opt12(R, ids);\n            relocate_pair(R, ids);\n            two_opt(R, ids);\n            if(!(R.front().x==DEPX && R.front().y==DEPY)) R.front() = {DEPX,DEPY,-1,false};\n            if(!(R.back().x==DEPX && R.back().y==DEPY)) R.back() = {DEPX,DEPY,-1,false};\n        };\n        refine(R1);\n        refine(R2);\n\n        long long d1 = routeDist(R1);\n        long long d2 = routeDist(R2);\n        if(d1 < bestLen){\n            bestLen = d1;\n            bestRoute = R1;\n            bestIds = ids;\n        }\n        if(d2 < bestLen){\n            bestLen = d2;\n            bestRoute = R2;\n            bestIds = ids;\n        }\n    }\n\n    if(bestRoute.empty() || !(bestRoute.front().x==DEPX && bestRoute.front().y==DEPY)){\n        bestRoute.insert(bestRoute.begin(), {DEPX,DEPY,-1,false});\n    }\n    if(!(bestRoute.back().x==DEPX && bestRoute.back().y==DEPY)){\n        bestRoute.push_back({DEPX,DEPY,-1,false});\n    }\n\n    cout<<bestIds.size();\n    for(int id: bestIds) cout<<\" \"<<id;\n    cout<<\"\\n\";\n    cout<<bestRoute.size();\n    for(auto &nd: bestRoute){\n        cout<<\" \"<<nd.x<<\" \"<<nd.y;\n    }\n    cout<<\"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    int comps;\n    DSU(int n=0): n(n), p(n), r(n,0), comps(n) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool same(int a,int b){ return find(a)==find(b); }\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        comps--;\n        return true;\n    }\n};\n\nstruct Edge {\n    int idx;\n    int u,v;\n    int d; // prior rounded Euclidean 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    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++){\n        if(!(cin>>x[i]>>y[i])) return 0;\n    }\n    vector<int> U(M), V(M);\n    for(int i=0;i<M;i++){\n        cin>>U[i]>>V[i];\n    }\n\n    auto rd = [&](int i)->int{\n        long long dx = x[U[i]] - x[V[i]];\n        long long dy = y[U[i]] - y[V[i]];\n        double dist = sqrt((double)(dx*dx + dy*dy));\n        return (int)llround(dist);\n    };\n\n    vector<Edge> edges(M);\n    for(int i=0;i<M;i++){\n        edges[i] = {i, U[i], V[i], rd(i)};\n    }\n\n    // Build 5 disjoint MST layers using d as weight\n    vector<int> layer(M, -1);\n    for(int lay=0; lay<5; lay++){\n        vector<int> avail;\n        avail.reserve(M);\n        for(int ei=0; ei<M; ei++){\n            if(layer[ei]==-1) avail.push_back(ei);\n        }\n        sort(avail.begin(), avail.end(), [&](int a, int b){\n            if(edges[a].d != edges[b].d) return edges[a].d < edges[b].d;\n            if(edges[a].u != edges[b].u) return edges[a].u < edges[b].u;\n            return edges[a].v < edges[b].v;\n        });\n        DSU dsu(N);\n        int taken = 0;\n        for(int eid: avail){\n            int u = edges[eid].u, v = edges[eid].v;\n            if(!dsu.same(u,v)){\n                dsu.unite(u,v);\n                layer[eid] = lay;\n                taken++;\n                if(taken == N-1) break;\n            }\n        }\n        // As per generation, this will assign exactly N-1 edges per layer\n    }\n\n    // Online phase with guaranteed connectivity via backup layer\n    DSU cur(N);\n\n    int backup_layer = 0; // rely on the base MST layer by d as guaranteed backbone\n\n    // Strict acceptance multipliers for non-backup layers (prefer very good edges only)\n    array<double,5> beta;\n    beta[0]=1.25; beta[1]=1.20; beta[2]=1.15; beta[3]=1.10; beta[4]=1.05;\n\n    for(int i=0;i<M;i++){\n        int l_i;\n        if(!(cin>>l_i)) return 0;\n\n        int u = U[i], v = V[i];\n        int d = edges[i].d;\n        int lay = layer[i];\n        if(lay < 0 || lay > 4) lay = 4; // fallback, shouldn't happen\n\n        bool accept = false;\n        if(cur.same(u,v)){\n            accept = false;\n        }else{\n            if(lay == backup_layer){\n                // Unconditional acceptance for backup layer cross edges ensures connectivity\n                accept = true;\n            }else{\n                // Only accept clearly cheap edges from other layers\n                double mul = beta[lay];\n                if((double)l_i <= mul * (double)d) accept = true;\n            }\n        }\n\n        if(accept){\n            if(!cur.same(u,v)) cur.unite(u,v);\n            cout << 1 << '\\n';\n        }else{\n            cout << 0 << '\\n';\n        }\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int H = 30, W = 30;\n\nstruct Pet { int x,y,t; };\nstruct Human {\n    int x,y;\n    int orient; // 0=horizontal, 1=vertical\n    int line;   // row if horizontal, col if vertical\n    int stand;  // stand row if horizontal, stand col if vertical\n    int L, R;   // sweep range along the axis\n    int dir;    // +1 forward, -1 backward\n};\n\ninline bool inb(int x,int y){ return 1<=x && x<=H && 1<=y && y<=W; }\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N; if(!(cin>>N)) return 0;\n    vector<Pet> pets(N);\n    for(int i=0;i<N;i++){\n        int px,py,pt; cin>>px>>py>>pt;\n        pets[i]={px,py,pt};\n    }\n    int M; cin>>M;\n    vector<Human> humans(M);\n    for(int i=0;i<M;i++){\n        int hx,hy; cin>>hx>>hy;\n        humans[i].x=hx; humans[i].y=hy;\n        humans[i].orient=0; humans[i].line=6; humans[i].stand=5;\n        humans[i].L=1; humans[i].R=W; humans[i].dir=+1;\n    }\n\n    vector<vector<bool>> blocked(H+1, vector<bool>(W+1,false));\n    vector<vector<int>> petCnt(H+1, vector<int>(W+1,0));\n    for(auto &p: pets) petCnt[p.x][p.y]++;\n\n    auto line_pet_score = [&](int orient, int line, int L, int R)->int{\n        int score=0;\n        if(orient==0){\n            for(int y=L;y<=R;y++){\n                int x=line; if(!inb(x,y)) continue;\n                score += petCnt[x][y]*3; // stronger weight on exact cells\n                static int dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};\n                for(int k=0;k<4;k++){\n                    int nx=x+dx[k], ny=y+dy[k];\n                    if(inb(nx,ny)) score += (petCnt[nx][ny]>0);\n                }\n            }\n        }else{\n            for(int x=L;x<=R;x++){\n                int y=line; if(!inb(x,y)) continue;\n                score += petCnt[x][y]*3;\n                static int dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};\n                for(int k=0;k<4;k++){\n                    int nx=x+dx[k], ny=y+dy[k];\n                    if(inb(nx,ny)) score += (petCnt[nx][ny]>0);\n                }\n            }\n        }\n        return score;\n    };\n\n    auto segment_pet_score = [&](int orient, int line, int L, int R)->int{\n        // lighter/faster: just sum exact cells\n        int s=0;\n        if(orient==0){ for(int y=L;y<=R;y++) s+= petCnt[line][y]; }\n        else { for(int x=L;x<=R;x++) s+= petCnt[x][line]; }\n        return s;\n    };\n\n    // Build candidate lines: rows and cols near bases\n    vector<int> bases = {6,12,18,24};\n    struct Candidate { int orient, line; };\n    vector<Candidate> cands;\n    for(int r: bases) cands.push_back({0,r});\n    for(int c: bases) cands.push_back({1,c});\n\n    // Greedy assignment: distribute humans to candidates minimizing pet score and distance\n    vector<int> assignedIdx(M, -1);\n    vector<int> candLoad(cands.size(), 0);\n    int sweepLen = 10;\n    for(int i=0;i<M;i++){\n        int bestJ=-1, bestScore=INT_MAX;\n        for(int j=0;j<(int)cands.size();j++){\n            int orient=cands[j].orient, line=cands[j].line;\n            int stand = line-1; if(stand<1) stand=line+1;\n            int L, R;\n            if(orient==0){\n                int hy=humans[i].y;\n                L = max(1, hy - sweepLen/2);\n                R = min(W, L + sweepLen - 1);\n                L = max(1, min(L, W - sweepLen + 1));\n                int sc = line_pet_score(orient, line, L, R) + abs(humans[i].x - stand) + candLoad[j]*50;\n                if(sc < bestScore){ bestScore=sc; bestJ=j; }\n            }else{\n                int hx=humans[i].x;\n                L = max(1, hx - sweepLen/2);\n                R = min(H, L + sweepLen - 1);\n                L = max(1, min(L, H - sweepLen + 1));\n                int sc = line_pet_score(orient, line, L, R) + abs(humans[i].y - stand) + candLoad[j]*50;\n                if(sc < bestScore){ bestScore=sc; bestJ=j; }\n            }\n        }\n        assignedIdx[i]=bestJ;\n        candLoad[bestJ]++;\n    }\n\n    // Initialize each human according to assignment\n    for(int i=0;i<M;i++){\n        int j=assignedIdx[i];\n        int orient=cands[j].orient, line=cands[j].line;\n        humans[i].orient=orient; humans[i].line=line;\n        int stand=line-1; if(stand<1) stand=line+1;\n        humans[i].stand=stand;\n        if(orient==0){\n            int hy=humans[i].y;\n            int L = max(1, hy - sweepLen/2);\n            int R = min(W, L + sweepLen - 1);\n            L = max(1, min(L, W - sweepLen + 1));\n            humans[i].L=L; humans[i].R=R;\n            humans[i].dir = (abs(hy - L) <= abs(hy - R)) ? +1 : -1;\n        }else{\n            int hx=humans[i].x;\n            int L = max(1, hx - sweepLen/2);\n            int R = min(H, L + sweepLen - 1);\n            L = max(1, min(L, H - sweepLen + 1));\n            humans[i].L=L; humans[i].R=R;\n            humans[i].dir = (abs(hx - L) <= abs(hx - R)) ? +1 : -1;\n        }\n    }\n\n    auto safe_to_block = [&](int tx,int ty, const vector<Human>& hs)->bool{\n        if(!inb(tx,ty)) return false;\n        if(blocked[tx][ty]) return false;\n        if(petCnt[tx][ty]>0) return false;\n        // cannot choose a square that contains humans at start of turn\n        for(const auto& h: hs) if(h.x==tx && h.y==ty) return false;\n        // cannot choose a square whose adjacent square contains a pet\n        static const int dx[4]={-1,1,0,0};\n        static const int dy[4]={0,0,-1,1};\n        for(int k=0;k<4;k++){\n            int nx=tx+dx[k], ny=ty+dy[k];\n            if(inb(nx,ny) && petCnt[nx][ny]>0) return false;\n        }\n        return true;\n    };\n\n    auto pet_within2 = [&](int tx,int ty)->bool{\n        for(int dx=-2; dx<=2; dx++){\n            for(int dy=-2; dy<=2; dy++){\n                if(abs(dx)+abs(dy) > 2) continue;\n                int nx=tx+dx, ny=ty+dy;\n                if(inb(nx,ny) && petCnt[nx][ny]>0) return true;\n            }\n        }\n        return false;\n    };\n\n    auto blocked_ratio = [&](const Human& h)->double{\n        int tot=0, b=0;\n        if(h.orient==0){\n            for(int y=h.L; y<=h.R; y++){ tot++; if(blocked[h.line][y]) b++; }\n        }else{\n            for(int x=h.L; x<=h.R; x++){ tot++; if(blocked[x][h.line]) b++; }\n        }\n        if(tot==0) return 0.0;\n        return (double)b / tot;\n    };\n\n    for(int turn=0; turn<300; turn++){\n        string actions(M, '.');\n        bool gapPhase = (turn >= 80); // start closing earlier\n\n        // Adaptive sweep extension if segment almost done\n        for(int i=0;i<M;i++){\n            auto &h = humans[i];\n            if(blocked_ratio(h) >= 0.8){\n                if(h.orient==0){\n                    // extend toward side with fewer pets by up to 4\n                    int more = 4;\n                    int leftScore = (h.L>1)? segment_pet_score(0, h.line, max(1,h.L-more), h.L-1) : 1e9;\n                    int rightScore = (h.R<W)? segment_pet_score(0, h.line, h.R+1, min(W,h.R+more)) : 1e9;\n                    if(leftScore < rightScore && h.L>1) h.L = max(1, h.L - min(more, h.L-1));\n                    else if(h.R<W) h.R = min(W, h.R + min(more, W-h.R));\n                }else{\n                    int more=4;\n                    int upScore = (h.L>1)? segment_pet_score(1, h.line, max(1,h.L-more), h.L-1) : 1e9;\n                    int downScore = (h.R<H)? segment_pet_score(1, h.line, h.R+1, min(H,h.R+more)) : 1e9;\n                    if(upScore < downScore && h.L>1) h.L = max(1, h.L - min(more, h.L-1));\n                    else if(h.R<H) h.R = min(H, h.R + min(more, H-h.R));\n                }\n            }\n        }\n\n        // Propose actions\n        for(int i=0;i<M;i++){\n            auto &h = humans[i];\n            if(h.orient==0){\n                // Align to stand row\n                if(h.x != h.stand){\n                    if(h.x > h.stand && inb(h.x-1,h.y) && !blocked[h.x-1][h.y]) { actions[i]='U'; continue; }\n                    if(h.x < h.stand && inb(h.x+1,h.y) && !blocked[h.x+1][h.y]) { actions[i]='D'; continue; }\n                    actions[i]='.'; continue;\n                }\n                // Move within segment\n                if(h.y < h.L){\n                    if(!blocked[h.x][h.y+1]) { actions[i]='R'; continue; }\n                    actions[i]='.'; continue;\n                }\n                if(h.y > h.R){\n                    if(!blocked[h.x][h.y-1]) { actions[i]='L'; continue; }\n                    actions[i]='.'; continue;\n                }\n                // Try to block at current column if safe and not too close to pets\n                {\n                    int tx=h.line, ty=h.y;\n                    char place = (h.stand < h.line ? 'd' : 'u');\n                    if(safe_to_block(tx,ty, humans) && !pet_within2(tx,ty)){\n                        actions[i]=place; continue;\n                    }\n                }\n                // Door-closing or search for nearby safe target, move toward it\n                int rad = gapPhase ? 4 : 2;\n                int bestDy = 1e9, bestCy=-1, bestAdj=-1;\n                for(int dy=-rad; dy<=rad; dy++){\n                    int cy = h.y + dy;\n                    if(cy < h.L || cy > h.R) continue;\n                    int tx=h.line, ty=cy;\n                    if(!inb(tx,ty) || blocked[tx][ty]) continue;\n                    if(!safe_to_block(tx,ty, humans) || pet_within2(tx,ty)) continue;\n                    int adjBlocked = 0;\n                    if(inb(tx,ty-1) && blocked[tx][ty-1]) adjBlocked++;\n                    if(inb(tx,ty+1) && blocked[tx][ty+1]) adjBlocked++;\n                    int ad = abs(dy);\n                    if(adjBlocked > bestAdj || (adjBlocked==bestAdj && ad < bestDy)){\n                        bestAdj=adjBlocked; bestDy=ad; bestCy=cy;\n                    }\n                }\n                if(bestCy!=-1){\n                    if(bestCy > h.y && !blocked[h.x][h.y+1]) { actions[i]='R'; continue; }\n                    if(bestCy < h.y && !blocked[h.x][h.y-1]) { actions[i]='L'; continue; }\n                    actions[i]='.'; continue;\n                }\n                // Sweep along\n                if(h.dir>0){\n                    if(h.y < h.R && !blocked[h.x][h.y+1]) actions[i]='R';\n                    else {\n                        h.dir=-1;\n                        if(h.y > h.L && !blocked[h.x][h.y-1]) actions[i]='L';\n                        else actions[i]='.';\n                    }\n                }else{\n                    if(h.y > h.L && !blocked[h.x][h.y-1]) actions[i]='L';\n                    else {\n                        h.dir=+1;\n                        if(h.y < h.R && !blocked[h.x][h.y+1]) actions[i]='R';\n                        else actions[i]='.';\n                    }\n                }\n            }else{\n                // vertical\n                if(h.y != h.stand){\n                    if(h.y > h.stand && inb(h.x,h.y-1) && !blocked[h.x][h.y-1]) { actions[i]='L'; continue; }\n                    if(h.y < h.stand && inb(h.x,h.y+1) && !blocked[h.x][h.y+1]) { actions[i]='R'; continue; }\n                    actions[i]='.'; continue;\n                }\n                if(h.x < h.L){\n                    if(!blocked[h.x+1][h.y]) { actions[i]='D'; continue; }\n                    actions[i]='.'; continue;\n                }\n                if(h.x > h.R){\n                    if(!blocked[h.x-1][h.y]) { actions[i]='U'; continue; }\n                    actions[i]='.'; continue;\n                }\n                {\n                    int tx=h.x, ty=h.line;\n                    char place = (h.stand < h.line ? 'r' : 'l');\n                    if(safe_to_block(tx,ty, humans) && !pet_within2(tx,ty)){\n                        actions[i]=place; continue;\n                    }\n                }\n                int rad = gapPhase ? 4 : 2;\n                int bestDx = 1e9, bestCx=-1, bestAdj=-1;\n                for(int dx=-rad; dx<=rad; dx++){\n                    int cx = h.x + dx;\n                    if(cx < h.L || cx > h.R) continue;\n                    int tx=cx, ty=h.line;\n                    if(!inb(tx,ty) || blocked[tx][ty]) continue;\n                    if(!safe_to_block(tx,ty, humans) || pet_within2(tx,ty)) continue;\n                    int adjBlocked = 0;\n                    if(inb(tx-1,ty) && blocked[tx-1][ty]) adjBlocked++;\n                    if(inb(tx+1,ty) && blocked[tx+1][ty]) adjBlocked++;\n                    int ad = abs(dx);\n                    if(adjBlocked > bestAdj || (adjBlocked==bestAdj && ad < bestDx)){\n                        bestAdj=adjBlocked; bestDx=ad; bestCx=cx;\n                    }\n                }\n                if(bestCx!=-1){\n                    if(bestCx > h.x && !blocked[h.x+1][h.y]) { actions[i]='D'; continue; }\n                    if(bestCx < h.x && !blocked[h.x-1][h.y]) { actions[i]='U'; continue; }\n                    actions[i]='.'; continue;\n                }\n                if(h.dir>0){\n                    if(h.x < h.R && !blocked[h.x+1][h.y]) actions[i]='D';\n                    else { h.dir=-1; if(h.x > h.L && !blocked[h.x-1][h.y]) actions[i]='U'; else actions[i]='.'; }\n                }else{\n                    if(h.x > h.L && !blocked[h.x-1][h.y]) actions[i]='U';\n                    else { h.dir=+1; if(h.x < h.R && !blocked[h.x+1][h.y]) actions[i]='D'; else actions[i]='.'; }\n                }\n            }\n        }\n\n        // Prevent moving into a cell that will be blocked this turn\n        vector<vector<bool>> willBlock(H+1, vector<bool>(W+1,false));\n        for(int i=0;i<M;i++){\n            char c=actions[i];\n            if(c=='u'||c=='d'||c=='l'||c=='r'){\n                int tx=humans[i].x, ty=humans[i].y;\n                if(c=='u') tx--; else if(c=='d') tx++; else if(c=='l') ty--; else if(c=='r') ty++;\n                if(inb(tx,ty)) willBlock[tx][ty]=true;\n            }\n        }\n        for(int i=0;i<M;i++){\n            char c=actions[i];\n            if(c=='U'||c=='D'||c=='L'||c=='R'){\n                int nx=humans[i].x, ny=humans[i].y;\n                if(c=='U') nx--; else if(c=='D') nx++; else if(c=='L') ny--; else if(c=='R') ny++;\n                if(inb(nx,ny) && willBlock[nx][ny]) actions[i]='.';\n            }\n        }\n\n        // Output\n        cout<<actions<<\"\\n\";\n        cout.flush();\n\n        // Apply blocks\n        for(int i=0;i<M;i++){\n            char c=actions[i];\n            if(c=='u'||c=='d'||c=='l'||c=='r'){\n                int tx=humans[i].x, ty=humans[i].y;\n                if(c=='u') tx--; else if(c=='d') tx++; else if(c=='l') ty--; else if(c=='r') ty++;\n                if(inb(tx,ty)) blocked[tx][ty]=true;\n            }\n        }\n        // Apply moves\n        for(int i=0;i<M;i++){\n            char c=actions[i];\n            int nx=humans[i].x, ny=humans[i].y;\n            if(c=='U') nx--; else if(c=='D') nx++; else if(c=='L') ny--; else if(c=='R') ny++;\n            if(inb(nx,ny) && !blocked[nx][ny]){ humans[i].x=nx; humans[i].y=ny; }\n        }\n\n        // Read pets and update\n        vector<string> pm(N);\n        for(int i=0;i<N;i++) cin>>pm[i];\n        for(int x=1;x<=H;x++) for(int y=1;y<=W;y++) petCnt[x][y]=0;\n        for(int i=0;i<N;i++){\n            for(char c: pm[i]){\n                int nx=pets[i].x, ny=pets[i].y;\n                if(c=='U') nx--; else if(c=='D') nx++; else if(c=='L') ny--; else if(c=='R') ny++;\n                if(inb(nx,ny)) { pets[i].x=nx; pets[i].y=ny; }\n            }\n            petCnt[pets[i].x][pets[i].y]++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si,sj,ti,tj;\n    double p;\n    if(!(cin>>si>>sj>>ti>>tj>>p)) return 0;\n    vector<string> h(20), v(19);\n    for(int i=0;i<20;i++){\n        cin>>h[i];\n    }\n    for(int i=0;i<19;i++){\n        cin>>v[i];\n    }\n    auto inb = [](int x,int y){ return 0<=x && x<20 && 0<=y && y<20; };\n    auto can_move = [&](int x,int y,int nx,int ny)->bool{\n        if(!inb(nx,ny)) return false;\n        if(nx==x && ny==y+1){\n            return h[x][y]=='0';\n        }\n        if(nx==x && ny==y-1){\n            return h[x][y-1]=='0';\n        }\n        if(nx==x+1 && ny==y){\n            return v[x][y]=='0';\n        }\n        if(nx==x-1 && ny==y){\n            return v[x-1][y]=='0';\n        }\n        return false;\n    };\n    // BFS shortest path\n    const int N=20;\n    vector<vector<int>> dist(N, vector<int>(N, INT_MAX));\n    vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj]=0;\n    q.push({si,sj});\n    int dx[4]={-1,1,0,0};\n    int dy[4]={0,0,-1,1};\n    char dc[4] = {'U','D','L','R'};\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        if(x==ti && y==tj) break;\n        for(int d=0;d<4;d++){\n            int nx=x+dx[d], ny=y+dy[d];\n            if(!inb(nx,ny)) continue;\n            if(!can_move(x,y,nx,ny)) continue;\n            if(dist[nx][ny] > dist[x][y] + 1){\n                dist[nx][ny] = dist[x][y] + 1;\n                par[nx][ny] = {x,y};\n                q.push({nx,ny});\n            }\n        }\n    }\n    // Reconstruct path\n    vector<pair<int,int>> path;\n    int cx=ti, cy=tj;\n    while(!(cx==si && cy==sj) && cx!=-1){\n        path.push_back({cx,cy});\n        auto pr = par[cx][cy];\n        cx = pr.first; cy = pr.second;\n    }\n    path.push_back({si,sj});\n    reverse(path.begin(), path.end());\n    // If BFS somehow fails (shouldn't), fallback to simple greedy without walls\n    vector<char> dirs;\n    if((int)path.size()>=2){\n        for(size_t k=1;k<path.size();k++){\n            int x0=path[k-1].first, y0=path[k-1].second;\n            int x1=path[k].first, y1=path[k].second;\n            if(x1==x0-1 && y1==y0) dirs.push_back('U');\n            else if(x1==x0+1 && y1==y0) dirs.push_back('D');\n            else if(x1==x0 && y1==y0-1) dirs.push_back('L');\n            else if(x1==x0 && y1==y0+1) dirs.push_back('R');\n        }\n    }else{\n        // fallback: straight moves\n        int x=si,y=sj;\n        while(x>ti) { dirs.push_back('U'); x--; }\n        while(x<ti) { dirs.push_back('D'); x++; }\n        while(y>tj) { dirs.push_back('L'); y--; }\n        while(y<tj) { dirs.push_back('R'); y++; }\n    }\n    int D = (int)dirs.size();\n    if(D==0){\n        cout << \"\\n\";\n        return 0;\n    }\n    // Choose repetition factor r\n    // target epsilon for failing to advance on a block: p^r <= 0.02\n    auto safe_ceil = [](double x)->int{\n        int k = (int)ceil(x - 1e-12);\n        return k;\n    };\n    int r_cap;\n    if(p>=1.0-1e-12) r_cap = 8;\n    else {\n        double num = log(0.02);\n        double den = log(p);\n        int rc = safe_ceil(num/den); // since den<0, this is positive\n        r_cap = max(2, min(8, rc));\n    }\n    int r_max = max(1, 200 / max(1, D));\n    int r = min(r_max, r_cap);\n    // Build output\n    string out;\n    out.reserve(200);\n    auto append_repeats = [&](const vector<char>& P, int rep){\n        for(char c: P){\n            for(int k=0;k<rep;k++){\n                if((int)out.size()<200) out.push_back(c);\n            }\n        }\n    };\n    append_repeats(dirs, r);\n    // Add extra full-path copies (unrepeated) to fill up to near 200\n    while((int)out.size() + D <= 200){\n        for(char c: dirs){\n            if((int)out.size()<200) out.push_back(c);\n        }\n    }\n    // If still too short and we have a bit of space, add prefix of path\n    int rem = 200 - (int)out.size();\n    for(int i=0;i<rem && i<D;i++) out.push_back(dirs[i]);\n\n    cout << out << \"\\n\";\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int H = 30, W = 30;\nstatic const int di4[4] = {0,-1,0,1};\nstatic const int dj4[4] = {-1,0,1,0};\n\n// Base to mapping for tile types 0..7 as per statement.\nint base_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// to_rot[t][r][d]: with tile type t rotated r times CCW, entering from direction d, output direction or -1.\nint to_rot[8][4][4];\n\ninline int mod4(int x){ x%=4; if(x<0)x+=4; return x; }\n\nstruct Solver {\n    array<array<int, W>, H> t;\n    array<array<int, W>, H> r;         // current rotations\n    array<array<int, W>, H> best_r;\n    array<array<int, W>, H> tmp_r;\n\n    // desired outgoing direction for each entering direction\n    array<array<array<int,4>, W>, H> desired_to;\n\n    int proxyScore = 0;\n\n    mt19937 rng;\n\n    Solver(): rng(712367) {}\n\n    void precompute_to_rot() {\n        for(int tt=0; tt<8; ++tt){\n            for(int rot=0; rot<4; ++rot){\n                for(int d=0; d<4; ++d){\n                    int din = mod4(d - rot);\n                    int e = base_to_[tt][din];\n                    if(e==-1) to_rot[tt][rot][d] = -1;\n                    else to_rot[tt][rot][d] = mod4(e + rot);\n                }\n            }\n        }\n    }\n\n    void read_input() {\n        for(int i=0;i<H;++i){\n            string s; cin>>s;\n            for(int j=0;j<W;++j){\n                t[i][j] = s[j]-'0';\n            }\n        }\n    }\n\n    // Build desired_to by selecting a pattern id\n    // pattern 0: two vortices (left/right)\n    // pattern 1: single center vortex\n    // pattern 2: horizontal ring (prefer left/right flow loop)\n    // pattern 3: vertical ring\n    // pattern 4: four quadrants vortices\n    // pattern 5: serpentine sweeping rows\n    void build_desired(int pattern) {\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                for(int d=0; d<4; ++d) desired_to[i][j][d]=2; // default right\n            }\n        }\n        auto pick_card = [&](double ti, double tj)->int{\n            static const int vx[4] = {0,-1,0,1};\n            static const int vy[4] = {-1,0,1,0};\n            int bestd = 0;\n            double bestdot = -1e100;\n            for(int d=0; d<4; ++d){\n                double dot = ti*vx[d] + tj*vy[d];\n                if(dot > bestdot){ bestdot=dot; bestd=d; }\n            }\n            return bestd;\n        };\n        if(pattern==0){ // two vortices\n            double c1i = 14.5, c1j = 7.5;\n            double c2i = 14.5, c2j = 22.5;\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    double ci, cj;\n                    if(j < W/2) { ci=c1i; cj=c1j; }\n                    else { ci=c2i; cj=c2j; }\n                    double pi = i+0.5, pj=j+0.5;\n                    double ui = pi - ci, uj = pj - cj;\n                    double ti = -uj, tj = ui; // CCW tangent\n                    int dsel = pick_card(ti,tj);\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else if(pattern==1){ // single center vortex\n            double ci = 14.5, cj = 14.5;\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    double pi = i+0.5, pj=j+0.5;\n                    double ui = pi - ci, uj = pj - cj;\n                    double ti = -uj, tj = ui;\n                    int dsel = pick_card(ti,tj);\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else if(pattern==2){ // horizontal ring\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int dsel = (i%2==0)?2:0; // even rows go right, odd left\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else if(pattern==3){ // vertical ring\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int dsel = (j%2==0)?3:1; // even cols go down, odd up\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else if(pattern==4){ // four quadrants vortices\n            double ci1=7.5,cj1=7.5, ci2=7.5,cj2=21.5, ci3=21.5,cj3=7.5, ci4=21.5,cj4=21.5;\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    double ci, cj;\n                    if(i<15 && j<15){ ci=ci1; cj=cj1; }\n                    else if(i<15){ ci=ci2; cj=cj2; }\n                    else if(j<15){ ci=ci3; cj=cj3; }\n                    else { ci=ci4; cj=cj4; }\n                    double pi = i+0.5, pj=j+0.5;\n                    double ui = pi - ci, uj = pj - cj;\n                    double ti = -uj, tj = ui;\n                    int dsel = pick_card(ti,tj);\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        } else { // serpentine with bias to loop around borders\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int dsel;\n                    if(i==0) dsel = 2;\n                    else if(i==H-1) dsel = 0;\n                    else dsel = (i%2==0)?2:0;\n                    for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n                }\n            }\n        }\n    }\n\n    int tile_local_score(int i,int j,int rot, const array<array<int,W>,H>& rotAssign){\n        int sc = 0;\n        for(int d=0; d<4; ++d){\n            int e = to_rot[t[i][j]][rot][d];\n            if(e==-1){ sc -= 2; continue; }\n            if(e == desired_to[i][j][d]) sc += 1;\n            int ni = i + di4[e], nj = j + dj4[e];\n            if(ni<0||ni>=H||nj<0||nj>=W) sc -= 3;\n            else {\n                // neighbor tentative consistency\n                int need = (e+2)&3;\n                int ne = to_rot[t[ni][nj]][rotAssign[ni][nj]][need];\n                if(ne == need) sc += 1;\n            }\n        }\n        return sc;\n    }\n\n    void initial_assignment() {\n        // simple greedy with a couple of sweeps to incorporate neighbor consistency\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                int bestRot=0, bestSc = INT_MIN;\n                for(int rot=0; rot<4; ++rot){\n                    int sc = 0;\n                    for(int d=0; d<4; ++d){\n                        int e = to_rot[t[i][j]][rot][d];\n                        if(e==-1){ sc -= 2; continue; }\n                        if(e == desired_to[i][j][d]) sc += 1;\n                        int ni = i + di4[e], nj = j + dj4[e];\n                        if(ni<0||ni>=H||nj<0||nj>=W) sc -= 3;\n                    }\n                    if(sc > bestSc){\n                        bestSc = sc; bestRot = rot;\n                    }\n                }\n                r[i][j] = bestRot;\n            }\n        }\n        // a few refinement sweeps\n        for(int it=0; it<2; ++it){\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int cur = r[i][j];\n                    int bestRot = cur, bestSc = tile_local_score(i,j,cur,r);\n                    for(int rot=0; rot<4; ++rot){\n                        if(rot==cur) continue;\n                        int sc = tile_local_score(i,j,rot,r);\n                        if(sc > bestSc){ bestSc = sc; bestRot = rot; }\n                    }\n                    r[i][j] = bestRot;\n                }\n            }\n        }\n    }\n\n    // Edge match proxy: bidirectional usability across an edge\n    inline int edge_match_at(int i,int j,int d) {\n        int ni = i + di4[d], nj = j + dj4[d];\n        if(ni<0||ni>=H||nj<0||nj>=W) return 0;\n        // A entering from opposite of edge, out to the edge\n        int Ato = to_rot[t[i][j]][r[i][j]][(d+2)&3];\n        if(Ato != d) return 0;\n        // B entering from its opposite of edge, out back along the edge\n        int Bd = (d+2)&3;\n        int Bto = to_rot[t[ni][nj]][r[ni][nj]][(Bd+2)&3]; // careful: entering from opposite of the edge at B is actually d (from A to B). For symmetric, use:\n        // Correct: for B, entering from opposite direction of edge from its perspective is d (from its neighbor). The pair that forms the straight across the shared edge is:\n        // If we cross edge between A and B, then at B the entering direction is (d+2)%4. To continue across back to A, B should output (d+2)%4 (backwards), but for a loop we need B to accept from (d+2) and send back (d+2). However, to ensure the edge can be traversed both ways by trains coming from both sides, we check both A->B and B->A. We'll implement that fully below outside this function for accuracy.\n        (void)Bto;\n        return 1; // placeholder, not used\n    }\n\n    // Proper undirected edge usability: both directions usable\n    inline int edge_bidirected_usable(int ai,int aj,int d){\n        int bi = ai + di4[d], bj = aj + dj4[d];\n        if(bi<0||bi>=H||bj<0||bj>=W) return 0;\n        // A->B\n        int eA = to_rot[t[ai][aj]][r[ai][aj]][(d+2)&3];\n        if(eA != d) return 0;\n        int eB = to_rot[t[bi][bj]][r[bi][bj]][(d+2)&3];\n        if(eB != (d+2)&3) return 0;\n        // B->A\n        int eB2 = to_rot[t[bi][bj]][r[bi][bj]][(d)&3];\n        if(eB2 != (d+2)&3) return 0;\n        int eA2 = to_rot[t[ai][aj]][r[ai][aj]][(d)&3];\n        if(eA2 != d) return 0;\n        return 1;\n    }\n\n    int compute_proxy_score() {\n        int total = 0;\n        for(int i=0;i<H;++i){\n            for(int j=0;j+1<W;++j){\n                total += edge_bidirected_usable(i,j,2);\n            }\n        }\n        for(int i=0;i+1<H;++i){\n            for(int j=0;j<W;++j){\n                total += edge_bidirected_usable(i,j,3);\n            }\n        }\n        return total;\n    }\n\n    int local_proxy_contrib_cell(int i,int j){\n        int sum=0;\n        if(j>0) sum += edge_bidirected_usable(i,j-1,2);\n        if(j<W-1) sum += edge_bidirected_usable(i,j,2);\n        if(i>0) sum += edge_bidirected_usable(i-1,j,3);\n        if(i<H-1) sum += edge_bidirected_usable(i,j,3);\n        return sum;\n    }\n\n    // Compute top two loop lengths and optionally record states of the loops\n    pair<int,int> compute_top2_loops(vector<pair<int,int>>* bestLoopCells = nullptr, vector<pair<int,int>>* secondLoopCells = nullptr) {\n        vector<vector<array<char,4>>> vis(H, vector<array<char,4>>(W, {0,0,0,0}));\n        int best1=0, best2=0;\n        vector<pair<int,int>> loop1cells, loop2cells;\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                for(int d=0; d<4; ++d){\n                    if(vis[i][j][d]) continue;\n                    int ci=i, cj=j, cd=d;\n                    int steps=0;\n                    // map state to step index\n                    // use array for performance: 3600 states, but we need per-walk storage. Use unordered_map reserved small.\n                    unordered_map<int,int> seen;\n                    seen.reserve(32);\n                    auto enc = [&](int x,int y,int dd){ return ((x*W + y)<<2) | dd; };\n                    vector<tuple<int,int,int>> walk;\n                    while(true){\n                        int key = enc(ci,cj,cd);\n                        if(seen.find(key)!=seen.end()){\n                            int st = seen[key];\n                            int cyc_len = steps - st;\n                            if(cyc_len >= best1){\n                                best2 = best1; loop2cells = loop1cells;\n                                best1 = cyc_len;\n                                loop1cells.clear();\n                                for(int k=st;k<(int)walk.size();++k){\n                                    auto [x,y,dd] = walk[k];\n                                    loop1cells.emplace_back(x,y);\n                                }\n                            } else if(cyc_len > best2){\n                                best2 = cyc_len;\n                                loop2cells.clear();\n                                for(int k=st;k<(int)walk.size();++k){\n                                    auto [x,y,dd] = walk[k];\n                                    loop2cells.emplace_back(x,y);\n                                }\n                            }\n                            break;\n                        }\n                        if(vis[ci][cj][cd]) break;\n                        seen[key] = steps;\n                        walk.emplace_back(ci,cj,cd);\n                        int e = to_rot[t[ci][cj]][r[ci][cj]][cd];\n                        if(e==-1) break;\n                        int ni = ci + di4[e], nj = cj + dj4[e];\n                        if(ni<0||ni>=H||nj<0||nj>=W) break;\n                        int nd = (e+2)&3;\n                        ci=ni; cj=nj; cd=nd;\n                        steps++;\n                    }\n                    // mark visited\n                    for(auto &tp: walk){\n                        int x,y,dd; tie(x,y,dd)=tp;\n                        vis[x][y][dd]=1;\n                    }\n                }\n            }\n        }\n        if(bestLoopCells) *bestLoopCells = loop1cells;\n        if(secondLoopCells) *secondLoopCells = loop2cells;\n        return {best1,best2};\n    }\n\n    // Reinforce tiles along loop cells by choosing rotation that maximizes participation edges\n    void reinforce_along_loops(const vector<pair<int,int>>& loopCells){\n        if(loopCells.empty()) return;\n        // mark cells\n        vector<vector<char>> mark(H, vector<char>(W, 0));\n        for(auto &p: loopCells) mark[p.first][p.second]=1;\n        // try improving rotations on marked cells\n        for(auto &p: loopCells){\n            int i=p.first, j=p.second;\n            int cur = r[i][j];\n            int bestRot = cur;\n            int bestLoc = local_proxy_contrib_cell(i,j);\n            for(int rot=0; rot<4; ++rot){\n                if(rot==cur) continue;\n                int old = r[i][j];\n                r[i][j]=rot;\n                int val = local_proxy_contrib_cell(i,j);\n                if(val > bestLoc){ bestLoc=val; bestRot=rot; }\n                r[i][j]=old;\n            }\n            r[i][j]=bestRot;\n        }\n    }\n\n    // Hill climb / SA\n    void optimize(double timeLimitSec, long long &bestScoreAll, array<array<int,W>,H> &bestRAll){\n        proxyScore = compute_proxy_score();\n        auto top2 = compute_top2_loops();\n        long long bestScore = 1LL*top2.first*top2.second;\n        best_r = r;\n\n        auto start = chrono::high_resolution_clock::now();\n        int iter=0, accepted=0;\n        uniform_real_distribution<double> urd(0.0,1.0);\n\n        while(true){\n            iter++;\n            if((iter & 0x1FFF)==0){\n                auto now = chrono::high_resolution_clock::now();\n                double t = chrono::duration<double>(now - start).count();\n                if(t > timeLimitSec) break;\n            }\n            int i = rng()%H;\n            int j = rng()%W;\n            int cur = r[i][j];\n            int before = local_proxy_contrib_cell(i,j);\n            int bestRot = cur;\n            int bestLocal = before;\n            for(int rot=0; rot<4; ++rot){\n                if(rot==cur) continue;\n                int old = r[i][j];\n                r[i][j] = rot;\n                int after = local_proxy_contrib_cell(i,j);\n                if(after > bestLocal){\n                    bestLocal = after; bestRot = rot;\n                }\n                r[i][j] = old;\n            }\n            int gain = bestLocal - before;\n            // SA acceptance with cooling\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            double frac = min(1.0, elapsed / timeLimitSec);\n            double T0 = 0.5, T1 = 0.02;\n            double temp = T0 * (1.0 - frac) + T1 * frac;\n            bool take = false;\n            if(gain > 0) take = true;\n            else {\n                double prob = exp(gain / max(1e-9, temp));\n                if(urd(rng) < prob) take = true;\n            }\n            if(take){\n                r[i][j] = bestRot;\n                proxyScore += gain;\n                accepted++;\n                if((accepted % 200)==0){\n                    auto p = compute_top2_loops();\n                    long long sc = 1LL*p.first*p.second;\n                    if(sc > bestScore){\n                        bestScore = sc;\n                        best_r = r;\n                    }\n                }\n            }\n        }\n        // Final evaluation and reinforcement\n        auto cells1 = vector<pair<int,int>>(), cells2 = vector<pair<int,int>>();\n        auto p = compute_top2_loops(&cells1, &cells2);\n        long long sc = 1LL*p.first*p.second;\n        if(sc > bestScore){ bestScore = sc; best_r = r; }\n        // reinforce along the two best loops and re-evaluate\n        r = best_r;\n        reinforce_along_loops(cells1);\n        reinforce_along_loops(cells2);\n        auto p2 = compute_top2_loops();\n        long long sc2 = 1LL*p2.first*p2.second;\n        if(sc2 > bestScore){ bestScore = sc2; best_r = r; }\n\n        if(bestScore > bestScoreAll){\n            bestScoreAll = bestScore;\n            bestRAll = best_r;\n        }\n        // restore best for further usage\n        r = best_r;\n    }\n\n    void solve() {\n        precompute_to_rot();\n        read_input();\n\n        long long globalBestScore = -1;\n        array<array<int,W>,H> globalBestR;\n\n        // Try several patterns with limited time shares\n        const int PATTERNS[6] = {0,1,2,3,4,5};\n        double totalTime = 1.95;\n        double initShare = 0.15; // time for initialization refinements\n        double perPatternTime = (totalTime - initShare) / 6.0;\n\n        auto tstart = chrono::high_resolution_clock::now();\n\n        for(int pid = 0; pid < 6; ++pid){\n            build_desired(PATTERNS[pid]);\n            initial_assignment();\n            // Use a portion of time for this pattern\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - tstart).count();\n            double remaining = max(0.0, totalTime - elapsed);\n            double budget = min(perPatternTime, remaining);\n            if(budget <= 0.0) break;\n            optimize(budget, globalBestScore, globalBestR);\n        }\n\n        // As fallback, if nothing ran (shouldn't happen), compute once\n        if(globalBestScore < 0){\n            build_desired(0);\n            initial_assignment();\n            auto p = compute_top2_loops();\n            globalBestR = r;\n        }\n\n        // Output best rotations as a single line of 900 digits\n        string out; out.reserve(H*W);\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                out.push_back(char('0' + (globalBestR[i][j] & 3)));\n            }\n        }\n        cout << out << \"\\n\";\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver s;\n    s.solve();\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction bits: 1=L, 2=U, 4=R, 8=D\nstatic inline bool matchLR(int a, int b){ return (a & 4) && (b & 1); }\nstatic inline bool matchUD(int a, int b){ return (a & 8) && (b & 2); }\n\nstruct RNG {\n    uint64_t x;\n    RNG(uint64_t seed=712367821) : x(seed) {}\n    uint32_t next(){ x ^= x<<7; x ^= x>>9; return (uint32_t)x; }\n    int randint(int l,int r){ return l + (int)(next() % (uint32_t)(r-l+1)); }\n    double uniform(){ return (next()+0.5)/double(UINT32_MAX); }\n    bool prob(double p){ return uniform() < p; }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, Tlimit;\n    if(!(cin>>N>>Tlimit)) return 0;\n    vector<string> rows(N);\n    for(int i=0;i<N;i++) cin>>rows[i];\n    vector<int> a(N*N);\n    int er=-1, ec=-1;\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            char c = rows[i][j];\n            int v = (c<='9') ? c-'0' : 10 + (c-'a');\n            a[i*N+j]=v;\n            if(v==0){ er=i; ec=j; }\n        }\n    }\n\n    RNG rng(123456789 ^ (uint64_t)chrono::high_resolution_clock::now().time_since_epoch().count());\n    auto inb=[&](int r,int c){ return r>=0 && r<N && c>=0 && c<N; };\n\n    // Matched adjacency arrays\n    vector<char> horiz(N*(N-1),0), vert((N-1)*N,0);\n    auto idxH=[&](int i,int j){ return i*(N-1)+j; };\n    auto idxV=[&](int i,int j){ return i*N+j; };\n\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N-1;j++){\n            int L=a[i*N+j], Rv=a[i*N+j+1];\n            horiz[idxH(i,j)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n    }\n    for(int i=0;i<N-1;i++){\n        for(int j=0;j<N;j++){\n            int U=a[i*N+j], Dv=a[(i+1)*N+j];\n            vert[idxV(i,j)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n    }\n\n    auto recompute_local_edges = [&](int r,int c){\n        if(c-1>=0){\n            int L=a[r*N+(c-1)], Rv=a[r*N+c];\n            horiz[idxH(r,c-1)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n        if(c<N-1){\n            int L=a[r*N+c], Rv=a[r*N+(c+1)];\n            horiz[idxH(r,c)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n        if(r-1>=0){\n            int U=a[(r-1)*N+c], Dv=a[r*N+c];\n            vert[idxV(r-1,c)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n        if(r<N-1){\n            int U=a[r*N+c], Dv=a[(r+1)*N+c];\n            vert[idxV(r,c)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n    };\n\n    auto totalE = [&](){\n        int s=0;\n        for(char v: horiz) s+=v;\n        for(char v: vert)  s+=v;\n        return s;\n    };\n    int E = totalE();\n    int bestE = E; // aspiration\n    int sinceBest = 0;\n\n    // Compute exact local delta in matched edges for swapping empty at (er,ec) with neighbor (nr,nc)\n    auto delta_for_move = [&](int er,int ec,int nr,int nc)->int{\n        int before=0, after=0;\n        auto add_edges = [&](int r,int c,int &acc){\n            if(c-1>=0) acc += horiz[idxH(r,c-1)];\n            if(c<N-1) acc += horiz[idxH(r,c)];\n            if(r-1>=0) acc += vert[idxV(r-1,c)];\n            if(r<N-1) acc += vert[idxV(r,c)];\n        };\n        add_edges(er,ec,before);\n        add_edges(nr,nc,before);\n\n        int pe=er*N+ec, pn=nr*N+nc;\n        int vn=a[pn];\n        auto contrib_cell = [&](int r,int c,int val_at_rc)->int{\n            int s=0;\n            if(c-1>=0){\n                int L = (r*N + c-1 == pe ? vn : (r*N + c-1 == pn ? 0 : a[r*N + c-1]));\n                int Rv = val_at_rc;\n                s += (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n            }\n            if(c<N-1){\n                int L = val_at_rc;\n                int Rv = (r*N + c+1 == pe ? vn : (r*N + c+1 == pn ? 0 : a[r*N + c+1]));\n                s += (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n            }\n            if(r-1>=0){\n                int U = ((r-1)*N + c == pe ? vn : ((r-1)*N + c == pn ? 0 : a[(r-1)*N + c]));\n                int Dv = val_at_rc;\n                s += (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n            }\n            if(r<N-1){\n                int U = val_at_rc;\n                int Dv = ((r+1)*N + c == pe ? vn : ((r+1)*N + c == pn ? 0 : a[(r+1)*N + c]));\n                s += (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n            }\n            return s;\n        };\n        after += contrib_cell(er,ec,vn);\n        after += contrib_cell(nr,nc,0);\n        return after - before;\n    };\n\n    // Potential hint: number of neighbors around destination that could match based on bits\n    auto potential_gain_hint = [&](int nr,int nc)->int{\n        int pn = nr*N+nc;\n        int vn = a[pn];\n        if(vn==0) return 0;\n        int pot=0;\n        if(nc+1<N){\n            int x = a[nr*N + (nc+1)];\n            if(x!=0 && (vn & 4) && (x & 1)) pot++;\n        }\n        if(nc-1>=0){\n            int x = a[nr*N + (nc-1)];\n            if(x!=0 && (vn & 1) && (x & 4)) pot++;\n        }\n        if(nr+1<N){\n            int x = a[(nr+1)*N + nc];\n            if(x!=0 && (vn & 8) && (x & 2)) pot++;\n        }\n        if(nr-1>=0){\n            int x = a[(nr-1)*N + nc];\n            if(x!=0 && (vn & 2) && (x & 8)) pot++;\n        }\n        return pot;\n    };\n\n    const int dr[4]={-1,1,0,0};\n    const int dc[4]={0,0,-1,1};\n    const char dch[4]={'U','D','L','R'};\n    const int revdir[4]={1,0,3,2};\n\n    string moves; moves.reserve(Tlimit);\n    int last_dir = -1;\n\n    auto apply_move = [&](int dir, int dE)->bool{\n        if((int)moves.size() >= Tlimit) return false;\n        int nr=er+dr[dir], nc=ec+dc[dir];\n        int pe=er*N+ec, pn=nr*N+nc;\n        swap(a[pe], a[pn]);\n        recompute_local_edges(er,ec);\n        recompute_local_edges(nr,nc);\n        E += dE;\n        if(E > bestE){ bestE = E; sinceBest = 0; } else sinceBest++;\n        er=nr; ec=nc;\n        moves.push_back(dch[dir]);\n        last_dir = dir;\n        return true;\n    };\n\n    auto t_start = chrono::high_resolution_clock::now();\n    const double time_limit_ms = 2800.0;\n\n    // Parameters\n    const double anneal_start = 0.2;\n    const double anneal_end   = 0.01;\n    int stagnation = 0;\n\n    auto steer_empty_towards = [&](int tr,int tc, int steps){\n        for(int s=0; s<steps; ++s){\n            if((int)moves.size() >= Tlimit) break;\n            int bestd=-1, bestScore=-1e9, bestDelta=-1000;\n            for(int d=0; d<4; ++d){\n                int nr=er+dr[d], nc=ec+dc[d];\n                if(!inb(nr,nc)) continue;\n                int dE = delta_for_move(er,ec,nr,nc);\n                int md_before = abs(er-tr)+abs(ec-tc);\n                int md_after  = abs(nr-tr)+abs(nc-tc);\n                int score = (md_before - md_after)*5 + (dE>=0 ? 10*dE : dE) + potential_gain_hint(nr,nc);\n                if(last_dir!=-1 && revdir[d]==last_dir) score -= 2;\n                if(score > bestScore){\n                    bestScore=score; bestDelta=dE; bestd=d;\n                }\n            }\n            if(bestd==-1) break;\n            if(!apply_move(bestd, bestDelta)) break;\n        }\n    };\n\n    // Try a 2x2 rotation (CW or CCW) on square with top-left at (r,c) if empty is inside\n    auto try_2x2_cycle = [&](int r,int c)->bool{\n        if(r<0 || c<0 || r>=N-1 || c>=N-1) return false;\n        // positions: (r,c) (r,c+1) (r+1,c) (r+1,c+1)\n        // We need empty at one of these; if not, attempt to bring it in with a few steps\n        if(!((er==r || er==r+1) && (ec==c || ec==c+1))){\n            // steer to nearest corner\n            int tr = (er < r ? r : (er > r+1 ? r+1 : er));\n            int tc = (ec < c ? c : (ec > c+1 ? c+1 : ec));\n            steer_empty_towards(tr, tc, 6);\n            if(!((er==r || er==r+1) && (ec==c || ec==c+1))) return false;\n        }\n        // Determine sequence to rotate CW and CCW based on empty location\n        // We'll construct possible sequences as list of dirs length 3\n        vector<vector<int>> seqs;\n        // Predefined cycles when empty at each corner\n        // If empty at (r,c): CW: R,D,L ; CCW: D,R,U\n        if(er==r && ec==c){\n            seqs.push_back({3,1,2}); // R,D,L\n            seqs.push_back({1,3,0}); // D,R,U\n        }else if(er==r && ec==c+1){\n            // empty at (r,c+1): CW: D,L,U ; CCW: L,D,R\n            seqs.push_back({1,2,0});\n            seqs.push_back({2,1,3});\n        }else if(er==r+1 && ec==c){\n            // empty at (r+1,c): CW: U,R,D ; CCW: R,U,L\n            seqs.push_back({0,3,1});\n            seqs.push_back({3,0,2});\n        }else if(er==r+1 && ec==c+1){\n            // empty at (r+1,c+1): CW: L,U,R ; CCW: U,L,D\n            seqs.push_back({2,0,3});\n            seqs.push_back({0,2,1});\n        }\n        // Evaluate each sequence deltaE sum; ensure all moves stay within the 2x2 bounds (they will by construction)\n        int bestIdx=-1, bestGain=-1e9;\n        vector<int> deltas;\n        for(int si=0; si<(int)seqs.size(); ++si){\n            auto seq = seqs[si];\n            int cur_r=er, cur_c=ec;\n            int gain=0;\n            bool ok=true;\n            deltas.clear();\n            for(int d: seq){\n                int nr=cur_r+dr[d], nc=cur_c+dc[d];\n                if(!(nr>=r && nr<=r+1 && nc>=c && nc<=c+1)){ ok=false; break; }\n                int dE = delta_for_move(cur_r,cur_c,nr,nc);\n                gain += dE;\n                deltas.push_back(dE);\n                cur_r=nr; cur_c=nc;\n            }\n            if(ok && gain>bestGain){\n                bestGain=gain; bestIdx=si;\n            }\n        }\n        if(bestIdx==-1 || bestGain<=0) return false;\n        // Apply the best sequence\n        auto seq = seqs[bestIdx];\n        for(int d: seq){\n            if((int)moves.size() >= Tlimit) return true;\n            int dE = delta_for_move(er,ec, er+dr[d], ec+dc[d]);\n            if(!apply_move(d, dE)) return true;\n        }\n        return true;\n    };\n\n    auto tguard = [&](){\n        auto now=chrono::high_resolution_clock::now();\n        double ms=chrono::duration<double, milli>(now - t_start).count();\n        return ms > time_limit_ms;\n    };\n\n    for(int step=0; step<Tlimit; ++step){\n        if((int)moves.size() >= Tlimit) break;\n        if((step & 255)==0){\n            if(tguard()) break;\n        }\n\n        struct Cand{ int dir; int dE; int tie; };\n        vector<Cand> cands;\n        for(int d=0; d<4; ++d){\n            int nr=er+dr[d], nc=ec+dc[d];\n            if(!inb(nr,nc)) continue;\n            int dE = delta_for_move(er,ec,nr,nc);\n            int tie = 0;\n            // center bias for empty\n            tie -= (abs((N-1)/2 - nr) + abs((N-1)/2 - nc));\n            // mild potential hint\n            tie += potential_gain_hint(nr,nc);\n            // avoid immediate reversal slightly\n            if(last_dir!=-1 && revdir[d]==last_dir) tie -= 2;\n            // small jitter\n            tie += (rng.randint(0,3)==0 ? 1 : 0);\n            cands.push_back({d, dE, tie});\n        }\n        if(cands.empty()) break;\n\n        sort(cands.begin(), cands.end(), [&](const Cand& A, const Cand& B){\n            if(A.dE != B.dE) return A.dE > B.dE;\n            return A.tie > B.tie;\n        });\n\n        int chosen = 0;\n        if(cands[0].dE > 0){\n            stagnation = 0;\n            if(last_dir!=-1 && revdir[cands[0].dir]==last_dir && cands.size()>=2 && cands[1].dE==cands[0].dE){\n                chosen = 1;\n            }\n        }else{\n            stagnation++;\n            double progress = (double)step / max(1,Tlimit);\n            double Temp = anneal_start * pow(anneal_end/anneal_start, progress);\n            int k = min((int)cands.size(), 3);\n            vector<double> w(k);\n            double sumw=0;\n            for(int i=0;i<k;i++){\n                double x = cands[i].dE / max(1e-6, Temp);\n                if(x > 12) x = 12;\n                if(x < -12) x = -12;\n                w[i] = exp(x);\n                sumw += w[i];\n            }\n            double r = rng.uniform() * sumw, acc=0;\n            for(int i=0;i<k;i++){ acc += w[i]; if(r <= acc){ chosen = i; break; } }\n\n            // If long stagnation and time remains, attempt 2x2 cycle repair around a random nearby block\n            if(stagnation > 50 && !tguard()){\n                // Try up to few attempts\n                bool applied=false;\n                for(int att=0; att<3 && !applied; ++att){\n                    int r = min(max(er + rng.randint(-1,0), 0), N-2);\n                    int c = min(max(ec + rng.randint(-1,0), 0), N-2);\n                    applied = try_2x2_cycle(r,c);\n                }\n                if(applied){ stagnation = 0; continue; }\n            }\n\n            // occasional directed relocation to center or border\n            if(stagnation > 70 && !tguard()){\n                if(rng.prob(0.5)){\n                    int tr=(N-1)/2, tc=(N-1)/2;\n                    steer_empty_towards(tr, tc, rng.randint(5,9));\n                }else{\n                    int side = rng.randint(0,3);\n                    int tr = (side==0?0: side==1?N-1: rng.randint(0,N-1));\n                    int tc = (side==2?0: side==3?N-1: rng.randint(0,N-1));\n                    steer_empty_towards(tr, tc, rng.randint(5,9));\n                }\n                stagnation = 0;\n                continue;\n            }\n\n            // fallback: short random-walk burst\n            if(stagnation > 40 && rng.prob(0.3)){\n                int L = rng.randint(3,6);\n                for(int t=0; t<L; ++t){\n                    if((int)moves.size() >= Tlimit) break;\n                    vector<int> dirs;\n                    for(int d=0; d<4; ++d){\n                        int nr=er+dr[d], nc=ec+dc[d];\n                        if(!inb(nr,nc)) continue;\n                        if(t>0 && d==revdir[last_dir]) continue;\n                        dirs.push_back(d);\n                    }\n                    if(dirs.empty()){\n                        for(int d=0; d<4; ++d){\n                            int nr=er+dr[d], nc=ec+dc[d];\n                            if(inb(nr,nc)) dirs.push_back(d);\n                        }\n                    }\n                    int d = dirs[rng.randint(0,(int)dirs.size()-1)];\n                    int dE = delta_for_move(er,ec, er+dr[d], ec+dc[d]);\n                    if(!apply_move(d, dE)) break;\n                }\n                stagnation = 0;\n                continue;\n            }\n        }\n\n        if(!apply_move(cands[chosen].dir, cands[chosen].dE)) break;\n    }\n\n    if((int)moves.size() > Tlimit) moves.resize(Tlimit);\n    cout<<moves<<\"\\n\";\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Sig {\n    uint64_t a=0, b=0;\n    bool operator==(Sig const& o) const { return a==o.a && b==o.b; }\n};\nstruct SigHash {\n    size_t operator()(Sig const& s) const noexcept {\n        uint64_t x = s.a ^ (s.b + 0x9E3779B97F4A7C15ULL + (s.a<<6) + (s.a>>2));\n        x ^= (x >> 27);\n        x *= 0x3C79AC492BA7B653ULL;\n        x ^= (x >> 33);\n        x *= 0x1C69B3F74AC4AE35ULL;\n        x ^= (x >> 27);\n        return (size_t)x;\n    }\n};\n\nstruct Point { int x,y; };\nstruct LineParam { int A,B; long long T; };\n\nstatic inline long long dotAB(int A,int B,int x,int y){ return (long long)A*x + (long long)B*y; }\n\nstatic long long egcd(long long a, long long b, long long &x, long long &y){\n    if(b==0){ x = (a>=0?1:-1); y=0; return llabs(a); }\n    long long x1,y1;\n    long long g = egcd(b, a%b, x1, y1);\n    x = y1;\n    y = x1 - (a/b) * y1;\n    return g;\n}\n\nstatic inline void reduce_coprime(int &A, int &B){\n    if(A==0 && B==0){ A=1; B=0; return; }\n    if(A==0){ B = (B>0?1:-1); return; }\n    if(B==0){ A = (A>0?1:-1); return; }\n    int g = std::gcd(abs(A),abs(B));\n    A/=g; B/=g;\n    if(A<0){ A=-A; B=-B; }\n    else if(A==0 && B<0){ B=-B; }\n}\n\nstatic inline pair<long long,long long> clip2(long long x, long long y){\n    auto clip = [](long long v){\n        if(v < -1000000000LL) return -1000000000LL;\n        if(v > 1000000000LL) return 1000000000LL;\n        return v;\n    };\n    return {clip(x), clip(y)};\n}\n\nstatic inline pair<pair<long long,long long>, pair<long long,long long>>\ntwo_points_on_line(int A, int B, long long T){\n    long long x0,y0;\n    long long g = egcd(A,B,x0,y0);\n    if(g<0){ g=-g; x0=-x0; y0=-y0; }\n    long long mul = T / g;\n    __int128 xi = (__int128)x0 * mul;\n    __int128 yi = (__int128)y0 * mul;\n    long long X = (long long)xi;\n    long long Y = (long long)yi;\n    long long kk = 100000;\n    long long X2 = X + (long long)B * kk;\n    long long Y2 = Y - (long long)A * kk;\n    auto p1 = clip2(X,Y);\n    auto p2 = clip2(X2,Y2);\n    if(p1==p2){\n        kk = 1;\n        X2 = X + (long long)B * kk;\n        Y2 = Y - (long long)A * kk;\n        p2 = clip2(X2,Y2);\n        if(p1==p2){\n            kk = 2;\n            X2 = X + (long long)B * kk;\n            Y2 = Y - (long long)A * kk;\n            p2 = clip2(X2,Y2);\n        }\n    }\n    return {p1,p2};\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, K;\n    if(!(cin>>N>>K)) return 0;\n    vector<int> a(11);\n    for(int d=1; d<=10; ++d) cin>>a[d];\n    vector<Point> pts(N);\n    for(int i=0;i<N;++i) cin>>pts[i].x >> pts[i].y;\n\n    // Curated base normals (small, robust)\n    vector<pair<int,int>> baseNormals = {\n        {1,0},{0,1},{1,1},{1,-1},\n        {2,1},{1,2},{2,-1},{1,-2},\n        {3,1},{1,3},{3,2},{2,3},{3,-1},{1,-3},{3,-2},{2,-3},\n        {4,1},{1,4},{4,3},{3,4},{5,2},{2,5}\n    };\n    for(auto &p: baseNormals) reduce_coprime(p.first, p.second);\n    sort(baseNormals.begin(), baseNormals.end());\n    baseNormals.erase(unique(baseNormals.begin(), baseNormals.end()), baseNormals.end());\n\n    vector<Sig> sig(N);\n    unordered_map<Sig, vector<int>, SigHash> cells;\n    vector<int> bd(11,0);\n\n    auto recompute = [&](){\n        cells.clear();\n        cells.reserve(N*2);\n        for(int i=0;i<N;++i) cells[sig[i]].push_back(i);\n        fill(bd.begin(), bd.end(), 0);\n        for(auto &kv : cells){\n            int s = (int)kv.second.size();\n            if(s<=10) bd[s]++;\n        }\n    };\n    recompute();\n\n    vector<LineParam> lines; lines.reserve(K);\n\n    auto all_satisfied = [&](){\n        for(int d=1; d<=10; ++d) if(bd[d] < a[d]) return false;\n        return true;\n    };\n\n    vector<long long> proj; proj.reserve(N);\n\n    int cutsLeft = K;\n    while(cutsLeft>0){\n        if(all_satisfied()) break;\n\n        vector<int> need(11,0);\n        for(int d=1; d<=10; ++d) need[d] = max(0, a[d]-bd[d]);\n\n        // Phases similar to the better version\n        enum Phase { EARLY, MID, LATE } phase;\n        if(cutsLeft > 66) phase = EARLY;\n        else if(cutsLeft > 20) phase = MID;\n        else phase = LATE;\n\n        // Candidate cells: top by size\n        vector<pair<int,Sig>> cands;\n        cands.reserve(cells.size());\n        for(auto &kv : cells) cands.emplace_back((int)kv.second.size(), kv.first);\n        if(cands.empty()) break;\n        sort(cands.begin(), cands.end(), [](auto &L, auto &R){ return L.first > R.first; });\n        int consider = min<int>((int)cands.size(), 16);\n\n        // Demand list\n        vector<int> demandList;\n        for(int d=1; d<=10; ++d) if(need[d]>0) demandList.push_back(d);\n        sort(demandList.begin(), demandList.end(), [&](int u,int v){\n            if(need[u]!=need[v]) return need[u]>need[v];\n            return u<v;\n        });\n        if(demandList.empty()){\n            for(int d=1; d<=10; ++d) demandList.push_back(d);\n        }\n\n        long long bestScore = LLONG_MIN;\n        LineParam bestLine{1,0,0};\n        bool found = false;\n\n        for(int ci=0; ci<consider; ++ci){\n            int s = cands[ci].first;\n            if(s<=1) continue;\n            auto &idxs = cells[cands[ci].second];\n\n            // PCA normals\n            long double meanx=0, meany=0;\n            for(int id : idxs){ meanx += pts[id].x; meany += pts[id].y; }\n            meanx /= s; meany /= s;\n            long double cxx=0,cxy=0,cyy=0;\n            for(int id : idxs){\n                long double dx = (long double)pts[id].x - meanx;\n                long double dy = (long double)pts[id].y - meany;\n                cxx += dx*dx; cxy += dx*dy; cyy += dy*dy;\n            }\n            long double tr = cxx + cyy;\n            long double det = cxx*cyy - cxy*cxy;\n            long double tmp = max((long double)0.0L, tr*tr/4 - det);\n            long double l1 = tr/2 + sqrtl(tmp);\n            long double vx,vy;\n            if(fabsl(cxy) > 1e-14L){ vx = l1 - cyy; vy = cxy; }\n            else { if(cxx >= cyy){ vx=1; vy=0; } else { vx=0; vy=1; } }\n            long double normv = sqrtl(vx*vx + vy*vy);\n            if(normv < 1e-18L){ vx=1; vy=0; normv=1; }\n            vx/=normv; vy/=normv;\n            long double nx1=-vy, ny1=vx;\n            long double nx2= vy, ny2=-vx;\n            auto to_small_int = [&](long double nx,long double ny)->pair<int,int>{\n                long double scale = 12.0L;\n                int A = (int)llround(nx*scale);\n                int B = (int)llround(ny*scale);\n                if(A==0 && B==0){\n                    if(fabsl(nx) >= fabsl(ny)) A = (nx>=0?1:-1);\n                    else B = (ny>=0?1:-1);\n                }\n                reduce_coprime(A,B);\n                if(abs(A)>20 || abs(B)>20){\n                    int g = max(abs(A),abs(B));\n                    int k = (g+19)/20; if(k==0) k=1;\n                    A/=k; B/=k; if(A==0 && B==0){ A=1; B=0; }\n                    reduce_coprime(A,B);\n                }\n                return {A,B};\n            };\n            pair<int,int> pca1 = to_small_int(nx1,ny1);\n            pair<int,int> pca2 = to_small_int(nx2,ny2);\n\n            // Normals to try\n            static vector<pair<int,int>> normals;\n            normals.clear();\n            normals.insert(normals.end(), baseNormals.begin(), baseNormals.end());\n            normals.push_back(pca1);\n            normals.push_back(pca2);\n            sort(normals.begin(), normals.end());\n            normals.erase(unique(normals.begin(), normals.end()), normals.end());\n\n            // Candidate left sizes\n            auto build_Lcands = [&](int s)->vector<int>{\n                vector<int> Lc;\n                if(s>=2){\n                    Lc.push_back(s/2);\n                    Lc.push_back(max(1, s/3));\n                    Lc.push_back(max(1, (2*s)/3));\n                }\n                int take = min(5, (int)demandList.size());\n                for(int i=0;i<take;++i){\n                    int d = demandList[i];\n                    if(d < s) Lc.push_back(d);\n                    if(s-d >= 1 && s-d < s) Lc.push_back(s-d);\n                }\n                if(phase==LATE){\n                    for(int d=1; d<=4; ++d){\n                        if(d < s) Lc.push_back(d);\n                        if(s-d>=1 && s-d<s) Lc.push_back(s-d);\n                    }\n                }\n                for(int &v: Lc){ if(v<1) v=1; if(v>s-1) v=s-1; }\n                sort(Lc.begin(), Lc.end());\n                Lc.erase(unique(Lc.begin(), Lc.end()), Lc.end());\n                return Lc;\n            };\n            auto Lcands = build_Lcands(s);\n\n            for(auto [A,B] : normals){\n                proj.resize(s);\n                for(int i=0;i<s;++i){\n                    const auto &p = pts[idxs[i]];\n                    proj[i] = dotAB(A,B,p.x,p.y);\n                }\n                sort(proj.begin(), proj.end());\n\n                auto get_gap_for_l = [&](int l, long long &vL, long long &vR, int &lChosen)->bool{\n                    if(l<1 || l>=s) return false;\n                    int i = l-1;\n                    long long aL = proj[i], aR = proj[i+1];\n                    if(aL < aR){\n                        vL = aL; vR = aR; lChosen = l; return true;\n                    }\n                    int il = i; while(il>=0 && proj[il]==aL) --il;\n                    int ir = i+1; while(ir<s && proj[ir]==aR) ++ir;\n                    bool ok=false;\n                    long long vL1=0,vR1=0,vL2=0,vR2=0; int l1=-1,l2=-1;\n                    if(il>=0 && proj[il] < proj[il+1]){ vL1=proj[il]; vR1=proj[il+1]; l1=il+1; ok=true; }\n                    if(ir<s && proj[ir-1] < proj[ir]){ vL2=proj[ir-1]; vR2=proj[ir]; l2=ir; ok=true; }\n                    if(!ok) return false;\n                    if(l1==-1){ vL=vL2; vR=vR2; lChosen=l2; }\n                    else if(l2==-1){ vL=vL1; vR=vR1; lChosen=l1; }\n                    else{\n                        int d1 = abs(l1 - l), d2 = abs(l2 - l);\n                        if(d1 < d2 || (d1==d2 && (vR1-vL1) >= (vR2-vL2))){ vL=vL1; vR=vR1; lChosen=l1; }\n                        else { vL=vL2; vR=vR2; lChosen=l2; }\n                    }\n                    return true;\n                };\n\n                for(int lTarget : Lcands){\n                    long long vL, vR; int lChosen;\n                    if(!get_gap_for_l(lTarget, vL, vR, lChosen)) continue;\n                    long long T = (vL + vR) / 2;\n                    int leftSize = lChosen;\n                    int rightSize = s - lChosen;\n\n                    auto minA = [&](int d, int b){ return min(a[d], b); };\n                    long long delta = 0;\n                    if(leftSize<=10) delta += minA(leftSize, bd[leftSize]+1) - minA(leftSize, bd[leftSize]);\n                    if(rightSize<=10) delta += minA(rightSize, bd[rightSize]+1) - minA(rightSize, bd[rightSize]);\n                    if(s<=10) delta += minA(s, bd[s]-1) - minA(s, bd[s]);\n\n                    long long over10Penalty = 0;\n                    if(leftSize>10) over10Penalty -= (phase==LATE ? 2 : (phase==MID ? 1 : 0));\n                    if(rightSize>10) over10Penalty -= (phase==LATE ? 2 : (phase==MID ? 1 : 0));\n\n                    long long overs = 0;\n                    if(leftSize<=10 && bd[leftSize] >= a[leftSize]) overs -= (phase==LATE ? 2 : 1);\n                    if(rightSize<=10 && bd[rightSize] >= a[rightSize]) overs -= (phase==LATE ? 2 : 1);\n\n                    long long bonus = 0;\n                    if(leftSize<=10 && need[leftSize]>0) bonus += (phase==EARLY ? 1 : 2);\n                    if(rightSize<=10 && need[rightSize]>0) bonus += (phase==EARLY ? 1 : 2);\n\n                    long long balance = - llabs(leftSize - rightSize);\n                    if(phase==EARLY) balance *= 2;\n\n                    // protection for needed small s (relaxed in LATE)\n                    bool protect = (s<=10 && bd[s] < a[s] && phase!=LATE);\n                    if(protect && delta <= 0){\n                        bool anyHelp = false;\n                        if(leftSize<=10 && need[leftSize]>0) anyHelp = true;\n                        if(rightSize<=10 && need[rightSize]>0) anyHelp = true;\n                        if(!anyHelp) continue;\n                    }\n\n                    auto lookahead = [&](int size)->int{\n                        if(size<=1) return 0;\n                        int l2 = size/2;\n                        int r2 = size - l2;\n                        int gain = 0;\n                        if(l2<=10 && need[l2]>0) gain++;\n                        if(r2<=10 && need[r2]>0) gain++;\n                        return gain;\n                    };\n                    int la = lookahead(max(leftSize, rightSize));\n\n                    long long score = (delta<<24) + (bonus<<16) + (overs<<12) + (over10Penalty<<10) + (la<<8) + balance;\n\n                    if(phase==EARLY && s > 40){\n                        score += (long long)(-abs(leftSize - rightSize)) * 2;\n                    }\n\n                    if(score > bestScore){\n                        bestScore = score;\n                        bestLine = {A,B,T};\n                        found = true;\n                    }\n                }\n            }\n        }\n\n        if(!found){\n            // Tail fallback: split largest cell toward top need and balance\n            auto &idxs = cells[cands[0].second];\n            int s = (int)idxs.size();\n            int target = 1, bestNeed=0;\n            for(int d=1; d<=10; ++d) if(need[d]>bestNeed){ bestNeed=need[d]; target=d; }\n            vector<int> targets;\n            if(target < s) targets.push_back(target);\n            if(s-target >= 1 && s-target < s) targets.push_back(s-target);\n            targets.push_back(s/2);\n            targets.push_back(max(1, s/3));\n            targets.push_back(max(1, (2*s)/3));\n\n            // PCA normal and axes\n            // Compute PCA\n            long double meanx=0, meany=0;\n            for(int id: idxs){ meanx += pts[id].x; meany += pts[id].y; }\n            meanx/=s; meany/=s;\n            long double cxx=0,cxy=0,cyy=0;\n            for(int id: idxs){\n                long double dx=(long double)pts[id].x-meanx;\n                long double dy=(long double)pts[id].y-meany;\n                cxx+=dx*dx; cxy+=dx*dy; cyy+=dy*dy;\n            }\n            long double tr=cxx+cyy, det=cxx*cyy-cxy*cxy;\n            long double tmp=max((long double)0.0L, tr*tr/4-det);\n            long double l1=tr/2+sqrtl(tmp);\n            long double vx,vy;\n            if(fabsl(cxy)>1e-14L){ vx=l1-cyy; vy=cxy; } else { if(cxx>=cyy){ vx=1; vy=0; } else { vx=0; vy=1; } }\n            long double normv = sqrtl(vx*vx+vy*vy); if(normv<1e-18L){ vx=1; vy=0; normv=1; } vx/=normv; vy/=normv;\n            long double nx=-vy, ny=vx;\n            auto to_small = [&](long double nx,long double ny){ int A=(int)llround(nx*12.0L); int B=(int)llround(ny*12.0L); if(A==0&&B==0)A=1; reduce_coprime(A,B); return pair<int,int>(A,B); };\n            auto pca = to_small(nx,ny);\n            vector<pair<int,int>> normals = { {1,0},{0,1}, pca };\n\n            int A_best=1,B_best=0; long long T_best=0; bool got=false;\n            for(auto [A,B] : normals){\n                proj.resize(s);\n                for(int i=0;i<s;++i) proj[i]=dotAB(A,B,pts[idxs[i]].x, pts[idxs[i]].y);\n                sort(proj.begin(), proj.end());\n                for(int l : targets){\n                    if(l<1 || l>=s) continue;\n                    long long vL = proj[l-1], vR = proj[l];\n                    if(vL==vR){\n                        int il=l-1; while(il>=0 && proj[il]==vL) --il;\n                        int ir=l; while(ir<s && proj[ir]==vR) ++ir;\n                        if(il>=0){ vL=proj[il]; vR=proj[il+1]; }\n                        else if(ir<s){ vL=proj[ir-1]; vR=proj[ir]; }\n                        else continue;\n                    }\n                    long long T=(vL+vR)/2;\n                    A_best=A; B_best=B; T_best=T; got=true; break;\n                }\n                if(got) break;\n            }\n            bestLine = {A_best,B_best,T_best};\n        }\n\n        // Commit line\n        int bitIndex = (int)lines.size();\n        lines.push_back(bestLine);\n        for(int i=0;i<N;++i){\n            long long v = dotAB(bestLine.A, bestLine.B, pts[i].x, pts[i].y);\n            bool left = (v <= bestLine.T);\n            if(bitIndex < 64){\n                if(left) sig[i].a |= (1ULL<<bitIndex);\n            }else{\n                int bi = bitIndex-64;\n                if(left) sig[i].b |= (1ULL<<bi);\n            }\n        }\n        recompute();\n        cutsLeft--;\n    }\n\n    // Output\n    cout << (int)lines.size() << \"\\n\";\n    for(auto &L : lines){\n        auto pp = two_points_on_line(L.A, L.B, L.T);\n        auto [p0, p1] = pp;\n        cout << p0.first << \" \" << p0.second << \" \" << p1.first << \" \" << p1.second << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct P { int x,y; };\n\nstatic inline int64_t w_of(int x,int y,int c){\n    int dx=x-c, dy=y-c;\n    return int64_t(dx)*dx + int64_t(dy)*dy + 1;\n}\n\nstruct Candidate{\n    // rectangle in order: p1=new point, then others around perimeter\n    P p1,p2,p3,p4;\n    int64_t score;\n};\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    vector<P> init(M);\n    for(int i=0;i<M;i++){ cin>>init[i].x>>init[i].y; }\n    int c=(N-1)/2;\n\n    // Occupancy grid\n    vector<vector<char>> occ(N, vector<char>(N, 0));\n    for(auto &p:init) occ[p.x][p.y]=1;\n\n    // Edge usage: used horizontal edges H[y][x] for (x,y)-(x+1,y), x in [0..N-2], y in [0..N-1]\n    vector<vector<char>> usedH(N, vector<char>(N-1, 0));\n    // Vertical edges V[x][y] for (x,y)-(x,y+1), x in [0..N-1], y in [0..N-2]\n    vector<vector<char>> usedV(N, vector<char>(N-1, 0));\n\n    // Maintain list of occupied points per row/col for faster enumeration\n    vector<vector<int>> rows(N), cols(N);\n    auto rebuild_index = [&](){\n        for(int y=0;y<N;y++){ rows[y].clear(); }\n        for(int x=0;x<N;x++){ cols[x].clear(); }\n        for(int x=0;x<N;x++) for(int y=0;y<N;y++) if(occ[x][y]){\n            rows[y].push_back(x);\n            cols[x].push_back(y);\n        }\n        for(int y=0;y<N;y++) sort(rows[y].begin(), rows[y].end());\n        for(int x=0;x<N;x++) sort(cols[x].begin(), cols[x].end());\n    };\n    rebuild_index();\n\n    // Candidate generation full enumeration (axis-aligned):\n    auto build_candidates = [&](vector<Candidate>& out){\n        out.clear();\n        const size_t CAP = 40000;\n        for(int xb=0; xb<N; xb++){\n            for(int yb=0; yb<N; yb++){\n                if(!occ[xb][yb]) continue;\n                const auto& row = rows[yb];\n                const auto& col = cols[xb];\n                if(row.empty() || col.empty()) continue;\n                for(int xa : row){\n                    if(xa==xb) continue;\n                    for(int yc : col){\n                        if(yc==yb) continue;\n                        int xd = xa;\n                        int yd = yc;\n                        if(occ[xd][yd]) continue;\n                        // define rectangle order p1=D, p2=A, p3=B, p4=C:\n                        P D{xd,yd}, A{xa,yb}, B{xb,yb}, C{xb,yc};\n                        // perimeter dot check\n                        auto ok_line = [&](int x1,int y1,int x2,int y2)->bool{\n                            if(x1==x2){\n                                int x=x1;\n                                int ylo=min(y1,y2), yhi=max(y1,y2);\n                                for(int y=ylo; y<=yhi; y++){\n                                    if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                                    if(occ[x][y]) return false;\n                                }\n                            }else if(y1==y2){\n                                int y=y1;\n                                int xlo=min(x1,x2), xhi=max(x1,x2);\n                                for(int x=xlo; x<=xhi; x++){\n                                    if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                                    if(occ[x][y]) return false;\n                                }\n                            }else{\n                                return false;\n                            }\n                            return true;\n                        };\n                        if(!ok_line(D.x,D.y,A.x,A.y)) continue;\n                        if(!ok_line(A.x,A.y,B.x,B.y)) continue;\n                        if(!ok_line(B.x,B.y,C.x,C.y)) continue;\n                        if(!ok_line(C.x,C.y,D.x,D.y)) continue;\n                        // edge overlap check without marking now\n                        auto edges_free = [&]()->bool{\n                            auto check_edge = [&](int x1,int y1,int x2,int y2)->bool{\n                                if(x1==x2){\n                                    int x=x1;\n                                    int ylo=min(y1,y2), yhi=max(y1,y2);\n                                    for(int y=ylo; y<yhi; y++) if(usedV[x][y]) return false;\n                                }else{\n                                    int y=y1;\n                                    int xlo=min(x1,x2), xhi=max(x1,x2);\n                                    for(int x=xlo; x<xhi; x++) if(usedH[y][x]) return false;\n                                }\n                                return true;\n                            };\n                            return check_edge(D.x,D.y,A.x,A.y) && check_edge(A.x,A.y,B.x,B.y)\n                                && check_edge(B.x,B.y,C.x,C.y) && check_edge(C.x,C.y,D.x,D.y);\n                        };\n                        if(!edges_free()) continue;\n                        Candidate cand;\n                        cand.p1=D; cand.p2=A; cand.p3=B; cand.p4=C;\n                        cand.score = w_of(D.x,D.y,c);\n                        out.push_back(cand);\n                        if(out.size() >= CAP) return;\n                    }\n                }\n            }\n        }\n    };\n\n    vector<array<int,8>> answer;\n    answer.reserve(100000);\n\n    auto apply_rect = [&](const Candidate& cand){\n        const P &D=cand.p1, &A=cand.p2, &B=cand.p3, &C=cand.p4;\n        // Mark edges\n        auto mark_edge = [&](int x1,int y1,int x2,int y2){\n            if(x1==x2){\n                int x=x1;\n                int ylo=min(y1,y2), yhi=max(y1,y2);\n                for(int y=ylo; y<yhi; y++) usedV[x][y]=1;\n            }else{\n                int y=y1;\n                int xlo=min(x1,x2), xhi=max(x1,x2);\n                for(int x=xlo; x<xhi; x++) usedH[y][x]=1;\n            }\n        };\n        mark_edge(D.x,D.y,A.x,A.y);\n        mark_edge(A.x,A.y,B.x,B.y);\n        mark_edge(B.x,B.y,C.x,C.y);\n        mark_edge(C.x,C.y,D.x,D.y);\n        // Place dot\n        occ[D.x][D.y]=1;\n        rows[D.y].push_back(D.x);\n        cols[D.x].push_back(D.y);\n        // Record\n        array<int,8> op = {D.x,D.y, A.x,A.y, B.x,B.y, C.x,C.y};\n        answer.push_back(op);\n    };\n\n    // Main greedy loop\n    auto t_start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.8; // seconds\n    int iter = 0;\n    while(true){\n        if(iter % 10 == 0){\n            auto t_now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(t_now - t_start).count();\n            if(elapsed > TIME_LIMIT) break;\n        }\n        if(iter % 50 == 0) rebuild_index();\n\n        vector<Candidate> cands;\n        build_candidates(cands);\n        if(cands.empty()) break;\n        // sort by score descending, minor tiebreaker by perimeter length\n        stable_sort(cands.begin(), cands.end(), [&](const Candidate& a, const Candidate& b){\n            if(a.score != b.score) return a.score > b.score;\n            int per_a = abs(a.p1.x - a.p3.x) + abs(a.p1.y - a.p3.y) + abs(a.p2.x - a.p4.x) + abs(a.p2.y - a.p4.y);\n            int per_b = abs(b.p1.x - b.p3.x) + abs(b.p1.y - b.p3.y) + abs(b.p2.x - b.p4.x) + abs(b.p2.y - b.p4.y);\n            return per_a > per_b;\n        });\n        bool placed = false;\n        for(const auto& cand : cands){\n            const P &D=cand.p1, &A=cand.p2, &B=cand.p3, &C=cand.p4;\n            if(occ[D.x][D.y]) continue;\n            // recheck perimeter cleanliness and edges\n            auto ok_line = [&](int x1,int y1,int x2,int y2)->bool{\n                if(x1==x2){\n                    int x=x1;\n                    int ylo=min(y1,y2), yhi=max(y1,y2);\n                    for(int y=ylo; y<=yhi; y++){\n                        if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                        if(occ[x][y]) return false;\n                    }\n                }else if(y1==y2){\n                    int y=y1;\n                    int xlo=min(x1,x2), xhi=max(x1,x2);\n                    for(int x=xlo; x<=xhi; x++){\n                        if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                        if(occ[x][y]) return false;\n                    }\n                }else{\n                    return false;\n                }\n                return true;\n            };\n            if(!ok_line(D.x,D.y,A.x,A.y)) continue;\n            if(!ok_line(A.x,A.y,B.x,B.y)) continue;\n            if(!ok_line(B.x,B.y,C.x,C.y)) continue;\n            if(!ok_line(C.x,C.y,D.x,D.y)) continue;\n\n            auto edges_free = [&]()->bool{\n                auto check_edge = [&](int x1,int y1,int x2,int y2)->bool{\n                    if(x1==x2){\n                        int x=x1;\n                        int ylo=min(y1,y2), yhi=max(y1,y2);\n                        for(int y=ylo; y<yhi; y++) if(usedV[x][y]) return false;\n                    }else{\n                        int y=y1;\n                        int xlo=min(x1,x2), xhi=max(x1,x2);\n                        for(int x=xlo; x<xhi; x++) if(usedH[y][x]) return false;\n                    }\n                    return true;\n                };\n                return check_edge(D.x,D.y,A.x,A.y) && check_edge(A.x,A.y,B.x,B.y)\n                    && check_edge(B.x,B.y,C.x,C.y) && check_edge(C.x,C.y,D.x,D.y);\n            };\n            if(!edges_free()) continue;\n\n            apply_rect(cand);\n            placed = true;\n            break;\n        }\n        if(!placed) break;\n        iter++;\n    }\n\n    cout<< (int)answer.size() << \"\\n\";\n    for(auto &op: answer){\n        for(int i=0;i<8;i++){\n            if(i) cout<<' ';\n            cout<<op[i];\n        }\n        cout<<\"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Board {\n    static constexpr int H=10, W=10;\n    array<array<int,W>,H> g{};\n    void clear(){ for(int i=0;i<H;i++) for(int j=0;j<W;j++) g[i][j]=0; }\n\n    pair<int,int> place_by_index(int p, int f){\n        int cnt=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                if(g[i][j]==0){\n                    ++cnt;\n                    if(cnt==p){\n                        g[i][j]=f;\n                        return {i,j};\n                    }\n                }\n            }\n        }\n        return {-1,-1};\n    }\n\n    Board tilt(char dir) const {\n        Board b=*this;\n        if(dir=='F'){ // up\n            for(int j=0;j<W;j++){\n                int w=0;\n                for(int i=0;i<H;i++){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        if(i!=w){ b.g[i][j]=0; b.g[w][j]=v; }\n                        ++w;\n                    }\n                }\n            }\n        } else if(dir=='B'){ // down\n            for(int j=0;j<W;j++){\n                int w=H-1;\n                for(int i=H-1;i>=0;i--){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        if(i!=w){ b.g[i][j]=0; b.g[w][j]=v; }\n                        --w;\n                    }\n                }\n            }\n        } else if(dir=='L'){ // left\n            for(int i=0;i<H;i++){\n                int w=0;\n                for(int j=0;j<W;j++){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        if(j!=w){ b.g[i][j]=0; b.g[i][w]=v; }\n                        ++w;\n                    }\n                }\n            }\n        } else { // 'R' right\n            for(int i=0;i<H;i++){\n                int w=W-1;\n                for(int j=W-1;j>=0;j--){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        if(j!=w){ b.g[i][j]=0; b.g[i][w]=v; }\n                        --w;\n                    }\n                }\n            }\n        }\n        return b;\n    }\n\n    bool equals(const Board& o) const {\n        for(int i=0;i<H;i++) for(int j=0;j<W;j++) if(g[i][j]!=o.g[i][j]) return false;\n        return true;\n    }\n};\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    DSU(int n=0): n(n), p(n), r(n,0){ iota(p.begin(), p.end(), 0); }\n    int find(int a){ return p[a]==a?a:p[a]=find(p[a]); }\n    void unite(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a; if(r[a]==r[b]) r[a]++;\n    }\n};\n\nstruct Heuristic {\n    // flavor->anchor\n    array<pair<int,int>,4> anchor;\n    // desired walls\n    array<array<int,4>,4> edgePref{}; // [T,B,L,R]\n\n    // weights\n    int w_adj_same = 7;\n    int w_adj_diff = 2;\n    int w_dist = 1;\n    int w_boundaries = 2;\n    int w_cc = 16;\n    int w_edge = 2;\n    int w_corner = 1;\n    int w_line_seg = 2;\n    int w_wall_line = 4;\n    int w_merge_potential = 1; // reward empty cells adjacent to blobs\n    int w_good_empty_next = 3; // reward empty cells adjacent to next flavor\n\n    // zone assignment\n    int flavorTopLeft=1, flavorTopRight=2, flavorBottom=3;\n    bool bottomRight=false;\n\n    Heuristic(){\n        anchor[1]={0,0}; anchor[2]={0,9}; anchor[3]={9,0};\n        edgePref[1]={1,0,1,0};\n        edgePref[2]={1,0,0,1};\n        edgePref[3]={0,1,1,0};\n    }\n\n    void setup_anchors_by_counts_and_early(const array<int,4>& cnt, const vector<int>& early){\n        array<int,3> ids = {1,2,3};\n        sort(ids.begin(), ids.end(), [&](int a,int b){ return cnt[a]>cnt[b]; });\n        int A=ids[0], B=ids[1], C=ids[2];\n        flavorTopLeft=A; flavorTopRight=B; flavorBottom=C;\n\n        anchor[A]={0,0}; edgePref[A]={1,0,1,0};\n        anchor[B]={0,9}; edgePref[B]={1,0,0,1};\n\n        int earlyTake = min<int>(20, early.size());\n        int earlyA=0, earlyB=0;\n        for(int i=0;i<earlyTake;i++){\n            if(early[i]==A) earlyA++;\n            else if(early[i]==B) earlyB++;\n        }\n        if(earlyB > earlyA){\n            bottomRight = false; // bottom-left\n            anchor[C]={9,0}; edgePref[C]={0,1,1,0};\n        }else{\n            bottomRight = true; // bottom-right\n            anchor[C]={9,9}; edgePref[C]={0,1,0,1};\n        }\n    }\n\n    void nudge_anchors(const Board& b){\n        array<long long,4> si{}, sj{}, cnt{};\n        for(int i=0;i<Board::H;i++){\n            for(int j=0;j<Board::W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                si[v]+=i; sj[v]+=j; cnt[v]++;\n            }\n        }\n        auto clamp = [&](int x,int lo,int hi){ return max(lo, min(hi, x)); };\n        auto zone = [&](int fl)->array<int,4>{\n            if(fl==flavorTopLeft) return array<int,4>{0, 5, 0, 5};\n            if(fl==flavorTopRight) return array<int,4>{0, 5, 4, 9};\n            if(bottomRight) return array<int,4>{4, 9, 4, 9};\n            else return array<int,4>{4, 9, 0, 5};\n        };\n        for(int fl=1; fl<=3; fl++){\n            if(cnt[fl]==0) continue;\n            int ci = int(si[fl]/cnt[fl]);\n            int cj = int(sj[fl]/cnt[fl]);\n            auto z = zone(fl);\n            int ti = clamp(ci, z[0], z[1]);\n            int tj = clamp(cj, z[2], z[3]);\n            auto [ai,aj] = anchor[fl];\n            if(ai < ti) ai++; else if(ai > ti) ai--;\n            if(aj < tj) aj++; else if(aj > tj) aj--;\n            ai = clamp(ai, z[0], z[1]);\n            aj = clamp(aj, z[2], z[3]);\n            anchor[fl] = {ai,aj};\n        }\n    }\n\n    int adj_score(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int same=0, diff=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                if(i+1<H && b.g[i+1][j]){\n                    if(b.g[i+1][j]==v) same++; else diff++;\n                }\n                if(j+1<W && b.g[i][j+1]){\n                    if(b.g[i][j+1]==v) same++; else diff++;\n                }\n            }\n        }\n        return w_adj_same*same - w_adj_diff*diff;\n    }\n\n    int distance_score(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                auto [ai,aj]=anchor[v];\n                sc -= w_dist * (abs(i-ai)+abs(j-aj));\n                int d = abs(i-ai)+abs(j-aj); // fixed: removed extra ')'\n                if(d<=2) sc += w_corner*(3-d);\n            }\n        }\n        return sc;\n    }\n\n    int boundaries_penalty(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int boundaries=0;\n        for(int i=0;i<H;i++){\n            int prev = 0;\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(prev && v && v!=prev) boundaries++;\n                if(v) prev=v;\n            }\n        }\n        for(int j=0;j<W;j++){\n            int prev = 0;\n            for(int i=0;i<H;i++){\n                int v=b.g[i][j];\n                if(prev && v && v!=prev) boundaries++;\n                if(v) prev=v;\n            }\n        }\n        return -w_boundaries * boundaries;\n    }\n\n    int cc_penalty_and_maxcc(const Board& b, int& maxcc_out) const {\n        int H=Board::H, W=Board::W;\n        int F=H*W;\n        DSU dsu(F);\n        auto id = [&](int i,int j){ return i*W + j; };\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                if(i+1<H && b.g[i+1][j]==v) dsu.unite(id(i,j), id(i+1,j));\n                if(j+1<W && b.g[i][j+1]==v) dsu.unite(id(i,j), id(i,j+1));\n            }\n        }\n        array<unordered_map<int,int>,4> compSize;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                int r = dsu.find(id(i,j));\n                compSize[v][r]++;\n            }\n        }\n        int cc = 0;\n        int maxcc = 0;\n        for(int fl=1; fl<=3; fl++){\n            cc += (int)compSize[fl].size();\n            for(auto &kv: compSize[fl]){\n                maxcc = max(maxcc, kv.second);\n            }\n        }\n        maxcc_out = maxcc;\n        return -w_cc * cc;\n    }\n\n    int edge_reward(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                auto pref = edgePref[v];\n                if(i==0) sc += w_edge * pref[0];\n                if(i==H-1) sc += w_edge * pref[1];\n                if(j==0) sc += w_edge * pref[2];\n                if(j==W-1) sc += w_edge * pref[3];\n            }\n        }\n        return sc;\n    }\n\n    int line_segment_reward(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        // rows\n        for(int i=0;i<H;i++){\n            int len=0, col=0;\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(v && v==col) len++;\n                else{\n                    if(col && len>=2) sc += w_line_seg * (len-1);\n                    col=v; len = (v?1:0);\n                }\n            }\n            if(col && len>=2) sc += w_line_seg * (len-1);\n        }\n        // cols\n        for(int j=0;j<W;j++){\n            int len=0, col=0;\n            for(int i=0;i<H;i++){\n                int v=b.g[i][j];\n                if(v && v==col) len++;\n                else{\n                    if(col && len>=2) sc += w_line_seg * (len-1);\n                    col=v; len = (v?1:0);\n                }\n            }\n            if(col && len>=2) sc += w_line_seg * (len-1);\n        }\n        return sc;\n    }\n\n    int wall_line_reward(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        for(int j=0;j<W;j++){\n            if(b.g[0][j]==flavorTopLeft) sc += w_wall_line;\n            if(b.g[0][j]==flavorTopRight) sc += w_wall_line;\n        }\n        for(int i=0;i<H;i++){\n            if(b.g[i][0]==flavorTopLeft) sc += w_wall_line;\n            if(!bottomRight && b.g[i][0]==flavorBottom) sc += w_wall_line;\n        }\n        for(int i=0;i<H;i++){\n            if(b.g[i][W-1]==flavorTopRight) sc += w_wall_line;\n            if(bottomRight && b.g[i][W-1]==flavorBottom) sc += w_wall_line;\n        }\n        for(int j=0;j<W;j++){\n            if(b.g[H-1][j]==flavorBottom) sc += w_wall_line;\n        }\n        return sc;\n    }\n\n    int merge_potential(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        static const int di[4]={-1,1,0,0};\n        static const int dj[4]={0,0,-1,1};\n        int pot=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                if(b.g[i][j]!=0) continue; // empty cell\n                array<int,4> seen{}; // flavors seen around\n                for(int d=0; d<4; d++){\n                    int ni=i+di[d], nj=j+dj[d];\n                    if(ni<0||ni>=H||nj<0||nj>=W) continue;\n                    int v=b.g[ni][nj];\n                    if(v) seen[v]=1;\n                }\n                pot += seen[1]+seen[2]+seen[3];\n            }\n        }\n        return w_merge_potential * pot;\n    }\n\n    int good_empty_for_flavor(const Board& b, int fl) const {\n        int H=Board::H, W=Board::W;\n        static const int di[4]={-1,1,0,0};\n        static const int dj[4]={0,0,-1,1};\n        int cnt=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                if(b.g[i][j]!=0) continue;\n                bool good=false;\n                for(int d=0; d<4; d++){\n                    int ni=i+di[d], nj=j+dj[d];\n                    if(ni<0||ni>=H||nj<0||nj>=W) continue;\n                    if(b.g[ni][nj]==fl){ good=true; break; }\n                }\n                if(good) cnt++;\n            }\n        }\n        return w_good_empty_next * cnt;\n    }\n\n    int score(const Board& b, int& maxcc_out) const {\n        int s=0;\n        s += adj_score(b);\n        s += distance_score(b);\n        s += boundaries_penalty(b);\n        s += edge_reward(b);\n        s += line_segment_reward(b);\n        s += wall_line_reward(b);\n        s += merge_potential(b);\n        int maxcc=0;\n        s += cc_penalty_and_maxcc(b, maxcc);\n        maxcc_out = maxcc;\n        // tiny deterministic tie-breaker\n        uint32_t h=2166136261u;\n        for(int i=0;i<Board::H;i++) for(int j=0;j<Board::W;j++){\n            h ^= uint32_t(b.g[i][j]+1); h *= 16777619u;\n        }\n        s += int(h%3)-1;\n        return s;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> f(100);\n    for(int i=0;i<100;i++){\n        if(!(cin>>f[i])) return 0;\n    }\n    array<int,4> cnt{}; cnt.fill(0);\n    for(int x: f) cnt[x]++;\n\n    Board board; board.clear();\n    Heuristic H;\n    H.setup_anchors_by_counts_and_early(cnt, f);\n\n    const array<char,4> dirs = {'F','B','L','R'};\n    char lastMove = 'F';\n\n    for(int t=0;t<100;t++){\n        int p;\n        if(!(cin>>p)) return 0;\n        board.place_by_index(p, f[t]);\n\n        if(t%10==0) H.nudge_anchors(board);\n\n        if(t==99){\n            continue; // skip final tilt\n        }\n\n        int bestScore = INT_MIN;\n        char bestDir = 'F';\n        Board bestBoard = board;\n        int bestMaxCC = -1;\n\n        int nextFlavor = f[t+1]; // known\n\n        for(char d1 : dirs){\n            Board b1 = board.tilt(d1);\n            int maxcc1=0;\n            int s1 = H.score(b1, maxcc1);\n\n            // candidate second moves: orthogonals preferred first\n            array<char,4> cand2;\n            if(d1=='F' || d1=='B') cand2 = {'L','R','F','B'};\n            else cand2 = {'F','B','L','R'};\n\n            int bestSecond = INT_MIN;\n            for(int k=0;k<4;k++){\n                char d2 = cand2[k];\n                Board b2 = b1.tilt(d2);\n                int maxcc2=0;\n                int s2 = H.score(b2, maxcc2);\n                // add lookahead knowledge: good empty cells for next flavor\n                s2 += H.good_empty_for_flavor(b2, nextFlavor);\n                // prefer larger component too\n                s2 += maxcc2;\n                bestSecond = max(bestSecond, s2);\n            }\n\n            // combine; give decent weight to immediate to stabilize\n            int combined = bestSecond + s1/3;\n\n            // packing preference: fewer non-empty lines in dir of move\n            auto nonEmptyLines = [&](const Board& after, char dir)->int{\n                int cntLines=0;\n                if(dir=='F' || dir=='B'){\n                    vector<int> occ(Board::H,0);\n                    for(int i=0;i<Board::H;i++){\n                        for(int j=0;j<Board::W;j++){\n                            if(after.g[i][j]){ occ[i]=1; break; }\n                        }\n                    }\n                    for(int i=0;i<Board::H;i++) cntLines += occ[i];\n                }else{\n                    vector<int> occ(Board::W,0);\n                    for(int j=0;j<Board::W;j++){\n                        for(int i=0;i<Board::H;i++){\n                            if(after.g[i][j]){ occ[j]=1; break; }\n                        }\n                    }\n                    for(int j=0;j<Board::W;j++) cntLines += occ[j];\n                }\n                return cntLines;\n            };\n            int lines = nonEmptyLines(b1, d1);\n            combined -= lines;\n\n            if(b1.equals(board)) combined -= 1;\n\n            if(combined > bestScore ||\n               (combined==bestScore && maxcc1 > bestMaxCC) ||\n               (combined==bestScore && maxcc1==bestMaxCC && d1==lastMove)){\n                bestScore = combined;\n                bestDir = d1;\n                bestBoard = b1;\n                bestMaxCC = maxcc1;\n            }\n        }\n\n        cout << bestDir << '\\n' << flush;\n        lastMove = bestDir;\n        board = bestBoard;\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\n\nusing ull = unsigned long long;\n\nstruct XorShift64 {\n    uint64_t x;\n    XorShift64(uint64_t s=88172645463393265ull){ if(!s) s=1; x=s; }\n    uint64_t rng(){ uint64_t y=x; y^=y<<7; y^=y>>9; return x=y; }\n    double drand(){ return (rng() >> 11) * (1.0/9007199254740992.0); } // [0,1)\n    int irand(int L,int R){ return L + (int)(rng() % (uint64_t)(R-L+1)); }\n};\n\nstatic inline int idx_pair(int N,int i,int j){ // i<j\n    return i*N - i*(i+1)/2 + (j - i - 1);\n}\n\nstruct Features {\n    vector<double> deg_hist;      // size N normalized\n    vector<int> deg_sorted;       // size N\n    vector<double> deg_buckets;   // size DB (e.g., 16)\n    vector<int> core_sorted;      // sorted k-core numbers per vertex\n    vector<double> core_hist;     // histogram over 0..maxcore (capped to NB=16)\n    vector<double> eigA;          // top T eigenvalues of adjacency\n    vector<double> eigLN;         // top T eigenvalues of normalized Laplacian\n    vector<double> nbrdeg_hist;   // histogram of neighbor-degree sums\n    vector<double> nbr_deg_buck;  // histogram of neighbor degree buckets\n};\n\nstruct TemplateG {\n    vector<uint8_t> bits; // length N(N-1)/2\n    vector<int> deg;\n    Features feat;\n};\n\nstatic vector<int> kcore_decomposition(int N, const vector<uint8_t>& bits){\n    vector<int> deg(N,0);\n    vector<vector<int>> adj(N);\n    for(int i=0;i<N;i++){\n        for(int j=i+1;j<N;j++){\n            if(bits[idx_pair(N,i,j)]){\n                deg[i]++; deg[j]++;\n                adj[i].push_back(j);\n                adj[j].push_back(i);\n            }\n        }\n    }\n    int maxd = 0;\n    for(int d:deg) maxd = max(maxd, d);\n    vector<int> bin(maxd+1,0);\n    for(int d:deg) bin[d]++;\n    vector<int> start(maxd+1,0);\n    int sum=0;\n    for(int d=0; d<=maxd; d++){ start[d]=sum; sum+=bin[d]; }\n    vector<int> pos(N), vert(N);\n    vector<int> cnt = start;\n    for(int v=0; v<N; v++){\n        pos[v] = cnt[deg[v]]++;\n        vert[pos[v]] = v;\n    }\n    vector<int> core = deg;\n    for(int i=0;i<N;i++){\n        int v = vert[i];\n        for(int u: adj[v]){\n            if(core[u] > core[v]){\n                int du = core[u];\n                int pu = pos[u];\n                int pw = start[du];\n                int w = vert[pw];\n                if(u != w){\n                    vert[pu] = w; pos[w] = pu;\n                    vert[pw] = u; pos[u] = pw;\n                }\n                start[du]++; core[u]--;\n            }\n        }\n    }\n    return core;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double eps;\n    if(!(cin>>M>>eps)) return 0;\n\n    // Adaptive N by eps\n    int N;\n    if (eps <= 0.04) N = 32;\n    else if (eps <= 0.12) N = 48;\n    else if (eps <= 0.24) N = 64;\n    else if (eps <= 0.32) N = 80;\n    else N = 96;\n    if (M >= 90 && eps <= 0.04) N = 36;\n    if (N < 4) N = 4;\n    if (N > 100) N = 100;\n\n    // Deterministic seed from M and eps\n    uint64_t seed = 1469598103934665603ull ^ (uint64_t)M * 1099511628211ull ^ (uint64_t)llround(eps*100.0+0.5);\n\n    // Blocks for SBM-like graph generation\n    auto initial_blocks = [&](int B){\n        vector<int> block(N);\n        for(int i=0;i<N;i++) block[i] = (long long)i * B / N;\n        return block;\n    };\n\n    auto add_backbone = [&](vector<uint8_t>& bits, int k){\n        if (N < 10) return;\n        int cycleSize = 8;\n        int step = max(1, N / cycleSize);\n        vector<int> cyc;\n        cyc.reserve(cycleSize);\n        int pos = (k*7 + 3) % N;\n        for(int t=0;t<cycleSize;t++){\n            cyc.push_back(pos);\n            pos = (pos + step) % N;\n        }\n        for(int t=0;t<cycleSize;t++){\n            int u = cyc[t];\n            int v = cyc[(t+1)%cycleSize];\n            if (u==v) continue;\n            int i=min(u,v), j=max(u,v);\n            bits[idx_pair(N,i,j)] = 1;\n        }\n        for(int t=0;t<cycleSize/2;t++){\n            int u = cyc[t];\n            int widx = (t+2 + (k+t)%3) % cycleSize;\n            int v = cyc[widx];\n            if (u==v) continue;\n            int i=min(u,v), j=max(u,v);\n            bits[idx_pair(N,i,j)] = 1;\n        }\n    };\n\n    auto rewiring_degree_palette = [&](vector<uint8_t>& bits, vector<int>& deg, const vector<int>& target, XorShift64& g){\n        int attempts = min( (int)(N*5), 1500 );\n        for(int it=0; it<attempts; ++it){\n            int v = g.irand(0, N-1);\n            if (deg[v] < target[v]){\n                // add an edge to a non-neighbor u\n                int trials = 8;\n                while(trials--){\n                    int u = g.irand(0, N-1);\n                    if (u==v) continue;\n                    int i=min(u,v), j=max(u,v);\n                    int id = idx_pair(N, i, j);\n                    if (bits[id]==0){\n                        bits[id]=1;\n                        deg[u]++; deg[v]++;\n                        break;\n                    }\n                }\n            }else if (deg[v] > target[v]){\n                // remove an edge to a neighbor u\n                int trials = 8;\n                while(trials--){\n                    int u = g.irand(0, N-1);\n                    if (u==v) continue;\n                    int i=min(u,v), j=max(u,v);\n                    int id = idx_pair(N, i, j);\n                    if (bits[id]==1){\n                        bits[id]=0;\n                        deg[u]--; deg[v]--;\n                        break;\n                    }\n                }\n            }\n        }\n    };\n\n    auto compute_features = [&](const vector<uint8_t>& bits)->pair<vector<int>, Features>{\n        Eigen::MatrixXd A(N, N);\n        A.setZero();\n        vector<int> deg(N,0);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                uint8_t v = bits[idx_pair(N,i,j)];\n                if(v){\n                    A(i,j)=A(j,i)=1.0;\n                    deg[i]++; deg[j]++;\n                }\n            }\n        }\n\n        // degree features\n        vector<double> dh(N, 0.0);\n        for(int d:deg) dh[d] += 1.0;\n        for(double &x:dh) x /= N;\n\n        vector<int> dsort = deg;\n        sort(dsort.begin(), dsort.end());\n\n        // degree buckets\n        const int DB = 16;\n        vector<double> db(DB, 0.0);\n        int dmax = 0;\n        for(int d:deg) dmax = max(dmax, d);\n        int span = max(1, dmax+1);\n        for(int d:deg){\n            int b = d * DB / span;\n            if(b>=DB) b=DB-1;\n            db[b] += 1.0;\n        }\n        for(double &x:db) x/=N;\n\n        // neighbor degree sums and neighbor degree bucket histogram\n        vector<int> degNbrSum(N,0);\n        vector<int> nbrDegCounts(DB, 0);\n        for(int i=0;i<N;i++){\n            int s=0;\n            for(int j=0;j<N;j++) if (A(i,j)>0.5) {\n                s += deg[j];\n                int b = deg[j] * DB / span;\n                if(b>=DB) b=DB-1;\n                nbrDegCounts[b] += 1;\n            }\n            degNbrSum[i]=s;\n        }\n        int Hbins = 16;\n        int minv = *min_element(degNbrSum.begin(), degNbrSum.end());\n        int maxv = *max_element(degNbrSum.begin(), degNbrSum.end());\n        if (maxv==minv) maxv=minv+1;\n        vector<double> ndh(Hbins,0.0);\n        for(int v:degNbrSum){\n            int b = (int)((long long)(v - minv) * Hbins / (long long)(maxv - minv + 1));\n            if(b<0) b=0;\n            if(b>=Hbins) b=Hbins-1;\n            ndh[b] += 1.0;\n        }\n        for(double &x:ndh) x/=N;\n\n        vector<double> ndb(DB, 0.0);\n        double totNbr = 0.0;\n        for(int b=0;b<DB;b++) totNbr += nbrDegCounts[b];\n        if (totNbr < 1.0) totNbr = 1.0;\n        for(int b=0;b<DB;b++) ndb[b] = nbrDegCounts[b] / totNbr;\n\n        // k-core\n        vector<int> core = kcore_decomposition(N, bits);\n        vector<int> core_sorted = core;\n        sort(core_sorted.begin(), core_sorted.end());\n        int cmax = 0; for(int c:core) cmax = max(cmax, c);\n        int CB = 16;\n        vector<double> core_hist(CB, 0.0);\n        int cspan = max(1, cmax+1);\n        for(int c:core){\n            int b = c * CB / cspan; if(b>=CB) b=CB-1;\n            core_hist[b] += 1.0;\n        }\n        for(double &x:core_hist) x/=N;\n\n        // Spectra: adjacency and normalized Laplacian\n        int Ttop = min(12, N);\n        vector<double> eigA, eigLN;\n        eigA.reserve(Ttop); eigLN.reserve(Ttop);\n        // adjacency\n        {\n            Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(A);\n            if (es.info() == Eigen::Success) {\n                auto evals = es.eigenvalues(); // ascending\n                vector<double> all(N);\n                for(int i=0;i<N;i++) all[i] = evals(i);\n                vector<int> idx(N); iota(idx.begin(), idx.end(), 0);\n                sort(idx.begin(), idx.end(), [&](int a,int b){\n                    return fabs(all[a]) > fabs(all[b]);\n                });\n                int maxdeg = 1;\n                for(int d:deg) if(d>maxdeg) maxdeg=d;\n                double scale = sqrt((double)maxdeg);\n                if(scale == 0.0) scale = 1.0;\n                for(int t=0;t<Ttop;t++){\n                    eigA.push_back(all[idx[t]] / scale);\n                }\n            } else {\n                eigA.assign(Ttop, 0.0);\n            }\n        }\n        // Normalized Laplacian Lnorm = I - D^{-1/2} A D^{-1/2}\n        {\n            Eigen::VectorXd invs(N);\n            for(int i=0;i<N;i++){\n                if (deg[i] > 0) invs(i) = 1.0 / sqrt((double)deg[i]);\n                else invs(i) = 0.0;\n            }\n            Eigen::MatrixXd Lnorm = Eigen::MatrixXd::Identity(N,N);\n            for(int i=0;i<N;i++){\n                for(int j=i+1;j<N;j++){\n                    if (A(i,j) > 0.5){\n                        double w = invs(i) * invs(j);\n                        if (w != 0.0){\n                            Lnorm(i,j) -= w;\n                            Lnorm(j,i) -= w;\n                        }\n                    }\n                }\n            }\n            Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(Lnorm);\n            if (es.info() == Eigen::Success) {\n                auto evals = es.eigenvalues(); // ascending in [0,2]\n                vector<double> all(N);\n                for(int i=0;i<N;i++) all[i] = evals(i);\n                vector<int> idx(N); iota(idx.begin(), idx.end(), 0);\n                sort(idx.begin(), idx.end(), [&](int a,int b){\n                    return fabs(all[a]-1.0) > fabs(all[b]-1.0);\n                });\n                for(int t=0;t<Ttop;t++){\n                    eigLN.push_back(all[idx[t]]);\n                }\n            } else {\n                eigLN.assign(Ttop, 0.0);\n            }\n        }\n\n        Features F;\n        F.deg_hist = move(dh);\n        F.deg_sorted = move(dsort);\n        F.deg_buckets = move(db);\n        F.core_sorted = move(core_sorted);\n        F.core_hist = move(core_hist);\n        F.eigA = move(eigA);\n        F.eigLN = move(eigLN);\n        F.nbrdeg_hist = move(ndh);\n        F.nbr_deg_buck = move(ndb);\n        return {deg, F};\n    };\n\n    // Build templates and features\n    vector<TemplateG> temps(M);\n    for(int k=0;k<M;k++){\n        // Select number of blocks: alternate 4/5 when N>=60\n        int B = (N >= 60 ? (4 + ((k + M) % 2)) : 4);\n        vector<int> base_block = initial_blocks(B);\n\n        XorShift64 g(seed ^ (uint64_t)(0x9e3779b97f4a7c15ull * (k+1)));\n        vector<int> blk(N);\n        // Remap block labels randomly\n        vector<int> permB(B);\n        iota(permB.begin(), permB.end(), 0);\n        for(int i=0;i<B;i++){ int j = g.irand(0,B-1); swap(permB[i], permB[j]); }\n        for(int i=0;i<N;i++) blk[i] = permB[ base_block[i] ];\n\n        // Create P with diagonal/off-diagonal contrast\n        double base = 0.25 + 0.4 * ( (k*0.1234567) - floor(k*0.1234567) );\n        double diag_boost = 0.18 + 0.12 * (g.drand());\n        double off_var = 0.14 + 0.08 * (g.drand());\n        vector<vector<double>> P(B, vector<double>(B, 0.0));\n        for(int b=0;b<B;b++){\n            for(int c=b;c<B;c++){\n                double val = base + off_var * (g.drand()-0.5);\n                if (b==c) val = base + diag_boost * (g.drand()-0.5) + 0.35;\n                val = min(0.98, max(0.02, val));\n                P[b][c]=P[c][b]=val;\n            }\n        }\n        vector<double> biasB(B);\n        for(int b=0;b<B;b++) biasB[b] = (g.drand()-0.5)*0.20;\n\n        int Ebits = N*(N-1)/2;\n        vector<uint8_t> bits(Ebits, 0);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                int bi = blk[i], bj = blk[j];\n                double p = P[bi][bj];\n                double vbi = biasB[bi] + 0.05 * sin((i+1)*(k+3)*0.13);\n                double vbj = biasB[bj] + 0.05 * cos((j+3)*(k+5)*0.17);\n                double adjp = p + 0.14*(vbi+vbj);\n                if(adjp < 0.01) adjp = 0.01;\n                if(adjp > 0.99) adjp = 0.99;\n                if (g.drand() < adjp){\n                    bits[idx_pair(N,i,j)] = 1;\n                }\n            }\n        }\n        // Backbone\n        add_backbone(bits, k);\n\n        // Compute degrees\n        vector<int> deg(N,0);\n        for(int i=0;i<N;i++){\n            int d=0;\n            for(int j=0;j<i;j++) d += bits[idx_pair(N,j,i)];\n            for(int j=i+1;j<N;j++) d += bits[idx_pair(N,i,j)];\n            deg[i]=d;\n        }\n\n        // Degree palette: template-specific but conservative\n        vector<int> target(N);\n        for(int i=0;i<N;i++){\n            int bi = blk[i];\n            // center fraction varies with k and block\n            double basef = 0.15 + 0.12 * ( (k%7) - 3 );\n            basef = basef / (double)max(1,(int)N); // too small; refine below\n            // use block-based center\n            double f = 0.18 + 0.12*bi + 0.02*((k%5)-2);\n            f = max(0.05, min(0.9, f));\n            int t = (int)round(f * (N-1));\n            // small stagger by i and k\n            t += ((i + 3*k) % 5) - 2;\n            t = max(0, min(N-1, t));\n            target[i] = t;\n        }\n        rewiring_degree_palette(bits, deg, target, g);\n\n        // Features\n        auto [deg2, F] = compute_features(bits);\n        temps[k].bits = move(bits);\n        temps[k].deg = move(deg2);\n        temps[k].feat = move(F);\n    }\n\n    // Helper distances\n    auto l2 = [](const vector<double>& x, const vector<double>& y){\n        double s=0; size_t n=min(x.size(), y.size());\n        for(size_t i=0;i<n;i++){ double d=x[i]-y[i]; s+=d*d; }\n        return sqrt(s);\n    };\n    auto l1sorted = [](const vector<int>& x, const vector<int>& y){\n        double s=0; size_t n=min(x.size(), y.size());\n        for(size_t i=0;i<n;i++){ s += abs(x[i]-y[i]); }\n        return s / (double)n;\n    };\n\n    // Smooth \u03b5 weight interpolation helper\n    auto mix = [](double a, double b, double t){ return a*(1.0-t) + b*t; };\n    double t_eps = min(1.0, max(0.0, (eps - 0.10) / 0.25)); // 0 near low eps, 1 near high eps\n\n    auto dist_deg_fast = [&](const Features& A, const Features& B)->double{\n        double s= l2(A.deg_buckets, B.deg_buckets);\n        double t= l1sorted(A.deg_sorted, B.deg_sorted);\n        double u= l2(A.nbr_deg_buck, B.nbr_deg_buck);\n        double v= l2(A.core_hist, B.core_hist);\n        // weights smoothly vary with eps\n        double w_deg = mix(0.70, 0.45, t_eps);\n        double w_sort= mix(0.25, 0.25, t_eps);\n        double w_nbr = mix(0.05, 0.20, t_eps);\n        double w_core= mix(0.00, 0.10, t_eps);\n        return w_deg*s + w_sort*t + w_nbr*u + w_core*v;\n    };\n\n    auto dist_full = [&](const Features& A, const Features& B)->double{\n        double d_deg_hist = l2(A.deg_hist, B.deg_hist);\n        double d_deg_buck = l2(A.deg_buckets, B.deg_buckets);\n        double d_nbr_sum  = l2(A.nbrdeg_hist, B.nbrdeg_hist);\n        double d_nbr_buck = l2(A.nbr_deg_buck, B.nbr_deg_buck);\n        double d_eigA     = l2(A.eigA, B.eigA);\n        double d_eigLN    = l2(A.eigLN, B.eigLN);\n        double d_sorted   = l1sorted(A.deg_sorted, B.deg_sorted);\n        double d_coreh    = l2(A.core_hist, B.core_hist);\n        double d_cores    = l1sorted(A.core_sorted, B.core_sorted);\n\n        // \u03b5-aware weights via smooth interpolation\n        double w_eigA  = mix(0.16, 0.24, t_eps);\n        double w_eigLN = mix(0.08, 0.14, t_eps);\n        double w_dh    = mix(0.20, 0.10, t_eps);\n        double w_db    = mix(0.18, 0.16, t_eps);\n        double w_ns    = mix(0.08, 0.07, t_eps);\n        double w_nb    = mix(0.04, 0.09, t_eps);\n        double w_sort  = mix(0.08, 0.06, t_eps);\n        double w_ch    = mix(0.04, 0.05, t_eps);\n        double w_cs    = mix(0.02, 0.09, t_eps);\n\n        return w_eigA*d_eigA + w_eigLN*d_eigLN\n             + w_dh*d_deg_hist + w_db*d_deg_buck\n             + w_ns*d_nbr_sum + w_nb*d_nbr_buck\n             + w_sort*d_sorted + w_ch*d_coreh + w_cs*d_cores;\n    };\n\n    // Output templates\n    cout<<N<<\"\\n\";\n    for(int k=0;k<M;k++){\n        int L = N*(N-1)/2;\n        string s; s.resize(L);\n        for(int i=0;i<L;i++) s[i] = temps[k].bits[i] ? '1':'0';\n        cout<<s<<\"\\n\";\n    }\n    cout.flush();\n\n    // Answer queries\n    int shortlist_base = (eps >= 0.25 ? 20 : 12);\n    for(int q=0;q<100;q++){\n        string Hs;\n        if(!(cin>>Hs)) return 0;\n        int L = N*(N-1)/2;\n        vector<uint8_t> Hbits(L,0);\n        for(int i=0;i<L;i++) Hbits[i] = (Hs[i]=='1');\n\n        auto [Hdeg, HF] = compute_features(Hbits);\n\n        int S = min(shortlist_base, M);\n        vector<pair<double,int>> cand;\n        cand.reserve(M);\n        for(int k=0;k<M;k++){\n            double d = dist_deg_fast(HF, temps[k].feat);\n            cand.emplace_back(d, k);\n        }\n        nth_element(cand.begin(), cand.begin()+S, cand.end());\n        cand.resize(S);\n\n        int bestk = cand[0].second;\n        double bestd = 1e100;\n        for(auto &pr : cand){\n            int k = pr.second;\n            double d = dist_full(HF, temps[k].feat);\n            if(d < bestd){\n                bestd = d; bestk = k;\n            }\n        }\n        cout<<bestk<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge { int id, u, v; int w; };\nstruct Adj { int to, eid, w; };\n\nstruct Timer {\n    chrono::high_resolution_clock::time_point st;\n    Timer(){ reset(); }\n    void reset(){ st = chrono::high_resolution_clock::now(); }\n    double ms() const { return chrono::duration<double, std::milli>(chrono::high_resolution_clock::now()-st).count(); }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Timer timer;\n\n    int N,M,D,K;\n    if(!(cin>>N>>M>>D>>K)) return 0;\n    vector<Edge> edges(M);\n    for(int i=0;i<M;++i){\n        int u,v,w; cin>>u>>v>>w; --u;--v; edges[i]={i,u,v,w};\n    }\n    vector<pair<int,int>> coords(N);\n    for(int i=0;i<N;++i){ int x,y; cin>>x>>y; coords[i]={x,y}; }\n\n    vector<vector<Adj>> g(N);\n    vector<int> deg(N,0);\n    for(auto &e: edges){\n        g[e.u].push_back({e.v, e.id, e.w});\n        g[e.v].push_back({e.u, e.id, e.w});\n        deg[e.u]++; deg[e.v]++;\n    }\n\n    // Importance components: weight and degree penalty\n    long long wmin=LLONG_MAX,wmax=0;\n    for(auto &e: edges){ wmin=min<long long>(wmin,e.w); wmax=max<long long>(wmax,e.w); }\n    double denom_w = (wmax>wmin ? double(wmax-wmin) : 1.0);\n    vector<double> imp_w(M), imp_deg(M);\n    for(auto &e: edges) imp_w[e.id] = (double)(e.w - wmin) / denom_w;\n    for(auto &e: edges){\n        double pu = 1.0 / max(1, deg[e.u]-1);\n        double pv = 1.0 / max(1, deg[e.v]-1);\n        imp_deg[e.id] = 0.5*(pu+pv);\n    }\n\n    // Betweenness-like using SSSP tree usage from multiple sources (deterministic)\n    mt19937 rng(912531);\n    vector<int> nodes(N); iota(nodes.begin(), nodes.end(), 0);\n    shuffle(nodes.begin(), nodes.end(), rng);\n    int S = 30; if(N<=900) S=28; if(N<=750) S=26; if(N<=600) S=24; if(N<=500) S=22; S = min(S, max(18, N/40));\n    int T = 16; if(N<750) T=14; if(N<600) T=12; // targets per source for path backtracking\n\n    vector<long long> dist(N);\n    vector<int> parent_edge(N, -1);\n    struct QN{ long long d; int v; };\n    struct Cmp{ bool operator()(const QN&a,const QN&b)const{return a.d>b.d;}};\n    vector<long long> bet_count(M,0);\n\n    // Co-occurrence top-K map per edge\n    const int KCO = 16;\n    vector<unordered_map<int,int>> co_occur(M);\n\n    auto push_co = [&](int e1, int e2){\n        if(e1==e2) return;\n        auto &mp = co_occur[e1];\n        auto it = mp.find(e2);\n        if(it != mp.end()){ it->second++; return; }\n        if((int)mp.size() < KCO){ mp.emplace(e2,1); return; }\n        // deterministic replacement: remove current minimum count; tie -> remove largest key\n        int min_k = -1, min_v = INT_MAX;\n        for(auto &kv: mp){\n            if(kv.second < min_v || (kv.second == min_v && kv.first > min_k)){\n                min_v = kv.second; min_k = kv.first;\n            }\n        }\n        if(min_v <= 1){ mp.erase(min_k); mp.emplace(e2,1); }\n        // else ignore to keep strongest pairs\n    };\n\n    vector<int> targets; targets.reserve(T);\n    vector<int> path_edges; path_edges.reserve(N);\n\n    for(int si=0; si<S && si<N; ++si){\n        if(timer.ms() > 2200.0) break;\n        int s = nodes[si];\n        // Dijkstra single parent (deterministic)\n        fill(dist.begin(), dist.end(), (long long)4e18);\n        fill(parent_edge.begin(), parent_edge.end(), -1);\n        priority_queue<QN, vector<QN>, Cmp> pq;\n        dist[s]=0; pq.push({0,s});\n        while(!pq.empty()){\n            auto [d,v]=pq.top(); pq.pop();\n            if(d!=dist[v]) continue;\n            for(auto &ae: g[v]){\n                int to = ae.to; long long nd = d + ae.w;\n                if(nd < dist[to]){\n                    dist[to]=nd; parent_edge[to]=ae.eid; pq.push({nd,to});\n                }\n            }\n        }\n        for(int v=0; v<N; ++v){\n            if(v==s) continue;\n            int pe = parent_edge[v];\n            if(pe>=0) bet_count[pe] += 1;\n        }\n        // sample targets deterministically from shuffled nodes block\n        targets.clear();\n        for(int t=0; t<T; ++t){\n            int idx = (si*911 + t*811) % N;\n            int v = nodes[idx]; if(v==s) v = (v+1)%N;\n            targets.push_back(v);\n        }\n        // Backtrack along unique parents to build paths and update co-occurrence\n        for(int tnode: targets){\n            path_edges.clear();\n            int cur = tnode; int steps=0;\n            while(cur != s && steps < N){\n                int pe = parent_edge[cur];\n                if(pe < 0) break;\n                path_edges.push_back(pe);\n                int a=edges[pe].u, b=edges[pe].v;\n                cur = (cur==a? b: a);\n                steps++;\n            }\n            int Lp = (int)path_edges.size();\n            for(int i=0;i<Lp;++i){\n                int e1 = path_edges[i];\n                bet_count[e1] += 1;\n                // limited window to contain cost\n                int l = max(0, i-7), r = min(Lp-1, i+7);\n                for(int j=l;j<=r;++j){\n                    if(j==i) continue;\n                    push_co(e1, path_edges[j]);\n                }\n            }\n        }\n    }\n\n    // Normalize betweenness\n    long long bmin=LLONG_MAX, bmax=0;\n    for(int i=0;i<M;++i){ bmin=min(bmin, bet_count[i]); bmax=max(bmax, bet_count[i]); }\n    double denom_b = (bmax>bmin? double(bmax-bmin):1.0);\n    vector<double> imp_bet(M,0.0);\n    for(int i=0;i<M;++i) imp_bet[i] = (double)(bet_count[i]-bmin)/denom_b;\n\n    // Single sectorization\n    double cx=0, cy=0;\n    for(auto &p: coords){ cx += p.first; cy += p.second; }\n    cx /= N; cy /= N;\n    int SECT = 12;\n    vector<int> edge_sect(M,0);\n    for(auto &e: edges){\n        double mx = 0.5*(coords[e.u].first + coords[e.v].first);\n        double my = 0.5*(coords[e.u].second + coords[e.v].second);\n        double ang = atan2(my - cy, mx - cx);\n        if(ang < 0) ang += 2*M_PI;\n        int s = int(SECT * (ang/(2*M_PI)));\n        if(s<0) s=0; if(s>=SECT) s=SECT-1;\n        edge_sect[e.id] = s;\n    }\n\n    // Final score with stable weights\n    double w_w = 0.35, w_deg = 0.55, w_bet = 1.10;\n    vector<double> score(M);\n    for(int i=0;i<M;++i) score[i] = w_w*imp_w[i] + w_deg*imp_deg[i] + w_bet*imp_bet[i];\n\n    vector<int> order(M); iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i,int j){\n        if(score[i]!=score[j]) return score[i] > score[j];\n        return i<j;\n    });\n\n    // Assignment with penalties\n    vector<int> day_of_edge(M, -1);\n    vector<int> load(D,0);\n    vector<double> day_imp(D,0.0), day_imp2(D,0.0);\n    vector<vector<int>> incid_on_day(N, vector<int>(D,0));\n    vector<vector<int>> sect_on_day(D, vector<int>(SECT,0));\n    vector<int> target(D);\n    int base=M/D, rem=M%D;\n    for(int d=0; d<D; ++d) target[d] = min(K, base + (d<rem?1:0));\n    vector<int> v_soft(N);\n    for(int v=0; v<N; ++v) v_soft[v] = (deg[v] + D - 1)/D + 1;\n\n    double alpha_adj = 1.1;\n    double beta_lin = 0.22;\n    double beta_var = 0.24;\n    double gamma_co = 0.36;\n    double delta_sect = 0.13;\n    double soft_cap_pen = 0.25;\n\n    for(int ei: order){\n        int u=edges[ei].u, v=edges[ei].v, sec=edge_sect[ei];\n        int bestd=-1; double bestc=1e100;\n        for(int d=0; d<D; ++d){\n            if(load[d] >= K) continue;\n            int iu=incid_on_day[u][d], iv=incid_on_day[v][d];\n            double pen_adj = alpha_adj * (iu + iv);\n            double pen_vsoft = 0.0;\n            if(iu >= v_soft[u]) pen_vsoft += (iu - v_soft[u] + 1)*0.5;\n            if(iv >= v_soft[v]) pen_vsoft += (iv - v_soft[v] + 1)*0.5;\n            double bal = beta_lin * day_imp[d] + beta_var * day_imp2[d];\n            double pen_co = 0.0;\n            auto &mp = co_occur[ei];\n            int seen=0;\n            for(auto &kv: mp){\n                int ej=kv.first; int dj = (unsigned)ej < (unsigned)M ? day_of_edge[ej] : -1;\n                if(dj==d){ pen_co += gamma_co * kv.second; if(++seen>=KCO) break; }\n            }\n            double pen_sec = delta_sect * sect_on_day[d][sec];\n            double cap_soft = (load[d] < target[d] ? 0.0 : soft_cap_pen * (load[d] - target[d] + 1));\n            double cost = pen_adj + pen_vsoft + bal + pen_co + pen_sec + cap_soft;\n            if(cost < bestc){ bestc=cost; bestd=d; }\n        }\n        if(bestd<0){ int md=0; for(int d=1; d<D; ++d) if(load[d] < load[md]) md=d; bestd=md; }\n        day_of_edge[ei]=bestd;\n        load[bestd]++; day_imp[bestd]+=score[ei]; day_imp2[bestd]+=score[ei]*score[ei];\n        incid_on_day[u][bestd]++; incid_on_day[v][bestd]++;\n        sect_on_day[bestd][sec]++;\n    }\n\n    // Refinement: single-edge moves + pair swaps\n    auto eval_day_cost_partial = [&](int ei, int d)->double{\n        int u=edges[ei].u, v=edges[ei].v, sec=edge_sect[ei];\n        int iu = incid_on_day[u][d] - (day_of_edge[ei]==d?1:0);\n        int iv = incid_on_day[v][d] - (day_of_edge[ei]==d?1:0);\n        double pen_adj = alpha_adj * (iu + iv);\n        double pen_vsoft = 0.0;\n        if(iu >= v_soft[u]) pen_vsoft += (iu - v_soft[u] + 1)*0.5;\n        if(iv >= v_soft[v]) pen_vsoft += (iv - v_soft[v] + 1)*0.5;\n        double bal = beta_lin * day_imp[d] + beta_var * day_imp2[d];\n        double pen_co = 0.0;\n        auto &mp = co_occur[ei];\n        int seen=0;\n        for(auto &kv: mp){\n            int ej=kv.first; int dj = day_of_edge[ej];\n            if(dj==d){ pen_co += gamma_co * kv.second; if(++seen>=KCO) break; }\n        }\n        double pen_sec = delta_sect * (sect_on_day[d][sec] - (day_of_edge[ei]==d?1:0));\n        return pen_adj + pen_vsoft + bal + pen_co + pen_sec;\n    };\n\n    auto move_edge = [&](int ei, int dfrom, int dto){\n        int u=edges[ei].u, v=edges[ei].v, sec=edge_sect[ei];\n        incid_on_day[u][dfrom]--; incid_on_day[v][dfrom]--;\n        incid_on_day[u][dto]++; incid_on_day[v][dto]++;\n        sect_on_day[dfrom][sec]--; sect_on_day[dto][sec]++;\n        load[dfrom]--; load[dto]++;\n        day_imp[dfrom] -= score[ei]; day_imp2[dfrom] -= score[ei]*score[ei];\n        day_imp[dto] += score[ei]; day_imp2[dto] += score[ei]*score[ei];\n        day_of_edge[ei]=dto;\n    };\n\n    double time_left = max(0.0, 5200.0 - timer.ms());\n    double ref1 = min(1400.0, time_left * 0.55);\n    double ref2 = min(700.0, time_left * 0.30);\n    double ref3 = min(650.0, time_left * 0.30); // audit+ejection budget, overlapping a bit with remaining time\n\n    Timer t1;\n    uniform_int_distribution<int> distE(0, M-1);\n    int iters=0;\n    while(t1.ms() < ref1 && iters < 220000){\n        ++iters;\n        int ei = distE(rng);\n        int di = day_of_edge[ei];\n        double cur = eval_day_cost_partial(ei, di);\n        int bestd = di; double best_gain = 0.0;\n        for(int d=0; d<D; ++d){\n            if(d==di) continue;\n            if(load[d] >= K) continue;\n            double newc = eval_day_cost_partial(ei, d);\n            double s = score[ei];\n            double old_bal = (beta_lin*day_imp[di] + beta_var*day_imp2[di]) + (beta_lin*day_imp[d] + beta_var*day_imp2[d]);\n            double new_bal = (beta_lin*(day_imp[di]-s) + beta_var*(day_imp2[di]-s*s))\n                           + (beta_lin*(day_imp[d]+s) + beta_var*(day_imp2[d]+s*s));\n            double gain = (cur - newc) + (old_bal - new_bal);\n            if(gain > best_gain){ best_gain=gain; bestd=d; }\n        }\n        if(bestd != di && best_gain > 1e-9){\n            move_edge(ei, di, bestd);\n        }\n    }\n\n    // Pair swaps\n    Timer t2;\n    int swaps=0;\n    vector<int> ord = order; // hot edges first\n    int H = min((int)ord.size(), max(120, M/7));\n    while(t2.ms() < ref2 && swaps < 40000){\n        ++swaps;\n        int e1 = ord[rng() % H];\n        int e2 = distE(rng);\n        if(e1==e2) continue;\n        int d1 = day_of_edge[e1];\n        int d2 = day_of_edge[e2];\n        if(d1==d2) continue;\n\n        double c11 = eval_day_cost_partial(e1, d1);\n        double c22 = eval_day_cost_partial(e2, d2);\n        double c12 = eval_day_cost_partial(e1, d2);\n        double c21 = eval_day_cost_partial(e2, d1);\n\n        double s1 = score[e1], s2 = score[e2];\n        double old_bal = (beta_lin*day_imp[d1] + beta_var*day_imp2[d1]) + (beta_lin*day_imp[d2] + beta_var*day_imp2[d2]);\n        double new_imp_d1 = day_imp[d1] - s1 + s2;\n        double new_imp2_d1 = day_imp2[d1] - s1*s1 + s2*s2;\n        double new_imp_d2 = day_imp[d2] - s2 + s1;\n        double new_imp2_d2 = day_imp2[d2] - s2*s2 + s1*s1;\n        double new_bal = (beta_lin*new_imp_d1 + beta_var*new_imp2_d1) + (beta_lin*new_imp_d2 + beta_var*new_imp2_d2);\n\n        double gain = (c11 + c22) - (c12 + c21) + (old_bal - new_bal);\n        if(gain > 1e-9){\n            int u1=edges[e1].u, v1=edges[e1].v, sec1=edge_sect[e1];\n            int u2=edges[e2].u, v2=edges[e2].v, sec2=edge_sect[e2];\n            // apply swap\n            incid_on_day[u1][d1]--; incid_on_day[v1][d1]--; sect_on_day[d1][sec1]--;\n            incid_on_day[u1][d2]++; incid_on_day[v1][d2]++; sect_on_day[d2][sec1]++;\n            incid_on_day[u2][d2]--; incid_on_day[v2][d2]--; sect_on_day[d2][sec2]--;\n            incid_on_day[u2][d1]++; incid_on_day[v2][d1]++; sect_on_day[d1][sec2]++;\n            day_imp[d1] = new_imp_d1; day_imp2[d1] = new_imp2_d1;\n            day_imp[d2] = new_imp_d2; day_imp2[d2] = new_imp2_d2;\n            day_of_edge[e1]=d2; day_of_edge[e2]=d1;\n        }\n    }\n\n    // Day auditing + ejection-reassignment\n    Timer t3;\n    if (t3.ms() < ref3) {\n        // Build per-day edge lists\n        vector<vector<int>> day_edges(D);\n        day_edges.assign(D, {});\n        for (int ei = 0; ei < M; ++ei) {\n            int d = day_of_edge[ei];\n            if (d>=0) day_edges[d].push_back(ei);\n        }\n        // Compute day risk = a*imp + b*sector_l2 + c*co_conflict\n        vector<double> day_risk(D, 0.0);\n        vector<double> sector_l2(D, 0.0);\n        vector<double> co_conflict(D, 0.0);\n        double a_imp=0.35, b_sect=0.20, c_co=0.45;\n\n        for (int d=0; d<D; ++d) {\n            // sector L2\n            double l2=0.0;\n            for (int s=0; s<SECT; ++s) {\n                double x = sect_on_day[d][s];\n                l2 += x*x;\n            }\n            sector_l2[d] = l2;\n            // co-occurrence conflict (approx): sum over edges of sum co with edges on same day, using map\n            double co=0.0;\n            for (int ei : day_edges[d]) {\n                auto &mp = co_occur[ei];\n                int seen=0;\n                for (auto &kv: mp) {\n                    int ej = kv.first;\n                    if (ej>=0 && ej<M && day_of_edge[ej]==d) {\n                        co += kv.second;\n                        if (++seen >= KCO) break;\n                    }\n                }\n            }\n            co_conflict[d] = co;\n            day_risk[d] = a_imp * day_imp[d] + b_sect * sector_l2[d] + c_co * co_conflict[d];\n        }\n\n        // Pick top bad days\n        vector<int> day_ord(D); iota(day_ord.begin(), day_ord.end(), 0);\n        sort(day_ord.begin(), day_ord.end(), [&](int i,int j){ return day_risk[i] > day_risk[j]; });\n        int bad_days = max(1, D/4);\n        bad_days = min(bad_days, D);\n\n        // For each bad day, select hot edges (high local conflict * score)\n        vector<int> eject;\n        for (int bi=0; bi<bad_days; ++bi) {\n            int d = day_ord[bi];\n            auto &elist = day_edges[d];\n            if (elist.empty()) continue;\n            vector<pair<double,int>> contrib; contrib.reserve(elist.size());\n            for (int ei : elist) {\n                double local = 0.0;\n                auto &mp = co_occur[ei];\n                int seen=0;\n                for (auto &kv: mp) {\n                    int ej = kv.first;\n                    if (ej>=0 && ej<M && day_of_edge[ej]==d) {\n                        local += kv.second;\n                        if (++seen >= KCO) break;\n                    }\n                }\n                double val = local * (0.5 + score[ei]); // weight by importance\n                // small bump if many same-sector edges exist\n                val += 0.2 * sect_on_day[d][edge_sect[ei]];\n                contrib.emplace_back(val, ei);\n            }\n            sort(contrib.begin(), contrib.end(), greater<>());\n            int take = max(1, (int)elist.size()/20); // up to 5% from this day\n            take = min(take, 20); // cap per day\n            for (int i=0; i<take && i<(int)contrib.size(); ++i) eject.push_back(contrib[i].second);\n        }\n\n        // Eject uniques\n        sort(eject.begin(), eject.end());\n        eject.erase(unique(eject.begin(), eject.end()), eject.end());\n\n        // Remove them from their days\n        for (int ei : eject) {\n            int d = day_of_edge[ei];\n            if (d<0) continue;\n            int u=edges[ei].u, v=edges[ei].v, sec=edge_sect[ei];\n            incid_on_day[u][d]--; incid_on_day[v][d]--;\n            sect_on_day[d][sec]--;\n            load[d]--;\n            day_imp[d] -= score[ei]; day_imp2[d] -= score[ei]*score[ei];\n            day_of_edge[ei] = -1;\n        }\n\n        // Reassign ejected edges using a slightly stronger sector+co-occurrence penalty to diversify\n        double extra_co = 0.10;\n        double extra_sec = 0.08;\n        for (int ei : eject) {\n            int u=edges[ei].u, v=edges[ei].v, sec=edge_sect[ei];\n            int bestd=-1; double bestc=1e100;\n            for (int d=0; d<D; ++d) {\n                if (load[d] >= K) continue;\n                int iu=incid_on_day[u][d], iv=incid_on_day[v][d];\n                double pen_adj = alpha_adj * (iu + iv);\n                double pen_vsoft = 0.0;\n                if(iu >= v_soft[u]) pen_vsoft += (iu - v_soft[u] + 1)*0.5;\n                if(iv >= v_soft[v]) pen_vsoft += (iv - v_soft[v] + 1)*0.5;\n                double bal = beta_lin * day_imp[d] + beta_var * day_imp2[d];\n                double pen_co = 0.0;\n                auto &mp = co_occur[ei];\n                int seen=0;\n                for(auto &kv: mp){\n                    int ej=kv.first; int dj = (unsigned)ej < (unsigned)M ? day_of_edge[ej] : -1;\n                    if(dj==d){ pen_co += (gamma_co + extra_co) * kv.second; if(++seen>=KCO) break; }\n                }\n                double pen_sec = (delta_sect + extra_sec) * sect_on_day[d][sec];\n                double cap_soft = (load[d] < target[d] ? 0.0 : soft_cap_pen * (load[d] - target[d] + 1));\n                double cost = pen_adj + pen_vsoft + bal + pen_co + pen_sec + cap_soft;\n                if(cost < bestc){ bestc=cost; bestd=d; }\n            }\n            if(bestd<0){ int md=0; for (int d=1; d<D; ++d) if(load[d] < load[md]) md=d; bestd=md; }\n            day_of_edge[ei]=bestd;\n            load[bestd]++; day_imp[bestd]+=score[ei]; day_imp2[bestd]+=score[ei]*score[ei];\n            incid_on_day[u][bestd]++; incid_on_day[v][bestd]++;\n            sect_on_day[bestd][sec]++;\n        }\n    }\n\n    // Output\n    for(int i=0;i<M;++i){\n        int d = day_of_edge[i];\n        if(d<0) d = i % D;\n        cout << (d+1) << (i+1==M?'\\n':' ');\n    }\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Prefix3D {\n    int D;\n    vector<int> ps; // (D+1)^3\n    inline int id(int x,int y,int z) const { return (x*(D+1) + y)*(D+1) + z; }\n    void build(const vector<char>& M){\n        const int P = (D+1)*(D+1)*(D+1);\n        ps.assign(P, 0);\n        for(int x=1;x<=D;++x){\n            for(int y=1;y<=D;++y){\n                int acc = 0;\n                for(int z=1; z<=D; ++z){\n                    int v = M[(x-1)*D*D + (y-1)*D + (z-1)] ? 1 : 0;\n                    acc += v;\n                    ps[id(x,y,z)] = ps[id(x-1,y,z)] + ps[id(x,y-1,z)] - ps[id(x-1,y-1,z)] + acc;\n                }\n            }\n        }\n    }\n    inline int sum(int x0,int y0,int z0,int x1,int y1,int z1) const {\n        int a = ps[id(x1,y1,z1)];\n        int b = ps[id(x0,y1,z1)];\n        int c = ps[id(x1,y0,z1)];\n        int d = ps[id(x1,y1,z0)];\n        int e = ps[id(x0,y0,z1)];\n        int f = ps[id(x0,y1,z0)];\n        int g = ps[id(x1,y0,z0)];\n        int h = ps[id(x0,y0,z0)];\n        return a - b - c - d + e + f + g - h;\n    }\n    inline bool full(const int x0,const int y0,const int z0,const int dx,const int dy,const int dz) const {\n        if (x0<0||y0<0||z0<0) return false;\n        int x1=x0+dx, y1=y0+dy, z1=z0+dz;\n        if (x1>D || y1>D || z1>D) return false;\n        int s = sum(x0,y0,z0,x1,y1,z1);\n        return s == dx*dy*dz;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D;\n    if (!(cin>>D)) return 0;\n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    for(int i=0;i<2;++i){\n        for(int z=0;z<D;++z) cin>>f[i][z];\n        for(int z=0;z<D;++z) cin>>r[i][z];\n    }\n    const int N = D*D*D;\n    auto idx = [&](int x,int y,int z){ return x*D*D + y*D + z; };\n\n    // Masks per arrangement\n    vector<char> M1(N,0), M2(N,0);\n    for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z){\n        if (f[0][z][x]=='1' && r[0][z][y]=='1') M1[idx(x,y,z)] = 1;\n        if (f[1][z][x]=='1' && r[1][z][y]=='1') M2[idx(x,y,z)] = 1;\n    }\n\n    vector<int> b1(N,0), b2(N,0);\n    int nBlocks = 0;\n\n    auto mark_block = [&](vector<char>& M, vector<int>& Bout, int bid, int x0,int y0,int z0,int dx,int dy,int dz){\n        for(int x=x0;x<x0+dx;++x)\n            for(int y=y0;y<y0+dy;++y)\n                for(int z=z0;z<z0+dz;++z){\n                    int id3 = idx(x,y,z);\n                    M[id3] = 0;\n                    Bout[id3] = bid;\n                }\n    };\n\n    auto now = [&]()->double{\n        static auto st = chrono::high_resolution_clock::now();\n        chrono::duration<double> diff = chrono::high_resolution_clock::now()-st;\n        return diff.count();\n    };\n\n    // Build prefix sums\n    Prefix3D P1, P2;\n    P1.D=D; P2.D=D;\n    P1.build(M1); P2.build(M2);\n\n    // Deterministic shared cuboid packing\n    const int CAP = min(8, D);\n    double TL = 3.5; // seconds budget for packing\n\n    // We will iterate over all possible min corners, try descending sizes\n    // For performance, we precompute for each (x0,y0,z0) the maximal runs along axes.\n    vector<int> maxX(N,0), maxY(N,0), maxZ(N,0);\n    auto recompute_max_runs = [&](const vector<char>& M, Prefix3D& P, vector<int>& mx, vector<int>& my, vector<int>& mz){\n        for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z){\n            int id3 = idx(x,y,z);\n            if (!M[id3]) { mx[id3]=my[id3]=mz[id3]=0; continue; }\n            int a=0; while (a<CAP && x+a<D && P.full(x,y,z, a+1,1,1)) ++a; mx[id3]=a;\n            int b=0; while (b<CAP && y+b<D && P.full(x,y,z, 1,b+1,1)) ++b; my[id3]=b;\n            int c=0; while (c<CAP && z+c<D && P.full(x,y,z, 1,1,c+1)) ++c; mz[id3]=c;\n        }\n    };\n    recompute_max_runs(M1, P1, maxX, maxY, maxZ);\n\n    auto try_place_from_corner = [&](int x0,int y0,int z0)->bool{\n        int id3 = idx(x0,y0,z0);\n        if (!M1[id3]) return false;\n        int a = maxX[id3], b = maxY[id3], c = maxZ[id3];\n        if (a==0 || b==0 || c==0) return false;\n        // Try sizes biased to large volumes: iterate candidates with steps\n        // We'll try top sizes by halving strategy\n        vector<tuple<int,int,int>> candidates;\n        auto push_cand = [&](int dx,int dy,int dz){\n            if (dx<=0||dy<=0||dz<=0) return;\n            if (x0+dx>D || y0+dy>D || z0+dz>D) return;\n            candidates.emplace_back(dx,dy,dz);\n        };\n        // Try full extent and some scaled downs\n        push_cand(a,b,c);\n        push_cand(a, b, max(1, c/2));\n        push_cand(a, max(1, b/2), c);\n        push_cand(max(1, a/2), b, c);\n        push_cand(a, max(1, b/2), max(1, c/2));\n        push_cand(max(1, a/2), b, max(1, c/2));\n        push_cand(max(1, a/2), max(1, b/2), c);\n        // Ensure unique\n        sort(candidates.begin(), candidates.end());\n        candidates.erase(unique(candidates.begin(), candidates.end()), candidates.end());\n        // Sort by volume descending\n        sort(candidates.begin(), candidates.end(), [](auto &L, auto &R){\n            long long vL = 1LL*get<0>(L)*get<1>(L)*get<2>(L);\n            long long vR = 1LL*get<0>(R)*get<1>(R)*get<2>(R);\n            if (vL != vR) return vL > vR;\n            if (get<0>(L)!=get<0>(R)) return get<0>(L)>get<0>(R);\n            if (get<1>(L)!=get<1>(R)) return get<1>(L)>get<1>(R);\n            return get<2>(L)>get<2>(R);\n        });\n        for (auto &cand : candidates){\n            int dx = get<0>(cand), dy = get<1>(cand), dz = get<2>(cand);\n            if (!P1.full(x0,y0,z0, dx,dy,dz)) continue; // safety check\n            // Try match in scene 2 with any permutation\n            int perms[6][3] = {\n                {dx,dy,dz},{dx,dz,dy},{dy,dx,dz},{dy,dz,dx},{dz,dx,dy},{dz,dy,dx}\n            };\n            bool placed=false;\n            int bestx=0,besty=0,bestz=0, psel=-1;\n            // Deterministic scan in scene 2\n            for(int p=0;p<6 && !placed;++p){\n                int ddx=perms[p][0], ddy=perms[p][1], ddz=perms[p][2];\n                for(int x=0;x+ddx<=D && !placed;++x){\n                    for(int y=0;y+ddy<=D && !placed;++y){\n                        for(int z=0;z+ddz<=D && !placed;++z){\n                            if (!P2.full(x,y,z, ddx,ddy,ddz)) continue;\n                            // double-check against current mask bits\n                            bool ok=true;\n                            for(int xi=x; xi<x+ddx && ok; ++xi)\n                                for(int yi=y; yi<y+ddy && ok; ++yi)\n                                    for(int zi=z; zi<z+ddz; ++zi)\n                                        if (!M2[idx(xi,yi,zi)]) { ok=false; break; }\n                            if (!ok) continue;\n                            bestx=x; besty=y; bestz=z; psel=p; placed=true;\n                        }\n                    }\n                }\n            }\n            if (!placed) continue;\n            // Place shared block\n            ++nBlocks;\n            mark_block(M1, b1, nBlocks, x0,y0,z0, dx,dy,dz);\n            int ddx=perms[psel][0], ddy=perms[psel][1], ddz=perms[psel][2];\n            mark_block(M2, b2, nBlocks, bestx,besty,bestz, ddx,ddy,ddz);\n            // Rebuild prefix sums and max runs locally (full recompute is fine)\n            P1.build(M1); P2.build(M2);\n            recompute_max_runs(M1, P1, maxX, maxY, maxZ);\n            return true;\n        }\n        return false;\n    };\n\n    // Main packing sweep over all potential corners, multiple passes until time or no progress\n    bool progress = true;\n    while (progress && now() < TL){\n        progress = false;\n        for(int x=0;x<D && now()<TL;++x){\n            for(int y=0;y<D && now()<TL;++y){\n                for(int z=0; z<D && now()<TL; ++z){\n                    int id3 = idx(x,y,z);\n                    if (!M1[id3]) continue;\n                    if (try_place_from_corner(x,y,z)) { progress = true; }\n                }\n            }\n        }\n    }\n\n    // Additional shared components from safe superset U = (f1&f2) & (r1&r2)\n    vector<vector<char>> Fboth(D, vector<char>(D,0));\n    vector<vector<char>> Rboth(D, vector<char>(D,0));\n    for (int z=0; z<D; ++z){\n        for (int x=0; x<D; ++x) Fboth[z][x] = (f[0][z][x]=='1' && f[1][z][x]=='1');\n        for (int y=0; y<D; ++y) Rboth[z][y] = (r[0][z][y]=='1' && r[1][z][y]=='1');\n    }\n    vector<char> U(N,0);\n    for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z){\n        if (Fboth[z][x] && Rboth[z][y]) U[idx(x,y,z)] = 1;\n    }\n    // Limit to remaining availability per arrangement (both must allow)\n    for(int i=0;i<N;++i) if (!(M1[i] && M2[i])) U[i]=0;\n\n    auto place_components = [&](const vector<char>& mask, bool in1, bool in2){\n        vector<char> vis(N,0);\n        const int dxs[6]={1,-1,0,0,0,0};\n        const int dys[6]={0,0,1,-1,0,0};\n        const int dzs[6]={0,0,0,0,1,-1};\n        for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z){\n            int s = idx(x,y,z);\n            if (!mask[s] || vis[s]) continue;\n            ++nBlocks;\n            queue<int> q;\n            q.push(s);\n            vis[s]=1;\n            if (in1) b1[s]=nBlocks;\n            if (in2) b2[s]=nBlocks;\n            while(!q.empty()){\n                int v=q.front(); q.pop();\n                int vx = v/(D*D);\n                int rem = v%(D*D);\n                int vy = rem/D;\n                int vz = rem% D;\n                for(int d=0; d<6; ++d){\n                    int nx=vx+dxs[d], ny=vy+dys[d], nz=vz+dzs[d];\n                    if (nx<0||nx>=D||ny<0||ny>=D||nz<0||nz>=D) continue;\n                    int u = idx(nx,ny,nz);\n                    if (mask[u] && !vis[u]){\n                        vis[u]=1;\n                        q.push(u);\n                        if (in1) b1[u]=nBlocks;\n                        if (in2) b2[u]=nBlocks;\n                    }\n                }\n            }\n        }\n    };\n\n    // Use U as shared components first\n    place_components(U, true, true);\n    // Remove U from M1/M2\n    for(int i=0;i<N;++i) if (U[i]) { M1[i]=0; M2[i]=0; }\n\n    // Leftover identical coordinates can also be shared (just in case)\n    vector<char> Csame(N,0);\n    for(int i=0;i<N;++i) if (M1[i] && M2[i]) Csame[i]=1;\n    place_components(Csame, true, true);\n    for(int i=0;i<N;++i) if (Csame[i]) { M1[i]=0; M2[i]=0; }\n\n    // Remaining exclusives\n    place_components(M1, true, false);\n    place_components(M2, false, true);\n\n    // Output\n    cout << nBlocks << \"\\n\";\n    for(int i=0;i<N;++i){\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << \"\\n\";\n    for(int i=0;i<N;++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};\nstruct AdjEdge { int to, id; long long w; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K;\n    if(!(cin>>N>>M>>K)) return 0;\n    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n    vector<Edge> edges(M);\n    vector<vector<AdjEdge>> g(N);\n    for(int j=0;j<M;j++){\n        int u,v; long long w;\n        cin>>u>>v>>w; --u;--v;\n        edges[j]={u,v,w};\n        g[u].push_back({v,j,w});\n        g[v].push_back({u,j,w});\n    }\n    vector<int> ax(K), ay(K);\n    for(int k=0;k<K;k++) cin>>ax[k]>>ay[k];\n\n    auto dist_int = [&](int xi,int yi,int a,int b)->int{\n        long double dx = (long double)xi - a;\n        long double dy = (long double)yi - b;\n        long double d = sqrt((double)(dx*dx + dy*dy));\n        // ceil to ensure coverage\n        int id = (int)ceil(d - 1e-12);\n        if(id>5000) id=5000;\n        if(id<0) id=0;\n        return id;\n    };\n\n    // Precompute station-resident distances\n    vector<vector<int>> res_order(N);\n    vector<vector<int>> res_dist(N);\n    for(int i=0;i<N;i++){\n        res_order[i].resize(K);\n        iota(res_order[i].begin(), res_order[i].end(), 0);\n        vector<int> tmpd(K);\n        for(int k=0;k<K;k++){\n            tmpd[k] = dist_int(x[i],y[i],ax[k],ay[k]);\n        }\n        // sort indices by distance\n        stable_sort(res_order[i].begin(), res_order[i].end(), [&](int a,int b){\n            return tmpd[a] < tmpd[b];\n        });\n        res_dist[i].resize(K);\n        for(int idx=0; idx<K; ++idx){\n            int rk = res_order[i][idx];\n            res_dist[i][idx] = tmpd[rk];\n        }\n    }\n\n    // Dijkstra from 0 to get shortest path tree\n    const long long INFLL = (1LL<<62);\n    vector<long long> dist(N, INFLL);\n    vector<int> parE(N, -1), parV(N, -1);\n    struct Node { long long d; int v;};\n    struct Cmp { bool operator()(const Node& a, const Node& b) const { return a.d>b.d; } };\n    priority_queue<Node, vector<Node>, Cmp> pq;\n    dist[0]=0; pq.push({0,0});\n    while(!pq.empty()){\n        auto [d,u]=pq.top(); pq.pop();\n        if(d!=dist[u]) continue;\n        for(auto &e: g[u]){\n            int v=e.to; long long nd = d + e.w;\n            if(nd < dist[v]){\n                dist[v]=nd; parE[v]=e.id; parV[v]=u;\n                pq.push({nd,v});\n            }\n        }\n    }\n    // Build SPT edges set\n    vector<int> tree_parent_edge(N,-1);\n    for(int v=1; v<N; v++){\n        tree_parent_edge[v]=parE[v];\n    }\n\n    // Baseline: assign each resident to nearest station (by Euclidean distance, not connectivity)\n    vector<int> P(N,0);\n    vector<int> req(N,0);\n    for(int k=0;k<K;k++){\n        int besti=0; int bestd = dist_int(x[0],y[0],ax[k],ay[k]);\n        for(int i=1;i<N;i++){\n            int d = dist_int(x[i],y[i],ax[k],ay[k]);\n            if(d < bestd){\n                bestd = d; besti=i;\n            }\n        }\n        if(bestd>req[besti]) req[besti]=bestd;\n    }\n    for(int i=0;i<N;i++) P[i]=req[i];\n\n    // Determine set of broadcasting stations (terminals)\n    vector<char> is_terminal(N,false);\n    int terminals=0;\n    for(int i=0;i<N;i++){\n        if(P[i]>0){ is_terminal[i]=true; terminals++; }\n    }\n    is_terminal[0] = is_terminal[0] || (P[0]>0); // ensure 0 marked if broadcasting\n\n    // Determine which tree edges are needed to connect terminals to root in the SPT\n    vector<char> need_edge(M,false);\n    vector<int> used(N,0);\n    // Mark all terminals and propagate to root\n    vector<int> degree_in_subtree(N,0);\n    for(int v=0; v<N; v++){\n        if(!is_terminal[v]) continue;\n        int u=v;\n        while(u!=0){\n            int e = tree_parent_edge[u];\n            if(e<0) break;\n            if(need_edge[e]) { // already marked\n                u = edges[e].u==u ? edges[e].v : edges[e].u;\n                continue;\n            }\n            need_edge[e]=true;\n            degree_in_subtree[edges[e].u]++;\n            degree_in_subtree[edges[e].v]++;\n            u = edges[e].u==u ? edges[e].v : edges[e].u;\n        }\n    }\n\n    // Optional: try to reduce broadcasting set by reassigning to currently broadcasting stations\n    // Build list of broadcasters\n    vector<int> broadcasters;\n    broadcasters.reserve(N);\n    for(int i=0;i<N;i++) if(P[i]>0) broadcasters.push_back(i);\n    if(broadcasters.empty()){\n        // If somehow no broadcasters (shouldn't happen as K>=2000), ensure station 1 covers nearest residents\n        // Set P[0] to max distance to all residents (capped)\n        int mx=0;\n        for(int k=0;k<K;k++){ mx = max(mx, dist_int(x[0],y[0],ax[k],ay[k])); }\n        P[0]=mx;\n        is_terminal[0]=true;\n        // no edges needed\n        fill(need_edge.begin(), need_edge.end(), false);\n    } else {\n        // Reassign residents to nearest broadcaster and recompute P\n        vector<int> newP(N,0);\n        for(int k=0;k<K;k++){\n            int besti = broadcasters[0];\n            int bestd = dist_int(x[besti],y[besti],ax[k],ay[k]);\n            for(size_t t=1;t<broadcasters.size();t++){\n                int i = broadcasters[t];\n                int d = dist_int(x[i],y[i],ax[k],ay[k]);\n                if(d < bestd){ bestd=d; besti=i; }\n            }\n            if(bestd > newP[besti]) newP[besti]=bestd;\n        }\n        P.swap(newP);\n        // update terminals\n        fill(is_terminal.begin(), is_terminal.end(), false);\n        broadcasters.clear();\n        for(int i=0;i<N;i++) if(P[i]>0){ is_terminal[i]=true; broadcasters.push_back(i); }\n        // recompute needed edges on SPT\n        fill(need_edge.begin(), need_edge.end(), false);\n        for(int v=0; v<N; v++){\n            if(!is_terminal[v]) continue;\n            int u=v;\n            while(u!=0){\n                int e = tree_parent_edge[u];\n                if(e<0) break;\n                if(need_edge[e]){\n                    u = edges[e].u==u ? edges[e].v : edges[e].u;\n                    continue;\n                }\n                need_edge[e]=true;\n                u = edges[e].u==u ? edges[e].v : edges[e].u;\n            }\n        }\n    }\n\n    // Final small tightening: try to reduce P[i] by trimming unnecessary slack.\n    // For each broadcaster i, compute max distance among residents to i when residents choose nearest broadcaster.\n    // Already done; but do a quick pass: for each i, try lowering to the next smaller actual distance in its assigned set.\n    // To keep it simple and fast, we skip recalculating assignments; the previous calculation already set P exactly.\n\n    // Build B array\n    vector<int> B(M,0);\n    for(int j=0;j<M;j++) if(need_edge[j]) B[j]=1;\n\n    // Output\n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << P[i];\n    }\n    cout << '\\n';\n    for(int j=0;j<M;j++){\n        if(j) cout << ' ';\n        cout << B[j];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    const int NN = N * (N + 1) / 2;\n\n    auto id_of = [&](int x, int y)->int { return x*(x+1)/2 + y; };\n    vector<int> x_of(NN), y_of(NN);\n    for (int x=0, id=0; x<N; ++x) for (int y=0; y<=x; ++y, ++id) { x_of[id]=x; y_of[id]=y; }\n\n    vector<int> A(NN);\n    for (int x=0; x<N; ++x) for (int y=0; y<=x; ++y) cin >> A[id_of(x,y)];\n\n    const int NONE = -1;\n    vector<array<int,2>> child(NN, {NONE, NONE});\n    for (int x=0; x<N-1; ++x) {\n        for (int y=0; y<=x; ++y) {\n            int id = id_of(x,y);\n            child[id][0] = id_of(x+1, y);\n            child[id][1] = id_of(x+1, y+1);\n        }\n    }\n\n    struct Move { int x1,y1,x2,y2; };\n    vector<Move> moves;\n    moves.reserve(10000);\n    auto do_swap = [&](int id1, int id2){\n        swap(A[id1], A[id2]);\n        moves.push_back({x_of[id1], y_of[id1], x_of[id2], y_of[id2]});\n    };\n\n    const int K_LIMIT = 10000;\n\n    // Single-pass bottom-up siftdown for all internal nodes\n    auto siftdown = [&](int start_id){\n        int id = start_id;\n        while (child[id][0] != NONE) {\n            int c0 = child[id][0], c1 = child[id][1];\n            int mc = (A[c0] < A[c1] ? c0 : c1);\n            if (A[id] <= A[mc]) break;\n            do_swap(id, mc);\n            if ((int)moves.size() >= K_LIMIT) return;\n            id = mc;\n        }\n    };\n\n    for (int x=N-2; x>=0; --x) {\n        // alternate direction per row can slightly reduce conflicts; try left-to-right for even x, right-to-left for odd x\n        if ((x & 1) == 0) {\n            for (int y=0; y<=x; ++y) {\n                siftdown(id_of(x,y));\n                if ((int)moves.size() >= K_LIMIT) break;\n            }\n        } else {\n            for (int y=x; y>=0; --y) {\n                siftdown(id_of(x,y));\n                if ((int)moves.size() >= K_LIMIT) break;\n            }\n        }\n        if ((int)moves.size() >= K_LIMIT) break;\n    }\n\n    // Safety polish: if any violations remain and we have budget, do one light pass to fix them.\n    if ((int)moves.size() < K_LIMIT) {\n        bool has_violation = false;\n        for (int x=0; x<N-1 && !has_violation; ++x) {\n            for (int y=0; y<=x; ++y) {\n                int id = id_of(x,y);\n                int c0 = child[id][0], c1 = child[id][1];\n                int mc = (A[c0] < A[c1] ? c0 : c1);\n                if (A[id] > A[mc]) { has_violation = true; break; }\n            }\n        }\n        if (has_violation) {\n            // One pass: for each violation, swap and continue siftdown locally\n            for (int x=0; x<N-1 && (int)moves.size() < K_LIMIT; ++x) {\n                for (int y=0; y<=x && (int)moves.size() < K_LIMIT; ++y) {\n                    int id = id_of(x,y);\n                    while (child[id][0] != NONE) {\n                        int c0 = child[id][0], c1 = child[id][1];\n                        int mc = (A[c0] < A[c1] ? c0 : c1);\n                        if (A[id] > A[mc]) {\n                            do_swap(id, mc);\n                            id = mc;\n                            if ((int)moves.size() >= K_LIMIT) break;\n                        } else break;\n                    }\n                }\n            }\n        }\n    }\n\n    cout << moves.size() << '\\n';\n    for (auto &mv : moves) {\n        cout << mv.x1 << ' ' << mv.y1 << ' ' << mv.x2 << ' ' << mv.y2 << '\\n';\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D,N;\n    if(!(cin>>D>>N)) return 0;\n    vector<vector<int>> obs(D, vector<int>(D, 0));\n    for(int k=0;k<N;k++){\n        int r,c; cin>>r>>c;\n        obs[r][c]=1;\n    }\n    // Entrance\n    int ei = 0, ej = (D-1)/2;\n    // Build list of free cells excluding entrance\n    vector<Pos> cells; cells.reserve(D*D-1-N);\n    // Snake order by rows, skipping obstacles and entrance\n    for(int i=0;i<D;i++){\n        if(i%2==0){\n            for(int j=0;j<D;j++){\n                if(i==ei && j==ej) continue;\n                if(obs[i][j]) continue;\n                cells.push_back({i,j});\n            }\n        }else{\n            for(int jj=D-1;jj>=0;jj--){\n                int j=jj;\n                if(i==ei && j==ej) continue;\n                if(obs[i][j]) continue;\n                cells.push_back({i,j});\n            }\n        }\n    }\n    int M = (int)cells.size(); // should be D*D-1-N\n    // Map position index for quick lookup\n    vector<vector<int>> posIndex(D, vector<int>(D, -1));\n    for(int idx=0; idx<M; idx++){\n        posIndex[cells[idx].i][cells[idx].j] = idx;\n    }\n    // Occupancy grid: 0 empty, 1 occupied (container), -1 obstacle, -2 entrance (treated as empty for BFS)\n    vector<vector<int>> occ(D, vector<int>(D, 0));\n    for(int i=0;i<D;i++) for(int j=0;j<D;j++){\n        if(obs[i][j]) occ[i][j] = -1;\n    }\n    occ[ei][ej] = -2;\n\n    // For recording where each t is placed\n    vector<Pos> loc_of_id(M, {-1,-1});\n    vector<int> id_at_cell(M, -1); // by path index\n    vector<int> free_pos(M, 1);\n\n    auto bfs_reach = [&](){\n        vector<vector<char>> vis(D, vector<char>(D, 0));\n        queue<Pos> q;\n        q.push({ei,ej});\n        vis[ei][ej]=1;\n        int di[4]={-1,1,0,0};\n        int dj[4]={0,0,-1,1};\n        while(!q.empty()){\n            auto p=q.front(); q.pop();\n            for(int k=0;k<4;k++){\n                int ni=p.i+di[k], nj=p.j+dj[k];\n                if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                if(vis[ni][nj]) continue;\n                if(occ[ni][nj]==0 || occ[ni][nj]==-2){ // empty or entrance\n                    vis[ni][nj]=1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n        return vis;\n    };\n\n    // Online placement\n    for(int d=0; d<M; d++){\n        int t; cin>>t;\n        // compute reachable empty cells mask\n        auto vis = bfs_reach();\n        int ideal = t; if(ideal<0) ideal=0; if(ideal>=M) ideal=M-1;\n        int chosen_idx = -1;\n        // search window expanding\n        int W = 12;\n        int maxW = M;\n        for(int w=W; w<=maxW && chosen_idx==-1; w+=12){\n            int L = max(0, ideal - w);\n            int R = min(M-1, ideal + w);\n            // Collect reachable free candidates with minimal |pos-ideal|\n            int bestScore = INT_MAX;\n            int bestIdx = -1;\n            for(int pos=L; pos<=R; pos++){\n                if(!free_pos[pos]) continue;\n                Pos p = cells[pos];\n                if(!vis[p.i][p.j]) continue;\n                int score = abs(pos - ideal);\n                if(score < bestScore){\n                    bestScore = score;\n                    bestIdx = pos;\n                }else if(score == bestScore && bestIdx!=-1){\n                    // tie-break: for larger t, prefer larger pos; for smaller t, prefer smaller pos\n                    if(t*2 >= M){\n                        if(pos > bestIdx) bestIdx = pos;\n                    }else{\n                        if(pos < bestIdx) bestIdx = pos;\n                    }\n                }\n            }\n            if(bestIdx!=-1) chosen_idx = bestIdx;\n        }\n        if(chosen_idx==-1){\n            // Fallback: pick any reachable free cell, prefer towards ideal direction\n            int bestIdx=-1, bestScore=INT_MAX;\n            for(int pos=0; pos<M; pos++){\n                if(!free_pos[pos]) continue;\n                Pos p=cells[pos];\n                if(!vis[p.i][p.j]) continue;\n                int score = abs(pos - ideal);\n                if(score < bestScore){\n                    bestScore=score; bestIdx=pos;\n                }\n            }\n            if(bestIdx!=-1) chosen_idx=bestIdx;\n        }\n        if(chosen_idx==-1){\n            // As a last resort, pick any free (shouldn't happen because all free cells are reachable by guarantee if empty)\n            for(int pos=0; pos<M; pos++){\n                if(free_pos[pos]){\n                    chosen_idx=pos; break;\n                }\n            }\n        }\n        // Place\n        Pos place = cells[chosen_idx];\n        cout<<place.i<<\" \"<<place.j<<\"\\n\"<<flush;\n        occ[place.i][place.j] = 1;\n        free_pos[chosen_idx]=0;\n        id_at_cell[chosen_idx]=t;\n        loc_of_id[t]=place;\n    }\n\n    // Extraction: repeatedly remove smallest-ID reachable\n    // Build a map from (i,j) to ID\n    vector<vector<int>> id_grid(D, vector<int>(D, -1));\n    for(int pos=0; pos<M; pos++){\n        if(id_at_cell[pos]>=0){\n            Pos p = cells[pos];\n            id_grid[p.i][p.j] = id_at_cell[pos];\n        }\n    }\n\n    vector<pair<int,int>> output_order;\n    output_order.reserve(M);\n\n    auto bfs_reach_cells = [&](){\n        vector<vector<char>> vis(D, vector<char>(D, 0));\n        queue<Pos> q;\n        q.push({ei,ej});\n        vis[ei][ej]=1;\n        int di[4]={-1,1,0,0};\n        int dj[4]={0,0,-1,1};\n        while(!q.empty()){\n            auto p=q.front(); q.pop();\n            for(int k=0;k<4;k++){\n                int ni=p.i+di[k], nj=p.j+dj[k];\n                if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                if(vis[ni][nj]) continue;\n                // reachable through empty cells only\n                if(occ[ni][nj]==0 || occ[ni][nj]==-2){\n                    vis[ni][nj]=1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n        return vis;\n    };\n\n    for(int removed=0; removed<M; removed++){\n        // compute which occupied cells are currently reachable: cell must be adjacent via empty path to entrance\n        // A container is removable if its cell is reachable from entrance through empty cells; i.e., the container's cell must itself be marked reachable when considering it as occupied? The definition says:\n        // \"The square containing the container to be transported out must be reachable from the entrance by only passing through adjacent empty squares\"\n        // That implies the path does not include the container square (since it's not empty). Typically the last step into its square would require the square to be empty, which is impossible. Usually interpretation is: there exists a path of empty cells to a neighbor of the target, and then we can remove it. However AtCoder's typical definition here counts the container square as allowed at endpoint.\n        // The common approach is to allow reaching its cell if we treat it as empty for reachability test of candidate. We'll check neighbors.\n        auto vis = bfs_reach_cells();\n        int bestID = INT_MAX;\n        Pos bestP{-1,-1};\n        for(int i=0;i<D;i++){\n            for(int j=0;j<D;j++){\n                if(id_grid[i][j] < 0) continue;\n                // check if reachable: there exists a path of empty cells from entrance to a neighbor of (i,j)\n                bool reachable = false;\n                int di[4]={-1,1,0,0};\n                int dj[4]={0,0,-1,1};\n                for(int k=0;k<4;k++){\n                    int ni=i+di[k], nj=j+dj[k];\n                    if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                    if(vis[ni][nj]) { reachable=true; break; }\n                }\n                if(!reachable) continue;\n                int curID = id_grid[i][j];\n                if(curID < bestID){\n                    bestID = curID;\n                    bestP = {i,j};\n                }\n            }\n        }\n        if(bestID==INT_MAX){\n            // Fallback: if none reachable by neighbor method, allow cells that themselves are marked reachable if we consider them empty\n            // Temporarily mark all occupied as walls; vis marks empty reachables. None found -> choose any with minimal ID that is adjacent via zero? We'll pick minimal ID anywhere.\n            for(int i=0;i<D;i++){\n                for(int j=0;j<D;j++){\n                    if(id_grid[i][j] >= 0){\n                        int curID = id_grid[i][j];\n                        if(curID < bestID){\n                            bestID=curID; bestP={i,j};\n                        }\n                    }\n                }\n            }\n        }\n        // Output and remove\n        cout<<bestP.i<<\" \"<<bestP.j<<\"\\n\";\n        // Mark empty now\n        occ[bestP.i][bestP.j] = 0;\n        id_grid[bestP.i][bestP.j] = -1;\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int DX[4] = {1,-1,0,0};\nstatic const int DY[4] = {0,0,1,-1};\n\nint n, m, Cn;\ninline bool inb(int i,int j){ return (unsigned)i < (unsigned)n && (unsigned)j < (unsigned)n; }\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if(!(cin >> n >> m)) return 0;\n    Cn = n*n;\n    vector<int> d(Cn);\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            int c; cin >> c;\n            d[i*n+j] = c;\n        }\n    }\n    int C = m+1;\n\n    // Original adjacency matrix\n    vector<vector<char>> A(C, vector<char>(C, 0));\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            int u = d[i*n+j];\n            if(i+1<n){\n                int v = d[(i+1)*n+j];\n                if(u!=v){ A[u][v]=A[v][u]=1; }\n            }\n            if(j+1<n){\n                int v = d[i*n+(j+1)];\n                if(u!=v){ A[u][v]=A[v][u]=1; }\n            }\n        }\n    }\n    for(int i=0;i<n;i++){\n        int c1 = d[i*n+0];\n        int c2 = d[i*n+(n-1)];\n        A[0][c1]=A[c1][0]=1;\n        A[0][c2]=A[c2][0]=1;\n    }\n    for(int j=0;j<n;j++){\n        int c1 = d[0*n+j];\n        int c2 = d[(n-1)*n+j];\n        A[0][c1]=A[c1][0]=1;\n        A[0][c2]=A[c2][0]=1;\n    }\n\n    // Current adjacency counts\n    vector<vector<int>> adjCnt(C, vector<int>(C, 0));\n    auto recomputeAdjCnt = [&](){\n        for(int u=0;u<C;u++) fill(adjCnt[u].begin(), adjCnt[u].end(), 0);\n        for(int i=0;i<n;i++){\n            for(int j=0;j<n;j++){\n                int u = d[i*n+j];\n                if(i+1<n){\n                    int v = d[(i+1)*n+j];\n                    if(u!=v){ adjCnt[u][v]++; adjCnt[v][u]++; }\n                }\n                if(j+1<n){\n                    int v = d[i*n+(j+1)];\n                    if(u!=v){ adjCnt[u][v]++; adjCnt[v][u]++; }\n                }\n            }\n        }\n        for(int i=0;i<n;i++){\n            int c1 = d[i*n+0];\n            int c2 = d[i*n+(n-1)];\n            if(c1!=0){ adjCnt[0][c1]++; adjCnt[c1][0]++; }\n            if(c2!=0){ adjCnt[0][c2]++; adjCnt[c2][0]++; }\n        }\n        for(int j=0;j<n;j++){\n            int c1 = d[0*n+j];\n            int c2 = d[(n-1)*n+j];\n            if(c1!=0){ adjCnt[0][c1]++; adjCnt[c1][0]++; }\n            if(c2!=0){ adjCnt[0][c2]++; adjCnt[c2][0]++; }\n        }\n    };\n    recomputeAdjCnt();\n\n    vector<int> totalCells(C, 0);\n    for(int v : d) totalCells[v]++;\n\n    vector<char> allowZeroAdj(C, 0);\n    for(int c=0;c<C;c++) allowZeroAdj[c] = A[0][c];\n\n    vector<char> zeroConn(Cn, 0);\n\n    deque<int> frontier;\n    vector<char> inFrontier(Cn, 0);\n\n    auto addToFrontier = [&](int p){\n        if(inFrontier[p]) return;\n        int i = p / n, j = p % n;\n        int c = d[p];\n        if(c==0) return;\n        if(!allowZeroAdj[c]) return;\n        if(totalCells[c] <= 1) return;\n        bool canConnectZero = (i==0 || i==n-1 || j==0 || j==n-1);\n        if(!canConnectZero){\n            for(int dir=0;dir<4;dir++){\n                int ni = i + DX[dir], nj = j + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int q = ni*n+nj;\n                if(d[q]==0 && zeroConn[q]){ canConnectZero = true; break; }\n            }\n        }\n        if(!canConnectZero) return;\n        frontier.push_back(p);\n        inFrontier[p] = 1;\n    };\n\n    // Initialize frontier with boundary cells of carveable colors\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            int p = i*n+j;\n            int c = d[p];\n            if(c==0) continue;\n            if(!allowZeroAdj[c]) continue;\n            if(totalCells[c] <= 1) continue;\n            if(i==0 || i==n-1 || j==0 || j==n-1){\n                addToFrontier(p);\n            }\n        }\n    }\n\n    auto t0 = chrono::high_resolution_clock::now();\n    const double TIME_LIMIT = 1.90;\n\n    // Connectivity check\n    vector<char> vis(Cn, 0);\n    auto connectedAfterRemoval = [&](int c, int p)->bool{\n        if(totalCells[c] <= 1) return false;\n        int pi = p / n, pj = p % n;\n        int neighCount = 0;\n        int start = -1;\n        int samePos[4], sc=0;\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            int q = ni*n+nj;\n            if(d[q] == c){ neighCount++; start = q; samePos[sc++] = q; }\n        }\n        if(neighCount <= 1) return true;\n        // Tiny shortcut: if two neighbors forming a 2x2 with p share a same-color neighbor among themselves\n        if(neighCount==2){\n            int q1 = samePos[0], q2 = samePos[1];\n            int q1i = q1/n, q1j = q1%n, q2i = q2/n, q2j = q2%n;\n            // If they are orthogonal and share a common same-color neighbor (the corner opposite to p)\n            if(q1i!=q2i && q1j!=q2j){\n                int ci = q1i, cj = q2j; // corner opposite to p\n                if(inb(ci,cj)){\n                    int r = ci*n+cj;\n                    if(d[r]==c){\n                        // q1 -- r -- q2 connects around p\n                        return true;\n                    }\n                }\n            }\n        }\n        fill(vis.begin(), vis.end(), 0);\n        deque<int> dq;\n        dq.push_back(start);\n        vis[start] = 1;\n        int reach = 1;\n        const int need = totalCells[c]-1;\n        while(!dq.empty()){\n            int v = dq.front(); dq.pop_front();\n            if(reach >= need) break;\n            int vi = v / n, vj = v % n;\n            for(int dir=0;dir<4;dir++){\n                int ni = vi + DX[dir], nj = vj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int u = ni*n+nj;\n                if(u==p) continue;\n                if(!vis[u] && d[u]==c){\n                    vis[u]=1; dq.push_back(u); reach++;\n                }\n            }\n        }\n        return reach == need;\n    };\n\n    auto floodZeroFrom = [&](int sIdx){\n        if(d[sIdx] != 0) return;\n        if(zeroConn[sIdx]) return;\n        deque<int> dq;\n        dq.push_back(sIdx);\n        zeroConn[sIdx] = 1;\n        while(!dq.empty()){\n            int v = dq.front(); dq.pop_front();\n            int vi = v / n, vj = v % n;\n            for(int dir=0;dir<4;dir++){\n                int ni = vi + DX[dir], nj = vj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int u = ni*n+nj;\n                if(d[u]==0 && !zeroConn[u]){\n                    zeroConn[u]=1;\n                    dq.push_back(u);\n                }\n            }\n        }\n    };\n\n    auto compute_k0 = [&](int p)->int{\n        int pi = p / n, pj = p % n;\n        int k0 = 0;\n        if(pi==0) k0++;\n        if(pi==n-1) k0++;\n        if(pj==0) k0++;\n        if(pj==n-1) k0++;\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            if(d[ni*n+nj]==0) k0++;\n        }\n        return k0;\n    };\n\n    // Try to remove a given cell p with full checks\n    auto tryRemove = [&](int p)->bool{\n        int c = d[p];\n        if(c==0) return false;\n        if(!allowZeroAdj[c]) return false;\n        if(totalCells[c] <= 1) return false;\n        int pi = p / n, pj = p % n;\n        // zero connectivity condition\n        bool canConnectZero = (pi==0 || pi==n-1 || pj==0 || pj==n-1);\n        if(!canConnectZero){\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int q = ni*n+nj;\n                if(d[q]==0 && zeroConn[q]){ canConnectZero = true; break; }\n            }\n        }\n        if(!canConnectZero) return false;\n\n        // Neighbor constraints and gather neighbors\n        int neighArr[4], neighCnt=0;\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            int y = d[ni*n+nj];\n            neighArr[neighCnt++] = y;\n            if(y!=c && !allowZeroAdj[y]) return false;\n        }\n        // Preserve required adjacencies c-y\n        for(int k=0;k<neighCnt;k++){\n            int y = neighArr[k];\n            if(y==c) continue;\n            if(A[c][y]){\n                int contrib = 0;\n                for(int dir=0;dir<4;dir++){\n                    int ni = pi + DX[dir], nj = pj + DY[dir];\n                    if(!inb(ni,nj)) continue;\n                    if(d[ni*n+nj]==y) contrib++;\n                }\n                if(adjCnt[c][y] == contrib) return false;\n            }\n        }\n        // Preserve c-0 adjacency if required\n        if(A[0][c]){\n            int k0 = compute_k0(p);\n            if(adjCnt[0][c] == k0) return false;\n        }\n        // Connectivity\n        if(!connectedAfterRemoval(c, p)) return false;\n\n        // Apply removal: update adjCnt\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(inb(ni,nj)){\n                int y = d[ni*n+nj];\n                if(y != c){\n                    adjCnt[c][y]--; adjCnt[y][c]--;\n                }\n            }else{\n                adjCnt[0][c]--; adjCnt[c][0]--;\n            }\n        }\n        d[p] = 0;\n        totalCells[c]--;\n\n        // Flood 0 connectivity\n        if(pi==0 || pi==n-1 || pj==0 || pj==n-1) floodZeroFrom(p);\n        else{\n            bool neighZeroConn = false;\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int q = ni*n+nj;\n                if(d[q]==0 && zeroConn[q]){ neighZeroConn = true; break; }\n            }\n            if(neighZeroConn) floodZeroFrom(p);\n        }\n\n        // Add new edges between 0 and neighbors\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            int y = d[ni*n+nj];\n            if(y != 0){\n                adjCnt[0][y]++; adjCnt[y][0]++;\n            }\n        }\n\n        // Expand frontier around p\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            int q = ni*n+nj;\n            if(d[q]!=0){\n                addToFrontier(q);\n                int qi = q/n, qj = q%n;\n                for(int dir2=0;dir2<4;dir2++){\n                    int ri = qi + DX[dir2], rj = qj + DY[dir2];\n                    if(!inb(ri,rj)) continue;\n                    int r = ri*n+rj;\n                    if(d[r]!=0) addToFrontier(r);\n                }\n            }\n        }\n\n        return true;\n    };\n\n    // Initial rim seeding: quick pass along boundary under small time slice\n    {\n        auto tStart = chrono::high_resolution_clock::now();\n        for(int i=0;i<n;i++){\n            for(int j=0;j<n;j++){\n                if(!(i==0 || i==n-1 || j==0 || j==n-1)) continue;\n                int p = i*n+j;\n                if(d[p]==0) continue;\n                int c = d[p];\n                if(!allowZeroAdj[c]) continue;\n                if(totalCells[c] <= 1) continue;\n                // Quick local checks before full try\n                // Avoid if this is the only c-0 contact\n                if(A[0][c] && adjCnt[0][c] == compute_k0(p)) continue;\n                tryRemove(p);\n                auto tNow = chrono::high_resolution_clock::now();\n                if(chrono::duration<double>(tNow - tStart).count() > 0.10) break;\n            }\n        }\n    }\n\n    int rebuildCounter = 0;\n    while(true){\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - t0).count();\n        if(elapsed > TIME_LIMIT) break;\n\n        if(frontier.empty()){\n            rebuildCounter++;\n            if(rebuildCounter > 3) break;\n            for(int k=0;k<Cn;k++) inFrontier[k]=0;\n            for(int i=0;i<n;i++){\n                for(int j=0;j<n;j++){\n                    int p = i*n+j;\n                    addToFrontier(p);\n                }\n            }\n            if(frontier.empty()) break;\n        }\n\n        // Pop a batch and prioritize by heuristic score\n        struct Node{ int p; int score; };\n        vector<Node> nodes;\n        nodes.reserve(256);\n        int take = min<int>(256, frontier.size());\n        for(int t=0;t<take;t++){\n            int p = frontier.front(); frontier.pop_front();\n            inFrontier[p]=0;\n            int c = d[p];\n            if(c==0) continue;\n            if(!allowZeroAdj[c]) continue;\n            if(totalCells[c] <= 1) continue;\n            int i = p/n, j = p%n;\n            bool canConnectZero = (i==0 || i==n-1 || j==0 || j==n-1);\n            if(!canConnectZero){\n                for(int dir=0;dir<4;dir++){\n                    int ni = i + DX[dir], nj = j + DY[dir];\n                    if(!inb(ni,nj)) continue;\n                    int q = ni*n+nj;\n                    if(d[q]==0 && zeroConn[q]){ canConnectZero = true; break; }\n                }\n            }\n            if(!canConnectZero) continue;\n\n            int same=0, reqAdj=0, boundaryContrib=0, badNbr=0;\n            for(int dir=0;dir<4;dir++){\n                int ni = i + DX[dir], nj = j + DY[dir];\n                if(inb(ni,nj)){\n                    int y = d[ni*n+nj];\n                    if(y==c) same++;\n                    else{\n                        if(!allowZeroAdj[y]) badNbr++;\n                        if(A[c][y]) reqAdj++;\n                    }\n                }else boundaryContrib++;\n            }\n            int rare = (adjCnt[0][c] <= 2) ? 3 : (adjCnt[0][c] <= 5 ? 1 : 0);\n            int score = same*12 - reqAdj*4 - boundaryContrib*2 - badNbr*100 - rare;\n            nodes.push_back({p, score});\n        }\n        sort(nodes.begin(), nodes.end(), [&](const Node& a, const Node& b){\n            if(a.score != b.score) return a.score > b.score;\n            return a.p < b.p;\n        });\n\n        bool anyRemoved = false;\n        for(const auto& nd : nodes){\n            auto t1 = chrono::high_resolution_clock::now();\n            double el = chrono::duration<double>(t1 - t0).count();\n            if(el > TIME_LIMIT) break;\n\n            int p = nd.p;\n            int c = d[p];\n            if(c==0) continue;\n\n            // If removing p would drop the last c-0 adjacency, try to pre-ensure new contact\n            bool needEnsure = false;\n            if(A[0][c]){\n                int k0 = compute_k0(p);\n                if(adjCnt[0][c] == k0) needEnsure = true;\n            }\n            if(needEnsure){\n                // Find a nearby cell r of color c that can be removed and connects to zero/boundary\n                bool ensured = false;\n                int pi = p/n, pj = p%n;\n                // Search in radius 2 Manhattan\n                for(int rad=1; rad<=2 && !ensured; rad++){\n                    for(int dir=0; dir<4 && !ensured; dir++){\n                        for(int t=1; t<=rad; t++){\n                            int ni = pi + DX[dir]*t;\n                            int nj = pj + DY[dir]*t;\n                            if(!inb(ni,nj)) continue;\n                            int r = ni*n+nj;\n                            if(d[r] != c) continue;\n                            int ri = ni, rj = nj;\n                            bool canConn = (ri==0 || ri==n-1 || rj==0 || rj==n-1);\n                            if(!canConn){\n                                for(int dd=0; dd<4; dd++){\n                                    int si = ri + DX[dd], sj = rj + DY[dd];\n                                    if(!inb(si,sj)) continue;\n                                    int s = si*n+sj;\n                                    if(d[s]==0 && zeroConn[s]){ canConn = true; break; }\n                                }\n                            }\n                            if(!canConn) continue;\n                            // Avoid last c-0 contact removal for r\n                            if(A[0][c] && adjCnt[0][c] == compute_k0(r)) continue;\n                            if(tryRemove(r)){\n                                ensured = true;\n                            }\n                        }\n                    }\n                }\n            }\n\n            if(tryRemove(p)){\n                anyRemoved = true;\n            }\n        }\n\n        if(!anyRemoved && frontier.empty()){\n            rebuildCounter++;\n            if(rebuildCounter > 3) break;\n            for(int k=0;k<Cn;k++) inFrontier[k]=0;\n            for(int i=0;i<n;i++){\n                for(int j=0;j<n;j++){\n                    int p = i*n+j;\n                    addToFrontier(p);\n                }\n            }\n        }\n    }\n\n    // Output\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            if(j) cout << ' ';\n            cout << d[i*n+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    uint64_t seed = chrono::high_resolution_clock::now().time_since_epoch().count();\n    mt19937_64 rng(seed);\n\n    // Budgets\n    int Q_duel = max(0, Q / 5);           // 20% for duels focusing on top items\n    int Q_corr = Q - Q_duel;              // rest for correlation\n    // Correlation parameters: three K values\n    int Ks[3];\n    Ks[0] = max(2, N / 2);\n    Ks[1] = max(2, N / 3);\n    Ks[2] = max(2, N / 4);\n\n    // Data\n    vector<long long> corr(N, 0);\n    vector<int> appear(N, 0);\n    vector<int> idx(N); iota(idx.begin(), idx.end(), 0);\n\n    auto do_query = [&](const vector<int>& L, const vector<int>& R)->int{\n        cout << (int)L.size() << \" \" << (int)R.size();\n        for (int v : L) cout << \" \" << v;\n        for (int v : R) cout << \" \" << v;\n        cout << \"\\n\" << flush;\n        string s; if (!(cin >> s)) exit(0);\n        if (s == \"<\") return -1;\n        if (s == \">\") return +1;\n        return 0;\n    };\n\n    // Helper: pick k distinct indices biased toward low appearance count\n    auto pick_k_biased = [&](int k)->vector<int>{\n        // Build weights inversely proportional to 1+appear\n        vector<double> w(N);\n        double sumw = 0;\n        for (int i = 0; i < N; i++) { w[i] = 1.0 / (1.0 + appear[i]); sumw += w[i]; }\n        vector<int> chosen;\n        chosen.reserve(k);\n        vector<char> used(N, 0);\n        for (int t = 0; t < k && t < N; t++) {\n            // sample index by roulette wheel\n            double r = uniform_real_distribution<double>(0, sumw)(rng);\n            int pick = -1;\n            double acc = 0;\n            for (int i = 0; i < N; i++) if (!used[i]) {\n                acc += w[i];\n                if (acc >= r) { pick = i; break; }\n            }\n            if (pick == -1) {\n                // fallback: choose first unused\n                for (int i = 0; i < N; i++) if (!used[i]) { pick = i; break; }\n            }\n            if (pick == -1) break;\n            used[pick] = 1;\n            chosen.push_back(pick);\n            sumw -= w[pick];\n        }\n        return chosen;\n    };\n\n    // Phase: correlation queries with mixed K and balanced participation\n    int kc = 0;\n    for (int q = 0; q < Q_corr; q++) {\n        int K = Ks[kc];\n        kc = (kc + 1) % 3;\n        K = min(K, N);\n        if (K < 2) K = 2;\n        vector<int> sel = pick_k_biased(K);\n        int k = (int)sel.size();\n        if (k < 2) {\n            // fallback: pick 2 random distinct\n            int a = uniform_int_distribution<int>(0, N-1)(rng);\n            int b = uniform_int_distribution<int>(0, N-1)(rng);\n            while (b == a) b = uniform_int_distribution<int>(0, N-1)(rng);\n            sel = {a, b};\n            k = 2;\n        }\n        // shuffle sel and split alternately\n        shuffle(sel.begin(), sel.end(), rng);\n        vector<int> L, R;\n        L.reserve(k/2+1); R.reserve(k/2+1);\n        for (int t = 0; t < k; t++) {\n            if (t & 1) R.push_back(sel[t]); else L.push_back(sel[t]);\n            appear[sel[t]]++;\n        }\n        int y = do_query(L, R);\n        if (y != 0) {\n            for (int v : L) corr[v] += y;\n            for (int v : R) corr[v] -= y;\n        }\n    }\n\n    // Build initial ranking by correlation\n    long long mnCorr = *min_element(corr.begin(), corr.end());\n    vector<double> corrScore(N);\n    for (int i = 0; i < N; i++) {\n        long long s = corr[i] - mnCorr + 1;\n        corrScore[i] = pow((double)s, 1.3); // slightly accentuate\n    }\n    // Normalize corrScore to [0,1]\n    double cmin = *min_element(corrScore.begin(), corrScore.end());\n    double cmax = *max_element(corrScore.begin(), corrScore.end());\n    if (cmax - cmin < 1e-12) cmax = cmin + 1.0;\n    for (int i = 0; i < N; i++) corrScore[i] = (corrScore[i] - cmin) / (cmax - cmin);\n\n    // Select top M for duels\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    stable_sort(ord.begin(), ord.end(), [&](int a, int b){\n        if (corrScore[a] != corrScore[b]) return corrScore[a] > corrScore[b];\n        return a < b;\n    });\n    int M = min(N, max(10, N / 2)); // duel among top half\n    vector<int> top(ord.begin(), ord.begin() + M);\n\n    // Duels among top to refine order\n    vector<int> wins(N, 0), games(N, 0);\n    for (int q = 0; q < Q_duel; q++) {\n        int ia = uniform_int_distribution<int>(0, M-1)(rng);\n        int ib = uniform_int_distribution<int>(0, M-1)(rng);\n        while (ib == ia) ib = uniform_int_distribution<int>(0, M-1)(rng);\n        int i = top[ia], j = top[ib];\n        int y = do_query(vector<int>{i}, vector<int>{j});\n        if (y > 0) wins[i]++; else if (y < 0) wins[j]++;\n        games[i]++; games[j]++;\n    }\n    vector<double> wr(N, 0.5);\n    for (int i = 0; i < N; i++) wr[i] = games[i] ? (double)wins[i]/games[i] : 0.5;\n    // Normalize wr to [0,1]\n    double wrMin = 1.0, wrMax = 0.0;\n    for (double x : wr) { wrMin = min(wrMin, x); wrMax = max(wrMax, x); }\n    if (wrMax - wrMin < 1e-12) wrMax = wrMin + 1.0;\n    vector<double> wrScaled(N);\n    for (int i = 0; i < N; i++) wrScaled[i] = (wr[i] - wrMin) / (wrMax - wrMin);\n\n    // Combine into final estimates and apply isotonic smoothing over corr order\n    vector<double> est(N);\n    double a_corr = 1.0, a_wr = 0.3;\n    for (int i = 0; i < N; i++) {\n        double v = a_corr * (1.0 + 9.0 * corrScore[i]) + a_wr * (1.0 + 4.0 * wrScaled[i]);\n        if (!isfinite(v) || v <= 0) v = 1.0;\n        est[i] = v;\n    }\n    // Isotonic smoothing along corr order to enforce non-increasing estimated weights\n    // Pool Adjacent Violators Algorithm (PAVA)\n    vector<double> smooth(N);\n    vector<int> block_sz(N, 1);\n    for (int p = 0; p < N; p++) smooth[p] = est[ord[p]];\n    for (int p = 1; p < N; p++) {\n        if (smooth[p] > smooth[p-1]) {\n            int q = p;\n            while (q > 0 && smooth[q] > smooth[q-1]) {\n                double s = smooth[q]*block_sz[q] + smooth[q-1]*block_sz[q-1];\n                int b = block_sz[q] + block_sz[q-1];\n                double avg = s / b;\n                smooth[q-1] = avg;\n                block_sz[q-1] = b;\n                // shift left by removing q\n                for (int t = q; t < N; t++) { smooth[t] = (t+1 < N ? smooth[t+1] : smooth[t]); block_sz[t] = (t+1 < N ? block_sz[t+1] : block_sz[t]); }\n                p--; // adjust due to shift\n                q--;\n            }\n        }\n    }\n    // Map smoothed back to items\n    vector<double> est_smooth(N);\n    for (int i = 0; i < N; i++) est_smooth[ord[i]] = smooth[i];\n\n    // Final ordering for packing\n    vector<int> order(N); iota(order.begin(), order.end(), 0);\n    stable_sort(order.begin(), order.end(), [&](int a, int b){\n        if (est_smooth[a] != est_smooth[b]) return est_smooth[a] > est_smooth[b];\n        return a < b;\n    });\n\n    // LPT packing\n    vector<int> assign(N, 0);\n    vector<double> bins(D, 0.0);\n    using PDI = pair<double,int>;\n    priority_queue<PDI, vector<PDI>, greater<PDI>> pq;\n    for (int d = 0; d < D; d++) pq.emplace(0.0, d);\n    for (int v : order) {\n        auto [s, d] = pq.top(); pq.pop();\n        assign[v] = d;\n        s += est_smooth[v];\n        bins[d] = s;\n        pq.emplace(s, d);\n    }\n\n    // Local search: focus on extremes with limited trials\n    vector<vector<int>> binItems(D);\n    for (int i = 0; i < N; i++) binItems[assign[i]].push_back(i);\n\n    auto variance = [&](const vector<double>& bs)->double{\n        double mean = 0; for (double x : bs) mean += x; mean /= D;\n        double v = 0; for (double x : bs){ double d = x-mean; v += d*d; }\n        return v / D;\n    };\n    int iters = 600;\n    for (int it = 0; it < iters; it++) {\n        int h = int(max_element(bins.begin(), bins.end()) - bins.begin());\n        int l = int(min_element(bins.begin(), bins.end()) - bins.begin());\n        if (h == l) break;\n        double baseVar = variance(bins);\n        double bestDelta = 0.0;\n        int bi = -1, bj = -1, bestType = 0;\n\n        // Candidates\n        vector<int> candH = binItems[h], candL = binItems[l];\n        int tryH = min((int)candH.size(), 24);\n        int tryL = min((int)candL.size(), 24);\n        if ((int)candH.size() > tryH) { shuffle(candH.begin(), candH.end(), rng); candH.resize(tryH); }\n        if ((int)candL.size() > tryL) { shuffle(candL.begin(), candL.end(), rng); candL.resize(tryL); }\n\n        // Single move\n        for (int i : candH) {\n            bins[h] -= est_smooth[i]; bins[l] += est_smooth[i];\n            double vnew = variance(bins);\n            double delta = baseVar - vnew;\n            bins[h] += est_smooth[i]; bins[l] -= est_smooth[i];\n            if (delta > bestDelta + 1e-12) { bestDelta = delta; bestType = 1; bi = i; }\n        }\n        // Swap\n        for (int i : candH) for (int j : candL) {\n            bins[h] = bins[h] - est_smooth[i] + est_smooth[j];\n            bins[l] = bins[l] - est_smooth[j] + est_smooth[i];\n            double vnew = variance(bins);\n            double delta = baseVar - vnew;\n            bins[h] = bins[h] + est_smooth[i] - est_smooth[j];\n            bins[l] = bins[l] + est_smooth[j] - est_smooth[i];\n            if (delta > bestDelta + 1e-12) { bestDelta = delta; bestType = 2; bi = i; bj = j; }\n        }\n        if (bestType == 0 || bestDelta <= 1e-12) break;\n\n        auto remove_from = [&](vector<int>& v, int x){\n            for (size_t p = 0; p < v.size(); ++p) if (v[p]==x){ v[p]=v.back(); v.pop_back(); return; }\n        };\n        if (bestType == 1) {\n            remove_from(binItems[h], bi);\n            binItems[l].push_back(bi);\n            bins[h] -= est_smooth[bi]; bins[l] += est_smooth[bi];\n        } else {\n            remove_from(binItems[h], bi);\n            remove_from(binItems[l], bj);\n            binItems[h].push_back(bj);\n            binItems[l].push_back(bi);\n            bins[h] = bins[h] - est_smooth[bi] + est_smooth[bj];\n            bins[l] = bins[l] - est_smooth[bj] + est_smooth[bi];\n        }\n    }\n\n    // Output final assignment\n    vector<int> finalAssign(N);\n    for (int d = 0; d < D; d++) for (int i : binItems[d]) finalAssign[i] = d;\n\n    for (int i = 0; i < N; i++) {\n        if (i) cout << ' ';\n        cout << finalAssign[i];\n    }\n    cout << \"\\n\" << flush;\n\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Heuristic solver for AHC026-like problem\n// n=200, m=10 fixed in tests, but code keeps generality.\n\nstruct Solver {\n    int n, m, H;\n    vector<vector<int>> st; // stacks: bottom -> top\n    vector<int> whereS; // stack index (0..m-1) for each box (1..n)\n    vector<int> whereIdx; // index in stack vector\n    vector<pair<int,int>> ops; // (v,i) with i in [0..m]\n    vector<char> removed;\n\n    void read_input() {\n        cin >> n >> m;\n        H = n / m;\n        st.assign(m, {});\n        whereS.assign(n+1, -1);\n        whereIdx.assign(n+1, -1);\n        removed.assign(n+1, 0);\n        for (int i = 0; i < m; ++i) {\n            st[i].resize(H);\n            for (int j = 0; j < H; ++j) {\n                int v; cin >> v;\n                st[i][j] = v;\n                whereS[v] = i;\n                whereIdx[v] = j;\n            }\n        }\n    }\n\n    inline int top_value(int i) const {\n        if (st[i].empty()) return INT_MAX/4; // treat empty as very large top for preference\n        return st[i].back();\n    }\n\n    void do_move(int v, int dest) {\n        // Operation 1: move suffix starting at v from its current stack to top of dest (1-based output dest+1)\n        int s = whereS[v];\n        if (s == dest) {\n            // avoid self-move; but spec allows it; however it's wasteful. We should not call this.\n            // To be safe, don't perform and don't record.\n            return;\n        }\n        int idx = whereIdx[v];\n        int k = (int)st[s].size() - idx; // number of boxes moved\n        // record op\n        ops.emplace_back(v, dest+1);\n        // move elements\n        // append to dest\n        st[dest].reserve(st[dest].size() + k);\n        for (int i = idx; i < (int)st[s].size(); ++i) {\n            int x = st[s][i];\n            st[dest].push_back(x);\n            whereS[x] = dest;\n            whereIdx[x] = (int)st[dest].size() - 1;\n        }\n        // erase from source\n        st[s].resize(idx);\n    }\n\n    void do_carry(int v) {\n        // Operation 2: carry out v; it must be top of its stack and be the smallest remaining.\n        int s = whereS[v];\n        if (s == -1) return; // already removed\n        // record op\n        ops.emplace_back(v, 0);\n        // pop\n        int topv = st[s].back();\n        if (topv != v) {\n            // Shouldn't happen; guard\n            // Find v and remove it (fallback)\n            auto it = find(st[s].begin(), st[s].end(), v);\n            if (it != st[s].end()) {\n                st[s].erase(it);\n                // rebuild indices in this stack\n                for (int i = 0; i < (int)st[s].size(); ++i) whereIdx[st[s][i]] = i;\n            }\n        } else {\n            st[s].pop_back();\n        }\n        whereS[v] = -1;\n        whereIdx[v] = -1;\n        removed[v] = 1;\n    }\n\n    int choose_dest(int v) {\n        int s = whereS[v];\n        // Preferred bin stack\n        int bin = (v - 1) / H; // 0-based\n        int d_pref = min(bin, m-1); // guard\n        if (d_pref != s) return d_pref;\n        // choose another stack:\n        int best = -1;\n        int bestTop = -1;\n        int bestHeight = INT_MAX;\n        for (int i = 0; i < m; ++i) if (i != s) {\n            int tv = top_value(i);\n            // prefer larger top value; empty stack has INT_MAX/4 which is largest\n            if (tv > bestTop) {\n                bestTop = tv;\n                bestHeight = (int)st[i].size();\n                best = i;\n            } else if (tv == bestTop) {\n                int h = (int)st[i].size();\n                if (h < bestHeight) {\n                    bestHeight = h;\n                    best = i;\n                }\n            }\n        }\n        if (best == -1) best = (s+1)%m;\n        return best;\n    }\n\n    void solve() {\n        // Process in ascending order\n        for (int t = 1; t <= n; ++t) {\n            if (removed[t]) continue;\n            int s = whereS[t];\n            // while t not at top of its stack, move suffix including t to chosen destination\n            if (st[s].empty()) continue; // shouldn't\n            if (st[s].back() == t) {\n                do_carry(t);\n                continue;\n            }\n            int dest = choose_dest(t);\n            // perform move so that t becomes top of dest\n            do_move(t, dest);\n            // Now t should be top at dest\n            do_carry(t);\n            // No further consolidation to keep it simple\n            if ((int)ops.size() >= 4999) {\n                // fallback: carry remaining if possible when already on top\n                for (int u = t+1; u <= n && (int)ops.size() < 5000; ++u) {\n                    if (!removed[u]) {\n                        int su = whereS[u];\n                        if (su != -1 && !st[su].empty() && st[su].back() == u) {\n                            do_carry(u);\n                        } else {\n                            // cannot finish, break\n                            break;\n                        }\n                    }\n                }\n                break;\n            }\n        }\n    }\n\n    void output() {\n        int K = (int)ops.size();\n        for (auto &p : ops) {\n            cout << p.first << \" \" << p.second << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver solver;\n    solver.read_input();\n    solver.solve();\n    solver.output();\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin>>N)) return 0;\n    vector<string> h(N-1), v(N);\n    for(int i=0;i<N-1;i++) cin>>h[i];\n    for(int i=0;i<N;i++) cin>>v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>d[i][j];\n\n    auto inb = [&](int i,int j){ return 0<=i && i<N && 0<=j && j<N; };\n    const int di[4]={0,1,0,-1};\n    const int dj[4]={1,0,-1,0};\n    string DIR = \"RDLU\";\n    auto canMoveDir = [&](int i,int j,int dir)->bool{\n        if(dir==0){ if(j+1>=N) return false; return v[i][j]=='0'; }\n        if(dir==2){ if(j-1<0)   return false; return v[i][j-1]=='0'; }\n        if(dir==1){ if(i+1>=N) return false; return h[i][j]=='0'; }\n        if(dir==3){ if(i-1<0)   return false; return h[i-1][j]=='0'; }\n        return false;\n    };\n    auto idx = [&](int i,int j){ return i*N + j; };\n    auto posOf = [&](int id)->Pos{ return Pos{ id/N, id%N }; };\n\n    int V = N*N;\n    const int INF = 1e9;\n\n    // Precompute all-pairs BFS distances and parent for reconstruction\n    vector<vector<int>> dist(V, vector<int>(V, INF));\n    vector<vector<pair<int,int>>> parent(V, vector<pair<int,int>>(V, {-1,-1}));\n    for(int si=0; si<N; si++){\n        for(int sj=0; sj<N; sj++){\n            int s = idx(si,sj);\n            deque<Pos> q;\n            vector<char> vis(V, 0);\n            q.push_back({si,sj});\n            vis[s]=1;\n            dist[s][s]=0;\n            parent[s][s] = {si,sj};\n            while(!q.empty()){\n                auto p = q.front(); q.pop_front();\n                int pid = idx(p.i,p.j);\n                for(int dir=0; dir<4; dir++){\n                    int ni=p.i+di[dir], nj=p.j+dj[dir];\n                    if(!inb(ni,nj)) continue;\n                    if(!canMoveDir(p.i,p.j,dir)) continue;\n                    int nid = idx(ni,nj);\n                    if(vis[nid]) continue;\n                    vis[nid]=1;\n                    dist[s][nid] = dist[s][pid] + 1;\n                    parent[s][nid] = {p.i, p.j};\n                    q.push_back({ni,nj});\n                }\n            }\n        }\n    }\n\n    auto reconstruct_path_dirs = [&](Pos s, Pos t)->vector<int>{\n        vector<int> dirs;\n        if(s.i==t.i && s.j==t.j) return dirs;\n        int sid = idx(s.i,s.j);\n        int tid = idx(t.i,t.j);\n        if(dist[sid][tid] >= INF) return dirs;\n        vector<Pos> rev;\n        Pos cur = t;\n        while(!(cur.i==s.i && cur.j==s.j)){\n            rev.push_back(cur);\n            auto par = parent[sid][ idx(cur.i,cur.j) ];\n            cur = {par.first, par.second};\n        }\n        reverse(rev.begin(), rev.end());\n        int ci=s.i, cj=s.j;\n        for(auto &p: rev){\n            for(int dir=0; dir<4; dir++){\n                if(ci+di[dir]==p.i && cj+dj[dir]==p.j){\n                    dirs.push_back(dir);\n                    ci=p.i; cj=p.j;\n                    break;\n                }\n            }\n        }\n        return dirs;\n    };\n\n    // Build base visiting order: row serpentine per row\n    vector<vector<int>> rowSeq(N, vector<int>(N));\n    for(int i=0;i<N;i++){\n        if(i%2==0){\n            for(int j=0;j<N;j++) rowSeq[i][j] = idx(i,j);\n        }else{\n            for(int j=0;j<N;j++) rowSeq[i][j] = idx(i,N-1-j);\n        }\n    }\n\n    // Row-direction toggle heuristic: for each row, try reversing the row order if it reduces local connection costs\n    auto rowCostSegment = [&](int r)->long long{\n        // Sum of distances inside row (consecutive in rowSeq[r])\n        long long sum=0;\n        for(int k=0;k<N-1;k++){\n            int a=rowSeq[r][k], b=rowSeq[r][k+1];\n            sum += dist[a][b];\n        }\n        return sum;\n    };\n    auto rowEndpoints = [&](int r)->pair<int,int>{\n        return { rowSeq[r].front(), rowSeq[r].back() };\n    };\n    for(int r=0;r<N;r++){\n        // Compute cost including connections to previous and next rows\n        long long curCost = 0;\n        auto [s,e] = rowEndpoints(r);\n        curCost += rowCostSegment(r);\n        if(r==0){\n            // from (0,0) to start of row0\n            curCost += dist[idx(0,0)][s];\n        }else{\n            auto [ps,pe] = rowEndpoints(r-1);\n            curCost += dist[pe][s];\n        }\n        if(r < N-1){\n            auto [ns,ne] = rowEndpoints(r+1);\n            curCost += dist[e][ns];\n        }else{\n            // back to (0,0) from last row end will be accounted later overall; for local decision, approximate with dist to (0,0)\n            curCost += dist[e][idx(0,0)];\n        }\n        // Try reversed\n        reverse(rowSeq[r].begin(), rowSeq[r].end());\n        long long revCost = 0;\n        auto [s2,e2] = rowEndpoints(r);\n        revCost += rowCostSegment(r);\n        if(r==0){\n            revCost += dist[idx(0,0)][s2];\n        }else{\n            auto [ps,pe] = rowEndpoints(r-1);\n            revCost += dist[pe][s2];\n        }\n        if(r < N-1){\n            auto [ns,ne] = rowEndpoints(r+1);\n            revCost += dist[e2][ns];\n        }else{\n            revCost += dist[e2][idx(0,0)];\n        }\n        if(revCost >= curCost){\n            // revert back\n            reverse(rowSeq[r].begin(), rowSeq[r].end());\n        } // else keep reversed\n    }\n\n    // Flatten order\n    vector<int> order;\n    order.reserve(V);\n    for(int i=0;i<N;i++){\n        for(int k=0;k<N;k++) order.push_back(rowSeq[i][k]);\n    }\n\n    // Intra-row micro-optimization: two passes of adjacent swaps to reduce dist sum\n    for(int row=0; row<N; row++){\n        int start = row*N;\n        int end = start + N - 1;\n        for(int pass=0; pass<2; pass++){\n            for(int k=start; k<end-1; k++){\n                int a = order[k];\n                int b = order[k+1];\n                int c = order[k+2];\n                long long before = (long long)dist[a][b] + dist[b][c];\n                long long after  = (long long)dist[a][c] + dist[c][b];\n                if(after < before){\n                    swap(order[k+1], order[k+2]);\n                }\n            }\n            for(int k=end-1; k>start+0; k--){\n                int a = order[k-2];\n                int b = order[k-1];\n                int c = order[k];\n                long long before = (long long)dist[a][b] + dist[b][c];\n                long long after  = (long long)dist[a][c] + dist[c][b];\n                if(after < before){\n                    swap(order[k-1], order[k]);\n                }\n            }\n        }\n    }\n\n    // Build base moves by chaining shortest paths and return to (0,0)\n    string baseMoves;\n    baseMoves.reserve(V*4);\n    Pos curp = posOf(order[0]);\n    for(int k=1;k<V;k++){\n        Pos nxt = posOf(order[k]);\n        auto seg = reconstruct_path_dirs(curp, nxt);\n        for(int dir: seg) baseMoves.push_back(DIR[dir]);\n        curp = nxt;\n    }\n    {\n        auto seg = reconstruct_path_dirs(curp, {0,0});\n        for(int dir: seg) baseMoves.push_back(DIR[dir]);\n        curp = {0,0};\n    }\n\n    // Nodes along base path\n    vector<Pos> baseNodes;\n    baseNodes.reserve(baseMoves.size()+1);\n    {\n        int i=0,j=0;\n        baseNodes.push_back({i,j});\n        for(char c: baseMoves){\n            int dir = (c=='R'?0: c=='D'?1: c=='L'?2:3);\n            i += di[dir]; j += dj[dir];\n            baseNodes.push_back({i,j});\n        }\n    }\n\n    // Precompute best local loop per cell (prefer 4-cycles)\n    struct Loop { vector<int> dirs; int cost; bool is4; };\n    vector<vector<Loop>> loopOf(N, vector<Loop>(N));\n    auto makeLoopAt = [&](int i,int j)->Loop{\n        struct Cand { int score; vector<int> dirs; };\n        vector<Cand> cands;\n        auto add4 = [&](int a, int b){\n            int i0=i, j0=j;\n            if(!canMoveDir(i0,j0,a)) return;\n            int i1=i0+di[a], j1=j0+dj[a];\n            if(!canMoveDir(i1,j1,b)) return;\n            int i2=i1+di[b], j2=j1+dj[b];\n            int a2=(a+2)%4, b2=(b+2)%4;\n            if(!canMoveDir(i2,j2,a2)) return;\n            int i3=i2+di[a2], j3=j2+dj[a2];\n            if(!(i3==i1 && j3==j1)) return;\n            if(!canMoveDir(i3,j3,b2)) return;\n            int i4=i3+di[b2], j4=j3+dj[b2];\n            if(!(i4==i && j4==j)) return;\n            int score = d[i][j] + d[i1][j1] + d[i2][j2] + d[i3][j3];\n            cands.push_back({score, {a,b,a2,b2}});\n        };\n        add4(0,1); add4(1,2); add4(2,3); add4(3,0);\n        if(!cands.empty()){\n            auto best = *max_element(cands.begin(), cands.end(), [](const Cand&a,const Cand&b){return a.score<b.score;});\n            return Loop{best.dirs, (int)best.dirs.size(), true};\n        }\n        // fallback ping-pong\n        int bestDir=-1, bestScore=-1;\n        for(int dir=0; dir<4; dir++){\n            if(!canMoveDir(i,j,dir)) continue;\n            int ni=i+di[dir], nj=j+dj[dir];\n            int sc = d[i][j] + d[ni][nj];\n            if(sc>bestScore){ bestScore=sc; bestDir=dir; }\n        }\n        if(bestDir!=-1) return Loop{ vector<int>{bestDir, (bestDir+2)%4}, 2, false };\n        return Loop{ vector<int>(), 0, false };\n    };\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) loopOf[i][j]=makeLoopAt(i,j);\n\n    // Visit times and gap estimates\n    int L0 = (int)baseMoves.size();\n    vector<vector<vector<int>>> visits(N, vector<vector<int>>(N));\n    for(int t=0;t<(int)baseNodes.size();t++){\n        auto p = baseNodes[t];\n        visits[p.i][p.j].push_back(t);\n    }\n    vector<vector<double>> gapEst(N, vector<double>(N, 0.0));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            auto &vec = visits[i][j];\n            if(vec.size()<=1){\n                gapEst[i][j] = (double)L0;\n            }else{\n                long long sumGap=0;\n                for(size_t k=1;k<vec.size();k++) sumGap += (vec[k]-vec[k-1]);\n                sumGap += ((int)baseNodes.size()-1 - vec.back()) + vec.front();\n                double avgGap = (double)sumGap / (double)vec.size();\n                gapEst[i][j] = max(1.0, avgGap);\n            }\n        }\n    }\n\n    // Hotspots with priority: d * gap * eff / cost\n    struct Hot { int i,j; int cost; bool is4; double pr; };\n    vector<Hot> hots;\n    hots.reserve(N*N);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        const auto &lp = loopOf[i][j];\n        if(lp.cost==0) continue;\n        double eff = lp.is4 ? 2.0 : 1.0;\n        double pr = (double)d[i][j] * gapEst[i][j] * eff / (double)lp.cost;\n        hots.push_back({i,j, lp.cost, lp.is4, pr});\n    }\n    if(hots.empty()){\n        cout<<baseMoves<<\"\\n\";\n        return 0;\n    }\n    sort(hots.begin(), hots.end(), [](const Hot&a,const Hot&b){ return a.pr > b.pr; });\n    int K = min((int)hots.size(), max(60, (N*N)/10));\n\n    // Budget\n    long long budgetMax = 100000LL;\n    long long B = budgetMax - (long long)L0;\n    if(B<0) B=0;\n\n    double totalPr=0.0;\n    for(int t=0; t<K; t++) totalPr += max(1e-9, hots[t].pr);\n\n    // Occurrence indices for each hot\n    vector<vector<int>> occIdx(K);\n    for(int t=0; t<K; t++){\n        occIdx[t] = visits[ hots[t].i ][ hots[t].j ];\n    }\n\n    // Allocate repeats conservatively\n    vector<long long> repeats(K, 0);\n    long long used=0;\n    for(int t=0;t<K;t++){\n        auto &hc = hots[t];\n        double frac = max(1e-12, hc.pr) / totalPr;\n        long long targetCost = (long long) floor(frac * (double)B);\n        long long rep = targetCost / hc.cost;\n        long long perVisitCap = hc.is4 ? 22 : 10;\n        long long cap = (long long)occIdx[t].size() * perVisitCap;\n        if(rep > cap) rep = cap;\n        repeats[t]=rep;\n        used += rep * hc.cost;\n    }\n    if(used > B){\n        double scale = (double)B / (double)max(1LL, used);\n        used=0;\n        for(int t=0;t<K;t++){\n            repeats[t] = (long long) floor(repeats[t] * scale);\n            used += repeats[t] * hots[t].cost;\n        }\n    }\n    long long rem = B - used;\n    if(rem > 0){\n        // Greedy to top few 4-cycles\n        vector<int> ord(K);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a,int b){\n            double ea = (double)d[ hots[a].i ][ hots[a].j ] * (hots[a].is4?1.7:0.7) / hots[a].cost;\n            double eb = (double)d[ hots[b].i ][ hots[b].j ] * (hots[b].is4?1.7:0.7) / hots[b].cost;\n            return ea>eb;\n        });\n        int limit = min((int)ord.size(), 10);\n        for(int k=0; k<limit && rem>0; k++){\n            int id = ord[k];\n            int cost = hots[id].cost;\n            if(cost==0) continue;\n            long long occ = (long long)occIdx[id].size();\n            long long extraCap = occ * 6;\n            long long can = min(extraCap, rem / cost);\n            if(can<=0) continue;\n            repeats[id] += can;\n            rem -= can * cost;\n        }\n    }\n\n    // Spread repeats evenly across occurrences\n    vector<vector<long long>> perOcc(K);\n    for(int t=0;t<K;t++){\n        int m = (int)occIdx[t].size();\n        perOcc[t].assign(m, 0);\n        long long R = repeats[t];\n        if(m>0 && R>0){\n            for(long long r=0; r<R; r++){\n                perOcc[t][ r % m ]++;\n            }\n            long long cap = hots[t].is4 ? 24 : 12;\n            for(int k=0;k<m;k++) if(perOcc[t][k] > cap) perOcc[t][k]=cap;\n        }\n    }\n\n    // Map node time index to injection loop and count\n    vector<long long> injectCount(baseNodes.size(), 0);\n    vector<const vector<int>*> injectDirs(baseNodes.size(), nullptr);\n    for(int t=0; t<K; t++){\n        auto &occ = occIdx[t];\n        auto &per = perOcc[t];\n        auto &lp = loopOf[ hots[t].i ][ hots[t].j ].dirs;\n        for(int k=0;k<(int)occ.size();k++){\n            if(per[k] > 0){\n                int ti = occ[k];\n                injectCount[ti] += per[k];\n                injectDirs[ti] = &lp;\n            }\n        }\n    }\n\n    // Emit final path, respecting length limit\n    string out;\n    long long L0ll = (long long)baseMoves.size();\n    out.reserve(min(100000LL, L0ll + B));\n    long long budgetMoves = 100000LL;\n    long long remainingBase = L0ll;\n    for(size_t t=0; t<baseNodes.size(); t++){\n        long long cnt = injectCount[t];\n        auto lp = injectDirs[t];\n        if(cnt>0 && lp && !lp->empty()){\n            int cost = (int)lp->size();\n            while(cnt>0){\n                if(budgetMoves <= remainingBase) break;\n                long long free = budgetMoves - remainingBase;\n                if(free < cost) break;\n                for(int dir: *lp){\n                    out.push_back(DIR[dir]);\n                    budgetMoves--;\n                }\n                cnt--;\n            }\n        }\n        if(t < baseMoves.size()){\n            if(budgetMoves==0) break;\n            out.push_back(baseMoves[t]);\n            budgetMoves--;\n            remainingBase--;\n        }\n    }\n    cout<<out<<\"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\nstatic inline long long manh(const Pos& a, const Pos& b){\n    return llabs(a.i - b.i) + llabs(a.j - b.j);\n}\n\nstruct WordData {\n    array<vector<Pos>,5> L;\n    vector<long long> back1;     // on L1: min cost from L1[j] to finish\n    vector<long long> tailCost0; // per L0 index: exact min from fixed first to finish\n};\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 si, sj;\n    cin >> si >> sj;\n    vector<string> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\n    vector<string> t(M);\n    for(int k=0;k<M;k++) cin >> t[k];\n\n    // Positions per letter\n    vector<vector<Pos>> letterPos(26);\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            letterPos[A[i][j]-'A'].push_back({i,j});\n        }\n    }\n\n    // Precompute per-word data: levels and backward DP for tail costs\n    vector<WordData> W(M);\n    for(int k=0;k<M;k++){\n        const string &s = t[k];\n        for(int d=0; d<5; d++) W[k].L[d] = letterPos[s[d]-'A'];\n        const auto &L0 = W[k].L[0], &L1 = W[k].L[1], &L2 = W[k].L[2], &L3 = W[k].L[3], &L4 = W[k].L[4];\n        int n1=L1.size(), n2=L2.size(), n3=L3.size(), n4=L4.size();\n\n        vector<long long> back3(n3, (long long)4e18);\n        for(int j=0;j<n3;j++){\n            long long best=(long long)4e18;\n            for(int i4=0;i4<n4;i4++){\n                long long v = manh(L3[j], L4[i4]);\n                if(v<best) best=v;\n            }\n            back3[j]=best;\n        }\n        vector<long long> back2(n2, (long long)4e18);\n        for(int j=0;j<n2;j++){\n            long long best=(long long)4e18;\n            for(int i3=0;i3<n3;i3++){\n                long long v = manh(L2[j], L3[i3]) + back3[i3];\n                if(v<best) best=v;\n            }\n            back2[j]=best;\n        }\n        W[k].back1.assign(n1, (long long)4e18);\n        for(int j=0;j<n1;j++){\n            long long best=(long long)4e18;\n            for(int i2=0;i2<n2;i2++){\n                long long v = manh(L1[j], L2[i2]) + back2[i2];\n                if(v<best) best=v;\n            }\n            W[k].back1[j]=best;\n        }\n        int n0=L0.size();\n        W[k].tailCost0.assign(n0, (long long)4e18);\n        for(int i0=0;i0<n0;i0++){\n            long long best=(long long)4e18;\n            for(int i1=0;i1<n1;i1++){\n                long long v = manh(L0[i0], L1[i1]) + W[k].back1[i1];\n                if(v<best) best=v;\n            }\n            W[k].tailCost0[i0]=best;\n        }\n    }\n\n    vector<int> rem(M);\n    iota(rem.begin(), rem.end(), 0);\n    vector<pair<int,int>> ops;\n    ops.reserve(200*5);\n    Pos cur{si,sj};\n\n    const double BETA = 0.3;\n    const double GAMMA = 0.1; // start-distance bias\n    const int K_END = 5;\n    const long long DELTA_SWITCH = 2;\n\n    // exact DP from start for word k\n    auto exact_dp = [&](int k, const Pos& start,\n                        vector<long long>& d0, vector<long long>& d1, vector<long long>& d2, vector<long long>& d3, vector<long long>& d4,\n                        vector<int>& p0, vector<int>& p1, vector<int>& p2, vector<int>& p3){\n        const auto &L0 = W[k].L[0], &L1 = W[k].L[1], &L2 = W[k].L[2], &L3 = W[k].L[3], &L4 = W[k].L[4];\n        int n0=L0.size(), n1=L1.size(), n2=L2.size(), n3=L3.size(), n4=L4.size();\n        d0.assign(n0, 0);\n        for(int i0=0;i0<n0;i0++) d0[i0] = manh(start, L0[i0]);\n        d1.assign(n1, (long long)4e18); p0.assign(n1, -1);\n        for(int i1=0;i1<n1;i1++){\n            long long best=(long long)4e18; int arg=-1;\n            for(int i0=0;i0<n0;i0++){\n                long long v = d0[i0] + manh(L0[i0], L1[i1]);\n                if(v<best){best=v; arg=i0;}\n            }\n            d1[i1]=best; p0[i1]=arg;\n        }\n        d2.assign(n2, (long long)4e18); p1.assign(n2, -1);\n        for(int i2=0;i2<n2;i2++){\n            long long best=(long long)4e18; int arg=-1;\n            for(int i1=0;i1<n1;i1++){\n                long long v = d1[i1] + manh(L1[i1], L2[i2]);\n                if(v<best){best=v; arg=i1;}\n            }\n            d2[i2]=best; p1[i2]=arg;\n        }\n        d3.assign(n3, (long long)4e18); p2.assign(n3, -1);\n        for(int i3=0;i3<n3;i3++){\n            long long best=(long long)4e18; int arg=-1;\n            for(int i2=0;i2<n2;i2++){\n                long long v = d2[i2] + manh(L2[i2], L3[i3]);\n                if(v<best){best=v; arg=i2;}\n            }\n            d3[i3]=best; p2[i3]=arg;\n        }\n        d4.assign(n4, (long long)4e18); p3.assign(n4, -1);\n        for(int i4=0;i4<n4;i4++){\n            long long best=(long long)4e18; int arg=-1;\n            for(int i3=0;i3<n3;i3++){\n                long long v = d3[i3] + manh(L3[i3], L4[i4]);\n                if(v<best){best=v; arg=i3;}\n            }\n            d4[i4]=best; p3[i4]=arg;\n        }\n    };\n\n    // exact next cost via precomputed tail given start\n    auto next_cost_exact_via_tail = [&](int k, const Pos& start)->long long{\n        const auto &L0 = W[k].L[0];\n        const auto &tail = W[k].tailCost0;\n        long long best = (long long)4e18;\n        for(int i0=0;i0<(int)L0.size();i0++){\n            long long v = manh(start, L0[i0]) + tail[i0];\n            if(v<best) best=v;\n        }\n        return (best==(long long)4e18?0:best);\n    };\n\n    // nearest distance from a point to each letter's occurrence list (cached per iteration)\n    array<long long,26> nearestToLetter;\n\n    while(!rem.empty()){\n        // compute nearest start distance for each letter from current cur\n        for(int c=0;c<26;c++){\n            long long best = (long long)4e18;\n            for(const auto &p : letterPos[c]){\n                long long d = manh(cur, p);\n                if(d < best) best = d;\n            }\n            nearestToLetter[c] = best;\n        }\n\n        long long bestCost = (1LL<<60);\n        double bestAug = 1e100;\n        int bestIdxPos = -1;\n        array<int,5> bestIdxInLevels = {-1,-1,-1,-1,-1};\n\n        for(int p=0; p<(int)rem.size(); p++){\n            int a = rem[p];\n            // Exact DP for word a\n            vector<long long> d0,d1,d2,d3,d4;\n            vector<int> p0,p1,p2,p3;\n            exact_dp(a, cur, d0,d1,d2,d3,d4, p0,p1,p2,p3);\n\n            const auto &L0 = W[a].L[0], &L1 = W[a].L[1], &L2 = W[a].L[2], &L3 = W[a].L[3], &L4 = W[a].L[4];\n            int n4=L4.size();\n            // Top K_END ends by d4\n            vector<int> ord4(n4);\n            iota(ord4.begin(), ord4.end(), 0);\n            int take = min(K_END, n4);\n            nth_element(ord4.begin(), ord4.begin()+take-1, ord4.end(), [&](int x, int y){ return d4[x] < d4[y]; });\n            partial_sort(ord4.begin(), ord4.begin()+take, ord4.end(), [&](int x, int y){ return d4[x] < d4[y]; });\n\n            // Evaluate each end with lookahead and start-distance bias\n            long long bestLocalCost = (1LL<<60);\n            double bestLocalAug = 1e100;\n            array<int,5> bestLocalIdx = {-1,-1,-1,-1,-1};\n\n            // start-distance penalty: nearest distance from cur to first letter of this word\n            long long startBias = nearestToLetter[t[a][0]-'A'];\n\n            for(int rk=0; rk<take; rk++){\n                int i4 = ord4[rk];\n                long long costA = d4[i4];\n                int i3 = p3[i4];\n                int i2 = p2[i3];\n                int i1 = p1[i2];\n                int i0 = p0[i1];\n                Pos endA = L4[i4];\n\n                long long bestNext = 0;\n                if(rem.size()>1){\n                    bestNext = (long long)4e18;\n                    for(int q=0; q<(int)rem.size(); q++){\n                        if(q==p) continue;\n                        int b = rem[q];\n                        long long v = next_cost_exact_via_tail(b, endA);\n                        if(v < bestNext) bestNext = v;\n                    }\n                    if(bestNext == (long long)4e18) bestNext = 0;\n                }\n\n                double aug = (double)costA + BETA * (double)bestNext + GAMMA * (double)startBias;\n                if(aug < bestLocalAug || (abs(aug - bestLocalAug) < 1e-9 && costA < bestLocalCost)){\n                    bestLocalAug = aug;\n                    bestLocalCost = costA;\n                    bestLocalIdx = {i0,i1,i2,i3,i4};\n                }\n            }\n\n            // Micro local refinement: consider any end within DELTA_SWITCH\n            {\n                int i4_best = bestLocalIdx[4];\n                long long baseCost = d4[i4_best];\n                Pos baseEnd = L4[i4_best];\n                long long baseNext = 0;\n                if(rem.size()>1){\n                    baseNext = (long long)4e18;\n                    for(int q=0;q<(int)rem.size();q++){\n                        if(q==p) continue;\n                        int b = rem[q];\n                        long long v = next_cost_exact_via_tail(b, baseEnd);\n                        if(v<baseNext) baseNext=v;\n                    }\n                    if(baseNext==(long long)4e18) baseNext=0;\n                }\n                double baseAug = (double)baseCost + BETA * (double)baseNext + GAMMA * (double)startBias;\n\n                for(int i4=0; i4<n4; i4++){\n                    if(d4[i4] > baseCost + DELTA_SWITCH) continue;\n                    if(i4 == i4_best) continue;\n                    long long costA = d4[i4];\n                    int i3 = p3[i4];\n                    int i2 = p2[i3];\n                    int i1 = p1[i2];\n                    int i0 = p0[i1];\n                    Pos endA = L4[i4];\n\n                    long long bestNext = 0;\n                    if(rem.size()>1){\n                        bestNext = (long long)4e18;\n                        for(int q=0;q<(int)rem.size();q++){\n                            if(q==p) continue;\n                            int b = rem[q];\n                            long long v = next_cost_exact_via_tail(b, endA);\n                            if(v<bestNext) bestNext=v;\n                        }\n                        if(bestNext==(long long)4e18) bestNext=0;\n                    }\n                    double aug = (double)costA + BETA * (double)bestNext + GAMMA * (double)startBias;\n                    if(aug + 1e-9 < baseAug){\n                        baseAug = aug;\n                        bestLocalAug = aug;\n                        bestLocalCost = costA;\n                        bestLocalIdx = {i0,i1,i2,i3,i4};\n                    }\n                }\n            }\n\n            if(bestLocalAug < bestAug || (abs(bestLocalAug - bestAug) < 1e-9 && bestLocalCost < bestCost)){\n                bestAug = bestLocalAug;\n                bestCost = bestLocalCost;\n                bestIdxPos = p;\n                bestIdxInLevels = bestLocalIdx;\n            }\n        }\n\n        if(bestIdxPos == -1){\n            // Fallback: choose the closest first letter\n            long long bestD = (1LL<<60); int pick=0;\n            for(int p=0;p<(int)rem.size();p++){\n                int a = rem[p];\n                for(const auto &q : W[a].L[0]){\n                    long long d = manh(cur, q);\n                    if(d<bestD){bestD=d; pick=p;}\n                }\n            }\n            bestIdxPos = pick;\n            // Compute exact indices\n            int a = rem[bestIdxPos];\n            vector<long long> d0,d1,d2,d3,d4;\n            vector<int> p0,p1,p2,p3;\n            exact_dp(a, cur, d0,d1,d2,d3,d4, p0,p1,p2,p3);\n            int i4 = int(min_element(d4.begin(), d4.end()) - d4.begin());\n            int i3 = p3[i4];\n            int i2 = p2[i3];\n            int i1 = p1[i2];\n            int i0 = p0[i1];\n            bestIdxInLevels = {i0,i1,i2,i3,i4};\n        }\n\n        // Emit operations for the chosen word\n        int chosen = rem[bestIdxPos];\n        const auto &L0 = W[chosen].L[0];\n        const auto &L1 = W[chosen].L[1];\n        const auto &L2 = W[chosen].L[2];\n        const auto &L3 = W[chosen].L[3];\n        const auto &L4 = W[chosen].L[4];\n        array<Pos,5> seq = {\n            L0[bestIdxInLevels[0]],\n            L1[bestIdxInLevels[1]],\n            L2[bestIdxInLevels[2]],\n            L3[bestIdxInLevels[3]],\n            L4[bestIdxInLevels[4]]\n        };\n        for(int z=0; z<5; z++){\n            ops.emplace_back(seq[z].i, seq[z].j);\n            cur = seq[z];\n        }\n        rem.erase(rem.begin() + bestIdxPos);\n    }\n\n    for(auto &p : ops){\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int di, dj;\n    vector<int> cells;\n    bitset<400> mask; // up to 20*20\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n    if (!(cin >> N >> M >> eps)) return 0;\n    int G = N*N;\n    auto idx = [N](int i,int j){ return i*N + j; };\n    auto ij = [N](int p){ return pair<int,int>(p/N, p%N); };\n\n    vector<vector<pair<int,int>>> shapes(M);\n    vector<int> shape_h(M), shape_w(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        int min_i = INT_MAX, min_j = INT_MAX, max_i = INT_MIN, max_j = INT_MIN;\n        for (int t = 0; t < d; ++t) {\n            int i,j; cin >> i >> j;\n            shapes[k][t] = {i,j};\n            min_i = min(min_i, i);\n            min_j = min(min_j, j);\n            max_i = max(max_i, i);\n            max_j = max(max_j, j);\n        }\n        shape_h[k] = max_i - min_i + 1;\n        shape_w[k] = max_j - min_j + 1;\n    }\n\n    // Generate candidates\n    vector<vector<Placement>> candidates(M);\n    for (int k = 0; k < M; ++k) {\n        int h = shape_h[k], w = shape_w[k];\n        for (int di = 0; di + h <= N; ++di) {\n            for (int dj = 0; dj + w <= N; ++dj) {\n                Placement P; P.di = di; P.dj = dj;\n                P.mask.reset();\n                bool ok = true;\n                for (auto [oi,oj] : shapes[k]) {\n                    int i = di + oi, j = dj + oj;\n                    if (i<0||i>=N||j<0||j>=N) { ok=false; break; }\n                    int p = idx(i,j);\n                    P.cells.push_back(p);\n                    P.mask.set(p);\n                }\n                if (ok) candidates[k].push_back(move(P));\n            }\n        }\n    }\n\n    // Reverse index (k,t) covering p\n    vector<vector<pair<int,int>>> cell_covers(G);\n    for (int k = 0; k < M; ++k) {\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            for (int p : candidates[k][t].cells) {\n                cell_covers[p].push_back({k,t});\n            }\n        }\n    }\n\n    // Alive flags and counts\n    vector<vector<char>> alive(M);\n    vector<int> alive_count(M);\n    for (int k = 0; k < M; ++k) {\n        alive[k].assign(candidates[k].size(), 1);\n        alive_count[k] = (int)candidates[k].size();\n    }\n\n    // Per-shape per-cell count of alive candidates covering p\n    vector<vector<int>> cnt_cover(M, vector<int>(G, 0));\n    // For each cell, total number of alive candidates covering it (across shapes)\n    vector<int> cover_count(G, 0);\n    // Per cell, number of shapes that can cover it (have at least one alive candidate covering it)\n    vector<int> S_can(G, 0);\n    for (int k = 0; k < M; ++k) {\n        vector<char> can(N*N, 0);\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            for (int p : candidates[k][t].cells) {\n                cnt_cover[k][p]++;\n                cover_count[p]++;\n                can[p] = 1;\n            }\n        }\n        for (int p = 0; p < G; ++p) if (can[p]) S_can[p]++;\n    }\n\n    // Forced coverage constraints: for shape k, set of cells that must be covered by its placement\n    vector<bitset<400>> forced_cover(M);\n    for (int k = 0; k < M; ++k) forced_cover[k].reset();\n\n    // cell state: -1 unknown, 0 zero, 1 positive\n    vector<int> state(G, -1);\n\n    auto flushout = [](){ cout.flush(); };\n\n    deque<int> shapes_to_commit;\n\n    auto kill_candidate = [&](int k, int t) {\n        if (!alive[k][t]) return;\n        alive[k][t] = 0;\n        alive_count[k]--;\n        // update counts\n        const bitset<400>& m = candidates[k][t].mask;\n        for (int p = m._Find_first(); p < G; p = m._Find_next(p)) {\n            cnt_cover[k][p]--;\n            cover_count[p]--;\n            if (cnt_cover[k][p] == 0) {\n                S_can[p]--;\n            }\n        }\n        if (alive_count[k] == 1) shapes_to_commit.push_back(k);\n    };\n\n    // Apply forced constraints for shape k: eliminate any candidate not covering all forced cells\n    auto enforce_forced = [&](int k) {\n        const bitset<400>& fc = forced_cover[k];\n        if (fc.none()) return;\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            if (!alive[k][t]) continue;\n            // candidate must include all forced bits\n            // Check (mask & fc) == fc\n            bitset<400> tmp = candidates[k][t].mask;\n            tmp &= fc;\n            if (tmp != fc) {\n                kill_candidate(k,t);\n            }\n        }\n    };\n\n    auto commit_singletons = [&]() {\n        while (!shapes_to_commit.empty()) {\n            int k = shapes_to_commit.front(); shapes_to_commit.pop_front();\n            if (alive_count[k] != 1) continue;\n            int tstar = -1;\n            for (int t = 0; t < (int)alive[k].size(); ++t) if (alive[k][t]) { tstar = t; break; }\n            if (tstar == -1) continue;\n            // Mark its cells as positive\n            for (int p : candidates[k][tstar].cells) {\n                if (state[p] == -1) state[p] = 1;\n            }\n            // Also, its forced constraints are trivially satisfied; no further eliminations needed here.\n        }\n    };\n\n    auto all_singleton = [&]() -> bool {\n        for (int k = 0; k < M; ++k) if (alive_count[k] != 1) return false;\n        return true;\n    };\n\n    auto select_next = [&]() -> int {\n        int bestp = -1;\n        long long bestScore = LLONG_MIN;\n        for (int p = 0; p < G; ++p) {\n            if (state[p] != -1) continue;\n            if (S_can[p] == 0) {\n                // can already mark zero; skip drilling\n                continue;\n            }\n            // composite score: prioritize high cover_count and small S_can\n            long long score = 2LL * cover_count[p] + (10 - S_can[p]);\n            if (score > bestScore) {\n                bestScore = score;\n                bestp = p;\n            }\n        }\n        if (bestp == -1) {\n            // fallback any unknown\n            for (int p = 0; p < G; ++p) if (state[p]==-1) return p;\n        }\n        return bestp;\n    };\n\n    int ops_used = 0, max_ops = 2*N*N;\n\n    // Propagate zeros for S_can==0\n    auto propagate_zero_cells = [&]() {\n        for (int p = 0; p < G; ++p) {\n            if (state[p] == -1 && S_can[p] == 0) state[p] = 0;\n        }\n    };\n    propagate_zero_cells();\n\n    while (ops_used < max_ops) {\n        if (all_singleton()) break;\n\n        // If all remaining unknowns are determinable as zero without drilling, stop loop\n        bool undecidedNeedsDrill = false;\n        for (int p = 0; p < G; ++p) {\n            if (state[p] == -1 && S_can[p] > 0) { undecidedNeedsDrill = true; break; }\n        }\n        if (!undecidedNeedsDrill) break;\n\n        int p = select_next();\n        if (p == -1) break;\n        auto [i,j] = ij(p);\n        cout << \"q 1 \" << i << ' ' << j << '\\n';\n        flushout();\n        ops_used++;\n        int vresp;\n        if (!(cin >> vresp)) return 0;\n        if (vresp == 0) {\n            state[p] = 0;\n            // eliminate all candidates covering p\n            // Iterate current list; but some entries might already be dead\n            for (auto [k,t] : cell_covers[p]) {\n                if (alive[k][t]) kill_candidate(k,t);\n            }\n            commit_singletons();\n            propagate_zero_cells();\n        } else {\n            state[p] = 1;\n            // Positive constraints\n            int x = vresp;\n            int Sc = S_can[p];\n            // If Sc == 0 this contradicts, but shouldn't happen.\n            if (Sc > 0) {\n                // If exactly x shapes can possibly cover p, then each of those must cover p\n                // In both this case and the more general case below, we enforce for some shapes that they must cover p\n                // Determine shapes where they must cover p\n                for (int k = 0; k < M; ++k) {\n                    if (cnt_cover[k][p] > 0) {\n                        int others = Sc - 1;\n                        if (others < x) {\n                            // shape k must cover p\n                            if (!forced_cover[k].test(p)) {\n                                forced_cover[k].set(p);\n                                enforce_forced(k);\n                            }\n                        }\n                    }\n                }\n                // Special case Sc==x: all shapes that can cover must cover\n                if (Sc == x) {\n                    for (int k = 0; k < M; ++k) {\n                        if (cnt_cover[k][p] > 0) {\n                            if (!forced_cover[k].test(p)) {\n                                forced_cover[k].set(p);\n                                enforce_forced(k);\n                            }\n                        }\n                    }\n                }\n                commit_singletons();\n                propagate_zero_cells();\n            }\n        }\n        if (ops_used >= max_ops) break;\n    }\n\n    // If still undecided cells, drill remaining unknowns to guarantee correctness\n    for (int p = 0; p < G && ops_used < max_ops; ++p) {\n        if (state[p] == -1) {\n            auto [i,j] = ij(p);\n            cout << \"q 1 \" << i << ' ' << j << '\\n';\n            flushout();\n            ops_used++;\n            int vresp;\n            if (!(cin >> vresp)) return 0;\n            state[p] = (vresp > 0) ? 1 : 0;\n            if (vresp == 0) {\n                // optional: could prune, but near end it doesn't matter\n            }\n        }\n    }\n\n    // Build answer: all cells with state==1\n    vector<pair<int,int>> ans;\n    ans.reserve(G);\n    for (int p = 0; p < G; ++p) if (state[p] == 1) ans.push_back(ij(p));\n\n    cout << \"a \" << ans.size();\n    for (auto [i,j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n';\n    flushout();\n\n    int ok;\n    if (!(cin >> ok)) return 0;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect { int i0,j0,i1,j1; long long area() const { return 1LL*(i1-i0)*(j1-j0); } };\n\n// Hopcroft-Karp bipartite matching\nstruct HopcroftKarp {\n    int nL, nR;\n    vector<vector<int>> adj;\n    vector<int> dist, matchL, matchR;\n    HopcroftKarp(int nL=0, int nR=0):nL(nL), nR(nR), adj(nL), dist(nL), matchL(nL,-1), matchR(nR,-1){}\n    void reset(int nl, int nr){ nL=nl; nR=nr; adj.assign(nL, {}); matchL.assign(nL,-1); matchR.assign(nR,-1); dist.resize(nL); }\n    void addEdge(int u, int v){ adj[u].push_back(v); }\n    bool bfs(){\n        queue<int> q;\n        fill(dist.begin(), dist.end(), -1);\n        for(int u=0; u<nL; u++){\n            if(matchL[u]==-1){ dist[u]=0; q.push(u); }\n        }\n        bool found=false;\n        while(!q.empty()){\n            int u=q.front(); q.pop();\n            for(int v: adj[u]){\n                int w = matchR[v];\n                if(w>=0 && dist[w]<0){\n                    dist[w]=dist[u]+1;\n                    q.push(w);\n                }\n                if(w==-1) found=true;\n            }\n        }\n        return found;\n    }\n    bool dfs(int u){\n        for(int v: adj[u]){\n            int w = matchR[v];\n            if(w==-1 || (w>=0 && dist[w]==dist[u]+1 && dfs(w))){\n                matchL[u]=v; matchR[v]=u;\n                return true;\n            }\n        }\n        dist[u]=-1;\n        return false;\n    }\n    int maxMatching(){\n        int matching=0;\n        while(bfs()){\n            for(int u=0; u<nL; u++){\n                if(matchL[u]==-1 && dfs(u)) matching++;\n            }\n        }\n        return matching;\n    }\n};\n\nstatic inline void build_cells_from_hw(const vector<int>& h, const vector<int>& w, vector<Rect>& cells, vector<long long>& areas){\n    int R = (int)h.size();\n    int C = (int)w.size();\n    vector<int> hi(R+1,0), wj(C+1,0);\n    for(int i=0;i<R;i++) hi[i+1]=hi[i]+h[i];\n    for(int j=0;j<C;j++) wj[j+1]=wj[j]+w[j];\n    cells.clear(); areas.clear();\n    cells.reserve(R*C); areas.reserve(R*C);\n    for(int i=0;i<R;i++) for(int j=0;j<C;j++){\n        Rect r{hi[i], wj[j], hi[i+1], wj[j+1]};\n        cells.push_back(r);\n        areas.push_back(r.area());\n    }\n}\n\nstatic inline void uniform_partition(int W, int R, int C, vector<int>& h, vector<int>& w){\n    h.assign(R, W/R);\n    int remH = W - accumulate(h.begin(), h.end(), 0);\n    for(int i=0;i<remH;i++) h[i%R]++;\n    w.assign(C, W/C);\n    int remW = W - accumulate(w.begin(), w.end(), 0);\n    for(int j=0;j<remW;j++) w[j%C]++;\n}\n\nstruct Candidate {\n    vector<Rect> blocksAsc;\n    long long deficit;\n    int matched;\n};\n\nstatic inline Candidate evaluate_candidate(const vector<long long>& B, const vector<Rect>& cells, const vector<long long>& areas,\n                                           const vector<int>& matchL){\n    int N = (int)B.size();\n    int RC = (int)areas.size();\n    vector<char> used(RC, 0);\n    vector<Rect> blocks(N);\n    int matchedCount=0;\n    for(int u=0; u<N; u++){\n        int v = matchL[u];\n        if (v != -1){\n            blocks[u] = cells[v];\n            used[v]=1;\n            matchedCount++;\n        }\n    }\n    vector<int> idx(RC);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int x,int y){\n        if (areas[x]!=areas[y]) return areas[x] > areas[y];\n        return x<y;\n    });\n    int ptr=0;\n    for(int u=0; u<N; u++){\n        if (matchL[u]==-1){\n            while(ptr<RC && used[idx[ptr]]) ptr++;\n            if (ptr<RC){\n                blocks[u] = cells[idx[ptr]];\n                used[idx[ptr]] = 1;\n                ptr++;\n            } else {\n                blocks[u] = Rect{0,0,0,0};\n            }\n        }\n    }\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int x,int y){\n        long long ax=1LL*(blocks[x].i1-blocks[x].i0)*(blocks[x].j1-blocks[x].j0);\n        long long ay=1LL*(blocks[y].i1-blocks[y].i0)*(blocks[y].j1-blocks[y].j0);\n        if (ax!=ay) return ax<ay;\n        return x<y;\n    });\n    vector<Rect> asc(N);\n    for(int r=0;r<N;r++) asc[r]=blocks[ord[r]];\n    long long deficit=0;\n    for(int r=0;r<N;r++){\n        long long need=B[r], have=1LL*(asc[r].i1-asc[r].i0)*(asc[r].j1-asc[r].j0);\n        if (have<need) deficit += (need-have);\n    }\n    return Candidate{asc, deficit, matchedCount};\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int W,D,N;\n    if(!(cin>>W>>D>>N)) return 0;\n    vector<vector<int>> a(D, vector<int>(N));\n    for(int d=0; d<D; d++) for(int k=0; k<N; k++) cin>>a[d][k];\n\n    // Rank-wise maxima\n    vector<int> M(N,0);\n    for(int d=0; d<D; d++){\n        auto v=a[d];\n        sort(v.begin(), v.end());\n        for(int r=0;r<N;r++) M[r]=max(M[r], v[r]);\n    }\n    vector<long long> B(N);\n    for(int i=0;i<N;i++) B[i]=M[i];\n    sort(B.begin(), B.end());\n\n    // Prepare shapes\n    vector<pair<int,int>> shapes;\n    int base = max(1, (int)round(sqrt((double)N)));\n    auto push_shape = [&](int R,int C){\n        if (R<1) R=1;\n        if (C<1) C=1;\n        if (1LL*R*C < N) return;\n        shapes.emplace_back(R,C);\n    };\n    for(int dr=-3; dr<=3; dr++){\n        int R = max(1, base+dr);\n        int C = (N + R - 1)/R;\n        push_shape(R,C);\n    }\n    for(int dc=-3; dc<=3; dc++){\n        int C = max(1, base+dc);\n        int R = (N + C - 1)/C;\n        push_shape(R,C);\n    }\n    for(int r=1;r<=min(N,30);r++){\n        int c=(N + r - 1)/r;\n        push_shape(r,c);\n    }\n    for(int c=1;c<=min(N,30);c++){\n        int r=(N + c - 1)/c;\n        push_shape(r,c);\n    }\n    push_shape(N,1);\n    push_shape(1,N);\n    sort(shapes.begin(), shapes.end());\n    shapes.erase(unique(shapes.begin(), shapes.end()), shapes.end());\n\n    Candidate best; best.deficit = LLONG_MAX; best.matched=-1;\n\n    // For each shape, do matching and local improvements\n    for(auto [R,C] : shapes){\n        vector<int> h,w;\n        uniform_partition(W, R, C, h, w);\n\n        vector<Rect> cells;\n        vector<long long> areas;\n        build_cells_from_hw(h, w, cells, areas);\n\n        int RC = R*C;\n\n        // Use only top K cells on the right to stabilize\n        vector<int> cellOrder(RC);\n        iota(cellOrder.begin(), cellOrder.end(), 0);\n        sort(cellOrder.begin(), cellOrder.end(), [&](int x,int y){\n            if (areas[x]!=areas[y]) return areas[x] > areas[y];\n            return x<y;\n        });\n        int K = max(N, (int)(RC*3/4));\n        if (K>RC) K=RC;\n        vector<int> cellMap(RC, -1);\n        for(int i=0;i<K;i++) cellMap[cellOrder[i]] = i; // map original cell idx -> compact idx [0..K-1]\n\n        auto run_matching = [&](HopcroftKarp& hk, vector<int>& matchL, vector<int>& matchR)->int{\n            hk = HopcroftKarp(N, K);\n            for(int u=0; u<N; u++){\n                for(int vOrig=0; vOrig<RC; vOrig++){\n                    int v = cellMap[vOrig];\n                    if (v<0) continue;\n                    if (areas[vOrig] >= B[u]) hk.addEdge(u, v);\n                }\n            }\n            int mm = hk.maxMatching();\n            matchL = hk.matchL;\n            matchR = hk.matchR;\n            // Expand matchL to original cell index for evaluation\n            for(int u=0; u<N; u++){\n                int v = matchL[u];\n                if (v!=-1){\n                    int vOrig = cellOrder[v];\n                    matchL[u] = vOrig;\n                }\n            }\n            return mm;\n        };\n\n        HopcroftKarp hk;\n        vector<int> matchL, matchR;\n        run_matching(hk, matchL, matchR);\n        Candidate cand = evaluate_candidate(B, cells, areas, matchL);\n        if (cand.deficit < best.deficit || (cand.deficit==best.deficit && cand.matched > best.matched)){\n            best = cand;\n            if (best.deficit==0) break;\n        }\n\n        // Local improvements\n        int STEPS = 180;\n        for(int step=0; step<STEPS && cand.deficit>0; step++){\n            // pick a target: alternate smallest and largest rank\n            int target_r = (step % 2 == 0) ? 0 : (N-1);\n            long long need = B[target_r];\n\n            // find cell closest below need\n            int bestCell=-1;\n            long long bestArea=-1;\n            for(int v=0; v<RC; v++){\n                if (areas[v] < need && areas[v] > bestArea){\n                    bestArea = areas[v];\n                    bestCell = v;\n                }\n            }\n            if (bestCell==-1){\n                // Try generic variation: shift 1 unit from smallest row to largest row or similar for cols\n                int riMax = int(max_element(h.begin(), h.end()) - h.begin());\n                int riMin = int(min_element(h.begin(), h.end()) - h.begin());\n                bool moved=false;\n                if (h[riMin] > 1){\n                    h[riMax]++; h[riMin]--;\n                    moved=true;\n                } else {\n                    int cjMax = int(max_element(w.begin(), w.end()) - w.begin());\n                    int cjMin = int(min_element(w.begin(), w.end()) - w.begin());\n                    if (w[cjMin] > 1){\n                        w[cjMax]++; w[cjMin]--;\n                        moved=true;\n                    }\n                }\n                if (!moved) break;\n            } else {\n                int ri = bestCell / C;\n                int cj = bestCell % C;\n                long long bestImprove = LLONG_MIN;\n                bool useRow=true; int a=-1,b=-1;\n\n                auto test_op = [&](bool isRow, int A, int Bidx){\n                    if (isRow){\n                        if (h[Bidx]<=1) return;\n                        h[A]++; h[Bidx]--;\n                    } else {\n                        if (w[Bidx]<=1) return;\n                        w[A]++; w[Bidx]--;\n                    }\n                    build_cells_from_hw(h, w, cells, areas);\n                    HopcroftKarp hk2;\n                    vector<int> mL, mR;\n                    run_matching(hk2, mL, mR);\n                    Candidate c2 = evaluate_candidate(B, cells, areas, mL);\n                    long long improve = cand.deficit - c2.deficit;\n                    if (improve > bestImprove){\n                        bestImprove = improve;\n                        useRow = isRow; a=A; b=Bidx;\n                    }\n                    // revert\n                    if (isRow){ h[A]--; h[Bidx]++; }\n                    else { w[A]--; w[Bidx]++; }\n                };\n\n                for(int r2=0;r2<R;r2++){\n                    if (r2==ri) continue;\n                    test_op(true, ri, r2);\n                }\n                for(int c2=0;c2<C;c2++){\n                    if (c2==cj) continue;\n                    test_op(false, cj, c2);\n                }\n\n                if (a==-1){\n                    // No beneficial move found; stop this shape's local search\n                    break;\n                } else {\n                    if (useRow){ h[a]++; h[b]--; }\n                    else { w[a]++; w[b]--; }\n                    build_cells_from_hw(h, w, cells, areas);\n                }\n            }\n            // re-evaluate candidate\n            HopcroftKarp hk3;\n            vector<int> mL3, mR3;\n            run_matching(hk3, mL3, mR3);\n            cand = evaluate_candidate(B, cells, areas, mL3);\n            if (cand.deficit < best.deficit || (cand.deficit==best.deficit && cand.matched > best.matched)){\n                best = cand;\n                if (best.deficit==0) break;\n            }\n        }\n        if (best.deficit==0) break;\n    }\n\n    vector<Rect> blocksAsc;\n    if (best.blocksAsc.empty()){\n        // fallback equal stripes\n        blocksAsc.resize(N);\n        int hh = max(1, W / max(1, N));\n        int cur=0;\n        int extra = W - hh*N;\n        for(int i=0;i<N;i++){\n            int h = hh + (i<extra?1:0);\n            blocksAsc[i] = Rect{cur, 0, cur+h, W};\n            cur += h;\n        }\n    } else {\n        blocksAsc = best.blocksAsc;\n    }\n\n    // Output per day\n    for(int d=0; d<D; d++){\n        vector<int> ord(N);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int x,int y){ return a[d][x] < a[d][y]; });\n        vector<Rect> out(N);\n        for(int r=0;r<N;r++){\n            out[ord[r]] = blocksAsc[r];\n        }\n        for(int k=0; k<N; k++){\n            auto &r = out[k];\n            cout<<r.i0<<\" \"<<r.j0<<\" \"<<r.i1<<\" \"<<r.j1<<\"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const long long MOD = 998244353LL;\n\nstruct Entry {\n    int m, p, q;\n    long long gain;       // immediate objective delta\n    int overflow;         // count of cells where (v+s) wraps mod MOD\n    long long headroom;   // sum over 3x3 of max(0, (MOD-1) - new_v)\n    uint64_t ver;         // version for lazy heap\n    bool operator<(const Entry& other) const {\n        if (gain != other.gain) return gain < other.gain; // max-heap by gain\n        if (overflow != other.overflow) return overflow > other.overflow; // prefer fewer wraps\n        if (headroom != other.headroom) return headroom < other.headroom; // prefer larger remaining headroom\n        if (m != other.m) return m > other.m;\n        if (p != other.p) return p > other.p;\n        return q > other.q;\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    vector<vector<long long>> w(N, vector<long long>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            long long x; cin >> x;\n            w[i][j] = x % MOD;\n        }\n    vector<array<long long,9>> stamps(M);\n    for (int m = 0; m < M; ++m) {\n        int idx=0;\n        for (int i=0;i<3;++i) for (int j=0;j<3;++j) {\n            long long s; cin >> s;\n            stamps[m][idx++] = s % MOD;\n        }\n    }\n\n    const int Pmax = N-3; // inclusive top-left range 0..6 for N=9\n\n    auto compute_move = [&](int m, int p, int q)->Entry{\n        long long g = 0;\n        int of = 0;\n        long long hr = 0;\n        int idx=0;\n        for (int di=0; di<3; ++di) for (int dj=0; dj<3; ++dj,++idx){\n            int r=p+di, c=q+dj;\n            long long v = w[r][c];\n            long long s = stamps[m][idx];\n            long long nv = v + s;\n            if (nv >= MOD) { nv -= MOD; of++; }\n            g += (nv - v);\n            long long head = (MOD - 1) - nv;\n            if (head > 0) hr += head;\n        }\n        return Entry{m,p,q,g,of,hr,0};\n    };\n\n    // Maintain versions for lazy heap\n    vector<vector<vector<uint64_t>>> ver(M, vector<vector<uint64_t>>(Pmax+1, vector<uint64_t>(Pmax+1, 0)));\n\n    priority_queue<Entry> pq;\n    // initial push\n    for (int m=0; m<M; ++m) for (int p=0; p<=Pmax; ++p) for (int q=0; q<=Pmax; ++q){\n        Entry e = compute_move(m,p,q);\n        e.ver = ver[m][p][q];\n        pq.push(e);\n    }\n\n    vector<tuple<int,int,int>> ops; ops.reserve(K);\n\n    auto refresh_region = [&](int pL, int pR, int qL, int qR){\n        pL = max(pL, 0); pR = min(pR, Pmax);\n        qL = max(qL, 0); qR = min(qR, Pmax);\n        for (int p = pL; p <= pR; ++p) {\n            for (int q = qL; q <= qR; ++q) {\n                for (int m=0; m<M; ++m) {\n                    Entry e = compute_move(m,p,q);\n                    uint64_t &v = ver[m][p][q];\n                    v++;\n                    e.ver = v;\n                    pq.push(e);\n                }\n            }\n        }\n    };\n\n    for (int t=0; t<K; ++t) {\n        Entry best;\n        bool found = false;\n        while (!pq.empty()) {\n            best = pq.top(); pq.pop();\n            if (best.ver != ver[best.m][best.p][best.q]) continue; // stale\n            found = true; break;\n        }\n        if (!found) break;\n        if (best.gain <= 0) break;\n\n        // apply best move\n        int m = best.m, p = best.p, q = best.q;\n        int idx=0;\n        for (int di=0; di<3; ++di) for (int dj=0; dj<3; ++dj,++idx){\n            int r = p+di, c = q+dj;\n            long long s = stamps[m][idx];\n            long long nv = w[r][c] + s;\n            if (nv >= MOD) nv -= MOD;\n            w[r][c] = nv;\n        }\n        ops.emplace_back(m,p,q);\n\n        // Only moves whose 3x3 overlaps the updated 3x3 region may change.\n        refresh_region(p-2, p+2, q-2, q+2);\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto &op : ops) {\n        int m,p,q; tie(m,p,q) = op;\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Planner {\n    static const int N = 5;\n    vector<vector<int>> A;\n    vector<string> S;\n\n    int cr=0, cc=0;\n    bool holding=false;\n    int held_id=-1;\n\n    bool occ[N][N]; // interior occupancy (cols 1..3)\n    unordered_map<int, pair<int,int>> loc; // container id -> stored position\n\n    int next_needed[N];\n    int idx_head[N];\n    int dispatched=0;\n\n    int dtgt = -1; // current batching destination row\n\n    Planner(const vector<vector<int>>& Ain): A(Ain) {\n        S.assign(N, \"\");\n        for (int i=1;i<N;i++) S[i].push_back('B'); // bomb small cranes\n        memset(occ, 0, sizeof(occ));\n        for (int i=0;i<N;i++){ next_needed[i]=N*i; idx_head[i]=0; }\n    }\n\n    void appendLarge(char ch){\n        S[0].push_back(ch);\n        for (int i=1;i<N;i++){\n            if ((int)S[i].size() < (int)S[0].size()) S[i].push_back('.');\n        }\n    }\n    void moveTo(int tr, int tc){\n        while (cr != tr) {\n            if (tr < cr) { cr--; appendLarge('U'); }\n            else { cr++; appendLarge('D'); }\n        }\n        while (cc != tc) {\n            if (tc < cc) { cc--; appendLarge('L'); }\n            else { cc++; appendLarge('R'); }\n        }\n    }\n    void pickAtCurrent(int cid){\n        held_id = cid; holding = true; appendLarge('P');\n    }\n    void dropAtCurrent(){\n        holding = false; appendLarge('Q');\n    }\n\n    // Preferred free cell in destination row (3->2->1), else nearest anywhere\n    pair<int,int> preferredFreeInRow(int drow){\n        for (int c=3;c>=1;c--){\n            if (!occ[drow][c]) return {drow,c};\n        }\n        int best=1e9; pair<int,int> ans{-1,-1};\n        for (int r=0;r<N;r++){\n            for (int c=1;c<=3;c++){\n                if (!occ[r][c]){\n                    int d = abs(cr-r)+abs(cc-c);\n                    if (d < best){ best=d; ans={r,c}; }\n                }\n            }\n        }\n        return ans;\n    }\n    pair<int,int> nearestFreeAnywhere(){\n        int best=1e9; pair<int,int> ans{-1,-1};\n        for (int r=0;r<N;r++){\n            for (int c=1;c<=3;c++){\n                if (!occ[r][c]){\n                    int d = abs(cr-r)+abs(cc-c);\n                    if (d < best){ best=d; ans={r,c}; }\n                }\n            }\n        }\n        return ans;\n    }\n    bool hasFreeInRow(int drow){\n        for (int c=1;c<=3;c++) if (!occ[drow][c]) return true;\n        return false;\n    }\n    // Preferred spillover free cell near gate for rows d-1 or d+1\n    pair<int,int> preferredSpilloverNearGate(int drow){\n        vector<int> rows;\n        if (drow-1 >= 0) rows.push_back(drow-1);\n        if (drow+1 < N) rows.push_back(drow+1);\n        for (int rr: rows){\n            for (int c=3;c>=1;c--){\n                if (!occ[rr][c]) return {rr,c};\n            }\n        }\n        // none\n        return {-1,-1};\n    }\n\n    // Flush next-needed for row d: choose closest candidate among storage; else left head\n    bool flush_one_for_row(int d){\n        int need = next_needed[d];\n        if (need >= N*d + N) return false;\n        // check storage: if multiple, choose closest; prioritize same row\n        pair<int,int> bestPos{-1,-1}; int bestDist = 1e9;\n        auto it = loc.find(need);\n        if (it != loc.end()){\n            // Single exact mapping; but might exist only once; keep as-is\n            bestPos = it->second;\n            bestDist = abs(cr - bestPos.first) + abs(cc - bestPos.second) + abs(bestPos.first - d) + abs(bestPos.second - (N-1));\n            // no need to search more; loc keeps only one position per id\n            moveTo(bestPos.first, bestPos.second);\n            pickAtCurrent(need);\n            occ[bestPos.first][bestPos.second] = false;\n            loc.erase(need);\n            moveTo(d, N-1);\n            dropAtCurrent();\n            next_needed[d]++; dispatched++;\n            dtgt = d;\n            return true;\n        }\n        // left heads\n        int best_r=-1; bestDist = 1e9;\n        for (int r=0;r<N;r++){\n            if (idx_head[r] < N && A[r][idx_head[r]] == need){\n                int dist = abs(cr - r) + abs(cc - 0) + abs(r - d) + abs(0 - (N-1));\n                if (dist < bestDist){ bestDist = dist; best_r = r; }\n            }\n        }\n        if (best_r != -1){\n            moveTo(best_r, 0);\n            pickAtCurrent(need);\n            idx_head[best_r]++;\n            moveTo(d, N-1);\n            dropAtCurrent();\n            next_needed[d]++; dispatched++;\n            dtgt = d;\n            return true;\n        }\n        return false;\n    }\n\n    bool flush_one(){\n        if (dtgt != -1 && flush_one_for_row(dtgt)) return true;\n        // choose best row by minimal fetch+deliver distance among those with need in storage or at left\n        int bestD=-1, bestCost=1e9;\n        // storage possibilities\n        for (int d=0; d<N; d++){\n            int need = next_needed[d];\n            if (need >= N*d + N) continue;\n            auto it = loc.find(need);\n            if (it != loc.end()){\n                int dist = abs(cr - it->second.first) + abs(cc - it->second.second) + abs(it->second.first - d) + abs(it->second.second - (N-1));\n                if (dist < bestCost){ bestCost=dist; bestD=d; }\n            } else {\n                for (int r=0;r<N;r++){\n                    if (idx_head[r] < N && A[r][idx_head[r]] == need){\n                        int dist = abs(cr - r) + abs(cc - 0) + abs(r - d) + abs(0 - (N-1));\n                        if (dist < bestCost){ bestCost=dist; bestD=d; }\n                    }\n                }\n            }\n        }\n        if (bestD != -1) return flush_one_for_row(bestD);\n        return false;\n    }\n\n    // At gate d: chain dispatch and adaptive pre-staging with spillover\n    void flush_chain_at_row(int d){\n        dtgt = d;\n        while (flush_one_for_row(d)) {}\n        // Remaining to dispatch in row d\n        int remaining = N*(d+1) - next_needed[d];\n        if (remaining <= 0) return;\n        // Count already stored for d\n        int stored_for_d = 0;\n        for (auto &kv: loc){\n            if (kv.first / N == d) stored_for_d++;\n        }\n        int K = min(4, max(0, remaining - stored_for_d));\n        int pulled = 0;\n        while (pulled < K){\n            // if no space in row d, try spillover near gate\n            bool rowSpace = hasFreeInRow(d);\n            pair<int,int> placePos{-1,-1};\n            if (rowSpace) {\n                // we will compute pos after selecting source\n            } else {\n                placePos = preferredSpilloverNearGate(d);\n                if (placePos.first == -1) break; // nowhere to place\n            }\n            // Choose nearest source destined to d (not immediate)\n            int best_r=-1, best_cost=1e9, best_b=-1;\n            for (int r=0;r<N;r++){\n                if (idx_head[r] >= N) continue;\n                int b = A[r][idx_head[r]];\n                if (b / N != d) continue;\n                if (b == next_needed[d]) continue; // would be flushed\n                // cost: to pick + to placement\n                pair<int,int> tentativePos;\n                if (rowSpace) {\n                    // figure current best free in row d from current position\n                    int bestc=-1, bestcDist=1e9;\n                    for (int c=3;c>=1;c--){\n                        if (!occ[d][c]){\n                            int dist = abs(r - d) + abs(0 - c);\n                            if (dist < bestcDist){ bestcDist=dist; bestc=c; }\n                        }\n                    }\n                    tentativePos = {d, (bestc==-1?2:bestc)};\n                } else {\n                    tentativePos = placePos;\n                }\n                int cost = abs(cr - r) + abs(cc - 0) + abs(r - tentativePos.first) + abs(0 - tentativePos.second);\n                if (cost < best_cost){ best_cost=cost; best_r=r; best_b=b; }\n            }\n            if (best_r == -1) break;\n            moveTo(best_r, 0);\n            pickAtCurrent(best_b);\n            idx_head[best_r]++;\n            if (rowSpace) placePos = preferredFreeInRow(d);\n            if (placePos.first == -1) {\n                placePos = preferredSpilloverNearGate(d);\n                if (placePos.first == -1) { // fallback anywhere\n                    placePos = nearestFreeAnywhere();\n                    if (placePos.first == -1) { appendLarge('.'); break; }\n                }\n            }\n            moveTo(placePos.first, placePos.second);\n            dropAtCurrent();\n            occ[placePos.first][placePos.second]=true; loc[best_b]=placePos;\n            pulled++;\n            // After pre-staging, try flushing again for d\n            while (flush_one_for_row(d)) {}\n        }\n    }\n\n    void ensureLargeNotBlockingStart(){\n        if (cr==0 && cc==0){\n            cc=1; appendLarge('R');\n        }\n    }\n\n    // Choose next source:\n    // 1) immediate need anywhere\n    // 2) closest head destined to dtgt\n    // 3) minimal estimated cost: pick + to nearest free in dest row from (r,0)\n    int choose_source_row(){\n        // 1) immediate\n        for (int r=0;r<N;r++){\n            if (idx_head[r] >= N) continue;\n            int b = A[r][idx_head[r]];\n            if (next_needed[b / N] == b) return r;\n        }\n        // 2) prefer dtgt\n        if (dtgt != -1){\n            int best=-1, bestd=1e9;\n            for (int r=0;r<N;r++){\n                if (idx_head[r] >= N) continue;\n                int b = A[r][idx_head[r]];\n                if (b / N != dtgt) continue;\n                int d = abs(cr - r) + abs(cc - 0);\n                if (d < bestd){ bestd=d; best=r; }\n            }\n            if (best != -1) return best;\n        }\n        // 3) general cost\n        int best=-1; int bestCost=1e9;\n        for (int r=0;r<N;r++){\n            if (idx_head[r] >= N) continue;\n            int b = A[r][idx_head[r]];\n            int dest = b / N;\n            int pick = abs(cr - r) + abs(cc - 0);\n            // find nearest free in dest row from (r,0)\n            int place = 1e9;\n            for (int c=3;c>=1;c--){\n                if (!occ[dest][c]){\n                    int cost = abs(r - dest) + abs(0 - c);\n                    place = min(place, cost);\n                }\n            }\n            if (place == 1e9){\n                // fallback anywhere from (r,0)\n                for (int rr=0; rr<N; rr++){\n                    for (int cc2=1; cc2<=3; cc2++){\n                        if (!occ[rr][cc2]){\n                            int cost = abs(r - rr) + abs(0 - cc2);\n                            place = min(place, cost);\n                        }\n                    }\n                }\n            }\n            int total = pick + place;\n            if (total < bestCost){ bestCost=total; best=r; }\n        }\n        return best;\n    }\n\n    void run(){\n        ensureLargeNotBlockingStart();\n        int maxTurns = 9500;\n\n        while (dispatched < N*N && (int)S[0].size() < maxTurns){\n            // If holding, resolve it\n            if (holding){\n                int d = held_id / N;\n                if (next_needed[d] == held_id){\n                    moveTo(d, N-1);\n                    dropAtCurrent();\n                    next_needed[d]++; dispatched++;\n                    flush_chain_at_row(d);\n                    continue;\n                } else {\n                    auto pos = preferredFreeInRow(d);\n                    if (pos.first == -1){\n                        if (flush_one()) continue;\n                        pos = nearestFreeAnywhere();\n                    }\n                    if (pos.first != -1){\n                        moveTo(pos.first, pos.second);\n                        dropAtCurrent();\n                        occ[pos.first][pos.second]=true; loc[held_id]=pos;\n                    } else {\n                        appendLarge('.');\n                    }\n                    continue;\n                }\n            }\n\n            // Try to flush immediate items, dtgt first\n            if (flush_one()) continue;\n\n            // Choose next source\n            int r = choose_source_row();\n            if (r == -1){\n                appendLarge('.');\n                continue;\n            }\n\n            int b = A[r][idx_head[r]];\n            int d = b / N;\n            bool immediate = (next_needed[d] == b);\n\n            // Pre-check storage if not immediate\n            if (!immediate){\n                if (!hasFreeInRow(d)){\n                    if (flush_one()) continue;\n                    auto pos = nearestFreeAnywhere();\n                    if (pos.first == -1){\n                        appendLarge('.');\n                        continue;\n                    }\n                }\n            }\n\n            // Go pick\n            moveTo(r, 0);\n            pickAtCurrent(b);\n            idx_head[r]++;\n            if (cc==0){ cc=1; appendLarge('R'); } // safety step off column 0\n\n            if (immediate){\n                moveTo(d, N-1);\n                dropAtCurrent();\n                next_needed[d]++; dispatched++;\n                flush_chain_at_row(d);\n            } else {\n                auto pos = preferredFreeInRow(d);\n                if (pos.first == -1) pos = nearestFreeAnywhere();\n                if (pos.first != -1){\n                    moveTo(pos.first, pos.second);\n                    dropAtCurrent();\n                    occ[pos.first][pos.second]=true; loc[b]=pos;\n                } else {\n                    appendLarge('.');\n                }\n            }\n        }\n\n        // Pad\n        size_t L = S[0].size();\n        for (int i=1;i<N;i++){\n            while (S[i].size() < L) S[i].push_back('.');\n        }\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i=0;i<N;i++){\n        for (int j=0;j<N;j++){\n            cin >> A[i][j];\n        }\n    }\n    Planner planner(A);\n    planner.run();\n    for (int i=0;i<N;i++){\n        cout << planner.S[i] << \"\\n\";\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Plan {\n    vector<string> ops;\n    long long cost = (long long)4e18;\n};\n\nstatic inline void add_load(long long d, vector<string>& ops, long long& cost, long long& load) {\n    if (d <= 0) return;\n    ops.emplace_back(\"+\" + to_string(d));\n    cost += d;\n    load += d;\n}\nstatic inline void sub_load(long long d, vector<string>& ops, long long& cost, long long& load) {\n    if (d <= 0) return;\n    ops.emplace_back(\"-\" + to_string(d));\n    cost += d;\n    load -= d;\n}\n\nstatic inline void move_manhattan(pair<int,int> from, pair<int,int> to, vector<string>& ops, long long& cost, long long load) {\n    int r = from.first, c = from.second;\n    while (r < to.first) { ops.emplace_back(\"D\"); cost += 100 + load; ++r; }\n    while (r > to.first) { ops.emplace_back(\"U\"); cost += 100 + load; --r; }\n    while (c < to.second) { ops.emplace_back(\"R\"); cost += 100 + load; ++c; }\n    while (c > to.second) { ops.emplace_back(\"L\"); cost += 100 + load; --c; }\n}\n\nstatic inline void append_adjacent_move(pair<int,int> from, pair<int,int> to, vector<string>& ops, long long& cost, long long load) {\n    int dr = to.first - from.first;\n    int dc = to.second - from.second;\n    if (dr == 1 && dc == 0) { ops.emplace_back(\"D\"); cost += 100 + load; }\n    else if (dr == -1 && dc == 0) { ops.emplace_back(\"U\"); cost += 100 + load; }\n    else if (dr == 0 && dc == 1) { ops.emplace_back(\"R\"); cost += 100 + load; }\n    else if (dr == 0 && dc == -1) { ops.emplace_back(\"L\"); cost += 100 + load; }\n    else {\n        move_manhattan(from, to, ops, cost, load);\n    }\n}\n\nvector<pair<int,int>> build_snake_rows(int N, bool reverse_start=false) {\n    vector<pair<int,int>> ord;\n    ord.reserve(N*N);\n    if (!reverse_start) {\n        for (int i = 0; i < N; ++i) {\n            if (i % 2 == 0) for (int j = 0; j < N; ++j) ord.emplace_back(i,j);\n            else for (int j = N-1; j >= 0; --j) ord.emplace_back(i,j);\n        }\n    } else {\n        for (int i = N-1; i >= 0; --i) {\n            if ((N-1 - i) % 2 == 0) for (int j = N-1; j >= 0; --j) ord.emplace_back(i,j);\n            else for (int j = 0; j < N; ++j) ord.emplace_back(i,j);\n        }\n    }\n    return ord;\n}\nvector<pair<int,int>> build_snake_cols(int N, bool reverse_start=false) {\n    vector<pair<int,int>> ord;\n    ord.reserve(N*N);\n    if (!reverse_start) {\n        for (int j = 0; j < N; ++j) {\n            if (j % 2 == 0) for (int i = 0; i < N; ++i) ord.emplace_back(i,j);\n            else for (int i = N-1; i >= 0; --i) ord.emplace_back(i,j);\n        }\n    } else {\n        for (int j = N-1; j >= 0; --j) {\n            if ((N-1 - j) % 2 == 0) for (int i = N-1; i >= 0; --i) ord.emplace_back(i,j);\n            else for (int i = 0; i < N; ++i) ord.emplace_back(i,j);\n        }\n    }\n    return ord;\n}\n\n// Hilbert helpers\nvoid rot(int n, int &x, int &y, int rx, int ry) {\n    if (ry == 0) {\n        if (rx == 1) {\n            x = n-1 - x;\n            y = n-1 - y;\n        }\n        int t = x; x = y; y = t;\n    }\n}\npair<int,int> d2xy(int n, int d) {\n    int x = 0, y = 0;\n    int t = d;\n    for (int s = 1; s < n; s <<= 1) {\n        int rx = 1 & (t >> 1);\n        int ry = 1 & (t ^ rx);\n        rot(s, x, y, rx, ry);\n        x += s * rx;\n        y += s * ry;\n        t >>= 2;\n    }\n    return {x, y};\n}\n\nvector<pair<int,int>> build_hilbert_base(int N) {\n    int n = 1;\n    while (n < N) n <<= 1;\n    vector<pair<int,int>> pts;\n    pts.reserve(N*N);\n    for (int d = 0; d < n*n; ++d) {\n        auto p = d2xy(n, d); // (x,y)\n        if (p.first < N && p.second < N) {\n            pts.emplace_back(p.second, p.first); // map to (r,c) = (y,x)\n            if ((int)pts.size() == N*N) break;\n        }\n    }\n    return pts;\n}\n\nvector<pair<int,int>> transform_points_rc(const vector<pair<int,int>>& pts, int N, int rotk, bool reflect) {\n    // rotate around center of NxN and optional mirror horizontally\n    vector<pair<int,int>> out; out.reserve(pts.size());\n    for (auto p : pts) {\n        int r = p.first, c = p.second;\n        if (reflect) c = N-1 - c;\n        for (int k = 0; k < rotk; ++k) {\n            int nr = c;\n            int nc = N-1 - r;\n            r = nr; c = nc;\n        }\n        out.emplace_back(r,c);\n    }\n    return out;\n}\n\n// Morton/Z-order traversal on NxN where N is arbitrary\nvoid morton_rec(int r0, int c0, int h, int w, vector<pair<int,int>>& out) {\n    if (h <= 0 || w <= 0) return;\n    if (h == 1 && w == 1) {\n        out.emplace_back(r0, c0);\n        return;\n    }\n    int h1 = (h+1)/2, h2 = h - h1;\n    int w1 = (w+1)/2, w2 = w - w1;\n    // Quadrants in Z-order: TL, TR, BL, BR\n    morton_rec(r0, c0, h1, w1, out);\n    morton_rec(r0, c0 + w1, h1, w2, out);\n    morton_rec(r0 + h1, c0, h2, w1, out);\n    morton_rec(r0 + h1, c0 + w1, h2, w2, out);\n}\nvector<pair<int,int>> build_morton(int N) {\n    vector<pair<int,int>> out;\n    out.reserve(N*N);\n    morton_rec(0,0,N,N,out);\n    return out;\n}\n\nvector<pair<int,int>> build_spiral(int N, int sr, int sc, bool cw=true) {\n    // spiral from starting corner (sr,sc) where each is 0 or N-1\n    // cw: clockwise\n    int top = 0, left = 0, bottom = N-1, right = N-1;\n    vector<pair<int,int>> ord; ord.reserve(N*N);\n    int phase = 0;\n    // Determine initial direction based on start corner and cw\n    // We'll generate layers and order sides accordingly to start at given corner\n    // Easier: generate a full spiral from top-left clockwise, then transform by rotations/reflections\n    // But we'll implement a straightforward generator for the given start.\n    // To keep it simple, generate base from (0,0) CW, then rotate/reflect to match (sr,sc) and cw.\n    // Here we implement base and then transform outside, for simplicity we only build base here.\n    // We'll return base spiral (0,0) clockwise; callers will transform via transform_points_rc.\n    while (top <= bottom && left <= right) {\n        for (int j = left; j <= right; ++j) ord.emplace_back(top, j);\n        for (int i = top+1; i <= bottom; ++i) ord.emplace_back(i, right);\n        if (top < bottom) {\n            for (int j = right-1; j >= left; --j) ord.emplace_back(bottom, j);\n        }\n        if (left < right) {\n            for (int i = bottom-1; i > top; --i) ord.emplace_back(i, left);\n        }\n        ++top; ++left; --bottom; --right;\n    }\n    // ord is base; transformation will be done by transform_points_rc\n    return ord;\n}\n\nvector<pair<int,int>> build_block_snake(int N, int BS) {\n    // Traverse tiles in snake order, inside each tile snake order\n    vector<pair<int,int>> ord; ord.reserve(N*N);\n    int TR = (N + BS - 1)/BS;\n    int TC = (N + BS - 1)/BS;\n    for (int tr = 0; tr < TR; ++tr) {\n        if (tr % 2 == 0) {\n            for (int tc = 0; tc < TC; ++tc) {\n                int r0 = tr*BS, c0 = tc*BS;\n                int r1 = min(N, r0 + BS);\n                int c1 = min(N, c0 + BS);\n                for (int r = r0; r < r1; ++r) {\n                    if ((r - r0) % 2 == 0) {\n                        for (int c = c0; c < c1; ++c) ord.emplace_back(r,c);\n                    } else {\n                        for (int c = c1-1; c >= c0; --c) ord.emplace_back(r,c);\n                    }\n                }\n            }\n        } else {\n            for (int tc = TC-1; tc >= 0; --tc) {\n                int r0 = tr*BS, c0 = tc*BS;\n                int r1 = min(N, r0 + BS);\n                int c1 = min(N, c0 + BS);\n                for (int r = r0; r < r1; ++r) {\n                    if ((r - r0) % 2 == 0) {\n                        for (int c = c0; c < c1; ++c) ord.emplace_back(r,c);\n                    } else {\n                        for (int c = c1-1; c >= c0; --c) ord.emplace_back(r,c);\n                    }\n                }\n            }\n        }\n    }\n    return ord;\n}\n\nbool is_adjacent_path(const vector<pair<int,int>>& ord) {\n    int SZ = (int)ord.size();\n    for (int i = 0; i + 1 < SZ; ++i) {\n        int dr = abs(ord[i+1].first - ord[i].first);\n        int dc = abs(ord[i+1].second - ord[i].second);\n        if (dr + dc != 1) return false;\n    }\n    return true;\n}\n\nPlan build_plan(int N, const vector<vector<long long>>& h0, const vector<pair<int,int>>& order) {\n    vector<vector<long long>> h = h0;\n    vector<string> ops;\n    ops.reserve(12000);\n    long long cost = 0;\n    long long load = 0;\n\n    pair<int,int> cur = {0,0};\n    if (cur != order[0]) {\n        move_manhattan(cur, order[0], ops, cost, load);\n        cur = order[0];\n    }\n    int SZ = (int)order.size();\n    for (int idx = 0; idx + 1 < SZ; ++idx) {\n        auto p = order[idx];\n        auto q = order[idx+1];\n        if (cur != p) {\n            move_manhattan(cur, p, ops, cost, load);\n            cur = p;\n        }\n        long long x = h[p.first][p.second];\n        if (x >= 0) {\n            if (x > 0) add_load(x, ops, cost, load);\n            append_adjacent_move(p, q, ops, cost, load);\n            cur = q;\n            if (x > 0) sub_load(x, ops, cost, load);\n            h[q.first][q.second] += x;\n            h[p.first][p.second] = 0;\n        } else {\n            long long d = -x;\n            append_adjacent_move(p, q, ops, cost, load); // move empty to q\n            cur = q;\n            add_load(d, ops, cost, load);               // load at q\n            append_adjacent_move(q, p, ops, cost, load); // move back with load\n            cur = p;\n            sub_load(d, ops, cost, load);               // unload at p\n            h[p.first][p.second] = 0;\n            h[q.first][q.second] -= d;\n            append_adjacent_move(p, q, ops, cost, load); // move to q to continue\n            cur = q;\n        }\n    }\n    Plan res;\n    res.ops = move(ops);\n    res.cost = cost;\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<long long>> h(N, vector<long long>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> h[i][j];\n\n    vector<vector<pair<int,int>>> candidates;\n\n    // Row and column snakes\n    candidates.push_back(build_snake_rows(N, false));\n    candidates.push_back(build_snake_rows(N, true));\n    candidates.push_back(build_snake_cols(N, false));\n    candidates.push_back(build_snake_cols(N, true));\n\n    // Hilbert base (r,c)\n    auto hil_base = build_hilbert_base(N);\n    for (int rotk = 0; rotk < 4; ++rotk) {\n        for (int refl = 0; refl < 2; ++refl) {\n            auto ord = transform_points_rc(hil_base, N, rotk, refl);\n            if (is_adjacent_path(ord)) {\n                candidates.push_back(ord);\n                auto rord = ord; reverse(rord.begin(), rord.end());\n                candidates.push_back(rord);\n            }\n        }\n    }\n\n    // Morton/Z-order and variants via rotation/reflection\n    auto mort = build_morton(N);\n    for (int rotk = 0; rotk < 4; ++rotk) {\n        for (int refl = 0; refl < 2; ++refl) {\n            auto ord = transform_points_rc(mort, N, rotk, refl);\n            // Morton order is not strictly adjacent; skip non-adjacent to avoid long manhattan jumps\n            if (is_adjacent_path(ord)) {\n                candidates.push_back(ord);\n                auto rord = ord; reverse(rord.begin(), rord.end());\n                candidates.push_back(rord);\n            }\n        }\n    }\n\n    // Block snakes with different block sizes\n    for (int bs : {3,4,5}) {\n        auto b = build_block_snake(N, bs);\n        if (is_adjacent_path(b)) {\n            candidates.push_back(b);\n            auto rb = b; reverse(rb.begin(), rb.end());\n            candidates.push_back(rb);\n        }\n        // also rotated/reflected\n        for (int rotk = 1; rotk < 4; ++rotk) {\n            auto ord = transform_points_rc(b, N, rotk, false);\n            if (is_adjacent_path(ord)) {\n                candidates.push_back(ord);\n                auto rord = ord; reverse(rord.begin(), rord.end());\n                candidates.push_back(rord);\n            }\n        }\n    }\n\n    // Spiral from TL CW; then rotate/reflect to cover 8 variants and reverses\n    auto spiral_base = build_spiral(N, 0, 0, true);\n    for (int rotk = 0; rotk < 4; ++rotk) {\n        for (int refl = 0; refl < 2; ++refl) {\n            auto ord = transform_points_rc(spiral_base, N, rotk, refl);\n            if (is_adjacent_path(ord)) {\n                candidates.push_back(ord);\n                auto rord = ord; reverse(rord.begin(), rord.end());\n                candidates.push_back(rord);\n            }\n        }\n    }\n\n    // Deduplicate\n    sort(candidates.begin(), candidates.end(), [](const auto& a, const auto& b){\n        if (a.size() != b.size()) return a.size() < b.size();\n        return a < b;\n    });\n    candidates.erase(unique(candidates.begin(), candidates.end()), candidates.end());\n\n    Plan best;\n    for (const auto& ord : candidates) {\n        Plan p = build_plan(N, h, ord);\n        if (p.cost < best.cost) best = move(p);\n    }\n\n    for (const auto& s : best.ops) {\n        cout << s << '\\n';\n    }\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Seed {\n    int id;\n    array<int,15> x{};\n    int V=0;\n    double baseScore=0;\n    int maxComp=0;\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,T;\n    if(!(cin>>N>>M>>T)) return 0;\n    const int S = 2*N*(N-1); // 60\n    vector<Seed> seeds(S);\n    for(int i=0;i<S;i++){\n        seeds[i].id = i;\n        int sum=0; int mx=0;\n        for(int l=0;l<M;l++){\n            int v; cin>>v;\n            seeds[i].x[l]=v;\n            sum+=v; mx=max(mx,v);\n        }\n        seeds[i].V=sum;\n        seeds[i].baseScore=sum;\n        seeds[i].maxComp=mx;\n    }\n\n    // Grid\n    const int H=N, W=N, P=H*W;\n    auto pid=[&](int r,int c){ return r*W+c; };\n    vector<pair<int,int>> pos_of(P);\n    vector<vector<int>> adj(P);\n    for(int r=0;r<H;r++){\n        for(int c=0;c<W;c++){\n            int u=pid(r,c);\n            pos_of[u]={r,c};\n            if(r>0) adj[u].push_back(pid(r-1,c));\n            if(r+1<H) adj[u].push_back(pid(r+1,c));\n            if(c>0) adj[u].push_back(pid(r,c-1));\n            if(c+1<W) adj[u].push_back(pid(r,c+1));\n        }\n    }\n    auto degree=[&](int u){ return (int)adj[u].size(); };\n\n    // Three initial cell orders\n    vector<int> order1(P), order2(P), order3(P);\n    iota(order1.begin(), order1.end(), 0);\n    iota(order2.begin(), order2.end(), 0);\n    // degree-first, black-first\n    stable_sort(order1.begin(), order1.end(), [&](int a,int b){\n        int da=degree(a), db=degree(b);\n        if(da!=db) return da>db;\n        auto [ra,ca]=pos_of[a]; auto [rb,cb]=pos_of[b];\n        int caColor=(ra+ca)&1, cbColor=(rb+cb)&1;\n        if(caColor!=cbColor) return caColor<cbColor;\n        if(ra!=rb) return ra<rb;\n        return ca<cb;\n    });\n    // degree-first, white-first\n    iota(order2.begin(), order2.end(), 0);\n    stable_sort(order2.begin(), order2.end(), [&](int a,int b){\n        int da=degree(a), db=degree(b);\n        if(da!=db) return da>db;\n        auto [ra,ca]=pos_of[a]; auto [rb,cb]=pos_of[b];\n        int caColor=(ra+ca)&1, cbColor=(rb+cb)&1;\n        if(caColor!=cbColor) return caColor>cbColor;\n        if(ra!=rb) return ra<rb;\n        return ca<cb;\n    });\n    // serpentine order (snake), degree not used here\n    int idx=0;\n    for(int r=0;r<H;r++){\n        if(r%2==0){\n            for(int c=0;c<W;c++) order3[idx++] = pid(r,c);\n        }else{\n            for(int c=W-1;c>=0;c--) order3[idx++] = pid(r,c);\n        }\n    }\n\n    // Edges and incidence\n    vector<pair<int,int>> edges;\n    vector<vector<int>> posEdgeIdx(P);\n    {\n        vector<char> seen(P*P,0);\n        auto enc=[&](int a,int b){ return a*P+b; };\n        for(int u=0;u<P;u++){\n            for(int v: adj[u]){\n                if(u<v && !seen[enc(u,v)]){\n                    seen[enc(u,v)]=1;\n                    int ei=(int)edges.size();\n                    edges.emplace_back(u,v);\n                    posEdgeIdx[u].push_back(ei);\n                    posEdgeIdx[v].push_back(ei);\n                }\n            }\n        }\n    }\n    int E=(int)edges.size();\n\n    // Mild adaptive dimension weights\n    auto compute_dim_weights = [&](const vector<Seed>& pool)->array<double,15>{\n        array<int,15> curMax{};\n        curMax.fill(0);\n        for(auto &s: pool) for(int l=0;l<M;l++) curMax[l]=max(curMax[l], s.x[l]);\n        array<double,15> w{};\n        double sumw=0;\n        const double gamma=0.25;\n        for(int l=0;l<M;l++){\n            double wl = 1.0 + gamma * (max(0,100-curMax[l])) / 100.0; // 1..1.25\n            wl = max(0.85, min(1.25, wl));\n            w[l]=wl; sumw+=wl;\n        }\n        for(int l=0;l<M;l++) w[l] = w[l] * (M / sumw);\n        return w;\n    };\n\n    auto compute_base_scores = [&](vector<Seed>& pool, const array<double,15>& wdim){\n        int n=pool.size();\n        vector<int> idxv(n);\n        iota(idxv.begin(), idxv.end(), 0);\n        vector<vector<int>> rank(M, vector<int>(n,0));\n        for(int l=0;l<M;l++){\n            sort(idxv.begin(), idxv.end(), [&](int a,int b){\n                if(pool[a].x[l]!=pool[b].x[l]) return pool[a].x[l]>pool[b].x[l];\n                return pool[a].V>pool[b].V;\n            });\n            for(int r=0;r<n;r++) rank[l][idxv[r]] = r+1;\n        }\n        for(int i=0;i<n;i++){\n            pool[i].V=0; pool[i].maxComp=0;\n            for(int l=0;l<M;l++){ pool[i].V+=pool[i].x[l]; pool[i].maxComp=max(pool[i].maxComp, pool[i].x[l]); }\n        }\n        for(int i=0;i<n;i++){\n            double bonus=0.0;\n            for(int l=0;l<M;l++){\n                int r=rank[l][i];\n                double b=0.0;\n                if(r==1) b=3.0;\n                else if(r<=3) b=2.0;\n                else if(r<=6) b=1.0;\n                bonus += wdim[l]*b;\n            }\n            // small tie-break on max component to favor good donors\n            pool[i].baseScore = pool[i].V + 8.0*bonus + 0.5*pool[i].maxComp;\n        }\n    };\n\n    auto cosine_sim = [&](const Seed& a, const Seed& b)->double{\n        double dot=0, na=0, nb=0;\n        for(int l=0;l<M;l++){\n            double xa=a.x[l], xb=b.x[l];\n            dot += xa*xb; na += xa*xa; nb += xb*xb;\n        }\n        if(na==0||nb==0) return 0.0;\n        return dot / (sqrt(na)*sqrt(nb));\n    };\n\n    auto select_diverse = [&](const vector<Seed>& pool, int tTurn)->vector<int>{\n        int n=pool.size();\n        vector<int> ord(n);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a,int b){\n            if(pool[a].baseScore!=pool[b].baseScore) return pool[a].baseScore>pool[b].baseScore;\n            if(pool[a].V!=pool[b].V) return pool[a].V>pool[b].V;\n            return pool[a].maxComp>pool[b].maxComp;\n        });\n\n        int Klock = (tTurn>=T-2 ? 10 : 8);\n        vector<int> byV(n);\n        iota(byV.begin(), byV.end(), 0);\n        sort(byV.begin(), byV.end(), [&](int a,int b){\n            if(pool[a].V!=pool[b].V) return pool[a].V>pool[b].V;\n            if(pool[a].baseScore!=pool[b].baseScore) return pool[a].baseScore>pool[b].baseScore;\n            return pool[a].maxComp>pool[b].maxComp;\n        });\n        vector<int> selected; selected.reserve(P);\n        vector<char> used(n,0);\n        for(int i=0;i<Klock;i++){ selected.push_back(byV[i]); used[byV[i]]=1; }\n\n        static double simMat[60][60];\n        for(int i=0;i<n;i++){\n            for(int j=i;j<n;j++){\n                double s=cosine_sim(pool[i], pool[j]);\n                simMat[i][j]=simMat[j][i]=s;\n            }\n        }\n\n        double lambda = (tTurn>=T-1 ? 0.08 : (tTurn>=T-3 ? 0.20 : 0.32));\n        int limit = min(n, 50);\n        while((int)selected.size()<P){\n            int best=-1; double bestScore=-1e100;\n            for(int i=0;i<limit;i++){\n                int c=ord[i];\n                if(used[c]) continue;\n                vector<double> sims; sims.reserve(selected.size());\n                for(int s: selected) sims.push_back(simMat[c][s]);\n                double penalty=0.0;\n                if(!sims.empty()){\n                    nth_element(sims.begin(), sims.begin()+sims.size()/2, sims.end());\n                    penalty = sims[sims.size()/2];\n                }\n                double sc = pool[c].baseScore - lambda * 800.0 * penalty;\n                if(sc>bestScore){ bestScore=sc; best=c; }\n            }\n            if(best==-1){\n                for(int i=0;i<n;i++){ if(!used[ord[i]]){ best=ord[i]; break; } }\n            }\n            used[best]=1;\n            selected.push_back(best);\n        }\n        return selected;\n    };\n\n    // Edge fitness\n    auto edge_fitness = [&](const Seed& a, const Seed& b, const array<double,15>& wdim)->double{\n        double s=0.0;\n        int split=0;\n        for(int l=0;l<M;l++){\n            int ax=a.x[l], bx=b.x[l];\n            s += wdim[l] * (double)max(ax,bx);\n            if(ax!=bx) split++;\n        }\n        s += min(10, split);\n        return s;\n    };\n\n    auto evaluate_layout = [&](const vector<int>& pos2poolIdx, const vector<Seed>& pool, const array<double,15>& wdim, vector<double>& edgeVal)->double{\n        double total=0.0;\n        for(int e=0;e<E;e++){\n            int u=edges[e].first, v=edges[e].second;\n            int su=pos2poolIdx[u], sv=pos2poolIdx[v];\n            double val = edge_fitness(pool[su], pool[sv], wdim);\n            edgeVal[e]=val;\n            total += val;\n        }\n        return total;\n    };\n\n    mt19937 rng(1234567u + (unsigned)chrono::high_resolution_clock::now().time_since_epoch().count());\n\n    auto local_search = [&](vector<int>& pos2poolIdx, const vector<Seed>& pool, const array<double,15>& wdim, vector<double>& edgeVal, double& total, int itersA){\n        uniform_int_distribution<int> distPos(0, P-1);\n        // Phase A: random sampled best-improvement\n        for(int it=0; it<itersA; it++){\n            int a = distPos(rng);\n            int bestB=-1; double bestDelta=0.0;\n            int K = 8;\n            for(int s=0;s<K;s++){\n                int b = distPos(rng);\n                if(b==a) continue;\n                static int buf[16]; int cnt=0;\n                auto add=[&](int ei){ for(int t=0;t<cnt;t++) if(buf[t]==ei) return; buf[cnt++]=ei; };\n                for(int ei: posEdgeIdx[a]) add(ei);\n                for(int ei: posEdgeIdx[b]) add(ei);\n                double oldSum=0.0, newSum=0.0;\n                for(int t2=0;t2<cnt;t2++){\n                    int ei=buf[t2];\n                    oldSum += edgeVal[ei];\n                    int u=edges[ei].first, v=edges[ei].second;\n                    int su=pos2poolIdx[u], sv=pos2poolIdx[v];\n                    if(u==a) su=pos2poolIdx[b]; else if(u==b) su=pos2poolIdx[a];\n                    if(v==a) sv=pos2poolIdx[b]; else if(v==b) sv=pos2poolIdx[a];\n                    double val = edge_fitness(pool[su], pool[sv], wdim);\n                    newSum += val;\n                }\n                double delta=newSum-oldSum;\n                if(delta>bestDelta){ bestDelta=delta; bestB=b; }\n            }\n            if(bestB!=-1 && bestDelta>0.0){\n                swap(pos2poolIdx[a], pos2poolIdx[bestB]);\n                total += bestDelta;\n                static int buf[16]; int cnt=0;\n                auto add=[&](int ei){ for(int t=0;t<cnt;t++) if(buf[t]==ei) return; buf[cnt++]=ei; };\n                for(int ei: posEdgeIdx[a]) add(ei);\n                for(int ei: posEdgeIdx[bestB]) add(ei);\n                for(int t2=0;t2<cnt;t2++){\n                    int ei=buf[t2];\n                    int u=edges[ei].first, v=edges[ei].second;\n                    int su=pos2poolIdx[u], sv=pos2poolIdx[v];\n                    edgeVal[ei]=edge_fitness(pool[su], pool[sv], wdim);\n                }\n            }\n        }\n        // Phase B: deterministic greedy on high-degree positions with heuristic candidate set\n        vector<int> posByDeg(P);\n        iota(posByDeg.begin(), posByDeg.end(), 0);\n        sort(posByDeg.begin(), posByDeg.end(), [&](int a,int b){ return degree(a)>degree(b); });\n        int topD = min(P, 14);\n        for(int idx=0; idx<topD; idx++){\n            int a = posByDeg[idx];\n            double bestDelta=0.0; int bestB=-1;\n            vector<int> cand;\n            cand.reserve(20);\n            for(int nb: adj[a]) cand.push_back(nb);\n            for(int nb: adj[a]) for(int nb2: adj[nb]) cand.push_back(nb2);\n            cand.push_back(a);\n            sort(cand.begin(), cand.end());\n            cand.erase(unique(cand.begin(), cand.end()), cand.end());\n            uniform_int_distribution<int> distAll(0, P-1);\n            while((int)cand.size()<18){\n                int r = distAll(rng);\n                if(find(cand.begin(), cand.end(), r)==cand.end()) cand.push_back(r);\n            }\n            for(int b: cand){\n                if(b==a) continue;\n                static int buf[20]; int cnt=0;\n                auto add=[&](int ei){ for(int t=0;t<cnt;t++) if(buf[t]==ei) return; buf[cnt++]=ei; };\n                for(int ei: posEdgeIdx[a]) add(ei);\n                for(int ei: posEdgeIdx[b]) add(ei);\n                double oldSum=0.0, newSum=0.0;\n                for(int t2=0;t2<cnt;t2++){\n                    int ei=buf[t2];\n                    oldSum += edgeVal[ei];\n                    int u=edges[ei].first, v=edges[ei].second;\n                    int su=pos2poolIdx[u], sv=pos2poolIdx[v];\n                    if(u==a) su=pos2poolIdx[b]; else if(u==b) su=pos2poolIdx[a];\n                    if(v==a) sv=pos2poolIdx[b]; else if(v==b) sv=pos2poolIdx[a];\n                    double val = edge_fitness(pool[su], pool[sv], wdim);\n                    newSum += val;\n                }\n                double delta=newSum-oldSum;\n                if(delta>bestDelta){ bestDelta=delta; bestB=b; }\n            }\n            if(bestB!=-1 && bestDelta>0.0){\n                swap(pos2poolIdx[a], pos2poolIdx[bestB]);\n                static int buf[20]; int cnt=0;\n                auto add=[&](int ei){ for(int t=0;t<cnt;t++) if(buf[t]==ei) return; buf[cnt++]=ei; };\n                for(int ei: posEdgeIdx[a]) add(ei);\n                for(int ei: posEdgeIdx[bestB]) add(ei);\n                for(int t2=0;t2<cnt;t2++){\n                    int ei=buf[t2];\n                    int u=edges[ei].first, v=edges[ei].second;\n                    int su=pos2poolIdx[u], sv=pos2poolIdx[v];\n                    edgeVal[ei]=edge_fitness(pool[su], pool[sv], wdim);\n                }\n            }\n        }\n    };\n\n    auto force_super_edge = [&](vector<int>& pos2poolIdx, const vector<int>& selIdx, const vector<int>& order){\n        // Ensure top-2 by V are adjacent in the layout by swapping their positions into adjacent cells, if not already.\n        // Find indices of top-2 by V among selected\n        vector<int> sel = selIdx;\n        sort(sel.begin(), sel.end(), [&](int a,int b){\n            if(seeds[a].V!=seeds[b].V) return seeds[a].V>seeds[b].V;\n            if(seeds[a].baseScore!=seeds[b].baseScore) return seeds[a].baseScore>seeds[b].baseScore;\n            return seeds[a].maxComp>seeds[b].maxComp;\n        });\n        int sA = sel[0], sB = sel[1];\n        // Find positions where sA and sB are placed\n        int posA=-1, posB=-1;\n        for(int p=0;p<P;p++){\n            if(pos2poolIdx[ order[p] ]==sA) posA=order[p];\n            if(pos2poolIdx[ order[p] ]==sB) posB=order[p];\n        }\n        if(posA==-1 || posB==-1) return;\n        // If already adjacent, done\n        for(int nb: adj[posA]) if(nb==posB) return;\n        // Try to move sB near sA: find a neighbor cell of posA and swap its seed with sB\n        int target=-1;\n        for(int nb: adj[posA]){ target=nb; break; }\n        if(target==-1) return;\n        // find current position that holds sB\n        int curB=-1;\n        for(int p=0;p<P;p++){\n            if(pos2poolIdx[p]==sB){ curB=p; break; }\n        }\n        if(curB==-1) return;\n        swap(pos2poolIdx[target], pos2poolIdx[curB]);\n    };\n\n    for(int t=0;t<T;t++){\n        auto wdim = compute_dim_weights(seeds);\n        compute_base_scores(seeds, wdim);\n        vector<int> selIdx = select_diverse(seeds, t);\n\n        auto solve_layout = [&](const vector<int>& order)->pair<vector<int>, double>{\n            vector<int> pos2poolIdx(P,-1);\n            for(int k=0;k<P;k++) pos2poolIdx[ order[k] ] = selIdx[k];\n            // Force a \"super-edge\" by making top-2 adjacent (only on final 3 turns to bias outlier)\n            if(t>=T-3) force_super_edge(pos2poolIdx, selIdx, order);\n            vector<double> edgeVal(E,0.0);\n            double total = evaluate_layout(pos2poolIdx, seeds, wdim, edgeVal);\n            int itA = (t>=T-1 ? 5000 : (t>=T-3 ? 4300 : 3600));\n            local_search(pos2poolIdx, seeds, wdim, edgeVal, total, itA);\n            return {pos2poolIdx, total};\n        };\n\n        auto [layout1, score1] = solve_layout(order1);\n        auto [layout2, score2] = solve_layout(order2);\n        auto [layout3, score3] = solve_layout(order3);\n        vector<int> bestLayout = layout1;\n        double bestScore = score1;\n        if(score2>bestScore){ bestScore=score2; bestLayout=layout2; }\n        if(score3>bestScore){ bestScore=score3; bestLayout=layout3; }\n\n        // Output placement\n        for(int r=0;r<N;r++){\n            for(int c=0;c<N;c++){\n                if(c) cout << ' ';\n                int pos = pid(r,c);\n                cout << seeds[ bestLayout[pos] ].id;\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // Read next generation\n        vector<Seed> next(S);\n        for(int i=0;i<S;i++){\n            next[i].id=i;\n            int sum=0; int mx=0;\n            for(int l=0;l<M;l++){\n                int v; cin>>v;\n                next[i].x[l]=v;\n                sum+=v; mx=max(mx,v);\n            }\n            next[i].V=sum;\n            next[i].baseScore=sum;\n            next[i].maxComp=mx;\n        }\n        seeds.swap(next);\n    }\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Task {\n    int sx, sy, tx, ty;\n    // Chosen at execution time\n    int dir_pick=0, rpx=0, rpy=0;\n    int dir_drop=0, rdx=0, rdy=0;\n};\n\ninline int manh(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\ninline bool inb(int x,int y,int N){ return 0<=x && x<N && 0<=y && y<N; }\nstatic const int dx4[4]={0,1,0,-1};\nstatic const int dy4[4]={1,0,-1,0};\n\ninline pair<int,int> rot_need(int fromDir,int toDir){\n    int d = (toDir - fromDir + 4) % 4;\n    if(d==0) return {0,0};\n    if(d==1) return {1,0};\n    if(d==2) return {2,0}; // choose CW\n    return {0,1}; // d==3\n}\n\n// Hungarian algorithm for rectangular cost matrix. Returns assignment for rows.\nvector<int> hungarian_min_assign(const vector<vector<int>>& cost) {\n    int n = cost.size();\n    int m = cost[0].size();\n    int N = max(n, m);\n    const int INF = 1e9;\n    vector<vector<int>> a(N, vector<int>(N, 0));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            if(i<n && j<m) a[i][j] = cost[i][j];\n            else a[i][j] = 0;\n        }\n    }\n    vector<int> u(N+1,0), v(N+1,0), p(N+1,0), way(N+1,0);\n    for(int i=1;i<=N;i++){\n        p[0]=i;\n        int j0=0;\n        vector<int> minv(N+1, INF);\n        vector<char> used(N+1, false);\n        do{\n            used[j0]=true;\n            int i0=p[j0], delta=INF, j1=0;\n            for(int j=1;j<=N;j++){\n                if(used[j]) continue;\n                int cur = a[i0-1][j-1]-u[i0]-v[j];\n                if(cur<minv[j]) minv[j]=cur, way[j]=j0;\n                if(minv[j]<delta) delta=minv[j], j1=j;\n            }\n            for(int j=0;j<=N;j++){\n                if(used[j]) u[p[j]]+=delta, v[j]-=delta;\n                else minv[j]-=delta;\n            }\n            j0=j1;\n        } while(p[j0]!=0);\n        do{\n            int j1=way[j0];\n            p[j0]=p[j1];\n            j0=j1;\n        } while(j0);\n    }\n    vector<int> ans(n, -1);\n    for(int j=1;j<=N;j++){\n        if(p[j]>=1 && p[j]<=n && j<=m) ans[p[j]-1]=j-1;\n    }\n    return ans;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\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    vector<pair<int,int>> S, D;\n    vector<vector<int>> occ(N, vector<int>(N,0));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            int si=s[i][j]-'0', ti=t[i][j]-'0';\n            occ[i][j]=si;\n            if(si==1 && ti==0) S.emplace_back(i,j);\n            if(si==0 && ti==1) D.emplace_back(i,j);\n        }\n    }\n    int nS=S.size(), nD=D.size();\n    if(nS==0){\n        cout<<2<<\"\\n\";\n        cout<<0<<\" \"<<1<<\"\\n\";\n        cout<<0<<\" \"<<0<<\"\\n\";\n        return 0;\n    }\n\n    // Assignment\n    vector<int> assign(nS, -1);\n    if(nS <= 220){\n        vector<vector<int>> cost(nS, vector<int>(nD));\n        for(int i=0;i<nS;i++)\n            for(int j=0;j<nD;j++)\n                cost[i][j]=manh(S[i].first,S[i].second,D[j].first,D[j].second);\n        assign = hungarian_min_assign(cost);\n    }else{\n        // Deterministic greedy: process sources in Morton order to preserve locality\n        auto morton = [&](int x,int y){\n            // interleave bits up to 6 bits since N<=30\n            unsigned xx=x, yy=y;\n            unsigned z=0;\n            for(int b=0;b<6;b++){\n                z |= ((yy>>b)&1u) << (2*b);\n                z |= ((xx>>b)&1u) << (2*b+1);\n            }\n            return z;\n        };\n        vector<int> idx(nS);\n        iota(idx.begin(), idx.end(), 0);\n        sort(idx.begin(), idx.end(), [&](int a,int b){\n            auto [ax,ay]=S[a]; auto [bx,by]=S[b];\n            return morton(ax,ay)<morton(bx,by);\n        });\n        vector<char> usedD(nD,0);\n        for(int idS : idx){\n            auto [sx,sy]=S[idS];\n            int bj=-1, bd=INT_MAX;\n            for(int j=0;j<nD;j++){\n                if(usedD[j]) continue;\n                int d=manh(sx,sy,D[j].first,D[j].second);\n                if(d<bd){ bd=d; bj=j; }\n            }\n            if(bj>=0){ usedD[bj]=1; assign[idS]=bj; }\n        }\n        // Local improvements (deterministic order)\n        for(int a=0;a<nS;a++){\n            int da=assign[a]; if(da<0) continue;\n            for(int b=a+1;b<nS;b++){\n                int db=assign[b]; if(db<0) continue;\n                auto [ax,ay]=S[a]; auto [bx,by]=S[b];\n                auto [tax,tay]=D[da]; auto [tbx,tby]=D[db];\n                int before = manh(ax,ay,tax,tay) + manh(bx,by,tbx,tby);\n                int after  = manh(ax,ay,tbx,tby) + manh(bx,by,tax,tay);\n                if(after<before) swap(assign[a], assign[b]);\n            }\n        }\n        // One pass of 3-cycle improvement\n        for(int a=0;a<nS;a++){\n            int da=assign[a]; if(da<0) continue;\n            for(int b=a+1;b<nS;b++){\n                int db=assign[b]; if(db<0) continue;\n                for(int c=b+1;c<nS;c++){\n                    int dc=assign[c]; if(dc<0) continue;\n                    auto [ax,ay]=S[a]; auto [bx,by]=S[b]; auto [cx,cy]=S[c];\n                    auto [tax,tay]=D[da]; auto [tbx,tby]=D[db]; auto [tcx,tcy]=D[dc];\n                    int before = manh(ax,ay,tax,tay)+manh(bx,by,tbx,tby)+manh(cx,cy,tcx,tcy);\n                    int after1 = manh(ax,ay,tbx,tby)+manh(bx,by,tcx,tcy)+manh(cx,cy,tax,tay);\n                    int after2 = manh(ax,ay,tcx,tcy)+manh(bx,by,tax,tay)+manh(cx,cy,tbx,tby);\n                    if(after1<before && after1<=after2){\n                        int tmp=assign[a]; assign[a]=assign[b]; assign[b]=assign[c]; assign[c]=tmp;\n                    }else if(after2<before){\n                        int tmp=assign[a]; assign[a]=assign[c]; assign[c]=assign[b]; assign[b]=tmp;\n                    }\n                }\n            }\n        }\n    }\n\n    // Build tasks\n    vector<Task> tasks;\n    tasks.reserve(nS);\n    for(int i=0;i<nS;i++){\n        if(assign[i]>=0) tasks.push_back({S[i].first,S[i].second,D[assign[i]].first,D[assign[i]].second});\n    }\n    int Tn = tasks.size();\n    if(Tn==0){\n        cout<<2<<\"\\n\";\n        cout<<0<<\" \"<<1<<\"\\n\";\n        cout<<0<<\" \"<<0<<\"\\n\";\n        return 0;\n    }\n\n    // Sequencing: greedy NN from (0,0) considering minimal pick-root distance\n    vector<int> order; order.reserve(Tn);\n    vector<char> usedT(Tn, 0);\n    int crx=0, cry=0;\n    for(int it=0; it<Tn; ++it){\n        int best=-1, bd=INT_MAX;\n        for(int i=0;i<Tn;i++){\n            if(usedT[i]) continue;\n            // distance from current root to nearest feasible pick-root\n            int bestd=INT_MAX;\n            for(int k=0;k<4;k++){\n                int rpx = tasks[i].sx - dx4[k], rpy = tasks[i].sy - dy4[k];\n                if(!inb(rpx,rpy,N)) continue;\n                bestd = min(bestd, manh(crx,cry,rpx,rpy));\n            }\n            if(bestd<bd){ bd=bestd; best=i; }\n        }\n        usedT[best]=1; order.push_back(best);\n        // move current to the chosen pick-root approximation\n        int brx=crx, bry=cry, bestd2=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rpx = tasks[best].sx - dx4[k], rpy = tasks[best].sy - dy4[k];\n            if(!inb(rpx,rpy,N)) continue;\n            int d=manh(crx,cry,rpx,rpy);\n            if(d<bestd2){ bestd2=d; brx=rpx; bry=rpy; }\n        }\n        crx=brx; cry=bry;\n    }\n\n    // 2-opt with exact delta evaluation on transitions:\n    // Route consists of alternating pick-root and drop-root per task; inside each task, we choose best drop-root later,\n    // but for sequencing we approximate drop-root as the nearest to its pick-root.\n    auto pick_best_root_dist = [&](int fromx,int fromy, const Task& tk)->pair<int,pair<int,int>>{\n        int bestk=0; int brx=0,bry=0; int bd=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rpx=tk.sx - dx4[k], rpy=tk.sy - dy4[k];\n            if(!inb(rpx,rpy,N)) continue;\n            int d=manh(fromx,fromy,rpx,rpy);\n            if(d<bd){ bd=d; bestk=k; brx=rpx; bry=rpy; }\n        }\n        return {bestk, {brx,bry}};\n    };\n    auto drop_best_root_from_pick = [&](int prx,int pry, const Task& tk)->pair<int,pair<int,int>>{\n        int bestk=0; int brx=0,bry=0; int bd=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rdx=tk.tx - dx4[k], rdy=tk.ty - dy4[k];\n            if(!inb(rdx,rdy,N)) continue;\n            int d=manh(prx,pry,rdx,rdy);\n            if(d<bd){ bd=d; bestk=k; brx=rdx; bry=rdy; }\n        }\n        return {bestk, {brx,bry}};\n    };\n    auto route_cost = [&](const vector<int>& ord)->long long{\n        long long c=0;\n        int x=0,y=0;\n        for(int id: ord){\n            auto [pk, pr] = pick_best_root_dist(x,y,tasks[id]);\n            int prx=pr.first, pry=pr.second;\n            auto [dk, dr] = drop_best_root_from_pick(prx,pry,tasks[id]);\n            int drx=dr.first, dry=dr.second;\n            c += manh(x,y,prx,pry);\n            c += manh(prx,pry,drx,dry);\n            x=drx; y=dry;\n        }\n        return c;\n    };\n    long long rc = route_cost(order);\n    // 2-opt iterations\n    int n = order.size();\n    auto try_two_opt = [&](int a,int b){\n        if(b-a<2) return false;\n        // compute new cost quickly by recomputing whole since Tn<=~450, but limit iterations\n        vector<int> tmp = order;\n        reverse(tmp.begin()+a, tmp.begin()+b);\n        long long nc = route_cost(tmp);\n        if(nc < rc){\n            order.swap(tmp); rc=nc; return true;\n        }\n        return false;\n    };\n    // simple loop with deterministic pairs\n    for(int len=2; len<=min(n, 100); ++len){\n        for(int a=0; a+len<n; ++a){\n            int b=a+len;\n            try_two_opt(a,b);\n        }\n    }\n\n    // Execution\n    int rx=0, ry=0;\n    int leaf_dir=0; // Right\n    bool holding=false;\n    vector<string> out;\n    out.reserve(200000);\n    const int TURN_LIMIT = 100000;\n\n    auto emit_turn = [&](char mv, char rot, bool P){\n        string st(4,'.');\n        st[0]=mv?mv:'.';\n        st[1]=rot?rot:'.';\n        st[3]=P?'P':'.';\n        out.push_back(st);\n    };\n    auto move_step = [&](int tx,int ty, int &cw,int &ccw){\n        char mv='.';\n        if(rx<tx){ mv='D'; rx++; }\n        else if(rx>tx){ mv='U'; rx--; }\n        else if(ry<ty){ mv='R'; ry++; }\n        else if(ry>ty){ mv='L'; ry--; }\n        char rot='.';\n        if(cw>0){ rot='R'; cw--; leaf_dir=(leaf_dir+1)&3; }\n        else if(ccw>0){ rot='L'; ccw--; leaf_dir=(leaf_dir+3)&3; }\n        emit_turn(mv, rot, false);\n    };\n    auto move_to = [&](int tx,int ty, int &cw,int &ccw){\n        while((rx!=tx || ry!=ty) && (int)out.size()<TURN_LIMIT){\n            move_step(tx,ty,cw,ccw);\n        }\n    };\n\n    auto plan_pick = [&](const Task& tk)->tuple<int,int,int,int,int>{\n        // choose dir minimizing manh(root->pickRoot)+rot\n        int bestDir=0, brx=rx, bry=ry, bcw=0, bccw=0;\n        int bestScore=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rpx = tk.sx - dx4[k], rpy = tk.sy - dy4[k];\n            if(!inb(rpx,rpy,N)) continue;\n            auto [cw,ccw] = rot_need(leaf_dir, k);\n            int score = manh(rx,ry,rpx,rpy) + (cw+ccw);\n            if(score<bestScore){\n                bestScore=score; bestDir=k; brx=rpx; bry=rpy; bcw=cw; bccw=ccw;\n            }\n        }\n        return {bestDir, brx, bry, bcw, bccw};\n    };\n    auto best_pick_root_from = [&](int fromx,int fromy, const Task& tk){\n        int bestk=0, brx=0,bry=0, bd=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rpx = tk.sx - dx4[k], rpy = tk.sy - dy4[k];\n            if(!inb(rpx,rpy,N)) continue;\n            int d=manh(fromx,fromy,rpx,rpy);\n            if(d<bd){ bd=d; bestk=k; brx=rpx; bry=bry=rpy; }\n        }\n        return tuple<int,int,int>(bestk, brx, bry);\n    };\n\n    for(int idx_pos=0; idx_pos<(int)order.size(); ++idx_pos){\n        if((int)out.size()>=TURN_LIMIT) break;\n        Task &tk = tasks[order[idx_pos]];\n\n        // Plan pick\n        int dirp, prx, pry, pcw, pccw;\n        tie(dirp, prx, pry, pcw, pccw) = plan_pick(tk);\n        tk.dir_pick=dirp; tk.rpx=prx; tk.rpy=pry;\n\n        move_to(tk.rpx, tk.rpy, pcw, pccw);\n        while((pcw>0 || pccw>0) && (int)out.size()<TURN_LIMIT){\n            char rot='.';\n            if(pcw>0){ rot='R'; pcw--; leaf_dir=(leaf_dir+1)&3; }\n            else { rot='L'; pccw--; leaf_dir=(leaf_dir+3)&3; }\n            emit_turn('.', rot, false);\n        }\n        if((int)out.size()>=TURN_LIMIT) break;\n\n        // Pick\n        int fx = rx + dx4[leaf_dir];\n        int fy = ry + dy4[leaf_dir];\n        bool canPick = inb(fx,fy,N) && !holding && occ[fx][fy]==1;\n        emit_turn('.', '.', canPick);\n        if(canPick){ holding=true; occ[fx][fy]=0; }\n        if((int)out.size()>=TURN_LIMIT) break;\n\n        // Plan drop with exact lookahead to next task's optimal pick-root from the drop root\n        int dird=-1, drx=0, dry=0, dcw=0, dccw=0;\n        int bestScore=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rdx = tk.tx - dx4[k], rdy = tk.ty - dy4[k];\n            if(!inb(rdx,rdy,N)) continue;\n            auto [cw,ccw]=rot_need(leaf_dir, k);\n            // lookahead: if there is a next task, compute its best pick-root from (rdx,rdy)\n            int nextCost=0;\n            if(idx_pos+1 < (int)order.size()){\n                Task &nxt = tasks[order[idx_pos+1]];\n                int nk=0, nprx=0, npry=0, bd=INT_MAX;\n                for(int kk=0;kk<4;kk++){\n                    int rpx2 = nxt.sx - dx4[kk], rpy2 = nxt.sy - dy4[kk];\n                    if(!inb(rpx2,rpy2,N)) continue;\n                    int d = manh(rdx,rdy,rpx2,rpy2);\n                    if(d<bd){ bd=d; nk=kk; nprx=rpx2; npry=rpy2; }\n                }\n                nextCost = bd;\n            }\n            int score = manh(rx,ry,rdx,rdy) + (cw+ccw) + nextCost;\n            if(score < bestScore){\n                bestScore=score; dird=k; drx=rdx; dry=rdy; dcw=cw; dccw=ccw;\n            }\n        }\n        if(dird==-1){\n            // fallback\n            auto [cw,ccw]=rot_need(leaf_dir, 0);\n            dird=0; drx=tk.tx - dx4[0]; dry=tk.ty - dy4[0]; dcw=cw; dccw=ccw;\n        }\n        tk.dir_drop=dird; tk.rdx=drx; tk.rdy=dry;\n\n        move_to(tk.rdx, tk.rdy, dcw, dccw);\n        while((dcw>0 || dccw>0) && (int)out.size()<TURN_LIMIT){\n            char rot='.';\n            if(dcw>0){ rot='R'; dcw--; leaf_dir=(leaf_dir+1)&3; }\n            else { rot='L'; dccw--; leaf_dir=(leaf_dir+3)&3; }\n            emit_turn('.', rot, false);\n        }\n        if((int)out.size()>=TURN_LIMIT) break;\n\n        // Drop\n        fx = rx + dx4[leaf_dir];\n        fy = ry + dy4[leaf_dir];\n        bool canDrop = inb(fx,fy,N) && holding && occ[fx][fy]==0;\n        emit_turn('.', '.', canDrop);\n        if(canDrop){ holding=false; occ[fx][fy]=1; }\n        if((int)out.size()>=TURN_LIMIT) break;\n    }\n\n    // Output arm design: 2 vertices, edge length 1, root at (0,0)\n    cout<<2<<\"\\n\";\n    cout<<0<<\" \"<<1<<\"\\n\";\n    cout<<0<<\" \"<<0<<\"\\n\";\n    for(auto &row : out) cout<<row<<\"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    int w; // +1 mackerel, -1 sardine\n};\nstruct Rect {\n    int x1,y1,x2,y2; // inclusive\n    long long score = LLONG_MIN;\n    int a=0,b=0;\n};\n\nstatic inline long long rect_perimeter(int x1,int y1,int x2,int y2){\n    long long w = llabs((long long)x2 - x1);\n    long long h = llabs((long long)y2 - y1);\n    return 2*(w + h);\n}\nstatic inline bool insideRectInclusive(const Rect& r, int x, int y){\n    return (x >= r.x1 && x <= r.x2 && y >= r.y1 && y <= r.y2);\n}\n\nstruct Grid {\n    int G;\n    int B; // bin size\n    int maxCoord = 100000;\n    int W,H;\n    vector<int> a; // W*H\n    vector<long long> ps; // (W+1)*(H+1)\n    Grid(int G_): G(G_) {\n        B = (maxCoord + G - 1) / G; // ceil division\n        W = G; H = G;\n        a.assign(W*H, 0);\n        ps.assign((W+1)*(H+1), 0);\n    }\n    inline int idx(int ix,int iy) const { return iy*W + ix; }\n    inline void addPoint(int x,int y,int w){\n        int ix = min(W-1, x / B);\n        int iy = min(H-1, y / B);\n        a[idx(ix,iy)] += w;\n    }\n    void buildPS(){\n        for(int iy=0; iy<=H; ++iy){\n            for(int ix=0; ix<=W; ++ix){\n                if (ix==0 || iy==0) { ps[iy*(W+1)+ix] = 0; }\n            }\n        }\n        for(int iy=1; iy<=H; ++iy){\n            long long run = 0;\n            for(int ix=1; ix<=W; ++ix){\n                run += a[idx(ix-1,iy-1)];\n                ps[iy*(W+1)+ix] = ps[(iy-1)*(W+1)+ix] + run;\n            }\n        }\n    }\n    inline long long sumRectCells(int lx,int ly,int rx,int ry) const {\n        if (lx>rx || ly>ry) return 0;\n        lx = max(0,lx); ly = max(0,ly);\n        rx = min(W-1,rx); ry = min(H-1,ry);\n        if (lx>rx || ly>ry) return 0;\n        long long s = ps[(ry+1)*(W+1)+(rx+1)]\n                    - ps[(ly)*(W+1)+(rx+1)]\n                    - ps[(ry+1)*(W+1)+(lx)]\n                    + ps[(ly)*(W+1)+(lx)];\n        return s;\n    }\n    inline int cellX1(int ix) const { return max(0, ix * B); }\n    inline int cellX2(int ix) const { return min(maxCoord, (ix+1)*B); }\n    inline int cellY1(int iy) const { return max(0, iy * B); }\n    inline int cellY2(int iy) const { return min(maxCoord, (iy+1)*B); }\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    for(int i=0;i<N;i++){ int x,y; cin>>x>>y; pts.push_back({x,y,+1}); }\n    for(int i=0;i<N;i++){ int x,y; cin>>x>>y; pts.push_back({x,y,-1}); }\n\n    const long long PERIM_LIMIT = 400000;\n    const int MAXC = 100000;\n\n    // Build multiple grids\n    vector<int> Gsizes = {256, 384, 512};\n    vector<Grid> grids;\n    grids.reserve(Gsizes.size());\n    for(int g: Gsizes) grids.emplace_back(g);\n    for (auto &p: pts)\n        for (auto &gr: grids) gr.addPoint(p.x, p.y, p.w);\n    for (auto &gr: grids) gr.buildPS();\n\n    // Candidate pool\n    vector<Rect> candidates;\n    candidates.reserve(4000);\n\n    auto clamp_rect = [&](Rect r)->Rect{\n        r.x1 = max(0, min(MAXC, r.x1));\n        r.x2 = max(0, min(MAXC, r.x2));\n        r.y1 = max(0, min(MAXC, r.y1));\n        r.y2 = max(0, min(MAXC, r.y2));\n        if (r.x1 > r.x2) swap(r.x1, r.x2);\n        if (r.y1 > r.y2) swap(r.y1, r.y2);\n        if (r.x1==r.x2) { if (r.x2<MAXC) r.x2++; else if (r.x1>0) r.x1--; }\n        if (r.y1==r.y2) { if (r.y2<MAXC) r.y2++; else if (r.y1>0) r.y1--; }\n        if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) > PERIM_LIMIT){\n            // shrink around center\n            long long w = r.x2 - r.x1;\n            long long h = r.y2 - r.y1;\n            if (w + h == 0) return r;\n            long long max_sum = PERIM_LIMIT/2;\n            double scale = (double)max_sum / (double)(w + h);\n            long long nw = max(1LL, (long long)(w*scale));\n            long long nh = max(1LL, (long long)(h*scale));\n            long long cx = (r.x1 + r.x2)/2;\n            long long cy = (r.y1 + r.y2)/2;\n            long long nx1 = max(0LL, cx - nw/2);\n            long long nx2 = min((long long)MAXC, nx1 + nw);\n            nx1 = max(0LL, nx2 - nw);\n            long long ny1 = max(0LL, cy - nh/2);\n            long long ny2 = min((long long)MAXC, ny1 + nh);\n            ny1 = max(0LL, ny2 - nh);\n            r.x1 = (int)nx1; r.x2 = (int)nx2;\n            r.y1 = (int)ny1; r.y2 = (int)ny2;\n        }\n        return r;\n    };\n    auto add_candidate = [&](Rect r){\n        r = clamp_rect(r);\n        candidates.push_back(r);\n    };\n\n    // Grid-based candidates with multi-step expansions (binary search per side)\n    for (auto &gr: grids){\n        int W=gr.W, H=gr.H;\n        struct Cell { int ix,iy; int val; };\n        vector<Cell> cells;\n        cells.reserve(W*H);\n        for(int iy=0; iy<H; ++iy)\n            for(int ix=0; ix<W; ++ix)\n                cells.push_back({ix,iy, gr.a[gr.idx(ix,iy)]});\n        int T = min(300, (int)cells.size());\n        nth_element(cells.begin(), cells.begin()+T, cells.end(), [](const Cell& a, const Cell& b){ return a.val > b.val; });\n        cells.resize(T);\n\n        auto rectFromCells = [&](int lx,int ly,int rx,int ry)->Rect{\n            return Rect{ gr.cellX1(lx), gr.cellY1(ly), gr.cellX2(rx), gr.cellY2(ry), 0 };\n        };\n        auto perim_ok_cells = [&](int lx,int ly,int rx,int ry)->bool{\n            Rect r = rectFromCells(lx,ly,rx,ry);\n            return rect_perimeter(r.x1,r.y1,r.x2,r.y2) <= PERIM_LIMIT;\n        };\n        for (const auto &c: cells){\n            int lx=c.ix, rx=c.ix, ly=c.iy, ry=c.iy;\n            long long bestS = gr.sumRectCells(lx,ly,rx,ry);\n            bool improved = true;\n            int iter=0;\n            while (improved && iter<200){\n                ++iter;\n                improved = false;\n                int blx=lx, bly=ly, brx=rx, bry=ry;\n                long long bS = bestS;\n\n                // For each direction, try to expand by multiple cells using exponential then binary search\n                auto try_expand = [&](int &lx,int &ly,int &rx,int &ry, int dir)->void{\n                    // dir: 0 expand left, 1 right, 2 down, 3 up\n                    int Lx=lx, Ly=ly, Rx=rx, Ry=ry;\n                    int lo=0, hi=0;\n                    auto sumHere = [&](int Lx,int Ly,int Rx,int Ry){ return gr.sumRectCells(Lx,Ly,Rx,Ry); };\n                    auto ok = [&](int Lx,int Ly,int Rx,int Ry){ return perim_ok_cells(Lx,Ly,Rx,Ry); };\n                    // prepare movement limits\n                    auto advance = [&](int step)->bool{\n                        int nlx=Lx, nly=Ly, nrx=Rx, nry=Ry;\n                        if (dir==0) nlx = Lx - step;\n                        else if (dir==1) nrx = Rx + step;\n                        else if (dir==2) nly = Ly - step;\n                        else nry = Ry + step;\n                        if (nlx<0 || nly<0 || nrx>=W || nry>=H) return false;\n                        if (!ok(nlx,nly,nrx,nry)) return false;\n                        long long s = sumHere(nlx,nly,nrx,nry);\n                        if (s > bS){ bS = s; blx=nlx; bly=nly; brx=nrx; bry=nry; return true; }\n                        return false;\n                    };\n                    // exponential search for hi\n                    int step = 1;\n                    int lastGood = 0;\n                    while (true){\n                        int nlx=Lx, nly=Ly, nrx=Rx, nry=Ry;\n                        if (dir==0) nlx = Lx - step;\n                        else if (dir==1) nrx = Rx + step;\n                        else if (dir==2) nly = Ly - step;\n                        else nry = Ry + step;\n                        if (nlx<0 || nly<0 || nrx>=W || nry>=H) break;\n                        if (!ok(nlx,nly,nrx,nry)) break;\n                        lastGood = step;\n                        step <<= 1;\n                        if (step <= 0) break;\n                    }\n                    if (lastGood==0) return;\n                    // binary search in [1..lastGood] for best sum (not necessarily monotonic, but we will sample midpoints improving only; to stay simple, we can just try a few splits)\n                    int loStep = 1, hiStep = lastGood;\n                    // Instead of true binary search, try few trial steps: quarter, half, three-quarter, and lastGood\n                    vector<int> trials = { hiStep, hiStep*3/4, hiStep/2, hiStep/4 };\n                    sort(trials.begin(), trials.end());\n                    trials.erase(unique(trials.begin(), trials.end()), trials.end());\n                    for (int s: trials){\n                        int nlx=Lx, nly=Ly, nrx=Rx, nry=Ry;\n                        if (dir==0) nlx = Lx - s;\n                        else if (dir==1) nrx = Rx + s;\n                        else if (dir==2) nly = Ly - s;\n                        else nry = Ry + s;\n                        if (nlx<0 || nly<0 || nrx>=W || nry>=H) continue;\n                        if (!ok(nlx,nly,nrx,nry)) continue;\n                        long long val = sumHere(nlx,nly,nrx,nry);\n                        if (val > bS){ bS=val; blx=nlx; bly=nly; brx=nrx; bry=nry; }\n                    }\n                };\n\n                try_expand(lx,ly,rx,ry,0);\n                try_expand(lx,ly,rx,ry,1);\n                try_expand(lx,ly,rx,ry,2);\n                try_expand(lx,ly,rx,ry,3);\n\n                // Small shrinks might help if sardine-heavy margins got included\n                auto try_shrink = [&](int dir)->void{\n                    int nlx=lx, nly=ly, nrx=rx, nry=ry;\n                    if (dir==0 && lx<rx) nlx=lx+1;\n                    if (dir==1 && lx<rx) nrx=rx-1;\n                    if (dir==2 && ly<ry) nly=ly+1;\n                    if (dir==3 && ly<ry) nry=ry-1;\n                    if (nlx>nrx || nly>nry) return;\n                    long long s = gr.sumRectCells(nlx,nly,nrx,nry);\n                    if (s > bS){ bS=s; blx=nlx; bly=nly; brx=nrx; bry=nry; }\n                };\n                try_shrink(0); try_shrink(1); try_shrink(2); try_shrink(3);\n\n                if (bS > bestS){\n                    bestS = bS;\n                    lx=blx; ly=bly; rx=brx; ry=bry;\n                    improved = true;\n                }\n            }\n            Rect r = rectFromCells(lx,ly,rx,ry);\n            add_candidate(r);\n\n            // Add a few variants: small expansions if within perimeter\n            int variants = 3;\n            for(int t=1;t<=variants;t++){\n                int elx = max(0, lx - t);\n                int erx = min(W-1, rx + t);\n                int ely = max(0, ly - t);\n                int ery = min(H-1, ry + t);\n                Rect r2 = rectFromCells(elx,ly,rx,ry); add_candidate(r2);\n                r2 = rectFromCells(lx,ely,rx,ry); add_candidate(r2);\n                r2 = rectFromCells(lx,ly,erx,ry); add_candidate(r2);\n                r2 = rectFromCells(lx,ly,rx,ery); add_candidate(r2);\n            }\n        }\n    }\n\n    // Random sampling using biased coordinates\n    vector<int> xs_all, ys_all, xs_m, ys_m;\n    xs_all.reserve(pts.size()); ys_all.reserve(pts.size());\n    xs_m.reserve(pts.size()); ys_m.reserve(pts.size());\n    for (auto &p: pts){\n        xs_all.push_back(p.x); ys_all.push_back(p.y);\n        if (p.w==+1){ xs_m.push_back(p.x); ys_m.push_back(p.y); }\n    }\n    auto sample_unique = [&](const vector<int>& v, int k){\n        int M = v.size();\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        static std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n        shuffle(idx.begin(), idx.end(), rng);\n        unordered_set<int> seen;\n        seen.reserve(k*2);\n        vector<int> out; out.reserve(k);\n        for(int i=0;i<M && (int)out.size()<k;i++){\n            int val = v[idx[i]];\n            if (seen.insert(val).second) out.push_back(val);\n        }\n        sort(out.begin(), out.end());\n        return out;\n    };\n    vector<int> sx_all = sample_unique(xs_all, 250);\n    vector<int> sy_all = sample_unique(ys_all, 250);\n    vector<int> sx_m = sample_unique(xs_m, 250);\n    vector<int> sy_m = sample_unique(ys_m, 250);\n    auto merge_coords = [&](vector<int> a, vector<int> b){\n        a.insert(a.end(), b.begin(), b.end());\n        a.push_back(0); a.push_back(MAXC);\n        sort(a.begin(), a.end());\n        a.erase(unique(a.begin(), a.end()), a.end());\n        return a;\n    };\n    vector<int> sx = merge_coords(sx_all, sx_m);\n    vector<int> sy = merge_coords(sy_all, sy_m);\n\n    std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto randint = [&](int L, int R){ std::uniform_int_distribution<int> dist(L,R); return dist(rng); };\n\n    int Xn = (int)sx.size();\n    int Yn = (int)sy.size();\n\n    auto add_rect_from_bounds = [&](int xl,int xr,int yl,int yr){\n        if (xl==xr){ if (xr<MAXC) xr++; else if (xl>0) xl--; }\n        if (yl==yr){ if (yr<MAXC) yr++; else if (yl>0) yl--; }\n        Rect r{xl,yl,xr,yr,0};\n        if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) <= PERIM_LIMIT) add_candidate(r);\n    };\n\n    // Uniform random pairs\n    int S = 2000;\n    for(int t=0;t<S;t++){\n        int i1 = randint(0, Xn-1), i2 = randint(0, Xn-1);\n        int j1 = randint(0, Yn-1), j2 = randint(0, Yn-1);\n        if (i1==i2){ if (i2+1<Xn) i2++; else if (i1>0) i1--; }\n        if (j1==j2){ if (j2+1<Yn) j2++; else if (j1>0) j1--; }\n        int xl = min(sx[i1], sx[i2]);\n        int xr = max(sx[i1], sx[i2]);\n        int yl = min(sy[j1], sy[j2]);\n        int yr = max(sy[j1], sy[j2]);\n        add_rect_from_bounds(xl,xr,yl,yr);\n    }\n    // Biased rectangles: use mackerel coords for one axis\n    int Sb = 1000;\n    for(int t=0;t<Sb;t++){\n        int i1 = randint(0, (int)sx_m.size()-1);\n        int i2 = randint(0, (int)sx_m.size()-1);\n        int j1 = randint(0, Yn-1);\n        int j2 = randint(0, Yn-1);\n        if (i1==i2){ if (i2+1<(int)sx_m.size()) i2++; else if (i1>0) i1--; }\n        if (j1==j2){ if (j2+1<Yn) j2++; else if (j1>0) j1--; }\n        int xl = min(sx_m[i1], sx_m[i2]);\n        int xr = max(sx_m[i1], sx_m[i2]);\n        int yl = min(sy[j1], sy[j2]);\n        int yr = max(sy[j1], sy[j2]);\n        add_rect_from_bounds(xl,xr,yl,yr);\n    }\n    // Anchored rectangles\n    for(int t=0;t<400;t++){\n        int i = randint(0, Xn-1);\n        int j = randint(0, Yn-1);\n        int xl = min(sx[i], MAXC/2);\n        int xr = MAXC;\n        int yl = min(sy[j], MAXC/2);\n        int yr = MAXC;\n        add_rect_from_bounds(xl,xr,yl,yr);\n        add_rect_from_bounds(0, sx[i], 0, sy[j]);\n    }\n\n    // Exact evaluation function\n    auto evaluate = [&](Rect &r){\n        int a=0,b=0;\n        for (auto &p: pts){\n            if (insideRectInclusive(r, p.x, p.y)){\n                if (p.w==1) a++; else b++;\n            }\n        }\n        r.a = a; r.b = b;\n        r.score = (long long)a - (long long)b;\n    };\n\n    // Evaluate all candidates and keep top K\n    for (auto &r: candidates){\n        // ensure within limits\n        r = clamp_rect(r);\n    }\n    // Deduplicate rough by hashing bounds to reduce repeated evals\n    sort(candidates.begin(), candidates.end(), [](const Rect& A, const Rect& B){\n        if (A.x1!=B.x1) return A.x1<B.x1;\n        if (A.y1!=B.y1) return A.y1<B.y1;\n        if (A.x2!=B.x2) return A.x2<B.x2;\n        return A.y2<B.y2;\n    });\n    candidates.erase(unique(candidates.begin(), candidates.end(), [](const Rect& A, const Rect& B){\n        return A.x1==B.x1 && A.y1==B.y1 && A.x2==B.x2 && A.y2==B.y2;\n    }), candidates.end());\n\n    // Evaluate, keep top M\n    int Mkeep = 80;\n    vector<Rect> top;\n    top.reserve(Mkeep);\n    Rect best; best.score = LLONG_MIN;\n    for (auto &r: candidates){\n        evaluate(r);\n        if ((int)top.size() < Mkeep){\n            top.push_back(r);\n        }else{\n            // keep if better than worst\n            int worst = 0;\n            for (int i=1;i<Mkeep;i++) if (top[i].score < top[worst].score) worst = i;\n            if (r.score > top[worst].score || (r.score==top[worst].score && r.a > top[worst].a)){\n                top[worst] = r;\n            }\n        }\n        if (r.score > best.score || (r.score==best.score && r.a > best.a)) best = r;\n    }\n    if (top.empty()){\n        Rect r{0,0,MAXC,MAXC,0}; evaluate(r); best=r; top.push_back(r);\n    }\n\n    // Exact coordinate-descent refinement on top K\n    // Prepare candidate coordinate sets (unique x,y from points near the rectangle)\n    vector<int> xs_pts, ys_pts;\n    xs_pts.reserve(pts.size()); ys_pts.reserve(pts.size());\n    for (auto &p: pts){ xs_pts.push_back(p.x); ys_pts.push_back(p.y); }\n    sort(xs_pts.begin(), xs_pts.end()); xs_pts.erase(unique(xs_pts.begin(), xs_pts.end()), xs_pts.end());\n    sort(ys_pts.begin(), ys_pts.end()); ys_pts.erase(unique(ys_pts.begin(), ys_pts.end()), ys_pts.end());\n\n    auto refine_rect = [&](Rect r){\n        // Limit candidate positions to around current bounds to keep complexity reasonable\n        auto gather_candidates = [&](const vector<int>& v, int low, int high, int k)->vector<int>{\n            // collect indices near low and high\n            vector<int> cand;\n            cand.reserve(k*2 + 10);\n            int iLow = lower_bound(v.begin(), v.end(), low) - v.begin();\n            int iHigh = lower_bound(v.begin(), v.end(), high) - v.begin();\n            // add window around iLow and iHigh\n            for (int d=-k; d<=k; ++d){\n                int i = iLow + d;\n                if (0<=i && i<(int)v.size()) cand.push_back(v[i]);\n                i = iHigh + d;\n                if (0<=i && i<(int)v.size()) cand.push_back(v[i]);\n            }\n            cand.push_back(0); cand.push_back(MAXC);\n            sort(cand.begin(), cand.end());\n            cand.erase(unique(cand.begin(), cand.end()), cand.end());\n            return cand;\n        };\n        vector<int> candX1 = gather_candidates(xs_pts, r.x1, r.x2, 30);\n        vector<int> candX2 = candX1; // reuse\n        vector<int> candY1 = gather_candidates(ys_pts, r.y1, r.y2, 30);\n        vector<int> candY2 = candY1;\n\n        bool improved = true;\n        int iter=0;\n        while (improved && iter<5){\n            ++iter; improved = false;\n            // Move left side\n            Rect bestLoc = r;\n            for (int nx1: candX1){\n                if (nx1 > r.x2) break;\n                if (nx1==r.x1) continue;\n                Rect t{nx1, r.y1, r.x2, r.y2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n            // Move right side\n            bestLoc = r;\n            for (int nx2: candX2){\n                if (nx2 < r.x1) continue;\n                if (nx2==r.x2) continue;\n                Rect t{r.x1, r.y1, nx2, r.y2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n            // Move bottom\n            bestLoc = r;\n            for (int ny1: candY1){\n                if (ny1 > r.y2) break;\n                if (ny1==r.y1) continue;\n                Rect t{r.x1, ny1, r.x2, r.y2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n            // Move top\n            bestLoc = r;\n            for (int ny2: candY2){\n                if (ny2 < r.y1) continue;\n                if (ny2==r.y2) continue;\n                Rect t{r.x1, r.y1, r.x2, ny2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n        }\n        return r;\n    };\n\n    int refineK = min(30, (int)top.size());\n    // Select top refineK by current exact score\n    sort(top.begin(), top.end(), [](const Rect& A, const Rect& B){\n        if (A.score!=B.score) return A.score>B.score;\n        return A.a>B.a;\n    });\n    top.resize(refineK);\n\n    for (int i=0;i<refineK;i++){\n        Rect r = top[i];\n        Rect rr = refine_rect(r);\n        if (rr.score==LLONG_MIN) evaluate(rr);\n        if (rr.score > best.score || (rr.score==best.score && rr.a > best.a)) best = rr;\n    }\n\n    // Final small random nudges around best\n    {\n        std::uniform_int_distribution<int> d(-1000, 1000);\n        for (int t=0;t<200;t++){\n            int dx1 = d(rng), dx2 = d(rng), dy1 = d(rng), dy2 = d(rng);\n            Rect r{\n                max(0, min(MAXC, best.x1 + dx1)),\n                max(0, min(MAXC, best.y1 + dy1)),\n                max(0, min(MAXC, best.x2 + dx2)),\n                max(0, min(MAXC, best.y2 + dy2)),\n                0\n            };\n            if (r.x1>r.x2) swap(r.x1,r.x2);\n            if (r.y1>r.y2) swap(r.y1,r.y2);\n            if (r.x1==r.x2) { if (r.x2<MAXC) r.x2++; else if (r.x1>0) r.x1--; }\n            if (r.y1==r.y2) { if (r.y2<MAXC) r.y2++; else if (r.y1>0) r.y1--; }\n            if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) > PERIM_LIMIT) continue;\n            evaluate(r);\n            if (r.score > best.score || (r.score==best.score && r.a > best.a)) best = r;\n        }\n    }\n\n    // Output rectangle polygon\n    int x1 = max(0, min(MAXC, best.x1));\n    int y1 = max(0, min(MAXC, best.y1));\n    int x2 = max(0, min(MAXC, best.x2));\n    int y2 = max(0, min(MAXC, best.y2));\n    if (x1==x2){ if (x2<MAXC) x2++; else if (x1>0) x1--; }\n    if (y1==y2){ if (y2<MAXC) y2++; else if (y1>0) y1--; }\n    while (rect_perimeter(x1,y1,x2,y2) > PERIM_LIMIT){\n        if ((x2-x1) >= (y2-y1)){\n            if (x2-x1>1) x2--;\n            else if (y2-y1>1) y2--;\n            else break;\n        } else {\n            if (y2-y1>1) y2--;\n            else if (x2-x1>1) x2--;\n            else break;\n        }\n    }\n    cout << 4 << \"\\n\";\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct ColumnState {\n    long long sumH = 0;   // sum of heights in column\n    long long maxW = 0;   // max width in column\n    vector<int> items;    // indices assigned\n};\n\nstruct BuiltLayout {\n    vector<int> col_of;           // column rank (sorted by anchor) for each item\n    vector<int> rot;              // rotation chosen per item (0/1)\n    vector<int> anchor_of_col;    // anchor index per column rank\n    vector<int> prev_anchor;      // previous column's anchor per column rank\n    long long estW = 0, estH = 0;\n    int K = 1;\n};\n\nenum OrderType { BY_HEIGHT=0, BY_WIDTH=1, BY_MIXED=2 };\n\nstruct BuildParams {\n    int K;\n    double alpha;\n    double beta;\n    OrderType ord;\n    double mixedLambda; // weight for mixed ordering\n};\n\nstatic BuiltLayout build_and_improve(\n    int N,\n    const vector<long long>& w0, const vector<long long>& h0,\n    const BuildParams& P\n) {\n    int K = P.K;\n    // Precompute orientation dims\n    vector<long long> hA(N), wA(N), hB(N), wB(N);\n    vector<long long> hMin(N), wMax(N);\n    vector<long double> mixedKey(N);\n    for (int i = 0; i < N; i++) {\n        hA[i] = h0[i]; wA[i] = w0[i];\n        hB[i] = w0[i]; wB[i] = h0[i];\n        hMin[i] = min(h0[i], w0[i]);\n        wMax[i] = max(h0[i], w0[i]);\n        mixedKey[i] = (long double)wMax[i] + (long double)P.mixedLambda * (long double)hMin[i];\n    }\n    // Order items\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a, int b){\n        if (P.ord == BY_HEIGHT) {\n            if (hMin[a] != hMin[b]) return hMin[a] > hMin[b];\n            if (wMax[a] != wMax[b]) return wMax[a] > wMax[b];\n            return a < b;\n        } else if (P.ord == BY_WIDTH) {\n            if (wMax[a] != wMax[b]) return wMax[a] > wMax[b];\n            if (hMin[a] != hMin[b]) return hMin[a] > hMin[b];\n            return a < b;\n        } else {\n            if (mixedKey[a] != mixedKey[b]) return mixedKey[a] > mixedKey[b];\n            return a < b;\n        }\n    });\n\n    vector<ColumnState> cols(K);\n    vector<int> col_of(N, -1);\n    vector<int> rot(N, 0);\n    long long sumW = 0;\n\n    auto estH = [&]() -> long long {\n        long long mh=0;\n        for (int c=0;c<K;c++) mh = max(mh, cols[c].sumH);\n        return mh;\n    };\n    auto proxy_val = [&]() -> long long {\n        return sumW + estH();\n    };\n\n    // Assign items greedily with width-aware scoring and rotation choice\n    for (int idx : ord) {\n        int bestC = 0, bestR = 0;\n        long double bestScore = numeric_limits<long double>::infinity();\n        for (int c = 0; c < K; c++) {\n            // r=0\n            {\n                long long newH = cols[c].sumH + hA[idx];\n                long long newMaxW = max(cols[c].maxW, wA[idx]);\n                long long sumW_if = sumW - cols[c].maxW + newMaxW;\n                long double sc = P.alpha * (long double)newH + P.beta * (long double)sumW_if;\n                if (sc < bestScore) {\n                    bestScore = sc; bestC = c; bestR = 0;\n                }\n            }\n            // r=1\n            {\n                long long newH = cols[c].sumH + hB[idx];\n                long long newMaxW = max(cols[c].maxW, wB[idx]);\n                long long sumW_if = sumW - cols[c].maxW + newMaxW;\n                long double sc = P.alpha * (long double)newH + P.beta * (long double)sumW_if;\n                if (sc < bestScore) {\n                    bestScore = sc; bestC = c; bestR = 1;\n                }\n            }\n        }\n        // commit\n        if (bestR == 0) {\n            cols[bestC].sumH += hA[idx];\n            if (wA[idx] > cols[bestC].maxW) {\n                sumW += (wA[idx] - cols[bestC].maxW);\n                cols[bestC].maxW = wA[idx];\n            }\n        } else {\n            cols[bestC].sumH += hB[idx];\n            if (wB[idx] > cols[bestC].maxW) {\n                sumW += (wB[idx] - cols[bestC].maxW);\n                cols[bestC].maxW = wB[idx];\n            }\n        }\n        cols[bestC].items.push_back(idx);\n        col_of[idx] = bestC;\n        rot[idx] = bestR;\n    }\n\n    // Post-pass 1: Per-item rotation recheck within same column (safe)\n    for (int c = 0; c < K; c++) if (!cols[c].items.empty()) {\n        // Precompute current proxy once per column item\n        for (int idx : cols[c].items) {\n            long long baseProxy = proxy_val();\n            int r0 = rot[idx];\n            long long h0c = (r0==0 ? hA[idx] : hB[idx]);\n            long long w0c = (r0==0 ? wA[idx] : wB[idx]);\n            int r1 = 1 - r0;\n            long long h1c = (r1==0 ? hA[idx] : hB[idx]);\n            long long w1c = (r1==0 ? wA[idx] : wB[idx]);\n\n            // Calculate new sumW if flipping may change maxW of column c\n            long long oldMax = cols[c].maxW;\n            bool isMax = (w0c == oldMax);\n            long long sumW_if = sumW;\n            long long newMax = oldMax;\n            if (w1c <= oldMax) {\n                // If current was the max and we flip to smaller, need to recompute new max\n                if (isMax && w1c < oldMax) {\n                    long long rec=0;\n                    for (int v : cols[c].items) {\n                        if (v == idx) continue;\n                        long long wv = (rot[v]==0 ? wA[v] : wB[v]);\n                        if (wv > rec) rec = wv;\n                    }\n                    newMax = max(rec, w1c);\n                    sumW_if += (newMax - oldMax);\n                } // else no change\n            } else {\n                // Increase maxW\n                newMax = w1c;\n                sumW_if += (newMax - oldMax);\n            }\n            // estH change\n            long long estH_if = 0;\n            for (int cc=0; cc<K; cc++) {\n                long long sh = cols[cc].sumH + ((cc==c) ? (h1c - h0c) : 0);\n                if (cc==c) sh = cols[cc].sumH - h0c + h1c;\n                estH_if = max(estH_if, sh);\n            }\n            long long proxy_if = sumW_if + estH_if;\n            if (proxy_if < baseProxy) {\n                // flip\n                cols[c].sumH = cols[c].sumH - h0c + h1c;\n                if (newMax != oldMax) {\n                    cols[c].maxW = newMax;\n                    sumW = sumW_if;\n                }\n                rot[idx] = r1;\n            }\n        }\n    }\n\n    // Post-pass 2: Enhanced consolidation allowing sumW decrease even if target's max increases\n    if (K >= 2) {\n        vector<int> items(N);\n        iota(items.begin(), items.end(), 0);\n        sort(items.begin(), items.end(), [&](int a, int b){\n            long long wa = (rot[a]==0 ? wA[a] : wB[a]);\n            long long wb = (rot[b]==0 ? wA[b] : wB[b]);\n            if (wa != wb) return wa > wb;\n            return a < b;\n        });\n        int M = min(N, max(12, N/3));\n        for (int t = 0; t < M; t++) {\n            int idx = items[t];\n            int c0 = col_of[idx];\n            long long baseProxy = proxy_val();\n            long long h_contrib = (rot[idx]==0 ? hA[idx] : hB[idx]);\n            long long w_contrib = (rot[idx]==0 ? wA[idx] : wB[idx]);\n\n            // Remove from c0 temporarily\n            cols[c0].sumH -= h_contrib;\n            auto &vec = cols[c0].items;\n            auto itpos = find(vec.begin(), vec.end(), idx);\n            if (itpos != vec.end()) vec.erase(itpos);\n\n            long long oldMax_c0 = cols[c0].maxW;\n            long long sumW_after_remove = sumW;\n            bool maxWas = (w_contrib == oldMax_c0);\n            if (maxWas) {\n                long long rec=0;\n                for (int v : cols[c0].items) {\n                    long long wv = (rot[v]==0 ? wA[v] : wB[v]);\n                    if (wv > rec) rec = wv;\n                }\n                sumW_after_remove += (rec - oldMax_c0);\n            }\n\n            long long bestGain = 0;\n            int bestC = c0;\n            int bestR = rot[idx];\n\n            for (int c = 0; c < K; c++) if (c != c0) {\n                for (int rTry = 0; rTry < 2; rTry++) {\n                    long long addH = (rTry==0 ? hA[idx] : hB[idx]);\n                    long long addW = (rTry==0 ? wA[idx] : wB[idx]);\n                    long long oldMaxWc = cols[c].maxW;\n                    long long newMaxWc = max(oldMaxWc, addW);\n                    long long sumW_if = sumW_after_remove - oldMaxWc + newMaxWc;\n                    long long estH_if = 0;\n                    for (int cc=0; cc<K; cc++) {\n                        long long sh = cols[cc].sumH + ((cc==c) ? addH : 0);\n                        estH_if = max(estH_if, sh);\n                    }\n                    long long proxy_if = sumW_if + estH_if;\n                    long long gain = baseProxy - proxy_if;\n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestC = c;\n                        bestR = rTry;\n                    }\n                }\n            }\n\n            if (bestGain > 0) {\n                // commit to bestC\n                rot[idx] = bestR;\n                long long addH = (bestR==0 ? hA[idx] : hB[idx]);\n                long long addW = (bestR==0 ? wA[idx] : wB[idx]);\n                // update sumW and per-columns\n                if (maxWas) {\n                    long long rec=0;\n                    for (int v : cols[c0].items) {\n                        long long wv = (rot[v]==0 ? wA[v] : wB[v]);\n                        if (wv > rec) rec = wv;\n                    }\n                    sumW += (rec - oldMax_c0);\n                    cols[c0].maxW = rec;\n                }\n                cols[bestC].sumH += addH;\n                if (addW > cols[bestC].maxW) {\n                    sumW += (addW - cols[bestC].maxW);\n                    cols[bestC].maxW = addW;\n                }\n                cols[bestC].items.push_back(idx);\n                col_of[idx] = bestC;\n            } else {\n                // revert\n                cols[c0].sumH += h_contrib;\n                cols[c0].items.push_back(idx);\n            }\n        }\n    }\n\n    // Determine anchors (min index per original column)\n    vector<int> anchor_orig(K, -1);\n    for (int c = 0; c < K; c++) {\n        if (cols[c].items.empty()) continue;\n        int mn = cols[c].items[0];\n        for (int v : cols[c].items) mn = min(mn, v);\n        anchor_orig[c] = mn;\n    }\n    // Sort columns by anchor index (empty go last)\n    vector<int> col_order(K);\n    iota(col_order.begin(), col_order.end(), 0);\n    sort(col_order.begin(), col_order.end(), [&](int a, int b){\n        int aa = anchor_orig[a], bb = anchor_orig[b];\n        if (aa == -1) return false;\n        if (bb == -1) return true;\n        if (aa != bb) return aa < bb;\n        return a < b;\n    });\n\n    // Build outputs\n    BuiltLayout out;\n    out.K = K;\n    out.col_of.assign(N, -1);\n    out.rot = rot;\n    out.anchor_of_col.assign(K, -1);\n    out.prev_anchor.assign(K, -1);\n    long long estW_final = 0, estH_final = 0;\n    for (int pos = 0; pos < K; pos++) {\n        int c = col_order[pos];\n        if (anchor_orig[c] != -1) out.anchor_of_col[pos] = anchor_orig[c];\n        if (pos > 0) out.prev_anchor[pos] = anchor_orig[col_order[pos-1]];\n        for (int v : cols[c].items) out.col_of[v] = pos;\n        if (!cols[c].items.empty()) {\n            estW_final += cols[c].maxW;\n            estH_final = max(estH_final, cols[c].sumH);\n        }\n    }\n    out.estW = estW_final; out.estH = estH_final;\n    return out;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<long long> wp(N), hp(N);\n    for (int i = 0; i < N; i++) cin >> wp[i] >> hp[i];\n\n    // Build plan list\n    vector<int> Ks;\n    vector<int> baseK = {1,2,3,4,5,6,8,10,12};\n    for (int k : baseK) if (k <= N) Ks.push_back(k);\n    if ((int)Ks.size() > T) Ks.resize(T);\n\n    vector<pair<double,double>> AB = {\n        {1.0, 1.0},\n        {2.0, 1.0}\n    };\n    vector<OrderType> ORD = {BY_MIXED, BY_WIDTH, BY_HEIGHT};\n\n    struct Plan { BuildParams P; };\n    vector<Plan> plans;\n\n    // First phase: diverse deterministic plans\n    for (int k : Ks) {\n        for (auto [a,b] : AB) {\n            for (auto ord : ORD) {\n                BuildParams P;\n                P.K = k; P.alpha = a; P.beta = b; P.ord = ord; P.mixedLambda = 0.25;\n                plans.push_back({P});\n            }\n        }\n    }\n    int Pcnt = (int)plans.size();\n    if (Pcnt > T) plans.resize(T);\n\n    // Second phase: repeat best with lambda variations if we have remaining turns\n    int remaining = T - (int)plans.size();\n    vector<double> lambdas = {0.15, 0.25, 0.35};\n    // We'll fill later after knowing best plan (we still must output per turn; we decide adaptively)\n    int bestIdxSoFar = -1;\n    long long bestProxy = (1LL<<62);\n    BuildParams bestP = {max(2, min(8, N/8)), 1.0, 1.0, BY_MIXED, 0.25};\n\n    for (int t = 0; t < T; t++) {\n        BuildParams curP;\n        if (t < (int)plans.size()) {\n            curP = plans[t].P;\n        } else {\n            // Adaptive: repeat best with varied lambda\n            BuildParams P = bestP;\n            P.mixedLambda = lambdas[(t - (int)plans.size()) % (int)lambdas.size()];\n            curP = P;\n        }\n\n        auto layout = build_and_improve(N, wp, hp, curP);\n        long long proxy = layout.estW + layout.estH;\n        if (proxy < bestProxy) {\n            bestProxy = proxy;\n            bestIdxSoFar = t;\n            bestP = curP;\n        }\n\n        // Emit placement in increasing index order\n        cout << N << '\\n';\n        for (int i = 0; i < N; i++) {\n            int c = layout.col_of[i];\n            int b = -1;\n            if (c > 0) b = layout.prev_anchor[c];\n            cout << i << ' ' << layout.rot[i] << ' ' << 'U' << ' ' << b << '\\n';\n        }\n        cout.flush();\n        long long Wp, Hp;\n        if (!(cin >> Wp >> Hp)) return 0;\n        // Optional debug:\n        // cerr << \"# t=\"<<t<<\" K=\"<<curP.K<<\" ord=\"<<curP.ord<<\" lam=\"<<curP.mixedLambda<<\" proxy=\"<<proxy<<\" obs=\"<<(Wp+Hp)<<\"\\n\";\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct RunResult {\n    vector<int> parent;\n    vector<int> depth;\n    long long score;\n};\n\nstatic inline uint64_t get_time_us() {\n    using namespace std::chrono;\n    return duration_cast<microseconds>(steady_clock::now().time_since_epoch()).count();\n}\n\n// Layered multi-source BFS with controlled ordering\nstruct BFSEngine {\n    int N;\n    const vector<vector<int>> &adj;\n    const vector<int> &A;\n    BFSEngine(int N, const vector<vector<int>>& adj, const vector<int>& A): N(N), adj(adj), A(A) {}\n\n    void run(const vector<int>& roots, vector<int>& parent, vector<int>& depth, vector<int>& root_of){\n        const int INF = 1e9;\n        parent.assign(N, -2);\n        depth.assign(N, INF);\n        root_of.assign(N, -1);\n        vector<int> cur, nxt;\n        cur.reserve(N);\n        nxt.reserve(N);\n        for(int r: roots){\n            depth[r] = 0;\n            parent[r] = -1;\n            root_of[r] = r;\n            cur.push_back(r);\n        }\n        auto cmpNode = [&](int i, int j){\n            if(A[i] != A[j]) return A[i] < A[j];\n            int di = (int)adj[i].size(), dj = (int)adj[j].size();\n            if(di != dj) return di < dj; // prefer low-degree first\n            return i < j;\n        };\n        sort(cur.begin(), cur.end(), cmpNode);\n        int d = 0;\n        while(!cur.empty()){\n            for(int u: cur){\n                for(int v: adj[u]){\n                    if(depth[v] == INF){\n                        depth[v] = d + 1;\n                        parent[v] = u;\n                        root_of[v] = root_of[u];\n                        nxt.push_back(v);\n                    }else if(depth[v] == d + 1){\n                        int pu = parent[v];\n                        if(A[u] < A[pu] || (A[u]==A[pu] && (int)adj[u].size() < (int)adj[pu].size())){\n                            parent[v] = u;\n                            root_of[v] = root_of[u];\n                        }\n                    }\n                }\n            }\n            d++;\n            if(nxt.empty()) break;\n            sort(nxt.begin(), nxt.end(), cmpNode);\n            cur.clear();\n            cur.swap(nxt);\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    vector<int> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\n    vector<vector<int>> adj(N);\n    vector<pair<int,int>> edges(M);\n    for(int i=0;i<M;i++){\n        int u,v; cin >> u >> v;\n        edges[i] = {u,v};\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    for(int i=0;i<N;i++){ int x,y; cin >> x >> y; (void)x; (void)y; }\n\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j){\n        if(A[i]!=A[j]) return A[i] < A[j];\n        return i < j;\n    });\n\n    BFSEngine bfs(N, adj, A);\n\n    auto compute_score = [&](const vector<int>& depth)-> long long {\n        long long s = 1;\n        for(int i=0;i<N;i++){\n            int d = depth[i];\n            if(d < 0 || d > 100000000) d = 0;\n            s += 1LL * (d + 1) * A[i];\n        }\n        return s;\n    };\n\n    // Post-process: choose parent among neighbors at depth-1 by minimal A then minimal degree\n    auto refine_parents = [&](vector<int>& parent, const vector<int>& depth){\n        for(int v=0; v<N; v++){\n            int d = depth[v];\n            if(d <= 0) continue;\n            int bestp = parent[v];\n            int bestA = (bestp>=0 ? A[bestp] : INT_MAX);\n            int bestDeg = (bestp>=0 ? (int)adj[bestp].size() : INT_MAX);\n            for(int u: adj[v]){\n                if(depth[u] == d-1){\n                    int du = (int)adj[u].size();\n                    if(A[u] < bestA || (A[u]==bestA && du < bestDeg)){\n                        bestA = A[u];\n                        bestDeg = du;\n                        bestp = u;\n                    }\n                }\n            }\n            parent[v] = bestp;\n        }\n    };\n\n    // Weighted coverage estimate: sum of A for nodes with depth>H within H steps from cand\n    auto estimate_coverage_weighted = [&](int cand, const vector<int>& depth)-> long long {\n        vector<int> dist(N, INT_MAX);\n        deque<int> dq;\n        dist[cand] = 0;\n        dq.push_back(cand);\n        long long covered = 0;\n        while(!dq.empty()){\n            int u = dq.front(); dq.pop_front();\n            if(depth[u] > H) covered += A[u];\n            if(dist[u] == H) continue;\n            for(int v: adj[u]){\n                if(dist[v] == INT_MAX){\n                    dist[v] = dist[u] + 1;\n                    dq.push_back(v);\n                }\n            }\n        }\n        return covered;\n    };\n\n    // Build roots with enhanced selection\n    auto build_roots = [&](int seed)-> vector<int> {\n        vector<int> roots;\n        roots.push_back(seed);\n        vector<int> parent, depth, root_of;\n        bfs.run(roots, parent, depth, root_of);\n        while(true){\n            int Dmax = -1;\n            for(int v=0; v<N; v++) if(depth[v] > H && depth[v] < INT_MAX) Dmax = max(Dmax, depth[v]);\n            if(Dmax == -1) break;\n            int band_low = max(H+1, Dmax - 3);\n            struct Cand { int v; int a; int d; int deg; long long cov; };\n            vector<Cand> cands;\n            cands.reserve(96);\n            for(int v=0; v<N; v++){\n                if(depth[v] > H && depth[v] >= band_low){\n                    cands.push_back({v, A[v], depth[v], (int)adj[v].size(), 0});\n                }\n            }\n            if(cands.empty()){\n                for(int v=0; v<N; v++){\n                    if(depth[v] > H){\n                        cands.push_back({v, A[v], depth[v], (int)adj[v].size(), 0});\n                    }\n                }\n            }\n            if(cands.empty()) break;\n            sort(cands.begin(), cands.end(), [&](const Cand& x, const Cand& y){\n                if(x.a != y.a) return x.a < y.a;\n                if(x.d != y.d) return x.d > y.d;\n                return x.deg > y.deg;\n            });\n            int K = min<int>(48, cands.size());\n            int bestIdx = 0;\n            int bestA = INT_MAX, bestD = -1, bestDeg = -1;\n            long long bestCov = -1;\n            for(int i=0;i<K;i++){\n                int v = cands[i].v;\n                long long cov = estimate_coverage_weighted(v, depth);\n                cands[i].cov = cov;\n                int a = cands[i].a;\n                int d = cands[i].d;\n                int deg = cands[i].deg;\n                if(a < bestA ||\n                   (a==bestA && cov > bestCov) ||\n                   (a==bestA && cov==bestCov && d > bestD) ||\n                   (a==bestA && cov==bestCov && d==bestD && deg > bestDeg)){\n                    bestA = a; bestCov = cov; bestD = d; bestDeg = deg; bestIdx = i;\n                }\n            }\n            int pick = cands[bestIdx].v;\n            roots.push_back(pick);\n            bfs.run(roots, parent, depth, root_of);\n        }\n        return roots;\n    };\n\n    // Prepare seeds\n    int L_low = min(N, 160);\n    vector<int> lowA(order.begin(), order.begin()+L_low);\n\n    auto farthest_sampling = [&](int k)-> vector<int> {\n        vector<int> seeds;\n        if(lowA.empty() || k<=0) return seeds;\n        seeds.push_back(lowA[0]);\n        vector<int> dist(N, INT_MAX);\n        while((int)seeds.size() < k){\n            deque<int> dq;\n            fill(dist.begin(), dist.end(), INT_MAX);\n            for(int s: seeds){\n                dist[s] = 0;\n                dq.push_back(s);\n            }\n            while(!dq.empty()){\n                int u = dq.front(); dq.pop_front();\n                for(int v: adj[u]){\n                    if(dist[v] == INT_MAX){\n                        dist[v] = dist[u] + 1;\n                        dq.push_back(v);\n                    }\n                }\n            }\n            int bestv = -1, bestd = -1, besta = INT_MAX;\n            for(int v: lowA){\n                if(dist[v] > bestd || (dist[v]==bestd && A[v] < besta)){\n                    bestd = dist[v];\n                    besta = A[v];\n                    bestv = v;\n                }\n            }\n            if(bestv == -1) break;\n            if(find(seeds.begin(), seeds.end(), bestv) != seeds.end()) break;\n            seeds.push_back(bestv);\n        }\n        return seeds;\n    };\n\n    uint64_t start_us = get_time_us();\n    uint64_t time_budget_us = 1900000; // ~1.9s\n    vector<int> seed_list;\n    int K_byA = min(18, L_low);\n    for(int i=0;i<K_byA;i++) seed_list.push_back(lowA[i]);\n    vector<int> spread = farthest_sampling(8);\n    for(int s: spread) seed_list.push_back(s);\n    sort(seed_list.begin(), seed_list.end());\n    seed_list.erase(unique(seed_list.begin(), seed_list.end()), seed_list.end());\n\n    RunResult best; best.score = LLONG_MIN;\n\n    for(size_t si=0; si<seed_list.size(); si++){\n        if(get_time_us() - start_us > time_budget_us) break;\n        int seed = seed_list[si];\n        vector<int> roots = build_roots(seed);\n        vector<int> parent, depth, root_of;\n        bfs.run(roots, parent, depth, root_of);\n\n        // Safety: enforce constraints\n        for(int i=0;i<N;i++){\n            if(depth[i] == INT_MAX){ parent[i] = -1; depth[i] = 0; }\n            if(depth[i] > H){ parent[i] = -1; depth[i] = 0; }\n            if(parent[i] == -2){ parent[i] = -1; if(depth[i] == INT_MAX) depth[i] = 0; }\n        }\n        // Refinement: choose best parent among depth-1 neighbors\n        refine_parents(parent, depth);\n\n        // Final validation and repair to ensure a forest of rooted trees using edges of G and height <= H\n        // 1) Ensure parent edge exists in G; build adjacency set for quick check\n        vector<unordered_set<int>> adjset(N);\n        for(int u=0; u<N; u++){\n            adjset[u].reserve(adj[u].size()*2+1);\n            for(int v: adj[u]) adjset[u].insert(v);\n        }\n        for(int v=0; v<N; v++){\n            if(parent[v] >= 0){\n                int p = parent[v];\n                if(p<0 || p>=N || !adjset[v].count(p)){\n                    parent[v] = -1;\n                    depth[v] = 0;\n                }\n            }\n        }\n        // 2) Recompute depths from roots and detect cycles\n        vector<int> indeg(N,0);\n        for(int v=0; v<N; v++) if(parent[v] >= 0) indeg[v]++;\n        // Build children lists and check for cycles using visited status\n        vector<int> new_depth(N, -1);\n        vector<int> state(N, 0); // 0 unvisited, 1 visiting, 2 done\n        function<void(int)> dfs = [&](int v){\n            state[v] = 1;\n            int p = parent[v];\n            if(p == -1){\n                new_depth[v] = 0;\n            }else{\n                if(state[p] == 0){\n                    dfs(p);\n                }else if(state[p] == 1){\n                    // cycle found; break it by making this node a root\n                    parent[v] = -1;\n                    new_depth[v] = 0;\n                }else{\n                    // parent done\n                }\n                if(parent[v] == -1){\n                    new_depth[v] = 0;\n                }else{\n                    if(new_depth[p] == -1) new_depth[v] = 0; // should not happen\n                    else new_depth[v] = new_depth[p] + 1;\n                }\n            }\n            state[v] = 2;\n        };\n        for(int v=0; v<N; v++){\n            if(state[v] == 0) dfs(v);\n        }\n        // 3) Enforce height limit H: if any depth > H, cut to root\n        for(int v=0; v<N; v++){\n            if(new_depth[v] > H){\n                parent[v] = -1;\n                new_depth[v] = 0;\n            }\n        }\n        // 4) Optional: fix any parent non-edge (shouldn't be after step 1)\n        for(int v=0; v<N; v++){\n            if(parent[v] >= 0 && !adjset[v].count(parent[v])){\n                parent[v] = -1;\n                new_depth[v] = 0;\n            }\n        }\n\n        long long sc = compute_score(new_depth);\n        if(sc > best.score){\n            best.score = sc;\n            best.parent = parent;\n        }\n    }\n\n    if(best.parent.empty()){\n        vector<int> parent(N, -1);\n        for(int i=0;i<N;i++){\n            if(i) cout << ' ';\n            cout << parent[i];\n        }\n        cout << '\\n';\n        return 0;\n    }\n\n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << best.parent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<string> C(N);\n    for (int i = 0; i < N; ++i) cin >> C[i];\n\n    // Collect positions and precompute Fukunokami positions.\n    vector<vector<bool>> hasF(N, vector<bool>(N, false));\n    vector<pair<int,int>> oni;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (C[i][j] == 'o') hasF[i][j] = true;\n            else if (C[i][j] == 'x') oni.emplace_back(i, j);\n        }\n    }\n\n    // Precompute prefix counts of Fukunokami per row/column to check rays quickly.\n    vector<vector<int>> rowPref(N, vector<int>(N+1, 0));\n    vector<vector<int>> colPref(N, vector<int>(N+1, 0));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            rowPref[i][j+1] = rowPref[i][j] + (hasF[i][j] ? 1 : 0);\n            colPref[j][i+1] = colPref[j][i] + (hasF[i][j] ? 1 : 0);\n        }\n    }\n\n    auto safe_up = [&](int i, int j)->bool {\n        // No Fukunokami above (rows 0..i-1) in column j\n        if (i == 0) return true;\n        return colPref[j][i] - colPref[j][0] == 0;\n    };\n    auto safe_down = [&](int i, int j)->bool {\n        // No Fukunokami below (rows i+1..N-1) in column j\n        if (i == N-1) return true;\n        return colPref[j][N] - colPref[j][i+1] == 0;\n    };\n    auto safe_left = [&](int i, int j)->bool {\n        if (j == 0) return true;\n        return rowPref[i][j] - rowPref[i][0] == 0;\n    };\n    auto safe_right = [&](int i, int j)->bool {\n        if (j == N-1) return true;\n        return rowPref[i][N] - rowPref[i][j+1] == 0;\n    };\n\n    struct Op { char d; int p; };\n    vector<Op> ops;\n    ops.reserve(1600);\n\n    // For each Oni, pick minimal cost safe direction and emit.\n    for (auto [i, j] : oni) {\n        // Determine available safe directions and their costs.\n        int bestCost = INT_MAX;\n        char bestDir = 0;\n        int param = -1; // row/col index\n\n        // Up\n        if (safe_up(i, j)) {\n            int k = i; // distance to top edge\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'U'; param = j; }\n        }\n        // Down\n        if (safe_down(i, j)) {\n            int k = (N - 1 - i);\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'D'; param = j; }\n        }\n        // Left\n        if (safe_left(i, j)) {\n            int k = j;\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'L'; param = i; }\n        }\n        // Right\n        if (safe_right(i, j)) {\n            int k = (N - 1 - j);\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'R'; param = i; }\n        }\n\n        // Per problem guarantee, at least one is safe.\n        if (bestDir == 0) {\n            // Fallback: should not happen; do nothing to avoid WA.\n            continue;\n        }\n\n        // Emit k+1 pushes toward bestDir, then k+1 pushes back.\n        int k;\n        char backDir;\n        if (bestDir == 'U') { k = i; backDir = 'D'; }\n        else if (bestDir == 'D') { k = (N - 1 - i); backDir = 'U'; }\n        else if (bestDir == 'L') { k = j; backDir = 'R'; }\n        else { // 'R'\n            k = (N - 1 - j); backDir = 'L';\n        }\n\n        // Ensure we do not exceed 4N^2 operations; with guarantees this should hold.\n        // But add a safety break.\n        if ((int)ops.size() + 2 * (k + 1) > 4 * N * N) break;\n\n        for (int t = 0; t < k + 1; ++t) ops.push_back({bestDir, param});\n        for (int t = 0; t < k + 1; ++t) ops.push_back({backDir, param});\n    }\n\n    // Output\n    for (auto &op : ops) {\n        cout << op.d << ' ' << op.p << '\\n';\n    }\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::high_resolution_clock::time_point st;\n    Timer(){ reset(); }\n    void reset(){ st = chrono::high_resolution_clock::now(); }\n    double elapsed() const {\n        auto ed = chrono::high_resolution_clock::now();\n        return chrono::duration<double>(ed - st).count();\n    }\n};\n\nstatic inline long long llabsll(long long x){ return x<0?-x:x; }\n\nstruct Solution {\n    vector<int> a, b, t;\n    long long error = (1LL<<60);\n};\n\nstatic inline vector<int> simulate_counts(const vector<int>& a, const vector<int>& b, long long L){\n    int N = (int)a.size();\n    vector<int> t(N,0);\n    int x = 0;\n    for(long long week=0; week<L; week++){\n        t[x]++;\n        int nx = ((t[x] & 1) ? a[x] : b[x]);\n        x = nx;\n    }\n    return t;\n}\nstatic inline long long compute_error(const vector<int>& t, const vector<int>& T){\n    long long e=0;\n    int N = (int)t.size();\n    for(int i=0;i<N;i++) e += llabsll((long long)t[i]-T[i]);\n    return e;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N; long long L;\n    if(!(cin>>N>>L)) return 0;\n    vector<int> T(N);\n    for(int i=0;i<N;i++) cin>>T[i];\n\n    Timer tim;\n    std::mt19937 rng(20250916);\n\n    // Backbone b: a simple ring\n    vector<int> b(N);\n    for(int i=0;i<N;i++) b[i] = (i+1)%N;\n\n    // Approximate usage per source\n    vector<int> d1(N), d0(N);\n    for(int i=0;i<N;i++){ d1[i] = (T[i]+1)/2; d0[i] = T[i]/2; }\n\n    // Helper: recompute over/under lists\n    auto recompute_lists = [&](const vector<int>& t, vector<pair<long long,int>>& over, vector<pair<long long,int>>& under){\n        over.clear(); under.clear();\n        for(int i=0;i<N;i++){\n            long long diff = (long long)t[i] - T[i];\n            if(diff > 0) over.push_back({diff, i});\n            else if(diff < 0) under.push_back({-diff, i});\n        }\n        sort(over.begin(), over.end(), greater<>());\n        sort(under.begin(), under.end(), greater<>());\n    };\n\n    // Build initial a via destination-priority greedy (b-matching-like)\n    auto build_candidate_a = [&](int seed)->vector<int>{\n        vector<int> a(N, -1);\n        // compute b-inflow and a-demands\n        vector<int> b_in(N,0);\n        for(int i=0;i<N;i++) b_in[b[i]] += d0[i];\n        vector<long long> a_dem(N,0);\n        for(int j=0;j<N;j++){\n            long long need = (long long)T[j] - (long long)b_in[j];\n            if(need < 0) need = 0;\n            a_dem[j] = need;\n        }\n        vector<int> a_sup = d1;\n\n        // destination priority queue\n        struct Dest { long long rem; int id; };\n        struct Cmp { bool operator()(const Dest& A, const Dest& B) const {\n            if(A.rem != B.rem) return A.rem < B.rem;\n            return A.id > B.id;\n        } };\n        priority_queue<Dest, vector<Dest>, Cmp> pq;\n        for(int j=0;j<N;j++) pq.push({a_dem[j], j});\n\n        // sources sorted by supply desc with rotation\n        vector<int> src(N); iota(src.begin(), src.end(), 0);\n        int rot = (seed % N);\n        sort(src.begin(), src.end(), [&](int x, int y){\n            if(a_sup[x] != a_sup[y]) return a_sup[x] > a_sup[y];\n            return ((x-rot+N)%N) < ((y-rot+N)%N);\n        });\n\n        // iterator over sources in cycling order for each picked destination\n        deque<int> srcdq(src.begin(), src.end());\n\n        // assignment loop: pick the destination with max remaining demand, assign a source with max supply\n        int guard = 0;\n        while(!pq.empty() && guard < 3*N){\n            guard++;\n            Dest top = pq.top(); pq.pop();\n            if(top.rem <= 0){\n                // all remaining are zero\n                break;\n            }\n            int dst = top.id;\n            // pick a source with largest supply not causing a 2-cycle\n            int picked_s = -1; int picked_idx = -1;\n            // try a handful from front\n            int tries = min((int)srcdq.size(), 12);\n            for(int k=0;k<tries;k++){\n                int s = srcdq[k];\n                if(a_sup[s] <= 0) continue;\n                if(dst == b[s] || dst == s) continue;\n                picked_s = s; picked_idx = k; break;\n            }\n            if(picked_s==-1){\n                // find any with positive supply\n                for(int k=0;k<(int)srcdq.size();k++){\n                    int s = srcdq[k];\n                    if(a_sup[s] <= 0) continue;\n                    if(dst == b[s] || dst == s) continue;\n                    picked_s = s; picked_idx = k; break;\n                }\n            }\n            if(picked_s==-1){\n                // force pick largest supply ignoring constraint\n                for(int k=0;k<(int)srcdq.size();k++){\n                    int s = srcdq[k];\n                    if(a_sup[s] > 0){ picked_s = s; picked_idx = k; break; }\n                }\n            }\n            if(picked_s==-1){\n                // no available sources with supply\n                pq.push(top);\n                break;\n            }\n            // assign dst to picked_s\n            a[picked_s] = dst;\n            long long used = min<long long>(a_sup[picked_s], top.rem);\n            a_sup[picked_s] = 0; // one a per source\n            top.rem -= used;\n            // move picked to back\n            srcdq.erase(srcdq.begin()+picked_idx);\n            srcdq.push_back(picked_s);\n            // push back updated destination\n            pq.push(top);\n        }\n\n        // fill any remaining unassigned sources with near-ring alternatives\n        for(int i=0;i<N;i++){\n            if(a[i] == -1){\n                int cand = (b[i]+2)%N;\n                if(cand==i) cand=(cand+1)%N;\n                if(cand==b[i]) cand=(cand+1)%N;\n                a[i] = cand;\n            }\n            if(a[i] == b[i]){\n                int alt = (b[i]+2)%N;\n                if(alt==i) alt=(alt+1)%N;\n                a[i] = alt;\n            }\n            if(a[i] == i){\n                int alt = (i+2)%N;\n                if(alt==b[i]) alt=(alt+1)%N;\n                if(alt==i) alt=(alt+1)%N;\n                a[i] = alt;\n            }\n        }\n        return a;\n    };\n\n    auto evaluate = [&](const vector<int>& a, const vector<int>& b)->Solution{\n        Solution sol;\n        sol.a = a; sol.b = b;\n        sol.t = simulate_counts(sol.a, sol.b, L);\n        sol.error = compute_error(sol.t, T);\n        return sol;\n    };\n\n    // Multiple initializations with time cap\n    int init_trials = 6;\n    Solution best; best.error = (1LL<<60);\n    vector<int> bestA, bestB, bestT;\n    for(int v=0; v<init_trials; v++){\n        if(tim.elapsed() > 0.6) break;\n        auto a0 = build_candidate_a(v*31 + 7);\n        auto sol = evaluate(a0, b);\n        if(sol.error < best.error){\n            best = sol; bestA = sol.a; bestB = sol.b; bestT = sol.t;\n        }\n    }\n\n    vector<int> a = bestA, t = bestT;\n    long long bestE = best.error;\n\n    // Local search with strict bounds\n    vector<pair<long long,int>> over, under;\n    recompute_lists(t, over, under);\n\n    auto try_redirect = [&](int s, int new_dest)->bool{\n        if(new_dest==b[s] || new_dest==s) return false;\n        if(a[s]==new_dest) return false;\n        int old = a[s];\n        a[s] = new_dest;\n        auto tt = simulate_counts(a,b,L);\n        long long E = compute_error(tt, T);\n        if(E < bestE){\n            bestE = E; t.swap(tt);\n            recompute_lists(t, over, under);\n            return true;\n        }else{\n            a[s] = old;\n            return false;\n        }\n    };\n    auto try_swap = [&](int s1, int s2)->bool{\n        if(s1==s2) return false;\n        int a1=a[s1], a2=a[s2];\n        if(a1==a2) return false;\n        if(a2==b[s1] || a1==b[s2] || a2==s1 || a1==s2) return false;\n        swap(a[s1], a[s2]);\n        auto tt = simulate_counts(a,b,L);\n        long long E = compute_error(tt, T);\n        if(E < bestE){\n            bestE = E; t.swap(tt);\n            recompute_lists(t, over, under);\n            return true;\n        }else{\n            swap(a[s1], a[s2]);\n            return false;\n        }\n    };\n\n    if(!over.empty() && !under.empty()){\n        int redirects_budget = 16;\n        int swaps_budget = 6;\n\n        // Redirects: from top over -> top under\n        for(int oi=0; oi<(int)over.size() && redirects_budget>0; oi++){\n            if(tim.elapsed() > 1.5) break;\n            int dst_over = over[oi].second;\n            // collect sources with a[s]==dst_over\n            vector<int> sources;\n            for(int s=0;s<N;s++) if(a[s]==dst_over) sources.push_back(s);\n            if(sources.empty()) continue;\n            shuffle(sources.begin(), sources.end(), rng);\n            int topu = min(8, (int)under.size());\n            for(int s: sources){\n                for(int ui=0; ui<topu && redirects_budget>0; ui++){\n                    int dst_under = under[ui].second;\n                    if(try_redirect(s, dst_under)){\n                        redirects_budget--;\n                        break;\n                    }\n                }\n                if(redirects_budget<=0 || tim.elapsed()>1.5) break;\n            }\n        }\n        // Swaps\n        recompute_lists(t, over, under);\n        if(!over.empty() && !under.empty()){\n            int topk = min(6, (int)over.size());\n            for(int oi=0; oi<topk && swaps_budget>0; oi++){\n                if(tim.elapsed() > 1.8) break;\n                int dst_over = over[oi].second;\n                vector<int> s_over;\n                for(int s=0;s<N;s++) if(a[s]==dst_over) s_over.push_back(s);\n                if(s_over.empty()) continue;\n                int s1 = s_over[rng()%s_over.size()];\n                int s2 = -1;\n                int topu = min(6, (int)under.size());\n                for(int ui=0; ui<topu && s2==-1; ui++){\n                    int du = under[ui].second;\n                    for(int s=0;s<N;s++){\n                        if(a[s]==du && s!=s1){ s2 = s; break; }\n                    }\n                }\n                if(s2!=-1){\n                    if(try_swap(s1, s2)) swaps_budget--;\n                }\n            }\n        }\n    }\n\n    // Output final plan\n    for(int i=0;i<N;i++){\n        cout<<a[i]<<\" \"<<b[i]<<\"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    DSU(int n=0): n(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){ a=find(a); b=find(b); if(a==b) return false; if(r[a]<r[b]) swap(a,b); p[b]=a; if(r[a]==r[b]) r[a]++; return true; }\n};\n\nstatic inline uint32_t part1by1(uint32_t x){\n    x &= 0x0000ffff;\n    x = (x | (x << 8)) & 0x00FF00FF;\n    x = (x | (x << 4)) & 0x0F0F0F0F;\n    x = (x | (x << 2)) & 0x33333333;\n    x = (x | (x << 1)) & 0x55555555;\n    return x;\n}\nstatic inline uint32_t morton2D(uint32_t x, uint32_t y){\n    return (part1by1(y) << 1) | part1by1(x);\n}\n\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    vector<int> cx(N), cy(N);\n    for(int i=0;i<N;i++){\n        cx[i] = (lx[i]+rx[i])>>1;\n        cy[i] = (ly[i]+ry[i])>>1;\n    }\n    auto codeOf = [&](int i)->uint32_t{\n        uint32_t xs = (uint32_t) min(16383, max(0, cx[i]*16383/10000));\n        uint32_t ys = (uint32_t) min(16383, max(0, cy[i]*16383/10000));\n        return morton2D(xs, ys);\n    };\n    auto centerDist = [&](int a, int b)->int{\n        long dx = cx[a]-cx[b];\n        long dy = cy[a]-cy[b];\n        long long d2 = dx*dx + dy*dy;\n        return (int)floor(sqrt((long double)d2));\n    };\n\n    // initial Morton ordering\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a,int b){\n        uint32_t ca=codeOf(a), cb=codeOf(b);\n        if(ca!=cb) return ca<cb;\n        if(cx[a]!=cx[b]) return cx[a]<cx[b];\n        if(cy[a]!=cy[b]) return cy[a]<cy[b];\n        return a<b;\n    });\n\n    // Build boundary cuts with small local optimization without modifying ord array:\n    vector<int> cuts(M+1, 0);\n    for(int i=1;i<=M;i++) cuts[i] = cuts[i-1] + G[i-1];\n    const int S = 5;\n    for(int b=1;b<M;b++){\n        int base = cuts[b];\n        int bestCut = base;\n        long bestScore = LLONG_MAX;\n        for(int cut = base - S; cut <= base + S; cut++){\n            if(cut <= cuts[b-1]) continue;\n            if(cut >= cuts[b+1]) continue;\n            auto safeDist = [&](int i, int j)->int{\n                if(i<0||j<0||i>=N||j>=N) return 1000000;\n                return centerDist(ord[i], ord[j]);\n            };\n            long sc = 0;\n            sc += safeDist(cut-1, cut);\n            sc += safeDist(cut-2, cut);\n            sc += safeDist(cut-1, cut+1);\n            if(sc < bestScore){ bestScore=sc; bestCut=cut; }\n        }\n        int delta = bestCut - base;\n        // apply this delta to all subsequent cuts\n        for(int t=b; t<=M; t++) cuts[t] += delta;\n    }\n    // Build groups by ord and cuts\n    vector<vector<int>> groups(M);\n    for(int k=0;k<M;k++){\n        int l = cuts[k], r = cuts[k+1];\n        l = max(l, 0); r = min(r, N);\n        if(r<l) r=l;\n        groups[k].assign(ord.begin()+l, ord.begin()+r);\n        // if due to constraints it became wrong size, fix by simple fallback slicing from ord\n        if((int)groups[k].size() != G[k]){\n            groups.clear(); groups.resize(M);\n            int p=0;\n            for(int i=0;i<M;i++){\n                for(int t=0;t<G[i];t++) groups[i].push_back(ord[p++]);\n            }\n            break;\n        }\n    }\n\n    int queries_left = Q;\n\n    auto do_query = [&](const vector<int>& C)->vector<pair<int,int>>{\n        int l = (int)C.size();\n        if(l<2) return {};\n        if(l>L) l=L; // safety cap, but we only call with l<=L\n        cout<<\"? \"<<l;\n        for(int i=0;i<l;i++) cout<<\" \"<<C[i];\n        cout<<\"\\n\"<<flush;\n        vector<pair<int,int>> ret;\n        ret.reserve(max(0,l-1));\n        for(int i=0;i<l-1;i++){\n            int a,b; cin>>a>>b;\n            if(a>b) swap(a,b);\n            ret.emplace_back(a,b);\n        }\n        return ret;\n    };\n\n    struct Edge {int u,v,w;};\n\n    // grid-based candidate edges\n    auto grid_candidates = [&](const vector<int>& vs, int cell)->vector<Edge>{\n        int n = (int)vs.size();\n        if(n<=1) return {};\n        unordered_map<long long, vector<int>> bucket;\n        bucket.reserve(n*2);\n        auto key = [&](int x, int y)->long long{\n            long long gx = x / cell;\n            long long gy = y / cell;\n            return (gx<<20) ^ gy;\n        };\n        for(int u: vs){\n            bucket[key(cx[u], cy[u])].push_back(u);\n        }\n        vector<Edge> edges;\n        edges.reserve(n*8);\n        int dxs[9] = {-1,0,1,-1,0,1,-1,0,1};\n        int dys[9] = {-1,-1,-1,0,0,0,1,1,1};\n        for(int u: vs){\n            long long gx = cx[u] / cell;\n            long long gy = cy[u] / cell;\n            vector<pair<int,int>> cand;\n            cand.reserve(24);\n            for(int d=0; d<9; d++){\n                long long nx = gx + dxs[d];\n                long long ny = gy + dys[d];\n                long long k = (nx<<20) ^ ny;\n                auto it = bucket.find(k);\n                if(it==bucket.end()) continue;\n                for(int v: it->second){\n                    if(v==u) continue;\n                    cand.emplace_back(centerDist(u,v), v);\n                }\n            }\n            int take = min((int)cand.size(), 8);\n            if(take>0){\n                nth_element(cand.begin(), cand.begin()+take, cand.end(),\n                            [](const auto& A, const auto& B){ return A.first < B.first; });\n                for(int i=0;i<take;i++){\n                    int a=u,b=cand[i].second; if(a>b) swap(a,b);\n                    edges.push_back({a,b,cand[i].first});\n                }\n            }\n        }\n        sort(edges.begin(), edges.end(), [](const Edge& A,const Edge& B){\n            if(A.u!=B.u) return A.u<B.u;\n            if(A.v!=B.v) return A.v<B.v;\n            return A.w<B.w;\n        });\n        edges.erase(unique(edges.begin(), edges.end(), [](const Edge& A,const Edge& B){\n            return A.u==B.u && A.v==B.v;\n        }), edges.end());\n        return edges;\n    };\n\n    // approximate MST with rich candidates\n    auto approx_mst = [&](const vector<int>& vs)->vector<pair<int,int>>{\n        int n=(int)vs.size();\n        if(n<=1) return {};\n        vector<Edge> edges;\n        edges.reserve(n*28);\n        // Morton\n        vector<pair<uint32_t,int>> marr(n);\n        for(int i=0;i<n;i++) marr[i]={codeOf(vs[i]), vs[i]};\n        sort(marr.begin(), marr.end());\n        vector<int> mseq(n);\n        for(int i=0;i<n;i++) mseq[i]=marr[i].second;\n        // axis\n        vector<int> xseq = vs, yseq = vs;\n        sort(xseq.begin(), xseq.end(), [&](int a,int b){\n            if(cx[a]!=cx[b]) return cx[a]<cx[b];\n            if(cy[a]!=cy[b]) return cy[a]<cy[b];\n            return a<b;\n        });\n        sort(yseq.begin(), yseq.end(), [&](int a,int b){\n            if(cy[a]!=cy[b]) return cy[a]<cy[b];\n            if(cx[a]!=cx[b]) return cx[a]<cx[b];\n            return a<b;\n        });\n        const int mortonWindow=70, mortonK=14, axisWindow=14, axisK=8;\n        for(int i=0;i<n;i++){\n            int u=mseq[i];\n            vector<pair<int,int>> cand; cand.reserve(2*mortonWindow);\n            for(int d=1; d<=mortonWindow; d++){\n                int j=i-d; if(j>=0){ int v=mseq[j]; cand.emplace_back(centerDist(u,v), v); }\n                j=i+d; if(j<n){ int v=mseq[j]; cand.emplace_back(centerDist(u,v), v); }\n            }\n            int take=min((int)cand.size(), mortonK);\n            if(take>0){\n                nth_element(cand.begin(), cand.begin()+take, cand.end(),\n                            [](const auto& A,const auto& B){ return A.first < B.first; });\n                for(int t=0;t<take;t++){\n                    int v=cand[t].second, w=cand[t].first;\n                    int a=u,b=v; if(a>b) swap(a,b);\n                    edges.push_back({a,b,w});\n                }\n            }\n        }\n        auto add_seq = [&](const vector<int>& seq){\n            for(int i=0;i<(int)seq.size();i++){\n                int u=seq[i];\n                vector<pair<int,int>> cand; cand.reserve(2*axisWindow);\n                for(int d=1; d<=axisWindow; d++){\n                    int j=i-d; if(j>=0){ int v=seq[j]; cand.emplace_back(centerDist(u,v), v); }\n                    j=i+d; if(j<(int)seq.size()){ int v=seq[j]; cand.emplace_back(centerDist(u,v), v); }\n                }\n                int take=min((int)cand.size(), axisK);\n                if(take>0){\n                    nth_element(cand.begin(), cand.begin()+take, cand.end(),\n                                [](const auto& A,const auto& B){ return A.first < B.first; });\n                    for(int t=0;t<take;t++){\n                        int v=cand[t].second, w=cand[t].first;\n                        int a=u,b=v; if(a>b) swap(a,b);\n                        edges.push_back({a,b,w});\n                    }\n                }\n            }\n        };\n        add_seq(xseq);\n        add_seq(yseq);\n        int cell = max(400, min(1200, W));\n        auto gridE = grid_candidates(vs, cell);\n        edges.insert(edges.end(), gridE.begin(), gridE.end());\n\n        sort(edges.begin(), edges.end(), [&](const Edge& A,const Edge& B){\n            if(A.u!=B.u) return A.u<B.u;\n            if(A.v!=B.v) return A.v<B.v;\n            return A.w<B.w;\n        });\n        edges.erase(unique(edges.begin(), edges.end(), [&](const Edge& A,const Edge& B){\n            return A.u==B.u && A.v==B.v;\n        }), edges.end());\n\n        DSU dsu(N);\n        sort(edges.begin(), edges.end(), [&](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        vector<pair<int,int>> res; res.reserve(n-1);\n        for(const auto &e: edges){\n            if(dsu.unite(e.u,e.v)){\n                res.emplace_back(e.u,e.v);\n                if((int)res.size()==n-1) break;\n            }\n        }\n        if((int)res.size()<n-1){\n            for(int i=0;i<n-1;i++){\n                int a=mseq[i], b=mseq[i+1];\n                if(dsu.unite(a,b)){\n                    if(a>b) swap(a,b);\n                    res.emplace_back(a,b);\n                }\n            }\n        }\n        if((int)res.size()>n-1) res.resize(n-1);\n        return res;\n    };\n\n    // Block MST with strict query accounting: will only query if queries_left >= blocks\n    auto block_mst = [&](const vector<int>& vs, int &queries_left_ref)->vector<pair<int,int>>{\n        int n=(int)vs.size();\n        if(n<=1) return {};\n        vector<pair<uint32_t,int>> marr(n);\n        for(int i=0;i<n;i++) marr[i]={codeOf(vs[i]), vs[i]};\n        sort(marr.begin(), marr.end());\n        vector<int> orderLoc(n);\n        for(int i=0;i<n;i++) orderLoc[i]=marr[i].second;\n        vector<vector<int>> blocks;\n        for(int i=0;i<n;i+=L){\n            int r=min(n, i+L);\n            vector<int> blk; blk.reserve(r-i);\n            for(int j=i;j<r;j++) blk.push_back(orderLoc[j]);\n            blocks.push_back(move(blk));\n        }\n        int B=(int)blocks.size();\n        if(B<=queries_left_ref){\n            vector<pair<int,int>> intra;\n            for(int b=0;b<B;b++){\n                if((int)blocks[b].size()<=1) continue;\n                auto e = do_query(blocks[b]);\n                queries_left_ref--; // consume here\n                intra.insert(intra.end(), e.begin(), e.end());\n            }\n            // connect blocks approximately\n            struct Edge{int u,v,w;};\n            vector<Edge> inter;\n            auto add_best_between = [&](const vector<int>& A, const vector<int>& B, int capPairs){\n                vector<int> aCand, bCand;\n                int ca=min(6,(int)A.size()), cb=min(6,(int)B.size());\n                for(int t=0;t<ca;t++){\n                    int idx = (int)llround((double)t*(A.size()-1)/max(1,ca-1));\n                    aCand.push_back(A[idx]);\n                }\n                for(int t=0;t<cb;t++){\n                    int idx = (int)llround((double)t*(B.size()-1)/max(1,cb-1));\n                    bCand.push_back(B[idx]);\n                }\n                vector<Edge> local;\n                for(int a: aCand) for(int b: bCand){\n                    int w=centerDist(a,b);\n                    int u=a,v=b; if(u>v) swap(u,v);\n                    local.push_back({u,v,w});\n                }\n                sort(local.begin(), local.end(), [](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                int take=min((int)local.size(), capPairs);\n                for(int i=0;i<take;i++) inter.push_back(local[i]);\n            };\n            for(int b=0;b<B-1;b++) add_best_between(blocks[b], blocks[b+1], 3);\n            for(int b=0;b<B-2;b++) add_best_between(blocks[b], blocks[b+2], 1);\n\n            vector<tuple<int,int,int>> edges; edges.reserve(intra.size()+inter.size());\n            for(auto &p: intra){\n                int w=centerDist(p.first,p.second);\n                edges.emplace_back(w, min(p.first,p.second), max(p.first,p.second));\n            }\n            for(auto &e: inter){\n                edges.emplace_back(e.w, e.u, e.v);\n            }\n            sort(edges.begin(), edges.end());\n            DSU dsu(N);\n            vector<pair<int,int>> res; res.reserve(n-1);\n            for(auto &t: edges){\n                int u=get<1>(t), v=get<2>(t);\n                if(dsu.unite(u,v)){\n                    res.emplace_back(u,v);\n                    if((int)res.size()==n-1) break;\n                }\n            }\n            if((int)res.size()<n-1){\n                for(int i=0;i<n-1;i++){\n                    int a=orderLoc[i], b=orderLoc[i+1];\n                    if(dsu.unite(a,b)){\n                        if(a>b) swap(a,b);\n                        res.emplace_back(a,b);\n                    }\n                }\n            }\n            if((int)res.size()>n-1) res.resize(n-1);\n            return res;\n        }else{\n            return approx_mst(vs);\n        }\n    };\n\n    // Micro-queries: t subsets of size L; consume queries_left accordingly and return anchors\n    auto micro_queries = [&](const vector<int>& vs, int t, int &queries_left_ref)->vector<pair<int,int>>{\n        vector<pair<int,int>> anchors;\n        int n=(int)vs.size();\n        if(n<=1 || t<=0) return anchors;\n        vector<pair<uint32_t,int>> marr(n);\n        for(int i=0;i<n;i++) marr[i]={codeOf(vs[i]), vs[i]};\n        sort(marr.begin(), marr.end());\n        vector<int> seq(n);\n        for(int i=0;i<n;i++) seq[i]=marr[i].second;\n        t = min(t, queries_left_ref);\n        for(int s=0; s<t; s++){\n            vector<int> subset; subset.reserve(L);\n            long long start = (long long)s * n / t;\n            for(int j=0;j<L;j++){\n                long long idx = (start + (long long)j * n / L) % n;\n                subset.push_back(seq[(int)idx]);\n            }\n            auto e = do_query(subset);\n            queries_left_ref--;\n            anchors.insert(anchors.end(), e.begin(), e.end());\n        }\n        return anchors;\n    };\n\n    // Query planning strictly with per-group counts\n    vector<int> plan(M, 0); // 0=approx, 1=whole, 2=block, 3=approx+micro\n    vector<int> micro_cnt(M, 0);\n\n    // First: whole-group for small\n    for(int k=0;k<M;k++){\n        if((int)groups[k].size()<=L && queries_left>=1){\n            plan[k]=1;\n            queries_left -= 1; // reserve\n        }\n    }\n    // Medium: block if affordable now\n    for(int k=0;k<M;k++){\n        if(plan[k]!=0) continue;\n        int sz = (int)groups[k].size();\n        if(sz>L && sz<=3*L){\n            int need = (sz+L-1)/L;\n            if(queries_left>=need){\n                plan[k]=2;\n                queries_left -= need; // reserve\n            }\n        }\n    }\n    // Distribute remaining queries to large groups as micro anchors, 1 each in round-robin\n    vector<int> largeIdx;\n    for(int k=0;k<M;k++){\n        if(plan[k]==0 && (int)groups[k].size()>3*L) largeIdx.push_back(k);\n    }\n    int ptr=0;\n    while(queries_left>0 && !largeIdx.empty()){\n        int k = largeIdx[ptr];\n        micro_cnt[k] += 1;\n        queries_left -= 1;\n        ptr++; if(ptr>=(int)largeIdx.size()) ptr=0;\n    }\n    // Note: We reserved queries in planning; during construction we will not consume again. To keep accounting consistent,\n    // we introduce a local variable local_queries_left = planned_reserved + remaining actual Q at construction time\n    int local_queries_left = Q;\n\n    // Build edges per group\n    vector<vector<pair<int,int>>> group_edges(M);\n    for(int k=0;k<M;k++){\n        const auto& g = groups[k];\n        int sz = (int)g.size();\n        if(sz<=1){ group_edges[k]={}; continue; }\n        if(plan[k]==1){\n            // whole group query\n            // consume one query from local_queries_left (must be >=1)\n            if(local_queries_left>=1){\n                auto e = do_query(g);\n                local_queries_left -= 1;\n                group_edges[k]=e;\n            }else{\n                group_edges[k]=approx_mst(g);\n            }\n        }else if(plan[k]==2){\n            // block queries\n            group_edges[k] = block_mst(g, local_queries_left);\n        }else if(micro_cnt[k]>0){\n            auto anchors = micro_queries(g, micro_cnt[k], local_queries_left);\n            auto approx = approx_mst(g);\n            struct T {int w,u,v,t;};\n            vector<T> E; E.reserve(anchors.size()+approx.size());\n            for(auto &p: anchors){\n                int w=centerDist(p.first,p.second);\n                E.push_back({w, min(p.first,p.second), max(p.first,p.second), 0});\n            }\n            for(auto &p: approx){\n                int w=centerDist(p.first,p.second);\n                E.push_back({w, min(p.first,p.second), max(p.first,p.second), 1});\n            }\n            sort(E.begin(), E.end(), [](const T& A,const T& B){\n                if(A.w!=B.w) return A.w<B.w;\n                if(A.t!=B.t) return A.t<B.t;\n                if(A.u!=B.u) return A.u<B.u;\n                return A.v<B.v;\n            });\n            DSU dsu(N);\n            vector<pair<int,int>> res; res.reserve(sz-1);\n            for(auto &e: E){\n                if(dsu.unite(e.u,e.v)){\n                    res.emplace_back(e.u,e.v);\n                    if((int)res.size()==sz-1) break;\n                }\n            }\n            if((int)res.size()<sz-1){\n                // fallback simple chain within group order g (which is contiguous in ord)\n                for(int i=0;i<sz-1;i++){\n                    int a=g[i], b=g[i+1];\n                    if(dsu.unite(a,b)){\n                        if(a>b) swap(a,b);\n                        res.emplace_back(a,b);\n                    }\n                }\n            }\n            if((int)res.size()>sz-1) res.resize(sz-1);\n            group_edges[k]=res;\n        }else{\n            group_edges[k]=approx_mst(g);\n        }\n        // safety: enforce endpoints belong to group and count exact sz-1\n        if((int)group_edges[k].size() < sz-1){\n            // fill with chain\n            DSU dsu2(N);\n            for(auto &e: group_edges[k]) dsu2.unite(e.first, e.second);\n            for(int i=0;i<sz-1 && (int)group_edges[k].size()<sz-1;i++){\n                int a=g[i], b=g[i+1];\n                if(dsu2.unite(a,b)){\n                    if(a>b) swap(a,b);\n                    group_edges[k].push_back({a,b});\n                }\n            }\n        }else if((int)group_edges[k].size() > sz-1){\n            group_edges[k].resize(sz-1);\n        }\n    }\n\n    // Final output\n    cout<<\"!\"<<\"\\n\";\n    for(int k=0;k<M;k++){\n        const auto& g = groups[k];\n        for(int i=0;i<(int)g.size();i++){\n            if(i) cout<<\" \";\n            cout<<g[i];\n        }\n        cout<<\"\\n\";\n        for(auto &e: group_edges[k]){\n            cout<<e.first<<\" \"<<e.second<<\"\\n\";\n        }\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\nint N,M;\nvector<Pos> targets;\nvector<string> out_actions;\n\nenum Dir {U=0,D=1,L=2,R=3};\nconst int di[4] = {-1,1,0,0};\nconst int dj[4] = {0,0,-1,1};\nchar dirChar(Dir d){ return d==U?'U':d==D?'D':d==L?'L':'R'; }\n\ninline bool inb(int i,int j,int N){ return 0<=i && i<N && 0<=j && j<N; }\n\nstruct Grid {\n    int N;\n    vector<uint8_t> blk;\n    Grid(int N=0):N(N),blk(N*N,0){}\n    inline bool isBlock(int i,int j) const { return blk[i*N+j]; }\n} grid;\n\nvoid emit_to(vector<string> &outv, char act, Dir d){\n    string s; s+=act; s+=' '; s+=dirChar(d);\n    outv.push_back(s);\n}\n\nbool try_move(Pos &p, Dir d, vector<string> *outv){\n    int ni=p.i+di[d], nj=p.j+dj[d];\n    if(!inb(ni,nj,N)) return false;\n    if(grid.isBlock(ni,nj)) return false;\n    if(outv) emit_to(*outv,'M',d);\n    p.i=ni; p.j=nj;\n    return true;\n}\n\nPos simulate_slide_pos(const Pos &p, Dir d){\n    int i=p.i, j=p.j;\n    while(true){\n        int ni=i+di[d], nj=j+dj[d];\n        if(!inb(ni,nj,N)) break;\n        if(grid.isBlock(ni,nj)) break;\n        i=ni; j=nj;\n    }\n    return {i,j};\n}\nvoid do_slide(Pos &p, Dir d, vector<string> *outv){\n    if(outv) emit_to(*outv,'S',d);\n    p = simulate_slide_pos(p,d);\n}\n\n// Single-slide if already aligned and target on border in that direction\nbool can_land_by_slide_to_target(const Pos &p, const Pos &t, Dir &d_out){\n    if(p.i==t.i){\n        if(t.j==0 && t.j<p.j){ d_out = L; return true; }\n        if(t.j==N-1 && t.j>p.j){ d_out = R; return true; }\n    }\n    if(p.j==t.j){\n        if(t.i==0 && t.i<p.i){ d_out = U; return true; }\n        if(t.i==N-1 && t.i>p.i){ d_out = D; return true; }\n    }\n    return false;\n}\n\n// Move towards t with greedy Manhattan and opportunistic single border slide if available mid-route\nvoid move_with_opportunistic_slide(Pos &p, const Pos &t, vector<string> *outv){\n    while(!(p.i==t.i && p.j==t.j)){\n        // Check for immediate single slide\n        Dir sd;\n        if(can_land_by_slide_to_target(p, t, sd)){\n            do_slide(p, sd, outv);\n            return;\n        }\n        // Greedy step: take the larger axis first\n        Dir d;\n        if(abs(p.i - t.i) >= abs(p.j - t.j)){\n            d = (p.i < t.i) ? D : U;\n        }else{\n            d = (p.j < t.j) ? R : L;\n        }\n        if(!try_move(p,d,outv)){\n            // fallback (shouldn't happen without blocks)\n            bool moved=false;\n            for(int k=0;k<4;k++){\n                if(try_move(p,(Dir)k,outv)){ moved=true; break; }\n            }\n            if(!moved) break;\n        }\n    }\n}\n\n// Simulators\nint simulate_moves_only(const Pos &start, const Pos &t){\n    Pos cur = start;\n    vector<string> tmp;\n    move_with_opportunistic_slide(cur, t, &tmp);\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &tmp);\n    }\n    return (int)tmp.size();\n}\n\nint simulate_single_slide_if_possible(const Pos &start, const Pos &t){\n    Dir d;\n    if(!can_land_by_slide_to_target(start, t, d)) return INT_MAX/4;\n    Pos cur = start;\n    vector<string> tmp;\n    do_slide(cur, d, &tmp);\n    if(!(cur.i==t.i && cur.j==t.j)) return INT_MAX/4;\n    return (int)tmp.size();\n}\n\n// Horizontal-first: align row, then two slides with chosen border sequence\nint simulate_horizontal_two_slides(const Pos &start, const Pos &t, bool leftFirst){\n    Pos cur = start;\n    vector<string> tmp;\n    // Align row (with opportunistic single-slide)\n    while(cur.i != t.i){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n            break;\n        }\n        Dir d = (cur.i < t.i) ? D : U;\n        if(!try_move(cur,d,&tmp)) return INT_MAX/4;\n    }\n    if(cur.i==t.i && !(cur.j==t.j)){\n        if(leftFirst){\n            if(cur.j > 0) do_slide(cur, L, &tmp);\n            if(cur.j <= t.j) do_slide(cur, R, &tmp);\n        }else{\n            if(cur.j < N-1) do_slide(cur, R, &tmp);\n            if(cur.j >= t.j) do_slide(cur, L, &tmp);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &tmp);\n    }\n    return (int)tmp.size();\n}\n\n// Horizontal-first one-slide: align row then single slide if possible, else moves\nint simulate_horizontal_one_slide(const Pos &start, const Pos &t){\n    Pos cur = start;\n    vector<string> tmp;\n    while(cur.i != t.i){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n            break;\n        }\n        Dir d = (cur.i < t.i) ? D : U;\n        if(!try_move(cur,d,&tmp)) return INT_MAX/4;\n    }\n    if(cur.i==t.i && !(cur.j==t.j)){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n        }else{\n            move_with_opportunistic_slide(cur, t, &tmp);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &tmp);\n    }\n    return (int)tmp.size();\n}\n\nint simulate_vertical_two_slides(const Pos &start, const Pos &t, bool upFirst){\n    Pos cur = start;\n    vector<string> tmp;\n    while(cur.j != t.j){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n            break;\n        }\n        Dir d = (cur.j < t.j) ? R : L;\n        if(!try_move(cur,d,&tmp)) return INT_MAX/4;\n    }\n    if(cur.j==t.j && !(cur.i==t.i)){\n        if(upFirst){\n            if(cur.i > 0) do_slide(cur, U, &tmp);\n            if(cur.i <= t.i) do_slide(cur, D, &tmp);\n        }else{\n            if(cur.i < N-1) do_slide(cur, D, &tmp);\n            if(cur.i >= t.i) do_slide(cur, U, &tmp);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &tmp);\n    }\n    return (int)tmp.size();\n}\n\nint simulate_vertical_one_slide(const Pos &start, const Pos &t){\n    Pos cur = start;\n    vector<string> tmp;\n    while(cur.j != t.j){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n            break;\n        }\n        Dir d = (cur.j < t.j) ? R : L;\n        if(!try_move(cur,d,&tmp)) return INT_MAX/4;\n    }\n    if(cur.j==t.j && !(cur.i==t.i)){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n        }else{\n            move_with_opportunistic_slide(cur, t, &tmp);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &tmp);\n    }\n    return (int)tmp.size();\n}\n\n// Executors mirror simulators\nvoid exec_moves_only(Pos &cur, const Pos &t){\n    move_with_opportunistic_slide(cur, t, &out_actions);\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &out_actions);\n    }\n}\nvoid exec_horizontal_two_slides(Pos &cur, const Pos &t, bool leftFirst){\n    while(cur.i != t.i){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &out_actions);\n            break;\n        }\n        Dir d = (cur.i < t.i) ? D : U;\n        try_move(cur,d,&out_actions);\n    }\n    if(cur.i==t.i && !(cur.j==t.j)){\n        if(leftFirst){\n            if(cur.j > 0) do_slide(cur, L, &out_actions);\n            if(cur.j <= t.j) do_slide(cur, R, &out_actions);\n        }else{\n            if(cur.j < N-1) do_slide(cur, R, &out_actions);\n            if(cur.j >= t.j) do_slide(cur, L, &out_actions);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &out_actions);\n    }\n}\nvoid exec_horizontal_one_slide(Pos &cur, const Pos &t){\n    while(cur.i != t.i){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &out_actions);\n            break;\n        }\n        Dir d = (cur.i < t.i) ? D : U;\n        try_move(cur,d,&out_actions);\n    }\n    if(cur.i==t.i && !(cur.j==t.j)){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &out_actions);\n        }else{\n            move_with_opportunistic_slide(cur, t, &out_actions);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &out_actions);\n    }\n}\nvoid exec_vertical_two_slides(Pos &cur, const Pos &t, bool upFirst){\n    while(cur.j != t.j){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &out_actions);\n            break;\n        }\n        Dir d = (cur.j < t.j) ? R : L;\n        try_move(cur,d,&out_actions);\n    }\n    if(cur.j==t.j && !(cur.i==t.i)){\n        if(upFirst){\n            if(cur.i > 0) do_slide(cur, U, &out_actions);\n            if(cur.i <= t.i) do_slide(cur, D, &out_actions);\n        }else{\n            if(cur.i < N-1) do_slide(cur, D, &out_actions);\n            if(cur.i >= t.i) do_slide(cur, U, &out_actions);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &out_actions);\n    }\n}\nvoid exec_vertical_one_slide(Pos &cur, const Pos &t){\n    while(cur.j != t.j){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &out_actions);\n            break;\n        }\n        Dir d = (cur.j < t.j) ? R : L;\n        try_move(cur,d,&out_actions);\n    }\n    if(cur.j==t.j && !(cur.i==t.i)){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &out_actions);\n        }else{\n            move_with_opportunistic_slide(cur, t, &out_actions);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &out_actions);\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if(!(cin>>N>>M)) return 0;\n    targets.resize(M);\n    for(int k=0;k<M;k++) cin>>targets[k].i>>targets[k].j;\n    grid = Grid(N);\n    Pos cur = targets[0];\n\n    for(int k=1;k<M;k++){\n        Pos t = targets[k];\n\n        // Candidate plans and simulation\n        int bestCost = INT_MAX;\n        int bestPlan = 0;\n        // 0 moves, 1 single slide, 2 H-one, 3 H-two-leftFirst, 4 H-two-rightFirst, 5 V-one, 6 V-two-upFirst, 7 V-two-downFirst\n        int c0 = simulate_moves_only(cur, t);\n        bestCost=c0; bestPlan=0;\n\n        int c1 = simulate_single_slide_if_possible(cur, t);\n        if(c1 < bestCost){ bestCost=c1; bestPlan=1; }\n\n        int c2 = simulate_horizontal_one_slide(cur, t);\n        if(c2 < bestCost){ bestCost=c2; bestPlan=2; }\n\n        int c3 = simulate_horizontal_two_slides(cur, t, true);\n        if(c3 < bestCost){ bestCost=c3; bestPlan=3; }\n        int c4 = simulate_horizontal_two_slides(cur, t, false);\n        if(c4 < bestCost){ bestCost=c4; bestPlan=4; }\n\n        int c5 = simulate_vertical_one_slide(cur, t);\n        if(c5 < bestCost){ bestCost=c5; bestPlan=5; }\n\n        int c6 = simulate_vertical_two_slides(cur, t, true);\n        if(c6 < bestCost){ bestCost=c6; bestPlan=6; }\n        int c7 = simulate_vertical_two_slides(cur, t, false);\n        if(c7 < bestCost){ bestCost=c7; bestPlan=7; }\n\n        // Execute\n        switch(bestPlan){\n            case 0: exec_moves_only(cur, t); break;\n            case 1: {\n                Dir d; can_land_by_slide_to_target(cur, t, d);\n                do_slide(cur, d, &out_actions);\n                break;\n            }\n            case 2: exec_horizontal_one_slide(cur, t); break;\n            case 3: exec_horizontal_two_slides(cur, t, true); break;\n            case 4: exec_horizontal_two_slides(cur, t, false); break;\n            case 5: exec_vertical_one_slide(cur, t); break;\n            case 6: exec_vertical_two_slides(cur, t, true); break;\n            case 7: exec_vertical_two_slides(cur, t, false); break;\n            default: exec_moves_only(cur, t); break;\n        }\n    }\n\n    for(auto &s: out_actions) cout<<s<<\"\\n\";\n    return 0;\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int a,b,c,d; // [a,c) x [b,d)\n    long long area;\n    inline int w() const { return c - a; }\n    inline int h() const { return d - b; }\n    inline void recompute_area() { area = 1LL * (c - a) * (d - b); }\n};\n\nstatic inline bool overlap_pos(const Rect& A, const Rect& B){\n    if (A.c <= B.a || B.c <= A.a) return false;\n    if (A.d <= B.b || B.d <= A.b) return false;\n    return true;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n;\n    if(!(cin>>n)) return 0;\n    vector<int> x(n), y(n);\n    vector<long long> r(n);\n    for(int i=0;i<n;i++) cin>>x[i]>>y[i]>>r[i];\n\n    vector<Rect> rect(n);\n\n    // Spatial grid\n    const int G = 64;\n    const int GRID = (10000 + G - 1) / G;\n    vector<vector<int>> buckets(GRID * GRID);\n    auto cell_id = [&](int gx, int gy){ return gy*GRID + gx; };\n    auto gx_from_x = [&](int X){ return min(GRID-1, max(0, X / G)); };\n    auto gy_from_y = [&](int Y){ return min(GRID-1, max(0, Y / G)); };\n\n    auto add_rect = [&](int id){\n        const Rect &R = rect[id];\n        int gx0 = gx_from_x(R.a), gx1 = gx_from_x(max(0, R.c-1));\n        int gy0 = gy_from_y(R.b), gy1 = gy_from_y(max(0, R.d-1));\n        for(int gy=gy0; gy<=gy1; ++gy)\n            for(int gx=gx0; gx<=gx1; ++gx)\n                buckets[cell_id(gx,gy)].push_back(id);\n    };\n    auto remove_rect = [&](int id){\n        const Rect &R = rect[id];\n        int gx0 = gx_from_x(R.a), gx1 = gx_from_x(max(0, R.c-1));\n        int gy0 = gy_from_y(R.b), gy1 = gy_from_y(max(0, R.d-1));\n        for(int gy=gy0; gy<=gy1; ++gy)\n            for(int gx=gx0; gx<=gx1; ++gx){\n                auto &v = buckets[cell_id(gx,gy)];\n                for(size_t k=0;k<v.size();++k){\n                    if(v[k]==id){ v[k]=v.back(); v.pop_back(); break; }\n                }\n            }\n    };\n    auto check_band = [&](const Rect& NR, int x0, int x1, int y0, int y1, int self)->bool{\n        int gx0 = gx_from_x(x0);\n        int gx1 = gx_from_x(max(0,x1-1));\n        int gy0 = gy_from_y(y0);\n        int gy1 = gy_from_y(max(0,y1-1));\n        for (int gy=gy0; gy<=gy1; ++gy)\n            for (int gx=gx0; gx<=gx1; ++gx){\n                const auto &v = buckets[cell_id(gx,gy)];\n                for (int id : v) {\n                    if (id==self) continue;\n                    if (overlap_pos(NR, rect[id])) return false;\n                }\n            }\n        return true;\n    };\n    auto can_expand = [&](int i, int s)->bool{\n        const Rect &R = rect[i];\n        if (s==0) { if (R.a <= 0) return false; Rect NR=R; NR.a=R.a-1; return check_band(NR, NR.a, R.a, R.b, R.d, i); }\n        if (s==1) { if (R.c >= 10000) return false; Rect NR=R; NR.c=R.c+1; return check_band(NR, R.c, NR.c, R.b, R.d, i); }\n        if (s==2) { if (R.b <= 0) return false; Rect NR=R; NR.b=R.b-1; return check_band(NR, R.a, R.c, NR.b, R.b, i); }\n        if (R.d >= 10000) return false; Rect NR=R; NR.d=R.d+1; return check_band(NR, R.a, R.c, R.d, NR.d, i);\n    };\n    auto do_expand = [&](int i, int s){\n        remove_rect(i);\n        if (s==0) rect[i].a--;\n        else if (s==1) rect[i].c++;\n        else if (s==2) rect[i].b--;\n        else rect[i].d++;\n        rect[i].recompute_area();\n        add_rect(i);\n    };\n    auto contains_seed = [&](int i, const Rect& R)->bool{\n        return (R.a <= x[i] && x[i]+1 <= R.c && R.b <= y[i] && y[i]+1 <= R.d);\n    };\n    auto can_shrink = [&](int i, int s)->bool{\n        const Rect &R = rect[i];\n        Rect NR = R;\n        if (s==0) { if (R.c - (R.a+1) <= 0) return false; NR.a++; }\n        else if (s==1) { if ((R.c-1) - R.a <= 0) return false; NR.c--; }\n        else if (s==2) { if (R.d - (R.b+1) <= 0) return false; NR.b++; }\n        else { if ((R.d-1) - R.b <= 0) return false; NR.d--; }\n        if (!contains_seed(i, NR)) return false;\n        return true;\n    };\n    auto do_shrink = [&](int i, int s){\n        remove_rect(i);\n        if (s==0) rect[i].a++;\n        else if (s==1) rect[i].c--;\n        else if (s==2) rect[i].b++;\n        else rect[i].d--;\n        rect[i].recompute_area();\n        add_rect(i);\n    };\n    auto score = [&](long long si, long long ri)->long double{\n        long double mn = min<long double>(ri, si);\n        long double mx = max<long double>(ri, si);\n        long double t = mn / mx;\n        return 1.0L - (1.0L - t)*(1.0L - t);\n    };\n\n    // RNG and timer\n    uint64_t seed = chrono::high_resolution_clock::now().time_since_epoch().count();\n    mt19937_64 rng(seed);\n    auto now = [&](){ return chrono::high_resolution_clock::now(); };\n    auto start_time = now();\n    const double TIME_LIMIT = 4.9;\n    auto elapsed_sec = [&](){ return chrono::duration<double>(now() - start_time).count(); };\n\n    // Initialization: 1x1 seeds\n    for (int i=0;i<n;i++){\n        Rect R = {x[i], y[i], x[i]+1, y[i]+1, 0};\n        R.recompute_area();\n        rect[i]=R;\n        add_rect(i);\n    }\n\n    vector<long double> PI(n);\n    for (int i=0;i<n;i++) PI[i] = score(rect[i].area, r[i]);\n\n    auto max_expand_steps = [&](int i, int s, int maxSteps)->int{\n        const Rect &R = rect[i];\n        int lo = 0, hi = maxSteps;\n        auto feasible = [&](int steps)->bool{\n            if (steps==0) return true;\n            Rect NR = R;\n            if (s==0) { if (R.a - steps < 0) return false; NR.a = R.a - steps; return check_band(NR, R.a - steps, R.a, R.b, R.d, i); }\n            if (s==1) { if (R.c + steps > 10000) return false; NR.c = R.c + steps; return check_band(NR, R.c, R.c + steps, R.b, R.d, i); }\n            if (s==2) { if (R.b - steps < 0) return false; NR.b = R.b - steps; return check_band(NR, R.a, R.c, R.b - steps, R.b, i); }\n            if (R.d + steps > 10000) return false; NR.d = R.d + steps; return check_band(NR, R.a, R.c, R.d, R.d + steps, i);\n        };\n        while (lo < hi) {\n            int mid = (lo + hi + 1) >> 1;\n            if (feasible(mid)) lo = mid; else hi = mid - 1;\n        }\n        return lo;\n    };\n\n    auto probe_potential = [&](int i, int dir, int cap)->int{\n        const Rect &R = rect[i];\n        int cnt = 0;\n        Rect NR = R;\n        for (int t=0; t<cap; ++t) {\n            if (dir==0) { if (NR.a <= 0) break; Rect T=NR; T.a--; if (!check_band(T, T.a, NR.a, NR.b, NR.d, i)) break; NR.a--; }\n            else if (dir==1) { if (NR.c >= 10000) break; Rect T=NR; T.c++; if (!check_band(T, NR.c, T.c, NR.b, NR.d, i)) break; NR.c++; }\n            else if (dir==2) { if (NR.b <= 0) break; Rect T=NR; T.b--; if (!check_band(T, NR.a, NR.c, T.b, NR.b, i)) break; NR.b--; }\n            else { if (NR.d >= 10000) break; Rect T=NR; T.d++; if (!check_band(T, NR.a, NR.c, NR.d, T.d, i)) break; NR.d++; }\n            cnt++;\n        }\n        return cnt;\n    };\n\n    auto aspect_bias = [&](int i, int dir, long long k)->long double{\n        long double target = sqrt((long double)r[i]);\n        long double w = rect[i].w(), h = rect[i].h();\n        if (dir<=1) w += k; else h += k;\n        long double aerr = fabsl(w/h - 1.0L);\n        long double aw = fabsl(w - target);\n        long double ah = fabsl(h - target);\n        return -0.00001L * aerr - 0.000001L * (aw + ah);\n    };\n\n    // Phase A: grow to target\n    while (elapsed_sec() < TIME_LIMIT * 0.70) {\n        vector<pair<long long,int>> ord(n);\n        for (int i=0;i<n;i++){\n            long long deficit = r[i] - rect[i].area;\n            ord[i] = {deficit, i};\n        }\n        sort(ord.begin(), ord.end(), [&](auto &L, auto &R){\n            if (L.first != R.first) return L.first > R.first;\n            return L.second < R.second;\n        });\n        bool any=false;\n        for (int kk=0; kk<n && elapsed_sec() < TIME_LIMIT * 0.70; ++kk){\n            int i = ord[kk].second;\n            if (rect[i].area >= r[i]) continue;\n            int w0 = rect[i].w(), h0 = rect[i].h();\n            array<tuple<long double,int,int>,4> options;\n            int opt_cnt=0;\n            for (int d=0; d<4; ++d){\n                int steps = max_expand_steps(i, d, 96);\n                if (steps <= 0) continue;\n                long long inc_per = (d<=1 ? h0 : w0);\n                long long need = r[i] - rect[i].area;\n                long long k = min<long long>(steps, max(0LL, need) / max(1LL, inc_per));\n                if (k <= 0) k = min<long long>(steps, 1);\n                long long si = rect[i].area;\n                long long newS = si + k * inc_per;\n                if (newS > r[i]) continue;\n                int pot = probe_potential(i, d, 10); // slightly wider probe\n                long double gain = (score(newS, r[i]) - score(si, r[i])) + aspect_bias(i, d, k) + 0.002L * pot;\n                options[opt_cnt++] = make_tuple(gain, d, (int)k);\n            }\n            if (opt_cnt==0) continue;\n            sort(options.begin(), options.begin()+opt_cnt, [&](auto &A, auto &B){ return get<0>(A) > get<0>(B); });\n            int attempts = min(2, opt_cnt);\n            for (int oi=0; oi<attempts; ++oi) {\n                auto [gain, d, k] = options[oi];\n                if (gain <= 1e-18 || k<=0) continue;\n                int executed=0;\n                for (int t=0; t<k; ++t) {\n                    if (!can_expand(i, d)) break;\n                    do_expand(i, d);\n                    executed++;\n                }\n                if (executed>0) { PI[i] = score(rect[i].area, r[i]); any=true; break; }\n            }\n        }\n        if (!any) break;\n    }\n\n    // Isolation-based overshoot (adaptive, conservative)\n    auto isolation_score = [&](int i)->int{\n        int total = 0;\n        total += max_expand_steps(i, 0, 64);\n        total += max_expand_steps(i, 1, 64);\n        total += max_expand_steps(i, 2, 64);\n        total += max_expand_steps(i, 3, 64);\n        return total;\n    };\n    vector<int> iso(n);\n    for (int i=0;i<n;i++) iso[i] = isolation_score(i);\n\n    while (elapsed_sec() < TIME_LIMIT * 0.72) {\n        vector<tuple<int,long long,int>> order2;\n        order2.reserve(n);\n        for (int i=0;i<n;i++) order2.emplace_back(iso[i], r[i]-rect[i].area, i);\n        sort(order2.begin(), order2.end(), [&](auto&A, auto&B){\n            if (get<0>(A)!=get<0>(B)) return get<0>(A)>get<0>(B);\n            if (get<1>(A)!=get<1>(B)) return get<1>(A)>get<1>(B);\n            return get<2>(A)<get<2>(B);\n        });\n        bool any=false;\n        for (auto &tp: order2){\n            if (elapsed_sec() >= TIME_LIMIT * 0.72) break;\n            int i = get<2>(tp);\n            long long si = rect[i].area, ri_ = r[i];\n            double iso_term = min(0.09, 0.00045 * get<0>(tp));\n            double size_term = min(0.03, (double)ri_ / 1e8 * 0.03);\n            double f = 1.0 + min(0.12, 0.02 + iso_term + size_term);\n            long long cap = (long long)floor(ri_ * f + 1e-9);\n            if (si >= cap) continue;\n            int w0 = rect[i].w(), h0 = rect[i].h();\n            array<tuple<long double,int,int>,4> options;\n            int opt_cnt=0;\n            for (int d=0; d<4; ++d){\n                int steps = max_expand_steps(i, d, 48);\n                if (steps<=0) continue;\n                long long inc_per = (d<=1 ? h0 : w0);\n                long long k = min<long long>(steps, (cap - si) / max(1LL, inc_per));\n                if (k<=0) continue;\n                long long newS = si + k * inc_per;\n                int pot = probe_potential(i, d, 6);\n                long double gain = (score(newS, ri_) - score(si, ri_)) + 0.5L*aspect_bias(i, d, k) + 0.001L * pot;\n                options[opt_cnt++] = make_tuple(gain, d, (int)k);\n            }\n            if (opt_cnt==0) continue;\n            sort(options.begin(), options.begin()+opt_cnt, [&](auto &A, auto &B){ return get<0>(A) > get<0>(B); });\n            int attempts = min(2, opt_cnt);\n            for (int oi=0; oi<attempts; ++oi) {\n                auto [gain, d, k] = options[oi];\n                if (gain <= 1e-12 || k<=0) continue;\n                int executed=0;\n                for (int t=0; t<k; ++t){ if (!can_expand(i,d)) break; do_expand(i,d); executed++; }\n                if (executed>0) { PI[i]=score(rect[i].area, r[i]); any=true; break; }\n            }\n        }\n        if (!any) break;\n        for (int i=0;i<n;i++) if ((i&7)==0) iso[i]=isolation_score(i);\n    }\n\n    // Cooperative micro-shrink (focused on freed side)\n    auto try_coop = [&](int a, int side)->bool{\n        if (rect[a].area <= r[a]) return false;\n        if (!can_shrink(a, side)) return false;\n        Rect oldA = rect[a];\n        remove_rect(a);\n        if (side==0) rect[a].a++;\n        else if (side==1) rect[a].c--;\n        else if (side==2) rect[a].b++;\n        else rect[a].d--;\n        rect[a].recompute_area();\n        add_rect(a);\n        long double dSelf = score(rect[a].area, r[a]) - PI[a];\n\n        int x0, x1, y0, y1, dir_for_neighbor=-1;\n        if (side==0){ x0=rect[a].a; x1=rect[a].a+1; y0=rect[a].b; y1=rect[a].d; dir_for_neighbor=1; }\n        else if (side==1){ x0=rect[a].c-1; x1=rect[a].c; y0=rect[a].b; y1=rect[a].d; dir_for_neighbor=0; }\n        else if (side==2){ x0=rect[a].a; x1=rect[a].c; y0=rect[a].b; y1=rect[a].b+1; dir_for_neighbor=3; }\n        else { x0=rect[a].a; x1=rect[a].c; y0=rect[a].d-1; y1=rect[a].d; dir_for_neighbor=2; }\n        int gx0 = gx_from_x(x0), gx1 = gx_from_x(max(0,x1-1));\n        int gy0 = gy_from_y(y0), gy1 = gy_from_y(max(0,y1-1));\n        unordered_set<int> cand; cand.reserve(64);\n        for (int gy=gy0; gy<=gy1; ++gy)\n            for (int gx=gx0; gx<=gx1; ++gx)\n                for (int b : buckets[cell_id(gx,gy)]) if (b!=a) cand.insert(b);\n\n        int bestB=-1, bestK=0; long double bestG=0.0L;\n        for (int b : cand) {\n            if (rect[b].area >= r[b]) continue;\n            int dnb = dir_for_neighbor;\n            int steps = max_expand_steps(b, dnb, 32);\n            if (steps<=0) continue;\n            long long inc_per = (dnb<=1 ? rect[b].h() : rect[b].w());\n            long long need = r[b] - rect[b].area;\n            long long k = min<long long>(steps, need / max(1LL, inc_per));\n            if (k<=0) k = min(steps, 1);\n            long long si = rect[b].area;\n            long long newS = si + k * inc_per;\n            if (newS > r[b]) continue;\n            long double g = score(newS, r[b]) - score(si, r[b]);\n            if (g > bestG + 1e-12) { bestG=g; bestB=b; bestK=(int)k; }\n        }\n\n        long double total_gain = dSelf + bestG;\n        if (bestB != -1 && total_gain > 1e-12) {\n            for (int t=0; t<bestK; ++t) { if (!can_expand(bestB, dir_for_neighbor)) break; do_expand(bestB, dir_for_neighbor); }\n            PI[a] += dSelf;\n            PI[bestB] = score(rect[bestB].area, r[bestB]);\n            return true;\n        } else {\n            remove_rect(a);\n            rect[a] = oldA;\n            rect[a].recompute_area();\n            add_rect(a);\n            return false;\n        }\n    };\n\n    double coop_budget_end = TIME_LIMIT * 0.80;\n    vector<int> order(n); iota(order.begin(), order.end(), 0);\n    int coop_attempts = 0;\n    while (elapsed_sec() < coop_budget_end && coop_attempts < 15000){\n        shuffle(order.begin(), order.end(), rng);\n        bool any=false;\n        for (int i : order){\n            if (elapsed_sec() >= coop_budget_end) break;\n            if (rect[i].area <= r[i]) continue;\n            array<pair<int,int>,4> sides = {{\n                {rect[i].w(), 0}, {rect[i].w(), 1}, {rect[i].h(), 2}, {rect[i].h(), 3}\n            }};\n            sort(sides.begin(), sides.end(), [&](auto &A, auto &B){ return A.first > B.first; });\n            for (auto [__, s] : sides) {\n                coop_attempts++;\n                if (try_coop(i, s)) { any=true; break; }\n                if (elapsed_sec() >= coop_budget_end) break;\n            }\n        }\n        if (!any) break;\n    }\n\n    // Final exact fill: greedy per-rect passes\n    double final_end = TIME_LIMIT * 0.975;\n    bool changed=true;\n    while (changed && elapsed_sec() < final_end) {\n        changed=false;\n        vector<pair<long long,int>> ord2(n);\n        for (int i=0;i<n;i++) ord2[i] = {r[i] - rect[i].area, i};\n        sort(ord2.begin(), ord2.end(), [&](auto& A, auto& B){\n            if (A.first != B.first) return A.first > B.first;\n            return A.second < B.second;\n        });\n        for (auto &pr : ord2) {\n            if (elapsed_sec() >= final_end) break;\n            int i = pr.second;\n            if (rect[i].area >= r[i]) continue;\n            for (int iter=0; iter<8; ++iter) {\n                if (elapsed_sec() >= final_end) break;\n                int best_dir=-1; long double best_gain=0.0L;\n                for (int d=0; d<4; ++d){\n                    if (!can_expand(i,d)) continue;\n                    long long inc = (d<=1 ? rect[i].h() : rect[i].w());\n                    if (rect[i].area + inc > r[i]) continue;\n                    long double gain = score(rect[i].area + inc, r[i]) - score(rect[i].area, r[i]);\n                    if (gain > best_gain + 1e-18) { best_gain=gain; best_dir=d; }\n                }\n                if (best_dir==-1) break;\n                do_expand(i, best_dir);\n                changed=true;\n                if (rect[i].area >= r[i]) break;\n            }\n        }\n    }\n\n    // Band-focused final mopup: exact 1-step hits\n    auto band_mopup = [&](){\n        bool any=false;\n        vector<int> idx(n); iota(idx.begin(), idx.end(), 0);\n        shuffle(idx.begin(), idx.end(), rng);\n        for (int i : idx) {\n            if (rect[i].area >= r[i]) continue;\n            long long si = rect[i].area, ri_ = r[i];\n            for (int d=0; d<4; ++d){\n                if (!can_expand(i,d)) continue;\n                long long inc = (d<=1 ? rect[i].h() : rect[i].w());\n                if (si + inc != ri_) continue;\n                do_expand(i,d);\n                any=true;\n            }\n        }\n        return any;\n    };\n    double band_end = TIME_LIMIT * 0.985;\n    while (elapsed_sec() < band_end) {\n        if (!band_mopup()) break;\n    }\n\n    // Border-aware final expansion: expand toward borders when underfilled and feasible\n    auto border_pass = [&](){\n        bool any=false;\n        for (int i=0;i<n;i++){\n            if (rect[i].area >= r[i]) continue;\n            // Try to expand toward nearest border first if it fits exactly or improves\n            array<pair<int,int>,4> dirs = {{\n                {rect[i].a, 0}, {10000-rect[i].c, 1}, {rect[i].b, 2}, {10000-rect[i].d, 3}\n            }};\n            // sort preferring closer to border\n            sort(dirs.begin(), dirs.end(), [&](auto&A, auto&B){ return A.first < B.first; });\n            for (auto &pr : dirs){\n                int d = pr.second;\n                if (!can_expand(i,d)) continue;\n                long long inc = (d<=1 ? rect[i].h() : rect[i].w());\n                if (rect[i].area + inc > r[i]) continue;\n                do_expand(i,d);\n                any=true;\n                break;\n            }\n        }\n        return any;\n    };\n    double border_end = TIME_LIMIT * 0.99;\n    while (elapsed_sec() < border_end) {\n        if (!border_pass()) break;\n    }\n\n    // Two-step exact hit finisher (orthogonal preference)\n    auto try_two_step_exact = [&](int i)->bool{\n        if (rect[i].area >= r[i]) return false;\n        long long si = rect[i].area, ri_ = r[i];\n        struct Move { int d; long long inc; };\n        Move moves[4]; int mcnt=0;\n        for (int d=0; d<4; ++d) if (can_expand(i,d)) {\n            long long inc = (d<=1 ? rect[i].h() : rect[i].w());\n            if (si + inc <= ri_) moves[mcnt++] = {d, inc};\n        }\n        if (mcnt==0) return false;\n        for (int a=0; a<mcnt; ++a){\n            int d1 = moves[a].d;\n            if (!can_expand(i,d1)) continue;\n            do_expand(i,d1);\n            long long s1 = rect[i].area;\n            // try orthogonal first\n            array<int,4> order = { (d1^2), (d1^3), (d1^1), d1 };\n            bool done=false;\n            for (int idx=0; idx<4; ++idx){\n                int d2 = order[idx];\n                if (!can_expand(i,d2)) continue;\n                long long inc2 = (d2<=1 ? rect[i].h() : rect[i].w());\n                if (s1 + inc2 == ri_) { do_expand(i,d2); done=true; break; }\n            }\n            if (done) return true;\n            int opp = (d1^1);\n            if (can_shrink(i, opp)) do_shrink(i, opp);\n            else {\n                remove_rect(i);\n                rect[i] = {x[i], y[i], x[i]+1, y[i]+1, 0};\n                rect[i].recompute_area();\n                add_rect(i);\n            }\n        }\n        return false;\n    };\n\n    double two_step_end = TIME_LIMIT * 0.995;\n    vector<int> ids(n); iota(ids.begin(), ids.end(), 0);\n    int two_attempts=0;\n    while (elapsed_sec() < two_step_end && two_attempts < 4000){\n        shuffle(ids.begin(), ids.end(), rng);\n        bool any=false;\n        for (int i : ids){\n            if (elapsed_sec() >= two_step_end) break;\n            if (rect[i].area >= r[i]) continue;\n            two_attempts++;\n            if (try_two_step_exact(i)) any=true;\n        }\n        if (!any) break;\n    }\n\n    // Safety: ensure seed containment\n    for (int i=0;i<n;i++){\n        if (!contains_seed(i, rect[i])) {\n            remove_rect(i);\n            rect[i] = {x[i], y[i], x[i]+1, y[i]+1, 0};\n            rect[i].recompute_area();\n            add_rect(i);\n        }\n    }\n\n    // Safety: resolve overlaps by shrinking minimal-harm rectangle/side\n    auto marginal_loss = [&](int i, int side)->long double{\n        if (!can_shrink(i, side)) return 1e18L;\n        long long si = rect[i].area;\n        long long ri_ = r[i];\n        long long dec = (side<=1 ? rect[i].h() : rect[i].w());\n        long long newS = si - dec;\n        long double cur = score(si, ri_);\n        long double nxt = score(max(1LL, newS), ri_);\n        return cur - nxt;\n    };\n\n    auto has_overlap_pair = [&](int &u, int &v)->bool{\n        for (int i=0;i<n;i++){\n            for (int j=i+1;j<n;j++){\n                if (overlap_pos(rect[i], rect[j])) { u=i; v=j; return true; }\n            }\n        }\n        return false;\n    };\n    int u,v;\n    int guard = 200000;\n    while (guard-- > 0 && has_overlap_pair(u,v)) {\n        int t = u, other = v;\n        long long over_u = rect[u].area - r[u];\n        long long over_v = rect[v].area - r[v];\n        if (over_v > over_u) { t = v; other = u; }\n        else if (over_v == over_u) {\n            long double best_u = 1e18L, best_v = 1e18L;\n            for (int s=0;s<4;s++) best_u = min(best_u, marginal_loss(u,s));\n            for (int s=0;s<4;s++) best_v = min(best_v, marginal_loss(v,s));\n            if (best_v + 1e-15 < best_u) { t = v; other = u; }\n        }\n\n        vector<pair<long double,int>> options; options.reserve(4);\n        for (int s=0;s<4;s++){\n            long double loss = marginal_loss(t,s);\n            if (loss >= 1e17L) continue;\n            long double toward = 0;\n            if (s==0 && rect[other].a <= rect[t].a) toward -= 1e-3;\n            if (s==1 && rect[other].c >= rect[t].c) toward -= 1e-3;\n            if (s==2 && rect[other].b <= rect[t].b) toward -= 1e-3;\n            if (s==3 && rect[other].d >= rect[t].d) toward -= 1e-3;\n            options.emplace_back(loss + toward, s);\n        }\n        bool shrunk=false;\n        sort(options.begin(), options.end());\n        for (auto &op : options){\n            int s = op.second;\n            if (can_shrink(t,s)) { do_shrink(t,s); shrunk=true; break; }\n        }\n        if (!shrunk) {\n            remove_rect(t);\n            rect[t] = {x[t], y[t], x[t]+1, y[t]+1, 0};\n            rect[t].recompute_area();\n            add_rect(t);\n        }\n    }\n\n    // Output\n    for (int i=0;i<n;i++){\n        cout << rect[i].a << ' ' << rect[i].b << ' ' << rect[i].c << ' ' << rect[i].d << '\\n';\n    }\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic constexpr int H = 50, W = 50;\nstatic constexpr int di[4] = {-1,1,0,0};\nstatic constexpr int dj[4] = {0,0,-1,1};\nstatic constexpr char dc[4] = {'U','D','L','R'};\n\nstruct Solver {\n    int si, sj;\n    vector<vector<int>> t, p;\n    int M;\n    vector<vector<pair<int,int>>> tiles;\n    vector<vector<char>> preferred;\n    vector<vector<int>> sidx;\n\n    vector<char> visited_tile;\n    vector<vector<char>> visited_cell;\n\n    uint64_t seed;\n    inline uint64_t rng64() {\n        seed ^= seed << 7; seed ^= seed >> 9; seed ^= 0x9e3779b97f4a7c15ull;\n        return seed;\n    }\n    static inline bool inb(int i,int j){ return 0<=i && i<H && 0<=j && j<W; }\n\n    Solver(int si_, int sj_, const vector<vector<int>>& t_, const vector<vector<int>>& p_)\n        : si(si_), sj(sj_), t(t_), p(p_) {\n        M = 0;\n        for (int i=0;i<H;i++) for (int j=0;j<W;j++) M = max(M, t[i][j]+1);\n        tiles.assign(M, {});\n        for (int i=0;i<H;i++) for (int j=0;j<W;j++) tiles[t[i][j]].push_back({i,j});\n\n        preferred.assign(H, vector<char>(W, 0));\n        for (int id=0; id<M; id++){\n            auto &cells = tiles[id];\n            if (cells.empty()) continue;\n            int bestk = 0, bestv = -1;\n            for (int k=0;k<(int)cells.size();k++){\n                auto [i,j] = cells[k];\n                if (p[i][j] > bestv) { bestv = p[i][j]; bestk = k; }\n            }\n            for (int k=0;k<(int)cells.size();k++){\n                auto [i,j] = cells[k];\n                preferred[i][j] = (k==bestk);\n            }\n        }\n\n        sidx.assign(H, vector<int>(W, -1));\n        int idx=0;\n        for (int i=0;i<H;i++){\n            if (i%2==0){\n                for (int j=0;j<W;j++) sidx[i][j]=idx++;\n            }else{\n                for (int j=W-1;j>=0;j--) sidx[i][j]=idx++;\n            }\n        }\n    }\n\n    vector<pair<int,int>> build_rail_targets() {\n        vector<pair<int,int>> order;\n        order.reserve(H*W);\n        for (int i=0;i<H;i++){\n            if (i%2==0) for (int j=0;j<W;j++) order.push_back({i,j});\n            else for (int j=W-1;j>=0;j--) order.push_back({i,j});\n        }\n        vector<pair<int,int>> targets;\n        targets.reserve(H*W);\n        vector<char> seenTile(M, 0);\n        for (auto [i,j]: order){\n            int id = t[i][j];\n            if (seenTile[id]) continue;\n            pair<int,int> rep = {i,j};\n            if (!preferred[i][j]) {\n                for (auto &c: tiles[id]) if (preferred[c.first][c.second]) { rep=c; break; }\n            }\n            seenTile[id]=1;\n            targets.push_back(rep);\n        }\n        return targets;\n    }\n\n    pair<vector<char>, bool> bfs_path(pair<int,int> start, pair<int,int> target) {\n        if (start == target) return {{}, true};\n        static char vis[H][W];\n        static int preDir[H][W];\n        static pair<int,int> prevCell[H][W];\n        memset(vis, 0, sizeof(vis));\n        deque<pair<int,int>> dq;\n        dq.emplace_back(start);\n        vis[start.first][start.second]=1;\n        bool found=false;\n        while(!dq.empty()){\n            auto [i,j]=dq.front(); dq.pop_front();\n            for (int k=0;k<4;k++){\n                int ni=i+di[k], nj=j+dj[k];\n                if (!inb(ni,nj)) continue;\n                int tid = t[ni][nj];\n                if (visited_tile[tid]) continue;\n                if (vis[ni][nj]) continue;\n                vis[ni][nj]=1;\n                preDir[ni][nj]=k;\n                prevCell[ni][nj]={i,j};\n                if (ni==target.first && nj==target.second){ found=true; dq.clear(); break; }\n                dq.emplace_back(ni,nj);\n            }\n        }\n        if (!found) return {{}, false};\n        vector<char> rev;\n        int ci=target.first, cj=target.second;\n        while(!(ci==start.first && cj==start.second)){\n            int k = preDir[ci][cj];\n            rev.push_back(dc[k]);\n            auto pr = prevCell[ci][cj];\n            ci=pr.first; cj=pr.second;\n        }\n        reverse(rev.begin(), rev.end());\n        return {rev, true};\n    }\n\n    int local_region_after(int i,int j, int rad=3){\n        int tid0 = t[i][j];\n        int rmin=max(0,i-rad), rmax=min(H-1,i+rad);\n        int cmin=max(0,j-rad), cmax=min(W-1,j+rad);\n        static char vis[H][W];\n        memset(vis, 0, sizeof(vis));\n        deque<pair<int,int>> dq;\n        vector<char> seen(M, 0);\n        int cnt=0;\n        for (int k=0;k<4;k++){\n            int ni=i+di[k], nj=j+dj[k];\n            if (!inb(ni,nj)) continue;\n            if (ni<rmin||ni>rmax||nj<cmin||nj>cmax) continue;\n            int tid=t[ni][nj];\n            if (tid==tid0) continue;\n            if (visited_tile[tid]) continue;\n            if (vis[ni][nj]) continue;\n            vis[ni][nj]=1; dq.emplace_back(ni,nj);\n        }\n        while(!dq.empty()){\n            auto [x,y]=dq.front(); dq.pop_front();\n            int tid=t[x][y];\n            if (!seen[tid]){ seen[tid]=1; cnt++; }\n            for (int k=0;k<4;k++){\n                int nx=x+di[k], ny=y+dj[k];\n                if (!inb(nx,ny)) continue;\n                if (nx<rmin||nx>rmax||ny<cmin||ny>cmax) continue;\n                int tnx=t[nx][ny];\n                if (tnx==tid0) continue;\n                if (visited_tile[tnx]) continue;\n                if (!vis[nx][ny]){ vis[nx][ny]=1; dq.emplace_back(nx,ny); }\n            }\n        }\n        return cnt;\n    }\n\n    int local_deg(int i,int j){\n        int d=0;\n        for (int k=0;k<4;k++){\n            int ni=i+di[k], nj=j+dj[k];\n            if (!inb(ni,nj)) continue;\n            if (!visited_tile[t[ni][nj]]) d++;\n        }\n        return d;\n    }\n\n    inline bool can_step_to(int ni, int nj) const {\n        if (!inb(ni,nj)) return false;\n        int tidn = t[ni][nj];\n        if (visited_tile[tidn]) return false;\n        return true;\n    }\n    inline bool apply_move_dir(int &ci, int &cj, int dir, string &ans, long long &score) {\n        int ni = ci + di[dir], nj = cj + dj[dir];\n        if (!can_step_to(ni, nj)) return false;\n        ci = ni; cj = nj;\n        ans.push_back(dc[dir]);\n        visited_tile[t[ci][cj]] = 1;\n        visited_cell[ci][cj] = 1;\n        score += p[ci][cj];\n        return true;\n    }\n    inline bool apply_move_char(int &ci, int &cj, char mv, string &ans, long long &score) {\n        int dir = -1; for (int k=0;k<4;k++) if (dc[k]==mv) { dir = k; break; }\n        if (dir == -1) return false;\n        return apply_move_dir(ci, cj, dir, ans, score);\n    }\n\n    // Choose next anchor among a window by distance - density bonus; expand window optionally\n    int choose_anchor(int ci, int cj, const vector<pair<int,int>>& targets, int ti, int windowL, int &bestDist, vector<char>& bestMoves, bool expand) {\n        int chosen = -1;\n        bestDist = INT_MAX;\n        bestMoves.clear();\n        int L = min((int)targets.size(), ti + (expand ? windowL + 6 : windowL));\n        int bestScore = INT_MAX;\n        for (int tj=ti; tj<L; tj++){\n            if (visited_tile[t[targets[tj].first][targets[tj].second]]) continue;\n            auto [moves, ok] = bfs_path({ci,cj}, targets[tj]);\n            if (!ok) continue;\n            int dist = (int)moves.size();\n            int density = 0;\n            for (int k=0;k<4;k++){\n                int ni=targets[tj].first + di[k], nj=targets[tj].second + dj[k];\n                if (!inb(ni,nj)) continue;\n                if (!visited_tile[t[ni][nj]]) density++;\n            }\n            int sc = dist - density;\n            if (sc < bestScore || (sc == bestScore && dist < bestDist)) {\n                bestScore = sc;\n                chosen = tj;\n                bestMoves = moves;\n                bestDist = dist;\n                if (bestDist <= 3) break;\n            }\n        }\n        return chosen;\n    }\n\n    // Try detour safely, only current target\n    int try_detour(pair<int,int> cur, pair<int,int> target, int topK, int detThreshold, int regMin, int degMin, int stepsDone, bool allowHighPLowDegOnce) {\n        int i=cur.first, j=cur.second;\n        struct Cand { int k, ni, nj, val, deg; bool pref; };\n        vector<Cand> neigh;\n        for (int k=0;k<4;k++){\n            int ni=i+di[k], nj=j+dj[k];\n            if (!inb(ni,nj)) continue;\n            int tid=t[ni][nj];\n            if (visited_tile[tid]) continue;\n            int val=p[ni][nj];\n            int deg=local_deg(ni,nj);\n            neigh.push_back({k,ni,nj,val,deg,(bool)preferred[ni][nj]});\n        }\n        if (neigh.empty()) return -1;\n        sort(neigh.begin(), neigh.end(), [&](const Cand& a, const Cand& b){\n            if (a.val!=b.val) return a.val>b.val;\n            if (a.pref!=b.pref) return a.pref>b.pref;\n            return a.deg>b.deg;\n        });\n        int trials=min(topK,(int)neigh.size());\n        for (int idx=0; idx<trials; idx++){\n            auto c = neigh[idx];\n            if (c.val < detThreshold) continue;\n            bool allowLow = (allowHighPLowDegOnce && stepsDone > 200 && c.val >= 97);\n            if (!allowLow) {\n                if (c.deg < degMin) continue;\n                if (local_region_after(c.ni, c.nj, 3) < regMin) continue;\n            } else {\n                if (local_region_after(c.ni, c.nj, 3) < max(2, regMin-1)) continue;\n            }\n            int tidn=t[c.ni][c.nj];\n            visited_tile[tidn]=1;\n            auto [mv, ok]=bfs_path({c.ni,c.nj}, target);\n            visited_tile[tidn]=0;\n            if (ok) return c.k;\n        }\n        return -1;\n    }\n\n    // If next rail step is unsafe (deg <= 1), try a safer neighbor that still keeps target reachable.\n    bool rail_safe_step_or_alternative(int &ci, int &cj, const pair<int,int>& target, char railMv, string &ans, long long &score) {\n        int dir = -1; for (int k=0;k<4;k++) if (dc[k]==railMv) {dir=k; break;}\n        int ni = ci + di[dir], nj = cj + dj[dir];\n        auto deg = [&](int x,int y){ int d=0; for(int k=0;k<4;k++){int xi=x+di[k], xj=y+dj[k]; if(inb(xi,xj) && !visited_tile[t[xi][xj]]) d++;} return d; };\n        if (can_step_to(ni,nj)) {\n            int dnext = deg(ni,nj);\n            if (dnext > 1) {\n                return apply_move_char(ci, cj, railMv, ans, score);\n            }\n            // search alternative\n            struct Cand{int k, x, y, d;};\n            vector<Cand> alts;\n            for (int k=0;k<4;k++){\n                int xi=ci+di[k], xj=cj+dj[k];\n                if (!can_step_to(xi,xj)) continue;\n                alts.push_back({k,xi,xj,deg(xi,xj)});\n            }\n            sort(alts.begin(), alts.end(), [&](const Cand& a, const Cand& b){\n                if (a.d != b.d) return a.d > b.d;\n                return (p[a.x][a.y] > p[b.x][b.y]);\n            });\n            for (auto &c: alts){\n                // ensure target remains reachable\n                int tidn = t[c.x][c.y];\n                visited_tile[tidn]=1;\n                auto [mv, ok] = bfs_path({c.x,c.y}, target);\n                visited_tile[tidn]=0;\n                if (ok && c.d >= dnext) {\n                    return apply_move_dir(ci, cj, c.k, ans, score);\n                }\n            }\n            // fallback to rail step\n            return apply_move_char(ci, cj, railMv, ans, score);\n        } else {\n            return false;\n        }\n    }\n\n    // Greedy finish with escape and small center bias; two runs and pick best\n    string greedy_finish_dual(int &ci, int &cj, long long &score) {\n        string bestAns;\n        long long bestGain = -1;\n        auto run_once = [&](int WP, int Wdeg, int Wlk, int Wpref, int escapeDeg)->pair<long long,string>{\n            string ans;\n            long long gain = 0;\n            auto deg_here = [&](int i,int j){ int d=0; for(int k=0;k<4;k++){int ni=i+di[k],nj=j+dj[k]; if(inb(ni,nj)&&!visited_tile[t[ni][nj]]) d++;} return d; };\n            vector<char> vt = visited_tile;\n            vector<vector<char>> vc = visited_cell;\n            int x=ci, y=cj;\n            // escape if too tight\n            if (deg_here(x,y) < escapeDeg) {\n                static char vis[H][W];\n                static int preDir[H][W];\n                static pair<int,int> prevCell[H][W];\n                memset(vis, 0, sizeof(vis));\n                deque<pair<int,int>> dq;\n                dq.emplace_back(x,y);\n                vis[x][y]=1;\n                pair<int,int> target = {-1,-1};\n                while(!dq.empty()){\n                    auto [i,j]=dq.front(); dq.pop_front();\n                    if (deg_here(i,j) >= escapeDeg) { target={i,j}; break; }\n                    for (int k=0;k<4;k++){\n                        int ni=i+di[k], nj=j+dj[k];\n                        if (!inb(ni,nj)) continue;\n                        int tidn=t[ni][nj];\n                        if (vt[tidn]) continue;\n                        if (vis[ni][nj]) continue;\n                        vis[ni][nj]=1; preDir[ni][nj]=k; prevCell[ni][nj]={i,j};\n                        dq.emplace_back(ni,nj);\n                    }\n                }\n                if (target.first!=-1){\n                    vector<char> rev;\n                    int a=target.first, b=target.second;\n                    while(!(a==x && b==y)){\n                        int k=preDir[a][b];\n                        rev.push_back(dc[k]);\n                        auto pr=prevCell[a][b]; a=pr.first; b=pr.second;\n                    }\n                    reverse(rev.begin(), rev.end());\n                    for (char mv: rev){\n                        int dir=-1; for (int k=0;k<4;k++) if (dc[k]==mv) {dir=k; break;}\n                        int nx=x+di[dir], ny=y+dj[dir];\n                        if (!inb(nx,ny) || vt[t[nx][ny]]) break;\n                        x=nx; y=ny; vt[t[x][y]]=1; vc[x][y]=1; ans.push_back(mv); gain += p[x][y];\n                    }\n                }\n            }\n            // greedy walk with center bias\n            auto centerDist = [&](int i,int j){ return abs(i-25)+abs(j-25); };\n            for (int step=0; step<H*W; step++){\n                struct C { int k, ni, nj, pv, deg, lkdeg, cdist; long long sc; bool pref; };\n                vector<C> cands;\n                for (int k=0;k<4;k++){\n                    int ni=x+di[k], nj=y+dj[k];\n                    if (!inb(ni,nj)) continue;\n                    int tidn=t[ni][nj];\n                    if (vt[tidn]) continue;\n                    int pv=p[ni][nj];\n                    int deg=0;\n                    for(int d=0; d<4; d++){int xi=ni+di[d], xj=nj+dj[d]; if(inb(xi,xj) && !vt[t[xi][xj]]) deg++;}\n                    vt[tidn]=1;\n                    int bestd2=-1;\n                    for (int k2=0;k2<4;k2++){\n                        int xi=ni+di[k2], xj=nj+dj[k2];\n                        if (!inb(xi,xj)) continue;\n                        int tid2=t[xi][xj];\n                        if (vt[tid2]) continue;\n                        int d2=0;\n                        for (int k3=0;k3<4;k3++){\n                            int yi=xi+di[k3], yj=xj+dj[k3];\n                            if (!inb(yi,yj)) continue;\n                            int tid3=t[yi][yj];\n                            if (tid3==tidn) continue;\n                            if (vt[tid3]) continue;\n                            d2++;\n                        }\n                        bestd2=max(bestd2,d2);\n                    }\n                    vt[tidn]=0;\n                    int cdist = centerDist(ni,nj);\n                    long long sc = 1LL*WP*pv + 1LL*Wdeg*deg + 1LL*Wlk*max(bestd2,0) + (preferred[ni][nj]?Wpref:0) - cdist; // small bias\n                    sc += (rng64() & 3);\n                    cands.push_back({k,ni,nj,pv,deg,bestd2,cdist,sc,(bool)preferred[ni][nj]});\n                }\n                if (cands.empty()) break;\n                sort(cands.begin(), cands.end(), [&](const C&a,const C&b){\n                    if (a.sc!=b.sc) return a.sc>b.sc;\n                    if (a.deg!=b.deg) return a.deg>b.deg;\n                    if (a.pv!=b.pv) return a.pv>b.pv;\n                    return a.cdist < b.cdist;\n                });\n                auto best=cands[0];\n                int nx = x + di[best.k], ny = y + dj[best.k];\n                if (!inb(nx,ny) || vt[t[nx][ny]]) break;\n                x=nx; y=ny; vt[t[x][y]]=1; vc[x][y]=1; ans.push_back(dc[best.k]); gain += p[x][y];\n            }\n            return {gain, ans};\n        };\n\n        auto [gain1, a1] = run_once(88, 11, 12, 6, 3);\n        auto [gain2, a2] = run_once(80, 14, 16, 4, 2);\n        if (gain2 > gain1) {\n            for (char mv: a2) {\n                int dir=-1; for (int k=0;k<4;k++) if (dc[k]==mv) {dir=k; break;}\n                int ni=ci+di[dir], nj=cj+dj[dir];\n                if (!inb(ni,nj) || visited_tile[t[ni][nj]]) break;\n                ci=ni; cj=nj; visited_tile[t[ci][cj]]=1; visited_cell[ci][cj]=1; score += p[ci][cj];\n            }\n            return a2;\n        } else {\n            for (char mv: a1) {\n                int dir=-1; for (int k=0;k<4;k++) if (dc[k]==mv) {dir=k; break;}\n                int ni=ci+di[dir], nj=cj+dj[dir];\n                if (!inb(ni,nj) || visited_tile[t[ni][nj]]) break;\n                ci=ni; cj=nj; visited_tile[t[ci][cj]]=1; visited_cell[ci][cj]=1; score += p[ci][cj];\n            }\n            return a1;\n        }\n    }\n\n    struct Preset {\n        int detourTopK;\n        int detourThresholdStart;\n        int detourThresholdEnd;\n        int regMinStart, regMinEnd;\n        int degMinStart, degMinEnd;\n        int targetSearchWindow;\n        int maxRailStepDist;\n        bool allowHighPLowDegOnce;\n    };\n\n    pair<long long, string> run(const Preset& pr, uint64_t seed0, double time_limit_ms = 1.85e3) {\n        seed = seed0;\n        visited_tile.assign(M, 0);\n        visited_cell.assign(H, vector<char>(W, 0));\n        int ci=si, cj=sj;\n        visited_tile[t[ci][cj]]=1;\n        visited_cell[ci][cj]=1;\n        long long score = p[ci][cj];\n        string ans;\n\n        auto targets = build_rail_targets();\n        int ti = 0;\n        if (!targets.empty() && targets[0] == make_pair(si, sj)) ti = 1;\n\n        auto tstart = chrono::high_resolution_clock::now();\n\n        int stepsDone = 0;\n        bool usedHighPLowDeg = false;\n\n        while (ti < (int)targets.size()) {\n            if (stepsDone % 200 == 0) {\n                auto now = chrono::high_resolution_clock::now();\n                double ms = chrono::duration<double, std::milli>(now - tstart).count();\n                if (ms > time_limit_ms) break;\n            }\n\n            if (visited_tile[t[targets[ti].first][targets[ti].second]]) { ti++; continue; }\n\n            int bestDist = 0;\n            vector<char> railMoves;\n            int chosen = choose_anchor(ci, cj, targets, ti, pr.targetSearchWindow, bestDist, railMoves, bestDist > pr.maxRailStepDist/2);\n            if (chosen == -1) break;\n            if (chosen != ti) ti = chosen;\n\n            if (bestDist > pr.maxRailStepDist) { ti++; continue; }\n\n            size_t pos = 0;\n            while (pos < railMoves.size()) {\n                // If next rail step is safe and target is nearby, suppress detours to keep momentum\n                bool allowDetour = true;\n                if (pos < railMoves.size()) {\n                    int dir = -1; for (int k=0;k<4;k++) if (dc[k]==railMoves[pos]) { dir=k; break; }\n                    int nni = ci + di[dir], nnj = cj + dj[dir];\n                    if (can_step_to(nni, nnj)) {\n                        int dnext = local_deg(nni, nnj);\n                        if (dnext >= 2 && (int)railMoves.size() - (int)pos <= 5) allowDetour = false;\n                    }\n                }\n\n                if (allowDetour) {\n                    int detThreshold = pr.detourThresholdStart + (pr.detourThresholdEnd - pr.detourThresholdStart) * stepsDone / (H*W);\n                    int regMin = pr.regMinStart + (pr.regMinEnd - pr.regMinStart) * stepsDone / (H*W);\n                    int degMin = pr.degMinStart + (pr.degMinEnd - pr.degMinStart) * stepsDone / (H*W);\n                    int dd = try_detour({ci,cj}, targets[ti], pr.detourTopK, detThreshold, regMin, degMin, stepsDone,\n                                        pr.allowHighPLowDegOnce && !usedHighPLowDeg);\n                    if (dd != -1) {\n                        if (!apply_move_dir(ci, cj, dd, ans, score)) break;\n                        stepsDone++;\n                        if (pr.allowHighPLowDegOnce && !usedHighPLowDeg && p[ci][cj] >= 97) usedHighPLowDeg = true;\n                        auto [moves2, ok] = bfs_path({ci,cj}, targets[ti]);\n                        if (!ok) break;\n                        railMoves = moves2;\n                        pos = 0;\n                        continue;\n                    }\n                }\n\n                char mv = railMoves[pos++];\n                if (!rail_safe_step_or_alternative(ci, cj, targets[ti], mv, ans, score)) {\n                    auto [moves2, ok] = bfs_path({ci,cj}, targets[ti]);\n                    if (!ok) break;\n                    railMoves = moves2;\n                    pos = 0;\n                    continue;\n                }\n                stepsDone++;\n            }\n            ti++;\n        }\n\n        string tail = greedy_finish_dual(ci, cj, score);\n        ans += tail;\n\n        return {score, ans};\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj;\n    if (!(cin>>si>>sj)) return 0;\n    vector<vector<int>> t(H, vector<int>(W));\n    vector<vector<int>> p(H, vector<int>(W));\n    for (int i=0;i<H;i++) for (int j=0;j<W;j++) cin>>t[i][j];\n    for (int i=0;i<H;i++) for (int j=0;j<W;j++) cin>>p[i][j];\n\n    Solver solver(si, sj, t, p);\n    uint64_t seedBase = 1469598103934665603ull ^ (uint64_t)(si*131 + sj*911);\n\n    vector<Solver::Preset> presets = {\n        // detK, thrStart, thrEnd, regStart, regEnd, degStart, degEnd, window, maxDist, allowHighPLowDegOnce\n        {2, 86, 72, 4, 2, 2, 1, 10, 120, true},\n        {1, 92, 80, 5, 3, 3, 2, 12, 100, false},\n        {2, 78, 68, 4, 2, 2, 1, 8, 140, true},\n        {1, 95, 85, 6, 4, 3, 2, 14, 90,  false},\n    };\n\n    long long bestScore = -1;\n    string bestAns;\n    for (int r=0; r<(int)presets.size(); r++){\n        auto [sc, ans] = solver.run(presets[r], seedBase ^ (0x9e3779b97f4a7c15ull * (r+1)));\n        if (sc > bestScore) { bestScore = sc; bestAns = move(ans); }\n    }\n\n    cout << bestAns << \"\\n\";\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct GridRouter {\n    static constexpr int HN = 30;\n    static constexpr int WN = 30;\n    static constexpr int HHE = HN * (WN - 1); // 870 horizontal edges\n    static constexpr int HVE = (HN - 1) * WN; // 870 vertical edges\n    static constexpr int E = HHE + HVE;       // 1740 total edges\n\n    vector<double> w; // per-edge base weights\n    vector<pair<int,int>> adjIdx[HN][WN]; // (neighbor node index, edge id)\n    mt19937_64 rng;\n\n    // Global orientation scales\n    double gH = 1.0, gV = 1.0;\n    // Per-row/per-column micro-calibration\n    array<double, HN> rowScale;\n    array<double, WN> colScale;\n    // Optional light decay counters for micro scales\n    array<int, HN> rowTouch;\n    array<int, WN> colTouch;\n\n    // Edge usage counts to prefer underused corridors in near ties\n    vector<int> usedCount;\n\n    GridRouter() : w(E, 5000.0), usedCount(E, 0) {\n        rng.seed(std::chrono::high_resolution_clock::now().time_since_epoch().count());\n        rowScale.fill(1.0);\n        colScale.fill(1.0);\n        rowTouch.fill(0);\n        colTouch.fill(0);\n        buildGraph();\n    }\n\n    static int idH(int i, int j) { return i * (WN - 1) + j; }\n    static int idV(int i, int j) { return HHE + i * WN + j; }\n    int nodeId(int i, int j) const { return i * WN + j; }\n    pair<int,int> nodePos(int id) const { return {id / WN, id % WN}; }\n\n    void buildGraph() {\n        for (int i = 0; i < HN; ++i) for (int j = 0; j < WN; ++j) adjIdx[i][j].clear();\n        for (int i = 0; i < HN; ++i) {\n            for (int j = 0; j < WN - 1; ++j) {\n                int e = idH(i,j);\n                int u = nodeId(i,j), v = nodeId(i,j+1);\n                adjIdx[i][j].push_back({v, e});\n                adjIdx[i][j+1].push_back({u, e});\n            }\n        }\n        for (int i = 0; i < HN - 1; ++i) {\n            for (int j = 0; j < WN; ++j) {\n                int e = idV(i,j);\n                int u = nodeId(i,j), v = nodeId(i+1,j);\n                adjIdx[i][j].push_back({v, e});\n                adjIdx[i+1][j].push_back({u, e});\n            }\n        }\n    }\n\n    inline double effWeight(int e) const {\n        if (e < HHE) {\n            int i = e / (WN - 1);\n            return w[e] * gH * rowScale[i];\n        } else {\n            int ve = e - HHE;\n            int j = ve % WN;\n            return w[e] * gV * colScale[j];\n        }\n    }\n\n    struct DRes {\n        vector<int> prevNode;\n        vector<int> prevEdge;\n        vector<int> pathEdges;\n        string pathMoves;\n        double pathCost;\n    };\n\n    // Dijkstra with optional per-edge randomization and tiny orientation bias\n    DRes shortestPath(pair<int,int> s, pair<int,int> t, double randEps, uint64_t randSeed, double biasH = 1.0, double biasV = 1.0) {\n        int N = HN * WN;\n        vector<double> dist(N, numeric_limits<double>::infinity());\n        vector<int> prevN(N, -1), prevE(N, -1);\n        int sId = nodeId(s.first, s.second);\n        int tId = nodeId(t.first, t.second);\n\n        vector<float> mult;\n        if (randEps > 0) {\n            mult.assign(E, 1.0f);\n            uint64_t x = randSeed ? randSeed : rng();\n            auto nextRand = [&]() {\n                x ^= x << 13; x ^= x >> 7; x ^= x << 17;\n                return x;\n            };\n            for (int e = 0; e < E; ++e) {\n                uint64_t r = nextRand();\n                double u = ((r >> 11) & 0xFFFFFFFFull) / double(0xFFFFFFFFull);\n                double z = 2.0*u - 1.0;\n                mult[e] = float(1.0 + randEps * z);\n            }\n        }\n\n        using P = pair<double,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        dist[sId] = 0.0;\n        pq.emplace(0.0, sId);\n\n        while (!pq.empty()) {\n            auto [d,u] = pq.top(); pq.pop();\n            if (d != dist[u]) continue;\n            if (u == tId) break;\n            auto [ui, uj] = nodePos(u);\n            for (auto [v, e] : adjIdx[ui][uj]) {\n                double ew;\n                if (e < HHE) {\n                    int i = e / (WN - 1);\n                    ew = w[e] * gH * rowScale[i];\n                    if (!mult.empty()) ew *= mult[e];\n                    ew *= biasH;\n                } else {\n                    int ve = e - HHE;\n                    int j = ve % WN;\n                    ew = w[e] * gV * colScale[j];\n                    if (!mult.empty()) ew *= mult[e];\n                    ew *= biasV;\n                }\n                ew = max(100.0, min(20000.0, ew));\n                double nd = d + ew;\n                if (nd < dist[v]) {\n                    dist[v] = nd;\n                    prevN[v] = u;\n                    prevE[v] = e;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n\n        DRes res;\n        res.prevNode = move(prevN);\n        res.prevEdge = move(prevE);\n        res.pathCost = dist[tId];\n\n        vector<int> edges;\n        string moves;\n        int cur = tId;\n        while (cur != sId && res.prevEdge[cur] != -1) {\n            int e = res.prevEdge[cur];\n            edges.push_back(e);\n            auto [pi, pj] = nodePos(res.prevNode[cur]);\n            auto [ci, cj] = nodePos(cur);\n            if (ci == pi) moves.push_back(cj == pj + 1 ? 'R' : 'L');\n            else moves.push_back(ci == pi + 1 ? 'D' : 'U');\n            cur = res.prevNode[cur];\n        }\n        reverse(edges.begin(), edges.end());\n        reverse(moves.begin(), moves.end());\n        res.pathEdges = move(edges);\n        res.pathMoves = move(moves);\n        return res;\n    }\n\n    double predictSum(const vector<int>& pathEdges) const {\n        double s = 0.0;\n        for (int e : pathEdges) s += effWeight(e);\n        return s;\n    }\n\n    // Sum of usage counts for a path\n    long long pathUsageScore(const vector<int>& pathEdges) const {\n        long long sc = 0;\n        for (int e : pathEdges) sc += usedCount[e];\n        return sc;\n    }\n\n    void gentleDecayMicroScales(double progress) {\n        // Very mild decay toward 1.0 to avoid drifting extremes when untouched\n        double decay = 1e-4 * (0.5 + 0.5 * progress); // 1e-4 -> 5e-5 strength per call\n        for (int i = 0; i < HN; ++i) {\n            rowScale[i] += decay * (1.0 - rowScale[i]);\n        }\n        for (int j = 0; j < WN; ++j) {\n            colScale[j] += decay * (1.0 - colScale[j]);\n        }\n    }\n\n    void updateWeights(const vector<int>& pathEdges, long long observed, int qIndex) {\n        if (pathEdges.empty()) return;\n\n        // Compute predicted effective sum and orientation shares\n        double pred = 0.0, predH = 0.0, predV = 0.0;\n        vector<double> effW_e(pathEdges.size());\n        for (size_t i = 0; i < pathEdges.size(); ++i) {\n            int e = pathEdges[i];\n            double ew = effWeight(e);\n            effW_e[i] = ew;\n            pred += ew;\n            if (e < HHE) predH += ew; else predV += ew;\n        }\n        if (pred <= 1e-9) return;\n\n        double y = (double)observed;\n        double s = y / pred;\n        // Clip scaling\n        s = max(0.88, min(1.12, s));\n\n        // Learning rates\n        double progress = (double)qIndex / 999.0;\n        double eta_dir0  = 0.26, eta_dir1  = 0.05;\n        double eta_edge0 = 0.34, eta_edge1 = 0.085; // slightly higher floor for edges\n        double eta_row0  = 0.10, eta_row1  = 0.02;  // very mild\n        double eta_col0  = 0.10, eta_col1  = 0.02;\n\n        double eta_dir  = eta_dir0  * (1.0 - progress) + eta_dir1  * progress;\n        double eta_edge = eta_edge0 * (1.0 - progress) + eta_edge1 * progress;\n        double eta_row  = eta_row0  * (1.0 - progress) + eta_row1  * progress;\n        double eta_col  = eta_col0  * (1.0 - progress) + eta_col1  * progress;\n\n        // Outlier guard: if s was clipped near extremes, slightly damp learning this round\n        if (s <= 0.885 || s >= 1.115) {\n            eta_dir *= 0.85;\n            eta_edge *= 0.9;\n            eta_row *= 0.85;\n            eta_col *= 0.85;\n        }\n\n        // Orientation shares\n        double fracH = predH / pred;\n        double fracV = predV / pred;\n\n        // Global orientation scales in log space\n        double log_s = log(s);\n        double stepH = eta_dir * fracH * log_s;\n        double stepV = eta_dir * fracV * log_s;\n        double cap = log(1.02);\n        stepH = max(-cap, min(cap, stepH));\n        stepV = max(-cap, min(cap, stepV));\n        gH = exp(log(gH) + stepH);\n        gV = exp(log(gV) + stepV);\n        gH = max(0.5, min(2.0, gH));\n        gV = max(0.5, min(2.0, gV));\n\n        // Per-row/col micro calibration in log space\n        // Accumulate total eff weight per row and per col used in this path\n        array<double, HN> rowSum{}; array<int, HN> rowCnt{};\n        array<double, WN> colSum{}; array<int, WN> colCnt{};\n        for (size_t i = 0; i < pathEdges.size(); ++i) {\n            int e = pathEdges[i];\n            if (e < HHE) {\n                int r = e / (WN - 1);\n                rowSum[r] += effW_e[i];\n                rowCnt[r] += 1;\n            } else {\n                int ve = e - HHE;\n                int c = ve % WN;\n                colSum[c] += effW_e[i];\n                colCnt[c] += 1;\n            }\n        }\n        for (int r = 0; r < HN; ++r) if (rowCnt[r] > 0) {\n            double share = (predH > 0 ? rowSum[r] / predH : 0.0);\n            double st = eta_row * share * log_s;\n            double capRow = log(1.01);\n            st = max(-capRow, min(capRow, st));\n            rowScale[r] = exp(log(rowScale[r]) + st);\n            rowScale[r] = max(0.5, min(2.0, rowScale[r]));\n            rowTouch[r] = qIndex + 1;\n        }\n        for (int c = 0; c < WN; ++c) if (colCnt[c] > 0) {\n            double share = (predV > 0 ? colSum[c] / predV : 0.0);\n            double st = eta_col * share * log_s;\n            double capCol = log(1.01);\n            st = max(-capCol, min(capCol, st));\n            colScale[c] = exp(log(colScale[c]) + st);\n            colScale[c] = max(0.5, min(2.0, colScale[c]));\n            colTouch[c] = qIndex + 1;\n        }\n\n        // Per-edge multiplicative update, share-weighted\n        double baseFactor = 1.0 + eta_edge * (s - 1.0);\n        baseFactor = max(0.95, min(1.05, baseFactor));\n        for (size_t i = 0; i < pathEdges.size(); ++i) {\n            int e = pathEdges[i];\n            double share = effW_e[i] / pred;\n            double expo = 0.6 + 0.4 * share; // in [0.6, 1.0]\n            double f = pow(baseFactor, expo);\n            w[e] *= f;\n            usedCount[e]++;\n        }\n\n        // Adaptive smoothing to neighbors; weaker for short paths\n        double plen = (double)pathEdges.size();\n        double baseBeta = 0.011 * (1.0 - progress) + 0.007 * progress;\n        double beta = baseBeta * min(1.6, 0.5 + plen / 60.0);\n        if (plen < 40.0) beta *= 0.7; // extra reduction for short paths\n        for (int e : pathEdges) {\n            if (e < HHE) {\n                int i = e / (WN - 1);\n                int j = e % (WN - 1);\n                if (j - 1 >= 0) {\n                    int ne = idH(i, j - 1);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n                if (j + 1 < WN - 1) {\n                    int ne = idH(i, j + 1);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n            } else {\n                int ve = e - HHE;\n                int i = ve / WN;\n                int j = ve % WN;\n                if (i - 1 >= 0) {\n                    int ne = idV(i - 1, j);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n                if (i + 1 < HN - 1) {\n                    int ne = idV(i + 1, j);\n                    w[ne] += beta * (w[e] - w[ne]);\n                }\n            }\n        }\n\n        // Clip updated edges\n        for (int e : pathEdges) {\n            if (w[e] < 500.0) w[e] = 500.0;\n            if (w[e] > 15000.0) w[e] = 15000.0;\n        }\n\n        // Gentle decay of micro scales toward 1.0 to prevent long-term drift\n        gentleDecayMicroScales(progress);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    GridRouter gr;\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        // Very mild exploration for first 320 queries\n        double eps = 0.0;\n        if (q < 320) {\n            double t = (double)q / 320.0;\n            eps = 0.026 * (1.0 - t);\n        }\n\n        uint64_t seedBase = ((uint64_t)si<<48) ^ ((uint64_t)sj<<32) ^ ((uint64_t)ti<<16) ^ (uint64_t)tj ^ (uint64_t)(q*11400714819323198485ull);\n        uint64_t seed1 = seedBase;\n        uint64_t seed2 = seedBase ^ 0x9e3779b97f4a7c15ull;\n        uint64_t seed3 = seedBase ^ 0xbf58476d1ce4e5b9ull; // third distinct seed\n\n        // Three candidates: slight H-favor vs V-favor, and neutral with randomization\n        auto rH = gr.shortestPath({si,sj},{ti,tj}, eps, seed1, 0.995, 1.005);\n        auto rV = gr.shortestPath({si,sj},{ti,tj}, eps, seed2, 1.005, 0.995);\n        auto rN = gr.shortestPath({si,sj},{ti,tj}, eps, seed3, 1.0, 1.0);\n\n        double pH = gr.predictSum(rH.pathEdges);\n        double pV = gr.predictSum(rV.pathEdges);\n        double pN = gr.predictSum(rN.pathEdges);\n\n        // Adaptive near-tie threshold based on path length\n        double lenH = (double)rH.pathEdges.size();\n        double lenV = (double)rV.pathEdges.size();\n        double lenN = (double)rN.pathEdges.size();\n        double avgLen = (lenH + lenV + lenN) / 3.0;\n        double nearTie = 1.0 + min(0.02, 0.008 + avgLen / 4000.0);\n\n        // Choose the best predicted; if within nearTie, choose the least-used path to diversify\n        struct Cand { double pred; long long usage; int idx; };\n        vector<Cand> cands;\n        if (!rH.pathEdges.empty()) cands.push_back({pH, gr.pathUsageScore(rH.pathEdges), 0});\n        if (!rV.pathEdges.empty()) cands.push_back({pV, gr.pathUsageScore(rV.pathEdges), 1});\n        if (!rN.pathEdges.empty()) cands.push_back({pN, gr.pathUsageScore(rN.pathEdges), 2});\n\n        GridRouter::DRes* chosenPtr = nullptr;\n        if (!cands.empty()) {\n            sort(cands.begin(), cands.end(), [](const Cand& a, const Cand& b){\n                if (a.pred != b.pred) return a.pred < b.pred;\n                return a.usage < b.usage;\n            });\n            double bestPred = cands.front().pred;\n            // collect near-tie candidates\n            vector<Cand> near;\n            for (auto &c : cands) {\n                if (c.pred <= bestPred * nearTie + 1e-6) near.push_back(c);\n            }\n            // choose among near-tie by lowest usage\n            sort(near.begin(), near.end(), [](const Cand& a, const Cand& b){\n                if (a.usage != b.usage) return a.usage < b.usage;\n                return a.pred < b.pred;\n            });\n            int pickIdx = near.front().idx;\n            if (pickIdx == 0) chosenPtr = &rH;\n            else if (pickIdx == 1) chosenPtr = &rV;\n            else chosenPtr = &rN;\n        } else {\n            // Fallback should not happen; construct Manhattan path if needed\n            chosenPtr = &rH;\n        }\n\n        GridRouter::DRes& res = *chosenPtr;\n        string path = res.pathMoves;\n        if (path.empty()) {\n            int di = ti - si;\n            int dj = tj - sj;\n            if (di > 0) path.append(di, 'D'); else path.append(-di, 'U');\n            if (dj > 0) path.append(dj, 'R'); else path.append(-dj, 'L');\n        }\n\n        cout << path << \"\\n\";\n        cout.flush();\n\n        long long observed;\n        if (!(cin >> observed)) return 0;\n\n        gr.updateWeights(res.pathEdges, observed, q);\n    }\n\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic inline int ch2i(char c){ return c - 'A'; }\nstatic inline char i2ch(int x){ return char('A' + x); }\n\nstruct Placement { uint8_t dir, fixed, start; };\nstruct PlCover { vector<uint16_t> idxs; };\nstruct Occ { int si, pi, pos; };\n\nstruct RNG {\n    uint64_t x;\n    RNG(uint64_t seed=88172645463393265ull){ x=seed; }\n    inline uint64_t rng() { x ^= x<<7; x ^= x>>9; return x; }\n    inline int randint(int l, int r){ return int(l + rng() % (uint64_t)(r - l + 1)); }\n    inline double rand01(){ return (rng() >> 11) * (1.0/9007199254740992.0); }\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    vector<string> s(M);\n    for(int i=0;i<M;i++) cin >> s[i];\n\n    // Encode and stats\n    vector<vector<uint8_t>> enc(M);\n    vector<int> slen(M);\n    array<int,8> globalCnt{}; globalCnt.fill(0);\n    for(int i=0;i<M;i++){\n        int k = (int)s[i].size();\n        slen[i]=k;\n        enc[i].resize(k);\n        for(int p=0;p<k;p++){\n            int v = ch2i(s[i][p]);\n            enc[i][p]=(uint8_t)v;\n            globalCnt[v]++;\n        }\n    }\n    int totalChars=0; for(int v:globalCnt) totalChars+=v;\n    array<double,8> invFreq;\n    for(int c=0;c<8;c++) invFreq[c] = globalCnt[c] ? (double)totalChars / (double)globalCnt[c] : 2.0*totalChars;\n    vector<double> sWeight(M,0.0);\n    for(int i=0;i<M;i++){\n        double r=0.0; for(uint8_t v: enc[i]) r += invFreq[v];\n        sWeight[i] = 0.03 * (r / max(1,slen[i]));\n    }\n\n    // Duplicate multiplicities\n    unordered_map<string,int> multMap;\n    multMap.reserve(M*2);\n    for(int i=0;i<M;i++) multMap[s[i]]++;\n    vector<int> multiplicity(M);\n    for(int i=0;i<M;i++) multiplicity[i] = multMap[s[i]];\n\n    // Precompute placements and covers\n    const int N2 = N*N;\n    vector<vector<Placement>> placements(M);\n    vector<vector<PlCover>> covers(M);\n    for(int i=0;i<M;i++){\n        vector<Placement> ps; ps.reserve(2*N*N);\n        for(int r=0;r<N;r++) for(int c0=0;c0<N;c0++) ps.push_back(Placement{0,(uint8_t)r,(uint8_t)c0});\n        for(int c=0;c<N;c++) for(int r0=0;r0<N;r0++) ps.push_back(Placement{1,(uint8_t)c,(uint8_t)r0});\n        placements[i] = move(ps);\n        vector<PlCover> cv(placements[i].size());\n        for(size_t pi=0; pi<placements[i].size(); ++pi){\n            const auto& pl = placements[i][pi];\n            int k = slen[i];\n            cv[pi].idxs.resize(k);\n            if(pl.dir==0){\n                int r=pl.fixed, c0=pl.start, base=r*N;\n                for(int p=0;p<k;p++){ int c=(c0+p)%N; cv[pi].idxs[p]=(uint16_t)(base+c); }\n            }else{\n                int c=pl.fixed, r0=pl.start;\n                for(int p=0;p<k;p++){ int r=(r0+p)%N; cv[pi].idxs[p]=(uint16_t)(r*N + c); }\n            }\n        }\n        covers[i] = move(cv);\n    }\n\n    // Inverted index\n    vector<vector<Occ>> occ(N2);\n    for(int i=0;i<M;i++){\n        int k = slen[i], P=(int)covers[i].size();\n        for(int pi=0; pi<P; ++pi){\n            const auto& cv = covers[i][pi];\n            for(int p=0;p<k;p++){\n                occ[ cv.idxs[p] ].push_back(Occ{i,pi,p});\n            }\n        }\n    }\n\n    auto solve_once = [&](RNG& rng, double time_ms){\n        const int UNKNOWN = -1;\n        vector<int8_t> grid(N2, UNKNOWN);\n\n        vector<vector<char>> alive(M);\n        vector<int> aliveCnt(M,0);\n        for(int i=0;i<M;i++){\n            int P=(int)covers[i].size();\n            alive[i].assign(P,1);\n            aliveCnt[i]=P;\n        }\n        vector<char> satisfied(M,0);\n\n        auto kill = [&](int i, int pi){\n            if(alive[i][pi]){ alive[i][pi]=0; aliveCnt[i]--; }\n        };\n        auto on_fix_cell = [&](int idx){\n            int8_t val = grid[idx];\n            for(const auto& oc: occ[idx]){\n                if(!alive[oc.si][oc.pi]) continue;\n                if(enc[oc.si][oc.pos] != val) kill(oc.si, oc.pi);\n            }\n        };\n        auto check_zero_gain_and_mark = [&](int i)->bool{\n            if(satisfied[i]) return true;\n            if(aliveCnt[i]==0) return false;\n            const auto& e = enc[i];\n            int P=(int)covers[i].size();\n            for(int pi=0; pi<P; ++pi){\n                if(!alive[i][pi]) continue;\n                const auto& cv = covers[i][pi];\n                bool ok=true;\n                for(int p=0;p<slen[i];++p){\n                    int idx=cv.idxs[p];\n                    if(grid[idx]==UNKNOWN || grid[idx] != (int)e[p]){ ok=false; break; }\n                }\n                if(ok){ satisfied[i]=1; return true; }\n            }\n            return false;\n        };\n        auto eval_placement = [&](int i, int pi)->pair<int,int>{\n            if(!alive[i][pi]) return make_pair(-1,0);\n            const auto& e = enc[i];\n            const auto& cv = covers[i][pi];\n            int g=0,a=0;\n            for(int p=0;p<slen[i];++p){\n                int idx=cv.idxs[p];\n                int8_t v=grid[idx];\n                if(v==UNKNOWN) g++;\n                else if(v==(int)e[p]) a++;\n                else return make_pair(-1,0);\n            }\n            return make_pair(g,a);\n        };\n        auto apply_placement = [&](int i, int pi){\n            const auto& e = enc[i];\n            const auto& cv = covers[i][pi];\n            for(int p=0;p<slen[i];++p){\n                int idx=cv.idxs[p];\n                if(grid[idx]==UNKNOWN){\n                    grid[idx]=(int8_t)e[p];\n                    on_fix_cell(idx);\n                }\n            }\n            satisfied[i]=1;\n        };\n\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        stable_sort(order.begin(), order.end(), [&](int a, int b){\n            if(slen[a] != slen[b]) return slen[a] > slen[b];\n            if(multiplicity[a] != multiplicity[b]) return multiplicity[a] > multiplicity[b];\n            return sWeight[a] > sWeight[b];\n        });\n\n        auto t0 = chrono::high_resolution_clock::now();\n\n        deque<int> q;\n        vector<char> inq(M,0);\n        for(int i=0;i<M;i++) if(aliveCnt[i]==1){ q.push_back(i); inq[i]=1; }\n        auto process_forced = [&](){\n            bool progress=false;\n            while(!q.empty()){\n                int i=q.front(); q.pop_front(); inq[i]=0;\n                if(satisfied[i] || aliveCnt[i]!=1) continue;\n                int onlyPi=-1, P=(int)alive[i].size();\n                for(int pi=0; pi<P; ++pi) if(alive[i][pi]){ onlyPi=pi; break; }\n                if(onlyPi==-1) continue;\n                auto ga=eval_placement(i, onlyPi);\n                if(ga.first<0) continue;\n                if(ga.first==0){ satisfied[i]=1; continue; }\n                apply_placement(i, onlyPi);\n                progress=true;\n                const auto& cv=covers[i][onlyPi];\n                for(int p=0;p<slen[i];++p){\n                    int idx=cv.idxs[p];\n                    for(const auto& oc: occ[idx]){\n                        int j=oc.si;\n                        if(!satisfied[j] && aliveCnt[j]==1 && !inq[j]){ q.push_back(j); inq[j]=1; }\n                    }\n                }\n            }\n            return progress;\n        };\n\n        // Unit cell fix\n        auto unit_cells_fix = [&]()->int{\n            int applied=0;\n            for(int idx=0; idx<N2; ++idx){\n                if(grid[idx] != -1) continue;\n                int agreed = -2; bool seen=false;\n                for(const auto& oc: occ[idx]){\n                    if(!alive[oc.si][oc.pi]) continue;\n                    int letter = enc[oc.si][oc.pos];\n                    if(!seen){ agreed = letter; seen=true; }\n                    else if(agreed != letter){ agreed = -1; break; }\n                }\n                if(seen && agreed >= 0){\n                    grid[idx] = (int8_t)agreed;\n                    on_fix_cell(idx);\n                    applied++;\n                }\n            }\n            if(applied>0){\n                for(int idx=0; idx<N2; ++idx){\n                    if(grid[idx]==-1) continue;\n                    for(const auto& oc: occ[idx]){\n                        int j=oc.si;\n                        if(!satisfied[j] && aliveCnt[j]==1 && !inq[j]){ q.push_back(j); inq[j]=1; }\n                    }\n                }\n                process_forced();\n            }\n            return applied;\n        };\n\n        // Seeding: medium-long and long (>=9)\n        {\n            vector<pair<double, pair<int,int>>> seeds;\n            for(int i=0;i<M;i++){\n                if(slen[i] >= 9){\n                    int P=(int)covers[i].size();\n                    int bestPi=-1, bestG=-1, bestA=-1;\n                    for(int pi=0; pi<P; ++pi){\n                        auto ga = eval_placement(i, pi);\n                        if(ga.first > bestG || (ga.first==bestG && ga.second>bestA)){\n                            bestG = ga.first; bestA = ga.second; bestPi = pi;\n                            if(bestG == slen[i]) break;\n                        }\n                    }\n                    if(bestPi!=-1 && bestG>0){\n                        double factor = (slen[i]>=11 ? 1.0 : 0.5);\n                        double multBonus = 0.002 * multiplicity[i];\n                        seeds.push_back({bestG + factor + 0.002*sWeight[i] + multBonus, {i,bestPi}});\n                    }\n                }\n            }\n            sort(seeds.begin(), seeds.end(), greater<>());\n            int limit = min<int>(14, seeds.size());\n            for(int t=0; t<limit; ++t){\n                int i = seeds[t].second.first;\n                int pi = seeds[t].second.second;\n                auto ga = eval_placement(i, pi);\n                if(ga.first > 0) apply_placement(i, pi);\n            }\n            process_forced();\n            unit_cells_fix();\n        }\n\n        // Initial zero-gain\n        for(int i=0;i<M;i++) check_zero_gain_and_mark(i);\n        process_forced();\n        unit_cells_fix();\n\n        // Support map (for scoring)\n        vector<array<int,8>> support(N2);\n        auto compute_support = [&](){\n            for(int idx=0; idx<N2; ++idx) support[idx].fill(0);\n            for(int i=0;i<M;i++){\n                int P=(int)covers[i].size();\n                const auto& e = enc[i];\n                for(int pi=0; pi<P; ++pi){\n                    if(!alive[i][pi]) continue;\n                    const auto& cv=covers[i][pi];\n                    bool ok=true;\n                    for(int p=0;p<slen[i];++p){\n                        int idx=cv.idxs[p];\n                        int8_t v=grid[idx];\n                        if(v!=-1 && v!=(int)e[p]){ ok=false; break; }\n                    }\n                    if(!ok) continue;\n                    for(int p=0;p<slen[i];++p){\n                        int idx=cv.idxs[p];\n                        if(grid[idx]==-1) support[idx][ e[p] ]++;\n                    }\n                }\n            }\n        };\n\n        // Main loop\n        while(true){\n            auto now = chrono::high_resolution_clock::now();\n            double ms = chrono::duration<double, std::milli>(now - t0).count();\n            if(ms > time_ms) break;\n\n            if(((uint32_t)rng.rng() & 255) == 0){\n                unit_cells_fix();\n            }\n            if(((uint32_t)rng.rng() & 63) == 0){\n                compute_support();\n            }\n\n            struct Cand { int si, pi, gain, agree; double score; };\n            vector<Cand> cands;\n            cands.reserve(64);\n\n            if(rng.rand01() < 0.12){\n                int a=rng.randint(0,M-1), b=rng.randint(0,M-1);\n                if(a!=b) swap(order[a], order[b]);\n            }\n\n            for(int oi=0; oi<M; ++oi){\n                int i=order[oi];\n                if(satisfied[i] || aliveCnt[i]==0) continue;\n                if(check_zero_gain_and_mark(i)) continue;\n\n                int P=(int)covers[i].size();\n                int k=slen[i];\n                int target;\n                if(k>=9) target = P;\n                else if(k<=4) target = 360;\n                else target = max(P / 2, 560);\n                int step = max(1, P / max(1,target));\n                int bestPi=-1, bestG=-1, bestA=-1;\n                for(int pi=0; pi<P; pi+=step){\n                    if(!alive[i][pi]) continue;\n                    auto ga = eval_placement(i, pi);\n                    int g=ga.first; if(g<=0) continue;\n                    int a=ga.second;\n                    if(g>bestG || (g==bestG && a>bestA)){ bestG=g; bestA=a; bestPi=pi; }\n                }\n                // local neighborhood scan around best sampled placement: same row/col start +/- delta\n                if(bestPi!=-1){\n                    const auto& pl = placements[i][bestPi];\n                    int basePi = bestPi;\n                    int bestG2=bestG, bestA2=bestA, bestPi2=bestPi;\n                    int deltas[4] = {-2,-1,1,2};\n                    for(int d : deltas){\n                        int npi = -1;\n                        if(pl.dir==0){\n                            int r = pl.fixed;\n                            int c0 = (int)pl.start;\n                            int nc0 = (c0 + d + N) % N;\n                            npi = r*N + nc0;\n                        }else{\n                            int c = pl.fixed;\n                            int r0 = (int)pl.start;\n                            int nr0 = (r0 + d + N) % N;\n                            npi = N*N + c*N + nr0;\n                        }\n                        if(npi<0 || npi>=P) continue;\n                        if(!alive[i][npi]) continue;\n                        auto ga = eval_placement(i, npi);\n                        if(ga.first > bestG2 || (ga.first==bestG2 && ga.second>bestA2)){\n                            bestG2=ga.first; bestA2=ga.second; bestPi2=npi;\n                        }\n                    }\n                    bestPi = bestPi2; bestG = bestG2; bestA = bestA2;\n                }else if(k<=4){\n                    int tries=96;\n                    while(tries--){\n                        int pi=rng.randint(0,P-1);\n                        if(!alive[i][pi]) continue;\n                        auto ga=eval_placement(i, pi);\n                        if(ga.first>0){ bestPi=pi; bestG=ga.first; bestA=ga.second; break; }\n                    }\n                }\n\n                if(bestPi != -1){\n                    int bonus=0;\n                    double suppBonus=0.0;\n                    const auto& cv = covers[i][bestPi];\n                    int contiguousUnknowns = 0, maxContig=0;\n                    for(int p=0;p<k;p++){\n                        int idx=cv.idxs[p];\n                        if(grid[idx]==-1){\n                            contiguousUnknowns++;\n                            int cnt=0, cap=12;\n                            for(const auto& oc: occ[idx]){\n                                if(cnt>=cap) break;\n                                if(!alive[oc.si][oc.pi]) continue;\n                                if(enc[oc.si][oc.pos] == enc[i][p]) cnt++;\n                            }\n                            bonus += cnt;\n                            if(!support[idx].empty()){\n                                suppBonus += 0.001 * support[idx][ enc[i][p] ];\n                            }\n                        }else{\n                            maxContig = max(maxContig, contiguousUnknowns);\n                            contiguousUnknowns = 0;\n                        }\n                    }\n                    maxContig = max(maxContig, contiguousUnknowns);\n                    double longBonus = (k>=9 ? 0.8 : 0.0);\n                    double multBonus = 0.003 * multiplicity[i];\n                    double contigBonus = 0.01 * maxContig;\n                    double score = bestG + 0.10*bestA + 0.0012*bonus + 0.0035*sWeight[i] + longBonus + suppBonus + multBonus + contigBonus;\n                    cands.push_back(Cand{i,bestPi,bestG,bestA,score});\n                    if((int)cands.size()>64){\n                        nth_element(cands.begin(), cands.begin()+48, cands.end(),\n                            [](const Cand& A, const Cand& B){ return A.score > B.score; });\n                        cands.resize(48);\n                    }\n                }\n            }\n\n            if(cands.empty()){\n                if(!process_forced()){\n                    int units = unit_cells_fix();\n                    if(units==0) break;\n                }\n                continue;\n            }\n            sort(cands.begin(), cands.end(), [](const Cand& A, const Cand& B){\n                if(A.score != B.score) return A.score > B.score;\n                if(A.gain != B.gain) return A.gain > B.gain;\n                return A.agree > B.agree;\n            });\n            int topk = min(6, (int)cands.size());\n            int pick = 0;\n            if(topk>1 && rng.rand01()<0.25) pick = rng.randint(0, topk-1);\n\n            int si=cands[pick].si, pi=cands[pick].pi;\n            auto ga2=eval_placement(si, pi);\n            if(ga2.first > 0){\n                apply_placement(si, pi);\n                const auto& cv = covers[si][pi];\n                for(int p=0;p<slen[si];++p){\n                    int idx=cv.idxs[p];\n                    for(const auto& oc: occ[idx]){\n                        int j=oc.si;\n                        if(!satisfied[j] && aliveCnt[j]==1 && !inq[j]){ q.push_back(j); inq[j]=1; }\n                    }\n                }\n                process_forced();\n                unit_cells_fix();\n            }else if(ga2.first == 0){\n                satisfied[si]=1;\n            }\n        }\n\n        // Endgame absorption along rows/cols with low gain threshold\n        int endApps = 0, endLimit = 60;\n        for(int i=0;i<M && endApps<endLimit;i++){\n            if(satisfied[i] || aliveCnt[i]==0) continue;\n            int P=(int)covers[i].size();\n            int bestPi=-1, bestG=0, bestA=-1;\n            for(int pi=0; pi<P; ++pi){\n                if(!alive[i][pi]) continue;\n                auto ga=eval_placement(i, pi);\n                if(ga.first > bestG || (ga.first==bestG && ga.second>bestA)){\n                    bestG=ga.first; bestA=ga.second; bestPi=pi;\n                }\n            }\n            if(bestPi!=-1){\n                if(bestG>0 && (bestG<=3 || slen[i]>=9)){\n                    apply_placement(i, bestPi);\n                    endApps++;\n                }else if(bestG==0){\n                    satisfied[i]=1;\n                }\n            }\n        }\n        process_forced();\n        unit_cells_fix();\n\n        // Final zero-gain check\n        for(int i=0;i<M;i++){\n            if(satisfied[i]) continue;\n            const auto& e = enc[i];\n            int P=(int)covers[i].size();\n            for(int pi=0; pi<P; ++pi){\n                if(!alive[i][pi]) continue;\n                const auto& cv=covers[i][pi];\n                bool ok=true;\n                for(int p=0;p<slen[i];++p){\n                    if(grid[ cv.idxs[p] ] != (int)e[p]){ ok=false; break; }\n                }\n                if(ok){ satisfied[i]=1; break; }\n            }\n        }\n\n        // Fill unknowns using alive placements\n        vector<array<int,8>> votesFill(N2);\n        for(int idx=0; idx<N2; ++idx) votesFill[idx].fill(0);\n        for(int i=0;i<M;i++){\n            int P=(int)covers[i].size();\n            const auto& e = enc[i];\n            for(int pi=0; pi<P; ++pi){\n                if(!alive[i][pi]) continue;\n                const auto& cv=covers[i][pi];\n                bool ok=true;\n                for(int p=0;p<slen[i];++p){\n                    int idx=cv.idxs[p];\n                    int8_t v=grid[idx];\n                    if(v != -1 && v != (int)e[p]){ ok=false; break; }\n                }\n                if(!ok) continue;\n                for(int p=0;p<slen[i];++p){\n                    int idx=cv.idxs[p];\n                    if(grid[idx]==-1) votesFill[idx][ e[p] ]++;\n                }\n            }\n        }\n        int fillGlobal = int(max_element(globalCnt.begin(), globalCnt.end()) - globalCnt.begin());\n        for(int idx=0; idx<N2; ++idx){\n            if(grid[idx]==-1){\n                int bestL=fillGlobal, bestV=-1;\n                for(int c=0;c<8;c++){\n                    if(votesFill[idx][c] > bestV){ bestV=votesFill[idx][c]; bestL=c; }\n                }\n                grid[idx]=(int8_t)bestL;\n            }\n        }\n\n        // Final count\n        int satisfiedCount=0;\n        for(int i=0;i<M;i++){\n            const auto& e = enc[i];\n            int P=(int)covers[i].size();\n            bool ok=false;\n            for(int pi=0; pi<P; ++pi){\n                const auto& cv=covers[i][pi];\n                bool match=true;\n                for(int p=0;p<slen[i];++p){\n                    if(grid[ cv.idxs[p] ] != (int)e[p]){ match=false; break; }\n                }\n                if(match){ ok=true; break; }\n            }\n            if(ok) satisfiedCount++;\n        }\n        return pair<vector<int8_t>, int>(move(grid), satisfiedCount);\n    };\n\n    RNG rng((uint64_t)chrono::high_resolution_clock::now().time_since_epoch().count());\n    auto start = chrono::high_resolution_clock::now();\n    double total_budget_ms = 2700.0;\n\n    vector<int8_t> bestGrid;\n    int bestC = -1;\n    int restarts = 0;\n    while(true){\n        auto now = chrono::high_resolution_clock::now();\n        double used = chrono::duration<double, std::milli>(now - start).count();\n        if(used > total_budget_ms) break;\n        double remain = total_budget_ms - used;\n        double per = max(800.0, remain / 1.8); // ~3 runs\n        auto res = solve_once(rng, per);\n        if(res.second > bestC){\n            bestC = res.second;\n            bestGrid = move(res.first);\n        }\n        restarts++;\n        if(restarts >= 3) break;\n    }\n    if(bestGrid.empty()) bestGrid.assign(N2, 0);\n\n    for(int r=0;r<N;r++){\n        string line(N, 'A');\n        for(int c=0;c<N;c++){\n            line[c] = i2ch(bestGrid[r*N + c]);\n        }\n        cout << line << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() { st = chrono::steady_clock::now(); }\n    double elapsed() const {\n        using namespace chrono;\n        return duration<double>(steady_clock::now() - st).count();\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    auto inb = [&](int i, int j){ return 0<=i && i<N && 0<=j && j<N; };\n    auto isRoad = [&](int i, int j){ return inb(i,j) && g[i][j] != '#'; };\n\n    // Compress road cells\n    int R = 0;\n    vector<int> id(N*N, -1);\n    vector<pair<int,int>> pos; pos.reserve(N*N);\n    for (int i=0;i<N;++i) for (int j=0;j<N;++j) if (isRoad(i,j)) {\n        id[i*N+j] = R++;\n        pos.emplace_back(i,j);\n    }\n    int startId = id[si*N+sj];\n    if (startId < 0) { cout << \"\\n\"; return 0; }\n\n    // Neighbors and weights\n    vector<array<int,4>> neigh(R);\n    vector<array<int,4>> moveCost(R);\n    for (int r=0;r<R;++r){\n        auto [i,j] = pos[r];\n        int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};\n        for (int d=0; d<4; ++d) {\n            int ni=i+dirs[d][0], nj=j+dirs[d][1];\n            if (isRoad(ni,nj)) {\n                int nid = id[ni*N+nj];\n                neigh[r][d] = nid;\n                moveCost[r][d] = g[ni][nj]-'0';\n            } else {\n                neigh[r][d] = -1;\n                moveCost[r][d] = 0;\n            }\n        }\n    }\n\n    // Bitset utils\n    int W = (R + 63) >> 6;\n    using BVec = vector<uint64_t>;\n    auto popcount_bits = [&](const BVec& a)->int{\n        int s=0; for (int k=0;k<W;++k) s += (int)__builtin_popcountll(a[k]); return s;\n    };\n    auto marginal_gain = [&](const BVec& v, const BVec& rem)->int{\n        int s=0; for (int k=0;k<W;++k) s += (int)__builtin_popcountll(v[k] & rem[k]); return s;\n    };\n\n    // Precompute visibility per cell; row/col runs and ids\n    vector<BVec> vis(R, BVec(W, 0));\n    vector<vector<int>> rowRuns; rowRuns.reserve(N*2);\n    vector<int> rowRunId(R, -1), colRunId(R, -1);\n    int rowRunCnt = 0, colRunCnt = 0;\n    for (int i=0;i<N;++i) {\n        int j=0;\n        while (j<N) {\n            while (j<N && !isRoad(i,j)) ++j;\n            if (j>=N) break;\n            int k=j;\n            vector<int> run;\n            while (k<N && isRoad(i,k)) { run.push_back(id[i*N+k]); ++k; }\n            for (int idx : run) {\n                rowRunId[idx] = rowRunCnt;\n                auto &b = vis[idx];\n                for (int rid : run) b[rid>>6] |= (1ULL << (rid&63));\n            }\n            rowRuns.push_back(run);\n            rowRunCnt++;\n            j = k;\n        }\n    }\n    vector<vector<int>> colRuns; colRuns.reserve(N*2);\n    for (int j=0;j<N;++j) {\n        int i=0;\n        while (i<N) {\n            while (i<N && !isRoad(i,j)) ++i;\n            if (i>=N) break;\n            int k=i;\n            vector<int> run;\n            while (k<N && isRoad(k,j)) { run.push_back(id[k*N+j]); ++k; }\n            for (int idx : run) {\n                colRunId[idx] = colRunCnt;\n                auto &b = vis[idx];\n                for (int rid : run) b[rid>>6] |= (1ULL << (rid&63));\n            }\n            colRuns.push_back(run);\n            colRunCnt++;\n            i = k;\n        }\n    }\n\n    // Degree for POIs\n    vector<int> deg(R,0);\n    for (int r=0;r<R;++r) for (int d=0; d<4; ++d) if (neigh[r][d] >= 0) deg[r]++;\n\n    // Candidate vantage points: junctions/endpoints + reps per run\n    vector<int> cand;\n    cand.reserve(R/2);\n    for (int r=0;r<R;++r) if (deg[r] != 2) cand.push_back(r);\n    if (find(cand.begin(), cand.end(), startId) == cand.end()) cand.push_back(startId);\n    auto add_reps = [&](const vector<vector<int>>& runs){\n        const int K = 2;\n        for (const auto& run : runs) {\n            int m = (int)run.size();\n            if (m == 0) continue;\n            if (m <= 3) {\n                cand.insert(cand.end(), run.begin(), run.end());\n            } else {\n                for (int k=0; k<K; ++k) {\n                    int idx = (int)llround((double)(k+1) * (m+1) / (K+1)) - 1;\n                    idx = max(0, min(m-1, idx));\n                    cand.push_back(run[idx]);\n                }\n            }\n        }\n    };\n    add_reps(rowRuns);\n    add_reps(colRuns);\n    sort(cand.begin(), cand.end());\n    cand.erase(unique(cand.begin(), cand.end()), cand.end());\n\n    // Potential cost per node (normalized)\n    vector<double> pot(R, 0.0);\n    for (int r=0;r<R;++r){\n        int cnt=0, sum=0;\n        for (int d=0; d<4; ++d) if (neigh[r][d] >= 0) { sum += moveCost[r][d]; cnt++; }\n        if (cnt>0) pot[r] = (double)sum / cnt;\n        else {\n            auto [i,j] = pos[r];\n            pot[r] = g[i][j]-'0';\n        }\n    }\n    double minP=*min_element(pot.begin(), pot.end());\n    double maxP=*max_element(pot.begin(), pot.end());\n    double spanP = max(1e-9, maxP - minP);\n    for (int r=0;r<R;++r) pot[r] = (pot[r] - minP) / spanP;\n\n    // Centrality\n    double ci = (N-1)/2.0, cj = (N-1)/2.0;\n    vector<double> centrality(R);\n    double maxC = 0.0;\n    for (int r=0;r<R;++r){\n        auto [i,j] = pos[r];\n        double c = fabs(i - ci) + fabs(j - cj);\n        centrality[r] = c;\n        maxC = max(maxC, c);\n    }\n    for (int r=0;r<R;++r) centrality[r] = 1.0 - (centrality[r] / (maxC>0?maxC:1.0));\n\n    // Dijkstra utils\n    const int INF = 1e9;\n    vector<int> dist(R), prevArr(R,-1);\n    auto dijkstra = [&](int src, vector<int>& distOut, vector<int>* prevOut){\n        fill(distOut.begin(), distOut.end(), INF);\n        if (prevOut) fill(prevOut->begin(), prevOut->end(), -1);\n        using P = pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n        distOut[src] = 0;\n        pq.emplace(0, src);\n        while (!pq.empty()){\n            auto [cd,u] = pq.top(); pq.pop();\n            if (cd != distOut[u]) continue;\n            for (int d=0; d<4; ++d) {\n                int v = neigh[u][d];\n                if (v < 0) continue;\n                int w = moveCost[u][d];\n                int nd = cd + w;\n                if (nd < distOut[v]) {\n                    distOut[v] = nd;\n                    if (prevOut) (*prevOut)[v] = u;\n                    pq.emplace(nd, v);\n                }\n            }\n        }\n    };\n    auto reconstruct_seq = [&](int curId, int tgtId, const vector<int>& prev)->vector<int>{\n        vector<int> seq;\n        if (curId == tgtId) return seq;\n        int x = tgtId;\n        while (x != -1 && x != curId) { seq.push_back(x); x = prev[x]; }\n        if (x != curId) { seq.clear(); return seq; }\n        reverse(seq.begin(), seq.end());\n        return seq;\n    };\n\n    // Precompute dist_to_start and average\n    vector<int> dist_to_start(R);\n    dijkstra(startId, dist_to_start, nullptr);\n    long long sumd = 0; int cntd = 0;\n    for (int r=0;r<R;++r) if (dist_to_start[r] < INF) { sumd += dist_to_start[r]; cntd++; }\n    double avgDistToStart = (cntd ? (double)sumd / cntd : 1.0);\n\n    // Coverage tracking\n    BVec covered(W, 0), remaining(W, 0);\n    for (int r=0;r<R;++r) remaining[r>>6] |= (1ULL << (r&63));\n    auto see_from_apply = [&](int node, int &remCount){\n        for (int k=0;k<W;++k) {\n            uint64_t bits = vis[node][k];\n            uint64_t newbits = bits & ~covered[k];\n            int add = (int)__builtin_popcountll(newbits);\n            covered[k] |= bits;\n            remaining[k] &= ~bits;\n            remCount -= add;\n        }\n    };\n\n    // Uncovered mass per run\n    vector<int> rowRem(rowRunCnt, 0), colRem(colRunCnt, 0);\n    for (int r=0;r<R;++r) { rowRem[rowRunId[r]]++; colRem[colRunId[r]]++; }\n    auto update_run_mass_after_see = [&](int node){\n        for (int k=0;k<W;++k) {\n            uint64_t newbits = vis[node][k] & ~covered[k];\n            uint64_t bits = newbits;\n            while (bits) {\n                uint64_t b = bits & -bits;\n                int idx = (k<<6) + __builtin_ctzll(bits);\n                if (idx < R) {\n                    int rr = rowRunId[idx], cc = colRunId[idx];\n                    if (rr >= 0) rowRem[rr]--;\n                    if (cc >= 0) colRem[cc]--;\n                }\n                bits ^= b;\n            }\n        }\n    };\n\n    int remCount = R;\n    update_run_mass_after_see(startId);\n    see_from_apply(startId, remCount);\n\n    string answer;\n    Timer timer;\n    double timeLimit = 2.85;\n    int cur = startId;\n\n    vector<int> dist_cur(R), prev_cur(R);\n\n    auto compute_lambda = [&](double coveredRatio, int curNode)->double{\n        double curToStart = (dist_to_start[curNode] < INF ? dist_to_start[curNode] : avgDistToStart);\n        double lambda = 0.0;\n        if (coveredRatio > 0.6) {\n            lambda = 0.05 * (curToStart / max(1.0, avgDistToStart));\n            if (coveredRatio > 0.9) lambda *= 1.6;\n            if (coveredRatio > 0.95) lambda *= 1.4;\n        }\n        if (coveredRatio > 0.95 && curToStart > 1.5*avgDistToStart) lambda *= 1.3;\n        return lambda;\n    };\n\n    auto score_candidate = [&](int t, double lambda, int remCount, const BVec& remaining,\n                               int phase)->optional<double>{\n        int d0 = dist_cur[t];\n        if (d0 >= INF) return nullopt;\n        int gain = marginal_gain(vis[t], remaining);\n        if (gain <= 0) return nullopt;\n\n        int rr = rowRunId[t], cc = colRunId[t];\n        int mass = 0;\n        if (rr >= 0) mass += max(0, rowRem[rr]);\n        if (cc >= 0) mass += max(0, colRem[cc]);\n        double massBoost = 1.0 + 0.15 * tanh(mass / 20.0);\n        double potPen = 1.0 + 0.1 * pot[t];\n        double centBoost = 1.0 + 0.1 * centrality[t];\n\n        double eff = ((double)d0 + lambda * (double)dist_to_start[t]) * potPen;\n        if (phase == 0) { // EARLY\n            double beta = 1.08;\n            return (eff / pow((double)gain, beta)) / (massBoost * centBoost);\n        } else if (phase == 1) { // MID\n            double alpha = 0.02;\n            return -(((double)gain*massBoost*centBoost) - alpha * eff);\n        } else { // LATE\n            int minGainReq = (remCount > 8 ? 2 : 1);\n            if (gain < minGainReq) return nullopt;\n            return (eff / (double)gain) / (0.7*massBoost + 0.3*centBoost);\n        }\n    };\n\n    while (remCount > 0) {\n        if (timer.elapsed() > timeLimit) break;\n\n        dijkstra(cur, dist_cur, &prev_cur);\n\n        double coveredRatio = 1.0 - (double)remCount / (double)R;\n        double lambda = compute_lambda(coveredRatio, cur);\n        int phase = 0;\n        if (remCount <= R / 4) phase = 1;\n        if (remCount <= max(32, R / 12)) phase = 2;\n\n        // Select shortlist\n        struct CandScore { int t; int gain; double eff; double score; };\n        vector<CandScore> cs; cs.reserve(min((int)cand.size(), 256));\n\n        auto eval_primary = [&](int t)->optional<CandScore>{\n            int d0 = dist_cur[t];\n            if (d0 >= INF) return nullopt;\n            int gain = marginal_gain(vis[t], remaining);\n            if (gain <= 0) return nullopt;\n\n            int rr = rowRunId[t], cc = colRunId[t];\n            int mass = 0;\n            if (rr >= 0) mass += max(0, rowRem[rr]);\n            if (cc >= 0) mass += max(0, colRem[cc]);\n            double massBoost = 1.0 + 0.15 * tanh(mass / 20.0);\n            double potPen = 1.0 + 0.1 * pot[t];\n            double centBoost = 1.0 + 0.1 * centrality[t];\n\n            double eff = ((double)d0 + lambda * (double)dist_to_start[t]) * potPen;\n            double sc;\n            if (phase == 0) {\n                double beta = 1.08;\n                sc = (eff / pow((double)gain, beta)) / (massBoost * centBoost);\n            } else if (phase == 1) {\n                double alpha = 0.02;\n                sc = -(((double)gain*massBoost*centBoost) - alpha * eff);\n            } else {\n                int minGainReq = (remCount > 8 ? 2 : 1);\n                if (gain < minGainReq) return nullopt;\n                sc = (eff / (double)gain) / (0.7*massBoost + 0.3*centBoost);\n            }\n            return CandScore{t, gain, eff, sc};\n        };\n\n        for (int t : cand) {\n            auto r = eval_primary(t);\n            if (r) cs.push_back(*r);\n        }\n        if (cs.empty()) {\n            vector<pair<int,int>> gain_nodes; gain_nodes.reserve(600);\n            for (int t=0;t<R;++t) {\n                if (dist_cur[t] >= INF) continue;\n                int gain = marginal_gain(vis[t], remaining);\n                if (gain > 0) gain_nodes.emplace_back(-gain, t);\n            }\n            if (!gain_nodes.empty()) {\n                int K = min((int)gain_nodes.size(), 600);\n                nth_element(gain_nodes.begin(), gain_nodes.begin()+K, gain_nodes.end());\n                for (int i=0;i<K;++i) {\n                    auto r = eval_primary(gain_nodes[i].second);\n                    if (r) cs.push_back(*r);\n                }\n            }\n        }\n        if (cs.empty()) break;\n\n        int BEAM = 10;\n        if (timer.elapsed() > timeLimit*0.9) BEAM = 6;\n        nth_element(cs.begin(), cs.begin()+min(BEAM,(int)cs.size())-1, cs.end(),\n                    [&](const CandScore& a, const CandScore& b){ return a.score < b.score; });\n        int beamSize = min(BEAM, (int)cs.size());\n        cs.resize(beamSize);\n\n        // Two-step lookahead\n        int bestFirst = -1;\n        double bestPlanScore = 1e300;\n        vector<int> dist_tmp(R), prev_tmp(R);\n        int SEC_K_BASE = 60;\n        if (timer.elapsed() > timeLimit*0.9) SEC_K_BASE = 40;\n\n        for (int bi=0; bi<beamSize; ++bi) {\n            int t1 = cs[bi].t;\n            vector<pair<int,int>> secPool;\n            secPool.reserve(150);\n            for (int c : cand) {\n                int g2 = marginal_gain(vis[c], remaining);\n                if (g2 > 0) secPool.emplace_back(-g2, c);\n            }\n            if (!secPool.empty()) {\n                int SEC_K = min((int)secPool.size(), SEC_K_BASE);\n                nth_element(secPool.begin(), secPool.begin()+SEC_K, secPool.end());\n                secPool.resize(SEC_K);\n                dijkstra(t1, dist_tmp, &prev_tmp);\n                double bestSecondScore = cs[bi].score;\n                for (auto [negGain, c2] : secPool) {\n                    int d1 = dist_cur[t1];\n                    int d12 = dist_tmp[c2];\n                    if (d1 >= INF || d12 >= INF) continue;\n                    // marginal second gain after t1\n                    int secGain = 0;\n                    for (int k=0;k<W;++k) {\n                        uint64_t remk = remaining[k] & ~vis[t1][k];\n                        secGain += (int)__builtin_popcountll(remk & vis[c2][k]);\n                    }\n                    if (secGain <= 0) continue;\n\n                    int rr2 = rowRunId[c2], cc2 = colRunId[c2];\n                    int mass2 = 0;\n                    if (rr2 >= 0) mass2 += max(0, rowRem[rr2]);\n                    if (cc2 >= 0) mass2 += max(0, colRem[cc2]);\n                    double massBoost2 = 1.0 + 0.15 * tanh(mass2 / 20.0);\n                    double potPen2 = 1.0 + 0.1 * pot[c2];\n                    double centBoost2 = 1.0 + 0.1 * centrality[c2];\n\n                    double eff1 = ((double)d1 + lambda * (double)dist_to_start[t1]) * (1.0 + 0.1 * pot[t1]);\n                    double eff2 = ((double)d12 + lambda * (double)dist_to_start[c2]) * potPen2;\n\n                    double planScore;\n                    if (phase == 0) {\n                        double beta = 1.08;\n                        planScore = (eff1 / pow((double)cs[bi].gain, beta))\n                                    + 0.8 * ((eff2 / pow((double)secGain, beta)) / (massBoost2 * centBoost2));\n                    } else if (phase == 1) {\n                        double alpha = 0.02;\n                        double p1 = ((double)cs[bi].gain) - alpha * eff1;\n                        double p2 = (double)secGain * (massBoost2 * centBoost2) - alpha * eff2;\n                        planScore = -(p1 + 0.8*p2);\n                    } else {\n                        planScore = (eff1 / max(1, cs[bi].gain))\n                                    + 0.8 * ((eff2 / max(1, secGain)) / (0.7*massBoost2 + 0.3*centBoost2));\n                    }\n                    if (planScore < bestSecondScore) bestSecondScore = planScore;\n                }\n                if (bestSecondScore < bestPlanScore) {\n                    bestPlanScore = bestSecondScore;\n                    bestFirst = t1;\n                }\n            } else {\n                if (cs[bi].score < bestPlanScore) {\n                    bestPlanScore = cs[bi].score;\n                    bestFirst = t1;\n                }\n            }\n            if (timer.elapsed() > timeLimit) break;\n        }\n        if (bestFirst == -1) bestFirst = cs[0].t;\n\n        // Build path to bestFirst\n        vector<int> seq = reconstruct_seq(cur, bestFirst, prev_cur);\n        if (seq.empty() && cur != bestFirst) break;\n\n        string mv;\n        int prevNode = cur;\n        int gainedAlong = 0;\n        int reevaluateThreshold = max(12, remCount / 60);\n        // Opportunistic on-path replanning parameters\n        int stepCount = 0;\n        for (int v : seq) {\n            auto [ui,uj] = pos[prevNode];\n            auto [vi,vj] = pos[v];\n            if (vi==ui-1 && vj==uj) mv.push_back('U');\n            else if (vi==ui+1 && vj==uj) mv.push_back('D');\n            else if (vi==ui && vj==uj-1) mv.push_back('L');\n            else if (vi==ui && vj==uj+1) mv.push_back('R');\n\n            // Before applying, compute run mass update\n            update_run_mass_after_see(v);\n            int before = popcount_bits(remaining);\n            see_from_apply(v, remCount);\n            int after = popcount_bits(remaining);\n            gainedAlong += before - after;\n\n            prevNode = v;\n            stepCount++;\n            if (remCount == 0) break;\n\n            // Opportunistic local re-evaluation: every few steps, check if a nearby candidate now is much better\n            if (stepCount % 3 == 0 && timer.elapsed() < timeLimit*0.95) {\n                // Dijkstra from current small check\n                dijkstra(prevNode, dist_cur, &prev_cur);\n                double newLambda = compute_lambda(1.0 - (double)remCount / (double)R, prevNode);\n                double bestSc = 1e300;\n                int bestLoc = -1;\n                int checks = 0;\n                for (int t : cand) {\n                    if (checks >= 12) break;\n                    auto sc = score_candidate(t, newLambda, remCount, remaining, phase);\n                    if (!sc) continue;\n                    double val = *sc;\n                    if (val < bestSc) { bestSc = val; bestLoc = t; }\n                    checks++;\n                }\n                // If local best significantly better than committing to original endpoint, break\n                if (bestLoc != -1) {\n                    // heuristic: if after progress, any candidate beats continuation, replan\n                    break;\n                }\n            }\n\n            if (gainedAlong >= reevaluateThreshold) break;\n            if (timer.elapsed() > timeLimit) break;\n        }\n        answer += mv;\n        cur = prevNode;\n\n        if (timer.elapsed() > timeLimit) break;\n    }\n\n    // Return to start\n    if (cur != startId) {\n        vector<int> dist_back(R), prev_back(R);\n        auto dijkstra2 = [&](int src){\n            fill(dist_back.begin(), dist_back.end(), 1e9);\n            fill(prev_back.begin(), prev_back.end(), -1);\n            using P = pair<int,int>;\n            priority_queue<P, vector<P>, greater<P>> pq;\n            dist_back[src] = 0; pq.emplace(0, src);\n            while (!pq.empty()) {\n                auto [cd,u] = pq.top(); pq.pop();\n                if (cd != dist_back[u]) continue;\n                for (int d=0; d<4; ++d) {\n                    int v = neigh[u][d];\n                    if (v < 0) continue;\n                    int w = moveCost[u][d];\n                    int nd = cd + w;\n                    if (nd < dist_back[v]) {\n                        dist_back[v] = nd; prev_back[v] = u;\n                        pq.emplace(nd, v);\n                    }\n                }\n            }\n        };\n        dijkstra2(cur);\n        vector<int> seq;\n        if (dist_back[startId] < 1e9) {\n            int x = startId;\n            while (x != -1 && x != cur) { seq.push_back(x); x = prev_back[x]; }\n            if (x == cur) reverse(seq.begin(), seq.end());\n            else seq.clear();\n        }\n        string mv;\n        int prevNode = cur;\n        for (int v : seq) {\n            auto [ui,uj] = pos[prevNode];\n            auto [vi,vj] = pos[v];\n            if (vi==ui-1 && vj==uj) mv.push_back('U');\n            else if (vi==ui+1 && vj==uj) mv.push_back('D');\n            else if (vi==ui && vj==uj-1) mv.push_back('L');\n            else if (vi==ui && vj==uj+1) mv.push_back('R');\n            prevNode = v;\n        }\n        answer += mv;\n    }\n\n    cout << answer << '\\n';\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct RNG {\n    uint64_t x=88172645463393265ull;\n    uint32_t next() { x ^= x<<7; x ^= x>>9; return uint32_t(x); }\n    double drand() { return (next()>>8) * (1.0/16777216.0); }\n} rng;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,K,R;\n    if(!(cin>>N>>M>>K>>R)) return 0;\n    vector<vector<int>> d(N, vector<int>(K));\n    for(int i=0;i<N;i++) for(int k=0;k<K;k++) cin>>d[i][k];\n    vector<vector<int>> g(N);\n    vector<int> indeg(N,0);\n    for(int i=0;i<R;i++){\n        int u,v; cin>>u>>v; --u;--v;\n        g[u].push_back(v);\n        indeg[v]++;\n    }\n    // Topological order\n    vector<int> topo;\n    {\n        vector<int> indeg2 = indeg;\n        queue<int> q;\n        for(int i=0;i<N;i++) if(indeg2[i]==0) q.push(i);\n        while(!q.empty()){\n            int u=q.front(); q.pop();\n            topo.push_back(u);\n            for(int v: g[u]) if(--indeg2[v]==0) q.push(v);\n        }\n        if((int)topo.size()!=N){\n            topo.clear();\n            for(int i=0;i<N;i++) topo.push_back(i);\n        }\n    }\n    // Height (longest path to sink)\n    vector<int> height(N,0);\n    for(int idx=N-1; idx>=0; --idx){\n        int u=topo[idx];\n        int best=0;\n        for(int v: g[u]) best = max(best, 1 + height[v]);\n        height[u]=best;\n    }\n    // Out-degree and priority\n    vector<int> outdeg(N,0);\n    for(int u=0;u<N;u++) outdeg[u] = (int)g[u].size();\n    const double lambda = 0.15;\n    vector<double> prio(N);\n    for(int i=0;i<N;i++) prio[i] = height[i] + lambda * outdeg[i];\n\n    // Estimates\n    vector<vector<double>> est(M, vector<double>(K, 10.0));\n    vector<vector<int>> lb(M, vector<int>(K, 0));\n\n    // States\n    vector<int> tstat(N,0); // 0 not started, 1 started, 2 done\n    vector<int> started_by(N,-1), start_day(N,-1);\n    vector<int> mtask(M,-1);\n    vector<int> cur_indeg = indeg;\n    vector<char> ready_flag(N,0);\n    for(int i=0;i<N;i++) if(cur_indeg[i]==0) ready_flag[i]=1;\n\n    int done_cnt = 0;\n\n    // Global calibration bias for t prediction\n    double bias_b = 0.3; // start with small positive\n    int bias_cnt = 0;\n\n    auto predicted_w = [&](int task, int mem)->double{\n        double w=0.0;\n        for(int k=0;k<K;k++){\n            double df = (double)d[task][k] - est[mem][k];\n            if(df>0) w += df;\n        }\n        return w;\n    };\n    auto predicted_time = [&](int task, int mem)->double{\n        double w = predicted_w(task, mem);\n        if(w<1.0) return 1.0;\n        return max(1.0, w + bias_b);\n    };\n\n    auto assign_task = [&](int mem, int task, int day){\n        mtask[mem]=task;\n        tstat[task]=1;\n        started_by[task]=mem;\n        start_day[task]=day;\n        ready_flag[task]=0;\n    };\n\n    int day=0;\n    const double base_beta = 0.22;\n    const double eps = 0.05;\n\n    while(true){\n        day++;\n\n        // Idle members\n        vector<int> idle;\n        idle.reserve(M);\n        for(int j=0;j<M;j++) if(mtask[j]==-1) idle.push_back(j);\n\n        // Ready tasks\n        vector<int> ready_all;\n        ready_all.reserve(1024);\n        for(int i=0;i<N;i++){\n            if(ready_flag[i] && tstat[i]==0) ready_all.push_back(i);\n        }\n\n        vector<int> rlist = ready_all;\n        // Dynamic priority weight: later stages reduce priority emphasis\n        int remaining_tasks = 0;\n        for(int i=0;i<N;i++) if(tstat[i]!=2) remaining_tasks++;\n        double beta = base_beta * (remaining_tasks > 300 ? 1.0 : (0.6 + 0.4 * (double)remaining_tasks / 300.0));\n\n        // Cap by priority but also include best-fit pool\n        int cap_prio = 320;\n        if((int)rlist.size()>cap_prio){\n            nth_element(rlist.begin(), rlist.begin()+cap_prio, rlist.end(), [&](int a,int b){\n                return prio[a] > prio[b];\n            });\n            rlist.resize(cap_prio);\n        }\n        // Add best-fit pool: tasks with minimal predicted w across idle members\n        if(!idle.empty()){\n            vector<pair<double,int>> bestfit;\n            bestfit.reserve(256);\n            for(int t : ready_all){\n                // skip if already in rlist\n                // mark in set for O(1)\n            }\n            vector<char> inR(N, 0);\n            for(int t: rlist) inR[t]=1;\n            for(int t: ready_all){\n                if(inR[t]) continue;\n                double minw = 1e100;\n                for(int mem: idle){\n                    double w = predicted_w(t, mem);\n                    if(w < minw) minw = w;\n                }\n                bestfit.emplace_back(minw, t);\n            }\n            int cap_fit = 80;\n            if((int)bestfit.size() > cap_fit){\n                nth_element(bestfit.begin(), bestfit.begin()+cap_fit, bestfit.end(),\n                            [&](const auto& A, const auto& B){ return A.first < B.first; });\n                bestfit.resize(cap_fit);\n            }\n            for(auto &p: bestfit) rlist.push_back(p.second);\n        }\n\n        // Remove duplicates in rlist\n        sort(rlist.begin(), rlist.end());\n        rlist.erase(unique(rlist.begin(), rlist.end()), rlist.end());\n\n        vector<pair<int,int>> out;\n        out.reserve(idle.size());\n\n        if(!idle.empty() && !rlist.empty()){\n            size_t U = idle.size(), L = rlist.size();\n            vector<char> taskTaken(L, 0);\n            vector<char> memTaken(U, 0);\n\n            // Precompute predicted w\n            vector<vector<double>> pw(U, vector<double>(L, 0.0));\n            for(size_t ui=0; ui<U; ++ui){\n                int mem = idle[ui];\n                for(size_t li=0; li<L; ++li){\n                    int t = rlist[li];\n                    pw[ui][li] = predicted_w(t, mem);\n                }\n            }\n\n            // Phase 1: perfect-fit w<1\n            for(size_t ui=0; ui<U; ++ui){\n                if(memTaken[ui]) continue;\n                int mem = idle[ui];\n                int bestIdx=-1; double bestSc=-1e100;\n                for(size_t li=0; li<L; ++li){\n                    if(taskTaken[li]) continue;\n                    if(pw[ui][li] < 1.0 - 1e-9){\n                        double sc = prio[rlist[li]];\n                        if(sc > bestSc){\n                            bestSc = sc; bestIdx = (int)li;\n                        }\n                    }\n                }\n                if(bestIdx!=-1){\n                    taskTaken[bestIdx]=1;\n                    memTaken[ui]=1;\n                    out.emplace_back(mem, rlist[bestIdx]);\n                }\n            }\n\n            // Phase 2: near-perfect (1..3], assign to best member, prioritize by prio\n            vector<int> bestMemForTask(L, -1);\n            for(size_t li=0; li<L; ++li){\n                if(taskTaken[li]) continue;\n                double bestW = 1e100; int bestUI=-1;\n                for(size_t ui=0; ui<U; ++ui){\n                    if(memTaken[ui]) continue;\n                    double w = pw[ui][li];\n                    if(w >= 1.0 - 1e-9 && w <= 3.0 + 1e-9){\n                        if(w < bestW - 1e-12){\n                            bestW = w; bestUI=(int)ui;\n                        }\n                    }\n                }\n                bestMemForTask[li]=bestUI;\n            }\n            vector<int> order(L);\n            iota(order.begin(), order.end(), 0);\n            sort(order.begin(), order.end(), [&](int a,int b){\n                return prio[rlist[a]] > prio[rlist[b]];\n            });\n            for(int li: order){\n                if(taskTaken[li]) continue;\n                int ui = bestMemForTask[li];\n                if(ui>=0 && !memTaken[ui]){\n                    taskTaken[li]=1;\n                    memTaken[ui]=1;\n                    out.emplace_back(idle[ui], rlist[li]);\n                }\n            }\n\n            // Phase 3: greedy fill by predicted time - beta*prio\n            for(size_t ui=0; ui<U; ++ui){\n                if(memTaken[ui]) continue;\n                int mem = idle[ui];\n                bool explore = (rng.drand() < eps);\n                int bestIdx=-1; double bestScore=1e100;\n                if(explore){\n                    for(size_t li=0; li<L; ++li){\n                        if(taskTaken[li]) continue;\n                        int t = rlist[li];\n                        double w = pw[ui][li];\n                        double score = fabs(w-1.8) - 0.05*prio[t];\n                        if(score < bestScore){\n                            bestScore = score; bestIdx=(int)li;\n                        }\n                    }\n                }else{\n                    for(size_t li=0; li<L; ++li){\n                        if(taskTaken[li]) continue;\n                        int t = rlist[li];\n                        double tp = (pw[ui][li] < 1.0 ? 1.0 : pw[ui][li] + bias_b);\n                        double score = tp - beta * prio[t];\n                        if(score < bestScore){\n                            bestScore = score; bestIdx=(int)li;\n                        }\n                    }\n                }\n                if(bestIdx!=-1){\n                    taskTaken[bestIdx]=1;\n                    out.emplace_back(mem, rlist[bestIdx]);\n                }\n            }\n\n            // Phase 4: if still idle and ready set small, search globally among all ready tasks\n            if(!ready_all.empty() && ready_all.size() <= 200){\n                for(size_t ui=0; ui<U; ++ui){\n                    if(memTaken[ui]) continue; // only truly idle if not assigned; however memTaken tracks internal, we check actual out assignments\n                }\n                // build set of already assigned tasks\n                vector<char> assignedT(N, 0);\n                for(auto &p: out) assignedT[p.second]=1;\n                for(int mem : idle){\n                    bool already=false;\n                    for(auto &p: out) if(p.first==mem){ already=true; break; }\n                    if(already) continue;\n                    int bestT=-1; double bestVal=1e100;\n                    for(int t : ready_all){\n                        if(assignedT[t]) continue;\n                        double tp = predicted_time(t, mem);\n                        double val = tp - beta * prio[t];\n                        if(val < bestVal){\n                            bestVal = val; bestT = t;\n                        }\n                    }\n                    if(bestT!=-1){\n                        assignedT[bestT]=1;\n                        out.emplace_back(mem, bestT);\n                    }\n                }\n            }\n        }\n\n        // Output\n        cout<<out.size();\n        for(auto &p: out){\n            cout<<\" \"<<(p.first+1)<<\" \"<<(p.second+1);\n            assign_task(p.first, p.second, day);\n        }\n        cout<<\"\\n\";\n        cout.flush();\n\n        // Feedback\n        int nfin;\n        if(!(cin>>nfin)) return 0;\n        if(nfin==-1) return 0;\n        vector<int> fins(nfin);\n        for(int i=0;i<nfin;i++){ cin>>fins[i]; fins[i]--; }\n\n        // Process finishes\n        for(int mem: fins){\n            int task = mtask[mem];\n            if(task<0) continue;\n            int dur = day - start_day[task] + 1;\n            done_cnt++;\n\n            // Update global bias from this observation if dur>1\n            {\n                double w0 = 0.0;\n                for(int k=0;k<K;k++){\n                    double df = (double)d[task][k] - est[mem][k];\n                    if(df>0) w0 += df;\n                }\n                if(dur>1){\n                    double resid = (double)dur - w0;\n                    resid = max(-3.0, min(3.0, resid));\n                    // running average with clipping to [-1,1]\n                    bias_cnt++;\n                    double lr_b = 1.0 / min(500, bias_cnt);\n                    bias_b = (1.0 - lr_b) * bias_b + lr_b * resid;\n                    bias_b = max(-1.0, min(1.0, bias_b));\n                }\n            }\n\n            if(dur<=1){\n                for(int k=0;k<K;k++){\n                    lb[mem][k] = max(lb[mem][k], d[task][k]);\n                    est[mem][k] = max(est[mem][k], (double)d[task][k]);\n                }\n            }else{\n                // Compute deficits\n                vector<double> def(K, 0.0);\n                double W=0.0;\n                for(int k=0;k<K;k++){\n                    double df = (double)d[task][k] - est[mem][k];\n                    if(df>0){ def[k]=df; W+=df; }\n                }\n                double high = dur + 3.0;\n                if(W > high + 1e-9){\n                    double delta = W - high;\n                    // adaptive learning rate; boost when dur small (e.g., 2 or 3) and W is much larger\n                    double lr = min(0.7, 0.25 + 0.03 * max(0.0, W - high));\n                    if(dur<=3) lr = min(0.8, lr + 0.1);\n                    double step = min(delta, 8.0) * lr;\n                    double sumdef = W;\n                    if(sumdef>1e-9){\n                        for(int k=0;k<K;k++){\n                            if(def[k]>1e-12){\n                                double inc = step * (def[k]/sumdef);\n                                double capInc = max(0.0, (double)d[task][k] - est[mem][k]);\n                                if(inc > capInc) inc = capInc;\n                                est[mem][k] += inc;\n                            }\n                            if(est[mem][k] < lb[mem][k]) est[mem][k] = lb[mem][k];\n                        }\n                    }else{\n                        for(int k=0;k<K;k++){\n                            if(est[mem][k] < lb[mem][k]) est[mem][k] = lb[mem][k];\n                        }\n                    }\n                }else{\n                    // Enforce lb only\n                    for(int k=0;k<K;k++){\n                        if(est[mem][k] < lb[mem][k]) est[mem][k] = lb[mem][k];\n                    }\n                }\n            }\n\n            // Mark done and unlock successors\n            mtask[mem] = -1;\n            tstat[task]=2;\n            for(int v: g[task]){\n                if(--cur_indeg[v]==0 && tstat[v]==0){\n                    ready_flag[v]=1;\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int ax, ay, cx, cy, idx;\n    double base_score;\n};\n\nstruct Node { int x,y; int ordIdx; bool isPickup; };\n\nstatic inline int manh(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\n\nstatic inline long long routeDist(const vector<Node>& R){\n    long long t=0;\n    for(size_t i=0;i+1<R.size();++i) t += manh(R[i].x,R[i].y,R[i+1].x,R[i+1].y);\n    return t;\n}\n\nstatic inline bool precedence_ok(const vector<Node>& R, const vector<int>& selectedIdx){\n    vector<int> pidx(1001,-1), didx(1001,-1);\n    for(int k=0;k<(int)R.size();++k){\n        int id=R[k].ordIdx;\n        if(id==-1) continue;\n        if(R[k].isPickup){ if(pidx[id]==-1) pidx[id]=k; }\n        else { if(didx[id]==-1) didx[id]=k; }\n    }\n    for(int id: selectedIdx){\n        int pid = pidx[id];\n        int did = didx[id];\n        if(pid==-1 || did==-1) continue;\n        if(pid >= did) return false;\n    }\n    return true;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int DEPX=400, DEPY=400;\n    vector<Order> all;\n    all.reserve(1000);\n    for(int i=0;i<1000;i++){\n        int a,b,c,d;\n        if(!(cin>>a>>b>>c>>d)) return 0;\n        Order o; o.ax=a;o.ay=b;o.cx=c;o.cy=d;o.idx=i+1;o.base_score=0;\n        all.push_back(o);\n    }\n    if(all.size()!=1000){\n        cout<<\"0\\n1 400 400\\n\";\n        return 0;\n    }\n\n    // Base scores\n    for(auto &o: all){\n        int da = manh(DEPX,DEPY,o.ax,o.ay);\n        int ac = manh(o.ax,o.ay,o.cx,o.cy);\n        int cd = manh(o.cx,o.cy,DEPX,DEPY);\n        o.base_score = da + ac + 0.6*cd;\n    }\n\n    auto select_orders = [&](double lambda)->vector<Order>{\n        int m = 50;\n        vector<int> used(1000,0);\n        vector<Order> chosen;\n        chosen.reserve(m);\n        // initial pick\n        int besti=-1; double bestv=1e100;\n        for(int i=0;i<1000;i++){\n            double v = all[i].base_score + 0.2 * (manh(DEPX,DEPY,all[i].ax,all[i].ay) + manh(DEPX,DEPY,all[i].cx,all[i].cy));\n            if(v < bestv){ bestv=v; besti=i; }\n        }\n        used[besti]=1; chosen.push_back(all[besti]);\n\n        auto mindist_to_cluster = [&](const Order& o)->int{\n            int md = INT_MAX;\n            for(auto &c: chosen){\n                md = min(md, manh(o.ax,o.ay,c.ax,c.ay));\n                md = min(md, manh(o.ax,o.ay,c.cx,c.cy));\n                md = min(md, manh(o.cx,o.cy,c.ax,c.ay));\n                md = min(md, manh(o.cx,o.cy,c.cx,c.cy));\n            }\n            return md;\n        };\n\n        for(int k=1;k<m;k++){\n            int pick=-1; double best=1e100;\n            for(int i=0;i<1000;i++){\n                if(used[i]) continue;\n                int md = mindist_to_cluster(all[i]);\n                double val = all[i].base_score + lambda * md;\n                if(val < best){\n                    best=val; pick=i;\n                }\n            }\n            used[pick]=1; chosen.push_back(all[pick]);\n        }\n        return chosen;\n    };\n\n    auto build_greedy_pd = [&](const vector<Order>& sel)->vector<Node>{\n        unordered_map<int, Order> om;\n        om.reserve(sel.size()*2);\n        for(auto &o: sel) om[o.idx]=o;\n        vector<int> unpicked, carrying;\n        for(auto &o: sel) unpicked.push_back(o.idx);\n        int curx=DEPX, cury=DEPY;\n        vector<Node> R;\n        R.push_back({DEPX,DEPY,-1,false});\n        while(!unpicked.empty()){\n            int bestDid=-1, bestDdist=INT_MAX, dx=0,dy=0;\n            for(int id: carrying){\n                auto &o = om[id];\n                int d = manh(curx,cury,o.cx,o.cy);\n                if(d < bestDdist){ bestDdist=d; bestDid=id; dx=o.cx; dy=o.cy; }\n            }\n            int bestPid=-1, bestPdist=INT_MAX, px=0,py=0;\n            for(int id: unpicked){\n                auto &o = om[id];\n                int d = manh(curx,cury,o.ax,o.ay);\n                if(d < bestPdist){ bestPdist=d; bestPid=id; px=o.ax; py=o.ay; }\n            }\n            if(bestDid!=-1 && bestDdist <= bestPdist/3){\n                R.push_back({dx,dy,bestDid,false});\n                curx=dx; cury=dy;\n                auto it = find(carrying.begin(), carrying.end(), bestDid);\n                if(it!=carrying.end()) carrying.erase(it);\n            }else{\n                R.push_back({px,py,bestPid,true});\n                curx=px; cury=py;\n                auto it = find(unpicked.begin(), unpicked.end(), bestPid);\n                if(it!=unpicked.end()) unpicked.erase(it);\n                carrying.push_back(bestPid);\n            }\n        }\n        while(!carrying.empty()){\n            int bestDid=-1, bestDdist=INT_MAX, dx=0,dy=0;\n            for(int id: carrying){\n                auto &o = om[id];\n                int d = manh(curx,cury,o.cx,o.cy);\n                if(d < bestDdist){ bestDdist=d; bestDid=id; dx=o.cx; dy=o.cy; }\n            }\n            R.push_back({dx,dy,bestDid,false});\n            curx=dx; cury=dy;\n            auto it = find(carrying.begin(), carrying.end(), bestDid);\n            if(it!=carrying.end()) carrying.erase(it);\n        }\n        R.push_back({DEPX,DEPY,-1,false});\n        return R;\n    };\n\n    auto build_insertion = [&](const vector<Order>& sel)->vector<Node>{\n        vector<Node> R;\n        R.push_back({DEPX,DEPY,-1,false});\n        R.push_back({DEPX,DEPY,-1,false});\n        // insert pickups\n        for(auto &o: sel){\n            Node P{ o.ax, o.ay, o.idx, true };\n            long long bestInc = (1LL<<60);\n            int bestPos = 1;\n            for(int pos=1; pos<(int)R.size(); ++pos){\n                long long d0 = manh(R[pos-1].x,R[pos-1].y,R[pos].x,R[pos].y);\n                long long d1 = manh(R[pos-1].x,R[pos-1].y,P.x,P.y) + manh(P.x,P.y,R[pos].x,R[pos].y);\n                long long inc = d1 - d0;\n                if(inc < bestInc){\n                    bestInc = inc; bestPos = pos;\n                }\n            }\n            R.insert(R.begin()+bestPos, P);\n        }\n        // insert drops\n        for(auto &o: sel){\n            Node D{ o.cx, o.cy, o.idx, false };\n            int pidx=-1;\n            for(int i=0;i<(int)R.size();++i){\n                if(R[i].ordIdx==o.idx && R[i].isPickup){ pidx=i; break; }\n            }\n            long long bestInc = (1LL<<60);\n            int bestPos = pidx+1;\n            for(int pos=pidx+1; pos<(int)R.size(); ++pos){\n                long long d0 = manh(R[pos-1].x,R[pos-1].y,R[pos].x,R[pos].y);\n                long long d1 = manh(R[pos-1].x,R[pos-1].y,D.x,D.y) + manh(D.x,D.y,R[pos].x,R[pos].y);\n                long long inc = d1 - d0;\n                if(inc < bestInc){\n                    bestInc = inc; bestPos = pos;\n                }\n            }\n            R.insert(R.begin()+bestPos, D);\n        }\n        // ensure ends\n        if(!(R.front().x==DEPX && R.front().y==DEPY)) R.insert(R.begin(), {DEPX,DEPY,-1,false});\n        if(!(R.back().x==DEPX && R.back().y==DEPY)) R.push_back({DEPX,DEPY,-1,false});\n        return R;\n    };\n\n    auto two_opt = [&](vector<Node>& R, const vector<int>& ids){\n        bool improved=true;\n        int iter=0;\n        while(improved && iter<200){\n            improved=false; iter++;\n            long long bestGain=0;\n            int bi=-1,bj=-1;\n            for(int i=1;i+2<(int)R.size();++i){\n                for(int j=i+1;j+1<(int)R.size();++j){\n                    long long d0 = manh(R[i-1].x,R[i-1].y,R[i].x,R[i].y)\n                                  + manh(R[j].x,R[j].y,R[j+1].x,R[j+1].y);\n                    long long d1 = manh(R[i-1].x,R[i-1].y,R[j].x,R[j].y)\n                                  + manh(R[i].x,R[i].y,R[j+1].x,R[j+1].y);\n                    long long gain = d0 - d1;\n                    if(gain > bestGain){\n                        reverse(R.begin()+i, R.begin()+j+1);\n                        if(precedence_ok(R, ids)){\n                            bestGain = gain;\n                            bi=i; bj=j;\n                        }\n                        reverse(R.begin()+i, R.begin()+j+1);\n                    }\n                }\n            }\n            if(bestGain > 0 && bi!=-1){\n                reverse(R.begin()+bi, R.begin()+bj+1);\n                improved=true;\n            }\n        }\n    };\n\n    auto or_opt12 = [&](vector<Node>& R, const vector<int>& ids){\n        bool improved=true;\n        int iter=0;\n        while(improved && iter<120){\n            improved=false; iter++;\n            long long curL = routeDist(R);\n            int N = (int)R.size();\n            for(int len=1; len<=2; ++len){\n                bool applied=false;\n                for(int i=1; i+len <= N-1; ++i){\n                    if(i <= 0 || i+len-1 >= N-1) continue; // avoid endpoints\n                    vector<Node> seg(R.begin()+i, R.begin()+i+len);\n                    vector<Node> T;\n                    T.reserve(N);\n                    T.insert(T.end(), R.begin(), R.begin()+i);\n                    T.insert(T.end(), R.begin()+i+len, R.end());\n                    for(int j=1; j <= (int)T.size()-1; ++j){\n                        if(j==i) continue;\n                        if(j >= (int)T.size()) break;\n                        if(j > (int)T.size()-1) continue;\n                        vector<Node> W=T;\n                        int jj = min(j, (int)W.size()-1);\n                        W.insert(W.begin()+jj, seg.begin(), seg.end());\n                        if(!precedence_ok(W, ids)) continue;\n                        if(!(W.front().x==DEPX && W.front().y==DEPY)) continue;\n                        if(!(W.back().x==DEPX && W.back().y==DEPY)) continue;\n                        long long newL = routeDist(W);\n                        if(newL < curL){\n                            R.swap(W);\n                            improved=true; applied=true;\n                            N = (int)R.size();\n                            break;\n                        }\n                    }\n                    if(applied) break;\n                }\n                if(improved) break;\n            }\n        }\n    };\n\n    auto relocate_pair = [&](vector<Node>& R, const vector<int>& ids){\n        bool improved=true;\n        int attempts=0;\n        while(improved && attempts<80){\n            improved=false; attempts++;\n            long long curL = routeDist(R);\n            bool applied=false;\n            int N = (int)R.size();\n            for(int id: ids){\n                int pid=-1,did=-1;\n                for(int i=0;i<N;i++){\n                    if(R[i].ordIdx==id){\n                        if(R[i].isPickup) pid=i;\n                        else did=i;\n                    }\n                }\n                if(pid==-1 || did==-1 || pid>=did) continue;\n                for(int dp=-3; dp<=3; ++dp){\n                    int ppos = min(max(1, pid+dp), N-2); // keep pickup away from endpoints\n                    for(int dd=-3; dd<=3; ++dd){\n                        int dposRaw = did+dd;\n                        vector<Node> T = R;\n                        Node P = T[pid], D=T[did];\n                        if(pid<did){\n                            T.erase(T.begin()+did);\n                            T.erase(T.begin()+pid);\n                        }else{\n                            T.erase(T.begin()+pid);\n                            T.erase(T.begin()+did);\n                        }\n                        int Np = (int)T.size();\n                        int pposClamped = min(max(1, ppos), Np-1); // insert before last depot\n                        T.insert(T.begin()+pposClamped, P);\n                        int Nq = (int)T.size();\n                        int dbase = min(max(pposClamped+1, dposRaw), Nq-1);\n                        int dpos = dbase;\n                        if(dpos <= pposClamped) dpos = pposClamped+1;\n                        if(dpos >= Nq) dpos = Nq-1; // avoid last depot\n                        T.insert(T.begin()+dpos, D);\n                        if(!(T.front().x==DEPX && T.front().y==DEPY)) continue;\n                        if(!(T.back().x==DEPX && T.back().y==DEPY)) continue;\n                        if(!precedence_ok(T, ids)) continue;\n                        long long newL = routeDist(T);\n                        if(newL < curL){\n                            R.swap(T);\n                            improved=true; applied=true;\n                            N = (int)R.size();\n                            break;\n                        }\n                    }\n                    if(applied) break;\n                }\n                if(applied) break;\n            }\n        }\n    };\n\n    const int tries = 3;\n    vector<double> lambdas = {-0.8, -0.5, -0.2};\n    long long bestLen = (1LL<<60);\n    vector<Node> bestRoute;\n    vector<int> bestIds;\n\n    for(int t=0;t<tries;t++){\n        auto sel = select_orders(lambdas[t%lambdas.size()]);\n        vector<int> ids; ids.reserve(sel.size());\n        for(auto &o: sel) ids.push_back(o.idx);\n\n        auto R1 = build_greedy_pd(sel);\n        auto R2 = build_insertion(sel);\n        if(!precedence_ok(R2, ids)) R2 = R1;\n\n        auto refine = [&](vector<Node>& R){\n            if(!(R.front().x==DEPX && R.front().y==DEPY)) R.insert(R.begin(), {DEPX,DEPY,-1,false});\n            if(!(R.back().x==DEPX && R.back().y==DEPY)) R.push_back({DEPX,DEPY,-1,false});\n            two_opt(R, ids);\n            or_opt12(R, ids);\n            relocate_pair(R, ids);\n            two_opt(R, ids);\n            if(!(R.front().x==DEPX && R.front().y==DEPY)) R.front() = {DEPX,DEPY,-1,false};\n            if(!(R.back().x==DEPX && R.back().y==DEPY)) R.back() = {DEPX,DEPY,-1,false};\n        };\n        refine(R1);\n        refine(R2);\n\n        long long d1 = routeDist(R1);\n        long long d2 = routeDist(R2);\n        if(d1 < bestLen){\n            bestLen = d1;\n            bestRoute = R1;\n            bestIds = ids;\n        }\n        if(d2 < bestLen){\n            bestLen = d2;\n            bestRoute = R2;\n            bestIds = ids;\n        }\n    }\n\n    if(bestRoute.empty() || !(bestRoute.front().x==DEPX && bestRoute.front().y==DEPY)){\n        bestRoute.insert(bestRoute.begin(), {DEPX,DEPY,-1,false});\n    }\n    if(!(bestRoute.back().x==DEPX && bestRoute.back().y==DEPY)){\n        bestRoute.push_back({DEPX,DEPY,-1,false});\n    }\n\n    cout<<bestIds.size();\n    for(int id: bestIds) cout<<\" \"<<id;\n    cout<<\"\\n\";\n    cout<<bestRoute.size();\n    for(auto &nd: bestRoute){\n        cout<<\" \"<<nd.x<<\" \"<<nd.y;\n    }\n    cout<<\"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    int comps;\n    DSU(int n=0): n(n), p(n), r(n,0), comps(n) { iota(p.begin(), p.end(), 0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool same(int a,int b){ return find(a)==find(b); }\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        comps--;\n        return true;\n    }\n};\n\nstruct Edge {\n    int idx;\n    int u,v;\n    int d; // prior rounded Euclidean 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    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++){\n        if(!(cin>>x[i]>>y[i])) return 0;\n    }\n    vector<int> U(M), V(M);\n    for(int i=0;i<M;i++){\n        cin>>U[i]>>V[i];\n    }\n\n    auto rd = [&](int i)->int{\n        long long dx = x[U[i]] - x[V[i]];\n        long long dy = y[U[i]] - y[V[i]];\n        double dist = sqrt((double)(dx*dx + dy*dy));\n        return (int)llround(dist);\n    };\n\n    vector<Edge> edges(M);\n    for(int i=0;i<M;i++){\n        edges[i] = {i, U[i], V[i], rd(i)};\n    }\n\n    // Build 5 disjoint MST layers using d as weight\n    vector<int> layer(M, -1);\n    for(int lay=0; lay<5; lay++){\n        vector<int> avail;\n        avail.reserve(M);\n        for(int ei=0; ei<M; ei++){\n            if(layer[ei]==-1) avail.push_back(ei);\n        }\n        sort(avail.begin(), avail.end(), [&](int a, int b){\n            if(edges[a].d != edges[b].d) return edges[a].d < edges[b].d;\n            if(edges[a].u != edges[b].u) return edges[a].u < edges[b].u;\n            return edges[a].v < edges[b].v;\n        });\n        DSU dsu(N);\n        int taken = 0;\n        for(int eid: avail){\n            int u = edges[eid].u, v = edges[eid].v;\n            if(!dsu.same(u,v)){\n                dsu.unite(u,v);\n                layer[eid] = lay;\n                taken++;\n                if(taken == N-1) break;\n            }\n        }\n        // As per generation, this will assign exactly N-1 edges per layer\n    }\n\n    // Online phase with guaranteed connectivity via backup layer\n    DSU cur(N);\n\n    int backup_layer = 0; // rely on the base MST layer by d as guaranteed backbone\n\n    // Strict acceptance multipliers for non-backup layers (prefer very good edges only)\n    array<double,5> beta;\n    beta[0]=1.25; beta[1]=1.20; beta[2]=1.15; beta[3]=1.10; beta[4]=1.05;\n\n    for(int i=0;i<M;i++){\n        int l_i;\n        if(!(cin>>l_i)) return 0;\n\n        int u = U[i], v = V[i];\n        int d = edges[i].d;\n        int lay = layer[i];\n        if(lay < 0 || lay > 4) lay = 4; // fallback, shouldn't happen\n\n        bool accept = false;\n        if(cur.same(u,v)){\n            accept = false;\n        }else{\n            if(lay == backup_layer){\n                // Unconditional acceptance for backup layer cross edges ensures connectivity\n                accept = true;\n            }else{\n                // Only accept clearly cheap edges from other layers\n                double mul = beta[lay];\n                if((double)l_i <= mul * (double)d) accept = true;\n            }\n        }\n\n        if(accept){\n            if(!cur.same(u,v)) cur.unite(u,v);\n            cout << 1 << '\\n';\n        }else{\n            cout << 0 << '\\n';\n        }\n        cout.flush();\n    }\n\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int H = 30, W = 30;\n\nstruct Pet { int x,y,t; };\nstruct Human {\n    int x,y;\n    int orient; // 0=horizontal, 1=vertical\n    int line;   // row if horizontal, col if vertical\n    int stand;  // stand row if horizontal, stand col if vertical\n    int L, R;   // sweep range along the axis\n    int dir;    // +1 forward, -1 backward\n    int lastTargetPos = -1; // last target coordinate along axis (y for horizontal, x for vertical)\n    int targetStallCnt = 0; // consecutive turns we targeted same position but unsafe (pet-adj)\n};\n\ninline bool inb(int x,int y){ return 1<=x && x<=H && 1<=y && y<=W; }\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N; if(!(cin>>N)) return 0;\n    vector<Pet> pets(N);\n    for(int i=0;i<N;i++){\n        int px,py,pt; cin>>px>>py>>pt;\n        pets[i]={px,py,pt};\n    }\n    int M; cin>>M;\n    vector<Human> humans(M);\n    for(int i=0;i<M;i++){\n        int hx,hy; cin>>hx>>hy;\n        humans[i].x=hx; humans[i].y=hy;\n        humans[i].orient=0; humans[i].line=6; humans[i].stand=5;\n        humans[i].L=1; humans[i].R=W; humans[i].dir=+1;\n        humans[i].lastTargetPos=-1; humans[i].targetStallCnt=0;\n    }\n\n    vector<vector<bool>> blocked(H+1, vector<bool>(W+1,false));\n    vector<vector<int>> petCnt(H+1, vector<int>(W+1,0));\n    for(auto &p: pets) petCnt[p.x][p.y]++;\n\n    auto line_pet_score = [&](int orient, int line, int L, int R)->int{\n        int score=0;\n        if(orient==0){\n            for(int y=L;y<=R;y++){\n                int x=line; if(!inb(x,y)) continue;\n                score += petCnt[x][y];\n                static const int dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};\n                for(int k=0;k<4;k++){\n                    int nx=x+dx[k], ny=y+dy[k];\n                    if(inb(nx,ny)) score += (petCnt[nx][ny]>0);\n                }\n            }\n        }else{\n            for(int x=L;x<=R;x++){\n                int y=line; if(!inb(x,y)) continue;\n                score += petCnt[x][y];\n                static const int dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};\n                for(int k=0;k<4;k++){\n                    int nx=x+dx[k], ny=y+dy[k];\n                    if(inb(nx,ny)) score += (petCnt[nx][ny]>0);\n                }\n            }\n        }\n        return score;\n    };\n\n    // Select line per human with travel bias\n    vector<int> bases = {6,12,18,24};\n    for(int i=0;i<M;i++){\n        int hx=humans[i].x, hy=humans[i].y;\n        int sweepLen = 10;\n        int best_orient=0, best_line=6, best_stand=5, bestL=1, bestR=W;\n        int bestScore = INT_MAX;\n        // horizontal candidates\n        for(int r: bases){\n            int stand = r-1; if(stand<1) stand=r+1;\n            int L = max(1, hy - sweepLen/2);\n            int R = min(W, L + sweepLen - 1);\n            L = max(1, min(L, W - sweepLen + 1));\n            int sc = line_pet_score(0, r, L, R) + 2*abs(hx - stand);\n            if(sc < bestScore){\n                bestScore=sc; best_orient=0; best_line=r; best_stand=stand; bestL=L; bestR=R;\n            }\n        }\n        // vertical candidates\n        for(int c: bases){\n            int stand = c-1; if(stand<1) stand=c+1;\n            int L = max(1, hx - sweepLen/2);\n            int R = min(H, L + sweepLen - 1);\n            L = max(1, min(L, H - sweepLen + 1));\n            int sc = line_pet_score(1, c, L, R) + 2*abs(hy - stand);\n            if(sc < bestScore){\n                bestScore=sc; best_orient=1; best_line=c; best_stand=stand; bestL=L; bestR=R;\n            }\n        }\n        humans[i].orient=best_orient; humans[i].line=best_line; humans[i].stand=best_stand;\n        humans[i].L=bestL; humans[i].R=bestR;\n        if(humans[i].orient==0){\n            humans[i].dir = (abs(humans[i].y - humans[i].L) <= abs(humans[i].y - humans[i].R)) ? +1 : -1;\n        }else{\n            humans[i].dir = (abs(humans[i].x - humans[i].L) <= abs(humans[i].x - humans[i].R)) ? +1 : -1;\n        }\n    }\n\n    auto safe_to_block = [&](int tx,int ty, const vector<Human>& hs)->bool{\n        if(!inb(tx,ty)) return false;\n        if(blocked[tx][ty]) return false;\n        if(petCnt[tx][ty]>0) return false;\n        // cannot block a square that contains humans at start of turn\n        for(const auto& h: hs) if(h.x==tx && h.y==ty) return false;\n        // cannot block a square whose adjacent square contains a pet\n        static const int dx[4]={-1,1,0,0};\n        static const int dy[4]={0,0,-1,1};\n        for(int k=0;k<4;k++){\n            int nx=tx+dx[k], ny=ty+dy[k];\n            if(inb(nx,ny) && petCnt[nx][ny]>0) return false;\n        }\n        return true;\n    };\n\n    auto pet_adjacent = [&](int tx,int ty)->bool{\n        static const int dx[4]={-1,1,0,0};\n        static const int dy[4]={0,0,-1,1};\n        for(int k=0;k<4;k++){\n            int nx=tx+dx[k], ny=ty+dy[k];\n            if(inb(nx,ny) && petCnt[nx][ny]>0) return true;\n        }\n        return false;\n    };\n\n    auto blocked_ratio = [&](const Human& h)->double{\n        int tot=0, b=0;\n        if(h.orient==0){\n            for(int y=h.L; y<=h.R; y++){ tot++; if(blocked[h.line][y]) b++; }\n        }else{\n            for(int x=h.L; x<=h.R; x++){ tot++; if(blocked[x][h.line]) b++; }\n        }\n        if(tot==0) return 0.0;\n        return (double)b / tot;\n    };\n\n    auto segment_pet_score = [&](int orient, int line, int L, int R)->int{\n        int s=0;\n        if(orient==0){ for(int y=L;y<=R;y++) s+= petCnt[line][y]; }\n        else { for(int x=L;x<=R;x++) s+= petCnt[x][line]; }\n        return s;\n    };\n\n    // Soft de-duplication: nudge segments to reduce heavy overlap\n    auto reduce_overlap = [&](int maxShift){\n        for(int i=0;i<M;i++){\n            for(int j=i+1;j<M;j++){\n                if(humans[i].orient!=humans[j].orient) continue;\n                if(humans[i].line!=humans[j].line) continue;\n                int Li=humans[i].L, Ri=humans[i].R;\n                int Lj=humans[j].L, Rj=humans[j].R;\n                int overlap = max(0, min(Ri,Rj) - max(Li,Lj) + 1);\n                int leni = max(0, Ri-Li+1), lenj = max(0, Rj-Lj+1);\n                int smaller = min(leni, lenj);\n                if(smaller<=0) continue;\n                if(overlap*10 >= 6*smaller){ // >60%\n                    int ci=(Li+Ri)/2, cj=(Lj+Rj)/2;\n                    if(humans[i].orient==0){\n                        if(ci<=cj){\n                            int shift = min(maxShift, Li-1);\n                            humans[i].L = max(1, Li - shift);\n                            humans[i].R = max(humans[i].L, Ri - shift);\n                        }else{\n                            int shift = min(maxShift, W - Rj);\n                            humans[j].R = min(W, Rj + shift);\n                            humans[j].L = min(humans[j].R, Lj + shift);\n                        }\n                    }else{\n                        if(ci<=cj){\n                            int shift = min(maxShift, Li-1);\n                            humans[i].L = max(1, Li - shift);\n                            humans[i].R = max(humans[i].L, Ri - shift);\n                        }else{\n                            int shift = min(maxShift, H - Rj);\n                            humans[j].R = min(H, Rj + shift);\n                            humans[j].L = min(humans[j].R, Lj + shift);\n                        }\n                    }\n                }\n            }\n        }\n    };\n\n    // Direction synchronization among humans on same line: alternate sweep directions\n    auto sync_directions = [&](){\n        map<pair<int,int>, vector<int>> groups;\n        for(int i=0;i<M;i++) groups[{humans[i].orient, humans[i].line}].push_back(i);\n        for(auto &kv: groups){\n            auto &vec = kv.second;\n            if(vec.size()<=1) continue;\n            if(kv.first.first==0){ // horizontal: sort by y\n                sort(vec.begin(), vec.end(), [&](int a,int b){ return humans[a].y < humans[b].y; });\n                for(size_t idx=0; idx<vec.size(); idx++){\n                    int i = vec[idx];\n                    humans[i].dir = (idx%2==0 ? -1 : +1);\n                }\n            }else{ // vertical: sort by x\n                sort(vec.begin(), vec.end(), [&](int a,int b){ return humans[a].x < humans[b].x; });\n                for(size_t idx=0; idx<vec.size(); idx++){\n                    int i = vec[idx];\n                    humans[i].dir = (idx%2==0 ? -1 : +1);\n                }\n            }\n        }\n    };\n\n    // Apply de-dup and dir sync at start\n    reduce_overlap(2);\n    sync_directions();\n\n    auto willBlockCancelMoves = [&](string &actions){\n        vector<vector<bool>> willBlock(H+1, vector<bool>(W+1,false));\n        for(int i=0;i<M;i++){\n            char c=actions[i];\n            if(c=='u'||c=='d'||c=='l'||c=='r'){\n                int tx=humans[i].x, ty=humans[i].y;\n                if(c=='u') tx--; else if(c=='d') tx++; else if(c=='l') ty--; else if(c=='r') ty++;\n                if(inb(tx,ty)) willBlock[tx][ty]=true;\n            }\n        }\n        for(int i=0;i<M;i++){\n            char c=actions[i];\n            if(c=='U'||c=='D'||c=='L'||c=='R'){\n                int nx=humans[i].x, ny=humans[i].y;\n                if(c=='U') nx--; else if(c=='D') nx++; else if(c=='L') ny--; else if(c=='R') ny++;\n                if(inb(nx,ny) && willBlock[nx][ny]) actions[i]='.';\n            }\n        }\n    };\n\n    for(int turn=0; turn<300; turn++){\n        if(turn==60){ reduce_overlap(2); sync_directions(); }\n        if(turn==100){ reduce_overlap(3); sync_directions(); }\n\n        string actions(M, '.');\n\n        // Expand segment ranges when almost done to connect pieces\n        for(int i=0;i<M;i++){\n            auto &h = humans[i];\n            if(blocked_ratio(h) >= 0.7){\n                if(h.orient==0){\n                    int more=3;\n                    int leftScore = (h.L>1)? (segment_pet_score(0, h.line, max(1,h.L-more), h.L-1)) : 1e9;\n                    int rightScore = (h.R<W)? (segment_pet_score(0, h.line, h.R+1, min(W,h.R+more))) : 1e9;\n                    if(leftScore < rightScore && h.L>1){\n                        int shift = min(more, h.L-1);\n                        h.L -= shift;\n                    }else if(h.R<W){\n                        int shift = min(more, W-h.R);\n                        h.R += shift;\n                    }\n                }else{\n                    int more=3;\n                    int upScore = (h.L>1)? (segment_pet_score(1, h.line, max(1,h.L-more), h.L-1)) : 1e9;\n                    int downScore = (h.R<H)? (segment_pet_score(1, h.line, h.R+1, min(H,h.R+more))) : 1e9;\n                    if(upScore < downScore && h.L>1){\n                        int shift=min(more, h.L-1);\n                        h.L -= shift;\n                    }else if(h.R<H){\n                        int shift=min(more, H-h.R);\n                        h.R += shift;\n                    }\n                }\n            }\n        }\n\n        bool gapPhase = (turn >= 80);\n\n        for(int i=0;i<M;i++){\n            auto &h = humans[i];\n\n            if(h.orient==0){\n                // align to stand row\n                if(h.x != h.stand){\n                    if(h.x > h.stand && inb(h.x-1,h.y) && !blocked[h.x-1][h.y]) { actions[i]='U'; continue; }\n                    if(h.x < h.stand && inb(h.x+1,h.y) && !blocked[h.x+1][h.y]) { actions[i]='D'; continue; }\n                    actions[i]='.'; continue;\n                }\n                // move into segment if outside\n                if(h.y < h.L){\n                    if(!blocked[h.x][h.y+1]) { actions[i]='R'; continue; }\n                    actions[i]='.'; continue;\n                }\n                if(h.y > h.R){\n                    if(!blocked[h.x][h.y-1]) { actions[i]='L'; continue; }\n                    actions[i]='.'; continue;\n                }\n\n                int tx=h.line, ty=h.y;\n                char place = (h.stand < h.line ? 'd' : 'u');\n\n                bool hereSafe = safe_to_block(tx,ty, humans);\n                bool hereAdj = pet_adjacent(tx,ty);\n\n                if(hereSafe && !hereAdj){\n                    actions[i]=place; h.lastTargetPos=ty; h.targetStallCnt=0; continue;\n                }\n\n                if(gapPhase){\n                    int rad=8;\n                    int bestGrade=-1, bestDist=1e9, bestCy=-1, bestCenter=1e9;\n                    int centerY = W/2;\n                    for(int cy=h.L; cy<=h.R; cy++){\n                        int dy = cy - h.y;\n                        if(abs(dy) > rad) continue;\n                        int ttx=tx, tty=cy;\n                        if(blocked[ttx][tty]) continue;\n                        if(!safe_to_block(ttx,tty, humans) || pet_adjacent(ttx,tty)) continue;\n                        int adj=0;\n                        if(inb(ttx,tty-1) && blocked[ttx][tty-1]) adj++;\n                        if(inb(ttx,tty+1) && blocked[ttx][tty+1]) adj++;\n                        int grade = (adj==2?2:(adj==1?1:0));\n                        int dist = abs(dy);\n                        int centerDist = abs(cy - centerY);\n                        if(grade > bestGrade || (grade==bestGrade && (dist < bestDist || (dist==bestDist && centerDist < bestCenter)))){\n                            bestGrade=grade; bestDist=dist; bestCy=cy; bestCenter=centerDist;\n                        }\n                    }\n                    if(bestCy!=-1){\n                        if(h.lastTargetPos == bestCy) {\n                            if(!hereSafe || hereAdj) h.targetStallCnt = min(h.targetStallCnt+1, 8);\n                        } else {\n                            h.lastTargetPos = bestCy; h.targetStallCnt = 0;\n                        }\n                        // If stalled many turns, skip past by 2 cells if possible to work elsewhere\n                        if(h.targetStallCnt >= 5){\n                            if(bestCy > h.y){\n                                if(h.y+2<=h.R && !blocked[h.x][h.y+1] && !blocked[h.x][h.y+2]) { actions[i]='R'; continue; }\n                                if(h.y < h.R && !blocked[h.x][h.y+1]) { actions[i]='R'; continue; }\n                            }else{\n                                if(h.y-2>=h.L && !blocked[h.x][h.y-1] && !blocked[h.x][h.y-2]) { actions[i]='L'; continue; }\n                                if(h.y > h.L && !blocked[h.x][h.y-1]) { actions[i]='L'; continue; }\n                            }\n                        }\n                        if(bestCy > h.y && !blocked[h.x][h.y+1]) { actions[i]='R'; continue; }\n                        if(bestCy < h.y && !blocked[h.x][h.y-1]) { actions[i]='L'; continue; }\n                    }\n                }\n\n                if(hereSafe && hereAdj){\n                    if(h.y < h.R && !blocked[h.x][h.y+1]) { actions[i]='R'; continue; }\n                    if(h.y > h.L && !blocked[h.x][h.y-1]) { actions[i]='L'; continue; }\n                }\n\n                // default sweep\n                if(h.dir>0){\n                    if(h.y < h.R && !blocked[h.x][h.y+1]) actions[i]='R';\n                    else {\n                        h.dir=-1;\n                        if(h.y > h.L && !blocked[h.x][h.y-1]) actions[i]='L';\n                        else actions[i]='.';\n                    }\n                }else{\n                    if(h.y > h.L && !blocked[h.x][h.y-1]) actions[i]='L';\n                    else {\n                        h.dir=+1;\n                        if(h.y < h.R && !blocked[h.x][h.y+1]) actions[i]='R';\n                        else actions[i]='.';\n                    }\n                }\n            }else{\n                // vertical\n                if(h.y != h.stand){\n                    if(h.y > h.stand && inb(h.x,h.y-1) && !blocked[h.x][h.y-1]) { actions[i]='L'; continue; }\n                    if(h.y < h.stand && inb(h.x,h.y+1) && !blocked[h.x][h.y+1]) { actions[i]='R'; continue; }\n                    actions[i]='.'; continue;\n                }\n                if(h.x < h.L){\n                    if(!blocked[h.x+1][h.y]) { actions[i]='D'; continue; }\n                    actions[i]='.'; continue;\n                }\n                if(h.x > h.R){\n                    if(!blocked[h.x-1][h.y]) { actions[i]='U'; continue; }\n                    actions[i]='.'; continue;\n                }\n\n                int tx=h.x, ty=h.line;\n                char place = (h.stand < h.line ? 'r' : 'l');\n\n                bool hereSafe = safe_to_block(tx,ty, humans);\n                bool hereAdj = pet_adjacent(tx,ty);\n\n                if(hereSafe && !hereAdj){\n                    actions[i]=place; h.lastTargetPos=tx; h.targetStallCnt=0; continue;\n                }\n\n                if(gapPhase){\n                    int rad=8;\n                    int bestGrade=-1, bestDist=1e9, bestCx=-1, bestCenter=1e9;\n                    int centerX = H/2;\n                    for(int cx=h.L; cx<=h.R; cx++){\n                        int dx = cx - h.x;\n                        if(abs(dx) > rad) continue;\n                        int ttx=cx, tty=ty;\n                        if(blocked[ttx][tty]) continue;\n                        if(!safe_to_block(ttx,tty, humans) || pet_adjacent(ttx,tty)) continue;\n                        int adj=0;\n                        if(inb(ttx-1,tty) && blocked[ttx-1][tty]) adj++;\n                        if(inb(ttx+1,tty) && blocked[ttx+1][tty]) adj++;\n                        int grade=(adj==2?2:(adj==1?1:0));\n                        int dist=abs(dx);\n                        int centerDist = abs(cx - centerX);\n                        if(grade > bestGrade || (grade==bestGrade && (dist < bestDist || (dist==bestDist && centerDist < bestCenter)))){\n                            bestGrade=grade; bestDist=dist; bestCx=cx; bestCenter=centerDist;\n                        }\n                    }\n                    if(bestCx!=-1){\n                        if(h.lastTargetPos == bestCx) {\n                            if(!hereSafe || hereAdj) h.targetStallCnt = min(h.targetStallCnt+1, 8);\n                        } else {\n                            h.lastTargetPos = bestCx; h.targetStallCnt = 0;\n                        }\n                        if(h.targetStallCnt >= 5){\n                            if(bestCx > h.x){\n                                if(h.x+2<=h.R && !blocked[h.x+1][h.y] && !blocked[h.x+2][h.y]) { actions[i]='D'; continue; }\n                                if(h.x < h.R && !blocked[h.x+1][h.y]) { actions[i]='D'; continue; }\n                            }else{\n                                if(h.x-2>=h.L && !blocked[h.x-1][h.y] && !blocked[h.x-2][h.y]) { actions[i]='U'; continue; }\n                                if(h.x > h.L && !blocked[h.x-1][h.y]) { actions[i]='U'; continue; }\n                            }\n                        }\n                        if(bestCx > h.x && !blocked[h.x+1][h.y]) { actions[i]='D'; continue; }\n                        if(bestCx < h.x && !blocked[h.x-1][h.y]) { actions[i]='U'; continue; }\n                    }\n                }\n\n                if(hereSafe && hereAdj){\n                    if(h.x < h.R && !blocked[h.x+1][h.y]) { actions[i]='D'; continue; }\n                    if(h.x > h.L && !blocked[h.x-1][h.y]) { actions[i]='U'; continue; }\n                }\n\n                if(h.dir>0){\n                    if(h.x < h.R && !blocked[h.x+1][h.y]) actions[i]='D';\n                    else { h.dir=-1; if(h.x > h.L && !blocked[h.x-1][h.y]) actions[i]='U'; else actions[i]='.'; }\n                }else{\n                    if(h.x > h.L && !blocked[h.x-1][h.y]) actions[i]='U';\n                    else { h.dir=+1; if(h.x < h.R && !blocked[h.x+1][h.y]) actions[i]='D'; else actions[i]='.'; }\n                }\n            }\n        }\n\n        // Prevent moving into a cell that will be blocked this turn\n        vector<vector<bool>> willBlock(H+1, vector<bool>(W+1,false));\n        for(int i=0;i<M;i++){\n            char c=actions[i];\n            if(c=='u'||c=='d'||c=='l'||c=='r'){\n                int tx=humans[i].x, ty=humans[i].y;\n                if(c=='u') tx--; else if(c=='d') tx++; else if(c=='l') ty--; else if(c=='r') ty++;\n                if(inb(tx,ty)) willBlock[tx][ty]=true;\n            }\n        }\n        for(int i=0;i<M;i++){\n            char c=actions[i];\n            if(c=='U'||c=='D'||c=='L'||c=='R'){\n                int nx=humans[i].x, ny=humans[i].y;\n                if(c=='U') nx--; else if(c=='D') nx++; else if(c=='L') ny--; else if(c=='R') ny++;\n                if(inb(nx,ny) && willBlock[nx][ny]) actions[i]='.';\n            }\n        }\n\n        // Output\n        cout<<actions<<\"\\n\";\n        cout.flush();\n\n        // Apply blocks locally\n        for(int i=0;i<M;i++){\n            char c=actions[i];\n            if(c=='u'||c=='d'||c=='l'||c=='r'){\n                int tx=humans[i].x, ty=humans[i].y;\n                if(c=='u') tx--; else if(c=='d') tx++; else if(c=='l') ty--; else if(c=='r') ty++;\n                if(inb(tx,ty)) blocked[tx][ty]=true;\n            }\n        }\n        // Apply moves locally\n        for(int i=0;i<M;i++){\n            char c=actions[i];\n            int nx=humans[i].x, ny=humans[i].y;\n            if(c=='U') nx--; else if(c=='D') nx++; else if(c=='L') ny--; else if(c=='R') ny++;\n            if(inb(nx,ny) && !blocked[nx][ny]){ humans[i].x=nx; humans[i].y=ny; }\n        }\n\n        // Read pets moves and update positions\n        vector<string> pm(N);\n        for(int i=0;i<N;i++) cin>>pm[i];\n        for(int x=1;x<=H;x++) for(int y=1;y<=W;y++) petCnt[x][y]=0;\n        for(int i=0;i<N;i++){\n            for(char c: pm[i]){\n                int nx=pets[i].x, ny=pets[i].y;\n                if(c=='U') nx--; else if(c=='D') nx++; else if(c=='L') ny--; else if(c=='R') ny++;\n                if(inb(nx,ny)) { pets[i].x=nx; pets[i].y=ny; }\n            }\n            petCnt[pets[i].x][pets[i].y]++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int si,sj,ti,tj;\n    double p;\n    if(!(cin>>si>>sj>>ti>>tj>>p)) return 0;\n    vector<string> h(20), v(19);\n    for(int i=0;i<20;i++){\n        cin>>h[i];\n    }\n    for(int i=0;i<19;i++){\n        cin>>v[i];\n    }\n    auto inb = [](int x,int y){ return 0<=x && x<20 && 0<=y && y<20; };\n    auto can_move = [&](int x,int y,int nx,int ny)->bool{\n        if(!inb(nx,ny)) return false;\n        if(nx==x && ny==y+1){\n            return h[x][y]=='0';\n        }\n        if(nx==x && ny==y-1){\n            return h[x][y-1]=='0';\n        }\n        if(nx==x+1 && ny==y){\n            return v[x][y]=='0';\n        }\n        if(nx==x-1 && ny==y){\n            return v[x-1][y]=='0';\n        }\n        return false;\n    };\n    // BFS shortest path\n    const int N=20;\n    vector<vector<int>> dist(N, vector<int>(N, INT_MAX));\n    vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N, {-1,-1}));\n    queue<pair<int,int>> q;\n    dist[si][sj]=0;\n    q.push({si,sj});\n    int dx[4]={-1,1,0,0};\n    int dy[4]={0,0,-1,1};\n    char dc[4] = {'U','D','L','R'};\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        if(x==ti && y==tj) break;\n        for(int d=0;d<4;d++){\n            int nx=x+dx[d], ny=y+dy[d];\n            if(!inb(nx,ny)) continue;\n            if(!can_move(x,y,nx,ny)) continue;\n            if(dist[nx][ny] > dist[x][y] + 1){\n                dist[nx][ny] = dist[x][y] + 1;\n                par[nx][ny] = {x,y};\n                q.push({nx,ny});\n            }\n        }\n    }\n    // Reconstruct path\n    vector<pair<int,int>> path;\n    int cx=ti, cy=tj;\n    while(!(cx==si && cy==sj) && cx!=-1){\n        path.push_back({cx,cy});\n        auto pr = par[cx][cy];\n        cx = pr.first; cy = pr.second;\n    }\n    path.push_back({si,sj});\n    reverse(path.begin(), path.end());\n    // If BFS somehow fails (shouldn't), fallback to simple greedy without walls\n    vector<char> dirs;\n    if((int)path.size()>=2){\n        for(size_t k=1;k<path.size();k++){\n            int x0=path[k-1].first, y0=path[k-1].second;\n            int x1=path[k].first, y1=path[k].second;\n            if(x1==x0-1 && y1==y0) dirs.push_back('U');\n            else if(x1==x0+1 && y1==y0) dirs.push_back('D');\n            else if(x1==x0 && y1==y0-1) dirs.push_back('L');\n            else if(x1==x0 && y1==y0+1) dirs.push_back('R');\n        }\n    }else{\n        // fallback: straight moves\n        int x=si,y=sj;\n        while(x>ti) { dirs.push_back('U'); x--; }\n        while(x<ti) { dirs.push_back('D'); x++; }\n        while(y>tj) { dirs.push_back('L'); y--; }\n        while(y<tj) { dirs.push_back('R'); y++; }\n    }\n    int D = (int)dirs.size();\n    if(D==0){\n        cout << \"\\n\";\n        return 0;\n    }\n    // Choose repetition factor r\n    // target epsilon for failing to advance on a block: p^r <= 0.02\n    auto safe_ceil = [](double x)->int{\n        int k = (int)ceil(x - 1e-12);\n        return k;\n    };\n    int r_cap;\n    if(p>=1.0-1e-12) r_cap = 8;\n    else {\n        double num = log(0.02);\n        double den = log(p);\n        int rc = safe_ceil(num/den); // since den<0, this is positive\n        r_cap = max(2, min(8, rc));\n    }\n    int r_max = max(1, 200 / max(1, D));\n    int r = min(r_max, r_cap);\n    // Build output\n    string out;\n    out.reserve(200);\n    auto append_repeats = [&](const vector<char>& P, int rep){\n        for(char c: P){\n            for(int k=0;k<rep;k++){\n                if((int)out.size()<200) out.push_back(c);\n            }\n        }\n    };\n    append_repeats(dirs, r);\n    // Add extra full-path copies (unrepeated) to fill up to near 200\n    while((int)out.size() + D <= 200){\n        for(char c: dirs){\n            if((int)out.size()<200) out.push_back(c);\n        }\n    }\n    // If still too short and we have a bit of space, add prefix of path\n    int rem = 200 - (int)out.size();\n    for(int i=0;i<rem && i<D;i++) out.push_back(dirs[i]);\n\n    cout << out << \"\\n\";\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int H = 30, W = 30;\nstatic const int di4[4] = {0,-1,0,1};   // L,U,R,D\nstatic const int dj4[4] = {-1,0,1,0};\n\nint base_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};\nint to_rot[8][4][4];\n\ninline int enc_state(int i,int j,int d){ return ((i*W + j)<<2) | d; }\n\nstruct Solver {\n    array<array<int, W>, H> t;\n    array<array<int, W>, H> r, best_r;\n    array<array<array<int,4>, W>, H> desired_to;\n    mt19937 rng;\n\n    Solver(): rng(20250915) {}\n\n    void precompute_to_rot() {\n        for(int tt=0; tt<8; ++tt){\n            for(int rot=0; rot<4; ++rot){\n                for(int d=0; d<4; ++d){\n                    int din = (d - rot) & 3;\n                    int e = base_to_[tt][din];\n                    to_rot[tt][rot][d] = (e==-1) ? -1 : ((e + rot) & 3);\n                }\n            }\n        }\n    }\n\n    void read_input() {\n        for(int i=0;i<H;++i){\n            string s; cin>>s;\n            for(int j=0;j<W;++j){\n                t[i][j] = s[j]-'0';\n            }\n        }\n    }\n\n    void build_desired_two_vortices() {\n        auto pick_card = [&](double ti, double tj)->int{\n            static const int vx[4] = {0,-1,0,1};\n            static const int vy[4] = {-1,0,1,0};\n            int bestd = 0; double bestdot = -1e100;\n            for(int d=0; d<4; ++d){\n                double dot = ti*vx[d] + tj*vy[d];\n                if(dot > bestdot){ bestdot=dot; bestd=d; }\n            }\n            return bestd;\n        };\n        double c1i = 14.5, c1j = 7.5;\n        double c2i = 14.5, c2j = 22.5;\n        for(int i=0;i<H;++i) for(int j=0;j<W;++j){\n            double ci, cj; if(j<W/2){ci=c1i; cj=c1j;} else {ci=c2i; cj=c2j;}\n            double pi=i+0.5, pj=j+0.5, ui=pi-ci, uj=pj-cj;\n            int dsel = pick_card(-uj, ui); // CCW tangent\n            for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n        }\n    }\n    void build_desired_single_vortex() {\n        auto pick_card = [&](double ti, double tj)->int{\n            static const int vx[4] = {0,-1,0,1};\n            static const int vy[4] = {-1,0,1,0};\n            int bestd = 0; double bestdot = -1e100;\n            for(int d=0; d<4; ++d){\n                double dot = ti*vx[d] + tj*vy[d];\n                if(dot > bestdot){ bestdot=dot; bestd=d; }\n            }\n            return bestd;\n        };\n        double ci = 14.5, cj = 14.5;\n        for(int i=0;i<H;++i) for(int j=0;j<W;++j){\n            double pi=i+0.5, pj=j+0.5, ui=pi-ci, uj=pj-cj;\n            int dsel = pick_card(-uj, ui);\n            for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n        }\n    }\n    void build_desired_serpentine() {\n        for(int i=0;i<H;++i) for(int j=0;j<W;++j){\n            int dsel = (i%2==0)?2:0;\n            for(int d=0; d<4; ++d) desired_to[i][j][d]=dsel;\n        }\n    }\n\n    int tile_local_score_init(int i,int j,int rot){\n        int sc=0;\n        for(int d=0; d<4; ++d){\n            int e = to_rot[t[i][j]][rot][d];\n            if(e==-1){ sc -= 2; continue; }\n            if(e == desired_to[i][j][d]) sc += 1;\n            int ni=i+di4[e], nj=j+dj4[e];\n            if(ni<0||ni>=H||nj<0||nj>=W) sc -= 3;\n        }\n        return sc;\n    }\n\n    void initial_assignment() {\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                int bestRot=0, bestSc=INT_MIN;\n                for(int rot=0; rot<4; ++rot){\n                    int sc = tile_local_score_init(i,j,rot);\n                    if(sc>bestSc){ bestSc=sc; bestRot=rot; }\n                }\n                r[i][j]=bestRot;\n            }\n        }\n        // one refinement sweep with neighbor consistency\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                int cur=r[i][j], bestRot=cur, bestSc=INT_MIN;\n                for(int rot=0; rot<4; ++rot){\n                    int sc=0;\n                    for(int d=0; d<4; ++d){\n                        int e = to_rot[t[i][j]][rot][d];\n                        if(e==-1){ sc -= 2; continue; }\n                        if(e == desired_to[i][j][d]) sc += 1;\n                        int ni=i+di4[e], nj=j+dj4[e];\n                        if(ni<0||ni>=H||nj<0||nj>=W) sc -= 3;\n                        else{\n                            int need=(e+2)&3;\n                            int ne = to_rot[t[ni][nj]][r[ni][nj]][need];\n                            if(ne==need) sc += 1;\n                        }\n                    }\n                    if(sc>bestSc){ bestSc=sc; bestRot=rot; }\n                }\n                r[i][j]=bestRot;\n            }\n        }\n    }\n\n    inline int edge_match(int ai,int aj,int d){\n        int bi=ai+di4[d], bj=aj+dj4[d];\n        if(bi<0||bi>=H||bj<0||bj>=W) return 0;\n        int Ato = to_rot[t[ai][aj]][r[ai][aj]][(d+2)&3];\n        if(Ato != d) return 0;\n        int Bto = to_rot[t[bi][bj]][r[bi][bj]][( (d+2)&3 )];\n        if(Bto != ((d+2)&3)) return 0;\n        return 1;\n    }\n\n    inline bool edge_near_match(int ai,int aj,int d){\n        int bi=ai+di4[d], bj=aj+dj4[d];\n        if(bi<0||bi>=H||bj<0||bj>=W) return false;\n        int Aok = (to_rot[t[ai][aj]][r[ai][aj]][(d+2)&3] == d);\n        int Bok = (to_rot[t[bi][bj]][r[bi][bj]][( (d+2)&3 )] == ((d+2)&3));\n        return (Aok ^ Bok);\n    }\n\n    int local_proxy_contrib_cell(int i,int j){\n        int s=0;\n        if(j>0) s += edge_match(i,j-1,2);\n        if(j<W-1) s += edge_match(i,j,2);\n        if(i>0) s += edge_match(i-1,j,3);\n        if(i<H-1) s += edge_match(i,j,3);\n        return s;\n    }\n\n    pair<int,int> compute_top2_loops() {\n        static int seenStep[H*W*4];\n        static int seenId[H*W*4];\n        static int globId = 1;\n        memset(seenId, 0, sizeof(seenId));\n\n        auto step_one = [&](int &ci,int &cj,int &cd)->bool{\n            int e = to_rot[t[ci][cj]][r[ci][cj]][cd];\n            if(e==-1) return false;\n            int ni=ci+di4[e], nj=cj+dj4[e];\n            if(ni<0||ni>=H||nj<0||nj>=W) return false;\n            int nd = (e+2)&3;\n            ci=ni;cj=nj;cd=nd; return true;\n        };\n\n        int best1=0,best2=0;\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                for(int d=0; d<4; ++d){\n                    int s0 = enc_state(i,j,d);\n                    if(seenId[s0]) continue;\n                    int ci=i,cj=j,cd=d;\n                    int id=globId++;\n                    vector<int> order; order.reserve(64);\n                    int step=0;\n                    while(true){\n                        int s = enc_state(ci,cj,cd);\n                        if(seenId[s]==id){\n                            int st = seenStep[s];\n                            int cyc_len = step - st;\n                            if(cyc_len >= best1){ best2=best1; best1=cyc_len; }\n                            else if(cyc_len > best2){ best2=cyc_len; }\n                            break;\n                        }\n                        if(seenId[s]) break;\n                        seenId[s]=id; seenStep[s]=step; order.push_back(s);\n                        if(!step_one(ci,cj,cd)) break;\n                        ++step;\n                    }\n                    for(int ss: order){ seenId[ss]=1; }\n                }\n            }\n        }\n        return {best1,best2};\n    }\n\n    pair<vector<pair<int,int>>, vector<pair<int,int>>> get_top2_cells(){\n        static int seenStep[H*W*4];\n        static int seenId[H*W*4];\n        static int globId = 1;\n        memset(seenId, 0, sizeof(seenId));\n        vector<pair<int,int>> c1, c2;\n        int best1=0,best2=0;\n        auto step_one = [&](int &ci,int &cj,int &cd)->bool{\n            int e = to_rot[t[ci][cj]][r[ci][cj]][cd];\n            if(e==-1) return false;\n            int ni=ci+di4[e], nj=cj+dj4[e];\n            if(ni<0||ni>=H||nj<0||nj>=W) return false;\n            int nd = (e+2)&3;\n            ci=ni;cj=nj;cd=nd; return true;\n        };\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                for(int d=0; d<4; ++d){\n                    int s0 = enc_state(i,j,d);\n                    if(seenId[s0]) continue;\n                    int ci=i,cj=j,cd=d;\n                    int id=globId++;\n                    vector<int> order; order.reserve(64);\n                    int step=0;\n                    while(true){\n                        int s = enc_state(ci,cj,cd);\n                        if(seenId[s]==id){\n                            int st = seenStep[s];\n                            int cyc_len = step - st;\n                            if(cyc_len >= best1){\n                                best2=best1; c2=c1;\n                                best1=cyc_len; c1.clear();\n                                for(int k=st;k<(int)order.size();++k){\n                                    int ss=order[k];\n                                    int ti = (ss>>2)/W;\n                                    int tj = (ss>>2)%W;\n                                    c1.emplace_back(ti,tj);\n                                }\n                            } else if(cyc_len > best2){\n                                best2=cyc_len; c2.clear();\n                                for(int k=st;k<(int)order.size();++k){\n                                    int ss=order[k];\n                                    int ti = (ss>>2)/W;\n                                    int tj = (ss>>2)%W;\n                                    c2.emplace_back(ti,tj);\n                                }\n                            }\n                            break;\n                        }\n                        if(seenId[s]) break;\n                        seenId[s]=id; seenStep[s]=step; order.push_back(s);\n                        if(!step_one(ci,cj,cd)) break;\n                        ++step;\n                    }\n                    for(int ss: order){ seenId[ss]=1; }\n                }\n            }\n        }\n        return {c1,c2};\n    }\n\n    void reinforce_along_cells(const vector<pair<int,int>>& cells){\n        for(auto &p: cells){\n            int i=p.first, j=p.second;\n            int cur=r[i][j];\n            int bestRot=cur, bestLoc=local_proxy_contrib_cell(i,j);\n            for(int rot=0; rot<4; ++rot){\n                if(rot==cur) continue;\n                int old=r[i][j]; r[i][j]=rot;\n                int val=local_proxy_contrib_cell(i,j);\n                if(val>bestLoc){ bestLoc=val; bestRot=rot; }\n                r[i][j]=old;\n            }\n            r[i][j]=bestRot;\n        }\n    }\n\n    void optimize_sa(double timeBudgetSec, uint64_t seedOffset = 0){\n        mt19937 lrng(rng());\n        if(seedOffset) lrng.seed(rng()+seedOffset);\n\n        auto start = chrono::high_resolution_clock::now();\n        auto p0 = compute_top2_loops();\n        long long bestScore = 1LL*p0.first*p0.second;\n        best_r = r;\n\n        vector<pair<int,int>> pool;\n        pool.reserve(H*W*3);\n        for(int i=0;i<H;++i) for(int j=0;j<W;++j){\n            int w = (t[i][j]>=4)?3:1;\n            for(int k=0;k<w;++k) pool.emplace_back(i,j);\n        }\n        shuffle(pool.begin(), pool.end(), lrng);\n\n        uniform_int_distribution<int> pick(0, (int)pool.size()-1);\n        uniform_int_distribution<int> coin(0, 9);\n        uniform_real_distribution<double> urd(0.0,1.0);\n\n        int iter=0, accepted=0;\n        while(true){\n            iter++;\n            if((iter & 0x1FFF)==0){\n                auto now = chrono::high_resolution_clock::now();\n                double t = chrono::duration<double>(now - start).count();\n                if(t > timeBudgetSec) break;\n            }\n            bool pairMove = (coin(lrng)==0);\n            if(!pairMove){\n                auto [i,j] = pool[pick(lrng)];\n                int cur = r[i][j];\n                int before = local_proxy_contrib_cell(i,j);\n                int bestRot=cur, bestLoc=before;\n                for(int rot=0; rot<4; ++rot){\n                    if(rot==cur) continue;\n                    r[i][j]=rot;\n                    int val = local_proxy_contrib_cell(i,j);\n                    if(val>bestLoc){ bestLoc=val; bestRot=rot; }\n                }\n                int gain = bestLoc - before;\n                auto now = chrono::high_resolution_clock::now();\n                double elapsed = chrono::duration<double>(now - start).count();\n                double frac = min(1.0, elapsed / timeBudgetSec);\n                double T0 = seedOffset?0.48:0.55;\n                double T1 = 0.02;\n                double temp = T0*(1.0-frac) + T1*frac;\n                bool take = gain>0 || urd(lrng) < exp(gain / max(1e-9, temp));\n                if(take){\n                    r[i][j]=bestRot;\n                    accepted++;\n                    if((accepted % 64)==0){\n                        auto p = compute_top2_loops();\n                        long long sc = 1LL*p.first*p.second;\n                        if(sc > bestScore){ bestScore=sc; best_r=r; }\n                    }\n                } else {\n                    r[i][j]=cur;\n                }\n            } else {\n                auto [i,j] = pool[pick(lrng)];\n                int dir = lrng()%4;\n                int ni=i+di4[dir], nj=j+dj4[dir];\n                if(ni<0||ni>=H||nj<0||nj>=W) continue;\n                int cur1=r[i][j], cur2=r[ni][nj];\n                int before = local_proxy_contrib_cell(i,j) + local_proxy_contrib_cell(ni,nj);\n                int best1=cur1, best2=cur2, bestLoc=before;\n                for(int rot1=0; rot1<4; ++rot1){\n                    r[i][j]=rot1;\n                    for(int rot2=0; rot2<4; ++rot2){\n                        r[ni][nj]=rot2;\n                        int val = local_proxy_contrib_cell(i,j) + local_proxy_contrib_cell(ni,nj);\n                        if(val>bestLoc){ bestLoc=val; best1=rot1; best2=rot2; }\n                    }\n                }\n                int gain = bestLoc - before;\n                auto now = chrono::high_resolution_clock::now();\n                double elapsed = chrono::duration<double>(now - start).count();\n                double frac = min(1.0, elapsed / timeBudgetSec);\n                double T0 = seedOffset?0.48:0.55;\n                double T1 = 0.02;\n                double temp = T0*(1.0-frac) + T1*frac;\n                bool take = gain>0 || urd(lrng) < exp(gain / max(1e-9, temp));\n                if(take){\n                    r[i][j]=best1; r[ni][nj]=best2;\n                    accepted++;\n                    if((accepted % 64)==0){\n                        auto p = compute_top2_loops();\n                        long long sc = 1LL*p.first*p.second;\n                        if(sc > bestScore){ bestScore=sc; best_r=r; }\n                    }\n                } else {\n                    r[i][j]=cur1; r[ni][nj]=cur2;\n                }\n            }\n        }\n        auto p = compute_top2_loops();\n        long long sc = 1LL*p.first*p.second;\n        if(sc > bestScore){ bestScore=sc; best_r=r; }\n        r = best_r;\n    }\n\n    vector<pair<int,int>> gather_mismatch_shortlist(bool include_near=true){\n        vector<pair<int,int>> v;\n        vector<vector<char>> seen(H, vector<char>(W, 0));\n        auto add = [&](int i,int j){\n            if(i<0||i>=H||j<0||j>=W) return;\n            if(seen[i][j]) return;\n            seen[i][j]=1;\n            v.emplace_back(i,j);\n        };\n        for(int i=0;i<H;++i){\n            for(int j=0;j<W;++j){\n                if(j+1<W){\n                    if(!edge_match(i,j,2) || (include_near && edge_near_match(i,j,2))){\n                        add(i,j); add(i,j+1);\n                    }\n                }\n                if(i+1<H){\n                    if(!edge_match(i,j,3) || (include_near && edge_near_match(i,j,3))){\n                        add(i,j); add(i+1,j);\n                    }\n                }\n            }\n        }\n        return v;\n    }\n\n    void edge_repair_pass(int budget){\n        auto shortlist = gather_mismatch_shortlist(true);\n        if(shortlist.empty()) return;\n        shuffle(shortlist.begin(), shortlist.end(), rng);\n        int cnt = 0;\n        for(auto &cell: shortlist){\n            if(cnt >= budget) break;\n            int i=cell.first, j=cell.second;\n            int cur=r[i][j];\n            int bestRot=cur, bestLoc=local_proxy_contrib_cell(i,j);\n            for(int rot=0; rot<4; ++rot){\n                if(rot==cur) continue;\n                int old=r[i][j]; r[i][j]=rot;\n                int val=local_proxy_contrib_cell(i,j);\n                if(val>bestLoc){ bestLoc=val; bestRot=rot; }\n                r[i][j]=old;\n            }\n            if(bestRot!=cur){\n                r[i][j]=bestRot;\n                cnt++;\n            }\n        }\n    }\n\n    // Border bias pass: align outer two rings via proxy local best-of-4\n    void border_bias_pass(){\n        auto relax = [&](int i,int j){\n            int cur=r[i][j];\n            int bestRot=cur, bestLoc=local_proxy_contrib_cell(i,j);\n            for(int rot=0;rot<4;++rot){\n                if(rot==cur) continue;\n                int old=r[i][j]; r[i][j]=rot;\n                int val=local_proxy_contrib_cell(i,j);\n                if(val>bestLoc){ bestLoc=val; bestRot=rot; }\n                r[i][j]=old;\n            }\n            r[i][j]=bestRot;\n        };\n        for(int j=0;j<W;++j){ relax(0,j); relax(1,j); relax(H-2,j); relax(H-1,j); }\n        for(int i=0;i<H;++i){ relax(i,0); relax(i,1); relax(i,W-2); relax(i,W-1); }\n    }\n\n    // Direct greedy: as earlier\n    void direct_cycle_greedy(double timeBudgetSec){\n        auto start = chrono::high_resolution_clock::now();\n        auto loops = get_top2_cells();\n        vector<vector<char>> onloop(H, vector<char>(W,0));\n        for(auto &p: loops.first) onloop[p.first][p.second]=1;\n        for(auto &p: loops.second) onloop[p.first][p.second]=1;\n\n        vector<pair<int,int>> cand;\n        cand.reserve(1200);\n        for(auto &p: loops.first) cand.emplace_back(p.first,p.second);\n        for(auto &p: loops.second) cand.emplace_back(p.first,p.second);\n        for(int i=0;i<H;++i)for(int j=0;j<W;++j){\n            if(onloop[i][j]) continue;\n            bool near=false;\n            for(int d=0; d<4; ++d){\n                int ni=i+di4[d], nj=j+dj4[d];\n                if(ni>=0&&ni<H&&nj>=0&&nj<W && onloop[ni][nj]){ near=true; break; }\n            }\n            if(near) cand.emplace_back(i,j);\n        }\n        auto mismatch = gather_mismatch_shortlist(true);\n        cand.insert(cand.end(), mismatch.begin(), mismatch.end());\n        sort(cand.begin(), cand.end());\n        cand.erase(unique(cand.begin(), cand.end()), cand.end());\n        if((int)cand.size() > 900){\n            shuffle(cand.begin(), cand.end(), rng);\n            cand.resize(900);\n        }\n\n        auto p0 = compute_top2_loops();\n        long long baseScore = 1LL*p0.first*p0.second;\n\n        bool improved = true;\n        int passes = 0;\n        uniform_int_distribution<int> dirpick(0,3);\n\n        while(improved){\n            passes++;\n            improved = false;\n            shuffle(cand.begin(), cand.end(), rng);\n            for(auto &cell: cand){\n                auto now = chrono::high_resolution_clock::now();\n                double t = chrono::duration<double>(now - start).count();\n                if(t > timeBudgetSec) return;\n                int i=cell.first, j=cell.second;\n                int cur = r[i][j];\n                int bestRot=cur;\n                long long bestSc=baseScore;\n                for(int rot=0; rot<4; ++rot){\n                    if(rot==cur) continue;\n                    int old=r[i][j]; r[i][j]=rot;\n                    auto p = compute_top2_loops();\n                    long long sc = 1LL*p.first*p.second;\n                    if(sc > bestSc){ bestSc=sc; bestRot=rot; }\n                    r[i][j]=old;\n                }\n                if(bestRot!=cur){\n                    r[i][j]=bestRot;\n                    baseScore = bestSc;\n                    improved = true;\n                    continue;\n                }\n                // 2-tile joint\n                int dir = dirpick(rng);\n                int ni=i+di4[dir], nj=j+dj4[dir];\n                if(ni<0||ni>=H||nj<0||nj>=W) continue;\n                int cur1=r[i][j], cur2=r[ni][nj];\n                int best1=cur1, best2=cur2;\n                long long best2Sc=baseScore;\n                for(int rot1=0; rot1<4; ++rot1){\n                    r[i][j]=rot1;\n                    for(int rot2=0; rot2<4; ++rot2){\n                        r[ni][nj]=rot2;\n                        auto p = compute_top2_loops();\n                        long long sc = 1LL*p.first*p.second;\n                        if(sc > best2Sc){ best2Sc=sc; best1=rot1; best2=rot2; }\n                    }\n                }\n                r[i][j]=cur1; r[ni][nj]=cur2;\n                if(best2Sc > baseScore){\n                    r[i][j]=best1; r[ni][nj]=best2;\n                    baseScore = best2Sc;\n                    improved = true;\n                }\n            }\n            if(passes >= 2) break;\n        }\n    }\n\n    void solve() {\n        precompute_to_rot();\n        read_input();\n\n        double totalTime = 1.95;\n        auto tstart = chrono::high_resolution_clock::now();\n\n        long long globalBestScore = -1;\n        array<array<int,W>,H> globalBestR;\n\n        // Build seeds\n        vector<array<array<int,W>,H>> seeds;\n        auto construct_two_rect_lr = [&](){\n            array<array<int,W>,H> rr{};\n            auto want = [&](int i,int j)->int{\n                bool left = (j<15);\n                int jl = left?0:15;\n                int jr = left?14:29;\n                if(i==0) return 2;\n                if(i==H-1) return 0;\n                if(j==jl) return 3;\n                if(j==jr) return 1;\n                return (i%2==0)?2:0;\n            };\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int br=0, bs=-1e9;\n                    for(int rot=0;rot<4;++rot){\n                        int sc=0;\n                        for(int d=0;d<4;++d){\n                            int e=to_rot[t[i][j]][rot][d];\n                            if(e==-1){ sc-=2; continue; }\n                            if(e==want(i,j)) sc+=1;\n                            int ni=i+di4[e], nj=j+dj4[e];\n                            if(ni<0||ni>=H||nj<0||nj>=W) sc-=3;\n                        }\n                        if(sc>bs){bs=sc;br=rot;}\n                    }\n                    rr[i][j]=br;\n                }\n            }\n            return rr;\n        };\n        auto construct_two_rect_tb = [&](){\n            array<array<int,W>,H> rr{};\n            auto want = [&](int i,int j)->int{\n                bool top = (i<15);\n                int it = top?0:15;\n                int ib = top?14:29;\n                if(j==0) return 3;\n                if(j==W-1) return 1;\n                if(i==it) return 2;\n                if(i==ib) return 0;\n                return (j%2==0)?3:1;\n            };\n            for(int i=0;i<H;++i){\n                for(int j=0;j<W;++j){\n                    int br=0, bs=-1e9;\n                    for(int rot=0;rot<4;++rot){\n                        int sc=0;\n                        for(int d=0;d<4; ++d){\n                            int e=to_rot[t[i][j]][rot][d];\n                            if(e==-1){ sc-=2; continue; }\n                            if(e==want(i,j)) sc+=1;\n                            int ni=i+di4[e], nj=j+dj4[e];\n                            if(ni<0||ni>=H||nj<0||nj>=W) sc-=3;\n                        }\n                        if(sc>bs){bs=sc;br=rot;}\n                    }\n                    rr[i][j]=br;\n                }\n            }\n            return rr;\n        };\n        seeds.push_back(construct_two_rect_lr());\n        seeds.push_back(construct_two_rect_tb());\n        build_desired_two_vortices();\n        initial_assignment();\n        seeds.push_back(r);\n        build_desired_single_vortex();\n        initial_assignment();\n        seeds.push_back(r);\n        build_desired_serpentine();\n        initial_assignment();\n        seeds.push_back(r);\n\n        // Evaluate seeds\n        vector<pair<long long,int>> ord; ord.reserve(seeds.size());\n        for(int i=0;i<(int)seeds.size(); ++i){\n            auto bak = r; r = seeds[i];\n            auto p = compute_top2_loops();\n            long long sc = 1LL*p.first*p.second;\n            r = bak;\n            ord.emplace_back(sc,i);\n        }\n        sort(ord.begin(), ord.end(), greater<>());\n\n        // Diversified selection: pick one from constructive, one from desired-based, and one serpentine if possible\n        vector<int> selected;\n        // pick best of the two constructives\n        int bestC = -1; long long bestCSc=-1;\n        for(int idx=0; idx<2; ++idx) if(ord[idx].second < 2){\n            if(ord[idx].first > bestCSc){ bestCSc = ord[idx].first; bestC = ord[idx].second; }\n        }\n        if(bestC==-1){\n            for(auto &p: ord){ if(p.second<2){ bestC=p.second; break; } }\n        }\n        if(bestC!=-1) selected.push_back(bestC);\n        // pick best of desired-based (indices 2 and 3 in our push order)\n        int bestD = -1;\n        for(auto &p: ord){\n            if(p.second==2 || p.second==3){ bestD=p.second; break; }\n        }\n        if(bestD!=-1) selected.push_back(bestD);\n        // pick serpentine (index 4)\n        int serp = -1;\n        for(auto &p: ord){ if(p.second==4){ serp=p.second; break; } }\n        if(serp!=-1) selected.push_back(serp);\n        // if we have fewer than 3, fill with next best overall distinct\n        for(auto &p: ord){\n            if((int)selected.size()>=3) break;\n            bool exists=false; for(int x: selected) if(x==p.second) exists=true;\n            if(!exists) selected.push_back(p.second);\n        }\n\n        for(int selIdx=0; selIdx<(int)selected.size(); ++selIdx){\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - tstart).count();\n            double remain = max(0.0, totalTime - elapsed);\n            if(remain < 0.12) break;\n\n            r = seeds[selected[selIdx]];\n\n            // Border bias then edge repair\n            border_bias_pass();\n            int mismatchCount = (int)gather_mismatch_shortlist(true).size();\n            int budget = min(240, max(80, mismatchCount / 2));\n            edge_repair_pass(budget);\n\n            auto now2 = chrono::high_resolution_clock::now();\n            double elapsed2 = chrono::duration<double>(now2 - tstart).count();\n            double remain2 = max(0.0, totalTime - elapsed2);\n            double budget1 = max(0.0, remain2 - 0.08);\n            if(budget1 > 0) optimize_sa(budget1, 0);\n\n            auto now3 = chrono::high_resolution_clock::now();\n            double elapsed3 = chrono::duration<double>(now3 - tstart).count();\n            double remain3 = max(0.0, totalTime - elapsed3);\n            double greedyBudget = min(0.06, max(0.0, remain3 - 0.02));\n            if(greedyBudget > 0) direct_cycle_greedy(greedyBudget);\n\n            // small second SA polish if time remains\n            auto now4 = chrono::high_resolution_clock::now();\n            double elapsed4 = chrono::duration<double>(now4 - tstart).count();\n            double remain4 = max(0.0, totalTime - elapsed4);\n            if(remain4 > 0.03) optimize_sa(remain4 - 0.01, 987654321);\n\n            auto p = compute_top2_loops();\n            long long sc = 1LL*p.first*p.second;\n            if(sc > globalBestScore){ globalBestScore=sc; globalBestR=r; }\n        }\n\n        // Final reinforcement along top two loops\n        r = globalBestR;\n        auto loops = get_top2_cells();\n        reinforce_along_cells(loops.first);\n        reinforce_along_cells(loops.second);\n\n        // Micro-polish on border/corners with exact evaluation\n        vector<pair<int,int>> micro;\n        micro.emplace_back(0,0); micro.emplace_back(0,W-1);\n        micro.emplace_back(H-1,0); micro.emplace_back(H-1,W-1);\n        for(int j=0;j<W;j+=3){ micro.emplace_back(0,j); micro.emplace_back(H-1,j); }\n        for(int i=0;i<H;i+=3){ micro.emplace_back(i,0); micro.emplace_back(i,W-1); }\n        auto pbase = compute_top2_loops();\n        long long baseSc = 1LL*pbase.first*pbase.second;\n        for(auto &cell: micro){\n            int i=cell.first, j=cell.second;\n            int cur=r[i][j], bestRot=cur;\n            long long bestSc=baseSc;\n            for(int rot=0; rot<4; ++rot){\n                if(rot==cur) continue;\n                int old=r[i][j]; r[i][j]=rot;\n                auto p = compute_top2_loops();\n                long long sc = 1LL*p.first*p.second;\n                if(sc > bestSc){ bestSc=sc; bestRot=rot; }\n                r[i][j]=old;\n            }\n            if(bestRot!=cur){\n                r[i][j]=bestRot; baseSc=bestSc;\n            }\n        }\n\n        auto pf = compute_top2_loops();\n        long long scf = 1LL*pf.first*pf.second;\n        if(scf > globalBestScore){ globalBestScore=scf; globalBestR=r; }\n\n        string out; out.reserve(H*W);\n        for(int i=0;i<H;++i) for(int j=0;j<W;++j) out.push_back(char('0' + (globalBestR[i][j] & 3)));\n        cout << out << \"\\n\";\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver s;\n    s.solve();\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Direction bits: 1=L, 2=U, 4=R, 8=D\nstatic inline bool matchLR(int a, int b){ return (a & 4) && (b & 1); }\nstatic inline bool matchUD(int a, int b){ return (a & 8) && (b & 2); }\n\nstruct RNG {\n    uint64_t x;\n    RNG(uint64_t seed=712367821) : x(seed) {}\n    uint32_t next(){ x ^= x<<7; x ^= x>>9; return (uint32_t)x; }\n    int randint(int l,int r){ return l + (int)(next() % (uint32_t)(r-l+1)); }\n    double uniform(){ return (next()+0.5)/double(UINT32_MAX); }\n    bool prob(double p){ return uniform() < p; }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, Tlimit;\n    if(!(cin>>N>>Tlimit)) return 0;\n    vector<string> rows(N);\n    for(int i=0;i<N;i++) cin>>rows[i];\n    vector<int> a(N*N);\n    int er=-1, ec=-1;\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            char c = rows[i][j];\n            int v = (c<='9') ? c-'0' : 10 + (c-'a');\n            a[i*N+j]=v;\n            if(v==0){ er=i; ec=j; }\n        }\n    }\n\n    RNG rng(123456789 ^ (uint64_t)chrono::high_resolution_clock::now().time_since_epoch().count());\n    auto inb=[&](int r,int c){ return r>=0 && r<N && c>=0 && c<N; };\n\n    // Matched adjacency arrays\n    vector<char> horiz(N*(N-1),0), vert((N-1)*N,0);\n    auto idxH=[&](int i,int j){ return i*(N-1)+j; };\n    auto idxV=[&](int i,int j){ return i*N+j; };\n\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N-1;j++){\n            int L=a[i*N+j], Rv=a[i*N+j+1];\n            horiz[idxH(i,j)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n    }\n    for(int i=0;i<N-1;i++){\n        for(int j=0;j<N;j++){\n            int U=a[i*N+j], Dv=a[(i+1)*N+j];\n            vert[idxV(i,j)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n    }\n\n    auto recompute_local_edges = [&](int r,int c){\n        if(c-1>=0){\n            int L=a[r*N+(c-1)], Rv=a[r*N+c];\n            horiz[idxH(r,c-1)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n        if(c<N-1){\n            int L=a[r*N+c], Rv=a[r*N+(c+1)];\n            horiz[idxH(r,c)] = (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n        }\n        if(r-1>=0){\n            int U=a[(r-1)*N+c], Dv=a[r*N+c];\n            vert[idxV(r-1,c)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n        if(r<N-1){\n            int U=a[r*N+c], Dv=a[(r+1)*N+c];\n            vert[idxV(r,c)] = (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n        }\n    };\n\n    auto totalE = [&](){\n        int s=0;\n        for(char v: horiz) s+=v;\n        for(char v: vert)  s+=v;\n        return s;\n    };\n    int E = totalE();\n    int bestE = E; // aspiration\n    int sinceBest = 0;\n\n    // Compute exact local delta in matched edges for swapping empty at (er,ec) with neighbor (nr,nc)\n    auto delta_for_move = [&](int er,int ec,int nr,int nc)->int{\n        int before=0, after=0;\n        auto add_edges = [&](int r,int c,int &acc){\n            if(c-1>=0) acc += horiz[idxH(r,c-1)];\n            if(c<N-1) acc += horiz[idxH(r,c)];\n            if(r-1>=0) acc += vert[idxV(r-1,c)];\n            if(r<N-1) acc += vert[idxV(r,c)];\n        };\n        add_edges(er,ec,before);\n        add_edges(nr,nc,before);\n\n        int pe=er*N+ec, pn=nr*N+nc;\n        int vn=a[pn];\n        auto contrib_cell = [&](int r,int c,int val_at_rc)->int{\n            int s=0;\n            if(c-1>=0){\n                int L = (r*N + c-1 == pe ? vn : (r*N + c-1 == pn ? 0 : a[r*N + c-1]));\n                int Rv = val_at_rc;\n                s += (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n            }\n            if(c<N-1){\n                int L = val_at_rc;\n                int Rv = (r*N + c+1 == pe ? vn : (r*N + c+1 == pn ? 0 : a[r*N + c+1]));\n                s += (L!=0 && Rv!=0 && matchLR(L,Rv)) ? 1:0;\n            }\n            if(r-1>=0){\n                int U = ((r-1)*N + c == pe ? vn : ((r-1)*N + c == pn ? 0 : a[(r-1)*N + c]));\n                int Dv = val_at_rc;\n                s += (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n            }\n            if(r<N-1){\n                int U = val_at_rc;\n                int Dv = ((r+1)*N + c == pe ? vn : ((r+1)*N + c == pn ? 0 : a[(r+1)*N + c]));\n                s += (U!=0 && Dv!=0 && matchUD(U,Dv)) ? 1:0;\n            }\n            return s;\n        };\n        after += contrib_cell(er,ec,vn);\n        after += contrib_cell(nr,nc,0);\n        return after - before;\n    };\n\n    // Potential hint: number of neighbors around destination that could match based on bits\n    auto potential_gain_hint = [&](int nr,int nc)->int{\n        int pn = nr*N+nc;\n        int vn = a[pn];\n        if(vn==0) return 0;\n        int pot=0;\n        if(nc+1<N){\n            int x = a[nr*N + (nc+1)];\n            if(x!=0 && (vn & 4) && (x & 1)) pot++;\n        }\n        if(nc-1>=0){\n            int x = a[nr*N + (nc-1)];\n            if(x!=0 && (vn & 1) && (x & 4)) pot++;\n        }\n        if(nr+1<N){\n            int x = a[(nr+1)*N + nc];\n            if(x!=0 && (vn & 8) && (x & 2)) pot++;\n        }\n        if(nr-1>=0){\n            int x = a[(nr-1)*N + nc];\n            if(x!=0 && (vn & 2) && (x & 8)) pot++;\n        }\n        return pot;\n    };\n\n    const int dr[4]={-1,1,0,0};\n    const int dc[4]={0,0,-1,1};\n    const char dch[4]={'U','D','L','R'};\n    const int revdir[4]={1,0,3,2};\n\n    string moves; moves.reserve(Tlimit);\n    int last_dir = -1;\n\n    auto apply_move = [&](int dir, int dE)->bool{\n        if((int)moves.size() >= Tlimit) return false;\n        int nr=er+dr[dir], nc=ec+dc[dir];\n        int pe=er*N+ec, pn=nr*N+nc;\n        swap(a[pe], a[pn]);\n        recompute_local_edges(er,ec);\n        recompute_local_edges(nr,nc);\n        E += dE;\n        if(E > bestE){ bestE = E; sinceBest = 0; } else sinceBest++;\n        er=nr; ec=nc;\n        moves.push_back(dch[dir]);\n        last_dir = dir;\n        return true;\n    };\n\n    auto t_start = chrono::high_resolution_clock::now();\n    const double time_limit_ms = 2800.0;\n\n    // Parameters\n    const double anneal_start = 0.2;\n    const double anneal_end   = 0.01;\n    int stagnation = 0;\n\n    auto steer_empty_towards = [&](int tr,int tc, int steps){\n        for(int s=0; s<steps; ++s){\n            if((int)moves.size() >= Tlimit) break;\n            int bestd=-1, bestScore=-1e9, bestDelta=-1000;\n            for(int d=0; d<4; ++d){\n                int nr=er+dr[d], nc=ec+dc[d];\n                if(!inb(nr,nc)) continue;\n                int dE = delta_for_move(er,ec,nr,nc);\n                int md_before = abs(er-tr)+abs(ec-tc);\n                int md_after  = abs(nr-tr)+abs(nc-tc);\n                int score = (md_before - md_after)*5 + (dE>=0 ? 10*dE : dE) + potential_gain_hint(nr,nc);\n                if(last_dir!=-1 && revdir[d]==last_dir) score -= 2;\n                if(score > bestScore){\n                    bestScore=score; bestDelta=dE; bestd=d;\n                }\n            }\n            if(bestd==-1) break;\n            if(!apply_move(bestd, bestDelta)) break;\n        }\n    };\n\n    // Try a 2x2 rotation (CW or CCW) on square with top-left at (r,c) if empty is inside\n    auto try_2x2_cycle = [&](int r,int c)->bool{\n        if(r<0 || c<0 || r>=N-1 || c>=N-1) return false;\n        // positions: (r,c) (r,c+1) (r+1,c) (r+1,c+1)\n        // We need empty at one of these; if not, attempt to bring it in with a few steps\n        if(!((er==r || er==r+1) && (ec==c || ec==c+1))){\n            // steer to nearest corner\n            int tr = (er < r ? r : (er > r+1 ? r+1 : er));\n            int tc = (ec < c ? c : (ec > c+1 ? c+1 : ec));\n            steer_empty_towards(tr, tc, 6);\n            if(!((er==r || er==r+1) && (ec==c || ec==c+1))) return false;\n        }\n        // Determine sequence to rotate CW and CCW based on empty location\n        // We'll construct possible sequences as list of dirs length 3\n        vector<vector<int>> seqs;\n        // Predefined cycles when empty at each corner\n        // If empty at (r,c): CW: R,D,L ; CCW: D,R,U\n        if(er==r && ec==c){\n            seqs.push_back({3,1,2}); // R,D,L\n            seqs.push_back({1,3,0}); // D,R,U\n        }else if(er==r && ec==c+1){\n            // empty at (r,c+1): CW: D,L,U ; CCW: L,D,R\n            seqs.push_back({1,2,0});\n            seqs.push_back({2,1,3});\n        }else if(er==r+1 && ec==c){\n            // empty at (r+1,c): CW: U,R,D ; CCW: R,U,L\n            seqs.push_back({0,3,1});\n            seqs.push_back({3,0,2});\n        }else if(er==r+1 && ec==c+1){\n            // empty at (r+1,c+1): CW: L,U,R ; CCW: U,L,D\n            seqs.push_back({2,0,3});\n            seqs.push_back({0,2,1});\n        }\n        // Evaluate each sequence deltaE sum; ensure all moves stay within the 2x2 bounds (they will by construction)\n        int bestIdx=-1, bestGain=-1e9;\n        vector<int> deltas;\n        for(int si=0; si<(int)seqs.size(); ++si){\n            auto seq = seqs[si];\n            int cur_r=er, cur_c=ec;\n            int gain=0;\n            bool ok=true;\n            deltas.clear();\n            for(int d: seq){\n                int nr=cur_r+dr[d], nc=cur_c+dc[d];\n                if(!(nr>=r && nr<=r+1 && nc>=c && nc<=c+1)){ ok=false; break; }\n                int dE = delta_for_move(cur_r,cur_c,nr,nc);\n                gain += dE;\n                deltas.push_back(dE);\n                cur_r=nr; cur_c=nc;\n            }\n            if(ok && gain>bestGain){\n                bestGain=gain; bestIdx=si;\n            }\n        }\n        if(bestIdx==-1 || bestGain<=0) return false;\n        // Apply the best sequence\n        auto seq = seqs[bestIdx];\n        for(int d: seq){\n            if((int)moves.size() >= Tlimit) return true;\n            int dE = delta_for_move(er,ec, er+dr[d], ec+dc[d]);\n            if(!apply_move(d, dE)) return true;\n        }\n        return true;\n    };\n\n    auto tguard = [&](){\n        auto now=chrono::high_resolution_clock::now();\n        double ms=chrono::duration<double, milli>(now - t_start).count();\n        return ms > time_limit_ms;\n    };\n\n    for(int step=0; step<Tlimit; ++step){\n        if((int)moves.size() >= Tlimit) break;\n        if((step & 255)==0){\n            if(tguard()) break;\n        }\n\n        struct Cand{ int dir; int dE; int tie; };\n        vector<Cand> cands;\n        for(int d=0; d<4; ++d){\n            int nr=er+dr[d], nc=ec+dc[d];\n            if(!inb(nr,nc)) continue;\n            int dE = delta_for_move(er,ec,nr,nc);\n            int tie = 0;\n            // center bias for empty\n            tie -= (abs((N-1)/2 - nr) + abs((N-1)/2 - nc));\n            // mild potential hint\n            tie += potential_gain_hint(nr,nc);\n            // avoid immediate reversal slightly\n            if(last_dir!=-1 && revdir[d]==last_dir) tie -= 2;\n            // small jitter\n            tie += (rng.randint(0,3)==0 ? 1 : 0);\n            cands.push_back({d, dE, tie});\n        }\n        if(cands.empty()) break;\n\n        sort(cands.begin(), cands.end(), [&](const Cand& A, const Cand& B){\n            if(A.dE != B.dE) return A.dE > B.dE;\n            return A.tie > B.tie;\n        });\n\n        int chosen = 0;\n        if(cands[0].dE > 0){\n            stagnation = 0;\n            if(last_dir!=-1 && revdir[cands[0].dir]==last_dir && cands.size()>=2 && cands[1].dE==cands[0].dE){\n                chosen = 1;\n            }\n        }else{\n            stagnation++;\n            double progress = (double)step / max(1,Tlimit);\n            double Temp = anneal_start * pow(anneal_end/anneal_start, progress);\n            int k = min((int)cands.size(), 3);\n            vector<double> w(k);\n            double sumw=0;\n            for(int i=0;i<k;i++){\n                double x = cands[i].dE / max(1e-6, Temp);\n                if(x > 12) x = 12;\n                if(x < -12) x = -12;\n                w[i] = exp(x);\n                sumw += w[i];\n            }\n            double r = rng.uniform() * sumw, acc=0;\n            for(int i=0;i<k;i++){ acc += w[i]; if(r <= acc){ chosen = i; break; } }\n\n            // If long stagnation and time remains, attempt 2x2 cycle repair around a random nearby block\n            if(stagnation > 50 && !tguard()){\n                // Try up to few attempts\n                bool applied=false;\n                for(int att=0; att<3 && !applied; ++att){\n                    int r = min(max(er + rng.randint(-1,0), 0), N-2);\n                    int c = min(max(ec + rng.randint(-1,0), 0), N-2);\n                    applied = try_2x2_cycle(r,c);\n                }\n                if(applied){ stagnation = 0; continue; }\n            }\n\n            // occasional directed relocation to center or border\n            if(stagnation > 70 && !tguard()){\n                if(rng.prob(0.5)){\n                    int tr=(N-1)/2, tc=(N-1)/2;\n                    steer_empty_towards(tr, tc, rng.randint(5,9));\n                }else{\n                    int side = rng.randint(0,3);\n                    int tr = (side==0?0: side==1?N-1: rng.randint(0,N-1));\n                    int tc = (side==2?0: side==3?N-1: rng.randint(0,N-1));\n                    steer_empty_towards(tr, tc, rng.randint(5,9));\n                }\n                stagnation = 0;\n                continue;\n            }\n\n            // fallback: short random-walk burst\n            if(stagnation > 40 && rng.prob(0.3)){\n                int L = rng.randint(3,6);\n                for(int t=0; t<L; ++t){\n                    if((int)moves.size() >= Tlimit) break;\n                    vector<int> dirs;\n                    for(int d=0; d<4; ++d){\n                        int nr=er+dr[d], nc=ec+dc[d];\n                        if(!inb(nr,nc)) continue;\n                        if(t>0 && d==revdir[last_dir]) continue;\n                        dirs.push_back(d);\n                    }\n                    if(dirs.empty()){\n                        for(int d=0; d<4; ++d){\n                            int nr=er+dr[d], nc=ec+dc[d];\n                            if(inb(nr,nc)) dirs.push_back(d);\n                        }\n                    }\n                    int d = dirs[rng.randint(0,(int)dirs.size()-1)];\n                    int dE = delta_for_move(er,ec, er+dr[d], ec+dc[d]);\n                    if(!apply_move(d, dE)) break;\n                }\n                stagnation = 0;\n                continue;\n            }\n        }\n\n        if(!apply_move(cands[chosen].dir, cands[chosen].dE)) break;\n    }\n\n    if((int)moves.size() > Tlimit) moves.resize(Tlimit);\n    cout<<moves<<\"\\n\";\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Sig {\n    uint64_t a=0, b=0;\n    bool operator==(Sig const& o) const { return a==o.a && b==o.b; }\n};\nstruct SigHash {\n    size_t operator()(Sig const& s) const noexcept {\n        uint64_t x = s.a ^ (s.b + 0x9E3779B97F4A7C15ULL + (s.a<<6) + (s.a>>2));\n        x ^= (x >> 27);\n        x *= 0x3C79AC492BA7B653ULL;\n        x ^= (x >> 33);\n        x *= 0x1C69B3F74AC4AE35ULL;\n        x ^= (x >> 27);\n        return (size_t)x;\n    }\n};\n\nstruct Point { int x,y; };\nstruct LineParam { int A,B; long long T; };\n\nstatic inline long long dotAB(int A,int B,int x,int y){ return (long long)A*x + (long long)B*y; }\n\nstatic long long egcd(long long a, long long b, long long &x, long long &y){\n    if(b==0){ x = (a>=0?1:-1); y=0; return llabs(a); }\n    long long x1,y1;\n    long long g = egcd(b, a%b, x1, y1);\n    x = y1;\n    y = x1 - (a/b) * y1;\n    return g;\n}\n\nstatic inline void reduce_coprime(int &A, int &B){\n    if(A==0 && B==0){ A=1; B=0; return; }\n    if(A==0){ B = (B>0?1:-1); return; }\n    if(B==0){ A = (A>0?1:-1); return; }\n    int g = std::gcd(abs(A),abs(B));\n    A/=g; B/=g;\n    if(A<0){ A=-A; B=-B; }\n    else if(A==0 && B<0){ B=-B; }\n}\n\nstatic inline pair<long long,long long> clip2(long long x, long long y){\n    auto clip = [](long long v){\n        if(v < -1000000000LL) return -1000000000LL;\n        if(v > 1000000000LL) return 1000000000LL;\n        return v;\n    };\n    return {clip(x), clip(y)};\n}\n\nstatic inline pair<pair<long long,long long>, pair<long long,long long>>\ntwo_points_on_line(int A, int B, long long T){\n    long long x0,y0;\n    long long g = egcd(A,B,x0,y0);\n    if(g<0){ g=-g; x0=-x0; y0=-y0; }\n    long long mul = T / g;\n    __int128 xi = (__int128)x0 * mul;\n    __int128 yi = (__int128)y0 * mul;\n    long long X = (long long)xi;\n    long long Y = (long long)yi;\n    long long kk = 100000;\n    long long X2 = X + (long long)B * kk;\n    long long Y2 = Y - (long long)A * kk;\n    auto p1 = clip2(X,Y);\n    auto p2 = clip2(X2,Y2);\n    if(p1==p2){\n        kk = 1;\n        X2 = X + (long long)B * kk;\n        Y2 = Y - (long long)A * kk;\n        p2 = clip2(X2,Y2);\n        if(p1==p2){\n            kk = 2;\n            X2 = X + (long long)B * kk;\n            Y2 = Y - (long long)A * kk;\n            p2 = clip2(X2,Y2);\n        }\n    }\n    return {p1,p2};\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, K;\n    if(!(cin>>N>>K)) return 0;\n    vector<int> a(11);\n    for(int d=1; d<=10; ++d) cin>>a[d];\n    vector<Point> pts(N);\n    for(int i=0;i<N;++i) cin>>pts[i].x >> pts[i].y;\n\n    // Curated base normals (small, robust)\n    vector<pair<int,int>> baseNormals = {\n        {1,0},{0,1},{1,1},{1,-1},\n        {2,1},{1,2},{2,-1},{1,-2},\n        {3,1},{1,3},{3,2},{2,3},{3,-1},{1,-3},{3,-2},{2,-3},\n        {4,1},{1,4},{4,3},{3,4},{5,2},{2,5}\n    };\n    for(auto &p: baseNormals) reduce_coprime(p.first, p.second);\n    sort(baseNormals.begin(), baseNormals.end());\n    baseNormals.erase(unique(baseNormals.begin(), baseNormals.end()), baseNormals.end());\n\n    vector<Sig> sig(N);\n    unordered_map<Sig, vector<int>, SigHash> cells;\n    vector<int> bd(11,0);\n\n    auto recompute = [&](){\n        cells.clear();\n        cells.reserve(N*2);\n        for(int i=0;i<N;++i) cells[sig[i]].push_back(i);\n        fill(bd.begin(), bd.end(), 0);\n        for(auto &kv : cells){\n            int s = (int)kv.second.size();\n            if(s<=10) bd[s]++;\n        }\n    };\n    recompute();\n\n    vector<LineParam> lines; lines.reserve(K);\n\n    auto all_satisfied = [&](){\n        for(int d=1; d<=10; ++d) if(bd[d] < a[d]) return false;\n        return true;\n    };\n\n    vector<long long> proj; proj.reserve(N);\n\n    int cutsLeft = K;\n    while(cutsLeft>0){\n        if(all_satisfied()) break;\n\n        vector<int> need(11,0);\n        for(int d=1; d<=10; ++d) need[d] = max(0, a[d]-bd[d]);\n\n        // Phases similar to the better version\n        enum Phase { EARLY, MID, LATE } phase;\n        if(cutsLeft > 66) phase = EARLY;\n        else if(cutsLeft > 20) phase = MID;\n        else phase = LATE;\n\n        // Candidate cells: top by size\n        vector<pair<int,Sig>> cands;\n        cands.reserve(cells.size());\n        for(auto &kv : cells) cands.emplace_back((int)kv.second.size(), kv.first);\n        if(cands.empty()) break;\n        sort(cands.begin(), cands.end(), [](auto &L, auto &R){ return L.first > R.first; });\n        int consider = min<int>((int)cands.size(), 16);\n\n        // Demand list\n        vector<int> demandList;\n        for(int d=1; d<=10; ++d) if(need[d]>0) demandList.push_back(d);\n        sort(demandList.begin(), demandList.end(), [&](int u,int v){\n            if(need[u]!=need[v]) return need[u]>need[v];\n            return u<v;\n        });\n        if(demandList.empty()){\n            for(int d=1; d<=10; ++d) demandList.push_back(d);\n        }\n\n        long long bestScore = LLONG_MIN;\n        LineParam bestLine{1,0,0};\n        bool found = false;\n\n        for(int ci=0; ci<consider; ++ci){\n            int s = cands[ci].first;\n            if(s<=1) continue;\n            auto &idxs = cells[cands[ci].second];\n\n            // PCA normals\n            long double meanx=0, meany=0;\n            for(int id : idxs){ meanx += pts[id].x; meany += pts[id].y; }\n            meanx /= s; meany /= s;\n            long double cxx=0,cxy=0,cyy=0;\n            for(int id : idxs){\n                long double dx = (long double)pts[id].x - meanx;\n                long double dy = (long double)pts[id].y - meany;\n                cxx += dx*dx; cxy += dx*dy; cyy += dy*dy;\n            }\n            long double tr = cxx + cyy;\n            long double det = cxx*cyy - cxy*cxy;\n            long double tmp = max((long double)0.0L, tr*tr/4 - det);\n            long double l1 = tr/2 + sqrtl(tmp);\n            long double vx,vy;\n            if(fabsl(cxy) > 1e-14L){ vx = l1 - cyy; vy = cxy; }\n            else { if(cxx >= cyy){ vx=1; vy=0; } else { vx=0; vy=1; } }\n            long double normv = sqrtl(vx*vx + vy*vy);\n            if(normv < 1e-18L){ vx=1; vy=0; normv=1; }\n            vx/=normv; vy/=normv;\n            long double nx1=-vy, ny1=vx;\n            long double nx2= vy, ny2=-vx;\n            auto to_small_int = [&](long double nx,long double ny)->pair<int,int>{\n                long double scale = 12.0L;\n                int A = (int)llround(nx*scale);\n                int B = (int)llround(ny*scale);\n                if(A==0 && B==0){\n                    if(fabsl(nx) >= fabsl(ny)) A = (nx>=0?1:-1);\n                    else B = (ny>=0?1:-1);\n                }\n                reduce_coprime(A,B);\n                if(abs(A)>20 || abs(B)>20){\n                    int g = max(abs(A),abs(B));\n                    int k = (g+19)/20; if(k==0) k=1;\n                    A/=k; B/=k; if(A==0 && B==0){ A=1; B=0; }\n                    reduce_coprime(A,B);\n                }\n                return {A,B};\n            };\n            pair<int,int> pca1 = to_small_int(nx1,ny1);\n            pair<int,int> pca2 = to_small_int(nx2,ny2);\n\n            // Normals to try\n            static vector<pair<int,int>> normals;\n            normals.clear();\n            normals.insert(normals.end(), baseNormals.begin(), baseNormals.end());\n            normals.push_back(pca1);\n            normals.push_back(pca2);\n            sort(normals.begin(), normals.end());\n            normals.erase(unique(normals.begin(), normals.end()), normals.end());\n\n            // Candidate left sizes\n            auto build_Lcands = [&](int s)->vector<int>{\n                vector<int> Lc;\n                if(s>=2){\n                    Lc.push_back(s/2);\n                    Lc.push_back(max(1, s/3));\n                    Lc.push_back(max(1, (2*s)/3));\n                }\n                int take = min(5, (int)demandList.size());\n                for(int i=0;i<take;++i){\n                    int d = demandList[i];\n                    if(d < s) Lc.push_back(d);\n                    if(s-d >= 1 && s-d < s) Lc.push_back(s-d);\n                }\n                if(phase==LATE){\n                    for(int d=1; d<=4; ++d){\n                        if(d < s) Lc.push_back(d);\n                        if(s-d>=1 && s-d<s) Lc.push_back(s-d);\n                    }\n                }\n                for(int &v: Lc){ if(v<1) v=1; if(v>s-1) v=s-1; }\n                sort(Lc.begin(), Lc.end());\n                Lc.erase(unique(Lc.begin(), Lc.end()), Lc.end());\n                return Lc;\n            };\n            auto Lcands = build_Lcands(s);\n\n            for(auto [A,B] : normals){\n                proj.resize(s);\n                for(int i=0;i<s;++i){\n                    const auto &p = pts[idxs[i]];\n                    proj[i] = dotAB(A,B,p.x,p.y);\n                }\n                sort(proj.begin(), proj.end());\n\n                auto get_gap_for_l = [&](int l, long long &vL, long long &vR, int &lChosen)->bool{\n                    if(l<1 || l>=s) return false;\n                    int i = l-1;\n                    long long aL = proj[i], aR = proj[i+1];\n                    if(aL < aR){\n                        vL = aL; vR = aR; lChosen = l; return true;\n                    }\n                    int il = i; while(il>=0 && proj[il]==aL) --il;\n                    int ir = i+1; while(ir<s && proj[ir]==aR) ++ir;\n                    bool ok=false;\n                    long long vL1=0,vR1=0,vL2=0,vR2=0; int l1=-1,l2=-1;\n                    if(il>=0 && proj[il] < proj[il+1]){ vL1=proj[il]; vR1=proj[il+1]; l1=il+1; ok=true; }\n                    if(ir<s && proj[ir-1] < proj[ir]){ vL2=proj[ir-1]; vR2=proj[ir]; l2=ir; ok=true; }\n                    if(!ok) return false;\n                    if(l1==-1){ vL=vL2; vR=vR2; lChosen=l2; }\n                    else if(l2==-1){ vL=vL1; vR=vR1; lChosen=l1; }\n                    else{\n                        int d1 = abs(l1 - l), d2 = abs(l2 - l);\n                        if(d1 < d2 || (d1==d2 && (vR1-vL1) >= (vR2-vL2))){ vL=vL1; vR=vR1; lChosen=l1; }\n                        else { vL=vL2; vR=vR2; lChosen=l2; }\n                    }\n                    return true;\n                };\n\n                for(int lTarget : Lcands){\n                    long long vL, vR; int lChosen;\n                    if(!get_gap_for_l(lTarget, vL, vR, lChosen)) continue;\n                    long long T = (vL + vR) / 2;\n                    int leftSize = lChosen;\n                    int rightSize = s - lChosen;\n\n                    auto minA = [&](int d, int b){ return min(a[d], b); };\n                    long long delta = 0;\n                    if(leftSize<=10) delta += minA(leftSize, bd[leftSize]+1) - minA(leftSize, bd[leftSize]);\n                    if(rightSize<=10) delta += minA(rightSize, bd[rightSize]+1) - minA(rightSize, bd[rightSize]);\n                    if(s<=10) delta += minA(s, bd[s]-1) - minA(s, bd[s]);\n\n                    long long over10Penalty = 0;\n                    if(leftSize>10) over10Penalty -= (phase==LATE ? 2 : (phase==MID ? 1 : 0));\n                    if(rightSize>10) over10Penalty -= (phase==LATE ? 2 : (phase==MID ? 1 : 0));\n\n                    long long overs = 0;\n                    if(leftSize<=10 && bd[leftSize] >= a[leftSize]) overs -= (phase==LATE ? 2 : 1);\n                    if(rightSize<=10 && bd[rightSize] >= a[rightSize]) overs -= (phase==LATE ? 2 : 1);\n\n                    long long bonus = 0;\n                    if(leftSize<=10 && need[leftSize]>0) bonus += (phase==EARLY ? 1 : 2);\n                    if(rightSize<=10 && need[rightSize]>0) bonus += (phase==EARLY ? 1 : 2);\n\n                    long long balance = - llabs(leftSize - rightSize);\n                    if(phase==EARLY) balance *= 2;\n\n                    // protection for needed small s (relaxed in LATE)\n                    bool protect = (s<=10 && bd[s] < a[s] && phase!=LATE);\n                    if(protect && delta <= 0){\n                        bool anyHelp = false;\n                        if(leftSize<=10 && need[leftSize]>0) anyHelp = true;\n                        if(rightSize<=10 && need[rightSize]>0) anyHelp = true;\n                        if(!anyHelp) continue;\n                    }\n\n                    auto lookahead = [&](int size)->int{\n                        if(size<=1) return 0;\n                        int l2 = size/2;\n                        int r2 = size - l2;\n                        int gain = 0;\n                        if(l2<=10 && need[l2]>0) gain++;\n                        if(r2<=10 && need[r2]>0) gain++;\n                        return gain;\n                    };\n                    int la = lookahead(max(leftSize, rightSize));\n\n                    long long score = (delta<<24) + (bonus<<16) + (overs<<12) + (over10Penalty<<10) + (la<<8) + balance;\n\n                    if(phase==EARLY && s > 40){\n                        score += (long long)(-abs(leftSize - rightSize)) * 2;\n                    }\n\n                    if(score > bestScore){\n                        bestScore = score;\n                        bestLine = {A,B,T};\n                        found = true;\n                    }\n                }\n            }\n        }\n\n        if(!found){\n            // Tail fallback: split largest cell toward top need and balance\n            auto &idxs = cells[cands[0].second];\n            int s = (int)idxs.size();\n            int target = 1, bestNeed=0;\n            for(int d=1; d<=10; ++d) if(need[d]>bestNeed){ bestNeed=need[d]; target=d; }\n            vector<int> targets;\n            if(target < s) targets.push_back(target);\n            if(s-target >= 1 && s-target < s) targets.push_back(s-target);\n            targets.push_back(s/2);\n            targets.push_back(max(1, s/3));\n            targets.push_back(max(1, (2*s)/3));\n\n            // PCA normal and axes\n            // Compute PCA\n            long double meanx=0, meany=0;\n            for(int id: idxs){ meanx += pts[id].x; meany += pts[id].y; }\n            meanx/=s; meany/=s;\n            long double cxx=0,cxy=0,cyy=0;\n            for(int id: idxs){\n                long double dx=(long double)pts[id].x-meanx;\n                long double dy=(long double)pts[id].y-meany;\n                cxx+=dx*dx; cxy+=dx*dy; cyy+=dy*dy;\n            }\n            long double tr=cxx+cyy, det=cxx*cyy-cxy*cxy;\n            long double tmp=max((long double)0.0L, tr*tr/4-det);\n            long double l1=tr/2+sqrtl(tmp);\n            long double vx,vy;\n            if(fabsl(cxy)>1e-14L){ vx=l1-cyy; vy=cxy; } else { if(cxx>=cyy){ vx=1; vy=0; } else { vx=0; vy=1; } }\n            long double normv = sqrtl(vx*vx+vy*vy); if(normv<1e-18L){ vx=1; vy=0; normv=1; } vx/=normv; vy/=normv;\n            long double nx=-vy, ny=vx;\n            auto to_small = [&](long double nx,long double ny){ int A=(int)llround(nx*12.0L); int B=(int)llround(ny*12.0L); if(A==0&&B==0)A=1; reduce_coprime(A,B); return pair<int,int>(A,B); };\n            auto pca = to_small(nx,ny);\n            vector<pair<int,int>> normals = { {1,0},{0,1}, pca };\n\n            int A_best=1,B_best=0; long long T_best=0; bool got=false;\n            for(auto [A,B] : normals){\n                proj.resize(s);\n                for(int i=0;i<s;++i) proj[i]=dotAB(A,B,pts[idxs[i]].x, pts[idxs[i]].y);\n                sort(proj.begin(), proj.end());\n                for(int l : targets){\n                    if(l<1 || l>=s) continue;\n                    long long vL = proj[l-1], vR = proj[l];\n                    if(vL==vR){\n                        int il=l-1; while(il>=0 && proj[il]==vL) --il;\n                        int ir=l; while(ir<s && proj[ir]==vR) ++ir;\n                        if(il>=0){ vL=proj[il]; vR=proj[il+1]; }\n                        else if(ir<s){ vL=proj[ir-1]; vR=proj[ir]; }\n                        else continue;\n                    }\n                    long long T=(vL+vR)/2;\n                    A_best=A; B_best=B; T_best=T; got=true; break;\n                }\n                if(got) break;\n            }\n            bestLine = {A_best,B_best,T_best};\n        }\n\n        // Commit line\n        int bitIndex = (int)lines.size();\n        lines.push_back(bestLine);\n        for(int i=0;i<N;++i){\n            long long v = dotAB(bestLine.A, bestLine.B, pts[i].x, pts[i].y);\n            bool left = (v <= bestLine.T);\n            if(bitIndex < 64){\n                if(left) sig[i].a |= (1ULL<<bitIndex);\n            }else{\n                int bi = bitIndex-64;\n                if(left) sig[i].b |= (1ULL<<bi);\n            }\n        }\n        recompute();\n        cutsLeft--;\n    }\n\n    // Output\n    cout << (int)lines.size() << \"\\n\";\n    for(auto &L : lines){\n        auto pp = two_points_on_line(L.A, L.B, L.T);\n        auto [p0, p1] = pp;\n        cout << p0.first << \" \" << p0.second << \" \" << p1.first << \" \" << p1.second << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct P { int x,y; };\n\nstatic inline int64_t w_of(int x,int y,int c){\n    int dx=x-c, dy=y-c;\n    return int64_t(dx)*dx + int64_t(dy)*dy + 1;\n}\n\nstruct Candidate{\n    // rectangle in order: p1=new point, then others around perimeter\n    P p1,p2,p3,p4;\n    int64_t score;\n};\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    vector<P> init(M);\n    for(int i=0;i<M;i++){ cin>>init[i].x>>init[i].y; }\n    int c=(N-1)/2;\n\n    // Occupancy grid\n    vector<vector<char>> occ(N, vector<char>(N, 0));\n    for(auto &p:init) occ[p.x][p.y]=1;\n\n    // Edge usage: used horizontal edges H[y][x] for (x,y)-(x+1,y), x in [0..N-2], y in [0..N-1]\n    vector<vector<char>> usedH(N, vector<char>(N-1, 0));\n    // Vertical edges V[x][y] for (x,y)-(x,y+1), x in [0..N-1], y in [0..N-2]\n    vector<vector<char>> usedV(N, vector<char>(N-1, 0));\n\n    // Maintain list of occupied points per row/col for faster enumeration\n    vector<vector<int>> rows(N), cols(N);\n    auto rebuild_index = [&](){\n        for(int y=0;y<N;y++){ rows[y].clear(); }\n        for(int x=0;x<N;x++){ cols[x].clear(); }\n        for(int x=0;x<N;x++) for(int y=0;y<N;y++) if(occ[x][y]){\n            rows[y].push_back(x);\n            cols[x].push_back(y);\n        }\n        for(int y=0;y<N;y++) sort(rows[y].begin(), rows[y].end());\n        for(int x=0;x<N;x++) sort(cols[x].begin(), cols[x].end());\n    };\n    rebuild_index();\n\n    // Candidate generation full enumeration (axis-aligned):\n    auto build_candidates = [&](vector<Candidate>& out){\n        out.clear();\n        const size_t CAP = 40000;\n        for(int xb=0; xb<N; xb++){\n            for(int yb=0; yb<N; yb++){\n                if(!occ[xb][yb]) continue;\n                const auto& row = rows[yb];\n                const auto& col = cols[xb];\n                if(row.empty() || col.empty()) continue;\n                for(int xa : row){\n                    if(xa==xb) continue;\n                    for(int yc : col){\n                        if(yc==yb) continue;\n                        int xd = xa;\n                        int yd = yc;\n                        if(occ[xd][yd]) continue;\n                        // define rectangle order p1=D, p2=A, p3=B, p4=C:\n                        P D{xd,yd}, A{xa,yb}, B{xb,yb}, C{xb,yc};\n                        // perimeter dot check\n                        auto ok_line = [&](int x1,int y1,int x2,int y2)->bool{\n                            if(x1==x2){\n                                int x=x1;\n                                int ylo=min(y1,y2), yhi=max(y1,y2);\n                                for(int y=ylo; y<=yhi; y++){\n                                    if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                                    if(occ[x][y]) return false;\n                                }\n                            }else if(y1==y2){\n                                int y=y1;\n                                int xlo=min(x1,x2), xhi=max(x1,x2);\n                                for(int x=xlo; x<=xhi; x++){\n                                    if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                                    if(occ[x][y]) return false;\n                                }\n                            }else{\n                                return false;\n                            }\n                            return true;\n                        };\n                        if(!ok_line(D.x,D.y,A.x,A.y)) continue;\n                        if(!ok_line(A.x,A.y,B.x,B.y)) continue;\n                        if(!ok_line(B.x,B.y,C.x,C.y)) continue;\n                        if(!ok_line(C.x,C.y,D.x,D.y)) continue;\n                        // edge overlap check without marking now\n                        auto edges_free = [&]()->bool{\n                            auto check_edge = [&](int x1,int y1,int x2,int y2)->bool{\n                                if(x1==x2){\n                                    int x=x1;\n                                    int ylo=min(y1,y2), yhi=max(y1,y2);\n                                    for(int y=ylo; y<yhi; y++) if(usedV[x][y]) return false;\n                                }else{\n                                    int y=y1;\n                                    int xlo=min(x1,x2), xhi=max(x1,x2);\n                                    for(int x=xlo; x<xhi; x++) if(usedH[y][x]) return false;\n                                }\n                                return true;\n                            };\n                            return check_edge(D.x,D.y,A.x,A.y) && check_edge(A.x,A.y,B.x,B.y)\n                                && check_edge(B.x,B.y,C.x,C.y) && check_edge(C.x,C.y,D.x,D.y);\n                        };\n                        if(!edges_free()) continue;\n                        Candidate cand;\n                        cand.p1=D; cand.p2=A; cand.p3=B; cand.p4=C;\n                        cand.score = w_of(D.x,D.y,c);\n                        out.push_back(cand);\n                        if(out.size() >= CAP) return;\n                    }\n                }\n            }\n        }\n    };\n\n    vector<array<int,8>> answer;\n    answer.reserve(100000);\n\n    auto apply_rect = [&](const Candidate& cand){\n        const P &D=cand.p1, &A=cand.p2, &B=cand.p3, &C=cand.p4;\n        // Mark edges\n        auto mark_edge = [&](int x1,int y1,int x2,int y2){\n            if(x1==x2){\n                int x=x1;\n                int ylo=min(y1,y2), yhi=max(y1,y2);\n                for(int y=ylo; y<yhi; y++) usedV[x][y]=1;\n            }else{\n                int y=y1;\n                int xlo=min(x1,x2), xhi=max(x1,x2);\n                for(int x=xlo; x<xhi; x++) usedH[y][x]=1;\n            }\n        };\n        mark_edge(D.x,D.y,A.x,A.y);\n        mark_edge(A.x,A.y,B.x,B.y);\n        mark_edge(B.x,B.y,C.x,C.y);\n        mark_edge(C.x,C.y,D.x,D.y);\n        // Place dot\n        occ[D.x][D.y]=1;\n        rows[D.y].push_back(D.x);\n        cols[D.x].push_back(D.y);\n        // Record\n        array<int,8> op = {D.x,D.y, A.x,A.y, B.x,B.y, C.x,C.y};\n        answer.push_back(op);\n    };\n\n    // Main greedy loop\n    auto t_start = chrono::steady_clock::now();\n    const double TIME_LIMIT = 4.8; // seconds\n    int iter = 0;\n    while(true){\n        if(iter % 10 == 0){\n            auto t_now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(t_now - t_start).count();\n            if(elapsed > TIME_LIMIT) break;\n        }\n        if(iter % 50 == 0) rebuild_index();\n\n        vector<Candidate> cands;\n        build_candidates(cands);\n        if(cands.empty()) break;\n        // sort by score descending, minor tiebreaker by perimeter length\n        stable_sort(cands.begin(), cands.end(), [&](const Candidate& a, const Candidate& b){\n            if(a.score != b.score) return a.score > b.score;\n            int per_a = abs(a.p1.x - a.p3.x) + abs(a.p1.y - a.p3.y) + abs(a.p2.x - a.p4.x) + abs(a.p2.y - a.p4.y);\n            int per_b = abs(b.p1.x - b.p3.x) + abs(b.p1.y - b.p3.y) + abs(b.p2.x - b.p4.x) + abs(b.p2.y - b.p4.y);\n            return per_a > per_b;\n        });\n        bool placed = false;\n        for(const auto& cand : cands){\n            const P &D=cand.p1, &A=cand.p2, &B=cand.p3, &C=cand.p4;\n            if(occ[D.x][D.y]) continue;\n            // recheck perimeter cleanliness and edges\n            auto ok_line = [&](int x1,int y1,int x2,int y2)->bool{\n                if(x1==x2){\n                    int x=x1;\n                    int ylo=min(y1,y2), yhi=max(y1,y2);\n                    for(int y=ylo; y<=yhi; y++){\n                        if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                        if(occ[x][y]) return false;\n                    }\n                }else if(y1==y2){\n                    int y=y1;\n                    int xlo=min(x1,x2), xhi=max(x1,x2);\n                    for(int x=xlo; x<=xhi; x++){\n                        if((x==D.x && y==D.y) || (x==A.x && y==A.y) || (x==B.x && y==B.y) || (x==C.x && y==C.y)) continue;\n                        if(occ[x][y]) return false;\n                    }\n                }else{\n                    return false;\n                }\n                return true;\n            };\n            if(!ok_line(D.x,D.y,A.x,A.y)) continue;\n            if(!ok_line(A.x,A.y,B.x,B.y)) continue;\n            if(!ok_line(B.x,B.y,C.x,C.y)) continue;\n            if(!ok_line(C.x,C.y,D.x,D.y)) continue;\n\n            auto edges_free = [&]()->bool{\n                auto check_edge = [&](int x1,int y1,int x2,int y2)->bool{\n                    if(x1==x2){\n                        int x=x1;\n                        int ylo=min(y1,y2), yhi=max(y1,y2);\n                        for(int y=ylo; y<yhi; y++) if(usedV[x][y]) return false;\n                    }else{\n                        int y=y1;\n                        int xlo=min(x1,x2), xhi=max(x1,x2);\n                        for(int x=xlo; x<xhi; x++) if(usedH[y][x]) return false;\n                    }\n                    return true;\n                };\n                return check_edge(D.x,D.y,A.x,A.y) && check_edge(A.x,A.y,B.x,B.y)\n                    && check_edge(B.x,B.y,C.x,C.y) && check_edge(C.x,C.y,D.x,D.y);\n            };\n            if(!edges_free()) continue;\n\n            apply_rect(cand);\n            placed = true;\n            break;\n        }\n        if(!placed) break;\n        iter++;\n    }\n\n    cout<< (int)answer.size() << \"\\n\";\n    for(auto &op: answer){\n        for(int i=0;i<8;i++){\n            if(i) cout<<' ';\n            cout<<op[i];\n        }\n        cout<<\"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Board {\n    static constexpr int H=10, W=10;\n    array<array<int,W>,H> g{};\n    void clear(){ for(int i=0;i<H;i++) for(int j=0;j<W;j++) g[i][j]=0; }\n\n    pair<int,int> place_by_index(int p, int f){\n        int cnt=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                if(g[i][j]==0){\n                    ++cnt;\n                    if(cnt==p){\n                        g[i][j]=f;\n                        return {i,j};\n                    }\n                }\n            }\n        }\n        return {-1,-1};\n    }\n\n    Board tilt(char dir) const {\n        Board b=*this;\n        if(dir=='F'){ // up\n            for(int j=0;j<W;j++){\n                int w=0;\n                for(int i=0;i<H;i++){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        if(i!=w){ b.g[i][j]=0; b.g[w][j]=v; }\n                        ++w;\n                    }\n                }\n            }\n        } else if(dir=='B'){ // down\n            for(int j=0;j<W;j++){\n                int w=H-1;\n                for(int i=H-1;i>=0;i--){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        if(i!=w){ b.g[i][j]=0; b.g[w][j]=v; }\n                        --w;\n                    }\n                }\n            }\n        } else if(dir=='L'){ // left\n            for(int i=0;i<H;i++){\n                int w=0;\n                for(int j=0;j<W;j++){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        if(j!=w){ b.g[i][j]=0; b.g[i][w]=v; }\n                        ++w;\n                    }\n                }\n            }\n        } else { // 'R' right\n            for(int i=0;i<H;i++){\n                int w=W-1;\n                for(int j=W-1;j>=0;j--){\n                    if(b.g[i][j]){\n                        int v=b.g[i][j];\n                        if(j!=w){ b.g[i][j]=0; b.g[i][w]=v; }\n                        --w;\n                    }\n                }\n            }\n        }\n        return b;\n    }\n\n    bool equals(const Board& o) const {\n        for(int i=0;i<H;i++) for(int j=0;j<W;j++) if(g[i][j]!=o.g[i][j]) return false;\n        return true;\n    }\n};\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    DSU(int n=0): n(n), p(n), r(n,0){ iota(p.begin(), p.end(), 0); }\n    int find(int a){ return p[a]==a?a:p[a]=find(p[a]); }\n    void unite(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a; if(r[a]==r[b]) r[a]++;\n    }\n};\n\nstruct Heuristic {\n    array<pair<int,int>,4> anchor;\n    array<array<int,4>,4> edgePref{}; // [T,B,L,R]\n\n    // weights\n    int w_adj_same = 7;\n    int w_adj_diff = 2;\n    int w_dist = 1;\n    int w_boundaries = 2;\n    int w_cc = 16;\n    int w_edge = 2;\n    int w_corner = 1;\n    int w_line_seg = 2;\n    int w_wall_line = 4;\n    int w_merge_potential = 1;\n    int w_good_empty_next = 3;\n\n    // zone assignment\n    int flavorTopLeft=1, flavorTopRight=2, flavorBottom=3;\n    bool bottomRight=false;\n\n    Heuristic(){\n        anchor[1]={0,0}; anchor[2]={0,9}; anchor[3]={9,0};\n        edgePref[1]={1,0,1,0};\n        edgePref[2]={1,0,0,1};\n        edgePref[3]={0,1,1,0};\n    }\n\n    void setup_anchors_by_counts_and_early(const array<int,4>& cnt, const vector<int>& early){\n        array<int,3> ids = {1,2,3};\n        sort(ids.begin(), ids.end(), [&](int a,int b){ return cnt[a]>cnt[b]; });\n        int A=ids[0], B=ids[1], C=ids[2];\n        flavorTopLeft=A; flavorTopRight=B; flavorBottom=C;\n\n        anchor[A]={0,0}; edgePref[A]={1,0,1,0};\n        anchor[B]={0,9}; edgePref[B]={1,0,0,1};\n\n        int earlyTake = min<int>(20, early.size());\n        int earlyA=0, earlyB=0;\n        for(int i=0;i<earlyTake;i++){\n            if(early[i]==A) earlyA++;\n            else if(early[i]==B) earlyB++;\n        }\n        if(earlyB > earlyA){\n            bottomRight = false; // bottom-left\n            anchor[C]={9,0}; edgePref[C]={0,1,1,0};\n        }else{\n            bottomRight = true; // bottom-right\n            anchor[C]={9,9}; edgePref[C]={0,1,0,1};\n        }\n    }\n\n    void nudge_anchors(const Board& b){\n        array<long long,4> si{}, sj{}, cnt{};\n        for(int i=0;i<Board::H;i++){\n            for(int j=0;j<Board::W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                si[v]+=i; sj[v]+=j; cnt[v]++;\n            }\n        }\n        auto clamp = [&](int x,int lo,int hi){ return max(lo, min(hi, x)); };\n        auto zone = [&](int fl)->array<int,4>{\n            if(fl==flavorTopLeft) return array<int,4>{0, 5, 0, 5};\n            if(fl==flavorTopRight) return array<int,4>{0, 5, 4, 9};\n            if(bottomRight) return array<int,4>{4, 9, 4, 9};\n            else return array<int,4>{4, 9, 0, 5};\n        };\n        for(int fl=1; fl<=3; fl++){\n            if(cnt[fl]==0) continue;\n            int ci = int(si[fl]/cnt[fl]);\n            int cj = int(sj[fl]/cnt[fl]);\n            auto z = zone(fl);\n            int ti = clamp(ci, z[0], z[1]);\n            int tj = clamp(cj, z[2], z[3]);\n            auto [ai,aj] = anchor[fl];\n            if(ai < ti) ai++; else if(ai > ti) ai--;\n            if(aj < tj) aj++; else if(aj > tj) aj--;\n            ai = clamp(ai, z[0], z[1]);\n            aj = clamp(aj, z[2], z[3]);\n            anchor[fl] = {ai,aj};\n        }\n    }\n\n    int adj_score(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int same=0, diff=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                if(i+1<H && b.g[i+1][j]){\n                    if(b.g[i+1][j]==v) same++; else diff++;\n                }\n                if(j+1<W && b.g[i][j+1]){\n                    if(b.g[i][j+1]==v) same++; else diff++;\n                }\n            }\n        }\n        return w_adj_same*same - w_adj_diff*diff;\n    }\n\n    int distance_score(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                auto [ai,aj]=anchor[v];\n                sc -= w_dist * (abs(i-ai)+abs(j-aj));\n                int d = abs(i-ai)+abs(j-aj);\n                if(d<=2) sc += w_corner*(3-d);\n            }\n        }\n        return sc;\n    }\n\n    int boundaries_penalty(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int boundaries=0;\n        for(int i=0;i<H;i++){\n            int prev = 0;\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(prev && v && v!=prev) boundaries++;\n                if(v) prev=v;\n            }\n        }\n        for(int j=0;j<W;j++){\n            int prev = 0;\n            for(int i=0;i<H;i++){\n                int v=b.g[i][j];\n                if(prev && v && v!=prev) boundaries++;\n                if(v) prev=v;\n            }\n        }\n        return -w_boundaries * boundaries;\n    }\n\n    int cc_penalty_and_maxcc(const Board& b, int& maxcc_out) const {\n        int H=Board::H, W=Board::W;\n        int F=H*W;\n        DSU dsu(F);\n        auto id = [&](int i,int j){ return i*W + j; };\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                if(i+1<H && b.g[i+1][j]==v) dsu.unite(id(i,j), id(i+1,j));\n                if(j+1<W && b.g[i][j+1]==v) dsu.unite(id(i,j), id(i,j+1));\n            }\n        }\n        array<unordered_map<int,int>,4> compSize;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                int r = dsu.find(id(i,j));\n                compSize[v][r]++;\n            }\n        }\n        int cc = 0;\n        int maxcc = 0;\n        for(int fl=1; fl<=3; fl++){\n            cc += (int)compSize[fl].size();\n            for(auto &kv: compSize[fl]){\n                maxcc = max(maxcc, kv.second);\n            }\n        }\n        maxcc_out = maxcc;\n        return -w_cc * cc;\n    }\n\n    int edge_reward(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(!v) continue;\n                auto pref = edgePref[v];\n                if(i==0) sc += w_edge * pref[0];\n                if(i==H-1) sc += w_edge * pref[1];\n                if(j==0) sc += w_edge * pref[2];\n                if(j==W-1) sc += w_edge * pref[3];\n            }\n        }\n        return sc;\n    }\n\n    int line_segment_reward(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        // rows\n        for(int i=0;i<H;i++){\n            int len=0, col=0;\n            for(int j=0;j<W;j++){\n                int v=b.g[i][j];\n                if(v && v==col) len++;\n                else{\n                    if(col && len>=2) sc += w_line_seg * (len-1);\n                    col=v; len = (v?1:0);\n                }\n            }\n            if(col && len>=2) sc += w_line_seg * (len-1);\n        }\n        // cols\n        for(int j=0;j<W;j++){\n            int len=0, col=0;\n            for(int i=0;i<H;i++){\n                int v=b.g[i][j];\n                if(v && v==col) len++;\n                else{\n                    if(col && len>=2) sc += w_line_seg * (len-1);\n                    col=v; len = (v?1:0);\n                }\n            }\n            if(col && len>=2) sc += w_line_seg * (len-1);\n        }\n        return sc;\n    }\n\n    int wall_line_reward(const Board& b) const {\n        // Reward presence of flavors on their favored boundary walls\n        int H=Board::H, W=Board::W;\n        int sc=0;\n        for(int j=0;j<W;j++){\n            if(b.g[0][j]==flavorTopLeft) sc += w_wall_line;\n            if(b.g[0][j]==flavorTopRight) sc += w_wall_line;\n        }\n        for(int i=0;i<H;i++){\n            if(b.g[i][0]==flavorTopLeft) sc += w_wall_line;\n            if(!bottomRight && b.g[i][0]==flavorBottom) sc += w_wall_line;\n        }\n        for(int i=0;i<H;i++){\n            if(b.g[i][W-1]==flavorTopRight) sc += w_wall_line;\n            if(bottomRight && b.g[i][W-1]==flavorBottom) sc += w_wall_line;\n        }\n        for(int j=0;j<W;j++){\n            if(b.g[H-1][j]==flavorBottom) sc += w_wall_line;\n        }\n        return sc;\n    }\n\n    int merge_potential(const Board& b) const {\n        int H=Board::H, W=Board::W;\n        static const int di[4]={-1,1,0,0};\n        static const int dj[4]={0,0,-1,1};\n        int pot=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                if(b.g[i][j]!=0) continue; // empty cell\n                array<int,4> seen{}; // flavors seen around\n                for(int d=0; d<4; d++){\n                    int ni=i+di[d], nj=j+dj[d];\n                    if(ni<0||ni>=H||nj<0||nj>=W) continue;\n                    int v=b.g[ni][nj];\n                    if(v) seen[v]=1;\n                }\n                pot += seen[1]+seen[2]+seen[3];\n            }\n        }\n        return w_merge_potential * pot;\n    }\n\n    int good_empty_for_flavor(const Board& b, int fl) const {\n        int H=Board::H, W=Board::W;\n        static const int di[4]={-1,1,0,0};\n        static const int dj[4]={0,0,-1,1};\n        int cnt=0;\n        for(int i=0;i<H;i++){\n            for(int j=0;j<W;j++){\n                if(b.g[i][j]!=0) continue;\n                bool good=false;\n                for(int d=0; d<4; d++){\n                    int ni=i+di[d], nj=j+dj[d];\n                    if(ni<0||ni>=H||nj<0||nj>=W) continue;\n                    if(b.g[ni][nj]==fl){ good=true; break; }\n                }\n                if(good) cnt++;\n            }\n        }\n        return w_good_empty_next * cnt;\n    }\n\n    int score(const Board& b, int& maxcc_out) const {\n        int s=0;\n        s += adj_score(b);\n        s += distance_score(b);\n        s += boundaries_penalty(b);\n        s += edge_reward(b);\n        s += line_segment_reward(b);\n        s += wall_line_reward(b);\n        s += merge_potential(b);\n        int maxcc=0;\n        s += cc_penalty_and_maxcc(b, maxcc);\n        maxcc_out = maxcc;\n        // tiny deterministic tie-breaker\n        uint32_t h=2166136261u;\n        for(int i=0;i<Board::H;i++) for(int j=0;j<Board::W;j++){\n            h ^= uint32_t(b.g[i][j]+1); h *= 16777619u;\n        }\n        s += int(h%3)-1;\n        return s;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    vector<int> f(100);\n    for(int i=0;i<100;i++){\n        if(!(cin>>f[i])) return 0;\n    }\n    array<int,4> cnt{}; cnt.fill(0);\n    for(int x: f) cnt[x]++;\n\n    Board board; board.clear();\n    Heuristic H;\n    H.setup_anchors_by_counts_and_early(cnt, f);\n\n    const array<char,4> dirs = {'F','B','L','R'};\n    char lastMove = 'F';\n\n    for(int t=0;t<100;t++){\n        int p;\n        if(!(cin>>p)) return 0;\n        board.place_by_index(p, f[t]);\n\n        if(t%10==0) H.nudge_anchors(board);\n\n        if(t==99){\n            continue; // skip final tilt\n        }\n\n        int bestScore = INT_MIN;\n        char bestDir = 'F';\n        Board bestBoard = board;\n        int bestMaxCC = -1;\n        bool bestNoop = false;\n\n        int nextFlavor = f[t+1]; // known\n\n        array<int,4> combinedScore{};\n        array<int,4> maxcc1arr{};\n        array<bool,4> noopArr{};\n        array<Board,4> b1arr;\n\n        for(int idx=0; idx<4; idx++){\n            char d1 = dirs[idx];\n            Board b1 = board.tilt(d1);\n            b1arr[idx] = b1;\n            int maxcc1=0;\n            int s1 = H.score(b1, maxcc1);\n\n            array<char,4> cand2;\n            if(d1=='F' || d1=='B') cand2 = {'L','R','F','B'};\n            else cand2 = {'F','B','L','R'};\n\n            int bestSecond = INT_MIN;\n            for(int k=0;k<4;k++){\n                char d2 = cand2[k];\n                Board b2 = b1.tilt(d2);\n                int maxcc2=0;\n                int s2 = H.score(b2, maxcc2);\n                s2 += H.good_empty_for_flavor(b2, nextFlavor);\n                s2 += maxcc2;\n                bestSecond = max(bestSecond, s2);\n            }\n\n            int combined = bestSecond + s1/3;\n\n            auto nonEmptyLines = [&](const Board& after, char dir)->int{\n                int cntLines=0;\n                if(dir=='F' || dir=='B'){\n                    vector<int> occ(Board::H,0);\n                    for(int i=0;i<Board::H;i++){\n                        for(int j=0;j<Board::W;j++){\n                            if(after.g[i][j]){ occ[i]=1; break; }\n                        }\n                    }\n                    for(int i=0;i<Board::H;i++) cntLines += occ[i];\n                }else{\n                    vector<int> occ(Board::W,0);\n                    for(int j=0;j<Board::W;j++){\n                        for(int i=0;i<Board::H;i++){\n                            if(after.g[i][j]){ occ[j]=1; break; }\n                        }\n                    }\n                    for(int j=0;j<Board::W;j++) cntLines += occ[j];\n                }\n                return cntLines;\n            };\n            int lines = nonEmptyLines(b1, d1);\n            combined -= lines;\n\n            bool isNoop = b1.equals(board);\n            if(isNoop) combined -= 1;\n\n            combinedScore[idx] = combined;\n            maxcc1arr[idx] = maxcc1;\n            noopArr[idx] = isNoop;\n        }\n\n        // Choose best with safe tie-breaking\n        int bestIdx = -1;\n        for(int idx=0; idx<4; idx++){\n            if(bestIdx==-1 ||\n               combinedScore[idx] > combinedScore[bestIdx] ||\n               (combinedScore[idx] == combinedScore[bestIdx] && maxcc1arr[idx] > maxcc1arr[bestIdx]) ||\n               (combinedScore[idx] == combinedScore[bestIdx] && maxcc1arr[idx] == maxcc1arr[bestIdx] &&\n                ((dirs[idx]==lastMove && !noopArr[idx]) || bestIdx==-1))) {\n                bestIdx = idx;\n            }\n        }\n        bestDir = dirs[bestIdx];\n        bestBoard = b1arr[bestIdx];\n\n        cout << bestDir << '\\n' << flush;\n        lastMove = bestDir;\n        board = bestBoard;\n    }\n\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\n\nusing ull = unsigned long long;\n\nstruct XorShift64 {\n    uint64_t x;\n    XorShift64(uint64_t s=88172645463393265ull){ if(!s) s=1; x=s; }\n    uint64_t rng(){ uint64_t y=x; y^=y<<7; y^=y>>9; return x=y; }\n    double drand(){ return (rng() >> 11) * (1.0/9007199254740992.0); } // [0,1)\n    int irand(int L,int R){ return L + (int)(rng() % (uint64_t)(R-L+1)); }\n};\n\nstatic inline int idx_pair(int N,int i,int j){ // i<j\n    return i*N - i*(i+1)/2 + (j - i - 1);\n}\n\nstruct Features {\n    vector<double> deg_hist;\n    vector<int> deg_sorted;\n    vector<double> deg_buckets;\n    vector<int> core_sorted;\n    vector<double> core_hist;\n    vector<double> eigA;   // standardized\n    vector<double> eigLN;  // standardized\n    vector<double> nbrdeg_hist;\n    vector<double> nbr_deg_buck;\n    vector<double> wedge_hist;\n    struct Sig { int deg; int sumNbr; int core; int avgNbr; int wl_bucket; };\n    vector<Sig> local_sigs_sorted;\n    vector<double> local_bucket_hist;\n    double deg_m2 = 0.0, deg_m3 = 0.0;\n    double lap_spec_sum = 0.0;\n    double assort_proxy = 0.0;\n    vector<double> wl_hist; // WL histogram\n    double deg_gini = 0.0;  // new: degree Gini proxy\n    double eig_gap_proxy = 0.0; // from normalized Laplacian eigenvalues (shape-based)\n};\n\nstruct TemplateG {\n    vector<uint8_t> bits;\n    vector<int> deg;\n    Features feat;\n};\n\nstatic vector<int> kcore_decomposition(int N, const vector<uint8_t>& bits){\n    vector<int> deg(N,0);\n    vector<vector<int>> adj(N);\n    for(int i=0;i<N;i++){\n        for(int j=i+1;j<N;j++){\n            if(bits[idx_pair(N,i,j)]){\n                deg[i]++; deg[j]++;\n                adj[i].push_back(j);\n                adj[j].push_back(i);\n            }\n        }\n    }\n    int maxd = 0;\n    for(int d:deg) maxd = max(maxd, d);\n    vector<int> bin(maxd+1,0);\n    for(int d:deg) bin[d]++;\n    vector<int> start(maxd+1,0);\n    int sum=0;\n    for(int d=0; d<=maxd; d++){ start[d]=sum; sum+=bin[d]; }\n    vector<int> pos(N), vert(N);\n    vector<int> cnt = start;\n    for(int v=0; v<N; v++){\n        pos[v] = cnt[deg[v]]++;\n        vert[pos[v]] = v;\n    }\n    vector<int> core = deg;\n    for(int i=0;i<N;i++){\n        int v = vert[i];\n        for(int u: adj[v]){\n            if(core[u] > core[v]){\n                int du = core[u];\n                int pu = pos[u];\n                int pw = start[du];\n                int w = vert[pw];\n                if(u != w){\n                    vert[pu] = w; pos[w] = pu;\n                    vert[pw] = u; pos[u] = pw;\n                }\n                start[du]++; core[u]--;\n            }\n        }\n    }\n    return core;\n}\n\n// Hungarian algorithm for assignment; cost matrix size P x P\nstatic double hungarian_min_cost(const vector<vector<double>>& cost){\n    int n = (int)cost.size();\n    if(n==0) return 0.0;\n    const double INF = 1e18;\n    vector<double> u(n+1,0), v(n+1,0);\n    vector<int> p(n+1,0), way(n+1,0);\n    for(int i=1;i<=n;i++){\n        p[0] = i;\n        int j0 = 0;\n        vector<double> minv(n+1, INF);\n        vector<char> used(n+1, false);\n        do{\n            used[j0] = true;\n            int i0 = p[j0], j1 = 0;\n            double delta = INF;\n            for(int j=1;j<=n;j++) if(!used[j]){\n                double cur = cost[i0-1][j-1] - u[i0] - v[j];\n                if(cur < minv[j]){ minv[j] = cur; way[j] = j0; }\n                if(minv[j] < delta){ delta = minv[j]; j1 = j; }\n            }\n            for(int j=0;j<=n;j++){\n                if(used[j]){ u[p[j]] += delta; v[j] -= delta; }\n                else minv[j] -= delta;\n            }\n            j0 = j1;\n        }while(p[j0]!=0);\n        do{\n            int j1 = way[j0];\n            p[j0] = p[j1];\n            j0 = j1;\n        }while(j0);\n    }\n    double total = 0.0;\n    for(int j=1;j<=n;j++){\n        int i = p[j];\n        if(i>=1) total += cost[i-1][j-1];\n    }\n    return total / n;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double eps;\n    if(!(cin>>M>>eps)) return 0;\n\n    // Adaptive N\n    int N;\n    if (eps <= 0.04) N = 32;\n    else if (eps <= 0.12) N = 48;\n    else if (eps <= 0.24) N = 64;\n    else if (eps <= 0.32) N = 84;\n    else N = 100;\n    if (M >= 90 && eps <= 0.04) N = 36;\n    N = max(4, min(100, N));\n\n    uint64_t seed = 1469598103934665603ull ^ (uint64_t)M * 1099511628211ull ^ (uint64_t)llround(eps*100.0+0.5);\n\n    auto initial_blocks = [&](int B){\n        vector<int> block(N);\n        for(int i=0;i<N;i++) block[i] = (long long)i * B / N;\n        return block;\n    };\n\n    auto add_backbone = [&](vector<uint8_t>& bits, int k){\n        if (N < 10) return;\n        int cycleSize = 8;\n        int step = max(1, N / cycleSize);\n        vector<int> cyc;\n        cyc.reserve(cycleSize);\n        int pos = (k*7 + 3) % N;\n        for(int t=0;t<cycleSize;t++){\n            cyc.push_back(pos);\n            pos = (pos + step) % N;\n        }\n        for(int t=0;t<cycleSize;t++){\n            int u = cyc[t];\n            int v = cyc[(t+1)%cycleSize];\n            int a=min(u,v), b=max(u,v);\n            bits[idx_pair(N,a,b)] = 1;\n        }\n        for(int t=0;t<cycleSize/2;t++){\n            int u = cyc[t];\n            int widx = (t+2 + (k+t)%3) % cycleSize;\n            int v = cyc[widx];\n            int a=min(u,v), b=max(u,v);\n            bits[idx_pair(N,a,b)] = 1;\n        }\n    };\n\n    auto add_anchor_code = [&](vector<uint8_t>& bits, int A, uint64_t h){\n        if (N < A || A <= 1) return;\n        vector<int> anc(A);\n        for(int t=0;t<A;t++) anc[t] = (t * (N / A)) % N;\n        vector<int> deltas = {1, 3, 5, 7};\n        for(size_t bi=0; bi<deltas.size(); ++bi){\n            if ( (h >> bi) & 1ull ){\n                int d = deltas[bi] % A;\n                for(int t=0;t<A;t++){\n                    int u = anc[t];\n                    int v = anc[(t+d)%A];\n                    int a=min(u,v), b=max(u,v);\n                    bits[idx_pair(N,a,b)] = 1;\n                }\n            }\n        }\n    };\n\n    auto add_block_hub_edges = [&](vector<uint8_t>& bits, const vector<int>& blk, int B, int k){\n        if (B <= 1) return;\n        vector<int> rep(B, -1);\n        for(int i=0;i<N;i++){\n            int b = blk[i];\n            if (rep[b] == -1) rep[b] = i;\n        }\n        vector<int> reps;\n        for(int b=0;b<B;b++) if(rep[b]!=-1) reps.push_back(rep[b]);\n        int R = (int)reps.size();\n        if (R < 2) return;\n        for(int i=0;i<R;i++){\n            int u=reps[i], v=reps[(i+1)%R];\n            int a=min(u,v), b=max(u,v);\n            bits[idx_pair(N,a,b)] = 1;\n        }\n        if (R >= 4){\n            int s = 1 + (k % (R-1));\n            for(int i=0;i<R;i++){\n                int u=reps[i], v=reps[(i+s)%R];\n                int a=min(u,v), b=max(u,v);\n                bits[idx_pair(N,a,b)] = 1;\n            }\n        }\n    };\n\n    auto add_anchor_regular_overlay = [&](vector<uint8_t>& bits, int k){\n        int A = 20;\n        if (N < A) return;\n        vector<int> anc(A);\n        for(int t=0;t<A;t++) anc[t] = (t * (N / A)) % N;\n        for(int t=0;t<A;t++){\n            int u = anc[t], v = anc[(t+1)%A];\n            int a=min(u,v), b=max(u,v);\n            bits[idx_pair(N,a,b)] = 1;\n        }\n        int delta = 3 + (k % (A/2 - 2));\n        for(int t=0;t<A;t++){\n            int u = anc[t], v = anc[(t+delta)%A];\n            int a=min(u,v), b=max(u,v);\n            bits[idx_pair(N,a,b)] = 1;\n        }\n    };\n\n    auto rewiring_degree_palette = [&](vector<uint8_t>& bits, vector<int>& deg, const vector<int>& target, XorShift64& g){\n        int attempts = min( (int)(N*4), 1200 );\n        for(int it=0; it<attempts; ++it){\n            int v = g.irand(0, N-1);\n            if (deg[v] < target[v]){\n                int trials = 6;\n                while(trials--){\n                    int u = g.irand(0, N-1);\n                    if (u==v) continue;\n                    int a=min(u,v), b=max(u,v);\n                    int id = idx_pair(N, a, b);\n                    if (bits[id]==0){\n                        bits[id]=1;\n                        deg[u]++; deg[v]++;\n                        break;\n                    }\n                }\n            }else if (deg[v] > target[v]){\n                int trials = 6;\n                while(trials--){\n                    int u = g.irand(0, N-1);\n                    if (u==v) continue;\n                    int a=min(u,v), b=max(u,v);\n                    int id = idx_pair(N, a, b);\n                    if (bits[id]==1){\n                        bits[id]=0;\n                        deg[u]--; deg[v]--;\n                        break;\n                    }\n                }\n            }\n        }\n    };\n\n    auto standardize = [](vector<double>& v){\n        if(v.empty()) return;\n        double mean=0; for(double x:v) mean += x; mean /= v.size();\n        double var=0; for(double x:v){ double d=x-mean; var+=d*d; }\n        var = sqrt(var + 1e-9);\n        if (var == 0) var = 1.0;\n        for(double &x:v) x = (x - mean) / var;\n    };\n\n    auto compute_assort_proxy_exact = [&](const vector<uint8_t>& bits, const vector<int>& deg)->double{\n        long long m=0;\n        long double sumx=0, sumy=0, sumxy=0, sumx2=0, sumy2=0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                if (bits[idx_pair(N,i,j)]){\n                    double x=deg[i], y=deg[j];\n                    m++;\n                    sumx+=x; sumy+=y; sumxy+=x*y; sumx2+=x*x; sumy2+=y*y;\n                }\n            }\n        }\n        if (m==0) return 0.0;\n        long double mx=sumx/m, my=sumy/m;\n        long double cov = sumxy/m - mx*my;\n        long double vx = sumx2/m - mx*mx;\n        long double vy = sumy2/m - my*my;\n        long double denom = sqrt(max((long double)1e-12, vx*vy));\n        double r = (double)(cov / denom);\n        if (!isfinite(r)) r=0.0;\n        return max(-1.0, min(1.0, r));\n    };\n\n    auto wl1_colors = [&](const vector<uint8_t>& bits, const vector<int>& deg, const vector<int>& core)->vector<int>{\n        const int DB=16, CB=16;\n        int Nn=N;\n        int dmax=*max_element(deg.begin(), deg.end());\n        int cmax=*max_element(core.begin(), core.end());\n        vector<int> col(Nn);\n        for(int i=0;i<Nn;i++){\n            int bd = min(DB-1, (int)((long long)deg[i]*DB/(long long)max(1,dmax+1)));\n            int bc = min(CB-1, (int)((long long)core[i]*CB/(long long)max(1,cmax+1)));\n            col[i] = bd*CB + bc;\n        }\n        vector<vector<int>> adj(Nn);\n        for(int i=0;i<Nn;i++){\n            for(int j=i+1;j<Nn;j++){\n                if (bits[idx_pair(Nn,i,j)]){\n                    adj[i].push_back(j);\n                    adj[j].push_back(i);\n                }\n            }\n        }\n        vector<int> newcol(Nn);\n        unordered_map<uint64_t,int> comp; comp.reserve(Nn*2);\n        int next_id=0;\n        for(int i=0;i<Nn;i++){\n            vector<int> mult;\n            mult.reserve(adj[i].size());\n            for(int v:adj[i]) mult.push_back(col[v]);\n            sort(mult.begin(), mult.end());\n            uint64_t h = 1469598103934665603ull ^ (uint64_t)(col[i]*1315423911u);\n            for(int c:mult){\n                h ^= (uint64_t)c + 0x9e3779b97f4a7c15ull + (h<<6) + (h>>2);\n            }\n            auto it = comp.find(h);\n            if (it==comp.end()){\n                comp.emplace(h, next_id);\n                newcol[i] = next_id++;\n            }else newcol[i] = it->second;\n        }\n        return newcol;\n    };\n\n    auto compute_features = [&](const vector<uint8_t>& bits)->pair<vector<int>, Features>{\n        Eigen::MatrixXd A(N, N);\n        A.setZero();\n        vector<int> deg(N,0);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                uint8_t v = bits[idx_pair(N,i,j)];\n                if(v){\n                    A(i,j)=A(j,i)=1.0;\n                    deg[i]++; deg[j]++;\n                }\n            }\n        }\n\n        vector<double> dh(N, 0.0);\n        for(int d:deg) dh[d] += 1.0;\n        for(double &x:dh) x /= N;\n\n        vector<int> dsort = deg;\n        sort(dsort.begin(), dsort.end());\n\n        const int DB = 16;\n        vector<double> db(DB, 0.0);\n        int dmax = 0;\n        for(int d:deg) dmax = max(dmax, d);\n        int span = max(1, dmax+1);\n        for(int d:deg){\n            int b = d * DB / span;\n            if(b>=DB) b=DB-1;\n            db[b] += 1.0;\n        }\n        for(double &x:db) x/=N;\n\n        vector<int> degNbrSum(N,0);\n        vector<int> nbrDegCounts(DB, 0);\n        vector<int> avgNbr(N,0);\n        for(int i=0;i<N;i++){\n            int s=0, c=0;\n            for(int j=0;j<N;j++) if (A(i,j)>0.5) {\n                s += deg[j]; c++;\n                int b = deg[j] * DB / span;\n                if(b>=DB) b=DB-1;\n                nbrDegCounts[b] += 1;\n            }\n            degNbrSum[i]=s;\n            avgNbr[i] = (c>0? (s / c) : 0);\n        }\n        int Hbins = 16;\n        int minv = *min_element(degNbrSum.begin(), degNbrSum.end());\n        int maxv = *max_element(degNbrSum.begin(), degNbrSum.end());\n        if (maxv==minv) maxv=minv+1;\n        vector<double> ndh(Hbins,0.0);\n        for(int v:degNbrSum){\n            int b = (int)((long long)(v - minv) * Hbins / (long long)(maxv - minv + 1));\n            b = max(0, min(Hbins-1, b));\n            ndh[b] += 1.0;\n        }\n        for(double &x:ndh) x/=N;\n\n        vector<double> ndb(DB, 0.0);\n        double totNbr = 0.0;\n        for(int b=0;b<DB;b++) totNbr += nbrDegCounts[b];\n        if (totNbr < 1.0) totNbr = 1.0;\n        for(int b=0;b<DB;b++) ndb[b] = nbrDegCounts[b] / totNbr;\n\n        vector<int> core = kcore_decomposition(N, bits);\n        vector<int> core_sorted = core;\n        sort(core_sorted.begin(), core_sorted.end());\n        int cmax = 0; for(int c:core) cmax = max(cmax, c);\n        int CB = 16;\n        vector<double> core_hist(CB, 0.0);\n        int cspan = max(1, cmax+1);\n        for(int c:core){\n            int b = c * CB / cspan; b = max(0, min(CB-1, b));\n            core_hist[b] += 1.0;\n        }\n        for(double &x:core_hist) x/=N;\n\n        vector<int> wedges(N,0);\n        for(int i=0;i<N;i++){\n            long long d = deg[i];\n            long long w = d*(d-1)/2;\n            if (w > INT_MAX) w = INT_MAX;\n            wedges[i] = (int)w;\n        }\n        int Wbins = 16;\n        int wmin = *min_element(wedges.begin(), wedges.end());\n        int wmax = *max_element(wedges.begin(), wedges.end());\n        if (wmax==wmin) wmax=wmin+1;\n        vector<double> wdh(Wbins, 0.0);\n        for(int w:wedges){\n            int b = (int)((long long)(w - wmin) * Wbins / (long long)(wmax - wmin + 1));\n            b = max(0, min(Wbins-1, b));\n            wdh[b] += 1.0;\n        }\n        for(double &x:wdh) x/=N;\n\n        // WL-1 colors\n        vector<int> wl = wl1_colors(bits, deg, core);\n        const int WB=32;\n        vector<double> wlh(WB, 0.0);\n        for(int c:wl){\n            int b = ( (uint32_t)(c*2654435761u) ) % WB;\n            wlh[b] += 1.0;\n        }\n        for(double &x:wlh) x/=N;\n\n        // Local signatures\n        vector<Features::Sig> sigs(N);\n        for(int i=0;i<N;i++){\n            sigs[i].deg = deg[i];\n            sigs[i].sumNbr = degNbrSum[i];\n            sigs[i].core = core[i];\n            sigs[i].avgNbr = avgNbr[i];\n            sigs[i].wl_bucket = ( (uint32_t)(wl[i]*2654435761u) ) % WB;\n        }\n        sort(sigs.begin(), sigs.end(), [](const Features::Sig& a, const Features::Sig& b){\n            if(a.deg!=b.deg) return a.deg < b.deg;\n            if(a.core!=b.core) return a.core < b.core;\n            if(a.avgNbr!=b.avgNbr) return a.avgNbr < b.avgNbr;\n            if(a.sumNbr!=b.sumNbr) return a.sumNbr < b.sumNbr;\n            return a.wl_bucket < b.wl_bucket;\n        });\n        const int LB=24;\n        vector<double> lbh(LB,0.0);\n        for(int i=0;i<N;i++){\n            int d = sigs[i].deg;\n            int c = sigs[i].core;\n            int bd = min(DB-1, (int)((long long)d * DB / (long long)max(1,dmax+1)));\n            int bc = min(CB-1, (int)((long long)c * CB / (long long)max(1,cmax+1)));\n            int key = (bd * 31 + bc * 17) % LB;\n            lbh[key] += 1.0;\n        }\n        for(double &x:lbh) x/=N;\n\n        // moments\n        double m2=0.0, m3=0.0;\n        double den = max(1, N-1);\n        for(int d:deg){\n            double x = d/den;\n            m2 += x*x;\n            m3 += x*x*x;\n        }\n        m2 /= N; m3 /= N;\n\n        // Spectra\n        int Ttop = (N >= 80 ? 12 : 10);\n        vector<double> eigA, eigLN;\n        eigA.reserve(Ttop); eigLN.reserve(Ttop);\n        {\n            Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(A);\n            if (es.info() == Eigen::Success) {\n                auto evals = es.eigenvalues();\n                vector<double> all(N);\n                for(int i=0;i<N;i++) all[i] = evals(i);\n                vector<int> idx(N); iota(idx.begin(), idx.end(), 0);\n                sort(idx.begin(), idx.end(), [&](int a,int b){\n                    return fabs(all[a]) > fabs(all[b]);\n                });\n                int maxdeg = 1;\n                for(int d:deg) if(d>maxdeg) maxdeg=d;\n                double scale = sqrt((double)maxdeg);\n                if(scale == 0.0) scale = 1.0;\n                for(int t=0;t<Ttop;t++){\n                    eigA.push_back(all[idx[t]] / scale);\n                }\n            } else eigA.assign(Ttop, 0.0);\n            standardize(eigA);\n        }\n        double lap_sum_proxy=0.0;\n        {\n            Eigen::VectorXd invs(N);\n            for(int i=0;i<N;i++){\n                if (deg[i] > 0) invs(i) = 1.0 / sqrt((double)deg[i]);\n                else invs(i) = 0.0;\n            }\n            Eigen::MatrixXd Lnorm = Eigen::MatrixXd::Identity(N,N);\n            for(int i=0;i<N;i++){\n                for(int j=i+1;j<N;j++){\n                    if (A(i,j) > 0.5){\n                        double w = invs(i) * invs(j);\n                        if (w != 0.0){\n                            Lnorm(i,j) -= w;\n                            Lnorm(j,i) -= w;\n                        }\n                    }\n                }\n            }\n            Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(Lnorm);\n            if (es.info() == Eigen::Success) {\n                auto evals = es.eigenvalues();\n                vector<double> all(N);\n                for(int i=0;i<N;i++) all[i] = evals(i);\n                vector<int> idx(N); iota(idx.begin(), idx.end(), 0);\n                sort(idx.begin(), idx.end(), [&](int a,int b){\n                    return fabs(all[a]-1.0) > fabs(all[b]-1.0);\n                });\n                for(int t=0;t<Ttop;t++){\n                    eigLN.push_back(all[idx[t]]);\n                    lap_sum_proxy += fabs(all[idx[t]] - 1.0);\n                }\n            } else eigLN.assign(Ttop, 0.0);\n            standardize(eigLN);\n        }\n\n        double assort = compute_assort_proxy_exact(bits, deg);\n\n        // degree Gini proxy via sampling\n        double gini=0.0;\n        {\n            int S = min(2000, N*4);\n            if (S<=0) gini=0.0;\n            else{\n                XorShift64 rg(seed ^ 0xdeadbeefcafebabeull ^ (uint64_t)N);\n                long double sum=0.0;\n                for(int s=0;s<S;s++){\n                    int i = rg.irand(0,N-1), j = rg.irand(0,N-1);\n                    if (i==j) continue;\n                    sum += fabsl((long double)deg[i] - (long double)deg[j]);\n                }\n                long double denom = (long double)S * (long double)max(1, N-1) * 2.0L;\n                gini = (double)(sum / max(1.0L, denom));\n            }\n        }\n\n        // eig gap proxy from eigLN standardized vector: use spread between largest two entries by absolute deviation from 0\n        double eig_gap=0.0;\n        {\n            vector<double> tmp = eigLN;\n            vector<double> absd(tmp.size());\n            for(size_t i=0;i<tmp.size();i++) absd[i] = fabs(tmp[i]);\n            sort(absd.begin(), absd.end(), greater<double>());\n            if (absd.size() >= 3) eig_gap = fabs(absd[0] - absd[1]);\n            else if (absd.size() == 2) eig_gap = fabs(absd[0] - absd[1]);\n            else eig_gap = 0.0;\n        }\n\n        Features F;\n        F.deg_hist = move(dh);\n        F.deg_sorted = move(dsort);\n        F.deg_buckets = move(db);\n        F.core_sorted = move(core_sorted);\n        F.core_hist = move(core_hist);\n        F.eigA = move(eigA);\n        F.eigLN = move(eigLN);\n        F.nbrdeg_hist = move(ndh);\n        F.nbr_deg_buck = move(ndb);\n        F.wedge_hist = move(wdh);\n        F.local_sigs_sorted = move(sigs);\n        F.local_bucket_hist = move(lbh);\n        F.deg_m2 = m2; F.deg_m3 = m3;\n        F.lap_spec_sum = lap_sum_proxy;\n        F.assort_proxy = assort;\n        F.wl_hist = move(wlh);\n        F.deg_gini = gini;\n        F.eig_gap_proxy = eig_gap;\n        return {deg, F};\n    };\n\n    // Build templates and features\n    vector<TemplateG> temps(M);\n    for(int k=0;k<M;k++){\n        int B = (N >= 60 ? (4 + ((k + M) % 2)) : 4);\n        vector<int> base_block = initial_blocks(B);\n\n        XorShift64 g(seed ^ (uint64_t)(0x9e3779b97f4a7c15ull * (k+1)));\n        vector<int> blk(N);\n        vector<int> permB(B);\n        iota(permB.begin(), permB.end(), 0);\n        for(int i=0;i<B;i++){ int j = g.irand(0,B-1); swap(permB[i], permB[j]); }\n        for(int i=0;i<N;i++) blk[i] = permB[ base_block[i] ];\n\n        double base = 0.25 + 0.4 * ( (k*0.1234567) - floor(k*0.1234567) );\n        double diag_boost = 0.18 + 0.12 * (g.drand());\n        double off_var = 0.14 + 0.08 * (g.drand());\n        vector<vector<double>> P(B, vector<double>(B, 0.0));\n        for(int b=0;b<B;b++){\n            for(int c=b;c<B;c++){\n                double val = base + off_var * (g.drand()-0.5);\n                if (b==c) val = base + diag_boost * (g.drand()-0.5) + 0.35;\n                val = min(0.98, max(0.02, val));\n                P[b][c]=P[c][b]=val;\n            }\n        }\n        vector<double> biasB(B);\n        for(int b=0;b<B;b++) biasB[b] = (g.drand()-0.5)*0.20;\n\n        int Ebits = N*(N-1)/2;\n        vector<uint8_t> bits(Ebits, 0);\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                int bi = blk[i], bj = blk[j];\n                double p = P[bi][bj];\n                double vbi = biasB[bi] + 0.05 * sin((i+1)*(k+3)*0.13);\n                double vbj = biasB[bj] + 0.05 * cos((j+3)*(k+5)*0.17);\n                double adjp = p + 0.14*(vbi+vbj);\n                if(adjp < 0.01) adjp = 0.01;\n                if(adjp > 0.99) adjp = 0.99;\n                if (g.drand() < adjp){\n                    bits[idx_pair(N,i,j)] = 1;\n                }\n            }\n        }\n        add_backbone(bits, k);\n        uint64_t h1 = (uint64_t)k * 0x9e3779b97f4a7c15ull ^ (uint64_t)(k+1234567)*0xbf58476d1ce4e5b9ull;\n        uint64_t h2 = (uint64_t)(k+0x5bd1e995) * 0x94d049bb133111ebull ^ (uint64_t)(k*3+7)*0x2545F4914F6CDD1Dull;\n        add_anchor_code(bits, 12, h1);\n        add_anchor_code(bits, 16, h2);\n        add_block_hub_edges(bits, blk, B, k);\n        add_anchor_regular_overlay(bits, k);\n\n        vector<int> deg(N,0);\n        for(int i=0;i<N;i++){\n            int d=0;\n            for(int j=0;j<i;j++) d += bits[idx_pair(N,j,i)];\n            for(int j=i+1;j<N;j++) d += bits[idx_pair(N,i,j)];\n            deg[i]=d;\n        }\n\n        vector<int> target(N);\n        for(int i=0;i<N;i++){\n            int bi = blk[i];\n            double basef = 0.15 + 0.12*bi;\n            double f = basef\n                + 0.05 * sin( (i+1) * (0.07*(k%13+1)) )\n                + 0.03 * cos( (i+1) * (0.11*((k%7)+1)) );\n            f = max(0.04, min(0.92, f));\n            int t = (int)round(f * (N-1));\n            target[i] = max(0, min(N-1, t));\n        }\n        XorShift64 g2(seed ^ (uint64_t)(0x6a09e667f3bcc909ull * (k+17)));\n        auto tmpBits = bits;\n        rewiring_degree_palette(tmpBits, deg, target, g2);\n\n        auto [deg2, F] = compute_features(tmpBits);\n        temps[k].bits = move(tmpBits);\n        temps[k].deg = move(deg2);\n        temps[k].feat = move(F);\n    }\n\n    auto l2 = [](const vector<double>& x, const vector<double>& y){\n        double s=0; size_t n=min(x.size(), y.size());\n        for(size_t i=0;i<n;i++){ double d=x[i]-y[i]; s+=d*d; }\n        return sqrt(s);\n    };\n    auto l1sorted = [](const vector<int>& x, const vector<int>& y){\n        double s=0; size_t n=min(x.size(), y.size());\n        for(size_t i=0;i<n;i++){ s += abs(x[i]-y[i]); }\n        return s / (double)n;\n    };\n    auto mix = [](double a, double b, double t){ return a*(1.0-t) + b*t; };\n    double t_eps = min(1.0, max(0.0, (eps - 0.10) / 0.25));\n\n    auto dist_deg_fast = [&](const Features& A, const Features& B)->double{\n        double s= l2(A.deg_buckets, B.deg_buckets);\n        double t= l1sorted(A.deg_sorted, B.deg_sorted);\n        double u= l2(A.nbr_deg_buck, B.nbr_deg_buck);\n        double v= l2(A.core_hist, B.core_hist);\n        double wloc = l2(A.local_bucket_hist, B.local_bucket_hist);\n        double wwedge = l2(A.wedge_hist, B.wedge_hist);\n        double wmom = fabs(A.deg_m2 - B.deg_m2) + 0.5 * fabs(A.deg_m3 - B.deg_m3);\n        double wlap = fabs(A.lap_spec_sum - B.lap_spec_sum);\n        double wl1 = l2(A.wl_hist, B.wl_hist);\n        double wgin = fabs(A.deg_gini - B.deg_gini);\n        double w_deg = mix(0.53, 0.33, t_eps);\n        double w_sort= mix(0.24, 0.18, t_eps);\n        double w_nbr = mix(0.06, 0.18, t_eps);\n        double w_core= mix(0.03, 0.12, t_eps);\n        double w_loc = mix(0.05, 0.07, t_eps);\n        double w_wdg = mix(0.03, 0.05, t_eps);\n        double w_mom = 0.02;\n        double w_lap = 0.02;\n        double w_wl1 = mix(0.03, 0.04, t_eps);\n        double w_gin = 0.01;\n        return w_deg*s + w_sort*t + w_nbr*u + w_core*v + w_loc*wloc + w_wdg*wwedge + w_mom*wmom + w_lap*wlap + w_wl1*wl1 + w_gin*wgin;\n    };\n\n    auto hungarian_match_cost_dual = [&](const Features& A, const Features& B)->double{\n        auto build_cost = [&](const vector<Features::Sig>& SA, const vector<Features::Sig>& SB, int offA, int offB, int P)->double{\n            int nA = (int)SA.size(), nB = (int)SB.size();\n            if (nA==0 || nB==0) return 0.0;\n            int Puse = min(P, min(nA, nB));\n            vector<vector<double>> C(Puse, vector<double>(Puse, 0.0));\n            int NA = max(1, N);\n            for(int i=0;i<Puse;i++){\n                const auto &a = SA[min(nA-1, offA + i)];\n                for(int j=0;j<Puse;j++){\n                    const auto &b = SB[min(nB-1, offB + j)];\n                    double ddeg = abs(a.deg - b.deg) / (double)max(1, N-1);\n                    double dcore= abs(a.core - b.core) / (double)max(1, N-1);\n                    double dsum = fabs((double)a.sumNbr - (double)b.sumNbr) / (double)NA;\n                    double davg = fabs((double)a.avgNbr - (double)b.avgNbr) / (double)max(1,N-1);\n                    double dcol = (a.wl_bucket==b.wl_bucket? 0.0 : 0.15);\n                    C[i][j] = 0.43*ddeg + 0.14*dcore + 0.23*dsum + 0.15*davg + dcol;\n                }\n            }\n            return hungarian_min_cost(C);\n        };\n        int P = 18;\n        int n = (int)A.local_sigs_sorted.size();\n        int m = (int)B.local_sigs_sorted.size();\n        if (n==0 || m==0) return 0.0;\n        double cost_top = build_cost(A.local_sigs_sorted, B.local_sigs_sorted, max(0,n-P), max(0,m-P), P);\n        int midA = max(0, n/2 - P/2);\n        int midB = max(0, m/2 - P/2);\n        double cost_mid = build_cost(A.local_sigs_sorted, B.local_sigs_sorted, midA, midB, P);\n        return 0.6*cost_top + 0.4*cost_mid;\n    };\n\n    auto dist_full = [&](const Features& A, const Features& B)->double{\n        double d_deg_hist = l2(A.deg_hist, B.deg_hist);\n        double d_deg_buck = l2(A.deg_buckets, B.deg_buckets);\n        double d_nbr_sum  = l2(A.nbrdeg_hist, B.nbrdeg_hist);\n        double d_nbr_buck = l2(A.nbr_deg_buck, B.nbr_deg_buck);\n        double d_eigA     = l2(A.eigA, B.eigA);\n        double d_eigLN    = l2(A.eigLN, B.eigLN);\n        double d_sorted   = l1sorted(A.deg_sorted, B.deg_sorted);\n        double d_coreh    = l2(A.core_hist, B.core_hist);\n        double d_cores    = l1sorted(A.core_sorted, B.core_sorted);\n        double d_loc      = l2(A.local_bucket_hist, B.local_bucket_hist);\n        double d_wedge    = l2(A.wedge_hist, B.wedge_hist);\n        double d_match    = hungarian_match_cost_dual(A, B);\n        double d_wl1      = l2(A.wl_hist, B.wl_hist);\n\n        double w_eigA  = mix(0.16, 0.24, t_eps);\n        double w_eigLN = mix(0.10, 0.18, t_eps);\n        double w_dh    = mix(0.20, 0.10, t_eps);\n        double w_db    = mix(0.16, 0.16, t_eps);\n        double w_ns    = mix(0.07, 0.06, t_eps);\n        double w_nb    = mix(0.03, 0.09, t_eps);\n        double w_sort  = mix(0.08, 0.05, t_eps);\n        double w_ch    = mix(0.04, 0.05, t_eps);\n        double w_cs    = mix(0.02, 0.05, t_eps);\n        double w_loc   = mix(0.03, 0.05, t_eps);\n        double w_wdg   = mix(0.02, 0.05, t_eps);\n        double w_match = mix(0.04, 0.10, t_eps);\n        double w_wl1   = mix(0.02, 0.03, t_eps);\n\n        return w_eigA*d_eigA + w_eigLN*d_eigLN\n             + w_dh*d_deg_hist + w_db*d_deg_buck\n             + w_ns*d_nbr_sum + w_nb*d_nbr_buck\n             + w_sort*d_sorted + w_ch*d_coreh + w_cs*d_cores\n             + w_loc*d_loc + w_wdg*d_wedge + w_match*d_match + w_wl1*d_wl1;\n    };\n\n    // Output templates\n    cout<<N<<\"\\n\";\n    for(int k=0;k<M;k++){\n        int L = N*(N-1)/2;\n        string s; s.resize(L);\n        for(int i=0;i<L;i++) s[i] = temps[k].bits[i] ? '1':'0';\n        cout<<s<<\"\\n\";\n    }\n    cout.flush();\n\n    // Answer queries\n    int shortlist_base = (eps >= 0.30 ? 26 : (eps >= 0.20 ? 22 : 12));\n    if (M > 80 && eps >= 0.20) shortlist_base += 4;\n    shortlist_base = min(M, shortlist_base);\n\n    for(int q=0;q<100;q++){\n        string Hs;\n        if(!(cin>>Hs)) return 0;\n        int L = N*(N-1)/2;\n        vector<uint8_t> Hbits(L,0);\n        for(int i=0;i<L;i++) Hbits[i] = (Hs[i]=='1');\n\n        auto [Hdeg, HF] = compute_features(Hbits);\n\n        vector<pair<double,int>> allcand;\n        allcand.reserve(M);\n        for(int k=0;k<M;k++){\n            double d = dist_deg_fast(HF, temps[k].feat);\n            allcand.emplace_back(d, k);\n        }\n        int S = shortlist_base;\n        nth_element(allcand.begin(), allcand.begin()+min(S+4, M-1), allcand.end());\n        sort(allcand.begin(), allcand.begin()+min(S+4, M), [](auto& a, auto& b){ return a.first < b.first; });\n        double d0 = allcand[0].first;\n        double dS = allcand[min(S-1, (int)allcand.size()-1)].first;\n        double dS2= allcand[min(S+3, (int)allcand.size()-1)].first;\n        int widen = 0;\n        if (dS - d0 < 0.03) widen += 4;\n        if (dS2 - d0 < 0.06) widen += 4;\n        if (dS2 - d0 < 0.02) widen += 4;\n        int widen_cap = max(8, M/10);\n        widen = min(widen, widen_cap);\n        S = min(M, S + widen);\n        vector<pair<double,int>> cand(allcand.begin(), allcand.begin()+S);\n\n        // full evaluation\n        vector<pair<double,int>> scored;\n        scored.reserve(S);\n        for(auto &pr : cand){\n            int k = pr.second;\n            double d = dist_full(HF, temps[k].feat);\n            scored.emplace_back(d, k);\n        }\n        sort(scored.begin(), scored.end());\n\n        int bestk = scored[0].second;\n        // tie-breaker using eigengap proxy if needed\n        if (scored.size() >= 3){\n            double bestd = scored[0].first;\n            double close_thr = max(1e-6, 0.02 * bestd + 0.002);\n            int K = 3;\n            vector<int> ties; ties.push_back(scored[0].second);\n            for(int i=1;i<min(K,(int)scored.size());i++){\n                if (scored[i].first - bestd <= close_thr) ties.push_back(scored[i].second);\n            }\n            if (ties.size() >= 2){\n                // pick candidate with min |eig_gap_proxy diff|\n                double hg = HF.eig_gap_proxy;\n                double bestExtra = 1e100;\n                int pick = bestk;\n                for(int c : ties){\n                    double diff = fabs(temps[c].feat.eig_gap_proxy - hg);\n                    if (diff < bestExtra) { bestExtra = diff; pick = c; }\n                }\n                bestk = pick;\n            }\n        }\n\n        cout<<bestk<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge { int id, u, v; int w; };\nstruct Adj { int to, eid, w; };\n\nstruct Timer {\n    chrono::high_resolution_clock::time_point st;\n    Timer(){ reset(); }\n    void reset(){ st = chrono::high_resolution_clock::now(); }\n    double ms() const { return chrono::duration<double, std::milli>(chrono::high_resolution_clock::now()-st).count(); }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Timer timer;\n\n    int N,M,D,K;\n    if(!(cin>>N>>M>>D>>K)) return 0;\n    vector<Edge> edges(M);\n    for(int i=0;i<M;++i){\n        int u,v,w; cin>>u>>v>>w; --u;--v; edges[i]={i,u,v,w};\n    }\n    vector<pair<int,int>> coords(N);\n    for(int i=0;i<N;++i){ int x,y; cin>>x>>y; coords[i]={x,y}; }\n\n    vector<vector<Adj>> g(N);\n    vector<int> deg(N,0);\n    for(auto &e: edges){\n        g[e.u].push_back({e.v, e.id, e.w});\n        g[e.v].push_back({e.u, e.id, e.w});\n        deg[e.u]++; deg[e.v]++;\n    }\n\n    // Importance components: weight and degree penalty\n    long long wmin=LLONG_MAX,wmax=0;\n    for(auto &e: edges){ wmin=min<long long>(wmin,e.w); wmax=max<long long>(wmax,e.w); }\n    double denom_w = (wmax>wmin ? double(wmax-wmin) : 1.0);\n    vector<double> imp_w(M), imp_deg(M);\n    for(auto &e: edges) imp_w[e.id] = (double)(e.w - wmin) / denom_w;\n    for(auto &e: edges){\n        double pu = 1.0 / max(1, deg[e.u]-1);\n        double pv = 1.0 / max(1, deg[e.v]-1);\n        imp_deg[e.id] = 0.5*(pu+pv);\n    }\n\n    // Betweenness-like using SSSP tree usage from multiple sources (deterministic)\n    mt19937 rng(912531);\n    vector<int> nodes(N); iota(nodes.begin(), nodes.end(), 0);\n    shuffle(nodes.begin(), nodes.end(), rng);\n    int S = 30; if(N<=900) S=28; if(N<=750) S=26; if(N<=600) S=24; if(N<=500) S=22; S = min(S, max(18, N/40));\n    int T = 16; if(N<750) T=14; if(N<600) T=12; // targets per source for path backtracking\n\n    vector<long long> dist(N);\n    vector<int> parent_edge(N, -1);\n    struct QN{ long long d; int v; };\n    struct Cmp{ bool operator()(const QN&a,const QN&b)const{return a.d>b.d;}};\n    vector<long long> bet_count(M,0);\n\n    // Co-occurrence top-K map per edge\n    const int KCO = 16;\n    vector<unordered_map<int,int>> co_occur(M);\n\n    auto push_co = [&](int e1, int e2){\n        if(e1==e2) return;\n        auto &mp = co_occur[e1];\n        auto it = mp.find(e2);\n        if(it != mp.end()){ it->second++; return; }\n        if((int)mp.size() < KCO){ mp.emplace(e2,1); return; }\n        // deterministic replacement: remove current minimum count; tie -> remove largest key\n        int min_k = -1, min_v = INT_MAX;\n        for(auto &kv: mp){\n            if(kv.second < min_v || (kv.second == min_v && kv.first > min_k)){\n                min_v = kv.second; min_k = kv.first;\n            }\n        }\n        if(min_v <= 1){ mp.erase(min_k); mp.emplace(e2,1); }\n        // else ignore to keep strongest pairs\n    };\n\n    vector<int> targets; targets.reserve(T);\n    vector<int> path_edges; path_edges.reserve(N);\n\n    for(int si=0; si<S && si<N; ++si){\n        if(timer.ms() > 2200.0) break;\n        int s = nodes[si];\n        // Dijkstra single parent (deterministic)\n        fill(dist.begin(), dist.end(), (long long)4e18);\n        fill(parent_edge.begin(), parent_edge.end(), -1);\n        priority_queue<QN, vector<QN>, Cmp> pq;\n        dist[s]=0; pq.push({0,s});\n        while(!pq.empty()){\n            auto [d,v]=pq.top(); pq.pop();\n            if(d!=dist[v]) continue;\n            for(auto &ae: g[v]){\n                int to = ae.to; long long nd = d + ae.w;\n                if(nd < dist[to]){\n                    dist[to]=nd; parent_edge[to]=ae.eid; pq.push({nd,to});\n                }\n            }\n        }\n        for(int v=0; v<N; ++v){\n            if(v==s) continue;\n            int pe = parent_edge[v];\n            if(pe>=0) bet_count[pe] += 1;\n        }\n        // sample targets deterministically from shuffled nodes block\n        targets.clear();\n        for(int t=0; t<T; ++t){\n            int idx = (si*911 + t*811) % N;\n            int v = nodes[idx]; if(v==s) v = (v+1)%N;\n            targets.push_back(v);\n        }\n        // Backtrack along unique parents to build paths and update co-occurrence\n        for(int tnode: targets){\n            path_edges.clear();\n            int cur = tnode; int steps=0;\n            while(cur != s && steps < N){\n                int pe = parent_edge[cur];\n                if(pe < 0) break;\n                path_edges.push_back(pe);\n                int a=edges[pe].u, b=edges[pe].v;\n                cur = (cur==a? b: a);\n                steps++;\n            }\n            int Lp = (int)path_edges.size();\n            for(int i=0;i<Lp;++i){\n                int e1 = path_edges[i];\n                bet_count[e1] += 1;\n                // limited window to contain cost\n                int l = max(0, i-7), r = min(Lp-1, i+7);\n                for(int j=l;j<=r;++j){\n                    if(j==i) continue;\n                    push_co(e1, path_edges[j]);\n                }\n            }\n        }\n    }\n\n    // Normalize betweenness\n    long long bmin=LLONG_MAX, bmax=0;\n    for(int i=0;i<M;++i){ bmin=min(bmin, bet_count[i]); bmax=max(bmax, bet_count[i]); }\n    double denom_b = (bmax>bmin? double(bmax-bmin):1.0);\n    vector<double> imp_bet(M,0.0);\n    for(int i=0;i<M;++i) imp_bet[i] = (double)(bet_count[i]-bmin)/denom_b;\n\n    // Single sectorization\n    double cx=0, cy=0;\n    for(auto &p: coords){ cx += p.first; cy += p.second; }\n    cx /= N; cy /= N;\n    int SECT = 12;\n    vector<int> edge_sect(M,0);\n    for(auto &e: edges){\n        double mx = 0.5*(coords[e.u].first + coords[e.v].first);\n        double my = 0.5*(coords[e.u].second + coords[e.v].second);\n        double ang = atan2(my - cy, mx - cx);\n        if(ang < 0) ang += 2*M_PI;\n        int s = int(SECT * (ang/(2*M_PI)));\n        if(s<0) s=0; if(s>=SECT) s=SECT-1;\n        edge_sect[e.id] = s;\n    }\n\n    // Final score with stable weights\n    double w_w = 0.35, w_deg = 0.55, w_bet = 1.10;\n    vector<double> score(M);\n    for(int i=0;i<M;++i) score[i] = w_w*imp_w[i] + w_deg*imp_deg[i] + w_bet*imp_bet[i];\n\n    vector<int> order(M); iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i,int j){\n        if(score[i]!=score[j]) return score[i] > score[j];\n        return i<j;\n    });\n\n    // Assignment with penalties\n    vector<int> day_of_edge(M, -1);\n    vector<int> load(D,0);\n    vector<double> day_imp(D,0.0), day_imp2(D,0.0);\n    vector<vector<int>> incid_on_day(N, vector<int>(D,0));\n    vector<vector<int>> sect_on_day(D, vector<int>(SECT,0));\n    vector<int> target(D);\n    int base=M/D, rem=M%D;\n    for(int d=0; d<D; ++d) target[d] = min(K, base + (d<rem?1:0));\n    vector<int> v_soft(N);\n    for(int v=0; v<N; ++v) v_soft[v] = (deg[v] + D - 1)/D + 1;\n\n    double alpha_adj = 1.1;\n    double beta_lin = 0.22;\n    double beta_var = 0.24;\n    double gamma_co = 0.36;\n    double delta_sect = 0.13;\n    double soft_cap_pen = 0.25;\n\n    for(int ei: order){\n        int u=edges[ei].u, v=edges[ei].v, sec=edge_sect[ei];\n        int bestd=-1; double bestc=1e100;\n        for(int d=0; d<D; ++d){\n            if(load[d] >= K) continue;\n            int iu=incid_on_day[u][d], iv=incid_on_day[v][d];\n            double pen_adj = alpha_adj * (iu + iv);\n            double pen_vsoft = 0.0;\n            if(iu >= v_soft[u]) pen_vsoft += (iu - v_soft[u] + 1)*0.5;\n            if(iv >= v_soft[v]) pen_vsoft += (iv - v_soft[v] + 1)*0.5;\n            double bal = beta_lin * day_imp[d] + beta_var * day_imp2[d];\n            double pen_co = 0.0;\n            auto &mp = co_occur[ei];\n            int seen=0;\n            for(auto &kv: mp){\n                int ej=kv.first; int dj = (unsigned)ej < (unsigned)M ? day_of_edge[ej] : -1;\n                if(dj==d){ pen_co += gamma_co * kv.second; if(++seen>=KCO) break; }\n            }\n            double pen_sec = delta_sect * sect_on_day[d][sec];\n            double cap_soft = (load[d] < target[d] ? 0.0 : soft_cap_pen * (load[d] - target[d] + 1));\n            double cost = pen_adj + pen_vsoft + bal + pen_co + pen_sec + cap_soft;\n            if(cost < bestc){ bestc=cost; bestd=d; }\n        }\n        if(bestd<0){ int md=0; for(int d=1; d<D; ++d) if(load[d] < load[md]) md=d; bestd=md; }\n        day_of_edge[ei]=bestd;\n        load[bestd]++; day_imp[bestd]+=score[ei]; day_imp2[bestd]+=score[ei]*score[ei];\n        incid_on_day[u][bestd]++; incid_on_day[v][bestd]++;\n        sect_on_day[bestd][sec]++;\n    }\n\n    // Refinement: single-edge moves + pair swaps\n    auto eval_day_cost_partial = [&](int ei, int d)->double{\n        int u=edges[ei].u, v=edges[ei].v, sec=edge_sect[ei];\n        int iu = incid_on_day[u][d] - (day_of_edge[ei]==d?1:0);\n        int iv = incid_on_day[v][d] - (day_of_edge[ei]==d?1:0);\n        double pen_adj = alpha_adj * (iu + iv);\n        double pen_vsoft = 0.0;\n        if(iu >= v_soft[u]) pen_vsoft += (iu - v_soft[u] + 1)*0.5;\n        if(iv >= v_soft[v]) pen_vsoft += (iv - v_soft[v] + 1)*0.5;\n        double bal = beta_lin * day_imp[d] + beta_var * day_imp2[d];\n        double pen_co = 0.0;\n        auto &mp = co_occur[ei];\n        int seen=0;\n        for(auto &kv: mp){\n            int ej=kv.first; int dj = day_of_edge[ej];\n            if(dj==d){ pen_co += gamma_co * kv.second; if(++seen>=KCO) break; }\n        }\n        double pen_sec = delta_sect * (sect_on_day[d][sec] - (day_of_edge[ei]==d?1:0));\n        return pen_adj + pen_vsoft + bal + pen_co + pen_sec;\n    };\n\n    auto move_edge = [&](int ei, int dfrom, int dto){\n        int u=edges[ei].u, v=edges[ei].v, sec=edge_sect[ei];\n        incid_on_day[u][dfrom]--; incid_on_day[v][dfrom]--;\n        incid_on_day[u][dto]++; incid_on_day[v][dto]++;\n        sect_on_day[dfrom][sec]--; sect_on_day[dto][sec]++;\n        load[dfrom]--; load[dto]++;\n        day_imp[dfrom] -= score[ei]; day_imp2[dfrom] -= score[ei]*score[ei];\n        day_imp[dto] += score[ei]; day_imp2[dto] += score[ei]*score[ei];\n        day_of_edge[ei]=dto;\n    };\n\n    double time_left = max(0.0, 5200.0 - timer.ms());\n    double ref1 = min(1400.0, time_left * 0.55);\n    double ref2 = min(700.0, time_left * 0.30);\n    double ref3 = min(650.0, time_left * 0.30); // audit+ejection budget, overlapping a bit with remaining time\n\n    Timer t1;\n    uniform_int_distribution<int> distE(0, M-1);\n    int iters=0;\n    while(t1.ms() < ref1 && iters < 220000){\n        ++iters;\n        int ei = distE(rng);\n        int di = day_of_edge[ei];\n        double cur = eval_day_cost_partial(ei, di);\n        int bestd = di; double best_gain = 0.0;\n        for(int d=0; d<D; ++d){\n            if(d==di) continue;\n            if(load[d] >= K) continue;\n            double newc = eval_day_cost_partial(ei, d);\n            double s = score[ei];\n            double old_bal = (beta_lin*day_imp[di] + beta_var*day_imp2[di]) + (beta_lin*day_imp[d] + beta_var*day_imp2[d]);\n            double new_bal = (beta_lin*(day_imp[di]-s) + beta_var*(day_imp2[di]-s*s))\n                           + (beta_lin*(day_imp[d]+s) + beta_var*(day_imp2[d]+s*s));\n            double gain = (cur - newc) + (old_bal - new_bal);\n            if(gain > best_gain){ best_gain=gain; bestd=d; }\n        }\n        if(bestd != di && best_gain > 1e-9){\n            move_edge(ei, di, bestd);\n        }\n    }\n\n    // Pair swaps\n    Timer t2;\n    int swaps=0;\n    vector<int> ord = order; // hot edges first\n    int H = min((int)ord.size(), max(120, M/7));\n    while(t2.ms() < ref2 && swaps < 40000){\n        ++swaps;\n        int e1 = ord[rng() % H];\n        int e2 = distE(rng);\n        if(e1==e2) continue;\n        int d1 = day_of_edge[e1];\n        int d2 = day_of_edge[e2];\n        if(d1==d2) continue;\n\n        double c11 = eval_day_cost_partial(e1, d1);\n        double c22 = eval_day_cost_partial(e2, d2);\n        double c12 = eval_day_cost_partial(e1, d2);\n        double c21 = eval_day_cost_partial(e2, d1);\n\n        double s1 = score[e1], s2 = score[e2];\n        double old_bal = (beta_lin*day_imp[d1] + beta_var*day_imp2[d1]) + (beta_lin*day_imp[d2] + beta_var*day_imp2[d2]);\n        double new_imp_d1 = day_imp[d1] - s1 + s2;\n        double new_imp2_d1 = day_imp2[d1] - s1*s1 + s2*s2;\n        double new_imp_d2 = day_imp[d2] - s2 + s1;\n        double new_imp2_d2 = day_imp2[d2] - s2*s2 + s1*s1;\n        double new_bal = (beta_lin*new_imp_d1 + beta_var*new_imp2_d1) + (beta_lin*new_imp_d2 + beta_var*new_imp2_d2);\n\n        double gain = (c11 + c22) - (c12 + c21) + (old_bal - new_bal);\n        if(gain > 1e-9){\n            int u1=edges[e1].u, v1=edges[e1].v, sec1=edge_sect[e1];\n            int u2=edges[e2].u, v2=edges[e2].v, sec2=edge_sect[e2];\n            // apply swap\n            incid_on_day[u1][d1]--; incid_on_day[v1][d1]--; sect_on_day[d1][sec1]--;\n            incid_on_day[u1][d2]++; incid_on_day[v1][d2]++; sect_on_day[d2][sec1]++;\n            incid_on_day[u2][d2]--; incid_on_day[v2][d2]--; sect_on_day[d2][sec2]--;\n            incid_on_day[u2][d1]++; incid_on_day[v2][d1]++; sect_on_day[d1][sec2]++;\n            day_imp[d1] = new_imp_d1; day_imp2[d1] = new_imp2_d1;\n            day_imp[d2] = new_imp_d2; day_imp2[d2] = new_imp2_d2;\n            day_of_edge[e1]=d2; day_of_edge[e2]=d1;\n        }\n    }\n\n    // Day auditing + ejection-reassignment\n    Timer t3;\n    if (t3.ms() < ref3) {\n        // Build per-day edge lists\n        vector<vector<int>> day_edges(D);\n        day_edges.assign(D, {});\n        for (int ei = 0; ei < M; ++ei) {\n            int d = day_of_edge[ei];\n            if (d>=0) day_edges[d].push_back(ei);\n        }\n        // Compute day risk = a*imp + b*sector_l2 + c*co_conflict\n        vector<double> day_risk(D, 0.0);\n        vector<double> sector_l2(D, 0.0);\n        vector<double> co_conflict(D, 0.0);\n        double a_imp=0.35, b_sect=0.20, c_co=0.45;\n\n        for (int d=0; d<D; ++d) {\n            // sector L2\n            double l2=0.0;\n            for (int s=0; s<SECT; ++s) {\n                double x = sect_on_day[d][s];\n                l2 += x*x;\n            }\n            sector_l2[d] = l2;\n            // co-occurrence conflict (approx): sum over edges of sum co with edges on same day, using map\n            double co=0.0;\n            for (int ei : day_edges[d]) {\n                auto &mp = co_occur[ei];\n                int seen=0;\n                for (auto &kv: mp) {\n                    int ej = kv.first;\n                    if (ej>=0 && ej<M && day_of_edge[ej]==d) {\n                        co += kv.second;\n                        if (++seen >= KCO) break;\n                    }\n                }\n            }\n            co_conflict[d] = co;\n            day_risk[d] = a_imp * day_imp[d] + b_sect * sector_l2[d] + c_co * co_conflict[d];\n        }\n\n        // Pick top bad days\n        vector<int> day_ord(D); iota(day_ord.begin(), day_ord.end(), 0);\n        sort(day_ord.begin(), day_ord.end(), [&](int i,int j){ return day_risk[i] > day_risk[j]; });\n        int bad_days = max(1, D/4);\n        bad_days = min(bad_days, D);\n\n        // For each bad day, select hot edges (high local conflict * score)\n        vector<int> eject;\n        for (int bi=0; bi<bad_days; ++bi) {\n            int d = day_ord[bi];\n            auto &elist = day_edges[d];\n            if (elist.empty()) continue;\n            vector<pair<double,int>> contrib; contrib.reserve(elist.size());\n            for (int ei : elist) {\n                double local = 0.0;\n                auto &mp = co_occur[ei];\n                int seen=0;\n                for (auto &kv: mp) {\n                    int ej = kv.first;\n                    if (ej>=0 && ej<M && day_of_edge[ej]==d) {\n                        local += kv.second;\n                        if (++seen >= KCO) break;\n                    }\n                }\n                double val = local * (0.5 + score[ei]); // weight by importance\n                // small bump if many same-sector edges exist\n                val += 0.2 * sect_on_day[d][edge_sect[ei]];\n                contrib.emplace_back(val, ei);\n            }\n            sort(contrib.begin(), contrib.end(), greater<>());\n            int take = max(1, (int)elist.size()/20); // up to 5% from this day\n            take = min(take, 20); // cap per day\n            for (int i=0; i<take && i<(int)contrib.size(); ++i) eject.push_back(contrib[i].second);\n        }\n\n        // Eject uniques\n        sort(eject.begin(), eject.end());\n        eject.erase(unique(eject.begin(), eject.end()), eject.end());\n\n        // Remove them from their days\n        for (int ei : eject) {\n            int d = day_of_edge[ei];\n            if (d<0) continue;\n            int u=edges[ei].u, v=edges[ei].v, sec=edge_sect[ei];\n            incid_on_day[u][d]--; incid_on_day[v][d]--;\n            sect_on_day[d][sec]--;\n            load[d]--;\n            day_imp[d] -= score[ei]; day_imp2[d] -= score[ei]*score[ei];\n            day_of_edge[ei] = -1;\n        }\n\n        // Reassign ejected edges using a slightly stronger sector+co-occurrence penalty to diversify\n        double extra_co = 0.10;\n        double extra_sec = 0.08;\n        for (int ei : eject) {\n            int u=edges[ei].u, v=edges[ei].v, sec=edge_sect[ei];\n            int bestd=-1; double bestc=1e100;\n            for (int d=0; d<D; ++d) {\n                if (load[d] >= K) continue;\n                int iu=incid_on_day[u][d], iv=incid_on_day[v][d];\n                double pen_adj = alpha_adj * (iu + iv);\n                double pen_vsoft = 0.0;\n                if(iu >= v_soft[u]) pen_vsoft += (iu - v_soft[u] + 1)*0.5;\n                if(iv >= v_soft[v]) pen_vsoft += (iv - v_soft[v] + 1)*0.5;\n                double bal = beta_lin * day_imp[d] + beta_var * day_imp2[d];\n                double pen_co = 0.0;\n                auto &mp = co_occur[ei];\n                int seen=0;\n                for(auto &kv: mp){\n                    int ej=kv.first; int dj = (unsigned)ej < (unsigned)M ? day_of_edge[ej] : -1;\n                    if(dj==d){ pen_co += (gamma_co + extra_co) * kv.second; if(++seen>=KCO) break; }\n                }\n                double pen_sec = (delta_sect + extra_sec) * sect_on_day[d][sec];\n                double cap_soft = (load[d] < target[d] ? 0.0 : soft_cap_pen * (load[d] - target[d] + 1));\n                double cost = pen_adj + pen_vsoft + bal + pen_co + pen_sec + cap_soft;\n                if(cost < bestc){ bestc=cost; bestd=d; }\n            }\n            if(bestd<0){ int md=0; for (int d=1; d<D; ++d) if(load[d] < load[md]) md=d; bestd=md; }\n            day_of_edge[ei]=bestd;\n            load[bestd]++; day_imp[bestd]+=score[ei]; day_imp2[bestd]+=score[ei]*score[ei];\n            incid_on_day[u][bestd]++; incid_on_day[v][bestd]++;\n            sect_on_day[bestd][sec]++;\n        }\n    }\n\n    // Output\n    for(int i=0;i<M;++i){\n        int d = day_of_edge[i];\n        if(d<0) d = i % D;\n        cout << (d+1) << (i+1==M?'\\n':' ');\n    }\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Prefix3D {\n    int D;\n    vector<int> ps; // (D+1)^3\n    inline int id(int x,int y,int z) const { return (x*(D+1) + y)*(D+1) + z; }\n    void build(const vector<char>& M){\n        const int P = (D+1)*(D+1)*(D+1);\n        ps.assign(P, 0);\n        for(int x=1;x<=D;++x){\n            for(int y=1;y<=D;++y){\n                int acc = 0;\n                for(int z=1; z<=D; ++z){\n                    int v = M[(x-1)*D*D + (y-1)*D + (z-1)] ? 1 : 0;\n                    acc += v;\n                    ps[id(x,y,z)] = ps[id(x-1,y,z)] + ps[id(x,y-1,z)] - ps[id(x-1,y-1,z)] + acc;\n                }\n            }\n        }\n    }\n    inline int sum(int x0,int y0,int z0,int x1,int y1,int z1) const {\n        int a = ps[id(x1,y1,z1)];\n        int b = ps[id(x0,y1,z1)];\n        int c = ps[id(x1,y0,z1)];\n        int d = ps[id(x1,y1,z0)];\n        int e = ps[id(x0,y0,z1)];\n        int f = ps[id(x0,y1,z0)];\n        int g = ps[id(x1,y0,z0)];\n        int h = ps[id(x0,y0,z0)];\n        return a - b - c - d + e + f + g - h;\n    }\n    inline bool full(const int x0,const int y0,const int z0,const int dx,const int dy,const int dz) const {\n        if (x0<0||y0<0||z0<0) return false;\n        int x1=x0+dx, y1=y0+dy, z1=z0+dz;\n        if (x1>D || y1>D || z1>D) return false;\n        int s = sum(x0,y0,z0,x1,y1,z1);\n        return s == dx*dy*dz;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D;\n    if (!(cin>>D)) return 0;\n    vector<vector<string>> f(2, vector<string>(D));\n    vector<vector<string>> r(2, vector<string>(D));\n    for(int i=0;i<2;++i){\n        for(int z=0;z<D;++z) cin>>f[i][z];\n        for(int z=0;z<D;++z) cin>>r[i][z];\n    }\n    const int N = D*D*D;\n    auto idx = [&](int x,int y,int z){ return x*D*D + y*D + z; };\n\n    // Build masks per arrangement\n    vector<char> M1(N,0), M2(N,0);\n    for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z){\n        if (f[0][z][x]=='1' && r[0][z][y]=='1') M1[idx(x,y,z)] = 1;\n        if (f[1][z][x]=='1' && r[1][z][y]=='1') M2[idx(x,y,z)] = 1;\n    }\n\n    vector<int> b1(N,0), b2(N,0);\n    int nBlocks = 0;\n\n    auto mark_block = [&](vector<char>& M, vector<int>& Bout, int bid, int x0,int y0,int z0,int dx,int dy,int dz){\n        for(int x=x0;x<x0+dx;++x)\n            for(int y=y0;y<y0+dy;++y)\n                for(int z=z0;z<z0+dz;++z){\n                    int id3 = idx(x,y,z);\n                    M[id3] = 0;\n                    Bout[id3] = bid;\n                }\n    };\n\n    auto now = [&]()->double{\n        static auto st = chrono::high_resolution_clock::now();\n        chrono::duration<double> diff = chrono::high_resolution_clock::now()-st;\n        return diff.count();\n    };\n\n    Prefix3D P1, P2;\n    P1.D=D; P2.D=D;\n    P1.build(M1); P2.build(M2);\n\n    // Precompute maximal runs at each min-corner for M1\n    vector<int> maxX(N,0), maxY(N,0), maxZ(N,0);\n    auto recompute_max_runs = [&](const vector<char>& M, Prefix3D& P, vector<int>& mx, vector<int>& my, vector<int>& mz){\n        for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z){\n            int id3 = idx(x,y,z);\n            if (!M[id3]) { mx[id3]=my[id3]=mz[id3]=0; continue; }\n            int a=0; while (x+a<D && P.full(x,y,z, a+1,1,1)) ++a; mx[id3]=a;\n            int b=0; while (y+b<D && P.full(x,y,z, 1,b+1,1)) ++b; my[id3]=b;\n            int c=0; while (z+c<D && P.full(x,y,z, 1,1,c+1)) ++c; mz[id3]=c;\n        }\n    };\n    recompute_max_runs(M1, P1, maxX, maxY, maxZ);\n\n    auto generate_candidates = [&](int x0,int y0,int z0, vector<tuple<int,int,int,int>>& out){\n        int id3 = idx(x0,y0,z0);\n        if (!M1[id3]) return;\n        int a = maxX[id3], b = maxY[id3], c = maxZ[id3];\n        if (a==0 || b==0 || c==0) return;\n\n        auto push = [&](int dx,int dy,int dz){\n            if (dx<=0||dy<=0||dz<=0) return;\n            if (x0+dx<=D && y0+dy<=D && z0+dz<=D) out.emplace_back(dx,dy,dz,0);\n            if (x0-dx+1>=0 && y0-dy+1>=0 && z0-dz+1>=0) out.emplace_back(dx,dy,dz,1);\n        };\n        // Try combinations with full, half, third\n        auto split3 = [](int len)->array<int,3>{\n            int a = len;\n            int b = max(1, (len+1)/2);\n            int c = max(1, (len+2)/3);\n            array<int,3> v = {a,b,c};\n            sort(v.begin(), v.end());\n            v[0]=v[2]; v[2]=a; v[1]=b; // ensure a,b,c maps roughly to full, half, third (keep variety)\n            // just return {a,b,c} straightforward\n            return {a, b, c};\n        };\n        array<int,3> xs = split3(a);\n        array<int,3> ys = split3(b);\n        array<int,3> zs = split3(c);\n        // push top combinations (27 total)\n        for(int ix=0; ix<3; ++ix)\n            for(int iy=0; iy<3; ++iy)\n                for(int iz=0; iz<3; ++iz)\n                    push(xs[ix], ys[iy], zs[iz]);\n\n        // Also push full and some halves explicitly (duplicates will be removed)\n        push(a,b,c);\n        push(a, b, max(1, c/2));\n        push(a, max(1, b/2), c);\n        push(max(1, a/2), b, c);\n    };\n\n    auto place_shared_from_corner = [&](int x0,int y0,int z0)->bool{\n        vector<tuple<int,int,int,int>> cands;\n        generate_candidates(x0,y0,z0, cands);\n        if (cands.empty()) return false;\n        sort(cands.begin(), cands.end());\n        cands.erase(unique(cands.begin(), cands.end()), cands.end());\n        sort(cands.begin(), cands.end(), [&](auto &L, auto &R){\n            long long vL = 1LL*get<0>(L)*get<1>(L)*get<2>(L);\n            long long vR = 1LL*get<0>(R)*get<1>(R)*get<2>(R);\n            if (vL != vR) return vL > vR;\n            return L < R;\n        });\n\n        for (auto &tup : cands){\n            int dx=get<0>(tup), dy=get<1>(tup), dz=get<2>(tup), mode=get<3>(tup);\n            int ax=x0, ay=y0, az=z0;\n            if (mode==1){ ax = x0-dx+1; ay = y0-dy+1; az = z0-dz+1; }\n            if (!P1.full(ax,ay,az, dx,dy,dz)) continue;\n\n            int perms[6][3] = {\n                {dx,dy,dz},{dx,dz,dy},{dy,dx,dz},{dy,dz,dx},{dz,dx,dy},{dz,dy,dx}\n            };\n            bool placed=false;\n            int bx=0,by=0,bz=0, ddx=0,ddy=0,ddz=0;\n            for(int p=0;p<6 && !placed;++p){\n                ddx=perms[p][0]; ddy=perms[p][1]; ddz=perms[p][2];\n                for(int x=0;x+ddx<=D && !placed;++x){\n                    for(int y=0;y+ddy<=D && !placed;++y){\n                        for(int z=0;z+ddz<=D && !placed;++z){\n                            if (!P2.full(x,y,z, ddx,ddy,ddz)) continue;\n                            // masks consistency\n                            bool ok=true;\n                            for(int xi=x; xi<x+ddx && ok; ++xi)\n                                for(int yi=y; yi<y+ddy && ok; ++yi)\n                                    for(int zi=z; zi<z+ddz; ++zi)\n                                        if (!M2[idx(xi,yi,zi)]) { ok=false; break; }\n                            if (!ok) continue;\n                            bx=x; by=y; bz=z; placed=true;\n                        }\n                    }\n                }\n            }\n            if (!placed) continue;\n\n            // Place shared block\n            ++nBlocks;\n            mark_block(M1, b1, nBlocks, ax,ay,az, dx,dy,dz);\n            mark_block(M2, b2, nBlocks, bx,by,bz, ddx,ddy,ddz);\n            // Rebuild prefix sums and recompute runs\n            P1.build(M1); P2.build(M2);\n            recompute_max_runs(M1, P1, maxX, maxY, maxZ);\n            return true;\n        }\n        return false;\n    };\n\n    // Packing loop over all corners with time guard\n    double TL = 4.3;\n    bool changed = true;\n    while (changed && now() < TL){\n        changed = false;\n        for(int x=0;x<D && now()<TL;++x){\n            for(int y=0;y<D && now()<TL;++y){\n                for(int z=0; z<D && now()<TL; ++z){\n                    int id3 = idx(x,y,z);\n                    if (!M1[id3]) continue;\n                    if (place_shared_from_corner(x,y,z)) changed = true;\n                }\n            }\n        }\n    }\n\n    // Additional shared from safe superset U after packing\n    vector<vector<char>> Fboth(D, vector<char>(D,0));\n    vector<vector<char>> Rboth(D, vector<char>(D,0));\n    for (int z=0; z<D; ++z){\n        for (int x=0; x<D; ++x) Fboth[z][x] = (f[0][z][x]=='1' && f[1][z][x]=='1');\n        for (int y=0; y<D; ++y) Rboth[z][y] = (r[0][z][y]=='1' && r[1][z][y]=='1');\n    }\n    vector<char> U(N,0);\n    for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z){\n        if (Fboth[z][x] && Rboth[z][y]) U[idx(x,y,z)] = 1;\n    }\n    for(int i=0;i<N;++i) if (!(M1[i] && M2[i])) U[i]=0;\n\n    // Carve U into shared cuboids first\n    Prefix3D PU; PU.D=D;\n    vector<char> MU(N,0);\n    for(int i=0;i<N;++i) MU[i]=U[i];\n    PU.build(MU);\n    for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z){\n        int id3 = idx(x,y,z);\n        if (!MU[id3]) continue;\n        int a=0; while (x+a<D && PU.full(x,y,z, a+1,1,1)) ++a;\n        int b=0; while (y+b<D && PU.full(x,y,z, 1,b+1,1)) ++b;\n        int c=0; while (z+c<D && PU.full(x,y,z, 1,1,c+1)) ++c;\n        if (a==0||b==0||c==0) continue;\n        int dx=a, dy=b, dz=c;\n        ++nBlocks;\n        mark_block(M1, b1, nBlocks, x,y,z, dx,dy,dz);\n        mark_block(M2, b2, nBlocks, x,y,z, dx,dy,dz);\n        for(int xi=x;xi<x+dx;++xi)\n            for(int yi=y;yi<y+dy;++yi)\n                for(int zi=z;zi<z+dz;++zi)\n                    MU[idx(xi,yi,zi)]=0;\n        PU.build(MU);\n    }\n    for(int i=0;i<N;++i) if (U[i]) { M1[i]=0; M2[i]=0; }\n\n    // Shared identical coordinates leftover (Csame) -> try to carve cuboids too\n    vector<char> Csame(N,0);\n    for(int i=0;i<N;++i) if (M1[i] && M2[i]) Csame[i]=1;\n    // Carve Csame with cuboids in same coordinates\n    Prefix3D PC; PC.D=D;\n    vector<char> MC = Csame;\n    PC.build(MC);\n    for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z){\n        int id3 = idx(x,y,z);\n        if (!MC[id3]) continue;\n        int a=0; while (x+a<D && PC.full(x,y,z, a+1,1,1)) ++a;\n        int b=0; while (y+b<D && PC.full(x,y,z, 1,b+1,1)) ++b;\n        int c=0; while (z+c<D && PC.full(x,y,z, 1,1,c+1)) ++c;\n        if (a==0||b==0||c==0) continue;\n        int dx=a, dy=b, dz=c;\n        ++nBlocks;\n        mark_block(M1, b1, nBlocks, x,y,z, dx,dy,dz);\n        mark_block(M2, b2, nBlocks, x,y,z, dx,dy,dz);\n        for(int xi=x;xi<x+dx;++xi)\n            for(int yi=y;yi<y+dy;++yi)\n                for(int zi=z;zi<z+dz;++zi)\n                    MC[idx(xi,yi,zi)]=0;\n        PC.build(MC);\n    }\n    // Remove remaining Csame\n    for(int i=0;i<N;++i) if (Csame[i]) { M1[i]=0; M2[i]=0; }\n\n    // Remaining exclusives -> components\n    auto place_components = [&](const vector<char>& mask, bool in1, bool in2){\n        vector<char> vis(N,0);\n        const int dxs[6]={1,-1,0,0,0,0};\n        const int dys[6]={0,0,1,-1,0,0};\n        const int dzs[6]={0,0,0,0,1,-1};\n        for(int x=0;x<D;++x) for(int y=0;y<D;++y) for(int z=0;z<D;++z){\n            int s = idx(x,y,z);\n            if (!mask[s] || vis[s]) continue;\n            ++nBlocks;\n            queue<int> q;\n            q.push(s);\n            vis[s]=1;\n            if (in1) b1[s]=nBlocks;\n            if (in2) b2[s]=nBlocks;\n            while(!q.empty()){\n                int v=q.front(); q.pop();\n                int vx = v/(D*D);\n                int rem = v%(D*D);\n                int vy = rem/D;\n                int vz = rem% D;\n                for(int d=0; d<6; ++d){\n                    int nx=vx+dxs[d], ny=vy+dys[d], nz=vz+dzs[d];\n                    if (nx<0||nx>=D||ny<0||ny>=D||nz<0||nz>=D) continue;\n                    int u = idx(nx,ny,nz);\n                    if (mask[u] && !vis[u]){\n                        vis[u]=1;\n                        q.push(u);\n                        if (in1) b1[u]=nBlocks;\n                        if (in2) b2[u]=nBlocks;\n                    }\n                }\n            }\n        }\n    };\n\n    // Build masks again to feed components: anything nonzero is remaining\n    vector<char> R1 = M1, R2 = M2;\n    place_components(R1, true, false);\n    place_components(R2, false, true);\n\n    // Output\n    cout << nBlocks << \"\\n\";\n    for(int i=0;i<N;++i){\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << \"\\n\";\n    for(int i=0;i<N;++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};\nstruct AdjEdge { int to, id; long long w; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M, K;\n    if(!(cin>>N>>M>>K)) return 0;\n    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n    vector<Edge> edges(M);\n    vector<vector<AdjEdge>> g(N);\n    for(int j=0;j<M;j++){\n        int u,v; long long w;\n        cin>>u>>v>>w; --u;--v;\n        edges[j]={u,v,w};\n        g[u].push_back({v,j,w});\n        g[v].push_back({u,j,w});\n    }\n    vector<int> ax(K), ay(K);\n    for(int k=0;k<K;k++) cin>>ax[k]>>ay[k];\n\n    auto dist_int = [&](int xi,int yi,int a,int b)->int{\n        long double dx = (long double)xi - a;\n        long double dy = (long double)yi - b;\n        long double d = sqrt((double)(dx*dx + dy*dy));\n        // ceil to ensure coverage\n        int id = (int)ceil(d - 1e-12);\n        if(id>5000) id=5000;\n        if(id<0) id=0;\n        return id;\n    };\n\n    // Precompute station-resident distances\n    vector<vector<int>> res_order(N);\n    vector<vector<int>> res_dist(N);\n    for(int i=0;i<N;i++){\n        res_order[i].resize(K);\n        iota(res_order[i].begin(), res_order[i].end(), 0);\n        vector<int> tmpd(K);\n        for(int k=0;k<K;k++){\n            tmpd[k] = dist_int(x[i],y[i],ax[k],ay[k]);\n        }\n        // sort indices by distance\n        stable_sort(res_order[i].begin(), res_order[i].end(), [&](int a,int b){\n            return tmpd[a] < tmpd[b];\n        });\n        res_dist[i].resize(K);\n        for(int idx=0; idx<K; ++idx){\n            int rk = res_order[i][idx];\n            res_dist[i][idx] = tmpd[rk];\n        }\n    }\n\n    // Dijkstra from 0 to get shortest path tree\n    const long long INFLL = (1LL<<62);\n    vector<long long> dist(N, INFLL);\n    vector<int> parE(N, -1), parV(N, -1);\n    struct Node { long long d; int v;};\n    struct Cmp { bool operator()(const Node& a, const Node& b) const { return a.d>b.d; } };\n    priority_queue<Node, vector<Node>, Cmp> pq;\n    dist[0]=0; pq.push({0,0});\n    while(!pq.empty()){\n        auto [d,u]=pq.top(); pq.pop();\n        if(d!=dist[u]) continue;\n        for(auto &e: g[u]){\n            int v=e.to; long long nd = d + e.w;\n            if(nd < dist[v]){\n                dist[v]=nd; parE[v]=e.id; parV[v]=u;\n                pq.push({nd,v});\n            }\n        }\n    }\n    // Build SPT edges set\n    vector<int> tree_parent_edge(N,-1);\n    for(int v=1; v<N; v++){\n        tree_parent_edge[v]=parE[v];\n    }\n\n    // Baseline: assign each resident to nearest station (by Euclidean distance, not connectivity)\n    vector<int> P(N,0);\n    vector<int> req(N,0);\n    for(int k=0;k<K;k++){\n        int besti=0; int bestd = dist_int(x[0],y[0],ax[k],ay[k]);\n        for(int i=1;i<N;i++){\n            int d = dist_int(x[i],y[i],ax[k],ay[k]);\n            if(d < bestd){\n                bestd = d; besti=i;\n            }\n        }\n        if(bestd>req[besti]) req[besti]=bestd;\n    }\n    for(int i=0;i<N;i++) P[i]=req[i];\n\n    // Determine set of broadcasting stations (terminals)\n    vector<char> is_terminal(N,false);\n    int terminals=0;\n    for(int i=0;i<N;i++){\n        if(P[i]>0){ is_terminal[i]=true; terminals++; }\n    }\n    is_terminal[0] = is_terminal[0] || (P[0]>0); // ensure 0 marked if broadcasting\n\n    // Determine which tree edges are needed to connect terminals to root in the SPT\n    vector<char> need_edge(M,false);\n    vector<int> used(N,0);\n    // Mark all terminals and propagate to root\n    vector<int> degree_in_subtree(N,0);\n    for(int v=0; v<N; v++){\n        if(!is_terminal[v]) continue;\n        int u=v;\n        while(u!=0){\n            int e = tree_parent_edge[u];\n            if(e<0) break;\n            if(need_edge[e]) { // already marked\n                u = edges[e].u==u ? edges[e].v : edges[e].u;\n                continue;\n            }\n            need_edge[e]=true;\n            degree_in_subtree[edges[e].u]++;\n            degree_in_subtree[edges[e].v]++;\n            u = edges[e].u==u ? edges[e].v : edges[e].u;\n        }\n    }\n\n    // Optional: try to reduce broadcasting set by reassigning to currently broadcasting stations\n    // Build list of broadcasters\n    vector<int> broadcasters;\n    broadcasters.reserve(N);\n    for(int i=0;i<N;i++) if(P[i]>0) broadcasters.push_back(i);\n    if(broadcasters.empty()){\n        // If somehow no broadcasters (shouldn't happen as K>=2000), ensure station 1 covers nearest residents\n        // Set P[0] to max distance to all residents (capped)\n        int mx=0;\n        for(int k=0;k<K;k++){ mx = max(mx, dist_int(x[0],y[0],ax[k],ay[k])); }\n        P[0]=mx;\n        is_terminal[0]=true;\n        // no edges needed\n        fill(need_edge.begin(), need_edge.end(), false);\n    } else {\n        // Reassign residents to nearest broadcaster and recompute P\n        vector<int> newP(N,0);\n        for(int k=0;k<K;k++){\n            int besti = broadcasters[0];\n            int bestd = dist_int(x[besti],y[besti],ax[k],ay[k]);\n            for(size_t t=1;t<broadcasters.size();t++){\n                int i = broadcasters[t];\n                int d = dist_int(x[i],y[i],ax[k],ay[k]);\n                if(d < bestd){ bestd=d; besti=i; }\n            }\n            if(bestd > newP[besti]) newP[besti]=bestd;\n        }\n        P.swap(newP);\n        // update terminals\n        fill(is_terminal.begin(), is_terminal.end(), false);\n        broadcasters.clear();\n        for(int i=0;i<N;i++) if(P[i]>0){ is_terminal[i]=true; broadcasters.push_back(i); }\n        // recompute needed edges on SPT\n        fill(need_edge.begin(), need_edge.end(), false);\n        for(int v=0; v<N; v++){\n            if(!is_terminal[v]) continue;\n            int u=v;\n            while(u!=0){\n                int e = tree_parent_edge[u];\n                if(e<0) break;\n                if(need_edge[e]){\n                    u = edges[e].u==u ? edges[e].v : edges[e].u;\n                    continue;\n                }\n                need_edge[e]=true;\n                u = edges[e].u==u ? edges[e].v : edges[e].u;\n            }\n        }\n    }\n\n    // Final small tightening: try to reduce P[i] by trimming unnecessary slack.\n    // For each broadcaster i, compute max distance among residents to i when residents choose nearest broadcaster.\n    // Already done; but do a quick pass: for each i, try lowering to the next smaller actual distance in its assigned set.\n    // To keep it simple and fast, we skip recalculating assignments; the previous calculation already set P exactly.\n\n    // Build B array\n    vector<int> B(M,0);\n    for(int j=0;j<M;j++) if(need_edge[j]) B[j]=1;\n\n    // Output\n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << P[i];\n    }\n    cout << '\\n';\n    for(int j=0;j<M;j++){\n        if(j) cout << ' ';\n        cout << B[j];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    const int NN = N * (N + 1) / 2;\n\n    auto id_of = [&](int x, int y)->int { return x*(x+1)/2 + y; };\n    vector<int> x_of(NN), y_of(NN);\n    for (int x=0, id=0; x<N; ++x) {\n        for (int y=0; y<=x; ++y, ++id) {\n            x_of[id]=x; y_of[id]=y;\n        }\n    }\n\n    vector<int> A(NN);\n    for (int x=0; x<N; ++x)\n        for (int y=0; y<=x; ++y)\n            cin >> A[id_of(x,y)];\n\n    const int NONE = -1;\n    vector<array<int,2>> child(NN, {NONE, NONE});\n    vector<array<int,2>> parent(NN, {NONE, NONE});\n    for (int x=0; x<N; ++x) {\n        for (int y=0; y<=x; ++y) {\n            int id = id_of(x,y);\n            if (x < N-1) {\n                int c0 = id_of(x+1, y);\n                int c1 = id_of(x+1, y+1);\n                child[id][0] = c0;\n                child[id][1] = c1;\n                if (parent[c0][0] == NONE) parent[c0][0] = id; else parent[c0][1] = id;\n                if (parent[c1][0] == NONE) parent[c1][0] = id; else parent[c1][1] = id;\n            }\n        }\n    }\n\n    struct Move { int x1,y1,x2,y2; };\n    vector<Move> moves;\n    moves.reserve(10000);\n    auto do_swap = [&](int id1, int id2){\n        swap(A[id1], A[id2]);\n        moves.push_back({x_of[id1], y_of[id1], x_of[id2], y_of[id2]});\n    };\n    const int K_LIMIT = 10000;\n\n    // Strict siftdown along the smaller child path with an early violation check\n    auto siftdown = [&](int start_id){\n        int id = start_id;\n        while (child[id][0] != NONE) {\n            int c0 = child[id][0], c1 = child[id][1];\n            // fast check: if A[id] <= both, stop\n            int v = A[id];\n            int v0 = A[c0], v1 = A[c1];\n            if (v <= v0 && v <= v1) break;\n            int mc = (v0 < v1 ? c0 : c1);\n            do_swap(id, mc);\n            if ((int)moves.size() >= K_LIMIT) return;\n            id = mc;\n        }\n    };\n\n    // 1) Bottom-up single pass, alternating direction per row.\n    // Within a row, process nodes with larger values first (descending A) to push big elements down early.\n    for (int x=N-2; x>=0; --x) {\n        vector<int> ids;\n        ids.reserve(x+1);\n        for (int y=0; y<=x; ++y) ids.push_back(id_of(x,y));\n        // sort by current value descending; stable tie-break by y depending on row parity\n        if ((x & 1) == 0) {\n            stable_sort(ids.begin(), ids.end(), [&](int a, int b){\n                if (A[a] != A[b]) return A[a] > A[b];\n                return y_of[a] < y_of[b];\n            });\n        } else {\n            stable_sort(ids.begin(), ids.end(), [&](int a, int b){\n                if (A[a] != A[b]) return A[a] > A[b];\n                return y_of[a] > y_of[b];\n            });\n        }\n        for (int id : ids) {\n            siftdown(id);\n            if ((int)moves.size() >= K_LIMIT) break;\n        }\n        if ((int)moves.size() >= K_LIMIT) break;\n    }\n\n    auto violates = [&](int id)->bool{\n        if (child[id][0] == NONE) return false;\n        int c0 = child[id][0], c1 = child[id][1];\n        return (A[id] > A[c0] || A[id] > A[c1]);\n    };\n\n    // 2) Targeted polishing using a queue of violating nodes\n    if ((int)moves.size() < K_LIMIT) {\n        deque<int> q;\n        vector<char> inq(NN, 0);\n        for (int x=0; x<N-1; ++x) {\n            for (int y=0; y<=x; ++y) {\n                int id = id_of(x,y);\n                if (violates(id)) { q.push_back(id); inq[id]=1; }\n            }\n        }\n        auto push = [&](int id){\n            if (id==NONE) return;\n            if (child[id][0]==NONE) return;\n            if (!inq[id]) { q.push_back(id); inq[id]=1; }\n        };\n        while (!q.empty() && (int)moves.size() < K_LIMIT) {\n            int id = q.front(); q.pop_front(); inq[id]=0;\n            bool did = false;\n            while (child[id][0] != NONE) {\n                int c0 = child[id][0], c1 = child[id][1];\n                int v = A[id], v0 = A[c0], v1 = A[c1];\n                if (v <= v0 && v <= v1) break;\n                int mc = (v0 < v1 ? c0 : c1);\n                do_swap(id, mc);\n                did = true;\n                if ((int)moves.size() >= K_LIMIT) break;\n                id = mc;\n            }\n            if ((int)moves.size() >= K_LIMIT) break;\n            if (did) {\n                // Enqueue affected neighbors\n                push(parent[id][0]);\n                push(parent[id][1]);\n                push(id);\n                int c0 = child[id][0], c1 = child[id][1];\n                push(c0);\n                push(c1);\n            }\n        }\n    }\n\n    cout << moves.size() << '\\n';\n    for (auto &mv : moves) {\n        cout << mv.x1 << ' ' << mv.y1 << ' ' << mv.x2 << ' ' << mv.y2 << '\\n';\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int D,N;\n    if(!(cin>>D>>N)) return 0;\n    vector<vector<int>> obs(D, vector<int>(D, 0));\n    for(int k=0;k<N;k++){\n        int r,c; cin>>r>>c;\n        obs[r][c]=1;\n    }\n    // Entrance\n    int ei = 0, ej = (D-1)/2;\n    // Build list of free cells excluding entrance\n    vector<Pos> cells; cells.reserve(D*D-1-N);\n    // Snake order by rows, skipping obstacles and entrance\n    for(int i=0;i<D;i++){\n        if(i%2==0){\n            for(int j=0;j<D;j++){\n                if(i==ei && j==ej) continue;\n                if(obs[i][j]) continue;\n                cells.push_back({i,j});\n            }\n        }else{\n            for(int jj=D-1;jj>=0;jj--){\n                int j=jj;\n                if(i==ei && j==ej) continue;\n                if(obs[i][j]) continue;\n                cells.push_back({i,j});\n            }\n        }\n    }\n    int M = (int)cells.size(); // should be D*D-1-N\n    // Map position index for quick lookup\n    vector<vector<int>> posIndex(D, vector<int>(D, -1));\n    for(int idx=0; idx<M; idx++){\n        posIndex[cells[idx].i][cells[idx].j] = idx;\n    }\n    // Occupancy grid: 0 empty, 1 occupied (container), -1 obstacle, -2 entrance (treated as empty for BFS)\n    vector<vector<int>> occ(D, vector<int>(D, 0));\n    for(int i=0;i<D;i++) for(int j=0;j<D;j++){\n        if(obs[i][j]) occ[i][j] = -1;\n    }\n    occ[ei][ej] = -2;\n\n    // For recording where each t is placed\n    vector<Pos> loc_of_id(M, {-1,-1});\n    vector<int> id_at_cell(M, -1); // by path index\n    vector<int> free_pos(M, 1);\n\n    auto bfs_reach = [&](){\n        vector<vector<char>> vis(D, vector<char>(D, 0));\n        queue<Pos> q;\n        q.push({ei,ej});\n        vis[ei][ej]=1;\n        int di[4]={-1,1,0,0};\n        int dj[4]={0,0,-1,1};\n        while(!q.empty()){\n            auto p=q.front(); q.pop();\n            for(int k=0;k<4;k++){\n                int ni=p.i+di[k], nj=p.j+dj[k];\n                if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                if(vis[ni][nj]) continue;\n                if(occ[ni][nj]==0 || occ[ni][nj]==-2){ // empty or entrance\n                    vis[ni][nj]=1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n        return vis;\n    };\n\n    // Online placement\n    for(int d=0; d<M; d++){\n        int t; cin>>t;\n        // compute reachable empty cells mask\n        auto vis = bfs_reach();\n        int ideal = t; if(ideal<0) ideal=0; if(ideal>=M) ideal=M-1;\n        int chosen_idx = -1;\n        // search window expanding\n        int W = 12;\n        int maxW = M;\n        for(int w=W; w<=maxW && chosen_idx==-1; w+=12){\n            int L = max(0, ideal - w);\n            int R = min(M-1, ideal + w);\n            // Collect reachable free candidates with minimal |pos-ideal|\n            int bestScore = INT_MAX;\n            int bestIdx = -1;\n            for(int pos=L; pos<=R; pos++){\n                if(!free_pos[pos]) continue;\n                Pos p = cells[pos];\n                if(!vis[p.i][p.j]) continue;\n                int score = abs(pos - ideal);\n                if(score < bestScore){\n                    bestScore = score;\n                    bestIdx = pos;\n                }else if(score == bestScore && bestIdx!=-1){\n                    // tie-break: for larger t, prefer larger pos; for smaller t, prefer smaller pos\n                    if(t*2 >= M){\n                        if(pos > bestIdx) bestIdx = pos;\n                    }else{\n                        if(pos < bestIdx) bestIdx = pos;\n                    }\n                }\n            }\n            if(bestIdx!=-1) chosen_idx = bestIdx;\n        }\n        if(chosen_idx==-1){\n            // Fallback: pick any reachable free cell, prefer towards ideal direction\n            int bestIdx=-1, bestScore=INT_MAX;\n            for(int pos=0; pos<M; pos++){\n                if(!free_pos[pos]) continue;\n                Pos p=cells[pos];\n                if(!vis[p.i][p.j]) continue;\n                int score = abs(pos - ideal);\n                if(score < bestScore){\n                    bestScore=score; bestIdx=pos;\n                }\n            }\n            if(bestIdx!=-1) chosen_idx=bestIdx;\n        }\n        if(chosen_idx==-1){\n            // As a last resort, pick any free (shouldn't happen because all free cells are reachable by guarantee if empty)\n            for(int pos=0; pos<M; pos++){\n                if(free_pos[pos]){\n                    chosen_idx=pos; break;\n                }\n            }\n        }\n        // Place\n        Pos place = cells[chosen_idx];\n        cout<<place.i<<\" \"<<place.j<<\"\\n\"<<flush;\n        occ[place.i][place.j] = 1;\n        free_pos[chosen_idx]=0;\n        id_at_cell[chosen_idx]=t;\n        loc_of_id[t]=place;\n    }\n\n    // Extraction: repeatedly remove smallest-ID reachable\n    // Build a map from (i,j) to ID\n    vector<vector<int>> id_grid(D, vector<int>(D, -1));\n    for(int pos=0; pos<M; pos++){\n        if(id_at_cell[pos]>=0){\n            Pos p = cells[pos];\n            id_grid[p.i][p.j] = id_at_cell[pos];\n        }\n    }\n\n    vector<pair<int,int>> output_order;\n    output_order.reserve(M);\n\n    auto bfs_reach_cells = [&](){\n        vector<vector<char>> vis(D, vector<char>(D, 0));\n        queue<Pos> q;\n        q.push({ei,ej});\n        vis[ei][ej]=1;\n        int di[4]={-1,1,0,0};\n        int dj[4]={0,0,-1,1};\n        while(!q.empty()){\n            auto p=q.front(); q.pop();\n            for(int k=0;k<4;k++){\n                int ni=p.i+di[k], nj=p.j+dj[k];\n                if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                if(vis[ni][nj]) continue;\n                // reachable through empty cells only\n                if(occ[ni][nj]==0 || occ[ni][nj]==-2){\n                    vis[ni][nj]=1;\n                    q.push({ni,nj});\n                }\n            }\n        }\n        return vis;\n    };\n\n    for(int removed=0; removed<M; removed++){\n        // compute which occupied cells are currently reachable: cell must be adjacent via empty path to entrance\n        // A container is removable if its cell is reachable from entrance through empty cells; i.e., the container's cell must itself be marked reachable when considering it as occupied? The definition says:\n        // \"The square containing the container to be transported out must be reachable from the entrance by only passing through adjacent empty squares\"\n        // That implies the path does not include the container square (since it's not empty). Typically the last step into its square would require the square to be empty, which is impossible. Usually interpretation is: there exists a path of empty cells to a neighbor of the target, and then we can remove it. However AtCoder's typical definition here counts the container square as allowed at endpoint.\n        // The common approach is to allow reaching its cell if we treat it as empty for reachability test of candidate. We'll check neighbors.\n        auto vis = bfs_reach_cells();\n        int bestID = INT_MAX;\n        Pos bestP{-1,-1};\n        for(int i=0;i<D;i++){\n            for(int j=0;j<D;j++){\n                if(id_grid[i][j] < 0) continue;\n                // check if reachable: there exists a path of empty cells from entrance to a neighbor of (i,j)\n                bool reachable = false;\n                int di[4]={-1,1,0,0};\n                int dj[4]={0,0,-1,1};\n                for(int k=0;k<4;k++){\n                    int ni=i+di[k], nj=j+dj[k];\n                    if(ni<0||nj<0||ni>=D||nj>=D) continue;\n                    if(vis[ni][nj]) { reachable=true; break; }\n                }\n                if(!reachable) continue;\n                int curID = id_grid[i][j];\n                if(curID < bestID){\n                    bestID = curID;\n                    bestP = {i,j};\n                }\n            }\n        }\n        if(bestID==INT_MAX){\n            // Fallback: if none reachable by neighbor method, allow cells that themselves are marked reachable if we consider them empty\n            // Temporarily mark all occupied as walls; vis marks empty reachables. None found -> choose any with minimal ID that is adjacent via zero? We'll pick minimal ID anywhere.\n            for(int i=0;i<D;i++){\n                for(int j=0;j<D;j++){\n                    if(id_grid[i][j] >= 0){\n                        int curID = id_grid[i][j];\n                        if(curID < bestID){\n                            bestID=curID; bestP={i,j};\n                        }\n                    }\n                }\n            }\n        }\n        // Output and remove\n        cout<<bestP.i<<\" \"<<bestP.j<<\"\\n\";\n        // Mark empty now\n        occ[bestP.i][bestP.j] = 0;\n        id_grid[bestP.i][bestP.j] = -1;\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int DX[4] = {1,-1,0,0};\nstatic const int DY[4] = {0,0,1,-1};\n\nint n, m, Cn;\ninline bool inb(int i,int j){ return (unsigned)i < (unsigned)n && (unsigned)j < (unsigned)n; }\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if(!(cin >> n >> m)) return 0;\n    Cn = n*n;\n    vector<int> d(Cn);\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            int c; cin >> c;\n            d[i*n+j] = c;\n        }\n    }\n    int C = m+1;\n\n    // Original adjacency matrix\n    vector<vector<char>> A(C, vector<char>(C, 0));\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            int u = d[i*n+j];\n            if(i+1<n){\n                int v = d[(i+1)*n+j];\n                if(u!=v){ A[u][v]=A[v][u]=1; }\n            }\n            if(j+1<n){\n                int v = d[i*n+(j+1)];\n                if(u!=v){ A[u][v]=A[v][u]=1; }\n            }\n        }\n    }\n    for(int i=0;i<n;i++){\n        int c1 = d[i*n+0];\n        int c2 = d[i*n+(n-1)];\n        A[0][c1]=A[c1][0]=1;\n        A[0][c2]=A[c2][0]=1;\n    }\n    for(int j=0;j<n;j++){\n        int c1 = d[0*n+j];\n        int c2 = d[(n-1)*n+j];\n        A[0][c1]=A[c1][0]=1;\n        A[0][c2]=A[c2][0]=1;\n    }\n\n    // Current adjacency counts\n    vector<vector<int>> adjCnt(C, vector<int>(C, 0));\n    auto recomputeAdjCnt = [&](){\n        for(int u=0;u<C;u++) fill(adjCnt[u].begin(), adjCnt[u].end(), 0);\n        for(int i=0;i<n;i++){\n            for(int j=0;j<n;j++){\n                int u = d[i*n+j];\n                if(i+1<n){\n                    int v = d[(i+1)*n+j];\n                    if(u!=v){ adjCnt[u][v]++; adjCnt[v][u]++; }\n                }\n                if(j+1<n){\n                    int v = d[i*n+(j+1)];\n                    if(u!=v){ adjCnt[u][v]++; adjCnt[v][u]++; }\n                }\n            }\n        }\n        for(int i=0;i<n;i++){\n            int c1 = d[i*n+0];\n            int c2 = d[i*n+(n-1)];\n            if(c1!=0){ adjCnt[0][c1]++; adjCnt[c1][0]++; }\n            if(c2!=0){ adjCnt[0][c2]++; adjCnt[c2][0]++; }\n        }\n        for(int j=0;j<n;j++){\n            int c1 = d[0*n+j];\n            int c2 = d[(n-1)*n+j];\n            if(c1!=0){ adjCnt[0][c1]++; adjCnt[c1][0]++; }\n            if(c2!=0){ adjCnt[0][c2]++; adjCnt[c2][0]++; }\n        }\n    };\n    recomputeAdjCnt();\n\n    vector<int> totalCells(C, 0);\n    for(int v : d) totalCells[v]++;\n\n    vector<char> allowZeroAdj(C, 0);\n    for(int c=0;c<C;c++) allowZeroAdj[c] = A[0][c];\n\n    vector<char> zeroConn(Cn, 0);\n\n    deque<int> frontier;\n    vector<char> inFrontier(Cn, 0);\n\n    auto addToFrontier = [&](int p){\n        if(inFrontier[p]) return;\n        int i = p / n, j = p % n;\n        int c = d[p];\n        if(c==0) return;\n        if(!allowZeroAdj[c]) return;\n        if(totalCells[c] <= 1) return;\n        bool canConnectZero = (i==0 || i==n-1 || j==0 || j==n-1);\n        if(!canConnectZero){\n            for(int dir=0;dir<4;dir++){\n                int ni = i + DX[dir], nj = j + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int q = ni*n+nj;\n                if(d[q]==0 && zeroConn[q]){ canConnectZero = true; break; }\n            }\n        }\n        if(!canConnectZero) return;\n        frontier.push_back(p);\n        inFrontier[p] = 1;\n    };\n\n    // Initialize frontier with boundary cells of carveable colors\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            int p = i*n+j;\n            int c = d[p];\n            if(c==0) continue;\n            if(!allowZeroAdj[c]) continue;\n            if(totalCells[c] <= 1) continue;\n            if(i==0 || i==n-1 || j==0 || j==n-1){\n                addToFrontier(p);\n            }\n        }\n    }\n\n    auto t0 = chrono::high_resolution_clock::now();\n    const double TIME_LIMIT = 1.90;\n\n    // Connectivity check\n    vector<char> vis(Cn, 0);\n    auto connectedAfterRemoval = [&](int c, int p)->bool{\n        if(totalCells[c] <= 1) return false;\n        int pi = p / n, pj = p % n;\n        int neighCount = 0;\n        int start = -1;\n        int samePos[4], sc=0;\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            int q = ni*n+nj;\n            if(d[q] == c){ neighCount++; start = q; samePos[sc++] = q; }\n        }\n        if(neighCount <= 1) return true;\n        // Tiny shortcut: if two neighbors forming a 2x2 with p share a same-color neighbor among themselves\n        if(neighCount==2){\n            int q1 = samePos[0], q2 = samePos[1];\n            int q1i = q1/n, q1j = q1%n, q2i = q2/n, q2j = q2%n;\n            // If they are orthogonal and share a common same-color neighbor (the corner opposite to p)\n            if(q1i!=q2i && q1j!=q2j){\n                int ci = q1i, cj = q2j; // corner opposite to p\n                if(inb(ci,cj)){\n                    int r = ci*n+cj;\n                    if(d[r]==c){\n                        // q1 -- r -- q2 connects around p\n                        return true;\n                    }\n                }\n            }\n        }\n        fill(vis.begin(), vis.end(), 0);\n        deque<int> dq;\n        dq.push_back(start);\n        vis[start] = 1;\n        int reach = 1;\n        const int need = totalCells[c]-1;\n        while(!dq.empty()){\n            int v = dq.front(); dq.pop_front();\n            if(reach >= need) break;\n            int vi = v / n, vj = v % n;\n            for(int dir=0;dir<4;dir++){\n                int ni = vi + DX[dir], nj = vj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int u = ni*n+nj;\n                if(u==p) continue;\n                if(!vis[u] && d[u]==c){\n                    vis[u]=1; dq.push_back(u); reach++;\n                }\n            }\n        }\n        return reach == need;\n    };\n\n    auto floodZeroFrom = [&](int sIdx){\n        if(d[sIdx] != 0) return;\n        if(zeroConn[sIdx]) return;\n        deque<int> dq;\n        dq.push_back(sIdx);\n        zeroConn[sIdx] = 1;\n        while(!dq.empty()){\n            int v = dq.front(); dq.pop_front();\n            int vi = v / n, vj = v % n;\n            for(int dir=0;dir<4;dir++){\n                int ni = vi + DX[dir], nj = vj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int u = ni*n+nj;\n                if(d[u]==0 && !zeroConn[u]){\n                    zeroConn[u]=1;\n                    dq.push_back(u);\n                }\n            }\n        }\n    };\n\n    auto compute_k0 = [&](int p)->int{\n        int pi = p / n, pj = p % n;\n        int k0 = 0;\n        if(pi==0) k0++;\n        if(pi==n-1) k0++;\n        if(pj==0) k0++;\n        if(pj==n-1) k0++;\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            if(d[ni*n+nj]==0) k0++;\n        }\n        return k0;\n    };\n\n    // Try to remove a given cell p with full checks\n    auto tryRemove = [&](int p)->bool{\n        int c = d[p];\n        if(c==0) return false;\n        if(!allowZeroAdj[c]) return false;\n        if(totalCells[c] <= 1) return false;\n        int pi = p / n, pj = p % n;\n        // zero connectivity condition\n        bool canConnectZero = (pi==0 || pi==n-1 || pj==0 || pj==n-1);\n        if(!canConnectZero){\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int q = ni*n+nj;\n                if(d[q]==0 && zeroConn[q]){ canConnectZero = true; break; }\n            }\n        }\n        if(!canConnectZero) return false;\n\n        // Neighbor constraints and gather neighbors\n        int neighArr[4], neighCnt=0;\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            int y = d[ni*n+nj];\n            neighArr[neighCnt++] = y;\n            if(y!=c && !allowZeroAdj[y]) return false;\n        }\n        // Preserve required adjacencies c-y\n        for(int k=0;k<neighCnt;k++){\n            int y = neighArr[k];\n            if(y==c) continue;\n            if(A[c][y]){\n                int contrib = 0;\n                for(int dir=0;dir<4;dir++){\n                    int ni = pi + DX[dir], nj = pj + DY[dir];\n                    if(!inb(ni,nj)) continue;\n                    if(d[ni*n+nj]==y) contrib++;\n                }\n                if(adjCnt[c][y] == contrib) return false;\n            }\n        }\n        // Preserve c-0 adjacency if required\n        if(A[0][c]){\n            int k0 = compute_k0(p);\n            if(adjCnt[0][c] == k0) return false;\n        }\n        // Connectivity\n        if(!connectedAfterRemoval(c, p)) return false;\n\n        // Apply removal: update adjCnt\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(inb(ni,nj)){\n                int y = d[ni*n+nj];\n                if(y != c){\n                    adjCnt[c][y]--; adjCnt[y][c]--;\n                }\n            }else{\n                adjCnt[0][c]--; adjCnt[c][0]--;\n            }\n        }\n        d[p] = 0;\n        totalCells[c]--;\n\n        // Flood 0 connectivity\n        if(pi==0 || pi==n-1 || pj==0 || pj==n-1) floodZeroFrom(p);\n        else{\n            bool neighZeroConn = false;\n            for(int dir=0;dir<4;dir++){\n                int ni = pi + DX[dir], nj = pj + DY[dir];\n                if(!inb(ni,nj)) continue;\n                int q = ni*n+nj;\n                if(d[q]==0 && zeroConn[q]){ neighZeroConn = true; break; }\n            }\n            if(neighZeroConn) floodZeroFrom(p);\n        }\n\n        // Add new edges between 0 and neighbors\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            int y = d[ni*n+nj];\n            if(y != 0){\n                adjCnt[0][y]++; adjCnt[y][0]++;\n            }\n        }\n\n        // Expand frontier around p\n        for(int dir=0;dir<4;dir++){\n            int ni = pi + DX[dir], nj = pj + DY[dir];\n            if(!inb(ni,nj)) continue;\n            int q = ni*n+nj;\n            if(d[q]!=0){\n                addToFrontier(q);\n                int qi = q/n, qj = q%n;\n                for(int dir2=0;dir2<4;dir2++){\n                    int ri = qi + DX[dir2], rj = qj + DY[dir2];\n                    if(!inb(ri,rj)) continue;\n                    int r = ri*n+rj;\n                    if(d[r]!=0) addToFrontier(r);\n                }\n            }\n        }\n\n        return true;\n    };\n\n    // Initial rim seeding: quick pass along boundary under small time slice\n    {\n        auto tStart = chrono::high_resolution_clock::now();\n        for(int i=0;i<n;i++){\n            for(int j=0;j<n;j++){\n                if(!(i==0 || i==n-1 || j==0 || j==n-1)) continue;\n                int p = i*n+j;\n                if(d[p]==0) continue;\n                int c = d[p];\n                if(!allowZeroAdj[c]) continue;\n                if(totalCells[c] <= 1) continue;\n                // Quick local checks before full try\n                // Avoid if this is the only c-0 contact\n                if(A[0][c] && adjCnt[0][c] == compute_k0(p)) continue;\n                tryRemove(p);\n                auto tNow = chrono::high_resolution_clock::now();\n                if(chrono::duration<double>(tNow - tStart).count() > 0.10) break;\n            }\n        }\n    }\n\n    int rebuildCounter = 0;\n    while(true){\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - t0).count();\n        if(elapsed > TIME_LIMIT) break;\n\n        if(frontier.empty()){\n            rebuildCounter++;\n            if(rebuildCounter > 3) break;\n            for(int k=0;k<Cn;k++) inFrontier[k]=0;\n            for(int i=0;i<n;i++){\n                for(int j=0;j<n;j++){\n                    int p = i*n+j;\n                    addToFrontier(p);\n                }\n            }\n            if(frontier.empty()) break;\n        }\n\n        // Pop a batch and prioritize by heuristic score\n        struct Node{ int p; int score; };\n        vector<Node> nodes;\n        nodes.reserve(256);\n        int take = min<int>(256, frontier.size());\n        for(int t=0;t<take;t++){\n            int p = frontier.front(); frontier.pop_front();\n            inFrontier[p]=0;\n            int c = d[p];\n            if(c==0) continue;\n            if(!allowZeroAdj[c]) continue;\n            if(totalCells[c] <= 1) continue;\n            int i = p/n, j = p%n;\n            bool canConnectZero = (i==0 || i==n-1 || j==0 || j==n-1);\n            if(!canConnectZero){\n                for(int dir=0;dir<4;dir++){\n                    int ni = i + DX[dir], nj = j + DY[dir];\n                    if(!inb(ni,nj)) continue;\n                    int q = ni*n+nj;\n                    if(d[q]==0 && zeroConn[q]){ canConnectZero = true; break; }\n                }\n            }\n            if(!canConnectZero) continue;\n\n            int same=0, reqAdj=0, boundaryContrib=0, badNbr=0;\n            for(int dir=0;dir<4;dir++){\n                int ni = i + DX[dir], nj = j + DY[dir];\n                if(inb(ni,nj)){\n                    int y = d[ni*n+nj];\n                    if(y==c) same++;\n                    else{\n                        if(!allowZeroAdj[y]) badNbr++;\n                        if(A[c][y]) reqAdj++;\n                    }\n                }else boundaryContrib++;\n            }\n            int rare = (adjCnt[0][c] <= 2) ? 3 : (adjCnt[0][c] <= 5 ? 1 : 0);\n            int score = same*12 - reqAdj*4 - boundaryContrib*2 - badNbr*100 - rare;\n            nodes.push_back({p, score});\n        }\n        sort(nodes.begin(), nodes.end(), [&](const Node& a, const Node& b){\n            if(a.score != b.score) return a.score > b.score;\n            return a.p < b.p;\n        });\n\n        bool anyRemoved = false;\n        for(const auto& nd : nodes){\n            auto t1 = chrono::high_resolution_clock::now();\n            double el = chrono::duration<double>(t1 - t0).count();\n            if(el > TIME_LIMIT) break;\n\n            int p = nd.p;\n            int c = d[p];\n            if(c==0) continue;\n\n            // If removing p would drop the last c-0 adjacency, try to pre-ensure new contact\n            bool needEnsure = false;\n            if(A[0][c]){\n                int k0 = compute_k0(p);\n                if(adjCnt[0][c] == k0) needEnsure = true;\n            }\n            if(needEnsure){\n                // Find a nearby cell r of color c that can be removed and connects to zero/boundary\n                bool ensured = false;\n                int pi = p/n, pj = p%n;\n                // Search in radius 2 Manhattan\n                for(int rad=1; rad<=2 && !ensured; rad++){\n                    for(int dir=0; dir<4 && !ensured; dir++){\n                        for(int t=1; t<=rad; t++){\n                            int ni = pi + DX[dir]*t;\n                            int nj = pj + DY[dir]*t;\n                            if(!inb(ni,nj)) continue;\n                            int r = ni*n+nj;\n                            if(d[r] != c) continue;\n                            int ri = ni, rj = nj;\n                            bool canConn = (ri==0 || ri==n-1 || rj==0 || rj==n-1);\n                            if(!canConn){\n                                for(int dd=0; dd<4; dd++){\n                                    int si = ri + DX[dd], sj = rj + DY[dd];\n                                    if(!inb(si,sj)) continue;\n                                    int s = si*n+sj;\n                                    if(d[s]==0 && zeroConn[s]){ canConn = true; break; }\n                                }\n                            }\n                            if(!canConn) continue;\n                            // Avoid last c-0 contact removal for r\n                            if(A[0][c] && adjCnt[0][c] == compute_k0(r)) continue;\n                            if(tryRemove(r)){\n                                ensured = true;\n                            }\n                        }\n                    }\n                }\n            }\n\n            if(tryRemove(p)){\n                anyRemoved = true;\n            }\n        }\n\n        if(!anyRemoved && frontier.empty()){\n            rebuildCounter++;\n            if(rebuildCounter > 3) break;\n            for(int k=0;k<Cn;k++) inFrontier[k]=0;\n            for(int i=0;i<n;i++){\n                for(int j=0;j<n;j++){\n                    int p = i*n+j;\n                    addToFrontier(p);\n                }\n            }\n        }\n    }\n\n    // Output\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            if(j) cout << ' ';\n            cout << d[i*n+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    uint64_t seed = chrono::high_resolution_clock::now().time_since_epoch().count();\n    mt19937_64 rng(seed);\n\n    // Budgets\n    int Q_duel = max(0, Q / 20);   // ~5%\n    int Q_corr = Q - Q_duel;       // ~95%\n\n    // K schedule for correlation\n    vector<int> Ks = { max(2, N/2), max(2, N/3), max(2, N/4), max(2, N/6) };\n    int kKinds = (int)Ks.size();\n\n    vector<long long> corr(N, 0);\n\n    // Global shuffled index array for fair participation\n    vector<int> base(N); iota(base.begin(), base.end(), 0);\n    shuffle(base.begin(), base.end(), rng);\n    int rr = 0;\n\n    auto do_query = [&](vector<int> L, vector<int> R)->int{\n        // Ensure unique and disjoint\n        auto uniq = [](vector<int>& v){\n            sort(v.begin(), v.end());\n            v.erase(unique(v.begin(), v.end()), v.end());\n        };\n        uniq(L); uniq(R);\n        // Remove intersection from R\n        vector<int> RR; RR.reserve(R.size());\n        size_t i = 0, j = 0;\n        while (i < L.size() && j < R.size()) {\n            if (L[i] == R[j]) { ++i; ++j; }\n            else if (L[i] < R[j]) ++i;\n            else { RR.push_back(R[j]); ++j; }\n        }\n        while (j < R.size()) { RR.push_back(R[j]); ++j; }\n        R.swap(RR);\n        if (L.empty() && !R.empty()) { L.push_back(R.back()); R.pop_back(); }\n        if (R.empty() && !L.empty()) { R.push_back(L.back()); L.pop_back(); }\n        if (L.empty() || R.empty()) {\n            int a = uniform_int_distribution<int>(0, N-1)(rng);\n            int b = uniform_int_distribution<int>(0, N-1)(rng);\n            while (b == a) b = uniform_int_distribution<int>(0, N-1)(rng);\n            L = {a}; R = {b};\n        }\n        cout << (int)L.size() << \" \" << (int)R.size();\n        for (int v : L) cout << \" \" << v;\n        for (int v : R) cout << \" \" << v;\n        cout << \"\\n\" << flush;\n        string s; if (!(cin >> s)) exit(0);\n        if (s == \"<\") return -1;\n        if (s == \">\") return +1;\n        return 0;\n    };\n\n    // Correlation queries\n    int ki = 0;\n    for (int q = 0; q < Q_corr; q++) {\n        int K = Ks[ki]; ki = (ki+1) % kKinds;\n        K = min(K, N);\n        if (K < 2) K = 2;\n        vector<int> sel; sel.reserve(K);\n        for (int t = 0; t < K; t++) sel.push_back(base[(rr + t) % N]);\n        rr = (rr + K) % N;\n        shuffle(sel.begin(), sel.end(), rng);\n        vector<int> L, R;\n        int leftTarget = K/2;\n        L.reserve((K+1)/2); R.reserve(K/2);\n        for (int t = 0; t < K; t++) {\n            if ((int)L.size() < leftTarget) L.push_back(sel[t]);\n            else R.push_back(sel[t]);\n        }\n        if (L.empty()) { L.push_back(R.back()); R.pop_back(); }\n        if (R.empty()) { R.push_back(L.back()); L.pop_back(); }\n        int y = do_query(L, R);\n        if (y != 0) {\n            for (int v : L) corr[v] += y;\n            for (int v : R) corr[v] -= y;\n        }\n    }\n\n    // Correlation-based score: stronger power transform, then normalize\n    long long mnCorr = *min_element(corr.begin(), corr.end());\n    vector<double> corrScore(N);\n    for (int i = 0; i < N; i++) {\n        double s = (double)(corr[i] - mnCorr + 1);\n        corrScore[i] = pow(s, 1.45);\n    }\n    double cmin = *min_element(corrScore.begin(), corrScore.end());\n    double cmax = *max_element(corrScore.begin(), corrScore.end());\n    if (cmax - cmin < 1e-12) cmax = cmin + 1.0;\n    for (int i = 0; i < N; i++) corrScore[i] = (corrScore[i] - cmin) / (cmax - cmin);\n\n    // Order by correlation\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    stable_sort(ord.begin(), ord.end(), [&](int a, int b){\n        if (corrScore[a] != corrScore[b]) return corrScore[a] > corrScore[b];\n        return a < b;\n    });\n\n    // Micro top-k equalization: nudge top T to spread a little\n    int Tspread = min(N, max(5, N/5));\n    for (int r = 0; r < Tspread; r++) {\n        int i = ord[r];\n        double factor = 1.0 - 0.05 * (double)r / max(1, Tspread-1); // from 1.0 to ~0.95\n        corrScore[i] *= factor;\n    }\n\n    // Light duels among top M to refine very top (small weight)\n    int M = min(N, max(8, N/3));\n    vector<int> top(ord.begin(), ord.begin()+M);\n    vector<int> wins(N,0), games(N,0);\n    for (int q = 0; q < Q_duel; q++) {\n        int ia = uniform_int_distribution<int>(0, M-1)(rng);\n        int ib = uniform_int_distribution<int>(0, M-1)(rng);\n        while (ib == ia) ib = uniform_int_distribution<int>(0, M-1)(rng);\n        int a = top[ia], b = top[ib];\n        int y = do_query(vector<int>{a}, vector<int>{b});\n        if (y > 0) wins[a]++; else if (y < 0) wins[b]++;\n        games[a]++; games[b]++;\n    }\n    vector<double> wr(N, 0.5);\n    for (int i = 0; i < N; i++) wr[i] = games[i] ? (double)wins[i]/games[i] : 0.5;\n    double wrMin = 1.0, wrMax = 0.0;\n    for (double x : wr) { wrMin = min(wrMin, x); wrMax = max(wrMax, x); }\n    if (wrMax - wrMin < 1e-12) wrMax = wrMin + 1.0;\n    vector<double> wrScaled(N);\n    for (int i = 0; i < N; i++) wrScaled[i] = (wr[i] - wrMin) / (wrMax - wrMin);\n\n    // Combine estimates: correlation dominates, small duel refine\n    double a_corr = 1.0, a_duel = 0.12;\n    vector<double> est(N);\n    for (int i = 0; i < N; i++) {\n        double v = a_corr * corrScore[i] + a_duel * wrScaled[i];\n        if (!isfinite(v) || v <= 0) v = 1e-6;\n        est[i] = v;\n    }\n\n    // Isotonic smoothing along corr order (non-increasing)\n    vector<double> val; val.reserve(N);\n    vector<int> cnt; cnt.reserve(N);\n    for (int p = 0; p < N; p++) {\n        val.push_back(est[ord[p]]);\n        cnt.push_back(1);\n        while (val.size() >= 2 && val[val.size()-2] < val.back()) {\n            int c1 = cnt[val.size()-2], c2 = cnt.back();\n            double avg = (val[val.size()-2]*c1 + val.back()*c2) / (c1 + c2);\n            val.pop_back(); cnt.pop_back();\n            val.back() = avg; cnt.back() = c1 + c2;\n        }\n    }\n    vector<double> iso; iso.reserve(N);\n    for (size_t i = 0; i < val.size(); i++) for (int c = 0; c < cnt[i]; c++) iso.push_back(val[i]);\n    vector<double> est_smooth(N);\n    for (int i = 0; i < N; i++) est_smooth[ord[i]] = iso[i];\n\n    // LPT assignment\n    vector<int> order(N); iota(order.begin(), order.end(), 0);\n    stable_sort(order.begin(), order.end(), [&](int a, int b){\n        if (est_smooth[a] != est_smooth[b]) return est_smooth[a] > est_smooth[b];\n        return a < b;\n    });\n    vector<int> assign(N, 0);\n    vector<double> bins(D, 0.0);\n    using PDI = pair<double,int>;\n    priority_queue<PDI, vector<PDI>, greater<PDI>> pq;\n    for (int d = 0; d < D; d++) pq.emplace(0.0, d);\n    for (int v : order) {\n        auto [s, d] = pq.top(); pq.pop();\n        assign[v] = d;\n        s += est_smooth[v];\n        bins[d] = s;\n        pq.emplace(s, d);\n    }\n\n    // Build bin items\n    vector<vector<int>> binItems(D);\n    for (int i = 0; i < N; i++) binItems[assign[i]].push_back(i);\n\n    auto variance = [&](const vector<double>& bs)->double{\n        double mean = 0; for (double x : bs) mean += x; mean /= D;\n        double v = 0; for (double x : bs){ double d = x-mean; v += d*d; }\n        return v / D;\n    };\n    auto remove_from = [&](vector<int>& v, int x){\n        for (size_t p = 0; p < v.size(); ++p) if (v[p]==x){ v[p]=v.back(); v.pop_back(); return; }\n    };\n\n    // Quick top-heavy spread: if two of top H are in same bin, try moving one to lightest bin\n    int H = min(N, 8);\n    vector<int> topH = order; if ((int)topH.size() > H) topH.resize(H);\n    for (int x = 0; x < H; x++) {\n        for (int y = x+1; y < H; y++) {\n            int i = topH[x], j = topH[y];\n            int bi = assign[i], bj = assign[j];\n            if (bi == bj) {\n                int l = int(min_element(bins.begin(), bins.end()) - bins.begin());\n                if (l != bi) {\n                    double before = variance(bins);\n                    // try moving j\n                    bins[bi] -= est_smooth[j]; bins[l] += est_smooth[j];\n                    double after = variance(bins);\n                    if (after + 1e-12 < before) {\n                        remove_from(binItems[bi], j);\n                        binItems[l].push_back(j);\n                        assign[j] = l;\n                    } else {\n                        // revert\n                        bins[bi] += est_smooth[j]; bins[l] -= est_smooth[j];\n                    }\n                }\n            }\n        }\n    }\n\n    // Recompute bins after potential moves\n    fill(bins.begin(), bins.end(), 0.0);\n    for (int d = 0; d < D; d++) {\n        double s = 0;\n        for (int i : binItems[d]) s += est_smooth[i];\n        bins[d] = s;\n    }\n\n    // Local search: single move, swap, small multi-swap\n    int iters = 700;\n    for (int it = 0; it < iters; it++) {\n        int h = int(max_element(bins.begin(), bins.end()) - bins.begin());\n        int l = int(min_element(bins.begin(), bins.end()) - bins.begin());\n        if (h == l) break;\n        double baseVar = variance(bins);\n        double bestDelta = 0.0;\n        int bi=-1, bj=-1, bestType=0;\n        vector<int> pack;\n\n        vector<int> candH = binItems[h], candL = binItems[l];\n        int tryH = min((int)candH.size(), 24);\n        int tryL = min((int)candL.size(), 24);\n        if ((int)candH.size() > tryH) { shuffle(candH.begin(), candH.end(), rng); candH.resize(tryH); }\n        if ((int)candL.size() > tryL) { shuffle(candL.begin(), candL.end(), rng); candL.resize(tryL); }\n\n        // Single move\n        for (int i : candH) {\n            bins[h] -= est_smooth[i]; bins[l] += est_smooth[i];\n            double vnew = variance(bins);\n            double delta = baseVar - vnew;\n            bins[h] += est_smooth[i]; bins[l] -= est_smooth[i];\n            if (delta > bestDelta + 1e-12) { bestDelta = delta; bestType = 1; bi = i; }\n        }\n        // Pair swap\n        for (int i : candH) for (int j : candL) {\n            bins[h] = bins[h] - est_smooth[i] + est_smooth[j];\n            bins[l] = bins[l] - est_smooth[j] + est_smooth[i];\n            double vnew = variance(bins);\n            double delta = baseVar - vnew;\n            bins[h] = bins[h] + est_smooth[i] - est_smooth[j];\n            bins[l] = bins[l] + est_smooth[j] - est_smooth[i];\n            if (delta > bestDelta + 1e-12) { bestDelta = delta; bestType = 2; bi = i; bj = j; }\n        }\n        // 2-for-1: one big from h vs best pair from l\n        if ((int)candL.size() >= 2) {\n            sort(candL.begin(), candL.end(), [&](int a, int b){ return est_smooth[a] < est_smooth[b]; });\n            for (int i : candH) {\n                double target = est_smooth[i];\n                int a = 0, b = (int)candL.size()-1;\n                double bestSum = -1; pair<int,int> bestPair = {-1,-1};\n                while (a < b) {\n                    double s = est_smooth[candL[a]] + est_smooth[candL[b]];\n                    if (s <= target * 1.3) {\n                        if (s > bestSum) { bestSum = s; bestPair = {candL[a], candL[b]}; }\n                        a++;\n                    } else b--;\n                }\n                if (bestSum > 0) {\n                    bins[h] = bins[h] - est_smooth[i] + bestSum;\n                    bins[l] = bins[l] - bestSum + est_smooth[i];\n                    double vnew = variance(bins);\n                    double delta = baseVar - vnew;\n                    bins[h] = bins[h] + est_smooth[i] - bestSum;\n                    bins[l] = bins[l] + bestSum - est_smooth[i];\n                    if (delta > bestDelta + 1e-12) {\n                        bestDelta = delta; bestType = 3; bi = i; pack = {bestPair.first, bestPair.second};\n                    }\n                }\n            }\n        }\n        // Greedy k-for-1\n        {\n            vector<int> smalls = candL;\n            sort(smalls.begin(), smalls.end(), [&](int a, int b){ return est_smooth[a] < est_smooth[b]; });\n            for (int i : candH) {\n                double target = est_smooth[i];\n                double sum = 0.0; vector<int> take;\n                for (int j : smalls) {\n                    if ((int)take.size() >= 10) break;\n                    if (sum + est_smooth[j] <= target * 1.25) {\n                        sum += est_smooth[j]; take.push_back(j);\n                    }\n                }\n                if (take.empty()) continue;\n                bins[h] = bins[h] - est_smooth[i] + sum;\n                bins[l] = bins[l] - sum + est_smooth[i];\n                double vnew = variance(bins);\n                double delta = baseVar - vnew;\n                bins[h] = bins[h] + est_smooth[i] - sum;\n                bins[l] = bins[l] + sum - est_smooth[i];\n                if (delta > bestDelta + 1e-12) {\n                    bestDelta = delta; bestType = 4; bi = i; pack = take;\n                }\n            }\n        }\n\n        if (bestType == 0 || bestDelta <= 1e-12) break;\n\n        auto remove_from_vec = [&](vector<int>& v, int x){\n            for (size_t p = 0; p < v.size(); ++p) if (v[p]==x){ v[p]=v.back(); v.pop_back(); return; }\n        };\n\n        if (bestType == 1) {\n            remove_from_vec(binItems[h], bi);\n            binItems[l].push_back(bi);\n            bins[h] -= est_smooth[bi]; bins[l] += est_smooth[bi];\n        } else if (bestType == 2) {\n            remove_from_vec(binItems[h], bi);\n            remove_from_vec(binItems[l], bj);\n            binItems[h].push_back(bj);\n            binItems[l].push_back(bi);\n            bins[h] = bins[h] - est_smooth[bi] + est_smooth[bj];\n            bins[l] = bins[l] - est_smooth[bj] + est_smooth[bi];\n        } else {\n            remove_from_vec(binItems[h], bi);\n            binItems[l].push_back(bi);\n            bins[h] -= est_smooth[bi]; bins[l] += est_smooth[bi];\n            double sum = 0.0;\n            for (int j : pack) sum += est_smooth[j];\n            for (int j : pack) { remove_from_vec(binItems[l], j); binItems[h].push_back(j); }\n            bins[h] += sum; bins[l] -= sum;\n        }\n    }\n\n    vector<int> finalAssign(N);\n    for (int d = 0; d < D; d++) for (int i : binItems[d]) finalAssign[i] = d;\n\n    for (int i = 0; i < N; i++) {\n        if (i) cout << ' ';\n        cout << finalAssign[i];\n    }\n    cout << \"\\n\" << flush;\n\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Solver {\n    int n, m, H;\n    vector<vector<int>> st;     // stacks: bottom -> top\n    vector<int> whereS;         // stack index for each box (1..n), -1 if removed\n    vector<pair<int,int>> ops;  // operations (v, i), i in [0..m]\n\n    void read_input() {\n        cin >> n >> m;\n        H = n / m; // For given constraints: n=200, m=10 -> H=20\n        st.assign(m, {});\n        whereS.assign(n + 1, -1);\n        for (int i = 0; i < m; ++i) {\n            st[i].resize(H);\n            for (int j = 0; j < H; ++j) {\n                int v; cin >> v;\n                st[i][j] = v;\n                whereS[v] = i;\n            }\n        }\n    }\n\n    // Find index of v in stack s by scan; return -1 if not found\n    int find_index_in_stack(int v, int s) const {\n        if (s < 0) return -1;\n        const auto &vec = st[s];\n        for (int i = 0; i < (int)vec.size(); ++i) {\n            if (vec[i] == v) return i;\n        }\n        return -1;\n    }\n\n    inline int bin_of(int v) const {\n        int b = (v - 1) / H;\n        if (b < 0) b = 0;\n        if (b >= m) b = m - 1;\n        return b;\n    }\n\n    inline int top_value(int i) const {\n        if (st[i].empty()) return INT_MAX / 4; // empty is excellent target\n        return st[i].back();\n    }\n\n    // Compute an approximate min-bin of a block st[s][idx..end) using only first W elements\n    int approx_min_bin_of_block(int s, int idx, int W = 7) const {\n        int end = (int)st[s].size();\n        int lim = min(end, idx + W);\n        int mb = m - 1;\n        for (int i = idx; i < lim; ++i) {\n            mb = min(mb, bin_of(st[s][i]));\n            if (mb == 0) break;\n        }\n        return mb;\n    }\n\n    // Evaluate destination for moving suffix [idx..end) from stack s to dest.\n    // Lower score is better.\n    long long score_destination(int s, int idx, int dest) const {\n        if (dest == s) return (1LL<<60);\n        if (st[dest].empty()) {\n            // Very strong preference to empty stacks; also favor smaller moved size\n            int moved = (int)st[s].size() - idx;\n            return -1000000LL + moved; // tiny tie-break by moved size\n        }\n\n        // Features\n        int moved = (int)st[s].size() - idx;\n        int w = st[s][idx];\n        int bw = bin_of(w);\n        int mb = approx_min_bin_of_block(s, idx);\n\n        // Penalize burying smaller-bin tops in dest's top few\n        int K = min(6, (int)st[dest].size());\n        int badSmallBins = 0;\n        for (int t = 0; t < K; ++t) {\n            int x = st[dest][(int)st[dest].size() - 1 - t];\n            if (bin_of(x) < mb) badSmallBins++;\n        }\n\n        // Prefer shallower dest\n        int h = (int)st[dest].size();\n        // Prefer larger top value as a mild tie-breaker\n        int tv = top_value(dest);\n\n        // Also mild preference to place into the home of the block's min-bin\n        int homeBias = (dest == mb) ? -3 : 0;\n\n        // Composite score\n        long long score = 2000LL * badSmallBins + 5LL * h + 2LL * moved - (long long)tv / 2000 + homeBias;\n        return score;\n    }\n\n    int choose_dest_for_move(int s, int idx) const {\n        // Try home's bin of the approximate min-bin as a quick win if empty\n        int mb = approx_min_bin_of_block(s, idx);\n        if (mb != s && st[mb].empty()) return mb;\n\n        int best = -1;\n        long long bestScore = (1LL<<60);\n        for (int d = 0; d < m; ++d) if (d != s) {\n            long long sc = score_destination(s, idx, d);\n            if (sc < bestScore) {\n                bestScore = sc;\n                best = d;\n            }\n        }\n        if (best == -1) {\n            best = (s + 1) % m;\n            if (best == s) best = (best + 1) % m;\n        }\n        return best;\n    }\n\n    void move_suffix_from_idx(int s, int idx, int dest) {\n        // Move st[s][idx..end) to top of dest\n        int v = st[s][idx];\n        ops.emplace_back(v, dest + 1);\n        int oldSize = (int)st[s].size();\n        for (int i = idx; i < oldSize; ++i) {\n            int x = st[s][i];\n            st[dest].push_back(x);\n            whereS[x] = dest;\n        }\n        st[s].resize(idx);\n    }\n\n    void carry_top(int s) {\n        int v = st[s].back();\n        ops.emplace_back(v, 0);\n        st[s].pop_back();\n        whereS[v] = -1;\n    }\n\n    void expose_and_carry(int t) {\n        int s = whereS[t];\n        // Move blocks above t until t is on top\n        while (true) {\n            int idx = find_index_in_stack(t, s);\n            int h = (int)st[s].size();\n            if (idx == h - 1) break; // t is on top\n            int dest = choose_dest_for_move(s, idx + 1);\n            if (dest == s) {\n                dest = (s + 1) % m;\n                if (dest == s) dest = (dest + 1) % m;\n            }\n            move_suffix_from_idx(s, idx + 1, dest);\n        }\n        carry_top(s);\n    }\n\n    void solve() {\n        ops.reserve(5000);\n        for (int t = 1; t <= n; ++t) {\n            expose_and_carry(t);\n        }\n    }\n\n    void output() const {\n        for (auto &p : ops) {\n            cout << p.first << \" \" << p.second << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver solver;\n    solver.read_input();\n    solver.solve();\n    solver.output();\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if(!(cin>>N)) return 0;\n    vector<string> h(N-1), v(N);\n    for(int i=0;i<N-1;i++) cin>>h[i];\n    for(int i=0;i<N;i++) cin>>v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>d[i][j];\n\n    auto inb = [&](int i,int j){ return 0<=i && i<N && 0<=j && j<N; };\n    const int di[4]={0,1,0,-1};\n    const int dj[4]={1,0,-1,0};\n    string DIR = \"RDLU\";\n    auto canMoveDir = [&](int i,int j,int dir)->bool{\n        if(dir==0){ if(j+1>=N) return false; return v[i][j]=='0'; }\n        if(dir==2){ if(j-1<0)   return false; return v[i][j-1]=='0'; }\n        if(dir==1){ if(i+1>=N) return false; return h[i][j]=='0'; }\n        if(dir==3){ if(i-1<0)   return false; return h[i-1][j]=='0'; }\n        return false;\n    };\n    auto idx = [&](int i,int j){ return i*N + j; };\n    auto posOf = [&](int id)->Pos{ return Pos{ id/N, id%N }; };\n\n    int V = N*N;\n    const int INF = 1e9;\n\n    // All-pairs shortest paths via BFS from each cell\n    vector<vector<int>> dist(V, vector<int>(V, INF));\n    vector<vector<pair<int,int>>> parent(V, vector<pair<int,int>>(V, {-1,-1}));\n    for(int si=0; si<N; si++){\n        for(int sj=0; sj<N; sj++){\n            int s = idx(si,sj);\n            deque<Pos> q;\n            vector<char> vis(V, 0);\n            q.push_back({si,sj});\n            vis[s]=1;\n            dist[s][s]=0;\n            parent[s][s] = {si,sj};\n            while(!q.empty()){\n                auto p = q.front(); q.pop_front();\n                int pid = idx(p.i,p.j);\n                for(int dir=0; dir<4; dir++){\n                    int ni=p.i+di[dir], nj=p.j+dj[dir];\n                    if(!inb(ni,nj)) continue;\n                    if(!canMoveDir(p.i,p.j,dir)) continue;\n                    int nid = idx(ni,nj);\n                    if(vis[nid]) continue;\n                    vis[nid]=1;\n                    dist[s][nid] = dist[s][pid] + 1;\n                    parent[s][nid] = {p.i, p.j};\n                    q.push_back({ni,nj});\n                }\n            }\n        }\n    }\n\n    auto reconstruct_path_dirs = [&](Pos s, Pos t)->vector<int>{\n        vector<int> dirs;\n        if(s.i==t.i && s.j==t.j) return dirs;\n        int sid = idx(s.i,s.j);\n        int tid = idx(t.i,t.j);\n        if(dist[sid][tid] >= INF) return dirs;\n        vector<Pos> rev;\n        Pos cur = t;\n        while(!(cur.i==s.i && cur.j==s.j)){\n            rev.push_back(cur);\n            auto par = parent[sid][ idx(cur.i,cur.j) ];\n            cur = {par.first, par.second};\n        }\n        reverse(rev.begin(), rev.end());\n        int ci=s.i, cj=s.j;\n        for(auto &p: rev){\n            for(int dir=0; dir<4; dir++){\n                if(ci+di[dir]==p.i && cj+dj[dir]==p.j){\n                    dirs.push_back(dir);\n                    ci=p.i; cj=p.j;\n                    break;\n                }\n            }\n        }\n        return dirs;\n    };\n\n    // Build row sequences (default serpentine per row)\n    vector<vector<int>> rowSeq(N, vector<int>(N));\n    for(int i=0;i<N;i++){\n        if(i%2==0){\n            for(int j=0;j<N;j++) rowSeq[i][j] = idx(i,j);\n        }else{\n            for(int j=0;j<N;j++) rowSeq[i][j] = idx(i,N-1-j);\n        }\n    }\n\n    // Precompute internal row path costs for both directions for DP\n    vector<long long> rowCostF(N,0), rowCostR(N,0);\n    vector<pair<int,int>> rowEndsF(N), rowEndsR(N);\n    for(int r=0;r<N;r++){\n        long long sumF=0;\n        for(int k=0;k<N-1;k++) sumF += dist[rowSeq[r][k]][rowSeq[r][k+1]];\n        rowCostF[r]=sumF;\n        rowEndsF[r]={ rowSeq[r].front(), rowSeq[r].back() };\n        long long sumR=0;\n        for(int k=N-1;k>=1;k--) sumR += dist[rowSeq[r][k]][rowSeq[r][k-1]];\n        rowCostR[r]=sumR;\n        rowEndsR[r]={ rowSeq[r].back(), rowSeq[r].front() };\n    }\n\n    // DP over rows: choose orientation per row to minimize total enter + internal + transitions\n    vector<array<long long,2>> dp(N);\n    vector<array<int,2>> prevState(N);\n    auto addSafe = [&](long long a,long long b)->long long{\n        long long LIM = (long long)4e18;\n        if(a>=LIM || b>=LIM) return LIM;\n        return a+b;\n    };\n    for(int s=0;s<2;s++){\n        int startNode = (s==0? rowEndsF[0].first : rowEndsR[0].first);\n        long long enter = dist[idx(0,0)][ startNode ];\n        long long inside = (s==0? rowCostF[0] : rowCostR[0]);\n        dp[0][s] = addSafe(enter, inside);\n        prevState[0][s] = -1;\n    }\n    for(int r=1;r<N;r++){\n        for(int s=0;s<2;s++){\n            dp[r][s] = (long long)4e18;\n            int sStart = (s==0? rowEndsF[r].first : rowEndsR[r].first);\n            long long inside = (s==0? rowCostF[r] : rowCostR[r]);\n            for(int ps=0; ps<2; ps++){\n                int pEnd = (ps==0? rowEndsF[r-1].second : rowEndsR[r-1].second);\n                long long trans = dist[pEnd][ sStart ];\n                long long cand = addSafe(dp[r-1][ps], addSafe(trans, inside));\n                if(cand < dp[r][s]){\n                    dp[r][s]=cand;\n                    prevState[r][s]=ps;\n                }\n            }\n        }\n    }\n    long long bestCost = (long long)4e18;\n    int bestS = 0;\n    for(int s=0;s<2;s++){\n        int endNode = (s==0? rowEndsF[N-1].second : rowEndsR[N-1].second);\n        long long tot = addSafe(dp[N-1][s], dist[endNode][ idx(0,0) ]);\n        if(tot < bestCost){ bestCost=tot; bestS=s; }\n    }\n    vector<int> rowDir(N,0);\n    int s = bestS;\n    for(int r=N-1; r>=0; r--){\n        rowDir[r]=s;\n        s = (r>0? prevState[r][s]:0);\n        if(r==0) break;\n    }\n\n    // Local adjacent-row pair refinement\n    auto getEnds = [&](int rr, int ss)->pair<int,int>{\n        return ss==0 ? rowEndsF[rr] : rowEndsR[rr];\n    };\n    auto getInside = [&](int rr, int ss)->long long{\n        return ss==0 ? rowCostF[rr] : rowCostR[rr];\n    };\n    auto evalPairChange = [&](int r, int s1, int s2)->long long{\n        long long cost=0;\n        if(r==0) cost += dist[idx(0,0)][ getEnds(r,s1).first ];\n        else cost += dist[ getEnds(r-1,rowDir[r-1]).second ][ getEnds(r,s1).first ];\n        cost += getInside(r,s1);\n        cost += dist[ getEnds(r,s1).second ][ getEnds(r+1,s2).first ];\n        cost += getInside(r+1,s2);\n        if(r+1 == N-1) cost += dist[ getEnds(r+1,s2).second ][ idx(0,0) ];\n        else cost += dist[ getEnds(r+1,s2).second ][ getEnds(r+2,rowDir[r+2]).first ];\n        return cost;\n    };\n    for(int r=0; r+1<N; r++){\n        int curS1=rowDir[r], curS2=rowDir[r+1];\n        long long curCost = evalPairChange(r, curS1, curS2);\n        long long flip1 = evalPairChange(r, 1-curS1, curS2);\n        long long flip2 = evalPairChange(r, curS1, 1-curS2);\n        long long flipBoth = evalPairChange(r, 1-curS1, 1-curS2);\n        long long best = curCost; int bs1=curS1, bs2=curS2;\n        if(flip1 < best){ best=flip1; bs1=1-curS1; bs2=curS2; }\n        if(flip2 < best){ best=flip2; bs1=curS1; bs2=1-curS2; }\n        if(flipBoth < best){ best=flipBoth; bs1=1-curS1; bs2=1-curS2; }\n        rowDir[r]=bs1; rowDir[r+1]=bs2;\n    }\n\n    // Build order following chosen row directions\n    vector<int> order; order.reserve(V);\n    for(int r=0;r<N;r++){\n        if(rowDir[r]==0){\n            for(int k=0;k<N;k++) order.push_back(rowSeq[r][k]);\n        }else{\n            for(int k=N-1;k>=0;k--) order.push_back(rowSeq[r][k]);\n        }\n    }\n\n    // Per-row emergency reordering if row internal cost is large\n    for(int row=0; row<N; row++){\n        int start = row*N;\n        int end = start + N - 1;\n        long long internal=0;\n        for(int k=start; k<end; k++) internal += dist[order[k]][order[k+1]];\n        double avgStep = (double)internal / max(1, N-1);\n        if(avgStep > 2.3){ // slightly more aggressive\n            // Cells in this row\n            vector<int> cells; cells.reserve(N);\n            for(int k=start;k<=end;k++) cells.push_back(order[k]);\n            // Previous end\n            int prevEnd = (row==0? idx(0,0) : order[start-1]);\n            // Choose start index minimizing (entry + lookahead)\n            int bestStartIdx = 0;\n            int bestCost = INT_MAX;\n            for(int i=0;i<N;i++){\n                int entry = dist[prevEnd][cells[i]];\n                int lookahead = INT_MAX;\n                for(int j=0;j<N;j++){\n                    if(j==i) continue;\n                    lookahead = min(lookahead, dist[cells[i]][cells[j]]);\n                }\n                int score = entry + (lookahead==INT_MAX?0:lookahead);\n                if(score < bestCost){ bestCost=score; bestStartIdx=i; }\n            }\n            // Greedy NN within row\n            vector<char> used(N,0);\n            vector<int> newRow; newRow.reserve(N);\n            int curId = cells[bestStartIdx];\n            used[bestStartIdx]=1;\n            newRow.push_back(curId);\n            for(int it=1; it<N; it++){\n                int best=-1, bestD=INF;\n                for(int i=0;i<N;i++){\n                    if(used[i]) continue;\n                    int dd = dist[curId][cells[i]];\n                    if(dd < bestD){ bestD=dd; best=i; }\n                }\n                used[best]=1;\n                curId = cells[best];\n                newRow.push_back(curId);\n            }\n            // Write back\n            for(int k=0;k<N;k++) order[start+k] = newRow[k];\n\n            // Extra 2-opt sweep with larger window W=8 for this row\n            int W = 8;\n            for(int i=start; i<=end-2; i++){\n                int jmax = min(end-1, i+W);\n                for(int j=i+2; j<=jmax; j++){\n                    int a = order[i];\n                    int b = order[i+1];\n                    int c = order[j];\n                    int dnode = (j+1<=end? order[j+1] : (row+1<N? order[(row+1)*N] : idx(0,0)));\n                    long long before = (long long)dist[a][b] + dist[c][dnode];\n                    long long after  = (long long)dist[a][c] + dist[b][dnode];\n                    if(after < before){\n                        reverse(order.begin()+i+1, order.begin()+j+1);\n                    }\n                }\n            }\n        }\n    }\n\n    // Intra-row micro-optimization: adjacent swaps (2 passes) + small-window 2-opt (W=6)\n    for(int row=0; row<N; row++){\n        int start = row*N;\n        int end = start + N - 1;\n        for(int pass=0; pass<2; pass++){\n            for(int k=start; k<end-1; k++){\n                int a = order[k];\n                int b = order[k+1];\n                int c = order[k+2];\n                long long before = (long long)dist[a][b] + dist[b][c];\n                long long after  = (long long)dist[a][c] + dist[c][b];\n                if(after < before){\n                    swap(order[k+1], order[k+2]);\n                }\n            }\n            for(int k=end-1; k>start+0; k--){\n                int a = order[k-2];\n                int b = order[k-1];\n                int c = order[k];\n                long long before = (long long)dist[a][b] + dist[b][c];\n                long long after  = (long long)dist[a][c] + dist[c][b];\n                if(after < before){\n                    swap(order[k-1], order[k]);\n                }\n            }\n        }\n        int W = 6;\n        for(int i=start; i<=end-2; i++){\n            int jmax = min(end-1, i+W);\n            for(int j=i+2; j<=jmax; j++){\n                int a = order[i];\n                int b = order[i+1];\n                int c = order[j];\n                int dnode = (j+1<=end? order[j+1] : (row+1<N? order[(row+1)*N] : idx(0,0)));\n                long long before = (long long)dist[a][b] + dist[c][dnode];\n                long long after  = (long long)dist[a][c] + dist[b][dnode];\n                if(after < before){\n                    reverse(order.begin()+i+1, order.begin()+j+1);\n                }\n            }\n        }\n    }\n\n    // Build base moves by chaining shortest paths and return to (0,0)\n    string baseMoves;\n    baseMoves.reserve(V*4);\n    Pos curp = posOf(order[0]);\n    for(int k=1;k<V;k++){\n        Pos nxt = posOf(order[k]);\n        auto seg = reconstruct_path_dirs(curp, nxt);\n        for(int dir: seg) baseMoves.push_back(DIR[dir]);\n        curp = nxt;\n    }\n    {\n        auto seg = reconstruct_path_dirs(curp, {0,0});\n        for(int dir: seg) baseMoves.push_back(DIR[dir]);\n        curp = {0,0};\n    }\n\n    // Nodes along base path\n    vector<Pos> baseNodes;\n    baseNodes.reserve(baseMoves.size()+1);\n    {\n        int i=0,j=0;\n        baseNodes.push_back({i,j});\n        for(char c: baseMoves){\n            int dir = (c=='R'?0: c=='D'?1: c=='L'?2:3);\n            i += di[dir]; j += dj[dir];\n            baseNodes.push_back({i,j});\n        }\n    }\n\n    // Precompute best local loop per cell (prefer 4-cycles), record loopScore\n    struct Loop { vector<int> dirs; int cost; bool is4; int score; };\n    vector<vector<Loop>> loopOf(N, vector<Loop>(N));\n    auto makeLoopAt = [&](int i,int j)->Loop{\n        struct Cand { int score; vector<int> dirs; };\n        vector<Cand> cands;\n        auto add4 = [&](int a, int b){\n            int i0=i, j0=j;\n            if(!canMoveDir(i0,j0,a)) return;\n            int i1=i0+di[a], j1=j0+dj[a];\n            if(!canMoveDir(i1,j1,b)) return;\n            int i2=i1+di[b], j2=j1+dj[b];\n            int a2=(a+2)%4, b2=(b+2)%4;\n            if(!canMoveDir(i2,j2,a2)) return;\n            int i3=i2+di[a2], j3=j2+dj[a2];\n            if(!(i3==i1 && j3==j1)) return;\n            if(!canMoveDir(i3,j3,b2)) return;\n            int i4=i3+di[b2], j4=j3+dj[b2];\n            if(!(i4==i && j4==j)) return;\n            int score = d[i][j] + d[i1][j1] + d[i2][j2] + d[i3][j3];\n            cands.push_back({score, {a,b,a2,b2}});\n        };\n        add4(0,1); add4(1,2); add4(2,3); add4(3,0);\n        if(!cands.empty()){\n            auto best = *max_element(cands.begin(), cands.end(), [](const Cand&a,const Cand&b){return a.score<b.score;});\n            return Loop{best.dirs, (int)best.dirs.size(), true, best.score};\n        }\n        // fallback ping-pong: score = d[i][j] + d[ni][nj]\n        int bestDir=-1, bestScore=-1;\n        for(int dir=0; dir<4; dir++){\n            if(!canMoveDir(i,j,dir)) continue;\n            int ni=i+di[dir], nj=j+dj[dir];\n            int sc = d[i][j] + d[ni][nj];\n            if(sc>bestScore){ bestScore=sc; bestDir=dir; }\n        }\n        if(bestDir!=-1) return Loop{ vector<int>{bestDir, (bestDir+2)%4}, 2, false, bestScore };\n        return Loop{ vector<int>(), 0, false, 0 };\n    };\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) loopOf[i][j]=makeLoopAt(i,j);\n\n    // Visit times and gap estimates\n    int L0 = (int)baseMoves.size();\n    vector<vector<vector<int>>> visits(N, vector<vector<int>>(N));\n    for(int t=0;t<(int)baseNodes.size();t++){\n        auto p = baseNodes[t];\n        visits[p.i][p.j].push_back(t);\n    }\n    vector<vector<double>> gapEst(N, vector<double>(N, 0.0));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            auto &vec = visits[i][j];\n            if(vec.size()<=1){\n                gapEst[i][j] = (double)L0;\n            }else{\n                long long sumGap=0;\n                for(size_t k=1;k<vec.size();k++) sumGap += (vec[k]-vec[k-1]);\n                sumGap += ((int)baseNodes.size()-1 - vec.back()) + vec.front();\n                double avgGap = (double)sumGap / (double)vec.size();\n                gapEst[i][j] = max(1.0, avgGap);\n            }\n        }\n    }\n\n    // Hotspots with priority: loopScore * (gap + lambda) / cost\n    struct Hot { int i,j; int cost; bool is4; double pr; int loopScore; };\n    vector<Hot> hots;\n    hots.reserve(N*N);\n    double lambda = 8.0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        const auto &lp = loopOf[i][j];\n        if(lp.cost==0) continue;\n        double pr = (double)lp.score * (gapEst[i][j] + lambda) / (double)lp.cost;\n        hots.push_back({i,j, lp.cost, lp.is4, pr, lp.score});\n    }\n    if(hots.empty()){\n        cout<<baseMoves<<\"\\n\";\n        return 0;\n    }\n    sort(hots.begin(), hots.end(), [](const Hot&a,const Hot&b){ return a.pr > b.pr; });\n    int K = min((int)hots.size(), max(60, (N*N)/10));\n\n    // Budget\n    long long budgetMax = 100000LL;\n    long long B = budgetMax - (long long)L0;\n    if(B<0) B=0;\n\n    double totalPr=0.0;\n    for(int t=0; t<K; t++) totalPr += max(1e-9, hots[t].pr);\n\n    // Occurrence indices for each hot\n    vector<vector<int>> occIdx(K);\n    for(int t=0; t<K; t++){\n        occIdx[t] = visits[ hots[t].i ][ hots[t].j ];\n    }\n\n    // Allocate repeats conservatively\n    vector<long long> repeats(K, 0);\n    long long used=0;\n    for(int t=0;t<K;t++){\n        auto &hc = hots[t];\n        double frac = max(1e-12, hc.pr) / totalPr;\n        long long targetCost = (long long) floor(frac * (double)B);\n        long long rep = targetCost / hc.cost;\n        long long perVisitCap = hc.is4 ? 22 : 9;\n        long long cap = (long long)occIdx[t].size() * perVisitCap;\n        if(rep > cap) rep = cap;\n        repeats[t]=rep;\n        used += rep * hots[t].cost;\n    }\n    if(used > B){\n        double scale = (double)B / (double)max(1LL, used);\n        used=0;\n        for(int t=0;t<K;t++){\n            repeats[t] = (long long) floor(repeats[t] * scale);\n            used += repeats[t] * hots[t].cost;\n        }\n    }\n    long long rem = B - used;\n    if(rem > 0){\n        // Greedy residual to top loops by loopScore/cost (favor 4-cycles naturally)\n        vector<int> ord(K);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a,int b){\n            double ea = (double)hots[a].loopScore / hots[a].cost;\n            double eb = (double)hots[b].loopScore / hots[b].cost;\n            return ea>eb;\n        });\n        int limit = min((int)ord.size(), 8); // tighter residual focus\n        for(int k=0; k<limit && rem>0; k++){\n            int id = ord[k];\n            int cost = hots[id].cost;\n            if(cost==0) continue;\n            long long occ = (long long)occIdx[id].size();\n            long long can = min(occ * 4LL, rem / cost); // tight extra cap\n            if(can<=0) continue;\n            repeats[id] += can;\n            rem -= can * cost;\n        }\n    }\n\n    // Spread repeats evenly across occurrences\n    vector<vector<long long>> perOcc(K);\n    for(int t=0;t<K;t++){\n        int m = (int)occIdx[t].size();\n        perOcc[t].assign(m, 0);\n        long long R = repeats[t];\n        if(m>0 && R>0){\n            for(long long r=0; r<R; r++){\n                perOcc[t][ r % m ]++;\n            }\n            long long cap = hots[t].is4 ? 24 : 12;\n            for(int k=0;k<m;k++) if(perOcc[t][k] > cap) perOcc[t][k]=cap;\n        }\n    }\n\n    // Map node time index to injection loop and count\n    vector<long long> injectCount(baseNodes.size(), 0);\n    vector<const vector<int>*> injectDirs(baseNodes.size(), nullptr);\n    for(int t=0; t<K; t++){\n        auto &occ = occIdx[t];\n        auto &per = perOcc[t];\n        auto &lp = loopOf[ hots[t].i ][ hots[t].j ].dirs;\n        for(int k=0;k<(int)occ.size();k++){\n            if(per[k] > 0){\n                int ti = occ[k];\n                injectCount[ti] += per[k];\n                injectDirs[ti] = &lp;\n            }\n        }\n    }\n\n    // Emit final path, respecting length limit\n    string out;\n    long long L0ll = (long long)baseMoves.size();\n    out.reserve(min(100000LL, L0ll + B));\n    long long budgetMoves = 100000LL;\n    long long remainingBase = L0ll;\n    for(size_t t=0; t<baseNodes.size(); t++){\n        long long cnt = injectCount[t];\n        auto lp = injectDirs[t];\n        if(cnt>0 && lp && !lp->empty()){\n            int cost = (int)lp->size();\n            while(cnt>0){\n                if(budgetMoves <= remainingBase) break;\n                long long free = budgetMoves - remainingBase;\n                if(free < cost) break;\n                for(int dir: *lp){\n                    out.push_back(DIR[dir]);\n                    budgetMoves--;\n                }\n                cnt--;\n            }\n        }\n        if(t < baseMoves.size()){\n            if(budgetMoves==0) break;\n            out.push_back(baseMoves[t]);\n            budgetMoves--;\n            remainingBase--;\n        }\n    }\n    cout<<out<<\"\\n\";\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\nstatic inline long long manh(const Pos& a, const Pos& b){\n    return llabs(a.i - b.i) + llabs(a.j - b.j);\n}\n\nstruct WordData {\n    array<vector<Pos>,5> L;\n    vector<long long> back1;     // on L1: min cost from L1[j] to finish\n    vector<long long> tailCost0; // per L0 index: exact min from fixed first to finish\n};\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 si, sj;\n    cin >> si >> sj;\n    vector<string> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\n    vector<string> t(M);\n    for(int k=0;k<M;k++) cin >> t[k];\n\n    // Positions per letter\n    vector<vector<Pos>> letterPos(26);\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            letterPos[A[i][j]-'A'].push_back({i,j});\n        }\n    }\n\n    // Precompute per-word data: levels and backward DP for tail costs\n    vector<WordData> W(M);\n    for(int k=0;k<M;k++){\n        const string &s = t[k];\n        for(int d=0; d<5; d++) W[k].L[d] = letterPos[s[d]-'A'];\n        const auto &L0 = W[k].L[0], &L1 = W[k].L[1], &L2 = W[k].L[2], &L3 = W[k].L[3], &L4 = W[k].L[4];\n        int n1=L1.size(), n2=L2.size(), n3=L3.size(), n4=L4.size();\n\n        vector<long long> back3(n3, (long long)4e18);\n        for(int j=0;j<n3;j++){\n            long long best=(long long)4e18;\n            for(int i4=0;i4<n4;i4++){\n                long long v = manh(L3[j], L4[i4]);\n                if(v<best) best=v;\n            }\n            back3[j]=best;\n        }\n        vector<long long> back2(n2, (long long)4e18);\n        for(int j=0;j<n2;j++){\n            long long best=(long long)4e18;\n            for(int i3=0;i3<n3;i3++){\n                long long v = manh(L2[j], L3[i3]) + back3[i3];\n                if(v<best) best=v;\n            }\n            back2[j]=best;\n        }\n        W[k].back1.assign(n1, (long long)4e18);\n        for(int j=0;j<n1;j++){\n            long long best=(long long)4e18;\n            for(int i2=0;i2<n2;i2++){\n                long long v = manh(L1[j], L2[i2]) + back2[i2];\n                if(v<best) best=v;\n            }\n            W[k].back1[j]=best;\n        }\n        int n0=L0.size();\n        W[k].tailCost0.assign(n0, (long long)4e18);\n        for(int i0=0;i0<n0;i0++){\n            long long best=(long long)4e18;\n            for(int i1=0;i1<n1;i1++){\n                long long v = manh(L0[i0], L1[i1]) + W[k].back1[i1];\n                if(v<best) best=v;\n            }\n            W[k].tailCost0[i0]=best;\n        }\n    }\n\n    vector<int> rem(M);\n    iota(rem.begin(), rem.end(), 0);\n    vector<pair<int,int>> ops;\n    ops.reserve(200*5);\n    Pos cur{si,sj};\n\n    const double BETA = 0.3;\n    const double GAMMA = 0.1; // start-distance bias\n    const int K_END = 5;\n    const long long DELTA_SWITCH = 2;\n\n    // exact DP from start for word k\n    auto exact_dp = [&](int k, const Pos& start,\n                        vector<long long>& d0, vector<long long>& d1, vector<long long>& d2, vector<long long>& d3, vector<long long>& d4,\n                        vector<int>& p0, vector<int>& p1, vector<int>& p2, vector<int>& p3){\n        const auto &L0 = W[k].L[0], &L1 = W[k].L[1], &L2 = W[k].L[2], &L3 = W[k].L[3], &L4 = W[k].L[4];\n        int n0=L0.size(), n1=L1.size(), n2=L2.size(), n3=L3.size(), n4=L4.size();\n        d0.assign(n0, 0);\n        for(int i0=0;i0<n0;i0++) d0[i0] = manh(start, L0[i0]);\n        d1.assign(n1, (long long)4e18); p0.assign(n1, -1);\n        for(int i1=0;i1<n1;i1++){\n            long long best=(long long)4e18; int arg=-1;\n            for(int i0=0;i0<n0;i0++){\n                long long v = d0[i0] + manh(L0[i0], L1[i1]);\n                if(v<best){best=v; arg=i0;}\n            }\n            d1[i1]=best; p0[i1]=arg;\n        }\n        d2.assign(n2, (long long)4e18); p1.assign(n2, -1);\n        for(int i2=0;i2<n2;i2++){\n            long long best=(long long)4e18; int arg=-1;\n            for(int i1=0;i1<n1;i1++){\n                long long v = d1[i1] + manh(L1[i1], L2[i2]);\n                if(v<best){best=v; arg=i1;}\n            }\n            d2[i2]=best; p1[i2]=arg;\n        }\n        d3.assign(n3, (long long)4e18); p2.assign(n3, -1);\n        for(int i3=0;i3<n3;i3++){\n            long long best=(long long)4e18; int arg=-1;\n            for(int i2=0;i2<n2;i2++){\n                long long v = d2[i2] + manh(L2[i2], L3[i3]);\n                if(v<best){best=v; arg=i2;}\n            }\n            d3[i3]=best; p2[i3]=arg;\n        }\n        d4.assign(n4, (long long)4e18); p3.assign(n4, -1);\n        for(int i4=0;i4<n4;i4++){\n            long long best=(long long)4e18; int arg=-1;\n            for(int i3=0;i3<n3;i3++){\n                long long v = d3[i3] + manh(L3[i3], L4[i4]);\n                if(v<best){best=v; arg=i3;}\n            }\n            d4[i4]=best; p3[i4]=arg;\n        }\n    };\n\n    // exact next cost via precomputed tail given start\n    auto next_cost_exact_via_tail = [&](int k, const Pos& start)->long long{\n        const auto &L0 = W[k].L[0];\n        const auto &tail = W[k].tailCost0;\n        long long best = (long long)4e18;\n        for(int i0=0;i0<(int)L0.size();i0++){\n            long long v = manh(start, L0[i0]) + tail[i0];\n            if(v<best) best=v;\n        }\n        return (best==(long long)4e18?0:best);\n    };\n\n    // nearest distance from a point to each letter's occurrence list (cached per iteration)\n    array<long long,26> nearestToLetter;\n\n    while(!rem.empty()){\n        // compute nearest start distance for each letter from current cur\n        for(int c=0;c<26;c++){\n            long long best = (long long)4e18;\n            for(const auto &p : letterPos[c]){\n                long long d = manh(cur, p);\n                if(d < best) best = d;\n            }\n            nearestToLetter[c] = best;\n        }\n\n        long long bestCost = (1LL<<60);\n        double bestAug = 1e100;\n        int bestIdxPos = -1;\n        array<int,5> bestIdxInLevels = {-1,-1,-1,-1,-1};\n\n        for(int p=0; p<(int)rem.size(); p++){\n            int a = rem[p];\n            // Exact DP for word a\n            vector<long long> d0,d1,d2,d3,d4;\n            vector<int> p0,p1,p2,p3;\n            exact_dp(a, cur, d0,d1,d2,d3,d4, p0,p1,p2,p3);\n\n            const auto &L0 = W[a].L[0], &L1 = W[a].L[1], &L2 = W[a].L[2], &L3 = W[a].L[3], &L4 = W[a].L[4];\n            int n4=L4.size();\n            // Top K_END ends by d4\n            vector<int> ord4(n4);\n            iota(ord4.begin(), ord4.end(), 0);\n            int take = min(K_END, n4);\n            nth_element(ord4.begin(), ord4.begin()+take-1, ord4.end(), [&](int x, int y){ return d4[x] < d4[y]; });\n            partial_sort(ord4.begin(), ord4.begin()+take, ord4.end(), [&](int x, int y){ return d4[x] < d4[y]; });\n\n            // Evaluate each end with lookahead and start-distance bias\n            long long bestLocalCost = (1LL<<60);\n            double bestLocalAug = 1e100;\n            array<int,5> bestLocalIdx = {-1,-1,-1,-1,-1};\n\n            // start-distance penalty: nearest distance from cur to first letter of this word\n            long long startBias = nearestToLetter[t[a][0]-'A'];\n\n            for(int rk=0; rk<take; rk++){\n                int i4 = ord4[rk];\n                long long costA = d4[i4];\n                int i3 = p3[i4];\n                int i2 = p2[i3];\n                int i1 = p1[i2];\n                int i0 = p0[i1];\n                Pos endA = L4[i4];\n\n                long long bestNext = 0;\n                if(rem.size()>1){\n                    bestNext = (long long)4e18;\n                    for(int q=0; q<(int)rem.size(); q++){\n                        if(q==p) continue;\n                        int b = rem[q];\n                        long long v = next_cost_exact_via_tail(b, endA);\n                        if(v < bestNext) bestNext = v;\n                    }\n                    if(bestNext == (long long)4e18) bestNext = 0;\n                }\n\n                double aug = (double)costA + BETA * (double)bestNext + GAMMA * (double)startBias;\n                if(aug < bestLocalAug || (abs(aug - bestLocalAug) < 1e-9 && costA < bestLocalCost)){\n                    bestLocalAug = aug;\n                    bestLocalCost = costA;\n                    bestLocalIdx = {i0,i1,i2,i3,i4};\n                }\n            }\n\n            // Micro local refinement: consider any end within DELTA_SWITCH\n            {\n                int i4_best = bestLocalIdx[4];\n                long long baseCost = d4[i4_best];\n                Pos baseEnd = L4[i4_best];\n                long long baseNext = 0;\n                if(rem.size()>1){\n                    baseNext = (long long)4e18;\n                    for(int q=0;q<(int)rem.size();q++){\n                        if(q==p) continue;\n                        int b = rem[q];\n                        long long v = next_cost_exact_via_tail(b, baseEnd);\n                        if(v<baseNext) baseNext=v;\n                    }\n                    if(baseNext==(long long)4e18) baseNext=0;\n                }\n                double baseAug = (double)baseCost + BETA * (double)baseNext + GAMMA * (double)startBias;\n\n                for(int i4=0; i4<n4; i4++){\n                    if(d4[i4] > baseCost + DELTA_SWITCH) continue;\n                    if(i4 == i4_best) continue;\n                    long long costA = d4[i4];\n                    int i3 = p3[i4];\n                    int i2 = p2[i3];\n                    int i1 = p1[i2];\n                    int i0 = p0[i1];\n                    Pos endA = L4[i4];\n\n                    long long bestNext = 0;\n                    if(rem.size()>1){\n                        bestNext = (long long)4e18;\n                        for(int q=0;q<(int)rem.size();q++){\n                            if(q==p) continue;\n                            int b = rem[q];\n                            long long v = next_cost_exact_via_tail(b, endA);\n                            if(v<bestNext) bestNext=v;\n                        }\n                        if(bestNext==(long long)4e18) bestNext=0;\n                    }\n                    double aug = (double)costA + BETA * (double)bestNext + GAMMA * (double)startBias;\n                    if(aug + 1e-9 < baseAug){\n                        baseAug = aug;\n                        bestLocalAug = aug;\n                        bestLocalCost = costA;\n                        bestLocalIdx = {i0,i1,i2,i3,i4};\n                    }\n                }\n            }\n\n            if(bestLocalAug < bestAug || (abs(bestLocalAug - bestAug) < 1e-9 && bestLocalCost < bestCost)){\n                bestAug = bestLocalAug;\n                bestCost = bestLocalCost;\n                bestIdxPos = p;\n                bestIdxInLevels = bestLocalIdx;\n            }\n        }\n\n        if(bestIdxPos == -1){\n            // Fallback: choose the closest first letter\n            long long bestD = (1LL<<60); int pick=0;\n            for(int p=0;p<(int)rem.size();p++){\n                int a = rem[p];\n                for(const auto &q : W[a].L[0]){\n                    long long d = manh(cur, q);\n                    if(d<bestD){bestD=d; pick=p;}\n                }\n            }\n            bestIdxPos = pick;\n            // Compute exact indices\n            int a = rem[bestIdxPos];\n            vector<long long> d0,d1,d2,d3,d4;\n            vector<int> p0,p1,p2,p3;\n            exact_dp(a, cur, d0,d1,d2,d3,d4, p0,p1,p2,p3);\n            int i4 = int(min_element(d4.begin(), d4.end()) - d4.begin());\n            int i3 = p3[i4];\n            int i2 = p2[i3];\n            int i1 = p1[i2];\n            int i0 = p0[i1];\n            bestIdxInLevels = {i0,i1,i2,i3,i4};\n        }\n\n        // Emit operations for the chosen word\n        int chosen = rem[bestIdxPos];\n        const auto &L0 = W[chosen].L[0];\n        const auto &L1 = W[chosen].L[1];\n        const auto &L2 = W[chosen].L[2];\n        const auto &L3 = W[chosen].L[3];\n        const auto &L4 = W[chosen].L[4];\n        array<Pos,5> seq = {\n            L0[bestIdxInLevels[0]],\n            L1[bestIdxInLevels[1]],\n            L2[bestIdxInLevels[2]],\n            L3[bestIdxInLevels[3]],\n            L4[bestIdxInLevels[4]]\n        };\n        for(int z=0; z<5; z++){\n            ops.emplace_back(seq[z].i, seq[z].j);\n            cur = seq[z];\n        }\n        rem.erase(rem.begin() + bestIdxPos);\n    }\n\n    for(auto &p : ops){\n        cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Placement {\n    int di, dj;\n    vector<int> cells;\n    bitset<400> mask;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    double eps;\n    if (!(cin >> N >> M >> eps)) return 0;\n    int G = N * N;\n    auto idx = [N](int i, int j) { return i * N + j; };\n    auto ij = [N](int p) { return pair<int,int>(p / N, p % N); };\n\n    // Read shapes\n    vector<vector<pair<int,int>>> shapes(M);\n    vector<int> shape_h(M), shape_w(M), shape_area(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        shape_area[k] = d;\n        int min_i = INT_MAX, min_j = INT_MAX, max_i = INT_MIN, max_j = INT_MIN;\n        for (int t = 0; t < d; ++t) {\n            int i, j; cin >> i >> j;\n            shapes[k][t] = {i, j};\n            min_i = min(min_i, i);\n            min_j = min(min_j, j);\n            max_i = max(max_i, i);\n            max_j = max(max_j, j);\n        }\n        shape_h[k] = max_i - min_i + 1;\n        shape_w[k] = max_j - min_j + 1;\n    }\n\n    // Generate all candidates\n    vector<vector<Placement>> candidates(M);\n    for (int k = 0; k < M; ++k) {\n        int h = shape_h[k], w = shape_w[k];\n        for (int di = 0; di + h <= N; ++di) {\n            for (int dj = 0; dj + w <= N; ++dj) {\n                Placement P; P.di = di; P.dj = dj; P.mask.reset();\n                bool ok = true;\n                for (auto [oi, oj] : shapes[k]) {\n                    int i = di + oi, j = dj + oj;\n                    if (i < 0 || i >= N || j < 0 || j >= N) { ok = false; break; }\n                    int p = idx(i, j);\n                    P.cells.push_back(p);\n                    P.mask.set(p);\n                }\n                if (ok) candidates[k].push_back(move(P));\n            }\n        }\n    }\n\n    // Reverse index: list of (k,t) covering each cell p\n    vector<vector<pair<int,int>>> cell_covers(G);\n    for (int k = 0; k < M; ++k) {\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            for (int p : candidates[k][t].cells) {\n                cell_covers[p].push_back({k, t});\n            }\n        }\n    }\n\n    // Alive tracking\n    vector<vector<char>> alive(M);\n    vector<int> alive_count(M);\n    for (int k = 0; k < M; ++k) {\n        alive[k].assign(candidates[k].size(), 1);\n        alive_count[k] = (int)candidates[k].size();\n    }\n\n    // Counts\n    vector<vector<int>> cnt_cover(M, vector<int>(G, 0)); // per-shape alive candidates that cover p\n    vector<int> cover_count(G, 0); // total alive candidates covering p\n    vector<int> S_can(G, 0);       // number of shapes that can cover p\n    for (int k = 0; k < M; ++k) {\n        vector<char> can(G, 0);\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            for (int p : candidates[k][t].cells) {\n                cnt_cover[k][p]++;\n                cover_count[p]++;\n                can[p] = 1;\n            }\n        }\n        for (int p = 0; p < G; ++p) if (can[p]) S_can[p]++;\n    }\n\n    // Must/may cover bitsets maintained from counts\n    vector<bitset<400>> must_cover_shape(M), may_cover_shape(M);\n    auto refresh_must_may_cell = [&](int k, int p) {\n        if (cnt_cover[k][p] > 0) may_cover_shape[k].set(p);\n        else may_cover_shape[k].reset(p);\n        if (alive_count[k] > 0 && cnt_cover[k][p] == alive_count[k]) must_cover_shape[k].set(p);\n        else must_cover_shape[k].reset(p);\n    };\n    auto recompute_must_may_shape = [&](int k) {\n        for (int p = 0; p < G; ++p) refresh_must_may_cell(k, p);\n    };\n    for (int k = 0; k < M; ++k) recompute_must_may_shape(k);\n\n    // Forced-cover constraints per shape\n    vector<bitset<400>> forced_cover(M);\n    for (int k = 0; k < M; ++k) forced_cover[k].reset();\n\n    // State\n    vector<int> state(G, -1);   // -1 unknown, 0 zero, 1 positive\n    vector<int> v_known(G, -1); // drilled v(i,j), else -1\n\n    deque<int> shapes_to_commit;\n\n    auto flushout = [](){ cout.flush(); };\n\n    auto kill_candidate = [&](int k, int t) {\n        if (!alive[k][t]) return;\n        alive[k][t] = 0;\n        alive_count[k]--;\n        const bitset<400>& m = candidates[k][t].mask;\n        for (int p = m._Find_first(); p < G; p = m._Find_next(p)) {\n            cnt_cover[k][p]--;\n            cover_count[p]--;\n            if (cnt_cover[k][p] == 0) {\n                S_can[p]--;\n            }\n            refresh_must_may_cell(k, p);\n        }\n        if (alive_count[k] == 1) shapes_to_commit.push_back(k);\n    };\n\n    auto enforce_forced = [&](int k) {\n        const bitset<400>& fc = forced_cover[k];\n        if (fc.none()) return;\n        for (int t = 0; t < (int)candidates[k].size(); ++t) {\n            if (!alive[k][t]) continue;\n            bitset<400> tmp = candidates[k][t].mask & fc;\n            if (tmp != fc) {\n                kill_candidate(k, t);\n            }\n        }\n    };\n\n    auto commit_singletons = [&]() {\n        while (!shapes_to_commit.empty()) {\n            int k = shapes_to_commit.front(); shapes_to_commit.pop_front();\n            if (alive_count[k] != 1) continue;\n            int tstar = -1;\n            for (int t = 0; t < (int)alive[k].size(); ++t) if (alive[k][t]) { tstar = t; break; }\n            if (tstar == -1) continue;\n            for (int p : candidates[k][tstar].cells) {\n                if (state[p] == -1) state[p] = 1;\n            }\n        }\n    };\n\n    auto all_singleton = [&]() -> bool {\n        for (int k = 0; k < M; ++k) if (alive_count[k] != 1) return false;\n        return true;\n    };\n\n    // Deduced zeros: S_can==0 => mark zero and prune candidates\n    auto propagate_zero_cells = [&]() {\n        for (int p = 0; p < G; ++p) {\n            if (state[p] == -1 && S_can[p] == 0) {\n                state[p] = 0;\n                for (auto [k, t] : cell_covers[p]) {\n                    if (alive[k][t]) kill_candidate(k, t);\n                }\n            }\n        }\n    };\n\n    // Forced count at cell\n    auto forced_count_at = [&](int p)->int {\n        int c = 0;\n        for (int k = 0; k < M; ++k) if (forced_cover[k].test(p)) c++;\n        return c;\n    };\n\n    // Enforce constraints at drilled positive cell p (small fixed-point)\n    auto enforce_cell_constraints_at_p = [&](int p) {\n        if (v_known[p] <= 0) return;\n        int x = v_known[p];\n        bool changed = true;\n        for (int it = 0; it < 4 && changed; ++it) {\n            changed = false;\n            int Sc = S_can[p];\n            // If exactly x shapes can cover p, force all\n            if (Sc == x) {\n                for (int k = 0; k < M; ++k) {\n                    if (cnt_cover[k][p] > 0 && !forced_cover[k].test(p)) {\n                        forced_cover[k].set(p);\n                        enforce_forced(k);\n                        changed = true;\n                    }\n                }\n            }\n            // If for some shape all alive candidates cover p, force it\n            for (int k = 0; k < M; ++k) {\n                if (alive_count[k] > 0 && cnt_cover[k][p] == alive_count[k] && !forced_cover[k].test(p)) {\n                    forced_cover[k].set(p);\n                    enforce_forced(k);\n                    changed = true;\n                }\n            }\n            // Cap: if already x shapes forced to cover p, eliminate any other covering p\n            int fc = forced_count_at(p);\n            if (fc == x) {\n                for (int k = 0; k < M; ++k) {\n                    if (forced_cover[k].test(p)) continue;\n                    if (cnt_cover[k][p] > 0) {\n                        for (int t = 0; t < (int)candidates[k].size(); ++t) if (alive[k][t]) {\n                            if (candidates[k][t].mask.test(p)) {\n                                kill_candidate(k, t);\n                                changed = true;\n                            }\n                        }\n                    }\n                }\n                // Recheck Sc==x after capping\n                int Sc2 = S_can[p];\n                if (Sc2 == x) {\n                    for (int k = 0; k < M; ++k) {\n                        if (cnt_cover[k][p] > 0 && !forced_cover[k].test(p)) {\n                            forced_cover[k].set(p);\n                            enforce_forced(k);\n                            changed = true;\n                        }\n                    }\n                }\n            }\n            // Necessity: if Sc - 1 < x for some shape, force it\n            Sc = S_can[p];\n            for (int k = 0; k < M; ++k) {\n                if (cnt_cover[k][p] > 0 && !forced_cover[k].test(p)) {\n                    if (Sc - 1 < x) {\n                        forced_cover[k].set(p);\n                        enforce_forced(k);\n                        changed = true;\n                    }\n                }\n            }\n        }\n    };\n\n    // Anchor selection for shapes with small alive_count (2..4)\n    auto select_anchor_for_shape = [&](int k)->int {\n        if (alive_count[k] <= 1 || alive_count[k] > 4) return -1;\n        int bestp = -1;\n        long long bestScore = LLONG_MIN;\n        for (int p = 0; p < G; ++p) {\n            if (state[p] != -1) continue;\n            int cc = cnt_cover[k][p];\n            if (cc <= 0) continue;\n            // prefer cc near half of alive_count to maximize separation\n            long long sep = - llabs(cc * 2 - alive_count[k]);\n            long long score = 60LL * sep + 12LL * cover_count[p] - 6LL * S_can[p];\n            if (score > bestScore) {\n                bestScore = score;\n                bestp = p;\n            }\n        }\n        return bestp;\n    };\n\n    // Global selection: emphasize zero impact and unique coverage; prefer separators; penalize too many must-cover (less info if positive)\n    auto select_next = [&]() -> int {\n        // Try anchors first\n        for (int k = 0; k < M; ++k) {\n            if (alive_count[k] >= 2 && alive_count[k] <= 4) {\n                int p = select_anchor_for_shape(k);\n                if (p != -1) return p;\n            }\n        }\n        int bestp = -1;\n        long long bestScore = LLONG_MIN;\n        for (int p = 0; p < G; ++p) {\n            if (state[p] != -1) continue;\n            if (S_can[p] == 0) continue;\n            int uniq = 0, disc = 0, near_sep = 0, mustm = 0;\n            for (int k = 0; k < M; ++k) {\n                int cc = cnt_cover[k][p];\n                if (cc > 0) {\n                    if (cc == 1) { uniq++; if (alive_count[k] <= 3) near_sep++; }\n                    if (cc < alive_count[k]) disc++;\n                }\n                if (must_cover_shape[k].test(p)) mustm++;\n            }\n            long long score = 18LL * cover_count[p] + 26LL * uniq - 6LL * S_can[p]\n                              + 16LL * disc + 10LL * near_sep - 6LL * mustm;\n            if (S_can[p] <= 2) score += 40;\n            if (score > bestScore) {\n                bestScore = score;\n                bestp = p;\n            }\n        }\n        if (bestp == -1) {\n            for (int p = 0; p < G; ++p) if (state[p] == -1) return p;\n        }\n        return bestp;\n    };\n\n    int ops_used = 0, max_ops = 2 * N * N;\n\n    // Initial deduced zeros\n    propagate_zero_cells();\n\n    // Main loop\n    while (ops_used < max_ops) {\n        if (all_singleton()) break;\n        bool need = false;\n        for (int p = 0; p < G; ++p) if (state[p] == -1 && S_can[p] > 0) { need = true; break; }\n        if (!need) break;\n\n        int p = select_next();\n        if (p == -1) break;\n        auto [i, j] = ij(p);\n        cout << \"q 1 \" << i << ' ' << j << '\\n';\n        flushout();\n        ops_used++;\n        int vresp;\n        if (!(cin >> vresp)) return 0;\n        v_known[p] = vresp;\n        if (vresp == 0) {\n            state[p] = 0;\n            for (auto [k, t] : cell_covers[p]) if (alive[k][t]) kill_candidate(k, t);\n            commit_singletons();\n            propagate_zero_cells();\n        } else {\n            state[p] = 1;\n            enforce_cell_constraints_at_p(p);\n            commit_singletons();\n            propagate_zero_cells();\n        }\n        if (ops_used >= max_ops) break;\n    }\n\n    // If remaining unknowns all deduced zeros, avoid drilling them\n    bool all_deduced = true;\n    for (int p = 0; p < G; ++p) if (state[p] == -1 && S_can[p] > 0) { all_deduced = false; break; }\n    if (!all_deduced) {\n        // Final correctness: drill remaining unknowns\n        for (int p = 0; p < G && ops_used < max_ops; ++p) {\n            if (state[p] == -1) {\n                auto [i, j] = ij(p);\n                cout << \"q 1 \" << i << ' ' << j << '\\n';\n                flushout();\n                ops_used++;\n                int vresp;\n                if (!(cin >> vresp)) return 0;\n                state[p] = (vresp > 0) ? 1 : 0;\n            }\n        }\n    } else {\n        for (int p = 0; p < G; ++p) if (state[p] == -1 && S_can[p] == 0) state[p] = 0;\n    }\n\n    vector<pair<int,int>> ans;\n    ans.reserve(G);\n    for (int p = 0; p < G; ++p) if (state[p] == 1) ans.push_back(ij(p));\n\n    cout << \"a \" << ans.size();\n    for (auto [i, j] : ans) cout << ' ' << i << ' ' << j;\n    cout << '\\n';\n    flushout();\n\n    int ok;\n    if (!(cin >> ok)) return 0;\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect { int i0,j0,i1,j1; long long area() const { return 1LL*(i1-i0)*(j1-j0); } };\n\n// Hopcroft-Karp maximum bipartite matching\nstruct HopcroftKarp {\n    int nL, nR;\n    vector<vector<int>> adj;\n    vector<int> dist, matchL, matchR;\n    HopcroftKarp(int nL=0, int nR=0):nL(nL), nR(nR), adj(nL), dist(nL), matchL(nL,-1), matchR(nR,-1){}\n    void reset(int nl, int nr){ nL=nl; nR=nr; adj.assign(nL, {}); matchL.assign(nL,-1); matchR.assign(nR,-1); dist.resize(nL); }\n    void addEdge(int u, int v){ adj[u].push_back(v); }\n    bool bfs(){\n        queue<int> q;\n        fill(dist.begin(), dist.end(), -1);\n        for(int u=0; u<nL; u++){\n            if(matchL[u]==-1){ dist[u]=0; q.push(u); }\n        }\n        bool found=false;\n        while(!q.empty()){\n            int u=q.front(); q.pop();\n            for(int v: adj[u]){\n                int w = matchR[v];\n                if(w>=0 && dist[w]<0){\n                    dist[w]=dist[u]+1;\n                    q.push(w);\n                }\n                if(w==-1) found=true;\n            }\n        }\n        return found;\n    }\n    bool dfs(int u){\n        for(int v: adj[u]){\n            int w = matchR[v];\n            if(w==-1 || (w>=0 && dist[w]==dist[u]+1 && dfs(w))){\n                matchL[u]=v; matchR[v]=u;\n                return true;\n            }\n        }\n        dist[u]=-1;\n        return false;\n    }\n    int maxMatching(){\n        int matching=0;\n        while(bfs()){\n            for(int u=0; u<nL; u++){\n                if(matchL[u]==-1 && dfs(u)) matching++;\n            }\n        }\n        return matching;\n    }\n};\n\nstatic inline void build_cells_from_hw(const vector<int>& h, const vector<int>& w, vector<Rect>& cells, vector<long long>& areas){\n    int R = (int)h.size();\n    int C = (int)w.size();\n    vector<int> hi(R+1,0), wj(C+1,0);\n    for(int i=0;i<R;i++) hi[i+1]=hi[i]+h[i];\n    for(int j=0;j<C;j++) wj[j+1]=wj[j]+w[j];\n    cells.clear(); areas.clear();\n    cells.reserve(R*C); areas.reserve(R*C);\n    for(int i=0;i<R;i++) for(int j=0;j<C;j++){\n        Rect r{hi[i], wj[j], hi[i+1], wj[j+1]};\n        cells.push_back(r);\n        areas.push_back(r.area());\n    }\n}\n\nstatic inline void uniform_partition(int W, int R, int C, vector<int>& h, vector<int>& w){\n    h.assign(R, W/R);\n    int remH = W - accumulate(h.begin(), h.end(), 0);\n    for(int i=0;i<remH;i++) h[i%R]++;\n    w.assign(C, W/C);\n    int remW = W - accumulate(w.begin(), w.end(), 0);\n    for(int j=0;j<remW;j++) w[j%C]++;\n}\n\nstruct Candidate {\n    vector<Rect> blocksAsc;\n    long long deficit;\n    int matched;\n};\n\nstatic inline Candidate evaluate_candidate(const vector<long long>& B, const vector<Rect>& cells, const vector<long long>& areas,\n                                           const vector<int>& matchL){\n    int N = (int)B.size();\n    int RC = (int)areas.size();\n    vector<char> used(RC, 0);\n    vector<Rect> blocks(N);\n    int matchedCount=0;\n    for(int u=0; u<N; u++){\n        int v = matchL[u];\n        if (v != -1){\n            blocks[u] = cells[v];\n            used[v]=1;\n            matchedCount++;\n        }\n    }\n    vector<int> idx(RC);\n    iota(idx.begin(), idx.end(), 0);\n    sort(idx.begin(), idx.end(), [&](int x,int y){\n        if (areas[x]!=areas[y]) return areas[x] > areas[y];\n        return x<y;\n    });\n    int ptr=0;\n    for(int u=0; u<N; u++){\n        if (matchL[u]==-1){\n            while(ptr<RC && used[idx[ptr]]) ptr++;\n            if (ptr<RC){\n                blocks[u] = cells[idx[ptr]];\n                used[idx[ptr]] = 1;\n                ptr++;\n            } else {\n                blocks[u] = Rect{0,0,0,0};\n            }\n        }\n    }\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int x,int y){\n        long long ax=1LL*(blocks[x].i1-blocks[x].i0)*(blocks[x].j1-blocks[x].j0);\n        long long ay=1LL*(blocks[y].i1-blocks[y].i0)*(blocks[y].j1-blocks[y].j0);\n        if (ax!=ay) return ax<ay;\n        return x<y;\n    });\n    vector<Rect> asc(N);\n    for(int r=0;r<N;r++) asc[r]=blocks[ord[r]];\n    long long deficit=0;\n    for(int r=0;r<N;r++){\n        long long need=B[r], have=1LL*(asc[r].i1-asc[r].i0)*(asc[r].j1-asc[r].j0);\n        if (have<need) deficit += (need-have);\n    }\n    return Candidate{asc, deficit, matchedCount};\n}\n\n// Constructive stripes (horizontal)\nstatic inline bool build_stripe_grouping(int W, const vector<long long>& B, vector<Rect>& outAsc){\n    int N = (int)B.size();\n    vector<long long> needs(B.rbegin(), B.rend()); // descending\n    struct Row { int h; vector<long long> items; };\n    vector<Row> rows;\n    int usedH=0;\n    while(!needs.empty()){\n        long long x = needs.front();\n        int h_min = (int)((x + W - 1) / W);\n        int h_guess = (int)floor(sqrt((double)max(1.0, (double)x)));\n        int remH = W - usedH;\n        if (remH <= 0) return false;\n        int h = max(h_min, min(remH, h_guess));\n        long long usedW=0;\n        vector<long long> pack;\n        for(size_t i=0;i<needs.size();){\n            long long need = needs[i];\n            long long wreq = (need + h - 1) / h;\n            if (usedW + wreq <= W){\n                pack.push_back(need);\n                usedW += wreq;\n                needs.erase(needs.begin()+i);\n            } else i++;\n        }\n        if (pack.empty()){\n            long long wreq = (x + h - 1) / h;\n            if (wreq > W){\n                int needh = (int)((x + W - 1) / W);\n                if (needh > remH) return false;\n                h = needh;\n                wreq = (x + h - 1) / h;\n                if (wreq > W) return false;\n            }\n            pack.push_back(x);\n            needs.erase(needs.begin());\n        }\n        rows.push_back(Row{h, pack});\n        usedH += h;\n        if (usedH > W) return false;\n    }\n    vector<Rect> rects;\n    rects.reserve(N);\n    int cur_i=0;\n    for(auto &row: rows){\n        int i0=cur_i, i1=i0+row.h;\n        int cur_j=0;\n        for(auto need: row.items){\n            int w = (int)((need + row.h - 1) / row.h);\n            int j0=cur_j, j1=min(W, cur_j + w);\n            rects.push_back(Rect{i0,j0,i1,j1});\n            cur_j=j1;\n        }\n        cur_i=i1;\n    }\n    if ((int)rects.size()!=N) return false;\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int x,int y){\n        long long ax=rects[x].area(), ay=rects[y].area();\n        if (ax!=ay) return ax<ay;\n        return x<y;\n    });\n    outAsc.resize(N);\n    for(int r=0;r<N;r++) outAsc[r]=rects[order[r]];\n    for(int r=0;r<N;r++) if (outAsc[r].area() < B[r]) return false;\n    return true;\n}\n\n// Constructive stripes (vertical)\nstatic inline bool build_stripe_grouping_vertical(int W, const vector<long long>& B, vector<Rect>& outAsc){\n    int N = (int)B.size();\n    vector<long long> needs(B.rbegin(), B.rend()); // descending\n    struct Col { int w; vector<long long> items; };\n    vector<Col> cols;\n    int usedW=0;\n    while(!needs.empty()){\n        long long x = needs.front();\n        int w_min = (int)((x + W - 1) / W);\n        int w_guess = (int)floor(sqrt((double)max(1.0, (double)x)));\n        int remW = W - usedW;\n        if (remW <= 0) return false;\n        int w = max(w_min, min(remW, w_guess));\n        long long usedH=0;\n        vector<long long> pack;\n        for(size_t i=0;i<needs.size();){\n            long long need = needs[i];\n            long long hreq = (need + w - 1) / w;\n            if (usedH + hreq <= W){\n                pack.push_back(need);\n                usedH += hreq;\n                needs.erase(needs.begin()+i);\n            } else i++;\n        }\n        if (pack.empty()){\n            long long hreq = (x + w - 1) / w;\n            if (hreq > W){\n                int needw = (int)((x + W - 1) / W);\n                if (needw > remW) return false;\n                w = needw;\n                hreq = (x + w - 1) / w;\n                if (hreq > W) return false;\n            }\n            pack.push_back(x);\n            needs.erase(needs.begin());\n        }\n        cols.push_back(Col{w, pack});\n        usedW += w;\n        if (usedW > W) return false;\n    }\n    vector<Rect> rects;\n    rects.reserve(N);\n    int cur_j=0;\n    for(auto &col: cols){\n        int j0=cur_j, j1=j0+col.w;\n        int cur_i=0;\n        for(auto need: col.items){\n            int h = (int)((need + col.w - 1) / col.w);\n            int i0=cur_i, i1=min(W, cur_i + h);\n            rects.push_back(Rect{i0,j0,i1,j1});\n            cur_i=i1;\n        }\n        cur_j=j1;\n    }\n    if ((int)rects.size()!=N) return false;\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int x,int y){\n        long long ax=rects[x].area(), ay=rects[y].area();\n        if (ax!=ay) return ax<ay;\n        return x<y;\n    });\n    outAsc.resize(N);\n    for(int r=0;r<N;r++) outAsc[r]=rects[order[r]];\n    for(int r=0;r<N;r++) if (outAsc[r].area() < B[r]) return false;\n    return true;\n}\n\n// Proportional grid initialization for a shape (R,C): returns h,w sums==W using row/col sums from B mapped row-major\nstatic inline void proportional_init_hw(int W, int R, int C, const vector<long long>& B, vector<int>& h, vector<int>& w){\n    int N = (int)B.size();\n    vector<long long> Sr(R,0), Sc(C,0);\n    for(int idx=0; idx<N; idx++){\n        int i = idx / C, j = idx % C;\n        if (i<R && j<C) { Sr[i] += B[idx]; Sc[j] += B[idx]; }\n    }\n    long long S = accumulate(Sr.begin(), Sr.end(), 0LL);\n    if (S==0){\n        uniform_partition(W,R,C,h,w);\n        return;\n    }\n    h.assign(R,1);\n    w.assign(C,1);\n    int sumh=R, sumw=C;\n    vector<pair<double,int>> hr, wc;\n    hr.reserve(R); wc.reserve(C);\n    for(int i=0;i<R;i++){\n        double x = (double)W * (double)Sr[i] / (double)S;\n        hr.emplace_back(x, i);\n    }\n    for(int j=0;j<C;j++){\n        double x = (double)W * (double)Sc[j] / (double)S;\n        wc.emplace_back(x, j);\n    }\n    // Grow rows to match target\n    while(sumh < W){\n        int best=-1; double bestGap=-1e18;\n        for(auto [x,i] : hr){\n            double gap = x - h[i];\n            if (gap > bestGap){ bestGap=gap; best=i; }\n        }\n        if (best==-1) break;\n        h[best]++; sumh++;\n    }\n    // Grow cols\n    while(sumw < W){\n        int best=-1; double bestGap=-1e18;\n        for(auto [x,j] : wc){\n            double gap = x - w[j];\n            if (gap > bestGap){ bestGap=gap; best=j; }\n        }\n        if (best==-1) break;\n        w[best]++; sumw++;\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto start = chrono::steady_clock::now();\n    auto elapsed_ms = [&](){\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-start).count();\n    };\n    const long long TIME_LIMIT_MS = 2850; // safety margin\n\n    int W,D,N;\n    if(!(cin>>W>>D>>N)) return 0;\n    vector<vector<int>> a(D, vector<int>(N));\n    for(int d=0; d<D; d++) for(int k=0; k<N; k++) cin>>a[d][k];\n\n    // Rank-wise maxima\n    vector<int> M(N,0);\n    for(int d=0; d<D; d++){\n        auto v=a[d];\n        sort(v.begin(), v.end());\n        for(int r=0;r<N;r++) M[r]=max(M[r], v[r]);\n    }\n    vector<long long> B(N);\n    for(int i=0;i<N;i++) B[i]=M[i];\n    sort(B.begin(), B.end());\n\n    Candidate best; best.deficit = LLONG_MAX; best.matched=-1;\n\n    // Fast constructive attempts\n    {\n        vector<Rect> asc;\n        if (build_stripe_grouping(W, B, asc)){\n            best.blocksAsc = asc; best.deficit = 0; best.matched = N;\n        }\n    }\n    if (best.deficit!=0){\n        vector<Rect> asc;\n        if (build_stripe_grouping_vertical(W, B, asc)){\n            best.blocksAsc = asc; best.deficit = 0; best.matched = N;\n        }\n    }\n    // Optional proportional grids if time allows and still not perfect\n    if (best.deficit!=0 && elapsed_ms() < TIME_LIMIT_MS/5){\n        vector<Rect> asc;\n        // non-transposed\n        int C = (int)ceil(sqrt((double)N));\n        int R = (N + C - 1)/C;\n        vector<int> h,w;\n        proportional_init_hw(W, R, C, B, h, w);\n        vector<Rect> cells; vector<long long> areas;\n        build_cells_from_hw(h,w,cells,areas);\n        vector<int> ord(cells.size());\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int x,int y){\n            if (areas[x]!=areas[y]) return areas[x] < areas[y];\n            return x<y;\n        });\n        bool ok=true; asc.resize(N);\n        for(int r=0;r<N;r++){ asc[r]=cells[ord[r]]; if (asc[r].area()<B[r]) ok=false; }\n        if (ok){ best.blocksAsc=asc; best.deficit=0; best.matched=N; }\n    }\n    if (best.deficit==0){\n        // Output now\n        for(int d=0; d<D; d++){\n            vector<int> ord(N);\n            iota(ord.begin(), ord.end(), 0);\n            sort(ord.begin(), ord.end(), [&](int x,int y){ return a[d][x] < a[d][y]; });\n            for(int k=0;k<N;k++){\n                Rect r = best.blocksAsc[ord[k]];\n                cout<<r.i0<<\" \"<<r.j0<<\" \"<<r.i1<<\" \"<<r.j1<<\"\\n\";\n            }\n        }\n        return 0;\n    }\n\n    // Matching search over shapes with bounded local search\n    vector<pair<int,int>> shapes;\n    int base = max(1, (int)round(sqrt((double)N)));\n    auto push_shape = [&](int R,int C){\n        if (R<1) R=1;\n        if (C<1) C=1;\n        if (1LL*R*C < N) return;\n        shapes.emplace_back(R,C);\n    };\n    for(int dr=-2; dr<=2; dr++){\n        int R = max(1, base+dr);\n        int C = (N + R - 1)/R;\n        push_shape(R,C);\n    }\n    for(int dc=-2; dc<=2; dc++){\n        int C = max(1, base+dc);\n        int R = (N + C - 1)/C;\n        push_shape(R,C);\n    }\n    push_shape(N,1);\n    push_shape(1,N);\n    sort(shapes.begin(), shapes.end());\n    shapes.erase(unique(shapes.begin(), shapes.end()), shapes.end());\n\n    auto build_candidate_from_hw = [&](const vector<int>& h, const vector<int>& w)->Candidate{\n        vector<Rect> cells; vector<long long> areas;\n        build_cells_from_hw(h, w, cells, areas);\n        int RC = (int)areas.size();\n        HopcroftKarp hk(N, RC);\n        for(int u=0; u<N; u++){\n            for(int v=0; v<RC; v++){\n                if (areas[v] >= B[u]) hk.addEdge(u, v);\n            }\n        }\n        hk.maxMatching();\n        return evaluate_candidate(B, cells, areas, hk.matchL);\n    };\n\n    for(auto [R,C] : shapes){\n        if (elapsed_ms() > TIME_LIMIT_MS) break;\n        vector<int> h,w;\n        // Proportional init for this shape to get better start than uniform\n        proportional_init_hw(W, R, C, B, h, w);\n\n        Candidate cand = build_candidate_from_hw(h, w);\n        if (cand.deficit < best.deficit || (cand.deficit==best.deficit && cand.matched > best.matched)){\n            best = cand;\n            if (best.deficit==0) break;\n        }\n\n        // Cheap quick growth for hardest ranks (a few iterations)\n        if (elapsed_ms() < TIME_LIMIT_MS*3/5){\n            int quickSteps = 20;\n            for(int qs=0; qs<quickSteps; qs++){\n                vector<Rect> cells2; vector<long long> areas2;\n                build_cells_from_hw(h, w, cells2, areas2);\n                long long need = B.back();\n                int RC2=(int)areas2.size(), R2=(int)h.size(), C2=(int)w.size();\n                int bestCell=-1; long long bestArea=-1;\n                for(int v=0; v<RC2; v++){ if (areas2[v] < need && areas2[v] > bestArea){ bestArea=areas2[v]; bestCell=v; } }\n                if (bestCell==-1) break;\n                int ri=bestCell/C2, cj=bestCell% C2; // note: C2 is w size\n                // grow row or col towards need by stealing from thinnest donor\n                int donorR=-1, donorC=-1;\n                for(int i=0;i<R2;i++){ if (i!=ri && (donorR==-1 || h[i]<h[donorR])) donorR=i; }\n                for(int j=0;j<C2;j++){ if (j!=cj && (donorC==-1 || w[j]<w[donorC])) donorC=j; }\n                bool moved=false;\n                if (donorR!=-1 && h[donorR]>1){ h[ri]++; h[donorR]--; moved=true; }\n                if (!moved && donorC!=-1 && w[donorC]>1){ w[cj]++; w[donorC]--; moved=true; }\n                if (!moved) break;\n                Candidate c2 = build_candidate_from_hw(h, w);\n                if (c2.deficit < best.deficit || (c2.deficit==best.deficit && c2.matched > best.matched)) best=c2;\n                if (best.deficit==0) break;\n            }\n            if (best.deficit==0) break;\n        }\n\n        // Beam search local adjustments: beam=2, steps depend on time\n        struct State { vector<int> h,w; Candidate cand; };\n        vector<State> beam;\n        beam.push_back(State{h,w,cand});\n        int STEPS = (int)min<long long>(140, max(60LL, (TIME_LIMIT_MS - elapsed_ms())/12));\n        int BEAM = 2;\n        for(int step=0; step<STEPS; step++){\n            if (elapsed_ms() > TIME_LIMIT_MS) break;\n            vector<State> next;\n            for(auto &st : beam){\n                long long maxNeed = B.back();\n                vector<Rect> cells2; vector<long long> areas2;\n                build_cells_from_hw(st.h, st.w, cells2, areas2);\n                int RC2 = (int)areas2.size();\n                int R2=(int)st.h.size(), C2=(int)st.w.size();\n                int bestCell=-1; long long bestArea=-1;\n                for(int v=0; v<RC2; v++){\n                    if (areas2[v] < maxNeed && areas2[v] > bestArea){\n                        bestArea=areas2[v]; bestCell=v;\n                    }\n                }\n                vector<pair<bool,pair<int,int>>> moves;\n                if (bestCell!=-1){\n                    int ri = bestCell / C2, cj = bestCell % C2;\n                    vector<int> rowOrd(R2), colOrd(C2);\n                    iota(rowOrd.begin(), rowOrd.end(), 0);\n                    iota(colOrd.begin(), colOrd.end(), 0);\n                    sort(rowOrd.begin(), rowOrd.end(), [&](int x,int y){ return st.h[x] < st.h[y]; });\n                    sort(colOrd.begin(), colOrd.end(), [&](int x,int y){ return st.w[x] < st.w[y]; });\n                    for(int k=0;k<min(R2,4);k++){ int b=rowOrd[k]; if (b!=ri && st.h[b]>1) moves.push_back({true,{ri,b}}); }\n                    for(int k=0;k<min(C2,4);k++){ int b=colOrd[k]; if (b!=cj && st.w[b]>1) moves.push_back({false,{cj,b}}); }\n                    // also from largest donors\n                    sort(rowOrd.begin(), rowOrd.end(), [&](int x,int y){ return st.h[x] > st.h[y]; });\n                    sort(colOrd.begin(), colOrd.end(), [&](int x,int y){ return st.w[x] > st.w[y]; });\n                    for(int k=0;k<min(R2,2);k++){ int b=rowOrd[k]; if (b!=ri && st.h[b]>1) moves.push_back({true,{ri,b}}); }\n                    for(int k=0;k<min(C2,2);k++){ int b=colOrd[k]; if (b!=cj && st.w[b]>1) moves.push_back({false,{cj,b}}); }\n                } else {\n                    int riMax = int(max_element(st.h.begin(), st.h.end()) - st.h.begin());\n                    int riMin = int(min_element(st.h.begin(), st.h.end()) - st.h.begin());\n                    if (st.h[riMin]>1) moves.push_back({true,{riMax,riMin}});\n                    int cjMax = int(max_element(st.w.begin(), st.w.end()) - st.w.begin());\n                    int cjMin = int(min_element(st.w.begin(), st.w.end()) - st.w.begin());\n                    if (st.w[cjMin]>1) moves.push_back({false,{cjMax,cjMin}});\n                }\n                for(auto mv : moves){\n                    auto h2 = st.h; auto w2 = st.w;\n                    if (mv.first){\n                        int a=mv.second.first, b=mv.second.second;\n                        if (h2[b]<=1) continue;\n                        h2[a]++; h2[b]--;\n                    } else {\n                        int a=mv.second.first, b=mv.second.second;\n                        if (w2[b]<=1) continue;\n                        w2[a]++; w2[b]--;\n                    }\n                    Candidate c2 = build_candidate_from_hw(h2, w2);\n                    next.push_back(State{h2,w2,c2});\n                }\n            }\n            if (next.empty()) break;\n            sort(next.begin(), next.end(), [&](const State& A, const State& Bc){\n                if (A.cand.deficit != Bc.cand.deficit) return A.cand.deficit < Bc.cand.deficit;\n                return A.cand.matched > Bc.cand.matched;\n            });\n            vector<State> beam2;\n            for(auto &st2 : next){\n                bool dup=false;\n                for(auto &p: beam2){ if (p.h==st2.h && p.w==st2.w){ dup=true; break; } }\n                if (!dup) beam2.push_back(st2);\n                if ((int)beam2.size()>=BEAM) break;\n            }\n            beam.swap(beam2);\n            for(auto &st2 : beam){\n                if (st2.cand.deficit < best.deficit || (st2.cand.deficit==best.deficit && st2.cand.matched > best.matched)){\n                    best = st2.cand;\n                }\n            }\n            if (best.deficit==0) break;\n        }\n        if (best.deficit==0) break;\n    }\n\n    vector<Rect> blocksAsc;\n    if (best.blocksAsc.empty()){\n        // fallback equal stripes\n        blocksAsc.resize(N);\n        int hh = max(1, W / max(1, N));\n        int cur=0;\n        int extra = W - hh*N;\n        for(int i=0;i<N;i++){\n            int h = hh + (i<extra?1:0);\n            blocksAsc[i] = Rect{cur, 0, cur+h, W};\n            cur += h;\n        }\n    } else {\n        blocksAsc = best.blocksAsc;\n    }\n\n    // Output per day: assign ascending demands to blocks\n    for(int d=0; d<D; d++){\n        vector<int> ord(N);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int x,int y){ return a[d][x] < a[d][y]; });\n        for(int k=0;k<N;k++){\n            Rect r = blocksAsc[ord[k]];\n            cout<<r.i0<<\" \"<<r.j0<<\" \"<<r.i1<<\" \"<<r.j1<<\"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const long long MOD = 998244353LL;\n\nstruct Entry {\n    int m, p, q;\n    long long gain;       // immediate objective delta\n    int overflow;         // count of cells where (v+s) wraps mod MOD\n    long long headroom;   // sum over 3x3 of max(0, (MOD-1) - new_v)\n    int safeCnt;          // count of cells with new_v <= (MOD-1)/2\n    uint64_t ver;         // version for lazy heap\n    bool operator<(const Entry& other) const {\n        if (gain != other.gain) return gain < other.gain; // max-heap by gain\n        if (overflow != other.overflow) return overflow > other.overflow; // prefer fewer wraps\n        if (headroom != other.headroom) return headroom < other.headroom; // prefer larger remaining headroom\n        if (safeCnt != other.safeCnt) return safeCnt < other.safeCnt; // prefer more safe cells\n        if (m != other.m) return m > other.m;\n        if (p != other.p) return p > other.p;\n        return q > other.q;\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    vector<vector<long long>> w(N, vector<long long>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            long long x; cin >> x;\n            w[i][j] = x % MOD;\n        }\n    vector<array<long long,9>> stamps(M);\n    for (int m = 0; m < M; ++m) {\n        int idx=0;\n        for (int i=0;i<3;++i) for (int j=0;j<3;++j) {\n            long long s; cin >> s;\n            stamps[m][idx++] = s % MOD;\n        }\n    }\n\n    const int Pmax = N-3; // top-left range 0..6 for N=9\n    const long long MID = (MOD - 1) / 2;\n\n    auto compute_entry = [&](int m, int p, int q)->Entry{\n        long long g = 0;\n        int of = 0;\n        long long hr = 0;\n        int sc = 0;\n        int idx=0;\n        for (int di=0; di<3; ++di) for (int dj=0; dj<3; ++dj,++idx){\n            int r=p+di, c=q+dj;\n            long long v = w[r][c];\n            long long s = stamps[m][idx];\n            long long nv = v + s;\n            if (nv >= MOD) { nv -= MOD; of++; }\n            g += (nv - v);\n            long long head = (MOD - 1) - nv;\n            if (head > 0) hr += head;\n            if (nv <= MID) sc++;\n        }\n        return Entry{m,p,q,g,of,hr,sc,0};\n    };\n\n    // Versions for lazy heap\n    vector<vector<vector<uint64_t>>> ver(M, vector<vector<uint64_t>>(Pmax+1, vector<uint64_t>(Pmax+1, 0)));\n\n    priority_queue<Entry> pq;\n    // initial push of all moves\n    for (int m=0; m<M; ++m) for (int p=0; p<=Pmax; ++p) for (int q=0; q<=Pmax; ++q){\n        Entry e = compute_entry(m,p,q);\n        e.ver = ver[m][p][q];\n        pq.push(e);\n    }\n\n    vector<tuple<int,int,int>> ops; ops.reserve(K);\n\n    auto refresh_region = [&](int pL, int pR, int qL, int qR){\n        pL = max(pL, 0); pR = min(pR, Pmax);\n        qL = max(qL, 0); qR = min(qR, Pmax);\n        for (int p = pL; p <= pR; ++p) {\n            for (int q = qL; q <= qR; ++q) {\n                for (int m=0; m<M; ++m) {\n                    Entry e = compute_entry(m,p,q);\n                    uint64_t &v = ver[m][p][q];\n                    v++;\n                    e.ver = v;\n                    pq.push(e);\n                }\n            }\n        }\n    };\n\n    auto apply_move = [&](int m, int p, int q){\n        int idx=0;\n        for (int di=0; di<3; ++di) for (int dj=0; dj<3; ++dj,++idx){\n            int r = p+di, c = q+dj;\n            long long s = stamps[m][idx];\n            long long nv = w[r][c] + s;\n            if (nv >= MOD) nv -= MOD;\n            w[r][c] = nv;\n        }\n    };\n\n    int used = 0;\n    while (used < K) {\n        Entry best;\n        bool found = false;\n        while (!pq.empty()) {\n            best = pq.top(); pq.pop();\n            if (best.ver != ver[best.m][best.p][best.q]) continue; // stale\n            found = true; break;\n        }\n        if (!found) break;\n\n        if (best.gain > 0) {\n            // normal positive-gain step\n            apply_move(best.m, best.p, best.q);\n            ops.emplace_back(best.m, best.p, best.q);\n            used++;\n            refresh_region(best.p-2, best.p+2, best.q-2, best.q+2);\n            continue;\n        }\n\n        // No positive-gain move at the top. Try a small number of zero-gain nudges.\n        int nudgeBudget = min(3, K - used);\n        bool nudged = false;\n        while (nudgeBudget > 0) {\n            // We already have one zero-gain candidate \"best\" (gain==0). Gather a few more zero-gain candidates to choose the best deterministic tie-break.\n            vector<Entry> zeros;\n            zeros.push_back(best);\n            // Pull up to 8 more zero-gain moves\n            const int Z = 9;\n            while ((int)zeros.size() < Z && !pq.empty()) {\n                Entry e = pq.top(); pq.pop();\n                if (e.ver != ver[e.m][e.p][e.q]) continue;\n                if (e.gain == 0) zeros.push_back(e);\n                else { pq.push(e); break; }\n            }\n            // Choose the best zero by our ordering (priority_queue ordering already applies).\n            Entry chosen = zeros[0];\n            for (size_t i = 1; i < zeros.size(); ++i) {\n                if (chosen < zeros[i]) chosen = zeros[i];\n            }\n            // Reinsert the unused zeros\n            for (auto &e : zeros) {\n                if (e.m == chosen.m && e.p == chosen.p && e.q == chosen.q && e.ver == chosen.ver) continue;\n                if (e.ver == ver[e.m][e.p][e.q]) pq.push(e);\n            }\n            // Apply the chosen zero-gain move\n            apply_move(chosen.m, chosen.p, chosen.q);\n            ops.emplace_back(chosen.m, chosen.p, chosen.q);\n            used++;\n            nudgeBudget--;\n            nudged = true;\n            refresh_region(chosen.p-2, chosen.p+2, chosen.q-2, chosen.q+2);\n\n            // After refreshing, see if a positive move appears at the top; if so, break nudge loop.\n            while (!pq.empty()) {\n                Entry peek = pq.top();\n                if (peek.ver != ver[peek.m][peek.p][peek.q]) { pq.pop(); continue; }\n                if (peek.gain > 0) { break; }\n                else { break; }\n            }\n            break; // perform at most one zero-gain nudge per iteration to keep behavior controlled\n        }\n        if (!nudged) break; // no zero-gain candidates or no budget; stop\n    }\n\n    cout << ops.size() << \"\\n\";\n    for (auto &op : ops) {\n        int m,p,q; tie(m,p,q) = op;\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Planner {\n    static const int N = 5;\n    vector<vector<int>> A;\n    vector<string> S;\n\n    int cr=0, cc=0;\n    bool holding=false;\n    int held_id=-1;\n\n    bool occ[N][N]; // occupancy for interior cols 1..3\n    unordered_map<int, pair<int,int>> loc; // id -> stored pos\n\n    int next_needed[N];\n    int idx_head[N];\n    int dispatched=0;\n\n    int dtgt = -1; // batching target row\n\n    Planner(const vector<vector<int>>& Ain): A(Ain) {\n        S.assign(N, \"\");\n        for (int i=1;i<N;i++) S[i].push_back('B'); // bomb small cranes\n        memset(occ, 0, sizeof(occ));\n        for (int i=0;i<N;i++){ next_needed[i]=N*i; idx_head[i]=0; }\n    }\n\n    void appendLarge(char ch){\n        S[0].push_back(ch);\n        for (int i=1;i<N;i++){\n            if ((int)S[i].size() < (int)S[0].size()) S[i].push_back('.');\n        }\n    }\n    void moveTo(int tr, int tc){\n        while (cr != tr) {\n            if (tr < cr) { cr--; appendLarge('U'); }\n            else { cr++; appendLarge('D'); }\n        }\n        while (cc != tc) {\n            if (tc < cc) { cc--; appendLarge('L'); }\n            else { cc++; appendLarge('R'); }\n        }\n    }\n    void pickAtCurrent(int cid){ held_id = cid; holding = true; appendLarge('P'); }\n    void dropAtCurrent(){ holding = false; appendLarge('Q'); }\n\n    // Find nearest free slot from arbitrary point\n    pair<int,int> nearestFreeAnywhereFrom(int sr, int sc){\n        int best=1e9; pair<int,int> ans{-1,-1};\n        for (int r=0;r<N;r++) for (int c=1;c<=3;c++) if (!occ[r][c]){\n            int d = abs(sr-r)+abs(sc-c);\n            if (d < best){ best=d; ans={r,c}; }\n        }\n        return ans;\n    }\n    // In dest row: choose free slot minimizing cost = dist from (psr,psc) to slot + dist slot -> gate(d,4)\n    pair<int,int> bestFreeInRowGateAware(int drow, int psr, int psc){\n        int best=1e9; pair<int,int> ans{-1,-1};\n        for (int c=1;c<=3;c++){\n            if (!occ[drow][c]){\n                int cost = abs(psr - drow) + abs(psc - c) + abs(drow - drow) + abs(c - (N-1)); // slot->gate\n                if (cost < best){ best=cost; ans={drow,c}; }\n            }\n        }\n        if (ans.first != -1) return ans;\n        return nearestFreeAnywhereFrom(psr, psc);\n    }\n    bool hasFreeInRow(int drow){ for (int c=1;c<=3;c++) if (!occ[drow][c]) return true; return false; }\n    pair<int,int> preferredSpilloverNearGate(int drow){\n        vector<int> rows;\n        if (drow-1 >= 0) rows.push_back(drow-1);\n        if (drow+1 < N) rows.push_back(drow+1);\n        int best=1e9; pair<int,int> ans{-1,-1};\n        for (int rr: rows) for (int c=1;c<=3;c++) if (!occ[rr][c]){\n            int d = abs(cr - rr) + abs(cc - c);\n            if (d < best){ best=d; ans={rr,c}; }\n        }\n        return ans;\n    }\n\n    // Flush next-needed for row d: storage or left head (closest)\n    bool flush_one_for_row(int d){\n        int need = next_needed[d];\n        if (need >= N*d + N) return false;\n        auto it = loc.find(need);\n        if (it != loc.end()){\n            auto [sr, sc] = it->second;\n            moveTo(sr, sc);\n            pickAtCurrent(need);\n            occ[sr][sc] = false;\n            loc.erase(need);\n            moveTo(d, N-1);\n            dropAtCurrent();\n            next_needed[d]++; dispatched++; dtgt = d;\n            return true;\n        }\n        int best_r=-1, bestCost=1e9;\n        for (int r=0;r<N;r++){\n            if (idx_head[r] < N && A[r][idx_head[r]] == need){\n                int cost = abs(cr - r) + abs(cc - 0) + abs(r - d) + abs(0 - (N-1));\n                if (cost < bestCost){ bestCost=cost; best_r=r; }\n            }\n        }\n        if (best_r != -1){\n            moveTo(best_r, 0);\n            pickAtCurrent(need);\n            idx_head[best_r]++;\n            moveTo(d, N-1);\n            dropAtCurrent();\n            next_needed[d]++; dispatched++; dtgt = d;\n            return true;\n        }\n        return false;\n    }\n\n    // Global best flush candidate across all rows\n    bool flush_one(){\n        // prioritize dtgt for locality\n        if (dtgt != -1 && flush_one_for_row(dtgt)) return true;\n        int bestD=-1, bestCost=1e9, mode=0; // 1=storage, 2=left\n        pair<int,int> spos; int sid=-1;\n        // storage first\n        for (int d=0; d<N; d++){\n            int need = next_needed[d];\n            if (need >= N*d + N) continue;\n            auto it = loc.find(need);\n            if (it != loc.end()){\n                int cost = abs(cr - it->second.first) + abs(cc - it->second.second) + abs(it->second.first - d) + abs(it->second.second - (N-1));\n                if (cost < bestCost){ bestCost=cost; bestD=d; mode=1; spos=it->second; sid=need; }\n            }\n        }\n        // left heads next\n        for (int d=0; d<N; d++){\n            int need = next_needed[d];\n            if (need >= N*d + N) continue;\n            for (int r=0;r<N;r++){\n                if (idx_head[r] < N && A[r][idx_head[r]] == need){\n                    int cost = abs(cr - r) + abs(cc - 0) + abs(r - d) + abs(0 - (N-1));\n                    if (cost < bestCost){ bestCost=cost; bestD=d; mode=2; spos={r,0}; sid=need; }\n                }\n            }\n        }\n        if (bestD == -1) return false;\n        if (mode == 1){\n            moveTo(spos.first, spos.second);\n            pickAtCurrent(sid);\n            occ[spos.first][spos.second]=false;\n            loc.erase(sid);\n            moveTo(bestD, N-1);\n            dropAtCurrent();\n            next_needed[bestD]++; dispatched++; dtgt = bestD;\n            return true;\n        } else {\n            moveTo(spos.first, spos.second);\n            pickAtCurrent(sid);\n            idx_head[spos.first]++;\n            moveTo(bestD, N-1);\n            dropAtCurrent();\n            next_needed[bestD]++; dispatched++; dtgt = bestD;\n            return true;\n        }\n    }\n\n    // At gate d: chain dispatch and conservative pre-staging; then optionally dispatch a nearby other row if very cheap\n    void flush_chain_at_row(int d){\n        dtgt = d;\n        while (flush_one_for_row(d)) {}\n        // Try dispatch a very near other-row next-needed to exploit locality\n        int bestD=-1, bestCost=1e9, mode=0; pair<int,int> spos; int sid=-1;\n        for (int d2=0; d2<N; d2++){\n            if (d2==d) continue;\n            int need = next_needed[d2];\n            if (need >= N*d2 + N) continue;\n            auto it = loc.find(need);\n            if (it != loc.end()){\n                int cost = abs(cr - it->second.first) + abs(cc - it->second.second) + abs(it->second.first - d2) + abs(it->second.second - (N-1));\n                if (cost < bestCost){ bestCost=cost; bestD=d2; mode=1; spos=it->second; sid=need; }\n            } else {\n                for (int r=0;r<N;r++){\n                    if (idx_head[r] < N && A[r][idx_head[r]] == need){\n                        int cost = abs(cr - r) + abs(cc - 0) + abs(r - d2) + abs(0 - (N-1));\n                        if (cost < bestCost){ bestCost=cost; bestD=d2; mode=2; spos={r,0}; sid=need; }\n                    }\n                }\n            }\n        }\n        if (bestD != -1 && bestCost <= 6){\n            if (mode == 1){\n                moveTo(spos.first, spos.second);\n                pickAtCurrent(sid);\n                occ[spos.first][spos.second]=false;\n                loc.erase(sid);\n            } else {\n                moveTo(spos.first, spos.second);\n                pickAtCurrent(sid);\n                idx_head[spos.first]++;\n            }\n            moveTo(bestD, N-1);\n            dropAtCurrent();\n            next_needed[bestD]++; dispatched++; dtgt = bestD;\n            while (flush_one_for_row(bestD)) {}\n            return;\n        }\n\n        // Pre-stage a few to row d\n        int remaining = N*(d+1) - next_needed[d];\n        if (remaining <= 0) return;\n        int stored_for_d = 0;\n        for (auto &kv: loc) if (kv.first / N == d) stored_for_d++;\n        int K = min(3, max(0, remaining - stored_for_d)); // small cap\n        int pulled = 0;\n        while (pulled < K){\n            bool rowSpace = hasFreeInRow(d);\n            pair<int,int> placePos{-1,-1};\n            if (!rowSpace){\n                // conservative spillover: only if adjacent slot is very close\n                auto sp = preferredSpilloverNearGate(d);\n                if (sp.first != -1){\n                    int dist = abs(cr - sp.first) + abs(cc - sp.second);\n                    if (dist <= 2) placePos = sp;\n                }\n                if (placePos.first == -1) break;\n            }\n            int best_r=-1, best_cost=1e9, best_b=-1;\n            for (int r=0;r<N;r++){\n                if (idx_head[r] >= N) continue;\n                int b = A[r][idx_head[r]];\n                if (b / N != d) continue;\n                if (b == next_needed[d]) continue;\n                // choose slot minimizing pick->slot + slot->gate\n                pair<int,int> tentative;\n                if (rowSpace){\n                    int bestc=-1, bestcCost=1e9;\n                    for (int c=1;c<=3;c++) if (!occ[d][c]){\n                        int cost = abs(r - d) + abs(0 - c) + abs(d - d) + abs(c - (N-1));\n                        if (cost < bestcCost){ bestcCost=cost; bestc=c; }\n                    }\n                    tentative = {d, (bestc==-1?2:bestc)};\n                } else {\n                    tentative = placePos;\n                }\n                int cost = abs(cr - r) + abs(cc - 0) + abs(r - tentative.first) + abs(0 - tentative.second);\n                if (cost < best_cost){ best_cost=cost; best_r=r; best_b=b; }\n            }\n            if (best_r == -1) break;\n            moveTo(best_r, 0);\n            pickAtCurrent(best_b);\n            idx_head[best_r]++;\n            if (rowSpace) placePos = bestFreeInRowGateAware(d, cr, cc);\n            if (placePos.first == -1) break;\n            moveTo(placePos.first, placePos.second);\n            dropAtCurrent();\n            occ[placePos.first][placePos.second]=true; loc[best_b]=placePos;\n            pulled++;\n            while (flush_one_for_row(d)) {}\n        }\n    }\n\n    void ensureLargeNotBlockingStart(){\n        if (cr==0 && cc==0){\n            cc=1; appendLarge('R');\n        }\n    }\n\n    // Source selection with band locality:\n    // 1) immediate need (closest)\n    // 2) closest head destined to dtgt\n    // 3) minimal cost: to pick + to best storage in dest row from (r,0), tie-breaker by vertical proximity and band membership\n    int choose_source_row(){\n        int best_r=-1, bestDist=1e9;\n        // immediate\n        for (int r=0;r<N;r++){\n            if (idx_head[r] >= N) continue;\n            int b = A[r][idx_head[r]];\n            if (next_needed[b / N] == b){\n                int dist = abs(cr - r) + abs(cc - 0);\n                if (dist < bestDist){ bestDist=dist; best_r=r; }\n            }\n        }\n        if (best_r != -1) return best_r;\n        // prefer dtgt\n        if (dtgt != -1){\n            best_r=-1; bestDist=1e9;\n            for (int r=0;r<N;r++){\n                if (idx_head[r] >= N) continue;\n                int b = A[r][idx_head[r]];\n                if (b / N != dtgt) continue;\n                int dist = abs(cr - r) + abs(cc - 0);\n                if (dist < bestDist){ bestDist=dist; best_r=r; }\n            }\n            if (best_r != -1) return best_r;\n        }\n        // general with tie-breaker and band bias\n        int best=-1; int bestCost=1e9; int bestRowTie=1e9; int bestBand=-1;\n        for (int r=0;r<N;r++){\n            if (idx_head[r] >= N) continue;\n            int b = A[r][idx_head[r]];\n            int dest = b / N;\n            int pick = abs(cr - r) + abs(cc - 0);\n            // placement cost from (r,0) to best free in dest row\n            int place = 1e9;\n            for (int c=1;c<=3;c++) if (!occ[dest][c]){\n                place = min(place, abs(r - dest) + abs(0 - c));\n            }\n            if (place == 1e9){\n                for (int rr=0; rr<N; rr++) for (int cc2=1; cc2<=3; cc2++) if (!occ[rr][cc2]){\n                    place = min(place, abs(r - rr) + abs(0 - cc2));\n                }\n            }\n            int total = pick + place;\n            int rowTie = abs(cr - r);\n            int inBand = (rowTie <= 2) ? 1 : 0;\n            if (total < bestCost ||\n                (total == bestCost && (inBand > bestBand || (inBand == bestBand && rowTie < bestRowTie)))){\n                bestCost=total; best=r; bestRowTie=rowTie; bestBand=inBand;\n            }\n        }\n        return best;\n    }\n\n    // Initial pre-stage: one pass over all rows\n    void initial_prestage(){\n        ensureLargeNotBlockingStart();\n        for (int r=0;r<N;r++){\n            if (idx_head[r] >= N) continue;\n            int b = A[r][idx_head[r]];\n            int d = b / N;\n            if (next_needed[d] == b){\n                // If immediate and cheap, dispatch now\n                int cost = abs(cr - r) + abs(cc - 0) + abs(r - d) + abs(0 - (N-1));\n                if (cost <= 6){\n                    moveTo(r, 0); pickAtCurrent(b); idx_head[r]++;\n                    moveTo(d, N-1); dropAtCurrent();\n                    next_needed[d]++; dispatched++; dtgt = d;\n                    while (flush_one_for_row(d)) {}\n                    continue;\n                } else {\n                    continue;\n                }\n            }\n            // ensure some space\n            if (!hasFreeInRow(d)){\n                if (!flush_one()) {\n                    auto any = nearestFreeAnywhereFrom(cr, cc);\n                    if (any.first == -1) continue;\n                }\n            }\n            moveTo(r, 0);\n            pickAtCurrent(b);\n            idx_head[r]++;\n            auto pos = bestFreeInRowGateAware(d, cr, cc);\n            if (pos.first == -1) pos = nearestFreeAnywhereFrom(cr, cc);\n            if (pos.first != -1){\n                moveTo(pos.first, pos.second);\n                dropAtCurrent();\n                occ[pos.first][pos.second]=true; loc[b]=pos;\n            } else {\n                appendLarge('.');\n            }\n        }\n    }\n\n    void run(){\n        ensureLargeNotBlockingStart();\n        initial_prestage();\n\n        int maxTurns = 9500;\n\n        while (dispatched < N*N && (int)S[0].size() < maxTurns){\n            // Resolve holding\n            if (holding){\n                int d = held_id / N;\n                if (next_needed[d] == held_id){\n                    moveTo(d, N-1);\n                    dropAtCurrent();\n                    next_needed[d]++; dispatched++;\n                    flush_chain_at_row(d);\n                    continue;\n                } else {\n                    auto pos = bestFreeInRowGateAware(d, cr, cc);\n                    if (pos.first == -1){\n                        if (flush_one()) continue;\n                        pos = nearestFreeAnywhereFrom(cr, cc);\n                    }\n                    if (pos.first != -1){\n                        moveTo(pos.first, pos.second);\n                        dropAtCurrent();\n                        occ[pos.first][pos.second]=true; loc[held_id]=pos;\n                    } else {\n                        appendLarge('.');\n                    }\n                    continue;\n                }\n            }\n\n            // Try to flush globally (best candidate)\n            if (flush_one()) continue;\n\n            // Choose next source\n            int r = choose_source_row();\n            if (r == -1){ appendLarge('.'); continue; }\n\n            int b = A[r][idx_head[r]];\n            int d = b / N;\n            bool immediate = (next_needed[d] == b);\n\n            // Ensure space for non-immediate\n            if (!immediate){\n                if (!hasFreeInRow(d)){\n                    if (flush_one()) continue;\n                    auto pos = nearestFreeAnywhereFrom(cr, cc);\n                    if (pos.first == -1){ appendLarge('.'); continue; }\n                }\n            }\n\n            moveTo(r, 0);\n            pickAtCurrent(b);\n            idx_head[r]++;\n            if (cc==0){ cc=1; appendLarge('R'); }\n\n            if (immediate){\n                moveTo(d, N-1);\n                dropAtCurrent();\n                next_needed[d]++; dispatched++;\n                flush_chain_at_row(d);\n            } else {\n                auto pos = bestFreeInRowGateAware(d, cr, cc);\n                if (pos.first == -1) pos = nearestFreeAnywhereFrom(cr, cc);\n                if (pos.first != -1){\n                    moveTo(pos.first, pos.second);\n                    dropAtCurrent();\n                    occ[pos.first][pos.second]=true; loc[b]=pos;\n                } else {\n                    appendLarge('.');\n                }\n            }\n        }\n\n        size_t L = S[0].size();\n        for (int i=1;i<N;i++) while (S[i].size() < L) S[i].push_back('.');\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i=0;i<N;i++) for (int j=0;j<N;j++) cin >> A[i][j];\n    Planner planner(A);\n    planner.run();\n    for (int i=0;i<N;i++) cout << planner.S[i] << \"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Plan {\n    vector<string> ops;\n    long long cost = (long long)4e18;\n};\n\nstatic inline void add_load(long long d, vector<string>& ops, long long& cost, long long& load) {\n    if (d <= 0) return;\n    ops.emplace_back(\"+\" + to_string(d));\n    cost += d;\n    load += d;\n}\nstatic inline void sub_load(long long d, vector<string>& ops, long long& cost, long long& load) {\n    if (d <= 0) return;\n    ops.emplace_back(\"-\" + to_string(d));\n    cost += d;\n    load -= d;\n}\n\nstatic inline void move_manhattan(pair<int,int> from, pair<int,int> to, vector<string>& ops, long long& cost, long long load) {\n    int r = from.first, c = from.second;\n    while (r < to.first) { ops.emplace_back(\"D\"); cost += 100 + load; ++r; }\n    while (r > to.first) { ops.emplace_back(\"U\"); cost += 100 + load; --r; }\n    while (c < to.second) { ops.emplace_back(\"R\"); cost += 100 + load; ++c; }\n    while (c > to.second) { ops.emplace_back(\"L\"); cost += 100 + load; --c; }\n}\n\nstatic inline void append_adjacent_move(pair<int,int> from, pair<int,int> to, vector<string>& ops, long long& cost, long long load) {\n    int dr = to.first - from.first;\n    int dc = to.second - from.second;\n    if (dr == 1 && dc == 0) { ops.emplace_back(\"D\"); cost += 100 + load; }\n    else if (dr == -1 && dc == 0) { ops.emplace_back(\"U\"); cost += 100 + load; }\n    else if (dr == 0 && dc == 1) { ops.emplace_back(\"R\"); cost += 100 + load; }\n    else if (dr == 0 && dc == -1) { ops.emplace_back(\"L\"); cost += 100 + load; }\n    else {\n        move_manhattan(from, to, ops, cost, load);\n    }\n}\n\nvector<pair<int,int>> build_snake_rows(int N, bool reverse_start=false) {\n    vector<pair<int,int>> ord;\n    ord.reserve(N*N);\n    if (!reverse_start) {\n        for (int i = 0; i < N; ++i) {\n            if (i % 2 == 0) for (int j = 0; j < N; ++j) ord.emplace_back(i,j);\n            else for (int j = N-1; j >= 0; --j) ord.emplace_back(i,j);\n        }\n    } else {\n        for (int i = N-1; i >= 0; --i) {\n            if ((N-1 - i) % 2 == 0) for (int j = N-1; j >= 0; --j) ord.emplace_back(i,j);\n            else for (int j = 0; j < N; ++j) ord.emplace_back(i,j);\n        }\n    }\n    return ord;\n}\nvector<pair<int,int>> build_snake_cols(int N, bool reverse_start=false) {\n    vector<pair<int,int>> ord;\n    ord.reserve(N*N);\n    if (!reverse_start) {\n        for (int j = 0; j < N; ++j) {\n            if (j % 2 == 0) for (int i = 0; i < N; ++i) ord.emplace_back(i,j);\n            else for (int i = N-1; i >= 0; --i) ord.emplace_back(i,j);\n        }\n    } else {\n        for (int j = N-1; j >= 0; --j) {\n            if ((N-1 - j) % 2 == 0) for (int i = N-1; i >= 0; --i) ord.emplace_back(i,j);\n            else for (int i = 0; i < N; ++i) ord.emplace_back(i,j);\n        }\n    }\n    return ord;\n}\n\n// Hilbert helpers\nvoid rot(int n, int &x, int &y, int rx, int ry) {\n    if (ry == 0) {\n        if (rx == 1) {\n            x = n-1 - x;\n            y = n-1 - y;\n        }\n        int t = x; x = y; y = t;\n    }\n}\npair<int,int> d2xy(int n, int d) {\n    int x = 0, y = 0;\n    int t = d;\n    for (int s = 1; s < n; s <<= 1) {\n        int rx = 1 & (t >> 1);\n        int ry = 1 & (t ^ rx);\n        rot(s, x, y, rx, ry);\n        x += s * rx;\n        y += s * ry;\n        t >>= 2;\n    }\n    return {x, y};\n}\n\nvector<pair<int,int>> build_hilbert_base(int N) {\n    int n = 1;\n    while (n < N) n <<= 1;\n    vector<pair<int,int>> pts;\n    pts.reserve(N*N);\n    for (int d = 0; d < n*n; ++d) {\n        auto p = d2xy(n, d); // (x,y)\n        if (p.first < N && p.second < N) {\n            pts.emplace_back(p.second, p.first); // map to (r,c) = (y,x)\n            if ((int)pts.size() == N*N) break;\n        }\n    }\n    return pts;\n}\n\nvector<pair<int,int>> transform_points_rc(const vector<pair<int,int>>& pts, int N, int rotk, bool reflect) {\n    // rotate around center of NxN and optional mirror horizontally\n    vector<pair<int,int>> out; out.reserve(pts.size());\n    for (auto p : pts) {\n        int r = p.first, c = p.second;\n        if (reflect) c = N-1 - c;\n        for (int k = 0; k < rotk; ++k) {\n            int nr = c;\n            int nc = N-1 - r;\n            r = nr; c = nc;\n        }\n        out.emplace_back(r,c);\n    }\n    return out;\n}\n\n// Morton/Z-order traversal on NxN where N is arbitrary\nvoid morton_rec(int r0, int c0, int h, int w, vector<pair<int,int>>& out) {\n    if (h <= 0 || w <= 0) return;\n    if (h == 1 && w == 1) {\n        out.emplace_back(r0, c0);\n        return;\n    }\n    int h1 = (h+1)/2, h2 = h - h1;\n    int w1 = (w+1)/2, w2 = w - w1;\n    // Quadrants in Z-order: TL, TR, BL, BR\n    morton_rec(r0, c0, h1, w1, out);\n    morton_rec(r0, c0 + w1, h1, w2, out);\n    morton_rec(r0 + h1, c0, h2, w1, out);\n    morton_rec(r0 + h1, c0 + w1, h2, w2, out);\n}\nvector<pair<int,int>> build_morton(int N) {\n    vector<pair<int,int>> out;\n    out.reserve(N*N);\n    morton_rec(0,0,N,N,out);\n    return out;\n}\n\nvector<pair<int,int>> build_spiral(int N, int sr, int sc, bool cw=true) {\n    // spiral from starting corner (sr,sc) where each is 0 or N-1\n    // cw: clockwise\n    int top = 0, left = 0, bottom = N-1, right = N-1;\n    vector<pair<int,int>> ord; ord.reserve(N*N);\n    int phase = 0;\n    // Determine initial direction based on start corner and cw\n    // We'll generate layers and order sides accordingly to start at given corner\n    // Easier: generate a full spiral from top-left clockwise, then transform by rotations/reflections\n    // But we'll implement a straightforward generator for the given start.\n    // To keep it simple, generate base from (0,0) CW, then rotate/reflect to match (sr,sc) and cw.\n    // Here we implement base and then transform outside, for simplicity we only build base here.\n    // We'll return base spiral (0,0) clockwise; callers will transform via transform_points_rc.\n    while (top <= bottom && left <= right) {\n        for (int j = left; j <= right; ++j) ord.emplace_back(top, j);\n        for (int i = top+1; i <= bottom; ++i) ord.emplace_back(i, right);\n        if (top < bottom) {\n            for (int j = right-1; j >= left; --j) ord.emplace_back(bottom, j);\n        }\n        if (left < right) {\n            for (int i = bottom-1; i > top; --i) ord.emplace_back(i, left);\n        }\n        ++top; ++left; --bottom; --right;\n    }\n    // ord is base; transformation will be done by transform_points_rc\n    return ord;\n}\n\nvector<pair<int,int>> build_block_snake(int N, int BS) {\n    // Traverse tiles in snake order, inside each tile snake order\n    vector<pair<int,int>> ord; ord.reserve(N*N);\n    int TR = (N + BS - 1)/BS;\n    int TC = (N + BS - 1)/BS;\n    for (int tr = 0; tr < TR; ++tr) {\n        if (tr % 2 == 0) {\n            for (int tc = 0; tc < TC; ++tc) {\n                int r0 = tr*BS, c0 = tc*BS;\n                int r1 = min(N, r0 + BS);\n                int c1 = min(N, c0 + BS);\n                for (int r = r0; r < r1; ++r) {\n                    if ((r - r0) % 2 == 0) {\n                        for (int c = c0; c < c1; ++c) ord.emplace_back(r,c);\n                    } else {\n                        for (int c = c1-1; c >= c0; --c) ord.emplace_back(r,c);\n                    }\n                }\n            }\n        } else {\n            for (int tc = TC-1; tc >= 0; --tc) {\n                int r0 = tr*BS, c0 = tc*BS;\n                int r1 = min(N, r0 + BS);\n                int c1 = min(N, c0 + BS);\n                for (int r = r0; r < r1; ++r) {\n                    if ((r - r0) % 2 == 0) {\n                        for (int c = c0; c < c1; ++c) ord.emplace_back(r,c);\n                    } else {\n                        for (int c = c1-1; c >= c0; --c) ord.emplace_back(r,c);\n                    }\n                }\n            }\n        }\n    }\n    return ord;\n}\n\nbool is_adjacent_path(const vector<pair<int,int>>& ord) {\n    int SZ = (int)ord.size();\n    for (int i = 0; i + 1 < SZ; ++i) {\n        int dr = abs(ord[i+1].first - ord[i].first);\n        int dc = abs(ord[i+1].second - ord[i].second);\n        if (dr + dc != 1) return false;\n    }\n    return true;\n}\n\nPlan build_plan(int N, const vector<vector<long long>>& h0, const vector<pair<int,int>>& order) {\n    vector<vector<long long>> h = h0;\n    vector<string> ops;\n    ops.reserve(12000);\n    long long cost = 0;\n    long long load = 0;\n\n    pair<int,int> cur = {0,0};\n    if (cur != order[0]) {\n        move_manhattan(cur, order[0], ops, cost, load);\n        cur = order[0];\n    }\n    int SZ = (int)order.size();\n    for (int idx = 0; idx + 1 < SZ; ++idx) {\n        auto p = order[idx];\n        auto q = order[idx+1];\n        if (cur != p) {\n            move_manhattan(cur, p, ops, cost, load);\n            cur = p;\n        }\n        long long x = h[p.first][p.second];\n        if (x >= 0) {\n            if (x > 0) add_load(x, ops, cost, load);\n            append_adjacent_move(p, q, ops, cost, load);\n            cur = q;\n            if (x > 0) sub_load(x, ops, cost, load);\n            h[q.first][q.second] += x;\n            h[p.first][p.second] = 0;\n        } else {\n            long long d = -x;\n            append_adjacent_move(p, q, ops, cost, load); // move empty to q\n            cur = q;\n            add_load(d, ops, cost, load);               // load at q\n            append_adjacent_move(q, p, ops, cost, load); // move back with load\n            cur = p;\n            sub_load(d, ops, cost, load);               // unload at p\n            h[p.first][p.second] = 0;\n            h[q.first][q.second] -= d;\n            append_adjacent_move(p, q, ops, cost, load); // move to q to continue\n            cur = q;\n        }\n    }\n    Plan res;\n    res.ops = move(ops);\n    res.cost = cost;\n    return res;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<vector<long long>> h(N, vector<long long>(N));\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            cin >> h[i][j];\n\n    vector<vector<pair<int,int>>> candidates;\n\n    // Row and column snakes\n    candidates.push_back(build_snake_rows(N, false));\n    candidates.push_back(build_snake_rows(N, true));\n    candidates.push_back(build_snake_cols(N, false));\n    candidates.push_back(build_snake_cols(N, true));\n\n    // Hilbert base (r,c)\n    auto hil_base = build_hilbert_base(N);\n    for (int rotk = 0; rotk < 4; ++rotk) {\n        for (int refl = 0; refl < 2; ++refl) {\n            auto ord = transform_points_rc(hil_base, N, rotk, refl);\n            if (is_adjacent_path(ord)) {\n                candidates.push_back(ord);\n                auto rord = ord; reverse(rord.begin(), rord.end());\n                candidates.push_back(rord);\n            }\n        }\n    }\n\n    // Morton/Z-order and variants via rotation/reflection\n    auto mort = build_morton(N);\n    for (int rotk = 0; rotk < 4; ++rotk) {\n        for (int refl = 0; refl < 2; ++refl) {\n            auto ord = transform_points_rc(mort, N, rotk, refl);\n            // Morton order is not strictly adjacent; skip non-adjacent to avoid long manhattan jumps\n            if (is_adjacent_path(ord)) {\n                candidates.push_back(ord);\n                auto rord = ord; reverse(rord.begin(), rord.end());\n                candidates.push_back(rord);\n            }\n        }\n    }\n\n    // Block snakes with different block sizes\n    for (int bs : {3,4,5}) {\n        auto b = build_block_snake(N, bs);\n        if (is_adjacent_path(b)) {\n            candidates.push_back(b);\n            auto rb = b; reverse(rb.begin(), rb.end());\n            candidates.push_back(rb);\n        }\n        // also rotated/reflected\n        for (int rotk = 1; rotk < 4; ++rotk) {\n            auto ord = transform_points_rc(b, N, rotk, false);\n            if (is_adjacent_path(ord)) {\n                candidates.push_back(ord);\n                auto rord = ord; reverse(rord.begin(), rord.end());\n                candidates.push_back(rord);\n            }\n        }\n    }\n\n    // Spiral from TL CW; then rotate/reflect to cover 8 variants and reverses\n    auto spiral_base = build_spiral(N, 0, 0, true);\n    for (int rotk = 0; rotk < 4; ++rotk) {\n        for (int refl = 0; refl < 2; ++refl) {\n            auto ord = transform_points_rc(spiral_base, N, rotk, refl);\n            if (is_adjacent_path(ord)) {\n                candidates.push_back(ord);\n                auto rord = ord; reverse(rord.begin(), rord.end());\n                candidates.push_back(rord);\n            }\n        }\n    }\n\n    // Deduplicate\n    sort(candidates.begin(), candidates.end(), [](const auto& a, const auto& b){\n        if (a.size() != b.size()) return a.size() < b.size();\n        return a < b;\n    });\n    candidates.erase(unique(candidates.begin(), candidates.end()), candidates.end());\n\n    Plan best;\n    for (const auto& ord : candidates) {\n        Plan p = build_plan(N, h, ord);\n        if (p.cost < best.cost) best = move(p);\n    }\n\n    for (const auto& s : best.ops) {\n        cout << s << '\\n';\n    }\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Seed {\n    int id;\n    array<int,15> x{};\n    int V=0;\n    double baseScore=0;\n    int maxComp=0;\n    int top1Count=0; // count of dimensions equal to current per-dim max\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,T;\n    if(!(cin>>N>>M>>T)) return 0;\n    const int S = 2*N*(N-1); // 60\n    vector<Seed> seeds(S);\n    for(int i=0;i<S;i++){\n        seeds[i].id = i;\n        int sum=0, mx=0;\n        for(int l=0;l<M;l++){\n            int v; cin>>v;\n            seeds[i].x[l]=v;\n            sum+=v; mx=max(mx, v);\n        }\n        seeds[i].V=sum;\n        seeds[i].baseScore=sum;\n        seeds[i].maxComp=mx;\n        seeds[i].top1Count=0;\n    }\n\n    // Grid\n    const int H=N, W=N, P=H*W;\n    auto pid=[&](int r,int c){ return r*W+c; };\n    vector<pair<int,int>> pos_of(P);\n    vector<vector<int>> adj(P);\n    for(int r=0;r<H;r++){\n        for(int c=0;c<W;c++){\n            int u=pid(r,c);\n            pos_of[u]={r,c};\n            if(r>0) adj[u].push_back(pid(r-1,c));\n            if(r+1<H) adj[u].push_back(pid(r+1,c));\n            if(c>0) adj[u].push_back(pid(r,c-1));\n            if(c+1<W) adj[u].push_back(pid(r,c+1));\n        }\n    }\n    auto degree=[&](int u){ return (int)adj[u].size(); };\n\n    // Four initial cell orders: two checkerboard variants, serpentine, and central spiral\n    vector<int> order1(P), order2(P), order3(P), order4(P);\n    iota(order1.begin(), order1.end(), 0);\n    stable_sort(order1.begin(), order1.end(), [&](int a,int b){\n        int da=degree(a), db=degree(b);\n        if(da!=db) return da>db;\n        auto [ra,ca]=pos_of[a]; auto [rb,cb]=pos_of[b];\n        int caColor=(ra+ca)&1, cbColor=(rb+cb)&1;\n        if(caColor!=cbColor) return caColor<cbColor;\n        if(ra!=rb) return ra<rb;\n        return ca<cb;\n    });\n    iota(order2.begin(), order2.end(), 0);\n    stable_sort(order2.begin(), order2.end(), [&](int a,int b){\n        int da=degree(a), db=degree(b);\n        if(da!=db) return da>db;\n        auto [ra,ca]=pos_of[a]; auto [rb,cb]=pos_of[b];\n        int caColor=(ra+ca)&1, cbColor=(rb+cb)&1;\n        if(caColor!=cbColor) return caColor>cbColor;\n        if(ra!=rb) return ra<rb;\n        return ca<cb;\n    });\n    // serpentine\n    {\n        int idx=0;\n        for(int r=0;r<H;r++){\n            if(r%2==0) for(int c=0;c<W;c++) order3[idx++] = pid(r,c);\n            else for(int c=W-1;c>=0;c--) order3[idx++] = pid(r,c);\n        }\n    }\n    // central-first spiral (approx via sorting by manhattan distance to center, then row/col)\n    {\n        vector<int> tmp(P); iota(tmp.begin(), tmp.end(), 0);\n        double cr=(H-1)/2.0, cc=(W-1)/2.0;\n        sort(tmp.begin(), tmp.end(), [&](int a,int b){\n            auto [ra,ca]=pos_of[a]; auto [rb,cb]=pos_of[b];\n            int da = abs(ra - (int)round(cr)) + abs(ca - (int)round(cc));\n            int db = abs(rb - (int)round(cr)) + abs(cb - (int)round(cc));\n            if(da!=db) return da<db;\n            if(degree(a)!=degree(b)) return degree(a)>degree(b);\n            if(ra!=rb) return ra<rb;\n            return ca<cb;\n        });\n        order4 = move(tmp);\n    }\n\n    // Edges and incidence\n    vector<pair<int,int>> edges;\n    vector<vector<int>> posEdgeIdx(P);\n    {\n        vector<char> seen(P*P,0);\n        auto enc=[&](int a,int b){return a*P+b;};\n        for(int u=0;u<P;u++){\n            for(int v: adj[u]){\n                if(u<v && !seen[enc(u,v)]){\n                    seen[enc(u,v)]=1;\n                    int ei=(int)edges.size();\n                    edges.emplace_back(u,v);\n                    posEdgeIdx[u].push_back(ei);\n                    posEdgeIdx[v].push_back(ei);\n                }\n            }\n        }\n    }\n    int E=(int)edges.size();\n\n    // Mild adaptive dimension weights\n    auto compute_dim_weights = [&](const vector<Seed>& pool)->array<double,15>{\n        array<int,15> curMax{};\n        curMax.fill(0);\n        for(auto &s: pool) for(int l=0;l<M;l++) curMax[l]=max(curMax[l], s.x[l]);\n        array<double,15> w{};\n        double sumw=0;\n        const double gamma=0.25;\n        for(int l=0;l<M;l++){\n            double wl = 1.0 + gamma * (max(0,100-curMax[l])) / 100.0;\n            wl = max(0.85, min(1.25, wl));\n            w[l]=wl; sumw+=wl;\n        }\n        for(int l=0;l<M;l++) w[l] = w[l] * (M / sumw);\n        return w;\n    };\n\n    // Update top1Count and lagging donor set\n    auto update_top1_and_lagging = [&](vector<Seed>& pool)->array<int,15>{\n        array<int,15> curMax{};\n        curMax.fill(0);\n        for(auto &s: pool) for(int l=0;l<M;l++) curMax[l]=max(curMax[l], s.x[l]);\n        for(auto &s: pool){\n            int cnt=0;\n            for(int l=0;l<M;l++) if(s.x[l]==curMax[l]) cnt++;\n            s.top1Count = cnt;\n        }\n        // return curMax for lagging measure\n        return curMax;\n    };\n\n    auto compute_base_scores = [&](vector<Seed>& pool, const array<double,15>& wdim){\n        int n=pool.size();\n        vector<int> idxv(n);\n        iota(idxv.begin(), idxv.end(), 0);\n        vector<vector<int>> rank(M, vector<int>(n,0));\n        for(int l=0;l<M;l++){\n            sort(idxv.begin(), idxv.end(), [&](int a,int b){\n                if(pool[a].x[l]!=pool[b].x[l]) return pool[a].x[l]>pool[b].x[l];\n                return pool[a].V>pool[b].V;\n            });\n            for(int r=0;r<n;r++) rank[l][idxv[r]]=r+1;\n        }\n        array<int,15> curMax = update_top1_and_lagging(pool);\n        // Identify lagging dimensions (far from 100)\n        array<double,15> lagW{};\n        for(int l=0;l<M;l++){\n            lagW[l] = (100 - curMax[l]) / 100.0; // 0..1\n        }\n\n        for(int i=0;i<n;i++){\n            pool[i].V=0; pool[i].maxComp=0;\n            for(int l=0;l<M;l++){ pool[i].V+=pool[i].x[l]; pool[i].maxComp=max(pool[i].maxComp, pool[i].x[l]); }\n        }\n        for(int i=0;i<n;i++){\n            double bonus=0.0;\n            for(int l=0;l<M;l++){\n                int r=rank[l][i];\n                double b=0.0;\n                if(r==1) b=3.0;\n                else if(r<=3) b=2.0;\n                else if(r<=6) b=1.0;\n                bonus += wdim[l]*b;\n            }\n            // Small lagging-dimension donor bonus: value in lagging dims contributes a little extra\n            double lagBonus=0.0;\n            for(int l=0;l<M;l++){\n                if(lagW[l] > 0.0) lagBonus += lagW[l] * (double)seeds[i].x[l];\n            }\n            lagBonus *= 0.05; // small\n            pool[i].baseScore = pool[i].V + 8.0*bonus + 0.6*pool[i].maxComp + 3.0*pool[i].top1Count + lagBonus;\n        }\n    };\n\n    auto cosine_sim = [&](const Seed& a, const Seed& b)->double{\n        double dot=0, na=0, nb=0;\n        for(int l=0;l<M;l++){\n            double xa=a.x[l], xb=b.x[l];\n            dot += xa*xb; na += xa*xa; nb += xb*xb;\n        }\n        if(na==0||nb==0) return 0.0;\n        return dot / (sqrt(na)*sqrt(nb));\n    };\n\n    auto select_diverse = [&](const vector<Seed>& pool, int tTurn)->vector<int>{\n        int n=pool.size();\n        vector<int> ord(n);\n        iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a,int b){\n            if(pool[a].baseScore!=pool[b].baseScore) return pool[a].baseScore>pool[b].baseScore;\n            if(pool[a].V!=pool[b].V) return pool[a].V>pool[b].V;\n            if(pool[a].top1Count!=pool[b].top1Count) return pool[a].top1Count>pool[b].top1Count;\n            return pool[a].maxComp>pool[b].maxComp;\n        });\n\n        int Klock = (tTurn>=T-2 ? 10 : 8);\n        vector<int> byV(n);\n        iota(byV.begin(), byV.end(), 0);\n        sort(byV.begin(), byV.end(), [&](int a,int b){\n            if(pool[a].V!=pool[b].V) return pool[a].V>pool[b].V;\n            if(pool[a].baseScore!=pool[b].baseScore) return pool[a].baseScore>pool[b].baseScore;\n            if(pool[a].top1Count!=pool[b].top1Count) return pool[a].top1Count>pool[b].top1Count;\n            return pool[a].maxComp>pool[b].maxComp;\n        });\n        vector<int> selected; selected.reserve(P);\n        vector<char> used(n,0);\n        for(int i=0;i<Klock;i++){ selected.push_back(byV[i]); used[byV[i]]=1; }\n\n        static double simMat[60][60];\n        for(int i=0;i<n;i++){\n            for(int j=i;j<n;j++){\n                double s=cosine_sim(pool[i], pool[j]);\n                simMat[i][j]=simMat[j][i]=s;\n            }\n        }\n\n        double lambda = (tTurn>=T-1 ? 0.08 : (tTurn>=T-3 ? 0.20 : 0.32));\n        int limit = min(n, 50);\n        while((int)selected.size()<P){\n            int best=-1; double bestScore=-1e100;\n            for(int i=0;i<limit;i++){\n                int c=ord[i];\n                if(used[c]) continue;\n                vector<double> sims; sims.reserve(selected.size());\n                for(int s: selected) sims.push_back(simMat[c][s]);\n                double penalty=0.0;\n                if(!sims.empty()){\n                    nth_element(sims.begin(), sims.begin()+sims.size()/2, sims.end());\n                    penalty = sims[sims.size()/2];\n                }\n                double sc = pool[c].baseScore - lambda * 800.0 * penalty;\n                if(sc>bestScore){ bestScore=sc; best=c; }\n            }\n            if(best==-1){\n                for(int i=0;i<n;i++){ if(!used[ord[i]]){ best=ord[i]; break; } }\n            }\n            used[best]=1;\n            selected.push_back(best);\n        }\n        return selected;\n    };\n\n    // Edge fitness\n    auto edge_fitness = [&](const Seed& a, const Seed& b, const array<double,15>& wdim)->double{\n        double s=0.0; int split=0;\n        for(int l=0;l<M;l++){\n            int ax=a.x[l], bx=b.x[l];\n            s += wdim[l] * (double)max(ax,bx);\n            if(ax!=bx) split++;\n        }\n        s += min(10, split);\n        return s;\n    };\n\n    auto evaluate_layout = [&](const vector<int>& pos2poolIdx, const vector<Seed>& pool, const array<double,15>& wdim, vector<double>& edgeVal)->double{\n        double total=0.0;\n        for(int e=0;e<E;e++){\n            int u=edges[e].first, v=edges[e].second;\n            int su=pos2poolIdx[u], sv=pos2poolIdx[v];\n            double val = edge_fitness(pool[su], pool[sv], wdim);\n            edgeVal[e]=val; total+=val;\n        }\n        return total;\n    };\n\n    mt19937 rng(1234567u + (unsigned)chrono::high_resolution_clock::now().time_since_epoch().count());\n\n    auto local_search = [&](vector<int>& pos2poolIdx, const vector<Seed>& pool, const array<double,15>& wdim, vector<double>& edgeVal, double& total, int itersA){\n        uniform_int_distribution<int> distPos(0, P-1);\n        for(int it=0; it<itersA; it++){\n            int a = distPos(rng);\n            int bestB=-1; double bestDelta=0.0;\n            int K = 8;\n            for(int s=0;s<K;s++){\n                int b = distPos(rng);\n                if(b==a) continue;\n                static int buf[16]; int cnt=0;\n                auto add=[&](int ei){ for(int t=0;t<cnt;t++) if(buf[t]==ei) return; buf[cnt++]=ei; };\n                for(int ei: posEdgeIdx[a]) add(ei);\n                for(int ei: posEdgeIdx[b]) add(ei);\n                double oldSum=0.0, newSum=0.0;\n                for(int t2=0;t2<cnt;t2++){\n                    int ei=buf[t2];\n                    oldSum += edgeVal[ei];\n                    int u=edges[ei].first, v=edges[ei].second;\n                    int su=pos2poolIdx[u], sv=pos2poolIdx[v];\n                    if(u==a) su=pos2poolIdx[b]; else if(u==b) su=pos2poolIdx[a];\n                    if(v==a) sv=pos2poolIdx[b]; else if(v==b) sv=pos2poolIdx[a];\n                    double val = edge_fitness(pool[su], pool[sv], wdim);\n                    newSum += val;\n                }\n                double delta=newSum-oldSum;\n                if(delta>bestDelta){ bestDelta=delta; bestB=b; }\n            }\n            if(bestB!=-1 && bestDelta>0.0){\n                swap(pos2poolIdx[a], pos2poolIdx[bestB]);\n                total += bestDelta;\n                static int buf[16]; int cnt=0;\n                auto add=[&](int ei){ for(int t=0;t<cnt;t++) if(buf[t]==ei) return; buf[cnt++]=ei; };\n                for(int ei: posEdgeIdx[a]) add(ei);\n                for(int ei: posEdgeIdx[bestB]) add(ei);\n                for(int t2=0;t2<cnt;t2++){\n                    int ei=buf[t2];\n                    int u=edges[ei].first, v=edges[ei].second;\n                    int su=pos2poolIdx[u], sv=pos2poolIdx[v];\n                    edgeVal[ei]=edge_fitness(pool[su], pool[sv], wdim);\n                }\n            }\n        }\n        // Greedy pass on high-degree positions\n        vector<int> posByDeg(P);\n        iota(posByDeg.begin(), posByDeg.end(), 0);\n        sort(posByDeg.begin(), posByDeg.end(), [&](int a,int b){ return degree(a)>degree(b); });\n        int topD = min(P, 14);\n        for(int idx=0; idx<topD; idx++){\n            int a = posByDeg[idx];\n            double bestDelta=0.0; int bestB=-1;\n            vector<int> cand;\n            cand.reserve(20);\n            for(int nb: adj[a]) cand.push_back(nb);\n            for(int nb: adj[a]) for(int nb2: adj[nb]) cand.push_back(nb2);\n            cand.push_back(a);\n            sort(cand.begin(), cand.end());\n            cand.erase(unique(cand.begin(), cand.end()), cand.end());\n            uniform_int_distribution<int> distAll(0, P-1);\n            while((int)cand.size()<18){\n                int r = distAll(rng);\n                if(find(cand.begin(), cand.end(), r)==cand.end()) cand.push_back(r);\n            }\n            for(int b: cand){\n                if(b==a) continue;\n                static int buf[20]; int cnt=0;\n                auto add=[&](int ei){ for(int t=0;t<cnt;t++) if(buf[t]==ei) return; buf[cnt++]=ei; };\n                for(int ei: posEdgeIdx[a]) add(ei);\n                for(int ei: posEdgeIdx[b]) add(ei);\n                double oldSum=0.0, newSum=0.0;\n                for(int t2=0;t2<cnt;t2++){\n                    int ei=buf[t2];\n                    oldSum += edgeVal[ei];\n                    int u=edges[ei].first, v=edges[ei].second;\n                    int su=pos2poolIdx[u], sv=pos2poolIdx[v];\n                    if(u==a) su=pos2poolIdx[b]; else if(u==b) su=pos2poolIdx[a];\n                    if(v==a) sv=pos2poolIdx[b]; else if(v==b) sv=pos2poolIdx[a];\n                    double val = edge_fitness(pool[su], pool[sv], wdim);\n                    newSum += val;\n                }\n                double delta=newSum-oldSum;\n                if(delta>bestDelta){ bestDelta=delta; bestB=b; }\n            }\n            if(bestB!=-1 && bestDelta>0.0){\n                swap(pos2poolIdx[a], pos2poolIdx[bestB]);\n                static int buf[20]; int cnt=0;\n                auto add=[&](int ei){ for(int t=0;t<cnt;t++) if(buf[t]==ei) return; buf[cnt++]=ei; };\n                for(int ei: posEdgeIdx[a]) add(ei);\n                for(int ei: posEdgeIdx[bestB]) add(ei);\n                for(int t2=0;t2<cnt;t2++){\n                    int ei=buf[t2];\n                    int u=edges[ei].first, v=edges[ei].second;\n                    int su=pos2poolIdx[u], sv=pos2poolIdx[v];\n                    edgeVal[ei]=edge_fitness(pool[su], pool[sv], wdim);\n                }\n            }\n        }\n    };\n\n    auto force_super_edges = [&](vector<int>& pos2poolIdx, const vector<int>& selIdx, int countPairs, bool clique4){\n        // Ensure strong adjacencies among elites. If clique4=true, try to ensure multiple adjacencies among top-4.\n        vector<int> sel = selIdx;\n        sort(sel.begin(), sel.end(), [&](int a,int b){\n            if(seeds[a].V!=seeds[b].V) return seeds[a].V>seeds[b].V;\n            if(seeds[a].baseScore!=seeds[b].baseScore) return seeds[a].baseScore>seeds[b].baseScore;\n            if(seeds[a].top1Count!=seeds[b].top1Count) return seeds[a].top1Count>seeds[b].top1Count;\n            return seeds[a].maxComp>seeds[b].maxComp;\n        });\n        int K = min((int)sel.size(), clique4 ? 4 : 6);\n        vector<int> elites(sel.begin(), sel.begin()+K);\n        // Map seed -> current position\n        vector<int> seedPosIdx(S, -1);\n        for(int p=0;p<P;p++){\n            int sId = pos2poolIdx[p];\n            seedPosIdx[sId]=p;\n        }\n        if(clique4){\n            // Try to ensure top-4 are forming at least a chain of adjacencies: s0-s1, s1-s2, s2-s3\n            for(int i=0;i<K-1;i++){\n                int sa=elites[i], sb=elites[i+1];\n                int pa=seedPosIdx[sa], pb=seedPosIdx[sb];\n                if(pa<0||pb<0) continue;\n                bool ok=false;\n                for(int nb: adj[pa]) if(nb==pb){ ok=true; break; }\n                if(!ok){\n                    // Move sb next to sa\n                    int target = adj[pa].empty()? -1 : adj[pa][0];\n                    if(target==-1) continue;\n                    int curB=pb;\n                    swap(pos2poolIdx[target], pos2poolIdx[curB]);\n                    seedPosIdx[ pos2poolIdx[target] ] = target;\n                    seedPosIdx[ pos2poolIdx[curB] ] = curB;\n                }\n            }\n        }else{\n            int made=0;\n            for(int i=0;i+1<K && made<countPairs; i+=2){\n                int sA=elites[i], sB=elites[i+1];\n                int posA = seedPosIdx[sA];\n                int posB = seedPosIdx[sB];\n                if(posA<0||posB<0) continue;\n                bool adjOK=false;\n                for(int nb: adj[posA]) if(nb==posB) { adjOK=true; break; }\n                if(adjOK){ made++; continue; }\n                int target=-1;\n                for(int nb: adj[posA]){ target=nb; break; }\n                if(target==-1) continue;\n                int curB = seedPosIdx[sB];\n                if(curB==-1) continue;\n                swap(pos2poolIdx[target], pos2poolIdx[curB]);\n                seedPosIdx[ pos2poolIdx[target] ] = target;\n                seedPosIdx[ pos2poolIdx[curB] ] = curB;\n                made++;\n            }\n        }\n    };\n\n    for(int t=0;t<T;t++){\n        auto wdim = compute_dim_weights(seeds);\n        compute_base_scores(seeds, wdim);\n        vector<int> selIdx = select_diverse(seeds, t);\n\n        auto solve_layout = [&](const vector<int>& order)->pair<vector<int>, double>{\n            vector<int> pos2poolIdx(P,-1);\n            for(int k=0;k<P;k++) pos2poolIdx[ order[k] ] = selIdx[k];\n            if(t>=T-3){\n                // On T-2 and T-3: ensure at least one strong pair. On T-1: form a small elite chain among top-4 and two disjoint pairs if possible.\n                if(t==T-1){\n                    force_super_edges(pos2poolIdx, selIdx, 2, true);\n                }else{\n                    force_super_edges(pos2poolIdx, selIdx, 1, false);\n                }\n            }\n            vector<double> edgeVal(E,0.0);\n            double total = evaluate_layout(pos2poolIdx, seeds, wdim, edgeVal);\n            int itA = (t>=T-1 ? 5400 : (t>=T-3 ? 4600 : 3800));\n            local_search(pos2poolIdx, seeds, wdim, edgeVal, total, itA);\n\n            // Final-turn elite-edge refinement (stronger)\n            if(t==T-1){\n                vector<int> byV = selIdx;\n                sort(byV.begin(), byV.end(), [&](int a,int b){\n                    if(seeds[a].V!=seeds[b].V) return seeds[a].V>seeds[b].V;\n                    if(seeds[a].baseScore!=seeds[b].baseScore) return seeds[a].baseScore>seeds[b].baseScore;\n                    if(seeds[a].top1Count!=seeds[b].top1Count) return seeds[a].top1Count>seeds[b].top1Count;\n                    return seeds[a].maxComp>seeds[b].maxComp;\n                });\n                int K = min((int)byV.size(), 6);\n                vector<int> eliteSeeds(byV.begin(), byV.begin()+K);\n                vector<int> seedPos(S,-1);\n                for(int p=0;p<P;p++) seedPos[ pos2poolIdx[p] ] = p;\n                // two rounds of refinement\n                for(int round=0; round<2; round++){\n                    for(int es: eliteSeeds){\n                        int p = seedPos[es];\n                        if(p<0) continue;\n                        vector<int> cand;\n                        for(int nb: adj[p]){ cand.push_back(nb); for(int nb2: adj[nb]) cand.push_back(nb2); }\n                        cand.push_back(p);\n                        sort(cand.begin(), cand.end());\n                        cand.erase(unique(cand.begin(), cand.end()), cand.end());\n                        double bestDelta=0.0; int bestPos=-1;\n                        for(int q: cand){\n                            if(q==p) continue;\n                            static int buf[24]; int cnt=0;\n                            auto add=[&](int ei){ for(int t2=0;t2<cnt;t2++) if(buf[t2]==ei) return; buf[cnt++]=ei; };\n                            for(int ei: posEdgeIdx[p]) add(ei);\n                            for(int ei: posEdgeIdx[q]) add(ei);\n                            double oldSum=0.0, newSum=0.0;\n                            for(int t2=0;t2<cnt;t2++){\n                                int ei=buf[t2];\n                                oldSum += edgeVal[ei];\n                                int u=edges[ei].first, v=edges[ei].second;\n                                int su=pos2poolIdx[u], sv=pos2poolIdx[v];\n                                if(u==p) su=pos2poolIdx[q]; else if(u==q) su=pos2poolIdx[p];\n                                if(v==p) sv=pos2poolIdx[q]; else if(v==q) sv=pos2poolIdx[p];\n                                double val = edge_fitness(seeds[su], seeds[sv], wdim);\n                                newSum += val;\n                            }\n                            double delta=newSum-oldSum;\n                            if(delta>bestDelta){ bestDelta=delta; bestPos=q; }\n                        }\n                        if(bestPos!=-1 && bestDelta>0.0){\n                            int q=bestPos;\n                            swap(pos2poolIdx[p], pos2poolIdx[q]);\n                            static int buf[24]; int cnt=0;\n                            auto add=[&](int ei){ for(int t2=0;t2<cnt;t2++) if(buf[t2]==ei) return; buf[cnt++]=ei; };\n                            for(int ei: posEdgeIdx[p]) add(ei);\n                            for(int ei: posEdgeIdx[q]) add(ei);\n                            for(int t2=0;t2<cnt;t2++){\n                                int ei=buf[t2];\n                                int u=edges[ei].first, v=edges[ei].second;\n                                int su=pos2poolIdx[u], sv=pos2poolIdx[v];\n                                edgeVal[ei]=edge_fitness(seeds[su], seeds[sv], wdim);\n                            }\n                            seedPos[es] = q;\n                        }\n                    }\n                }\n            }\n\n            return pair{pos2poolIdx, total};\n        };\n\n        auto [layout1, score1] = solve_layout(order1);\n        auto [layout2, score2] = solve_layout(order2);\n        auto [layout3, score3] = solve_layout(order3);\n        auto [layout4, score4] = solve_layout(order4);\n        vector<int> bestLayout = layout1;\n        double bestScore = score1;\n        if(score2>bestScore){ bestScore=score2; bestLayout=layout2; }\n        if(score3>bestScore){ bestScore=score3; bestLayout=layout3; }\n        if(score4>bestScore){ bestScore=score4; bestLayout=layout4; }\n\n        // Output placement\n        for(int r=0;r<N;r++){\n            for(int c=0;c<N;c++){\n                if(c) cout << ' ';\n                int pos = pid(r,c);\n                cout << seeds[ bestLayout[pos] ].id;\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        // Read next generation\n        vector<Seed> next(S);\n        for(int i=0;i<S;i++){\n            next[i].id=i;\n            int sum=0, mx=0;\n            for(int l=0;l<M;l++){\n                int v; cin>>v;\n                next[i].x[l]=v;\n                sum+=v; mx=max(mx, v);\n            }\n            next[i].V=sum;\n            next[i].baseScore=sum;\n            next[i].maxComp=mx;\n            next[i].top1Count=0;\n        }\n        seeds.swap(next);\n    }\n\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Task {\n    int sx, sy, tx, ty;\n    int dir_pick=0, rpx=0, rpy=0;\n    int dir_drop=0, rdx=0, rdy=0;\n};\n\ninline int manh(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\ninline bool inb(int x,int y,int N){ return 0<=x && x<N && 0<=y && y<N; }\nstatic const int dx4[4]={0,1,0,-1};\nstatic const int dy4[4]={1,0,-1,0};\n\ninline pair<int,int> rot_need(int fromDir,int toDir){\n    int d = (toDir - fromDir + 4) % 4;\n    if(d==0) return {0,0};\n    if(d==1) return {1,0};\n    if(d==2) return {2,0};\n    return {0,1};\n}\n\n// Hungarian for rectangular matrix (n x m)\nvector<int> hungarian_min_assign(const vector<vector<int>>& cost) {\n    int n = cost.size();\n    int m = cost[0].size();\n    int N = max(n, m);\n    const int INF = 1e9;\n    vector<vector<int>> a(N, vector<int>(N, 0));\n    for(int i=0;i<N;i++)\n        for(int j=0;j<N;j++)\n            a[i][j] = (i<n && j<m) ? cost[i][j] : 0;\n    vector<int> u(N+1,0), v(N+1,0), p(N+1,0), way(N+1,0);\n    for(int i=1;i<=N;i++){\n        p[0]=i;\n        int j0=0;\n        vector<int> minv(N+1, INF);\n        vector<char> used(N+1, false);\n        do{\n            used[j0]=true;\n            int i0=p[j0], delta=INF, j1=0;\n            for(int j=1;j<=N;j++){\n                if(used[j]) continue;\n                int cur = a[i0-1][j-1]-u[i0]-v[j];\n                if(cur<minv[j]) minv[j]=cur, way[j]=j0;\n                if(minv[j]<delta) delta=minv[j], j1=j;\n            }\n            for(int j=0;j<=N;j++){\n                if(used[j]) u[p[j]]+=delta, v[j]-=delta;\n                else minv[j]-=delta;\n            }\n            j0=j1;\n        } while(p[j0]!=0);\n        do{\n            int j1=way[j0];\n            p[j0]=p[j1];\n            j0=j1;\n        } while(j0);\n    }\n    vector<int> ans(n, -1);\n    for(int j=1;j<=N;j++){\n        if(p[j]>=1 && p[j]<=n && j<=m) ans[p[j]-1]=j-1;\n    }\n    return ans;\n}\n\n// Hilbert curve index (k=5 covers up to 32x32)\ninline int hilbertIndex(int x, int y, int k=5){\n    int d=0;\n    for(int s=1<<(k-1); s>0; s>>=1){\n        int rx = (x & s) > 0;\n        int ry = (y & s) > 0;\n        d += s * s * ((3 * rx) ^ ry);\n        if(ry==0){\n            if(rx==1){ x = (1<<k)-1 - x; y = (1<<k)-1 - y; }\n            int t=x; x=y; y=t;\n        }\n    }\n    return d;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    auto t0 = chrono::high_resolution_clock::now();\n\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    vector<pair<int,int>> S, D;\n    vector<vector<int>> occ(N, vector<int>(N,0));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            int si=s[i][j]-'0', ti=t[i][j]-'0';\n            occ[i][j]=si;\n            if(si==1 && ti==0) S.emplace_back(i,j);\n            if(si==0 && ti==1) D.emplace_back(i,j);\n        }\n    }\n    int nS=S.size(), nD=D.size();\n    if(nS==0){\n        cout<<2<<\"\\n\";\n        cout<<0<<\" \"<<1<<\"\\n\";\n        cout<<0<<\" \"<<0<<\"\\n\";\n        return 0;\n    }\n\n    // Assignment\n    vector<int> assign(nS, -1);\n    if(nS <= 220){\n        vector<vector<int>> cost(nS, vector<int>(nD));\n        for(int i=0;i<nS;i++)\n            for(int j=0;j<nD;j++)\n                cost[i][j]=manh(S[i].first,S[i].second,D[j].first,D[j].second);\n        assign = hungarian_min_assign(cost);\n    }else{\n        // Hilbert greedy\n        vector<int> idx(nS);\n        iota(idx.begin(), idx.end(), 0);\n        sort(idx.begin(), idx.end(), [&](int a,int b){\n            auto [ax,ay]=S[a]; auto [bx,by]=S[b];\n            return hilbertIndex(ax,ay) < hilbertIndex(bx,by);\n        });\n        vector<char> usedD(nD,0);\n        for(int idS: idx){\n            auto [sx,sy]=S[idS];\n            int bj=-1, bd=INT_MAX;\n            for(int j=0;j<nD;j++){\n                if(usedD[j]) continue;\n                int d=manh(sx,sy,D[j].first,D[j].second);\n                if(d<bd){ bd=d; bj=j; }\n            }\n            if(bj>=0){ usedD[bj]=1; assign[idS]=bj; }\n        }\n        // Local 2-swap\n        for(int a=0;a<nS;a++){\n            int da=assign[a]; if(da<0) continue;\n            for(int b=a+1;b<nS;b++){\n                int db=assign[b]; if(db<0) continue;\n                auto [ax,ay]=S[a]; auto [bx,by]=S[b];\n                auto [tax,tay]=D[da]; auto [tbx,tby]=D[db];\n                int before = manh(ax,ay,tax,tay)+manh(bx,by,tbx,tby);\n                int after  = manh(ax,ay,tbx,tby)+manh(bx,by,tax,tay);\n                if(after<before) swap(assign[a], assign[b]);\n            }\n        }\n    }\n\n    // Build tasks\n    vector<Task> tasks;\n    tasks.reserve(nS);\n    for(int i=0;i<nS;i++){\n        int j=assign[i];\n        if(j>=0) tasks.push_back({S[i].first,S[i].second,D[j].first,D[j].second});\n    }\n    int Tn = tasks.size();\n    if(Tn==0){\n        cout<<2<<\"\\n\";\n        cout<<0<<\" \"<<1<<\"\\n\";\n        cout<<0<<\" \"<<0<<\"\\n\";\n        return 0;\n    }\n\n    // k-means clustering on pick positions to K clusters\n    int K;\n    if(Tn <= 120) K = 6;\n    else if(Tn <= 240) K = 8;\n    else if(Tn <= 360) K = 10;\n    else K = 12; // max around 12 to keep TSP small\n    K = min(K, Tn);\n    vector<pair<int,int>> cent(K);\n    for(int k=0;k<K;k++){\n        int id = (long long)k * (Tn-1) / max(1, K-1);\n        cent[k] = {tasks[id].sx, tasks[id].sy};\n    }\n    vector<int> belong(Tn, 0);\n    for(int it=0; it<8; ++it){\n        for(int i=0;i<Tn;i++){\n            int bk=0, bd=INT_MAX;\n            for(int k=0;k<K;k++){\n                int d = manh(tasks[i].sx, tasks[i].sy, cent[k].first, cent[k].second);\n                if(d<bd){ bd=d; bk=k; }\n            }\n            belong[i]=bk;\n        }\n        vector<long long> sx(K,0), sy(K,0), cnt(K,0);\n        for(int i=0;i<Tn;i++){\n            sx[belong[i]] += tasks[i].sx;\n            sy[belong[i]] += tasks[i].sy;\n            cnt[belong[i]]++;\n        }\n        for(int k=0;k<K;k++){\n            if(cnt[k]) cent[k] = {(int)(sx[k]/cnt[k]), (int)(sy[k]/cnt[k])};\n        }\n    }\n\n    // Exact TSP on cluster centroids (starting from nearest to (0,0))\n    int start = 0, bestd=INT_MAX;\n    for(int k=0;k<K;k++){\n        int d = manh(0,0,cent[k].first,cent[k].second);\n        if(d<bestd){ bestd=d; start=k; }\n    }\n    vector<vector<int>> distK(K, vector<int>(K,0));\n    for(int i=0;i<K;i++) for(int j=0;j<K;j++){\n        distK[i][j] = manh(cent[i].first, cent[i].second, cent[j].first, cent[j].second);\n    }\n    int FULL = 1<<K;\n    const int INF = 1e9;\n    vector<vector<int>> dp(FULL, vector<int>(K, INF));\n    vector<vector<int>> prevK(FULL, vector<int>(K, -1));\n    dp[1<<start][start]=0;\n    for(int mask=0; mask<FULL; ++mask){\n        for(int u=0; u<K; ++u){\n            if(dp[mask][u]>=INF) continue;\n            for(int v=0; v<K; ++v){\n                if(mask>>v & 1) continue;\n                int nmask = mask | (1<<v);\n                int nd = dp[mask][u] + distK[u][v];\n                if(nd < dp[nmask][v]){\n                    dp[nmask][v]=nd; prevK[nmask][v]=u;\n                }\n            }\n        }\n    }\n    int last=-1; int bestCost=INF;\n    int fullMask = FULL-1;\n    for(int u=0; u<K; ++u){\n        if(dp[fullMask][u] < bestCost){\n            bestCost = dp[fullMask][u]; last=u;\n        }\n    }\n    vector<int> clusterOrder;\n    {\n        int mask=fullMask, u=last;\n        while(u!=-1){\n            clusterOrder.push_back(u);\n            int pu = prevK[mask][u];\n            if(pu==-1) break;\n            mask ^= 1<<u;\n            u=pu;\n        }\n        reverse(clusterOrder.begin(), clusterOrder.end());\n    }\n\n    // Build initial order: visit clusters in TSP order; within each use Hilbert then greedy NN\n    vector<vector<int>> perC(K);\n    for(int i=0;i<Tn;i++) perC[belong[i]].push_back(i);\n    for(int k=0;k<K;k++){\n        auto &vec=perC[k];\n        sort(vec.begin(), vec.end(), [&](int a,int b){\n            return hilbertIndex(tasks[a].sx, tasks[a].sy) < hilbertIndex(tasks[b].sx, tasks[b].sy);\n        });\n    }\n    vector<int> order;\n    order.reserve(Tn);\n    int rx_est=0, ry_est=0;\n    for(int ck : clusterOrder){\n        auto &vec = perC[ck];\n        vector<char> used(vec.size(), 0);\n        for(size_t step=0; step<vec.size(); ++step){\n            int best=-1, bd=INT_MAX;\n            for(size_t z=0; z<vec.size(); ++z){\n                if(used[z]) continue;\n                int id=vec[z];\n                int dpick=INT_MAX;\n                for(int k=0;k<4;k++){\n                    int rpx=tasks[id].sx - dx4[k], rpy=tasks[id].sy - dy4[k];\n                    if(!inb(rpx,rpy,N)) continue;\n                    dpick = min(dpick, manh(rx_est,ry_est,rpx,rpy));\n                }\n                if(dpick<bd){ bd=dpick; best=(int)z; }\n            }\n            if(best==-1) break;\n            int id=vec[best];\n            used[best]=1;\n            order.push_back(id);\n            int brx=rx_est, bry=ry_est, bd2=INT_MAX;\n            for(int k=0;k<4;k++){\n                int rpx=tasks[id].sx - dx4[k], rpy=tasks[id].sy - dy4[k];\n                if(!inb(rpx,rpy,N)) continue;\n                int d=manh(rx_est,ry_est,rpx,rpy);\n                if(d<bd2){ bd2=d; brx=rpx; bry=rpy; }\n            }\n            // advance to drop root approx\n            int drbx=brx, drby=bry, bd3=INT_MAX;\n            for(int k=0;k<4;k++){\n                int rdx=tasks[id].tx - dx4[k], rdy=tasks[id].ty - dy4[k];\n                if(!inb(rdx,rdy,N)) continue;\n                int d=manh(brx,bry,rdx,rdy);\n                if(d<bd3){ bd3=d; drbx=rdx; drby=rdy; }\n            }\n            rx_est=drbx; ry_est=drby;\n        }\n    }\n\n    // Approximate route helpers\n    auto best_pick_from = [&](int fromx,int fromy, const Task& tk){\n        int brx=0, bry=0, bd=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rpx=tk.sx - dx4[k], rpy=tk.sy - dy4[k];\n            if(!inb(rpx,rpy,N)) continue;\n            int d=manh(fromx,fromy,rpx,rpy);\n            if(d<bd){ bd=d; brx=rpx; bry=rpy; }\n        }\n        return pair<int,int>(brx,bry);\n    };\n    auto best_drop_from_pick = [&](int prx,int pry, const Task& tk){\n        int brx=0, bry=0, bd=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rdx=tk.tx - dx4[k], rdy=tk.ty - dy4[k];\n            if(!inb(rdx,rdy,N)) continue;\n            int d=manh(prx,pry,rdx,rdy);\n            if(d<bd){ bd=d; brx=rdx; bry=rdy; }\n        }\n        return pair<int,int>(brx,bry);\n    };\n\n    int n = order.size();\n    vector<int> prx(n), pry(n), drx(n), dry(n);\n    auto rebuild_waypoints = [&](){\n        int x=0,y=0;\n        for(int i=0;i<n;i++){\n            int id=order[i];\n            auto pr = best_pick_from(x,y,tasks[id]);\n            prx[i]=pr.first; pry[i]=pr.second;\n            auto dr = best_drop_from_pick(prx[i],pry[i],tasks[id]);\n            drx[i]=dr.first; dry[i]=dr.second;\n            x=drx[i]; y=dry[i];\n        }\n    };\n    auto total_cost = [&](){\n        long long c=0; int x=0,y=0;\n        for(int i=0;i<n;i++){\n            c += manh(x,y,prx[i],pry[i]);\n            c += manh(prx[i],pry[i],drx[i],dry[i]);\n            x=drx[i]; y=dry[i];\n        }\n        return c;\n    };\n\n    rebuild_waypoints();\n    long long curCost = total_cost();\n\n    auto elapsed_ms = [&](){\n        return (int)chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - t0).count();\n    };\n\n    // Deterministic 2-opt under time cap\n    for(int len=2; len<=min(n, 140) && elapsed_ms()<260; ++len){\n        for(int a=0; a+len<=n && elapsed_ms()<260; ++a){\n            int b=a+len;\n            vector<int> cand = order;\n            reverse(cand.begin()+a, cand.begin()+b);\n            auto backup = order;\n            order.swap(cand);\n            rebuild_waypoints();\n            long long nc = total_cost();\n            if(nc < curCost){\n                curCost = nc;\n            }else{\n                order.swap(backup);\n                rebuild_waypoints();\n            }\n        }\n    }\n\n    // Execute with overlap rotations and lookahead\n    int rx=0, ry=0;\n    int leaf_dir=0; // Right\n    bool holding=false;\n    vector<string> out;\n    out.reserve(200000);\n    const int TURN_LIMIT = 100000;\n\n    auto emit_turn = [&](char mv, char rot, bool P){\n        string st(4,'.');\n        st[0]=mv?mv:'.';\n        st[1]=rot?rot:'.';\n        st[3]=P?'P':'.';\n        out.push_back(st);\n    };\n    auto move_step_smart = [&](int tx,int ty, int &cw,int &ccw){\n        char mv='.';\n        if(rx!=tx && ry!=ty){\n            if(abs(rx-tx) >= abs(ry-ty)){\n                mv = (rx<tx ? 'D' : 'U'); rx += (mv=='D'?1:-1);\n            }else{\n                mv = (ry<ty ? 'R' : 'L'); ry += (mv=='R'?1:-1);\n            }\n        }else if(rx!=tx){\n            mv = (rx<tx ? 'D' : 'U'); rx += (mv=='D'?1:-1);\n        }else if(ry!=ty){\n            mv = (ry<ty ? 'R' : 'L'); ry += (mv=='R'?1:-1);\n        }\n        char rot='.';\n        if(cw>0){ rot='R'; cw--; leaf_dir=(leaf_dir+1)&3; }\n        else if(ccw>0){ rot='L'; ccw--; leaf_dir=(leaf_dir+3)&3; }\n        emit_turn(mv, rot, false);\n    };\n    auto move_to = [&](int tx,int ty, int &cw,int &ccw){\n        while((rx!=tx || ry!=ty) && (int)out.size()<TURN_LIMIT){\n            move_step_smart(tx,ty,cw,ccw);\n        }\n    };\n\n    auto plan_pick = [&](const Task& tk)->tuple<int,int,int,int,int>{\n        int bestDir=0, brx=rx, bry=ry, bcw=0, bccw=0;\n        int bestScore=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rpx = tk.sx - dx4[k], rpy = tk.sy - dy4[k];\n            if(!inb(rpx,rpy,N)) continue;\n            auto [cw,ccw] = rot_need(leaf_dir, k);\n            int score = manh(rx,ry,rpx,rpy) + (cw+ccw);\n            int inter = min({rpx, rpy, N-1-rpx, N-1-rpy});\n            if(score<bestScore || (score==bestScore && inter > min({brx, bry, N-1-brx, N-1-bry}))){\n                bestScore=score; bestDir=k; brx=rpx; bry=rpy; bcw=cw; bccw=ccw;\n            }\n        }\n        return {bestDir, brx, bry, bcw, bccw};\n    };\n\n    auto best_pick_root_from_drop = [&](int drx,int dry, const Task& tk){\n        int nk=0, nprx=0, npry=0, bd=INT_MAX;\n        for(int kk=0;kk<4;kk++){\n            int rpx2 = tk.sx - dx4[kk], rpy2 = tk.sy - dy4[kk];\n            if(!inb(rpx2,rpy2,N)) continue;\n            int d = manh(drx,dry,rpx2,rpy2);\n            if(d<bd){ bd=d; nk=kk; nprx=rpx2; npry=rpy2; }\n        }\n        return tuple<int,int,int,int>(nk, nprx, npry, bd);\n    };\n\n    for(int pos=0; pos<n; ++pos){\n        if((int)out.size()>=TURN_LIMIT) break;\n        Task &tk = tasks[order[pos]];\n\n        // Plan pick\n        int dirp, prx0, pry0, pcw, pccw;\n        tie(dirp, prx0, pry0, pcw, pccw) = plan_pick(tk);\n        tk.dir_pick=dirp; tk.rpx=prx0; tk.rpy=pry0;\n        move_to(tk.rpx, tk.rpy, pcw, pccw);\n        while((pcw>0 || pccw>0) && (int)out.size()<TURN_LIMIT){\n            char rot='.';\n            if(pcw>0){ rot='R'; pcw--; leaf_dir=(leaf_dir+1)&3; }\n            else { rot='L'; pccw--; leaf_dir=(leaf_dir+3)&3; }\n            emit_turn('.', rot, false);\n        }\n        if((int)out.size()>=TURN_LIMIT) break;\n\n        // Pick\n        int fx = rx + dx4[leaf_dir];\n        int fy = ry + dy4[leaf_dir];\n        bool canPick = inb(fx,fy,N) && !holding && occ[fx][fy]==1;\n        emit_turn('.', '.', canPick);\n        if(canPick){ holding=true; occ[fx][fy]=0; }\n        if((int)out.size()>=TURN_LIMIT) break;\n\n        // Drop with lookahead\n        int dird=-1, drx0=0, dry0=0, dcw=0, dccw=0;\n        int bestScore=INT_MAX, bestRot=INT_MAX;\n        for(int k=0;k<4;k++){\n            int rdx = tk.tx - dx4[k], rdy = tk.ty - dy4[k];\n            if(!inb(rdx,rdy,N)) continue;\n            auto [cw,ccw]=rot_need(leaf_dir, k);\n            int nextCost=0;\n            if(pos+1 < n){\n                Task &nxt = tasks[order[pos+1]];\n                int nk, nprx, npry, d;\n                tie(nk, nprx, npry, d) = best_pick_root_from_drop(rdx, rdy, nxt);\n                nextCost = d;\n            }\n            int score = manh(rx,ry,rdx,rdy) + nextCost;\n            int rotCost = (cw+ccw);\n            if(score < bestScore || (score==bestScore && rotCost < bestRot)){\n                bestScore=score; bestRot=rotCost; dird=k; drx0=rdx; dry0=rdy; dcw=cw; dccw=ccw;\n            }\n        }\n        if(dird==-1){\n            auto [cw,ccw]=rot_need(leaf_dir, 0);\n            dird=0; drx0=tk.tx - dx4[0]; dry0=tk.ty - dy4[0]; dcw=cw; dccw=ccw;\n        }\n        tk.dir_drop=dird; tk.rdx=drx0; tk.rdy=dry0;\n        move_to(tk.rdx, tk.rdy, dcw, dccw);\n        while((dcw>0 || dccw>0) && (int)out.size()<TURN_LIMIT){\n            char rot='.';\n            if(dcw>0){ rot='R'; dcw--; leaf_dir=(leaf_dir+1)&3; }\n            else { rot='L'; dccw--; leaf_dir=(leaf_dir+3)&3; }\n            emit_turn('.', rot, false);\n        }\n        if((int)out.size()>=TURN_LIMIT) break;\n\n        // Drop\n        fx = rx + dx4[leaf_dir];\n        fy = ry + dy4[leaf_dir];\n        bool canDrop = inb(fx,fy,N) && holding && occ[fx][fy]==0;\n        emit_turn('.', '.', canDrop);\n        if(canDrop){ holding=false; occ[fx][fy]=1; }\n        if((int)out.size()>=TURN_LIMIT) break;\n    }\n\n    // Output arm: 2 vertices, length 1, root at (0,0)\n    cout<<2<<\"\\n\";\n    cout<<0<<\" \"<<1<<\"\\n\";\n    cout<<0<<\" \"<<0<<\"\\n\";\n    for(auto &row : out) cout<<row<<\"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    int w; // +1 mackerel, -1 sardine\n};\nstruct Rect {\n    int x1,y1,x2,y2; // inclusive\n    long long score = LLONG_MIN;\n    int a=0,b=0;\n};\n\nstatic inline long long rect_perimeter(int x1,int y1,int x2,int y2){\n    long long w = llabs((long long)x2 - x1);\n    long long h = llabs((long long)y2 - y1);\n    return 2*(w + h);\n}\nstatic inline bool insideRectInclusive(const Rect& r, int x, int y){\n    return (x >= r.x1 && x <= r.x2 && y >= r.y1 && y <= r.y2);\n}\n\nstruct Grid {\n    int G;\n    int B; // bin size\n    int maxCoord = 100000;\n    int W,H;\n    vector<int> a; // W*H\n    vector<long long> ps; // (W+1)*(H+1)\n    Grid(int G_): G(G_) {\n        B = (maxCoord + G - 1) / G; // ceil division\n        W = G; H = G;\n        a.assign(W*H, 0);\n        ps.assign((W+1)*(H+1), 0);\n    }\n    inline int idx(int ix,int iy) const { return iy*W + ix; }\n    inline void addPoint(int x,int y,int w){\n        int ix = min(W-1, x / B);\n        int iy = min(H-1, y / B);\n        a[idx(ix,iy)] += w;\n    }\n    void buildPS(){\n        for(int iy=0; iy<=H; ++iy){\n            for(int ix=0; ix<=W; ++ix){\n                if (ix==0 || iy==0) { ps[iy*(W+1)+ix] = 0; }\n            }\n        }\n        for(int iy=1; iy<=H; ++iy){\n            long long run = 0;\n            for(int ix=1; ix<=W; ++ix){\n                run += a[idx(ix-1,iy-1)];\n                ps[iy*(W+1)+ix] = ps[(iy-1)*(W+1)+ix] + run;\n            }\n        }\n    }\n    inline long long sumRectCells(int lx,int ly,int rx,int ry) const {\n        if (lx>rx || ly>ry) return 0;\n        lx = max(0,lx); ly = max(0,ly);\n        rx = min(W-1,rx); ry = min(H-1,ry);\n        if (lx>rx || ly>ry) return 0;\n        long long s = ps[(ry+1)*(W+1)+(rx+1)]\n                    - ps[(ly)*(W+1)+(rx+1)]\n                    - ps[(ry+1)*(W+1)+(lx)]\n                    + ps[(ly)*(W+1)+(lx)];\n        return s;\n    }\n    inline int cellX1(int ix) const { return max(0, ix * B); }\n    inline int cellX2(int ix) const { return min(maxCoord, (ix+1)*B); }\n    inline int cellY1(int iy) const { return max(0, iy * B); }\n    inline int cellY2(int iy) const { return min(maxCoord, (iy+1)*B); }\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    for(int i=0;i<N;i++){ int x,y; cin>>x>>y; pts.push_back({x,y,+1}); }\n    for(int i=0;i<N;i++){ int x,y; cin>>x>>y; pts.push_back({x,y,-1}); }\n\n    const long long PERIM_LIMIT = 400000;\n    const int MAXC = 100000;\n\n    // Build multiple grids\n    vector<int> Gsizes = {256, 384, 512};\n    vector<Grid> grids;\n    grids.reserve(Gsizes.size());\n    for(int g: Gsizes) grids.emplace_back(g);\n    for (auto &p: pts)\n        for (auto &gr: grids) gr.addPoint(p.x, p.y, p.w);\n    for (auto &gr: grids) gr.buildPS();\n\n    // Candidate pool\n    vector<Rect> candidates;\n    candidates.reserve(4000);\n\n    auto clamp_rect = [&](Rect r)->Rect{\n        r.x1 = max(0, min(MAXC, r.x1));\n        r.x2 = max(0, min(MAXC, r.x2));\n        r.y1 = max(0, min(MAXC, r.y1));\n        r.y2 = max(0, min(MAXC, r.y2));\n        if (r.x1 > r.x2) swap(r.x1, r.x2);\n        if (r.y1 > r.y2) swap(r.y1, r.y2);\n        if (r.x1==r.x2) { if (r.x2<MAXC) r.x2++; else if (r.x1>0) r.x1--; }\n        if (r.y1==r.y2) { if (r.y2<MAXC) r.y2++; else if (r.y1>0) r.y1--; }\n        if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) > PERIM_LIMIT){\n            // shrink around center\n            long long w = r.x2 - r.x1;\n            long long h = r.y2 - r.y1;\n            if (w + h == 0) return r;\n            long long max_sum = PERIM_LIMIT/2;\n            double scale = (double)max_sum / (double)(w + h);\n            long long nw = max(1LL, (long long)(w*scale));\n            long long nh = max(1LL, (long long)(h*scale));\n            long long cx = (r.x1 + r.x2)/2;\n            long long cy = (r.y1 + r.y2)/2;\n            long long nx1 = max(0LL, cx - nw/2);\n            long long nx2 = min((long long)MAXC, nx1 + nw);\n            nx1 = max(0LL, nx2 - nw);\n            long long ny1 = max(0LL, cy - nh/2);\n            long long ny2 = min((long long)MAXC, ny1 + nh);\n            ny1 = max(0LL, ny2 - nh);\n            r.x1 = (int)nx1; r.x2 = (int)nx2;\n            r.y1 = (int)ny1; r.y2 = (int)ny2;\n        }\n        return r;\n    };\n    auto add_candidate = [&](Rect r){\n        r = clamp_rect(r);\n        candidates.push_back(r);\n    };\n\n    // Grid-based candidates with multi-step expansions (binary search per side)\n    for (auto &gr: grids){\n        int W=gr.W, H=gr.H;\n        struct Cell { int ix,iy; int val; };\n        vector<Cell> cells;\n        cells.reserve(W*H);\n        for(int iy=0; iy<H; ++iy)\n            for(int ix=0; ix<W; ++ix)\n                cells.push_back({ix,iy, gr.a[gr.idx(ix,iy)]});\n        int T = min(300, (int)cells.size());\n        nth_element(cells.begin(), cells.begin()+T, cells.end(), [](const Cell& a, const Cell& b){ return a.val > b.val; });\n        cells.resize(T);\n\n        auto rectFromCells = [&](int lx,int ly,int rx,int ry)->Rect{\n            return Rect{ gr.cellX1(lx), gr.cellY1(ly), gr.cellX2(rx), gr.cellY2(ry), 0 };\n        };\n        auto perim_ok_cells = [&](int lx,int ly,int rx,int ry)->bool{\n            Rect r = rectFromCells(lx,ly,rx,ry);\n            return rect_perimeter(r.x1,r.y1,r.x2,r.y2) <= PERIM_LIMIT;\n        };\n        for (const auto &c: cells){\n            int lx=c.ix, rx=c.ix, ly=c.iy, ry=c.iy;\n            long long bestS = gr.sumRectCells(lx,ly,rx,ry);\n            bool improved = true;\n            int iter=0;\n            while (improved && iter<200){\n                ++iter;\n                improved = false;\n                int blx=lx, bly=ly, brx=rx, bry=ry;\n                long long bS = bestS;\n\n                // For each direction, try to expand by multiple cells using exponential then binary search\n                auto try_expand = [&](int &lx,int &ly,int &rx,int &ry, int dir)->void{\n                    // dir: 0 expand left, 1 right, 2 down, 3 up\n                    int Lx=lx, Ly=ly, Rx=rx, Ry=ry;\n                    int lo=0, hi=0;\n                    auto sumHere = [&](int Lx,int Ly,int Rx,int Ry){ return gr.sumRectCells(Lx,Ly,Rx,Ry); };\n                    auto ok = [&](int Lx,int Ly,int Rx,int Ry){ return perim_ok_cells(Lx,Ly,Rx,Ry); };\n                    // prepare movement limits\n                    auto advance = [&](int step)->bool{\n                        int nlx=Lx, nly=Ly, nrx=Rx, nry=Ry;\n                        if (dir==0) nlx = Lx - step;\n                        else if (dir==1) nrx = Rx + step;\n                        else if (dir==2) nly = Ly - step;\n                        else nry = Ry + step;\n                        if (nlx<0 || nly<0 || nrx>=W || nry>=H) return false;\n                        if (!ok(nlx,nly,nrx,nry)) return false;\n                        long long s = sumHere(nlx,nly,nrx,nry);\n                        if (s > bS){ bS = s; blx=nlx; bly=nly; brx=nrx; bry=nry; return true; }\n                        return false;\n                    };\n                    // exponential search for hi\n                    int step = 1;\n                    int lastGood = 0;\n                    while (true){\n                        int nlx=Lx, nly=Ly, nrx=Rx, nry=Ry;\n                        if (dir==0) nlx = Lx - step;\n                        else if (dir==1) nrx = Rx + step;\n                        else if (dir==2) nly = Ly - step;\n                        else nry = Ry + step;\n                        if (nlx<0 || nly<0 || nrx>=W || nry>=H) break;\n                        if (!ok(nlx,nly,nrx,nry)) break;\n                        lastGood = step;\n                        step <<= 1;\n                        if (step <= 0) break;\n                    }\n                    if (lastGood==0) return;\n                    // binary search in [1..lastGood] for best sum (not necessarily monotonic, but we will sample midpoints improving only; to stay simple, we can just try a few splits)\n                    int loStep = 1, hiStep = lastGood;\n                    // Instead of true binary search, try few trial steps: quarter, half, three-quarter, and lastGood\n                    vector<int> trials = { hiStep, hiStep*3/4, hiStep/2, hiStep/4 };\n                    sort(trials.begin(), trials.end());\n                    trials.erase(unique(trials.begin(), trials.end()), trials.end());\n                    for (int s: trials){\n                        int nlx=Lx, nly=Ly, nrx=Rx, nry=Ry;\n                        if (dir==0) nlx = Lx - s;\n                        else if (dir==1) nrx = Rx + s;\n                        else if (dir==2) nly = Ly - s;\n                        else nry = Ry + s;\n                        if (nlx<0 || nly<0 || nrx>=W || nry>=H) continue;\n                        if (!ok(nlx,nly,nrx,nry)) continue;\n                        long long val = sumHere(nlx,nly,nrx,nry);\n                        if (val > bS){ bS=val; blx=nlx; bly=nly; brx=nrx; bry=nry; }\n                    }\n                };\n\n                try_expand(lx,ly,rx,ry,0);\n                try_expand(lx,ly,rx,ry,1);\n                try_expand(lx,ly,rx,ry,2);\n                try_expand(lx,ly,rx,ry,3);\n\n                // Small shrinks might help if sardine-heavy margins got included\n                auto try_shrink = [&](int dir)->void{\n                    int nlx=lx, nly=ly, nrx=rx, nry=ry;\n                    if (dir==0 && lx<rx) nlx=lx+1;\n                    if (dir==1 && lx<rx) nrx=rx-1;\n                    if (dir==2 && ly<ry) nly=ly+1;\n                    if (dir==3 && ly<ry) nry=ry-1;\n                    if (nlx>nrx || nly>nry) return;\n                    long long s = gr.sumRectCells(nlx,nly,nrx,nry);\n                    if (s > bS){ bS=s; blx=nlx; bly=nly; brx=nrx; bry=nry; }\n                };\n                try_shrink(0); try_shrink(1); try_shrink(2); try_shrink(3);\n\n                if (bS > bestS){\n                    bestS = bS;\n                    lx=blx; ly=bly; rx=brx; ry=bry;\n                    improved = true;\n                }\n            }\n            Rect r = rectFromCells(lx,ly,rx,ry);\n            add_candidate(r);\n\n            // Add a few variants: small expansions if within perimeter\n            int variants = 3;\n            for(int t=1;t<=variants;t++){\n                int elx = max(0, lx - t);\n                int erx = min(W-1, rx + t);\n                int ely = max(0, ly - t);\n                int ery = min(H-1, ry + t);\n                Rect r2 = rectFromCells(elx,ly,rx,ry); add_candidate(r2);\n                r2 = rectFromCells(lx,ely,rx,ry); add_candidate(r2);\n                r2 = rectFromCells(lx,ly,erx,ry); add_candidate(r2);\n                r2 = rectFromCells(lx,ly,rx,ery); add_candidate(r2);\n            }\n        }\n    }\n\n    // Random sampling using biased coordinates\n    vector<int> xs_all, ys_all, xs_m, ys_m;\n    xs_all.reserve(pts.size()); ys_all.reserve(pts.size());\n    xs_m.reserve(pts.size()); ys_m.reserve(pts.size());\n    for (auto &p: pts){\n        xs_all.push_back(p.x); ys_all.push_back(p.y);\n        if (p.w==+1){ xs_m.push_back(p.x); ys_m.push_back(p.y); }\n    }\n    auto sample_unique = [&](const vector<int>& v, int k){\n        int M = v.size();\n        vector<int> idx(M);\n        iota(idx.begin(), idx.end(), 0);\n        static std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n        shuffle(idx.begin(), idx.end(), rng);\n        unordered_set<int> seen;\n        seen.reserve(k*2);\n        vector<int> out; out.reserve(k);\n        for(int i=0;i<M && (int)out.size()<k;i++){\n            int val = v[idx[i]];\n            if (seen.insert(val).second) out.push_back(val);\n        }\n        sort(out.begin(), out.end());\n        return out;\n    };\n    vector<int> sx_all = sample_unique(xs_all, 250);\n    vector<int> sy_all = sample_unique(ys_all, 250);\n    vector<int> sx_m = sample_unique(xs_m, 250);\n    vector<int> sy_m = sample_unique(ys_m, 250);\n    auto merge_coords = [&](vector<int> a, vector<int> b){\n        a.insert(a.end(), b.begin(), b.end());\n        a.push_back(0); a.push_back(MAXC);\n        sort(a.begin(), a.end());\n        a.erase(unique(a.begin(), a.end()), a.end());\n        return a;\n    };\n    vector<int> sx = merge_coords(sx_all, sx_m);\n    vector<int> sy = merge_coords(sy_all, sy_m);\n\n    std::mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto randint = [&](int L, int R){ std::uniform_int_distribution<int> dist(L,R); return dist(rng); };\n\n    int Xn = (int)sx.size();\n    int Yn = (int)sy.size();\n\n    auto add_rect_from_bounds = [&](int xl,int xr,int yl,int yr){\n        if (xl==xr){ if (xr<MAXC) xr++; else if (xl>0) xl--; }\n        if (yl==yr){ if (yr<MAXC) yr++; else if (yl>0) yl--; }\n        Rect r{xl,yl,xr,yr,0};\n        if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) <= PERIM_LIMIT) add_candidate(r);\n    };\n\n    // Uniform random pairs\n    int S = 2000;\n    for(int t=0;t<S;t++){\n        int i1 = randint(0, Xn-1), i2 = randint(0, Xn-1);\n        int j1 = randint(0, Yn-1), j2 = randint(0, Yn-1);\n        if (i1==i2){ if (i2+1<Xn) i2++; else if (i1>0) i1--; }\n        if (j1==j2){ if (j2+1<Yn) j2++; else if (j1>0) j1--; }\n        int xl = min(sx[i1], sx[i2]);\n        int xr = max(sx[i1], sx[i2]);\n        int yl = min(sy[j1], sy[j2]);\n        int yr = max(sy[j1], sy[j2]);\n        add_rect_from_bounds(xl,xr,yl,yr);\n    }\n    // Biased rectangles: use mackerel coords for one axis\n    int Sb = 1000;\n    for(int t=0;t<Sb;t++){\n        int i1 = randint(0, (int)sx_m.size()-1);\n        int i2 = randint(0, (int)sx_m.size()-1);\n        int j1 = randint(0, Yn-1);\n        int j2 = randint(0, Yn-1);\n        if (i1==i2){ if (i2+1<(int)sx_m.size()) i2++; else if (i1>0) i1--; }\n        if (j1==j2){ if (j2+1<Yn) j2++; else if (j1>0) j1--; }\n        int xl = min(sx_m[i1], sx_m[i2]);\n        int xr = max(sx_m[i1], sx_m[i2]);\n        int yl = min(sy[j1], sy[j2]);\n        int yr = max(sy[j1], sy[j2]);\n        add_rect_from_bounds(xl,xr,yl,yr);\n    }\n    // Anchored rectangles\n    for(int t=0;t<400;t++){\n        int i = randint(0, Xn-1);\n        int j = randint(0, Yn-1);\n        int xl = min(sx[i], MAXC/2);\n        int xr = MAXC;\n        int yl = min(sy[j], MAXC/2);\n        int yr = MAXC;\n        add_rect_from_bounds(xl,xr,yl,yr);\n        add_rect_from_bounds(0, sx[i], 0, sy[j]);\n    }\n\n    // Exact evaluation function\n    auto evaluate = [&](Rect &r){\n        int a=0,b=0;\n        for (auto &p: pts){\n            if (insideRectInclusive(r, p.x, p.y)){\n                if (p.w==1) a++; else b++;\n            }\n        }\n        r.a = a; r.b = b;\n        r.score = (long long)a - (long long)b;\n    };\n\n    // Evaluate all candidates and keep top K\n    for (auto &r: candidates){\n        // ensure within limits\n        r = clamp_rect(r);\n    }\n    // Deduplicate rough by hashing bounds to reduce repeated evals\n    sort(candidates.begin(), candidates.end(), [](const Rect& A, const Rect& B){\n        if (A.x1!=B.x1) return A.x1<B.x1;\n        if (A.y1!=B.y1) return A.y1<B.y1;\n        if (A.x2!=B.x2) return A.x2<B.x2;\n        return A.y2<B.y2;\n    });\n    candidates.erase(unique(candidates.begin(), candidates.end(), [](const Rect& A, const Rect& B){\n        return A.x1==B.x1 && A.y1==B.y1 && A.x2==B.x2 && A.y2==B.y2;\n    }), candidates.end());\n\n    // Evaluate, keep top M\n    int Mkeep = 80;\n    vector<Rect> top;\n    top.reserve(Mkeep);\n    Rect best; best.score = LLONG_MIN;\n    for (auto &r: candidates){\n        evaluate(r);\n        if ((int)top.size() < Mkeep){\n            top.push_back(r);\n        }else{\n            // keep if better than worst\n            int worst = 0;\n            for (int i=1;i<Mkeep;i++) if (top[i].score < top[worst].score) worst = i;\n            if (r.score > top[worst].score || (r.score==top[worst].score && r.a > top[worst].a)){\n                top[worst] = r;\n            }\n        }\n        if (r.score > best.score || (r.score==best.score && r.a > best.a)) best = r;\n    }\n    if (top.empty()){\n        Rect r{0,0,MAXC,MAXC,0}; evaluate(r); best=r; top.push_back(r);\n    }\n\n    // Exact coordinate-descent refinement on top K\n    // Prepare candidate coordinate sets (unique x,y from points near the rectangle)\n    vector<int> xs_pts, ys_pts;\n    xs_pts.reserve(pts.size()); ys_pts.reserve(pts.size());\n    for (auto &p: pts){ xs_pts.push_back(p.x); ys_pts.push_back(p.y); }\n    sort(xs_pts.begin(), xs_pts.end()); xs_pts.erase(unique(xs_pts.begin(), xs_pts.end()), xs_pts.end());\n    sort(ys_pts.begin(), ys_pts.end()); ys_pts.erase(unique(ys_pts.begin(), ys_pts.end()), ys_pts.end());\n\n    auto refine_rect = [&](Rect r){\n        // Limit candidate positions to around current bounds to keep complexity reasonable\n        auto gather_candidates = [&](const vector<int>& v, int low, int high, int k)->vector<int>{\n            // collect indices near low and high\n            vector<int> cand;\n            cand.reserve(k*2 + 10);\n            int iLow = lower_bound(v.begin(), v.end(), low) - v.begin();\n            int iHigh = lower_bound(v.begin(), v.end(), high) - v.begin();\n            // add window around iLow and iHigh\n            for (int d=-k; d<=k; ++d){\n                int i = iLow + d;\n                if (0<=i && i<(int)v.size()) cand.push_back(v[i]);\n                i = iHigh + d;\n                if (0<=i && i<(int)v.size()) cand.push_back(v[i]);\n            }\n            cand.push_back(0); cand.push_back(MAXC);\n            sort(cand.begin(), cand.end());\n            cand.erase(unique(cand.begin(), cand.end()), cand.end());\n            return cand;\n        };\n        vector<int> candX1 = gather_candidates(xs_pts, r.x1, r.x2, 30);\n        vector<int> candX2 = candX1; // reuse\n        vector<int> candY1 = gather_candidates(ys_pts, r.y1, r.y2, 30);\n        vector<int> candY2 = candY1;\n\n        bool improved = true;\n        int iter=0;\n        while (improved && iter<5){\n            ++iter; improved = false;\n            // Move left side\n            Rect bestLoc = r;\n            for (int nx1: candX1){\n                if (nx1 > r.x2) break;\n                if (nx1==r.x1) continue;\n                Rect t{nx1, r.y1, r.x2, r.y2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n            // Move right side\n            bestLoc = r;\n            for (int nx2: candX2){\n                if (nx2 < r.x1) continue;\n                if (nx2==r.x2) continue;\n                Rect t{r.x1, r.y1, nx2, r.y2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n            // Move bottom\n            bestLoc = r;\n            for (int ny1: candY1){\n                if (ny1 > r.y2) break;\n                if (ny1==r.y1) continue;\n                Rect t{r.x1, ny1, r.x2, r.y2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n            // Move top\n            bestLoc = r;\n            for (int ny2: candY2){\n                if (ny2 < r.y1) continue;\n                if (ny2==r.y2) continue;\n                Rect t{r.x1, r.y1, r.x2, ny2, 0};\n                if (rect_perimeter(t.x1,t.y1,t.x2,t.y2) > PERIM_LIMIT) continue;\n                evaluate(t);\n                if (t.score > bestLoc.score || (t.score==bestLoc.score && t.a > bestLoc.a)) bestLoc = t;\n            }\n            if (bestLoc.score > r.score || (bestLoc.score==r.score && bestLoc.a > r.a)){ r = bestLoc; improved = true; }\n        }\n        return r;\n    };\n\n    int refineK = min(30, (int)top.size());\n    // Select top refineK by current exact score\n    sort(top.begin(), top.end(), [](const Rect& A, const Rect& B){\n        if (A.score!=B.score) return A.score>B.score;\n        return A.a>B.a;\n    });\n    top.resize(refineK);\n\n    for (int i=0;i<refineK;i++){\n        Rect r = top[i];\n        Rect rr = refine_rect(r);\n        if (rr.score==LLONG_MIN) evaluate(rr);\n        if (rr.score > best.score || (rr.score==best.score && rr.a > best.a)) best = rr;\n    }\n\n    // Final small random nudges around best\n    {\n        std::uniform_int_distribution<int> d(-1000, 1000);\n        for (int t=0;t<200;t++){\n            int dx1 = d(rng), dx2 = d(rng), dy1 = d(rng), dy2 = d(rng);\n            Rect r{\n                max(0, min(MAXC, best.x1 + dx1)),\n                max(0, min(MAXC, best.y1 + dy1)),\n                max(0, min(MAXC, best.x2 + dx2)),\n                max(0, min(MAXC, best.y2 + dy2)),\n                0\n            };\n            if (r.x1>r.x2) swap(r.x1,r.x2);\n            if (r.y1>r.y2) swap(r.y1,r.y2);\n            if (r.x1==r.x2) { if (r.x2<MAXC) r.x2++; else if (r.x1>0) r.x1--; }\n            if (r.y1==r.y2) { if (r.y2<MAXC) r.y2++; else if (r.y1>0) r.y1--; }\n            if (rect_perimeter(r.x1,r.y1,r.x2,r.y2) > PERIM_LIMIT) continue;\n            evaluate(r);\n            if (r.score > best.score || (r.score==best.score && r.a > best.a)) best = r;\n        }\n    }\n\n    // Output rectangle polygon\n    int x1 = max(0, min(MAXC, best.x1));\n    int y1 = max(0, min(MAXC, best.y1));\n    int x2 = max(0, min(MAXC, best.x2));\n    int y2 = max(0, min(MAXC, best.y2));\n    if (x1==x2){ if (x2<MAXC) x2++; else if (x1>0) x1--; }\n    if (y1==y2){ if (y2<MAXC) y2++; else if (y1>0) y1--; }\n    while (rect_perimeter(x1,y1,x2,y2) > PERIM_LIMIT){\n        if ((x2-x1) >= (y2-y1)){\n            if (x2-x1>1) x2--;\n            else if (y2-y1>1) y2--;\n            else break;\n        } else {\n            if (y2-y1>1) y2--;\n            else if (x2-x1>1) x2--;\n            else break;\n        }\n    }\n    cout << 4 << \"\\n\";\n    cout << x1 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y1 << \"\\n\";\n    cout << x2 << \" \" << y2 << \"\\n\";\n    cout << x1 << \" \" << y2 << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct ColumnState {\n    long long sumH = 0;   // sum of heights in column\n    long long maxW = 0;   // max width in column\n    vector<int> items;    // indices assigned\n};\n\nstruct BuiltLayout {\n    vector<int> col_of;           // column rank (sorted by anchor) for each item\n    vector<int> rot;              // rotation chosen per item (0/1)\n    vector<int> anchor_of_col;    // anchor index per column rank\n    vector<int> prev_anchor;      // previous column's anchor per column rank\n    long long estW = 0, estH = 0;\n    int K = 1;\n};\n\nenum OrderType { BY_HEIGHT=0, BY_WIDTH=1, BY_MIXED=2 };\n\n// Build with stable heuristic + safe post-improvements\nstatic BuiltLayout build_columns(\n    int N, int K,\n    const vector<long long>& w0, const vector<long long>& h0,\n    double alpha, double beta,\n    OrderType ordType,\n    bool do_safe_consolidation\n) {\n    // Precompute both orientations per item\n    vector<long long> hA(N), wA(N), hB(N), wB(N); // A: r=0, B: r=1\n    vector<long long> hMin(N), wMax(N);\n    vector<long double> mixedKey(N);\n    for (int i = 0; i < N; i++) {\n        hA[i] = h0[i]; wA[i] = w0[i];\n        hB[i] = w0[i]; wB[i] = h0[i];\n        hMin[i] = min(h0[i], w0[i]);\n        wMax[i] = max(h0[i], w0[i]);\n        mixedKey[i] = (long double)wMax[i] + 0.25L * (long double)hMin[i];\n    }\n    // Order items\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a, int b){\n        if (ordType == BY_HEIGHT) {\n            if (hMin[a] != hMin[b]) return hMin[a] > hMin[b];\n            if (wMax[a] != wMax[b]) return wMax[a] > wMax[b];\n            return a < b;\n        } else if (ordType == BY_WIDTH) {\n            if (wMax[a] != wMax[b]) return wMax[a] > wMax[b];\n            if (hMin[a] != hMin[b]) return hMin[a] > hMin[b];\n            return a < b;\n        } else {\n            if (mixedKey[a] != mixedKey[b]) return mixedKey[a] > mixedKey[b];\n            return a < b;\n        }\n    });\n\n    vector<ColumnState> cols(K);\n    vector<int> col_of(N, -1);\n    vector<int> rot(N, 0);\n    long long sumW = 0;\n\n    auto estH = [&](){\n        long long mh=0;\n        for (int c=0;c<K;c++) mh = max(mh, cols[c].sumH);\n        return mh;\n    };\n    auto proxy_val = [&](){\n        return sumW + estH();\n    };\n\n    // Assign items greedy with width-aware scoring and rotation choice\n    for (int idx : ord) {\n        int bestC = 0, bestR = 0;\n        long double bestScore = numeric_limits<long double>::infinity();\n        for (int c = 0; c < K; c++) {\n            // r=0\n            {\n                long long newH = cols[c].sumH + hA[idx];\n                long long newMaxW = max(cols[c].maxW, wA[idx]);\n                long long sumW_if = sumW - cols[c].maxW + newMaxW;\n                long double sc = alpha * (long double)newH + beta * (long double)sumW_if;\n                if (sc < bestScore) {\n                    bestScore = sc; bestC = c; bestR = 0;\n                }\n            }\n            // r=1\n            {\n                long long newH = cols[c].sumH + hB[idx];\n                long long newMaxW = max(cols[c].maxW, wB[idx]);\n                long long sumW_if = sumW - cols[c].maxW + newMaxW;\n                long double sc = alpha * (long double)newH + beta * (long double)sumW_if;\n                if (sc < bestScore) {\n                    bestScore = sc; bestC = c; bestR = 1;\n                }\n            }\n        }\n        // commit\n        if (bestR == 0) {\n            cols[bestC].sumH += hA[idx];\n            if (wA[idx] > cols[bestC].maxW) {\n                sumW += (wA[idx] - cols[bestC].maxW);\n                cols[bestC].maxW = wA[idx];\n            }\n        } else {\n            cols[bestC].sumH += hB[idx];\n            if (wB[idx] > cols[bestC].maxW) {\n                sumW += (wB[idx] - cols[bestC].maxW);\n                cols[bestC].maxW = wB[idx];\n            }\n        }\n        cols[bestC].items.push_back(idx);\n        col_of[idx] = bestC;\n        rot[idx] = bestR;\n    }\n\n    // Post-pass: per-item rotation recheck within same column (safe, deterministic)\n    for (int c = 0; c < K; c++) if (!cols[c].items.empty()) {\n        for (int idx : cols[c].items) {\n            long long baseProxy = proxy_val();\n            int r0 = rot[idx];\n            long long h0c = (r0==0 ? hA[idx] : hB[idx]);\n            long long w0c = (r0==0 ? wA[idx] : wB[idx]);\n            int r1 = 1 - r0;\n            long long h1c = (r1==0 ? hA[idx] : hB[idx]);\n            long long w1c = (r1==0 ? wA[idx] : wB[idx]);\n\n            long long oldMax = cols[c].maxW;\n            bool isMax = (w0c == oldMax);\n            long long sumW_if = sumW;\n            long long newMax = oldMax;\n            if (w1c <= oldMax) {\n                if (isMax && w1c < oldMax) {\n                    long long rec=0;\n                    for (int v : cols[c].items) if (v != idx) {\n                        long long wv = (rot[v]==0 ? wA[v] : wB[v]);\n                        if (wv > rec) rec = wv;\n                    }\n                    newMax = max(rec, w1c);\n                    sumW_if += (newMax - oldMax);\n                }\n            } else {\n                newMax = w1c;\n                sumW_if += (newMax - oldMax);\n            }\n            long long estH_if = 0;\n            for (int cc=0; cc<K; cc++) {\n                long long sh = cols[cc].sumH + ((cc==c) ? (h1c - h0c) : 0);\n                if (cc==c) sh = cols[cc].sumH - h0c + h1c;\n                estH_if = max(estH_if, sh);\n            }\n            long long proxy_if = sumW_if + estH_if;\n            if (proxy_if < baseProxy) {\n                cols[c].sumH = cols[c].sumH - h0c + h1c;\n                if (newMax != oldMax) {\n                    cols[c].maxW = newMax;\n                    sumW = sumW_if;\n                }\n                rot[idx] = r1;\n            }\n        }\n    }\n\n    // Safe consolidation: move very wide items to columns with >= maxW or with net sumW decrease\n    if (do_safe_consolidation && K >= 2) {\n        vector<int> items(N);\n        iota(items.begin(), items.end(), 0);\n        sort(items.begin(), items.end(), [&](int a, int b){\n            long long wa = (rot[a]==0 ? wA[a] : wB[a]);\n            long long wb = (rot[b]==0 ? wA[b] : wB[b]);\n            if (wa != wb) return wa > wb;\n            return a < b;\n        });\n        int M = min(N, max(10, N/3));\n        long long baseP0 = proxy_val();\n        long double margin = max(1.0L, 0.001L * (long double)baseP0); // 0.1% margin\n        auto recomputeMax = [&](int c)->long long{\n            long long m=0;\n            for (int v : cols[c].items) {\n                long long wv = (rot[v]==0 ? wA[v] : wB[v]);\n                if (wv > m) m = wv;\n            }\n            return m;\n        };\n        auto countMaxHCols = [&]() -> int {\n            long long mh=0;\n            for (int c=0;c<K;c++) mh = max(mh, cols[c].sumH);\n            int cnt=0;\n            for (int c=0;c<K;c++) if (cols[c].sumH == mh) cnt++;\n            return cnt;\n        };\n        int maxHColsBefore = countMaxHCols();\n\n        for (int t = 0; t < M; t++) {\n            int idx = items[t];\n            int c0 = col_of[idx];\n            long long P0 = proxy_val();\n\n            long long h_contrib = (rot[idx]==0 ? hA[idx] : hB[idx]);\n            long long w_contrib = (rot[idx]==0 ? wA[idx] : wB[idx]);\n\n            // temporarily remove from c0\n            cols[c0].sumH -= h_contrib;\n            auto &vec = cols[c0].items;\n            auto itpos = find(vec.begin(), vec.end(), idx);\n            if (itpos != vec.end()) vec.erase(itpos);\n            long long oldMax_c0 = cols[c0].maxW;\n            long long sumW_after_remove = sumW;\n            bool maxWas = (w_contrib == oldMax_c0);\n            if (maxWas) {\n                long long rec = recomputeMax(c0);\n                sumW_after_remove += (rec - oldMax_c0);\n            }\n\n            long long bestGain = 0;\n            int bestC = c0;\n            int bestR = rot[idx];\n\n            for (int c = 0; c < K; c++) if (c != c0) {\n                for (int rTry = 0; rTry < 2; rTry++) {\n                    long long addH = (rTry==0 ? hA[idx] : hB[idx]);\n                    long long addW = (rTry==0 ? wA[idx] : wB[idx]);\n                    long long oldMaxWc = cols[c].maxW;\n                    long long newMaxWc = max(oldMaxWc, addW);\n                    long long sumW_if = sumW_after_remove - oldMaxWc + newMaxWc;\n                    long long estH_if = 0;\n                    for (int cc=0; cc<K; cc++) {\n                        long long sh = cols[cc].sumH + ((cc==c) ? addH : 0);\n                        estH_if = max(estH_if, sh);\n                    }\n                    long long proxy_if = sumW_if + estH_if;\n                    long long gain = P0 - proxy_if;\n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestC = c;\n                        bestR = rTry;\n                    }\n                }\n            }\n\n            bool commit = false;\n            if (bestGain > margin) {\n                // Also check max-height columns count doesn't increase (stability)\n                int prevCnt = countMaxHCols();\n                // Simulate effect on counts quickly by applying on-the-fly:\n                // We\u2019ll approximate by checking estH_if compared to current mh. If it strictly reduces proxy with margin, accept.\n                commit = true;\n            }\n\n            if (commit) {\n                // commit to bestC\n                rot[idx] = bestR;\n                long long addH = (bestR==0 ? hA[idx] : hB[idx]);\n                long long addW = (bestR==0 ? wA[idx] : wB[idx]);\n                if (maxWas) {\n                    long long rec = recomputeMax(c0);\n                    sumW += (rec - oldMax_c0);\n                    cols[c0].maxW = rec;\n                }\n                cols[bestC].sumH += addH;\n                if (addW > cols[bestC].maxW) {\n                    sumW += (addW - cols[bestC].maxW);\n                    cols[bestC].maxW = addW;\n                }\n                cols[bestC].items.push_back(idx);\n                col_of[idx] = bestC;\n                baseP0 -= bestGain;\n            } else {\n                // revert\n                cols[c0].sumH += h_contrib;\n                if (w_contrib > cols[c0].maxW) {\n                    sumW += (w_contrib - cols[c0].maxW);\n                    cols[c0].maxW = w_contrib;\n                }\n                cols[c0].items.push_back(idx);\n            }\n        }\n    }\n\n    // Determine anchors (min index per original column)\n    vector<int> anchor_orig(K, -1);\n    for (int c = 0; c < K; c++) {\n        if (cols[c].items.empty()) continue;\n        int mn = cols[c].items[0];\n        for (int v : cols[c].items) mn = min(mn, v);\n        anchor_orig[c] = mn;\n    }\n    // Sort columns by anchor index (empty go last)\n    vector<int> col_order(K);\n    iota(col_order.begin(), col_order.end(), 0);\n    sort(col_order.begin(), col_order.end(), [&](int a, int b){\n        int aa = anchor_orig[a], bb = anchor_orig[b];\n        if (aa == -1) return false;\n        if (bb == -1) return true;\n        if (aa != bb) return aa < bb;\n        return a < b;\n    });\n\n    // Build outputs\n    BuiltLayout out;\n    out.K = K;\n    out.col_of.assign(N, -1);\n    out.rot = rot;\n    out.anchor_of_col.assign(K, -1);\n    out.prev_anchor.assign(K, -1);\n    long long estW_final = 0, estH_final = 0;\n    for (int pos = 0; pos < K; pos++) {\n        int c = col_order[pos];\n        if (anchor_orig[c] != -1) out.anchor_of_col[pos] = anchor_orig[c];\n        if (pos > 0) out.prev_anchor[pos] = anchor_orig[col_order[pos-1]];\n        for (int v : cols[c].items) out.col_of[v] = pos;\n        if (!cols[c].items.empty()) {\n            estW_final += cols[c].maxW;\n            estH_final = max(estH_final, cols[c].sumH);\n        }\n    }\n    out.estW = estW_final; out.estH = estH_final;\n    return out;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    long long sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<long long> wp(N), hp(N);\n    for (int i = 0; i < N; i++) cin >> wp[i] >> hp[i];\n\n    // Candidate K and (alpha,beta) and orders\n    vector<int> Ks;\n    vector<int> baseK = {1,2,3,4,5,6,7,8,9,10,11,12};\n    for (int k : baseK) if (k <= N) Ks.push_back(k);\n    if ((int)Ks.size() > T) Ks.resize(T);\n\n    vector<pair<double,double>> AB = {\n        {1.0, 1.0},\n        {2.0, 1.0}\n    };\n    vector<OrderType> ORD = {BY_MIXED, BY_WIDTH, BY_HEIGHT};\n\n    struct Plan { int K; double a, b; OrderType ord; bool consolidate; };\n    vector<Plan> plans;\n\n    // Deterministic, conservative plans\n    for (int k : Ks) {\n        for (auto [a,b] : AB) {\n            for (auto ord : ORD) {\n                bool cons = (ord != BY_HEIGHT); // consolidate when width-aware order\n                plans.push_back({k,a,b,ord,cons});\n            }\n        }\n    }\n    if ((int)plans.size() > T) plans.resize(T);\n    while ((int)plans.size() < T) {\n        plans.push_back({ min(8, max(2, N/8)), 1.0, 1.0, BY_MIXED, true });\n    }\n\n    long long bestProxy = (1LL<<62);\n\n    for (int t = 0; t < T; t++) {\n        auto &pl = plans[t];\n        auto layout = build_columns(N, pl.K, wp, hp, pl.a, pl.b, pl.ord, pl.consolidate);\n        long long proxy = layout.estW + layout.estH;\n        if (proxy < bestProxy) bestProxy = proxy;\n\n        // Emit placement in increasing index order\n        cout << N << '\\n';\n        for (int i = 0; i < N; i++) {\n            int c = layout.col_of[i];\n            int b = -1;\n            if (c > 0) b = layout.prev_anchor[c];\n            cout << i << ' ' << layout.rot[i] << ' ' << 'U' << ' ' << b << '\\n';\n        }\n        cout.flush();\n        long long Wp, Hp;\n        if (!(cin >> Wp >> Hp)) return 0;\n        // Optional debug:\n        // cerr << \"# t=\"<<t<<\" K=\"<<pl.K<<\" proxy=\"<<proxy<<\" obs=\"<<(Wp+Hp)<<\"\\n\";\n    }\n\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Graph {\n    int N;\n    vector<vector<int>> adj;\n};\n\nstatic void sort_adjacency(Graph& g){\n    for(int i=0;i<g.N;i++){\n        auto &v = g.adj[i];\n        sort(v.begin(), v.end());\n        v.erase(unique(v.begin(), v.end()), v.end());\n    }\n}\n\nstatic void multi_source_dist(const Graph& g, const vector<int>& roots, vector<int>& dist){\n    const int INF = 1e9;\n    dist.assign(g.N, INF);\n    deque<int> dq;\n    for(int r: roots){\n        if(dist[r] == 0) continue;\n        dist[r] = 0;\n        dq.push_back(r);\n    }\n    while(!dq.empty()){\n        int u = dq.front(); dq.pop_front();\n        int du = dist[u];\n        for(int v: g.adj[u]){\n            if(dist[v] == INF){\n                dist[v] = du + 1;\n                dq.push_back(v);\n            }\n        }\n    }\n}\n\nstatic void layered_bfs(const Graph& g, const vector<int>& A, const vector<int>& roots,\n                        vector<int>& parent, vector<int>& depth){\n    const int INF = 1e9;\n    parent.assign(g.N, -1);\n    depth.assign(g.N, INF);\n    vector<int> root_of(g.N, -1);\n    vector<int> cur, nxt;\n    cur.reserve(g.N);\n    nxt.reserve(g.N);\n    for(int r: roots){\n        depth[r] = 0;\n        parent[r] = -1;\n        root_of[r] = r;\n        cur.push_back(r);\n    }\n    auto cmpNode = [&](int i, int j){\n        if(A[i] != A[j]) return A[i] < A[j];\n        int di = (int)g.adj[i].size(), dj = (int)g.adj[j].size();\n        if(di != dj) return di < dj;\n        return i < j;\n    };\n    sort(cur.begin(), cur.end(), cmpNode);\n    int d = 0;\n    while(!cur.empty()){\n        for(int u: cur){\n            for(int v: g.adj[u]){\n                if(depth[v] == INF){\n                    depth[v] = d + 1;\n                    parent[v] = u;\n                    root_of[v] = root_of[u];\n                    nxt.push_back(v);\n                }else if(depth[v] == d + 1){\n                    int pu = parent[v];\n                    if(A[u] < A[pu] || (A[u]==A[pu] && (int)g.adj[u].size() < (int)g.adj[pu].size())){\n                        parent[v] = u;\n                        root_of[v] = root_of[u];\n                    }\n                }\n            }\n        }\n        d++;\n        if(nxt.empty()) break;\n        sort(nxt.begin(), nxt.end(), cmpNode);\n        cur.clear();\n        cur.swap(nxt);\n    }\n}\n\nstatic long long score_of(const vector<int>& depth, const vector<int>& A){\n    long long s = 1;\n    int N = (int)depth.size();\n    for(int i=0;i<N;i++){\n        int d = depth[i];\n        if(d < 0 || d > 100000000) d = 0;\n        s += 1LL * (d + 1) * A[i];\n    }\n    return s;\n}\n\n// Greedy roots: ensure all dist<=H, add minimal-A among farthest\nstatic vector<int> build_roots(const Graph& g, const vector<int>& A, int H, int seed){\n    vector<int> roots;\n    roots.push_back(seed);\n    vector<int> dist;\n    multi_source_dist(g, roots, dist);\n    while(true){\n        int far_v = -1;\n        int bestA = INT_MAX;\n        int bestDist = -1;\n        for(int v=0; v<g.N; v++){\n            if(dist[v] > H && dist[v] < INT_MAX){\n                if(A[v] < bestA){\n                    bestA = A[v];\n                    bestDist = dist[v];\n                    far_v = v;\n                }else if(A[v] == bestA && dist[v] > bestDist){\n                    bestDist = dist[v];\n                    far_v = v;\n                }\n            }\n        }\n        if(far_v == -1) break;\n        roots.push_back(far_v);\n        multi_source_dist(g, roots, dist);\n    }\n    return roots;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, H;\n    if(!(cin >> N >> M >> H)) return 0;\n    vector<int> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\n    Graph g;\n    g.N = N;\n    g.adj.assign(N, {});\n    for(int i=0;i<M;i++){\n        int u,v; cin >> u >> v;\n        g.adj[u].push_back(v);\n        g.adj[v].push_back(u);\n    }\n    for(int i=0;i<N;i++){ int x,y; cin >> x >> y; (void)x; (void)y; }\n    sort_adjacency(g);\n\n    // order by ascending A\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j){\n        if(A[i]!=A[j]) return A[i] < A[j];\n        return i < j;\n    });\n\n    // seeds: try several low-A seeds (deterministic)\n    int L_low = min(N, 32);\n    vector<int> seeds;\n    for(int i=0;i<L_low;i++) seeds.push_back(order[i]);\n\n    vector<int> best_parent(N, -1);\n    long long best_score = LLONG_MIN;\n\n    for(int seed: seeds){\n        vector<int> roots = build_roots(g, A, H, seed);\n\n        vector<int> parent, depth;\n        vector<int> root_of_dummy;\n        layered_bfs(g, A, roots, parent, depth);\n\n        // cap depth just in case (shouldn't be needed)\n        for(int i=0;i<N;i++){\n            if(depth[i] > H){\n                parent[i] = -1;\n                depth[i] = 0;\n            }\n        }\n        long long sc = score_of(depth, A);\n        if(sc > best_score){\n            best_score = sc;\n            best_parent = parent;\n        }\n    }\n\n    // Fallback\n    if(best_score == LLONG_MIN){\n        for(int i=0;i<N;i++){\n            if(i) cout << ' ';\n            cout << -1;\n        }\n        cout << '\\n';\n        return 0;\n    }\n\n    for(int i=0;i<N;i++){\n        if(i) cout << ' ';\n        cout << best_parent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    if (!(cin >> N)) return 0;\n    vector<string> C(N);\n    for (int i = 0; i < N; ++i) cin >> C[i];\n\n    // Collect positions and precompute Fukunokami positions.\n    vector<vector<bool>> hasF(N, vector<bool>(N, false));\n    vector<pair<int,int>> oni;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (C[i][j] == 'o') hasF[i][j] = true;\n            else if (C[i][j] == 'x') oni.emplace_back(i, j);\n        }\n    }\n\n    // Precompute prefix counts of Fukunokami per row/column to check rays quickly.\n    vector<vector<int>> rowPref(N, vector<int>(N+1, 0));\n    vector<vector<int>> colPref(N, vector<int>(N+1, 0));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            rowPref[i][j+1] = rowPref[i][j] + (hasF[i][j] ? 1 : 0);\n            colPref[j][i+1] = colPref[j][i] + (hasF[i][j] ? 1 : 0);\n        }\n    }\n\n    auto safe_up = [&](int i, int j)->bool {\n        // No Fukunokami above (rows 0..i-1) in column j\n        if (i == 0) return true;\n        return colPref[j][i] - colPref[j][0] == 0;\n    };\n    auto safe_down = [&](int i, int j)->bool {\n        // No Fukunokami below (rows i+1..N-1) in column j\n        if (i == N-1) return true;\n        return colPref[j][N] - colPref[j][i+1] == 0;\n    };\n    auto safe_left = [&](int i, int j)->bool {\n        if (j == 0) return true;\n        return rowPref[i][j] - rowPref[i][0] == 0;\n    };\n    auto safe_right = [&](int i, int j)->bool {\n        if (j == N-1) return true;\n        return rowPref[i][N] - rowPref[i][j+1] == 0;\n    };\n\n    struct Op { char d; int p; };\n    vector<Op> ops;\n    ops.reserve(1600);\n\n    // For each Oni, pick minimal cost safe direction and emit.\n    for (auto [i, j] : oni) {\n        // Determine available safe directions and their costs.\n        int bestCost = INT_MAX;\n        char bestDir = 0;\n        int param = -1; // row/col index\n\n        // Up\n        if (safe_up(i, j)) {\n            int k = i; // distance to top edge\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'U'; param = j; }\n        }\n        // Down\n        if (safe_down(i, j)) {\n            int k = (N - 1 - i);\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'D'; param = j; }\n        }\n        // Left\n        if (safe_left(i, j)) {\n            int k = j;\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'L'; param = i; }\n        }\n        // Right\n        if (safe_right(i, j)) {\n            int k = (N - 1 - j);\n            int cost = 2 * (k + 1);\n            if (cost < bestCost) { bestCost = cost; bestDir = 'R'; param = i; }\n        }\n\n        // Per problem guarantee, at least one is safe.\n        if (bestDir == 0) {\n            // Fallback: should not happen; do nothing to avoid WA.\n            continue;\n        }\n\n        // Emit k+1 pushes toward bestDir, then k+1 pushes back.\n        int k;\n        char backDir;\n        if (bestDir == 'U') { k = i; backDir = 'D'; }\n        else if (bestDir == 'D') { k = (N - 1 - i); backDir = 'U'; }\n        else if (bestDir == 'L') { k = j; backDir = 'R'; }\n        else { // 'R'\n            k = (N - 1 - j); backDir = 'L';\n        }\n\n        // Ensure we do not exceed 4N^2 operations; with guarantees this should hold.\n        // But add a safety break.\n        if ((int)ops.size() + 2 * (k + 1) > 4 * N * N) break;\n\n        for (int t = 0; t < k + 1; ++t) ops.push_back({bestDir, param});\n        for (int t = 0; t < k + 1; ++t) ops.push_back({backDir, param});\n    }\n\n    // Output\n    for (auto &op : ops) {\n        cout << op.d << ' ' << op.p << '\\n';\n    }\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Timer {\n    chrono::high_resolution_clock::time_point st;\n    Timer(){ reset(); }\n    void reset(){ st = chrono::high_resolution_clock::now(); }\n    double elapsed() const {\n        auto ed = chrono::high_resolution_clock::now();\n        return chrono::duration<double>(ed - st).count();\n    }\n};\n\nstatic inline long long llabsll(long long x){ return x<0?-x:x; }\n\nstruct Solution {\n    vector<int> a, b, t;\n    long long error = (1LL<<60);\n};\n\nstatic inline vector<int> simulate_counts(const vector<int>& a, const vector<int>& b, long long L){\n    int N = (int)a.size();\n    vector<int> t(N,0);\n    int x = 0;\n    for(long long week=0; week<L; week++){\n        t[x]++;\n        int nx = ((t[x] & 1) ? a[x] : b[x]);\n        x = nx;\n    }\n    return t;\n}\nstatic inline long long compute_error(const vector<int>& t, const vector<int>& T){\n    long long e=0;\n    int N = (int)t.size();\n    for(int i=0;i<N;i++) e += llabsll((long long)t[i]-T[i]);\n    return e;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N; long long L;\n    if(!(cin>>N>>L)) return 0;\n    vector<int> T(N);\n    for(int i=0;i<N;i++) cin>>T[i];\n\n    Timer tim;\n    std::mt19937 rng(20250916);\n\n    // Backbone b: a simple ring\n    vector<int> b(N);\n    for(int i=0;i<N;i++) b[i] = (i+1)%N;\n\n    // Approximate usage per source\n    vector<int> d1(N), d0(N);\n    for(int i=0;i<N;i++){ d1[i] = (T[i]+1)/2; d0[i] = T[i]/2; }\n\n    // Helper: recompute over/under lists\n    auto recompute_lists = [&](const vector<int>& t, vector<pair<long long,int>>& over, vector<pair<long long,int>>& under){\n        over.clear(); under.clear();\n        for(int i=0;i<N;i++){\n            long long diff = (long long)t[i] - T[i];\n            if(diff > 0) over.push_back({diff, i});\n            else if(diff < 0) under.push_back({-diff, i});\n        }\n        sort(over.begin(), over.end(), greater<>());\n        sort(under.begin(), under.end(), greater<>());\n    };\n\n    // Build initial a via destination-priority greedy (b-matching-like)\n    auto build_candidate_a = [&](int seed)->vector<int>{\n        vector<int> a(N, -1);\n        // compute b-inflow and a-demands\n        vector<int> b_in(N,0);\n        for(int i=0;i<N;i++) b_in[b[i]] += d0[i];\n        vector<long long> a_dem(N,0);\n        for(int j=0;j<N;j++){\n            long long need = (long long)T[j] - (long long)b_in[j];\n            if(need < 0) need = 0;\n            a_dem[j] = need;\n        }\n        vector<int> a_sup = d1;\n\n        // destination priority queue\n        struct Dest { long long rem; int id; };\n        struct Cmp { bool operator()(const Dest& A, const Dest& B) const {\n            if(A.rem != B.rem) return A.rem < B.rem;\n            return A.id > B.id;\n        } };\n        priority_queue<Dest, vector<Dest>, Cmp> pq;\n        for(int j=0;j<N;j++) pq.push({a_dem[j], j});\n\n        // sources sorted by supply desc with rotation\n        vector<int> src(N); iota(src.begin(), src.end(), 0);\n        int rot = (seed % N);\n        sort(src.begin(), src.end(), [&](int x, int y){\n            if(a_sup[x] != a_sup[y]) return a_sup[x] > a_sup[y];\n            return ((x-rot+N)%N) < ((y-rot+N)%N);\n        });\n\n        // iterator over sources in cycling order for each picked destination\n        deque<int> srcdq(src.begin(), src.end());\n\n        // assignment loop: pick the destination with max remaining demand, assign a source with max supply\n        int guard = 0;\n        while(!pq.empty() && guard < 3*N){\n            guard++;\n            Dest top = pq.top(); pq.pop();\n            if(top.rem <= 0){\n                // all remaining are zero\n                break;\n            }\n            int dst = top.id;\n            // pick a source with largest supply not causing a 2-cycle\n            int picked_s = -1; int picked_idx = -1;\n            // try a handful from front\n            int tries = min((int)srcdq.size(), 12);\n            for(int k=0;k<tries;k++){\n                int s = srcdq[k];\n                if(a_sup[s] <= 0) continue;\n                if(dst == b[s] || dst == s) continue;\n                picked_s = s; picked_idx = k; break;\n            }\n            if(picked_s==-1){\n                // find any with positive supply\n                for(int k=0;k<(int)srcdq.size();k++){\n                    int s = srcdq[k];\n                    if(a_sup[s] <= 0) continue;\n                    if(dst == b[s] || dst == s) continue;\n                    picked_s = s; picked_idx = k; break;\n                }\n            }\n            if(picked_s==-1){\n                // force pick largest supply ignoring constraint\n                for(int k=0;k<(int)srcdq.size();k++){\n                    int s = srcdq[k];\n                    if(a_sup[s] > 0){ picked_s = s; picked_idx = k; break; }\n                }\n            }\n            if(picked_s==-1){\n                // no available sources with supply\n                pq.push(top);\n                break;\n            }\n            // assign dst to picked_s\n            a[picked_s] = dst;\n            long long used = min<long long>(a_sup[picked_s], top.rem);\n            a_sup[picked_s] = 0; // one a per source\n            top.rem -= used;\n            // move picked to back\n            srcdq.erase(srcdq.begin()+picked_idx);\n            srcdq.push_back(picked_s);\n            // push back updated destination\n            pq.push(top);\n        }\n\n        // fill any remaining unassigned sources with near-ring alternatives\n        for(int i=0;i<N;i++){\n            if(a[i] == -1){\n                int cand = (b[i]+2)%N;\n                if(cand==i) cand=(cand+1)%N;\n                if(cand==b[i]) cand=(cand+1)%N;\n                a[i] = cand;\n            }\n            if(a[i] == b[i]){\n                int alt = (b[i]+2)%N;\n                if(alt==i) alt=(alt+1)%N;\n                a[i] = alt;\n            }\n            if(a[i] == i){\n                int alt = (i+2)%N;\n                if(alt==b[i]) alt=(alt+1)%N;\n                if(alt==i) alt=(alt+1)%N;\n                a[i] = alt;\n            }\n        }\n        return a;\n    };\n\n    auto evaluate = [&](const vector<int>& a, const vector<int>& b)->Solution{\n        Solution sol;\n        sol.a = a; sol.b = b;\n        sol.t = simulate_counts(sol.a, sol.b, L);\n        sol.error = compute_error(sol.t, T);\n        return sol;\n    };\n\n    // Multiple initializations with time cap\n    int init_trials = 6;\n    Solution best; best.error = (1LL<<60);\n    vector<int> bestA, bestB, bestT;\n    for(int v=0; v<init_trials; v++){\n        if(tim.elapsed() > 0.6) break;\n        auto a0 = build_candidate_a(v*31 + 7);\n        auto sol = evaluate(a0, b);\n        if(sol.error < best.error){\n            best = sol; bestA = sol.a; bestB = sol.b; bestT = sol.t;\n        }\n    }\n\n    vector<int> a = bestA, t = bestT;\n    long long bestE = best.error;\n\n    // Local search with strict bounds\n    vector<pair<long long,int>> over, under;\n    recompute_lists(t, over, under);\n\n    auto try_redirect = [&](int s, int new_dest)->bool{\n        if(new_dest==b[s] || new_dest==s) return false;\n        if(a[s]==new_dest) return false;\n        int old = a[s];\n        a[s] = new_dest;\n        auto tt = simulate_counts(a,b,L);\n        long long E = compute_error(tt, T);\n        if(E < bestE){\n            bestE = E; t.swap(tt);\n            recompute_lists(t, over, under);\n            return true;\n        }else{\n            a[s] = old;\n            return false;\n        }\n    };\n    auto try_swap = [&](int s1, int s2)->bool{\n        if(s1==s2) return false;\n        int a1=a[s1], a2=a[s2];\n        if(a1==a2) return false;\n        if(a2==b[s1] || a1==b[s2] || a2==s1 || a1==s2) return false;\n        swap(a[s1], a[s2]);\n        auto tt = simulate_counts(a,b,L);\n        long long E = compute_error(tt, T);\n        if(E < bestE){\n            bestE = E; t.swap(tt);\n            recompute_lists(t, over, under);\n            return true;\n        }else{\n            swap(a[s1], a[s2]);\n            return false;\n        }\n    };\n\n    if(!over.empty() && !under.empty()){\n        int redirects_budget = 16;\n        int swaps_budget = 6;\n\n        // Redirects: from top over -> top under\n        for(int oi=0; oi<(int)over.size() && redirects_budget>0; oi++){\n            if(tim.elapsed() > 1.5) break;\n            int dst_over = over[oi].second;\n            // collect sources with a[s]==dst_over\n            vector<int> sources;\n            for(int s=0;s<N;s++) if(a[s]==dst_over) sources.push_back(s);\n            if(sources.empty()) continue;\n            shuffle(sources.begin(), sources.end(), rng);\n            int topu = min(8, (int)under.size());\n            for(int s: sources){\n                for(int ui=0; ui<topu && redirects_budget>0; ui++){\n                    int dst_under = under[ui].second;\n                    if(try_redirect(s, dst_under)){\n                        redirects_budget--;\n                        break;\n                    }\n                }\n                if(redirects_budget<=0 || tim.elapsed()>1.5) break;\n            }\n        }\n        // Swaps\n        recompute_lists(t, over, under);\n        if(!over.empty() && !under.empty()){\n            int topk = min(6, (int)over.size());\n            for(int oi=0; oi<topk && swaps_budget>0; oi++){\n                if(tim.elapsed() > 1.8) break;\n                int dst_over = over[oi].second;\n                vector<int> s_over;\n                for(int s=0;s<N;s++) if(a[s]==dst_over) s_over.push_back(s);\n                if(s_over.empty()) continue;\n                int s1 = s_over[rng()%s_over.size()];\n                int s2 = -1;\n                int topu = min(6, (int)under.size());\n                for(int ui=0; ui<topu && s2==-1; ui++){\n                    int du = under[ui].second;\n                    for(int s=0;s<N;s++){\n                        if(a[s]==du && s!=s1){ s2 = s; break; }\n                    }\n                }\n                if(s2!=-1){\n                    if(try_swap(s1, s2)) swaps_budget--;\n                }\n            }\n        }\n    }\n\n    // Output final plan\n    for(int i=0;i<N;i++){\n        cout<<a[i]<<\" \"<<b[i]<<\"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int n;\n    vector<int> p, r;\n    DSU(int n=0): n(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){ a=find(a); b=find(b); if(a==b) return false; if(r[a]<r[b]) swap(a,b); p[b]=a; if(r[a]==r[b]) r[a]++; return true; }\n};\n\nstatic inline uint32_t part1by1(uint32_t x){\n    x &= 0x0000ffff;\n    x = (x | (x << 8)) & 0x00FF00FF;\n    x = (x | (x << 4)) & 0x0F0F0F0F;\n    x = (x | (x << 2)) & 0x33333333;\n    x = (x | (x << 1)) & 0x55555555;\n    return x;\n}\nstatic inline uint32_t morton2D(uint32_t x, uint32_t y){\n    return (part1by1(y) << 1) | part1by1(x);\n}\n\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    vector<int> cx(N), cy(N);\n    for(int i=0;i<N;i++){\n        cx[i] = (lx[i]+rx[i])>>1;\n        cy[i] = (ly[i]+ry[i])>>1;\n    }\n    auto codeOf = [&](int i)->uint32_t{\n        uint32_t xs = (uint32_t) min(16383, max(0, cx[i]*16383/10000));\n        uint32_t ys = (uint32_t) min(16383, max(0, cy[i]*16383/10000));\n        return morton2D(xs, ys);\n    };\n    auto centerDist = [&](int a, int b)->int{\n        long dx = cx[a]-cx[b];\n        long dy = cy[a]-cy[b];\n        long long d2 = dx*dx + dy*dy;\n        return (int)floor(sqrt((long double)d2));\n    };\n\n    // initial Morton ordering\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a,int b){\n        uint32_t ca=codeOf(a), cb=codeOf(b);\n        if(ca!=cb) return ca<cb;\n        if(cx[a]!=cx[b]) return cx[a]<cx[b];\n        if(cy[a]!=cy[b]) return cy[a]<cy[b];\n        return a<b;\n    });\n\n    // Build boundary cuts with small local optimization without modifying ord array:\n    vector<int> cuts(M+1, 0);\n    for(int i=1;i<=M;i++) cuts[i] = cuts[i-1] + G[i-1];\n    const int S = 5;\n    for(int b=1;b<M;b++){\n        int base = cuts[b];\n        int bestCut = base;\n        long bestScore = LLONG_MAX;\n        for(int cut = base - S; cut <= base + S; cut++){\n            if(cut <= cuts[b-1]) continue;\n            if(cut >= cuts[b+1]) continue;\n            auto safeDist = [&](int i, int j)->int{\n                if(i<0||j<0||i>=N||j>=N) return 1000000;\n                return centerDist(ord[i], ord[j]);\n            };\n            long sc = 0;\n            sc += safeDist(cut-1, cut);\n            sc += safeDist(cut-2, cut);\n            sc += safeDist(cut-1, cut+1);\n            if(sc < bestScore){ bestScore=sc; bestCut=cut; }\n        }\n        int delta = bestCut - base;\n        // apply this delta to all subsequent cuts\n        for(int t=b; t<=M; t++) cuts[t] += delta;\n    }\n    // Build groups by ord and cuts\n    vector<vector<int>> groups(M);\n    for(int k=0;k<M;k++){\n        int l = cuts[k], r = cuts[k+1];\n        l = max(l, 0); r = min(r, N);\n        if(r<l) r=l;\n        groups[k].assign(ord.begin()+l, ord.begin()+r);\n        // if due to constraints it became wrong size, fix by simple fallback slicing from ord\n        if((int)groups[k].size() != G[k]){\n            groups.clear(); groups.resize(M);\n            int p=0;\n            for(int i=0;i<M;i++){\n                for(int t=0;t<G[i];t++) groups[i].push_back(ord[p++]);\n            }\n            break;\n        }\n    }\n\n    int queries_left = Q;\n\n    auto do_query = [&](const vector<int>& C)->vector<pair<int,int>>{\n        int l = (int)C.size();\n        if(l<2) return {};\n        if(l>L) l=L; // safety cap, but we only call with l<=L\n        cout<<\"? \"<<l;\n        for(int i=0;i<l;i++) cout<<\" \"<<C[i];\n        cout<<\"\\n\"<<flush;\n        vector<pair<int,int>> ret;\n        ret.reserve(max(0,l-1));\n        for(int i=0;i<l-1;i++){\n            int a,b; cin>>a>>b;\n            if(a>b) swap(a,b);\n            ret.emplace_back(a,b);\n        }\n        return ret;\n    };\n\n    struct Edge {int u,v,w;};\n\n    // grid-based candidate edges\n    auto grid_candidates = [&](const vector<int>& vs, int cell)->vector<Edge>{\n        int n = (int)vs.size();\n        if(n<=1) return {};\n        unordered_map<long long, vector<int>> bucket;\n        bucket.reserve(n*2);\n        auto key = [&](int x, int y)->long long{\n            long long gx = x / cell;\n            long long gy = y / cell;\n            return (gx<<20) ^ gy;\n        };\n        for(int u: vs){\n            bucket[key(cx[u], cy[u])].push_back(u);\n        }\n        vector<Edge> edges;\n        edges.reserve(n*8);\n        int dxs[9] = {-1,0,1,-1,0,1,-1,0,1};\n        int dys[9] = {-1,-1,-1,0,0,0,1,1,1};\n        for(int u: vs){\n            long long gx = cx[u] / cell;\n            long long gy = cy[u] / cell;\n            vector<pair<int,int>> cand;\n            cand.reserve(24);\n            for(int d=0; d<9; d++){\n                long long nx = gx + dxs[d];\n                long long ny = gy + dys[d];\n                long long k = (nx<<20) ^ ny;\n                auto it = bucket.find(k);\n                if(it==bucket.end()) continue;\n                for(int v: it->second){\n                    if(v==u) continue;\n                    cand.emplace_back(centerDist(u,v), v);\n                }\n            }\n            int take = min((int)cand.size(), 8);\n            if(take>0){\n                nth_element(cand.begin(), cand.begin()+take, cand.end(),\n                            [](const auto& A, const auto& B){ return A.first < B.first; });\n                for(int i=0;i<take;i++){\n                    int a=u,b=cand[i].second; if(a>b) swap(a,b);\n                    edges.push_back({a,b,cand[i].first});\n                }\n            }\n        }\n        sort(edges.begin(), edges.end(), [](const Edge& A,const Edge& B){\n            if(A.u!=B.u) return A.u<B.u;\n            if(A.v!=B.v) return A.v<B.v;\n            return A.w<B.w;\n        });\n        edges.erase(unique(edges.begin(), edges.end(), [](const Edge& A,const Edge& B){\n            return A.u==B.u && A.v==B.v;\n        }), edges.end());\n        return edges;\n    };\n\n    // approximate MST with rich candidates\n    auto approx_mst = [&](const vector<int>& vs)->vector<pair<int,int>>{\n        int n=(int)vs.size();\n        if(n<=1) return {};\n        vector<Edge> edges;\n        edges.reserve(n*28);\n        // Morton\n        vector<pair<uint32_t,int>> marr(n);\n        for(int i=0;i<n;i++) marr[i]={codeOf(vs[i]), vs[i]};\n        sort(marr.begin(), marr.end());\n        vector<int> mseq(n);\n        for(int i=0;i<n;i++) mseq[i]=marr[i].second;\n        // axis\n        vector<int> xseq = vs, yseq = vs;\n        sort(xseq.begin(), xseq.end(), [&](int a,int b){\n            if(cx[a]!=cx[b]) return cx[a]<cx[b];\n            if(cy[a]!=cy[b]) return cy[a]<cy[b];\n            return a<b;\n        });\n        sort(yseq.begin(), yseq.end(), [&](int a,int b){\n            if(cy[a]!=cy[b]) return cy[a]<cy[b];\n            if(cx[a]!=cx[b]) return cx[a]<cx[b];\n            return a<b;\n        });\n        const int mortonWindow=70, mortonK=14, axisWindow=14, axisK=8;\n        for(int i=0;i<n;i++){\n            int u=mseq[i];\n            vector<pair<int,int>> cand; cand.reserve(2*mortonWindow);\n            for(int d=1; d<=mortonWindow; d++){\n                int j=i-d; if(j>=0){ int v=mseq[j]; cand.emplace_back(centerDist(u,v), v); }\n                j=i+d; if(j<n){ int v=mseq[j]; cand.emplace_back(centerDist(u,v), v); }\n            }\n            int take=min((int)cand.size(), mortonK);\n            if(take>0){\n                nth_element(cand.begin(), cand.begin()+take, cand.end(),\n                            [](const auto& A,const auto& B){ return A.first < B.first; });\n                for(int t=0;t<take;t++){\n                    int v=cand[t].second, w=cand[t].first;\n                    int a=u,b=v; if(a>b) swap(a,b);\n                    edges.push_back({a,b,w});\n                }\n            }\n        }\n        auto add_seq = [&](const vector<int>& seq){\n            for(int i=0;i<(int)seq.size();i++){\n                int u=seq[i];\n                vector<pair<int,int>> cand; cand.reserve(2*axisWindow);\n                for(int d=1; d<=axisWindow; d++){\n                    int j=i-d; if(j>=0){ int v=seq[j]; cand.emplace_back(centerDist(u,v), v); }\n                    j=i+d; if(j<(int)seq.size()){ int v=seq[j]; cand.emplace_back(centerDist(u,v), v); }\n                }\n                int take=min((int)cand.size(), axisK);\n                if(take>0){\n                    nth_element(cand.begin(), cand.begin()+take, cand.end(),\n                                [](const auto& A,const auto& B){ return A.first < B.first; });\n                    for(int t=0;t<take;t++){\n                        int v=cand[t].second, w=cand[t].first;\n                        int a=u,b=v; if(a>b) swap(a,b);\n                        edges.push_back({a,b,w});\n                    }\n                }\n            }\n        };\n        add_seq(xseq);\n        add_seq(yseq);\n        int cell = max(400, min(1200, W));\n        auto gridE = grid_candidates(vs, cell);\n        edges.insert(edges.end(), gridE.begin(), gridE.end());\n\n        sort(edges.begin(), edges.end(), [&](const Edge& A,const Edge& B){\n            if(A.u!=B.u) return A.u<B.u;\n            if(A.v!=B.v) return A.v<B.v;\n            return A.w<B.w;\n        });\n        edges.erase(unique(edges.begin(), edges.end(), [&](const Edge& A,const Edge& B){\n            return A.u==B.u && A.v==B.v;\n        }), edges.end());\n\n        DSU dsu(N);\n        sort(edges.begin(), edges.end(), [&](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        vector<pair<int,int>> res; res.reserve(n-1);\n        for(const auto &e: edges){\n            if(dsu.unite(e.u,e.v)){\n                res.emplace_back(e.u,e.v);\n                if((int)res.size()==n-1) break;\n            }\n        }\n        if((int)res.size()<n-1){\n            for(int i=0;i<n-1;i++){\n                int a=mseq[i], b=mseq[i+1];\n                if(dsu.unite(a,b)){\n                    if(a>b) swap(a,b);\n                    res.emplace_back(a,b);\n                }\n            }\n        }\n        if((int)res.size()>n-1) res.resize(n-1);\n        return res;\n    };\n\n    // Block MST with strict query accounting: will only query if queries_left >= blocks\n    auto block_mst = [&](const vector<int>& vs, int &queries_left_ref)->vector<pair<int,int>>{\n        int n=(int)vs.size();\n        if(n<=1) return {};\n        vector<pair<uint32_t,int>> marr(n);\n        for(int i=0;i<n;i++) marr[i]={codeOf(vs[i]), vs[i]};\n        sort(marr.begin(), marr.end());\n        vector<int> orderLoc(n);\n        for(int i=0;i<n;i++) orderLoc[i]=marr[i].second;\n        vector<vector<int>> blocks;\n        for(int i=0;i<n;i+=L){\n            int r=min(n, i+L);\n            vector<int> blk; blk.reserve(r-i);\n            for(int j=i;j<r;j++) blk.push_back(orderLoc[j]);\n            blocks.push_back(move(blk));\n        }\n        int B=(int)blocks.size();\n        if(B<=queries_left_ref){\n            vector<pair<int,int>> intra;\n            for(int b=0;b<B;b++){\n                if((int)blocks[b].size()<=1) continue;\n                auto e = do_query(blocks[b]);\n                queries_left_ref--; // consume here\n                intra.insert(intra.end(), e.begin(), e.end());\n            }\n            // connect blocks approximately\n            struct Edge{int u,v,w;};\n            vector<Edge> inter;\n            auto add_best_between = [&](const vector<int>& A, const vector<int>& B, int capPairs){\n                vector<int> aCand, bCand;\n                int ca=min(6,(int)A.size()), cb=min(6,(int)B.size());\n                for(int t=0;t<ca;t++){\n                    int idx = (int)llround((double)t*(A.size()-1)/max(1,ca-1));\n                    aCand.push_back(A[idx]);\n                }\n                for(int t=0;t<cb;t++){\n                    int idx = (int)llround((double)t*(B.size()-1)/max(1,cb-1));\n                    bCand.push_back(B[idx]);\n                }\n                vector<Edge> local;\n                for(int a: aCand) for(int b: bCand){\n                    int w=centerDist(a,b);\n                    int u=a,v=b; if(u>v) swap(u,v);\n                    local.push_back({u,v,w});\n                }\n                sort(local.begin(), local.end(), [](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                int take=min((int)local.size(), capPairs);\n                for(int i=0;i<take;i++) inter.push_back(local[i]);\n            };\n            for(int b=0;b<B-1;b++) add_best_between(blocks[b], blocks[b+1], 3);\n            for(int b=0;b<B-2;b++) add_best_between(blocks[b], blocks[b+2], 1);\n\n            vector<tuple<int,int,int>> edges; edges.reserve(intra.size()+inter.size());\n            for(auto &p: intra){\n                int w=centerDist(p.first,p.second);\n                edges.emplace_back(w, min(p.first,p.second), max(p.first,p.second));\n            }\n            for(auto &e: inter){\n                edges.emplace_back(e.w, e.u, e.v);\n            }\n            sort(edges.begin(), edges.end());\n            DSU dsu(N);\n            vector<pair<int,int>> res; res.reserve(n-1);\n            for(auto &t: edges){\n                int u=get<1>(t), v=get<2>(t);\n                if(dsu.unite(u,v)){\n                    res.emplace_back(u,v);\n                    if((int)res.size()==n-1) break;\n                }\n            }\n            if((int)res.size()<n-1){\n                for(int i=0;i<n-1;i++){\n                    int a=orderLoc[i], b=orderLoc[i+1];\n                    if(dsu.unite(a,b)){\n                        if(a>b) swap(a,b);\n                        res.emplace_back(a,b);\n                    }\n                }\n            }\n            if((int)res.size()>n-1) res.resize(n-1);\n            return res;\n        }else{\n            return approx_mst(vs);\n        }\n    };\n\n    // Micro-queries: t subsets of size L; consume queries_left accordingly and return anchors\n    auto micro_queries = [&](const vector<int>& vs, int t, int &queries_left_ref)->vector<pair<int,int>>{\n        vector<pair<int,int>> anchors;\n        int n=(int)vs.size();\n        if(n<=1 || t<=0) return anchors;\n        vector<pair<uint32_t,int>> marr(n);\n        for(int i=0;i<n;i++) marr[i]={codeOf(vs[i]), vs[i]};\n        sort(marr.begin(), marr.end());\n        vector<int> seq(n);\n        for(int i=0;i<n;i++) seq[i]=marr[i].second;\n        t = min(t, queries_left_ref);\n        for(int s=0; s<t; s++){\n            vector<int> subset; subset.reserve(L);\n            long long start = (long long)s * n / t;\n            for(int j=0;j<L;j++){\n                long long idx = (start + (long long)j * n / L) % n;\n                subset.push_back(seq[(int)idx]);\n            }\n            auto e = do_query(subset);\n            queries_left_ref--;\n            anchors.insert(anchors.end(), e.begin(), e.end());\n        }\n        return anchors;\n    };\n\n    // Query planning strictly with per-group counts\n    vector<int> plan(M, 0); // 0=approx, 1=whole, 2=block, 3=approx+micro\n    vector<int> micro_cnt(M, 0);\n\n    // First: whole-group for small\n    for(int k=0;k<M;k++){\n        if((int)groups[k].size()<=L && queries_left>=1){\n            plan[k]=1;\n            queries_left -= 1; // reserve\n        }\n    }\n    // Medium: block if affordable now\n    for(int k=0;k<M;k++){\n        if(plan[k]!=0) continue;\n        int sz = (int)groups[k].size();\n        if(sz>L && sz<=3*L){\n            int need = (sz+L-1)/L;\n            if(queries_left>=need){\n                plan[k]=2;\n                queries_left -= need; // reserve\n            }\n        }\n    }\n    // Distribute remaining queries to large groups as micro anchors, 1 each in round-robin\n    vector<int> largeIdx;\n    for(int k=0;k<M;k++){\n        if(plan[k]==0 && (int)groups[k].size()>3*L) largeIdx.push_back(k);\n    }\n    int ptr=0;\n    while(queries_left>0 && !largeIdx.empty()){\n        int k = largeIdx[ptr];\n        micro_cnt[k] += 1;\n        queries_left -= 1;\n        ptr++; if(ptr>=(int)largeIdx.size()) ptr=0;\n    }\n    // Note: We reserved queries in planning; during construction we will not consume again. To keep accounting consistent,\n    // we introduce a local variable local_queries_left = planned_reserved + remaining actual Q at construction time\n    int local_queries_left = Q;\n\n    // Build edges per group\n    vector<vector<pair<int,int>>> group_edges(M);\n    for(int k=0;k<M;k++){\n        const auto& g = groups[k];\n        int sz = (int)g.size();\n        if(sz<=1){ group_edges[k]={}; continue; }\n        if(plan[k]==1){\n            // whole group query\n            // consume one query from local_queries_left (must be >=1)\n            if(local_queries_left>=1){\n                auto e = do_query(g);\n                local_queries_left -= 1;\n                group_edges[k]=e;\n            }else{\n                group_edges[k]=approx_mst(g);\n            }\n        }else if(plan[k]==2){\n            // block queries\n            group_edges[k] = block_mst(g, local_queries_left);\n        }else if(micro_cnt[k]>0){\n            auto anchors = micro_queries(g, micro_cnt[k], local_queries_left);\n            auto approx = approx_mst(g);\n            struct T {int w,u,v,t;};\n            vector<T> E; E.reserve(anchors.size()+approx.size());\n            for(auto &p: anchors){\n                int w=centerDist(p.first,p.second);\n                E.push_back({w, min(p.first,p.second), max(p.first,p.second), 0});\n            }\n            for(auto &p: approx){\n                int w=centerDist(p.first,p.second);\n                E.push_back({w, min(p.first,p.second), max(p.first,p.second), 1});\n            }\n            sort(E.begin(), E.end(), [](const T& A,const T& B){\n                if(A.w!=B.w) return A.w<B.w;\n                if(A.t!=B.t) return A.t<B.t;\n                if(A.u!=B.u) return A.u<B.u;\n                return A.v<B.v;\n            });\n            DSU dsu(N);\n            vector<pair<int,int>> res; res.reserve(sz-1);\n            for(auto &e: E){\n                if(dsu.unite(e.u,e.v)){\n                    res.emplace_back(e.u,e.v);\n                    if((int)res.size()==sz-1) break;\n                }\n            }\n            if((int)res.size()<sz-1){\n                // fallback simple chain within group order g (which is contiguous in ord)\n                for(int i=0;i<sz-1;i++){\n                    int a=g[i], b=g[i+1];\n                    if(dsu.unite(a,b)){\n                        if(a>b) swap(a,b);\n                        res.emplace_back(a,b);\n                    }\n                }\n            }\n            if((int)res.size()>sz-1) res.resize(sz-1);\n            group_edges[k]=res;\n        }else{\n            group_edges[k]=approx_mst(g);\n        }\n        // safety: enforce endpoints belong to group and count exact sz-1\n        if((int)group_edges[k].size() < sz-1){\n            // fill with chain\n            DSU dsu2(N);\n            for(auto &e: group_edges[k]) dsu2.unite(e.first, e.second);\n            for(int i=0;i<sz-1 && (int)group_edges[k].size()<sz-1;i++){\n                int a=g[i], b=g[i+1];\n                if(dsu2.unite(a,b)){\n                    if(a>b) swap(a,b);\n                    group_edges[k].push_back({a,b});\n                }\n            }\n        }else if((int)group_edges[k].size() > sz-1){\n            group_edges[k].resize(sz-1);\n        }\n    }\n\n    // Final output\n    cout<<\"!\"<<\"\\n\";\n    for(int k=0;k<M;k++){\n        const auto& g = groups[k];\n        for(int i=0;i<(int)g.size();i++){\n            if(i) cout<<\" \";\n            cout<<g[i];\n        }\n        cout<<\"\\n\";\n        for(auto &e: group_edges[k]){\n            cout<<e.first<<\" \"<<e.second<<\"\\n\";\n        }\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int i,j; };\nint N,M;\nvector<Pos> targets;\nvector<string> out_actions;\n\nenum Dir {U=0,D=1,L=2,R=3};\nconst int di[4] = {-1,1,0,0};\nconst int dj[4] = {0,0,-1,1};\nchar dirChar(Dir d){ return d==U?'U':d==D?'D':d==L?'L':'R'; }\ninline bool inb(int i,int j,int N){ return 0<=i && i<N && 0<=j && j<N; }\n\nstruct Grid {\n    int N;\n    vector<uint8_t> blk;\n    Grid(int N=0):N(N),blk(N*N,0){}\n    inline bool isBlock(int i,int j) const { return blk[i*N+j]; }\n} grid;\n\nvoid emit_to(vector<string> &outv, char act, Dir d){\n    string s; s+=act; s+=' '; s+=dirChar(d);\n    outv.push_back(s);\n}\n\nbool try_move(Pos &p, Dir d, vector<string> *outv){\n    int ni=p.i+di[d], nj=p.j+dj[d];\n    if(!inb(ni,nj,N)) return false;\n    if(grid.isBlock(ni,nj)) return false;\n    if(outv) emit_to(*outv,'M',d);\n    p.i=ni; p.j=nj;\n    return true;\n}\n\nPos simulate_slide_pos(const Pos &p, Dir d){\n    int i=p.i, j=p.j;\n    while(true){\n        int ni=i+di[d], nj=j+dj[d];\n        if(!inb(ni,nj,N)) break;\n        if(grid.isBlock(ni,nj)) break;\n        i=ni; j=nj;\n    }\n    return {i,j};\n}\nvoid do_slide(Pos &p, Dir d, vector<string> *outv){\n    if(outv) emit_to(*outv,'S',d);\n    p = simulate_slide_pos(p,d);\n}\n\nbool can_land_by_slide_to_target(const Pos &p, const Pos &t, Dir &d_out){\n    if(p.i==t.i){\n        if(t.j==0 && t.j<p.j){ d_out = L; return true; }\n        if(t.j==N-1 && t.j>p.j){ d_out = R; return true; }\n    }\n    if(p.j==t.j){\n        if(t.i==0 && t.i<p.i){ d_out = U; return true; }\n        if(t.i==N-1 && t.i>p.i){ d_out = D; return true; }\n    }\n    return false;\n}\n\n// orderMode: 0 = prioritize larger delta, 1 = vertical-first, 2 = horizontal-first\nvoid move_with_opportunistic_slide(Pos &p, const Pos &t, vector<string> *outv, int orderMode){\n    while(!(p.i==t.i && p.j==t.j)){\n        Dir sd;\n        if(can_land_by_slide_to_target(p, t, sd)){\n            do_slide(p, sd, outv);\n            return;\n        }\n        Dir d;\n        if(orderMode==1){\n            if(p.i != t.i) d = (p.i < t.i) ? D : U;\n            else d = (p.j < t.j) ? R : L;\n        }else if(orderMode==2){\n            if(p.j != t.j) d = (p.j < t.j) ? R : L;\n            else d = (p.i < t.i) ? D : U;\n        }else{\n            if(abs(p.i - t.i) >= abs(p.j - t.j)){\n                d = (p.i < t.i) ? D : U;\n            }else{\n                d = (p.j < t.j) ? R : L;\n            }\n        }\n        if(!try_move(p,d,outv)){\n            bool moved=false;\n            for(int k=0;k<4;k++){\n                if(try_move(p,(Dir)k,outv)){ moved=true; break; }\n            }\n            if(!moved) break;\n        }\n    }\n}\n\nint simulate_moves_only(const Pos &start, const Pos &t){\n    int best = INT_MAX;\n    for(int mode=0; mode<3; ++mode){\n        Pos cur = start;\n        vector<string> tmp;\n        move_with_opportunistic_slide(cur, t, &tmp, mode);\n        if(!(cur.i==t.i && cur.j==t.j)){\n            move_with_opportunistic_slide(cur, t, &tmp, mode);\n        }\n        best = min(best, (int)tmp.size());\n    }\n    return best;\n}\n\nint simulate_single_slide_if_possible(const Pos &start, const Pos &t){\n    Dir d;\n    if(!can_land_by_slide_to_target(start, t, d)) return INT_MAX/4;\n    Pos cur = start;\n    vector<string> tmp;\n    do_slide(cur, d, &tmp);\n    if(!(cur.i==t.i && cur.j==t.j)) return INT_MAX/4;\n    return (int)tmp.size();\n}\n\n// After a first slide in two-slide plans, check for early finish\nstatic inline void early_finish_after_first_slide(Pos &cur, const Pos &t, vector<string> *tmp){\n    if(cur.i==t.i && cur.j==t.j) return;\n    Dir sd;\n    if(can_land_by_slide_to_target(cur, t, sd)){\n        do_slide(cur, sd, tmp);\n        return;\n    }\n    // If adjacent, single move\n    if(abs(cur.i - t.i) + abs(cur.j - t.j) == 1){\n        Dir d;\n        if(t.i < cur.i) d=U;\n        else if(t.i > cur.i) d=D;\n        else if(t.j < cur.j) d=L;\n        else d=R;\n        try_move(cur, d, tmp);\n    }\n}\n\nint simulate_horizontal_two_slides(const Pos &start, const Pos &t, bool leftFirst){\n    Pos cur = start;\n    vector<string> tmp;\n    while(cur.i != t.i){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n            break;\n        }\n        Dir d = (cur.i < t.i) ? D : U;\n        if(!try_move(cur,d,&tmp)) return INT_MAX/4;\n    }\n    if(cur.i==t.i && !(cur.j==t.j)){\n        if(leftFirst){\n            if(cur.j > 0) do_slide(cur, L, &tmp);\n            early_finish_after_first_slide(cur, t, &tmp);\n            if(!(cur.i==t.i && cur.j==t.j) && cur.j <= t.j) do_slide(cur, R, &tmp);\n        }else{\n            if(cur.j < N-1) do_slide(cur, R, &tmp);\n            early_finish_after_first_slide(cur, t, &tmp);\n            if(!(cur.i==t.i && cur.j==t.j) && cur.j >= t.j) do_slide(cur, L, &tmp);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &tmp, 0);\n    }\n    return (int)tmp.size();\n}\n\nint simulate_horizontal_one_slide(const Pos &start, const Pos &t){\n    Pos cur = start;\n    vector<string> tmp;\n    while(cur.i != t.i){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n            break;\n        }\n        Dir d = (cur.i < t.i) ? D : U;\n        if(!try_move(cur,d,&tmp)) return INT_MAX/4;\n    }\n    if(cur.i==t.i && !(cur.j==t.j)){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n        }else{\n            move_with_opportunistic_slide(cur, t, &tmp, 0);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &tmp, 0);\n    }\n    return (int)tmp.size();\n}\n\nint simulate_vertical_two_slides(const Pos &start, const Pos &t, bool upFirst){\n    Pos cur = start;\n    vector<string> tmp;\n    while(cur.j != t.j){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n            break;\n        }\n        Dir d = (cur.j < t.j) ? R : L;\n        if(!try_move(cur,d,&tmp)) return INT_MAX/4;\n    }\n    if(cur.j==t.j && !(cur.i==t.i)){\n        if(upFirst){\n            if(cur.i > 0) do_slide(cur, U, &tmp);\n            early_finish_after_first_slide(cur, t, &tmp);\n            if(!(cur.i==t.i && cur.j==t.j) && cur.i <= t.i) do_slide(cur, D, &tmp);\n        }else{\n            if(cur.i < N-1) do_slide(cur, D, &tmp);\n            early_finish_after_first_slide(cur, t, &tmp);\n            if(!(cur.i==t.i && cur.j==t.j) && cur.i >= t.i) do_slide(cur, U, &tmp);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &tmp, 0);\n    }\n    return (int)tmp.size();\n}\n\nint simulate_vertical_one_slide(const Pos &start, const Pos &t){\n    Pos cur = start;\n    vector<string> tmp;\n    while(cur.j != t.j){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n            break;\n        }\n        Dir d = (cur.j < t.j) ? R : L;\n        if(!try_move(cur,d,&tmp)) return INT_MAX/4;\n    }\n    if(cur.j==t.j && !(cur.i==t.i)){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n        }else{\n            move_with_opportunistic_slide(cur, t, &tmp, 0);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &tmp, 0);\n    }\n    return (int)tmp.size();\n}\n\n// New: one-slide-then-moves variants after alignment\nint simulate_horizontal_one_slide_then_moves(const Pos &start, const Pos &t, bool toLeft){\n    Pos cur = start;\n    vector<string> tmp;\n    // Align row\n    while(cur.i != t.i){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n            break;\n        }\n        Dir d = (cur.i < t.i) ? D : U;\n        if(!try_move(cur,d,&tmp)) return INT_MAX/4;\n    }\n    if(cur.i==t.i && !(cur.j==t.j)){\n        if(toLeft){\n            if(cur.j > 0) do_slide(cur, L, &tmp);\n        }else{\n            if(cur.j < N-1) do_slide(cur, R, &tmp);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &tmp, 0);\n    }\n    return (int)tmp.size();\n}\n\nint simulate_vertical_one_slide_then_moves(const Pos &start, const Pos &t, bool toUp){\n    Pos cur = start;\n    vector<string> tmp;\n    while(cur.j != t.j){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &tmp);\n            break;\n        }\n        Dir d = (cur.j < t.j) ? R : L;\n        if(!try_move(cur,d,&tmp)) return INT_MAX/4;\n    }\n    if(cur.j==t.j && !(cur.i==t.i)){\n        if(toUp){\n            if(cur.i > 0) do_slide(cur, U, &tmp);\n        }else{\n            if(cur.i < N-1) do_slide(cur, D, &tmp);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &tmp, 0);\n    }\n    return (int)tmp.size();\n}\n\n// Pivot-based: move to a pivot that shares target line enabling one final slide to border target\nint simulate_pivot_final_slide(const Pos &start, const Pos &t){\n    bool borderH = (t.j==0 || t.j==N-1);\n    bool borderV = (t.i==0 || t.i==N-1);\n    if(!borderH && !borderV) return INT_MAX/4;\n\n    int best = INT_MAX;\n    vector<Pos> pivots;\n\n    if(borderH){\n        int ii = t.i;\n        vector<int> js = {0, N-1, start.j, (N-1)/2, N/2, (start.j>0?start.j-1:start.j), (start.j<N-1?start.j+1:start.j)};\n        for(int j: js){\n            if(!inb(ii,j,N)) continue;\n            if(j==t.j) continue;\n            pivots.push_back({ii,j});\n        }\n    }\n    if(borderV){\n        int jj = t.j;\n        vector<int> is = {0, N-1, start.i, (N-1)/2, N/2, (start.i>0?start.i-1:start.i), (start.i<N-1?start.i+1:start.i)};\n        for(int i: is){\n            if(!inb(i,jj,N)) continue;\n            if(i==t.i) continue;\n            pivots.push_back({i,jj});\n        }\n    }\n    sort(pivots.begin(), pivots.end(), [](const Pos&a,const Pos&b){ if(a.i!=b.i) return a.i<b.i; return a.j<b.j;});\n    pivots.erase(unique(pivots.begin(), pivots.end(), [](const Pos&a,const Pos&b){ return a.i==b.i && a.j==b.j; }), pivots.end());\n\n    for(const auto &pv: pivots){\n        Pos cur = start;\n        vector<string> tmp;\n        // Move to pivot with best of three orders\n        int bestMode = 0, bestLocal = INT_MAX;\n        for(int mode=0; mode<3; ++mode){\n            Pos tp = cur;\n            vector<string> tout;\n            move_with_opportunistic_slide(tp, pv, &tout, mode);\n            if(!(tp.i==pv.i && tp.j==pv.j)){\n                move_with_opportunistic_slide(tp, pv, &tout, mode);\n            }\n            if((int)tout.size() < bestLocal){\n                bestLocal = (int)tout.size();\n                bestMode = mode;\n            }\n        }\n        move_with_opportunistic_slide(cur, pv, &tmp, bestMode);\n        if(!(cur.i==pv.i && cur.j==pv.j)){\n            move_with_opportunistic_slide(cur, pv, &tmp, bestMode);\n        }\n        Dir d;\n        if(!can_land_by_slide_to_target(cur, t, d)) continue;\n        do_slide(cur, d, &tmp);\n        if(cur.i==t.i && cur.j==t.j){\n            best = min(best, (int)tmp.size());\n        }\n    }\n    return best;\n}\n\nvoid exec_pivot_final_slide(Pos &cur, const Pos &t){\n    bool borderH = (t.j==0 || t.j==N-1);\n    bool borderV = (t.i==0 || t.i==N-1);\n    vector<Pos> pivots;\n    if(borderH){\n        int ii = t.i;\n        vector<int> js = {0, N-1, cur.j, (N-1)/2, N/2, (cur.j>0?cur.j-1:cur.j), (cur.j<N-1?cur.j+1:cur.j)};\n        for(int j: js){\n            if(!inb(ii,j,N)) continue;\n            if(j==t.j) continue;\n            pivots.push_back({ii,j});\n        }\n    }\n    if(borderV){\n        int jj = t.j;\n        vector<int> is = {0, N-1, cur.i, (N-1)/2, N/2, (cur.i>0?cur.i-1:cur.i), (cur.i<N-1?cur.i+1:cur.i)};\n        for(int i: is){\n            if(!inb(i,jj,N)) continue;\n            if(i==t.i) continue;\n            pivots.push_back({i,jj});\n        }\n    }\n    sort(pivots.begin(), pivots.end(), [](const Pos&a,const Pos&b){ if(a.i!=b.i) return a.i<b.i; return a.j<b.j;});\n    pivots.erase(unique(pivots.begin(), pivots.end(), [](const Pos&a,const Pos&b){ return a.i==b.i && a.j==b.j; }), pivots.end());\n\n    int bestCost = INT_MAX; Pos bestPv = cur; int bestMode=0;\n    for(const auto &pv: pivots){\n        for(int mode=0; mode<3; ++mode){\n            Pos tp = cur;\n            vector<string> tmp;\n            move_with_opportunistic_slide(tp, pv, &tmp, mode);\n            if(!(tp.i==pv.i && tp.j==pv.j)){\n                move_with_opportunistic_slide(tp, pv, &tmp, mode);\n            }\n            if(!(tp.i==pv.i && tp.j==pv.j)) continue;\n            Dir d; if(!can_land_by_slide_to_target(pv, t, d)) continue;\n            int cst = (int)tmp.size() + 1;\n            if(cst < bestCost){\n                bestCost = cst; bestPv = pv; bestMode = mode;\n            }\n        }\n    }\n    move_with_opportunistic_slide(cur, bestPv, &out_actions, bestMode);\n    if(!(cur.i==bestPv.i && cur.j==bestPv.j)){\n        move_with_opportunistic_slide(cur, bestPv, &out_actions, bestMode);\n    }\n    Dir d; if(can_land_by_slide_to_target(cur, t, d)) do_slide(cur, d, &out_actions);\n}\n\n// Executors for main plans\nvoid exec_moves_only(Pos &cur, const Pos &t){\n    int best = INT_MAX, bestMode = 0;\n    for(int mode=0; mode<3; ++mode){\n        Pos tmpPos = cur;\n        vector<string> tmp;\n        move_with_opportunistic_slide(tmpPos, t, &tmp, mode);\n        if(!(tmpPos.i==t.i && tmpPos.j==t.j)){\n            move_with_opportunistic_slide(tmpPos, t, &tmp, mode);\n        }\n        if((int)tmp.size() < best){ best=(int)tmp.size(); bestMode=mode; }\n    }\n    move_with_opportunistic_slide(cur, t, &out_actions, bestMode);\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &out_actions, bestMode);\n    }\n}\nvoid exec_horizontal_two_slides(Pos &cur, const Pos &t, bool leftFirst){\n    while(cur.i != t.i){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &out_actions);\n            break;\n        }\n        Dir d = (cur.i < t.i) ? D : U;\n        try_move(cur,d,&out_actions);\n    }\n    if(cur.i==t.i && !(cur.j==t.j)){\n        if(leftFirst){\n            if(cur.j > 0) do_slide(cur, L, &out_actions);\n            early_finish_after_first_slide(cur, t, &out_actions);\n            if(!(cur.i==t.i && cur.j==t.j) && cur.j <= t.j) do_slide(cur, R, &out_actions);\n        }else{\n            if(cur.j < N-1) do_slide(cur, R, &out_actions);\n            early_finish_after_first_slide(cur, t, &out_actions);\n            if(!(cur.i==t.i && cur.j==t.j) && cur.j >= t.j) do_slide(cur, L, &out_actions);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &out_actions, 0);\n    }\n}\nvoid exec_horizontal_one_slide(Pos &cur, const Pos &t){\n    while(cur.i != t.i){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &out_actions);\n            break;\n        }\n        Dir d = (cur.i < t.i) ? D : U;\n        try_move(cur,d,&out_actions);\n    }\n    if(cur.i==t.i && !(cur.j==t.j)){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &out_actions);\n        }else{\n            move_with_opportunistic_slide(cur, t, &out_actions, 0);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &out_actions, 0);\n    }\n}\nvoid exec_vertical_two_slides(Pos &cur, const Pos &t, bool upFirst){\n    while(cur.j != t.j){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &out_actions);\n            break;\n        }\n        Dir d = (cur.j < t.j) ? R : L;\n        try_move(cur,d,&out_actions);\n    }\n    if(cur.j==t.j && !(cur.i==t.i)){\n        if(upFirst){\n            if(cur.i > 0) do_slide(cur, U, &out_actions);\n            early_finish_after_first_slide(cur, t, &out_actions);\n            if(!(cur.i==t.i && cur.j==t.j) && cur.i <= t.i) do_slide(cur, D, &out_actions);\n        }else{\n            if(cur.i < N-1) do_slide(cur, D, &out_actions);\n            early_finish_after_first_slide(cur, t, &out_actions);\n            if(!(cur.i==t.i && cur.j==t.j) && cur.i >= t.i) do_slide(cur, U, &out_actions);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &out_actions, 0);\n    }\n}\nvoid exec_vertical_one_slide(Pos &cur, const Pos &t){\n    while(cur.j != t.j){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &out_actions);\n            break;\n        }\n        Dir d = (cur.j < t.j) ? R : L;\n        try_move(cur,d,&out_actions);\n    }\n    if(cur.j==t.j && !(cur.i==t.i)){\n        Dir sd;\n        if(can_land_by_slide_to_target(cur, t, sd)){\n            do_slide(cur, sd, &out_actions);\n        }else{\n            move_with_opportunistic_slide(cur, t, &out_actions, 0);\n        }\n    }\n    if(!(cur.i==t.i && cur.j==t.j)){\n        move_with_opportunistic_slide(cur, t, &out_actions, 0);\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    if(!(cin>>N>>M)) return 0;\n    targets.resize(M);\n    for(int k=0;k<M;k++) cin>>targets[k].i>>targets[k].j;\n    grid = Grid(N);\n    Pos cur = targets[0];\n\n    for(int k=1;k<M;k++){\n        Pos t = targets[k];\n\n        int bestCost = INT_MAX;\n        int bestPlan = 0;\n\n        // 0 moves-only\n        int c0 = simulate_moves_only(cur, t);\n        bestCost=c0; bestPlan=0;\n\n        // 1 single slide immediate\n        int c1 = simulate_single_slide_if_possible(cur, t);\n        if(c1 < bestCost){ bestCost=c1; bestPlan=1; }\n\n        // 2 H-one-slide, 3 H-two-left, 4 H-two-right\n        int c2 = simulate_horizontal_one_slide(cur, t);\n        if(c2 < bestCost){ bestCost=c2; bestPlan=2; }\n        int c3 = simulate_horizontal_two_slides(cur, t, true);\n        if(c3 < bestCost){ bestCost=c3; bestPlan=3; }\n        int c4 = simulate_horizontal_two_slides(cur, t, false);\n        if(c4 < bestCost){ bestCost=c4; bestPlan=4; }\n\n        // 5 V-one-slide, 6 V-two-up, 7 V-two-down\n        int c5 = simulate_vertical_one_slide(cur, t);\n        if(c5 < bestCost){ bestCost=c5; bestPlan=5; }\n        int c6 = simulate_vertical_two_slides(cur, t, true);\n        if(c6 < bestCost){ bestCost=c6; bestPlan=6; }\n        int c7 = simulate_vertical_two_slides(cur, t, false);\n        if(c7 < bestCost){ bestCost=c7; bestPlan=7; }\n\n        // New: 8 H-one-slide-then-moves left, 9 H-one-slide-then-moves right\n        int c8 = simulate_horizontal_one_slide_then_moves(cur, t, true);\n        if(c8 < bestCost){ bestCost=c8; bestPlan=8; }\n        int c9 = simulate_horizontal_one_slide_then_moves(cur, t, false);\n        if(c9 < bestCost){ bestCost=c9; bestPlan=9; }\n\n        // New: 10 V-one-slide-then-moves up, 11 V-one-slide-then-moves down\n        int c10 = simulate_vertical_one_slide_then_moves(cur, t, true);\n        if(c10 < bestCost){ bestCost=c10; bestPlan=10; }\n        int c11 = simulate_vertical_one_slide_then_moves(cur, t, false);\n        if(c11 < bestCost){ bestCost=c11; bestPlan=11; }\n\n        // 12 pivot-final-slide\n        int c12 = simulate_pivot_final_slide(cur, t);\n        if(c12 < bestCost){ bestCost=c12; bestPlan=12; }\n\n        switch(bestPlan){\n            case 0: {\n                int best = INT_MAX, bestMode = 0;\n                for(int mode=0; mode<3; ++mode){\n                    Pos tmpPos = cur;\n                    vector<string> tmp;\n                    move_with_opportunistic_slide(tmpPos, t, &tmp, mode);\n                    if(!(tmpPos.i==t.i && tmpPos.j==t.j)){\n                        move_with_opportunistic_slide(tmpPos, t, &tmp, mode);\n                    }\n                    if((int)tmp.size() < best){ best=(int)tmp.size(); bestMode=mode; }\n                }\n                move_with_opportunistic_slide(cur, t, &out_actions, bestMode);\n                if(!(cur.i==t.i && cur.j==t.j)){\n                    move_with_opportunistic_slide(cur, t, &out_actions, bestMode);\n                }\n                break;\n            }\n            case 1: { Dir d; can_land_by_slide_to_target(cur, t, d); do_slide(cur, d, &out_actions); break; }\n            case 2: exec_horizontal_one_slide(cur, t); break;\n            case 3: exec_horizontal_two_slides(cur, t, true); break;\n            case 4: exec_horizontal_two_slides(cur, t, false); break;\n            case 5: exec_vertical_one_slide(cur, t); break;\n            case 6: exec_vertical_two_slides(cur, t, true); break;\n            case 7: exec_vertical_two_slides(cur, t, false); break;\n            case 8: {\n                // align row, slide left once, then moves\n                Pos dummy = cur;\n                vector<string> tmp; // not used\n                while(dummy.i != t.i){\n                    Dir dstep = (dummy.i < t.i) ? D : U;\n                    try_move(dummy, dstep, nullptr);\n                }\n                if(cur.i != t.i){\n                    while(cur.i != t.i){\n                        Dir dstep = (cur.i < t.i) ? D : U;\n                        try_move(cur, dstep, &out_actions);\n                    }\n                }\n                if(cur.j > 0) do_slide(cur, L, &out_actions);\n                if(!(cur.i==t.i && cur.j==t.j)){\n                    move_with_opportunistic_slide(cur, t, &out_actions, 0);\n                }\n                break;\n            }\n            case 9: {\n                while(cur.i != t.i){\n                    Dir dstep = (cur.i < t.i) ? D : U;\n                    try_move(cur, dstep, &out_actions);\n                }\n                if(cur.j < N-1) do_slide(cur, R, &out_actions);\n                if(!(cur.i==t.i && cur.j==t.j)){\n                    move_with_opportunistic_slide(cur, t, &out_actions, 0);\n                }\n                break;\n            }\n            case 10: {\n                while(cur.j != t.j){\n                    Dir dstep = (cur.j < t.j) ? R : L;\n                    try_move(cur, dstep, &out_actions);\n                }\n                if(cur.i > 0) do_slide(cur, U, &out_actions);\n                if(!(cur.i==t.i && cur.j==t.j)){\n                    move_with_opportunistic_slide(cur, t, &out_actions, 0);\n                }\n                break;\n            }\n            case 11: {\n                while(cur.j != t.j){\n                    Dir dstep = (cur.j < t.j) ? R : L;\n                    try_move(cur, dstep, &out_actions);\n                }\n                if(cur.i < N-1) do_slide(cur, D, &out_actions);\n                if(!(cur.i==t.i && cur.j==t.j)){\n                    move_with_opportunistic_slide(cur, t, &out_actions, 0);\n                }\n                break;\n            }\n            case 12: exec_pivot_final_slide(cur, t); break;\n            default: break;\n        }\n    }\n\n    for(auto &s: out_actions) cout<<s<<\"\\n\";\n    return 0;\n}"}}}