{"model_name":"o3-high","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\nstruct Rect { int a, b, c, d; };          // [a,c) \u00d7 [b,d)\n\n/* --------- helpers ------------------------------------------------------- */\ninline bool intersect(const Rect& A, const Rect& B) {\n    return max(A.a, B.a) < min(A.c, B.c) &&\n           max(A.b, B.b) < min(A.d, B.d);          // positive area?\n}\ninline double sat(long long need, long long have) {\n    double mi = (double)min(need, have);\n    double ma = (double)max(need, have);\n    double r  = mi / ma;\n    double t  = 1.0 - r;                // 1-ratio\n    return 1.0 - t * t;\n}\n/* ------------------------------------------------------------------------ */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* -------- read input ------------------------------------------------- */\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    constexpr int W = 10000;\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> rd01(0.0, 1.0);\n\n    /* -------- initial 1\u00d71 rectangles ------------------------------------ */\n    vector<Rect> rect(n);\n    vector<long long> area(n, 1);\n    vector<double> p(n);\n    double score = 0.0;\n    for (int i = 0; i < n; ++i) {\n        rect[i] = {x[i], y[i], x[i] + 1, y[i] + 1};\n        p[i] = sat(r[i], 1);\n        score += p[i];\n    }\n    double bestScore = score;\n    auto bestRect   = rect;\n    auto bestArea   = area;\n    auto bestP      = p;\n\n    /* -------- simulated annealing --------------------------------------- */\n    const double TIME_LIMIT = 4.9;           // seconds\n    const double T0 = 5e-2, T1 = 1e-4;       // temperatures\n    const auto   T_start = chrono::steady_clock::now();\n\n    while (true) {\n        double elapsed = chrono::duration<double>(\n                             chrono::steady_clock::now() - T_start).count();\n        if (elapsed > TIME_LIMIT) break;\n        double temp = T0 + (T1 - T0) * (elapsed / TIME_LIMIT);\n\n        /* choose victim rectangle ---------------------------------------- */\n        int i = rng() % n;\n        long long diff = r[i] - area[i];\n        bool wantExpand = diff > 0;\n        bool expand = wantExpand;\n        if (rd01(rng) < 0.20) expand = !expand;      // 20 % opposite\n\n        int dir = rng() & 3;                         // 0 L,1 R,2 D,3 U\n        Rect old = rect[i], neu = old;\n        int deltaMax = 0;\n\n        auto width  = old.c - old.a;\n        auto height = old.d - old.b;\n\n        switch (dir) {\n            case 0: // left side\n                deltaMax = expand ? old.a\n                                   : min(width - 1, x[i] - old.a);\n                break;\n            case 1: // right side\n                deltaMax = expand ? (W - old.c)\n                                   : min(width - 1, old.c - (x[i] + 1));\n                break;\n            case 2: // bottom side\n                deltaMax = expand ? old.b\n                                   : min(height - 1, y[i] - old.b);\n                break;\n            default: // top side\n                deltaMax = expand ? (W - old.d)\n                                   : min(height - 1, old.d - (y[i] + 1));\n        }\n        if (deltaMax <= 0) continue;\n\n        /* choose \u0394 ------------------------------------------------------- */\n        int delta = 1;\n        if (expand) {\n            long long need = llabs(diff);\n            if (dir <= 1) {                    // changing width\n                long long per = height;\n                delta = (int)min<long long>(deltaMax,\n                        max<long long>(1, (need + per - 1) / per));\n            } else {                           // changing height\n                long long per = width;\n                delta = (int)min<long long>(deltaMax,\n                        max<long long>(1, (need + per - 1) / per));\n            }\n        } else {\n            delta = 1 + (rng() % deltaMax);\n        }\n\n        /* apply the move ------------------------------------------------- */\n        if (expand) {\n            if (dir == 0) neu.a -= delta;\n            if (dir == 1) neu.c += delta;\n            if (dir == 2) neu.b -= delta;\n            if (dir == 3) neu.d += delta;\n        } else {\n            if (dir == 0) neu.a += delta;\n            if (dir == 1) neu.c -= delta;\n            if (dir == 2) neu.b += delta;\n            if (dir == 3) neu.d -= delta;\n        }\n\n        /* overlap test --------------------------------------------------- */\n        bool ok = true;\n        for (int j = 0; j < n && ok; ++j)\n            if (j != i && intersect(neu, rect[j])) ok = false;\n        if (!ok) continue;\n\n        long long newArea = 1LL * (neu.c - neu.a) * (neu.d - neu.b);\n        double  new_p = sat(r[i], newArea);\n        double  dScore = new_p - p[i];\n\n        if (dScore >= 0.0 || rd01(rng) < exp(dScore / temp)) {\n            /* accept move ------------------------------------------------ */\n            rect[i]  = neu;\n            area[i]  = newArea;\n            p[i]     = new_p;\n            score   += dScore;\n            if (score > bestScore) {\n                bestScore = score;\n                bestRect  = rect;\n                bestArea  = area;\n                bestP     = p;\n            }\n        }\n    }\n\n    /* -------- output best rectangles ------------------------------------ */\n    for (int i = 0; i < n; ++i)\n        cout << bestRect[i].a << ' ' << bestRect[i].b << ' '\n             << bestRect[i].c << ' ' << bestRect[i].d << '\\n';\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** RNG : xoroshiro128+ (fast, good enough for heuristic) *******************/\nstruct Xoroshiro {\n    using ull = unsigned long long;\n    ull s[2];\n    Xoroshiro(ull seed=88172645463325252ULL) { // some default\n        s[0] = splitmix64(seed); s[1] = splitmix64(s[0]);\n    }\n    static ull splitmix64(ull &x){ ull z=(x+=0x9e3779b97f4a7c15ULL);\n        z=(z^(z>>30))*0xbf58476d1ce4e5b9ULL; z=(z^(z>>27))*0x94d049bb133111ebULL;\n        return z^(z>>31); }\n    ull next() { ull t = s[0] + s[1]; ull x = s[0]; ull y = s[1];\n        s[1] ^= x; s[0] = rotl(x,24) ^ y ^ (y<<16); s[1] = rotl(y,37); return t; }\n    int randint(int n){ return int(next() % n); }\n    double rnd01(){ return (next() >> 11) * (1.0/9007199254740992.0); } // /2^53\n    static ull rotl(ull x,int k){ return (x<<k)|(x>>(64-k)); }\n};\n\n/*** data ********************************************************************/\nconst int H = 50, W = 50;\nint si, sj;\nint tile[H][W];\nint valueCell[H][W];\nint M;                     // number of tiles\nvector<array<int,4>> neigh; // for each cell id, indices of neighbours (-1 if none)\nint cellId(int r,int c){ return r*W+c; }\n\nstruct Move { int dir; int deg; int val; int scoreEval; }; // helper for chooser\nint dr[4]={-1,1,0,0};\nint dc[4]={0,0,-1,1};\nchar dch[4]={'U','D','L','R'};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read input */\n    cin >> si >> sj;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cin >> tile[i][j];\n    M = 0;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) M = max(M, tile[i][j]+1);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cin >> valueCell[i][j];\n\n    /* pre\u2013compute neighbours that belong to a *different* tile */\n    neigh.resize(H*W);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        for(int d=0;d<4;d++){\n            int ni=i+dr[d], nj=j+dc[d];\n            if(ni<0||nj<0||ni>=H||nj>=W || tile[ni][nj]==tile[i][j])\n                neigh[cellId(i,j)][d]=-1;\n            else\n                neigh[cellId(i,j)][d]=cellId(ni,nj);\n        }\n    }\n\n    /* search the best walk within the time limit */\n    auto time_limit = chrono::steady_clock::now() + chrono::milliseconds(1950);\n    Xoroshiro rng(chrono::high_resolution_clock::now().time_since_epoch().count());\n\n    long long   bestScore = -1;\n    string      bestPath;\n\n    vector<char> pathBuf;     pathBuf.reserve(H*W);\n    vector<char> dirOrder = {0,1,2,3};\n\n    vector<char> visitedTile(M,0);\n\n    while(chrono::steady_clock::now() < time_limit){\n        /* parameters for this try */\n        int lambda = rng.randint(91)+10; // 10 \u2026 100\n        shuffle(dirOrder.begin(), dirOrder.end(), std::default_random_engine(rng.next()));\n\n        /* reset */\n        fill(visitedTile.begin(), visitedTile.end(), 0);\n        pathBuf.clear();\n\n        int r=si, c=sj;\n        visitedTile[tile[r][c]] = 1;\n        long long scoreHere = valueCell[r][c];\n\n        /* greedy walk */\n        for(;;){\n            int cid = cellId(r,c);\n            Move best{-1,-1,-1,INT_MIN};\n\n            for(int idx=0; idx<4; ++idx){\n                int d = dirOrder[idx];\n                int nid = neigh[cid][d];\n                if(nid==-1) continue;\n\n                int nr = nid / W, nc = nid % W;\n                int tId = tile[nr][nc];\n                if(visitedTile[tId]) continue;\n\n                /* degree after entering this neighbour */\n                int deg = 0;\n                for(int d2=0; d2<4; ++d2){\n                    int nnid = neigh[nid][d2];\n                    if(nnid==-1) continue;\n                    int tr = nnid / W, tc = nnid % W;\n                    int tt = tile[tr][tc];\n                    if(tt==tId || visitedTile[tt]) continue;\n                    ++deg;\n                }\n                int val = valueCell[nr][nc];\n                int eval = val + lambda*deg + rng.randint(3); // tiny noise\n\n                if(eval > best.scoreEval){\n                    best = {d,deg,val,eval};\n                }\n            }\n\n            if(best.dir==-1) break;          // dead end -> finish walk\n\n            /* do the chosen move */\n            int dir = best.dir;\n            r += dr[dir];\n            c += dc[dir];\n            visitedTile[tile[r][c]] = 1;\n            pathBuf.push_back(dch[dir]);\n            scoreHere += valueCell[r][c];\n        }\n\n        if(scoreHere > bestScore){\n            bestScore = scoreHere;\n            bestPath.assign(pathBuf.begin(), pathBuf.end());\n        }\n    }\n\n    /* output the best path found */\n    cout << bestPath << '\\n';\n    return 0;\n}","ahc003":"//  AHC003 \u2013 simple SGD learner on the edges of a 30\u00d730 grid\n//  g++ -std=c++20 -O2 -pipe -static -s main.cpp\n#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int H = 30, W = 30;\nconstexpr int HOR = H * (W - 1);\nconstexpr int VER = (H - 1) * W;\nconstexpr int E   = HOR + VER;\nconstexpr double INIT_W = 5000.0;\nconstexpr double MIN_W  =  300.0;\nconstexpr double MAX_W  = 20000.0;\nconstexpr double BASE_ETA = 0.5;          // learning-rate numerator\nconstexpr double EXPL_NOISE = 0.40;       // \u00b140 %\nconstexpr double EXPL_START = 0.30;       // 30 %\nconstexpr double EXPL_DECAY = 0.997;      // p(k)=start*decay^k\n\nstruct Edge {\n    int to;\n    int id;\n};\narray<array<array<Edge,4>, W>, H> adj;   // fixed adjacency (unused entries: id = -1)\n\narray<double, E>  w;          // current estimate of every edge weight\narray<int,     E> cnt;        // how many times we have touched the edge\n\n/* ---------------------------------------------------------- */\nint horId[int(H)][int(W-1)];\nint verId[int(H-1)][int(W)];\nvoid build_graph() {\n    int id = 0;\n    for (int i = 0; i < H; ++i)\n        for (int j = 0; j < W-1; ++j)\n            horId[i][j] = id++;\n    for (int i = 0; i < H-1; ++i)\n        for (int j = 0; j < W; ++j)\n            verId[i][j] = id++;\n    // adjacency list\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                adj[i][j][d].id = -1;  // mark unused\n    for (int i = 0; i < H; ++i)\n        for (int j = 0; j < W; ++j) {\n            // up\n            if (i) {\n                int eid = verId[i-1][j];\n                adj[i][j][0] = { (i-1)*W + j, eid };\n            }\n            // down\n            if (i+1 < H) {\n                int eid = verId[i][j];\n                adj[i][j][1] = { (i+1)*W + j, eid };\n            }\n            // left\n            if (j) {\n                int eid = horId[i][j-1];\n                adj[i][j][2] = { i*W + (j-1), eid };\n            }\n            // right\n            if (j+1 < W) {\n                int eid = horId[i][j];\n                adj[i][j][3] = { i*W + (j+1), eid };\n            }\n        }\n}\n\n/* ---------------------------------------------------------- */\nstruct Node {\n    double dist;\n    int v;\n    bool operator<(const Node& other) const { return dist > other.dist; } // min-heap\n};\n\nmt19937 rng((uint64_t)chrono::high_resolution_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> unif01(0.0,1.0);\ndouble randpm(double mag){ return (unif01(rng)*2-1)*mag; }   // uniform in [-mag , +mag]\n\n/* shortest path on possibly perturbed weights;  returns edge list (id order from s to t) */\nvector<int> dijkstra(int si,int sj,int ti,int tj,bool exploration) {\n    array<double, H*W> dist;\n    array<int,    H*W> prvV, prvE;\n    dist.fill(1e100);\n    dist[si*W+sj]=0;\n    prvE.fill(-1);\n    priority_queue<Node> pq;\n    pq.push({0.0,si*W+sj});\n\n    while(!pq.empty()){\n        auto [d,v]=pq.top(); pq.pop();\n        if(d!=dist[v]) continue;\n        if(v==ti*W+tj) break;\n        int vi=v/W, vj=v%W;\n        for(int k=0;k<4;k++){\n            auto [to,eid]=adj[vi][vj][k];\n            if(eid<0) continue;\n            double ww = w[eid];\n            if(exploration) ww *= 1.0 + randpm(EXPL_NOISE);\n            double nd = d + ww;\n            if(nd < dist[to]){\n                dist[to]=nd;\n                prvV[to]=v;\n                prvE[to]=eid;\n                pq.push({nd,to});\n            }\n        }\n    }\n    vector<int> edges;\n    int cur=ti*W+tj;\n    while(cur!=si*W+sj){\n        int e = prvE[cur];\n        edges.push_back(e);\n        cur = prvV[cur];\n    }\n    reverse(edges.begin(),edges.end());\n    return edges;\n}\n\n/* convert edge list to movement string */\nstring edgesToString(const vector<int>& edges){\n    string s;\n    for(int eid:edges){\n        if(eid < HOR){          // horizontal\n            int i = eid/(W-1);\n            int j = eid%(W-1);\n            // direction depends on current vertex in path string\n            // we can reconstruct from string length so far\n        }\n    }\n    // easier: walk along edges accumulating coordinates\n    int x=0,y=0; // dummy\n    return s; // replaced below\n}\n/* we will rebuild string directly while walking vertices: */\nstring buildPathString(int si,int sj,const vector<int>& edges){\n    string res;\n    int ci=si,cj=sj;\n    for(int eid:edges){\n        int ni=ci, nj=cj;\n        if(eid < HOR){                // horizontal\n            int i = eid/(W-1);\n            int j = eid%(W-1);\n            if(ci==i && cj==j){ nj = cj+1; res.push_back('R'); }\n            else { nj = cj-1; res.push_back('L'); }\n        }else{                         // vertical\n            int ee = eid - HOR;\n            int i = ee/W;\n            int j = ee%W;\n            if(ci==i && cj==j){ ni = ci+1; res.push_back('D'); }\n            else { ni = ci-1; res.push_back('U'); }\n        }\n        ci=ni; cj=nj;\n    }\n    return res;\n}\n\n/* ---------------------------------------------------------- */\nvoid learn(const vector<int>& edges, long long measured){\n    double est=0.0;\n    for(int e:edges) est += w[e];\n    if(est<=0) return;\n    double r = (double)measured / est;\n    for(int e:edges){\n        double eta = BASE_ETA / sqrt(cnt[e]+1.0);\n        w[e] *= pow(r, eta);\n        w[e] = min(MAX_W, max(MIN_W, w[e]));\n        cnt[e]++;\n    }\n}\n\n/* ---------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    build_graph();\n    w.fill(INIT_W);\n    cnt.fill(0);\n\n    for(int query=0; query<1000; ++query){\n        int si,sj,ti,tj;\n        if(!(cin>>si>>sj>>ti>>tj)) return 0;\n        double pExpl = EXPL_START * pow(EXPL_DECAY, query);\n        bool exploration = unif01(rng) < pExpl;\n\n        vector<int> pathEdges = dijkstra(si,sj,ti,tj, exploration);\n        string pathStr = buildPathString(si,sj,pathEdges);\n\n        cout << pathStr << '\\n' << flush;\n\n        long long result;\n        cin >> result;          // noisy length from judge\n        learn(pathEdges, result);\n    }\n    return 0;\n}","ahc004":"//  g++ -std=c++20 -O2 -pipe -static -s\n#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N  = 20;     // matrix size (fixed)\nconstexpr int CH = 8;      // A..H\nconstexpr int MAXLEN = 12; // max length of s_i\n\nstruct Placement {\n    uint8_t len;                  // length of the string\n    uint16_t cell[MAXLEN];        // linear cell id (0..399)\n    uint8_t  letter[MAXLEN];      // 0..7\n};\nstruct Watch {\n    int sid;          // string id\n    int pid;          // placement id within that string\n    uint8_t letter;   // letter required in this cell by that placement\n};\n\nint c2i(char c){ return c-'A'; }\nchar i2c(int x){ return 'A'+x; }\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;  /* N is fixed 20 */\n    cin >> std::ws;\n    cin.ignore(numeric_limits<streamsize>::max(),' '); // throw away N\n    cin >> M;\n    vector<string> S(M);\n    for(auto& s:S) cin >> s;\n\n    /*------------------------------------------------------------------*\n     * 1. enumerate every placement                                     *\n     *------------------------------------------------------------------*/\n    vector<vector<Placement>> plac(M);\n    vector<vector<char>> active(M);        // 1 = still alive\n    vector<vector<Watch>> watchers(N*N);   // placements touching each cell\n\n    for(int sid=0; sid<M; ++sid){\n        const string& s = S[sid];\n        const int L = (int)s.size();\n        plac[sid].reserve(800);\n        /* horizontal */\n        for(int row=0; row<N; ++row)\n            for(int st=0; st<N; ++st){\n                Placement p; p.len=L;\n                for(int k=0;k<L;++k){\n                    int col=(st+k)%N;\n                    int cell=row*N+col;\n                    p.cell[k]=cell;\n                    p.letter[k]=c2i(s[k]);\n                }\n                int pid=plac[sid].size();\n                plac[sid].push_back(p);\n                for(int k=0;k<L;++k)\n                    watchers[p.cell[k]].push_back({sid,pid,p.letter[k]});\n            }\n        /* vertical */\n        for(int col=0; col<N; ++col)\n            for(int st=0; st<N; ++st){\n                Placement p; p.len=L;\n                for(int k=0;k<L;++k){\n                    int row=(st+k)%N;\n                    int cell=row*N+col;\n                    p.cell[k]=cell;\n                    p.letter[k]=c2i(s[k]);\n                }\n                int pid=plac[sid].size();\n                plac[sid].push_back(p);\n                for(int k=0;k<L;++k)\n                    watchers[p.cell[k]].push_back({sid,pid,p.letter[k]});\n            }\n        active[sid].assign(plac[sid].size(),1);\n    }\n\n    /*------------------------------------------------------------------*\n     * 2. propagation of forced letters                                 *\n     *------------------------------------------------------------------*/\n    vector<int8_t> fixed(N*N,-1); // -1 = unknown, else 0..7\n    bool changed=true;\n    while(changed){\n        changed=false;\n        /* remove placements inconsistent with already fixed letters */\n        for(int sid=0; sid<M; ++sid){\n            auto &v = plac[sid];\n            auto &alive = active[sid];\n            for(int pid=0,sz=v.size(); pid<sz; ++pid){\n                if(!alive[pid]) continue;\n                const Placement& p=v[pid];\n                bool ok=true;\n                for(int k=0;k<p.len && ok;++k){\n                    int c = p.cell[k];\n                    if(fixed[c]!=-1 && fixed[c]!=p.letter[k]) ok=false;\n                }\n                if(!ok){ alive[pid]=0; changed=true; }\n            }\n        }\n        /* fix cells that now have only one possible letter */\n        for(int cell=0; cell<N*N; ++cell){\n            if(fixed[cell]!=-1) continue;\n            uint8_t mask=0;\n            for(const auto& w: watchers[cell])\n                if(active[w.sid][w.pid]) mask |= (1u<<w.letter);\n            if(mask && (mask & (mask-1))==0){           // power of two\n                fixed[cell]=__builtin_ctz(mask);\n                changed=true;\n            }\n        }\n    }\n\n    /*------------------------------------------------------------------*\n     * 3. greedy assignment (strings with fewer choices first)          *\n     *------------------------------------------------------------------*/\n    mt19937 rng(712367); // deterministic, change for randomisation\n    vector<int> aliveCnt(M);\n    for(int i=0;i<M;++i){\n        aliveCnt[i]=accumulate(begin(active[i]),end(active[i]),0);\n    }\n    vector<int> order(M); iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),\n         [&](int a,int b){ return aliveCnt[a]<aliveCnt[b]; });\n\n    for(int sid:order){\n        int bestPid=-1, bestNew=99;\n        for(int pid=0,sz=plac[sid].size(); pid<sz; ++pid){\n            if(!active[sid][pid]) continue;\n            const auto& p = plac[sid][pid];\n            bool ok=true; int newCnt=0;\n            for(int k=0;k<p.len && ok;++k){\n                int c = p.cell[k];\n                if(fixed[c]!=-1 && fixed[c]!=p.letter[k]) ok=false;\n                else if(fixed[c]==-1) ++newCnt;\n            }\n            if(!ok) continue;\n            if(newCnt<bestNew || (newCnt==bestNew && rng()%2)){\n                bestNew=newCnt; bestPid=pid;\n            }\n        }\n        if(bestPid==-1) continue;                 // cannot place this string\n        const auto& p=plac[sid][bestPid];\n        /* fix the cells decided by this placement */\n        for(int k=0;k<p.len;++k){\n            int c=p.cell[k];\n            if(fixed[c]==p.letter[k]) continue;\n            fixed[c]=p.letter[k];\n            /* eliminate incompatible placements touching this cell */\n            for(const auto& w: watchers[c]){\n                if(!active[w.sid][w.pid]) continue;\n                if(w.letter!=fixed[c]){\n                    active[w.sid][w.pid]=0;\n                    --aliveCnt[w.sid];\n                }\n            }\n        }\n    }\n\n    /*------------------------------------------------------------------*\n     * 4. fill remaining unknown cells arbitrarily                      *\n     *------------------------------------------------------------------*/\n    uniform_int_distribution<int> d8(0,7);\n    for(int c=0;c<N*N;++c)\n        if(fixed[c]==-1) fixed[c]=d8(rng);\n\n    /*------------------------------------------------------------------*\n     * 5. output                                                        *\n     *------------------------------------------------------------------*/\n    for(int r=0;r<N;++r){\n        for(int c=0;c<N;++c) cout << i2c(fixed[r*N+c]);\n        cout << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\nstruct Edge{int to,w; char dir;};\nusing ll = long long;\nconst int INF = 1e9;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* --- read input ---------------------------------------------------- */\n    int N, si, sj;\n    if(!(cin>>N>>si>>sj)) return 0;\n    vector<string> S(N);\n    for(int i=0;i<N;i++) cin>>S[i];\n\n    auto inb=[&](int i,int j){return 0<=i&&i<N&&0<=j&&j<N;};\n\n    const int NN = N*N;\n    auto id=[&](int i,int j){return i*N+j;};\n    auto row=[&](int id){return id/N;};\n    auto col=[&](int id){return id%N;};\n\n    /* --- build road mask ---------------------------------------------- */\n    vector<char> isRoad(NN,0), cost(NN,0);\n    for(int i=0;i<N;i++)\n        for(int j=0;j<N;j++)\n            if(S[i][j]!='#'){\n                isRoad[id(i,j)]=1;\n                cost[id(i,j)]= S[i][j]-'0';\n            }\n\n    /* --- find horizontal runs ----------------------------------------- */\n    vector<int> rowRunOf(NN,-1), colRunOf(NN,-1);\n    vector<vector<int>> rowRuns, colRuns;\n\n    for(int i=0;i<N;i++){\n        int j=0;\n        while(j<N){\n            if(!isRoad[id(i,j)]){ ++j; continue;}\n            int st=j;\n            vector<int> cells;\n            while(j<N && isRoad[id(i,j)]){ cells.push_back(id(i,j)); ++j;}\n            int rId = (int)rowRuns.size();\n            for(int v:cells) rowRunOf[v]=rId;\n            rowRuns.push_back(move(cells));\n        }\n    }\n    /* --- vertical runs ------------------------------------------------- */\n    for(int j=0;j<N;j++){\n        int i=0;\n        while(i<N){\n            if(!isRoad[id(i,j)]){ ++i; continue;}\n            int st=i;\n            vector<int> cells;\n            while(i<N && isRoad[id(i,j)]){ cells.push_back(id(i,j)); ++i;}\n            int cId = (int)colRuns.size();\n            for(int v:cells) colRunOf[v]=cId;\n            colRuns.push_back(move(cells));\n        }\n    }\n    const int H = (int)rowRuns.size();\n    const int V = (int)colRuns.size();\n\n    /* --- choose vantage squares --------------------------------------- */\n    vector<char> hCov(H,0), vCov(V,0);\n    int startId = id(si,sj);\n    if(rowRunOf[startId]>=0) hCov[rowRunOf[startId]]=1;\n    if(colRunOf[startId]>=0) vCov[colRunOf[startId]]=1;\n\n    vector<char> selected(NN,0);\n    vector<int> vPoints;                     // ids, NOT including the start\n    auto addPoint=[&](int cid){\n        if(!selected[cid] && cid!=startId){\n            selected[cid]=1;\n            vPoints.push_back(cid);\n        }\n    };\n\n    /* pairing pass */\n    for(int r=0;r<H;r++) if(!hCov[r]){\n        for(int cell: rowRuns[r]){\n            int c = colRunOf[cell];\n            if(!vCov[c]){\n                hCov[r]=vCov[c]=1;\n                addPoint(cell);\n                break;\n            }\n        }\n    }\n    /* remaining horizontal runs */\n    for(int r=0;r<H;r++) if(!hCov[r]){\n        int cell=rowRuns[r][0];\n        hCov[r]=1;\n        addPoint(cell);\n    }\n    /* remaining vertical runs */\n    for(int c=0;c<V;c++) if(!vCov[c]){\n        int cell=colRuns[c][0];\n        vCov[c]=1;\n        addPoint(cell);\n    }\n\n    /* --- build graph --------------------------------------------------- */\n    vector<array<int,4>> neigh(NN);\n    const int di[4]={-1,1,0,0};\n    const int dj[4]={0,0,-1,1};\n    const char dch[4]={'U','D','L','R'};\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        int idx=id(i,j);\n        for(int k=0;k<4;k++){\n            int ni=i+di[k], nj=j+dj[k];\n            neigh[idx][k]= (inb(ni,nj)&&isRoad[id(ni,nj)]) ? id(ni,nj) : -1;\n        }\n    }\n\n    /* --- node list: start + vPoints ----------------------------------- */\n    vector<int> nodes; nodes.reserve(vPoints.size()+1);\n    nodes.push_back(startId);\n    nodes.insert(nodes.end(), vPoints.begin(), vPoints.end());\n    const int K = (int)nodes.size();\n\n    /* --- all\u2013pairs shortest paths & move strings ---------------------- */\n    vector<vector<int>> dist(K, vector<int>(K,INF));\n    vector<vector<string>> path(K, vector<string>(K));\n\n    vector<int> d(NN), par(NN);\n    vector<char> pdir(NN);\n\n    using Pair = pair<int,int>;\n    priority_queue<Pair, vector<Pair>, greater<Pair>> pq;\n\n    for(int s=0;s<K;s++){\n        fill(d.begin(), d.end(), INF);\n        d[nodes[s]]=0; pq.emplace(0,nodes[s]);\n        fill(par.begin(), par.end(), -1);\n\n        while(!pq.empty()){\n            auto [dv, v]=pq.top(); pq.pop();\n            if(dv!=d[v]) continue;\n            for(int k=0;k<4;k++){\n                int to=neigh[v][k];\n                if(to==-1) continue;\n                int nd=dv + cost[to];\n                if(nd<d[to]){\n                    d[to]=nd;\n                    par[to]=v;\n                    pdir[to]=dch[k];\n                    pq.emplace(nd,to);\n                }\n            }\n        }\n        for(int t=0;t<K;t++){\n            int dst=nodes[t];\n            dist[s][t]=d[dst];\n            if(s==t) { path[s][t]=\"\"; continue;}\n            string mv;\n            int cur=dst;\n            while(cur!=nodes[s]){\n                mv.push_back(pdir[cur]);\n                cur=par[cur];\n            }\n            reverse(mv.begin(), mv.end());\n            path[s][t]=move(mv);\n        }\n    }\n\n    /* --- nearest neighbour tour --------------------------------------- */\n    vector<char> used(K,0); used[0]=1;           // start already visited\n    vector<int> order; order.reserve(K+1);\n    int cur=0;\n    for(int step=1;step<K;step++){\n        int best=-1,bestd=INF;\n        for(int j=1;j<K;j++) if(!used[j] && dist[cur][j]<bestd){\n            bestd=dist[cur][j]; best=j;\n        }\n        used[best]=1;\n        order.push_back(best);\n        cur=best;\n    }\n    order.push_back(0);                         // return to start\n\n    /* --- build final answer ------------------------------------------- */\n    string answer;\n    long long totalTime=0;\n    cur=0;\n    for(int nx:order){\n        answer += path[cur][nx];\n        totalTime += dist[cur][nx];\n        cur = nx;\n    }\n\n    /* --- output -------------------------------------------------------- */\n    cout<<answer<<\"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Worker {\n    vector<int> skill;   // proven lower bound\n    int task = -1;       // current task id (0-based) or -1\n    int startDay = -1;   // day the current task was started\n    double gap = 0.0;    // unknown part of w\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    /* ---------- read tasks ---------- */\n    vector<vector<int>> demand(N, vector<int>(K));\n    for (int i = 0; i < N; ++i)\n        for (int k = 0; k < K; ++k) cin >> demand[i][k];\n\n    vector<vector<int>> out(N);\n    vector<int> indeg(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v; cin >> u >> v;\n        --u; --v;\n        out[u].push_back(v);\n        ++indeg[v];\n    }\n\n    vector<int> prio(N);\n    for (int i = 0; i < N; ++i) prio[i] = (int)out[i].size();\n\n    /* ---------- initial ready list ---------- */\n    vector<int> status(N, 0);          // 0 not started, 1 running, 2 done\n    vector<int> ready;\n    vector<char> inReady(N, 0);\n    for (int i = 0; i < N; ++i)\n        if (indeg[i] == 0) {\n            ready.push_back(i);\n            inReady[i] = 1;\n        }\n\n    /* ---------- workers ---------- */\n    vector<Worker> W(M, Worker{vector<int>(K, 0), -1, -1, 0.0});\n\n    int day = 1;\n    while (true) {\n        /* ===== choose assignments for idle workers ===== */\n        vector<pair<int,int>> today;           // (worker, task), 0-based\n\n        for (int j = 0; j < M; ++j) {\n            if (W[j].task != -1) continue;     // busy\n\n            int bestTask = -1;\n            int bestPredT = INT_MAX;\n            int bestPr = -1;\n\n            for (int id : ready) {\n                if (status[id] != 0) continue;     // already taken\n                // predict w\n                int def = 0;\n                for (int k = 0; k < K; ++k) {\n                    int diff = demand[id][k] - W[j].skill[k];\n                    if (diff > 0) def += diff;\n                }\n                int wPred = def + (int)std::round(W[j].gap);\n                if (wPred == 0) wPred = 1;\n\n                if (wPred < bestPredT ||\n                   (wPred == bestPredT && prio[id] > bestPr) ||\n                   (wPred == bestPredT && prio[id] == bestPr && id < bestTask))\n                {\n                    bestTask = id;\n                    bestPredT = wPred;\n                    bestPr    = prio[id];\n                }\n            }\n\n            if (bestTask != -1) {\n                today.emplace_back(j, bestTask);\n                status[bestTask] = 1;\n                W[j].task = bestTask;\n                W[j].startDay = day;\n            }\n        }\n\n        /* ---------- output ---------- */\n        cout << (int)today.size();\n        for (auto [j, t] : today) cout << ' ' << j+1 << ' ' << t+1;\n        cout << '\\n' << flush;\n\n        /* ---------- read finished list ---------- */\n        int nFinish;\n        if (!(cin >> nFinish)) return 0;\n        if (nFinish == -1) break;\n\n        for (int i = 0; i < nFinish; ++i) {\n            int f; cin >> f; --f;\n            Worker &wk = W[f];\n            int taskId = wk.task;\n            if (taskId < 0) continue;      // safety\n\n            int realT = day - wk.startDay + 1;\n            int wObs  = (realT == 1 ? 0 : realT);\n\n            /* ----- update skill lower bound ----- */\n            if (wObs == 0) {               // we are sure every dim is covered\n                for (int k = 0; k < K; ++k)\n                    wk.skill[k] = max(wk.skill[k], demand[taskId][k]);\n                wk.gap *= 0.9;\n            } else {\n                int defPred = 0;\n                for (int k = 0; k < K; ++k) {\n                    int diff = demand[taskId][k] - wk.skill[k];\n                    if (diff > 0) defPred += diff;\n                }\n                if (defPred > wObs) {      // we over-estimated: raise skills\n                    int need = defPred - wObs;\n                    for (int k = 0; k < K && need > 0; ++k) {\n                        int lack = demand[taskId][k] - wk.skill[k];\n                        if (lack <= 0) continue;\n                        int inc = min(lack, need);\n                        wk.skill[k] += inc;\n                        need -= inc;\n                    }\n                    wk.gap *= 0.9;\n                } else {                   // we underestimated: enlarge gap\n                    double delta = wObs - defPred;\n                    wk.gap = 0.7 * wk.gap + 0.3 * delta;\n                }\n            }\n\n            /* ----- mark task finished ----- */\n            status[taskId] = 2;\n            wk.task = -1;\n\n            for (int v : out[taskId]) {\n                if (--indeg[v] == 0 && status[v] == 0 && !inReady[v]) {\n                    ready.push_back(v);\n                    inReady[v] = 1;\n                }\n            }\n        }\n\n        ++day;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct Order {\n    int id;                 // 0-based\n    int ax, ay;             // restaurant\n    int cx, cy;             // destination\n    int inner;              // |a-c|+|b-d|\n    int distP2C;            // |a-400|+|b-400|\n    int distD2C;            // |c-400|+|d-400|\n};\n\ninline int manhattan(int x1,int y1,int x2,int y2){\n    return abs(x1-x2)+abs(y1-y2);\n}\n\n/* ---------- cross cost of an order sequence (without internal distances) --- */\nll cross_cost(const vector<Order>& ord,\n              const vector<int>& seq)\n{\n    if(seq.empty()) return 0;\n    ll c = 0;\n    const int Cx = 400, Cy = 400;\n    c += manhattan(Cx,Cy, ord[seq[0]].ax, ord[seq[0]].ay);\n    for(size_t i=0;i+1<seq.size();++i){\n        const Order &o1 = ord[seq[i]];\n        const Order &o2 = ord[seq[i+1]];\n        c += manhattan(o1.cx,o1.cy, o2.ax,o2.ay);\n    }\n    const Order &last = ord[seq.back()];\n    c += manhattan(last.cx,last.cy, Cx,Cy);\n    return c;\n}\n\n/* ------------------------- main ------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 1000, NEED = 50;\n    vector<Order> ord(N);\n    for(int i=0;i<N;++i){\n        int a,b,c,d;\n        cin>>a>>b>>c>>d;\n        ord[i] = {\n            i,\n            a,b,c,d,\n            manhattan(a,b,c,d),\n            manhattan(a,b,400,400),\n            manhattan(c,d,400,400)\n        };\n    }\n\n    /* ---- Step 1: sort by inner distance (ascending) ---------------------- */\n    vector<int> cand(N);\n    iota(cand.begin(), cand.end(), 0);\n    sort(cand.begin(), cand.end(),\n         [&](int i,int j){ return ord[i].inner < ord[j].inner; });\n\n    /* ---- Step 2: greedy construction ------------------------------------ */\n    const int SAMPLE = 300;          // how many first candidates we look at\n    const double w_cur = 1.0;\n    const double w_inner = 0.30;\n    const double w_d2c = 0.10;\n\n    int curx = 400, cury = 400;\n    vector<int> seq;  seq.reserve(NEED);\n\n    while((int)seq.size() < NEED){\n        int bestIdx = -1;\n        double bestScore = 1e100;\n\n        int limit = min<int>(SAMPLE, (int)cand.size());\n        for(int k=0;k<limit;++k){\n            int id = cand[k];\n            const Order &o = ord[id];\n            double score =\n                w_cur   * manhattan(curx,cury, o.ax,o.ay) +\n                w_inner * o.inner +\n                w_d2c   * o.distD2C;\n            if(score < bestScore){\n                bestScore = score;\n                bestIdx = k;\n            }\n        }\n\n        if(bestIdx==-1) bestIdx = 0;          // fallback (should never happen)\n\n        int chosen = cand[bestIdx];\n        seq.push_back(chosen);\n        curx = ord[chosen].cx;\n        cury = ord[chosen].cy;\n        cand.erase(cand.begin()+bestIdx);\n    }\n\n    /* ---- Step 3: 2-opt on the order sequence ---------------------------- */\n    ll baseCross = cross_cost(ord, seq);\n    bool improved = true;\n    while(improved){\n        improved = false;\n        for(int i=0;i<NEED-1;++i){\n            for(int j=i+1;j<NEED;++j){\n                reverse(seq.begin()+i+1, seq.begin()+j+1);\n                ll ncost = cross_cost(ord, seq);\n                if(ncost < baseCross){\n                    baseCross = ncost;\n                    improved = true;\n                }else{\n                    reverse(seq.begin()+i+1, seq.begin()+j+1);   // rollback\n                }\n            }\n        }\n    }\n\n    /* ---- total travel time T -------------------------------------------- */\n    ll innerSum = 0;\n    for(int id:seq) innerSum += ord[id].inner;\n    ll T = innerSum + baseCross;\n\n    /* ---- build final route ---------------------------------------------- */\n    vector<int> routeX, routeY;\n    routeX.reserve(2*NEED + 2);\n    routeY.reserve(2*NEED + 2);\n\n    routeX.push_back(400); routeY.push_back(400);\n    for(int id:seq){\n        routeX.push_back(ord[id].ax); routeY.push_back(ord[id].ay);\n        routeX.push_back(ord[id].cx); routeY.push_back(ord[id].cy);\n    }\n    routeX.push_back(400); routeY.push_back(400);\n\n    /* ---- output --------------------------------------------------------- */\n    cout << NEED;\n    for(int id:seq) cout << ' ' << (id+1);           // to 1-based\n    cout << '\\n';\n\n    cout << routeX.size();\n    for(size_t i=0;i<routeX.size();++i){\n        cout << ' ' << routeX[i] << ' ' << routeY[i];\n    }\n    cout << '\\n';\n\n    /*  The programme writes only once, therefore the last output is final.  */\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** -------- union-find -------- ***/\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        sz.assign(n, 1);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int v) { return p[v] == v ? v : p[v] = find(p[v]); }\n    bool unite(int a, int b) {\n        a = find(a);  b = find(b);\n        if (a == b) return false;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a;\n        sz[a] += sz[b];\n        return true;\n    }\n};\n\n/*** -------- main -------- ***/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 400;\n    const int M = 1995;\n\n    /* ----- read coordinates ----- */\n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; ++i) cin >> x[i] >> y[i];\n\n    /* ----- read edge list ----- */\n    vector<int> U(M), V(M);\n    for (int i = 0; i < M; ++i) cin >> U[i] >> V[i];\n\n    /* ----- pre-compute Euclidean lower bounds d_i ----- */\n    vector<int> d(M);\n    for (int i = 0; i < M; ++i) {\n        long long dx = x[U[i]] - x[V[i]];\n        long long dy = y[U[i]] - y[V[i]];\n        d[i] = int(lround(sqrt(double(dx * dx + dy * dy))));\n        if (d[i] == 0) d[i] = 1;               // just in case\n    }\n\n    /* ----- build one Euclidean MST (Kruskal) ----- */\n    vector<int> ord(M);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a, int b){ return d[a] < d[b]; });\n\n    vector<char> inMST(M, 0);\n    DSU dsu0(N);\n    int used = 0;\n    for (int id : ord) {\n        if (dsu0.unite(U[id], V[id])) {\n            inMST[id] = 1;\n            if (++used == N - 1) break;\n        }\n    }\n\n    /* ----- on-line phase ----- */\n    DSU dsu(N);\n    int components = N;\n\n    const int BASE_MARGIN = 15;                // safety margin while many edges are left\n\n    for (int i = 0; i < M; ++i) {\n        long long li;\n        cin >> li;\n\n        int u = U[i], v = V[i];\n        int cu = dsu.find(u), cv = dsu.find(v);\n\n        bool take = false;\n\n        if (cu != cv) {                        // only edges that shrink the forest are useful\n            double ratio = double(li) / double(d[i]);\n\n            /* time-dependent threshold 1.15 \u2192 3.00 */\n            double thr = 1.15 + 1.85 * double(i) / double(M);\n            if (inMST[i]) thr += 0.15;         // small bonus for MST edge\n\n            if (ratio <= thr) take = true;     // cheap enough\n\n            /* safety rule */\n            long long edgesLeft = M - i - 1;\n            int margin      = (edgesLeft > 100 ? BASE_MARGIN : 0);\n            if (!take) {\n                int compIfReject = components;\n                if (compIfReject - 1 > edgesLeft - margin) take = true;\n            }\n        }\n\n        /* ----- output decision ----- */\n        cout << (take ? 1 : 0) << '\\n' << flush;\n\n        if (take && dsu.unite(u, v)) --components;\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pet{\n    int x, y, type;\n};\nstruct Human{\n    int x, y;              // current position (1-based)\n    int line_col;          // column of the wall we are drawing\n    int side;              // +1 : we stand right of the wall and build left  (action 'l')\n                           // -1 : we stand left  of the wall and build right (action 'r')\n    int target_col;        // column we want to stand on while building\n    int phase = 0;         // 0 = move to starting cell (row 1, target_col)\n                           // 1 = build wall while going down\n    bool build_next = true;\n};\n\nconst int H = 30, W = 30;\nconst int dx[4]={-1,1,0,0};\nconst int dy[4]={0,0,-1,1};\n\nbool inside(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;                    // pets\n    if(!(cin>>N)) return 0;\n    vector<Pet> pets(N);\n    for(auto &p:pets) cin>>p.x>>p.y>>p.type;\n\n    int M;                    // humans\n    cin>>M;\n    vector<Human> hum(M);\n    for(auto &h:hum) cin>>h.x>>h.y;\n\n    /* precompute the columns on which walls will be built */\n    const vector<int> WALL_COLS = {2,5,8,11,14,17,20,23,26,29};\n\n    for(int i=0;i<M;i++){\n        hum[i].line_col = WALL_COLS[i];               // one line per human\n        hum[i].side     = (hum[i].line_col < 15)? +1 : -1;\n        hum[i].target_col = hum[i].line_col + hum[i].side;\n    }\n\n    /* current map,   '.' = passable,  '#' = wall                                */\n    vector<string> board(H+2,string(W+2,'#'));        // sentinel rim\n    for(int x=1;x<=H;x++) for(int y=1;y<=W;y++) board[x][y]='.';\n\n    auto pet_near = [&](int x,int y)->bool{\n        for(const auto &p:pets){\n            if(p.x==x && p.y==y) return true;\n            if(abs(p.x-x)+abs(p.y-y)==1) return true;\n        }\n        return false;\n    };\n\n    for(int turn=0;turn<300;turn++){\n        string actions;\n        actions.reserve(M);\n\n        /* choose an action for every human */\n        for(int i=0;i<M;i++){\n            auto &h = hum[i];\n            char act='.';            // default : stay\n\n            if(h.phase==0){\n                if(h.y != h.target_col){\n                    act = (h.y < h.target_col)? 'R':'L';\n                }else if(h.x != 1){\n                    act = 'U';\n                }else{\n                    h.phase = 1;\n                    h.build_next = true;        // fall through to phase 1\n                }\n            }\n            if(h.phase==1 && act=='.'){\n                if(h.build_next){\n                    int tx = h.x;\n                    int ty = h.y - h.side;      // square where we create a wall\n                    if(inside(tx,ty) && board[tx][ty]=='.' && !pet_near(tx,ty)){\n                        act = (h.side==1)? 'l':'r';   // build\n                    }else{\n                        act='.';                      // skip if illegal\n                    }\n                    h.build_next = false;\n                }else{\n                    if(h.x < H){\n                        act='D';\n                        h.build_next = true;\n                    }else{\n                        act='.';\n                    }\n                }\n            }\n            actions.push_back(act);\n        }\n\n        /* output */\n        cout<<actions<<\"\\n\"<<flush;\n\n        /* apply our actions */\n        for(int i=0;i<M;i++){\n            char c = actions[i];\n            auto &h=hum[i];\n            if(c=='.') continue;\n            if(c=='U'){ h.x--; }\n            else if(c=='D'){ h.x++; }\n            else if(c=='L'){ h.y--; }\n            else if(c=='R'){ h.y++; }\n            else{\n                int tx=h.x, ty=h.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(inside(tx,ty)) board[tx][ty]='#';\n            }\n        }\n\n        /* read pets' movement and update their positions */\n        for(int i=0;i<N;i++){\n            string s; cin>>s;\n            auto &p=pets[i];\n            for(char c:s){\n                if(c=='U') p.x--;\n                else if(c=='D') p.x++;\n                else if(c=='L') p.y--;\n                else if(c=='R') p.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\n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n\n    /*  The next 20 + 19 = 39 lines describe the walls.\n        We read and ignore them, because the route we output is fixed.   */\n    string tmp;\n    for (int i = 0; i < 20; ++i) cin >> tmp;   // horizontal walls\n    for (int i = 0; i < 19; ++i) cin >> tmp;   // vertical walls\n\n    /*  Build the route:  \"DR\" repeated 100 times  */\n    string route;\n    route.reserve(200);\n    for (int i = 0; i < 100; ++i) {\n        route.push_back('D');\n        route.push_back('R');\n    }\n    cout << route << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int H = 30, W = 30;\nconstexpr int DIR = 4;\nconst int di[DIR] = {0,-1,0,1};   // left, up, right, down\nconst int dj[DIR] = {-1,0,1,0};\n\nconst int TO_BASE[8][4] = {\n /*0*/ {1,0,-1,-1},\n /*1*/ {3,-1,-1,0},\n /*2*/ {-1,-1,3,2},\n /*3*/ {-1,2,1,-1},\n /*4*/ {1,0,3,2},\n /*5*/ {3,2,1,0},\n /*6*/ {2,-1,0,-1},\n /*7*/ {-1,3,-1,1}\n};\n\nstruct Timer{\n    const double TL;\n    chrono::steady_clock::time_point st;\n    Timer(double TLsec=1.95):TL(TLsec){st=chrono::steady_clock::now();}\n    double elapsed()const{\n        return chrono::duration<double>(chrono::steady_clock::now()-st).count();\n    }\n    bool remain()const{ return elapsed()<TL; }\n} timer;\n\nint type[H][W];          // input (0..7)\nint rot [H][W];          // current rotation 0..3\nint maskTable[8][4];     // bit 0: L, 1:U, 2:R, 3:D\nint toTable  [8][4][4];  // after rotation r : entry d -> exit\n\n/* ------------------------------------------------------------------ */\n/* pre\u2013computation                                                    */\nvoid precalc(){\n    for(int t=0;t<8;t++){\n        for(int r=0;r<4;r++){\n            int m=0;\n            for(int d=0;d<4;d++){\n                int d0=(d-r+4)%4;\n                int td=TO_BASE[t][d0];\n                int res=-1;\n                if(td!=-1) res=(td+r)%4;\n                toTable[t][r][d]=res;\n                if(res!=-1){\n                    m|=1<<d;\n                    m|=1<<res;\n                }\n            }\n            maskTable[t][r]=m;\n        }\n    }\n}\n/* ------------------------------------------------------------------ */\n/* helpers                                                            */\ninline bool inside(int i,int j){return 0<=i&&i<H&&0<=j&&j<W;}\ninline int countBits(int x){ return __builtin_popcount((unsigned)x); }\n/* ------------------------------------------------------------------ */\n/* current side mask                                                  */\ninline int curMask(int i,int j){return maskTable[type[i][j]][rot[i][j]];}\n/* ------------------------------------------------------------------ */\n/* mismatch counter (open ends)                                       */\nint openEnds=0;          // each endpoint counted once\nvoid recomputeMismatch(){\n    openEnds=0;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int m=curMask(i,j);\n        for(int d=0;d<4;d++) if(m>>d&1){\n            int ni=i+di[d], nj=j+dj[d];\n            if(!inside(ni,nj)){\n                ++openEnds;\n            }else{\n                int nm=curMask(ni,nj);\n                if( !(nm>>((d+2)&3)&1) ) ++openEnds;\n            }\n        }\n    }\n}\n/* delta when we rotate a single tile to `nr`                         */\nint deltaOpenEnds(int i,int j,int nr){\n    int om=curMask(i,j);\n    int nm=maskTable[type[i][j]][nr];\n    if(om==nm) return 0;\n    int diff=0;\n    for(int d=0;d<4;d++){\n        int ni=i+di[d], nj=j+dj[d];\n        int oldU = (om>>d)&1;\n        int newU = (nm>>d)&1;\n        int nbU  = 0;\n        if(inside(ni,nj)) nbU = curMask(ni,nj)>>((d+2)&3)&1;\n        int oldMis = oldU ^ nbU;\n        int newMis = newU ^ nbU;\n        if(inside(ni,nj)) diff += 2*(newMis - oldMis);   // two endpoints\n        else               diff +=    newMis - oldMis;   // one endpoint\n    }\n    return diff;\n}\n/* actually rotate and update openEnds                                */\nvoid applyRotation(int i,int j,int nr){\n    openEnds += deltaOpenEnds(i,j,nr);\n    rot[i][j]=nr;\n}\n/* ------------------------------------------------------------------ */\n/* loop length computation                                            */\nlong long scoreLoops(const array<array<int,W>,H>& R){\n    static bool vis[H][W][4];\n    memset(vis,0,sizeof(vis));\n    vector<int> lengths;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int r=R[i][j];\n        const int (*tbl)[4] = toTable[type[i][j]];\n        int mask = maskTable[type[i][j]][r];\n        for(int sd=0;sd<4;sd++){\n            if(!(mask>>sd&1) || vis[i][j][sd]) continue;\n            int si=i,sj=j,sd0=sd;\n            int ci=i,cj=j,cd=sd;\n            int len=0;\n            while(true){\n                vis[ci][cj][cd]=true;\n                int nd = toTable[type[ci][cj]][ R[ci][cj] ][cd];\n                if(nd==-1) { len=0; break; }            // should not happen\n                int ni = ci + di[nd];\n                int nj = cj + dj[nd];\n                if(!inside(ni,nj)) { len=0; break; }    // open \u2192 should not happen\n                int ndIn = (nd+2)&3;\n                ++len;\n                ci=ni; cj=nj; cd=ndIn;\n                if(ci==si && cj==sj && cd==sd0){lengths.push_back(len);break;}\n                if(vis[ci][cj][cd]){len=0;break;}       // abnormal\n            }\n        }\n    }\n    if(lengths.size()<2) return 0;\n    nth_element(lengths.begin(),lengths.begin()+1,lengths.end(),greater<int>());\n    long long L1= lengths[0];\n    long long L2= lengths[1];\n    return L1*L2;\n}\n/* wrapper using current rot[][]                                      */\nlong long currentScore(){\n    array<array<int,W>,H> R;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) R[i][j]=rot[i][j];\n    return scoreLoops(R);\n}\n/* ------------------------------------------------------------------ */\n/* initial pattern                                                    */\nint desiredMask(int i,int j){\n    bool evenRow = (i&1)==0;\n    bool evenCol = (j&1)==0;\n    if(evenRow){\n        return evenCol ? (1<<2)|(1<<3)  // R & D\n                        : (1<<0)|(1<<3); // L & D\n    }else{\n        return evenCol ? (1<<2)|(1<<1)  // R & U\n                        : (1<<0)|(1<<1); // L & U\n    }\n}\n/* choose initial rotation                                            */\nint bestInitialRot(int ty,int want){\n    int best=-1, bm=-1, extra=10;\n    for(int r=0;r<4;r++){\n        int mk=maskTable[ty][r];\n        int hit = countBits(mk & want);\n        int ext = countBits(mk & ~want);\n        if(hit>bm || (hit==bm && ext<extra)){\n            bm=hit; extra=ext; best=r;\n        }\n    }\n    return best;\n}\n/* ------------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    precalc();\n\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int x; cin>>x;\n        type[i][j]=x;\n    }\n\n    /* 1. initial rotations                                            */\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int want = desiredMask(i,j);\n        rot[i][j]=bestInitialRot(type[i][j],want);\n    }\n    recomputeMismatch();\n\n    /* 2. greedy repair of open ends                                   */\n    mt19937 rng(712367);\n    vector<pair<int,int>> idx;\n    idx.reserve(H*W);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) idx.emplace_back(i,j);\n\n    while(openEnds>0 && timer.remain() && timer.elapsed()<0.6){\n        shuffle(idx.begin(),idx.end(),rng);\n        bool improved=false;\n        for(auto [i,j]:idx){\n            int bestR=rot[i][j];\n            int bestDelta=0;\n            for(int r=0;r<4;r++){\n                int dlt = deltaOpenEnds(i,j,r);\n                if(dlt<bestDelta){\n                    bestDelta=dlt; bestR=r;\n                }\n            }\n            if(bestR!=rot[i][j]){\n                applyRotation(i,j,bestR);\n                improved=true;\n                if(openEnds==0) break;\n            }\n        }\n        if(!improved) break;          // stuck\n    }\n    if(openEnds!=0){\n        recomputeMismatch();          // safety (should not happen)\n    }\n\n    /* 3. hill climb for score                                         */\n    long long bestScore = (openEnds==0)? currentScore() : 0;\n    auto bestRot = array<array<int,W>,H>();\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) bestRot[i][j]=rot[i][j];\n\n    uniform_int_distribution<int> distCell(0,H*W-1);\n    while(timer.remain()){\n        int v = distCell(rng);\n        int i = v/W, j = v%W;\n        int oldR = rot[i][j];\n        int newR = (oldR + 1 + distCell(rng)%3) & 3;\n        int dlt = deltaOpenEnds(i,j,newR);\n        int oldOE = openEnds;\n        applyRotation(i,j,newR);\n\n        bool accept=false;\n        long long candScore = 0;\n        if(openEnds==0){\n            candScore = currentScore();\n            if(candScore>=bestScore) accept=true;\n        }else{\n            if(openEnds<oldOE) accept=true;             // improves consistency\n        }\n\n        if(accept){\n            if(openEnds==0 && candScore>bestScore){\n                bestScore=candScore;\n                for(int x=0;x<H;x++)for(int y=0;y<W;y++) bestRot[x][y]=rot[x][y];\n            }\n        }else{\n            applyRotation(i,j,oldR);                    // revert\n            openEnds=oldOE;\n        }\n    }\n\n    /* 4. output                                                       */\n    string out;\n    out.reserve(H*W);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++)\n        out.push_back(char('0'+bestRot[i][j]));\n    cout<<out<<\"\\n\";\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\nusing  ll = long long;\n\nstruct Timer{\n    chrono::steady_clock::time_point st;\n    Timer(){st = chrono::steady_clock::now();}\n    double elapsed() const {\n        return chrono::duration<double>(chrono::steady_clock::now()-st).count();\n    }\n};\n\nstruct Solver {\n    int N, T;\n    vector<int> board;          // -1 : empty , 0..15 : tile pattern\n    int blank;                  // index of the empty square (0..N*N-1)\n    string bestMoves;           // best prefix found so far\n    int bestScore = -1;         // its S value\n    string curMoves;            // moves executed in the current state\n    int curScore;               // S of current state\n    mt19937 rng;\n\n    static inline int bit(int dir){          // 0U 1D 2L 3R\n        static const int b[4]={2,8,1,4};\n        return b[dir];\n    }\n    static inline int opp(int dir){          // opposite direction\n        return dir^1;\n    }\n\n    int largestTree(const vector<int>& a){\n        const int NN = N*N;\n        vector<char> vis(NN,0);\n        int best=0;\n        static const int dx[4]={-1,1,0,0};\n        static const int dy[4]={0,0,-1,1};\n        queue<int> q;\n        for(int v=0;v<NN;v++){\n            if(a[v]==-1 || vis[v]) continue;\n            int vert=0, edges=0;\n            q.push(v);\n            vis[v]=1;\n            while(!q.empty()){\n                int id=q.front(); q.pop();\n                ++vert;\n                int x=id/N, y=id%N;\n                int t=a[id];\n                for(int d=0;d<4;d++){\n                    int nx=x+dx[d], ny=y+dy[d];\n                    if(nx<0||nx>=N||ny<0||ny>=N) continue;\n                    int nid=nx*N+ny;\n                    if(a[nid]==-1) continue;\n                    if( (t & bit(d)) && (a[nid] & bit(opp(d))) ){\n                        if(id < nid) ++edges;          // count each edge once\n                        if(!vis[nid]){\n                            vis[nid]=1;\n                            q.push(nid);\n                        }\n                    }\n                }\n            }\n            if(edges == vert-1) best = max(best, vert);\n        }\n        return best;\n    }\n\n    bool inRange(int x,int y){return 0<=x && x<N && 0<=y && y<N;}\n\n    void run(){\n        Timer timer;\n        rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n\n        curScore = largestTree(board);\n        bestScore = curScore;\n        bestMoves.clear();\n\n        uniform_real_distribution<double> uni(0.0,1.0);\n        static const int dx[4]={-1,1,0,0};\n        static const int dy[4]={0,0,-1,1};\n        static const char dc[4]={'U','D','L','R'};\n\n        const double TL = 2.95;                 // safety margin\n        const double T0 = 5.0, T1 = 0.1;        // annealing schedule\n\n        while(curMoves.size() < (size_t)T && timer.elapsed() < TL){\n            /* make a candidate move -------------------------------------- */\n            int bx = blank / N, by = blank % N;\n\n            vector<int> candDir;\n            for(int d=0;d<4;d++){\n                int nx=bx+dx[d], ny=by+dy[d];\n                if(inRange(nx,ny)) candDir.push_back(d);\n            }\n            int dir = candDir[rng() % candDir.size()];\n\n            vector<int> nb = board;\n            int nx=bx+dx[dir], ny=by+dy[dir];\n            int nid = nx*N + ny;\n            swap(nb[blank], nb[nid]);\n\n            int candScore = largestTree(nb);\n            int delta = candScore - curScore;\n\n            /* temperature according to progress */\n            double progress = double(curMoves.size()) / double(T);\n            double temp = T0 + (T1-T0)*progress;\n\n            bool accept = false;\n            if(delta >= 0) accept = true;\n            else           accept = (uni(rng) < exp(double(delta)/temp));\n\n            if(accept){\n                // commit\n                board.swap(nb);\n                blank = nid;\n                curMoves.push_back(dc[dir]);\n                curScore = candScore;\n\n                if(curScore > bestScore){\n                    bestScore = curScore;\n                    bestMoves = curMoves;\n                    // early exit if we achieved the theoretical maximum\n                    if(bestScore == N*N-1) break;\n                }\n            }\n        }\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    Solver S;\n    cin >> S.N >> S.T;\n    const int NN = S.N*S.N;\n    S.board.resize(NN);\n    for(int i=0;i<S.N;i++){\n        string row; cin >> row;\n        for(int j=0;j<S.N;j++){\n            char c=row[j];\n            int v = (c<='9') ? c-'0' : c-'a'+10;\n            if(v==0){                         // empty square\n                S.board[i*S.N+j]=-1;\n                S.blank = i*S.N+j;\n            }else{\n                S.board[i*S.N+j]=v;\n            }\n        }\n    }\n\n    S.run();\n    cout << S.bestMoves << '\\n';\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nstruct Evaluator {\n    const vector<pair<int,int>>& pts;\n    const array<int,11>& need;      // need[1..10]\n    Evaluator(const vector<pair<int,int>>& p,\n              const array<int,11>& n): pts(p), need(n) {}\n\n    // returns (#served , b[1..10]) for this grid\n    int operator()(const vector<int>& vx, const vector<int>& hy) const {\n        const int V = vx.size(), H = hy.size();\n        const int W = (V+1)*(H+1);\n        static vector<int> cell;        // reused, keeps counts per rectangle\n        cell.assign(W,0);\n\n        for (auto [x,y]: pts){\n            if (binary_search(vx.begin(),vx.end(),x)) continue; // on a line\n            if (binary_search(hy.begin(),hy.end(),y)) continue;\n            int cx = lower_bound(vx.begin(),vx.end(),x) - vx.begin();\n            int cy = lower_bound(hy.begin(),hy.end(),y) - hy.begin();\n            cell[cx*(H+1)+cy]++;\n        }\n\n        array<int,11> have{};           // b_d, 0-initialised\n        for (int c: cell){\n            if (1<=c && c<=10) ++have[c];\n        }\n        int served = 0;\n        for (int d=1; d<=10; ++d) served += min(need[d], have[d]);\n        return served;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read input ---- */\n    int N,K;  // K is always 100 in the judge data\n    if(!(cin>>N>>K)) return 0;\n    array<int,11> a{};           // 1-based\n    for(int d=1;d<=10;++d) cin>>a[d];\n    vector<pair<int,int>> p(N);\n    for(auto& [x,y]:p) cin>>x>>y;\n\n    const int R = 10000;         // cake radius\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> pickCoord(-R+1, R-1);\n\n    /* ---- search best grid ---- */\n    Evaluator eval(p,a);\n    int bestScore = -1;\n    vector<int> bestVX, bestHY;\n\n    const auto beg = chrono::steady_clock::now();\n    size_t tries = 0;\n    while (true){\n        auto now = chrono::steady_clock::now();\n        double sec = chrono::duration<double>(now - beg).count();\n        if (sec > 2.85) break;\n\n        int v = uniform_int_distribution<int>(1, 99)(rng);\n        int h = uniform_int_distribution<int>(1, 100 - v)(rng);\n\n        // generate unique random x positions\n        unordered_set<int> sx;\n        while ((int)sx.size() < v) sx.insert(pickCoord(rng));\n        vector<int> vx(sx.begin(), sx.end());\n        sort(vx.begin(), vx.end());\n\n        // generate unique random y positions\n        unordered_set<int> sy;\n        while ((int)sy.size() < h) sy.insert(pickCoord(rng));\n        vector<int> hy(sy.begin(), sy.end());\n        sort(hy.begin(), hy.end());\n\n        int score = eval(vx,hy);\n        if (score > bestScore){\n            bestScore = score;\n            bestVX = move(vx);\n            bestHY = move(hy);\n        }\n        ++tries;\n    }\n    // cerr<<\"tries \"<<tries<<\" best \"<<bestScore<<\"\\n\";\n\n    /* ---- output ---- */\n    const ll B = 1'000'000'000LL;\n    int k = (int)bestVX.size() + (int)bestHY.size();\n    cout<<k<<\"\\n\";\n    for (int x: bestVX){\n        cout<<x<<\" \"<<-B<<\"  \"<<x<<\" \"<<B<<\"\\n\";\n    }\n    for (int y: bestHY){\n        cout<<-B<<\" \"<<y<<\"  \"<<B<<\" \"<<y<<\"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Op {\n    int p[8];          // x1 y1 x2 y2 x3 y3 x4 y4\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    if (!(cin >> N >> M)) return 0;\n\n    const int MAXN = 61;                  // problem constraints\n    static bool dot[MAXN][MAXN] = {};     // current dots\n    static bool hEdge[MAXN][MAXN] = {};   // horizontal edge  (y , x)   between (x,y) \u2013 (x+1,y)\n    static bool vEdge[MAXN][MAXN] = {};   // vertical   edge  (y , x)   between (x,y) \u2013 (x,y+1)\n\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        dot[x][y] = true;\n    }\n\n    const int c = (N - 1) / 2;\n    static int weight[MAXN][MAXN];\n    for (int x = 0; x < N; ++x)\n        for (int y = 0; y < N; ++y)\n            weight[x][y] = (x - c) * (x - c) + (y - c) * (y - c) + 1;\n\n    vector<Op> ops;\n\n    while (true) {\n        int bestW = -1, bx = -1, by = -1, miss = -1;\n\n        for (int y = 0; y < N - 1; ++y) {\n            for (int x = 0; x < N - 1; ++x) {\n                if (hEdge[y][x] || hEdge[y + 1][x] || vEdge[y][x] || vEdge[y][x + 1])\n                    continue;                        // some edge already used\n\n                bool present[4] = {\n                    dot[x][y],\n                    dot[x + 1][y],\n                    dot[x + 1][y + 1],\n                    dot[x][y + 1]\n                };\n                int missingCnt = 0, missIdx = -1;\n                for (int k = 0; k < 4; ++k)\n                    if (!present[k]) { ++missingCnt; missIdx = k; }\n\n                if (missingCnt != 1) continue;\n\n                int mx = x + (missIdx == 1 || missIdx == 2);\n                int my = y + (missIdx >= 2);\n                int w  = weight[mx][my];\n\n                if (w > bestW) {\n                    bestW = w;\n                    bx = x; by = y; miss = missIdx;\n                }\n            }\n        }\n\n        if (bestW < 0) break;            // no more move\n\n        // build operation\n        int seq[4];\n        for (int i = 0; i < 4; ++i) seq[i] = (miss + i) & 3;\n\n        auto corner = [&](int idx) -> pair<int,int> {\n            switch (idx) {\n                case 0: return {bx    , by    }; // bottom-left\n                case 1: return {bx + 1, by    }; // bottom-right\n                case 2: return {bx + 1, by + 1}; // top-right\n                default:return {bx    , by + 1}; // top-left\n            }\n        };\n\n        Op op;\n        for (int i = 0; i < 4; ++i) {\n            auto [cx, cy] = corner(seq[i]);\n            op.p[2*i]   = cx;\n            op.p[2*i+1] = cy;\n        }\n        ops.push_back(op);\n\n        // place new dot\n        auto [nx, ny] = corner(miss);\n        dot[nx][ny] = true;\n\n        // mark the four edges\n        hEdge[by][bx]     = true;        // bottom\n        hEdge[by + 1][bx] = true;        // top\n        vEdge[by][bx]     = true;        // left\n        vEdge[by][bx + 1] = true;        // right\n    }\n\n    // output\n    cout << ops.size() << '\\n';\n    for (auto &op : ops) {\n        for (int i = 0; i < 8; ++i) {\n            if (i) cout << ' ';\n            cout << op.p[i];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Grid = array<array<int,10>,10>;\n\n/* ------------------------------------------------------------ */\npair<int,int> locate(const Grid& g,int idx){          // idx : 1-based\n    int cnt = 0;\n    for(int r=0;r<10;r++)\n        for(int c=0;c<10;c++)\n            if(g[r][c]==0 && ++cnt==idx) return {r,c};\n    return {-1,-1};                                    // never reached\n}\n/* ------------------------------------------------------------ */\nvoid tilt(Grid& dst,const Grid& src,char dir){\n    dst = {};                                          // fill with 0\n    if(dir=='F'){                                      // to row 0\n        for(int c=0;c<10;c++){\n            int wr = 0;\n            for(int r=0;r<10;r++)\n                if(src[r][c]) dst[wr++][c] = src[r][c];\n        }\n    }else if(dir=='B'){                                // to row 9\n        for(int c=0;c<10;c++){\n            int wr = 9;\n            for(int r=9;r>=0;r--)\n                if(src[r][c]) dst[wr--][c] = src[r][c];\n        }\n    }else if(dir=='L'){                                // to col 0\n        for(int r=0;r<10;r++){\n            int wc = 0;\n            for(int c=0;c<10;c++)\n                if(src[r][c]) dst[r][wc++] = src[r][c];\n        }\n    }else{                                             // 'R' to col 9\n        for(int r=0;r<10;r++){\n            int wc = 9;\n            for(int c=9;c>=0;c--)\n                if(src[r][c]) dst[r][wc--] = src[r][c];\n        }\n    }\n}\n/* ------------------------------------------------------------ */\nlong long score(const Grid& g){\n    static const int dr[4]={-1,1,0,0};\n    static const int dc[4]={0,0,-1,1};\n    bool vis[10][10]={};\n    long long s=0;\n    queue<pair<int,int>> q;\n    for(int r=0;r<10;r++)for(int c=0;c<10;c++){\n        if(g[r][c]==0||vis[r][c]) continue;\n        int col = g[r][c];\n        int sz  = 0;\n        vis[r][c]=true; q.push({r,c});\n        while(!q.empty()){\n            auto [cr,cc]=q.front(); q.pop(); ++sz;\n            for(int k=0;k<4;k++){\n                int nr=cr+dr[k], nc=cc+dc[k];\n                if(nr<0||nr>=10||nc<0||nc>=10) continue;\n                if(!vis[nr][nc] && g[nr][nc]==col){\n                    vis[nr][nc]=true; q.push({nr,nc});\n                }\n            }\n        }\n        s += 1LL*sz*sz;\n    }\n    return s;\n}\n/* ------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int flav[100];\n    for(int i=0;i<100;i++) cin>>flav[i];\n\n    Grid board={};\n\n    const char DIRS[4]={'F','B','L','R'};\n\n    for(int t=0;t<100;t++){\n        int p; cin>>p;\n        auto [r,c]=locate(board,p);\n        board[r][c]=flav[t];\n\n        if(t==99){                       // after putting the 100-th candy the grid is full\n            cout << \"F\\n\" << flush;      // arbitrary, does not change anything\n            break;\n        }\n\n        long long bestScore = -1;\n        char bestDir       = 'F';\n        Grid bestBoard;\n\n        for(char dir:DIRS){\n            Grid tmp;\n            tilt(tmp,board,dir);\n            long long sc = score(tmp);\n            if(sc>bestScore){\n                bestScore = sc;\n                bestDir   = dir;\n                bestBoard = tmp;\n            }\n        }\n        board = bestBoard;\n        cout << bestDir << '\\n' << flush;\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- splitmix64 (fast 64-bit hash) ------------------------------ */\nstatic uint64_t splitmix64(uint64_t x) {\n    x += 0x9e3779b97f4a7c15ULL;\n    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9ULL;\n    x = (x ^ (x >> 27)) * 0x94d049bb133111ebULL;\n    return x ^ (x >> 31);\n}\n\n/* ---------- small fixed bit matrix (max N = 100) ----------------------- */\nstruct Matrix {\n    // each row fits in two 64-bit words (128 bits \u2265 100)\n    array<array<uint64_t,2>,100> row{};\n    int N = 0;\n\n    inline void clear(int n) { N = n; for (int i=0;i<N;i++) row[i][0]=row[i][1]=0; }\n\n    inline void setEdge(int i,int j) {\n        if (j<64) row[i][0] |= 1ULL<<j;\n        else      row[i][1] |= 1ULL<<(j-64);\n    }\n    inline bool edge(int i,int j) const {\n        if (j<64) return row[i][0]>>j & 1ULL;\n        else      return row[i][1]>>(j-64) & 1ULL;\n    }\n    inline int degree(int i) const {             // popcount of the row\n        return __builtin_popcountll(row[i][0]) +\n               __builtin_popcountll(row[i][1]);\n    }\n};\n\n/* ---------- canonicalisation: 3 WL rounds + stable sort --------------- */\nstruct Canon {\n    vector<uint64_t> bits;        // bitset of N(N-1)/2 edges (canonical)\n};\n\nstatic Canon canonicalise(const Matrix& g) {\n    const int N = g.N;\n    vector<uint64_t> col(N);\n    for (int v=0; v<N; v++) col[v] = g.degree(v);    // initial colour\n\n    for (int it=0; it<3; it++) {\n        vector<uint64_t> ncol(N);\n        for (int v=0; v<N; v++) {\n            uint64_t sum = 0, sum2 = 0;\n            for (int u=0; u<N; u++) if (g.edge(v,u)) {\n                sum  += col[u];\n                sum2 += col[u]*col[u];\n            }\n            ncol[v] = splitmix64(col[v] ^ splitmix64(sum) ^ (sum2<<1));\n        }\n        col.swap(ncol);\n    }\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    stable_sort(ord.begin(), ord.end(), [&](int a,int b){\n        if (col[a]!=col[b]) return col[a]<col[b];\n        return a<b;\n    });\n    vector<int> pos(N);\n    for (int i=0;i<N;i++) pos[ ord[i] ] = i;\n\n    // build bitset in the canonical order (lexicographic by (i,j))\n    const size_t TOT = N*(N-1)/2;\n    size_t W = (TOT+63)>>6;\n    vector<uint64_t> bits(W,0ULL);\n    size_t idx = 0;\n    for (int i=0;i<N;i++){\n        int oi = ord[i];\n        for (int j=i+1;j<N;j++){\n            int oj = ord[j];\n            if (g.edge(oi,oj))\n                bits[idx>>6] |= 1ULL<<(idx&63);\n            ++idx;\n        }\n    }\n    return { std::move(bits) };\n}\n\n/* ---------- main ------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M; double eps;\n    if(!(cin>>M>>eps)) return 0;\n\n    /* choose N depending on \u03b5:  40 for small noise, up to 60 for \u03b5=0.4 */\n    int N = 40 + int( round(eps * 50.0) );   // 40 \u2026 60\n    N = max(4, min(100, N));\n\n    const size_t TOT = N*(N-1)/2;\n    /* prepare catalogue ------------------------------------------------- */\n    vector<Canon> catalogue(M);\n    vector<string> outStr(M);\n    Matrix tmp; tmp.clear(N);\n\n    mt19937_64 rng(123456789);           // fixed seed (deterministic)\n    uniform_int_distribution<uint64_t> bit01(0,1);\n\n    for (int k=0; k<M; k++) {\n        tmp.clear(N);\n        string s; s.reserve(TOT);\n        size_t idx = 0;\n        for (int i=0;i<N;i++){\n            for (int j=i+1;j<N;j++){\n                int b = bit01(rng);\n                s.push_back(b?'1':'0');\n                if (b) { tmp.setEdge(i,j); tmp.setEdge(j,i); }\n                ++idx;\n            }\n        }\n        outStr[k]=std::move(s);\n        catalogue[k]=canonicalise(tmp);\n    }\n\n    /* --------------- output graphs ------------------------------------ */\n    cout<<N<<\"\\n\";\n    for (int k=0;k<M;k++) cout<<outStr[k]<<\"\\n\";\n    cout.flush();\n\n    /* --------------- answer 100 queries --------------------------------*/\n    const size_t WORDS = (TOT+63)>>6;\n\n    for (int q=0;q<100;q++){\n        string hStr; cin>>hStr;\n        Matrix H; H.clear(N);\n        size_t idx=0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                if(hStr[idx++]=='1'){ H.setEdge(i,j); H.setEdge(j,i); }\n            }\n        }\n        Canon CH = canonicalise(H);\n\n        int best = 0;\n        int bestDist = INT_MAX;\n        for (int k=0;k<M;k++){\n            const auto& B = catalogue[k].bits;\n            int dist = 0;\n            for (size_t w=0; w<WORDS; w++)\n                dist += __builtin_popcountll( CH.bits[w] ^ B[w] );\n            if(dist<bestDist){ bestDist=dist; best=k; }\n        }\n        cout<<best<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int idx;\n    int u, v, w;\n    int priority;           // deg(u)+deg(v)\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- input ---------- */\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    vector<int> deg(N, 0);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {i, u, v, w, 0};\n        ++deg[u]; ++deg[v];\n    }\n    /* the coordinates follow \u2013 we ignore them */\n    for (int i = 0; i < N; ++i) {\n        int x, y;  cin >> x >> y;\n    }\n\n    /* ---------- edge priorities ---------- */\n    for (auto& e : edges) e.priority = deg[e.u] + deg[e.v];\n\n    /* sort: important edges first, random tie-breaking */\n    std::mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    std::shuffle(edges.begin(), edges.end(), rng);\n    std::stable_sort(edges.begin(), edges.end(),\n        [](const Edge& a, const Edge& b){ return a.priority > b.priority; });\n\n    /* ---------- greedy assignment ---------- */\n    vector<int> load(D, 0);                          // edges already on day d\n    vector<array<uint8_t, 30>> used(N);              // used[v][d]   (D \u2264 30)\n    /* uint8_t is plenty because per vertex per day we will never exceed K \u2264 600 */\n\n    vector<int> answer(M, 0);                        // 0-based temporarily\n\n    for (const auto& e : edges) {\n        int bestDay = -1;\n        int bestScore = INT_MAX;\n        int bestLoad  = INT_MAX;\n\n        /* evaluate all feasible days */\n        for (int d = 0; d < D; ++d) {\n            if (load[d] >= K) continue;              // full\n\n            int score = used[e.u][d] + used[e.v][d];\n            if (score < bestScore ||\n               (score == bestScore && load[d] < bestLoad)) {\n                bestScore = score;\n                bestLoad  = load[d];\n                bestDay   = d;\n            }\n        }\n\n        /* because K is generous, bestDay must exist */\n        if (bestDay == -1) {                         // very unlikely fallback\n            bestDay = int(min_element(load.begin(), load.end()) - load.begin());\n        }\n\n        answer[e.idx] = bestDay;\n        ++load[bestDay];\n        ++used[e.u][bestDay];\n        ++used[e.v][bestDay];\n    }\n\n    /* ---------- output (1-based) ---------- */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << (answer[i] + 1);\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct RooksMaker {\n    int D;\n    // build the rook set for one z-slice of one object, trying to reuse the vector< pair<int,int> > shared\n    static vector<pair<int,int>> build(int D,\n                                       const vector<int>& rows,\n                                       const vector<int>& cols,\n                                       const vector<pair<int,int>>& shared) {\n        vector<char> rowCov(D, 0), colCov(D, 0);\n        vector<pair<int,int>> res;\n\n        // 1. put all shared rooks that are valid for this object\n        for (auto [x,y] : shared) {\n            if (!rowCov[x] && !colCov[y]) {      // it surely is valid\n                res.emplace_back(x,y);\n                rowCov[x] = colCov[y] = 1;\n            }\n        }\n\n        // 2. cover remaining rows\n        int cy = 0;\n        for (int x : rows) if (!rowCov[x]) {\n            int y = cols[cy % cols.size()];\n            res.emplace_back(x, y);\n            rowCov[x] = colCov[y] = 1;\n            ++cy;\n        }\n\n        // 3. cover remaining columns\n        int cx = 0;\n        for (int y : cols) if (!colCov[y]) {\n            int x = rows[cx % rows.size()];\n            res.emplace_back(x, y);\n            rowCov[x] = colCov[y] = 1;\n            ++cx;\n        }\n        return res;   // size == max(|rows|,|cols|)\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\n    vector<vector<string>> front(2, vector<string>(D));\n    vector<vector<string>> rightv(2, vector<string>(D));\n    for (int k = 0; k < 2; ++k) {\n        for (int z = 0; z < D; ++z)  cin >> front[k][z];\n        for (int z = 0; z < D; ++z)  cin >> rightv[k][z];\n    }\n\n    const int SZ = D*D*D;\n    vector<char> occ1(SZ, 0), occ2(SZ, 0);          // occupancy of each voxel\n    auto idx = [D](int x,int y,int z){ return x*D*D + y*D + z; };\n\n    /* ------------------------------------------------------------------ *\n       create voxels slice by slice\n     * ------------------------------------------------------------------ */\n    for (int z = 0; z < D; ++z) {\n        // required rows/columns in this slice\n        vector<int> X[2], Y[2];\n        for (int x = 0; x < D; ++x) {\n            if (front[0][z][x]=='1') X[0].push_back(x);\n            if (front[1][z][x]=='1') X[1].push_back(x);\n        }\n        for (int y = 0; y < D; ++y) {\n            if (rightv[0][z][y]=='1') Y[0].push_back(y);\n            if (rightv[1][z][y]=='1') Y[1].push_back(y);\n        }\n\n        // intersection for shared rooks\n        vector<int> Xcom, Ycom;\n        {\n            vector<char> mark(D,0);\n            for (int x:X[0]) mark[x]=1;\n            for (int x:X[1]) if(mark[x]) Xcom.push_back(x);\n            fill(mark.begin(), mark.end(), 0);\n            for (int y:Y[0]) mark[y]=1;\n            for (int y:Y[1]) if(mark[y]) Ycom.push_back(y);\n        }\n        int k = min((int)Xcom.size(), (int)Ycom.size());\n        vector<pair<int,int>> shared;\n        for (int i=0;i<k;i++)\n            shared.emplace_back(Xcom[i], Ycom[i]);\n\n        // build rook sets\n        vector<pair<int,int>> R1 =\n            RooksMaker::build(D, X[0], Y[0], shared);\n        vector<pair<int,int>> R2 =\n            RooksMaker::build(D, X[1], Y[1], shared);\n\n        // mark occupancy\n        for (auto [x,y]:R1) occ1[idx(x,y,z)] = 1;\n        for (auto [x,y]:R2) occ2[idx(x,y,z)] = 1;\n    }\n\n    /* ------------------------------------------------------------------ *\n       determine shared / unique voxels and make blocks\n     * ------------------------------------------------------------------ */\n    vector<int> b1(SZ, 0), b2(SZ, 0);  // resulting block-ID grids\n    int nextId = 1;\n\n    // helper visited array for shared voxels\n    vector<char> visShared(SZ, 0);\n\n    // 1) shared pillars, one pillar-block per (x,y) and contiguous z-segment\n    for (int x=0;x<D;++x) for (int y=0;y<D;++y) {\n        int z = 0;\n        while (z < D) {\n            int p = idx(x,y,z);\n            if (occ1[p] && occ2[p] && !visShared[p]) {\n                int z0 = z;\n                while (z < D && occ1[idx(x,y,z)] && occ2[idx(x,y,z)])\n                    visShared[idx(x,y,z++)] = 1;\n                int z1 = z-1;\n                int id = nextId++;\n                for (int zz=z0; zz<=z1; ++zz) {\n                    int pos = idx(x,y,zz);\n                    b1[pos] = b2[pos] = id;\n                }\n            } else ++z;\n        }\n    }\n\n    // 2) unique voxels \u2192 single-cube blocks\n    for (int p=0; p<SZ; ++p) {\n        if (occ1[p] && !b1[p]) {\n            int id = nextId++;\n            b1[p] = id;          // only object-1 uses it\n        }\n        if (occ2[p] && !b2[p]) {\n            int id = nextId++;\n            b2[p] = id;          // only object-2 uses it\n        }\n    }\n\n    /* ------------------------------------------------------------------ *\n       output\n     * ------------------------------------------------------------------ */\n    cout << nextId-1 << '\\n';\n    for (int p=0;p<SZ;++p) {\n        if (p) cout << ' ';\n        cout << b1[p];\n    }\n    cout << '\\n';\n    for (int p=0;p<SZ;++p) {\n        if (p) cout << ' ';\n        cout << b2[p];\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 Neigh {\n    int to, idx;\n};\n\nconstexpr int MAX_R = 5000;\n\nlong long dist_int(int x1, int y1, int x2, int y2) {\n    long long dx = 1LL * x1 - x2;\n    long long dy = 1LL * y1 - y2;\n    return llround(std::ceil(std::sqrt(double(dx * dx + dy * dy))));\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    vector<int> vx(N), vy(N);\n    for (int i = 0; i < N; ++i) cin >> vx[i] >> vy[i];\n\n    vector<Edge> es(M);\n    vector<vector<Neigh>> g(N);\n    for (int i = 0; i < M; ++i) {\n        int a, b; long long w;\n        cin >> a >> b >> w;\n        --a; --b;\n        es[i] = {a, b, w};\n        g[a].push_back({b, i});\n        g[b].push_back({a, i});\n    }\n\n    vector<int> rx(K), ry(K);\n    for (int k = 0; k < K; ++k) cin >> rx[k] >> ry[k];\n\n    /* ---------------- shortest-path tree from root (vertex 0) --------------- */\n    const long long INF = (1LL << 60);\n    vector<long long> dist(N, INF);\n    vector<int> parV(N, -1), parE(N, -1);\n    priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;\n    dist[0] = 0;\n    pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (auto [to, idx] : g[v]) {\n            long long nd = d + es[idx].w;\n            if (nd < dist[to]) {\n                dist[to] = nd;\n                parV[to] = v;\n                parE[to] = idx;\n                pq.push({nd, to});\n            }\n        }\n    }\n\n    /* --------------- pre-compute residents reachable from each vertex ------- */\n    vector<vector<pair<int,int>>> cov(N);          // (resident id , distance<=5000)\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            int d = (int)dist_int(vx[i], vy[i], rx[k], ry[k]);\n            if (d <= MAX_R) cov[i].push_back({k, d});\n        }\n    }\n\n    /* ------------------------------ greedy ---------------------------------- */\n    vector<char> covered(K, 0);\n    int coveredCnt = 0;\n\n    vector<char> stationChosen(N, 0);\n    vector<int> P(N, 0);\n\n    vector<char> edgeOn(M, 0);\n\n    auto additional_edge_cost = [&](int v)->long long {\n        long long c = 0;\n        while (v != 0) {\n            int e = parE[v];\n            if (!edgeOn[e]) c += es[e].w;\n            v = parV[v];\n        }\n        return c;\n    };\n    auto turn_on_path = [&](int v){\n        while (v != 0) {\n            int e = parE[v];\n            edgeOn[e] = 1;\n            v = parV[v];\n        }\n    };\n\n    while (coveredCnt < K) {\n        int bestV = -1, bestRad = 0, bestGain = 0;\n        double bestScore = -1.0;\n        long long bestAddEdge = 0;\n\n        for (int v = 0; v < N; ++v) if (!stationChosen[v]) {\n            int gain = 0, mx = 0;\n            for (auto [rid, d] : cov[v])\n                if (!covered[rid]) { ++gain; mx = max(mx, d); }\n            if (gain == 0) continue;\n\n            long long eCost = additional_edge_cost(v);\n            long long cost = eCost + 1LL * mx * mx;\n            double sc = double(gain) / double(cost);\n            if (sc > bestScore) {\n                bestScore = sc;\n                bestV = v;\n                bestRad = mx;\n                bestGain = gain;\n                bestAddEdge = eCost;\n            }\n        }\n\n        if (bestV == -1) {                 // should not happen\n            cerr << \"fallback!\\n\";\n            for (int i = 0; i < N; ++i) { stationChosen[i] = 1; P[i] = 5000; }\n            fill(edgeOn.begin(), edgeOn.end(), 1);\n            break;\n        }\n\n        /* apply */\n        stationChosen[bestV] = 1;\n        P[bestV] = bestRad;\n        for (auto [rid, d] : cov[bestV])\n            if (!covered[rid] && d <= bestRad) { covered[rid] = 1; ++coveredCnt; }\n        turn_on_path(bestV);\n    }\n\n    /* ---------------- shrink radii: assign each resident to nearest --------- */\n    vector<int> chosenList;\n    for (int v = 0; v < N; ++v) if (stationChosen[v]) chosenList.push_back(v);\n\n    vector<int> bestRad(N, 0);\n    for (int k = 0; k < K; ++k) {\n        int bestV = -1, bestD = MAX_R + 1;\n        for (int v : chosenList) {\n            int d = (int)dist_int(vx[v], vy[v], rx[k], ry[k]);\n            if (d < bestD) { bestD = d; bestV = v; }\n        }\n        bestRad[bestV] = max(bestRad[bestV], bestD);\n    }\n    for (int v = 0; v < N; ++v) if (stationChosen[v]) P[v] = bestRad[v];\n\n    /* --------------- final edge set (union of paths to chosen) -------------- */\n    fill(edgeOn.begin(), edgeOn.end(), 0);\n    for (int v = 0; v < N; ++v) if (stationChosen[v]) {\n        int cur = v;\n        while (cur != 0) {\n            int e = parE[cur];\n            edgeOn[e] = 1;\n            cur = parV[cur];\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    for (int e = 0; e < M; ++e) {\n        if (e) cout << ' ';\n        cout << int(edgeOn[e]);\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    /* read input */\n    vector<vector<int>> a(N);\n    for (int x = 0; x < N; ++x) {\n        a[x].resize(x + 1);\n        for (int y = 0; y <= x; ++y) cin >> a[x][y];\n    }\n\n    vector<Swap> ops;\n    ops.reserve(5000);          // worst-case 4 495\n\n    auto do_swap = [&](int x1, int y1, int x2, int y2) {\n        swap(a[x1][y1], a[x2][y2]);\n        ops.push_back({x1, y1, x2, y2});\n    };\n\n    /* bottom-up heapify (Floyd) */\n    for (int x = N - 2; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int cx = x, cy = y;\n            while (cx < N - 1) {\n                int lx = cx + 1, ly = cy;       // left child\n                int rx = cx + 1, ry = cy + 1;   // right child\n\n                int minx = lx, miny = ly;\n                if (a[rx][ry] < a[lx][ly]) {\n                    minx = rx;\n                    miny = ry;\n                }\n                if (a[cx][cy] <= a[minx][miny]) break;\n\n                do_swap(cx, cy, minx, miny);\n                cx = minx;\n                cy = miny;\n            }\n        }\n    }\n\n    /* safeguard \u2013 in the very unlikely event we overshoot */\n    if (ops.size() > 10000) ops.resize(10000);\n\n    /* output */\n    cout << ops.size() << '\\n';\n    for (auto &s: ops)\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos{int r,c;};\nconst int DR[4]={-1,1,0,0};\nconst int DC[4]={0,0,-1,1};\nusing Grid = vector<vector<int>>;      // -2 obstacle, -1 empty, >=0 container id\n\nint D=9;                 // fixed\nint ENTR_C;              // (D-1)/2 = 4\nint K;                   // number of containers  = D*D-1-N\n\n// convenience\nbool inside(int r,int c){ return 0<=r && r<D && 0<=c && c<D; }\n\n/* BFS over current empty squares; returns list of reachable empties\n   and fills dist with distances (dist[e_r][e_c]=0).               */\nvector<Pos> bfs_empty(const Grid& g,const Pos& ent,vector<vector<int>>& dist){\n    dist.assign(D, vector<int>(D,-1));\n    vector<Pos> empties;\n    queue<Pos> q;\n    q.push(ent);\n    dist[ent.r][ent.c]=0;\n\n    while(!q.empty()){\n        auto [r,c]=q.front(); q.pop();\n        empties.push_back({r,c});\n        for(int dir=0;dir<4;++dir){\n            int nr=r+DR[dir], nc=c+DC[dir];\n            if(!inside(nr,nc)) continue;\n            if(g[nr][nc]==-1 && dist[nr][nc]==-1){\n                dist[nr][nc]=dist[r][c]+1;\n                q.push({nr,nc});\n            }\n        }\n    }\n    return empties;\n}\n\n/* true\u21d4 container at (r,c) has at least one adjacent empty cell that is\n   already reachable (dist>=0)                                            */\ninline bool container_reachable(const Grid& g,int r,int c,const vector<vector<int>>& dist){\n    for(int dir=0;dir<4;++dir){\n        int nr=r+DR[dir], nc=c+DC[dir];\n        if(inside(nr,nc) && dist[nr][nc]>=0) return true;\n    }\n    return false;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;                         // number of obstacles\n    cin>>D>>N;\n    ENTR_C=(D-1)/2;\n    Pos ENTR{0,ENTR_C};\n\n    Grid g(D, vector<int>(D,-1));  // empty\n    for(int k=0;k<N;++k){\n        int r,c; cin>>r>>c;\n        g[r][c]=-2;                // obstacle\n    }\n    K=D*D-1-N;\n\n    /* pre\u2013compute static BFS distance ignoring containers */\n    vector<vector<int>> dist0(D, vector<int>(D,-1));\n    {\n        queue<Pos> q;\n        q.push(ENTR);\n        dist0[ENTR.r][ENTR.c]=0;\n        while(!q.empty()){\n            auto [r,c]=q.front(); q.pop();\n            for(int d=0;d<4;++d){\n                int nr=r+DR[d], nc=c+DC[d];\n                if(!inside(nr,nc)) continue;\n                if(g[nr][nc]!=-2 && dist0[nr][nc]==-1){\n                    dist0[nr][nc]=dist0[r][c]+1;\n                    q.push({nr,nc});\n                }\n            }\n        }\n    }\n\n    /* vector of all non-forbidden squares, sorted by dist0 inc */\n    vector<Pos> all_cells;\n    for(int r=0;r<D;++r)for(int c=0;c<D;++c){\n        if(r==ENTR.r && c==ENTR.c) continue;\n        if(g[r][c]==-2) continue;\n        all_cells.push_back({r,c});\n    }\n    sort(all_cells.begin(), all_cells.end(), [&](const Pos& a,const Pos& b){\n        int da=dist0[a.r][a.c], db=dist0[b.r][b.c];\n        if(da!=db) return da<db;\n        return tie(a.r,a.c)<tie(b.r,b.c);\n    });\n    vector<vector<int>> rankCell(D, vector<int>(D,-1));\n    for(size_t i=0;i<all_cells.size();++i){\n        rankCell[all_cells[i].r][all_cells[i].c]=static_cast<int>(i);\n    }\n\n    vector<Pos> idPos(K);          // final positions of every id\n    vector<vector<int>> distTmp;   // reused buffer\n\n    /* ========= online placement phase ========= */\n    for(int step=0; step<K; ++step){\n        int id; cin>>id;\n        /* reachable empty cells right now */\n        auto reachable = bfs_empty(g,ENTR,distTmp);\n\n        /* sort reachable by static distance */\n        sort(reachable.begin(), reachable.end(),\n             [&](const Pos& a,const Pos& b){ return dist0[a.r][a.c] < dist0[b.r][b.c]; });\n\n        int chooseIdx;\n        if(reachable.size()==1){\n            chooseIdx=0;\n        }else{\n            double ratio= static_cast<double>(id)/(K-1); // 0..1\n            chooseIdx = static_cast<int>( round( ratio * (int(reachable.size())-1) ) );\n        }\n        Pos chosen = reachable[chooseIdx];\n\n        /* store */\n        g[chosen.r][chosen.c] = id;\n        idPos[id]=chosen;\n\n        cout<<chosen.r<<\" \"<<chosen.c<<\"\\n\"<<flush;\n    }\n\n    /* ========= retrieving phase ========= */\n    vector<char> shipped(K,0);\n    vector<Pos> answer;\n    answer.reserve(K);\n\n    int nextNeed=0;\n\n    while((int)answer.size()<K){\n        /* current reachable empty & dist */\n        auto empties = bfs_empty(g,ENTR,distTmp);\n\n        /* list of reachable containers with their min distance */\n        int best_for_need = -1;           // position index in answer vector\n        int best_other_id = -1;\n        int best_other_dist = 1e9;\n        Pos best_other_pos{-1,-1};\n\n        for(int id=0; id<K; ++id){\n            if(shipped[id]) continue;\n            auto [r,c]=idPos[id];\n            if(container_reachable(g,r,c,distTmp)){\n                if(id==nextNeed){\n                    best_for_need = id;\n                    break;               // perfect, take it\n                }else{\n                    int mind=1e9;\n                    for(int d=0;d<4;++d){\n                        int nr=r+DR[d], nc=c+DC[d];\n                        if(inside(nr,nc) && distTmp[nr][nc]>=0)\n                            mind = min(mind, distTmp[nr][nc]+1);\n                    }\n                    if(mind<best_other_dist || (mind==best_other_dist && id<best_other_id)){\n                        best_other_dist=mind;\n                        best_other_id=id;\n                        best_other_pos={r,c};\n                    }\n                }\n            }\n        }\n\n        int take_id;\n        Pos take_pos;\n        if(best_for_need!=-1){\n            take_id=best_for_need;\n            take_pos=idPos[take_id];\n        }else{\n            take_id=best_other_id;\n            take_pos=best_other_pos;\n        }\n\n        /* ship it */\n        shipped[take_id]=1;\n        g[take_pos.r][take_pos.c]=-1;         // becomes empty\n        answer.push_back(take_pos);\n\n        if(take_id==nextNeed){\n            while(nextNeed<K && shipped[nextNeed]) ++nextNeed;\n        }\n    }\n\n    /* ========= output retrieving order ========= */\n    for(auto &p:answer){\n        cout<<p.r<<\" \"<<p.c<<\"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 50;          // fixed by the task\nconstexpr int M = 100;         // fixed by the task\nconstexpr int DX[4] = {-1, 1, 0, 0};\nconstexpr int DY[4] = {0, 0, -1, 1};\n\nstruct State {\n    int g[N][N];                       // current grid\n    int cnt[M + 1] = {};               // squares per colour\n    int adj[M + 1][M + 1] = {};        // unordered edge counts (u<=v)\n    bool orig0Adj[M + 1] = {};         // was (0,x) adjacent in the input?\n    bool inQ[N][N] = {};               // helper for BFS/flood queue\n} st;\n\n/* ---------------------------------------------------------------------- */\ninline bool inside(int x, int y) { return 0 <= x && x < N && 0 <= y && y < N; }\n\ninline void addEdge(int a, int b, int delta) {       // a<=b\n    if (a > b) swap(a, b);\n    st.adj[a][b] += delta;\n}\n\n/* ---------------------------------------------------------------------- */\nvoid buildInitial(istream &in) {\n    int n, m;   in >> n >> m;   // both are 50 / 100\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            in >> st.g[i][j];\n            ++st.cnt[ st.g[i][j] ];\n        }\n\n    /* edge counters ---------------------------------------------------- */\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int c = st.g[i][j];\n\n            // right neighbour or outside\n            int d = (j + 1 < N) ? st.g[i][j + 1] : 0;\n            if (c != d) addEdge(c, d, +1);\n\n            // down neighbour or outside\n            d = (i + 1 < N) ? st.g[i + 1][j] : 0;\n            if (c != d) addEdge(c, d, +1);\n        }\n\n    for (int d = 1; d <= M; ++d)\n        st.orig0Adj[d] = st.adj[0][d] > 0;\n}\n\n/* ---------------------------------------------------------------------- */\nbool connectedAfterRemoval(int x, int y, int col) {\n    // we know cnt[col] >= 2\n    bool vis[N][N] = {};\n    queue<pair<int,int>> q;\n\n    // find a starting cell of 'col' different from (x,y)\n    for (int i = 0; i < N && q.empty(); ++i)\n        for (int j = 0; j < N; ++j)\n            if (!(i == x && j == y) && st.g[i][j] == col) {\n                q.emplace(i, j);\n                vis[i][j] = true;\n                break;\n            }\n\n    int need = st.cnt[col] - 1;        // we are pretending (x,y) is removed\n    int seen = 0;\n    while (!q.empty()) {\n        auto [cx, cy] = q.front(); q.pop();\n        ++seen;\n        if (seen == need) return true;      // early exit\n\n        for (int dir = 0; dir < 4; ++dir) {\n            int nx = cx + DX[dir], ny = cy + DY[dir];\n            if (!inside(nx, ny) || vis[nx][ny]) continue;\n            if (nx == x && ny == y) continue;           // pretend removed\n            if (st.g[nx][ny] == col) {\n                vis[nx][ny] = true;\n                q.emplace(nx, ny);\n            }\n        }\n    }\n    return false;\n}\n\n/* ---------------------------------------------------------------------- */\nbool tryRemove(int x, int y) {\n    int c = st.g[x][y];\n    if (c == 0 || st.cnt[c] == 1) return false;\n\n    // quick filters ------------------------------------------------------\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + DX[dir], ny = y + DY[dir];\n        int d = inside(nx, ny) ? st.g[nx][ny] : 0;\n        if (d == c) continue;\n\n        // would this create a new (0,d)?\n        if (d != 0 && !st.orig0Adj[d]) return false;\n\n        // would it delete the *last* (c,d)?\n        int a = c, b = d; if (a > b) swap(a, b);\n        if (st.adj[a][b] <= 1) return false;\n    }\n\n    // connectivity -------------------------------------------------------\n    if (!connectedAfterRemoval(x, y, c)) return false;\n\n    /* perform the removal --------------------------------------------- */\n    for (int dir = 0; dir < 4; ++dir) {\n        int nx = x + DX[dir], ny = y + DY[dir];\n        int d = inside(nx, ny) ? st.g[nx][ny] : 0;\n        if (d == c) continue;\n\n        addEdge(min(c,d), max(c,d), -1);        // delete old edge\n        if (d != 0) addEdge(0, d, +1);          // new edge between 0 and d\n    }\n\n    st.g[x][y] = 0;\n    --st.cnt[c];\n    return true;\n}\n\n/* ---------------------------------------------------------------------- */\nvoid floodFillZeros() {\n    queue<pair<int,int>> q;\n\n    auto touchZero = [&](int i, int j)->bool {\n        if (st.g[i][j] == 0) return false;\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = i + DX[dir], nj = j + DY[dir];\n            if (!inside(ni, nj) || st.g[ni][nj] == 0) return true;\n        }\n        return false;\n    };\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (touchZero(i,j)) {\n                q.emplace(i,j);\n                st.inQ[i][j] = true;\n            }\n\n    while (!q.empty()) {\n        auto [x,y] = q.front(); q.pop();\n        st.inQ[x][y] = false;\n        if (st.g[x][y]==0) continue;           // already removed earlier\n        if (!touchZero(x,y)) continue;         // not any more\n\n        if (tryRemove(x,y)) {\n            // neighbours may have become candidates\n            for (int dir = 0; dir < 4; ++dir) {\n                int nx = x + DX[dir], ny = y + DY[dir];\n                if (!inside(nx, ny)) continue;\n                if (st.g[nx][ny]==0 || st.inQ[nx][ny]) continue;\n                if (touchZero(nx,ny)) {\n                    q.emplace(nx,ny);\n                    st.inQ[nx][ny] = true;\n                }\n            }\n        }\n    }\n}\n\n/* ---------------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    buildInitial(cin);\n    floodFillZeros();\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 << st.g[i][j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, D, Q;\n    if (!(cin >> N >> D >> Q)) return 0;\n\n    vector<int> win(N, 0);      // number of direct wins of each item\n    int used = 0;               // queries already performed\n\n    /* ------------------------------------------------------------------\n       1.  Do as many distinct 1-vs-1 comparisons as possible.\n           For fairness we walk over the list of all pairs once in a\n           random order and stop as soon as we have no queries left\n           for \u201creal\u201d information gathering (we still need a few extra\n           queries in case Q is not yet exhausted \u2192 dummy part below).\n       ------------------------------------------------------------------ */\n\n    vector<pair<int,int>> pairs;\n    pairs.reserve(N*(N-1)/2);\n    for (int i = 0; i < N; ++i)\n        for (int j = i+1; j < N; ++j)\n            pairs.emplace_back(i, j);\n\n    std::mt19937_64 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(pairs.begin(), pairs.end(), rng);\n\n    size_t idx = 0;\n    while (used < Q && idx < pairs.size()) {\n        auto [a, b] = pairs[idx++];\n        cout << 1 << ' ' << 1 << ' ' << a << ' ' << b << '\\n' << flush;\n        string res;  cin >> res;\n        ++used;\n        if (res == \">\")      ++win[a];\n        else if (res == \"<\") ++win[b];\n        /*  '=' is virtually impossible for continuous weights \u2013 ignore */\n    }\n\n    /* ------------------------------------------------------------------\n       2.  If we still have to issue queries to reach exactly Q, reuse\n           the fixed pair (0,1).  We do NOT use their answers any more\n           (would bias the scores heavily).\n       ------------------------------------------------------------------ */\n    while (used < Q) {\n        cout << 1 << ' ' << 1 << ' ' << 0 << ' ' << 1 << '\\n' << flush;\n        string dummy; cin >> dummy;\n        ++used;\n    }\n\n    /* ------------------------------------------------------------------\n       3.  Build a rank from the collected win counts.\n           Ties are broken by the original index to keep sort stable.\n       ------------------------------------------------------------------ */\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int i, int j){\n        if (win[i] != win[j]) return win[i] > win[j];   // more wins \u21d2 heavier\n        return i < j;\n    });\n\n    vector<int> rankPos(N);             // rankPos[item] = 0 .. N-1 (0 \u2261 heaviest)\n    for (int r = 0; r < N; ++r) rankPos[ord[r]] = r;\n\n    /* ------------------------------------------------------------------\n       4.  Convert rank to an estimated weight.\n           For an exponential distribution Exp(\u03bb) the expected k-th\n           largest weight among N samples is\n\n             E[w_(k)] = (1/\u03bb) * ln( (N+1)/(k+1) )\n\n           We can freely drop the unknown constant 1/\u03bb \u2013 only *ratios*\n           matter for the greedy partitioning.\n       ------------------------------------------------------------------ */\n    vector<double> wEst(N);\n    const double NN = static_cast<double>(N) + 1.0;\n    for (int i = 0; i < N; ++i) {\n        int r = rankPos[i];                 // 0 .. N-1, 0 = heaviest\n        wEst[i] = log(NN / (r + 1.0));      // monotone, strictly positive\n    }\n\n    /* ------------------------------------------------------------------\n       5.  Greedy Largest-First assignment to D bags.\n       ------------------------------------------------------------------ */\n    struct Bag{\n        double sum = 0.0;\n        vector<int> items;\n    };\n    vector<Bag> bags(D);\n\n    // iterate items from heaviest to lightest\n    for (int idxItem : ord) {\n        // pick the currently lightest bag (min sum, then smaller index)\n        int best = 0;\n        for (int d = 1; d < D; ++d)\n            if (bags[d].sum < bags[best].sum - 1e-12)\n                best = d;\n        bags[best].items.push_back(idxItem);\n        bags[best].sum += wEst[idxItem];\n    }\n\n    /* ------------------------------------------------------------------\n       6.  Produce final answer: d_0 \u2026 d_{N-1}.\n       ------------------------------------------------------------------ */\n    vector<int> answer(N, 0);\n    for (int d = 0; d < D; ++d)\n        for (int v : bags[d].items)\n            answer[v] = d;\n\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << answer[i];\n    }\n    cout << '\\n' << flush;\n\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int INF = 1e9;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;          // safety\n    vector<vector<int>> st(m);               // bottom -> top\n    int h = n / m;\n    for (int i = 0; i < m; ++i) {\n        st[i].resize(h);\n        for (int j = 0; j < h; ++j) cin >> st[i][j];\n    }\n\n    vector<pair<int,int>> ops;               // (v, i)   i = 0 => carry out\n\n    for (int v = 1; v <= n; ++v) {\n        int s = -1, idx = -1;\n        // 1) locate v\n        for (int i = 0; i < m && s == -1; ++i) {\n            for (int j = 0; j < (int)st[i].size(); ++j) {\n                if (st[i][j] == v) { s = i; idx = j; break; }\n            }\n        }\n        if (s == -1) continue;               // should never happen\n\n        if (idx == (int)st[s].size() - 1) {  // already on the top\n            st[s].pop_back();\n            ops.emplace_back(v, 0);\n            continue;\n        }\n\n        // segment to move : idx+1 ... top\n        int w = st[s][idx + 1];              // first box of the segment\n        int dest = -1;\n        int bestTop = INF;\n\n        // 1) prefer empty stack\n        for (int i = 0; i < m; ++i)\n            if (i != s && st[i].empty()) { dest = i; break; }\n\n        // 2) stack whose top > w and minimal such top\n        if (dest == -1) {\n            for (int i = 0; i < m; ++i) if (i != s && !st[i].empty()) {\n                int tv = st[i].back();\n                if (tv > w && tv < bestTop) {\n                    bestTop = tv; dest = i;\n                }\n            }\n        }\n\n        // 3) otherwise stack with minimal height (ties -> smaller index)\n        if (dest == -1) {\n            int bestH = INF;\n            for (int i = 0; i < m; ++i) if (i != s) {\n                int hnow = (int)st[i].size();\n                if (hnow < bestH) { bestH = hnow; dest = i; }\n            }\n        }\n\n        // perform the move\n        vector<int> seg(st[s].begin() + idx + 1, st[s].end());\n        st[s].resize(idx + 1);               // keep v and lower part\n        st[dest].insert(st[dest].end(), seg.begin(), seg.end());\n\n        ops.emplace_back(w, dest + 1);       // stacks are 1-based in output\n\n        // now v is on top of stack s\n        st[s].pop_back();\n        ops.emplace_back(v, 0);\n    }\n\n    // output\n    for (auto [v, i] : ops) cout << v << ' ' << i << '\\n';\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** board representation ****************************************************/\nstruct Board {\n    int N;\n    vector<string> h;          // N-1 strings, wall to down\n    vector<string> v;          // N   strings, wall to right\n    vector<int> d;             // flattened N*N susceptibility\n    inline bool inside(int x, int y) const { return 0<=x && x<N && 0<=y && y<N; }\n    inline bool canMove(int x,int y,int dir) const{\n        // 0:R 1:D 2:L 3:U\n        if(dir==0) return y+1<N   && v[x][y]=='0';\n        if(dir==1) return x+1<N   && h[x][y]=='0';\n        if(dir==2) return y-1>=0  && v[x][y-1]=='0';\n        return            x-1>=0  && h[x-1][y]=='0';\n    }\n} B;\n\n/*** global data for loop allocation *****************************************/\nconst int DIRX[4]={0,1,0,-1};\nconst int DIRY[4]={1,0,-1,0};\nconst char DIRC[4]={'R','D','L','U'};\n\nvector<int> loops;            // extra loops assigned to each cell\nstring answer;                // output path\nint   N, LIM = 100000;\n\n/*** greedy allocation of extra visits ***************************************/\nvoid allocateLoops()\n{\n    int ncell = N*N;\n    loops.assign(ncell,0);\n    vector<int> vCnt(ncell,1);                    // visits so far\n    long long length = 2LL*(ncell-1);            // base DFS Euler\n\n    using Node = pair<double,int>;               // (value, idx)\n    priority_queue<Node> pq;\n    for(int i=0;i<ncell;i++){\n        double val = (double)B.d[i] / (vCnt[i]*(vCnt[i]+1));\n        pq.emplace(val,i);\n    }\n\n    while(length+2 <= LIM){\n        auto [val,idx]=pq.top(); pq.pop();\n        // value may be stale\n        double cur = (double)B.d[idx] / (vCnt[idx]*(vCnt[idx]+1));\n        if(fabs(cur-val) > 1e-9){ pq.emplace(cur,idx); continue; }\n\n        loops[idx]++;  vCnt[idx]++;  length+=2;\n        double nxt = (double)B.d[idx] / (vCnt[idx]*(vCnt[idx]+1));\n        pq.emplace(nxt,idx);\n    }\n}\n\n/*** choose a neighbour solely for bouncing **********************************/\nint bounceDir(int x,int y){\n    for(int dir=0;dir<4;dir++) if(B.canMove(x,y,dir)) return dir;\n    return -1;            // should never happen (board is connected)\n}\n\n/*** DFS Euler tour with loops ***********************************************/\nvector<vector<int>> vis;\nvoid dfs(int x,int y)\n{\n    int id = x*N + y;\n\n    /* output reserved back-and-forth loops */\n    int dir = bounceDir(x,y);\n    char c1 = DIRC[dir], c2 = DIRC[(dir+2)%4];\n    for(int k=0;k<loops[id];k++){ answer.push_back(c1); answer.push_back(c2); }\n\n    vis[x][y]=1;\n    for(int dirIter=0;dirIter<4;dirIter++){\n        int nx=x+DIRX[dirIter], ny=y+DIRY[dirIter];\n        if(!B.inside(nx,ny) || vis[nx][ny]) continue;\n        if(!B.canMove(x,y,dirIter)) continue;\n        answer.push_back(DIRC[dirIter]);\n        dfs(nx,ny);\n        answer.push_back(DIRC[(dirIter+2)%4]);\n    }\n}\n\n/*** main ********************************************************************/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read input */\n    cin>>N; B.N=N;\n    B.h.resize(N-1); for(int i=0;i<N-1;i++) cin>>B.h[i];\n    B.v.resize(N);   for(int i=0;i<N;i++)   cin>>B.v[i];\n    B.d.resize(N*N);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>B.d[i*N+j];\n\n    allocateLoops();                     // decide how many extra visits\n    vis.assign(N,vector<int>(N,0));\n    dfs(0,0);                            // build the actual path\n    cout<<answer<<\"\\n\";                  // output\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos {\n    int r, c;\n};\nconstexpr int INF = 1e9;\n\nint manhattan(const Pos& a, const Pos& b) {\n    return abs(a.r - b.r) + abs(a.c - b.c);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 15;\n    int n, m;\n    if (!(cin >> n >> m)) return 0;           // n == 15, m == 200\n    int si, sj; cin >> si >> sj;\n\n    vector<string> board(n);\n    for (int i = 0; i < n; ++i) cin >> board[i];\n\n    vector<string> t(m);\n    for (int k = 0; k < m; ++k) cin >> t[k];\n\n    /* --- 1.  build the target string ------------------------------------ */\n    string S;\n    S.reserve(m * 5);\n    for (auto &w: t) S += w;                  // length 1000\n\n    /* --- 2.  collect positions for every letter -------------------------- */\n    array<vector<Pos>, 26> where;\n    for (int i = 0; i < n; ++i)\n        for (int j = 0; j < n; ++j)\n            where[board[i][j] - 'A'].push_back({i, j});\n\n    /* --- 3.  DP over the string ----------------------------------------- */\n    int L = (int)S.size();\n    vector<vector<int>>   dp(L);              // minimal costs\n    vector<vector<uint16_t>> prv(L);          // predecessor indices (<= 225)\n    vector<int>           bestIdx(L, -1);     // cheapest position in layer\n\n    /* layer 0 ------------------------------------------------------------- */\n    {\n        int ch = S[0] - 'A';\n        int sz = where[ch].size();\n        dp[0].assign(sz, INF);\n        prv[0].assign(sz, 0);\n        for (int k = 0; k < sz; ++k) {\n            dp[0][k] = manhattan({si, sj}, where[ch][k]) + 1;\n        }\n        bestIdx[0] = min_element(dp[0].begin(), dp[0].end()) - dp[0].begin();\n    }\n\n    /* subsequent layers --------------------------------------------------- */\n    for (int i = 1; i < L; ++i) {\n        int chCur = S[i]   - 'A';\n        int chPrev= S[i-1] - 'A';\n        int szC = where[chCur].size();\n        int szP = where[chPrev].size();\n\n        dp[i].assign(szC, INF);\n        prv[i].assign(szC, 0);\n\n        for (int k = 0; k < szC; ++k) {\n            const Pos &to = where[chCur][k];\n            int best = INF, bestp = 0;\n            for (int j = 0; j < szP; ++j) {\n                int cand = dp[i-1][j] + manhattan(where[chPrev][j], to) + 1;\n                if (cand < best) { best = cand; bestp = j; }\n            }\n            dp[i][k]  = best;\n            prv[i][k] = bestp;\n        }\n        bestIdx[i] = min_element(dp[i].begin(), dp[i].end()) - dp[i].begin();\n    }\n\n    /* --- 4.  back-track to obtain the positions -------------------------- */\n    vector<Pos> answer(L);\n    int idx = bestIdx.back();\n    for (int i = L-1; i >= 0; --i) {\n        int ch = S[i] - 'A';\n        answer[i] = where[ch][idx];\n        idx = (i ? prv[i][idx] : 0);\n    }\n\n    /* --- 5.  output ------------------------------------------------------ */\n    for (auto &p : answer) {\n        cout << p.r << ' ' << p.c << '\\n';\n    }\n    return 0;\n}","ahc030":"//  Simple baseline for AHC030\n//  Drill every square, collect the positive ones, output.\n//\n//  Compile with:  g++ -std=c++20 -O2 -pipe -static -s main.cpp\n//\n//  The program never exceeds 2*N*N queries and is guaranteed to be correct.\n//-----------------------------------------------------------------------------\n#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastIO {\n    FastIO() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }\n} fio;\n\nint main() {\n    int N, M;\n    double eps;\n    if (!(cin >> N >> M >> eps)) return 0;\n\n    vector<vector<pair<int,int>>> shape(M);\n    for (int k = 0; k < M; ++k) {\n        int d; cin >> d;\n        shape[k].resize(d);\n        for (int t = 0; t < d; ++t) cin >> shape[k][t].first >> shape[k][t].second;\n    }\n\n    vector<pair<int,int>> hasOil;\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cout << \"q 1 \" << i << ' ' << j << '\\n' << flush;\n            string s;                   // judge returns an integer, but reading into string is safer\n            cin >> s;\n            if (s != \"0\") hasOil.emplace_back(i, j);\n        }\n    }\n\n    cout << \"a \" << hasOil.size();\n    for (auto [i,j] : hasOil) cout << ' ' << i << ' ' << j;\n    cout << '\\n' << flush;\n\n    int verdict = 0;\n    cin >> verdict;                    // 1 = correct, 0 = wrong (should never be 0 here)\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int i0, j0, i1, j1;          // top, left, bottom, right  (row,col)\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int W = 1000;                  // fixed by the problem\n    int D, N;\n    int dummyW;\n    if (!(cin >> dummyW >> D >> N)) return 0;\n\n    vector<vector<long long>> A(D, vector<long long>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> A[d][k];\n\n    vector<Rect> ans(N);\n\n    for (int d = 0; d < D; ++d) {\n        /* ---------- make rectangles for one day ---------- */\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int x, int y){ return A[d][x] > A[d][y]; });   // big first\n\n        vector<int> remain = order;\n        int y = 0;                       // current top of the next row\n\n        while (!remain.empty()) {\n            long long firstArea = A[d][remain.front()];\n            int remHeight = W - y;\n            if (remHeight <= 0) {        // should never happen\n                cerr << \"Packing failed: ran out of vertical space.\\n\";\n                exit(0);\n            }\n            /* choose row height */\n            int h = (int)std::sqrt((double)firstArea);\n            h = std::clamp(h, 1, remHeight);\n            int minH = (int)((firstArea + W - 1) / W);          // ceil(a/1000)\n            h = max(h, minH);\n            if (h > remHeight) h = remHeight;                   // final guard\n\n            int x = 0;\n            vector<int> nextRemain;\n            for (int id : remain) {\n                long long a = A[d][id];\n                int w = (int)((a + h - 1) / h);                 // ceil\n                if (w > W) w = W;                               // very unlikely\n                if (x + w <= W) {\n                    ans[id] = { y, x, y + h, x + w };\n                    x += w;\n                } else {\n                    nextRemain.push_back(id);                   // to next row\n                }\n            }\n            y += h;\n            remain.swap(nextRemain);\n        }\n\n        /* ---------- output ---------- */\n        for (int k = 0; k < N; ++k) {\n            const auto &r = ans[k];\n            cout << r.i0 << ' ' << r.j0 << ' '\n                 << r.i1 << ' ' << r.j1 << '\\n';\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\nconstexpr int64 MOD = 998244353LL;\n\nstruct Op {\n    int m, p, q;               // stamp id, top left (p, q)\n    array<int, 9> cells_idx;   // linear indices of the affected 9 cells\n    array<int64, 9> add;       // numbers written on the stamp\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 9, M = 20, K = 81;\n    vector<int64> board(N * N);\n    vector<array<int64, 9>> stamps(M);   // each stamp flattened row-major\n\n    /* read input */\n    int dummyN, dummyM, dummyK;\n    cin >> dummyN >> dummyM >> dummyK;   // all fixed to 9,20,81\n    for (auto &x : board) cin >> x;\n    for (int m = 0; m < M; ++m) {\n        for (int r = 0; r < 3; ++r)\n            for (int c = 0; c < 3; ++c)\n                cin >> stamps[m][r * 3 + c];\n    }\n\n    /* pre-compute the 980 possible operations */\n    vector<Op> ops;\n    ops.reserve(M * 49);\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                Op o;\n                o.m = m; o.p = p; o.q = q;\n                for (int dr = 0; dr < 3; ++dr)\n                    for (int dc = 0; dc < 3; ++dc) {\n                        int pos = (p + dr) * N + (q + dc);\n                        int idx = dr * 3 + dc;\n                        o.cells_idx[idx] = pos;\n                        o.add[idx]       = stamps[m][idx];\n                    }\n                ops.push_back(move(o));\n            }\n\n    vector<tuple<int,int,int>> answer;  // operations we finally perform\n\n    /* greedy search \u2013 at most K presses */\n    for (int step = 0; step < K; ++step) {\n        int best_id = -1;\n        int64 best_gain = 0;\n\n        for (int id = 0; id < (int)ops.size(); ++id) {\n            const Op &o = ops[id];\n            int64 gain = 0;\n            for (int k = 0; k < 9; ++k) {\n                int idx = o.cells_idx[k];\n                int64 v  = board[idx];\n                int64 nv = v + o.add[k];\n                if (nv >= MOD) nv -= MOD;\n                gain += nv - v;\n            }\n            if (gain > best_gain) {\n                best_gain = gain;\n                best_id   = id;\n            }\n        }\n\n        if (best_gain <= 0) break;   // nothing improves the score any more\n\n        const Op &o = ops[best_id];\n        /* apply */\n        for (int k = 0; k < 9; ++k) {\n            int idx = o.cells_idx[k];\n            board[idx] += o.add[k];\n            if (board[idx] >= MOD) board[idx] -= MOD;\n        }\n        answer.emplace_back(o.m, o.p, o.q);\n    }\n\n    /* output */\n    cout << answer.size() << '\\n';\n    for (auto &[m, p, q] : answer) {\n        cout << m << ' ' << p << ' ' << q << '\\n';\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N;\n    cin >> N;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0, x; j < N; ++j) cin >> x;   // read A_{i,j} \u2013 not used\n    }\n\n    string part = \"PRRRRQLLLL\";\n    string last = \"PRRRRQ\";\n    string cmd = \"RL\" + part + part + part + part + last;  // length 48\n    for (int i = 0; i < 5; ++i) {\n        cout << cmd << '\\n';\n    }\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Coord = pair<int,int>;\nconstexpr int N = 20;          // fixed in every test\n\n/* -------------------------------------------------------------------------- */\n/*  Build two Hamiltonian snakes: row\u2013wise and column\u2013wise                    */\n/* -------------------------------------------------------------------------- */\nvector<Coord> build_row_snake() {\n    vector<Coord> path; path.reserve(N*N);\n    for (int r = 0; r < N; ++r) {\n        if (r & 1)\n            for (int c = N-1; c >= 0; --c) path.emplace_back(r,c);\n        else\n            for (int c = 0; c <  N; ++c) path.emplace_back(r,c);\n    }\n    return path;\n}\nvector<Coord> build_col_snake() {\n    vector<Coord> path; path.reserve(N*N);\n    for (int c = 0; c < N; ++c) {\n        if (c & 1)\n            for (int r = N-1; r >= 0; --r) path.emplace_back(r,c);\n        else\n            for (int r = 0; r <  N; ++r) path.emplace_back(r,c);\n    }\n    return path;\n}\n\n/* -------------------------------------------------------------------------- */\n/*  Move helper (Manhattan)                                                   */\n/* -------------------------------------------------------------------------- */\nvoid move_to(int &r,int &c,int tr,int tc,vector<string>& out){\n    while(r<tr){ out.emplace_back(\"D\"); ++r; }\n    while(r>tr){ out.emplace_back(\"U\"); --r; }\n    while(c<tc){ out.emplace_back(\"R\"); ++c; }\n    while(c>tc){ out.emplace_back(\"L\"); --c; }\n}\n\n/* -------------------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyN;                    // always 20\n    if(!(cin>>dummyN)) return 0;\n\n    vector<vector<int>> h(N, vector<int>(N));\n    for(int r=0;r<N;r++) for(int c=0;c<N;c++) cin>>h[r][c];\n\n    /* ---- prepare candidate paths ---------------------------------------- */\n    vector<vector<Coord>> cand = { build_row_snake(), build_col_snake() };\n\n    int bestPath = 0, bestStart = 0, bestDist = INT_MAX;\n    for(int id=0; id<(int)cand.size(); ++id){\n        const auto& path = cand[id];\n        int n = path.size();\n\n        /* prefix sums */\n        vector<long long> pref(n+1,0);\n        for(int i=0;i<n;i++){\n            const auto [r,c] = path[i];\n            pref[i+1] = pref[i] + h[r][c];\n        }\n        long long mn = pref[0]; int mnpos = 0;\n        for(int i=1;i<=n;i++) if(pref[i] < mn){ mn = pref[i]; mnpos = i; }\n        int s = mnpos % n;                       // rotation start\n\n        /* distance (0,0) -> start square, no load so cheap but still relevant */\n        auto [sr,sc] = path[s];\n        int dist = abs(sr) + abs(sc);\n        if(dist < bestDist){ bestDist = dist; bestPath = id; bestStart = s; }\n    }\n\n    const auto& path = cand[bestPath];\n    int n = path.size();\n    int s = bestStart;\n\n    vector<string> out; out.reserve(1000);\n\n    int r = 0, c = 0, load = 0;\n    /* go to the chosen start square with empty truck */\n    auto [sr,sc] = path[s];\n    move_to(r,c,sr,sc,out);\n\n    /* main tour */\n    for(int step=0; step<n; ++step){\n        int idx = (s + step) % n;\n        auto [cr,cc] = path[idx];\n\n        int val = h[cr][cc];\n        if(val > 0){\n            out.emplace_back(\"+\" + to_string(val));\n            load += val;\n        }else if(val < 0){\n            out.emplace_back(\"-\" + to_string(-val));\n            load -= -val;          // unload\n        }\n        h[cr][cc] = 0;\n\n        if(step != n-1){\n            auto [nr,nc] = path[(idx+1)%n];\n            move_to(r,c,nr,nc,out);   // adjacent, exactly 1 move\n        }\n    }\n    /* load must be 0 here by construction */\n    // cerr << \"final load = \" << load << \"\\n\";\n\n    /* ------------------------------------------------------------------ */\n    for(const string& s : out) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** fixed parameters ***/\nconstexpr int N  = 6;               // grid size\nconstexpr int M  = 15;              // #criteria\nconstexpr int T  = 10;              // #turns\nconstexpr int SEED_CNT = 2 * N * (N - 1);     // always 60\nconstexpr int PLANT_CNT = N * N;               // 36\n\nstruct Seed {\n    array<uint8_t, M> x;\n    int               sum = 0;\n};\n\n/*** geometry of the 6\u00d76 field ***/\narray<vector<int>, PLANT_CNT> neighbours;\nvector<pair<int,int>>          edges;          // each edge once\narray<int, PLANT_CNT>          degree;\n\nvoid build_geometry() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c) {\n            int idx = r * N + c;\n            auto add = [&](int rr,int cc){\n                if (0<=rr && rr<N && 0<=cc && cc<N)\n                    neighbours[idx].push_back(rr*N+cc);\n            };\n            if (c+1 < N){ add(r,c+1); edges.emplace_back(idx, r*N+c+1); }\n            if (r+1 < N){ add(r+1,c); edges.emplace_back(idx, (r+1)*N+c); }\n            add(r,c-1); add(r-1,c);          // for fast \u0394 evaluation\n        }\n    for (int i = 0; i < PLANT_CNT; ++i) degree[i] = (int)neighbours[i].size();\n}\n\n/*** global containers reused every turn ***/\narray<Seed, SEED_CNT> seed;           // current 60 seeds\nint   syn[SEED_CNT][SEED_CNT];        // synergy matrix (\u22641500, fits in int)\narray<int, PLANT_CNT>  cell2seed;     // current grid \u2192 seed id\narray<int, PLANT_CNT>  bestPlant;     // best arrangement found\nlong long              bestScore;\n\n/*** synergy between two seeds ***/\ninline int synergy(int a,int b){ return syn[a][b]; }\n\n/*** objective = \u03a3 synergy over (undirected) edges *********************/\ninline long long objective() {\n    long long s = 0;\n    for (auto [u,v]: edges) s += synergy(cell2seed[u], cell2seed[v]);\n    return s;\n}\n\n/*** fast \u0394 when swapping/replacing one cell ***************************/\nlong long delta_one_cell(int pos,int oldSeed,int newSeed){\n    long long d = 0;\n    for (int nb : neighbours[pos]) {\n        d -= synergy(oldSeed      , cell2seed[nb]);\n        d += synergy(newSeed      , cell2seed[nb]);\n    }\n    return d;\n}\n\n/*** a very small simulated annealing **********************************/\nvoid simulated_annealing(mt19937_64 &rng,\n                         vector<int> &pool) {\n    constexpr int ITER      = 30000;\n    constexpr double T0     = 1000.0;\n    constexpr double T1     = 5.0;\n    uniform_real_distribution<double> urd(0.0,1.0);\n    uniform_int_distribution<int>     cellDist(0, PLANT_CNT-1);\n\n    bestPlant = cell2seed;\n    bestScore = objective();\n    long long curScore = bestScore;\n\n    for (int it = 0; it < ITER; ++it) {\n        double temp = T0 + (T1 - T0) * it / ITER;\n\n        if (!pool.empty() && urd(rng) < 0.30) {            // replace with pool\n            int pos  = cellDist(rng);\n            int pidx = uniform_int_distribution<int>(0,(int)pool.size()-1)(rng);\n            int s_old = cell2seed[pos], s_new = pool[pidx];\n            long long d = delta_one_cell(pos, s_old, s_new);\n\n            if (d >= 0 || urd(rng) < exp(d / temp)) {\n                cell2seed[pos] = s_new;\n                pool[pidx]     = s_old;\n                curScore      += d;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestPlant = cell2seed;\n                }\n            }\n        } else {                                           // swap two cells\n            int a = cellDist(rng), b = cellDist(rng);\n            if (a == b) continue;\n            int sa = cell2seed[a], sb = cell2seed[b];\n\n            long long d  = delta_one_cell(a, sa, sb)\n                         + delta_one_cell(b, sb, sa);\n            if (d >= 0 || urd(rng) < exp(d / temp)) {\n                cell2seed[a] = sb;\n                cell2seed[b] = sa;\n                curScore    += d;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestPlant = cell2seed;\n                }\n            }\n        }\n    }\n    cell2seed = bestPlant;\n}\n\n/*** main **************************************************************/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    build_geometry();\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    /* --- read the very first 60 seeds --------------------------------*/\n    int dummyN, dummyM, dummyT;\n    cin >> dummyN >> dummyM >> dummyT;          // they are always 6 15 10\n    for (int i = 0; i < SEED_CNT; ++i){\n        int sum = 0;\n        for (int l = 0; l < M; ++l){\n            int v; cin >> v;\n            seed[i].x[l] = (uint8_t)v;\n            sum += v;\n        }\n        seed[i].sum = sum;\n    }\n\n    for (int turn = 0; turn < T; ++turn){\n        /* --- choose seeds to work with: 36 best by V -----------------*/\n        vector<int> idx(SEED_CNT); iota(idx.begin(), idx.end(), 0);\n        ranges::sort(idx, [&](int a,int b){ return seed[a].sum > seed[b].sum; });\n\n        vector<int> pool(idx.begin()+PLANT_CNT, idx.end());          // 24 seeds\n        /* --- precalculate synergy matrix -----------------------------*/\n        for (int i = 0; i < SEED_CNT; ++i){\n            syn[i][i] = seed[i].sum;          // not needed, but harmless\n            for (int j = i+1; j < SEED_CNT; ++j){\n                int s = 0;\n                for (int l = 0; l < M; ++l)\n                    s += max(seed[i].x[l], seed[j].x[l]);\n                syn[i][j] = syn[j][i] = s;\n            }\n        }\n\n        /* --- initial placement: best seeds on highest-degree cells ---*/\n        array<int, PLANT_CNT> cells;\n        iota(cells.begin(), cells.end(), 0);\n        ranges::sort(cells, [&](int a,int b){ return degree[a] > degree[b]; });\n\n        for (int k = 0; k < PLANT_CNT; ++k)\n            cell2seed[cells[k]] = idx[k];\n\n        /* --- improve by SA -------------------------------------------*/\n        simulated_annealing(rng, pool);\n\n        /* --- output --------------------------------------------------*/\n        for (int r = 0; r < N; ++r){\n            for (int c = 0; c < N; ++c){\n                if (c) cout << ' ';\n                cout << cell2seed[r*N+c];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        /* --- read the 60 children for the next turn ------------------*/\n        if (turn == T-1) break;               // still need to read, but no calc\n        for (int i = 0; i < SEED_CNT; ++i){\n            int sum = 0;\n            for (int l = 0; l < M; ++l){\n                int v; cin >> v;\n                seed[i].x[l] = (uint8_t)v;\n                sum += v;\n            }\n            seed[i].sum = sum;\n        }\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int x, y; };\n\nint manhattan(const Pos& a, const Pos& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, Vmax;\n    if (!(cin >> N >> M >> Vmax)) return 0;\n    vector<string> S(N), T(N);\n    for (int i = 0; i < N; ++i) cin >> S[i];\n    for (int i = 0; i < N; ++i) cin >> T[i];\n\n    /* ------------------------------------------------------------------ */\n    /* 1. arm design  (root 0, fingertip 1, length = 1)                   */\n    /* ------------------------------------------------------------------ */\n    cout << 2 << '\\n';\n    cout << 0 << ' ' << 1 << '\\n';   // p_1  L(0,1)\n    cout << 0 << ' ' << 0 << '\\n';   // root starts at (0,0)\n\n    /* ------------------------------------------------------------------ */\n    /* 2. create lists of sources and targets                             */\n    /* ------------------------------------------------------------------ */\n    vector<vector<int>> has(N, vector<int>(N));\n    vector<Pos> sources, targets;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            has[i][j] = (S[i][j] == '1');\n            bool src = S[i][j] == '1' && T[i][j] == '0';\n            bool tar = S[i][j] == '0' && T[i][j] == '1';\n            if (src) sources.push_back({i, j});\n            if (tar) targets.push_back({i, j});\n        }\n\n    /* direction 0:R 1:D 2:L 3:U --------------------------------------- */\n    const int dx[4] = {0, 1, 0,-1};\n    const int dy[4] = {1, 0,-1, 0};\n\n    auto in_field = [&](int x, int y) {\n        return (0 <= x && x < N && 0 <= y && y < N);\n    };\n\n    /* ------------------------------------------------------------------ */\n    /* 3. simulation & command emission                                   */\n    /* ------------------------------------------------------------------ */\n    vector<string> cmds;\n\n    int rx = 0, ry = 0;      // current root position\n    int dir = 0;             // 0:right,1:down,2:left,3:up\n    bool holding = false;    // fingertip load status\n\n    auto emit = [&](char move, char rot, char act) {\n        string s(4, '.');\n        s[0] = move;\n        s[1] = rot;\n        s[3] = act;\n        cmds.push_back(std::move(s));\n    };\n\n    auto rotate_to = [&](int target_dir) {\n        int diff = (target_dir - dir + 4) % 4;\n        if (diff == 0) return;\n        if (diff == 1) { emit('.', 'R', '.'); dir = (dir + 1) & 3; }\n        else if (diff == 2) {\n            emit('.', 'R', '.'); dir = (dir + 1) & 3;\n            emit('.', 'R', '.'); dir = (dir + 1) & 3;\n        } else {            // diff == 3  -> one left\n            emit('.', 'L', '.'); dir = (dir + 3) & 3;\n        }\n    };\n\n    auto move_root = [&](int tx, int ty) {\n        while (rx != tx) {\n            if (rx < tx) { ++rx; emit('D', '.', '.'); }\n            else          { --rx; emit('U', '.', '.'); }\n        }\n        while (ry != ty) {\n            if (ry < ty) { ++ry; emit('R', '.', '.'); }\n            else          { --ry; emit('L', '.', '.'); }\n        }\n    };\n\n    while (!sources.empty()) {\n        /* ---- get next source ---------------------------------------- */\n        Pos src = sources.back();\n        sources.pop_back();\n\n        /* pick the closest target to this source ---------------------- */\n        int bestIdx = 0, bestDist = 1e9;\n        for (int i = 0; i < (int)targets.size(); ++i) {\n            int d = manhattan(src, targets[i]);\n            if (d < bestDist) { bestDist = d; bestIdx = i; }\n        }\n        Pos tar = targets[bestIdx];\n        targets[bestIdx] = targets.back();\n        targets.pop_back();\n\n        /* ---- step 1 : move to source & pick ------------------------- */\n        int bestDir = -1, bestCost = 1e9;\n        int root_sx = 0, root_sy = 0;\n        for (int d = 0; d < 4; ++d) {\n            int tx = src.x - dx[d], ty = src.y - dy[d];\n            if (!in_field(tx, ty)) continue;\n            int cost = manhattan({rx, ry}, {tx, ty})\n                     + ((d - dir + 4) % 4 == 3 ? 1 : (d - dir + 4) % 4);\n            if (cost < bestCost) { bestCost = cost; bestDir = d; root_sx = tx; root_sy = ty; }\n        }\n        move_root(root_sx, root_sy);\n        rotate_to(bestDir);\n        /* pick */\n        emit('.', '.', 'P');\n        holding = true;\n        has[src.x][src.y] = 0;\n\n        /* ---- step 2 : move to target & place ------------------------ */\n        bestDir = -1; bestCost = 1e9;\n        int root_tx = 0, root_ty = 0;\n        for (int d = 0; d < 4; ++d) {\n            int tx = tar.x - dx[d], ty = tar.y - dy[d];\n            if (!in_field(tx, ty)) continue;\n            int cost = manhattan({rx, ry}, {tx, ty})\n                     + ((d - dir + 4) % 4 == 3 ? 1 : (d - dir + 4) % 4);\n            if (cost < bestCost) { bestCost = cost; bestDir = d; root_tx = tx; root_ty = ty; }\n        }\n        move_root(root_tx, root_ty);\n        rotate_to(bestDir);\n        /* place */\n        emit('.', '.', 'P');\n        holding = false;\n        has[tar.x][tar.y] = 1;\n    }\n\n    /* ------------------------------------------------------------------ */\n    /* 4. output all commands                                             */\n    /* ------------------------------------------------------------------ */\n    for (const string& s : cmds) cout << s << '\\n';\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n};\n\nstruct Rect {\n    int x1, y1, x2, y2;            // inclusive borders, x1<=x2 , y1<=y2\n};\n\nconstexpr int MAXC = 100000;\nconstexpr int CELL = 1000;         // 1 000 \u00d7 1 000 grid\nconstexpr int GRID = MAXC / CELL + 1; // 101\nconstexpr int N_SAMPLE = 4000;\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<Point> mac(N), sar(N);\n    for (int i = 0; i < N; ++i) cin >> mac[i].x >> mac[i].y;\n    for (int i = 0; i < N; ++i) cin >> sar[i].x >> sar[i].y;\n\n    /* 1. build difference grid ------------------------------------------------*/\n    static int diff[GRID][GRID];\n    for (auto &p: mac) {\n        diff[p.y / CELL][p.x / CELL] += 1;\n    }\n    for (auto &p: sar) {\n        diff[p.y / CELL][p.x / CELL] -= 1;\n    }\n\n    /* 2. 2-D maximum sub-array on the GRID \u00d7 GRID matrix ----------------------*/\n    int bestGridScore = INT_MIN;\n    Rect bestGridRect{0,0,0,0};\n\n    static int colSum[GRID];\n    for (int top = 0; top < GRID; ++top) {\n        fill(colSum, colSum + GRID, 0);\n        for (int bottom = top; bottom < GRID; ++bottom) {\n            for (int col = 0; col < GRID; ++col)\n                colSum[col] += diff[bottom][col];\n\n            int curSum = 0, curL = 0;\n            for (int col = 0; col < GRID; ++col) {\n                curSum += colSum[col];\n                if (curSum > bestGridScore) {\n                    bestGridScore = curSum;\n                    bestGridRect = {\n                        curL * CELL,\n                        top  * CELL,\n                        (col + 1) * CELL - 1,\n                        (bottom + 1) * CELL - 1\n                    };\n                }\n                if (curSum < 0) {\n                    curSum = 0;\n                    curL = col + 1;\n                }\n            }\n        }\n    }\n\n    /* helper: exact score of a rectangle -------------------------------------*/\n    auto scoreRect = [&](const Rect &r)->int{\n        int diffCnt = 0;\n        for (auto &p: mac)\n            if (r.x1 <= p.x && p.x <= r.x2 && r.y1 <= p.y && p.y <= r.y2)\n                ++diffCnt;\n        for (auto &p: sar)\n            if (r.x1 <= p.x && p.x <= r.x2 && r.y1 <= p.y && p.y <= r.y2)\n                --diffCnt;\n        return diffCnt;\n    };\n\n    /* 3. refine: shrink to bounding box of mackerels inside -------------------*/\n    auto refine = [&](Rect r) -> Rect {\n        int minx = MAXC, miny = MAXC, maxx = 0, maxy = 0;\n        bool any = false;\n        for (auto &p: mac)\n            if (r.x1 <= p.x && p.x <= r.x2 && r.y1 <= p.y && p.y <= r.y2) {\n                any = true;\n                minx = min(minx, p.x);\n                miny = min(miny, p.y);\n                maxx = max(maxx, p.x);\n                maxy = max(maxy, p.y);\n            }\n        if (!any) return r;              // no mackerel ! keep old rectangle\n        // keep rectangle non-degenerate\n        if (minx == maxx) maxx = min(maxx + 1, MAXC);\n        if (miny == maxy) maxy = min(maxy + 1, MAXC);\n        return {minx, miny, maxx, maxy};\n    };\n\n    Rect bestRect = refine(bestGridRect);\n    int bestScore = scoreRect(bestRect);\n\n    /* 4. additional random rectangles around mackerels ------------------------*/\n    static int widths[] = {1500, 3000, 6000, 9000, 12000};\n    static int heights[] = {1500, 3000, 6000, 9000, 12000};\n\n    mt19937 rng(20240107);                       // fixed seed for reproducibility\n    uniform_int_distribution<int> uniMac(0, N - 1);\n    uniform_int_distribution<int> uniW(0, (int)(sizeof(widths)/sizeof(widths[0])) - 1);\n\n    for (int sample = 0; sample < N_SAMPLE; ++sample) {\n        const Point &c = mac[uniMac(rng)];\n        int w = widths[uniW(rng)];\n        int h = heights[uniW(rng)];\n\n        int x1 = c.x - w / 2;\n        if (x1 < 0) x1 = 0;\n        if (x1 + w > MAXC) x1 = MAXC - w;\n        int y1 = c.y - h / 2;\n        if (y1 < 0) y1 = 0;\n        if (y1 + h > MAXC) y1 = MAXC - h;\n        Rect r {x1, y1, x1 + w - 1, y1 + h - 1};\n\n        int sc = scoreRect(r);\n        if (sc > bestScore) {\n            bestScore = sc;\n            bestRect  = r;\n        }\n    }\n\n    /* 5. guarantee positive width/height, else fall back to (0,0)-(1,1) ------*/\n    if (bestScore <= 0 || bestRect.x1 >= bestRect.x2 || bestRect.y1 >= bestRect.y2) {\n        bestRect = {0,0,1,1};\n    }\n\n    /* 6. output rectangle -----------------------------------------------------*/\n    cout << 4 << '\\n';\n    cout << bestRect.x1 << ' ' << bestRect.y1 << '\\n';\n    cout << bestRect.x2 << ' ' << bestRect.y1 << '\\n';\n    cout << bestRect.x2 << ' ' << bestRect.y2 << '\\n';\n    cout << bestRect.x1 << ' ' << bestRect.y2 << '\\n';\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\n\nstruct Rect {\n    int64 w, h;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n    vector<Rect> a(N);\n    for (int i = 0; i < N; ++i) cin >> a[i].w >> a[i].h;\n\n    /* ----------  (1)  enumerate candidate height limits  ---------- */\n    vector<int64> cand;\n    cand.reserve(2 * N);\n    for (auto &r: a) {\n        cand.push_back(r.w);\n        cand.push_back(r.h);\n    }\n    sort(cand.begin(), cand.end());\n    cand.erase(unique(cand.begin(), cand.end()), cand.end());\n\n    const int64 INF = (1LL << 62);\n    int64 bestScore = INF;\n    vector<char> bestRotate(N, 0);\n\n    auto try_limit = [&](int64 H, vector<char>& out) -> int64 {\n        int64 widthSum = 0, curH = 0;\n        out.assign(N, 0);\n        for (int i = 0; i < N; ++i) {\n            int64 w0 = a[i].w, h0 = a[i].h;\n            int64 w1 = a[i].h, h1 = a[i].w;   // rotated\n            bool ok0 = (h0 <= H);\n            bool ok1 = (h1 <= H);\n            if (!ok0 && !ok1) return INF;      // impossible\n            if (ok0 && (!ok1 || w0 <= w1)) {\n                out[i] = 0;\n                widthSum += w0;\n                curH = max(curH, h0);\n            } else {\n                out[i] = 1;\n                widthSum += w1;\n                curH = max(curH, h1);\n            }\n        }\n        return widthSum + curH;\n    };\n\n    vector<char> buf;\n    for (auto H: cand) {\n        int64 sc = try_limit(H, buf);\n        if (sc < bestScore) {\n            bestScore = sc;\n            bestRotate = buf;\n        }\n    }\n    /* If none of the candidate limits worked (shouldn\u2019t happen),            */\n    /* fall back to \u201cshorter side = height\u201d.                                 */\n    if (bestScore == INF) {\n        int64 widthSum = 0, curH = 0;\n        for (int i = 0; i < N; ++i) {\n            if (a[i].w < a[i].h) {           // keep as is\n                bestRotate[i] = 0;\n                widthSum += a[i].w;\n                curH = max(curH, a[i].h);\n            } else {\n                bestRotate[i] = 1;\n                widthSum += a[i].h;\n                curH = max(curH, a[i].w);\n            }\n        }\n        bestScore = widthSum + curH;\n    }\n\n    /* ----------  (2)  greedy local improvement (single-flip)  ---------- */\n    bool improved = true;\n    int64 widthSum = 0, curH = 0;\n    auto recompute = [&]() {\n        widthSum = 0;\n        curH = 0;\n        for (int i = 0; i < N; ++i) {\n            bool rot = bestRotate[i];\n            int64 w = rot ? a[i].h : a[i].w;\n            int64 h = rot ? a[i].w : a[i].h;\n            widthSum += w;\n            curH = max(curH, h);\n        }\n    };\n    recompute();\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < N; ++i) {\n            bool rot = bestRotate[i];\n            int64 w_now = rot ? a[i].h : a[i].w;\n            int64 h_now = rot ? a[i].w : a[i].h;\n            int64 w_new = rot ? a[i].w : a[i].h;\n            int64 h_new = rot ? a[i].h : a[i].w;\n\n            int64 newWidth = widthSum - w_now + w_new;\n            int64 newH;\n            if (h_now == curH) {\n                /* need to know the 2nd largest height */\n                int64 secondMax = 0;\n                for (int j = 0; j < N; ++j) if (j != i) {\n                    int64 h = bestRotate[j] ? a[j].w : a[j].h;\n                    secondMax = max(secondMax, h);\n                }\n                newH = max(secondMax, h_new);\n            } else {\n                newH = max(curH, h_new);\n            }\n            if (newWidth + newH < widthSum + curH) {\n                bestRotate[i] ^= 1;\n                widthSum = newWidth;\n                curH = newH;\n                improved = true;\n            }\n        }\n    }\n\n    /* ----------  (3)  pre-built placement instructions  ---------- */\n    vector<array<string,4>> output(N);\n    for (int i = 0; i < N; ++i) {\n        output[i][0] = to_string(i);\n        output[i][1] = bestRotate[i] ? \"1\" : \"0\";\n        output[i][2] = \"U\";\n        output[i][3] = (i == 0 ? \"-1\" : to_string(i-1));\n    }\n\n    /* ----------  (4)  interact for T turns  ---------- */\n    for (int t = 0; t < T; ++t) {\n        cout << N << '\\n';\n        for (int i = 0; i < N; ++i) {\n            cout << output[i][0] << ' '\n                 << output[i][1] << ' '\n                 << output[i][2] << ' '\n                 << output[i][3] << '\\n';\n        }\n        cout << flush;\n        int64 WP, HP;\n        if (!(cin >> WP >> HP)) return 0;   // judge finished (shouldn\u2019t happen)\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;\n    vector<int> A(N);\n    for (int &x: A) cin >> x;\n    \n    vector<vector<int>> g(N);\n    for (int i = 0, u, v; i < M; ++i) {\n        cin >> u >> v;\n        g[u].push_back(v);\n        g[v].push_back(u);\n    }\n    /* coordinates are irrelevant for the algorithm */\n    for (int i = 0, xv, yv; i < N; ++i) cin >> xv >> yv;\n\n    /* vertices ordered by increasing beauty */\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(),\n         [&](int a, int b){ return A[a] < A[b]; });\n\n    const int UNASSIGNED = -2;\n    vector<int> root(N, UNASSIGNED);   // which root owns the vertex\n    vector<int> parent(N, UNASSIGNED); // answer to output\n    vector<int> depth(N, -1);\n\n    vector<int> dist(N, -1);\n    queue<int> q;\n\n    for (int v : ord) {\n        if (root[v] != UNASSIGNED) continue;          // already covered\n\n        /* new root */\n        root[v]   = v;\n        parent[v] = -1;\n        depth[v]  = 0;\n\n        fill(dist.begin(), dist.end(), -1);\n        dist[v] = 0;\n        while (!q.empty()) q.pop();\n        q.push(v);\n\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            if (dist[u] == H) continue;               // depth limit reached\n            for (int nb : g[u]) {\n                if (root[nb] != UNASSIGNED) continue; // belongs to another tree\n                if (dist[nb] != -1) continue;         // already visited in this BFS\n                int d = dist[u] + 1;\n                if (d > H) continue;\n\n                root[nb]   = v;\n                parent[nb] = u;\n                depth[nb]  = d;\n                dist[nb]   = d;\n                q.push(nb);\n            }\n        }\n    }\n\n    /* output */\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << parent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Op {\n    char dir;   // 'U','D','L','R'\n    int  idx;   // row or column index\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 is always 20 in the contest\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    // convenient lambda: is there no Fukunokami ('o') from (r,c) to the edge?\n    auto clear = [&](int r,int c,int dr,int dc)->bool{\n        r += dr; c += dc;\n        while (0 <= r && r < N && 0 <= c && c < N) {\n            if (board[r][c] == 'o') return false;\n            r += dr; c += dc;\n        }\n        return true;\n    };\n\n    struct Task { int r,c,dist; char dir; };\n    vector<Task> tasks;\n\n    // decide best direction for every Oni\n    for (int r = 0; r < N; ++r) for (int c = 0; c < N; ++c) if (board[r][c] == 'x') {\n        int bestD = 1e9;  char bestDir = '?';\n\n        auto upd=[&](bool ok,int dist,char dir){\n            if (ok && dist < bestD){ bestD = dist; bestDir = dir; }\n        };\n        upd(clear(r,c,-1, 0), r+1   , 'U');      // up\n        upd(clear(r,c, 1, 0), N-r   , 'D');      // down\n        upd(clear(r,c, 0,-1), c+1   , 'L');      // left\n        upd(clear(r,c, 0, 1), N-c   , 'R');      // right\n\n        tasks.push_back({r,c,bestD,bestDir});\n    }\n\n    vector<Op> ops;\n    const int LIMIT = 4*20*20;          // 1600\n\n    for (auto &t : tasks) {\n        int d   = t.dist;\n        char dir= t.dir;\n        char rev;\n        switch(dir){\n            case 'U': rev='D'; break;\n            case 'D': rev='U'; break;\n            case 'L': rev='R'; break;\n            default : rev='L'; break;   // dir == 'R'\n        }\n        int idx = (dir=='U'||dir=='D') ? t.c : t.r;\n\n        if (ops.size() + 2*d > LIMIT) break;     // safety, should never trigger\n        for (int k = 0; k < d; ++k) ops.push_back({dir, idx});\n        for (int k = 0; k < d; ++k) ops.push_back({rev, idx});\n\n        board[t.r][t.c] = '.';                   // Oni gone\n    }\n\n    // output\n    for (auto &o : ops) cout << o.dir << ' ' << o.idx << '\\n';\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ---------- */\n    int N, L;\n    if (!(cin >> N >> L)) return 0;          // safety\n    const int M = 2 * N;                     // #edges = 200\n    vector<int> T(N);\n    for (int &x : T) cin >> x;\n\n    /* ---------- target in-degrees ---------- */\n    const int STEP = L / M;                  // 2500\n    vector<int> indeg(N), rem(N);\n    ll sum_floor = 0;\n    for (int i = 0; i < N; ++i) {\n        indeg[i] = T[i] / STEP;              // floor(T/2500)\n        if (indeg[i] > 4) indeg[i] = 4;      // theoretical upper bound\n        sum_floor += indeg[i];\n        rem[i] = T[i] - indeg[i] * STEP;\n    }\n    int need = M - (int)sum_floor;           // edges still to distribute\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(),\n         [&](int a, int b){ return rem[a] > rem[b]; });\n    for (int k = 0; k < need; ++k) ++indeg[ord[k]];\n\n    /* make sure every T_i>0 gets at least one incoming edge */\n    for (int i = 0; i < N; ++i)\n        if (T[i] > 0 && indeg[i] == 0) {\n            for (int j = 0; j < N; ++j)\n                if (indeg[j] > 1) { --indeg[j]; ++indeg[i]; break; }\n        }\n\n    /* multiset of destinations: k_i copies of i */\n    vector<int> baseDest;\n    baseDest.reserve(M);\n    for (int v = 0; v < N; ++v)\n        for (int k = 0; k < indeg[v]; ++k)\n            baseDest.push_back(v);\n\n    /* ---------- search loop ---------- */\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> bestA(N), bestB(N);\n    ll bestErr = (1LL << 60);\n\n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < 1.85) {\n        ++iter;\n        vector<int> dest = baseDest;\n        shuffle(dest.begin(), dest.end(), rng);\n\n        /* assign two edges to every source */\n        vector<int> edgeDest(M);\n        int pos = 0;\n        for (int s = 0; s < N; ++s) {\n            edgeDest[2*s]   = dest[pos++];\n            edgeDest[2*s+1] = dest[pos++];\n        }\n\n        /* try to eliminate self-loops by simple swapping          */\n        for (int idx1 = 0; idx1 < M; ++idx1) {\n            int src1 = idx1 / 2;\n            if (edgeDest[idx1] == src1) {\n                for (int idx2 = 0; idx2 < M; ++idx2) if (idx1 != idx2) {\n                    int src2 = idx2 / 2;\n                    if (src2 != src1 &&\n                        edgeDest[idx2] != src1 &&\n                        edgeDest[idx2] != src2)\n                    {\n                        swap(edgeDest[idx1], edgeDest[idx2]);\n                        break;\n                    }\n                }\n            }\n        }\n\n        vector<int> a(N), b(N);\n        for (int s = 0; s < N; ++s) {\n            a[s] = edgeDest[2*s];\n            b[s] = edgeDest[2*s+1];\n        }\n\n        /* ---------- simulate rotor walk ---------- */\n        vector<int> cnt(N, 0), vis(N, 0);\n        int cur = 0;\n        for (int w = 0; w < L; ++w) {\n            int nxt = ( (cnt[cur] & 1) == 0 ? b[cur] : a[cur] );\n            ++cnt[cur];\n            ++vis[cur];\n            cur = nxt;\n        }\n\n        ll err = 0;\n        for (int i = 0; i < N; ++i) err += llabs( (ll)vis[i] - T[i] );\n        if (err < bestErr) {\n            bestErr = err;\n            bestA.swap(a);\n            bestB.swap(b);\n        }\n    }\n\n    /* ---------- output best found plan ---------- */\n    for (int i = 0; i < N; ++i)\n        cout << bestA[i] << ' ' << bestB[i] << '\\n';\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*------------------------------------------------------------*\n *  Hilbert curve order (integer coordinates 0 .. 16383)      *\n *------------------------------------------------------------*/\nstatic inline uint64_t hilbertOrder(int x, int y)\n{\n    const int BITS = 14;              // 2^14 = 16384 > 10000\n    uint64_t d = 0;\n    for (int s = BITS - 1; s >= 0; --s) {\n        int rx = (x >> s) & 1;\n        int ry = (y >> s) & 1;\n        uint64_t idx = (rx ^ ry) | (ry << 1);          // 0,1,2,3\n        d = (d << 2) | idx;\n        /* rotate */\n        if (!ry) {\n            if (rx) {\n                x = ((1 << BITS) - 1) - x;\n                y = ((1 << BITS) - 1) - y;\n            }\n            swap(x, y);\n        }\n    }\n    return d;\n}\n\n/*------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ---------- */\n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n\n    vector<int> G(M);\n    for (int &g : G) cin >> g;\n\n    struct City {\n        int id;\n        int lx, rx, ly, ry;\n        int cx, cy;          // centre\n        uint64_t hil;\n    };\n    vector<City> city(N);\n\n    for (int i = 0; i < N; ++i) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        int cx = (lx + rx) / 2;\n        int cy = (ly + ry) / 2;\n        int sx = (cx * 16383) / 10000;      // scale to 0..16383\n        int sy = (cy * 16383) / 10000;\n        city[i] = { i, lx, rx, ly, ry, cx, cy, hilbertOrder(sx, sy) };\n    }\n\n    /* ---------- sort by Hilbert order ---------- */\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int a, int b) { return city[a].hil < city[b].hil; });\n\n    /* ---------- build groups ---------- */\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; ++i) {\n        groups[i].reserve(G[i]);\n        for (int k = 0; k < G[i]; ++k) groups[i].push_back(order[idx++]);\n    }\n\n    /* ---------- build edges ---------- */\n    vector<vector<pair<int,int>>> edges(M);\n    int queries_used = 0;\n\n    for (int i = 0; i < M; ++i) {\n        int sz = groups[i].size();\n        if (sz <= 1) continue;\n\n        if (sz == 2) {\n            edges[i].push_back({groups[i][0], groups[i][1]});\n            continue;\n        }\n\n        if (3 <= sz && sz <= L && queries_used < Q) {\n            /* perform one query with the whole group */\n            cout << \"? \" << sz;\n            for (int v : groups[i]) cout << ' ' << v;\n            cout << '\\n' << flush;\n\n            for (int k = 0; k < sz - 1; ++k) {\n                int a, b; cin >> a >> b;\n                edges[i].push_back({a, b});\n            }\n            ++queries_used;\n        } else {    // fallback: chain in Hilbert order\n            for (int k = 1; k < sz; ++k)\n                edges[i].push_back({groups[i][k-1], groups[i][k]});\n        }\n    }\n\n    /* ---------- output answer ---------- */\n    cout << \"!\\n\";\n    for (int i = 0; i < M; ++i) {\n        /* cities */\n        for (int k = 0; k < (int)groups[i].size(); ++k) {\n            if (k) cout << ' ';\n            cout << groups[i][k];\n        }\n        cout << '\\n';\n        /* roads */\n        for (auto [a,b] : edges[i]) cout << a << ' ' << b << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Step {\n    char act; // 'M' or 'S'\n    char dir; // 'U','D','L','R'\n};\nconst int N = 20;\nconst int SZ = N * N;\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char DIRC[4] = {'U', 'D', 'L', 'R'};\n\ninline int id(int r, int c) { return r * N + c; }\ninline pair<int,int> rc(int v){ return {v / N, v % N}; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    vector<int> px, py;\n    {\n        int n_in;\n        if(!(cin >> n_in >> M)) return 0; // N is always 20\n        px.resize(M);\n        py.resize(M);\n        for (int k = 0; k < M; ++k) cin >> px[k] >> py[k];\n    }\n\n    vector<Step> answer;\n    vector<int> dist(SZ);\n    vector<int> prevv(SZ);\n    vector<char> preva(SZ);\n    vector<char> prevd(SZ);\n    deque<int> q;\n\n    int cur = id(px[0], py[0]);\n    for (int tgtIdx = 1; tgtIdx < M; ++tgtIdx) {\n        int goal = id(px[tgtIdx], py[tgtIdx]);\n\n        // BFS\n        fill(dist.begin(), dist.end(), -1);\n        q.clear();\n        dist[cur] = 0;\n        q.push_back(cur);\n\n        while (!q.empty()) {\n            int v = q.front(); q.pop_front();\n            if (v == goal) break;\n            auto [r, c] = rc(v);\n            for (int d = 0; d < 4; ++d) {\n                // Move\n                int nr = r + dx[d], nc = c + dy[d];\n                if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                    int nv = id(nr, nc);\n                    if (dist[nv] == -1) {\n                        dist[nv] = dist[v] + 1;\n                        prevv[nv] = v;\n                        preva[nv] = 'M';\n                        prevd[nv] = DIRC[d];\n                        q.push_back(nv);\n                    }\n                }\n                // Slide\n                int sr = r, sc = c;\n                while (true) {\n                    int tr = sr + dx[d], tc = sc + dy[d];\n                    if (tr < 0 || tr >= N || tc < 0 || tc >= N) break;\n                    sr = tr; sc = tc;\n                }\n                int sv = id(sr, sc);\n                if (sv != v && dist[sv] == -1) {\n                    dist[sv] = dist[v] + 1;\n                    prevv[sv] = v;\n                    preva[sv] = 'S';\n                    prevd[sv] = DIRC[d];\n                    q.push_back(sv);\n                }\n            }\n        }\n\n        // Reconstruct path\n        vector<Step> chunk;\n        for (int v = goal; v != cur; v = prevv[v]) {\n            chunk.push_back({preva[v], prevd[v]});\n        }\n        reverse(chunk.begin(), chunk.end());\n        answer.insert(answer.end(), chunk.begin(), chunk.end());\n        cur = goal;\n    }\n\n    // Output\n    for (auto &st : answer) cout << st.act << ' ' << st.dir << '\\n';\n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\nstruct Rect { int a, b, c, d; };          // [a,c) \u00d7 [b,d)\n\n/* --------- helpers ------------------------------------------------------- */\ninline bool intersect(const Rect& A, const Rect& B) {\n    return max(A.a, B.a) < min(A.c, B.c) &&\n           max(A.b, B.b) < min(A.d, B.d);          // positive area?\n}\ninline double sat(long long need, long long have) {\n    double mi = (double)min(need, have);\n    double ma = (double)max(need, have);\n    double r  = mi / ma;\n    double t  = 1.0 - r;                // 1-ratio\n    return 1.0 - t * t;\n}\n/* ------------------------------------------------------------------------ */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* -------- read input ------------------------------------------------- */\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    constexpr int W = 10000;\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> rd01(0.0, 1.0);\n\n    /* -------- initial 1\u00d71 rectangles ------------------------------------ */\n    vector<Rect> rect(n);\n    vector<long long> area(n, 1);\n    vector<double> p(n);\n    double score = 0.0;\n    for (int i = 0; i < n; ++i) {\n        rect[i] = {x[i], y[i], x[i] + 1, y[i] + 1};\n        p[i] = sat(r[i], 1);\n        score += p[i];\n    }\n    double bestScore = score;\n    auto bestRect   = rect;\n    auto bestArea   = area;\n    auto bestP      = p;\n\n    /* -------- simulated annealing --------------------------------------- */\n    const double TIME_LIMIT = 4.9;           // seconds\n    const double T0 = 5e-2, T1 = 1e-4;       // temperatures\n    const auto   T_start = chrono::steady_clock::now();\n\n    while (true) {\n        double elapsed = chrono::duration<double>(\n                             chrono::steady_clock::now() - T_start).count();\n        if (elapsed > TIME_LIMIT) break;\n        double temp = T0 + (T1 - T0) * (elapsed / TIME_LIMIT);\n\n        /* choose victim rectangle ---------------------------------------- */\n        int i = rng() % n;\n        long long diff = r[i] - area[i];\n        bool wantExpand = diff > 0;\n        bool expand = wantExpand;\n        if (rd01(rng) < 0.20) expand = !expand;      // 20 % opposite\n\n        int dir = rng() & 3;                         // 0 L,1 R,2 D,3 U\n        Rect old = rect[i], neu = old;\n        int deltaMax = 0;\n\n        auto width  = old.c - old.a;\n        auto height = old.d - old.b;\n\n        switch (dir) {\n            case 0: // left side\n                deltaMax = expand ? old.a\n                                   : min(width - 1, x[i] - old.a);\n                break;\n            case 1: // right side\n                deltaMax = expand ? (W - old.c)\n                                   : min(width - 1, old.c - (x[i] + 1));\n                break;\n            case 2: // bottom side\n                deltaMax = expand ? old.b\n                                   : min(height - 1, y[i] - old.b);\n                break;\n            default: // top side\n                deltaMax = expand ? (W - old.d)\n                                   : min(height - 1, old.d - (y[i] + 1));\n        }\n        if (deltaMax <= 0) continue;\n\n        /* choose \u0394 ------------------------------------------------------- */\n        int delta = 1;\n        if (expand) {\n            long long need = llabs(diff);\n            if (dir <= 1) {                    // changing width\n                long long per = height;\n                delta = (int)min<long long>(deltaMax,\n                        max<long long>(1, (need + per - 1) / per));\n            } else {                           // changing height\n                long long per = width;\n                delta = (int)min<long long>(deltaMax,\n                        max<long long>(1, (need + per - 1) / per));\n            }\n        } else {\n            delta = 1 + (rng() % deltaMax);\n        }\n\n        /* apply the move ------------------------------------------------- */\n        if (expand) {\n            if (dir == 0) neu.a -= delta;\n            if (dir == 1) neu.c += delta;\n            if (dir == 2) neu.b -= delta;\n            if (dir == 3) neu.d += delta;\n        } else {\n            if (dir == 0) neu.a += delta;\n            if (dir == 1) neu.c -= delta;\n            if (dir == 2) neu.b += delta;\n            if (dir == 3) neu.d -= delta;\n        }\n\n        /* overlap test --------------------------------------------------- */\n        bool ok = true;\n        for (int j = 0; j < n && ok; ++j)\n            if (j != i && intersect(neu, rect[j])) ok = false;\n        if (!ok) continue;\n\n        long long newArea = 1LL * (neu.c - neu.a) * (neu.d - neu.b);\n        double  new_p = sat(r[i], newArea);\n        double  dScore = new_p - p[i];\n\n        if (dScore >= 0.0 || rd01(rng) < exp(dScore / temp)) {\n            /* accept move ------------------------------------------------ */\n            rect[i]  = neu;\n            area[i]  = newArea;\n            p[i]     = new_p;\n            score   += dScore;\n            if (score > bestScore) {\n                bestScore = score;\n                bestRect  = rect;\n                bestArea  = area;\n                bestP     = p;\n            }\n        }\n    }\n\n    /* -------- output best rectangles ------------------------------------ */\n    for (int i = 0; i < n; ++i)\n        cout << bestRect[i].a << ' ' << bestRect[i].b << ' '\n             << bestRect[i].c << ' ' << bestRect[i].d << '\\n';\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** RNG : xoroshiro128+ (fast, good enough for heuristic) *******************/\nstruct Xoroshiro {\n    using ull = unsigned long long;\n    ull s[2];\n    Xoroshiro(ull seed=88172645463325252ULL) { // some default\n        s[0] = splitmix64(seed); s[1] = splitmix64(s[0]);\n    }\n    static ull splitmix64(ull &x){ ull z=(x+=0x9e3779b97f4a7c15ULL);\n        z=(z^(z>>30))*0xbf58476d1ce4e5b9ULL; z=(z^(z>>27))*0x94d049bb133111ebULL;\n        return z^(z>>31); }\n    ull next() { ull t = s[0] + s[1]; ull x = s[0]; ull y = s[1];\n        s[1] ^= x; s[0] = rotl(x,24) ^ y ^ (y<<16); s[1] = rotl(y,37); return t; }\n    int randint(int n){ return int(next() % n); }\n    double rnd01(){ return (next() >> 11) * (1.0/9007199254740992.0); } // /2^53\n    static ull rotl(ull x,int k){ return (x<<k)|(x>>(64-k)); }\n};\n\n/*** data ********************************************************************/\nconst int H = 50, W = 50;\nint si, sj;\nint tile[H][W];\nint valueCell[H][W];\nint M;                     // number of tiles\nvector<array<int,4>> neigh; // for each cell id, indices of neighbours (-1 if none)\nint cellId(int r,int c){ return r*W+c; }\n\nstruct Move { int dir; int deg; int val; int scoreEval; }; // helper for chooser\nint dr[4]={-1,1,0,0};\nint dc[4]={0,0,-1,1};\nchar dch[4]={'U','D','L','R'};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read input */\n    cin >> si >> sj;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cin >> tile[i][j];\n    M = 0;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) M = max(M, tile[i][j]+1);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cin >> valueCell[i][j];\n\n    /* pre\u2013compute neighbours that belong to a *different* tile */\n    neigh.resize(H*W);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        for(int d=0;d<4;d++){\n            int ni=i+dr[d], nj=j+dc[d];\n            if(ni<0||nj<0||ni>=H||nj>=W || tile[ni][nj]==tile[i][j])\n                neigh[cellId(i,j)][d]=-1;\n            else\n                neigh[cellId(i,j)][d]=cellId(ni,nj);\n        }\n    }\n\n    /* search the best walk within the time limit */\n    auto time_limit = chrono::steady_clock::now() + chrono::milliseconds(1950);\n    Xoroshiro rng(chrono::high_resolution_clock::now().time_since_epoch().count());\n\n    long long   bestScore = -1;\n    string      bestPath;\n\n    vector<char> pathBuf;     pathBuf.reserve(H*W);\n    vector<char> dirOrder = {0,1,2,3};\n\n    vector<char> visitedTile(M,0);\n\n    while(chrono::steady_clock::now() < time_limit){\n        /* parameters for this try */\n        int lambda = rng.randint(91)+10; // 10 \u2026 100\n        shuffle(dirOrder.begin(), dirOrder.end(), std::default_random_engine(rng.next()));\n\n        /* reset */\n        fill(visitedTile.begin(), visitedTile.end(), 0);\n        pathBuf.clear();\n\n        int r=si, c=sj;\n        visitedTile[tile[r][c]] = 1;\n        long long scoreHere = valueCell[r][c];\n\n        /* greedy walk */\n        for(;;){\n            int cid = cellId(r,c);\n            Move best{-1,-1,-1,INT_MIN};\n\n            for(int idx=0; idx<4; ++idx){\n                int d = dirOrder[idx];\n                int nid = neigh[cid][d];\n                if(nid==-1) continue;\n\n                int nr = nid / W, nc = nid % W;\n                int tId = tile[nr][nc];\n                if(visitedTile[tId]) continue;\n\n                /* degree after entering this neighbour */\n                int deg = 0;\n                for(int d2=0; d2<4; ++d2){\n                    int nnid = neigh[nid][d2];\n                    if(nnid==-1) continue;\n                    int tr = nnid / W, tc = nnid % W;\n                    int tt = tile[tr][tc];\n                    if(tt==tId || visitedTile[tt]) continue;\n                    ++deg;\n                }\n                int val = valueCell[nr][nc];\n                int eval = val + lambda*deg + rng.randint(3); // tiny noise\n\n                if(eval > best.scoreEval){\n                    best = {d,deg,val,eval};\n                }\n            }\n\n            if(best.dir==-1) break;          // dead end -> finish walk\n\n            /* do the chosen move */\n            int dir = best.dir;\n            r += dr[dir];\n            c += dc[dir];\n            visitedTile[tile[r][c]] = 1;\n            pathBuf.push_back(dch[dir]);\n            scoreHere += valueCell[r][c];\n        }\n\n        if(scoreHere > bestScore){\n            bestScore = scoreHere;\n            bestPath.assign(pathBuf.begin(), pathBuf.end());\n        }\n    }\n\n    /* output the best path found */\n    cout << bestPath << '\\n';\n    return 0;\n}","ahc003":"/****************************************************************************\n *  AHC003 \u2013 refined learner                                                *\n *  Changes w.r.t. the previous version                                     *\n *  \u2013 additive SGD based on true gradient                                   *\n *  \u2013 per-edge learning rate \u03b7 = \u03b70 / sqrt(cnt+1)                           *\n *  \u2013 slightly stronger but faster-vanishing exploration                    *\n ****************************************************************************/\n#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------------- constants ---------------- */\nconstexpr int H = 30, W = 30;\nconstexpr int HOR = H * (W - 1);\nconstexpr int VER = (H - 1) * W;\nconstexpr int E   = HOR + VER;\n\nconstexpr double INIT_W   = 5000.0;\nconstexpr double MIN_W    =  100.0;\nconstexpr double MAX_W    = 20000.0;\n\nconstexpr double ETA0      = 0.8;     // numerator of learning rate\nconstexpr double EX_NOISE  = 0.60;    // exploration: \u00b160 %\nconstexpr double EX_P0     = 0.45;    // exploration probability at k = 0\nconstexpr double EX_DECAY  = 0.996;   // p(k) = EX_P0 * EX_DECAY^k\n\n/* ---------------- data structures ---------------- */\nstruct Edge { int to, id; };\n\narray<array<array<Edge,4>, W>, H> adj;          // adjacency (id = \u20131 if absent)\narray<double, E>  w;                            // current estimate\narray<int   , E>  cnt;                          // times the edge has appeared\n\nint horId[H][W-1];\nint verId[H-1][W];\n\n/* ---------------- helpers ---------------- */\nvoid build_graph() {\n    int id = 0;\n    for (int i = 0; i < H; ++i)\n        for (int j = 0; j < W-1; ++j)\n            horId[i][j] = id++;\n    for (int i = 0; i < H-1; ++i)\n        for (int j = 0; j < W; ++j)\n            verId[i][j] = id++;\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                adj[i][j][d].id = -1;\n\n    for (int i = 0; i < H; ++i)\n        for (int j = 0; j < W; ++j) {\n            // up\n            if (i)          adj[i][j][0] = { (i-1)*W + j, verId[i-1][j] };\n            // down\n            if (i+1 < H)    adj[i][j][1] = { (i+1)*W + j, verId[i][j]   };\n            // left\n            if (j)          adj[i][j][2] = {  i   *W+j-1, horId[i][j-1] };\n            // right\n            if (j+1 < W)    adj[i][j][3] = {  i   *W+j+1, horId[i][j]   };\n        }\n}\n\n/* -------- random helpers -------- */\nmt19937 rng( (uint64_t)chrono::high_resolution_clock::now()\n             .time_since_epoch().count() );\nuniform_real_distribution<double> unif01(0.0,1.0);\ninline double rand_pm(double amp){ return (unif01(rng)*2.0-1.0)*amp; }\n\n/* -------- shortest path (Dijkstra) -------- */\nstruct Node {\n    double dist; int v;\n    bool operator<(const Node& o) const { return dist > o.dist; } // min-heap\n};\n\nvector<int> dijkstra(int si,int sj,int ti,int tj,bool explore){\n    array<double, H*W> dist; dist.fill(1e100);\n    array<int   , H*W> prvV, prvE; prvE.fill(-1);\n    dist[si*W+sj]=0;\n    priority_queue<Node> pq;\n    pq.push({0,si*W+sj});\n\n    while(!pq.empty()){\n        auto [d,v]=pq.top(); pq.pop();\n        if(d!=dist[v]) continue;\n        if(v==ti*W+tj) break;\n        int vi=v/W, vj=v%W;\n        for(int k=0;k<4;k++){\n            auto [to,eid]=adj[vi][vj][k];\n            if(eid<0) continue;\n            double ww = w[eid];\n            if(explore) ww *= 1.0 + rand_pm(EX_NOISE);\n            double nd = d + ww;\n            if(nd < dist[to]){\n                dist[to]=nd;\n                prvV[to]=v;\n                prvE[to]=eid;\n                pq.push({nd,to});\n            }\n        }\n    }\n    vector<int> edges;\n    int cur=ti*W+tj;\n    while(cur!=si*W+sj){\n        edges.push_back(prvE[cur]);\n        cur = prvV[cur];\n    }\n    reverse(edges.begin(),edges.end());\n    return edges;\n}\n\n/* -------- build UDLR string from edge list -------- */\nstring build_path(int si,int sj,const vector<int>& edges){\n    string res;\n    int i=si, j=sj;\n    for(int eid:edges){\n        if(eid < HOR){                 // horizontal\n            int row = eid/(W-1);\n            int col = eid%(W-1);\n            if(i==row && j==col){      // move right\n                res.push_back('R'); ++j;\n            }else{                     // move left\n                res.push_back('L'); --j;\n            }\n        }else{                         // vertical\n            int ee = eid-HOR;\n            int row = ee/W;\n            int col = ee%W;\n            if(i==row && j==col){      // move down\n                res.push_back('D'); ++i;\n            }else{                     // move up\n                res.push_back('U'); --i;\n            }\n        }\n    }\n    return res;\n}\n\n/* -------- learning (additive SGD) -------- */\nvoid learn(const vector<int>& edges, long long measured){\n    double pred = 0;\n    for(int e:edges) pred += w[e];\n\n    double diff = static_cast<double>(measured) - pred;\n    int    L    = (int)edges.size();\n    if(L==0) return;\n\n    for(int e:edges){\n        double eta = ETA0 / sqrt(cnt[e] + 1.0);\n        w[e] += eta * diff / L;\n        w[e] = min(MAX_W, max(MIN_W, w[e]));\n        ++cnt[e];\n    }\n}\n\n/* ========================================================== */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    build_graph();\n    w.fill(INIT_W);\n    cnt.fill(0);\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        bool explore = unif01(rng) < EX_P0 * pow(EX_DECAY, q);\n        auto edges   = dijkstra(si,sj,ti,tj, explore);\n        string path  = build_path(si,sj,edges);\n        cout << path << '\\n' << flush;\n\n        long long m; cin >> m;\n        learn(edges, m);\n    }\n    return 0;\n}","ahc004":"//  g++ -std=c++20 -O2 -pipe -static -s\n#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N  = 20;     // matrix size (fixed)\nconstexpr int CH = 8;      // A..H\nconstexpr int MAXLEN = 12; // max length of s_i\n\nstruct Placement {\n    uint8_t len;                  // length of the string\n    uint16_t cell[MAXLEN];        // linear cell id (0..399)\n    uint8_t  letter[MAXLEN];      // 0..7\n};\nstruct Watch {\n    int sid;          // string id\n    int pid;          // placement id within that string\n    uint8_t letter;   // letter required in this cell by that placement\n};\n\nint c2i(char c){ return c-'A'; }\nchar i2c(int x){ return 'A'+x; }\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;  /* N is fixed 20 */\n    cin >> std::ws;\n    cin.ignore(numeric_limits<streamsize>::max(),' '); // throw away N\n    cin >> M;\n    vector<string> S(M);\n    for(auto& s:S) cin >> s;\n\n    /*------------------------------------------------------------------*\n     * 1. enumerate every placement                                     *\n     *------------------------------------------------------------------*/\n    vector<vector<Placement>> plac(M);\n    vector<vector<char>> active(M);        // 1 = still alive\n    vector<vector<Watch>> watchers(N*N);   // placements touching each cell\n\n    for(int sid=0; sid<M; ++sid){\n        const string& s = S[sid];\n        const int L = (int)s.size();\n        plac[sid].reserve(800);\n        /* horizontal */\n        for(int row=0; row<N; ++row)\n            for(int st=0; st<N; ++st){\n                Placement p; p.len=L;\n                for(int k=0;k<L;++k){\n                    int col=(st+k)%N;\n                    int cell=row*N+col;\n                    p.cell[k]=cell;\n                    p.letter[k]=c2i(s[k]);\n                }\n                int pid=plac[sid].size();\n                plac[sid].push_back(p);\n                for(int k=0;k<L;++k)\n                    watchers[p.cell[k]].push_back({sid,pid,p.letter[k]});\n            }\n        /* vertical */\n        for(int col=0; col<N; ++col)\n            for(int st=0; st<N; ++st){\n                Placement p; p.len=L;\n                for(int k=0;k<L;++k){\n                    int row=(st+k)%N;\n                    int cell=row*N+col;\n                    p.cell[k]=cell;\n                    p.letter[k]=c2i(s[k]);\n                }\n                int pid=plac[sid].size();\n                plac[sid].push_back(p);\n                for(int k=0;k<L;++k)\n                    watchers[p.cell[k]].push_back({sid,pid,p.letter[k]});\n            }\n        active[sid].assign(plac[sid].size(),1);\n    }\n\n    /*------------------------------------------------------------------*\n     * 2. propagation of forced letters                                 *\n     *------------------------------------------------------------------*/\n    vector<int8_t> fixed(N*N,-1); // -1 = unknown, else 0..7\n    bool changed=true;\n    while(changed){\n        changed=false;\n        /* remove placements inconsistent with already fixed letters */\n        for(int sid=0; sid<M; ++sid){\n            auto &v = plac[sid];\n            auto &alive = active[sid];\n            for(int pid=0,sz=v.size(); pid<sz; ++pid){\n                if(!alive[pid]) continue;\n                const Placement& p=v[pid];\n                bool ok=true;\n                for(int k=0;k<p.len && ok;++k){\n                    int c = p.cell[k];\n                    if(fixed[c]!=-1 && fixed[c]!=p.letter[k]) ok=false;\n                }\n                if(!ok){ alive[pid]=0; changed=true; }\n            }\n        }\n        /* fix cells that now have only one possible letter */\n        for(int cell=0; cell<N*N; ++cell){\n            if(fixed[cell]!=-1) continue;\n            uint8_t mask=0;\n            for(const auto& w: watchers[cell])\n                if(active[w.sid][w.pid]) mask |= (1u<<w.letter);\n            if(mask && (mask & (mask-1))==0){           // power of two\n                fixed[cell]=__builtin_ctz(mask);\n                changed=true;\n            }\n        }\n    }\n\n    /*------------------------------------------------------------------*\n     * 3. greedy assignment (strings with fewer choices first)          *\n     *------------------------------------------------------------------*/\n    mt19937 rng(712367); // deterministic, change for randomisation\n    vector<int> aliveCnt(M);\n    for(int i=0;i<M;++i){\n        aliveCnt[i]=accumulate(begin(active[i]),end(active[i]),0);\n    }\n    vector<int> order(M); iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),\n         [&](int a,int b){ return aliveCnt[a]<aliveCnt[b]; });\n\n    for(int sid:order){\n        int bestPid=-1, bestNew=99;\n        for(int pid=0,sz=plac[sid].size(); pid<sz; ++pid){\n            if(!active[sid][pid]) continue;\n            const auto& p = plac[sid][pid];\n            bool ok=true; int newCnt=0;\n            for(int k=0;k<p.len && ok;++k){\n                int c = p.cell[k];\n                if(fixed[c]!=-1 && fixed[c]!=p.letter[k]) ok=false;\n                else if(fixed[c]==-1) ++newCnt;\n            }\n            if(!ok) continue;\n            if(newCnt<bestNew || (newCnt==bestNew && rng()%2)){\n                bestNew=newCnt; bestPid=pid;\n            }\n        }\n        if(bestPid==-1) continue;                 // cannot place this string\n        const auto& p=plac[sid][bestPid];\n        /* fix the cells decided by this placement */\n        for(int k=0;k<p.len;++k){\n            int c=p.cell[k];\n            if(fixed[c]==p.letter[k]) continue;\n            fixed[c]=p.letter[k];\n            /* eliminate incompatible placements touching this cell */\n            for(const auto& w: watchers[c]){\n                if(!active[w.sid][w.pid]) continue;\n                if(w.letter!=fixed[c]){\n                    active[w.sid][w.pid]=0;\n                    --aliveCnt[w.sid];\n                }\n            }\n        }\n    }\n\n    /*------------------------------------------------------------------*\n     * 4. fill remaining unknown cells arbitrarily                      *\n     *------------------------------------------------------------------*/\n    uniform_int_distribution<int> d8(0,7);\n    for(int c=0;c<N*N;++c)\n        if(fixed[c]==-1) fixed[c]=d8(rng);\n\n    /*------------------------------------------------------------------*\n     * 5. output                                                        *\n     *------------------------------------------------------------------*/\n    for(int r=0;r<N;++r){\n        for(int c=0;c<N;++c) cout << i2c(fixed[r*N+c]);\n        cout << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst int INF = 1e9;\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nstruct Edge{int to,id;};\nconst int di[4]={-1,1,0,0};\nconst int dj[4]={0,0,-1,1};\nconst char dch[4]={'U','D','L','R'};\ninline bool inside(int x,int n){return 0<=x&&x<n;}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 covering set \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nstruct CoverBuilder{\n    int N,NN;\n    vector<string> S;\n    vector<char> isRoad,cost;\n    vector<int> rowRunOf,colRunOf;\n    vector<vector<int>> rowRuns,colRuns;\n    vector<int> vPoints;                 // without the start cell\n\n    CoverBuilder(int N_,vector<string>&& s):N(N_),NN(N_*N_),S(s){\n        isRoad.assign(NN,0); cost.assign(NN,0);\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            if(S[i][j]!='#'){isRoad[id(i,j)]=1; cost[id(i,j)]=S[i][j]-'0';}\n        }\n        buildRuns();\n    }\n\n    int id(int i,int j)const{return i*N+j;}\n    int row(int idx)const{return idx/N;}\n    int col(int idx)const{return idx%N;}\n\n    void buildRuns(){\n        rowRunOf.assign(NN,-1); colRunOf.assign(NN,-1);\n\n        /* horizontal */\n        for(int i=0;i<N;i++){\n            int j=0;\n            while(j<N){\n                if(!isRoad[id(i,j)]){++j;continue;}\n                vector<int> cells;\n                while(j<N&&isRoad[id(i,j)]){cells.push_back(id(i,j));++j;}\n                int r=rowRuns.size();\n                for(int v:cells) rowRunOf[v]=r;\n                rowRuns.push_back(move(cells));\n            }\n        }\n        /* vertical */\n        for(int j=0;j<N;j++){\n            int i=0;\n            while(i<N){\n                if(!isRoad[id(i,j)]){++i;continue;}\n                vector<int> cells;\n                while(i<N&&isRoad[id(i,j)]){cells.push_back(id(i,j));++i;}\n                int c=colRuns.size();\n                for(int v:cells) colRunOf[v]=c;\n                colRuns.push_back(move(cells));\n            }\n        }\n    }\n\n    vector<int> build(int si,int sj){\n        int start=id(si,sj);\n        int H=rowRuns.size(), V=colRuns.size();\n        vector<char> hCov(H,0), vCov(V,0), selected(NN,0);\n\n        auto addPoint=[&](int cell){\n            if(cell!=start && !selected[cell]){\n                selected[cell]=1; vPoints.push_back(cell);\n            }\n        };\n\n        if(rowRunOf[start]>=0) hCov[rowRunOf[start]]=1;\n        if(colRunOf[start]>=0) vCov[colRunOf[start]]=1;\n\n        /* try to pair */\n        for(int r=0;r<H;r++) if(!hCov[r]){\n            for(int cell:rowRuns[r]){\n                int c=colRunOf[cell];\n                if(!vCov[c]){\n                    hCov[r]=vCov[c]=1;\n                    addPoint(cell); break;\n                }\n            }\n        }\n        /* remaining horizontals */\n        for(int r=0;r<H;r++) if(!hCov[r]){\n            hCov[r]=1; addPoint(rowRuns[r][0]);\n        }\n        /* remaining verticals */\n        for(int c=0;c<V;c++) if(!vCov[c]){\n            vCov[c]=1; addPoint(colRuns[c][0]);\n        }\n        return vPoints;           // for convenience\n    }\n};\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 all-pairs shortest paths \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nstruct APSP{\n    int N,NN;\n    const vector<char>& cost;\n    const vector<char>& isRoad;\n    const vector<int>& vtx;              // selected nodes (id on grid)\n\n    vector<vector<int>> dist;            // in node-space\n    vector<vector<string>> path;         // move strings\n\n    APSP(int N_,const vector<char>& c,const vector<char>& road,\n         const vector<int>& nodes)\n         :N(N_),NN(N_*N_),cost(c),isRoad(road),vtx(nodes)\n    {\n        int K=vtx.size();\n        dist.assign(K,vector<int>(K,INF));\n        path.assign(K,vector<string>(K));\n        build();\n    }\n    int id(int i,int j)const{return i*N+j;}\n    void build(){\n        /* adjacency on grid */\n        vector<array<int,4>> nb(NN);\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            int idx=id(i,j);\n            for(int k=0;k<4;k++){\n                int ni=i+di[k], nj=j+dj[k];\n                nb[idx][k]=(inside(ni,N)&&inside(nj,N)&&isRoad[id(ni,nj)])\n                            ? id(ni,nj):-1;\n            }\n        }\n        vector<int> d(NN),par(NN);\n        vector<char> pdir(NN);\n        using Pair=pair<int,int>;\n        priority_queue<Pair,vector<Pair>,greater<Pair>> pq;\n\n        int K=vtx.size();\n        for(int s=0;s<K;s++){\n            fill(d.begin(),d.end(),INF);\n            fill(par.begin(),par.end(),-1);\n            d[vtx[s]]=0; pq.emplace(0,vtx[s]);\n\n            while(!pq.empty()){\n                auto [dv,v]=pq.top(); pq.pop();\n                if(dv!=d[v]) continue;\n                for(int k=0;k<4;k++){\n                    int to=nb[v][k];\n                    if(to==-1) continue;\n                    int nd=dv+cost[to];\n                    if(nd<d[to]){\n                        d[to]=nd; par[to]=v; pdir[to]=dch[k];\n                        pq.emplace(nd,to);\n                    }\n                }\n            }\n            for(int t=0;t<K;t++){\n                int dst=vtx[t];\n                dist[s][t]=d[dst];\n                if(s==t){path[s][t]=\"\"; continue;}\n                string mv;\n                int cur=dst;\n                while(cur!=vtx[s]){\n                    mv.push_back(pdir[cur]);\n                    cur=par[cur];\n                }\n                reverse(mv.begin(),mv.end());\n                path[s][t]=move(mv);\n            }\n        }\n    }\n};\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Christofides TSP \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nvector<int> christofides(const vector<vector<int>>& dMat){\n    int K=dMat.size();\n    /* Prim MST */\n    vector<int> parent(K,-1), key(K,INF);\n    vector<char> inMST(K,0);\n    key[0]=0;\n    for(int it=0;it<K;it++){\n        int v=-1;\n        for(int i=0;i<K;i++) if(!inMST[i] && (v==-1||key[i]<key[v])) v=i;\n        inMST[v]=1;\n        for(int u=0;u<K;u++)\n            if(!inMST[u] && dMat[v][u]<key[u]){key[u]=dMat[v][u]; parent[u]=v;}\n    }\n    vector<vector<int>> adj(K);\n    vector<int> deg(K,0);\n    for(int i=1;i<K;i++){\n        adj[i].push_back(parent[i]);\n        adj[parent[i]].push_back(i);\n        deg[i]++; deg[parent[i]]++;\n    }\n    /* odd vertices */\n    vector<int> odd;\n    for(int i=0;i<K;i++) if(deg[i]&1) odd.push_back(i);\n    /* greedy minimum matching */\n    int m=odd.size();\n    vector<char> matched(K,0);\n    vector<tuple<int,int,int>> cand;\n    for(int i=0;i<m;i++) for(int j=i+1;j<m;j++){\n        int a=odd[i], b=odd[j];\n        cand.emplace_back(dMat[a][b],a,b);\n    }\n    sort(cand.begin(),cand.end());\n    for(auto [w,a,b]:cand){\n        if(!matched[a] && !matched[b]){\n            matched[a]=matched[b]=1;\n            adj[a].push_back(b); adj[b].push_back(a);\n        }\n    }\n\n    /* Euler tour (Hierholzer) */\n    vector<int> it(K,0), stk={0}, euler;\n    vector<vector<int>> *ad=&adj;        // to shorten typing\n    while(!stk.empty()){\n        int v=stk.back();\n        while(it[v]<(int)(*ad)[v].size() && (*ad)[v][it[v]]==-1) ++it[v];\n        if(it[v]==(int)(*ad)[v].size()){\n            euler.push_back(v); stk.pop_back();\n        }else{\n            int u=(*ad)[v][it[v]];\n            (*ad)[v][it[v]]=-1;                    // mark used\n            /* remove v from u's list later when reached */\n            for(int &x:(*ad)[u]) if(x==v){x=-1; break;}\n            stk.push_back(u);\n        }\n    }\n    /* shortcut repeated vertices */\n    vector<int> order;\n    vector<char> seen(K,0);\n    for(int v:euler){\n        if(!seen[v]){order.push_back(v); seen[v]=1;}\n    }\n    order.push_back(0);                 // return to start\n    return order;\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 2-opt \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nvoid two_opt(vector<int>& order,const vector<vector<int>>& dist){\n    int L=(int)order.size();\n    bool improved=true;\n    while(improved){\n        improved=false;\n        for(int i=1;i<L-3;i++){\n            for(int j=i+1;j<L-1;j++){\n                if(j==i+1) continue;\n                int a=order[i-1], b=order[i], c=order[j], d=order[(j+1)%L];\n                int delta = dist[a][b]+dist[c][d] - dist[a][c]-dist[b][d];\n                if(delta>0){\n                    reverse(order.begin()+i,order.begin()+j+1);\n                    improved=true;\n                }\n            }\n        }\n    }\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 main \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N,si,sj;\n    if(!(cin>>N>>si>>sj)) return 0;\n    vector<string> S(N);\n    for(int i=0;i<N;i++) cin>>S[i];\n\n    /* build covering set */\n    CoverBuilder cb(N,move(S));\n    cb.build(si,sj);\n    vector<int> nodes;\n    nodes.push_back(cb.id(si,sj));\n    nodes.insert(nodes.end(),cb.vPoints.begin(),cb.vPoints.end());\n    int K=nodes.size();\n\n    /* APSP */\n    APSP apsp(N,cb.cost,cb.isRoad,nodes);\n\n    /* route via Christofides + 2-opt */\n    vector<int> order = christofides(apsp.dist);\n    two_opt(order,apsp.dist);\n\n    /* build final move string */\n    string answer;\n    long long total = 0;\n    for(size_t i=0;i+1<order.size();i++){\n        int a=order[i], b=order[i+1];\n        answer += apsp.path[a][b];\n        total  += apsp.dist[a][b];\n    }\n    cout<<answer<<\"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Worker {\n    vector<int> skill;   // proven lower bound\n    int task = -1;       // current task id (0-based) or -1\n    int startDay = -1;   // day the current task was started\n    double gap = 0.0;    // unknown part of w\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    /* ---------- read tasks ---------- */\n    vector<vector<int>> demand(N, vector<int>(K));\n    for (int i = 0; i < N; ++i)\n        for (int k = 0; k < K; ++k) cin >> demand[i][k];\n\n    vector<vector<int>> out(N);\n    vector<int> indeg(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v; cin >> u >> v;\n        --u; --v;\n        out[u].push_back(v);\n        ++indeg[v];\n    }\n\n    vector<int> prio(N);\n    for (int i = 0; i < N; ++i) prio[i] = (int)out[i].size();\n\n    /* ---------- initial ready list ---------- */\n    vector<int> status(N, 0);          // 0 not started, 1 running, 2 done\n    vector<int> ready;\n    vector<char> inReady(N, 0);\n    for (int i = 0; i < N; ++i)\n        if (indeg[i] == 0) {\n            ready.push_back(i);\n            inReady[i] = 1;\n        }\n\n    /* ---------- workers ---------- */\n    vector<Worker> W(M, Worker{vector<int>(K, 0), -1, -1, 0.0});\n\n    int day = 1;\n    while (true) {\n        /* ===== choose assignments for idle workers ===== */\n        vector<pair<int,int>> today;           // (worker, task), 0-based\n\n        for (int j = 0; j < M; ++j) {\n            if (W[j].task != -1) continue;     // busy\n\n            int bestTask = -1;\n            int bestPredT = INT_MAX;\n            int bestPr = -1;\n\n            for (int id : ready) {\n                if (status[id] != 0) continue;     // already taken\n                // predict w\n                int def = 0;\n                for (int k = 0; k < K; ++k) {\n                    int diff = demand[id][k] - W[j].skill[k];\n                    if (diff > 0) def += diff;\n                }\n                int wPred = def + (int)std::round(W[j].gap);\n                if (wPred == 0) wPred = 1;\n\n                if (wPred < bestPredT ||\n                   (wPred == bestPredT && prio[id] > bestPr) ||\n                   (wPred == bestPredT && prio[id] == bestPr && id < bestTask))\n                {\n                    bestTask = id;\n                    bestPredT = wPred;\n                    bestPr    = prio[id];\n                }\n            }\n\n            if (bestTask != -1) {\n                today.emplace_back(j, bestTask);\n                status[bestTask] = 1;\n                W[j].task = bestTask;\n                W[j].startDay = day;\n            }\n        }\n\n        /* ---------- output ---------- */\n        cout << (int)today.size();\n        for (auto [j, t] : today) cout << ' ' << j+1 << ' ' << t+1;\n        cout << '\\n' << flush;\n\n        /* ---------- read finished list ---------- */\n        int nFinish;\n        if (!(cin >> nFinish)) return 0;\n        if (nFinish == -1) break;\n\n        for (int i = 0; i < nFinish; ++i) {\n            int f; cin >> f; --f;\n            Worker &wk = W[f];\n            int taskId = wk.task;\n            if (taskId < 0) continue;      // safety\n\n            int realT = day - wk.startDay + 1;\n            int wObs  = (realT == 1 ? 0 : realT);\n\n            /* ----- update skill lower bound ----- */\n            if (wObs == 0) {               // we are sure every dim is covered\n                for (int k = 0; k < K; ++k)\n                    wk.skill[k] = max(wk.skill[k], demand[taskId][k]);\n                wk.gap *= 0.9;\n            } else {\n                int defPred = 0;\n                for (int k = 0; k < K; ++k) {\n                    int diff = demand[taskId][k] - wk.skill[k];\n                    if (diff > 0) defPred += diff;\n                }\n                if (defPred > wObs) {      // we over-estimated: raise skills\n                    int need = defPred - wObs;\n                    for (int k = 0; k < K && need > 0; ++k) {\n                        int lack = demand[taskId][k] - wk.skill[k];\n                        if (lack <= 0) continue;\n                        int inc = min(lack, need);\n                        wk.skill[k] += inc;\n                        need -= inc;\n                    }\n                    wk.gap *= 0.9;\n                } else {                   // we underestimated: enlarge gap\n                    double delta = wObs - defPred;\n                    wk.gap = 0.7 * wk.gap + 0.3 * delta;\n                }\n            }\n\n            /* ----- mark task finished ----- */\n            status[taskId] = 2;\n            wk.task = -1;\n\n            for (int v : out[taskId]) {\n                if (--indeg[v] == 0 && status[v] == 0 && !inReady[v]) {\n                    ready.push_back(v);\n                    inReady[v] = 1;\n                }\n            }\n        }\n\n        ++day;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing ll = long long;\nstruct Order {\n    int id;                 // 0-based id\n    int ax, ay;             // restaurant\n    int cx, cy;             // destination\n    int inner;              // |a-c|+|b-d|\n};\ninline int md(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\n\n/* ---------------------------------------------------------------------- */\nll route_cost(const vector<Order>& ord, const vector<int>& seq) {\n    int x = 400, y = 400;\n    ll tot = 0;\n    for(int id:seq){\n        const Order& o = ord[id];\n        tot += md(x,y,o.ax,o.ay);\n        tot += o.inner;\n        x = o.cx; y = o.cy;\n    }\n    tot += md(x,y,400,400);\n    return tot;\n}\n/* ---------------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int N = 1000, NEED = 50;\n    vector<Order> ord(N);\n    for(int i=0;i<N;++i){\n        int a,b,c,d;  cin>>a>>b>>c>>d;\n        ord[i]={i,a,b,c,d,md(a,b,c,d)};\n    }\n\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    vector<int> best_seq;\n    ll best_cost = (1LL<<60);\n\n    const auto t0 = chrono::high_resolution_clock::now();\n    int rounds = 0;\n    while(true){\n        /* ---- 0. time management --------------------------------------- */\n        auto now = chrono::high_resolution_clock::now();\n        if(chrono::duration<double>(now-t0).count() > 1.9) break;\n        ++rounds;\n\n        /* ---- 1. construction ------------------------------------------ */\n        vector<int> seq;          seq.reserve(NEED);\n        vector<char> used(N,0);\n\n        /* random first order: pick one of the 300 smallest inner distance */\n        static vector<int> rank_by_inner;\n        if(rank_by_inner.empty()){\n            rank_by_inner.resize(N);\n            iota(rank_by_inner.begin(), rank_by_inner.end(), 0);\n            sort(rank_by_inner.begin(), rank_by_inner.end(),\n                 [&](int i,int j){ return ord[i].inner < ord[j].inner; });\n        }\n        int first = rank_by_inner[ uniform_int_distribution<int>(0,299)(rng) ];\n        seq.push_back(first);\n        used[first]=1;\n\n        while((int)seq.size()<NEED){\n            ll bestDelta = (1LL<<60);\n            int bestOrder=-1, bestPos=-1;\n\n            int m = seq.size();\n            for(int k=0;k<N;++k) if(!used[k]){\n                const Order &o = ord[k];\n                for(int pos=0; pos<=m; ++pos){\n                    int px,py,nx,ny;\n                    if(pos==0){\n                        px=400; py=400;\n                    }else{\n                        const Order &prev = ord[seq[pos-1]];\n                        px=prev.cx; py=prev.cy;\n                    }\n                    if(pos==m){\n                        nx=400; ny=400;\n                    }else{\n                        const Order &next = ord[seq[pos]];\n                        nx=next.ax; ny=next.ay;\n                    }\n                    ll delta = md(px,py,o.ax,o.ay) + o.inner + md(o.cx,o.cy,nx,ny)\n                               - md(px,py,nx,ny);\n                    if(delta < bestDelta){\n                        bestDelta = delta;\n                        bestOrder = k;\n                        bestPos   = pos;\n                    }\n                }\n            }\n            seq.insert(seq.begin()+bestPos, bestOrder);\n            used[bestOrder]=1;\n        }\n\n        /* ---- 2. 2-opt on the sequence of pairs ------------------------ */\n        bool improved = true;\n        ll curCost = route_cost(ord, seq);\n        while(improved){\n            improved = false;\n            for(int i=0;i<NEED-1 && !improved;++i){\n                for(int j=i+1;j<NEED;++j){\n                    reverse(seq.begin()+i, seq.begin()+j+1);\n                    ll nc = route_cost(ord, seq);\n                    if(nc < curCost){\n                        curCost = nc;\n                        improved = true;\n                        break;\n                    }\n                    reverse(seq.begin()+i, seq.begin()+j+1);   // rollback\n                }\n            }\n        }\n\n        /* ---- 3. keep the best ---------------------------------------- */\n        if(curCost < best_cost){\n            best_cost = curCost;\n            best_seq  = seq;\n        }\n    }\n\n    /* ---- 4. build the final explicit route --------------------------- */\n    vector<int> X, Y;\n    X.reserve(2*NEED+2); Y.reserve(2*NEED+2);\n    X.push_back(400); Y.push_back(400);\n    for(int id:best_seq){\n        const Order &o = ord[id];\n        X.push_back(o.ax); Y.push_back(o.ay);\n        X.push_back(o.cx); Y.push_back(o.cy);\n    }\n    X.push_back(400); Y.push_back(400);\n\n    /* ---- 5. output --------------------------------------------------- */\n    cout << NEED;\n    for(int id:best_seq) cout << ' ' << (id+1);         // 1-based indices\n    cout << '\\n';\n\n    cout << X.size();\n    for(size_t i=0;i<X.size();++i) cout << ' ' << X[i] << ' ' << Y[i];\n    cout << '\\n';\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- Union-Find (DSU) ---------- */\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        sz.assign(n, 1);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int v) { return p[v] == v ? v : p[v] = find(p[v]); }\n    /* returns new root */\n    int unite(int a, int b) {\n        a = find(a);  b = find(b);\n        if (a == b) return a;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a;\n        sz[a] += sz[b];\n        return a;                 // root that survives\n    }\n};\n\nconstexpr int N = 400;\nconstexpr int M = 1995;\n\n/* global static matrices (only 0.6 MiB) */\nstatic int remEdge[N][N];          // remaining edges between roots\nstatic int extCnt[N];              // remaining external edges of root\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read fixed part ---------- */\n    vector<int> X(N), Y(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i];\n\n    vector<int> U(M), V(M);\n    for (int i = 0; i < M; ++i) cin >> U[i] >> V[i];\n\n    /* ---------- lower-bound distances d[i] ---------- */\n    vector<int> d(M);\n    for (int i = 0; i < M; ++i) {\n        long long dx = X[U[i]] - X[V[i]];\n        long long dy = Y[U[i]] - Y[V[i]];\n        d[i] = int(lround(std::sqrt(double(dx * dx + dy * dy))));\n        if (d[i] == 0) d[i] = 1;                // just in case\n    }\n\n    /* ---------- mark one Euclidean MST ---------- */\n    vector<int> ord(M);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a, int b){ return d[a] < d[b]; });\n\n    vector<char> inMST(M, 0);\n    DSU tmp(N);\n    int used = 0;\n    for (int id : ord) {\n        if (tmp.unite(U[id], V[id]) != -1) {    // merged\n            inMST[id] = 1;\n            if (++used == N - 1) break;\n        }\n    }\n\n    /* ---------- initialise remaining-edge counters ---------- */\n    for (int i = 0; i < M; ++i) {\n        int u = U[i], v = V[i];\n        remEdge[u][v]++;\n        remEdge[v][u]++;\n        extCnt[u]++; extCnt[v]++;\n    }\n\n    /* ---------- on-line phase ---------- */\n    DSU dsu(N);\n    int components = N;\n\n    auto mergeRows = [&](int keep, int gone) {\n        for (int t = 0; t < N; ++t) if (t != keep && remEdge[gone][t]) {\n            remEdge[keep][t] += remEdge[gone][t];\n            remEdge[t][keep]  = remEdge[keep][t];\n            remEdge[gone][t] = remEdge[t][gone] = 0;\n        }\n        extCnt[gone] = 0;\n\n        long long sum = 0;\n        for (int t = 0; t < N; ++t) if (t != keep) sum += remEdge[keep][t];\n        extCnt[keep] = int(sum);\n    };\n\n    for (int i = 0; i < M; ++i) {\n        long long li; cin >> li;\n        int u = U[i], v = V[i];\n        int ru = dsu.find(u), rv = dsu.find(v);\n\n        /* 1) remove this edge from \"future\" */\n        if (ru != rv) {\n            remEdge[ru][rv]--;\n            remEdge[rv][ru]--;\n            --extCnt[ru];\n            --extCnt[rv];\n        }\n\n        bool take = false, mustTake = false;\n\n        if (ru != rv) {\n            /* last chance for one of the endpoints? */\n            if (extCnt[ru] == 0 || extCnt[rv] == 0) mustTake = true;\n\n            /* price check (only if not forced) */\n            double ratio = double(li) / double(d[i]);\n            double thr   = 1.15 + 1.85 * double(i) / double(M);\n            if (inMST[i]) thr += 0.15;\n\n            if (ratio <= thr) take = true;\n        }\n        if (mustTake) take = true;\n\n        /* absolute safety: we must not run out of edges */\n        if (!take && ru != rv) {\n            int edgesLeft = M - i - 1;\n            if (components - 1 > edgesLeft) take = true;\n        }\n\n        /* ---------- output decision ---------- */\n        cout << (take ? 1 : 0) << '\\n' << flush;\n\n        /* ---------- apply decision ---------- */\n        if (take && ru != rv) {\n            int newRoot = dsu.unite(ru, rv);\n            int dead    = (newRoot == ru ? rv : ru);\n            mergeRows(newRoot, dead);\n            --components;\n        }\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pet{\n    int x, y, type;\n};\nstruct Human{\n    int x, y;              // current position (1-based)\n    int line_col;          // column of the wall we are drawing\n    int side;              // +1 : we stand right of the wall and build left  (action 'l')\n                           // -1 : we stand left  of the wall and build right (action 'r')\n    int target_col;        // column we want to stand on while building\n    int phase = 0;         // 0 = move to starting cell (row 1, target_col)\n                           // 1 = build wall while going down\n    bool build_next = true;\n};\n\nconst int H = 30, W = 30;\nconst int dx[4]={-1,1,0,0};\nconst int dy[4]={0,0,-1,1};\n\nbool inside(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;                    // pets\n    if(!(cin>>N)) return 0;\n    vector<Pet> pets(N);\n    for(auto &p:pets) cin>>p.x>>p.y>>p.type;\n\n    int M;                    // humans\n    cin>>M;\n    vector<Human> hum(M);\n    for(auto &h:hum) cin>>h.x>>h.y;\n\n    /* precompute the columns on which walls will be built */\n    const vector<int> WALL_COLS = {2,5,8,11,14,17,20,23,26,29};\n\n    for(int i=0;i<M;i++){\n        hum[i].line_col = WALL_COLS[i];               // one line per human\n        hum[i].side     = (hum[i].line_col < 15)? +1 : -1;\n        hum[i].target_col = hum[i].line_col + hum[i].side;\n    }\n\n    /* current map,   '.' = passable,  '#' = wall                                */\n    vector<string> board(H+2,string(W+2,'#'));        // sentinel rim\n    for(int x=1;x<=H;x++) for(int y=1;y<=W;y++) board[x][y]='.';\n\n    auto pet_near = [&](int x,int y)->bool{\n        for(const auto &p:pets){\n            if(p.x==x && p.y==y) return true;\n            if(abs(p.x-x)+abs(p.y-y)==1) return true;\n        }\n        return false;\n    };\n\n    for(int turn=0;turn<300;turn++){\n        string actions;\n        actions.reserve(M);\n\n        /* choose an action for every human */\n        for(int i=0;i<M;i++){\n            auto &h = hum[i];\n            char act='.';            // default : stay\n\n            if(h.phase==0){\n                if(h.y != h.target_col){\n                    act = (h.y < h.target_col)? 'R':'L';\n                }else if(h.x != 1){\n                    act = 'U';\n                }else{\n                    h.phase = 1;\n                    h.build_next = true;        // fall through to phase 1\n                }\n            }\n            if(h.phase==1 && act=='.'){\n                if(h.build_next){\n                    int tx = h.x;\n                    int ty = h.y - h.side;      // square where we create a wall\n                    if(inside(tx,ty) && board[tx][ty]=='.' && !pet_near(tx,ty)){\n                        act = (h.side==1)? 'l':'r';   // build\n                    }else{\n                        act='.';                      // skip if illegal\n                    }\n                    h.build_next = false;\n                }else{\n                    if(h.x < H){\n                        act='D';\n                        h.build_next = true;\n                    }else{\n                        act='.';\n                    }\n                }\n            }\n            actions.push_back(act);\n        }\n\n        /* output */\n        cout<<actions<<\"\\n\"<<flush;\n\n        /* apply our actions */\n        for(int i=0;i<M;i++){\n            char c = actions[i];\n            auto &h=hum[i];\n            if(c=='.') continue;\n            if(c=='U'){ h.x--; }\n            else if(c=='D'){ h.x++; }\n            else if(c=='L'){ h.y--; }\n            else if(c=='R'){ h.y++; }\n            else{\n                int tx=h.x, ty=h.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(inside(tx,ty)) board[tx][ty]='#';\n            }\n        }\n\n        /* read pets' movement and update their positions */\n        for(int i=0;i<N;i++){\n            string s; cin>>s;\n            auto &p=pets[i];\n            for(char c:s){\n                if(c=='U') p.x--;\n                else if(c=='D') p.x++;\n                else if(c=='L') p.y--;\n                else if(c=='R') p.y++;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Node {\n    int i, j;\n};\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ------------------------------------------------ */\n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n\n    vector<string> h(20);          // horizontal walls, length 19 each\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);          // vertical   walls, length 20 each\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n\n    /* ---------- plain BFS -------------------------------------------------- */\n    const int H = 20, W = 20, N = H * W;\n    auto id = [&](int i, int j){ return i * W + j; };\n\n    vector<int> prev(N, -1);       // predecessor vertex\n    vector<char> prevMove(N);      // move taken to reach that vertex\n    queue<Node> q;\n    q.push({si, sj});\n    prev[id(si,sj)] = -2;          // mark as source\n\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    const char dc[4] = {'U','D','L','R'};\n\n    while(!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (ni < 0 || ni >= H || nj < 0 || nj >= W) continue;\n            bool wall = false;\n            if (dir == 0) wall = (v[i-1][j] == '1');           // up\n            if (dir == 1) wall = (v[i][j]   == '1');           // down\n            if (dir == 2) wall = (h[i][j-1] == '1');           // left\n            if (dir == 3) wall = (h[i][j]   == '1');           // right\n            if (wall) continue;\n\n            int nid = id(ni,nj);\n            if (prev[nid] != -1) continue;                     // visited\n            prev[nid] = id(i,j);\n            prevMove[nid] = dc[dir];\n            q.push({ni,nj});\n        }\n    }\n\n    /* ---------- reconstruct shortest path --------------------------------- */\n    string path;\n    for (int cur = id(ti,tj); prev[cur] != -2; cur = prev[cur])\n        path.push_back(prevMove[cur]);\n    reverse(path.begin(), path.end());          // now from start to goal\n\n    /* ---------- build the robust route ------------------------------------ */\n    string result;\n    result.reserve(200);\n\n    // copy the shortest path twice (<= 78 characters)\n    result += path;\n    result += path;\n\n    // fill the rest with the old fallback\n    while (result.size() + 2 <= 200) result += \"DR\";\n    if (result.size() < 200) result.push_back('D');   // length must be <=200\n\n    cout << result << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int H = 30, W = 30, DIR = 4;\nconst int di[DIR] = {0,-1,0,1};      // L, U, R, D\nconst int dj[DIR] = {-1,0,1,0};\n\nconst int TO_BASE[8][4] = {           // statement table\n    {1,0,-1,-1},\n    {3,-1,-1,0},\n    {-1,-1,3,2},\n    {-1,2,1,-1},\n    {1,0,3,2},\n    {3,2,1,0},\n    {2,-1,0,-1},\n    {-1,3,-1,1}\n};\n\nint type[H][W];                       // 0\u20257 read from input\nint rot [H][W];                       // current rotation 0\u20253\n\nint maskTable[8][4];                  // bitset of used sides after rot\nint toTable  [8][4][4];               // dir-mapping after rot\n\n/*------------------------------------------------------------------*/\nvoid precalc(){\n    for(int t=0;t<8;t++)\n        for(int r=0;r<4;r++){\n            int m=0;\n            for(int d=0;d<4;d++){\n                int d0=(d-r+4)%4;\n                int td=TO_BASE[t][d0];\n                int res = (td==-1) ? -1 : (td+r)%4;\n                toTable[t][r][d]=res;\n                if(res!=-1){ m|=1<<d; m|=1<<res; }\n            }\n            maskTable[t][r]=m;\n        }\n}\n/*------------------------------------------------------------------*/\ninline bool inside(int i,int j){return 0<=i && i<H && 0<=j && j<W;}\ninline int bitCnt(int x){ return __builtin_popcount((unsigned)x); }\ninline int curMask(int i,int j){ return maskTable[type[i][j]][rot[i][j]]; }\n\n/*------------------------------------------------------------------*/\n/* open-ends bookkeeping                                            */\nint openEnds = 0;\nint deltaOpenEnds(int i,int j,int newR){          // difference if (i,j)=newR\n    int oldM = curMask(i,j);\n    int newM = maskTable[type[i][j]][newR];\n    if(oldM==newM) return 0;\n    int diff = 0;\n    for(int d=0;d<4;d++){\n        int ni=i+di[d], nj=j+dj[d];\n        int oldU = (oldM>>d)&1;\n        int newU = (newM>>d)&1;\n        int nbU  = (inside(ni,nj)? (curMask(ni,nj)>>((d+2)&3)&1) : 0);\n        int oldMis = oldU ^ nbU;\n        int newMis = newU ^ nbU;\n        diff += (inside(ni,nj)? 2 : 1)*(newMis - oldMis);\n    }\n    return diff;\n}\nvoid applyRot(int i,int j,int newR){\n    openEnds += deltaOpenEnds(i,j,newR);\n    rot[i][j]=newR;\n}\nvoid recomputeOE(){\n    openEnds=0;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int m=curMask(i,j);\n        for(int d=0;d<4;d++) if(m>>d&1){\n            int ni=i+di[d], nj=j+dj[d];\n            if(!inside(ni,nj) || !(curMask(ni,nj)>>((d+2)&3)&1)) ++openEnds;\n        }\n    }\n}\n/*------------------------------------------------------------------*/\n/* loop score                                                        */\nlong long loopScore(const array<array<int,W>,H>& R){\n    static bool vis[H][W][4];\n    memset(vis,0,sizeof(vis));\n    vector<int> lens;\n    for(int si=0;si<H;si++)for(int sj=0;sj<W;sj++){\n        int r=R[si][sj];\n        int m = maskTable[type[si][sj]][r];\n        for(int sd=0;sd<4;sd++) if((m>>sd&1) && !vis[si][sj][sd]){\n            int i=si,j=sj,d=sd,len=0;\n            while(true){\n                vis[i][j][d]=true;\n                int nd = toTable[type[i][j]][ R[i][j] ][d];\n                if(nd==-1) { len=0; break; }\n                int ni=i+di[nd], nj=j+dj[nd];\n                if(!inside(ni,nj)) { len=0; break; }\n                int ndIn=(nd+2)&3;\n                ++len;\n                i=ni; j=nj; d=ndIn;\n                if(i==si && j==sj && d==sd){ lens.push_back(len); break; }\n                if(vis[i][j][d]){ len=0; break; }       // shouldn't happen\n            }\n        }\n    }\n    if(lens.size()<2) return 0;\n    nth_element(lens.begin(),lens.begin()+1,lens.end(),greater<int>());\n    return 1LL*lens[0]*lens[1];\n}\nlong long currentScore(){\n    array<array<int,W>,H> R;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) R[i][j]=rot[i][j];\n    return loopScore(R);\n}\n/*------------------------------------------------------------------*/\n/* initial pattern                                                   */\nint desiredMask(int i,int j){\n    bool evenRow = !(i&1), evenCol = !(j&1);\n    if(evenRow)  return evenCol ? ((1<<2)|(1<<3)) : ((1<<0)|(1<<3));\n    else         return evenCol ? ((1<<2)|(1<<1)) : ((1<<0)|(1<<1));\n}\nint bestInitRot(int ty,int want){\n    int best=-1, bestHit=-1, extra=10;\n    for(int r=0;r<4;r++){\n        int mk=maskTable[ty][r];\n        int hit = bitCnt(mk & want);\n        int ext = bitCnt(mk & ~want);\n        if(hit>bestHit || (hit==bestHit && ext<extra)){\n            bestHit=hit; extra=ext; best=r;\n        }\n    }\n    return best;\n}\n/*------------------------------------------------------------------*/\nstruct Timer{\n    const double TL; chrono::steady_clock::time_point st;\n    Timer(double tl=1.95):TL(tl),st(chrono::steady_clock::now()){}\n    double elap()const{\n        return chrono::duration<double>(chrono::steady_clock::now()-st).count();\n    }\n    bool good()const{ return elap()<TL; }\n} timer;\n/*------------------------------------------------------------------*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    precalc();\n\n    /* proper input reader: 30 \u00d7 30 digits without blanks */\n    for(int i=0;i<H;i++){\n        string s; cin>>s;\n        for(int j=0;j<W;j++) type[i][j]=s[j]-'0';\n    }\n\n    /* 1. deterministic start                                         */\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int want = desiredMask(i,j);\n        rot[i][j]=bestInitRot(type[i][j],want);\n    }\n    recomputeOE();\n\n    /* 2. greedy fix                                                  */\n    mt19937 rng(1234567);\n    vector<pair<int,int>> cells;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cells.emplace_back(i,j);\n\n    while(openEnds>0 && timer.elap()<0.6){\n        shuffle(cells.begin(),cells.end(),rng);\n        bool changed=false;\n        for(auto [i,j]:cells){\n            int bestR=rot[i][j], bestD=0;\n            for(int r=0;r<4;r++){\n                int d=deltaOpenEnds(i,j,r);\n                if(d<bestD){ bestD=d; bestR=r; }\n            }\n            if(bestR!=rot[i][j]){\n                applyRot(i,j,bestR);\n                changed=true;\n                if(openEnds==0) break;\n            }\n        }\n        if(!changed) break;\n    }\n\n    /* 3. quick hill-climb                                            */\n    long long bestScore = (openEnds==0)? currentScore() : 0;\n    array<array<int,W>,H> bestRot;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) bestRot[i][j]=rot[i][j];\n\n    uniform_int_distribution<int> dist(0,H*W-1);\n    while(timer.good()){\n        int v=dist(rng), i=v/W, j=v%W;\n        int oldR=rot[i][j];\n        int newR = (oldR + 1 + dist(rng)%3)&3;\n        int oldOE=openEnds;\n        applyRot(i,j,newR);\n\n        bool keep=false; long long cand=0;\n        if(openEnds==0){\n            cand=currentScore();\n            if(cand>=bestScore) keep=true;\n        }else if(openEnds<oldOE) keep=true;\n\n        if(keep){\n            if(openEnds==0 && cand>bestScore){\n                bestScore=cand;\n                for(int x=0;x<H;x++)for(int y=0;y<W;y++) bestRot[x][y]=rot[x][y];\n            }\n        }else{\n            applyRot(i,j,oldR);       // revert\n            openEnds=oldOE;\n        }\n    }\n\n    /* 4. output                                                      */\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'+bestRot[i][j]));\n    cout<<out<<\"\\n\";\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\nusing  ll = long long;\n\nstruct Timer{\n    chrono::steady_clock::time_point st;\n    Timer(){st = chrono::steady_clock::now();}\n    double elapsed() const {\n        return chrono::duration<double>(chrono::steady_clock::now()-st).count();\n    }\n};\n\nstruct Solver {\n    int N, T;\n    vector<int> board;          // -1 : empty , 0..15 : tile pattern\n    int blank;                  // index of the empty square (0..N*N-1)\n    string bestMoves;           // best prefix found so far\n    int bestScore = -1;         // its S value\n    string curMoves;            // moves executed in the current state\n    int curScore;               // S of current state\n    mt19937 rng;\n\n    static inline int bit(int dir){          // 0U 1D 2L 3R\n        static const int b[4]={2,8,1,4};\n        return b[dir];\n    }\n    static inline int opp(int dir){          // opposite direction\n        return dir^1;\n    }\n\n    int largestTree(const vector<int>& a){\n        const int NN = N*N;\n        vector<char> vis(NN,0);\n        int best=0;\n        static const int dx[4]={-1,1,0,0};\n        static const int dy[4]={0,0,-1,1};\n        queue<int> q;\n        for(int v=0;v<NN;v++){\n            if(a[v]==-1 || vis[v]) continue;\n            int vert=0, edges=0;\n            q.push(v);\n            vis[v]=1;\n            while(!q.empty()){\n                int id=q.front(); q.pop();\n                ++vert;\n                int x=id/N, y=id%N;\n                int t=a[id];\n                for(int d=0;d<4;d++){\n                    int nx=x+dx[d], ny=y+dy[d];\n                    if(nx<0||nx>=N||ny<0||ny>=N) continue;\n                    int nid=nx*N+ny;\n                    if(a[nid]==-1) continue;\n                    if( (t & bit(d)) && (a[nid] & bit(opp(d))) ){\n                        if(id < nid) ++edges;          // count each edge once\n                        if(!vis[nid]){\n                            vis[nid]=1;\n                            q.push(nid);\n                        }\n                    }\n                }\n            }\n            if(edges == vert-1) best = max(best, vert);\n        }\n        return best;\n    }\n\n    bool inRange(int x,int y){return 0<=x && x<N && 0<=y && y<N;}\n\n    void run(){\n        Timer timer;\n        rng.seed(chrono::steady_clock::now().time_since_epoch().count());\n\n        curScore = largestTree(board);\n        bestScore = curScore;\n        bestMoves.clear();\n\n        uniform_real_distribution<double> uni(0.0,1.0);\n        static const int dx[4]={-1,1,0,0};\n        static const int dy[4]={0,0,-1,1};\n        static const char dc[4]={'U','D','L','R'};\n\n        const double TL = 2.95;                 // safety margin\n        const double T0 = 5.0, T1 = 0.1;        // annealing schedule\n\n        while(curMoves.size() < (size_t)T && timer.elapsed() < TL){\n            /* make a candidate move -------------------------------------- */\n            int bx = blank / N, by = blank % N;\n\n            vector<int> candDir;\n            for(int d=0;d<4;d++){\n                int nx=bx+dx[d], ny=by+dy[d];\n                if(inRange(nx,ny)) candDir.push_back(d);\n            }\n            int dir = candDir[rng() % candDir.size()];\n\n            vector<int> nb = board;\n            int nx=bx+dx[dir], ny=by+dy[dir];\n            int nid = nx*N + ny;\n            swap(nb[blank], nb[nid]);\n\n            int candScore = largestTree(nb);\n            int delta = candScore - curScore;\n\n            /* temperature according to progress */\n            double progress = double(curMoves.size()) / double(T);\n            double temp = T0 + (T1-T0)*progress;\n\n            bool accept = false;\n            if(delta >= 0) accept = true;\n            else           accept = (uni(rng) < exp(double(delta)/temp));\n\n            if(accept){\n                // commit\n                board.swap(nb);\n                blank = nid;\n                curMoves.push_back(dc[dir]);\n                curScore = candScore;\n\n                if(curScore > bestScore){\n                    bestScore = curScore;\n                    bestMoves = curMoves;\n                    // early exit if we achieved the theoretical maximum\n                    if(bestScore == N*N-1) break;\n                }\n            }\n        }\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    Solver S;\n    cin >> S.N >> S.T;\n    const int NN = S.N*S.N;\n    S.board.resize(NN);\n    for(int i=0;i<S.N;i++){\n        string row; cin >> row;\n        for(int j=0;j<S.N;j++){\n            char c=row[j];\n            int v = (c<='9') ? c-'0' : c-'a'+10;\n            if(v==0){                         // empty square\n                S.board[i*S.N+j]=-1;\n                S.blank = i*S.N+j;\n            }else{\n                S.board[i*S.N+j]=v;\n            }\n        }\n    }\n\n    S.run();\n    cout << S.bestMoves << '\\n';\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconstexpr int R = 10000;              // cake radius\nconst ll BIG = 1'000'000'000LL;\n\nstruct FastRand {\n    uint64_t x = 88172645463325252ULL;\n    uint64_t next() { x ^= x << 7; x ^= x >> 9; return x; }\n    int next_int(int l, int r){ return int(next()%uint64_t(r-l+1))+l; }\n} rng;\n\n/* ------------------------------------------------------------\n   evaluate one AXIS-ALIGNED grid  (vx.size()+hy.size() \u2264 100)\n   returns the number of attendees that can be served\n   ------------------------------------------------------------ */\nstruct Evaluator{\n    const vector<pair<int,int>>& P;       // strawberries\n    const array<int,11>& need;            // a_d\n    vector<int> cell;                     // reused buffer\n\n    explicit Evaluator(const vector<pair<int,int>>& p,\n                       const array<int,11>& a): P(p),need(a){}\n\n    int operator()(const vector<int>& vx,const vector<int>& hy){\n        const int V=vx.size(), H=hy.size();\n        const int W=(V+1)*(H+1);\n        if((int)cell.size()<W) cell.resize(W);\n        fill(cell.begin(), cell.begin()+W, 0);\n\n        for(auto [x,y]:P){\n            // we guarantee that no line lies on a strawberry\n            int ix = int(lower_bound(vx.begin(),vx.end(),x)-vx.begin());\n            int iy = int(lower_bound(hy.begin(),hy.end(),y)-hy.begin());\n            cell[ix*(H+1)+iy]++;\n        }\n        array<int,11> have{};             // b_d\n        for(int c:cell) if(1<=c && c<=10) ++have[c];\n\n        int served=0;\n        for(int d=1;d<=10;++d) served += min(need[d], have[d]);\n        return served;\n    }\n};\n\n/* ------------------------------------------------------------\n   helpers\n   ------------------------------------------------------------ */\ntemplate<class S>\nint rnd_choice(const S& v){ return rng.next_int(0,(int)v.size()-1); }\n\nint sample_coord(unordered_set<int>& used,\n                 const unordered_set<int>& forbid,\n                 int l=-R, int r=R){\n    int x;\n    do{ x = rng.next_int(l,r); }while(used.count(x)||forbid.count(x));\n    used.insert(x);\n    return x;\n}\n\n/* ------------------------------------------------------------\n   main\n   ------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N,K;\n    if(!(cin>>N>>K)) return 0;\n    array<int,11> a{};\n    for(int d=1;d<=10;++d) cin>>a[d];\n\n    vector<pair<int,int>> P(N);\n    unordered_set<int> forbidX,forbidY; forbidX.reserve(N*2); forbidY.reserve(N*2);\n    for(auto& pt:P){\n        cin>>pt.first>>pt.second;\n        forbidX.insert(pt.first);\n        forbidY.insert(pt.second);\n    }\n\n    Evaluator eval(P,a);\n\n    /* ---------- initial random grid ----------------------- */\n    vector<int> vx,hy;\n    {\n        int v = rng.next_int(10,40);              // not too small, not too big\n        int h = rng.next_int(10,40);\n        unordered_set<int> u;\n        for(int i=0;i<v;++i) vx.push_back(sample_coord(u,forbidX));\n        u.clear();\n        for(int i=0;i<h;++i) hy.push_back(sample_coord(u,forbidY));\n        sort(vx.begin(),vx.end());\n        sort(hy.begin(),hy.end());\n    }\n\n    int curScore = eval(vx,hy);\n    vector<int> bestVX = vx, bestHY = hy;\n    int bestScore = curScore;\n\n    /* ---------- local search / hill climbing -------------- */\n    const auto t0 = chrono::steady_clock::now();\n    size_t iter = 0;\n    while(true){\n        auto now = chrono::steady_clock::now();\n        if(chrono::duration<double>(now-t0).count() > 2.9) break;\n\n        ++iter;\n        int op = rng.next_int(0,99);          // 0..59 move, 60..79 insert, 80..99 delete\n\n        vector<int> newVX = vx, newHY = hy;\n\n        bool ok = true;\n        if(op < 60 && (vx.size()+hy.size())>0){          // move\n            bool vertical = rng.next_int(0,1);\n            if(vertical && !newVX.empty()){\n                int idx = rnd_choice(newVX);\n                int old = newVX[idx];\n                int delta = rng.next_int(-800,800);\n                int neu = old + delta;\n                if(abs(neu) > R) neu = (neu>0?R:-R);     // keep inside disc (not mandatory)\n                if(!forbidX.count(neu) &&\n                   !binary_search(newVX.begin(),newVX.end(),neu)){\n                    newVX[idx]=neu; sort(newVX.begin(),newVX.end());\n                }else ok=false;\n            }else if(!vertical && !newHY.empty()){\n                int idx = rnd_choice(newHY);\n                int old = newHY[idx];\n                int delta = rng.next_int(-800,800);\n                int neu = old + delta;\n                if(abs(neu) > R) neu = (neu>0?R:-R);\n                if(!forbidY.count(neu) &&\n                   !binary_search(newHY.begin(),newHY.end(),neu)){\n                    newHY[idx]=neu; sort(newHY.begin(),newHY.end());\n                }else ok=false;\n            }else ok=false;\n        }\n        else if(op < 80 && (int)newVX.size()+ (int)newHY.size() < K){ // insert\n            bool vertical = rng.next_int(0,1);\n            if(vertical){\n                unordered_set<int> used(newVX.begin(),newVX.end());\n                int neu = sample_coord(used,forbidX);\n                newVX.push_back(neu); sort(newVX.begin(),newVX.end());\n            }else{\n                unordered_set<int> used(newHY.begin(),newHY.end());\n                int neu = sample_coord(used,forbidY);\n                newHY.push_back(neu); sort(newHY.begin(),newHY.end());\n            }\n        }\n        else if(op >=80){                                      // delete\n            bool vertical = (newHY.empty() || (!newVX.empty() && rng.next_int(0,1)));\n            if(vertical && !newVX.empty()){\n                newVX.erase(newVX.begin()+rnd_choice(newVX));\n            }else if(!vertical && !newHY.empty()){\n                newHY.erase(newHY.begin()+rnd_choice(newHY));\n            }else ok=false;\n        }\n\n        if(!ok) continue;                     // illegal proposal, skip\n\n        int sc = eval(newVX,newHY);\n        if(sc >= curScore){                   // hill climbing (accept ties)\n            vx.swap(newVX); hy.swap(newHY); curScore = sc;\n            if(sc > bestScore){\n                bestScore = sc;\n                bestVX = vx; bestHY = hy;\n            }\n        }\n    }\n    //cerr<<\"iterations \"<<iter<<\"  best \"<<bestScore<<\"\\n\";\n\n    /* ---------- output ------------------------------------ */\n    cout << bestVX.size()+bestHY.size() << '\\n';\n    for(int x: bestVX) cout<<x<<\" \"<<-BIG<<\"  \"<<x<<\" \"<<BIG<<\"\\n\";\n    for(int y: bestHY) cout<<-BIG<<\" \"<<y<<\"  \"<<BIG<<\" \"<<y<<\"\\n\";\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ------------------------------------------------------------\n   edge maps\n   ------------------------------------------------------------ */\nconstexpr int MAXN = 62;           // N \u2264 61  (make arrays 1 bigger)\n\nstatic bool dot[MAXN][MAXN];       // existing dots\nstatic bool hEdge[MAXN][MAXN];     // (x,y)-(x+1,y)\nstatic bool vEdge[MAXN][MAXN];     // (x,y)-(x,y+1)\nstatic bool neEdge[MAXN][MAXN];    // (x,y)-(x+1,y+1)\nstatic bool nwEdge[MAXN][MAXN];    // (x+1,y)-(x,y+1)\n\nstruct Op { int p[8]; };           // output record\n\n/* ------------------------------------------------------------\n   helper\n   ------------------------------------------------------------ */\ninline int w(int x,int y,int c){ return (x-c)*(x-c)+(y-c)*(y-c)+1; }\n\nint main(){\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    int N,M;  if(!(cin>>N>>M)) return 0;\n    for(int i=0;i<M;++i){ int x,y; cin>>x>>y; dot[x][y]=true; }\n\n    const int C = (N-1)/2;                 // board centre\n    vector<Op> ops;\n\n    while(true){\n        /* ---- search the best move -------------------------------- */\n        int bestW = -1;\n        int kind  = -1;        // 0 = axis square, 1 = diamond\n        int bx=-1,by=-1,miss=-1;\n\n        /* axis-parallel 1\u00d71 squares */\n        for(int y=0;y<N-1;++y) for(int x=0;x<N-1;++x){\n            if(hEdge[y][x]||hEdge[y+1][x]||vEdge[y][x]||vEdge[y][x+1]) continue;\n\n            bool p[4] = {dot[x][y],dot[x+1][y],dot[x+1][y+1],dot[x][y+1]};\n            int mc=0,mi=-1;\n            for(int k=0;k<4;++k) if(!p[k]){ ++mc; mi=k; }\n            if(mc!=1) continue;\n            int xx=x + (mi==1||mi==2);\n            int yy=y + (mi>=2);\n            int weight=w(xx,yy,C);\n            if(weight>bestW){\n                bestW=weight; kind=0; bx=x; by=y; miss=mi;\n            }\n        }\n\n        /* 45\u00b0 diamonds (bottom vertex = (x,y)) */\n        for(int y=0;y<=N-3;++y) for(int x=1;x<=N-2;++x){\n            if(neEdge[y][x]      || nwEdge[y+1][x] ||\n               neEdge[y+1][x-1] ||  nwEdge[y][x-1]) continue;\n\n            bool p[4] = {\n                dot[x][y],           // 0 bottom\n                dot[x+1][y+1],       // 1 right\n                dot[x][y+2],         // 2 top\n                dot[x-1][y+1]        // 3 left\n            };\n            int mc=0,mi=-1;\n            for(int k=0;k<4;++k) if(!p[k]){ ++mc; mi=k; }\n            if(mc!=1) continue;\n\n            int xx,yy;\n            switch(mi){\n                case 0: xx=x;     yy=y;     break;\n                case 1: xx=x+1;   yy=y+1;   break;\n                case 2: xx=x;     yy=y+2;   break;\n                default:xx=x-1;   yy=y+1;   break;\n            }\n            int weight=w(xx,yy,C);\n            if(weight>bestW){\n                bestW=weight; kind=1; bx=x; by=y; miss=mi;\n            }\n        }\n\n        if(bestW<0) break;          // no further move possible\n\n        Op op;\n        if(kind==0){\n            /* ----- axis square ----------------------------------- */\n            auto corner=[&](int i)->pair<int,int>{\n                switch(i&3){\n                    case 0: return {bx    ,by    };  // BL\n                    case 1: return {bx+1  ,by    };  // BR\n                    case 2: return {bx+1  ,by+1  };  // TR\n                    default:return {bx    ,by+1  };  // TL\n                }};\n            for(int i=0;i<4;++i){\n                auto [cx,cy]=corner(miss+i);\n                op.p[2*i]=cx; op.p[2*i+1]=cy;\n            }\n            /* mark edges */\n            hEdge[by][bx]=hEdge[by+1][bx]=true;\n            vEdge[by][bx]=vEdge[by][bx+1]=true;\n\n            /* new dot */\n            auto [nx,ny]=corner(miss);\n            dot[nx][ny]=true;\n        }else{\n            /* ----- diamond --------------------------------------- */\n            auto corner=[&](int i)->pair<int,int>{\n                switch(i&3){\n                    case 0: return {bx    ,by    };       // bottom\n                    case 1: return {bx+1  ,by+1  };       // right\n                    case 2: return {bx    ,by+2  };       // top\n                    default:return {bx-1  ,by+1  };       // left\n                }};\n            for(int i=0;i<4;++i){\n                auto [cx,cy]=corner(miss+i);\n                op.p[2*i]=cx; op.p[2*i+1]=cy;\n            }\n            /* mark edges */\n            neEdge[by][bx]      = true;            // bottom-right\n            nwEdge[by+1][bx]    = true;            // right-top\n            neEdge[by+1][bx-1]  = true;            // top-left\n            nwEdge[by][bx-1]    = true;            // left-bottom\n\n            /* new dot */\n            auto [nx,ny]=corner(miss);\n            dot[nx][ny]=true;\n        }\n        ops.push_back(op);\n    }\n\n    /* ------------- output ---------------------------------------- */\n    cout<<ops.size()<<'\\n';\n    for(auto &o:ops){\n        for(int i=0;i<8;++i){ if(i) cout<<' '; cout<<o.p[i]; }\n        cout<<'\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Grid = array<array<int,10>,10>;\n\n/* ------------------------------------------------------------ */\npair<int,int> locate(const Grid& g,int idx){          // idx : 1-based\n    int cnt = 0;\n    for(int r=0;r<10;r++)\n        for(int c=0;c<10;c++)\n            if(g[r][c]==0 && ++cnt==idx) return {r,c};\n    return {-1,-1};                                    // never reached\n}\n/* ------------------------------------------------------------ */\nvoid tilt(Grid& dst,const Grid& src,char dir){\n    dst = {};                                          // fill with 0\n    if(dir=='F'){                                      // to row 0\n        for(int c=0;c<10;c++){\n            int wr = 0;\n            for(int r=0;r<10;r++)\n                if(src[r][c]) dst[wr++][c] = src[r][c];\n        }\n    }else if(dir=='B'){                                // to row 9\n        for(int c=0;c<10;c++){\n            int wr = 9;\n            for(int r=9;r>=0;r--)\n                if(src[r][c]) dst[wr--][c] = src[r][c];\n        }\n    }else if(dir=='L'){                                // to col 0\n        for(int r=0;r<10;r++){\n            int wc = 0;\n            for(int c=0;c<10;c++)\n                if(src[r][c]) dst[r][wc++] = src[r][c];\n        }\n    }else{                                             // 'R' to col 9\n        for(int r=0;r<10;r++){\n            int wc = 9;\n            for(int c=9;c>=0;c--)\n                if(src[r][c]) dst[r][wc--] = src[r][c];\n        }\n    }\n}\n/* ------------------------------------------------------------ */\nlong long score(const Grid& g){\n    static const int dr[4]={-1,1,0,0};\n    static const int dc[4]={0,0,-1,1};\n    bool vis[10][10]={};\n    long long s=0;\n    queue<pair<int,int>> q;\n    for(int r=0;r<10;r++)for(int c=0;c<10;c++){\n        if(g[r][c]==0||vis[r][c]) continue;\n        int col = g[r][c];\n        int sz  = 0;\n        vis[r][c]=true; q.push({r,c});\n        while(!q.empty()){\n            auto [cr,cc]=q.front(); q.pop(); ++sz;\n            for(int k=0;k<4;k++){\n                int nr=cr+dr[k], nc=cc+dc[k];\n                if(nr<0||nr>=10||nc<0||nc>=10) continue;\n                if(!vis[nr][nc] && g[nr][nc]==col){\n                    vis[nr][nc]=true; q.push({nr,nc});\n                }\n            }\n        }\n        s += 1LL*sz*sz;\n    }\n    return s;\n}\n/* ------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int flav[100];\n    for(int i=0;i<100;i++) cin>>flav[i];\n\n    Grid board={};\n\n    const char DIRS[4]={'F','B','L','R'};\n\n    for(int t=0;t<100;t++){\n        int p; cin>>p;\n        auto [r,c]=locate(board,p);\n        board[r][c]=flav[t];\n\n        if(t==99){                       // after putting the 100-th candy the grid is full\n            cout << \"F\\n\" << flush;      // arbitrary, does not change anything\n            break;\n        }\n\n        long long bestScore = -1;\n        char bestDir       = 'F';\n        Grid bestBoard;\n\n        for(char dir:DIRS){\n            Grid tmp;\n            tilt(tmp,board,dir);\n            long long sc = score(tmp);\n            if(sc>bestScore){\n                bestScore = sc;\n                bestDir   = dir;\n                bestBoard = tmp;\n            }\n        }\n        board = bestBoard;\n        cout << bestDir << '\\n' << flush;\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- splitmix64 (fast 64-bit hash) ------------------------------ */\nstatic uint64_t splitmix64(uint64_t x) {\n    x += 0x9e3779b97f4a7c15ULL;\n    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9ULL;\n    x = (x ^ (x >> 27)) * 0x94d049bb133111ebULL;\n    return x ^ (x >> 31);\n}\n\n/* ---------- small fixed bit matrix (max N = 100) ----------------------- */\nstruct Matrix {\n    // each row fits in two 64-bit words (128 bits \u2265 100)\n    array<array<uint64_t,2>,100> row{};\n    int N = 0;\n\n    inline void clear(int n) { N = n; for (int i=0;i<N;i++) row[i][0]=row[i][1]=0; }\n\n    inline void setEdge(int i,int j) {\n        if (j<64) row[i][0] |= 1ULL<<j;\n        else      row[i][1] |= 1ULL<<(j-64);\n    }\n    inline bool edge(int i,int j) const {\n        if (j<64) return row[i][0]>>j & 1ULL;\n        else      return row[i][1]>>(j-64) & 1ULL;\n    }\n    inline int degree(int i) const {             // popcount of the row\n        return __builtin_popcountll(row[i][0]) +\n               __builtin_popcountll(row[i][1]);\n    }\n};\n\n/* ---------- canonicalisation: 3 WL rounds + stable sort --------------- */\nstruct Canon {\n    vector<uint64_t> bits;        // bitset of N(N-1)/2 edges (canonical)\n};\n\nstatic Canon canonicalise(const Matrix& g) {\n    const int N = g.N;\n    vector<uint64_t> col(N);\n    for (int v=0; v<N; v++) col[v] = g.degree(v);    // initial colour\n\n    for (int it=0; it<3; it++) {\n        vector<uint64_t> ncol(N);\n        for (int v=0; v<N; v++) {\n            uint64_t sum = 0, sum2 = 0;\n            for (int u=0; u<N; u++) if (g.edge(v,u)) {\n                sum  += col[u];\n                sum2 += col[u]*col[u];\n            }\n            ncol[v] = splitmix64(col[v] ^ splitmix64(sum) ^ (sum2<<1));\n        }\n        col.swap(ncol);\n    }\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    stable_sort(ord.begin(), ord.end(), [&](int a,int b){\n        if (col[a]!=col[b]) return col[a]<col[b];\n        return a<b;\n    });\n    vector<int> pos(N);\n    for (int i=0;i<N;i++) pos[ ord[i] ] = i;\n\n    // build bitset in the canonical order (lexicographic by (i,j))\n    const size_t TOT = N*(N-1)/2;\n    size_t W = (TOT+63)>>6;\n    vector<uint64_t> bits(W,0ULL);\n    size_t idx = 0;\n    for (int i=0;i<N;i++){\n        int oi = ord[i];\n        for (int j=i+1;j<N;j++){\n            int oj = ord[j];\n            if (g.edge(oi,oj))\n                bits[idx>>6] |= 1ULL<<(idx&63);\n            ++idx;\n        }\n    }\n    return { std::move(bits) };\n}\n\n/* ---------- main ------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M; double eps;\n    if(!(cin>>M>>eps)) return 0;\n\n    /* choose N depending on \u03b5:  40 for small noise, up to 60 for \u03b5=0.4 */\n    int N = 40 + int( round(eps * 50.0) );   // 40 \u2026 60\n    N = max(4, min(100, N));\n\n    const size_t TOT = N*(N-1)/2;\n    /* prepare catalogue ------------------------------------------------- */\n    vector<Canon> catalogue(M);\n    vector<string> outStr(M);\n    Matrix tmp; tmp.clear(N);\n\n    mt19937_64 rng(123456789);           // fixed seed (deterministic)\n    uniform_int_distribution<uint64_t> bit01(0,1);\n\n    for (int k=0; k<M; k++) {\n        tmp.clear(N);\n        string s; s.reserve(TOT);\n        size_t idx = 0;\n        for (int i=0;i<N;i++){\n            for (int j=i+1;j<N;j++){\n                int b = bit01(rng);\n                s.push_back(b?'1':'0');\n                if (b) { tmp.setEdge(i,j); tmp.setEdge(j,i); }\n                ++idx;\n            }\n        }\n        outStr[k]=std::move(s);\n        catalogue[k]=canonicalise(tmp);\n    }\n\n    /* --------------- output graphs ------------------------------------ */\n    cout<<N<<\"\\n\";\n    for (int k=0;k<M;k++) cout<<outStr[k]<<\"\\n\";\n    cout.flush();\n\n    /* --------------- answer 100 queries --------------------------------*/\n    const size_t WORDS = (TOT+63)>>6;\n\n    for (int q=0;q<100;q++){\n        string hStr; cin>>hStr;\n        Matrix H; H.clear(N);\n        size_t idx=0;\n        for(int i=0;i<N;i++){\n            for(int j=i+1;j<N;j++){\n                if(hStr[idx++]=='1'){ H.setEdge(i,j); H.setEdge(j,i); }\n            }\n        }\n        Canon CH = canonicalise(H);\n\n        int best = 0;\n        int bestDist = INT_MAX;\n        for (int k=0;k<M;k++){\n            const auto& B = catalogue[k].bits;\n            int dist = 0;\n            for (size_t w=0; w<WORDS; w++)\n                dist += __builtin_popcountll( CH.bits[w] ^ B[w] );\n            if(dist<bestDist){ bestDist=dist; best=k; }\n        }\n        cout<<best<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int idx;\n    int u, v, w;\n    int priority;           // deg(u)+deg(v)\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- input ---------- */\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n    vector<Edge> edges(M);\n    vector<int> deg(N, 0);\n    for (int i = 0; i < M; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        --u; --v;\n        edges[i] = {i, u, v, w, 0};\n        ++deg[u]; ++deg[v];\n    }\n    /* the coordinates follow \u2013 we ignore them */\n    for (int i = 0; i < N; ++i) {\n        int x, y;  cin >> x >> y;\n    }\n\n    /* ---------- edge priorities ---------- */\n    for (auto& e : edges) e.priority = deg[e.u] + deg[e.v];\n\n    /* sort: important edges first, random tie-breaking */\n    std::mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    std::shuffle(edges.begin(), edges.end(), rng);\n    std::stable_sort(edges.begin(), edges.end(),\n        [](const Edge& a, const Edge& b){ return a.priority > b.priority; });\n\n    /* ---------- greedy assignment ---------- */\n    vector<int> load(D, 0);                          // edges already on day d\n    vector<array<uint8_t, 30>> used(N);              // used[v][d]   (D \u2264 30)\n    /* uint8_t is plenty because per vertex per day we will never exceed K \u2264 600 */\n\n    vector<int> answer(M, 0);                        // 0-based temporarily\n\n    for (const auto& e : edges) {\n        int bestDay = -1;\n        int bestScore = INT_MAX;\n        int bestLoad  = INT_MAX;\n\n        /* evaluate all feasible days */\n        for (int d = 0; d < D; ++d) {\n            if (load[d] >= K) continue;              // full\n\n            int score = used[e.u][d] + used[e.v][d];\n            if (score < bestScore ||\n               (score == bestScore && load[d] < bestLoad)) {\n                bestScore = score;\n                bestLoad  = load[d];\n                bestDay   = d;\n            }\n        }\n\n        /* because K is generous, bestDay must exist */\n        if (bestDay == -1) {                         // very unlikely fallback\n            bestDay = int(min_element(load.begin(), load.end()) - load.begin());\n        }\n\n        answer[e.idx] = bestDay;\n        ++load[bestDay];\n        ++used[e.u][bestDay];\n        ++used[e.v][bestDay];\n    }\n\n    /* ---------- output (1-based) ---------- */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << (answer[i] + 1);\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pillar {\n    vector<int> vox;                 // indices of the voxels (all on the same (x,y) line)\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D;                                                  // --------- read input\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 k = 0; k < 2; ++k) {\n        for (int z = 0; z < D; ++z) cin >> F[k][z];\n        for (int z = 0; z < D; ++z) cin >> R[k][z];\n    }\n\n    const int SZ = D * D * D;\n    auto idx = [D](int x, int y, int z) { return x * D * D + y * D + z; };\n\n    // ------------------------------------------------------------------\n    // 1.  minimal rook construction  -> occ1 / occ2\n    // ------------------------------------------------------------------\n    vector<char> occ1(SZ, 0), occ2(SZ, 0);\n\n    auto build_slice = [&](int obj, int z, vector<char>& occ) {\n        vector<int> X, Y;\n        for (int x = 0; x < D; ++x)\n            if (F[obj][z][x] == '1') X.push_back(x);\n        for (int y = 0; y < D; ++y)\n            if (R[obj][z][y] == '1') Y.push_back(y);\n\n        // possible intersection rows / columns  (we first place as many shared rooks as possible)\n        vector<int> Xi(D, 0), Yi(D, 0);\n        for (int x : X) Xi[x] = 1;\n        for (int y : Y) Yi[y] = 1;\n        vector<int> Xc, Yc;\n        for (int x = 0; x < D; ++x) if (Xi[x] && (obj==0?F[1][z][x]:F[0][z][x])=='1') Xc.push_back(x);\n        for (int y = 0; y < D; ++y) if (Yi[y] && (obj==0?R[1][z][y]:R[0][z][y])=='1') Yc.push_back(y);\n\n        int kshare = min<int>(Xc.size(), Yc.size());\n        vector<char> rowCov(D, 0), colCov(D, 0);\n\n        // 1) shared rooks\n        for (int i = 0; i < kshare; ++i) {\n            int x = Xc[i], y = Yc[i];\n            occ[idx(x,y,z)] = 1;\n            rowCov[x] = colCov[y] = 1;\n        }\n        // 2) cover remaining rows\n        int cy = 0;\n        for (int x : X) if (!rowCov[x]) {\n            int y = Y[cy % Y.size()];\n            occ[idx(x,y,z)] = 1;\n            rowCov[x] = colCov[y] = 1;\n            ++cy;\n        }\n        // 3) cover remaining columns\n        int cx = 0;\n        for (int y : Y) if (!colCov[y]) {\n            int x = X[cx % X.size()];\n            occ[idx(x,y,z)] = 1;\n            rowCov[x] = colCov[y] = 1;\n            ++cx;\n        }\n    };\n\n    for (int z = 0; z < D; ++z) {\n        build_slice(0, z, occ1);\n        build_slice(1, z, occ2);\n    }\n\n    // ------------------------------------------------------------------\n    // 2.  cut every object into vertical pillars\n    // ------------------------------------------------------------------\n    vector<vector<Pillar>> P1(D+1), P2(D+1);        // grouped by length\n\n    auto collect = [&](const vector<char>& occ, vector<vector<Pillar>>& dest) {\n        for (int x=0; x<D; ++x) for (int y=0; y<D; ++y) {\n            int z = 0;\n            while (z < D) {\n                if (occ[idx(x,y,z)]) {\n                    Pillar p;\n                    int z0 = z;\n                    while (z < D && occ[idx(x,y,z)]) p.vox.push_back(idx(x,y,z++));\n                    dest[p.vox.size()].push_back(std::move(p));\n                } else ++z;\n            }\n        }\n    };\n    collect(occ1, P1);\n    collect(occ2, P2);\n\n    // ------------------------------------------------------------------\n    // 3.  pair pillars of equal length  (shared blocks)\n    // ------------------------------------------------------------------\n    vector<int> b1(SZ, 0), b2(SZ, 0);\n    int nextId = 1;\n\n    for (int len = D; len >= 1; --len) {\n        auto &v1 = P1[len], &v2 = P2[len];\n        size_t m = min(v1.size(), v2.size());\n        for (size_t i = 0; i < m; ++i) {\n            int id = nextId++;\n            for (int pos : v1.back().vox) b1[pos] = id;\n            for (int pos : v2.back().vox) b2[pos] = id;\n            v1.pop_back();\n            v2.pop_back();\n        }\n    }\n\n    // ------------------------------------------------------------------\n    // 4.  split remaining (unmatched) pillars into single cubes,\n    //     then pair as many singles as possible\n    // ------------------------------------------------------------------\n    auto harvestSingles = [&](vector<vector<Pillar>>& src, vector<Pillar>& singles) {\n        for (int len = 1; len <= D; ++len) {\n            for (auto &pl : src[len])\n                for (int pos : pl.vox)\n                    singles.emplace_back(Pillar{{pos}});\n            src[len].clear();\n        }\n    };\n    vector<Pillar> S1, S2;\n    harvestSingles(P1, S1);\n    harvestSingles(P2, S2);\n\n    size_t ms = min(S1.size(), S2.size());          // pair singles\n    for (size_t i = 0; i < ms; ++i) {\n        int id = nextId++;\n        b1[S1[i].vox[0]] = id;\n        b2[S2[i].vox[0]] = id;\n    }\n    // leftovers become unique\n    for (size_t i = ms; i < S1.size(); ++i) {\n        int id = nextId++;\n        b1[S1[i].vox[0]] = id;\n    }\n    for (size_t i = ms; i < S2.size(); ++i) {\n        int id = nextId++;\n        b2[S2[i].vox[0]] = id;\n    }\n\n    // ------------------------------------------------------------------\n    // 5.  output\n    // ------------------------------------------------------------------\n    cout << nextId - 1 << '\\n';\n    for (int i = 0; i < SZ; ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n    for (int i = 0; i < SZ; ++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 Neigh {\n    int to, idx;\n};\n\nconstexpr int MAX_R = 5000;\n\nlong long dist_int(int x1, int y1, int x2, int y2) {\n    long long dx = 1LL * x1 - x2;\n    long long dy = 1LL * y1 - y2;\n    return llround(std::ceil(std::sqrt(double(dx * dx + dy * dy))));\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    vector<int> vx(N), vy(N);\n    for (int i = 0; i < N; ++i) cin >> vx[i] >> vy[i];\n\n    vector<Edge> es(M);\n    vector<vector<Neigh>> g(N);\n    for (int i = 0; i < M; ++i) {\n        int a, b; long long w;\n        cin >> a >> b >> w;\n        --a; --b;\n        es[i] = {a, b, w};\n        g[a].push_back({b, i});\n        g[b].push_back({a, i});\n    }\n\n    vector<int> rx(K), ry(K);\n    for (int k = 0; k < K; ++k) cin >> rx[k] >> ry[k];\n\n    /* ---------------- shortest-path tree from root (vertex 0) --------------- */\n    const long long INF = (1LL << 60);\n    vector<long long> dist(N, INF);\n    vector<int> parV(N, -1), parE(N, -1);\n    priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;\n    dist[0] = 0;\n    pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (auto [to, idx] : g[v]) {\n            long long nd = d + es[idx].w;\n            if (nd < dist[to]) {\n                dist[to] = nd;\n                parV[to] = v;\n                parE[to] = idx;\n                pq.push({nd, to});\n            }\n        }\n    }\n\n    /* --------------- pre-compute residents reachable from each vertex ------- */\n    vector<vector<pair<int,int>>> cov(N);          // (resident id , distance<=5000)\n    for (int i = 0; i < N; ++i) {\n        for (int k = 0; k < K; ++k) {\n            int d = (int)dist_int(vx[i], vy[i], rx[k], ry[k]);\n            if (d <= MAX_R) cov[i].push_back({k, d});\n        }\n    }\n\n    /* ------------------------------ greedy ---------------------------------- */\n    vector<char> covered(K, 0);\n    int coveredCnt = 0;\n\n    vector<char> stationChosen(N, 0);\n    vector<int> P(N, 0);\n\n    vector<char> edgeOn(M, 0);\n\n    auto additional_edge_cost = [&](int v)->long long {\n        long long c = 0;\n        while (v != 0) {\n            int e = parE[v];\n            if (!edgeOn[e]) c += es[e].w;\n            v = parV[v];\n        }\n        return c;\n    };\n    auto turn_on_path = [&](int v){\n        while (v != 0) {\n            int e = parE[v];\n            edgeOn[e] = 1;\n            v = parV[v];\n        }\n    };\n\n    while (coveredCnt < K) {\n        int bestV = -1, bestRad = 0, bestGain = 0;\n        double bestScore = -1.0;\n        long long bestAddEdge = 0;\n\n        for (int v = 0; v < N; ++v) if (!stationChosen[v]) {\n            int gain = 0, mx = 0;\n            for (auto [rid, d] : cov[v])\n                if (!covered[rid]) { ++gain; mx = max(mx, d); }\n            if (gain == 0) continue;\n\n            long long eCost = additional_edge_cost(v);\n            long long cost = eCost + 1LL * mx * mx;\n            double sc = double(gain) / double(cost);\n            if (sc > bestScore) {\n                bestScore = sc;\n                bestV = v;\n                bestRad = mx;\n                bestGain = gain;\n                bestAddEdge = eCost;\n            }\n        }\n\n        if (bestV == -1) {                 // should not happen\n            cerr << \"fallback!\\n\";\n            for (int i = 0; i < N; ++i) { stationChosen[i] = 1; P[i] = 5000; }\n            fill(edgeOn.begin(), edgeOn.end(), 1);\n            break;\n        }\n\n        /* apply */\n        stationChosen[bestV] = 1;\n        P[bestV] = bestRad;\n        for (auto [rid, d] : cov[bestV])\n            if (!covered[rid] && d <= bestRad) { covered[rid] = 1; ++coveredCnt; }\n        turn_on_path(bestV);\n    }\n\n    /* ---------------- shrink radii: assign each resident to nearest --------- */\n    vector<int> chosenList;\n    for (int v = 0; v < N; ++v) if (stationChosen[v]) chosenList.push_back(v);\n\n    vector<int> bestRad(N, 0);\n    for (int k = 0; k < K; ++k) {\n        int bestV = -1, bestD = MAX_R + 1;\n        for (int v : chosenList) {\n            int d = (int)dist_int(vx[v], vy[v], rx[k], ry[k]);\n            if (d < bestD) { bestD = d; bestV = v; }\n        }\n        bestRad[bestV] = max(bestRad[bestV], bestD);\n    }\n    for (int v = 0; v < N; ++v) if (stationChosen[v]) P[v] = bestRad[v];\n\n    /* --------------- final edge set (union of paths to chosen) -------------- */\n    fill(edgeOn.begin(), edgeOn.end(), 0);\n    for (int v = 0; v < N; ++v) if (stationChosen[v]) {\n        int cur = v;\n        while (cur != 0) {\n            int e = parE[cur];\n            edgeOn[e] = 1;\n            cur = parV[cur];\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    for (int e = 0; e < M; ++e) {\n        if (e) cout << ' ';\n        cout << int(edgeOn[e]);\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    /* read input */\n    vector<vector<int>> a(N);\n    for (int x = 0; x < N; ++x) {\n        a[x].resize(x + 1);\n        for (int y = 0; y <= x; ++y) cin >> a[x][y];\n    }\n\n    vector<Swap> ops;\n    ops.reserve(5000);          // worst-case 4 495\n\n    auto do_swap = [&](int x1, int y1, int x2, int y2) {\n        swap(a[x1][y1], a[x2][y2]);\n        ops.push_back({x1, y1, x2, y2});\n    };\n\n    /* bottom-up heapify (Floyd) */\n    for (int x = N - 2; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int cx = x, cy = y;\n            while (cx < N - 1) {\n                int lx = cx + 1, ly = cy;       // left child\n                int rx = cx + 1, ry = cy + 1;   // right child\n\n                int minx = lx, miny = ly;\n                if (a[rx][ry] < a[lx][ly]) {\n                    minx = rx;\n                    miny = ry;\n                }\n                if (a[cx][cy] <= a[minx][miny]) break;\n\n                do_swap(cx, cy, minx, miny);\n                cx = minx;\n                cy = miny;\n            }\n        }\n    }\n\n    /* safeguard \u2013 in the very unlikely event we overshoot */\n    if (ops.size() > 10000) ops.resize(10000);\n\n    /* output */\n    cout << ops.size() << '\\n';\n    for (auto &s: ops)\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos{int r,c;};\nconst int DR[4]={-1,1,0,0};\nconst int DC[4]={0,0,-1,1};\nusing Grid = vector<vector<int>>;      // -2 obstacle, -1 empty, >=0 container id\n\nint D=9;                 // fixed\nint ENTR_C;              // (D-1)/2 = 4\nint K;                   // number of containers  = D*D-1-N\n\n// convenience\nbool inside(int r,int c){ return 0<=r && r<D && 0<=c && c<D; }\n\n/* BFS over current empty squares; returns list of reachable empties\n   and fills dist with distances (dist[e_r][e_c]=0).               */\nvector<Pos> bfs_empty(const Grid& g,const Pos& ent,vector<vector<int>>& dist){\n    dist.assign(D, vector<int>(D,-1));\n    vector<Pos> empties;\n    queue<Pos> q;\n    q.push(ent);\n    dist[ent.r][ent.c]=0;\n\n    while(!q.empty()){\n        auto [r,c]=q.front(); q.pop();\n        empties.push_back({r,c});\n        for(int dir=0;dir<4;++dir){\n            int nr=r+DR[dir], nc=c+DC[dir];\n            if(!inside(nr,nc)) continue;\n            if(g[nr][nc]==-1 && dist[nr][nc]==-1){\n                dist[nr][nc]=dist[r][c]+1;\n                q.push({nr,nc});\n            }\n        }\n    }\n    return empties;\n}\n\n/* true\u21d4 container at (r,c) has at least one adjacent empty cell that is\n   already reachable (dist>=0)                                            */\ninline bool container_reachable(const Grid& g,int r,int c,const vector<vector<int>>& dist){\n    for(int dir=0;dir<4;++dir){\n        int nr=r+DR[dir], nc=c+DC[dir];\n        if(inside(nr,nc) && dist[nr][nc]>=0) return true;\n    }\n    return false;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;                         // number of obstacles\n    cin>>D>>N;\n    ENTR_C=(D-1)/2;\n    Pos ENTR{0,ENTR_C};\n\n    Grid g(D, vector<int>(D,-1));  // empty\n    for(int k=0;k<N;++k){\n        int r,c; cin>>r>>c;\n        g[r][c]=-2;                // obstacle\n    }\n    K=D*D-1-N;\n\n    /* pre\u2013compute static BFS distance ignoring containers */\n    vector<vector<int>> dist0(D, vector<int>(D,-1));\n    {\n        queue<Pos> q;\n        q.push(ENTR);\n        dist0[ENTR.r][ENTR.c]=0;\n        while(!q.empty()){\n            auto [r,c]=q.front(); q.pop();\n            for(int d=0;d<4;++d){\n                int nr=r+DR[d], nc=c+DC[d];\n                if(!inside(nr,nc)) continue;\n                if(g[nr][nc]!=-2 && dist0[nr][nc]==-1){\n                    dist0[nr][nc]=dist0[r][c]+1;\n                    q.push({nr,nc});\n                }\n            }\n        }\n    }\n\n    /* vector of all non-forbidden squares, sorted by dist0 inc */\n    vector<Pos> all_cells;\n    for(int r=0;r<D;++r)for(int c=0;c<D;++c){\n        if(r==ENTR.r && c==ENTR.c) continue;\n        if(g[r][c]==-2) continue;\n        all_cells.push_back({r,c});\n    }\n    sort(all_cells.begin(), all_cells.end(), [&](const Pos& a,const Pos& b){\n        int da=dist0[a.r][a.c], db=dist0[b.r][b.c];\n        if(da!=db) return da<db;\n        return tie(a.r,a.c)<tie(b.r,b.c);\n    });\n    vector<vector<int>> rankCell(D, vector<int>(D,-1));\n    for(size_t i=0;i<all_cells.size();++i){\n        rankCell[all_cells[i].r][all_cells[i].c]=static_cast<int>(i);\n    }\n\n    vector<Pos> idPos(K);          // final positions of every id\n    vector<vector<int>> distTmp;   // reused buffer\n\n    /* ========= online placement phase ========= */\n    for(int step=0; step<K; ++step){\n        int id; cin>>id;\n        /* reachable empty cells right now */\n        auto reachable = bfs_empty(g,ENTR,distTmp);\n\n        /* sort reachable by static distance */\n        sort(reachable.begin(), reachable.end(),\n             [&](const Pos& a,const Pos& b){ return dist0[a.r][a.c] < dist0[b.r][b.c]; });\n\n        int chooseIdx;\n        if(reachable.size()==1){\n            chooseIdx=0;\n        }else{\n            double ratio= static_cast<double>(id)/(K-1); // 0..1\n            chooseIdx = static_cast<int>( round( ratio * (int(reachable.size())-1) ) );\n        }\n        Pos chosen = reachable[chooseIdx];\n\n        /* store */\n        g[chosen.r][chosen.c] = id;\n        idPos[id]=chosen;\n\n        cout<<chosen.r<<\" \"<<chosen.c<<\"\\n\"<<flush;\n    }\n\n    /* ========= retrieving phase ========= */\n    vector<char> shipped(K,0);\n    vector<Pos> answer;\n    answer.reserve(K);\n\n    int nextNeed=0;\n\n    while((int)answer.size()<K){\n        /* current reachable empty & dist */\n        auto empties = bfs_empty(g,ENTR,distTmp);\n\n        /* list of reachable containers with their min distance */\n        int best_for_need = -1;           // position index in answer vector\n        int best_other_id = -1;\n        int best_other_dist = 1e9;\n        Pos best_other_pos{-1,-1};\n\n        for(int id=0; id<K; ++id){\n            if(shipped[id]) continue;\n            auto [r,c]=idPos[id];\n            if(container_reachable(g,r,c,distTmp)){\n                if(id==nextNeed){\n                    best_for_need = id;\n                    break;               // perfect, take it\n                }else{\n                    int mind=1e9;\n                    for(int d=0;d<4;++d){\n                        int nr=r+DR[d], nc=c+DC[d];\n                        if(inside(nr,nc) && distTmp[nr][nc]>=0)\n                            mind = min(mind, distTmp[nr][nc]+1);\n                    }\n                    if(mind<best_other_dist || (mind==best_other_dist && id<best_other_id)){\n                        best_other_dist=mind;\n                        best_other_id=id;\n                        best_other_pos={r,c};\n                    }\n                }\n            }\n        }\n\n        int take_id;\n        Pos take_pos;\n        if(best_for_need!=-1){\n            take_id=best_for_need;\n            take_pos=idPos[take_id];\n        }else{\n            take_id=best_other_id;\n            take_pos=best_other_pos;\n        }\n\n        /* ship it */\n        shipped[take_id]=1;\n        g[take_pos.r][take_pos.c]=-1;         // becomes empty\n        answer.push_back(take_pos);\n\n        if(take_id==nextNeed){\n            while(nextNeed<K && shipped[nextNeed]) ++nextNeed;\n        }\n    }\n\n    /* ========= output retrieving order ========= */\n    for(auto &p:answer){\n        cout<<p.r<<\" \"<<p.c<<\"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 50;     // fixed\nconstexpr int M = 100;\nconst int DX[4] = {-1, 1, 0, 0};\nconst int DY[4] = {0, 0, -1, 1};\n\nstruct State {\n    int  g[N][N];                 // current grid\n    int  cnt[M + 1]{};            // remaining cells per colour\n    int  adj[M + 1][M + 1]{};     // unordered edge counts, 0-based\n    bool orig0Adj[M + 1]{};       // was (0,c) adjacent in the input?\n    bool inQ[N][N]{};             // helper for the flood queue\n} st;\n\n/* --------------------------------------------------------------- */\ninline bool inside(int x, int y) { return 0 <= x && x < N && 0 <= y && y < N; }\n\ninline void addEdge(int a, int b, int delta) {\n    if (a > b) swap(a, b);\n    st.adj[a][b] += delta;\n#ifdef DEBUG\n    if (st.adj[a][b] < 0) cerr << \"negative edge \" << a << ' ' << b << '\\n';\n#endif\n}\n\n/* ------------ input & initial edge counters -------------------- */\nvoid buildInitial() {\n    int n, m;  cin >> n >> m;           // 50 / 100\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            cin >> st.g[i][j];\n            ++st.cnt[ st.g[i][j] ];\n        }\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int c = st.g[i][j];\n            int d = (j + 1 < N) ? st.g[i][j + 1] : 0;\n            if (c != d) addEdge(c, d, +1);\n            d = (i + 1 < N) ? st.g[i + 1][j] : 0;\n            if (c != d) addEdge(c, d, +1);\n        }\n\n    for (int c = 1; c <= M; ++c) st.orig0Adj[c] = st.adj[0][c] > 0;\n}\n\n/* ---------------- connectivity of one colour ------------------- */\nbool connectedAfterRemoval(int x, int y, int col) {\n    bool vis[N][N] = {};\n    queue<pair<int,int>> q;\n    for (int i = 0; i < N && q.empty(); ++i)\n        for (int j = 0; j < N; ++j)\n            if (st.g[i][j] == col && !(i == x && j == y)) {\n                q.emplace(i, j); vis[i][j] = true;\n                break;\n            }\n\n    int need = st.cnt[col] - 1, got = 0;\n    while (!q.empty()) {\n        auto [cx, cy] = q.front(); q.pop();\n        if (++got == need) return true;\n        for (int d = 0; d < 4; ++d) {\n            int nx = cx + DX[d], ny = cy + DY[d];\n            if (!inside(nx, ny) || vis[nx][ny] || (nx == x && ny == y)) continue;\n            if (st.g[nx][ny] == col) { vis[nx][ny] = true; q.emplace(nx, ny); }\n        }\n    }\n    return false;\n}\n\n/* ---------------- attempt to turn (x,y) into 0 ------------------ */\nbool tryRemove(int x, int y) {\n    int c = st.g[x][y];\n    if (c == 0 || st.cnt[c] == 1) return false;\n\n    int freq[M + 1] = {};               // how many sides to each neighbour colour\n    for (int d = 0; d < 4; ++d) {\n        int nx = x + DX[d], ny = y + DY[d];\n        int col = inside(nx, ny) ? st.g[nx][ny] : 0;\n        ++freq[col];\n    }\n\n    /* --- cheap legality tests ----------------------------------- */\n    for (int d = 1; d <= M; ++d) {\n        if (d == c || freq[d] == 0) continue;\n\n        if (!st.orig0Adj[d]) return false;                      // new 0-d edge forbidden\n\n        int a = min(c, d), b = max(c, d);\n        if (st.adj[a][b] - freq[d] <= 0) return false;         // last (c,d) edge gone\n    }\n    if (!connectedAfterRemoval(x, y, c)) return false;\n\n    /* --- update edge counters ----------------------------------- */\n    int f0   = freq[0];\n    int fSame= freq[c];\n\n    if (f0   ) addEdge(0, c, -f0);        // c \u2013 0 edges disappear\n    if (fSame) addEdge(0, c, +fSame);     // new 0 \u2013 c edges where neighbour is c\n\n    for (int d = 1; d <= M; ++d) if (d != c && freq[d]) {\n        addEdge(c, d, -freq[d]);          // erase (c,d)\n        addEdge(0, d, +freq[d]);          // add (0,d)\n    }\n\n    /* --- materialise the deletion ------------------------------- */\n    st.g[x][y] = 0;\n    --st.cnt[c];\n    return true;\n}\n\n/* ---------------- flood-queue driver ---------------------------- */\ninline bool touchesZero(int i, int j) {\n    if (st.g[i][j] == 0) return false;\n    for (int d = 0; d < 4; ++d) {\n        int ni = i + DX[d], nj = j + DY[d];\n        if (!inside(ni, nj) || st.g[ni][nj] == 0) return true;\n    }\n    return false;\n}\n\nvoid flood() {\n    queue<pair<int,int>> q;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (touchesZero(i, j)) { q.emplace(i, j); st.inQ[i][j] = true; }\n\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        st.inQ[x][y] = false;\n        if (st.g[x][y] == 0 || !touchesZero(x, y)) continue;\n\n        if (tryRemove(x, y)) {\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + DX[d], ny = y + DY[d];\n                if (!inside(nx, ny) || st.g[nx][ny] == 0 || st.inQ[nx][ny]) continue;\n                if (touchesZero(nx, ny)) { q.emplace(nx, ny); st.inQ[nx][ny] = true; }\n            }\n        }\n    }\n}\n\n/* ---------------- main ------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    buildInitial();\n    flood();\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (j) cout << ' ';\n            cout << st.g[i][j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- small utilities ---------- */\nstruct FastRNG {\n    uint64_t x;\n    FastRNG() : x(chrono::steady_clock::now().time_since_epoch().count()) {}\n    uint32_t next() { x ^= x << 7; return (uint32_t)(x ^= x >> 9); }\n    template<class It> void shuffle(It first, It last){\n        for(auto i = (last-first); i>1; --i){\n            int j = next()%i;\n            swap(*(first+i-1), *(first+j));\n        }\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------------- read first line ---------------- */\n    int N,D,Q;\n    if(!(cin>>N>>D>>Q)) return 0;\n\n    /* ---------------- Bradley\u2013Terry / Elo ----------------\n       rating r_i  (real numbers)\n       P(i beats j) = 1 / (1+exp(-(r_i-r_j)))\n       update with learning-rate K   r += K*(S - P)\n    ------------------------------------------------------ */\n    const double K = 1.6;              // slightly aggressive\n    vector<double> rating(N, 0.0);\n\n    /* ---------------- schedule comparisons ------------- */\n    vector<pair<int,int>> pairs;\n    pairs.reserve(N*(N-1)/2);\n    for(int i=0;i<N;++i) for(int j=i+1;j<N;++j) pairs.emplace_back(i,j);\n\n    FastRNG rng;\n    rng.shuffle(pairs.begin(), pairs.end());\n\n    /* ---------------- perform informative queries ------ */\n    int used = 0, idx = 0;\n    auto ask = [&](int a,int b){\n        cout << 1 << ' ' << 1 << ' ' << a << ' ' << b << '\\n' << flush;\n        string res; cin >> res;\n        ++used;\n        if(res==\">\"||res==\"<\"){                // ignore '=' (practically never happens)\n            bool aWins = (res==\">\");\n            double ra = rating[a], rb = rating[b];\n            double p  = 1.0 / (1.0 + exp(rb - ra));\n            double diff = K * ((aWins?1.0:0.0) - p);\n            rating[a] += diff;\n            rating[b] -= diff;\n        }\n    };\n\n    while(used < Q && idx < (int)pairs.size()){\n        auto [a,b] = pairs[idx++];\n        ask(a,b);\n    }\n    /* -------------- consume possible leftover queries -- */\n    while(used < Q){ ask(0,1); }        // ignored but fulfils protocol\n\n    /* ---------------- derive positive weights ---------- */\n    double mn = *min_element(rating.begin(), rating.end());\n    vector<double> w(N);\n    for(int i=0;i<N;++i) w[i] = rating[i]-mn + 1e-3;   // >0\n\n    /* ---------------- initial greedy LPT --------------- */\n    struct Bag{ double sum=0; vector<int> items; };\n    vector<Bag> bag(D);\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a,int b){ return w[a]>w[b]; });\n\n    vector<int> belong(N);\n    for(int id:ord){\n        int best=0;\n        for(int d=1;d<D;++d)\n            if(bag[d].sum < bag[best].sum) best=d;\n        bag[best].items.push_back(id);\n        bag[best].sum += w[id];\n        belong[id]=best;\n    }\n\n    /* --------------- local improvement -----------------\n       objective  f = \u03a3  sum_d^2   (mean is fixed)         */\n    auto obj = [&](){ double v=0; for(auto &b:bag) v+=b.sum*b.sum; return v; };\n    double bestScore = obj();\n    bool improved=true; int iter=0;\n    while(improved && ++iter<4000){             // safeguard iterations\n        improved=false;\n        /* --- single moves --- */\n        for(int i=0;i<N;++i){\n            int a = belong[i];\n            double wa = w[i], sa = bag[a].sum;\n            double base = bestScore - sa*sa;\n            for(int b=0;b<D;++b) if(b!=a){\n                double sb = bag[b].sum;\n                double newScore = base - sb*sb\n                                   + (sa-wa)*(sa-wa) + (sb+wa)*(sb+wa);\n                if(newScore + 1e-9 < bestScore){\n                    /* apply */\n                    bag[a].sum -= wa;\n                    bag[b].sum += wa;\n                    belong[i]=b; improved=true;\n                    bestScore=newScore;\n                    goto next_iter;\n                }\n            }\n        }\n        /* --- pair swaps --- */\n        for(int i=0;i<N;++i) for(int j=i+1;j<N;++j)\n            if(belong[i]!=belong[j]){\n                int a=belong[i], b=belong[j];\n                double wi=w[i], wj=w[j];\n                double sa=bag[a].sum, sb=bag[b].sum;\n\n                double base = bestScore - sa*sa - sb*sb;\n                double newSa = sa - wi + wj;\n                double newSb = sb - wj + wi;\n                double newScore = base + newSa*newSa + newSb*newSb;\n                if(newScore + 1e-9 < bestScore){\n                    swap(belong[i], belong[j]);\n                    bag[a].sum = newSa;\n                    bag[b].sum = newSb;\n                    improved=true; bestScore=newScore;\n                    goto next_iter;\n                }\n            }\n        next_iter:;\n    }\n\n    /* -------------------- output division -------------- */\n    for(int i=0;i<N;++i){\n        if(i) cout << ' ';\n        cout << belong[i];\n    }\n    cout << '\\n' << flush;\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    if (!(cin >> n >> m)) return 0;\n    const int H = n / m;\n\n    vector<vector<int>> st(m);          // bottom -> top\n    for (int i = 0; i < m; ++i) {\n        st[i].resize(H);\n        for (int j = 0; j < H; ++j) cin >> st[i][j];\n    }\n\n    vector<pair<int,int>> ops;          // (v, i)   i==0 => carry out\n\n    for (int v = 1; v <= n; ++v) {\n        int s = -1, idx = -1;\n        // locate v\n        for (int i = 0; i < m && s == -1; ++i)\n            for (int j = 0; j < (int)st[i].size(); ++j)\n                if (st[i][j] == v) { s = i; idx = j; break; }\n\n        if (idx == (int)st[s].size() - 1) {   // already on top\n            st[s].pop_back();\n            ops.emplace_back(v, 0);\n            continue;\n        }\n\n        // segment to move: idx+1 .. end\n        vector<int> seg(st[s].begin() + idx + 1, st[s].end());\n        st[s].resize(idx + 1);                // keep the lower part (incl. v)\n\n        int maxSeg = *max_element(seg.begin(), seg.end());\n        int dest = -1;\n\n        // ---- choose destination ------------------------------------------\n        // 1) empty stack\n        for (int i = 0; i < m; ++i)\n            if (i != s && st[i].empty()) { dest = i; break; }\n\n        // 2) stack with minimal future conflicts\n        if (dest == -1) {\n            int bestCross = INT_MAX, bestHeight = INT_MAX;\n            for (int i = 0; i < m; ++i) if (i != s) {\n                int cross = 0;\n                for (int x : st[i]) if (x < maxSeg) ++cross;\n                if (cross < bestCross ||\n                   (cross == bestCross && (int)st[i].size() < bestHeight)) {\n                    bestCross  = cross;\n                    bestHeight = (int)st[i].size();\n                    dest = i;\n                }\n            }\n        }\n        // -------------------------------------------------------------------\n\n        // do the move (note: seg keeps original order)\n        st[dest].insert(st[dest].end(), seg.begin(), seg.end());\n        ops.emplace_back(seg.front(), dest + 1);   // stacks are 1-based\n\n        // now v is on top of its stack\n        st[s].pop_back();\n        ops.emplace_back(v, 0);\n    }\n\n    for (auto [v, i] : ops) cout << v << ' ' << i << '\\n';\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** constants and helpers ***************************************************/\nconst int DX[4] = {0, 1, 0, -1};\nconst int DY[4] = {1, 0, -1, 0};\nconst char DC[4] = {'R', 'D', 'L', 'U'};\n\nstruct Board {\n    int N;\n    vector<string> h;          // wall to down : size N-1, length N\n    vector<string> v;          // wall to right: size N  , length N-1\n    vector<int>     d;         // susceptibility flattened\n    inline bool inside(int x,int y) const { return 0<=x && x<N && 0<=y && y<N; }\n    inline bool canMove(int x,int y,int dir) const {\n        if(dir==0) return y+1<N && v[x][y]=='0';\n        if(dir==1) return x+1<N && h[x][y]=='0';\n        if(dir==2) return y-1>=0 && v[x][y-1]=='0';\n        return            x-1>=0 && h[x-1][y]=='0';\n    }\n} B;\n\n/*** data for optimisation ***************************************************/\nint N, LIM = 100000;\n\nvector<int> bounceDir;         // favourite neighbour of each cell\nvector<int> bounceTo;          // its index\nvector<int> loopsNeeded;       // how many extra loops finally allocated\n\nstring basePath;               // Euler tour without extra loops\nstring answer;                 // final route\n\n/*** building the Euler tour *************************************************/\nvector<vector<int>> visited;\nvoid dfsEuler(int x,int y)\n{\n    visited[x][y]=1;\n    for(int dir=0;dir<4;dir++){\n        int nx=x+DX[dir], ny=y+DY[dir];\n        if(!B.inside(nx,ny) || visited[nx][ny]) continue;\n        if(!B.canMove(x,y,dir)) continue;\n        basePath.push_back(DC[dir]);\n        dfsEuler(nx,ny);\n        basePath.push_back(DC[(dir+2)%4]);\n    }\n}\n\n/*** simulate any given path to count visits *********************************/\nvector<int> countVisits(const string& p)\n{\n    vector<int> v(N*N,0);\n    int x=0,y=0;\n    for(char c:p){\n        int dir = (c=='R'?0:c=='D'?1:c=='L'?2:3);\n        x += DX[dir]; y += DY[dir];\n        v[x*N+y]++;\n    }\n    return v;\n}\n\n/*** choose bounce neighbour (highest d) *************************************/\nvoid prepareBounce()\n{\n    bounceDir.assign(N*N,0);\n    bounceTo .assign(N*N,0);\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++){\n        int bestDir=-1, bestD=-1;\n        for(int dir=0;dir<4;dir++){\n            if(!B.canMove(x,y,dir)) continue;\n            int nx=x+DX[dir], ny=y+DY[dir];\n            int nd = B.d[nx*N+ny];\n            if(nd>bestD){ bestD=nd; bestDir=dir; }\n        }\n        bounceDir[x*N+y]=bestDir;\n        bounceTo [x*N+y]=(x+DX[bestDir])*N + (y+DY[bestDir]);\n    }\n}\n\n/*** greedy allocation of useful loops ***************************************/\nvoid allocateLoops(vector<int>& visit)\n{\n    loopsNeeded.assign(N*N,0);\n    long long L = (long long)basePath.size();             // current length\n    double R = 0;                                         // \u03a3 d / v\n    for(int i=0;i<N*N;i++) R += (double)B.d[i] / visit[i];\n\n    using Node = pair<double,int>;                        // (benefit, id)\n    priority_queue<Node> pq;\n    for(int i=0;i<N*N;i++){\n        int j=bounceTo[i];\n        double benefit = (double)B.d[i]/(visit[i]*(visit[i]+1))\n                       + (double)B.d[j]/(visit[j]*(visit[j]+1));\n        pq.emplace(benefit,i);\n    }\n\n    while(L+2 <= LIM){\n        double threshold = 2.0 * R / (L+2);               // need benefit > thresh\n        auto [benefit,id] = pq.top(); pq.pop();\n        int i=id, j=bounceTo[i];\n        // recompute real current benefit\n        benefit = (double)B.d[i]/(visit[i]*(visit[i]+1))\n                + (double)B.d[j]/(visit[j]*(visit[j]+1));\n        if(benefit < threshold - 1e-12){                  // no further improvement\n            break;\n        }\n        /* perform the loop */\n        loopsNeeded[i]++;  L += 2;\n        R -= (double)B.d[i]/visit[i] - (double)B.d[i]/(visit[i]+1);\n        R -= (double)B.d[j]/visit[j] - (double)B.d[j]/(visit[j]+1);\n        visit[i]++;  visit[j]++;\n\n        /* push updated entries (lazy) */\n        double newBenefitI = (double)B.d[i]/(visit[i]*(visit[i]+1))\n                           + (double)B.d[j]/(visit[j]*(visit[j]+1));\n        pq.emplace(newBenefitI,i);\n        double newBenefitJ = (double)B.d[j]/(visit[j]*(visit[j]+1))\n                           + (double)B.d[bounceTo[j]]/(visit[bounceTo[j]]*(visit[bounceTo[j]]+1));\n        pq.emplace(newBenefitJ,j);\n    }\n}\n\n/*** produce the final route **************************************************/\nvector<int> loopsRemain;\nstring outPath;\nint curX=0,curY=0;\n\nvoid emitMove(int dir)\n{\n    outPath.push_back(DC[dir]);\n    curX += DX[dir]; curY += DY[dir];\n}\n\nvoid emitBounce(int id)            // perform ONE back-and-forth loop\n{\n    int dir = bounceDir[id];\n    emitMove(dir);\n    emitMove((dir+2)%4);\n}\n\nvoid maybeBounce(int id)           // at most one loop here\n{\n    if(loopsRemain[id]>0){\n        loopsRemain[id]--;\n        emitBounce(id);\n    }\n}\n\nvector<vector<int>> vis2;\nvoid dfsFinal(int x,int y)\n{\n    int id = x*N+y;\n    vis2[x][y]=1;\n    maybeBounce(id);\n    for(int dir=0;dir<4;dir++){\n        int nx=x+DX[dir], ny=y+DY[dir];\n        if(!B.inside(nx,ny) || vis2[nx][ny]) continue;\n        if(!B.canMove(x,y,dir)) continue;\n        emitMove(dir);\n        dfsFinal(nx,ny);\n        emitMove((dir+2)%4);\n        maybeBounce(id);\n    }\n    while(loopsRemain[id]>0) {     // finish leftovers, very small number\n        loopsRemain[id]--;\n        emitBounce(id);\n    }\n}\n\n/*** main ********************************************************************/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* input */\n    cin>>N;  B.N=N;\n    B.h.resize(N-1); for(int i=0;i<N-1;i++) cin>>B.h[i];\n    B.v.resize(N);   for(int i=0;i<N;i++)   cin>>B.v[i];\n    B.d.resize(N*N);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) cin>>B.d[i*N+j];\n\n    /* step 1: base Euler tour */\n    visited.assign(N,vector<int>(N,0));\n    dfsEuler(0,0);\n\n    /* step 2: initial visits & bounce neighbour */\n    vector<int> visit = countVisits(basePath);        // size N*N\n    prepareBounce();\n\n    /* step 3: greedy extra loops only while useful */\n    allocateLoops(visit);\n\n    /* step 4: build the final route */\n    loopsRemain = loopsNeeded;\n    vis2.assign(N,vector<int>(N,0));\n    dfsFinal(0,0);\n\n    /* output */\n    cout << outPath << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int r, c; };\ninline int manhattan(const Pos& a, const Pos& b) {\n    return abs(a.r - b.r) + abs(a.c - b.c);\n}\n\n/* -------------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* --- input -------------------------------------------------------- */\n    int N, M;                   // N = 15, M = 200\n    cin >> N >> M;\n    int si, sj;  cin >> si >> sj;\n\n    vector<string> board(N);\n    for (int i = 0; i < N; ++i) cin >> board[i];\n\n    vector<string> word(M);\n    for (int i = 0; i < M; ++i) cin >> word[i];\n\n    /* --- letter locations / helper distances ------------------------- */\n    array<vector<Pos>, 26> where;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            where[board[i][j] - 'A'].push_back({i, j});\n\n    constexpr int INF = 1e9;\n    int charDist[26][26];\n    for (int a = 0; a < 26; ++a)\n        for (int b = 0; b < 26; ++b) {\n            int best = INF;\n            for (const auto &p : where[a])\n                for (const auto &q : where[b])\n                    best = min(best, manhattan(p, q));\n            charDist[a][b] = best;\n        }\n\n    int distStart[26];\n    for (int a = 0; a < 26; ++a) {\n        int best = INF;\n        for (const auto &p : where[a])\n            best = min(best, abs(p.r - si) + abs(p.c - sj));\n        distStart[a] = best;\n    }\n\n    /* --- first / last letters of every word -------------------------- */\n    array<int, 200> first{}, last{};\n    for (int i = 0; i < M; ++i) {\n        first[i] = word[i][0] - 'A';\n        last [i] = word[i][4] - 'A';\n    }\n\n    /* --- step 2-a  : greedy tour ------------------------------------- */\n    vector<int> order; order.reserve(M);\n    vector<char> used(M, 0);\n\n    int best0 = 0, bestD = INF;\n    for (int i = 0; i < M; ++i) {\n        if (distStart[first[i]] < bestD) {\n            bestD = distStart[first[i]];\n            best0 = i;\n        }\n    }\n    order.push_back(best0);  used[best0] = 1;\n\n    for (int iter = 1; iter < M; ++iter) {\n        int prev = order.back();\n        int best = -1, bestCost = INF;\n        for (int i = 0; i < M; ++i) if (!used[i]) {\n            int c = charDist[last[prev]][first[i]];\n            if (c < bestCost) { bestCost = c; best = i; }\n        }\n        order.push_back(best);\n        used[best] = 1;\n    }\n\n    /* --- step 2-b  : lightweight 2-opt ------------------------------- */\n    auto tourCost = [&](const vector<int>& ord)->int{\n        int cost = distStart[first[ord[0]]];\n        for (int i = 1; i < M; ++i)\n            cost += charDist[last[ord[i-1]]][first[ord[i]]];\n        return cost;\n    };\n    int curCost = tourCost(order);\n\n    std::mt19937 rng(1234567);\n    const int OPT_ITERS = 40000;\n    for (int it = 0; it < OPT_ITERS; ++it) {\n        int i = std::uniform_int_distribution<int>(1, M-2)(rng);\n        int j = std::uniform_int_distribution<int>(i+1, M-1)(rng);\n\n        int a  = order[i-1],   b  = order[i];\n        int c  = order[j-1],   d  = order[j];\n\n        int old = charDist[last[a]][first[b]]\n                + charDist[last[c]][first[d]];\n        int neu = charDist[last[a]][first[d]]\n                + charDist[last[b]][first[d==order.back()?0:order[j+1]]]; // simplify\n        // quick, conservative delta: only accept if surely better\n        if (neu < old) {\n            reverse(order.begin()+i, order.begin()+j+1);\n            curCost -= (old - neu);\n        }\n    }\n\n    /* --- step 3  : build the final string with overlaps -------------- */\n    string S = word[order[0]];\n    for (int idx = 1; idx < M; ++idx) {\n        const string &w = word[order[idx]];\n        int overlap = 0;\n        int lim = min<int>(4, S.size());\n        for (int l = lim; l >= 1; --l) {\n            bool ok = true;\n            for (int k = 0; k < l; ++k)\n                if (S[S.size()-l+k] != w[k]) { ok = false; break; }\n            if (ok) { overlap = l; break; }\n        }\n        S += w.substr(overlap);\n    }\n    const int L = (int)S.size();\n\n    /* --- step 4  : exact DP \u2013 identical to the first submission ------ */\n    vector<vector<int>>        dp(L);\n    vector<vector<uint16_t>>  prv(L);\n    vector<int>               bestIdx(L, -1);\n\n    /* layer 0 */\n    {\n        int ch = S[0] - 'A';\n        int sz = where[ch].size();\n        dp[0].assign(sz, INF);\n        prv[0].assign(sz, 0);\n        for (int k = 0; k < sz; ++k)\n            dp[0][k] = manhattan({si, sj}, where[ch][k]) + 1;\n        bestIdx[0] = min_element(dp[0].begin(), dp[0].end()) - dp[0].begin();\n    }\n    /* other layers */\n    for (int i = 1; i < L; ++i) {\n        int cur = S[i]   - 'A';\n        int pre = S[i-1] - 'A';\n        int szC = where[cur].size();\n        int szP = where[pre].size();\n        dp[i].assign(szC, INF);\n        prv[i].assign(szC, 0);\n        for (int k = 0; k < szC; ++k) {\n            const Pos &to = where[cur][k];\n            int best = INF, bestp = 0;\n            for (int j = 0; j < szP; ++j) {\n                int cand = dp[i-1][j] + manhattan(where[pre][j], to) + 1;\n                if (cand < best) { best = cand; bestp = j; }\n            }\n            dp[i][k]  = best;\n            prv[i][k] = bestp;\n        }\n        bestIdx[i] = min_element(dp[i].begin(), dp[i].end()) - dp[i].begin();\n    }\n\n    /* back-track */\n    vector<Pos> path(L);\n    int idx = bestIdx.back();\n    for (int i = L-1; i >= 0; --i) {\n        int ch = S[i] - 'A';\n        path[i] = where[ch][idx];\n        if (i) idx = prv[i][idx];\n    }\n\n    /* output ---------------------------------------------------------- */\n    for (auto &p : path) cout << p.r << ' ' << p.c << '\\n';\n    return 0;\n}","ahc030":"//  AHC030 \u2013 simple heuristic that eliminates impossible placements\n//  compile: g++ -std=c++20 -O2 -pipe -static -s main.cpp\n//---------------------------------------------------------------\n#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastIO {\n    FastIO() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }\n} fio;\n\n//---------------------------------------------------------------\n// data structures\n//---------------------------------------------------------------\nstruct Placement {\n    vector<int> cells;                // indices (i*N+j) of covered squares\n};\n\nstruct Field {\n    vector<Placement> plc;            // remaining candidate placements\n};\n\nint N, M;\ndouble EPS;\nvector<Field> fields;                 // size M\nint NN;                               // N*N\nint query_cnt = 0;\nint max_queries;                      // 2*N*N\n\n//---------------------------------------------------------------\ninline void flush() { cout << '\\n' << flush; }\n\n// convert id to coordinates\ninline pair<int,int> id2ij(int id){ return {id / N, id % N}; }\n\n// ask the judge\nint drill(int id)\n{\n    auto [i, j] = id2ij(id);\n    cout << \"q 1 \" << i << ' ' << j;\n    flush();\n    int v;  cin >> v;\n    ++query_cnt;\n    return v;\n}\n\n//---------------------------------------------------------------\n// read input and enumerate placements\n//---------------------------------------------------------------\nvoid read_input()\n{\n    cin >> N >> M >> EPS;\n    NN = N * N;\n    fields.resize(M);\n\n    for (int k = 0; k < M; ++k)\n    {\n        int d; cin >> d;\n        vector<pair<int,int>> cells(d);\n        int hmx = 0, wmx = 0;\n        for (int t = 0; t < d; ++t) {\n            cin >> cells[t].first >> cells[t].second;\n            hmx = max(hmx, cells[t].first);\n            wmx = max(wmx, cells[t].second);\n        }\n        ++hmx; ++wmx;                 // true size\n\n        // enumerate all translations that fit into the board\n        for (int si = 0; si + hmx <= N; ++si)\n            for (int sj = 0; sj + wmx <= N; ++sj)\n            {\n                Placement p;\n                p.cells.reserve(d);\n                for (auto [ci,cj]: cells) {\n                    int ni = ci + si, nj = cj + sj;\n                    p.cells.push_back(ni * N + nj);\n                }\n                fields[k].plc.push_back(std::move(p));\n            }\n    }\n    max_queries = 2 * NN;\n}\n\n//---------------------------------------------------------------\n// helper that recomputes statistics of remaining placements\n//---------------------------------------------------------------\nstruct StatPack {\n    vector<int> totalCnt;             // cnt over *ambiguous* fields\n    vector<double> logNoOil;          // log P(cell has *no* oil yet)\n    explicit StatPack(int n): totalCnt(n), logNoOil(n, 0.0) {}\n};\n\nStatPack compute_stats()\n{\n    StatPack st(NN);\n    for (const auto &f: fields) if (f.plc.size() > 1)\n    {\n        int S = (int)f.plc.size();\n        double invS = 1.0 / S;\n        vector<int> cnt(NN, 0);\n        for (const auto &pl : f.plc)\n            for (int id : pl.cells)   ++cnt[id];\n\n        for (int id = 0; id < NN; ++id) if (cnt[id])\n        {\n            st.totalCnt[id] += cnt[id];\n            double pf = cnt[id] * invS;\n            if (pf < 1.0)\n                st.logNoOil[id] += log(1.0 - pf);   // accumulate log(1-p)\n            else                                     // pf==1 => always oil\n                st.logNoOil[id] = -1e100;            // force probability 0\n        }\n    }\n    return st;\n}\n\n//---------------------------------------------------------------\n// main procedure\n//---------------------------------------------------------------\nint main()\n{\n    read_input();\n\n    vector<int> drilledValue(NN, -1); // -1=unknown, 0, or positive\n    vector<char> isOil(NN, 0);        // final answer flag\n\n    // phase 1: elimination loop\n    const int ELIM_Q_LIMIT = min(max_queries - 10, NN); // leave margin\n    while (true)\n    {\n        bool all_det = true;\n        for (auto &f : fields) if (f.plc.size() > 1) { all_det = false; break; }\n        if (all_det) break;\n        if (query_cnt >= ELIM_Q_LIMIT) break;          // give up \u2013 fall-back\n\n        auto st = compute_stats();\n\n        // pick square with best expected elimination\n        int bestId = -1;\n        double bestScore = -1.0;\n        for (int id = 0; id < NN; ++id)\n        {\n            if (drilledValue[id] != -1) continue;      // already drilled\n            int cnt = st.totalCnt[id];\n            if (cnt == 0) continue;\n            double pNoOil = exp(st.logNoOil[id]);      // could underflow to 0\n            double score = cnt * pNoOil;               // expected deletions\n            if (score > bestScore) { bestScore = score; bestId = id; }\n        }\n        if (bestId == -1) break;                       // nothing left to try\n\n        int v = drill(bestId);\n        drilledValue[bestId] = v;\n        if (v == 0)\n        {\n            // delete every placement that uses this square\n            for (auto &f : fields) if (f.plc.size() > 1)\n            {\n                vector<Placement> next;\n                next.reserve(f.plc.size());\n                for (auto &pl : f.plc) {\n                    bool has = false;\n                    for (int id : pl.cells) if (id == bestId) { has = true; break; }\n                    if (!has) next.push_back(std::move(pl));\n                }\n                if (!next.empty()) f.plc.swap(next);\n                // (next empty cannot happen \u2013 true placement never removed)\n            }\n        }\n        else\n        {\n            isOil[bestId] = 1;                         // known oil\n        }\n    }\n\n    // phase 2: fall-back \u2013 drill every not-decided square that still MAY hold oil\n    vector<char> mayOil(NN, 0);\n    for (const auto &f : fields)\n        for (const auto &pl : f.plc)\n            for (int id : pl.cells) mayOil[id] = 1;\n\n    for (int id = 0; id < NN && query_cnt < max_queries; ++id)\n        if (mayOil[id] && drilledValue[id] == -1)\n        {\n            int v = drill(id);\n            drilledValue[id] = v;\n            if (v) isOil[id] = 1;\n        }\n\n    // final answer set = all cells that belong to the (now unique) placements\n    //                    union all positively drilled cells (safety)\n    for (const auto &f : fields)\n        for (const auto &pl : f.plc)\n            for (int id : pl.cells) isOil[id] = 1;\n\n    vector<int> ans;\n    for (int id = 0; id < NN; ++id) if (isOil[id]) ans.push_back(id);\n\n    // output\n    cout << \"a \" << ans.size();\n    for (int id : ans) {\n        auto [i,j] = id2ij(id);\n        cout << ' ' << i << ' ' << j;\n    }\n    flush();\n\n    int judge; cin >> judge;            // should be 1\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rect {\n    int i0, j0, i1, j1;          // top, left, bottom, right  (row,col)\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int W = 1000;                  // fixed by the problem\n    int D, N;\n    int dummyW;\n    if (!(cin >> dummyW >> D >> N)) return 0;\n\n    vector<vector<long long>> A(D, vector<long long>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> A[d][k];\n\n    vector<Rect> ans(N);\n\n    for (int d = 0; d < D; ++d) {\n        /* ---------- make rectangles for one day ---------- */\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(),\n             [&](int x, int y){ return A[d][x] > A[d][y]; });   // big first\n\n        vector<int> remain = order;\n        int y = 0;                       // current top of the next row\n\n        while (!remain.empty()) {\n            long long firstArea = A[d][remain.front()];\n            int remHeight = W - y;\n            if (remHeight <= 0) {        // should never happen\n                cerr << \"Packing failed: ran out of vertical space.\\n\";\n                exit(0);\n            }\n            /* choose row height */\n            int h = (int)std::sqrt((double)firstArea);\n            h = std::clamp(h, 1, remHeight);\n            int minH = (int)((firstArea + W - 1) / W);          // ceil(a/1000)\n            h = max(h, minH);\n            if (h > remHeight) h = remHeight;                   // final guard\n\n            int x = 0;\n            vector<int> nextRemain;\n            for (int id : remain) {\n                long long a = A[d][id];\n                int w = (int)((a + h - 1) / h);                 // ceil\n                if (w > W) w = W;                               // very unlikely\n                if (x + w <= W) {\n                    ans[id] = { y, x, y + h, x + w };\n                    x += w;\n                } else {\n                    nextRemain.push_back(id);                   // to next row\n                }\n            }\n            y += h;\n            remain.swap(nextRemain);\n        }\n\n        /* ---------- output ---------- */\n        for (int k = 0; k < N; ++k) {\n            const auto &r = ans[k];\n            cout << r.i0 << ' ' << r.j0 << ' '\n                 << r.i1 << ' ' << r.j1 << '\\n';\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\nconstexpr int64 MOD = 998244353LL;\n\n/* ------------------------------------------------------------------------- */\n/* fast xoshiro64** RNG \u2013 good enough for SA                                 */\nstruct RNG {\n    uint64_t s;\n    RNG() : s(chrono::steady_clock::now().time_since_epoch().count()) {}\n    uint32_t next() {\n        s ^= s << 13;\n        s ^= s >> 7;\n        s ^= s << 17;\n        return static_cast<uint32_t>(s);\n    }\n    uint32_t next(uint32_t lim) { return next() % lim; }\n    double   uniform()          { return double(next()) / 4294967295.0; }\n} rng;\n\n/* ------------------------------------------------------------------------- */\nstruct Op {\n    int  m, p, q;                  // for the answer\n    int  idx[9];                   // linear indices of covered cells\n    int  add[9];                   // what is written on them\n};\n\n/* helper: gain when we ADD this operation to the current board */\ninline int64 gain_add(const Op& o, const array<int,81>& board){\n    int64 g = 0;\n    for (int k=0;k<9;++k){\n        int v  = board[o.idx[k]];\n        int nv = v + o.add[k];\n        if (nv >= MOD) nv -= MOD;\n        g += nv - v;\n    }\n    return g;\n}\n/* same when we REMOVE it (board already contains it) */\ninline int64 gain_sub(const Op& o, const array<int,81>& board){\n    int64 g = 0;\n    for (int k=0;k<9;++k){\n        int v  = board[o.idx[k]];\n        int nv = v - o.add[k];\n        if (nv < 0) nv += MOD;\n        g += nv - v;\n    }\n    return g;\n}\n/* apply / undo */\ninline void apply_add(const Op& o, array<int,81>& board){\n    for (int k=0;k<9;++k){\n        int& v = board[o.idx[k]];\n        v += o.add[k];\n        if (v >= MOD) v -= MOD;\n    }\n}\ninline void apply_sub(const Op& o, array<int,81>& board){\n    for (int k=0;k<9;++k){\n        int& v = board[o.idx[k]];\n        v -= o.add[k];\n        if (v < 0) v += MOD;\n    }\n}\n/* does this op wrap at least one of the 9 cells? */\ninline bool is_safe(const Op& o, const array<int,81>& board){\n    for (int k=0;k<9;++k){\n        if (board[o.idx[k]] + o.add[k] >= MOD) return false;\n    }\n    return true;\n}\n\n/* ------------------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* -------- read input -------------------------------------------------- */\n    const int N = 9, M = 20, K = 81;\n    int dummyN,dummyM,dummyK;\n    cin >> dummyN >> dummyM >> dummyK;\n\n    array<int,81> board{};\n    for (int i=0;i<81;++i) cin >> board[i];\n\n    array<array<int,9>,M> stamps{};\n    for (int m=0;m<M;++m)\n        for (int r=0;r<3;++r)\n            for (int c=0;c<3;++c)\n                cin >> stamps[m][r*3+c];\n\n    /* -------- enumerate the 980 possible presses -------------------------- */\n    vector<Op> ops;\n    ops.reserve(M*49);\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                Op o; o.m=m; o.p=p; o.q=q;\n                int t=0;\n                for (int dr=0;dr<3;++dr)\n                    for (int dc=0;dc<3;++dc){\n                        o.idx[t] = (p+dr)*N + (q+dc);\n                        o.add[t] = stamps[m][t];\n                        ++t;\n                    }\n                ops.push_back(o);\n            }\n    const int OPS = (int)ops.size();   // 980\n\n    /* --------------------------------------------------------------------- */\n    vector<int> chosen; chosen.reserve(K);   // indices into ops\n\n    /* phase 1 : safe greedy ------------------------------------------------ */\n    while ((int)chosen.size() < K){\n        int best = -1; int64 bestGain = 0;\n        for (int i=0;i<OPS;++i){\n            if(!is_safe(ops[i],board)) continue;\n            int64 g = gain_add(ops[i],board);\n            if (g > bestGain){ bestGain = g; best = i; }\n        }\n        if (best < 0 || bestGain <= 0) break;\n        apply_add(ops[best],board);\n        chosen.push_back(best);\n    }\n\n    /* phase 2 : ordinary greedy ------------------------------------------- */\n    while ((int)chosen.size() < K){\n        int best = -1; int64 bestGain = 0;\n        for (int i=0;i<OPS;++i){\n            int64 g = gain_add(ops[i],board);\n            if (g > bestGain){ bestGain = g; best = i; }\n        }\n        if (best < 0 || bestGain <= 0) break;\n        apply_add(ops[best],board);\n        chosen.push_back(best);\n    }\n\n    /* current score */\n    int64 curScore = 0;\n    for (int v: board) curScore += v;\n\n    /* phase 3 : simulated annealing --------------------------------------- */\n    const double TIME_LIMIT = 1.8;   // seconds\n    const auto  time0 = chrono::steady_clock::now();\n    const double T0 = 1.0e9, T1 = 1.0e6;\n\n    vector<int> pressList = chosen;          // working copy\n    array<int,81> workBoard = board;         // working board\n    int64 workScore = curScore;\n\n    auto sec = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now()-time0).count();\n    };\n\n    long long iteration = 0;\n    while (sec() < TIME_LIMIT){\n        ++iteration;\n        double t = sec()/TIME_LIMIT;\n        double Temp = T0 * pow(T1/T0, t);\n\n        int moveType = rng.next(3);      // 0 add, 1 remove, 2 replace\n        if (moveType==0 && (int)pressList.size()>=K) moveType = 2;   // cannot add\n        if (moveType==1 && pressList.empty())         continue;      // cannot remove\n        if (moveType==2 && pressList.empty())         moveType = 0;  // must add\n\n        if (moveType==0){          /* add */\n            int oi = rng.next(OPS);\n            int64 delta = gain_add(ops[oi],workBoard);\n            if (delta>=0 || rng.uniform() < exp(delta/Temp)){\n                apply_add(ops[oi],workBoard);\n                workScore += delta;\n                pressList.push_back(oi);\n            }\n        }\n        else if (moveType==1){     /* remove */\n            int id = rng.next((uint32_t)pressList.size());\n            int oi = pressList[id];\n            int64 delta = gain_sub(ops[oi],workBoard);   // negative or zero\n            if (delta>=0 || rng.uniform() < exp(delta/Temp)){\n                apply_sub(ops[oi],workBoard);\n                workScore += delta;\n                pressList[id] = pressList.back();\n                pressList.pop_back();\n            }\n        }\n        else{                      /* replace */\n            int id = rng.next((uint32_t)pressList.size());\n            int oldOp = pressList[id];\n            int newOp = rng.next(OPS);\n            if (newOp==oldOp) continue;\n\n            int64 delta = gain_sub(ops[oldOp],workBoard);\n            apply_sub(ops[oldOp],workBoard);\n            delta += gain_add(ops[newOp],workBoard);\n            bool accept = (delta>=0) || (rng.uniform() < exp(delta/Temp));\n            if (accept){\n                apply_add(ops[newOp],workBoard);\n                workScore += delta;\n                pressList[id] = newOp;\n            }else{\n                /* rollback */\n                apply_add(ops[oldOp],workBoard);\n            }\n        }\n    }\n\n    /* keep the better of (phase2) and (phase3) ---------------------------- */\n    if (workScore > curScore){\n        chosen.swap(pressList);\n        board  = workBoard;\n        curScore = workScore;\n    }\n\n    /* ------------------ output ------------------------------------------- */\n    cout << chosen.size() << '\\n';\n    for (int id: chosen){\n        const Op& o = ops[id];\n        cout << o.m << ' ' << o.p << ' ' << o.q << '\\n';\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Crane {\n    int r, c;          // position\n    bool alive = true;\n    bool holding = false;\n    int box = -1;      // id of the held container\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;                         // N is always 5 in this contest\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> recv(N, vector<int>(N));\n    for (auto &v: recv) for (int &x: v) cin >> x;\n\n    /* --- problem constants ------------------------------------------------ */\n    const int COL_IN  = 0;         // Receiving Gates  (column 0)\n    const int COL_OUT = N - 1;     // Dispatch  Gates  (column 4)\n\n    /* --- simulation state -------------------------------------------------- */\n    vector<vector<int>> field(N, vector<int>(N, -1));   // -1: empty, else id\n    array<int, 5> nextIdx{};                            // next container per row\n\n    vector<Crane> cr(N);            // 0 = big crane\n    for (int i = 0; i < N; ++i) cr[i] = {i, 0, true, false, -1};\n\n    vector<string> cmd(N);          // answer strings, one per crane\n\n    int dispatched = 0, turn = 0;\n\n    /* ---------------------------------------------------------------------- */\n    auto spawn = [&] () {\n        for (int r = 0; r < N; ++r) {\n            if (nextIdx[r] == N) continue;          // 5 containers already\n            if (field[r][COL_IN] != -1) continue;   // gate still occupied\n            bool holder_here = false;\n            for (auto &c : cr)\n                if (c.alive && c.holding && c.r == r && c.c == COL_IN)\n                    holder_here = true;\n            if (!holder_here)\n                field[r][COL_IN] = recv[r][nextIdx[r]++];\n        }\n    };\n\n    auto neighbours = [&](int r1, int c1, int r2, int c2) {\n        return abs(r1 - r2) + abs(c1 - c2);\n    };\n\n    /* =================== main turn loop =================================== */\n    while (dispatched < N * N) {\n        /* step 1: new containers arrive */\n        spawn();\n\n        /* step 2: decide commands ----------------------------------------- */\n        vector<char> op(N, '.');\n\n        /* small cranes: bomb on the very first turn, afterwards '.' */\n        if (turn == 0)\n            for (int i = 1; i < N; ++i) op[i] = 'B';\n\n        /* big crane logic */\n        Crane &b = cr[0];\n        char bc = '.';\n\n        if (b.holding) {                     // carrying a container\n            int destR = b.box / N, destC = COL_OUT;\n            if (b.r == destR && b.c == destC) {\n                // at the Dispatch Gate\n                bc = (field[destR][destC] == -1 ? 'Q' : '.');\n            } else {\n                // move one step toward destination (vertical first)\n                if (b.r < destR)      bc = 'D';\n                else if (b.r > destR) bc = 'U';\n                else if (b.c < destC) bc = 'R';\n                else                  bc = 'L';\n            }\n        } else {                              // empty-handed\n            if (field[b.r][b.c] != -1) {\n                bc = 'P';                     // box under our feet\n            } else {\n                // look for the nearest waiting box (always at column 0)\n                int bestR = -1, bestDist = 1e9;\n                for (int r = 0; r < N; ++r)\n                    if (field[r][COL_IN] != -1) {\n                        int d = neighbours(b.r, b.c, r, COL_IN);\n                        if (d < bestDist) bestDist = d, bestR = r;\n                    }\n                if (bestR == -1) {\n                    bc = '.';\n                } else {\n                    if (b.r < bestR)      bc = 'D';\n                    else if (b.r > bestR) bc = 'U';\n                    else if (b.c > COL_IN)bc = 'L';\n                    else                  bc = 'R';\n                }\n            }\n        }\n        op[0] = bc;\n\n        /* append to output strings */\n        for (int i = 0; i < N; ++i) cmd[i].push_back(op[i]);\n\n        /* apply actions ---------------------------------------------------- */\n        /* small cranes */\n        for (int i = 1; i < N; ++i) {\n            if (!cr[i].alive) continue;\n            if (op[i] == 'B') { cr[i].alive = false; continue; }\n        }\n\n        /* big crane */\n        switch (bc) {\n            case 'U': --b.r; break;\n            case 'D': ++b.r; break;\n            case 'L': --b.c; break;\n            case 'R': ++b.c; break;\n            case 'P':\n                b.holding = true;\n                b.box = field[b.r][b.c];\n                field[b.r][b.c] = -1;\n                break;\n            case 'Q':\n                field[b.r][b.c] = b.box;\n                b.holding = false;\n                b.box = -1;\n                break;\n            default: break;\n        }\n\n        /* step 3: automatic dispatch -------------------------------------- */\n        for (int r = 0; r < N; ++r)\n            if (field[r][COL_OUT] != -1) {\n                field[r][COL_OUT] = -1;      // container leaves the grid\n                ++dispatched;\n            }\n\n        ++turn;\n        if (turn >= 10000) break;            // safety (never reached)\n    }\n\n    /* pad the shorter strings with '.' ------------------------------------ */\n    const size_t L = cmd[0].size();\n    for (int i = 1; i < N; ++i)\n        if (cmd[i].size() < L) cmd[i].append(L - cmd[i].size(), '.');\n\n    /* output -------------------------------------------------------------- */\n    for (int i = 0; i < N; ++i) cout << cmd[i] << '\\n';\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Coord = pair<int,int>;\nconstexpr int N = 20;                 // fixed\n\n/* -------------------------------------------------------------------------- */\n/*  Path builders                                                             */\n/* -------------------------------------------------------------------------- */\nvector<Coord> build_row_snake(bool startLeftRight = true){\n    vector<Coord> p; p.reserve(N*N);\n    for(int r=0;r<N;r++){\n        if((r&1) == (startLeftRight?0:1))\n            for(int c=0;c<N;c++)  p.emplace_back(r,c);\n        else\n            for(int c=N-1;c>=0;c--) p.emplace_back(r,c);\n    }\n    return p;\n}\nvector<Coord> build_col_snake(bool startTopBottom = true){\n    vector<Coord> p; p.reserve(N*N);\n    for(int c=0;c<N;c++){\n        if((c&1) == (startTopBottom?0:1))\n            for(int r=0;r<N;r++)  p.emplace_back(r,c);\n        else\n            for(int r=N-1;r>=0;r--) p.emplace_back(r,c);\n    }\n    return p;\n}\nvector<Coord> build_spiral(bool clockwise = true){\n    vector<Coord> p; p.reserve(N*N);\n    int top=0,bot=N-1,left=0,right=N-1;\n    while(top<=bot && left<=right){\n        if(clockwise){\n            for(int c=left;c<=right;c++) p.emplace_back(top,c);\n            ++top;\n            for(int r=top;r<=bot;r++)   p.emplace_back(r,right);\n            --right;\n            if(top<=bot){\n                for(int c=right;c>=left;c--) p.emplace_back(bot,c);\n                --bot;\n            }\n            if(left<=right){\n                for(int r=bot;r>=top;r--)   p.emplace_back(r,left);\n                ++left;\n            }\n        }else{                      // counter\u2013clockwise start\n            for(int r=top;r<=bot;r++)   p.emplace_back(r,left);\n            ++left;\n            for(int c=left;c<=right;c++) p.emplace_back(bot,c);\n            --bot;\n            if(left<=right){\n                for(int r=bot;r>=top;r--)   p.emplace_back(r,right);\n                --right;\n            }\n            if(top<=bot){\n                for(int c=right;c>=left;c--) p.emplace_back(top,c);\n                ++top;\n            }\n        }\n    }\n    return p;\n}\n\n/* -------------------------------------------------------------------------- */\nlong long prefix_cost_and_start(const vector<Coord>& path,\n                                const vector<vector<int>>& h,\n                                int& bestStartIdx)\n{\n    const int M = path.size();             // 400\n    static long long pref[401];\n    pref[0]=0;\n    for(int i=0;i<M;i++){\n        auto [r,c]=path[i];\n        pref[i+1]=pref[i]+h[r][c];\n    }\n    long long mn=pref[0]; int mnPos=0;\n    for(int i=1;i<=M;i++){\n        if(pref[i]<mn){ mn=pref[i]; mnPos=i; }\n    }\n    int s = mnPos % M;                     // feasible rotation\n    bestStartIdx = s;\n\n    long long cost=0, load=0;\n    for(int step=0; step<M-1; ++step){\n        load += h[path[(s+step)%M].first][path[(s+step)%M].second];\n        cost += load;\n    }\n    return cost;\n}\n\n/* -------------------------------------------------------------------------- */\nvoid move_to(int &r,int &c,int tr,int tc,vector<string>& out){\n    while(r<tr){ out.emplace_back(\"D\"); ++r; }\n    while(r>tr){ out.emplace_back(\"U\"); --r; }\n    while(c<tc){ out.emplace_back(\"R\"); ++c; }\n    while(c>tc){ out.emplace_back(\"L\"); --c; }\n}\n\n/* -------------------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyN; if(!(cin>>dummyN)) return 0;\n\n    vector<vector<int>> h(N, vector<int>(N));\n    for(int r=0;r<N;r++) for(int c=0;c<N;c++) cin>>h[r][c];\n\n    /* ----- build candidate Hamiltonian paths ----------------------------- */\n    vector<vector<Coord>> paths;\n    paths.emplace_back(build_row_snake(true));\n    paths.emplace_back(build_row_snake(false));\n    paths.emplace_back(build_col_snake(true));\n    paths.emplace_back(build_col_snake(false));\n    paths.emplace_back(build_spiral(true));\n    paths.emplace_back(build_spiral(false));\n\n    /* ----- evaluate ------------------------------------------------------ */\n    long long bestScore = (1LL<<62);\n    int bestPathId=0, bestStartIdx=0, bestDist=0;\n\n    for(int pid=0; pid<(int)paths.size(); ++pid){\n        int sIdx=0;\n        long long pcost = prefix_cost_and_start(paths[pid],h,sIdx);\n\n        auto [sr,sc] = paths[pid][sIdx];\n        int dist = abs(sr) + abs(sc);              // empty truck approach\n        long long totalMoveCost = pcost + 100LL*( (N*N-1) + dist );\n\n        if(totalMoveCost < bestScore){\n            bestScore = totalMoveCost;\n            bestPathId = pid;\n            bestStartIdx = sIdx;\n            bestDist = dist;\n        }\n    }\n\n    /* ----- produce operations for the chosen path ------------------------ */\n    const auto& path = paths[bestPathId];\n    const int M = path.size();\n    const int s = bestStartIdx;\n\n    vector<string> out; out.reserve(1200);\n\n    int r=0,c=0, load=0;\n    auto [sr,sc] = path[s];\n    move_to(r,c,sr,sc,out);                // empty approach, cost 100 each\n\n    for(int k=0;k<M;k++){\n        int idx = (s+k)%M;\n        auto [cr,cc] = path[idx];\n        int val = h[cr][cc];\n        if(val>0){\n            out.emplace_back(\"+\" + to_string(val));\n            load += val;\n        }else if(val<0){\n            out.emplace_back(\"-\" + to_string(-val));\n            load -= -val;\n        }\n        h[cr][cc]=0;\n\n        if(k!=M-1){\n            auto [nr,nc]=path[(idx+1)%M];\n            move_to(r,c,nr,nc,out);        // exactly one step\n        }\n    }\n    /* load == 0 now */\n\n    for(const string& s : out) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** fixed parameters ***/\nconstexpr int N  = 6;               // grid size\nconstexpr int M  = 15;              // #criteria\nconstexpr int T  = 10;              // #turns\nconstexpr int SEED_CNT = 2 * N * (N - 1);     // always 60\nconstexpr int PLANT_CNT = N * N;               // 36\n\nstruct Seed {\n    array<uint8_t, M> x;\n    int               sum = 0;\n};\n\n/*** geometry of the 6\u00d76 field ***/\narray<vector<int>, PLANT_CNT> neighbours;\nvector<pair<int,int>>          edges;          // each edge once\narray<int, PLANT_CNT>          degree;\n\nvoid build_geometry() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c) {\n            int idx = r * N + c;\n            auto add = [&](int rr,int cc){\n                if (0<=rr && rr<N && 0<=cc && cc<N)\n                    neighbours[idx].push_back(rr*N+cc);\n            };\n            if (c+1 < N){ add(r,c+1); edges.emplace_back(idx, r*N+c+1); }\n            if (r+1 < N){ add(r+1,c); edges.emplace_back(idx, (r+1)*N+c); }\n            add(r,c-1); add(r-1,c);          // for fast \u0394 evaluation\n        }\n    for (int i = 0; i < PLANT_CNT; ++i) degree[i] = (int)neighbours[i].size();\n}\n\n/*** global containers reused every turn ***/\narray<Seed, SEED_CNT> seed;           // current 60 seeds\nint   syn[SEED_CNT][SEED_CNT];        // synergy matrix (\u22641500, fits in int)\narray<int, PLANT_CNT>  cell2seed;     // current grid \u2192 seed id\narray<int, PLANT_CNT>  bestPlant;     // best arrangement found\nlong long              bestScore;\n\n/*** synergy between two seeds ***/\ninline int synergy(int a,int b){ return syn[a][b]; }\n\n/*** objective = \u03a3 synergy over (undirected) edges *********************/\ninline long long objective() {\n    long long s = 0;\n    for (auto [u,v]: edges) s += synergy(cell2seed[u], cell2seed[v]);\n    return s;\n}\n\n/*** fast \u0394 when swapping/replacing one cell ***************************/\nlong long delta_one_cell(int pos,int oldSeed,int newSeed){\n    long long d = 0;\n    for (int nb : neighbours[pos]) {\n        d -= synergy(oldSeed      , cell2seed[nb]);\n        d += synergy(newSeed      , cell2seed[nb]);\n    }\n    return d;\n}\n\n/*** a very small simulated annealing **********************************/\nvoid simulated_annealing(mt19937_64 &rng,\n                         vector<int> &pool) {\n    constexpr int ITER      = 30000;\n    constexpr double T0     = 1000.0;\n    constexpr double T1     = 5.0;\n    uniform_real_distribution<double> urd(0.0,1.0);\n    uniform_int_distribution<int>     cellDist(0, PLANT_CNT-1);\n\n    bestPlant = cell2seed;\n    bestScore = objective();\n    long long curScore = bestScore;\n\n    for (int it = 0; it < ITER; ++it) {\n        double temp = T0 + (T1 - T0) * it / ITER;\n\n        if (!pool.empty() && urd(rng) < 0.30) {            // replace with pool\n            int pos  = cellDist(rng);\n            int pidx = uniform_int_distribution<int>(0,(int)pool.size()-1)(rng);\n            int s_old = cell2seed[pos], s_new = pool[pidx];\n            long long d = delta_one_cell(pos, s_old, s_new);\n\n            if (d >= 0 || urd(rng) < exp(d / temp)) {\n                cell2seed[pos] = s_new;\n                pool[pidx]     = s_old;\n                curScore      += d;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestPlant = cell2seed;\n                }\n            }\n        } else {                                           // swap two cells\n            int a = cellDist(rng), b = cellDist(rng);\n            if (a == b) continue;\n            int sa = cell2seed[a], sb = cell2seed[b];\n\n            long long d  = delta_one_cell(a, sa, sb)\n                         + delta_one_cell(b, sb, sa);\n            if (d >= 0 || urd(rng) < exp(d / temp)) {\n                cell2seed[a] = sb;\n                cell2seed[b] = sa;\n                curScore    += d;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestPlant = cell2seed;\n                }\n            }\n        }\n    }\n    cell2seed = bestPlant;\n}\n\n/*** main **************************************************************/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    build_geometry();\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    /* --- read the very first 60 seeds --------------------------------*/\n    int dummyN, dummyM, dummyT;\n    cin >> dummyN >> dummyM >> dummyT;          // they are always 6 15 10\n    for (int i = 0; i < SEED_CNT; ++i){\n        int sum = 0;\n        for (int l = 0; l < M; ++l){\n            int v; cin >> v;\n            seed[i].x[l] = (uint8_t)v;\n            sum += v;\n        }\n        seed[i].sum = sum;\n    }\n\n    for (int turn = 0; turn < T; ++turn){\n        /* --- choose seeds to work with: 36 best by V -----------------*/\n        vector<int> idx(SEED_CNT); iota(idx.begin(), idx.end(), 0);\n        ranges::sort(idx, [&](int a,int b){ return seed[a].sum > seed[b].sum; });\n\n        vector<int> pool(idx.begin()+PLANT_CNT, idx.end());          // 24 seeds\n        /* --- precalculate synergy matrix -----------------------------*/\n        for (int i = 0; i < SEED_CNT; ++i){\n            syn[i][i] = seed[i].sum;          // not needed, but harmless\n            for (int j = i+1; j < SEED_CNT; ++j){\n                int s = 0;\n                for (int l = 0; l < M; ++l)\n                    s += max(seed[i].x[l], seed[j].x[l]);\n                syn[i][j] = syn[j][i] = s;\n            }\n        }\n\n        /* --- initial placement: best seeds on highest-degree cells ---*/\n        array<int, PLANT_CNT> cells;\n        iota(cells.begin(), cells.end(), 0);\n        ranges::sort(cells, [&](int a,int b){ return degree[a] > degree[b]; });\n\n        for (int k = 0; k < PLANT_CNT; ++k)\n            cell2seed[cells[k]] = idx[k];\n\n        /* --- improve by SA -------------------------------------------*/\n        simulated_annealing(rng, pool);\n\n        /* --- output --------------------------------------------------*/\n        for (int r = 0; r < N; ++r){\n            for (int c = 0; c < N; ++c){\n                if (c) cout << ' ';\n                cout << cell2seed[r*N+c];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        /* --- read the 60 children for the next turn ------------------*/\n        if (turn == T-1) break;               // still need to read, but no calc\n        for (int i = 0; i < SEED_CNT; ++i){\n            int sum = 0;\n            for (int l = 0; l < M; ++l){\n                int v; cin >> v;\n                seed[i].x[l] = (uint8_t)v;\n                sum += v;\n            }\n            seed[i].sum = sum;\n        }\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int x, y; };\nstatic constexpr int DX[4] = {0, 1, 0,-1};\nstatic constexpr int DY[4] = {1, 0,-1, 0};\n\nint manhattan(const Pos& a, const Pos& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n/* the 4 candidate root positions for a square (i,j) ------------------ */\ninline bool in_field(int x,int y,int N){ return 0<=x && x<N && 0<=y && y<N; }\narray<Pos,4> cand_root(const Pos& p){      // R,D,L,U\n    return {{{p.x-DX[0],p.y-DY[0]},\n             {p.x-DX[1],p.y-DY[1]},\n             {p.x-DX[2],p.y-DY[2]},\n             {p.x-DX[3],p.y-DY[3]}}};\n}\n\n/* ------------------------------------------------------------------ */\nstruct Simulator {\n    int N;\n    vector<string> cmd;          // final command list\n\n    int rx=0, ry=0;              // current root position\n    int dir=0;                   // 0:R 1:D 2:L 3:U\n    bool holding=false;\n\n    void push(char mv,char rot,char act){\n        string s(4,'.');\n        s[0]=mv; s[1]=rot; s[3]=act;\n        cmd.push_back(move(s));\n    }\n\n    /* move root to (tx,ty) and orient fingertip to targetDir --------*/\n    void move_and_rotate(int tx,int ty,int targetDir){\n        int cw = (targetDir - dir + 4) % 4;\n        int ccw= (dir - targetDir + 4) % 4;\n        char rotChar; int rotCnt;\n        if (cw<=ccw){ rotChar='R'; rotCnt=cw; }\n        else        { rotChar='L'; rotCnt=ccw; }\n\n        /* overlap rotation steps with translation ------------------ */\n        while (rx!=tx || ry!=ty){\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\n            char rot='.';\n            if(rotCnt>0){\n                rot=rotChar; --rotCnt;\n                dir = (dir + (rot=='R'?1:3)) & 3;\n            }\n            push(mv,rot,'.');\n        }\n        /* remaining rotations (if translation shorter than diff) ---- */\n        while(rotCnt--){\n            push('.' ,rotChar,'.');\n            dir = (dir + (rotChar=='R'?1:3)) & 3;\n        }\n    }\n};\n/* ------------------------------------------------------------------ */\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N,M,Vmax;\n    if(!(cin>>N>>M>>Vmax)) 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    /* ----------------- split into sources / targets ---------------- */\n    vector<Pos> src, tar;\n    for(int i=0;i<N;++i)\n        for(int j=0;j<N;++j){\n            bool s = S[i][j]=='1';\n            bool t = T[i][j]=='1';\n            if( s && !t) src.push_back({i,j});\n            if(!s &&  t) tar.push_back({i,j});\n        }\n\n    /* --------------------------- output arm ------------------------ */\n    cout<<2<<\"\\n\";\n    cout<<0<<\" 1\\n\";             // child 1 at distance 1\n    cout<<0<<\" 0\\n\";             // root starts (0,0)\n\n    Simulator sim; sim.N = N;\n\n    /* we remove items from vectors, therefore random-access index ----*/\n    auto erase_swap = [](vector<Pos>& v,size_t idx){\n        v[idx]=v.back(); v.pop_back();\n    };\n\n    /* -------------------------- main loop -------------------------- */\n    while(!src.empty()){\n        /* ------------------------------------------------ source step */\n        int bestIdx=-1, bestD=INT_MAX, bestRootX=0, bestRootY=0, bestDir=0;\n        for(size_t i=0;i<src.size();++i){\n            const Pos& p = src[i];\n            auto roots = cand_root(p);\n            for(int d=0;d<4;++d){\n                int x=roots[d].x, y=roots[d].y;\n                if(!in_field(x,y,N)) continue;\n                int path = manhattan({sim.rx,sim.ry},{x,y});\n                int rot  = min((d - sim.dir + 4)%4,(sim.dir - d +4)%4);\n                int cost = path + max(0, rot - path);   // rotations not overlap\n                if(cost<bestD){\n                    bestD=cost; bestIdx=i;\n                    bestRootX=x; bestRootY=y; bestDir=d;\n                }\n            }\n        }\n\n        /* go there, pick ------------------------------------------- */\n        sim.move_and_rotate(bestRootX,bestRootY,bestDir);\n        sim.push('.','.','P');           // grab\n        sim.holding=true;\n        Pos piece = src[bestIdx];\n        erase_swap(src,bestIdx);\n\n        /* ------------------------------------------------ target step */\n        int bestTarIdx=-1, bestDist=INT_MAX;\n        for(size_t i=0;i<tar.size();++i){\n            int d = manhattan(piece, tar[i]);\n            if(d<bestDist){ bestDist=d; bestTarIdx=i; }\n        }\n        Pos goal = tar[bestTarIdx];\n        erase_swap(tar,bestTarIdx);\n\n        int bestRX=0,bestRY=0,bestTD=0,bestC=INT_MAX;\n        auto roots = cand_root(goal);\n        for(int d=0;d<4;++d){\n            int x=roots[d].x, y=roots[d].y;\n            if(!in_field(x,y,N)) continue;\n            int path = manhattan({sim.rx,sim.ry},{x,y});\n            int rot  = min((d - sim.dir + 4)%4,(sim.dir - d +4)%4);\n            int cost = path + max(0, rot - path);\n            if(cost<bestC){ bestC=cost; bestRX=x; bestRY=y; bestTD=d; }\n        }\n\n        /* go there, place ------------------------------------------ */\n        sim.move_and_rotate(bestRX,bestRY,bestTD);\n        sim.push('.','.','P');           // drop\n        sim.holding=false;\n    }\n\n    /* -------------------------- command list ----------------------- */\n    for(const string& s: sim.cmd) cout<<s<<\"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* data structures ---------------------------------------------------------*/\nstruct Point { int x, y; };\n\nstruct GridRect {               // inclusive indices on the grid\n    int l, r, t, b;             // l<=r , t<=b\n};\n\nconstexpr int MAXC = 100000;\nconstexpr int CELL  = 250;                       // finer resolution\nconstexpr int GRID  = MAXC / CELL + 1;           // 401\n\nstatic int diffGrid[GRID][GRID];\nstatic int pref[GRID + 1][GRID + 1];             // 2-D prefix sum\n\ninline int rectSum(int t, int l, int b, int r) { // inclusive \u2192 O(1) balance\n    return pref[b + 1][r + 1] - pref[t][r + 1] - pref[b + 1][l] + pref[t][l];\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<Point> mac(N), sar(N);\n    for (int i = 0; i < N; ++i) cin >> mac[i].x >> mac[i].y;\n    for (int i = 0; i < N; ++i) cin >> sar[i].x >> sar[i].y;\n\n    /* 1. build difference grid --------------------------------------------*/\n    for (auto &p: mac) diffGrid[p.y / CELL][p.x / CELL] += 1;\n    for (auto &p: sar) diffGrid[p.y / CELL][p.x / CELL] -= 1;\n\n    /* 2. prefix sums -------------------------------------------------------*/\n    for (int y = 0; y < GRID; ++y) {\n        int row = 0;\n        for (int x = 0; x < GRID; ++x) {\n            row += diffGrid[y][x];\n            pref[y + 1][x + 1] = pref[y][x + 1] + row;\n        }\n    }\n\n    /* 3. 2-D maximum sub-array (Kadane) on the fine grid -------------------*/\n    int bestSum = INT_MIN;\n    GridRect bestR{0,0,0,0};\n    static int colSum[GRID];\n\n    for (int top = 0; top < GRID; ++top) {\n        fill(colSum, colSum + GRID, 0);\n        for (int bot = top; bot < GRID; ++bot) {\n            for (int x = 0; x < GRID; ++x) colSum[x] += diffGrid[bot][x];\n\n            int cur = 0, curL = 0;\n            for (int x = 0; x < GRID; ++x) {\n                cur += colSum[x];\n                if (cur > bestSum) {\n                    bestSum = cur;\n                    bestR   = {curL, x, top, bot};\n                }\n                if (cur < 0) { cur = 0; curL = x + 1; }\n            }\n        }\n    }\n\n    /* 4. many cheap random rectangles on the grid --------------------------*/\n    mt19937 rng(1234567);\n    uniform_int_distribution<int> macPick(0, N - 1);\n    uniform_int_distribution<int> sizePick(1, 60);          // up to 60 cells (=15 000)\n    const int SAMPLES = 60000;\n\n    for (int s = 0; s < SAMPLES; ++s) {\n        const Point &c = mac[macPick(rng)];\n        int gx = c.x / CELL, gy = c.y / CELL;\n        int w  = sizePick(rng), h = sizePick(rng);\n\n        int l = max(0, gx - w / 2);\n        int r = min(GRID - 1, l + w - 1);\n        l = max(0, r - w + 1);\n        int t = max(0, gy - h / 2);\n        int b = min(GRID - 1, t + h - 1);\n        t = max(0, b - h + 1);\n\n        int sc = rectSum(t, l, b, r);\n        if (sc > bestSum) { bestSum = sc; bestR = {l, r, t, b}; }\n    }\n\n    /* 5. greedy shrinkage (still on the grid) ------------------------------*/\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        int cur = rectSum(bestR.t, bestR.l, bestR.b, bestR.r);\n\n        if (bestR.l < bestR.r &&\n            rectSum(bestR.t, bestR.l + 1, bestR.b, bestR.r) > cur) {\n            ++bestR.l; improved = true; continue;\n        }\n        if (bestR.l < bestR.r &&\n            rectSum(bestR.t, bestR.l, bestR.b, bestR.r - 1) > cur) {\n            --bestR.r; improved = true; continue;\n        }\n        if (bestR.t < bestR.b &&\n            rectSum(bestR.t + 1, bestR.l, bestR.b, bestR.r) > cur) {\n            ++bestR.t; improved = true; continue;\n        }\n        if (bestR.t < bestR.b &&\n            rectSum(bestR.t, bestR.l, bestR.b - 1, bestR.r) > cur) {\n            --bestR.b; improved = true; continue;\n        }\n    }\n\n    /* 6. convert to true coordinates ---------------------------------------*/\n    int x1 = bestR.l * CELL;\n    int y1 = bestR.t * CELL;\n    int x2 = min(MAXC, (bestR.r + 1) * CELL - 1);\n    int y2 = min(MAXC, (bestR.b + 1) * CELL - 1);\n\n    /* 7. optional exact shrink to mackerel bounding box --------------------*/\n    auto inside = [&](const Point &p) {\n        return x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2;\n    };\n    int minx = MAXC, miny = MAXC, maxx = 0, maxy = 0;\n    bool any = false;\n    for (auto &p: mac)\n        if (inside(p)) { any = true; minx = min(minx, p.x); miny = min(miny, p.y);\n                         maxx = max(maxx, p.x); maxy = max(maxy, p.y); }\n    if (any) {\n        if (minx == maxx) maxx = min(MAXC, maxx + 1);\n        if (miny == maxy) maxy = min(MAXC, maxy + 1);\n\n        int diffOld = 0, diffNew = 0;\n        for (auto &p: mac) {\n            if (inside(p)) ++diffOld;\n            if (minx <= p.x && p.x <= maxx && miny <= p.y && p.y <= maxy) ++diffNew;\n        }\n        for (auto &p: sar) {\n            if (inside(p)) --diffOld;\n            if (minx <= p.x && p.x <= maxx && miny <= p.y && p.y <= maxy) --diffNew;\n        }\n        if (diffNew >= diffOld) { x1 = minx; y1 = miny; x2 = maxx; y2 = maxy; }\n    }\n\n    /* 8. final safety check -------------------------------------------------*/\n    int finalDiff = 0;\n    for (auto &p: mac) if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) ++finalDiff;\n    for (auto &p: sar) if (x1 <= p.x && p.x <= x2 && y1 <= p.y && p.y <= y2) --finalDiff;\n\n    if (finalDiff <= 0) { x1 = y1 = 0; x2 = y2 = 1; } // guaranteed 1-point score\n\n    /* 9. output as a simple rectangle --------------------------------------*/\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;\nusing int64 = long long;\n\n/*------------------------------------------------------------\n   rectangle estimates\n ------------------------------------------------------------*/\nstruct Est {\n    int64 w, h;          // w' , h'\n};\n\n/*------------------------------------------------------------\n   greedy shelves for a given width limit\n ------------------------------------------------------------*/\nstruct Layout {\n    vector<char> rot;          // 0 = as is, 1 = rotated\n    vector<int>  rowStart;     // starting index of every row (ascending)\n    vector<int64> rowWidth, rowHeight;\n    int64  boxW = 0, boxH = 0; // W  and H\n    int64  score() const { return boxW + boxH; }\n};\n\nLayout buildLayout(const vector<Est>& a, int64 Wlim)\n{\n    const int N = (int)a.size();\n    Layout L;\n    L.rot.assign(N, 0);\n    L.rowStart.clear();\n    L.rowWidth.clear();\n    L.rowHeight.clear();\n\n    int64 curW = 0, curH = 0;\n    L.rowStart.push_back(0);\n\n    for (int i = 0; i < N; ++i) {\n        int64 w0 = a[i].w, h0 = a[i].h;\n        int64 w1 = h0,     h1 = w0;\n\n        bool fit0 = (curW + w0 <= Wlim);\n        bool fit1 = (curW + w1 <= Wlim);\n\n        auto choose_orientation = [&](bool inRow) -> char {\n            if (inRow) {\n                if (fit0 && fit1) {\n                    /* both fit \u2013 pick the smaller resulting height,\n                       break ties by smaller width */\n                    int64 newH0 = max(curH, h0);\n                    int64 newH1 = max(curH, h1);\n                    if (newH0 != newH1) return (newH0 < newH1 ? 0 : 1);\n                    return (curW + w0 <= curW + w1 ? 0 : 1);\n                }\n                if (fit0) return 0;\n                if (fit1) return 1;\n            }\n            /* either starting a new row or none fits in the current row */\n            return (h0 != h1 ? (h0 < h1 ? 0 : 1)\n                             : (w0 <= w1 ? 0 : 1));\n        };\n\n        char useRot = choose_orientation(true);\n\n        auto place_in_new_row = [&](char rotFlag) {\n            if (!L.rowWidth.empty()) {\n                L.rowWidth.back() = curW;\n                L.rowHeight.back() = curH;\n            }\n            L.rowStart.push_back(i);\n            curW = 0;\n            curH = 0;\n            useRot = rotFlag;\n        };\n\n        if (!(fit0 || fit1)) {\n            /* close current row, start a new one */\n            char rotFirst = choose_orientation(false);\n            place_in_new_row(rotFirst);\n        }\n\n        /* place the (possibly first) rectangle of the row */\n        if (useRot == 0) {\n            curW += w0;\n            curH = max(curH, h0);\n        } else {\n            curW += w1;\n            curH = max(curH, h1);\n        }\n        L.rot[i] = useRot;\n    }\n    /* push the last row */\n    L.rowWidth.push_back(curW);\n    L.rowHeight.push_back(curH);\n\n    L.boxW = *max_element(L.rowWidth.begin(), L.rowWidth.end());\n    L.boxH = accumulate(L.rowHeight.begin(), L.rowHeight.end(), int64(0));\n    return L;\n}\n\n/*------------------------------------------------------------\n   one\u2013flip hill climbing within fixed rows\n ------------------------------------------------------------*/\nvoid improveLayout(Layout& lay, const vector<Est>& a)\n{\n    const int N = (int)a.size();\n    const int R = (int)lay.rowStart.size();\n    vector<int> rowOf(N);\n    for (int r = 0; r < R; ++r) {\n        int st = lay.rowStart[r];\n        int ed = (r + 1 < R ? lay.rowStart[r + 1] : N);\n        for (int i = st; i < ed; ++i) rowOf[i] = r;\n    }\n    int64 best = lay.score();\n    bool improved = true;\n\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < N; ++i) {\n            int r = rowOf[i];\n            int st = lay.rowStart[r];\n            int ed = (r + 1 < R ? lay.rowStart[r + 1] : N);\n\n            /* current and flipped sizes */\n            int64 w0 = lay.rot[i] ? a[i].h : a[i].w;\n            int64 h0 = lay.rot[i] ? a[i].w : a[i].h;\n            int64 w1 = lay.rot[i] ? a[i].w : a[i].h;\n            int64 h1 = lay.rot[i] ? a[i].h : a[i].w;\n            if (w0 == w1 && h0 == h1) continue;   // square\n\n            int64 newRowW = lay.rowWidth[r] - w0 + w1;\n\n            /* recompute the row height if necessary */\n            int64 newRowH;\n            if (h0 == lay.rowHeight[r]) {\n                int64 secondMax = 0;\n                for (int j = st; j < ed; ++j)\n                    if (j != i) {\n                        int64 h = lay.rot[j] ? a[j].w : a[j].h;\n                        secondMax = max(secondMax, h);\n                    }\n                newRowH = max(secondMax, h1);\n            } else {\n                newRowH = max(lay.rowHeight[r], h1);\n            }\n\n            int64 newBoxH = lay.boxH - lay.rowHeight[r] + newRowH;\n\n            int64 newBoxW;\n            if (lay.rowWidth[r] == lay.boxW) {\n                newBoxW = newRowW;\n                for (int rr = 0; rr < R; ++rr) {\n                    int64 w = (rr == r ? newRowW : lay.rowWidth[rr]);\n                    newBoxW = max(newBoxW, w);\n                }\n            } else {\n                newBoxW = max(lay.boxW, newRowW);\n            }\n\n            int64 newScore = newBoxW + newBoxH;\n            if (newScore < best) {\n                /* accept the flip */\n                lay.rot[i] ^= 1;\n                lay.rowWidth[r] = newRowW;\n                lay.rowHeight[r] = newRowH;\n                lay.boxW = newBoxW;\n                lay.boxH = newBoxH;\n                best = newScore;\n                improved = true;\n            }\n        }\n    }\n}\n\n/*------------------------------------------------------------\n   produce placement sequence\n ------------------------------------------------------------*/\nstruct Command {\n    int p; char r; char d; int b;\n};\nvector<Command> buildCommands(const Layout& lay,\n                              const vector<Est>& a)\n{\n    const int N = (int)a.size();\n    const int R = (int)lay.rowStart.size();\n    vector<int> tallestIdx(R);\n    /* locate the tallest rectangle of every row */\n    for (int r = 0; r < R; ++r) {\n        int st = lay.rowStart[r];\n        int ed = (r + 1 < R ? lay.rowStart[r + 1] : N);\n        int64 bestH = -1;\n        for (int i = st; i < ed; ++i) {\n            int64 h = lay.rot[i] ? a[i].w : a[i].h;\n            if (h > bestH) { bestH = h; tallestIdx[r] = i; }\n        }\n    }\n\n    vector<Command> out(N);\n    for (int i = 0; i < N; ++i) {\n        int rRow = (int)(upper_bound(lay.rowStart.begin(),\n                                     lay.rowStart.end(), i) - lay.rowStart.begin()) - 1;\n        bool isRowFirst = (i == lay.rowStart[rRow]);\n        Command cmd;\n        cmd.p = i;\n        cmd.r = lay.rot[i];\n        if (rRow == 0 && isRowFirst) {\n            cmd.d = 'U';\n            cmd.b = -1;\n        } else if (isRowFirst) {\n            cmd.d = 'L';\n            cmd.b = tallestIdx[rRow - 1];\n        } else {\n            cmd.d = 'U';\n            cmd.b = i - 1;\n        }\n        out[i] = cmd;\n    }\n    return out;\n}\n\n/*------------------------------------------------------------\n   main\n ------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    if (!(cin >> N >> T >> sigma)) return 0;\n\n    vector<Est> rect(N);\n    for (int i = 0; i < N; ++i) cin >> rect[i].w >> rect[i].h;\n\n    /* ---- (1) prepare candidate width limits ---- */\n    long double area = 0;\n    int64 wMax = 0;\n    for (auto &e: rect) {\n        area += (long double)e.w * (long double)e.h;\n        wMax = max(wMax, max(e.w, e.h));\n    }\n    long double Wideal = sqrtl(area);           // \u2248 sqrt(total area)\n\n    vector<int64> candidates;\n    vector<long double> factor = {0.3L,0.4L,0.5L,0.6L,0.7L,0.8L,\n                                  1.0L,1.2L,1.5L,2.0L,3.0L,5.0L};\n\n    for (auto f : factor) {\n        int64 w = (int64)(Wideal * f);\n        w = max<int64>(w, wMax);\n        candidates.push_back(w);\n    }\n    candidates.push_back(wMax);               // very narrow (one per row)\n    /* remove duplicates */\n    sort(candidates.begin(), candidates.end());\n    candidates.erase(unique(candidates.begin(), candidates.end()), candidates.end());\n\n    /* ---- (2) try all candidates ---- */\n    Layout bestLay;\n    bestLay.boxW = (1LL << 60);\n    bestLay.boxH = (1LL << 60);\n\n    for (int64 Wlim : candidates) {\n        Layout L = buildLayout(rect, Wlim);\n        if (L.score() < bestLay.score()) bestLay = std::move(L);\n    }\n\n    /* ---- (3) local improvement ---- */\n    improveLayout(bestLay, rect);\n\n    /* ---- (4) build placement commands ---- */\n    auto cmds = buildCommands(bestLay, rect);\n\n    /* ---- (5) interact \u2013 identical answer every turn ---- */\n    for (int t = 0; t < T; ++t) {\n        cout << N << '\\n';\n        for (auto &c : cmds) {\n            cout << c.p << ' ' << int(c.r) << ' ' << c.d << ' ' << c.b << '\\n';\n        }\n        cout << flush;\n\n        /* read and ignore the noisy measurement */\n        int64 WP, HP;\n        if (!(cin >> WP >> HP)) return 0;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int UNASSIGNED = -2;\nconstexpr int LIMH       = 10;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- input ---------- */\n    int N, M, H;\n    if (!(cin >> N >> M >> H)) return 0;                  // H is always 10\n    vector<int> A(N);\n    for (int &x : A) cin >> x;\n\n    vector<vector<int>> g(N);\n    for (int i = 0, u, v; i < M; ++i) {\n        cin >> u >> v;\n        g[u].push_back(v);\n        g[v].push_back(u);\n    }\n    /* positions are irrelevant for the algorithm */\n    for (int i = 0, xv, yv; i < N; ++i) cin >> xv >> yv;\n\n    /* ---------- sort adjacency lists by increasing beauty ---------- */\n    for (int v = 0; v < N; ++v)\n        sort(g[v].begin(), g[v].end(),\n             [&](int a, int b){ return A[a] < A[b]; });\n\n    /* ---------- pre-compute \u201cvertices reachable within 10 steps\u201d ---- */\n    vector<vector<int>> reach10(N);\n    {\n        vector<int> dist(N, -1);\n        queue<int> q;\n        for (int s = 0; s < N; ++s) {\n            fill(dist.begin(), dist.end(), -1);\n            dist[s] = 0;\n            q.push(s);\n            reach10[s].push_back(s);\n            while (!q.empty()) {\n                int v = q.front(); q.pop();\n                if (dist[v] == LIMH) continue;\n                for (int nb : g[v]) if (dist[nb] == -1) {\n                    dist[nb] = dist[v] + 1;\n                    reach10[s].push_back(nb);\n                    q.push(nb);\n                }\n            }\n        }\n    }\n\n    /* ---------- main greedy construction --------------------------- */\n    vector<char> covered(N, 0);\n    int uncoveredCnt = N;\n\n    vector<int> parent(N, UNASSIGNED);\n    vector<int> depth (N, -1);\n\n    queue<int> q;                        // reused BFS queue\n\n    while (uncoveredCnt > 0) {\n        /* ---- pick best new root ----------------------------------- */\n        double bestScore = 1e100;\n        int    bestRoot  = -1;\n\n        for (int v = 0; v < N; ++v) if (!covered[v]) {\n            long long coverSum = 0;\n            for (int u : reach10[v]) if (!covered[u]) coverSum += A[u];\n            if (coverSum == 0) continue;                 // shouldn\u2019t happen\n            double score = double(A[v]) / double(coverSum);\n            if (score < bestScore) {\n                bestScore = score;\n                bestRoot  = v;\n            }\n        }\n\n        int root = bestRoot;\n        parent[root] = -1;\n        depth [root] = 0;\n        covered[root] = 1;\n        --uncoveredCnt;\n\n        /* ---- grow the tree from the chosen root ------------------- */\n        while (!q.empty()) q.pop();\n        q.push(root);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (depth[v] == LIMH) continue;              // depth limit\n            for (int nb : g[v]) if (!covered[nb]) {\n                covered[nb] = 1;\n                --uncoveredCnt;\n                parent[nb] = v;\n                depth [nb] = depth[v] + 1;\n                q.push(nb);\n            }\n        }\n    }\n\n    /* ---------- output --------------------------------------------- */\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << parent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Op{ char dir; int idx; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;                        // N is 20 in all official tests\n    if(!(cin>>N)) return 0;\n    vector<string> G(N);\n    for(int i=0;i<N;++i) cin>>G[i];\n\n    const int INF = 1e9;\n    auto clearUp=[&](int r,int c){\n        for(int i=0;i<r;++i) if(G[i][c]=='o') return false;\n        return true;\n    };\n    auto clearDown=[&](int r,int c){\n        for(int i=r+1;i<N;++i) if(G[i][c]=='o') return false;\n        return true;\n    };\n    auto clearLeft=[&](int r,int c){\n        for(int j=0;j<c;++j) if(G[r][j]=='o') return false;\n        return true;\n    };\n    auto clearRight=[&](int r,int c){\n        for(int j=c+1;j<N;++j) if(G[r][j]=='o') return false;\n        return true;\n    };\n\n    /*  maximum distance needed inside every (dir,line) group           */\n    array<array<int,20>,4> dist{};          // 0:U 1:D 2:L 3:R\n\n    for(int r=0;r<N;++r)for(int c=0;c<N;++c)if(G[r][c]=='x'){\n        int best = INF; char dir='?';\n\n        if(clearUp(r,c))    {int d=r+1;   if(d<best){best=d; dir='U';}}\n        if(clearDown(r,c))  {int d=N-r;   if(d<best){best=d; dir='D';}}\n        if(clearLeft(r,c))  {int d=c+1;   if(d<best){best=d; dir='L';}}\n        if(clearRight(r,c)) {int d=N-c;   if(d<best){best=d; dir='R';}}\n\n        switch(dir){\n            case 'U': dist[0][c] = max(dist[0][c], best); break;\n            case 'D': dist[1][c] = max(dist[1][c], best); break;\n            case 'L': dist[2][r] = max(dist[2][r], best); break;\n            case 'R': dist[3][r] = max(dist[3][r], best); break;\n            default:  break;       // should never happen\n        }\n    }\n\n    vector<Op> ops;\n    auto push = [&](char d,int idx,int cnt){\n        for(int k=0;k<cnt;++k) ops.push_back({d,idx});\n    };\n\n    /*  emit column groups (Up / Down)   */\n    for(int c=0;c<N;++c){\n        int d = dist[0][c];                 // upward\n        if(d>0){ push('U',c,d); push('D',c,d); }\n    }\n    for(int c=0;c<N;++c){\n        int d = dist[1][c];                 // downward\n        if(d>0){ push('D',c,d); push('U',c,d); }\n    }\n\n    /*  emit row groups (Left / Right)   */\n    for(int r=0;r<N;++r){\n        int d = dist[2][r];                 // leftward\n        if(d>0){ push('L',r,d); push('R',r,d); }\n    }\n    for(int r=0;r<N;++r){\n        int d = dist[3][r];                 // rightward\n        if(d>0){ push('R',r,d); push('L',r,d); }\n    }\n\n    /*  safety \u2013 the produced number is much smaller than 4 N\u00b2 anyway   */\n    if((int)ops.size() > 4*N*N){\n        ops.resize(4*N*N);\n    }\n\n    for(auto &o:ops) cout<<o.dir<<' '<<o.idx<<'\\n';\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n/* ------------------------------------------------------------------ */\n/*  small helper for timing                                            */\nstruct Timer {\n    chrono::steady_clock::time_point st;\n    Timer() { st = chrono::steady_clock::now(); }\n    double elapsed() const {\n        return chrono::duration<double>(chrono::steady_clock::now() - st)\n            .count();\n    }\n};\n/* ------------------------------------------------------------------ */\n\nstatic constexpr int N = 100;        // fixed in the task\nstatic constexpr int L = 500'000;    // fixed in the task\nstatic constexpr int STEP = L / (2 * N);   // 2500\nstatic constexpr int EDGE_CNT = 2 * N;     // 200\n\n/* ------------------------------------------------------------------ */\n/*  pick the optimal in-degrees k_i \u2208 {0\u20264} with \u03a3k = 200             */\nvector<int> choose_indeg(const vector<int>& T) {\n    vector<int> k(N, 0);\n\n    /* current error for every vertex */\n    auto err = [&](int i, int ki) -> int {\n        return abs(T[i] - STEP * ki);\n    };\n\n    int used = 0;\n    while (used < EDGE_CNT) {\n        int best_i = -1, best_gain = -1e9;\n        for (int i = 0; i < N; ++i) if (k[i] < 4) {\n            int gain = err(i, k[i]) - err(i, k[i] + 1);\n            if (gain > best_gain) {\n                best_gain = gain;\n                best_i = i;\n            }\n        }\n        /* even if gain is negative we have to add an edge */\n        ++k[best_i];\n        ++used;\n    }\n\n    /* guarantee reachability (except possibly vertex 0) */\n    for (int i = 0; i < N; ++i)\n        if (T[i] > 0 && k[i] == 0) {\n            /* steal from some vertex with k>1, minimal harm */\n            int worst_j = -1, worst_cost = 1e9;\n            for (int j = 0; j < N; ++j) if (k[j] > 1) {\n                int cost = err(j, k[j] - 1) - err(j, k[j]);\n                if (cost < worst_cost) { worst_cost = cost; worst_j = j; }\n            }\n            --k[worst_j];\n            ++k[i];\n        }\n    return k;\n}\n\n/* ------------------------------------------------------------------ */\n/*  rotor walk simulation                                              */\nll simulate(const vector<int>& a, const vector<int>& b,\n            const vector<int>& T, vector<int>& cnt) {\n\n    fill(cnt.begin(), cnt.end(), 0);\n    int cur = 0;\n    for (int w = 0; w < L; ++w) {\n        ++cnt[cur];                                 // this week\n        int nxt = (cnt[cur] & 1 ? a[cur] : b[cur]); // odd \u21d2 a , even \u21d2 b\n        cur = nxt;\n    }\n    ll err = 0;\n    for (int i = 0; i < N; ++i) err += llabs((ll)cnt[i] - T[i]);\n    return err;\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n_in, l_in;\n    if (!(cin >> n_in >> l_in)) return 0;           // safety\n    vector<int> T(N);\n    for (int &x : T) cin >> x;\n\n    /* --- decide in-degrees --- */\n    vector<int> indeg = choose_indeg(T);\n\n    /* multiset of destinations */\n    vector<int> baseDest;\n    baseDest.reserve(EDGE_CNT);\n    for (int v = 0; v < N; ++v)\n        for (int k = 0; k < indeg[v]; ++k)\n            baseDest.push_back(v);\n\n    mt19937 rng((uint32_t)chrono::steady_clock::now()\n                    .time_since_epoch().count());\n\n    Timer tim;\n\n    vector<int> bestA(N), bestB(N), cnt(N);\n    ll bestErr = (1LL << 60);\n\n    /* few thousand iterations easily fit into the limit */\n    while (tim.elapsed() < 1.9) {\n        vector<int> dest = baseDest;\n        shuffle(dest.begin(), dest.end(), rng);\n\n        /* assign two destinations to every source */\n        vector<int> a(N), b(N);\n        int pos = 0;\n        for (int s = 0; s < N; ++s) {\n            a[s] = dest[pos++];\n            b[s] = dest[pos++];\n        }\n\n        /* quick attempt to eliminate self-loops / duplicates */\n        for (int s = 0; s < N; ++s) {\n            if (a[s] == s || a[s] == b[s]) {\n                for (int t = 0; t < N; ++t) if (t != s &&\n                    a[t] != t && b[t] != t && a[t] != b[t]) {\n                    swap(a[s], a[t]);\n                    break;\n                }\n            }\n            if (b[s] == s || a[s] == b[s]) {\n                for (int t = 0; t < N; ++t) if (t != s &&\n                    a[t] != t && b[t] != t && a[t] != b[t]) {\n                    swap(b[s], b[t]);\n                    break;\n                }\n            }\n        }\n\n        ll err = simulate(a, b, T, cnt);\n        if (err < bestErr) {\n            bestErr = err;\n            bestA.swap(a);\n            bestB.swap(b);\n        }\n    }\n\n    /* output */\n    for (int i = 0; i < N; ++i)\n        cout << bestA[i] << ' ' << bestB[i] << '\\n';\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*------------------------------------------------------------*\n *  Hilbert curve order (integer coordinates 0 .. 16383)      *\n *------------------------------------------------------------*/\nstatic inline uint64_t hilbertOrder(int x, int y)\n{\n    const int BITS = 14;              // 2^14 = 16384 > 10000\n    uint64_t d = 0;\n    for (int s = BITS - 1; s >= 0; --s) {\n        int rx = (x >> s) & 1;\n        int ry = (y >> s) & 1;\n        uint64_t idx = (rx ^ ry) | (ry << 1);          // 0,1,2,3\n        d = (d << 2) | idx;\n        /* rotate */\n        if (!ry) {\n            if (rx) {\n                x = ((1 << BITS) - 1) - x;\n                y = ((1 << BITS) - 1) - y;\n            }\n            swap(x, y);\n        }\n    }\n    return d;\n}\n\n/* squared Euclidean distance of rectangle centres (for heuristics) */\nstatic inline int64_t dist2(int cx1, int cy1, int cx2, int cy2)\n{\n    int64_t dx = cx1 - cx2;\n    int64_t dy = cy1 - cy2;\n    return dx * dx + dy * dy;\n}\n\n/*------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ---------- */\n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n\n    vector<int> G(M);\n    for (int &g : G) cin >> g;\n\n    struct City {\n        int id;\n        int lx, rx, ly, ry;\n        int cx, cy;          // rectangle centre\n        uint64_t hil;        // Hilbert order\n    };\n    vector<City> city(N);\n\n    for (int i = 0; i < N; ++i) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        int cx = (lx + rx) / 2;\n        int cy = (ly + ry) / 2;\n        int sx = (cx * 16383) / 10000;      // scale to 0..16383\n        int sy = (cy * 16383) / 10000;\n        city[i] = { i, lx, rx, ly, ry, cx, cy, hilbertOrder(sx, sy) };\n    }\n\n    /* ---------- sort by Hilbert order ---------- */\n    vector<int> hilSorted(N);\n    iota(hilSorted.begin(), hilSorted.end(), 0);\n    sort(hilSorted.begin(), hilSorted.end(),\n         [&](int a, int b) { return city[a].hil < city[b].hil; });\n\n    /* ---------- build groups ---------- */\n    vector<vector<int>> groups(M);           // result container\n    vector<bool> taken(N, false);\n\n    /* Step A: all groups with size > 2\n       -> take consecutive cities on the Hilbert curve               */\n    size_t pos = 0;\n    for (int idx = 0; idx < M; ++idx) {\n        if (G[idx] > 2) {\n            groups[idx].reserve(G[idx]);\n            for (int k = 0; k < G[idx]; ++k) {\n                int v = hilSorted[pos++];\n                groups[idx].push_back(v);\n                taken[v] = true;\n            }\n        }\n    }\n\n    /* collect the still unassigned cities (they will be in 1- or 2-groups) */\n    vector<int> rest;\n    rest.reserve(N - pos);\n    for (size_t k = pos; k < hilSorted.size(); ++k) rest.push_back(hilSorted[k]);\n\n    /* count how many singles / pairs we need */\n    int needSingles = 0, needPairs = 0;\n    for (int g : G) {\n        if (g == 1) ++needSingles;\n        else if (g == 2) ++needPairs;\n    }\n\n    /* ---------- build good pairs for size-2 groups ---------- */\n    vector<pair<int,int>> pairList;          // will contain exactly needPairs pairs\n    pairList.reserve(needPairs);\n\n    /* Greedy nearest-neighbour matching on the still free cities             */\n    while ((int)pairList.size() < needPairs) {\n        int a = rest.back();\n        rest.pop_back();\n\n        int bestIdx = -1;\n        int64_t bestD = (1LL << 60);\n        for (int i = 0; i < (int)rest.size(); ++i) {\n            int b = rest[i];\n            int64_t d = dist2(city[a].cx, city[a].cy, city[b].cx, city[b].cy);\n            if (d < bestD) {\n                bestD = d;\n                bestIdx = i;\n            }\n        }\n        int b = rest[bestIdx];\n        rest[bestIdx] = rest.back();\n        rest.pop_back();\n\n        pairList.emplace_back(a, b);\n        taken[a] = taken[b] = true;\n    }\n    /* the remaining cities will be the singles */\n    vector<int> singles = move(rest);\n    assert((int)singles.size() == needSingles);\n\n    /* ---------- fill the still empty groups (size 1 and 2) ---------- */\n    int curPair = 0, curSingle = 0;\n    for (int idx = 0; idx < M; ++idx) {\n        if (!groups[idx].empty()) continue;      // already assigned (size>2)\n        if (G[idx] == 1) {\n            groups[idx] = { singles[curSingle++] };\n        } else {                                 // size == 2\n            groups[idx] = { pairList[curPair].first, pairList[curPair].second };\n            ++curPair;\n        }\n    }\n\n    /* ---------- build edge lists ---------- */\n    vector<vector<pair<int,int>>> edges(M);\n    int queries_used = 0;\n\n    auto do_query = [&](const vector<int>& subset, vector<pair<int,int>>& ed)\n    {\n        int sz = subset.size();\n        cout << \"? \" << sz;\n        for (int v : subset) cout << ' ' << v;\n        cout << '\\n' << flush;\n\n        ed.reserve(sz - 1);\n        for (int k = 0; k < sz - 1; ++k) {\n            int a, b; cin >> a >> b;\n            ed.emplace_back(a, b);\n        }\n    };\n\n    for (int i = 0; i < M; ++i) {\n        int sz = groups[i].size();\n        edges[i].clear();\n        if (sz <= 1) continue;\n        if (sz == 2) {\n            edges[i].push_back({groups[i][0], groups[i][1]});\n            continue;\n        }\n        if (3 <= sz && sz <= L && queries_used < Q) {\n            do_query(groups[i], edges[i]);\n            ++queries_used;\n        } else {          // fallback: simple chain\n            for (int k = 1; k < sz; ++k)\n                edges[i].push_back({groups[i][k-1], groups[i][k]});\n        }\n    }\n\n    /* ---------- output answer ---------- */\n    cout << \"!\\n\";\n    for (int i = 0; i < M; ++i) {\n        /* list of cities */\n        for (int k = 0; k < (int)groups[i].size(); ++k) {\n            if (k) cout << ' ';\n            cout << groups[i][k];\n        }\n        cout << '\\n';\n        /* roads (exactly |group|-1 lines) */\n        for (auto [a,b] : edges[i]) cout << a << ' ' << b << '\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Step {\n    char act; // 'M' or 'S'\n    char dir; // 'U','D','L','R'\n};\nconst int N = 20;\nconst int SZ = N * N;\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char DIRC[4] = {'U', 'D', 'L', 'R'};\n\ninline int id(int r, int c) { return r * N + c; }\ninline pair<int,int> rc(int v){ return {v / N, v % N}; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    vector<int> px, py;\n    {\n        int n_in;\n        if(!(cin >> n_in >> M)) return 0; // N is always 20\n        px.resize(M);\n        py.resize(M);\n        for (int k = 0; k < M; ++k) cin >> px[k] >> py[k];\n    }\n\n    vector<Step> answer;\n    vector<int> dist(SZ);\n    vector<int> prevv(SZ);\n    vector<char> preva(SZ);\n    vector<char> prevd(SZ);\n    deque<int> q;\n\n    int cur = id(px[0], py[0]);\n    for (int tgtIdx = 1; tgtIdx < M; ++tgtIdx) {\n        int goal = id(px[tgtIdx], py[tgtIdx]);\n\n        // BFS\n        fill(dist.begin(), dist.end(), -1);\n        q.clear();\n        dist[cur] = 0;\n        q.push_back(cur);\n\n        while (!q.empty()) {\n            int v = q.front(); q.pop_front();\n            if (v == goal) break;\n            auto [r, c] = rc(v);\n            for (int d = 0; d < 4; ++d) {\n                // Move\n                int nr = r + dx[d], nc = c + dy[d];\n                if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                    int nv = id(nr, nc);\n                    if (dist[nv] == -1) {\n                        dist[nv] = dist[v] + 1;\n                        prevv[nv] = v;\n                        preva[nv] = 'M';\n                        prevd[nv] = DIRC[d];\n                        q.push_back(nv);\n                    }\n                }\n                // Slide\n                int sr = r, sc = c;\n                while (true) {\n                    int tr = sr + dx[d], tc = sc + dy[d];\n                    if (tr < 0 || tr >= N || tc < 0 || tc >= N) break;\n                    sr = tr; sc = tc;\n                }\n                int sv = id(sr, sc);\n                if (sv != v && dist[sv] == -1) {\n                    dist[sv] = dist[v] + 1;\n                    prevv[sv] = v;\n                    preva[sv] = 'S';\n                    prevd[sv] = DIRC[d];\n                    q.push_back(sv);\n                }\n            }\n        }\n\n        // Reconstruct path\n        vector<Step> chunk;\n        for (int v = goal; v != cur; v = prevv[v]) {\n            chunk.push_back({preva[v], prevd[v]});\n        }\n        reverse(chunk.begin(), chunk.end());\n        answer.insert(answer.end(), chunk.begin(), chunk.end());\n        cur = goal;\n    }\n\n    // Output\n    for (auto &st : answer) cout << st.act << ' ' << st.dir << '\\n';\n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\nstruct Rect { int a, b, c, d; };          // [a,c) \u00d7 [b,d)\n\n/* --------- helpers ------------------------------------------------------- */\ninline bool intersect(const Rect& A, const Rect& B) {\n    return max(A.a, B.a) < min(A.c, B.c) &&\n           max(A.b, B.b) < min(A.d, B.d);          // positive area?\n}\ninline double sat(long long need, long long have) {\n    double mi = (double)min(need, have);\n    double ma = (double)max(need, have);\n    double r  = mi / ma;\n    double t  = 1.0 - r;                // 1-ratio\n    return 1.0 - t * t;\n}\n/* ------------------------------------------------------------------------ */\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* -------- read input ------------------------------------------------- */\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    constexpr int W = 10000;\n    mt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<double> rd01(0.0, 1.0);\n\n    /* -------- initial 1\u00d71 rectangles ------------------------------------ */\n    vector<Rect> rect(n);\n    vector<long long> area(n, 1);\n    vector<double> p(n);\n    double score = 0.0;\n    for (int i = 0; i < n; ++i) {\n        rect[i] = {x[i], y[i], x[i] + 1, y[i] + 1};\n        p[i] = sat(r[i], 1);\n        score += p[i];\n    }\n    double bestScore = score;\n    auto bestRect   = rect;\n    auto bestArea   = area;\n    auto bestP      = p;\n\n    /* -------- simulated annealing --------------------------------------- */\n    const double TIME_LIMIT = 4.9;           // seconds\n    const double T0 = 5e-2, T1 = 1e-4;       // temperatures\n    const auto   T_start = chrono::steady_clock::now();\n\n    while (true) {\n        double elapsed = chrono::duration<double>(\n                             chrono::steady_clock::now() - T_start).count();\n        if (elapsed > TIME_LIMIT) break;\n        double temp = T0 + (T1 - T0) * (elapsed / TIME_LIMIT);\n\n        /* choose victim rectangle ---------------------------------------- */\n        int i = rng() % n;\n        long long diff = r[i] - area[i];\n        bool wantExpand = diff > 0;\n        bool expand = wantExpand;\n        if (rd01(rng) < 0.20) expand = !expand;      // 20 % opposite\n\n        int dir = rng() & 3;                         // 0 L,1 R,2 D,3 U\n        Rect old = rect[i], neu = old;\n        int deltaMax = 0;\n\n        auto width  = old.c - old.a;\n        auto height = old.d - old.b;\n\n        switch (dir) {\n            case 0: // left side\n                deltaMax = expand ? old.a\n                                   : min(width - 1, x[i] - old.a);\n                break;\n            case 1: // right side\n                deltaMax = expand ? (W - old.c)\n                                   : min(width - 1, old.c - (x[i] + 1));\n                break;\n            case 2: // bottom side\n                deltaMax = expand ? old.b\n                                   : min(height - 1, y[i] - old.b);\n                break;\n            default: // top side\n                deltaMax = expand ? (W - old.d)\n                                   : min(height - 1, old.d - (y[i] + 1));\n        }\n        if (deltaMax <= 0) continue;\n\n        /* choose \u0394 ------------------------------------------------------- */\n        int delta = 1;\n        if (expand) {\n            long long need = llabs(diff);\n            if (dir <= 1) {                    // changing width\n                long long per = height;\n                delta = (int)min<long long>(deltaMax,\n                        max<long long>(1, (need + per - 1) / per));\n            } else {                           // changing height\n                long long per = width;\n                delta = (int)min<long long>(deltaMax,\n                        max<long long>(1, (need + per - 1) / per));\n            }\n        } else {\n            delta = 1 + (rng() % deltaMax);\n        }\n\n        /* apply the move ------------------------------------------------- */\n        if (expand) {\n            if (dir == 0) neu.a -= delta;\n            if (dir == 1) neu.c += delta;\n            if (dir == 2) neu.b -= delta;\n            if (dir == 3) neu.d += delta;\n        } else {\n            if (dir == 0) neu.a += delta;\n            if (dir == 1) neu.c -= delta;\n            if (dir == 2) neu.b += delta;\n            if (dir == 3) neu.d -= delta;\n        }\n\n        /* overlap test --------------------------------------------------- */\n        bool ok = true;\n        for (int j = 0; j < n && ok; ++j)\n            if (j != i && intersect(neu, rect[j])) ok = false;\n        if (!ok) continue;\n\n        long long newArea = 1LL * (neu.c - neu.a) * (neu.d - neu.b);\n        double  new_p = sat(r[i], newArea);\n        double  dScore = new_p - p[i];\n\n        if (dScore >= 0.0 || rd01(rng) < exp(dScore / temp)) {\n            /* accept move ------------------------------------------------ */\n            rect[i]  = neu;\n            area[i]  = newArea;\n            p[i]     = new_p;\n            score   += dScore;\n            if (score > bestScore) {\n                bestScore = score;\n                bestRect  = rect;\n                bestArea  = area;\n                bestP     = p;\n            }\n        }\n    }\n\n    /* -------- output best rectangles ------------------------------------ */\n    for (int i = 0; i < n; ++i)\n        cout << bestRect[i].a << ' ' << bestRect[i].b << ' '\n             << bestRect[i].c << ' ' << bestRect[i].d << '\\n';\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ------------ fast RNG : xoroshiro128+ ------------ */\nstruct Xoroshiro {\n    using ull = unsigned long long;\n    ull s[2];\n    static ull rotl(ull x,int k){ return (x<<k)|(x>>(64-k)); }\n    static ull splitmix64(ull &x){ ull z=(x+=0x9e3779b97f4a7c15ULL);\n        z=(z^(z>>30))*0xbf58476d1ce4e5b9ULL; z=(z^(z>>27))*0x94d049bb133111ebULL;\n        return z^(z>>31); }\n    Xoroshiro(ull seed=0x123456789abcdefULL){\n        ull x=seed?seed:0xfeedbeefcafef00dULL;\n        s[0]=splitmix64(x); s[1]=splitmix64(x);\n    }\n    ull next(){ ull t=s[0]+s[1]; ull x=s[0]; ull y=s[1];\n        s[1]^=x; s[0]=rotl(x,24)^y^(y<<16); s[1]=rotl(y,37); return t; }\n    int randint(int n){ return int(next()%n); }\n    double real01(){ return (next()>>11)*(1.0/9007199254740992.0); } // /2^53\n};\n\n/* ------------ constants, helpers ------------------ */\nconstexpr int H=50, W=50, DIR=4;\nint dr[DIR]={-1,1,0,0};\nint dc[DIR]={0,0,-1,1};\nchar dch[DIR]={'U','D','L','R'};\ninline int cid(int r,int c){return r*W+c;}\n\n/* ------------ input data -------------------------- */\nint si,sj;\nint tile[H][W];\nint val [H][W];\nint lost[H][W];                   // value of the *other* cell in the same tile\nint M;                            // number of tiles\narray<int,DIR> diffNbr[H*W];      // neighbour of *different* tile or -1\n\n/* ================================================== */\n/* ---------- one greedy walk with/without 2-ply -----*/\nstruct Walk { long long score; string path; };\n\nWalk single_walk(Xoroshiro& rng, vector<char>& visited_tile)\n{\n    /* parameters of this run (tuned to safe ranges) */\n    bool use_two_ply = (rng.randint(3)==0);          // \u2248 33 % of the walks\n    int  lambda       = rng.randint(41)+10;          // 10 \u2026 50\n    const double alpha = 0.25;                       // domino penalty\n    const double beta  = 0.55;                       // weight of 2nd ply\n\n    /* state --------------------------------------------------- */\n    fill(visited_tile.begin(), visited_tile.end(), 0);\n    string path; path.reserve(H*W);\n\n    int r=si, c=sj;\n    visited_tile[tile[r][c]] = 1;\n    long long total = val[r][c];\n\n    /* helper for small on-the-fly shuffle of 4 chars */\n    auto random_order = [&](int *a){\n        a[0]=0;a[1]=1;a[2]=2;a[3]=3;\n        for(int i=3;i>0;--i) swap(a[i],a[rng.randint(i+1)]);\n    };\n\n    /* main loop ---------------------------------------------- */\n    while(true){\n        int bestDir=-1;\n        double bestEval=-1e100;\n        int order[4]; random_order(order);\n\n        int curId = cid(r,c);\n\n        for(int k=0;k<DIR;++k){\n            int d = order[k];\n            int nid = diffNbr[curId][d];\n            if(nid==-1) continue;\n\n            int nr=nid/W, nc=nid%W, tId=tile[nr][nc];\n            if(visited_tile[tId]) continue;\n\n            /* --- degree after entering this neighbour --------*/\n            int deg1=0;\n            for(int d2=0; d2<DIR; ++d2){\n                int nnid = diffNbr[nid][d2];\n                if(nnid==-1) continue;\n                int t2 = tile[nnid/W][nnid%W];\n                if(t2==tId || visited_tile[t2]) continue;\n                ++deg1;\n            }\n            double eval = val[nr][nc] - alpha*lost[nr][nc] + lambda*deg1;\n\n            /* --- shallow 2-ply look-ahead (optional) ---------*/\n            if(use_two_ply){\n                double best2=-1e100;\n                for(int d2=0; d2<DIR; ++d2){\n                    int nnid = diffNbr[nid][d2];\n                    if(nnid==-1) continue;\n                    int rr=nnid/W, cc=nnid%W, tt=tile[rr][cc];\n                    if(tt==tId || visited_tile[tt]) continue;\n\n                    int deg2=0;\n                    for(int d3=0; d3<DIR; ++d3){\n                        int n3 = diffNbr[nnid][d3];\n                        if(n3==-1) continue;\n                        int t3 = tile[n3/W][n3%W];\n                        if(t3==tId || t3==tt || visited_tile[t3]) continue;\n                        ++deg2;\n                    }\n                    double ev2 = val[rr][cc] - alpha*lost[rr][cc] + lambda*deg2;\n                    if(ev2>best2) best2=ev2;\n                }\n                if(best2>-1e90) eval += beta*best2;\n            }\n\n            eval += rng.randint(3)*1e-3; // tiny noise for tie-break\n            if(eval>bestEval){ bestEval=eval; bestDir=d; }\n        }\n\n        if(bestDir==-1) break;           // dead end\n\n        /* perform the chosen move */\n        r += dr[bestDir];  c += dc[bestDir];\n        visited_tile[ tile[r][c] ] = 1;\n        total += val[r][c];\n        path.push_back( dch[bestDir] );\n    }\n    return {total, std::move(path)};\n}\n\n/* =================================================== */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ------------ read input ----------------------- */\n    cin >> si >> sj;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cin >> tile[i][j];\n    M = 0;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) M = max(M, tile[i][j]+1);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cin >> val[i][j];\n\n    /* ------------ lost value per cell -------------- */\n    vector<vector<pair<int,int>>> cells_of(M);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cells_of[tile[i][j]].push_back({i,j});\n    for(int t=0;t<M;++t){\n        if(cells_of[t].size()==2){\n            auto [r1,c1]=cells_of[t][0]; auto [r2,c2]=cells_of[t][1];\n            lost[r1][c1]=val[r2][c2]; lost[r2][c2]=val[r1][c1];\n        }else{\n            for(auto [r,c]:cells_of[t]) lost[r][c]=0;\n        }\n    }\n\n    /* ------------ neighbours of *different* tiles -- */\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        for(int d=0;d<DIR;++d){\n            int ni=i+dr[d], nj=j+dc[d];\n            if(ni<0||nj<0||ni>=H||nj>=W||tile[ni][nj]==tile[i][j]) diffNbr[cid(i,j)][d]=-1;\n            else diffNbr[cid(i,j)][d]=cid(ni,nj);\n        }\n    }\n\n    /* ------------ iterative improvement ------------ */\n    Xoroshiro rng( chrono::high_resolution_clock::now()\n                  .time_since_epoch().count() );\n    vector<char> visited_tile(M,0);\n    auto time_limit = chrono::steady_clock::now() + chrono::milliseconds(1950);\n\n    long long   bestScore = -1;\n    string      bestPath;\n\n    while(chrono::steady_clock::now() < time_limit){\n        auto res = single_walk(rng, visited_tile);\n        if(res.score > bestScore){\n            bestScore = res.score;\n            bestPath.swap(res.path);\n        }\n    }\n\n    cout << bestPath << '\\n';\n    return 0;\n}","ahc003":"/*****************************************************************************\n *  AHC003 \u2013 UCB-guided exploration + hybrid learning                        *\n *                                                                           *\n *  compile:  g++ -std=c++20 -O2 -pipe -static -s main.cpp                   *\n *****************************************************************************/\n#include <bits/stdc++.h>\nusing namespace std;\n\n/*** --- fixed grid description ------------------------------------------ ***/\nconstexpr int H = 30, W = 30;\nconstexpr int HOR = H * (W - 1);\nconstexpr int VER = (H - 1) * W;\nconstexpr int E   = HOR + VER;\n\nint horId[H][W-1];\nint verId[H-1][W];\n\nstruct Edge { int to, id; };           // adjacency entry\narray<array<array<Edge,4>, W>, H> adj;\n\nvoid build_graph() {\n    int id = 0;\n    for(int i=0;i<H;i++) for(int j=0;j<W-1;j++) horId[i][j]=id++;\n    for(int i=0;i<H-1;i++) for(int j=0;j<W  ;j++) verId[i][j]=id++;\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++) adj[i][j][d].id = -1;\n\n    for(int i=0;i<H;i++) for(int j=0;j<W;j++){\n        if(i)          adj[i][j][0]={ (i-1)*W+j , verId[i-1][j] };\n        if(i+1<H)      adj[i][j][1]={ (i+1)*W+j , verId[i][j]   };\n        if(j)          adj[i][j][2]={  i   *W+j-1 , horId[i][j-1] };\n        if(j+1<W)      adj[i][j][3]={  i   *W+j+1 , horId[i][j]   };\n    }\n}\n\n/*** --- state of our model ---------------------------------------------- ***/\nconstexpr double INIT_W   = 5000.0;\nconstexpr double MIN_W    =  100.0;\nconstexpr double MAX_W    = 20000.0;\n\narray<double,E> w;             // current estimate of every edge\narray<int   ,E> cnt;           // how many times the edge appeared\n\n/*** --- random helpers --------------------------------------------------- ***/\nmt19937 rng( (uint64_t)chrono::high_resolution_clock::now()\n             .time_since_epoch().count() );\nuniform_real_distribution<double> unif01(0.0,1.0);\ninline double rand_pm(double amp){ return (unif01(rng)*2.0-1.0)*amp; }\n\n/*** --- shortest path (Dijkstra) ---------------------------------------- ***/\nstruct Node {\n    double dist; int v;\n    bool operator<(const Node& o) const { return dist > o.dist; } // min-heap\n};\n\nconstexpr double B_UCB    = 1200.0; // optimistic discount\nconstexpr double NOISE_A  = 0.80;   // \u00b180 % when random exploration\n\nvector<int> dijkstra(int si,int sj,int ti,int tj,bool exploring){\n    array<double,H*W> dist; dist.fill(1e100);\n    array<int   ,H*W> prvV, prvE; prvE.fill(-1);\n    dist[si*W+sj]=0.0;\n    priority_queue<Node> pq;\n    pq.push({0.0, si*W+sj});\n\n    while(!pq.empty()){\n        auto [d,v]=pq.top(); pq.pop();\n        if(d!=dist[v]) continue;\n        if(v==ti*W+tj) break;\n        int vi=v/W, vj=v%W;\n        for(int dir=0;dir<4;dir++){\n            auto [to,eid]=adj[vi][vj][dir];\n            if(eid<0) continue;\n\n            /* optimistic weight ------------------------------------------------*/\n            double ww = w[eid];\n            ww -= B_UCB / sqrt(cnt[eid]+1.0);              // optimism\n            if(exploring) ww *= 1.0 + rand_pm(NOISE_A);    // extra shake\n            ww = max(50.0, ww);                            // keep positive\n\n            double nd = d + ww;\n            if(nd < dist[to]){\n                dist[to]=nd;\n                prvV[to]=v;\n                prvE[to]=eid;\n                pq.push({nd,to});\n            }\n        }\n    }\n    /* build edge list --------------------------------------------------------*/\n    vector<int> edges;\n    for(int cur=ti*W+tj; cur!=si*W+sj; cur=prvV[cur])\n        edges.push_back(prvE[cur]);\n    reverse(edges.begin(), edges.end());\n    return edges;\n}\n\n/*** --- path string ------------------------------------------------------ ***/\nstring build_path(int si,int sj,const vector<int>& edges){\n    string res;\n    int i=si,j=sj;\n    for(int eid:edges){\n        if(eid < HOR){                 // horizontal edge\n            int row=eid/(W-1), col=eid%(W-1);\n            if(i==row && j==col){ res.push_back('R'); ++j; }\n            else                 { res.push_back('L'); --j; }\n        }else{                         // vertical edge\n            int id2=eid-HOR;\n            int row=id2/W, col=id2%W;\n            if(i==row && j==col){ res.push_back('D'); ++i; }\n            else                 { res.push_back('U'); --i; }\n        }\n    }\n    return res;\n}\n\n/*** --- learning --------------------------------------------------------- ***/\nconstexpr int  MUL_PHASE = 200;    // first 200 queries \u2192 multiplicative\nconstexpr double ETA_MUL = 0.6;    // base rate for multiplicative part\nconstexpr double ETA_ADD = 1.0;    // base rate for additive part\n\nvoid learn_mul(const vector<int>& edges, double ratio){\n    for(int e:edges){\n        double eta = ETA_MUL / sqrt(cnt[e]+1.0);\n        w[e] *= pow(ratio, eta);\n        w[e] = min(MAX_W, max(MIN_W, w[e]));\n        ++cnt[e];\n    }\n}\nvoid learn_add(const vector<int>& edges, double diff, double pred){\n    for(int e:edges){\n        double eta = ETA_ADD / sqrt(cnt[e]+1.0);\n        w[e] += eta * diff * (w[e]/pred);          // proportional additive\n        w[e] = min(MAX_W, max(MIN_W, w[e]));\n        ++cnt[e];\n    }\n}\n\n/*** --- main loop -------------------------------------------------------- ***/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    build_graph();\n    w.fill(INIT_W);\n    cnt.fill(0);\n\n    const int FORCED_EXP  = 100;      // first 100 queries always exploring\n    const double P_EXP0   = 0.35;     // afterwards: geometric decay\n    const double EXP_DEC  = 0.995;\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        /* ---- decide whether to explore this query ---------------------- */\n        bool exploring;\n        if(q < FORCED_EXP) exploring = true;\n        else exploring = unif01(rng) < P_EXP0 * pow(EXP_DEC, q-FORCED_EXP);\n\n        auto edges = dijkstra(si,sj,ti,tj, exploring);\n        string path = build_path(si,sj,edges);\n        cout << path << '\\n' << flush;\n\n        long long measLL; cin >> measLL;\n        double measured = static_cast<double>(measLL);\n\n        /* ---- prediction ------------------------------------------------ */\n        double pred = 0.0;\n        for(int e:edges) pred += w[e];\n\n        if(pred <= 0.0) pred = 1.0;           // safety\n        double ratio = measured / pred;\n        double diff  = measured - pred;\n\n        if(q < MUL_PHASE)  learn_mul(edges, ratio);\n        else               learn_add(edges, diff, pred);\n    }\n    return 0;\n}","ahc004":"//  g++ -std=c++20 -O2 -pipe -static -s\n#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N  = 20;     // matrix size (fixed)\nconstexpr int CH = 8;      // A..H\nconstexpr int MAXLEN = 12; // max length of s_i\n\nstruct Placement {\n    uint8_t len;                  // length of the string\n    uint16_t cell[MAXLEN];        // linear cell id (0..399)\n    uint8_t  letter[MAXLEN];      // 0..7\n};\nstruct Watch {\n    int sid;          // string id\n    int pid;          // placement id within that string\n    uint8_t letter;   // letter required in this cell by that placement\n};\n\nint c2i(char c){ return c-'A'; }\nchar i2c(int x){ return 'A'+x; }\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;  /* N is fixed 20 */\n    cin >> std::ws;\n    cin.ignore(numeric_limits<streamsize>::max(),' '); // throw away N\n    cin >> M;\n    vector<string> S(M);\n    for(auto& s:S) cin >> s;\n\n    /*------------------------------------------------------------------*\n     * 1. enumerate every placement                                     *\n     *------------------------------------------------------------------*/\n    vector<vector<Placement>> plac(M);\n    vector<vector<char>> active(M);        // 1 = still alive\n    vector<vector<Watch>> watchers(N*N);   // placements touching each cell\n\n    for(int sid=0; sid<M; ++sid){\n        const string& s = S[sid];\n        const int L = (int)s.size();\n        plac[sid].reserve(800);\n        /* horizontal */\n        for(int row=0; row<N; ++row)\n            for(int st=0; st<N; ++st){\n                Placement p; p.len=L;\n                for(int k=0;k<L;++k){\n                    int col=(st+k)%N;\n                    int cell=row*N+col;\n                    p.cell[k]=cell;\n                    p.letter[k]=c2i(s[k]);\n                }\n                int pid=plac[sid].size();\n                plac[sid].push_back(p);\n                for(int k=0;k<L;++k)\n                    watchers[p.cell[k]].push_back({sid,pid,p.letter[k]});\n            }\n        /* vertical */\n        for(int col=0; col<N; ++col)\n            for(int st=0; st<N; ++st){\n                Placement p; p.len=L;\n                for(int k=0;k<L;++k){\n                    int row=(st+k)%N;\n                    int cell=row*N+col;\n                    p.cell[k]=cell;\n                    p.letter[k]=c2i(s[k]);\n                }\n                int pid=plac[sid].size();\n                plac[sid].push_back(p);\n                for(int k=0;k<L;++k)\n                    watchers[p.cell[k]].push_back({sid,pid,p.letter[k]});\n            }\n        active[sid].assign(plac[sid].size(),1);\n    }\n\n    /*------------------------------------------------------------------*\n     * 2. propagation of forced letters                                 *\n     *------------------------------------------------------------------*/\n    vector<int8_t> fixed(N*N,-1); // -1 = unknown, else 0..7\n    bool changed=true;\n    while(changed){\n        changed=false;\n        /* remove placements inconsistent with already fixed letters */\n        for(int sid=0; sid<M; ++sid){\n            auto &v = plac[sid];\n            auto &alive = active[sid];\n            for(int pid=0,sz=v.size(); pid<sz; ++pid){\n                if(!alive[pid]) continue;\n                const Placement& p=v[pid];\n                bool ok=true;\n                for(int k=0;k<p.len && ok;++k){\n                    int c = p.cell[k];\n                    if(fixed[c]!=-1 && fixed[c]!=p.letter[k]) ok=false;\n                }\n                if(!ok){ alive[pid]=0; changed=true; }\n            }\n        }\n        /* fix cells that now have only one possible letter */\n        for(int cell=0; cell<N*N; ++cell){\n            if(fixed[cell]!=-1) continue;\n            uint8_t mask=0;\n            for(const auto& w: watchers[cell])\n                if(active[w.sid][w.pid]) mask |= (1u<<w.letter);\n            if(mask && (mask & (mask-1))==0){           // power of two\n                fixed[cell]=__builtin_ctz(mask);\n                changed=true;\n            }\n        }\n    }\n\n    /*------------------------------------------------------------------*\n     * 3. greedy assignment (strings with fewer choices first)          *\n     *------------------------------------------------------------------*/\n    mt19937 rng(712367); // deterministic, change for randomisation\n    vector<int> aliveCnt(M);\n    for(int i=0;i<M;++i){\n        aliveCnt[i]=accumulate(begin(active[i]),end(active[i]),0);\n    }\n    vector<int> order(M); iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),\n         [&](int a,int b){ return aliveCnt[a]<aliveCnt[b]; });\n\n    for(int sid:order){\n        int bestPid=-1, bestNew=99;\n        for(int pid=0,sz=plac[sid].size(); pid<sz; ++pid){\n            if(!active[sid][pid]) continue;\n            const auto& p = plac[sid][pid];\n            bool ok=true; int newCnt=0;\n            for(int k=0;k<p.len && ok;++k){\n                int c = p.cell[k];\n                if(fixed[c]!=-1 && fixed[c]!=p.letter[k]) ok=false;\n                else if(fixed[c]==-1) ++newCnt;\n            }\n            if(!ok) continue;\n            if(newCnt<bestNew || (newCnt==bestNew && rng()%2)){\n                bestNew=newCnt; bestPid=pid;\n            }\n        }\n        if(bestPid==-1) continue;                 // cannot place this string\n        const auto& p=plac[sid][bestPid];\n        /* fix the cells decided by this placement */\n        for(int k=0;k<p.len;++k){\n            int c=p.cell[k];\n            if(fixed[c]==p.letter[k]) continue;\n            fixed[c]=p.letter[k];\n            /* eliminate incompatible placements touching this cell */\n            for(const auto& w: watchers[c]){\n                if(!active[w.sid][w.pid]) continue;\n                if(w.letter!=fixed[c]){\n                    active[w.sid][w.pid]=0;\n                    --aliveCnt[w.sid];\n                }\n            }\n        }\n    }\n\n    /*------------------------------------------------------------------*\n     * 4. fill remaining unknown cells arbitrarily                      *\n     *------------------------------------------------------------------*/\n    uniform_int_distribution<int> d8(0,7);\n    for(int c=0;c<N*N;++c)\n        if(fixed[c]==-1) fixed[c]=d8(rng);\n\n    /*------------------------------------------------------------------*\n     * 5. output                                                        *\n     *------------------------------------------------------------------*/\n    for(int r=0;r<N;++r){\n        for(int c=0;c<N;++c) cout << i2c(fixed[r*N+c]);\n        cout << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst int INF = 1e9;\n\n/*---------------------------------------------------------------------*/\n/* small grid helpers                                                  */\nconst int di[4]={-1,1,0,0};\nconst int dj[4]={0,0,-1,1};\nconst char dch[4]={'U','D','L','R'};\ninline bool inside(int x,int n){ return 0<=x && x<n; }\n\n/*---------------------------------------------------------------------*/\n/* 1.  Build the covering set                                          */\nstruct CoverBuilder{\n    int N, NN;\n    vector<string> S;\n    vector<char> isRoad, cost;\n    vector<int> rowRunOf, colRunOf;\n    vector<vector<int>> rowRuns, colRuns;\n    vector<int> points;                           // without the start cell\n\n    CoverBuilder(int N_, vector<string>&& src): N(N_), NN(N_*N_), S(src){\n        isRoad.assign(NN,0); cost.assign(NN,0);\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)\n            if(S[i][j] != '#'){ isRoad[id(i,j)]=1; cost[id(i,j)]=S[i][j]-'0'; }\n        buildRuns();\n    }\n    int id(int i,int j) const { return i*N+j; }\n\n    void buildRuns(){\n        rowRunOf.assign(NN,-1); colRunOf.assign(NN,-1);\n\n        /* horizontal runs */\n        for(int i=0;i<N;i++){\n            for(int j=0;j<N;){\n                if(!isRoad[id(i,j)]){ ++j; continue; }\n                vector<int> cells;\n                while(j<N && isRoad[id(i,j)]){ cells.push_back(id(i,j)); ++j; }\n                int r=rowRuns.size();\n                for(int v:cells) rowRunOf[v]=r;\n                rowRuns.push_back(move(cells));\n            }\n        }\n        /* vertical runs */\n        for(int j=0;j<N;j++){\n            for(int i=0;i<N;){\n                if(!isRoad[id(i,j)]){ ++i; continue; }\n                vector<int> cells;\n                while(i<N && isRoad[id(i,j)]){ cells.push_back(id(i,j)); ++i; }\n                int c=colRuns.size();\n                for(int v:cells) colRunOf[v]=c;\n                colRuns.push_back(move(cells));\n            }\n        }\n    }\n\n    vector<int> build(int si,int sj){\n        int start = id(si,sj);\n        int H = rowRuns.size(), V = colRuns.size();\n        vector<char> hCov(H,0), vCov(V,0), taken(NN,0);\n\n        auto add=[&](int cell){\n            if(cell!=start && !taken[cell]){\n                taken[cell]=1; points.push_back(cell);\n            }\n        };\n        hCov[rowRunOf[start]] = 1;\n        vCov[colRunOf[start]] = 1;\n\n        /* pairing pass \u2013 pick *cheapest* cell that covers both an uncovered row\n           and an uncovered column                                           */\n        for(int r=0;r<H;r++) if(!hCov[r]){\n            int best=-1, bestCost=INF;\n            for(int cell: rowRuns[r]){\n                int c = colRunOf[cell];\n                if(!vCov[c] && cost[cell] < bestCost){\n                    bestCost = cost[cell]; best = cell;\n                }\n            }\n            if(best!=-1){\n                hCov[r]=1; vCov[colRunOf[best]]=1;\n                add(best);\n            }\n        }\n\n        /* remaining horizontal runs \u2013 cheapest digit in that run           */\n        for(int r=0;r<H;r++) if(!hCov[r]){\n            int best=rowRuns[r][0];\n            for(int cell: rowRuns[r])\n                if(cost[cell] < cost[best]) best = cell;\n            hCov[r]=1; add(best);\n        }\n\n        /* remaining vertical runs \u2013 cheapest digit in that run             */\n        for(int c=0;c<V;c++) if(!vCov[c]){\n            int best=colRuns[c][0];\n            for(int cell: colRuns[c])\n                if(cost[cell] < cost[best]) best = cell;\n            vCov[c]=1; add(best);\n        }\n        return points;\n    }\n};\n\n/*---------------------------------------------------------------------*/\n/* 2.  All-pairs shortest paths between the chosen squares              */\nstruct APSP{\n    int N, NN, K;\n    const vector<char>& cost;\n    const vector<char>& isRoad;\n    const vector<int>& nodes;                   // grid-ids of the view points\n\n    vector<vector<int>> dist;\n    vector<vector<string>> path;\n\n    APSP(int N_, const vector<char>& c, const vector<char>& rd,\n         const vector<int>& nd)\n        : N(N_), NN(N_*N_), cost(c), isRoad(rd), nodes(nd)\n    {\n        K = nodes.size();\n        dist.assign(K, vector<int>(K, INF));\n        path.resize(K, vector<string>(K));\n        build();\n    }\n    int id(int i,int j) const { return i*N+j; }\n\n    void build(){\n        /* adjacency (grid) */\n        vector<array<int,4>> nb(NN);\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            int idx=id(i,j);\n            for(int k=0;k<4;k++){\n                int ni=i+di[k], nj=j+dj[k];\n                nb[idx][k] = inside(ni,N)&&inside(nj,N)&&isRoad[id(ni,nj)]\n                              ? id(ni,nj) : -1;\n            }\n        }\n        vector<int> d(NN), par(NN);\n        vector<char> pdir(NN);\n        using P=pair<int,int>;\n        priority_queue<P, vector<P>, greater<P>> pq;\n\n        for(int s=0;s<K;s++){\n            fill(d.begin(),d.end(),INF);\n            fill(par.begin(),par.end(),-1);\n            d[nodes[s]]=0; pq.emplace(0,nodes[s]);\n\n            while(!pq.empty()){\n                auto [dv,v]=pq.top(); pq.pop();\n                if(dv!=d[v]) continue;\n                for(int k=0;k<4;k++){\n                    int to=nb[v][k]; if(to==-1) continue;\n                    int nd = dv + cost[to];\n                    if(nd<d[to]){\n                        d[to]=nd; par[to]=v; pdir[to]=dch[k];\n                        pq.emplace(nd,to);\n                    }\n                }\n            }\n            for(int t=0;t<K;t++){\n                int dst = nodes[t];\n                dist[s][t]=d[dst];\n                if(s==t){ path[s][t]=\"\"; continue; }\n                string mv;\n                for(int cur=dst; cur!=nodes[s]; cur=par[cur])\n                    mv.push_back(pdir[cur]);\n                reverse(mv.begin(),mv.end());\n                path[s][t]=move(mv);\n            }\n        }\n    }\n};\n\n/*---------------------------------------------------------------------*/\n/* 3.  Christofides heuristic                                           */\nvector<int> christofides(const vector<vector<int>>& D){\n    int K=D.size();\n    /* 3-a  MST (Prim) */\n    vector<int> par(K,-1), key(K,INF);\n    vector<char> inMST(K,0);\n    key[0]=0;\n    for(int it=0; it<K; ++it){\n        int v=-1;\n        for(int i=0;i<K;i++) if(!inMST[i] && (v==-1||key[i]<key[v])) v=i;\n        inMST[v]=1;\n        for(int u=0;u<K;u++){\n            if(!inMST[u] && D[v][u] < key[u]){ key[u]=D[v][u]; par[u]=v; }\n        }\n    }\n    vector<vector<int>> adj(K);\n    vector<int> deg(K,0);\n    for(int i=1;i<K;i++){\n        adj[i].push_back(par[i]);\n        adj[par[i]].push_back(i);\n        deg[i]++; deg[par[i]]++;\n    }\n\n    /* 3-b  set of vertices with odd degree */\n    vector<int> odd;\n    for(int i=0;i<K;i++) if(deg[i]&1) odd.push_back(i);\n\n    /* 3-c  greedy light-weight perfect matching on the odd set */\n    int m=odd.size();\n    vector<char> matched(K,0);\n    vector<tuple<int,int,int>> cand;\n    cand.reserve(m*m/2);\n    for(int i=0;i<m;i++) for(int j=i+1;j<m;j++)\n        cand.emplace_back(D[odd[i]][odd[j]], odd[i], odd[j]);\n    sort(cand.begin(),cand.end());\n    for(auto [w,a,b]: cand)\n        if(!matched[a] && !matched[b]){\n            matched[a]=matched[b]=1;\n            adj[a].push_back(b); adj[b].push_back(a);\n        }\n\n    /* 3-d  Euler tour + shortcut (Hierholzer) */\n    vector<int> it(K,0), st = {0}, eul;\n    while(!st.empty()){\n        int v = st.back();\n        while(it[v] < (int)adj[v].size() && adj[v][it[v]]==-1) ++it[v];\n        if(it[v] == (int)adj[v].size()){\n            eul.push_back(v); st.pop_back();\n        }else{\n            int u = adj[v][it[v]];\n            adj[v][it[v]] = -1;\n            for(int& x: adj[u]) if(x==v){ x=-1; break; }\n            st.push_back(u);\n        }\n    }\n    vector<char> seen(K,0);\n    vector<int> order;\n    for(int v: eul) if(!seen[v]){ order.push_back(v); seen[v]=1; }\n    order.push_back(0);\n    return order;\n}\n\n/*---------------------------------------------------------------------*/\n/* 4.  Local search : 2-opt + Or-opt                                    */\nvoid two_opt(vector<int>& ord, const vector<vector<int>>& D){\n    int L=ord.size();\n    bool improved=true;\n    while(improved){\n        improved=false;\n        for(int i=1;i<L-3;i++){\n            for(int j=i+2;j<L-1;j++){\n                int a=ord[i-1], b=ord[i];\n                int c=ord[j],   d=ord[j+1];\n                int delta = D[a][b]+D[c][d] - D[a][c]-D[b][d];\n                if(delta>0){\n                    reverse(ord.begin()+i, ord.begin()+j+1);\n                    improved=true;\n                    goto nxt;\n                }\n            }\n        }\n        nxt:;\n    }\n}\nvoid or_opt(vector<int>& ord, const vector<vector<int>>& D){\n    int L=ord.size();\n    bool improved=true;\n    while(improved){\n        improved=false;\n        for(int i=1;i<L-1;i++){\n            int b = ord[i];\n            int a = ord[i-1], c = ord[i+1];\n            int removeGain = D[a][b] + D[b][c] - D[a][c];\n            for(int j=1;j<L-1;j++){\n                if(j==i || j==i-1) continue;\n                int u = ord[j], v = ord[j+1];\n                int insertCost = D[u][b] + D[b][v] - D[u][v];\n                if(removeGain - insertCost > 0){          // net improvement\n                    int node = ord[i];\n                    ord.erase(ord.begin()+i);\n                    if(j<i) ord.insert(ord.begin()+j+1, node);\n                    else    ord.insert(ord.begin()+j  , node);\n                    improved=true;\n                    goto again;\n                }\n            }\n        }\n        again:;\n    }\n}\n\n/*---------------------------------------------------------------------*/\n/* 5.  main                                                            */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    if(!(cin>>N>>si>>sj)) return 0;\n    vector<string> S(N);\n    for(int i=0;i<N;i++) cin>>S[i];\n\n    /* build covering set (view points) */\n    CoverBuilder cb(N, move(S));\n    cb.build(si, sj);\n    vector<int> nodes;\n    nodes.push_back(cb.id(si,sj));\n    nodes.insert(nodes.end(), cb.points.begin(), cb.points.end());\n\n    /* all-pairs shortest paths */\n    APSP apsp(N, cb.cost, cb.isRoad, nodes);\n\n    /* Christofides + local search */\n    vector<int> order = christofides(apsp.dist);\n    two_opt(order, apsp.dist);\n    or_opt (order, apsp.dist);\n\n    /* materialise the route */\n    string ans;\n    long long total=0;\n    for(size_t i=0;i+1<order.size();i++){\n        ans += apsp.path[order[i]][order[i+1]];\n        total+= apsp.dist[order[i]][order[i+1]];\n    }\n    cout<<ans<<\"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*------------------------------------------------ data structures -----------*/\nstruct Worker {\n    vector<int> low;              // proven lower bounds of skill\n    int task  = -1;               // current task id, -1 == idle\n    int start = -1;               // day the task was started\n    int gap   = 3;                // still unknown deficiency\n};\n\n/*------------------------------------------------ helper --------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /*---------------- read fixed instance data ----------------*/\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n\n    vector<vector<int>> need(N, vector<int>(K));\n    for (auto &v : need)\n        for (int &x : v) cin >> x;\n\n    vector<vector<int>> out(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        out[u].push_back(v);\n        ++indeg[v];\n    }\n\n    /*---------------- static priority = out-deg + longest path --------------*/\n    vector<int> topo; topo.reserve(N);\n    {\n        queue<int> q;\n        vector<int> deg = indeg;               // copy\n        for (int i = 0; i < N; ++i)\n            if (deg[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 : out[u])\n                if (--deg[v] == 0) q.push(v);\n        }\n    }\n    vector<int> lp(N, 0);                      // longest path length\n    for (int idx = N - 1; idx >= 0; --idx) {\n        int u = topo[idx];\n        int best = 0;\n        for (int v : out[u]) best = max(best, lp[v] + 1);\n        lp[u] = best;\n    }\n\n    vector<int> prio(N);\n    for (int i = 0; i < N; ++i)\n        prio[i] = (int)out[i].size() + lp[i];\n\n    /*---------------- dynamic state ----------------*/\n    vector<char> state(N, 0);                  // 0 not started, 1 running, 2 done\n    vector<char> inReady(N, 0);\n    vector<int> ready; ready.reserve(N);\n    for (int i = 0; i < N; ++i)\n        if (indeg[i] == 0) { ready.push_back(i); inReady[i] = 1; }\n\n    vector<Worker> W(M, Worker{vector<int>(K, 0)});\n    const double BETA = 0.15;                  // priority weight\n    int day = 1;\n\n    auto predicted_time = [&](const Worker &w, int task) -> int {\n        int lack = w.gap;\n        for (int k = 0; k < K; ++k) {\n            int diff = need[task][k] - w.low[k];\n            if (diff > 0) lack += diff;\n        }\n        return max(1, lack);\n    };\n\n    /*=========================== main loop =============================*/\n    while (true) {\n        /*----- collect idle workers -----*/\n        vector<int> idle;\n        for (int j = 0; j < M; ++j)\n            if (W[j].task == -1) idle.push_back(j);\n\n        /*----- collect startable tasks (state==0) -----*/\n        vector<int> tasksToday;\n        for (int id : ready)\n            if (state[id] == 0) tasksToday.push_back(id);\n\n        /*----- greedy global matching worker \u2194 task -----*/\n        vector<pair<int,int>> today;           // (worker, task)\n        vector<char> taken(N, 0);\n\n        while (!idle.empty() && !tasksToday.empty()) {\n            long long bestScore = LLONG_MAX;\n            int bestW = -1, bestT = -1;\n\n            for (int wId : idle) {\n                const Worker &wk = W[wId];\n                long long bestForW = LLONG_MAX;\n                int chosenT = -1, chosenPr = -1;\n\n                for (int tId : tasksToday) if (!taken[tId]) {\n                    int pred = predicted_time(wk, tId);\n                    long long score = (long long)pred - (long long)(BETA * prio[tId]);\n                    if (score < bestForW ||\n                        (score == bestForW && prio[tId] > chosenPr)) {\n                        bestForW = score;\n                        chosenT  = tId;\n                        chosenPr = prio[tId];\n                    }\n                }\n                if (chosenT != -1 && bestForW < bestScore) {\n                    bestScore = bestForW;\n                    bestW     = wId;\n                    bestT     = chosenT;\n                }\n            }\n            if (bestW == -1) break;            // nothing assignable\n\n            /* commit */\n            today.emplace_back(bestW, bestT);\n            taken[bestT]  = 1;\n            W[bestW].task = bestT;\n            W[bestW].start = day;\n            state[bestT]  = 1;\n\n            idle.erase(find(idle.begin(), idle.end(), bestW));\n        }\n\n        /*--- output decisions of today ---*/\n        cout << (int)today.size();\n        for (auto [w, t] : today) cout << ' ' << w + 1 << ' ' << t + 1;\n        cout << '\\n' << flush;\n\n        /*--- receive completed workers ---*/\n        int nDone;\n        if (!(cin >> nDone)) return 0;\n        if (nDone == -1) break;               // judge finished\n\n        for (int i = 0; i < nDone; ++i) {\n            int id; cin >> id; --id;\n            Worker &wk = W[id];\n            int tId = wk.task;\n            if (tId < 0) continue;            // safety\n\n            int realT = day - wk.start + 1;\n            int wLow  = max(0, realT - 3);\n            int wHigh = realT + 3;\n\n            /* predicted lack before update */\n            int predLack = wk.gap;\n            for (int k = 0; k < K; ++k) {\n                int diff = need[tId][k] - wk.low[k];\n                if (diff > 0) predLack += diff;\n            }\n\n            /* update model */\n            if (predLack > wHigh) {                       // over-predicted\n                int excess = predLack - wHigh;\n                for (int k = 0; k < K && excess > 0; ++k) {\n                    int lack = need[tId][k] - wk.low[k];\n                    if (lack <= 0) continue;\n                    int inc = min(lack, excess);\n                    wk.low[k] += inc;\n                    excess    -= inc;\n                }\n                wk.gap = max(0, wk.gap - excess);\n            } else if (predLack < wLow) {                 // under-predicted\n                wk.gap += (wLow - predLack);\n            } else {                                      // plausible\n                wk.gap = (int)(wk.gap * 0.9);\n            }\n\n            /* task finished */\n            state[tId] = 2;\n            wk.task = -1;\n\n            for (int v : out[tId]) {\n                if (--indeg[v] == 0 && !inReady[v]) {\n                    ready.push_back(v);\n                    inReady[v] = 1;\n                }\n            }\n        }\n        ++day;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** geometry **************************************************************/\nstruct Pt{short x,y;};\ninline int md(const Pt&a,const Pt&b){return abs(a.x-b.x)+abs(a.y-b.y);}\n\n/*** constants *************************************************************/\nconstexpr int NORD = 1000;          // total orders\nconstexpr int NEED =   50;          // we must serve exactly 50\nconstexpr int DEPOT=0;\nconstexpr double TLIMIT = 1.95;\n\n/*** global data ***********************************************************/\nvector<Pt>  node;                   // 0 + 2*NORD points\nvector<uint16_t> distM;             // (2*N+1)^2  Manhattan matrix\ninline int dist(int u,int v){return distM[u*(2*NORD+1)+v];}\n\nvector<int> idxP(NORD), idxD(NORD), inner(NORD);\nvector<int> sortedByInner;\n\n/*** helpers ***************************************************************/\nlong long routeCost(const vector<int>& r){\n    long long c=0;\n    for(size_t i=0;i+1<r.size();++i) c+=dist(r[i],r[i+1]);\n    return c;\n}\n\nstruct Insert{ long long delta; int eP,eD; };\nInsert bestInsert(const vector<int>& route,int ip,int id){\n    const int R=route.size();\n    long long best=LLONG_MAX; int bp=0,bd=0;\n    for(int i=0;i<R-1;++i){\n        long long d1= dist(route[i],ip)+dist(ip,route[i+1])-dist(route[i],route[i+1]);\n\n        /* delivery right after pickup */\n        long long delta=d1+ dist(ip,id)+dist(id,route[i+1])-dist(ip,route[i+1]);\n        if(delta<best){best=delta;bp=i;bd=i;}\n\n        for(int j=i+1;j<R-1;++j){\n            long long d2= dist(route[j],id)+dist(id,route[j+1])-dist(route[j],route[j+1]);\n            delta=d1+d2;\n            if(delta<best){best=delta;bp=i;bd=j;}\n        }\n    }\n    return {best,bp,bd};\n}\nvoid applyInsert(vector<int>& r,int ip,int id,int eP,int eD){\n    r.insert(r.begin()+eP+1,ip);\n    if(eD==eP) r.insert(r.begin()+eP+2,id);\n    else       r.insert(r.begin()+eD+2,id);\n}\n\n/*** constructive GRASP ****************************************************/\nvector<int> greedyConstruct(mt19937& rng){\n    vector<char> used(NORD,0);\n    vector<int> route={DEPOT,DEPOT};\n    const int CAND=300, WIDTH=8;\n\n    for(int step=0;step<NEED;++step){\n        /* candidate list ------------------------------------------------*/\n        int cnt=0; static int pool[CAND];\n        for(int o:sortedByInner) if(!used[o]){\n            pool[cnt++]=o; if(cnt==CAND) break;\n        }\n\n        /* evaluate ------------------------------------------------------*/\n        struct Info{ long long d; int ord,eP,eD; };\n        array<Info,WIDTH> best; for(auto&b:best)b.d=LLONG_MAX;\n\n        for(int k=0;k<cnt;++k){\n            int id=pool[k];\n            auto ins=bestInsert(route,idxP[id],idxD[id]);\n            if(ins.delta>=best[WIDTH-1].d) continue;\n            best[WIDTH-1]={ins.delta,id,ins.eP,ins.eD};\n            for(int w=WIDTH-1;w>0&&best[w].d<best[w-1].d;--w) swap(best[w],best[w-1]);\n        }\n        int pick=uniform_int_distribution<int>(0,min(WIDTH-1,step))(rng);\n        const auto &ch=best[pick];\n        applyInsert(route,idxP[ch.ord],idxD[ch.ord],ch.eP,ch.eD);\n        used[ch.ord]=1;\n    }\n    return route;\n}\n\n/*** pure improvement: first-descent pair-relocate **************************/\nvoid hillClimb(vector<int>& route,const vector<char>& used){\n    bool imp=true;\n    while(imp){\n        imp=false;\n        for(int id=0;id<NORD && !imp;++id) if(used[id]){\n            /* remove ---------------------------------------------------*/\n            vector<int> shortR; shortR.reserve(route.size()-2);\n            for(int v:route) if(v!=idxP[id]&&v!=idxD[id]) shortR.push_back(v);\n\n            auto ins=bestInsert(shortR,idxP[id],idxD[id]);\n            if(ins.delta<0){\n                applyInsert(shortR,idxP[id],idxD[id],ins.eP,ins.eD);\n                route.swap(shortR); imp=true;\n            }\n        }\n    }\n}\n\n/*** SA moves **************************************************************/\nvoid erasePair(vector<int>& r,int ip,int id){\n    r.erase(remove(r.begin(),r.end(),ip),r.end());\n    r.erase(remove(r.begin(),r.end(),id),r.end());\n}\nvoid collectUsed(const vector<int>& route,vector<char>& used){\n    fill(used.begin(),used.end(),0);\n    for(int v:route) if(v){\n        int ord=(v-1)>>1; used[ord]=1;\n    }\n}\n/* ----------------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read -------------------------------------------------------------- */\n    vector<array<int,4>> raw(NORD);\n    for(auto&o:raw) cin>>o[0]>>o[1]>>o[2]>>o[3];\n\n    /* geometry ---------------------------------------------------------- */\n    node.reserve(1+2*NORD); node.push_back({400,400});\n    for(int i=0;i<NORD;++i){\n        node.push_back({(short)raw[i][0],(short)raw[i][1]});\n        node.push_back({(short)raw[i][2],(short)raw[i][3]});\n    }\n    int NN=node.size();\n    distM.resize((size_t)NN*NN);\n    for(int i=0;i<NN;++i)for(int j=0;j<NN;++j)distM[i*NN+j]=(uint16_t)md(node[i],node[j]);\n\n    for(int i=0;i<NORD;++i){\n        idxP[i]=1+2*i; idxD[i]=1+2*i+1;\n        inner[i]=dist(idxP[i],idxD[i]);\n    }\n    sortedByInner.resize(NORD);\n    iota(sortedByInner.begin(),sortedByInner.end(),0);\n    sort(sortedByInner.begin(),sortedByInner.end(),\n         [&](int a,int b){return inner[a]<inner[b];});\n\n    /* timers & rng ------------------------------------------------------- */\n    const auto t0=chrono::high_resolution_clock::now();\n    auto sec=[&](){\n        return chrono::duration<double>(chrono::high_resolution_clock::now()-t0).count();\n    };\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n\n    /* multi-start construction ------------------------------------------ */\n    vector<int> bestRoute; long long bestCost=LLONG_MAX;\n    vector<char> used(NORD);\n    while(sec()<0.55){\n        auto r=greedyConstruct(rng);\n        collectUsed(r,used);\n        hillClimb(r,used);\n        long long c=routeCost(r);\n        if(c<bestCost){bestCost=c;bestRoute.swap(r);}\n    }\n    collectUsed(bestRoute,used);\n\n    /* ---------- Simulated Annealing ------------------------------------ */\n    double T0=600.0, Tend=1e-1;\n    long long curCost=bestCost;\n    auto curRoute=bestRoute;\n    auto curUsed = used;\n    vector<int> candInner(sortedByInner.begin(),sortedByInner.begin()+256);\n\n    int iter=0;\n    while(sec()<TLIMIT-0.02){\n        ++iter;\n        double t=sec()/ (TLIMIT-0.02);\n        double Temp=T0*pow(Tend/T0,t);\n\n        bool exchange = uniform_real_distribution<>(0,1)(rng)<0.30;\n\n        vector<int> nxtRoute=curRoute;\n        auto nxtUsed=curUsed;\n        long long nxtCost;\n\n        if(exchange){\n            /* remove one in-route order --------------------------------*/\n            vector<int> inOrders;\n            for(int o=0;o<NORD;++o) if(curUsed[o]) inOrders.push_back(o);\n            int outOrd=inOrders[uniform_int_distribution<int>(0,inOrders.size()-1)(rng)];\n            erasePair(nxtRoute,idxP[outOrd],idxD[outOrd]);\n            nxtUsed[outOrd]=0;\n\n            /* choose an unused candidate ------------------------------ */\n            vector<int> pool;\n            for(int o:candInner) if(!nxtUsed[o]) pool.push_back(o);\n            if(pool.empty()){curCost=routeCost(curRoute);continue;}\n            int inOrd=pool[uniform_int_distribution<int>(0,pool.size()-1)(rng)];\n            auto ins=bestInsert(nxtRoute,idxP[inOrd],idxD[inOrd]);\n            applyInsert(nxtRoute,idxP[inOrd],idxD[inOrd],ins.eP,ins.eD);\n            nxtUsed[inOrd]=1;\n        }else{\n            /* relocate ------------------------------------------------- */\n            vector<int> inOrders;\n            for(int o=0;o<NORD;++o) if(curUsed[o]) inOrders.push_back(o);\n            int ord=inOrders[uniform_int_distribution<int>(0,inOrders.size()-1)(rng)];\n            erasePair(nxtRoute,idxP[ord],idxD[ord]);\n            auto ins=bestInsert(nxtRoute,idxP[ord],idxD[ord]);\n            applyInsert(nxtRoute,idxP[ord],idxD[ord],ins.eP,ins.eD);\n        }\n        nxtCost=routeCost(nxtRoute);\n        long long diff=nxtCost-curCost;\n        if(diff<0 || exp(-diff/Temp)>uniform_real_distribution<>(0,1)(rng)){\n            curRoute.swap(nxtRoute);\n            curUsed .swap(nxtUsed );\n            curCost = nxtCost;\n            if(curCost<bestCost){\n                bestCost=curCost;\n                bestRoute=curRoute;\n            }\n        }\n    }\n\n    /* ---------- extract order list ------------------------------------ */\n    vector<int> finalUsed;\n    finalUsed.reserve(NEED);\n    vector<char> mark(NORD,0);\n    for(int v:bestRoute) if(v){\n        int o=(v-1)>>1;\n        if(!mark[o]){mark[o]=1;finalUsed.push_back(o);}\n    }\n    sort(finalUsed.begin(),finalUsed.end());               // any order is ok\n\n    /* ---------- output ------------------------------------------------- */\n    cout<<NEED;\n    for(int o:finalUsed) cout<<' '<<o+1;                   // 1-based\n    cout<<\"\\n\";\n\n    cout<<bestRoute.size();\n    for(int v:bestRoute) cout<<' '<<node[v].x<<' '<<node[v].y;\n    cout<<\"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- Union-Find ---------- */\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        p.resize(n);\n        sz.assign(n, 1);\n        iota(p.begin(), p.end(), 0);\n    }\n    int find(int v) { return p[v] == v ? v : p[v] = find(p[v]); }\n    /* returns surviving root */\n    int unite(int a, int b) {\n        a = find(a);  b = find(b);\n        if (a == b) return a;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a;\n        sz[a] += sz[b];\n        return a;\n    }\n};\n\nconstexpr int N = 400;\nconstexpr int M = 1995;\n\n/* global static matrices ( 400\u00b2 \u00b7 4 B = 0.6 MiB ) */\nstatic int remEdge[N][N];   // future edges between roots\nstatic int extCnt [N];      // \u03a3 remEdge[root][*]\n\n/* merge rows/columns after a DSU merge */\nstatic void mergeRows(int keep, int gone) {\n    for (int t = 0; t < N; ++t) if (t != keep && remEdge[gone][t]) {\n        remEdge[keep][t] += remEdge[gone][t];\n        remEdge[t][keep]  = remEdge[keep][t];\n        remEdge[gone][t] = remEdge[t][gone] = 0;\n    }\n    extCnt[gone] = 0;\n\n    long long sum = 0;\n    for (int t = 0; t < N; ++t) if (t != keep) sum += remEdge[keep][t];\n    extCnt[keep] = int(sum);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- fixed input ---------- */\n    vector<int> X(N), Y(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i];\n\n    vector<int> U(M), V(M);\n    for (int i = 0; i < M; ++i) cin >> U[i] >> V[i];\n\n    /* ---------- lower-bound distances d[i] ---------- */\n    vector<int> d(M);\n    for (int i = 0; i < M; ++i) {\n        long long dx = X[U[i]] - X[V[i]];\n        long long dy = Y[U[i]] - Y[V[i]];\n        d[i] = int(lround(std::sqrt(double(dx * dx + dy * dy))));\n        if (d[i] == 0) d[i] = 1;\n    }\n\n    /* ---------- discover the 5 generator layers ---------- */\n    vector<int> layer(M, 4);                 // default \u201cworst\u201d layer\n    vector<int> ord(M); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(),\n         [&](int a, int b){ return d[a] < d[b]; });\n\n    vector<char> alive(M, 1);\n    for (int l = 0; l < 5; ++l) {\n        DSU tmp(N);\n        int cnt = 0;\n        for (int id : ord) if (alive[id]) {\n            if (tmp.unite(U[id], V[id]) != -1) {\n                layer[id] = l;\n                alive[id] = 0;               // remove for next round\n                if (++cnt == N - 1) break;\n            }\n        }\n    }\n\n    /* ---------- \u201cfuture edge\u201d counters ---------- */\n    for (int i = 0; i < M; ++i) {\n        int u = U[i], v = V[i];\n        remEdge[u][v]++; remEdge[v][u]++;\n        ++extCnt[u]; ++extCnt[v];\n    }\n\n    /* ---------- online phase ---------- */\n    DSU dsu(N);\n    int components = N;\n\n    for (int i = 0; i < M; ++i) {\n        long long li; cin >> li;\n\n        int u = U[i], v = V[i];\n        int ru = dsu.find(u), rv = dsu.find(v);\n\n        /* remove this edge from the \u201cfuture\u201d lists */\n        if (ru != rv) {\n            --remEdge[ru][rv];\n            --remEdge[rv][ru];\n            --extCnt[ru];\n            --extCnt[rv];\n        }\n\n        bool mustTake = false, take = false;\n\n        if (ru != rv) {\n            if (extCnt[ru] == 0 || extCnt[rv] == 0) mustTake = true;\n\n            /* ---------- price based decision ---------- */\n            double ratio = double(li) / double(d[i]);\n\n            /* time dependent base threshold */\n            double t = double(i) / double(M);\n            double base = 1.05 + 1.95 * std::pow(t, 1.3);\n\n            /* bonuses */\n            double thr = base\n                       + (0.20 - 0.05 * layer[i]);          // layer bonus\n\n            int minExt = std::min(extCnt[ru], extCnt[rv]);\n            if (minExt <= 2)       thr += 0.40;\n            else if (minExt <= 4)  thr += 0.20;\n\n            if (thr > 3.0) thr = 3.0;\n\n            if (ratio <= thr) take = true;\n        }\n        if (mustTake) take = true;\n\n        /* absolute safety net */\n        if (!take && ru != rv && components - 1 > M - i - 1)\n            take = true;\n\n        /* ---------- output ---------- */\n        cout << (take ? 1 : 0) << '\\n' << flush;\n\n        /* ---------- apply decision ---------- */\n        if (take && ru != rv) {\n            int newRoot = dsu.unite(ru, rv);\n            int dead    = (newRoot == ru ? rv : ru);\n            mergeRows(newRoot, dead);\n            --components;\n        }\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int H = 30, W = 30;\nconst int DX[4] = {-1, 1, 0, 0};\nconst int DY[4] = { 0, 0,-1, 1};\nconst char DIR_CH[4] = {'U','D','L','R'};\n\nstruct Pet{ int x,y,t; };\n\nstruct Human{\n    int x,y;\n    int line_col;          // the column we turn into a wall\n    int side;              // +1 = stand right of wall, build left  (command 'l')\n                           // -1 = stand left  of wall, build right (command 'r')\n    int target_col;        // column we stand on while building\n    int phase = 0;         // 0 = walk to (1,target_col), 1 = build wall downward\n    bool build_next = true;\n};\n\n/*** helpers ***************************************************************/\n\nbool inside(int x,int y){ return 1<=x && x<=H && 1<=y && y<=W; }\n\n/* BFS that returns first move from (sx,sy) to (gx,gy) avoiding walls (#).\n   If unreachable, returns '.'                                                  */\nchar bfs_first_step(const vector<string>& board,int sx,int sy,int gx,int gy){\n    if(sx==gx && sy==gy) return '.';\n    static int dist[H+2][W+2];\n    for(int i=1;i<=H;i++) for(int j=1;j<=W;j++) dist[i][j]=-1;\n    queue<pair<int,int>> q;\n    dist[sx][sy]=0;\n    q.push({sx,sy});\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        for(int d=0;d<4;d++){\n            int nx=x+DX[d], ny=y+DY[d];\n            if(!inside(nx,ny) || board[nx][ny]=='#' || dist[nx][ny]!=-1) continue;\n            dist[nx][ny]=dist[x][y]+1;\n            q.push({nx,ny});\n        }\n    }\n    if(dist[gx][gy]==-1) return '.';\n    for(int d=0;d<4;d++){\n        int nx=sx+DX[d], ny=sy+DY[d];\n        if(inside(nx,ny) && dist[nx][ny]==dist[gx][gy]-1) return DIR_CH[d];\n    }\n    return '.';                       // should not reach here\n}\n\n/*** main ******************************************************************/\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* -------- read the initial state -------- */\n    int N; if(!(cin>>N)) return 0;\n    vector<Pet> pets(N);\n    for(auto &p:pets) cin>>p.x>>p.y>>p.t;\n\n    int M; cin>>M;\n    vector<Human> hum(M);\n    for(auto &h:hum) cin>>h.x>>h.y;\n\n    /* columns where we build vertical walls                                       */\n    const vector<int> WALL_COL = {2,5,8,11,14,17,20,23,26,29};\n    for(int i=0;i<M;i++){\n        hum[i].line_col   = WALL_COL[i];\n        hum[i].side       = (hum[i].line_col < 15)? +1 : -1;\n        hum[i].target_col = hum[i].line_col + hum[i].side;\n    }\n\n    /* current map, with a sentinel rim                                            */\n    vector<string> board(H+2,string(W+2,'#'));\n    for(int x=1;x<=H;x++) for(int y=1;y<=W;y++) board[x][y]='.';\n\n    auto pet_near = [&](int x,int y)->bool{\n        for(const auto &p:pets){\n            if(p.x==x && p.y==y) return true;\n            if(abs(p.x-x)+abs(p.y-y)==1) return true;\n        }\n        return false;\n    };\n    auto human_on = [&](int x,int y)->bool{\n        for(const auto &h:hum) if(h.x==x && h.y==y) return true;\n        return false;\n    };\n\n    /* ---------------- 300 turns ---------------- */\n    for(int turn=0;turn<300;turn++){\n        /* first pass : tentative actions and build targets                         */\n        struct Tmp{ char act='.'; int nx,ny; int bx,by; }; // nx,ny : move target\n        vector<Tmp> tmp(M);\n        bool willWall[H+1][W+1]={};\n\n        for(int i=0;i<M;i++){\n            auto &h = hum[i];\n            Tmp &t  = tmp[i];\n            t.nx=h.x; t.ny=h.y; t.bx=t.by=-1;\n\n            if(h.phase==0){                     // pathfinding to start cell\n                char mv = bfs_first_step(board,h.x,h.y,1,h.target_col);\n                if(mv!='.'){\n                    if(mv=='U'){ t.act='U'; t.nx=h.x-1; t.ny=h.y; }\n                    else if(mv=='D'){ t.act='D'; t.nx=h.x+1; t.ny=h.y; }\n                    else if(mv=='L'){ t.act='L'; t.nx=h.x; t.ny=h.y-1; }\n                    else if(mv=='R'){ t.act='R'; t.nx=h.x; t.ny=h.y+1; }\n                }\n            }\n            else{                               // phase 1 : build / move pattern\n                if(h.build_next){\n                    int bx=h.x, by=h.y - h.side;\n                    if(inside(bx,by) && board[bx][by]=='.'\n                       && !pet_near(bx,by) && !human_on(bx,by)){\n                        t.act = (h.side==1)?'l':'r';\n                        t.bx = bx; t.by = by;\n                        willWall[bx][by]=true;\n                    }else{\n                        t.act='.';                     // skip, keep build_next\n                    }\n                }else{                                // need to move down\n                    if(h.x < H && board[h.x+1][h.y]=='.'){\n                        t.act='D'; t.nx=h.x+1; t.ny=h.y;\n                    }else{\n                        t.act='.';                     // cannot move\n                    }\n                }\n            }\n        }\n\n        /* second pass : cancel illegal moves (into wall or future wall)            */\n        for(int i=0;i<M;i++){\n            Tmp &t = tmp[i];\n            if(t.act=='U'||t.act=='D'||t.act=='L'||t.act=='R'){\n                if(board[t.nx][t.ny]=='#' || willWall[t.nx][t.ny]){\n                    t.act='.';                        // cancel\n                    t.nx=hum[i].x; t.ny=hum[i].y;\n                }\n            }\n        }\n\n        /* ---------- output the final action string ---------- */\n        string actions;\n        actions.reserve(M);\n        for(auto &t:tmp) actions.push_back(t.act);\n        cout<<actions<<\"\\n\"<<flush;\n\n        /* ---------- apply executed actions, update state ---------- */\n        for(int i=0;i<M;i++){\n            char c = tmp[i].act;\n            Human &h = hum[i];\n\n            /* position change */\n            if(c=='U'||c=='D'||c=='L'||c=='R'){\n                h.x = tmp[i].nx;\n                h.y = tmp[i].ny;\n            }\n            /* build */\n            if(c=='u'||c=='d'||c=='l'||c=='r'){\n                int bx=h.x, by=h.y;\n                if(c=='u') --bx;\n                else if(c=='d') ++bx;\n                else if(c=='l') --by;\n                else if(c=='r') ++by;\n                if(inside(bx,by)) board[bx][by]='#';\n            }\n\n            /* update scheduling variables */\n            if(h.phase==0 && h.x==1 && h.y==h.target_col){\n                h.phase = 1;\n                h.build_next = true;\n            }else if(h.phase==1){\n                if(c=='l'||c=='r')       h.build_next = false;\n                else if(c=='D')          h.build_next = true;\n                /* c=='.' -> keep the flag unchanged                                 */\n            }\n        }\n\n        /* ---------- read pets' movements ---------- */\n        for(int i=0;i<N;i++){\n            string s; cin>>s;\n            auto &p = pets[i];\n            for(char c:s){\n                if(c=='U') --p.x;\n                else if(c=='D') ++p.x;\n                else if(c=='L') --p.y;\n                else if(c=='R') ++p.y;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Node {\n    int i, j;\n};\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ------------------------------------------------ */\n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n\n    vector<string> h(20);          // horizontal walls, length 19 each\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);          // vertical   walls, length 20 each\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n\n    /* ---------- plain BFS -------------------------------------------------- */\n    const int H = 20, W = 20, N = H * W;\n    auto id = [&](int i, int j){ return i * W + j; };\n\n    vector<int> prev(N, -1);       // predecessor vertex\n    vector<char> prevMove(N);      // move taken to reach that vertex\n    queue<Node> q;\n    q.push({si, sj});\n    prev[id(si,sj)] = -2;          // mark as source\n\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    const char dc[4] = {'U','D','L','R'};\n\n    while(!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (ni < 0 || ni >= H || nj < 0 || nj >= W) continue;\n            bool wall = false;\n            if (dir == 0) wall = (v[i-1][j] == '1');           // up\n            if (dir == 1) wall = (v[i][j]   == '1');           // down\n            if (dir == 2) wall = (h[i][j-1] == '1');           // left\n            if (dir == 3) wall = (h[i][j]   == '1');           // right\n            if (wall) continue;\n\n            int nid = id(ni,nj);\n            if (prev[nid] != -1) continue;                     // visited\n            prev[nid] = id(i,j);\n            prevMove[nid] = dc[dir];\n            q.push({ni,nj});\n        }\n    }\n\n    /* ---------- reconstruct shortest path --------------------------------- */\n    string path;\n    for (int cur = id(ti,tj); prev[cur] != -2; cur = prev[cur])\n        path.push_back(prevMove[cur]);\n    reverse(path.begin(), path.end());          // now from start to goal\n\n    /* ---------- build the robust route ------------------------------------ */\n    string result;\n    result.reserve(200);\n\n    // copy the shortest path twice (<= 78 characters)\n    result += path;\n    result += path;\n\n    // fill the rest with the old fallback\n    while (result.size() + 2 <= 200) result += \"DR\";\n    if (result.size() < 200) result.push_back('D');   // length must be <=200\n\n    cout << result << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int H = 30, W = 30, DIR = 4;\nconst int di[DIR] = {0,-1,0,1};      // L, U, R, D\nconst int dj[DIR] = {-1,0,1,0};\n\nconst int TO_BASE[8][4] = {           // statement table\n    {1,0,-1,-1},\n    {3,-1,-1,0},\n    {-1,-1,3,2},\n    {-1,2,1,-1},\n    {1,0,3,2},\n    {3,2,1,0},\n    {2,-1,0,-1},\n    {-1,3,-1,1}\n};\n\nint type[H][W];                       // 0\u20257 read from input\nint rot [H][W];                       // current rotation 0\u20253\n\nint maskTable[8][4];                  // bitset of used sides after rot\nint toTable  [8][4][4];               // dir-mapping after rot\n\n/*------------------------------------------------------------------*/\nvoid precalc(){\n    for(int t=0;t<8;t++)\n        for(int r=0;r<4;r++){\n            int m=0;\n            for(int d=0;d<4;d++){\n                int d0=(d-r+4)%4;\n                int td=TO_BASE[t][d0];\n                int res = (td==-1) ? -1 : (td+r)%4;\n                toTable[t][r][d]=res;\n                if(res!=-1){ m|=1<<d; m|=1<<res; }\n            }\n            maskTable[t][r]=m;\n        }\n}\n/*------------------------------------------------------------------*/\ninline bool inside(int i,int j){return 0<=i && i<H && 0<=j && j<W;}\ninline int bitCnt(int x){ return __builtin_popcount((unsigned)x); }\ninline int curMask(int i,int j){ return maskTable[type[i][j]][rot[i][j]]; }\n\n/*------------------------------------------------------------------*/\n/* open-ends bookkeeping                                            */\nint openEnds = 0;\nint deltaOpenEnds(int i,int j,int newR){          // difference if (i,j)=newR\n    int oldM = curMask(i,j);\n    int newM = maskTable[type[i][j]][newR];\n    if(oldM==newM) return 0;\n    int diff = 0;\n    for(int d=0;d<4;d++){\n        int ni=i+di[d], nj=j+dj[d];\n        int oldU = (oldM>>d)&1;\n        int newU = (newM>>d)&1;\n        int nbU  = (inside(ni,nj)? (curMask(ni,nj)>>((d+2)&3)&1) : 0);\n        int oldMis = oldU ^ nbU;\n        int newMis = newU ^ nbU;\n        diff += (inside(ni,nj)? 2 : 1)*(newMis - oldMis);\n    }\n    return diff;\n}\nvoid applyRot(int i,int j,int newR){\n    openEnds += deltaOpenEnds(i,j,newR);\n    rot[i][j]=newR;\n}\nvoid recomputeOE(){\n    openEnds=0;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int m=curMask(i,j);\n        for(int d=0;d<4;d++) if(m>>d&1){\n            int ni=i+di[d], nj=j+dj[d];\n            if(!inside(ni,nj) || !(curMask(ni,nj)>>((d+2)&3)&1)) ++openEnds;\n        }\n    }\n}\n/*------------------------------------------------------------------*/\n/* loop score                                                        */\nlong long loopScore(const array<array<int,W>,H>& R){\n    static bool vis[H][W][4];\n    memset(vis,0,sizeof(vis));\n    vector<int> lens;\n    for(int si=0;si<H;si++)for(int sj=0;sj<W;sj++){\n        int r=R[si][sj];\n        int m = maskTable[type[si][sj]][r];\n        for(int sd=0;sd<4;sd++) if((m>>sd&1) && !vis[si][sj][sd]){\n            int i=si,j=sj,d=sd,len=0;\n            while(true){\n                vis[i][j][d]=true;\n                int nd = toTable[type[i][j]][ R[i][j] ][d];\n                if(nd==-1) { len=0; break; }\n                int ni=i+di[nd], nj=j+dj[nd];\n                if(!inside(ni,nj)) { len=0; break; }\n                int ndIn=(nd+2)&3;\n                ++len;\n                i=ni; j=nj; d=ndIn;\n                if(i==si && j==sj && d==sd){ lens.push_back(len); break; }\n                if(vis[i][j][d]){ len=0; break; }       // shouldn't happen\n            }\n        }\n    }\n    if(lens.size()<2) return 0;\n    nth_element(lens.begin(),lens.begin()+1,lens.end(),greater<int>());\n    return 1LL*lens[0]*lens[1];\n}\nlong long currentScore(){\n    array<array<int,W>,H> R;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) R[i][j]=rot[i][j];\n    return loopScore(R);\n}\n/*------------------------------------------------------------------*/\n/* initial pattern                                                   */\nint desiredMask(int i,int j){\n    bool evenRow = !(i&1), evenCol = !(j&1);\n    if(evenRow)  return evenCol ? ((1<<2)|(1<<3)) : ((1<<0)|(1<<3));\n    else         return evenCol ? ((1<<2)|(1<<1)) : ((1<<0)|(1<<1));\n}\nint bestInitRot(int ty,int want){\n    int best=-1, bestHit=-1, extra=10;\n    for(int r=0;r<4;r++){\n        int mk=maskTable[ty][r];\n        int hit = bitCnt(mk & want);\n        int ext = bitCnt(mk & ~want);\n        if(hit>bestHit || (hit==bestHit && ext<extra)){\n            bestHit=hit; extra=ext; best=r;\n        }\n    }\n    return best;\n}\n/*------------------------------------------------------------------*/\nstruct Timer{\n    const double TL; chrono::steady_clock::time_point st;\n    Timer(double tl=1.95):TL(tl),st(chrono::steady_clock::now()){}\n    double elap()const{\n        return chrono::duration<double>(chrono::steady_clock::now()-st).count();\n    }\n    bool good()const{ return elap()<TL; }\n} timer;\n/*------------------------------------------------------------------*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    precalc();\n\n    /* proper input reader: 30 \u00d7 30 digits without blanks */\n    for(int i=0;i<H;i++){\n        string s; cin>>s;\n        for(int j=0;j<W;j++) type[i][j]=s[j]-'0';\n    }\n\n    /* 1. deterministic start                                         */\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int want = desiredMask(i,j);\n        rot[i][j]=bestInitRot(type[i][j],want);\n    }\n    recomputeOE();\n\n    /* 2. greedy fix                                                  */\n    mt19937 rng(1234567);\n    vector<pair<int,int>> cells;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cells.emplace_back(i,j);\n\n    while(openEnds>0 && timer.elap()<0.6){\n        shuffle(cells.begin(),cells.end(),rng);\n        bool changed=false;\n        for(auto [i,j]:cells){\n            int bestR=rot[i][j], bestD=0;\n            for(int r=0;r<4;r++){\n                int d=deltaOpenEnds(i,j,r);\n                if(d<bestD){ bestD=d; bestR=r; }\n            }\n            if(bestR!=rot[i][j]){\n                applyRot(i,j,bestR);\n                changed=true;\n                if(openEnds==0) break;\n            }\n        }\n        if(!changed) break;\n    }\n\n    /* 3. quick hill-climb                                            */\n    long long bestScore = (openEnds==0)? currentScore() : 0;\n    array<array<int,W>,H> bestRot;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) bestRot[i][j]=rot[i][j];\n\n    uniform_int_distribution<int> dist(0,H*W-1);\n    while(timer.good()){\n        int v=dist(rng), i=v/W, j=v%W;\n        int oldR=rot[i][j];\n        int newR = (oldR + 1 + dist(rng)%3)&3;\n        int oldOE=openEnds;\n        applyRot(i,j,newR);\n\n        bool keep=false; long long cand=0;\n        if(openEnds==0){\n            cand=currentScore();\n            if(cand>=bestScore) keep=true;\n        }else if(openEnds<oldOE) keep=true;\n\n        if(keep){\n            if(openEnds==0 && cand>bestScore){\n                bestScore=cand;\n                for(int x=0;x<H;x++)for(int y=0;y<W;y++) bestRot[x][y]=rot[x][y];\n            }\n        }else{\n            applyRot(i,j,oldR);       // revert\n            openEnds=oldOE;\n        }\n    }\n\n    /* 4. output                                                      */\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'+bestRot[i][j]));\n    cout<<out<<\"\\n\";\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ------------------------------------------------------------\n   Constants / helpers\n------------------------------------------------------------ */\nconstexpr int MAXN = 10;                       // N \u2264 10\nconstexpr int MAXNN = MAXN * MAXN;\ninline int bit(int d){                         // 0U 1D 2L 3R  \u2192 2 8 1 4\n    static const int b[4] = {2, 8, 1, 4};\n    return b[d];\n}\ninline int opp(int d){ return d ^ 1; }         // U\u2194D, L\u2194R\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = { 0, 0,-1, 1};\nconst char DIRC[4] = {'U','D','L','R'};\n\nstruct Timer{\n    chrono::steady_clock::time_point st = chrono::steady_clock::now();\n    double elapsed() const{\n        return chrono::duration<double>(chrono::steady_clock::now()-st).count();\n    }\n};\nmt19937 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());\n\n/* ------------------------------------------------------------\n   Board + evaluation\n------------------------------------------------------------ */\nstruct Board{\n    int N;                                        // 6\u202610\n    array<int8_t,MAXNN> a;                        // -1 = blank, else 0\u202615\n    int blank;                                    // index of blank 0\u2026N\u00b2-1\n\n    /* slide; assumes dir is legal, returns new blank index */\n    int slide(int dir){\n        int bx = blank / N, by = blank % N;\n        int nx = bx + dx[dir], ny = by + dy[dir];\n        int nid = nx * N + ny;\n        swap(a[blank], a[nid]);\n        blank = nid;\n        return blank;\n    }\n\n    /* evaluate board: S = largest tree,  E = #matching edges */\n    pair<int,int> evaluate() const{\n        const int NN = N * N;\n        array<uint8_t,MAXNN> vis{};               // 0/1 visited flags\n        int bestTree = 0, edgeTot = 0;\n        array<int,MAXNN> q;\n\n        for(int v=0; v<NN; ++v) if(a[v]>=0 && !vis[v]){\n            int qs=0, qe=0; q[qe++] = v; vis[v]=1;\n            int verts=0, edges=0;\n            while(qs<qe){\n                int id = q[qs++]; ++verts;\n                int x=id/N, y=id%N, pat=a[id];\n                for(int d=0; d<4; ++d) if(pat&bit(d)){\n                    int nx=x+dx[d], ny=y+dy[d];\n                    if(nx<0||nx>=N||ny<0||ny>=N) continue;\n                    int nid=nx*N+ny;\n                    if(a[nid]<0) continue;\n                    if(a[nid]&bit(opp(d))){\n                        if(id < nid){ ++edges; ++edgeTot; }   // count once\n                        if(!vis[nid]){ vis[nid]=1; q[qe++]=nid; }\n                    }\n                }\n            }\n            if(edges == verts-1) bestTree = max(bestTree, verts);\n        }\n        return {bestTree, edgeTot};\n    }\n};\n\n/* ------------------------------------------------------------\n   State kept in the beam\n------------------------------------------------------------ */\nstruct State{\n    Board bd;\n    int S, E, eval;                               // evaluation  S*1000+E\n    char lastDir;                                 // last move (to forbid undo)\n    string moves;                                 // whole path\n\n    bool operator<(const State& o) const{\n        return eval < o.eval;\n    }\n};\n\n/* ------------------------------------------------------------\n   Solver with beam search\n------------------------------------------------------------ */\nstruct Solver{\n    int N, Tlim;\n    int BEAM;\n\n    State bestGlobal;\n    double TL = 2.95;                             // time safety margin\n\n    /* ---------------------------------------------------- */\n    State make_initial(){\n        Board b; b.N = N;\n        for(int i=0;i<N*N;++i) b.a[i]=0;          // placeholder\n        for(int i=0;i<N;i++){\n            string row; cin >> row;\n            for(int j=0;j<N;j++){\n                int idx=i*N+j;\n                char c=row[j];\n                int v = (c<='9') ? c-'0' : c-'a'+10;\n                if(v==0){ b.a[idx]=-1; b.blank=idx; }\n                else    { b.a[idx]=int8_t(v); }\n            }\n        }\n        auto [S,E]=b.evaluate();\n        State st{b,S,E,S*1000+E,-1,\"\"};\n        return st;\n    }\n\n    /* ---------------------------------------------------- */\n    void solve(){\n        Timer tim;\n        State init = make_initial();\n        bestGlobal = init;\n\n        vector<State> beam, nxt;\n        beam.reserve(1000); nxt.reserve(1000);\n        beam.push_back(init);\n\n        int depth=0;\n        while(depth < Tlim && tim.elapsed()<TL){\n            nxt.clear();\n            for(const State& st: beam){\n                int bx = st.bd.blank/ N, by=st.bd.blank%N;\n                for(int d=0; d<4; ++d){\n                    if(st.lastDir!=-1 && d==opp(st.lastDir)) continue; // avoid undo\n                    int nx=bx+dx[d], ny=by+dy[d];\n                    if(nx<0||nx>=N||ny<0||ny>=N) continue;\n\n                    State ns = st;                   // copy\n                    ns.bd.slide(d);\n                    ns.lastDir = d;\n                    ns.moves.push_back(DIRC[d]);\n\n                    auto[S,E]=ns.bd.evaluate();\n                    ns.S=S; ns.E=E; ns.eval=S*1000+E;\n\n                    if(ns.S > bestGlobal.S){\n                        bestGlobal = ns;\n                        if(bestGlobal.S == N*N-1) goto OUT;  // perfect\n                    }\n                    if((int)ns.moves.size() < Tlim) nxt.push_back(move(ns));\n                }\n            }\n            if(nxt.empty()) break;\n            /* keep best BEAM states */\n            int keep = min(BEAM,(int)nxt.size());\n            nth_element(nxt.begin(), nxt.begin()+keep, nxt.end(),\n                         [](const State& a,const State& b){return a.eval>b.eval;});\n            beam.assign(nxt.begin(), nxt.begin()+keep);\n            ++depth;\n        }\nOUT:   ;\n    }\n\n    void output() const {\n        cout << bestGlobal.moves << '\\n';\n    }\n\n    void run(){\n        ios::sync_with_stdio(false); cin.tie(nullptr);\n        cin>>N>>Tlim;\n        BEAM = (N==10? 400: 250);     // simple size heuristic\n        solve();\n        output();\n    }\n};\n\n/* ------------------------------------------------------------ */\nint main(){ Solver().run(); return 0; }","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconstexpr int R = 10000;              // cake radius\nconst ll BIG = 1'000'000'000LL;\n\nstruct FastRand {\n    uint64_t x = 88172645463325252ULL;\n    uint64_t next() { x ^= x << 7; x ^= x >> 9; return x; }\n    int next_int(int l, int r){ return int(next()%uint64_t(r-l+1))+l; }\n} rng;\n\n/* ------------------------------------------------------------\n   evaluate one AXIS-ALIGNED grid  (vx.size()+hy.size() \u2264 100)\n   returns the number of attendees that can be served\n   ------------------------------------------------------------ */\nstruct Evaluator{\n    const vector<pair<int,int>>& P;       // strawberries\n    const array<int,11>& need;            // a_d\n    vector<int> cell;                     // reused buffer\n\n    explicit Evaluator(const vector<pair<int,int>>& p,\n                       const array<int,11>& a): P(p),need(a){}\n\n    int operator()(const vector<int>& vx,const vector<int>& hy){\n        const int V=vx.size(), H=hy.size();\n        const int W=(V+1)*(H+1);\n        if((int)cell.size()<W) cell.resize(W);\n        fill(cell.begin(), cell.begin()+W, 0);\n\n        for(auto [x,y]:P){\n            // we guarantee that no line lies on a strawberry\n            int ix = int(lower_bound(vx.begin(),vx.end(),x)-vx.begin());\n            int iy = int(lower_bound(hy.begin(),hy.end(),y)-hy.begin());\n            cell[ix*(H+1)+iy]++;\n        }\n        array<int,11> have{};             // b_d\n        for(int c:cell) if(1<=c && c<=10) ++have[c];\n\n        int served=0;\n        for(int d=1;d<=10;++d) served += min(need[d], have[d]);\n        return served;\n    }\n};\n\n/* ------------------------------------------------------------\n   helpers\n   ------------------------------------------------------------ */\ntemplate<class S>\nint rnd_choice(const S& v){ return rng.next_int(0,(int)v.size()-1); }\n\nint sample_coord(unordered_set<int>& used,\n                 const unordered_set<int>& forbid,\n                 int l=-R, int r=R){\n    int x;\n    do{ x = rng.next_int(l,r); }while(used.count(x)||forbid.count(x));\n    used.insert(x);\n    return x;\n}\n\n/* ------------------------------------------------------------\n   main\n   ------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N,K;\n    if(!(cin>>N>>K)) return 0;\n    array<int,11> a{};\n    for(int d=1;d<=10;++d) cin>>a[d];\n\n    vector<pair<int,int>> P(N);\n    unordered_set<int> forbidX,forbidY; forbidX.reserve(N*2); forbidY.reserve(N*2);\n    for(auto& pt:P){\n        cin>>pt.first>>pt.second;\n        forbidX.insert(pt.first);\n        forbidY.insert(pt.second);\n    }\n\n    Evaluator eval(P,a);\n\n    /* ---------- initial random grid ----------------------- */\n    vector<int> vx,hy;\n    {\n        int v = rng.next_int(10,40);              // not too small, not too big\n        int h = rng.next_int(10,40);\n        unordered_set<int> u;\n        for(int i=0;i<v;++i) vx.push_back(sample_coord(u,forbidX));\n        u.clear();\n        for(int i=0;i<h;++i) hy.push_back(sample_coord(u,forbidY));\n        sort(vx.begin(),vx.end());\n        sort(hy.begin(),hy.end());\n    }\n\n    int curScore = eval(vx,hy);\n    vector<int> bestVX = vx, bestHY = hy;\n    int bestScore = curScore;\n\n    /* ---------- local search / hill climbing -------------- */\n    const auto t0 = chrono::steady_clock::now();\n    size_t iter = 0;\n    while(true){\n        auto now = chrono::steady_clock::now();\n        if(chrono::duration<double>(now-t0).count() > 2.9) break;\n\n        ++iter;\n        int op = rng.next_int(0,99);          // 0..59 move, 60..79 insert, 80..99 delete\n\n        vector<int> newVX = vx, newHY = hy;\n\n        bool ok = true;\n        if(op < 60 && (vx.size()+hy.size())>0){          // move\n            bool vertical = rng.next_int(0,1);\n            if(vertical && !newVX.empty()){\n                int idx = rnd_choice(newVX);\n                int old = newVX[idx];\n                int delta = rng.next_int(-800,800);\n                int neu = old + delta;\n                if(abs(neu) > R) neu = (neu>0?R:-R);     // keep inside disc (not mandatory)\n                if(!forbidX.count(neu) &&\n                   !binary_search(newVX.begin(),newVX.end(),neu)){\n                    newVX[idx]=neu; sort(newVX.begin(),newVX.end());\n                }else ok=false;\n            }else if(!vertical && !newHY.empty()){\n                int idx = rnd_choice(newHY);\n                int old = newHY[idx];\n                int delta = rng.next_int(-800,800);\n                int neu = old + delta;\n                if(abs(neu) > R) neu = (neu>0?R:-R);\n                if(!forbidY.count(neu) &&\n                   !binary_search(newHY.begin(),newHY.end(),neu)){\n                    newHY[idx]=neu; sort(newHY.begin(),newHY.end());\n                }else ok=false;\n            }else ok=false;\n        }\n        else if(op < 80 && (int)newVX.size()+ (int)newHY.size() < K){ // insert\n            bool vertical = rng.next_int(0,1);\n            if(vertical){\n                unordered_set<int> used(newVX.begin(),newVX.end());\n                int neu = sample_coord(used,forbidX);\n                newVX.push_back(neu); sort(newVX.begin(),newVX.end());\n            }else{\n                unordered_set<int> used(newHY.begin(),newHY.end());\n                int neu = sample_coord(used,forbidY);\n                newHY.push_back(neu); sort(newHY.begin(),newHY.end());\n            }\n        }\n        else if(op >=80){                                      // delete\n            bool vertical = (newHY.empty() || (!newVX.empty() && rng.next_int(0,1)));\n            if(vertical && !newVX.empty()){\n                newVX.erase(newVX.begin()+rnd_choice(newVX));\n            }else if(!vertical && !newHY.empty()){\n                newHY.erase(newHY.begin()+rnd_choice(newHY));\n            }else ok=false;\n        }\n\n        if(!ok) continue;                     // illegal proposal, skip\n\n        int sc = eval(newVX,newHY);\n        if(sc >= curScore){                   // hill climbing (accept ties)\n            vx.swap(newVX); hy.swap(newHY); curScore = sc;\n            if(sc > bestScore){\n                bestScore = sc;\n                bestVX = vx; bestHY = hy;\n            }\n        }\n    }\n    //cerr<<\"iterations \"<<iter<<\"  best \"<<bestScore<<\"\\n\";\n\n    /* ---------- output ------------------------------------ */\n    cout << bestVX.size()+bestHY.size() << '\\n';\n    for(int x: bestVX) cout<<x<<\" \"<<-BIG<<\"  \"<<x<<\" \"<<BIG<<\"\\n\";\n    for(int y: bestHY) cout<<-BIG<<\" \"<<y<<\"  \"<<BIG<<\" \"<<y<<\"\\n\";\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int MAXN = 62;                    // 61 + 1 safety row/col\n\n/* ------------------------------------------------------------------ */\n/*  very small, cache-friendly board representation                    */\n/* ------------------------------------------------------------------ */\nstruct Board {\n    int N, C;\n    unsigned char dot [MAXN][MAXN];\n    unsigned char h   [MAXN][MAXN];         // horizontal edge  (x,y)-(x+1,y)\n    unsigned char v   [MAXN][MAXN];         // vertical   edge  (x,y)-(x,y+1)\n    unsigned char ne  [MAXN][MAXN];         // diagonal  /\n    unsigned char nw  [MAXN][MAXN];         // diagonal  \\\n\n    void clearEdges(int n) {\n        for (int y = 0; y < n; ++y) {\n            memset(h [y],  0, n);\n            memset(v [y],  0, n);\n            memset(ne[y],  0, n);\n            memset(nw[y],  0, n);\n        }\n    }\n};\n\n/* ------------------------------------------------------------------ */\nstatic int              N, M;\nstatic long long        weight[MAXN][MAXN];\nstatic long long        Sboard = 0;\nstatic Board            basic;\nstatic long long        basicSum = 0;\n\n/* ------------------------------------------------------------------ */\nstruct Candidate {\n    int kind, x, y, miss;                   // 0 = square, 1 = diamond\n    int w;                                  // missing corner weight\n};\nstatic Candidate candPool[512];             // filled per iteration\nstatic int       poolSz;\n\n/* ------------------------------------------------------------------ */\nstruct RunResult {\n    long long sum;\n    vector<array<int,8>> moves;\n};\n\n/* ------------------------------------------------------------------ */\nRunResult oneRun(mt19937 &rng, int T0, int cool) {\n    Board B = basic;            // copy dots, empty edges\n    B.clearEdges(N);\n\n    vector<array<int,8>> moves;\n    long long sum = basicSum;\n\n    int step = 0;\n    while (true) {\n        int best = -1;\n        poolSz = 0;\n\n        /* ------------ axis aligned unit squares ------------------ */\n        for (int y = 0; y < N-1; ++y)\n            for (int x = 0; x < N-1; ++x) {\n                if (B.h[y][x] || B.h[y+1][x] || B.v[y][x] || B.v[y][x+1]) continue;\n\n                unsigned char p0 = B.dot[x][y]    ,\n                               p1 = B.dot[x+1][y]  ,\n                               p2 = B.dot[x+1][y+1],\n                               p3 = B.dot[x][y+1]  ;\n                int missCnt = (!p0)+(!p1)+(!p2)+(!p3);\n                if (missCnt != 1) continue;\n\n                int mi = !p0 ? 0 : !p1 ? 1 : !p2 ? 2 : 3;\n                int xx = x + (mi==1 || mi==2);\n                int yy = y + (mi>=2);\n                int w  = (int)weight[xx][yy];\n\n                if (w > best) best = w;\n                if (poolSz < 512) candPool[poolSz++] = {0,x,y,mi,w};\n            }\n\n        /* ------------ 45\u00b0 diamonds ------------------------------- */\n        for (int y = 0; y <= N-3; ++y)\n            for (int x = 1; x <= N-2; ++x) {\n                if (B.ne[y][x]      || B.nw[y+1][x] ||\n                    B.ne[y+1][x-1] ||  B.nw[y][x-1]) continue;\n\n                unsigned char p0 = B.dot[x][y]     ,\n                               p1 = B.dot[x+1][y+1] ,\n                               p2 = B.dot[x][y+2]   ,\n                               p3 = B.dot[x-1][y+1] ;\n                int missCnt = (!p0)+(!p1)+(!p2)+(!p3);\n                if (missCnt != 1) continue;\n\n                int mi = !p0 ? 0 : !p1 ? 1 : !p2 ? 2 : 3;\n                int xx, yy;\n                if (mi==0){xx=x;   yy=y;}\n                if (mi==1){xx=x+1; yy=y+1;}\n                if (mi==2){xx=x;   yy=y+2;}\n                if (mi==3){xx=x-1; yy=y+1;}\n                int w = (int)weight[xx][yy];\n\n                if (w > best) best = w;\n                if (poolSz < 512) candPool[poolSz++] = {1,x,y,mi,w};\n            }\n\n        if (poolSz == 0) break;            // no legal move left\n\n        int tol = max(5, T0 - step / cool);\n        int th  = best - tol;\n\n        /* ----------- build roulette -------------------------------- */\n        uint64_t tot = 0;\n        static uint64_t acc[512];\n        int kept = 0;\n        for (int i = 0; i < poolSz; ++i) {\n            int rel = candPool[i].w - th;\n            if (rel < 0) continue;         // below threshold\n            uint64_t score = 1ull * rel * rel + 1;   // (rel)\u00b2  (+1 avoids 0)\n            tot += score;\n            acc[kept] = tot;\n            candPool[kept++] = candPool[i];\n        }\n        poolSz = kept;\n        if (poolSz == 0) break;            // numerical safety\n\n        uint64_t r = rng() % tot;\n        int idx = int(lower_bound(acc, acc + poolSz, r + 1) - acc);\n        const Candidate &c = candPool[idx];\n\n        array<int,8> line;\n\n        if (c.kind == 0) {                 /* --------- square ------ */\n            auto corner=[&](int k)->pair<int,int>{\n                switch(k&3){\n                    case 0:return {c.x    ,c.y    };\n                    case 1:return {c.x+1  ,c.y    };\n                    case 2:return {c.x+1  ,c.y+1  };\n                    default:return{c.x    ,c.y+1  };\n                }};\n\n            bool cw = rng() & 1;\n            for (int k=0;k<4;++k){\n                auto [cx,cy]=corner(c.miss + (cw? k : -k));\n                line[2*k]=cx; line[2*k+1]=cy;\n            }\n            /* mark */\n            B.h[c.y][c.x]   = 1;\n            B.h[c.y+1][c.x] = 1;\n            B.v[c.y][c.x]   = 1;\n            B.v[c.y][c.x+1] = 1;\n\n            auto [nx,ny]=corner(c.miss);\n            B.dot[nx][ny]=1;\n            sum += weight[nx][ny];\n        } else {                           /* --------- diamond ----- */\n            auto corner=[&](int k)->pair<int,int>{\n                switch(k&3){\n                    case 0:return {c.x    ,c.y    };\n                    case 1:return {c.x+1  ,c.y+1  };\n                    case 2:return {c.x    ,c.y+2  };\n                    default:return{c.x-1  ,c.y+1  };\n                }};\n            bool cw = rng() & 1;\n            for (int k=0;k<4;++k){\n                auto [cx,cy]=corner(c.miss + (cw? k : -k));\n                line[2*k]=cx; line[2*k+1]=cy;\n            }\n            /* mark */\n            B.ne[c.y][c.x]     = 1;\n            B.nw[c.y+1][c.x]   = 1;\n            B.ne[c.y+1][c.x-1] = 1;\n            B.nw[c.y][c.x-1]   = 1;\n\n            auto [nx,ny]=corner(c.miss);\n            B.dot[nx][ny]=1;\n            sum += weight[nx][ny];\n        }\n\n        moves.push_back(line);\n        ++step;\n    }\n    return {sum, move(moves)};\n}\n\n/* ------------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin>>N>>M)) return 0;\n    int C = (N-1)/2;\n\n    for (int y=0;y<N;++y)\n        for (int x=0;x<N;++x){\n            long long w = 1LL*(x-C)*(x-C) + 1LL*(y-C)*(y-C) + 1;\n            weight[x][y]=w;\n            Sboard += w;\n        }\n\n    memset(basic.dot,0,sizeof(basic.dot));\n    for (int i=0;i<M;++i){\n        int x,y;cin>>x>>y;\n        basic.dot[x][y]=1;\n        basicSum += weight[x][y];\n    }\n    basic.N=N; basic.C=C;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto t0 = chrono::steady_clock::now();\n\n    RunResult best {basicSum,{}};\n\n    int runs = 0;\n    while (true){\n        ++runs;\n        int T0   = 120 + rng()%181;        // 120 \u2026 300\n        int cool = 3   + rng()%3;          // 3,4,5\n        RunResult r = oneRun(rng, T0, cool);\n        if (r.sum > best.sum) best = move(r);\n\n        if (chrono::duration<double>(chrono::steady_clock::now()-t0).count() > 4.8)\n            break;\n    }\n    // cerr<<\"runs=\"<<runs<<\"\\n\";\n\n    cout<<best.moves.size()<<'\\n';\n    for (auto &ln: best.moves){\n        for (int i=0;i<8;++i){\n            if (i) cout<<' ';\n            cout<<ln[i];\n        }\n        cout<<'\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Grid = array<array<int,10>,10>;\n\n/* ------------------------------------------------------------ */\n/* 1.  locate p-th empty cell (1-based) in row-major order       */\npair<int,int> locate_empty(const Grid& g,int idx){\n    int cnt = 0;\n    for(int r=0;r<10;r++)\n        for(int c=0;c<10;c++)\n            if(g[r][c]==0 && ++cnt==idx) return {r,c};\n    return {-1,-1};                 // never happens\n}\n/* ------------------------------------------------------------ */\n/* 2.  perform one tilt                                          */\nvoid tilt(Grid& dst,const Grid& src,char dir){\n    dst = {};                               // fill with zeros\n    if(dir=='F'){                           // to row 0\n        for(int c=0;c<10;c++){\n            int wr = 0;\n            for(int r=0;r<10;r++) if(src[r][c]) dst[wr++][c]=src[r][c];\n        }\n    }else if(dir=='B'){                     // to row 9\n        for(int c=0;c<10;c++){\n            int wr = 9;\n            for(int r=9;r>=0;r--) if(src[r][c]) dst[wr--][c]=src[r][c];\n        }\n    }else if(dir=='L'){                     // to col 0\n        for(int r=0;r<10;r++){\n            int wc = 0;\n            for(int c=0;c<10;c++) if(src[r][c]) dst[r][wc++]=src[r][c];\n        }\n    }else{                                  // 'R' to col 9\n        for(int r=0;r<10;r++){\n            int wc = 9;\n            for(int c=9;c>=0;c--) if(src[r][c]) dst[r][wc--]=src[r][c];\n        }\n    }\n}\n/* ------------------------------------------------------------ */\n/* 3.  gather statistics of a board                              */\nstruct Stat{\n    long long sum_sq;    // \u03a3 component_size\u00b2\n    int same_edges;      // #adjacent pairs with identical flavour\n    int diff_edges;      // #adjacent pairs with different flavour\n    int moved;           // how many candies changed their coordinates\n};\nStat analyse(const Grid& before,const Grid& after){\n    static const int dr[4]={-1,1,0,0};\n    static const int dc[4]={0,0,-1,1};\n\n    /* a) \u03a3 n\u00b2 -------------------------------------------------- */\n    bool vis[10][10] = {};\n    long long sum = 0;\n    queue<pair<int,int>> q;\n    for(int r=0;r<10;r++)for(int c=0;c<10;c++){\n        if(after[r][c]==0||vis[r][c]) continue;\n        int col = after[r][c], sz=0;\n        vis[r][c]=true; q.push({r,c});\n        while(!q.empty()){\n            auto [cr,cc]=q.front(); q.pop(); ++sz;\n            for(int k=0;k<4;k++){\n                int nr=cr+dr[k], nc=cc+dc[k];\n                if(nr<0||nr>=10||nc<0||nc>=10) continue;\n                if(!vis[nr][nc] && after[nr][nc]==col){\n                    vis[nr][nc]=true; q.push({nr,nc});\n                }\n            }\n        }\n        sum += 1LL*sz*sz;\n    }\n\n    /* b) edge statistics + moved counter ---------------------- */\n    int sameE = 0, diffE = 0, moved = 0;\n    for(int r=0;r<10;r++)for(int c=0;c<10;c++){\n        int v = after[r][c];\n        if(v && before[r][c]!=v) ++moved;\n\n        if(r+1<10 && v && after[r+1][c]){\n            (v==after[r+1][c] ? sameE : diffE)++;\n        }\n        if(c+1<10 && v && after[r][c+1]){\n            (v==after[r][c+1] ? sameE : diffE)++;\n        }\n    }\n    return {sum,sameE,diffE,moved};\n}\n/* ------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read full flavour sequence */\n    int flavour[100];\n    for(int i=0;i<100;i++) cin>>flavour[i];\n\n    Grid board = {};                        // start empty\n    const char DIRS[4] = {'F','B','L','R'};\n\n    for(int t=0;t<100;t++){\n        int p; cin>>p;                      // placement index\n        auto [r,c] = locate_empty(board,p);\n        board[r][c] = flavour[t];\n\n        if(t==99) break;                    // last candy, tilt does nothing\n\n        /* evaluate the four directions */\n        long long best_sum   = -1;\n        int       best_same  = -1;          // we maximise this\n        int       best_diff  = INT_MAX;     // we minimise this\n        int       best_moved = INT_MAX;\n        char      best_dir   = 'F';\n        Grid      best_board;\n\n        for(char dir:DIRS){\n            Grid after;\n            tilt(after,board,dir);\n            Stat st = analyse(board,after);\n\n            bool better = false;\n            if(st.sum_sq > best_sum) better = true;\n            else if(st.sum_sq == best_sum){\n                if(st.same_edges > best_same) better = true;\n                else if(st.same_edges == best_same){\n                    if(st.diff_edges < best_diff) better = true;\n                    else if(st.diff_edges == best_diff){\n                        if(st.moved < best_moved) better = true;\n                    }\n                }\n            }\n            if(better){\n                best_sum   = st.sum_sq;\n                best_same  = st.same_edges;\n                best_diff  = st.diff_edges;\n                best_moved = st.moved;\n                best_dir   = dir;\n                best_board = after;\n            }\n        }\n\n        board = best_board;\n        cout << best_dir << '\\n' << flush;\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** ---------- tiny fast 64-bit hash -------------------------------- */\nstatic uint64_t splitmix64(uint64_t x) {\n    x += 0x9e3779b97f4a7c15ULL;\n    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9ULL;\n    x = (x ^ (x >> 27)) * 0x94d049bb133111ebULL;\n    return x ^ (x >> 31);\n}\n\n/*** ---------- light RNG (xor-shift) -------------------------------- */\nstatic uint64_t rng_state = 123456789987654321ULL;\nstatic inline uint64_t rng64() {\n    rng_state ^= rng_state << 7;\n    rng_state ^= rng_state >> 9;\n    return rng_state;\n}\n\n/*** ---------- small undirected graph, N \u2264 100 ---------------------- */\nstruct Graph {\n    int N = 0;\n    array<array<uint64_t,2>,100> row{};          // adjacency bits\n\n    void init(int n){\n        N = n;\n        for(int i=0;i<N;i++) row[i][0]=row[i][1]=0;\n    }\n    inline void addEdge(int i,int j){\n        if(j<64){ row[i][0]|=1ULL<<j; row[j][0]|=1ULL<<i; }\n        else     { row[i][1]|=1ULL<<(j-64); row[j][1]|=1ULL<<(i-64); }\n    }\n    inline bool edge(int i,int j) const{\n        return (j<64) ? ( (row[i][0]>>j)&1ULL )\n                      : ( (row[i][1]>>(j-64))&1ULL );\n    }\n    inline int degree(int i) const{\n        return __builtin_popcountll(row[i][0]) +\n               __builtin_popcountll(row[i][1]);\n    }\n};\n\n/*** ---------- canonical bitset of a graph -------------------------- */\nstruct Canon {\n    vector<uint64_t> bits;           // length = ceil(T/64)\n};\n\nstatic Canon canonicalise(const Graph& g)\n{\n    const int N = g.N;\n    vector<uint64_t> col(N);\n    for(int v=0; v<N; ++v) col[v] = g.degree(v);          // initial colour\n\n    vector<uint64_t> ncol(N);\n    for(int it=0; it<4; ++it){\n        for(int v=0; v<N; ++v){\n            uint64_t h1=0, h2=0;\n            for(int u=0; u<N; ++u) if(g.edge(v,u)){\n                h1 += col[u];\n                h2 += splitmix64(col[u]);\n            }\n            ncol[v] = splitmix64(col[v]^h1^splitmix64(h2));\n        }\n        col.swap(ncol);\n    }\n\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    stable_sort(ord.begin(), ord.end(),\n                [&](int a,int b){ return col[a]<col[b]; });\n\n    const size_t TOT = N*(N-1)/2;\n    const size_t W   = (TOT+63)>>6;\n    vector<uint64_t> bits(W,0ULL);\n\n    size_t idx = 0;\n    for(int i=0;i<N;i++){\n        int oi = ord[i];\n        for(int j=i+1;j<N;j++){\n            int oj = ord[j];\n            if(g.edge(oi,oj)) bits[idx>>6] |= 1ULL<<(idx&63);\n            ++idx;\n        }\n    }\n    return { move(bits) };\n}\n\n/*** ---------- helpers ---------------------------------------------- */\ninline int hamming(const vector<uint64_t>& A,\n                   const vector<uint64_t>& B)\n{\n    int s = 0;\n    for(size_t i=0;i<A.size();i++)\n        s += __builtin_popcountll(A[i]^B[i]);\n    return s;\n}\n\n/*** ---------- main -------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M; double eps;\n    if(!(cin>>M>>eps)) return 0;\n\n    /* choose N depending on \u03b5 */\n    int N;\n    if(eps<=0.12)       N=24;\n    else if(eps<=0.20)  N=30;\n    else if(eps<=0.28)  N=40;\n    else if(eps<=0.36)  N=55;\n    else                N=70;\n\n    const size_t TOT = N*(N-1)/2;\n    const size_t WORDS = (TOT+63)>>6;\n\n    cout<<N<<\"\\n\";\n\n    /* -------- build catalogue -------------------------------------- */\n    vector<Canon> cat(M);\n    vector<string> outStr(M);\n    Graph tmp; tmp.init(N);\n\n    for(int k=0;k<M;k++){\n        tmp.init(N);\n        string s; s.reserve(TOT);\n\n        for(int i=0;i<N;i++)\n            for(int j=i+1;j<N;j++){\n                bool e = rng64() & 1ULL;          // p = 0.5\n                s.push_back(e?'1':'0');\n                if(e) tmp.addEdge(i,j);\n            }\n\n        cat[k] = canonicalise(tmp);\n        outStr[k] = move(s);\n        cout<<outStr[k]<<\"\\n\";\n    }\n    cout.flush();\n\n    /* -------- answer 100 queries ----------------------------------- */\n    for(int q=0;q<100;q++){\n        string hs; cin>>hs;\n        Graph H; H.init(N);\n        size_t idx=0;\n        for(int i=0;i<N;i++)\n            for(int j=i+1;j<N;j++)\n                if(hs[idx++]=='1') H.addEdge(i,j);\n\n        Canon CH = canonicalise(H);\n\n        int best = 0, bestDist = INT_MAX;\n        for(int k=0;k<M;k++){\n            int d = hamming(CH.bits, cat[k].bits);\n            if(d<bestDist){ bestDist=d; best=k; }\n        }\n        cout<<best<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int MAX_D = 30;                     // statement limit\nusing  Clock  = chrono::steady_clock;\n\n/* ------------------------------------------------------------ */\nstruct Edge { int u, v, w; int imp = 0; };\n\n/* ---------- shortest-path-tree importance ------------------- */\nvoid accumulate_importance(int s,\n    const vector<vector<pair<int,int>>>& adj,      // (to, edgeID)\n    vector<Edge>& E, vector<long long>& dist,\n    vector<int>& parent)\n{\n    const long long INF = (1LL<<60);\n    fill(dist.begin(), dist.end(), INF);\n    fill(parent.begin(), parent.end(), -1);\n\n    using Q = pair<long long,int>;\n    priority_queue<Q, vector<Q>, greater<Q>> pq;\n    dist[s] = 0;  pq.emplace(0LL, s);\n\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        for (auto [to, id] : adj[v]) {\n            long long nd = d + E[id].w;\n            if (nd < dist[to]) {\n                dist[to] = nd;\n                parent[to] = id;\n                pq.emplace(nd, to);\n            }\n        }\n    }\n    const int N = dist.size();\n    for (int v = 0; v < N; ++v)\n        if (v != s && parent[v] >= 0) ++E[parent[v]].imp;\n}\n\n/* ---------- connectivity test (edges of day \u2018ban\u2019) ---------- */\nbool connected_without_day(int ban,\n    const vector<Edge>& E, const vector<int>& day,\n    const vector<vector<pair<int,int>>>& adj, vector<int>& vis)\n{\n    const int N = adj.size();\n    fill(vis.begin(), vis.end(), 0);\n    vis[0] = 1;\n    static int que[1024];                       // N \u2264 1000\n    int qh = 0, qt = 0;  que[qt++] = 0;\n\n    while (qh < qt) {\n        int v = que[qh++];\n        for (auto [to, id] : adj[v])\n            if (day[id] != ban && !vis[to]) {\n                vis[to] = 1;  que[qt++] = to;\n            }\n    }\n    for (int v = 0; v < N; ++v) if (!vis[v]) return false;\n    return true;\n}\n\n/* ------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------------- read input ---------------- */\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<Edge> E(M);\n    vector<int> deg(N, 0);\n    for (int i = 0; i < M; ++i) {\n        cin >> E[i].u >> E[i].v >> E[i].w;\n        --E[i].u; --E[i].v;\n        ++deg[E[i].u]; ++deg[E[i].v];\n    }\n    for (int i = 0, x, y; i < N; ++i) cin >> x >> y;   // coords ignored\n\n    /* ---------------- build adjacency ---------------- */\n    vector<vector<pair<int,int>>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        adj[E[i].u].push_back({E[i].v, i});\n        adj[E[i].v].push_back({E[i].u, i});\n    }\n\n    /* ---------------- edge importance ---------------- */\n    vector<long long> dist(N);\n    vector<int> parent(N);\n    std::mt19937 rng(20240517u);\n    for (int it = 0; it < 20; ++it) {\n        int s = rng() % N;\n        accumulate_importance(s, adj, E, dist, parent);\n    }\n\n    vector<int> importance(M);\n    for (int i = 0; i < M; ++i) importance[i] = E[i].imp;\n\n    /* ---------------- capacities per (v,d) ------------ */\n    vector< array<uint8_t, MAX_D> > cap(N);\n    for (int v = 0; v < N; ++v) {\n        int base = deg[v] / D, rem = deg[v] % D;\n        int shift = rng() % D;\n        for (int i = 0; i < D; ++i) {\n            int d = (i + shift) % D;\n            cap[v][d] = base + (i < rem ? 1 : 0);\n        }\n    }\n\n    /* ---------------- greedy construction ------------- */\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    shuffle(order.begin(), order.end(), rng);\n    sort(order.begin(), order.end(), [&](int a, int b){\n        return importance[a] > importance[b];\n    });\n\n    vector<int> day(M, -1);\n    vector<int16_t> load(D, 0);\n    vector< array<int16_t, MAX_D> > used(N);  for (auto& a: used) a.fill(0);\n    vector<long long> dayImp(D, 0);\n\n    for (int id : order) {\n        int u = E[id].u, v = E[id].v, imp = importance[id];\n        long long bestScore = (1LL<<60);\n        int bestDay = -1;\n\n        for (int d = 0; d < D; ++d) if (load[d] < K) {\n            long long score = 20LL * (used[u][d] + used[v][d])\n                            + dayImp[d];\n            if (score < bestScore) {\n                bestScore = score;\n                bestDay = d;\n            }\n        }\n        if (bestDay < 0) bestDay =\n              int(min_element(load.begin(), load.end()) - load.begin());\n\n        day[id] = bestDay;\n        ++load[bestDay];\n        dayImp[bestDay] += imp;\n        ++used[u][bestDay];\n        ++used[v][bestDay];\n    }\n\n    /* ---------------- simulated annealing ------------- */\n    auto cost_now = [&]()->long long{\n        long long vc = 0, dc = 0;\n        for (int v = 0; v < N; ++v)\n            for (int d = 0; d < D; ++d)\n                vc += 1LL * used[v][d] * used[v][d];\n        for (int d = 0; d < D; ++d) dc += dayImp[d] * dayImp[d];\n        return vc + dc;\n    };\n    long long bestCost = cost_now();\n    vector<int> bestDay = day;\n\n    const double LIMIT = 3.8;            // seconds for SA\n    const double T0 = 1.0, T1 = 0.01;\n    auto t_start = Clock::now();\n    uniform_real_distribution<double> U01(0,1);\n\n    vector<int> candidateDays(D);\n    for (long long iter = 1; ; ++iter) {\n        if ((iter & 4095) == 0) {\n            double t = chrono::duration<double>(Clock::now()-t_start).count();\n            if (t >= LIMIT) break;\n        }\n        double prog = chrono::duration<double>(Clock::now()-t_start).count()\n                      / LIMIT;\n        double Temp = T0 * pow(T1/T0, prog);\n\n        int id = rng() % M;\n        int d0 = day[id];\n        int d1 = rng() % D;\n        if (d1 == d0 || load[d1] >= K) continue;\n\n        int u = E[id].u, v = E[id].v;\n        int imp = importance[id];\n\n        /* \u0394 vertex term */\n        long long delta =\n            -1LL*used[u][d0]*used[u][d0] - 1LL*used[v][d0]*used[v][d0]\n            -1LL*used[u][d1]*used[u][d1] - 1LL*used[v][d1]*used[v][d1]\n            +1LL*(used[u][d0]-1)*(used[u][d0]-1)\n            +1LL*(used[v][d0]-1)*(used[v][d0]-1)\n            +1LL*(used[u][d1]+1)*(used[u][d1]+1)\n            +1LL*(used[v][d1]+1)*(used[v][d1]+1);\n\n        /* \u0394 dayImportance term */\n        long long imp0 = dayImp[d0], imp1 = dayImp[d1];\n        delta += -(imp0*imp0 + imp1*imp1)\n                 +(imp0-imp)*(imp0-imp) + (imp1+imp)*(imp1+imp);\n\n        if (delta <= 0 || U01(rng) < exp(-delta / Temp)) {\n            /* accept */\n            day[id] = d1;\n            --load[d0]; ++load[d1];\n            --used[u][d0]; --used[v][d0];\n            ++used[u][d1]; ++used[v][d1];\n            dayImp[d0] -= imp; dayImp[d1] += imp;\n            bestCost += delta;\n            if (bestCost < 0) bestCost = 0;      // guard\n\n            if (bestCost <  /* previous best */ 0 ||\n                rng() == 0) {}                   // dummy, we always keep\n            if (bestCost < cost_now()) {         // improved real cost\n                bestCost = cost_now();\n                bestDay  = day;\n            }\n        }\n    }\n\n    /* rebuild arrays for best solution */\n    day = bestDay;\n    fill(load.begin(), load.end(), 0);\n    for (auto& a: used) a.fill(0);\n    fill(dayImp.begin(), dayImp.end(), 0);\n    for (int i = 0; i < M; ++i) {\n        ++load[ day[i] ];\n        ++used[E[i].u][ day[i] ];\n        ++used[E[i].v][ day[i] ];\n        dayImp[ day[i] ] += importance[i];\n    }\n\n    /* ---------------- connectivity repair --------------- */\n    vector<vector<int>> edgesOfDay(D);\n    for (int d = 0; d < D; ++d) edgesOfDay[d].clear();\n    for (int i = 0; i < M; ++i) edgesOfDay[ day[i] ].push_back(i);\n\n    vector<int> vis(N);\n    for (int d = 0; d < D; ++d) {\n        bool changed = true;\n        while (changed && !connected_without_day(d, E, day, adj, vis)) {\n            changed = false;\n            /* recompute components */\n            fill(vis.begin(), vis.end(), -1);\n            int compCnt = 0;\n            static int q[1024];\n            for (int s = 0; s < N; ++s) if (vis[s] < 0) {\n                int qs = 0, qe = 0; q[qe++] = s; vis[s] = compCnt;\n                while (qs < qe) {\n                    int v = q[qs++];\n                    for (auto [to, id] : adj[v])\n                        if (day[id] != d && vis[to] < 0) {\n                            vis[to] = compCnt;\n                            q[qe++] = to;\n                        }\n                }\n                ++compCnt;\n            }\n            if (compCnt == 1) break;\n\n            /* try to move one crossing edge */\n            for (int idx = 0; idx < (int)edgesOfDay[d].size(); ++idx) {\n                int id = edgesOfDay[d][idx];\n                int u = E[id].u, v = E[id].v;\n                if (vis[u] == vis[v]) continue;        // not crossing\n                /* pick target day with room */\n                int best = -1;\n                for (int t = 0; t < D; ++t)\n                    if (t != d && load[t] < K) { best = t; break; }\n                if (best < 0) continue;                // should not happen\n\n                /* perform move */\n                day[id] = best;\n                ++load[best]; --load[d];\n                ++used[u][best]; ++used[v][best];\n                --used[u][d];   --used[v][d];\n                dayImp[d]  -= importance[id];\n                dayImp[best]+= importance[id];\n\n                edgesOfDay[best].push_back(id);\n                edgesOfDay[d][idx] = edgesOfDay[d].back();\n                edgesOfDay[d].pop_back();\n\n                changed = true;\n                break;\n            }\n        }\n    }\n\n    /* ---------------- output ----------------------------- */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << day[i] + 1;\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pillar {\n    vector<int> vox;                     // sorted by increasing z\n};\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D;\n    if (!(cin >> D)) return 0;\n\n    /* ---------------- read silhouettes ---------------- */\n    vector<vector<string>> F(2, vector<string>(D));\n    vector<vector<string>> R(2, vector<string>(D));\n    for (int k = 0; k < 2; ++k) {\n        for (int z = 0; z < D; ++z) cin >> F[k][z];\n        for (int z = 0; z < D; ++z) cin >> R[k][z];\n    }\n\n    const int SZ = D * D * D;\n    auto idx = [D](int x, int y, int z) { return x * D * D + y * D + z; };\n\n    /* ---------- 1. minimal\u2013rook construction (occ1 / occ2) ---------- */\n    vector<char> occ1(SZ, 0), occ2(SZ, 0);\n    auto build_slice = [&](int obj, int z, vector<char>& occ) {\n        vector<int> X, Y;\n        for (int x = 0; x < D; ++x) if (F[obj][z][x] == '1') X.push_back(x);\n        for (int y = 0; y < D; ++y) if (R[obj][z][y] == '1') Y.push_back(y);\n\n        /* intersection rows / columns that are allowed for both objects */\n        vector<char> markX(D,0), markY(D,0);\n        for (int x:X) markX[x]=1;\n        vector<int> Xc, Yc;\n        for (int x = 0; x < D; ++x)\n            if (markX[x] && F[obj^1][z][x]=='1') Xc.push_back(x);\n        for (int y:Y) markY[y]=1;\n        for (int y = 0; y < D; ++y)\n            if (markY[y] && R[obj^1][z][y]=='1') Yc.push_back(y);\n\n        int kshare = min<int>(Xc.size(), Yc.size());\n        vector<char> row(D,0), col(D,0);\n\n        /* shared rooks first */\n        for (int i = 0; i < kshare; ++i) {\n            int x = Xc[i], y = Yc[i];\n            occ[idx(x,y,z)] = 1;\n            row[x] = col[y] = 1;\n        }\n        /* remaining rows */\n        int cy = 0;\n        for (int x:X) if (!row[x]) {\n            int y = Y[cy % Y.size()];\n            occ[idx(x,y,z)] = 1;\n            row[x] = col[y] = 1;\n            ++cy;\n        }\n        /* remaining columns */\n        int cx = 0;\n        for (int y:Y) if (!col[y]) {\n            int x = X[cx % X.size()];\n            occ[idx(x,y,z)] = 1;\n            row[x] = col[y] = 1;\n            ++cx;\n        }\n    };\n    for (int z = 0; z < D; ++z) {\n        build_slice(0, z, occ1);\n        build_slice(1, z, occ2);\n    }\n\n    /* ---------- 2. cut each object into vertical pillars ---------- */\n    auto collect = [&](const vector<char>& occ,\n                       vector<unique_ptr<Pillar>>& store) {\n        for (int x = 0; x < D; ++x) for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ) {\n                if (occ[idx(x,y,z)]) {\n                    auto p = make_unique<Pillar>();\n                    int z0 = z;\n                    while (z < D && occ[idx(x,y,z)])\n                        p->vox.push_back(idx(x,y,z++));\n                    store.emplace_back(std::move(p));\n                } else ++z;\n            }\n        }\n    };\n    vector<unique_ptr<Pillar>> P1, P2;\n    collect(occ1, P1);\n    collect(occ2, P2);\n\n    /* ---------- 3. pair pillars \u2013 allow splitting ------------------ */\n    auto cmp = [](Pillar* a, Pillar* b){ return a->vox.size() < b->vox.size(); };\n    priority_queue<Pillar*, vector<Pillar*>, decltype(cmp)> Q1(cmp), Q2(cmp);\n    for (auto& p:P1) Q1.push(p.get());\n    for (auto& p:P2) Q2.push(p.get());\n\n    vector<int> b1(SZ,0), b2(SZ,0);\n    int nextId = 1;\n\n    while (!Q1.empty() && !Q2.empty()) {\n        Pillar* a = Q1.top(); Q1.pop();\n        Pillar* b = Q2.top(); Q2.pop();\n        if (a->vox.empty() || b->vox.empty()) continue;   // safety\n\n        int L = (int)min(a->vox.size(), b->vox.size());\n        int id = nextId++;\n\n        for (int i = 0; i < L; ++i) {\n            int pa = a->vox.back(); a->vox.pop_back();\n            int pb = b->vox.back(); b->vox.pop_back();\n            b1[pa] = id;\n            b2[pb] = id;\n        }\n        if (!a->vox.empty()) Q1.push(a);\n        if (!b->vox.empty()) Q2.push(b);\n    }\n\n    /* ---------- 4. remaining voxels \u2192 singles, pair if possible ---- */\n    vector<int> sing1, sing2;\n    for (auto& p:P1)\n        for (int v:p->vox) if (!b1[v]) sing1.push_back(v);\n    for (auto& p:P2)\n        for (int v:p->vox) if (!b2[v]) sing2.push_back(v);\n\n    size_t m = min(sing1.size(), sing2.size());\n    for (size_t i = 0; i < m; ++i) {\n        int id = nextId++;\n        b1[sing1[i]] = id;\n        b2[sing2[i]] = id;\n    }\n    for (size_t i = m; i < sing1.size(); ++i) {\n        int id = nextId++;\n        b1[sing1[i]] = id;                    // unique to object-1\n    }\n    for (size_t i = m; i < sing2.size(); ++i) {\n        int id = nextId++;\n        b2[sing2[i]] = id;                    // unique to object-2\n    }\n\n    /* ---------- 5. output ----------------------------------------- */\n    cout << nextId-1 << '\\n';\n    for (int i = 0; i < SZ; ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n    for (int i = 0; i < SZ; ++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\n/* ------------------------------------------------- geometry -------------- */\ninline int ceilDist(int x1,int y1,int x2,int y2){\n    long long dx = 1LL*x1 - x2, dy = 1LL*y1 - y2;\n    return int(std::ceil(std::sqrt(double(dx*dx + dy*dy))));\n}\n/* ----------------------------------------------------- DSU --------------- */\nstruct DSU{\n    vector<int> p,sz;\n    DSU(int n=0):p(n),sz(n,1){iota(p.begin(),p.end(),0);}\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(sz[a]<sz[b]) swap(a,b);\n        p[b]=a; sz[a]+=sz[b]; return true;\n    }\n};\n/* ------------------------------------------------------- main ------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    const int MAX_R = 5000;\n    int N,M,K; if(!(cin>>N>>M>>K)) return 0;\n\n    vector<int> vx(N),vy(N);\n    for(int i=0;i<N;++i) cin>>vx[i]>>vy[i];\n\n    struct Edge{int u,v; long long w;};\n    vector<Edge> es(M);\n    vector<vector<pair<int,int>>> g(N);\n    for(int i=0;i<M;++i){\n        int a,b; long long w; cin>>a>>b>>w; --a;--b;\n        es[i]={a,b,w};\n        g[a].push_back({b,i});\n        g[b].push_back({a,i});\n    }\n\n    vector<int> rx(K),ry(K);\n    for(int k=0;k<K;++k) cin>>rx[k]>>ry[k];\n\n    /* ------------- all distances vertex\u2194resident + lists within 5000 ------ */\n    vector<vector<int>> distVR(N,vector<int>(K));\n    vector<vector<pair<int,int>>> cov(N);               // (resident,dist) d<=5000\n    for(int v=0;v<N;++v){\n        for(int k=0;k<K;++k){\n            int d = ceilDist(vx[v],vy[v],rx[k],ry[k]);\n            distVR[v][k]=d;\n            if(d<=MAX_R) cov[v].push_back({k,d});\n        }\n    }\n\n    /* ---------------- root\u2192vertex shortest-path tree ---------------------- */\n    const long long INF64 = (1LL<<60);\n    vector<long long> dist(N,INF64);\n    vector<int> parV(N,-1),parE(N,-1);\n    using Pair = pair<long long,int>;\n    priority_queue<Pair,vector<Pair>,greater<Pair>> 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 [to,idx]:g[u]){\n            long long nd=d+es[idx].w;\n            if(nd<dist[to]){\n                dist[to]=nd; parV[to]=u; parE[to]=idx; pq.push({nd,to});\n            }\n        }\n    }\n    auto path_add_cost = [&](int v,const vector<char>& on,vector<int>& buf)->long long{\n        long long add=0; buf.clear();\n        while(v!=0){\n            int e=parE[v];\n            if(!on[e]) add+=es[e].w, buf.push_back(e);\n            v=parV[v];\n        }\n        return add;\n    };\n    auto turn_on_path = [&](int v,vector<char>& on){\n        while(v!=0){ on[parE[v]]=1; v=parV[v]; }\n    };\n\n    /* ---------------- phase-1 : greedy cover ------------------------------ */\n    vector<char> covered(K,0), chosen(N,0), edgeOn(M,0);\n    vector<int> P(N,0);\n    int coveredCnt=0;\n    vector<int> scratch;\n    while(coveredCnt<K){\n        int bestV=-1,bestR=0,bestGain=0; double bestScore=-1; long long bestAdd=0;\n        for(int v=0;v<N;++v) if(!chosen[v]){\n            int gain=0,rad=0;\n            for(auto [rid,d]:cov[v]) if(!covered[rid]){++gain; rad=max(rad,d);}\n            if(!gain) continue;\n            long long add=path_add_cost(v,edgeOn,scratch);\n            double sc = double(gain)/(double(add)+1.0*rad*rad);\n            if(sc>bestScore){bestScore=sc; bestV=v; bestR=rad; bestGain=gain; bestAdd=add;}\n        }\n        chosen[bestV]=1; P[bestV]=bestR;\n        for(auto [rid,d]:cov[bestV]) if(!covered[rid] && d<=bestR){covered[rid]=1;++coveredCnt;}\n        turn_on_path(bestV,edgeOn);\n    }\n\n    /* ---------------- helper containers ---------------------------------- */\n    vector<int> assign(K,-1), assignD(K,MAX_R+1);\n    vector<vector<int>> resByV(N);\n    vector<int> radius(N,0);\n\n    auto rebuild_lists = [&](){\n        for(int v=0;v<N;++v){resByV[v].clear(); radius[v]=0;}\n        for(int k=0;k<K;++k){\n            resByV[assign[k]].push_back(k);\n            radius[assign[k]]=max(radius[assign[k]],assignD[k]);\n        }\n    };\n    /* ------------- phase-2 : safe shrink (nearest within 5000) ------------ */\n    for(int k=0;k<K;++k){\n        int bestV=-1,bestD=MAX_R+1;\n        for(int v=0;v<N;++v) if(chosen[v]){\n            int d=distVR[v][k];\n            if(d<=MAX_R && d<bestD){bestD=d; bestV=v;}\n        }\n        if(bestV==-1){               // shouldn\u2019t happen, but be safe\n            for(int v=0;v<N;++v) if(distVR[v][k]<=MAX_R){bestV=v; chosen[v]=1; turn_on_path(v,edgeOn); break;}\n            bestD = distVR[bestV][k];\n        }\n        assign[k]=bestV; assignD[k]=bestD;\n    }\n    rebuild_lists();\n\n    /* ------------- phase-3 : cheap add-only local search ------------------ */\n    auto current_S = [&]()->long long{\n        long long s=0;\n        for(int v=0;v<N;++v) s+=1LL*radius[v]*radius[v];\n        for(int e=0;e<M;++e) if(edgeOn[e]) s+=es[e].w;\n        return s;\n    };\n    auto startT = chrono::high_resolution_clock::now();\n    vector<int> moved;\n    while(true){\n        long long bestDelta = 0;\n        int bestV=-1;\n        long long curS = current_S();\n        for(int v=0;v<N;++v) if(!chosen[v]){\n            moved.clear();\n            int radNew=0;\n            for(auto [rid,d]:cov[v]) if(d<assignD[rid]){\n                moved.push_back(rid); radNew=max(radNew,d);\n            }\n            if(moved.empty()) continue;\n            /* edge cost */\n            long long addEdge=path_add_cost(v,edgeOn,scratch);\n            /* radius of affected old stations after move */\n            unordered_set<int> affected;\n            for(int rid:moved) affected.insert(assign[rid]);\n            long long delta = addEdge + 1LL*radNew*radNew;\n            for(int s:affected){\n                int newR=0;\n                for(int rid:resByV[s])\n                    if(find(moved.begin(),moved.end(),rid)==moved.end())\n                        newR=max(newR,assignD[rid]);\n                delta += 1LL*newR*newR - 1LL*radius[s]*radius[s];\n            }\n            if(delta<bestDelta){ bestDelta=delta; bestV=v; }\n        }\n        if(bestV==-1) break;\n        /* apply the best move */\n        chosen[bestV]=1;\n        turn_on_path(bestV,edgeOn);\n        for(auto [rid,d]:cov[bestV]) if(d<assignD[rid]){\n            assign[rid]=bestV; assignD[rid]=d;\n        }\n        rebuild_lists();\n        /* time limit guard (~1.8 s) */\n        if(chrono::duration<double>(chrono::high_resolution_clock::now()-startT).count()>1.8) break;\n    }\n\n    /* ------------- phase-4 : Steiner-like tree (MST + prune) -------------- */\n    DSU dsu(N);\n    vector<int> ord(M); iota(ord.begin(),ord.end(),0);\n    sort(ord.begin(),ord.end(),[&](int a,int b){return es[a].w<es[b].w;});\n    vector<char> inMST(M,0);\n    for(int id:ord){\n        auto &e=es[id];\n        if(dsu.unite(e.u,e.v)) inMST[id]=1;\n    }\n    vector<vector<int>> adj(N);\n    for(int i=0;i<M;++i) if(inMST[i]){\n        adj[es[i].u].push_back(i);\n        adj[es[i].v].push_back(i);\n    }\n    vector<char> terminal(N,0);\n    for(int v=0;v<N;++v) if(chosen[v]) terminal[v]=1;\n    terminal[0]=1;                             // root\n    queue<int> q;\n    vector<int> deg(N);\n    for(int v=0;v<N;++v){deg[v]=adj[v].size(); if(deg[v]==1 && !terminal[v]) q.push(v);}\n    while(!q.empty()){\n        int v=q.front(); q.pop();\n        for(int ei:adj[v]) if(inMST[ei]){\n            int u = es[ei].u==v? es[ei].v : es[ei].u;\n            inMST[ei]=0;\n            if(--deg[u]==1 && !terminal[u]) q.push(u);\n        }\n    }\n    vector<char> edgeFinal(M,0);\n    for(int i=0;i<M;++i) if(inMST[i]) edgeFinal[i]=1;\n\n    /* ------------- final radii (guaranteed \u2264 5000) ------------------------ */\n    vector<int> finalP(N,0);\n    for(int v=0;v<N;++v) if(chosen[v]) finalP[v]=radius[v];\n\n    /* --------------------------- output ----------------------------------- */\n    for(int i=0;i<N;++i){ if(i) cout<<' '; cout<<finalP[i]; }\n    cout<<\"\\n\";\n    for(int i=0;i<M;++i){ if(i) cout<<' '; cout<<int(edgeFinal[i]); }\n    cout<<\"\\n\";\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    /* read input */\n    vector<vector<int>> a(N);\n    for (int x = 0; x < N; ++x) {\n        a[x].resize(x + 1);\n        for (int y = 0; y <= x; ++y) cin >> a[x][y];\n    }\n\n    vector<Swap> ops;\n    ops.reserve(5000);          // worst-case 4 495\n\n    auto do_swap = [&](int x1, int y1, int x2, int y2) {\n        swap(a[x1][y1], a[x2][y2]);\n        ops.push_back({x1, y1, x2, y2});\n    };\n\n    /* bottom-up heapify (Floyd) */\n    for (int x = N - 2; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int cx = x, cy = y;\n            while (cx < N - 1) {\n                int lx = cx + 1, ly = cy;       // left child\n                int rx = cx + 1, ry = cy + 1;   // right child\n\n                int minx = lx, miny = ly;\n                if (a[rx][ry] < a[lx][ly]) {\n                    minx = rx;\n                    miny = ry;\n                }\n                if (a[cx][cy] <= a[minx][miny]) break;\n\n                do_swap(cx, cy, minx, miny);\n                cx = minx;\n                cy = miny;\n            }\n        }\n    }\n\n    /* safeguard \u2013 in the very unlikely event we overshoot */\n    if (ops.size() > 10000) ops.resize(10000);\n\n    /* output */\n    cout << ops.size() << '\\n';\n    for (auto &s: ops)\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ------------------------------------------------------------ */\nstruct Pos{int r,c;};\nconst int DR[4]={-1,1,0,0};\nconst int DC[4]={0,0,-1,1};\n\nusing Grid = vector<vector<int>>;      // -2 obstacle, -1 empty, >=0 container id\nconstexpr int OBST  = -2;\nconstexpr int EMPTY = -1;\n\n/* ------------------------------------------------------------ */\ninline bool inside(int r,int c,int D){ return 0<=r && r<D && 0<=c && c<D; }\n\n/* BFS over EMPTY cells; fills dist and returns list of visited empties */\nvector<Pos> bfs_empty(const Grid& g,const Pos& ent,\n                      vector<vector<int>>& dist)\n{\n    int D=g.size();\n    dist.assign(D, vector<int>(D,-1));\n    vector<Pos> lst;\n    queue<Pos> q;\n    q.push(ent);\n    dist[ent.r][ent.c]=0;\n    while(!q.empty()){\n        auto [r,c]=q.front(); q.pop();\n        lst.push_back({r,c});\n        for(int d=0;d<4;++d){\n            int nr=r+DR[d], nc=c+DC[d];\n            if(!inside(nr,nc,D)) continue;\n            if(g[nr][nc]==EMPTY && dist[nr][nc]==-1){\n                dist[nr][nc]=dist[r][c]+1;\n                q.push({nr,nc});\n            }\n        }\n    }\n    return lst;\n}\n\n/* does placing a container on p keep all empties reachable? */\nbool safe_to_place(Grid& g,const Pos& p,const Pos& ent,\n                   vector<vector<int>>& buf)\n{\n    g[p.r][p.c]=OBST;                      // temporary wall\n    bfs_empty(g, ent, buf);\n    bool ok=true;\n    for(int r=0;r<g.size() && ok;++r)\n        for(int c=0;c<g.size();++c)\n            if(g[r][c]==EMPTY && buf[r][c]==-1){ ok=false; break; }\n    g[p.r][p.c]=EMPTY;                     // restore\n    return ok;\n}\n\n/* container at (r,c) is currently reachable? */\ninline bool container_reachable(const Grid& g,int r,int c,\n                                const vector<vector<int>>& dist)\n{\n    int D=g.size();\n    for(int d=0;d<4;++d){\n        int nr=r+DR[d], nc=c+DC[d];\n        if(inside(nr,nc,D) && dist[nr][nc]>=0) return true;\n    }\n    return false;\n}\n\n/* ------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D,N;\n    if(!(cin>>D>>N)) return 0;\n    const Pos ENTR{0,(D-1)/2};\n\n    Grid g(D, vector<int>(D,EMPTY));\n    for(int i=0;i<N;++i){\n        int r,c; cin>>r>>c;\n        g[r][c]=OBST;\n    }\n    const int K = D*D-1-N;            // number of containers\n\n    /* obstacle-aware shortest-path tree and parent pointers */\n    vector<vector<int>> distStatic(D, vector<int>(D,-1));\n    vector<vector<Pos>> parent(D, vector<Pos>(D, {-1,-1}));\n    {\n        queue<Pos> q;\n        q.push(ENTR);\n        distStatic[ENTR.r][ENTR.c]=0;\n        while(!q.empty()){\n            auto [r,c]=q.front(); q.pop();\n            for(int d=0;d<4;++d){\n                int nr=r+DR[d], nc=c+DC[d];\n                if(!inside(nr,nc,D)) continue;\n                if(g[nr][nc]==OBST || distStatic[nr][nc]!=-1) continue;\n                distStatic[nr][nc]=distStatic[r][c]+1;\n                parent[nr][nc]={r,c};\n                q.push({nr,nc});\n            }\n        }\n    }\n\n    vector<Pos> idPos(K);             // final square of each id\n    vector<vector<int>> distBuf, distBuf2;\n\n    /* -------------------- placement -------------------- */\n    const double GAMMA = 1.25;        // >1 pushes extremes further\n    for(int step=0; step<K; ++step){\n        int id; cin>>id;\n\n        /* reachable empties right now */\n        auto reachable = bfs_empty(g, ENTR, distBuf);\n\n        /* remove entrance itself */\n        reachable.erase(remove_if(reachable.begin(), reachable.end(),\n                     [&](const Pos&p){return p.r==ENTR.r && p.c==ENTR.c;}),\n                     reachable.end());\n\n        /* keep only safe candidates (still one step, small board) */\n        vector<Pos> safe;\n        safe.reserve(reachable.size());\n        for(const auto& p: reachable)\n            if(safe_to_place(g,p,ENTR,distBuf2)) safe.push_back(p);\n        const vector<Pos>& cand = safe.empty()? reachable : safe;\n\n        /* sort by static distance from entrance */\n        vector<Pos> cells = cand;\n        sort(cells.begin(), cells.end(),\n             [&](const Pos&a,const Pos&b){\n                 int da = distStatic[a.r][a.c];\n                 int db = distStatic[b.r][b.c];\n                 return da!=db ? da<db : tie(a.r,a.c)<tie(b.r,b.c);\n             });\n\n        /* exponential quantile */\n        double ratio = static_cast<double>(id)/(K-1);      // 0..1\n        double q     = pow(ratio, GAMMA);\n        int idx      = (cells.size()==1)?0:\n                       int(std::round(q*(cells.size()-1)));\n        idx = std::clamp(idx,0,int(cells.size()-1));\n\n        Pos chosen = cells[idx];\n        g[chosen.r][chosen.c]=id;\n        idPos[id]=chosen;\n\n        cout<<chosen.r<<\" \"<<chosen.c<<\"\\n\"<<flush;\n    }\n\n    /* -------------------- retrieval -------------------- */\n    vector<char> shipped(K,0);\n    vector<Pos> answer; answer.reserve(K);\n    int nextNeed=0;\n\n    while((int)answer.size()<K){\n        bfs_empty(g, ENTR, distBuf);\n\n        if(nextNeed<K && container_reachable(g,\n                idPos[nextNeed].r,idPos[nextNeed].c,distBuf))\n        {\n            /* perfect, we can ship nextNeed */\n            Pos p = idPos[nextNeed];\n            shipped[nextNeed]=1;\n            g[p.r][p.c]=EMPTY;\n            answer.push_back(p);\n            while(nextNeed<K && shipped[nextNeed]) ++nextNeed;\n            continue;\n        }\n\n        /* otherwise follow the tree-path and take first blocker */\n        vector<Pos> path;\n        for(Pos v=idPos[nextNeed]; !(v.r==ENTR.r && v.c==ENTR.c); )\n        {\n            path.push_back(v);\n            v = parent[v.r][v.c];\n        }\n        /* walk from entrance side: last element is nextNeed, so iterate\n           backwards, skipping the entrance that is not in vector        */\n        int blockerId=-1; Pos blocker{-1,-1};\n        for(int i=int(path.size())-1; i>=0; --i){\n            Pos p = path[i];\n            if(g[p.r][p.c]>=0 && !shipped[g[p.r][p.c]]){\n                blockerId = g[p.r][p.c];\n                blocker   = p;\n                break;\n            }\n        }\n        if(blockerId==-1){                 // fall-back (should not occur)\n            for(int id=0; id<K; ++id) if(!shipped[id]){\n                blockerId=id; blocker=idPos[id]; break;\n            }\n        }\n        shipped[blockerId]=1;\n        g[blocker.r][blocker.c]=EMPTY;\n        answer.push_back(blocker);\n    }\n\n    for(const auto& p:answer) cout<<p.r<<\" \"<<p.c<<\"\\n\";\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 50;     // fixed\nconstexpr int M = 100;\nconst int DX[4] = {-1, 1, 0, 0};\nconst int DY[4] = {0, 0, -1, 1};\n\nstruct State {\n    int  g[N][N];                 // current grid\n    int  cnt[M + 1]{};            // remaining cells per colour\n    int  adj[M + 1][M + 1]{};     // unordered edge counts, 0-based\n    bool orig0Adj[M + 1]{};       // was (0,c) adjacent in the input?\n    bool inQ[N][N]{};             // helper for the flood queue\n} st;\n\n/* --------------------------------------------------------------- */\ninline bool inside(int x, int y) { return 0 <= x && x < N && 0 <= y && y < N; }\n\ninline void addEdge(int a, int b, int delta) {\n    if (a > b) swap(a, b);\n    st.adj[a][b] += delta;\n#ifdef DEBUG\n    if (st.adj[a][b] < 0) cerr << \"negative edge \" << a << ' ' << b << '\\n';\n#endif\n}\n\n/* ------------ input & initial edge counters -------------------- */\nvoid buildInitial() {\n    int n, m;  cin >> n >> m;           // 50 / 100\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            cin >> st.g[i][j];\n            ++st.cnt[ st.g[i][j] ];\n        }\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int c = st.g[i][j];\n            int d = (j + 1 < N) ? st.g[i][j + 1] : 0;\n            if (c != d) addEdge(c, d, +1);\n            d = (i + 1 < N) ? st.g[i + 1][j] : 0;\n            if (c != d) addEdge(c, d, +1);\n        }\n\n    for (int c = 1; c <= M; ++c) st.orig0Adj[c] = st.adj[0][c] > 0;\n}\n\n/* ---------------- connectivity of one colour ------------------- */\nbool connectedAfterRemoval(int x, int y, int col) {\n    bool vis[N][N] = {};\n    queue<pair<int,int>> q;\n    for (int i = 0; i < N && q.empty(); ++i)\n        for (int j = 0; j < N; ++j)\n            if (st.g[i][j] == col && !(i == x && j == y)) {\n                q.emplace(i, j); vis[i][j] = true;\n                break;\n            }\n\n    int need = st.cnt[col] - 1, got = 0;\n    while (!q.empty()) {\n        auto [cx, cy] = q.front(); q.pop();\n        if (++got == need) return true;\n        for (int d = 0; d < 4; ++d) {\n            int nx = cx + DX[d], ny = cy + DY[d];\n            if (!inside(nx, ny) || vis[nx][ny] || (nx == x && ny == y)) continue;\n            if (st.g[nx][ny] == col) { vis[nx][ny] = true; q.emplace(nx, ny); }\n        }\n    }\n    return false;\n}\n\n/* ---------------- attempt to turn (x,y) into 0 ------------------ */\nbool tryRemove(int x, int y) {\n    int c = st.g[x][y];\n    if (c == 0 || st.cnt[c] == 1) return false;\n\n    int freq[M + 1] = {};               // how many sides to each neighbour colour\n    for (int d = 0; d < 4; ++d) {\n        int nx = x + DX[d], ny = y + DY[d];\n        int col = inside(nx, ny) ? st.g[nx][ny] : 0;\n        ++freq[col];\n    }\n\n    /* --- cheap legality tests ----------------------------------- */\n    for (int d = 1; d <= M; ++d) {\n        if (d == c || freq[d] == 0) continue;\n\n        if (!st.orig0Adj[d]) return false;                      // new 0-d edge forbidden\n\n        int a = min(c, d), b = max(c, d);\n        if (st.adj[a][b] - freq[d] <= 0) return false;         // last (c,d) edge gone\n    }\n    if (!connectedAfterRemoval(x, y, c)) return false;\n\n    /* --- update edge counters ----------------------------------- */\n    int f0   = freq[0];\n    int fSame= freq[c];\n\n    if (f0   ) addEdge(0, c, -f0);        // c \u2013 0 edges disappear\n    if (fSame) addEdge(0, c, +fSame);     // new 0 \u2013 c edges where neighbour is c\n\n    for (int d = 1; d <= M; ++d) if (d != c && freq[d]) {\n        addEdge(c, d, -freq[d]);          // erase (c,d)\n        addEdge(0, d, +freq[d]);          // add (0,d)\n    }\n\n    /* --- materialise the deletion ------------------------------- */\n    st.g[x][y] = 0;\n    --st.cnt[c];\n    return true;\n}\n\n/* ---------------- flood-queue driver ---------------------------- */\ninline bool touchesZero(int i, int j) {\n    if (st.g[i][j] == 0) return false;\n    for (int d = 0; d < 4; ++d) {\n        int ni = i + DX[d], nj = j + DY[d];\n        if (!inside(ni, nj) || st.g[ni][nj] == 0) return true;\n    }\n    return false;\n}\n\nvoid flood() {\n    queue<pair<int,int>> q;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (touchesZero(i, j)) { q.emplace(i, j); st.inQ[i][j] = true; }\n\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        st.inQ[x][y] = false;\n        if (st.g[x][y] == 0 || !touchesZero(x, y)) continue;\n\n        if (tryRemove(x, y)) {\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + DX[d], ny = y + DY[d];\n                if (!inside(nx, ny) || st.g[nx][ny] == 0 || st.inQ[nx][ny]) continue;\n                if (touchesZero(nx, ny)) { q.emplace(nx, ny); st.inQ[nx][ny] = true; }\n            }\n        }\n    }\n}\n\n/* ---------------- main ------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    buildInitial();\n    flood();\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (j) cout << ' ';\n            cout << st.g[i][j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- small utilities ---------- */\nstruct FastRNG {\n    uint64_t x;\n    FastRNG() : x(chrono::steady_clock::now().time_since_epoch().count()) {}\n    uint32_t next() { x ^= x << 7; return (uint32_t)(x ^= x >> 9); }\n    template<class It> void shuffle(It first, It last){\n        for(auto i = (last-first); i>1; --i){\n            int j = next()%i;\n            swap(*(first+i-1), *(first+j));\n        }\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------------- read first line ---------------- */\n    int N,D,Q;\n    if(!(cin>>N>>D>>Q)) return 0;\n\n    /* ---------------- Bradley\u2013Terry / Elo ----------------\n       rating r_i  (real numbers)\n       P(i beats j) = 1 / (1+exp(-(r_i-r_j)))\n       update with learning-rate K   r += K*(S - P)\n    ------------------------------------------------------ */\n    const double K = 1.6;              // slightly aggressive\n    vector<double> rating(N, 0.0);\n\n    /* ---------------- schedule comparisons ------------- */\n    vector<pair<int,int>> pairs;\n    pairs.reserve(N*(N-1)/2);\n    for(int i=0;i<N;++i) for(int j=i+1;j<N;++j) pairs.emplace_back(i,j);\n\n    FastRNG rng;\n    rng.shuffle(pairs.begin(), pairs.end());\n\n    /* ---------------- perform informative queries ------ */\n    int used = 0, idx = 0;\n    auto ask = [&](int a,int b){\n        cout << 1 << ' ' << 1 << ' ' << a << ' ' << b << '\\n' << flush;\n        string res; cin >> res;\n        ++used;\n        if(res==\">\"||res==\"<\"){                // ignore '=' (practically never happens)\n            bool aWins = (res==\">\");\n            double ra = rating[a], rb = rating[b];\n            double p  = 1.0 / (1.0 + exp(rb - ra));\n            double diff = K * ((aWins?1.0:0.0) - p);\n            rating[a] += diff;\n            rating[b] -= diff;\n        }\n    };\n\n    while(used < Q && idx < (int)pairs.size()){\n        auto [a,b] = pairs[idx++];\n        ask(a,b);\n    }\n    /* -------------- consume possible leftover queries -- */\n    while(used < Q){ ask(0,1); }        // ignored but fulfils protocol\n\n    /* ---------------- derive positive weights ---------- */\n    double mn = *min_element(rating.begin(), rating.end());\n    vector<double> w(N);\n    for(int i=0;i<N;++i) w[i] = rating[i]-mn + 1e-3;   // >0\n\n    /* ---------------- initial greedy LPT --------------- */\n    struct Bag{ double sum=0; vector<int> items; };\n    vector<Bag> bag(D);\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a,int b){ return w[a]>w[b]; });\n\n    vector<int> belong(N);\n    for(int id:ord){\n        int best=0;\n        for(int d=1;d<D;++d)\n            if(bag[d].sum < bag[best].sum) best=d;\n        bag[best].items.push_back(id);\n        bag[best].sum += w[id];\n        belong[id]=best;\n    }\n\n    /* --------------- local improvement -----------------\n       objective  f = \u03a3  sum_d^2   (mean is fixed)         */\n    auto obj = [&](){ double v=0; for(auto &b:bag) v+=b.sum*b.sum; return v; };\n    double bestScore = obj();\n    bool improved=true; int iter=0;\n    while(improved && ++iter<4000){             // safeguard iterations\n        improved=false;\n        /* --- single moves --- */\n        for(int i=0;i<N;++i){\n            int a = belong[i];\n            double wa = w[i], sa = bag[a].sum;\n            double base = bestScore - sa*sa;\n            for(int b=0;b<D;++b) if(b!=a){\n                double sb = bag[b].sum;\n                double newScore = base - sb*sb\n                                   + (sa-wa)*(sa-wa) + (sb+wa)*(sb+wa);\n                if(newScore + 1e-9 < bestScore){\n                    /* apply */\n                    bag[a].sum -= wa;\n                    bag[b].sum += wa;\n                    belong[i]=b; improved=true;\n                    bestScore=newScore;\n                    goto next_iter;\n                }\n            }\n        }\n        /* --- pair swaps --- */\n        for(int i=0;i<N;++i) for(int j=i+1;j<N;++j)\n            if(belong[i]!=belong[j]){\n                int a=belong[i], b=belong[j];\n                double wi=w[i], wj=w[j];\n                double sa=bag[a].sum, sb=bag[b].sum;\n\n                double base = bestScore - sa*sa - sb*sb;\n                double newSa = sa - wi + wj;\n                double newSb = sb - wj + wi;\n                double newScore = base + newSa*newSa + newSb*newSb;\n                if(newScore + 1e-9 < bestScore){\n                    swap(belong[i], belong[j]);\n                    bag[a].sum = newSa;\n                    bag[b].sum = newSb;\n                    improved=true; bestScore=newScore;\n                    goto next_iter;\n                }\n            }\n        next_iter:;\n    }\n\n    /* -------------------- output division -------------- */\n    for(int i=0;i<N;++i){\n        if(i) cout << ' ';\n        cout << belong[i];\n    }\n    cout << '\\n' << flush;\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n/* ------------------------------------------------------------------------- */\n/*  the instance is tiny, therefore we just keep the stacks in std::vector    */\n/* ------------------------------------------------------------------------- */\nstruct Solution {\n    int energy;\n    vector<pair<int,int>> ops;          // (v, stack)   stack == 0  \u21d2 carry-out\n};\n\n/* ------------------------------------------------------------------------- */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read input ----------------------------------------------------------- */\n    int n, m;\n    if (!(cin >> n >> m)) return 0;           // no input \u2013 should not happen\n    const int H = n / m;                      // = 20 in the official tests\n\n    vector<vector<int>> initial(m, vector<int>(H));\n    for (int i = 0; i < m; ++i)\n        for (int j = 0; j < H; ++j) cin >> initial[i][j];\n\n    /* random engine -------------------------------------------------------- */\n    std::mt19937 rng((std::random_device{})());\n    auto randInt = [&](int l, int r){ return std::uniform_int_distribution<int>(l,r)(rng); };\n\n    /* --------------------------------------------------------------------- */\n    auto simulate = [&](int PENALTY_TOP, int WEIGHT_SIZE, bool randomTies)->Solution {\n\n        vector<vector<int>> st = initial;        // current stacks\n        vector<pair<int,int>> ops;\n        int energy = 0;\n\n        /* -------------------------------------------------------------- */\n        for (int v = 1; v <= n; ++v) {\n\n            /* locate box v -------------------------------------------- */\n            int s = -1, idx = -1;\n            for (int i = 0; i < m && s == -1; ++i)\n                for (int j = 0, sz = (int)st[i].size(); j < sz; ++j)\n                    if (st[i][j] == v) { s = i; idx = j; break; }\n\n            /* on top \u2192 carry out directly ----------------------------- */\n            if (idx == (int)st[s].size() - 1) {\n                st[s].pop_back();\n                ops.emplace_back(v, 0);\n                continue;\n            }\n\n            /* segment above v ----------------------------------------- */\n            vector<int> seg(st[s].begin() + idx + 1, st[s].end());\n            const int segSz = (int)seg.size();\n            const int segCost = segSz + 1;         // energy to move the segment\n            const int segMax  = *max_element(seg.begin(), seg.end());\n            st[s].resize(idx + 1);                 // keep lower part incl. v\n\n            /* choose destination stack -------------------------------- */\n            int bestScore = INT_MAX, dest = -1;\n\n            for (int t = 0; t < m; ++t) if (t != s) {\n\n                /* blocking pairs between seg and stack t -------------- */\n                int bp = 0;\n                for (int y : seg)\n                    for (int x : st[t])\n                        if (y > x) ++bp;           // large y above small x\n\n                int score = bp * segCost;\n                if (!st[t].empty() && st[t].back() < segMax)\n                    score += segCost * PENALTY_TOP;\n\n                score += (int)st[t].size() * WEIGHT_SIZE;\n\n                if (randomTies) score += randInt(0,3);    // tiny diversification\n\n                if (score < bestScore) { bestScore = score; dest = t; }\n            }\n\n            /* perform the move --------------------------------------- */\n            st[dest].insert(st[dest].end(), seg.begin(), seg.end());\n            energy += segCost;\n            ops.emplace_back(seg.front(), dest + 1);       // stacks are 1-based\n\n            /* now v is on the top of its original stack --------------- */\n            st[s].pop_back();\n            ops.emplace_back(v, 0);\n        }\n        return {energy, std::move(ops)};\n    };\n\n    /* --------------------------------------------------------------------- */\n    auto start = std::chrono::steady_clock::now();\n\n    Solution best = simulate(16, 1, false);        // a solid deterministic run\n    int runs = 1;\n\n    /* explore variants until ~1.9 s --------------------------------------- */\n    while (true) {\n        auto now = std::chrono::steady_clock::now();\n        if (std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count() > 1850)\n            break;\n\n        int P  = randInt(12,20);                   // penalty for burying stack-top\n        int W  = randInt(0,2);                     // balancing weight\n        Solution cand = simulate(P, W, true);\n        if (cand.energy < best.energy) best = std::move(cand);\n        ++runs;\n    }\n    // cerr << \"runs = \" << runs << \"   best energy = \" << best.energy << '\\n';\n\n    /* output --------------------------------------------------------------- */\n    for (auto [v,i] : best.ops) cout << v << ' ' << i << '\\n';\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** constants and helpers ***************************************************/\nconst int DX[4] = {0, 1, 0, -1};\nconst int DY[4] = {1, 0, -1, 0};\nconst char DC[4] = {'R', 'D', 'L', 'U'};\n\nstruct Board {\n    int N;\n    vector<string> h;          // wall to down : size N-1, length N\n    vector<string> v;          // wall to right: size N  , length N-1\n    vector<int>     d;         // susceptibility flattened\n    inline bool inside(int x,int y) const { return 0<=x && x<N && 0<=y && y<N; }\n    inline bool canMove(int x,int y,int dir) const {\n        if(dir==0) return y+1<N && v[x][y]=='0';\n        if(dir==1) return x+1<N && h[x][y]=='0';\n        if(dir==2) return y-1>=0 && v[x][y-1]=='0';\n        return            x-1>=0 && h[x-1][y]=='0';\n    }\n} B;\n\n/*** data for optimisation ***************************************************/\nint N, LIM = 100000;\n\nvector<int> bounceDir;         // favourite neighbour of each cell\nvector<int> bounceTo;          // its index\nvector<int> loopsNeeded;       // how many extra loops finally allocated\n\nstring basePath;               // Euler tour without extra loops\nstring answer;                 // final route\n\n/*** building the Euler tour *************************************************/\nvector<vector<int>> visited;\nvoid dfsEuler(int x,int y)\n{\n    visited[x][y]=1;\n    for(int dir=0;dir<4;dir++){\n        int nx=x+DX[dir], ny=y+DY[dir];\n        if(!B.inside(nx,ny) || visited[nx][ny]) continue;\n        if(!B.canMove(x,y,dir)) continue;\n        basePath.push_back(DC[dir]);\n        dfsEuler(nx,ny);\n        basePath.push_back(DC[(dir+2)%4]);\n    }\n}\n\n/*** simulate any given path to count visits *********************************/\nvector<int> countVisits(const string& p)\n{\n    vector<int> v(N*N,0);\n    int x=0,y=0;\n    for(char c:p){\n        int dir = (c=='R'?0:c=='D'?1:c=='L'?2:3);\n        x += DX[dir]; y += DY[dir];\n        v[x*N+y]++;\n    }\n    return v;\n}\n\n/*** choose bounce neighbour (highest d) *************************************/\nvoid prepareBounce()\n{\n    bounceDir.assign(N*N,0);\n    bounceTo .assign(N*N,0);\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++){\n        int bestDir=-1, bestD=-1;\n        for(int dir=0;dir<4;dir++){\n            if(!B.canMove(x,y,dir)) continue;\n            int nx=x+DX[dir], ny=y+DY[dir];\n            int nd = B.d[nx*N+ny];\n            if(nd>bestD){ bestD=nd; bestDir=dir; }\n        }\n        bounceDir[x*N+y]=bestDir;\n        bounceTo [x*N+y]=(x+DX[bestDir])*N + (y+DY[bestDir]);\n    }\n}\n\n/*** greedy allocation of useful loops ***************************************/\nvoid allocateLoops(vector<int>& visit)\n{\n    loopsNeeded.assign(N*N,0);\n    long long L = (long long)basePath.size();             // current length\n    double R = 0;                                         // \u03a3 d / v\n    for(int i=0;i<N*N;i++) R += (double)B.d[i] / visit[i];\n\n    using Node = pair<double,int>;                        // (benefit, id)\n    priority_queue<Node> pq;\n    for(int i=0;i<N*N;i++){\n        int j=bounceTo[i];\n        double benefit = (double)B.d[i]/(visit[i]*(visit[i]+1))\n                       + (double)B.d[j]/(visit[j]*(visit[j]+1));\n        pq.emplace(benefit,i);\n    }\n\n    while(L+2 <= LIM){\n        double threshold = 2.0 * R / (L+2);               // need benefit > thresh\n        auto [benefit,id] = pq.top(); pq.pop();\n        int i=id, j=bounceTo[i];\n        // recompute real current benefit\n        benefit = (double)B.d[i]/(visit[i]*(visit[i]+1))\n                + (double)B.d[j]/(visit[j]*(visit[j]+1));\n        if(benefit < threshold - 1e-12){                  // no further improvement\n            break;\n        }\n        /* perform the loop */\n        loopsNeeded[i]++;  L += 2;\n        R -= (double)B.d[i]/visit[i] - (double)B.d[i]/(visit[i]+1);\n        R -= (double)B.d[j]/visit[j] - (double)B.d[j]/(visit[j]+1);\n        visit[i]++;  visit[j]++;\n\n        /* push updated entries (lazy) */\n        double newBenefitI = (double)B.d[i]/(visit[i]*(visit[i]+1))\n                           + (double)B.d[j]/(visit[j]*(visit[j]+1));\n        pq.emplace(newBenefitI,i);\n        double newBenefitJ = (double)B.d[j]/(visit[j]*(visit[j]+1))\n                           + (double)B.d[bounceTo[j]]/(visit[bounceTo[j]]*(visit[bounceTo[j]]+1));\n        pq.emplace(newBenefitJ,j);\n    }\n}\n\n/*** produce the final route **************************************************/\nvector<int> loopsRemain;\nstring outPath;\nint curX=0,curY=0;\n\nvoid emitMove(int dir)\n{\n    outPath.push_back(DC[dir]);\n    curX += DX[dir]; curY += DY[dir];\n}\n\nvoid emitBounce(int id)            // perform ONE back-and-forth loop\n{\n    int dir = bounceDir[id];\n    emitMove(dir);\n    emitMove((dir+2)%4);\n}\n\nvoid maybeBounce(int id)           // at most one loop here\n{\n    if(loopsRemain[id]>0){\n        loopsRemain[id]--;\n        emitBounce(id);\n    }\n}\n\nvector<vector<int>> vis2;\nvoid dfsFinal(int x,int y)\n{\n    int id = x*N+y;\n    vis2[x][y]=1;\n    maybeBounce(id);\n    for(int dir=0;dir<4;dir++){\n        int nx=x+DX[dir], ny=y+DY[dir];\n        if(!B.inside(nx,ny) || vis2[nx][ny]) continue;\n        if(!B.canMove(x,y,dir)) continue;\n        emitMove(dir);\n        dfsFinal(nx,ny);\n        emitMove((dir+2)%4);\n        maybeBounce(id);\n    }\n    while(loopsRemain[id]>0) {     // finish leftovers, very small number\n        loopsRemain[id]--;\n        emitBounce(id);\n    }\n}\n\n/*** main ********************************************************************/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* input */\n    cin>>N;  B.N=N;\n    B.h.resize(N-1); for(int i=0;i<N-1;i++) cin>>B.h[i];\n    B.v.resize(N);   for(int i=0;i<N;i++)   cin>>B.v[i];\n    B.d.resize(N*N);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) cin>>B.d[i*N+j];\n\n    /* step 1: base Euler tour */\n    visited.assign(N,vector<int>(N,0));\n    dfsEuler(0,0);\n\n    /* step 2: initial visits & bounce neighbour */\n    vector<int> visit = countVisits(basePath);        // size N*N\n    prepareBounce();\n\n    /* step 3: greedy extra loops only while useful */\n    allocateLoops(visit);\n\n    /* step 4: build the final route */\n    loopsRemain = loopsNeeded;\n    vis2.assign(N,vector<int>(N,0));\n    dfsFinal(0,0);\n\n    /* output */\n    cout << outPath << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*--------------------------------------------------------------------*/\nstruct Pos { int r, c; };\ninline int md(const Pos& a, const Pos& b) {\n    return abs(a.r - b.r) + abs(a.c - b.c);\n}\n\n/*--------------------------------------------------------------------*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ------------------  input ------------------------------------- */\n    int N, M;                           // N = 15  ,  M = 200\n    if (!(cin >> N >> M)) return 0;\n    int si, sj;  cin >> si >> sj;\n\n    vector<string> grid(N);\n    for (int i = 0; i < N; ++i) cin >> grid[i];\n\n    vector<string> w(M);                // lucky words, |w| = 5\n    for (int i = 0; i < M; ++i) cin >> w[i];\n\n    /* ------------------  letter positions -------------------------- */\n    array<vector<Pos>, 26> pos;\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c)\n            pos[grid[r][c] - 'A'].push_back({r, c});\n\n    /* ------------------  distance between letters ------------------ */\n    constexpr int INF = 1e9;\n    int charD[26][26];\n    for (int a = 0; a < 26; ++a)\n        for (int b = 0; b < 26; ++b) {\n            int best = INF;\n            for (const auto &pa : pos[a])\n                for (const auto &pb : pos[b])\n                    best = min(best, md(pa, pb));\n            charD[a][b] = best;\n        }\n\n    int distStart[26];\n    for (int a = 0; a < 26; ++a) {\n        int best = INF;\n        for (const auto &p : pos[a])\n            best = min(best, abs(p.r - si) + abs(p.c - sj));\n        distStart[a] = best;\n    }\n\n    /* ------------------  helper arrays for words ------------------- */\n    array<int, 200> first{}, last{};\n    for (int i = 0; i < M; ++i) {\n        first[i] = w[i][0] - 'A';\n        last [i] = w[i][4] - 'A';\n    }\n\n    /* -----------  maximal overlap & edge cost (travel+letters) ------ */\n    static uint8_t ov[200][200];        // longest overlap length\n    static int     edge[200][200];      // heuristic edge cost\n\n    for (int i = 0; i < M; ++i)\n        for (int j = 0; j < M; ++j) {\n            int best = 0;\n            for (int l = 4; l >= 1; --l)              // test 4 \u2026 1\n                if (equal(w[i].end()-l, w[i].end(), w[j].begin())) {\n                    best = l; break;\n                }\n            ov[i][j] = best;\n            int nxtLetter = w[j][best] - 'A';\n            edge[i][j] = charD[last[i]][nxtLetter] + (5 - best);\n        }\n\n    int startC[200];                                   // start edge\n    for (int i = 0; i < M; ++i) startC[i] = distStart[first[i]] + 5;\n\n    /* ------------------  greedy initial tour ----------------------- */\n    vector<int> ord;  ord.reserve(M);\n    vector<char> used(M, 0);\n\n    int cur = -1;                                      // -1  \u21d2  \u201cstart\u201d\n    while ((int)ord.size() < M) {\n        int best = -1, bestCost = INF;\n        for (int i = 0; i < M; ++i) if (!used[i]) {\n            int c = (cur == -1 ? startC[i] : edge[cur][i]);\n            if (c < bestCost) { bestCost = c; best = i; }\n        }\n        ord.push_back(best);\n        used[best] = 1;\n        cur = best;\n    }\n\n    /* ------------------  helper to evaluate a tour ----------------- */\n    auto tourCost = [&](const vector<int>& v) {\n        int cost = startC[v[0]];\n        for (int i = 1; i < M; ++i) cost += edge[v[i-1]][v[i]];\n        return cost;\n    };\n\n    int bestCost = tourCost(ord);\n    vector<int> bestOrd = ord;\n\n    /* ------------------  Simulated Annealing  ---------------------- */\n    std::mt19937 rng((uint32_t)\n        chrono::steady_clock::now().time_since_epoch().count());\n\n    const double T0 = 3000.0, Tend = 1e-2;\n    const double TIME_LIMIT = 1.85;                          // seconds\n    auto t_start = chrono::steady_clock::now();\n\n    vector<int> cand(M);\n\n    auto elapsed = [&]() {\n        return chrono::duration<double>(\n            chrono::steady_clock::now() - t_start).count();\n    };\n\n    while (elapsed() < TIME_LIMIT) {\n\n        /* ----- create neighbour (swap / reverse / insert) ---------- */\n        cand = ord;\n        int a = rng() % M, b = rng() % M;\n        if (a == b) continue;\n        if (rng() & 1) {                     // swap two nodes\n            swap(cand[a], cand[b]);\n        } else if (rng() & 1) {              // reverse segment\n            if (a > b) swap(a, b);\n            reverse(cand.begin() + a, cand.begin() + b + 1);\n        } else {                             // insertion\n            int from = a, to = b;\n            int node = cand[from];\n            cand.erase(cand.begin() + from);\n            if (to > from) --to;\n            cand.insert(cand.begin() + to, node);\n        }\n\n        int newCost = tourCost(cand);\n\n        /* ----- SA acceptance --------------------------------------- */\n        double t = elapsed() / TIME_LIMIT;\n        double temp = pow(Tend / T0, t) * T0;          // geometric\n        if (newCost < bestCost ||\n            exp((bestCost - newCost) / temp) > (rng() / 4294967296.0)) {\n            ord.swap(cand);\n            if (newCost < bestCost) {\n                bestCost = newCost;\n                bestOrd  = ord;\n            }\n        }\n    }\n    ord.swap(bestOrd);                                 // best tour found\n\n    /* ------------------  build the final string -------------------- */\n    string S = w[ord[0]];\n    for (int i = 1; i < M; ++i) {\n        int pre = ord[i-1], curW = ord[i];\n        int l = ov[pre][curW];\n        S += w[curW].substr(l);\n    }\n    int L = (int)S.size();\n\n    /* ------------------  exact DP for the path --------------------- */\n    constexpr int BIG = 1e9;\n    vector<vector<int>>        dp(L);\n    vector<vector<uint16_t>>  prv(L);\n    vector<int>              bestIdx(L);\n\n    /* layer 0 */\n    {\n        int ch = S[0] - 'A';\n        int sz = pos[ch].size();\n        dp[0].assign(sz, BIG);\n        prv[0].assign(sz, 0);\n        for (int k = 0; k < sz; ++k)\n            dp[0][k] = md({si, sj}, pos[ch][k]) + 1;\n        bestIdx[0] = min_element(dp[0].begin(), dp[0].end()) - dp[0].begin();\n    }\n\n    for (int i = 1; i < L; ++i) {\n        int a = S[i-1] - 'A', b = S[i] - 'A';\n        int szA = pos[a].size(), szB = pos[b].size();\n\n        dp[i].assign(szB, BIG);\n        prv[i].assign(szB, 0);\n\n        for (int k = 0; k < szB; ++k) {\n            const Pos &to = pos[b][k];\n            int best = BIG, bestj = 0;\n            for (int j = 0; j < szA; ++j) {\n                int cand = dp[i-1][j] + md(pos[a][j], to) + 1;\n                if (cand < best) { best = cand; bestj = j; }\n            }\n            dp[i][k]  = best;\n            prv[i][k] = bestj;\n        }\n        bestIdx[i] = min_element(dp[i].begin(), dp[i].end()) - dp[i].begin();\n    }\n\n    /* ------------------  back-track -------------------------------- */\n    vector<Pos> path(L);\n    int idx = bestIdx.back();\n    for (int i = L - 1; i >= 0; --i) {\n        int ch = S[i] - 'A';\n        path[i] = pos[ch][idx];\n        if (i) idx = prv[i][idx];\n    }\n\n    /* ------------------  output ------------------------------------ */\n    for (auto &p : path) cout << p.r << ' ' << p.c << '\\n';\n    return 0;\n}","ahc030":"//  AHC030 \u2013 unique solution via placement elimination + DFS\n//  compile: g++ -std=c++20 -O2 -pipe -static -s main.cpp\n//------------------------------------------------------------------\n#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastIO{ FastIO(){ ios::sync_with_stdio(false); cin.tie(nullptr); }} fio;\n\n//------------------------------------------------------------------\nstruct Placement{ vector<int> cells; };\n\nstruct Field{ vector<Placement> plc; };\n\nint N, M, NN, maxQueries;\ndouble EPS;\n\nvector<Field> fields;\nint queryCnt = 0;\nvector<int> drilled;                 // -1 unknown, >=0 exact v(i,j)\nvector<char> isOil;                  // squares already proven to contain oil\n//------------------------------------------------------------------\ninline void flush(){ cout << '\\n' << flush; }\ninline pair<int,int> id2ij(int id){ return {id / N, id % N}; }\n\nint drill(int id)\n{\n    auto [i,j] = id2ij(id);\n    cout << \"q 1 \" << i << ' ' << j; flush();\n    int v; cin >> v;\n    ++queryCnt;\n    drilled[id] = v;\n    if (v) isOil[id] = 1;\n    return v;\n}\n//------------------------------------------------------------------\nvoid eliminateZero(int id0)\n{\n    for (auto &f : fields) if (f.plc.size() > 1)\n    {\n        vector<Placement> nxt;\n        nxt.reserve(f.plc.size());\n        for (auto &pl : f.plc)\n        {\n            bool hit = false;\n            for (int id : pl.cells) if (id == id0){ hit=true; break; }\n            if (!hit) nxt.push_back(std::move(pl));\n        }\n        if (!nxt.empty()) f.plc.swap(nxt);\n    }\n}\n//------------------------------------------------------------------\n// statistics used for zero-elimination drill suggestion\nstruct Stat{\n    vector<int> cnt;\n    vector<double> logNoOil;\n    explicit Stat(int n): cnt(n), logNoOil(n,0.0){}\n};\nStat makeStat()\n{\n    Stat st(NN);\n    for (const auto &f: fields) if (f.plc.size() > 1)\n    {\n        int S = (int)f.plc.size();\n        double invS = 1.0 / S;\n        vector<int> local(NN,0);\n        for (const auto &pl: f.plc)\n            for (int id: pl.cells) ++local[id];\n\n        for (int id=0; id<NN; ++id) if (local[id])\n        {\n            st.cnt[id] += local[id];\n            double p = local[id]*invS;\n            if (p < 1.0) st.logNoOil[id] += log(1.0 - p);\n            else         st.logNoOil[id] = -1e100;\n        }\n    }\n    return st;\n}\n//------------------------------------------------------------------\n// DFS that enumerates feasible global solutions (stops after 2)\nstruct DFSSolver{\n    const vector<Field> &F;\n    vector<int> posIds, posVal;                 // positive drilled squares\n    vector<vector<char>> someCover;             // field\u2192posIdx   (bool)\n    vector<vector<int>>  plcMask;               // flattened placement\u2192list posIdx\n    vector<int> curCnt, remMax, assign;\n    int solutions=0;\n    vector<int> solA, solB;\n\n    DFSSolver(const vector<Field> &fld, const vector<int> &drilled)\n        : F(fld)\n    {\n        for(int id=0; id<(int)drilled.size(); ++id)\n            if (drilled[id] > 0){ posIds.push_back(id); posVal.push_back(drilled[id]); }\n\n        int P = (int)posIds.size();\n        someCover.assign(M, vector<char>(P,0));\n        plcMask.clear(); plcMask.reserve(8192);\n\n        for (int f=0; f<M; ++f)\n            for (const auto &pl: F[f].plc)\n            {\n                vector<int> mask;\n                for (int id: pl.cells)\n                {\n                    auto it = find(posIds.begin(), posIds.end(), id);\n                    if (it != posIds.end()){\n                        int idx = (int)(it - posIds.begin());\n                        mask.push_back(idx);\n                        someCover[f][idx] = 1;\n                    }\n                }\n                plcMask.push_back(std::move(mask));\n            }\n\n        curCnt.assign(P,0);\n        remMax.assign(P,0);\n        for(int p=0;p<P;++p)\n            for(int f=0;f<M;++f)\n                if (someCover[f][p]) ++remMax[p];\n\n        assign.assign(M,-1);\n    }\n    //--------------------------------------------------------------\n    void dfs(int depth,\n             const vector<int> &order,\n             const vector<int> &offset)\n    {\n        if (solutions>=2) return;\n        if (depth==(int)order.size())\n        {\n            for (int p=0;p<(int)posIds.size();++p)\n                if (curCnt[p]!=posVal[p]) return;\n            if (solutions==0) solA=assign; else solB=assign;\n            ++solutions; return;\n        }\n        int f = order[depth], base = offset[f], K = (int)F[f].plc.size();\n\n        // remove f's potential from remMax\n        for (int p=0;p<(int)posIds.size();++p) if (someCover[f][p]) --remMax[p];\n\n        for (int k=0;k<K && solutions<2;++k)\n        {\n            const auto& mask = plcMask[base+k];\n            bool ok=true;\n            for(int idx:mask)\n                if(curCnt[idx]+1>posVal[idx]){ ok=false; break; }\n            if (!ok) continue;\n\n            for(int idx:mask) ++curCnt[idx];\n            assign[f]=k;\n\n            for(int p=0;p<(int)posIds.size();++p)\n                if(curCnt[p]+remMax[p]<posVal[p]){ ok=false; break; }\n\n            if(ok) dfs(depth+1,order,offset);\n\n            assign[f]=-1;\n            for(int idx:mask) --curCnt[idx];\n        }\n        for (int p=0;p<(int)posIds.size();++p) if (someCover[f][p]) ++remMax[p];\n    }\n    //--------------------------------------------------------------\n    int solve()\n    {\n        if (posIds.empty())\n        {\n            bool uniq=true;\n            for(const auto &f:F) if(f.plc.size()!=1){ uniq=false; break; }\n            if (uniq){ solA.assign(M,0); solutions=1; return 1; }\n            return 2;\n        }\n        vector<int> ord(M); iota(ord.begin(),ord.end(),0);\n        sort(ord.begin(),ord.end(),\n             [&](int a,int b){ return F[a].plc.size()<F[b].plc.size(); });\n        vector<int> off(M);\n        int cur=0;\n        for(int f=0;f<M;++f){ off[f]=cur; cur+=(int)F[f].plc.size(); }\n        dfs(0,ord,off);\n        return min(solutions,2);\n    }\n};\n//------------------------------------------------------------------\nint pickDiscriminatingCell(const vector<int>& sA,\n                           const vector<int>& sB)\n{\n    vector<int> cntA(NN,0), cntB(NN,0);\n    for(int f=0;f<M;++f){\n        for(int id: fields[f].plc[sA[f]].cells) ++cntA[id];\n        for(int id: fields[f].plc[sB[f]].cells) ++cntB[id];\n    }\n    int best=-1, diffMax=0;\n    for(int id=0;id<NN;++id) if(drilled[id]==-1 && cntA[id]!=cntB[id]){\n        int diff=abs(cntA[id]-cntB[id]);\n        if(diff>diffMax){ diffMax=diff; best=id; }\n    }\n    if(best!=-1) return best;\n\n    // counts identical but coverage sets might differ (union)\n    for(int id=0;id<NN;++id)\n        if(drilled[id]==-1 && (cntA[id]>0)!=(cntB[id]>0))\n            return id;\n    return -1;                       // indistinguishable by single square\n}\n//------------------------------------------------------------------\nvoid readInput()\n{\n    cin >> N >> M >> EPS;\n    NN = N*N; maxQueries = 2*NN;\n    fields.resize(M);\n    drilled.assign(NN,-1);\n    isOil.assign(NN,0);\n\n    for(int k=0;k<M;++k)\n    {\n        int d; cin >> d;\n        vector<pair<int,int>> c(d);\n        int hi=0, wi=0;\n        for(int t=0;t<d;++t){\n            cin >> c[t].first >> c[t].second;\n            hi=max(hi,c[t].first); wi=max(wi,c[t].second);\n        }\n        ++hi; ++wi;\n        for(int si=0; si+hi<=N; ++si)\n            for(int sj=0; sj+wi<=N; ++sj)\n            {\n                Placement p; p.cells.reserve(d);\n                for(auto [ci,cj]:c) p.cells.push_back((ci+si)*N + cj+sj);\n                fields[k].plc.push_back(std::move(p));\n            }\n    }\n}\n//------------------------------------------------------------------\nint main()\n{\n    readInput();\n    const int ELIM_LIMIT = min(maxQueries-20, NN);  // 20 margin for later\n\n    // phase A: cheap elimination on v=0\n    while(queryCnt<ELIM_LIMIT)\n    {\n        auto st = makeStat();\n        int best=-1; double score=-1;\n        for(int id=0; id<NN; ++id) if(drilled[id]==-1 && st.cnt[id])\n        {\n            double pNo = exp(st.logNoOil[id]);\n            double sc = st.cnt[id]*pNo;\n            if(sc>score){ score=sc; best=id; }\n        }\n        if(best==-1) break;\n        int v=drill(best);\n        if(v==0) eliminateZero(best);\n    }\n\n    // phase B: iterate with DFS until unique solution obtained\n    while(true)\n    {\n        DFSSolver dfs(fields, drilled);\n        int res = dfs.solve();\n        if(res==0){\n            cerr<<\"Internal inconsistency!\\n\"; return 0;\n        }\n        if(res==1){        // unique \u2013 output and finish\n            vector<char> finalOil(NN,0);\n            for(int f=0;f<M;++f)\n                for(int id: fields[f].plc[dfs.solA[f]].cells)\n                    finalOil[id]=1;\n            for(int id=0;id<NN;++id) if(isOil[id]) finalOil[id]=1;\n\n            vector<int> ans;\n            for(int id=0;id<NN;++id) if(finalOil[id]) ans.push_back(id);\n\n            cout<<\"a \"<<ans.size();\n            for(int id:ans){\n                auto [i,j]=id2ij(id);\n                cout<<' '<<i<<' '<<j;\n            }\n            flush();\n            int judge; cin>>judge;\n            return 0;\n        }\n        // res == 2 : at least two solutions -> try to separate\n        int diff = pickDiscriminatingCell(dfs.solA, dfs.solB);\n        if(diff==-1){\n            // solutions identical w.r.t. every square's count \u21d2 answer safe\n            vector<char> finalOil(NN,0);\n            for(int id: isOil){}           // dummy to silence warnings\n            for(int f=0;f<M;++f)\n                for(int id: fields[f].plc[dfs.solA[f]].cells)\n                    finalOil[id]=1;\n            for(int id=0;id<NN;++id) if(isOil[id]) finalOil[id]=1;\n\n            vector<int> ans;\n            for(int id=0;id<NN;++id) if(finalOil[id]) ans.push_back(id);\n            cout<<\"a \"<<ans.size();\n            for(int id:ans){\n                auto [i,j]=id2ij(id);\n                cout<<' '<<i<<' '<<j;\n            }\n            flush();\n            int judge; cin>>judge;\n            return 0;\n        }\n        int v=drill(diff);\n        if(v==0) eliminateZero(diff);\n        if(queryCnt>=maxQueries) break;   // safety\n    }\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconstexpr int W = 1000;                     // hall size 1000 \u00d7 1000\n\nstruct Rect { int i0, j0, i1, j1; };        // [top,left) \u2013 [bottom,right)\n\n/* ------------------------------------------------------------------ */\n/* Fast   shelf (row) packing \u2013 1st try                                */\n/* ------------------------------------------------------------------ */\nbool pack_rowwise(const vector<ll>& a, vector<Rect>& out) {\n    const int N = (int)a.size();\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int x, int y){ return a[x] > a[y]; });\n\n    out.assign(N, {0,0,0,0});\n    int y = 0;                              // top of the current row\n    vector<int> remain = ord, nxt;\n\n    while (!remain.empty()) {\n        int idx0 = remain.front();\n        int h    = (int)((a[idx0] + W - 1) / W);       // minimal legal height\n        if (y + h > W) return false;                   // overflow \u2192 fallback\n\n        int x = 0;\n        nxt.clear();\n        for (int id : remain) {\n            int w = (int)((a[id] + h - 1) / h);        // ceil(a / h)  \u2264 1000\n            if (x + w <= W) {\n                out[id] = { y, x, y + h, x + w };\n                x += w;\n            } else {\n                nxt.push_back(id);                     // move to next row\n            }\n        }\n        y += h;\n        remain.swap(nxt);\n    }\n    return true;\n}\n\n/* ------------------------------------------------------------------ */\n/* Skyline fallback \u2013 guaranteed and fast                             */\n/* ------------------------------------------------------------------ */\nbool skyline_place(int h, int w,\n                   const vector<int>& sky, int &px, int &py) {\n    deque<int> dq;\n    // build first window\n    for (int i = 0; i < w; ++i) {\n        while (!dq.empty() && sky[dq.back()] <= sky[i]) dq.pop_back();\n        dq.push_back(i);\n    }\n    int curMax = sky[dq.front()];\n    if (curMax + h <= W) { px = 0; py = curMax; return true; }\n\n    for (int x = 1; x + w <= W; ++x) {\n        if (dq.front() == x - 1) dq.pop_front();\n        int idx = x + w - 1;\n        while (!dq.empty() && sky[dq.back()] <= sky[idx]) dq.pop_back();\n        dq.push_back(idx);\n        curMax = sky[dq.front()];\n        if (curMax + h <= W) { px = x; py = curMax; return true; }\n    }\n    return false;\n}\n\nbool pack_skyline(const vector<ll>& a, vector<Rect>& out) {\n    const int N = (int)a.size();\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int x, int y){ return a[x] > a[y]; });\n\n    vector<int> sky(W, 0);                  // current column heights\n    out.assign(N, {0,0,0,0});\n\n    for (int id : ord) {\n        ll area = a[id];\n        int hMin = (int)((area + W - 1) / W);          // ceil(area/1000)\n        bool placed = false;\n\n        for (int h = hMin; h <= W && !placed; ++h) {\n            int w = (int)((area + h - 1) / h);         // ceil(area / h)\n            if (w > W) continue;\n            int x, y;\n            if (skyline_place(h, w, sky, x, y)) {\n                out[id] = { y, x, y + h, x + w };\n                for (int i = x; i < x + w; ++i) sky[i] = y + h;\n                placed = true;\n            }\n        }\n        if (!placed) return false;                     // should never happen\n    }\n    return true;\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyW, D, N;\n    if (!(cin >> dummyW >> D >> N)) return 0;\n\n    vector<vector<ll>> A(D, vector<ll>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> A[d][k];\n\n    vector<Rect> dayRects;\n    for (int d = 0; d < D; ++d) {\n        bool ok = pack_rowwise(A[d], dayRects);\n        if (!ok) ok = pack_skyline(A[d], dayRects);    // fast guaranteed fallback\n        if (!ok) {                                     // ultimate safety \u2013 1\u00d71 cells\n            dayRects.resize(N);\n            for (int k = 0; k < N; ++k)\n                dayRects[k] = { k, 0, k + 1, 1 };\n        }\n        for (int k = 0; k < N; ++k) {\n            auto &r = dayRects[k];\n            cout << r.i0 << ' ' << r.j0 << ' '\n                 << r.i1 << ' ' << r.j1 << '\\n';\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\nconstexpr int MOD = 998244353;\nconstexpr int N = 9;\nconstexpr int M = 20;\nconstexpr int K = 81;\n\n/* ------------------------------- RNG ------------------------------------ */\nstruct RNG {\n    uint64_t s;\n    RNG() : s(chrono::steady_clock::now().time_since_epoch().count()) {}\n    uint32_t next() {\n        s ^= s << 13;\n        s ^= s >> 7;\n        s ^= s << 17;\n        return static_cast<uint32_t>(s);\n    }\n    uint32_t next(uint32_t lim) { return next() % lim; }\n    double   uniform()          { return double(next()) / 4294967295.0; }\n} rng;\n\n/* ----------------------------- operation -------------------------------- */\nstruct Op {\n    int m, p, q;     // for the answer\n    int idx[9];      // linear indices of the 9 covered cells\n    int add[9];\n};\n\ninline int64 gain_add(const Op& o, const array<int,81>& b){\n    int64 g = 0;\n    for (int k=0;k<9;++k){\n        int v  = b[o.idx[k]];\n        int nv = v + o.add[k];\n        if (nv >= MOD) nv -= MOD;\n        g += nv - v;\n    }\n    return g;\n}\ninline int64 gain_sub(const Op& o, const array<int,81>& b){\n    int64 g = 0;\n    for (int k=0;k<9;++k){\n        int v  = b[o.idx[k]];\n        int nv = v - o.add[k];\n        if (nv < 0) nv += MOD;\n        g += nv - v;\n    }\n    return g;\n}\ninline void apply_add(const Op& o, array<int,81>& b){\n    for (int k=0;k<9;++k){\n        int& v = b[o.idx[k]];\n        v += o.add[k];\n        if (v >= MOD) v -= MOD;\n    }\n}\ninline void apply_sub(const Op& o, array<int,81>& b){\n    for (int k=0;k<9;++k){\n        int& v = b[o.idx[k]];\n        v -= o.add[k];\n        if (v < 0) v += MOD;\n    }\n}\ninline bool is_safe(const Op& o,const array<int,81>& b){\n    for(int k=0;k<9;++k) if(b[o.idx[k]]+o.add[k]>=MOD) return false;\n    return true;\n}\n\n/* --------------------------- SA parameters ------------------------------ */\nconst double T0 = 1.0e9;\nconst double T1 = 1.0e5;\nconst int    SAMPLE = 4;      // how many random ops are compared when we need one\n\n/* ------------------------------- SA run --------------------------------- */\nstruct State{\n    array<int,81> board;\n    vector<int>   press;   // indices into ops[]\n    int64         score;\n};\n\nvoid simulated_annealing(State &st,\n                         const vector<Op>& ops,\n                         double time_limit){          // seconds\n    const auto time0 = chrono::steady_clock::now();\n    auto sec = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now()-time0).count();\n    };\n    int OPS = (int)ops.size();\n\n    array<int,81> b = st.board;\n    vector<int>   lst = st.press;\n    int64         cur = st.score;\n    int64         best = cur;\n    array<int,81> bestB = b;\n    vector<int>   bestL = lst;\n\n    long long iter = 0;\n    while(sec() < time_limit){\n        ++iter;\n        double t = sec()/time_limit;\n        double Temp = T0 * pow(T1/T0, t);\n\n        int moveType = rng.next(3);              // 0 add, 1 remove, 2 replace\n        if(moveType==0 && (int)lst.size()>=K) moveType=2;\n        if(moveType==1 && lst.empty())          moveType=0;\n        if(moveType==2 && lst.empty())          moveType=0;\n\n        if(moveType==0){          // ADD\n            int bestOp=-1;\n            int64 bestGain = LLONG_MIN;\n            for(int s=0;s<SAMPLE;++s){\n                int oi = rng.next(OPS);\n                int64 g = gain_add(ops[oi],b);\n                if(g>bestGain){bestGain=g;bestOp=oi;}\n            }\n            int64 delta = bestGain;\n            if(delta>=0 || rng.uniform()<exp(delta/Temp)){\n                apply_add(ops[bestOp],b);\n                lst.push_back(bestOp);\n                cur += delta;\n            }\n        }\n        else if(moveType==1){     // REMOVE\n            int id = rng.next((uint32_t)lst.size());\n            int oi = lst[id];\n            int64 delta = gain_sub(ops[oi],b);   // could be positive\n            if(delta>=0 || rng.uniform()<exp(delta/Temp)){\n                apply_sub(ops[oi],b);\n                cur += delta;\n                lst[id] = lst.back(); lst.pop_back();\n            }\n        }\n        else{                     // REPLACE\n            int id = rng.next((uint32_t)lst.size());\n            int oldOp = lst[id];\n\n            int bestOp=-1;\n            int64 bestDelta = LLONG_MIN;\n\n            // sample several candidates, take the best\n            for(int s=0;s<SAMPLE;++s){\n                int cand = rng.next(OPS);\n                if(cand==oldOp) continue;\n                int64 delta = gain_sub(ops[oldOp],b);\n                apply_sub(ops[oldOp],b);\n                delta += gain_add(ops[cand],b);\n                apply_add(ops[oldOp],b);     // rollback\n                if(delta>bestDelta){bestDelta=delta;bestOp=cand;}\n            }\n            if(bestOp<0) continue;\n\n            int64 delta = gain_sub(ops[oldOp],b);\n            apply_sub(ops[oldOp],b);\n            delta += gain_add(ops[bestOp],b);\n            if(delta>=0 || rng.uniform()<exp(delta/Temp)){\n                apply_add(ops[bestOp],b);\n                lst[id] = bestOp;\n                cur += delta;\n            }else{\n                apply_add(ops[oldOp],b);     // rollback\n            }\n        }\n\n        if(cur > best){\n            best = cur;\n            bestB = b;\n            bestL = lst;\n        }\n    }\n    st.board = bestB;\n    st.press = bestL;\n    st.score = best;\n}\n\n/* --------------------------- baseline greedy ---------------------------- */\nState baseline(const vector<Op>& ops){\n    State st;\n    st.board.fill(0);\n    st.score = 0;\n    st.press.clear();\n    /* read original A into board */\n    for(int i=0;i<81;++i){\n        int v; cin>>v; st.board[i]=v;\n        st.score += v;\n    }\n\n    // safe greedy\n    while((int)st.press.size()<K){\n        int best=-1; int64 bestGain=0;\n        for(int i=0;i<(int)ops.size();++i){\n            if(!is_safe(ops[i],st.board)) continue;\n            int64 g = gain_add(ops[i],st.board);\n            if(g>bestGain){bestGain=g;best=i;}\n        }\n        if(best<0||bestGain<=0) break;\n        apply_add(ops[best],st.board);\n        st.press.push_back(best);\n        st.score += bestGain;\n    }\n    // ordinary greedy\n    while((int)st.press.size()<K){\n        int best=-1; int64 bestGain=0;\n        for(int i=0;i<(int)ops.size();++i){\n            int64 g = gain_add(ops[i],st.board);\n            if(g>bestGain){bestGain=g;best=i;}\n        }\n        if(best<0||bestGain<=0) break;\n        apply_add(ops[best],st.board);\n        st.press.push_back(best);\n        st.score += bestGain;\n    }\n    return st;\n}\n\n/* ------------------------------- main ----------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyN,dummyM,dummyK;\n    cin>>dummyN>>dummyM>>dummyK;         // all fixed\n\n    /* read A later inside baseline() because we need it twice */\n    vector<int> firstRow(81);\n    for(int i=0;i<81;++i) cin>>firstRow[i];\n\n    /* read stamps */\n    array<array<int,9>,M> stamp{};\n    for(int m=0;m<M;++m)\n        for(int r=0;r<3;++r)\n            for(int c=0;c<3;++c){\n                int x; cin>>x; stamp[m][r*3+c]=x;\n            }\n\n    /* create all 980 presses */\n    vector<Op> ops; ops.reserve(M*49);\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                Op o; o.m=m; o.p=p; o.q=q;\n                int t=0;\n                for(int dr=0;dr<3;++dr)\n                    for(int dc=0;dc<3;++dc){\n                        o.idx[t]=(p+dr)*N+q+dc;\n                        o.add[t]=stamp[m][t];\n                        ++t;\n                    }\n                ops.push_back(o);\n            }\n\n    const auto global_start = chrono::steady_clock::now();\n    auto elapsed = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now()-global_start).count();\n    };\n\n    /* we need two copies of A because baseline() consumes the stream once   */\n    stringstream ss;\n    for(int v:firstRow) ss<<v<<' ';\n    string remainA = ss.str();\n    cin.seekg(0);                        // rewind\n    cin.clear();\n    cin.ignore(numeric_limits<streamsize>::max(),'\\n'); // skip first line\n    /* baseline run 1 */\n    {\n        for(int v:firstRow) cin>>v;      // dummy read to align the stream\n        cin.ignore(numeric_limits<streamsize>::max(),'\\n'); // stamps already read\n    }\n    /* rebuild input for baseline() */\n    string inputA = remainA;\n    stringstream inA(inputA);\n    /* replace cin buffer with inA for baseline() */\n    cin.rdbuf(inA.rdbuf());\n\n    State bestState = baseline(ops);     // baseline\n    double time_used = elapsed();\n    const double TOTAL = 1.95;           // keep tiny margin\n    const double single_time = 0.35;     // each SA slice\n\n    while(time_used + single_time < TOTAL){\n        State st = bestState;            // start from baseline\n        simulated_annealing(st, ops, single_time);\n        if(st.score > bestState.score) bestState = move(st);\n        time_used = elapsed();\n    }\n\n    /* output -------------------------------------------------------------- */\n    cout<<bestState.press.size()<<\"\\n\";\n    for(int id:bestState.press){\n        const Op& o = ops[id];\n        cout<<o.m<<\" \"<<o.p<<\" \"<<o.q<<\"\\n\";\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Crane {\n    int r, c;          // position\n    bool alive = true;\n    bool holding = false;\n    int box = -1;      // id of the held container\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;                         // N is always 5 in this contest\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> recv(N, vector<int>(N));\n    for (auto &v: recv) for (int &x: v) cin >> x;\n\n    /* --- problem constants ------------------------------------------------ */\n    const int COL_IN  = 0;         // Receiving Gates  (column 0)\n    const int COL_OUT = N - 1;     // Dispatch  Gates  (column 4)\n\n    /* --- simulation state -------------------------------------------------- */\n    vector<vector<int>> field(N, vector<int>(N, -1));   // -1: empty, else id\n    array<int, 5> nextIdx{};                            // next container per row\n\n    vector<Crane> cr(N);            // 0 = big crane\n    for (int i = 0; i < N; ++i) cr[i] = {i, 0, true, false, -1};\n\n    vector<string> cmd(N);          // answer strings, one per crane\n\n    int dispatched = 0, turn = 0;\n\n    /* ---------------------------------------------------------------------- */\n    auto spawn = [&] () {\n        for (int r = 0; r < N; ++r) {\n            if (nextIdx[r] == N) continue;          // 5 containers already\n            if (field[r][COL_IN] != -1) continue;   // gate still occupied\n            bool holder_here = false;\n            for (auto &c : cr)\n                if (c.alive && c.holding && c.r == r && c.c == COL_IN)\n                    holder_here = true;\n            if (!holder_here)\n                field[r][COL_IN] = recv[r][nextIdx[r]++];\n        }\n    };\n\n    auto neighbours = [&](int r1, int c1, int r2, int c2) {\n        return abs(r1 - r2) + abs(c1 - c2);\n    };\n\n    /* =================== main turn loop =================================== */\n    while (dispatched < N * N) {\n        /* step 1: new containers arrive */\n        spawn();\n\n        /* step 2: decide commands ----------------------------------------- */\n        vector<char> op(N, '.');\n\n        /* small cranes: bomb on the very first turn, afterwards '.' */\n        if (turn == 0)\n            for (int i = 1; i < N; ++i) op[i] = 'B';\n\n        /* big crane logic */\n        Crane &b = cr[0];\n        char bc = '.';\n\n        if (b.holding) {                     // carrying a container\n            int destR = b.box / N, destC = COL_OUT;\n            if (b.r == destR && b.c == destC) {\n                // at the Dispatch Gate\n                bc = (field[destR][destC] == -1 ? 'Q' : '.');\n            } else {\n                // move one step toward destination (vertical first)\n                if (b.r < destR)      bc = 'D';\n                else if (b.r > destR) bc = 'U';\n                else if (b.c < destC) bc = 'R';\n                else                  bc = 'L';\n            }\n        } else {                              // empty-handed\n            if (field[b.r][b.c] != -1) {\n                bc = 'P';                     // box under our feet\n            } else {\n                // look for the nearest waiting box (always at column 0)\n                int bestR = -1, bestDist = 1e9;\n                for (int r = 0; r < N; ++r)\n                    if (field[r][COL_IN] != -1) {\n                        int d = neighbours(b.r, b.c, r, COL_IN);\n                        if (d < bestDist) bestDist = d, bestR = r;\n                    }\n                if (bestR == -1) {\n                    bc = '.';\n                } else {\n                    if (b.r < bestR)      bc = 'D';\n                    else if (b.r > bestR) bc = 'U';\n                    else if (b.c > COL_IN)bc = 'L';\n                    else                  bc = 'R';\n                }\n            }\n        }\n        op[0] = bc;\n\n        /* append to output strings */\n        for (int i = 0; i < N; ++i) cmd[i].push_back(op[i]);\n\n        /* apply actions ---------------------------------------------------- */\n        /* small cranes */\n        for (int i = 1; i < N; ++i) {\n            if (!cr[i].alive) continue;\n            if (op[i] == 'B') { cr[i].alive = false; continue; }\n        }\n\n        /* big crane */\n        switch (bc) {\n            case 'U': --b.r; break;\n            case 'D': ++b.r; break;\n            case 'L': --b.c; break;\n            case 'R': ++b.c; break;\n            case 'P':\n                b.holding = true;\n                b.box = field[b.r][b.c];\n                field[b.r][b.c] = -1;\n                break;\n            case 'Q':\n                field[b.r][b.c] = b.box;\n                b.holding = false;\n                b.box = -1;\n                break;\n            default: break;\n        }\n\n        /* step 3: automatic dispatch -------------------------------------- */\n        for (int r = 0; r < N; ++r)\n            if (field[r][COL_OUT] != -1) {\n                field[r][COL_OUT] = -1;      // container leaves the grid\n                ++dispatched;\n            }\n\n        ++turn;\n        if (turn >= 10000) break;            // safety (never reached)\n    }\n\n    /* pad the shorter strings with '.' ------------------------------------ */\n    const size_t L = cmd[0].size();\n    for (int i = 1; i < N; ++i)\n        if (cmd[i].size() < L) cmd[i].append(L - cmd[i].size(), '.');\n\n    /* output -------------------------------------------------------------- */\n    for (int i = 0; i < N; ++i) cout << cmd[i] << '\\n';\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Coord = pair<int,int>;\nconstexpr int N = 20;                     // fixed in all test cases\n\n/* -------------------------------------------------------------------------- */\n/*  Elementary helpers                                                        */\n/* -------------------------------------------------------------------------- */\nvoid move_to(int &r,int &c,int tr,int tc,vector<string>& out){\n    while(r<tr){ out.emplace_back(\"D\"); ++r; }\n    while(r>tr){ out.emplace_back(\"U\"); --r; }\n    while(c<tc){ out.emplace_back(\"R\"); ++c; }\n    while(c>tc){ out.emplace_back(\"L\"); --c; }\n}\n\n/* -------------------------------------------------------------------------- */\n/*  1. Classical snakes                                                       */\n/* -------------------------------------------------------------------------- */\nvector<Coord> build_row_snake(bool firstLeftRight){\n    vector<Coord> p; p.reserve(N*N);\n    for(int r=0;r<N;r++){\n        if( (r&1) == (firstLeftRight?0:1) )\n            for(int c=0;c<N;c++) p.emplace_back(r,c);\n        else\n            for(int c=N-1;c>=0;--c) p.emplace_back(r,c);\n    }\n    return p;\n}\nvector<Coord> build_col_snake(bool firstTopBottom){\n    vector<Coord> p; p.reserve(N*N);\n    for(int c=0;c<N;c++){\n        if( (c&1) == (firstTopBottom?0:1) )\n            for(int r=0;r<N;r++) p.emplace_back(r,c);\n        else\n            for(int r=N-1;r>=0;--r) p.emplace_back(r,c);\n    }\n    return p;\n}\n\n/* -------------------------------------------------------------------------- */\n/*  2. Spiral                                                                 */\n/* -------------------------------------------------------------------------- */\nvector<Coord> build_spiral(bool clockwise){\n    vector<Coord> p; p.reserve(N*N);\n    int top=0, bot=N-1, left=0, right=N-1;\n    while(top<=bot && left<=right){\n        if(clockwise){\n            for(int c=left;c<=right;c++) p.emplace_back(top,c);\n            ++top;\n            for(int r=top;r<=bot;r++)   p.emplace_back(r,right);\n            --right;\n            if(top<=bot){\n                for(int c=right;c>=left;c--) p.emplace_back(bot,c);\n                --bot;\n            }\n            if(left<=right){\n                for(int r=bot;r>=top;r--)   p.emplace_back(r,left);\n                ++left;\n            }\n        }else{                     // counter-clockwise\n            for(int r=top;r<=bot;r++)   p.emplace_back(r,left);\n            ++left;\n            for(int c=left;c<=right;c++) p.emplace_back(bot,c);\n            --bot;\n            if(left<=right){\n                for(int r=bot;r>=top;r--)   p.emplace_back(r,right);\n                --right;\n            }\n            if(top<=bot){\n                for(int c=right;c>=left;c--) p.emplace_back(top,c);\n                ++top;\n            }\n        }\n    }\n    return p;\n}\n\n/* -------------------------------------------------------------------------- */\n/*  3. New: 2-column loop snake                                               */\n/* -------------------------------------------------------------------------- */\nvector<Coord> build_col_pair_loop() {\n    vector<Coord> p; p.reserve(N*N);\n    for(int c=0;c<N;c+=2){\n        int c0 = c;\n        int c1 = c+1;\n        for(int r=0;r<N;r++) p.emplace_back(r,c0);        // down left col\n        for(int r=N-1;r>=0;--r) p.emplace_back(r,c1);     // up  right col\n    }\n    return p;\n}\n/* -------------------------------------------------------------------------- */\n/*  4. New: 2-row loop snake                                                  */\n/* -------------------------------------------------------------------------- */\nvector<Coord> build_row_pair_loop() {\n    vector<Coord> p; p.reserve(N*N);\n    for(int r=0;r<N;r+=2){\n        int r0 = r;\n        int r1 = r+1;\n        for(int c=0;c<N;c++) p.emplace_back(r0,c);        // \u2192 upper row\n        for(int c=N-1;c>=0;--c) p.emplace_back(r1,c);     // \u2190 lower row\n    }\n    return p;\n}\n\n/* -------------------------------------------------------------------------- */\n/*  Compute cheapest feasible rotation and its movement cost                  */\n/* -------------------------------------------------------------------------- */\nlong long eval_path(const vector<Coord>& path,\n                    const vector<vector<int>>& h,\n                    int &chosenStart)\n{\n    const int M = path.size();               // 400\n    static long long pref[401];\n    pref[0] = 0;\n    for(int i=0;i<M;i++){\n        auto [r,c] = path[i];\n        pref[i+1] = pref[i] + h[r][c];\n    }\n    long long mn = pref[0]; int mnPos = 0;\n    for(int i=1;i<=M;i++)\n        if(pref[i] < mn){ mn = pref[i]; mnPos = i; }\n\n    int s = mnPos % M;                      // feasible rotation\n    chosenStart = s;\n\n    /* prefix-load sum ----------------------------------------------------- */\n    long long cost = 0, load = 0;\n    for(int k=0;k<M-1;k++){\n        load += h[path[(s+k)%M].first][path[(s+k)%M].second];\n        cost += load;                       // load before the next move\n    }\n    return cost;                            // \u03a3 load term only\n}\n\n/* -------------------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyN;\n    if(!(cin>>dummyN)) return 0;\n\n    vector<vector<int>> h(N, vector<int>(N));\n    for(auto &row:h) for(int &x:row) cin>>x;\n\n    /* ---------- build 20 candidate Hamiltonian paths -------------------- */\n    vector<vector<Coord>> paths;\n\n    paths.push_back(build_row_snake(true));\n    paths.push_back(build_row_snake(false));\n    paths.push_back(build_col_snake(true));\n    paths.push_back(build_col_snake(false));\n    paths.push_back(build_spiral(true));\n    paths.push_back(build_spiral(false));\n    paths.push_back(build_col_pair_loop());\n    paths.push_back(build_row_pair_loop());\n\n    const int initCnt = paths.size();\n    for(int i=0;i<initCnt;i++){             // add reversed versions\n        vector<Coord> rev = paths[i];\n        reverse(rev.begin(), rev.end());\n        paths.push_back(move(rev));\n    }\n\n    /* ---------- evaluate all paths -------------------------------------- */\n    long long bestScore = (1LL<<62);\n    int bestPid = 0, bestStart = 0, bestDist = 0;\n\n    for(int pid=0; pid<(int)paths.size(); ++pid){\n        int startIdx = 0;\n        long long loadSum = eval_path(paths[pid], h, startIdx);\n\n        auto [sr,sc] = paths[pid][startIdx];\n        int approach = abs(sr) + abs(sc);               // empty truck\n\n        long long mv = 100LL*( (N*N-1) + approach );    // 100 per move\n        long long totalMoveCost = loadSum + mv;\n\n        if(totalMoveCost < bestScore){\n            bestScore  = totalMoveCost;\n            bestPid    = pid;\n            bestStart  = startIdx;\n            bestDist   = approach;\n        }\n    }\n\n    /* ---------- produce the chosen operation list ----------------------- */\n    const auto& path = paths[bestPid];\n    const int M = path.size();\n    const int s = bestStart;\n\n    vector<string> out; out.reserve(1200);\n\n    int r = 0, c = 0, load = 0;\n    auto [sr,sc] = path[s];\n    move_to(r,c,sr,sc,out);                        // empty approach\n\n    for(int k=0;k<M;k++){\n        int idx = (s + k) % M;\n        auto [cr,cc] = path[idx];\n        int val = h[cr][cc];\n\n        if(val > 0){\n            out.emplace_back(\"+\" + to_string(val));\n            load += val;\n        }else if(val < 0){\n            out.emplace_back(\"-\" + to_string(-val));\n            load -= -val;\n        }\n        if(k != M-1){\n            auto [nr,nc] = path[(idx+1)%M];\n            move_to(r,c,nr,nc,out);               // exactly one step\n        }\n    }\n    /* load is guaranteed to be 0 here */\n\n    for(const string& s : out) cout << s << '\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** fixed parameters ***/\nconstexpr int N  = 6;               // grid size\nconstexpr int M  = 15;              // #criteria\nconstexpr int T  = 10;              // #turns\nconstexpr int SEED_CNT = 2 * N * (N - 1);     // always 60\nconstexpr int PLANT_CNT = N * N;               // 36\n\nstruct Seed {\n    array<uint8_t, M> x;\n    int               sum = 0;\n};\n\n/*** geometry of the 6\u00d76 field ***/\narray<vector<int>, PLANT_CNT> neighbours;\nvector<pair<int,int>>          edges;          // each edge once\narray<int, PLANT_CNT>          degree;\n\nvoid build_geometry() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c) {\n            int idx = r * N + c;\n            auto add = [&](int rr,int cc){\n                if (0<=rr && rr<N && 0<=cc && cc<N)\n                    neighbours[idx].push_back(rr*N+cc);\n            };\n            if (c+1 < N){ add(r,c+1); edges.emplace_back(idx, r*N+c+1); }\n            if (r+1 < N){ add(r+1,c); edges.emplace_back(idx, (r+1)*N+c); }\n            add(r,c-1); add(r-1,c);          // for fast \u0394 evaluation\n        }\n    for (int i = 0; i < PLANT_CNT; ++i) degree[i] = (int)neighbours[i].size();\n}\n\n/*** global containers reused every turn ***/\narray<Seed, SEED_CNT> seed;           // current 60 seeds\nint   syn[SEED_CNT][SEED_CNT];        // synergy matrix (\u22641500, fits in int)\narray<int, PLANT_CNT>  cell2seed;     // current grid \u2192 seed id\narray<int, PLANT_CNT>  bestPlant;     // best arrangement found\nlong long              bestScore;\n\n/*** synergy between two seeds ***/\ninline int synergy(int a,int b){ return syn[a][b]; }\n\n/*** objective = \u03a3 synergy over (undirected) edges *********************/\ninline long long objective() {\n    long long s = 0;\n    for (auto [u,v]: edges) s += synergy(cell2seed[u], cell2seed[v]);\n    return s;\n}\n\n/*** fast \u0394 when swapping/replacing one cell ***************************/\nlong long delta_one_cell(int pos,int oldSeed,int newSeed){\n    long long d = 0;\n    for (int nb : neighbours[pos]) {\n        d -= synergy(oldSeed      , cell2seed[nb]);\n        d += synergy(newSeed      , cell2seed[nb]);\n    }\n    return d;\n}\n\n/*** a very small simulated annealing **********************************/\nvoid simulated_annealing(mt19937_64 &rng,\n                         vector<int> &pool) {\n    constexpr int ITER      = 30000;\n    constexpr double T0     = 1000.0;\n    constexpr double T1     = 5.0;\n    uniform_real_distribution<double> urd(0.0,1.0);\n    uniform_int_distribution<int>     cellDist(0, PLANT_CNT-1);\n\n    bestPlant = cell2seed;\n    bestScore = objective();\n    long long curScore = bestScore;\n\n    for (int it = 0; it < ITER; ++it) {\n        double temp = T0 + (T1 - T0) * it / ITER;\n\n        if (!pool.empty() && urd(rng) < 0.30) {            // replace with pool\n            int pos  = cellDist(rng);\n            int pidx = uniform_int_distribution<int>(0,(int)pool.size()-1)(rng);\n            int s_old = cell2seed[pos], s_new = pool[pidx];\n            long long d = delta_one_cell(pos, s_old, s_new);\n\n            if (d >= 0 || urd(rng) < exp(d / temp)) {\n                cell2seed[pos] = s_new;\n                pool[pidx]     = s_old;\n                curScore      += d;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestPlant = cell2seed;\n                }\n            }\n        } else {                                           // swap two cells\n            int a = cellDist(rng), b = cellDist(rng);\n            if (a == b) continue;\n            int sa = cell2seed[a], sb = cell2seed[b];\n\n            long long d  = delta_one_cell(a, sa, sb)\n                         + delta_one_cell(b, sb, sa);\n            if (d >= 0 || urd(rng) < exp(d / temp)) {\n                cell2seed[a] = sb;\n                cell2seed[b] = sa;\n                curScore    += d;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestPlant = cell2seed;\n                }\n            }\n        }\n    }\n    cell2seed = bestPlant;\n}\n\n/*** main **************************************************************/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    build_geometry();\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    /* --- read the very first 60 seeds --------------------------------*/\n    int dummyN, dummyM, dummyT;\n    cin >> dummyN >> dummyM >> dummyT;          // they are always 6 15 10\n    for (int i = 0; i < SEED_CNT; ++i){\n        int sum = 0;\n        for (int l = 0; l < M; ++l){\n            int v; cin >> v;\n            seed[i].x[l] = (uint8_t)v;\n            sum += v;\n        }\n        seed[i].sum = sum;\n    }\n\n    for (int turn = 0; turn < T; ++turn){\n        /* --- choose seeds to work with: 36 best by V -----------------*/\n        vector<int> idx(SEED_CNT); iota(idx.begin(), idx.end(), 0);\n        ranges::sort(idx, [&](int a,int b){ return seed[a].sum > seed[b].sum; });\n\n        vector<int> pool(idx.begin()+PLANT_CNT, idx.end());          // 24 seeds\n        /* --- precalculate synergy matrix -----------------------------*/\n        for (int i = 0; i < SEED_CNT; ++i){\n            syn[i][i] = seed[i].sum;          // not needed, but harmless\n            for (int j = i+1; j < SEED_CNT; ++j){\n                int s = 0;\n                for (int l = 0; l < M; ++l)\n                    s += max(seed[i].x[l], seed[j].x[l]);\n                syn[i][j] = syn[j][i] = s;\n            }\n        }\n\n        /* --- initial placement: best seeds on highest-degree cells ---*/\n        array<int, PLANT_CNT> cells;\n        iota(cells.begin(), cells.end(), 0);\n        ranges::sort(cells, [&](int a,int b){ return degree[a] > degree[b]; });\n\n        for (int k = 0; k < PLANT_CNT; ++k)\n            cell2seed[cells[k]] = idx[k];\n\n        /* --- improve by SA -------------------------------------------*/\n        simulated_annealing(rng, pool);\n\n        /* --- output --------------------------------------------------*/\n        for (int r = 0; r < N; ++r){\n            for (int c = 0; c < N; ++c){\n                if (c) cout << ' ';\n                cout << cell2seed[r*N+c];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        /* --- read the 60 children for the next turn ------------------*/\n        if (turn == T-1) break;               // still need to read, but no calc\n        for (int i = 0; i < SEED_CNT; ++i){\n            int sum = 0;\n            for (int l = 0; l < M; ++l){\n                int v; cin >> v;\n                seed[i].x[l] = (uint8_t)v;\n                sum += v;\n            }\n            seed[i].sum = sum;\n        }\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Pos { int x, y; };\nstatic constexpr int DX[4] = {0, 1, 0,-1};\nstatic constexpr int DY[4] = {1, 0,-1, 0};\n\nint manhattan(const Pos& a, const Pos& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n/* the 4 candidate root positions for a square (i,j) ------------------ */\ninline bool in_field(int x,int y,int N){ return 0<=x && x<N && 0<=y && y<N; }\narray<Pos,4> cand_root(const Pos& p){      // R,D,L,U\n    return {{{p.x-DX[0],p.y-DY[0]},\n             {p.x-DX[1],p.y-DY[1]},\n             {p.x-DX[2],p.y-DY[2]},\n             {p.x-DX[3],p.y-DY[3]}}};\n}\n\n/* ------------------------------------------------------------------ */\nstruct Simulator {\n    int N;\n    vector<string> cmd;          // final command list\n\n    int rx=0, ry=0;              // current root position\n    int dir=0;                   // 0:R 1:D 2:L 3:U\n    bool holding=false;\n\n    void push(char mv,char rot,char act){\n        string s(4,'.');\n        s[0]=mv; s[1]=rot; s[3]=act;\n        cmd.push_back(move(s));\n    }\n\n    /* move root to (tx,ty) and orient fingertip to targetDir --------*/\n    void move_and_rotate(int tx,int ty,int targetDir){\n        int cw = (targetDir - dir + 4) % 4;\n        int ccw= (dir - targetDir + 4) % 4;\n        char rotChar; int rotCnt;\n        if (cw<=ccw){ rotChar='R'; rotCnt=cw; }\n        else        { rotChar='L'; rotCnt=ccw; }\n\n        /* overlap rotation steps with translation ------------------ */\n        while (rx!=tx || ry!=ty){\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\n            char rot='.';\n            if(rotCnt>0){\n                rot=rotChar; --rotCnt;\n                dir = (dir + (rot=='R'?1:3)) & 3;\n            }\n            push(mv,rot,'.');\n        }\n        /* remaining rotations (if translation shorter than diff) ---- */\n        while(rotCnt--){\n            push('.' ,rotChar,'.');\n            dir = (dir + (rotChar=='R'?1:3)) & 3;\n        }\n    }\n};\n/* ------------------------------------------------------------------ */\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N,M,Vmax;\n    if(!(cin>>N>>M>>Vmax)) 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    /* ----------------- split into sources / targets ---------------- */\n    vector<Pos> src, tar;\n    for(int i=0;i<N;++i)\n        for(int j=0;j<N;++j){\n            bool s = S[i][j]=='1';\n            bool t = T[i][j]=='1';\n            if( s && !t) src.push_back({i,j});\n            if(!s &&  t) tar.push_back({i,j});\n        }\n\n    /* --------------------------- output arm ------------------------ */\n    cout<<2<<\"\\n\";\n    cout<<0<<\" 1\\n\";             // child 1 at distance 1\n    cout<<0<<\" 0\\n\";             // root starts (0,0)\n\n    Simulator sim; sim.N = N;\n\n    /* we remove items from vectors, therefore random-access index ----*/\n    auto erase_swap = [](vector<Pos>& v,size_t idx){\n        v[idx]=v.back(); v.pop_back();\n    };\n\n    /* -------------------------- main loop -------------------------- */\n    while(!src.empty()){\n        /* ------------------------------------------------ source step */\n        int bestIdx=-1, bestD=INT_MAX, bestRootX=0, bestRootY=0, bestDir=0;\n        for(size_t i=0;i<src.size();++i){\n            const Pos& p = src[i];\n            auto roots = cand_root(p);\n            for(int d=0;d<4;++d){\n                int x=roots[d].x, y=roots[d].y;\n                if(!in_field(x,y,N)) continue;\n                int path = manhattan({sim.rx,sim.ry},{x,y});\n                int rot  = min((d - sim.dir + 4)%4,(sim.dir - d +4)%4);\n                int cost = path + max(0, rot - path);   // rotations not overlap\n                if(cost<bestD){\n                    bestD=cost; bestIdx=i;\n                    bestRootX=x; bestRootY=y; bestDir=d;\n                }\n            }\n        }\n\n        /* go there, pick ------------------------------------------- */\n        sim.move_and_rotate(bestRootX,bestRootY,bestDir);\n        sim.push('.','.','P');           // grab\n        sim.holding=true;\n        Pos piece = src[bestIdx];\n        erase_swap(src,bestIdx);\n\n        /* ------------------------------------------------ target step */\n        int bestTarIdx=-1, bestDist=INT_MAX;\n        for(size_t i=0;i<tar.size();++i){\n            int d = manhattan(piece, tar[i]);\n            if(d<bestDist){ bestDist=d; bestTarIdx=i; }\n        }\n        Pos goal = tar[bestTarIdx];\n        erase_swap(tar,bestTarIdx);\n\n        int bestRX=0,bestRY=0,bestTD=0,bestC=INT_MAX;\n        auto roots = cand_root(goal);\n        for(int d=0;d<4;++d){\n            int x=roots[d].x, y=roots[d].y;\n            if(!in_field(x,y,N)) continue;\n            int path = manhattan({sim.rx,sim.ry},{x,y});\n            int rot  = min((d - sim.dir + 4)%4,(sim.dir - d +4)%4);\n            int cost = path + max(0, rot - path);\n            if(cost<bestC){ bestC=cost; bestRX=x; bestRY=y; bestTD=d; }\n        }\n\n        /* go there, place ------------------------------------------ */\n        sim.move_and_rotate(bestRX,bestRY,bestTD);\n        sim.push('.','.','P');           // drop\n        sim.holding=false;\n    }\n\n    /* -------------------------- command list ----------------------- */\n    for(const string& s: sim.cmd) cout<<s<<\"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* --------------------------------------------------------------------- */\nstruct Point { int x, y; };\nstruct Rect  { int x1, y1, x2, y2;           // inclusive\n               bool valid() const { return x1 < x2 && y1 < y2; } };\n/* --------------------------------------------------------------------- */\nconstexpr int MAXC = 100000;\nconstexpr int CELL = 250;\nconstexpr int GRID = MAXC / CELL + 1;         // 401\n\nstatic int diffGrid[GRID][GRID];\nstatic int pref[GRID + 1][GRID + 1];\n\ninline int gridSum(int t,int l,int b,int r){  // inclusive\n    return pref[b+1][r+1] - pref[t][r+1] - pref[b+1][l] + pref[t][l];\n}\n\n/* exact score of any rectangle (inclusive) ----------------------------- */\nint exactScore(const Rect &r,\n               const vector<Point> &mac,\n               const vector<Point> &sar)\n{\n    int res = 0;\n    for (const auto &p: mac)\n        if (r.x1 <= p.x && p.x <= r.x2 && r.y1 <= p.y && p.y <= r.y2) ++res;\n    for (const auto &p: sar)\n        if (r.x1 <= p.x && p.x <= r.x2 && r.y1 <= p.y && p.y <= r.y2) --res;\n    return res;\n}\n\n/* 1-D optimum for one side --------------------------------------------- */\ntemplate<bool vertical, bool lower>           // lower ? left/bottom : right/top\nbool optimiseSide(Rect &R, int &best,\n                  const vector<Point> &mac,\n                  const vector<Point> &sar)\n{\n    /* collect relevant fish */\n    vector<pair<int,int>> v;                  // (coord , value)\n    v.reserve(20000);\n\n    if constexpr (vertical) {                 // optimise x1/x2\n        for (const auto &p: mac)\n            if (R.y1 <= p.y && p.y <= R.y2 &&\n                (lower ? p.x <= R.x2 : p.x >= R.x1))\n                v.emplace_back(p.x, +1);\n        for (const auto &p: sar)\n            if (R.y1 <= p.y && p.y <= R.y2 &&\n                (lower ? p.x <= R.x2 : p.x >= R.x1))\n                v.emplace_back(p.x, -1);\n    } else {                                  // optimise y1/y2\n        for (const auto &p: mac)\n            if (R.x1 <= p.x && p.x <= R.x2 &&\n                (lower ? p.y <= R.y2 : p.y >= R.y1))\n                v.emplace_back(p.y, +1);\n        for (const auto &p: sar)\n            if (R.x1 <= p.x && p.x <= R.x2 &&\n                (lower ? p.y <= R.y2 : p.y >= R.y1))\n                v.emplace_back(p.y, -1);\n    }\n    if (v.empty()) return false;\n\n    /* compress equal coordinates */\n    sort(v.begin(), v.end(),\n         [](auto a, auto b){ return a.first < b.first; });\n    vector<pair<int,int>> g;                  // (coord , sumVal)\n    g.reserve(v.size());\n    for (auto [c,val] : v) {\n        if (g.empty() || g.back().first != c) g.emplace_back(c,val);\n        else g.back().second += val;\n    }\n\n    /* total diff when side is at extreme 0 / MAXC */\n    int total = 0;\n    for (auto &p : g) total += p.second;\n\n    bool improved = false;\n    if constexpr (vertical &&  lower){        /* LEFT side sweep \u2192 right */\n        int prefix = 0, bestLocal = best, bestPos = R.x1;\n\n        /* candidate at extreme x1 = 0 */\n        if (total > bestLocal && 0 < R.x2) {\n            bestLocal = total; bestPos = 0; improved = true;\n        }\n        for (size_t i = 0; i < g.size(); ++i) {\n            int x = g[i].first, group = g[i].second;\n\n            /* x1 = x (fish on edge stay inside) */\n            if (x < R.x2) {\n                int sc = total - prefix;\n                if (sc > bestLocal) { bestLocal = sc; bestPos = x; improved = true; }\n            }\n            /* x1 = x+1 (fish on x are kicked out) */\n            if (x+1 < R.x2) {\n                int sc = total - (prefix + group);\n                if (sc > bestLocal) { bestLocal = sc; bestPos = x+1; improved = true; }\n            }\n            prefix += group;\n        }\n        if (improved){ R.x1 = bestPos; best = bestLocal; }\n    }\n    else if constexpr (vertical && !lower){   /* RIGHT side sweep \u2190 left */\n        int suffix = 0, bestLocal = best, bestPos = R.x2;\n\n        /* x2 = MAXC */\n        if (total > bestLocal && MAXC > R.x1) {\n            bestLocal = total; bestPos = MAXC; improved = true;\n        }\n        for (int idx = (int)g.size()-1; idx >= 0; --idx) {\n            int x = g[idx].first, group = g[idx].second;\n\n            /* x2 = x (fish stay inside) */\n            if (x > R.x1) {\n                int sc = total - suffix;\n                if (sc > bestLocal) { bestLocal = sc; bestPos = x; improved = true; }\n            }\n            /* x2 = x-1 */\n            if (x-1 > R.x1) {\n                int sc = total - (suffix + group);\n                if (sc > bestLocal) { bestLocal = sc; bestPos = x-1; improved = true; }\n            }\n            suffix += group;\n        }\n        if (improved){ R.x2 = bestPos; best = bestLocal; }\n    }\n    else if constexpr (!vertical && lower){   /* BOTTOM side sweep \u2191 */\n        int prefix = 0, bestLocal = best, bestPos = R.y1;\n        if (total > bestLocal && 0 < R.y2) {\n            bestLocal = total; bestPos = 0; improved = true;\n        }\n        for (size_t i = 0; i < g.size(); ++i){\n            int y = g[i].first, group = g[i].second;\n            if (y < R.y2){\n                int sc = total - prefix;\n                if (sc > bestLocal){ bestLocal = sc; bestPos = y; improved = true;}\n            }\n            if (y+1 < R.y2){\n                int sc = total - (prefix + group);\n                if (sc > bestLocal){bestLocal = sc; bestPos = y+1; improved = true;}\n            }\n            prefix += group;\n        }\n        if (improved){ R.y1 = bestPos; best = bestLocal; }\n    }\n    else {                                    /* TOP side sweep \u2193 */\n        int suffix = 0, bestLocal = best, bestPos = R.y2;\n        if (total > bestLocal && MAXC > R.y1){\n            bestLocal = total; bestPos = MAXC; improved = true;\n        }\n        for (int idx=(int)g.size()-1; idx>=0; --idx){\n            int y = g[idx].first, group=g[idx].second;\n            if (y > R.y1){\n                int sc = total - suffix;\n                if (sc > bestLocal){ bestLocal = sc; bestPos = y; improved = true; }\n            }\n            if (y-1 > R.y1){\n                int sc = total - (suffix + group);\n                if (sc > bestLocal){ bestLocal = sc; bestPos = y-1; improved = true; }\n            }\n            suffix += group;\n        }\n        if (improved){ R.y2 = bestPos; best = bestLocal; }\n    }\n    return improved;\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<Point> mac(N), sar(N);\n    for(int i=0;i<N;++i) cin>>mac[i].x>>mac[i].y;\n    for(int i=0;i<N;++i) cin>>sar[i].x>>sar[i].y;\n\n    /* 1. difference grid & prefix sum ------------------------------------ */\n    for(auto &p:mac) diffGrid[p.y/CELL][p.x/CELL]+=1;\n    for(auto &p:sar) diffGrid[p.y/CELL][p.x/CELL]-=1;\n\n    for(int y=0;y<GRID;++y){\n        int row=0;\n        for(int x=0;x<GRID;++x){\n            row+=diffGrid[y][x];\n            pref[y+1][x+1]=pref[y][x+1]+row;\n        }\n    }\n\n    /* 2. exact 2-D Kadane on the grid ------------------------------------ */\n    int best=-1e9, bl=0,br=0,bt=0,bb=0;\n    static int colSum[GRID];\n\n    for(int top=0;top<GRID;++top){\n        fill(colSum,colSum+GRID,0);\n        for(int bot=top;bot<GRID;++bot){\n            for(int x=0;x<GRID;++x) colSum[x]+=diffGrid[bot][x];\n\n            int cur=0, curL=0;\n            for(int x=0;x<GRID;++x){\n                cur+=colSum[x];\n                if(cur>best){ best=cur; bl=curL; br=x; bt=top; bb=bot; }\n                if(cur<0){ cur=0; curL=x+1; }\n            }\n        }\n    }\n\n    /* 3. random rectangles (unchanged) ----------------------------------- */\n    mt19937 rng(123456);\n    uniform_int_distribution<int> macPick(0,N-1),\n                                  sizePick(1,60);\n    const int SAMPLES=60000;\n\n    for(int s=0;s<SAMPLES;++s){\n        const auto &c=mac[macPick(rng)];\n        int gx=c.x/CELL, gy=c.y/CELL;\n        int w=sizePick(rng), h=sizePick(rng);\n        int l=max(0,gx-w/2);\n        int r=min(GRID-1,l+w-1);\n        l=max(0,r-w+1);\n        int t=max(0,gy-h/2);\n        int b=min(GRID-1,t+h-1);\n        t=max(0,b-h+1);\n\n        int sc=gridSum(t,l,b,r);\n        if(sc>best){best=sc; bl=l;br=r;bt=t;bb=b;}\n    }\n\n    /* 4. greedy cell shrink ---------------------------------------------- */\n    bool change=true;\n    while(change){\n        change=false;\n        int cur=gridSum(bt,bl,bb,br);\n        if(bl<br && gridSum(bt,bl+1,bb,br)>cur){++bl;change=true;continue;}\n        if(bl<br && gridSum(bt,bl,bb,br-1)>cur){--br;change=true;continue;}\n        if(bt<bb && gridSum(bt+1,bl,bb,br)>cur){++bt;change=true;continue;}\n        if(bt<bb && gridSum(bt,bl,bb-1,br)>cur){--bb;change=true;continue;}\n    }\n\n    /* 5. convert to real coordinates & initial exact score ---------------- */\n    Rect R{bl*CELL,\n           bt*CELL,\n           min(MAXC,(br+1)*CELL-1),\n           min(MAXC,(bb+1)*CELL-1)};\n\n    best = exactScore(R,mac,sar);\n\n    /* 6. repeated exact 1-D side optimisation ----------------------------- */\n    for(int round=0; round<6; ++round){\n        bool improved=false;\n        improved |= optimiseSide<true ,true >(R,best,mac,sar); // left\n        improved |= optimiseSide<true ,false>(R,best,mac,sar); // right\n        improved |= optimiseSide<false,true >(R,best,mac,sar); // bottom\n        improved |= optimiseSide<false,false>(R,best,mac,sar); // top\n        if(!improved) break;\n    }\n\n    /* 7. final safety fallback ------------------------------------------- */\n    if(best<=0 || !R.valid()) R={0,0,1,1};\n\n    /* 8. output rectangle ------------------------------------------------- */\n    cout<<4<<\"\\n\";\n    cout<<R.x1<<\" \"<<R.y1<<\"\\n\";\n    cout<<R.x2<<\" \"<<R.y1<<\"\\n\";\n    cout<<R.x2<<\" \"<<R.y2<<\"\\n\";\n    cout<<R.x1<<\" \"<<R.y2<<\"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\n\n/*------------------------------------------------------------------*/\n/*  data of a rectangle in the two possible orientations            */\n/*------------------------------------------------------------------*/\nstruct Rec  { int64 w , h; };           // as read (w' , h')\nstatic inline Rec rot(const Rec& r){ return Rec{r.h , r.w}; }\n\n/*------------------------------------------------------------------*/\n/*  a packing is described by                                       */\n/*      \u2013 orientation[i]  (0 / 1)                                   */\n/*      \u2013 rowStart[i]     true  <=>  i is the first in its row      */\n/*------------------------------------------------------------------*/\nstruct Layout {\n    vector<char>  orient;    // size N\n    vector<char>  rowStart;  // size N (rowStart[0] == 1)\n    int64         score;     // exact W + H\n};\n\n/*------------------------------------------------------------------*/\n/*  exact evaluation of a layout                                    */\n/*------------------------------------------------------------------*/\nint64 evaluate_exact(const vector<Rec>& r,\n                     const vector<char>& orient,\n                     const vector<char>& rowStart)\n{\n    const int N = (int)r.size();\n    vector<int> rowIdx;               // starting indices of rows\n    for (int i = 0; i < N; ++i) if (rowStart[i]) rowIdx.push_back(i);\n    const int R = (int)rowIdx.size();\n\n    /*  pre-compute per row                                              */\n    vector<int64> rowW(R,0), rowH(R,0);\n    vector<int>    tallest(R);        // index of a tallest rectangle\n    for (int rr = 0; rr < R; ++rr) {\n        int st = rowIdx[rr];\n        int ed = (rr+1<R ? rowIdx[rr+1] : N);\n        int64 hMax = -1;\n        for (int i = st; i < ed; ++i) {\n            const Rec& rc = (orient[i] ? rot(r[i]) : r[i]);\n            rowW[rr] += rc.w;\n            if (rc.h > hMax) { hMax = rc.h; tallest[rr] = i; }\n        }\n        rowH[rr] = hMax;\n    }\n\n    /*  forward simulation \u2013 x-coordinate of every rectangle             */\n    vector<int64> posX(N,0);          // left edge\n    vector<int64> offset(R,0);        // left edge of the first rect\n    int64 maxX = 0, sumH = 0;\n\n    for (int rr = 0; rr < R; ++rr) {\n        int st = rowIdx[rr];\n        int ed = (rr+1<R ? rowIdx[rr+1] : N);\n\n        /* place rectangles of this row, contiguous left-to-right        */\n        for (int i = st; i < ed; ++i) {\n            const Rec& rc = (orient[i] ? rot(r[i]) : r[i]);\n            if (i == st) posX[i] = offset[rr];\n            else         posX[i] = posX[i-1] + (orient[i-1] ? rot(r[i-1]).w : r[i-1].w);\n            maxX = max(maxX, posX[i] + rc.w);\n        }\n        sumH += rowH[rr];\n\n        /* compute the offset of the next row                            */\n        if (rr+1 < R) {\n            int base = tallest[rr];                   // rectangle the next row refers to\n            int64 baseLeft = posX[base];\n            int64 nxtOffset = baseLeft - rowW[rr+1];  // right edge must touch baseLeft\n            if (nxtOffset < 0) nxtOffset = 0;         // stopped by x = 0\n            offset[rr+1] = nxtOffset;\n        }\n    }\n    return maxX + sumH;\n}\n\n/*------------------------------------------------------------------*/\n/*  helper: build an initial layout with a width limit               */\n/*------------------------------------------------------------------*/\nLayout greedy_initial(const vector<Rec>& r, double widthLimit)\n{\n    const int N = (int)r.size();\n    vector<char> orient(N,0), rowStart(N,0); rowStart[0]=1;\n\n    double curW = 0; double curH = 0;       // working with doubles \u2013 fine\n\n    for (int i=0;i<N;++i){\n        Rec a = r[i], b = rot(r[i]);\n\n        /*  try to stay in the current row                              */\n        bool fitA = (curW + a.w <= widthLimit);\n        bool fitB = (curW + b.w <= widthLimit);\n\n        char use = 0;\n        if (fitA && fitB){\n            /*  choose the orientation that keeps the smaller height    */\n            double hA = max(curH , (double)a.h);\n            double hB = max(curH , (double)b.h);\n            if (hB < hA || (hB==hA && b.w<a.w)) use = 1;\n        }else if (!fitA && fitB) use = 1;\n        else if (!fitA && !fitB){\n            /*  start a new row                                         */\n            rowStart[i]=1;\n            curW = 0; curH = 0;\n            fitA = fitB = true;\n            if (b.h < a.h || (b.h==a.h && b.w<a.w)) use = 1;\n        }\n        orient[i]=use;\n        const Rec& rc = (use?b:a);\n        curW += rc.w;\n        curH = max(curH,(double)rc.h);\n    }\n    Layout L{orient,rowStart,0};\n    L.score = evaluate_exact(r, L.orient, L.rowStart);\n    return L;\n}\n\n/*------------------------------------------------------------------*/\n/*  single-variable SA / hill-climb                                  */\n/*------------------------------------------------------------------*/\nLayout improveSA(const vector<Rec>& r, Layout lay,\n                 const chrono::steady_clock::time_point& deadline)\n{\n    const int N = (int)r.size();\n    std::mt19937 rng(1234567);\n    uniform_int_distribution<int> pickRec(0,N-1);\n    uniform_real_distribution<double> uni(0,1);\n\n    const int MAX_IT = 300000;\n    double T0 = lay.score * 0.3, T1 = 1.0;\n    auto temp = [&](int it){ double f=(double)it/MAX_IT; return T0*pow(T1/T0,f); };\n\n    for (int it=0; it<MAX_IT; ++it){\n        if (chrono::steady_clock::now() > deadline) break;\n        bool opOrientation = (uni(rng) < 0.6);   // 60 % flips, 40 % row cut toggles\n        int idx = pickRec(rng);\n\n        if (opOrientation){\n            lay.orient[idx] ^= 1;\n            int64 newScore = evaluate_exact(r,lay.orient,lay.rowStart);\n            int64 diff = newScore - lay.score;\n            if (diff < 0 || uni(rng) < exp(-diff / temp(it))) lay.score = newScore;\n            else lay.orient[idx] ^= 1;           // revert\n        }else{\n            if (idx==0) continue;                // rowStart[0] is fixed\n            if (!lay.rowStart[idx] && !lay.rowStart[idx-1]){\n                /*  try to add a cut                                         */\n                lay.rowStart[idx] = 1;\n                int64 newScore = evaluate_exact(r,lay.orient,lay.rowStart);\n                int64 diff = newScore - lay.score;\n                if (diff < 0 || uni(rng) < exp(-diff / temp(it))) lay.score = newScore;\n                else lay.rowStart[idx] = 0;      // revert\n            }else if (lay.rowStart[idx] && (idx+1==N || !lay.rowStart[idx+1])){\n                /*  try to remove a cut                                       */\n                lay.rowStart[idx] = 0;\n                int64 newScore = evaluate_exact(r,lay.orient,lay.rowStart);\n                int64 diff = newScore - lay.score;\n                if (diff < 0 || uni(rng) < exp(-diff / temp(it))) lay.score = newScore;\n                else lay.rowStart[idx] = 1;      // revert\n            }\n        }\n    }\n    return lay;\n}\n\n/*------------------------------------------------------------------*/\n/*  build output commands                                            */\n/*------------------------------------------------------------------*/\nstruct Cmd { int p; char r,d; int b; };\n\nvector<Cmd> build_commands(const vector<Rec>& r, const Layout& lay)\n{\n    const int N = (int)r.size();\n    /* locate rows & tallest per row (again, now final)                  */\n    vector<int> rowIdx; for(int i=0;i<N;++i) if(lay.rowStart[i]) rowIdx.push_back(i);\n    int R = (int)rowIdx.size();\n    vector<int> tallest(R);\n    for(int rr=0; rr<R; ++rr){\n        int st=rowIdx[rr], ed=(rr+1<R?rowIdx[rr+1]:N);\n        int64 bestH=-1;\n        for(int i=st;i<ed;++i){\n            int64 h = lay.orient[i]?r[i].w:r[i].h;\n            if(h>bestH){ bestH=h; tallest[rr]=i; }\n        }\n    }\n\n    vector<Cmd> out(N);\n    for(int i=0;i<N;++i){\n        Cmd c; c.p=i; c.r=lay.orient[i];\n        bool first = lay.rowStart[i];\n        int rr = (int)(upper_bound(rowIdx.begin(),rowIdx.end(),i) - rowIdx.begin()) -1;\n        if(rr==0 && first){\n            c.d='U'; c.b=-1;\n        }else if(first){\n            c.d='L'; c.b=tallest[rr-1];\n        }else{\n            c.d='U'; c.b=i-1;\n        }\n        out[i]=c;\n    }\n    return out;\n}\n\n/*------------------------------------------------------------------*/\n/*  main                                                             */\n/*------------------------------------------------------------------*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N,T,sigma;\n    if(!(cin>>N>>T>>sigma)) return 0;\n    vector<Rec> rec(N);\n    for(int i=0;i<N;++i) cin>>rec[i].w>>rec[i].h;\n\n    /* ---------- initial heuristic width limit ----------------------- */\n    long double totArea=0;\n    for(auto &rc:rec) totArea += (long double)rc.w*rc.h;\n    double wideal = sqrt((double)totArea);\n    Layout best = greedy_initial(rec,wideal);\n\n    /* ---------- simulated annealing / hill-climb -------------------- */\n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(1800);\n    best = improveSA(rec,best,deadline);\n\n    /* ---------- produce one fixed answer ---------------------------- */\n    auto cmds = build_commands(rec,best);\n\n    for(int turn=0; turn<T; ++turn){\n        cout<<N<<'\\n';\n        for(auto &c:cmds) cout<<c.p<<' '<<int(c.r)<<' '<<c.d<<' '<<c.b<<'\\n';\n        cout<<flush;\n\n        long long dummyW, dummyH;\n        if(!(cin>>dummyW>>dummyH)) return 0;     // just consume\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int H      = 10;           // depth limit\nconstexpr int UNASS  = -2;\nconstexpr int VARS   = 9;            // number of root-selection formulas\n\n/* ------------------------------------------------------------------ */\ninline double score_function(int variant,\n                             int Av,\n                             long long sumB,\n                             int cnt) {\n    switch (variant) {\n        case 0: return double(Av);\n        case 1: return double(Av) * Av;\n        case 2: return double(Av)       / double(sumB);\n        case 3: return double(Av) * Av  / double(sumB);\n        case 4: return double(Av) * Av * Av / double(sumB);\n        case 5: return double(Av)       / double(cnt);\n        case 6: return double(Av) * Av  / double(cnt);\n        case 7: return 1.0 / double(sumB);\n        case 8: return 1.0 / double(cnt);\n    }\n    return 1e100;                      // should never reach here\n}\n\n/* build a forest with a chosen variant; returns attractiveness */\nlong long build_forest(const vector<vector<int>>& g,\n                       const vector<vector<int>>& reach10,\n                       const vector<int>& A,\n                       int variant,\n                       vector<int>& parent_out)\n{\n    const int N = A.size();\n    vector<char> covered(N, 0);\n    vector<int>  depth  (N, -1);\n    vector<int>  parent (N, UNASS);\n    int uncovered = N;\n\n    queue<int> q;\n\n    while (uncovered) {\n        /* pick the vertex with the minimum score */\n        double bestScore = 1e100;\n        int    bestRoot  = -1;\n\n        for (int v = 0; v < N; ++v) if (!covered[v]) {\n            long long sumB = 0;\n            int cnt = 0;\n            for (int u : reach10[v])\n                if (!covered[u]) { sumB += A[u]; ++cnt; }\n\n            double sc = score_function(variant, A[v], sumB, cnt);\n            if (sc < bestScore) { bestScore = sc; bestRoot = v; }\n        }\n\n        /* grow a BFS tree from bestRoot (depth limited to 10) */\n        covered[bestRoot] = 1; --uncovered;\n        parent[bestRoot]  = -1;\n        depth [bestRoot]  = 0;\n        while (!q.empty()) q.pop();\n        q.push(bestRoot);\n\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (depth[v] == H) continue;\n            for (int nb : g[v]) if (!covered[nb]) {\n                covered[nb] = 1; --uncovered;\n                parent[nb]  = v;\n                depth [nb]  = depth[v] + 1;\n                q.push(nb);\n            }\n        }\n    }\n\n    long long attr = 0;\n    for (int v = 0; v < N; ++v)\n        attr += 1LL * (depth[v] + 1) * A[v];\n\n    parent_out.swap(parent);\n    return attr;\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read input ---------------------------------------------------- */\n    int N, M, H_input;\n    if (!(cin >> N >> M >> H_input)) return 0;   // H_input is always 10\n    vector<int> A(N);\n    for (int &x : A) cin >> x;\n\n    vector<vector<int>> g(N);\n    for (int i = 0, u, v; i < M; ++i) {\n        cin >> u >> v;\n        g[u].push_back(v);\n        g[v].push_back(u);\n    }\n    /* coordinates are not used by the algorithm */\n    for (int i = 0, xv, yv; i < N; ++i) cin >> xv >> yv;\n\n    /* pre-processing ------------------------------------------------ */\n    for (int v = 0; v < N; ++v)\n        sort(g[v].begin(), g[v].end(),\n             [&](int a, int b){ return A[a] < A[b]; });\n\n    vector<vector<int>> reach10(N);\n    {\n        vector<int> dist(N);\n        queue<int>  q;\n        for (int s = 0; s < N; ++s) {\n            fill(dist.begin(), dist.end(), -1);\n            dist[s] = 0;\n            q.push(s);\n            reach10[s].push_back(s);\n            while (!q.empty()) {\n                int v = q.front(); q.pop();\n                if (dist[v] == H) continue;\n                for (int nb : g[v]) if (dist[nb] == -1) {\n                    dist[nb] = dist[v] + 1;\n                    reach10[s].push_back(nb);\n                    q.push(nb);\n                }\n            }\n        }\n    }\n\n    /* try several variants and take the best ----------------------- */\n    long long bestAttr = -1;\n    vector<int> bestParent;\n\n    for (int var = 0; var < VARS; ++var) {\n        vector<int> parent;\n        long long attr = build_forest(g, reach10, A, var, parent);\n        if (attr > bestAttr) {\n            bestAttr   = attr;\n            bestParent = std::move(parent);\n        }\n    }\n\n    /* output -------------------------------------------------------- */\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << bestParent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Option { int gid, dist; };              // candidate move for one Oni\nstruct Op     { char dir; int idx; };\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ------------------------------------------------ */\n    int N;                                     // 20 in every test\n    if (!(cin >> N)) return 0;\n    vector<string> G(N);\n    for (auto &s: G) cin >> s;\n\n    /* ---------- small helpers -------------------------------------------- */\n    auto clear_up    =[&](int r,int c){for(int i=0;i< r   ;++i) if(G[i][c]=='o') return false; return true;};\n    auto clear_down  =[&](int r,int c){for(int i=r+1;i<N  ;++i) if(G[i][c]=='o') return false; return true;};\n    auto clear_left  =[&](int r,int c){for(int j=0;j< c   ;++j) if(G[r][j]=='o') return false; return true;};\n    auto clear_right =[&](int r,int c){for(int j=c+1;j<N  ;++j) if(G[r][j]=='o') return false; return true;};\n\n    /* ---------- enumerate Oni -------------------------------------------- */\n    struct Oni { vector<Option> opt; };\n    vector<Oni> oni; oni.reserve(40);\n\n    for (int r=0;r<N;++r)\n        for (int c=0;c<N;++c) if (G[r][c]=='x') {\n            Oni o;\n            if (clear_up(r,c))    o.opt.push_back({ 0*20+c , r+1 });\n            if (clear_down(r,c))  o.opt.push_back({ 1*20+c , N-r });\n            if (clear_left(r,c))  o.opt.push_back({ 2*20+r , c+1 });\n            if (clear_right(r,c)) o.opt.push_back({ 3*20+r , N-c });\n            oni.push_back(move(o));\n        }\n    const int M = oni.size();                 // always 40\n    const int Gcnt = 80;                      // 4*20 groups\n\n    /* ---------- dist table ------------------------------------------------ */\n    vector<array<int,Gcnt>> dist(M);\n    for (int i=0;i<M;++i){ dist[i].fill(0); for(auto&op:oni[i].opt) dist[i][op.gid]=op.dist; }\n\n    /* ---------- initial assignment : shortest safe dir ------------------- */\n    vector<int> assign(M,-1);                 // gid of each Oni\n    array<vector<int>,Gcnt> members;          // members per group\n    array<int,Gcnt>         gMax{};           // max distance per group\n\n    for (int id=0; id<M; ++id){\n        int bestD=1e9,bestG=-1;\n        for(auto&op:oni[id].opt)\n            if (op.dist<bestD){bestD=op.dist;bestG=op.gid;}\n        assign[id]=bestG;\n        members[bestG].push_back(id);\n        gMax[bestG]=max(gMax[bestG],bestD);\n    }\n\n    /* ---------- tiny hill-climber (same as before) ----------------------- */\n    std::mt19937 rng(1234567);\n    bool better=true;\n    while(better){\n        better=false;\n        vector<int> order(M); iota(order.begin(),order.end(),0);\n        shuffle(order.begin(),order.end(),rng);\n\n        for(int id:order){\n            int g0=assign[id], d0=dist[id][g0], old0=gMax[g0];\n            int new0;\n            if (d0<old0) new0=old0;\n            else{\n                new0=0;\n                for(int o:members[g0]) if(o!=id) new0=max(new0,dist[o][g0]);\n            }\n            for(auto&op:oni[id].opt) if(op.gid!=g0){\n                int g1=op.gid, d1=op.dist, old1=gMax[g1];\n                int new1=max(old1,d1);\n                if (2*(new0-old0)+2*(new1-old1)<0){\n                    /* apply move */\n                    auto &v=members[g0];\n                    v.erase(remove(v.begin(),v.end(),id),v.end());\n                    gMax[g0]=new0;\n                    members[g1].push_back(id);\n                    gMax[g1]=new1;\n                    assign[id]=g1;\n                    better=true;\n                    break;\n                }\n            }\n        }\n    }\n\n    /* ---------- pick the no-return group --------------------------------- */\n    int lastG=-1, lastD=-1;\n    for(int g=0;g<Gcnt;++g) if(gMax[g]>lastD){lastD=gMax[g]; lastG=g;}\n\n    /* ---------- prepare operation list ----------------------------------- */\n    const char OUT[4]={'U','D','L','R'};\n    const char REV[4]={'D','U','R','L'};\n    vector<Op> ops; ops.reserve(1600);\n\n    auto emit=[&](char d,int idx,int cnt){ for(int k=0;k<cnt;++k) ops.push_back({d,idx}); };\n\n    /* 1. all normal groups (out + back) */\n    for(int g=0; g<Gcnt; ++g) if(g!=lastG && gMax[g]){\n        int dir=g/20, line=g%20, d=gMax[g];\n        emit(OUT[dir],line,d);\n        emit(REV[dir],line,d);\n    }\n\n    /* 2. final group (out only) */\n    if(lastD>0){\n        int dir=lastG/20, line=lastG%20;\n        emit(OUT[dir],line,lastD);\n    }\n\n    /* ---------- safety guard (theory says ops \u2264 1 599) ------------------- */\n    const int LIMIT = 4*N*N;                 // 1 600\n    if((int)ops.size()>LIMIT) ops.resize(LIMIT);\n\n    /* ---------- output --------------------------------------------------- */\n    for(auto&o:ops) cout<<o.dir<<' '<<o.idx<<'\\n';\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconstexpr int N      = 100;\nconstexpr int L      = 500'000;\nconstexpr int EDGES  = 2 * N;          // 200\nconstexpr int STEP   = L / EDGES;      // 2500\n\n/* ------------------------------------------------------------------ */\n/*  exact DP for optimal rounding                                      */\nvector<int> optimal_indeg(const array<int,N>& T) {\n    const int INF = 1e9;\n    static int dp[N + 1][EDGES + 1];\n    static uint8_t prevk[N + 1][EDGES + 1];\n\n    for (int s = 0; s <= EDGES; ++s) dp[0][s] = INF;\n    dp[0][0] = 0;\n\n    for (int i = 0; i < N; ++i) {\n        for (int s = 0; s <= EDGES; ++s) dp[i + 1][s] = INF;\n        for (int s = 0; s <= EDGES; ++s) if (dp[i][s] != INF) {\n            for (int k = 0; k <= 4 && s + k <= EDGES; ++k) {\n                int v = dp[i][s] + abs(T[i] - STEP * k);\n                if (v < dp[i + 1][s + k]) {\n                    dp[i + 1][s + k] = v;\n                    prevk[i + 1][s + k] = k;\n                }\n            }\n        }\n    }\n    vector<int> k(N);\n    int s = EDGES;\n    for (int i = N; i--;) {\n        k[i] = prevk[i + 1][s];\n        s -= k[i];\n    }\n\n    /* each positive-target employee must have \u22651 incoming edge */\n    for (int i = 0; i < N; ++i) if (T[i] > 0 && k[i] == 0) {\n        int best = -1, bestCost = INT_MAX;\n        for (int j = 0; j < N; ++j) if (k[j] > 1) {\n            int cost = abs(T[j] - STEP * (k[j] - 1)) - abs(T[j] - STEP * k[j]);\n            if (cost < bestCost) { bestCost = cost; best = j; }\n        }\n        --k[best]; ++k[i];\n    }\n    return k;\n}\n\n/* ------------------------------------------------------------------ */\n/*  simulate 500 000 weeks                                             */\ninline ll simulate(const array<int,EDGES>& dest,\n                   const array<int,N>& T,\n                   array<int,N>& cnt) {\n    cnt.fill(0);\n    int cur = 0;\n    for (int w = 0; w < L; ++w) {\n        ++cnt[cur];\n        cur = dest[2 * cur + ((cnt[cur] & 1) ? 0 : 1)];\n    }\n    ll err = 0;\n    for (int i = 0; i < N; ++i) err += llabs(cnt[i] - T[i]);\n    return err;\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyN, dummyL;\n    if (!(cin >> dummyN >> dummyL)) return 0;\n\n    array<int,N> T{};\n    for (int &x : T) cin >> x;\n\n    auto t_start = std::chrono::steady_clock::now();\n\n    /* ---------- choose in-degrees ---------- */\n    vector<int> k = optimal_indeg(T);\n\n    /* ---------- destination multiset ---------- */\n    vector<int> pool; pool.reserve(EDGES);\n    for (int v = 0; v < N; ++v)\n        for (int c = 0; c < k[v]; ++c) pool.push_back(v);\n\n    mt19937 rng((uint32_t)chrono::steady_clock::now()\n                    .time_since_epoch().count());\n\n    array<int,EDGES> bestDest{}, tmpDest{};\n    array<int,N>     cnt{};\n    ll bestErr = (1LL << 60);\n\n    auto eval = [&](array<int,EDGES>& d) {\n        for (int v = 0; v < N; ++v)\n            if (d[2*v] == v && d[2*v+1] == v) return;   // trap, skip\n        ll e = simulate(d, T, cnt);\n        if (e < bestErr) { bestErr = e; bestDest = d; }\n    };\n\n    /* ---------- 40 global shuffles ---------- */\n    for (int g = 0; g < 40; ++g) {\n        shuffle(pool.begin(), pool.end(), rng);\n        for (int i = 0; i < EDGES; ++i) tmpDest[i] = pool[i];\n\n        /* quick repair of double self-loops */\n        for (int v = 0; v < N; ++v)\n            if (tmpDest[2*v] == v && tmpDest[2*v+1] == v) {\n                int idx = -1;\n                for (int e = 0; e < EDGES; ++e) {\n                    int s = e / 2;\n                    if (s != v && tmpDest[e] != s) { idx = e; break; }\n                }\n                if (idx >= 0) swap(tmpDest[2*v+1], tmpDest[idx]);\n            }\n        eval(tmpDest);\n    }\n\n    /* ---------- local hill-climbing ---------- */\n    const int LOCAL_ITERS = 260;      // fits safely in remaining time\n    for (int it = 0; it < LOCAL_ITERS; ++it) {\n        tmpDest = bestDest;\n        if (rng() & 1) {                 // edge swap\n            int e1 = rng() % EDGES, e2;\n            do e2 = rng() % EDGES; while (e2 == e1);\n            swap(tmpDest[e1], tmpDest[e2]);\n            int s1 = e1 / 2, s2 = e2 / 2;\n            if ((tmpDest[2*s1] == s1 && tmpDest[2*s1+1] == s1) ||\n                (tmpDest[2*s2] == s2 && tmpDest[2*s2+1] == s2))\n                continue;                // produced a trap; skip\n        } else {                         // orientation flip\n            int v = rng() % N;\n            swap(tmpDest[2*v], tmpDest[2*v+1]);\n            if (tmpDest[2*v] == v && tmpDest[2*v+1] == v) continue;\n        }\n        eval(tmpDest);\n    }\n\n    /* ---------- output ---------- */\n    for (int v = 0; v < N; ++v)\n        cout << bestDest[2*v] << ' ' << bestDest[2*v+1] << '\\n';\n\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*--------------------------- Hilbert order -----------------------------*/\nstatic inline uint64_t hilbertOrder(int x, int y) {\n    const int B = 14;                     // 2^14 = 16384 > 10000\n    uint64_t d = 0;\n    for (int s = B - 1; s >= 0; --s) {\n        int rx = (x >> s) & 1;\n        int ry = (y >> s) & 1;\n        uint64_t idx = (rx ^ ry) | (ry << 1);     // 0,1,2,3\n        d = (d << 2) | idx;\n        if (!ry) {\n            if (rx) { x = ((1 << B) - 1) - x; y = ((1 << B) - 1) - y; }\n            swap(x, y);\n        }\n    }\n    return d;\n}\nstatic inline int64_t dist2(int x1,int y1,int x2,int y2){\n    int64_t dx=x1-x2, dy=y1-y2; return dx*dx+dy*dy;\n}\n\n/*--------------------------- DSU ---------------------------------------*/\nstruct DSU{\n    vector<int> p, sz;\n    DSU(int n=0){ init(n); }\n    void init(int n){ p.resize(n); sz.assign(n,1); iota(p.begin(),p.end(),0);}\n    int find(int v){ return p[v]==v? v : p[v]=find(p[v]);}\n    bool unite(int a,int b){\n        a=find(a); b=find(b); if(a==b) return false;\n        if(sz[a]<sz[b]) swap(a,b);\n        p[b]=a; sz[a]+=sz[b]; return true;\n    }\n};\n\n/*--------------------------- main --------------------------------------*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* input */\n    int N,M,Q,L,W; cin>>N>>M>>Q>>L>>W;\n    vector<int> G(M); for(int &g:G) cin>>g;\n\n    struct City{ int id,lx,rx,ly,ry,cx,cy; uint64_t hil; };\n    vector<City> city(N);\n    for(int i=0;i<N;++i){\n        int lx,rx,ly,ry; cin>>lx>>rx>>ly>>ry;\n        int cx=(lx+rx)/2, cy=(ly+ry)/2;\n        int sx=(cx*16383)/10000, sy=(cy*16383)/10000;\n        city[i]={i,lx,rx,ly,ry,cx,cy,hilbertOrder(sx,sy)};\n    }\n\n    /* Hilbert sort */\n    vector<int> hilSorted(N); iota(hilSorted.begin(),hilSorted.end(),0);\n    sort(hilSorted.begin(),hilSorted.end(),\n         [&](int a,int b){ return city[a].hil<city[b].hil;});\n\n    /* create groups ---------------------------------------------------- */\n    vector<vector<int>> groups(M);\n    vector<bool> used(N,false);\n\n    /* big groups (>2) first */\n    size_t pos=0;\n    for(int i=0;i<M;++i) if(G[i]>2){\n        groups[i].reserve(G[i]);\n        for(int k=0;k<G[i];++k){ groups[i].push_back(hilSorted[pos]); used[hilSorted[pos]]=true; ++pos; }\n    }\n\n    /* rest of the cities -> singles / pairs */\n    vector<int> rest;\n    for(; pos<hilSorted.size(); ++pos) rest.push_back(hilSorted[pos]);\n\n    int needSingles=0, needPairs=0;\n    for(int g:G){ if(g==1) ++needSingles; else if(g==2) ++needPairs; }\n\n    /* global greedy matching for pairs */\n    vector<pair<int,int>> pairList; pairList.reserve(needPairs);\n    while((int)pairList.size()<needPairs){\n        int a=rest.back(); rest.pop_back();\n        int bestIdx=-1; int64_t best=LLONG_MAX;\n        for(int i=0;i<(int)rest.size();++i){\n            int b=rest[i];\n            int64_t d=dist2(city[a].cx,city[a].cy,city[b].cx,city[b].cy);\n            if(d<best){ best=d; bestIdx=i; }\n        }\n        int b=rest[bestIdx]; rest[bestIdx]=rest.back(); rest.pop_back();\n        pairList.emplace_back(a,b);\n    }\n    vector<int> singles = move(rest);\n    /* fill empty groups */\n    int ptrPair=0, ptrSingle=0;\n    for(int i=0;i<M;++i) if(groups[i].empty()){\n        if(G[i]==1) groups[i]={singles[ptrSingle++]};\n        else        groups[i]={pairList[ptrPair].first, pairList[ptrPair].second}, ++ptrPair;\n    }\n\n    /* container for roads */\n    vector<vector<pair<int,int>>> edges(M);\n    int queries_used=0;\n\n    auto ask_query=[&](const vector<int>& subset, vector<pair<int,int>>& out){\n        int sz=subset.size();\n        cout<<\"? \"<<sz;\n        for(int v:subset) cout<<' '<<v;\n        cout<<'\\n'<<flush;\n        out.reserve(out.size()+sz-1);\n        for(int k=0;k<sz-1;++k){\n            int a,b; cin>>a>>b; out.emplace_back(a,b);\n        }\n    };\n\n    /* ---------- pass 1 : groups with size 3..L ----------------------- */\n    for(int i=0;i<M;++i){\n        int sz=groups[i].size();\n        if(sz<3 || sz>L) continue;\n        ask_query(groups[i], edges[i]);\n        ++queries_used;\n    }\n\n    /* ---------- pass 2 : small trivial groups (size 1 / 2) ----------- */\n    for(int i=0;i<M;++i){\n        int sz=groups[i].size();\n        if(sz==1) continue;\n        if(sz==2) edges[i]={{groups[i][0],groups[i][1]}};\n    }\n\n    /* queries left for big groups */\n    int queries_left = Q - queries_used;\n\n    /* quick helper: mapping city id -> local index */\n    vector<int> id2idx(N);\n\n    /* ---------- pass 3 : groups with size > L ------------------------ */\n    for(int gi=0; gi<M; ++gi){\n        int k=groups[gi].size();\n        if(k<=L) continue;                    // already handled\n\n        /* how many queries would we need for disjoint blocks */\n        int blockCnt = (k + L - 1) / L;\n        bool useQueries = (blockCnt*2 <= queries_left);   // keep a margin\n\n        if(useQueries){\n            /* split into blockCnt blocks, all sizes between 2 and L */\n            vector<int> &g = groups[gi];\n            vector<vector<int>> blocks;\n            blocks.reserve(blockCnt);\n\n            /* distribute sizes almost evenly, always \u22652 */\n            vector<int> blkSize(blockCnt, k / blockCnt);\n            for(int i=0;i<k%blockCnt;++i) ++blkSize[i];\n            for(int i=0;i<blockCnt;++i) if(blkSize[i]==1){\n                for(int j=0;j<blockCnt;++j) if(blkSize[j]>2){\n                    --blkSize[j]; ++blkSize[i]; break;\n                }\n            }\n            /* build blocks */\n            int p=0;\n            for(int s:blkSize){\n                blocks.emplace_back(g.begin()+p, g.begin()+p+s);\n                p+=s;\n            }\n\n            /* query each block -------------------------------------- */\n            for(auto &blk:blocks){\n                ask_query(blk, edges[gi]);\n                ++queries_used; --queries_left;\n            }\n\n            /* connect the blocks with centre-distance Kruskal ------- */\n            /* mapping id -> local */\n            for(int j=0;j<k;++j) id2idx[g[j]]=j;\n            DSU dsu(k);\n            for(auto [a,b]:edges[gi]) dsu.unite(id2idx[a], id2idx[b]);\n\n            struct Edge{ int a,b; int64_t d; };\n            vector<Edge> cand; cand.reserve(k*(k-1)/2);\n            for(int i=0;i<k;++i){\n                for(int j=i+1;j<k;++j){\n                    if(dsu.find(i)==dsu.find(j)) continue;\n                    cand.push_back({g[i],g[j],\n                                    dist2(city[g[i]].cx,city[g[i]].cy,\n                                          city[g[j]].cx,city[g[j]].cy)});\n                }\n            }\n            sort(cand.begin(),cand.end(),[](const Edge&x,const Edge&y){return x.d<y.d;});\n            for(auto &e:cand){\n                if(edges[gi].size()==k-1) break;\n                if(dsu.unite(id2idx[e.a], id2idx[e.b]))\n                    edges[gi].push_back({e.a,e.b});\n            }\n        }\n        /* not enough queries left: fall back to centre MST ---------- */\n        if(edges[gi].empty()){           // nothing built yet\n            /* Prim on centre distances */\n            vector<int> &g = groups[gi];\n            const int INF = 1e9;\n            vector<int64_t> best(k,LLONG_MAX);\n            vector<int> parent(k,-1); vector<char> usedP(k,0);\n            best[0]=0;\n            for(int step=0;step<k;++step){\n                int v=-1; int64_t bd=LLONG_MAX;\n                for(int i=0;i<k;++i) if(!usedP[i] && best[i]<bd){bd=best[i]; v=i;}\n                usedP[v]=1;\n                if(parent[v]!=-1) edges[gi].push_back({g[v], g[parent[v]]});\n                for(int u=0;u<k;++u) if(!usedP[u]){\n                    int64_t d = dist2(city[g[v]].cx,city[g[v]].cy,\n                                       city[g[u]].cx,city[g[u]].cy);\n                    if(d<best[u]){ best[u]=d; parent[u]=v; }\n                }\n            }\n        }\n    }\n\n    /* ----------- sanity (optional) ---------------------------------- */\n#ifndef NDEBUG\n    for(int i=0;i<M;++i){\n        assert((int)edges[i].size()==(int)groups[i].size()-1);\n    }\n#endif\n\n    /* ----------------- final output --------------------------------- */\n    cout<<\"!\\n\";\n    for(int i=0;i<M;++i){\n        for(size_t j=0;j<groups[i].size();++j){\n            if(j) cout<<' ';\n            cout<<groups[i][j];\n        }\n        cout<<'\\n';\n        for(auto [a,b]:edges[i]) cout<<a<<' '<<b<<'\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Step {\n    char act; // 'M' or 'S'\n    char dir; // 'U','D','L','R'\n};\nconst int N = 20;\nconst int SZ = N * N;\nconst int dx[4] = {-1, 1, 0, 0};\nconst int dy[4] = {0, 0, -1, 1};\nconst char DIRC[4] = {'U', 'D', 'L', 'R'};\n\ninline int id(int r, int c) { return r * N + c; }\ninline pair<int,int> rc(int v){ return {v / N, v % N}; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;\n    vector<int> px, py;\n    {\n        int n_in;\n        if(!(cin >> n_in >> M)) return 0; // N is always 20\n        px.resize(M);\n        py.resize(M);\n        for (int k = 0; k < M; ++k) cin >> px[k] >> py[k];\n    }\n\n    vector<Step> answer;\n    vector<int> dist(SZ);\n    vector<int> prevv(SZ);\n    vector<char> preva(SZ);\n    vector<char> prevd(SZ);\n    deque<int> q;\n\n    int cur = id(px[0], py[0]);\n    for (int tgtIdx = 1; tgtIdx < M; ++tgtIdx) {\n        int goal = id(px[tgtIdx], py[tgtIdx]);\n\n        // BFS\n        fill(dist.begin(), dist.end(), -1);\n        q.clear();\n        dist[cur] = 0;\n        q.push_back(cur);\n\n        while (!q.empty()) {\n            int v = q.front(); q.pop_front();\n            if (v == goal) break;\n            auto [r, c] = rc(v);\n            for (int d = 0; d < 4; ++d) {\n                // Move\n                int nr = r + dx[d], nc = c + dy[d];\n                if (0 <= nr && nr < N && 0 <= nc && nc < N) {\n                    int nv = id(nr, nc);\n                    if (dist[nv] == -1) {\n                        dist[nv] = dist[v] + 1;\n                        prevv[nv] = v;\n                        preva[nv] = 'M';\n                        prevd[nv] = DIRC[d];\n                        q.push_back(nv);\n                    }\n                }\n                // Slide\n                int sr = r, sc = c;\n                while (true) {\n                    int tr = sr + dx[d], tc = sc + dy[d];\n                    if (tr < 0 || tr >= N || tc < 0 || tc >= N) break;\n                    sr = tr; sc = tc;\n                }\n                int sv = id(sr, sc);\n                if (sv != v && dist[sv] == -1) {\n                    dist[sv] = dist[v] + 1;\n                    prevv[sv] = v;\n                    preva[sv] = 'S';\n                    prevd[sv] = DIRC[d];\n                    q.push_back(sv);\n                }\n            }\n        }\n\n        // Reconstruct path\n        vector<Step> chunk;\n        for (int v = goal; v != cur; v = prevv[v]) {\n            chunk.push_back({preva[v], prevd[v]});\n        }\n        reverse(chunk.begin(), chunk.end());\n        answer.insert(answer.end(), chunk.begin(), chunk.end());\n        cur = goal;\n    }\n\n    // Output\n    for (auto &st : answer) cout << st.act << ' ' << st.dir << '\\n';\n    return 0;\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int LIM = 10000;                 // board size\n\nstruct Rect { int a,b,c,d; };              // [a,c) \u00d7 [b,d)\n\n/* positive-area overlap? -------------------------------------------------*/\ninline bool overlap1d(int l1,int r1,int l2,int r2){\n    return max(l1,l2) < min(r1,r2);\n}\ninline bool intersect(const Rect& A,const Rect& B){\n    return overlap1d(A.a,A.c,B.a,B.c) && overlap1d(A.b,A.d,B.b,B.d);\n}\n\n/* satisfaction -----------------------------------------------------------*/\ninline double sat(long long need,long long have){\n    double mi = static_cast<double>(min(need,have));\n    double ma = static_cast<double>(max(need,have));\n    double t  = 1.0 - mi/ma;\n    return 1.0 - t*t;\n}\n\n/* maximal free expansion distance of rect[i]  --------------------------- */\nint free_delta(const vector<Rect>& R,int i,int side){\n    const Rect &cur = R[i];\n    int d = 0;\n    if(side==0){                               // LEFT  (a decreases)\n        d = cur.a;                             // frame\n        for(size_t j=0;j<R.size();++j) if((int)j!=i)\n            if(overlap1d(cur.b,cur.d,R[j].b,R[j].d) && R[j].c<=cur.a)\n                d = min(d, cur.a - R[j].c);\n    }else if(side==1){                         // RIGHT (c increases)\n        d = LIM - cur.c;\n        for(size_t j=0;j<R.size();++j) if((int)j!=i)\n            if(overlap1d(cur.b,cur.d,R[j].b,R[j].d) && R[j].a>=cur.c)\n                d = min(d, R[j].a - cur.c);\n    }else if(side==2){                         // DOWN  (b decreases)\n        d = cur.b;\n        for(size_t j=0;j<R.size();++j) if((int)j!=i)\n            if(overlap1d(cur.a,cur.c,R[j].a,R[j].c) && R[j].d<=cur.b)\n                d = min(d, cur.b - R[j].d);\n    }else{                                     // UP    (d increases)\n        d = LIM - cur.d;\n        for(size_t j=0;j<R.size();++j) if((int)j!=i)\n            if(overlap1d(cur.a,cur.c,R[j].a,R[j].c) && R[j].b>=cur.d)\n                d = min(d, R[j].b - cur.d);\n    }\n    return d;\n}\n\n/* ----------------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int 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    /* ----------- initial 1\u00d71 rectangles --------------------------------*/\n    vector<Rect>        rect(n);\n    vector<long long>   area(n,1);\n    vector<double>      p(n);\n    double score=0;\n    for(int i=0;i<n;++i){\n        rect[i]={x[i],y[i],x[i]+1,y[i]+1};\n        p[i]=sat(r[i],1); score+=p[i];\n    }\n    double bestScore=score;\n    auto bestRect = rect; auto bestArea=area; auto bestP=p;\n\n    /* -------- simulated annealing -------------------------------------*/\n    mt19937 rng((uint32_t)chrono::steady_clock::now()\n                   .time_since_epoch().count());\n    uniform_real_distribution<double> urd(0,1);\n    const double TL=4.9, T0=5e-2, T1=1e-4;\n    auto t0=chrono::steady_clock::now();\n\n    while(true){\n        double t=chrono::duration<double>(chrono::steady_clock::now()-t0).count();\n        if(t>TL) break;\n        double temp=T0+(T1-T0)*(t/TL);\n\n        int i=rng()%n;\n        Rect cur=rect[i], neu=cur;\n        long long diff=r[i]-area[i];\n\n        if(urd(rng)<0.25){                      /* translation move */\n            int dxMin=max(-cur.a, (x[i]+1)-cur.c);\n            int dxMax=min(LIM-cur.c,  x[i]-cur.a);\n            int dyMin=max(-cur.b, (y[i]+1)-cur.d);\n            int dyMax=min(LIM-cur.d,  y[i]-cur.b);\n            if(dxMin>dxMax || dyMin>dyMax) continue;\n            int dx=dxMin + rng()%(dxMax-dxMin+1);\n            int dy=dyMin + rng()%(dyMax-dyMin+1);\n            if(dx==0 && dy==0) continue;\n            neu.a+=dx; neu.c+=dx; neu.b+=dy; neu.d+=dy;\n            bool ok=true;\n            for(int j=0;j<n && ok;++j) if(j!=i) ok=!intersect(neu,rect[j]);\n            if(!ok) continue;\n            rect[i]=neu;                        // area & score unchanged\n            continue;\n        }\n\n        /* one-sided grow / shrink ------------------------------------- */\n        bool wantExpand=diff>0;\n        bool expand=wantExpand;\n        if(urd(rng)<0.20) expand=!expand;\n        int dir=rng()&3;\n        int deltaMax;\n        if(dir==0)      deltaMax = expand?cur.a\n                                         :min(cur.c-cur.a-1, x[i]-cur.a);\n        else if(dir==1) deltaMax = expand?LIM-cur.c\n                                         :min(cur.c-cur.a-1, cur.c-(x[i]+1));\n        else if(dir==2) deltaMax = expand?cur.b\n                                         :min(cur.d-cur.b-1, y[i]-cur.b);\n        else            deltaMax = expand?LIM-cur.d\n                                         :min(cur.d-cur.b-1, cur.d-(y[i]+1));\n        if(deltaMax<=0) continue;\n\n        int w=cur.c-cur.a, h=cur.d-cur.b, per=(dir<=1?h:w);\n        int delta = expand ? min<int>(deltaMax, max<long long>(1,(llabs(diff)+per-1)/per))\n                           : 1 + rng()%deltaMax;\n\n        if(expand){\n            if(dir==0) neu.a-=delta; if(dir==1) neu.c+=delta;\n            if(dir==2) neu.b-=delta; if(dir==3) neu.d+=delta;\n        }else{\n            if(dir==0) neu.a+=delta; if(dir==1) neu.c-=delta;\n            if(dir==2) neu.b+=delta; if(dir==3) neu.d-=delta;\n        }\n\n        bool ok=true;\n        for(int j=0;j<n && ok;++j) if(j!=i) ok=!intersect(neu,rect[j]);\n        if(!ok) continue;\n\n        long long newArea=1LL*(neu.c-neu.a)*(neu.d-neu.b);\n        double newP=sat(r[i],newArea);\n        double dS=newP-p[i];\n\n        if(dS>=0 || urd(rng)<exp(dS/temp)){\n            rect[i]=neu; area[i]=newArea; p[i]=newP; score+=dS;\n            if(score>bestScore){\n                bestScore=score; bestRect=rect; bestArea=area; bestP=p;\n            }\n        }\n    }\n\n    /* ------------ deterministic post-processing -----------------------*/\n    auto grow_pass=[&](){\n        bool changed=false;\n        for(int i=0;i<n;++i){\n            if(bestArea[i]>=r[i]) continue;\n            while(bestArea[i]<r[i]){\n                Rect cur=bestRect[i]; int w=cur.c-cur.a, h=cur.d-cur.b;\n                long long need=r[i]-bestArea[i];\n                int bestSide=-1, bestDelta=0; long long bestGain=0;\n                for(int side=0;side<4;++side){\n                    int per=(side<=1?h:w);\n                    if(per==0) continue;\n                    int fd=free_delta(bestRect,i,side);\n                    if(fd<=0) continue;\n                    int delta=min<int>(fd, (need+per-1)/per);\n                    if(delta<=0) continue;\n                    long long gain=1LL*delta*per;\n                    if(gain>bestGain){\n                        bestGain=gain; bestSide=side; bestDelta=delta;\n                    }\n                }\n                if(bestSide==-1) break;\n                switch(bestSide){\n                    case 0: bestRect[i].a-=bestDelta; break;\n                    case 1: bestRect[i].c+=bestDelta; break;\n                    case 2: bestRect[i].b-=bestDelta; break;\n                    case 3: bestRect[i].d+=bestDelta; break;\n                }\n                bestArea[i]+=bestGain; changed=true;\n            }\n            bestP[i]=sat(r[i],bestArea[i]);\n        }\n        return changed;\n    };\n\n    /* 1) shrink too-large rectangles (old step) ------------------------ */\n    for(int i=0;i<n;++i){\n        while(bestArea[i]>r[i]){\n            Rect cur=bestRect[i]; int w=cur.c-cur.a, h=cur.d-cur.b;\n            long long diff=bestArea[i]-r[i];\n            struct S{int side,per,lim;};\n            array<S,4> c{{\n                {0,h, x[i]-cur.a},\n                {1,h, cur.c-(x[i]+1)},\n                {2,w, y[i]-cur.b},\n                {3,w, cur.d-(y[i]+1)}\n            }};\n            int bs=-1,bd=0; long long br=LLONG_MAX;\n            for(auto s:c){\n                if(s.lim<=0) continue;\n                int delta=min<int>(s.lim,(diff+s.per-1)/s.per);\n                long long resid=llabs(diff-1LL*delta*s.per);\n                if(resid<br){ br=resid; bs=s.side; bd=delta; }\n            }\n            if(bs==-1) break;\n            switch(bs){\n                case 0: bestRect[i].a+=bd; break;\n                case 1: bestRect[i].c-=bd; break;\n                case 2: bestRect[i].b+=bd; break;\n                case 3: bestRect[i].d-=bd; break;\n            }\n            bestArea[i]-=1LL*bd*(bs<=1?h:w);\n        }\n        bestP[i]=sat(r[i],bestArea[i]);\n    }\n\n    /* 2) grow small rectangles,  repeate twice to exploit new space ---- */\n    grow_pass();\n    grow_pass();            // second time often still helps a bit\n\n    /* 3) final shrink if we barely overshot during growing ------------- */\n    for(int i=0;i<n;++i){\n        if(bestArea[i]>r[i]){\n            Rect cur=bestRect[i]; int w=cur.c-cur.a, h=cur.d-cur.b;\n            long long diff=bestArea[i]-r[i];\n            struct S{int side,per,lim;};\n            array<S,4> c{{\n                {0,h, x[i]-cur.a},\n                {1,h, cur.c-(x[i]+1)},\n                {2,w, y[i]-cur.b},\n                {3,w, cur.d-(y[i]+1)}\n            }};\n            for(auto s:c){\n                if(diff==0) break;\n                if(s.lim<=0) continue;\n                int delta=min<long long>(s.lim,diff/s.per);\n                if(delta<=0) continue;\n                switch(s.side){\n                    case 0: bestRect[i].a+=delta; break;\n                    case 1: bestRect[i].c-=delta; break;\n                    case 2: bestRect[i].b+=delta; break;\n                    case 3: bestRect[i].d-=delta; break;\n                }\n                bestArea[i]-=1LL*delta*s.per;\n                diff-=1LL*delta*s.per;\n            }\n            bestP[i]=sat(r[i],bestArea[i]);\n        }\n    }\n\n    /* ------------- output -------------------------------------------- */\n    for(const auto &re: bestRect)\n        cout<<re.a<<' '<<re.b<<' '<<re.c<<' '<<re.d<<\"\\n\";\n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** fast RNG : xoroshiro128+ ***********************************************/\nstruct Xoroshiro {\n    using ull = unsigned long long;\n    ull s[2];\n    static ull rotl(ull x,int k){ return (x<<k)|(x>>(64-k)); }\n    static ull splitmix64(ull &x){ ull z=(x+=0x9e3779b97f4a7c15ULL);\n      z=(z^(z>>30))*0xbf58476d1ce4e5b9ULL; z=(z^(z>>27))*0x94d049bb133111ebULL;\n      return z^(z>>31); }\n    explicit Xoroshiro(ull seed){\n        ull x=seed?seed:0xfeedbeefcafef00dULL;\n        s[0]=splitmix64(x); s[1]=splitmix64(x);\n    }\n    ull next(){ ull r=s[0]+s[1]; ull x=s[0]; ull y=s[1];\n      s[1]^=x; s[0]=rotl(x,24)^y^(y<<16); s[1]=rotl(y,37); return r; }\n    int randint(int n){ return int(next()%n); }\n    double real01(){ return (next()>>11)*(1.0/9007199254740992.0); } // /2^53\n};\n\n/*** problem constants ******************************************************/\nconstexpr int H=50, W=50, DIR=4;\nconst int dr[DIR]={-1,1,0,0};\nconst int dc[DIR]={0,0,-1,1};\nconst char dch[DIR]={'U','D','L','R'};\ninline int cid(int r,int c){ return r*W+c; }\n\n/*** input data *************************************************************/\nint si,sj;\nint tile[H][W];\nint v   [H][W];\nint lost[H][W];                     // value of the other cell in the same tile\nint M;                              // number of tiles\narray<int,DIR> diffNbr[H*W];\n\n/*** utilities **************************************************************/\ninline int deg_after(int cellId,const vector<char>& vis,int tSelf){\n    int d=0;\n    for(int k=0;k<DIR;++k){\n        int nb = diffNbr[cellId][k];\n        if(nb==-1) continue;\n        int t = tile[nb/W][nb%W];\n        if(t==tSelf || vis[t]) continue;\n        ++d;\n    }\n    return d;\n}\n\n/*** one complete walk ******************************************************/\nstruct Walk{ long long score; string path; };\n\nWalk make_walk(Xoroshiro& rng, vector<char>& vis){\n    /* ----- choose parameter style for this run -------------------------- */\n    int style = rng.randint(3);      // 0 / 1 / 2\n    int lambda = (style==0?  (rng.randint(31)+10)   :   // 10 \u2026 40\n                 style==1? -(rng.randint(31)+10)    :   // \u201340 \u2026 \u201310\n                           (rng.randint(41)+40) );      // 40 \u2026 80\n    bool use2ply = rng.randint(6)==0;                       // \u224816 %\n    double alpha = 0.25 * (1.0 + 0.5*rng.real01());         // 0.25 \u2026 0.375\n    double beta  = 0.5  + 0.3*rng.real01();                 // 0.5 \u2026 0.8\n\n    fill(vis.begin(), vis.end(), 0);\n    string path; path.reserve(H*W);\n\n    int r=si, c=sj;\n    vis[ tile[r][c] ] = 1;\n    long long score = v[r][c];\n\n    int order[DIR];\n    auto shuffle4 = [&](int* a){\n        a[0]=0;a[1]=1;a[2]=2;a[3]=3;\n        for(int i=3;i>0;--i) swap(a[i],a[rng.randint(i+1)]);\n    };\n\n    const int earlyDeadEndLimit = 200;\n\n    while(true){\n        int bestDir=-1;\n        double bestEval=-1e100;\n        shuffle4(order);\n\n        int curId = cid(r,c);\n        int walkLen = (int)path.size()+1;\n\n        for(int kk=0; kk<DIR; ++kk){\n            int d = order[kk];\n            int nid = diffNbr[curId][d];\n            if(nid==-1) continue;\n\n            int nr=nid/W, nc=nid%W, tId = tile[nr][nc];\n            if(vis[tId]) continue;\n\n            int deg1 = deg_after(nid, vis, tId);\n            if(deg1==0 && walkLen<earlyDeadEndLimit) continue;\n\n            double eval = v[nr][nc] - alpha*lost[nr][nc] + lambda*deg1;\n\n            if(use2ply){\n                double best2=-1e100;\n                for(int d2=0; d2<DIR; ++d2){\n                    int nnid = diffNbr[nid][d2];\n                    if(nnid==-1) continue;\n                    int rr=nnid/W, cc=nnid%W, tt = tile[rr][cc];\n                    if(tt==tId || vis[tt]) continue;\n\n                    int deg2 = deg_after(nnid, vis, tt);\n                    double e2 = v[rr][cc] - alpha*lost[rr][cc] + lambda*deg2;\n                    best2 = max(best2, e2);\n                }\n                if(best2>-1e90) eval += beta*best2;\n            }\n            eval += rng.randint(3)*1e-3;\n\n            if(eval>bestEval){ bestEval=eval; bestDir=d; }\n        }\n        if(bestDir==-1) break;\n\n        r += dr[bestDir];  c += dc[bestDir];\n        vis[ tile[r][c] ] = 1;\n        score += v[r][c];\n        path.push_back(dch[bestDir]);\n    }\n    return {score, std::move(path)};\n}\n\n/*** main *******************************************************************/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read board ----------------------------------------------------- */\n    cin >> si >> sj;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cin >> tile[i][j];\n    M=0;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) M = max(M, tile[i][j]+1);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cin >> v[i][j];\n\n    /* ---- lost value (value of partner cell in same tile) ---------------- */\n    vector<vector<pair<int,int>>> cells(M);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cells[tile[i][j]].push_back({i,j});\n    for(int t=0;t<M;++t){\n        if(cells[t].size()==2){\n            auto [r1,c1] = cells[t][0];\n            auto [r2,c2] = cells[t][1];\n            lost[r1][c1] = v[r2][c2];\n            lost[r2][c2] = v[r1][c1];\n        }else{\n            for(auto [r,c]:cells[t]) lost[r][c]=0;\n        }\n    }\n\n    /* ---- neighbours with different tile -------------------------------- */\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        for(int d=0;d<DIR;++d){\n            int ni=i+dr[d], nj=j+dc[d];\n            diffNbr[cid(i,j)][d] =\n                (ni<0||nj<0||ni>=H||nj>=W||tile[ni][nj]==tile[i][j])\n                ? -1 : cid(ni,nj);\n        }\n    }\n\n    /* ---- iterative multi-start search ---------------------------------- */\n    Xoroshiro rng( chrono::high_resolution_clock::now()\n                  .time_since_epoch().count() );\n    vector<char> visited(M,0);\n    long long   bestScore=-1;\n    string      bestPath;\n\n    auto T_end = chrono::steady_clock::now() + chrono::milliseconds(1950);\n\n    while(chrono::steady_clock::now() < T_end){\n        auto w = make_walk(rng, visited);\n        if(w.score > bestScore){\n            bestScore = w.score;\n            bestPath.swap(w.path);\n        }\n    }\n\n    cout << bestPath << '\\n';\n    return 0;\n}","ahc003":"/*****************************************************************************\n *  AHC003 \u2013 learner with local neighbour diffusion                          *\n *                                                                           *\n *  compile:  g++ -std=c++20 -O2 -pipe -static -s main.cpp                   *\n *****************************************************************************/\n#include <bits/stdc++.h>\nusing namespace std;\n\n/*** -------- fixed grid description ------------------------------------- ***/\nconstexpr int H = 30, W = 30;\nconstexpr int HOR = H * (W - 1);          // #horizontal edges\nconstexpr int VER = (H - 1) * W;          // #vertical   edges\nconstexpr int E   = HOR + VER;            // 1740 edges in total\n\nint  horId[H][W-1];\nint  verId[H-1][W];\n\nstruct Edge { int to, id; };\narray<array<array<Edge,4>, W>, H> adj;\n\nvoid build_graph() {\n    int id = 0;\n    for(int i=0;i<H;i++) for(int j=0;j<W-1;j++) horId[i][j]=id++;\n    for(int i=0;i<H-1;i++) for(int j=0;j<W  ;j++) verId[i][j]=id++;\n    for(auto &row:adj) for(auto &col:row) for(auto &e:col) e.id=-1;\n\n    for(int i=0;i<H;i++) for(int j=0;j<W;j++){\n        if(i)          adj[i][j][0]={ (i-1)*W+j , verId[i-1][j] };\n        if(i+1<H)      adj[i][j][1]={ (i+1)*W+j , verId[i][j]   };\n        if(j)          adj[i][j][2]={  i*W+j-1  , horId[i][j-1] };\n        if(j+1<W)      adj[i][j][3]={  i*W+j+1  , horId[i][j]   };\n    }\n}\n\n/*** -------- model ------------------------------------------------------- ***/\nconstexpr double INIT_W = 5000.0, MIN_W = 100.0, MAX_W = 20000.0;\narray<double,E> w;\narray<int   ,E> cnt;\n\n/*** -------- random helpers --------------------------------------------- ***/\nmt19937 rng((uint64_t)chrono::high_resolution_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> unif01(0.0,1.0);\ninline double rand_pm(double amp){ return (unif01(rng)*2.0-1.0)*amp; }\n\n/*** -------- shortest path ---------------------------------------------- ***/\nstruct Node{ double d; int v; bool operator<(const Node&o)const{return d>o.d;}};\n\nconstexpr double B_EXPLORE = 1200.0;   // optimism during exploration\nconstexpr double B_EXPLOIT0 = 300.0;   // initial optimism during exploitation\nconstexpr double B_EXPLOIT_DECAY = 0.997; // per query decay\nconstexpr double NOISE_A   = 0.80;     // \u00b180 % random shake in exploration\n\nvector<int> dijkstra(int si,int sj,int ti,int tj,bool exploring,int qIdx){\n    array<double,H*W> dist; dist.fill(1e100);\n    array<int   ,H*W> prvV, prvE; prvE.fill(-1);\n    priority_queue<Node> pq;\n    dist[si*W+sj]=0.0; pq.push({0.0,si*W+sj});\n\n    const double B_base = exploring ? B_EXPLORE\n                                    : B_EXPLOIT0*pow(B_EXPLOIT_DECAY,qIdx);\n\n    while(!pq.empty()){\n        auto [d,v]=pq.top(); pq.pop();\n        if(d!=dist[v]) continue;\n        if(v==ti*W+tj) break;\n        int vi=v/W, vj=v%W;\n        for(int k=0;k<4;k++){\n            auto [to,eid]=adj[vi][vj][k];\n            if(eid<0) continue;\n            double ww=w[eid] - B_base/ sqrt(cnt[eid]+1.0);\n            if(exploring) ww *= 1.0 + rand_pm(NOISE_A);\n            ww=max(50.0,ww);\n            double nd=d+ww;\n            if(nd<dist[to]){ dist[to]=nd; prvV[to]=v; prvE[to]=eid; pq.push({nd,to}); }\n        }\n    }\n    vector<int> path;\n    for(int cur=ti*W+tj; cur!=si*W+sj; cur=prvV[cur]) path.push_back(prvE[cur]);\n    reverse(path.begin(),path.end());\n    return path;\n}\n\n/*** -------- build UDLR string ------------------------------------------ ***/\nstring build_path(int si,int sj,const vector<int>& edges){\n    string res; res.reserve(edges.size());\n    int i=si,j=sj;\n    for(int eid:edges){\n        if(eid < HOR){ int r=eid/(W-1), c=eid%(W-1);\n            if(i==r&&j==c){ res+='R'; ++j;} else{ res+='L'; --j; }\n        }else{ int id2=eid-HOR, r=id2/W, c=id2%W;\n            if(i==r&&j==c){ res+='D'; ++i;} else{ res+='U'; --i; }\n        }\n    }\n    return res;\n}\n\n/*** -------- learning ---------------------------------------------------- ***/\nconstexpr int    MUL_PHASE = 200;\nconstexpr double ETA_MUL = 0.6, ETA_ADD = 1.0;\n\nvoid learn_mul(const vector<int>& edges,double ratio){\n    for(int e:edges){\n        double eta=ETA_MUL/sqrt(cnt[e]+1.0);\n        w[e]*=pow(ratio,eta);\n        w[e]=clamp(w[e],MIN_W,MAX_W);\n        ++cnt[e];\n    }\n}\nvoid learn_add(const vector<int>& edges,double diff,double pred){\n    for(int e:edges){\n        double eta=ETA_ADD/sqrt(cnt[e]+1.0);\n        w[e]+=eta*diff*(w[e]/pred);\n        w[e]=clamp(w[e],MIN_W,MAX_W);\n        ++cnt[e];\n    }\n}\n\n/*** -------- local neighbour diffusion ---------------------------------- ***/\nconstexpr int    DIFF_LIMIT = 6;        // apply while edge seen \u2264 6 times\nconstexpr double DIFF_ALPHA = 0.20;     // 20 % towards neighbour mean\n\nvoid neighbour_diffusion(){\n    /* horizontal -------------------------------------------------------- */\n    for(int i=0;i<H;i++){\n        for(int j=0;j<W-1;j++){\n            int id = horId[i][j];\n            if(cnt[id]>DIFF_LIMIT) continue;\n            double s=0; int c=0;\n            if(j && cnt[horId[i][j-1]]){ s+=w[horId[i][j-1]]; ++c; }\n            if(j+1<W-1 && cnt[horId[i][j+1]]){ s+=w[horId[i][j+1]]; ++c; }\n            if(c){\n                double avg=s/c;\n                w[id]=w[id]*(1.0-DIFF_ALPHA)+avg*DIFF_ALPHA;\n            }\n        }\n    }\n    /* vertical ---------------------------------------------------------- */\n    for(int j=0;j<W;j++){\n        for(int i=0;i<H-1;i++){\n            int id = verId[i][j];\n            if(cnt[id]>DIFF_LIMIT) continue;\n            double s=0; int c=0;\n            if(i && cnt[verId[i-1][j]]){ s+=w[verId[i-1][j]]; ++c; }\n            if(i+1<H-1 && cnt[verId[i+1][j]]){ s+=w[verId[i+1][j]]; ++c; }\n            if(c){\n                double avg=s/c;\n                w[id]=w[id]*(1.0-DIFF_ALPHA)+avg*DIFF_ALPHA;\n            }\n        }\n    }\n}\n\n/*** -------- main loop --------------------------------------------------- ***/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    build_graph();\n    w.fill(INIT_W); cnt.fill(0);\n\n    const int    FORCED_EXP = 100;\n    const double P_EXP0 = 0.35, EXP_DEC = 0.995;\n\n    for(int q=0;q<1000;q++){\n        int si,sj,ti,tj; if(!(cin>>si>>sj>>ti>>tj)) return 0;\n\n        bool exploring = (q < FORCED_EXP) ||\n                         (unif01(rng) < P_EXP0*pow(EXP_DEC, q-FORCED_EXP));\n\n        auto edges = dijkstra(si,sj,ti,tj,exploring,q);\n        cout << build_path(si,sj,edges) << '\\n' << flush;\n\n        long long measLL; cin>>measLL; double measured=double(measLL);\n\n        double pred=0; for(int e:edges) pred+=w[e];\n        if(pred<=0) pred=1;\n        double ratio=measured/pred, diff=measured-pred;\n\n        (q < MUL_PHASE) ? learn_mul(edges,ratio)\n                        : learn_add(edges,diff,pred);\n\n        neighbour_diffusion();               // <\u2014 new local smoothing\n    }\n    return 0;\n}","ahc004":"//  g++ -std=c++20 -O2 -pipe -static -s\n#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N  = 20;     // matrix size (fixed)\nconstexpr int CH = 8;      // A..H\nconstexpr int MAXLEN = 12; // max length of s_i\n\nstruct Placement {\n    uint8_t len;                  // length of the string\n    uint16_t cell[MAXLEN];        // linear cell id (0..399)\n    uint8_t  letter[MAXLEN];      // 0..7\n};\nstruct Watch {\n    int sid;          // string id\n    int pid;          // placement id within that string\n    uint8_t letter;   // letter required in this cell by that placement\n};\n\nint c2i(char c){ return c-'A'; }\nchar i2c(int x){ return 'A'+x; }\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;  /* N is fixed 20 */\n    cin >> std::ws;\n    cin.ignore(numeric_limits<streamsize>::max(),' '); // throw away N\n    cin >> M;\n    vector<string> S(M);\n    for(auto& s:S) cin >> s;\n\n    /*------------------------------------------------------------------*\n     * 1. enumerate every placement                                     *\n     *------------------------------------------------------------------*/\n    vector<vector<Placement>> plac(M);\n    vector<vector<char>> active(M);        // 1 = still alive\n    vector<vector<Watch>> watchers(N*N);   // placements touching each cell\n\n    for(int sid=0; sid<M; ++sid){\n        const string& s = S[sid];\n        const int L = (int)s.size();\n        plac[sid].reserve(800);\n        /* horizontal */\n        for(int row=0; row<N; ++row)\n            for(int st=0; st<N; ++st){\n                Placement p; p.len=L;\n                for(int k=0;k<L;++k){\n                    int col=(st+k)%N;\n                    int cell=row*N+col;\n                    p.cell[k]=cell;\n                    p.letter[k]=c2i(s[k]);\n                }\n                int pid=plac[sid].size();\n                plac[sid].push_back(p);\n                for(int k=0;k<L;++k)\n                    watchers[p.cell[k]].push_back({sid,pid,p.letter[k]});\n            }\n        /* vertical */\n        for(int col=0; col<N; ++col)\n            for(int st=0; st<N; ++st){\n                Placement p; p.len=L;\n                for(int k=0;k<L;++k){\n                    int row=(st+k)%N;\n                    int cell=row*N+col;\n                    p.cell[k]=cell;\n                    p.letter[k]=c2i(s[k]);\n                }\n                int pid=plac[sid].size();\n                plac[sid].push_back(p);\n                for(int k=0;k<L;++k)\n                    watchers[p.cell[k]].push_back({sid,pid,p.letter[k]});\n            }\n        active[sid].assign(plac[sid].size(),1);\n    }\n\n    /*------------------------------------------------------------------*\n     * 2. propagation of forced letters                                 *\n     *------------------------------------------------------------------*/\n    vector<int8_t> fixed(N*N,-1); // -1 = unknown, else 0..7\n    bool changed=true;\n    while(changed){\n        changed=false;\n        /* remove placements inconsistent with already fixed letters */\n        for(int sid=0; sid<M; ++sid){\n            auto &v = plac[sid];\n            auto &alive = active[sid];\n            for(int pid=0,sz=v.size(); pid<sz; ++pid){\n                if(!alive[pid]) continue;\n                const Placement& p=v[pid];\n                bool ok=true;\n                for(int k=0;k<p.len && ok;++k){\n                    int c = p.cell[k];\n                    if(fixed[c]!=-1 && fixed[c]!=p.letter[k]) ok=false;\n                }\n                if(!ok){ alive[pid]=0; changed=true; }\n            }\n        }\n        /* fix cells that now have only one possible letter */\n        for(int cell=0; cell<N*N; ++cell){\n            if(fixed[cell]!=-1) continue;\n            uint8_t mask=0;\n            for(const auto& w: watchers[cell])\n                if(active[w.sid][w.pid]) mask |= (1u<<w.letter);\n            if(mask && (mask & (mask-1))==0){           // power of two\n                fixed[cell]=__builtin_ctz(mask);\n                changed=true;\n            }\n        }\n    }\n\n    /*------------------------------------------------------------------*\n     * 3. greedy assignment (strings with fewer choices first)          *\n     *------------------------------------------------------------------*/\n    mt19937 rng(712367); // deterministic, change for randomisation\n    vector<int> aliveCnt(M);\n    for(int i=0;i<M;++i){\n        aliveCnt[i]=accumulate(begin(active[i]),end(active[i]),0);\n    }\n    vector<int> order(M); iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),\n         [&](int a,int b){ return aliveCnt[a]<aliveCnt[b]; });\n\n    for(int sid:order){\n        int bestPid=-1, bestNew=99;\n        for(int pid=0,sz=plac[sid].size(); pid<sz; ++pid){\n            if(!active[sid][pid]) continue;\n            const auto& p = plac[sid][pid];\n            bool ok=true; int newCnt=0;\n            for(int k=0;k<p.len && ok;++k){\n                int c = p.cell[k];\n                if(fixed[c]!=-1 && fixed[c]!=p.letter[k]) ok=false;\n                else if(fixed[c]==-1) ++newCnt;\n            }\n            if(!ok) continue;\n            if(newCnt<bestNew || (newCnt==bestNew && rng()%2)){\n                bestNew=newCnt; bestPid=pid;\n            }\n        }\n        if(bestPid==-1) continue;                 // cannot place this string\n        const auto& p=plac[sid][bestPid];\n        /* fix the cells decided by this placement */\n        for(int k=0;k<p.len;++k){\n            int c=p.cell[k];\n            if(fixed[c]==p.letter[k]) continue;\n            fixed[c]=p.letter[k];\n            /* eliminate incompatible placements touching this cell */\n            for(const auto& w: watchers[c]){\n                if(!active[w.sid][w.pid]) continue;\n                if(w.letter!=fixed[c]){\n                    active[w.sid][w.pid]=0;\n                    --aliveCnt[w.sid];\n                }\n            }\n        }\n    }\n\n    /*------------------------------------------------------------------*\n     * 4. fill remaining unknown cells arbitrarily                      *\n     *------------------------------------------------------------------*/\n    uniform_int_distribution<int> d8(0,7);\n    for(int c=0;c<N*N;++c)\n        if(fixed[c]==-1) fixed[c]=d8(rng);\n\n    /*------------------------------------------------------------------*\n     * 5. output                                                        *\n     *------------------------------------------------------------------*/\n    for(int r=0;r<N;++r){\n        for(int c=0;c<N;++c) cout << i2c(fixed[r*N+c]);\n        cout << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconst int INF = 1e9;\n\n/* timer ------------------------------------------------------------ */\nusing Clock = std::chrono::steady_clock;\nClock::time_point g_start;\ninline bool time_over() {\n    return (Clock::now() - g_start) >\n           std::chrono::milliseconds(2400);          // 2.4 s for local search\n}\n\n/* grid helpers ----------------------------------------------------- */\nconst int di[4]={-1,1,0,0};\nconst int dj[4]={0,0,-1,1};\nconst char dch[4]={'U','D','L','R'};\ninline bool inside(int x,int n){ return 0<=x && x<n; }\n\n/*-------------------- 1. structure with precomputed runs -----------*/\nstruct PreprocessedGrid{\n    int N, NN;\n    vector<char> isRoad, digit;\n    vector<int> rowRunOf, colRunOf;\n    vector<vector<int>> rowRuns, colRuns;\n\n    PreprocessedGrid(int N_, const vector<string>& S): N(N_), NN(N_*N_){\n        isRoad.assign(NN,0); digit.assign(NN,0);\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++)\n            if(S[i][j]!='#'){ isRoad[id(i,j)]=1; digit[id(i,j)]=S[i][j]-'0'; }\n        buildRuns();\n    }\n    int id(int i,int j) const { return i*N+j; }\n    int row(int idx) const { return idx/N; }\n    int col(int idx) const { return idx%N; }\n\n    void buildRuns(){\n        rowRunOf.assign(NN,-1); colRunOf.assign(NN,-1);\n\n        for(int i=0;i<N;i++){\n            for(int j=0;j<N;){\n                if(!isRoad[id(i,j)]){ ++j; continue; }\n                vector<int> cells;\n                while(j<N && isRoad[id(i,j)]){ cells.push_back(id(i,j)); ++j; }\n                int r=rowRuns.size();\n                for(int v:cells) rowRunOf[v]=r;\n                rowRuns.push_back(move(cells));\n            }\n        }\n        for(int j=0;j<N;j++){\n            for(int i=0;i<N;){\n                if(!isRoad[id(i,j)]){ ++i; continue; }\n                vector<int> cells;\n                while(i<N && isRoad[id(i,j)]){ cells.push_back(id(i,j)); ++i; }\n                int c=colRuns.size();\n                for(int v:cells) colRunOf[v]=c;\n                colRuns.push_back(move(cells));\n            }\n        }\n    }\n};\n\n/* Hungarian for rectangular matrices (n<=m, cost >= 0) -------------*/\nvector<int> hungarian(const vector<vector<int>>& a){\n    int n=a.size(), m=a[0].size(), BIG=1e8;\n    vector<int> u(n+1), v(m+1), p(m+1), way(m+1);\n    for(int i=1;i<=n;i++){\n        p[0]=i; int j0=0;\n        vector<int> minv(m+1,BIG);\n        vector<char> used(m+1,false);\n        do{\n            used[j0]=true;\n            int i0=p[j0], delta=BIG, j1=0;\n            for(int j=1;j<=m;j++) if(!used[j]){\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<=m;j++)\n                if(used[j]){ u[p[j]]+=delta; v[j]-=delta; }\n                else         minv[j]-=delta;\n            j0=j1;\n        }while(p[j0]!=0);\n        do{\n            int j1=way[j0]; p[j0]=p[j1]; j0=j1;\n        }while(j0);\n    }\n    vector<int> match(n,-1);\n    for(int j=1;j<=m;j++) if(p[j]) match[p[j]-1]=j-1;\n    return match;\n}\n\n/*-------------- 2. build covering set for ONE weight W -------------*/\nvector<int> build_cover(const PreprocessedGrid& G,\n                        int si,int sj,int W){\n    int N=G.N, start=G.id(si,sj);\n    int H=G.rowRuns.size(), V=G.colRuns.size();\n    vector<char> hCov(H,0), vCov(V,0), taken(G.NN,0);\n    hCov[G.rowRunOf[start]]=1;\n    vCov[G.colRunOf[start]]=1;\n\n    auto metric=[&](int cell){\n        return W*G.digit[cell] +\n               abs(G.row(cell)-si)+abs(G.col(cell)-sj);\n    };\n    vector<int> rows, cols;\n    for(int r=0;r<H;r++) if(!hCov[r]) rows.push_back(r);\n    for(int c=0;c<V;c++) if(!vCov[c]) cols.push_back(c);\n\n    vector<int> chosen;\n\n    if(rows.size()<=cols.size()){\n        int n=rows.size(), m=cols.size(), BIG=1e8;\n        vector<vector<int>> costMat(n, vector<int>(m,BIG)),\n                            pick   (n, vector<int>(m,-1));\n        for(int i=0;i<n;i++){\n            int r=rows[i];\n            for(int cell: G.rowRuns[r]){\n                int c=G.colRunOf[cell];\n                int j=lower_bound(cols.begin(),cols.end(),c)-cols.begin();\n                if(j<m && cols[j]==c){\n                    int w=metric(cell);\n                    if(w<costMat[i][j]){ costMat[i][j]=w; pick[i][j]=cell; }\n                }\n            }\n        }\n        auto match=hungarian(costMat);\n        for(int i=0;i<n;i++){\n            int cell=pick[i][match[i]];\n            if(cell==-1){                          // extremely rare fallback\n                cell=G.rowRuns[rows[i]][0];\n                for(int x:G.rowRuns[rows[i]])\n                    if(metric(x)<metric(cell)) cell=x;\n            }\n            chosen.push_back(cell);\n            hCov[rows[i]]=1; vCov[cols[match[i]]]=1; taken[cell]=1;\n        }\n    }else{\n        /* symmetric (less columns than rows) */\n        int n=cols.size(), m=rows.size(), BIG=1e8;\n        vector<vector<int>> costMat(n, vector<int>(m,BIG)),\n                            pick   (n, vector<int>(m,-1));\n        for(int j=0;j<m;j++){\n            int r=rows[j];\n            for(int cell:G.rowRuns[r]){\n                int c=G.colRunOf[cell];\n                int i=lower_bound(cols.begin(),cols.end(),c)-cols.begin();\n                if(i<n && cols[i]==c){\n                    int w=metric(cell);\n                    if(w<costMat[i][j]){ costMat[i][j]=w; pick[i][j]=cell; }\n                }\n            }\n        }\n        auto match=hungarian(costMat);            // col i -> row match[i]\n        for(int i=0;i<n;i++){\n            int cell=pick[i][match[i]];\n            if(cell==-1){\n                cell=G.colRuns[cols[i]][0];\n                for(int x:G.colRuns[cols[i]])\n                    if(metric(x)<metric(cell)) cell=x;\n            }\n            chosen.push_back(cell);\n            hCov[rows[match[i]]]=1; vCov[cols[i]]=1; taken[cell]=1;\n        }\n    }\n    /* leftover runs (if |H|\u2260|V|) */\n    for(int r=0;r<H;r++) if(!hCov[r]){\n        int best=G.rowRuns[r][0];\n        for(int x:G.rowRuns[r])\n            if(metric(x)<metric(best)) best=x;\n        chosen.push_back(best); hCov[r]=1;\n    }\n    for(int c=0;c<V;c++) if(!vCov[c]){\n        int best=G.colRuns[c][0];\n        for(int x:G.colRuns[c])\n            if(metric(x)<metric(best)) best=x;\n        chosen.push_back(best); vCov[c]=1;\n    }\n    return chosen;\n}\n\n/*---------------------- 3. APSP on a node set ----------------------*/\nstruct APSP{\n    int N, NN, K;\n    const vector<char>& digit;\n    const vector<char>& road;\n    const vector<int>& nodes;\n    vector<vector<int>> dist;\n    vector<vector<string>> path;\n\n    APSP(const PreprocessedGrid& G,const vector<int>& nd)\n        : N(G.N), NN(G.NN), K(nd.size()),\n          digit(G.digit), road(G.isRoad), nodes(nd)\n    {\n        dist.assign(K, vector<int>(K,INF));\n        path.resize(K, vector<string>(K));\n        build();\n    }\n    int id(int i,int j) const { return i*N+j; }\n    void build(){\n        vector<array<int,4>> nb(NN);\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            int idx=id(i,j);\n            for(int k=0;k<4;k++){\n                int ni=i+di[k], nj=j+dj[k];\n                nb[idx][k]= inside(ni,N)&&inside(nj,N)&&road[id(ni,nj)]\n                            ? id(ni,nj):-1;\n            }\n        }\n        vector<int> d(NN), par(NN);\n        vector<char> pdir(NN);\n        using P=pair<int,int>;\n        priority_queue<P,vector<P>,greater<P>> pq;\n\n        for(int s=0;s<K;s++){\n            fill(d.begin(),d.end(),INF);\n            fill(par.begin(),par.end(),-1);\n            d[nodes[s]]=0; pq.emplace(0,nodes[s]);\n\n            while(!pq.empty()){\n                auto [dv,v]=pq.top(); pq.pop();\n                if(dv!=d[v]) continue;\n                for(int k=0;k<4;k++){\n                    int to=nb[v][k]; if(to==-1) continue;\n                    int nd=dv+digit[to];\n                    if(nd<d[to]){\n                        d[to]=nd; par[to]=v; pdir[to]=dch[k];\n                        pq.emplace(nd,to);\n                    }\n                }\n            }\n            for(int t=0;t<K;t++){\n                int dst=nodes[t];\n                dist[s][t]=d[dst];\n                if(s==t){ path[s][t]=\"\"; continue; }\n                string mv;\n                for(int cur=dst; cur!=nodes[s]; cur=par[cur])\n                    mv.push_back(pdir[cur]);\n                reverse(mv.begin(),mv.end());\n                path[s][t]=move(mv);\n            }\n        }\n    }\n};\n\n/*----------------- 4. Christofides + quick evaluation --------------*/\nvector<int> christofides(const vector<vector<int>>& D){\n    int K=D.size();\n    vector<int> par(K,-1), key(K,INF), in(K,0);\n    key[0]=0;\n    for(int r=0;r<K;r++){\n        int v=-1;\n        for(int i=0;i<K;i++) if(!in[i] && (v==-1||key[i]<key[v])) v=i;\n        in[v]=1;\n        for(int u=0;u<K;u++) if(!in[u] && D[v][u]<key[u]){\n            key[u]=D[v][u]; par[u]=v;\n        }\n    }\n    vector<vector<int>> adj(K);\n    vector<int> deg(K,0);\n    for(int i=1;i<K;i++){\n        adj[i].push_back(par[i]); adj[par[i]].push_back(i);\n        deg[i]++; deg[par[i]]++;\n    }\n    vector<int> odd;\n    for(int i=0;i<K;i++) if(deg[i]&1) odd.push_back(i);\n    vector<char> matched(K,0);\n    vector<tuple<int,int,int>> e;\n    for(int i=0;i<(int)odd.size();i++)\n        for(int j=i+1;j<(int)odd.size();j++)\n            e.emplace_back(D[odd[i]][odd[j]], odd[i], odd[j]);\n    sort(e.begin(),e.end());\n    for(auto [w,a,b]:e)\n        if(!matched[a] && !matched[b]){\n            matched[a]=matched[b]=1;\n            adj[a].push_back(b); adj[b].push_back(a);\n        }\n    vector<int> it(K,0), st={0}, eul;\n    while(!st.empty()){\n        int v=st.back();\n        while(it[v]<(int)adj[v].size() && adj[v][it[v]]==-1) ++it[v];\n        if(it[v]==(int)adj[v].size()){ eul.push_back(v); st.pop_back(); }\n        else{\n            int u=adj[v][it[v]];\n            adj[v][it[v]]=-1;\n            for(int &x:adj[u]) if(x==v){ x=-1; break; }\n            st.push_back(u);\n        }\n    }\n    vector<char> seen(K,0);\n    vector<int> tour;\n    for(int v:eul) if(!seen[v]){ tour.push_back(v); seen[v]=1; }\n    tour.push_back(0);\n    return tour;\n}\nlong long quick_length(const vector<int>& tour,\n                       const vector<vector<int>>& D){\n    long long sum=0;\n    for(size_t i=0;i+1<tour.size();i++) sum+=D[tour[i]][tour[i+1]];\n    return sum;\n}\n\n/*-------------------------- 5. local search ------------------------*/\nbool two_opt(vector<int>& ord,const vector<vector<int>>& D){\n    int L=ord.size(); bool changed=false, improved=true;\n    while(improved && !time_over()){\n        improved=false;\n        for(int i=1;i<L-3;i++){\n            for(int j=i+2;j<L-1;j++){\n                int a=ord[i-1], b=ord[i], c=ord[j], d=ord[j+1];\n                int gain=D[a][b]+D[c][d]-D[a][c]-D[b][d];\n                if(gain>0){\n                    reverse(ord.begin()+i, ord.begin()+j+1);\n                    improved=changed=true;\n                    if(time_over()) return changed;\n                }\n            }\n        }\n    }\n    return changed;\n}\nbool or_opt(vector<int>& ord,const vector<vector<int>>& D,int k){\n    int L=ord.size(); bool changed=false, improved=true;\n    while(improved && !time_over()){\n        improved=false;\n        for(int i=1;i<L-1-k;i++){\n            int pre=ord[i-1], post=ord[i+k];\n            int segStart=ord[i], segEnd=ord[i+k-1];\n            int remGain=D[pre][segStart]+D[segEnd][post]-D[pre][post];\n            for(int j=1;j<L-1;j++){\n                if(j>=i && j<=i+k-1) continue;\n                int u=ord[j], v=ord[j+1];\n                int insCost=D[u][segStart]+D[segEnd][v]-D[u][v];\n                if(remGain-insCost>0){\n                    vector<int> seg(ord.begin()+i, ord.begin()+i+k);\n                    ord.erase(ord.begin()+i, ord.begin()+i+k);\n                    if(j<i) ord.insert(ord.begin()+j+1, seg.begin(), seg.end());\n                    else     ord.insert(ord.begin()+j-k+1, seg.begin(), seg.end());\n                    improved=changed=true;\n                    if(time_over()) return changed;\n                    goto AGAIN;\n                }\n            }\n        }\nAGAIN: ;\n    }\n    return changed;\n}\nbool swap_nodes(vector<int>& ord,const vector<vector<int>>& D){\n    int L=ord.size(); bool changed=false, improved=true;\n    while(improved && !time_over()){\n        improved=false;\n        for(int i=1;i<L-2;i++){\n            for(int j=i+2;j<L-1;j++){\n                int aPrev=ord[i-1], a=ord[i], aNext=ord[i+1];\n                int bPrev=ord[j-1], b=ord[j], bNext=ord[j+1];\n                int gain=(D[aPrev][a]+D[a][aNext]+D[bPrev][b]+D[b][bNext])\n                        -(D[aPrev][b]+D[b][aNext]+D[bPrev][a]+D[a][bNext]);\n                if(gain>0){\n                    swap(ord[i],ord[j]);\n                    improved=changed=true;\n                    if(time_over()) return changed;\n                    goto AGAIN2;\n                }\n            }\n        }\nAGAIN2: ;\n    }\n    return changed;\n}\nvoid local_search(vector<int>& ord,const vector<vector<int>>& D){\n    int K=ord.size()-1;\n    bool allow_or2=K<=120, allow_or3=K<=120, allow_swap=K<=200;\n    bool improved=true;\n    while(improved && !time_over()){\n        improved=false;\n        improved|=two_opt(ord,D);\n        if(allow_or2) improved|=or_opt(ord,D,2);\n        if(allow_or3) improved|=or_opt(ord,D,3);\n        if(allow_swap) improved|=swap_nodes(ord,D);\n    }\n}\n\n/*------------------------------ 6. main ----------------------------*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    g_start = Clock::now();\n\n    int N, si, sj;\n    if(!(cin>>N>>si>>sj)) return 0;\n    vector<string> S(N);\n    for(int i=0;i<N;i++) cin>>S[i];\n\n    PreprocessedGrid grid(N,S);\n\n    /* try three different digit-weights, keep the cheapest quick tour */\n    const int WEIGHTS[3]={3,10,30};\n    long long bestLen=LLONG_MAX;\n    vector<int> bestNodes, bestTour;\n    vector<vector<int>> bestDist;\n    vector<vector<string>> bestPath;\n\n    for(int w:WEIGHTS){\n        vector<int> cover = build_cover(grid,si,sj,w);\n        vector<int> nodes(1, grid.id(si,sj));\n        nodes.insert(nodes.end(), cover.begin(), cover.end());\n\n        APSP apsp(grid, nodes);\n        vector<int> tour = christofides(apsp.dist);\n        long long len = quick_length(tour, apsp.dist);\n\n        if(len<bestLen){\n            bestLen=len;\n            bestNodes.swap(nodes);\n            bestTour.swap(tour);\n            bestDist.swap(apsp.dist);\n            bestPath.swap(apsp.path);\n        }\n    }\n\n    /* improve the best candidate */\n    local_search(bestTour, bestDist);\n\n    /* materialise */\n    string answer;\n    for(size_t i=0;i+1<bestTour.size();i++)\n        answer += bestPath[bestTour[i]][bestTour[i+1]];\n    cout<<answer<<\"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*---------------- Hungarian (square) ----------------*/\nconst long long INF64 = (1LL << 60);\n\nvector<int> hungarian(const vector<vector<long long>>& a) {\n    int n = (int)a.size() - 1;                // 1-based\n    vector<long long> u(n + 1), v(n + 1), minv(n + 1);\n    vector<int> p(n + 1), way(n + 1);\n    for (int i = 1; i <= n; ++i) {\n        p[0] = i; int j0 = 0;\n        fill(minv.begin(), minv.end(), INF64);\n        vector<char> used(n + 1, 0);\n        do {\n            used[j0] = 1;\n            int i0 = p[j0], j1 = 0; long long delta = INF64;\n            for (int j = 1; j <= n; ++j) if (!used[j]) {\n                long long cur = a[i0][j] - 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            j0 = j1;\n        } while (p[j0]);\n        do { int j1 = way[j0]; p[j0] = p[j1]; j0 = j1; } while (j0);\n    }\n    vector<int> ans(n + 1);\n    for (int j = 1; j <= n; ++j) ans[p[j]] = j;\n    return ans;                                  // row i \u2192 column ans[i]\n}\n\n/*---------------- Worker ----------------*/\nstruct Worker {\n    vector<int> low;     // proven lower bound\n    int task  = -1;\n    int start = -1;\n    int gap   = 3;\n};\n\n/*==========================================================================*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /*---- read instance ----*/\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    vector<vector<int>> need(N, vector<int>(K));\n    for (auto &v : need) for (int &x : v) cin >> x;\n\n    vector<vector<int>> out(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        out[u].push_back(v); ++indeg[v];\n    }\n\n    /*---- static priority = out-degree + longest path ----*/\n    vector<int> topo; topo.reserve(N);\n    {\n        queue<int> q; auto d = indeg;\n        for (int i = 0; i < N; ++i) if (!d[i]) q.push(i);\n        while (!q.empty()) {\n            int u = q.front(); q.pop(); topo.push_back(u);\n            for (int v : out[u]) if (!--d[v]) q.push(v);\n        }\n    }\n    vector<int> lp(N, 0);\n    for (int i = N - 1; i >= 0; --i)\n        for (int v : out[topo[i]])\n            lp[topo[i]] = max(lp[topo[i]], lp[v] + 1);\n    vector<int> basePrio(N);\n    for (int i = 0; i < N; ++i)\n        basePrio[i] = (int)out[i].size() + lp[i];\n\n    /*---- dynamic state ----*/\n    vector<char> state(N, 0);      // 0 not-started,1 running,2 done\n    vector<int> readyDay(N, -1);\n    vector<int> ready;\n    for (int i = 0; i < N; ++i)\n        if (!indeg[i]) { ready.push_back(i); readyDay[i] = 1; }\n\n    vector<Worker> W(M, Worker{vector<int>(K, 0)});\n\n    /*---- parameters ----*/\n    const int TOP_PRIO = 70, TOP_FAST = 70, MAX_CAND = 120;\n    const long long BIGC = 6'000'000LL;\n    const int  C_TIME  = 120;\n    const int  C_PRIO  = 16;\n\n    auto predict = [&](const Worker &w, int t) {\n        int lack = w.gap;\n        for (int k = 0; k < K; ++k) {\n            int d = need[t][k] - w.low[k];\n            if (d > 0) lack += d;\n        }\n        return max(1, lack);\n    };\n\n    int day = 1;\n    while (true) {\n        /*----- idle workers -----*/\n        vector<int> idle;\n        for (int j = 0; j < M; ++j) if (W[j].task == -1) idle.push_back(j);\n        int Wcnt = (int)idle.size();\n\n        /*----- generate candidate task list -----*/\n        vector<int> pool;\n        for (int id : ready) if (state[id] == 0) pool.push_back(id);\n\n        vector<int> cand;\n        if ((int)pool.size() <= MAX_CAND) cand = pool;\n        else {\n            struct Info { int id; long long effP; int bestT; };\n            vector<Info> infos; infos.reserve(pool.size());\n            for (int id : pool) {\n                long long effP = basePrio[id] + (day - readyDay[id]);\n                int bt = INT_MAX;\n                for (int wId : idle) bt = min(bt, predict(W[wId], id));\n                infos.push_back({id, effP, bt});\n            }\n            /* top by priority */\n            nth_element(infos.begin(), infos.begin() + TOP_PRIO, infos.end(),\n                        [](const Info &a, const Info &b){ return a.effP > b.effP; });\n            for (int i = 0; i < TOP_PRIO; ++i) cand.push_back(infos[i].id);\n\n            /* top by speed */\n            nth_element(infos.begin(), infos.begin() + TOP_FAST, infos.end(),\n                        [](const Info &a, const Info &b){ return a.bestT < b.bestT; });\n            for (int i = 0; i < TOP_FAST; ++i) cand.push_back(infos[i].id);\n\n            sort(cand.begin(), cand.end());\n            cand.erase(unique(cand.begin(), cand.end()), cand.end());\n\n            if ((int)cand.size() > MAX_CAND) {\n                sort(cand.begin(), cand.end(), [&](int a, int b){\n                    long long pa = basePrio[a] + (day - readyDay[a]);\n                    long long pb = basePrio[b] + (day - readyDay[b]);\n                    return pa > pb;\n                });\n                cand.resize(MAX_CAND);\n            }\n        }\n        int Tcnt = (int)cand.size();\n\n        /*----- cost matrix -----*/\n        int n = max(Wcnt, Tcnt);\n        vector<vector<long long>> cost(n + 1, vector<long long>(n + 1, BIGC));\n        for (int i = 0; i < Wcnt; ++i) {\n            const Worker &wk = W[idle[i]];\n            for (int j = 0; j < Tcnt; ++j) {\n                int t = cand[j];\n                int pt = predict(wk, t);\n                long long effP = basePrio[t] + (day - readyDay[t]);\n                cost[i + 1][j + 1] = C_TIME * (long long)pt - C_PRIO * effP;\n            }\n        }\n\n        /*----- Hungarian assignment -----*/\n        vector<pair<int,int>> today;                          // (worker, task)\n        if (Wcnt && Tcnt) {\n            auto match = hungarian(cost);\n            for (int i = 0; i < Wcnt; ++i) {\n                int j = match[i + 1] - 1;\n                if (j >= 0 && j < Tcnt && cost[i + 1][j + 1] < BIGC / 2) {\n                    int wid = idle[i], tid = cand[j];\n                    today.emplace_back(wid, tid);\n                    W[wid].task = tid; W[wid].start = day;\n                    state[tid] = 1;\n                }\n            }\n        }\n\n        /*----- output -----*/\n        cout << (int)today.size();\n        for (auto [w, t] : today) cout << ' ' << w + 1 << ' ' << t + 1;\n        cout << '\\n' << flush;\n\n        /*----- read end-of-day report -----*/\n        int done; if (!(cin >> done)) return 0;\n        if (done == -1) break;\n\n        for (int z = 0; z < done; ++z) {\n            int id; cin >> id; --id;\n            Worker &wk = W[id];\n            int tid = wk.task;\n            if (tid < 0) continue;\n\n            int realT = day - wk.start + 1;\n            int wLow  = max(0, realT - 3);\n            int wHigh = realT + 3;\n\n            int pred = wk.gap;\n            for (int k = 0; k < K; ++k) {\n                int d = need[tid][k] - wk.low[k];\n                if (d > 0) pred += d;\n            }\n\n            if (pred > wHigh) {                         // over-predicted\n                int excess = pred - wHigh;\n                for (int k = 0; k < K && excess; ++k) {\n                    int lack = need[tid][k] - wk.low[k];\n                    if (lack <= 0) continue;\n                    int inc = min(lack, excess);\n                    wk.low[k] += inc; excess -= inc;\n                }\n                wk.gap = max(0, wk.gap - excess);\n            }\n            else if (pred < wLow) {                     // under-predicted\n                wk.gap += (wLow - pred);               // lower bound only\n            }\n            else wk.gap = (int)(wk.gap * 0.9);\n\n            /* finished */\n            state[tid] = 2; wk.task = -1;\n            for (int v : out[tid])\n                if (--indeg[v] == 0) {\n                    ready.push_back(v);\n                    readyDay[v] = day + 1;\n                }\n        }\n        ++day;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** geometry **************************************************************/\nstruct Pt{ short x,y; };\ninline int md(const Pt&a,const Pt&b){ return abs(a.x-b.x)+abs(a.y-b.y); }\n\n/*** constants *************************************************************/\nconstexpr int NORD = 1000;\nconstexpr int NEED =   50;\nconstexpr int DEPOT = 0;\nconstexpr double TOTAL_TIME = 1.88;      // internal hard wall (< 2.0 s)\n\n/*** global data ***********************************************************/\nvector<Pt>          node;                // 0 + 2*NORD points\nvector<uint16_t>    distM;               // (2*N+1)^2  (\u226416 MiB)\ninline int dist(int u,int v){ return distM[u*(2*NORD+1)+v]; }\n\nvector<int> idxP(NORD), idxD(NORD), inner(NORD), byInner;\n\n/*** small tools ***********************************************************/\ninline long long routeCost(const vector<int>& r){\n    long long c=0;\n    for(size_t i=0;i+1<r.size();++i) c+=dist(r[i],r[i+1]);\n    return c;\n}\nstruct Ins{ long long d; int eP,eD; };\nIns bestInsert(const vector<int>& route,int ip,int id){\n    const int R=route.size();\n    long long best=LLONG_MAX; int bp=0,bd=0;\n    for(int i=0;i<R-1;++i){\n        long long d1=dist(route[i],ip)+dist(ip,route[i+1])-dist(route[i],route[i+1]);\n        long long delta=d1+dist(ip,id)+dist(id,route[i+1])-dist(ip,route[i+1]);\n        if(delta<best){best=delta;bp=i;bd=i;}\n        for(int j=i+1;j<R-1;++j){\n            long long d2=dist(route[j],id)+dist(id,route[j+1])-dist(route[j],route[j+1]);\n            delta=d1+d2;\n            if(delta<best){best=delta;bp=i;bd=j;}\n        }\n    }\n    return {best,bp,bd};\n}\ninline void applyInsert(vector<int>& r,int ip,int id,int eP,int eD){\n    r.insert(r.begin()+eP+1,ip);\n    if(eD==eP) r.insert(r.begin()+eP+2,id);\n    else       r.insert(r.begin()+eD+2,id);\n}\ninline void erasePair(vector<int>& r,int ip,int id){\n    r.erase(remove(r.begin(),r.end(),ip),r.end());\n    r.erase(remove(r.begin(),r.end(),id),r.end());\n}\ninline void collectUsed(const vector<int>& route,vector<char>& used){\n    fill(used.begin(),used.end(),0);\n    for(int v:route) if(v){ int o=(v-1)>>1; used[o]=1; }\n}\n\n/*** greedy construction ***************************************************/\nvector<int> greedyConstruct(mt19937& rng){\n    vector<char> used(NORD,0);\n    vector<int> route={DEPOT,DEPOT};\n    const int CAND=400, RCL=10;\n\n    for(int st=0;st<NEED;++st){\n        int cnt=0; static int pool[CAND];\n        for(int o:byInner) if(!used[o]){ pool[cnt++]=o; if(cnt==CAND) break; }\n\n        struct Info{ long long d; int o,eP,eD; };\n        array<Info,RCL> best; for(auto&b:best) b.d=LLONG_MAX;\n        for(int k=0;k<cnt;++k){\n            int id=pool[k];\n            auto ins=bestInsert(route,idxP[id],idxD[id]);\n            if(ins.d>=best[RCL-1].d) continue;\n            best[RCL-1]={ins.d,id,ins.eP,ins.eD};\n            for(int i=RCL-1;i>0&&best[i].d<best[i-1].d;--i) swap(best[i],best[i-1]);\n        }\n        int pick=uniform_int_distribution<int>(0,RCL-1)(rng);\n        const auto& ch=best[pick];\n        applyInsert(route,idxP[ch.o],idxD[ch.o],ch.eP,ch.eD);\n        used[ch.o]=1;\n    }\n    return route;\n}\n\n/*** hill climb: relocate (+ optional swap) *******************************/\nvoid hillClimb(vector<int>& route,vector<char>& used,bool withSwap){\n    bool imp=true;\n    while(imp){\n        imp=false;\n        for(int o=0;o<NORD && !imp;++o) if(used[o]){\n            vector<int> tmp=route;\n            erasePair(tmp,idxP[o],idxD[o]);\n            auto ins=bestInsert(tmp,idxP[o],idxD[o]);\n            if(ins.d<0){\n                applyInsert(tmp,idxP[o],idxD[o],ins.eP,ins.eD);\n                route.swap(tmp); imp=true;\n            }\n        }\n        if(withSwap){\n            for(int a=0;a<NORD && !imp;++a) if(used[a])\n            for(int b=a+1;b<NORD && !imp;++b) if(used[b]){\n                vector<int> tmp=route;\n                erasePair(tmp,idxP[a],idxD[a]);\n                erasePair(tmp,idxP[b],idxD[b]);\n                auto ia=bestInsert(tmp,idxP[a],idxD[a]); applyInsert(tmp,idxP[a],idxD[a],ia.eP,ia.eD);\n                auto ib=bestInsert(tmp,idxP[b],idxD[b]); applyInsert(tmp,idxP[b],idxD[b],ib.eP,ib.eD);\n                if(routeCost(tmp)<routeCost(route)){ route.swap(tmp); imp=true; }\n            }\n        }\n    }\n}\n\n/*** final deterministic single-exchange pass *****************************/\nvoid singleExchangeImprove(vector<int>& route,\n                           vector<char>& used,\n                           const vector<int>& candList,\n                           double timeLimit,\n                           const function<double()>& now)\n{\n    long long curC = routeCost(route);\n    while(now() < timeLimit){\n        long long bestNew = curC;\n        vector<int> bestR;\n        for(int oOut=0;oOut<NORD;++oOut) if(used[oOut]){\n            vector<int> rTmp = route;\n            erasePair(rTmp,idxP[oOut],idxD[oOut]);\n            long long costRemoved = routeCost(rTmp);\n\n            for(int oIn:candList) if(!used[oIn]){\n                auto ins = bestInsert(rTmp,idxP[oIn],idxD[oIn]);\n                long long newC = costRemoved + ins.d;\n                if(newC < bestNew){\n                    bestNew = newC;\n                    bestR   = rTmp;\n                    applyInsert(bestR,idxP[oIn],idxD[oIn],ins.eP,ins.eD);\n                }\n            }\n        }\n        if(bestNew < curC){\n            route.swap(bestR);\n            collectUsed(route,used);\n            curC = bestNew;\n        }else break;\n    }\n}\n\n/*** main ******************************************************************/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- input ------------------------------------------------- */\n    vector<array<int,4>> raw(NORD);\n    for(auto &v:raw) cin>>v[0]>>v[1]>>v[2]>>v[3];\n\n    /* ---------- nodes & distance matrix ------------------------------ */\n    node.reserve(1+2*NORD); node.push_back({400,400});\n    for(int i=0;i<NORD;++i){\n        node.push_back({(short)raw[i][0],(short)raw[i][1]});\n        node.push_back({(short)raw[i][2],(short)raw[i][3]});\n    }\n    int NN=node.size();\n    distM.resize((size_t)NN*NN);\n    for(int i=0;i<NN;++i) for(int j=0;j<NN;++j)\n        distM[i*NN+j]=(uint16_t)md(node[i],node[j]);\n\n    for(int i=0;i<NORD;++i){\n        idxP[i]=1+2*i; idxD[i]=idxP[i]+1;\n        inner[i]=dist(idxP[i],idxD[i]);\n    }\n    byInner.resize(NORD); iota(byInner.begin(),byInner.end(),0);\n    sort(byInner.begin(),byInner.end(),[&](int a,int b){return inner[a]<inner[b];});\n\n    /* ---------- timers & RNG ----------------------------------------- */\n    const auto t0=chrono::high_resolution_clock::now();\n    auto seconds=[&](){return chrono::duration<double>(chrono::high_resolution_clock::now()-t0).count();};\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<> U01(0,1);\n\n    /* ---------- 0) multi-start greedy (0.30 s) ----------------------- */\n    vector<int> bestR; long long bestC=LLONG_MAX; vector<char> used(NORD);\n    while(seconds()<0.30){\n        auto r=greedyConstruct(rng);\n        collectUsed(r,used);\n        hillClimb(r,used,false);                    // relocate only\n        long long c=routeCost(r);\n        if(c<bestC){bestC=c; bestR.swap(r);}\n    }\n    collectUsed(bestR,used);\n\n    /* ---------- 1) Simulated Annealing (until 1.55 s) ---------------- */\n    auto curR=bestR; auto curU=used; long long curC=bestC;\n    const double SA_END = 1.55;                     // leave >0.3 s\n    const double T0=800.0, Tend=0.2;\n\n    vector<int> best768(byInner.begin(),byInner.begin()+768);\n\n    while(seconds()<SA_END){\n        double prog=seconds()/SA_END;\n        double Temp = T0*pow(Tend/T0,prog);\n\n        double r=U01(rng);\n        enum Move{REL,EXC,SWP,RUI};\n        Move mv=(r<0.55)?REL:(r<0.75)?EXC:(r<0.90)?SWP:RUI;\n\n        vector<int> nxtR=curR; auto nxtU=curU;\n\n        if(mv==REL){\n            vector<int> in; for(int o=0;o<NORD;++o) if(curU[o]) in.push_back(o);\n            int o=in[uniform_int_distribution<int>(0,(int)in.size()-1)(rng)];\n            erasePair(nxtR,idxP[o],idxD[o]);\n            auto ins=bestInsert(nxtR,idxP[o],idxD[o]);\n            applyInsert(nxtR,idxP[o],idxD[o],ins.eP,ins.eD);\n\n        }else if(mv==EXC){\n            vector<int> in; for(int o=0;o<NORD;++o) if(curU[o]) in.push_back(o);\n            int outOrd=in[uniform_int_distribution<int>(0,(int)in.size()-1)(rng)];\n            erasePair(nxtR,idxP[outOrd],idxD[outOrd]); nxtU[outOrd]=0;\n\n            long long bestD=LLONG_MAX; int inOrd=-1,eP=0,eD=0;\n            for(int cand:best768) if(!nxtU[cand]){\n                auto ins=bestInsert(nxtR,idxP[cand],idxD[cand]);\n                if(ins.d<bestD){bestD=ins.d;inOrd=cand;eP=ins.eP;eD=ins.eD;}\n            }\n            if(inOrd<0) continue;\n            applyInsert(nxtR,idxP[inOrd],idxD[inOrd],eP,eD); nxtU[inOrd]=1;\n\n        }else if(mv==SWP){\n            vector<int> in; for(int o=0;o<NORD;++o) if(curU[o]) in.push_back(o);\n            if(in.size()<2) continue;\n            int A=in[uniform_int_distribution<int>(0,(int)in.size()-1)(rng)];\n            int B; do{B=in[uniform_int_distribution<int>(0,(int)in.size()-1)(rng)];}while(B==A);\n            erasePair(nxtR,idxP[A],idxD[A]); erasePair(nxtR,idxP[B],idxD[B]);\n            auto ia=bestInsert(nxtR,idxP[A],idxD[A]); applyInsert(nxtR,idxP[A],idxD[A],ia.eP,ia.eD);\n            auto ib=bestInsert(nxtR,idxP[B],idxD[B]); applyInsert(nxtR,idxP[B],idxD[B],ib.eP,ib.eD);\n\n        }else{ // RUI (3-4 orders)\n            vector<int> in; for(int o=0;o<NORD;++o) if(curU[o]) in.push_back(o);\n            int k=uniform_int_distribution<int>(3,4)(rng);\n            shuffle(in.begin(),in.end(),rng);\n            vector<int> rem(in.begin(),in.begin()+k);\n            for(int o:rem){ erasePair(nxtR,idxP[o],idxD[o]); nxtU[o]=0; }\n            for(int o:rem){\n                auto ins=bestInsert(nxtR,idxP[o],idxD[o]);\n                applyInsert(nxtR,idxP[o],idxD[o],ins.eP,ins.eD);\n                nxtU[o]=1;\n            }\n        }\n\n        long long nxtC=routeCost(nxtR);\n        long long diff=nxtC-curC;\n        if(diff<0 || exp(-diff/Temp)>U01(rng)){\n            curR.swap(nxtR); curU.swap(nxtU); curC=nxtC;\n            if(curC<bestC){bestC=curC; bestR=curR;}\n        }\n    }\n\n    /* ---------- 2) final clean-up (relocate+swap) -------------------- */\n    collectUsed(bestR,used);\n    hillClimb(bestR,used,true);\n\n    /* ---------- 3) deterministic single-exchange pass ---------------- */\n    collectUsed(bestR,used);\n    singleExchangeImprove(bestR,used,best768,TOTAL_TIME-0.03,seconds);\n\n    /* ---------- output ----------------------------------------------- */\n    vector<int> orders; vector<char> mark(NORD,0);\n    for(int v:bestR) if(v){\n        int o=(v-1)>>1; if(!mark[o]){ mark[o]=1; orders.push_back(o); }\n    }\n    sort(orders.begin(),orders.end());\n\n    cout<<NEED; for(int o:orders) cout<<' '<<o+1; cout<<\"\\n\";\n    cout<<bestR.size();\n    for(int v:bestR) cout<<' '<<node[v].x<<' '<<node[v].y;\n    cout<<\"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** ---------- DSU ---------- ***/\nstruct DSU {\n    vector<int> par, sz;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        par.resize(n);\n        sz.assign(n, 1);\n        iota(par.begin(), par.end(), 0);\n    }\n    int find(int v) { return par[v] == v ? v : par[v] = find(par[v]); }\n    /* returns true iff two different components were merged */\n    bool unite(int a, int b) {\n        a = find(a);  b = find(b);\n        if (a == b) return false;\n        if (sz[a] < sz[b]) swap(a, b);\n        par[b] = a;\n        sz[a] += sz[b];\n        return true;\n    }\n};\n\nconstexpr int N = 400;\nconstexpr int M = 1995;\n\n/*** ---------- classify edges into the 5 generator MST layers ---------- ***/\nvector<int> classifyLayers(const vector<int>& U, const vector<int>& V,\n                           const vector<int>& d)\n{\n    vector<int> layer(M, 4);                      // default = layer 4\n    vector<int> ord(M); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(),\n         [&](int a, int b){ return d[a] < d[b]; });\n\n    vector<char> alive(M, 1);\n    for (int L = 0; L < 5; ++L) {\n        DSU tmp(N);  int used = 0;\n        for (int id : ord) if (alive[id]) {\n            if (tmp.unite(U[id], V[id])) {\n                layer[id] = L;\n                alive[id] = 0;\n                if (++used == N - 1) break;\n            }\n        }\n    }\n    return layer;\n}\n\n/*** ---------- look-ahead: counts & minimal future d ---------- ***/\nstruct Info {\n    int cntU = 0, cntV = 0;\n    int minDU = INT_MAX, minDV = INT_MAX;\n};\n\nInfo lookAhead(int pos, int ru, int rv, DSU& dsu,\n               const vector<int>& U, const vector<int>& V,\n               const vector<int>& d)\n{\n    Info info;\n    for (int j = pos + 1; j < M; ++j) {\n        int a = dsu.find(U[j]);\n        int b = dsu.find(V[j]);\n        if (a == b) continue;                 // internal edge\n        int dj = d[j];\n        if (a == ru || b == ru) {\n            ++info.cntU;\n            info.minDU = std::min(info.minDU, dj);\n        }\n        if (a == rv || b == rv) {\n            ++info.cntV;\n            info.minDV = std::min(info.minDV, dj);\n        }\n    }\n    return info;\n}\n\n/*** ------------------------------------------------------------------ ***/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- fixed input ---------- */\n    vector<int> X(N), Y(N);\n    for (int i = 0; i < N; ++i) cin >> X[i] >> Y[i];\n\n    vector<int> U(M), V(M);\n    for (int i = 0; i < M; ++i) cin >> U[i] >> V[i];\n\n    /* ---------- lower-bound Euclidean distances ---------- */\n    vector<int> d(M);\n    for (int i = 0; i < M; ++i) {\n        long long dx = X[U[i]] - X[V[i]];\n        long long dy = Y[U[i]] - Y[V[i]];\n        d[i] = int(lround(std::sqrt(double(dx * dx + dy * dy))));\n        if (d[i] == 0) d[i] = 1;                 // safety\n    }\n\n    /* ---------- layer of each edge ---------- */\n    vector<int> layer = classifyLayers(U, V, d);\n\n    /* ---------- on-line phase ---------- */\n    DSU dsu(N);\n    int components = N;\n\n    for (int i = 0; i < M; ++i) {\n        long long li;  cin >> li;\n\n        int ru = dsu.find(U[i]);\n        int rv = dsu.find(V[i]);\n\n        if (ru == rv) {                         // already connected\n            cout << 0 << '\\n' << flush;\n            continue;\n        }\n\n        /* ---------- look-ahead ---------- */\n        Info info   = lookAhead(i, ru, rv, dsu, U, V, d);\n        int  minCnt = min(info.cntU, info.cntV);\n\n        bool mustTake = (minCnt == 0);          // last bridge for a side\n\n        /* ---------- price evaluation ---------- */\n        double ratio = double(li) / double(d[i]);\n\n        double t   = double(i) / double(M);\n        double thr = 0.85 + 2.15 * pow(t, 1.25);      // 0.85 \u2192 3.00\n        thr += 0.36 - 0.08 * layer[i];                // layer bonus\n\n        if (minCnt <= 1)       thr += 0.60;\n        else if (minCnt <= 3)  thr += 0.40;\n        else if (minCnt <= 6)  thr += 0.20;\n        else if (minCnt <=10)  thr += 0.10;\n\n        if (thr > 3.0) thr = 3.0;\n\n        /* absolute and expectation-based bargains */\n        bool veryCheap  = (li <= 25);\n        bool bestDist   = (d[i] <= min(info.minDU, info.minDV) - 1);\n\n        bool expectedGood = false;\n        if (info.minDU != INT_MAX) {\n            double expU = info.minDU + 2.0 * info.minDU / (info.cntU + 1);\n            if (li <= expU - 1) expectedGood = true;\n        }\n        if (!expectedGood && info.minDV != INT_MAX) {\n            double expV = info.minDV + 2.0 * info.minDV / (info.cntV + 1);\n            if (li <= expV - 1) expectedGood = true;\n        }\n\n        bool cheapEnough = veryCheap || bestDist || expectedGood || (ratio <= thr);\n\n        /* absolute safety: enough edges left? */\n        bool forcedByCnt = (components - 1 > M - i - 1);\n\n        bool take = mustTake || cheapEnough || forcedByCnt;\n\n        /* ---------- output & apply ---------- */\n        cout << (take ? 1 : 0) << '\\n' << flush;\n\n        if (take && dsu.unite(ru, rv))\n            --components;\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int H = 30, W = 30;\nconst int DX[4]={-1,1,0,0};\nconst int DY[4]={0,0,-1,1};\nconst char DIR_CH[4]={'U','D','L','R'};\n\nstruct Pet{ int x,y,t; };\n\nstruct Human{\n    int x,y;\n    int wall_col;          // column we will turn into a wall\n    int side;              // +1 : stand right of wall, build left  ('l')\n                           // -1 : stand left  of wall, build right ('r')\n    int lane_col;          // column on which we walk\n    int phase = 0;         // 0 walk to (1,lane), 1 build \u2193, 2 repair \u2191, 3 idle\n    bool build_next = true;\n};\n\n/* ------------------------------------------------------- helper functions */\nbool inside(int x,int y){ return 1<=x && x<=H && 1<=y && y<=W; }\n\nchar bfs_first(const vector<string>& board,int sx,int sy,int gx,int gy){\n    if(sx==gx && sy==gy) return '.';\n    static int dist[H+2][W+2];\n    for(int i=1;i<=H;i++) for(int j=1;j<=W;j++) dist[i][j]=-1;\n    queue<pair<int,int>> q;\n    dist[sx][sy]=0; q.push({sx,sy});\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        for(int d=0;d<4;d++){\n            int nx=x+DX[d], ny=y+DY[d];\n            if(!inside(nx,ny) || board[nx][ny]=='#' || dist[nx][ny]!=-1) continue;\n            dist[nx][ny]=dist[x][y]+1;\n            q.push({nx,ny});\n        }\n    }\n    if(dist[gx][gy]==-1) return '.';\n    for(int d=0;d<4;d++){\n        int nx=sx+DX[d], ny=sy+DY[d];\n        if(inside(nx,ny) && dist[nx][ny]==dist[gx][gy]-1) return DIR_CH[d];\n    }\n    return '.';\n}\n\n/* ======================================================================= */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ------------------------------------------------ */\n    int N; if(!(cin>>N)) return 0;\n    vector<Pet> pets(N);\n    for(auto &p:pets) cin>>p.x>>p.y>>p.t;\n\n    int M; cin>>M;\n    vector<Human> hum(M);\n    for(auto &h:hum) cin>>h.x>>h.y;\n\n    /* ---------- choose the best 3-column grid ----------------------------- */\n    int bestOffset = 0;\n    long long bestSum = (1LL<<60), bestWorst = (1LL<<60);\n\n    for(int off=0; off<3; ++off){\n        vector<int> stripeCnt(10,0);          // stripes between 10 internal walls\n        for(auto &p:pets){\n            int y0 = p.y - (2+off);\n            if(y0<0) continue;                // left of the first internal wall\n            int idx = y0/3;\n            if(idx>9) idx=9;\n            ++stripeCnt[idx];\n        }\n        /* which stripes will actually contain humans? -> walls spaced evenly */\n        long long sum=0, worst=0;\n        for(int i=0;i<M;i++){\n            int stripe = (long long)i*10/M;   // same rule as before\n            sum   += stripeCnt[stripe];\n            worst  = max<long long>(worst, stripeCnt[stripe]);\n        }\n        if(sum<bestSum || (sum==bestSum && worst<bestWorst)){\n            bestSum=sum; bestWorst=worst; bestOffset=off;\n        }\n    }\n\n    /* ---------- fixed walls for the chosen offset ------------------------- */\n    vector<int> WALL_COL;\n    for(int k=0; k<10; ++k){\n        int c = 2 + bestOffset + 3*k;\n        if(c<=W) WALL_COL.push_back(c);\n    }\n\n    /* pick M almost evenly spaced walls (same rule as previous versions) */\n    vector<int> used_cols;\n    for(int i=0;i<M;i++){\n        int idx = (long long)i* (int)WALL_COL.size() / M;\n        used_cols.push_back(WALL_COL[idx]);\n    }\n\n    /* initialise humans with those walls */\n    for(int i=0;i<M;i++){\n        hum[i].wall_col = used_cols[i];\n        hum[i].side     = (hum[i].wall_col < 15)? +1 : -1;\n        hum[i].lane_col = hum[i].wall_col + hum[i].side;\n    }\n\n    /* ---------- board representation -------------------------------------- */\n    vector<string> board(H+2,string(W+2,'#'));\n    for(int x=1;x<=H;x++) for(int y=1;y<=W;y++) board[x][y]='.';\n\n    auto pet_near = [&](int x,int y)->bool{\n        for(const auto &p:pets){\n            if(p.x==x && p.y==y) return true;\n            if(abs(p.x-x)+abs(p.y-y)==1) return true;\n        }\n        return false;\n    };\n    auto human_on = [&](int x,int y)->bool{\n        for(const auto &h:hum) if(h.x==x && h.y==y) return true;\n        return false;\n    };\n\n    /* ================= main loop \u2013 300 turns ============================== */\n    for(int turn=0;turn<300;turn++){\n        /* 1. decide tentative actions                                        */\n        struct Tmp{ char act='.'; int nx,ny; int bx,by; };\n        vector<Tmp> tmp(M);\n        bool willWall[H+1][W+1]={};\n\n        for(int i=0;i<M;i++){\n            Human &h = hum[i];\n            Tmp   &t = tmp[i];\n            t.nx=h.x; t.ny=h.y; t.bx=t.by=-1;\n\n            if(h.phase==1 && h.x==H) h.phase=2;            // finished DOWN\n            if(h.phase==2 && h.x==1){\n                int bx=h.x, by=h.y-h.side;\n                if(board[bx][by]=='#') h.phase=3;          // repair done\n            }\n\n            if(h.phase==0){                                // walk to start\n                char mv = bfs_first(board,h.x,h.y,1,h.lane_col);\n                if(mv!='.'){\n                    if(mv=='U'){ t.act='U'; t.nx=h.x-1; }\n                    else if(mv=='D'){ t.act='D'; t.nx=h.x+1; }\n                    else if(mv=='L'){ t.act='L'; t.ny=h.y-1; }\n                    else if(mv=='R'){ t.act='R'; t.ny=h.y+1; }\n                }\n            }\n            else if(h.phase==1){                           // build while \u2193\n                if(h.build_next){\n                    int bx=h.x, by=h.y-h.side;\n                    if(inside(bx,by) && board[bx][by]=='.'\n                       && !pet_near(bx,by) && !human_on(bx,by)){\n                        t.act = (h.side==1)?'l':'r';\n                        t.bx=bx; t.by=by; willWall[bx][by]=true;\n                    }\n                }else{\n                    if(h.x<H && board[h.x+1][h.y]=='.'){\n                        t.act='D'; t.nx=h.x+1;\n                    }\n                }\n            }\n            else if(h.phase==2){                           // repair while \u2191\n                int bx=h.x, by=h.y-h.side;\n                if(inside(bx,by) && board[bx][by]=='.'\n                   && !pet_near(bx,by) && !human_on(bx,by)){\n                    t.act = (h.side==1)?'l':'r';\n                    t.bx=bx; t.by=by; willWall[bx][by]=true;\n                }else if(h.x>1 && board[h.x-1][h.y]=='.'){\n                    t.act='U'; t.nx=h.x-1;\n                }\n            }\n            /* phase 3 : keep '.'                                            */\n        }\n\n        /* 2. cancel moves into walls (existing or new)                       */\n        for(int i=0;i<M;i++){\n            Tmp &t = tmp[i];\n            if(t.act=='U'||t.act=='D'||t.act=='L'||t.act=='R'){\n                if(board[t.nx][t.ny]=='#' || willWall[t.nx][t.ny]){\n                    t.act='.'; t.nx=hum[i].x; t.ny=hum[i].y;\n                }\n            }\n        }\n\n        /* 3. output                                                         */\n        string out; out.reserve(M);\n        for(auto &t:tmp) out.push_back(t.act);\n        cout<<out<<\"\\n\"<<flush;\n\n        /* 4. apply                                                          */\n        for(int i=0;i<M;i++){\n            char c = tmp[i].act;\n            Human &h = hum[i];\n\n            if(c=='U'||c=='D'||c=='L'||c=='R'){\n                h.x = tmp[i].nx; h.y = tmp[i].ny;\n            }\n            if(c=='u'||c=='d'||c=='l'||c=='r'){\n                int bx=h.x, by=h.y;\n                if(c=='u') --bx; else if(c=='d') ++bx;\n                else if(c=='l') --by; else if(c=='r') ++by;\n                if(inside(bx,by)) board[bx][by]='#';\n            }\n\n            if(h.phase==0 && h.x==1 && h.y==h.lane_col){\n                h.phase=1; h.build_next=true;\n            }else if(h.phase==1){\n                if(c=='l'||c=='r') h.build_next=false;\n                else if(c=='D')    h.build_next=true;\n            }\n        }\n\n        /* 5. pets\u2019 movement                                                 */\n        for(int i=0;i<N;i++){\n            string s; cin>>s;\n            auto &p=pets[i];\n            for(char c:s){\n                if(c=='U') --p.x;\n                else if(c=='D') ++p.x;\n                else if(c=='L') --p.y;\n                else if(c=='R') ++p.y;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Node {\n    int i, j;\n};\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ------------------------------------------------ */\n    int si, sj, ti, tj;\n    double p;\n    if (!(cin >> si >> sj >> ti >> tj >> p)) return 0;\n\n    vector<string> h(20);          // horizontal walls, length 19 each\n    for (int i = 0; i < 20; ++i) cin >> h[i];\n    vector<string> v(19);          // vertical   walls, length 20 each\n    for (int i = 0; i < 19; ++i) cin >> v[i];\n\n    /* ---------- plain BFS -------------------------------------------------- */\n    const int H = 20, W = 20, N = H * W;\n    auto id = [&](int i, int j){ return i * W + j; };\n\n    vector<int> prev(N, -1);       // predecessor vertex\n    vector<char> prevMove(N);      // move taken to reach that vertex\n    queue<Node> q;\n    q.push({si, sj});\n    prev[id(si,sj)] = -2;          // mark as source\n\n    const int di[4] = {-1,1,0,0};\n    const int dj[4] = {0,0,-1,1};\n    const char dc[4] = {'U','D','L','R'};\n\n    while(!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n\n        for (int dir = 0; dir < 4; ++dir) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (ni < 0 || ni >= H || nj < 0 || nj >= W) continue;\n            bool wall = false;\n            if (dir == 0) wall = (v[i-1][j] == '1');           // up\n            if (dir == 1) wall = (v[i][j]   == '1');           // down\n            if (dir == 2) wall = (h[i][j-1] == '1');           // left\n            if (dir == 3) wall = (h[i][j]   == '1');           // right\n            if (wall) continue;\n\n            int nid = id(ni,nj);\n            if (prev[nid] != -1) continue;                     // visited\n            prev[nid] = id(i,j);\n            prevMove[nid] = dc[dir];\n            q.push({ni,nj});\n        }\n    }\n\n    /* ---------- reconstruct shortest path --------------------------------- */\n    string path;\n    for (int cur = id(ti,tj); prev[cur] != -2; cur = prev[cur])\n        path.push_back(prevMove[cur]);\n    reverse(path.begin(), path.end());          // now from start to goal\n\n    /* ---------- build the robust route ------------------------------------ */\n    string result;\n    result.reserve(200);\n\n    // copy the shortest path twice (<= 78 characters)\n    result += path;\n    result += path;\n\n    // fill the rest with the old fallback\n    while (result.size() + 2 <= 200) result += \"DR\";\n    if (result.size() < 200) result.push_back('D');   // length must be <=200\n\n    cout << result << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int H = 30, W = 30, DIR = 4;\nconst int di[DIR] = {0,-1,0,1};      // L, U, R, D\nconst int dj[DIR] = {-1,0,1,0};\n\nconst int TO_BASE[8][4] = {           // statement table\n    {1,0,-1,-1},\n    {3,-1,-1,0},\n    {-1,-1,3,2},\n    {-1,2,1,-1},\n    {1,0,3,2},\n    {3,2,1,0},\n    {2,-1,0,-1},\n    {-1,3,-1,1}\n};\n\nint type[H][W];                       // 0\u20257 read from input\nint rot [H][W];                       // current rotation 0\u20253\n\nint maskTable[8][4];                  // bitset of used sides after rot\nint toTable  [8][4][4];               // dir-mapping after rot\n\n/*------------------------------------------------------------------*/\nvoid precalc(){\n    for(int t=0;t<8;t++)\n        for(int r=0;r<4;r++){\n            int m=0;\n            for(int d=0;d<4;d++){\n                int d0=(d-r+4)%4;\n                int td=TO_BASE[t][d0];\n                int res = (td==-1) ? -1 : (td+r)%4;\n                toTable[t][r][d]=res;\n                if(res!=-1){ m|=1<<d; m|=1<<res; }\n            }\n            maskTable[t][r]=m;\n        }\n}\n/*------------------------------------------------------------------*/\ninline bool inside(int i,int j){return 0<=i && i<H && 0<=j && j<W;}\ninline int bitCnt(int x){ return __builtin_popcount((unsigned)x); }\ninline int curMask(int i,int j){ return maskTable[type[i][j]][rot[i][j]]; }\n\n/*------------------------------------------------------------------*/\n/* open-ends bookkeeping                                            */\nint openEnds = 0;\nint deltaOpenEnds(int i,int j,int newR){          // difference if (i,j)=newR\n    int oldM = curMask(i,j);\n    int newM = maskTable[type[i][j]][newR];\n    if(oldM==newM) return 0;\n    int diff = 0;\n    for(int d=0;d<4;d++){\n        int ni=i+di[d], nj=j+dj[d];\n        int oldU = (oldM>>d)&1;\n        int newU = (newM>>d)&1;\n        int nbU  = (inside(ni,nj)? (curMask(ni,nj)>>((d+2)&3)&1) : 0);\n        int oldMis = oldU ^ nbU;\n        int newMis = newU ^ nbU;\n        diff += (inside(ni,nj)? 2 : 1)*(newMis - oldMis);\n    }\n    return diff;\n}\nvoid applyRot(int i,int j,int newR){\n    openEnds += deltaOpenEnds(i,j,newR);\n    rot[i][j]=newR;\n}\nvoid recomputeOE(){\n    openEnds=0;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int m=curMask(i,j);\n        for(int d=0;d<4;d++) if(m>>d&1){\n            int ni=i+di[d], nj=j+dj[d];\n            if(!inside(ni,nj) || !(curMask(ni,nj)>>((d+2)&3)&1)) ++openEnds;\n        }\n    }\n}\n/*------------------------------------------------------------------*/\n/* loop score                                                        */\nlong long loopScore(const array<array<int,W>,H>& R){\n    static bool vis[H][W][4];\n    memset(vis,0,sizeof(vis));\n    vector<int> lens;\n    for(int si=0;si<H;si++)for(int sj=0;sj<W;sj++){\n        int r=R[si][sj];\n        int m = maskTable[type[si][sj]][r];\n        for(int sd=0;sd<4;sd++) if((m>>sd&1) && !vis[si][sj][sd]){\n            int i=si,j=sj,d=sd,len=0;\n            while(true){\n                vis[i][j][d]=true;\n                int nd = toTable[type[i][j]][ R[i][j] ][d];\n                if(nd==-1) { len=0; break; }\n                int ni=i+di[nd], nj=j+dj[nd];\n                if(!inside(ni,nj)) { len=0; break; }\n                int ndIn=(nd+2)&3;\n                ++len;\n                i=ni; j=nj; d=ndIn;\n                if(i==si && j==sj && d==sd){ lens.push_back(len); break; }\n                if(vis[i][j][d]){ len=0; break; }       // shouldn't happen\n            }\n        }\n    }\n    if(lens.size()<2) return 0;\n    nth_element(lens.begin(),lens.begin()+1,lens.end(),greater<int>());\n    return 1LL*lens[0]*lens[1];\n}\nlong long currentScore(){\n    array<array<int,W>,H> R;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) R[i][j]=rot[i][j];\n    return loopScore(R);\n}\n/*------------------------------------------------------------------*/\n/* initial pattern                                                   */\nint desiredMask(int i,int j){\n    bool evenRow = !(i&1), evenCol = !(j&1);\n    if(evenRow)  return evenCol ? ((1<<2)|(1<<3)) : ((1<<0)|(1<<3));\n    else         return evenCol ? ((1<<2)|(1<<1)) : ((1<<0)|(1<<1));\n}\nint bestInitRot(int ty,int want){\n    int best=-1, bestHit=-1, extra=10;\n    for(int r=0;r<4;r++){\n        int mk=maskTable[ty][r];\n        int hit = bitCnt(mk & want);\n        int ext = bitCnt(mk & ~want);\n        if(hit>bestHit || (hit==bestHit && ext<extra)){\n            bestHit=hit; extra=ext; best=r;\n        }\n    }\n    return best;\n}\n/*------------------------------------------------------------------*/\nstruct Timer{\n    const double TL; chrono::steady_clock::time_point st;\n    Timer(double tl=1.95):TL(tl),st(chrono::steady_clock::now()){}\n    double elap()const{\n        return chrono::duration<double>(chrono::steady_clock::now()-st).count();\n    }\n    bool good()const{ return elap()<TL; }\n} timer;\n/*------------------------------------------------------------------*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    precalc();\n\n    /* proper input reader: 30 \u00d7 30 digits without blanks */\n    for(int i=0;i<H;i++){\n        string s; cin>>s;\n        for(int j=0;j<W;j++) type[i][j]=s[j]-'0';\n    }\n\n    /* 1. deterministic start                                         */\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int want = desiredMask(i,j);\n        rot[i][j]=bestInitRot(type[i][j],want);\n    }\n    recomputeOE();\n\n    /* 2. greedy fix                                                  */\n    mt19937 rng(1234567);\n    vector<pair<int,int>> cells;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cells.emplace_back(i,j);\n\n    while(openEnds>0 && timer.elap()<0.6){\n        shuffle(cells.begin(),cells.end(),rng);\n        bool changed=false;\n        for(auto [i,j]:cells){\n            int bestR=rot[i][j], bestD=0;\n            for(int r=0;r<4;r++){\n                int d=deltaOpenEnds(i,j,r);\n                if(d<bestD){ bestD=d; bestR=r; }\n            }\n            if(bestR!=rot[i][j]){\n                applyRot(i,j,bestR);\n                changed=true;\n                if(openEnds==0) break;\n            }\n        }\n        if(!changed) break;\n    }\n\n    /* 3. quick hill-climb                                            */\n    long long bestScore = (openEnds==0)? currentScore() : 0;\n    array<array<int,W>,H> bestRot;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) bestRot[i][j]=rot[i][j];\n\n    uniform_int_distribution<int> dist(0,H*W-1);\n    while(timer.good()){\n        int v=dist(rng), i=v/W, j=v%W;\n        int oldR=rot[i][j];\n        int newR = (oldR + 1 + dist(rng)%3)&3;\n        int oldOE=openEnds;\n        applyRot(i,j,newR);\n\n        bool keep=false; long long cand=0;\n        if(openEnds==0){\n            cand=currentScore();\n            if(cand>=bestScore) keep=true;\n        }else if(openEnds<oldOE) keep=true;\n\n        if(keep){\n            if(openEnds==0 && cand>bestScore){\n                bestScore=cand;\n                for(int x=0;x<H;x++)for(int y=0;y<W;y++) bestRot[x][y]=rot[x][y];\n            }\n        }else{\n            applyRot(i,j,oldR);       // revert\n            openEnds=oldOE;\n        }\n    }\n\n    /* 4. output                                                      */\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'+bestRot[i][j]));\n    cout<<out<<\"\\n\";\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ------------ helpers ------------------------------------------------ */\nconstexpr int MAXN  = 10;\nconstexpr int MAXNN = MAXN * MAXN;\ninline int bit(int d){ static constexpr int b[4]={2,8,1,4}; return b[d]; }\ninline int opp(int d){ return d ^ 1; }\nconstexpr int dx[4] = {-1,1,0,0},  dy[4] = {0,0,-1,1};\nconstexpr char DIRC[4] = {'U','D','L','R'};\n\nstruct Timer{\n    chrono::steady_clock::time_point st = chrono::steady_clock::now();\n    double elapsed() const{\n        return chrono::duration<double>(chrono::steady_clock::now()-st).count();\n    }\n};\n\n/* ------------ board -------------------------------------------------- */\nstruct Board{\n    int N;                                      // 6 \u2026 10\n    array<int8_t,MAXNN> a;                      // -1 = blank, else 0\u202615\n    int blank;                                  // 0 \u2026 N\u00b2\u22121\n\n    void slide(int dir){                        // dir legal\n        int bx=blank/N, by=blank%N;\n        int nx=bx+dx[dir], ny=by+dy[dir];\n        int nid=nx*N+ny;\n        swap(a[blank], a[nid]);\n        blank=nid;\n    }\n\n    struct Eval { int bestTree, score; };\n    Eval evaluate() const{\n        const int NN=N*N;\n        array<uint8_t,MAXNN> vis{};             // 0/1 visited\n        int que[MAXNN];\n\n        int bestT=0, treeSum=0, cycleTot=0, dangling=0, edgeTot=0;\n\n        for(int v=0; v<NN; ++v) if(a[v]>=0 && !vis[v]){\n            int qs=0, qe=0; que[qe++]=v; vis[v]=1;\n            int verts=0, edges=0;\n            while(qs<qe){\n                int id=que[qs++];\n                ++verts;\n                int x=id/N, y=id%N, pat=a[id];\n                for(int d=0; d<4; ++d) if(pat&bit(d)){\n                    int nx=x+dx[d], ny=y+dy[d];\n                    bool inside=(0<=nx && nx<N && 0<=ny && ny<N);\n                    if(!inside) continue;               // border: no penalty\n                    int nid=nx*N+ny;\n                    if(a[nid]<0){ ++dangling; continue; }\n                    bool match = a[nid]&bit(opp(d));\n                    if(match){\n                        if(id<nid){ ++edges; ++edgeTot; }\n                        if(!vis[nid]){ vis[nid]=1; que[qe++]=nid; }\n                    }else ++dangling;\n                }\n            }\n            int excess=max(0, edges-(verts-1));\n            cycleTot += excess;\n            if(excess==0){ bestT=max(bestT, verts); treeSum+=verts; }\n        }\n\n        /* adaptive cycle penalty: milder while bestTree is still small */\n        int cycPen = (bestT*2 < N*N ? 10'000 : 30'000);\n\n        int sc =  bestT   * 1'200'000        // official target (dominates)\n                + treeSum *     1'200        // NEW: reward many trees\n                - cycleTot*    cycPen\n                - dangling*       300\n                + edgeTot;\n        return {bestT, sc};\n    }\n};\n\n/* ------------ state -------------------------------------------------- */\nstruct State{\n    Board bd;\n    int bestTree;\n    int score;\n    char lastDir;\n    string moves;\n    bool operator<(const State& o) const { return score<o.score; }\n};\n\n/* ------------ solver ------------------------------------------------- */\nstruct Solver{\n    int N, Tlim, BEAM;\n    const double TL=2.95;\n    State bestGlobal;\n    mt19937 rng{1234567};\n\n    State read_initial(){\n        Board b; b.N=N;\n        for(int i=0;i<N*N;++i) b.a[i]=0;\n        for(int i=0;i<N;++i){\n            string row; cin>>row;\n            for(int j=0;j<N;++j){\n                int idx=i*N+j;\n                int v=(row[j]<='9')? row[j]-'0' : row[j]-'a'+10;\n                if(v==0){ b.a[idx]=-1; b.blank=idx; }\n                else    { b.a[idx]=int8_t(v);       }\n            }\n        }\n        auto ev=b.evaluate();\n        return {b, ev.bestTree, ev.score, -1, \"\"};\n    }\n\n    void beam_search(){\n        Timer tim;\n        vector<State> cur, nxt;\n        cur.reserve(BEAM*2); nxt.reserve(BEAM*4);\n\n        cur.push_back(read_initial());\n        bestGlobal=cur.front();\n\n        int depth=0;\n        while(depth<Tlim && tim.elapsed()<TL){\n            nxt.clear();\n            for(const State& st: cur){\n                int bx=st.bd.blank/N, by=st.bd.blank%N;\n                for(int d=0; d<4; ++d){\n                    if(st.lastDir!=-1 && d==opp(st.lastDir)) continue;\n                    int nx=bx+dx[d], ny=by+dy[d];\n                    if(nx<0||nx>=N||ny<0||ny>=N) continue;\n\n                    State ns=st;\n                    ns.bd.slide(d);\n                    ns.lastDir=d;\n                    ns.moves.push_back(DIRC[d]);\n\n                    auto ev=ns.bd.evaluate();\n                    ns.bestTree=ev.bestTree;\n                    ns.score   =ev.score;\n\n                    if(ev.bestTree>bestGlobal.bestTree){\n                        bestGlobal=ns;\n                        if(bestGlobal.bestTree==N*N-1) return; // done\n                    }\n                    if((int)ns.moves.size()<Tlim) nxt.push_back(move(ns));\n                }\n            }\n            if(nxt.empty()) break;\n\n            /* keep best part + a few random survivors for diversity */\n            int keepBest=min(BEAM, (int)nxt.size());\n            nth_element(nxt.begin(), nxt.begin()+keepBest, nxt.end(),\n                         [](const State&a,const State&b){return a.score>b.score;});\n\n            cur.assign(nxt.begin(), nxt.begin()+keepBest);\n            int extra = keepBest/10;                       // 10 % random\n            uniform_int_distribution<int> uni(keepBest, (int)nxt.size()-1);\n            while(extra-- && keepBest < (int)nxt.size()){\n                cur.push_back(nxt[uni(rng)]);\n            }\n            ++depth;\n        }\n    }\n\n    void run(){\n        ios::sync_with_stdio(false);\n        cin.tie(nullptr);\n        cin>>N>>Tlim;\n        BEAM=(N>=9? 2500: 1500);             // larger beam, still fast\n        beam_search();\n        cout<<bestGlobal.moves<<'\\n';\n    }\n};\n\n/* -------------------------------------------------------------------- */\nint main(){ Solver().run(); }","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n/* ------------------------------------------------------------------ */\n/* fast 64-bit xorshift RNG                                            */\nstruct FastRand{\n    uint64_t x = 88172645463325252ULL;\n    uint64_t next(){ x ^= x<<7; x ^= x>>9; return x; }\n    int next_int(int l,int r){ return int(next()%uint64_t(r-l+1))+l; }\n} rng;\n\n/* ----------------------------- constants --------------------------- */\nconstexpr int    R             = 10000;             // cake radius\nconstexpr ll     BIG           = 1'000'000'000LL;   // endpoints for lines\nconstexpr int    K_MAX         = 100;               // judge\u2019s cut limit\nconstexpr double TOTAL_TIME    = 2.85;              // whole programme\nconstexpr double MIN_RUN_TIME  = 0.10;              // don\u2019t start shorter\nconstexpr double SAFETY_MARGIN = 0.02;              // after every run\nconstexpr double T_START       = 30.0;              // SA temperature\n\n/* ---------------- helper: draw coordinate not forbidden ------------ */\nint sample_coord(const unordered_set<int>& forbid,\n                 unordered_set<int>&       used)\n{\n    int x;\n    do x = rng.next_int(-R+1, R-1);\n    while(forbid.count(x) || used.count(x));\n    used.insert(x);\n    return x;\n}\n\n/* ---------------- evaluator of an axis-aligned grid ---------------- */\nstruct Evaluator{\n    const vector<pair<int,int>>& P;\n    const array<int,11>& need;                 // a_d\n    vector<int> cell;                          // reusable buffer\n\n    Evaluator(const vector<pair<int,int>>& p,\n              const array<int,11>& a): P(p), need(a) {}\n\n    int operator()(const vector<int>& vx,const vector<int>& hy){\n        int V=vx.size(), H=hy.size(), W=(V+1)*(H+1);\n        cell.assign(W,0);                      // full reset\n\n        for(auto [x,y]:P){\n            int ix = int(lower_bound(vx.begin(),vx.end(),x)-vx.begin());\n            int iy = int(lower_bound(hy.begin(),hy.end(),y)-hy.begin());\n            ++cell[ix*(H+1)+iy];\n        }\n        array<int,11> have{};                 // b_d\n        for(int c:cell) if(1<=c && c<=10) ++have[c];\n\n        int ans=0;\n        for(int d=1; d<=10; ++d) ans += min(need[d],have[d]);\n        return ans;\n    }\n};\n\n/* ================================================================== */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read input ------------------------------------------------ */\n    int N,K;  if(!(cin>>N>>K)) return 0;\n    array<int,11> a{};  for(int d=1; d<=10; ++d) cin>>a[d];\n\n    vector<pair<int,int>> P(N);\n    unordered_set<int> forbidX,forbidY;\n    forbidX.reserve(N*2); forbidY.reserve(N*2);\n    for(auto& pt:P){\n        cin>>pt.first>>pt.second;\n        forbidX.insert(pt.first);\n        forbidY.insert(pt.second);\n    }\n    Evaluator eval(P,a);\n\n    /* ---- best solution so far ------------------------------------- */\n    vector<int> bestVX, bestHY;\n    int bestScore = -1;\n\n    const auto progBeg = chrono::steady_clock::now();\n\n    /* ==== multi-start simulated annealing ========================== */\n    while(true){\n        double elapsed = chrono::duration<double>\n                         (chrono::steady_clock::now()-progBeg).count();\n        double timeLeft = TOTAL_TIME - elapsed;\n        if(timeLeft <= MIN_RUN_TIME) break;          // no room for another run\n\n        double runLimit = min(0.25, timeLeft - SAFETY_MARGIN);\n\n        /* --- initial random grid ---------------------------------- */\n        vector<int> vx, hy;\n        {\n            int v = rng.next_int(8,48);\n            int h = rng.next_int(8,48);\n            unordered_set<int> used;\n            for(int i=0;i<v;++i) vx.push_back(sample_coord(forbidX,used));\n            used.clear();\n            for(int i=0;i<h;++i) hy.push_back(sample_coord(forbidY,used));\n            sort(vx.begin(),vx.end());\n            sort(hy.begin(),hy.end());\n        }\n        int curScore = eval(vx,hy);\n\n        const auto runBeg = chrono::steady_clock::now();\n\n        /* ---- SA loop for this run -------------------------------- */\n        while(true){\n            double rt = chrono::duration<double>\n                        (chrono::steady_clock::now()-runBeg).count();\n            if(rt > runLimit) break;\n\n            double T = T_START * pow(1.0/T_START, rt/runLimit);  // geometric\n\n            /* propose a modification --------------------------------*/\n            vector<int> nvx = vx, nhy = hy;\n            int op = rng.next_int(0,99);                         // 0-59 move, 60-79 add, 80-99 del\n            bool ok = true;\n\n            /* MOVE one line */\n            if(op < 60 && (!nvx.empty() || !nhy.empty())){\n                bool vert = nhy.empty() ? true\n                          : nvx.empty() ? false\n                          : rng.next_int(0,1);\n                if(vert){\n                    int idx = rng.next_int(0,(int)nvx.size()-1);\n                    int neu = nvx[idx] + rng.next_int(-1200,1200);\n                    neu = max(-R+1, min(R-1, neu));\n                    if(!forbidX.count(neu) &&\n                       !binary_search(nvx.begin(),nvx.end(),neu)){\n                        nvx[idx]=neu; sort(nvx.begin(),nvx.end());\n                    }else ok=false;\n                }else{\n                    int idx = rng.next_int(0,(int)nhy.size()-1);\n                    int neu = nhy[idx] + rng.next_int(-1200,1200);\n                    neu = max(-R+1, min(R-1, neu));\n                    if(!forbidY.count(neu) &&\n                       !binary_search(nhy.begin(),nhy.end(),neu)){\n                        nhy[idx]=neu; sort(nhy.begin(),nhy.end());\n                    }else ok=false;\n                }\n            }\n            /* INSERT a line */\n            else if(op < 80 && (int)nvx.size()+(int)nhy.size() < K){\n                bool vert = rng.next_int(0,1);\n                if(vert){\n                    unordered_set<int> used(nvx.begin(),nvx.end());\n                    int x = sample_coord(forbidX,used);\n                    nvx.push_back(x); sort(nvx.begin(),nvx.end());\n                }else{\n                    unordered_set<int> used(nhy.begin(),nhy.end());\n                    int y = sample_coord(forbidY,used);\n                    nhy.push_back(y); sort(nhy.begin(),nhy.end());\n                }\n            }\n            /* DELETE a line */\n            else if(!nvx.empty() || !nhy.empty()){\n                bool vert = nhy.empty() ? true\n                          : nvx.empty() ? false\n                          : rng.next_int(0,1);\n                if(vert) nvx.erase(nvx.begin()+rng.next_int(0,(int)nvx.size()-1));\n                else     nhy.erase(nhy.begin()+rng.next_int(0,(int)nhy.size()-1));\n            }else ok=false;\n\n            if(!ok) continue;\n\n            int newScore = eval(nvx,nhy);\n            int delta = newScore - curScore;\n            bool accept = delta >= 0 ||\n                          exp(double(delta)/T) >\n                          (rng.next_int(0,1000000)/1'000'000.0);\n\n            if(accept){\n                vx.swap(nvx); hy.swap(nhy); curScore = newScore;\n                if(newScore > bestScore){\n                    bestScore = newScore;\n                    bestVX = vx; bestHY = hy;\n                }\n            }\n        }\n    }\n\n    /* ---- output best grid ---------------------------------------- */\n    cout << bestVX.size()+bestHY.size() << '\\n';\n    for(int x: bestVX) cout<<x<<\" \"<<-BIG<<\" \"<<x<<\" \"<<BIG<<\"\\n\";\n    for(int y: bestHY) cout<<-BIG<<\" \"<<y<<\" \"<<BIG<<\" \"<<y<<\"\\n\";\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int MAXN = 62;                    // 61 + 1 safety row/col\n\n/* ------------------------------------------------------------------ */\n/*  very small, cache-friendly board representation                    */\n/* ------------------------------------------------------------------ */\nstruct Board {\n    int N, C;\n    unsigned char dot [MAXN][MAXN];\n    unsigned char h   [MAXN][MAXN];         // horizontal edge  (x,y)-(x+1,y)\n    unsigned char v   [MAXN][MAXN];         // vertical   edge  (x,y)-(x,y+1)\n    unsigned char ne  [MAXN][MAXN];         // diagonal  /\n    unsigned char nw  [MAXN][MAXN];         // diagonal  \\\n\n    void clearEdges(int n) {\n        for (int y = 0; y < n; ++y) {\n            memset(h [y],  0, n);\n            memset(v [y],  0, n);\n            memset(ne[y],  0, n);\n            memset(nw[y],  0, n);\n        }\n    }\n};\n\n/* ------------------------------------------------------------------ */\nstatic int              N, M;\nstatic long long        weight[MAXN][MAXN];\nstatic long long        Sboard = 0;\nstatic Board            basic;\nstatic long long        basicSum = 0;\n\n/* ------------------------------------------------------------------ */\nstruct Candidate {\n    int kind, x, y, miss;                   // 0 = square, 1 = diamond\n    int w;                                  // missing corner weight\n};\nstatic Candidate candPool[512];             // filled per iteration\nstatic int       poolSz;\n\n/* ------------------------------------------------------------------ */\nstruct RunResult {\n    long long sum;\n    vector<array<int,8>> moves;\n};\n\n/* ------------------------------------------------------------------ */\nRunResult oneRun(mt19937 &rng, int T0, int cool) {\n    Board B = basic;            // copy dots, empty edges\n    B.clearEdges(N);\n\n    vector<array<int,8>> moves;\n    long long sum = basicSum;\n\n    int step = 0;\n    while (true) {\n        int best = -1;\n        poolSz = 0;\n\n        /* ------------ axis aligned unit squares ------------------ */\n        for (int y = 0; y < N-1; ++y)\n            for (int x = 0; x < N-1; ++x) {\n                if (B.h[y][x] || B.h[y+1][x] || B.v[y][x] || B.v[y][x+1]) continue;\n\n                unsigned char p0 = B.dot[x][y]    ,\n                               p1 = B.dot[x+1][y]  ,\n                               p2 = B.dot[x+1][y+1],\n                               p3 = B.dot[x][y+1]  ;\n                int missCnt = (!p0)+(!p1)+(!p2)+(!p3);\n                if (missCnt != 1) continue;\n\n                int mi = !p0 ? 0 : !p1 ? 1 : !p2 ? 2 : 3;\n                int xx = x + (mi==1 || mi==2);\n                int yy = y + (mi>=2);\n                int w  = (int)weight[xx][yy];\n\n                if (w > best) best = w;\n                if (poolSz < 512) candPool[poolSz++] = {0,x,y,mi,w};\n            }\n\n        /* ------------ 45\u00b0 diamonds ------------------------------- */\n        for (int y = 0; y <= N-3; ++y)\n            for (int x = 1; x <= N-2; ++x) {\n                if (B.ne[y][x]      || B.nw[y+1][x] ||\n                    B.ne[y+1][x-1] ||  B.nw[y][x-1]) continue;\n\n                unsigned char p0 = B.dot[x][y]     ,\n                               p1 = B.dot[x+1][y+1] ,\n                               p2 = B.dot[x][y+2]   ,\n                               p3 = B.dot[x-1][y+1] ;\n                int missCnt = (!p0)+(!p1)+(!p2)+(!p3);\n                if (missCnt != 1) continue;\n\n                int mi = !p0 ? 0 : !p1 ? 1 : !p2 ? 2 : 3;\n                int xx, yy;\n                if (mi==0){xx=x;   yy=y;}\n                if (mi==1){xx=x+1; yy=y+1;}\n                if (mi==2){xx=x;   yy=y+2;}\n                if (mi==3){xx=x-1; yy=y+1;}\n                int w = (int)weight[xx][yy];\n\n                if (w > best) best = w;\n                if (poolSz < 512) candPool[poolSz++] = {1,x,y,mi,w};\n            }\n\n        if (poolSz == 0) break;            // no legal move left\n\n        int tol = max(5, T0 - step / cool);\n        int th  = best - tol;\n\n        /* ----------- build roulette -------------------------------- */\n        uint64_t tot = 0;\n        static uint64_t acc[512];\n        int kept = 0;\n        for (int i = 0; i < poolSz; ++i) {\n            int rel = candPool[i].w - th;\n            if (rel < 0) continue;         // below threshold\n            uint64_t score = 1ull * rel * rel + 1;   // (rel)\u00b2  (+1 avoids 0)\n            tot += score;\n            acc[kept] = tot;\n            candPool[kept++] = candPool[i];\n        }\n        poolSz = kept;\n        if (poolSz == 0) break;            // numerical safety\n\n        uint64_t r = rng() % tot;\n        int idx = int(lower_bound(acc, acc + poolSz, r + 1) - acc);\n        const Candidate &c = candPool[idx];\n\n        array<int,8> line;\n\n        if (c.kind == 0) {                 /* --------- square ------ */\n            auto corner=[&](int k)->pair<int,int>{\n                switch(k&3){\n                    case 0:return {c.x    ,c.y    };\n                    case 1:return {c.x+1  ,c.y    };\n                    case 2:return {c.x+1  ,c.y+1  };\n                    default:return{c.x    ,c.y+1  };\n                }};\n\n            bool cw = rng() & 1;\n            for (int k=0;k<4;++k){\n                auto [cx,cy]=corner(c.miss + (cw? k : -k));\n                line[2*k]=cx; line[2*k+1]=cy;\n            }\n            /* mark */\n            B.h[c.y][c.x]   = 1;\n            B.h[c.y+1][c.x] = 1;\n            B.v[c.y][c.x]   = 1;\n            B.v[c.y][c.x+1] = 1;\n\n            auto [nx,ny]=corner(c.miss);\n            B.dot[nx][ny]=1;\n            sum += weight[nx][ny];\n        } else {                           /* --------- diamond ----- */\n            auto corner=[&](int k)->pair<int,int>{\n                switch(k&3){\n                    case 0:return {c.x    ,c.y    };\n                    case 1:return {c.x+1  ,c.y+1  };\n                    case 2:return {c.x    ,c.y+2  };\n                    default:return{c.x-1  ,c.y+1  };\n                }};\n            bool cw = rng() & 1;\n            for (int k=0;k<4;++k){\n                auto [cx,cy]=corner(c.miss + (cw? k : -k));\n                line[2*k]=cx; line[2*k+1]=cy;\n            }\n            /* mark */\n            B.ne[c.y][c.x]     = 1;\n            B.nw[c.y+1][c.x]   = 1;\n            B.ne[c.y+1][c.x-1] = 1;\n            B.nw[c.y][c.x-1]   = 1;\n\n            auto [nx,ny]=corner(c.miss);\n            B.dot[nx][ny]=1;\n            sum += weight[nx][ny];\n        }\n\n        moves.push_back(line);\n        ++step;\n    }\n    return {sum, move(moves)};\n}\n\n/* ------------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin>>N>>M)) return 0;\n    int C = (N-1)/2;\n\n    for (int y=0;y<N;++y)\n        for (int x=0;x<N;++x){\n            long long w = 1LL*(x-C)*(x-C) + 1LL*(y-C)*(y-C) + 1;\n            weight[x][y]=w;\n            Sboard += w;\n        }\n\n    memset(basic.dot,0,sizeof(basic.dot));\n    for (int i=0;i<M;++i){\n        int x,y;cin>>x>>y;\n        basic.dot[x][y]=1;\n        basicSum += weight[x][y];\n    }\n    basic.N=N; basic.C=C;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto t0 = chrono::steady_clock::now();\n\n    RunResult best {basicSum,{}};\n\n    int runs = 0;\n    while (true){\n        ++runs;\n        int T0   = 120 + rng()%181;        // 120 \u2026 300\n        int cool = 3   + rng()%3;          // 3,4,5\n        RunResult r = oneRun(rng, T0, cool);\n        if (r.sum > best.sum) best = move(r);\n\n        if (chrono::duration<double>(chrono::steady_clock::now()-t0).count() > 4.8)\n            break;\n    }\n    // cerr<<\"runs=\"<<runs<<\"\\n\";\n\n    cout<<best.moves.size()<<'\\n';\n    for (auto &ln: best.moves){\n        for (int i=0;i<8;++i){\n            if (i) cout<<' ';\n            cout<<ln[i];\n        }\n        cout<<'\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Grid = array<array<int,10>,10>;\n\n/* ------------------------------------------------------------ */\n/* 1.  locate p-th empty cell (1-based) in row-major order       */\npair<int,int> locate_empty(const Grid& g,int idx){\n    int cnt = 0;\n    for(int r=0;r<10;r++)\n        for(int c=0;c<10;c++)\n            if(g[r][c]==0 && ++cnt==idx) return {r,c};\n    return {-1,-1};                 // never happens\n}\n/* ------------------------------------------------------------ */\n/* 2.  perform one tilt                                          */\nvoid tilt(Grid& dst,const Grid& src,char dir){\n    dst = {};                               // fill with zeros\n    if(dir=='F'){                           // to row 0\n        for(int c=0;c<10;c++){\n            int wr = 0;\n            for(int r=0;r<10;r++) if(src[r][c]) dst[wr++][c]=src[r][c];\n        }\n    }else if(dir=='B'){                     // to row 9\n        for(int c=0;c<10;c++){\n            int wr = 9;\n            for(int r=9;r>=0;r--) if(src[r][c]) dst[wr--][c]=src[r][c];\n        }\n    }else if(dir=='L'){                     // to col 0\n        for(int r=0;r<10;r++){\n            int wc = 0;\n            for(int c=0;c<10;c++) if(src[r][c]) dst[r][wc++]=src[r][c];\n        }\n    }else{                                  // 'R' to col 9\n        for(int r=0;r<10;r++){\n            int wc = 9;\n            for(int c=9;c>=0;c--) if(src[r][c]) dst[r][wc--]=src[r][c];\n        }\n    }\n}\n/* ------------------------------------------------------------ */\n/* 3.  gather statistics of a board                              */\nstruct Stat{\n    long long sum_sq;    // \u03a3 component_size\u00b2\n    int same_edges;      // #adjacent pairs with identical flavour\n    int diff_edges;      // #adjacent pairs with different flavour\n    int moved;           // how many candies changed their coordinates\n};\nStat analyse(const Grid& before,const Grid& after){\n    static const int dr[4]={-1,1,0,0};\n    static const int dc[4]={0,0,-1,1};\n\n    /* a) \u03a3 n\u00b2 -------------------------------------------------- */\n    bool vis[10][10] = {};\n    long long sum = 0;\n    queue<pair<int,int>> q;\n    for(int r=0;r<10;r++)for(int c=0;c<10;c++){\n        if(after[r][c]==0||vis[r][c]) continue;\n        int col = after[r][c], sz=0;\n        vis[r][c]=true; q.push({r,c});\n        while(!q.empty()){\n            auto [cr,cc]=q.front(); q.pop(); ++sz;\n            for(int k=0;k<4;k++){\n                int nr=cr+dr[k], nc=cc+dc[k];\n                if(nr<0||nr>=10||nc<0||nc>=10) continue;\n                if(!vis[nr][nc] && after[nr][nc]==col){\n                    vis[nr][nc]=true; q.push({nr,nc});\n                }\n            }\n        }\n        sum += 1LL*sz*sz;\n    }\n\n    /* b) edge statistics + moved counter ---------------------- */\n    int sameE = 0, diffE = 0, moved = 0;\n    for(int r=0;r<10;r++)for(int c=0;c<10;c++){\n        int v = after[r][c];\n        if(v && before[r][c]!=v) ++moved;\n\n        if(r+1<10 && v && after[r+1][c]){\n            (v==after[r+1][c] ? sameE : diffE)++;\n        }\n        if(c+1<10 && v && after[r][c+1]){\n            (v==after[r][c+1] ? sameE : diffE)++;\n        }\n    }\n    return {sum,sameE,diffE,moved};\n}\n/* ------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read full flavour sequence */\n    int flavour[100];\n    for(int i=0;i<100;i++) cin>>flavour[i];\n\n    Grid board = {};                        // start empty\n    const char DIRS[4] = {'F','B','L','R'};\n\n    for(int t=0;t<100;t++){\n        int p; cin>>p;                      // placement index\n        auto [r,c] = locate_empty(board,p);\n        board[r][c] = flavour[t];\n\n        if(t==99) break;                    // last candy, tilt does nothing\n\n        /* evaluate the four directions */\n        long long best_sum   = -1;\n        int       best_same  = -1;          // we maximise this\n        int       best_diff  = INT_MAX;     // we minimise this\n        int       best_moved = INT_MAX;\n        char      best_dir   = 'F';\n        Grid      best_board;\n\n        for(char dir:DIRS){\n            Grid after;\n            tilt(after,board,dir);\n            Stat st = analyse(board,after);\n\n            bool better = false;\n            if(st.sum_sq > best_sum) better = true;\n            else if(st.sum_sq == best_sum){\n                if(st.same_edges > best_same) better = true;\n                else if(st.same_edges == best_same){\n                    if(st.diff_edges < best_diff) better = true;\n                    else if(st.diff_edges == best_diff){\n                        if(st.moved < best_moved) better = true;\n                    }\n                }\n            }\n            if(better){\n                best_sum   = st.sum_sq;\n                best_same  = st.same_edges;\n                best_diff  = st.diff_edges;\n                best_moved = st.moved;\n                best_dir   = dir;\n                best_board = after;\n            }\n        }\n\n        board = best_board;\n        cout << best_dir << '\\n' << flush;\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\n/***------------ tiny 64-bit hash -----------------------------------***/\nstatic inline uint64_t splitmix64(uint64_t x){\n    x += 0x9e3779b97f4a7c15ULL;\n    x  = (x ^ (x>>30)) * 0xbf58476d1ce4e5b9ULL;\n    x  = (x ^ (x>>27)) * 0x94d049bb133111ebULL;\n    return  x ^ (x>>31);\n}\n\n/***------------ very small RNG -------------------------------------***/\nstatic uint64_t rng_state = 123456789987654321ULL;\nstatic inline uint64_t rng64(){\n    rng_state ^= rng_state<<7;  rng_state ^= rng_state>>9;\n    return rng_state;\n}\n\n/***------------ tiny graph,  N \u2264 100 -------------------------------***/\nstruct Graph{\n    int N{};\n    array<array<uint64_t,2>,100> row{};\n    void init(int n){ N=n; for(int i=0;i<N;i++) row[i][0]=row[i][1]=0; }\n    inline void addEdge(int i,int j){\n        if(j<64){ row[i][0]|=1ULL<<j; row[j][0]|=1ULL<<i; }\n        else     { row[i][1]|=1ULL<<(j-64); row[j][1]|=1ULL<<(i-64); }\n    }\n    inline bool edge(int i,int j) const{\n        return (j<64) ? ((row[i][0]>>j)&1ULL) : ((row[i][1]>>(j-64))&1ULL);\n    }\n    inline int degree(int i) const{\n        return __builtin_popcountll(row[i][0])+__builtin_popcountll(row[i][1]);\n    }\n};\n\n/***------------ canonicalisation with a seed -----------------------***/\nvector<uint64_t> canon_bits(const Graph& g, uint64_t seed){\n    const int N = g.N;\n    vector<uint64_t> col(N);\n    for(int v=0; v<N; ++v) col[v] = splitmix64( uint64_t(g.degree(v)) ^ seed );\n\n    vector<uint64_t> next(N);\n    for(int it=0; it<5; ++it){\n        for(int v=0; v<N; ++v){\n            uint64_t h1=0,h2=0;\n            for(int u=0; u<N; ++u) if(g.edge(v,u)){\n                h1 += col[u];\n                h2 += splitmix64(col[u]);\n            }\n            next[v] = splitmix64( col[v] ^ h1 ^ splitmix64(h2) ^ seed );\n        }\n        col.swap(next);\n    }\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    stable_sort(ord.begin(), ord.end(),\n                [&](int a,int b){ return col[a] < col[b]; });\n\n    size_t TOT   = size_t(N)*size_t(N-1)/2;\n    size_t WORDS = (TOT+63)>>6;\n    vector<uint64_t> bits(WORDS,0ULL);\n\n    size_t idx=0;\n    for(int i=0;i<N;i++){\n        int oi=ord[i];\n        for(int j=i+1;j<N;j++){\n            int oj=ord[j];\n            if(g.edge(oi,oj)) bits[idx>>6] |= 1ULL<<(idx&63);\n            ++idx;\n        }\n    }\n    return bits;\n}\n\n/***------------ Hamming distance of two bitsets --------------------***/\ninline int hamm(const vector<uint64_t>& A, const vector<uint64_t>& B){\n    int s=0; for(size_t i=0;i<A.size();i++) s += __builtin_popcountll(A[i]^B[i]);\n    return s;\n}\n\n/***==================================================================***/\nint main(){\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    int M; double eps;  if(!(cin>>M>>eps)) return 0;\n\n    /* ----------- choose N adaptively --------------------------------*/\n    int N;\n    if(eps<=0.12) N=24;\n    else if(eps<=0.18) N=28;\n    else if(eps<=0.24) N=35;\n    else if(eps<=0.30) N=45;\n    else if(eps<=0.36) N=60;\n    else               N=90;          // \u03b5 \u2265 0.36\n\n    size_t TOT   = size_t(N)*size_t(N-1)/2;\n    size_t WORDS = (TOT+63)>>6;\n    constexpr int S = 3;              // number of independent seeds\n    const uint64_t SEED[S] = {0x1337ULL, 0x9b1d2fe3ULL, 0xdeadbeefULL};\n\n    cout<<N<<\"\\n\";\n\n    /* ----------- build catalogue ------------------------------------*/\n    vector<array<vector<uint64_t>,S>> catBits(M);\n    Graph tmp; tmp.init(N);\n\n    for(int k=0;k<M;k++){\n        tmp.init(N);\n        string out; out.reserve(TOT);\n        for(int i=0;i<N;i++)\n            for(int j=i+1;j<N;j++){\n                bool e = rng64() & 1ULL;          // p = 0.5\n                out.push_back(e?'1':'0');\n                if(e) tmp.addEdge(i,j);\n            }\n\n        for(int s=0;s<S;s++) catBits[k][s] = canon_bits(tmp, SEED[s]);\n        cout<<out<<\"\\n\";\n    }\n    cout.flush();\n\n    /* ----------- answer 100 queries ---------------------------------*/\n    for(int q=0;q<100;q++){\n        string in; cin>>in;\n        Graph H; H.init(N);\n        size_t idx=0;\n        for(int i=0;i<N;i++)\n            for(int j=i+1;j<N;j++)\n                if(in[idx++]=='1') H.addEdge(i,j);\n\n        array<vector<uint64_t>,S> hBits;\n        for(int s=0;s<S;s++) hBits[s] = canon_bits(H, SEED[s]);\n\n        int best=-1, bestDist=INT_MAX;\n        for(int k=0;k<M;k++){\n            int d=INT_MAX;\n            for(int s=0;s<S;s++){\n                int dh = hamm(hBits[s], catBits[k][s]);\n                if(dh<d) d=dh;\n            }\n            if(d < bestDist){ bestDist=d; best=k; }\n        }\n        cout<<best<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int MAX_D = 30;            // hard upper bound given\nusing  Clock  = chrono::steady_clock;\n\n/* ------------------------------------------------------------ */\nstruct Edge { int u, v, w; };        // undirected, 0-based\n\n/* ---------- Dijkstra that may ignore one edge ---------------- */\nlong long dijkstra_ignore(int s, int t, int ban,\n        const vector<Edge>& E,\n        const vector<vector<pair<int,int>>>& adj,\n        vector<long long>& dist)\n{\n    const long long INF = (1LL<<60);\n    fill(dist.begin(), dist.end(), INF);\n    using Q = pair<long long,int>;\n    priority_queue<Q, vector<Q>, greater<Q>> pq;\n    dist[s] = 0;  pq.emplace(0, s);\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d != dist[v]) continue;\n        if (v == t) return d;\n        for (auto [to, id] : adj[v]) if (id != ban) {\n            long long nd = d + E[id].w;\n            if (nd < dist[to]) { dist[to] = nd; pq.emplace(nd, to); }\n        }\n    }\n    return INF;                                      // graph is 2-edge-conn.\n}\n\n/* ---------- connectivity after removing 1 day ---------------- */\nbool connected_without_day(int ban,\n        const vector<int>& day,\n        const vector<Edge>& E,\n        const vector<vector<pair<int,int>>>& adj,\n        vector<int>& vis)\n{\n    const int N = adj.size();\n    fill(vis.begin(), vis.end(), 0);\n    static int q[1024];\n    int qs = 0, qe = 0;  q[qe++] = 0; vis[0] = 1;\n    while (qs < qe) {\n        int v = q[qs++];\n        for (auto [to, id] : adj[v])\n            if (day[id] != ban && !vis[to]) { vis[to] = 1; q[qe++] = to; }\n    }\n    for (int v = 0; v < N; ++v) if (!vis[v]) return false;\n    return true;\n}\n\n/* ------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------------- read input ---------------- */\n    int N, M, D, K;\n    if (!(cin >> N >> M >> D >> K)) return 0;\n\n    vector<Edge> E(M);\n    vector<int> deg(N, 0);\n    for (int i = 0; i < M; ++i) {\n        cin >> E[i].u >> E[i].v >> E[i].w;\n        --E[i].u; --E[i].v;\n        ++deg[E[i].u]; ++deg[E[i].v];\n    }\n    for (int i = 0, x, y; i < N; ++i) cin >> x >> y;   // coords are unused\n\n    /* ---------------- adjacency ---------------- */\n    vector<vector<pair<int,int>>> adj(N);\n    for (int i = 0; i < M; ++i) {\n        adj[E[i].u].push_back({E[i].v, i});\n        adj[E[i].v].push_back({E[i].u, i});\n    }\n\n    /* ---------------- betweenness ---------------- */\n    std::mt19937 rng(20240517u);\n    vector<int> bet(M, 0);\n    vector<long long> dist(N);\n    vector<int> parent(N);\n    const int SRC_CNT = 40;\n    for (int it = 0; it < SRC_CNT; ++it) {\n        int s = rng() % N;\n        const long long INF = (1LL<<60);\n        fill(dist.begin(), dist.end(), INF);\n        fill(parent.begin(), parent.end(), -1);\n        using Q = pair<long long,int>;\n        priority_queue<Q, vector<Q>, greater<Q>> pq;\n        dist[s] = 0;  pq.emplace(0, s);\n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (d != dist[v]) continue;\n            for (auto [to, id] : adj[v]) {\n                long long nd = d + E[id].w;\n                if (nd < dist[to]) {\n                    dist[to] = nd;\n                    parent[to] = id;\n                    pq.emplace(nd, to);\n                }\n            }\n        }\n        for (int v = 0; v < N; ++v)\n            if (v != s && parent[v] >= 0) ++bet[parent[v]];\n    }\n\n    /* ---------------- detour penalty ---------------- */\n    vector<long long> extra(M, 0);\n    for (int id = 0; id < M; ++id)\n        extra[id] = dijkstra_ignore(E[id].u, E[id].v, id, E, adj, dist) - E[id].w;\n\n    /* final importance: 5*bet + extra/1000 (good balance) */\n    vector<int> imp(M);\n    for (int i = 0; i < M; ++i)\n        imp[i] = 5 * bet[i] + int(extra[i] / 1000);     // scale to O(10\u00b3)\n\n    /* ---------------- per-vertex per-day capacity -------- */\n    vector< array<uint8_t, MAX_D> > cap(N);\n    for (int v = 0; v < N; ++v) {\n        int base = deg[v] / D, rem = deg[v] % D, shift = rng() % D;\n        for (int i = 0; i < D; ++i) {\n            int d = (i + shift) % D;\n            cap[v][d] = base + (i < rem ? 1 : 0);\n        }\n    }\n\n    /* ---------------- greedy construction ---------------- */\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    shuffle(order.begin(), order.end(), rng);\n    sort(order.begin(), order.end(),\n         [&](int a, int b) { return imp[a] > imp[b]; });\n\n    vector<int> day(M, -1);                       // current assignment\n    vector<int16_t> load(D, 0);\n    vector< array<int16_t, MAX_D> > used(N);      for (auto& a: used) a.fill(0);\n    vector<long long> dayImp(D, 0), dayExtra(D, 0);\n\n    for (int id : order) {\n        int u = E[id].u, v = E[id].v;\n        long long bestScore = LLONG_MAX; int bestDay = -1;\n        for (int d = 0; d < D; ++d) if (load[d] < K) {\n            long long score = 20LL * (used[u][d] + used[v][d]) + dayImp[d];\n            if (score < bestScore) { bestScore = score; bestDay = d; }\n        }\n        if (bestDay < 0) bestDay =\n              int(min_element(load.begin(), load.end()) - load.begin());\n        day[id] = bestDay;\n        ++load[bestDay]; ++used[u][bestDay]; ++used[v][bestDay];\n        dayImp[bestDay]   += imp[id];\n        dayExtra[bestDay] += extra[id];\n    }\n\n    /* ---------------- simulated annealing ---------------- */\n    auto calcCost = [&]()->long long {\n        long long vterm = 0, dterm = 0;\n        for (int v = 0; v < N; ++v)\n            for (int d = 0; d < D; ++d)\n                vterm += 1LL * used[v][d] * used[v][d];\n        for (int d = 0; d < D; ++d)\n            dterm += dayImp[d] * dayImp[d];\n        return vterm + dterm;\n    };\n    long long bestCost = calcCost();\n    vector<int> bestDay = day;\n\n    const double SA_TIME = 3.5;                   // seconds\n    const double T0 = 1.0, T1 = 0.01;\n    auto tSA0 = Clock::now();\n    uniform_real_distribution<double> U01(0, 1);\n\n    for (long long iter = 1;; ++iter) {\n        if ((iter & 4095) == 0) {\n            double t = chrono::duration<double>(Clock::now() - tSA0).count();\n            if (t >= SA_TIME) break;\n        }\n        double prog = chrono::duration<double>(Clock::now() - tSA0).count()\n                      / SA_TIME;\n        double Temp = T0 * pow(T1 / T0, prog);\n\n        int id = rng() % M;\n        int d0 = day[id], d1 = rng() % D;\n        if (d0 == d1 || load[d1] >= K) continue;\n\n        int u = E[id].u, v = E[id].v;\n        long long delta = 0;\n\n        /* vertex term */\n        delta -= 1LL*used[u][d0]*used[u][d0] + 1LL*used[v][d0]*used[v][d0]\n               + 1LL*used[u][d1]*used[u][d1] + 1LL*used[v][d1]*used[v][d1];\n        delta += 1LL*(used[u][d0]-1)*(used[u][d0]-1)\n               + 1LL*(used[v][d0]-1)*(used[v][d0]-1)\n               + 1LL*(used[u][d1]+1)*(used[u][d1]+1)\n               + 1LL*(used[v][d1]+1)*(used[v][d1]+1);\n\n        /* day-importance term */\n        long long impw = imp[id];\n        delta -= dayImp[d0]*dayImp[d0] + dayImp[d1]*dayImp[d1];\n        delta += (dayImp[d0]-impw)*(dayImp[d0]-impw)\n               + (dayImp[d1]+impw)*(dayImp[d1]+impw);\n\n        if (delta <= 0 || U01(rng) < exp(-delta / Temp)) {\n            day[id] = d1;\n            --load[d0]; ++load[d1];\n            --used[u][d0]; --used[v][d0];\n            ++used[u][d1]; ++used[v][d1];\n            dayImp[d0] -= impw;  dayImp[d1] += impw;\n            dayExtra[d0] -= extra[id]; dayExtra[d1] += extra[id];\n\n            bestCost += delta;\n            if (bestCost < 0) bestCost = 0;\n            if (bestCost < calcCost()) {\n                bestCost = calcCost();\n                bestDay  = day;\n            }\n        }\n    }\n    day = bestDay;\n\n    /* ---------------- rebuild helper arrays ---------------- */\n    fill(load.begin(), load.end(), 0);\n    for (auto& a : used) a.fill(0);\n    fill(dayImp.begin(),   dayImp.end(),   0);\n    fill(dayExtra.begin(), dayExtra.end(), 0);\n    for (int i = 0; i < M; ++i) {\n        ++load[day[i]];\n        ++used[E[i].u][day[i]];\n        ++used[E[i].v][day[i]];\n        dayImp  [ day[i] ] += imp  [i];\n        dayExtra[ day[i] ] += extra[i];\n    }\n\n    /* ---------------- connectivity repair ------------------ */\n    vector<vector<int>> edgesOfDay(D);\n    for (int d = 0; d < D; ++d) edgesOfDay[d].clear();\n    for (int i = 0; i < M; ++i) edgesOfDay[ day[i] ].push_back(i);\n\n    vector<int> vis(N);\n    for (int d = 0; d < D; ++d) {\n        bool changed = true;\n        while (changed && !connected_without_day(d, day, E, adj, vis)) {\n            changed = false;\n\n            /* label components */\n            fill(vis.begin(), vis.end(), -1);\n            int compCnt = 0;\n            for (int s = 0; s < N; ++s) if (vis[s] < 0) {\n                queue<int> q; q.push(s); vis[s] = compCnt;\n                while (!q.empty()) {\n                    int v = q.front(); q.pop();\n                    for (auto [to, id] : adj[v])\n                        if (day[id] != d && vis[to] < 0) {\n                            vis[to] = compCnt; q.push(to);\n                        }\n                }\n                ++compCnt;\n            }\n            /* move one crossing edge out of day d */\n            for (int idx = 0; idx < (int)edgesOfDay[d].size(); ++idx) {\n                int id = edgesOfDay[d][idx];\n                int u = E[id].u, v = E[id].v;\n                if (vis[u] == vis[v]) continue;           // not a cut edge\n                int tgt = -1;\n                for (int t = 0; t < D; ++t)\n                    if (t != d && load[t] < K) { tgt = t; break; }\n                if (tgt < 0) continue;\n\n                /* perform move */\n                day[id] = tgt;\n                ++load[tgt]; --load[d];\n                ++used[u][tgt]; ++used[v][tgt];\n                --used[u][d];   --used[v][d];\n                dayImp  [d]   -= imp[id];  dayImp  [tgt] += imp[id];\n                dayExtra[d]   -= extra[id];dayExtra[tgt] += extra[id];\n\n                edgesOfDay[tgt].push_back(id);\n                edgesOfDay[d][idx] = edgesOfDay[d].back();\n                edgesOfDay[d].pop_back();\n\n                changed = true; break;\n            }\n        }\n    }\n\n    /* ---------------- detour-weight balancer --------------- */\n    auto tBal0 = Clock::now();\n    while (chrono::duration<double>(Clock::now() - tBal0).count() < 0.8) {\n        int dMax = max_element(dayExtra.begin(), dayExtra.end()) - dayExtra.begin();\n        int dMin = min_element(dayExtra.begin(), dayExtra.end()) - dayExtra.begin();\n        if (dayExtra[dMax] <= dayExtra[dMin] + 1000) break;     // balanced\n\n        /* heaviest edge on dMax */\n        int idBest = -1; long long bestEx = -1;\n        for (int id : edgesOfDay[dMax])\n            if (extra[id] > bestEx) { bestEx = extra[id]; idBest = id; }\n        if (idBest < 0) break;\n\n        bool moved = false;\n        for (int shift = 0; shift < D; ++shift) {\n            int tgt = (dMin + shift) % D;\n            if (tgt == dMax || load[tgt] >= K) continue;\n            day[idBest] = tgt;\n            if (connected_without_day(dMax, day, E, adj, vis) &&\n                connected_without_day(tgt , day, E, adj, vis)) {\n\n                /* commit */\n                ++load[tgt]; --load[dMax];\n                int u = E[idBest].u, v = E[idBest].v;\n                ++used[u][tgt]; ++used[v][tgt];\n                --used[u][dMax]; --used[v][dMax];\n                dayImp  [dMax] -= imp  [idBest]; dayImp  [tgt] += imp [idBest];\n                dayExtra[dMax] -= extra[idBest];dayExtra[tgt] += extra[idBest];\n                edgesOfDay[tgt].push_back(idBest);\n                edgesOfDay[dMax].erase(remove(edgesOfDay[dMax].begin(),\n                                              edgesOfDay[dMax].end(), idBest),\n                                        edgesOfDay[dMax].end());\n                moved = true; break;\n            }\n            day[idBest] = dMax;                       // restore\n        }\n        if (!moved) break;\n    }\n\n    /* ---------------- output ------------------------------- */\n    for (int i = 0; i < M; ++i) {\n        if (i) cout << ' ';\n        cout << day[i] + 1;                          // 1-based\n    }\n    cout << '\\n';\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ------------------------------------------------------------------ */\n/* helper structures                                                  */\n/* ------------------------------------------------------------------ */\nstruct Pillar {\n    std::vector<int> vox;                    // contiguous, sorted by z\n    int len() const { return (int)vox.size(); }\n};\nstruct CmpLen {\n    bool operator()(Pillar* a, Pillar* b) const {\n        return a->len() < b->len();\n    }\n};\n\n/* ---- utility ----------------------------------------------------- */\ntemplate <class T>\ninline bool chmax(T& a, const T& b)          // return true if a was updated\n{\n    if (a < b) { a = b; return true; }\n    return false;\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* -------- read input ------------------------------------------ */\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 k = 0; k < 2; ++k) {\n        for (int z = 0; z < D; ++z) cin >> F[k][z];\n        for (int z = 0; z < D; ++z) cin >> R[k][z];\n    }\n    const int SZ = D * D * D;\n    auto idx = [D](int x, int y, int z) { return x * D * D + y * D + z; };\n\n    /* ------------------------------------------------------------------ */\n    /* 1.  determine preferred partner for every row / column            */\n    /* ------------------------------------------------------------------ */\n    int cntRow[2][15][15] = {};     // object, row, column\n    int cntCol[2][15][15] = {};     // object, column, row\n    for (int obj = 0; obj < 2; ++obj) {\n        for (int z = 0; z < D; ++z) {\n            vector<int> X, Y;\n            for (int x = 0; x < D; ++x) if (F[obj][z][x] == '1') X.push_back(x);\n            for (int y = 0; y < D; ++y) if (R[obj][z][y] == '1') Y.push_back(y);\n            for (int x : X) for (int y : Y) {\n                ++cntRow[obj][x][y];\n                ++cntCol[obj][y][x];\n            }\n        }\n    }\n    int rowPref[2][15], colPref[2][15];\n    for (int obj = 0; obj < 2; ++obj) {\n        for (int x = 0; x < D; ++x) {\n            int best = 0, by = 0;\n            for (int y = 0; y < D; ++y)\n                if (chmax(best, cntRow[obj][x][y])) by = y;\n            rowPref[obj][x] = by;\n        }\n        for (int y = 0; y < D; ++y) {\n            int best = 0, bx = 0;\n            for (int x = 0; x < D; ++x)\n                if (chmax(best, cntCol[obj][y][x])) bx = x;\n            colPref[obj][y] = bx;\n        }\n    }\n\n    /* ------------------------------------------------------------------ */\n    /* 2.  build occupancy with preference-aware rook placement           */\n    /* ------------------------------------------------------------------ */\n    vector<char> occ[2];  occ[0].assign(SZ, 0);  occ[1].assign(SZ, 0);\n\n    auto build_slice = [&](int obj, int z) {\n        vector<int> X, Y;\n        for (int x = 0; x < D; ++x) if (F[obj][z][x] == '1') X.push_back(x);\n        for (int y = 0; y < D; ++y) if (R[obj][z][y] == '1') Y.push_back(y);\n        const bool rowMajor = X.size() >= Y.size();\n        vector<char> rowUsed(D, 0), colUsed(D, 0);\n\n        if (rowMajor) {                                   // -------- rows dominate\n            vector<int> unRow;\n            for (int x : X) {\n                int y = rowPref[obj][x];\n                if (find(Y.begin(), Y.end(), y) != Y.end() && !colUsed[y]) {\n                    occ[obj][idx(x, y, z)] = 1;\n                    rowUsed[x] = colUsed[y] = 1;\n                } else unRow.push_back(x);\n            }\n            for (int y : Y) if (!colUsed[y]) {            // uncovered columns\n                int x = unRow.back(); unRow.pop_back();\n                occ[obj][idx(x, y, z)] = 1;\n                rowUsed[x] = colUsed[y] = 1;\n            }\n            for (int x : unRow) {                         // remaining rows\n                int y = rowPref[obj][x];\n                if (find(Y.begin(), Y.end(), y) == Y.end()) y = Y[0];\n                occ[obj][idx(x, y, z)] = 1;\n            }\n        } else {                                          // -------- columns dominate\n            vector<int> unCol;\n            for (int y : Y) {\n                int x = colPref[obj][y];\n                if (find(X.begin(), X.end(), x) != X.end() && !rowUsed[x]) {\n                    occ[obj][idx(x, y, z)] = 1;\n                    rowUsed[x] = colUsed[y] = 1;\n                } else unCol.push_back(y);\n            }\n            for (int x : X) if (!rowUsed[x]) {\n                int y = unCol.back(); unCol.pop_back();\n                occ[obj][idx(x, y, z)] = 1;\n                rowUsed[x] = colUsed[y] = 1;\n            }\n            for (int y : unCol) {\n                int x = colPref[obj][y];\n                if (find(X.begin(), X.end(), x) == X.end()) x = X[0];\n                occ[obj][idx(x, y, z)] = 1;\n            }\n        }\n    };\n\n    for (int z = 0; z < D; ++z) {\n        build_slice(0, z);\n        build_slice(1, z);\n    }\n\n    /* ------------------------------------------------------------------ */\n    /* 3.  cut maximal vertical pillars                                  */\n    /* ------------------------------------------------------------------ */\n    vector<unique_ptr<Pillar>> store[2];\n    auto collect = [&](int obj) {\n        for (int x = 0; x < D; ++x) for (int y = 0; y < D; ++y) {\n            for (int z = 0; z < D; ) {\n                if (occ[obj][idx(x, y, z)]) {\n                    auto p = make_unique<Pillar>();\n                    while (z < D && occ[obj][idx(x, y, z)])\n                        p->vox.push_back(idx(x, y, z++));\n                    store[obj].push_back(std::move(p));\n                } else ++z;\n            }\n        }\n    };\n    collect(0);  collect(1);\n\n    priority_queue<Pillar*, vector<Pillar*>, CmpLen> Q[2];\n    for (auto& p : store[0]) Q[0].push(p.get());\n    for (auto& p : store[1]) Q[1].push(p.get());\n\n    /* ------------------------------------------------------------------ */\n    /* 4.  length-descending pairing                                     */\n    /* ------------------------------------------------------------------ */\n    vector<int> b1(SZ, 0), b2(SZ, 0);\n    int nextId = 1;\n    for (int L = D; L >= 1; --L) {\n        while (!Q[0].empty() && !Q[1].empty()\n               && Q[0].top()->len() >= L && Q[1].top()->len() >= L) {\n            Pillar* a = Q[0].top(); Q[0].pop();\n            Pillar* b = Q[1].top(); Q[1].pop();\n            int id = nextId++;\n            for (int i = 0; i < L; ++i) {\n                int pa = a->vox.back(); a->vox.pop_back();\n                int pb = b->vox.back(); b->vox.pop_back();\n                b1[pa] = id;  b2[pb] = id;\n            }\n            if (!a->vox.empty()) Q[0].push(a);\n            if (!b->vox.empty()) Q[1].push(b);\n        }\n    }\n\n    /* 5. leftover voxels become unique blocks -------------------------- */\n    for (int side = 0; side < 2; ++side) {\n        while (!Q[side].empty()) {\n            Pillar* p = Q[side].top(); Q[side].pop();\n            if (p->vox.empty()) continue;\n            int id = nextId++;\n            for (int pos : p->vox)\n                (side ? b2 : b1)[pos] = id;\n        }\n    }\n\n    /* 6. output -------------------------------------------------------- */\n    cout << nextId - 1 << '\\n';\n    for (int i = 0; i < SZ; ++i) {\n        if (i) cout << ' ';\n        cout << b1[i];\n    }\n    cout << '\\n';\n    for (int i = 0; i < SZ; ++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\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nusing ll = long long;\nconst int MAX_R = 5000;\nconst ll  INF64 = (1LL << 60);\n\ninline int ceilDist(int x1, int y1, int x2, int y2) {\n    long long dx = 1LL * x1 - x2, dy = 1LL * y1 - y2;\n    return int(std::ceil(std::sqrt(double(dx * dx + dy * dy))));\n}\nstruct Edge { int u, v; ll w; };\ninline int other(const Edge &e, int x) { return e.u == x ? e.v : e.u; }\n\nstruct DSU {\n    vector<int> p, sz;\n    explicit DSU(int n = 0): p(n), sz(n, 1) { iota(p.begin(), p.end(), 0); }\n    int  find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a; sz[a] += sz[b];\n        return true;\n    }\n};\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 main \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    /* vertices */\n    vector<int> vx(N), vy(N);\n    for (int i = 0; i < N; ++i) cin >> vx[i] >> vy[i];\n\n    /* edges */\n    vector<Edge> es(M);\n    vector<vector<pair<int,int>>> g(N);\n    for (int i = 0; i < M; ++i) {\n        int a, b; ll w; cin >> a >> b >> w; --a; --b;\n        es[i] = {a, b, w};\n        g[a].push_back({b, i});\n        g[b].push_back({a, i});\n    }\n\n    /* residents */\n    vector<int> rx(K), ry(K);\n    for (int k = 0; k < K; ++k) cin >> rx[k] >> ry[k];\n\n    /* dist(v, resident) \u2264 5000 */\n    vector<vector<int>> distVR(N, vector<int>(K, MAX_R + 1));\n    vector<vector<pair<int,int>>> cov(N);\n    for (int v = 0; v < N; ++v)\n        for (int k = 0; k < K; ++k) {\n            int d = ceilDist(vx[v], vy[v], rx[k], ry[k]);\n            distVR[v][k] = d;\n            if (d <= MAX_R) cov[v].push_back({k, d});\n        }\n\n    /* all-pairs shortest paths (100\u00d7Dijkstra) */\n    vector<vector<ll>> distVV(N, vector<ll>(N, INF64));\n    vector<vector<int>> parentE(N, vector<int>(N, -1));\n    using QEntry = pair<ll,int>;\n    for (int s = 0; s < N; ++s) {\n        auto &d  = distVV[s];\n        auto &pe = parentE[s];\n        priority_queue<QEntry, vector<QEntry>, greater<QEntry>> pq;\n        d[s] = 0; pq.push({0, s});\n        while (!pq.empty()) {\n            auto [du, u] = pq.top(); pq.pop();\n            if (du != d[u]) continue;\n            for (auto [to, idx] : g[u]) {\n                ll nd = du + es[idx].w;\n                if (nd < d[to]) { d[to] = nd; pe[to] = idx; pq.push({nd, to}); }\n            }\n        }\n    }\n    auto add_path = [&](int src, int dst, vector<char>& on) {\n        for (int v = dst; v != src; ) {\n            int e = parentE[src][v];\n            on[e] = 1;\n            v = other(es[e], v);\n        }\n    };\n\n    /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 greedy cover \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n    vector<char> chosen(N, 0);\n    chosen[0] = 1;                        // root always chosen\n\n    vector<char> covered(K, 0), edgeRootOn(M, 0);\n    auto addCostRootPath = [&](int v) {\n        ll c = 0;\n        for (int u = v; u != 0; ) {\n            int e = parentE[0][u];\n            if (!edgeRootOn[e]) c += es[e].w;\n            u = other(es[e], u);\n        }\n        return c;\n    };\n    int coveredCnt = 0;\n    while (coveredCnt < K) {\n        int bestV = -1, bestRad = 0;\n        double bestSc = -1;\n        for (int v = 0; v < N; ++v) if (!chosen[v]) {\n            int gain = 0, rad = 0;\n            for (auto [rid, d] : cov[v]) if (!covered[rid]) { ++gain; rad = max(rad, d); }\n            if (!gain) continue;\n            double sc = double(gain) / double(addCostRootPath(v) + 1LL * rad * rad);\n            if (sc > bestSc) { bestSc = sc; bestV = v; bestRad = rad; }\n        }\n        if (bestV == -1) break;\n        chosen[bestV] = 1;\n        for (auto [rid, d] : cov[bestV])\n            if (!covered[rid] && d <= bestRad) { covered[rid] = 1; ++coveredCnt; }\n        add_path(0, bestV, edgeRootOn);\n    }\n\n    /* assignment & radii */\n    vector<int> assign(K, -1), assignD(K, MAX_R + 1);\n    vector<vector<int>> resByV(N);\n    vector<int> radius(N, 0);\n    auto rebuild = [&](){\n        for (int v = 0; v < N; ++v) { resByV[v].clear(); radius[v] = 0; }\n        for (int k = 0; k < K; ++k) {\n            int bestV = -1, bestD = MAX_R + 1;\n            for (int v = 0; v < N; ++v) if (chosen[v]) {\n                int d = distVR[v][k];\n                if (d < bestD) { bestD = d; bestV = v; }\n            }\n            assign[k] = bestV; assignD[k] = bestD;\n            resByV[bestV].push_back(k);\n            radius[bestV] = max(radius[bestV], bestD);\n        }\n    };\n    rebuild();\n\n    /* cable builder for terminals (root+chosen) */\n    vector<char> edgeBuf(M);\n    auto cable_cost = [&](const vector<char>& chosenSet, vector<char>* out)->ll{\n        vector<char> term = chosenSet; term[0] = 1;\n        vector<int> terminals;\n        for (int v = 0; v < N; ++v) if (term[v]) terminals.push_back(v);\n        if (terminals.size() <= 1) { if (out) fill(out->begin(), out->end(), 0); return 0; }\n\n        int T = terminals.size();\n        vector<char> used(T, 0);\n        vector<ll>   best(T, INF64);\n        vector<int>  par(T, -1);\n        best[0] = 0;\n        vector<pair<int,int>> mst;\n        for (int it = 0; it < T; ++it) {\n            int v = -1;\n            for (int i = 0; i < T; ++i)\n                if (!used[i] && (v == -1 || best[i] < best[v])) v = i;\n            used[v] = 1;\n            if (par[v] != -1) mst.push_back({ terminals[v], terminals[par[v]] });\n            for (int j = 0; j < T; ++j) if (!used[j]) {\n                ll w = distVV[terminals[v]][terminals[j]];\n                if (w < best[j]) { best[j] = w; par[j] = v; }\n            }\n        }\n        vector<char> edgeOn(M, 0);\n        for (auto [a, b] : mst) add_path(a, b, edgeOn);\n\n        /* prune non-terminal leaves */\n        vector<vector<int>> adj(N);\n        vector<int> deg(N, 0);\n        for (int e = 0; e < M; ++e) if (edgeOn[e]) {\n            adj[es[e].u].push_back(e); adj[es[e].v].push_back(e);\n            ++deg[es[e].u]; ++deg[es[e].v];\n        }\n        queue<int> q;\n        for (int v = 0; v < N; ++v) if (deg[v] == 1 && !term[v]) q.push(v);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int ei : adj[v]) if (edgeOn[ei]) {\n                edgeOn[ei] = 0;\n                int u = other(es[ei], v);\n                if (--deg[u] == 1 && !term[u]) q.push(u);\n            }\n        }\n        ll cost = 0;\n        for (int e = 0; e < M; ++e) if (edgeOn[e]) cost += es[e].w;\n        if (out) *out = std::move(edgeOn);\n        return cost;\n    };\n\n    /* small local searches (time limited) */\n    auto startT = chrono::high_resolution_clock::now();\n\n    /* --- add-only --- */\n    while (true) {\n        int bestV = -1; ll bestDelta = 0;\n        ll radNow = 0; for (int v = 0; v < N; ++v) if (chosen[v]) radNow += 1LL * radius[v] * radius[v];\n\n        for (int cand = 0; cand < N; ++cand) if (!chosen[cand]) {\n            int radNew = 0; vector<int> moved;\n            for (auto [rid, d] : cov[cand])\n                if (d < assignD[rid]) { moved.push_back(rid); radNew = max(radNew, d); }\n            if (moved.empty()) continue;\n\n            vector<char> movedFlg(K, 0); for (int id : moved) movedFlg[id] = 1;\n            ll deltaRad = 1LL * radNew * radNew;\n            vector<int> touched;\n            for (int id : moved) {\n                int s = assign[id];\n                if (find(touched.begin(), touched.end(), s) == touched.end()) touched.push_back(s);\n            }\n            for (int s : touched) {\n                int newR = 0;\n                for (int rid : resByV[s]) if (!movedFlg[rid]) newR = max(newR, assignD[rid]);\n                deltaRad += 1LL * newR * newR - 1LL * radius[s] * radius[s];\n            }\n            ll edgeAdd = addCostRootPath(cand);\n            ll delta = deltaRad + edgeAdd;\n            if (delta < bestDelta) { bestDelta = delta; bestV = cand; }\n        }\n        if (bestV == -1) break;\n        chosen[bestV] = 1;\n        add_path(0, bestV, edgeRootOn);\n        for (auto [rid, d] : cov[bestV]) if (d < assignD[rid]) { assign[rid] = bestV; assignD[rid] = d; }\n        rebuild();\n        if (chrono::duration<double>(chrono::high_resolution_clock::now() - startT).count() > 1.4) break;\n    }\n\n    /* cable after additions */\n    vector<char> edgeNow;\n    ll cableNow = cable_cost(chosen, &edgeNow);\n\n    /* --- remove-if-beneficial --- */\n    while (true) {\n        ll radNow = 0; for (int v = 0; v < N; ++v) if (chosen[v]) radNow += 1LL * radius[v] * radius[v];\n        ll curTotal = radNow + cableNow;\n\n        int bestRem = -1; ll bestDelta = 0;\n        vector<int>  nAssign, nAssignD, nRadius;\n        vector<vector<int>> nResByV;\n\n        for (int cand = 1; cand < N; ++cand) if (chosen[cand]) { // never drop root\n            bool ok = true;\n            vector<int> a = assign, d = assignD;\n            for (int rid : resByV[cand]) {\n                int bestS = -1, bestD = MAX_R + 1;\n                for (int v = 0; v < N; ++v) if (chosen[v] && v != cand) {\n                    int dist = distVR[v][rid];\n                    if (dist <= MAX_R && dist < bestD) { bestD = dist; bestS = v; }\n                }\n                if (bestS == -1) { ok = false; break; }\n                a[rid] = bestS; d[rid] = bestD;\n            }\n            if (!ok) continue;\n\n            vector<vector<int>> rbv(N);\n            vector<int> rad(N, 0);\n            for (int k = 0; k < K; ++k) {\n                rbv[a[k]].push_back(k);\n                rad[a[k]] = max(rad[a[k]], d[k]);\n            }\n            vector<char> c2 = chosen; c2[cand] = 0;\n            ll radSum = 0; for (int v = 0; v < N; ++v) if (c2[v]) radSum += 1LL * rad[v] * rad[v];\n            ll cab = cable_cost(c2, nullptr);\n            ll delta = radSum + cab - curTotal;\n            if (delta < bestDelta) {\n                bestDelta = delta; bestRem = cand;\n                nAssign  = std::move(a);\n                nAssignD = std::move(d);\n                nRadius  = std::move(rad);\n                nResByV  = std::move(rbv);\n            }\n        }\n        if (bestRem == -1) break;\n        chosen[bestRem] = 0;\n        assign.swap(nAssign); assignD.swap(nAssignD);\n        radius.swap(nRadius); resByV.swap(nResByV);\n        cableNow = cable_cost(chosen, &edgeNow);\n        if (chrono::duration<double>(chrono::high_resolution_clock::now() - startT).count() > 1.9) break;\n    }\n\n    /* final powers */\n    vector<int> finalP(N, 0);\n    for (int v = 0; v < N; ++v) if (chosen[v]) finalP[v] = radius[v];\n\n    /* output */\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << finalP[i];\n    }\n    cout << '\\n';\n    for (int e = 0; e < M; ++e) {\n        if (e) cout << ' ';\n        cout << int(edgeNow[e]);\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Swap {\n    int x1, y1, x2, y2;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N = 30;\n    /* read input */\n    vector<vector<int>> a(N);\n    for (int x = 0; x < N; ++x) {\n        a[x].resize(x + 1);\n        for (int y = 0; y <= x; ++y) cin >> a[x][y];\n    }\n\n    vector<Swap> ops;\n    ops.reserve(5000);          // worst-case 4 495\n\n    auto do_swap = [&](int x1, int y1, int x2, int y2) {\n        swap(a[x1][y1], a[x2][y2]);\n        ops.push_back({x1, y1, x2, y2});\n    };\n\n    /* bottom-up heapify (Floyd) */\n    for (int x = N - 2; x >= 0; --x) {\n        for (int y = 0; y <= x; ++y) {\n            int cx = x, cy = y;\n            while (cx < N - 1) {\n                int lx = cx + 1, ly = cy;       // left child\n                int rx = cx + 1, ry = cy + 1;   // right child\n\n                int minx = lx, miny = ly;\n                if (a[rx][ry] < a[lx][ly]) {\n                    minx = rx;\n                    miny = ry;\n                }\n                if (a[cx][cy] <= a[minx][miny]) break;\n\n                do_swap(cx, cy, minx, miny);\n                cx = minx;\n                cy = miny;\n            }\n        }\n    }\n\n    /* safeguard \u2013 in the very unlikely event we overshoot */\n    if (ops.size() > 10000) ops.resize(10000);\n\n    /* output */\n    cout << ops.size() << '\\n';\n    for (auto &s: ops)\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ------------------------------------------------------------ */\nstruct Pos{ int r,c; };\nbool operator==(const Pos&a,const Pos&b){ return a.r==b.r && a.c==b.c; }\n\nconst int DR[4]={-1,1,0,0};\nconst int DC[4]={0,0,-1,1};\n\nusing Grid = vector<vector<int>>;           // -2 obstacle, -1 empty, \u22650 container id\nconstexpr int OBST  = -2;\nconstexpr int EMPTY = -1;\n\n/* ------------------------------------------------------------ */\ninline bool inside(int r,int c,int D){ return 0<=r && r<D && 0<=c && c<D; }\n\n/* ordinary BFS over EMPTY cells --------------------------------*/\nvector<Pos> bfs_empty(const Grid& g,const Pos& ent,\n                      vector<vector<int>>& dist)\n{\n    int D=g.size();\n    dist.assign(D, vector<int>(D,-1));\n    queue<Pos> q; q.push(ent); dist[ent.r][ent.c]=0;\n    vector<Pos> lst;\n\n    while(!q.empty()){\n        auto [r,c]=q.front(); q.pop();\n        lst.push_back({r,c});\n        for(int d=0;d<4;++d){\n            int nr=r+DR[d], nc=c+DC[d];\n            if(!inside(nr,nc,D) || g[nr][nc]!=EMPTY || dist[nr][nc]!=-1) continue;\n            dist[nr][nc]=dist[r][c]+1;\n            q.push({nr,nc});\n        }\n    }\n    return lst;\n}\n\n/* keep\u2013connectivity test (safety for retrieval) ----------------*/\nbool safe_to_place(Grid& g,const Pos& p,const Pos& ent,\n                   vector<vector<int>>& buf)\n{\n    g[p.r][p.c]=OBST;                        // temporarily block\n    bfs_empty(g,ent,buf);\n    bool ok=true;\n    for(int r=0;r<g.size()&&ok;++r)\n        for(int c=0;c<g.size();++c)\n            if(g[r][c]==EMPTY && buf[r][c]==-1){ ok=false; break; }\n    g[p.r][p.c]=EMPTY;                       // restore\n    return ok;\n}\n\n/* 0-1 BFS returning #blockers to every cell --------------------*/\nvoid bfs01(const Grid& g,const Pos& ent,\n           vector<vector<int>>& dist,\n           vector<vector<Pos>>& parent)\n{\n    int D=g.size();\n    dist.assign(D, vector<int>(D,INT_MAX));\n    parent.assign(D, vector<Pos>(D, {-1,-1}));\n\n    deque<Pos> dq; dq.push_front(ent);\n    dist[ent.r][ent.c]=0;\n\n    while(!dq.empty()){\n        auto v=dq.front(); dq.pop_front();\n        int cur=dist[v.r][v.c];\n\n        vector<Pos> zero, one;\n        for(int d=0;d<4;++d){\n            int nr=v.r+DR[d], nc=v.c+DC[d];\n            if(!inside(nr,nc,D) || g[nr][nc]==OBST) continue;\n            if(g[nr][nc]==EMPTY) zero.push_back({nr,nc});\n            else                 one .push_back({nr,nc});\n        }\n        sort(one.begin(), one.end(),\n             [&](const Pos&a,const Pos&b){ return g[a.r][a.c] < g[b.r][b.c]; });\n\n        auto relax=[&](const Pos& nxt,int w,bool front){\n            if(cur+w < dist[nxt.r][nxt.c]){\n                dist[nxt.r][nxt.c]=cur+w;\n                parent[nxt.r][nxt.c]=v;\n                if(front) dq.push_front(nxt); else dq.push_back(nxt);\n            }\n        };\n        for(const auto& n:zero) relax(n,0,true);\n        for(const auto& n:one ) relax(n,1,false);\n    }\n}\n\n/* ------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D,N; if(!(cin>>D>>N)) return 0;\n    const Pos ENTR{0,(D-1)/2};\n\n    Grid g(D, vector<int>(D,EMPTY));\n    for(int i=0;i<N;++i){\n        int r,c; cin>>r>>c; g[r][c]=OBST;\n    }\n    const int K=D*D-1-N;                   // number of containers\n\n    /* static distance for placement order ---------------------*/\n    vector<vector<int>> distStatic(D, vector<int>(D,-1));\n    {\n        queue<Pos> q; q.push(ENTR);\n        distStatic[ENTR.r][ENTR.c]=0;\n        while(!q.empty()){\n            auto [r,c]=q.front(); q.pop();\n            for(int d=0;d<4;++d){\n                int nr=r+DR[d], nc=c+DC[d];\n                if(!inside(nr,nc,D) || g[nr][nc]==OBST ||\n                   distStatic[nr][nc]!=-1) continue;\n                distStatic[nr][nc]=distStatic[r][c]+1;\n                q.push({nr,nc});\n            }\n        }\n    }\n\n    vector<Pos> idPos(K);                  // final square of each id\n    vector<vector<int>> buf1,buf2;\n    const double GAMMA=1.5;                // placement steepness\n\n    /* =================== placement phase =================== */\n    for(int step=0; step<K; ++step){\n        int id; cin>>id;\n\n        auto reachable=bfs_empty(g,ENTR,buf1);\n        reachable.erase(remove_if(reachable.begin(),reachable.end(),\n                         [&](const Pos&p){return p==ENTR;}),reachable.end());\n\n        vector<Pos> safe;\n        for(const auto&p:reachable)\n            if(safe_to_place(g,p,ENTR,buf2)) safe.push_back(p);\n        const auto& cand = safe.empty()? reachable : safe;\n\n        vector<Pos> cells=cand;\n        sort(cells.begin(),cells.end(),\n             [&](const Pos&a,const Pos&b){\n                 int da=distStatic[a.r][a.c], db=distStatic[b.r][b.c];\n                 return da!=db ? da<db : tie(a.r,a.c)<tie(b.r,b.c);\n             });\n\n        double q = pow( static_cast<double>(id)/(K-1) , GAMMA );\n        int idx  = cells.size()==1 ? 0\n                 : int(std::round(q*(cells.size()-1)));\n        idx = std::clamp(idx,0,(int)cells.size()-1);\n\n        Pos chosen=cells[idx];\n        g[chosen.r][chosen.c]=id;\n        idPos[id]=chosen;\n\n        cout<<chosen.r<<\" \"<<chosen.c<<\"\\n\"<<flush;\n    }\n\n    /* =================== retrieval phase =================== */\n    vector<char> shipped(K,0);\n    vector<Pos> answer; answer.reserve(K);\n    int nextNeed=0;\n\n    vector<vector<int>> dist01;\n    vector<vector<Pos>> parent01;\n\n    while(answer.size()<K){\n        while(nextNeed<K && shipped[nextNeed]) ++nextNeed;\n        if(nextNeed>=K) break;\n\n        bfs01(g,ENTR,dist01,parent01);\n\n        int dNeed = dist01[idPos[nextNeed].r][idPos[nextNeed].c];\n        if(dNeed==1){                               // already reachable\n            Pos p=idPos[nextNeed];\n            shipped[nextNeed]=1; g[p.r][p.c]=EMPTY;\n            answer.push_back(p);\n            ++nextNeed;\n            continue;\n        }\n\n        /* ---- 1) first blocker on one optimal path ---- */\n        vector<Pos> path;\n        for(Pos v=idPos[nextNeed]; !(v==ENTR); v=parent01[v.r][v.c])\n            path.push_back(v);\n        reverse(path.begin(),path.end());           // entrance \u2192 target\n\n        Pos blk{-1,-1}; int blkId=-1;\n        for(const auto& p:path)\n            if(g[p.r][p.c]>=0 && !shipped[g[p.r][p.c]]){\n                blk=p; blkId=g[p.r][p.c]; break;\n            }\n\n        /* ---- 2) smallest id among all currently reachable containers ---- */\n        int bestSmall = INT_MAX; Pos bestSmallPos{-1,-1};\n        for(int r=0;r<D;++r)for(int c=0;c<D;++c) if(g[r][c]>=0 && !shipped[g[r][c]]){\n            if(dist01[r][c]==1){                    // already reachable\n                int id=g[r][c];\n                if(id<bestSmall){ bestSmall=id; bestSmallPos={r,c}; }\n            }\n        }\n\n        /* ---- decide which one to ship ---- */\n        int shipId; Pos shipPos;\n        if(bestSmall<blkId){                       // prefer smaller reachable id\n            shipId = bestSmall; shipPos = bestSmallPos;\n        }else{\n            shipId = blkId; shipPos = blk;\n        }\n\n        shipped[shipId]=1; g[shipPos.r][shipPos.c]=EMPTY;\n        answer.push_back(shipPos);\n        if(shipId==nextNeed) ++nextNeed;\n    }\n\n    for(const auto& p:answer) cout<<p.r<<\" \"<<p.c<<\"\\n\";\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 50;     // fixed\nconstexpr int M = 100;\nconst int DX[4] = {-1, 1, 0, 0};\nconst int DY[4] = {0, 0, -1, 1};\n\nstruct State {\n    int  g[N][N];                 // current grid\n    int  cnt[M + 1]{};            // remaining cells per colour\n    int  adj[M + 1][M + 1]{};     // unordered edge counts, 0-based\n    bool orig0Adj[M + 1]{};       // was (0,c) adjacent in the input?\n    bool inQ[N][N]{};             // helper for the flood queue\n} st;\n\n/* --------------------------------------------------------------- */\ninline bool inside(int x, int y) { return 0 <= x && x < N && 0 <= y && y < N; }\n\ninline void addEdge(int a, int b, int delta) {\n    if (a > b) swap(a, b);\n    st.adj[a][b] += delta;\n#ifdef DEBUG\n    if (st.adj[a][b] < 0) cerr << \"negative edge \" << a << ' ' << b << '\\n';\n#endif\n}\n\n/* ------------ input & initial edge counters -------------------- */\nvoid buildInitial() {\n    int n, m;  cin >> n >> m;           // 50 / 100\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            cin >> st.g[i][j];\n            ++st.cnt[ st.g[i][j] ];\n        }\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int c = st.g[i][j];\n            int d = (j + 1 < N) ? st.g[i][j + 1] : 0;\n            if (c != d) addEdge(c, d, +1);\n            d = (i + 1 < N) ? st.g[i + 1][j] : 0;\n            if (c != d) addEdge(c, d, +1);\n        }\n\n    for (int c = 1; c <= M; ++c) st.orig0Adj[c] = st.adj[0][c] > 0;\n}\n\n/* ---------------- connectivity of one colour ------------------- */\nbool connectedAfterRemoval(int x, int y, int col) {\n    bool vis[N][N] = {};\n    queue<pair<int,int>> q;\n    for (int i = 0; i < N && q.empty(); ++i)\n        for (int j = 0; j < N; ++j)\n            if (st.g[i][j] == col && !(i == x && j == y)) {\n                q.emplace(i, j); vis[i][j] = true;\n                break;\n            }\n\n    int need = st.cnt[col] - 1, got = 0;\n    while (!q.empty()) {\n        auto [cx, cy] = q.front(); q.pop();\n        if (++got == need) return true;\n        for (int d = 0; d < 4; ++d) {\n            int nx = cx + DX[d], ny = cy + DY[d];\n            if (!inside(nx, ny) || vis[nx][ny] || (nx == x && ny == y)) continue;\n            if (st.g[nx][ny] == col) { vis[nx][ny] = true; q.emplace(nx, ny); }\n        }\n    }\n    return false;\n}\n\n/* ---------------- attempt to turn (x,y) into 0 ------------------ */\nbool tryRemove(int x, int y) {\n    int c = st.g[x][y];\n    if (c == 0 || st.cnt[c] == 1) return false;\n\n    int freq[M + 1] = {};               // how many sides to each neighbour colour\n    for (int d = 0; d < 4; ++d) {\n        int nx = x + DX[d], ny = y + DY[d];\n        int col = inside(nx, ny) ? st.g[nx][ny] : 0;\n        ++freq[col];\n    }\n\n    /* --- cheap legality tests ----------------------------------- */\n    for (int d = 1; d <= M; ++d) {\n        if (d == c || freq[d] == 0) continue;\n\n        if (!st.orig0Adj[d]) return false;                      // new 0-d edge forbidden\n\n        int a = min(c, d), b = max(c, d);\n        if (st.adj[a][b] - freq[d] <= 0) return false;         // last (c,d) edge gone\n    }\n    if (!connectedAfterRemoval(x, y, c)) return false;\n\n    /* --- update edge counters ----------------------------------- */\n    int f0   = freq[0];\n    int fSame= freq[c];\n\n    if (f0   ) addEdge(0, c, -f0);        // c \u2013 0 edges disappear\n    if (fSame) addEdge(0, c, +fSame);     // new 0 \u2013 c edges where neighbour is c\n\n    for (int d = 1; d <= M; ++d) if (d != c && freq[d]) {\n        addEdge(c, d, -freq[d]);          // erase (c,d)\n        addEdge(0, d, +freq[d]);          // add (0,d)\n    }\n\n    /* --- materialise the deletion ------------------------------- */\n    st.g[x][y] = 0;\n    --st.cnt[c];\n    return true;\n}\n\n/* ---------------- flood-queue driver ---------------------------- */\ninline bool touchesZero(int i, int j) {\n    if (st.g[i][j] == 0) return false;\n    for (int d = 0; d < 4; ++d) {\n        int ni = i + DX[d], nj = j + DY[d];\n        if (!inside(ni, nj) || st.g[ni][nj] == 0) return true;\n    }\n    return false;\n}\n\nvoid flood() {\n    queue<pair<int,int>> q;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (touchesZero(i, j)) { q.emplace(i, j); st.inQ[i][j] = true; }\n\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        st.inQ[x][y] = false;\n        if (st.g[x][y] == 0 || !touchesZero(x, y)) continue;\n\n        if (tryRemove(x, y)) {\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + DX[d], ny = y + DY[d];\n                if (!inside(nx, ny) || st.g[nx][ny] == 0 || st.inQ[nx][ny]) continue;\n                if (touchesZero(nx, ny)) { q.emplace(nx, ny); st.inQ[nx][ny] = true; }\n            }\n        }\n    }\n}\n\n/* ---------------- main ------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    buildInitial();\n    flood();\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (j) cout << ' ';\n            cout << st.g[i][j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- small utilities ---------- */\nstruct FastRNG {\n    uint64_t x;\n    FastRNG() : x(chrono::steady_clock::now().time_since_epoch().count()) {}\n    uint32_t next() { x ^= x << 7; return (uint32_t)(x ^= x >> 9); }\n    template<class It> void shuffle(It first, It last){\n        for(auto i = (last-first); i>1; --i){\n            int j = next()%i;\n            swap(*(first+i-1), *(first+j));\n        }\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------------- read first line ---------------- */\n    int N,D,Q;\n    if(!(cin>>N>>D>>Q)) return 0;\n\n    /* ---------------- Bradley\u2013Terry / Elo ----------------\n       rating r_i  (real numbers)\n       P(i beats j) = 1 / (1+exp(-(r_i-r_j)))\n       update with learning-rate K   r += K*(S - P)\n    ------------------------------------------------------ */\n    const double K = 1.6;              // slightly aggressive\n    vector<double> rating(N, 0.0);\n\n    /* ---------------- schedule comparisons ------------- */\n    vector<pair<int,int>> pairs;\n    pairs.reserve(N*(N-1)/2);\n    for(int i=0;i<N;++i) for(int j=i+1;j<N;++j) pairs.emplace_back(i,j);\n\n    FastRNG rng;\n    rng.shuffle(pairs.begin(), pairs.end());\n\n    /* ---------------- perform informative queries ------ */\n    int used = 0, idx = 0;\n    auto ask = [&](int a,int b){\n        cout << 1 << ' ' << 1 << ' ' << a << ' ' << b << '\\n' << flush;\n        string res; cin >> res;\n        ++used;\n        if(res==\">\"||res==\"<\"){                // ignore '=' (practically never happens)\n            bool aWins = (res==\">\");\n            double ra = rating[a], rb = rating[b];\n            double p  = 1.0 / (1.0 + exp(rb - ra));\n            double diff = K * ((aWins?1.0:0.0) - p);\n            rating[a] += diff;\n            rating[b] -= diff;\n        }\n    };\n\n    while(used < Q && idx < (int)pairs.size()){\n        auto [a,b] = pairs[idx++];\n        ask(a,b);\n    }\n    /* -------------- consume possible leftover queries -- */\n    while(used < Q){ ask(0,1); }        // ignored but fulfils protocol\n\n    /* ---------------- derive positive weights ---------- */\n    double mn = *min_element(rating.begin(), rating.end());\n    vector<double> w(N);\n    for(int i=0;i<N;++i) w[i] = rating[i]-mn + 1e-3;   // >0\n\n    /* ---------------- initial greedy LPT --------------- */\n    struct Bag{ double sum=0; vector<int> items; };\n    vector<Bag> bag(D);\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a,int b){ return w[a]>w[b]; });\n\n    vector<int> belong(N);\n    for(int id:ord){\n        int best=0;\n        for(int d=1;d<D;++d)\n            if(bag[d].sum < bag[best].sum) best=d;\n        bag[best].items.push_back(id);\n        bag[best].sum += w[id];\n        belong[id]=best;\n    }\n\n    /* --------------- local improvement -----------------\n       objective  f = \u03a3  sum_d^2   (mean is fixed)         */\n    auto obj = [&](){ double v=0; for(auto &b:bag) v+=b.sum*b.sum; return v; };\n    double bestScore = obj();\n    bool improved=true; int iter=0;\n    while(improved && ++iter<4000){             // safeguard iterations\n        improved=false;\n        /* --- single moves --- */\n        for(int i=0;i<N;++i){\n            int a = belong[i];\n            double wa = w[i], sa = bag[a].sum;\n            double base = bestScore - sa*sa;\n            for(int b=0;b<D;++b) if(b!=a){\n                double sb = bag[b].sum;\n                double newScore = base - sb*sb\n                                   + (sa-wa)*(sa-wa) + (sb+wa)*(sb+wa);\n                if(newScore + 1e-9 < bestScore){\n                    /* apply */\n                    bag[a].sum -= wa;\n                    bag[b].sum += wa;\n                    belong[i]=b; improved=true;\n                    bestScore=newScore;\n                    goto next_iter;\n                }\n            }\n        }\n        /* --- pair swaps --- */\n        for(int i=0;i<N;++i) for(int j=i+1;j<N;++j)\n            if(belong[i]!=belong[j]){\n                int a=belong[i], b=belong[j];\n                double wi=w[i], wj=w[j];\n                double sa=bag[a].sum, sb=bag[b].sum;\n\n                double base = bestScore - sa*sa - sb*sb;\n                double newSa = sa - wi + wj;\n                double newSb = sb - wj + wi;\n                double newScore = base + newSa*newSa + newSb*newSb;\n                if(newScore + 1e-9 < bestScore){\n                    swap(belong[i], belong[j]);\n                    bag[a].sum = newSa;\n                    bag[b].sum = newSb;\n                    improved=true; bestScore=newScore;\n                    goto next_iter;\n                }\n            }\n        next_iter:;\n    }\n\n    /* -------------------- output division -------------- */\n    for(int i=0;i<N;++i){\n        if(i) cout << ' ';\n        cout << belong[i];\n    }\n    cout << '\\n' << flush;\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** fixed problem parameters ********************************************/\nusing  u8 = uint8_t;\nusing  pii = pair<int,int>;\n\nconstexpr int N       = 200;          // boxes\nconstexpr int M       = 10;           // stacks\nconstexpr int H0      = N / M;        // initial height (=20)\nconstexpr int MAXH    = N;            // maximal height of any stack\nconstexpr int MAX_OPS = 400;          // 2 per box\n\n/*-----------------------------------------------------------------------*/\nstruct Sol {\n    int             energy = INT_MAX;\n    array<pii,MAX_OPS> ops{};\n    int             opCnt = 0;\n};\n\n/*** fast multi-start greedy *********************************************/\nSol greedySolver(const array<array<u8,H0>,M>& init,\n                 mt19937& rng, int Ptop, int Wsz, bool randomTie)\n{\n    auto rnd3 = [&](){ return uniform_int_distribution<int>(0,3)(rng); };\n\n    array<vector<u8>,M> st;\n    for (int i=0;i<M;++i)\n        st[i].assign(init[i].begin(), init[i].end());\n\n    Sol sol; sol.energy = 0;\n    int opPtr = 0;\n\n    for (int v=1; v<=N; ++v) {\n        int s=-1, idx=-1;\n        for (int i=0;i<M && s==-1;++i)\n            for (int j=0;j<(int)st[i].size();++j)\n                if (st[i][j]==v){s=i; idx=j; break;}\n\n        if (idx == (int)st[s].size()-1) {        // on top\n            sol.ops[opPtr++] = {v,0};\n            st[s].pop_back();\n            continue;\n        }\n\n        vector<u8> seg(st[s].begin()+idx+1, st[s].end());\n        int segSz = (int)seg.size();\n        int segCost = segSz + 1;\n        int segMax  = *max_element(seg.begin(), seg.end());\n        st[s].resize(idx+1);\n\n        int bestScore = INT_MAX, dest = -1;\n        for (int t=0;t<M;++t) if (t!=s) {\n            int bp=0;\n            for (u8 y:seg) for (u8 x:st[t]) if (y>x) ++bp;\n\n            int score = bp * segCost;\n            if (!st[t].empty() && st[t].back() < segMax)\n                score += segCost * Ptop;\n\n            score += (int)st[t].size() * Wsz;\n            if (randomTie) score += rnd3();\n\n            if (score < bestScore){ bestScore = score; dest = t; }\n        }\n\n        st[dest].insert(st[dest].end(), seg.begin(), seg.end());\n        sol.energy += segCost;\n        sol.ops[opPtr++] = {seg.front(), dest+1};\n\n        st[s].pop_back();                         // remove v\n        sol.ops[opPtr++] = {v,0};\n    }\n    sol.opCnt = opPtr;\n    return sol;\n}\n\n/*** helper for beam search **********************************************/\ninline int adjBad(const array<u8,MAXH>& s, int sz){\n    int c=0; for(int i=1;i<sz;++i) if(s[i-1]<s[i]) ++c; return c;\n}\n\n/*** single beam-search run **********************************************/\nstruct State{\n    array<array<u8,MAXH>,M> st{};\n    array<u8,M>             h{};\n    int                     energy=0, bad=0;\n    array<pii,MAX_OPS>      ops{};\n    int                     opCnt=0;\n    int score(int W) const { return energy + W*bad; }\n};\n\nSol beamSolver(const array<array<u8,H0>,M>& init, int heurW, int beamW)\n{\n    State root;\n    for (int i=0;i<M;++i){\n        copy(begin(init[i]), end(init[i]), begin(root.st[i]));\n        root.h[i]=H0;\n        root.bad+=adjBad(root.st[i],H0);\n    }\n\n    vector<State> beam{root}, nxt;\n\n    for (int v=1; v<=N; ++v){\n        nxt.clear();\n        for (const State& cur : beam){\n            int s=-1, idx=-1;\n            for(int i=0;i<M && s==-1;++i)\n                for(int j=0;j<cur.h[i];++j)\n                    if(cur.st[i][j]==v){s=i; idx=j; break;}\n\n            if(idx==cur.h[s]-1){                 // on top\n                State ch=cur;\n                --ch.h[s];\n                ch.bad-=adjBad(ch.st[s],ch.h[s]+1);\n                ch.bad+=adjBad(ch.st[s],ch.h[s]);\n                ch.ops[ch.opCnt++]={v,0};\n                nxt.emplace_back(move(ch));\n                continue;\n            }\n\n            int segSz=cur.h[s]-idx-1;\n            array<u8,MAXH> seg{};\n            for(int k=0;k<segSz;++k) seg[k]=cur.st[s][idx+1+k];\n            u8 firstMoved=seg[0];\n\n            for(int d=0; d<M; ++d) if(d!=s){\n                State ch=cur;\n\n                /* detach */\n                ch.bad-=adjBad(ch.st[s],ch.h[s]);\n                ch.h[s]=idx+1;\n                ch.bad+=adjBad(ch.st[s],ch.h[s]);\n\n                /* attach */\n                ch.bad-=adjBad(ch.st[d],ch.h[d]);\n                int dh=ch.h[d];\n                for(int k=0;k<segSz;++k) ch.st[d][dh+k]=seg[k];\n                ch.h[d]=dh+segSz;\n                ch.bad+=adjBad(ch.st[d],ch.h[d]);\n\n                ch.energy+=segSz+1;\n                ch.ops[ch.opCnt++]={firstMoved,d+1};\n\n                /* carry out v */\n                --ch.h[s];\n                ch.bad-=adjBad(ch.st[s],ch.h[s]+1);\n                ch.bad+=adjBad(ch.st[s],ch.h[s]);\n                ch.ops[ch.opCnt++]={v,0};\n\n                nxt.emplace_back(move(ch));\n            }\n        }\n        int keep=min(beamW,(int)nxt.size());\n        nth_element(nxt.begin(),nxt.begin()+keep,nxt.end(),\n                    [=](const State&a,const State&b){return a.score(heurW)<b.score(heurW);});\n        nxt.resize(keep);\n        beam.swap(nxt);\n    }\n\n    const State* best=&*min_element(beam.begin(),beam.end(),\n                        [](const State&a,const State&b){return a.energy<b.energy;});\n    Sol sol;\n    sol.energy=best->energy;\n    sol.opCnt =best->opCnt;\n    sol.ops   =best->ops;\n    return sol;\n}\n\n/*** MAIN *****************************************************************/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n,m; if(!(cin>>n>>m)) return 0;\n    array<array<u8,H0>,M> init{};\n    for(int i=0;i<M;++i)\n        for(int j=0;j<H0;++j){int x;cin>>x;init[i][j]=u8(x);}\n\n    mt19937 rng(1234567);\n\n    auto ms = [](auto d){return chrono::duration_cast<chrono::milliseconds>(d).count();};\n    auto t0 = chrono::steady_clock::now();\n\n    Sol best = greedySolver(init,rng,18,1,false);   // deterministic baseline\n\n    /* Phase 1: greedy multi-start (until 0.8 s) */\n    while (ms(chrono::steady_clock::now()-t0) < 800){\n        int P  = uniform_int_distribution<int>(12,30)(rng);\n        int Ws = uniform_int_distribution<int>(0,4)(rng);\n        Sol cand = greedySolver(init,rng,P,Ws,true);\n        if (cand.energy < best.energy) best = move(cand);\n    }\n\n    /* Phase 2: beam search variants (until 1.9 s) */\n    vector<int> widths  = {80,100,120,140};\n    vector<int> weights = {2,3,4,5,6,7};\n    size_t wi=0, we=0;\n    while (ms(chrono::steady_clock::now()-t0) < 1850){\n        int BW = widths[wi]; int W = weights[we];\n        wi=(wi+1)%widths.size(); we=(we+1)%weights.size();\n        Sol cand = beamSolver(init,W,BW);\n        if (cand.energy < best.energy) best = move(cand);\n    }\n\n    for(int i=0;i<best.opCnt;++i)\n        cout<<best.ops[i].first<<' '<<best.ops[i].second<<'\\n';\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** constants and helpers ***************************************************/\nconst int DX[4] = {0, 1, 0, -1};\nconst int DY[4] = {1, 0, -1, 0};\nconst char DC[4] = {'R', 'D', 'L', 'U'};\n\nstruct Board {\n    int N;\n    vector<string> h;          // wall to down : size N-1, length N\n    vector<string> v;          // wall to right: size N  , length N-1\n    vector<int>     d;         // susceptibility flattened\n    inline bool inside(int x,int y) const { return 0<=x && x<N && 0<=y && y<N; }\n    inline bool canMove(int x,int y,int dir) const {\n        if(dir==0) return y+1<N && v[x][y]=='0';\n        if(dir==1) return x+1<N && h[x][y]=='0';\n        if(dir==2) return y-1>=0 && v[x][y-1]=='0';\n        return            x-1>=0 && h[x-1][y]=='0';\n    }\n} B;\n\n/*** data for optimisation ***************************************************/\nint N, LIM = 100000;\n\nvector<int> bounceDir;         // favourite neighbour of each cell\nvector<int> bounceTo;          // its index\nvector<int> loopsNeeded;       // how many extra loops finally allocated\n\nstring basePath;               // Euler tour without extra loops\nstring answer;                 // final route\n\n/*** building the Euler tour *************************************************/\nvector<vector<int>> visited;\nvoid dfsEuler(int x,int y)\n{\n    visited[x][y]=1;\n    for(int dir=0;dir<4;dir++){\n        int nx=x+DX[dir], ny=y+DY[dir];\n        if(!B.inside(nx,ny) || visited[nx][ny]) continue;\n        if(!B.canMove(x,y,dir)) continue;\n        basePath.push_back(DC[dir]);\n        dfsEuler(nx,ny);\n        basePath.push_back(DC[(dir+2)%4]);\n    }\n}\n\n/*** simulate any given path to count visits *********************************/\nvector<int> countVisits(const string& p)\n{\n    vector<int> v(N*N,0);\n    int x=0,y=0;\n    for(char c:p){\n        int dir = (c=='R'?0:c=='D'?1:c=='L'?2:3);\n        x += DX[dir]; y += DY[dir];\n        v[x*N+y]++;\n    }\n    return v;\n}\n\n/*** choose bounce neighbour (highest d) *************************************/\nvoid prepareBounce()\n{\n    bounceDir.assign(N*N,0);\n    bounceTo .assign(N*N,0);\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++){\n        int bestDir=-1, bestD=-1;\n        for(int dir=0;dir<4;dir++){\n            if(!B.canMove(x,y,dir)) continue;\n            int nx=x+DX[dir], ny=y+DY[dir];\n            int nd = B.d[nx*N+ny];\n            if(nd>bestD){ bestD=nd; bestDir=dir; }\n        }\n        bounceDir[x*N+y]=bestDir;\n        bounceTo [x*N+y]=(x+DX[bestDir])*N + (y+DY[bestDir]);\n    }\n}\n\n/*** greedy allocation of useful loops ***************************************/\nvoid allocateLoops(vector<int>& visit)\n{\n    loopsNeeded.assign(N*N,0);\n    long long L = (long long)basePath.size();             // current length\n    double R = 0;                                         // \u03a3 d / v\n    for(int i=0;i<N*N;i++) R += (double)B.d[i] / visit[i];\n\n    using Node = pair<double,int>;                        // (benefit, id)\n    priority_queue<Node> pq;\n    for(int i=0;i<N*N;i++){\n        int j=bounceTo[i];\n        double benefit = (double)B.d[i]/(visit[i]*(visit[i]+1))\n                       + (double)B.d[j]/(visit[j]*(visit[j]+1));\n        pq.emplace(benefit,i);\n    }\n\n    while(L+2 <= LIM){\n        double threshold = 2.0 * R / (L+2);               // need benefit > thresh\n        auto [benefit,id] = pq.top(); pq.pop();\n        int i=id, j=bounceTo[i];\n        // recompute real current benefit\n        benefit = (double)B.d[i]/(visit[i]*(visit[i]+1))\n                + (double)B.d[j]/(visit[j]*(visit[j]+1));\n        if(benefit < threshold - 1e-12){                  // no further improvement\n            break;\n        }\n        /* perform the loop */\n        loopsNeeded[i]++;  L += 2;\n        R -= (double)B.d[i]/visit[i] - (double)B.d[i]/(visit[i]+1);\n        R -= (double)B.d[j]/visit[j] - (double)B.d[j]/(visit[j]+1);\n        visit[i]++;  visit[j]++;\n\n        /* push updated entries (lazy) */\n        double newBenefitI = (double)B.d[i]/(visit[i]*(visit[i]+1))\n                           + (double)B.d[j]/(visit[j]*(visit[j]+1));\n        pq.emplace(newBenefitI,i);\n        double newBenefitJ = (double)B.d[j]/(visit[j]*(visit[j]+1))\n                           + (double)B.d[bounceTo[j]]/(visit[bounceTo[j]]*(visit[bounceTo[j]]+1));\n        pq.emplace(newBenefitJ,j);\n    }\n}\n\n/*** produce the final route **************************************************/\nvector<int> loopsRemain;\nstring outPath;\nint curX=0,curY=0;\n\nvoid emitMove(int dir)\n{\n    outPath.push_back(DC[dir]);\n    curX += DX[dir]; curY += DY[dir];\n}\n\nvoid emitBounce(int id)            // perform ONE back-and-forth loop\n{\n    int dir = bounceDir[id];\n    emitMove(dir);\n    emitMove((dir+2)%4);\n}\n\nvoid maybeBounce(int id)           // at most one loop here\n{\n    if(loopsRemain[id]>0){\n        loopsRemain[id]--;\n        emitBounce(id);\n    }\n}\n\nvector<vector<int>> vis2;\nvoid dfsFinal(int x,int y)\n{\n    int id = x*N+y;\n    vis2[x][y]=1;\n    maybeBounce(id);\n    for(int dir=0;dir<4;dir++){\n        int nx=x+DX[dir], ny=y+DY[dir];\n        if(!B.inside(nx,ny) || vis2[nx][ny]) continue;\n        if(!B.canMove(x,y,dir)) continue;\n        emitMove(dir);\n        dfsFinal(nx,ny);\n        emitMove((dir+2)%4);\n        maybeBounce(id);\n    }\n    while(loopsRemain[id]>0) {     // finish leftovers, very small number\n        loopsRemain[id]--;\n        emitBounce(id);\n    }\n}\n\n/*** main ********************************************************************/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* input */\n    cin>>N;  B.N=N;\n    B.h.resize(N-1); for(int i=0;i<N-1;i++) cin>>B.h[i];\n    B.v.resize(N);   for(int i=0;i<N;i++)   cin>>B.v[i];\n    B.d.resize(N*N);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) cin>>B.d[i*N+j];\n\n    /* step 1: base Euler tour */\n    visited.assign(N,vector<int>(N,0));\n    dfsEuler(0,0);\n\n    /* step 2: initial visits & bounce neighbour */\n    vector<int> visit = countVisits(basePath);        // size N*N\n    prepareBounce();\n\n    /* step 3: greedy extra loops only while useful */\n    allocateLoops(visit);\n\n    /* step 4: build the final route */\n    loopsRemain = loopsNeeded;\n    vis2.assign(N,vector<int>(N,0));\n    dfsFinal(0,0);\n\n    /* output */\n    cout << outPath << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*---------------------------------------------------------------*/\nstruct Pos{int r,c;};\ninline int manhattan(const Pos&a,const Pos&b){\n    return abs(a.r-b.r)+abs(a.c-b.c);\n}\n\n/*----------------  helper for sentinel edges  ------------------*/\nstruct EdgeCost{\n    const vector<int>& start;           // startCost\n    const int (*e)[200];                // edge[i][j]\n    int operator()(int prev,int nxt)const{\n        if(nxt==-2) return 0;           // end\n        if(prev==-1) return start[nxt]; // start\n        return e[prev][nxt];\n    }\n};\n\n/*================================================================*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /*----------------  read input  ------------------------------*/\n    int N,M;           // N=15, M=200\n    if(!(cin>>N>>M)) return 0;\n    int si,sj; cin>>si>>sj;\n    vector<string> G(N);\n    for(int i=0;i<N;++i) cin>>G[i];\n    vector<string> w(M);               // lucky words\n    for(int i=0;i<M;++i) cin>>w[i];\n\n    /*----------------  letter positions ------------------------*/\n    array<vector<Pos>,26> at;\n    for(int r=0;r<N;++r)\n        for(int c=0;c<N;++c)\n            at[G[r][c]-'A'].push_back({r,c});\n\n    /*----------------  letter\u2012letter distance ------------------*/\n    int dChr[26][26];\n    for(int a=0;a<26;++a)\n        for(int b=0;b<26;++b){\n            int best=1e9;\n            for(auto &p:at[a])\n                for(auto &q:at[b])\n                    best=min(best,manhattan(p,q));\n            dChr[a][b]=best;\n        }\n    /* distance from start square to first letter */\n    int dStart[26];\n    for(int a=0;a<26;++a){\n        int best=1e9;\n        for(auto &p:at[a])\n            best=min(best,abs(p.r-si)+abs(p.c-sj));\n        dStart[a]=best;\n    }\n\n    /*----------------  per-word information --------------------*/\n    vector<int> fst(M),lst(M);\n    for(int i=0;i<M;++i){\n        fst[i]=w[i][0]-'A';\n        lst[i]=w[i][4]-'A';\n    }\n\n    /* overlap length & edge cost (travel + new keys) */\n    static uint8_t ov[200][200];\n    static int     edge[200][200];\n    for(int i=0;i<M;++i)\n        for(int j=0;j<M;++j){\n            int best=0;\n            for(int l=4;l>=1;--l)\n                if(equal(w[i].end()-l,w[i].end(),w[j].begin())){\n                    best=l; break;\n                }\n            ov[i][j]=best;\n            int nxtLetter=w[j][best]-'A';               // first *new* letter\n            edge[i][j]=dChr[lst[i]][nxtLetter]+(5-best);\n        }\n    vector<int> startC(M);\n    for(int i=0;i<M;++i) startC[i]=dStart[fst[i]]+5;\n\n    EdgeCost E{startC,edge};\n\n    /*----------------  greedy initial permutation --------------*/\n    vector<int> ord; ord.reserve(M);\n    vector<char> used(M,0);\n    int cur=-1;\n    while((int)ord.size()<M){\n        int best=-1,bestVal=1e9;\n        for(int i=0;i<M;++i) if(!used[i]){\n            int v=E(cur,i);\n            if(v<bestVal){bestVal=v;best=i;}\n        }\n        ord.push_back(best); used[best]=1; cur=best;\n    }\n\n    /*----------------  helper: tour cost  ----------------------*/\n    auto tourCost=[&](const vector<int>&v){\n        int c=E(-1,v[0]);\n        for(int i=1;i<M;++i) c+=E(v[i-1],v[i]);\n        return c;\n    };\n    int curCost=tourCost(ord), bestCost=curCost;\n    vector<int> bestOrd=ord;\n\n    /*----------------  \u0394-cost helpers  -------------------------*/\n    auto swapDelta=[&](const vector<int>& v,int a,int b)->int{\n        if(a>b) swap(a,b);\n        int preA = (a==0)? -1 : v[a-1];\n        int nxtA = (a+1<M)? v[a+1]: -2;\n        int preB = (b==0)? -1 : v[b-1];\n        int nxtB = (b+1<M)? v[b+1]: -2;\n        int A=v[a], B=v[b];\n\n        if(a+1==b){          // adjacent\n            int old = E(preA,A)+E(A,B)+E(B,nxtB);\n            int neu = E(preA,B)+E(B,A)+E(A,nxtB);\n            return neu-old;\n        }else{\n            int old = E(preA,A)+E(A,nxtA)+E(preB,B)+E(B,nxtB);\n            int neu = E(preA,B)+E(B,nxtA)+E(preB,A)+E(A,nxtB);\n            return neu-old;\n        }\n    };\n\n    auto insertDelta=[&](const vector<int>&v,int from,int to)->int{\n        // remove position 'from', insert AFTER position 'to'\n        if(from==to || from==to+1) return 0; // no real move\n        int preF = (from==0)? -1 : v[from-1];\n        int nxtF = (from+1<M)? v[from+1]: -2;\n        int node = v[from];\n\n        int dst = v[ to + (from<to?0: (from>to?0:0)) ]; // original index of dest node\n        int nxtD = ( (from<to? to+1 : to+1) < M ) ? v[to+1] : -2;\n        if(from<to){ nxtD = (to+1<M)? v[to+1] : -2; }\n        else        { nxtD = (to+1<M)? v[to+1] : -2; }\n\n        int old = E(preF,node)+E(node,nxtF)+E(dst,nxtD);\n        int neu = E(preF,nxtF)+E(dst,node)+E(node,nxtD);\n        return neu-old;\n    };\n\n    /*----------------  Simulated Annealing  --------------------*/\n    std::mt19937 rng((uint32_t)\n        chrono::steady_clock::now().time_since_epoch().count());\n    const double T0=3000.0, Tend=1e-3, TIME=1.9;\n    auto t0=chrono::steady_clock::now();\n    uniform_real_distribution<double> R01(0.0,1.0);\n\n    while( chrono::duration<double>(chrono::steady_clock::now()-t0).count() < TIME){\n        double prog = chrono::duration<double>(chrono::steady_clock::now()-t0).count()/TIME;\n        double temp = T0*pow(Tend/T0,prog);\n\n        if(rng()&1){                              /* swap */\n            int a = rng()%M, b = rng()%M;\n            if(a==b) continue;\n            int d = swapDelta(ord,a,b);\n            if(d<0 || R01(rng) < exp(-d/temp)){\n                curCost += d;\n                swap(ord[a],ord[b]);\n                if(curCost<bestCost){bestCost=curCost;bestOrd=ord;}\n            }\n        }else{                                    /* insertion */\n            int from = rng()%M, to = rng()%M;\n            if(from==to||from==to+1) continue;\n            int d = insertDelta(ord,from,to);\n            if(d==0) continue;\n            if(d<0 || R01(rng) < exp(-d/temp)){\n                curCost += d;\n                int node = ord[from];\n                ord.erase(ord.begin()+from);\n                if(from<to) --to;\n                ord.insert(ord.begin()+to+1,node);   // after 'to'\n                if(curCost<bestCost){bestCost=curCost;bestOrd=ord;}\n            }\n        }\n    }\n    ord.swap(bestOrd);\n\n    /*----------------  build final string ---------------------*/\n    string S = w[ord[0]];\n    for(int i=1;i<M;++i){\n        int l = ov[ord[i-1]][ord[i]];\n        S += w[ord[i]].substr(l);\n    }\n    const int L = (int)S.size();\n\n    /*----------------  exact DP for finger path ---------------*/\n    const int BIG=1e9;\n    vector<vector<int>> dp(L);\n    vector<vector<uint16_t>> prv(L);\n    vector<int> bestIdx(L);\n\n    /* layer 0 */\n    {\n        int ch=S[0]-'A';\n        int sz=at[ch].size();\n        dp[0].assign(sz,BIG); prv[0].assign(sz,0);\n        for(int k=0;k<sz;++k)\n            dp[0][k]=manhattan({si,sj},at[ch][k])+1;\n        bestIdx[0]=min_element(dp[0].begin(),dp[0].end())-dp[0].begin();\n    }\n    for(int i=1;i<L;++i){\n        int a=S[i-1]-'A', b=S[i]-'A';\n        int szA=at[a].size(), szB=at[b].size();\n        dp[i].assign(szB,BIG); prv[i].assign(szB,0);\n        for(int k=0;k<szB;++k){\n            int best=BIG, bestj=0;\n            for(int j=0;j<szA;++j){\n                int cand=dp[i-1][j]+manhattan(at[a][j],at[b][k])+1;\n                if(cand<best){best=cand;bestj=j;}\n            }\n            dp[i][k]=best; prv[i][k]=bestj;\n        }\n        bestIdx[i]=min_element(dp[i].begin(),dp[i].end())-dp[i].begin();\n    }\n\n    /* back-track */\n    vector<Pos> path(L);\n    int idx=bestIdx.back();\n    for(int i=L-1;i>=0;--i){\n        int ch=S[i]-'A';\n        path[i]=at[ch][idx];\n        if(i) idx=prv[i][idx];\n    }\n\n    /*----------------  output -------------------------------*/\n    for(auto &p:path) cout<<p.r<<' '<<p.c<<'\\n';\n    return 0;\n}","ahc030":"//  AHC030 \u2013 unique solution via placement elimination + DFS\n//  compile: g++ -std=c++20 -O2 -pipe -static -s main.cpp\n//------------------------------------------------------------------\n#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastIO{ FastIO(){ ios::sync_with_stdio(false); cin.tie(nullptr); }} fio;\n\n//------------------------------------------------------------------\nstruct Placement{ vector<int> cells; };\n\nstruct Field{ vector<Placement> plc; };\n\nint N, M, NN, maxQueries;\ndouble EPS;\n\nvector<Field> fields;\nint queryCnt = 0;\nvector<int> drilled;                 // -1 unknown, >=0 exact v(i,j)\nvector<char> isOil;                  // squares already proven to contain oil\n//------------------------------------------------------------------\ninline void flush(){ cout << '\\n' << flush; }\ninline pair<int,int> id2ij(int id){ return {id / N, id % N}; }\n\nint drill(int id)\n{\n    auto [i,j] = id2ij(id);\n    cout << \"q 1 \" << i << ' ' << j; flush();\n    int v; cin >> v;\n    ++queryCnt;\n    drilled[id] = v;\n    if (v) isOil[id] = 1;\n    return v;\n}\n//------------------------------------------------------------------\nvoid eliminateZero(int id0)\n{\n    for (auto &f : fields) if (f.plc.size() > 1)\n    {\n        vector<Placement> nxt;\n        nxt.reserve(f.plc.size());\n        for (auto &pl : f.plc)\n        {\n            bool hit = false;\n            for (int id : pl.cells) if (id == id0){ hit=true; break; }\n            if (!hit) nxt.push_back(std::move(pl));\n        }\n        if (!nxt.empty()) f.plc.swap(nxt);\n    }\n}\n//------------------------------------------------------------------\n// statistics used for zero-elimination drill suggestion\nstruct Stat{\n    vector<int> cnt;\n    vector<double> logNoOil;\n    explicit Stat(int n): cnt(n), logNoOil(n,0.0){}\n};\nStat makeStat()\n{\n    Stat st(NN);\n    for (const auto &f: fields) if (f.plc.size() > 1)\n    {\n        int S = (int)f.plc.size();\n        double invS = 1.0 / S;\n        vector<int> local(NN,0);\n        for (const auto &pl: f.plc)\n            for (int id: pl.cells) ++local[id];\n\n        for (int id=0; id<NN; ++id) if (local[id])\n        {\n            st.cnt[id] += local[id];\n            double p = local[id]*invS;\n            if (p < 1.0) st.logNoOil[id] += log(1.0 - p);\n            else         st.logNoOil[id] = -1e100;\n        }\n    }\n    return st;\n}\n//------------------------------------------------------------------\n// DFS that enumerates feasible global solutions (stops after 2)\nstruct DFSSolver{\n    const vector<Field> &F;\n    vector<int> posIds, posVal;                 // positive drilled squares\n    vector<vector<char>> someCover;             // field\u2192posIdx   (bool)\n    vector<vector<int>>  plcMask;               // flattened placement\u2192list posIdx\n    vector<int> curCnt, remMax, assign;\n    int solutions=0;\n    vector<int> solA, solB;\n\n    DFSSolver(const vector<Field> &fld, const vector<int> &drilled)\n        : F(fld)\n    {\n        for(int id=0; id<(int)drilled.size(); ++id)\n            if (drilled[id] > 0){ posIds.push_back(id); posVal.push_back(drilled[id]); }\n\n        int P = (int)posIds.size();\n        someCover.assign(M, vector<char>(P,0));\n        plcMask.clear(); plcMask.reserve(8192);\n\n        for (int f=0; f<M; ++f)\n            for (const auto &pl: F[f].plc)\n            {\n                vector<int> mask;\n                for (int id: pl.cells)\n                {\n                    auto it = find(posIds.begin(), posIds.end(), id);\n                    if (it != posIds.end()){\n                        int idx = (int)(it - posIds.begin());\n                        mask.push_back(idx);\n                        someCover[f][idx] = 1;\n                    }\n                }\n                plcMask.push_back(std::move(mask));\n            }\n\n        curCnt.assign(P,0);\n        remMax.assign(P,0);\n        for(int p=0;p<P;++p)\n            for(int f=0;f<M;++f)\n                if (someCover[f][p]) ++remMax[p];\n\n        assign.assign(M,-1);\n    }\n    //--------------------------------------------------------------\n    void dfs(int depth,\n             const vector<int> &order,\n             const vector<int> &offset)\n    {\n        if (solutions>=2) return;\n        if (depth==(int)order.size())\n        {\n            for (int p=0;p<(int)posIds.size();++p)\n                if (curCnt[p]!=posVal[p]) return;\n            if (solutions==0) solA=assign; else solB=assign;\n            ++solutions; return;\n        }\n        int f = order[depth], base = offset[f], K = (int)F[f].plc.size();\n\n        // remove f's potential from remMax\n        for (int p=0;p<(int)posIds.size();++p) if (someCover[f][p]) --remMax[p];\n\n        for (int k=0;k<K && solutions<2;++k)\n        {\n            const auto& mask = plcMask[base+k];\n            bool ok=true;\n            for(int idx:mask)\n                if(curCnt[idx]+1>posVal[idx]){ ok=false; break; }\n            if (!ok) continue;\n\n            for(int idx:mask) ++curCnt[idx];\n            assign[f]=k;\n\n            for(int p=0;p<(int)posIds.size();++p)\n                if(curCnt[p]+remMax[p]<posVal[p]){ ok=false; break; }\n\n            if(ok) dfs(depth+1,order,offset);\n\n            assign[f]=-1;\n            for(int idx:mask) --curCnt[idx];\n        }\n        for (int p=0;p<(int)posIds.size();++p) if (someCover[f][p]) ++remMax[p];\n    }\n    //--------------------------------------------------------------\n    int solve()\n    {\n        if (posIds.empty())\n        {\n            bool uniq=true;\n            for(const auto &f:F) if(f.plc.size()!=1){ uniq=false; break; }\n            if (uniq){ solA.assign(M,0); solutions=1; return 1; }\n            return 2;\n        }\n        vector<int> ord(M); iota(ord.begin(),ord.end(),0);\n        sort(ord.begin(),ord.end(),\n             [&](int a,int b){ return F[a].plc.size()<F[b].plc.size(); });\n        vector<int> off(M);\n        int cur=0;\n        for(int f=0;f<M;++f){ off[f]=cur; cur+=(int)F[f].plc.size(); }\n        dfs(0,ord,off);\n        return min(solutions,2);\n    }\n};\n//------------------------------------------------------------------\nint pickDiscriminatingCell(const vector<int>& sA,\n                           const vector<int>& sB)\n{\n    vector<int> cntA(NN,0), cntB(NN,0);\n    for(int f=0;f<M;++f){\n        for(int id: fields[f].plc[sA[f]].cells) ++cntA[id];\n        for(int id: fields[f].plc[sB[f]].cells) ++cntB[id];\n    }\n    int best=-1, diffMax=0;\n    for(int id=0;id<NN;++id) if(drilled[id]==-1 && cntA[id]!=cntB[id]){\n        int diff=abs(cntA[id]-cntB[id]);\n        if(diff>diffMax){ diffMax=diff; best=id; }\n    }\n    if(best!=-1) return best;\n\n    // counts identical but coverage sets might differ (union)\n    for(int id=0;id<NN;++id)\n        if(drilled[id]==-1 && (cntA[id]>0)!=(cntB[id]>0))\n            return id;\n    return -1;                       // indistinguishable by single square\n}\n//------------------------------------------------------------------\nvoid readInput()\n{\n    cin >> N >> M >> EPS;\n    NN = N*N; maxQueries = 2*NN;\n    fields.resize(M);\n    drilled.assign(NN,-1);\n    isOil.assign(NN,0);\n\n    for(int k=0;k<M;++k)\n    {\n        int d; cin >> d;\n        vector<pair<int,int>> c(d);\n        int hi=0, wi=0;\n        for(int t=0;t<d;++t){\n            cin >> c[t].first >> c[t].second;\n            hi=max(hi,c[t].first); wi=max(wi,c[t].second);\n        }\n        ++hi; ++wi;\n        for(int si=0; si+hi<=N; ++si)\n            for(int sj=0; sj+wi<=N; ++sj)\n            {\n                Placement p; p.cells.reserve(d);\n                for(auto [ci,cj]:c) p.cells.push_back((ci+si)*N + cj+sj);\n                fields[k].plc.push_back(std::move(p));\n            }\n    }\n}\n//------------------------------------------------------------------\nint main()\n{\n    readInput();\n    const int ELIM_LIMIT = min(maxQueries-20, NN);  // 20 margin for later\n\n    // phase A: cheap elimination on v=0\n    while(queryCnt<ELIM_LIMIT)\n    {\n        auto st = makeStat();\n        int best=-1; double score=-1;\n        for(int id=0; id<NN; ++id) if(drilled[id]==-1 && st.cnt[id])\n        {\n            double pNo = exp(st.logNoOil[id]);\n            double sc = st.cnt[id]*pNo;\n            if(sc>score){ score=sc; best=id; }\n        }\n        if(best==-1) break;\n        int v=drill(best);\n        if(v==0) eliminateZero(best);\n    }\n\n    // phase B: iterate with DFS until unique solution obtained\n    while(true)\n    {\n        DFSSolver dfs(fields, drilled);\n        int res = dfs.solve();\n        if(res==0){\n            cerr<<\"Internal inconsistency!\\n\"; return 0;\n        }\n        if(res==1){        // unique \u2013 output and finish\n            vector<char> finalOil(NN,0);\n            for(int f=0;f<M;++f)\n                for(int id: fields[f].plc[dfs.solA[f]].cells)\n                    finalOil[id]=1;\n            for(int id=0;id<NN;++id) if(isOil[id]) finalOil[id]=1;\n\n            vector<int> ans;\n            for(int id=0;id<NN;++id) if(finalOil[id]) ans.push_back(id);\n\n            cout<<\"a \"<<ans.size();\n            for(int id:ans){\n                auto [i,j]=id2ij(id);\n                cout<<' '<<i<<' '<<j;\n            }\n            flush();\n            int judge; cin>>judge;\n            return 0;\n        }\n        // res == 2 : at least two solutions -> try to separate\n        int diff = pickDiscriminatingCell(dfs.solA, dfs.solB);\n        if(diff==-1){\n            // solutions identical w.r.t. every square's count \u21d2 answer safe\n            vector<char> finalOil(NN,0);\n            for(int id: isOil){}           // dummy to silence warnings\n            for(int f=0;f<M;++f)\n                for(int id: fields[f].plc[dfs.solA[f]].cells)\n                    finalOil[id]=1;\n            for(int id=0;id<NN;++id) if(isOil[id]) finalOil[id]=1;\n\n            vector<int> ans;\n            for(int id=0;id<NN;++id) if(finalOil[id]) ans.push_back(id);\n            cout<<\"a \"<<ans.size();\n            for(int id:ans){\n                auto [i,j]=id2ij(id);\n                cout<<' '<<i<<' '<<j;\n            }\n            flush();\n            int judge; cin>>judge;\n            return 0;\n        }\n        int v=drill(diff);\n        if(v==0) eliminateZero(diff);\n        if(queryCnt>=maxQueries) break;   // safety\n    }\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\nconstexpr int W = 1000;                     // hall size 1000 \u00d7 1000\n\nstruct Rect { int i0, j0, i1, j1; };        // [top,left) \u2013 [bottom,right)\n\n/* ------------------------------------------------------------------ */\n/* Fast   shelf (row) packing \u2013 1st try                                */\n/* ------------------------------------------------------------------ */\nbool pack_rowwise(const vector<ll>& a, vector<Rect>& out) {\n    const int N = (int)a.size();\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int x, int y){ return a[x] > a[y]; });\n\n    out.assign(N, {0,0,0,0});\n    int y = 0;                              // top of the current row\n    vector<int> remain = ord, nxt;\n\n    while (!remain.empty()) {\n        int idx0 = remain.front();\n        int h    = (int)((a[idx0] + W - 1) / W);       // minimal legal height\n        if (y + h > W) return false;                   // overflow \u2192 fallback\n\n        int x = 0;\n        nxt.clear();\n        for (int id : remain) {\n            int w = (int)((a[id] + h - 1) / h);        // ceil(a / h)  \u2264 1000\n            if (x + w <= W) {\n                out[id] = { y, x, y + h, x + w };\n                x += w;\n            } else {\n                nxt.push_back(id);                     // move to next row\n            }\n        }\n        y += h;\n        remain.swap(nxt);\n    }\n    return true;\n}\n\n/* ------------------------------------------------------------------ */\n/* Skyline fallback \u2013 guaranteed and fast                             */\n/* ------------------------------------------------------------------ */\nbool skyline_place(int h, int w,\n                   const vector<int>& sky, int &px, int &py) {\n    deque<int> dq;\n    // build first window\n    for (int i = 0; i < w; ++i) {\n        while (!dq.empty() && sky[dq.back()] <= sky[i]) dq.pop_back();\n        dq.push_back(i);\n    }\n    int curMax = sky[dq.front()];\n    if (curMax + h <= W) { px = 0; py = curMax; return true; }\n\n    for (int x = 1; x + w <= W; ++x) {\n        if (dq.front() == x - 1) dq.pop_front();\n        int idx = x + w - 1;\n        while (!dq.empty() && sky[dq.back()] <= sky[idx]) dq.pop_back();\n        dq.push_back(idx);\n        curMax = sky[dq.front()];\n        if (curMax + h <= W) { px = x; py = curMax; return true; }\n    }\n    return false;\n}\n\nbool pack_skyline(const vector<ll>& a, vector<Rect>& out) {\n    const int N = (int)a.size();\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int x, int y){ return a[x] > a[y]; });\n\n    vector<int> sky(W, 0);                  // current column heights\n    out.assign(N, {0,0,0,0});\n\n    for (int id : ord) {\n        ll area = a[id];\n        int hMin = (int)((area + W - 1) / W);          // ceil(area/1000)\n        bool placed = false;\n\n        for (int h = hMin; h <= W && !placed; ++h) {\n            int w = (int)((area + h - 1) / h);         // ceil(area / h)\n            if (w > W) continue;\n            int x, y;\n            if (skyline_place(h, w, sky, x, y)) {\n                out[id] = { y, x, y + h, x + w };\n                for (int i = x; i < x + w; ++i) sky[i] = y + h;\n                placed = true;\n            }\n        }\n        if (!placed) return false;                     // should never happen\n    }\n    return true;\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyW, D, N;\n    if (!(cin >> dummyW >> D >> N)) return 0;\n\n    vector<vector<ll>> A(D, vector<ll>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> A[d][k];\n\n    vector<Rect> dayRects;\n    for (int d = 0; d < D; ++d) {\n        bool ok = pack_rowwise(A[d], dayRects);\n        if (!ok) ok = pack_skyline(A[d], dayRects);    // fast guaranteed fallback\n        if (!ok) {                                     // ultimate safety \u2013 1\u00d71 cells\n            dayRects.resize(N);\n            for (int k = 0; k < N; ++k)\n                dayRects[k] = { k, 0, k + 1, 1 };\n        }\n        for (int k = 0; k < N; ++k) {\n            auto &r = dayRects[k];\n            cout << r.i0 << ' ' << r.j0 << ' '\n                 << r.i1 << ' ' << r.j1 << '\\n';\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\nconstexpr int MOD = 998244353;\nconstexpr int N = 9;\nconstexpr int M = 20;\nconstexpr int K = 81;\n\n/* ------------------------------- RNG ------------------------------------ */\nstruct RNG {\n    uint64_t s;\n    RNG() : s(chrono::steady_clock::now().time_since_epoch().count()) {}\n    uint32_t next() {\n        s ^= s << 13;\n        s ^= s >> 7;\n        s ^= s << 17;\n        return static_cast<uint32_t>(s);\n    }\n    uint32_t next(uint32_t lim) { return next() % lim; }\n    double   uniform()          { return double(next()) / 4294967295.0; }\n} rng;\n\n/* ----------------------------- operation -------------------------------- */\nstruct Op {\n    int m, p, q;     // for the answer\n    int idx[9];      // linear indices of the 9 covered cells\n    int add[9];\n};\n\ninline int64 gain_add(const Op& o, const array<int,81>& b){\n    int64 g = 0;\n    for (int k=0;k<9;++k){\n        int v  = b[o.idx[k]];\n        int nv = v + o.add[k];\n        if (nv >= MOD) nv -= MOD;\n        g += nv - v;\n    }\n    return g;\n}\ninline int64 gain_sub(const Op& o, const array<int,81>& b){\n    int64 g = 0;\n    for (int k=0;k<9;++k){\n        int v  = b[o.idx[k]];\n        int nv = v - o.add[k];\n        if (nv < 0) nv += MOD;\n        g += nv - v;\n    }\n    return g;\n}\ninline void apply_add(const Op& o, array<int,81>& b){\n    for (int k=0;k<9;++k){\n        int& v = b[o.idx[k]];\n        v += o.add[k];\n        if (v >= MOD) v -= MOD;\n    }\n}\ninline void apply_sub(const Op& o, array<int,81>& b){\n    for (int k=0;k<9;++k){\n        int& v = b[o.idx[k]];\n        v -= o.add[k];\n        if (v < 0) v += MOD;\n    }\n}\ninline bool is_safe(const Op& o,const array<int,81>& b){\n    for(int k=0;k<9;++k) if(b[o.idx[k]]+o.add[k]>=MOD) return false;\n    return true;\n}\n\n/* --------------------------- SA parameters ------------------------------ */\nconst double T0 = 1.0e9;\nconst double T1 = 1.0e5;\nconst int    SAMPLE = 4;      // how many random ops are compared when we need one\n\n/* ------------------------------- SA run --------------------------------- */\nstruct State{\n    array<int,81> board;\n    vector<int>   press;   // indices into ops[]\n    int64         score;\n};\n\nvoid simulated_annealing(State &st,\n                         const vector<Op>& ops,\n                         double time_limit){          // seconds\n    const auto time0 = chrono::steady_clock::now();\n    auto sec = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now()-time0).count();\n    };\n    int OPS = (int)ops.size();\n\n    array<int,81> b = st.board;\n    vector<int>   lst = st.press;\n    int64         cur = st.score;\n    int64         best = cur;\n    array<int,81> bestB = b;\n    vector<int>   bestL = lst;\n\n    long long iter = 0;\n    while(sec() < time_limit){\n        ++iter;\n        double t = sec()/time_limit;\n        double Temp = T0 * pow(T1/T0, t);\n\n        int moveType = rng.next(3);              // 0 add, 1 remove, 2 replace\n        if(moveType==0 && (int)lst.size()>=K) moveType=2;\n        if(moveType==1 && lst.empty())          moveType=0;\n        if(moveType==2 && lst.empty())          moveType=0;\n\n        if(moveType==0){          // ADD\n            int bestOp=-1;\n            int64 bestGain = LLONG_MIN;\n            for(int s=0;s<SAMPLE;++s){\n                int oi = rng.next(OPS);\n                int64 g = gain_add(ops[oi],b);\n                if(g>bestGain){bestGain=g;bestOp=oi;}\n            }\n            int64 delta = bestGain;\n            if(delta>=0 || rng.uniform()<exp(delta/Temp)){\n                apply_add(ops[bestOp],b);\n                lst.push_back(bestOp);\n                cur += delta;\n            }\n        }\n        else if(moveType==1){     // REMOVE\n            int id = rng.next((uint32_t)lst.size());\n            int oi = lst[id];\n            int64 delta = gain_sub(ops[oi],b);   // could be positive\n            if(delta>=0 || rng.uniform()<exp(delta/Temp)){\n                apply_sub(ops[oi],b);\n                cur += delta;\n                lst[id] = lst.back(); lst.pop_back();\n            }\n        }\n        else{                     // REPLACE\n            int id = rng.next((uint32_t)lst.size());\n            int oldOp = lst[id];\n\n            int bestOp=-1;\n            int64 bestDelta = LLONG_MIN;\n\n            // sample several candidates, take the best\n            for(int s=0;s<SAMPLE;++s){\n                int cand = rng.next(OPS);\n                if(cand==oldOp) continue;\n                int64 delta = gain_sub(ops[oldOp],b);\n                apply_sub(ops[oldOp],b);\n                delta += gain_add(ops[cand],b);\n                apply_add(ops[oldOp],b);     // rollback\n                if(delta>bestDelta){bestDelta=delta;bestOp=cand;}\n            }\n            if(bestOp<0) continue;\n\n            int64 delta = gain_sub(ops[oldOp],b);\n            apply_sub(ops[oldOp],b);\n            delta += gain_add(ops[bestOp],b);\n            if(delta>=0 || rng.uniform()<exp(delta/Temp)){\n                apply_add(ops[bestOp],b);\n                lst[id] = bestOp;\n                cur += delta;\n            }else{\n                apply_add(ops[oldOp],b);     // rollback\n            }\n        }\n\n        if(cur > best){\n            best = cur;\n            bestB = b;\n            bestL = lst;\n        }\n    }\n    st.board = bestB;\n    st.press = bestL;\n    st.score = best;\n}\n\n/* --------------------------- baseline greedy ---------------------------- */\nState baseline(const vector<Op>& ops){\n    State st;\n    st.board.fill(0);\n    st.score = 0;\n    st.press.clear();\n    /* read original A into board */\n    for(int i=0;i<81;++i){\n        int v; cin>>v; st.board[i]=v;\n        st.score += v;\n    }\n\n    // safe greedy\n    while((int)st.press.size()<K){\n        int best=-1; int64 bestGain=0;\n        for(int i=0;i<(int)ops.size();++i){\n            if(!is_safe(ops[i],st.board)) continue;\n            int64 g = gain_add(ops[i],st.board);\n            if(g>bestGain){bestGain=g;best=i;}\n        }\n        if(best<0||bestGain<=0) break;\n        apply_add(ops[best],st.board);\n        st.press.push_back(best);\n        st.score += bestGain;\n    }\n    // ordinary greedy\n    while((int)st.press.size()<K){\n        int best=-1; int64 bestGain=0;\n        for(int i=0;i<(int)ops.size();++i){\n            int64 g = gain_add(ops[i],st.board);\n            if(g>bestGain){bestGain=g;best=i;}\n        }\n        if(best<0||bestGain<=0) break;\n        apply_add(ops[best],st.board);\n        st.press.push_back(best);\n        st.score += bestGain;\n    }\n    return st;\n}\n\n/* ------------------------------- main ----------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyN,dummyM,dummyK;\n    cin>>dummyN>>dummyM>>dummyK;         // all fixed\n\n    /* read A later inside baseline() because we need it twice */\n    vector<int> firstRow(81);\n    for(int i=0;i<81;++i) cin>>firstRow[i];\n\n    /* read stamps */\n    array<array<int,9>,M> stamp{};\n    for(int m=0;m<M;++m)\n        for(int r=0;r<3;++r)\n            for(int c=0;c<3;++c){\n                int x; cin>>x; stamp[m][r*3+c]=x;\n            }\n\n    /* create all 980 presses */\n    vector<Op> ops; ops.reserve(M*49);\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                Op o; o.m=m; o.p=p; o.q=q;\n                int t=0;\n                for(int dr=0;dr<3;++dr)\n                    for(int dc=0;dc<3;++dc){\n                        o.idx[t]=(p+dr)*N+q+dc;\n                        o.add[t]=stamp[m][t];\n                        ++t;\n                    }\n                ops.push_back(o);\n            }\n\n    const auto global_start = chrono::steady_clock::now();\n    auto elapsed = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now()-global_start).count();\n    };\n\n    /* we need two copies of A because baseline() consumes the stream once   */\n    stringstream ss;\n    for(int v:firstRow) ss<<v<<' ';\n    string remainA = ss.str();\n    cin.seekg(0);                        // rewind\n    cin.clear();\n    cin.ignore(numeric_limits<streamsize>::max(),'\\n'); // skip first line\n    /* baseline run 1 */\n    {\n        for(int v:firstRow) cin>>v;      // dummy read to align the stream\n        cin.ignore(numeric_limits<streamsize>::max(),'\\n'); // stamps already read\n    }\n    /* rebuild input for baseline() */\n    string inputA = remainA;\n    stringstream inA(inputA);\n    /* replace cin buffer with inA for baseline() */\n    cin.rdbuf(inA.rdbuf());\n\n    State bestState = baseline(ops);     // baseline\n    double time_used = elapsed();\n    const double TOTAL = 1.95;           // keep tiny margin\n    const double single_time = 0.35;     // each SA slice\n\n    while(time_used + single_time < TOTAL){\n        State st = bestState;            // start from baseline\n        simulated_annealing(st, ops, single_time);\n        if(st.score > bestState.score) bestState = move(st);\n        time_used = elapsed();\n    }\n\n    /* output -------------------------------------------------------------- */\n    cout<<bestState.press.size()<<\"\\n\";\n    for(int id:bestState.press){\n        const Op& o = ops[id];\n        cout<<o.m<<\" \"<<o.p<<\" \"<<o.q<<\"\\n\";\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Crane {\n    int r, c;          // position\n    bool alive = true;\n    bool holding = false;\n    int box = -1;      // id of the held container\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N;                         // N is always 5 in this contest\n    if (!(cin >> N)) return 0;\n    vector<vector<int>> recv(N, vector<int>(N));\n    for (auto &v: recv) for (int &x: v) cin >> x;\n\n    /* --- problem constants ------------------------------------------------ */\n    const int COL_IN  = 0;         // Receiving Gates  (column 0)\n    const int COL_OUT = N - 1;     // Dispatch  Gates  (column 4)\n\n    /* --- simulation state -------------------------------------------------- */\n    vector<vector<int>> field(N, vector<int>(N, -1));   // -1: empty, else id\n    array<int, 5> nextIdx{};                            // next container per row\n\n    vector<Crane> cr(N);            // 0 = big crane\n    for (int i = 0; i < N; ++i) cr[i] = {i, 0, true, false, -1};\n\n    vector<string> cmd(N);          // answer strings, one per crane\n\n    int dispatched = 0, turn = 0;\n\n    /* ---------------------------------------------------------------------- */\n    auto spawn = [&] () {\n        for (int r = 0; r < N; ++r) {\n            if (nextIdx[r] == N) continue;          // 5 containers already\n            if (field[r][COL_IN] != -1) continue;   // gate still occupied\n            bool holder_here = false;\n            for (auto &c : cr)\n                if (c.alive && c.holding && c.r == r && c.c == COL_IN)\n                    holder_here = true;\n            if (!holder_here)\n                field[r][COL_IN] = recv[r][nextIdx[r]++];\n        }\n    };\n\n    auto neighbours = [&](int r1, int c1, int r2, int c2) {\n        return abs(r1 - r2) + abs(c1 - c2);\n    };\n\n    /* =================== main turn loop =================================== */\n    while (dispatched < N * N) {\n        /* step 1: new containers arrive */\n        spawn();\n\n        /* step 2: decide commands ----------------------------------------- */\n        vector<char> op(N, '.');\n\n        /* small cranes: bomb on the very first turn, afterwards '.' */\n        if (turn == 0)\n            for (int i = 1; i < N; ++i) op[i] = 'B';\n\n        /* big crane logic */\n        Crane &b = cr[0];\n        char bc = '.';\n\n        if (b.holding) {                     // carrying a container\n            int destR = b.box / N, destC = COL_OUT;\n            if (b.r == destR && b.c == destC) {\n                // at the Dispatch Gate\n                bc = (field[destR][destC] == -1 ? 'Q' : '.');\n            } else {\n                // move one step toward destination (vertical first)\n                if (b.r < destR)      bc = 'D';\n                else if (b.r > destR) bc = 'U';\n                else if (b.c < destC) bc = 'R';\n                else                  bc = 'L';\n            }\n        } else {                              // empty-handed\n            if (field[b.r][b.c] != -1) {\n                bc = 'P';                     // box under our feet\n            } else {\n                // look for the nearest waiting box (always at column 0)\n                int bestR = -1, bestDist = 1e9;\n                for (int r = 0; r < N; ++r)\n                    if (field[r][COL_IN] != -1) {\n                        int d = neighbours(b.r, b.c, r, COL_IN);\n                        if (d < bestDist) bestDist = d, bestR = r;\n                    }\n                if (bestR == -1) {\n                    bc = '.';\n                } else {\n                    if (b.r < bestR)      bc = 'D';\n                    else if (b.r > bestR) bc = 'U';\n                    else if (b.c > COL_IN)bc = 'L';\n                    else                  bc = 'R';\n                }\n            }\n        }\n        op[0] = bc;\n\n        /* append to output strings */\n        for (int i = 0; i < N; ++i) cmd[i].push_back(op[i]);\n\n        /* apply actions ---------------------------------------------------- */\n        /* small cranes */\n        for (int i = 1; i < N; ++i) {\n            if (!cr[i].alive) continue;\n            if (op[i] == 'B') { cr[i].alive = false; continue; }\n        }\n\n        /* big crane */\n        switch (bc) {\n            case 'U': --b.r; break;\n            case 'D': ++b.r; break;\n            case 'L': --b.c; break;\n            case 'R': ++b.c; break;\n            case 'P':\n                b.holding = true;\n                b.box = field[b.r][b.c];\n                field[b.r][b.c] = -1;\n                break;\n            case 'Q':\n                field[b.r][b.c] = b.box;\n                b.holding = false;\n                b.box = -1;\n                break;\n            default: break;\n        }\n\n        /* step 3: automatic dispatch -------------------------------------- */\n        for (int r = 0; r < N; ++r)\n            if (field[r][COL_OUT] != -1) {\n                field[r][COL_OUT] = -1;      // container leaves the grid\n                ++dispatched;\n            }\n\n        ++turn;\n        if (turn >= 10000) break;            // safety (never reached)\n    }\n\n    /* pad the shorter strings with '.' ------------------------------------ */\n    const size_t L = cmd[0].size();\n    for (int i = 1; i < N; ++i)\n        if (cmd[i].size() < L) cmd[i].append(L - cmd[i].size(), '.');\n\n    /* output -------------------------------------------------------------- */\n    for (int i = 0; i < N; ++i) cout << cmd[i] << '\\n';\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Coord = pair<int,int>;\nconstexpr int N = 20;                       // fixed\n\n/* ------------------------------------------------------------------ */\nvoid move_to(int &r,int &c,int tr,int tc,vector<string>& out){\n    while(r<tr){ out.emplace_back(\"D\"); ++r; }\n    while(r>tr){ out.emplace_back(\"U\"); --r; }\n    while(c<tc){ out.emplace_back(\"R\"); ++c; }\n    while(c>tc){ out.emplace_back(\"L\"); --c; }\n}\n\n/* --------------------- elementary patterns ------------------------ */\nvector<Coord> rowSnake(bool startLR){\n    vector<Coord> p; p.reserve(N*N);\n    for(int r=0;r<N;r++){\n        if((r&1)==(startLR?0:1))\n            for(int c=0;c<N;c++)   p.emplace_back(r,c);\n        else\n            for(int c=N-1;c>=0;--c) p.emplace_back(r,c);\n    }\n    return p;\n}\nvector<Coord> colSnake(bool startTB){\n    vector<Coord> p; p.reserve(N*N);\n    for(int c=0;c<N;c++){\n        if((c&1)==(startTB?0:1))\n            for(int r=0;r<N;r++)   p.emplace_back(r,c);\n        else\n            for(int r=N-1;r>=0;--r) p.emplace_back(r,c);\n    }\n    return p;\n}\nvector<Coord> spiral(bool cw){\n    vector<Coord> p; p.reserve(N*N);\n    int top=0,bot=N-1,l=0,r=N-1;\n    while(top<=bot && l<=r){\n        if(cw){\n            for(int c=l;c<=r;c++) p.emplace_back(top,c); ++top;\n            for(int rr=top;rr<=bot;rr++) p.emplace_back(rr,r); --r;\n            if(top<=bot){ for(int c=r;c>=l;--c) p.emplace_back(bot,c); --bot; }\n            if(l<=r){ for(int rr=bot;rr>=top;--rr) p.emplace_back(rr,l); ++l; }\n        }else{\n            for(int rr=top;rr<=bot;rr++) p.emplace_back(rr,l); ++l;\n            for(int c=l;c<=r;c++) p.emplace_back(bot,c); --bot;\n            if(l<=r){ for(int rr=bot;rr>=top;--rr) p.emplace_back(rr,r); --r; }\n            if(top<=bot){ for(int c=r;c>=l;--c) p.emplace_back(top,c); ++top; }\n        }\n    }\n    return p;\n}\n/* --------------------- band snakes (width k) ---------------------- */\nvector<Coord> rowBand(int k,bool firstLR){\n    vector<Coord> p; p.reserve(N*N);\n    bool dir=firstLR;\n    for(int r=0;r<N;r++){\n        if(dir)\n            for(int c=0;c<N;c++)   p.emplace_back(r,c);\n        else\n            for(int c=N-1;c>=0;--c) p.emplace_back(r,c);\n        if((r+1)%k==0) dir=!dir;                 // toggle every k-th row\n    }\n    return p;\n}\nvector<Coord> colBand(int k,bool firstTB){\n    vector<Coord> p; p.reserve(N*N);\n    bool dir=firstTB;\n    for(int c=0;c<N;c++){\n        if(dir)\n            for(int r=0;r<N;r++)   p.emplace_back(r,c);\n        else\n            for(int r=N-1;r>=0;--r) p.emplace_back(r,c);\n        if((c+1)%k==0) dir=!dir;                 // toggle every k-th column\n    }\n    return p;\n}\n\n/* ------------------- exact evaluation of a walk ------------------- */\nstruct EvalRes{\n    long long cost;          // movement cost without \u03a3|h|\n    int startIdx;\n};\nEvalRes evaluate(const vector<Coord>& path,\n                 const vector<vector<int>>& h)\n{\n    const int M = path.size();                    // 400\n    static long long pref[401];\n    pref[0]=0;\n    for(int i=0;i<M;i++){\n        auto [r,c]=path[i];\n        pref[i+1]=pref[i]+h[r][c];\n    }\n    long long mn=pref[0]; int s=0;\n    for(int i=1;i<=M;i++) if(pref[i]<mn){ mn=pref[i]; s=i; }\n\n    long long load=0, loadDistSum=0, distSum=0;\n    for(int k=0;k<M-1;k++){\n        int idx=(s+k)%M;\n        load += h[path[idx].first][path[idx].second];      // after cell idx\n        int dr = abs(path[idx].first  - path[(idx+1)%M].first);\n        int dc = abs(path[idx].second - path[(idx+1)%M].second);\n        int d  = dr+dc;                                    // Manhattan distance\n        distSum     += d;\n        loadDistSum += load * d;\n    }\n    auto [sr,sc]=path[s];\n    int approach = abs(sr)+abs(sc);                        // empty truck\n    long long total = 100LL*(approach + distSum) + loadDistSum;\n    return {total, s};\n}\n\n/* ------------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n; if(!(cin>>n)) return 0;     // n = 20\n    vector<vector<int>> h(N, vector<int>(N));\n    for(auto &row:h) for(int &x:row) cin>>x;\n\n    /* -------- build template walks ------------------------------------- */\n    vector<vector<Coord>> paths;\n    paths.push_back(rowSnake(true));\n    paths.push_back(rowSnake(false));\n    paths.push_back(colSnake(true));\n    paths.push_back(colSnake(false));\n    paths.push_back(spiral(true));\n    paths.push_back(spiral(false));\n\n    for(int k:{2,3,4,5,10}){\n        paths.push_back(rowBand(k,true));\n        paths.push_back(rowBand(k,false));\n        paths.push_back(colBand(k,true));\n        paths.push_back(colBand(k,false));\n    }\n\n    const int baseCnt = paths.size();\n    for(int i=0;i<baseCnt;i++){\n        auto rev = paths[i];\n        reverse(rev.begin(), rev.end());\n        paths.push_back(move(rev));\n    }\n\n    /* -------- choose the cheapest walk --------------------------------- */\n    long long bestCost = (1LL<<62);\n    int bestPid=0, bestStart=0;\n\n    for(int pid=0; pid<(int)paths.size(); ++pid){\n        auto e = evaluate(paths[pid],h);\n        if(e.cost < bestCost){\n            bestCost  = e.cost;\n            bestPid   = pid;\n            bestStart = e.startIdx;\n        }\n    }\n\n    /* -------- emit operations ------------------------------------------ */\n    const auto& path = paths[bestPid];\n    const int M = path.size();\n    const int s = bestStart;\n\n    vector<string> out; out.reserve(1500);\n\n    int r=0,c=0;\n    move_to(r,c,path[s].first,path[s].second,out);     // empty approach\n\n    int load=0;\n    for(int k=0;k<M;k++){\n        int idx = (s+k)%M;\n        auto [cr,cc]=path[idx];\n        int v = h[cr][cc];\n\n        if(v>0){ out.emplace_back(\"+\"+to_string(v)); load+=v; }\n        else if(v<0){ out.emplace_back(\"-\"+to_string(-v)); load+=v; }\n\n        if(k!=M-1){\n            auto [nr,nc]=path[(idx+1)%M];\n            move_to(r,c,nr,nc,out);                   // true Manhattan route\n        }\n    }\n\n    for(const string& op:out) cout<<op<<'\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** constant problem parameters ****************************************/\nconstexpr int N          = 6;                   // grid side\nconstexpr int M          = 15;                  // criteria per seed\nconstexpr int T_TURNS    = 10;                  // operations\nconstexpr int SEED_CNT   = 2 * N * (N - 1);     // 60\nconstexpr int PLANT_CNT  = N * N;               // 36\nconstexpr int RESTARTS   = 4;                   // SA repetitions\n\nstruct Seed {\n    array<uint8_t, M> x;\n    int               sum = 0;                  // Vi = \u03a3 xi,l\n};\n\n/*** geometry of the 6\u00d76 field ******************************************/\narray<vector<int>, PLANT_CNT> nbr;               // neighbours (\u22644)\nvector<pair<int,int>>         edges;             // 60 undirected edges\narray<int, PLANT_CNT>         degree;\n\nvoid build_geometry() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c) {\n            int id = r * N + c;\n            auto add=[&](int rr,int cc){\n                if (0<=rr && rr<N && 0<=cc && cc<N)\n                    nbr[id].push_back(rr*N+cc);\n            };\n            if (c+1<N){ add(r,c+1); edges.emplace_back(id, r*N+c+1); }\n            if (r+1<N){ add(r+1,c); edges.emplace_back(id,(r+1)*N+c); }\n            add(r  ,c-1);\n            add(r-1,c  );\n        }\n    for (int i = 0; i < PLANT_CNT; ++i) degree[i] = nbr[i].size();\n}\n\n/*** containers reused every turn ***************************************/\narray<Seed, SEED_CNT>  seed;                     // 60 current seeds\nint                   w[SEED_CNT][SEED_CNT];     // edge weight = \u03a3 max\narray<int,PLANT_CNT>  cell2seed;                 // grid \u2192 seed id\n\n/*** \u0394 of \u03a3edges when a single cell changes *****************************/\ninline long long delta_one(int pos,int oldS,int newS){\n    long long d = 0;\n    for (int nb : nbr[pos]){\n        d -= w[oldS][cell2seed[nb]];\n        d += w[newS][cell2seed[nb]];\n    }\n    return d;\n}\n\n/*** deterministic greedy hill-climb ************************************/\nlong long greedy_improve(vector<int>& pool, long long curSum){\n    bool changed = true;\n    while (changed){\n        changed = false;\n        /* replacements ------------------------------------------------ */\n        for (int pos = 0; pos < PLANT_CNT; ++pos){\n            int oldS = cell2seed[pos];\n            long long bestD = 0; int bestIdx = -1;\n            for (int i = 0; i < (int)pool.size(); ++i){\n                long long d = delta_one(pos, oldS, pool[i]);\n                if (d > bestD){ bestD = d; bestIdx = i; }\n            }\n            if (bestD > 0){\n                swap(cell2seed[pos], pool[bestIdx]);\n                curSum += bestD;\n                changed = true;\n            }\n        }\n        /* swaps inside the grid -------------------------------------- */\n        for (int a = 0; a < PLANT_CNT; ++a)\n            for (int b = a+1; b < PLANT_CNT; ++b){\n                int sa = cell2seed[a], sb = cell2seed[b];\n                long long d = delta_one(a, sa, sb) + delta_one(b, sb, sa);\n                if (d > 0){\n                    swap(cell2seed[a], cell2seed[b]);\n                    curSum += d;\n                    changed = true;\n                }\n            }\n    }\n    return curSum;\n}\n\n/*** one simulated-annealing run (returns best \u03a3edge) *******************/\nlong long run_SA(mt19937_64 &rng, vector<int>& pool,\n                 array<int,PLANT_CNT>& grid){\n    static uniform_real_distribution<double> urd(0.0,1.0);\n    uniform_int_distribution<int> cellDist(0, PLANT_CNT-1);\n\n    cell2seed = grid;                        // work on the global buffer\n    long long curSum = 0;\n    for (auto [u,v] : edges) curSum += w[cell2seed[u]][cell2seed[v]];\n    array<int,PLANT_CNT> bestGrid = grid;\n    long long            bestSum  = curSum;\n\n    constexpr int    ITER = 50000;           // \u00d7 RESTARTS  \u2264 2e5\n    constexpr double T0   = 800.0;\n    constexpr double T1   =  10.0;\n\n    for (int it = 0; it < ITER; ++it){\n        double temp = T0 + (T1 - T0) * it / ITER;\n\n        bool poolMove = !pool.empty() && urd(rng) < 0.35;\n        int posA = cellDist(rng), posB;\n        long long dSum;\n\n        if (poolMove){\n            int pidx = uniform_int_distribution<int>(0,(int)pool.size()-1)(rng);\n            int s_new = pool[pidx], s_old = cell2seed[posA];\n            dSum = delta_one(posA, s_old, s_new);\n\n            if (dSum >= 0 || urd(rng) < exp(dSum / temp)){\n                cell2seed[posA] = s_new;\n                pool[pidx]      = s_old;\n                curSum         += dSum;\n                if (curSum > bestSum){ bestSum = curSum; bestGrid = cell2seed; }\n            }\n        } else {\n            do{ posB = cellDist(rng);} while (posB == posA);\n            int sa = cell2seed[posA], sb = cell2seed[posB];\n            dSum = delta_one(posA, sa, sb) + delta_one(posB, sb, sa);\n\n            if (dSum >= 0 || urd(rng) < exp(dSum / temp)){\n                swap(cell2seed[posA], cell2seed[posB]);\n                curSum += dSum;\n                if (curSum > bestSum){ bestSum = curSum; bestGrid = cell2seed; }\n            }\n        }\n    }\n    grid = bestGrid;\n    return bestSum;\n}\n\n/*** helper: rebuild pool = complement of grid **************************/\nvector<int> complement_pool(const array<int,PLANT_CNT>& grid){\n    vector<char> in( SEED_CNT, 0);\n    for (int s : grid) in[s] = 1;\n    vector<int> pool;\n    for (int i = 0; i < SEED_CNT; ++i) if (!in[i]) pool.push_back(i);\n    return pool;\n}\n\n/*** main ***************************************************************/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    build_geometry();\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    /* read initial seeds (N=6 M=15 T=10) */\n    int dummy; cin >> dummy >> dummy >> dummy;\n    for (int i = 0; i < SEED_CNT; ++i){\n        int s = 0;\n        for (int l = 0; l < M; ++l){\n            int v; cin >> v;\n            seed[i].x[l] = (uint8_t)v;\n            s += v;\n        }\n        seed[i].sum = s;\n    }\n\n    for (int turn = 0; turn < T_TURNS; ++turn){\n        /* build weight table w(i,j)=\u03a3 max(xi_l,xj_l) ----------------- */\n        for (int i = 0; i < SEED_CNT; ++i)\n            for (int j = i; j < SEED_CNT; ++j){\n                if (i==j){ w[i][i] = seed[i].sum; continue; }\n                int s = 0;\n                for (int l = 0; l < M; ++l)\n                    s += max(seed[i].x[l], seed[j].x[l]);\n                w[i][j] = w[j][i] = s;\n            }\n\n        /* initial deterministic grid: 36 highest sums ---------------- */\n        vector<int> idx(SEED_CNT); iota(idx.begin(),idx.end(),0);\n        ranges::sort(idx,[&](int a,int b){ return seed[a].sum > seed[b].sum; });\n\n        array<int,PLANT_CNT> baseGrid;\n        array<int,PLANT_CNT> cells;\n        iota(cells.begin(),cells.end(),0);\n        ranges::sort(cells,[&](int a,int b){ return degree[a]>degree[b]; });\n        for (int k = 0; k < PLANT_CNT; ++k)\n            baseGrid[cells[k]] = idx[k];\n\n        /* multi-start SA --------------------------------------------- */\n        array<int,PLANT_CNT> bestGrid = baseGrid;\n        long long            bestSum  = -1;\n\n        for (int rep = 0; rep < RESTARTS; ++rep){\n            array<int,PLANT_CNT> grid;\n            if (rep == 0){\n                grid = baseGrid;\n            } else {\n                /* random start: shuffle seeds & place on same cells   */\n                vector<int> all( SEED_CNT ); iota(all.begin(),all.end(),0);\n                shuffle(all.begin(), all.end(), rng);\n                for (int k = 0; k < PLANT_CNT; ++k) grid[cells[k]] = all[k];\n            }\n            vector<int> pool = complement_pool(grid);\n            long long sum = run_SA(rng, pool, grid);\n\n            if (sum > bestSum){\n                bestSum  = sum;\n                bestGrid = grid;\n            }\n        }\n        cell2seed = bestGrid;\n        vector<int> pool = complement_pool(cell2seed);\n\n        /* final deterministic polishing ------------------------------ */\n        bestSum = 0;\n        for (auto [u,v]: edges) bestSum += w[cell2seed[u]][cell2seed[v]];\n        bestSum = greedy_improve(pool, bestSum);\n\n        /* output grid ------------------------------------------------ */\n        for (int r = 0; r < N; ++r){\n            for (int c = 0; c < N; ++c){\n                if (c) cout << ' ';\n                cout << cell2seed[r*N+c];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        /* read next generation -------------------------------------- */\n        if (turn == T_TURNS-1) break;\n        for (int i = 0; i < SEED_CNT; ++i){\n            int s = 0;\n            for (int l = 0; l < M; ++l){\n                int v; cin >> v;\n                seed[i].x[l] = (uint8_t)v;\n                s += v;\n            }\n            seed[i].sum = s;\n        }\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ------------------------------------------------ utility ---------- */\nstruct Pos { int x, y; };\nconstexpr int DX[4] = {0, 1, 0,-1};          // 0:R 1:D 2:L 3:U\nconstexpr int DY[4] = {1, 0,-1, 0};\n\ninline int manhattan(const Pos& a,const Pos& b){\n    return abs(a.x-b.x)+abs(a.y-b.y);\n}\ninline bool inside(int x,int y,int N){ return 0<=x && x<N && 0<=y && y<N; }\n\n/* convert orientation -> vector index, 0:R \u2026 3:U -------------------- */\ninline Pos root_for(const Pos& sq,int dir){        // root s.t. leaf dir reaches sq\n    return { sq.x-DX[dir], sq.y-DY[dir] };\n}\n/* -------------------------------------------------------------------*/\nstruct Simulator{\n    int N;\n    int rx=0, ry=0;                                 // root position\n    vector<string> out;                             // command list\n\n    void emit(char move,int leafRotate,int leafIdx,int actionLeaf){ // one turn\n        string s(10,'.');                           // V'=5 => len=10\n        s[0] = move;                                // U,D,L,R,.\n        if(leafRotate)  s[leafIdx] = (leafRotate>0 ? 'R' : 'L');\n        if(actionLeaf)  s[5+actionLeaf] = 'P';\n        out.push_back(std::move(s));\n    }\n};\n/* -------------------------------------------------------------------*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N,M,Vmax;  if(!(cin>>N>>M>>Vmax)) 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    /* ---------------- make board, sources, targets ----------------- */\n    vector<vector<int>> has(N, vector<int>(N));\n    vector<Pos> SRC, TAR;\n    for(int i=0;i<N;++i)\n        for(int j=0;j<N;++j){\n            if(S[i][j]=='1'){ has[i][j]=1; }\n            bool src = S[i][j]=='1' && T[i][j]=='0';\n            bool tar = S[i][j]=='0' && T[i][j]=='1';\n            if(src) SRC.push_back({i,j});\n            if(tar) TAR.push_back({i,j});\n        }\n\n    /* --------------------- design the arm -------------------------- */\n    cout<<5<<\"\\n\";                       // root 0 + four leaves 1..4\n    for(int i=1;i<=4;i++) cout<<\"0 1\\n\";\n    cout<<\"0 0\\n\";                       // root at (0,0)\n\n    Simulator sim; sim.N = N;\n\n    /* ---------- initial two turns: rotate to star orientation ------ */\n    { string s(10,'.'); s[2]='R'; s[3]='L'; s[4]='R'; sim.out.push_back(s); }\n    { string s(10,'.'); s[4]='R'; sim.out.push_back(s); }\n\n    /* current orientation of each leaf (0:R 1:D 2:L 3:U) ------------ */\n    int ori[5]={0,0,1,3,2};        // leaf-1 right, 2 down, 3 up, 4 left\n\n    auto rotDir = [](int from,int to){        // -1:ccw 0:none +1: cw (*steps)\n        int diff=(to-from+4)&3;\n        if(diff==0) return pair<int,int>{0,0};\n        if(diff==3) return pair<int,int>{-1,1};\n        return pair<int,int>{+1,diff};        // diff==1 or 2\n    };\n\n    /* helper to overlap translation + rotation ---------------------- */\n    auto move_and_rotate = [&](int tx,int ty,int leaf,int tgtOri){\n        auto [dirSign,steps] = rotDir(ori[leaf],tgtOri);\n        while(sim.rx!=tx || sim.ry!=ty){\n            char mv='.';\n            if(sim.rx<tx){ ++sim.rx; mv='D'; }\n            else if(sim.rx>tx){ --sim.rx; mv='U'; }\n            else if(sim.ry<ty){ ++sim.ry; mv='R'; }\n            else               { --sim.ry; mv='L'; }\n\n            int r=0;\n            if(steps){ r=dirSign; --steps; ori[leaf]=(ori[leaf]+(dirSign==1?1:3))&3; }\n            sim.emit(mv,r,leaf,0);\n        }\n        while(steps){\n            int r=dirSign; --steps; ori[leaf]=(ori[leaf]+(dirSign==1?1:3))&3;\n            sim.emit('.',r,leaf,0);\n        }\n    };\n\n    auto patch_last_for_action = [&](int leaf){\n        if(sim.out.empty()) sim.emit('.' ,0,0,leaf);\n        else                sim.out.back()[5+leaf]='P';\n    };\n\n    auto erase_swap=[](auto& v,size_t idx){ v[idx]=v.back(); v.pop_back(); };\n\n    /* =========================== main loop ========================= */\n    while(!SRC.empty()){\n        /* -------- find best (source,leaf,orientation) -------------- */\n        int bestIdx=-1, bestLeaf=0, bestOri=0;\n        int bestRootX=0,bestRootY=0,bestCost=INT_MAX;\n\n        for(size_t i=0;i<SRC.size();++i){\n            const Pos& p=SRC[i];\n            for(int leaf=1;leaf<=4;++leaf){\n                for(int d=0;d<4;++d){\n                    Pos r = root_for(p,d);\n                    if(!inside(r.x,r.y,N)) continue;\n                    int dist = manhattan({sim.rx,sim.ry},r);\n                    auto [sg,st]=rotDir(ori[leaf],d);\n                    int cost = dist + max(0, st - dist); // extra turns if rot>dist\n                    if(cost<bestCost){\n                        bestCost=cost; bestIdx=i; bestLeaf=leaf; bestOri=d;\n                        bestRootX=r.x; bestRootY=r.y;\n                    }\n                }\n            }\n        }\n\n        /* ---------------- go to source, grab ----------------------- */\n        Pos src=SRC[bestIdx]; erase_swap(SRC,bestIdx);\n        move_and_rotate(bestRootX,bestRootY,bestLeaf,bestOri);\n        patch_last_for_action(bestLeaf);         // grab\n        has[src.x][src.y]=0;\n\n        /* ------------- choose target reachable with same leaf ------ */\n        int bestT=-1,bestTX=0,bestTY=0,bestTOri=0,bestC2=INT_MAX;\n        for(size_t j=0;j<TAR.size();++j){\n            const Pos& t=TAR[j];\n            for(int d2=0;d2<4;++d2){\n                Pos r = root_for(t,d2);\n                if(!inside(r.x,r.y,N)) continue;\n                int dist = manhattan({sim.rx,sim.ry},r);\n                auto [sg,st]=rotDir(ori[bestLeaf],d2);\n                int cost = dist + max(0, st - dist);\n                if(cost<bestC2){\n                    bestC2=cost; bestT=j; bestTX=r.x; bestTY=r.y; bestTOri=d2;\n                }\n            }\n        }\n        Pos target=TAR[bestT]; erase_swap(TAR,bestT);\n\n        /* ---------------- move there, release ---------------------- */\n        move_and_rotate(bestTX,bestTY,bestLeaf,bestTOri);\n        patch_last_for_action(bestLeaf);         // drop\n        has[target.x][target.y]=1;\n    }\n\n    /* --------------------- output whole plan ----------------------- */\n    for(const string& s:sim.out) cout<<s<<\"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------------------------------------------------------------------- */\nstruct Point { int x, y; };\nstruct Rect  { int x1, y1, x2, y2;  bool valid()const{return x1<x2&&y1<y2;} };\n/* ---------------------------------------------------------------------- */\nconstexpr int MAXC = 100000;\nconstexpr int CELL = 250;\nconstexpr int GRID = MAXC / CELL + 1;           // 401\nconstexpr int TOPK = 32;                        // how many coarse rectangles\n\nstatic int diffGrid[GRID][GRID];\nstatic int pref[GRID + 1][GRID + 1];\n\ninline int gridSum(int t,int l,int b,int r){    // inclusive\n    return pref[b+1][r+1]-pref[t][r+1]-pref[b+1][l]+pref[t][l];\n}\n\n/* exact score of any rectangle ------------------------------------------ */\nint exactScore(const Rect&r,\n               const vector<Point>&mac,const vector<Point>&sar){\n    int res=0;\n    for(const auto&p:mac)\n        if(r.x1<=p.x&&p.x<=r.x2&&r.y1<=p.y&&p.y<=r.y2) ++res;\n    for(const auto&p:sar)\n        if(r.x1<=p.x&&p.x<=r.x2&&r.y1<=p.y&&p.y<=r.y2) --res;\n    return res;\n}\n\n/*---------------------------------------------------------------------------*/\n/* one-dimensional optimum for a single side (same idea as previous version) */\ntemplate<bool vertical,bool lower>\nbool optimiseSide(Rect&R,int&best,\n                  const vector<Point>&mac,const vector<Point>&sar){\n    vector<pair<int,int>> v; v.reserve(20000);\n    if constexpr(vertical){\n        for(const auto&p:mac)\n            if(R.y1<=p.y&&p.y<=R.y2&&(lower?p.x<=R.x2:p.x>=R.x1))\n                v.emplace_back(p.x,+1);\n        for(const auto&p:sar)\n            if(R.y1<=p.y&&p.y<=R.y2&&(lower?p.x<=R.x2:p.x>=R.x1))\n                v.emplace_back(p.x,-1);\n    }else{\n        for(const auto&p:mac)\n            if(R.x1<=p.x&&p.x<=R.x2&&(lower?p.y<=R.y2:p.y>=R.y1))\n                v.emplace_back(p.y,+1);\n        for(const auto&p:sar)\n            if(R.x1<=p.x&&p.x<=R.x2&&(lower?p.y<=R.y2:p.y>=R.y1))\n                v.emplace_back(p.y,-1);\n    }\n    if(v.empty()) return false;\n    sort(v.begin(),v.end(),[](auto a,auto b){return a.first<b.first;});\n    vector<pair<int,int>> g; g.reserve(v.size());\n    for(auto [c,val]:v){\n        if(g.empty()||g.back().first!=c) g.emplace_back(c,val);\n        else g.back().second+=val;\n    }\n    int total=0; for(auto &p:g) total+=p.second;\n\n    bool improved=false;\n    if constexpr(vertical&&lower){             // left\n        int prefix=0,bestLocal=best,bestPos=R.x1;\n        if(total>bestLocal&&0<R.x2){bestLocal=total;bestPos=0;improved=true;}\n        for(size_t i=0;i<g.size();++i){\n            int x=g[i].first,group=g[i].second;\n            if(x<R.x2){\n                int sc=total-prefix;\n                if(sc>bestLocal){bestLocal=sc;bestPos=x;improved=true;}\n            }\n            if(x+1<R.x2){\n                int sc=total-(prefix+group);\n                if(sc>bestLocal){bestLocal=sc;bestPos=x+1;improved=true;}\n            }\n            prefix+=group;\n        }\n        if(improved){R.x1=bestPos;best=bestLocal;}\n    }else if constexpr(vertical&&!lower){      // right\n        int suffix=0,bestLocal=best,bestPos=R.x2;\n        if(total>bestLocal&&MAXC>R.x1){bestLocal=total;bestPos=MAXC;improved=true;}\n        for(int i=(int)g.size()-1;i>=0;--i){\n            int x=g[i].first,group=g[i].second;\n            if(x>R.x1){\n                int sc=total-suffix;\n                if(sc>bestLocal){bestLocal=sc;bestPos=x;improved=true;}\n            }\n            if(x-1>R.x1){\n                int sc=total-(suffix+group);\n                if(sc>bestLocal){bestLocal=sc;bestPos=x-1;improved=true;}\n            }\n            suffix+=group;\n        }\n        if(improved){R.x2=bestPos;best=bestLocal;}\n    }else if constexpr(!vertical&&lower){      // bottom\n        int prefix=0,bestLocal=best,bestPos=R.y1;\n        if(total>bestLocal&&0<R.y2){bestLocal=total;bestPos=0;improved=true;}\n        for(size_t i=0;i<g.size();++i){\n            int y=g[i].first,group=g[i].second;\n            if(y<R.y2){\n                int sc=total-prefix;\n                if(sc>bestLocal){bestLocal=sc;bestPos=y;improved=true;}\n            }\n            if(y+1<R.y2){\n                int sc=total-(prefix+group);\n                if(sc>bestLocal){bestLocal=sc;bestPos=y+1;improved=true;}\n            }\n            prefix+=group;\n        }\n        if(improved){R.y1=bestPos;best=bestLocal;}\n    }else{                                     // top\n        int suffix=0,bestLocal=best,bestPos=R.y2;\n        if(total>bestLocal&&MAXC>R.y1){bestLocal=total;bestPos=MAXC;improved=true;}\n        for(int i=(int)g.size()-1;i>=0;--i){\n            int y=g[i].first,group=g[i].second;\n            if(y>R.y1){\n                int sc=total-suffix;\n                if(sc>bestLocal){bestLocal=sc;bestPos=y;improved=true;}\n            }\n            if(y-1>R.y1){\n                int sc=total-(suffix+group);\n                if(sc>bestLocal){bestLocal=sc;bestPos=y-1;improved=true;}\n            }\n            suffix+=group;\n        }\n        if(improved){R.y2=bestPos;best=bestLocal;}\n    }\n    return improved;\n}\n\n/* greedy grid-cell shrink ----------------------------------------------- */\nvoid shrinkOnGrid(int &t,int &l,int &b,int &r){\n    bool changed=true;\n    while(changed){\n        changed=false;\n        int cur=gridSum(t,l,b,r);\n        if(l<r&&gridSum(t,l+1,b,r)>cur){++l;changed=true;continue;}\n        if(l<r&&gridSum(t,l,b,r-1)>cur){--r;changed=true;continue;}\n        if(t<b&&gridSum(t+1,l,b,r)>cur){++t;changed=true;continue;}\n        if(t<b&&gridSum(t,l,b-1,r)>cur){--b;changed=true;continue;}\n    }\n}\n\n/* ---------------------------------------------------------------------- */\nstruct GridRect{int l,r,t,b; int val;};\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<Point> mac(N),sar(N);\n    for(int i=0;i<N;++i) cin>>mac[i].x>>mac[i].y;\n    for(int i=0;i<N;++i) cin>>sar[i].x>>sar[i].y;\n\n    /* difference grid & prefix ------------------------------------------ */\n    for(auto &p:mac) diffGrid[p.y/CELL][p.x/CELL]+=1;\n    for(auto &p:sar) diffGrid[p.y/CELL][p.x/CELL]-=1;\n    for(int y=0;y<GRID;++y){\n        int row=0;\n        for(int x=0;x<GRID;++x){\n            row+=diffGrid[y][x];\n            pref[y+1][x+1]=pref[y][x+1]+row;\n        }\n    }\n\n    /* 1. best rectangle on the grid via 2-D Kadane ----------------------- */\n    static int colSum[GRID];\n    int bestKadane=-1e9; int bl=0,br=0,bt=0,bb=0;\n    for(int top=0;top<GRID;++top){\n        fill(colSum,colSum+GRID,0);\n        for(int bot=top;bot<GRID;++bot){\n            for(int x=0;x<GRID;++x) colSum[x]+=diffGrid[bot][x];\n            int cur=0,curL=0;\n            for(int x=0;x<GRID;++x){\n                cur+=colSum[x];\n                if(cur>bestKadane){bestKadane=cur;bl=curL;br=x;bt=top;bb=bot;}\n                if(cur<0){cur=0;curL=x+1;}\n            }\n        }\n    }\n\n    /* priority queue of TOPK coarse rectangles --------------------------- */\n    auto pushCand=[&](vector<GridRect>&vec,const GridRect&gr){\n        if((int)vec.size()<TOPK){vec.push_back(gr);}\n        else{\n            int mn=0;\n            for(int i=1;i<(int)vec.size();++i)\n                if(vec[i].val<vec[mn].val) mn=i;\n            if(gr.val>vec[mn].val) vec[mn]=gr;\n        }\n    };\n\n    vector<GridRect> cand;\n    pushCand(cand,{bl,br,bt,bb,bestKadane});\n\n    /* 2. 60k random rectangles ------------------------------------------ */\n    mt19937 rng(123456);\n    uniform_int_distribution<int> pickMac(0,N-1), sizePick(1,60);\n\n    const int SAMPLES=60000;\n    for(int s=0;s<SAMPLES;++s){\n        const auto &c=mac[pickMac(rng)];\n        int gx=c.x/CELL, gy=c.y/CELL;\n        int w=sizePick(rng), h=sizePick(rng);\n        int l=max(0,gx-w/2);\n        int r=min(GRID-1,l+w-1); l=max(0,r-w+1);\n        int t=max(0,gy-h/2);\n        int b=min(GRID-1,t+h-1); t=max(0,b-h+1);\n\n        int sc=gridSum(t,l,b,r);\n        pushCand(cand,{l,r,t,b,sc});\n    }\n\n    /* ------------------------------------------------------------------ */\n    Rect bestRect{0,0,1,1};\n    int  bestScore=0;\n\n    for(auto gr:cand){\n        /* local greedy shrink on grid */\n        shrinkOnGrid(gr.t,gr.l,gr.b,gr.r);\n\n        /* convert to real coordinates */\n        Rect R{gr.l*CELL,\n               gr.t*CELL,\n               min(MAXC,(gr.r+1)*CELL-1),\n               min(MAXC,(gr.b+1)*CELL-1)};\n\n        int cur=exactScore(R,mac,sar);\n\n        /* coordinate-wise exact optimisation (\u22646 rounds) */\n        for(int round=0;round<6;++round){\n            bool any=false;\n            any|=optimiseSide<true ,true >(R,cur,mac,sar);  // left\n            any|=optimiseSide<true ,false>(R,cur,mac,sar);  // right\n            any|=optimiseSide<false,true >(R,cur,mac,sar);  // bottom\n            any|=optimiseSide<false,false>(R,cur,mac,sar);  // top\n            if(!any) break;\n        }\n\n        if(cur>bestScore && R.valid()){ bestScore=cur; bestRect=R; }\n    }\n\n    if(bestScore<=0) bestRect={0,0,1,1};\n\n    /*  output rectangle ---------------------------------------------------- */\n    cout<<4<<\"\\n\";\n    cout<<bestRect.x1<<\" \"<<bestRect.y1<<\"\\n\";\n    cout<<bestRect.x2<<\" \"<<bestRect.y1<<\"\\n\";\n    cout<<bestRect.x2<<\" \"<<bestRect.y2<<\"\\n\";\n    cout<<bestRect.x1<<\" \"<<bestRect.y2<<\"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\n\n/*------------------------------------------------------------------*/\n/*  rectangle                                                        */\n/*------------------------------------------------------------------*/\nstruct Rec { int64 w, h; };\nstatic inline Rec rot(const Rec& r){ return Rec{r.h, r.w}; }\n\n/*------------------------------------------------------------------*/\n/*  EXACT evaluation obeying the right-edge rule                     */\n/*------------------------------------------------------------------*/\nint64 eval_exact(const vector<Rec>& r,\n                 const vector<char>& ori,\n                 const vector<char>& cut)          // cut[0]==1\n{\n    const int N = (int)r.size();\n    vector<int> rowIdx; for(int i=0;i<N;++i) if(cut[i]) rowIdx.push_back(i);\n    int R = (int)rowIdx.size();\n\n    vector<int64> rowW(R,0), rowH(R,0);\n    vector<int> tallest(R,0);\n    for(int rr=0; rr<R; ++rr){\n        int st=rowIdx[rr], ed=(rr+1<R?rowIdx[rr+1]:N);\n        int64 hMax=-1;\n        for(int i=st;i<ed;++i){\n            const Rec& rc = ori[i]?rot(r[i]):r[i];\n            rowW[rr]+=rc.w;\n            if(rc.h>hMax){ hMax=rc.h; tallest[rr]=i; }\n        }\n        rowH[rr]=hMax;\n    }\n\n    vector<int64> posX(N,0), offset(R,0);\n    int64 maxX=0, sumH=0;\n\n    for(int rr=0; rr<R; ++rr){\n        int st=rowIdx[rr], ed=(rr+1<R?rowIdx[rr+1]:N);\n\n        for(int i=st;i<ed;++i){\n            const Rec& prev = (i==st? Rec{0,0} : (ori[i-1]?rot(r[i-1]):r[i-1]));\n            const Rec& cur  = ori[i]?rot(r[i]):r[i];\n\n            if(i==st) posX[i]=offset[rr];\n            else      posX[i]=posX[i-1]+prev.w;\n\n            maxX = max(maxX, posX[i]+cur.w);\n        }\n        sumH += rowH[rr];\n\n        if(rr+1<R){\n            int b = tallest[rr];\n            int64 baseR = posX[b] + (ori[b]?rot(r[b]).w:r[b].w);\n            int64 cand  = baseR - rowW[rr+1];\n            if(cand<0) cand=0;\n            offset[rr+1]=cand;\n        }\n    }\n    return maxX + sumH;\n}\n\n/*------------------------------------------------------------------*/\n/*  Greedy construction under a width limit                          */\n/*------------------------------------------------------------------*/\nstruct Layout{\n    vector<char> ori;   // 0 = as is , 1 = rotated\n    vector<char> cut;   // cut[0]==1\n    int64 score;\n};\n\nLayout greedy_build(const vector<Rec>& r, double Wlim)\n{\n    const int N = (int)r.size();\n    vector<char> ori(N,0), cut(N,0); cut[0]=1;\n    double curW=0, curH=0;\n\n    for(int i=0;i<N;++i){\n        Rec a=r[i], b=rot(r[i]);\n        bool fitA = (curW + a.w <= Wlim);\n        bool fitB = (curW + b.w <= Wlim);\n\n        if(!fitA && !fitB){             // start new shelf\n            cut[i]=1; curW=0; curH=0;\n            fitA=fitB=true;\n        }\n        char use=0;\n        if(fitA && fitB){\n            double hA=max(curH,(double)a.h);\n            double hB=max(curH,(double)b.h);\n            if(hB<hA || (hB==hA && b.w<a.w)) use=1;\n        }else if(!fitA) use=1;\n\n        ori[i]=use;\n        const Rec& rc=use?b:a;\n        curW+=rc.w; curH=max(curH,(double)rc.h);\n    }\n    Layout L{ori,cut,0};\n    L.score = eval_exact(r,L.ori,L.cut);\n    return L;\n}\n\n/*------------------------------------------------------------------*/\n/*  Local monotone improvement                                       */\n/*------------------------------------------------------------------*/\nvoid improve(Layout& lay, const vector<Rec>& r)\n{\n    const int N=(int)r.size();\n    bool changed=true;\n    while(changed){\n        changed=false;\n\n        /* --- orientation flips ------------------------------- */\n        for(int i=0;i<N;++i){\n            lay.ori[i]^=1;\n            int64 sc=eval_exact(r,lay.ori,lay.cut);\n            if(sc<lay.score){ lay.score=sc; changed=true; }\n            else lay.ori[i]^=1;\n        }\n        /* --- insert a cut ------------------------------------ */\n        for(int i=1;i<N;++i) if(!lay.cut[i]){\n            lay.cut[i]=1;\n            int64 sc=eval_exact(r,lay.ori,lay.cut);\n            if(sc<lay.score){ lay.score=sc; changed=true; continue; }\n            lay.cut[i]=0;\n        }\n        /* --- remove a cut ------------------------------------ */\n        for(int i=1;i<N;++i) if(lay.cut[i]){\n            lay.cut[i]=0;\n            int64 sc=eval_exact(r,lay.ori,lay.cut);\n            if(sc<lay.score){ lay.score=sc; changed=true; continue; }\n            lay.cut[i]=1;\n        }\n        /* --- shift cut left/right ---------------------------- */\n        for(int i=1;i<N-1;++i) if(lay.cut[i]){\n            // shift left\n            if(!lay.cut[i-1]){\n                lay.cut[i]=0; lay.cut[i-1]=1;\n                int64 sc=eval_exact(r,lay.ori,lay.cut);\n                if(sc<lay.score){ lay.score=sc; changed=true; continue; }\n                lay.cut[i]=1; lay.cut[i-1]=0;\n            }\n            // shift right\n            if(!lay.cut[i+1]){\n                lay.cut[i]=0; lay.cut[i+1]=1;\n                int64 sc=eval_exact(r,lay.ori,lay.cut);\n                if(sc<lay.score){ lay.score=sc; changed=true; continue; }\n                lay.cut[i]=1; lay.cut[i+1]=0;\n            }\n        }\n    }\n}\n\n/*------------------------------------------------------------------*/\n/*  build command list (original indices)                            */\n/*------------------------------------------------------------------*/\nstruct Cmd{ int p; char r,d; int b; };\n\nvector<Cmd> build_cmds(const vector<Rec>& r,\n                       const Layout& lay,\n                       const vector<int>& origIdx)      // mapping sub-idx \u2192 original\n{\n    const int N = (int)r.size();\n    vector<int> rowIdx; for(int i=0;i<N;++i) if(lay.cut[i]) rowIdx.push_back(i);\n    int R = (int)rowIdx.size();\n\n    vector<int> tallest(R);\n    for(int rr=0; rr<R; ++rr){\n        int st=rowIdx[rr], ed=(rr+1<R?rowIdx[rr+1]:N);\n        int64 bestH=-1;\n        for(int i=st;i<ed;++i){\n            int64 h = lay.ori[i]?r[i].w:r[i].h;\n            if(h>bestH){ bestH=h; tallest[rr]=i; }\n        }\n    }\n\n    vector<Cmd> out;\n    out.reserve(N);\n    for(int i=0;i<N;++i){\n        int rr = (int)(upper_bound(rowIdx.begin(),rowIdx.end(),i)-rowIdx.begin())-1;\n        bool first = lay.cut[i];\n        Cmd c; c.p = origIdx[i]; c.r = lay.ori[i];\n        if(rr==0 && first){ c.d='U'; c.b=-1; }\n        else if(first){    c.d='L'; c.b = origIdx[ tallest[rr-1] ]; }\n        else{              c.d='U'; c.b = origIdx[i-1]; }\n        out.push_back(c);\n    }\n    return out;\n}\n\n/*------------------------------------------------------------------*/\n/*  best layout for a given inclusion set                            */\n/*------------------------------------------------------------------*/\nLayout solve_one(const vector<Rec>& r)\n{\n    long double area=0; for(auto &rc:r) area+=(long double)rc.w*rc.h;\n    double W0 = sqrt((double)area);\n\n    /* wider candidate list \u2013 dense log-scale ---------------------- */\n    vector<double> factors;\n    for(double f=0.25; f<=5.0+1e-9; f*=sqrt(2.0)) factors.push_back(f);\n\n    Layout best; best.score=(1LL<<60);\n    for(double f:factors){\n        Layout cur = greedy_build(r,W0*f);\n        if(cur.score<best.score) best=cur;\n    }\n    improve(best,r);\n    return best;\n}\n\n/*------------------------------------------------------------------*/\n/*  whole solver with optional exclusions                            */\n/*------------------------------------------------------------------*/\nstruct Result{\n    int64 totalScore;\n    vector<Cmd> cmds;\n};\n\nResult solve_with_excl(const vector<Rec>& full,\n                       const vector<int>& excl)\n{\n    const int N = (int)full.size();\n    vector<char> excluded(N,0);\n    for(int idx:excl) excluded[idx]=1;\n\n    vector<Rec> sub;\n    vector<int> origIdx;\n    for(int i=0;i<N;++i) if(!excluded[i]){\n        sub.push_back(full[i]);\n        origIdx.push_back(i);\n    }\n    if(sub.empty()){          // must pack at least one rectangle\n        Result bad; bad.totalScore = (1LL<<60);\n        return bad;\n    }\n\n    /* run on original orientation -------------------------------- */\n    Layout best1 = solve_one(sub);\n\n    /* run on swapped --------------------------------------------- */\n    vector<Rec> swapped=sub; for(auto &rc:swapped) swap(rc.w,rc.h);\n    Layout tmp  = solve_one(swapped);\n    for(auto &b:tmp.ori) b ^= 1;                  // back-convert orientation\n    tmp.score = eval_exact(sub,tmp.ori,tmp.cut);\n\n    Layout best = (best1.score <= tmp.score ? best1 : tmp);\n\n    /* penalty for skipped rectangles ----------------------------- */\n    int64 penalty=0;\n    for(int idx:excl) penalty += full[idx].w + full[idx].h;\n\n    Result ans;\n    ans.totalScore = best.score + penalty;\n    ans.cmds = build_cmds(sub,best,origIdx);\n    return ans;\n}\n\n/*------------------------------------------------------------------*/\n/*  main                                                             */\n/*------------------------------------------------------------------*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N,T,sigma;\n    if(!(cin>>N>>T>>sigma)) return 0;\n    vector<Rec> rec(N);\n    for(int i=0;i<N;++i) cin>>rec[i].w>>rec[i].h;\n\n    /* -------- prepare up to four biggest rectangles ------------- */\n    vector<int> ord(N);\n    iota(ord.begin(),ord.end(),0);\n    sort(ord.begin(),ord.end(),[&](int a,int b){\n        return rec[a].w+rec[a].h > rec[b].w+rec[b].h;\n    });\n    vector<int> big;\n    for(int i=0;i<4 && i<N;++i) big.push_back(ord[i]);\n\n    /* -------- enumerate exclusion subsets (size \u22642) ------------- */\n    vector<vector<int>> exclSets = {{}};\n    for(int idx:big) exclSets.push_back({idx});\n    for(int i=0;i<(int)big.size();++i) for(int j=i+1;j<(int)big.size();++j)\n        exclSets.push_back({big[i],big[j]});\n\n    Result bestAll; bestAll.totalScore = (1LL<<60);\n    for(auto &S:exclSets){\n        Result cand = solve_with_excl(rec,S);\n        if(cand.totalScore < bestAll.totalScore) bestAll = std::move(cand);\n    }\n\n    /* -------- send the same best answer for all T turns --------- */\n    const auto &cmds = bestAll.cmds;\n    cout.setf(ios::fixed);               // (not important \u2013 keeps output clean)\n    for(int turn=0; turn<T; ++turn){\n        cout << cmds.size() << '\\n';\n        for(auto &c:cmds)\n            cout << c.p << ' ' << int(c.r) << ' ' << c.d << ' ' << c.b << '\\n';\n        cout << flush;\n\n        long long dummyW,dummyH;\n        if(!(cin>>dummyW>>dummyH)) return 0;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int LIMH   = 10;     // height limit\nconstexpr int UNASS  = -2;     // mark: not yet assigned\nconstexpr int VARCNT = 12;     // total number of root-selection rules\n\n/* ------------------------------------------------------------ helpers */\ninline double score_of(int variant,\n                       int Av,\n                       long long sumB,\n                       int cnt,\n                       long long bound)\n{\n    switch (variant) {\n        case  0: return double(Av);\n        case  1: return double(Av)*Av;\n        case  2: return double(Av)       / double(sumB);\n        case  3: return double(Av)*Av    / double(sumB);\n        case  4: return double(Av)*Av*Av / double(sumB);\n        case  5: return double(Av)       / double(cnt);\n        case  6: return double(Av)*Av    / double(cnt);\n        case  7: return 1.0 / double(sumB);\n        case  8: return 1.0 / double(cnt);\n        case  9: return -double(bound);                      // maximal bound\n        case 10: return double(Av) / double(bound);\n        case 11: return double(Av)*Av / double(bound);\n    }\n    return 1e100;          // should never happen\n}\n\n/* build a forest with a chosen root-selection variant; returns score */\nlong long make_forest(const vector<vector<int>>& g,\n                      const vector<vector<pair<int,uint8_t>>>& reach,\n                      const vector<int>& A,\n                      int variant,\n                      vector<int>& parent_out)\n{\n    int N = (int)A.size();\n    vector<char> covered(N, 0);\n    vector<int>  depth  (N, -1);\n    vector<int>  parent (N, UNASS);\n    int uncovered = N;\n\n    queue<int> q;\n\n    while (uncovered) {\n        double bestScore = 1e100;\n        int    bestRoot  = -1;\n\n        for (int v = 0; v < N; ++v) if (!covered[v]) {\n            long long sumB = 0, bound = 0;\n            int cnt = 0;\n            for (auto [u, d] : reach[v])\n                if (!covered[u]) {\n                    ++cnt;\n                    sumB  += A[u];\n                    bound += 1LL * (d + 1) * A[u];\n                }\n\n            double sc = score_of(variant, A[v], sumB, cnt, bound);\n            if (sc < bestScore) { bestScore = sc; bestRoot = v; }\n        }\n\n        /* grow a BFS tree (depth limited to 10) from bestRoot */\n        covered[bestRoot] = 1; --uncovered;\n        parent[bestRoot]  = -1;\n        depth [bestRoot]  = 0;\n        while (!q.empty()) q.pop();\n        q.push(bestRoot);\n\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (depth[v] == LIMH) continue;\n            for (int nb : g[v]) if (!covered[nb]) {\n                covered[nb] = 1; --uncovered;\n                parent[nb]  = v;\n                depth [nb]  = depth[v] + 1;\n                q.push(nb);\n            }\n        }\n    }\n\n    long long attr = 0;\n    for (int v = 0; v < N; ++v)\n        attr += 1LL * (depth[v] + 1) * A[v];\n\n    parent_out.swap(parent);\n    return attr;\n}\n\n/* ==================================================================== */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ------------ read input ---------------- */\n    int N, M, H_in;\n    if (!(cin >> N >> M >> H_in)) return 0;   // H_in is always 10\n    vector<int> A(N);\n    for (int &x : A) cin >> x;\n\n    vector<vector<int>> g(N);\n    for (int i = 0, u, v; i < M; ++i) {\n        cin >> u >> v;\n        g[u].push_back(v);\n        g[v].push_back(u);\n    }\n    /* coordinates not used */\n    for (int i = 0, xv, yv; i < N; ++i) cin >> xv >> yv;\n\n    /* sort adjacency by increasing beauty */\n    for (int v = 0; v < N; ++v)\n        sort(g[v].begin(), g[v].end(),\n             [&](int a, int b){ return A[a] < A[b]; });\n\n    /* pre-compute radius-10 neighbourhoods incl. distance */\n    vector<vector<pair<int,uint8_t>>> reach(N);\n    {\n        vector<int> dist(N);\n        queue<int> q;\n        for (int s = 0; s < N; ++s) {\n            fill(dist.begin(), dist.end(), -1);\n            dist[s] = 0;\n            q.push(s);\n            reach[s].push_back({s, 0});\n            while (!q.empty()) {\n                int v = q.front(); q.pop();\n                if (dist[v] == LIMH) continue;\n                for (int nb : g[v]) if (dist[nb] == -1) {\n                    dist[nb] = dist[v] + 1;\n                    q.push(nb);\n                    reach[s].push_back({nb, static_cast<uint8_t>(dist[nb])});\n                }\n            }\n        }\n    }\n\n    /* try all variants and keep the best forest */\n    long long bestAttr = -1;\n    vector<int> bestParent;\n\n    for (int var = 0; var < VARCNT; ++var) {\n        vector<int> par;\n        long long attr = make_forest(g, reach, A, var, par);\n        if (attr > bestAttr) {\n            bestAttr   = attr;\n            bestParent = std::move(par);\n        }\n    }\n\n    /* --------------- output ----------------- */\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << bestParent[i];\n    }\n    cout << '\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Option { int gid, dist; };              // candidate move for one Oni\nstruct Op     { char dir; int idx; };\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ------------------------------------------------ */\n    int N;                                     // 20 in every test\n    if (!(cin >> N)) return 0;\n    vector<string> G(N);\n    for (auto &s: G) cin >> s;\n\n    /* ---------- small helpers -------------------------------------------- */\n    auto clear_up    =[&](int r,int c){for(int i=0;i< r   ;++i) if(G[i][c]=='o') return false; return true;};\n    auto clear_down  =[&](int r,int c){for(int i=r+1;i<N  ;++i) if(G[i][c]=='o') return false; return true;};\n    auto clear_left  =[&](int r,int c){for(int j=0;j< c   ;++j) if(G[r][j]=='o') return false; return true;};\n    auto clear_right =[&](int r,int c){for(int j=c+1;j<N  ;++j) if(G[r][j]=='o') return false; return true;};\n\n    /* ---------- enumerate Oni -------------------------------------------- */\n    struct Oni { vector<Option> opt; };\n    vector<Oni> oni; oni.reserve(40);\n\n    for (int r=0;r<N;++r)\n        for (int c=0;c<N;++c) if (G[r][c]=='x') {\n            Oni o;\n            if (clear_up(r,c))    o.opt.push_back({ 0*20+c , r+1 });\n            if (clear_down(r,c))  o.opt.push_back({ 1*20+c , N-r });\n            if (clear_left(r,c))  o.opt.push_back({ 2*20+r , c+1 });\n            if (clear_right(r,c)) o.opt.push_back({ 3*20+r , N-c });\n            oni.push_back(move(o));\n        }\n    const int M = oni.size();                 // always 40\n    const int Gcnt = 80;                      // 4*20 groups\n\n    /* ---------- dist table ------------------------------------------------ */\n    vector<array<int,Gcnt>> dist(M);\n    for (int i=0;i<M;++i){ dist[i].fill(0); for(auto&op:oni[i].opt) dist[i][op.gid]=op.dist; }\n\n    /* ---------- initial assignment : shortest safe dir ------------------- */\n    vector<int> assign(M,-1);                 // gid of each Oni\n    array<vector<int>,Gcnt> members;          // members per group\n    array<int,Gcnt>         gMax{};           // max distance per group\n\n    for (int id=0; id<M; ++id){\n        int bestD=1e9,bestG=-1;\n        for(auto&op:oni[id].opt)\n            if (op.dist<bestD){bestD=op.dist;bestG=op.gid;}\n        assign[id]=bestG;\n        members[bestG].push_back(id);\n        gMax[bestG]=max(gMax[bestG],bestD);\n    }\n\n    /* ---------- tiny hill-climber (same as before) ----------------------- */\n    std::mt19937 rng(1234567);\n    bool better=true;\n    while(better){\n        better=false;\n        vector<int> order(M); iota(order.begin(),order.end(),0);\n        shuffle(order.begin(),order.end(),rng);\n\n        for(int id:order){\n            int g0=assign[id], d0=dist[id][g0], old0=gMax[g0];\n            int new0;\n            if (d0<old0) new0=old0;\n            else{\n                new0=0;\n                for(int o:members[g0]) if(o!=id) new0=max(new0,dist[o][g0]);\n            }\n            for(auto&op:oni[id].opt) if(op.gid!=g0){\n                int g1=op.gid, d1=op.dist, old1=gMax[g1];\n                int new1=max(old1,d1);\n                if (2*(new0-old0)+2*(new1-old1)<0){\n                    /* apply move */\n                    auto &v=members[g0];\n                    v.erase(remove(v.begin(),v.end(),id),v.end());\n                    gMax[g0]=new0;\n                    members[g1].push_back(id);\n                    gMax[g1]=new1;\n                    assign[id]=g1;\n                    better=true;\n                    break;\n                }\n            }\n        }\n    }\n\n    /* ---------- pick the no-return group --------------------------------- */\n    int lastG=-1, lastD=-1;\n    for(int g=0;g<Gcnt;++g) if(gMax[g]>lastD){lastD=gMax[g]; lastG=g;}\n\n    /* ---------- prepare operation list ----------------------------------- */\n    const char OUT[4]={'U','D','L','R'};\n    const char REV[4]={'D','U','R','L'};\n    vector<Op> ops; ops.reserve(1600);\n\n    auto emit=[&](char d,int idx,int cnt){ for(int k=0;k<cnt;++k) ops.push_back({d,idx}); };\n\n    /* 1. all normal groups (out + back) */\n    for(int g=0; g<Gcnt; ++g) if(g!=lastG && gMax[g]){\n        int dir=g/20, line=g%20, d=gMax[g];\n        emit(OUT[dir],line,d);\n        emit(REV[dir],line,d);\n    }\n\n    /* 2. final group (out only) */\n    if(lastD>0){\n        int dir=lastG/20, line=lastG%20;\n        emit(OUT[dir],line,lastD);\n    }\n\n    /* ---------- safety guard (theory says ops \u2264 1 599) ------------------- */\n    const int LIMIT = 4*N*N;                 // 1 600\n    if((int)ops.size()>LIMIT) ops.resize(LIMIT);\n\n    /* ---------- output --------------------------------------------------- */\n    for(auto&o:ops) cout<<o.dir<<' '<<o.idx<<'\\n';\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconstexpr int N     = 100;\nconstexpr int L     = 500'000;\nconstexpr int E     = 2 * N;        // 200 edges\nconstexpr int STEP  = L / E;        // 2500 visits per edge in the limit\n\n/* ------------------------------------------------------------------ */\n/*  Exact DP: choose k_i \u2208 {0..4}  with \u03a3k_i = 200  (minimise L\u00b9-error) */\nvector<int> optimal_indeg(const array<int,N>& T) {\n    const int INF = 1e9;\n    static int dp[N + 1][E + 1];\n    static uint8_t prevk[N + 1][E + 1];\n\n    dp[0][0] = 0;\n    for (int s = 1; s <= E; ++s) dp[0][s] = INF;\n\n    for (int i = 0; i < N; ++i) {\n        for (int s = 0; s <= E; ++s) dp[i + 1][s] = INF;\n        for (int s = 0; s <= E; ++s) if (dp[i][s] != INF) {\n            for (int k = 0; k <= 4 && s + k <= E; ++k) {\n                int v = dp[i][s] + abs(T[i] - STEP * k);\n                if (v < dp[i + 1][s + k]) {\n                    dp[i + 1][s + k] = v;\n                    prevk[i + 1][s + k] = k;\n                }\n            }\n        }\n    }\n    vector<int> k(N);\n    int s = E;\n    for (int i = N; i--;) {\n        k[i] = prevk[i + 1][s];\n        s   -= k[i];\n    }\n    return k;                                   // optimal multiset\n}\n\n/* ------------------------------------------------------------------ */\n/*  500 000-week rotor simulation                                      */\ninline ll simulate(const array<int,E>& dest,\n                   const array<int,N>& T,\n                   array<int,N>& cnt) {\n    cnt.fill(0);\n    int cur = 0;\n    for (int w = 0; w < L; ++w) {\n        ++cnt[cur];                             // this week\n        cur = dest[2 * cur + ((cnt[cur] & 1) ? 0 : 1)];\n    }\n    ll err = 0;\n    for (int i = 0; i < N; ++i) err += llabs(cnt[i] - T[i]);\n    return err;\n}\n\n/* ------------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyN, dummyL;\n    if (!(cin >> dummyN >> dummyL)) return 0;\n\n    array<int,N> T{};\n    for (int &x : T) cin >> x;\n\n    /* ---------- choose in-degrees optimally ---------- */\n    vector<int> k = optimal_indeg(T);\n\n    /* ---------- build the destination multiset ---------- */\n    vector<int> pool; pool.reserve(E);\n    for (int v = 0; v < N; ++v) for (int c = 0; c < k[v]; ++c) pool.push_back(v);\n\n    mt19937 rng((uint32_t)chrono::steady_clock::now()\n                    .time_since_epoch().count());\n\n    array<int,E> best{}, tmp{};\n    array<int,N> cnt{};\n    ll bestErr = (1LL << 60);\n\n    auto evaluate = [&](array<int,E>& d) {\n        for (int v = 0; v < N; ++v)           // forbid double self-loop traps\n            if (d[2*v] == v && d[2*v+1] == v) return;\n        ll e = simulate(d, T, cnt);\n        if (e < bestErr) { bestErr = e; best = d; }\n    };\n\n    /* ---------- 40 completely random graphs ---------- */\n    for (int g = 0; g < 40; ++g) {\n        shuffle(pool.begin(), pool.end(), rng);\n        for (int i = 0; i < E; ++i) tmp[i] = pool[i];\n\n        /* repair possible double self-loops quickly      */\n        for (int v = 0; v < N; ++v)\n            if (tmp[2*v] == v && tmp[2*v+1] == v) {\n                int idx = -1;\n                for (int e = 0; e < E; ++e) {\n                    int s = e / 2;\n                    if (s != v && tmp[e] != s) { idx = e; break; }\n                }\n                if (idx != -1) swap(tmp[2*v+1], tmp[idx]);\n            }\n        evaluate(tmp);\n    }\n\n    /* ---------- local hill-climbing (edge swaps / flips) ---------- */\n    const int LOCAL_ITERS = 320;              // safe within the 2 s limit\n    for (int it = 0; it < LOCAL_ITERS; ++it) {\n        tmp = best;\n        if (rng() & 1) {                      // swap two edges\n            int e1 = rng() % E, e2;\n            do e2 = rng() % E; while (e2 == e1);\n            swap(tmp[e1], tmp[e2]);\n            int s1 = e1 / 2, s2 = e2 / 2;\n            if ((tmp[2*s1] == s1 && tmp[2*s1+1] == s1) ||\n                (tmp[2*s2] == s2 && tmp[2*s2+1] == s2))\n                continue;                     // would create a trap\n        } else {                              // flip orientation\n            int v = rng() % N;\n            swap(tmp[2*v], tmp[2*v+1]);\n            if (tmp[2*v] == v && tmp[2*v+1] == v) continue;\n        }\n        evaluate(tmp);\n    }\n\n    /* ---------- output best plan ---------- */\n    for (int v = 0; v < N; ++v)\n        cout << best[2*v] << ' ' << best[2*v+1] << '\\n';\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*--------------------------- Hilbert order -----------------------------*/\nstatic inline uint64_t hilbertOrder(int x, int y) {\n    const int B = 14;                     // 2^14 = 16384 > 10000\n    uint64_t d = 0;\n    for (int s = B - 1; s >= 0; --s) {\n        int rx = (x >> s) & 1;\n        int ry = (y >> s) & 1;\n        uint64_t idx = (rx ^ ry) | (ry << 1);     // 0,1,2,3\n        d = (d << 2) | idx;\n        if (!ry) {\n            if (rx) { x = ((1 << B) - 1) - x; y = ((1 << B) - 1) - y; }\n            swap(x, y);\n        }\n    }\n    return d;\n}\nstatic inline int64_t dist2(int x1,int y1,int x2,int y2){\n    int64_t dx=x1-x2, dy=y1-y2; return dx*dx+dy*dy;\n}\n/*--------------------------- DSU ---------------------------------------*/\nstruct DSU{\n    vector<int> p, sz;\n    DSU(int n=0){ init(n); }\n    void init(int n){ p.resize(n); sz.assign(n,1); iota(p.begin(),p.end(),0);}\n    int find(int v){ return p[v]==v? v : p[v]=find(p[v]); }\n    bool unite(int a,int b){\n        a=find(a); b=find(b); if(a==b) return false;\n        if(sz[a]<sz[b]) swap(a,b);\n        p[b]=a; sz[a]+=sz[b]; return true;\n    }\n};\n/*--------------------------- ask_query ---------------------------------*/\nvoid ask_query(const vector<int>& subset,\n               vector<pair<int,int>>& out)\n{\n    cout << \"? \" << subset.size();\n    for (int v: subset) cout << ' ' << v;\n    cout << '\\n' << flush;\n\n    for (int i = 0; i < (int)subset.size() - 1; ++i) {\n        int a, b; cin >> a >> b;\n        out.emplace_back(a, b);\n    }\n}\n/*--------------------------- main --------------------------------------*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* input */\n    int N,M,Q,L,W; cin>>N>>M>>Q>>L>>W;\n    vector<int> G(M); for(int &g:G) cin>>g;\n\n    struct City{ int id,lx,rx,ly,ry,cx,cy; uint64_t hil; };\n    vector<City> city(N);\n    for(int i=0;i<N;++i){\n        int lx,rx,ly,ry; cin>>lx>>rx>>ly>>ry;\n        int cx=(lx+rx)/2, cy=(ly+ry)/2;\n        int sx=(cx*16383)/10000, sy=(cy*16383)/10000;\n        city[i]={i,lx,rx,ly,ry,cx,cy,hilbertOrder(sx,sy)};\n    }\n\n    /* Hilbert sort */\n    vector<int> hilSorted(N); iota(hilSorted.begin(),hilSorted.end(),0);\n    sort(hilSorted.begin(),hilSorted.end(),\n         [&](int a,int b){ return city[a].hil<city[b].hil;});\n\n    /* create groups ---------------------------------------------------- */\n    vector<vector<int>> groups(M);\n    size_t pos=0;\n    for(int i=0;i<M;++i){\n        groups[i].reserve(G[i]);\n        for(int k=0;k<G[i];++k) groups[i].push_back(hilSorted[pos++]);\n    }\n\n    /* container for roads */\n    vector<vector<pair<int,int>>> edges(M);\n\n    /* ---------- Phase 1 : exact MST for groups of size 3 \u2026 L ---------- */\n    int queries_used = 0;\n    for(int i=0;i<M;++i){\n        int sz = groups[i].size();\n        if(3 <= sz && sz <= L){\n            ask_query(groups[i], edges[i]);\n            ++queries_used;\n        }\n    }\n    int queries_left = Q - queries_used;\n\n    /* ---------- Phase 2 : trivial groups size 1 / 2 ------------------- */\n    for(int i=0;i<M;++i){\n        if(groups[i].size()==2)\n            edges[i]={{groups[i][0], groups[i][1]}};\n    }\n\n    /* indices of large groups sorted by size (descending) */\n    vector<int> largeIdx;\n    for(int i=0;i<M;++i) if(groups[i].size() > L) largeIdx.push_back(i);\n    sort(largeIdx.begin(), largeIdx.end(),\n         [&](int a,int b){ return groups[a].size() > groups[b].size(); });\n\n    /* ---------- Phase 3 : handle each large group --------------------- */\n    vector<int> id2pos(N);\n    for(int gi: largeIdx){\n        auto &g = groups[gi];\n        int k = g.size();\n\n        /* split into blocks of size \u2264 L, all blocks >= 2 */\n        vector<vector<int>> blocks;\n        blocks.reserve((k+L-1)/L);\n        int idx = 0;\n        while(idx < k){\n            int rest = k - idx;\n            int sz = min(L, rest);\n            if(rest - sz == 1) --sz;                   // avoid size-1 block\n            blocks.emplace_back(g.begin()+idx, g.begin()+idx+sz);\n            idx += sz;\n        }\n        int B = blocks.size();\n\n        /* queries needed for this group */\n        int needBlock = B;\n        int needConnectMax = B - 1;      // we may use fewer if queries run out\n\n        if(queries_left < needBlock){    // no queries possible -> fallback\n            /* Prim on centre distances */\n            const int INF=1e9;\n            vector<int64_t> best(k,LLONG_MAX);\n            vector<int> parent(k,-1); vector<char> done(k,0);\n            for(int j=0;j<k;++j) id2pos[g[j]]=j;\n            best[0]=0;\n            for(int step=0;step<k;++step){\n                int v=-1; int64_t bd=LLONG_MAX;\n                for(int i=0;i<k;++i) if(!done[i] && best[i]<bd){ bd=best[i]; v=i;}\n                done[v]=1;\n                if(parent[v]!=-1) edges[gi].push_back({g[v], g[parent[v]]});\n                for(int u=0;u<k;++u) if(!done[u]){\n                    int64_t d = dist2(city[g[v]].cx,city[g[v]].cy,\n                                       city[g[u]].cx,city[g[u]].cy);\n                    if(d < best[u]){ best[u]=d; parent[u]=v; }\n                }\n            }\n            continue;\n        }\n\n        /* --- block MSTs ---------------------------------------------- */\n        for(auto &blk: blocks){\n            ask_query(blk, edges[gi]);\n            --queries_left; ++queries_used;\n        }\n\n        /* DSU on nodes to know current components */\n        for(int j=0;j<k;++j) id2pos[g[j]]=j;\n        DSU dsu(k);\n        for(auto [a,b]:edges[gi]) dsu.unite(id2pos[a], id2pos[b]);\n\n        /* --- build candidate edges between blocks -------------------- */\n        struct Cand{ int u,v; int64_t d; };\n        vector<Cand> cand;\n        cand.reserve(B*(B-1)/2);\n        for(int bi=0; bi<B; ++bi){\n            for(int bj=bi+1; bj<B; ++bj){\n                int bestU=-1,bestV=-1; int64_t bestD=LLONG_MAX;\n                for(int u:blocks[bi])\n                    for(int v:blocks[bj]){\n                        int64_t d = dist2(city[u].cx,city[u].cy,\n                                           city[v].cx,city[v].cy);\n                        if(d<bestD){ bestD=d; bestU=u; bestV=v; }\n                    }\n                cand.push_back({bestU,bestV,bestD});\n            }\n        }\n        sort(cand.begin(), cand.end(),\n             [](const Cand&a,const Cand&b){ return a.d < b.d; });\n\n        /* --- add connecting edges ------------------------------------ */\n        for(auto &e:cand){\n            if(edges[gi].size() == (size_t)k-1) break;\n            int aPos=id2pos[e.u], bPos=id2pos[e.v];\n            if(dsu.find(aPos)==dsu.find(bPos)) continue;\n\n            if(queries_left>0){\n                vector<pair<int,int>> tmp;\n                ask_query({e.u, e.v}, tmp);          // exactly one edge\n                --queries_left; ++queries_used;\n                edges[gi].push_back(tmp[0]);\n                dsu.unite(id2pos[tmp[0].first], id2pos[tmp[0].second]);\n            }else{\n                edges[gi].push_back({e.u, e.v});\n                dsu.unite(aPos, bPos);\n            }\n        }\n        /* If something is still missing (very unlikely) use centre edges */\n        if(edges[gi].size() < (size_t)k-1){\n            for(auto &e:cand){\n                int aPos=id2pos[e.u], bPos=id2pos[e.v];\n                if(dsu.unite(aPos,bPos))\n                    edges[gi].push_back({e.u,e.v});\n                if(edges[gi].size()==(size_t)k-1) break;\n            }\n        }\n    }\n\n#ifndef NDEBUG\n    for(int i=0;i<M;++i)\n        assert(edges[i].size() == groups[i].size()-1);\n#endif\n\n    /* ----------------- final output --------------------------------- */\n    cout<<\"!\\n\";\n    for(int i=0;i<M;++i){\n        for(size_t j=0;j<groups[i].size();++j){\n            if(j) cout<<' ';\n            cout<<groups[i][j];\n        }\n        cout<<'\\n';\n        for(auto [a,b]:edges[i]) cout<<a<<' '<<b<<'\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*-------------------------------------------------*/\n/*  basic geometry                                 */\n/*-------------------------------------------------*/\nconstexpr int N  = 20;\nconstexpr int SZ = N * N;\nconst int dx[4]   = {-1, 1, 0, 0};\nconst int dy[4]   = { 0, 0,-1, 1};\nconst char DIR[4] = {'U','D','L','R'};\ninline int  id(int r,int c){ return r * N + c; }\ninline auto rc(int v){ return pair{v / N, v % N}; }\ninline int  opposite(int d){ return d ^ 1; }   // 0<->1, 2<->3\n\n/*-------------------------------------------------*/\n/*  one elementary action                          */\n/*-------------------------------------------------*/\nstruct Step{ char act, dir; };\n\n/*-------------------------------------------------*/\n/*  BFS utilities (static board)                   */\n/*-------------------------------------------------*/\nint bfsDist(const array<bool,SZ>& wall,int s,int g)\n{\n    static array<int,SZ> dist;\n    dist.fill(-1);\n    queue<int> q;\n    dist[s]=0; q.push(s);\n\n    while(!q.empty()){\n        int v=q.front(); q.pop();\n        if(v==g) return dist[v];\n        auto [r,c]=rc(v);\n\n        for(int d=0; d<4; ++d){\n            int nr=r+dx[d], nc=c+dy[d];\n            if(0<=nr&&nr<N&&0<=nc&&nc<N&&!wall[id(nr,nc)]){\n                int nv=id(nr,nc);\n                if(dist[nv]==-1){ dist[nv]=dist[v]+1; q.push(nv); }\n            }\n\n            int sr=r, sc=c;\n            while(true){\n                int tr=sr+dx[d], tc=sc+dy[d];\n                if(tr<0||tr>=N||tc<0||tc>=N||wall[id(tr,tc)]) break;\n                sr=tr; sc=tc;\n            }\n            int sv=id(sr,sc);\n            if(sv!=v && dist[sv]==-1){\n                dist[sv]=dist[v]+1; q.push(sv);\n            }\n        }\n    }\n    return 1e9;                    // should never happen\n}\n\nvector<Step> bfsPath(const array<bool,SZ>& wall,int s,int g)\n{\n    static array<int,SZ> dist, prv;\n    static array<char,SZ> pact,pdir;\n    dist.fill(-1);\n    queue<int> q;\n    dist[s]=0; q.push(s);\n\n    while(!q.empty()){\n        int v=q.front(); q.pop();\n        if(v==g) break;\n        auto [r,c]=rc(v);\n\n        for(int d=0; d<4; ++d){\n            char dc=DIR[d];\n\n            int nr=r+dx[d], nc=c+dy[d];\n            if(0<=nr&&nr<N&&0<=nc&&nc<N&&!wall[id(nr,nc)]){\n                int nv=id(nr,nc);\n                if(dist[nv]==-1){\n                    dist[nv]=dist[v]+1; prv[nv]=v;\n                    pact[nv]='M'; pdir[nv]=dc; q.push(nv);\n                }\n            }\n            int sr=r, sc=c;\n            while(true){\n                int tr=sr+dx[d], tc=sc+dy[d];\n                if(tr<0||tr>=N||tc<0||tc>=N||wall[id(tr,tc)]) break;\n                sr=tr; sc=tc;\n            }\n            int sv=id(sr,sc);\n            if(sv!=v && dist[sv]==-1){\n                dist[sv]=dist[v]+1; prv[sv]=v;\n                pact[sv]='S'; pdir[sv]=dc; q.push(sv);\n            }\n        }\n    }\n    vector<Step> path;\n    for(int v=g; v!=s; v=prv[v])\n        path.push_back({pact[v],pdir[v]});\n    reverse(path.begin(),path.end());\n    return path;\n}\n\n/*-------------------------------------------------*/\n/*  helper: cost of the next H segments            */\n/*-------------------------------------------------*/\nint horizonCost(const array<bool,SZ>& wall,\n                const vector<int>& order,int startIdx,\n                int startPos,int H)\n{\n    int pos=startPos, cost=0;\n    int m=order.size();\n    for(int k=startIdx; k<min(m,startIdx+H); ++k){\n        int nxt=order[k];\n        cost += bfsDist(wall,pos,nxt);\n        pos = nxt;\n    }\n    return cost;\n}\n\n/*-------------------------------------------------*/\n/*                    main                         */\n/*-------------------------------------------------*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyN, M;\n    if(!(cin>>dummyN>>M)) return 0;\n    vector<int> order;            // flattened coordinates of start+targets\n    order.reserve(M);\n    for(int i=0;i<M;++i){\n        int r,c; cin>>r>>c;\n        order.push_back(id(r,c));\n    }\n\n    array<bool,SZ> wall{};        // permanent walls we decide to leave\n    vector<Step> answer;\n\n    int cur = order[0];\n    constexpr int H = 5;          // look-ahead depth\n\n    for(int idx=1; idx<M; ++idx){\n        int goal = order[idx];\n\n        /* baseline --------------------------------------------*/\n        int baseSeg    = bfsDist(wall,cur,goal);\n        int baseFuture = horizonCost(wall,order,idx,goal,H-1);\n        int bestTotal  = baseSeg + baseFuture;\n        int bestDir    = -1;          // no block by default\n\n        /* try to leave a blocker on the current square --------*/\n        if(!wall[cur]){\n            auto [r,c]=rc(cur);\n            for(int d=0; d<4; ++d){\n                int nr=r+dx[d], nc=c+dy[d];\n                if(nr<0||nr>=N||nc<0||nc>=N) continue;\n                int nid=id(nr,nc);\n                if(wall[nid]) continue;\n                if(nid==goal) continue;                // cannot stand on goal\n\n                wall[cur]=true;                        // virtual block\n                int seg    = bfsDist(wall,nid,goal);\n                int future = horizonCost(wall,order,idx,goal,H-1);\n                wall[cur]=false;\n\n                if(seg>=1e9) continue;                 // unreachable (rare)\n\n                int tot = 2 + seg + future;            // M + A + path\n                if(tot < bestTotal){\n                    bestTotal = tot;\n                    bestDir = d;\n                }\n            }\n        }\n\n        /* produce the real actions ----------------------------*/\n        if(bestDir == -1){\n            vector<Step> p = bfsPath(wall,cur,goal);\n            answer.insert(answer.end(),p.begin(),p.end());\n        }else{\n            int d=bestDir;\n            int nr = rc(cur).first  + dx[d];\n            int nc = rc(cur).second + dy[d];\n            int nid=id(nr,nc);\n\n            /* M + A */\n            answer.push_back({'M',DIR[d]});\n            answer.push_back({'A',DIR[opposite(d)]});\n            wall[cur]=true;\n\n            vector<Step> p = bfsPath(wall,nid,goal);\n            answer.insert(answer.end(),p.begin(),p.end());\n        }\n        cur=goal;\n    }\n\n    /* output --------------------------------------------------*/\n    for(auto st:answer) cout<<st.act<<' '<<st.dir<<'\\n';\n    return 0;\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int LIM = 10000;                 // board size\n\nstruct Rect{ int a,b,c,d; };               // [a,c) \u00d7 [b,d)\n\n/* overlap helpers ---------------------------------------------------- */\ninline bool ov1d(int l1,int r1,int l2,int r2){\n    return max(l1,l2) < min(r1,r2);\n}\ninline bool intersect(const Rect& A,const Rect& B){\n    return ov1d(A.a,A.c,B.a,B.c) && ov1d(A.b,A.d,B.b,B.d);\n}\ninline double sat(long long need,long long have){\n    double mi=min<double>(need,have), ma=max<double>(need,have);\n    double t=1.0-mi/ma;\n    return 1.0-t*t;\n}\n\n/* distance until the next obstacle for rect i, side 0=L 1=R 2=D 3=U */\nint free_delta(const vector<Rect>& R,int i,int side){\n    const Rect& cur=R[i];\n    int d=0;\n    if(side==0){            // LEFT\n        d=cur.a;\n        for(size_t j=0;j<R.size();++j) if((int)j!=i)\n            if(ov1d(cur.b,cur.d,R[j].b,R[j].d) && R[j].c<=cur.a)\n                d=min(d,cur.a-R[j].c);\n    }else if(side==1){      // RIGHT\n        d=LIM-cur.c;\n        for(size_t j=0;j<R.size();++j) if((int)j!=i)\n            if(ov1d(cur.b,cur.d,R[j].b,R[j].d) && R[j].a>=cur.c)\n                d=min(d,R[j].a-cur.c);\n    }else if(side==2){      // DOWN\n        d=cur.b;\n        for(size_t j=0;j<R.size();++j) if((int)j!=i)\n            if(ov1d(cur.a,cur.c,R[j].a,R[j].c) && R[j].d<=cur.b)\n                d=min(d,cur.b-R[j].d);\n    }else{                  // UP\n        d=LIM-cur.d;\n        for(size_t j=0;j<R.size();++j) if((int)j!=i)\n            if(ov1d(cur.a,cur.c,R[j].a,R[j].c) && R[j].b>=cur.d)\n                d=min(d,R[j].b-cur.d);\n    }\n    return d;\n}\n\n/* ------------------------------------------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int 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    /* --- initial 1\u00d71 rectangles ------------------------------------- */\n    vector<Rect>        rect(n);\n    vector<long long>   area(n,1);\n    vector<double>      p(n);\n    double score=0;\n    for(int i=0;i<n;++i){\n        rect[i]={x[i],y[i],x[i]+1,y[i]+1};\n        p[i]=sat(r[i],1); score+=p[i];\n    }\n    double bestScore=score;\n    auto bestRect=rect; auto bestArea=area; auto bestP=p;\n\n    /* --- simulated annealing ---------------------------------------- */\n    mt19937 rng((uint32_t)chrono::steady_clock::now()\n                   .time_since_epoch().count());\n    uniform_real_distribution<double> urd(0,1);\n    const double TL=4.9, T0=5e-2, T1=1e-4;\n    auto t0=chrono::steady_clock::now();\n\n    while(true){\n        double elapsed=chrono::duration<double>(\n                           chrono::steady_clock::now()-t0).count();\n        if(elapsed>TL) break;\n        double temp=T0+(T1-T0)*(elapsed/TL);\n\n        int i=rng()%n;\n        const Rect cur=rect[i]; const long long curA=area[i];\n        const double curP=p[i];\n        long long diff=r[i]-curA;\n\n        Rect neu=cur;\n        long long newA=curA; double newP=curP; double dS=0.0;\n\n        /* ------------ translation (prob. 1/3) ----------------------- */\n        if(urd(rng)<0.333){\n            int dxMin=max(-cur.a, (x[i]+1)-cur.c);\n            int dxMax=min(LIM-cur.c,  x[i]-cur.a);\n            int dyMin=max(-cur.b, (y[i]+1)-cur.d);\n            int dyMax=min(LIM-cur.d,  y[i]-cur.b);\n            if(dxMin>dxMax || dyMin>dyMax) continue;\n            int dx=dxMin + rng()%(dxMax-dxMin+1);\n            int dy=dyMin + rng()%(dyMax-dyMin+1);\n            if(dx==0 && dy==0) continue;\n            neu.a+=dx; neu.c+=dx; neu.b+=dy; neu.d+=dy;\n\n            bool ok=true;\n            for(int j=0;j<n && ok;++j)\n                if(j!=i && intersect(neu,rect[j])) ok=false;\n            if(!ok) continue;              // reject\n\n            /* score unchanged */\n        }else{                            /* grow / shrink one side */\n            bool expand = diff>0;\n            if(urd(rng)<0.20) expand=!expand;\n            int dir=rng()&3;\n\n            int deltaMax;\n            if(dir==0)      deltaMax=expand?cur.a\n                                           :min(cur.c-cur.a-1,x[i]-cur.a);\n            else if(dir==1) deltaMax=expand?LIM-cur.c\n                                           :min(cur.c-cur.a-1,cur.c-(x[i]+1));\n            else if(dir==2) deltaMax=expand?cur.b\n                                           :min(cur.d-cur.b-1,y[i]-cur.b);\n            else            deltaMax=expand?LIM-cur.d\n                                           :min(cur.d-cur.b-1,cur.d-(y[i]+1));\n            if(deltaMax<=0) continue;\n\n            int w=cur.c-cur.a, h=cur.d-cur.b, per=(dir<=1?h:w);\n            int delta= expand?min<int>(deltaMax,\n                              max<long long>(1,(llabs(diff)+per-1)/per))\n                             :1+rng()%deltaMax;\n            if(delta<=0) continue;\n\n            auto apply=[&](int d){\n                neu=cur;\n                if(expand){\n                    if(dir==0) neu.a-=d; else if(dir==1) neu.c+=d;\n                    else if(dir==2) neu.b-=d; else        neu.d+=d;\n                }else{\n                    if(dir==0) neu.a+=d; else if(dir==1) neu.c-=d;\n                    else if(dir==2) neu.b+=d; else        neu.d-=d;\n                }\n            };\n\n            apply(delta);\n            bool ok=true;\n            for(int j=0;j<n && ok;++j)\n                if(j!=i && intersect(neu,rect[j])) ok=false;\n\n            if(!ok && expand){            // too large -> cut to exact free \u0394\n                int fd=free_delta(rect,i,dir);\n                if(fd<=0) continue;\n                delta=fd;\n                apply(delta);\n                ok=true;\n                for(int j=0;j<n && ok;++j)\n                    if(j!=i && intersect(neu,rect[j])) ok=false;\n            }\n            if(!ok) continue;\n\n            newA=1LL*(neu.c-neu.a)*(neu.d-neu.b);\n            newP=sat(r[i],newA);\n            dS=newP-curP;\n        }\n\n        if(dS>=0.0 || urd(rng)<exp(dS/temp)){\n            rect[i]=neu; area[i]=newA; p[i]=newP; score+=dS;\n            if(score>bestScore){\n                bestScore=score; bestRect=rect; bestArea=area; bestP=p;\n            }\n        }\n    }\n\n    /* -------- deterministic shrink / grow loop ---------------------- */\n    auto shrink_large=[&](){\n        bool ch=false;\n        for(int i=0;i<n;++i){\n            while(bestArea[i]>r[i]){\n                Rect cur=bestRect[i]; int w=cur.c-cur.a, h=cur.d-cur.b;\n                long long diff=bestArea[i]-r[i];\n                struct S{int side,per,lim;};\n                array<S,4> c{{\n                    {0,h, x[i]-cur.a},\n                    {1,h, cur.c-(x[i]+1)},\n                    {2,w, y[i]-cur.b},\n                    {3,w, cur.d-(y[i]+1)}\n                }};\n                int bs=-1,bd=0; long long br=LLONG_MAX;\n                for(auto s:c){\n                    if(s.lim<=0) continue;\n                    int d=min<int>(s.lim,(diff+s.per-1)/s.per);\n                    long long resid=llabs(diff-1LL*d*s.per);\n                    if(resid<br){ br=resid; bs=s.side; bd=d; }\n                }\n                if(bs==-1) break;\n                switch(bs){\n                    case 0: bestRect[i].a+=bd; break;\n                    case 1: bestRect[i].c-=bd; break;\n                    case 2: bestRect[i].b+=bd; break;\n                    case 3: bestRect[i].d-=bd; break;\n                }\n                bestArea[i]-=1LL*bd*(bs<=1?h:w); ch=true;\n            }\n            bestP[i]=sat(r[i],bestArea[i]);\n        }\n        return ch;\n    };\n    auto grow_small=[&](){\n        bool ch=false;\n        for(int i=0;i<n;++i){\n            while(bestArea[i]<r[i]){\n                Rect cur=bestRect[i]; int w=cur.c-cur.a, h=cur.d-cur.b;\n                long long need=r[i]-bestArea[i];\n                int bs=-1,bd=0; long long bestGain=0;\n                for(int side=0;side<4;++side){\n                    int per=(side<=1?h:w); if(per==0) continue;\n                    int fd=free_delta(bestRect,i,side); if(fd<=0) continue;\n                    int d=min<int>(fd,(need+per-1)/per); if(d<=0) continue;\n                    long long gain=1LL*d*per;\n                    if(gain>bestGain){ bestGain=gain; bs=side; bd=d; }\n                }\n                if(bs==-1) break;\n                switch(bs){\n                    case 0: bestRect[i].a-=bd; break;\n                    case 1: bestRect[i].c+=bd; break;\n                    case 2: bestRect[i].b-=bd; break;\n                    case 3: bestRect[i].d+=bd; break;\n                }\n                bestArea[i]+=bestGain; ch=true;\n            }\n            bestP[i]=sat(r[i],bestArea[i]);\n        }\n        return ch;\n    };\n\n    for(int loop=0; loop<50; ++loop){\n        bool changed=false;\n        changed |= shrink_large();\n        changed |= grow_small();\n        if(!changed) break;\n    }\n    shrink_large();                       // final tidy\n\n    /* --------------- output ------------------------------------------ */\n    for(const auto& re: bestRect)\n        cout<<re.a<<' '<<re.b<<' '<<re.c<<' '<<re.d<<\"\\n\";\n    return 0;\n}","ahc002":"/********  AHC-type heuristic solver \u2013 final compact version  ********\n *  \u2013 50 \u00d7 50 board, each tile 1\u00d71 / 1\u00d72 / 2\u00d71 (id in t[][])\n *  \u2013 one tile may be stepped on at most once\n *  \u2013 goal: produce a long high-value walk\n *\n *  Strategy\n *  --------\n *  1. Thousands of ultra-cheap greedy walks (~1.55 s)\n *  2. If the best result is still very small (< 5000), run one\n *     \u201csafety-net\u201d walk that maximises the future playground\n *     (reach count of still unused tiles).  Improved:\n *        ignore neighbours with degree==0 while at least one\n *        candidate with degree>0 exists.\n *  3. Remainder of the 2.0 s for more greedy restarts.\n ********************************************************************/\n#include <bits/stdc++.h>\nusing namespace std;\n\n/*** xoroshiro128+ ***********************************************************/\nstruct Xoroshiro{\n    using ull = unsigned long long; ull s[2];\n    static ull rotl(ull x,int k){return (x<<k)|(x>>(64-k));}\n    static ull splitmix64(ull &x){ ull z=(x+=0x9e3779b97f4a7c15ULL);\n      z=(z^(z>>30))*0xbf58476d1ce4e5b9ULL; z=(z^(z>>27))*0x94d049bb133111ebULL;\n      return z^(z>>31);}\n    explicit Xoroshiro(ull seed){\n        ull x=seed?seed:0x123456789abcdefULL;\n        s[0]=splitmix64(x); s[1]=splitmix64(x);\n    }\n    ull next(){ ull r=s[0]+s[1]; ull x=s[0],y=s[1];\n      s[1]^=x; s[0]=rotl(x,24)^y^(y<<16); s[1]=rotl(y,37); return r;}\n    int randint(int n){return int(next()%n);}\n    double real01(){return (next()>>11)*(1.0/9007199254740992.0);}\n};\n\n/*** constants **************************************************************/\nconstexpr int H=50, W=50, DIR=4;\nconst int dr[DIR]={-1,1,0,0};\nconst int dc[DIR]={0,0,-1,1};\nconst char dch[DIR]={'U','D','L','R'};\ninline int cid(int r,int c){ return r*W+c; }\n\n/*** global data ************************************************************/\nint si,sj;\nint tile[H][W];          // tile id\nint val [H][W];          // cell score\nint lost[H][W];          // value of partner cell inside same tile (0 for 1\u00d71)\nint M;                    // number of tiles\narray<int,DIR> diffNbr[H*W];     // neighbour cell id with DIFFERENT tile or -1\nvector<vector<int>> tileAdj;     // adjacency list on tile graph (undirected)\n\n/*** helpers ***************************************************************/\ninline int degree_after(int cellId,const vector<char>& vis,int selfTile){\n    int d=0;\n    for(int k=0;k<DIR;++k){\n        int nb = diffNbr[cellId][k]; if(nb==-1) continue;\n        int t  = tile[nb/W][nb%W];\n        if(t==selfTile||vis[t]) continue;\n        ++d;\n    }\n    return d;\n}\n\n/*** fast greedy walk *******************************************************/\nstruct Walk{ long long score; string path; };\n\nWalk greedy_walk(Xoroshiro& rng, vector<char>& vis){\n    int style = rng.randint(3);\n    int lambda = style==0 ?  (rng.randint(31)+10)    //  10 \u2026 40\n               : style==1 ? -(rng.randint(31)+10)    // \u221240 \u2026 \u221210\n                           :  (rng.randint(41)+40);  //  40 \u2026 80\n    bool use2  = rng.randint(6)==0;                  // ~16 % use 2-ply\n    double alpha = 0.25*(1.0+0.5*rng.real01());\n    double beta  = 0.5 + 0.3*rng.real01();\n\n    fill(vis.begin(), vis.end(), 0);\n    string path; path.reserve(H*W);\n    int r=si, c=sj; vis[tile[r][c]]=1;\n    long long score = val[r][c];\n\n    int ord[DIR];\n    auto shuffle4=[&](int* a){\n        a[0]=0;a[1]=1;a[2]=2;a[3]=3;\n        for(int i=3;i>0;--i) swap(a[i],a[rng.randint(i+1)]);\n    };\n\n    const int EARLY=200;        // before length 200 avoid dead ends\n\n    while(true){\n        shuffle4(ord);\n        int cur = cid(r,c);\n        int bestDir=-1; double bestEval=-1e100;\n        int len = (int)path.size()+1;\n\n        for(int k=0;k<DIR;++k){\n            int d=ord[k];\n            int nid=diffNbr[cur][d]; if(nid==-1) continue;\n            int nr=nid/W, nc=nid%W, tId=tile[nr][nc];\n            if(vis[tId]) continue;\n\n            int deg1 = degree_after(nid,vis,tId);\n            if(deg1==0 && len<EARLY) continue;\n\n            double eval = val[nr][nc] - alpha*lost[nr][nc] + lambda*deg1;\n\n            if(use2){\n                double best2=-1e100;\n                for(int d2=0; d2<DIR; ++d2){\n                    int nn=diffNbr[nid][d2]; if(nn==-1) continue;\n                    int rr=nn/W, cc=nn%W, tt=tile[rr][cc];\n                    if(tt==tId || vis[tt]) continue;\n                    int deg2=degree_after(nn,vis,tt);\n                    best2 = max(best2,\n                                val[rr][cc]-alpha*lost[rr][cc]+lambda*deg2);\n                }\n                if(best2>-1e90) eval += beta*best2;\n            }\n            eval += rng.randint(3)*1e-3;   // tiny noise\n            if(eval>bestEval){ bestEval=eval; bestDir=d; }\n        }\n        if(bestDir==-1) break;             // trapped\n\n        r += dr[bestDir]; c += dc[bestDir];\n        vis[tile[r][c]] = 1;\n        score += val[r][c];\n        path.push_back(dch[bestDir]);\n    }\n    return {score, move(path)};\n}\n\n/*** size of still reachable tile set ***************************************/\nint reachable_tiles(const vector<char>& vis, int startTile){\n    static vector<int> seen; static int qBuf[2500]; static int stamp=0;\n    if(seen.empty()) seen.assign(M,0);\n    ++stamp; int head=0,tail=0,cnt=0;\n    seen[startTile]=stamp; qBuf[tail++]=startTile;\n    while(head<tail){\n        int t=qBuf[head++];\n        for(int nb:tileAdj[t]){\n            if(vis[nb] || seen[nb]==stamp) continue;\n            seen[nb]=stamp; qBuf[tail++]=nb; ++cnt;\n        }\n    }\n    return cnt;   // tiles except start\n}\n\n/*** robust safety-net walk (improved) **************************************/\nWalk bfs_walk(const chrono::steady_clock::time_point& deadline){\n    vector<char> vis(M,0);\n    string path; path.reserve(H*W);\n    int r=si, c=sj; vis[tile[r][c]]=1;\n    long long score = val[r][c];\n\n    while(chrono::steady_clock::now()<deadline){\n        struct Cand{int dir,deg,reach,val;};\n        Cand best{-1,0,-1,-1};\n        bool existsPos=false;\n        Cand cand[DIR]; int cnt=0;\n\n        int cur=cid(r,c);\n        for(int d=0; d<DIR; ++d){\n            int nid=diffNbr[cur][d]; if(nid==-1) continue;\n            int nr=nid/W, nc=nid%W, tId=tile[nr][nc];\n            if(vis[tId]) continue;\n\n            int deg1 = degree_after(nid,vis,tId);\n            vis[tId]=1;\n            int reach = reachable_tiles(vis,tId);\n            vis[tId]=0;\n\n            cand[cnt++] = {d,deg1,reach,val[nr][nc]};\n            if(deg1>0) existsPos=true;\n        }\n        if(cnt==0) break;\n\n        for(int i=0;i<cnt;++i){\n            if(existsPos && cand[i].deg==0) continue;         // new line\n            if(cand[i].reach > best.reach ||\n               (cand[i].reach == best.reach && cand[i].val > best.val))\n                best = cand[i];\n        }\n        if(best.dir==-1) break;\n\n        r += dr[best.dir]; c += dc[best.dir];\n        vis[tile[r][c]] = 1;\n        score += val[r][c];\n        path.push_back(dch[best.dir]);\n    }\n    return {score, move(path)};\n}\n\n/***************************************************************************/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ---------------------------------------------- */\n    cin >> si >> sj;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cin >> tile[i][j];\n    M=0; for(int i=0;i<H;i++)for(int j=0;j<W;j++) M=max(M, tile[i][j]+1);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cin >> val[i][j];\n\n    /* ---------- lost value per cell ------------------------------------- */\n    vector<vector<pair<int,int>>> cells(M);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++)\n        cells[tile[i][j]].push_back({i,j});\n    for(int t=0;t<M;++t){\n        if(cells[t].size()==2){\n            auto p1=cells[t][0], p2=cells[t][1];\n            lost[p1.first][p1.second] = val[p2.first][p2.second];\n            lost[p2.first][p2.second] = val[p1.first][p1.second];\n        }else{\n            for(auto p:cells[t]) lost[p.first][p.second]=0;\n        }\n    }\n\n    /* ---------- neighbour table (different tile) ------------------------ */\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        for(int d=0; d<DIR; ++d){\n            int ni=i+dr[d], nj=j+dc[d];\n            diffNbr[cid(i,j)][d] =\n                (ni<0||nj<0||ni>=H||nj>=W||tile[ni][nj]==tile[i][j])\n                ? -1 : cid(ni,nj);\n        }\n    }\n\n    /* ---------- tile graph ---------------------------------------------- */\n    tileAdj.assign(M,{});\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int t=tile[i][j];\n        if(i+1<H && tile[i+1][j]!=t){\n            tileAdj[t].push_back(tile[i+1][j]);\n            tileAdj[tile[i+1][j]].push_back(t);\n        }\n        if(j+1<W && tile[i][j+1]!=t){\n            tileAdj[t].push_back(tile[i][j+1]);\n            tileAdj[tile[i][j+1]].push_back(t);\n        }\n    }\n\n    /* ---------- iterative improvement ----------------------------------- */\n    const auto tStart = chrono::steady_clock::now();\n    const auto tEnd   = tStart + chrono::milliseconds(1950);\n    const auto tGreedy= tStart + chrono::milliseconds(1550);\n\n    Xoroshiro rng( chrono::high_resolution_clock::now()\n                   .time_since_epoch().count() );\n    vector<char> vis(M,0);\n    long long bestScore=-1;\n    string bestPath;\n\n    /* phase 1 : many greedy walks */\n    while(chrono::steady_clock::now() < tGreedy){\n        auto w = greedy_walk(rng, vis);\n        if(w.score > bestScore){ bestScore=w.score; bestPath.swap(w.path); }\n    }\n\n    /* phase 2 : safety-net if necessary */\n    if(bestScore < 5000){\n        auto dead = min(tEnd-chrono::milliseconds(150),\n                        chrono::steady_clock::now()+chrono::milliseconds(300));\n        auto w = bfs_walk(dead);\n        if(w.score > bestScore){ bestScore=w.score; bestPath.swap(w.path); }\n    }\n\n    /* phase 3 : final greedy attempts */\n    while(chrono::steady_clock::now() < tEnd){\n        auto w = greedy_walk(rng, vis);\n        if(w.score > bestScore){ bestScore=w.score; bestPath.swap(w.path); }\n    }\n\n    cout << bestPath << '\\n';\n    return 0;\n}","ahc003":"/*****************************************************************************\n *  AHC003 \u2013 learner with local neighbour diffusion                          *\n *                                                                           *\n *  compile:  g++ -std=c++20 -O2 -pipe -static -s main.cpp                   *\n *****************************************************************************/\n#include <bits/stdc++.h>\nusing namespace std;\n\n/*** -------- fixed grid description ------------------------------------- ***/\nconstexpr int H = 30, W = 30;\nconstexpr int HOR = H * (W - 1);          // #horizontal edges\nconstexpr int VER = (H - 1) * W;          // #vertical   edges\nconstexpr int E   = HOR + VER;            // 1740 edges in total\n\nint  horId[H][W-1];\nint  verId[H-1][W];\n\nstruct Edge { int to, id; };\narray<array<array<Edge,4>, W>, H> adj;\n\nvoid build_graph() {\n    int id = 0;\n    for(int i=0;i<H;i++) for(int j=0;j<W-1;j++) horId[i][j]=id++;\n    for(int i=0;i<H-1;i++) for(int j=0;j<W  ;j++) verId[i][j]=id++;\n    for(auto &row:adj) for(auto &col:row) for(auto &e:col) e.id=-1;\n\n    for(int i=0;i<H;i++) for(int j=0;j<W;j++){\n        if(i)          adj[i][j][0]={ (i-1)*W+j , verId[i-1][j] };\n        if(i+1<H)      adj[i][j][1]={ (i+1)*W+j , verId[i][j]   };\n        if(j)          adj[i][j][2]={  i*W+j-1  , horId[i][j-1] };\n        if(j+1<W)      adj[i][j][3]={  i*W+j+1  , horId[i][j]   };\n    }\n}\n\n/*** -------- model ------------------------------------------------------- ***/\nconstexpr double INIT_W = 5000.0, MIN_W = 100.0, MAX_W = 20000.0;\narray<double,E> w;\narray<int   ,E> cnt;\n\n/*** -------- random helpers --------------------------------------------- ***/\nmt19937 rng((uint64_t)chrono::high_resolution_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> unif01(0.0,1.0);\ninline double rand_pm(double amp){ return (unif01(rng)*2.0-1.0)*amp; }\n\n/*** -------- shortest path ---------------------------------------------- ***/\nstruct Node{ double d; int v; bool operator<(const Node&o)const{return d>o.d;}};\n\nconstexpr double B_EXPLORE = 1200.0;   // optimism during exploration\nconstexpr double B_EXPLOIT0 = 300.0;   // initial optimism during exploitation\nconstexpr double B_EXPLOIT_DECAY = 0.997; // per query decay\nconstexpr double NOISE_A   = 0.80;     // \u00b180 % random shake in exploration\n\nvector<int> dijkstra(int si,int sj,int ti,int tj,bool exploring,int qIdx){\n    array<double,H*W> dist; dist.fill(1e100);\n    array<int   ,H*W> prvV, prvE; prvE.fill(-1);\n    priority_queue<Node> pq;\n    dist[si*W+sj]=0.0; pq.push({0.0,si*W+sj});\n\n    const double B_base = exploring ? B_EXPLORE\n                                    : B_EXPLOIT0*pow(B_EXPLOIT_DECAY,qIdx);\n\n    while(!pq.empty()){\n        auto [d,v]=pq.top(); pq.pop();\n        if(d!=dist[v]) continue;\n        if(v==ti*W+tj) break;\n        int vi=v/W, vj=v%W;\n        for(int k=0;k<4;k++){\n            auto [to,eid]=adj[vi][vj][k];\n            if(eid<0) continue;\n            double ww=w[eid] - B_base/ sqrt(cnt[eid]+1.0);\n            if(exploring) ww *= 1.0 + rand_pm(NOISE_A);\n            ww=max(50.0,ww);\n            double nd=d+ww;\n            if(nd<dist[to]){ dist[to]=nd; prvV[to]=v; prvE[to]=eid; pq.push({nd,to}); }\n        }\n    }\n    vector<int> path;\n    for(int cur=ti*W+tj; cur!=si*W+sj; cur=prvV[cur]) path.push_back(prvE[cur]);\n    reverse(path.begin(),path.end());\n    return path;\n}\n\n/*** -------- build UDLR string ------------------------------------------ ***/\nstring build_path(int si,int sj,const vector<int>& edges){\n    string res; res.reserve(edges.size());\n    int i=si,j=sj;\n    for(int eid:edges){\n        if(eid < HOR){ int r=eid/(W-1), c=eid%(W-1);\n            if(i==r&&j==c){ res+='R'; ++j;} else{ res+='L'; --j; }\n        }else{ int id2=eid-HOR, r=id2/W, c=id2%W;\n            if(i==r&&j==c){ res+='D'; ++i;} else{ res+='U'; --i; }\n        }\n    }\n    return res;\n}\n\n/*** -------- learning ---------------------------------------------------- ***/\nconstexpr int    MUL_PHASE = 200;\nconstexpr double ETA_MUL = 0.6, ETA_ADD = 1.0;\n\nvoid learn_mul(const vector<int>& edges,double ratio){\n    for(int e:edges){\n        double eta=ETA_MUL/sqrt(cnt[e]+1.0);\n        w[e]*=pow(ratio,eta);\n        w[e]=clamp(w[e],MIN_W,MAX_W);\n        ++cnt[e];\n    }\n}\nvoid learn_add(const vector<int>& edges,double diff,double pred){\n    for(int e:edges){\n        double eta=ETA_ADD/sqrt(cnt[e]+1.0);\n        w[e]+=eta*diff*(w[e]/pred);\n        w[e]=clamp(w[e],MIN_W,MAX_W);\n        ++cnt[e];\n    }\n}\n\n/*** -------- local neighbour diffusion ---------------------------------- ***/\nconstexpr int    DIFF_LIMIT = 6;        // apply while edge seen \u2264 6 times\nconstexpr double DIFF_ALPHA = 0.20;     // 20 % towards neighbour mean\n\nvoid neighbour_diffusion(){\n    /* horizontal -------------------------------------------------------- */\n    for(int i=0;i<H;i++){\n        for(int j=0;j<W-1;j++){\n            int id = horId[i][j];\n            if(cnt[id]>DIFF_LIMIT) continue;\n            double s=0; int c=0;\n            if(j && cnt[horId[i][j-1]]){ s+=w[horId[i][j-1]]; ++c; }\n            if(j+1<W-1 && cnt[horId[i][j+1]]){ s+=w[horId[i][j+1]]; ++c; }\n            if(c){\n                double avg=s/c;\n                w[id]=w[id]*(1.0-DIFF_ALPHA)+avg*DIFF_ALPHA;\n            }\n        }\n    }\n    /* vertical ---------------------------------------------------------- */\n    for(int j=0;j<W;j++){\n        for(int i=0;i<H-1;i++){\n            int id = verId[i][j];\n            if(cnt[id]>DIFF_LIMIT) continue;\n            double s=0; int c=0;\n            if(i && cnt[verId[i-1][j]]){ s+=w[verId[i-1][j]]; ++c; }\n            if(i+1<H-1 && cnt[verId[i+1][j]]){ s+=w[verId[i+1][j]]; ++c; }\n            if(c){\n                double avg=s/c;\n                w[id]=w[id]*(1.0-DIFF_ALPHA)+avg*DIFF_ALPHA;\n            }\n        }\n    }\n}\n\n/*** -------- main loop --------------------------------------------------- ***/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    build_graph();\n    w.fill(INIT_W); cnt.fill(0);\n\n    const int    FORCED_EXP = 100;\n    const double P_EXP0 = 0.35, EXP_DEC = 0.995;\n\n    for(int q=0;q<1000;q++){\n        int si,sj,ti,tj; if(!(cin>>si>>sj>>ti>>tj)) return 0;\n\n        bool exploring = (q < FORCED_EXP) ||\n                         (unif01(rng) < P_EXP0*pow(EXP_DEC, q-FORCED_EXP));\n\n        auto edges = dijkstra(si,sj,ti,tj,exploring,q);\n        cout << build_path(si,sj,edges) << '\\n' << flush;\n\n        long long measLL; cin>>measLL; double measured=double(measLL);\n\n        double pred=0; for(int e:edges) pred+=w[e];\n        if(pred<=0) pred=1;\n        double ratio=measured/pred, diff=measured-pred;\n\n        (q < MUL_PHASE) ? learn_mul(edges,ratio)\n                        : learn_add(edges,diff,pred);\n\n        neighbour_diffusion();               // <\u2014 new local smoothing\n    }\n    return 0;\n}","ahc004":"//  g++ -std=c++20 -O2 -pipe -static -s\n#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N  = 20;     // matrix size (fixed)\nconstexpr int CH = 8;      // A..H\nconstexpr int MAXLEN = 12; // max length of s_i\n\nstruct Placement {\n    uint8_t len;                  // length of the string\n    uint16_t cell[MAXLEN];        // linear cell id (0..399)\n    uint8_t  letter[MAXLEN];      // 0..7\n};\nstruct Watch {\n    int sid;          // string id\n    int pid;          // placement id within that string\n    uint8_t letter;   // letter required in this cell by that placement\n};\n\nint c2i(char c){ return c-'A'; }\nchar i2c(int x){ return 'A'+x; }\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int M;  /* N is fixed 20 */\n    cin >> std::ws;\n    cin.ignore(numeric_limits<streamsize>::max(),' '); // throw away N\n    cin >> M;\n    vector<string> S(M);\n    for(auto& s:S) cin >> s;\n\n    /*------------------------------------------------------------------*\n     * 1. enumerate every placement                                     *\n     *------------------------------------------------------------------*/\n    vector<vector<Placement>> plac(M);\n    vector<vector<char>> active(M);        // 1 = still alive\n    vector<vector<Watch>> watchers(N*N);   // placements touching each cell\n\n    for(int sid=0; sid<M; ++sid){\n        const string& s = S[sid];\n        const int L = (int)s.size();\n        plac[sid].reserve(800);\n        /* horizontal */\n        for(int row=0; row<N; ++row)\n            for(int st=0; st<N; ++st){\n                Placement p; p.len=L;\n                for(int k=0;k<L;++k){\n                    int col=(st+k)%N;\n                    int cell=row*N+col;\n                    p.cell[k]=cell;\n                    p.letter[k]=c2i(s[k]);\n                }\n                int pid=plac[sid].size();\n                plac[sid].push_back(p);\n                for(int k=0;k<L;++k)\n                    watchers[p.cell[k]].push_back({sid,pid,p.letter[k]});\n            }\n        /* vertical */\n        for(int col=0; col<N; ++col)\n            for(int st=0; st<N; ++st){\n                Placement p; p.len=L;\n                for(int k=0;k<L;++k){\n                    int row=(st+k)%N;\n                    int cell=row*N+col;\n                    p.cell[k]=cell;\n                    p.letter[k]=c2i(s[k]);\n                }\n                int pid=plac[sid].size();\n                plac[sid].push_back(p);\n                for(int k=0;k<L;++k)\n                    watchers[p.cell[k]].push_back({sid,pid,p.letter[k]});\n            }\n        active[sid].assign(plac[sid].size(),1);\n    }\n\n    /*------------------------------------------------------------------*\n     * 2. propagation of forced letters                                 *\n     *------------------------------------------------------------------*/\n    vector<int8_t> fixed(N*N,-1); // -1 = unknown, else 0..7\n    bool changed=true;\n    while(changed){\n        changed=false;\n        /* remove placements inconsistent with already fixed letters */\n        for(int sid=0; sid<M; ++sid){\n            auto &v = plac[sid];\n            auto &alive = active[sid];\n            for(int pid=0,sz=v.size(); pid<sz; ++pid){\n                if(!alive[pid]) continue;\n                const Placement& p=v[pid];\n                bool ok=true;\n                for(int k=0;k<p.len && ok;++k){\n                    int c = p.cell[k];\n                    if(fixed[c]!=-1 && fixed[c]!=p.letter[k]) ok=false;\n                }\n                if(!ok){ alive[pid]=0; changed=true; }\n            }\n        }\n        /* fix cells that now have only one possible letter */\n        for(int cell=0; cell<N*N; ++cell){\n            if(fixed[cell]!=-1) continue;\n            uint8_t mask=0;\n            for(const auto& w: watchers[cell])\n                if(active[w.sid][w.pid]) mask |= (1u<<w.letter);\n            if(mask && (mask & (mask-1))==0){           // power of two\n                fixed[cell]=__builtin_ctz(mask);\n                changed=true;\n            }\n        }\n    }\n\n    /*------------------------------------------------------------------*\n     * 3. greedy assignment (strings with fewer choices first)          *\n     *------------------------------------------------------------------*/\n    mt19937 rng(712367); // deterministic, change for randomisation\n    vector<int> aliveCnt(M);\n    for(int i=0;i<M;++i){\n        aliveCnt[i]=accumulate(begin(active[i]),end(active[i]),0);\n    }\n    vector<int> order(M); iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),\n         [&](int a,int b){ return aliveCnt[a]<aliveCnt[b]; });\n\n    for(int sid:order){\n        int bestPid=-1, bestNew=99;\n        for(int pid=0,sz=plac[sid].size(); pid<sz; ++pid){\n            if(!active[sid][pid]) continue;\n            const auto& p = plac[sid][pid];\n            bool ok=true; int newCnt=0;\n            for(int k=0;k<p.len && ok;++k){\n                int c = p.cell[k];\n                if(fixed[c]!=-1 && fixed[c]!=p.letter[k]) ok=false;\n                else if(fixed[c]==-1) ++newCnt;\n            }\n            if(!ok) continue;\n            if(newCnt<bestNew || (newCnt==bestNew && rng()%2)){\n                bestNew=newCnt; bestPid=pid;\n            }\n        }\n        if(bestPid==-1) continue;                 // cannot place this string\n        const auto& p=plac[sid][bestPid];\n        /* fix the cells decided by this placement */\n        for(int k=0;k<p.len;++k){\n            int c=p.cell[k];\n            if(fixed[c]==p.letter[k]) continue;\n            fixed[c]=p.letter[k];\n            /* eliminate incompatible placements touching this cell */\n            for(const auto& w: watchers[c]){\n                if(!active[w.sid][w.pid]) continue;\n                if(w.letter!=fixed[c]){\n                    active[w.sid][w.pid]=0;\n                    --aliveCnt[w.sid];\n                }\n            }\n        }\n    }\n\n    /*------------------------------------------------------------------*\n     * 4. fill remaining unknown cells arbitrarily                      *\n     *------------------------------------------------------------------*/\n    uniform_int_distribution<int> d8(0,7);\n    for(int c=0;c<N*N;++c)\n        if(fixed[c]==-1) fixed[c]=d8(rng);\n\n    /*------------------------------------------------------------------*\n     * 5. output                                                        *\n     *------------------------------------------------------------------*/\n    for(int r=0;r<N;++r){\n        for(int c=0;c<N;++c) cout << i2c(fixed[r*N+c]);\n        cout << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\nconst int INF = 1e9;\n\n/*\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 timer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/\nusing Clock = std::chrono::steady_clock;\nClock::time_point g_start;\ninline long long millis(){return chrono::duration_cast<chrono::milliseconds>(Clock::now()-g_start).count();}\ninline bool time_over(){return millis()>=2400;}          // 2.4 s for local search\n\n/*\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 grid helpers \u2500\u2500\u2500\u2500\u2500*/\nconst int di[4]={-1,1,0,0};\nconst int dj[4]={0,0,-1,1};\nconst char dch[4]={'U','D','L','R'};\ninline bool inside(int x,int n){return 0<=x&&x<n;}\n\n/*\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 grid with runs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/\nstruct Grid{\n    int N,NN;                      /* N \u2264 69, NN \u2264 4761                     */\n    vector<char> road,digit;       /* digit = movement cost 5\u20269             */\n    vector<int> rowRunOf,colRunOf;\n    vector<vector<int>> rowRuns,colRuns;\n    Grid(int N_,const vector<string>& S):N(N_),NN(N_*N_){\n        road.assign(NN,0); digit.assign(NN,0);\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)\n            if(S[i][j]!='#'){road[id(i,j)]=1; digit[id(i,j)]=S[i][j]-'0';}\n        buildRuns();\n    }\n    int id(int i,int j) const {return i*N+j;}\n    int row(int v)const{return v/N;}\n    int col(int v)const{return v%N;}\n    void buildRuns(){\n        rowRunOf.assign(NN,-1); colRunOf.assign(NN,-1);\n        for(int i=0;i<N;i++){\n            for(int j=0;j<N;){\n                if(!road[id(i,j)]){++j;continue;}\n                vector<int> cells;\n                while(j<N&&road[id(i,j)]){cells.push_back(id(i,j));++j;}\n                int r=rowRuns.size();\n                for(int v:cells)rowRunOf[v]=r;\n                rowRuns.push_back(move(cells));\n            }\n        }\n        for(int j=0;j<N;j++){\n            for(int i=0;i<N;){\n                if(!road[id(i,j)]){++i;continue;}\n                vector<int> cells;\n                while(i<N&&road[id(i,j)]){cells.push_back(id(i,j));++i;}\n                int c=colRuns.size();\n                for(int v:cells)colRunOf[v]=c;\n                colRuns.push_back(move(cells));\n            }\n        }\n    }\n};\n\n/*\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Hungarian (rectangular) \u2500\u2500\u2500\u2500\u2500\u2500\u2500*/\nvector<int> hungarian(const vector<vector<int>>& a){\n    int n=a.size(),m=a[0].size(),BIG=1e8;\n    vector<int> u(n+1),v(m+1),p(m+1),way(m+1);\n    for(int i=1;i<=n;i++){\n        p[0]=i;int j0=0;\n        vector<int>minv(m+1,BIG);vector<char>used(m+1,false);\n        do{\n            used[j0]=true;\n            int i0=p[j0],delta=BIG,j1=0;\n            for(int j=1;j<=m;j++)if(!used[j]){\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<=m;j++)\n                if(used[j]){u[p[j]]+=delta;v[j]-=delta;}\n                else        minv[j]-=delta;\n            j0=j1;\n        }while(p[j0]!=0);\n        do{\n            int j1=way[j0];p[j0]=p[j1];j0=j1;\n        }while(j0);\n    }\n    vector<int>match(n,-1);\n    for(int j=1;j<=m;j++)if(p[j])match[p[j]-1]=j-1;\n    return match;\n}\n\n/*\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 covering set for a weight W \u2500\u2500\u2500*/\nvector<int> build_cover(const Grid& G,int si,int sj,int W){\n    auto metric=[&](int v){return W*G.digit[v]+abs(G.row(v)-si)+abs(G.col(v)-sj);};\n    int start=G.id(si,sj);\n    int H=G.rowRuns.size(),V=G.colRuns.size();\n    vector<char> hCov(H,0),vCov(V,0);\n    hCov[G.rowRunOf[start]]=1; vCov[G.colRunOf[start]]=1;\n\n    vector<int> rows,cols;\n    for(int r=0;r<H;r++)if(!hCov[r])rows.push_back(r);\n    for(int c=0;c<V;c++)if(!vCov[c])cols.push_back(c);\n\n    vector<int> sel;\n    const int BIG=1e8;\n    if(rows.size()<=cols.size()){\n        int n=rows.size(),m=cols.size();\n        vector<vector<int>>C(n,vector<int>(m,BIG)),pick(n,vector<int>(m,-1));\n        for(int i=0;i<n;i++)for(int v:G.rowRuns[rows[i]]){\n            int c=G.colRunOf[v];\n            int j=lower_bound(cols.begin(),cols.end(),c)-cols.begin();\n            if(j<m&&cols[j]==c){\n                int w=metric(v);if(w<C[i][j]){C[i][j]=w;pick[i][j]=v;}\n            }\n        }\n        auto match=hungarian(C);\n        for(int i=0;i<n;i++){\n            int v=pick[i][match[i]];\n            if(v==-1){v=G.rowRuns[rows[i]][0];\n                      for(int x:G.rowRuns[rows[i]])if(metric(x)<metric(v))v=x;}\n            sel.push_back(v);hCov[rows[i]]=1;vCov[cols[match[i]]]=1;\n        }\n    }else{\n        int n=cols.size(),m=rows.size();\n        vector<vector<int>>C(n,vector<int>(m,BIG)),pick(n,vector<int>(m,-1));\n        for(int j=0;j<m;j++)for(int v:G.rowRuns[rows[j]]){\n            int c=G.colRunOf[v];\n            int i=lower_bound(cols.begin(),cols.end(),c)-cols.begin();\n            if(i<n&&cols[i]==c){\n                int w=metric(v);if(w<C[i][j]){C[i][j]=w;pick[i][j]=v;}\n            }\n        }\n        auto match=hungarian(C);\n        for(int i=0;i<n;i++){\n            int v=pick[i][match[i]];\n            if(v==-1){v=G.colRuns[cols[i]][0];\n                      for(int x:G.colRuns[cols[i]])if(metric(x)<metric(v))v=x;}\n            sel.push_back(v);vCov[cols[i]]=1;hCov[rows[match[i]]]=1;\n        }\n    }\n    for(int r=0;r<H;r++)if(!hCov[r]){\n        int v=G.rowRuns[r][0];\n        for(int x:G.rowRuns[r])if(metric(x)<metric(v))v=x;\n        sel.push_back(v);\n    }\n    for(int c=0;c<V;c++)if(!vCov[c]){\n        int v=G.colRuns[c][0];\n        for(int x:G.colRuns[c])if(metric(x)<metric(v))v=x;\n        sel.push_back(v);\n    }\n    return sel;\n}\n\n/*\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 adjacency table \u2500\u2500\u2500\u2500\u2500*/\nvector<array<int,4>> build_nb(const Grid& G){\n    vector<array<int,4>> nb(G.NN);\n    for(int i=0;i<G.N;i++)for(int j=0;j<G.N;j++){\n        int idx=G.id(i,j);\n        for(int k=0;k<4;k++){\n            int ni=i+di[k],nj=j+dj[k];\n            nb[idx][k]=inside(ni,G.N)&&inside(nj,G.N)&&G.road[G.id(ni,nj)]\n                        ?G.id(ni,nj):-1;\n        }\n    }\n    return nb;\n}\n\n/*\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 distances matrix \u2500\u2500\u2500\u2500\u2500*/\nvector<vector<int>> build_dist(const Grid& G,const vector<int>& nodes,\n                               const vector<array<int,4>>& nb){\n    int K=nodes.size();vector<vector<int>>D(K,vector<int>(K,INF));\n    vector<int>d(G.NN);using P=pair<int,int>;priority_queue<P,vector<P>,greater<P>>pq;\n    for(int s=0;s<K;s++){\n        fill(d.begin(),d.end(),INF);d[nodes[s]]=0;pq.emplace(0,nodes[s]);\n        while(!pq.empty()){\n            auto [dv,v]=pq.top();pq.pop();if(dv!=d[v])continue;\n            for(int k=0;k<4;k++){\n                int to=nb[v][k];if(to==-1)continue;\n                int nd=dv+G.digit[to];if(nd<d[to]){d[to]=nd;pq.emplace(nd,to);}\n            }\n        }\n        for(int t=0;t<K;t++)D[s][t]=d[nodes[t]];\n    }\n    return D;\n}\n\n/*\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Christofides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/\nvector<int> christofides(const vector<vector<int>>& D){\n    int K=D.size();\n    vector<int>par(K,-1),key(K,INF),in(K,0);key[0]=0;\n    for(int it=0;it<K;it++){\n        int v=-1;for(int i=0;i<K;i++)if(!in[i]&&(v==-1||key[i]<key[v]))v=i;\n        in[v]=1;for(int u=0;u<K;u++)if(!in[u]&&D[v][u]<key[u]){key[u]=D[v][u];par[u]=v;}\n    }\n    vector<vector<int>>adj(K);vector<int>deg(K,0);\n    for(int i=1;i<K;i++){adj[i].push_back(par[i]);adj[par[i]].push_back(i);deg[i]++;deg[par[i]]++;}\n    vector<int>odd;for(int i=0;i<K;i++)if(deg[i]&1)odd.push_back(i);\n    vector<char>matched(K,0);vector<tuple<int,int,int>>e;\n    for(int i=0;i<(int)odd.size();i++)for(int j=i+1;j<(int)odd.size();j++)\n        e.emplace_back(D[odd[i]][odd[j]],odd[i],odd[j]);\n    sort(e.begin(),e.end());\n    for(auto [w,a,b]:e)if(!matched[a]&&!matched[b]){matched[a]=matched[b]=1;adj[a].push_back(b);adj[b].push_back(a);}\n    vector<int>it(K,0),st={0},eul;\n    while(!st.empty()){\n        int v=st.back();\n        while(it[v]<(int)adj[v].size()&&adj[v][it[v]]==-1)++it[v];\n        if(it[v]==(int)adj[v].size()){eul.push_back(v);st.pop_back();}\n        else{\n            int u=adj[v][it[v]];adj[v][it[v]]=-1;for(int&x:adj[u])if(x==v){x=-1;break;}st.push_back(u);\n        }\n    }\n    vector<char>seen(K,0);vector<int>tour;\n    for(int v:eul)if(!seen[v]){tour.push_back(v);seen[v]=1;}\n    tour.push_back(0);return tour;\n}\ninline long long tlen(const vector<int>&t,const vector<vector<int>>&D){\n    long long s=0;for(size_t i=0;i+1<t.size();i++)s+=D[t[i]][t[i+1]];return s;\n}\n\n/*\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 local-search moves \u2500\u2500\u2500\u2500\u2500*/\nbool two_opt(vector<int>&o,const vector<vector<int>>&D){\n    int L=o.size();bool ch=false,imp=true;\n    while(imp&&!time_over()){\n        imp=false;\n        for(int i=1;i<L-3;i++)for(int j=i+2;j<L-1;j++){\n            int a=o[i-1],b=o[i],c=o[j],d=o[j+1];\n            if(D[a][b]+D[c][d]>D[a][c]+D[b][d]){\n                reverse(o.begin()+i,o.begin()+j+1);imp=ch=true;if(time_over())return ch;\n            }\n        }\n    }\n    return ch;\n}\nbool or_opt_k(vector<int>&o,const vector<vector<int>>&D,int k){\n    int L=o.size();bool ch=false,imp=true;\n    while(imp&&!time_over()){\n        imp=false;\n        for(int i=1;i<L-1-k;i++){\n            int pre=o[i-1],post=o[i+k],segS=o[i],segE=o[i+k-1];\n            int loss=D[pre][segS]+D[segE][post]-D[pre][post];\n            for(int j=1;j<L-1;j++){\n                if(j>=i&&j<=i+k-1)continue;\n                int u=o[j],v=o[j+1];\n                int gain=D[u][segS]+D[segE][v]-D[u][v];\n                if(loss>gain){\n                    vector<int>seg(o.begin()+i,o.begin()+i+k);\n                    o.erase(o.begin()+i,o.begin()+i+k);\n                    if(j<i)o.insert(o.begin()+j+1,seg.begin(),seg.end());\n                    else   o.insert(o.begin()+j-k+1,seg.begin(),seg.end());\n                    imp=ch=true;if(time_over())return ch;goto AGAIN;\n                }\n            }\n        }\nAGAIN:;\n    }\n    return ch;\n}\n/* single-vertex relocation */\nbool or_opt1(vector<int>&o,const vector<vector<int>>&D){\n    int L=o.size();bool ch=false,imp=true;\n    while(imp&&!time_over()){\n        imp=false;\n        for(int i=1;i<L-1;i++){\n            int node=o[i],pre=o[i-1],nxt=o[i+1];\n            int loss=D[pre][node]+D[node][nxt]-D[pre][nxt];\n            for(int j=1;j<L-1;j++){\n                if(j==i||j==i-1)continue;\n                int u=o[j],v=o[j+1];\n                int gain=D[u][node]+D[node][v]-D[u][v];\n                if(loss>gain){\n                    o.erase(o.begin()+i);\n                    if(j<i)o.insert(o.begin()+j+1,node);\n                    else   o.insert(o.begin()+j,node);\n                    imp=ch=true;if(time_over())return ch;goto AGAIN1;\n                }\n            }\n        }\nAGAIN1:;\n    }\n    return ch;\n}\nbool swap_nodes(vector<int>&o,const vector<vector<int>>&D){\n    int L=o.size();bool ch=false,imp=true;\n    while(imp&&!time_over()){\n        imp=false;\n        for(int i=1;i<L-2;i++)for(int j=i+2;j<L-1;j++){\n            int aP=o[i-1],a=o[i],aN=o[i+1];\n            int bP=o[j-1],b=o[j],bN=o[j+1];\n            int before=D[aP][a]+D[a][aN]+D[bP][b]+D[b][bN];\n            int after =D[aP][b]+D[b][aN]+D[bP][a]+D[a][bN];\n            if(before>after){\n                swap(o[i],o[j]);imp=ch=true;if(time_over())return ch;goto AGAIN2;\n            }\n        }\nAGAIN2:;\n    }\n    return ch;\n}\nvoid local_search(vector<int>&o,const vector<vector<int>>&D){\n    int K=o.size()-1;\n    bool allow_big=K<=120;\n    bool changed=true;\n    while(changed&&!time_over()){\n        changed=false;\n        changed|=or_opt1(o,D);\n        changed|=two_opt(o,D);\n        if(allow_big){\n            changed|=or_opt_k(o,D,2);\n            changed|=or_opt_k(o,D,3);\n            changed|=swap_nodes(o,D);\n        }\n    }\n}\n\n/*\u2500\u2500\u2500\u2500 Dijkstra for final path string \u2500\u2500\u2500*/\nstring path_between(const Grid& G,int s,int t,const vector<array<int,4>>&nb){\n    vector<int>d(G.NN,INF),par(G.NN,-1);vector<char>pd(G.NN);\n    using P=pair<int,int>;priority_queue<P,vector<P>,greater<P>>pq;\n    d[s]=0;pq.emplace(0,s);\n    while(!pq.empty()){\n        auto [dv,v]=pq.top();pq.pop();if(v==t)break;if(dv!=d[v])continue;\n        for(int k=0;k<4;k++){\n            int to=nb[v][k];if(to==-1)continue;\n            int nd=dv+G.digit[to];if(nd<d[to]){d[to]=nd;par[to]=v;pd[to]=dch[k];pq.emplace(nd,to);}\n        }\n    }\n    string res;for(int cur=t;cur!=s;cur=par[cur])res.push_back(pd[cur]);\n    reverse(res.begin(),res.end());return res;\n}\n\n/*\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 main \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500*/\nstruct Candidate{\n    vector<int>nodes;\n    vector<vector<int>>dist;\n    vector<int>tour; long long len=LLONG_MAX;\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    g_start=Clock::now();\n\n    int N,si,sj; if(!(cin>>N>>si>>sj)) return 0;\n    vector<string>S(N);for(int i=0;i<N;i++)cin>>S[i];\n\n    Grid G(N,S);\n    auto nb=build_nb(G);\n\n    const int WEIGHTS[5]={2,5,10,20,40};\n    const int MAX_EVAL=3;\n    Candidate best,second; int cnt=0;\n    for(int w:WEIGHTS){\n        if(cnt>=MAX_EVAL||millis()>1200)break;\n        vector<int>cover=build_cover(G,si,sj,w);\n        Candidate c; c.nodes.push_back(G.id(si,sj));\n        c.nodes.insert(c.nodes.end(),cover.begin(),cover.end());\n        c.dist=build_dist(G,c.nodes,nb);\n        c.tour=christofides(c.dist);\n        c.len =tlen(c.tour,c.dist);\n\n        if(c.len<best.len){second=move(best);best=move(c);}\n        else if(c.len<second.len){second=move(c);}\n        ++cnt;\n    }\n    local_search(best.tour,best.dist);best.len=tlen(best.tour,best.dist);\n\n    if(!time_over()&&second.len<LLONG_MAX){\n        local_search(second.tour,second.dist);\n        second.len=tlen(second.tour,second.dist);\n        if(second.len<best.len)best=move(second);\n    }\n\n    string ans;\n    for(size_t i=0;i+1<best.tour.size();i++){\n        int a=best.nodes[best.tour[i]],b=best.nodes[best.tour[i+1]];\n        ans+=path_between(G,a,b,nb);\n    }\n    cout<<ans<<\"\\n\";\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*---------------- Hungarian (square) ----------------*/\nconst long long INF64 = (1LL << 60);\n\nvector<int> hungarian(const vector<vector<long long>>& a) {\n    int n = (int)a.size() - 1;                // 1-based\n    vector<long long> u(n + 1), v(n + 1), minv(n + 1);\n    vector<int> p(n + 1), way(n + 1);\n    for (int i = 1; i <= n; ++i) {\n        p[0] = i; int j0 = 0;\n        fill(minv.begin(), minv.end(), INF64);\n        vector<char> used(n + 1, 0);\n        do {\n            used[j0] = 1;\n            int i0 = p[j0], j1 = 0; long long delta = INF64;\n            for (int j = 1; j <= n; ++j) if (!used[j]) {\n                long long cur = a[i0][j] - 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            j0 = j1;\n        } while (p[j0]);\n        do { int j1 = way[j0]; p[j0] = p[j1]; j0 = j1; } while (j0);\n    }\n    vector<int> ans(n + 1);\n    for (int j = 1; j <= n; ++j) ans[p[j]] = j;\n    return ans;                                  // row i \u2192 column ans[i]\n}\n\n/*---------------- Worker ----------------*/\nstruct Worker {\n    vector<int> low;     // proven lower bound\n    int task  = -1;\n    int start = -1;\n    int gap   = 3;\n};\n\n/*==========================================================================*/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /*---- read instance ----*/\n    int N, M, K, R;\n    if (!(cin >> N >> M >> K >> R)) return 0;\n    vector<vector<int>> need(N, vector<int>(K));\n    for (auto &v : need) for (int &x : v) cin >> x;\n\n    vector<vector<int>> out(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        out[u].push_back(v); ++indeg[v];\n    }\n\n    /*---- static priority = out-degree + longest path ----*/\n    vector<int> topo; topo.reserve(N);\n    {\n        queue<int> q; auto d = indeg;\n        for (int i = 0; i < N; ++i) if (!d[i]) q.push(i);\n        while (!q.empty()) {\n            int u = q.front(); q.pop(); topo.push_back(u);\n            for (int v : out[u]) if (!--d[v]) q.push(v);\n        }\n    }\n    vector<int> lp(N, 0);\n    for (int i = N - 1; i >= 0; --i)\n        for (int v : out[topo[i]])\n            lp[topo[i]] = max(lp[topo[i]], lp[v] + 1);\n    vector<int> basePrio(N);\n    for (int i = 0; i < N; ++i)\n        basePrio[i] = (int)out[i].size() + lp[i];\n\n    /*---- dynamic state ----*/\n    vector<char> state(N, 0);      // 0 not-started,1 running,2 done\n    vector<int> readyDay(N, -1);\n    vector<int> ready;\n    for (int i = 0; i < N; ++i)\n        if (!indeg[i]) { ready.push_back(i); readyDay[i] = 1; }\n\n    vector<Worker> W(M, Worker{vector<int>(K, 0)});\n\n    /*---- parameters ----*/\n    const int TOP_PRIO = 70, TOP_FAST = 70, MAX_CAND = 120;\n    const long long BIGC = 6'000'000LL;\n    const int  C_TIME  = 120;\n    const int  C_PRIO  = 16;\n\n    auto predict = [&](const Worker &w, int t) {\n        int lack = w.gap;\n        for (int k = 0; k < K; ++k) {\n            int d = need[t][k] - w.low[k];\n            if (d > 0) lack += d;\n        }\n        return max(1, lack);\n    };\n\n    int day = 1;\n    while (true) {\n        /*----- idle workers -----*/\n        vector<int> idle;\n        for (int j = 0; j < M; ++j) if (W[j].task == -1) idle.push_back(j);\n        int Wcnt = (int)idle.size();\n\n        /*----- generate candidate task list -----*/\n        vector<int> pool;\n        for (int id : ready) if (state[id] == 0) pool.push_back(id);\n\n        vector<int> cand;\n        if ((int)pool.size() <= MAX_CAND) cand = pool;\n        else {\n            struct Info { int id; long long effP; int bestT; };\n            vector<Info> infos; infos.reserve(pool.size());\n            for (int id : pool) {\n                long long effP = basePrio[id] + (day - readyDay[id]);\n                int bt = INT_MAX;\n                for (int wId : idle) bt = min(bt, predict(W[wId], id));\n                infos.push_back({id, effP, bt});\n            }\n            /* top by priority */\n            nth_element(infos.begin(), infos.begin() + TOP_PRIO, infos.end(),\n                        [](const Info &a, const Info &b){ return a.effP > b.effP; });\n            for (int i = 0; i < TOP_PRIO; ++i) cand.push_back(infos[i].id);\n\n            /* top by speed */\n            nth_element(infos.begin(), infos.begin() + TOP_FAST, infos.end(),\n                        [](const Info &a, const Info &b){ return a.bestT < b.bestT; });\n            for (int i = 0; i < TOP_FAST; ++i) cand.push_back(infos[i].id);\n\n            sort(cand.begin(), cand.end());\n            cand.erase(unique(cand.begin(), cand.end()), cand.end());\n\n            if ((int)cand.size() > MAX_CAND) {\n                sort(cand.begin(), cand.end(), [&](int a, int b){\n                    long long pa = basePrio[a] + (day - readyDay[a]);\n                    long long pb = basePrio[b] + (day - readyDay[b]);\n                    return pa > pb;\n                });\n                cand.resize(MAX_CAND);\n            }\n        }\n        int Tcnt = (int)cand.size();\n\n        /*----- cost matrix -----*/\n        int n = max(Wcnt, Tcnt);\n        vector<vector<long long>> cost(n + 1, vector<long long>(n + 1, BIGC));\n        for (int i = 0; i < Wcnt; ++i) {\n            const Worker &wk = W[idle[i]];\n            for (int j = 0; j < Tcnt; ++j) {\n                int t = cand[j];\n                int pt = predict(wk, t);\n                long long effP = basePrio[t] + (day - readyDay[t]);\n                cost[i + 1][j + 1] = C_TIME * (long long)pt - C_PRIO * effP;\n            }\n        }\n\n        /*----- Hungarian assignment -----*/\n        vector<pair<int,int>> today;                          // (worker, task)\n        if (Wcnt && Tcnt) {\n            auto match = hungarian(cost);\n            for (int i = 0; i < Wcnt; ++i) {\n                int j = match[i + 1] - 1;\n                if (j >= 0 && j < Tcnt && cost[i + 1][j + 1] < BIGC / 2) {\n                    int wid = idle[i], tid = cand[j];\n                    today.emplace_back(wid, tid);\n                    W[wid].task = tid; W[wid].start = day;\n                    state[tid] = 1;\n                }\n            }\n        }\n\n        /*----- output -----*/\n        cout << (int)today.size();\n        for (auto [w, t] : today) cout << ' ' << w + 1 << ' ' << t + 1;\n        cout << '\\n' << flush;\n\n        /*----- read end-of-day report -----*/\n        int done; if (!(cin >> done)) return 0;\n        if (done == -1) break;\n\n        for (int z = 0; z < done; ++z) {\n            int id; cin >> id; --id;\n            Worker &wk = W[id];\n            int tid = wk.task;\n            if (tid < 0) continue;\n\n            int realT = day - wk.start + 1;\n            int wLow  = max(0, realT - 3);\n            int wHigh = realT + 3;\n\n            int pred = wk.gap;\n            for (int k = 0; k < K; ++k) {\n                int d = need[tid][k] - wk.low[k];\n                if (d > 0) pred += d;\n            }\n\n            if (pred > wHigh) {                         // over-predicted\n                int excess = pred - wHigh;\n                for (int k = 0; k < K && excess; ++k) {\n                    int lack = need[tid][k] - wk.low[k];\n                    if (lack <= 0) continue;\n                    int inc = min(lack, excess);\n                    wk.low[k] += inc; excess -= inc;\n                }\n                wk.gap = max(0, wk.gap - excess);\n            }\n            else if (pred < wLow) {                     // under-predicted\n                wk.gap += (wLow - pred);               // lower bound only\n            }\n            else wk.gap = (int)(wk.gap * 0.9);\n\n            /* finished */\n            state[tid] = 2; wk.task = -1;\n            for (int v : out[tid])\n                if (--indeg[v] == 0) {\n                    ready.push_back(v);\n                    readyDay[v] = day + 1;\n                }\n        }\n        ++day;\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** geometry **************************************************************/\nstruct Pt{ short x,y; };\ninline int md(const Pt&a,const Pt&b){ return abs(a.x-b.x)+abs(a.y-b.y); }\n\n/*** constants *************************************************************/\nconstexpr int NORD = 1000;\nconstexpr int NEED =   50;\nconstexpr int DEPOT = 0;\nconstexpr double TOTAL_TIME = 1.88;      // internal hard wall (< 2.0 s)\n\n/*** global data ***********************************************************/\nvector<Pt>          node;                // 0 + 2*NORD points\nvector<uint16_t>    distM;               // (2*N+1)^2  (\u226416 MiB)\ninline int dist(int u,int v){ return distM[u*(2*NORD+1)+v]; }\n\nvector<int> idxP(NORD), idxD(NORD), inner(NORD), byInner;\n\n/*** small tools ***********************************************************/\ninline long long routeCost(const vector<int>& r){\n    long long c=0;\n    for(size_t i=0;i+1<r.size();++i) c+=dist(r[i],r[i+1]);\n    return c;\n}\nstruct Ins{ long long d; int eP,eD; };\nIns bestInsert(const vector<int>& route,int ip,int id){\n    const int R=route.size();\n    long long best=LLONG_MAX; int bp=0,bd=0;\n    for(int i=0;i<R-1;++i){\n        long long d1=dist(route[i],ip)+dist(ip,route[i+1])-dist(route[i],route[i+1]);\n        long long delta=d1+dist(ip,id)+dist(id,route[i+1])-dist(ip,route[i+1]);\n        if(delta<best){best=delta;bp=i;bd=i;}\n        for(int j=i+1;j<R-1;++j){\n            long long d2=dist(route[j],id)+dist(id,route[j+1])-dist(route[j],route[j+1]);\n            delta=d1+d2;\n            if(delta<best){best=delta;bp=i;bd=j;}\n        }\n    }\n    return {best,bp,bd};\n}\ninline void applyInsert(vector<int>& r,int ip,int id,int eP,int eD){\n    r.insert(r.begin()+eP+1,ip);\n    if(eD==eP) r.insert(r.begin()+eP+2,id);\n    else       r.insert(r.begin()+eD+2,id);\n}\ninline void erasePair(vector<int>& r,int ip,int id){\n    r.erase(remove(r.begin(),r.end(),ip),r.end());\n    r.erase(remove(r.begin(),r.end(),id),r.end());\n}\ninline void collectUsed(const vector<int>& route,vector<char>& used){\n    fill(used.begin(),used.end(),0);\n    for(int v:route) if(v){ int o=(v-1)>>1; used[o]=1; }\n}\n\n/*** greedy construction ***************************************************/\nvector<int> greedyConstruct(mt19937& rng){\n    vector<char> used(NORD,0);\n    vector<int> route={DEPOT,DEPOT};\n    const int CAND=400, RCL=10;\n\n    for(int st=0;st<NEED;++st){\n        int cnt=0; static int pool[CAND];\n        for(int o:byInner) if(!used[o]){ pool[cnt++]=o; if(cnt==CAND) break; }\n\n        struct Info{ long long d; int o,eP,eD; };\n        array<Info,RCL> best; for(auto&b:best) b.d=LLONG_MAX;\n        for(int k=0;k<cnt;++k){\n            int id=pool[k];\n            auto ins=bestInsert(route,idxP[id],idxD[id]);\n            if(ins.d>=best[RCL-1].d) continue;\n            best[RCL-1]={ins.d,id,ins.eP,ins.eD};\n            for(int i=RCL-1;i>0&&best[i].d<best[i-1].d;--i) swap(best[i],best[i-1]);\n        }\n        int pick=uniform_int_distribution<int>(0,RCL-1)(rng);\n        const auto& ch=best[pick];\n        applyInsert(route,idxP[ch.o],idxD[ch.o],ch.eP,ch.eD);\n        used[ch.o]=1;\n    }\n    return route;\n}\n\n/*** hill climb: relocate (+ optional swap) *******************************/\nvoid hillClimb(vector<int>& route,vector<char>& used,bool withSwap){\n    bool imp=true;\n    while(imp){\n        imp=false;\n        for(int o=0;o<NORD && !imp;++o) if(used[o]){\n            vector<int> tmp=route;\n            erasePair(tmp,idxP[o],idxD[o]);\n            auto ins=bestInsert(tmp,idxP[o],idxD[o]);\n            if(ins.d<0){\n                applyInsert(tmp,idxP[o],idxD[o],ins.eP,ins.eD);\n                route.swap(tmp); imp=true;\n            }\n        }\n        if(withSwap){\n            for(int a=0;a<NORD && !imp;++a) if(used[a])\n            for(int b=a+1;b<NORD && !imp;++b) if(used[b]){\n                vector<int> tmp=route;\n                erasePair(tmp,idxP[a],idxD[a]);\n                erasePair(tmp,idxP[b],idxD[b]);\n                auto ia=bestInsert(tmp,idxP[a],idxD[a]); applyInsert(tmp,idxP[a],idxD[a],ia.eP,ia.eD);\n                auto ib=bestInsert(tmp,idxP[b],idxD[b]); applyInsert(tmp,idxP[b],idxD[b],ib.eP,ib.eD);\n                if(routeCost(tmp)<routeCost(route)){ route.swap(tmp); imp=true; }\n            }\n        }\n    }\n}\n\n/*** final deterministic single-exchange pass *****************************/\nvoid singleExchangeImprove(vector<int>& route,\n                           vector<char>& used,\n                           const vector<int>& candList,\n                           double timeLimit,\n                           const function<double()>& now)\n{\n    long long curC = routeCost(route);\n    while(now() < timeLimit){\n        long long bestNew = curC;\n        vector<int> bestR;\n        for(int oOut=0;oOut<NORD;++oOut) if(used[oOut]){\n            vector<int> rTmp = route;\n            erasePair(rTmp,idxP[oOut],idxD[oOut]);\n            long long costRemoved = routeCost(rTmp);\n\n            for(int oIn:candList) if(!used[oIn]){\n                auto ins = bestInsert(rTmp,idxP[oIn],idxD[oIn]);\n                long long newC = costRemoved + ins.d;\n                if(newC < bestNew){\n                    bestNew = newC;\n                    bestR   = rTmp;\n                    applyInsert(bestR,idxP[oIn],idxD[oIn],ins.eP,ins.eD);\n                }\n            }\n        }\n        if(bestNew < curC){\n            route.swap(bestR);\n            collectUsed(route,used);\n            curC = bestNew;\n        }else break;\n    }\n}\n\n/*** main ******************************************************************/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- input ------------------------------------------------- */\n    vector<array<int,4>> raw(NORD);\n    for(auto &v:raw) cin>>v[0]>>v[1]>>v[2]>>v[3];\n\n    /* ---------- nodes & distance matrix ------------------------------ */\n    node.reserve(1+2*NORD); node.push_back({400,400});\n    for(int i=0;i<NORD;++i){\n        node.push_back({(short)raw[i][0],(short)raw[i][1]});\n        node.push_back({(short)raw[i][2],(short)raw[i][3]});\n    }\n    int NN=node.size();\n    distM.resize((size_t)NN*NN);\n    for(int i=0;i<NN;++i) for(int j=0;j<NN;++j)\n        distM[i*NN+j]=(uint16_t)md(node[i],node[j]);\n\n    for(int i=0;i<NORD;++i){\n        idxP[i]=1+2*i; idxD[i]=idxP[i]+1;\n        inner[i]=dist(idxP[i],idxD[i]);\n    }\n    byInner.resize(NORD); iota(byInner.begin(),byInner.end(),0);\n    sort(byInner.begin(),byInner.end(),[&](int a,int b){return inner[a]<inner[b];});\n\n    /* ---------- timers & RNG ----------------------------------------- */\n    const auto t0=chrono::high_resolution_clock::now();\n    auto seconds=[&](){return chrono::duration<double>(chrono::high_resolution_clock::now()-t0).count();};\n    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());\n    uniform_real_distribution<> U01(0,1);\n\n    /* ---------- 0) multi-start greedy (0.30 s) ----------------------- */\n    vector<int> bestR; long long bestC=LLONG_MAX; vector<char> used(NORD);\n    while(seconds()<0.30){\n        auto r=greedyConstruct(rng);\n        collectUsed(r,used);\n        hillClimb(r,used,false);                    // relocate only\n        long long c=routeCost(r);\n        if(c<bestC){bestC=c; bestR.swap(r);}\n    }\n    collectUsed(bestR,used);\n\n    /* ---------- 1) Simulated Annealing (until 1.55 s) ---------------- */\n    auto curR=bestR; auto curU=used; long long curC=bestC;\n    const double SA_END = 1.55;                     // leave >0.3 s\n    const double T0=800.0, Tend=0.2;\n\n    vector<int> best768(byInner.begin(),byInner.begin()+768);\n\n    while(seconds()<SA_END){\n        double prog=seconds()/SA_END;\n        double Temp = T0*pow(Tend/T0,prog);\n\n        double r=U01(rng);\n        enum Move{REL,EXC,SWP,RUI};\n        Move mv=(r<0.55)?REL:(r<0.75)?EXC:(r<0.90)?SWP:RUI;\n\n        vector<int> nxtR=curR; auto nxtU=curU;\n\n        if(mv==REL){\n            vector<int> in; for(int o=0;o<NORD;++o) if(curU[o]) in.push_back(o);\n            int o=in[uniform_int_distribution<int>(0,(int)in.size()-1)(rng)];\n            erasePair(nxtR,idxP[o],idxD[o]);\n            auto ins=bestInsert(nxtR,idxP[o],idxD[o]);\n            applyInsert(nxtR,idxP[o],idxD[o],ins.eP,ins.eD);\n\n        }else if(mv==EXC){\n            vector<int> in; for(int o=0;o<NORD;++o) if(curU[o]) in.push_back(o);\n            int outOrd=in[uniform_int_distribution<int>(0,(int)in.size()-1)(rng)];\n            erasePair(nxtR,idxP[outOrd],idxD[outOrd]); nxtU[outOrd]=0;\n\n            long long bestD=LLONG_MAX; int inOrd=-1,eP=0,eD=0;\n            for(int cand:best768) if(!nxtU[cand]){\n                auto ins=bestInsert(nxtR,idxP[cand],idxD[cand]);\n                if(ins.d<bestD){bestD=ins.d;inOrd=cand;eP=ins.eP;eD=ins.eD;}\n            }\n            if(inOrd<0) continue;\n            applyInsert(nxtR,idxP[inOrd],idxD[inOrd],eP,eD); nxtU[inOrd]=1;\n\n        }else if(mv==SWP){\n            vector<int> in; for(int o=0;o<NORD;++o) if(curU[o]) in.push_back(o);\n            if(in.size()<2) continue;\n            int A=in[uniform_int_distribution<int>(0,(int)in.size()-1)(rng)];\n            int B; do{B=in[uniform_int_distribution<int>(0,(int)in.size()-1)(rng)];}while(B==A);\n            erasePair(nxtR,idxP[A],idxD[A]); erasePair(nxtR,idxP[B],idxD[B]);\n            auto ia=bestInsert(nxtR,idxP[A],idxD[A]); applyInsert(nxtR,idxP[A],idxD[A],ia.eP,ia.eD);\n            auto ib=bestInsert(nxtR,idxP[B],idxD[B]); applyInsert(nxtR,idxP[B],idxD[B],ib.eP,ib.eD);\n\n        }else{ // RUI (3-4 orders)\n            vector<int> in; for(int o=0;o<NORD;++o) if(curU[o]) in.push_back(o);\n            int k=uniform_int_distribution<int>(3,4)(rng);\n            shuffle(in.begin(),in.end(),rng);\n            vector<int> rem(in.begin(),in.begin()+k);\n            for(int o:rem){ erasePair(nxtR,idxP[o],idxD[o]); nxtU[o]=0; }\n            for(int o:rem){\n                auto ins=bestInsert(nxtR,idxP[o],idxD[o]);\n                applyInsert(nxtR,idxP[o],idxD[o],ins.eP,ins.eD);\n                nxtU[o]=1;\n            }\n        }\n\n        long long nxtC=routeCost(nxtR);\n        long long diff=nxtC-curC;\n        if(diff<0 || exp(-diff/Temp)>U01(rng)){\n            curR.swap(nxtR); curU.swap(nxtU); curC=nxtC;\n            if(curC<bestC){bestC=curC; bestR=curR;}\n        }\n    }\n\n    /* ---------- 2) final clean-up (relocate+swap) -------------------- */\n    collectUsed(bestR,used);\n    hillClimb(bestR,used,true);\n\n    /* ---------- 3) deterministic single-exchange pass ---------------- */\n    collectUsed(bestR,used);\n    singleExchangeImprove(bestR,used,best768,TOTAL_TIME-0.03,seconds);\n\n    /* ---------- output ----------------------------------------------- */\n    vector<int> orders; vector<char> mark(NORD,0);\n    for(int v:bestR) if(v){\n        int o=(v-1)>>1; if(!mark[o]){ mark[o]=1; orders.push_back(o); }\n    }\n    sort(orders.begin(),orders.end());\n\n    cout<<NEED; for(int o:orders) cout<<' '<<o+1; cout<<\"\\n\";\n    cout<<bestR.size();\n    for(int v:bestR) cout<<' '<<node[v].x<<' '<<node[v].y;\n    cout<<\"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** ---------------- DSU ---------------- ***/\nstruct DSU {\n    vector<int> par, sz;\n    DSU(int n = 0) { init(n); }\n    void init(int n) {\n        par.resize(n);\n        sz.assign(n, 1);\n        iota(par.begin(), par.end(), 0);\n    }\n    int  find(int v){ return par[v]==v ? v : par[v]=find(par[v]); }\n    bool unite(int a,int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(sz[a]<sz[b]) swap(a,b);\n        par[b]=a; sz[a]+=sz[b];\n        return true;\n    }\n};\n\nconstexpr int N = 400;\nconstexpr int M = 1995;\n\n/*** ----- helper: classify edges into 5 generator layers (0..4) ----- ***/\nvector<int> classify_layers(const vector<int>& U,const vector<int>& V,\n                            const vector<int>& d){\n    vector<int> layer(M,4), ord(M); iota(ord.begin(),ord.end(),0);\n    sort(ord.begin(),ord.end(),[&](int a,int b){ return d[a]<d[b]; });\n    vector<char> alive(M,1);\n    for(int L=0;L<5;++L){\n        DSU tmp(N); int used=0;\n        for(int id:ord) if(alive[id] && tmp.unite(U[id],V[id])){\n            layer[id]=L; alive[id]=0;\n            if(++used==N-1) break;\n        }\n    }\n    return layer;\n}\n\n/*** ----- helper: mark edges that belong to a global Euclidean MST ---- ***/\nvector<char> mark_global_mst(const vector<int>& U,const vector<int>& V,\n                             const vector<int>& d){\n    vector<int> ord(M); iota(ord.begin(),ord.end(),0);\n    sort(ord.begin(),ord.end(),[&](int a,int b){ return d[a]<d[b]; });\n    vector<char> inMST(M,0);\n    DSU tmp(N); int used=0;\n    for(int id:ord) if(tmp.unite(U[id],V[id])){\n        inMST[id]=1;\n        if(++used==N-1) break;\n    }\n    return inMST;\n}\n\n/*** ----- look-ahead information for the two incident components ----- ***/\nstruct Info{\n    int cntU=0,cntV=0,cntPair=0;\n    int minDU=INT_MAX,minDV=INT_MAX,minDPair=INT_MAX;\n};\n\nInfo look_ahead(int pos,int ru,int rv,DSU& dsu,\n                const vector<int>& U,const vector<int>& V,\n                const vector<int>& d){\n    Info I;\n    for(int j=pos+1;j<M;++j){\n        int a=dsu.find(U[j]), b=dsu.find(V[j]); if(a==b) continue;\n        int dj=d[j];\n        if(a==ru||b==ru){ ++I.cntU;  I.minDU   =min(I.minDU,dj); }\n        if(a==rv||b==rv){ ++I.cntV;  I.minDV   =min(I.minDV,dj); }\n        if((a==ru&&b==rv)||(a==rv&&b==ru)){\n            ++I.cntPair; I.minDPair=min(I.minDPair,dj);\n        }\n    }\n    return I;\n}\n\n/*** ------------------------------------------------------------------ ***/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* fixed part ---------------------------------------------------- */\n    vector<int> X(N),Y(N); for(int i=0;i<N;++i) cin>>X[i]>>Y[i];\n    vector<int> U(M),V(M); for(int i=0;i<M;++i) cin>>U[i]>>V[i];\n\n    /* Euclidean lower bounds --------------------------------------- */\n    vector<int> d(M);\n    for(int i=0;i<M;++i){\n        long long dx=X[U[i]]-X[V[i]];\n        long long dy=Y[U[i]]-Y[V[i]];\n        d[i]=int(lround(sqrt(double(dx*dx+dy*dy))));\n        if(d[i]==0) d[i]=1;\n    }\n\n    /* pre-computations --------------------------------------------- */\n    vector<int>  layer = classify_layers(U,V,d);\n    vector<char> inMST = mark_global_mst(U,V,d);\n\n    /* on-line phase ------------------------------------------------- */\n    DSU dsu(N); int components=N;\n    for(int i=0;i<M;++i){\n        long long li; cin>>li;\n        int ru=dsu.find(U[i]), rv=dsu.find(V[i]);\n\n        if(ru==rv){ cout<<0<<'\\n'<<flush; continue; }\n\n        Info info = look_ahead(i,ru,rv,dsu,U,V,d);\n        int  minCnt = min(info.cntU,info.cntV);\n        bool mustTake = (minCnt==0);\n\n        /* ratio threshold ------------------------------------------ */\n        double ratio = double(li)/double(d[i]);\n        double t = double(i)/double(M);\n        double thr = 0.85 + 2.15*pow(t,1.25);          // base\n        thr += 0.36 - 0.08*layer[i];                   // layer bonus\n\n        /* extra bonus for Euclidean MST edge ----------------------- */\n        if(inMST[i]){\n            if(layer[i]==0)      thr += 0.18;\n            else if(layer[i]==1) thr += 0.14;\n            else                 thr += 0.10;\n        }\n\n        if(minCnt<=1)       thr+=0.60;\n        else if(minCnt<=3)  thr+=0.40;\n        else if(minCnt<=6)  thr+=0.20;\n        else if(minCnt<=10) thr+=0.10;\n        if(thr>3.0) thr=3.0;\n\n        /* absolute & expectation bargains -------------------------- */\n        bool veryCheap = (li<=25);\n        bool bestDist  = (d[i] <= min(info.minDU,info.minDV)-1);\n\n        bool expectedGood=false;\n        if(info.minDU!=INT_MAX){\n            double expU = info.minDU + 2.0*info.minDU/(info.cntU+1);\n            if(li <= expU - 1) expectedGood = true;\n        }\n        if(!expectedGood && info.minDV!=INT_MAX){\n            double expV = info.minDV + 2.0*info.minDV/(info.cntV+1);\n            if(li <= expV - 1) expectedGood = true;\n        }\n\n        bool pairGood=false;\n        if(info.cntPair){\n            double limit = info.minDPair +\n                           double(info.minDPair)/(info.cntPair+1); // stricter\n            if(li <= limit - 1) pairGood = true;\n        }\n\n        bool cheapEnough = veryCheap || bestDist ||\n                           expectedGood || pairGood || (ratio<=thr);\n\n        bool forced = (components-1 > M-i-1);\n\n        bool take = mustTake || cheapEnough || forced;\n\n        cout<<(take?1:0)<<'\\n'<<flush;\n        if(take && dsu.unite(ru,rv)) --components;\n    }\n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int H = 30, W = 30;\nconst int DX[4]={-1,1,0,0};\nconst int DY[4]={0,0,-1,1};\nconst char DIR_CH[4]={'U','D','L','R'};\n\nstruct Pet{ int x,y,t; };\n\nstruct Human{\n    int x,y;\n    int wall_col;          // column we will turn into a wall\n    int side;              // +1 : stand right of wall, build left  ('l')\n                           // -1 : stand left  of wall, build right ('r')\n    int lane_col;          // column on which we walk\n    int phase = 0;         // 0 walk to (1,lane), 1 build \u2193, 2 repair \u2191, 3 idle\n    bool build_next = true;\n};\n\n/* ------------------------------------------------------- helper functions */\nbool inside(int x,int y){ return 1<=x && x<=H && 1<=y && y<=W; }\n\nchar bfs_first(const vector<string>& board,int sx,int sy,int gx,int gy){\n    if(sx==gx && sy==gy) return '.';\n    static int dist[H+2][W+2];\n    for(int i=1;i<=H;i++) for(int j=1;j<=W;j++) dist[i][j]=-1;\n    queue<pair<int,int>> q;\n    dist[sx][sy]=0; q.push({sx,sy});\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        for(int d=0;d<4;d++){\n            int nx=x+DX[d], ny=y+DY[d];\n            if(!inside(nx,ny) || board[nx][ny]=='#' || dist[nx][ny]!=-1) continue;\n            dist[nx][ny]=dist[x][y]+1;\n            q.push({nx,ny});\n        }\n    }\n    if(dist[gx][gy]==-1) return '.';\n    for(int d=0;d<4;d++){\n        int nx=sx+DX[d], ny=sy+DY[d];\n        if(inside(nx,ny) && dist[nx][ny]==dist[gx][gy]-1) return DIR_CH[d];\n    }\n    return '.';\n}\n\n/* ======================================================================= */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ------------------------------------------------ */\n    int N; if(!(cin>>N)) return 0;\n    vector<Pet> pets(N);\n    for(auto &p:pets) cin>>p.x>>p.y>>p.t;\n\n    int M; cin>>M;\n    vector<Human> hum(M);\n    for(auto &h:hum) cin>>h.x>>h.y;\n\n    /* ---------- choose the best 3-column grid ----------------------------- */\n    int bestOffset = 0;\n    long long bestSum = (1LL<<60), bestWorst = (1LL<<60);\n\n    for(int off=0; off<3; ++off){\n        vector<int> stripeCnt(10,0);          // stripes between 10 internal walls\n        for(auto &p:pets){\n            int y0 = p.y - (2+off);\n            if(y0<0) continue;                // left of the first internal wall\n            int idx = y0/3;\n            if(idx>9) idx=9;\n            ++stripeCnt[idx];\n        }\n        /* which stripes will actually contain humans? -> walls spaced evenly */\n        long long sum=0, worst=0;\n        for(int i=0;i<M;i++){\n            int stripe = (long long)i*10/M;   // same rule as before\n            sum   += stripeCnt[stripe];\n            worst  = max<long long>(worst, stripeCnt[stripe]);\n        }\n        if(sum<bestSum || (sum==bestSum && worst<bestWorst)){\n            bestSum=sum; bestWorst=worst; bestOffset=off;\n        }\n    }\n\n    /* ---------- fixed walls for the chosen offset ------------------------- */\n    vector<int> WALL_COL;\n    for(int k=0; k<10; ++k){\n        int c = 2 + bestOffset + 3*k;\n        if(c<=W) WALL_COL.push_back(c);\n    }\n\n    /* pick M almost evenly spaced walls (same rule as previous versions) */\n    vector<int> used_cols;\n    for(int i=0;i<M;i++){\n        int idx = (long long)i* (int)WALL_COL.size() / M;\n        used_cols.push_back(WALL_COL[idx]);\n    }\n\n    /* initialise humans with those walls */\n    for(int i=0;i<M;i++){\n        hum[i].wall_col = used_cols[i];\n        hum[i].side     = (hum[i].wall_col < 15)? +1 : -1;\n        hum[i].lane_col = hum[i].wall_col + hum[i].side;\n    }\n\n    /* ---------- board representation -------------------------------------- */\n    vector<string> board(H+2,string(W+2,'#'));\n    for(int x=1;x<=H;x++) for(int y=1;y<=W;y++) board[x][y]='.';\n\n    auto pet_near = [&](int x,int y)->bool{\n        for(const auto &p:pets){\n            if(p.x==x && p.y==y) return true;\n            if(abs(p.x-x)+abs(p.y-y)==1) return true;\n        }\n        return false;\n    };\n    auto human_on = [&](int x,int y)->bool{\n        for(const auto &h:hum) if(h.x==x && h.y==y) return true;\n        return false;\n    };\n\n    /* ================= main loop \u2013 300 turns ============================== */\n    for(int turn=0;turn<300;turn++){\n        /* 1. decide tentative actions                                        */\n        struct Tmp{ char act='.'; int nx,ny; int bx,by; };\n        vector<Tmp> tmp(M);\n        bool willWall[H+1][W+1]={};\n\n        for(int i=0;i<M;i++){\n            Human &h = hum[i];\n            Tmp   &t = tmp[i];\n            t.nx=h.x; t.ny=h.y; t.bx=t.by=-1;\n\n            if(h.phase==1 && h.x==H) h.phase=2;            // finished DOWN\n            if(h.phase==2 && h.x==1){\n                int bx=h.x, by=h.y-h.side;\n                if(board[bx][by]=='#') h.phase=3;          // repair done\n            }\n\n            if(h.phase==0){                                // walk to start\n                char mv = bfs_first(board,h.x,h.y,1,h.lane_col);\n                if(mv!='.'){\n                    if(mv=='U'){ t.act='U'; t.nx=h.x-1; }\n                    else if(mv=='D'){ t.act='D'; t.nx=h.x+1; }\n                    else if(mv=='L'){ t.act='L'; t.ny=h.y-1; }\n                    else if(mv=='R'){ t.act='R'; t.ny=h.y+1; }\n                }\n            }\n            else if(h.phase==1){                           // build while \u2193\n                if(h.build_next){\n                    int bx=h.x, by=h.y-h.side;\n                    if(inside(bx,by) && board[bx][by]=='.'\n                       && !pet_near(bx,by) && !human_on(bx,by)){\n                        t.act = (h.side==1)?'l':'r';\n                        t.bx=bx; t.by=by; willWall[bx][by]=true;\n                    }\n                }else{\n                    if(h.x<H && board[h.x+1][h.y]=='.'){\n                        t.act='D'; t.nx=h.x+1;\n                    }\n                }\n            }\n            else if(h.phase==2){                           // repair while \u2191\n                int bx=h.x, by=h.y-h.side;\n                if(inside(bx,by) && board[bx][by]=='.'\n                   && !pet_near(bx,by) && !human_on(bx,by)){\n                    t.act = (h.side==1)?'l':'r';\n                    t.bx=bx; t.by=by; willWall[bx][by]=true;\n                }else if(h.x>1 && board[h.x-1][h.y]=='.'){\n                    t.act='U'; t.nx=h.x-1;\n                }\n            }\n            /* phase 3 : keep '.'                                            */\n        }\n\n        /* 2. cancel moves into walls (existing or new)                       */\n        for(int i=0;i<M;i++){\n            Tmp &t = tmp[i];\n            if(t.act=='U'||t.act=='D'||t.act=='L'||t.act=='R'){\n                if(board[t.nx][t.ny]=='#' || willWall[t.nx][t.ny]){\n                    t.act='.'; t.nx=hum[i].x; t.ny=hum[i].y;\n                }\n            }\n        }\n\n        /* 3. output                                                         */\n        string out; out.reserve(M);\n        for(auto &t:tmp) out.push_back(t.act);\n        cout<<out<<\"\\n\"<<flush;\n\n        /* 4. apply                                                          */\n        for(int i=0;i<M;i++){\n            char c = tmp[i].act;\n            Human &h = hum[i];\n\n            if(c=='U'||c=='D'||c=='L'||c=='R'){\n                h.x = tmp[i].nx; h.y = tmp[i].ny;\n            }\n            if(c=='u'||c=='d'||c=='l'||c=='r'){\n                int bx=h.x, by=h.y;\n                if(c=='u') --bx; else if(c=='d') ++bx;\n                else if(c=='l') --by; else if(c=='r') ++by;\n                if(inside(bx,by)) board[bx][by]='#';\n            }\n\n            if(h.phase==0 && h.x==1 && h.y==h.lane_col){\n                h.phase=1; h.build_next=true;\n            }else if(h.phase==1){\n                if(c=='l'||c=='r') h.build_next=false;\n                else if(c=='D')    h.build_next=true;\n            }\n        }\n\n        /* 5. pets\u2019 movement                                                 */\n        for(int i=0;i<N;i++){\n            string s; cin>>s;\n            auto &p=pets[i];\n            for(char c:s){\n                if(c=='U') --p.x;\n                else if(c=='D') ++p.x;\n                else if(c=='L') --p.y;\n                else if(c=='R') ++p.y;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* --- helpers to query walls ------------------------------------------- */\ninline bool wallU(const vector<string>& v,int i,int j){ return i==0  || v[i-1][j]=='1'; }\ninline bool wallD(const vector<string>& v,int i,int j){ return i==19 || v[i][j]  =='1'; }\ninline bool wallL(const vector<string>& h,int i,int j){ return j==0  || h[i][j-1]=='1'; }\ninline bool wallR(const vector<string>& h,int i,int j){ return j==19 || h[i][j]  =='1'; }\n\n/* ====================================================================== */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ------------ read one test case ---------------------------------- */\n    int si,sj,ti,tj; double p;\n    if(!(cin>>si>>sj>>ti>>tj>>p)) return 0;\n\n    vector<string> h(20); for(int i=0;i<20;++i) cin>>h[i];\n    vector<string> v(19); for(int i=0;i<19;++i) cin>>v[i];\n\n    const int H=20,W=20,N=H*W;\n    auto id=[&](int i,int j){ return i*W+j; };\n\n    /* ===================================================================\n       1) plain BFS for a shortest path (direction order D,R,U,L \u2013 gives\n          a bias towards monotone routes but still allows U/L when needed)\n    =================================================================== */\n    const int di[4]={1,0,-1,0};          // D, R, U, L\n    const int dj[4]={0,1, 0,-1};\n    const char dc[4]={'D','R','U','L'};\n\n    queue<int> q;\n    vector<int>  prev(N,-1);\n    vector<char> pmv (N);\n\n    q.push(id(si,sj));\n    prev[id(si,sj)] = -2;                // source marker\n\n    while(!q.empty()){\n        int cur=q.front(); q.pop();\n        int i=cur/W, j=cur%W;\n        if(i==ti && j==tj) break;\n\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            bool block=(d==0?wallD(v,i,j):\n                        d==1?wallR(h,i,j):\n                        d==2?wallU(v,i,j):wallL(h,i,j));\n            if(block) continue;\n            int nid=id(ni,nj);\n            if(prev[nid]!=-1) continue;\n            prev[nid]=cur;\n            pmv [nid]=dc[d];\n            q.push(nid);\n        }\n    }\n\n    string path;\n    for(int cur=id(ti,tj); prev[cur]!=-2; cur=prev[cur])\n        path.push_back(pmv[cur]);\n    reverse(path.begin(), path.end());\n    const int L = path.size();           // 1 \u2026 39\n\n    /* ===================================================================\n       2) adaptive number of whole-path copies\n    =================================================================== */\n    int copies = 2;\n    if(p > 0.45 && L*3 <= 200) copies = 3;\n\n    /* ===================================================================\n       3) build the final command string\n    =================================================================== */\n    string res; res.reserve(200);\n    for(int k=0;k<copies;++k) res += path;\n\n    while(res.size()+2 <= 200) res += \"DR\";\n    if(res.size()+1 <= 200)    res += 'D';\n    if(res.size()   > 200)     res.resize(200);   // final guard\n\n    cout << res << '\\n';\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- constants ------------------------------------------- */\nconstexpr int H = 30, W = 30, DIR = 4;\nconst int di[DIR] = {0, -1, 0, 1};        // L U R D\nconst int dj[DIR] = {-1, 0, 1, 0};\n\nconst int TO_BASE[8][4] = {\n    {1,0,-1,-1}, {3,-1,-1,0}, {-1,-1,3,2}, {-1,2,1,-1},\n    {1,0,3,2},   {3,2,1,0},   {2,-1,0,-1}, {-1,3,-1,1}\n};\n\n/* ---------- global arrays --------------------------------------- */\nint type[H][W];\nint rot [H][W];                    // working board\nint bestRot[H][W];                 // best closed board\n\nint maskTbl[8][4];\nint toTbl  [8][4][4];\n\n/* ---------- helpers --------------------------------------------- */\ninline bool inside(int i,int j){ return 0<=i && i<H && 0<=j && j<W; }\n\n/* ---------- precalc --------------------------------------------- */\nvoid precalc(){\n    for(int t=0;t<8;++t)\n        for(int r=0;r<4;++r){\n            int m=0;\n            for(int d=0;d<4;++d){\n                int d0=(d-r+4)%4;\n                int nd=TO_BASE[t][d0];\n                int res = (nd==-1)? -1 : (nd+r)%4;\n                toTbl[t][r][d] = res;\n                if(res!=-1){ m |= 1<<d; m |= 1<<res; }\n            }\n            maskTbl[t][r] = m;\n        }\n}\ninline int curMask(int i,int j,const int R[H][W]){\n    return maskTbl[type[i][j]][ R[i][j] ];\n}\n\n/* ---------- fast loop scoring  ---------------------------------- */\nstatic uint16_t vis[H][W][4];\nstatic uint16_t gMark = 1;\n\nlong long loopProduct(const int R[H][W]){\n    uint16_t mark = gMark++;\n    if(mark==0){ memset(vis,0,sizeof(vis)); mark=gMark=1; }\n\n    int best1 = 0, best2 = 0;\n\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int m = maskTbl[type[i][j]][ R[i][j] ];\n        for(int sd=0;sd<4;sd++) if((m>>sd&1) && vis[i][j][sd]!=mark){\n            int si=i,sj=j,sd0=sd;\n            int ci=i,cj=j,cd=sd,len=0;\n            while(true){\n                vis[ci][cj][cd]=mark;\n                int nd = toTbl[type[ci][cj]][ R[ci][cj] ][cd];\n                if(nd==-1){ len=0; break; }\n                int ni = ci+di[nd],  nj = cj+dj[nd];\n                if(!inside(ni,nj)){ len=0; break; }\n                int ndIn = (nd+2)&3;\n                ++len;\n                ci=ni; cj=nj; cd=ndIn;\n                if(ci==si && cj==sj && cd==sd0){\n                    if(len>best1){ best2=best1; best1=len; }\n                    else if(len>best2) best2=len;\n                    break;\n                }\n                if(vis[ci][cj][cd]==mark){ len=0; break; }\n            }\n        }\n    }\n    return (best2==0)?0LL:1LL*best1*best2;\n}\n\n/* ---------- open-end bookkeeping -------------------------------- */\nint openEnds = 0;\nint deltaOE(int i,int j,int nr,const int R[H][W]){\n    int om = curMask(i,j,R), nm = maskTbl[type[i][j]][nr];\n    if(om==nm) return 0;\n    int diff = 0;\n    for(int d=0;d<4;++d){\n        int ni=i+di[d], nj=j+dj[d];\n        int ou=(om>>d)&1, nu=(nm>>d)&1;\n        int nb = inside(ni,nj)? (curMask(ni,nj,R)>>((d+2)&3)&1) : 0;\n        diff += (inside(ni,nj)?2:1) * ((nu^nb) - (ou^nb));\n    }\n    return diff;\n}\ninline void applyRot(int i,int j,int nr,int R[H][W]){\n    openEnds += deltaOE(i,j,nr,R);\n    R[i][j] = nr;\n}\nvoid recomputeOE(int R[H][W]){\n    openEnds=0;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        int m=curMask(i,j,R);\n        for(int d=0;d<4;d++) if(m>>d&1){\n            int ni=i+di[d], nj=j+dj[d];\n            if(!inside(ni,nj) || !(curMask(ni,nj,R)>>((d+2)&3)&1)) ++openEnds;\n        }\n    }\n}\n\n/* ---------- greedy repair (close board) ------------------------- */\nvoid closeBoard(int R[H][W]){\n    bool progress=true;\n    while(openEnds>0 && progress){\n        progress=false;\n        for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n            int bestR = R[i][j], bestD = 0;\n            for(int r=0;r<4;r++){\n                int d = deltaOE(i,j,r,R);\n                if(d<bestD){ bestD=d; bestR=r; }\n            }\n            if(bestD<0){ applyRot(i,j,bestR,R); progress=true; }\n        }\n    }\n}\n\n/* ---------- checkerboard start ---------------------------------- */\nint desiredMask(int i,int j){\n    bool er=!(i&1), ec=!(j&1);\n    if(er)  return ec?((1<<2)|(1<<3)):((1<<0)|(1<<3));\n    else    return ec?((1<<2)|(1<<1)):((1<<0)|(1<<1));\n}\nint bestStartRot(int ty,int want){\n    int best=-1, hit=-1, extra=9;\n    for(int r=0;r<4;r++){\n        int mk=maskTbl[ty][r];\n        int h=__builtin_popcount((unsigned)(mk&want));\n        int e=__builtin_popcount((unsigned)(mk&~want));\n        if(h>hit||(h==hit&&e<extra)){ hit=h; extra=e; best=r; }\n    }\n    return best;\n}\n\n/* ---------- copy helper ----------------------------------------- */\ninline void copyBoard(int dst[H][W], const int src[H][W]){\n    memcpy(dst, src, sizeof(int)*H*W);\n}\n\n/* ---------- timer ------------------------------------------------ */\nstruct Timer{\n    const double TL; chrono::steady_clock::time_point st;\n    Timer(double tl=1.95):TL(tl),st(chrono::steady_clock::now()){}\n    double elapsed()const{\n        return chrono::duration<double>(chrono::steady_clock::now()-st).count();\n    }\n    bool good()const{ return elapsed()<TL; }\n} timer;\n\n/* ===================== main ===================================== */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    precalc();\n    for(int i=0;i<H;i++){\n        string s; cin>>s;\n        for(int j=0;j<W;j++) type[i][j]=s[j]-'0';\n    }\n\n    /* 1. deterministic closed start ------------------------------ */\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++){\n        rot[i][j] = bestStartRot(type[i][j], desiredMask(i,j));\n    }\n    recomputeOE(rot);\n    closeBoard(rot);                          // ensure closed\n    copyBoard(bestRot, rot);\n\n    long long curScore  = loopProduct(rot);\n    long long bestScore = curScore;\n\n    /* 2. simulated annealing ------------------------------------- */\n    const int    PEN = 200;                   // weight for open ends\n    const double T0  = 4000.0, T1 = 2.0;\n\n    mt19937 rng((uint64_t)chrono::high_resolution_clock::now()\n                .time_since_epoch().count());\n    vector<pair<int,int>> v45, vOther;\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++)\n        (type[i][j]==4||type[i][j]==5? v45 : vOther).push_back({i,j});\n    uniform_int_distribution<int> d45(0,(int)v45.size()-1);\n    uniform_int_distribution<int> dO (0,(int)vOther.size()-1);\n    uniform_real_distribution<double> ur(0,1);\n\n    long long energy = PEN*openEnds - curScore;\n\n    while(timer.good()){\n        bool pick45 = !v45.empty() && (rng()%4);   // 75 % on 4/5\n        auto [i,j] = pick45 ? v45[d45(rng)] : vOther[dO(rng)];\n\n        int oldR = rot[i][j];\n        int newR = (type[i][j]==4||type[i][j]==5) ? (oldR^1)\n                   : ((oldR + 1 + (rng()&3)) & 3);\n        if(newR==oldR) continue;\n\n        int dOE = deltaOE(i,j,newR,rot);\n        applyRot(i,j,newR,rot);                  // tentatively\n        long long newScore = loopProduct(rot);\n        long long newEnergy= PEN*openEnds - newScore;\n        long long diff     = newEnergy - energy; // <0 good\n\n        double tFrac = timer.elapsed()/1.8;      // 0 \u2026 1\n        double T = T0 * pow(T1/T0, tFrac);\n        if(diff<=0 || exp(-diff/T) > ur(rng)){   // accept\n            energy=newEnergy; curScore=newScore;\n            if(openEnds==0 && curScore>bestScore){\n                bestScore=curScore;\n                copyBoard(bestRot, rot);\n            }\n        }else{                                   // rollback\n            applyRot(i,j,oldR,rot);\n            openEnds -= dOE;                     // restore\n        }\n    }\n\n    /* 3. final repair (safety) ----------------------------------- */\n    recomputeOE(bestRot);\n    if(openEnds!=0){\n        closeBoard(bestRot);\n    }\n\n    /* 4. output --------------------------------------------------- */\n    string out; out.reserve(H*W);\n    for(int i=0;i<H;i++)for(int j=0;j<W;j++)\n        out.push_back( char('0'+(bestRot[i][j]&3)) );\n    cout<<out<<\"\\n\";\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** helpers ***********************************************************/\nconstexpr int MAXN  = 10;\nconstexpr int MAXNN = MAXN * MAXN;\ninline int bit(int d){ static constexpr int b[4]={2,8,1,4}; return b[d]; }\ninline int opp(int d){ return d ^ 1; }\nconstexpr int dx[4]={-1,1,0,0},  dy[4]={0,0,-1,1};\nconstexpr char DIRC[4] = {'U','D','L','R'};\n\nstruct Timer{\n    chrono::steady_clock::time_point st=chrono::steady_clock::now();\n    double elapsed() const{\n        return chrono::duration<double>(chrono::steady_clock::now()-st).count();\n    }\n};\n\n/*** lightweight fixed hash-set *****************************************/\nstruct HashSet{\n    static constexpr uint64_t EMPTY = 0;\n    int mask;\n    vector<uint64_t> tbl;\n    explicit HashSet(size_t want){\n        size_t sz=1; while(sz < want*2) sz<<=1;\n        mask=int(sz-1);\n        tbl.assign(sz, EMPTY);\n    }\n    inline bool insert(uint64_t x){               // true if new\n        if(x==EMPTY) x=1;\n        int i=int(x)&mask;\n        while(true){\n            uint64_t &s=tbl[i];\n            if(s==EMPTY){ s=x; return true; }\n            if(s==x)     return false;\n            i=(i+1)&mask;\n        }\n    }\n};\n\n/*** Zobrist ***********************************************************/\nuint64_t Z[100][17];\n\n/*** board & evaluation *************************************************/\nstruct Board{\n    int N;\n    array<int8_t,MAXNN> a;          // -1 blank , else 0..15\n    int blank;\n\n    void slide(int dir){\n        int bx=blank/N, by=blank%N;\n        int nx=bx+dx[dir], ny=by+dy[dir];\n        int nid=nx*N+ny;\n        swap(a[blank], a[nid]);\n        blank=nid;\n    }\n\n    struct Eval{ int bestTree, score; };\n    Eval evaluate() const{\n        const int NN=N*N;\n        array<uint8_t,MAXNN> vis{};\n        int q[MAXNN];\n        int bestT=0, treeSum=0, compCnt=0, cycleTot=0, dangling=0, edgeTot=0;\n\n        for(int v=0; v<NN; ++v) if(a[v]>=0 && !vis[v]){\n            ++compCnt;\n            int qs=0, qe=0; q[qe++]=v; vis[v]=1;\n            int verts=0, edges=0;\n            while(qs<qe){\n                int id=q[qs++];\n                ++verts;\n                int x=id/N, y=id%N, pat=a[id];\n                for(int d=0; d<4; ++d) if(pat&bit(d)){\n                    int nx=x+dx[d], ny=y+dy[d];\n                    if(nx<0||nx>=N||ny<0||ny>=N) continue;\n                    int nid=nx*N+ny;\n                    if(a[nid]<0){ ++dangling; continue; }\n                    bool match=a[nid]&bit(opp(d));\n                    if(match){\n                        if(id<nid){ ++edges; ++edgeTot; }\n                        if(!vis[nid]){ vis[nid]=1; q[qe++]=nid; }\n                    }else ++dangling;\n                }\n            }\n            int excess=max(0,edges-(verts-1));\n            cycleTot+=excess;\n            if(excess==0){ bestT=max(bestT,verts); treeSum+=verts; }\n        }\n        int wComp = (bestT*3 < NN         ) ?  5'000 :\n                    (bestT*3 < NN*2       ) ? 35'000 : 160'000;\n        int wCyc  = (bestT*2 < NN*2       ) ? 10'000 :  90'000;\n\n        int sc =  bestT   * 1'500'000\n                + treeSum *     2'500\n                - compCnt *     wComp\n                - cycleTot*     wCyc\n                - dangling*         600\n                + edgeTot;\n        return {bestT, sc};\n    }\n};\n\n/*** beam state *********************************************************/\nstruct State{\n    Board bd;\n    uint64_t h;\n    int bestTree, score;\n    char lastDir;\n    string moves;\n    bool operator<(const State& o) const{ return score<o.score; }\n};\n\n/*** solver *************************************************************/\nstruct Solver{\n    int N,Tlim,BEAM;\n    const double TL = 2.75;          // tighter limit\n    mt19937_64 rng{424242};\n    State bestG;\n\n    uint64_t full_hash(const Board& b){\n        uint64_t h=0;\n        for(int i=0;i<N*N;++i){\n            int v=b.a[i]<0 ? 16 : b.a[i];\n            h ^= Z[i][v];\n        }\n        return h;\n    }\n    inline void upd_hash(uint64_t& h,int pBlank,int tile,int pTile){\n        h ^= Z[pBlank][16] ^ Z[pTile][tile] ^ Z[pBlank][tile] ^ Z[pTile][16];\n    }\n\n    State read_initial(){\n        Board b; b.N=N;\n        for(int i=0;i<N*N;++i) b.a[i]=0;\n        for(int i=0;i<N;++i){\n            string row; cin>>row;\n            for(int j=0;j<N;++j){\n                int idx=i*N+j;\n                int v=(row[j]<='9')?row[j]-'0':row[j]-'a'+10;\n                if(v==0){ b.a[idx]=-1; b.blank=idx; }\n                else    { b.a[idx]=int8_t(v);       }\n            }\n        }\n        auto ev=b.evaluate();\n        return {b, full_hash(b), ev.bestTree, ev.score, -1, \"\"};\n    }\n\n    void beam_search(){\n        Timer tim;\n        vector<State> beam, nxt;\n        beam.reserve(BEAM*2); nxt.reserve(BEAM*4);\n\n        HashSet seenGlobal(1<<20);\n        beam.push_back(read_initial());\n        seenGlobal.insert(beam.front().h);\n        bestG=beam.front();\n        int prevBest=bestG.bestTree;\n\n        while(!beam.empty()){\n            if(tim.elapsed() > TL-0.01) break;          // early stop\n            nxt.clear();\n            HashSet seenLayer(BEAM*8);\n\n            for(const State& st: beam){\n                if(st.moves.size()>=size_t(Tlim)) continue;\n                int bx=st.bd.blank/N, by=st.bd.blank%N;\n                for(int d=0; d<4; ++d){\n                    if(st.lastDir!=-1 && d==opp(st.lastDir)) continue;\n                    int nx=bx+dx[d], ny=by+dy[d];\n                    if(nx<0||nx>=N||ny<0||ny>=N) continue;\n\n                    State ns=st;\n                    int pB=ns.bd.blank, pT=nx*N+ny, tile=ns.bd.a[pT];\n                    upd_hash(ns.h,pB,tile,pT);\n                    ns.bd.slide(d);\n                    ns.lastDir=d;\n                    ns.moves.push_back(DIRC[d]);\n\n                    if(!seenGlobal.insert(ns.h)) continue;\n                    if(!seenLayer.insert(ns.h))  continue;\n\n                    auto ev=ns.bd.evaluate();\n                    ns.bestTree=ev.bestTree;\n                    ns.score   =ev.score;\n                    if(ev.bestTree>bestG.bestTree) bestG=ns;\n\n                    nxt.push_back(move(ns));\n                }\n                if(tim.elapsed()>TL-0.02) break;        // safety\n            }\n            if(nxt.empty()) break;\n\n            int keep=min(BEAM,(int)nxt.size());\n            nth_element(nxt.begin(),nxt.begin()+keep,nxt.end(),\n                         [](const State&a,const State&b){return a.score>b.score;});\n            beam.assign(nxt.begin(),nxt.begin()+keep);\n\n            /* 10 % random survivors */\n            int extra=keep/10;\n            if(keep<(int)nxt.size()){\n                uniform_int_distribution<int> uni(keep,(int)nxt.size()-1);\n                for(int i=0;i<extra;++i) beam.push_back(nxt[uni(rng)]);\n            }\n\n            if(bestG.bestTree>prevBest){\n                prevBest=bestG.bestTree;\n                beam.clear(); beam.push_back(bestG);\n            }\n        }\n    }\n\n    void run(){\n        ios::sync_with_stdio(false); cin.tie(nullptr);\n        cin>>N>>Tlim;\n        BEAM = (N>=9? 3000 : 2000);          // slightly reduced\n\n        for(auto& r:Z) for(auto& v:r) v=rng();\n        beam_search();\n        cout<<bestG.moves<<'\\n';\n    }\n};\n\n/*** main **************************************************************/\nint main(){ Solver().run(); }","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\n/* ---------- very small 64-bit xorshift RNG ----------------------- */\nstruct FastRand{\n    uint64_t x = 88172645463325252ULL;\n    uint64_t next(){ x ^= x<<7; x ^= x>>9; return x; }\n    int next_int(int l,int r){ return int(next()%uint64_t(r-l+1))+l; }\n} rng;\n\n/* ---------- constants ------------------------------------------- */\nconstexpr int    R            = 10000;                 // cake radius\nconstexpr ll     BIG          = 1'000'000'000LL;       // \u00b11e9 endpoints\nconstexpr int    K_MAX        = 100;                   // judge limit\nconstexpr double TOTAL_TIME   = 2.85;                  // whole runtime\nconstexpr double POST_TIME    = 0.35;                  // hill-climb phase\nconstexpr double SAFE_MARGIN  = 0.03;                  // printing etc.\nconstexpr double T0_MAIN      = 35.0;                  // SA temperature\n\n/* ---------- helper: fresh integer -------------------------------- */\nint fresh_coord(const unordered_set<int>& forbid,\n                unordered_set<int>&       used,\n                int lo,int hi){\n    int x;\n    do x = rng.next_int(lo,hi); while(forbid.count(x)||used.count(x));\n    used.insert(x);\n    return x;\n}\n\n/* ---------- evaluator: V \u00d7 H \u00d7 D\u207a \u00d7 D\u207b grid ---------------------- */\nstruct Evaluator{\n    const vector<pair<int,int>>& P;\n    const array<int,11>& need;\n    vector<int> buf;\n    Evaluator(const vector<pair<int,int>>& p,const array<int,11>& a)\n        :P(p),need(a){}\n\n    int operator()(const vector<int>& vx,\n                   const vector<int>& hy,\n                   const vector<int>& dp,\n                   const vector<int>& dn){\n        int V=vx.size(), H=hy.size(), Dp=dp.size(), Dn=dn.size();\n        size_t W = size_t(V+1)*(H+1)*(Dp+1)*(Dn+1);\n        buf.assign(W,0);\n\n        for(auto [x,y]:P){\n            int ix=int(lower_bound(vx.begin(),vx.end(),x)-vx.begin());\n            int iy=int(lower_bound(hy.begin(),hy.end(),y)-hy.begin());\n            int ip=Dp?int(lower_bound(dp.begin(),dp.end(),x-y)-dp.begin()):0;\n            int in=Dn?int(lower_bound(dn.begin(),dn.end(),x+y)-dn.begin()):0;\n            size_t idx=(((size_t)ix*(H+1)+iy)*(Dp+1)+ip)*(Dn+1)+in;\n            ++buf[idx];\n        }\n        array<int,11> have{};\n        for(int c:buf) if(1<=c && c<=10) ++have[c];\n\n        int served=0;\n        for(int d=1;d<=10;++d) served+=min(need[d],have[d]);\n        return served;\n    }\n};\n\n/* ---------- long SA on vertical + horizontal -------------------- */\nvoid SA_vh(double timeBudget,\n           const unordered_set<int>& forbidX,\n           const unordered_set<int>& forbidY,\n           Evaluator& eval,\n           vector<int>& VX, vector<int>& HY,\n           int&        bestScore)\n{\n    const auto beg=chrono::steady_clock::now();\n    auto elapsed=[&](){\n        return chrono::duration<double>(chrono::steady_clock::now()-beg).count();\n    };\n\n    while(elapsed()+SAFE_MARGIN < timeBudget){\n        double subLim=min(0.28, timeBudget-elapsed()-SAFE_MARGIN);\n        const auto subBeg=chrono::steady_clock::now();\n\n        /* random start, guaranteed distinct */\n        vector<int> vx,hy; unordered_set<int> used;\n        int v=rng.next_int(12,48), h=rng.next_int(12,48);\n        for(int i=0;i<v;++i) vx.push_back(fresh_coord(forbidX,used,-R+1,R-1));\n        used.clear();\n        for(int i=0;i<h;++i) hy.push_back(fresh_coord(forbidY,used,-R+1,R-1));\n        sort(vx.begin(),vx.end()); sort(hy.begin(),hy.end());\n\n        int cur = eval(vx,hy,{},{});                 // baseline\n\n        while(true){\n            double t=chrono::duration<double>(\n                      chrono::steady_clock::now()-subBeg).count();\n            if(t>subLim) break;\n            double T = T0_MAIN * pow(1.0/T0_MAIN, t/subLim);\n\n            vector<int> nvx=vx, nhy=hy;\n            int op=rng.next_int(0,99);               // 0-59 mv, 60-79 add, 80- del\n            bool ok=true;\n\n            if(op<60 && (!nvx.empty()||!nhy.empty())){   /* move */\n                bool vert=nhy.empty()?true:nvx.empty()?false:rng.next_int(0,1);\n                if(vert){\n                    int id=rng.next_int(0,(int)nvx.size()-1);\n                    int neu=nvx[id]+rng.next_int(-1200,1200);\n                    neu=max(-R+1,min(R-1,neu));\n                    if(!forbidX.count(neu)&&!binary_search(nvx.begin(),nvx.end(),neu)){\n                        nvx[id]=neu; sort(nvx.begin(),nvx.end());\n                    }else ok=false;\n                }else{\n                    int id=rng.next_int(0,(int)nhy.size()-1);\n                    int neu=nhy[id]+rng.next_int(-1200,1200);\n                    neu=max(-R+1,min(R-1,neu));\n                    if(!forbidY.count(neu)&&!binary_search(nhy.begin(),nhy.end(),neu)){\n                        nhy[id]=neu; sort(nhy.begin(),nhy.end());\n                    }else ok=false;\n                }\n            }\n            else if(op<80 && nvx.size()+nhy.size()<K_MAX){ /* insert */\n                bool vert=rng.next_int(0,1);\n                if(vert){\n                    unordered_set<int> u(nvx.begin(),nvx.end());\n                    int x=fresh_coord(forbidX,u,-R+1,R-1);\n                    nvx.push_back(x); sort(nvx.begin(),nvx.end());\n                }else{\n                    unordered_set<int> u(nhy.begin(),nhy.end());\n                    int y=fresh_coord(forbidY,u,-R+1,R-1);\n                    nhy.push_back(y); sort(nhy.begin(),nhy.end());\n                }\n            }\n            else if(!nvx.empty()||!nhy.empty()){          /* delete */\n                bool vert=nhy.empty()?true:nvx.empty()?false:rng.next_int(0,1);\n                if(vert) nvx.erase(nvx.begin()+rng.next_int(0,(int)nvx.size()-1));\n                else     nhy.erase(nhy.begin()+rng.next_int(0,(int)nhy.size()-1));\n            }else ok=false;\n\n            if(!ok) continue;\n\n            int sc=eval(nvx,nhy,{},{});                  /* still no diagonals */\n            int d=sc-cur;\n            bool acc = d>=0 || exp(double(d)/T) >\n                        (rng.next_int(0,1000000)/1'000'000.0);\n            if(acc){\n                vx.swap(nvx); hy.swap(nhy); cur=sc;\n                if(sc>bestScore){ bestScore=sc; VX=vx; HY=hy; }\n            }\n        }\n    }\n}\n\n/* ---------- monotone hill-climb on ALL families ------------------ */\nvoid hill_climb(double timeBudget,\n                const unordered_set<int>& forbidX,\n                const unordered_set<int>& forbidY,\n                const unordered_set<int>& forbidP,\n                const unordered_set<int>& forbidN,\n                Evaluator& eval,\n                vector<int>& VX, vector<int>& HY,\n                vector<int>& DP, vector<int>& DN,\n                int&        bestScore)\n{\n    const auto beg=chrono::steady_clock::now();\n    auto elapsed=[&](){return chrono::duration<double>(\n                          chrono::steady_clock::now()-beg).count();};\n\n    unordered_set<int> usedX(VX.begin(),VX.end()),\n                       usedY(HY.begin(),HY.end()),\n                       usedP(DP.begin(),DP.end()),\n                       usedN(DN.begin(),DN.end());\n\n    while(elapsed() < timeBudget){\n        int fam=rng.next_int(0,3);          // 0 V, 1 H, 2 P, 3 N\n        int op = rng.next_int(0,99);        // 0-49 mv, 50-79 add, 80- del\n        vector<int> nvx=VX, nhy=HY, ndp=DP, ndn=DN;\n        bool ok=true;\n\n        auto mv=[&](vector<int>& v,const unordered_set<int>& forbid,int span){\n            if(v.empty()){ ok=false; return; }\n            int id=rng.next_int(0,(int)v.size()-1);\n            int neu=v[id]+rng.next_int(-span,span);\n            neu=max(-span,min(span,neu));\n            if(forbid.count(neu)||binary_search(v.begin(),v.end(),neu)){ ok=false; return;}\n            v[id]=neu; sort(v.begin(),v.end());\n        };\n        auto ad=[&](vector<int>& v,unordered_set<int>& used,\n                    const unordered_set<int>& forbid,int lo,int hi){\n            if(VX.size()+HY.size()+DP.size()+DN.size()>=K_MAX){ ok=false; return; }\n            int x;\n            do x=rng.next_int(lo,hi); while(forbid.count(x)||used.count(x));\n            v.push_back(x); sort(v.begin(),v.end()); used.insert(x);\n        };\n        auto dl=[&](vector<int>& v,unordered_set<int>& used){\n            if(v.empty()){ ok=false; return; }\n            int id=rng.next_int(0,(int)v.size()-1);\n            used.erase(v[id]); v.erase(v.begin()+id);\n        };\n\n        if(op<50){ /* move */\n            if(fam==0) mv(nvx,forbidX,R-1);\n            else if(fam==1) mv(nhy,forbidY,R-1);\n            else if(fam==2) mv(ndp,forbidP,2*R-1);\n            else            mv(ndn,forbidN,2*R-1);\n        }\n        else if(op<80){ /* add */\n            if(fam==0) ad(nvx,usedX,forbidX,-R+1,R-1);\n            else if(fam==1) ad(nhy,usedY,forbidY,-R+1,R-1);\n            else if(fam==2) ad(ndp,usedP,forbidP,-2*R+1,2*R-1);\n            else            ad(ndn,usedN,forbidN,-2*R+1,2*R-1);\n        }\n        else{        /* delete */\n            if(fam==0) dl(nvx,usedX);\n            else if(fam==1) dl(nhy,usedY);\n            else if(fam==2) dl(ndp,usedP);\n            else            dl(ndn,usedN);\n        }\n        if(!ok) continue;\n\n        int sc=eval(nvx,nhy,ndp,ndn);\n        if(sc>bestScore){                    // keep strictly better grids\n            VX.swap(nvx); HY.swap(nhy); DP.swap(ndp); DN.swap(ndn);\n            bestScore=sc;\n        }\n    }\n}\n\n/* ============================= main ============================== */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N,K; if(!(cin>>N>>K)) return 0;\n    array<int,11> a{}; for(int d=1; d<=10; ++d) cin>>a[d];\n\n    vector<pair<int,int>> P(N);\n    unordered_set<int> forbidX,forbidY,forbidP,forbidN;\n    forbidX.reserve(N*2); forbidY.reserve(N*2);\n    forbidP.reserve(N*2); forbidN.reserve(N*2);\n    for(auto& pt:P){\n        cin>>pt.first>>pt.second;\n        forbidX.insert(pt.first);\n        forbidY.insert(pt.second);\n        forbidP.insert(pt.first-pt.second);\n        forbidN.insert(pt.first+pt.second);\n    }\n    Evaluator eval(P,a);\n\n    vector<int> VX,HY,DP,DN;\n    int bestScore=-1;\n\n    /* Phase 1: long SA on vertical + horizontal */\n    SA_vh(TOTAL_TIME-POST_TIME-SAFE_MARGIN,\n          forbidX,forbidY,\n          eval,VX,HY,bestScore);\n\n    /* Phase 2: monotone hill-climb on all four families */\n    hill_climb(POST_TIME,\n               forbidX,forbidY,forbidP,forbidN,\n               eval,VX,HY,DP,DN,bestScore);\n\n    /* ------------- output -------------------- */\n    cout<<VX.size()+HY.size()+DP.size()+DN.size()<<\"\\n\";\n    for(int x:VX) cout<<x<<\" \"<<-BIG<<\" \"<<x<<\" \"<<BIG<<\"\\n\";\n    for(int y:HY) cout<<-BIG<<\" \"<<y<<\" \"<<BIG<<\" \"<<y<<\"\\n\";\n    for(int c:DP){ ll X1=-100000,X2=100000; ll Y1=X1-c,Y2=X2-c;\n        cout<<X1<<\" \"<<Y1<<\" \"<<X2<<\" \"<<Y2<<\"\\n\"; }\n    for(int s:DN){ ll X1=-100000,X2=100000; ll Y1=s-X1, Y2=s-X2;\n        cout<<X1<<\" \"<<Y1<<\" \"<<X2<<\" \"<<Y2<<\"\\n\"; }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int MAXN = 62;                    // 61 + 1 safety row/col\n\n/* ------------------------------------------------------------------ */\n/*  very small, cache-friendly board representation                    */\n/* ------------------------------------------------------------------ */\nstruct Board {\n    int N, C;\n    unsigned char dot [MAXN][MAXN];\n    unsigned char h   [MAXN][MAXN];         // horizontal edge  (x,y)-(x+1,y)\n    unsigned char v   [MAXN][MAXN];         // vertical   edge  (x,y)-(x,y+1)\n    unsigned char ne  [MAXN][MAXN];         // diagonal  /\n    unsigned char nw  [MAXN][MAXN];         // diagonal  \\\n\n    void clearEdges(int n) {\n        for (int y = 0; y < n; ++y) {\n            memset(h [y],  0, n);\n            memset(v [y],  0, n);\n            memset(ne[y],  0, n);\n            memset(nw[y],  0, n);\n        }\n    }\n};\n\n/* ------------------------------------------------------------------ */\nstatic int              N, M;\nstatic long long        weight[MAXN][MAXN];\nstatic long long        Sboard = 0;\nstatic Board            basic;\nstatic long long        basicSum = 0;\n\n/* ------------------------------------------------------------------ */\nstruct Candidate {\n    int kind, x, y, miss;                   // 0 = square, 1 = diamond\n    int w;                                  // missing corner weight\n};\nstatic Candidate candPool[512];             // filled per iteration\nstatic int       poolSz;\n\n/* ------------------------------------------------------------------ */\nstruct RunResult {\n    long long sum;\n    vector<array<int,8>> moves;\n};\n\n/* ------------------------------------------------------------------ */\nRunResult oneRun(mt19937 &rng, int T0, int cool) {\n    Board B = basic;            // copy dots, empty edges\n    B.clearEdges(N);\n\n    vector<array<int,8>> moves;\n    long long sum = basicSum;\n\n    int step = 0;\n    while (true) {\n        int best = -1;\n        poolSz = 0;\n\n        /* ------------ axis aligned unit squares ------------------ */\n        for (int y = 0; y < N-1; ++y)\n            for (int x = 0; x < N-1; ++x) {\n                if (B.h[y][x] || B.h[y+1][x] || B.v[y][x] || B.v[y][x+1]) continue;\n\n                unsigned char p0 = B.dot[x][y]    ,\n                               p1 = B.dot[x+1][y]  ,\n                               p2 = B.dot[x+1][y+1],\n                               p3 = B.dot[x][y+1]  ;\n                int missCnt = (!p0)+(!p1)+(!p2)+(!p3);\n                if (missCnt != 1) continue;\n\n                int mi = !p0 ? 0 : !p1 ? 1 : !p2 ? 2 : 3;\n                int xx = x + (mi==1 || mi==2);\n                int yy = y + (mi>=2);\n                int w  = (int)weight[xx][yy];\n\n                if (w > best) best = w;\n                if (poolSz < 512) candPool[poolSz++] = {0,x,y,mi,w};\n            }\n\n        /* ------------ 45\u00b0 diamonds ------------------------------- */\n        for (int y = 0; y <= N-3; ++y)\n            for (int x = 1; x <= N-2; ++x) {\n                if (B.ne[y][x]      || B.nw[y+1][x] ||\n                    B.ne[y+1][x-1] ||  B.nw[y][x-1]) continue;\n\n                unsigned char p0 = B.dot[x][y]     ,\n                               p1 = B.dot[x+1][y+1] ,\n                               p2 = B.dot[x][y+2]   ,\n                               p3 = B.dot[x-1][y+1] ;\n                int missCnt = (!p0)+(!p1)+(!p2)+(!p3);\n                if (missCnt != 1) continue;\n\n                int mi = !p0 ? 0 : !p1 ? 1 : !p2 ? 2 : 3;\n                int xx, yy;\n                if (mi==0){xx=x;   yy=y;}\n                if (mi==1){xx=x+1; yy=y+1;}\n                if (mi==2){xx=x;   yy=y+2;}\n                if (mi==3){xx=x-1; yy=y+1;}\n                int w = (int)weight[xx][yy];\n\n                if (w > best) best = w;\n                if (poolSz < 512) candPool[poolSz++] = {1,x,y,mi,w};\n            }\n\n        if (poolSz == 0) break;            // no legal move left\n\n        int tol = max(5, T0 - step / cool);\n        int th  = best - tol;\n\n        /* ----------- build roulette -------------------------------- */\n        uint64_t tot = 0;\n        static uint64_t acc[512];\n        int kept = 0;\n        for (int i = 0; i < poolSz; ++i) {\n            int rel = candPool[i].w - th;\n            if (rel < 0) continue;         // below threshold\n            uint64_t score = 1ull * rel * rel + 1;   // (rel)\u00b2  (+1 avoids 0)\n            tot += score;\n            acc[kept] = tot;\n            candPool[kept++] = candPool[i];\n        }\n        poolSz = kept;\n        if (poolSz == 0) break;            // numerical safety\n\n        uint64_t r = rng() % tot;\n        int idx = int(lower_bound(acc, acc + poolSz, r + 1) - acc);\n        const Candidate &c = candPool[idx];\n\n        array<int,8> line;\n\n        if (c.kind == 0) {                 /* --------- square ------ */\n            auto corner=[&](int k)->pair<int,int>{\n                switch(k&3){\n                    case 0:return {c.x    ,c.y    };\n                    case 1:return {c.x+1  ,c.y    };\n                    case 2:return {c.x+1  ,c.y+1  };\n                    default:return{c.x    ,c.y+1  };\n                }};\n\n            bool cw = rng() & 1;\n            for (int k=0;k<4;++k){\n                auto [cx,cy]=corner(c.miss + (cw? k : -k));\n                line[2*k]=cx; line[2*k+1]=cy;\n            }\n            /* mark */\n            B.h[c.y][c.x]   = 1;\n            B.h[c.y+1][c.x] = 1;\n            B.v[c.y][c.x]   = 1;\n            B.v[c.y][c.x+1] = 1;\n\n            auto [nx,ny]=corner(c.miss);\n            B.dot[nx][ny]=1;\n            sum += weight[nx][ny];\n        } else {                           /* --------- diamond ----- */\n            auto corner=[&](int k)->pair<int,int>{\n                switch(k&3){\n                    case 0:return {c.x    ,c.y    };\n                    case 1:return {c.x+1  ,c.y+1  };\n                    case 2:return {c.x    ,c.y+2  };\n                    default:return{c.x-1  ,c.y+1  };\n                }};\n            bool cw = rng() & 1;\n            for (int k=0;k<4;++k){\n                auto [cx,cy]=corner(c.miss + (cw? k : -k));\n                line[2*k]=cx; line[2*k+1]=cy;\n            }\n            /* mark */\n            B.ne[c.y][c.x]     = 1;\n            B.nw[c.y+1][c.x]   = 1;\n            B.ne[c.y+1][c.x-1] = 1;\n            B.nw[c.y][c.x-1]   = 1;\n\n            auto [nx,ny]=corner(c.miss);\n            B.dot[nx][ny]=1;\n            sum += weight[nx][ny];\n        }\n\n        moves.push_back(line);\n        ++step;\n    }\n    return {sum, move(moves)};\n}\n\n/* ------------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    if (!(cin>>N>>M)) return 0;\n    int C = (N-1)/2;\n\n    for (int y=0;y<N;++y)\n        for (int x=0;x<N;++x){\n            long long w = 1LL*(x-C)*(x-C) + 1LL*(y-C)*(y-C) + 1;\n            weight[x][y]=w;\n            Sboard += w;\n        }\n\n    memset(basic.dot,0,sizeof(basic.dot));\n    for (int i=0;i<M;++i){\n        int x,y;cin>>x>>y;\n        basic.dot[x][y]=1;\n        basicSum += weight[x][y];\n    }\n    basic.N=N; basic.C=C;\n\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    auto t0 = chrono::steady_clock::now();\n\n    RunResult best {basicSum,{}};\n\n    int runs = 0;\n    while (true){\n        ++runs;\n        int T0   = 120 + rng()%181;        // 120 \u2026 300\n        int cool = 3   + rng()%3;          // 3,4,5\n        RunResult r = oneRun(rng, T0, cool);\n        if (r.sum > best.sum) best = move(r);\n\n        if (chrono::duration<double>(chrono::steady_clock::now()-t0).count() > 4.8)\n            break;\n    }\n    // cerr<<\"runs=\"<<runs<<\"\\n\";\n\n    cout<<best.moves.size()<<'\\n';\n    for (auto &ln: best.moves){\n        for (int i=0;i<8;++i){\n            if (i) cout<<' ';\n            cout<<ln[i];\n        }\n        cout<<'\\n';\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Grid = array<array<int,10>,10>;\n\n/* ------------------------------------------------------------------ */\n/* locate p-th empty cell (1-based, row-major order)                   */\npair<int,int> locate_empty(const Grid& g,int idx){\n    int cnt = 0;\n    for(int r=0;r<10;r++)\n        for(int c=0;c<10;c++)\n            if(g[r][c]==0 && ++cnt==idx) return {r,c};\n    return {-1,-1};                               // should never happen\n}\n\n/* ------------------------------------------------------------------ */\n/* perform one global tilt                                             */\nvoid tilt(Grid& dst,const Grid& src,char dir){\n    dst = {};                                     // fill with zeros\n    if(dir=='F'){                                 // to row 0\n        for(int c=0;c<10;c++){\n            int wr = 0;\n            for(int r=0;r<10;r++) if(src[r][c]) dst[wr++][c] = src[r][c];\n        }\n    }else if(dir=='B'){                           // to row 9\n        for(int c=0;c<10;c++){\n            int wr = 9;\n            for(int r=9;r>=0;r--) if(src[r][c]) dst[wr--][c] = src[r][c];\n        }\n    }else if(dir=='L'){                           // to col 0\n        for(int r=0;r<10;r++){\n            int wc = 0;\n            for(int c=0;c<10;c++) if(src[r][c]) dst[r][wc++] = src[r][c];\n        }\n    }else{                                        // 'R' to col 9\n        for(int r=0;r<10;r++){\n            int wc = 9;\n            for(int c=9;c>=0;c--) if(src[r][c]) dst[r][wc--] = src[r][c];\n        }\n    }\n}\n\n/* ------------------------------------------------------------------ */\n/* statistics needed for tie-breaking                                  */\nstruct Stat{\n    long long sum_sq;     // \u03a3 component_size\u00b2\n    int sameE;            // identical-flavour edges\n    int diffE;            // mixed-flavour edges\n    int maxComp;          // size of largest connected component\n    int moved;            // # candies whose coordinates changed\n};\n\nstatic const int DR[4]={-1,1,0,0};\nstatic const int DC[4]={0,0,-1,1};\n\nStat analyse(const Grid& before,const Grid& after){\n    /* --- \u03a3 size\u00b2, biggest component size (one BFS pass) ------------ */\n    bool vis[10][10]={};\n    long long sum = 0;\n    int largest = 0;\n    queue<pair<int,int>> q;\n\n    for(int r=0;r<10;r++)for(int c=0;c<10;c++){\n        if(after[r][c]==0 || vis[r][c]) continue;\n        int col = after[r][c], sz = 0;\n        vis[r][c] = true; q.push({r,c});\n        while(!q.empty()){\n            auto [cr,cc] = q.front(); q.pop(); ++sz;\n            for(int k=0;k<4;k++){\n                int nr = cr + DR[k], nc = cc + DC[k];\n                if(nr<0||nr>=10||nc<0||nc>=10) continue;\n                if(!vis[nr][nc] && after[nr][nc]==col){\n                    vis[nr][nc]=true; q.push({nr,nc});\n                }\n            }\n        }\n        sum     += 1LL*sz*sz;\n        largest  = max(largest,sz);\n    }\n\n    /* --- edge statistics and move count ---------------------------- */\n    int sameE=0, diffE=0, moved=0;\n    for(int r=0;r<10;r++)for(int c=0;c<10;c++){\n        int v = after[r][c];\n        if(v && before[r][c]!=v) ++moved;\n\n        if(r+1<10 && v && after[r+1][c])\n            (v==after[r+1][c] ? sameE : diffE)++;\n        if(c+1<10 && v && after[r][c+1])\n            (v==after[r][c+1] ? sameE : diffE)++;\n    }\n    return {sum,sameE,diffE,largest,moved};\n}\n\n/* ------------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read all 100 flavours */\n    int flavour[100];\n    for(int i=0;i<100;i++) cin>>flavour[i];\n\n    Grid board = {};                           // start empty\n    const char DIRS[4] = {'F','B','L','R'};\n\n    for(int t=0;t<100;t++){\n        int p; cin>>p;                         // placement index\n        auto [r,c] = locate_empty(board,p);\n        board[r][c] = flavour[t];\n\n        if(t==99) break;                       // final tilt irrelevant\n\n        /* evaluate the four directions -------------------------------- */\n        long long bestSum   = -1;\n        int       bestSame  = -1;\n        int       bestDiff  = INT_MAX;\n        int       bestMax   = -1;\n        int       bestMoved = INT_MAX;\n        char      bestDir   = 'F';\n        Grid      bestBoard;\n\n        for(char dir:DIRS){\n            Grid after;\n            tilt(after,board,dir);\n            Stat st = analyse(board,after);\n\n            bool better = false;\n            if(st.sum_sq > bestSum) better = true;\n            else if(st.sum_sq == bestSum){\n                if(st.sameE > bestSame) better = true;\n                else if(st.sameE == bestSame){\n                    if(st.diffE < bestDiff) better = true;\n                    else if(st.diffE == bestDiff){\n                        if(st.maxComp > bestMax) better = true;\n                        else if(st.maxComp == bestMax && st.moved < bestMoved)\n                            better = true;\n                    }\n                }\n            }\n            if(better){\n                bestSum   = st.sum_sq;\n                bestSame  = st.sameE;\n                bestDiff  = st.diffE;\n                bestMax   = st.maxComp;\n                bestMoved = st.moved;\n                bestDir   = dir;\n                bestBoard = after;\n            }\n        }\n\n        board = bestBoard;\n        cout << bestDir << '\\n' << flush;\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** tiny 64-bit hash ***************************************************/\nstatic inline uint64_t splitmix64(uint64_t x){\n    x += 0x9e3779b97f4a7c15ULL;\n    x  = (x ^ (x>>30)) * 0xbf58476d1ce4e5b9ULL;\n    x  = (x ^ (x>>27)) * 0x94d049bb133111ebULL;\n    return  x ^ (x>>31);\n}\n\n/*** very small RNG (xor-shift) *****************************************/\nstatic uint64_t rng_state = 123456789987654321ULL;\nstatic inline uint64_t rng64(){\n    rng_state ^= rng_state<<7;  rng_state ^= rng_state>>9;\n    return rng_state;\n}\n\n/*** tiny undirected graph, N \u2264 100 ************************************/\nstruct Graph{\n    int N{};\n    array<array<uint64_t,2>,100> row{};\n    void init(int n){ N=n; for(int i=0;i<n;i++) row[i][0]=row[i][1]=0; }\n    inline void addEdge(int i,int j){\n        if(j<64){ row[i][0]|=1ULL<<j; row[j][0]|=1ULL<<i; }\n        else     { row[i][1]|=1ULL<<(j-64); row[j][1]|=1ULL<<(i-64); }\n    }\n    inline bool edge(int i,int j) const{\n        return (j<64)?((row[i][0]>>j)&1ULL)\n                     :((row[i][1]>>(j-64))&1ULL);\n    }\n    inline int degree(int i) const{\n        return __builtin_popcountll(row[i][0]) + __builtin_popcountll(row[i][1]);\n    }\n};\n\n/*** canonical bitset by degree order (permutation invariant) ***********/\nvector<uint64_t> canon_deg(const Graph& g){\n    const int N=g.N;\n    vector<int> ord(N); iota(ord.begin(),ord.end(),0);\n    stable_sort(ord.begin(),ord.end(),[&](int a,int b){\n        if(g.degree(a)!=g.degree(b)) return g.degree(a)<g.degree(b);\n        return a<b;\n    });\n    const size_t TOT=size_t(N)*(N-1)/2, WORDS=(TOT+63)>>6;\n    vector<uint64_t> bits(WORDS,0ULL);\n    size_t idx=0;\n    for(int i=0;i<N;i++){\n        int oi=ord[i];\n        for(int j=i+1;j<N;j++){\n            int oj=ord[j];\n            if(g.edge(oi,oj)) bits[idx>>6]|=1ULL<<(idx&63);\n            ++idx;\n        }\n    }\n    return bits;\n}\n\n/*** canonical bitset with one WL seed **********************************/\nvector<uint64_t> canon_WL(const Graph& g, uint64_t seed){\n    const int N=g.N;\n    vector<uint64_t> col(N);\n    for(int v=0;v<N;v++) col[v]=splitmix64(uint64_t(g.degree(v))^seed);\n\n    vector<uint64_t> nxt(N);\n    for(int it=0; it<8; ++it){                         /* 8 WL rounds */\n        for(int v=0; v<N; ++v){\n            uint64_t h1=0,h2=0;\n            for(int u=0; u<N; ++u) if(g.edge(v,u)){\n                h1 += col[u];\n                h2 += splitmix64(col[u]);\n            }\n            nxt[v]=splitmix64(col[v]^h1^splitmix64(h2)^seed);\n        }\n        col.swap(nxt);\n    }\n\n    /* permutation-invariant tie-breaker *****************************/\n    vector<int> ord(N); iota(ord.begin(),ord.end(),0);\n    stable_sort(ord.begin(),ord.end(),[&](int a,int b){\n        if(col[a]!=col[b]) return col[a]<col[b];\n        return splitmix64(col[a]^seed)<splitmix64(col[b]^seed);\n    });\n\n    const size_t TOT=size_t(N)*(N-1)/2, WORDS=(TOT+63)>>6;\n    vector<uint64_t> bits(WORDS,0ULL);\n    size_t idx=0;\n    for(int i=0;i<N;i++){\n        int oi=ord[i];\n        for(int j=i+1;j<N;j++){\n            int oj=ord[j];\n            if(g.edge(oi,oj)) bits[idx>>6]|=1ULL<<(idx&63);\n            ++idx;\n        }\n    }\n    return bits;\n}\n\n/*** Hamming distance of two bit-vectors ******************************/\ninline int hamm(const vector<uint64_t>& A,const vector<uint64_t>& B){\n    int s=0; for(size_t i=0;i<A.size();i++) s+=__builtin_popcountll(A[i]^B[i]);\n    return s;\n}\n\n/*** ================================================================== */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M; double eps; if(!(cin>>M>>eps)) return 0;\n\n    /* graph size N (small for good 1/N factor) ---------------------- */\n    int N;\n    if(eps<=0.12) N=24;\n    else if(eps<=0.20) N=30;\n    else if(eps<=0.28) N=40;\n    else if(eps<=0.36) N=55;\n    else               N=70;\n\n    cout<<N<<\"\\n\";\n\n    const size_t TOT=size_t(N)*(N-1)/2;\n    constexpr int S_WL=17;                 /* WL seeds               */\n    constexpr int S   = S_WL+1;            /* +1 for degree order    */\n    const uint64_t SEED[S_WL]={\n        0x1337ULL,0x9b1d2fe3ULL,0xdeadbeefULL,0x8128abcdULL,0xfeedfaceULL,\n        0xabcdef01ULL,0x31415926ULL,0x27182818ULL,0xc001d00dULL,\n        0x0f1cebadULL,0xbadc0ffeeULL,0x422d0badULL,0x12345678ULL,\n        0x87654321ULL,0xa55a5aa5ULL,0x13579bdfULL,0xfdb97531ULL\n    };\n\n    /* --------------------- build catalogue ------------------------ */\n    struct Pack{ array<vector<uint64_t>,S> bits; };\n    vector<Pack> cat(M);\n    Graph g; g.init(N);\n\n    for(int k=0;k<M;k++){\n        g.init(N);\n        string line; line.reserve(TOT);\n        for(int i=0;i<N;i++)\n            for(int j=i+1;j<N;j++){\n                bool e = rng64() & 1ULL;          /* p = \u00bd */\n                line.push_back(e?'1':'0');\n                if(e) g.addEdge(i,j);\n            }\n        /* WL bitsets */\n        for(int s=0;s<S_WL;s++) cat[k].bits[s]=canon_WL(g,SEED[s]);\n        /* degree-order bitset (last slot) */\n        cat[k].bits[S-1]=canon_deg(g);\n        cout<<line<<\"\\n\";\n    }\n    cout.flush();\n\n    /* ----------------------- answer 100 queries ------------------- */\n    for(int q=0;q<100;q++){\n        string hs; cin>>hs;\n        Graph H; H.init(N);\n        size_t idx=0;\n        for(int i=0;i<N;i++)\n            for(int j=i+1;j<N;j++)\n                if(hs[idx++]=='1') H.addEdge(i,j);\n\n        array<vector<uint64_t>,S> qb;\n        for(int s=0;s<S_WL;s++) qb[s]=canon_WL(H,SEED[s]);\n        qb[S-1]=canon_deg(H);\n\n        int best=0, bestScore=INT_MAX;\n        for(int k=0;k<M;k++){\n            /* keep three smallest distances ----------------------- */\n            int a=INT_MAX,b=INT_MAX,c=INT_MAX;\n            for(int s=0;s<S;s++){\n                int d=hamm(qb[s],cat[k].bits[s]);\n                if(d<a){ c=b; b=a; a=d; }\n                else if(d<b){ c=b; b=d; }\n                else if(d<c) c=d;\n            }\n            int score=a+b+c;\n            if(score<bestScore){ bestScore=score; best=k; }\n        }\n        cout<<best<<\"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int MAX_D = 30;\nusing Clock = chrono::steady_clock;\nstruct Edge { int u,v,w; };\ninline long long sq(long long x){ return x*x; }\n\n/* ------------------------------------------------------------ */\n/* Dijkstra that ignores edge `ban` (\u20131 = none)                 */\nlong long dijkstra_ignore(int s,int t,int ban,\n        const vector<Edge>& E,\n        const vector<vector<pair<int,int>>>& adj,\n        vector<long long>& dist)\n{\n    const long long INF = (1LL<<60);\n    fill(dist.begin(),dist.end(),INF);\n    using Q=pair<long long,int>;\n    priority_queue<Q,vector<Q>,greater<Q>> pq;\n    dist[s]=0; pq.emplace(0,s);\n    while(!pq.empty()){\n        auto [d,v]=pq.top(); pq.pop();\n        if(d!=dist[v]) continue;\n        if(v==t) return d;\n        for(auto [to,id]:adj[v]) if(id!=ban){\n            long long nd=d+E[id].w;\n            if(nd<dist[to]){ dist[to]=nd; pq.emplace(nd,to); }\n        }\n    }\n    return INF;                                 // never happens\n}\n\n/* connectivity after removing day `ban` */\nbool connected_without_day(int ban,\n        const vector<int>& day,\n        const vector<vector<pair<int,int>>>& adj)\n{\n    int N=adj.size();\n    vector<char> vis(N,0);\n    queue<int> q; q.push(0); vis[0]=1; int seen=1;\n    while(!q.empty()){\n        int v=q.front(); q.pop();\n        for(auto [to,id]:adj[v])\n            if(day[id]!=ban && !vis[to]){ vis[to]=1; ++seen; q.push(to); }\n    }\n    return seen==N;\n}\n/* ------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N,M,D,K;\n    if(!(cin>>N>>M>>D>>K)) return 0;\n    vector<Edge> E(M);\n    vector<int> deg(N,0);\n    for(int i=0;i<M;++i){\n        cin>>E[i].u>>E[i].v>>E[i].w;\n        --E[i].u; --E[i].v;\n        ++deg[E[i].u]; ++deg[E[i].v];\n    }\n    for(int i=0,x,y;i<N;++i) cin>>x>>y;\n\n    /* adjacency */\n    vector<vector<pair<int,int>>> adj(N);\n    for(int i=0;i<M;++i){\n        adj[E[i].u].push_back({E[i].v,i});\n        adj[E[i].v].push_back({E[i].u,i});\n    }\n\n    std::mt19937 rng(20240517u);\n    vector<long long> dist(N);\n\n    /* betweenness from 40 random sources */\n    vector<int> bet(M,0), parent(N);\n    const int SRC=40;\n    for(int it=0; it<SRC; ++it){\n        int s=rng()%N;\n        const long long INF=(1LL<<60);\n        fill(dist.begin(),dist.end(),INF);\n        fill(parent.begin(),parent.end(),-1);\n        using Q=pair<long long,int>;\n        priority_queue<Q,vector<Q>,greater<Q>> pq;\n        dist[s]=0; pq.emplace(0,s);\n        while(!pq.empty()){\n            auto [d,v]=pq.top(); pq.pop();\n            if(d!=dist[v]) continue;\n            for(auto [to,id]:adj[v]){\n                long long nd=d+E[id].w;\n                if(nd<dist[to]){\n                    dist[to]=nd;\n                    parent[to]=id;\n                    pq.emplace(nd,to);\n                }\n            }\n        }\n        for(int v=0; v<N; ++v)\n            if(v!=s && parent[v]>=0) ++bet[parent[v]];\n    }\n\n    /* detour length */\n    vector<long long> extra(M);\n    for(int id=0; id<M; ++id)\n        extra[id]=dijkstra_ignore(E[id].u,E[id].v,id,E,adj,dist)-E[id].w;\n    vector<int> extraS(M);\n    for(int i=0;i<M;++i) extraS[i]=int(extra[i]/1000);\n\n    /* importance */\n    vector<int> imp(M);\n    for(int i=0;i<M;++i) imp[i]=5*bet[i]+extraS[i];\n\n    /* soft capacities per (v,d) */\n    vector< array<uint8_t,MAX_D> > cap(N);\n    for(int v=0; v<N; ++v){\n        int base=deg[v]/D, rem=deg[v]%D, shift=rng()%D;\n        for(int i=0;i<D;++i){\n            int d=(i+shift)%D;\n            cap[v][d]=base+(i<rem);\n        }\n    }\n\n    /* ---------------- greedy ---------------- */\n    vector<int> order(M); iota(order.begin(),order.end(),0);\n    shuffle(order.begin(),order.end(),rng);\n    sort(order.begin(),order.end(),\n         [&](int a,int b){ return imp[a]>imp[b]; });\n\n    vector<int> day(M,-1);\n    vector<int16_t> load(D);\n    vector< array<int16_t,MAX_D> > used(N); for(auto& a:used) a.fill(0);\n    vector<long long> dayImp(D), dayExtra(D);\n\n    for(int id:order){\n        int u=E[id].u, v=E[id].v;\n        long long best=LLONG_MAX; int bestD=-1;\n        for(int d=0; d<D; ++d) if(load[d]<K){\n            long long s=20LL*(used[u][d]+used[v][d])+dayImp[d];\n            if(s<best){ best=s; bestD=d; }\n        }\n        if(bestD<0) bestD=int(min_element(load.begin(),load.end())-load.begin());\n        day[id]=bestD;\n        ++load[bestD]; ++used[u][bestD]; ++used[v][bestD];\n        dayImp [bestD]+=imp[id];\n        dayExtra[bestD]+=extra[id];\n    }\n\n    auto computeCost=[&](){\n        long long v=0,d=0;\n        for(int vv=0; vv<N; ++vv) for(int dd=0; dd<D; ++dd)\n            v+=sq(used[vv][dd]);\n        for(int dd=0; dd<D; ++dd) d+=sq(dayImp[dd]);\n        return v+d;\n    };\n    long long curCost=computeCost(), bestCost=curCost;\n    vector<int> bestDay=day;\n\n    /* ---------------- SA (moves + swaps) ---------------- */\n    const double SA_TIME=4.0, T0=1.0, T1=0.01;\n    auto t0=Clock::now();\n    uniform_real_distribution<double> U01(0,1);\n\n    auto accept=[&](long long delta,double Temp)->bool{\n        return delta<=0 || U01(rng)<exp(-delta/Temp);\n    };\n\n    auto moveEdge=[&](int id,int toDay,double Temp){\n        int from=day[id]; if(from==toDay||load[toDay]>=K) return;\n        int u=E[id].u, v=E[id].v, w=imp[id];\n        long long delta =\n            -sq(used[u][from])-sq(used[v][from])-sq(used[u][toDay])-sq(used[v][toDay])\n            +sq(used[u][from]-1)+sq(used[v][from]-1)\n            +sq(used[u][toDay]+1)+sq(used[v][toDay]+1)\n            -sq(dayImp[from])-sq(dayImp[toDay])\n            +sq(dayImp[from]-w)+sq(dayImp[toDay]+w);\n        if(!accept(delta,Temp)) return;\n\n        /* commit */\n        day[id]=toDay;\n        --load[from]; ++load[toDay];\n        --used[u][from]; --used[v][from];\n        ++used[u][toDay]; ++used[v][toDay];\n        dayImp[from]-=w; dayImp[toDay]+=w;\n        curCost += delta;\n        if(curCost < bestCost){ bestCost=curCost; bestDay=day; }\n    };\n\n    auto swapEdges=[&](int a,int b,double Temp){\n        int dA=day[a], dB=day[b]; if(dA==dB) return;\n        int u1=E[a].u, v1=E[a].v, w1=imp[a];\n        int u2=E[b].u, v2=E[b].v, w2=imp[b];\n\n        long long delta=0;\n        auto upd=[&](int v,int d,int diff){\n            delta -= sq(used[v][d]);\n            delta += sq(used[v][d]+diff);\n        };\n        upd(u1,dA,-1); upd(v1,dA,-1);\n        upd(u2,dB,-1); upd(v2,dB,-1);\n        upd(u1,dB,+1); upd(v1,dB,+1);\n        upd(u2,dA,+1); upd(v2,dA,+1);\n\n        delta -= sq(dayImp[dA])+sq(dayImp[dB]);\n        delta += sq(dayImp[dA]-w1+w2)+sq(dayImp[dB]-w2+w1);\n\n        if(!accept(delta,Temp)) return;\n\n        /* commit */\n        day[a]=dB; day[b]=dA;\n        used[u1][dA]--; used[v1][dA]--;\n        used[u2][dB]--; used[v2][dB]--;\n        used[u1][dB]++; used[v1][dB]++;\n        used[u2][dA]++; used[v2][dA]++;\n        dayImp[dA]=dayImp[dA]-w1+w2;\n        dayImp[dB]=dayImp[dB]-w2+w1;\n        curCost += delta;\n        if(curCost < bestCost){ bestCost=curCost; bestDay=day; }\n    };\n\n    const int MASK=(1<<20)-1;\n    for(long long iter=0;;++iter){\n        if((iter&MASK)==0){\n            double t=chrono::duration<double>(Clock::now()-t0).count();\n            if(t>=SA_TIME) break;\n        }\n        double prog=chrono::duration<double>(Clock::now()-t0).count()/SA_TIME;\n        double Temp=T0*pow(T1/T0,prog);\n\n        if(rng()&1){\n            moveEdge(rng()%M, rng()%D, Temp);\n        }else{\n            int a=rng()%M, b=rng()%M;\n            swapEdges(a,b,Temp);\n        }\n    }\n    day=bestDay;                               // best schedule found\n\n    /* ---------------- rebuild helpers ---------------- */\n    fill(load.begin(),load.end(),0);\n    vector< array<int16_t,MAX_D> > used2(N); for(auto& a:used2) a.fill(0);\n    fill(dayImp.begin(),dayImp.end(),0);\n    fill(dayExtra.begin(),dayExtra.end(),0);\n    for(int i=0;i<M;++i){\n        ++load[day[i]];\n        ++used2[E[i].u][day[i]]; ++used2[E[i].v][day[i]];\n        dayImp [day[i]]+=imp[i];\n        dayExtra[day[i]]+=extra[i];\n    }\n    vector<vector<int>> listDay(D);\n    for(int d=0;d<D;++d) listDay[d].clear();\n    for(int i=0;i<M;++i) listDay[day[i]].push_back(i);\n\n    /* ---------------- connectivity repair (as before) ------------- */\n    for(int d=0; d<D; ++d){\n        bool changed=true;\n        while(changed && !connected_without_day(d,day,adj)){\n            changed=false;\n            /* components */\n            vector<int> comp(N,-1);\n            int cc=0;\n            for(int s=0;s<N;++s) if(comp[s]<0){\n                queue<int> q; q.push(s); comp[s]=cc;\n                while(!q.empty()){\n                    int v=q.front(); q.pop();\n                    for(auto [to,id]:adj[v])\n                        if(day[id]!=d && comp[to]<0){\n                            comp[to]=cc; q.push(to);\n                        }\n                }\n                ++cc;\n            }\n            for(int id:listDay[d]){\n                int u=E[id].u, v=E[id].v;\n                if(comp[u]==comp[v]) continue;\n                int tgt=-1;\n                for(int t=0;t<D;++t) if(t!=d && load[t]<K){ tgt=t; break; }\n                if(tgt<0) continue;\n                day[id]=tgt;\n                --load[d]; ++load[tgt];\n                --used2[u][d]; --used2[v][d];\n                ++used2[u][tgt]; ++used2[v][tgt];\n                dayImp[d]-=imp[id]; dayImp[tgt]+=imp[id];\n                dayExtra[d]-=extra[id]; dayExtra[tgt]+=extra[id];\n                listDay[tgt].push_back(id);\n                listDay[d].erase(remove(listDay[d].begin(),\n                                         listDay[d].end(),id),\n                                  listDay[d].end());\n                changed=true; break;\n            }\n        }\n    }\n\n    /* ---------------- small detour balancer ----------------------- */\n    auto tBal=Clock::now();\n    while(chrono::duration<double>(Clock::now()-tBal).count()<0.8){\n        int dMax=max_element(dayExtra.begin(),dayExtra.end())-dayExtra.begin();\n        int dMin=min_element(dayExtra.begin(),dayExtra.end())-dayExtra.begin();\n        if(dayExtra[dMax]<=dayExtra[dMin]+1000) break;\n        int idBest=-1; long long best=-1;\n        for(int id:listDay[dMax])\n            if(extra[id]>best){ best=extra[id]; idBest=id; }\n        if(idBest<0) break;\n        bool moved=false;\n        for(int shift=0; shift<D; ++shift){\n            int tgt=(dMin+shift)%D;\n            if(tgt==dMax || load[tgt]>=K) continue;\n            day[idBest]=tgt;\n            if(connected_without_day(dMax,day,adj) &&\n               connected_without_day(tgt ,day,adj)){\n                --load[dMax]; ++load[tgt];\n                int u=E[idBest].u, v=E[idBest].v;\n                --used2[u][dMax]; --used2[v][dMax];\n                ++used2[u][tgt];  ++used2[v][tgt];\n                dayImp[dMax]-=imp[idBest]; dayImp[tgt]+=imp[idBest];\n                dayExtra[dMax]-=extra[idBest]; dayExtra[tgt]+=extra[idBest];\n                listDay[tgt].push_back(idBest);\n                listDay[dMax].erase(remove(listDay[dMax].begin(),\n                                           listDay[dMax].end(),idBest),\n                                    listDay[dMax].end());\n                moved=true; break;\n            }\n            day[idBest]=dMax;\n        }\n        if(!moved) break;\n    }\n\n    /* ---------------- output -------------------- */\n    for(int i=0;i<M;++i){\n        if(i) cout<<' ';\n        cout<<day[i]+1;\n    }\n    cout<<\"\\n\";\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------------- helpers ---------------- */\ntemplate<class T>\ninline bool chmax(T& a,const T& b){ if(a<b){a=b;return true;} return false; }\n\nstruct Pillar{ vector<int> vox; int len()const{return (int)vox.size();} };\nstruct CmpLen{ bool operator()(Pillar*a,Pillar*b)const{return a->len()<b->len();} };\n\n/* =================================================================== */\nstruct Solver{\n    int D,SZ;\n    vector<vector<string>> F,R;\n    int rowPref[2][15]{}, colPref[2][15]{};\n    mt19937_64 rng{123456789};\n    chrono::steady_clock::time_point lim;\n\n    /* --------------------------------------------------------------- */\n    void read(){\n        cin>>D;\n        F.assign(2,vector<string>(D));\n        R.assign(2,vector<string>(D));\n        for(int k=0;k<2;++k){\n            for(int z=0;z<D;++z) cin>>F[k][z];\n            for(int z=0;z<D;++z) cin>>R[k][z];\n        }\n        SZ=D*D*D;\n    }\n\n    /* --------------------------------------------------------------- */\n    void buildPref(){\n        int cntRow[2][15][15]{}, cntCol[2][15][15]{};\n        for(int o=0;o<2;++o)\n            for(int z=0;z<D;++z)\n                for(int x=0;x<D;++x) if(F[o][z][x]=='1')\n                    for(int y=0;y<D;++y) if(R[o][z][y]=='1'){\n                        ++cntRow[o][x][y]; ++cntCol[o][y][x];\n                    }\n\n        for(int o=0;o<2;++o){\n            for(int x=0;x<D;++x){\n                int best=0,by=0;\n                for(int y=0;y<D;++y) if(chmax(best,cntRow[o][x][y])) by=y;\n                rowPref[o][x]=by;\n            }\n            for(int y=0;y<D;++y){\n                int best=0,bx=0;\n                for(int x=0;x<D;++x) if(chmax(best,cntCol[o][y][x])) bx=x;\n                colPref[o][y]=bx;\n            }\n        }\n    }\n\n    /* --------------------------------------------------------------- */\n    struct Res{ double score; int n; vector<int> b1,b2; };\n\n    Res trial(){\n        const auto idx=[this](int x,int y,int z){return x*D*D+y*D+z;};\n        vector<char> occ[2]; occ[0].assign(SZ,0); occ[1].assign(SZ,0);\n        vector<char> preferGrid(D*D);\n        uniform_real_distribution<double> uni(0.0,1.0);\n        auto rndElem=[&](const vector<int>& v){\n            return v[uniform_int_distribution<int>(0,(int)v.size()-1)(rng)];\n        };\n\n        auto place=[&](int o,int z,const vector<char>* prefer){\n            vector<int> X,Y;\n            for(int x=0;x<D;++x) if(F[o][z][x]=='1') X.push_back(x);\n            for(int y=0;y<D;++y) if(R[o][z][y]=='1') Y.push_back(y);\n\n            bool rowMajor = (X.size()==Y.size()) ? (rng()&1) : (X.size()>=Y.size());\n\n            vector<char> rowUsed(D,0), colUsed(D,0);\n            if(rowMajor){                                /* rows dominate */\n                vector<int> unRow;\n                for(int x:X){\n                    int y=-1;\n                    if(prefer)\n                        for(int yy:Y) if(!colUsed[yy]&&(*prefer)[x*D+yy]){y=yy;break;}\n                    if(y==-1){\n                        int cand = (rng()&1)? rowPref[o][x] : rndElem(Y);\n                        if(find(Y.begin(),Y.end(),cand)!=Y.end() && !colUsed[cand])\n                            y=cand;\n                    }\n                    if(y==-1){ unRow.push_back(x); continue; }\n                    occ[o][idx(x,y,z)]=1; rowUsed[x]=colUsed[y]=1;\n                }\n                for(int y:Y) if(!colUsed[y]){\n                    int x=unRow.back(); unRow.pop_back();\n                    occ[o][idx(x,y,z)]=1; rowUsed[x]=colUsed[y]=1;\n                }\n                for(int x:unRow){\n                    int y=rndElem(Y);\n                    occ[o][idx(x,y,z)]=1;\n                }\n            }else{                                       /* columns dominate */\n                vector<int> unCol;\n                for(int y:Y){\n                    int x=-1;\n                    if(prefer)\n                        for(int xx:X) if(!rowUsed[xx]&&(*prefer)[xx*D+y]){x=xx;break;}\n                    if(x==-1){\n                        int cand=(rng()&1)? colPref[o][y] : rndElem(X);\n                        if(find(X.begin(),X.end(),cand)!=X.end() && !rowUsed[cand])\n                            x=cand;\n                    }\n                    if(x==-1){ unCol.push_back(y); continue; }\n                    occ[o][idx(x,y,z)]=1; rowUsed[x]=colUsed[y]=1;\n                }\n                for(int x:X) if(!rowUsed[x]){\n                    int y=unCol.back(); unCol.pop_back();\n                    occ[o][idx(x,y,z)]=1; rowUsed[x]=colUsed[y]=1;\n                }\n                for(int y:unCol){\n                    int x=rndElem(X);\n                    occ[o][idx(x,y,z)]=1;\n                }\n            }\n        };\n\n        for(int z=0;z<D;++z){\n            if(rng()&1){\n                place(0,z,nullptr);\n                for(int x=0;x<D;++x) for(int y=0;y<D;++y)\n                    preferGrid[x*D+y]=occ[0][idx(x,y,z)];\n                place(1,z,&preferGrid);\n            }else{\n                place(1,z,nullptr);\n                for(int x=0;x<D;++x) for(int y=0;y<D;++y)\n                    preferGrid[x*D+y]=occ[1][idx(x,y,z)];\n                place(0,z,&preferGrid);\n            }\n        }\n\n        /* -------- pillar split & pairing -------------------------- */\n        vector<unique_ptr<Pillar>> store[2];\n        auto collect=[&](int s){\n            for(int x=0;x<D;++x) for(int y=0;y<D;++y)\n                for(int z=0;z<D;){\n                    if(occ[s][idx(x,y,z)]){\n                        auto p=make_unique<Pillar>();\n                        while(z<D&&occ[s][idx(x,y,z)]) p->vox.push_back(idx(x,y,z++));\n                        store[s].push_back(std::move(p));\n                    }else ++z;\n                };\n        };\n        collect(0); collect(1);\n\n        priority_queue<Pillar*,vector<Pillar*>,CmpLen> Q[2];\n        for(auto& p:store[0]) Q[0].push(p.get());\n        for(auto& p:store[1]) Q[1].push(p.get());\n\n        vector<int> B1(SZ,0), B2(SZ,0);\n        int nextId=1;\n        for(int L=D;L>=1;--L){\n            while(!Q[0].empty()&&!Q[1].empty()\n                  &&Q[0].top()->len()>=L&&Q[1].top()->len()>=L){\n                Pillar* a=Q[0].top(); Q[0].pop();\n                Pillar* b=Q[1].top(); Q[1].pop();\n                int id=nextId++;\n                for(int i=0;i<L;++i){\n                    B1[a->vox.back()]=id; a->vox.pop_back();\n                    B2[b->vox.back()]=id; b->vox.pop_back();\n                }\n                if(a->len()) Q[0].push(a);\n                if(b->len()) Q[1].push(b);\n            }\n        }\n        for(int s=0;s<2;++s)\n            for(auto& up:store[s]) if(up->len()){\n                int id=nextId++;\n                for(int v:up->vox) (s?B2:B1)[v]=id;\n            }\n\n        /* -------- evaluate ---------------------------------------- */\n        vector<int> vol(nextId), use(nextId);\n        for(int v:B1) if(v){vol[v]++; use[v]|=1;}\n        for(int v:B2) if(v){vol[v]++; use[v]|=2;}\n        double r1=0,r2=0,shared=0;\n        for(int id=1;id<nextId;++id){\n            if(use[id]==1) r2+=vol[id];\n            else if(use[id]==2) r1+=vol[id];\n            else if(use[id]==3) shared+=1.0/vol[id];\n        }\n        return {r1+r2+shared,nextId-1,std::move(B1),std::move(B2)};\n    }\n\n    /* --------------------------------------------------------------- */\n    void solve(){\n        buildPref();\n        lim=chrono::steady_clock::now()+chrono::milliseconds(5700);\n\n        Res best=trial();                       // deterministic first trial\n        while(chrono::steady_clock::now()<lim){\n            Res t=trial();\n            if(t.score<best.score) best=std::move(t);\n        }\n\n        cout<<best.n<<'\\n';\n        for(int i=0;i<SZ;++i){ if(i) cout<<' '; cout<<best.b1[i]; }\n        cout<<'\\n';\n        for(int i=0;i<SZ;++i){ if(i) cout<<' '; cout<<best.b2[i]; }\n        cout<<'\\n';\n    }\n};\n\n/* =================================================================== */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    Solver S;\n    S.read();\n    S.solve();\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nusing ll = long long;\nconst int MAX_R = 5000;\nconst ll  INF64 = (1LL << 60);\n\ninline int ceilDist(int x1, int y1, int x2, int y2) {\n    long long dx = 1LL * x1 - x2, dy = 1LL * y1 - y2;\n    return int(std::ceil(std::sqrt(double(dx * dx + dy * dy))));\n}\nstruct Edge { int u, v; ll w; };\ninline int other(const Edge &e, int x) { return e.u == x ? e.v : e.u; }\n\nstruct DSU {\n    vector<int> p, sz;\n    explicit DSU(int n = 0): p(n), sz(n, 1) { iota(p.begin(), p.end(), 0); }\n    int  find(int x) { return p[x] == x ? x : p[x] = find(p[x]); }\n    bool unite(int a, int b) {\n        a = find(a); b = find(b);\n        if (a == b) return false;\n        if (sz[a] < sz[b]) swap(a, b);\n        p[b] = a; sz[a] += sz[b];\n        return true;\n    }\n};\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 main \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K;\n    if (!(cin >> N >> M >> K)) return 0;\n\n    /* vertices */\n    vector<int> vx(N), vy(N);\n    for (int i = 0; i < N; ++i) cin >> vx[i] >> vy[i];\n\n    /* edges */\n    vector<Edge> es(M);\n    vector<vector<pair<int,int>>> g(N);\n    for (int i = 0; i < M; ++i) {\n        int a, b; ll w; cin >> a >> b >> w; --a; --b;\n        es[i] = {a, b, w};\n        g[a].push_back({b, i});\n        g[b].push_back({a, i});\n    }\n\n    /* residents */\n    vector<int> rx(K), ry(K);\n    for (int k = 0; k < K; ++k) cin >> rx[k] >> ry[k];\n\n    /* dist(v, resident) \u2264 5000 */\n    vector<vector<int>> distVR(N, vector<int>(K, MAX_R + 1));\n    vector<vector<pair<int,int>>> cov(N);\n    for (int v = 0; v < N; ++v)\n        for (int k = 0; k < K; ++k) {\n            int d = ceilDist(vx[v], vy[v], rx[k], ry[k]);\n            distVR[v][k] = d;\n            if (d <= MAX_R) cov[v].push_back({k, d});\n        }\n\n    /* all-pairs shortest paths (100\u00d7Dijkstra) */\n    vector<vector<ll>> distVV(N, vector<ll>(N, INF64));\n    vector<vector<int>> parentE(N, vector<int>(N, -1));\n    using QEntry = pair<ll,int>;\n    for (int s = 0; s < N; ++s) {\n        auto &d  = distVV[s];\n        auto &pe = parentE[s];\n        priority_queue<QEntry, vector<QEntry>, greater<QEntry>> pq;\n        d[s] = 0; pq.push({0, s});\n        while (!pq.empty()) {\n            auto [du, u] = pq.top(); pq.pop();\n            if (du != d[u]) continue;\n            for (auto [to, idx] : g[u]) {\n                ll nd = du + es[idx].w;\n                if (nd < d[to]) { d[to] = nd; pe[to] = idx; pq.push({nd, to}); }\n            }\n        }\n    }\n    auto add_path = [&](int src, int dst, vector<char>& on) {\n        for (int v = dst; v != src; ) {\n            int e = parentE[src][v];\n            on[e] = 1;\n            v = other(es[e], v);\n        }\n    };\n\n    /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 greedy cover \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n    vector<char> chosen(N, 0);\n    chosen[0] = 1;                        // root always chosen\n\n    vector<char> covered(K, 0), edgeRootOn(M, 0);\n    auto addCostRootPath = [&](int v) {\n        ll c = 0;\n        for (int u = v; u != 0; ) {\n            int e = parentE[0][u];\n            if (!edgeRootOn[e]) c += es[e].w;\n            u = other(es[e], u);\n        }\n        return c;\n    };\n    int coveredCnt = 0;\n    while (coveredCnt < K) {\n        int bestV = -1, bestRad = 0;\n        double bestSc = -1;\n        for (int v = 0; v < N; ++v) if (!chosen[v]) {\n            int gain = 0, rad = 0;\n            for (auto [rid, d] : cov[v]) if (!covered[rid]) { ++gain; rad = max(rad, d); }\n            if (!gain) continue;\n            double sc = double(gain) / double(addCostRootPath(v) + 1LL * rad * rad);\n            if (sc > bestSc) { bestSc = sc; bestV = v; bestRad = rad; }\n        }\n        if (bestV == -1) break;\n        chosen[bestV] = 1;\n        for (auto [rid, d] : cov[bestV])\n            if (!covered[rid] && d <= bestRad) { covered[rid] = 1; ++coveredCnt; }\n        add_path(0, bestV, edgeRootOn);\n    }\n\n    /* assignment & radii */\n    vector<int> assign(K, -1), assignD(K, MAX_R + 1);\n    vector<vector<int>> resByV(N);\n    vector<int> radius(N, 0);\n    auto rebuild = [&](){\n        for (int v = 0; v < N; ++v) { resByV[v].clear(); radius[v] = 0; }\n        for (int k = 0; k < K; ++k) {\n            int bestV = -1, bestD = MAX_R + 1;\n            for (int v = 0; v < N; ++v) if (chosen[v]) {\n                int d = distVR[v][k];\n                if (d < bestD) { bestD = d; bestV = v; }\n            }\n            assign[k] = bestV; assignD[k] = bestD;\n            resByV[bestV].push_back(k);\n            radius[bestV] = max(radius[bestV], bestD);\n        }\n    };\n    rebuild();\n\n    /* cable builder for terminals (root+chosen) */\n    vector<char> edgeBuf(M);\n    auto cable_cost = [&](const vector<char>& chosenSet, vector<char>* out)->ll{\n        vector<char> term = chosenSet; term[0] = 1;\n        vector<int> terminals;\n        for (int v = 0; v < N; ++v) if (term[v]) terminals.push_back(v);\n        if (terminals.size() <= 1) { if (out) fill(out->begin(), out->end(), 0); return 0; }\n\n        int T = terminals.size();\n        vector<char> used(T, 0);\n        vector<ll>   best(T, INF64);\n        vector<int>  par(T, -1);\n        best[0] = 0;\n        vector<pair<int,int>> mst;\n        for (int it = 0; it < T; ++it) {\n            int v = -1;\n            for (int i = 0; i < T; ++i)\n                if (!used[i] && (v == -1 || best[i] < best[v])) v = i;\n            used[v] = 1;\n            if (par[v] != -1) mst.push_back({ terminals[v], terminals[par[v]] });\n            for (int j = 0; j < T; ++j) if (!used[j]) {\n                ll w = distVV[terminals[v]][terminals[j]];\n                if (w < best[j]) { best[j] = w; par[j] = v; }\n            }\n        }\n        vector<char> edgeOn(M, 0);\n        for (auto [a, b] : mst) add_path(a, b, edgeOn);\n\n        /* prune non-terminal leaves */\n        vector<vector<int>> adj(N);\n        vector<int> deg(N, 0);\n        for (int e = 0; e < M; ++e) if (edgeOn[e]) {\n            adj[es[e].u].push_back(e); adj[es[e].v].push_back(e);\n            ++deg[es[e].u]; ++deg[es[e].v];\n        }\n        queue<int> q;\n        for (int v = 0; v < N; ++v) if (deg[v] == 1 && !term[v]) q.push(v);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            for (int ei : adj[v]) if (edgeOn[ei]) {\n                edgeOn[ei] = 0;\n                int u = other(es[ei], v);\n                if (--deg[u] == 1 && !term[u]) q.push(u);\n            }\n        }\n        ll cost = 0;\n        for (int e = 0; e < M; ++e) if (edgeOn[e]) cost += es[e].w;\n        if (out) *out = std::move(edgeOn);\n        return cost;\n    };\n\n    /* small local searches (time limited) */\n    auto startT = chrono::high_resolution_clock::now();\n\n    /* --- add-only --- */\n    while (true) {\n        int bestV = -1; ll bestDelta = 0;\n        ll radNow = 0; for (int v = 0; v < N; ++v) if (chosen[v]) radNow += 1LL * radius[v] * radius[v];\n\n        for (int cand = 0; cand < N; ++cand) if (!chosen[cand]) {\n            int radNew = 0; vector<int> moved;\n            for (auto [rid, d] : cov[cand])\n                if (d < assignD[rid]) { moved.push_back(rid); radNew = max(radNew, d); }\n            if (moved.empty()) continue;\n\n            vector<char> movedFlg(K, 0); for (int id : moved) movedFlg[id] = 1;\n            ll deltaRad = 1LL * radNew * radNew;\n            vector<int> touched;\n            for (int id : moved) {\n                int s = assign[id];\n                if (find(touched.begin(), touched.end(), s) == touched.end()) touched.push_back(s);\n            }\n            for (int s : touched) {\n                int newR = 0;\n                for (int rid : resByV[s]) if (!movedFlg[rid]) newR = max(newR, assignD[rid]);\n                deltaRad += 1LL * newR * newR - 1LL * radius[s] * radius[s];\n            }\n            ll edgeAdd = addCostRootPath(cand);\n            ll delta = deltaRad + edgeAdd;\n            if (delta < bestDelta) { bestDelta = delta; bestV = cand; }\n        }\n        if (bestV == -1) break;\n        chosen[bestV] = 1;\n        add_path(0, bestV, edgeRootOn);\n        for (auto [rid, d] : cov[bestV]) if (d < assignD[rid]) { assign[rid] = bestV; assignD[rid] = d; }\n        rebuild();\n        if (chrono::duration<double>(chrono::high_resolution_clock::now() - startT).count() > 1.4) break;\n    }\n\n    /* cable after additions */\n    vector<char> edgeNow;\n    ll cableNow = cable_cost(chosen, &edgeNow);\n\n    /* --- remove-if-beneficial --- */\n    while (true) {\n        ll radNow = 0; for (int v = 0; v < N; ++v) if (chosen[v]) radNow += 1LL * radius[v] * radius[v];\n        ll curTotal = radNow + cableNow;\n\n        int bestRem = -1; ll bestDelta = 0;\n        vector<int>  nAssign, nAssignD, nRadius;\n        vector<vector<int>> nResByV;\n\n        for (int cand = 1; cand < N; ++cand) if (chosen[cand]) { // never drop root\n            bool ok = true;\n            vector<int> a = assign, d = assignD;\n            for (int rid : resByV[cand]) {\n                int bestS = -1, bestD = MAX_R + 1;\n                for (int v = 0; v < N; ++v) if (chosen[v] && v != cand) {\n                    int dist = distVR[v][rid];\n                    if (dist <= MAX_R && dist < bestD) { bestD = dist; bestS = v; }\n                }\n                if (bestS == -1) { ok = false; break; }\n                a[rid] = bestS; d[rid] = bestD;\n            }\n            if (!ok) continue;\n\n            vector<vector<int>> rbv(N);\n            vector<int> rad(N, 0);\n            for (int k = 0; k < K; ++k) {\n                rbv[a[k]].push_back(k);\n                rad[a[k]] = max(rad[a[k]], d[k]);\n            }\n            vector<char> c2 = chosen; c2[cand] = 0;\n            ll radSum = 0; for (int v = 0; v < N; ++v) if (c2[v]) radSum += 1LL * rad[v] * rad[v];\n            ll cab = cable_cost(c2, nullptr);\n            ll delta = radSum + cab - curTotal;\n            if (delta < bestDelta) {\n                bestDelta = delta; bestRem = cand;\n                nAssign  = std::move(a);\n                nAssignD = std::move(d);\n                nRadius  = std::move(rad);\n                nResByV  = std::move(rbv);\n            }\n        }\n        if (bestRem == -1) break;\n        chosen[bestRem] = 0;\n        assign.swap(nAssign); assignD.swap(nAssignD);\n        radius.swap(nRadius); resByV.swap(nResByV);\n        cableNow = cable_cost(chosen, &edgeNow);\n        if (chrono::duration<double>(chrono::high_resolution_clock::now() - startT).count() > 1.9) break;\n    }\n\n    /* final powers */\n    vector<int> finalP(N, 0);\n    for (int v = 0; v < N; ++v) if (chosen[v]) finalP[v] = radius[v];\n\n    /* output */\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << finalP[i];\n    }\n    cout << '\\n';\n    for (int e = 0; e < M; ++e) {\n        if (e) cout << ' ';\n        cout << int(edgeNow[e]);\n    }\n    cout << '\\n';\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ------------ constants and basic types ---------------- */\nconstexpr int N      = 30;\nconstexpr int LAST   = N - 1;           // deepest tier index\nconstexpr int LIMIT  = 10000;           // hard swap limit\n\nstruct Swap { int x1, y1, x2, y2; };\nusing Board = array<array<int, N>, N>;\n\n/* ------------ coordinate helpers ----------------------- */\ninline bool inside (int x,int y){ return 0<=x && x<N && 0<=y && y<=x; }\ninline bool internal(int x)     { return x < LAST; }\n\ninline int child_x(int px){ return px + 1; }\ninline int child_y(int py,bool right){ return py + (right?1:0); }\n\n/* ======================================================= */\n/*   utility: apply swap list to a copy of the board       */\nBoard replay_board(const Board& src, const vector<Swap>& ops)\n{\n    Board b = src;\n    for (auto &s : ops) swap(b[s.x1][s.y1], b[s.x2][s.y2]);\n    return b;\n}\n\n/*   utility: check heap property                          */\nbool heap_ok(const Board& a)\n{\n    for (int x=0;x<LAST;++x)\n        for (int y=0;y<=x;++y)\n            if (a[x][y] > a[x+1][y] || a[x][y] > a[x+1][y+1])\n                return false;\n    return true;\n}\n\n/* ======================================================= */\n/*   1. classic bottom-up Floyd heapify                    */\nvector<Swap> run_floyd(Board a)\n{\n    vector<Swap> ops; ops.reserve(5000);\n\n    auto sw = [&](int x1,int y1,int x2,int y2){\n        swap(a[x1][y1], a[x2][y2]);\n        ops.push_back({x1,y1,x2,y2});\n    };\n\n    for (int x = LAST - 1; x >= 0 && ops.size() < LIMIT; --x)\n        for (int y = 0; y <= x && ops.size() < LIMIT; ++y)\n        {\n            int cx = x, cy = y;\n            while (cx < LAST)\n            {\n                int lx = cx + 1, ly = cy;\n                int rx = cx + 1, ry = cy + 1;\n                int chx = lx,   chy = ly;\n                if (a[rx][ry] < a[lx][ly]) { chx = rx; chy = ry; }\n                if (a[cx][cy] <= a[chx][chy]) break;\n                sw(cx,cy,chx,chy);\n                cx = chx; cy = chy;\n            }\n        }\n    return ops;\n}\n\n/* ======================================================= */\n/*   2. priority-based edge repair                         */\nstruct Edge { int px, py; bool right; };      // parent coord + side\nstruct PQE  { int diff; Edge e;               // diff = value(parent)-value(child)\n              bool operator<(const PQE& o) const { return diff < o.diff; } };\n\nvector<Swap> run_priority(Board a)\n{\n    vector<Swap> ops; ops.reserve(4000);\n\n    auto sw = [&](int x1,int y1,int x2,int y2){\n        swap(a[x1][y1], a[x2][y2]);\n        ops.push_back({x1,y1,x2,y2});\n    };\n\n    priority_queue<PQE> pq;\n\n    auto add_edge = [&](int px,int py,bool right){\n        if (!internal(px)) return;\n        int cx = child_x(px);\n        int cy = child_y(py,right);\n        if (!inside(cx,cy)) return;\n        int diff = a[px][py] - a[cx][cy];\n        if (diff > 0) pq.push({diff,{px,py,right}});\n    };\n\n    /* initial queue -------------------------------------------------- */\n    for (int x=0;x<LAST;++x)\n        for (int y=0;y<=x;++y){\n            add_edge(x,y,false);\n            add_edge(x,y,true);\n        }\n\n    /* processing loop ------------------------------------------------ */\n    while (!pq.empty() && ops.size() < LIMIT)\n    {\n        auto cur = pq.top(); pq.pop();\n        int px = cur.e.px,  py = cur.e.py;\n        bool right = cur.e.right;\n        int cx = child_x(px);\n        int cy = child_y(py,right);\n\n        if (a[px][py] <= a[cx][cy]) continue;   // stale edge\n\n        sw(px,py,cx,cy);                        // one adjacent swap\n\n        /* affected neighbourhood */\n        add_edge(px,py,false); add_edge(px,py,true);\n        add_edge(cx,cy,false); add_edge(cx,cy,true);\n\n        if (px>0){\n            add_edge(px-1, py,   false);\n            if (py>0) add_edge(px-1, py-1, true);\n        }\n        if (cx>0){\n            add_edge(cx-1, cy,   false);\n            if (cy>0) add_edge(cx-1, cy-1, true);\n        }\n    }\n    return ops;\n}\n\n/* ======================================================= */\n/*   main                                                  */\nint main()\n{\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* read input */\n    Board original{};\n    for (int x=0;x<N;++x)\n        for (int y=0;y<=x;++y)\n            cin >> original[x][y];\n\n    /* generate two candidates */\n    vector<Swap> pri_ops = run_priority(original);\n    bool pri_ok = heap_ok(replay_board(original, pri_ops));\n\n    vector<Swap> flo_ops = run_floyd(original);   // always valid\n\n    /* choose shorter legal sequence */\n    const vector<Swap>* best = &flo_ops;\n    if (pri_ok && pri_ops.size() < flo_ops.size())\n        best = &pri_ops;\n\n    /* output */\n    cout << best->size() << '\\n';\n    for (auto &s : *best)\n        cout << s.x1 << ' ' << s.y1 << ' ' << s.x2 << ' ' << s.y2 << '\\n';\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*-----------------------------------------------------------------*/\nstruct Pos{ int r,c; };\nbool operator==(const Pos&a,const Pos&b){ return a.r==b.r && a.c==b.c; }\n\nconst int DR[4]={-1,1,0,0};\nconst int DC[4]={0,0,-1,1};\n\nusing Grid = vector<vector<int>>;            // -2 obstacle, -1 empty, \u22650 container id\nconstexpr int OBST  = -2;\nconstexpr int EMPTY = -1;\n\n/*-----------------------------------------------------------------*/\ninline bool inside(int r,int c,int D){ return 0<=r && r<D && 0<=c && c<D; }\n\n/* BFS over empty cells -------------------------------------------*/\nvector<Pos> bfs_empty(const Grid& g,const Pos& src,\n                      vector<vector<int>>& dist)\n{\n    int D=g.size();\n    dist.assign(D, vector<int>(D,-1));\n    queue<Pos> q; q.push(src); dist[src.r][src.c]=0;\n    vector<Pos> lst;\n    while(!q.empty()){\n        auto [r,c]=q.front(); q.pop();\n        lst.push_back({r,c});\n        for(int d=0;d<4;++d){\n            int nr=r+DR[d], nc=c+DC[d];\n            if(!inside(nr,nc,D) || g[nr][nc]!=EMPTY || dist[nr][nc]!=-1) continue;\n            dist[nr][nc]=dist[r][c]+1;\n            q.push({nr,nc});\n        }\n    }\n    return lst;\n}\n\n/* keep the empty region connected during placement ---------------*/\nbool safe_to_place(Grid& g,const Pos& p,const Pos& ent,\n                   vector<vector<int>>& buf)\n{\n    g[p.r][p.c]=OBST;                    // temporarily occupied\n    bfs_empty(g,ent,buf);\n    bool ok=true;\n    for(int r=0;r<g.size() && ok;++r)\n        for(int c=0;c<g.size();++c)\n            if(g[r][c]==EMPTY && buf[r][c]==-1){ ok=false; break; }\n    g[p.r][p.c]=EMPTY;\n    return ok;\n}\n\n/* 0-1 BFS (empty cost 0, container cost 1) -----------------------*/\nvoid bfs01(const Grid& g,const Pos& src,\n           vector<vector<int>>& dist)\n{\n    int D=g.size();\n    dist.assign(D, vector<int>(D,INT_MAX));\n    deque<Pos> dq; dq.push_front(src);\n    dist[src.r][src.c]=0;\n\n    auto relax=[&](const Pos& v,const Pos& u,int w){\n        if(dist[v.r][v.c]+w < dist[u.r][u.c]){\n            dist[u.r][u.c]=dist[v.r][v.c]+w;\n            if(w==0) dq.push_front(u); else dq.push_back(u);\n        }\n    };\n\n    while(!dq.empty()){\n        auto v=dq.front(); dq.pop_front();\n        for(int d=0;d<4;++d){\n            int nr=v.r+DR[d], nc=v.c+DC[d];\n            if(!inside(nr,nc,D) || g[nr][nc]==OBST) continue;\n            relax(v,{nr,nc}, g[nr][nc]==EMPTY?0:1);\n        }\n    }\n}\n\n/*-----------------------------------------------------------------*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D,N; if(!(cin>>D>>N)) return 0;\n    const Pos ENTR{0,(D-1)/2};\n\n    Grid g(D, vector<int>(D,EMPTY));\n    for(int i=0;i<N;++i){\n        int r,c; cin>>r>>c; g[r][c]=OBST;\n    }\n    const int K=D*D-1-N;                 // number of containers\n\n    /* static distance from entrance -----------------------------*/\n    vector<vector<int>> distStatic(D, vector<int>(D,-1));\n    {\n        queue<Pos> q; q.push(ENTR);\n        distStatic[ENTR.r][ENTR.c]=0;\n        while(!q.empty()){\n            auto [r,c]=q.front(); q.pop();\n            for(int d=0;d<4;++d){\n                int nr=r+DR[d], nc=c+DC[d];\n                if(!inside(nr,nc,D) || g[nr][nc]==OBST ||\n                   distStatic[nr][nc]!=-1) continue;\n                distStatic[nr][nc]=distStatic[r][c]+1;\n                q.push({nr,nc});\n            }\n        }\n    }\n\n    vector<Pos> idPos(K);\n    vector<vector<int>> buf1,buf2;\n    const double GAMMA = 1.5;\n\n    /* =================== placement ============================*/\n    for(int step=0; step<K; ++step){\n        int id; cin>>id;\n\n        auto reach=bfs_empty(g,ENTR,buf1);\n        reach.erase(remove_if(reach.begin(),reach.end(),\n                     [&](const Pos&p){ return p==ENTR; }), reach.end());\n\n        vector<Pos> safe;\n        for(const auto& p:reach)\n            if(safe_to_place(g,p,ENTR,buf2)) safe.push_back(p);\n        const auto& cand = safe.empty()? reach : safe;\n\n        vector<Pos> cells=cand;\n        sort(cells.begin(),cells.end(),\n             [&](const Pos&a,const Pos&b){\n                 int da=distStatic[a.r][a.c], db=distStatic[b.r][b.c];\n                 return da!=db ? da<db : tie(a.r,a.c)<tie(b.r,b.c);\n             });\n\n        double q = pow( static_cast<double>(id)/(K-1), GAMMA );\n        int idx  = cells.size()==1 ? 0\n                 : int(std::round(q*(cells.size()-1)));\n        idx = std::clamp(idx,0,(int)cells.size()-1);\n\n        Pos chosen=cells[idx];\n        g[chosen.r][chosen.c]=id;\n        idPos[id]=chosen;\n\n        cout<<chosen.r<<\" \"<<chosen.c<<\"\\n\"<<flush;\n    }\n\n    /* =================== retrieval ============================*/\n    vector<char> shipped(K,0);\n    vector<Pos> answer; answer.reserve(K);\n    int nextNeed=0;\n\n    vector<vector<int>> distEntr, distNeed;\n    constexpr int THRESH = 8;            // id gap to prefer bestSmall\n\n    while(answer.size()<K){\n        while(nextNeed<K && shipped[nextNeed]) ++nextNeed;\n        if(nextNeed>=K) break;\n\n        bfs01(g,ENTR,distEntr);\n        int dNeed=distEntr[idPos[nextNeed].r][idPos[nextNeed].c];\n\n        if(dNeed==1){\n            Pos p=idPos[nextNeed];\n            shipped[nextNeed]=1; g[p.r][p.c]=EMPTY;\n            answer.push_back(p);\n            ++nextNeed;\n            continue;\n        }\n\n        int bestSmall=INT_MAX; Pos bestSmallPos{-1,-1};\n        int bestBlk  =INT_MAX; Pos bestBlkPos  {-1,-1};\n\n        bfs01(g,idPos[nextNeed],distNeed);\n\n        for(int r=0;r<D;++r)for(int c=0;c<D;++c)\n            if(g[r][c]>=0 && !shipped[g[r][c]]){\n                if(distEntr[r][c]==1 && g[r][c]<bestSmall){\n                    bestSmall=g[r][c]; bestSmallPos={r,c};\n                }\n                if(distEntr[r][c]==1 && distNeed[r][c]==dNeed-1 &&\n                   g[r][c]<bestBlk){\n                    bestBlk=g[r][c]; bestBlkPos={r,c};\n                }\n            }\n\n        int shipId; Pos shipPos;\n        if(bestSmall<bestBlk && bestBlk-bestSmall>THRESH){\n            shipId=bestSmall; shipPos=bestSmallPos;\n        }else{\n            shipId=bestBlk;   shipPos=bestBlkPos;\n        }\n\n        shipped[shipId]=1; g[shipPos.r][shipPos.c]=EMPTY;\n        answer.push_back(shipPos);\n        if(shipId==nextNeed) ++nextNeed;\n    }\n\n    for(const auto& p:answer) cout<<p.r<<\" \"<<p.c<<\"\\n\";\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 50;     // fixed\nconstexpr int M = 100;\nconst int DX[4] = {-1, 1, 0, 0};\nconst int DY[4] = {0, 0, -1, 1};\n\nstruct State {\n    int  g[N][N];                 // current grid\n    int  cnt[M + 1]{};            // remaining cells per colour\n    int  adj[M + 1][M + 1]{};     // unordered edge counts, 0-based\n    bool orig0Adj[M + 1]{};       // was (0,c) adjacent in the input?\n    bool inQ[N][N]{};             // helper for the flood queue\n} st;\n\n/* --------------------------------------------------------------- */\ninline bool inside(int x, int y) { return 0 <= x && x < N && 0 <= y && y < N; }\n\ninline void addEdge(int a, int b, int delta) {\n    if (a > b) swap(a, b);\n    st.adj[a][b] += delta;\n#ifdef DEBUG\n    if (st.adj[a][b] < 0) cerr << \"negative edge \" << a << ' ' << b << '\\n';\n#endif\n}\n\n/* ------------ input & initial edge counters -------------------- */\nvoid buildInitial() {\n    int n, m;  cin >> n >> m;           // 50 / 100\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            cin >> st.g[i][j];\n            ++st.cnt[ st.g[i][j] ];\n        }\n\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j) {\n            int c = st.g[i][j];\n            int d = (j + 1 < N) ? st.g[i][j + 1] : 0;\n            if (c != d) addEdge(c, d, +1);\n            d = (i + 1 < N) ? st.g[i + 1][j] : 0;\n            if (c != d) addEdge(c, d, +1);\n        }\n\n    for (int c = 1; c <= M; ++c) st.orig0Adj[c] = st.adj[0][c] > 0;\n}\n\n/* ---------------- connectivity of one colour ------------------- */\nbool connectedAfterRemoval(int x, int y, int col) {\n    bool vis[N][N] = {};\n    queue<pair<int,int>> q;\n    for (int i = 0; i < N && q.empty(); ++i)\n        for (int j = 0; j < N; ++j)\n            if (st.g[i][j] == col && !(i == x && j == y)) {\n                q.emplace(i, j); vis[i][j] = true;\n                break;\n            }\n\n    int need = st.cnt[col] - 1, got = 0;\n    while (!q.empty()) {\n        auto [cx, cy] = q.front(); q.pop();\n        if (++got == need) return true;\n        for (int d = 0; d < 4; ++d) {\n            int nx = cx + DX[d], ny = cy + DY[d];\n            if (!inside(nx, ny) || vis[nx][ny] || (nx == x && ny == y)) continue;\n            if (st.g[nx][ny] == col) { vis[nx][ny] = true; q.emplace(nx, ny); }\n        }\n    }\n    return false;\n}\n\n/* ---------------- attempt to turn (x,y) into 0 ------------------ */\nbool tryRemove(int x, int y) {\n    int c = st.g[x][y];\n    if (c == 0 || st.cnt[c] == 1) return false;\n\n    int freq[M + 1] = {};               // how many sides to each neighbour colour\n    for (int d = 0; d < 4; ++d) {\n        int nx = x + DX[d], ny = y + DY[d];\n        int col = inside(nx, ny) ? st.g[nx][ny] : 0;\n        ++freq[col];\n    }\n\n    /* --- cheap legality tests ----------------------------------- */\n    for (int d = 1; d <= M; ++d) {\n        if (d == c || freq[d] == 0) continue;\n\n        if (!st.orig0Adj[d]) return false;                      // new 0-d edge forbidden\n\n        int a = min(c, d), b = max(c, d);\n        if (st.adj[a][b] - freq[d] <= 0) return false;         // last (c,d) edge gone\n    }\n    if (!connectedAfterRemoval(x, y, c)) return false;\n\n    /* --- update edge counters ----------------------------------- */\n    int f0   = freq[0];\n    int fSame= freq[c];\n\n    if (f0   ) addEdge(0, c, -f0);        // c \u2013 0 edges disappear\n    if (fSame) addEdge(0, c, +fSame);     // new 0 \u2013 c edges where neighbour is c\n\n    for (int d = 1; d <= M; ++d) if (d != c && freq[d]) {\n        addEdge(c, d, -freq[d]);          // erase (c,d)\n        addEdge(0, d, +freq[d]);          // add (0,d)\n    }\n\n    /* --- materialise the deletion ------------------------------- */\n    st.g[x][y] = 0;\n    --st.cnt[c];\n    return true;\n}\n\n/* ---------------- flood-queue driver ---------------------------- */\ninline bool touchesZero(int i, int j) {\n    if (st.g[i][j] == 0) return false;\n    for (int d = 0; d < 4; ++d) {\n        int ni = i + DX[d], nj = j + DY[d];\n        if (!inside(ni, nj) || st.g[ni][nj] == 0) return true;\n    }\n    return false;\n}\n\nvoid flood() {\n    queue<pair<int,int>> q;\n    for (int i = 0; i < N; ++i)\n        for (int j = 0; j < N; ++j)\n            if (touchesZero(i, j)) { q.emplace(i, j); st.inQ[i][j] = true; }\n\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        st.inQ[x][y] = false;\n        if (st.g[x][y] == 0 || !touchesZero(x, y)) continue;\n\n        if (tryRemove(x, y)) {\n            for (int d = 0; d < 4; ++d) {\n                int nx = x + DX[d], ny = y + DY[d];\n                if (!inside(nx, ny) || st.g[nx][ny] == 0 || st.inQ[nx][ny]) continue;\n                if (touchesZero(nx, ny)) { q.emplace(nx, ny); st.inQ[nx][ny] = true; }\n            }\n        }\n    }\n}\n\n/* ---------------- main ------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    buildInitial();\n    flood();\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (j) cout << ' ';\n            cout << st.g[i][j];\n        }\n        cout << '\\n';\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------- very small RNG (xorshift-64) ---------- */\nstruct FastRNG {\n    uint64_t x;\n    FastRNG()\n        : x(chrono::steady_clock::now().time_since_epoch().count()) {}\n    uint32_t next() {          // 32-bit output is enough\n        x ^= x << 7;\n        x ^= x >> 9;\n        return static_cast<uint32_t>(x);\n    }\n    template<class It> void shuffle(It first, It last) {\n        for (auto n = last - first; n > 1; --n) {\n            auto j = next() % n;\n            swap(*(first + n - 1), *(first + j));\n        }\n    }\n};\n\n/* ---------- tiny Elo helper ----------------------- */\nstruct Elo {\n    vector<double> r;\n    static constexpr double K = 1.6;      // learning-rate\n    Elo(int n) : r(n, 0.0) {}\n    void update(int a, int b, bool aWins) {\n        double ra = r[a], rb = r[b];\n        double p  = 1.0 / (1.0 + exp(rb - ra));   // P(a beats b)\n        double d  = K * ((aWins ? 1.0 : 0.0) - p);\n        r[a] += d;  r[b] -= d;\n    }\n};\n\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    Elo      elo(N);\n    FastRNG  rng;\n\n    /* ---------- prepare list of all unordered pairs ---------- */\n    vector<pair<int,int>> pairs;\n    pairs.reserve(N*(N-1)/2);\n    for (int i = 0; i < N; ++i)\n        for (int j = i+1; j < N; ++j)\n            pairs.emplace_back(i, j);\n    rng.shuffle(pairs.begin(), pairs.end());\n\n    int    used = 0;\n    size_t idx  = 0;\n\n    auto ask = [&](int a, int b) {\n        cout << 1 << ' ' << 1 << ' ' << a << ' ' << b << '\\n' << flush;\n        string res;  cin >> res;\n        ++used;\n        if      (res == \">\") elo.update(a, b, true);\n        else if (res == \"<\") elo.update(a, b, false);\n    };\n\n    /* ---------- issue all Q queries -------------------------- */\n    while (used < Q) {\n        int a, b;\n        if (idx < pairs.size()) {\n            tie(a,b) = pairs[idx++];\n        } else {\n            a = rng.next() % N;\n            do b = rng.next() % N; while (b == a);\n        }\n        ask(a, b);\n    }\n\n    /* ---------- derive positive weights from Elo ------------- */\n    double mn = *min_element(elo.r.begin(), elo.r.end());\n    vector<double> w(N);\n    for (int i = 0; i < N; ++i) w[i] = (elo.r[i] - mn) + 1e-3;\n\n    /* ---------- greedy Largest-First construction ------------ */\n    struct Bag { double sum = 0.0; };\n    vector<Bag> bags(D);\n    vector<int> belong(N);\n\n    vector<int> order(N); iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(),\n         [&](int a,int b){ return w[a] > w[b]; });\n\n    for (int id : order) {\n        int best = 0;\n        for (int d = 1; d < D; ++d)\n            if (bags[d].sum < bags[best].sum)\n                best = d;\n        bags[best].sum += w[id];\n        belong[id]      = best;\n    }\n\n    /* ---------- local search: single moves + swaps ----------- */\n    auto obj = [&]() {\n        double v = 0.0;\n        for (auto &b : bags) v += b.sum * b.sum;\n        return v;\n    };\n    double bestScore = obj();\n    bool   improved  = true;\n    int    guard     = 0;\n\n    const int MAX_LOOP = 5000;\n\n    while (improved && guard++ < MAX_LOOP) {\n        improved = false;\n\n        /* ---- single-item moves ---- */\n        for (int i = 0; i < N; ++i) {\n            int    a  = belong[i];\n            double wi = w[i], sa = bags[a].sum;\n            double base = bestScore - sa * sa;\n\n            for (int b = 0; b < D; ++b) if (b != a) {\n                double sb = bags[b].sum;\n                double newScore = base - sb * sb\n                                  + (sa - wi) * (sa - wi)\n                                  + (sb + wi) * (sb + wi);\n                if (newScore + 1e-9 < bestScore) {\n                    bags[a].sum -= wi;\n                    bags[b].sum += wi;\n                    belong[i]    = b;\n                    bestScore    = newScore;\n                    improved     = true;\n                    goto next_outer;\n                }\n            }\n        }\n\n        /* ---- pair swaps (cheap for N \u2264 100) ---- */\n        for (int i = 0; i < N; ++i) for (int j = i+1; j < N; ++j)\n            if (belong[i] != belong[j]) {\n                int    a  = belong[i], b = belong[j];\n                double wi = w[i], wj = w[j];\n                double sa = bags[a].sum, sb = bags[b].sum;\n\n                double base    = bestScore - sa*sa - sb*sb;\n                double newSa   = sa - wi + wj;\n                double newSb   = sb - wj + wi;\n                double newScore = base + newSa*newSa + newSb*newSb;\n\n                if (newScore + 1e-9 < bestScore) {\n                    swap(belong[i], belong[j]);\n                    bags[a].sum = newSa;\n                    bags[b].sum = newSb;\n                    bestScore   = newScore;\n                    improved    = true;\n                    goto next_outer;\n                }\n            }\n        next_outer:;\n    }\n\n    /* ---------- output final assignment ---------------------- */\n    for (int i = 0; i < N; ++i) {\n        if (i) cout << ' ';\n        cout << belong[i];\n    }\n    cout << '\\n' << flush;\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** fixed parameters *****************************************************/\nusing  u8  = std::uint8_t;\nusing  pii = std::pair<int,int>;\n\nconstexpr int N       = 200;          // boxes\nconstexpr int M       = 10;           // stacks\nconstexpr int H0      = N / M;        // 20\nconstexpr int MAXH    = N;            // 200\nconstexpr int MAX_OPS = 400;          // 2 per box\n\nstruct Sol {\n    int                 energy = INT_MAX;\n    array<pii,MAX_OPS>  ops{};\n    int                 opCnt = 0;\n};\n\n/*** ------------------------------------------------------------------ ***/\n/*** fast greedy run                                                    ***/\nSol greedySolver(const array<array<u8,H0>,M>& init,\n                 std::mt19937& rng, int Ptop, int Wsize, bool rndTie)\n{\n    auto rnd3 = [&](){ return std::uniform_int_distribution<int>(0,3)(rng); };\n\n    array<vector<u8>,M> st;\n    for (int i=0;i<M;++i) st[i].assign(init[i].begin(), init[i].end());\n\n    Sol sol; sol.energy = 0; int op = 0;\n\n    for (int v=1; v<=N; ++v){\n        int s=-1, idx=-1;\n        for (int i=0;i<M && s==-1;++i)\n            for (int j=0;j<(int)st[i].size();++j)\n                if (st[i][j]==v){ s=i; idx=j; break; }\n\n        if (idx==(int)st[s].size()-1){          // already on top\n            sol.ops[op++] = {v,0};\n            st[s].pop_back();\n            continue;\n        }\n\n        vector<u8> seg(st[s].begin()+idx+1, st[s].end());\n        int segSz  = (int)seg.size();\n        int segCos = segSz + 1;\n        int segMax = *max_element(seg.begin(), seg.end());\n        st[s].resize(idx+1);\n\n        int bestSc = INT_MAX, dest = -1;\n        for (int t=0;t<M;++t) if (t!=s){\n            int bp = 0;\n            for (u8 y:seg) for (u8 x:st[t]) if (y>x) ++bp;\n\n            int sc = bp*segCos;\n            if (!st[t].empty() && st[t].back()<segMax) sc += segCos*Ptop;\n            sc += (int)st[t].size()*Wsize;\n            if (rndTie) sc += rnd3();\n\n            if (sc<bestSc){ bestSc=sc; dest=t; }\n        }\n\n        st[dest].insert(st[dest].end(), seg.begin(), seg.end());\n        sol.energy += segCos;\n        sol.ops[op++] = {seg.front(), dest+1};\n\n        st[s].pop_back();\n        sol.ops[op++] = {v,0};\n    }\n    sol.opCnt = op;\n    return sol;\n}\n\n/*** ------------------------------------------------------------------ ***/\n/*** beam search                                                        ***/\ninline int adjBad(const array<u8,MAXH>& s,int sz){\n    int c=0; for(int i=1;i<sz;++i) if(s[i-1]<s[i]) ++c; return c;\n}\nstruct State{\n    array<array<u8,MAXH>,M> st{};\n    array<u8,M>             h{};\n    int                     g=0, hval=0;     // g = energy so far\n    array<pii,MAX_OPS>      ops{};\n    int                     opCnt=0;\n    int score(int W)const { return g + W*hval; }\n};\n\nSol beamSolver(const array<array<u8,H0>,M>& init,\n               int heurW,int width,int bestEnergy)\n{\n    State root;\n    for(int i=0;i<M;++i){\n        std::copy(begin(init[i]),end(init[i]),begin(root.st[i]));\n        root.h[i]=H0;\n        root.hval += adjBad(root.st[i],H0);\n    }\n\n    std::vector<State> beam{root}, nxt;\n    nxt.reserve(width*9);\n\n    for(int v=1; v<=N; ++v){\n        nxt.clear();\n        State fallback; bool haveFallback=false;\n\n        for(const State& cur : beam){\n            int s=-1, idx=-1;\n            for(int i=0;i<M && s==-1;++i)\n                for(int j=0;j<cur.h[i];++j)\n                    if(cur.st[i][j]==v){ s=i; idx=j; break; }\n\n            /* branch 1: v already on top */\n            if(idx==cur.h[s]-1){\n                State ch=cur;\n                --ch.h[s];\n                ch.hval -= adjBad(ch.st[s],ch.h[s]+1);\n                ch.hval += adjBad(ch.st[s],ch.h[s]);\n                ch.ops[ch.opCnt++] = {v,0};\n\n                if (ch.g + ch.hval < bestEnergy) nxt.emplace_back(std::move(ch));\n                else if(!haveFallback){ fallback=std::move(ch); haveFallback=true; }\n                continue;\n            }\n\n            /* branch 2: need to move segment above v */\n            int segSz = cur.h[s]-idx-1;\n            array<u8,MAXH> seg{};\n            for(int k=0;k<segSz;++k) seg[k] = cur.st[s][idx+1+k];\n            u8 front = seg[0];\n\n            for(int d=0; d<M; ++d) if(d!=s){\n                State ch = cur;\n\n                /* detach */\n                ch.hval -= adjBad(ch.st[s],ch.h[s]);\n                ch.h[s]  = idx+1;\n                ch.hval += adjBad(ch.st[s],ch.h[s]);\n\n                /* attach */\n                ch.hval -= adjBad(ch.st[d],ch.h[d]);\n                int dh = ch.h[d];\n                for(int k=0;k<segSz;++k) ch.st[d][dh+k]=seg[k];\n                ch.h[d]=dh+segSz;\n                ch.hval += adjBad(ch.st[d],ch.h[d]);\n\n                ch.g += segSz+1;\n                ch.ops[ch.opCnt++] = {front,d+1};\n\n                /* carry out v */\n                --ch.h[s];\n                ch.hval -= adjBad(ch.st[s],ch.h[s]+1);\n                ch.hval += adjBad(ch.st[s],ch.h[s]);\n                ch.ops[ch.opCnt++] = {v,0};\n\n                if (ch.g + ch.hval < bestEnergy) nxt.emplace_back(std::move(ch));\n                else if(!haveFallback){ fallback=std::move(ch); haveFallback=true; }\n            }\n        }\n        if(nxt.empty() && haveFallback) nxt.emplace_back(std::move(fallback));\n\n        int keep=min(width,(int)nxt.size());\n        std::nth_element(nxt.begin(),nxt.begin()+keep,nxt.end(),\n                         [=](const State&a,const State&b){ return a.score(heurW)<b.score(heurW);});\n        nxt.resize(keep);\n        beam.swap(nxt);\n    }\n\n    const State* best=&*std::min_element(beam.begin(),beam.end(),\n                       [](const State&a,const State&b){ return a.g<b.g; });\n    Sol sol;\n    sol.energy=best->g;\n    sol.opCnt =best->opCnt;\n    sol.ops   =best->ops;\n    return sol;\n}\n\n/*** ------------------------------------------------------------------ ***/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n,m; if(!(cin>>n>>m)) return 0;\n    array<array<u8,H0>,M> init{};\n    for(int i=0;i<M;++i)\n        for(int j=0;j<H0;++j){ int x; cin>>x; init[i][j]=u8(x); }\n\n    std::mt19937 rng(1234567);\n    auto ms = [](auto d){ return std::chrono::duration_cast<std::chrono::milliseconds>(d).count(); };\n    const auto t0 = std::chrono::steady_clock::now();\n\n    /* deterministic baseline */\n    Sol best = greedySolver(init,rng,18,1,false);\n\n    /* 0 \u2013 200 ms : many cheap greedy variants */\n    while (ms(std::chrono::steady_clock::now()-t0) < 200){\n        int P  = std::uniform_int_distribution<int>(12,30)(rng);\n        int Ws = std::uniform_int_distribution<int>(0,4)(rng);\n        Sol cand = greedySolver(init,rng,P,Ws,true);\n        if(cand.energy<best.energy) best = std::move(cand);\n    }\n\n    /* beam search runs (widest first) until 1 600 ms */\n    const std::vector<int> widths = {220,200,180,160,140,120};\n    const std::vector<int> wHeur  = {2,3,4,5,6};\n    size_t wi=0, hi=0;\n\n    while (ms(std::chrono::steady_clock::now()-t0) < 1600){\n        Sol cand = beamSolver(init, wHeur[hi], widths[wi], best.energy);\n        if(cand.energy < best.energy) best = std::move(cand);\n        wi = (wi+1)%widths.size();\n        hi = (hi+1)%wHeur.size();\n    }\n\n    /* output the best sequence found */\n    for(int i=0;i<best.opCnt;++i)\n        cout << best.ops[i].first << ' ' << best.ops[i].second << '\\n';\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** constants and helpers ***************************************************/\nconst int DX[4] = {0, 1, 0, -1};\nconst int DY[4] = {1, 0, -1, 0};\nconst char DC[4] = {'R', 'D', 'L', 'U'};\n\nstruct Board {\n    int N;\n    vector<string> h;          // wall to down : size N-1, length N\n    vector<string> v;          // wall to right: size N  , length N-1\n    vector<int>     d;         // susceptibility flattened\n    inline bool inside(int x,int y) const { return 0<=x && x<N && 0<=y && y<N; }\n    inline bool canMove(int x,int y,int dir) const {\n        if(dir==0) return y+1<N && v[x][y]=='0';\n        if(dir==1) return x+1<N && h[x][y]=='0';\n        if(dir==2) return y-1>=0 && v[x][y-1]=='0';\n        return            x-1>=0 && h[x-1][y]=='0';\n    }\n} B;\n\n/*** data for optimisation ***************************************************/\nint N, LIM = 100000;\n\nvector<int> bounceDir;         // favourite neighbour of each cell\nvector<int> bounceTo;          // its index\nvector<int> loopsNeeded;       // how many extra loops finally allocated\n\nstring basePath;               // Euler tour without extra loops\nstring answer;                 // final route\n\n/*** building the Euler tour *************************************************/\nvector<vector<int>> visited;\nvoid dfsEuler(int x,int y)\n{\n    visited[x][y]=1;\n    for(int dir=0;dir<4;dir++){\n        int nx=x+DX[dir], ny=y+DY[dir];\n        if(!B.inside(nx,ny) || visited[nx][ny]) continue;\n        if(!B.canMove(x,y,dir)) continue;\n        basePath.push_back(DC[dir]);\n        dfsEuler(nx,ny);\n        basePath.push_back(DC[(dir+2)%4]);\n    }\n}\n\n/*** simulate any given path to count visits *********************************/\nvector<int> countVisits(const string& p)\n{\n    vector<int> v(N*N,0);\n    int x=0,y=0;\n    for(char c:p){\n        int dir = (c=='R'?0:c=='D'?1:c=='L'?2:3);\n        x += DX[dir]; y += DY[dir];\n        v[x*N+y]++;\n    }\n    return v;\n}\n\n/*** choose bounce neighbour (highest d) *************************************/\nvoid prepareBounce()\n{\n    bounceDir.assign(N*N,0);\n    bounceTo .assign(N*N,0);\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++){\n        int bestDir=-1, bestD=-1;\n        for(int dir=0;dir<4;dir++){\n            if(!B.canMove(x,y,dir)) continue;\n            int nx=x+DX[dir], ny=y+DY[dir];\n            int nd = B.d[nx*N+ny];\n            if(nd>bestD){ bestD=nd; bestDir=dir; }\n        }\n        bounceDir[x*N+y]=bestDir;\n        bounceTo [x*N+y]=(x+DX[bestDir])*N + (y+DY[bestDir]);\n    }\n}\n\n/*** greedy allocation of useful loops ***************************************/\nvoid allocateLoops(vector<int>& visit)\n{\n    loopsNeeded.assign(N*N,0);\n    long long L = (long long)basePath.size();             // current length\n    double R = 0;                                         // \u03a3 d / v\n    for(int i=0;i<N*N;i++) R += (double)B.d[i] / visit[i];\n\n    using Node = pair<double,int>;                        // (benefit, id)\n    priority_queue<Node> pq;\n    for(int i=0;i<N*N;i++){\n        int j=bounceTo[i];\n        double benefit = (double)B.d[i]/(visit[i]*(visit[i]+1))\n                       + (double)B.d[j]/(visit[j]*(visit[j]+1));\n        pq.emplace(benefit,i);\n    }\n\n    while(L+2 <= LIM){\n        double threshold = 2.0 * R / (L+2);               // need benefit > thresh\n        auto [benefit,id] = pq.top(); pq.pop();\n        int i=id, j=bounceTo[i];\n        // recompute real current benefit\n        benefit = (double)B.d[i]/(visit[i]*(visit[i]+1))\n                + (double)B.d[j]/(visit[j]*(visit[j]+1));\n        if(benefit < threshold - 1e-12){                  // no further improvement\n            break;\n        }\n        /* perform the loop */\n        loopsNeeded[i]++;  L += 2;\n        R -= (double)B.d[i]/visit[i] - (double)B.d[i]/(visit[i]+1);\n        R -= (double)B.d[j]/visit[j] - (double)B.d[j]/(visit[j]+1);\n        visit[i]++;  visit[j]++;\n\n        /* push updated entries (lazy) */\n        double newBenefitI = (double)B.d[i]/(visit[i]*(visit[i]+1))\n                           + (double)B.d[j]/(visit[j]*(visit[j]+1));\n        pq.emplace(newBenefitI,i);\n        double newBenefitJ = (double)B.d[j]/(visit[j]*(visit[j]+1))\n                           + (double)B.d[bounceTo[j]]/(visit[bounceTo[j]]*(visit[bounceTo[j]]+1));\n        pq.emplace(newBenefitJ,j);\n    }\n}\n\n/*** produce the final route **************************************************/\nvector<int> loopsRemain;\nstring outPath;\nint curX=0,curY=0;\n\nvoid emitMove(int dir)\n{\n    outPath.push_back(DC[dir]);\n    curX += DX[dir]; curY += DY[dir];\n}\n\nvoid emitBounce(int id)            // perform ONE back-and-forth loop\n{\n    int dir = bounceDir[id];\n    emitMove(dir);\n    emitMove((dir+2)%4);\n}\n\nvoid maybeBounce(int id)           // at most one loop here\n{\n    if(loopsRemain[id]>0){\n        loopsRemain[id]--;\n        emitBounce(id);\n    }\n}\n\nvector<vector<int>> vis2;\nvoid dfsFinal(int x,int y)\n{\n    int id = x*N+y;\n    vis2[x][y]=1;\n    maybeBounce(id);\n    for(int dir=0;dir<4;dir++){\n        int nx=x+DX[dir], ny=y+DY[dir];\n        if(!B.inside(nx,ny) || vis2[nx][ny]) continue;\n        if(!B.canMove(x,y,dir)) continue;\n        emitMove(dir);\n        dfsFinal(nx,ny);\n        emitMove((dir+2)%4);\n        maybeBounce(id);\n    }\n    while(loopsRemain[id]>0) {     // finish leftovers, very small number\n        loopsRemain[id]--;\n        emitBounce(id);\n    }\n}\n\n/*** main ********************************************************************/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* input */\n    cin>>N;  B.N=N;\n    B.h.resize(N-1); for(int i=0;i<N-1;i++) cin>>B.h[i];\n    B.v.resize(N);   for(int i=0;i<N;i++)   cin>>B.v[i];\n    B.d.resize(N*N);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) cin>>B.d[i*N+j];\n\n    /* step 1: base Euler tour */\n    visited.assign(N,vector<int>(N,0));\n    dfsEuler(0,0);\n\n    /* step 2: initial visits & bounce neighbour */\n    vector<int> visit = countVisits(basePath);        // size N*N\n    prepareBounce();\n\n    /* step 3: greedy extra loops only while useful */\n    allocateLoops(visit);\n\n    /* step 4: build the final route */\n    loopsRemain = loopsNeeded;\n    vis2.assign(N,vector<int>(N,0));\n    dfsFinal(0,0);\n\n    /* output */\n    cout << outPath << '\\n';\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*---------------------------------------------------------------*/\nstruct Pos{int r,c;};\ninline int manhattan(const Pos&a,const Pos&b){\n    return abs(a.r-b.r)+abs(a.c-b.c);\n}\n\n/*----------------  helper for sentinel edges  ------------------*/\nstruct EdgeCost{\n    const vector<int>& start;           // startCost\n    const int (*e)[200];                // edge[i][j]\n    int operator()(int prev,int nxt)const{\n        if(nxt==-2) return 0;           // end\n        if(prev==-1) return start[nxt]; // start\n        return e[prev][nxt];\n    }\n};\n\n/*================================================================*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /*----------------  read input  ------------------------------*/\n    int N,M;           // N=15, M=200\n    if(!(cin>>N>>M)) return 0;\n    int si,sj; cin>>si>>sj;\n    vector<string> G(N);\n    for(int i=0;i<N;++i) cin>>G[i];\n    vector<string> w(M);               // lucky words\n    for(int i=0;i<M;++i) cin>>w[i];\n\n    /*----------------  letter positions ------------------------*/\n    array<vector<Pos>,26> at;\n    for(int r=0;r<N;++r)\n        for(int c=0;c<N;++c)\n            at[G[r][c]-'A'].push_back({r,c});\n\n    /*----------------  letter\u2012letter distance ------------------*/\n    int dChr[26][26];\n    for(int a=0;a<26;++a)\n        for(int b=0;b<26;++b){\n            int best=1e9;\n            for(auto &p:at[a])\n                for(auto &q:at[b])\n                    best=min(best,manhattan(p,q));\n            dChr[a][b]=best;\n        }\n    /* distance from start square to first letter */\n    int dStart[26];\n    for(int a=0;a<26;++a){\n        int best=1e9;\n        for(auto &p:at[a])\n            best=min(best,abs(p.r-si)+abs(p.c-sj));\n        dStart[a]=best;\n    }\n\n    /*----------------  per-word information --------------------*/\n    vector<int> fst(M),lst(M);\n    for(int i=0;i<M;++i){\n        fst[i]=w[i][0]-'A';\n        lst[i]=w[i][4]-'A';\n    }\n\n    /* overlap length & edge cost (travel + new keys) */\n    static uint8_t ov[200][200];\n    static int     edge[200][200];\n    for(int i=0;i<M;++i)\n        for(int j=0;j<M;++j){\n            int best=0;\n            for(int l=4;l>=1;--l)\n                if(equal(w[i].end()-l,w[i].end(),w[j].begin())){\n                    best=l; break;\n                }\n            ov[i][j]=best;\n            int nxtLetter=w[j][best]-'A';               // first *new* letter\n            edge[i][j]=dChr[lst[i]][nxtLetter]+(5-best);\n        }\n    vector<int> startC(M);\n    for(int i=0;i<M;++i) startC[i]=dStart[fst[i]]+5;\n\n    EdgeCost E{startC,edge};\n\n    /*----------------  greedy initial permutation --------------*/\n    vector<int> ord; ord.reserve(M);\n    vector<char> used(M,0);\n    int cur=-1;\n    while((int)ord.size()<M){\n        int best=-1,bestVal=1e9;\n        for(int i=0;i<M;++i) if(!used[i]){\n            int v=E(cur,i);\n            if(v<bestVal){bestVal=v;best=i;}\n        }\n        ord.push_back(best); used[best]=1; cur=best;\n    }\n\n    /*----------------  helper: tour cost  ----------------------*/\n    auto tourCost=[&](const vector<int>&v){\n        int c=E(-1,v[0]);\n        for(int i=1;i<M;++i) c+=E(v[i-1],v[i]);\n        return c;\n    };\n    int curCost=tourCost(ord), bestCost=curCost;\n    vector<int> bestOrd=ord;\n\n    /*----------------  \u0394-cost helpers  -------------------------*/\n    auto swapDelta=[&](const vector<int>& v,int a,int b)->int{\n        if(a>b) swap(a,b);\n        int preA = (a==0)? -1 : v[a-1];\n        int nxtA = (a+1<M)? v[a+1]: -2;\n        int preB = (b==0)? -1 : v[b-1];\n        int nxtB = (b+1<M)? v[b+1]: -2;\n        int A=v[a], B=v[b];\n\n        if(a+1==b){          // adjacent\n            int old = E(preA,A)+E(A,B)+E(B,nxtB);\n            int neu = E(preA,B)+E(B,A)+E(A,nxtB);\n            return neu-old;\n        }else{\n            int old = E(preA,A)+E(A,nxtA)+E(preB,B)+E(B,nxtB);\n            int neu = E(preA,B)+E(B,nxtA)+E(preB,A)+E(A,nxtB);\n            return neu-old;\n        }\n    };\n\n    auto insertDelta=[&](const vector<int>&v,int from,int to)->int{\n        // remove position 'from', insert AFTER position 'to'\n        if(from==to || from==to+1) return 0; // no real move\n        int preF = (from==0)? -1 : v[from-1];\n        int nxtF = (from+1<M)? v[from+1]: -2;\n        int node = v[from];\n\n        int dst = v[ to + (from<to?0: (from>to?0:0)) ]; // original index of dest node\n        int nxtD = ( (from<to? to+1 : to+1) < M ) ? v[to+1] : -2;\n        if(from<to){ nxtD = (to+1<M)? v[to+1] : -2; }\n        else        { nxtD = (to+1<M)? v[to+1] : -2; }\n\n        int old = E(preF,node)+E(node,nxtF)+E(dst,nxtD);\n        int neu = E(preF,nxtF)+E(dst,node)+E(node,nxtD);\n        return neu-old;\n    };\n\n    /*----------------  Simulated Annealing  --------------------*/\n    std::mt19937 rng((uint32_t)\n        chrono::steady_clock::now().time_since_epoch().count());\n    const double T0=3000.0, Tend=1e-3, TIME=1.9;\n    auto t0=chrono::steady_clock::now();\n    uniform_real_distribution<double> R01(0.0,1.0);\n\n    while( chrono::duration<double>(chrono::steady_clock::now()-t0).count() < TIME){\n        double prog = chrono::duration<double>(chrono::steady_clock::now()-t0).count()/TIME;\n        double temp = T0*pow(Tend/T0,prog);\n\n        if(rng()&1){                              /* swap */\n            int a = rng()%M, b = rng()%M;\n            if(a==b) continue;\n            int d = swapDelta(ord,a,b);\n            if(d<0 || R01(rng) < exp(-d/temp)){\n                curCost += d;\n                swap(ord[a],ord[b]);\n                if(curCost<bestCost){bestCost=curCost;bestOrd=ord;}\n            }\n        }else{                                    /* insertion */\n            int from = rng()%M, to = rng()%M;\n            if(from==to||from==to+1) continue;\n            int d = insertDelta(ord,from,to);\n            if(d==0) continue;\n            if(d<0 || R01(rng) < exp(-d/temp)){\n                curCost += d;\n                int node = ord[from];\n                ord.erase(ord.begin()+from);\n                if(from<to) --to;\n                ord.insert(ord.begin()+to+1,node);   // after 'to'\n                if(curCost<bestCost){bestCost=curCost;bestOrd=ord;}\n            }\n        }\n    }\n    ord.swap(bestOrd);\n\n    /*----------------  build final string ---------------------*/\n    string S = w[ord[0]];\n    for(int i=1;i<M;++i){\n        int l = ov[ord[i-1]][ord[i]];\n        S += w[ord[i]].substr(l);\n    }\n    const int L = (int)S.size();\n\n    /*----------------  exact DP for finger path ---------------*/\n    const int BIG=1e9;\n    vector<vector<int>> dp(L);\n    vector<vector<uint16_t>> prv(L);\n    vector<int> bestIdx(L);\n\n    /* layer 0 */\n    {\n        int ch=S[0]-'A';\n        int sz=at[ch].size();\n        dp[0].assign(sz,BIG); prv[0].assign(sz,0);\n        for(int k=0;k<sz;++k)\n            dp[0][k]=manhattan({si,sj},at[ch][k])+1;\n        bestIdx[0]=min_element(dp[0].begin(),dp[0].end())-dp[0].begin();\n    }\n    for(int i=1;i<L;++i){\n        int a=S[i-1]-'A', b=S[i]-'A';\n        int szA=at[a].size(), szB=at[b].size();\n        dp[i].assign(szB,BIG); prv[i].assign(szB,0);\n        for(int k=0;k<szB;++k){\n            int best=BIG, bestj=0;\n            for(int j=0;j<szA;++j){\n                int cand=dp[i-1][j]+manhattan(at[a][j],at[b][k])+1;\n                if(cand<best){best=cand;bestj=j;}\n            }\n            dp[i][k]=best; prv[i][k]=bestj;\n        }\n        bestIdx[i]=min_element(dp[i].begin(),dp[i].end())-dp[i].begin();\n    }\n\n    /* back-track */\n    vector<Pos> path(L);\n    int idx=bestIdx.back();\n    for(int i=L-1;i>=0;--i){\n        int ch=S[i]-'A';\n        path[i]=at[ch][idx];\n        if(i) idx=prv[i][idx];\n    }\n\n    /*----------------  output -------------------------------*/\n    for(auto &p:path) cout<<p.r<<' '<<p.c<<'\\n';\n    return 0;\n}","ahc030":"//  AHC030 \u2013 unique solution via placement elimination + DFS\n//  compile: g++ -std=c++20 -O2 -pipe -static -s main.cpp\n//------------------------------------------------------------------\n#include <bits/stdc++.h>\nusing namespace std;\n\nstruct FastIO{ FastIO(){ ios::sync_with_stdio(false); cin.tie(nullptr); }} fio;\n\n//------------------------------------------------------------------\nstruct Placement{ vector<int> cells; };\n\nstruct Field{ vector<Placement> plc; };\n\nint N, M, NN, maxQueries;\ndouble EPS;\n\nvector<Field> fields;\nint queryCnt = 0;\nvector<int> drilled;                 // -1 unknown, >=0 exact v(i,j)\nvector<char> isOil;                  // squares already proven to contain oil\n//------------------------------------------------------------------\ninline void flush(){ cout << '\\n' << flush; }\ninline pair<int,int> id2ij(int id){ return {id / N, id % N}; }\n\nint drill(int id)\n{\n    auto [i,j] = id2ij(id);\n    cout << \"q 1 \" << i << ' ' << j; flush();\n    int v; cin >> v;\n    ++queryCnt;\n    drilled[id] = v;\n    if (v) isOil[id] = 1;\n    return v;\n}\n//------------------------------------------------------------------\nvoid eliminateZero(int id0)\n{\n    for (auto &f : fields) if (f.plc.size() > 1)\n    {\n        vector<Placement> nxt;\n        nxt.reserve(f.plc.size());\n        for (auto &pl : f.plc)\n        {\n            bool hit = false;\n            for (int id : pl.cells) if (id == id0){ hit=true; break; }\n            if (!hit) nxt.push_back(std::move(pl));\n        }\n        if (!nxt.empty()) f.plc.swap(nxt);\n    }\n}\n//------------------------------------------------------------------\n// statistics used for zero-elimination drill suggestion\nstruct Stat{\n    vector<int> cnt;\n    vector<double> logNoOil;\n    explicit Stat(int n): cnt(n), logNoOil(n,0.0){}\n};\nStat makeStat()\n{\n    Stat st(NN);\n    for (const auto &f: fields) if (f.plc.size() > 1)\n    {\n        int S = (int)f.plc.size();\n        double invS = 1.0 / S;\n        vector<int> local(NN,0);\n        for (const auto &pl: f.plc)\n            for (int id: pl.cells) ++local[id];\n\n        for (int id=0; id<NN; ++id) if (local[id])\n        {\n            st.cnt[id] += local[id];\n            double p = local[id]*invS;\n            if (p < 1.0) st.logNoOil[id] += log(1.0 - p);\n            else         st.logNoOil[id] = -1e100;\n        }\n    }\n    return st;\n}\n//------------------------------------------------------------------\n// DFS that enumerates feasible global solutions (stops after 2)\nstruct DFSSolver{\n    const vector<Field> &F;\n    vector<int> posIds, posVal;                 // positive drilled squares\n    vector<vector<char>> someCover;             // field\u2192posIdx   (bool)\n    vector<vector<int>>  plcMask;               // flattened placement\u2192list posIdx\n    vector<int> curCnt, remMax, assign;\n    int solutions=0;\n    vector<int> solA, solB;\n\n    DFSSolver(const vector<Field> &fld, const vector<int> &drilled)\n        : F(fld)\n    {\n        for(int id=0; id<(int)drilled.size(); ++id)\n            if (drilled[id] > 0){ posIds.push_back(id); posVal.push_back(drilled[id]); }\n\n        int P = (int)posIds.size();\n        someCover.assign(M, vector<char>(P,0));\n        plcMask.clear(); plcMask.reserve(8192);\n\n        for (int f=0; f<M; ++f)\n            for (const auto &pl: F[f].plc)\n            {\n                vector<int> mask;\n                for (int id: pl.cells)\n                {\n                    auto it = find(posIds.begin(), posIds.end(), id);\n                    if (it != posIds.end()){\n                        int idx = (int)(it - posIds.begin());\n                        mask.push_back(idx);\n                        someCover[f][idx] = 1;\n                    }\n                }\n                plcMask.push_back(std::move(mask));\n            }\n\n        curCnt.assign(P,0);\n        remMax.assign(P,0);\n        for(int p=0;p<P;++p)\n            for(int f=0;f<M;++f)\n                if (someCover[f][p]) ++remMax[p];\n\n        assign.assign(M,-1);\n    }\n    //--------------------------------------------------------------\n    void dfs(int depth,\n             const vector<int> &order,\n             const vector<int> &offset)\n    {\n        if (solutions>=2) return;\n        if (depth==(int)order.size())\n        {\n            for (int p=0;p<(int)posIds.size();++p)\n                if (curCnt[p]!=posVal[p]) return;\n            if (solutions==0) solA=assign; else solB=assign;\n            ++solutions; return;\n        }\n        int f = order[depth], base = offset[f], K = (int)F[f].plc.size();\n\n        // remove f's potential from remMax\n        for (int p=0;p<(int)posIds.size();++p) if (someCover[f][p]) --remMax[p];\n\n        for (int k=0;k<K && solutions<2;++k)\n        {\n            const auto& mask = plcMask[base+k];\n            bool ok=true;\n            for(int idx:mask)\n                if(curCnt[idx]+1>posVal[idx]){ ok=false; break; }\n            if (!ok) continue;\n\n            for(int idx:mask) ++curCnt[idx];\n            assign[f]=k;\n\n            for(int p=0;p<(int)posIds.size();++p)\n                if(curCnt[p]+remMax[p]<posVal[p]){ ok=false; break; }\n\n            if(ok) dfs(depth+1,order,offset);\n\n            assign[f]=-1;\n            for(int idx:mask) --curCnt[idx];\n        }\n        for (int p=0;p<(int)posIds.size();++p) if (someCover[f][p]) ++remMax[p];\n    }\n    //--------------------------------------------------------------\n    int solve()\n    {\n        if (posIds.empty())\n        {\n            bool uniq=true;\n            for(const auto &f:F) if(f.plc.size()!=1){ uniq=false; break; }\n            if (uniq){ solA.assign(M,0); solutions=1; return 1; }\n            return 2;\n        }\n        vector<int> ord(M); iota(ord.begin(),ord.end(),0);\n        sort(ord.begin(),ord.end(),\n             [&](int a,int b){ return F[a].plc.size()<F[b].plc.size(); });\n        vector<int> off(M);\n        int cur=0;\n        for(int f=0;f<M;++f){ off[f]=cur; cur+=(int)F[f].plc.size(); }\n        dfs(0,ord,off);\n        return min(solutions,2);\n    }\n};\n//------------------------------------------------------------------\nint pickDiscriminatingCell(const vector<int>& sA,\n                           const vector<int>& sB)\n{\n    vector<int> cntA(NN,0), cntB(NN,0);\n    for(int f=0;f<M;++f){\n        for(int id: fields[f].plc[sA[f]].cells) ++cntA[id];\n        for(int id: fields[f].plc[sB[f]].cells) ++cntB[id];\n    }\n    int best=-1, diffMax=0;\n    for(int id=0;id<NN;++id) if(drilled[id]==-1 && cntA[id]!=cntB[id]){\n        int diff=abs(cntA[id]-cntB[id]);\n        if(diff>diffMax){ diffMax=diff; best=id; }\n    }\n    if(best!=-1) return best;\n\n    // counts identical but coverage sets might differ (union)\n    for(int id=0;id<NN;++id)\n        if(drilled[id]==-1 && (cntA[id]>0)!=(cntB[id]>0))\n            return id;\n    return -1;                       // indistinguishable by single square\n}\n//------------------------------------------------------------------\nvoid readInput()\n{\n    cin >> N >> M >> EPS;\n    NN = N*N; maxQueries = 2*NN;\n    fields.resize(M);\n    drilled.assign(NN,-1);\n    isOil.assign(NN,0);\n\n    for(int k=0;k<M;++k)\n    {\n        int d; cin >> d;\n        vector<pair<int,int>> c(d);\n        int hi=0, wi=0;\n        for(int t=0;t<d;++t){\n            cin >> c[t].first >> c[t].second;\n            hi=max(hi,c[t].first); wi=max(wi,c[t].second);\n        }\n        ++hi; ++wi;\n        for(int si=0; si+hi<=N; ++si)\n            for(int sj=0; sj+wi<=N; ++sj)\n            {\n                Placement p; p.cells.reserve(d);\n                for(auto [ci,cj]:c) p.cells.push_back((ci+si)*N + cj+sj);\n                fields[k].plc.push_back(std::move(p));\n            }\n    }\n}\n//------------------------------------------------------------------\nint main()\n{\n    readInput();\n    const int ELIM_LIMIT = min(maxQueries-20, NN);  // 20 margin for later\n\n    // phase A: cheap elimination on v=0\n    while(queryCnt<ELIM_LIMIT)\n    {\n        auto st = makeStat();\n        int best=-1; double score=-1;\n        for(int id=0; id<NN; ++id) if(drilled[id]==-1 && st.cnt[id])\n        {\n            double pNo = exp(st.logNoOil[id]);\n            double sc = st.cnt[id]*pNo;\n            if(sc>score){ score=sc; best=id; }\n        }\n        if(best==-1) break;\n        int v=drill(best);\n        if(v==0) eliminateZero(best);\n    }\n\n    // phase B: iterate with DFS until unique solution obtained\n    while(true)\n    {\n        DFSSolver dfs(fields, drilled);\n        int res = dfs.solve();\n        if(res==0){\n            cerr<<\"Internal inconsistency!\\n\"; return 0;\n        }\n        if(res==1){        // unique \u2013 output and finish\n            vector<char> finalOil(NN,0);\n            for(int f=0;f<M;++f)\n                for(int id: fields[f].plc[dfs.solA[f]].cells)\n                    finalOil[id]=1;\n            for(int id=0;id<NN;++id) if(isOil[id]) finalOil[id]=1;\n\n            vector<int> ans;\n            for(int id=0;id<NN;++id) if(finalOil[id]) ans.push_back(id);\n\n            cout<<\"a \"<<ans.size();\n            for(int id:ans){\n                auto [i,j]=id2ij(id);\n                cout<<' '<<i<<' '<<j;\n            }\n            flush();\n            int judge; cin>>judge;\n            return 0;\n        }\n        // res == 2 : at least two solutions -> try to separate\n        int diff = pickDiscriminatingCell(dfs.solA, dfs.solB);\n        if(diff==-1){\n            // solutions identical w.r.t. every square's count \u21d2 answer safe\n            vector<char> finalOil(NN,0);\n            for(int id: isOil){}           // dummy to silence warnings\n            for(int f=0;f<M;++f)\n                for(int id: fields[f].plc[dfs.solA[f]].cells)\n                    finalOil[id]=1;\n            for(int id=0;id<NN;++id) if(isOil[id]) finalOil[id]=1;\n\n            vector<int> ans;\n            for(int id=0;id<NN;++id) if(finalOil[id]) ans.push_back(id);\n            cout<<\"a \"<<ans.size();\n            for(int id:ans){\n                auto [i,j]=id2ij(id);\n                cout<<' '<<i<<' '<<j;\n            }\n            flush();\n            int judge; cin>>judge;\n            return 0;\n        }\n        int v=drill(diff);\n        if(v==0) eliminateZero(diff);\n        if(queryCnt>=maxQueries) break;   // safety\n    }\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconstexpr int W = 1000;                 // hall size 1000 \u00d7 1000\nstruct Rect { int i0, j0, i1, j1; };    // [top,left) \u2013 [bottom,right)\n\n/*--------------------------------------------------------------*/\n/* 1)  minimal-height shelf (row) packer                         */\n/*--------------------------------------------------------------*/\nbool pack_rowwise(const vector<ll>& a, vector<Rect>& out)\n{\n    const int N = (int)a.size();\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(),\n         [&](int x, int y){ return a[x] > a[y]; });          // big first\n\n    out.assign(N, {0,0,0,0});\n    int y = 0;\n    vector<int> cur = ord, nxt;\n\n    while (!cur.empty()) {\n        int lead = cur.front();\n        int h    = int((a[lead] + W - 1) / W);               // minimal height\n        if (y + h > W) return false;                         // need fallback\n\n        int x = 0;  nxt.clear();\n        for (int id : cur) {\n            int w = int((a[id] + h - 1) / h);                // ceil(a/h)\n            if (x + w <= W) {\n                out[id] = { y, x, y + h, x + w };\n                x += w;\n            } else nxt.push_back(id);\n        }\n        y += h;\n        cur.swap(nxt);\n    }\n    return true;\n}\n\n/*--------------------------------------------------------------*/\n/* 2)  skyline packer                                           */\n/*--------------------------------------------------------------*/\nbool skyline_find(int h, int w, const vector<int>& sky, int& px, int& py)\n{\n    deque<int> dq;\n    for (int i = 0; i < w; ++i) {\n        while (!dq.empty() && sky[dq.back()] <= sky[i]) dq.pop_back();\n        dq.push_back(i);\n    }\n    if (sky[dq.front()] + h <= W) { px = 0; py = sky[dq.front()]; return true; }\n\n    for (int x = 1; x + w <= W; ++x) {\n        if (dq.front() == x - 1) dq.pop_front();\n        int idx = x + w - 1;\n        while (!dq.empty() && sky[dq.back()] <= sky[idx]) dq.pop_back();\n        dq.push_back(idx);\n        if (sky[dq.front()] + h <= W) { px = x; py = sky[dq.front()]; return true; }\n    }\n    return false;\n}\n\nbool skyline_place_one(ll area, vector<int>& sky, Rect& r)\n{\n    int hMin = int((area + W - 1) / W);\n    for (int h = hMin; h <= W; ++h) {\n        int w = int((area + h - 1) / h);                     // ceil(area/h)\n        if (w > W) continue;\n        int x, y;\n        if (skyline_find(h, w, sky, x, y)) {\n            for (int i = x; i < x + w; ++i) sky[i] = y + h;\n            r = { y, x, y + h, x + w };\n            return true;\n        }\n    }\n    return false;\n}\n\nbool pack_skyline(const vector<ll>& a, vector<Rect>& out)\n{\n    const int N = (int)a.size();\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(),\n         [&](int x, int y){ return a[x] > a[y]; });\n\n    vector<int> sky(W, 0);\n    out.assign(N, {0,0,0,0});\n    deque<int> q(ord.begin(), ord.end());\n\n    while (!q.empty()) {\n        bool progress = false;\n        size_t round  = q.size();\n        for (size_t i = 0; i < round; ++i) {\n            int id = q.front(); q.pop_front();\n            Rect r;\n            if (skyline_place_one(a[id], sky, r)) {\n                out[id] = r;\n                progress = true;\n            } else {\n                q.push_back(id);\n            }\n        }\n        if (!progress) return false;      // nothing fitted in this round\n    }\n    return true;\n}\n\n/*--------------------------------------------------------------*/\n/* 3)  guillotine packer                                        */\n/*     (simple 2-D bin packing; empirically always succeeds)    */\n/*--------------------------------------------------------------*/\nstruct Free { int i, j, h, w; };                              // free sub-rect\n\nbool place_in_free(const Free& fr, ll need, Rect& placed)\n{\n    if (1LL * fr.h * fr.w < need) return false;               // not enough area\n\n    /* try both orientations, favouring nearly square shapes */\n    for (int trySwap = 0; trySwap < 2; ++trySwap) {\n        int H = trySwap ? fr.w : fr.h;\n        int Wd= trySwap ? fr.h : fr.w;\n        int bestH = -1, bestW = -1;\n\n        int start = int(std::sqrt((double)need));\n        start = min(start, H);\n        for (int h = start; h >= 1; --h) {\n            int w = int((need + h - 1) / h);\n            if (w <= Wd) { bestH = h; bestW = w; break; }\n        }\n        if (bestH != -1) {\n            if (trySwap) std::swap(bestH, bestW);\n            placed = { fr.i, fr.j, fr.i + bestH, fr.j + bestW };\n            return true;\n        }\n    }\n    return false;\n}\n\nbool pack_guillotine(const vector<ll>& a, vector<Rect>& out)\n{\n    const int N = (int)a.size();\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(),\n         [&](int x, int y){ return a[x] > a[y]; });            // big first\n\n    vector<Free> freeR = { {0, 0, W, W} };\n    out.assign(N, {0,0,0,0});\n\n    for (int id : ord) {\n        bool placed = false;\n        for (size_t f = 0; f < freeR.size() && !placed; ++f) {\n            Rect r;\n            if (!place_in_free(freeR[f], a[id], r)) continue;\n\n            /* split the used free rectangle into up to 2 new ones */\n            Free fr = freeR[f];\n            freeR.erase(freeR.begin() + f);\n\n            int cutH = r.i1 - r.i0;\n            int cutW = r.j1 - r.j0;\n\n            Free right = { fr.i, fr.j + cutW, cutH, fr.w - cutW };\n            Free  down = { fr.i + cutH, fr.j, fr.h - cutH, fr.w };\n\n            if (right.h > 0 && right.w > 0) freeR.push_back(right);\n            if ( down.h > 0 &&  down.w > 0) freeR.push_back(down);\n\n            out[id] = r;\n            placed  = true;\n        }\n        if (!placed) return false;                             // guillotine failed\n    }\n    return true;\n}\n\n/*--------------------------------------------------------------*/\n/* 4)  tiny 10 \u00d7 10 grid fallback (guaranteed, but very fast)   */\n/*--------------------------------------------------------------*/\nbool pack_tiny_grid(const vector<ll>& a, vector<Rect>& out)\n{\n    constexpr int S = 10;                     // cell side\n    constexpr int G = W / S;                  // 100\n    static bool occ[G][G];\n    memset(occ, 0, sizeof(occ));\n\n    const int N = (int)a.size();\n    vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(),\n         [&](int x, int y){ return a[x] > a[y]; });\n\n    out.assign(N, {0,0,0,0});\n    for (int id : ord) {\n        int need = int((a[id] + S * S - 1) / (S * S));        // cells required\n        bool done = false;\n        for (int h = 1; h <= G && !done; ++h) {\n            int wMin = (need + h - 1) / h;\n            if (wMin > G) continue;\n            for (int y = 0; y + h <= G && !done; ++y)\n                for (int x = 0; x + wMin <= G && !done; ++x) {\n                    bool ok = true;\n                    for (int yy = 0; yy < h && ok; ++yy)\n                        for (int xx = 0; xx < wMin; ++xx)\n                            if (occ[y + yy][x + xx]) { ok = false; break; }\n                    if (ok) {\n                        for (int yy = 0; yy < h; ++yy)\n                            memset(&occ[y + yy][x], 1, wMin);\n                        out[id] = { y * S, x * S,\n                                     (y + h) * S, (x + wMin) * S };\n                        done = true;\n                    }\n                }\n        }\n        if (!done) return false;\n    }\n    return true;\n}\n\n/*--------------------------------------------------------------*/\n/* 5)  last resort \u2013 1 \u00d7 1 cells (should never be needed)       */\n/*--------------------------------------------------------------*/\nvoid last_resort(int N, vector<Rect>& out)\n{\n    out.resize(N);\n    for (int k = 0; k < N; ++k) out[k] = { k, 0, k + 1, 1 };\n}\n\n/*--------------------------------------------------------------*/\n/*                           main                               */\n/*--------------------------------------------------------------*/\nint main()\n{\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyW, D, N;\n    if (!(cin >> dummyW >> D >> N)) return 0;\n\n    vector<vector<ll>> A(D, vector<ll>(N));\n    for (int d = 0; d < D; ++d)\n        for (int k = 0; k < N; ++k)\n            cin >> A[d][k];\n\n    vector<Rect> day;\n    for (int d = 0; d < D; ++d) {\n        bool ok = pack_rowwise (A[d], day);\n        if (!ok) ok = pack_skyline (A[d], day);\n        if (!ok) ok = pack_guillotine(A[d], day);\n        if (!ok) ok = pack_tiny_grid(A[d], day);     // practically never used\n        if (!ok) last_resort(N, day);                // absolute safety\n\n        for (const auto& r : day)\n            cout << r.i0 << ' ' << r.j0 << ' ' << r.i1 << ' ' << r.j1 << '\\n';\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\nconstexpr int MOD = 998244353;\nconstexpr int N = 9;\nconstexpr int M = 20;\nconstexpr int K = 81;\n\n/* ------------------------------- RNG ------------------------------------ */\nstruct RNG {\n    uint64_t s;\n    RNG() : s(chrono::steady_clock::now().time_since_epoch().count()) {}\n    uint32_t next() {\n        s ^= s << 13;\n        s ^= s >> 7;\n        s ^= s << 17;\n        return static_cast<uint32_t>(s);\n    }\n    uint32_t next(uint32_t lim) { return next() % lim; }\n    double   uniform()          { return double(next()) / 4294967295.0; }\n} rng;\n\n/* ----------------------------- operation -------------------------------- */\nstruct Op {\n    int m, p, q;     // for the answer\n    int idx[9];      // linear indices of the 9 covered cells\n    int add[9];\n};\n\ninline int64 gain_add(const Op& o, const array<int,81>& b){\n    int64 g = 0;\n    for (int k=0;k<9;++k){\n        int v  = b[o.idx[k]];\n        int nv = v + o.add[k];\n        if (nv >= MOD) nv -= MOD;\n        g += nv - v;\n    }\n    return g;\n}\ninline int64 gain_sub(const Op& o, const array<int,81>& b){\n    int64 g = 0;\n    for (int k=0;k<9;++k){\n        int v  = b[o.idx[k]];\n        int nv = v - o.add[k];\n        if (nv < 0) nv += MOD;\n        g += nv - v;\n    }\n    return g;\n}\ninline void apply_add(const Op& o, array<int,81>& b){\n    for (int k=0;k<9;++k){\n        int& v = b[o.idx[k]];\n        v += o.add[k];\n        if (v >= MOD) v -= MOD;\n    }\n}\ninline void apply_sub(const Op& o, array<int,81>& b){\n    for (int k=0;k<9;++k){\n        int& v = b[o.idx[k]];\n        v -= o.add[k];\n        if (v < 0) v += MOD;\n    }\n}\ninline bool is_safe(const Op& o,const array<int,81>& b){\n    for(int k=0;k<9;++k) if(b[o.idx[k]]+o.add[k]>=MOD) return false;\n    return true;\n}\n\n/* --------------------------- SA parameters ------------------------------ */\nconst double T0 = 1.0e9;\nconst double T1 = 1.0e5;\nconst int    SAMPLE = 4;      // how many random ops are compared when we need one\n\n/* ------------------------------- SA run --------------------------------- */\nstruct State{\n    array<int,81> board;\n    vector<int>   press;   // indices into ops[]\n    int64         score;\n};\n\nvoid simulated_annealing(State &st,\n                         const vector<Op>& ops,\n                         double time_limit){          // seconds\n    const auto time0 = chrono::steady_clock::now();\n    auto sec = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now()-time0).count();\n    };\n    int OPS = (int)ops.size();\n\n    array<int,81> b = st.board;\n    vector<int>   lst = st.press;\n    int64         cur = st.score;\n    int64         best = cur;\n    array<int,81> bestB = b;\n    vector<int>   bestL = lst;\n\n    long long iter = 0;\n    while(sec() < time_limit){\n        ++iter;\n        double t = sec()/time_limit;\n        double Temp = T0 * pow(T1/T0, t);\n\n        int moveType = rng.next(3);              // 0 add, 1 remove, 2 replace\n        if(moveType==0 && (int)lst.size()>=K) moveType=2;\n        if(moveType==1 && lst.empty())          moveType=0;\n        if(moveType==2 && lst.empty())          moveType=0;\n\n        if(moveType==0){          // ADD\n            int bestOp=-1;\n            int64 bestGain = LLONG_MIN;\n            for(int s=0;s<SAMPLE;++s){\n                int oi = rng.next(OPS);\n                int64 g = gain_add(ops[oi],b);\n                if(g>bestGain){bestGain=g;bestOp=oi;}\n            }\n            int64 delta = bestGain;\n            if(delta>=0 || rng.uniform()<exp(delta/Temp)){\n                apply_add(ops[bestOp],b);\n                lst.push_back(bestOp);\n                cur += delta;\n            }\n        }\n        else if(moveType==1){     // REMOVE\n            int id = rng.next((uint32_t)lst.size());\n            int oi = lst[id];\n            int64 delta = gain_sub(ops[oi],b);   // could be positive\n            if(delta>=0 || rng.uniform()<exp(delta/Temp)){\n                apply_sub(ops[oi],b);\n                cur += delta;\n                lst[id] = lst.back(); lst.pop_back();\n            }\n        }\n        else{                     // REPLACE\n            int id = rng.next((uint32_t)lst.size());\n            int oldOp = lst[id];\n\n            int bestOp=-1;\n            int64 bestDelta = LLONG_MIN;\n\n            // sample several candidates, take the best\n            for(int s=0;s<SAMPLE;++s){\n                int cand = rng.next(OPS);\n                if(cand==oldOp) continue;\n                int64 delta = gain_sub(ops[oldOp],b);\n                apply_sub(ops[oldOp],b);\n                delta += gain_add(ops[cand],b);\n                apply_add(ops[oldOp],b);     // rollback\n                if(delta>bestDelta){bestDelta=delta;bestOp=cand;}\n            }\n            if(bestOp<0) continue;\n\n            int64 delta = gain_sub(ops[oldOp],b);\n            apply_sub(ops[oldOp],b);\n            delta += gain_add(ops[bestOp],b);\n            if(delta>=0 || rng.uniform()<exp(delta/Temp)){\n                apply_add(ops[bestOp],b);\n                lst[id] = bestOp;\n                cur += delta;\n            }else{\n                apply_add(ops[oldOp],b);     // rollback\n            }\n        }\n\n        if(cur > best){\n            best = cur;\n            bestB = b;\n            bestL = lst;\n        }\n    }\n    st.board = bestB;\n    st.press = bestL;\n    st.score = best;\n}\n\n/* --------------------------- baseline greedy ---------------------------- */\nState baseline(const vector<Op>& ops){\n    State st;\n    st.board.fill(0);\n    st.score = 0;\n    st.press.clear();\n    /* read original A into board */\n    for(int i=0;i<81;++i){\n        int v; cin>>v; st.board[i]=v;\n        st.score += v;\n    }\n\n    // safe greedy\n    while((int)st.press.size()<K){\n        int best=-1; int64 bestGain=0;\n        for(int i=0;i<(int)ops.size();++i){\n            if(!is_safe(ops[i],st.board)) continue;\n            int64 g = gain_add(ops[i],st.board);\n            if(g>bestGain){bestGain=g;best=i;}\n        }\n        if(best<0||bestGain<=0) break;\n        apply_add(ops[best],st.board);\n        st.press.push_back(best);\n        st.score += bestGain;\n    }\n    // ordinary greedy\n    while((int)st.press.size()<K){\n        int best=-1; int64 bestGain=0;\n        for(int i=0;i<(int)ops.size();++i){\n            int64 g = gain_add(ops[i],st.board);\n            if(g>bestGain){bestGain=g;best=i;}\n        }\n        if(best<0||bestGain<=0) break;\n        apply_add(ops[best],st.board);\n        st.press.push_back(best);\n        st.score += bestGain;\n    }\n    return st;\n}\n\n/* ------------------------------- main ----------------------------------- */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyN,dummyM,dummyK;\n    cin>>dummyN>>dummyM>>dummyK;         // all fixed\n\n    /* read A later inside baseline() because we need it twice */\n    vector<int> firstRow(81);\n    for(int i=0;i<81;++i) cin>>firstRow[i];\n\n    /* read stamps */\n    array<array<int,9>,M> stamp{};\n    for(int m=0;m<M;++m)\n        for(int r=0;r<3;++r)\n            for(int c=0;c<3;++c){\n                int x; cin>>x; stamp[m][r*3+c]=x;\n            }\n\n    /* create all 980 presses */\n    vector<Op> ops; ops.reserve(M*49);\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                Op o; o.m=m; o.p=p; o.q=q;\n                int t=0;\n                for(int dr=0;dr<3;++dr)\n                    for(int dc=0;dc<3;++dc){\n                        o.idx[t]=(p+dr)*N+q+dc;\n                        o.add[t]=stamp[m][t];\n                        ++t;\n                    }\n                ops.push_back(o);\n            }\n\n    const auto global_start = chrono::steady_clock::now();\n    auto elapsed = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now()-global_start).count();\n    };\n\n    /* we need two copies of A because baseline() consumes the stream once   */\n    stringstream ss;\n    for(int v:firstRow) ss<<v<<' ';\n    string remainA = ss.str();\n    cin.seekg(0);                        // rewind\n    cin.clear();\n    cin.ignore(numeric_limits<streamsize>::max(),'\\n'); // skip first line\n    /* baseline run 1 */\n    {\n        for(int v:firstRow) cin>>v;      // dummy read to align the stream\n        cin.ignore(numeric_limits<streamsize>::max(),'\\n'); // stamps already read\n    }\n    /* rebuild input for baseline() */\n    string inputA = remainA;\n    stringstream inA(inputA);\n    /* replace cin buffer with inA for baseline() */\n    cin.rdbuf(inA.rdbuf());\n\n    State bestState = baseline(ops);     // baseline\n    double time_used = elapsed();\n    const double TOTAL = 1.95;           // keep tiny margin\n    const double single_time = 0.35;     // each SA slice\n\n    while(time_used + single_time < TOTAL){\n        State st = bestState;            // start from baseline\n        simulated_annealing(st, ops, single_time);\n        if(st.score > bestState.score) bestState = move(st);\n        time_used = elapsed();\n    }\n\n    /* output -------------------------------------------------------------- */\n    cout<<bestState.press.size()<<\"\\n\";\n    for(int id:bestState.press){\n        const Op& o = ops[id];\n        cout<<o.m<<\" \"<<o.p<<\" \"<<o.q<<\"\\n\";\n    }\n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** fixed parameters *******************************************************/\nconstexpr int N       = 5;                   // grid is 5\u00d75\nconstexpr int COL_IN  = 0;                   // Receiving Gates (column 0)\nconstexpr int COL_OUT = N - 1;               // Dispatch  Gates (column 4)\nconstexpr int EMPTY   = -1;                  // empty cell\n\nstruct Crane {\n    int  r = 0, c = 0;                       // position\n    bool hold = false;\n    int  box  = -1;                          // id of carried container\n};\n\n/* Manhattan distance */\nstatic inline int dist(int r1,int c1,int r2,int c2){\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\n/* one-step helper */\nstatic inline char step(int cur,int dst,char neg,char pos){\n    return (cur < dst ? pos : neg);\n}\n\n/*****************************************************************************/\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---- read input ---------------------------------------------------- */\n    int dummyN;\n    cin >> dummyN;                           // always 5\n    array<array<int, N>, N> seq;             // arrival lists A_{row,j}\n    for (int r = 0; r < N; ++r)\n        for (int j = 0; j < N; ++j) cin >> seq[r][j];\n\n    /* ---- simulation state --------------------------------------------- */\n    array<array<int, N>, N> grid;\n    for (auto &row : grid) row.fill(EMPTY);\n\n    array<int, N> nextIdx{};                 // next to spawn per row\n\n    Crane big;                               // the only working crane\n    vector<string> cmd(N);                   // output lines (5 cranes)\n\n    int dispatched = 0, turn = 0;\n\n    /* =================== main simulation loop ========================== */\n    while (dispatched < N * N && turn < 10000) {\n\n        /* 1. automatic arrivals ---------------------------------------- */\n        for (int r = 0; r < N; ++r) {\n            if (nextIdx[r] == N) continue;                // row finished\n            bool gateBlocked = (big.r == r && big.c == COL_IN); // <-- fixed\n            if (!gateBlocked && grid[r][COL_IN] == EMPTY) {\n                int id = seq[r][nextIdx[r]++];\n                grid[r][COL_IN] = id;\n            }\n        }\n\n        /* 2. decide action for the big crane --------------------------- */\n        char op = '.';\n\n        if (big.hold) {                                   // carrying\n            int destR = big.box / N, destC = COL_OUT;\n            if (big.r == destR && big.c == destC) {\n                op = (grid[destR][destC] == EMPTY ? 'Q' : '.');\n            } else if (big.r != destR)\n                op = step(big.r, destR, 'U', 'D');\n            else\n                op = step(big.c, destC, 'L', 'R');\n        } else {                                          // empty-handed\n            /* nearest container that is not yet at a Dispatch Gate */\n            int bestR = -1, bestC = -1, bestD = INT_MAX;\n            for (int r = 0; r < N; ++r)\n                for (int c = 0; c < N; ++c)\n                    if (grid[r][c] != EMPTY && c != COL_OUT) {\n                        int d = dist(big.r, big.c, r, c);\n                        if (d < bestD) { bestD = d; bestR = r; bestC = c; }\n                    }\n\n            if (bestR == -1) {                            // nothing yet\n                /* avoid blocking further spawns */\n                if (big.c == COL_IN && nextIdx[big.r] < N) op = 'R';\n                else op = '.';\n            } else if (big.r == bestR && big.c == bestC) {\n                op = 'P';\n            } else if (big.r != bestR) {\n                op = step(big.r, bestR, 'U', 'D');\n            } else {\n                op = step(big.c, bestC, 'L', 'R');\n            }\n        }\n\n        /* 3. record commands for all cranes ---------------------------- */\n        cmd[0].push_back(op);\n        for (int i = 1; i < N; ++i)\n            cmd[i].push_back(turn ? '.' : 'B');           // bomb small ones\n\n        /* 4. execute the chosen action -------------------------------- */\n        switch (op) {\n            case 'U': --big.r; break;\n            case 'D': ++big.r; break;\n            case 'L': --big.c; break;\n            case 'R': ++big.c; break;\n            case 'P':\n                big.hold = true;\n                big.box  = grid[big.r][big.c];\n                grid[big.r][big.c] = EMPTY;\n                break;\n            case 'Q':\n                grid[big.r][big.c] = big.box;\n                big.hold = false; big.box = -1;\n                break;\n            default: break;\n        }\n\n        /* 5. automatic dispatch --------------------------------------- */\n        for (int r = 0; r < N; ++r)\n            if (grid[r][COL_OUT] != EMPTY) {\n                grid[r][COL_OUT] = EMPTY;\n                ++dispatched;\n            }\n\n        ++turn;\n    }\n\n    /* ---- pad / trim all lines to identical length \u2264 10 000 ----------- */\n    size_t L = 0;\n    for (auto &s : cmd) L = max(L, s.size());\n    if (L > 10000) L = 10000;\n    for (auto &s : cmd) {\n        if (s.size() < L) s.append(L - s.size(), '.');\n        else if (s.size() > L) s.resize(L);\n    }\n\n    /* ---- output ------------------------------------------------------ */\n    for (const auto &s : cmd) cout << s << '\\n';\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nusing Coord = pair<int,int>;\nconstexpr int N = 20;                       // fixed\n\n/* ------------------------------------------------------------------ */\nvoid move_to(int &r,int &c,int tr,int tc,vector<string>& out){\n    while(r<tr){ out.emplace_back(\"D\"); ++r; }\n    while(r>tr){ out.emplace_back(\"U\"); --r; }\n    while(c<tc){ out.emplace_back(\"R\"); ++c; }\n    while(c>tc){ out.emplace_back(\"L\"); --c; }\n}\n\n/* --------------------- elementary patterns ------------------------ */\nvector<Coord> rowSnake(bool startLR){\n    vector<Coord> p; p.reserve(N*N);\n    for(int r=0;r<N;r++){\n        if((r&1)==(startLR?0:1))\n            for(int c=0;c<N;c++)   p.emplace_back(r,c);\n        else\n            for(int c=N-1;c>=0;--c) p.emplace_back(r,c);\n    }\n    return p;\n}\nvector<Coord> colSnake(bool startTB){\n    vector<Coord> p; p.reserve(N*N);\n    for(int c=0;c<N;c++){\n        if((c&1)==(startTB?0:1))\n            for(int r=0;r<N;r++)   p.emplace_back(r,c);\n        else\n            for(int r=N-1;r>=0;--r) p.emplace_back(r,c);\n    }\n    return p;\n}\nvector<Coord> spiral(bool cw){\n    vector<Coord> p; p.reserve(N*N);\n    int top=0,bot=N-1,l=0,r=N-1;\n    while(top<=bot && l<=r){\n        if(cw){\n            for(int c=l;c<=r;c++) p.emplace_back(top,c); ++top;\n            for(int rr=top;rr<=bot;rr++) p.emplace_back(rr,r); --r;\n            if(top<=bot){ for(int c=r;c>=l;--c) p.emplace_back(bot,c); --bot; }\n            if(l<=r){ for(int rr=bot;rr>=top;--rr) p.emplace_back(rr,l); ++l; }\n        }else{\n            for(int rr=top;rr<=bot;rr++) p.emplace_back(rr,l); ++l;\n            for(int c=l;c<=r;c++) p.emplace_back(bot,c); --bot;\n            if(l<=r){ for(int rr=bot;rr>=top;--rr) p.emplace_back(rr,r); --r; }\n            if(top<=bot){ for(int c=r;c>=l;--c) p.emplace_back(top,c); ++top; }\n        }\n    }\n    return p;\n}\n/* --------------------- band snakes (width k) ---------------------- */\nvector<Coord> rowBand(int k,bool firstLR){\n    vector<Coord> p; p.reserve(N*N);\n    bool dir=firstLR;\n    for(int r=0;r<N;r++){\n        if(dir)\n            for(int c=0;c<N;c++)   p.emplace_back(r,c);\n        else\n            for(int c=N-1;c>=0;--c) p.emplace_back(r,c);\n        if((r+1)%k==0) dir=!dir;                 // toggle every k-th row\n    }\n    return p;\n}\nvector<Coord> colBand(int k,bool firstTB){\n    vector<Coord> p; p.reserve(N*N);\n    bool dir=firstTB;\n    for(int c=0;c<N;c++){\n        if(dir)\n            for(int r=0;r<N;r++)   p.emplace_back(r,c);\n        else\n            for(int r=N-1;r>=0;--r) p.emplace_back(r,c);\n        if((c+1)%k==0) dir=!dir;                 // toggle every k-th column\n    }\n    return p;\n}\n\n/* ------------------- exact evaluation of a walk ------------------- */\nstruct EvalRes{\n    long long cost;          // movement cost without \u03a3|h|\n    int startIdx;\n};\nEvalRes evaluate(const vector<Coord>& path,\n                 const vector<vector<int>>& h)\n{\n    const int M = path.size();                    // 400\n    static long long pref[401];\n    pref[0]=0;\n    for(int i=0;i<M;i++){\n        auto [r,c]=path[i];\n        pref[i+1]=pref[i]+h[r][c];\n    }\n    long long mn=pref[0]; int s=0;\n    for(int i=1;i<=M;i++) if(pref[i]<mn){ mn=pref[i]; s=i; }\n\n    long long load=0, loadDistSum=0, distSum=0;\n    for(int k=0;k<M-1;k++){\n        int idx=(s+k)%M;\n        load += h[path[idx].first][path[idx].second];      // after cell idx\n        int dr = abs(path[idx].first  - path[(idx+1)%M].first);\n        int dc = abs(path[idx].second - path[(idx+1)%M].second);\n        int d  = dr+dc;                                    // Manhattan distance\n        distSum     += d;\n        loadDistSum += load * d;\n    }\n    auto [sr,sc]=path[s];\n    int approach = abs(sr)+abs(sc);                        // empty truck\n    long long total = 100LL*(approach + distSum) + loadDistSum;\n    return {total, s};\n}\n\n/* ------------------------------------------------------------------ */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n; if(!(cin>>n)) return 0;     // n = 20\n    vector<vector<int>> h(N, vector<int>(N));\n    for(auto &row:h) for(int &x:row) cin>>x;\n\n    /* -------- build template walks ------------------------------------- */\n    vector<vector<Coord>> paths;\n    paths.push_back(rowSnake(true));\n    paths.push_back(rowSnake(false));\n    paths.push_back(colSnake(true));\n    paths.push_back(colSnake(false));\n    paths.push_back(spiral(true));\n    paths.push_back(spiral(false));\n\n    for(int k:{2,3,4,5,10}){\n        paths.push_back(rowBand(k,true));\n        paths.push_back(rowBand(k,false));\n        paths.push_back(colBand(k,true));\n        paths.push_back(colBand(k,false));\n    }\n\n    const int baseCnt = paths.size();\n    for(int i=0;i<baseCnt;i++){\n        auto rev = paths[i];\n        reverse(rev.begin(), rev.end());\n        paths.push_back(move(rev));\n    }\n\n    /* -------- choose the cheapest walk --------------------------------- */\n    long long bestCost = (1LL<<62);\n    int bestPid=0, bestStart=0;\n\n    for(int pid=0; pid<(int)paths.size(); ++pid){\n        auto e = evaluate(paths[pid],h);\n        if(e.cost < bestCost){\n            bestCost  = e.cost;\n            bestPid   = pid;\n            bestStart = e.startIdx;\n        }\n    }\n\n    /* -------- emit operations ------------------------------------------ */\n    const auto& path = paths[bestPid];\n    const int M = path.size();\n    const int s = bestStart;\n\n    vector<string> out; out.reserve(1500);\n\n    int r=0,c=0;\n    move_to(r,c,path[s].first,path[s].second,out);     // empty approach\n\n    int load=0;\n    for(int k=0;k<M;k++){\n        int idx = (s+k)%M;\n        auto [cr,cc]=path[idx];\n        int v = h[cr][cc];\n\n        if(v>0){ out.emplace_back(\"+\"+to_string(v)); load+=v; }\n        else if(v<0){ out.emplace_back(\"-\"+to_string(-v)); load+=v; }\n\n        if(k!=M-1){\n            auto [nr,nc]=path[(idx+1)%M];\n            move_to(r,c,nr,nc,out);                   // true Manhattan route\n        }\n    }\n\n    for(const string& op:out) cout<<op<<'\\n';\n    return 0;\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*** fixed problem parameters *******************************************/\nconstexpr int N          = 6;                   // grid size\nconstexpr int M          = 15;                  // criteria per seed\nconstexpr int T_TURNS    = 10;                  // operations\nconstexpr int SEED_CNT   = 2 * N * (N - 1);     // 60\nconstexpr int PLANT_CNT  = N * N;               // 36\nconstexpr int RESTARTS   = 10;                  // multi-start SA\nconstexpr int SA_ITERS   = 70000;               // iterations / restart\n\nstruct Seed {\n    array<uint8_t, M> x;\n    int               sum = 0;                  // Vi = \u03a3 xi,l\n};\n\n/*** geometry of the 6\u00d76 field ******************************************/\narray<vector<int>, PLANT_CNT> nbr;\nvector<pair<int,int>>         edges;            // 60 undirected edges\narray<int, PLANT_CNT>         degree;\n\nvoid build_geometry() {\n    for (int r = 0; r < N; ++r)\n        for (int c = 0; c < N; ++c) {\n            int id = r * N + c;\n            auto add=[&](int rr,int cc){\n                if (0<=rr && rr<N && 0<=cc && cc<N)\n                    nbr[id].push_back(rr*N+cc);\n            };\n            if (c+1<N){ add(r,c+1); edges.emplace_back(id, r*N+c+1); }\n            if (r+1<N){ add(r+1,c); edges.emplace_back(id,(r+1)*N+c); }\n            add(r  ,c-1); add(r-1,c  );\n        }\n    for (int i = 0; i < PLANT_CNT; ++i) degree[i] = (int)nbr[i].size();\n}\n\n/*** containers reused every turn ***************************************/\narray<Seed, SEED_CNT>  seed;                     // 60 current seeds\nint                   w[SEED_CNT][SEED_CNT];     // edge weight = \u03a3 max\narray<int,PLANT_CNT>  cell2seed;                 // working grid buffer\n\n/*** \u0394 of \u03a3edges when a single cell changes *****************************/\ninline long long delta_one(int pos,int oldS,int newS){\n    long long d = 0;\n    for (int nb : nbr[pos]){\n        d -= w[oldS][cell2seed[nb]];\n        d += w[newS][cell2seed[nb]];\n    }\n    return d;\n}\n\n/*** deterministic greedy hill-climb (local optimum) ********************/\nlong long greedy_improve(vector<int>& pool, long long curSum){\n    bool changed = true;\n    while (changed){\n        changed = false;\n        /* replacements ------------------------------------------------ */\n        for (int pos = 0; pos < PLANT_CNT; ++pos){\n            int oldS = cell2seed[pos];\n            long long bestD = 0; int bestIdx = -1;\n            for (int i = 0; i < (int)pool.size(); ++i){\n                long long d = delta_one(pos, oldS, pool[i]);\n                if (d > bestD){ bestD = d; bestIdx = i; }\n            }\n            if (bestD > 0){\n                swap(cell2seed[pos], pool[bestIdx]);\n                curSum += bestD;\n                changed = true;\n            }\n        }\n        /* swaps inside the grid -------------------------------------- */\n        for (int a = 0; a < PLANT_CNT; ++a)\n            for (int b = a+1; b < PLANT_CNT; ++b){\n                int sa = cell2seed[a], sb = cell2seed[b];\n                long long d = delta_one(a, sa, sb) + delta_one(b, sb, sa);\n                if (d > 0){\n                    swap(cell2seed[a], cell2seed[b]);\n                    curSum += d;\n                    changed = true;\n                }\n            }\n    }\n    return curSum;\n}\n\n/*** one simulated-annealing run ****************************************/\nlong long run_SA(mt19937_64 &rng, vector<int>& pool,\n                 array<int,PLANT_CNT>& grid){\n    static uniform_real_distribution<double> urd(0.0,1.0);\n    uniform_int_distribution<int>            cellDist(0, PLANT_CNT-1);\n\n    cell2seed = grid;                        // work on global buffer\n    long long curSum = 0;\n    for (auto [u,v]: edges) curSum += w[cell2seed[u]][cell2seed[v]];\n    array<int,PLANT_CNT> bestGrid = grid;\n    long long            bestSum  = curSum;\n\n    constexpr double T0 = 1000.0, T1 = 10.0;\n\n    for (int it = 0; it < SA_ITERS; ++it){\n        double temp = T0 + (T1 - T0) * it / SA_ITERS;\n\n        bool poolMove = !pool.empty() && urd(rng) < 0.35;\n        int posA = cellDist(rng), posB;\n        long long dSum;\n\n        if (poolMove){\n            int pidx = uniform_int_distribution<int>(0,(int)pool.size()-1)(rng);\n            int s_new = pool[pidx], s_old = cell2seed[posA];\n            dSum = delta_one(posA, s_old, s_new);\n            if (dSum >= 0 || urd(rng) < exp(dSum / temp)){\n                cell2seed[posA] = s_new;\n                pool[pidx]      = s_old;\n                curSum         += dSum;\n                if (curSum > bestSum){ bestSum = curSum; bestGrid = cell2seed; }\n            }\n        } else {\n            do{ posB = cellDist(rng);} while (posB == posA);\n            int sa = cell2seed[posA], sb = cell2seed[posB];\n            dSum = delta_one(posA, sa, sb) + delta_one(posB, sb, sa);\n            if (dSum >= 0 || urd(rng) < exp(dSum / temp)){\n                swap(cell2seed[posA], cell2seed[posB]);\n                curSum += dSum;\n                if (curSum > bestSum){ bestSum = curSum; bestGrid = cell2seed; }\n            }\n        }\n    }\n    grid = bestGrid;\n    return bestSum;\n}\n\n/*** helper: pool = complement of grid **********************************/\nvector<int> complement_pool(const array<int,PLANT_CNT>& grid){\n    vector<char> in(SEED_CNT,0);\n    for (int s : grid) in[s] = 1;\n    vector<int> pool;\n    for (int i = 0; i < SEED_CNT; ++i) if (!in[i]) pool.push_back(i);\n    return pool;\n}\n\n/*** weighted-random start (4-way tournament) ***************************/\narray<int,PLANT_CNT> random_start(mt19937_64 &rng,\n                                  const array<int,PLANT_CNT>& cells){\n    vector<int> bag(SEED_CNT); iota(bag.begin(),bag.end(),0);\n    array<int,PLANT_CNT> g;\n    uniform_int_distribution<int> pick(0, (int)bag.size()-1);\n    for (int pos = 0; pos < PLANT_CNT; ++pos){\n        int best = pick(rng);\n        for (int k=1;k<4;++k){\n            int idx = pick(rng);\n            if (seed[bag[idx]].sum > seed[bag[best]].sum) best = idx;\n        }\n        g[cells[pos]] = bag[best];\n        bag.erase(bag.begin()+best);\n        pick.param( decltype(pick)::param_type(0,(int)bag.size()-1) );\n    }\n    return g;\n}\n\n/*** main ****************************************************************/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    build_geometry();\n    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n    /* read initial seeds */\n    int dummy; cin >> dummy >> dummy >> dummy;              // N M T\n    for (int i=0;i<SEED_CNT;++i){\n        int s=0; for (int l=0;l<M;++l){ int v; cin>>v; seed[i].x[l]=v; s+=v; }\n        seed[i].sum = s;\n    }\n\n    for (int turn = 0; turn < T_TURNS; ++turn){\n\n        /* build edge weight table w(i,j)=\u03a3 max(xi_l,xj_l) */\n        for (int i=0;i<SEED_CNT;++i)\n            for (int j=i;j<SEED_CNT;++j){\n                if (i==j){ w[i][i]=seed[i].sum; continue; }\n                int s=0; for (int l=0;l<M;++l)\n                    s += max(seed[i].x[l], seed[j].x[l]);\n                w[i][j]=w[j][i]=s;\n            }\n\n        /* degree order of cells (fixed) */\n        array<int,PLANT_CNT> cells;\n        iota(cells.begin(),cells.end(),0);\n        ranges::sort(cells,[&](int a,int b){ return degree[a]>degree[b]; });\n\n        /* deterministic start (top sums) */\n        vector<int> idx(SEED_CNT); iota(idx.begin(),idx.end(),0);\n        ranges::sort(idx,[&](int a,int b){ return seed[a].sum>seed[b].sum; });\n        array<int,PLANT_CNT> baseGrid;\n        for (int k=0;k<PLANT_CNT;++k) baseGrid[cells[k]] = idx[k];\n\n        /* multi-start SA */\n        array<int,PLANT_CNT> bestGrid; long long bestSum = -1;\n        for (int rep=0; rep<RESTARTS; ++rep){\n            array<int,PLANT_CNT> grid =\n                (rep==0)? baseGrid : random_start(rng,cells);\n            vector<int> pool = complement_pool(grid);\n            long long s = run_SA(rng,pool,grid);\n            if (s > bestSum){ bestSum=s; bestGrid=grid; }\n        }\n        cell2seed = bestGrid;\n        vector<int> pool = complement_pool(cell2seed);\n\n        /* deterministic polishing */\n        bestSum = 0;\n        for (auto [u,v]: edges) bestSum += w[cell2seed[u]][cell2seed[v]];\n        bestSum = greedy_improve(pool,bestSum);\n\n        /* output planting plan */\n        for (int r=0;r<N;++r){\n            for (int c=0;c<N;++c){\n                if (c) cout << ' ';\n                cout << cell2seed[r*N+c];\n            }\n            cout << '\\n';\n        }\n        cout.flush();\n\n        /* read next generation */\n        if (turn == T_TURNS-1) break;\n        for (int i=0;i<SEED_CNT;++i){\n            int s=0; for (int l=0;l<M;++l){ int v; cin>>v; seed[i].x[l]=v; s+=v; }\n            seed[i].sum = s;\n        }\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------------- basic helpers ---------------------------------- */\nstruct Pos{ int x,y; };\nconstexpr int DX[4]={0,1,0,-1};   // 0:R 1:D 2:L 3:U\nconstexpr int DY[4]={1,0,-1,0};\n\ninline int manhattan(const Pos&a,const Pos&b){\n    return abs(a.x-b.x)+abs(a.y-b.y);\n}\ninline bool inside(int x,int y,int N){ return 0<=x&&x<N&&0<=y&&y<N; }\ninline Pos root_for(const Pos&p,int d){ return {p.x-DX[d],p.y-DY[d]}; }\n\n/* rotation -------------------------------------------------------- */\ninline pair<int,int> rotPlan(int f,int t){\n    int diff=(t-f+4)&3;\n    if(!diff) return {0,0};\n    if(diff==3) return {-1,1};\n    return {+1,diff};\n}\ninline int rotSteps(int f,int t){ return rotPlan(f,t).second; }\n\n/* ----------------------------------------------------------------- */\nstruct Simulator{\n    int N,rx=0,ry=0;\n    vector<string> cmd;\n    void emit(char mv,int rot,int leaf,int actLeaf){\n        string s(10,'.');            // V'=5  \u21d2 len 10\n        s[0]=mv;\n        if(rot) s[leaf]=(rot>0?'R':'L');\n        if(actLeaf) s[5+actLeaf]='P';\n        cmd.push_back(move(s));\n    }\n};\n/* =================================================================\n   Hungarian (minimum assignment)  \u2013 O(n\u00b3), 1-based internally      */\nvector<int> hungarian(const vector<vector<int>>& a){   // square matrix\n    const int n=a.size();\n    const int INF=1e9;\n    vector<int> u(n+1),v(n+1),p(n+1),way(n+1);\n    for(int i=1;i<=n;i++){\n        p[0]=i; int j0=0;\n        vector<int> minv(n+1,INF); 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++) if(!used[j]){\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]; j0=j1;\n        }while(j0!=0);\n    }\n    vector<int> match(n,-1);                  // src i -> tar match[i]\n    for(int j=1;j<=n;j++) if(p[j]) match[p[j]-1]=j-1;\n    return match;\n}\n/* ================================================================= */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N,M,Vmax; if(!(cin>>N>>M>>Vmax)) 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<Pos> SRC,TAR;\n    for(int i=0;i<N;++i)\n        for(int j=0;j<N;++j){\n            bool s=S[i][j]=='1', t=T[i][j]=='1';\n            if( s && !t) SRC.push_back({i,j});\n            if(!s &&  t) TAR.push_back({i,j});\n        }\n    const int M0=SRC.size();\n\n    /* ----------- global source \u2194 target assignment (Hungarian) ---- */\n    vector<vector<int>> cost(M0,vector<int>(M0));\n    for(int i=0;i<M0;i++)\n        for(int j=0;j<M0;j++)\n            cost[i][j]=manhattan(SRC[i],TAR[j]);\n    vector<int> assigned= hungarian(cost);         // size M0\n\n    /* -------------------- output arm design ----------------------- */\n    cout<<5<<\"\\n\";\n    for(int i=1;i<=4;i++) cout<<\"0 1\\n\";\n    cout<<\"0 0\\n\";\n\n    Simulator sim; sim.N=N;\n\n    /* turn 0+1 : rotate leaves to (\u2192 \u2193 \u2191 \u2190) ------------------------ */\n    { string s(10,'.'); s[2]='R'; s[3]='L'; s[4]='R'; sim.cmd.push_back(s); }\n    { string s(10,'.'); s[4]='R'; sim.cmd.push_back(s); }\n\n    int ori[5]={0,0,1,3,2};                    // leaf orientations\n\n    /* helpers ------------------------------------------------------ */\n    auto move_rot=[&](int tx,int ty,int leaf,int tgtOri){\n        auto [sg,st]=rotPlan(ori[leaf],tgtOri);\n        while(sim.rx!=tx || sim.ry!=ty){\n            char mv='.';\n            if      (sim.rx<tx){ ++sim.rx; mv='D'; }\n            else if (sim.rx>tx){ --sim.rx; mv='U'; }\n            else if (sim.ry<ty){ ++sim.ry; mv='R'; }\n            else                { --sim.ry; mv='L'; }\n            int r=0;\n            if(st){ r=sg; --st; ori[leaf]=(ori[leaf]+(sg>0?1:3))&3; }\n            sim.emit(mv,r,leaf,0);\n        }\n        while(st){\n            int r=sg; --st; ori[leaf]=(ori[leaf]+(sg>0?1:3))&3;\n            sim.emit('.',r,leaf,0);\n        }\n    };\n    auto markP=[&](int leaf){\n        if(sim.cmd.empty()) sim.emit('.',0,0,leaf);\n        else sim.cmd.back()[5+leaf]='P';\n    };\n\n    const double ALPHA0=0.40;\n\n    vector<char> done(M0,0);\n    int remaining=M0;\n    while(remaining){\n        double alpha=ALPHA0*remaining/M0;\n\n        int best=-1,bLeaf=0,bOriS=0,bOriT=0;\n        int pickX=0,pickY=0,dropX=0,dropY=0;\n        double bestScore=1e100;\n\n        for(int i=0;i<M0;i++) if(!done[i]){\n            const Pos& s=SRC[i];\n            const Pos& t=TAR[assigned[i]];\n            for(int leaf=1;leaf<=4;++leaf)\n                for(int d1=0;d1<4;++d1){\n                    Pos rP=root_for(s,d1);\n                    if(!inside(rP.x,rP.y,N)) continue;\n                    int dRoot=manhattan(Pos{sim.rx,sim.ry},rP);\n                    int rot1=rotSteps(ori[leaf],d1);\n                    int c1=max(dRoot,rot1);\n\n                    int bestOri2=-1,rDX=0,rDY=0,c2=INT_MAX;\n                    for(int d2=0;d2<4;++d2){\n                        Pos rD=root_for(t,d2);\n                        if(!inside(rD.x,rD.y,N)) continue;\n                        int d12=manhattan(rP,rD);\n                        int rot12=rotSteps(d1,d2);\n                        int c=max(d12,rot12);\n                        if(c<c2){ c2=c; bestOri2=d2; rDX=rD.x; rDY=rD.y; }\n                    }\n                    if(bestOri2==-1) continue;\n\n                    int nextCost=0;\n                    if(remaining>1){\n                        int mn=INT_MAX;\n                        for(int k=0;k<M0;k++) if(!done[k] && k!=i){\n                            const Pos& q=SRC[k];\n                            for(int d=0;d<4;++d){\n                                Pos rQ=root_for(q,d);\n                                if(!inside(rQ.x,rQ.y,N)) continue;\n                                int dR=manhattan(Pos{rDX,rDY},rQ);\n                                int rR=rotSteps(bestOri2,d);\n                                mn=min(mn,max(dR,rR));\n                            }\n                        }\n                        nextCost=(mn==INT_MAX?0:mn);\n                    }\n\n                    double score=c1+c2+alpha*nextCost;\n                    if(score<bestScore){\n                        bestScore=score; best=i; bLeaf=leaf; bOriS=d1;\n                        bOriT=bestOri2; pickX=rP.x; pickY=rP.y;\n                        dropX=rDX; dropY=rDY;\n                    }\n                }\n        }\n\n        done[best]=1; --remaining;\n\n        move_rot(pickX,pickY,bLeaf,bOriS); markP(bLeaf);  // grab\n        move_rot(dropX,dropY,bLeaf,bOriT); markP(bLeaf);  // drop\n    }\n\n    for(const string& s:sim.cmd) cout<<s<<\"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\n/* ---------------------------------------------------------------------- */\nstruct Point { int x, y; };\nstruct Rect  { int x1, y1, x2, y2;  bool valid()const{return x1<x2&&y1<y2;} };\n/* ---------------------------------------------------------------------- */\nconstexpr int MAXC = 100000;\nconstexpr int CELL = 250;\nconstexpr int GRID = MAXC / CELL + 1;           // 401\nconstexpr int TOPK = 32;                        // how many coarse rectangles\n\nstatic int diffGrid[GRID][GRID];\nstatic int pref[GRID + 1][GRID + 1];\n\ninline int gridSum(int t,int l,int b,int r){    // inclusive\n    return pref[b+1][r+1]-pref[t][r+1]-pref[b+1][l]+pref[t][l];\n}\n\n/* exact score of any rectangle ------------------------------------------ */\nint exactScore(const Rect&r,\n               const vector<Point>&mac,const vector<Point>&sar){\n    int res=0;\n    for(const auto&p:mac)\n        if(r.x1<=p.x&&p.x<=r.x2&&r.y1<=p.y&&p.y<=r.y2) ++res;\n    for(const auto&p:sar)\n        if(r.x1<=p.x&&p.x<=r.x2&&r.y1<=p.y&&p.y<=r.y2) --res;\n    return res;\n}\n\n/*---------------------------------------------------------------------------*/\n/* one-dimensional optimum for a single side (same idea as previous version) */\ntemplate<bool vertical,bool lower>\nbool optimiseSide(Rect&R,int&best,\n                  const vector<Point>&mac,const vector<Point>&sar){\n    vector<pair<int,int>> v; v.reserve(20000);\n    if constexpr(vertical){\n        for(const auto&p:mac)\n            if(R.y1<=p.y&&p.y<=R.y2&&(lower?p.x<=R.x2:p.x>=R.x1))\n                v.emplace_back(p.x,+1);\n        for(const auto&p:sar)\n            if(R.y1<=p.y&&p.y<=R.y2&&(lower?p.x<=R.x2:p.x>=R.x1))\n                v.emplace_back(p.x,-1);\n    }else{\n        for(const auto&p:mac)\n            if(R.x1<=p.x&&p.x<=R.x2&&(lower?p.y<=R.y2:p.y>=R.y1))\n                v.emplace_back(p.y,+1);\n        for(const auto&p:sar)\n            if(R.x1<=p.x&&p.x<=R.x2&&(lower?p.y<=R.y2:p.y>=R.y1))\n                v.emplace_back(p.y,-1);\n    }\n    if(v.empty()) return false;\n    sort(v.begin(),v.end(),[](auto a,auto b){return a.first<b.first;});\n    vector<pair<int,int>> g; g.reserve(v.size());\n    for(auto [c,val]:v){\n        if(g.empty()||g.back().first!=c) g.emplace_back(c,val);\n        else g.back().second+=val;\n    }\n    int total=0; for(auto &p:g) total+=p.second;\n\n    bool improved=false;\n    if constexpr(vertical&&lower){             // left\n        int prefix=0,bestLocal=best,bestPos=R.x1;\n        if(total>bestLocal&&0<R.x2){bestLocal=total;bestPos=0;improved=true;}\n        for(size_t i=0;i<g.size();++i){\n            int x=g[i].first,group=g[i].second;\n            if(x<R.x2){\n                int sc=total-prefix;\n                if(sc>bestLocal){bestLocal=sc;bestPos=x;improved=true;}\n            }\n            if(x+1<R.x2){\n                int sc=total-(prefix+group);\n                if(sc>bestLocal){bestLocal=sc;bestPos=x+1;improved=true;}\n            }\n            prefix+=group;\n        }\n        if(improved){R.x1=bestPos;best=bestLocal;}\n    }else if constexpr(vertical&&!lower){      // right\n        int suffix=0,bestLocal=best,bestPos=R.x2;\n        if(total>bestLocal&&MAXC>R.x1){bestLocal=total;bestPos=MAXC;improved=true;}\n        for(int i=(int)g.size()-1;i>=0;--i){\n            int x=g[i].first,group=g[i].second;\n            if(x>R.x1){\n                int sc=total-suffix;\n                if(sc>bestLocal){bestLocal=sc;bestPos=x;improved=true;}\n            }\n            if(x-1>R.x1){\n                int sc=total-(suffix+group);\n                if(sc>bestLocal){bestLocal=sc;bestPos=x-1;improved=true;}\n            }\n            suffix+=group;\n        }\n        if(improved){R.x2=bestPos;best=bestLocal;}\n    }else if constexpr(!vertical&&lower){      // bottom\n        int prefix=0,bestLocal=best,bestPos=R.y1;\n        if(total>bestLocal&&0<R.y2){bestLocal=total;bestPos=0;improved=true;}\n        for(size_t i=0;i<g.size();++i){\n            int y=g[i].first,group=g[i].second;\n            if(y<R.y2){\n                int sc=total-prefix;\n                if(sc>bestLocal){bestLocal=sc;bestPos=y;improved=true;}\n            }\n            if(y+1<R.y2){\n                int sc=total-(prefix+group);\n                if(sc>bestLocal){bestLocal=sc;bestPos=y+1;improved=true;}\n            }\n            prefix+=group;\n        }\n        if(improved){R.y1=bestPos;best=bestLocal;}\n    }else{                                     // top\n        int suffix=0,bestLocal=best,bestPos=R.y2;\n        if(total>bestLocal&&MAXC>R.y1){bestLocal=total;bestPos=MAXC;improved=true;}\n        for(int i=(int)g.size()-1;i>=0;--i){\n            int y=g[i].first,group=g[i].second;\n            if(y>R.y1){\n                int sc=total-suffix;\n                if(sc>bestLocal){bestLocal=sc;bestPos=y;improved=true;}\n            }\n            if(y-1>R.y1){\n                int sc=total-(suffix+group);\n                if(sc>bestLocal){bestLocal=sc;bestPos=y-1;improved=true;}\n            }\n            suffix+=group;\n        }\n        if(improved){R.y2=bestPos;best=bestLocal;}\n    }\n    return improved;\n}\n\n/* greedy grid-cell shrink ----------------------------------------------- */\nvoid shrinkOnGrid(int &t,int &l,int &b,int &r){\n    bool changed=true;\n    while(changed){\n        changed=false;\n        int cur=gridSum(t,l,b,r);\n        if(l<r&&gridSum(t,l+1,b,r)>cur){++l;changed=true;continue;}\n        if(l<r&&gridSum(t,l,b,r-1)>cur){--r;changed=true;continue;}\n        if(t<b&&gridSum(t+1,l,b,r)>cur){++t;changed=true;continue;}\n        if(t<b&&gridSum(t,l,b-1,r)>cur){--b;changed=true;continue;}\n    }\n}\n\n/* ---------------------------------------------------------------------- */\nstruct GridRect{int l,r,t,b; int val;};\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<Point> mac(N),sar(N);\n    for(int i=0;i<N;++i) cin>>mac[i].x>>mac[i].y;\n    for(int i=0;i<N;++i) cin>>sar[i].x>>sar[i].y;\n\n    /* difference grid & prefix ------------------------------------------ */\n    for(auto &p:mac) diffGrid[p.y/CELL][p.x/CELL]+=1;\n    for(auto &p:sar) diffGrid[p.y/CELL][p.x/CELL]-=1;\n    for(int y=0;y<GRID;++y){\n        int row=0;\n        for(int x=0;x<GRID;++x){\n            row+=diffGrid[y][x];\n            pref[y+1][x+1]=pref[y][x+1]+row;\n        }\n    }\n\n    /* 1. best rectangle on the grid via 2-D Kadane ----------------------- */\n    static int colSum[GRID];\n    int bestKadane=-1e9; int bl=0,br=0,bt=0,bb=0;\n    for(int top=0;top<GRID;++top){\n        fill(colSum,colSum+GRID,0);\n        for(int bot=top;bot<GRID;++bot){\n            for(int x=0;x<GRID;++x) colSum[x]+=diffGrid[bot][x];\n            int cur=0,curL=0;\n            for(int x=0;x<GRID;++x){\n                cur+=colSum[x];\n                if(cur>bestKadane){bestKadane=cur;bl=curL;br=x;bt=top;bb=bot;}\n                if(cur<0){cur=0;curL=x+1;}\n            }\n        }\n    }\n\n    /* priority queue of TOPK coarse rectangles --------------------------- */\n    auto pushCand=[&](vector<GridRect>&vec,const GridRect&gr){\n        if((int)vec.size()<TOPK){vec.push_back(gr);}\n        else{\n            int mn=0;\n            for(int i=1;i<(int)vec.size();++i)\n                if(vec[i].val<vec[mn].val) mn=i;\n            if(gr.val>vec[mn].val) vec[mn]=gr;\n        }\n    };\n\n    vector<GridRect> cand;\n    pushCand(cand,{bl,br,bt,bb,bestKadane});\n\n    /* 2. 60k random rectangles ------------------------------------------ */\n    mt19937 rng(123456);\n    uniform_int_distribution<int> pickMac(0,N-1), sizePick(1,60);\n\n    const int SAMPLES=60000;\n    for(int s=0;s<SAMPLES;++s){\n        const auto &c=mac[pickMac(rng)];\n        int gx=c.x/CELL, gy=c.y/CELL;\n        int w=sizePick(rng), h=sizePick(rng);\n        int l=max(0,gx-w/2);\n        int r=min(GRID-1,l+w-1); l=max(0,r-w+1);\n        int t=max(0,gy-h/2);\n        int b=min(GRID-1,t+h-1); t=max(0,b-h+1);\n\n        int sc=gridSum(t,l,b,r);\n        pushCand(cand,{l,r,t,b,sc});\n    }\n\n    /* ------------------------------------------------------------------ */\n    Rect bestRect{0,0,1,1};\n    int  bestScore=0;\n\n    for(auto gr:cand){\n        /* local greedy shrink on grid */\n        shrinkOnGrid(gr.t,gr.l,gr.b,gr.r);\n\n        /* convert to real coordinates */\n        Rect R{gr.l*CELL,\n               gr.t*CELL,\n               min(MAXC,(gr.r+1)*CELL-1),\n               min(MAXC,(gr.b+1)*CELL-1)};\n\n        int cur=exactScore(R,mac,sar);\n\n        /* coordinate-wise exact optimisation (\u22646 rounds) */\n        for(int round=0;round<6;++round){\n            bool any=false;\n            any|=optimiseSide<true ,true >(R,cur,mac,sar);  // left\n            any|=optimiseSide<true ,false>(R,cur,mac,sar);  // right\n            any|=optimiseSide<false,true >(R,cur,mac,sar);  // bottom\n            any|=optimiseSide<false,false>(R,cur,mac,sar);  // top\n            if(!any) break;\n        }\n\n        if(cur>bestScore && R.valid()){ bestScore=cur; bestRect=R; }\n    }\n\n    if(bestScore<=0) bestRect={0,0,1,1};\n\n    /*  output rectangle ---------------------------------------------------- */\n    cout<<4<<\"\\n\";\n    cout<<bestRect.x1<<\" \"<<bestRect.y1<<\"\\n\";\n    cout<<bestRect.x2<<\" \"<<bestRect.y1<<\"\\n\";\n    cout<<bestRect.x2<<\" \"<<bestRect.y2<<\"\\n\";\n    cout<<bestRect.x1<<\" \"<<bestRect.y2<<\"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\nusing int64 = long long;\n\n/*------------------------------------------------------------------*/\n/*  rectangle                                                       */\n/*------------------------------------------------------------------*/\nstruct Rec{ int64 w,h; };\nstatic inline Rec rot(const Rec&r){ return Rec{r.h,r.w}; }\n\n/*------------------------------------------------------------------*/\n/*  exact evaluation (statement rules)                              */\n/*------------------------------------------------------------------*/\nint64 eval_exact(const vector<Rec>& r,\n                 const vector<char>& ori,\n                 const vector<char>& cut)          // cut[0]==1\n{\n    const int N=(int)r.size();\n    vector<int> rows; for(int i=0;i<N;++i) if(cut[i]) rows.push_back(i);\n    const int R=(int)rows.size();\n\n    vector<int64> rowW(R,0), rowH(R,0); vector<int> tallest(R);\n    for(int rr=0; rr<R; ++rr){\n        int st=rows[rr], ed=(rr+1<R?rows[rr+1]:N); int64 hMax=-1;\n        for(int i=st;i<ed;++i){\n            const Rec& rc = ori[i]?rot(r[i]):r[i];\n            rowW[rr]+=rc.w;\n            if(rc.h>hMax){ hMax=rc.h; tallest[rr]=i; }\n        }\n        rowH[rr]=hMax;\n    }\n\n    vector<int64> posX(N,0), offset(R,0);\n    int64 maxX=0, sumH=0;\n    for(int rr=0; rr<R; ++rr){\n        int st=rows[rr], ed=(rr+1<R?rows[rr+1]:N);\n        for(int i=st;i<ed;++i){\n            const Rec& prev=(i==st?Rec{0,0}:(ori[i-1]?rot(r[i-1]):r[i-1]));\n            const Rec& cur =(ori[i]?rot(r[i]):r[i]);\n            posX[i]=(i==st?offset[rr]:posX[i-1]+prev.w);\n            maxX=max(maxX,posX[i]+cur.w);\n        }\n        sumH+=rowH[rr];\n        if(rr+1<R){\n            int b=tallest[rr];\n            int64 baseR=posX[b]+(ori[b]?rot(r[b]).w:r[b].w);\n            offset[rr+1]=max<int64>(0, baseR-rowW[rr+1]);\n        }\n    }\n    return maxX+sumH;\n}\n\n/*------------------------------------------------------------------*/\n/*  greedy construction under a width limit                          */\n/*------------------------------------------------------------------*/\nstruct Layout{\n    vector<char> ori,cut;      // cut[0]==1\n    int64 score;\n};\n\nLayout greedy_build(const vector<Rec>& r,double Wlim)\n{\n    const int N=(int)r.size();\n    vector<char> ori(N,0), cut(N,0); cut[0]=1;\n    double curW=0,curH=0;\n    for(int i=0;i<N;++i){\n        Rec a=r[i], b=rot(r[i]);\n        bool fitA=(curW+a.w<=Wlim), fitB=(curW+b.w<=Wlim);\n        if(!fitA && !fitB){ cut[i]=1; curW=curH=0; fitA=fitB=true; }\n        char use=0;\n        if(fitA&&fitB){\n            double hA=max(curH,(double)a.h), hB=max(curH,(double)b.h);\n            use=(hB<hA||(hB==hA&&b.w<a.w));\n        }else if(!fitA) use=1;\n        ori[i]=use;\n        const Rec& rc=use?b:a;\n        curW+=rc.w; curH=max(curH,(double)rc.h);\n    }\n    Layout L{ori,cut,eval_exact(r,ori,cut)};\n    return L;\n}\n\n/*------------------------------------------------------------------*/\n/*  monotone local improvement                                       */\n/*------------------------------------------------------------------*/\nvoid improve(Layout& lay,const vector<Rec>& r)\n{\n    const int N=(int)r.size(); bool changed=true;\n    while(changed){\n        changed=false;\n        for(int i=0;i<N;++i){                 // flip\n            lay.ori[i]^=1;\n            int64 sc=eval_exact(r,lay.ori,lay.cut);\n            if(sc<lay.score){ lay.score=sc; changed=true; } else lay.ori[i]^=1;\n        }\n        for(int i=1;i<N;++i){                 // toggle cut\n            lay.cut[i]^=1;\n            int64 sc=eval_exact(r,lay.ori,lay.cut);\n            if(sc<lay.score){ lay.score=sc; changed=true; continue; }\n            lay.cut[i]^=1;\n        }\n        for(int i=1;i<N-1;++i) if(lay.cut[i]){ // shift cut\n            if(!lay.cut[i-1]){\n                lay.cut[i]=0; lay.cut[i-1]=1;\n                int64 sc=eval_exact(r,lay.ori,lay.cut);\n                if(sc<lay.score){ lay.score=sc; changed=true; continue; }\n                lay.cut[i]=1; lay.cut[i-1]=0;\n            }\n            if(!lay.cut[i+1]){\n                lay.cut[i]=0; lay.cut[i+1]=1;\n                int64 sc=eval_exact(r,lay.ori,lay.cut);\n                if(sc<lay.score){ lay.score=sc; changed=true; continue; }\n                lay.cut[i]=1; lay.cut[i+1]=0;\n            }\n        }\n    }\n}\n\n/*------------------------------------------------------------------*/\n/*  optimise once on fixed rectangle set                             */\n/*------------------------------------------------------------------*/\nLayout solve_once(const vector<Rec>& r)\n{\n    long double area=0; for(auto &rc:r) area+=(long double)rc.w*rc.h;\n    double W0=sqrt((double)area);\n\n    vector<double> fac; for(double f=0.25; f<=6.4+1e-9; f*=1.26) fac.push_back(f);\n\n    Layout best; best.score=(1LL<<60);\n    for(double f:fac){\n        Layout cand=greedy_build(r,W0*f);\n        if(cand.score<best.score) best=cand;\n    }\n    improve(best,r);\n    return best;\n}\n\n/*------------------------------------------------------------------*/\n/*  build command list (original indices)                            */\n/*------------------------------------------------------------------*/\nstruct Cmd{ int p; char r,d; int b; };\n\nvector<Cmd> build_cmds(const vector<Rec>& r,const Layout& lay,\n                       const vector<int>& mapIdx)\n{\n    const int N=(int)r.size();\n    vector<int> rows; for(int i=0;i<N;++i) if(lay.cut[i]) rows.push_back(i);\n    int R=(int)rows.size();\n    vector<int> tall(R);\n    for(int rr=0; rr<R; ++rr){\n        int st=rows[rr], ed=(rr+1<R?rows[rr+1]:N); int64 bestH=-1;\n        for(int i=st;i<ed;++i){\n            int64 h=lay.ori[i]?r[i].w:r[i].h;\n            if(h>bestH){ bestH=h; tall[rr]=i; }\n        }\n    }\n\n    vector<Cmd> out; out.reserve(N);\n    for(int i=0;i<N;++i){\n        int rr=(int)(upper_bound(rows.begin(),rows.end(),i)-rows.begin())-1;\n        bool first=lay.cut[i];\n        Cmd c; c.p=mapIdx[i]; c.r=lay.ori[i];\n        if(rr==0 && first){ c.d='U'; c.b=-1; }\n        else if(first){     c.d='L'; c.b=mapIdx[tall[rr-1]]; }\n        else{               c.d='U'; c.b=mapIdx[i-1]; }\n        out.push_back(c);\n    }\n    return out;\n}\n\n/*------------------------------------------------------------------*/\n/*  generate all skip-sets |S| \u2264 4 among the 10 biggest              */\n/*------------------------------------------------------------------*/\nstruct Cand{ int64 score; int skipped; vector<Cmd> cmds; };\n\nvector<Cand> generate_all(const vector<Rec>& full)\n{\n    const int N=(int)full.size();\n    vector<int> ord(N); iota(ord.begin(),ord.end(),0);\n    sort(ord.begin(),ord.end(),[&](int a,int b){\n        return full[a].w+full[a].h > full[b].w+full[b].h;\n    });\n    const int K=min(10,N);\n\n    /* enumerate subsets of size 0\u20264 */\n    vector<vector<int>> subs{{}};\n    for(int i=0;i<K;++i) subs.push_back({ord[i]});\n    for(int i=0;i<K;++i) for(int j=i+1;j<K;++j) subs.push_back({ord[i],ord[j]});\n    for(int i=0;i<K;++i) for(int j=i+1;j<K;++j) for(int k=j+1;k<K;++k)\n        subs.push_back({ord[i],ord[j],ord[k]});\n    for(int i=0;i<K;++i) for(int j=i+1;j<K;++j) for(int k=j+1;k<K;++k)\n        for(int l=k+1;l<K;++l)\n            subs.push_back({ord[i],ord[j],ord[k],ord[l]});\n\n    vector<Cand> out; out.reserve(subs.size()*2);\n\n    for(auto &skip:subs){\n        vector<char> skipF(N,0); for(int x:skip) skipF[x]=1;\n        vector<Rec> sub; vector<int> mapIdx;\n        for(int i=0;i<N;++i) if(!skipF[i]){ sub.push_back(full[i]); mapIdx.push_back(i); }\n        if(sub.empty()) continue;\n\n        Layout L1=solve_once(sub);\n\n        vector<Rec> sw=sub; for(auto &rc:sw) swap(rc.w,rc.h);\n        Layout L2=solve_once(sw);\n        for(auto &b:L2.ori) b^=1;\n        L2.score = eval_exact(sub,L2.ori,L2.cut);\n\n        Layout bestL=(L1.score<=L2.score?L1:L2);\n\n        int64 penalty=0; for(int x:skip) penalty+=full[x].w+full[x].h;\n        int64 total=bestL.score+penalty;\n\n        Cand c; c.score=total; c.skipped=(int)skip.size();\n        c.cmds=build_cmds(sub,bestL,mapIdx);\n        out.push_back(std::move(c));\n    }\n\n    const int64 THR=10000;                  // noise margin\n    sort(out.begin(),out.end(),[&](const Cand&a,const Cand&b){\n        if(abs(a.score-b.score)>THR) return a.score<b.score;\n        return a.skipped < b.skipped;\n    });\n    return out;\n}\n\n/*------------------------------------------------------------------*/\n/*  main                                                             */\n/*------------------------------------------------------------------*/\nint main(){\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n\n    int N,T,sigma; if(!(cin>>N>>T>>sigma)) return 0;\n    vector<Rec> rec(N); for(int i=0;i<N;++i) cin>>rec[i].w>>rec[i].h;\n\n    auto all = generate_all(rec);\n    if(all.empty()) return 0;\n\n    const int K=min<int>(T, all.size());\n\n    for(int turn=0; turn<T; ++turn){\n        const auto &cmds = (turn<K ? all[turn].cmds : all[0].cmds);\n\n        cout<<cmds.size()<<'\\n';\n        for(auto &c:cmds)\n            cout<<c.p<<' '<<int(c.r)<<' '<<c.d<<' '<<c.b<<'\\n';\n        cout<<flush;\n\n        long long Wp,Hp; if(!(cin>>Wp>>Hp)) return 0;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int LIMH        = 10;\nconstexpr int UNASS       = -2;\n\n/* depth caps we try \u2013 best \u2192 worst order */\nstatic const int DEP_CAPS[] = {5,6,7,8,9,10};\nconstexpr int CAP_CNT = sizeof(DEP_CAPS)/sizeof(DEP_CAPS[0]);\n\n/* -------- root-selection score (rules 0 \u2026 15) --------------------- */\ninline double rootScore(int rule,\n                        double Av, double sumB,\n                        double cnt, double bound){\n    switch(rule){\n        case  0: return Av;\n        case  1: return Av*Av;\n        case  2: return Av/sumB;\n        case  3: return Av*Av/sumB;\n        case  4: return Av*Av*Av/sumB;\n        case  5: return Av/cnt;\n        case  6: return Av*Av/cnt;\n        case  7: return 1.0/sumB;\n        case  8: return 1.0/cnt;\n        case  9: return -bound;\n        case 10: return Av/bound;\n        case 11: return Av*Av/bound;\n        case 12: return Av*Av*Av*Av/sumB;\n        case 13: return Av*Av*Av*Av/cnt;\n        case 14: return Av/sqrt(bound);\n        case 15: return Av*Av/sqrt(bound);\n    }\n    return 1e100;\n}\n\n/* ---------------- container of one forest ------------------------ */\nstruct Forest{\n    vector<int> parent, depth, root;\n    vector<vector<int>> children;\n};\n\n/* subtree collection */\nvoid collectSub(int v,const vector<vector<int>>& ch,\n                vector<int>& buf){\n    buf.clear(); stack<int> st; st.push(v);\n    while(!st.empty()){\n        int x=st.top(); st.pop(); buf.push_back(x);\n        for(int c:ch[x]) st.push(c);\n    }\n}\n\n/* recompute \u03a3A and maxDepth */\nvoid recomputeAgg(const vector<int>& A,const Forest& F,\n                  vector<long long>& sumA,vector<int>& mxD){\n    int N=A.size();\n    sumA.assign(N,0); mxD.assign(N,0);\n    vector<int> ord(N); iota(ord.begin(),ord.end(),0);\n    sort(ord.begin(),ord.end(),\n         [&](int a,int b){return F.depth[a]>F.depth[b];});\n    for(int v:ord){\n        sumA[v]+=A[v];\n        for(int c:F.children[v]){\n            sumA[v]+=sumA[c];\n            mxD [v]=max(mxD[v],mxD[c]+1);\n        }\n    }\n}\n\n/* depth \u2264 10 \u21d2 O(depth) */\ninline bool isAncestor(int anc,int v,const vector<int>& par){\n    while(v!=-1){\n        if(v==anc) return true;\n        v = par[v];\n    }\n    return false;\n}\n\n/* -------------------- build + post-optimise one forest ------------ */\nlong long buildForest(\n        const vector<vector<int>>& g,\n        const vector<vector<pair<int,uint8_t>>>& reach,\n        const vector<pair<int,int>>& edges,\n        const vector<int>& A,\n        int rule,int cap,\n        vector<int>& parentOut){\n    const int N=A.size();\n    Forest F;\n    F.parent.assign(N,UNASS);\n    F.depth .assign(N,-1);\n    F.root  .assign(N,-1);\n    F.children.assign(N,{});\n\n    /* ------ greedy construction ------ */\n    vector<char> covered(N,0); int uncovered=N; queue<int> q;\n    while(uncovered){\n        double bestS=1e100; int bestR=-1;\n        for(int v=0;v<N;++v) if(!covered[v]){\n            double sumB=0,bound=0; int cnt=0;\n            for(auto [u,d]:reach[v]) if(!covered[u]){\n                ++cnt; sumB+=A[u]; bound+=1LL*(d+1)*A[u];\n            }\n            double s=rootScore(rule,A[v],sumB,cnt,bound);\n            if(s<bestS){bestS=s;bestR=v;}\n        }\n        int r=bestR;\n        F.parent[r]=-1; F.depth[r]=0; F.root[r]=r;\n        covered[r]=1; --uncovered; q.push(r);\n        while(!q.empty()){\n            int v=q.front(); q.pop();\n            if(F.depth[v]==cap) continue;\n            for(int nb:g[v]) if(!covered[nb]){\n                covered[nb]=1; --uncovered;\n                F.parent[nb]=v;\n                F.depth [nb]=F.depth[v]+1;\n                F.root  [nb]=r;\n                F.children[v].push_back(nb);\n                q.push(nb);\n            }\n        }\n    }\n\n    /* ------ post-processing local moves ------ */\n    vector<long long> sumA; vector<int> mxD;\n    recomputeAgg(A,F,sumA,mxD);\n    vector<int> buf;\n    bool improved=true;\n    while(improved){\n        improved=false; long long bestGain=-1;\n        int bestSub=-1,bestPar=-1;\n        for(auto [u,v]:edges){\n            if(!isAncestor(u,v,F.parent)){\n                int delta=F.depth[v]+1-F.depth[u];\n                if(delta>0 && F.depth[v]+1+mxD[u]<=LIMH){\n                    long long gain=1LL*delta*sumA[u];\n                    if(gain>bestGain){bestGain=gain;bestSub=u;bestPar=v;}\n                }\n            }\n            if(!isAncestor(v,u,F.parent)){\n                int delta=F.depth[u]+1-F.depth[v];\n                if(delta>0 && F.depth[u]+1+mxD[v]<=LIMH){\n                    long long gain=1LL*delta*sumA[v];\n                    if(gain>bestGain){bestGain=gain;bestSub=v;bestPar=u;}\n                }\n            }\n        }\n        if(bestGain<=0) break;\n\n        int oldPar=F.parent[bestSub];\n        if(oldPar!=-1){\n            auto &vec=F.children[oldPar];\n            vec.erase(find(vec.begin(),vec.end(),bestSub));\n        }\n        F.parent[bestSub]=bestPar;\n        F.children[bestPar].push_back(bestSub);\n\n        collectSub(bestSub,F.children,buf);\n        int delta=F.depth[bestPar]+1-F.depth[bestSub];\n        int newRoot=F.root[bestPar];\n        for(int x:buf){\n            F.depth[x]+=delta;\n            F.root [x]=newRoot;\n        }\n        improved=true;\n        recomputeAgg(A,F,sumA,mxD);\n    }\n\n    long long score=0;\n    for(int v=0;v<N;++v)\n        score+=1LL*(F.depth[v]+1)*A[v];\n\n    parentOut.swap(F.parent);\n    return score;\n}\n\n/* ================================================================== */\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N,M,tmpH; if(!(cin>>N>>M>>tmpH)) return 0;\n    vector<int> A(N); for(int &x:A) cin>>x;\n\n    vector<vector<int>> g(N);\n    vector<pair<int,int>> edges; edges.reserve(M);\n    for(int i=0,u,v;i<M;++i){\n        cin>>u>>v; g[u].push_back(v); g[v].push_back(u);\n        edges.emplace_back(u,v);\n    }\n    for(int i=0,x,y;i<N;++i) cin>>x>>y;         // coords ignored\n\n    for(int v=0;v<N;++v)\n        sort(g[v].begin(),g[v].end(),\n             [&](int a,int b){return A[a]<A[b];});\n\n    /* pre-compute reach-10 */\n    vector<vector<pair<int,uint8_t>>> reach(N);\n    {\n        vector<int> dist(N); queue<int> q;\n        for(int s=0;s<N;++s){\n            fill(dist.begin(),dist.end(),-1);\n            dist[s]=0; q.push(s); reach[s].push_back({s,0});\n            while(!q.empty()){\n                int v=q.front(); q.pop();\n                if(dist[v]==LIMH) continue;\n                for(int nb:g[v]) if(dist[nb]==-1){\n                    dist[nb]=dist[v]+1;\n                    reach[s].push_back({nb,(uint8_t)dist[nb]});\n                    q.push(nb);\n                }\n            }\n        }\n    }\n\n    /* -------------- enumerate variants with time guard ------------- */\n    const int RULE_MAX=16;\n    long long bestScore=-1; vector<int> bestPar;\n    auto start = chrono::steady_clock::now();            //  TIME\n\n    for(int rule=0; rule<RULE_MAX; ++rule){\n        for(int ci=0; ci<CAP_CNT; ++ci){\n            vector<int> par;\n            long long sc=buildForest(g,reach,edges,A,\n                                      rule,DEP_CAPS[ci],par);\n            if(sc>bestScore){bestScore=sc; bestPar=std::move(par);}\n\n            /* ---- time guard -------------------------------------- */\n            auto now = chrono::steady_clock::now();      //  TIME\n            double ms = chrono::duration<double>(now-start).count();\n            if(ms > 1.80) goto OUTPUT;                  //  TIME\n        }\n    }\n\nOUTPUT:\n    for(int i=0;i<N;++i){\n        if(i) cout<<' ';\n        cout<<bestPar[i];\n    }\n    cout<<'\\n';\n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Option { int gid, dist; };              // candidate move for one Oni\nstruct Op     { char dir; int idx; };\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ------------------------------------------------ */\n    int N;                                     // 20 in every test\n    if (!(cin >> N)) return 0;\n    vector<string> G(N);\n    for (auto &s: G) cin >> s;\n\n    /* ---------- small helpers -------------------------------------------- */\n    auto clear_up    =[&](int r,int c){for(int i=0;i< r   ;++i) if(G[i][c]=='o') return false; return true;};\n    auto clear_down  =[&](int r,int c){for(int i=r+1;i<N  ;++i) if(G[i][c]=='o') return false; return true;};\n    auto clear_left  =[&](int r,int c){for(int j=0;j< c   ;++j) if(G[r][j]=='o') return false; return true;};\n    auto clear_right =[&](int r,int c){for(int j=c+1;j<N  ;++j) if(G[r][j]=='o') return false; return true;};\n\n    /* ---------- enumerate Oni -------------------------------------------- */\n    struct Oni { vector<Option> opt; };\n    vector<Oni> oni; oni.reserve(40);\n\n    for (int r=0;r<N;++r)\n        for (int c=0;c<N;++c) if (G[r][c]=='x') {\n            Oni o;\n            if (clear_up(r,c))    o.opt.push_back({ 0*20+c , r+1 });\n            if (clear_down(r,c))  o.opt.push_back({ 1*20+c , N-r });\n            if (clear_left(r,c))  o.opt.push_back({ 2*20+r , c+1 });\n            if (clear_right(r,c)) o.opt.push_back({ 3*20+r , N-c });\n            oni.push_back(move(o));\n        }\n    const int M = oni.size();                 // always 40\n    const int Gcnt = 80;                      // 4*20 groups\n\n    /* ---------- dist table ------------------------------------------------ */\n    vector<array<int,Gcnt>> dist(M);\n    for (int i=0;i<M;++i){ dist[i].fill(0); for(auto&op:oni[i].opt) dist[i][op.gid]=op.dist; }\n\n    /* ---------- initial assignment : shortest safe dir ------------------- */\n    vector<int> assign(M,-1);                 // gid of each Oni\n    array<vector<int>,Gcnt> members;          // members per group\n    array<int,Gcnt>         gMax{};           // max distance per group\n\n    for (int id=0; id<M; ++id){\n        int bestD=1e9,bestG=-1;\n        for(auto&op:oni[id].opt)\n            if (op.dist<bestD){bestD=op.dist;bestG=op.gid;}\n        assign[id]=bestG;\n        members[bestG].push_back(id);\n        gMax[bestG]=max(gMax[bestG],bestD);\n    }\n\n    /* ---------- tiny hill-climber (same as before) ----------------------- */\n    std::mt19937 rng(1234567);\n    bool better=true;\n    while(better){\n        better=false;\n        vector<int> order(M); iota(order.begin(),order.end(),0);\n        shuffle(order.begin(),order.end(),rng);\n\n        for(int id:order){\n            int g0=assign[id], d0=dist[id][g0], old0=gMax[g0];\n            int new0;\n            if (d0<old0) new0=old0;\n            else{\n                new0=0;\n                for(int o:members[g0]) if(o!=id) new0=max(new0,dist[o][g0]);\n            }\n            for(auto&op:oni[id].opt) if(op.gid!=g0){\n                int g1=op.gid, d1=op.dist, old1=gMax[g1];\n                int new1=max(old1,d1);\n                if (2*(new0-old0)+2*(new1-old1)<0){\n                    /* apply move */\n                    auto &v=members[g0];\n                    v.erase(remove(v.begin(),v.end(),id),v.end());\n                    gMax[g0]=new0;\n                    members[g1].push_back(id);\n                    gMax[g1]=new1;\n                    assign[id]=g1;\n                    better=true;\n                    break;\n                }\n            }\n        }\n    }\n\n    /* ---------- pick the no-return group --------------------------------- */\n    int lastG=-1, lastD=-1;\n    for(int g=0;g<Gcnt;++g) if(gMax[g]>lastD){lastD=gMax[g]; lastG=g;}\n\n    /* ---------- prepare operation list ----------------------------------- */\n    const char OUT[4]={'U','D','L','R'};\n    const char REV[4]={'D','U','R','L'};\n    vector<Op> ops; ops.reserve(1600);\n\n    auto emit=[&](char d,int idx,int cnt){ for(int k=0;k<cnt;++k) ops.push_back({d,idx}); };\n\n    /* 1. all normal groups (out + back) */\n    for(int g=0; g<Gcnt; ++g) if(g!=lastG && gMax[g]){\n        int dir=g/20, line=g%20, d=gMax[g];\n        emit(OUT[dir],line,d);\n        emit(REV[dir],line,d);\n    }\n\n    /* 2. final group (out only) */\n    if(lastD>0){\n        int dir=lastG/20, line=lastG%20;\n        emit(OUT[dir],line,lastD);\n    }\n\n    /* ---------- safety guard (theory says ops \u2264 1 599) ------------------- */\n    const int LIMIT = 4*N*N;                 // 1 600\n    if((int)ops.size()>LIMIT) ops.resize(LIMIT);\n\n    /* ---------- output --------------------------------------------------- */\n    for(auto&o:ops) cout<<o.dir<<' '<<o.idx<<'\\n';\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nconstexpr int N    = 100;\nconstexpr int L    = 500'000;\nconstexpr int E    = 2 * N;          // 200 edges\nconstexpr int STEP = L / E;          // 2 500\n\n/* ------------------------------------------------------------ */\n/*  exact DP: k_i \u2208 {0..4}, \u03a3k = 200, minimise \u03a3|T_i-2500 k_i|  */\nvector<int> optimal_indeg(const array<int,N>& T) {\n    const int INF = 1e9;\n    static int dp[N + 1][E + 1];\n    static uint8_t prv[N + 1][E + 1];\n\n    dp[0][0] = 0;\n    for (int s = 1; s <= E; ++s) dp[0][s] = INF;\n\n    for (int i = 0; i < N; ++i) {\n        for (int s = 0; s <= E; ++s) dp[i + 1][s] = INF;\n        for (int s = 0; s <= E; ++s) if (dp[i][s] != INF) {\n            for (int k = 0; k <= 4 && s + k <= E; ++k) {\n                int v = dp[i][s] + abs(T[i] - STEP * k);\n                if (v < dp[i + 1][s + k]) {\n                    dp[i + 1][s + k] = v;\n                    prv[i + 1][s + k] = k;\n                }\n            }\n        }\n    }\n    vector<int> k(N);\n    int s = E;\n    for (int i = N; i--;) { k[i] = prv[i + 1][s]; s -= k[i]; }\n    return k;\n}\n\n/* ------------------------------------------------------------ */\n/*  full 500 000-week simulation (fast inner loop)              */\ninline ll simulate(const int odd[N], const int even[N],\n                   const array<int,N>& T)\n{\n    uint32_t cnt[N] = {};\n    uint8_t  par[N] = {};               // 0: even \u2192 use even[], 1: odd \u2192 odd[]\n    int cur = 0;\n\n    for (int w = 0; w < L; ++w) {\n        ++cnt[cur];\n        par[cur] ^= 1;\n        cur = (par[cur] ? odd[cur] : even[cur]);\n    }\n    ll err = 0;\n    for (int i = 0; i < N; ++i) err += llabs((ll)cnt[i] - T[i]);\n    return err;\n}\n\n/* ------------------------------------------------------------ */\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int dummyN, dummyL;\n    if (!(cin >> dummyN >> dummyL)) return 0;\n\n    array<int,N> T{};\n    for (int &x : T) cin >> x;\n\n    /* ---- decide indegrees optimally ---- */\n    vector<int> indeg = optimal_indeg(T);\n\n    /* ---- initial random graph (multiset shuffle) ---- */\n    vector<int> pool; pool.reserve(E);\n    for (int v = 0; v < N; ++v)\n        for (int c = 0; c < indeg[v]; ++c) pool.push_back(v);\n\n    mt19937 rng((uint32_t)chrono::steady_clock::now()\n                    .time_since_epoch().count());\n    shuffle(pool.begin(), pool.end(), rng);\n\n    int odd[N], even[N];                // two destinations per vertex\n    for (int v = 0; v < N; ++v) {\n        odd[v]  = pool[2*v];            // first copy = a_v (used on odd t)\n        even[v] = pool[2*v+1];          // second     = b_v (used on even t)\n    }\n\n    /* repair \u201cdouble self-loop\u201d traps */\n    for (int v = 0; v < N; ++v)\n        if (odd[v] == v && even[v] == v) {\n            for (int u = 0; u < N; ++u) if (u != v &&\n                 odd[u] != u && even[u] != u) {\n                swap(even[v], even[u]);\n                break;\n            }\n        }\n\n    ll bestErr = simulate(odd, even, T);\n    int bestOdd[N], bestEven[N];\n    memcpy(bestOdd,  odd,  sizeof odd);\n    memcpy(bestEven, even, sizeof even);\n\n    /* ---- local random-swap search (400 iterations) ---- */\n    const int MAX_ITERS = 400;\n    for (int it = 0; it < MAX_ITERS; ++it) {\n        int e1 = rng() % E, e2;\n        do e2 = rng() % E; while (e2 == e1);\n\n        int v1 = e1 / 2, pos1 = e1 & 1;\n        int v2 = e2 / 2, pos2 = e2 & 1;\n\n        int *p1 = (pos1 ? &even[v1] : &odd[v1]);\n        int *p2 = (pos2 ? &even[v2] : &odd[v2]);\n        std::swap(*p1, *p2);\n\n        /* prevent creation of a new trap */\n        if ((odd[v1] == v1 && even[v1] == v1) ||\n            (odd[v2] == v2 && even[v2] == v2)) {\n            std::swap(*p1, *p2);\n            continue;\n        }\n\n        ll err = simulate(odd, even, T);\n        if (err < bestErr) {\n            bestErr = err;\n            memcpy(bestOdd,  odd,  sizeof odd);\n            memcpy(bestEven, even, sizeof even);\n        } else {\n            std::swap(*p1, *p2);        // revert\n        }\n    }\n\n    /* ---- output best plan ---- */\n    for (int v = 0; v < N; ++v)\n        cout << bestOdd[v] << ' ' << bestEven[v] << '\\n';\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*------------------------------------------------------------------*/\nstatic inline uint64_t hilbert(int x,int y){  // 14-bit curve\n    const int B = 14;\n    uint64_t d = 0;\n    for (int s = B - 1; s >= 0; --s) {\n        int rx = (x >> s) & 1, ry = (y >> s) & 1;\n        d = (d << 2) | (rx ^ ry) | (ry << 1);\n        if (!ry) {\n            if (rx) { x = ((1 << B) - 1) - x; y = ((1 << B) - 1) - y; }\n            swap(x, y);\n        }\n    }\n    return d;\n}\n/*------------------------------------------------------------------*/\nstruct City{\n    int id,lx,rx,ly,ry,cx,cy;\n    uint64_t key[4];             // Hilbert keys for the 4 orientations\n};\nstatic inline int64_t cdist2(const City&a,const City&b){\n    int64_t dx=a.cx-b.cx, dy=a.cy-b.cy; return dx*dx+dy*dy;\n}\n/*------------------------------------------------------------------*/\nstruct DSU{\n    vector<int> p,sz;\n    DSU(int n=0){init(n);}\n    void init(int n){ p.resize(n); sz.assign(n,1); iota(p.begin(),p.end(),0);}\n    int  find(int v){ return p[v]==v? v: p[v]=find(p[v]); }\n    bool unite(int a,int b){\n        a=find(a); b=find(b); if(a==b) return false;\n        if(sz[a]<sz[b]) swap(a,b);\n        p[b]=a; sz[a]+=sz[b]; return true;\n    }\n};\n/*------------------------------------------------------------------*/\nvoid ask(const vector<int>& S, vector<pair<int,int>>& out){\n    cout<<\"? \"<<S.size();\n    for(int v:S) cout<<' '<<v;\n    cout<<'\\n'<<flush;\n    for(int i=0;i<(int)S.size()-1;++i){\n        int a,b; cin>>a>>b; out.emplace_back(a,b);\n    }\n}\n/*==================================================================*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    /* ---------- read input ---------------------------------------- */\n    int N,M,Q,L,W; cin>>N>>M>>Q>>L>>W;\n    vector<int> G(M); for(int &g:G) cin>>g;\n\n    vector<City> city(N);\n    for(int i=0;i<N;++i){\n        int lx,rx,ly,ry; cin>>lx>>rx>>ly>>ry;\n        int cx=(lx+rx)/2, cy=(ly+ry)/2;\n        int sx=(cx*16383)/10000, sy=(cy*16383)/10000;\n        /* 4 rotations of the centre */\n        int tx[4]={ cx, 10000-cy, 10000-cx,        cy };\n        int ty[4]={ cy,      cx,  10000-cy, 10000-cx};\n        uint64_t k[4];\n        for(int o=0;o<4;++o)\n            k[o]=hilbert((tx[o]*16383)/10000, (ty[o]*16383)/10000);\n        city[i]={i,lx,rx,ly,ry,cx,cy,{k[0],k[1],k[2],k[3]}};\n    }\n\n    /* centre distance matrix (int fits) */\n    static int dist2[800][800];\n    for(int i=0;i<N;++i){\n        dist2[i][i]=0;\n        for(int j=i+1;j<N;++j)\n            dist2[i][j]=dist2[j][i]=(int)cdist2(city[i],city[j]);\n    }\n\n    /* -------------------- size-2 groups --------------------------- */\n    vector<int> twoIdx;\n    for(int i=0;i<M;++i) if(G[i]==2) twoIdx.push_back(i);\n    const int P=twoIdx.size();\n\n    /* greedy matching */\n    struct Edge{int u,v,d;};\n    vector<Edge> el; el.reserve(N*(N-1)/2);\n    for(int i=0;i<N;++i) for(int j=i+1;j<N;++j)\n        el.push_back({i,j,dist2[i][j]});\n    sort(el.begin(),el.end(),[](auto&a,auto&b){return a.d<b.d;});\n    vector<int> mate(N,-1);\n    vector<pair<int,int>> pairs; pairs.reserve(P);\n    for(auto &e:el){\n        if((int)pairs.size()==P) break;\n        if(mate[e.u]==-1 && mate[e.v]==-1){\n            mate[e.u]=e.v; mate[e.v]=e.u;\n            pairs.emplace_back(e.u,e.v);\n        }\n    }\n    /* mild 2-opt if we have at least two pairs */\n    if(P>1){\n        mt19937 rng(1);\n        for(int it=0; it<5000; ++it){\n            int a=rng()%P, b=rng()%P; if(a==b) continue;\n            int u1=pairs[a].first ,v1=pairs[a].second;\n            int u2=pairs[b].first ,v2=pairs[b].second;\n            int cur=dist2[u1][v1]+dist2[u2][v2];\n            int alt1=dist2[u1][u2]+dist2[v1][v2];\n            int alt2=dist2[u1][v2]+dist2[v1][u2];\n            if(alt1<cur){ pairs[a]={u1,u2}; pairs[b]={v1,v2}; }\n            else if(alt2<cur){ pairs[a]={u1,v2}; pairs[b]={v1,u2}; }\n        }\n    }\n\n    /* mark used */\n    vector<char> used(N,0);\n    vector<vector<int>> groups(M);\n    vector<vector<pair<int,int>>> roads(M);\n    for(size_t k=0;k<twoIdx.size();++k){\n        int gid=twoIdx[k];\n        groups[gid]={pairs[k].first,pairs[k].second};\n        roads [gid].push_back({pairs[k].first,pairs[k].second});\n        used[pairs[k].first]=used[pairs[k].second]=1;\n    }\n\n    /* ---------------- orientation search for remaining cities ------ */\n    vector<int> restIdx;\n    for(int i=0;i<M;++i) if(G[i]!=2) restIdx.push_back(i);\n    sort(restIdx.begin(),restIdx.end(),\n         [&](int a,int b){ return G[a]>G[b]; });\n\n    int bestO=0; int64_t bestScore=LLONG_MAX;\n\n    vector<int> restCities;\n    for(int v=0;v<N;++v) if(!used[v]) restCities.push_back(v);\n\n    for(int o=0;o<4;++o){\n        vector<int> order=restCities;\n        sort(order.begin(),order.end(),\n             [&](int a,int b){return city[a].key[o]<city[b].key[o];});\n        size_t pos=0; int64_t score=0;\n        for(int gid:restIdx){\n            int need=G[gid];\n            int prev=order[pos]; ++pos;\n            for(int k=1;k<need;++k,++pos){\n                int cur=order[pos];\n                score+=dist2[prev][cur];\n                prev=cur;\n            }\n        }\n        if(score<bestScore){ bestScore=score; bestO=o; }\n    }\n\n    /* ------------ build non-size-2 groups with best orientation ---- */\n    vector<int> order=restCities;\n    sort(order.begin(),order.end(),\n         [&](int a,int b){return city[a].key[bestO]<city[b].key[bestO];});\n    size_t pos=0;\n    for(int gid:restIdx){\n        int need=G[gid];\n        groups[gid].assign(order.begin()+pos, order.begin()+pos+need);\n        pos+=need;\n    }\n\n#ifndef NDEBUG\n    {int cnt=0; for(int i=0;i<M;++i) cnt+=groups[i].size(); assert(cnt==N);}\n#endif\n\n    /* ----------------------- road construction --------------------- */\n    int qLeft=Q;\n\n    /* priority 1: large groups (>L) */\n    vector<int> big;\n    for(int i=0;i<M;++i) if((int)groups[i].size()>L) big.push_back(i);\n    sort(big.begin(),big.end(),\n         [&](int a,int b){return groups[a].size()>groups[b].size();});\n\n    vector<int> id2loc(N);\n\n    for(int gi:big){\n        auto &g=groups[gi]; int n=g.size();\n\n        /* split into \u2264L blocks */\n        vector<vector<int>> blocks;\n        for(int i=0;i<n;){\n            int rest=n-i, sz=min(L,rest);\n            if(rest-sz==1) --sz;\n            blocks.emplace_back(g.begin()+i, g.begin()+i+sz);\n            i+=sz;\n        }\n        int B=blocks.size();\n\n        /* internal block MSTs */\n        for(auto &blk:blocks){\n            if(qLeft){ ask(blk,roads[gi]); --qLeft; }\n            else{\n                int m=blk.size();\n                vector<int64_t> best(m,LLONG_MAX); vector<int> par(m,-1),done(m,0);\n                best[0]=0;\n                for(int step=0; step<m; ++step){\n                    int v=-1; int64_t bd=LLONG_MAX;\n                    for(int i=0;i<m;++i) if(!done[i] && best[i]<bd){bd=best[i]; v=i;}\n                    done[v]=1;\n                    if(par[v]!=-1) roads[gi].push_back({blk[v],blk[par[v]]});\n                    for(int u=0;u<m;++u) if(!done[u]){\n                        int64_t d=cdist2(city[blk[v]],city[blk[u]]);\n                        if(d<best[u]){ best[u]=d; par[u]=v; }\n                    }\n                }\n            }\n        }\n\n        /* connect blocks */\n        for(int i=0;i<n;++i) id2loc[g[i]]=i;\n        DSU dsu(n);\n        for(auto [a,b]:roads[gi]) dsu.unite(id2loc[a],id2loc[b]);\n\n        struct Cand{int u,v; int64_t d;};\n        vector<Cand> cand; cand.reserve(B*(B-1)/2);\n        for(int i=0;i<B;++i) for(int j=i+1;j<B;++j){\n            int bestU=-1,bestV=-1; int64_t best=LLONG_MAX;\n            for(int u:blocks[i]) for(int v:blocks[j]){\n                int64_t d=cdist2(city[u],city[v]);\n                if(d<best){best=d; bestU=u; bestV=v;}\n            }\n            cand.push_back({bestU,bestV,best});\n        }\n        sort(cand.begin(),cand.end(),[](auto&a,auto&b){return a.d<b.d;});\n\n        for(auto &c:cand){\n            if((int)roads[gi].size()==n-1) break;\n            if(!dsu.unite(id2loc[c.u],id2loc[c.v])) continue;\n            if(qLeft){ vector<pair<int,int>> tmp; ask({c.u,c.v},tmp); --qLeft;\n                       roads[gi].push_back(tmp[0]);\n            }else     roads[gi].push_back({c.u,c.v});\n        }\n        for(int i=0;i<n && (int)roads[gi].size()<n-1;++i)\n            for(int j=i+1;j<n && (int)roads[gi].size()<n-1;++j)\n                if(dsu.unite(i,j)) roads[gi].push_back({g[i],g[j]});\n    }\n\n    /* priority 2: groups of size 3\u2026L  (use remaining queries) */\n    for(int gi=0; gi<M; ++gi){\n        int sz=groups[gi].size();\n        if(sz<3 || sz> L) continue;\n        if(qLeft){ ask(groups[gi],roads[gi]); --qLeft; }\n        else{\n            vector<int64_t> best(sz,LLONG_MAX); vector<int> par(sz,-1),done(sz,0);\n            best[0]=0;\n            for(int step=0; step<sz; ++step){\n                int v=-1; int64_t bd=LLONG_MAX;\n                for(int i=0;i<sz;++i) if(!done[i] && best[i]<bd){bd=best[i]; v=i;}\n                done[v]=1;\n                if(par[v]!=-1) roads[gi].push_back({groups[gi][v],groups[gi][par[v]]});\n                for(int u=0;u<sz;++u) if(!done[u]){\n                    int64_t d=cdist2(city[groups[gi][v]],city[groups[gi][u]]);\n                    if(d<best[u]){ best[u]=d; par[u]=v; }\n                }\n            }\n        }\n    }\n\n#ifndef NDEBUG\n    for(int i=0;i<M;++i) assert(roads[i].size()==groups[i].size()-1);\n#endif\n\n    /* ------------------- output ------------------------------------ */\n    cout<<\"!\\n\";\n    for(int i=0;i<M;++i){\n        for(size_t k=0;k<groups[i].size();++k){\n            if(k) cout<<' ';\n            cout<<groups[i][k];\n        }\n        cout<<'\\n';\n        for(auto [a,b]:roads[i]) cout<<a<<' '<<b<<'\\n';\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\n/*------------------------------------------------------------*/\n/*  Geometry helpers                                          */\n/*------------------------------------------------------------*/\nconstexpr int N  = 20;\nconstexpr int SZ = N * N;\nconst int dx[4]   = {-1, 1, 0, 0};\nconst int dy[4]   = { 0, 0,-1, 1};\nconst char DIR[4] = {'U','D','L','R'};\ninline int  id(int r,int c){ return r * N + c; }\ninline auto rc(int v){ return pair{v / N, v % N}; }\ninline int  dirIdx(char c){ for(int i=0;i<4;++i) if(DIR[i]==c) return i; return -1; }\ninline int  opp(int d){ return d ^ 1; }               // 0<->1, 2<->3\n\nstruct Step{ char act, dir; };\n\n/*------------------------------------------------------------*/\n/*  BFS \u2013 distance only                                        */\n/*------------------------------------------------------------*/\nint bfsDist(const array<bool,SZ>& wall,int s,int g)\n{\n    static array<int,SZ> dist;\n    dist.fill(-1);\n    queue<int> q; dist[s]=0; q.push(s);\n\n    while(!q.empty()){\n        int v=q.front(); q.pop();\n        if(v==g) return dist[v];\n        auto [r,c]=rc(v);\n\n        for(int d=0; d<4; ++d){\n            int nr=r+dx[d], nc=c+dy[d];\n            if(0<=nr && nr<N && 0<=nc && nc<N && !wall[id(nr,nc)]){\n                int nv=id(nr,nc);\n                if(dist[nv]==-1){ dist[nv]=dist[v]+1; q.push(nv); }\n            }\n            int sr=r, sc=c;\n            while(true){\n                int tr=sr+dx[d], tc=sc+dy[d];\n                if(tr<0||tr>=N||tc<0||tc>=N||wall[id(tr,tc)]) break;\n                sr=tr; sc=tc;\n            }\n            int sv=id(sr,sc);\n            if(sv!=v && dist[sv]==-1){ dist[sv]=dist[v]+1; q.push(sv); }\n        }\n    }\n    return 1e9;                                    // unreachable\n}\n\n/*------------------------------------------------------------*/\n/*  BFS \u2013 full path                                            */\n/*------------------------------------------------------------*/\nvector<Step> bfsPath(const array<bool,SZ>& wall,int s,int g)\n{\n    static array<int,SZ> dist, prv;\n    static array<char,SZ> pact,pdir;\n    dist.fill(-1);\n    queue<int> q; dist[s]=0; q.push(s);\n\n    while(!q.empty()){\n        int v=q.front(); q.pop();\n        if(v==g) break;\n        auto [r,c]=rc(v);\n\n        for(int d=0; d<4; ++d){\n            char dc=DIR[d];\n            int nr=r+dx[d], nc=c+dy[d];\n            if(0<=nr && nr<N && 0<=nc && nc<N && !wall[id(nr,nc)]){\n                int nv=id(nr,nc);\n                if(dist[nv]==-1){\n                    dist[nv]=dist[v]+1; prv[nv]=v;\n                    pact[nv]='M'; pdir[nv]=dc; q.push(nv);\n                }\n            }\n            int sr=r, sc=c;\n            while(true){\n                int tr=sr+dx[d], tc=sc+dy[d];\n                if(tr<0||tr>=N||tc<0||tc>=N||wall[id(tr,tc)]) break;\n                sr=tr; sc=tc;\n            }\n            int sv=id(sr,sc);\n            if(sv!=v && dist[sv]==-1){\n                dist[sv]=dist[v]+1; prv[sv]=v;\n                pact[sv]='S'; pdir[sv]=dc; q.push(sv);\n            }\n        }\n    }\n    vector<Step> path;\n    for(int v=g; v!=s; v=prv[v]) path.push_back({pact[v],pdir[v]});\n    reverse(path.begin(),path.end());\n    return path;\n}\n\n/*------------------------------------------------------------*/\n/*  look-ahead cost                                           */\n/*------------------------------------------------------------*/\nint horizonCost(const array<bool,SZ>& wall,\n                const vector<int>& ord,int idx,\n                int pos,int H)\n{\n    int cost=0, m=ord.size();\n    for(int k=idx; k<min(m,idx+H); ++k){\n        int nxt=ord[k];\n        cost += bfsDist(wall,pos,nxt);\n        pos  = nxt;\n    }\n    return cost;\n}\n\n/*------------------------------------------------------------*/\n/*  apply one action to internal state                         */\n/*------------------------------------------------------------*/\nvoid applyStep(const Step& st,int& pos,array<bool,SZ>& wall)\n{\n    int d = dirIdx(st.dir);\n    auto [r,c]=rc(pos);\n    if(st.act=='M'){\n        pos = id(r+dx[d], c+dy[d]);\n    }else if(st.act=='A'){\n        wall[id(r+dx[d], c+dy[d])] = true;        // only add\n    }else{                                        // 'S'\n        while(true){\n            int tr=r+dx[d], tc=c+dy[d];\n            if(tr<0||tr>=N||tc<0||tc>=N||wall[id(tr,tc)]) break;\n            r=tr; c=tc;\n        }\n        pos=id(r,c);\n    }\n}\n\n/*------------------------------------------------------------*/\n/*  main                                                       */\n/*------------------------------------------------------------*/\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int Nread, M;\n    if(!(cin>>Nread>>M)) return 0;\n\n    vector<int> ord; ord.reserve(M);\n    for(int i=0;i<M;++i){\n        int r,c; cin>>r>>c;\n        ord.push_back(id(r,c));\n    }\n\n    array<bool,SZ> wall{};                       /* permanent blocks */\n    vector<char>   future(SZ,false);             /* yet-to-visit     */\n    for(int i=1;i<M;++i) future[ord[i]] = true;\n\n    vector<Step> answer;\n    int cur = ord[0];\n    constexpr int H = 12;                        /* look-ahead depth */\n\n    for(int idx=1; idx<M; ++idx){\n        int goal = ord[idx];\n\n        /* -------- baseline ------------------------------------ */\n        vector<Step> base = bfsPath(wall,cur,goal);\n        int bestCost = (int)base.size()\n                     + horizonCost(wall,ord,idx,goal,H-1);\n        vector<Step> bestPre;\n        array<bool,SZ> bestWall = wall;\n        int bestStart = cur;\n\n        auto [r,c]=rc(cur);\n\n        /* -------- candidate 1: add wall on neighbour ---------- */\n        for(int d=0; d<4; ++d){\n            int nr=r+dx[d], nc=c+dy[d];\n            if(nr<0||nr>=N||nc<0||nc>=N) continue;\n            int nid=id(nr,nc);\n            if(future[nid] || wall[nid]) continue;\n\n            wall[nid]=true;\n            int cost = 1 + bfsDist(wall,cur,goal)\n                      + horizonCost(wall,ord,idx,goal,H-1);\n            if(cost < bestCost){\n                bestCost = cost;\n                bestPre  = {{'A',DIR[d]}};\n                bestWall = wall;\n                bestStart = cur;\n            }\n            wall[nid]=false;\n        }\n\n        /* -------- candidate 2: stopper on current square ------ */\n        for(int d=0; d<4; ++d){\n            int nr=r+dx[d], nc=c+dy[d];\n            if(nr<0||nr>=N||nc<0||nc>=N) continue;\n            int nid=id(nr,nc);\n            if(wall[nid] || future[nid] || nid==goal) continue;\n            if(wall[cur]) continue;\n\n            wall[cur]=true;\n            int cost = 2 + bfsDist(wall,nid,goal)\n                      + horizonCost(wall,ord,idx,goal,H-1);\n            if(cost < bestCost){\n                bestCost = cost;\n                bestPre  = {{'M',DIR[d]},{'A',DIR[opp(d)]}};\n                bestWall = wall;\n                bestStart= nid;\n            }\n            wall[cur]=false;\n        }\n\n        /* -------- candidate 3: M neighbour + A secondary ------ */\n        for(int d1=0; d1<4; ++d1){\n            int nr=r+dx[d1], nc=c+dy[d1];\n            if(nr<0||nr>=N||nc<0||nc>=N) continue;\n            int nid=id(nr,nc);\n            if(wall[nid]) continue;                     /* must step onto free */\n            if(future[nid]) continue;\n\n            for(int d2=0; d2<4; ++d2){\n                int ar=nr+dx[d2], ac=nc+dy[d2];\n                if(ar<0||ar>=N||ac<0||ac>=N) continue;\n                int aid=id(ar,ac);\n                if(wall[aid] || future[aid] || aid==goal) continue;\n\n                wall[aid]=true;\n                int cost = 2 + bfsDist(wall,nid,goal)\n                          + horizonCost(wall,ord,idx,goal,H-1);\n                if(cost < bestCost){\n                    bestCost = cost;\n                    bestPre  = {{'M',DIR[d1]},{'A',DIR[d2]}};\n                    bestWall = wall;\n                    bestStart= nid;\n                }\n                wall[aid]=false;\n            }\n        }\n\n        /* -------- emit chosen pre-actions  -------------------- */\n        int pos = cur;\n        for(const Step& st: bestPre){\n            answer.push_back(st);\n            applyStep(st,pos,wall);\n        }\n        cur = pos;                                    /* now == bestStart */\n        wall = bestWall;                              /* permanent walls */\n\n        /* -------- segment path ------------------------------- */\n        vector<Step> seg = bfsPath(wall,cur,goal);\n        answer.insert(answer.end(),seg.begin(),seg.end());\n        for(const Step& st: seg) applyStep(st,cur,wall);\n\n        future[goal] = false;                         /* visited */\n    }\n\n    /* -------- output ---------------------------------------- */\n    for(const Step& st: answer) cout<<st.act<<' '<<st.dir << '\\n';\n    return 0;\n}"}}}