{"model_name":"claude-4.7-opus-no-thinking","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> X, Y, R;\nstruct Rect { int a, b, c, d; };\nvector<Rect> rects;\nconst int W = 10000;\n\ndouble score_one(int i) {\n    auto& r = rects[i];\n    if (X[i] < r.a || X[i] >= r.c || Y[i] < r.b || Y[i] >= r.d) return 0;\n    long long s = (long long)(r.c - r.a) * (r.d - r.b);\n    double mn = min((long long)R[i], s);\n    double mx = max((long long)R[i], s);\n    double t = 1 - mn/mx;\n    return 1 - t*t;\n}\n\nbool overlap(const Rect& x, const Rect& y) {\n    return !(x.c <= y.a || y.c <= x.a || x.d <= y.b || y.d <= x.b);\n}\n\nbool conflicts(int i, const Rect& nr) {\n    for (int j = 0; j < n; j++) if (j != i) {\n        if (overlap(nr, rects[j])) return true;\n    }\n    return false;\n}\n\nint main() {\n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    rects.resize(n);\n    for (int i = 0; i < n; i++) {\n        cin >> X[i] >> Y[i] >> R[i];\n        rects[i] = {X[i], Y[i], X[i]+1, Y[i]+1};\n    }\n    \n    auto start = chrono::steady_clock::now();\n    auto elapsed = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - start).count();\n    };\n    \n    mt19937 rng(42);\n    \n    while (elapsed() < 4.7) {\n        int i = rng() % n;\n        auto& r = rects[i];\n        double old_sc = score_one(i);\n        long long curS = (long long)(r.c - r.a) * (r.d - r.b);\n        \n        int move = rng() % 8; // 4 expand, 4 shrink\n        Rect saved = r;\n        int amt = 1 + rng() % 50;\n        \n        if (move == 0) r.a = max(0, r.a - amt);\n        else if (move == 1) r.c = min(W, r.c + amt);\n        else if (move == 2) r.b = max(0, r.b - amt);\n        else if (move == 3) r.d = min(W, r.d + amt);\n        else if (move == 4) r.a = min(X[i], r.a + amt);\n        else if (move == 5) r.c = max(X[i]+1, r.c - amt);\n        else if (move == 6) r.b = min(Y[i], r.b + amt);\n        else r.d = max(Y[i]+1, r.d - amt);\n        \n        if (r.a >= r.c || r.b >= r.d || r.a < 0 || r.b < 0 || r.c > W || r.d > W) {\n            r = saved; continue;\n        }\n        if (X[i] < r.a || X[i] >= r.c || Y[i] < r.b || Y[i] >= r.d) {\n            r = saved; continue;\n        }\n        if (move < 4 && conflicts(i, r)) {\n            r = saved; continue;\n        }\n        double new_sc = score_one(i);\n        if (new_sc < old_sc - 1e-12) r = saved;\n    }\n    \n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << \" \" << rects[i].b << \" \" << rects[i].c << \" \" << rects[i].d << \"\\n\";\n    }\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nint N = 50;\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dch[] = {'U', 'D', 'L', 'R'};\n\ndouble getTime() {\n    return (double)clock() / CLOCKS_PER_SEC;\n}\n\nmt19937 rng(98765);\n\nvector<pair<int,int>> path;\nvector<int> dirs;\nvector<bool> usedTile;\nint totalScore;\nint M;\n\nint bestTailScore;\nvector<int> bestTailDirs;\nvector<int> curTailDirs;\nint curTailScore;\ndouble dfsDeadline;\nbool timeUp;\nint dfsCount;\n\nvoid dfs(int r, int c) {\n    dfsCount++;\n    if ((dfsCount & 4095) == 0) {\n        if (getTime() > dfsDeadline) { timeUp = true; return; }\n    }\n    if (timeUp) return;\n    \n    if (curTailScore > bestTailScore) {\n        bestTailScore = curTailScore;\n        bestTailDirs = curTailDirs;\n    }\n    \n    int order[4] = {0,1,2,3};\n    for (int k = 3; k > 0; k--) {\n        int j = rng() % (k+1);\n        swap(order[k], order[j]);\n    }\n    for (int k = 0; k < 4; k++) {\n        int d = order[k];\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = t[nr][nc];\n        if (usedTile[tid]) continue;\n        usedTile[tid] = true;\n        curTailScore += p[nr][nc];\n        curTailDirs.push_back(d);\n        dfs(nr, nc);\n        curTailDirs.pop_back();\n        curTailScore -= p[nr][nc];\n        usedTile[tid] = false;\n        if (timeUp) return;\n    }\n}\n\nint main() {\n    cin >> si >> sj;\n    M = 0;\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) {\n            cin >> t[i][j];\n            M = max(M, t[i][j]+1);\n        }\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++)\n            cin >> p[i][j];\n    \n    usedTile.assign(M, false);\n    \n    path.push_back({si, sj});\n    dirs.clear();\n    usedTile[t[si][sj]] = true;\n    totalScore = p[si][sj];\n    \n    {\n        int r = si, c = sj;\n        while (true) {\n            vector<int> cand;\n            for (int d = 0; d < 4; d++) {\n                int nr = r+dr[d], nc = c+dc[d];\n                if (nr<0||nr>=N||nc<0||nc>=N) continue;\n                if (usedTile[t[nr][nc]]) continue;\n                cand.push_back(d);\n            }\n            if (cand.empty()) break;\n            int d = cand[rng()%cand.size()];\n            int nr = r+dr[d], nc = c+dc[d];\n            usedTile[t[nr][nc]] = true;\n            totalScore += p[nr][nc];\n            path.push_back({nr,nc});\n            dirs.push_back(d);\n            r = nr; c = nc;\n        }\n    }\n    \n    double TIME_LIMIT = 1.9;\n    \n    int iter = 0;\n    while (getTime() < TIME_LIMIT) {\n        iter++;\n        int L = path.size();\n        // Bias toward earlier indices for bigger impact\n        int i;\n        if (rng() % 3 == 0) {\n            i = rng() % L;\n        } else {\n            // prefer near end third to do small local changes? Actually, prefer varying\n            i = rng() % L;\n        }\n        \n        int oldSuffixScore = 0;\n        for (int k = i; k < L; k++) oldSuffixScore += p[path[k].first][path[k].second];\n        \n        for (int k = i+1; k < L; k++) {\n            usedTile[t[path[k].first][path[k].second]] = false;\n        }\n        \n        bestTailScore = p[path[i].first][path[i].second];\n        bestTailDirs.clear();\n        curTailScore = bestTailScore;\n        curTailDirs.clear();\n        timeUp = false;\n        dfsCount = 0;\n        \n        double remaining = TIME_LIMIT - getTime();\n        double budget = min(0.02, remaining * 0.02);\n        if (budget < 0.001) budget = 0.001;\n        dfsDeadline = getTime() + budget;\n        \n        dfs(path[i].first, path[i].second);\n        \n        if (bestTailScore >= oldSuffixScore) {\n            path.resize(i+1);\n            dirs.resize(i);\n            int r = path[i].first, c = path[i].second;\n            for (int d : bestTailDirs) {\n                int nr = r+dr[d], nc = c+dc[d];\n                path.push_back({nr,nc});\n                dirs.push_back(d);\n                usedTile[t[nr][nc]] = true;\n                r = nr; c = nc;\n            }\n            totalScore = totalScore - oldSuffixScore + bestTailScore;\n        } else {\n            for (int k = i+1; k < L; k++) {\n                usedTile[t[path[k].first][path[k].second]] = true;\n            }\n        }\n    }\n    \n    string out;\n    for (int d : dirs) out += dch[d];\n    cout << out << endl;\n    \n    cerr << \"Score: \" << totalScore << \" Iter: \" << iter << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\ndouble h[30][29];\ndouble v[29][30];\n\nint main() {\n    for (int i = 0; i < 30; i++) for (int j = 0; j < 29; j++) h[i][j] = 5000;\n    for (int i = 0; i < 29; i++) for (int j = 0; j < 30; j++) v[i][j] = 5000;\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n        \n        vector<vector<double>> dist(30, vector<double>(30, 1e18));\n        vector<vector<int>> prv(30, vector<int>(30, -1));\n        priority_queue<tuple<double,int,int>, vector<tuple<double,int,int>>, greater<>> pq;\n        dist[si][sj] = 0;\n        pq.push({0.0, si, sj});\n        int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};\n        while (!pq.empty()) {\n            auto [d, r, c] = pq.top(); pq.pop();\n            if (d > dist[r][c]) continue;\n            for (int dir = 0; dir < 4; dir++) {\n                int nr = r+dr[dir], nc = c+dc[dir];\n                if (nr<0||nr>=30||nc<0||nc>=30) continue;\n                double w;\n                if (dir == 0) w = v[nr][c];\n                else if (dir == 1) w = v[r][c];\n                else if (dir == 2) w = h[r][nc];\n                else w = h[r][c];\n                if (dist[nr][nc] > d + w) {\n                    dist[nr][nc] = d + w;\n                    prv[nr][nc] = dir;\n                    pq.push({dist[nr][nc], nr, nc});\n                }\n            }\n        }\n        \n        vector<int> dirs;\n        int r = ti, c = tj;\n        while (!(r == si && c == sj)) {\n            int d = prv[r][c];\n            dirs.push_back(d);\n            r -= dr[d]; c -= dc[d];\n        }\n        reverse(dirs.begin(), dirs.end());\n        \n        string path;\n        char ch[] = {'U','D','L','R'};\n        for (int d : dirs) path += ch[d];\n        cout << path << endl;\n        cout.flush();\n        \n        long long b;\n        cin >> b;\n        \n        vector<double*> edgePtrs;\n        r = si; c = sj;\n        double predicted = 0;\n        for (int d : dirs) {\n            int nr = r+dr[d], nc = c+dc[d];\n            double* ep;\n            if (d == 0) ep = &v[nr][c];\n            else if (d == 1) ep = &v[r][c];\n            else if (d == 2) ep = &h[r][nc];\n            else ep = &h[r][c];\n            edgePtrs.push_back(ep);\n            predicted += *ep;\n            r = nr; c = nc;\n        }\n        \n        double err = (double)b - predicted;\n        double alpha = 0.1;\n        double delta = alpha * err / (double)edgePtrs.size();\n        for (auto* ep : edgePtrs) {\n            *ep += delta;\n            if (*ep < 100) *ep = 100;\n            if (*ep > 9000) *ep = 9000;\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\nusing Clock = chrono::steady_clock;\n\nint N = 20;\nint M;\nvector<string> S;\n\nint ovlp(const string& a, const string& b) {\n    int m = min((int)a.size(), (int)b.size());\n    for (int k = m; k >= 1; k--) {\n        if (a.compare(a.size()-k, k, b, 0, k) == 0) return k;\n    }\n    return 0;\n}\n\nmt19937 rng(42);\n\nint countMatches(vector<string>& grid, vector<int>& avail) {\n    vector<string> tracks;\n    for (int r = 0; r < N; r++) tracks.push_back(grid[r] + grid[r].substr(0, 11));\n    for (int c = 0; c < N; c++) {\n        string col = \"\";\n        for (int r = 0; r < N; r++) col += grid[r][c];\n        tracks.push_back(col + col.substr(0, 11));\n    }\n    int cnt = 0;\n    for (int i : avail) {\n        for (auto& t : tracks) {\n            if (t.find(S[i]) != string::npos) { cnt++; break; }\n        }\n    }\n    return cnt;\n}\n\nint main() {\n    cin >> N >> M;\n    S.resize(M);\n    for (auto& s : S) cin >> s;\n    \n    vector<bool> redundant(M, false);\n    vector<int> idxSort(M);\n    iota(idxSort.begin(), idxSort.end(), 0);\n    sort(idxSort.begin(), idxSort.end(), [](int a, int b){ return S[a].size() > S[b].size(); });\n    \n    for (int ii = 0; ii < M; ii++) {\n        int i = idxSort[ii];\n        if (redundant[i]) continue;\n        for (int jj = ii+1; jj < M; jj++) {\n            int j = idxSort[jj];\n            if (redundant[j]) continue;\n            if (S[i].find(S[j]) != string::npos) redundant[j] = true;\n        }\n    }\n    \n    vector<int> avail;\n    for (int i = 0; i < M; i++) if (!redundant[i]) avail.push_back(i);\n    \n    auto startTime = Clock::now();\n    \n    vector<string> bestGrid(N, string(N, '.'));\n    int bestScore = -1;\n    int bestDots = -1;\n    \n    int trial = 0;\n    while (true) {\n        double elapsed = chrono::duration<double>(Clock::now() - startTime).count();\n        if (elapsed > 2.5) break;\n        trial++;\n        \n        vector<bool> used(M, false);\n        for (int i = 0; i < M; i++) if (redundant[i]) used[i] = true;\n        \n        vector<string> grid(N, string(N, '.'));\n        \n        vector<int> order = avail;\n        shuffle(order.begin(), order.end(), rng);\n        \n        for (int r = 0; r < N; r++) {\n            int first = -1;\n            int bestLen = -1;\n            for (int i : order) if (!used[i]) {\n                if ((int)S[i].size() > bestLen) { bestLen = S[i].size(); first = i; }\n            }\n            if (first == -1) break;\n            vector<int> topCands;\n            for (int i : order) if (!used[i] && (int)S[i].size() >= bestLen) topCands.push_back(i);\n            if (topCands.empty()) break;\n            first = topCands[rng() % topCands.size()];\n            \n            string row = S[first];\n            used[first] = true;\n            if ((int)row.size() > N) row = row.substr(0, N);\n            \n            while ((int)row.size() < N) {\n                vector<tuple<int,int,int>> cands;\n                for (int i : order) if (!used[i]) {\n                    int o = ovlp(row, S[i]);\n                    int addLen = (int)S[i].size() - o;\n                    if ((int)row.size() + addLen > N) continue;\n                    int sc = o * 1000 + (int)S[i].size();\n                    cands.push_back({sc, i, o});\n                }\n                if (cands.empty()) break;\n                sort(cands.begin(), cands.end(), greater<>());\n                int topk = min((int)cands.size(), 3);\n                auto [sc, best, o] = cands[rng() % topk];\n                row += S[best].substr(o);\n                used[best] = true;\n            }\n            \n            for (int j = 0; j < (int)row.size(); j++) grid[r][j] = row[j];\n            \n            string cyc = row;\n            if ((int)row.size() == N) cyc = row + row.substr(0, 11);\n            for (int i : avail) if (!used[i]) {\n                if (cyc.find(S[i]) != string::npos) used[i] = true;\n            }\n        }\n        \n        for (int c = 0; c < N; c++) {\n            string col = \"\";\n            for (int r = 0; r < N; r++) col += grid[r][c];\n            string cyc = col + col.substr(0, 11);\n            for (int i : avail) if (!used[i]) {\n                if (cyc.find(S[i]) != string::npos) used[i] = true;\n            }\n        }\n        \n        for (int i : avail) if (!used[i]) {\n            const string& s = S[i];\n            int L = s.size();\n            bool placed = false;\n            for (int c = 0; c < N && !placed; c++) {\n                for (int r = 0; r < N && !placed; r++) {\n                    bool ok = true;\n                    for (int p = 0; p < L; p++) {\n                        char ch = grid[(r+p)%N][c];\n                        if (ch != '.' && ch != s[p]) { ok = false; break; }\n                    }\n                    if (ok) {\n                        for (int p = 0; p < L; p++) grid[(r+p)%N][c] = s[p];\n                        used[i] = true;\n                        placed = true;\n                    }\n                }\n            }\n        }\n        \n        for (int i : avail) if (!used[i]) {\n            const string& s = S[i];\n            int L = s.size();\n            bool placed = false;\n            for (int r = 0; r < N && !placed; r++) {\n                for (int c = 0; c < N && !placed; c++) {\n                    bool ok = true;\n                    for (int p = 0; p < L; p++) {\n                        char ch = grid[r][(c+p)%N];\n                        if (ch != '.' && ch != s[p]) { ok = false; break; }\n                    }\n                    if (ok) {\n                        for (int p = 0; p < L; p++) grid[r][(c+p)%N] = s[p];\n                        used[i] = true;\n                        placed = true;\n                    }\n                }\n            }\n        }\n        \n        int score = countMatches(grid, avail);\n        int dots = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] == '.') dots++;\n        \n        bool better = false;\n        if (score > bestScore) better = true;\n        else if (score == bestScore) {\n            if (score == (int)avail.size()) {\n                if (dots > bestDots) better = true;\n            }\n        }\n        \n        if (better) {\n            bestScore = score;\n            bestDots = dots;\n            bestGrid = grid;\n        }\n    }\n    \n    if (bestScore == (int)avail.size()) {\n        int cur = bestScore;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) {\n            if (bestGrid[r][c] == '.') continue;\n            char orig = bestGrid[r][c];\n            bestGrid[r][c] = '.';\n            int nw = countMatches(bestGrid, avail);\n            if (nw < cur) bestGrid[r][c] = orig;\n            else cur = nw;\n        }\n    }\n    \n    cerr << \"Trials: \" << trial << \" score: \" << bestScore << \"/\" << avail.size() << \"\\n\";\n    \n    for (int i = 0; i < N; i++) cout << bestGrid[i] << \"\\n\";\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> G;\nvector<vector<int>> id;\nvector<pair<int,int>> pos;\nvector<int> cost;\nint R;\n\nbool isRoad(int i,int j){ return i>=0&&i<N&&j>=0&&j<N&&G[i][j]!='#'; }\n\nint main(){\n    cin>>N>>si>>sj;\n    G.resize(N);\n    for(auto&s:G)cin>>s;\n    id.assign(N,vector<int>(N,-1));\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(G[i][j]!='#'){\n        id[i][j]=pos.size();\n        pos.push_back({i,j});\n        cost.push_back(G[i][j]-'0');\n    }\n    R=pos.size();\n    \n    vector<vector<int>> visible(R);\n    int dx[]={-1,1,0,0},dy[]={0,0,-1,1};\n    for(int k=0;k<R;k++){\n        auto[i,j]=pos[k];\n        visible[k].push_back(k);\n        for(int d=0;d<4;d++){\n            int x=i+dx[d],y=j+dy[d];\n            while(isRoad(x,y)){\n                visible[k].push_back(id[x][y]);\n                x+=dx[d];y+=dy[d];\n            }\n        }\n    }\n    \n    int sid=id[si][sj];\n    vector<bool> covered(R,false);\n    vector<int> uncovCount(R);\n    for(int k=0;k<R;k++)uncovCount[k]=visible[k].size();\n    \n    vector<int> selected;\n    int nCov=0;\n    auto doSelect=[&](int k){\n        selected.push_back(k);\n        for(int v:visible[k]){\n            if(!covered[v]){\n                covered[v]=true;\n                nCov++;\n                for(int u:visible[v])uncovCount[u]--;\n            }\n        }\n    };\n    doSelect(sid);\n    \n    while(nCov<R){\n        int best=-1,bc=-1;\n        for(int k=0;k<R;k++)if(uncovCount[k]>bc){bc=uncovCount[k];best=k;}\n        doSelect(best);\n    }\n    \n    int K=selected.size();\n    \n    vector<vector<int>> dist(K,vector<int>(R,INT_MAX));\n    vector<vector<int>> prev_(K,vector<int>(R,-1));\n    for(int s=0;s<K;s++){\n        int src=selected[s];\n        dist[s][src]=0;\n        priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>> pq;\n        pq.push({0,src});\n        while(!pq.empty()){\n            auto[d,u]=pq.top();pq.pop();\n            if(d>dist[s][u])continue;\n            auto[i,j]=pos[u];\n            for(int di=0;di<4;di++){\n                int x=i+dx[di],y=j+dy[di];\n                if(!isRoad(x,y))continue;\n                int v=id[x][y];\n                int nd=d+cost[v];\n                if(nd<dist[s][v]){\n                    dist[s][v]=nd;\n                    prev_[s][v]=u;\n                    pq.push({nd,v});\n                }\n            }\n        }\n    }\n    \n    vector<vector<int>> D(K,vector<int>(K));\n    for(int a=0;a<K;a++)for(int b=0;b<K;b++)D[a][b]=dist[a][selected[b]];\n    \n    vector<int> tour;\n    tour.push_back(0);\n    vector<bool> used(K,false);\n    used[0]=true;\n    for(int i=1;i<K;i++){\n        int last=tour.back();\n        int bn=-1,bd=INT_MAX;\n        for(int j=0;j<K;j++)if(!used[j]&&D[last][j]<bd){bd=D[last][j];bn=j;}\n        tour.push_back(bn);used[bn]=true;\n    }\n    tour.push_back(0);\n    \n    auto startT=chrono::steady_clock::now();\n    auto elapsed=[&](){return chrono::duration<double>(chrono::steady_clock::now()-startT).count();};\n    \n    bool improved=true;\n    while(improved && elapsed()<2.5){\n        improved=false;\n        for(int i=1;i<K-1;i++){\n            for(int j=i+1;j<K;j++){\n                int a=tour[i-1],b=tour[i],c=tour[j],d=tour[j+1];\n                int delta=D[a][c]+D[b][d]-D[a][b]-D[c][d];\n                if(delta<0){\n                    reverse(tour.begin()+i,tour.begin()+j+1);\n                    improved=true;\n                }\n            }\n        }\n    }\n    \n    string result;\n    for(int i=0;i+1<(int)tour.size();i++){\n        int a=selected[tour[i]], b=selected[tour[i+1]];\n        if(a==b)continue;\n        int s=tour[i];\n        vector<int> path;\n        int cur=b;\n        while(cur!=a){\n            path.push_back(cur);\n            cur=prev_[s][cur];\n        }\n        reverse(path.begin(),path.end());\n        int px=pos[a].first, py=pos[a].second;\n        for(int n:path){\n            int nx=pos[n].first, ny=pos[n].second;\n            if(nx==px-1)result+='U';\n            else if(nx==px+1)result+='D';\n            else if(ny==py-1)result+='L';\n            else result+='R';\n            px=nx;py=ny;\n        }\n    }\n    \n    cout<<result<<endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> D;\nvector<vector<int>> deps;\nvector<vector<int>> children;\nvector<int> indeg;\nvector<int> longestPath;\n\nvector<vector<int>> estS;\nvector<vector<pair<int,int>>> obs;\n\nint computeW(const vector<int>& d, const vector<int>& s) {\n    int w = 0;\n    for (int k = 0; k < K; k++) w += max(0, d[k] - s[k]);\n    return w;\n}\n\nint predictTime(int task, int member) {\n    int w = computeW(D[task], estS[member]);\n    return (w == 0) ? 1 : max(1, w);\n}\n\ndouble errorFor(int member) {\n    double err = 0;\n    for (auto& p : obs[member]) {\n        int w = computeW(D[p.first], estS[member]);\n        int pred = (w == 0) ? 1 : max(1, w);\n        double diff = (double)pred - p.second;\n        err += diff * diff;\n    }\n    return err;\n}\n\nvoid updateSkills(int member) {\n    if (obs[member].empty()) return;\n    double best = errorFor(member);\n    for (int pass = 0; pass < 100; pass++) {\n        bool improved = false;\n        for (int k = 0; k < K; k++) {\n            for (int delta : {1, -1, 2, -2, 3, -3}) {\n                int old = estS[member][k];\n                int nv = old + delta;\n                if (nv < 0 || nv > 50) continue;\n                estS[member][k] = nv;\n                double e = errorFor(member);\n                if (e < best - 1e-9) {\n                    best = e;\n                    improved = true;\n                } else {\n                    estS[member][k] = old;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> N >> M >> K >> R;\n    D.assign(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> D[i][k];\n    deps.assign(N, {});\n    children.assign(N, {});\n    indeg.assign(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u);\n        children[u].push_back(v);\n        indeg[v]++;\n    }\n    \n    longestPath.assign(N, 0);\n    for (int i = N - 1; i >= 0; i--) {\n        int b = 0;\n        for (int ch : children[i]) b = max(b, longestPath[ch]);\n        longestPath[i] = b + 1;\n    }\n    \n    estS.assign(M, vector<int>(K, 3));\n    obs.assign(M, {});\n    \n    vector<int> taskStatus(N, 0);\n    vector<int> memberTask(M, -1);\n    vector<int> memberStartDay(M, 0);\n    vector<int> remIndeg = indeg;\n    \n    for (int day = 1; day <= 2000; day++) {\n        vector<int> avail;\n        for (int i = 0; i < N; i++)\n            if (taskStatus[i] == 0 && remIndeg[i] == 0) avail.push_back(i);\n        \n        sort(avail.begin(), avail.end(), [&](int a, int b) {\n            return longestPath[a] > longestPath[b];\n        });\n        \n        set<int> freeSet;\n        for (int j = 0; j < M; j++) if (memberTask[j] == -1) freeSet.insert(j);\n        \n        vector<pair<int,int>> assignments;\n        for (int task : avail) {\n            if (freeSet.empty()) break;\n            int bestMem = -1, bestTime = INT_MAX;\n            for (int j : freeSet) {\n                int t = predictTime(task, j);\n                if (t < bestTime) { bestTime = t; bestMem = j; }\n            }\n            if (bestMem != -1) {\n                assignments.push_back({bestMem, task});\n                freeSet.erase(bestMem);\n                taskStatus[task] = 1;\n                memberTask[bestMem] = task;\n                memberStartDay[bestMem] = day;\n            }\n        }\n        \n        cout << assignments.size();\n        for (auto& p : assignments) cout << \" \" << (p.first+1) << \" \" << (p.second+1);\n        cout << \"\\n\";\n        cout.flush();\n        \n        int n; cin >> n;\n        if (n == -1) return 0;\n        for (int i = 0; i < n; i++) {\n            int f; cin >> f; f--;\n            int task = memberTask[f];\n            int daysTaken = day - memberStartDay[f] + 1;\n            obs[f].push_back({task, daysTaken});\n            taskStatus[task] = 2;\n            memberTask[f] = -1;\n            for (int ch : children[task]) remIndeg[ch]--;\n            updateSkills(f);\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint A[1000][4];\n\ninline int px(int id) { \n    if(id<=0) return 400;\n    if(id<=1000) return A[id-1][0];\n    return A[id-1001][2];\n}\ninline int py(int id) {\n    if(id<=0) return 400;\n    if(id<=1000) return A[id-1][1];\n    return A[id-1001][3];\n}\ninline int D(int a, int b) {\n    return abs(px(a)-px(b))+abs(py(a)-py(b));\n}\n\nint routeCost(const vector<int>& s){\n    int t=0;\n    for(int i=0;i+1<(int)s.size();i++) t+=D(s[i],s[i+1]);\n    return t;\n}\n\nint insertOrder(vector<int>& s, int oid){\n    int p = oid+1, d = oid+1001;\n    int best = INT_MAX;\n    int bi=1,bj=1;\n    int n = s.size();\n    for(int i=1;i<n;i++){\n        int dps = D(s[i-1],p);\n        int dpe = D(p,s[i]);\n        int dss = D(s[i-1],s[i]);\n        {\n            int delta = dps + D(p,d) + D(d,s[i]) - dss;\n            if(delta<best){best=delta;bi=i;bj=i;}\n        }\n        int baseP = dps+dpe-dss;\n        for(int j=i+1;j<n;j++){\n            int delta = baseP + D(s[j-1],d)+D(d,s[j])-D(s[j-1],s[j]);\n            if(delta<best){best=delta;bi=i;bj=j;}\n        }\n    }\n    vector<int> ns;\n    ns.reserve(s.size()+2);\n    for(int k=0;k<(int)s.size();k++){\n        if(k==bi){\n            ns.push_back(p);\n            if(bj==bi) ns.push_back(d);\n        }\n        if(k==bj && bj!=bi) ns.push_back(d);\n        ns.push_back(s[k]);\n    }\n    s = ns;\n    return best;\n}\n\nvoid removeOrder(vector<int>& s, int oid){\n    int p=oid+1, d=oid+1001;\n    vector<int> ns;\n    ns.reserve(s.size());\n    for(int id : s) if(id!=p && id!=d) ns.push_back(id);\n    s = ns;\n}\n\nint main(){\n    auto start = steady_clock::now();\n    for(int i=0;i<1000;i++) for(int j=0;j<4;j++) cin>>A[i][j];\n    \n    vector<pair<int,int>> scored(1000);\n    for(int i=0;i<1000;i++){\n        int s = abs(A[i][0]-400)+abs(A[i][1]-400)+abs(A[i][2]-400)+abs(A[i][3]-400);\n        scored[i]={s,i};\n    }\n    sort(scored.begin(),scored.end());\n    \n    vector<bool> inChosen(1000,false);\n    vector<int> chosen;\n    for(int i=0;i<50;i++){ chosen.push_back(scored[i].second); inChosen[scored[i].second]=true; }\n    \n    vector<int> seq = {0, 0};\n    for(int oid : chosen) insertOrder(seq, oid);\n    \n    int curCost = routeCost(seq);\n    \n    mt19937 rng(12345);\n    \n    int timeLimit = 1850;\n    long long iter = 0;\n    \n    while(true){\n        if((iter&255)==0){\n            auto el = duration_cast<milliseconds>(steady_clock::now()-start).count();\n            if(el>timeLimit) break;\n        }\n        iter++;\n        \n        int mode = rng()%3;\n        if(mode<2){\n            int idx = rng()%50;\n            int oldOrd = chosen[idx];\n            int newOrd;\n            do { newOrd = rng()%1000; } while(inChosen[newOrd]);\n            \n            vector<int> ns = seq;\n            removeOrder(ns, oldOrd);\n            insertOrder(ns, newOrd);\n            int newCost = routeCost(ns);\n            if(newCost < curCost){\n                seq = ns;\n                curCost = newCost;\n                inChosen[oldOrd]=false;\n                inChosen[newOrd]=true;\n                chosen[idx]=newOrd;\n            }\n        } else {\n            int idx = rng()%50;\n            int oid = chosen[idx];\n            vector<int> ns = seq;\n            removeOrder(ns, oid);\n            insertOrder(ns, oid);\n            int newCost = routeCost(ns);\n            if(newCost < curCost){\n                seq = ns;\n                curCost = newCost;\n            }\n        }\n    }\n    \n    cout << 50;\n    vector<int> ords;\n    set<int> seen;\n    for(int id : seq){\n        if(id>=1 && id<=1000 && !seen.count(id-1)){\n            ords.push_back(id-1);\n            seen.insert(id-1);\n        }\n    }\n    for(int o : ords) cout << \" \" << (o+1);\n    cout << \"\\n\";\n    cout << seq.size();\n    for(int id : seq) cout << \" \" << px(id) << \" \" << py(id);\n    cout << \"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int p[400], r[400];\n    void init(int n){ for(int i=0;i<n;i++){p[i]=i;r[i]=0;} }\n    int f(int x){ while(p[x]!=x){p[x]=p[p[x]];x=p[x];} return x; }\n    bool u(int a,int b){ a=f(a);b=f(b); if(a==b)return false; if(r[a]<r[b])swap(a,b); p[b]=a; if(r[a]==r[b])r[a]++; return true; }\n};\n\nint N, M;\nint X[400], Y[400];\nint U[2000], V[2000], D[2000];\nint ew[2100], ea[2100], eb[2100];\nint idx_[2100];\nDSU sim;\n\nint main(){\n    N = 400; M = 1995;\n    for(int i=0;i<N;i++) scanf(\"%d %d\", &X[i], &Y[i]);\n    for(int i=0;i<M;i++){\n        scanf(\"%d %d\", &U[i], &V[i]);\n        double dx=X[U[i]]-X[V[i]], dy=Y[U[i]]-Y[V[i]];\n        D[i] = (int)round(sqrt(dx*dx+dy*dy));\n        if(D[i]<1) D[i]=1;\n    }\n    \n    vector<tuple<int,int,int>> adoptedEdges;\n    DSU glob; glob.init(N);\n    \n    mt19937 rng(98765);\n    \n    const int TRIALS = 40;\n    const int THRESH = 20;\n    \n    for(int i=0;i<M;i++){\n        int l; scanf(\"%d\", &l);\n        \n        if(glob.f(U[i]) == glob.f(V[i])){\n            printf(\"0\\n\"); fflush(stdout);\n            continue;\n        }\n        \n        int baseCnt = 0;\n        for(auto& [w,a,b]: adoptedEdges){\n            ew[baseCnt]=w; ea[baseCnt]=a; eb[baseCnt]=b; baseCnt++;\n        }\n        ew[baseCnt]=l; ea[baseCnt]=U[i]; eb[baseCnt]=V[i];\n        int curIdx = baseCnt;\n        baseCnt++;\n        \n        int adoptCount = 0;\n        int done = 0;\n        bool decided = false;\n        bool adopt = false;\n        for(int t=0; t<TRIALS; t++){\n            int cnt = baseCnt;\n            for(int j=i+1;j<M;j++){\n                int range = 2*D[j]+1;\n                int w = D[j] + (int)(rng() % range);\n                ew[cnt]=w; ea[cnt]=U[j]; eb[cnt]=V[j]; cnt++;\n            }\n            for(int k=0;k<cnt;k++) idx_[k]=k;\n            sort(idx_, idx_+cnt, [](int a, int b){ return ew[a]<ew[b]; });\n            sim.init(N);\n            bool used = false;\n            for(int k=0;k<cnt;k++){\n                int id = idx_[k];\n                if(sim.u(ea[id], eb[id])){\n                    if(id == curIdx){ used = true; }\n                }\n            }\n            if(used) adoptCount++;\n            done++;\n            int remaining = TRIALS - done;\n            if(adoptCount >= THRESH){ adopt=true; decided=true; break; }\n            if(adoptCount + remaining < THRESH){ adopt=false; decided=true; break; }\n        }\n        if(!decided) adopt = (adoptCount >= THRESH);\n        \n        if(adopt){\n            printf(\"1\\n\");\n            adoptedEdges.push_back({l, U[i], V[i]});\n            glob.u(U[i], V[i]);\n        } else {\n            printf(\"0\\n\");\n        }\n        fflush(stdout);\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint pt[25];\nint hx[15], hy[15];\nint grid[32][32];\nvector<pair<int,int>> pets;\n\nint dx4[] = {-1,1,0,0};\nint dy4[] = {0,0,-1,1};\nchar mvch[] = {'U','D','L','R'};\n\nbool inb(int x, int y) { return x>=1 && x<=30 && y>=1 && y<=30; }\n\nbool canWall(int x, int y) {\n    if (!inb(x,y)) return false;\n    if (grid[x][y]) return false;\n    for (auto& p : pets) if (p.first==x && p.second==y) return false;\n    for (int i=0;i<M;i++) if (hx[i]==x && hy[i]==y) return false;\n    for (int d=0;d<4;d++) {\n        int nx=x+dx4[d], ny=y+dy4[d];\n        for (auto& p : pets) if (p.first==nx && p.second==ny) return false;\n    }\n    return true;\n}\n\nvoid bfs(int sx, int sy, vector<vector<int>>& dist) {\n    dist.assign(32, vector<int>(32, -1));\n    if (!inb(sx,sy) || grid[sx][sy]) return;\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+dx4[d], ny=y+dy4[d];\n            if (!inb(nx,ny)||grid[nx][ny]||dist[nx][ny]!=-1) continue;\n            dist[nx][ny]=dist[x][y]+1;\n            q.push({nx,ny});\n        }\n    }\n}\n\nint main(){\n    cin >> N;\n    pets.resize(N);\n    for (int i=0;i<N;i++){\n        int x,y,t; cin >> x >> y >> t;\n        pets[i]={x,y}; pt[i]=t;\n    }\n    cin >> M;\n    for (int i=0;i<M;i++) cin >> hx[i] >> hy[i];\n    memset(grid,0,sizeof(grid));\n    \n    vector<int> order(M); iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),[](int a,int b){return hy[a]<hy[b];});\n    vector<pair<int,int>> assignSeg(M);\n    for (int k=0;k<M;k++){\n        int s = 1 + k*30/M, e = (k+1)*30/M;\n        assignSeg[order[k]] = {s, e};\n    }\n    \n    vector<int> standRow(M), wallRow(M,15);\n    vector<char> wallDir(M);\n    for (int i=0;i<M;i++){\n        if (hx[i] <= 14){ standRow[i]=14; wallDir[i]='d'; }\n        else if (hx[i] >= 16){ standRow[i]=16; wallDir[i]='u'; }\n        else { standRow[i]=14; wallDir[i]='d'; }\n    }\n    \n    vector<int> phase(M,0);\n    \n    auto isHumanAt = [&](int x, int y, int skip) {\n        for (int i=0;i<M;i++) if (i!=skip && hx[i]==x && hy[i]==y) return true;\n        return false;\n    };\n    \n    for (int turn=0; turn<300; turn++){\n        string action(M,'.');\n        vector<pair<int,int>> newWalls;\n        \n        for (int i=0;i<M;i++){\n            int cx=hx[i], cy=hy[i];\n            auto [cs, ce] = assignSeg[i];\n            \n            auto tryMove = [&](int tx, int ty) {\n                vector<vector<int>> dist;\n                bfs(tx,ty,dist);\n                if (dist[cx][cy]<=0) return;\n                for (int d=0;d<4;d++){\n                    int nx=cx+dx4[d], ny=cy+dy4[d];\n                    if (!inb(nx,ny)||grid[nx][ny]) continue;\n                    if (dist[nx][ny]==dist[cx][cy]-1 && !isHumanAt(nx,ny,i)){\n                        bool blocked=false;\n                        for (auto& w: newWalls) if (w.first==nx&&w.second==ny){blocked=true;break;}\n                        if (blocked) continue;\n                        action[i]=mvch[d];\n                        return;\n                    }\n                }\n            };\n            \n            if (phase[i]==0){\n                if (cx==standRow[i] && cy==cs){\n                    phase[i]=1;\n                } else {\n                    tryMove(standRow[i], cs);\n                    continue;\n                }\n            }\n            if (phase[i]==1){\n                if (cx!=standRow[i]){\n                    tryMove(standRow[i], cy);\n                    continue;\n                }\n                int wx = wallRow[i], wy=cy;\n                if (!grid[wx][wy]){\n                    if (canWall(wx,wy)){\n                        action[i]=wallDir[i];\n                        newWalls.push_back({wx,wy});\n                    }\n                } else {\n                    if (cy<ce){\n                        int nx=cx, ny=cy+1;\n                        if (inb(nx,ny)&&!grid[nx][ny]&&!isHumanAt(nx,ny,i)){\n                            action[i]='R';\n                        }\n                    } else {\n                        phase[i]=2;\n                    }\n                }\n            }\n        }\n        \n        cout << action << endl;\n        cout.flush();\n        \n        for (int i=0;i<M;i++){\n            char a = action[i];\n            if (a=='U'||a=='D'||a=='L'||a=='R'){\n                int d = (a=='U')?0:(a=='D')?1:(a=='L')?2:3;\n                hx[i]+=dx4[d]; hy[i]+=dy4[d];\n            }\n        }\n        for (auto& w : newWalls) grid[w.first][w.second]=1;\n        \n        for (int i=0;i<N;i++){\n            string s; cin >> s;\n            int x=pets[i].first, y=pets[i].second;\n            for (char c : s){\n                if (c=='U') x--;\n                else if (c=='D') x++;\n                else if (c=='L') y--;\n                else if (c=='R') y++;\n            }\n            pets[i]={x,y};\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si,sj,ti,tj;\ndouble p;\nint H[20][19], V[19][20];\n\nbool canMove(int i,int j,char c){\n    if(c=='U') return i>0 && V[i-1][j]==0;\n    if(c=='D') return i<19 && V[i][j]==0;\n    if(c=='L') return j>0 && H[i][j-1]==0;\n    if(c=='R') return j<19 && H[i][j]==0;\n    return false;\n}\npair<int,int> move1(int i,int j,char c){\n    if(!canMove(i,j,c)) return {i,j};\n    if(c=='U') return {i-1,j};\n    if(c=='D') return {i+1,j};\n    if(c=='L') return {i,j-1};\n    return {i,j+1};\n}\n\ndouble evalScore(const string& s){\n    static double dist[20][20], nd[20][20];\n    for(int i=0;i<20;i++)for(int j=0;j<20;j++) dist[i][j]=0;\n    dist[si][sj]=1.0;\n    if(si==ti && sj==tj) return 400.0;\n    double score=0;\n    int L=s.size();\n    for(int t=0;t<L;t++){\n        char c=s[t];\n        for(int i=0;i<20;i++)for(int j=0;j<20;j++) nd[i][j]=0;\n        for(int i=0;i<20;i++)for(int j=0;j<20;j++){\n            if(dist[i][j]<1e-18) continue;\n            nd[i][j] += dist[i][j]*p;\n            auto [ni,nj]=move1(i,j,c);\n            nd[ni][nj] += dist[i][j]*(1-p);\n        }\n        double arrived = nd[ti][tj];\n        score += arrived * (400 - t);\n        nd[ti][tj]=0;\n        memcpy(dist,nd,sizeof(dist));\n    }\n    return score;\n}\n\nint main(){\n    cin>>si>>sj>>ti>>tj>>p;\n    for(int i=0;i<20;i++){\n        string s; cin>>s;\n        for(int j=0;j<19;j++) H[i][j]=s[j]-'0';\n    }\n    for(int i=0;i<19;i++){\n        string s; cin>>s;\n        for(int j=0;j<20;j++) V[i][j]=s[j]-'0';\n    }\n    \n    vector<vector<int>> bd(20,vector<int>(20,-1));\n    vector<vector<pair<int,int>>> par(20,vector<pair<int,int>>(20,{-1,-1}));\n    vector<vector<char>> pc(20,vector<char>(20,0));\n    queue<pair<int,int>> q;\n    q.push({si,sj}); bd[si][sj]=0;\n    string dirs=\"UDLR\";\n    while(!q.empty()){\n        auto [i,j]=q.front(); q.pop();\n        for(char c:dirs){\n            if(canMove(i,j,c)){\n                auto [ni,nj]=move1(i,j,c);\n                if(bd[ni][nj]==-1){\n                    bd[ni][nj]=bd[i][j]+1;\n                    par[ni][nj]={i,j};\n                    pc[ni][nj]=c;\n                    q.push({ni,nj});\n                }\n            }\n        }\n    }\n    string path;\n    {\n        int ci=ti,cj=tj;\n        while(!(ci==si&&cj==sj)){\n            path+=pc[ci][cj];\n            auto [pi,pj]=par[ci][cj];\n            ci=pi; cj=pj;\n        }\n        reverse(path.begin(),path.end());\n    }\n    \n    string best=path;\n    double bestScore=evalScore(best);\n    int L=path.size();\n    \n    for(int k=1; k*L<=200; k++){\n        string cand;\n        for(char c:path) for(int r=0;r<k;r++) cand+=c;\n        if((int)cand.size()>200) cand=cand.substr(0,200);\n        double sc=evalScore(cand);\n        if(sc>bestScore){bestScore=sc; best=cand;}\n    }\n    \n    for(int k=1; k*L<=200; k++){\n        string cand;\n        for(char c:path) for(int r=0;r<k;r++) cand+=c;\n        while((int)cand.size()<200) cand+=path.back();\n        if((int)cand.size()>200) cand=cand.substr(0,200);\n        double sc=evalScore(cand);\n        if(sc>bestScore){bestScore=sc; best=cand;}\n    }\n    \n    auto start=chrono::steady_clock::now();\n    auto timeLeft=[&](){\n        auto now=chrono::steady_clock::now();\n        return chrono::duration_cast<chrono::milliseconds>(now-start).count()<1700;\n    };\n    \n    bool improved=true;\n    while(improved && timeLeft()){\n        improved=false;\n        for(int pos=0;pos<(int)best.size() && timeLeft();pos++){\n            for(char c : dirs){\n                if(c==best[pos]) continue;\n                string cand=best;\n                cand[pos]=c;\n                double sc=evalScore(cand);\n                if(sc>bestScore+1e-9){bestScore=sc; best=cand; improved=true;}\n            }\n        }\n    }\n    \n    cout<<best<<endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nint to_dir[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\nint di[4] = {0, -1, 0, 1};\nint dj[4] = {-1, 0, 1, 0};\nint rot1[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n\nint tiles[30][30];\nint visited[30][30][4];\nint gen = 0;\n\nlong long evaluate() {\n    gen++;\n    int L1 = 0, L2 = 0;\n    for (int si = 0; si < 30; si++) {\n        for (int sj = 0; sj < 30; sj++) {\n            for (int sd = 0; sd < 4; sd++) {\n                if (visited[si][sj][sd] == gen) continue;\n                int i = si, j = sj, d = sd;\n                int len = 0;\n                while (true) {\n                    if (visited[i][j][d] == gen) break;\n                    visited[i][j][d] = gen;\n                    int t = tiles[i][j];\n                    int d2 = to_dir[t][d];\n                    if (d2 == -1) break;\n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if (ni<0||ni>=30||nj<0||nj>=30) break;\n                    int nd = (d2 + 2) % 4;\n                    len++;\n                    if (ni == si && nj == sj && nd == sd) {\n                        if (len > L1) { L2 = L1; L1 = len; }\n                        else if (len > L2) L2 = len;\n                        break;\n                    }\n                    i = ni; j = nj; d = nd;\n                }\n            }\n        }\n    }\n    return (long long)L1 * L2;\n}\n\nint main() {\n    int input[30][30];\n    for (int i = 0; i < 30; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < 30; j++) input[i][j] = s[j]-'0';\n    }\n    int rot[30][30];\n    int bestRot[30][30];\n    memset(rot, 0, sizeof(rot));\n    \n    mt19937 rng(98765);\n    \n    for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) {\n        rot[i][j] = rng()%4;\n        int t = input[i][j];\n        for (int k = 0; k < rot[i][j]; k++) t = rot1[t];\n        tiles[i][j] = t;\n    }\n    \n    long long cur = evaluate();\n    long long best = cur;\n    memcpy(bestRot, rot, sizeof(rot));\n    \n    auto start = chrono::steady_clock::now();\n    double TL = 1.9;\n    \n    int iter = 0;\n    double T0 = 200.0, T1 = 1.0;\n    double elapsed = 0;\n    while (true) {\n        iter++;\n        if ((iter & 255) == 0) {\n            auto now = chrono::steady_clock::now();\n            elapsed = chrono::duration<double>(now-start).count();\n            if (elapsed > TL) break;\n        }\n        double progress = min(1.0, elapsed / TL);\n        double T = T0 * pow(T1/T0, progress);\n        \n        int i = rng()%30, j = rng()%30;\n        int oldT = tiles[i][j];\n        int oldR = rot[i][j];\n        int dr = 1 + rng()%3;\n        int newR = (oldR + dr) % 4;\n        int nt = oldT;\n        for (int k = 0; k < dr; k++) nt = rot1[nt];\n        tiles[i][j] = nt;\n        long long nv = evaluate();\n        long long delta = nv - cur;\n        if (delta >= 0 || (double)rng()/(double)rng.max() < exp((double)delta/T)) {\n            cur = nv;\n            rot[i][j] = newR;\n            if (cur > best) {\n                best = cur;\n                memcpy(bestRot, rot, sizeof(rot));\n            }\n        } else {\n            tiles[i][j] = oldT;\n        }\n    }\n    \n    string out;\n    for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) out += char('0'+bestRot[i][j]);\n    cout << out << endl;\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nmt19937 rng(12345);\n\nint computeTreeScore(vector<vector<int>>& b) {\n    int n = N;\n    vector<int> par(n*n), sz(n*n, 1);\n    vector<bool> bad(n*n, false);\n    iota(par.begin(), par.end(), 0);\n    function<int(int)> find = [&](int x){ while(par[x]!=x){par[x]=par[par[x]];x=par[x];} return x;};\n    auto unite = [&](int a, int b){\n        int ra=find(a), rb=find(b);\n        if(ra==rb){ bad[ra]=true; return;}\n        bool nb = bad[ra]||bad[rb];\n        if(sz[ra]<sz[rb])swap(ra,rb);\n        par[rb]=ra; sz[ra]+=sz[rb]; bad[ra]=nb;\n    };\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        if(b[i][j]==0) continue;\n        if(j+1<n && b[i][j+1]!=0 && (b[i][j]&4) && (b[i][j+1]&1)) unite(i*n+j, i*n+j+1);\n        if(i+1<n && b[i+1][j]!=0 && (b[i][j]&8) && (b[i+1][j]&2)) unite(i*n+j, (i+1)*n+j);\n    }\n    int best=0;\n    for(int i=0;i<n*n;i++){\n        if(b[i/n][i%n]==0) continue;\n        if(find(i)==i && !bad[i]) best=max(best,sz[i]);\n    }\n    return best;\n}\n\nint main(){\n    cin>>N>>T;\n    vector<string> initial(N);\n    for(auto&s:initial) cin>>s;\n    \n    vector<vector<int>> board(N, vector<int>(N));\n    int er=0, ec=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        char c = initial[i][j];\n        int v = (c>='0'&&c<='9')?c-'0':c-'a'+10;\n        board[i][j]=v;\n        if(v==0){er=i;ec=j;}\n    }\n    \n    auto target = board;\n    swap(target[er][ec], target[N-1][N-1]);\n    \n    int curScore = computeTreeScore(target);\n    auto startT = chrono::steady_clock::now();\n    double timeLimit = 2.3;\n    \n    int iter=0;\n    double temp0=3.0, temp1=0.05;\n    int bestScore = curScore;\n    auto bestTarget = target;\n    \n    while(true){\n        if((iter&1023)==0){\n            double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n            if(el>timeLimit) break;\n            if(bestScore==N*N-1) break;\n        }\n        iter++;\n        int i1,j1,i2,j2;\n        do { i1=rng()%N; j1=rng()%N; } while(i1==N-1&&j1==N-1);\n        do { i2=rng()%N; j2=rng()%N; } while((i2==N-1&&j2==N-1) || (i1==i2&&j1==j2));\n        if(target[i1][j1]==target[i2][j2]) continue;\n        swap(target[i1][j1], target[i2][j2]);\n        int ns = computeTreeScore(target);\n        double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n        double tt = temp0 * pow(temp1/temp0, el/timeLimit);\n        if(ns>=curScore || (double)rng()/(double)rng.max() < exp((ns-curScore)/tt)){\n            curScore=ns;\n            if(ns>bestScore){bestScore=ns; bestTarget=target;}\n        } else {\n            swap(target[i1][j1], target[i2][j2]);\n        }\n    }\n    target = bestTarget;\n    \n    vector<vector<int>> B = board;\n    int br=er, bc=ec;\n    string moves;\n    vector<vector<bool>> locked(N, vector<bool>(N, false));\n    \n    auto posOk = [&](int r, int c){ return r>=0&&r<N&&c>=0&&c<N; };\n    \n    auto moveBlankTo = [&](int tr, int tc, int avoidR, int avoidC)->bool{\n        if(br==tr&&bc==tc) return true;\n        if(locked[tr][tc]) return false;\n        vector<vector<int>> dist(N, vector<int>(N,-1));\n        vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N,{-1,-1}));\n        queue<pair<int,int>> q;\n        dist[br][bc]=0; q.push({br,bc});\n        while(!q.empty()){\n            auto [r,c]=q.front(); q.pop();\n            int dr[]={-1,1,0,0}, dc[]={0,0,-1,1};\n            for(int d=0;d<4;d++){\n                int nr=r+dr[d], nc=c+dc[d];\n                if(!posOk(nr,nc)) continue;\n                if(locked[nr][nc]) continue;\n                if(nr==avoidR&&nc==avoidC) continue;\n                if(dist[nr][nc]!=-1) continue;\n                dist[nr][nc]=dist[r][c]+1;\n                par[nr][nc]={r,c};\n                q.push({nr,nc});\n            }\n        }\n        if(dist[tr][tc]==-1) return false;\n        vector<pair<int,int>> path;\n        int r=tr,c=tc;\n        while(!(r==br&&c==bc)){\n            path.push_back({r,c});\n            auto [pr,pc]=par[r][c]; r=pr; c=pc;\n        }\n        reverse(path.begin(), path.end());\n        for(auto [nr,nc]:path){\n            char mv;\n            if(nr==br-1&&nc==bc) mv='U';\n            else if(nr==br+1&&nc==bc) mv='D';\n            else if(nc==bc-1&&nr==br) mv='L';\n            else mv='R';\n            moves.push_back(mv);\n            swap(B[br][bc], B[nr][nc]);\n            br=nr; bc=nc;\n        }\n        return true;\n    };\n    \n    auto findTile = [&](int type, int nearR, int nearC)->pair<int,int>{\n        int bestR=-1,bestC=-1, bestD=INT_MAX;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            if(locked[i][j]) continue;\n            if(B[i][j]==type){\n                int d=abs(i-nearR)+abs(j-nearC);\n                if(d<bestD){bestD=d; bestR=i; bestC=j;}\n            }\n        }\n        return {bestR,bestC};\n    };\n    \n    auto moveTileTo = [&](int sr, int sc, int tr, int tc)->bool{\n        while(sr!=tr || sc!=tc){\n            int nr=sr, nc=sc;\n            if(sr!=tr){\n                if(sr<tr) nr=sr+1; else nr=sr-1;\n            } else {\n                if(sc<tc) nc=sc+1; else nc=sc-1;\n            }\n            if(locked[nr][nc]) return false;\n            if(!moveBlankTo(nr,nc,sr,sc)) return false;\n            char mv;\n            if(sr==br-1&&sc==bc) mv='U';\n            else if(sr==br+1&&sc==bc) mv='D';\n            else if(sc==bc-1&&sr==br) mv='L';\n            else if(sc==bc+1&&sr==br) mv='R';\n            else return false;\n            moves.push_back(mv);\n            swap(B[br][bc], B[sr][sc]);\n            int obr=br, obc=bc;\n            br=sr; bc=sc;\n            sr=obr; sc=obc;\n        }\n        return true;\n    };\n    \n    bool solveFailed = false;\n    \n    for(int r=0; r<N-2 && !solveFailed; r++){\n        for(int c=0; c<N-2; c++){\n            int type = target[r][c];\n            auto [sr,sc] = findTile(type, r, c);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==r&&sc==c)){\n                if(!moveTileTo(sr,sc,r,c)){solveFailed=true; break;}\n            }\n            locked[r][c]=true;\n        }\n        if(solveFailed) break;\n        \n        int typeA = target[r][N-2];\n        int typeB = target[r][N-1];\n        \n        if(B[r][N-2]==typeA && B[r][N-1]==typeB){\n            locked[r][N-2]=true; locked[r][N-1]=true;\n            continue;\n        }\n        \n        {\n            auto [sr,sc] = findTile(typeA, r, N-1);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==r && sc==N-1)){\n                if(sr==r && sc==N-2){\n                    moveTileTo(sr,sc, r+1, N-2);\n                    auto p = findTile(typeA, r, N-1);\n                    sr=p.first; sc=p.second;\n                    if(sr==-1){solveFailed=true; break;}\n                }\n                if(!moveTileTo(sr, sc, r, N-1)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[r][N-1]=true;\n        \n        {\n            auto [sr,sc] = findTile(typeB, r+1, N-1);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==r+1 && sc==N-1)){\n                if(!moveTileTo(sr, sc, r+1, N-1)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[r+1][N-1]=true;\n        \n        locked[r][N-1]=false; locked[r+1][N-1]=false;\n        \n        if(!moveBlankTo(r, N-2, -1, -1)){solveFailed=true; break;}\n        moves.push_back('R');\n        swap(B[br][bc], B[r][N-1]); br=r; bc=N-1;\n        moves.push_back('D');\n        swap(B[br][bc], B[r+1][N-1]); br=r+1; bc=N-1;\n        \n        locked[r][N-2]=true; locked[r][N-1]=true;\n    }\n    \n    for(int c=0; c<N-2 && !solveFailed; c++){\n        int typeA = target[N-2][c];\n        int typeB = target[N-1][c];\n        \n        if(B[N-2][c]==typeA && B[N-1][c]==typeB){\n            locked[N-2][c]=true; locked[N-1][c]=true;\n            continue;\n        }\n        \n        {\n            auto [sr,sc] = findTile(typeA, N-1, c);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==N-1 && sc==c)){\n                if(sr==N-2 && sc==c){\n                    moveTileTo(sr,sc, N-2, c+1);\n                    auto p = findTile(typeA, N-1, c);\n                    sr=p.first; sc=p.second;\n                    if(sr==-1){solveFailed=true; break;}\n                }\n                if(!moveTileTo(sr, sc, N-1, c)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[N-1][c]=true;\n        \n        {\n            auto [sr,sc] = findTile(typeB, N-1, c+1);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==N-1 && sc==c+1)){\n                if(!moveTileTo(sr, sc, N-1, c+1)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[N-1][c+1]=true;\n        \n        locked[N-1][c]=false; locked[N-1][c+1]=false;\n        \n        if(!moveBlankTo(N-2, c, -1, -1)){solveFailed=true; break;}\n        moves.push_back('D'); swap(B[br][bc], B[N-1][c]); br=N-1; bc=c;\n        moves.push_back('R'); swap(B[br][bc], B[N-1][c+1]); br=N-1; bc=c+1;\n        locked[N-2][c]=true; locked[N-1][c]=true;\n    }\n    \n    if(!solveFailed){\n        for(int attempt=0; attempt<8; attempt++){\n            bool match = (B[N-2][N-2]==target[N-2][N-2]) && (B[N-2][N-1]==target[N-2][N-1]) && (B[N-1][N-2]==target[N-1][N-2]);\n            if(match && br==N-1 && bc==N-1) break;\n            if(br==N-1&&bc==N-1){ moves.push_back('U'); swap(B[br][bc],B[N-2][N-1]); br=N-2;bc=N-1;}\n            else if(br==N-2&&bc==N-1){ moves.push_back('L'); swap(B[br][bc],B[N-2][N-2]); br=N-2;bc=N-2;}\n            else if(br==N-2&&bc==N-2){ moves.push_back('D'); swap(B[br][bc],B[N-1][N-2]); br=N-1;bc=N-2;}\n            else if(br==N-1&&bc==N-2){ moves.push_back('R'); swap(B[br][bc],B[N-1][N-1]); br=N-1;bc=N-1;}\n        }\n    }\n    \n    // Truncate if exceeds T, finding best prefix\n    {\n        vector<vector<int>> BB = board;\n        int bbr=er, bbc=ec;\n        int bestS = computeTreeScore(BB);\n        int bestLen = 0;\n        int L = min((int)moves.size(), T);\n        for(int i=0;i<L;i++){\n            char mv = moves[i];\n            int nr=bbr, nc=bbc;\n            if(mv=='U') nr--;\n            else if(mv=='D') nr++;\n            else if(mv=='L') nc--;\n            else nc++;\n            if(!posOk(nr,nc)) break;\n            swap(BB[bbr][bbc], BB[nr][nc]);\n            bbr=nr; bbc=nc;\n            int curS = computeTreeScore(BB);\n            if(curS > bestS){ bestS=curS; bestLen=i+1; }\n        }\n        // If solve finished and moves<=T, keep all moves (final score = N\u00b2-1 gets K/T bonus)\n        if((int)moves.size() <= T && !solveFailed){\n            // keep all; that's optimal\n        } else {\n            moves = moves.substr(0, bestLen);\n        }\n    }\n    \n    cout << moves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, K;\nint a[11];\nvector<int> sx_arr, sy_arr;\n\nlong long computeScore(vector<double>& vc, vector<double>& hc) {\n    int nv = vc.size(), nh = hc.size();\n    static int cnt[105][105];\n    for (int i = 0; i <= nv; i++) for (int j = 0; j <= nh; j++) cnt[i][j] = 0;\n    for (int i = 0; i < N; i++) {\n        int xi = upper_bound(vc.begin(), vc.end(), (double)sx_arr[i]) - vc.begin();\n        int yi = upper_bound(hc.begin(), hc.end(), (double)sy_arr[i]) - hc.begin();\n        cnt[xi][yi]++;\n    }\n    int b[11] = {0};\n    for (int i = 0; i <= nv; i++)\n        for (int j = 0; j <= nh; j++) {\n            int c = cnt[i][j];\n            if (c >= 1 && c <= 10) b[c]++;\n        }\n    long long s = 0;\n    for (int d = 1; d <= 10; d++) s += min(a[d], b[d]);\n    return s;\n}\n\nint main() {\n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    sx_arr.resize(N); sy_arr.resize(N);\n    for (int i = 0; i < N; i++) cin >> sx_arr[i] >> sy_arr[i];\n    \n    vector<int> xs = sx_arr, ys = sy_arr;\n    sort(xs.begin(), xs.end());\n    xs.erase(unique(xs.begin(), xs.end()), xs.end());\n    sort(ys.begin(), ys.end());\n    ys.erase(unique(ys.begin(), ys.end()), ys.end());\n    \n    vector<double> cand_x, cand_y;\n    for (int i = 0; i + 1 < (int)xs.size(); i++)\n        cand_x.push_back((xs[i] + xs[i+1]) / 2.0);\n    for (int i = 0; i + 1 < (int)ys.size(); i++)\n        cand_y.push_back((ys[i] + ys[i+1]) / 2.0);\n    \n    mt19937 rng(42);\n    int kv = 50, kh = 50;\n    \n    auto pickEvenly = [&](vector<double>& cand, int k) {\n        vector<double> res;\n        if ((int)cand.size() <= k) res = cand;\n        else {\n            for (int i = 0; i < k; i++) {\n                int idx = (int)((long long)(i+1) * cand.size() / (k+1));\n                if (idx >= (int)cand.size()) idx = cand.size()-1;\n                res.push_back(cand[idx]);\n            }\n        }\n        sort(res.begin(), res.end());\n        res.erase(unique(res.begin(), res.end()), res.end());\n        return res;\n    };\n    \n    vector<double> vc = pickEvenly(cand_x, kv);\n    vector<double> hc = pickEvenly(cand_y, kh);\n    \n    long long curScore = computeScore(vc, hc);\n    long long bestScore = curScore;\n    vector<double> bestVC = vc, bestHC = hc;\n    \n    auto startTime = chrono::steady_clock::now();\n    double timeLimit = 2.7;\n    \n    int iters = 0;\n    while (true) {\n        iters++;\n        if ((iters & 63) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - startTime).count();\n            if (elapsed > timeLimit) break;\n        }\n        \n        vector<double> nvc = vc, nhc = hc;\n        int op = rng() % 4;\n        \n        if (op == 0 && !nvc.empty() && !cand_x.empty()) {\n            int i = rng() % nvc.size();\n            nvc[i] = cand_x[rng() % cand_x.size()];\n        } else if (op == 1 && !nhc.empty() && !cand_y.empty()) {\n            int i = rng() % nhc.size();\n            nhc[i] = cand_y[rng() % cand_y.size()];\n        } else if (op == 2) {\n            if (!nvc.empty() && (int)nvc.size() + (int)nhc.size() <= K && !cand_y.empty()) {\n                nvc.erase(nvc.begin() + rng() % nvc.size());\n                nhc.push_back(cand_y[rng() % cand_y.size()]);\n            }\n        } else {\n            if (!nhc.empty() && (int)nvc.size() + (int)nhc.size() <= K && !cand_x.empty()) {\n                nhc.erase(nhc.begin() + rng() % nhc.size());\n                nvc.push_back(cand_x[rng() % cand_x.size()]);\n            }\n        }\n        \n        sort(nvc.begin(), nvc.end());\n        nvc.erase(unique(nvc.begin(), nvc.end()), nvc.end());\n        sort(nhc.begin(), nhc.end());\n        nhc.erase(unique(nhc.begin(), nhc.end()), nhc.end());\n        if ((int)nvc.size() + (int)nhc.size() > K) continue;\n        \n        long long ns = computeScore(nvc, nhc);\n        if (ns >= curScore) {\n            curScore = ns;\n            vc = nvc; hc = nhc;\n            if (ns > bestScore) {\n                bestScore = ns;\n                bestVC = vc; bestHC = hc;\n            }\n        }\n    }\n    \n    cout << bestVC.size() + bestHC.size() << \"\\n\";\n    for (double c : bestVC) {\n        long long p = (long long)floor(c);\n        cout << p << \" \" << -1000000000LL << \" \" << p+1 << \" \" << 1000000000LL << \"\\n\";\n    }\n    for (double c : bestHC) {\n        long long p = (long long)floor(c);\n        cout << -1000000000LL << \" \" << p << \" \" << 1000000000LL << \" \" << p+1 << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint cx;\nvector<vector<bool>> has_dot;\nint dx8[8] = {1,1,0,-1,-1,-1,0,1};\nint dy8[8] = {0,1,1,1,0,-1,-1,-1};\nvector<vector<array<bool,8>>> edge_used;\n\nbool inside(int x, int y) { return 0<=x && x<N && 0<=y && y<N; }\nint weight(int x, int y) { return (x-cx)*(x-cx) + (y-cx)*(y-cx) + 1; }\n\nint nearestDot(int x, int y, int d) {\n    int nx = x + dx8[d], ny = y + dy8[d];\n    int steps = 1;\n    while (inside(nx, ny)) {\n        if (has_dot[nx][ny]) return steps;\n        nx += dx8[d]; ny += dy8[d]; steps++;\n    }\n    return -1;\n}\n\nbool checkSeg(int x, int y, int d, int len) {\n    int cxx = x, cyy = y;\n    for (int i = 0; i < len; i++) {\n        if (edge_used[cxx][cyy][d]) return false;\n        cxx += dx8[d]; cyy += dy8[d];\n        if (i < len-1 && has_dot[cxx][cyy]) return false;\n    }\n    return true;\n}\n\nvoid markSeg(int x, int y, int d, int len) {\n    int cxx = x, cyy = y;\n    for (int i = 0; i < len; i++) {\n        edge_used[cxx][cyy][d] = true;\n        int nx = cxx + dx8[d], ny = cyy + dy8[d];\n        edge_used[nx][ny][d^4] = true;\n        cxx = nx; cyy = ny;\n    }\n}\n\nstruct Move {\n    int p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y;\n    int d1, d2, len1, len2;\n};\n\nbool tryMove(int x, int y, int d1, Move& m) {\n    int d2 = (d1 + 2) % 8;\n    int l1 = nearestDot(x, y, d1);\n    if (l1 < 0) return false;\n    int l2 = nearestDot(x, y, d2);\n    if (l2 < 0) return false;\n    int p2x = x + dx8[d1]*l1, p2y = y + dy8[d1]*l1;\n    int p4x = x + dx8[d2]*l2, p4y = y + dy8[d2]*l2;\n    int p3x = p2x + dx8[d2]*l2, p3y = p2y + dy8[d2]*l2;\n    if (!inside(p3x, p3y)) return false;\n    if (!has_dot[p3x][p3y]) return false;\n    if (!checkSeg(x, y, d1, l1)) return false;\n    if (!checkSeg(x, y, d2, l2)) return false;\n    if (!checkSeg(p2x, p2y, d2, l2)) return false;\n    if (!checkSeg(p4x, p4y, d1, l1)) return false;\n    m.p1x=x; m.p1y=y; m.p2x=p2x; m.p2y=p2y; m.p3x=p3x; m.p3y=p3y; m.p4x=p4x; m.p4y=p4y;\n    m.d1=d1; m.d2=d2; m.len1=l1; m.len2=l2;\n    return true;\n}\n\nvoid applyMove(const Move& m) {\n    has_dot[m.p1x][m.p1y] = true;\n    markSeg(m.p1x, m.p1y, m.d1, m.len1);\n    markSeg(m.p1x, m.p1y, m.d2, m.len2);\n    markSeg(m.p2x, m.p2y, m.d2, m.len2);\n    markSeg(m.p4x, m.p4y, m.d1, m.len1);\n}\n\nint main() {\n    cin >> N >> M;\n    cx = (N-1)/2;\n    \n    auto startTime = chrono::steady_clock::now();\n    auto timeLeft = [&](){ return 4.7 - chrono::duration<double>(chrono::steady_clock::now() - startTime).count(); };\n    \n    vector<pair<int,int>> initial(M);\n    for (auto& p : initial) { cin >> p.first >> p.second; }\n    \n    auto resetState = [&]() {\n        has_dot.assign(N, vector<bool>(N, false));\n        edge_used.assign(N, vector<array<bool,8>>(N));\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) for (int k = 0; k < 8; k++) edge_used[i][j][k] = false;\n        for (auto& p : initial) has_dot[p.first][p.second] = true;\n    };\n    \n    vector<Move> bestMoves;\n    long long bestScore = -1;\n    \n    mt19937 rng(12345);\n    int iter = 0;\n    \n    while (timeLeft() > 0.3) {\n        resetState();\n        vector<Move> moves;\n        \n        while (timeLeft() > 0.2) {\n            Move bestM;\n            long long bestKey = LLONG_MIN;\n            bool found = false;\n            \n            int noise = (iter == 0) ? 0 : (iter * 5 + 10);\n            \n            for (int x = 0; x < N; x++) {\n                for (int y = 0; y < N; y++) {\n                    if (has_dot[x][y]) continue;\n                    for (int d1 = 0; d1 < 8; d1++) {\n                        Move m;\n                        if (tryMove(x, y, d1, m)) {\n                            long long w = weight(x, y);\n                            long long size = m.len1 + m.len2;\n                            long long key = w * 100000LL - size * 100LL;\n                            if (noise > 0) key += (long long)(rng() % (noise * 100));\n                            if (key > bestKey) {\n                                bestKey = key;\n                                bestM = m;\n                                found = true;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (!found) break;\n            applyMove(bestM);\n            moves.push_back(bestM);\n        }\n        \n        long long sumW = 0;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) {\n            if (has_dot[x][y]) sumW += weight(x,y);\n        }\n        \n        if (sumW > bestScore) {\n            bestScore = sumW;\n            bestMoves = moves;\n        }\n        iter++;\n    }\n    \n    cout << bestMoves.size() << \"\\n\";\n    for (auto& m : bestMoves) {\n        cout << m.p1x << \" \" << m.p1y << \" \" << m.p2x << \" \" << m.p2y << \" \"\n             << m.p3x << \" \" << m.p3y << \" \" << m.p4x << \" \" << m.p4y << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef array<int,100> Board;\n\ninline void tilt(Board& b, int dir) {\n    if (dir == 0) {\n        for (int c = 0; c < 10; c++) {\n            int w = 0;\n            for (int r = 0; r < 10; r++) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w++;\n                }\n            }\n        }\n    } else if (dir == 1) {\n        for (int c = 0; c < 10; c++) {\n            int w = 9;\n            for (int r = 9; r >= 0; r--) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w--;\n                }\n            }\n        }\n    } else if (dir == 2) {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 0;\n            for (int c = 0; c < 10; c++) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w++;\n                }\n            }\n        }\n    } else {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w--;\n                }\n            }\n        }\n    }\n}\n\nint placeCandy(Board& b, int p, int flavor) {\n    int cnt = 0;\n    for (int i = 0; i < 100; i++) {\n        if (!b[i]) {\n            cnt++;\n            if (cnt == p) {\n                b[i] = flavor;\n                return i;\n            }\n        }\n    }\n    return -1;\n}\n\nint computeScore(const Board& b) {\n    int vis[100] = {0};\n    int sum = 0;\n    int stk[100];\n    for (int i = 0; i < 100; i++) {\n        if (!vis[i] && b[i]) {\n            int flavor = b[i];\n            int sz = 0;\n            int top = 0;\n            stk[top++] = i;\n            vis[i] = 1;\n            while (top > 0) {\n                int x = stk[--top];\n                sz++;\n                int r = x/10, c = x%10;\n                if (r>0) { int ni = x-10; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (r<9) { int ni = x+10; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (c>0) { int ni = x-1; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (c<9) { int ni = x+1; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n            }\n            sum += sz*sz;\n        }\n    }\n    return sum;\n}\n\nmt19937 rng(12345);\n\nint main() {\n    auto startTime = chrono::steady_clock::now();\n    \n    vector<int> f(100);\n    for (int i = 0; i < 100; i++) cin >> f[i];\n    \n    Board board;\n    board.fill(0);\n    \n    double totalBudget = 1.85;\n    \n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        placeCandy(board, p, f[t]);\n        \n        if (t == 99) break;\n        \n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        double remaining = totalBudget - elapsed;\n        int stepsLeft = 100 - t;\n        double perStep = remaining / stepsLeft;\n        if (perStep < 0.001) perStep = 0.001;\n        auto stepStart = chrono::steady_clock::now();\n        \n        int remainingCandies = 100 - t - 1;\n        \n        long long scoreSum[4] = {0,0,0,0};\n        int trials[4] = {0,0,0,0};\n        \n        int roundIdx = 0;\n        while (true) {\n            if ((roundIdx & 15) == 0) {\n                auto nowS = chrono::steady_clock::now();\n                double el = chrono::duration<double>(nowS - stepStart).count();\n                if (el >= perStep) break;\n            }\n            \n            int dir = roundIdx & 3;\n            roundIdx++;\n            \n            Board b = board;\n            tilt(b, dir);\n            \n            int dp[3];\n            for (int k = 0; k < 3; k++) dp[k] = rng() & 3;\n            \n            for (int k = 0; k < remainingCandies; k++) {\n                int flavor = f[t+1+k];\n                int ec = 0;\n                int epos[100];\n                for (int i = 0; i < 100; i++) if (!b[i]) epos[ec++] = i;\n                int pick = epos[rng() % ec];\n                b[pick] = flavor;\n                tilt(b, dp[flavor-1]);\n            }\n            \n            int sc = computeScore(b);\n            scoreSum[dir] += sc;\n            trials[dir]++;\n        }\n        \n        double bestScore = -1;\n        int bestDir = 0;\n        for (int d = 0; d < 4; d++) {\n            if (trials[d] == 0) continue;\n            double avg = (double)scoreSum[d] / trials[d];\n            if (avg > bestScore) {\n                bestScore = avg;\n                bestDir = d;\n            }\n        }\n        \n        tilt(board, bestDir);\n        cout << \"FBLR\"[bestDir] << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int M; double eps;\n    cin >> M >> eps;\n    \n    int N;\n    if(eps < 0.005){\n        // need C(N,2) >= M-1\n        N = 4;\n        while(N*(N-1)/2 < M-1) N++;\n    } else {\n        N = 100;\n    }\n    \n    int E = N*(N-1)/2;\n    vector<int> target(M);\n    for(int k=0;k<M;k++){\n        target[k] = (int)round((double)k * E / (M-1));\n    }\n    // but need target values achievable and distinct when M-1 > E, handle\n    if(M-1 > E){\n        // shouldn't happen with above N selection for small eps; for large eps M<=100 and E=4950\n        for(int k=0;k<M;k++) target[k]=k;\n    }\n    \n    cout << N << \"\\n\";\n    for(int k=0;k<M;k++){\n        string s(E,'0');\n        for(int i=0;i<target[k] && i<E;i++) s[i]='1';\n        cout << s << \"\\n\";\n    }\n    cout.flush();\n    \n    for(int q=0;q<100;q++){\n        string h; cin >> h;\n        int cnt = count(h.begin(),h.end(),'1');\n        // expected edge count for G_k: t(1-eps) + (E-t)*eps = t(1-2eps)+E*eps\n        int best=0; double bd=1e18;\n        for(int k=0;k<M;k++){\n            double exp = target[k]*(1-2*eps) + E*eps;\n            double d = abs(exp - cnt);\n            if(d<bd){bd=d; best=k;}\n        }\n        cout << best << \"\\n\";\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint N, M, D, K;\nvector<vector<pair<int,int>>> adj;\nvector<int> W;\nvector<int> Eu, Ev;\n\nvector<int> sources;\nvector<vector<ll>> baseDist;\n\nvector<int> assign_;\nvector<vector<int>> dayEdges;\nint S;\n\nvector<char> removed;\n\nvector<ll> dijkstra(int src) {\n    vector<ll> dist(N, (ll)2e18);\n    priority_queue<pair<ll,int>, vector<pair<ll,int>>, greater<>> pq;\n    dist[src] = 0;\n    pq.push({0, src});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist[u]) continue;\n        for (auto [v, eid] : adj[u]) {\n            if (removed[eid]) continue;\n            ll nd = d + W[eid];\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                pq.push({nd, v});\n            }\n        }\n    }\n    return dist;\n}\n\ndouble dayCost(int k) {\n    for (int e : dayEdges[k]) removed[e] = 1;\n    double total = 0;\n    for (int si = 0; si < S; si++) {\n        auto dist = dijkstra(sources[si]);\n        for (int v = 0; v < N; v++) {\n            ll dv = (dist[v] >= (ll)1e18) ? 1000000000LL : dist[v];\n            total += (double)(dv - baseDist[si][v]);\n        }\n    }\n    for (int e : dayEdges[k]) removed[e] = 0;\n    return total;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> M >> D >> K;\n    adj.assign(N, {});\n    W.resize(M); Eu.resize(M); Ev.resize(M);\n    for (int i = 0; i < M; i++) {\n        int u,v,w; cin >> u >> v >> w; u--; v--;\n        Eu[i]=u; Ev[i]=v; W[i]=w;\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n    }\n    vector<int> X(N), Y(N);\n    for (int i = 0; i < N; i++) cin >> X[i] >> Y[i];\n    \n    removed.assign(M, 0);\n    \n    mt19937 rng(12345);\n    S = min(N, 40);\n    vector<int> perm(N);\n    iota(perm.begin(), perm.end(), 0);\n    shuffle(perm.begin(), perm.end(), rng);\n    sources.assign(perm.begin(), perm.begin()+S);\n    \n    baseDist.resize(S);\n    for (int i = 0; i < S; i++) baseDist[i] = dijkstra(sources[i]);\n    \n    assign_.assign(M, 0);\n    \n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){\n        double xa = (X[Eu[a]]+X[Ev[a]])*0.5, ya=(Y[Eu[a]]+Y[Ev[a]])*0.5;\n        double xb = (X[Eu[b]]+X[Ev[b]])*0.5, yb=(Y[Eu[b]]+Y[Ev[b]])*0.5;\n        return xa+ya < xb+yb;\n    });\n    \n    vector<int> dayCount(D, 0);\n    for (int i = 0; i < M; i++) {\n        int e = order[i];\n        int d = i % D;\n        while (dayCount[d] >= K) d = (d+1) % D;\n        assign_[e] = d;\n        dayCount[d]++;\n    }\n    \n    dayEdges.assign(D, {});\n    for (int i = 0; i < M; i++) dayEdges[assign_[i]].push_back(i);\n    \n    vector<double> costs(D);\n    for (int k = 0; k < D; k++) costs[k] = dayCost(k);\n    \n    auto start = chrono::steady_clock::now();\n    double TIME_LIMIT = 5.3;\n    auto getTime = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now() - start).count();\n    };\n    \n    int iter = 0, accepted = 0;\n    while (getTime() < TIME_LIMIT) {\n        iter++;\n        int op = rng() % 4;\n        if (op == 0) {\n            int e1 = rng() % M;\n            int d1 = assign_[e1];\n            int d2 = rng() % D;\n            if (d1 == d2) continue;\n            if ((int)dayEdges[d2].size() >= K) continue;\n            \n            auto& v1 = dayEdges[d1];\n            auto it1 = find(v1.begin(), v1.end(), e1);\n            v1.erase(it1);\n            dayEdges[d2].push_back(e1);\n            assign_[e1] = d2;\n            \n            double nc1 = dayCost(d1);\n            double nc2 = dayCost(d2);\n            double delta = (nc1+nc2) - (costs[d1]+costs[d2]);\n            if (delta < 0) {\n                costs[d1]=nc1; costs[d2]=nc2;\n                accepted++;\n            } else {\n                dayEdges[d2].pop_back();\n                v1.push_back(e1);\n                assign_[e1] = d1;\n            }\n        } else {\n            int e1 = rng() % M;\n            int e2 = rng() % M;\n            if (e1 == e2) continue;\n            int d1 = assign_[e1], d2 = assign_[e2];\n            if (d1 == d2) continue;\n            auto& v1 = dayEdges[d1];\n            auto& v2 = dayEdges[d2];\n            *find(v1.begin(), v1.end(), e1) = e2;\n            *find(v2.begin(), v2.end(), e2) = e1;\n            assign_[e1] = d2;\n            assign_[e2] = d1;\n            \n            double nc1 = dayCost(d1);\n            double nc2 = dayCost(d2);\n            double delta = (nc1+nc2) - (costs[d1]+costs[d2]);\n            if (delta < 0) {\n                costs[d1]=nc1; costs[d2]=nc2;\n                accepted++;\n            } else {\n                *find(v1.begin(), v1.end(), e2) = e1;\n                *find(v2.begin(), v2.end(), e1) = e2;\n                assign_[e1] = d1;\n                assign_[e2] = d2;\n            }\n        }\n    }\n    \n    cerr << \"iter=\" << iter << \" acc=\" << accepted << endl;\n    \n    for (int i = 0; i < M; i++) cout << assign_[i]+1 << \" \\n\"[i==M-1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nint F[2][14][14], R[2][14][14];\nint occ[2][14][14][14];\nint bid[2][14][14][14];\n\nint dx6[6]={1,-1,0,0,0,0};\nint dy6[6]={0,0,1,-1,0,0};\nint dz6[6]={0,0,0,0,1,-1};\n\nbool inb(int x,int y,int z){return x>=0&&x<D&&y>=0&&y<D&&z>=0&&z<D;}\n\nint fcount[2][14][14];\nint rcount[2][14][14];\n\nbool canRemove(int i,int x,int y,int z){\n    if(!occ[i][x][y][z]) return false;\n    if(F[i][z][x] && fcount[i][x][z]==1) return false;\n    if(R[i][z][y] && rcount[i][y][z]==1) return false;\n    return true;\n}\nvoid removeCell(int i,int x,int y,int z){\n    occ[i][x][y][z]=0;\n    fcount[i][x][z]--;\n    rcount[i][y][z]--;\n}\n\nmt19937 rng(12345);\n\nint main(){\n    cin>>D;\n    for(int i=0;i<2;i++){\n        for(int z=0;z<D;z++){string s;cin>>s;for(int x=0;x<D;x++)F[i][z][x]=s[x]-'0';}\n        for(int z=0;z<D;z++){string s;cin>>s;for(int y=0;y<D;y++)R[i][z][y]=s[y]-'0';}\n    }\n    for(int i=0;i<2;i++){\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(F[i][z][x]&&R[i][z][y]){\n                occ[i][x][y][z]=1;\n                fcount[i][x][z]++;\n                rcount[i][y][z]++;\n            }\n        }\n    }\n    \n    int nextId = 1;\n    auto chrono_start = chrono::steady_clock::now();\n    double TL = 5.0;\n    \n    auto listAvail = [&](int i){\n        vector<tuple<int,int,int>> v;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n            if(occ[i][x][y][z]&&!bid[i][x][y][z]) v.push_back({x,y,z});\n        return v;\n    };\n    \n    while(true){\n        if(chrono::duration<double>(chrono::steady_clock::now()-chrono_start).count()>TL) break;\n        auto a1 = listAvail(0);\n        auto a2 = listAvail(1);\n        if(a1.empty()||a2.empty()) break;\n        \n        int bestVol = 0;\n        vector<tuple<int,int,int>> bestCells1, bestCells2;\n        \n        shuffle(a1.begin(),a1.end(),rng);\n        shuffle(a2.begin(),a2.end(),rng);\n        \n        int tries1 = min(20, (int)a1.size());\n        int tries2 = min(20, (int)a2.size());\n        for(int t1=0;t1<tries1;t1++){\n            auto [x1,y1,z1] = a1[t1];\n            for(int t2=0;t2<tries2;t2++){\n                auto [x2,y2,z2] = a2[t2];\n                vector<tuple<int,int,int>> block;\n                set<tuple<int,int,int>> inblk;\n                queue<tuple<int,int,int>> q;\n                block.push_back({0,0,0});\n                inblk.insert({0,0,0});\n                q.push({0,0,0});\n                int maxV = 30;\n                while(!q.empty() && (int)block.size()<maxV){\n                    auto [ox,oy,oz] = q.front(); q.pop();\n                    int order[6]={0,1,2,3,4,5};\n                    shuffle(order,order+6,rng);\n                    for(int k=0;k<6;k++){\n                        int d=order[k];\n                        int nx=ox+dx6[d],ny=oy+dy6[d],nz=oz+dz6[d];\n                        if(inblk.count({nx,ny,nz})) continue;\n                        int ax=x1+nx, ay=y1+ny, az=z1+nz;\n                        int bx=x2+nx, by=y2+ny, bz=z2+nz;\n                        if(!inb(ax,ay,az)||!inb(bx,by,bz)) continue;\n                        if(!occ[0][ax][ay][az]||bid[0][ax][ay][az]) continue;\n                        if(!occ[1][bx][by][bz]||bid[1][bx][by][bz]) continue;\n                        inblk.insert({nx,ny,nz});\n                        block.push_back({nx,ny,nz});\n                        q.push({nx,ny,nz});\n                        if((int)block.size()>=maxV) break;\n                    }\n                }\n                if((int)block.size()>bestVol){\n                    bestVol = block.size();\n                    bestCells1.clear(); bestCells2.clear();\n                    for(auto [ox,oy,oz]:block){\n                        bestCells1.push_back({x1+ox,y1+oy,z1+oz});\n                        bestCells2.push_back({x2+ox,y2+oy,z2+oz});\n                    }\n                }\n            }\n        }\n        \n        if(bestVol==0) break;\n        int id = nextId++;\n        for(auto [x,y,z]:bestCells1) bid[0][x][y][z]=id;\n        for(auto [x,y,z]:bestCells2) bid[1][x][y][z]=id;\n    }\n    \n    for(int i=0;i<2;i++){\n        bool changed=true;\n        while(changed){\n            changed=false;\n            for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n                if(occ[i][x][y][z]&&!bid[i][x][y][z]&&canRemove(i,x,y,z)){\n                    removeCell(i,x,y,z);\n                    changed=true;\n                }\n            }\n        }\n    }\n    \n    for(int i=0;i<2;i++){\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(occ[i][x][y][z]&&!bid[i][x][y][z]){\n                bid[i][x][y][z] = nextId++;\n            }\n        }\n    }\n    \n    int n = nextId-1;\n    cout << n << \"\\n\";\n    for(int i=0;i<2;i++){\n        bool first=true;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(!first) cout<<\" \";\n            cout << bid[i][x][y][z];\n            first=false;\n        }\n        cout<<\"\\n\";\n    }\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K;\nvector<int> X, Y;\nvector<int> EU, EV; \nvector<long long> EW;\nvector<int> A, B;\nvector<vector<pair<int,int>>> adj; // vertex -> (neighbor, edge_id)\n\ndouble dist(double x1,double y1,double x2,double y2){\n    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));\n}\n\n// Dijkstra from source, returns dist and parent edge\npair<vector<long long>, vector<int>> dijkstra(int src, const vector<bool>& edgeAllowed){\n    vector<long long> d(N, LLONG_MAX);\n    vector<int> pe(N, -1);\n    d[src]=0;\n    priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;\n    pq.push({0,src});\n    while(!pq.empty()){\n        auto [du,u]=pq.top(); pq.pop();\n        if(du>d[u]) continue;\n        for(auto [v,eid]:adj[u]){\n            if(!edgeAllowed[eid]) continue;\n            long long nd = du + EW[eid];\n            if(nd<d[v]){ d[v]=nd; pe[v]=eid; pq.push({nd,v}); }\n        }\n    }\n    return {d,pe};\n}\n\nint main(){\n    cin>>N>>M>>K;\n    X.resize(N); Y.resize(N);\n    for(int i=0;i<N;i++) cin>>X[i]>>Y[i];\n    EU.resize(M); EV.resize(M); EW.resize(M);\n    adj.assign(N,{});\n    for(int j=0;j<M;j++){\n        cin>>EU[j]>>EV[j]>>EW[j];\n        EU[j]--; EV[j]--;\n        adj[EU[j]].push_back({EV[j],j});\n        adj[EV[j]].push_back({EU[j],j});\n    }\n    A.resize(K); B.resize(K);\n    for(int k=0;k<K;k++) cin>>A[k]>>B[k];\n    \n    // Precompute distance from each vertex to each resident\n    vector<vector<double>> vr(N, vector<double>(K));\n    for(int i=0;i<N;i++)\n        for(int k=0;k<K;k++)\n            vr[i][k] = dist(X[i],Y[i],A[k],B[k]);\n    \n    // Initial assignment: each resident to closest vertex\n    vector<int> assign(K);\n    for(int k=0;k<K;k++){\n        int best=0; double bd=vr[0][k];\n        for(int i=1;i<N;i++) if(vr[i][k]<bd){bd=vr[i][k]; best=i;}\n        assign[k]=best;\n    }\n    \n    auto computeP = [&](const vector<int>& assn)->vector<int>{\n        vector<double> mx(N,0);\n        for(int k=0;k<K;k++) mx[assn[k]] = max(mx[assn[k]], vr[assn[k]][k]);\n        vector<int> P(N,0);\n        for(int i=0;i<N;i++) P[i] = (int)ceil(mx[i]);\n        // Cap at 5000\n        for(int i=0;i<N;i++) if(P[i]>5000) P[i]=5000;\n        return P;\n    };\n    \n    // Build connection: collect active vertices, connect via Steiner tree heuristic\n    // Steiner heuristic: repeatedly add shortest path from current tree to nearest terminal\n    auto buildTree = [&](const vector<int>& P)->vector<int>{\n        vector<bool> terminal(N,false);\n        terminal[0]=true;\n        for(int i=0;i<N;i++) if(P[i]>0) terminal[i]=true;\n        \n        vector<bool> inTree(N,false);\n        inTree[0]=true;\n        vector<int> edgeOn(M,0);\n        vector<bool> allowed(M,true);\n        \n        // Find all terminals\n        vector<int> terms;\n        for(int i=0;i<N;i++) if(terminal[i]) terms.push_back(i);\n        \n        // Repeatedly connect nearest terminal to tree\n        while(true){\n            // Multi-source dijkstra from tree\n            vector<long long> d(N, LLONG_MAX);\n            vector<int> pe(N,-1), pv(N,-1);\n            priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;\n            for(int i=0;i<N;i++) if(inTree[i]){ d[i]=0; pq.push({0,i}); }\n            while(!pq.empty()){\n                auto [du,u]=pq.top(); pq.pop();\n                if(du>d[u]) continue;\n                for(auto [v,eid]:adj[u]){\n                    long long nd = du + EW[eid];\n                    if(nd<d[v]){ d[v]=nd; pe[v]=eid; pv[v]=u; pq.push({nd,v}); }\n                }\n            }\n            // Find nearest non-intree terminal\n            int target=-1; long long bestD=LLONG_MAX;\n            for(int t:terms) if(!inTree[t] && d[t]<bestD){bestD=d[t]; target=t;}\n            if(target==-1) break;\n            // Add path\n            int cur=target;\n            while(!inTree[cur]){\n                int eid=pe[cur];\n                edgeOn[eid]=1;\n                inTree[cur]=true;\n                cur = pv[cur];\n            }\n        }\n        return edgeOn;\n    };\n    \n    auto computeCost = [&](const vector<int>& P, const vector<int>& edgeOn)->long long{\n        long long s=0;\n        for(int i=0;i<N;i++) s += (long long)P[i]*P[i];\n        for(int j=0;j<M;j++) if(edgeOn[j]) s += EW[j];\n        return s;\n    };\n    \n    vector<int> P = computeP(assign);\n    vector<int> edgeOn = buildTree(P);\n    long long bestCost = computeCost(P, edgeOn);\n    vector<int> bestAssign = assign;\n    vector<int> bestP = P;\n    vector<int> bestEdge = edgeOn;\n    \n    // Local search: try removing vertices (reassigning their residents)\n    auto tryImprove = [&](){\n        // For each vertex with residents assigned, try removing it\n        // reassign its residents to some other vertex\n        bool improved=false;\n        for(int v=1;v<N;v++){\n            // collect residents assigned to v\n            vector<int> rs;\n            for(int k=0;k<K;k++) if(bestAssign[k]==v) rs.push_back(k);\n            if(rs.empty()) continue;\n            // try reassign all to best alternative\n            vector<int> newAssign = bestAssign;\n            for(int k:rs){\n                int best=-1; double bd=1e18;\n                for(int i=0;i<N;i++) if(i!=v){\n                    // cost of assigning k to i: need P_i >= vr[i][k]\n                    // use heuristic: just nearest\n                    if(vr[i][k]<bd){bd=vr[i][k]; best=i;}\n                }\n                newAssign[k]=best;\n            }\n            vector<int> newP = computeP(newAssign);\n            vector<int> newEdge = buildTree(newP);\n            long long nc = computeCost(newP,newEdge);\n            if(nc<bestCost){\n                bestCost=nc;\n                bestAssign=newAssign;\n                bestP=newP;\n                bestEdge=newEdge;\n                improved=true;\n            }\n        }\n        return improved;\n    };\n    \n    auto startT = chrono::steady_clock::now();\n    auto elapsed = [&](){return chrono::duration<double>(chrono::steady_clock::now()-startT).count();};\n    \n    // Iterative improvement\n    for(int iter=0;iter<20 && elapsed()<1.5;iter++){\n        if(!tryImprove()) break;\n    }\n    \n    // Try moving single residents to different vertices\n    mt19937 rng(42);\n    while(elapsed()<1.7){\n        int k = rng()%K;\n        int oldv = bestAssign[k];\n        int newv = rng()%N;\n        if(newv==oldv) continue;\n        vector<int> newAssign = bestAssign;\n        newAssign[k]=newv;\n        vector<int> newP = computeP(newAssign);\n        // quick check: only rebuild if P changes significantly\n        bool pchange=false;\n        for(int i=0;i<N;i++) if((newP[i]>0) != (bestP[i]>0)) {pchange=true; break;}\n        vector<int> newEdge;\n        if(pchange) newEdge = buildTree(newP);\n        else newEdge = bestEdge;\n        // verify tree still connects all active\n        // (it should if active set is subset, but check)\n        // If active set shrunk, existing tree might have extra but that's fine cost-wise if we prune\n        // Actually edges are in tree - if an active vertex becomes inactive, we could save edges\n        // For simplicity always rebuild when active set changes\n        long long nc = computeCost(newP,newEdge);\n        if(nc<bestCost){\n            bestCost=nc;\n            bestAssign=newAssign;\n            bestP=newP;\n            bestEdge=newEdge;\n        }\n    }\n    \n    // Output\n    for(int i=0;i<N;i++) cout<<bestP[i]<<\" \\n\"[i==N-1];\n    for(int j=0;j<M;j++) cout<<bestEdge[j]<<\" \\n\"[j==M-1];\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\nint N=30;\nint grid[30][30];\npair<int,int> pos[465];\nvector<tuple<int,int,int,int>> ops;\nvoid doSwap(int x1,int y1,int x2,int y2){\n    ops.push_back({x1,y1,x2,y2});\n    int v1=grid[x1][y1], v2=grid[x2][y2];\n    swap(grid[x1][y1],grid[x2][y2]);\n    pos[v1]={x2,y2}; pos[v2]={x1,y1};\n}\nint main(){\n    for(int x=0;x<N;x++)for(int y=0;y<=x;y++){\n        cin>>grid[x][y]; pos[grid[x][y]]={x,y};\n    }\n    int k=0;\n    for(int tx=0;tx<N-1;tx++)for(int ty=0;ty<=tx;ty++){\n        auto [cx,cy]=pos[k];\n        while(cx>tx || cy>ty){\n            if(cx==tx){ doSwap(cx,cy,cx,cy-1); cy--; }\n            else if(cy<ty){ doSwap(cx,cy,cx,cy+1); cy++; }\n            else if(cy>ty){ doSwap(cx,cy,cx-1,cy-1); cx--;cy--; }\n            else { doSwap(cx,cy,cx-1,cy); cx--; }\n        }\n        k++;\n    }\n    cout<<ops.size()<<\"\\n\";\n    for(auto[a,b,c,d]:ops)cout<<a<<\" \"<<b<<\" \"<<c<<\" \"<<d<<\"\\n\";\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N;\nbool obs[9][9];\nint dr[]={-1,1,0,0}, dc[]={0,0,-1,1};\n\nint main(){\n    cin>>D>>N;\n    for(int i=0;i<N;i++){int r,c;cin>>r>>c;obs[r][c]=true;}\n    int M=D*D-1-N;\n    \n    vector<pair<int,int>> order;\n    vector<vector<bool>> visited(9,vector<bool>(9,false));\n    function<void(int,int)> dfs=[&](int r,int c){\n        visited[r][c]=true;\n        if(!(r==0&&c==4)) order.push_back({r,c});\n        int dirs[]={1,2,3,0};\n        for(int d:dirs){\n            int nr=r+dr[d], nc=c+dc[d];\n            if(nr<0||nr>=9||nc<0||nc>=9) continue;\n            if(visited[nr][nc]||obs[nr][nc]) continue;\n            dfs(nr,nc);\n        }\n    };\n    dfs(0,4);\n    \n    vector<vector<int>> pidx(9,vector<int>(9,-1));\n    for(int k=0;k<(int)order.size();k++) pidx[order[k].first][order[k].second]=k;\n    \n    vector<vector<bool>> filled(9,vector<bool>(9,false));\n    vector<vector<int>> cellVal(9,vector<int>(9,-1));\n    \n    auto computeReach=[&](){\n        vector<vector<bool>> vis(9,vector<bool>(9,false));\n        queue<pair<int,int>> q;\n        vis[0][4]=true; q.push({0,4});\n        while(!q.empty()){\n            auto [r,c]=q.front(); q.pop();\n            for(int d=0;d<4;d++){\n                int nr=r+dr[d], nc=c+dc[d];\n                if(nr<0||nr>=9||nc<0||nc>=9) continue;\n                if(vis[nr][nc]||obs[nr][nc]||filled[nr][nc]) continue;\n                vis[nr][nc]=true; q.push({nr,nc});\n            }\n        }\n        return vis;\n    };\n    \n    for(int d=0;d<M;d++){\n        int t; cin>>t;\n        auto vis=computeReach();\n        int bestK=-1, bestDiff=INT_MAX;\n        for(int r=0;r<9;r++)for(int c=0;c<9;c++){\n            if(obs[r][c]||filled[r][c]) continue;\n            if(r==0&&c==4) continue;\n            if(!vis[r][c]) continue;\n            int k=pidx[r][c];\n            int diff=abs(k-t);\n            if(diff<bestDiff){bestDiff=diff;bestK=k;}\n        }\n        auto [pr,pc]=order[bestK];\n        filled[pr][pc]=true;\n        cellVal[pr][pc]=t;\n        cout<<pr<<\" \"<<pc<<\"\\n\";\n        cout.flush();\n    }\n    \n    for(int step=0;step<M;step++){\n        vector<vector<bool>> emptyVis(9,vector<bool>(9,false));\n        queue<pair<int,int>> q;\n        emptyVis[0][4]=true; q.push({0,4});\n        while(!q.empty()){\n            auto [r,c]=q.front();q.pop();\n            for(int di=0;di<4;di++){\n                int nr=r+dr[di],nc=c+dc[di];\n                if(nr<0||nr>=9||nc<0||nc>=9)continue;\n                if(emptyVis[nr][nc]||obs[nr][nc]||filled[nr][nc])continue;\n                emptyVis[nr][nc]=true; q.push({nr,nc});\n            }\n        }\n        int bestVal=INT_MAX, br=-1,bc=-1;\n        for(int r=0;r<9;r++)for(int c=0;c<9;c++){\n            if(!filled[r][c])continue;\n            bool adj=false;\n            for(int di=0;di<4;di++){\n                int nr=r+dr[di],nc=c+dc[di];\n                if(nr<0||nr>=9||nc<0||nc>=9)continue;\n                if(emptyVis[nr][nc]){adj=true;break;}\n            }\n            if(!adj)continue;\n            int v=cellVal[r][c];\n            if(v<bestVal){bestVal=v;br=r;bc=c;}\n        }\n        filled[br][bc]=false;\n        cout<<br<<\" \"<<bc<<\"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nvector<vector<int>> grid;\nint DX[4]={-1,1,0,0}, DY[4]={0,0,-1,1};\nvector<vector<int>> origAdj;\nvector<vector<int>> cnt;\n\nbool removable(int r, int c, int F){\n    vector<pair<int,int>> sames;\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&&grid[nr][nc]==F)sames.push_back({nr,nc});\n    }\n    if(sames.empty()) return false;\n    vector<vector<bool>> vis(n, vector<bool>(n,false));\n    queue<pair<int,int>> q;\n    q.push(sames[0]); vis[sames[0].first][sames[0].second]=true;\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(nx<0||nx>=n||ny<0||ny>=n)continue;\n            if(vis[nx][ny])continue;\n            if(nx==r&&ny==c)continue;\n            if(grid[nx][ny]!=F)continue;\n            vis[nx][ny]=true;\n            q.push({nx,ny});\n        }\n    }\n    for(auto[x,y]:sames)if(!vis[x][y])return false;\n    return true;\n}\n\nbool tryChange(int r, int c, int T){\n    int F = grid[r][c];\n    if(F==T)return false;\n    int nbrs[4];\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)nbrs[d]=0;\n        else nbrs[d]=grid[nr][nc];\n    }\n    bool tOk=false;\n    if(T==0){\n        if(r==0||r==n-1||c==0||c==n-1) tOk=true;\n        else for(int d=0;d<4;d++)if(nbrs[d]==0){tOk=true;break;}\n    } else {\n        for(int d=0;d<4;d++)if(nbrs[d]==T){tOk=true;break;}\n    }\n    if(!tOk) return false;\n    \n    auto modify=[&](int F_, int T_){\n        for(int d=0;d<4;d++){\n            int N=nbrs[d];\n            if(F_ != N){ cnt[F_][N]--; cnt[N][F_]--; }\n            if(T_ != N){ cnt[T_][N]++; cnt[N][T_]++; }\n        }\n    };\n    modify(F,T);\n    \n    bool ok=true;\n    set<int> affected; affected.insert(F); affected.insert(T);\n    for(int d=0;d<4;d++) affected.insert(nbrs[d]);\n    for(int a: affected){\n        if(!ok)break;\n        for(int b=0;b<=m;b++){\n            if(a==b)continue;\n            bool was = origAdj[a][b]!=0;\n            bool isnow = cnt[a][b]>0;\n            if(was != isnow){ok=false;break;}\n        }\n    }\n    if(!ok){\n        modify(T,F);\n        return false;\n    }\n    \n    grid[r][c]=T;\n    if(!removable(r,c,F)){\n        grid[r][c]=F;\n        modify(T,F);\n        return false;\n    }\n    return true;\n}\n\nint main(){\n    cin>>n>>m;\n    grid.assign(n,vector<int>(n));\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)cin>>grid[i][j];\n    \n    cnt.assign(m+1, vector<int>(m+1, 0));\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        int a=grid[i][j];\n        for(int d=0;d<4;d++){\n            int ni=i+DX[d],nj=j+DY[d];\n            if(ni<0||ni>=n||nj<0||nj>=n){\n                cnt[a][0]++; cnt[0][a]++;\n            } else {\n                int b=grid[ni][nj];\n                cnt[a][b]++;\n            }\n        }\n    }\n    origAdj.assign(m+1, vector<int>(m+1,0));\n    for(int a=0;a<=m;a++)for(int b=0;b<=m;b++)if(a!=b && cnt[a][b]>0)origAdj[a][b]=1;\n    \n    auto startTime = chrono::steady_clock::now();\n    mt19937 rng(42);\n    \n    int noImprove=0;\n    while(noImprove<3){\n        auto now = chrono::steady_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-startTime).count() > 1700) break;\n        bool improved=false;\n        vector<pair<int,int>> cells;\n        for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(grid[i][j]!=0)cells.push_back({i,j});\n        shuffle(cells.begin(), cells.end(), rng);\n        for(auto[r,c]:cells){\n            if(grid[r][c]==0)continue;\n            if(tryChange(r,c,0))improved=true;\n        }\n        if(!improved) noImprove++;\n        else noImprove=0;\n    }\n    \n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            cout<<grid[i][j]<<(j+1<n?' ':'\\n');\n        }\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\nint ask(const vector<int>& L, const vector<int>& R) {\n    queries_used++;\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << \"\\n\";\n    cout.flush();\n    char c; cin >> c;\n    if (c == '<') return -1;\n    if (c == '>') return 1;\n    return 0;\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    int reserve = max(2*D, min(Q/3, 15*D));\n    \n    function<vector<int>(vector<int>)> msort = [&](vector<int> v) -> vector<int> {\n        if (v.size() <= 1) return v;\n        int mid = v.size()/2;\n        vector<int> L(v.begin(), v.begin()+mid);\n        vector<int> R(v.begin()+mid, v.end());\n        L = msort(L);\n        R = msort(R);\n        vector<int> res;\n        int i=0,j=0;\n        while (i<(int)L.size() && j<(int)R.size()) {\n            if (queries_used >= Q - reserve) {\n                while (i<(int)L.size()) res.push_back(L[i++]);\n                while (j<(int)R.size()) res.push_back(R[j++]);\n                return res;\n            }\n            int c = ask({L[i]}, {R[j]});\n            if (c <= 0) res.push_back(L[i++]);\n            else res.push_back(R[j++]);\n        }\n        while (i<(int)L.size()) res.push_back(L[i++]);\n        while (j<(int)R.size()) res.push_back(R[j++]);\n        return res;\n    };\n    \n    vector<int> sorted_items = msort(items);\n    reverse(sorted_items.begin(), sorted_items.end());\n    \n    vector<int> rank_of(N);\n    for (int i = 0; i < N; i++) rank_of[sorted_items[i]] = i;\n    \n    auto estimate = [&](const vector<int>& g) {\n        double s = 0;\n        for (int x : g) s += exp(-rank_of[x] * 0.03);\n        return s;\n    };\n    \n    vector<vector<int>> groups(D);\n    for (int i = 0; i < D && i < N; i++) groups[i].push_back(sorted_items[i]);\n    for (int i = D; i < N; i++) {\n        int best = 0;\n        double bestv = estimate(groups[0]);\n        for (int d = 1; d < D; d++) {\n            double v = estimate(groups[d]);\n            if (v < bestv) { bestv = v; best = d; }\n        }\n        groups[best].push_back(sorted_items[i]);\n    }\n    \n    int fail_count = 0;\n    while (queries_used < Q) {\n        int heavy = 0, light = 0;\n        double hv = estimate(groups[0]), lv = hv;\n        for (int d = 1; d < D; d++) {\n            double v = estimate(groups[d]);\n            if (v > hv) { hv = v; heavy = d; }\n            if (v < lv) { lv = v; light = d; }\n        }\n        if (heavy == light) {\n            while (queries_used < Q) ask({0}, {1});\n            break;\n        }\n        \n        if (queries_used >= Q) break;\n        int c = ask(groups[heavy], groups[light]);\n        if (c == 0) {\n            if (fail_count++ > 5) { while (queries_used < Q) ask({0}, {1}); break; }\n            continue;\n        }\n        if (c < 0) swap(heavy, light);\n        \n        bool improved = false;\n        vector<int> hi = groups[heavy];\n        sort(hi.begin(), hi.end(), [&](int a, int b){ return rank_of[a] > rank_of[b]; });\n        \n        for (int x : hi) {\n            if ((int)groups[heavy].size() <= 1) break;\n            if (queries_used >= Q) break;\n            vector<int> nh, nl = groups[light];\n            for (int y : groups[heavy]) if (y != x) nh.push_back(y);\n            nl.push_back(x);\n            int c2 = ask(nh, nl);\n            if (c2 >= 0) {\n                groups[heavy] = nh;\n                groups[light] = nl;\n                improved = true;\n                break;\n            }\n            break;\n        }\n        \n        if (!improved && queries_used < Q) {\n            vector<tuple<int,int,int>> pairs;\n            for (int a : groups[heavy]) for (int b : groups[light]) {\n                if (rank_of[a] < rank_of[b]) \n                    pairs.push_back({rank_of[b] - rank_of[a], a, b});\n            }\n            sort(pairs.begin(), pairs.end());\n            \n            for (auto& [_, a, b] : pairs) {\n                if (queries_used >= Q) break;\n                vector<int> nh, nl;\n                for (int y : groups[heavy]) nh.push_back(y == a ? b : y);\n                for (int y : groups[light]) nl.push_back(y == b ? a : y);\n                int c2 = ask(nh, nl);\n                if (c2 >= 0) {\n                    groups[heavy] = nh;\n                    groups[light] = nl;\n                    improved = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!improved) fail_count++;\n        else fail_count = 0;\n        \n        if (fail_count > 10) {\n            while (queries_used < Q) ask({0}, {1});\n            break;\n        }\n    }\n    \n    vector<int> d(N, 0);\n    for (int g = 0; g < D; g++) for (int x : groups[g]) d[x] = g;\n    for (int i = 0; i < N; i++) {\n        cout << d[i];\n        cout << (i == N-1 ? '\\n' : ' ');\n    }\n    cout.flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nvector<vector<int>> stk;\nvector<pair<int,int>> ops;\n\nint main() {\n    cin >> n >> m;\n    stk.assign(m, {});\n    for (int i = 0; i < m; i++) {\n        stk[i].resize(n/m);\n        for (int j = 0; j < n/m; j++) cin >> stk[i][j];\n    }\n    \n    for (int v = 1; v <= n; v++) {\n        int si = -1, pos = -1;\n        for (int i = 0; i < m && si == -1; i++)\n            for (int j = 0; j < (int)stk[i].size(); j++)\n                if (stk[i][j]==v) { si=i; pos=j; break; }\n        \n        int above = stk[si].size() - 1 - pos;\n        \n        if (above > 0) {\n            vector<int> moved(stk[si].begin()+pos+1, stk[si].end());\n            int maxMoved = *max_element(moved.begin(), moved.end());\n            \n            int best = -1;\n            int bestGoodTop = INT_MAX;\n            for (int i = 0; i < m; i++) {\n                if (i == si) continue;\n                int t = stk[i].empty() ? n+10 : stk[i].back();\n                if (t > maxMoved && t < bestGoodTop) {\n                    bestGoodTop = t; best = i;\n                }\n            }\n            \n            if (best == -1) {\n                int maxTop = -1;\n                for (int i = 0; i < m; i++) {\n                    if (i == si) continue;\n                    int t = stk[i].empty() ? n+10 : stk[i].back();\n                    if (t > maxTop) { maxTop = t; best = i; }\n                }\n            }\n            \n            ops.push_back({moved[0], best+1});\n            stk[si].resize(pos+1);\n            for (int x : moved) stk[best].push_back(x);\n        }\n        \n        ops.push_back({v, 0});\n        stk[si].pop_back();\n    }\n    \n    for (auto [a,b] : ops) cout << a << \" \" << b << \"\\n\";\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> hh, vv;\nvector<vector<int>> d;\nint dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};\nchar DC[4]={'U','D','L','R'};\n\nbool canMove(int x,int y,int dir){\n    int nx=x+dx[dir], ny=y+dy[dir];\n    if(nx<0||nx>=N||ny<0||ny>=N) return false;\n    if(dir==0) return hh[nx][y]=='0';\n    if(dir==1) return hh[x][y]=='0';\n    if(dir==2) return vv[x][ny]=='0';\n    if(dir==3) return vv[x][y]=='0';\n    return false;\n}\n\nvector<vector<vector<vector<int>>>> allPar;\n\nvoid computeAllDist(){\n    allPar.assign(N,vector<vector<vector<int>>>(N,vector<vector<int>>(N,vector<int>(N,-1))));\n    for(int sx=0;sx<N;sx++)for(int sy=0;sy<N;sy++){\n        vector<vector<int>> D(N,vector<int>(N,INT_MAX));\n        auto& P=allPar[sx][sy];\n        D[sx][sy]=0;\n        queue<pair<int,int>> q; q.push({sx,sy});\n        while(!q.empty()){\n            auto [x,y]=q.front(); q.pop();\n            for(int d2=0;d2<4;d2++) if(canMove(x,y,d2)){\n                int nx=x+dx[d2], ny=y+dy[d2];\n                if(D[nx][ny]>D[x][y]+1){ D[nx][ny]=D[x][y]+1; P[nx][ny]=d2; q.push({nx,ny}); }\n            }\n        }\n    }\n}\n\nvector<int> getPath(int sx,int sy,int tx,int ty){\n    vector<int> res;\n    int x=tx,y=ty;\n    while(!(x==sx&&y==sy)){\n        int dir=allPar[sx][sy][x][y];\n        if(dir<0) return {};\n        res.push_back(dir);\n        int rdir = dir^1;\n        x+=dx[rdir]; y+=dy[rdir];\n    }\n    reverse(res.begin(),res.end());\n    return res;\n}\n\nvector<int> tour;\nvector<vector<bool>> visited;\nvoid dfs(int x,int y){\n    visited[x][y]=true;\n    for(int dir=0;dir<4;dir++){\n        if(canMove(x,y,dir)){\n            int nx=x+dx[dir],ny=y+dy[dir];\n            if(!visited[nx][ny]){\n                tour.push_back(dir);\n                dfs(nx,ny);\n                tour.push_back(dir^1);\n            }\n        }\n    }\n}\n\ndouble computeScore(const vector<int>& tr){\n    int L=tr.size();\n    if(L==0) return 1e18;\n    vector<vector<vector<int>>> times(N,vector<vector<int>>(N));\n    int x=0,y=0;\n    times[0][0].push_back(0);\n    for(int t=0;t<L;t++){\n        x+=dx[tr[t]]; y+=dy[tr[t]];\n        times[x][y].push_back(t+1);\n    }\n    if(x!=0||y!=0) return 1e18;\n    double total=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        auto& T=times[i][j];\n        if(T.empty()) return 1e18;\n        vector<int> U;\n        for(int t:T) if(t<L) U.push_back(t);\n        sort(U.begin(),U.end());\n        U.erase(unique(U.begin(),U.end()),U.end());\n        int k=U.size();\n        if(k==0) return 1e18;\n        long long sumSq=0;\n        for(int m=0;m<k;m++){\n            int g = (m+1<k? U[m+1]-U[m] : U[0]+L-U[m]);\n            sumSq += (long long)g*(g-1)/2;\n        }\n        total += (double)d[i][j] * sumSq;\n    }\n    return total / L;\n}\n\nint main(){\n    cin>>N;\n    hh.resize(N-1); for(auto&s:hh)cin>>s;\n    vv.resize(N); for(auto&s:vv)cin>>s;\n    d.assign(N,vector<int>(N));\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>d[i][j];\n    \n    computeAllDist();\n    \n    visited.assign(N,vector<bool>(N,false));\n    dfs(0,0);\n    \n    double curScore = computeScore(tour);\n    \n    mt19937 rng(12345);\n    auto startTime = chrono::steady_clock::now();\n    auto timeLeft = [&](){\n        auto now = chrono::steady_clock::now();\n        double el = chrono::duration<double>(now-startTime).count();\n        return 1.8 - el;\n    };\n    \n    vector<tuple<int,int,int>> cells;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) cells.push_back({d[i][j],i,j});\n    sort(cells.rbegin(),cells.rend());\n    \n    while(timeLeft()>0.05){\n        int mode = rng()%3;\n        if(mode==0){\n            int ci = rng() % min((int)cells.size(), 30);\n            auto [dv,ti,tj] = cells[ci];\n            int L = tour.size();\n            if(L>95000) { mode=1; }\n            else {\n                int pos = rng()%(L+1);\n                int cx=0,cy=0;\n                for(int t=0;t<pos;t++){ cx+=dx[tour[t]]; cy+=dy[tour[t]]; }\n                if(cx==ti&&cy==tj) continue;\n                auto p1 = getPath(cx,cy,ti,tj);\n                auto p2 = getPath(ti,tj,cx,cy);\n                if((int)(L+p1.size()+p2.size())>100000) continue;\n                vector<int> newTour;\n                newTour.reserve(L+p1.size()+p2.size());\n                for(int t=0;t<pos;t++) newTour.push_back(tour[t]);\n                for(int x:p1) newTour.push_back(x);\n                for(int x:p2) newTour.push_back(x);\n                for(int t=pos;t<L;t++) newTour.push_back(tour[t]);\n                double ns = computeScore(newTour);\n                if(ns<curScore){ tour=newTour; curScore=ns; }\n                continue;\n            }\n        }\n        if(mode==1){\n            int L=tour.size();\n            if(L<10) continue;\n            int a=rng()%L;\n            int maxlen = min(300,L-a-1);\n            if(maxlen<2) continue;\n            int b=a+2+rng()%(maxlen-1);\n            if(b>L) continue;\n            int ax=0,ay=0;\n            for(int t=0;t<a;t++){ax+=dx[tour[t]];ay+=dy[tour[t]];}\n            int bx=ax,by=ay;\n            for(int t=a;t<b;t++){bx+=dx[tour[t]];by+=dy[tour[t]];}\n            auto p = getPath(ax,ay,bx,by);\n            if((int)p.size()>=b-a) continue;\n            vector<int> newTour;\n            for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n            for(int x:p) newTour.push_back(x);\n            for(int t=b;t<L;t++) newTour.push_back(tour[t]);\n            double ns = computeScore(newTour);\n            if(ns<curScore){ tour=newTour; curScore=ns; }\n        } else {\n            int L=tour.size();\n            if(L<4) continue;\n            int a=rng()%(L-1);\n            if(tour[a]==(tour[a+1]^1)){\n                vector<int> newTour;\n                for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n                for(int t=a+2;t<L;t++) newTour.push_back(tour[t]);\n                double ns = computeScore(newTour);\n                if(ns<curScore){ tour=newTour; curScore=ns; }\n            }\n        }\n    }\n    \n    for(int dir:tour) cout<<DC[dir];\n    cout<<endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint si, sj;\nvector<string> grid;\nvector<string> words;\nvector<vector<pair<int,int>>> posOf(26);\n\nint distm(int r1,int c1,int r2,int c2){ return abs(r1-r2)+abs(c1-c2)+1; }\n\nstruct Result { int cost; int endR, endC; vector<pair<int,int>> path; };\n\nResult typeWord(int wi, int s, int pr, int pc){\n    string& w = words[wi];\n    int len = 5 - s;\n    if(len==0){\n        Result r; r.cost=0; r.endR=pr; r.endC=pc; return r;\n    }\n    vector<vector<int>> dp(len);\n    vector<vector<int>> par(len);\n    for(int i=0;i<len;i++){\n        char c = w[s+i];\n        int sz = posOf[c-'A'].size();\n        dp[i].assign(sz, INT_MAX);\n        par[i].assign(sz, -1);\n    }\n    {\n        char c = w[s];\n        for(int k=0;k<(int)posOf[c-'A'].size();k++){\n            auto [r,cc] = posOf[c-'A'][k];\n            dp[0][k] = distm(pr,pc,r,cc);\n        }\n    }\n    for(int i=1;i<len;i++){\n        char cprev = w[s+i-1];\n        char ccur = w[s+i];\n        auto& pp = posOf[cprev-'A'];\n        auto& pc2 = posOf[ccur-'A'];\n        for(int k=0;k<(int)pc2.size();k++){\n            auto [r,cc]=pc2[k];\n            for(int j=0;j<(int)pp.size();j++){\n                if(dp[i-1][j]==INT_MAX) continue;\n                auto [pr2,pc3]=pp[j];\n                int nc = dp[i-1][j] + distm(pr2,pc3,r,cc);\n                if(nc<dp[i][k]){ dp[i][k]=nc; par[i][k]=j; }\n            }\n        }\n    }\n    int best=INT_MAX, bk=-1;\n    for(int k=0;k<(int)dp[len-1].size();k++){\n        if(dp[len-1][k]<best){best=dp[len-1][k]; bk=k;}\n    }\n    Result res;\n    res.cost = best;\n    vector<int> idx(len);\n    idx[len-1]=bk;\n    for(int i=len-1;i>0;i--) idx[i-1]=par[i][idx[i]];\n    res.path.resize(len);\n    for(int i=0;i<len;i++){\n        char c = w[s+i];\n        res.path[i] = posOf[c-'A'][idx[i]];\n    }\n    res.endR = res.path.back().first;\n    res.endC = res.path.back().second;\n    return res;\n}\n\nint main(){\n    cin>>N>>M>>si>>sj;\n    grid.resize(N);\n    for(int i=0;i<N;i++) cin>>grid[i];\n    words.resize(M);\n    for(int i=0;i<M;i++) cin>>words[i];\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) posOf[grid[i][j]-'A'].push_back({i,j});\n    \n    vector<vector<int>> overlap(M, vector<int>(M,0));\n    for(int i=0;i<M;i++)for(int j=0;j<M;j++){\n        if(i==j) continue;\n        for(int k=4;k>=1;k--){\n            if(words[i].substr(5-k)==words[j].substr(0,k)){overlap[i][j]=k;break;}\n        }\n    }\n    \n    // Remove words that are substrings of others? Word length is 5, all distinct. Can a word be substring of another? No, all length 5 and distinct.\n    // But a word could appear inside concatenation of others. Skip this optimization.\n    \n    vector<bool> used(M,false);\n    vector<int> order;\n    int curR=si, curC=sj;\n    \n    for(int step=0;step<M;step++){\n        int bestW=-1;\n        int bestScore=INT_MAX;\n        int bestER=0, bestEC=0;\n        for(int w=0;w<M;w++) if(!used[w]){\n            int ov = order.empty()?0:overlap[order.back()][w];\n            Result r = typeWord(w, ov, curR, curC);\n            if(r.cost < bestScore){\n                bestScore = r.cost; bestW=w; bestER=r.endR; bestEC=r.endC;\n            }\n        }\n        used[bestW]=true;\n        order.push_back(bestW);\n        curR=bestER; curC=bestEC;\n    }\n    \n    vector<pair<int,int>> output;\n    curR=si; curC=sj;\n    for(int i=0;i<M;i++){\n        int ov = (i==0)?0:overlap[order[i-1]][order[i]];\n        Result r = typeWord(order[i], ov, curR, curC);\n        for(auto& p:r.path) output.push_back(p);\n        curR=r.endR; curC=r.endC;\n    }\n    \n    for(auto& p:output) cout<<p.first<<\" \"<<p.second<<\"\\n\";\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble EPS;\nvector<vector<pair<int,int>>> polys;\nvector<vector<pair<int,int>>> placements; // all possible (di,dj) for each poly\nvector<vector<vector<int>>> placement_cells; // flat cell indices for each placement\n\nmt19937 rng(12345);\n\nstruct Query {\n    vector<int> cells; // flat indices\n    int result;\n    bool exact; // drilling\n};\n\nvector<Query> queries;\nint total_cost_queries = 0;\ndouble total_cost = 0;\n\nint readInt() { int x; cin >> x; return x; }\n\nint drill(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int v; cin >> v;\n    total_cost += 1.0;\n    Query q; q.cells = {i*N+j}; q.result = v; q.exact = true;\n    queries.push_back(q);\n    return v;\n}\n\nint divine(vector<int>& cells) {\n    cout << \"q \" << cells.size();\n    for (int c : cells) cout << \" \" << c/N << \" \" << c%N;\n    cout << endl;\n    cout.flush();\n    int v; cin >> v;\n    total_cost += 1.0 / sqrt((double)cells.size());\n    Query q; q.cells = cells; q.result = v; q.exact = false;\n    queries.push_back(q);\n    return v;\n}\n\nint answer(vector<int>& cells) {\n    cout << \"a \" << cells.size();\n    for (int c : cells) cout << \" \" << c/N << \" \" << c%N;\n    cout << endl;\n    cout.flush();\n    int r; cin >> r;\n    return r;\n}\n\n// Given placement configuration (one placement index per polyomino), compute v grid\nvector<int> configToGrid(const vector<int>& conf) {\n    vector<int> g(N*N, 0);\n    for (int k = 0; k < M; k++) {\n        for (int c : placement_cells[k][conf[k]]) g[c]++;\n    }\n    return g;\n}\n\n// log prob of observing query result given true value v(S) = trueSum, |S|=k\ndouble logLikelihood(int trueSum, int k, int observed, bool exact) {\n    if (exact) {\n        return (trueSum == observed) ? 0.0 : -1e18;\n    }\n    // mu = (k-trueSum)*eps + trueSum*(1-eps)\n    double mu = (k - trueSum) * EPS + trueSum * (1.0 - EPS);\n    double var = k * EPS * (1.0 - EPS);\n    if (var < 1e-9) var = 1e-9;\n    // P(observed) ~ integral from observed-0.5 to observed+0.5 of N(mu,var)\n    // for observed=0: integral from -inf to 0.5\n    double sd = sqrt(var);\n    double lo, hi;\n    if (observed == 0) {\n        lo = -1e18;\n        hi = 0.5;\n    } else {\n        lo = observed - 0.5;\n        hi = observed + 0.5;\n    }\n    // use erf\n    auto phi = [&](double x) { return 0.5 * (1.0 + erf((x - mu) / (sd * sqrt(2.0)))); };\n    double p;\n    if (lo < -1e17) p = phi(hi);\n    else p = phi(hi) - phi(lo);\n    if (p < 1e-300) p = 1e-300;\n    return log(p);\n}\n\nint main() {\n    cin >> N >> M >> EPS;\n    polys.resize(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        polys[k].resize(d);\n        for (int i = 0; i < d; i++) cin >> polys[k][i].first >> polys[k][i].second;\n    }\n    \n    // Compute placements\n    placements.resize(M);\n    placement_cells.resize(M);\n    long long totalConfigs = 1;\n    for (int k = 0; k < M; k++) {\n        int mi = 0, mj = 0;\n        for (auto& p : polys[k]) { mi = max(mi, p.first); mj = max(mj, p.second); }\n        for (int di = 0; di + mi < N; di++) {\n            for (int dj = 0; dj + mj < N; dj++) {\n                placements[k].push_back({di, dj});\n                vector<int> cs;\n                for (auto& p : polys[k]) cs.push_back((p.first+di)*N + (p.second+dj));\n                placement_cells[k].push_back(cs);\n            }\n        }\n        totalConfigs *= placements[k].size();\n    }\n    \n    bool smallCase = (totalConfigs <= 200000);\n    \n    if (smallCase) {\n        // Enumerate all configs\n        vector<vector<int>> allConfs;\n        vector<int> cur(M, 0);\n        function<void(int)> gen = [&](int k) {\n            if (k == M) { allConfs.push_back(cur); return; }\n            for (int i = 0; i < (int)placements[k].size(); i++) {\n                cur[k] = i;\n                gen(k+1);\n            }\n        };\n        gen(0);\n        \n        int nConf = allConfs.size();\n        vector<double> logP(nConf, 0.0);\n        // uniform prior\n        \n        // Strategy: iteratively query to narrow down\n        int maxQueries = 2*N*N;\n        \n        auto normalize = [&]() {\n            double mx = *max_element(logP.begin(), logP.end());\n            double sum = 0;\n            for (auto& x : logP) sum += exp(x - mx);\n            double lsum = mx + log(sum);\n            for (auto& x : logP) x -= lsum;\n        };\n        \n        auto topProb = [&]() -> pair<int,double> {\n            int best = 0;\n            for (int i = 1; i < nConf; i++) if (logP[i] > logP[best]) best = i;\n            double mx = logP[best];\n            double sum = 0;\n            for (auto& x : logP) sum += exp(x - mx);\n            return {best, 1.0 / sum};\n        };\n        \n        while ((int)queries.size() < maxQueries - 1) {\n            normalize();\n            auto [best, prob] = topProb();\n            \n            if (prob > 0.85) {\n                // Submit\n                vector<int> grid = configToGrid(allConfs[best]);\n                vector<int> ans;\n                for (int i = 0; i < N*N; i++) if (grid[i] > 0) ans.push_back(i);\n                int r = answer(ans);\n                if (r == 1) return 0;\n                // wrong - eliminate this config\n                logP[best] = -1e18;\n                continue;\n            }\n            \n            // Choose a query: pick a cell with highest entropy\n            // Compute marginal distribution of v(i,j) under posterior\n            // Pick cell that maximizes entropy\n            \n            // Simpler: pick cells where probability is near 0.5 of having oil\n            vector<double> pOil(N*N, 0.0);\n            double totalW = 0;\n            for (int c = 0; c < nConf; c++) {\n                double w = exp(logP[c]);\n                totalW += w;\n                vector<int> g = configToGrid(allConfs[c]);\n                for (int i = 0; i < N*N; i++) if (g[i] > 0) pOil[i] += w;\n            }\n            for (auto& x : pOil) x /= totalW;\n            \n            // Choose cell with probability closest to 0.5\n            int bestCell = -1;\n            double bestScore = -1;\n            for (int i = 0; i < N*N; i++) {\n                double s = min(pOil[i], 1.0 - pOil[i]);\n                if (s > bestScore) { bestScore = s; bestCell = i; }\n            }\n            \n            if (bestCell == -1 || bestScore < 0.01) {\n                // Everything determined, answer\n                vector<int> grid = configToGrid(allConfs[best]);\n                vector<int> ans;\n                for (int i = 0; i < N*N; i++) if (grid[i] > 0) ans.push_back(i);\n                int r = answer(ans);\n                if (r == 1) return 0;\n                logP[best] = -1e18;\n                continue;\n            }\n            \n            int v = drill(bestCell / N, bestCell % N);\n            // update\n            for (int c = 0; c < nConf; c++) {\n                vector<int> g = configToGrid(allConfs[c]);\n                if (g[bestCell] != v) logP[c] = -1e18;\n            }\n        }\n        \n        // final answer\n        normalize();\n        auto [best, prob] = topProb();\n        vector<int> grid = configToGrid(allConfs[best]);\n        vector<int> ans;\n        for (int i = 0; i < N*N; i++) if (grid[i] > 0) ans.push_back(i);\n        answer(ans);\n        return 0;\n    }\n    \n    // Large case: drill everything\n    vector<int> grid(N*N, -1);\n    vector<int> ans;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if ((int)queries.size() >= 2*N*N - 1) break;\n            int v = drill(i, j);\n            grid[i*N+j] = v;\n            if (v > 0) ans.push_back(i*N+j);\n        }\n    }\n    answer(ans);\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint W, D, N;\nvector<vector<int>> a;\n\nstruct Rect { int i0,j0,i1,j1; };\n\nlong long solve(vector<int>& widths, vector<vector<Rect>>& final_rects) {\n    int C = widths.size();\n    vector<int> xs(C+1, 0);\n    for (int i = 0; i < C; i++) xs[i+1] = xs[i] + widths[i];\n    \n    vector<vector<set<int>>> dividers(D, vector<set<int>>(C));\n    long long deficit = 0;\n    \n    final_rects.assign(D, vector<Rect>(N));\n    \n    for (int d = 0; d < D; d++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        \n        vector<double> load(C, 0);\n        vector<vector<int>> col(C);\n        for (int k : order) {\n            int best = 0;\n            for (int c = 1; c < C; c++) if (load[c] < load[best]) best = c;\n            col[best].push_back(k);\n            load[best] += (double)a[d][k] / widths[best];\n        }\n        \n        for (int c = 0; c < C; c++) {\n            auto& items = col[c];\n            if (items.empty()) continue;\n            int w = widths[c];\n            int m = items.size();\n            if (m > W) return LLONG_MAX;\n            \n            vector<int> h(m);\n            long long total = 0;\n            for (int i = 0; i < m; i++) {\n                h[i] = max(1, (a[d][items[i]] + w - 1) / w);\n                total += h[i];\n            }\n            if (total > W) {\n                long long totA = 0;\n                for (int k : items) totA += a[d][k];\n                if (totA == 0) totA = 1;\n                vector<int> newH(m, 1);\n                int rem = W - m;\n                vector<double> frac(m);\n                for (int i = 0; i < m; i++) {\n                    frac[i] = (double)a[d][items[i]] / totA * rem;\n                }\n                int s = m;\n                for (int i = 0; i < m; i++) {\n                    int add = (int)frac[i];\n                    newH[i] += add;\n                    s += add;\n                }\n                vector<pair<double,int>> fr(m);\n                for (int i = 0; i < m; i++) fr[i] = {frac[i] - (int)frac[i], i};\n                sort(fr.begin(), fr.end(), greater<>());\n                int idx = 0;\n                while (s < W && idx < m) {\n                    newH[fr[idx].second]++;\n                    s++;\n                    idx++;\n                }\n                while (s < W) { newH[m-1]++; s++; }\n                h = newH;\n            }\n            int y = 0;\n            for (int i = 0; i < m; i++) {\n                int yEnd = (i == m-1) ? W : y + h[i];\n                if (yEnd > W) yEnd = W;\n                final_rects[d][items[i]] = {y, xs[c], yEnd, xs[c+1]};\n                if (yEnd < W) dividers[d][c].insert(yEnd);\n                y = yEnd;\n            }\n            for (int idx : items) {\n                auto& r = final_rects[d][idx];\n                long long area = (long long)(r.i1-r.i0)*(r.j1-r.j0);\n                if (area < a[d][idx]) deficit += 100LL * (a[d][idx] - area);\n            }\n        }\n    }\n    \n    long long partCost = 0;\n    for (int d = 1; d < D; d++) {\n        for (int c = 0; c < C; c++) {\n            auto& prev = dividers[d-1][c];\n            auto& cur = dividers[d][c];\n            int w = widths[c];\n            int sd = 0;\n            for (int x : prev) if (!cur.count(x)) sd++;\n            for (int x : cur) if (!prev.count(x)) sd++;\n            partCost += (long long)sd * w;\n        }\n    }\n    \n    return deficit + partCost;\n}\n\nint main() {\n    cin >> W >> D >> N;\n    a.assign(D, vector<int>(N));\n    for (int d = 0; d < D; d++) for (int k = 0; k < N; k++) cin >> a[d][k];\n    \n    long long bestCost = LLONG_MAX;\n    vector<vector<Rect>> bestRects;\n    \n    int maxC = min(N, 25);\n    for (int C = 1; C <= maxC; C++) {\n        vector<int> widths(C);\n        int base = W / C, extra = W % C;\n        for (int i = 0; i < C; i++) widths[i] = base + (i < extra ? 1 : 0);\n        vector<vector<Rect>> rects;\n        long long cost = solve(widths, rects);\n        if (cost < bestCost) {\n            bestCost = cost;\n            bestRects = rects;\n        }\n    }\n    \n    if (bestRects.empty()) {\n        bestRects.assign(D, vector<Rect>(N));\n        for (int d = 0; d < D; d++) for (int k = 0; k < N; k++)\n            bestRects[d][k] = {k, 0, k+1, W};\n    }\n    \n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            auto& r = bestRects[d][k];\n            cout << r.i0 << \" \" << r.j0 << \" \" << r.i1 << \" \" << r.j1 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nconst long long MOD = 998244353;\n\nint N, M, K;\nlong long a0[9][9];\nlong long s[20][3][3];\nlong long s00[20];\n\npair<long long, vector<tuple<int,int,int>>> solve(long long lambda){\n    long long a[9][9];\n    memcpy(a, a0, sizeof(a0));\n    vector<tuple<int,int,int>> ops;\n    int budget = K;\n    \n    for(int p=0;p<=N-3;p++){\n        for(int q=0;q<=N-3;q++){\n            int max_here = min(budget, 3);\n            if(max_here < 0) max_here = 0;\n            long long cur = a[p][q];\n            \n            long long bv[4];\n            vector<int> bs[4];\n            bv[0] = cur;\n            for(int k=1;k<=3;k++) bv[k] = -1;\n            \n            if(max_here >= 1){\n                bv[1] = cur;\n                for(int m=0;m<M;m++){\n                    long long v = (cur + s00[m]) % MOD;\n                    if(v > bv[1]){ bv[1] = v; bs[1] = {m}; }\n                }\n            }\n            if(max_here >= 2){\n                bv[2] = bv[1]; bs[2] = bs[1];\n                for(int m1=0;m1<M;m1++){\n                    for(int m2=m1;m2<M;m2++){\n                        long long v = (cur + s00[m1] + s00[m2]) % MOD;\n                        if(v > bv[2]){ bv[2] = v; bs[2] = {m1,m2}; }\n                    }\n                }\n            }\n            if(max_here >= 3){\n                bv[3] = bv[2]; bs[3] = bs[2];\n                for(int m1=0;m1<M;m1++){\n                    for(int m2=m1;m2<M;m2++){\n                        for(int m3=m2;m3<M;m3++){\n                            long long v = (cur + s00[m1] + s00[m2] + s00[m3]) % MOD;\n                            if(v > bv[3]){ bv[3] = v; bs[3] = {m1,m2,m3}; }\n                        }\n                    }\n                }\n            }\n            \n            int best_k = 0;\n            long long best_sc = bv[0];\n            for(int k=1;k<=max_here;k++){\n                long long sc = bv[k] - (long long)k * lambda;\n                if(sc > best_sc){ best_sc = sc; best_k = k; }\n            }\n            \n            for(int m : bs[best_k]){\n                ops.push_back({m,p,q});\n                for(int i=0;i<3;i++) for(int j=0;j<3;j++){\n                    a[p+i][q+j] = (a[p+i][q+j] + s[m][i][j]) % MOD;\n                }\n                budget--;\n            }\n        }\n    }\n    \n    long long score = 0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) score += a[i][j];\n    return {score, ops};\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> K;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>a0[i][j];\n    for(int m=0;m<M;m++){\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) cin>>s[m][i][j];\n        s00[m] = s[m][0][0];\n    }\n    \n    long long best_score = -1;\n    vector<tuple<int,int,int>> best_ops;\n    \n    for(int step = 0; step <= 400; step++){\n        long long lambda = (long long)((double)MOD * 0.4 * step / 400);\n        auto [sc, ops] = solve(lambda);\n        if((int)ops.size() <= K && sc > best_score){\n            best_score = sc;\n            best_ops = ops;\n        }\n    }\n    \n    cout << best_ops.size() << \"\\n\";\n    for(auto& [m,p,q] : best_ops) cout << m << \" \" << p << \" \" << q << \"\\n\";\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint A[5][5];\nint grid_[5][5];\nint cr_[5], cc_[5];\nbool hold_[5];\nint held_[5];\nint nin_[5];\nint nout_[5];\nvector<string> out_;\nint totalDisp = 0;\nint turns_ = 0;\n\nvoid doStep(const string& a) {\n    for(int i=0;i<5;i++){\n        if(nin_[i]>=5)continue;\n        if(grid_[i][0]!=-1)continue;\n        bool h=false;\n        for(int k=0;k<5;k++) if(cr_[k]==i&&cc_[k]==0&&hold_[k]){h=true;break;}\n        if(h)continue;\n        grid_[i][0]=A[i][nin_[i]++];\n    }\n    int nr[5], nc[5];\n    for(int i=0;i<5;i++){nr[i]=cr_[i];nc[i]=cc_[i];}\n    for(int i=0;i<5;i++){\n        if(cr_[i]==-1)continue;\n        char ch=a[i];\n        if(ch=='U')nr[i]--;\n        else if(ch=='D')nr[i]++;\n        else if(ch=='L')nc[i]--;\n        else if(ch=='R')nc[i]++;\n    }\n    for(int i=0;i<5;i++){cr_[i]=nr[i];cc_[i]=nc[i];}\n    for(int i=0;i<5;i++){\n        if(cr_[i]==-1)continue;\n        char ch=a[i];\n        if(ch=='P'){\n            held_[i]=grid_[cr_[i]][cc_[i]];\n            grid_[cr_[i]][cc_[i]]=-1;\n            hold_[i]=true;\n        } else if(ch=='Q'){\n            grid_[cr_[i]][cc_[i]]=held_[i];\n            held_[i]=-1;\n            hold_[i]=false;\n        } else if(ch=='B'){\n            cr_[i]=-1;cc_[i]=-1;\n        }\n    }\n    for(int i=0;i<5;i++) out_[i]+=a[i];\n    turns_++;\n    for(int i=0;i<5;i++){\n        if(grid_[i][4]!=-1){\n            int v=grid_[i][4];\n            grid_[i][4]=-1;\n            totalDisp++;\n            if(v/5==i) nout_[i]++;\n        }\n    }\n}\n\nvoid moveLarge(int tr, int tc) {\n    int guard=0;\n    while((cr_[0]!=tr || cc_[0]!=tc) && turns_<9900 && guard<200) {\n        string a=\".....\"; \n        char ch='.';\n        if(cr_[0]<tr) ch='D';\n        else if(cr_[0]>tr) ch='U';\n        else if(cc_[0]<tc) ch='R';\n        else if(cc_[0]>tc) ch='L';\n        a[0]=ch;\n        doStep(a);\n        guard++;\n    }\n}\n\nint main(){\n    int N; cin>>N;\n    for(int i=0;i<5;i++) for(int j=0;j<5;j++) cin>>A[i][j];\n    for(int i=0;i<5;i++)for(int j=0;j<5;j++)grid_[i][j]=-1;\n    for(int i=0;i<5;i++){cr_[i]=i;cc_[i]=0;hold_[i]=false;held_[i]=-1;nin_[i]=0;nout_[i]=0;}\n    out_.assign(5,\"\");\n    \n    doStep(\"PPPPP\");\n    doStep(\"RRRRR\");\n    doStep(\"QQQQQ\");\n    doStep(\".BBBB\");\n    \n    int stuck=0;\n    while(totalDisp < 25 && turns_ < 9900) {\n        bool found=false;\n        int tr=-1,tc=-1,tgate=-1;\n        for(int g=0;g<5 && !found;g++){\n            if(nout_[g]>=5) continue;\n            int want = g*5 + nout_[g];\n            for(int r=0;r<5 && !found;r++) for(int c=0;c<5 && !found;c++) {\n                if(grid_[r][c]==want){\n                    tr=r;tc=c;tgate=g;found=true;\n                }\n            }\n        }\n        if(found) {\n            moveLarge(tr,tc);\n            { string a=\".....\"; a[0]='P'; doStep(a); }\n            moveLarge(tgate,4);\n            { string a=\".....\"; a[0]='Q'; doStep(a); }\n            stuck=0;\n        } else {\n            int sr=-1;\n            for(int i=0;i<5;i++) if(grid_[i][0]!=-1){sr=i;break;}\n            if(sr==-1) {\n                doStep(\".....\");\n                stuck++;\n                if(stuck>50) break;\n                continue;\n            }\n            int dr=-1,dc=-1;\n            int colOrder[] = {2,3,1};\n            for(int co=0;co<3 && dr==-1;co++){\n                int c=colOrder[co];\n                for(int r=0;r<5;r++) if(grid_[r][c]==-1){dr=r;dc=c;break;}\n            }\n            if(dr==-1){\n                doStep(\".....\");\n                stuck++;\n                if(stuck>50) break;\n                continue;\n            }\n            moveLarge(sr,0);\n            { string a=\".....\"; a[0]='P'; doStep(a); }\n            moveLarge(dr,dc);\n            { string a=\".....\"; a[0]='Q'; doStep(a); }\n            stuck=0;\n        }\n    }\n    \n    for(int i=0;i<5;i++) cout<<out_[i]<<\"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\nvector<string> ops;\nint cr=0, cc=0, load=0;\n\nvoid move(char d){\n    ops.push_back(string(1,d));\n    if(d=='U')cr--; else if(d=='D')cr++; else if(d=='L')cc--; else cc++;\n}\nvoid doLoad(int d){ if(d<=0)return; ops.push_back(\"+\"+to_string(d)); h[cr][cc]-=d; load+=d; }\nvoid doUnload(int d){ if(d<=0)return; ops.push_back(\"-\"+to_string(d)); h[cr][cc]+=d; load-=d; }\n\nint main(){\n    cin>>N;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>h[i][j];\n    \n    // snake path coordinates\n    vector<pair<int,int>> path;\n    for(int i=0;i<N;i++){\n        if(i%2==0) for(int j=0;j<N;j++) path.push_back({i,j});\n        else for(int j=N-1;j>=0;j--) path.push_back({i,j});\n    }\n    \n    auto moveTo=[&](int tr,int tc){\n        while(cr!=tr){ if(cr<tr)move('D'); else move('U'); }\n        while(cc!=tc){ if(cc<tc)move('R'); else move('L'); }\n    };\n    \n    // iterate passes\n    for(int iter=0;iter<20;iter++){\n        bool any=false;\n        for(int i=0;i<(int)path.size();i++)if(h[path[i].first][path[i].second]!=0){any=true;break;}\n        if(!any)break;\n        \n        if(iter%2==0){\n            // forward\n            for(auto [r,c]:path){\n                moveTo(r,c);\n                if(h[r][c]>0) doLoad(h[r][c]);\n                else if(h[r][c]<0) doUnload(min(load,-h[r][c]));\n            }\n        } else {\n            for(int i=path.size()-1;i>=0;i--){\n                auto [r,c]=path[i];\n                moveTo(r,c);\n                if(h[r][c]>0) doLoad(h[r][c]);\n                else if(h[r][c]<0) doUnload(min(load,-h[r][c]));\n            }\n        }\n    }\n    \n    for(auto&s:ops)cout<<s<<\"\\n\";\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, T, SC;\nvector<vector<int>> X;\nmt19937 rng(12345);\n\nint pairScore(int a, int b) {\n    int s = 0;\n    for (int l = 0; l < M; l++) s += max(X[a][l], X[b][l]);\n    return s;\n}\n\nint totalScore(vector<vector<int>>& A) {\n    int s = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            if (j+1 < N) s += pairScore(A[i][j], A[i][j+1]);\n            if (i+1 < N) s += pairScore(A[i][j], A[i+1][j]);\n        }\n    return s;\n}\n\nint deltaSwap(vector<vector<int>>& A, int i1, int j1, int i2, int j2) {\n    int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};\n    auto contrib = [&](int i, int j, int other_i, int other_j) {\n        int total = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = i+dr[d], nj = j+dc[d];\n            if (ni<0||ni>=N||nj<0||nj>=N) continue;\n            if (ni==other_i && nj==other_j) continue;\n            total += pairScore(A[i][j], A[ni][nj]);\n        }\n        return total;\n    };\n    int before = contrib(i1,j1,i2,j2) + contrib(i2,j2,i1,j1);\n    bool adj = (abs(i1-i2)+abs(j1-j2)==1);\n    if (adj) before += pairScore(A[i1][j1], A[i2][j2]);\n    swap(A[i1][j1], A[i2][j2]);\n    int after = contrib(i1,j1,i2,j2) + contrib(i2,j2,i1,j1);\n    if (adj) after += pairScore(A[i1][j1], A[i2][j2]);\n    swap(A[i1][j1], A[i2][j2]);\n    return after - before;\n}\n\nint main() {\n    cin >> N >> M >> T;\n    SC = 2*N*(N-1);\n    X.assign(SC, vector<int>(M));\n    for (int i = 0; i < SC; i++)\n        for (int j = 0; j < M; j++) cin >> X[i][j];\n    \n    for (int t = 0; t < T; t++) {\n        vector<int> Xmax(M, 0);\n        for (int k = 0; k < SC; k++)\n            for (int l = 0; l < M; l++) Xmax[l] = max(Xmax[l], X[k][l]);\n        \n        vector<double> score(SC, 0);\n        for (int k = 0; k < SC; k++) {\n            for (int l = 0; l < M; l++) {\n                if (Xmax[l] > 0) {\n                    double r = (double)X[k][l] / Xmax[l];\n                    score[k] += r * r * Xmax[l];\n                }\n            }\n        }\n        \n        vector<int> idx(SC);\n        iota(idx.begin(), idx.end(), 0);\n        sort(idx.begin(), idx.end(), [&](int a, int b){ return score[a] > score[b]; });\n        vector<int> chosen(idx.begin(), idx.begin() + N*N);\n        sort(chosen.begin(), chosen.end(), [&](int a, int b){ return score[a] > score[b]; });\n        \n        vector<pair<int,int>> cells;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            int deg = (i>0)+(i<N-1)+(j>0)+(j<N-1);\n            cells.push_back({-deg, i*N+j});\n        }\n        sort(cells.begin(), cells.end());\n        \n        vector<vector<int>> A(N, vector<int>(N));\n        for (int c = 0; c < N*N; c++) {\n            int p = cells[c].second;\n            A[p/N][p%N] = chosen[c];\n        }\n        \n        int curScore = totalScore(A);\n        auto start = chrono::steady_clock::now();\n        int iters = 0;\n        double timeLimit = 0.15;\n        while (true) {\n            iters++;\n            if ((iters & 1023) == 0) {\n                auto now = chrono::steady_clock::now();\n                double elapsed = chrono::duration<double>(now-start).count();\n                if (elapsed > timeLimit) break;\n            }\n            int p1 = rng() % (N*N);\n            int p2 = rng() % (N*N);\n            if (p1 == p2) continue;\n            int i1=p1/N, j1=p1%N, i2=p2/N, j2=p2%N;\n            int delta = deltaSwap(A, i1, j1, i2, j2);\n            if (delta >= 0) {\n                swap(A[i1][j1], A[i2][j2]);\n                curScore += delta;\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << A[i][j];\n                cout << (j==N-1 ? '\\n' : ' ');\n            }\n        }\n        cout.flush();\n        \n        for (int i = 0; i < SC; i++)\n            for (int j = 0; j < M; j++) cin >> X[i][j];\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<string> sg, tg;\n\nint dx[4] = {0, 1, 0, -1};\nint dy[4] = {1, 0, -1, 0};\n\nint main() {\n    cin >> N >> M >> V;\n    sg.resize(N); tg.resize(N);\n    for (int i = 0; i < N; i++) cin >> sg[i];\n    for (int i = 0; i < N; i++) cin >> tg[i];\n    \n    vector<pair<int,int>> sources, targets;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (sg[i][j]=='1' && tg[i][j]=='1') {\n        } else if (sg[i][j]=='1') {\n            sources.push_back({i,j});\n        } else if (tg[i][j]=='1') {\n            targets.push_back({i,j});\n        }\n    }\n    \n    cout << 2 << \"\\n\";\n    cout << 0 << \" \" << 1 << \"\\n\";\n    \n    int rx = 0, ry = 0;\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    int dir = 0;\n    vector<string> ops;\n    \n    auto planMove = [&](int tx, int ty) {\n        int best = INT_MAX;\n        int brx=rx, bry=ry, bd=dir;\n        for (int d = 0; d < 4; d++) {\n            int nrx = tx - dx[d];\n            int nry = ty - dy[d];\n            if (nrx<0||nrx>=N||nry<0||nry>=N) continue;\n            int mv = abs(nrx-rx)+abs(nry-ry);\n            int rot = min((d-dir+4)%4, (dir-d+4)%4);\n            int cost = max(mv, rot);\n            if (cost < best) { best=cost; brx=nrx; bry=nry; bd=d; }\n        }\n        return make_tuple(brx, bry, bd, best);\n    };\n    \n    auto execute = [&](int nrx, int nry, int nd) {\n        int mv_dx = nrx - rx, mv_dy = nry - ry;\n        int rot_diff = (nd - dir + 4) % 4;\n        int cw = 0, ccw = 0;\n        if (rot_diff == 1) cw = 1;\n        else if (rot_diff == 2) cw = 2;\n        else if (rot_diff == 3) ccw = 1;\n        \n        int mv_steps = abs(mv_dx) + abs(mv_dy);\n        int rot_steps = cw + ccw;\n        int turns = max(mv_steps, rot_steps);\n        \n        vector<char> mvSeq, rotSeq;\n        for (int i = 0; i < abs(mv_dx); i++) mvSeq.push_back(mv_dx>0?'D':'U');\n        for (int i = 0; i < abs(mv_dy); i++) mvSeq.push_back(mv_dy>0?'R':'L');\n        for (int i = 0; i < cw; i++) rotSeq.push_back('R');\n        for (int i = 0; i < ccw; i++) rotSeq.push_back('L');\n        \n        for (int i = 0; i < turns; i++) {\n            char c0 = i < (int)mvSeq.size() ? mvSeq[i] : '.';\n            char c1 = i < (int)rotSeq.size() ? rotSeq[i] : '.';\n            string s = \"\";\n            s += c0; s += c1; s += '.'; s += '.';\n            ops.push_back(s);\n        }\n        rx = nrx; ry = nry; dir = nd;\n    };\n    \n    vector<bool> usedS(sources.size(), false), usedT(targets.size(), false);\n    \n    for (int k = 0; k < (int)sources.size(); k++) {\n        int bestS = -1, bestCost = INT_MAX;\n        int bRx=rx, bRy=ry, bD=dir;\n        for (int i = 0; i < (int)sources.size(); i++) {\n            if (usedS[i]) continue;\n            auto [nrx, nry, nd, cost] = planMove(sources[i].first, sources[i].second);\n            if (cost < bestCost) { bestCost=cost; bestS=i; bRx=nrx; bRy=nry; bD=nd;}\n        }\n        if (bestS < 0) break;\n        execute(bRx, bRy, bD);\n        ops.push_back(\"...P\");\n        usedS[bestS] = true;\n        \n        int bestT = -1; bestCost = INT_MAX;\n        for (int i = 0; i < (int)targets.size(); i++) {\n            if (usedT[i]) continue;\n            auto [nrx, nry, nd, cost] = planMove(targets[i].first, targets[i].second);\n            if (cost < bestCost) { bestCost=cost; bestT=i; bRx=nrx; bRy=nry; bD=nd;}\n        }\n        if (bestT < 0) break;\n        execute(bRx, bRy, bD);\n        ops.push_back(\"...P\");\n        usedT[bestT] = true;\n    }\n    \n    for (auto& o : ops) cout << o << \"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N; scanf(\"%d\", &N);\n    vector<int> X(2*N), Y(2*N);\n    for(int i=0;i<2*N;i++) scanf(\"%d %d\",&X[i],&Y[i]);\n    \n    int W = 100, H = 100;\n    int cw = 100000/W, ch = 100000/H;\n    vector<vector<int>> grid(W, vector<int>(H,0));\n    for(int i=0;i<2*N;i++){\n        int c = min(W-1, X[i]/cw);\n        int r = min(H-1, Y[i]/ch);\n        grid[c][r] += (i<N) ? 1 : -1;\n    }\n    \n    vector<int> lo(W), hi(W), val(W);\n    for(int c=0;c<W;c++){\n        int bestSum = INT_MIN, bestL=0, bestR=-1;\n        int curSum=0, curL=0;\n        for(int r=0;r<H;r++){\n            if(curSum <= 0){ curSum = grid[c][r]; curL = r; }\n            else curSum += grid[c][r];\n            if(curSum > bestSum){ bestSum = curSum; bestL=curL; bestR=r; }\n        }\n        lo[c]=bestL; hi[c]=bestR; val[c]=bestSum;\n    }\n    \n    int totBest=INT_MIN, cL=0, cR=0, cs=0, cSL=0;\n    for(int c=0;c<W;c++){\n        if(cs<=0){ cs=val[c]; cSL=c; } else cs+=val[c];\n        if(cs>totBest){ totBest=cs; cL=cSL; cR=c; }\n    }\n    \n    auto build=[&](int cL,int cR)->vector<pair<int,int>>{\n        vector<pair<int,int>> poly;\n        poly.push_back({cL*cw, lo[cL]*ch});\n        for(int c=cL;c<=cR;c++){\n            int yb = lo[c]*ch;\n            if(c>cL && lo[c]!=lo[c-1]){\n                poly.push_back({c*cw, yb});\n            }\n            poly.push_back({(c+1)*cw, yb});\n        }\n        poly.push_back({(cR+1)*cw, (hi[cR]+1)*ch});\n        for(int c=cR;c>=cL;c--){\n            int yt = (hi[c]+1)*ch;\n            if(c<cR && hi[c]!=hi[c+1]){\n                poly.push_back({(c+1)*cw, yt});\n            }\n            poly.push_back({c*cw, yt});\n        }\n        vector<pair<int,int>> out;\n        for(auto& p : poly){\n            if(out.empty() || out.back()!=p) out.push_back(p);\n        }\n        while(out.size()>1 && out.front()==out.back()) out.pop_back();\n        return out;\n    };\n    \n    auto perim=[&](vector<pair<int,int>>& p){\n        long long s=0;\n        int n=p.size();\n        for(int i=0;i<n;i++){\n            auto& a=p[i]; auto& b=p[(i+1)%n];\n            s += abs(a.first-b.first)+abs(a.second-b.second);\n        }\n        return s;\n    };\n    \n    auto out = build(cL,cR);\n    // If perimeter exceeds, shrink or fix: simplest fallback - use bounding rect of best column\n    if(perim(out) > 400000 || out.size() > 1000){\n        // fallback: just one column\n        int bc=cL;\n        for(int c=cL;c<=cR;c++) if(val[c]>val[bc]) bc=c;\n        out = build(bc,bc);\n    }\n    \n    printf(\"%d\\n\",(int)out.size());\n    for(auto& p : out) printf(\"%d %d\\n\", p.first, p.second);\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, sigma;\nvector<int> W_, H_;\nmt19937 rng(42);\n\nstruct Rect { long long x1,y1,x2,y2; };\n\npair<long long,long long> simulate(const vector<tuple<int,int,char,int>>& ops, const vector<int>& ww, const vector<int>& hh) {\n    unordered_map<int, Rect> placed;\n    placed.reserve(ops.size()*2);\n    long long maxX=0, maxY=0;\n    for (auto& [p, r, d, b] : ops) {\n        long long w = r==0 ? ww[p] : hh[p];\n        long long h = r==0 ? hh[p] : ww[p];\n        if (d == 'U') {\n            long long x1 = (b == -1) ? 0 : placed[b].x2;\n            long long x2 = x1 + w;\n            long long y1 = 0;\n            for (auto& kv : placed) {\n                auto& rc = kv.second;\n                if (rc.x2 <= x1 || rc.x1 >= x2) continue;\n                y1 = max(y1, rc.y2);\n            }\n            long long y2 = y1 + h;\n            placed[p] = {x1,y1,x2,y2};\n            maxX = max(maxX, x2); maxY = max(maxY, y2);\n        } else {\n            long long y1 = (b == -1) ? 0 : placed[b].y2;\n            long long y2 = y1 + h;\n            long long x1 = 0;\n            for (auto& kv : placed) {\n                auto& rc = kv.second;\n                if (rc.y2 <= y1 || rc.y1 >= y2) continue;\n                x1 = max(x1, rc.x2);\n            }\n            long long x2 = x1 + w;\n            placed[p] = {x1,y1,x2,y2};\n            maxX = max(maxX, x2); maxY = max(maxY, y2);\n        }\n    }\n    return {maxX, maxY};\n}\n\nvector<tuple<int,int,char,int>> buildRowLayout(long long targetW, const vector<int>& ww, const vector<int>& hh, const vector<int>& rots) {\n    vector<tuple<int,int,char,int>> ops;\n    long long shelfX = 0;\n    int firstOfShelf = -1;\n    int prevOnShelf = -1;\n    for (int i = 0; i < N; i++) {\n        int rot = rots[i];\n        long long w = rot==0 ? ww[i] : hh[i];\n        if (firstOfShelf == -1) {\n            ops.push_back({i, rot, 'U', -1});\n            firstOfShelf = i; prevOnShelf = i; shelfX = w;\n        } else if (shelfX + w <= targetW) {\n            ops.push_back({i, rot, 'U', prevOnShelf});\n            prevOnShelf = i; shelfX += w;\n        } else {\n            ops.push_back({i, rot, 'L', firstOfShelf});\n            firstOfShelf = i; prevOnShelf = i; shelfX = w;\n        }\n    }\n    return ops;\n}\n\nint main() {\n    cin >> N >> T >> sigma;\n    W_.resize(N); H_.resize(N);\n    for (int i = 0; i < N; i++) cin >> W_[i] >> H_[i];\n    \n    long long totalArea = 0;\n    for (int i = 0; i < N; i++) totalArea += (long long)W_[i] * H_[i];\n    long long sideEst = (long long)sqrt((double)totalArea);\n    \n    vector<tuple<int,int,char,int>> best;\n    long long bestScore = LLONG_MAX;\n    \n    auto tryOps = [&](vector<tuple<int,int,char,int>>& ops) {\n        auto [w,h] = simulate(ops, W_, H_);\n        long long sc = w+h;\n        if (sc < bestScore) { bestScore = sc; best = ops; }\n    };\n    \n    for (double f = 0.5; f <= 2.0; f += 0.05) {\n        long long tw = (long long)(sideEst * f);\n        for (int mode = 0; mode < 3; mode++) {\n            vector<int> r(N);\n            for (int i = 0; i < N; i++) {\n                if (mode == 0) r[i] = 0;\n                else if (mode == 1) r[i] = (W_[i] > H_[i]) ? 1 : 0;\n                else r[i] = (W_[i] < H_[i]) ? 1 : 0;\n            }\n            auto ops = buildRowLayout(tw, W_, H_, r);\n            tryOps(ops);\n        }\n    }\n    \n    auto startTime = chrono::steady_clock::now();\n    auto elapsed = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - startTime).count();\n    };\n    \n    double totalTime = 2.5;\n    \n    for (int t = 0; t < T; t++) {\n        double deadline = totalTime * (t+1) / T;\n        while (elapsed() < deadline) {\n            vector<int> r(N);\n            for (int i = 0; i < N; i++) r[i] = rng()%2;\n            double f = 0.5 + (rng()%150)/100.0;\n            long long tw = (long long)(sideEst * f);\n            auto ops = buildRowLayout(tw, W_, H_, r);\n            tryOps(ops);\n        }\n        \n        cout << best.size() << \"\\n\";\n        for (auto& [p,r,d,b] : best) cout << p << \" \" << r << \" \" << d << \" \" << b << \"\\n\";\n        cout.flush();\n        long long wm, hm; cin >> wm >> hm;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, H;\nvector<int> A;\nvector<vector<int>> adj;\nvector<int> par, dep;\nvector<vector<int>> ch;\n\nvoid buildChildren() {\n    ch.assign(N, {});\n    for (int i = 0; i < N; i++) if (par[i] != -1) ch[par[i]].push_back(i);\n}\n\nvoid recomputeDepths() {\n    queue<int> q;\n    for (int i = 0; i < N; i++) {\n        if (par[i] == -1) { dep[i] = 0; q.push(i); }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int c : ch[u]) { dep[c] = dep[u]+1; q.push(c); }\n    }\n}\n\nlong long computeScore() {\n    long long s = 0;\n    for (int i = 0; i < N; i++) s += (long long)(dep[i]+1) * A[i];\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    cin >> N >> M >> H;\n    A.resize(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    adj.assign(N, {});\n    for (int i = 0; i < M; i++) {\n        int u, v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<int> xs(N), ys(N);\n    for (int i = 0; i < N; i++) cin >> xs[i] >> ys[i];\n    \n    par.assign(N, -1);\n    dep.assign(N, 0);\n    buildChildren();\n    \n    auto startTime = chrono::steady_clock::now();\n    auto timeMs = [&]() {\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - startTime).count();\n    };\n    \n    mt19937 rng(12345);\n    \n    vector<char> inSub(N, 0);\n    vector<int> subBuf;\n    vector<int> stk;\n    \n    auto doPass = [&]() -> bool {\n        bool improved = false;\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n        for (int v : order) {\n            subBuf.clear();\n            int sumA = 0, maxD = dep[v];\n            stk.clear(); stk.push_back(v);\n            while (!stk.empty()) {\n                int u = stk.back(); stk.pop_back();\n                subBuf.push_back(u);\n                inSub[u] = 1;\n                sumA += A[u];\n                if (dep[u] > maxD) maxD = dep[u];\n                for (int c : ch[u]) stk.push_back(c);\n            }\n            int relMaxD = maxD - dep[v];\n            \n            int bestP = par[v];\n            long long bestDelta = 0;\n            int curDep = dep[v];\n            int oldP = par[v];\n            \n            if (oldP != -1) {\n                int delta = 0 - curDep;\n                long long change = (long long)delta * sumA;\n                if (change > bestDelta) { bestDelta = change; bestP = -1; }\n            }\n            for (int u : adj[v]) {\n                if (u == oldP) continue;\n                if (inSub[u]) continue;\n                int newDep = dep[u] + 1;\n                if (newDep + relMaxD > H) continue;\n                int delta = newDep - curDep;\n                long long change = (long long)delta * sumA;\n                if (change > bestDelta) { bestDelta = change; bestP = u; }\n            }\n            \n            for (int u : subBuf) inSub[u] = 0;\n            \n            if (bestDelta > 0) {\n                int oldP2 = par[v];\n                par[v] = bestP;\n                int newDep = (bestP == -1 ? 0 : dep[bestP] + 1);\n                int delta = newDep - curDep;\n                if (oldP2 != -1) {\n                    auto& vec = ch[oldP2];\n                    vec.erase(find(vec.begin(), vec.end(), v));\n                }\n                if (bestP != -1) ch[bestP].push_back(v);\n                stk.clear(); stk.push_back(v);\n                while (!stk.empty()) {\n                    int u = stk.back(); stk.pop_back();\n                    dep[u] += delta;\n                    for (int c : ch[u]) stk.push_back(c);\n                }\n                improved = true;\n            }\n        }\n        return improved;\n    };\n    \n    long long bestScore = computeScore();\n    vector<int> bestPar = par;\n    \n    while (timeMs() < 500 && doPass()) {}\n    {\n        long long sc = computeScore();\n        if (sc > bestScore) { bestScore = sc; bestPar = par; }\n    }\n    \n    while (timeMs() < 1800) {\n        int K = 30 + (int)(rng() % 100);\n        for (int t = 0; t < K; t++) {\n            int v = (int)(rng() % N);\n            if (par[v] != -1) {\n                auto& vec = ch[par[v]];\n                auto it = find(vec.begin(), vec.end(), v);\n                if (it != vec.end()) vec.erase(it);\n                par[v] = -1;\n            }\n        }\n        recomputeDepths();\n        \n        while (timeMs() < 1800 && doPass()) {}\n        long long sc2 = computeScore();\n        if (sc2 > bestScore) {\n            bestScore = sc2;\n            bestPar = par;\n        } else {\n            par = bestPar;\n            buildChildren();\n            recomputeDepths();\n        }\n    }\n    \n    par = bestPar;\n    for (int i = 0; i < N; i++) cout << par[i] << \" \\n\"[i==N-1];\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nusing Board = vector<string>;\nstruct Move { char d; int p; };\n\nchar shiftOp(Board& b, char d, int p) {\n    char rem;\n    if (d=='L') { rem=b[p][0]; for(int j=0;j<N-1;j++)b[p][j]=b[p][j+1]; b[p][N-1]='.'; }\n    else if (d=='R') { rem=b[p][N-1]; for(int j=N-1;j>0;j--)b[p][j]=b[p][j-1]; b[p][0]='.'; }\n    else if (d=='U') { rem=b[0][p]; for(int i=0;i<N-1;i++)b[i][p]=b[i+1][p]; b[N-1][p]='.'; }\n    else { rem=b[N-1][p]; for(int i=N-1;i>0;i--)b[i][p]=b[i-1][p]; b[0][p]='.'; }\n    return rem;\n}\n\nint countOni(const Board& b) {\n    int c=0; for(auto&r:b)for(char x:r)if(x=='x')c++; return c;\n}\n\nvector<Move> greedy(Board b, mt19937& rng, bool randomize) {\n    vector<Move> moves;\n    int limit = 4*N*N;\n    while (countOni(b) > 0) {\n        vector<tuple<double,int,int,char,int>> cands;\n        for (char d : {'L','R','U','D'}) {\n            for (int p = 0; p < N; p++) {\n                Board tmp = b;\n                int oniRem = 0;\n                for (int k = 1; k <= N; k++) {\n                    char r = shiftOp(tmp, d, p);\n                    if (r == 'o') break;\n                    if (r == 'x') oniRem++;\n                    if (oniRem > 0) {\n                        double sc = (double)k / oniRem;\n                        cands.push_back({sc, k, oniRem, d, p});\n                    }\n                }\n            }\n        }\n        if (cands.empty()) return {};\n        sort(cands.begin(), cands.end());\n        int pick = 0;\n        if (randomize && cands.size() > 1) {\n            int top = min((int)cands.size(), 3);\n            pick = rng() % top;\n        }\n        auto [sc, k, orem, d, p] = cands[pick];\n        for (int i = 0; i < k; i++) {\n            shiftOp(b, d, p);\n            moves.push_back({d, p});\n            if ((int)moves.size() > limit) return {};\n        }\n    }\n    return moves;\n}\n\nvector<Move> hintSol(Board b) {\n    vector<Move> moves;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (b[i][j]=='x') {\n        bool up=true, down=true, left=true, right=true;\n        for (int r = 0; r < i; r++) if (b[r][j]=='o') up=false;\n        for (int r = i+1; r < N; r++) if (b[r][j]=='o') down=false;\n        for (int c = 0; c < j; c++) if (b[i][c]=='o') left=false;\n        for (int c = j+1; c < N; c++) if (b[i][c]=='o') right=false;\n        int bestCost = INT_MAX; char bestDir='?';\n        if (up && 2*(i+1) < bestCost) { bestCost=2*(i+1); bestDir='U'; }\n        if (down && 2*(N-i) < bestCost) { bestCost=2*(N-i); bestDir='D'; }\n        if (left && 2*(j+1) < bestCost) { bestCost=2*(j+1); bestDir='L'; }\n        if (right && 2*(N-j) < bestCost) { bestCost=2*(N-j); bestDir='R'; }\n        int k = bestCost/2;\n        char revD = (bestDir=='U'?'D':bestDir=='D'?'U':bestDir=='L'?'R':'L');\n        int p = (bestDir=='U'||bestDir=='D')?j:i;\n        for (int t = 0; t < k; t++) moves.push_back({bestDir, p});\n        for (int t = 0; t < k; t++) moves.push_back({revD, p});\n    }\n    return moves;\n}\n\nint main() {\n    cin >> N;\n    Board b0(N);\n    for (int i = 0; i < N; i++) cin >> b0[i];\n    \n    auto start = chrono::steady_clock::now();\n    mt19937 rng(42);\n    \n    vector<Move> best;\n    auto det = greedy(b0, rng, false);\n    if (!det.empty()) best = det;\n    \n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-start).count() < 1700) {\n        auto m = greedy(b0, rng, true);\n        if (!m.empty() && (best.empty() || m.size() < best.size())) best = m;\n    }\n    \n    if (best.empty() || (int)best.size() > 4*N*N) {\n        best = hintSol(b0);\n    }\n    \n    for (auto& m : best) cout << m.d << \" \" << m.p << \"\\n\";\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, L;\nint Tg[128];\nint a[128], b[128];\nint cnt[128];\nint vp[128];\n\nlong long simError() {\n    for (int i = 0; i < N; i++) { cnt[i]=0; vp[i]=0; }\n    int x = 0;\n    for (int w = 0; w < L; w++) {\n        cnt[x]++;\n        vp[x] ^= 1;\n        x = vp[x] ? a[x] : b[x];\n    }\n    long long e = 0;\n    for (int i = 0; i < N; i++) e += abs(cnt[i] - Tg[i]);\n    return e;\n}\n\nint main() {\n    cin >> N >> L;\n    for (int i = 0; i < N; i++) cin >> Tg[i];\n    \n    vector<int> filled(N, 0);\n    filled[0] = 1;\n    \n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int x, int y){ return Tg[x] > Tg[y]; });\n    \n    for (int x : ord) {\n        int ca = (Tg[x] + 1) / 2;\n        int cb = Tg[x] / 2;\n        int besta = 0, bv = INT_MIN;\n        for (int i = 0; i < N; i++) {\n            int v = Tg[i] - filled[i];\n            if (v > bv) { bv = v; besta = i; }\n        }\n        a[x] = besta;\n        filled[besta] += ca;\n        int bestb = 0; bv = INT_MIN;\n        for (int i = 0; i < N; i++) {\n            int v = Tg[i] - filled[i];\n            if (v > bv) { bv = v; bestb = i; }\n        }\n        b[x] = bestb;\n        filled[bestb] += cb;\n    }\n    \n    long long bestE = simError();\n    \n    mt19937 rng(12345);\n    auto start = chrono::steady_clock::now();\n    \n    int iters = 0;\n    while (true) {\n        if ((iters & 7) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > 1.8) break;\n        }\n        iters++;\n        \n        int i = rng() % N;\n        int side = rng() % 2;\n        int newv = rng() % N;\n        int old;\n        if (side == 0) { old = a[i]; if (old == newv) continue; a[i] = newv; }\n        else { old = b[i]; if (old == newv) continue; b[i] = newv; }\n        \n        long long ne = simError();\n        if (ne <= bestE) {\n            bestE = ne;\n        } else {\n            if (side == 0) a[i] = old;\n            else b[i] = old;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> Gs;\nvector<int> lx, rx, ly, ry;\nvector<double> cx, cy;\nint queries_used = 0;\n\nvector<pair<int,int>> doQuery(vector<int> c) {\n    queries_used++;\n    cout << \"? \" << c.size();\n    for (int v : c) cout << \" \" << v;\n    cout << \"\\n\";\n    cout.flush();\n    vector<pair<int,int>> res(c.size()-1);\n    for (auto& p : res) cin >> p.first >> p.second;\n    return res;\n}\n\ndouble estDist(int i, int j) {\n    double dx = cx[i]-cx[j], dy = cy[i]-cy[j];\n    return sqrt(dx*dx+dy*dy);\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> Q >> L >> W;\n    Gs.resize(M);\n    for (auto& g : Gs) cin >> g;\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i]+rx[i])/2.0;\n        cy[i] = (ly[i]+ry[i])/2.0;\n    }\n    \n    vector<int> assigned(N, -1);\n    vector<vector<int>> groups(M);\n    \n    vector<int> gorder(M);\n    iota(gorder.begin(), gorder.end(), 0);\n    sort(gorder.begin(), gorder.end(), [&](int a, int b){ return Gs[a] > Gs[b]; });\n    \n    for (int gi : gorder) {\n        int sz = Gs[gi];\n        int seed = -1;\n        double bestv = 1e18;\n        for (int i = 0; i < N; i++) {\n            if (assigned[i] != -1) continue;\n            double v = cx[i] + cy[i]*0.0001;\n            if (v < bestv) { bestv = v; seed = i; }\n        }\n        vector<int>& grp = groups[gi];\n        grp.push_back(seed);\n        assigned[seed] = gi;\n        \n        // Maintain min-dist-to-group for each unassigned city\n        vector<double> minD(N, 1e18);\n        for (int i = 0; i < N; i++) if (assigned[i] == -1) minD[i] = estDist(seed, i);\n        \n        while ((int)grp.size() < sz) {\n            int best = -1; double bd = 1e18;\n            for (int i = 0; i < N; i++) {\n                if (assigned[i] != -1) continue;\n                if (minD[i] < bd) { bd = minD[i]; best = i; }\n            }\n            grp.push_back(best);\n            assigned[best] = gi;\n            for (int i = 0; i < N; i++) {\n                if (assigned[i] == -1) {\n                    double d = estDist(best, i);\n                    if (d < minD[i]) minD[i] = d;\n                }\n            }\n        }\n    }\n    \n    vector<vector<pair<int,int>>> allEdges(M);\n    \n    for (int gi = 0; gi < M; gi++) {\n        int g = Gs[gi];\n        vector<int>& grp = groups[gi];\n        if (g == 1) continue;\n        if (g == 2) {\n            allEdges[gi].push_back({grp[0], grp[1]});\n            continue;\n        }\n        \n        vector<int> order;\n        vector<bool> used(g, false);\n        int start = 0;\n        double bv = 1e18;\n        for (int i = 0; i < g; i++) {\n            double v = cx[grp[i]] + cy[grp[i]]*0.0001;\n            if (v < bv) { bv = v; start = i; }\n        }\n        order.push_back(start); used[start] = true;\n        while ((int)order.size() < g) {\n            int last = order.back();\n            int best = -1; double bd = 1e18;\n            for (int i = 0; i < g; i++) {\n                if (used[i]) continue;\n                double d = estDist(grp[last], grp[i]);\n                if (d < bd) { bd = d; best = i; }\n            }\n            order.push_back(best); used[best] = true;\n        }\n        \n        set<pair<int,int>> edgeSet;\n        auto addEdge = [&](int u, int v) {\n            if (u > v) swap(u,v);\n            edgeSet.insert({u,v});\n        };\n        \n        int chunk_sz = L;\n        int step = max(1, L - 1);\n        for (int st = 0; st < g; st += step) {\n            int en = min(st + chunk_sz, g);\n            if (en - st < 2) break;\n            if (queries_used >= Q) break;\n            vector<int> q;\n            for (int i = st; i < en; i++) q.push_back(grp[order[i]]);\n            auto es = doQuery(q);\n            for (auto& [a,b] : es) addEdge(a,b);\n            if (en == g) break;\n        }\n        \n        vector<tuple<double,int,int>> edges;\n        for (auto& p : edgeSet) edges.push_back({estDist(p.first, p.second), p.first, p.second});\n        sort(edges.begin(), edges.end());\n        \n        map<int,int> idx;\n        for (int i = 0; i < g; i++) idx[grp[i]] = i;\n        vector<int> par(g); iota(par.begin(), par.end(), 0);\n        function<int(int)> find = [&](int x){ return par[x]==x?x:par[x]=find(par[x]); };\n        \n        for (auto& [d,u,v] : edges) {\n            int a = idx[u], b = idx[v];\n            int ra = find(a), rb = find(b);\n            if (ra != rb) {\n                par[ra] = rb;\n                allEdges[gi].push_back({u,v});\n            }\n        }\n        \n        vector<tuple<double,int,int>> allPairs;\n        for (int i = 0; i < g; i++) for (int j = i+1; j < g; j++) {\n            allPairs.push_back({estDist(grp[i], grp[j]), i, j});\n        }\n        sort(allPairs.begin(), allPairs.end());\n        for (auto& [d,a,b] : allPairs) {\n            int ra = find(a), rb = find(b);\n            if (ra != rb) {\n                par[ra] = rb;\n                allEdges[gi].push_back({grp[a], grp[b]});\n            }\n        }\n    }\n    \n    cout << \"!\\n\";\n    for (int gi = 0; gi < M; gi++) {\n        for (int i = 0; i < (int)groups[gi].size(); i++) {\n            cout << groups[gi][i];\n            if (i+1 < (int)groups[gi].size()) cout << \" \";\n        }\n        cout << \"\\n\";\n        for (auto& p : allEdges[gi]) cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint di[4]={-1,1,0,0}, dj[4]={0,0,-1,1};\nchar dch[4]={'U','D','L','R'};\nvector<vector<bool>> blk;\n\npair<int,int> slideEnd(int i,int j,int d){\n    while(true){\n        int ni=i+di[d],nj=j+dj[d];\n        if(ni<0||ni>=N||nj<0||nj>=N||blk[ni][nj])break;\n        i=ni;j=nj;\n    }\n    return {i,j};\n}\n\nint main(){\n    cin>>N>>M;\n    vector<pair<int,int>> pts(M);\n    for(auto&p:pts)cin>>p.first>>p.second;\n    blk.assign(N,vector<bool>(N,false));\n    vector<string> out;\n    int ci=pts[0].first, cj=pts[0].second;\n    \n    for(int t=1;t<M;t++){\n        int ti=pts[t].first, tj=pts[t].second;\n        vector<vector<int>> dist(N,vector<int>(N,INT_MAX));\n        vector<vector<tuple<int,int,string>>> par(N,vector<tuple<int,int,string>>(N));\n        dist[ci][cj]=0;\n        queue<pair<int,int>> q;\n        q.push({ci,cj});\n        while(!q.empty()){\n            auto [i,j]=q.front();q.pop();\n            int c=dist[i][j];\n            for(int d=0;d<4;d++){\n                int ni=i+di[d],nj=j+dj[d];\n                if(ni>=0&&ni<N&&nj>=0&&nj<N&&!blk[ni][nj]){\n                    if(c+1<dist[ni][nj]){\n                        dist[ni][nj]=c+1;\n                        par[ni][nj]={i,j,string(\"M\")+dch[d]};\n                        q.push({ni,nj});\n                    }\n                }\n                auto [si,sj]=slideEnd(i,j,d);\n                if((si!=i||sj!=j)&&c+1<dist[si][sj]){\n                    dist[si][sj]=c+1;\n                    par[si][sj]={i,j,string(\"S\")+dch[d]};\n                    q.push({si,sj});\n                }\n            }\n        }\n        if(dist[ti][tj]==INT_MAX)break;\n        vector<string> acts;\n        int ii=ti,jj=tj;\n        while(ii!=ci||jj!=cj){\n            auto[pi,pj,a]=par[ii][jj];\n            acts.push_back(a);\n            ii=pi;jj=pj;\n        }\n        reverse(acts.begin(),acts.end());\n        for(auto&a:acts)out.push_back(a);\n        ci=ti;cj=tj;\n    }\n    for(auto&s:out)cout<<s[0]<<\" \"<<s[1]<<\"\\n\";\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> X, Y, R;\nstruct Rect { int a, b, c, d; };\nvector<Rect> rects;\nconst int W = 10000;\n\ndouble score_one(int i) {\n    auto& r = rects[i];\n    if (X[i] < r.a || X[i] >= r.c || Y[i] < r.b || Y[i] >= r.d) return 0;\n    long long s = (long long)(r.c - r.a) * (r.d - r.b);\n    double mn = min((long long)R[i], s);\n    double mx = max((long long)R[i], s);\n    double t = 1 - mn/mx;\n    return 1 - t*t;\n}\n\nbool overlap(const Rect& x, const Rect& y) {\n    return !(x.c <= y.a || y.c <= x.a || x.d <= y.b || y.d <= x.b);\n}\n\nbool conflicts(int i, const Rect& nr) {\n    for (int j = 0; j < n; j++) if (j != i) {\n        if (overlap(nr, rects[j])) return true;\n    }\n    return false;\n}\n\nint main() {\n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    rects.resize(n);\n    for (int i = 0; i < n; i++) {\n        cin >> X[i] >> Y[i] >> R[i];\n        rects[i] = {X[i], Y[i], X[i]+1, Y[i]+1};\n    }\n    \n    auto start = chrono::steady_clock::now();\n    auto elapsed = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - start).count();\n    };\n    \n    mt19937 rng(42);\n    \n    while (elapsed() < 4.7) {\n        int i = rng() % n;\n        auto& r = rects[i];\n        double old_sc = score_one(i);\n        long long curS = (long long)(r.c - r.a) * (r.d - r.b);\n        \n        int move = rng() % 8; // 4 expand, 4 shrink\n        Rect saved = r;\n        int amt = 1 + rng() % 50;\n        \n        if (move == 0) r.a = max(0, r.a - amt);\n        else if (move == 1) r.c = min(W, r.c + amt);\n        else if (move == 2) r.b = max(0, r.b - amt);\n        else if (move == 3) r.d = min(W, r.d + amt);\n        else if (move == 4) r.a = min(X[i], r.a + amt);\n        else if (move == 5) r.c = max(X[i]+1, r.c - amt);\n        else if (move == 6) r.b = min(Y[i], r.b + amt);\n        else r.d = max(Y[i]+1, r.d - amt);\n        \n        if (r.a >= r.c || r.b >= r.d || r.a < 0 || r.b < 0 || r.c > W || r.d > W) {\n            r = saved; continue;\n        }\n        if (X[i] < r.a || X[i] >= r.c || Y[i] < r.b || Y[i] >= r.d) {\n            r = saved; continue;\n        }\n        if (move < 4 && conflicts(i, r)) {\n            r = saved; continue;\n        }\n        double new_sc = score_one(i);\n        if (new_sc < old_sc - 1e-12) r = saved;\n    }\n    \n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << \" \" << rects[i].b << \" \" << rects[i].c << \" \" << rects[i].d << \"\\n\";\n    }\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nint N = 50;\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dch[] = {'U', 'D', 'L', 'R'};\n\ndouble getTime() {\n    return (double)clock() / CLOCKS_PER_SEC;\n}\n\nmt19937 rng(98765);\n\nvector<pair<int,int>> path;\nvector<int> dirs;\nvector<bool> usedTile;\nint totalScore;\nint M;\n\nint bestTailScore;\nvector<int> bestTailDirs;\nvector<int> curTailDirs;\nint curTailScore;\ndouble dfsDeadline;\nbool timeUp;\nint dfsCount;\n\nvoid dfs(int r, int c) {\n    dfsCount++;\n    if ((dfsCount & 4095) == 0) {\n        if (getTime() > dfsDeadline) { timeUp = true; return; }\n    }\n    if (timeUp) return;\n    \n    if (curTailScore > bestTailScore) {\n        bestTailScore = curTailScore;\n        bestTailDirs = curTailDirs;\n    }\n    \n    int order[4] = {0,1,2,3};\n    for (int k = 3; k > 0; k--) {\n        int j = rng() % (k+1);\n        swap(order[k], order[j]);\n    }\n    for (int k = 0; k < 4; k++) {\n        int d = order[k];\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = t[nr][nc];\n        if (usedTile[tid]) continue;\n        usedTile[tid] = true;\n        curTailScore += p[nr][nc];\n        curTailDirs.push_back(d);\n        dfs(nr, nc);\n        curTailDirs.pop_back();\n        curTailScore -= p[nr][nc];\n        usedTile[tid] = false;\n        if (timeUp) return;\n    }\n}\n\nint main() {\n    cin >> si >> sj;\n    M = 0;\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) {\n            cin >> t[i][j];\n            M = max(M, t[i][j]+1);\n        }\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++)\n            cin >> p[i][j];\n    \n    usedTile.assign(M, false);\n    \n    path.push_back({si, sj});\n    dirs.clear();\n    usedTile[t[si][sj]] = true;\n    totalScore = p[si][sj];\n    \n    {\n        int r = si, c = sj;\n        while (true) {\n            vector<int> cand;\n            for (int d = 0; d < 4; d++) {\n                int nr = r+dr[d], nc = c+dc[d];\n                if (nr<0||nr>=N||nc<0||nc>=N) continue;\n                if (usedTile[t[nr][nc]]) continue;\n                cand.push_back(d);\n            }\n            if (cand.empty()) break;\n            int d = cand[rng()%cand.size()];\n            int nr = r+dr[d], nc = c+dc[d];\n            usedTile[t[nr][nc]] = true;\n            totalScore += p[nr][nc];\n            path.push_back({nr,nc});\n            dirs.push_back(d);\n            r = nr; c = nc;\n        }\n    }\n    \n    double TIME_LIMIT = 1.9;\n    \n    int iter = 0;\n    while (getTime() < TIME_LIMIT) {\n        iter++;\n        int L = path.size();\n        // Bias toward earlier indices for bigger impact\n        int i;\n        if (rng() % 3 == 0) {\n            i = rng() % L;\n        } else {\n            // prefer near end third to do small local changes? Actually, prefer varying\n            i = rng() % L;\n        }\n        \n        int oldSuffixScore = 0;\n        for (int k = i; k < L; k++) oldSuffixScore += p[path[k].first][path[k].second];\n        \n        for (int k = i+1; k < L; k++) {\n            usedTile[t[path[k].first][path[k].second]] = false;\n        }\n        \n        bestTailScore = p[path[i].first][path[i].second];\n        bestTailDirs.clear();\n        curTailScore = bestTailScore;\n        curTailDirs.clear();\n        timeUp = false;\n        dfsCount = 0;\n        \n        double remaining = TIME_LIMIT - getTime();\n        double budget = min(0.02, remaining * 0.02);\n        if (budget < 0.001) budget = 0.001;\n        dfsDeadline = getTime() + budget;\n        \n        dfs(path[i].first, path[i].second);\n        \n        if (bestTailScore >= oldSuffixScore) {\n            path.resize(i+1);\n            dirs.resize(i);\n            int r = path[i].first, c = path[i].second;\n            for (int d : bestTailDirs) {\n                int nr = r+dr[d], nc = c+dc[d];\n                path.push_back({nr,nc});\n                dirs.push_back(d);\n                usedTile[t[nr][nc]] = true;\n                r = nr; c = nc;\n            }\n            totalScore = totalScore - oldSuffixScore + bestTailScore;\n        } else {\n            for (int k = i+1; k < L; k++) {\n                usedTile[t[path[k].first][path[k].second]] = true;\n            }\n        }\n    }\n    \n    string out;\n    for (int d : dirs) out += dch[d];\n    cout << out << endl;\n    \n    cerr << \"Score: \" << totalScore << \" Iter: \" << iter << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\ndouble h[30][29];\ndouble v[29][30];\n\nint main() {\n    for (int i = 0; i < 30; i++) for (int j = 0; j < 29; j++) h[i][j] = 5000;\n    for (int i = 0; i < 29; i++) for (int j = 0; j < 30; j++) v[i][j] = 5000;\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n        \n        vector<vector<double>> dist(30, vector<double>(30, 1e18));\n        vector<vector<int>> prv(30, vector<int>(30, -1));\n        priority_queue<tuple<double,int,int>, vector<tuple<double,int,int>>, greater<>> pq;\n        dist[si][sj] = 0;\n        pq.push({0.0, si, sj});\n        int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};\n        while (!pq.empty()) {\n            auto [d, r, c] = pq.top(); pq.pop();\n            if (d > dist[r][c]) continue;\n            for (int dir = 0; dir < 4; dir++) {\n                int nr = r+dr[dir], nc = c+dc[dir];\n                if (nr<0||nr>=30||nc<0||nc>=30) continue;\n                double w;\n                if (dir == 0) w = v[nr][c];\n                else if (dir == 1) w = v[r][c];\n                else if (dir == 2) w = h[r][nc];\n                else w = h[r][c];\n                if (dist[nr][nc] > d + w) {\n                    dist[nr][nc] = d + w;\n                    prv[nr][nc] = dir;\n                    pq.push({dist[nr][nc], nr, nc});\n                }\n            }\n        }\n        \n        vector<int> dirs;\n        int r = ti, c = tj;\n        while (!(r == si && c == sj)) {\n            int d = prv[r][c];\n            dirs.push_back(d);\n            r -= dr[d]; c -= dc[d];\n        }\n        reverse(dirs.begin(), dirs.end());\n        \n        string path;\n        char ch[] = {'U','D','L','R'};\n        for (int d : dirs) path += ch[d];\n        cout << path << endl;\n        cout.flush();\n        \n        long long b;\n        cin >> b;\n        \n        vector<tuple<int,int,int>> edges;\n        r = si; c = sj;\n        double predicted = 0;\n        for (int d : dirs) {\n            int nr = r+dr[d], nc = c+dc[d];\n            if (d == 0) { edges.push_back({1, nr, c}); predicted += v[nr][c]; }\n            else if (d == 1) { edges.push_back({1, r, c}); predicted += v[r][c]; }\n            else if (d == 2) { edges.push_back({0, r, nc}); predicted += h[r][nc]; }\n            else { edges.push_back({0, r, c}); predicted += h[r][c]; }\n            r = nr; c = nc;\n        }\n        \n        double ratio = (double)b / predicted;\n        if (ratio > 1.5) ratio = 1.5;\n        if (ratio < 0.67) ratio = 0.67;\n        \n        double alpha = 0.1;\n        double sigma = 5.0;\n        \n        double h_delta[30][29] = {{0}};\n        double v_delta[29][30] = {{0}};\n        double h_wt[30][29] = {{0}};\n        double v_wt[29][30] = {{0}};\n        \n        for (auto [type, ei, ej] : edges) {\n            if (type == 0) {\n                for (int jj = 0; jj < 29; jj++) {\n                    double dj = jj - ej;\n                    double w = exp(-dj*dj / (2*sigma*sigma));\n                    h_delta[ei][jj] += w * (ratio - 1.0);\n                    h_wt[ei][jj] += w;\n                }\n            } else {\n                for (int ii = 0; ii < 29; ii++) {\n                    double di = ii - ei;\n                    double w = exp(-di*di / (2*sigma*sigma));\n                    v_delta[ii][ej] += w * (ratio - 1.0);\n                    v_wt[ii][ej] += w;\n                }\n            }\n        }\n        \n        for (int i = 0; i < 30; i++) {\n            for (int j = 0; j < 29; j++) {\n                if (h_wt[i][j] > 0) {\n                    double avg = h_delta[i][j] / h_wt[i][j];\n                    h[i][j] *= (1.0 + alpha * avg);\n                    if (h[i][j] < 1000) h[i][j] = 1000;\n                    if (h[i][j] > 9000) h[i][j] = 9000;\n                }\n            }\n        }\n        for (int i = 0; i < 29; i++) {\n            for (int j = 0; j < 30; j++) {\n                if (v_wt[i][j] > 0) {\n                    double avg = v_delta[i][j] / v_wt[i][j];\n                    v[i][j] *= (1.0 + alpha * avg);\n                    if (v[i][j] < 1000) v[i][j] = 1000;\n                    if (v[i][j] > 9000) v[i][j] = 9000;\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\nusing Clock = chrono::steady_clock;\n\nint N = 20;\nint M;\nvector<string> S;\n\nint ovlp(const string& a, const string& b) {\n    int m = min((int)a.size(), (int)b.size());\n    for (int k = m; k >= 1; k--) {\n        if (a.compare(a.size()-k, k, b, 0, k) == 0) return k;\n    }\n    return 0;\n}\n\nmt19937 rng(42);\n\nint countMatches(vector<string>& grid, vector<int>& avail) {\n    vector<string> tracks;\n    for (int r = 0; r < N; r++) tracks.push_back(grid[r] + grid[r].substr(0, 11));\n    for (int c = 0; c < N; c++) {\n        string col = \"\";\n        for (int r = 0; r < N; r++) col += grid[r][c];\n        tracks.push_back(col + col.substr(0, 11));\n    }\n    int cnt = 0;\n    for (int i : avail) {\n        for (auto& t : tracks) {\n            if (t.find(S[i]) != string::npos) { cnt++; break; }\n        }\n    }\n    return cnt;\n}\n\nint main() {\n    cin >> N >> M;\n    S.resize(M);\n    for (auto& s : S) cin >> s;\n    \n    vector<bool> redundant(M, false);\n    vector<int> idxSort(M);\n    iota(idxSort.begin(), idxSort.end(), 0);\n    sort(idxSort.begin(), idxSort.end(), [](int a, int b){ return S[a].size() > S[b].size(); });\n    \n    for (int ii = 0; ii < M; ii++) {\n        int i = idxSort[ii];\n        if (redundant[i]) continue;\n        for (int jj = ii+1; jj < M; jj++) {\n            int j = idxSort[jj];\n            if (redundant[j]) continue;\n            if (S[i].find(S[j]) != string::npos) redundant[j] = true;\n        }\n    }\n    \n    vector<int> avail;\n    for (int i = 0; i < M; i++) if (!redundant[i]) avail.push_back(i);\n    \n    auto startTime = Clock::now();\n    \n    vector<string> bestGrid(N, string(N, '.'));\n    int bestScore = -1;\n    int bestDots = -1;\n    \n    int trial = 0;\n    while (true) {\n        double elapsed = chrono::duration<double>(Clock::now() - startTime).count();\n        if (elapsed > 2.5) break;\n        trial++;\n        \n        vector<bool> used(M, false);\n        for (int i = 0; i < M; i++) if (redundant[i]) used[i] = true;\n        \n        vector<string> grid(N, string(N, '.'));\n        \n        vector<int> order = avail;\n        shuffle(order.begin(), order.end(), rng);\n        \n        for (int r = 0; r < N; r++) {\n            int first = -1;\n            int bestLen = -1;\n            for (int i : order) if (!used[i]) {\n                if ((int)S[i].size() > bestLen) { bestLen = S[i].size(); first = i; }\n            }\n            if (first == -1) break;\n            vector<int> topCands;\n            for (int i : order) if (!used[i] && (int)S[i].size() >= bestLen) topCands.push_back(i);\n            if (topCands.empty()) break;\n            first = topCands[rng() % topCands.size()];\n            \n            string row = S[first];\n            used[first] = true;\n            if ((int)row.size() > N) row = row.substr(0, N);\n            \n            while ((int)row.size() < N) {\n                vector<tuple<int,int,int>> cands;\n                for (int i : order) if (!used[i]) {\n                    int o = ovlp(row, S[i]);\n                    int addLen = (int)S[i].size() - o;\n                    if ((int)row.size() + addLen > N) continue;\n                    int sc = o * 1000 + (int)S[i].size();\n                    cands.push_back({sc, i, o});\n                }\n                if (cands.empty()) break;\n                sort(cands.begin(), cands.end(), greater<>());\n                int topk = min((int)cands.size(), 3);\n                auto [sc, best, o] = cands[rng() % topk];\n                row += S[best].substr(o);\n                used[best] = true;\n            }\n            \n            for (int j = 0; j < (int)row.size(); j++) grid[r][j] = row[j];\n            \n            string cyc = row;\n            if ((int)row.size() == N) cyc = row + row.substr(0, 11);\n            for (int i : avail) if (!used[i]) {\n                if (cyc.find(S[i]) != string::npos) used[i] = true;\n            }\n        }\n        \n        for (int c = 0; c < N; c++) {\n            string col = \"\";\n            for (int r = 0; r < N; r++) col += grid[r][c];\n            string cyc = col + col.substr(0, 11);\n            for (int i : avail) if (!used[i]) {\n                if (cyc.find(S[i]) != string::npos) used[i] = true;\n            }\n        }\n        \n        for (int i : avail) if (!used[i]) {\n            const string& s = S[i];\n            int L = s.size();\n            bool placed = false;\n            for (int c = 0; c < N && !placed; c++) {\n                for (int r = 0; r < N && !placed; r++) {\n                    bool ok = true;\n                    for (int p = 0; p < L; p++) {\n                        char ch = grid[(r+p)%N][c];\n                        if (ch != '.' && ch != s[p]) { ok = false; break; }\n                    }\n                    if (ok) {\n                        for (int p = 0; p < L; p++) grid[(r+p)%N][c] = s[p];\n                        used[i] = true;\n                        placed = true;\n                    }\n                }\n            }\n        }\n        \n        for (int i : avail) if (!used[i]) {\n            const string& s = S[i];\n            int L = s.size();\n            bool placed = false;\n            for (int r = 0; r < N && !placed; r++) {\n                for (int c = 0; c < N && !placed; c++) {\n                    bool ok = true;\n                    for (int p = 0; p < L; p++) {\n                        char ch = grid[r][(c+p)%N];\n                        if (ch != '.' && ch != s[p]) { ok = false; break; }\n                    }\n                    if (ok) {\n                        for (int p = 0; p < L; p++) grid[r][(c+p)%N] = s[p];\n                        used[i] = true;\n                        placed = true;\n                    }\n                }\n            }\n        }\n        \n        int score = countMatches(grid, avail);\n        int dots = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] == '.') dots++;\n        \n        bool better = false;\n        if (score > bestScore) better = true;\n        else if (score == bestScore) {\n            if (score == (int)avail.size()) {\n                if (dots > bestDots) better = true;\n            }\n        }\n        \n        if (better) {\n            bestScore = score;\n            bestDots = dots;\n            bestGrid = grid;\n        }\n    }\n    \n    if (bestScore == (int)avail.size()) {\n        int cur = bestScore;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) {\n            if (bestGrid[r][c] == '.') continue;\n            char orig = bestGrid[r][c];\n            bestGrid[r][c] = '.';\n            int nw = countMatches(bestGrid, avail);\n            if (nw < cur) bestGrid[r][c] = orig;\n            else cur = nw;\n        }\n    }\n    \n    cerr << \"Trials: \" << trial << \" score: \" << bestScore << \"/\" << avail.size() << \"\\n\";\n    \n    for (int i = 0; i < N; i++) cout << bestGrid[i] << \"\\n\";\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> G;\nvector<vector<int>> id;\nvector<pair<int,int>> pos;\nvector<int> cost;\nint R;\n\nbool isRoad(int i,int j){ return i>=0&&i<N&&j>=0&&j<N&&G[i][j]!='#'; }\n\nchrono::steady_clock::time_point startT;\ndouble elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-startT).count();}\n\nint main(){\n    startT=chrono::steady_clock::now();\n    cin>>N>>si>>sj;\n    G.resize(N);\n    for(auto&s:G)cin>>s;\n    id.assign(N,vector<int>(N,-1));\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(G[i][j]!='#'){\n        id[i][j]=pos.size();\n        pos.push_back({i,j});\n        cost.push_back(G[i][j]-'0');\n    }\n    R=pos.size();\n    \n    vector<vector<int>> visible(R);\n    int dx[]={-1,1,0,0},dy[]={0,0,-1,1};\n    for(int k=0;k<R;k++){\n        auto[i,j]=pos[k];\n        visible[k].push_back(k);\n        for(int d=0;d<4;d++){\n            int x=i+dx[d],y=j+dy[d];\n            while(isRoad(x,y)){\n                visible[k].push_back(id[x][y]);\n                x+=dx[d];y+=dy[d];\n            }\n        }\n    }\n    \n    int sid=id[si][sj];\n    \n    auto greedyCover=[&](unsigned seed)->vector<int>{\n        mt19937 rng(seed);\n        vector<bool> covered(R,false);\n        vector<int> uncovCount(R);\n        for(int k=0;k<R;k++)uncovCount[k]=visible[k].size();\n        vector<int> sel;\n        int nCov=0;\n        auto doSel=[&](int k){\n            sel.push_back(k);\n            for(int v:visible[k]){\n                if(!covered[v]){\n                    covered[v]=true;\n                    nCov++;\n                    for(int u:visible[v])uncovCount[u]--;\n                }\n            }\n        };\n        doSel(sid);\n        while(nCov<R){\n            int bc=-1;\n            vector<int> bests;\n            for(int k=0;k<R;k++){\n                if(uncovCount[k]>bc){bc=uncovCount[k];bests.clear();bests.push_back(k);}\n                else if(uncovCount[k]==bc)bests.push_back(k);\n            }\n            int pick=bests[rng()%bests.size()];\n            doSel(pick);\n        }\n        // redundancy removal\n        vector<int> coverCnt(R,0);\n        for(int s:sel)for(int v:visible[s])coverCnt[v]++;\n        vector<bool> keep(sel.size(),true);\n        vector<int> ord;\n        for(int i=1;i<(int)sel.size();i++)ord.push_back(i);\n        shuffle(ord.begin(),ord.end(),rng);\n        for(int i:ord){\n            int s=sel[i];\n            bool can=true;\n            for(int v:visible[s])if(coverCnt[v]<2){can=false;break;}\n            if(can){\n                keep[i]=false;\n                for(int v:visible[s])coverCnt[v]--;\n            }\n        }\n        vector<int> res;\n        for(int i=0;i<(int)sel.size();i++)if(keep[i])res.push_back(sel[i]);\n        return res;\n    };\n    \n    vector<int> selected = greedyCover(1);\n    for(int t=2;t<=8;t++){\n        auto s2=greedyCover(t*7919u+1);\n        if(s2.size()<selected.size())selected=s2;\n    }\n    // ensure sid is first\n    for(int i=0;i<(int)selected.size();i++)if(selected[i]==sid){swap(selected[0],selected[i]);break;}\n    \n    int K=selected.size();\n    \n    vector<vector<int>> dist(K,vector<int>(R,INT_MAX));\n    vector<vector<int>> prev_(K,vector<int>(R,-1));\n    for(int s=0;s<K;s++){\n        int src=selected[s];\n        dist[s][src]=0;\n        priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>> pq;\n        pq.push({0,src});\n        while(!pq.empty()){\n            auto[d,u]=pq.top();pq.pop();\n            if(d>dist[s][u])continue;\n            auto[i,j]=pos[u];\n            for(int di=0;di<4;di++){\n                int x=i+dx[di],y=j+dy[di];\n                if(!isRoad(x,y))continue;\n                int v=id[x][y];\n                int nd=d+cost[v];\n                if(nd<dist[s][v]){\n                    dist[s][v]=nd;\n                    prev_[s][v]=u;\n                    pq.push({nd,v});\n                }\n            }\n        }\n    }\n    \n    vector<vector<int>> D(K,vector<int>(K));\n    for(int a=0;a<K;a++)for(int b=0;b<K;b++)D[a][b]=dist[a][selected[b]];\n    \n    auto tourLen=[&](const vector<int>&t){\n        int s=0;for(int i=0;i+1<(int)t.size();i++)s+=D[t[i]][t[i+1]];return s;\n    };\n    \n    // Multiple nearest neighbor starts + 2-opt\n    auto twoOpt=[&](vector<int>&tour, double timeLimit){\n        int n=tour.size();\n        bool improved=true;\n        while(improved){\n            improved=false;\n            for(int i=1;i<n-2;i++){\n                if(elapsed()>=timeLimit)return;\n                for(int j=i+1;j<n-1;j++){\n                    int a=tour[i-1],b=tour[i],c=tour[j],d=tour[j+1];\n                    int delta=D[a][c]+D[b][d]-D[a][b]-D[c][d];\n                    if(delta<0){\n                        reverse(tour.begin()+i,tour.begin()+j+1);\n                        improved=true;\n                    }\n                }\n            }\n        }\n    };\n    \n    // Or-opt: move segment to different place\n    auto orOpt=[&](vector<int>&tour, double timeLimit){\n        int n=tour.size();\n        bool improved=true;\n        while(improved){\n            improved=false;\n            for(int segLen=1;segLen<=3;segLen++){\n                for(int i=1;i+segLen<n;i++){\n                    if(elapsed()>=timeLimit)return;\n                    int a=tour[i-1], b=tour[i], c=tour[i+segLen-1], d=tour[i+segLen];\n                    int removeCost=D[a][b]+D[c][d]-D[a][d];\n                    int bestDelta=0, bestJ=-1;\n                    bool bestRev=false;\n                    for(int j=0;j<n-1;j++){\n                        if(j>=i-1 && j<=i+segLen-1)continue;\n                        int e=tour[j], f=tour[j+1];\n                        // insert forward\n                        int ic=D[e][b]+D[c][f]-D[e][f];\n                        int delta=ic-removeCost;\n                        if(delta<bestDelta){bestDelta=delta;bestJ=j;bestRev=false;}\n                        // insert reversed\n                        int ic2=D[e][c]+D[b][f]-D[e][f];\n                        int delta2=ic2-removeCost;\n                        if(delta2<bestDelta){bestDelta=delta2;bestJ=j;bestRev=true;}\n                    }\n                    if(bestJ>=0){\n                        vector<int> seg(tour.begin()+i, tour.begin()+i+segLen);\n                        if(bestRev)reverse(seg.begin(),seg.end());\n                        vector<int> nt;\n                        int j=bestJ;\n                        if(j<i-1){\n                            for(int k=0;k<=j;k++)nt.push_back(tour[k]);\n                            for(int x:seg)nt.push_back(x);\n                            for(int k=j+1;k<i;k++)nt.push_back(tour[k]);\n                            for(int k=i+segLen;k<n;k++)nt.push_back(tour[k]);\n                        } else {\n                            for(int k=0;k<i;k++)nt.push_back(tour[k]);\n                            for(int k=i+segLen;k<=j;k++)nt.push_back(tour[k]);\n                            for(int x:seg)nt.push_back(x);\n                            for(int k=j+1;k<n;k++)nt.push_back(tour[k]);\n                        }\n                        tour=nt;\n                        improved=true;\n                        break;\n                    }\n                }\n                if(improved)break;\n            }\n        }\n    };\n    \n    auto nearestNeighborFrom=[&](int start){\n        vector<int> tour;\n        // tour must start at 0\n        vector<bool> used(K,false);\n        used[0]=true;\n        tour.push_back(0);\n        if(start!=0){\n            tour.push_back(start);\n            used[start]=true;\n        }\n        while((int)tour.size()<K){\n            int last=tour.back();\n            int bn=-1,bd=INT_MAX;\n            for(int j=0;j<K;j++)if(!used[j]&&D[last][j]<bd){bd=D[last][j];bn=j;}\n            tour.push_back(bn);used[bn]=true;\n        }\n        tour.push_back(0);\n        return tour;\n    };\n    \n    vector<int> bestTour = nearestNeighborFrom(0);\n    twoOpt(bestTour, 0.3);\n    orOpt(bestTour, 0.5);\n    twoOpt(bestTour, 0.6);\n    int bestLen = tourLen(bestTour);\n    \n    // Try other starting neighbors\n    for(int s=1;s<K && elapsed()<1.0;s++){\n        vector<int> t = nearestNeighborFrom(s);\n        twoOpt(t, min(1.0, elapsed()+0.1));\n        int l=tourLen(t);\n        if(l<bestLen){bestLen=l;bestTour=t;}\n    }\n    \n    // Double bridge perturbation + 2-opt\n    mt19937 rng(12345);\n    while(elapsed()<2.7){\n        vector<int> t2 = bestTour;\n        int n = t2.size()-1;\n        if(n<8){\n            // just do 2-opt\n            break;\n        }\n        int p1=1+rng()%(n/4);\n        int p2=p1+1+rng()%(n/4);\n        int p3=p2+1+rng()%(n/4);\n        if(p3>=n)continue;\n        vector<int> nt;\n        nt.push_back(t2[0]);\n        for(int i=p3;i<n;i++)nt.push_back(t2[i]);\n        for(int i=p2;i<p3;i++)nt.push_back(t2[i]);\n        for(int i=p1;i<p2;i++)nt.push_back(t2[i]);\n        for(int i=1;i<p1;i++)nt.push_back(t2[i]);\n        nt.push_back(t2[0]);\n        \n        double lim = min(2.7, elapsed()+0.2);\n        twoOpt(nt, lim);\n        orOpt(nt, min(2.7, elapsed()+0.1));\n        twoOpt(nt, min(2.7, elapsed()+0.1));\n        int l=tourLen(nt);\n        if(l<bestLen){bestLen=l;bestTour=nt;}\n    }\n    \n    vector<int>& tour = bestTour;\n    \n    string result;\n    for(int i=0;i+1<(int)tour.size();i++){\n        int a=selected[tour[i]], b=selected[tour[i+1]];\n        if(a==b)continue;\n        int s=tour[i];\n        vector<int> path;\n        int cur=b;\n        while(cur!=a){\n            path.push_back(cur);\n            cur=prev_[s][cur];\n        }\n        reverse(path.begin(),path.end());\n        int px=pos[a].first, py=pos[a].second;\n        for(int n:path){\n            int nx=pos[n].first, ny=pos[n].second;\n            if(nx==px-1)result+='U';\n            else if(nx==px+1)result+='D';\n            else if(ny==py-1)result+='L';\n            else result+='R';\n            px=nx;py=ny;\n        }\n    }\n    \n    cout<<result<<endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> D;\nvector<vector<int>> deps;\nvector<vector<int>> children;\nvector<int> indeg;\nvector<int> longestPath;\n\nvector<vector<int>> estS;\nvector<vector<pair<int,int>>> obs;\n\nint computeW(const vector<int>& d, const vector<int>& s) {\n    int w = 0;\n    for (int k = 0; k < K; k++) w += max(0, d[k] - s[k]);\n    return w;\n}\n\nint predictTime(int task, int member) {\n    int w = computeW(D[task], estS[member]);\n    return (w == 0) ? 1 : max(1, w);\n}\n\ndouble errorFor(int member) {\n    double err = 0;\n    for (auto& p : obs[member]) {\n        int w = computeW(D[p.first], estS[member]);\n        int pred = (w == 0) ? 1 : max(1, w);\n        double diff = (double)pred - p.second;\n        err += diff * diff;\n    }\n    return err;\n}\n\nvoid updateSkills(int member) {\n    if (obs[member].empty()) return;\n    double best = errorFor(member);\n    for (int pass = 0; pass < 100; pass++) {\n        bool improved = false;\n        for (int k = 0; k < K; k++) {\n            for (int delta : {1, -1, 2, -2, 3, -3}) {\n                int old = estS[member][k];\n                int nv = old + delta;\n                if (nv < 0 || nv > 50) continue;\n                estS[member][k] = nv;\n                double e = errorFor(member);\n                if (e < best - 1e-9) {\n                    best = e;\n                    improved = true;\n                } else {\n                    estS[member][k] = old;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> N >> M >> K >> R;\n    D.assign(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> D[i][k];\n    deps.assign(N, {});\n    children.assign(N, {});\n    indeg.assign(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u);\n        children[u].push_back(v);\n        indeg[v]++;\n    }\n    \n    longestPath.assign(N, 0);\n    for (int i = N - 1; i >= 0; i--) {\n        int b = 0;\n        for (int ch : children[i]) b = max(b, longestPath[ch]);\n        longestPath[i] = b + 1;\n    }\n    \n    estS.assign(M, vector<int>(K, 3));\n    obs.assign(M, {});\n    \n    vector<int> taskStatus(N, 0);\n    vector<int> memberTask(M, -1);\n    vector<int> memberStartDay(M, 0);\n    vector<int> remIndeg = indeg;\n    \n    for (int day = 1; day <= 2000; day++) {\n        vector<int> avail;\n        for (int i = 0; i < N; i++)\n            if (taskStatus[i] == 0 && remIndeg[i] == 0) avail.push_back(i);\n        \n        sort(avail.begin(), avail.end(), [&](int a, int b) {\n            return longestPath[a] > longestPath[b];\n        });\n        \n        set<int> freeSet;\n        for (int j = 0; j < M; j++) if (memberTask[j] == -1) freeSet.insert(j);\n        \n        vector<pair<int,int>> assignments;\n        for (int task : avail) {\n            if (freeSet.empty()) break;\n            int bestMem = -1, bestTime = INT_MAX;\n            for (int j : freeSet) {\n                int t = predictTime(task, j);\n                if (t < bestTime) { bestTime = t; bestMem = j; }\n            }\n            if (bestMem != -1) {\n                assignments.push_back({bestMem, task});\n                freeSet.erase(bestMem);\n                taskStatus[task] = 1;\n                memberTask[bestMem] = task;\n                memberStartDay[bestMem] = day;\n            }\n        }\n        \n        cout << assignments.size();\n        for (auto& p : assignments) cout << \" \" << (p.first+1) << \" \" << (p.second+1);\n        cout << \"\\n\";\n        cout.flush();\n        \n        int n; cin >> n;\n        if (n == -1) return 0;\n        for (int i = 0; i < n; i++) {\n            int f; cin >> f; f--;\n            int task = memberTask[f];\n            int daysTaken = day - memberStartDay[f] + 1;\n            obs[f].push_back({task, daysTaken});\n            taskStatus[task] = 2;\n            memberTask[f] = -1;\n            for (int ch : children[task]) remIndeg[ch]--;\n            updateSkills(f);\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint A[1000][4];\n\ninline int px(int id) { \n    if(id<=0) return 400;\n    if(id<=1000) return A[id-1][0];\n    return A[id-1001][2];\n}\ninline int py(int id) {\n    if(id<=0) return 400;\n    if(id<=1000) return A[id-1][1];\n    return A[id-1001][3];\n}\ninline int D(int a, int b) {\n    return abs(px(a)-px(b))+abs(py(a)-py(b));\n}\n\nint routeCost(const vector<int>& s){\n    int t=0;\n    for(int i=0;i+1<(int)s.size();i++) t+=D(s[i],s[i+1]);\n    return t;\n}\n\nint insertOrderBest(vector<int>& s, int oid){\n    int p = oid+1, d = oid+1001;\n    int best = INT_MAX;\n    int bi=1,bj=1;\n    int n = s.size();\n    for(int i=1;i<n;i++){\n        int dss = D(s[i-1],s[i]);\n        int dps = D(s[i-1],p);\n        int dpe = D(p,s[i]);\n        {\n            int delta = dps + D(p,d) + D(d,s[i]) - dss;\n            if(delta<best){best=delta;bi=i;bj=i;}\n        }\n        int baseP = dps+dpe-dss;\n        for(int j=i+1;j<n;j++){\n            int delta = baseP + D(s[j-1],d)+D(d,s[j])-D(s[j-1],s[j]);\n            if(delta<best){best=delta;bi=i;bj=j;}\n        }\n    }\n    if(bi==bj){\n        s.insert(s.begin()+bi, d);\n        s.insert(s.begin()+bi, p);\n    } else {\n        s.insert(s.begin()+bj, d);\n        s.insert(s.begin()+bi, p);\n    }\n    return best;\n}\n\nint removeOrderDelta(vector<int>& s, int oid){\n    int p=oid+1, d=oid+1001;\n    int ip=-1, idx_=-1;\n    int n=s.size();\n    for(int i=0;i<n;i++){\n        if(s[i]==p) ip=i;\n        else if(s[i]==d) idx_=i;\n    }\n    int delta = 0;\n    if(idx_ == ip+1){\n        delta = D(s[ip-1], s[idx_+1]) - D(s[ip-1],p) - D(p,d) - D(d, s[idx_+1]);\n        s.erase(s.begin()+ip, s.begin()+idx_+1);\n    } else {\n        delta -= D(s[ip-1],p) + D(p, s[ip+1]);\n        delta += D(s[ip-1], s[ip+1]);\n        delta -= D(s[idx_-1], d) + D(d, s[idx_+1]);\n        delta += D(s[idx_-1], s[idx_+1]);\n        s.erase(s.begin()+idx_);\n        s.erase(s.begin()+ip);\n    }\n    return delta;\n}\n\nint relocateOnce(vector<int>& s){\n    int n = s.size();\n    vector<int> partnerPos(n, -1);\n    vector<int> pos(2001, -1);\n    for(int i=0;i<n;i++) pos[s[i]]=i;\n    for(int i=0;i<n;i++){\n        int id = s[i];\n        if(id<=0) continue;\n        int partner = (id<=1000) ? id+1000 : id-1000;\n        partnerPos[i] = pos[partner];\n    }\n    \n    int bestDelta = 0;\n    int bestFrom=-1, bestTo=-1;\n    for(int from=1;from<n-1;from++){\n        int id = s[from];\n        if(id<=0) continue;\n        bool isPickup = (id<=1000);\n        int pp = partnerPos[from];\n        int lo, hi;\n        if(isPickup){ lo=1; hi=pp; }\n        else { lo=pp+1; hi=n; }\n        int remGain = D(s[from-1],s[from])+D(s[from],s[from+1])-D(s[from-1],s[from+1]);\n        for(int to=lo;to<=hi;to++){\n            if(to==from || to==from+1) continue;\n            int aa = s[to-1], bb = s[to];\n            int insCost = D(aa,id)+D(id,bb)-D(aa,bb);\n            int delta = insCost - remGain;\n            if(delta < bestDelta){\n                bestDelta = delta;\n                bestFrom = from;\n                bestTo = to;\n            }\n        }\n    }\n    if(bestDelta<0){\n        int id = s[bestFrom];\n        s.erase(s.begin()+bestFrom);\n        int to = bestTo;\n        if(to>bestFrom) to--;\n        s.insert(s.begin()+to, id);\n        return bestDelta;\n    }\n    return 0;\n}\n\nint main(){\n    auto start = steady_clock::now();\n    for(int i=0;i<1000;i++) for(int j=0;j<4;j++) cin>>A[i][j];\n    \n    vector<pair<int,int>> scored(1000);\n    for(int i=0;i<1000;i++){\n        int s = abs(A[i][0]-400)+abs(A[i][1]-400)+abs(A[i][2]-400)+abs(A[i][3]-400);\n        scored[i]={s,i};\n    }\n    sort(scored.begin(),scored.end());\n    \n    vector<bool> inChosen(1000,false);\n    vector<int> chosen;\n    for(int i=0;i<50;i++){ chosen.push_back(scored[i].second); inChosen[scored[i].second]=true; }\n    \n    vector<int> seq = {0, 0};\n    for(int oid : chosen) insertOrderBest(seq, oid);\n    int curCost = routeCost(seq);\n    \n    while(relocateOnce(seq) < 0);\n    curCost = routeCost(seq);\n    \n    mt19937 rng(12345);\n    \n    int timeLimit = 1850;\n    long long iter = 0;\n    vector<int> backup;\n    \n    while(true){\n        if((iter&1023)==0){\n            auto el = duration_cast<milliseconds>(steady_clock::now()-start).count();\n            if(el>timeLimit) break;\n        }\n        iter++;\n        \n        int mode = rng()%5;\n        if(mode<3){\n            int idx = rng()%50;\n            int oldOrd = chosen[idx];\n            int newOrd;\n            do { newOrd = rng()%1000; } while(inChosen[newOrd]);\n            \n            backup = seq;\n            int remDelta = removeOrderDelta(seq, oldOrd);\n            int insDelta = insertOrderBest(seq, newOrd);\n            int total = remDelta + insDelta;\n            if(total < 0){\n                curCost += total;\n                inChosen[oldOrd]=false;\n                inChosen[newOrd]=true;\n                chosen[idx]=newOrd;\n            } else {\n                seq = backup;\n            }\n        } else if(mode==3){\n            int d = relocateOnce(seq);\n            curCost += d;\n        } else {\n            int idx = rng()%50;\n            int oid = chosen[idx];\n            int remDelta = removeOrderDelta(seq, oid);\n            int insDelta = insertOrderBest(seq, oid);\n            curCost += remDelta + insDelta;\n        }\n    }\n    \n    while(relocateOnce(seq) < 0);\n    \n    cout << 50;\n    vector<int> ords;\n    set<int> seen;\n    for(int id : seq){\n        if(id>=1 && id<=1000 && !seen.count(id-1)){\n            ords.push_back(id-1);\n            seen.insert(id-1);\n        }\n    }\n    for(int o : ords) cout << \" \" << (o+1);\n    cout << \"\\n\";\n    cout << seq.size();\n    for(int id : seq) cout << \" \" << px(id) << \" \" << py(id);\n    cout << \"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    int p[400], r[400];\n    void init(int n){ for(int i=0;i<n;i++){p[i]=i;r[i]=0;} }\n    int f(int x){ while(p[x]!=x){p[x]=p[p[x]];x=p[x];} return x; }\n    bool u(int a,int b){ a=f(a);b=f(b); if(a==b)return false; if(r[a]<r[b])swap(a,b); p[b]=a; if(r[a]==r[b])r[a]++; return true; }\n};\n\nint N=400, M=1995;\nint X[400], Y[400];\nint U[2000], V[2000], D[2000];\n\nconst int WMAX = 4000;\nint bkt_head[WMAX+2];\nint bkt_next[2100];\nint ea[2100], eb[2100], ew[2100];\nDSU sim;\n\nint main(){\n    for(int i=0;i<N;i++) scanf(\"%d %d\", &X[i], &Y[i]);\n    for(int i=0;i<M;i++){\n        scanf(\"%d %d\", &U[i], &V[i]);\n        double dx=X[U[i]]-X[V[i]], dy=Y[U[i]]-Y[V[i]];\n        D[i] = (int)round(sqrt(dx*dx+dy*dy));\n        if(D[i]<1) D[i]=1;\n    }\n    \n    vector<tuple<int,int,int>> adoptedEdges;\n    DSU glob; glob.init(N);\n    \n    uint64_t rng_state = 123456789;\n    auto rnd = [&]() -> uint32_t {\n        rng_state ^= rng_state << 13;\n        rng_state ^= rng_state >> 7;\n        rng_state ^= rng_state << 17;\n        return (uint32_t)rng_state;\n    };\n    \n    const int TRIALS = 20;\n    const int THRESH = 10;\n    \n    for(int i=0;i<M;i++){\n        int l; scanf(\"%d\", &l);\n        \n        if(glob.f(U[i]) == glob.f(V[i])){\n            printf(\"0\\n\"); fflush(stdout);\n            continue;\n        }\n        \n        int cnt = 0;\n        int maxW = 0;\n        for(auto& [w,a,b]: adoptedEdges){\n            ew[cnt]=w; ea[cnt]=a; eb[cnt]=b; cnt++;\n            if(w>maxW) maxW=w;\n        }\n        ew[cnt]=l; ea[cnt]=U[i]; eb[cnt]=V[i];\n        int curIdx = cnt;\n        if(l>maxW) maxW=l;\n        cnt++;\n        int staticCnt = cnt;\n        \n        for(int j=i+1;j<M;j++){\n            ea[cnt]=U[j]; eb[cnt]=V[j]; cnt++;\n        }\n        \n        int adoptCount = 0;\n        int done = 0;\n        bool decided = false;\n        bool adopt = false;\n        \n        for(int t=0; t<TRIALS; t++){\n            int tmpMax = maxW;\n            for(int k=staticCnt; k<cnt; k++){\n                int j = i+1 + (k - staticCnt);\n                int range = 2*D[j]+1;\n                int w = D[j] + (int)(rnd() % (uint32_t)range);\n                ew[k] = w;\n                if(w > tmpMax) tmpMax = w;\n            }\n            \n            for(int w=0; w<=tmpMax; w++) bkt_head[w] = -1;\n            for(int k=0; k<cnt; k++){\n                bkt_next[k] = bkt_head[ew[k]];\n                bkt_head[ew[k]] = k;\n            }\n            \n            sim.init(N);\n            bool used = false;\n            int compCount = N;\n            for(int w=0; w<=tmpMax && compCount>1; w++){\n                for(int k=bkt_head[w]; k!=-1; k=bkt_next[k]){\n                    if(sim.u(ea[k], eb[k])){\n                        compCount--;\n                        if(k == curIdx) used = true;\n                    }\n                }\n            }\n            \n            if(used) adoptCount++;\n            done++;\n            int remaining = TRIALS - done;\n            if(adoptCount >= THRESH){ adopt=true; decided=true; break; }\n            if(adoptCount + remaining < THRESH){ adopt=false; decided=true; break; }\n        }\n        if(!decided) adopt = (adoptCount >= THRESH);\n        \n        if(adopt){\n            printf(\"1\\n\");\n            adoptedEdges.push_back({l, U[i], V[i]});\n            glob.u(U[i], V[i]);\n        } else {\n            printf(\"0\\n\");\n        }\n        fflush(stdout);\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint pt[25];\nint hx[15], hy[15];\nint grid[32][32];\nvector<pair<int,int>> pets;\n\nint dx4[] = {-1,1,0,0};\nint dy4[] = {0,0,-1,1};\nchar mvch[] = {'U','D','L','R'};\n\nbool inb(int x, int y) { return x>=1 && x<=30 && y>=1 && y<=30; }\n\nbool canWall(int x, int y) {\n    if (!inb(x,y)) return false;\n    if (grid[x][y]) return false;\n    for (auto& p : pets) if (p.first==x && p.second==y) return false;\n    for (int i=0;i<M;i++) if (hx[i]==x && hy[i]==y) return false;\n    for (int d=0;d<4;d++) {\n        int nx=x+dx4[d], ny=y+dy4[d];\n        for (auto& p : pets) if (p.first==nx && p.second==ny) return false;\n    }\n    return true;\n}\n\nvoid bfs(int sx, int sy, vector<vector<int>>& dist) {\n    dist.assign(32, vector<int>(32, -1));\n    if (!inb(sx,sy) || grid[sx][sy]) return;\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+dx4[d], ny=y+dy4[d];\n            if (!inb(nx,ny)||grid[nx][ny]||dist[nx][ny]!=-1) continue;\n            dist[nx][ny]=dist[x][y]+1;\n            q.push({nx,ny});\n        }\n    }\n}\n\nint main(){\n    cin >> N;\n    pets.resize(N);\n    for (int i=0;i<N;i++){\n        int x,y,t; cin >> x >> y >> t;\n        pets[i]={x,y}; pt[i]=t;\n    }\n    cin >> M;\n    for (int i=0;i<M;i++) cin >> hx[i] >> hy[i];\n    memset(grid,0,sizeof(grid));\n    \n    vector<int> order(M); iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),[](int a,int b){return hy[a]<hy[b];});\n    vector<pair<int,int>> assignSeg(M);\n    for (int k=0;k<M;k++){\n        int s = 1 + k*30/M, e = (k+1)*30/M;\n        assignSeg[order[k]] = {s, e};\n    }\n    \n    vector<int> standRow(M), wallRow(M,15);\n    vector<char> wallDir(M);\n    for (int i=0;i<M;i++){\n        if (hx[i] <= 14){ standRow[i]=14; wallDir[i]='d'; }\n        else if (hx[i] >= 16){ standRow[i]=16; wallDir[i]='u'; }\n        else { standRow[i]=14; wallDir[i]='d'; }\n    }\n    \n    vector<int> phase(M,0);\n    \n    auto isHumanAt = [&](int x, int y, int skip) {\n        for (int i=0;i<M;i++) if (i!=skip && hx[i]==x && hy[i]==y) return true;\n        return false;\n    };\n    \n    for (int turn=0; turn<300; turn++){\n        string action(M,'.');\n        vector<pair<int,int>> newWalls;\n        \n        for (int i=0;i<M;i++){\n            int cx=hx[i], cy=hy[i];\n            auto [cs, ce] = assignSeg[i];\n            \n            auto tryMove = [&](int tx, int ty) {\n                vector<vector<int>> dist;\n                bfs(tx,ty,dist);\n                if (dist[cx][cy]<=0) return;\n                for (int d=0;d<4;d++){\n                    int nx=cx+dx4[d], ny=cy+dy4[d];\n                    if (!inb(nx,ny)||grid[nx][ny]) continue;\n                    if (dist[nx][ny]==dist[cx][cy]-1 && !isHumanAt(nx,ny,i)){\n                        bool blocked=false;\n                        for (auto& w: newWalls) if (w.first==nx&&w.second==ny){blocked=true;break;}\n                        if (blocked) continue;\n                        action[i]=mvch[d];\n                        return;\n                    }\n                }\n            };\n            \n            if (phase[i]==0){\n                if (cx==standRow[i] && cy==cs){\n                    phase[i]=1;\n                } else {\n                    tryMove(standRow[i], cs);\n                    continue;\n                }\n            }\n            if (phase[i]==1){\n                if (cx!=standRow[i]){\n                    tryMove(standRow[i], cy);\n                    continue;\n                }\n                int wx = wallRow[i], wy=cy;\n                if (!grid[wx][wy]){\n                    if (canWall(wx,wy)){\n                        action[i]=wallDir[i];\n                        newWalls.push_back({wx,wy});\n                    }\n                } else {\n                    if (cy<ce){\n                        int nx=cx, ny=cy+1;\n                        if (inb(nx,ny)&&!grid[nx][ny]&&!isHumanAt(nx,ny,i)){\n                            action[i]='R';\n                        }\n                    } else {\n                        phase[i]=2;\n                    }\n                }\n            }\n        }\n        \n        cout << action << endl;\n        cout.flush();\n        \n        for (int i=0;i<M;i++){\n            char a = action[i];\n            if (a=='U'||a=='D'||a=='L'||a=='R'){\n                int d = (a=='U')?0:(a=='D')?1:(a=='L')?2:3;\n                hx[i]+=dx4[d]; hy[i]+=dy4[d];\n            }\n        }\n        for (auto& w : newWalls) grid[w.first][w.second]=1;\n        \n        for (int i=0;i<N;i++){\n            string s; cin >> s;\n            int x=pets[i].first, y=pets[i].second;\n            for (char c : s){\n                if (c=='U') x--;\n                else if (c=='D') x++;\n                else if (c=='L') y--;\n                else if (c=='R') y++;\n            }\n            pets[i]={x,y};\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si,sj,ti,tj;\ndouble p;\nint H[20][19], V[19][20];\n\ninline bool canMove(int i,int j,char c){\n    if(c=='U') return i>0 && V[i-1][j]==0;\n    if(c=='D') return i<19 && V[i][j]==0;\n    if(c=='L') return j>0 && H[i][j-1]==0;\n    return j<19 && H[i][j]==0;\n}\ninline pair<int,int> move1(int i,int j,char c){\n    if(!canMove(i,j,c)) return {i,j};\n    if(c=='U') return {i-1,j};\n    if(c=='D') return {i+1,j};\n    if(c=='L') return {i,j-1};\n    return {i,j+1};\n}\n\ndouble evalScore(const string& s){\n    static double dist[400], nd[400];\n    memset(dist,0,sizeof(dist));\n    int start_idx = si*20+sj;\n    int goal_idx = ti*20+tj;\n    dist[start_idx]=1.0;\n    if(start_idx==goal_idx) return 400.0;\n    double score=0;\n    int L=s.size();\n    double pp=p, q=1-p;\n    for(int t=0;t<L;t++){\n        char c=s[t];\n        memset(nd,0,sizeof(nd));\n        for(int idx=0;idx<400;idx++){\n            double d=dist[idx];\n            if(d<1e-18) continue;\n            int i=idx/20, j=idx%20;\n            nd[idx] += d*pp;\n            auto [ni,nj]=move1(i,j,c);\n            nd[ni*20+nj] += d*q;\n        }\n        double arrived = nd[goal_idx];\n        score += arrived * (400 - t);\n        nd[goal_idx]=0;\n        memcpy(dist,nd,sizeof(dist));\n    }\n    return score;\n}\n\nvector<string> findPaths(int maxPaths, mt19937& rng){\n    vector<string> paths;\n    set<string> seen;\n    string dirs=\"UDLR\";\n    \n    auto bfsPath=[&](string order)->string{\n        vector<vector<int>> bd(20,vector<int>(20,-1));\n        vector<vector<pair<int,int>>> par(20,vector<pair<int,int>>(20,{-1,-1}));\n        vector<vector<char>> pc(20,vector<char>(20,0));\n        queue<pair<int,int>> q;\n        q.push({si,sj}); bd[si][sj]=0;\n        while(!q.empty()){\n            auto [i,j]=q.front(); q.pop();\n            for(char c:order){\n                if(canMove(i,j,c)){\n                    auto [ni,nj]=move1(i,j,c);\n                    if(bd[ni][nj]==-1){\n                        bd[ni][nj]=bd[i][j]+1;\n                        par[ni][nj]={i,j};\n                        pc[ni][nj]=c;\n                        q.push({ni,nj});\n                    }\n                }\n            }\n        }\n        string path;\n        int ci=ti,cj=tj;\n        if(bd[ti][tj]==-1) return \"\";\n        while(!(ci==si&&cj==sj)){\n            path+=pc[ci][cj];\n            auto [pi,pj]=par[ci][cj];\n            ci=pi; cj=pj;\n        }\n        reverse(path.begin(),path.end());\n        return path;\n    };\n    \n    string p1=bfsPath(\"UDLR\");\n    paths.push_back(p1); seen.insert(p1);\n    int shortestLen=p1.size();\n    \n    for(int attempt=0; attempt<300 && (int)paths.size()<maxPaths; attempt++){\n        string d=dirs;\n        shuffle(d.begin(),d.end(),rng);\n        string path=bfsPath(d);\n        if(!path.empty() && (int)path.size() <= shortestLen+4 && !seen.count(path)){\n            paths.push_back(path);\n            seen.insert(path);\n        }\n    }\n    return paths;\n}\n\nint main(){\n    cin>>si>>sj>>ti>>tj>>p;\n    for(int i=0;i<20;i++){\n        string s; cin>>s;\n        for(int j=0;j<19;j++) H[i][j]=s[j]-'0';\n    }\n    for(int i=0;i<19;i++){\n        string s; cin>>s;\n        for(int j=0;j<20;j++) V[i][j]=s[j]-'0';\n    }\n    \n    auto start=chrono::steady_clock::now();\n    auto elapsedMs=[&](){\n        auto now=chrono::steady_clock::now();\n        return chrono::duration_cast<chrono::milliseconds>(now-start).count();\n    };\n    \n    mt19937 rng(12345);\n    \n    vector<string> paths = findPaths(20, rng);\n    \n    string best=\"\";\n    double bestScore=-1;\n    string dirs=\"UDLR\";\n    \n    for(auto& path : paths){\n        int L=path.size();\n        if(L==0) continue;\n        for(int k=1; k*L<=200; k++){\n            string cand;\n            for(char c:path) for(int r=0;r<k;r++) cand+=c;\n            double sc=evalScore(cand);\n            if(sc>bestScore){bestScore=sc; best=cand;}\n        }\n        for(int k=1; k*L<=200; k++){\n            string cand;\n            for(char c:path) for(int r=0;r<k;r++) cand+=c;\n            while((int)cand.size()<200) cand+=path.back();\n            double sc=evalScore(cand);\n            if(sc>bestScore){bestScore=sc; best=cand;}\n        }\n    }\n    \n    int TIME_LIMIT = 1800;\n    \n    // Local search\n    bool improved=true;\n    while(improved && elapsedMs()<TIME_LIMIT){\n        improved=false;\n        // substitution\n        for(int pos=0;pos<(int)best.size() && elapsedMs()<TIME_LIMIT;pos++){\n            char orig=best[pos];\n            for(char c : dirs){\n                if(c==orig) continue;\n                best[pos]=c;\n                double sc=evalScore(best);\n                if(sc>bestScore+1e-9){bestScore=sc; improved=true; orig=c;}\n                else best[pos]=orig;\n            }\n        }\n        // deletion\n        for(int pos=0;pos<(int)best.size() && elapsedMs()<TIME_LIMIT;pos++){\n            string cand=best;\n            cand.erase(cand.begin()+pos);\n            double sc=evalScore(cand);\n            if(sc>bestScore+1e-9){bestScore=sc; best=cand; improved=true; pos--;}\n        }\n        // insertion\n        for(int pos=0;pos<=(int)best.size() && (int)best.size()<200 && elapsedMs()<TIME_LIMIT;pos++){\n            for(char c : dirs){\n                string cand=best;\n                cand.insert(cand.begin()+pos,c);\n                double sc=evalScore(cand);\n                if(sc>bestScore+1e-9){bestScore=sc; best=cand; improved=true; break;}\n            }\n        }\n    }\n    \n    cout<<best<<endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nint to_dir[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\nint di[4] = {0, -1, 0, 1};\nint dj[4] = {-1, 0, 1, 0};\nint rot1[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n\nint tiles[30][30];\nint visited[30][30][4];\nint gen = 0;\n\nstruct EvalRes {\n    long long score;\n    long long proxy;\n};\n\nEvalRes evaluate() {\n    gen++;\n    int L1 = 0, L2 = 0;\n    long long sumSq = 0;\n    for (int si = 0; si < 30; si++) {\n        for (int sj = 0; sj < 30; sj++) {\n            for (int sd = 0; sd < 4; sd++) {\n                if (visited[si][sj][sd] == gen) continue;\n                int i = si, j = sj, d = sd;\n                int len = 0;\n                while (true) {\n                    if (visited[i][j][d] == gen) break;\n                    visited[i][j][d] = gen;\n                    int t = tiles[i][j];\n                    int d2 = to_dir[t][d];\n                    if (d2 == -1) break;\n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if (ni<0||ni>=30||nj<0||nj>=30) break;\n                    int nd = (d2 + 2) % 4;\n                    len++;\n                    if (ni == si && nj == sj && nd == sd) {\n                        if (len > L1) { L2 = L1; L1 = len; }\n                        else if (len > L2) L2 = len;\n                        sumSq += (long long)len * len;\n                        break;\n                    }\n                    i = ni; j = nj; d = nd;\n                }\n            }\n        }\n    }\n    return {(long long)L1 * L2, sumSq};\n}\n\nint rot[30][30];\nint bestRot[30][30];\nint inputG[30][30];\n\ninline void applyRot(int i, int j, int r) {\n    rot[i][j] = r;\n    int t = inputG[i][j];\n    for (int k = 0; k < r; k++) t = rot1[t];\n    tiles[i][j] = t;\n}\n\nint main() {\n    for (int i = 0; i < 30; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < 30; j++) inputG[i][j] = s[j]-'0';\n    }\n    \n    mt19937 rng(12345);\n    long long bestScore = 0;\n    \n    auto start = chrono::steady_clock::now();\n    double TL = 1.9;\n    \n    int restart = 0;\n    bool done = false;\n    while (!done) {\n        auto now = chrono::steady_clock::now();\n        double elapsedTotal = chrono::duration<double>(now-start).count();\n        if (elapsedTotal > TL - 0.01) break;\n        \n        restart++;\n        for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) {\n            int r = (restart == 1) ? 0 : rng()%4;\n            applyRot(i, j, r);\n        }\n        \n        auto cur = evaluate();\n        if (cur.score > bestScore) {\n            bestScore = cur.score;\n            memcpy(bestRot, rot, sizeof(rot));\n        }\n        \n        double restartBudget = 0.6;\n        if (TL - elapsedTotal < restartBudget) restartBudget = TL - elapsedTotal;\n        double restartStart = elapsedTotal;\n        \n        double T0 = 2000.0, T1 = 1.0;\n        int iter = 0;\n        double localElapsed = 0;\n        while (true) {\n            iter++;\n            if ((iter & 255) == 0) {\n                auto now2 = chrono::steady_clock::now();\n                double e = chrono::duration<double>(now2-start).count();\n                localElapsed = e - restartStart;\n                if (e > TL) { done = true; break; }\n                if (localElapsed > restartBudget) break;\n            }\n            double progress = localElapsed / restartBudget;\n            if (progress > 1) progress = 1;\n            double T = T0 * pow(T1/T0, progress);\n            \n            int mtype = rng()%10;\n            if (mtype < 7) {\n                int i = rng()%30, j = rng()%30;\n                int oldR = rot[i][j];\n                int newR = (oldR + 1 + rng()%3) % 4;\n                applyRot(i, j, newR);\n                auto nw = evaluate();\n                long long delta = nw.proxy - cur.proxy;\n                if (delta >= 0 || (double)rng()/(double)rng.max() < exp((double)delta/T)) {\n                    cur = nw;\n                    if (nw.score > bestScore) {\n                        bestScore = nw.score;\n                        memcpy(bestRot, rot, sizeof(rot));\n                    }\n                } else {\n                    applyRot(i, j, oldR);\n                }\n            } else {\n                int i1 = rng()%30, j1 = rng()%30;\n                int i2 = rng()%30, j2 = rng()%30;\n                int oldR1 = rot[i1][j1], oldR2 = rot[i2][j2];\n                int newR1 = (oldR1 + 1 + rng()%3) % 4;\n                int newR2 = (oldR2 + 1 + rng()%3) % 4;\n                applyRot(i1, j1, newR1);\n                applyRot(i2, j2, newR2);\n                auto nw = evaluate();\n                long long delta = nw.proxy - cur.proxy;\n                if (delta >= 0 || (double)rng()/(double)rng.max() < exp((double)delta/T)) {\n                    cur = nw;\n                    if (nw.score > bestScore) {\n                        bestScore = nw.score;\n                        memcpy(bestRot, rot, sizeof(rot));\n                    }\n                } else {\n                    applyRot(i1, j1, oldR1);\n                    applyRot(i2, j2, oldR2);\n                }\n            }\n        }\n    }\n    \n    string out;\n    for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) out += char('0'+bestRot[i][j]);\n    cout << out << endl;\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nmt19937 rng(98765);\n\nint computeTreeScore(vector<vector<int>>& b) {\n    int n = N;\n    vector<int> par(n*n), sz(n*n, 1);\n    vector<bool> bad(n*n, false);\n    iota(par.begin(), par.end(), 0);\n    function<int(int)> find = [&](int x){ while(par[x]!=x){par[x]=par[par[x]];x=par[x];} return x;};\n    auto unite = [&](int a, int b){\n        int ra=find(a), rb=find(b);\n        if(ra==rb){ bad[ra]=true; return;}\n        bool nb = bad[ra]||bad[rb];\n        if(sz[ra]<sz[rb])swap(ra,rb);\n        par[rb]=ra; sz[ra]+=sz[rb]; bad[ra]=nb;\n    };\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        if(b[i][j]==0) continue;\n        if(j+1<n && b[i][j+1]!=0 && (b[i][j]&4) && (b[i][j+1]&1)) unite(i*n+j, i*n+j+1);\n        if(i+1<n && b[i+1][j]!=0 && (b[i][j]&8) && (b[i+1][j]&2)) unite(i*n+j, (i+1)*n+j);\n    }\n    int best=0;\n    for(int i=0;i<n*n;i++){\n        if(b[i/n][i%n]==0) continue;\n        if(find(i)==i && !bad[i]) best=max(best,sz[i]);\n    }\n    return best;\n}\n\nint computeTargetScore(vector<vector<int>>& b) {\n    int n = N;\n    int penalty = 0;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        int v = b[i][j];\n        if(v==0) continue;\n        if((v&1) && j==0) penalty++;\n        if((v&2) && i==0) penalty++;\n        if((v&4) && j==n-1) penalty++;\n        if((v&8) && i==n-1) penalty++;\n    }\n    int s = computeTreeScore(b);\n    return s * 100 - penalty;\n}\n\nint main(){\n    cin>>N>>T;\n    vector<string> initial(N);\n    for(auto&s:initial) cin>>s;\n    \n    vector<vector<int>> board(N, vector<int>(N));\n    int er=0, ec=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        char c = initial[i][j];\n        int v = (c>='0'&&c<='9')?c-'0':c-'a'+10;\n        board[i][j]=v;\n        if(v==0){er=i;ec=j;}\n    }\n    \n    auto startT = chrono::steady_clock::now();\n    double totalTime = 2.7;\n    \n    auto target = board;\n    swap(target[er][ec], target[N-1][N-1]);\n    int curScore = computeTargetScore(target);\n    int bestTargetScore = curScore;\n    auto bestTarget = target;\n    \n    double saTime = 1.2;\n    int iter=0;\n    double temp0=300.0, temp1=1.0;\n    int goal = (N*N-1)*100;\n    \n    while(true){\n        if((iter&1023)==0){\n            double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n            if(el>saTime) break;\n            if(bestTargetScore >= goal) break;\n        }\n        iter++;\n        int i1,j1,i2,j2;\n        do { i1=rng()%N; j1=rng()%N; } while(i1==N-1&&j1==N-1);\n        do { i2=rng()%N; j2=rng()%N; } while((i2==N-1&&j2==N-1) || (i1==i2&&j1==j2));\n        if(target[i1][j1]==target[i2][j2]) continue;\n        swap(target[i1][j1], target[i2][j2]);\n        int ns = computeTargetScore(target);\n        double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n        double tt = temp0 * pow(temp1/temp0, el/saTime);\n        if(ns>=curScore || (double)rng()/(double)rng.max() < exp((ns-curScore)/tt)){\n            curScore=ns;\n            if(ns>bestTargetScore){bestTargetScore=ns; bestTarget=target;}\n        } else {\n            swap(target[i1][j1], target[i2][j2]);\n        }\n    }\n    target = bestTarget;\n    \n    auto solveFromTarget = [&](vector<vector<int>> tgt) -> string {\n        vector<vector<int>> B = board;\n        int br=er, bc=ec;\n        string moves;\n        vector<vector<bool>> locked(N, vector<bool>(N, false));\n        bool solveFailed = false;\n        \n        auto posOk = [&](int r, int c){ return r>=0&&r<N&&c>=0&&c<N; };\n        \n        auto moveBlankTo = [&](int tr, int tc, int avoidR, int avoidC)->bool{\n            if(br==tr&&bc==tc) return true;\n            if(!posOk(tr,tc)) return false;\n            if(locked[tr][tc]) return false;\n            if(tr==avoidR&&tc==avoidC) return false;\n            vector<vector<int>> dist(N, vector<int>(N,-1));\n            vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N,{-1,-1}));\n            queue<pair<int,int>> q;\n            dist[br][bc]=0; q.push({br,bc});\n            while(!q.empty()){\n                auto [r,c]=q.front(); q.pop();\n                int dr[]={-1,1,0,0}, dc[]={0,0,-1,1};\n                for(int d=0;d<4;d++){\n                    int nr=r+dr[d], nc=c+dc[d];\n                    if(!posOk(nr,nc)) continue;\n                    if(locked[nr][nc]) continue;\n                    if(nr==avoidR&&nc==avoidC) continue;\n                    if(dist[nr][nc]!=-1) continue;\n                    dist[nr][nc]=dist[r][c]+1;\n                    par[nr][nc]={r,c};\n                    q.push({nr,nc});\n                }\n            }\n            if(dist[tr][tc]==-1) return false;\n            vector<pair<int,int>> path;\n            int r=tr,c=tc;\n            while(!(r==br&&c==bc)){\n                path.push_back({r,c});\n                auto [pr,pc]=par[r][c]; r=pr; c=pc;\n            }\n            reverse(path.begin(), path.end());\n            for(auto [nr,nc]:path){\n                char mv;\n                if(nr==br-1&&nc==bc) mv='U';\n                else if(nr==br+1&&nc==bc) mv='D';\n                else if(nc==bc-1&&nr==br) mv='L';\n                else mv='R';\n                moves.push_back(mv);\n                swap(B[br][bc], B[nr][nc]);\n                br=nr; bc=nc;\n            }\n            return true;\n        };\n        \n        auto findTile = [&](int type, int nearR, int nearC)->pair<int,int>{\n            int bestR=-1,bestC=-1, bestD=INT_MAX;\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                if(locked[i][j]) continue;\n                if(B[i][j]==type){\n                    int d=abs(i-nearR)+abs(j-nearC);\n                    if(d<bestD){bestD=d; bestR=i; bestC=j;}\n                }\n            }\n            return {bestR,bestC};\n        };\n        \n        auto moveTileTo = [&](int sr, int sc, int tr, int tc)->pair<bool,pair<int,int>>{\n            int safety = 0;\n            while(sr!=tr || sc!=tc){\n                if(++safety > 4*N*N) return {false,{sr,sc}};\n                vector<pair<int,int>> candidates;\n                if(sr!=tr){\n                    if(sr<tr) candidates.push_back({sr+1, sc}); else candidates.push_back({sr-1, sc});\n                }\n                if(sc!=tc){\n                    if(sc<tc) candidates.push_back({sr, sc+1}); else candidates.push_back({sr, sc-1});\n                }\n                bool moved=false;\n                int newNr=-1, newNc=-1;\n                for(auto [cnr, cnc] : candidates){\n                    if(!posOk(cnr,cnc)) continue;\n                    if(locked[cnr][cnc]) continue;\n                    int saveBr=br, saveBc=bc;\n                    size_t saveMl = moves.size();\n                    auto saveB = B;\n                    if(moveBlankTo(cnr,cnc,sr,sc)){\n                        newNr=cnr; newNc=cnc; moved=true; break;\n                    }\n                    br=saveBr; bc=saveBc; moves.resize(saveMl); B=saveB;\n                }\n                if(!moved) return {false,{sr,sc}};\n                char mv;\n                if(sr==br-1&&sc==bc) mv='U';\n                else if(sr==br+1&&sc==bc) mv='D';\n                else if(sc==bc-1&&sr==br) mv='L';\n                else if(sc==bc+1&&sr==br) mv='R';\n                else return {false,{sr,sc}};\n                moves.push_back(mv);\n                swap(B[br][bc], B[sr][sc]);\n                int obr=br, obc=bc;\n                br=sr; bc=sc;\n                sr=obr; sc=obc;\n            }\n            return {true,{sr,sc}};\n        };\n        \n        for(int r=0; r<N-2 && !solveFailed; r++){\n            for(int c=0; c<N-2; c++){\n                int type = tgt[r][c];\n                auto [sr,sc] = findTile(type, r, c);\n                if(sr==-1){solveFailed=true; break;}\n                if(!(sr==r&&sc==c)){\n                    auto res = moveTileTo(sr,sc,r,c);\n                    if(!res.first){solveFailed=true; break;}\n                }\n                locked[r][c]=true;\n            }\n            if(solveFailed) break;\n            \n            int typeA = tgt[r][N-2];\n            int typeB = tgt[r][N-1];\n            \n            if(B[r][N-2]==typeA && B[r][N-1]==typeB){\n                locked[r][N-2]=true; locked[r][N-1]=true;\n                continue;\n            }\n            \n            {\n                auto [sr,sc] = findTile(typeA, r, N-1);\n                if(sr==-1){solveFailed=true; break;}\n                if(!(sr==r && sc==N-1)){\n                    if(sr==r && sc==N-2){\n                        auto res = moveTileTo(sr,sc, r+1, N-2);\n                        if(!res.first){solveFailed=true; break;}\n                        auto p = findTile(typeA, r, N-1);\n                        sr=p.first; sc=p.second;\n                        if(sr==-1){solveFailed=true; break;}\n                    }\n                    auto res = moveTileTo(sr, sc, r, N-1);\n                    if(!res.first){solveFailed=true; break;}\n                }\n            }\n            if(solveFailed) break;\n            locked[r][N-1]=true;\n            \n            {\n                auto [sr,sc] = findTile(typeB, r+1, N-1);\n                if(sr==-1){solveFailed=true; break;}\n                if(!(sr==r+1 && sc==N-1)){\n                    auto res = moveTileTo(sr, sc, r+1, N-1);\n                    if(!res.first){solveFailed=true; break;}\n                }\n            }\n            if(solveFailed) break;\n            locked[r+1][N-1]=true;\n            \n            locked[r][N-1]=false; locked[r+1][N-1]=false;\n            \n            if(!moveBlankTo(r, N-2, -1, -1)){solveFailed=true; break;}\n            moves.push_back('R');\n            swap(B[br][bc], B[r][N-1]); br=r; bc=N-1;\n            moves.push_back('D');\n            swap(B[br][bc], B[r+1][N-1]); br=r+1; bc=N-1;\n            \n            locked[r][N-2]=true; locked[r][N-1]=true;\n        }\n        \n        for(int c=0; c<N-2 && !solveFailed; c++){\n            int typeA = tgt[N-2][c];\n            int typeB = tgt[N-1][c];\n            \n            if(B[N-2][c]==typeA && B[N-1][c]==typeB){\n                locked[N-2][c]=true; locked[N-1][c]=true;\n                continue;\n            }\n            \n            {\n                auto [sr,sc] = findTile(typeA, N-1, c);\n                if(sr==-1){solveFailed=true; break;}\n                if(!(sr==N-1 && sc==c)){\n                    if(sr==N-2 && sc==c){\n                        auto res = moveTileTo(sr,sc, N-2, c+1);\n                        if(!res.first){solveFailed=true; break;}\n                        auto p = findTile(typeA, N-1, c);\n                        sr=p.first; sc=p.second;\n                        if(sr==-1){solveFailed=true; break;}\n                    }\n                    auto res = moveTileTo(sr, sc, N-1, c);\n                    if(!res.first){solveFailed=true; break;}\n                }\n            }\n            if(solveFailed) break;\n            locked[N-1][c]=true;\n            \n            {\n                auto [sr,sc] = findTile(typeB, N-1, c+1);\n                if(sr==-1){solveFailed=true; break;}\n                if(!(sr==N-1 && sc==c+1)){\n                    auto res = moveTileTo(sr, sc, N-1, c+1);\n                    if(!res.first){solveFailed=true; break;}\n                }\n            }\n            if(solveFailed) break;\n            locked[N-1][c+1]=true;\n            \n            locked[N-1][c]=false; locked[N-1][c+1]=false;\n            \n            if(!moveBlankTo(N-2, c, -1, -1)){solveFailed=true; break;}\n            moves.push_back('D'); swap(B[br][bc], B[N-1][c]); br=N-1; bc=c;\n            moves.push_back('R'); swap(B[br][bc], B[N-1][c+1]); br=N-1; bc=c+1;\n            locked[N-2][c]=true; locked[N-1][c]=true;\n        }\n        \n        if(!solveFailed){\n            for(int attempt=0; attempt<8; attempt++){\n                bool match = (B[N-2][N-2]==tgt[N-2][N-2]) && (B[N-2][N-1]==tgt[N-2][N-1]) && (B[N-1][N-2]==tgt[N-1][N-2]);\n                if(match && br==N-1 && bc==N-1) break;\n                if(br==N-1&&bc==N-1){ moves.push_back('U'); swap(B[br][bc],B[N-2][N-1]); br=N-2;bc=N-1;}\n                else if(br==N-2&&bc==N-1){ moves.push_back('L'); swap(B[br][bc],B[N-2][N-2]); br=N-2;bc=N-2;}\n                else if(br==N-2&&bc==N-2){ moves.push_back('D'); swap(B[br][bc],B[N-1][N-2]); br=N-1;bc=N-2;}\n                else if(br==N-1&&bc==N-2){ moves.push_back('R'); swap(B[br][bc],B[N-1][N-1]); br=N-1;bc=N-1;}\n            }\n        }\n        \n        return moves;\n    };\n    \n    auto processMoves = [&](const string& mv) -> pair<string, int> {\n        vector<vector<int>> BB = board;\n        int bbr=er, bbc=ec;\n        int curS = computeTreeScore(BB);\n        int bestS = curS;\n        int bestLen = 0;\n        int fullLen = mv.size();\n        int lim = min(fullLen, T);\n        for(int i=0;i<lim;i++){\n            char m = mv[i];\n            int nr=bbr, nc=bbc;\n            if(m=='U') nr--;\n            else if(m=='D') nr++;\n            else if(m=='L') nc--;\n            else nc++;\n            if(nr<0||nr>=N||nc<0||nc>=N) break;\n            swap(BB[bbr][bbc], BB[nr][nc]);\n            bbr=nr; bbc=nc;\n            curS = computeTreeScore(BB);\n            if(curS > bestS){ bestS=curS; bestLen=i+1; }\n            if(curS == N*N-1){\n                return {mv.substr(0, i+1), curS};\n            }\n        }\n        return {mv.substr(0, bestLen), bestS};\n    };\n    \n    auto evalResult = [&](const string& mv, int s) -> double {\n        if(s == N*N-1){\n            return 500000.0 * (2.0 - (double)mv.size()/T);\n        }\n        return 500000.0 * s / (N*N-1);\n    };\n    \n    string bestMoves = \"\";\n    int bestFinalScore = computeTreeScore(board);\n    \n    auto tryTarget = [&](vector<vector<int>>& tgt){\n        string mv = solveFromTarget(tgt);\n        auto [finalMv, finalS] = processMoves(mv);\n        double curEval = evalResult(finalMv, finalS);\n        double bestEval = evalResult(bestMoves, bestFinalScore);\n        if(curEval > bestEval){\n            bestMoves = finalMv;\n            bestFinalScore = finalS;\n        }\n    };\n    \n    tryTarget(target);\n    \n    // Continue SA to find more targets\n    auto curTarget = bestTarget;\n    int curTgtScore = bestTargetScore;\n    \n    while(true){\n        double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n        if(el > totalTime - 0.15) break;\n        \n        // Some SA iterations\n        for(int k=0;k<3000;k++){\n            int i1,j1,i2,j2;\n            do { i1=rng()%N; j1=rng()%N; } while(i1==N-1&&j1==N-1);\n            do { i2=rng()%N; j2=rng()%N; } while((i2==N-1&&j2==N-1) || (i1==i2&&j1==j2));\n            if(curTarget[i1][j1]==curTarget[i2][j2]) continue;\n            swap(curTarget[i1][j1], curTarget[i2][j2]);\n            int ns = computeTargetScore(curTarget);\n            double tt = 5.0;\n            if(ns>=curTgtScore || (double)rng()/(double)rng.max() < exp((ns-curTgtScore)/tt)){\n                curTgtScore=ns;\n            } else {\n                swap(curTarget[i1][j1], curTarget[i2][j2]);\n            }\n        }\n        \n        if(curTgtScore >= goal - 5){\n            tryTarget(curTarget);\n        }\n    }\n    \n    cout << bestMoves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, K;\nint a[11];\nvector<int> sx_arr, sy_arr;\n\nint cnt[105][105];\nint bcnt[12];\nlong long curScoreVal;\nint nvG, nhG;\nvector<double> vcG, hcG;\nvector<int> sortedByX, sortedByY;\n\nvoid fullRecompute() {\n    nvG = vcG.size(); nhG = hcG.size();\n    for (int i = 0; i <= nvG; i++) for (int j = 0; j <= nhG; j++) cnt[i][j] = 0;\n    for (int i = 0; i < N; i++) {\n        int xi = upper_bound(vcG.begin(), vcG.end(), (double)sx_arr[i]) - vcG.begin();\n        int yi = upper_bound(hcG.begin(), hcG.end(), (double)sy_arr[i]) - hcG.begin();\n        cnt[xi][yi]++;\n    }\n    for (int d = 0; d < 12; d++) bcnt[d] = 0;\n    for (int i = 0; i <= nvG; i++)\n        for (int j = 0; j <= nhG; j++) {\n            int c = cnt[i][j];\n            if (c >= 1 && c <= 10) bcnt[c]++;\n        }\n    curScoreVal = 0;\n    for (int d = 1; d <= 10; d++) curScoreVal += min(a[d], bcnt[d]);\n}\n\ninline void updateCell(int col, int row, int delta) {\n    int oldv = cnt[col][row];\n    int newv = oldv + delta;\n    cnt[col][row] = newv;\n    if (oldv >= 1 && oldv <= 10) {\n        int before = min(a[oldv], bcnt[oldv]);\n        bcnt[oldv]--;\n        int after = min(a[oldv], bcnt[oldv]);\n        curScoreVal += after - before;\n    }\n    if (newv >= 1 && newv <= 10) {\n        int before = min(a[newv], bcnt[newv]);\n        bcnt[newv]++;\n        int after = min(a[newv], bcnt[newv]);\n        curScoreVal += after - before;\n    }\n}\n\nvoid moveVCut(int ci, double newVal) {\n    double oldVal = vcG[ci];\n    if (newVal == oldVal) return;\n    double lo = min(oldVal, newVal), hi = max(oldVal, newVal);\n    int l, r;\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sx_arr[sortedByX[m]] > lo) b2 = m; else a2 = m+1; }\n        l = a2;\n    }\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sx_arr[sortedByX[m]] >= hi) b2 = m; else a2 = m+1; }\n        r = a2;\n    }\n    int fromCol, toCol;\n    if (newVal > oldVal) { fromCol = ci + 1; toCol = ci; }\n    else { fromCol = ci; toCol = ci + 1; }\n    vcG[ci] = newVal;\n    for (int k = l; k < r; k++) {\n        int si = sortedByX[k];\n        int j = upper_bound(hcG.begin(), hcG.end(), (double)sy_arr[si]) - hcG.begin();\n        updateCell(fromCol, j, -1);\n        updateCell(toCol, j, +1);\n    }\n}\n\nvoid moveHCut(int ci, double newVal) {\n    double oldVal = hcG[ci];\n    if (newVal == oldVal) return;\n    double lo = min(oldVal, newVal), hi = max(oldVal, newVal);\n    int l, r;\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sy_arr[sortedByY[m]] > lo) b2 = m; else a2 = m+1; }\n        l = a2;\n    }\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sy_arr[sortedByY[m]] >= hi) b2 = m; else a2 = m+1; }\n        r = a2;\n    }\n    int fromRow, toRow;\n    if (newVal > oldVal) { fromRow = ci + 1; toRow = ci; }\n    else { fromRow = ci; toRow = ci + 1; }\n    hcG[ci] = newVal;\n    for (int k = l; k < r; k++) {\n        int si = sortedByY[k];\n        int j = upper_bound(vcG.begin(), vcG.end(), (double)sx_arr[si]) - vcG.begin();\n        updateCell(j, fromRow, -1);\n        updateCell(j, toRow, +1);\n    }\n}\n\nint main() {\n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    sx_arr.resize(N); sy_arr.resize(N);\n    for (int i = 0; i < N; i++) cin >> sx_arr[i] >> sy_arr[i];\n    \n    sortedByX.resize(N); sortedByY.resize(N);\n    iota(sortedByX.begin(), sortedByX.end(), 0);\n    iota(sortedByY.begin(), sortedByY.end(), 0);\n    sort(sortedByX.begin(), sortedByX.end(), [&](int x, int y){ return sx_arr[x] < sx_arr[y]; });\n    sort(sortedByY.begin(), sortedByY.end(), [&](int x, int y){ return sy_arr[x] < sy_arr[y]; });\n    \n    vector<int> xs = sx_arr, ys = sy_arr;\n    sort(xs.begin(), xs.end()); xs.erase(unique(xs.begin(), xs.end()), xs.end());\n    sort(ys.begin(), ys.end()); ys.erase(unique(ys.begin(), ys.end()), ys.end());\n    \n    vector<double> cand_x, cand_y;\n    for (int i = 0; i + 1 < (int)xs.size(); i++) cand_x.push_back((xs[i] + xs[i+1]) / 2.0);\n    for (int i = 0; i + 1 < (int)ys.size(); i++) cand_y.push_back((ys[i] + ys[i+1]) / 2.0);\n    \n    mt19937 rng(42);\n    \n    auto pickEvenly = [&](vector<double>& cand, int k) {\n        vector<double> res;\n        if ((int)cand.size() <= k) res = cand;\n        else {\n            for (int i = 0; i < k; i++) {\n                int idx = (int)((long long)(i+1) * cand.size() / (k+1));\n                if (idx >= (int)cand.size()) idx = cand.size()-1;\n                res.push_back(cand[idx]);\n            }\n        }\n        sort(res.begin(), res.end());\n        res.erase(unique(res.begin(), res.end()), res.end());\n        return res;\n    };\n    \n    auto startTime = chrono::steady_clock::now();\n    double totalTime = 2.7;\n    \n    long long bestScore = -1;\n    vector<double> bestVC, bestHC;\n    \n    vector<pair<int,int>> splits = {{50,50},{45,55},{55,45},{40,60},{60,40}};\n    for (auto& sp : splits) {\n        int kv = sp.first, kh = sp.second;\n        vcG = pickEvenly(cand_x, kv);\n        hcG = pickEvenly(cand_y, kh);\n        fullRecompute();\n        if (curScoreVal > bestScore) {\n            bestScore = curScoreVal;\n            bestVC = vcG; bestHC = hcG;\n        }\n    }\n    \n    vcG = bestVC; hcG = bestHC;\n    fullRecompute();\n    \n    double T0 = 2.5, T1 = 0.05;\n    long long iters = 0;\n    double cachedProgress = 0.0;\n    \n    while (true) {\n        iters++;\n        if ((iters & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - startTime).count();\n            if (elapsed > totalTime) break;\n            cachedProgress = elapsed / totalTime;\n        }\n        \n        double T = T0 * pow(T1/T0, cachedProgress);\n        \n        int op = rng() % 2;\n        \n        if (op == 0) {\n            if (vcG.empty() || cand_x.empty()) continue;\n            int i = rng() % vcG.size();\n            double lo_b = (i == 0) ? -1e18 : vcG[i-1];\n            double hi_b = (i == (int)vcG.size()-1) ? 1e18 : vcG[i+1];\n            auto itL = upper_bound(cand_x.begin(), cand_x.end(), lo_b);\n            auto itR = lower_bound(cand_x.begin(), cand_x.end(), hi_b);\n            if (itL >= itR) continue;\n            int numCand = itR - itL;\n            double newVal = *(itL + rng() % numCand);\n            if (newVal == vcG[i]) continue;\n            \n            long long prevScore = curScoreVal;\n            double prevVal = vcG[i];\n            moveVCut(i, newVal);\n            long long delta = curScoreVal - prevScore;\n            if (delta >= 0 || (double)rng()/(double)rng.max() < exp((double)delta / T)) {\n                if (curScoreVal > bestScore) {\n                    bestScore = curScoreVal;\n                    bestVC = vcG; bestHC = hcG;\n                }\n            } else {\n                moveVCut(i, prevVal);\n            }\n        } else {\n            if (hcG.empty() || cand_y.empty()) continue;\n            int i = rng() % hcG.size();\n            double lo_b = (i == 0) ? -1e18 : hcG[i-1];\n            double hi_b = (i == (int)hcG.size()-1) ? 1e18 : hcG[i+1];\n            auto itL = upper_bound(cand_y.begin(), cand_y.end(), lo_b);\n            auto itR = lower_bound(cand_y.begin(), cand_y.end(), hi_b);\n            if (itL >= itR) continue;\n            int numCand = itR - itL;\n            double newVal = *(itL + rng() % numCand);\n            if (newVal == hcG[i]) continue;\n            \n            long long prevScore = curScoreVal;\n            double prevVal = hcG[i];\n            moveHCut(i, newVal);\n            long long delta = curScoreVal - prevScore;\n            if (delta >= 0 || (double)rng()/(double)rng.max() < exp((double)delta / T)) {\n                if (curScoreVal > bestScore) {\n                    bestScore = curScoreVal;\n                    bestVC = vcG; bestHC = hcG;\n                }\n            } else {\n                moveHCut(i, prevVal);\n            }\n        }\n    }\n    \n    vcG = bestVC; hcG = bestHC;\n    \n    cout << vcG.size() + hcG.size() << \"\\n\";\n    for (double c : vcG) {\n        long long p = (long long)floor(c);\n        cout << p << \" \" << -1000000000LL << \" \" << p+1 << \" \" << 1000000000LL << \"\\n\";\n    }\n    for (double c : hcG) {\n        long long p = (long long)floor(c);\n        cout << -1000000000LL << \" \" << p << \" \" << 1000000000LL << \" \" << p+1 << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint cx;\nvector<vector<bool>> has_dot;\nint dx8[8] = {1,1,0,-1,-1,-1,0,1};\nint dy8[8] = {0,1,1,1,0,-1,-1,-1};\nvector<vector<array<bool,8>>> edge_used;\n\nbool inside(int x, int y) { return 0<=x && x<N && 0<=y && y<N; }\nint weight(int x, int y) { return (x-cx)*(x-cx) + (y-cx)*(y-cx) + 1; }\n\nint nearestDot(int x, int y, int d) {\n    int nx = x + dx8[d], ny = y + dy8[d];\n    int steps = 1;\n    while (inside(nx, ny)) {\n        if (has_dot[nx][ny]) return steps;\n        nx += dx8[d]; ny += dy8[d]; steps++;\n    }\n    return -1;\n}\n\nbool checkSeg(int x, int y, int d, int len) {\n    int cxx = x, cyy = y;\n    for (int i = 0; i < len; i++) {\n        if (edge_used[cxx][cyy][d]) return false;\n        cxx += dx8[d]; cyy += dy8[d];\n        if (i < len-1 && has_dot[cxx][cyy]) return false;\n    }\n    return true;\n}\n\nvoid markSeg(int x, int y, int d, int len) {\n    int cxx = x, cyy = y;\n    for (int i = 0; i < len; i++) {\n        edge_used[cxx][cyy][d] = true;\n        int nx = cxx + dx8[d], ny = cyy + dy8[d];\n        edge_used[nx][ny][d^4] = true;\n        cxx = nx; cyy = ny;\n    }\n}\n\nstruct Move {\n    int p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y;\n    int d1, d2, len1, len2;\n};\n\nbool validateMove(const Move& m) {\n    if (has_dot[m.p1x][m.p1y]) return false;\n    if (!has_dot[m.p2x][m.p2y]) return false;\n    if (!has_dot[m.p3x][m.p3y]) return false;\n    if (!has_dot[m.p4x][m.p4y]) return false;\n    if (!checkSeg(m.p1x, m.p1y, m.d1, m.len1)) return false;\n    if (!checkSeg(m.p1x, m.p1y, m.d2, m.len2)) return false;\n    if (!checkSeg(m.p2x, m.p2y, m.d2, m.len2)) return false;\n    if (!checkSeg(m.p4x, m.p4y, m.d1, m.len1)) return false;\n    return true;\n}\n\nvoid applyMove(const Move& m) {\n    has_dot[m.p1x][m.p1y] = true;\n    markSeg(m.p1x, m.p1y, m.d1, m.len1);\n    markSeg(m.p1x, m.p1y, m.d2, m.len2);\n    markSeg(m.p2x, m.p2y, m.d2, m.len2);\n    markSeg(m.p4x, m.p4y, m.d1, m.len1);\n}\n\nvoid addCandsWithDot(int qx, int qy, vector<Move>& out) {\n    for (int d1 = 0; d1 < 8; d1++) {\n        int d2 = (d1+2)%8;\n        int opp1 = (d1+4)%8;\n        int l1max;\n        int nd = nearestDot(qx, qy, opp1);\n        if (nd < 0) {\n            l1max = 0;\n            int tx = qx + dx8[opp1], ty = qy + dy8[opp1];\n            while (inside(tx, ty)) { l1max++; tx += dx8[opp1]; ty += dy8[opp1]; }\n        } else l1max = nd - 1;\n        for (int l1 = 1; l1 <= l1max; l1++) {\n            int p1x = qx + dx8[opp1]*l1, p1y = qy + dy8[opp1]*l1;\n            int l2 = nearestDot(p1x, p1y, d2);\n            if (l2 < 0) continue;\n            int p4x = p1x + dx8[d2]*l2, p4y = p1y + dy8[d2]*l2;\n            int p3x = qx + dx8[d2]*l2, p3y = qy + dy8[d2]*l2;\n            if (!inside(p3x, p3y) || !has_dot[p3x][p3y]) continue;\n            Move m{p1x,p1y,qx,qy,p3x,p3y,p4x,p4y,d1,d2,l1,l2};\n            if (validateMove(m)) out.push_back(m);\n        }\n    }\n    for (int d1 = 0; d1 < 8; d1++) {\n        int d2 = (d1+2)%8;\n        int opp2 = (d2+4)%8;\n        int l2max;\n        int nd = nearestDot(qx, qy, opp2);\n        if (nd < 0) {\n            l2max = 0;\n            int tx = qx + dx8[opp2], ty = qy + dy8[opp2];\n            while (inside(tx, ty)) { l2max++; tx += dx8[opp2]; ty += dy8[opp2]; }\n        } else l2max = nd - 1;\n        for (int l2 = 1; l2 <= l2max; l2++) {\n            int p1x = qx + dx8[opp2]*l2, p1y = qy + dy8[opp2]*l2;\n            int l1 = nearestDot(p1x, p1y, d1);\n            if (l1 < 0) continue;\n            int p2x = p1x + dx8[d1]*l1, p2y = p1y + dy8[d1]*l1;\n            int p3x = qx + dx8[d1]*l1, p3y = qy + dy8[d1]*l1;\n            if (!inside(p3x, p3y) || !has_dot[p3x][p3y]) continue;\n            Move m{p1x,p1y,p2x,p2y,p3x,p3y,qx,qy,d1,d2,l1,l2};\n            if (validateMove(m)) out.push_back(m);\n        }\n    }\n    for (int d1 = 0; d1 < 8; d1++) {\n        int d2 = (d1+2)%8;\n        int opp1 = (d1+4)%8;\n        int opp2 = (d2+4)%8;\n        int l2 = nearestDot(qx, qy, opp2);\n        if (l2 < 0) continue;\n        int p2x = qx + dx8[opp2]*l2, p2y = qy + dy8[opp2]*l2;\n        int l1 = nearestDot(qx, qy, opp1);\n        if (l1 < 0) continue;\n        int p4x = qx + dx8[opp1]*l1, p4y = qy + dy8[opp1]*l1;\n        int p1x = p2x + dx8[opp1]*l1, p1y = p2y + dy8[opp1]*l1;\n        if (!inside(p1x, p1y) || has_dot[p1x][p1y]) continue;\n        Move m{p1x,p1y,p2x,p2y,qx,qy,p4x,p4y,d1,d2,l1,l2};\n        if (validateMove(m)) out.push_back(m);\n    }\n}\n\nint main() {\n    cin >> N >> M;\n    cx = (N-1)/2;\n    \n    auto startTime = chrono::steady_clock::now();\n    auto timeLeft = [&](){ return 4.7 - chrono::duration<double>(chrono::steady_clock::now() - startTime).count(); };\n    \n    vector<pair<int,int>> initial(M);\n    for (auto& p : initial) { cin >> p.first >> p.second; }\n    \n    auto resetState = [&]() {\n        has_dot.assign(N, vector<bool>(N, false));\n        edge_used.assign(N, vector<array<bool,8>>(N));\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) for (int k = 0; k < 8; k++) edge_used[i][j][k] = false;\n        for (auto& p : initial) has_dot[p.first][p.second] = true;\n    };\n    \n    vector<Move> bestMoves;\n    long long bestScore = -1;\n    \n    mt19937 rng(12345);\n    int iter = 0;\n    \n    while (timeLeft() > 0.3) {\n        resetState();\n        vector<Move> moves;\n        \n        vector<Move> cands;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (has_dot[x][y]) continue;\n                for (int d1 = 0; d1 < 8; d1++) {\n                    int d2 = (d1+2)%8;\n                    int l1 = nearestDot(x, y, d1);\n                    if (l1 < 0) continue;\n                    int l2 = nearestDot(x, y, d2);\n                    if (l2 < 0) continue;\n                    int p2x = x + dx8[d1]*l1, p2y = y + dy8[d1]*l1;\n                    int p4x = x + dx8[d2]*l2, p4y = y + dy8[d2]*l2;\n                    int p3x = p2x + dx8[d2]*l2, p3y = p2y + dy8[d2]*l2;\n                    if (!inside(p3x, p3y) || !has_dot[p3x][p3y]) continue;\n                    Move m{x,y,p2x,p2y,p3x,p3y,p4x,p4y,d1,d2,l1,l2};\n                    if (validateMove(m)) cands.push_back(m);\n                }\n            }\n        }\n        \n        int noiseLevel = iter;\n        \n        while (timeLeft() > 0.2) {\n            long long bestKey = LLONG_MIN;\n            int bestIdx = -1;\n            \n            int sz = cands.size();\n            for (int i = 0; i < sz; i++) {\n                if (!validateMove(cands[i])) continue;\n                long long w = weight(cands[i].p1x, cands[i].p1y);\n                long long size = cands[i].len1 + cands[i].len2;\n                long long key = w * 100000LL - size * 100LL;\n                if (noiseLevel > 0) {\n                    key += (long long)(rng() % (noiseLevel * 300 + 100));\n                }\n                if (key > bestKey) {\n                    bestKey = key;\n                    bestIdx = i;\n                }\n            }\n            \n            if (bestIdx < 0) break;\n            Move m = cands[bestIdx];\n            applyMove(m);\n            moves.push_back(m);\n            \n            cands[bestIdx] = cands.back();\n            cands.pop_back();\n            \n            addCandsWithDot(m.p1x, m.p1y, cands);\n            \n            if ((int)cands.size() > 30000) {\n                vector<Move> pruned;\n                pruned.reserve(cands.size()/2);\n                for (auto& c : cands) if (validateMove(c)) pruned.push_back(c);\n                cands = std::move(pruned);\n            }\n        }\n        \n        long long sumW = 0;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) {\n            if (has_dot[x][y]) sumW += weight(x,y);\n        }\n        \n        if (sumW > bestScore) {\n            bestScore = sumW;\n            bestMoves = moves;\n        }\n        iter++;\n    }\n    \n    cout << bestMoves.size() << \"\\n\";\n    for (auto& m : bestMoves) {\n        cout << m.p1x << \" \" << m.p1y << \" \" << m.p2x << \" \" << m.p2y << \" \"\n             << m.p3x << \" \" << m.p3y << \" \" << m.p4x << \" \" << m.p4y << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef array<int,100> Board;\n\ninline void tilt(Board& b, int dir) {\n    if (dir == 0) {\n        for (int c = 0; c < 10; c++) {\n            int w = 0;\n            for (int r = 0; r < 10; r++) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w++;\n                }\n            }\n        }\n    } else if (dir == 1) {\n        for (int c = 0; c < 10; c++) {\n            int w = 9;\n            for (int r = 9; r >= 0; r--) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w--;\n                }\n            }\n        }\n    } else if (dir == 2) {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 0;\n            for (int c = 0; c < 10; c++) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w++;\n                }\n            }\n        }\n    } else {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w--;\n                }\n            }\n        }\n    }\n}\n\nint placeCandy(Board& b, int p, int flavor) {\n    int cnt = 0;\n    for (int i = 0; i < 100; i++) {\n        if (!b[i]) {\n            cnt++;\n            if (cnt == p) {\n                b[i] = flavor;\n                return i;\n            }\n        }\n    }\n    return -1;\n}\n\nint computeScore(const Board& b) {\n    int vis[100] = {0};\n    int sum = 0;\n    int stk[100];\n    for (int i = 0; i < 100; i++) {\n        if (!vis[i] && b[i]) {\n            int flavor = b[i];\n            int sz = 0;\n            int top = 0;\n            stk[top++] = i;\n            vis[i] = 1;\n            while (top > 0) {\n                int x = stk[--top];\n                sz++;\n                int r = x/10, c = x%10;\n                if (r>0) { int ni = x-10; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (r<9) { int ni = x+10; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (c>0) { int ni = x-1; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (c<9) { int ni = x+1; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n            }\n            sum += sz*sz;\n        }\n    }\n    return sum;\n}\n\nmt19937 rng(12345);\n\nint main() {\n    auto startTime = chrono::steady_clock::now();\n    \n    vector<int> f(100);\n    for (int i = 0; i < 100; i++) cin >> f[i];\n    \n    Board board;\n    board.fill(0);\n    \n    double totalBudget = 1.85;\n    \n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        placeCandy(board, p, f[t]);\n        \n        if (t == 99) break;\n        \n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        double remaining = totalBudget - elapsed;\n        int stepsLeft = 100 - t;\n        double perStep = remaining / stepsLeft;\n        if (perStep < 0.001) perStep = 0.001;\n        auto stepStart = chrono::steady_clock::now();\n        \n        int remainingCandies = 100 - t - 1;\n        \n        long long scoreSum[4] = {0,0,0,0};\n        int trials[4] = {0,0,0,0};\n        \n        int roundIdx = 0;\n        while (true) {\n            if ((roundIdx & 15) == 0) {\n                auto nowS = chrono::steady_clock::now();\n                double el = chrono::duration<double>(nowS - stepStart).count();\n                if (el >= perStep) break;\n            }\n            \n            int dir = roundIdx & 3;\n            roundIdx++;\n            \n            Board b = board;\n            tilt(b, dir);\n            \n            int dp[3];\n            for (int k = 0; k < 3; k++) dp[k] = rng() & 3;\n            \n            for (int k = 0; k < remainingCandies; k++) {\n                int flavor = f[t+1+k];\n                int ec = 0;\n                int epos[100];\n                for (int i = 0; i < 100; i++) if (!b[i]) epos[ec++] = i;\n                int pick = epos[rng() % ec];\n                b[pick] = flavor;\n                tilt(b, dp[flavor-1]);\n            }\n            \n            int sc = computeScore(b);\n            scoreSum[dir] += sc;\n            trials[dir]++;\n        }\n        \n        double bestScore = -1;\n        int bestDir = 0;\n        for (int d = 0; d < 4; d++) {\n            if (trials[d] == 0) continue;\n            double avg = (double)scoreSum[d] / trials[d];\n            if (avg > bestScore) {\n                bestScore = avg;\n                bestDir = d;\n            }\n        }\n        \n        tilt(board, bestDir);\n        cout << \"FBLR\"[bestDir] << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int M; double eps;\n    cin >> M >> eps;\n    \n    int bestN = 100;\n    double bestScore = -1;\n    for(int N=4; N<=100; N++){\n        int E = N*(N-1)/2;\n        double p;\n        if(M==1) p=0;\n        else if(eps < 1e-9){\n            p = (M-1 <= E) ? 0 : 1;\n        } else {\n            if(M-1 > E){ p=1; }\n            else {\n                double spacing = (double)E/(M-1) * (1-2*eps);\n                double sigma = sqrt((double)E*eps*(1-eps));\n                double z = spacing/(2*sigma);\n                p = erfc(z/sqrt(2));\n                if(p>1) p=1;\n            }\n        }\n        double score = pow(0.9, 100*p) / N;\n        if(score > bestScore){ bestScore = score; bestN = N; }\n    }\n    int N = bestN;\n    int E = N*(N-1)/2;\n    \n    vector<int> target(M);\n    if(M==1) target[0]=0;\n    else for(int k=0;k<M;k++) target[k] = (int)round((double)k * E / (M-1));\n    \n    cout << N << \"\\n\";\n    for(int k=0;k<M;k++){\n        string s(E,'0');\n        for(int i=0;i<target[k];i++) s[i]='1';\n        cout << s << \"\\n\";\n    }\n    cout.flush();\n    \n    for(int q=0;q<100;q++){\n        string h; cin >> h;\n        int cnt = count(h.begin(),h.end(),'1');\n        int best=0; double bd=1e18;\n        for(int k=0;k<M;k++){\n            double exp_cnt = target[k]*(1-2*eps) + E*eps;\n            double d = fabs(exp_cnt - cnt);\n            if(d<bd){bd=d; best=k;}\n        }\n        cout << best << \"\\n\";\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint N, M, D, K;\nvector<vector<pair<int,int>>> adj;\nvector<int> W;\nvector<int> Eu, Ev;\n\nvector<int> sources;\nvector<vector<ll>> baseDist;\n\nvector<int> assign_;\nvector<vector<int>> dayEdges;\nint S;\n\nvector<char> removed;\n\nvector<ll> dijkstra(int src) {\n    vector<ll> dist(N, (ll)2e18);\n    priority_queue<pair<ll,int>, vector<pair<ll,int>>, greater<>> pq;\n    dist[src] = 0;\n    pq.push({0, src});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist[u]) continue;\n        for (auto [v, eid] : adj[u]) {\n            if (removed[eid]) continue;\n            ll nd = d + W[eid];\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                pq.push({nd, v});\n            }\n        }\n    }\n    return dist;\n}\n\ndouble dayCost(int k) {\n    for (int e : dayEdges[k]) removed[e] = 1;\n    double total = 0;\n    for (int si = 0; si < S; si++) {\n        auto dist = dijkstra(sources[si]);\n        for (int v = 0; v < N; v++) {\n            ll dv = (dist[v] >= (ll)1e18) ? 1000000000LL : dist[v];\n            total += (double)(dv - baseDist[si][v]);\n        }\n    }\n    for (int e : dayEdges[k]) removed[e] = 0;\n    return total;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> M >> D >> K;\n    adj.assign(N, {});\n    W.resize(M); Eu.resize(M); Ev.resize(M);\n    for (int i = 0; i < M; i++) {\n        int u,v,w; cin >> u >> v >> w; u--; v--;\n        Eu[i]=u; Ev[i]=v; W[i]=w;\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n    }\n    vector<int> X(N), Y(N);\n    for (int i = 0; i < N; i++) cin >> X[i] >> Y[i];\n    \n    removed.assign(M, 0);\n    \n    mt19937 rng(12345);\n    S = min(N, 40);\n    vector<int> perm(N);\n    iota(perm.begin(), perm.end(), 0);\n    shuffle(perm.begin(), perm.end(), rng);\n    sources.assign(perm.begin(), perm.begin()+S);\n    \n    baseDist.resize(S);\n    for (int i = 0; i < S; i++) baseDist[i] = dijkstra(sources[i]);\n    \n    assign_.assign(M, 0);\n    \n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){\n        double xa = (X[Eu[a]]+X[Ev[a]])*0.5, ya=(Y[Eu[a]]+Y[Ev[a]])*0.5;\n        double xb = (X[Eu[b]]+X[Ev[b]])*0.5, yb=(Y[Eu[b]]+Y[Ev[b]])*0.5;\n        return xa+ya < xb+yb;\n    });\n    \n    vector<int> dayCount(D, 0);\n    for (int i = 0; i < M; i++) {\n        int e = order[i];\n        int d = i % D;\n        while (dayCount[d] >= K) d = (d+1) % D;\n        assign_[e] = d;\n        dayCount[d]++;\n    }\n    \n    dayEdges.assign(D, {});\n    for (int i = 0; i < M; i++) dayEdges[assign_[i]].push_back(i);\n    \n    vector<double> costs(D);\n    for (int k = 0; k < D; k++) costs[k] = dayCost(k);\n    \n    auto start = chrono::steady_clock::now();\n    double TIME_LIMIT = 5.3;\n    auto getTime = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now() - start).count();\n    };\n    \n    int iter = 0, accepted = 0;\n    while (getTime() < TIME_LIMIT) {\n        iter++;\n        int op = rng() % 4;\n        if (op == 0) {\n            int e1 = rng() % M;\n            int d1 = assign_[e1];\n            int d2 = rng() % D;\n            if (d1 == d2) continue;\n            if ((int)dayEdges[d2].size() >= K) continue;\n            \n            auto& v1 = dayEdges[d1];\n            auto it1 = find(v1.begin(), v1.end(), e1);\n            v1.erase(it1);\n            dayEdges[d2].push_back(e1);\n            assign_[e1] = d2;\n            \n            double nc1 = dayCost(d1);\n            double nc2 = dayCost(d2);\n            double delta = (nc1+nc2) - (costs[d1]+costs[d2]);\n            if (delta < 0) {\n                costs[d1]=nc1; costs[d2]=nc2;\n                accepted++;\n            } else {\n                dayEdges[d2].pop_back();\n                v1.push_back(e1);\n                assign_[e1] = d1;\n            }\n        } else {\n            int e1 = rng() % M;\n            int e2 = rng() % M;\n            if (e1 == e2) continue;\n            int d1 = assign_[e1], d2 = assign_[e2];\n            if (d1 == d2) continue;\n            auto& v1 = dayEdges[d1];\n            auto& v2 = dayEdges[d2];\n            *find(v1.begin(), v1.end(), e1) = e2;\n            *find(v2.begin(), v2.end(), e2) = e1;\n            assign_[e1] = d2;\n            assign_[e2] = d1;\n            \n            double nc1 = dayCost(d1);\n            double nc2 = dayCost(d2);\n            double delta = (nc1+nc2) - (costs[d1]+costs[d2]);\n            if (delta < 0) {\n                costs[d1]=nc1; costs[d2]=nc2;\n                accepted++;\n            } else {\n                *find(v1.begin(), v1.end(), e2) = e1;\n                *find(v2.begin(), v2.end(), e1) = e2;\n                assign_[e1] = d1;\n                assign_[e2] = d2;\n            }\n        }\n    }\n    \n    cerr << \"iter=\" << iter << \" acc=\" << accepted << endl;\n    \n    for (int i = 0; i < M; i++) cout << assign_[i]+1 << \" \\n\"[i==M-1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nint F[2][14][14], R[2][14][14];\nint occ[2][14][14][14];\nint bid[2][14][14][14];\nint best_bid[2][14][14][14];\n\nint dx6[6]={1,-1,0,0,0,0};\nint dy6[6]={0,0,1,-1,0,0};\nint dz6[6]={0,0,0,0,1,-1};\n\nbool inb(int x,int y,int z){return x>=0&&x<D&&y>=0&&y<D&&z>=0&&z<D;}\n\nint fcount[2][14][14];\nint rcount[2][14][14];\n\nbool canRemove(int i,int x,int y,int z){\n    if(!occ[i][x][y][z]) return false;\n    if(F[i][z][x] && fcount[i][x][z]==1) return false;\n    if(R[i][z][y] && rcount[i][y][z]==1) return false;\n    return true;\n}\nvoid removeCell(int i,int x,int y,int z){\n    occ[i][x][y][z]=0;\n    fcount[i][x][z]--;\n    rcount[i][y][z]--;\n}\n\nmt19937 rng(12345);\n\n// 24 rotations as 3x3 matrices\nint rots[24][9];\n\nvoid genRots(){\n    // Generate 24 rotation matrices (proper rotations, no reflection)\n    // Using axis permutations and sign flips\n    int perms[6][3] = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};\n    int permSign[6] = {1,-1,-1,1,1,-1}; // sign of permutation\n    int cnt=0;\n    for(int p=0;p<6;p++){\n        for(int s=0;s<8;s++){\n            int sx = (s&1)?-1:1;\n            int sy = (s&2)?-1:1;\n            int sz = (s&4)?-1:1;\n            // determinant = permSign * sx*sy*sz\n            if(permSign[p]*sx*sy*sz != 1) continue;\n            int M[9]={0,0,0,0,0,0,0,0,0};\n            int signs[3]={sx,sy,sz};\n            for(int row=0;row<3;row++){\n                M[row*3 + perms[p][row]] = signs[row];\n            }\n            for(int k=0;k<9;k++) rots[cnt][k]=M[k];\n            cnt++;\n        }\n    }\n    // should be 24\n}\n\nvoid applyRot(int ri, int x, int y, int z, int& ox, int& oy, int& oz){\n    int* M = rots[ri];\n    ox = M[0]*x + M[1]*y + M[2]*z;\n    oy = M[3]*x + M[4]*y + M[5]*z;\n    oz = M[6]*x + M[7]*y + M[8]*z;\n}\n\ndouble evalScore(){\n    // Compute evaluation value\n    // Need block volumes per obj\n    int maxId = 0;\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        maxId = max(maxId, bid[i][x][y][z]);\n    vector<int> v1(maxId+1,0), v2(maxId+1,0);\n    for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n        if(bid[0][x][y][z]) v1[bid[0][x][y][z]]++;\n        if(bid[1][x][y][z]) v2[bid[1][x][y][z]]++;\n    }\n    double score = 0;\n    for(int id=1;id<=maxId;id++){\n        if(v1[id]>0 && v2[id]>0){\n            // shared, v1[id] should equal v2[id]\n            score += 1.0/v1[id];\n        } else if(v1[id]>0){\n            score += v1[id]; // unused in obj2\n        } else if(v2[id]>0){\n            score += v2[id]; // unused in obj1\n        }\n    }\n    return score;\n}\n\nvoid runGreedy(double timeLimit, chrono::steady_clock::time_point start){\n    int nextId = 1;\n    \n    while(true){\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed>timeLimit) break;\n        \n        vector<tuple<int,int,int>> a1, a2;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(occ[0][x][y][z]&&!bid[0][x][y][z]) a1.push_back({x,y,z});\n            if(occ[1][x][y][z]&&!bid[1][x][y][z]) a2.push_back({x,y,z});\n        }\n        if(a1.empty()||a2.empty()) break;\n        \n        int bestVol = 0;\n        vector<tuple<int,int,int>> bestCells1, bestCells2;\n        \n        shuffle(a1.begin(),a1.end(),rng);\n        shuffle(a2.begin(),a2.end(),rng);\n        \n        int tries1 = min(15, (int)a1.size());\n        int tries2 = min(15, (int)a2.size());\n        // Also try some rotations\n        int rotSamples = 6; // random rotations out of 24\n        \n        for(int t1=0;t1<tries1;t1++){\n            auto [x1,y1,z1] = a1[t1];\n            for(int t2=0;t2<tries2;t2++){\n                auto [x2,y2,z2] = a2[t2];\n                // try a few random rotations\n                for(int rs=0;rs<rotSamples;rs++){\n                    int ri = rng()%24;\n                    vector<tuple<int,int,int>> block;\n                    set<tuple<int,int,int>> inblk;\n                    queue<tuple<int,int,int>> q;\n                    block.push_back({0,0,0});\n                    inblk.insert({0,0,0});\n                    q.push({0,0,0});\n                    int maxV = 30;\n                    while(!q.empty() && (int)block.size()<maxV){\n                        auto [ox,oy,oz] = q.front(); q.pop();\n                        int order[6]={0,1,2,3,4,5};\n                        shuffle(order,order+6,rng);\n                        for(int k=0;k<6;k++){\n                            int d=order[k];\n                            int nx=ox+dx6[d],ny=oy+dy6[d],nz=oz+dz6[d];\n                            if(inblk.count({nx,ny,nz})) continue;\n                            int ax=x1+nx, ay=y1+ny, az=z1+nz;\n                            // rotate offset for obj2\n                            int rx,ry,rz;\n                            applyRot(ri, nx, ny, nz, rx, ry, rz);\n                            int bx=x2+rx, by=y2+ry, bz=z2+rz;\n                            if(!inb(ax,ay,az)||!inb(bx,by,bz)) continue;\n                            if(!occ[0][ax][ay][az]||bid[0][ax][ay][az]) continue;\n                            if(!occ[1][bx][by][bz]||bid[1][bx][by][bz]) continue;\n                            inblk.insert({nx,ny,nz});\n                            block.push_back({nx,ny,nz});\n                            q.push({nx,ny,nz});\n                            if((int)block.size()>=maxV) break;\n                        }\n                    }\n                    if((int)block.size()>bestVol){\n                        bestVol = block.size();\n                        bestCells1.clear(); bestCells2.clear();\n                        for(auto [ox,oy,oz]:block){\n                            bestCells1.push_back({x1+ox,y1+oy,z1+oz});\n                            int rx,ry,rz;\n                            applyRot(ri, ox, oy, oz, rx, ry, rz);\n                            bestCells2.push_back({x2+rx,y2+ry,z2+rz});\n                        }\n                    }\n                }\n            }\n        }\n        \n        if(bestVol==0) break;\n        int id = nextId++;\n        for(auto [x,y,z]:bestCells1) bid[0][x][y][z]=id;\n        for(auto [x,y,z]:bestCells2) bid[1][x][y][z]=id;\n    }\n    \n    // Remove unnecessary unassigned cells\n    for(int i=0;i<2;i++){\n        bool changed=true;\n        while(changed){\n            changed=false;\n            for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n                if(occ[i][x][y][z]&&!bid[i][x][y][z]&&canRemove(i,x,y,z)){\n                    removeCell(i,x,y,z);\n                    changed=true;\n                }\n            }\n        }\n    }\n    \n    // Assign remaining as single-cell blocks\n    for(int i=0;i<2;i++){\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(occ[i][x][y][z]&&!bid[i][x][y][z]){\n                bid[i][x][y][z] = nextId++;\n            }\n        }\n    }\n}\n\nint occ_backup[2][14][14][14];\nint fcount_backup[2][14][14];\nint rcount_backup[2][14][14];\n\nvoid backup(){\n    memcpy(occ_backup, occ, sizeof(occ));\n    memcpy(fcount_backup, fcount, sizeof(fcount));\n    memcpy(rcount_backup, rcount, sizeof(rcount));\n}\nvoid restore(){\n    memcpy(occ, occ_backup, sizeof(occ));\n    memcpy(fcount, fcount_backup, sizeof(fcount));\n    memcpy(rcount, rcount_backup, sizeof(rcount));\n}\n\nint main(){\n    genRots();\n    cin>>D;\n    for(int i=0;i<2;i++){\n        for(int z=0;z<D;z++){string s;cin>>s;for(int x=0;x<D;x++)F[i][z][x]=s[x]-'0';}\n        for(int z=0;z<D;z++){string s;cin>>s;for(int y=0;y<D;y++)R[i][z][y]=s[y]-'0';}\n    }\n    for(int i=0;i<2;i++){\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(F[i][z][x]&&R[i][z][y]){\n                occ[i][x][y][z]=1;\n                fcount[i][x][z]++;\n                rcount[i][y][z]++;\n            }\n        }\n    }\n    backup();\n    \n    auto start = chrono::steady_clock::now();\n    double TL_total = 5.5;\n    \n    double bestScore = 1e18;\n    \n    int iter = 0;\n    while(true){\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed > TL_total) break;\n        \n        restore();\n        memset(bid, 0, sizeof(bid));\n        \n        // Each iteration has a time budget\n        double budget = min(1.5, TL_total - elapsed - 0.1);\n        auto iter_start = chrono::steady_clock::now();\n        runGreedy(budget, iter_start);\n        \n        double sc = evalScore();\n        if(sc < bestScore){\n            bestScore = sc;\n            memcpy(best_bid, bid, sizeof(bid));\n        }\n        iter++;\n        if(iter >= 20) break;\n    }\n    \n    // Output best\n    int maxId = 0;\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        maxId = max(maxId, best_bid[i][x][y][z]);\n    \n    // Renumber to ensure each block is used\n    vector<int> remap(maxId+1, 0);\n    int cur = 0;\n    for(int id=1;id<=maxId;id++){\n        bool used=false;\n        for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n            if(best_bid[i][x][y][z]==id){used=true; goto done;}\n        done:;\n        if(used) remap[id] = ++cur;\n    }\n    \n    cout << cur << \"\\n\";\n    for(int i=0;i<2;i++){\n        bool first=true;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(!first) cout<<\" \";\n            cout << remap[best_bid[i][x][y][z]];\n            first=false;\n        }\n        cout<<\"\\n\";\n    }\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K;\nvector<int> X, Y;\nvector<int> EU, EV;\nvector<long long> EW;\nvector<int> A, B;\nvector<vector<pair<int,int>>> adj;\n\ndouble dist(double x1,double y1,double x2,double y2){\n    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));\n}\n\nchrono::steady_clock::time_point startT;\ndouble elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-startT).count();}\n\nlong long computeCost(const vector<int>& P, const vector<int>& edgeOn){\n    long long s=0;\n    for(int i=0;i<N;i++) s += (long long)P[i]*P[i];\n    for(int j=0;j<M;j++) if(edgeOn[j]) s += EW[j];\n    return s;\n}\n\nint main(){\n    startT = chrono::steady_clock::now();\n    cin>>N>>M>>K;\n    X.resize(N); Y.resize(N);\n    for(int i=0;i<N;i++) cin>>X[i]>>Y[i];\n    EU.resize(M); EV.resize(M); EW.resize(M);\n    adj.assign(N,{});\n    for(int j=0;j<M;j++){\n        cin>>EU[j]>>EV[j]>>EW[j];\n        EU[j]--; EV[j]--;\n        adj[EU[j]].push_back({EV[j],j});\n        adj[EV[j]].push_back({EU[j],j});\n    }\n    A.resize(K); B.resize(K);\n    for(int k=0;k<K;k++) cin>>A[k]>>B[k];\n    \n    vector<vector<double>> vr(N, vector<double>(K));\n    for(int i=0;i<N;i++)\n        for(int k=0;k<K;k++)\n            vr[i][k] = dist(X[i],Y[i],A[k],B[k]);\n    \n    mt19937 rng(12345);\n    \n    // Build Steiner tree given terminal set (with 0 always included)\n    // Using shortest-path-heuristic with random ordering; also try improvements.\n    auto buildTree = [&](const vector<char>& isTerm, int seed)->pair<vector<int>, vector<char>>{\n        vector<int> terms;\n        for(int i=0;i<N;i++) if(isTerm[i]) terms.push_back(i);\n        vector<char> inTree(N,0);\n        inTree[0]=1;\n        vector<int> edgeOn(M,0);\n        \n        // Greedy: repeatedly add nearest terminal\n        while(true){\n            vector<long long> d(N, LLONG_MAX);\n            vector<int> pe(N,-1), pv(N,-1);\n            priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;\n            for(int i=0;i<N;i++) if(inTree[i]){ d[i]=0; pq.push({0,i}); }\n            while(!pq.empty()){\n                auto [du,u]=pq.top(); pq.pop();\n                if(du>d[u]) continue;\n                for(auto [v,eid]:adj[u]){\n                    long long nd = du + EW[eid];\n                    if(nd<d[v]){ d[v]=nd; pe[v]=eid; pv[v]=u; pq.push({nd,v}); }\n                }\n            }\n            int target=-1; long long bestD=LLONG_MAX;\n            for(int t:terms) if(!inTree[t] && d[t]<bestD){bestD=d[t]; target=t;}\n            if(target==-1) break;\n            int cur=target;\n            while(!inTree[cur]){\n                edgeOn[pe[cur]]=1;\n                inTree[cur]=1;\n                cur = pv[cur];\n            }\n        }\n        return {edgeOn, inTree};\n    };\n    \n    // Prune tree: remove leaf edges leading to non-terminals\n    auto pruneTree = [&](vector<int>& edgeOn, vector<char>& inTree, const vector<char>& isTerm){\n        bool changed=true;\n        while(changed){\n            changed=false;\n            vector<int> deg(N,0);\n            for(int j=0;j<M;j++) if(edgeOn[j]){deg[EU[j]]++; deg[EV[j]]++;}\n            for(int i=0;i<N;i++){\n                if(i==0) continue;\n                if(inTree[i] && !isTerm[i] && deg[i]==1){\n                    // remove the one edge\n                    for(int j=0;j<M;j++) if(edgeOn[j] && (EU[j]==i||EV[j]==i)){\n                        edgeOn[j]=0;\n                        break;\n                    }\n                    inTree[i]=0;\n                    changed=true;\n                }\n            }\n        }\n    };\n    \n    // Given tree (inTree), assign each resident to nearest vertex in tree, compute P\n    auto computePFromTree = [&](const vector<char>& inTree)->vector<int>{\n        vector<double> mx(N,0);\n        for(int k=0;k<K;k++){\n            int best=-1; double bd=1e18;\n            for(int i=0;i<N;i++) if(inTree[i] && vr[i][k]<bd){bd=vr[i][k]; best=i;}\n            if(best>=0) mx[best]=max(mx[best], bd);\n        }\n        vector<int> P(N,0);\n        for(int i=0;i<N;i++){\n            P[i]=(int)ceil(mx[i]);\n            if(P[i]>5000) P[i]=5000;\n        }\n        return P;\n    };\n    \n    // Compute which residents are covered given P and inTree\n    auto allCovered = [&](const vector<int>& P, const vector<char>& inTree)->bool{\n        for(int k=0;k<K;k++){\n            bool ok=false;\n            for(int i=0;i<N;i++) if(inTree[i] && vr[i][k]<=P[i]+1e-9){ok=true;break;}\n            if(!ok) return false;\n        }\n        return true;\n    };\n    \n    // Initial: assign residents to nearest vertex, those become terminals\n    vector<char> isTerm(N,0);\n    isTerm[0]=1;\n    for(int k=0;k<K;k++){\n        int best=0; double bd=vr[0][k];\n        for(int i=1;i<N;i++) if(vr[i][k]<bd){bd=vr[i][k]; best=i;}\n        isTerm[best]=1;\n    }\n    \n    auto [edgeOn, inTree] = buildTree(isTerm, 0);\n    pruneTree(edgeOn, inTree, isTerm);\n    vector<int> P = computePFromTree(inTree);\n    long long bestCost = computeCost(P, edgeOn);\n    vector<int> bestP = P;\n    vector<int> bestEdge = edgeOn;\n    vector<char> bestInTree = inTree;\n    \n    // Local search: try toggling each vertex in/out of terminal set\n    auto trySet = [&](vector<char> newTerm)->bool{\n        newTerm[0]=1;\n        auto [ne, nt] = buildTree(newTerm, 0);\n        pruneTree(ne, nt, newTerm);\n        // after prune, active set = nt (those in tree)\n        vector<int> np = computePFromTree(nt);\n        // Make terminals = those with P>0 or in tree... but some in tree might have P=0 (not covering anyone)\n        // They're still in tree (cost already paid). Fine.\n        long long nc = computeCost(np, ne);\n        if(nc<bestCost){\n            bestCost=nc;\n            bestP=np;\n            bestEdge=ne;\n            bestInTree=nt;\n            return true;\n        }\n        return false;\n    };\n    \n    // Main loop: hill climb by toggling\n    vector<char> curTerm = isTerm;\n    // Update curTerm based on bestInTree\n    for(int i=0;i<N;i++) curTerm[i] = bestInTree[i];\n    curTerm[0]=1;\n    \n    int noImprove=0;\n    while(elapsed()<1.7 && noImprove<3){\n        bool improved=false;\n        // Try toggle each vertex\n        vector<int> order(N);\n        iota(order.begin(),order.end(),0);\n        shuffle(order.begin(),order.end(),rng);\n        for(int v: order){\n            if(v==0) continue;\n            if(elapsed()>1.7) break;\n            vector<char> nt = curTerm;\n            nt[v] = 1-nt[v];\n            auto [ne, inT] = buildTree(nt, 0);\n            pruneTree(ne, inT, nt);\n            vector<int> np = computePFromTree(inT);\n            long long nc = computeCost(np, ne);\n            if(nc<bestCost){\n                bestCost=nc;\n                bestP=np;\n                bestEdge=ne;\n                bestInTree=inT;\n                curTerm = nt;\n                // Update curTerm to reflect pruning\n                for(int i=0;i<N;i++) if(!inT[i]) curTerm[i]=0;\n                curTerm[0]=1;\n                improved=true;\n            }\n        }\n        if(!improved) noImprove++;\n        else noImprove=0;\n    }\n    \n    // Also try: add pairs\n    while(elapsed()<1.85){\n        int v = rng()%N;\n        if(v==0) continue;\n        vector<char> nt = curTerm;\n        nt[v] = 1-nt[v];\n        auto [ne, inT] = buildTree(nt, 0);\n        pruneTree(ne, inT, nt);\n        vector<int> np = computePFromTree(inT);\n        long long nc = computeCost(np, ne);\n        if(nc<bestCost){\n            bestCost=nc;\n            bestP=np;\n            bestEdge=ne;\n            bestInTree=inT;\n            curTerm = nt;\n            for(int i=0;i<N;i++) if(!inT[i]) curTerm[i]=0;\n            curTerm[0]=1;\n        }\n    }\n    \n    // Final verification: ensure all residents covered\n    if(!allCovered(bestP, bestInTree)){\n        // Fallback: extend P to cover\n        for(int k=0;k<K;k++){\n            bool ok=false;\n            for(int i=0;i<N;i++) if(bestInTree[i] && vr[i][k]<=bestP[i]+1e-9){ok=true;break;}\n            if(!ok){\n                // find nearest in tree, extend\n                int best=-1; double bd=1e18;\n                for(int i=0;i<N;i++) if(bestInTree[i] && vr[i][k]<bd){bd=vr[i][k]; best=i;}\n                if(best>=0) bestP[best] = min(5000, (int)ceil(bd));\n            }\n        }\n    }\n    \n    for(int i=0;i<N;i++) cout<<bestP[i]<<\" \\n\"[i==N-1];\n    for(int j=0;j<M;j++) cout<<bestEdge[j]<<\" \\n\"[j==M-1];\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\nint N=30;\nint grid[30][30];\npair<int,int> pos[465];\nbool filled[30][30];\nvector<tuple<int,int,int,int>> ops;\nint dist_[30][30];\npair<int,int> prev_[30][30];\n\nvoid doSwap(int x1,int y1,int x2,int y2){\n    ops.push_back({x1,y1,x2,y2});\n    int v1=grid[x1][y1], v2=grid[x2][y2];\n    swap(grid[x1][y1],grid[x2][y2]);\n    pos[v1]={x2,y2}; pos[v2]={x1,y1};\n}\n\nint dx6[]={-1,-1,0,0,1,1};\nint dy6[]={-1,0,-1,1,0,1};\n\nvoid bfs(int sx,int sy){\n    for(int i=0;i<N;i++)for(int j=0;j<N;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<6;d++){\n            int nx=x+dx6[d], ny=y+dy6[d];\n            if(nx<0||nx>=N||ny<0||ny>nx) continue;\n            if(filled[nx][ny]) continue;\n            if(dist_[nx][ny]!=-1) continue;\n            dist_[nx][ny]=dist_[x][y]+1;\n            prev_[nx][ny]={x,y};\n            q.push({nx,ny});\n        }\n    }\n}\n\nint main(){\n    for(int x=0;x<N;x++)for(int y=0;y<=x;y++){\n        cin>>grid[x][y]; pos[grid[x][y]]={x,y};\n    }\n    \n    auto isAvailable = [&](int x, int y) -> bool {\n        if(x>=N-1) return false;\n        if(filled[x][y]) return false;\n        if(x==0) return true;\n        if(y-1>=0 && !filled[x-1][y-1]) return false;\n        if(y<=x-1 && !filled[x-1][y]) return false;\n        return true;\n    };\n    \n    for(int k=0;k<435;k++){\n        auto [cx,cy]=pos[k];\n        bfs(cx,cy);\n        int bestD=INT_MAX, btx=-1, bty=-1;\n        for(int x=0;x<N-1;x++)for(int y=0;y<=x;y++){\n            if(!isAvailable(x,y)) continue;\n            if(dist_[x][y]==-1) continue;\n            if(dist_[x][y]<bestD){\n                bestD=dist_[x][y]; btx=x; bty=y;\n            }\n        }\n        vector<pair<int,int>> path;\n        int x=btx,y=bty;\n        while(!(x==cx&&y==cy)){\n            path.push_back({x,y});\n            auto [px,py]=prev_[x][y];\n            x=px; y=py;\n        }\n        path.push_back({cx,cy});\n        reverse(path.begin(),path.end());\n        for(int i=0;i+1<(int)path.size();i++){\n            doSwap(path[i].first,path[i].second,path[i+1].first,path[i+1].second);\n        }\n        filled[btx][bty]=true;\n    }\n    \n    cout<<ops.size()<<\"\\n\";\n    for(auto[a,b,c,d]:ops)cout<<a<<\" \"<<b<<\" \"<<c<<\" \"<<d<<\"\\n\";\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N;\nbool obs[9][9];\nint dr[]={-1,1,0,0}, dc[]={0,0,-1,1};\n\nint main(){\n    cin>>D>>N;\n    for(int i=0;i<N;i++){int r,c;cin>>r>>c;obs[r][c]=true;}\n    int M=D*D-1-N;\n    \n    vector<pair<int,int>> order;\n    vector<vector<bool>> visited(9,vector<bool>(9,false));\n    function<void(int,int)> dfs=[&](int r,int c){\n        visited[r][c]=true;\n        if(!(r==0&&c==4)) order.push_back({r,c});\n        int dirs[]={1,2,3,0};\n        for(int d:dirs){\n            int nr=r+dr[d], nc=c+dc[d];\n            if(nr<0||nr>=9||nc<0||nc>=9) continue;\n            if(visited[nr][nc]||obs[nr][nc]) continue;\n            dfs(nr,nc);\n        }\n    };\n    dfs(0,4);\n    \n    vector<vector<int>> pidx(9,vector<int>(9,-1));\n    for(int k=0;k<(int)order.size();k++) pidx[order[k].first][order[k].second]=k;\n    \n    vector<vector<bool>> filled(9,vector<bool>(9,false));\n    vector<vector<int>> cellVal(9,vector<int>(9,-1));\n    \n    auto computeReach=[&](){\n        vector<vector<bool>> vis(9,vector<bool>(9,false));\n        queue<pair<int,int>> q;\n        vis[0][4]=true; q.push({0,4});\n        while(!q.empty()){\n            auto [r,c]=q.front(); q.pop();\n            for(int d=0;d<4;d++){\n                int nr=r+dr[d], nc=c+dc[d];\n                if(nr<0||nr>=9||nc<0||nc>=9) continue;\n                if(vis[nr][nc]||obs[nr][nc]||filled[nr][nc]) continue;\n                vis[nr][nc]=true; q.push({nr,nc});\n            }\n        }\n        return vis;\n    };\n    \n    for(int d=0;d<M;d++){\n        int t; cin>>t;\n        auto vis=computeReach();\n        int bestK=-1, bestDiff=INT_MAX;\n        for(int r=0;r<9;r++)for(int c=0;c<9;c++){\n            if(obs[r][c]||filled[r][c]) continue;\n            if(r==0&&c==4) continue;\n            if(!vis[r][c]) continue;\n            int k=pidx[r][c];\n            int diff=abs(k-t);\n            if(diff<bestDiff){bestDiff=diff;bestK=k;}\n        }\n        auto [pr,pc]=order[bestK];\n        filled[pr][pc]=true;\n        cellVal[pr][pc]=t;\n        cout<<pr<<\" \"<<pc<<\"\\n\";\n        cout.flush();\n    }\n    \n    for(int step=0;step<M;step++){\n        vector<vector<bool>> emptyVis(9,vector<bool>(9,false));\n        queue<pair<int,int>> q;\n        emptyVis[0][4]=true; q.push({0,4});\n        while(!q.empty()){\n            auto [r,c]=q.front();q.pop();\n            for(int di=0;di<4;di++){\n                int nr=r+dr[di],nc=c+dc[di];\n                if(nr<0||nr>=9||nc<0||nc>=9)continue;\n                if(emptyVis[nr][nc]||obs[nr][nc]||filled[nr][nc])continue;\n                emptyVis[nr][nc]=true; q.push({nr,nc});\n            }\n        }\n        int bestVal=INT_MAX, br=-1,bc=-1;\n        for(int r=0;r<9;r++)for(int c=0;c<9;c++){\n            if(!filled[r][c])continue;\n            bool adj=false;\n            for(int di=0;di<4;di++){\n                int nr=r+dr[di],nc=c+dc[di];\n                if(nr<0||nr>=9||nc<0||nc>=9)continue;\n                if(emptyVis[nr][nc]){adj=true;break;}\n            }\n            if(!adj)continue;\n            int v=cellVal[r][c];\n            if(v<bestVal){bestVal=v;br=r;bc=c;}\n        }\n        filled[br][bc]=false;\n        cout<<br<<\" \"<<bc<<\"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nvector<vector<int>> grid;\nint DX[4]={-1,1,0,0}, DY[4]={0,0,-1,1};\nvector<vector<int>> origAdj;\nvector<vector<int>> cnt;\n\nbool localConnected(int r, int c, int F){\n    auto at = [&](int x, int y)->int{\n        if(x<0||x>=n||y<0||y>=n) return -1;\n        return grid[x][y];\n    };\n    bool ring[8];\n    ring[0] = at(r-1,c)==F;\n    ring[1] = at(r-1,c+1)==F;\n    ring[2] = at(r,c+1)==F;\n    ring[3] = at(r+1,c+1)==F;\n    ring[4] = at(r+1,c)==F;\n    ring[5] = at(r+1,c-1)==F;\n    ring[6] = at(r,c-1)==F;\n    ring[7] = at(r-1,c-1)==F;\n    int orthCount = (int)ring[0]+ring[2]+ring[4]+ring[6];\n    if(orthCount==0) return false;\n    if(orthCount==1) return true;\n    int comp[8]; for(int i=0;i<8;i++)comp[i]=-1;\n    int cc=0;\n    for(int i=0;i<8;i++){\n        if(!ring[i]||comp[i]>=0)continue;\n        comp[i]=cc;\n        vector<int> stk={i};\n        while(!stk.empty()){\n            int x=stk.back();stk.pop_back();\n            for(int dd:{-1,1}){\n                int y=(x+dd+8)%8;\n                if(ring[y]&&comp[y]<0){comp[y]=cc;stk.push_back(y);}\n            }\n        }\n        cc++;\n    }\n    int first=-1;\n    for(int i:{0,2,4,6}){\n        if(!ring[i])continue;\n        if(first<0)first=comp[i];\n        else if(comp[i]!=first)return false;\n    }\n    return true;\n}\n\nbool fullRemovableBFS(int r, int c, int F){\n    vector<pair<int,int>> sames;\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&&grid[nr][nc]==F)sames.push_back({nr,nc});\n    }\n    if(sames.empty())return false;\n    static bool vis[60][60];\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)vis[i][j]=false;\n    queue<pair<int,int>> q;\n    q.push(sames[0]); vis[sames[0].first][sames[0].second]=true;\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(nx<0||nx>=n||ny<0||ny>=n)continue;\n            if(vis[nx][ny])continue;\n            if(nx==r&&ny==c)continue;\n            if(grid[nx][ny]!=F)continue;\n            vis[nx][ny]=true;\n            q.push({nx,ny});\n        }\n    }\n    for(auto[x,y]:sames)if(!vis[x][y])return false;\n    return true;\n}\n\nbool removable(int r, int c, int F){\n    if(localConnected(r,c,F))return true;\n    return fullRemovableBFS(r,c,F);\n}\n\nbool tryChange(int r, int c, int T){\n    int F = grid[r][c];\n    if(F==T)return false;\n    int nbrs[4];\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)nbrs[d]=0;\n        else nbrs[d]=grid[nr][nc];\n    }\n    bool tOk=false;\n    if(T==0){\n        if(r==0||r==n-1||c==0||c==n-1) tOk=true;\n        else for(int d=0;d<4;d++)if(nbrs[d]==0){tOk=true;break;}\n    } else {\n        for(int d=0;d<4;d++)if(nbrs[d]==T){tOk=true;break;}\n    }\n    if(!tOk) return false;\n    \n    auto modify=[&](int F_, int T_){\n        for(int d=0;d<4;d++){\n            int N=nbrs[d];\n            if(F_ != N){ cnt[F_][N]--; cnt[N][F_]--; }\n            if(T_ != N){ cnt[T_][N]++; cnt[N][T_]++; }\n        }\n    };\n    modify(F,T);\n    \n    bool ok=true;\n    auto chk=[&](int a,int b)->bool{\n        if(a==b)return true;\n        return (origAdj[a][b]!=0)==(cnt[a][b]>0);\n    };\n    for(int d=0;d<4 && ok;d++){\n        int N=nbrs[d];\n        if(N!=F && !chk(F,N))ok=false;\n        if(ok && N!=T && !chk(T,N))ok=false;\n    }\n    if(ok && !chk(F,T))ok=false;\n    \n    if(!ok){\n        modify(T,F);\n        return false;\n    }\n    \n    grid[r][c]=T;\n    if(!removable(r,c,F)){\n        grid[r][c]=F;\n        modify(T,F);\n        return false;\n    }\n    return true;\n}\n\nint main(){\n    cin>>n>>m;\n    grid.assign(n,vector<int>(n));\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)cin>>grid[i][j];\n    \n    cnt.assign(m+1, vector<int>(m+1, 0));\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        int a=grid[i][j];\n        for(int d=0;d<4;d++){\n            int ni=i+DX[d],nj=j+DY[d];\n            if(ni<0||ni>=n||nj<0||nj>=n){\n                cnt[a][0]++; cnt[0][a]++;\n            } else {\n                int b=grid[ni][nj];\n                cnt[a][b]++;\n            }\n        }\n    }\n    origAdj.assign(m+1, vector<int>(m+1,0));\n    for(int a=0;a<=m;a++)for(int b=0;b<=m;b++)if(a!=b && cnt[a][b]>0)origAdj[a][b]=1;\n    \n    auto startTime = chrono::steady_clock::now();\n    auto elapsed = [&]()->long long{\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();\n    };\n    mt19937 rng(42);\n    \n    // Phase 1: aggressive 0-flipping\n    while(elapsed() < 400){\n        bool improved=false;\n        vector<pair<int,int>> cells;\n        for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(grid[i][j]!=0)cells.push_back({i,j});\n        shuffle(cells.begin(), cells.end(), rng);\n        for(auto[r,c]:cells){\n            if(grid[r][c]==0)continue;\n            if(tryChange(r,c,0))improved=true;\n        }\n        if(!improved)break;\n    }\n    \n    // Phase 2: alternate lateral moves and 0-flips\n    while(elapsed() < 1800){\n        // random lateral moves\n        for(int tries=0; tries<8000 && elapsed()<1800; tries++){\n            int r = rng()%n, c = rng()%n;\n            if(grid[r][c]==0)continue;\n            int d = rng()%4;\n            int nr=r+DX[d],nc=c+DY[d];\n            int T;\n            if(nr<0||nr>=n||nc<0||nc>=n)T=0;\n            else T=grid[nr][nc];\n            if(T==grid[r][c])continue;\n            tryChange(r,c,T);\n        }\n        // 0-flip pass\n        vector<pair<int,int>> cells;\n        for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(grid[i][j]!=0)cells.push_back({i,j});\n        shuffle(cells.begin(), cells.end(), rng);\n        for(auto[r,c]:cells){\n            if(grid[r][c]==0)continue;\n            tryChange(r,c,0);\n        }\n    }\n    \n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            cout<<grid[i][j]<<(j+1<n?' ':'\\n');\n        }\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\nint ask(const vector<int>& L, const vector<int>& R) {\n    queries_used++;\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << \"\\n\";\n    cout.flush();\n    char c; cin >> c;\n    if (c == '<') return -1;\n    if (c == '>') return 1;\n    return 0;\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    int reserve = max(2*D, min(Q/3, 15*D));\n    \n    function<vector<int>(vector<int>)> msort = [&](vector<int> v) -> vector<int> {\n        if (v.size() <= 1) return v;\n        int mid = v.size()/2;\n        vector<int> L(v.begin(), v.begin()+mid);\n        vector<int> R(v.begin()+mid, v.end());\n        L = msort(L);\n        R = msort(R);\n        vector<int> res;\n        int i=0,j=0;\n        while (i<(int)L.size() && j<(int)R.size()) {\n            if (queries_used >= Q - reserve) {\n                while (i<(int)L.size()) res.push_back(L[i++]);\n                while (j<(int)R.size()) res.push_back(R[j++]);\n                return res;\n            }\n            int c = ask({L[i]}, {R[j]});\n            if (c <= 0) res.push_back(L[i++]);\n            else res.push_back(R[j++]);\n        }\n        while (i<(int)L.size()) res.push_back(L[i++]);\n        while (j<(int)R.size()) res.push_back(R[j++]);\n        return res;\n    };\n    \n    vector<int> sorted_items = msort(items);\n    reverse(sorted_items.begin(), sorted_items.end());\n    \n    vector<int> rank_of(N);\n    for (int i = 0; i < N; i++) rank_of[sorted_items[i]] = i;\n    \n    auto estimate = [&](const vector<int>& g) {\n        double s = 0;\n        for (int x : g) s += exp(-rank_of[x] * 0.03);\n        return s;\n    };\n    \n    vector<vector<int>> groups(D);\n    for (int i = 0; i < D && i < N; i++) groups[i].push_back(sorted_items[i]);\n    for (int i = D; i < N; i++) {\n        int best = 0;\n        double bestv = estimate(groups[0]);\n        for (int d = 1; d < D; d++) {\n            double v = estimate(groups[d]);\n            if (v < bestv) { bestv = v; best = d; }\n        }\n        groups[best].push_back(sorted_items[i]);\n    }\n    \n    int fail_count = 0;\n    while (queries_used < Q) {\n        int heavy = 0, light = 0;\n        double hv = estimate(groups[0]), lv = hv;\n        for (int d = 1; d < D; d++) {\n            double v = estimate(groups[d]);\n            if (v > hv) { hv = v; heavy = d; }\n            if (v < lv) { lv = v; light = d; }\n        }\n        if (heavy == light) {\n            while (queries_used < Q) ask({0}, {1});\n            break;\n        }\n        \n        if (queries_used >= Q) break;\n        int c = ask(groups[heavy], groups[light]);\n        if (c == 0) {\n            if (fail_count++ > 5) { while (queries_used < Q) ask({0}, {1}); break; }\n            continue;\n        }\n        if (c < 0) swap(heavy, light);\n        \n        bool improved = false;\n        vector<int> hi = groups[heavy];\n        sort(hi.begin(), hi.end(), [&](int a, int b){ return rank_of[a] > rank_of[b]; });\n        \n        for (int x : hi) {\n            if ((int)groups[heavy].size() <= 1) break;\n            if (queries_used >= Q) break;\n            vector<int> nh, nl = groups[light];\n            for (int y : groups[heavy]) if (y != x) nh.push_back(y);\n            nl.push_back(x);\n            int c2 = ask(nh, nl);\n            if (c2 >= 0) {\n                groups[heavy] = nh;\n                groups[light] = nl;\n                improved = true;\n                break;\n            }\n            break;\n        }\n        \n        if (!improved && queries_used < Q) {\n            vector<tuple<int,int,int>> pairs;\n            for (int a : groups[heavy]) for (int b : groups[light]) {\n                if (rank_of[a] < rank_of[b]) \n                    pairs.push_back({rank_of[b] - rank_of[a], a, b});\n            }\n            sort(pairs.begin(), pairs.end());\n            \n            for (auto& [_, a, b] : pairs) {\n                if (queries_used >= Q) break;\n                vector<int> nh, nl;\n                for (int y : groups[heavy]) nh.push_back(y == a ? b : y);\n                for (int y : groups[light]) nl.push_back(y == b ? a : y);\n                int c2 = ask(nh, nl);\n                if (c2 >= 0) {\n                    groups[heavy] = nh;\n                    groups[light] = nl;\n                    improved = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!improved) fail_count++;\n        else fail_count = 0;\n        \n        if (fail_count > 10) {\n            while (queries_used < Q) ask({0}, {1});\n            break;\n        }\n    }\n    \n    vector<int> d(N, 0);\n    for (int g = 0; g < D; g++) for (int x : groups[g]) d[x] = g;\n    for (int i = 0; i < N; i++) {\n        cout << d[i];\n        cout << (i == N-1 ? '\\n' : ' ');\n    }\n    cout.flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nvector<vector<int>> stk;\nvector<pair<int,int>> ops;\n\nint main() {\n    cin >> n >> m;\n    stk.assign(m, {});\n    for (int i = 0; i < m; i++) {\n        stk[i].resize(n/m);\n        for (int j = 0; j < n/m; j++) cin >> stk[i][j];\n    }\n    \n    for (int v = 1; v <= n; v++) {\n        int si = -1, pos = -1;\n        for (int i = 0; i < m && si == -1; i++)\n            for (int j = 0; j < (int)stk[i].size(); j++)\n                if (stk[i][j]==v) { si=i; pos=j; break; }\n        \n        int above = stk[si].size() - 1 - pos;\n        \n        if (above > 0) {\n            vector<int> moved(stk[si].begin()+pos+1, stk[si].end());\n            int maxMoved = *max_element(moved.begin(), moved.end());\n            \n            int best = -1;\n            int bestMin = INT_MAX;\n            int emptyStack = -1;\n            for (int i = 0; i < m; i++) {\n                if (i == si) continue;\n                if (stk[i].empty()) { emptyStack = i; continue; }\n                int mn = *min_element(stk[i].begin(), stk[i].end());\n                if (mn > maxMoved && mn < bestMin) {\n                    bestMin = mn; best = i;\n                }\n            }\n            \n            if (best == -1 && emptyStack != -1) {\n                best = emptyStack;\n            }\n            \n            if (best == -1) {\n                // Unsafe: pick dest that minimizes expected re-move cost\n                // score = #moved elements > dest_min (these will need re-moving)\n                //       + (depth of existing boxes above dest_min in dest)\n                // Minimize this.\n                int bestScore = INT_MAX;\n                int bestTop = -1;\n                for (int i = 0; i < m; i++) {\n                    if (i == si) continue;\n                    int mn = *min_element(stk[i].begin(), stk[i].end());\n                    int above_mn = 0;\n                    for (int j = (int)stk[i].size()-1; j >= 0; j--) {\n                        if (stk[i][j] == mn) break;\n                        above_mn++;\n                    }\n                    int cnt = 0;\n                    for (int x : moved) if (x > mn) cnt++;\n                    int score = cnt + above_mn;\n                    int t = stk[i].back();\n                    if (score < bestScore || (score == bestScore && t > bestTop)) {\n                        bestScore = score; best = i; bestTop = t;\n                    }\n                }\n            }\n            \n            ops.push_back({moved[0], best+1});\n            stk[si].resize(pos+1);\n            for (int x : moved) stk[best].push_back(x);\n        }\n        \n        ops.push_back({v, 0});\n        stk[si].pop_back();\n    }\n    \n    for (auto [a,b] : ops) cout << a << \" \" << b << \"\\n\";\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> hh, vv;\nvector<vector<int>> d;\nint dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};\nchar DC[4]={'U','D','L','R'};\n\nbool canMove(int x,int y,int dir){\n    int nx=x+dx[dir], ny=y+dy[dir];\n    if(nx<0||nx>=N||ny<0||ny>=N) return false;\n    if(dir==0) return hh[nx][y]=='0';\n    if(dir==1) return hh[x][y]=='0';\n    if(dir==2) return vv[x][ny]=='0';\n    if(dir==3) return vv[x][y]=='0';\n    return false;\n}\n\nvector<vector<vector<vector<int>>>> allPar;\nvector<vector<vector<vector<int>>>> allD;\n\nvoid computeAllDist(){\n    allPar.assign(N,vector<vector<vector<int>>>(N,vector<vector<int>>(N,vector<int>(N,-1))));\n    allD.assign(N,vector<vector<vector<int>>>(N,vector<vector<int>>(N,vector<int>(N,INT_MAX))));\n    for(int sx=0;sx<N;sx++)for(int sy=0;sy<N;sy++){\n        auto& D=allD[sx][sy];\n        auto& P=allPar[sx][sy];\n        D[sx][sy]=0;\n        queue<pair<int,int>> q; q.push({sx,sy});\n        while(!q.empty()){\n            auto [x,y]=q.front(); q.pop();\n            for(int d2=0;d2<4;d2++) if(canMove(x,y,d2)){\n                int nx=x+dx[d2], ny=y+dy[d2];\n                if(D[nx][ny]>D[x][y]+1){ D[nx][ny]=D[x][y]+1; P[nx][ny]=d2; q.push({nx,ny}); }\n            }\n        }\n    }\n}\n\nvector<int> getPath(int sx,int sy,int tx,int ty){\n    vector<int> res;\n    int x=tx,y=ty;\n    while(!(x==sx&&y==sy)){\n        int dir=allPar[sx][sy][x][y];\n        if(dir<0) return {};\n        res.push_back(dir);\n        int rdir = dir^1;\n        x+=dx[rdir]; y+=dy[rdir];\n    }\n    reverse(res.begin(),res.end());\n    return res;\n}\n\nvector<int> tour;\nvector<vector<bool>> visited;\nvoid dfs(int x,int y){\n    visited[x][y]=true;\n    for(int dir=0;dir<4;dir++){\n        if(canMove(x,y,dir)){\n            int nx=x+dx[dir],ny=y+dy[dir];\n            if(!visited[nx][ny]){\n                tour.push_back(dir);\n                dfs(nx,ny);\n                tour.push_back(dir^1);\n            }\n        }\n    }\n}\n\n// Score: sum_{cell} d[cell] * sum_{gaps g} g*(g-1)/2, then divide by L\n// Using cyclic gaps\n\ndouble computeScore(const vector<int>& tr){\n    int L=tr.size();\n    if(L==0) return 1e18;\n    vector<vector<vector<int>>> times(N,vector<vector<int>>(N));\n    int x=0,y=0;\n    times[0][0].push_back(0);\n    for(int t=0;t<L;t++){\n        x+=dx[tr[t]]; y+=dy[tr[t]];\n        times[x][y].push_back(t+1);\n    }\n    if(x!=0||y!=0) return 1e18;\n    double total=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        auto& T=times[i][j];\n        if(T.empty()) return 1e18;\n        vector<int> U;\n        U.reserve(T.size());\n        for(int t:T) if(t<L) U.push_back(t);\n        sort(U.begin(),U.end());\n        U.erase(unique(U.begin(),U.end()),U.end());\n        int k=U.size();\n        if(k==0) return 1e18;\n        long long sumSq=0;\n        for(int m=0;m<k;m++){\n            int g = (m+1<k? U[m+1]-U[m] : U[0]+L-U[m]);\n            sumSq += (long long)g*(g-1)/2;\n        }\n        total += (double)d[i][j] * sumSq;\n    }\n    return total / L;\n}\n\nint main(){\n    cin>>N;\n    hh.resize(N-1); for(auto&s:hh)cin>>s;\n    vv.resize(N); for(auto&s:vv)cin>>s;\n    d.assign(N,vector<int>(N));\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>d[i][j];\n    \n    computeAllDist();\n    \n    visited.assign(N,vector<bool>(N,false));\n    dfs(0,0);\n    \n    // First: simplify tour by replacing segments with shortest paths if they return to same cell\n    // This is a strong preprocessing\n    \n    double curScore = computeScore(tour);\n    \n    mt19937 rng(12345);\n    auto startTime = chrono::steady_clock::now();\n    auto elapsed = [&](){\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now-startTime).count();\n    };\n    \n    vector<tuple<int,int,int>> cells;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) cells.push_back({d[i][j],i,j});\n    sort(cells.rbegin(),cells.rend());\n    \n    // Phase 1: aggressive segment shortening \u2014 replace any subpath with shortest-path version if it reduces score\n    // Pass multiple times\n    {\n        bool improved = true;\n        int passes = 0;\n        while(improved && passes < 20 && elapsed() < 0.3){\n            improved = false;\n            passes++;\n            int L = tour.size();\n            // precompute positions\n            vector<pair<int,int>> pos(L+1);\n            pos[0] = {0,0};\n            for(int t=0;t<L;t++){ pos[t+1] = {pos[t].first+dx[tour[t]], pos[t].second+dy[tour[t]]}; }\n            \n            for(int a=0; a<L && elapsed()<0.3; a++){\n                int maxb = min(L, a+400);\n                for(int b=a+2; b<=maxb; b++){\n                    int dist = allD[pos[a].first][pos[a].second][pos[b].first][pos[b].second];\n                    if(dist >= b-a) continue;\n                    // try replacement\n                    auto p = getPath(pos[a].first,pos[a].second,pos[b].first,pos[b].second);\n                    vector<int> newTour;\n                    newTour.reserve(L-(b-a)+p.size());\n                    for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n                    for(int x:p) newTour.push_back(x);\n                    for(int t=b;t<L;t++) newTour.push_back(tour[t]);\n                    double ns = computeScore(newTour);\n                    if(ns < curScore){\n                        tour = newTour;\n                        curScore = ns;\n                        improved = true;\n                        goto restart;\n                    }\n                }\n            }\n            restart:;\n        }\n    }\n    \n    // Phase 2: random local search \u2014 detour insertion + segment replacement + redundancy removal\n    while(elapsed() < 1.85){\n        int mode = rng()%4;\n        int L = tour.size();\n        \n        if(mode==0){\n            // detour insertion to high-d cell\n            int ci = rng() % min((int)cells.size(), 50);\n            auto [dv,ti,tj] = cells[ci];\n            if(L>95000) continue;\n            int pos_i = rng()%(L+1);\n            int cx=0,cy=0;\n            for(int t=0;t<pos_i;t++){ cx+=dx[tour[t]]; cy+=dy[tour[t]]; }\n            if(cx==ti&&cy==tj) continue;\n            auto p1 = getPath(cx,cy,ti,tj);\n            auto p2 = getPath(ti,tj,cx,cy);\n            if((int)(L+p1.size()+p2.size())>100000) continue;\n            vector<int> newTour;\n            newTour.reserve(L+p1.size()+p2.size());\n            for(int t=0;t<pos_i;t++) newTour.push_back(tour[t]);\n            for(int x:p1) newTour.push_back(x);\n            for(int x:p2) newTour.push_back(x);\n            for(int t=pos_i;t<L;t++) newTour.push_back(tour[t]);\n            double ns = computeScore(newTour);\n            if(ns<curScore){ tour=newTour; curScore=ns; }\n        } else if(mode==1){\n            // segment replacement\n            if(L<10) continue;\n            int a=rng()%L;\n            int maxlen = min(500,L-a-1);\n            if(maxlen<2) continue;\n            int b=a+2+rng()%(maxlen-1);\n            if(b>L) continue;\n            int ax=0,ay=0;\n            for(int t=0;t<a;t++){ax+=dx[tour[t]];ay+=dy[tour[t]];}\n            int bx=ax,by=ay;\n            for(int t=a;t<b;t++){bx+=dx[tour[t]];by+=dy[tour[t]];}\n            int dist = allD[ax][ay][bx][by];\n            if(dist>=b-a) continue;\n            auto p = getPath(ax,ay,bx,by);\n            vector<int> newTour;\n            newTour.reserve(L-(b-a)+p.size());\n            for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n            for(int x:p) newTour.push_back(x);\n            for(int t=b;t<L;t++) newTour.push_back(tour[t]);\n            double ns = computeScore(newTour);\n            if(ns<curScore){ tour=newTour; curScore=ns; }\n        } else if(mode==2){\n            // back-and-forth removal\n            if(L<4) continue;\n            int a=rng()%(L-1);\n            if(tour[a]==(tour[a+1]^1)){\n                vector<int> newTour;\n                newTour.reserve(L-2);\n                for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n                for(int t=a+2;t<L;t++) newTour.push_back(tour[t]);\n                double ns = computeScore(newTour);\n                if(ns<curScore){ tour=newTour; curScore=ns; }\n            }\n        } else {\n            // insert detour via random path of length 2 (visit a random neighbor twice)\n            if(L>99998) continue;\n            int pos_i = rng()%(L+1);\n            int cx=0,cy=0;\n            for(int t=0;t<pos_i;t++){ cx+=dx[tour[t]]; cy+=dy[tour[t]]; }\n            vector<int> dirs;\n            for(int dr=0;dr<4;dr++) if(canMove(cx,cy,dr)) dirs.push_back(dr);\n            if(dirs.empty()) continue;\n            int dr = dirs[rng()%dirs.size()];\n            vector<int> newTour;\n            newTour.reserve(L+2);\n            for(int t=0;t<pos_i;t++) newTour.push_back(tour[t]);\n            newTour.push_back(dr);\n            newTour.push_back(dr^1);\n            for(int t=pos_i;t<L;t++) newTour.push_back(tour[t]);\n            double ns = computeScore(newTour);\n            if(ns<curScore){ tour=newTour; curScore=ns; }\n        }\n    }\n    \n    for(int dir:tour) cout<<DC[dir];\n    cout<<endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint si, sj;\nvector<string> grid;\nvector<string> words;\nvector<vector<pair<int,int>>> posOf(26);\n\ninline int distm(int r1,int c1,int r2,int c2){ return abs(r1-r2)+abs(c1-c2)+1; }\n\nvector<vector<int>> overlap;\nvector<vector<pair<int,int>>> lastPos;\n\nvector<vector<array<int,5>>> fromCost;\nvector<vector<array<int,5>>> fromEnd;\n\nint main(){\n    auto start_time = chrono::steady_clock::now();\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin>>N>>M>>si>>sj;\n    grid.resize(N);\n    for(int i=0;i<N;i++) cin>>grid[i];\n    words.resize(M);\n    for(int i=0;i<M;i++) cin>>words[i];\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) posOf[grid[i][j]-'A'].push_back({i,j});\n    \n    overlap.assign(M, vector<int>(M,0));\n    for(int i=0;i<M;i++)for(int j=0;j<M;j++){\n        if(i==j) continue;\n        for(int k=4;k>=1;k--){\n            if(words[i].substr(5-k)==words[j].substr(0,k)){overlap[i][j]=k;break;}\n        }\n    }\n    \n    lastPos.resize(M);\n    for(int i=0;i<M;i++) lastPos[i] = posOf[words[i][4]-'A'];\n    \n    int NC = N*N;\n    fromCost.assign(NC, vector<array<int,5>>(M));\n    fromEnd.assign(NC, vector<array<int,5>>(M));\n    \n    for(int cIdx=0; cIdx<NC; cIdx++){\n        int pr = cIdx/N, pc = cIdx%N;\n        for(int j=0; j<M; j++){\n            string& w = words[j];\n            for(int ov=0; ov<5; ov++){\n                int len = 5-ov;\n                static int dp[5][30];\n                int sizes[5];\n                for(int i=0;i<len;i++) sizes[i] = posOf[w[ov+i]-'A'].size();\n                {\n                    auto& pv = posOf[w[ov]-'A'];\n                    for(int k=0;k<sizes[0];k++) dp[0][k] = distm(pr,pc,pv[k].first,pv[k].second);\n                }\n                for(int i=1;i<len;i++){\n                    auto& pp = posOf[w[ov+i-1]-'A'];\n                    auto& pc2 = posOf[w[ov+i]-'A'];\n                    for(int k=0;k<sizes[i];k++){\n                        int r=pc2[k].first, c=pc2[k].second;\n                        int best=INT_MAX;\n                        for(int jj=0;jj<sizes[i-1];jj++){\n                            int nc = dp[i-1][jj] + distm(pp[jj].first,pp[jj].second,r,c);\n                            if(nc<best) best=nc;\n                        }\n                        dp[i][k]=best;\n                    }\n                }\n                int best=INT_MAX, bk=-1;\n                for(int k=0;k<sizes[len-1];k++) if(dp[len-1][k]<best){best=dp[len-1][k];bk=k;}\n                fromCost[cIdx][j][ov] = best;\n                fromEnd[cIdx][j][ov] = bk;\n            }\n        }\n    }\n    \n    auto evaluate = [&](const vector<int>& ord)->int{\n        int cIdx = si*N+sj;\n        int cost = fromCost[cIdx][ord[0]][0];\n        int endIdx = fromEnd[cIdx][ord[0]][0];\n        for(int i=1;i<M;i++){\n            auto& lp = lastPos[ord[i-1]][endIdx];\n            int cIdx2 = lp.first*N + lp.second;\n            int ov = overlap[ord[i-1]][ord[i]];\n            cost += fromCost[cIdx2][ord[i]][ov];\n            endIdx = fromEnd[cIdx2][ord[i]][ov];\n        }\n        return cost;\n    };\n    \n    vector<int> order;\n    {\n        vector<bool> used(M,false);\n        int cIdx = si*N+sj;\n        int bw=-1, bc=INT_MAX, be=-1;\n        for(int j=0;j<M;j++){\n            if(fromCost[cIdx][j][0]<bc){bc=fromCost[cIdx][j][0]; bw=j; be=fromEnd[cIdx][j][0];}\n        }\n        order.push_back(bw); used[bw]=true;\n        int curEnd = be;\n        int curWord = bw;\n        for(int step=1; step<M; step++){\n            auto& lp = lastPos[curWord][curEnd];\n            int ci = lp.first*N+lp.second;\n            int bw2=-1, bc2=INT_MAX, be2=-1;\n            for(int j=0;j<M;j++) if(!used[j]){\n                int ov = overlap[curWord][j];\n                if(fromCost[ci][j][ov]<bc2){\n                    bc2=fromCost[ci][j][ov]; bw2=j; be2=fromEnd[ci][j][ov];\n                }\n            }\n            order.push_back(bw2); used[bw2]=true;\n            curWord=bw2; curEnd=be2;\n        }\n    }\n    \n    int curCost = evaluate(order);\n    int bestCost = curCost;\n    vector<int> bestOrder = order;\n    \n    mt19937 rng(42);\n    auto time_ms = [&](){ return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-start_time).count(); };\n    \n    int iter=0;\n    while(time_ms() < 1800){\n        iter++;\n        int op = rng()%4;\n        if(op==0){\n            int a = rng()%M, b = rng()%M;\n            if(a==b) continue;\n            if(a>b) swap(a,b);\n            reverse(order.begin()+a, order.begin()+b+1);\n            int nc = evaluate(order);\n            if(nc < curCost){\n                curCost = nc;\n                if(nc<bestCost){bestCost=nc; bestOrder=order;}\n            } else {\n                reverse(order.begin()+a, order.begin()+b+1);\n            }\n        } else if(op==1){\n            int a = rng()%M, b = rng()%M;\n            if(a==b) continue;\n            int v = order[a];\n            if(a<b){\n                for(int i=a;i<b;i++) order[i]=order[i+1];\n                order[b]=v;\n            } else {\n                for(int i=a;i>b;i--) order[i]=order[i-1];\n                order[b]=v;\n            }\n            int nc = evaluate(order);\n            if(nc < curCost){\n                curCost = nc;\n                if(nc<bestCost){bestCost=nc; bestOrder=order;}\n            } else {\n                int v2 = order[b];\n                if(a<b){\n                    for(int i=b;i>a;i--) order[i]=order[i-1];\n                    order[a]=v2;\n                } else {\n                    for(int i=b;i<a;i++) order[i]=order[i+1];\n                    order[a]=v2;\n                }\n            }\n        } else if(op==2){\n            int a=rng()%M, b=rng()%M;\n            if(a==b) continue;\n            swap(order[a],order[b]);\n            int nc = evaluate(order);\n            if(nc < curCost){\n                curCost = nc;\n                if(nc<bestCost){bestCost=nc; bestOrder=order;}\n            } else {\n                swap(order[a],order[b]);\n            }\n        } else {\n            int L = 2+(rng()%2);\n            if(M-L<1) continue;\n            int a = rng()%(M-L+1);\n            int b = rng()%(M-L+1);\n            if(a==b) continue;\n            vector<int> seg(order.begin()+a, order.begin()+a+L);\n            vector<int> rest;\n            rest.reserve(M-L);\n            for(int i=0;i<M;i++) if(i<a||i>=a+L) rest.push_back(order[i]);\n            int insPos = b; if(insPos>(int)rest.size()) insPos=rest.size();\n            vector<int> newOrd;\n            newOrd.reserve(M);\n            for(int i=0;i<insPos;i++) newOrd.push_back(rest[i]);\n            for(int x:seg) newOrd.push_back(x);\n            for(int i=insPos;i<(int)rest.size();i++) newOrd.push_back(rest[i]);\n            int nc = evaluate(newOrd);\n            if(nc < curCost){\n                order = newOrd;\n                curCost = nc;\n                if(nc<bestCost){bestCost=nc; bestOrder=order;}\n            }\n        }\n    }\n    \n    order = bestOrder;\n    \n    auto typeWordPath = [&](int wj, int ov, int pr, int pc){\n        string& w = words[wj];\n        int len = 5-ov;\n        vector<pair<int,int>> res;\n        if(len<=0) return res;\n        vector<vector<int>> dp(len), par(len);\n        for(int i=0;i<len;i++){\n            int sz = posOf[w[ov+i]-'A'].size();\n            dp[i].assign(sz,INT_MAX);\n            par[i].assign(sz,-1);\n        }\n        auto& p0 = posOf[w[ov]-'A'];\n        for(int k=0;k<(int)p0.size();k++) dp[0][k]=distm(pr,pc,p0[k].first,p0[k].second);\n        for(int i=1;i<len;i++){\n            auto& pp=posOf[w[ov+i-1]-'A'];\n            auto& pc2=posOf[w[ov+i]-'A'];\n            for(int k=0;k<(int)pc2.size();k++){\n                int r=pc2[k].first, c=pc2[k].second;\n                for(int j=0;j<(int)pp.size();j++){\n                    int nc=dp[i-1][j]+distm(pp[j].first,pp[j].second,r,c);\n                    if(nc<dp[i][k]){dp[i][k]=nc;par[i][k]=j;}\n                }\n            }\n        }\n        int best=INT_MAX,bk=-1;\n        for(int k=0;k<(int)dp[len-1].size();k++) if(dp[len-1][k]<best){best=dp[len-1][k];bk=k;}\n        vector<int> idx(len);\n        idx[len-1]=bk;\n        for(int i=len-1;i>0;i--) idx[i-1]=par[i][idx[i]];\n        res.resize(len);\n        for(int i=0;i<len;i++) res[i]=posOf[w[ov+i]-'A'][idx[i]];\n        return res;\n    };\n    \n    vector<pair<int,int>> output;\n    int curR=si, curC=sj;\n    for(int i=0;i<M;i++){\n        int ov = (i==0)?0:overlap[order[i-1]][order[i]];\n        auto path = typeWordPath(order[i], ov, curR, curC);\n        for(auto& p:path) output.push_back(p);\n        if(!path.empty()){ curR=path.back().first; curC=path.back().second; }\n    }\n    \n    for(auto& p:output) cout<<p.first<<\" \"<<p.second<<\"\\n\";\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble EPS;\nvector<vector<pair<int,int>>> polys;\nvector<vector<pair<int,int>>> placements;\nvector<vector<vector<int>>> placement_cells;\n\nstruct Query {\n    vector<int> cells;\n    int result;\n    bool exact;\n};\n\nvector<Query> queries;\ndouble total_cost = 0;\n\nauto START_TIME = chrono::steady_clock::now();\ndouble elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - START_TIME).count();\n}\n\nint drill(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int v; cin >> v;\n    total_cost += 1.0;\n    Query q; q.cells = {i*N+j}; q.result = v; q.exact = true;\n    queries.push_back(q);\n    return v;\n}\n\nint answer(vector<int>& cells) {\n    cout << \"a \" << cells.size();\n    for (int c : cells) cout << \" \" << c/N << \" \" << c%N;\n    cout << endl;\n    cout.flush();\n    int r; cin >> r;\n    return r;\n}\n\nint main() {\n    cin >> N >> M >> EPS;\n    polys.resize(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        polys[k].resize(d);\n        for (int i = 0; i < d; i++) cin >> polys[k][i].first >> polys[k][i].second;\n    }\n    \n    placements.resize(M);\n    placement_cells.resize(M);\n    long long totalConfigs = 1;\n    for (int k = 0; k < M; k++) {\n        int mi = 0, mj = 0;\n        for (auto& p : polys[k]) { mi = max(mi, p.first); mj = max(mj, p.second); }\n        for (int di = 0; di + mi < N; di++) {\n            for (int dj = 0; dj + mj < N; dj++) {\n                placements[k].push_back({di, dj});\n                vector<int> cs;\n                for (auto& p : polys[k]) cs.push_back((p.first+di)*N + (p.second+dj));\n                placement_cells[k].push_back(cs);\n            }\n        }\n        totalConfigs *= (long long)placements[k].size();\n        if (totalConfigs > (long long)1e9) totalConfigs = (long long)1e9;\n    }\n    \n    int NN = N * N;\n    bool smallCase = (totalConfigs <= 50000);\n    \n    if (smallCase) {\n        // Enumerate all configs, precompute grids\n        int nConf = (int)totalConfigs;\n        // store grids as flat array: grids[c * NN + i]\n        vector<unsigned char> grids((size_t)nConf * NN, 0);\n        vector<vector<int>> allConfs;\n        allConfs.reserve(nConf);\n        \n        vector<int> cur(M, 0);\n        function<void(int)> gen = [&](int k) {\n            if (k == M) {\n                int idx = allConfs.size();\n                allConfs.push_back(cur);\n                size_t base = (size_t)idx * NN;\n                for (int kk = 0; kk < M; kk++) {\n                    for (int c : placement_cells[kk][cur[kk]]) {\n                        grids[base + c]++;\n                    }\n                }\n                return;\n            }\n            for (int i = 0; i < (int)placements[k].size(); i++) {\n                cur[k] = i;\n                gen(k+1);\n            }\n        };\n        gen(0);\n        \n        vector<char> alive(nConf, 1);\n        int aliveCount = nConf;\n        // log probabilities uniform; with only exact drills, we just prune\n        \n        int maxQueries = 2*N*N;\n        \n        while ((int)queries.size() < maxQueries - 1 && elapsed() < 2.5) {\n            // Find best config (any alive)\n            int best = -1;\n            for (int c = 0; c < nConf; c++) if (alive[c]) { best = c; break; }\n            if (best == -1) break;\n            \n            // If only one alive, submit\n            if (aliveCount == 1) {\n                size_t base = (size_t)best * NN;\n                vector<int> ans;\n                for (int i = 0; i < NN; i++) if (grids[base + i] > 0) ans.push_back(i);\n                int r = answer(ans);\n                if (r == 1) return 0;\n                alive[best] = 0;\n                aliveCount--;\n                continue;\n            }\n            \n            // Compute cell with most balanced oil probability\n            vector<int> cntOil(NN, 0);\n            for (int c = 0; c < nConf; c++) {\n                if (!alive[c]) continue;\n                size_t base = (size_t)c * NN;\n                for (int i = 0; i < NN; i++) if (grids[base + i] > 0) cntOil[i]++;\n            }\n            \n            int bestCell = -1;\n            int bestDiff = INT_MAX;\n            for (int i = 0; i < NN; i++) {\n                if (cntOil[i] == 0 || cntOil[i] == aliveCount) continue;\n                int diff = abs(2*cntOil[i] - aliveCount);\n                if (diff < bestDiff) { bestDiff = diff; bestCell = i; }\n            }\n            \n            if (bestCell == -1) {\n                // All configs agree on oil positions; submit\n                size_t base = (size_t)best * NN;\n                vector<int> ans;\n                for (int i = 0; i < NN; i++) if (grids[base + i] > 0) ans.push_back(i);\n                int r = answer(ans);\n                if (r == 1) return 0;\n                alive[best] = 0;\n                aliveCount--;\n                continue;\n            }\n            \n            int v = drill(bestCell / N, bestCell % N);\n            // update alive\n            for (int c = 0; c < nConf; c++) {\n                if (!alive[c]) continue;\n                if ((int)grids[(size_t)c * NN + bestCell] != v) {\n                    alive[c] = 0;\n                    aliveCount--;\n                }\n            }\n        }\n        \n        // fallback: answer with best remaining\n        int best = -1;\n        for (int c = 0; c < nConf; c++) if (alive[c]) { best = c; break; }\n        if (best == -1) best = 0;\n        size_t base = (size_t)best * NN;\n        vector<int> ans;\n        for (int i = 0; i < NN; i++) if (grids[base + i] > 0) ans.push_back(i);\n        answer(ans);\n        return 0;\n    }\n    \n    // Large case: drill everything\n    vector<int> ans;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if ((int)queries.size() >= 2*N*N - 1) break;\n            int v = drill(i, j);\n            if (v > 0) ans.push_back(i*N+j);\n        }\n    }\n    answer(ans);\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint W, D, N;\nvector<vector<int>> a;\n\nstruct Rect { int i0,j0,i1,j1; };\n\nlong long solveWithWidths(vector<int>& widths, vector<vector<Rect>>& final_rects) {\n    int C = widths.size();\n    vector<int> xs(C+1, 0);\n    for (int i = 0; i < C; i++) xs[i+1] = xs[i] + widths[i];\n    \n    vector<vector<set<int>>> dividers(D, vector<set<int>>(C));\n    long long deficit = 0;\n    \n    final_rects.assign(D, vector<Rect>(N));\n    \n    for (int d = 0; d < D; d++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        \n        vector<double> load(C, 0);\n        vector<vector<int>> col(C);\n        for (int k : order) {\n            int best = 0;\n            double bestVal = 1e18;\n            for (int c = 0; c < C; c++) {\n                double v = load[c] + (double)a[d][k] / widths[c];\n                if (v < bestVal) { bestVal = v; best = c; }\n            }\n            col[best].push_back(k);\n            load[best] += (double)a[d][k] / widths[best];\n        }\n        \n        for (int c = 0; c < C; c++) {\n            auto& items = col[c];\n            if (items.empty()) continue;\n            int w = widths[c];\n            int m = items.size();\n            if (m > W) return LLONG_MAX;\n            \n            vector<int> h(m);\n            long long total = 0;\n            for (int i = 0; i < m; i++) {\n                h[i] = max(1, (a[d][items[i]] + w - 1) / w);\n                total += h[i];\n            }\n            if (total > W) {\n                long long totA = 0;\n                for (int k : items) totA += a[d][k];\n                if (totA == 0) totA = 1;\n                vector<int> newH(m, 1);\n                int rem = W - m;\n                vector<double> frac(m);\n                for (int i = 0; i < m; i++) {\n                    frac[i] = (double)a[d][items[i]] / totA * rem;\n                }\n                int s = m;\n                for (int i = 0; i < m; i++) {\n                    int add = (int)frac[i];\n                    newH[i] += add;\n                    s += add;\n                }\n                vector<pair<double,int>> fr(m);\n                for (int i = 0; i < m; i++) fr[i] = {frac[i] - (int)frac[i], i};\n                sort(fr.begin(), fr.end(), greater<>());\n                int idx = 0;\n                while (s < W && idx < m) {\n                    newH[fr[idx].second]++;\n                    s++;\n                    idx++;\n                }\n                while (s < W) { newH[m-1]++; s++; }\n                h = newH;\n            }\n            int y = 0;\n            for (int i = 0; i < m; i++) {\n                int yEnd = (i == m-1) ? W : y + h[i];\n                if (yEnd > W) yEnd = W;\n                final_rects[d][items[i]] = {y, xs[c], yEnd, xs[c+1]};\n                if (yEnd < W) dividers[d][c].insert(yEnd);\n                y = yEnd;\n            }\n            for (int idx : items) {\n                auto& r = final_rects[d][idx];\n                long long area = (long long)(r.i1-r.i0)*(r.j1-r.j0);\n                if (area < a[d][idx]) deficit += 100LL * (a[d][idx] - area);\n            }\n        }\n    }\n    \n    long long partCost = 0;\n    for (int d = 1; d < D; d++) {\n        for (int c = 0; c < C; c++) {\n            auto& prev = dividers[d-1][c];\n            auto& cur = dividers[d][c];\n            int w = widths[c];\n            int sd = 0;\n            for (int x : prev) if (!cur.count(x)) sd++;\n            for (int x : cur) if (!prev.count(x)) sd++;\n            partCost += (long long)sd * w;\n        }\n    }\n    \n    return deficit + partCost;\n}\n\n// Fixed partition across all days: 0 partition cost after day 0.\n// Use single column with N rows - each row is k-th rank item on each day.\nlong long solveFixedSingleCol(vector<vector<Rect>>& final_rects) {\n    // Single column of width W, N rows\n    // row r (0-indexed) gets the r-th largest item of each day\n    // height of row r = max over d of (a[d][rank_r] / W) rounded up\n    \n    vector<int> h(N);\n    for (int r = 0; r < N; r++) {\n        int mx = 1;\n        for (int d = 0; d < D; d++) {\n            // sort descending - rank r means (N-1-r)th element in sorted ascending, since a is sorted ascending\n            // a[d] is sorted ascending, so rank r (largest) = a[d][N-1-r]\n            int val = a[d][N-1-r];\n            int req = (val + W - 1) / W;\n            mx = max(mx, req);\n        }\n        h[r] = mx;\n    }\n    long long sum = 0;\n    for (int x : h) sum += x;\n    \n    if (sum > W) {\n        // Scale down - proportional\n        double ratio = (double)W / sum;\n        long long s = 0;\n        for (int& x : h) { x = max(1, (int)(x * ratio)); s += x; }\n        // adjust\n        while (s > W) {\n            int mi = 0;\n            for (int i = 1; i < N; i++) if (h[i] > h[mi]) mi = i;\n            if (h[mi] > 1) { h[mi]--; s--; } else break;\n        }\n        while (s < W) { h[N-1]++; s++; }\n    } else {\n        h[N-1] += (W - sum);\n    }\n    \n    final_rects.assign(D, vector<Rect>(N));\n    long long deficit = 0;\n    for (int d = 0; d < D; d++) {\n        // item at rank r (largest first) gets row r\n        // items sorted ascending in a[d], so sort indices\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        \n        int y = 0;\n        for (int r = 0; r < N; r++) {\n            int yEnd = y + h[r];\n            if (r == N-1) yEnd = W;\n            int k = order[r];\n            final_rects[d][k] = {y, 0, yEnd, W};\n            long long area = (long long)(yEnd - y) * W;\n            if (area < a[d][k]) deficit += 100LL * (a[d][k] - area);\n            y = yEnd;\n        }\n    }\n    return deficit;\n}\n\n// Multi-column fixed: use C columns with widths, N items distributed via rank rotation\nlong long solveFixedCols(vector<int>& widths, vector<vector<Rect>>& final_rects) {\n    int C = widths.size();\n    if (C > N) return LLONG_MAX;\n    vector<int> xs(C+1, 0);\n    for (int i = 0; i < C; i++) xs[i+1] = xs[i] + widths[i];\n    \n    // Distribute N ranks to C columns\n    // slot[c] = list of ranks assigned (in order from top)\n    // Strategy: assign ranks to columns so each column's total max area is balanced\n    // Simple: snake / round-robin by (width desc): largest items to widest column\n    \n    vector<int> colOrder(C);\n    iota(colOrder.begin(), colOrder.end(), 0);\n    sort(colOrder.begin(), colOrder.end(), [&](int x, int y){ return widths[x] > widths[y]; });\n    \n    vector<vector<int>> colRanks(C); // colRanks[c] = list of ranks (0=largest)\n    // round-robin\n    for (int r = 0; r < N; r++) {\n        colRanks[colOrder[r % C]].push_back(r);\n    }\n    \n    // For each column, for each slot, compute required height = max across days of ceil(a[d][corresponding item]/w)\n    vector<vector<int>> slotH(C);\n    for (int c = 0; c < C; c++) {\n        int w = widths[c];\n        int ns = colRanks[c].size();\n        slotH[c].assign(ns, 1);\n        for (int s = 0; s < ns; s++) {\n            int rank = colRanks[c][s];\n            int mx = 1;\n            for (int d = 0; d < D; d++) {\n                int val = a[d][N-1-rank];\n                int req = (val + w - 1) / w;\n                mx = max(mx, req);\n            }\n            slotH[c][s] = mx;\n        }\n    }\n    \n    // Adjust each column's slotH to sum to W\n    long long deficit = 0;\n    for (int c = 0; c < C; c++) {\n        int ns = slotH[c].size();\n        if (ns == 0) continue;\n        long long sum = 0;\n        for (int x : slotH[c]) sum += x;\n        if (sum > W) {\n            double ratio = (double)W / sum;\n            long long s = 0;\n            for (int& x : slotH[c]) { x = max(1, (int)(x * ratio)); s += x; }\n            while (s > W) {\n                int mi = 0;\n                for (int i = 1; i < ns; i++) if (slotH[c][i] > slotH[c][mi]) mi = i;\n                if (slotH[c][mi] > 1) { slotH[c][mi]--; s--; } else break;\n            }\n            while (s < W) { slotH[c][ns-1]++; s++; }\n        } else {\n            slotH[c][ns-1] += (W - sum);\n        }\n    }\n    \n    final_rects.assign(D, vector<Rect>(N));\n    for (int d = 0; d < D; d++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        // order[r] = item index at rank r (r=0 largest)\n        \n        for (int c = 0; c < C; c++) {\n            int y = 0;\n            int ns = colRanks[c].size();\n            for (int s = 0; s < ns; s++) {\n                int yEnd = y + slotH[c][s];\n                if (s == ns-1) yEnd = W;\n                int rank = colRanks[c][s];\n                int k = order[rank];\n                final_rects[d][k] = {y, xs[c], yEnd, xs[c+1]};\n                long long area = (long long)(yEnd - y) * widths[c];\n                if (area < a[d][k]) deficit += 100LL * (a[d][k] - area);\n                y = yEnd;\n            }\n        }\n    }\n    return deficit;\n}\n\nint main() {\n    cin >> W >> D >> N;\n    a.assign(D, vector<int>(N));\n    for (int d = 0; d < D; d++) for (int k = 0; k < N; k++) cin >> a[d][k];\n    \n    long long bestCost = LLONG_MAX;\n    vector<vector<Rect>> bestRects;\n    \n    auto tryResult = [&](long long cost, vector<vector<Rect>>& rects) {\n        if (cost < bestCost) {\n            bestCost = cost;\n            bestRects = rects;\n        }\n    };\n    \n    int maxC = min(N, 25);\n    \n    // Try dynamic column solver with equal widths\n    for (int C = 1; C <= maxC; C++) {\n        vector<int> widths(C);\n        int base = W / C, extra = W % C;\n        for (int i = 0; i < C; i++) widths[i] = base + (i < extra ? 1 : 0);\n        vector<vector<Rect>> rects;\n        long long cost = solveWithWidths(widths, rects);\n        tryResult(cost, rects);\n    }\n    \n    // Try fixed single column\n    {\n        vector<vector<Rect>> rects;\n        long long cost = solveFixedSingleCol(rects);\n        tryResult(cost, rects);\n    }\n    \n    // Try fixed multi-column equal widths\n    for (int C = 2; C <= maxC; C++) {\n        vector<int> widths(C);\n        int base = W / C, extra = W % C;\n        for (int i = 0; i < C; i++) widths[i] = base + (i < extra ? 1 : 0);\n        vector<vector<Rect>> rects;\n        long long cost = solveFixedCols(widths, rects);\n        tryResult(cost, rects);\n    }\n    \n    // Random search over column widths with fixed solver\n    mt19937 rng(42);\n    auto clock_start = chrono::steady_clock::now();\n    auto get_time = [&](){\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - clock_start).count();\n    };\n    \n    int trials = 0;\n    while (get_time() < 2500 && trials < 2000) {\n        trials++;\n        int C = 2 + rng() % (maxC - 1);\n        if (C > N) continue;\n        set<int> bs;\n        int guard = 0;\n        while ((int)bs.size() < C-1 && guard < 1000) {\n            int x = 10 + rng() % (W - 20);\n            bs.insert(x);\n            guard++;\n        }\n        if ((int)bs.size() < C-1) continue;\n        vector<int> breaks(bs.begin(), bs.end());\n        vector<int> widths(C);\n        int prev = 0;\n        for (int i = 0; i < C-1; i++) {\n            widths[i] = breaks[i] - prev;\n            prev = breaks[i];\n        }\n        widths[C-1] = W - prev;\n        bool ok = true;\n        for (int w : widths) if (w < 5) { ok = false; break; }\n        if (!ok) continue;\n        \n        vector<vector<Rect>> rects;\n        long long cost = solveFixedCols(widths, rects);\n        tryResult(cost, rects);\n        \n        if (trials % 3 == 0) {\n            long long cost2 = solveWithWidths(widths, rects);\n            tryResult(cost2, rects);\n        }\n    }\n    \n    if (bestRects.empty()) {\n        bestRects.assign(D, vector<Rect>(N));\n        for (int d = 0; d < D; d++) for (int k = 0; k < N; k++)\n            bestRects[d][k] = {k, 0, k+1, W};\n    }\n    \n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            auto& r = bestRects[d][k];\n            if (r.i0 >= r.i1 || r.j0 >= r.j1) r = {0, 0, 1, 1};\n            cout << r.i0 << \" \" << r.j0 << \" \" << r.i1 << \" \" << r.j1 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nconst long long MOD = 998244353;\n\nint N, M, K;\nlong long a0[9][9];\nlong long s[20][3][3];\n\nconst int MAX_K = 6;\n\nstruct Combo {\n    int8_t stamps[MAX_K];\n    int8_t k;\n    long long mat[9];\n};\n\nvector<Combo> combos_by_k[MAX_K+1];\n\nvoid gen_combos(){\n    Combo zero;\n    for(int i=0;i<MAX_K;i++) zero.stamps[i] = 0;\n    zero.k = 0;\n    for(int i=0;i<9;i++) zero.mat[i] = 0;\n    combos_by_k[0].push_back(zero);\n    for(int k=1; k<=MAX_K; k++){\n        for(auto& c : combos_by_k[k-1]){\n            int start = (k==1) ? 0 : c.stamps[k-2];\n            for(int m=start; m<M; m++){\n                Combo nc = c;\n                nc.stamps[k-1] = m;\n                nc.k = k;\n                for(int i=0;i<3;i++) for(int j=0;j<3;j++){\n                    nc.mat[i*3+j] += s[m][i][j];\n                }\n                combos_by_k[k].push_back(nc);\n            }\n        }\n    }\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    cin >> N >> M >> K;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>a0[i][j];\n    for(int m=0;m<M;m++) for(int i=0;i<3;i++) for(int j=0;j<3;j++) cin>>s[m][i][j];\n    \n    gen_combos();\n    \n    auto solve = [&](long long lambda) -> pair<long long, vector<tuple<int,int,int>>> {\n        long long a[9][9];\n        memcpy(a, a0, sizeof(a0));\n        vector<tuple<int,int,int>> ops;\n        int budget = K;\n        \n        for(int p=0;p<=N-3;p++){\n            for(int q=0;q<=N-3;q++){\n                int locked_indices[9];\n                int locked_di[9], locked_dj[9];\n                int nlocked = 0;\n                for(int di=0;di<3;di++) for(int dj=0;dj<3;dj++){\n                    int i = p+di, j = q+dj;\n                    if(min(6,i)==p && min(6,j)==q){\n                        locked_indices[nlocked] = di*3+dj;\n                        locked_di[nlocked] = di;\n                        locked_dj[nlocked] = dj;\n                        nlocked++;\n                    }\n                }\n                \n                int max_k;\n                if(nlocked == 1) max_k = 3;\n                else if(nlocked == 3) max_k = 4;\n                else max_k = MAX_K;\n                if(max_k > budget) max_k = budget;\n                if(max_k < 0) max_k = 0;\n                \n                long long curv[9];\n                for(int ii=0; ii<nlocked; ii++){\n                    curv[ii] = a[p+locked_di[ii]][q+locked_dj[ii]];\n                }\n                \n                int best_k = 0;\n                long long best_sc = LLONG_MIN;\n                const Combo* best_combo = &combos_by_k[0][0];\n                \n                for(int k=0; k<=max_k; k++){\n                    long long kl = (long long)k * lambda;\n                    for(auto& c : combos_by_k[k]){\n                        long long sum = 0;\n                        for(int ii=0; ii<nlocked; ii++){\n                            sum += (curv[ii] + c.mat[locked_indices[ii]]) % MOD;\n                        }\n                        long long sc = sum - kl;\n                        if(sc > best_sc){\n                            best_sc = sc;\n                            best_k = k;\n                            best_combo = &c;\n                        }\n                    }\n                }\n                \n                for(int ii=0; ii<best_k; ii++){\n                    int m = best_combo->stamps[ii];\n                    ops.push_back({m,p,q});\n                    for(int i=0;i<3;i++) for(int j=0;j<3;j++){\n                        a[p+i][q+j] = (a[p+i][q+j] + s[m][i][j]) % MOD;\n                    }\n                    budget--;\n                }\n            }\n        }\n        \n        long long score = 0;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++) score += a[i][j];\n        return {score, ops};\n    };\n    \n    long long best_score = -1;\n    vector<tuple<int,int,int>> best_ops;\n    \n    int num_lambdas = 60;\n    for(int step=0; step<=num_lambdas; step++){\n        long long lambda = (long long)((double)MOD * 0.4 * step / num_lambdas);\n        auto [sc, ops] = solve(lambda);\n        if((int)ops.size() <= K && sc > best_score){\n            best_score = sc;\n            best_ops = ops;\n        }\n    }\n    \n    cout << best_ops.size() << \"\\n\";\n    for(auto& [m,p,q] : best_ops) cout << m << \" \" << p << \" \" << q << \"\\n\";\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint A[5][5];\nint grid_[5][5];\nint cr_[5], cc_[5];\nbool hold_[5];\nint held_[5];\nint nin_[5];\nint nout_[5];\nvector<string> out_;\nint totalDisp = 0;\nint turns_ = 0;\n\nvoid doStep(const string& a) {\n    for(int i=0;i<5;i++){\n        if(nin_[i]>=5)continue;\n        if(grid_[i][0]!=-1)continue;\n        bool h=false;\n        for(int k=0;k<5;k++) if(cr_[k]==i&&cc_[k]==0&&hold_[k]){h=true;break;}\n        if(h)continue;\n        grid_[i][0]=A[i][nin_[i]++];\n    }\n    int nr[5], nc[5];\n    for(int i=0;i<5;i++){nr[i]=cr_[i];nc[i]=cc_[i];}\n    for(int i=0;i<5;i++){\n        if(cr_[i]==-1)continue;\n        char ch=a[i];\n        if(ch=='U')nr[i]--;\n        else if(ch=='D')nr[i]++;\n        else if(ch=='L')nc[i]--;\n        else if(ch=='R')nc[i]++;\n    }\n    for(int i=0;i<5;i++){cr_[i]=nr[i];cc_[i]=nc[i];}\n    for(int i=0;i<5;i++){\n        if(cr_[i]==-1)continue;\n        char ch=a[i];\n        if(ch=='P'){\n            held_[i]=grid_[cr_[i]][cc_[i]];\n            grid_[cr_[i]][cc_[i]]=-1;\n            hold_[i]=true;\n        } else if(ch=='Q'){\n            grid_[cr_[i]][cc_[i]]=held_[i];\n            held_[i]=-1;\n            hold_[i]=false;\n        } else if(ch=='B'){\n            cr_[i]=-1;cc_[i]=-1;\n        }\n    }\n    for(int i=0;i<5;i++) out_[i]+=a[i];\n    turns_++;\n    for(int i=0;i<5;i++){\n        if(grid_[i][4]!=-1){\n            int v=grid_[i][4];\n            grid_[i][4]=-1;\n            totalDisp++;\n            if(v/5==i) nout_[i]++;\n        }\n    }\n}\n\nvoid moveLarge(int tr, int tc) {\n    int guard=0;\n    while((cr_[0]!=tr || cc_[0]!=tc) && turns_<9950 && guard<200) {\n        string a=\".....\"; \n        char ch='.';\n        if(cr_[0]<tr) ch='D';\n        else if(cr_[0]>tr) ch='U';\n        else if(cc_[0]<tc) ch='R';\n        else if(cc_[0]>tc) ch='L';\n        a[0]=ch;\n        doStep(a);\n        guard++;\n    }\n}\n\nvoid P0(){ string a=\".....\"; a[0]='P'; doStep(a); }\nvoid Q0(){ string a=\".....\"; a[0]='Q'; doStep(a); }\n\nint main(){\n    int N; cin>>N;\n    for(int i=0;i<5;i++) for(int j=0;j<5;j++) cin>>A[i][j];\n    for(int i=0;i<5;i++)for(int j=0;j<5;j++)grid_[i][j]=-1;\n    for(int i=0;i<5;i++){cr_[i]=i;cc_[i]=0;hold_[i]=false;held_[i]=-1;nin_[i]=0;nout_[i]=0;}\n    out_.assign(5,\"\");\n    \n    // Phase 1: 2-pass staging. 10 turns.\n    doStep(\"PPPPP\");  // T0: pick A[i][0]\n    doStep(\"RRRRR\");  // T1: to (i,1) holding\n    doStep(\"RRRRR\");  // T2: to (i,2) holding, (i,0) gets A[i][1]\n    doStep(\"QQQQQ\");  // T3: drop at (i,2)\n    doStep(\"LLLLL\");  // T4: to (i,1) empty\n    doStep(\"LLLLL\");  // T5: to (i,0) on A[i][1]\n    doStep(\"PPPPP\");  // T6: pick A[i][1]\n    doStep(\"RRRRR\");  // T7: to (i,1) holding empty\n    doStep(\"QQQQQ\");  // T8: drop at (i,1), (i,0) gets A[i][2]\n    doStep(\".BBBB\"); // T9: bomb small cranes, large dots\n    \n    int stuck=0;\n    while(totalDisp < 25 && turns_ < 9950) {\n        bool found=false;\n        int tr=-1,tc=-1,tgate=-1;\n        for(int g=0;g<5 && !found;g++){\n            if(nout_[g]>=5) continue;\n            int want = g*5 + nout_[g];\n            for(int r=0;r<5 && !found;r++) for(int c=0;c<5 && !found;c++) {\n                if(grid_[r][c]==want){\n                    tr=r;tc=c;tgate=g;found=true;\n                }\n            }\n        }\n        if(found) {\n            moveLarge(tr,tc);\n            P0();\n            moveLarge(tgate,4);\n            Q0();\n            stuck=0;\n        } else {\n            int sr=-1;\n            for(int i=0;i<5;i++) if(grid_[i][0]!=-1){sr=i;break;}\n            if(sr==-1) {\n                doStep(\".....\");\n                stuck++;\n                if(stuck>50) break;\n                continue;\n            }\n            int v = grid_[sr][0];\n            int tgt_row = v/5;\n            int dr=-1, dc=-1;\n            int colPref[] = {3,2,1};\n            for(int ci=0;ci<3;ci++){\n                int c=colPref[ci];\n                if(grid_[tgt_row][c]==-1){dr=tgt_row;dc=c;break;}\n            }\n            if(dr==-1) {\n                for(int ci=0;ci<3 && dr==-1;ci++){\n                    int c=colPref[ci];\n                    for(int r=0;r<5;r++) if(grid_[r][c]==-1){dr=r;dc=c;break;}\n                }\n            }\n            if(dr==-1){\n                doStep(\".....\");\n                stuck++;\n                if(stuck>50) break;\n                continue;\n            }\n            moveLarge(sr,0);\n            P0();\n            moveLarge(dr,dc);\n            Q0();\n            stuck=0;\n        }\n    }\n    \n    for(int i=0;i<5;i++) cout<<out_[i]<<\"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint H0[25][25];\n\nstruct Sim {\n    int h[25][25];\n    vector<string> ops;\n    int cr=0, cc=0;\n    long long load=0;\n    long long cost=0;\n    \n    void init(){\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)h[i][j]=H0[i][j];\n        ops.clear(); cr=cc=0; load=0; cost=0;\n    }\n    void mv(char d){\n        ops.push_back(string(1,d));\n        cost += 100+load;\n        if(d=='U')cr--; else if(d=='D')cr++; else if(d=='L')cc--; else cc++;\n    }\n    void doLoad(long long d){ if(d<=0)return; ops.push_back(\"+\"+to_string(d)); h[cr][cc]-=d; load+=d; cost+=d;}\n    void doUnload(long long d){ if(d<=0)return; ops.push_back(\"-\"+to_string(d)); h[cr][cc]+=d; load-=d; cost+=d;}\n    void moveTo(int tr,int tc){\n        while(cr!=tr){ if(cr<tr)mv('D'); else mv('U'); }\n        while(cc!=tc){ if(cc<tc)mv('R'); else mv('L'); }\n    }\n};\n\nlong long runConfig(bool rowMajor, bool startBot, bool startRight, Sim& out){\n    Sim s; s.init();\n    vector<pair<int,int>> path;\n    if(rowMajor){\n        for(int ii=0;ii<N;ii++){\n            int i = startBot ? N-1-ii : ii;\n            bool rev = (ii%2==1) ^ startRight;\n            if(!rev) for(int j=0;j<N;j++) path.push_back({i,j});\n            else for(int j=N-1;j>=0;j--) path.push_back({i,j});\n        }\n    } else {\n        for(int jj=0;jj<N;jj++){\n            int j = startRight ? N-1-jj : jj;\n            bool rev = (jj%2==1) ^ startBot;\n            if(!rev) for(int i=0;i<N;i++) path.push_back({i,j});\n            else for(int i=N-1;i>=0;i--) path.push_back({i,j});\n        }\n    }\n    \n    for(int iter=0;iter<20;iter++){\n        bool any=false;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(s.h[i][j]!=0){any=true;break;}\n        if(!any)break;\n        if(iter%2==0){\n            for(auto& p:path){\n                int r=p.first,c=p.second;\n                s.moveTo(r,c);\n                if(s.h[r][c]>0) s.doLoad(s.h[r][c]);\n                else if(s.h[r][c]<0) s.doUnload(min(s.load,(long long)-s.h[r][c]));\n            }\n        } else {\n            for(int i=(int)path.size()-1;i>=0;i--){\n                int r=path[i].first,c=path[i].second;\n                s.moveTo(r,c);\n                if(s.h[r][c]>0) s.doLoad(s.h[r][c]);\n                else if(s.h[r][c]<0) s.doUnload(min(s.load,(long long)-s.h[r][c]));\n            }\n        }\n    }\n    out = s;\n    return s.cost;\n}\n\nint main(){\n    cin>>N;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>H0[i][j];\n    \n    Sim best, tmp;\n    long long bestCost = LLONG_MAX;\n    for(int rm=0;rm<2;rm++)for(int sb=0;sb<2;sb++)for(int sr=0;sr<2;sr++){\n        long long c = runConfig(rm,sb,sr,tmp);\n        if(c < bestCost){ bestCost=c; best=tmp; }\n    }\n    for(auto&o:best.ops) cout<<o<<\"\\n\";\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, T, SC;\nvector<vector<int>> X;\nmt19937 rng(12345);\n\ninline int pairScore(int a, int b) {\n    int s = 0;\n    for (int l = 0; l < M; l++) s += max(X[a][l], X[b][l]);\n    return s;\n}\n\nint totalScore(vector<vector<int>>& A) {\n    int s = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            if (j+1 < N) s += pairScore(A[i][j], A[i][j+1]);\n            if (i+1 < N) s += pairScore(A[i][j], A[i+1][j]);\n        }\n    return s;\n}\n\nint deltaSwap(vector<vector<int>>& A, int i1, int j1, int i2, int j2) {\n    int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};\n    auto contrib = [&](int i, int j, int other_i, int other_j) {\n        int total = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = i+dr[d], nj = j+dc[d];\n            if (ni<0||ni>=N||nj<0||nj>=N) continue;\n            if (ni==other_i && nj==other_j) continue;\n            total += pairScore(A[i][j], A[ni][nj]);\n        }\n        return total;\n    };\n    int before = contrib(i1,j1,i2,j2) + contrib(i2,j2,i1,j1);\n    bool adj = (abs(i1-i2)+abs(j1-j2)==1);\n    if (adj) before += pairScore(A[i1][j1], A[i2][j2]);\n    swap(A[i1][j1], A[i2][j2]);\n    int after = contrib(i1,j1,i2,j2) + contrib(i2,j2,i1,j1);\n    if (adj) after += pairScore(A[i1][j1], A[i2][j2]);\n    swap(A[i1][j1], A[i2][j2]);\n    return after - before;\n}\n\nint main() {\n    cin >> N >> M >> T;\n    SC = 2*N*(N-1);\n    X.assign(SC, vector<int>(M));\n    for (int i = 0; i < SC; i++)\n        for (int j = 0; j < M; j++) cin >> X[i][j];\n    \n    for (int t = 0; t < T; t++) {\n        vector<int> Xmax(M, 0);\n        for (int k = 0; k < SC; k++)\n            for (int l = 0; l < M; l++) Xmax[l] = max(Xmax[l], X[k][l]);\n        \n        vector<double> score(SC, 0);\n        for (int k = 0; k < SC; k++) {\n            for (int l = 0; l < M; l++) {\n                if (Xmax[l] > 0) {\n                    double r = (double)X[k][l] / Xmax[l];\n                    score[k] += r * r * Xmax[l];\n                }\n            }\n        }\n        \n        vector<int> idx(SC);\n        iota(idx.begin(), idx.end(), 0);\n        sort(idx.begin(), idx.end(), [&](int a, int b){ return score[a] > score[b]; });\n        vector<int> chosen(idx.begin(), idx.begin() + N*N);\n        \n        set<int> chosenSet(chosen.begin(), chosen.end());\n        for (int l = 0; l < M; l++) {\n            vector<int> maxSeeds;\n            for (int k = 0; k < SC; k++) if (X[k][l] == Xmax[l]) maxSeeds.push_back(k);\n            bool found = false;\n            for (int k : maxSeeds) if (chosenSet.count(k)) { found = true; break; }\n            if (!found && !maxSeeds.empty()) {\n                int best = maxSeeds[0];\n                for (int k : maxSeeds) if (score[k] > score[best]) best = k;\n                int worst = -1; double worstS = 1e18;\n                for (int c : chosen) {\n                    bool isUnique = false;\n                    for (int ll = 0; ll < M; ll++) {\n                        if (X[c][ll] == Xmax[ll]) {\n                            int cnt = 0;\n                            for (int kk : chosen) if (X[kk][ll] == Xmax[ll]) cnt++;\n                            if (cnt == 1) { isUnique = true; break; }\n                        }\n                    }\n                    if (isUnique) continue;\n                    if (score[c] < worstS) { worstS = score[c]; worst = c; }\n                }\n                if (worst >= 0) {\n                    auto it = find(chosen.begin(), chosen.end(), worst);\n                    *it = best;\n                    chosenSet.erase(worst); chosenSet.insert(best);\n                }\n            }\n        }\n        \n        sort(chosen.begin(), chosen.end(), [&](int a, int b){ return score[a] > score[b]; });\n        \n        vector<pair<int,int>> cells;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            int deg = (i>0)+(i<N-1)+(j>0)+(j<N-1);\n            cells.push_back({-deg, i*N+j});\n        }\n        sort(cells.begin(), cells.end());\n        \n        vector<vector<int>> A(N, vector<int>(N));\n        for (int c = 0; c < N*N; c++) {\n            int p = cells[c].second;\n            A[p/N][p%N] = chosen[c];\n        }\n        \n        int curScore = totalScore(A);\n        int bestScore = curScore;\n        vector<vector<int>> bestA = A;\n        \n        auto start = chrono::steady_clock::now();\n        double timeLimit = 0.18;\n        int iters = 0;\n        double T0 = 40.0, T1 = 0.3;\n        \n        while (true) {\n            iters++;\n            if ((iters & 2047) == 0) {\n                auto now = chrono::steady_clock::now();\n                double elapsed = chrono::duration<double>(now-start).count();\n                if (elapsed > timeLimit) break;\n            }\n            double progress = min(1.0, (double)iters / 250000.0);\n            double temp = T0 * pow(T1/T0, progress);\n            \n            int p1 = rng() % (N*N);\n            int p2 = rng() % (N*N);\n            if (p1 == p2) continue;\n            int i1=p1/N, j1=p1%N, i2=p2/N, j2=p2%N;\n            int delta = deltaSwap(A, i1, j1, i2, j2);\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else {\n                double p = exp(delta / temp);\n                if ((double)(rng() % 1000000) / 1000000.0 < p) accept = true;\n            }\n            if (accept) {\n                swap(A[i1][j1], A[i2][j2]);\n                curScore += delta;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestA = A;\n                }\n            }\n        }\n        \n        A = bestA;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << A[i][j];\n                cout << (j==N-1 ? '\\n' : ' ');\n            }\n        }\n        cout.flush();\n        \n        for (int i = 0; i < SC; i++)\n            for (int j = 0; j < M; j++) cin >> X[i][j];\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V, Vp;\nint dx[4] = {0, 1, 0, -1};\nint dy[4] = {1, 0, -1, 0};\n\nint main() {\n    cin >> N >> M >> V;\n    vector<string> sg(N), tg(N);\n    for (auto& s : sg) cin >> s;\n    for (auto& s : tg) cin >> s;\n    \n    vector<vector<int>> has_(N, vector<int>(N, 0));\n    vector<vector<int>> isTarget(N, vector<int>(N, 0));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        has_[i][j] = sg[i][j]=='1';\n        isTarget[i][j] = tg[i][j]=='1';\n    }\n    \n    Vp = min(V, 5);\n    int nFingers = Vp - 1;\n    \n    cout << Vp << \"\\n\";\n    for (int i = 1; i < Vp; i++) cout << 0 << \" \" << 1 << \"\\n\";\n    \n    int rx = N/2, ry = N/2;\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<int> fdir(nFingers, 0);\n    vector<int> fhold(nFingers, 0);\n    \n    vector<string> ops;\n    \n    auto rotCost = [](int a, int b) {\n        return min((a-b+4)%4, (b-a+4)%4);\n    };\n    \n    auto doTurn = [&](char moveC, vector<char> rotC) {\n        if (moveC == 'U') rx--;\n        else if (moveC == 'D') rx++;\n        else if (moveC == 'L') ry--;\n        else if (moveC == 'R') ry++;\n        for (int i = 0; i < nFingers; i++) {\n            if (rotC[i] == 'R') fdir[i] = (fdir[i]+1)%4;\n            else if (rotC[i] == 'L') fdir[i] = (fdir[i]+3)%4;\n        }\n        vector<bool> actuallyP(nFingers, false);\n        for (int i = 0; i < nFingers; i++) {\n            int fx = rx + dx[fdir[i]], fy = ry + dy[fdir[i]];\n            if (fx<0||fx>=N||fy<0||fy>=N) continue;\n            if (fhold[i] == 0) {\n                if (has_[fx][fy] && !isTarget[fx][fy]) {\n                    has_[fx][fy] = 0;\n                    fhold[i] = 1;\n                    actuallyP[i] = true;\n                }\n            } else {\n                if (!has_[fx][fy] && isTarget[fx][fy]) {\n                    has_[fx][fy] = 1;\n                    fhold[i] = 0;\n                    actuallyP[i] = true;\n                }\n            }\n        }\n        string s(2*Vp, '.');\n        if (moveC != 0) s[0] = moveC;\n        for (int i = 0; i < nFingers; i++) if (rotC[i]) s[1+i] = rotC[i];\n        for (int i = 0; i < nFingers; i++) if (actuallyP[i]) s[Vp+1+i] = 'P';\n        ops.push_back(s);\n    };\n    \n    while (true) {\n        int srcCnt = 0, tgtCnt = 0;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (has_[i][j] && !isTarget[i][j]) srcCnt++;\n            if (!has_[i][j] && isTarget[i][j]) tgtCnt++;\n        }\n        int nHolding = 0;\n        for (int i = 0; i < nFingers; i++) nHolding += fhold[i];\n        \n        if (srcCnt == 0 && nHolding == 0) break;\n        if ((int)ops.size() > 95000) break;\n        \n        int bestCost = INT_MAX;\n        int bestType = -1;\n        int bestFinger = -1, bestRx=rx, bestRy=ry, bestD=0;\n        \n        if (nHolding < nFingers && srcCnt > 0) {\n            for (int fi = 0; fi < nFingers; fi++) {\n                if (fhold[fi]) continue;\n                for (int sx = 0; sx < N; sx++) for (int sy = 0; sy < N; sy++) {\n                    if (!has_[sx][sy] || isTarget[sx][sy]) continue;\n                    for (int d = 0; d < 4; d++) {\n                        int nrx = sx - dx[d];\n                        int nry = sy - dy[d];\n                        if (nrx<0||nrx>=N||nry<0||nry>=N) continue;\n                        int mv = abs(nrx-rx)+abs(nry-ry);\n                        int rot = rotCost(fdir[fi], d);\n                        int cost = max(mv, rot);\n                        if (cost == 0) cost = 1;\n                        if (cost < bestCost) {\n                            bestCost = cost; bestType = 0;\n                            bestFinger = fi; bestRx = nrx; bestRy = nry; bestD = d;\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (nHolding > 0 && tgtCnt > 0) {\n            for (int fi = 0; fi < nFingers; fi++) {\n                if (!fhold[fi]) continue;\n                for (int tx = 0; tx < N; tx++) for (int ty = 0; ty < N; ty++) {\n                    if (has_[tx][ty] || !isTarget[tx][ty]) continue;\n                    for (int d = 0; d < 4; d++) {\n                        int nrx = tx - dx[d];\n                        int nry = ty - dy[d];\n                        if (nrx<0||nrx>=N||nry<0||nry>=N) continue;\n                        int mv = abs(nrx-rx)+abs(nry-ry);\n                        int rot = rotCost(fdir[fi], d);\n                        int cost = max(mv, rot);\n                        if (cost == 0) cost = 1;\n                        if (cost < bestCost) {\n                            bestCost = cost; bestType = 1;\n                            bestFinger = fi; bestRx = nrx; bestRy = nry; bestD = d;\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (bestType == -1) break;\n        \n        int mv_dx = bestRx - rx, mv_dy = bestRy - ry;\n        int rot_diff = (bestD - fdir[bestFinger] + 4) % 4;\n        int cw = 0, ccw = 0;\n        if (rot_diff == 1) cw = 1;\n        else if (rot_diff == 2) cw = 2;\n        else if (rot_diff == 3) ccw = 1;\n        int mv_steps = abs(mv_dx) + abs(mv_dy);\n        int rot_steps = cw + ccw;\n        int turns = max(mv_steps, rot_steps);\n        if (turns == 0) turns = 1;\n        \n        vector<char> mvSeq, rotSeq;\n        for (int i = 0; i < abs(mv_dx); i++) mvSeq.push_back(mv_dx>0?'D':'U');\n        for (int i = 0; i < abs(mv_dy); i++) mvSeq.push_back(mv_dy>0?'R':'L');\n        for (int i = 0; i < cw; i++) rotSeq.push_back('R');\n        for (int i = 0; i < ccw; i++) rotSeq.push_back('L');\n        \n        for (int i = 0; i < turns; i++) {\n            char mc = i < (int)mvSeq.size() ? mvSeq[i] : 0;\n            vector<char> rc(nFingers, 0);\n            if (i < (int)rotSeq.size()) rc[bestFinger] = rotSeq[i];\n            doTurn(mc, rc);\n        }\n    }\n    \n    for (auto& o : ops) cout << o << \"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N; scanf(\"%d\", &N);\n    vector<int> X(2*N), Y(2*N);\n    for(int i=0;i<2*N;i++) scanf(\"%d %d\",&X[i],&Y[i]);\n    \n    int W = 100, H = 100;\n    int cw = 100000/W, ch = 100000/H;\n    vector<vector<int>> grid(W, vector<int>(H,0));\n    for(int i=0;i<2*N;i++){\n        int c = min(W-1, X[i]/cw);\n        int r = min(H-1, Y[i]/ch);\n        grid[c][r] += (i<N) ? 1 : -1;\n    }\n    \n    vector<int> lo(W), hi(W), val(W);\n    for(int c=0;c<W;c++){\n        int bestSum = INT_MIN, bestL=0, bestR=-1;\n        int curSum=0, curL=0;\n        for(int r=0;r<H;r++){\n            if(curSum <= 0){ curSum = grid[c][r]; curL = r; }\n            else curSum += grid[c][r];\n            if(curSum > bestSum){ bestSum = curSum; bestL=curL; bestR=r; }\n        }\n        lo[c]=bestL; hi[c]=bestR; val[c]=bestSum;\n    }\n    \n    int totBest=INT_MIN, cL=0, cR=0, cs=0, cSL=0;\n    for(int c=0;c<W;c++){\n        if(cs<=0){ cs=val[c]; cSL=c; } else cs+=val[c];\n        if(cs>totBest){ totBest=cs; cL=cSL; cR=c; }\n    }\n    \n    auto build=[&](int cL,int cR)->vector<pair<int,int>>{\n        vector<pair<int,int>> poly;\n        poly.push_back({cL*cw, lo[cL]*ch});\n        for(int c=cL;c<=cR;c++){\n            int yb = lo[c]*ch;\n            if(c>cL && lo[c]!=lo[c-1]){\n                poly.push_back({c*cw, yb});\n            }\n            poly.push_back({(c+1)*cw, yb});\n        }\n        poly.push_back({(cR+1)*cw, (hi[cR]+1)*ch});\n        for(int c=cR;c>=cL;c--){\n            int yt = (hi[c]+1)*ch;\n            if(c<cR && hi[c]!=hi[c+1]){\n                poly.push_back({(c+1)*cw, yt});\n            }\n            poly.push_back({c*cw, yt});\n        }\n        vector<pair<int,int>> out;\n        for(auto& p : poly){\n            if(out.empty() || out.back()!=p) out.push_back(p);\n        }\n        while(out.size()>1 && out.front()==out.back()) out.pop_back();\n        return out;\n    };\n    \n    auto perim=[&](vector<pair<int,int>>& p){\n        long long s=0;\n        int n=p.size();\n        for(int i=0;i<n;i++){\n            auto& a=p[i]; auto& b=p[(i+1)%n];\n            s += abs(a.first-b.first)+abs(a.second-b.second);\n        }\n        return s;\n    };\n    \n    auto out = build(cL,cR);\n    // If perimeter exceeds, shrink or fix: simplest fallback - use bounding rect of best column\n    if(perim(out) > 400000 || out.size() > 1000){\n        // fallback: just one column\n        int bc=cL;\n        for(int c=cL;c<=cR;c++) if(val[c]>val[bc]) bc=c;\n        out = build(bc,bc);\n    }\n    \n    printf(\"%d\\n\",(int)out.size());\n    for(auto& p : out) printf(\"%d %d\\n\", p.first, p.second);\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, sigma;\nvector<int> W_, H_;\nmt19937 rng(42);\n\nstruct Rect { long long x1,y1,x2,y2; };\n\npair<long long,long long> simulate(const vector<tuple<int,int,char,int>>& ops, const vector<int>& ww, const vector<int>& hh) {\n    unordered_map<int, Rect> placed;\n    placed.reserve(ops.size()*2);\n    long long maxX=0, maxY=0;\n    for (auto& [p, r, d, b] : ops) {\n        long long w = r==0 ? ww[p] : hh[p];\n        long long h = r==0 ? hh[p] : ww[p];\n        if (d == 'U') {\n            long long x1 = (b == -1) ? 0 : placed[b].x2;\n            long long x2 = x1 + w;\n            long long y1 = 0;\n            for (auto& kv : placed) {\n                auto& rc = kv.second;\n                if (rc.x2 <= x1 || rc.x1 >= x2) continue;\n                y1 = max(y1, rc.y2);\n            }\n            long long y2 = y1 + h;\n            placed[p] = {x1,y1,x2,y2};\n            maxX = max(maxX, x2); maxY = max(maxY, y2);\n        } else {\n            long long y1 = (b == -1) ? 0 : placed[b].y2;\n            long long y2 = y1 + h;\n            long long x1 = 0;\n            for (auto& kv : placed) {\n                auto& rc = kv.second;\n                if (rc.y2 <= y1 || rc.y1 >= y2) continue;\n                x1 = max(x1, rc.x2);\n            }\n            long long x2 = x1 + w;\n            placed[p] = {x1,y1,x2,y2};\n            maxX = max(maxX, x2); maxY = max(maxY, y2);\n        }\n    }\n    return {maxX, maxY};\n}\n\nvector<tuple<int,int,char,int>> buildRowLayout(long long targetW, const vector<int>& ww, const vector<int>& hh, const vector<int>& rots) {\n    vector<tuple<int,int,char,int>> ops;\n    long long shelfX = 0;\n    int firstOfShelf = -1;\n    int prevOnShelf = -1;\n    for (int i = 0; i < N; i++) {\n        int rot = rots[i];\n        long long w = rot==0 ? ww[i] : hh[i];\n        if (firstOfShelf == -1) {\n            ops.push_back({i, rot, 'U', -1});\n            firstOfShelf = i; prevOnShelf = i; shelfX = w;\n        } else if (shelfX + w <= targetW) {\n            ops.push_back({i, rot, 'U', prevOnShelf});\n            prevOnShelf = i; shelfX += w;\n        } else {\n            ops.push_back({i, rot, 'L', firstOfShelf});\n            firstOfShelf = i; prevOnShelf = i; shelfX = w;\n        }\n    }\n    return ops;\n}\n\nint main() {\n    cin >> N >> T >> sigma;\n    W_.resize(N); H_.resize(N);\n    for (int i = 0; i < N; i++) cin >> W_[i] >> H_[i];\n    \n    long long totalArea = 0;\n    for (int i = 0; i < N; i++) totalArea += (long long)W_[i] * H_[i];\n    long long sideEst = (long long)sqrt((double)totalArea);\n    \n    vector<tuple<int,int,char,int>> best;\n    long long bestScore = LLONG_MAX;\n    \n    auto tryOps = [&](vector<tuple<int,int,char,int>>& ops) {\n        auto [w,h] = simulate(ops, W_, H_);\n        long long sc = w+h;\n        if (sc < bestScore) { bestScore = sc; best = ops; }\n    };\n    \n    for (double f = 0.5; f <= 2.0; f += 0.05) {\n        long long tw = (long long)(sideEst * f);\n        for (int mode = 0; mode < 3; mode++) {\n            vector<int> r(N);\n            for (int i = 0; i < N; i++) {\n                if (mode == 0) r[i] = 0;\n                else if (mode == 1) r[i] = (W_[i] > H_[i]) ? 1 : 0;\n                else r[i] = (W_[i] < H_[i]) ? 1 : 0;\n            }\n            auto ops = buildRowLayout(tw, W_, H_, r);\n            tryOps(ops);\n        }\n    }\n    \n    auto startTime = chrono::steady_clock::now();\n    auto elapsed = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - startTime).count();\n    };\n    \n    double totalTime = 2.5;\n    \n    for (int t = 0; t < T; t++) {\n        double deadline = totalTime * (t+1) / T;\n        while (elapsed() < deadline) {\n            vector<int> r(N);\n            for (int i = 0; i < N; i++) r[i] = rng()%2;\n            double f = 0.5 + (rng()%150)/100.0;\n            long long tw = (long long)(sideEst * f);\n            auto ops = buildRowLayout(tw, W_, H_, r);\n            tryOps(ops);\n        }\n        \n        cout << best.size() << \"\\n\";\n        for (auto& [p,r,d,b] : best) cout << p << \" \" << r << \" \" << d << \" \" << b << \"\\n\";\n        cout.flush();\n        long long wm, hm; cin >> wm >> hm;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, H;\nvector<int> A;\nvector<vector<int>> adj;\nvector<int> par, dep;\nvector<vector<int>> ch;\n\nvoid buildChildren() {\n    ch.assign(N, {});\n    for (int i = 0; i < N; i++) if (par[i] != -1) ch[par[i]].push_back(i);\n}\n\nvoid recomputeDepths() {\n    queue<int> q;\n    for (int i = 0; i < N; i++) {\n        if (par[i] == -1) { dep[i] = 0; q.push(i); }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int c : ch[u]) { dep[c] = dep[u]+1; q.push(c); }\n    }\n}\n\nlong long computeScore() {\n    long long s = 0;\n    for (int i = 0; i < N; i++) s += (long long)(dep[i]+1) * A[i];\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    cin >> N >> M >> H;\n    A.resize(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    adj.assign(N, {});\n    for (int i = 0; i < M; i++) {\n        int u, v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<int> xs(N), ys(N);\n    for (int i = 0; i < N; i++) cin >> xs[i] >> ys[i];\n    \n    par.assign(N, -1);\n    dep.assign(N, 0);\n    buildChildren();\n    \n    auto startTime = chrono::steady_clock::now();\n    auto timeMs = [&]() {\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - startTime).count();\n    };\n    \n    mt19937 rng(12345);\n    \n    vector<char> inSub(N, 0);\n    vector<int> subBuf;\n    vector<int> stk;\n    \n    auto doPass = [&]() -> bool {\n        bool improved = false;\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n        for (int v : order) {\n            subBuf.clear();\n            int sumA = 0, maxD = dep[v];\n            stk.clear(); stk.push_back(v);\n            while (!stk.empty()) {\n                int u = stk.back(); stk.pop_back();\n                subBuf.push_back(u);\n                inSub[u] = 1;\n                sumA += A[u];\n                if (dep[u] > maxD) maxD = dep[u];\n                for (int c : ch[u]) stk.push_back(c);\n            }\n            int relMaxD = maxD - dep[v];\n            \n            int bestP = par[v];\n            long long bestDelta = 0;\n            int curDep = dep[v];\n            int oldP = par[v];\n            \n            if (oldP != -1) {\n                int delta = 0 - curDep;\n                long long change = (long long)delta * sumA;\n                if (change > bestDelta) { bestDelta = change; bestP = -1; }\n            }\n            for (int u : adj[v]) {\n                if (u == oldP) continue;\n                if (inSub[u]) continue;\n                int newDep = dep[u] + 1;\n                if (newDep + relMaxD > H) continue;\n                int delta = newDep - curDep;\n                long long change = (long long)delta * sumA;\n                if (change > bestDelta) { bestDelta = change; bestP = u; }\n            }\n            \n            for (int u : subBuf) inSub[u] = 0;\n            \n            if (bestDelta > 0) {\n                int oldP2 = par[v];\n                par[v] = bestP;\n                int newDep = (bestP == -1 ? 0 : dep[bestP] + 1);\n                int delta = newDep - curDep;\n                if (oldP2 != -1) {\n                    auto& vec = ch[oldP2];\n                    vec.erase(find(vec.begin(), vec.end(), v));\n                }\n                if (bestP != -1) ch[bestP].push_back(v);\n                stk.clear(); stk.push_back(v);\n                while (!stk.empty()) {\n                    int u = stk.back(); stk.pop_back();\n                    dep[u] += delta;\n                    for (int c : ch[u]) stk.push_back(c);\n                }\n                improved = true;\n            }\n        }\n        return improved;\n    };\n    \n    long long bestScore = computeScore();\n    vector<int> bestPar = par;\n    \n    while (timeMs() < 500 && doPass()) {}\n    {\n        long long sc = computeScore();\n        if (sc > bestScore) { bestScore = sc; bestPar = par; }\n    }\n    \n    while (timeMs() < 1800) {\n        int K = 30 + (int)(rng() % 100);\n        for (int t = 0; t < K; t++) {\n            int v = (int)(rng() % N);\n            if (par[v] != -1) {\n                auto& vec = ch[par[v]];\n                auto it = find(vec.begin(), vec.end(), v);\n                if (it != vec.end()) vec.erase(it);\n                par[v] = -1;\n            }\n        }\n        recomputeDepths();\n        \n        while (timeMs() < 1800 && doPass()) {}\n        long long sc2 = computeScore();\n        if (sc2 > bestScore) {\n            bestScore = sc2;\n            bestPar = par;\n        } else {\n            par = bestPar;\n            buildChildren();\n            recomputeDepths();\n        }\n    }\n    \n    par = bestPar;\n    for (int i = 0; i < N; i++) cout << par[i] << \" \\n\"[i==N-1];\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nusing Board = vector<string>;\nstruct Move { char d; int p; };\n\nchar shiftOp(Board& b, char d, int p) {\n    char rem;\n    if (d=='L') { rem=b[p][0]; for(int j=0;j<N-1;j++)b[p][j]=b[p][j+1]; b[p][N-1]='.'; }\n    else if (d=='R') { rem=b[p][N-1]; for(int j=N-1;j>0;j--)b[p][j]=b[p][j-1]; b[p][0]='.'; }\n    else if (d=='U') { rem=b[0][p]; for(int i=0;i<N-1;i++)b[i][p]=b[i+1][p]; b[N-1][p]='.'; }\n    else { rem=b[N-1][p]; for(int i=N-1;i>0;i--)b[i][p]=b[i-1][p]; b[0][p]='.'; }\n    return rem;\n}\n\nint countOni(const Board& b) {\n    int c=0; for(auto&r:b)for(char x:r)if(x=='x')c++; return c;\n}\n\nint heuristic(const Board& b) {\n    int leftF[20], rightF[20], topF[20], botF[20];\n    for (int i = 0; i < N; i++) { leftF[i]=N; rightF[i]=-1; topF[i]=N; botF[i]=-1; }\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (b[i][j]=='o') {\n        if (j < leftF[i]) leftF[i]=j;\n        if (j > rightF[i]) rightF[i]=j;\n        if (i < topF[j]) topF[j]=i;\n        if (i > botF[j]) botF[j]=i;\n    }\n    int h = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (b[i][j]=='x') {\n        int best = 100;\n        if (leftF[i] > j) best = min(best, j+1);\n        if (rightF[i] < j) best = min(best, N-j);\n        if (topF[j] > i) best = min(best, i+1);\n        if (botF[j] < i) best = min(best, N-i);\n        h += best;\n    }\n    return h;\n}\n\nvector<Move> greedyAH(Board b, mt19937& rng, bool randomize, double alpha) {\n    vector<Move> moves;\n    int limit = 4*N*N;\n    while (countOni(b) > 0) {\n        vector<tuple<double,int,int,char,int>> cands;\n        for (char d : {'L','R','U','D'}) {\n            for (int p = 0; p < N; p++) {\n                Board tmp = b;\n                int oniRem = 0;\n                for (int k = 1; k <= N; k++) {\n                    char r = shiftOp(tmp, d, p);\n                    if (r == 'o') break;\n                    if (r == 'x') oniRem++;\n                    if (oniRem > 0) {\n                        int h = heuristic(tmp);\n                        double sc = k + alpha * h;\n                        cands.push_back({sc, k, oniRem, d, p});\n                    }\n                }\n            }\n        }\n        if (cands.empty()) return {};\n        sort(cands.begin(), cands.end());\n        int pick = 0;\n        if (randomize && cands.size() > 1) {\n            int top = min((int)cands.size(), 5);\n            pick = rng() % top;\n        }\n        auto [sc, k, orem, d, p] = cands[pick];\n        for (int i = 0; i < k; i++) {\n            shiftOp(b, d, p);\n            moves.push_back({d, p});\n            if ((int)moves.size() > limit) return {};\n        }\n    }\n    return moves;\n}\n\nvector<Move> greedyR(Board b, mt19937& rng, bool randomize) {\n    vector<Move> moves;\n    int limit = 4*N*N;\n    while (countOni(b) > 0) {\n        vector<tuple<double,int,int,char,int>> cands;\n        for (char d : {'L','R','U','D'}) {\n            for (int p = 0; p < N; p++) {\n                Board tmp = b;\n                int oniRem = 0;\n                for (int k = 1; k <= N; k++) {\n                    char r = shiftOp(tmp, d, p);\n                    if (r == 'o') break;\n                    if (r == 'x') oniRem++;\n                    if (oniRem > 0) {\n                        double sc = (double)k / oniRem;\n                        cands.push_back({sc, k, oniRem, d, p});\n                    }\n                }\n            }\n        }\n        if (cands.empty()) return {};\n        sort(cands.begin(), cands.end());\n        int pick = 0;\n        if (randomize && cands.size() > 1) {\n            int top = min((int)cands.size(), 3);\n            pick = rng() % top;\n        }\n        auto [sc, k, orem, d, p] = cands[pick];\n        for (int i = 0; i < k; i++) {\n            shiftOp(b, d, p);\n            moves.push_back({d, p});\n            if ((int)moves.size() > limit) return {};\n        }\n    }\n    return moves;\n}\n\nvector<Move> hintSol(Board b) {\n    vector<Move> moves;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (b[i][j]=='x') {\n        bool up=true, down=true, left=true, right=true;\n        for (int r = 0; r < i; r++) if (b[r][j]=='o') up=false;\n        for (int r = i+1; r < N; r++) if (b[r][j]=='o') down=false;\n        for (int c = 0; c < j; c++) if (b[i][c]=='o') left=false;\n        for (int c = j+1; c < N; c++) if (b[i][c]=='o') right=false;\n        int bestCost = INT_MAX; char bestDir='?';\n        if (up && 2*(i+1) < bestCost) { bestCost=2*(i+1); bestDir='U'; }\n        if (down && 2*(N-i) < bestCost) { bestCost=2*(N-i); bestDir='D'; }\n        if (left && 2*(j+1) < bestCost) { bestCost=2*(j+1); bestDir='L'; }\n        if (right && 2*(N-j) < bestCost) { bestCost=2*(N-j); bestDir='R'; }\n        int k = bestCost/2;\n        char revD = (bestDir=='U'?'D':bestDir=='D'?'U':bestDir=='L'?'R':'L');\n        int p = (bestDir=='U'||bestDir=='D')?j:i;\n        for (int t = 0; t < k; t++) moves.push_back({bestDir, p});\n        for (int t = 0; t < k; t++) moves.push_back({revD, p});\n    }\n    return moves;\n}\n\nint main() {\n    cin >> N;\n    Board b0(N);\n    for (int i = 0; i < N; i++) cin >> b0[i];\n    \n    auto start = chrono::steady_clock::now();\n    mt19937 rng(42);\n    \n    vector<Move> best = hintSol(b0);\n    \n    auto tryAH = [&](bool rnd, double alpha) {\n        auto m = greedyAH(b0, rng, rnd, alpha);\n        if (!m.empty() && m.size() < best.size()) best = m;\n    };\n    auto tryR = [&](bool rnd) {\n        auto m = greedyR(b0, rng, rnd);\n        if (!m.empty() && m.size() < best.size()) best = m;\n    };\n    \n    tryR(false);\n    for (double a : {0.5, 0.75, 1.0, 1.25, 1.5, 2.0}) tryAH(false, a);\n    \n    int iter = 0;\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-start).count() < 1700) {\n        if (iter % 3 == 0) {\n            tryR(true);\n        } else {\n            double a = 0.3 + (rng()%1000)/1000.0 * 2.0;\n            tryAH(true, a);\n        }\n        iter++;\n    }\n    \n    for (auto& m : best) cout << m.d << \" \" << m.p << \"\\n\";\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, L;\nint Tg[128];\nint a[128], b[128];\nint cnt[128];\nint vp[128];\n\nlong long simError() {\n    for (int i = 0; i < N; i++) { cnt[i]=0; vp[i]=0; }\n    int x = 0;\n    for (int w = 0; w < L; w++) {\n        cnt[x]++;\n        vp[x] ^= 1;\n        x = vp[x] ? a[x] : b[x];\n    }\n    long long e = 0;\n    for (int i = 0; i < N; i++) e += abs(cnt[i] - Tg[i]);\n    return e;\n}\n\nint main() {\n    cin >> N >> L;\n    for (int i = 0; i < N; i++) cin >> Tg[i];\n    \n    vector<int> filled(N, 0);\n    filled[0] = 1;\n    \n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int x, int y){ return Tg[x] > Tg[y]; });\n    \n    for (int x : ord) {\n        int ca = (Tg[x] + 1) / 2;\n        int cb = Tg[x] / 2;\n        int besta = 0, bv = INT_MIN;\n        for (int i = 0; i < N; i++) {\n            int v = Tg[i] - filled[i];\n            if (v > bv) { bv = v; besta = i; }\n        }\n        a[x] = besta;\n        filled[besta] += ca;\n        int bestb = 0; bv = INT_MIN;\n        for (int i = 0; i < N; i++) {\n            int v = Tg[i] - filled[i];\n            if (v > bv) { bv = v; bestb = i; }\n        }\n        b[x] = bestb;\n        filled[bestb] += cb;\n    }\n    \n    long long bestE = simError();\n    \n    mt19937 rng(12345);\n    auto start = chrono::steady_clock::now();\n    \n    int iters = 0;\n    while (true) {\n        if ((iters & 7) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > 1.8) break;\n        }\n        iters++;\n        \n        int i = rng() % N;\n        int side = rng() % 2;\n        int newv = rng() % N;\n        int old;\n        if (side == 0) { old = a[i]; if (old == newv) continue; a[i] = newv; }\n        else { old = b[i]; if (old == newv) continue; b[i] = newv; }\n        \n        long long ne = simError();\n        if (ne <= bestE) {\n            bestE = ne;\n        } else {\n            if (side == 0) a[i] = old;\n            else b[i] = old;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> Gs;\nvector<int> lx, rx, ly, ry;\nvector<double> cx, cy;\nint queries_used = 0;\n\nvector<pair<int,int>> doQuery(vector<int> c) {\n    queries_used++;\n    cout << \"? \" << c.size();\n    for (int v : c) cout << \" \" << v;\n    cout << \"\\n\";\n    cout.flush();\n    vector<pair<int,int>> res(c.size()-1);\n    for (auto& p : res) cin >> p.first >> p.second;\n    return res;\n}\n\ndouble estDist(int i, int j) {\n    double dx = cx[i]-cx[j], dy = cy[i]-cy[j];\n    return sqrt(dx*dx+dy*dy);\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> Q >> L >> W;\n    Gs.resize(M);\n    for (auto& g : Gs) cin >> g;\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i]+rx[i])/2.0;\n        cy[i] = (ly[i]+ry[i])/2.0;\n    }\n    \n    vector<int> assigned(N, -1);\n    vector<vector<int>> groups(M);\n    \n    vector<int> gorder(M);\n    iota(gorder.begin(), gorder.end(), 0);\n    sort(gorder.begin(), gorder.end(), [&](int a, int b){ return Gs[a] > Gs[b]; });\n    \n    for (int gi : gorder) {\n        int sz = Gs[gi];\n        int seed = -1;\n        double bestv = 1e18;\n        for (int i = 0; i < N; i++) {\n            if (assigned[i] != -1) continue;\n            double v = cx[i] + cy[i]*0.0001;\n            if (v < bestv) { bestv = v; seed = i; }\n        }\n        vector<int>& grp = groups[gi];\n        grp.push_back(seed);\n        assigned[seed] = gi;\n        \n        vector<double> minD(N, 1e18);\n        for (int i = 0; i < N; i++) if (assigned[i] == -1) minD[i] = estDist(seed, i);\n        \n        while ((int)grp.size() < sz) {\n            int best = -1; double bd = 1e18;\n            for (int i = 0; i < N; i++) {\n                if (assigned[i] != -1) continue;\n                if (minD[i] < bd) { bd = minD[i]; best = i; }\n            }\n            grp.push_back(best);\n            assigned[best] = gi;\n            for (int i = 0; i < N; i++) {\n                if (assigned[i] == -1) {\n                    double d = estDist(best, i);\n                    if (d < minD[i]) minD[i] = d;\n                }\n            }\n        }\n    }\n    \n    vector<set<pair<int,int>>> edgeSets(M);\n    auto addEdge = [&](set<pair<int,int>>& es, int u, int v) {\n        if (u > v) swap(u,v);\n        es.insert({u,v});\n    };\n    \n    // Phase 1: chain queries for connectivity\n    for (int gi = 0; gi < M; gi++) {\n        int g = Gs[gi];\n        vector<int>& grp = groups[gi];\n        if (g <= 2) continue;\n        \n        vector<int> order;\n        vector<bool> used(g, false);\n        int start = 0;\n        double bv = 1e18;\n        for (int i = 0; i < g; i++) {\n            double v = cx[grp[i]] + cy[grp[i]]*0.0001;\n            if (v < bv) { bv = v; start = i; }\n        }\n        order.push_back(start); used[start] = true;\n        while ((int)order.size() < g) {\n            int last = order.back();\n            int best = -1; double bd = 1e18;\n            for (int i = 0; i < g; i++) {\n                if (used[i]) continue;\n                double d = estDist(grp[last], grp[i]);\n                if (d < bd) { bd = d; best = i; }\n            }\n            order.push_back(best); used[best] = true;\n        }\n        \n        int chunk_sz = L;\n        int step = max(1, L - 1);\n        for (int st = 0; st < g; st += step) {\n            int en = min(st + chunk_sz, g);\n            if (en - st < 2) break;\n            if (queries_used >= Q) break;\n            vector<int> q;\n            for (int i = st; i < en; i++) q.push_back(grp[order[i]]);\n            auto es = doQuery(q);\n            for (auto& [a,b] : es) addEdge(edgeSets[gi], a, b);\n            if (en == g) break;\n        }\n    }\n    \n    // Phase 2: extra queries\n    {\n        int remaining = Q - queries_used - 1;\n        if (remaining > 0) {\n            long long totalW = 0;\n            for (int gi = 0; gi < M; gi++) if (Gs[gi] >= 3) totalW += Gs[gi];\n            \n            vector<int> extraQ(M, 0);\n            if (totalW > 0) {\n                for (int gi = 0; gi < M; gi++) {\n                    if (Gs[gi] >= 3) {\n                        extraQ[gi] = (int)((long long)remaining * Gs[gi] / totalW);\n                    }\n                }\n            }\n            \n            for (int gi = 0; gi < M; gi++) {\n                int g = Gs[gi];\n                if (g < 3) continue;\n                vector<int>& grp = groups[gi];\n                int eq = extraQ[gi];\n                \n                for (int t = 0; t < eq && queries_used < Q; t++) {\n                    int pivot = grp[t % g];\n                    vector<pair<double,int>> cand;\n                    for (int c : grp) {\n                        if (c == pivot) continue;\n                        cand.push_back({estDist(pivot, c), c});\n                    }\n                    sort(cand.begin(), cand.end());\n                    int take = min((int)cand.size(), L - 1);\n                    vector<int> q;\n                    q.push_back(pivot);\n                    for (int i = 0; i < take; i++) q.push_back(cand[i].second);\n                    if ((int)q.size() < 2) continue;\n                    auto es = doQuery(q);\n                    for (auto& [a,b] : es) addEdge(edgeSets[gi], a, b);\n                }\n            }\n        }\n    }\n    \n    vector<vector<pair<int,int>>> allEdges(M);\n    \n    for (int gi = 0; gi < M; gi++) {\n        int g = Gs[gi];\n        vector<int>& grp = groups[gi];\n        if (g == 1) continue;\n        if (g == 2) {\n            allEdges[gi].push_back({grp[0], grp[1]});\n            continue;\n        }\n        \n        vector<tuple<double,int,int>> edges;\n        for (auto& p : edgeSets[gi]) edges.push_back({estDist(p.first, p.second), p.first, p.second});\n        sort(edges.begin(), edges.end());\n        \n        map<int,int> idx;\n        for (int i = 0; i < g; i++) idx[grp[i]] = i;\n        vector<int> par(g); iota(par.begin(), par.end(), 0);\n        function<int(int)> find = [&](int x){ return par[x]==x?x:par[x]=find(par[x]); };\n        \n        for (auto& [d,u,v] : edges) {\n            int a = idx[u], b = idx[v];\n            int ra = find(a), rb = find(b);\n            if (ra != rb) {\n                par[ra] = rb;\n                allEdges[gi].push_back({u,v});\n            }\n        }\n        \n        vector<tuple<double,int,int>> allPairs;\n        for (int i = 0; i < g; i++) for (int j = i+1; j < g; j++) {\n            allPairs.push_back({estDist(grp[i], grp[j]), i, j});\n        }\n        sort(allPairs.begin(), allPairs.end());\n        for (auto& [d,a,b] : allPairs) {\n            int ra = find(a), rb = find(b);\n            if (ra != rb) {\n                par[ra] = rb;\n                allEdges[gi].push_back({grp[a], grp[b]});\n            }\n        }\n    }\n    \n    cout << \"!\\n\";\n    for (int gi = 0; gi < M; gi++) {\n        for (int i = 0; i < (int)groups[gi].size(); i++) {\n            cout << groups[gi][i];\n            if (i+1 < (int)groups[gi].size()) cout << \" \";\n        }\n        cout << \"\\n\";\n        for (auto& p : allEdges[gi]) cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint di[4]={-1,1,0,0}, dj[4]={0,0,-1,1};\nchar dch[4]={'U','D','L','R'};\nvector<vector<bool>> blk;\n\npair<int,int> slideEnd(int i,int j,int d){\n    while(true){\n        int ni=i+di[d],nj=j+dj[d];\n        if(ni<0||ni>=N||nj<0||nj>=N||blk[ni][nj])break;\n        i=ni;j=nj;\n    }\n    return {i,j};\n}\n\nint main(){\n    cin>>N>>M;\n    vector<pair<int,int>> pts(M);\n    for(auto&p:pts)cin>>p.first>>p.second;\n    blk.assign(N,vector<bool>(N,false));\n    vector<string> out;\n    int ci=pts[0].first, cj=pts[0].second;\n    \n    for(int t=1;t<M;t++){\n        int ti=pts[t].first, tj=pts[t].second;\n        vector<vector<int>> dist(N,vector<int>(N,INT_MAX));\n        vector<vector<tuple<int,int,string>>> par(N,vector<tuple<int,int,string>>(N));\n        dist[ci][cj]=0;\n        queue<pair<int,int>> q;\n        q.push({ci,cj});\n        while(!q.empty()){\n            auto [i,j]=q.front();q.pop();\n            int c=dist[i][j];\n            for(int d=0;d<4;d++){\n                int ni=i+di[d],nj=j+dj[d];\n                if(ni>=0&&ni<N&&nj>=0&&nj<N&&!blk[ni][nj]){\n                    if(c+1<dist[ni][nj]){\n                        dist[ni][nj]=c+1;\n                        par[ni][nj]={i,j,string(\"M\")+dch[d]};\n                        q.push({ni,nj});\n                    }\n                }\n                auto [si,sj]=slideEnd(i,j,d);\n                if((si!=i||sj!=j)&&c+1<dist[si][sj]){\n                    dist[si][sj]=c+1;\n                    par[si][sj]={i,j,string(\"S\")+dch[d]};\n                    q.push({si,sj});\n                }\n            }\n        }\n        if(dist[ti][tj]==INT_MAX)break;\n        vector<string> acts;\n        int ii=ti,jj=tj;\n        while(ii!=ci||jj!=cj){\n            auto[pi,pj,a]=par[ii][jj];\n            acts.push_back(a);\n            ii=pi;jj=pj;\n        }\n        reverse(acts.begin(),acts.end());\n        for(auto&a:acts)out.push_back(a);\n        ci=ti;cj=tj;\n    }\n    for(auto&s:out)cout<<s[0]<<\" \"<<s[1]<<\"\\n\";\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> X, Y, R;\nstruct Rect { int a, b, c, d; };\nvector<Rect> rects;\nconst int W = 10000;\n\ninline double score_one_of(int i, const Rect& r) {\n    if (X[i] < r.a || X[i] >= r.c || Y[i] < r.b || Y[i] >= r.d) return 0;\n    long long s = (long long)(r.c - r.a) * (r.d - r.b);\n    double mn = min((long long)R[i], s);\n    double mx = max((long long)R[i], s);\n    double t = 1.0 - mn/mx;\n    return 1.0 - t*t;\n}\n\nint main() {\n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    rects.resize(n);\n    for (int i = 0; i < n; i++) {\n        cin >> X[i] >> Y[i] >> R[i];\n        rects[i] = {X[i], Y[i], X[i]+1, Y[i]+1};\n    }\n    \n    auto start = chrono::steady_clock::now();\n    auto elapsed = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - start).count();\n    };\n    \n    mt19937 rng(42);\n    auto randd = [&]() { return (rng() & 0xffffff) / (double)0x1000000; };\n    \n    const double TIME_LIMIT = 4.8;\n    \n    // SA parameters\n    double T_start = 0.005;\n    double T_end = 0.00005;\n    \n    long long iters = 0;\n    double T = T_start;\n    \n    while (true) {\n        if ((iters & 2047) == 0) {\n            double e = elapsed();\n            if (e > TIME_LIMIT) break;\n            double progress = e / TIME_LIMIT;\n            T = T_start * pow(T_end / T_start, progress);\n        }\n        iters++;\n        \n        int i = rng() % n;\n        Rect& r = rects[i];\n        double old_sc = score_one_of(i, r);\n        long long curS = (long long)(r.c - r.a) * (r.d - r.b);\n        \n        int move = rng() % 8;\n        Rect saved = r;\n        bool expand = move < 4;\n        \n        // Compute useful amount based on area target\n        int amt;\n        long long diff = expand ? max(0LL, (long long)R[i] - curS) : max(0LL, curS - (long long)R[i]);\n        \n        int rn = rng() % 100;\n        if (rn < 40 && diff > 0) {\n            // \"ideal\" amount to bring area close to target\n            int side;\n            if (move == 0 || move == 1) side = r.d - r.b;\n            else if (move == 2 || move == 3) side = r.c - r.a;\n            else if (move == 4 || move == 5) side = r.d - r.b;\n            else side = r.c - r.a;\n            if (side == 0) side = 1;\n            amt = max(1, (int)(diff / side));\n            // add noise\n            amt = max(1, amt + (int)(rng() % 5) - 2);\n        } else if (rn < 80) {\n            amt = 1 + rng() % 20;\n        } else {\n            amt = 1 + rng() % 200;\n        }\n        \n        if (move == 0) { r.a -= amt; if (r.a < 0) r.a = 0; }\n        else if (move == 1) { r.c += amt; if (r.c > W) r.c = W; }\n        else if (move == 2) { r.b -= amt; if (r.b < 0) r.b = 0; }\n        else if (move == 3) { r.d += amt; if (r.d > W) r.d = W; }\n        else if (move == 4) { r.a += amt; if (r.a > X[i]) r.a = X[i]; }\n        else if (move == 5) { r.c -= amt; if (r.c < X[i]+1) r.c = X[i]+1; }\n        else if (move == 6) { r.b += amt; if (r.b > Y[i]) r.b = Y[i]; }\n        else { r.d -= amt; if (r.d < Y[i]+1) r.d = Y[i]+1; }\n        \n        if (saved.a == r.a && saved.b == r.b && saved.c == r.c && saved.d == r.d) continue;\n        \n        if (expand) {\n            bool bad = false;\n            for (int j = 0; j < n; j++) {\n                if (j == i) continue;\n                const Rect& rj = rects[j];\n                if (r.c <= rj.a || rj.c <= r.a || r.d <= rj.b || rj.d <= r.b) continue;\n                bad = true; break;\n            }\n            if (bad) { r = saved; continue; }\n        }\n        \n        double new_sc = score_one_of(i, r);\n        double delta = new_sc - old_sc;\n        \n        if (delta >= 0) {\n            // accept\n        } else {\n            double p = exp(delta / T);\n            if (randd() >= p) { r = saved; continue; }\n        }\n    }\n    \n    // Final pure hill-climbing pass to clean up any worsening from SA\n    while (elapsed() < 4.95) {\n        int i = rng() % n;\n        Rect& r = rects[i];\n        double old_sc = score_one_of(i, r);\n        long long curS = (long long)(r.c - r.a) * (r.d - r.b);\n        \n        int move = rng() % 8;\n        Rect saved = r;\n        bool expand = move < 4;\n        int amt = 1 + rng() % 30;\n        \n        if (move == 0) { r.a -= amt; if (r.a < 0) r.a = 0; }\n        else if (move == 1) { r.c += amt; if (r.c > W) r.c = W; }\n        else if (move == 2) { r.b -= amt; if (r.b < 0) r.b = 0; }\n        else if (move == 3) { r.d += amt; if (r.d > W) r.d = W; }\n        else if (move == 4) { r.a += amt; if (r.a > X[i]) r.a = X[i]; }\n        else if (move == 5) { r.c -= amt; if (r.c < X[i]+1) r.c = X[i]+1; }\n        else if (move == 6) { r.b += amt; if (r.b > Y[i]) r.b = Y[i]; }\n        else { r.d -= amt; if (r.d < Y[i]+1) r.d = Y[i]+1; }\n        \n        if (saved.a == r.a && saved.b == r.b && saved.c == r.c && saved.d == r.d) continue;\n        \n        if (expand) {\n            bool bad = false;\n            for (int j = 0; j < n; j++) {\n                if (j == i) continue;\n                const Rect& rj = rects[j];\n                if (r.c <= rj.a || rj.c <= r.a || r.d <= rj.b || rj.d <= r.b) continue;\n                bad = true; break;\n            }\n            if (bad) { r = saved; continue; }\n        }\n        \n        double new_sc = score_one_of(i, r);\n        if (new_sc < old_sc - 1e-12) { r = saved; }\n    }\n    \n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << \" \" << rects[i].b << \" \" << rects[i].c << \" \" << rects[i].d << \"\\n\";\n    }\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nconst int N = 50;\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dch[] = {'U', 'D', 'L', 'R'};\n\ndouble getTime() {\n    return (double)clock() / CLOCKS_PER_SEC;\n}\n\nmt19937 rng(42);\n\nvector<pair<int,int>> path;\nvector<int> dirs;\nvector<bool> usedTile;\nint totalScore;\nint M;\n\nint targetR, targetC;\nint bestSegScore;\nvector<int> bestSegDirs;\nvector<int> curSegDirs;\nint curSegScore;\ndouble dfsDeadline;\nbool timeUp;\nint dfsCount;\nint maxDepth;\n\nvoid dfsSeg(int r, int c, int depth) {\n    dfsCount++;\n    if ((dfsCount & 4095) == 0) {\n        if (getTime() > dfsDeadline) { timeUp = true; return; }\n    }\n    if (timeUp) return;\n    \n    if (r == targetR && c == targetC) {\n        if (curSegScore > bestSegScore) {\n            bestSegScore = curSegScore;\n            bestSegDirs = curSegDirs;\n        }\n        return;\n    }\n    \n    if (depth >= maxDepth) return;\n    int md = abs(r - targetR) + abs(c - targetC);\n    if (depth + md > maxDepth) return;\n    \n    int order[4] = {0,1,2,3};\n    for (int k = 3; k > 0; k--) {\n        int j = rng() % (k+1);\n        swap(order[k], order[j]);\n    }\n    for (int k = 0; k < 4; k++) {\n        int d = order[k];\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = t[nr][nc];\n        if (usedTile[tid]) continue;\n        usedTile[tid] = true;\n        curSegScore += p[nr][nc];\n        curSegDirs.push_back(d);\n        dfsSeg(nr, nc, depth+1);\n        curSegDirs.pop_back();\n        curSegScore -= p[nr][nc];\n        usedTile[tid] = false;\n        if (timeUp) return;\n    }\n}\n\nint bestTailScore;\nvector<int> bestTailDirs;\nvector<int> curTailDirs;\nint curTailScore;\n\nvoid dfsTail(int r, int c) {\n    dfsCount++;\n    if ((dfsCount & 4095) == 0) {\n        if (getTime() > dfsDeadline) { timeUp = true; return; }\n    }\n    if (timeUp) return;\n    \n    if (curTailScore > bestTailScore) {\n        bestTailScore = curTailScore;\n        bestTailDirs = curTailDirs;\n    }\n    \n    int order[4] = {0,1,2,3};\n    for (int k = 3; k > 0; k--) {\n        int j = rng() % (k+1);\n        swap(order[k], order[j]);\n    }\n    for (int k = 0; k < 4; k++) {\n        int d = order[k];\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = t[nr][nc];\n        if (usedTile[tid]) continue;\n        usedTile[tid] = true;\n        curTailScore += p[nr][nc];\n        curTailDirs.push_back(d);\n        dfsTail(nr, nc);\n        curTailDirs.pop_back();\n        curTailScore -= p[nr][nc];\n        usedTile[tid] = false;\n        if (timeUp) return;\n    }\n}\n\nvoid rebuildUsedTiles() {\n    fill(usedTile.begin(), usedTile.end(), false);\n    for (auto& pp : path) usedTile[t[pp.first][pp.second]] = true;\n}\n\nbool validatePath() {\n    if (path.empty()) return false;\n    if (path[0].first != si || path[0].second != sj) return false;\n    if (path.size() != dirs.size() + 1) return false;\n    vector<bool> seen(M, false);\n    for (int k = 0; k < (int)path.size(); k++) {\n        int r = path[k].first, c = path[k].second;\n        if (r < 0 || r >= N || c < 0 || c >= N) return false;\n        if (seen[t[r][c]]) return false;\n        seen[t[r][c]] = true;\n        if (k > 0) {\n            int d = dirs[k-1];\n            int er = path[k-1].first + dr[d];\n            int ec = path[k-1].second + dc[d];\n            if (er != r || ec != c) return false;\n        }\n    }\n    return true;\n}\n\nint main() {\n    cin >> si >> sj;\n    M = 0;\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) {\n            cin >> t[i][j];\n            M = max(M, t[i][j]+1);\n        }\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++)\n            cin >> p[i][j];\n    \n    usedTile.assign(M, false);\n    \n    path.push_back({si, sj});\n    dirs.clear();\n    usedTile[t[si][sj]] = true;\n    totalScore = p[si][sj];\n    \n    {\n        int r = si, c = sj;\n        while (true) {\n            int cand[4], ncand = 0;\n            for (int d = 0; d < 4; d++) {\n                int nr = r+dr[d], nc = c+dc[d];\n                if (nr<0||nr>=N||nc<0||nc>=N) continue;\n                if (usedTile[t[nr][nc]]) continue;\n                cand[ncand++] = d;\n            }\n            if (ncand == 0) break;\n            int d = cand[rng()%ncand];\n            int nr = r+dr[d], nc = c+dc[d];\n            usedTile[t[nr][nc]] = true;\n            totalScore += p[nr][nc];\n            path.push_back({nr,nc});\n            dirs.push_back(d);\n            r = nr; c = nc;\n        }\n    }\n    \n    vector<pair<int,int>> savedPath = path;\n    vector<int> savedDirs = dirs;\n    int savedScore = totalScore;\n    \n    double TIME_LIMIT = 1.80;\n    \n    int iter = 0;\n    \n    while (getTime() < TIME_LIMIT) {\n        iter++;\n        int L = path.size();\n        \n        int mode = rng() % 10;\n        \n        if (mode < 2) {\n            int i = rng() % L;\n            \n            int oldSuffixScore = 0;\n            for (int k = i+1; k < L; k++) oldSuffixScore += p[path[k].first][path[k].second];\n            \n            for (int k = i+1; k < L; k++) {\n                usedTile[t[path[k].first][path[k].second]] = false;\n            }\n            usedTile[t[path[i].first][path[i].second]] = true;\n            \n            bestTailScore = 0;\n            bestTailDirs.clear();\n            curTailScore = 0;\n            curTailDirs.clear();\n            timeUp = false;\n            dfsCount = 0;\n            \n            double remaining = TIME_LIMIT - getTime();\n            double budget = min(0.015, remaining * 0.015);\n            if (budget < 0.001) budget = 0.001;\n            dfsDeadline = getTime() + budget;\n            \n            dfsTail(path[i].first, path[i].second);\n            \n            if (bestTailScore >= oldSuffixScore) {\n                path.resize(i+1);\n                dirs.resize(i);\n                int r = path[i].first, c = path[i].second;\n                for (int d : bestTailDirs) {\n                    int nr = r+dr[d], nc = c+dc[d];\n                    path.push_back({nr,nc});\n                    dirs.push_back(d);\n                    usedTile[t[nr][nc]] = true;\n                    r = nr; c = nc;\n                }\n                totalScore = totalScore - oldSuffixScore + bestTailScore;\n            } else {\n                for (int k = i+1; k < L; k++) {\n                    usedTile[t[path[k].first][path[k].second]] = true;\n                }\n            }\n        } else {\n            int i = rng() % L;\n            int len;\n            int r_mode = rng() % 10;\n            if (r_mode < 6) len = 3 + rng() % 15;\n            else if (r_mode < 9) len = 10 + rng() % 30;\n            else len = 20 + rng() % 60;\n            \n            int j = min(L-1, i + len);\n            if (j - i < 2) continue;\n            \n            int tj = t[path[j].first][path[j].second];\n            if (j+1 < L && t[path[j+1].first][path[j+1].second] == tj) continue;\n            \n            int oldSegScore = 0;\n            for (int k = i+1; k <= j; k++) oldSegScore += p[path[k].first][path[k].second];\n            \n            for (int k = i+1; k <= j; k++) {\n                usedTile[t[path[k].first][path[k].second]] = false;\n            }\n            usedTile[t[path[i].first][path[i].second]] = true;\n            \n            targetR = path[j].first;\n            targetC = path[j].second;\n            \n            bestSegScore = -1;\n            bestSegDirs.clear();\n            curSegScore = 0;\n            curSegDirs.clear();\n            timeUp = false;\n            dfsCount = 0;\n            int baseLen = j - i;\n            maxDepth = baseLen + min(15, baseLen);\n            \n            double remaining = TIME_LIMIT - getTime();\n            double budget;\n            if (baseLen < 15) budget = 0.003;\n            else if (baseLen < 30) budget = 0.008;\n            else budget = 0.015;\n            budget = min(budget, remaining * 0.01);\n            if (budget < 0.0003) budget = 0.0003;\n            dfsDeadline = getTime() + budget;\n            \n            dfsSeg(path[i].first, path[i].second, 0);\n            \n            if (bestSegScore >= oldSegScore && !bestSegDirs.empty()) {\n                vector<pair<int,int>> newSeg;\n                {\n                    int r = path[i].first, c = path[i].second;\n                    for (int d : bestSegDirs) {\n                        int nr = r+dr[d], nc = c+dc[d];\n                        newSeg.push_back({nr, nc});\n                        r = nr; c = nc;\n                    }\n                }\n                \n                for (auto& pp : newSeg) usedTile[t[pp.first][pp.second]] = true;\n                \n                vector<pair<int,int>> newPath;\n                newPath.reserve(path.size() + newSeg.size());\n                vector<int> newDirs;\n                newDirs.reserve(dirs.size() + bestSegDirs.size());\n                for (int k = 0; k <= i; k++) newPath.push_back(path[k]);\n                for (int k = 0; k < i; k++) newDirs.push_back(dirs[k]);\n                for (int d : bestSegDirs) newDirs.push_back(d);\n                for (auto& pp : newSeg) newPath.push_back(pp);\n                for (int k = j+1; k < L; k++) newPath.push_back(path[k]);\n                for (int k = j; k < (int)dirs.size(); k++) newDirs.push_back(dirs[k]);\n                \n                path = std::move(newPath);\n                dirs = std::move(newDirs);\n                totalScore = totalScore - oldSegScore + bestSegScore;\n            } else {\n                for (int k = i+1; k <= j; k++) {\n                    usedTile[t[path[k].first][path[k].second]] = true;\n                }\n            }\n        }\n        \n        if ((iter & 255) == 0) {\n            if (validatePath()) {\n                savedPath = path;\n                savedDirs = dirs;\n                savedScore = totalScore;\n            } else {\n                path = savedPath;\n                dirs = savedDirs;\n                totalScore = savedScore;\n                rebuildUsedTiles();\n            }\n        }\n    }\n    \n    if (!validatePath()) {\n        path = savedPath;\n        dirs = savedDirs;\n        totalScore = savedScore;\n    }\n    \n    string out;\n    for (int d : dirs) out += dch[d];\n    cout << out << endl;\n    \n    cerr << \"Score: \" << totalScore << \" Iter: \" << iter << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\ndouble h[30][29];\ndouble v[29][30];\n\nstruct Obs {\n    vector<tuple<int,int,int>> edges;\n    double observed;\n};\n\nvector<Obs> history;\n\nvoid update_with_obs(const vector<tuple<int,int,int>>& edges, double b, double alpha, double sigma) {\n    double predicted = 0;\n    for (auto [t,i,j] : edges) {\n        if (t == 0) predicted += h[i][j];\n        else predicted += v[i][j];\n    }\n    double ratio_delta = (b / predicted) - 1.0;\n    if (ratio_delta > 0.5) ratio_delta = 0.5;\n    if (ratio_delta < -0.4) ratio_delta = -0.4;\n    \n    static double h_delta[30][29];\n    static double v_delta[29][30];\n    static double h_wt[30][29];\n    static double v_wt[29][30];\n    memset(h_delta, 0, sizeof(h_delta));\n    memset(v_delta, 0, sizeof(v_delta));\n    memset(h_wt, 0, sizeof(h_wt));\n    memset(v_wt, 0, sizeof(v_wt));\n    \n    double inv_2s2 = 1.0 / (2*sigma*sigma);\n    for (auto& [type, ei, ej] : edges) {\n        if (type == 0) {\n            for (int jj = 0; jj < 29; jj++) {\n                double dj = jj - ej;\n                double w = exp(-dj*dj * inv_2s2);\n                h_delta[ei][jj] += w * ratio_delta;\n                h_wt[ei][jj] += w;\n            }\n        } else {\n            for (int ii = 0; ii < 29; ii++) {\n                double di = ii - ei;\n                double w = exp(-di*di * inv_2s2);\n                v_delta[ii][ej] += w * ratio_delta;\n                v_wt[ii][ej] += w;\n            }\n        }\n    }\n    \n    for (int i = 0; i < 30; i++) {\n        for (int j = 0; j < 29; j++) {\n            if (h_wt[i][j] > 0) {\n                double avg = h_delta[i][j] / h_wt[i][j];\n                h[i][j] *= (1.0 + alpha * avg);\n                if (h[i][j] < 1000) h[i][j] = 1000;\n                if (h[i][j] > 9000) h[i][j] = 9000;\n            }\n        }\n    }\n    for (int i = 0; i < 29; i++) {\n        for (int j = 0; j < 30; j++) {\n            if (v_wt[i][j] > 0) {\n                double avg = v_delta[i][j] / v_wt[i][j];\n                v[i][j] *= (1.0 + alpha * avg);\n                if (v[i][j] < 1000) v[i][j] = 1000;\n                if (v[i][j] > 9000) v[i][j] = 9000;\n            }\n        }\n    }\n}\n\nint main() {\n    for (int i = 0; i < 30; i++) for (int j = 0; j < 29; j++) h[i][j] = 5000;\n    for (int i = 0; i < 29; i++) for (int j = 0; j < 30; j++) v[i][j] = 5000;\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n        \n        vector<vector<double>> dist(30, vector<double>(30, 1e18));\n        vector<vector<int>> prv(30, vector<int>(30, -1));\n        priority_queue<tuple<double,int,int>, vector<tuple<double,int,int>>, greater<>> pq;\n        dist[si][sj] = 0;\n        pq.push({0.0, si, sj});\n        int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};\n        while (!pq.empty()) {\n            auto [d, r, c] = pq.top(); pq.pop();\n            if (d > dist[r][c]) continue;\n            for (int dir = 0; dir < 4; dir++) {\n                int nr = r+dr[dir], nc = c+dc[dir];\n                if (nr<0||nr>=30||nc<0||nc>=30) continue;\n                double w;\n                if (dir == 0) w = v[nr][c];\n                else if (dir == 1) w = v[r][c];\n                else if (dir == 2) w = h[r][nc];\n                else w = h[r][c];\n                if (dist[nr][nc] > d + w) {\n                    dist[nr][nc] = d + w;\n                    prv[nr][nc] = dir;\n                    pq.push({dist[nr][nc], nr, nc});\n                }\n            }\n        }\n        \n        vector<int> dirs;\n        int r = ti, c = tj;\n        while (!(r == si && c == sj)) {\n            int d = prv[r][c];\n            dirs.push_back(d);\n            r -= dr[d]; c -= dc[d];\n        }\n        reverse(dirs.begin(), dirs.end());\n        \n        string path;\n        char ch[] = {'U','D','L','R'};\n        for (int d : dirs) path += ch[d];\n        cout << path << endl;\n        cout.flush();\n        \n        long long b;\n        cin >> b;\n        \n        vector<tuple<int,int,int>> edges;\n        r = si; c = sj;\n        for (int d : dirs) {\n            int nr = r+dr[d], nc = c+dc[d];\n            if (d == 0) edges.push_back({1, nr, c});\n            else if (d == 1) edges.push_back({1, r, c});\n            else if (d == 2) edges.push_back({0, r, nc});\n            else edges.push_back({0, r, c});\n            r = nr; c = nc;\n        }\n        \n        history.push_back({edges, (double)b});\n        \n        update_with_obs(edges, (double)b, 0.15, 5.0);\n        \n        int replay_n = min((int)history.size() - 1, 30);\n        int start = history.size() - 1 - replay_n;\n        for (int rep = 0; rep < 2; rep++) {\n            for (int idx = start; idx < (int)history.size() - 1; idx++) {\n                update_with_obs(history[idx].edges, history[idx].observed, 0.04, 5.0);\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\nusing Clock = chrono::steady_clock;\n\nint N = 20;\nint M;\nvector<string> S;\nmt19937 rng(42);\n\nint ovlp(const string& a, const string& b) {\n    int m = min((int)a.size(), (int)b.size());\n    for (int k = m; k >= 1; k--) {\n        if (a.compare(a.size()-k, k, b, 0, k) == 0) return k;\n    }\n    return 0;\n}\n\nvector<string> makeTracks(const vector<string>& grid) {\n    vector<string> tracks(2*N);\n    for (int r = 0; r < N; r++) tracks[r] = grid[r] + grid[r].substr(0, 11);\n    for (int c = 0; c < N; c++) {\n        string col(N, '.');\n        for (int r = 0; r < N; r++) col[r] = grid[r][c];\n        tracks[N+c] = col + col.substr(0, 11);\n    }\n    return tracks;\n}\n\nint countMatches(const vector<string>& grid, const vector<int>& avail) {\n    auto tracks = makeTracks(grid);\n    int cnt = 0;\n    for (int i : avail) {\n        for (auto& t : tracks) {\n            if (t.find(S[i]) != string::npos) { cnt++; break; }\n        }\n    }\n    return cnt;\n}\n\nint tryPlace(vector<string>& grid, const string& s, int r, int c, int dir, bool doIt) {\n    int L = s.size();\n    int cost = 0;\n    for (int p = 0; p < L; p++) {\n        int rr, cc;\n        if (dir == 0) { rr = r; cc = (c+p) % N; }\n        else { rr = (r+p) % N; cc = c; }\n        if (grid[rr][cc] == '.') cost++;\n        else if (grid[rr][cc] != s[p]) return -1;\n    }\n    if (doIt) {\n        for (int p = 0; p < L; p++) {\n            int rr, cc;\n            if (dir == 0) { rr = r; cc = (c+p) % N; }\n            else { rr = (r+p) % N; cc = c; }\n            grid[rr][cc] = s[p];\n        }\n    }\n    return cost;\n}\n\nvoid updateCovered(vector<string>& grid, const vector<int>& avail, vector<bool>& placed) {\n    auto tracks = makeTracks(grid);\n    for (int i : avail) {\n        if (placed[i]) continue;\n        for (auto& t : tracks) {\n            if (t.find(S[i]) != string::npos) { placed[i] = true; break; }\n        }\n    }\n}\n\nvector<string> greedyBuild(const vector<int>& avail, const vector<bool>& redundant) {\n    vector<bool> used(M, false);\n    for (int i = 0; i < M; i++) if (redundant[i]) used[i] = true;\n    \n    vector<string> grid(N, string(N, '.'));\n    vector<int> order = avail;\n    shuffle(order.begin(), order.end(), rng);\n    \n    for (int r = 0; r < N; r++) {\n        int first = -1;\n        int bestLen = -1;\n        for (int i : order) if (!used[i]) {\n            if ((int)S[i].size() > bestLen) { bestLen = S[i].size(); first = i; }\n        }\n        if (first == -1) break;\n        vector<int> topCands;\n        for (int i : order) if (!used[i] && (int)S[i].size() >= bestLen) topCands.push_back(i);\n        if (topCands.empty()) break;\n        first = topCands[rng() % topCands.size()];\n        \n        string row = S[first];\n        used[first] = true;\n        if ((int)row.size() > N) row = row.substr(0, N);\n        \n        while ((int)row.size() < N) {\n            vector<tuple<int,int,int>> cands;\n            for (int i : order) if (!used[i]) {\n                int o = ovlp(row, S[i]);\n                int addLen = (int)S[i].size() - o;\n                if ((int)row.size() + addLen > N) continue;\n                int sc = o * 1000 + (int)S[i].size();\n                cands.push_back({sc, i, o});\n            }\n            if (cands.empty()) break;\n            sort(cands.begin(), cands.end(), greater<>());\n            int topk = min((int)cands.size(), 3);\n            auto [sc, best, o] = cands[rng() % topk];\n            row += S[best].substr(o);\n            used[best] = true;\n        }\n        \n        if ((int)row.size() == N) {\n            string cyc = row + row.substr(0, 11);\n            for (int i : avail) if (!used[i]) {\n                if (cyc.find(S[i]) != string::npos) used[i] = true;\n            }\n        }\n        \n        for (int j = 0; j < (int)row.size() && j < N; j++) grid[r][j] = row[j];\n    }\n    \n    updateCovered(grid, avail, used);\n    \n    vector<int> remaining;\n    for (int i : avail) if (!used[i]) remaining.push_back(i);\n    sort(remaining.begin(), remaining.end(), [](int a, int b){ return S[a].size() > S[b].size(); });\n    \n    for (int i : remaining) {\n        if (used[i]) continue;\n        const string& s = S[i];\n        int bestCost = INT_MAX;\n        int bestR = -1, bestC = -1, bestDir = -1;\n        for (int dir = 0; dir < 2; dir++) {\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    int cost = tryPlace(grid, s, r, c, dir, false);\n                    if (cost >= 0 && cost < bestCost) {\n                        bestCost = cost;\n                        bestR = r; bestC = c; bestDir = dir;\n                    }\n                }\n            }\n        }\n        if (bestR != -1) {\n            tryPlace(grid, s, bestR, bestC, bestDir, true);\n            used[i] = true;\n            updateCovered(grid, avail, used);\n        }\n    }\n    \n    return grid;\n}\n\nint main() {\n    cin >> N >> M;\n    S.resize(M);\n    for (auto& s : S) cin >> s;\n    \n    vector<bool> redundant(M, false);\n    vector<int> idxSort(M);\n    iota(idxSort.begin(), idxSort.end(), 0);\n    sort(idxSort.begin(), idxSort.end(), [](int a, int b){ return S[a].size() > S[b].size(); });\n    \n    for (int ii = 0; ii < M; ii++) {\n        int i = idxSort[ii];\n        if (redundant[i]) continue;\n        for (int jj = ii+1; jj < M; jj++) {\n            int j = idxSort[jj];\n            if (redundant[j]) continue;\n            if (S[i].find(S[j]) != string::npos) redundant[j] = true;\n        }\n    }\n    \n    vector<int> avail;\n    for (int i = 0; i < M; i++) if (!redundant[i]) avail.push_back(i);\n    \n    auto startTime = Clock::now();\n    auto timeUsed = [&]() { return chrono::duration<double>(Clock::now() - startTime).count(); };\n    \n    vector<string> bestGrid(N, string(N, '.'));\n    int bestScore = -1;\n    int bestDots = -1;\n    \n    // Phase 1: Many greedy trials\n    int trial = 0;\n    while (timeUsed() < 1.3) {\n        trial++;\n        vector<string> grid = greedyBuild(avail, redundant);\n        int score = countMatches(grid, avail);\n        int dots = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] == '.') dots++;\n        \n        if (score > bestScore || (score == bestScore && dots > bestDots)) {\n            bestScore = score;\n            bestDots = dots;\n            bestGrid = grid;\n        }\n    }\n    cerr << \"Phase 1 trials: \" << trial << \" best: \" << bestScore << \"/\" << avail.size() << \"\\n\";\n    \n    // Phase 2: Hill climb on best grid\n    {\n        vector<string> grid = bestGrid;\n        int cur = bestScore;\n        bool improved = true;\n        while (improved && timeUsed() < 2.7) {\n            improved = false;\n            \n            for (int r = 0; r < N; r++) {\n                if (timeUsed() > 2.7) break;\n                string orig = grid[r];\n                int bestShift = 0;\n                int bestSc = cur;\n                for (int sh = 1; sh < N; sh++) {\n                    grid[r] = orig.substr(sh) + orig.substr(0, sh);\n                    int sc = countMatches(grid, avail);\n                    if (sc > bestSc) { bestSc = sc; bestShift = sh; }\n                }\n                grid[r] = orig.substr(bestShift) + orig.substr(0, bestShift);\n                if (bestShift != 0) { cur = bestSc; improved = true; }\n            }\n            \n            for (int c = 0; c < N; c++) {\n                if (timeUsed() > 2.7) break;\n                string orig_col(N, '.');\n                for (int r = 0; r < N; r++) orig_col[r] = grid[r][c];\n                int bestShift = 0;\n                int bestSc = cur;\n                for (int sh = 1; sh < N; sh++) {\n                    string nc = orig_col.substr(sh) + orig_col.substr(0, sh);\n                    for (int r = 0; r < N; r++) grid[r][c] = nc[r];\n                    int sc = countMatches(grid, avail);\n                    if (sc > bestSc) { bestSc = sc; bestShift = sh; }\n                }\n                string nc = orig_col.substr(bestShift) + orig_col.substr(0, bestShift);\n                for (int r = 0; r < N; r++) grid[r][c] = nc[r];\n                if (bestShift != 0) { cur = bestSc; improved = true; }\n            }\n            \n            for (int r1 = 0; r1 < N && timeUsed() < 2.7; r1++) {\n                for (int r2 = r1+1; r2 < N; r2++) {\n                    swap(grid[r1], grid[r2]);\n                    int sc = countMatches(grid, avail);\n                    if (sc > cur) { cur = sc; improved = true; }\n                    else swap(grid[r1], grid[r2]);\n                }\n            }\n            \n            for (int c1 = 0; c1 < N && timeUsed() < 2.7; c1++) {\n                for (int c2 = c1+1; c2 < N; c2++) {\n                    for (int r = 0; r < N; r++) swap(grid[r][c1], grid[r][c2]);\n                    int sc = countMatches(grid, avail);\n                    if (sc > cur) { cur = sc; improved = true; }\n                    else for (int r = 0; r < N; r++) swap(grid[r][c1], grid[r][c2]);\n                }\n            }\n        }\n        \n        int dots = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] == '.') dots++;\n        if (cur > bestScore || (cur == bestScore && dots > bestDots)) {\n            bestScore = cur;\n            bestDots = dots;\n            bestGrid = grid;\n        }\n    }\n    \n    if (bestScore == (int)avail.size()) {\n        int cur = bestScore;\n        vector<pair<int,int>> cells;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) cells.push_back({r,c});\n        shuffle(cells.begin(), cells.end(), rng);\n        for (auto [r, c] : cells) {\n            if (bestGrid[r][c] == '.') continue;\n            char orig = bestGrid[r][c];\n            bestGrid[r][c] = '.';\n            int nw = countMatches(bestGrid, avail);\n            if (nw < cur) bestGrid[r][c] = orig;\n            else cur = nw;\n        }\n    }\n    \n    cerr << \"Final: \" << bestScore << \"/\" << avail.size() << \"\\n\";\n    \n    for (int i = 0; i < N; i++) cout << bestGrid[i] << \"\\n\";\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> G;\nvector<vector<int>> id;\nvector<pair<int,int>> pos;\nvector<int> cost;\nint R;\n\nbool isRoad(int i,int j){ return i>=0&&i<N&&j>=0&&j<N&&G[i][j]!='#'; }\n\nchrono::steady_clock::time_point startT;\ndouble elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-startT).count();}\n\nint dx_[]={-1,1,0,0},dy_[]={0,0,-1,1};\n\nvoid dijkstra(int src, vector<int>&dist, vector<int>&prv){\n    dist.assign(R,INT_MAX);\n    prv.assign(R,-1);\n    dist[src]=0;\n    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>> pq;\n    pq.push({0,src});\n    while(!pq.empty()){\n        auto[d,u]=pq.top();pq.pop();\n        if(d>dist[u])continue;\n        auto[i,j]=pos[u];\n        for(int di=0;di<4;di++){\n            int x=i+dx_[di],y=j+dy_[di];\n            if(!isRoad(x,y))continue;\n            int v=id[x][y];\n            int nd=d+cost[v];\n            if(nd<dist[v]){\n                dist[v]=nd;\n                prv[v]=u;\n                pq.push({nd,v});\n            }\n        }\n    }\n}\n\nint main(){\n    startT=chrono::steady_clock::now();\n    cin>>N>>si>>sj;\n    G.resize(N);\n    for(auto&s:G)cin>>s;\n    id.assign(N,vector<int>(N,-1));\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(G[i][j]!='#'){\n        id[i][j]=pos.size();\n        pos.push_back({i,j});\n        cost.push_back(G[i][j]-'0');\n    }\n    R=pos.size();\n    \n    vector<vector<int>> visible(R);\n    vector<vector<char>> visMat(R, vector<char>(R, 0));\n    for(int k=0;k<R;k++){\n        auto[i,j]=pos[k];\n        visible[k].push_back(k);\n        visMat[k][k]=1;\n        for(int d=0;d<4;d++){\n            int x=i+dx_[d],y=j+dy_[d];\n            while(isRoad(x,y)){\n                int v=id[x][y];\n                visible[k].push_back(v);\n                visMat[k][v]=1;\n                x+=dx_[d];y+=dy_[d];\n            }\n        }\n    }\n    \n    int sid=id[si][sj];\n    \n    auto greedyCover=[&](unsigned seed)->vector<int>{\n        mt19937 rng(seed);\n        vector<bool> covered(R,false);\n        vector<int> uncovCount(R);\n        for(int k=0;k<R;k++)uncovCount[k]=visible[k].size();\n        vector<int> sel;\n        int nCov=0;\n        auto doSel=[&](int k){\n            sel.push_back(k);\n            for(int v:visible[k]){\n                if(!covered[v]){\n                    covered[v]=true;\n                    nCov++;\n                    for(int u:visible[v])uncovCount[u]--;\n                }\n            }\n        };\n        doSel(sid);\n        while(nCov<R){\n            int bc=-1;\n            vector<int> bests;\n            for(int k=0;k<R;k++){\n                if(uncovCount[k]>bc){bc=uncovCount[k];bests.clear();bests.push_back(k);}\n                else if(uncovCount[k]==bc)bests.push_back(k);\n            }\n            int pick=bests[rng()%bests.size()];\n            doSel(pick);\n        }\n        vector<int> coverCnt(R,0);\n        for(int s:sel)for(int v:visible[s])coverCnt[v]++;\n        vector<bool> keep(sel.size(),true);\n        vector<int> ord;\n        for(int i=1;i<(int)sel.size();i++)ord.push_back(i);\n        shuffle(ord.begin(),ord.end(),rng);\n        for(int i:ord){\n            int s=sel[i];\n            bool can=true;\n            for(int v:visible[s])if(coverCnt[v]<2){can=false;break;}\n            if(can){\n                keep[i]=false;\n                for(int v:visible[s])coverCnt[v]--;\n            }\n        }\n        vector<int> res;\n        for(int i=0;i<(int)sel.size();i++)if(keep[i])res.push_back(sel[i]);\n        return res;\n    };\n    \n    vector<int> selected = greedyCover(1);\n    for(int t=2;t<=10 && elapsed()<0.2;t++){\n        auto s2=greedyCover(t*7919u+1);\n        if(s2.size()<selected.size())selected=s2;\n    }\n    for(int i=0;i<(int)selected.size();i++)if(selected[i]==sid){swap(selected[0],selected[i]);break;}\n    \n    int K=selected.size();\n    vector<vector<int>> dist(K), prev_(K);\n    for(int s=0;s<K;s++)dijkstra(selected[s],dist[s],prev_[s]);\n    \n    vector<vector<int>> D(K,vector<int>(K));\n    for(int a=0;a<K;a++)for(int b=0;b<K;b++)D[a][b]=dist[a][selected[b]];\n    \n    auto tourLen=[&](const vector<int>&t){\n        int s=0;for(int i=0;i+1<(int)t.size();i++)s+=D[t[i]][t[i+1]];return s;\n    };\n    \n    auto twoOpt=[&](vector<int>&tour, double timeLimit){\n        int n=tour.size();\n        bool improved=true;\n        while(improved){\n            improved=false;\n            for(int i=1;i<n-2;i++){\n                if(elapsed()>=timeLimit)return;\n                for(int j=i+1;j<n-1;j++){\n                    int a=tour[i-1],b=tour[i],c=tour[j],d=tour[j+1];\n                    int delta=D[a][c]+D[b][d]-D[a][b]-D[c][d];\n                    if(delta<0){\n                        reverse(tour.begin()+i,tour.begin()+j+1);\n                        improved=true;\n                    }\n                }\n            }\n        }\n    };\n    \n    auto orOpt=[&](vector<int>&tour, double timeLimit){\n        int n=tour.size();\n        bool improved=true;\n        while(improved){\n            improved=false;\n            for(int segLen=1;segLen<=3;segLen++){\n                for(int i=1;i+segLen<n;i++){\n                    if(elapsed()>=timeLimit)return;\n                    int a=tour[i-1], b=tour[i], c=tour[i+segLen-1], d=tour[i+segLen];\n                    int removeCost=D[a][b]+D[c][d]-D[a][d];\n                    int bestDelta=0, bestJ=-1;\n                    bool bestRev=false;\n                    for(int j=0;j<n-1;j++){\n                        if(j>=i-1 && j<=i+segLen-1)continue;\n                        int e=tour[j], f=tour[j+1];\n                        int ic=D[e][b]+D[c][f]-D[e][f];\n                        int delta=ic-removeCost;\n                        if(delta<bestDelta){bestDelta=delta;bestJ=j;bestRev=false;}\n                        int ic2=D[e][c]+D[b][f]-D[e][f];\n                        int delta2=ic2-removeCost;\n                        if(delta2<bestDelta){bestDelta=delta2;bestJ=j;bestRev=true;}\n                    }\n                    if(bestJ>=0){\n                        vector<int> seg(tour.begin()+i, tour.begin()+i+segLen);\n                        if(bestRev)reverse(seg.begin(),seg.end());\n                        vector<int> nt;\n                        int j=bestJ;\n                        if(j<i-1){\n                            for(int k=0;k<=j;k++)nt.push_back(tour[k]);\n                            for(int x:seg)nt.push_back(x);\n                            for(int k=j+1;k<i;k++)nt.push_back(tour[k]);\n                            for(int k=i+segLen;k<n;k++)nt.push_back(tour[k]);\n                        } else {\n                            for(int k=0;k<i;k++)nt.push_back(tour[k]);\n                            for(int k=i+segLen;k<=j;k++)nt.push_back(tour[k]);\n                            for(int x:seg)nt.push_back(x);\n                            for(int k=j+1;k<n;k++)nt.push_back(tour[k]);\n                        }\n                        tour=nt;\n                        improved=true;\n                        break;\n                    }\n                }\n                if(improved)break;\n            }\n        }\n    };\n    \n    auto nearestNeighborFrom=[&](int startNeighbor){\n        vector<int> tour;\n        vector<bool> used(K,false);\n        used[0]=true;\n        tour.push_back(0);\n        if(startNeighbor!=0 && startNeighbor<K){\n            tour.push_back(startNeighbor);\n            used[startNeighbor]=true;\n        }\n        while((int)tour.size()<K){\n            int last=tour.back();\n            int bn=-1,bd=INT_MAX;\n            for(int j=0;j<K;j++)if(!used[j]&&D[last][j]<bd){bd=D[last][j];bn=j;}\n            tour.push_back(bn);used[bn]=true;\n        }\n        tour.push_back(0);\n        return tour;\n    };\n    \n    vector<int> bestTour = nearestNeighborFrom(0);\n    twoOpt(bestTour, 0.2);\n    orOpt(bestTour, 0.35);\n    twoOpt(bestTour, 0.45);\n    int bestLen = tourLen(bestTour);\n    \n    for(int s=1;s<K && elapsed()<0.6;s++){\n        vector<int> t = nearestNeighborFrom(s);\n        twoOpt(t, min(0.6, elapsed()+0.03));\n        int l=tourLen(t);\n        if(l<bestLen){bestLen=l;bestTour=t;}\n    }\n    \n    mt19937 rng(12345);\n    \n    while(elapsed()<0.9){\n        vector<int> t2 = bestTour;\n        int n = t2.size()-1;\n        if(n<8)break;\n        int p1=1+rng()%(n/4);\n        int p2=p1+1+rng()%(n/4);\n        int p3=p2+1+rng()%(n/4);\n        if(p3>=n)continue;\n        vector<int> nt;\n        nt.push_back(t2[0]);\n        for(int i=p3;i<n;i++)nt.push_back(t2[i]);\n        for(int i=p2;i<p3;i++)nt.push_back(t2[i]);\n        for(int i=p1;i<p2;i++)nt.push_back(t2[i]);\n        for(int i=1;i<p1;i++)nt.push_back(t2[i]);\n        nt.push_back(t2[0]);\n        double lim = min(0.9, elapsed()+0.08);\n        twoOpt(nt, lim);\n        orOpt(nt, min(0.9, elapsed()+0.04));\n        int l=tourLen(nt);\n        if(l<bestLen){bestLen=l;bestTour=nt;}\n    }\n    \n    auto tryGlobalReplacement=[&]()->int{\n        vector<int> coverCnt(R,0);\n        for(int s:selected)for(int v:visible[s])coverCnt[v]++;\n        \n        int changes=0;\n        vector<int> order;\n        for(int i=1;i<K;i++)order.push_back(i);\n        shuffle(order.begin(),order.end(),rng);\n        \n        for(int ti:order){\n            if(elapsed()>2.3)break;\n            if(ti>=K)continue; // K may have changed\n            int origPt = selected[ti];\n            vector<int> unique_sq;\n            for(int v:visible[origPt])if(coverCnt[v]==1)unique_sq.push_back(v);\n            \n            int pos_in_tour=-1;\n            for(int p=0;p<(int)bestTour.size();p++)if(bestTour[p]==ti){pos_in_tour=p;break;}\n            if(pos_in_tour<0)continue;\n            int prv = bestTour[pos_in_tour-1];\n            int nxt = bestTour[pos_in_tour+1];\n            int removeGain = D[prv][ti]+D[ti][nxt]-D[prv][nxt];\n            \n            if(unique_sq.empty()){\n                if(removeGain>0){\n                    int removedIdx = ti;\n                    vector<int> newSel;\n                    for(int i=0;i<K;i++)if(i!=removedIdx)newSel.push_back(selected[i]);\n                    selected = newSel;\n                    K = selected.size();\n                    dist.assign(K,{}); prev_.assign(K,{});\n                    for(int s=0;s<K;s++)dijkstra(selected[s],dist[s],prev_[s]);\n                    D.assign(K,vector<int>(K));\n                    for(int a=0;a<K;a++)for(int b=0;b<K;b++)D[a][b]=dist[a][selected[b]];\n                    vector<int> newTour;\n                    for(int x:bestTour){\n                        if(x==removedIdx)continue;\n                        newTour.push_back(x>removedIdx?x-1:x);\n                    }\n                    vector<int> nt2;\n                    for(int x:newTour){\n                        if(!nt2.empty() && nt2.back()==x)continue;\n                        nt2.push_back(x);\n                    }\n                    if(nt2.empty() || nt2[0]!=0){nt2.insert(nt2.begin(),0);}\n                    if(nt2.back()!=0)nt2.push_back(0);\n                    bestTour = nt2;\n                    bestLen = tourLen(bestTour);\n                    changes++;\n                    // recompute coverCnt\n                    coverCnt.assign(R,0);\n                    for(int s:selected)for(int v:visible[s])coverCnt[v]++;\n                }\n                continue;\n            }\n            \n            vector<int> candidates;\n            int smallest=unique_sq[0];\n            for(int v:unique_sq)if((int)visible[v].size()<(int)visible[smallest].size())smallest=v;\n            for(int c:visible[smallest]){\n                bool ok=true;\n                for(int v:unique_sq)if(!visMat[c][v]){ok=false;break;}\n                if(ok)candidates.push_back(c);\n            }\n            \n            int bestDelta = 0;\n            int bestCand = -1;\n            int bestInsertPos = -2;\n            int n_tour = bestTour.size();\n            \n            for(int cand:candidates){\n                if(cand==origPt)continue;\n                // Insert at non-adjacent-to-ti edges\n                for(int p=0;p+1<n_tour;p++){\n                    if(p==pos_in_tour-1 || p==pos_in_tour)continue;\n                    int ej = bestTour[p], fj = bestTour[p+1];\n                    int d1 = dist[ej][cand];\n                    if(d1>=INT_MAX/2)continue;\n                    int d2 = dist[fj][cand] - cost[selected[fj]] + cost[cand];\n                    int insertCost = d1 + d2 - D[ej][fj];\n                    int delta = -removeGain + insertCost;\n                    if(delta < bestDelta){\n                        bestDelta = delta;\n                        bestCand = cand;\n                        bestInsertPos = p;\n                    }\n                }\n                // Same position as ti\n                {\n                    int ej = prv, fj = nxt;\n                    int d1 = dist[ej][cand];\n                    if(d1<INT_MAX/2){\n                        int d2 = dist[fj][cand] - cost[selected[fj]] + cost[cand];\n                        int insertCost = d1 + d2 - D[prv][nxt];\n                        int delta = -removeGain + insertCost;\n                        if(delta < bestDelta){\n                            bestDelta = delta;\n                            bestCand = cand;\n                            bestInsertPos = -1; // sentinel: same position\n                        }\n                    }\n                }\n            }\n            \n            if(bestCand==-1)continue;\n            \n            int cand = bestCand;\n            for(int v:visible[origPt])coverCnt[v]--;\n            for(int v:visible[cand])coverCnt[v]++;\n            selected[ti]=cand;\n            dijkstra(cand, dist[ti], prev_[ti]);\n            for(int b=0;b<K;b++)D[ti][b]=dist[ti][selected[b]];\n            for(int b=0;b<K;b++){\n                if(b==ti)continue;\n                D[b][ti] = D[ti][b] + cost[cand] - cost[selected[b]];\n            }\n            if(bestInsertPos==-1){\n                // no position change\n            } else {\n                vector<int> shortT;\n                for(int p=0;p<(int)bestTour.size();p++)if(p!=pos_in_tour)shortT.push_back(bestTour[p]);\n                int adjInsert = bestInsertPos;\n                if(bestInsertPos > pos_in_tour) adjInsert = bestInsertPos - 1;\n                vector<int> nt;\n                for(int p=0;p<=adjInsert;p++)nt.push_back(shortT[p]);\n                nt.push_back(ti);\n                for(int p=adjInsert+1;p<(int)shortT.size();p++)nt.push_back(shortT[p]);\n                bestTour = nt;\n            }\n            bestLen = tourLen(bestTour);\n            changes++;\n        }\n        return changes;\n    };\n    \n    for(int round=0;round<30 && elapsed()<2.0;round++){\n        int ch = tryGlobalReplacement();\n        twoOpt(bestTour, min(2.2, elapsed()+0.1));\n        orOpt(bestTour, min(2.2, elapsed()+0.05));\n        bestLen = tourLen(bestTour);\n        if(ch==0 && round>0)break;\n    }\n    \n    while(elapsed()<2.75){\n        vector<int> t2 = bestTour;\n        int n = t2.size()-1;\n        if(n<8)break;\n        int p1=1+rng()%(n/4);\n        int p2=p1+1+rng()%(n/4);\n        int p3=p2+1+rng()%(n/4);\n        if(p3>=n)continue;\n        vector<int> nt;\n        nt.push_back(t2[0]);\n        for(int i=p3;i<n;i++)nt.push_back(t2[i]);\n        for(int i=p2;i<p3;i++)nt.push_back(t2[i]);\n        for(int i=p1;i<p2;i++)nt.push_back(t2[i]);\n        for(int i=1;i<p1;i++)nt.push_back(t2[i]);\n        nt.push_back(t2[0]);\n        double lim = min(2.75, elapsed()+0.08);\n        twoOpt(nt, lim);\n        orOpt(nt, min(2.75, elapsed()+0.04));\n        int l=tourLen(nt);\n        if(l<bestLen){bestLen=l;bestTour=nt;}\n    }\n    \n    vector<int>& tour = bestTour;\n    \n    string result;\n    for(int i=0;i+1<(int)tour.size();i++){\n        int a=selected[tour[i]], b=selected[tour[i+1]];\n        if(a==b)continue;\n        int s=tour[i];\n        vector<int> path;\n        int cur=b;\n        while(cur!=a){\n            path.push_back(cur);\n            cur=prev_[s][cur];\n        }\n        reverse(path.begin(),path.end());\n        int px=pos[a].first, py=pos[a].second;\n        for(int nd:path){\n            int nx=pos[nd].first, ny=pos[nd].second;\n            if(nx==px-1)result+='U';\n            else if(nx==px+1)result+='D';\n            else if(ny==py-1)result+='L';\n            else result+='R';\n            px=nx;py=ny;\n        }\n    }\n    \n    cout<<result<<endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> D;\nvector<vector<int>> deps;\nvector<vector<int>> children;\nvector<int> indeg;\nvector<int> longestPath;\n\nvector<vector<int>> estS;\nvector<vector<pair<int,int>>> obs;\n\nint computeW(const vector<int>& d, const vector<int>& s) {\n    int w = 0;\n    for (int k = 0; k < K; k++) w += max(0, d[k] - s[k]);\n    return w;\n}\n\nint predictTime(int task, int member) {\n    int w = computeW(D[task], estS[member]);\n    return (w == 0) ? 1 : max(1, w);\n}\n\ndouble errorFor(int member) {\n    double err = 0;\n    for (auto& p : obs[member]) {\n        int w = computeW(D[p.first], estS[member]);\n        int pred = (w == 0) ? 1 : max(1, w);\n        double diff = (double)pred - p.second;\n        err += diff * diff;\n    }\n    return err;\n}\n\nvoid updateSkills(int member) {\n    if (obs[member].empty()) return;\n    double best = errorFor(member);\n    for (int pass = 0; pass < 100; pass++) {\n        bool improved = false;\n        for (int k = 0; k < K; k++) {\n            for (int delta : {1, -1, 2, -2, 3, -3}) {\n                int old = estS[member][k];\n                int nv = old + delta;\n                if (nv < 0 || nv > 50) continue;\n                estS[member][k] = nv;\n                double e = errorFor(member);\n                if (e < best - 1e-9) {\n                    best = e;\n                    improved = true;\n                } else {\n                    estS[member][k] = old;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> N >> M >> K >> R;\n    D.assign(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> D[i][k];\n    deps.assign(N, {});\n    children.assign(N, {});\n    indeg.assign(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u);\n        children[u].push_back(v);\n        indeg[v]++;\n    }\n    \n    longestPath.assign(N, 0);\n    for (int i = N - 1; i >= 0; i--) {\n        int b = 0;\n        for (int ch : children[i]) b = max(b, longestPath[ch]);\n        longestPath[i] = b + 1;\n    }\n    \n    estS.assign(M, vector<int>(K, 3));\n    obs.assign(M, {});\n    \n    vector<int> taskStatus(N, 0);\n    vector<int> memberTask(M, -1);\n    vector<int> memberStartDay(M, 0);\n    vector<int> remIndeg = indeg;\n    \n    for (int day = 1; day <= 2000; day++) {\n        vector<int> avail;\n        for (int i = 0; i < N; i++)\n            if (taskStatus[i] == 0 && remIndeg[i] == 0) avail.push_back(i);\n        \n        sort(avail.begin(), avail.end(), [&](int a, int b) {\n            return longestPath[a] > longestPath[b];\n        });\n        \n        set<int> freeSet;\n        for (int j = 0; j < M; j++) if (memberTask[j] == -1) freeSet.insert(j);\n        \n        vector<pair<int,int>> assignments;\n        for (int task : avail) {\n            if (freeSet.empty()) break;\n            int bestMem = -1, bestTime = INT_MAX;\n            for (int j : freeSet) {\n                int t = predictTime(task, j);\n                if (t < bestTime) { bestTime = t; bestMem = j; }\n            }\n            if (bestMem != -1) {\n                assignments.push_back({bestMem, task});\n                freeSet.erase(bestMem);\n                taskStatus[task] = 1;\n                memberTask[bestMem] = task;\n                memberStartDay[bestMem] = day;\n            }\n        }\n        \n        cout << assignments.size();\n        for (auto& p : assignments) cout << \" \" << (p.first+1) << \" \" << (p.second+1);\n        cout << \"\\n\";\n        cout.flush();\n        \n        int n; cin >> n;\n        if (n == -1) return 0;\n        for (int i = 0; i < n; i++) {\n            int f; cin >> f; f--;\n            int task = memberTask[f];\n            int daysTaken = day - memberStartDay[f] + 1;\n            obs[f].push_back({task, daysTaken});\n            taskStatus[task] = 2;\n            memberTask[f] = -1;\n            for (int ch : children[task]) remIndeg[ch]--;\n            updateSkills(f);\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint A[1000][4];\n\ninline int px(int id) { \n    if(id<=0) return 400;\n    if(id<=1000) return A[id-1][0];\n    return A[id-1001][2];\n}\ninline int py(int id) {\n    if(id<=0) return 400;\n    if(id<=1000) return A[id-1][1];\n    return A[id-1001][3];\n}\ninline int D(int a, int b) {\n    return abs(px(a)-px(b))+abs(py(a)-py(b));\n}\n\nint routeCost(const vector<int>& s){\n    int t=0;\n    for(int i=0;i+1<(int)s.size();i++) t+=D(s[i],s[i+1]);\n    return t;\n}\n\nint insertOrderBest(vector<int>& s, int oid){\n    int p = oid+1, d = oid+1001;\n    int best = INT_MAX;\n    int bi=1,bj=1;\n    int n = s.size();\n    for(int i=1;i<n;i++){\n        int dss = D(s[i-1],s[i]);\n        int dps = D(s[i-1],p);\n        int dpe = D(p,s[i]);\n        {\n            int delta = dps + D(p,d) + D(d,s[i]) - dss;\n            if(delta<best){best=delta;bi=i;bj=i;}\n        }\n        int baseP = dps+dpe-dss;\n        for(int j=i+1;j<n;j++){\n            int delta = baseP + D(s[j-1],d)+D(d,s[j])-D(s[j-1],s[j]);\n            if(delta<best){best=delta;bi=i;bj=j;}\n        }\n    }\n    if(bi==bj){\n        s.insert(s.begin()+bi, d);\n        s.insert(s.begin()+bi, p);\n    } else {\n        s.insert(s.begin()+bj, d);\n        s.insert(s.begin()+bi, p);\n    }\n    return best;\n}\n\nint removeOrderDelta(vector<int>& s, int oid){\n    int p=oid+1, d=oid+1001;\n    int ip=-1, idx_=-1;\n    int n=s.size();\n    for(int i=0;i<n;i++){\n        if(s[i]==p) ip=i;\n        else if(s[i]==d) idx_=i;\n    }\n    int delta = 0;\n    if(idx_ == ip+1){\n        delta = D(s[ip-1], s[idx_+1]) - D(s[ip-1],p) - D(p,d) - D(d, s[idx_+1]);\n        s.erase(s.begin()+ip, s.begin()+idx_+1);\n    } else {\n        delta -= D(s[ip-1],p) + D(p, s[ip+1]);\n        delta += D(s[ip-1], s[ip+1]);\n        delta -= D(s[idx_-1], d) + D(d, s[idx_+1]);\n        delta += D(s[idx_-1], s[idx_+1]);\n        s.erase(s.begin()+idx_);\n        s.erase(s.begin()+ip);\n    }\n    return delta;\n}\n\nstatic int POS_[2001];\nstatic int PP_[128];\n\nint relocateOnce(vector<int>& s){\n    int n = s.size();\n    for(int i=0;i<n;i++) POS_[s[i]]=i;\n    for(int i=0;i<n;i++){\n        int id = s[i];\n        if(id<=0){ PP_[i]=-1; continue; }\n        int partner = (id<=1000) ? id+1000 : id-1000;\n        PP_[i] = POS_[partner];\n    }\n    \n    int bestDelta = 0;\n    int bestFrom=-1, bestTo=-1;\n    for(int from=1;from<n-1;from++){\n        int id = s[from];\n        if(id<=0) continue;\n        bool isPickup = (id<=1000);\n        int pp = PP_[from];\n        int lo, hi;\n        if(isPickup){ lo=1; hi=pp; }\n        else { lo=pp+1; hi=n; }\n        int remGain = D(s[from-1],s[from])+D(s[from],s[from+1])-D(s[from-1],s[from+1]);\n        for(int to=lo;to<=hi;to++){\n            if(to==from || to==from+1) continue;\n            int aa = s[to-1], bb = s[to];\n            int insCost = D(aa,id)+D(id,bb)-D(aa,bb);\n            int delta = insCost - remGain;\n            if(delta < bestDelta){\n                bestDelta = delta;\n                bestFrom = from;\n                bestTo = to;\n            }\n        }\n    }\n    if(bestDelta<0){\n        int id = s[bestFrom];\n        s.erase(s.begin()+bestFrom);\n        int to = bestTo;\n        if(to>bestFrom) to--;\n        s.insert(s.begin()+to, id);\n        return bestDelta;\n    }\n    return 0;\n}\n\nint twoOptOnce(vector<int>& s){\n    int n = s.size();\n    for(int i=0;i<n;i++) POS_[s[i]]=i;\n    for(int i=0;i<n;i++){\n        int id = s[i];\n        if(id<=0){ PP_[i]=-1; continue; }\n        int partner = (id<=1000) ? id+1000 : id-1000;\n        PP_[i] = POS_[partner];\n    }\n    int bestDelta = 0;\n    int bi=-1, bj=-1;\n    for(int i=1;i<n-2;i++){\n        int pairCount = 0;\n        int si_1 = s[i-1], si = s[i];\n        int d_im1_i = D(si_1, si);\n        for(int j=i+1;j<n-1;j++){\n            if(PP_[j] >= i && PP_[j] < j) pairCount++;\n            if(pairCount == 0){\n                int sj = s[j], sj1 = s[j+1];\n                int delta = D(si_1, sj) + D(si, sj1) - d_im1_i - D(sj, sj1);\n                if(delta < bestDelta){ bestDelta = delta; bi=i; bj=j; }\n            }\n        }\n    }\n    if(bestDelta<0){\n        reverse(s.begin()+bi, s.begin()+bj+1);\n        return bestDelta;\n    }\n    return 0;\n}\n\nint main(){\n    auto start = steady_clock::now();\n    for(int i=0;i<1000;i++) for(int j=0;j<4;j++) cin>>A[i][j];\n    \n    vector<pair<int,int>> scored(1000);\n    for(int i=0;i<1000;i++){\n        int s = abs(A[i][0]-400)+abs(A[i][1]-400)+abs(A[i][2]-400)+abs(A[i][3]-400);\n        scored[i]={s,i};\n    }\n    sort(scored.begin(),scored.end());\n    \n    vector<bool> inChosen(1000,false);\n    vector<int> chosen;\n    for(int i=0;i<50;i++){ chosen.push_back(scored[i].second); inChosen[scored[i].second]=true; }\n    \n    vector<int> seq = {0, 0};\n    for(int oid : chosen) insertOrderBest(seq, oid);\n    int curCost = routeCost(seq);\n    \n    auto localOpt = [&](){\n        int d;\n        bool improved = true;\n        while(improved){\n            improved = false;\n            while((d = twoOptOnce(seq)) < 0){ curCost += d; improved = true; }\n            while((d = relocateOnce(seq)) < 0){ curCost += d; improved = true; }\n        }\n    };\n    \n    localOpt();\n    \n    mt19937 rng(12345);\n    int timeLimit = 1850;\n    vector<int> backup;\n    int bestCost = curCost;\n    vector<int> bestSeq = seq;\n    vector<int> bestChosen = chosen;\n    vector<bool> bestInChosen = inChosen;\n    \n    long long iter = 0;\n    double progress = 0.0;\n    double t0 = 30.0, t1 = 0.5;\n    \n    while(true){\n        if((iter&127)==0){\n            auto el = duration_cast<milliseconds>(steady_clock::now()-start).count();\n            if(el>timeLimit) break;\n            progress = el / (double)timeLimit;\n        }\n        iter++;\n        double temp = t0 * pow(t1/t0, progress);\n        \n        int idx = rng()%50;\n        int oldOrd = chosen[idx];\n        int newOrd;\n        do { newOrd = rng()%1000; } while(inChosen[newOrd]);\n        \n        backup = seq;\n        int savedCost = curCost;\n        int remDelta = removeOrderDelta(seq, oldOrd);\n        int insDelta = insertOrderBest(seq, newOrd);\n        curCost += remDelta + insDelta;\n        int d;\n        if((d = twoOptOnce(seq)) < 0) curCost += d;\n        if((d = relocateOnce(seq)) < 0) curCost += d;\n        if((d = twoOptOnce(seq)) < 0) curCost += d;\n        \n        int diff = curCost - savedCost;\n        bool accept = false;\n        if(diff <= 0) accept = true;\n        else {\n            double prob = exp(-diff/temp);\n            if((rng()&0xFFFFFF)/(double)0x1000000 < prob) accept = true;\n        }\n        \n        if(accept){\n            inChosen[oldOrd]=false;\n            inChosen[newOrd]=true;\n            chosen[idx]=newOrd;\n            if(curCost < bestCost){\n                localOpt();\n                if(curCost < bestCost){\n                    bestCost = curCost;\n                    bestSeq = seq;\n                    bestChosen = chosen;\n                    bestInChosen = inChosen;\n                }\n            }\n        } else {\n            seq = backup;\n            curCost = savedCost;\n        }\n    }\n    \n    seq = bestSeq;\n    chosen = bestChosen;\n    curCost = bestCost;\n    localOpt();\n    \n    cout << 50;\n    vector<int> ords;\n    set<int> seen;\n    for(int id : seq){\n        if(id>=1 && id<=1000 && !seen.count(id-1)){\n            ords.push_back(id-1);\n            seen.insert(id-1);\n        }\n    }\n    for(int o : ords) cout << \" \" << (o+1);\n    cout << \"\\n\";\n    cout << seq.size();\n    for(int id : seq) cout << \" \" << px(id) << \" \" << py(id);\n    cout << \"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\n#include <sys/time.h>\nusing namespace std;\n\ndouble get_time(){\n    struct timeval tv;\n    gettimeofday(&tv, NULL);\n    return tv.tv_sec + tv.tv_usec * 1e-6;\n}\n\nstruct DSU {\n    int p[400], r[400];\n    void init(int n){ for(int i=0;i<n;i++){p[i]=i;r[i]=0;} }\n    int f(int x){ while(p[x]!=x){p[x]=p[p[x]];x=p[x];} return x; }\n    bool u(int a,int b){ a=f(a);b=f(b); if(a==b)return false; if(r[a]<r[b])swap(a,b); p[b]=a; if(r[a]==r[b])r[a]++; return true; }\n};\n\nint N=400, M=1995;\nint X[400], Y[400];\nint U[2000], V[2000], D[2000];\n\nconst int WMAX = 4000;\nint bkt_head[WMAX+2];\nint bkt_next[2100];\nint ea[2100], eb[2100], ew[2100];\nDSU sim;\n\nint main(){\n    double startTime = get_time();\n    double timeLimit = 1.80;\n    \n    for(int i=0;i<N;i++) scanf(\"%d %d\", &X[i], &Y[i]);\n    for(int i=0;i<M;i++){\n        scanf(\"%d %d\", &U[i], &V[i]);\n        double dx=X[U[i]]-X[V[i]], dy=Y[U[i]]-Y[V[i]];\n        D[i] = (int)round(sqrt(dx*dx+dy*dy));\n        if(D[i]<1) D[i]=1;\n    }\n    \n    vector<tuple<int,int,int>> adoptedEdges;\n    DSU glob; glob.init(N);\n    \n    uint64_t rng_state = 88172645463325252ULL;\n    auto rnd = [&]() -> uint32_t {\n        rng_state ^= rng_state << 13;\n        rng_state ^= rng_state >> 7;\n        rng_state ^= rng_state << 17;\n        return (uint32_t)rng_state;\n    };\n    \n    for(int i=0;i<M;i++){\n        int l; scanf(\"%d\", &l);\n        \n        if(glob.f(U[i]) == glob.f(V[i])){\n            printf(\"0\\n\"); fflush(stdout);\n            continue;\n        }\n        \n        int cnt = 0;\n        int maxW = 0;\n        for(auto& [w,a,b]: adoptedEdges){\n            ew[cnt]=w; ea[cnt]=a; eb[cnt]=b; cnt++;\n            if(w>maxW) maxW=w;\n        }\n        ew[cnt]=l; ea[cnt]=U[i]; eb[cnt]=V[i];\n        int curIdx = cnt;\n        if(l>maxW) maxW=l;\n        cnt++;\n        int staticCnt = cnt;\n        \n        for(int j=i+1;j<M;j++){\n            ea[cnt]=U[j]; eb[cnt]=V[j]; cnt++;\n        }\n        \n        double elapsed = get_time() - startTime;\n        double remTime = timeLimit - elapsed;\n        int remEdges = M - i;\n        double perEdgeBudget = remTime > 0 ? remTime / remEdges : 0.00001;\n        \n        const int MAX_TRIALS = 150;\n        const int MIN_TRIALS = 10;\n        int adoptCount = 0;\n        int done = 0;\n        double edgeStart = get_time();\n        \n        for(int t=0; t<MAX_TRIALS; t++){\n            int tmpMax = maxW;\n            for(int k=staticCnt; k<cnt; k++){\n                int j = i+1 + (k - staticCnt);\n                int range = 2*D[j]+1;\n                int w = D[j] + (int)(rnd() % (uint32_t)range);\n                ew[k] = w;\n                if(w > tmpMax) tmpMax = w;\n            }\n            \n            for(int w=0; w<=tmpMax; w++) bkt_head[w] = -1;\n            for(int k=0; k<cnt; k++){\n                bkt_next[k] = bkt_head[ew[k]];\n                bkt_head[ew[k]] = k;\n            }\n            \n            sim.init(N);\n            bool used = false;\n            int compCount = N;\n            for(int w=0; w<=tmpMax && compCount>1; w++){\n                for(int k=bkt_head[w]; k!=-1; k=bkt_next[k]){\n                    if(sim.u(ea[k], eb[k])){\n                        compCount--;\n                        if(k == curIdx) used = true;\n                    }\n                }\n            }\n            \n            if(used) adoptCount++;\n            done++;\n            \n            if(done >= MIN_TRIALS && (done & 7) == 0){\n                double edgeElapsed = get_time() - edgeStart;\n                if(edgeElapsed > perEdgeBudget) break;\n                int rem = MAX_TRIALS - done;\n                // confident decision?\n                if(adoptCount > (done + rem + 10)/2) break;\n                if((done - adoptCount) > (done + rem + 10)/2) break;\n            }\n        }\n        \n        bool adopt = (adoptCount * 2 >= done);\n        \n        if(adopt){\n            printf(\"1\\n\");\n            adoptedEdges.push_back({l, U[i], V[i]});\n            glob.u(U[i], V[i]);\n        } else {\n            printf(\"0\\n\");\n        }\n        fflush(stdout);\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint pt[25];\nint hx[15], hy[15];\nint grid[32][32];\nvector<pair<int,int>> pets;\n\nint dx4[] = {-1,1,0,0};\nint dy4[] = {0,0,-1,1};\nchar mvch[] = {'U','D','L','R'};\n\nbool inb(int x, int y) { return x>=1 && x<=30 && y>=1 && y<=30; }\n\nbool canWall(int x, int y) {\n    if (!inb(x,y)) return false;\n    if (grid[x][y]) return false;\n    for (auto& p : pets) if (p.first==x && p.second==y) return false;\n    for (int i=0;i<M;i++) if (hx[i]==x && hy[i]==y) return false;\n    for (int d=0;d<4;d++) {\n        int nx=x+dx4[d], ny=y+dy4[d];\n        for (auto& p : pets) if (p.first==nx && p.second==ny) return false;\n    }\n    return true;\n}\n\nint main(){\n    cin >> N;\n    pets.resize(N);\n    for (int i=0;i<N;i++){\n        int x,y,t; cin >> x >> y >> t;\n        pets[i]={x,y}; pt[i]=t;\n    }\n    cin >> M;\n    for (int i=0;i<M;i++) cin >> hx[i] >> hy[i];\n    memset(grid,0,sizeof(grid));\n    \n    vector<int> topH, botH;\n    for (int i=0;i<M;i++){\n        if (hx[i] <= 15) topH.push_back(i);\n        else botH.push_back(i);\n    }\n    if (topH.empty() && !botH.empty()) {\n        int half = (botH.size()+1)/2;\n        for (int k=0;k<half;k++) topH.push_back(botH[k]);\n        botH.erase(botH.begin(), botH.begin()+half);\n    } else if (botH.empty() && !topH.empty()) {\n        int half = (topH.size()+1)/2;\n        for (int k=0;k<half;k++) botH.push_back(topH[k]);\n        topH.erase(topH.begin(), topH.begin()+half);\n    }\n    \n    sort(topH.begin(), topH.end(), [](int a, int b){return hy[a]<hy[b];});\n    sort(botH.begin(), botH.end(), [](int a, int b){return hy[a]<hy[b];});\n    \n    vector<vector<tuple<int,int,char>>> tasks(M);\n    \n    auto assignGroup = [&](vector<int>& group, int wallRow, int standDir) {\n        int n = group.size();\n        if (n == 0) return;\n        \n        for (int k=0; k<n; k++){\n            int cs = 1 + k*30/n, ce = (k+1)*30/n;\n            int hi = group[k];\n            int sr = wallRow + standDir;\n            char dir = (standDir == -1) ? 'd' : 'u';\n            vector<int> cols;\n            if (abs(hy[hi] - cs) < abs(hy[hi] - ce)){\n                for (int c = cs; c <= ce; c++) cols.push_back(c);\n            } else {\n                for (int c = ce; c >= cs; c--) cols.push_back(c);\n            }\n            for (int c : cols) tasks[hi].push_back({sr, c, dir});\n        }\n        \n        for (int k=0; k<n-1; k++){\n            int cs_k = 1 + k*30/n, ce_k = (k+1)*30/n;\n            if (ce_k - cs_k < 1) continue;\n            int hi = group[k];\n            int dividerCol = ce_k;\n            int standCol = dividerCol - 1;\n            char dir = 'r';\n            \n            int r_start, r_end, r_step;\n            if (standDir == -1) {\n                r_start = wallRow - 1; r_end = 1; r_step = -1;\n            } else {\n                r_start = wallRow + 1; r_end = 30; r_step = 1;\n            }\n            \n            for (int r = r_start; r != r_end + r_step; r += r_step){\n                tasks[hi].push_back({r, standCol, dir});\n            }\n        }\n    };\n    \n    assignGroup(topH, 9, -1);\n    assignGroup(botH, 21, +1);\n    \n    vector<int> taskIdx(M, 0);\n    \n    auto wallPos = [&](int sr, int sc, char dir) -> pair<int,int> {\n        if (dir == 'u') return {sr-1, sc};\n        if (dir == 'd') return {sr+1, sc};\n        if (dir == 'l') return {sr, sc-1};\n        return {sr, sc+1};\n    };\n    \n    for (int turn=0; turn<300; turn++){\n        string action(M,'.');\n        vector<pair<int,int>> newWalls;\n        vector<pair<int,int>> nextPos(M);\n        for (int i=0;i<M;i++) nextPos[i] = {hx[i], hy[i]};\n        \n        vector<bool> decided(M, false);\n        \n        for (int i=0;i<M;i++){\n            while (taskIdx[i] < (int)tasks[i].size()){\n                auto [sr, sc, dir] = tasks[i][taskIdx[i]];\n                auto [wr, wc] = wallPos(sr, sc, dir);\n                if (grid[wr][wc]) taskIdx[i]++;\n                else break;\n            }\n        }\n        \n        for (int i=0;i<M;i++){\n            int cx=hx[i], cy=hy[i];\n            if (taskIdx[i] >= (int)tasks[i].size()) { decided[i]=true; continue; }\n            auto [sr, sc, dir] = tasks[i][taskIdx[i]];\n            auto [wr, wc] = wallPos(sr, sc, dir);\n            \n            if (cx == sr && cy == sc){\n                if (canWall(wr, wc)){\n                    action[i] = dir;\n                    newWalls.push_back({wr, wc});\n                    taskIdx[i]++;\n                    decided[i] = true;\n                } else {\n                    action[i]='.';\n                    decided[i] = true;\n                }\n            }\n        }\n        \n        auto isPlannedWall = [&](int x, int y) {\n            for (auto& w : newWalls) if (w.first==x && w.second==y) return true;\n            return false;\n        };\n        auto isOtherDest = [&](int x, int y, int skip) {\n            for (int i=0;i<M;i++) if (i!=skip && nextPos[i].first==x && nextPos[i].second==y) return true;\n            return false;\n        };\n        \n        for (int i=0;i<M;i++){\n            if (decided[i]) continue;\n            int cx=hx[i], cy=hy[i];\n            if (taskIdx[i] >= (int)tasks[i].size()) continue;\n            auto [sr, sc, dir] = tasks[i][taskIdx[i]];\n            \n            vector<vector<int>> dist(32, vector<int>(32, -1));\n            if (inb(sr,sc) && !grid[sr][sc] && !isPlannedWall(sr,sc)){\n                queue<pair<int,int>> q;\n                dist[sr][sc]=0; q.push({sr,sc});\n                while(!q.empty()){\n                    auto [x,y]=q.front(); q.pop();\n                    for (int d=0;d<4;d++){\n                        int nx=x+dx4[d], ny=y+dy4[d];\n                        if (!inb(nx,ny)||grid[nx][ny]||dist[nx][ny]!=-1) continue;\n                        if (isPlannedWall(nx,ny)) continue;\n                        dist[nx][ny]=dist[x][y]+1;\n                        q.push({nx,ny});\n                    }\n                }\n            }\n            \n            bool moved = false;\n            if (dist[cx][cy] > 0){\n                for (int d=0;d<4;d++){\n                    int nx=cx+dx4[d], ny=cy+dy4[d];\n                    if (!inb(nx,ny)||grid[nx][ny]) continue;\n                    if (isPlannedWall(nx,ny)) continue;\n                    if (dist[nx][ny]==dist[cx][cy]-1 && !isOtherDest(nx,ny,i)){\n                        action[i]=mvch[d];\n                        nextPos[i]={nx,ny};\n                        moved = true;\n                        break;\n                    }\n                }\n            }\n            \n            if (!moved && dist[cx][cy] == -1) {\n                taskIdx[i]++;\n            }\n        }\n        \n        for (int i=0;i<M;i++){\n            char a = action[i];\n            if (a=='U'||a=='D'||a=='L'||a=='R'){\n                if (isPlannedWall(nextPos[i].first, nextPos[i].second)){\n                    action[i] = '.';\n                    nextPos[i] = {hx[i], hy[i]};\n                }\n            }\n        }\n        \n        cout << action << endl;\n        cout.flush();\n        \n        for (int i=0;i<M;i++){\n            char a = action[i];\n            if (a=='U'||a=='D'||a=='L'||a=='R'){\n                int d = (a=='U')?0:(a=='D')?1:(a=='L')?2:3;\n                hx[i]+=dx4[d]; hy[i]+=dy4[d];\n            }\n        }\n        for (auto& w : newWalls) grid[w.first][w.second]=1;\n        \n        for (int i=0;i<N;i++){\n            string s; cin >> s;\n            int x=pets[i].first, y=pets[i].second;\n            for (char c : s){\n                if (c=='U') x--;\n                else if (c=='D') x++;\n                else if (c=='L') y--;\n                else if (c=='R') y++;\n            }\n            pets[i]={x,y};\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si,sj,ti,tj;\ndouble p;\nint H[20][19], V[19][20];\n\ninline bool canMove(int i,int j,char c){\n    if(c=='U') return i>0 && V[i-1][j]==0;\n    if(c=='D') return i<19 && V[i][j]==0;\n    if(c=='L') return j>0 && H[i][j-1]==0;\n    return j<19 && H[i][j]==0;\n}\ninline pair<int,int> move1(int i,int j,char c){\n    if(!canMove(i,j,c)) return {i,j};\n    if(c=='U') return {i-1,j};\n    if(c=='D') return {i+1,j};\n    if(c=='L') return {i,j-1};\n    return {i,j+1};\n}\n\ndouble evalScore(const string& s){\n    static double dist[400], nd[400];\n    memset(dist,0,sizeof(dist));\n    int start_idx = si*20+sj;\n    int goal_idx = ti*20+tj;\n    dist[start_idx]=1.0;\n    if(start_idx==goal_idx) return 400.0;\n    double score=0;\n    int L=s.size();\n    double pp=p, q=1-p;\n    for(int t=0;t<L;t++){\n        char c=s[t];\n        memset(nd,0,sizeof(nd));\n        for(int idx=0;idx<400;idx++){\n            double d=dist[idx];\n            if(d<1e-18) continue;\n            int i=idx/20, j=idx%20;\n            nd[idx] += d*pp;\n            auto [ni,nj]=move1(i,j,c);\n            nd[ni*20+nj] += d*q;\n        }\n        double arrived = nd[goal_idx];\n        score += arrived * (400 - t);\n        nd[goal_idx]=0;\n        memcpy(dist,nd,sizeof(dist));\n    }\n    return score;\n}\n\nvector<string> findPaths(int maxPaths, mt19937& rng){\n    vector<string> paths;\n    set<string> seen;\n    string dirs=\"UDLR\";\n    \n    auto bfsPath=[&](string order)->string{\n        vector<vector<int>> bd(20,vector<int>(20,-1));\n        vector<vector<pair<int,int>>> par(20,vector<pair<int,int>>(20,{-1,-1}));\n        vector<vector<char>> pc(20,vector<char>(20,0));\n        queue<pair<int,int>> q;\n        q.push({si,sj}); bd[si][sj]=0;\n        while(!q.empty()){\n            auto [i,j]=q.front(); q.pop();\n            for(char c:order){\n                if(canMove(i,j,c)){\n                    auto [ni,nj]=move1(i,j,c);\n                    if(bd[ni][nj]==-1){\n                        bd[ni][nj]=bd[i][j]+1;\n                        par[ni][nj]={i,j};\n                        pc[ni][nj]=c;\n                        q.push({ni,nj});\n                    }\n                }\n            }\n        }\n        string path;\n        int ci=ti,cj=tj;\n        if(bd[ti][tj]==-1) return \"\";\n        while(!(ci==si&&cj==sj)){\n            path+=pc[ci][cj];\n            auto [pi,pj]=par[ci][cj];\n            ci=pi; cj=pj;\n        }\n        reverse(path.begin(),path.end());\n        return path;\n    };\n    \n    string p1=bfsPath(\"UDLR\");\n    paths.push_back(p1); seen.insert(p1);\n    int shortestLen=p1.size();\n    \n    for(int attempt=0; attempt<300 && (int)paths.size()<maxPaths; attempt++){\n        string d=dirs;\n        shuffle(d.begin(),d.end(),rng);\n        string path=bfsPath(d);\n        if(!path.empty() && (int)path.size() <= shortestLen+4 && !seen.count(path)){\n            paths.push_back(path);\n            seen.insert(path);\n        }\n    }\n    return paths;\n}\n\nint main(){\n    cin>>si>>sj>>ti>>tj>>p;\n    for(int i=0;i<20;i++){\n        string s; cin>>s;\n        for(int j=0;j<19;j++) H[i][j]=s[j]-'0';\n    }\n    for(int i=0;i<19;i++){\n        string s; cin>>s;\n        for(int j=0;j<20;j++) V[i][j]=s[j]-'0';\n    }\n    \n    auto start=chrono::steady_clock::now();\n    auto elapsedMs=[&](){\n        auto now=chrono::steady_clock::now();\n        return chrono::duration_cast<chrono::milliseconds>(now-start).count();\n    };\n    \n    mt19937 rng(12345);\n    \n    vector<string> paths = findPaths(20, rng);\n    \n    string best=\"\";\n    double bestScore=-1;\n    string dirs=\"UDLR\";\n    \n    for(auto& path : paths){\n        int L=path.size();\n        if(L==0) continue;\n        for(int k=1; k*L<=200; k++){\n            string cand;\n            for(char c:path) for(int r=0;r<k;r++) cand+=c;\n            double sc=evalScore(cand);\n            if(sc>bestScore){bestScore=sc; best=cand;}\n        }\n        for(int k=1; k*L<=200; k++){\n            string cand;\n            for(char c:path) for(int r=0;r<k;r++) cand+=c;\n            while((int)cand.size()<200) cand+=path.back();\n            double sc=evalScore(cand);\n            if(sc>bestScore){bestScore=sc; best=cand;}\n        }\n    }\n    \n    int TIME_LIMIT = 1800;\n    \n    // Local search\n    bool improved=true;\n    while(improved && elapsedMs()<TIME_LIMIT){\n        improved=false;\n        // substitution\n        for(int pos=0;pos<(int)best.size() && elapsedMs()<TIME_LIMIT;pos++){\n            char orig=best[pos];\n            for(char c : dirs){\n                if(c==orig) continue;\n                best[pos]=c;\n                double sc=evalScore(best);\n                if(sc>bestScore+1e-9){bestScore=sc; improved=true; orig=c;}\n                else best[pos]=orig;\n            }\n        }\n        // deletion\n        for(int pos=0;pos<(int)best.size() && elapsedMs()<TIME_LIMIT;pos++){\n            string cand=best;\n            cand.erase(cand.begin()+pos);\n            double sc=evalScore(cand);\n            if(sc>bestScore+1e-9){bestScore=sc; best=cand; improved=true; pos--;}\n        }\n        // insertion\n        for(int pos=0;pos<=(int)best.size() && (int)best.size()<200 && elapsedMs()<TIME_LIMIT;pos++){\n            for(char c : dirs){\n                string cand=best;\n                cand.insert(cand.begin()+pos,c);\n                double sc=evalScore(cand);\n                if(sc>bestScore+1e-9){bestScore=sc; best=cand; improved=true; break;}\n            }\n        }\n    }\n    \n    cout<<best<<endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int to_dir[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\nstatic const int di[4] = {0, -1, 0, 1};\nstatic const int dj[4] = {-1, 0, 1, 0};\nstatic const int rot1[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n\nstatic int tiles[30][30];\nstatic int visited[30][30][4];\nstatic int gen = 0;\n\nstruct EvalRes {\n    long long score;\n    long long proxy;\n};\n\ninline EvalRes evaluate() {\n    gen++;\n    int L1 = 0, L2 = 0;\n    long long sumSq = 0;\n    for (int si = 0; si < 30; si++) {\n        for (int sj = 0; sj < 30; sj++) {\n            for (int sd = 0; sd < 4; sd++) {\n                if (visited[si][sj][sd] == gen) continue;\n                int i = si, j = sj, d = sd;\n                int len = 0;\n                while (true) {\n                    if (visited[i][j][d] == gen) break;\n                    visited[i][j][d] = gen;\n                    int d2 = to_dir[tiles[i][j]][d];\n                    if (d2 < 0) break;\n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if ((unsigned)ni >= 30 || (unsigned)nj >= 30) break;\n                    int nd = d2 ^ 2;\n                    len++;\n                    if (ni == si && nj == sj && nd == sd) {\n                        if (len > L1) { L2 = L1; L1 = len; }\n                        else if (len > L2) L2 = len;\n                        sumSq += (long long)len * len;\n                        break;\n                    }\n                    i = ni; j = nj; d = nd;\n                }\n            }\n        }\n    }\n    return {(long long)L1 * L2, sumSq};\n}\n\nstatic int rot[30][30];\nstatic int bestRot[30][30];\nstatic int inputG[30][30];\n\ninline void applyRot(int i, int j, int r) {\n    rot[i][j] = r;\n    int t = inputG[i][j];\n    for (int k = 0; k < r; k++) t = rot1[t];\n    tiles[i][j] = t;\n}\n\nstatic uint64_t xrand_state = 0x12345678abcdef01ULL;\ninline uint64_t xrand() {\n    uint64_t x = xrand_state;\n    x ^= x << 13;\n    x ^= x >> 7;\n    x ^= x << 17;\n    xrand_state = x;\n    return x;\n}\ninline double frand() {\n    return (double)(xrand() & 0xFFFFFFFFULL) / (double)0x100000000ULL;\n}\n\nint main() {\n    for (int i = 0; i < 30; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < 30; j++) inputG[i][j] = s[j]-'0';\n    }\n    \n    long long bestScore = 0;\n    auto start = chrono::steady_clock::now();\n    double TL = 1.9;\n    \n    int restart = 0;\n    bool done = false;\n    while (!done) {\n        auto now = chrono::steady_clock::now();\n        double elapsedTotal = chrono::duration<double>(now-start).count();\n        if (elapsedTotal > TL - 0.02) break;\n        \n        restart++;\n        for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) {\n            int r = (restart == 1) ? 0 : (int)(xrand()%4);\n            applyRot(i, j, r);\n        }\n        \n        auto cur = evaluate();\n        if (cur.score > bestScore) {\n            bestScore = cur.score;\n            memcpy(bestRot, rot, sizeof(rot));\n        }\n        \n        double restartBudget = 0.95;\n        if (TL - elapsedTotal < restartBudget) restartBudget = TL - elapsedTotal;\n        double restartStart = elapsedTotal;\n        \n        double T0 = 2000.0, T1 = 1.0;\n        int iter = 0;\n        double localElapsed = 0;\n        while (true) {\n            iter++;\n            if ((iter & 255) == 0) {\n                double e = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n                localElapsed = e - restartStart;\n                if (e > TL) { done = true; break; }\n                if (localElapsed > restartBudget) break;\n            }\n            double progress = localElapsed / restartBudget;\n            if (progress > 1) progress = 1;\n            double T = T0 * pow(T1/T0, progress);\n            \n            int mtype = (int)(xrand()%10);\n            if (mtype < 7) {\n                int i = (int)(xrand()%30), j = (int)(xrand()%30);\n                int oldR = rot[i][j];\n                int newR = (oldR + 1 + (int)(xrand()%3)) & 3;\n                applyRot(i, j, newR);\n                auto nw = evaluate();\n                long long delta = nw.proxy - cur.proxy;\n                if (delta >= 0 || frand() < exp((double)delta/T)) {\n                    cur = nw;\n                    if (nw.score > bestScore) {\n                        bestScore = nw.score;\n                        memcpy(bestRot, rot, sizeof(rot));\n                    }\n                } else {\n                    applyRot(i, j, oldR);\n                }\n            } else {\n                int i1 = (int)(xrand()%30), j1 = (int)(xrand()%30);\n                int i2 = (int)(xrand()%30), j2 = (int)(xrand()%30);\n                int oldR1 = rot[i1][j1], oldR2 = rot[i2][j2];\n                int newR1 = (oldR1 + 1 + (int)(xrand()%3)) & 3;\n                int newR2 = (oldR2 + 1 + (int)(xrand()%3)) & 3;\n                applyRot(i1, j1, newR1);\n                applyRot(i2, j2, newR2);\n                auto nw = evaluate();\n                long long delta = nw.proxy - cur.proxy;\n                if (delta >= 0 || frand() < exp((double)delta/T)) {\n                    cur = nw;\n                    if (nw.score > bestScore) {\n                        bestScore = nw.score;\n                        memcpy(bestRot, rot, sizeof(rot));\n                    }\n                } else {\n                    applyRot(i1, j1, oldR1);\n                    applyRot(i2, j2, oldR2);\n                }\n            }\n        }\n    }\n    \n    string out;\n    for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) out += char('0'+bestRot[i][j]);\n    cout << out << endl;\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nmt19937 rng(98765);\nint er, ec;\nvector<vector<int>> board;\n\nint computeTreeScore(const vector<vector<int>>& b) {\n    int n = N;\n    vector<int> par(n*n), sz(n*n, 1);\n    vector<bool> bad(n*n, false);\n    iota(par.begin(), par.end(), 0);\n    function<int(int)> find = [&](int x){ while(par[x]!=x){par[x]=par[par[x]];x=par[x];} return x;};\n    auto unite = [&](int a, int b){\n        int ra=find(a), rb=find(b);\n        if(ra==rb){ bad[ra]=true; return;}\n        bool nb = bad[ra]||bad[rb];\n        if(sz[ra]<sz[rb])swap(ra,rb);\n        par[rb]=ra; sz[ra]+=sz[rb]; bad[ra]=nb;\n    };\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        if(b[i][j]==0) continue;\n        if(j+1<n && b[i][j+1]!=0 && (b[i][j]&4) && (b[i][j+1]&1)) unite(i*n+j, i*n+j+1);\n        if(i+1<n && b[i+1][j]!=0 && (b[i][j]&8) && (b[i+1][j]&2)) unite(i*n+j, (i+1)*n+j);\n    }\n    int best=0;\n    for(int i=0;i<n*n;i++){\n        if(b[i/n][i%n]==0) continue;\n        if(find(i)==i && !bad[i]) best=max(best,sz[i]);\n    }\n    return best;\n}\n\nint computeBoundaryPenalty(const vector<vector<int>>& b) {\n    int n = N, penalty = 0;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        int v = b[i][j]; if(v==0) continue;\n        if((v&1) && j==0) penalty++;\n        if((v&2) && i==0) penalty++;\n        if((v&4) && j==n-1) penalty++;\n        if((v&8) && i==n-1) penalty++;\n    }\n    return penalty;\n}\n\nstring solveFromTarget(vector<vector<int>> tgt){\n    vector<vector<int>> B = board;\n    int br=er, bc=ec;\n    string moves;\n    vector<vector<bool>> locked(N, vector<bool>(N, false));\n    bool solveFailed = false;\n    \n    auto posOk = [&](int r, int c){ return r>=0&&r<N&&c>=0&&c<N; };\n    \n    auto moveBlankTo = [&](int tr, int tc, int avoidR, int avoidC)->bool{\n        if(br==tr&&bc==tc) return true;\n        if(!posOk(tr,tc)) return false;\n        if(locked[tr][tc]) return false;\n        if(tr==avoidR&&tc==avoidC) return false;\n        vector<vector<int>> dist(N, vector<int>(N,-1));\n        vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N,{-1,-1}));\n        queue<pair<int,int>> q;\n        dist[br][bc]=0; q.push({br,bc});\n        while(!q.empty()){\n            auto [r,c]=q.front(); q.pop();\n            int dr[]={-1,1,0,0}, dc[]={0,0,-1,1};\n            for(int d=0;d<4;d++){\n                int nr=r+dr[d], nc=c+dc[d];\n                if(!posOk(nr,nc)) continue;\n                if(locked[nr][nc]) continue;\n                if(nr==avoidR&&nc==avoidC) continue;\n                if(dist[nr][nc]!=-1) continue;\n                dist[nr][nc]=dist[r][c]+1;\n                par[nr][nc]={r,c};\n                q.push({nr,nc});\n            }\n        }\n        if(dist[tr][tc]==-1) return false;\n        vector<pair<int,int>> path;\n        int r=tr,c=tc;\n        while(!(r==br&&c==bc)){\n            path.push_back({r,c});\n            auto [pr,pc]=par[r][c]; r=pr; c=pc;\n        }\n        reverse(path.begin(), path.end());\n        for(auto [nr,nc]:path){\n            char mv;\n            if(nr==br-1&&nc==bc) mv='U';\n            else if(nr==br+1&&nc==bc) mv='D';\n            else if(nc==bc-1&&nr==br) mv='L';\n            else mv='R';\n            moves.push_back(mv);\n            swap(B[br][bc], B[nr][nc]);\n            br=nr; bc=nc;\n        }\n        return true;\n    };\n    \n    auto findTile = [&](int type, int nearR, int nearC)->pair<int,int>{\n        int bestR=-1,bestC=-1, bestD=INT_MAX;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            if(locked[i][j]) continue;\n            if(B[i][j]==type){\n                int d=abs(i-nearR)+abs(j-nearC);\n                if(d<bestD){bestD=d; bestR=i; bestC=j;}\n            }\n        }\n        return {bestR,bestC};\n    };\n    \n    auto moveTileTo = [&](int& sr, int& sc, int tr, int tc)->bool{\n        int safety = 0;\n        while(sr!=tr || sc!=tc){\n            if(++safety > 4*N*N) return false;\n            vector<pair<int,int>> candidates;\n            if(sr!=tr){\n                if(sr<tr) candidates.push_back({sr+1, sc}); else candidates.push_back({sr-1, sc});\n            }\n            if(sc!=tc){\n                if(sc<tc) candidates.push_back({sr, sc+1}); else candidates.push_back({sr, sc-1});\n            }\n            bool moved=false;\n            for(auto [cnr, cnc] : candidates){\n                if(!posOk(cnr,cnc)) continue;\n                if(locked[cnr][cnc]) continue;\n                int saveBr=br, saveBc=bc;\n                size_t saveMl = moves.size();\n                auto saveB = B;\n                if(moveBlankTo(cnr,cnc,sr,sc)){\n                    moved=true; break;\n                }\n                br=saveBr; bc=saveBc; moves.resize(saveMl); B=saveB;\n            }\n            if(!moved) return false;\n            char mv;\n            if(sr==br-1&&sc==bc) mv='U';\n            else if(sr==br+1&&sc==bc) mv='D';\n            else if(sc==bc-1&&sr==br) mv='L';\n            else if(sc==bc+1&&sr==br) mv='R';\n            else return false;\n            moves.push_back(mv);\n            swap(B[br][bc], B[sr][sc]);\n            int obr=br, obc=bc;\n            br=sr; bc=sc;\n            sr=obr; sc=obc;\n        }\n        return true;\n    };\n    \n    for(int r=0; r<N-2 && !solveFailed; r++){\n        for(int c=0; c<N-2; c++){\n            int type = tgt[r][c];\n            auto [sr,sc] = findTile(type, r, c);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==r&&sc==c)){\n                if(!moveTileTo(sr,sc,r,c)){solveFailed=true; break;}\n            }\n            locked[r][c]=true;\n        }\n        if(solveFailed) break;\n        \n        int typeA = tgt[r][N-2];\n        int typeB = tgt[r][N-1];\n        \n        if(B[r][N-2]==typeA && B[r][N-1]==typeB){\n            locked[r][N-2]=true; locked[r][N-1]=true;\n            continue;\n        }\n        \n        {\n            auto [sr,sc] = findTile(typeA, r, N-1);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==r && sc==N-1)){\n                if(sr==r && sc==N-2){\n                    if(!moveTileTo(sr,sc, r+1, N-2)){solveFailed=true; break;}\n                    auto p = findTile(typeA, r, N-1);\n                    sr=p.first; sc=p.second;\n                    if(sr==-1){solveFailed=true; break;}\n                }\n                if(!moveTileTo(sr, sc, r, N-1)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[r][N-1]=true;\n        \n        {\n            auto [sr,sc] = findTile(typeB, r+1, N-1);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==r+1 && sc==N-1)){\n                if(!moveTileTo(sr, sc, r+1, N-1)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[r+1][N-1]=true;\n        \n        locked[r][N-1]=false; locked[r+1][N-1]=false;\n        \n        if(!moveBlankTo(r, N-2, -1, -1)){solveFailed=true; break;}\n        moves.push_back('R');\n        swap(B[br][bc], B[r][N-1]); br=r; bc=N-1;\n        moves.push_back('D');\n        swap(B[br][bc], B[r+1][N-1]); br=r+1; bc=N-1;\n        \n        locked[r][N-2]=true; locked[r][N-1]=true;\n    }\n    \n    for(int c=0; c<N-2 && !solveFailed; c++){\n        int typeA = tgt[N-2][c];\n        int typeB = tgt[N-1][c];\n        \n        if(B[N-2][c]==typeA && B[N-1][c]==typeB){\n            locked[N-2][c]=true; locked[N-1][c]=true;\n            continue;\n        }\n        \n        {\n            auto [sr,sc] = findTile(typeA, N-1, c);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==N-1 && sc==c)){\n                if(sr==N-2 && sc==c){\n                    if(!moveTileTo(sr,sc, N-2, c+1)){solveFailed=true; break;}\n                    auto p = findTile(typeA, N-1, c);\n                    sr=p.first; sc=p.second;\n                    if(sr==-1){solveFailed=true; break;}\n                }\n                if(!moveTileTo(sr, sc, N-1, c)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[N-1][c]=true;\n        \n        {\n            auto [sr,sc] = findTile(typeB, N-1, c+1);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==N-1 && sc==c+1)){\n                if(!moveTileTo(sr, sc, N-1, c+1)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[N-1][c+1]=true;\n        \n        locked[N-1][c]=false; locked[N-1][c+1]=false;\n        \n        if(!moveBlankTo(N-2, c, -1, -1)){solveFailed=true; break;}\n        moves.push_back('D'); swap(B[br][bc], B[N-1][c]); br=N-1; bc=c;\n        moves.push_back('R'); swap(B[br][bc], B[N-1][c+1]); br=N-1; bc=c+1;\n        locked[N-2][c]=true; locked[N-1][c]=true;\n    }\n    \n    if(!solveFailed){\n        for(int attempt=0; attempt<8; attempt++){\n            bool match = (B[N-2][N-2]==tgt[N-2][N-2]) && (B[N-2][N-1]==tgt[N-2][N-1]) && (B[N-1][N-2]==tgt[N-1][N-2]);\n            if(match && br==N-1 && bc==N-1) break;\n            if(br==N-1&&bc==N-1){ moves.push_back('U'); swap(B[br][bc],B[N-2][N-1]); br=N-2;bc=N-1;}\n            else if(br==N-2&&bc==N-1){ moves.push_back('L'); swap(B[br][bc],B[N-2][N-2]); br=N-2;bc=N-2;}\n            else if(br==N-2&&bc==N-2){ moves.push_back('D'); swap(B[br][bc],B[N-1][N-2]); br=N-1;bc=N-2;}\n            else if(br==N-1&&bc==N-2){ moves.push_back('R'); swap(B[br][bc],B[N-1][N-1]); br=N-1;bc=N-1;}\n        }\n    }\n    \n    return moves;\n}\n\nstring eliminateCycles(const string& mv){\n    vector<vector<int>> B = board;\n    int br=er, bc=ec;\n    auto hashState = [&]() -> uint64_t {\n        uint64_t h = 1469598103934665603ULL;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            h = h*31 + (uint64_t)B[i][j];\n        }\n        h = h*31 + (uint64_t)(br*N+bc);\n        return h;\n    };\n    vector<uint64_t> hashes;\n    hashes.push_back(hashState());\n    for(int i=0;i<(int)mv.size();i++){\n        char m = mv[i];\n        int nr=br, nc=bc;\n        if(m=='U') nr--;\n        else if(m=='D') nr++;\n        else if(m=='L') nc--;\n        else nc++;\n        if(nr<0||nr>=N||nc<0||nc>=N) { hashes.push_back(hashes.back()); continue; }\n        swap(B[br][bc], B[nr][nc]);\n        br=nr; bc=nc;\n        hashes.push_back(hashState());\n    }\n    unordered_map<uint64_t, int> lastIdx;\n    for(int i=(int)hashes.size()-1;i>=0;i--){\n        if(lastIdx.find(hashes[i])==lastIdx.end()){\n            lastIdx[hashes[i]] = i;\n        }\n    }\n    string result;\n    int i = 0;\n    int total = (int)mv.size();\n    while(i < total){\n        auto it = lastIdx.find(hashes[i]);\n        int jump = (it != lastIdx.end()) ? it->second : i;\n        if(jump > i){\n            i = jump; continue;\n        }\n        result.push_back(mv[i]);\n        i++;\n    }\n    return result;\n}\n\npair<string,int> processMoves(const string& mv){\n    vector<vector<int>> BB = board;\n    int bbr=er, bbc=ec;\n    int curS = computeTreeScore(BB);\n    int bestS = curS;\n    int bestLen = 0;\n    int fullLen = mv.size();\n    int lim = min(fullLen, T);\n    for(int i=0;i<lim;i++){\n        char m = mv[i];\n        int nr=bbr, nc=bbc;\n        if(m=='U') nr--;\n        else if(m=='D') nr++;\n        else if(m=='L') nc--;\n        else nc++;\n        if(nr<0||nr>=N||nc<0||nc>=N) break;\n        swap(BB[bbr][bbc], BB[nr][nc]);\n        bbr=nr; bbc=nc;\n        curS = computeTreeScore(BB);\n        if(curS > bestS){ bestS=curS; bestLen=i+1; }\n        if(curS == N*N-1){\n            return {mv.substr(0, i+1), curS};\n        }\n    }\n    return {mv.substr(0, bestLen), bestS};\n}\n\ndouble evalResult(const string& mv, int s){\n    if(s == N*N-1 && (int)mv.size() <= T){\n        return 500000.0 * (2.0 - (double)mv.size()/T);\n    }\n    return 500000.0 * s / (N*N-1);\n}\n\nint main(){\n    cin>>N>>T;\n    vector<string> initial(N);\n    for(auto&s:initial) cin>>s;\n    \n    board.assign(N, vector<int>(N));\n    er=0; ec=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        char c = initial[i][j];\n        int v = (c>='0'&&c<='9')?c-'0':c-'a'+10;\n        board[i][j]=v;\n        if(v==0){er=i;ec=j;}\n    }\n    \n    auto startT = chrono::steady_clock::now();\n    double totalTime = 2.7;\n    int goalTree = N*N-1;\n    \n    string bestMoves = \"\";\n    int bestFinalScore = computeTreeScore(board);\n    \n    auto tryTarget = [&](vector<vector<int>>& tgt){\n        string mv = solveFromTarget(tgt);\n        if(mv.empty()){\n            auto [f, s] = processMoves(mv);\n            double ev = evalResult(f, s);\n            double bv = evalResult(bestMoves, bestFinalScore);\n            if(ev > bv){ bestMoves = f; bestFinalScore = s; }\n            return;\n        }\n        string mvReduced = eliminateCycles(mv);\n        auto [f1, s1] = processMoves(mv);\n        auto [f2, s2] = processMoves(mvReduced);\n        double e1 = evalResult(f1, s1);\n        double e2 = evalResult(f2, s2);\n        string fm; int fs;\n        if(e2 >= e1){ fm=f2; fs=s2; } else { fm=f1; fs=s1; }\n        double ev = evalResult(fm, fs);\n        double bv = evalResult(bestMoves, bestFinalScore);\n        if(ev > bv){ bestMoves = fm; bestFinalScore = fs; }\n    };\n    \n    auto runSA = [&](double timeLimit, double weightMis, bool startShuffle) -> vector<vector<int>> {\n        auto t = board;\n        swap(t[er][ec], t[N-1][N-1]);\n        if(startShuffle){\n            for(int k=0;k<N*N*3;k++){\n                int i1,j1,i2,j2;\n                do { i1=rng()%N; j1=rng()%N; } while(i1==N-1&&j1==N-1);\n                do { i2=rng()%N; j2=rng()%N; } while((i2==N-1&&j2==N-1) || (i1==i2&&j1==j2));\n                swap(t[i1][j1], t[i2][j2]);\n            }\n        }\n        \n        int curMis=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) if(t[i][j]!=board[i][j]) curMis++;\n        int curTree = computeTreeScore(t);\n        int curPen = computeBoundaryPenalty(t);\n        auto obj = [&](int tree, int pen, int mis){ return (double)tree*10000 - weightMis*mis - pen; };\n        double curObj = obj(curTree, curPen, curMis);\n        int bestTree = curTree;\n        auto bestT = t;\n        double bestObj = curObj;\n        \n        auto saStart = chrono::steady_clock::now();\n        int it=0;\n        double temp0=2000.0, temp1=1.0;\n        while(true){\n            if((it&1023)==0){\n                double el = chrono::duration<double>(chrono::steady_clock::now()-saStart).count();\n                if(el>timeLimit) break;\n            }\n            it++;\n            int i1,j1,i2,j2;\n            do { i1=rng()%N; j1=rng()%N; } while(i1==N-1&&j1==N-1);\n            do { i2=rng()%N; j2=rng()%N; } while((i2==N-1&&j2==N-1) || (i1==i2&&j1==j2));\n            if(t[i1][j1]==t[i2][j2]) continue;\n            int v1=t[i1][j1], v2=t[i2][j2];\n            int b1=board[i1][j1], b2=board[i2][j2];\n            int oldMisDelta = (v1!=b1?1:0) + (v2!=b2?1:0);\n            int newMisDelta = (v2!=b1?1:0) + (v1!=b2?1:0);\n            int newMis = curMis - oldMisDelta + newMisDelta;\n            swap(t[i1][j1], t[i2][j2]);\n            int newTree = computeTreeScore(t);\n            int newPen = computeBoundaryPenalty(t);\n            double newObj = obj(newTree, newPen, newMis);\n            double el = chrono::duration<double>(chrono::steady_clock::now()-saStart).count();\n            double tt = temp0 * pow(temp1/temp0, el/timeLimit);\n            if(newObj>=curObj || (double)rng()/(double)rng.max() < exp((newObj-curObj)/tt)){\n                curTree=newTree; curPen=newPen; curMis=newMis; curObj=newObj;\n                if(newTree > bestTree || (newTree==bestTree && newObj>bestObj)){\n                    bestTree = newTree; bestObj = newObj; bestT = t;\n                }\n            } else {\n                swap(t[i1][j1], t[i2][j2]);\n            }\n        }\n        return bestT;\n    };\n    \n    set<vector<vector<int>>> seenTgt;\n    \n    // Phase 1: long SA, pure tree score\n    {\n        auto t = runSA(0.9, 0.0, false);\n        if(seenTgt.insert(t).second) tryTarget(t);\n    }\n    \n    // Phase 2: multiple shorter SAs with various weights\n    while(true){\n        double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n        if(el > totalTime - 0.2) break;\n        double w_options[] = {0.0, 0.0, 0.0, 3.0, 10.0};\n        double w = w_options[rng()%5];\n        bool shuf = (rng()%2)==0;\n        auto t = runSA(0.25, w, shuf);\n        if(seenTgt.insert(t).second){\n            tryTarget(t);\n        }\n    }\n    \n    cout << bestMoves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, K;\nint a[11];\nvector<int> sx_arr, sy_arr;\n\nint cnt[105][105];\nint bcnt[12];\nlong long curScoreVal;\nint nvG, nhG;\nvector<double> vcG, hcG;\nvector<int> sortedByX, sortedByY;\n\nvoid fullRecompute() {\n    nvG = vcG.size(); nhG = hcG.size();\n    for (int i = 0; i <= nvG; i++) for (int j = 0; j <= nhG; j++) cnt[i][j] = 0;\n    for (int i = 0; i < N; i++) {\n        int xi = upper_bound(vcG.begin(), vcG.end(), (double)sx_arr[i]) - vcG.begin();\n        int yi = upper_bound(hcG.begin(), hcG.end(), (double)sy_arr[i]) - hcG.begin();\n        cnt[xi][yi]++;\n    }\n    for (int d = 0; d < 12; d++) bcnt[d] = 0;\n    for (int i = 0; i <= nvG; i++)\n        for (int j = 0; j <= nhG; j++) {\n            int c = cnt[i][j];\n            if (c >= 1 && c <= 10) bcnt[c]++;\n        }\n    curScoreVal = 0;\n    for (int d = 1; d <= 10; d++) curScoreVal += min(a[d], bcnt[d]);\n}\n\ninline void updateCell(int col, int row, int delta) {\n    int oldv = cnt[col][row];\n    int newv = oldv + delta;\n    cnt[col][row] = newv;\n    if (oldv >= 1 && oldv <= 10) {\n        int before = min(a[oldv], bcnt[oldv]);\n        bcnt[oldv]--;\n        int after = min(a[oldv], bcnt[oldv]);\n        curScoreVal += after - before;\n    }\n    if (newv >= 1 && newv <= 10) {\n        int before = min(a[newv], bcnt[newv]);\n        bcnt[newv]++;\n        int after = min(a[newv], bcnt[newv]);\n        curScoreVal += after - before;\n    }\n}\n\nvoid moveVCut(int ci, double newVal) {\n    double oldVal = vcG[ci];\n    if (newVal == oldVal) return;\n    double lo = min(oldVal, newVal), hi = max(oldVal, newVal);\n    int l, r;\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sx_arr[sortedByX[m]] > lo) b2 = m; else a2 = m+1; }\n        l = a2;\n    }\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sx_arr[sortedByX[m]] >= hi) b2 = m; else a2 = m+1; }\n        r = a2;\n    }\n    int fromCol, toCol;\n    if (newVal > oldVal) { fromCol = ci + 1; toCol = ci; }\n    else { fromCol = ci; toCol = ci + 1; }\n    vcG[ci] = newVal;\n    for (int k = l; k < r; k++) {\n        int si = sortedByX[k];\n        int j = upper_bound(hcG.begin(), hcG.end(), (double)sy_arr[si]) - hcG.begin();\n        updateCell(fromCol, j, -1);\n        updateCell(toCol, j, +1);\n    }\n}\n\nvoid moveHCut(int ci, double newVal) {\n    double oldVal = hcG[ci];\n    if (newVal == oldVal) return;\n    double lo = min(oldVal, newVal), hi = max(oldVal, newVal);\n    int l, r;\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sy_arr[sortedByY[m]] > lo) b2 = m; else a2 = m+1; }\n        l = a2;\n    }\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sy_arr[sortedByY[m]] >= hi) b2 = m; else a2 = m+1; }\n        r = a2;\n    }\n    int fromRow, toRow;\n    if (newVal > oldVal) { fromRow = ci + 1; toRow = ci; }\n    else { fromRow = ci; toRow = ci + 1; }\n    hcG[ci] = newVal;\n    for (int k = l; k < r; k++) {\n        int si = sortedByY[k];\n        int j = upper_bound(vcG.begin(), vcG.end(), (double)sx_arr[si]) - vcG.begin();\n        updateCell(j, fromRow, -1);\n        updateCell(j, toRow, +1);\n    }\n}\n\nstruct XorShift {\n    uint64_t s;\n    XorShift(uint64_t seed): s(seed ? seed : 1) {}\n    inline uint32_t next() {\n        s ^= s << 13; s ^= s >> 7; s ^= s << 17;\n        return (uint32_t)s;\n    }\n    inline double nextDouble() {\n        return (double)(next() & 0xFFFFFF) / (double)(1 << 24);\n    }\n};\n\nint main() {\n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    sx_arr.resize(N); sy_arr.resize(N);\n    for (int i = 0; i < N; i++) cin >> sx_arr[i] >> sy_arr[i];\n    \n    sortedByX.resize(N); sortedByY.resize(N);\n    iota(sortedByX.begin(), sortedByX.end(), 0);\n    iota(sortedByY.begin(), sortedByY.end(), 0);\n    sort(sortedByX.begin(), sortedByX.end(), [&](int x, int y){ return sx_arr[x] < sx_arr[y]; });\n    sort(sortedByY.begin(), sortedByY.end(), [&](int x, int y){ return sy_arr[x] < sy_arr[y]; });\n    \n    vector<int> xs = sx_arr, ys = sy_arr;\n    sort(xs.begin(), xs.end()); xs.erase(unique(xs.begin(), xs.end()), xs.end());\n    sort(ys.begin(), ys.end()); ys.erase(unique(ys.begin(), ys.end()), ys.end());\n    \n    vector<double> cand_x, cand_y;\n    for (int i = 0; i + 1 < (int)xs.size(); i++) cand_x.push_back((xs[i] + xs[i+1]) / 2.0);\n    for (int i = 0; i + 1 < (int)ys.size(); i++) cand_y.push_back((ys[i] + ys[i+1]) / 2.0);\n    \n    XorShift rng(1234567);\n    \n    auto pickEvenly = [&](vector<double>& cand, int k) {\n        vector<double> res;\n        if ((int)cand.size() <= k) res = cand;\n        else {\n            for (int i = 0; i < k; i++) {\n                int idx = (int)((long long)(i+1) * cand.size() / (k+1));\n                if (idx >= (int)cand.size()) idx = cand.size()-1;\n                res.push_back(cand[idx]);\n            }\n        }\n        sort(res.begin(), res.end());\n        res.erase(unique(res.begin(), res.end()), res.end());\n        return res;\n    };\n    \n    auto startTime = chrono::steady_clock::now();\n    double totalTime = 2.7;\n    \n    long long bestScore = -1;\n    vector<double> bestVC, bestHC;\n    \n    for (int kv = 30; kv <= 70; kv += 5) {\n        int kh = K - kv;\n        vcG = pickEvenly(cand_x, kv);\n        hcG = pickEvenly(cand_y, kh);\n        fullRecompute();\n        if (curScoreVal > bestScore) {\n            bestScore = curScoreVal;\n            bestVC = vcG; bestHC = hcG;\n        }\n    }\n    \n    vcG = bestVC; hcG = bestHC;\n    fullRecompute();\n    \n    double T0 = 3.0, T1 = 0.05;\n    long long iters = 0;\n    double cachedProgress = 0.0;\n    \n    auto tryInsertCut = [&](vector<double>& vec, double v) -> bool {\n        auto it = lower_bound(vec.begin(), vec.end(), v);\n        if (it != vec.end() && *it == v) return false;\n        vec.insert(it, v);\n        return true;\n    };\n    \n    while (true) {\n        iters++;\n        if ((iters & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - startTime).count();\n            if (elapsed > totalTime) break;\n            cachedProgress = elapsed / totalTime;\n        }\n        \n        double T = T0 * pow(T1/T0, cachedProgress);\n        \n        int op = rng.next() % 100;\n        \n        if (op < 48) {\n            if (vcG.empty() || cand_x.empty()) continue;\n            int i = rng.next() % vcG.size();\n            double lo_b = (i == 0) ? -1e18 : vcG[i-1];\n            double hi_b = (i == (int)vcG.size()-1) ? 1e18 : vcG[i+1];\n            auto itL = upper_bound(cand_x.begin(), cand_x.end(), lo_b);\n            auto itR = lower_bound(cand_x.begin(), cand_x.end(), hi_b);\n            if (itL >= itR) continue;\n            int numCand = itR - itL;\n            double newVal = *(itL + rng.next() % numCand);\n            if (newVal == vcG[i]) continue;\n            \n            long long prevScore = curScoreVal;\n            double prevVal = vcG[i];\n            moveVCut(i, newVal);\n            long long delta = curScoreVal - prevScore;\n            if (delta >= 0 || rng.nextDouble() < exp((double)delta / T)) {\n                if (curScoreVal > bestScore) {\n                    bestScore = curScoreVal;\n                    bestVC = vcG; bestHC = hcG;\n                }\n            } else {\n                moveVCut(i, prevVal);\n            }\n        } else if (op < 96) {\n            if (hcG.empty() || cand_y.empty()) continue;\n            int i = rng.next() % hcG.size();\n            double lo_b = (i == 0) ? -1e18 : hcG[i-1];\n            double hi_b = (i == (int)hcG.size()-1) ? 1e18 : hcG[i+1];\n            auto itL = upper_bound(cand_y.begin(), cand_y.end(), lo_b);\n            auto itR = lower_bound(cand_y.begin(), cand_y.end(), hi_b);\n            if (itL >= itR) continue;\n            int numCand = itR - itL;\n            double newVal = *(itL + rng.next() % numCand);\n            if (newVal == hcG[i]) continue;\n            \n            long long prevScore = curScoreVal;\n            double prevVal = hcG[i];\n            moveHCut(i, newVal);\n            long long delta = curScoreVal - prevScore;\n            if (delta >= 0 || rng.nextDouble() < exp((double)delta / T)) {\n                if (curScoreVal > bestScore) {\n                    bestScore = curScoreVal;\n                    bestVC = vcG; bestHC = hcG;\n                }\n            } else {\n                moveHCut(i, prevVal);\n            }\n        } else {\n            vector<double> saveVC = vcG, saveHC = hcG;\n            long long prevScoreFull = curScoreVal;\n            \n            int dir = rng.next() % 2;\n            bool ok = false;\n            if (dir == 0) {\n                if (!vcG.empty() && !cand_y.empty()) {\n                    int ri = rng.next() % vcG.size();\n                    vcG.erase(vcG.begin() + ri);\n                    double nv = cand_y[rng.next() % cand_y.size()];\n                    ok = tryInsertCut(hcG, nv);\n                }\n            } else {\n                if (!hcG.empty() && !cand_x.empty()) {\n                    int ri = rng.next() % hcG.size();\n                    hcG.erase(hcG.begin() + ri);\n                    double nv = cand_x[rng.next() % cand_x.size()];\n                    ok = tryInsertCut(vcG, nv);\n                }\n            }\n            if (!ok) { vcG = saveVC; hcG = saveHC; continue; }\n            \n            fullRecompute();\n            long long delta = curScoreVal - prevScoreFull;\n            if (delta >= 0 || rng.nextDouble() < exp((double)delta / T)) {\n                if (curScoreVal > bestScore) {\n                    bestScore = curScoreVal;\n                    bestVC = vcG; bestHC = hcG;\n                }\n            } else {\n                vcG = saveVC; hcG = saveHC;\n                fullRecompute();\n            }\n        }\n    }\n    \n    vcG = bestVC; hcG = bestHC;\n    \n    cout << vcG.size() + hcG.size() << \"\\n\";\n    for (double c : vcG) {\n        long long p = (long long)floor(c);\n        cout << p << \" \" << -1000000000LL << \" \" << p+1 << \" \" << 1000000000LL << \"\\n\";\n    }\n    for (double c : hcG) {\n        long long p = (long long)floor(c);\n        cout << -1000000000LL << \" \" << p << \" \" << 1000000000LL << \" \" << p+1 << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint cx;\nvector<vector<bool>> has_dot;\nint dx8[8] = {1,1,0,-1,-1,-1,0,1};\nint dy8[8] = {0,1,1,1,0,-1,-1,-1};\nvector<vector<array<bool,8>>> edge_used;\n\nbool inside(int x, int y) { return 0<=x && x<N && 0<=y && y<N; }\nint weight(int x, int y) { return (x-cx)*(x-cx) + (y-cx)*(y-cx) + 1; }\n\nint nearestDot(int x, int y, int d) {\n    int nx = x + dx8[d], ny = y + dy8[d];\n    int steps = 1;\n    while (inside(nx, ny)) {\n        if (has_dot[nx][ny]) return steps;\n        nx += dx8[d]; ny += dy8[d]; steps++;\n    }\n    return -1;\n}\n\nbool checkSeg(int x, int y, int d, int len) {\n    int cxx = x, cyy = y;\n    for (int i = 0; i < len; i++) {\n        if (edge_used[cxx][cyy][d]) return false;\n        cxx += dx8[d]; cyy += dy8[d];\n        if (i < len-1 && has_dot[cxx][cyy]) return false;\n    }\n    return true;\n}\n\nvoid markSeg(int x, int y, int d, int len) {\n    int cxx = x, cyy = y;\n    for (int i = 0; i < len; i++) {\n        edge_used[cxx][cyy][d] = true;\n        int nx = cxx + dx8[d], ny = cyy + dy8[d];\n        edge_used[nx][ny][d^4] = true;\n        cxx = nx; cyy = ny;\n    }\n}\n\nstruct Move {\n    int p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y;\n    int8_t d1, d2;\n    int len1, len2;\n};\n\nbool validateMove(const Move& m) {\n    if (has_dot[m.p1x][m.p1y]) return false;\n    if (!has_dot[m.p2x][m.p2y]) return false;\n    if (!has_dot[m.p3x][m.p3y]) return false;\n    if (!has_dot[m.p4x][m.p4y]) return false;\n    if (!checkSeg(m.p1x, m.p1y, m.d1, m.len1)) return false;\n    if (!checkSeg(m.p1x, m.p1y, m.d2, m.len2)) return false;\n    if (!checkSeg(m.p2x, m.p2y, m.d2, m.len2)) return false;\n    if (!checkSeg(m.p4x, m.p4y, m.d1, m.len1)) return false;\n    return true;\n}\n\nvoid applyMove(const Move& m) {\n    has_dot[m.p1x][m.p1y] = true;\n    markSeg(m.p1x, m.p1y, m.d1, m.len1);\n    markSeg(m.p1x, m.p1y, m.d2, m.len2);\n    markSeg(m.p2x, m.p2y, m.d2, m.len2);\n    markSeg(m.p4x, m.p4y, m.d1, m.len1);\n}\n\nmt19937 g_rng(12345);\nint g_noiseLevel = 0;\n\nlong long computePriority(const Move& m) {\n    long long w = weight(m.p1x, m.p1y);\n    long long size = m.len1 + m.len2;\n    long long key = w * 100000LL - size * 100LL;\n    if (g_noiseLevel > 0) {\n        key += (long long)(g_rng() % (g_noiseLevel * 300 + 100));\n    }\n    return key;\n}\n\nstruct PQItem {\n    long long key;\n    Move m;\n    bool operator<(const PQItem& o) const { return key < o.key; }\n};\n\nvoid addCandsWithDot(int qx, int qy, priority_queue<PQItem>& pq) {\n    auto tryAdd = [&](const Move& m) {\n        if (validateMove(m)) {\n            pq.push({computePriority(m), m});\n        }\n    };\n    \n    for (int d1 = 0; d1 < 8; d1++) {\n        int d2 = (d1+2)%8;\n        int opp1 = (d1+4)%8;\n        int l1max;\n        int nd = nearestDot(qx, qy, opp1);\n        if (nd < 0) {\n            l1max = 0;\n            int tx = qx + dx8[opp1], ty = qy + dy8[opp1];\n            while (inside(tx, ty)) { l1max++; tx += dx8[opp1]; ty += dy8[opp1]; }\n        } else l1max = nd - 1;\n        for (int l1 = 1; l1 <= l1max; l1++) {\n            int p1x = qx + dx8[opp1]*l1, p1y = qy + dy8[opp1]*l1;\n            int l2 = nearestDot(p1x, p1y, d2);\n            if (l2 < 0) continue;\n            int p4x = p1x + dx8[d2]*l2, p4y = p1y + dy8[d2]*l2;\n            int p3x = qx + dx8[d2]*l2, p3y = qy + dy8[d2]*l2;\n            if (!inside(p3x, p3y) || !has_dot[p3x][p3y]) continue;\n            Move m{p1x,p1y,qx,qy,p3x,p3y,p4x,p4y,(int8_t)d1,(int8_t)d2,l1,l2};\n            tryAdd(m);\n        }\n    }\n    for (int d1 = 0; d1 < 8; d1++) {\n        int d2 = (d1+2)%8;\n        int opp2 = (d2+4)%8;\n        int l2max;\n        int nd = nearestDot(qx, qy, opp2);\n        if (nd < 0) {\n            l2max = 0;\n            int tx = qx + dx8[opp2], ty = qy + dy8[opp2];\n            while (inside(tx, ty)) { l2max++; tx += dx8[opp2]; ty += dy8[opp2]; }\n        } else l2max = nd - 1;\n        for (int l2 = 1; l2 <= l2max; l2++) {\n            int p1x = qx + dx8[opp2]*l2, p1y = qy + dy8[opp2]*l2;\n            int l1 = nearestDot(p1x, p1y, d1);\n            if (l1 < 0) continue;\n            int p2x = p1x + dx8[d1]*l1, p2y = p1y + dy8[d1]*l1;\n            int p3x = qx + dx8[d1]*l1, p3y = qy + dy8[d1]*l1;\n            if (!inside(p3x, p3y) || !has_dot[p3x][p3y]) continue;\n            Move m{p1x,p1y,p2x,p2y,p3x,p3y,qx,qy,(int8_t)d1,(int8_t)d2,l1,l2};\n            tryAdd(m);\n        }\n    }\n    for (int d1 = 0; d1 < 8; d1++) {\n        int d2 = (d1+2)%8;\n        int opp1 = (d1+4)%8;\n        int opp2 = (d2+4)%8;\n        int l2 = nearestDot(qx, qy, opp2);\n        if (l2 < 0) continue;\n        int p2x = qx + dx8[opp2]*l2, p2y = qy + dy8[opp2]*l2;\n        int l1 = nearestDot(qx, qy, opp1);\n        if (l1 < 0) continue;\n        int p4x = qx + dx8[opp1]*l1, p4y = qy + dy8[opp1]*l1;\n        int p1x = p2x + dx8[opp1]*l1, p1y = p2y + dy8[opp1]*l1;\n        if (!inside(p1x, p1y) || has_dot[p1x][p1y]) continue;\n        Move m{p1x,p1y,p2x,p2y,qx,qy,p4x,p4y,(int8_t)d1,(int8_t)d2,l1,l2};\n        tryAdd(m);\n    }\n}\n\nint main() {\n    cin >> N >> M;\n    cx = (N-1)/2;\n    \n    auto startTime = chrono::steady_clock::now();\n    auto timeLeft = [&](){ return 4.7 - chrono::duration<double>(chrono::steady_clock::now() - startTime).count(); };\n    \n    vector<pair<int,int>> initial(M);\n    for (auto& p : initial) { cin >> p.first >> p.second; }\n    \n    auto resetState = [&]() {\n        has_dot.assign(N, vector<bool>(N, false));\n        edge_used.assign(N, vector<array<bool,8>>(N));\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) for (int k = 0; k < 8; k++) edge_used[i][j][k] = false;\n        for (auto& p : initial) has_dot[p.first][p.second] = true;\n    };\n    \n    vector<Move> bestMoves;\n    long long bestScore = -1;\n    \n    int iter = 0;\n    \n    while (timeLeft() > 0.3) {\n        resetState();\n        vector<Move> moves;\n        \n        g_noiseLevel = iter == 0 ? 0 : (1 + iter);\n        \n        priority_queue<PQItem> pq;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (has_dot[x][y]) continue;\n                for (int d1 = 0; d1 < 8; d1++) {\n                    int d2 = (d1+2)%8;\n                    int l1 = nearestDot(x, y, d1);\n                    if (l1 < 0) continue;\n                    int l2 = nearestDot(x, y, d2);\n                    if (l2 < 0) continue;\n                    int p2x = x + dx8[d1]*l1, p2y = y + dy8[d1]*l1;\n                    int p4x = x + dx8[d2]*l2, p4y = y + dy8[d2]*l2;\n                    int p3x = p2x + dx8[d2]*l2, p3y = p2y + dy8[d2]*l2;\n                    if (!inside(p3x, p3y) || !has_dot[p3x][p3y]) continue;\n                    Move m{x,y,p2x,p2y,p3x,p3y,p4x,p4y,(int8_t)d1,(int8_t)d2,l1,l2};\n                    if (validateMove(m)) pq.push({computePriority(m), m});\n                }\n            }\n        }\n        \n        while (!pq.empty() && timeLeft() > 0.2) {\n            PQItem top = pq.top(); pq.pop();\n            if (!validateMove(top.m)) continue;\n            applyMove(top.m);\n            moves.push_back(top.m);\n            addCandsWithDot(top.m.p1x, top.m.p1y, pq);\n        }\n        \n        long long sumW = 0;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) {\n            if (has_dot[x][y]) sumW += weight(x,y);\n        }\n        \n        if (sumW > bestScore) {\n            bestScore = sumW;\n            bestMoves = moves;\n        }\n        iter++;\n    }\n    \n    cout << bestMoves.size() << \"\\n\";\n    for (auto& m : bestMoves) {\n        cout << m.p1x << \" \" << m.p1y << \" \" << m.p2x << \" \" << m.p2y << \" \"\n             << m.p3x << \" \" << m.p3y << \" \" << m.p4x << \" \" << m.p4y << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef array<int,100> Board;\n\ninline void tilt(Board& b, int dir) {\n    if (dir == 0) {\n        for (int c = 0; c < 10; c++) {\n            int w = 0;\n            for (int r = 0; r < 10; r++) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w++;\n                }\n            }\n        }\n    } else if (dir == 1) {\n        for (int c = 0; c < 10; c++) {\n            int w = 9;\n            for (int r = 9; r >= 0; r--) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w--;\n                }\n            }\n        }\n    } else if (dir == 2) {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 0;\n            for (int c = 0; c < 10; c++) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w++;\n                }\n            }\n        }\n    } else {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w--;\n                }\n            }\n        }\n    }\n}\n\nvoid placeCandy(Board& b, int p, int flavor) {\n    int cnt = 0;\n    for (int i = 0; i < 100; i++) {\n        if (!b[i]) {\n            cnt++;\n            if (cnt == p) {\n                b[i] = flavor;\n                return;\n            }\n        }\n    }\n}\n\nint computeScore(const Board& b) {\n    int vis[100] = {0};\n    int sum = 0;\n    int stk[100];\n    for (int i = 0; i < 100; i++) {\n        if (!vis[i] && b[i]) {\n            int flavor = b[i];\n            int sz = 0;\n            int top = 0;\n            stk[top++] = i;\n            vis[i] = 1;\n            while (top > 0) {\n                int x = stk[--top];\n                sz++;\n                int r = x/10, c = x%10;\n                if (r>0) { int ni = x-10; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (r<9) { int ni = x+10; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (c>0) { int ni = x-1; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (c<9) { int ni = x+1; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n            }\n            sum += sz*sz;\n        }\n    }\n    return sum;\n}\n\nmt19937 rng(12345);\n\nint policies[24][3] = {\n    {0,1,2}, {0,1,3}, {0,2,1}, {0,2,3}, {0,3,1}, {0,3,2},\n    {1,0,2}, {1,0,3}, {1,2,0}, {1,2,3}, {1,3,0}, {1,3,2},\n    {2,0,1}, {2,0,3}, {2,1,0}, {2,1,3}, {2,3,0}, {2,3,1},\n    {3,0,1}, {3,0,2}, {3,1,0}, {3,1,2}, {3,2,0}, {3,2,1},\n};\n\ninline int simulate_crn(Board b, int firstDir, int startT, const vector<int>& f, const int* policy, const unsigned* rnd) {\n    tilt(b, firstDir);\n    int N = (int)f.size();\n    int epos[100];\n    for (int k = startT; k < N; k++) {\n        int flavor = f[k];\n        int ec = 0;\n        for (int i = 0; i < 100; i++) if (!b[i]) epos[ec++] = i;\n        int pick = epos[rnd[k - startT] % ec];\n        b[pick] = flavor;\n        tilt(b, policy[flavor-1]);\n    }\n    return computeScore(b);\n}\n\nint main() {\n    auto startTime = chrono::steady_clock::now();\n    \n    vector<int> f(100);\n    for (int i = 0; i < 100; i++) cin >> f[i];\n    \n    Board board;\n    board.fill(0);\n    \n    double totalBudget = 1.85;\n    \n    int bestPolicy = 0;\n    {\n        auto bs = chrono::steady_clock::now();\n        double evalBudget = 0.15;\n        long long ps[24] = {0};\n        int pt[24] = {0};\n        int ri = 0;\n        int epos[100];\n        while (true) {\n            if ((ri & 7) == 0) {\n                auto ns = chrono::steady_clock::now();\n                double el = chrono::duration<double>(ns - bs).count();\n                if (el >= evalBudget) break;\n            }\n            int pi = ri % 24;\n            ri++;\n            Board b;\n            b.fill(0);\n            for (int k = 0; k < 100; k++) {\n                int flavor = f[k];\n                int ec = 0;\n                for (int i = 0; i < 100; i++) if (!b[i]) epos[ec++] = i;\n                int pick = epos[rng() % ec];\n                b[pick] = flavor;\n                if (k < 99) tilt(b, policies[pi][flavor-1]);\n            }\n            int sc = computeScore(b);\n            ps[pi] += sc;\n            pt[pi]++;\n        }\n        double bestAvg = -1;\n        for (int i = 0; i < 24; i++) {\n            if (pt[i] == 0) continue;\n            double avg = (double)ps[i] / pt[i];\n            if (avg > bestAvg) { bestAvg = avg; bestPolicy = i; }\n        }\n    }\n    \n    unsigned rnd[100];\n    \n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        placeCandy(board, p, f[t]);\n        \n        if (t == 99) break;\n        \n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        double remaining = totalBudget - elapsed;\n        int stepsLeft = 100 - t;\n        double perStep = remaining / stepsLeft;\n        if (perStep < 0.001) perStep = 0.001;\n        auto stepStart = chrono::steady_clock::now();\n        \n        long long scoreSum[4] = {0,0,0,0};\n        int trials[4] = {0,0,0,0};\n        \n        int iter = 0;\n        int remainingCandies = 99 - t;\n        \n        while (true) {\n            if ((iter & 3) == 0) {\n                auto nowS = chrono::steady_clock::now();\n                double el = chrono::duration<double>(nowS - stepStart).count();\n                if (el >= perStep) break;\n            }\n            iter++;\n            \n            for (int k = 0; k < remainingCandies; k++) rnd[k] = rng();\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int sc = simulate_crn(board, dir, t+1, f, policies[bestPolicy], rnd);\n                scoreSum[dir] += sc;\n                trials[dir]++;\n            }\n        }\n        \n        double bestScoreV = -1;\n        int bestDir = 0;\n        for (int d = 0; d < 4; d++) {\n            if (trials[d] == 0) continue;\n            double avg = (double)scoreSum[d] / trials[d];\n            if (avg > bestScoreV) {\n                bestScoreV = avg;\n                bestDir = d;\n            }\n        }\n        \n        tilt(board, bestDir);\n        cout << \"FBLR\"[bestDir] << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int M; double eps;\n    cin >> M >> eps;\n    \n    auto genPairs = [](int N){\n        vector<pair<int,int>> p;\n        p.push_back({0,0});\n        for(int b=2;b<=N;b++) p.push_back({0,b});\n        for(int a=2;a<=N;a++) for(int b=a; a+b<=N; b++) p.push_back({a,b});\n        return p;\n    };\n    \n    int N;\n    if(eps < 1e-9){\n        for(N=4;N<=100;N++){\n            if((int)genPairs(N).size() >= M) break;\n        }\n    } else if(eps <= 0.03){\n        N = 15;\n        while(N<100 && (int)genPairs(N).size() < 3*M) N+=3;\n        N = min(N, 100);\n    } else if(eps <= 0.08){\n        N = 60;\n    } else {\n        N = 100;\n    }\n    \n    int E = N*(N-1)/2;\n    auto pairs = genPairs(N);\n    \n    auto expSeq = [&](int a, int b){\n        vector<double> seq(N);\n        double d_iso = (N-1)*eps;\n        int n_iso = N - a - b;\n        double da = (a>=2) ? (a-1)*(1-eps) + (N-a)*eps : d_iso;\n        double db = (b>=2) ? (b-1)*(1-eps) + (N-b)*eps : d_iso;\n        int p=0;\n        for(int i=0;i<n_iso;i++) seq[p++]=d_iso;\n        for(int i=0;i<a;i++) seq[p++]=da;\n        for(int i=0;i<b;i++) seq[p++]=db;\n        sort(seq.begin(), seq.end());\n        return seq;\n    };\n    \n    int P = pairs.size();\n    vector<vector<double>> allSeq(P);\n    for(int i=0;i<P;i++) allSeq[i] = expSeq(pairs[i].first, pairs[i].second);\n    \n    auto dist2 = [&](const vector<double>& x, const vector<double>& y){\n        double d=0;\n        for(int i=0;i<N;i++){ double t=x[i]-y[i]; d+=t*t; }\n        return d;\n    };\n    \n    vector<int> chosen;\n    chosen.push_back(0);\n    vector<double> minD(P, 1e18);\n    vector<bool> used(P,false); used[0]=true;\n    for(int i=0;i<P;i++) if(!used[i]) minD[i] = dist2(allSeq[0], allSeq[i]);\n    \n    while((int)chosen.size() < M && (int)chosen.size() < P){\n        int bi=-1; double bv=-1;\n        for(int i=0;i<P;i++){\n            if(used[i]) continue;\n            if(minD[i] > bv){ bv=minD[i]; bi=i; }\n        }\n        if(bi<0) break;\n        chosen.push_back(bi);\n        used[bi]=true;\n        for(int i=0;i<P;i++) if(!used[i]){\n            double d=dist2(allSeq[bi], allSeq[i]);\n            if(d<minD[i]) minD[i]=d;\n        }\n    }\n    while((int)chosen.size()<M){\n        for(int i=0;i<P;i++) if(!used[i]){ used[i]=true; chosen.push_back(i); break;}\n    }\n    \n    cout << N << \"\\n\";\n    vector<vector<double>> targetSeq(M);\n    for(int k=0;k<M;k++){\n        int idx = chosen[k];\n        int a = pairs[idx].first, b = pairs[idx].second;\n        string s(E, '0');\n        int p=0;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){\n            bool edge=false;\n            if(a>=2 && i<a && j<a) edge=true;\n            else if(b>=2 && i>=a && i<a+b && j>=a && j<a+b) edge=true;\n            s[p++] = edge?'1':'0';\n        }\n        cout << s << \"\\n\";\n        targetSeq[k] = allSeq[idx];\n    }\n    cout.flush();\n    \n    for(int q=0;q<100;q++){\n        string h; cin >> h;\n        vector<int> deg(N,0);\n        int p=0;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){\n            if(h[p++]=='1'){ deg[i]++; deg[j]++; }\n        }\n        vector<double> sd(N);\n        for(int i=0;i<N;i++) sd[i]=deg[i];\n        sort(sd.begin(), sd.end());\n        \n        int best=0; double bd=1e18;\n        for(int k=0;k<M;k++){\n            double d=dist2(sd, targetSeq[k]);\n            if(d<bd){bd=d; best=k;}\n        }\n        cout << best << \"\\n\";\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint N, M, D, K;\nvector<vector<pair<int,int>>> adj;\nvector<int> W;\nvector<int> Eu, Ev;\n\nvector<int> sources;\nvector<vector<ll>> baseDist;\n\nvector<int> assign_;\nvector<vector<int>> dayEdges;\nint S;\n\nvector<char> removed;\n\nvector<ll> dijkstra(int src) {\n    vector<ll> dist(N, (ll)2e18);\n    priority_queue<pair<ll,int>, vector<pair<ll,int>>, greater<>> pq;\n    dist[src] = 0;\n    pq.push({0, src});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist[u]) continue;\n        for (auto [v, eid] : adj[u]) {\n            if (removed[eid]) continue;\n            ll nd = d + W[eid];\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                pq.push({nd, v});\n            }\n        }\n    }\n    return dist;\n}\n\ndouble dayCost(int k) {\n    for (int e : dayEdges[k]) removed[e] = 1;\n    double total = 0;\n    for (int si = 0; si < S; si++) {\n        auto dist = dijkstra(sources[si]);\n        for (int v = 0; v < N; v++) {\n            ll dv = (dist[v] >= (ll)1e18) ? 1000000000LL : dist[v];\n            total += (double)(dv - baseDist[si][v]);\n        }\n    }\n    for (int e : dayEdges[k]) removed[e] = 0;\n    return total;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> M >> D >> K;\n    adj.assign(N, {});\n    W.resize(M); Eu.resize(M); Ev.resize(M);\n    for (int i = 0; i < M; i++) {\n        int u,v,w; cin >> u >> v >> w; u--; v--;\n        Eu[i]=u; Ev[i]=v; W[i]=w;\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n    }\n    vector<int> X(N), Y(N);\n    for (int i = 0; i < N; i++) cin >> X[i] >> Y[i];\n    \n    removed.assign(M, 0);\n    \n    mt19937 rng(12345);\n    S = min(N, 40);\n    vector<int> perm(N);\n    iota(perm.begin(), perm.end(), 0);\n    shuffle(perm.begin(), perm.end(), rng);\n    sources.assign(perm.begin(), perm.begin()+S);\n    \n    baseDist.resize(S);\n    for (int i = 0; i < S; i++) baseDist[i] = dijkstra(sources[i]);\n    \n    assign_.assign(M, 0);\n    \n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){\n        double xa = (X[Eu[a]]+X[Ev[a]])*0.5, ya=(Y[Eu[a]]+Y[Ev[a]])*0.5;\n        double xb = (X[Eu[b]]+X[Ev[b]])*0.5, yb=(Y[Eu[b]]+Y[Ev[b]])*0.5;\n        return xa+ya < xb+yb;\n    });\n    \n    vector<int> dayCount(D, 0);\n    for (int i = 0; i < M; i++) {\n        int e = order[i];\n        int d = i % D;\n        while (dayCount[d] >= K) d = (d+1) % D;\n        assign_[e] = d;\n        dayCount[d]++;\n    }\n    \n    dayEdges.assign(D, {});\n    for (int i = 0; i < M; i++) dayEdges[assign_[i]].push_back(i);\n    \n    vector<double> costs(D);\n    for (int k = 0; k < D; k++) costs[k] = dayCost(k);\n    \n    auto start = chrono::steady_clock::now();\n    double TIME_LIMIT = 5.3;\n    auto getTime = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now() - start).count();\n    };\n    \n    int iter = 0, accepted = 0;\n    while (getTime() < TIME_LIMIT) {\n        iter++;\n        int op = rng() % 4;\n        if (op == 0) {\n            int e1 = rng() % M;\n            int d1 = assign_[e1];\n            int d2 = rng() % D;\n            if (d1 == d2) continue;\n            if ((int)dayEdges[d2].size() >= K) continue;\n            \n            auto& v1 = dayEdges[d1];\n            auto it1 = find(v1.begin(), v1.end(), e1);\n            v1.erase(it1);\n            dayEdges[d2].push_back(e1);\n            assign_[e1] = d2;\n            \n            double nc1 = dayCost(d1);\n            double nc2 = dayCost(d2);\n            double delta = (nc1+nc2) - (costs[d1]+costs[d2]);\n            if (delta < 0) {\n                costs[d1]=nc1; costs[d2]=nc2;\n                accepted++;\n            } else {\n                dayEdges[d2].pop_back();\n                v1.push_back(e1);\n                assign_[e1] = d1;\n            }\n        } else {\n            int e1 = rng() % M;\n            int e2 = rng() % M;\n            if (e1 == e2) continue;\n            int d1 = assign_[e1], d2 = assign_[e2];\n            if (d1 == d2) continue;\n            auto& v1 = dayEdges[d1];\n            auto& v2 = dayEdges[d2];\n            *find(v1.begin(), v1.end(), e1) = e2;\n            *find(v2.begin(), v2.end(), e2) = e1;\n            assign_[e1] = d2;\n            assign_[e2] = d1;\n            \n            double nc1 = dayCost(d1);\n            double nc2 = dayCost(d2);\n            double delta = (nc1+nc2) - (costs[d1]+costs[d2]);\n            if (delta < 0) {\n                costs[d1]=nc1; costs[d2]=nc2;\n                accepted++;\n            } else {\n                *find(v1.begin(), v1.end(), e2) = e1;\n                *find(v2.begin(), v2.end(), e1) = e2;\n                assign_[e1] = d1;\n                assign_[e2] = d2;\n            }\n        }\n    }\n    \n    cerr << \"iter=\" << iter << \" acc=\" << accepted << endl;\n    \n    for (int i = 0; i < M; i++) cout << assign_[i]+1 << \" \\n\"[i==M-1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nint F[2][14][14], R[2][14][14];\nint occ[2][14][14][14];\nint bid[2][14][14][14];\nint best_bid[2][14][14][14];\nint occ_init[2][14][14][14];\n\nint dx6[6]={1,-1,0,0,0,0};\nint dy6[6]={0,0,1,-1,0,0};\nint dz6[6]={0,0,0,0,1,-1};\n\nbool inb(int x,int y,int z){return x>=0&&x<D&&y>=0&&y<D&&z>=0&&z<D;}\n\nint fcount[2][14][14];\nint rcount[2][14][14];\nint fcount_init[2][14][14];\nint rcount_init[2][14][14];\n\nbool canRemove(int i,int x,int y,int z){\n    if(!occ[i][x][y][z]) return false;\n    if(F[i][z][x] && fcount[i][x][z]==1) return false;\n    if(R[i][z][y] && rcount[i][y][z]==1) return false;\n    return true;\n}\nvoid removeCell(int i,int x,int y,int z){\n    occ[i][x][y][z]=0;\n    fcount[i][x][z]--;\n    rcount[i][y][z]--;\n}\n\nmt19937 rng(98765);\n\nint rots[24][9];\n\nvoid genRots(){\n    int perms[6][3] = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};\n    int permSign[6] = {1,-1,-1,1,1,-1};\n    int cnt=0;\n    for(int p=0;p<6;p++){\n        for(int s=0;s<8;s++){\n            int sx = (s&1)?-1:1;\n            int sy = (s&2)?-1:1;\n            int sz = (s&4)?-1:1;\n            if(permSign[p]*sx*sy*sz != 1) continue;\n            int M[9]={0,0,0,0,0,0,0,0,0};\n            int signs[3]={sx,sy,sz};\n            for(int row=0;row<3;row++){\n                M[row*3 + perms[p][row]] = signs[row];\n            }\n            for(int k=0;k<9;k++) rots[cnt][k]=M[k];\n            cnt++;\n        }\n    }\n}\n\ninline void applyRot(int ri, int x, int y, int z, int& ox, int& oy, int& oz){\n    int* M = rots[ri];\n    ox = M[0]*x + M[1]*y + M[2]*z;\n    oy = M[3]*x + M[4]*y + M[5]*z;\n    oz = M[6]*x + M[7]*y + M[8]*z;\n}\n\ndouble evalScore(int (*curbid)[14][14][14]){\n    int maxId = 0;\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        maxId = max(maxId, curbid[i][x][y][z]);\n    vector<int> v1(maxId+1,0), v2(maxId+1,0);\n    for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n        if(curbid[0][x][y][z]) v1[curbid[0][x][y][z]]++;\n        if(curbid[1][x][y][z]) v2[curbid[1][x][y][z]]++;\n    }\n    double score = 0;\n    for(int id=1;id<=maxId;id++){\n        if(v1[id]>0 && v2[id]>0) score += 1.0/v1[id];\n        else if(v1[id]>0) score += v1[id];\n        else if(v2[id]>0) score += v2[id];\n    }\n    return score;\n}\n\nint growOne(int x1,int y1,int z1,int x2,int y2,int z2, int ri, int maxV,\n            vector<tuple<int,int,int>>& outBlock){\n    outBlock.clear();\n    set<tuple<int,int,int>> inblk;\n    deque<tuple<int,int,int>> q;\n    outBlock.push_back({0,0,0});\n    inblk.insert({0,0,0});\n    q.push_back({0,0,0});\n    \n    while(!q.empty() && (int)outBlock.size()<maxV){\n        auto [ox,oy,oz] = q.front(); q.pop_front();\n        int order[6]={0,1,2,3,4,5};\n        for(int i=5;i>0;i--){int j=rng()%(i+1);swap(order[i],order[j]);}\n        for(int k=0;k<6;k++){\n            int d=order[k];\n            int nx=ox+dx6[d],ny=oy+dy6[d],nz=oz+dz6[d];\n            if(inblk.count({nx,ny,nz})) continue;\n            int ax=x1+nx, ay=y1+ny, az=z1+nz;\n            int rx,ry,rz;\n            applyRot(ri, nx, ny, nz, rx, ry, rz);\n            int bx=x2+rx, by=y2+ry, bz=z2+rz;\n            if(!inb(ax,ay,az)||!inb(bx,by,bz)) continue;\n            if(!occ[0][ax][ay][az]||bid[0][ax][ay][az]) continue;\n            if(!occ[1][bx][by][bz]||bid[1][bx][by][bz]) continue;\n            inblk.insert({nx,ny,nz});\n            outBlock.push_back({nx,ny,nz});\n            q.push_back({nx,ny,nz});\n            if((int)outBlock.size()>=maxV) break;\n        }\n    }\n    return outBlock.size();\n}\n\nvoid runGreedy(double timeLimit, chrono::steady_clock::time_point start, int maxV, int tryRots){\n    int nextId = 1;\n    \n    while(true){\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed>timeLimit) break;\n        \n        vector<tuple<int,int,int>> a1, a2;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(occ[0][x][y][z]&&!bid[0][x][y][z]) a1.push_back({x,y,z});\n            if(occ[1][x][y][z]&&!bid[1][x][y][z]) a2.push_back({x,y,z});\n        }\n        if(a1.empty()||a2.empty()) break;\n        \n        int bestVol = 0;\n        vector<tuple<int,int,int>> bestCells1, bestCells2;\n        \n        shuffle(a1.begin(),a1.end(),rng);\n        shuffle(a2.begin(),a2.end(),rng);\n        \n        // Adaptive tries based on tryRots (fewer rots = more seeds)\n        int totalBudget = 200; // rough\n        int seedsPerDim = max(3, (int)sqrt((double)totalBudget/max(1,tryRots)));\n        int tries1 = min((int)a1.size(), seedsPerDim);\n        int tries2 = min((int)a2.size(), seedsPerDim);\n        \n        for(int t1=0;t1<tries1;t1++){\n            auto [x1,y1,z1] = a1[t1];\n            for(int t2=0;t2<tries2;t2++){\n                auto [x2,y2,z2] = a2[t2];\n                int rotIds[24];\n                for(int i=0;i<24;i++) rotIds[i]=i;\n                for(int i=23;i>0;i--){int j=rng()%(i+1);swap(rotIds[i],rotIds[j]);}\n                int numRots = min(tryRots, 24);\n                for(int rr=0;rr<numRots;rr++){\n                    int ri = rotIds[rr];\n                    vector<tuple<int,int,int>> block;\n                    int v = growOne(x1,y1,z1,x2,y2,z2,ri,maxV,block);\n                    if(v > bestVol){\n                        bestVol = v;\n                        bestCells1.clear(); bestCells2.clear();\n                        for(auto [ox,oy,oz]:block){\n                            bestCells1.push_back({x1+ox,y1+oy,z1+oz});\n                            int rx,ry,rz;\n                            applyRot(ri, ox, oy, oz, rx, ry, rz);\n                            bestCells2.push_back({x2+rx,y2+ry,z2+rz});\n                        }\n                    }\n                }\n            }\n            double el = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n            if(el>timeLimit) break;\n        }\n        \n        if(bestVol==0) break;\n        int id = nextId++;\n        for(auto [x,y,z]:bestCells1) bid[0][x][y][z]=id;\n        for(auto [x,y,z]:bestCells2) bid[1][x][y][z]=id;\n    }\n    \n    for(int i=0;i<2;i++){\n        vector<tuple<int,int,int>> cells;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(occ[i][x][y][z]&&!bid[i][x][y][z]) cells.push_back({x,y,z});\n        }\n        shuffle(cells.begin(),cells.end(),rng);\n        bool changed=true;\n        while(changed){\n            changed=false;\n            for(auto [x,y,z]:cells){\n                if(occ[i][x][y][z]&&!bid[i][x][y][z]&&canRemove(i,x,y,z)){\n                    removeCell(i,x,y,z);\n                    changed=true;\n                }\n            }\n        }\n    }\n    \n    for(int i=0;i<2;i++){\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(occ[i][x][y][z]&&!bid[i][x][y][z]){\n                bid[i][x][y][z] = nextId++;\n            }\n        }\n    }\n}\n\nvoid resetState(){\n    memcpy(occ, occ_init, sizeof(occ));\n    memcpy(fcount, fcount_init, sizeof(fcount));\n    memcpy(rcount, rcount_init, sizeof(rcount));\n    memset(bid, 0, sizeof(bid));\n}\n\nint main(){\n    genRots();\n    cin>>D;\n    for(int i=0;i<2;i++){\n        for(int z=0;z<D;z++){string s;cin>>s;for(int x=0;x<D;x++)F[i][z][x]=s[x]-'0';}\n        for(int z=0;z<D;z++){string s;cin>>s;for(int y=0;y<D;y++)R[i][z][y]=s[y]-'0';}\n    }\n    for(int i=0;i<2;i++){\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(F[i][z][x]&&R[i][z][y]){\n                occ_init[i][x][y][z]=1;\n                fcount_init[i][x][z]++;\n                rcount_init[i][y][z]++;\n            }\n        }\n    }\n    \n    auto start = chrono::steady_clock::now();\n    double TL_total = 5.5;\n    \n    double bestScore = 1e18;\n    \n    int iter = 0;\n    while(true){\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed > TL_total - 0.2) break;\n        \n        resetState();\n        \n        double remaining = TL_total - elapsed - 0.1;\n        double iter_budget = min(remaining, 0.8);\n        auto iter_start = chrono::steady_clock::now();\n        \n        int maxV, tryRots;\n        int mode = iter % 6;\n        switch(mode){\n            case 0: maxV=25; tryRots=1; break;\n            case 1: maxV=40; tryRots=1; break;\n            case 2: maxV=20; tryRots=4; break;\n            case 3: maxV=30; tryRots=4; break;\n            case 4: maxV=20; tryRots=24; break;\n            case 5: maxV=50; tryRots=2; break;\n        }\n        \n        runGreedy(iter_budget, iter_start, maxV, tryRots);\n        \n        double sc = evalScore(bid);\n        if(sc < bestScore){\n            bestScore = sc;\n            memcpy(best_bid, bid, sizeof(bid));\n        }\n        iter++;\n    }\n    \n    int maxId = 0;\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        maxId = max(maxId, best_bid[i][x][y][z]);\n    \n    vector<int> used(maxId+1, 0);\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        if(best_bid[i][x][y][z]) used[best_bid[i][x][y][z]]=1;\n    vector<int> remap(maxId+1, 0);\n    int cur = 0;\n    for(int id=1;id<=maxId;id++) if(used[id]) remap[id] = ++cur;\n    \n    cout << cur << \"\\n\";\n    for(int i=0;i<2;i++){\n        bool first=true;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(!first) cout<<\" \";\n            cout << remap[best_bid[i][x][y][z]];\n            first=false;\n        }\n        cout<<\"\\n\";\n    }\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K;\nvector<int> X, Y;\nvector<int> EU, EV;\nvector<long long> EW;\nvector<int> A, B;\nvector<vector<pair<int,int>>> adj;\nvector<vector<float>> vr;  // use float for speed\n\nfloat dist2(float x1,float y1,float x2,float y2){\n    return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));\n}\n\nchrono::steady_clock::time_point startT;\ndouble elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-startT).count();}\n\nlong long computeCost(const vector<int>& P, const vector<int>& edgeOn){\n    long long s=0;\n    for(int i=0;i<N;i++) s += (long long)P[i]*P[i];\n    for(int j=0;j<M;j++) if(edgeOn[j]) s += EW[j];\n    return s;\n}\n\npair<vector<int>, vector<char>> buildTree(const vector<char>& isTerm){\n    vector<int> terms;\n    for(int i=0;i<N;i++) if(isTerm[i]) terms.push_back(i);\n    vector<char> inTree(N,0);\n    inTree[0]=1;\n    vector<int> edgeOn(M,0);\n    \n    while(true){\n        vector<long long> d(N, LLONG_MAX);\n        vector<int> pe(N,-1), pv(N,-1);\n        priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;\n        for(int i=0;i<N;i++) if(inTree[i]){ d[i]=0; pq.push({0,i}); }\n        while(!pq.empty()){\n            auto [du,u]=pq.top(); pq.pop();\n            if(du>d[u]) continue;\n            for(auto [v,eid]:adj[u]){\n                long long nd = du + EW[eid];\n                if(nd<d[v]){ d[v]=nd; pe[v]=eid; pv[v]=u; pq.push({nd,v}); }\n            }\n        }\n        int target=-1; long long bestD=LLONG_MAX;\n        for(int t:terms) if(!inTree[t] && d[t]<bestD){bestD=d[t]; target=t;}\n        if(target==-1) break;\n        int cur=target;\n        while(!inTree[cur]){\n            edgeOn[pe[cur]]=1;\n            inTree[cur]=1;\n            cur = pv[cur];\n        }\n    }\n    return {edgeOn, inTree};\n}\n\nvoid pruneTree(vector<int>& edgeOn, vector<char>& inTree, const vector<char>& isTerm){\n    bool changed=true;\n    while(changed){\n        changed=false;\n        vector<int> deg(N,0);\n        for(int j=0;j<M;j++) if(edgeOn[j]){deg[EU[j]]++; deg[EV[j]]++;}\n        for(int i=1;i<N;i++){\n            if(inTree[i] && !isTerm[i] && deg[i]==1){\n                for(int j=0;j<M;j++) if(edgeOn[j] && (EU[j]==i||EV[j]==i)){\n                    edgeOn[j]=0;\n                    break;\n                }\n                inTree[i]=0;\n                changed=true;\n            }\n        }\n    }\n}\n\nvector<int> computePFromTreeSmart(const vector<char>& inTree){\n    vector<int> treeV;\n    for(int i=0;i<N;i++) if(inTree[i]) treeV.push_back(i);\n    if(treeV.empty()) return vector<int>(N,0);\n    int TV = treeV.size();\n    \n    // Compute nearest distance for each resident\n    vector<pair<float,int>> order(K);\n    for(int k=0;k<K;k++){\n        float bd=1e18f;\n        for(int v:treeV) if(vr[v][k]<bd) bd=vr[v][k];\n        order[k]={bd,k};\n    }\n    sort(order.begin(),order.end(),greater<>());\n    \n    vector<float> r(N,0);\n    for(auto [d_,k]:order){\n        int bestV=-1;\n        float bestInc=1e18f;\n        for(int v:treeV){\n            float cv = vr[v][k];\n            float newR = max(r[v], cv);\n            if(newR>5000) continue;\n            float inc = newR*newR - r[v]*r[v];\n            if(inc<bestInc){bestInc=inc; bestV=v;}\n            if(inc==0) break; // optimal, can't do better\n        }\n        if(bestV<0){\n            float bd=1e18f; int bv=-1;\n            for(int v:treeV) if(vr[v][k]<bd){bd=vr[v][k]; bv=v;}\n            bestV=bv;\n        }\n        if(vr[bestV][k] > r[bestV]) r[bestV] = vr[bestV][k];\n    }\n    \n    vector<int> P(N,0);\n    for(int i=0;i<N;i++){\n        P[i]=(int)ceilf(r[i]);\n        if(P[i]>5000) P[i]=5000;\n    }\n    return P;\n}\n\nint main(){\n    startT = chrono::steady_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    cin>>N>>M>>K;\n    X.resize(N); Y.resize(N);\n    for(int i=0;i<N;i++) cin>>X[i]>>Y[i];\n    EU.resize(M); EV.resize(M); EW.resize(M);\n    adj.assign(N,{});\n    for(int j=0;j<M;j++){\n        cin>>EU[j]>>EV[j]>>EW[j];\n        EU[j]--; EV[j]--;\n        adj[EU[j]].push_back({EV[j],j});\n        adj[EV[j]].push_back({EU[j],j});\n    }\n    A.resize(K); B.resize(K);\n    for(int k=0;k<K;k++) cin>>A[k]>>B[k];\n    \n    vr.assign(N, vector<float>(K));\n    for(int i=0;i<N;i++)\n        for(int k=0;k<K;k++)\n            vr[i][k] = dist2((float)X[i],(float)Y[i],(float)A[k],(float)B[k]);\n    \n    mt19937 rng(12345);\n    \n    // Initial: each resident's nearest vertex as terminals\n    vector<char> isTerm(N,0);\n    isTerm[0]=1;\n    for(int k=0;k<K;k++){\n        int best=0; float bd=vr[0][k];\n        for(int i=1;i<N;i++) if(vr[i][k]<bd){bd=vr[i][k]; best=i;}\n        isTerm[best]=1;\n    }\n    \n    auto [edgeOn0, inTree0] = buildTree(isTerm);\n    pruneTree(edgeOn0, inTree0, isTerm);\n    vector<int> P0 = computePFromTreeSmart(inTree0);\n    long long bestCost = computeCost(P0, edgeOn0);\n    vector<int> bestP = P0;\n    vector<int> bestEdge = edgeOn0;\n    vector<char> bestInTree = inTree0;\n    \n    vector<char> curTerm(N,0);\n    for(int i=0;i<N;i++) curTerm[i] = inTree0[i];\n    curTerm[0]=1;\n    long long curCost = bestCost;\n    \n    auto evaluate = [&](const vector<char>& nt) -> tuple<long long, vector<int>, vector<int>, vector<char>>{\n        auto [ne, inT] = buildTree(nt);\n        pruneTree(ne, inT, nt);\n        vector<int> np = computePFromTreeSmart(inT);\n        long long nc = computeCost(np, ne);\n        return {nc, np, ne, inT};\n    };\n    \n    // Hill climb: toggle each vertex\n    int noImproveRounds=0;\n    double phase1End = 0.8;\n    while(elapsed()<phase1End && noImproveRounds<2){\n        bool improved=false;\n        vector<int> order(N);\n        iota(order.begin(),order.end(),0);\n        shuffle(order.begin(),order.end(),rng);\n        for(int v: order){\n            if(v==0) continue;\n            if(elapsed()>phase1End) break;\n            vector<char> nt = curTerm;\n            nt[v] = 1-nt[v];\n            auto [nc, np, ne, inT] = evaluate(nt);\n            if(nc<curCost){\n                curCost=nc;\n                curTerm = nt;\n                for(int i=0;i<N;i++) if(!inT[i]) curTerm[i]=0;\n                curTerm[0]=1;\n                if(nc<bestCost){\n                    bestCost=nc;\n                    bestP=np;\n                    bestEdge=ne;\n                    bestInTree=inT;\n                }\n                improved=true;\n            }\n        }\n        if(!improved) noImproveRounds++;\n        else noImproveRounds=0;\n    }\n    \n    // SA phase\n    double TL = 1.85;\n    double T0=5e5, T1=1e2;\n    while(elapsed()<TL){\n        double t = (elapsed()-phase1End)/(TL-phase1End);\n        if(t<0) t=0; if(t>1) t=1;\n        double T = T0 * pow(T1/T0, t);\n        \n        // Move type: 1) toggle; 2) swap (add one, remove one)\n        int mt = rng()%3;\n        vector<char> nt = curTerm;\n        if(mt==0 || mt==1){\n            int v = rng()%N;\n            if(v==0) continue;\n            nt[v] = 1-nt[v];\n        } else {\n            // swap: remove a random term, add a non-term\n            vector<int> terms, nonterms;\n            for(int i=1;i<N;i++){\n                if(nt[i]) terms.push_back(i);\n                else nonterms.push_back(i);\n            }\n            if(terms.empty() || nonterms.empty()) continue;\n            int a = terms[rng()%terms.size()];\n            int b = nonterms[rng()%nonterms.size()];\n            nt[a]=0; nt[b]=1;\n        }\n        auto [nc, np, ne, inT] = evaluate(nt);\n        double delta = (double)(nc - curCost);\n        if(delta<0 || exp(-delta/T) > (double)(rng()%100000)/100000.0){\n            curCost=nc;\n            curTerm = nt;\n            for(int i=0;i<N;i++) if(!inT[i]) curTerm[i]=0;\n            curTerm[0]=1;\n            if(nc<bestCost){\n                bestCost=nc;\n                bestP=np;\n                bestEdge=ne;\n                bestInTree=inT;\n            }\n        }\n    }\n    \n    // Final coverage check\n    for(int k=0;k<K;k++){\n        bool ok=false;\n        for(int i=0;i<N;i++) if(bestInTree[i] && vr[i][k]<=bestP[i]+1e-6f){ok=true;break;}\n        if(!ok){\n            int bv=-1; float bd=1e18f;\n            for(int i=0;i<N;i++) if(bestInTree[i] && vr[i][k]<bd){bd=vr[i][k]; bv=i;}\n            if(bv>=0) bestP[bv]=min(5000,(int)ceilf(bd));\n        }\n    }\n    \n    for(int i=0;i<N;i++) cout<<bestP[i]<<\" \\n\"[i==N-1];\n    for(int j=0;j<M;j++) cout<<bestEdge[j]<<\" \\n\"[j==M-1];\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nint N=30;\nint init_grid[30][30];\nint grid[30][30];\npair<int,int> pos[465];\nbool filled[30][30];\nint dist_[30][30];\npair<int,int> prev_[30][30];\n\nint dx6[]={-1,-1,0,0,1,1};\nint dy6[]={-1,0,-1,1,0,1};\n\nbool isAvailable(int x, int y){\n    if(x>=29) return false;\n    if(filled[x][y]) return false;\n    if(x==0) return true;\n    if(y-1>=0 && !filled[x-1][y-1]) return false;\n    if(y<=x-1 && !filled[x-1][y]) return false;\n    return true;\n}\n\nvoid dijkstra(int sx,int sy, int baseK, int base, int window){\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)dist_[i][j]=INT_MAX;\n    priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n    dist_[sx][sy]=0; pq.push({0,sx,sy});\n    while(!pq.empty()){\n        auto [d,x,y]=pq.top(); pq.pop();\n        if(d>dist_[x][y]) continue;\n        for(int dr=0;dr<6;dr++){\n            int nx=x+dx6[dr], ny=y+dy6[dr];\n            if(nx<0||nx>=N||ny<0||ny>nx) continue;\n            if(filled[nx][ny]) continue;\n            int v = grid[nx][ny];\n            int penalty = (v - baseK <= window) ? 1 : 0;\n            int nd = d + base + penalty;\n            if(nd < dist_[nx][ny]){\n                dist_[nx][ny]=nd;\n                prev_[nx][ny]={x,y};\n                pq.push({nd,nx,ny});\n            }\n        }\n    }\n}\n\nvector<tuple<int,int,int,int>> run(int base, int window, int randomness, mt19937& rng){\n    for(int i=0;i<30;i++)for(int j=0;j<30;j++){\n        grid[i][j] = init_grid[i][j];\n        filled[i][j] = false;\n    }\n    for(int i=0;i<30;i++)for(int j=0;j<=i;j++) pos[grid[i][j]] = {i,j};\n    \n    vector<tuple<int,int,int,int>> local_ops;\n    \n    for(int k=0;k<435;k++){\n        auto [cx,cy]=pos[k];\n        dijkstra(cx,cy,k,base,window);\n        vector<tuple<int,int,int>> cands;\n        for(int x=0;x<29;x++)for(int y=0;y<=x;y++){\n            if(!isAvailable(x,y)) continue;\n            if(dist_[x][y]==INT_MAX) continue;\n            cands.push_back({dist_[x][y], x, y});\n        }\n        sort(cands.begin(), cands.end());\n        int pick_range = min((int)cands.size(), randomness);\n        int pick = (pick_range > 1) ? (rng() % pick_range) : 0;\n        int btx = get<1>(cands[pick]);\n        int bty = get<2>(cands[pick]);\n        \n        vector<pair<int,int>> path;\n        int x=btx,y=bty;\n        while(!(x==cx&&y==cy)){\n            path.push_back({x,y});\n            auto [px,py]=prev_[x][y];\n            x=px; y=py;\n        }\n        path.push_back({cx,cy});\n        reverse(path.begin(),path.end());\n        for(int i=0;i+1<(int)path.size();i++){\n            int x1=path[i].first, y1=path[i].second;\n            int x2=path[i+1].first, y2=path[i+1].second;\n            local_ops.push_back({x1,y1,x2,y2});\n            int v1=grid[x1][y1], v2=grid[x2][y2];\n            swap(grid[x1][y1],grid[x2][y2]);\n            pos[v1]={x2,y2}; pos[v2]={x1,y1};\n        }\n        filled[btx][bty]=true;\n    }\n    return local_ops;\n}\n\nint main(){\n    auto start_time = chrono::steady_clock::now();\n    for(int x=0;x<N;x++)for(int y=0;y<=x;y++){\n        cin>>init_grid[x][y];\n    }\n    \n    vector<tuple<int,int,int,int>> best;\n    int best_size = INT_MAX;\n    mt19937 rng(42);\n    \n    vector<pair<int,int>> params = {\n        {1000, 0}, {1000, 20}, {1000, 50}, {1000, 100},\n        {2, 20}, {3, 50}, {5, 30}, {10, 50}, {1, 30}, {1, 50}\n    };\n    for(auto [b,w] : params){\n        auto ops = run(b,w,1,rng);\n        if((int)ops.size() < best_size){ best_size = (int)ops.size(); best = ops; }\n    }\n    \n    while(true){\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now-start_time).count();\n        if(elapsed > 1.7) break;\n        int b = (rng()%2==0) ? 1000 : (1 + rng() % 10);\n        int w = rng() % 100;\n        int r = 1 + rng() % 4;\n        auto ops = run(b,w,r,rng);\n        if((int)ops.size() < best_size){ best_size = (int)ops.size(); best = ops; }\n    }\n    \n    cout<<best.size()<<\"\\n\";\n    for(auto[a,b,c,d]:best)cout<<a<<\" \"<<b<<\" \"<<c<<\" \"<<d<<\"\\n\";\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N;\nint obs[9][9];\nint filled[9][9];\nint cellVal[9][9];\nint dr[4] = {-1, 1, 0, 0};\nint dc[4] = {0, 0, -1, 1};\n\nvoid bfs_reach(int reach[9][9]) {\n    for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) reach[i][j] = 0;\n    queue<pair<int,int>> q;\n    reach[0][4] = 1;\n    q.push({0, 4});\n    while (!q.empty()) {\n        int r = q.front().first, c = q.front().second;\n        q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= 9 || nc < 0 || nc >= 9) continue;\n            if (reach[nr][nc] || obs[nr][nc] || filled[nr][nc]) continue;\n            reach[nr][nc] = 1;\n            q.push({nr, nc});\n        }\n    }\n}\n\nint main() {\n    cin >> D >> N;\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        obs[r][c] = 1;\n    }\n    int M = 81 - 1 - N;\n    for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) cellVal[i][j] = -1;\n    \n    vector<pair<int,int>> order;\n    int vis[9][9];\n    for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) vis[i][j] = 0;\n    \n    function<void(int,int)> dfs = [&](int r, int c) {\n        vis[r][c] = 1;\n        if (!(r == 0 && c == 4)) order.push_back({r, c});\n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= 9 || nc < 0 || nc >= 9) continue;\n            if (vis[nr][nc] || obs[nr][nc]) continue;\n            dfs(nr, nc);\n        }\n    };\n    dfs(0, 4);\n    \n    int pidx[9][9];\n    for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) pidx[i][j] = -1;\n    for (int k = 0; k < (int)order.size(); k++) {\n        pidx[order[k].first][order[k].second] = k;\n    }\n    \n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n        int reach[9][9];\n        bfs_reach(reach);\n        \n        int totalReach = 0;\n        for (int r = 0; r < 9; r++) for (int c = 0; c < 9; c++)\n            if (reach[r][c] && !(r==0 && c==4)) totalReach++;\n        \n        int bestK = -1, bestDiff = INT_MAX;\n        int bestSafeK = -1, bestSafeDiff = INT_MAX;\n        int fbR = -1, fbC = -1;\n        \n        for (int r = 0; r < 9; r++) {\n            for (int c = 0; c < 9; c++) {\n                if (obs[r][c] || filled[r][c]) continue;\n                if (r == 0 && c == 4) continue;\n                if (!reach[r][c]) continue;\n                fbR = r; fbC = c;\n                int k = pidx[r][c];\n                if (k < 0) continue;\n                int diff = abs(k - t);\n                if (diff < bestDiff) { bestDiff = diff; bestK = k; }\n                \n                if (totalReach == 1) {\n                    // only one cell, must pick it, it's \"safe\" trivially\n                    if (diff < bestSafeDiff) { bestSafeDiff = diff; bestSafeK = k; }\n                    continue;\n                }\n                \n                filled[r][c] = 1;\n                int reach2[9][9];\n                bfs_reach(reach2);\n                filled[r][c] = 0;\n                int newReach = 0;\n                for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++)\n                    if (reach2[i][j] && !(i==0 && j==4)) newReach++;\n                if (newReach == totalReach - 1) {\n                    if (diff < bestSafeDiff) { bestSafeDiff = diff; bestSafeK = k; }\n                }\n            }\n        }\n        \n        int pr, pc;\n        if (bestSafeK >= 0) {\n            pr = order[bestSafeK].first;\n            pc = order[bestSafeK].second;\n        } else if (bestK >= 0) {\n            pr = order[bestK].first;\n            pc = order[bestK].second;\n        } else {\n            pr = fbR; pc = fbC;\n        }\n        filled[pr][pc] = 1;\n        cellVal[pr][pc] = t;\n        cout << pr << \" \" << pc << \"\\n\";\n        cout.flush();\n    }\n    \n    for (int step = 0; step < M; step++) {\n        int ev[9][9];\n        for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) ev[i][j] = 0;\n        queue<pair<int,int>> q;\n        ev[0][4] = 1;\n        q.push({0, 4});\n        while (!q.empty()) {\n            int r = q.front().first, c = q.front().second;\n            q.pop();\n            for (int d = 0; d < 4; d++) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (nr < 0 || nr >= 9 || nc < 0 || nc >= 9) continue;\n                if (ev[nr][nc] || obs[nr][nc] || filled[nr][nc]) continue;\n                ev[nr][nc] = 1;\n                q.push({nr, nc});\n            }\n        }\n        int bestVal = INT_MAX, br = -1, bc = -1;\n        for (int r = 0; r < 9; r++) {\n            for (int c = 0; c < 9; c++) {\n                if (!filled[r][c]) continue;\n                bool adj = false;\n                for (int d = 0; d < 4; d++) {\n                    int nr = r + dr[d], nc = c + dc[d];\n                    if (nr < 0 || nr >= 9 || nc < 0 || nc >= 9) continue;\n                    if (ev[nr][nc]) { adj = true; break; }\n                }\n                if (!adj) continue;\n                if (cellVal[r][c] < bestVal) {\n                    bestVal = cellVal[r][c];\n                    br = r;\n                    bc = c;\n                }\n            }\n        }\n        filled[br][bc] = 0;\n        cout << br << \" \" << bc << \"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nint grid[55][55];\nint bestGrid[55][55];\nint bestNonZero;\nint curNonZero;\nint DX[4]={-1,1,0,0}, DY[4]={0,0,-1,1};\nvector<vector<int>> origAdj;\nvector<vector<int>> cnt;\nbool visBuf[55][55];\n\nbool localConnected(int r, int c, int F){\n    auto at = [&](int x, int y)->int{\n        if(x<0||x>=n||y<0||y>=n) return -1;\n        return grid[x][y];\n    };\n    bool ring[8];\n    ring[0] = at(r-1,c)==F;\n    ring[1] = at(r-1,c+1)==F;\n    ring[2] = at(r,c+1)==F;\n    ring[3] = at(r+1,c+1)==F;\n    ring[4] = at(r+1,c)==F;\n    ring[5] = at(r+1,c-1)==F;\n    ring[6] = at(r,c-1)==F;\n    ring[7] = at(r-1,c-1)==F;\n    int orthCount = (int)ring[0]+ring[2]+ring[4]+ring[6];\n    if(orthCount==0) return false;\n    if(orthCount==1) return true;\n    int trans=0;\n    for(int i=0;i<8;i++)if(ring[i] != ring[(i+1)%8])trans++;\n    return trans<=2;\n}\n\nbool fullRemovableBFS(int r, int c, int F){\n    int sr=-1,sc=-1;\n    bool hasOther=false;\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&&grid[nr][nc]==F){\n            if(sr<0){sr=nr;sc=nc;}\n            else hasOther=true;\n        }\n    }\n    if(sr<0)return false;\n    if(!hasOther)return true;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)visBuf[i][j]=false;\n    static int qx[3000], qy[3000];\n    int qh=0,qt=0;\n    qx[qt]=sr;qy[qt]=sc;qt++;\n    visBuf[sr][sc]=true;\n    while(qh<qt){\n        int x=qx[qh],y=qy[qh];qh++;\n        for(int d=0;d<4;d++){\n            int nx=x+DX[d],ny=y+DY[d];\n            if(nx<0||nx>=n||ny<0||ny>=n)continue;\n            if(visBuf[nx][ny])continue;\n            if(nx==r&&ny==c)continue;\n            if(grid[nx][ny]!=F)continue;\n            visBuf[nx][ny]=true;\n            qx[qt]=nx;qy[qt]=ny;qt++;\n        }\n    }\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&&grid[nr][nc]==F && !visBuf[nr][nc])return false;\n    }\n    return true;\n}\n\nbool removable(int r, int c, int F){\n    if(localConnected(r,c,F))return true;\n    return fullRemovableBFS(r,c,F);\n}\n\nbool tryChange(int r, int c, int T){\n    int F = grid[r][c];\n    if(F==T)return false;\n    int nbrs[4];\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)nbrs[d]=0;\n        else nbrs[d]=grid[nr][nc];\n    }\n    bool tOk=false;\n    if(T==0){\n        if(r==0||r==n-1||c==0||c==n-1) tOk=true;\n        else for(int d=0;d<4;d++)if(nbrs[d]==0){tOk=true;break;}\n    } else {\n        for(int d=0;d<4;d++)if(nbrs[d]==T){tOk=true;break;}\n    }\n    if(!tOk) return false;\n    \n    for(int d=0;d<4;d++){\n        int N=nbrs[d];\n        if(F != N){ cnt[F][N]--; cnt[N][F]--; }\n        if(T != N){ cnt[T][N]++; cnt[N][T]++; }\n    }\n    \n    bool ok=true;\n    auto chk=[&](int a,int b)->bool{\n        if(a==b)return true;\n        return (origAdj[a][b]!=0)==(cnt[a][b]>0);\n    };\n    for(int d=0;d<4;d++){\n        int N=nbrs[d];\n        if(N!=F && !chk(F,N)){ok=false;break;}\n        if(ok && N!=T && !chk(T,N)){ok=false;break;}\n    }\n    if(ok && !chk(F,T))ok=false;\n    \n    auto revert=[&](){\n        for(int d=0;d<4;d++){\n            int N=nbrs[d];\n            if(T != N){ cnt[T][N]--; cnt[N][T]--; }\n            if(F != N){ cnt[F][N]++; cnt[N][F]++; }\n        }\n    };\n    \n    if(!ok){ revert(); return false; }\n    \n    grid[r][c]=T;\n    if(!removable(r,c,F)){\n        grid[r][c]=F;\n        revert();\n        return false;\n    }\n    if(F!=0 && T==0) curNonZero--;\n    else if(F==0 && T!=0) curNonZero++;\n    return true;\n}\n\nvoid saveBest(){\n    if(curNonZero < bestNonZero){\n        bestNonZero = curNonZero;\n        memcpy(bestGrid, grid, sizeof(grid));\n    }\n}\n\nint main(){\n    cin>>n>>m;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)cin>>grid[i][j];\n    curNonZero = 0;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(grid[i][j]!=0)curNonZero++;\n    \n    cnt.assign(m+1, vector<int>(m+1, 0));\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        int a=grid[i][j];\n        for(int d=0;d<4;d++){\n            int ni=i+DX[d],nj=j+DY[d];\n            if(ni<0||ni>=n||nj<0||nj>=n){\n                cnt[a][0]++; cnt[0][a]++;\n            } else {\n                int b=grid[ni][nj];\n                cnt[a][b]++;\n            }\n        }\n    }\n    origAdj.assign(m+1, vector<int>(m+1,0));\n    for(int a=0;a<=m;a++)for(int b=0;b<=m;b++)if(a!=b && cnt[a][b]>0)origAdj[a][b]=1;\n    \n    bestNonZero = curNonZero;\n    memcpy(bestGrid, grid, sizeof(grid));\n    \n    auto startTime = chrono::steady_clock::now();\n    auto elapsed = [&]()->long long{\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();\n    };\n    mt19937 rng(42);\n    uniform_real_distribution<double> urd(0.0, 1.0);\n    \n    // Initial greedy\n    for(int pass=0; pass<10 && elapsed()<300; pass++){\n        vector<pair<int,int>> cells;\n        for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(grid[i][j]!=0)cells.push_back({i,j});\n        shuffle(cells.begin(), cells.end(), rng);\n        bool any=false;\n        for(auto[r,c]:cells){\n            if(grid[r][c]==0)continue;\n            if(tryChange(r,c,0))any=true;\n        }\n        if(!any)break;\n    }\n    saveBest();\n    \n    long long TL = 1850;\n    double T_start = 1.5, T_end = 0.03;\n    \n    while(elapsed() < TL){\n        double progress = (double)elapsed() / (double)TL;\n        double Temp = T_start * pow(T_end/T_start, progress);\n        \n        for(int k=0;k<3000;k++){\n            int r = rng()%n, c = rng()%n;\n            int F = grid[r][c];\n            int T_color;\n            int moveType = rng()%10;\n            if(moveType < 6){\n                if(F==0) continue;\n                T_color = 0;\n            } else if(moveType < 9){\n                if(F==0) continue;\n                int d = rng()%4;\n                int nr=r+DX[d],nc=c+DY[d];\n                if(nr<0||nr>=n||nc<0||nc>=n)T_color=0;\n                else T_color=grid[nr][nc];\n            } else {\n                if(F!=0) continue;\n                int d = rng()%4;\n                int nr=r+DX[d],nc=c+DY[d];\n                if(nr<0||nr>=n||nc<0||nc>=n)continue;\n                T_color=grid[nr][nc];\n                if(T_color==0)continue;\n            }\n            if(F==T_color)continue;\n            \n            int delta = 0;\n            if(F==0 && T_color!=0) delta=1;\n            else if(F!=0 && T_color==0) delta=-1;\n            \n            if(delta > 0){\n                double p = exp(-(double)delta/Temp);\n                if(urd(rng) > p) continue;\n            }\n            \n            if(tryChange(r,c,T_color)){\n                saveBest();\n            }\n        }\n        \n        // Full greedy exploit pass\n        vector<pair<int,int>> cells;\n        for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(grid[i][j]!=0)cells.push_back({i,j});\n        shuffle(cells.begin(), cells.end(), rng);\n        for(auto[r,c]:cells){\n            if(grid[r][c]==0)continue;\n            tryChange(r,c,0);\n        }\n        saveBest();\n    }\n    \n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            cout<<bestGrid[i][j]<<(j+1<n?' ':'\\n');\n        }\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\nint ask(const vector<int>& L, const vector<int>& R) {\n    queries_used++;\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << \"\\n\";\n    cout.flush();\n    char c; cin >> c;\n    if (c == '<') return -1;\n    if (c == '>') return 1;\n    return 0;\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    int reserve;\n    if (Q < 4 * N) reserve = Q / 3;\n    else if (Q > 16 * N) reserve = Q * 3 / 4;\n    else reserve = Q / 2;\n    \n    function<vector<int>(vector<int>)> msort = [&](vector<int> v) -> vector<int> {\n        if (v.size() <= 1) return v;\n        int mid = v.size()/2;\n        vector<int> L(v.begin(), v.begin()+mid);\n        vector<int> R(v.begin()+mid, v.end());\n        L = msort(L);\n        R = msort(R);\n        vector<int> res;\n        int i=0,j=0;\n        while (i<(int)L.size() && j<(int)R.size()) {\n            if (queries_used >= Q - reserve) {\n                while (i<(int)L.size()) res.push_back(L[i++]);\n                while (j<(int)R.size()) res.push_back(R[j++]);\n                return res;\n            }\n            int c = ask({L[i]}, {R[j]});\n            if (c <= 0) res.push_back(L[i++]);\n            else res.push_back(R[j++]);\n        }\n        while (i<(int)L.size()) res.push_back(L[i++]);\n        while (j<(int)R.size()) res.push_back(R[j++]);\n        return res;\n    };\n    \n    vector<int> sorted_items = msort(items);\n    reverse(sorted_items.begin(), sorted_items.end());\n    \n    vector<double> est_weight(N);\n    for (int k = 0; k < N; k++) {\n        double s = 0;\n        for (int i = k+1; i <= N; i++) s += 1.0/i;\n        est_weight[sorted_items[k]] = s;\n    }\n    \n    auto gweight = [&](const vector<int>& g) {\n        double s = 0;\n        for (int x : g) s += est_weight[x];\n        return s;\n    };\n    \n    vector<vector<int>> groups(D);\n    for (int i = 0; i < N; i++) {\n        int best = 0;\n        double bestv = gweight(groups[0]);\n        for (int d = 1; d < D; d++) {\n            double v = gweight(groups[d]);\n            if (v < bestv) { bestv = v; best = d; }\n        }\n        groups[best].push_back(sorted_items[i]);\n    }\n    \n    set<pair<int,int>> failed_pairs;\n    int total_resets = 0;\n    \n    while (queries_used < Q - 1) {\n        vector<int> order(D);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b){\n            return gweight(groups[a]) > gweight(groups[b]);\n        });\n        \n        int heavy = -1, light = -1;\n        for (int i = 0; i < D && heavy == -1; i++) {\n            for (int j = D-1; j > i && heavy == -1; j--) {\n                int A = order[i], B = order[j];\n                auto p = make_pair(min(A,B), max(A,B));\n                if (failed_pairs.count(p)) continue;\n                heavy = A;\n                light = B;\n            }\n        }\n        if (heavy == -1) {\n            failed_pairs.clear();\n            total_resets++;\n            if (total_resets > 3) break;\n            continue;\n        }\n        \n        if (queries_used >= Q) break;\n        int c = ask(groups[heavy], groups[light]);\n        auto pair_key = make_pair(min(heavy, light), max(heavy, light));\n        \n        if (c == 0) {\n            failed_pairs.insert(pair_key);\n            continue;\n        }\n        if (c < 0) swap(heavy, light);\n        \n        bool improved = false;\n        \n        vector<int> hi = groups[heavy];\n        sort(hi.begin(), hi.end(), [&](int a, int b){ return est_weight[a] < est_weight[b]; });\n        \n        int x = hi[0];\n        if ((int)groups[heavy].size() > 1 && queries_used < Q) {\n            vector<int> nh, nl = groups[light];\n            for (int y : groups[heavy]) if (y != x) nh.push_back(y);\n            nl.push_back(x);\n            int c2 = ask(nh, nl);\n            if (c2 >= 0) {\n                groups[heavy] = nh;\n                groups[light] = nl;\n                improved = true;\n            } else {\n                vector<int> li_sorted = groups[light];\n                sort(li_sorted.begin(), li_sorted.end(), [&](int a, int b){ return est_weight[a] < est_weight[b]; });\n                for (int y : li_sorted) {\n                    if (est_weight[y] >= est_weight[x]) break;\n                    if (queries_used >= Q) break;\n                    vector<int> nnh, nnl;\n                    for (int z : groups[heavy]) nnh.push_back(z == x ? y : z);\n                    for (int z : groups[light]) nnl.push_back(z == y ? x : z);\n                    int c3 = ask(nnh, nnl);\n                    if (c3 >= 0) {\n                        groups[heavy] = nnh;\n                        groups[light] = nnl;\n                        improved = true;\n                        break;\n                    }\n                    break;\n                }\n                \n                if (!improved) {\n                    vector<tuple<double,int,int>> pairs;\n                    for (int a : groups[heavy]) for (int b : groups[light]) {\n                        if (est_weight[a] > est_weight[b]) {\n                            pairs.push_back({est_weight[a] - est_weight[b], a, b});\n                        }\n                    }\n                    sort(pairs.begin(), pairs.end());\n                    for (auto& [diff, a, b] : pairs) {\n                        if (queries_used >= Q) break;\n                        vector<int> nnh, nnl;\n                        for (int z : groups[heavy]) nnh.push_back(z == a ? b : z);\n                        for (int z : groups[light]) nnl.push_back(z == b ? a : z);\n                        int c3 = ask(nnh, nnl);\n                        if (c3 >= 0) {\n                            groups[heavy] = nnh;\n                            groups[light] = nnl;\n                            improved = true;\n                            break;\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n        \n        if (improved) {\n            failed_pairs.clear();\n        } else {\n            failed_pairs.insert(pair_key);\n        }\n    }\n    \n    while (queries_used < Q) ask({0}, {1});\n    \n    vector<int> d(N, 0);\n    for (int g = 0; g < D; g++) for (int x : groups[g]) d[x] = g;\n    for (int i = 0; i < N; i++) {\n        cout << d[i];\n        cout << (i == N-1 ? '\\n' : ' ');\n    }\n    cout.flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\n\nint stackMin(const vector<int>& s) {\n    if (s.empty()) return INT_MAX;\n    int mn = INT_MAX;\n    for (int x : s) mn = min(mn, x);\n    return mn;\n}\n\npair<int,int> findBox(const vector<vector<int>>& stk, int v) {\n    for (int i = 0; i < m; i++)\n        for (int j = 0; j < (int)stk[i].size(); j++)\n            if (stk[i][j] == v) return {i, j};\n    return {-1, -1};\n}\n\nint chooseDestination(const vector<vector<int>>& stk, int si, const vector<int>& moved) {\n    int maxMoved = 0;\n    for (int x : moved) maxMoved = max(maxMoved, x);\n    int best = -1;\n    int bestMin = INT_MAX;\n    int emptyStack = -1;\n    for (int i = 0; i < m; i++) {\n        if (i == si) continue;\n        if (stk[i].empty()) { if (emptyStack == -1) emptyStack = i; continue; }\n        int mn = stackMin(stk[i]);\n        if (mn > maxMoved && mn < bestMin) {\n            bestMin = mn; best = i;\n        }\n    }\n    if (best == -1 && emptyStack != -1) best = emptyStack;\n    if (best == -1) {\n        int bestScore = INT_MAX, bestTop = -1;\n        for (int i = 0; i < m; i++) {\n            if (i == si) continue;\n            int mn = stackMin(stk[i]);\n            int above_mn = 0;\n            for (int j = (int)stk[i].size()-1; j >= 0; j--) {\n                if (stk[i][j] == mn) break;\n                above_mn++;\n            }\n            int cnt = 0;\n            for (int x : moved) if (x > mn) cnt++;\n            int score = cnt + above_mn;\n            int t = stk[i].back();\n            if (score < bestScore || (score == bestScore && t > bestTop)) {\n                bestScore = score; best = i; bestTop = t;\n            }\n        }\n    }\n    return best;\n}\n\nint rolloutCost(vector<vector<int>>& stk, int startV) {\n    int cost = 0;\n    for (int v = startV; v <= n; v++) {\n        auto [si, pos] = findBox(stk, v);\n        int above = (int)stk[si].size() - 1 - pos;\n        if (above > 0) {\n            vector<int> moved(stk[si].begin()+pos+1, stk[si].end());\n            int dest = chooseDestination(stk, si, moved);\n            cost += above + 1;\n            stk[si].resize(pos+1);\n            for (int x : moved) stk[dest].push_back(x);\n        }\n        stk[si].pop_back();\n    }\n    return cost;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    cin >> n >> m;\n    vector<vector<int>> stk(m);\n    for (int i = 0; i < m; i++) {\n        stk[i].resize(n/m);\n        for (int j = 0; j < n/m; j++) cin >> stk[i][j];\n    }\n    \n    vector<pair<int,int>> ops;\n    \n    for (int v = 1; v <= n; v++) {\n        auto [si, pos] = findBox(stk, v);\n        int above = (int)stk[si].size() - 1 - pos;\n        if (above > 0) {\n            vector<int> moved(stk[si].begin()+pos+1, stk[si].end());\n            \n            int bestDest = -1;\n            int bestTotal = INT_MAX;\n            for (int d = 0; d < m; d++) {\n                if (d == si) continue;\n                vector<vector<int>> sim = stk;\n                sim[si].resize(pos+1);\n                for (int x : moved) sim[d].push_back(x);\n                sim[si].pop_back();\n                int futureCost = rolloutCost(sim, v+1);\n                int total = (above + 1) + futureCost;\n                if (total < bestTotal) {\n                    bestTotal = total;\n                    bestDest = d;\n                }\n            }\n            \n            ops.push_back({moved[0], bestDest+1});\n            stk[si].resize(pos+1);\n            for (int x : moved) stk[bestDest].push_back(x);\n        }\n        ops.push_back({v, 0});\n        stk[si].pop_back();\n    }\n    \n    for (auto& [a, b] : ops) cout << a << \" \" << b << \"\\n\";\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> hh, vv;\nvector<vector<int>> d;\nint dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};\nchar DC[4]={'U','D','L','R'};\n\nbool canMove(int x,int y,int dir){\n    int nx=x+dx[dir], ny=y+dy[dir];\n    if(nx<0||nx>=N||ny<0||ny>=N) return false;\n    if(dir==0) return hh[nx][y]=='0';\n    if(dir==1) return hh[x][y]=='0';\n    if(dir==2) return vv[x][ny]=='0';\n    if(dir==3) return vv[x][y]=='0';\n    return false;\n}\n\nvector<vector<vector<vector<int>>>> allPar;\nvector<vector<vector<vector<int>>>> allD;\n\nvoid computeAllDist(){\n    allPar.assign(N,vector<vector<vector<int>>>(N,vector<vector<int>>(N,vector<int>(N,-1))));\n    allD.assign(N,vector<vector<vector<int>>>(N,vector<vector<int>>(N,vector<int>(N,INT_MAX))));\n    for(int sx=0;sx<N;sx++)for(int sy=0;sy<N;sy++){\n        auto& D=allD[sx][sy];\n        auto& P=allPar[sx][sy];\n        D[sx][sy]=0;\n        queue<pair<int,int>> q; q.push({sx,sy});\n        while(!q.empty()){\n            auto [x,y]=q.front(); q.pop();\n            for(int d2=0;d2<4;d2++) if(canMove(x,y,d2)){\n                int nx=x+dx[d2], ny=y+dy[d2];\n                if(D[nx][ny]>D[x][y]+1){ D[nx][ny]=D[x][y]+1; P[nx][ny]=d2; q.push({nx,ny}); }\n            }\n        }\n    }\n}\n\nvector<int> getPath(int sx,int sy,int tx,int ty){\n    vector<int> res;\n    int x=tx,y=ty;\n    while(!(x==sx&&y==sy)){\n        int dir=allPar[sx][sy][x][y];\n        if(dir<0) return {};\n        res.push_back(dir);\n        int rdir = dir^1;\n        x+=dx[rdir]; y+=dy[rdir];\n    }\n    reverse(res.begin(),res.end());\n    return res;\n}\n\n// DFS baseline\nvector<int> dfsResult;\nvector<vector<bool>> dfsVisited;\nvoid dfs(int x,int y){\n    dfsVisited[x][y]=true;\n    for(int dir=0;dir<4;dir++){\n        if(canMove(x,y,dir)){\n            int nx=x+dx[dir],ny=y+dy[dir];\n            if(!dfsVisited[nx][ny]){\n                dfsResult.push_back(dir);\n                dfs(nx,ny);\n                dfsResult.push_back(dir^1);\n            }\n        }\n    }\n}\n\ndouble computeScore(const vector<int>& tr){\n    int L=tr.size();\n    if(L==0) return 1e18;\n    vector<vector<vector<int>>> times(N,vector<vector<int>>(N));\n    int x=0,y=0;\n    times[0][0].push_back(0);\n    for(int t=0;t<L;t++){\n        x+=dx[tr[t]]; y+=dy[tr[t]];\n        times[x][y].push_back(t+1);\n    }\n    if(x!=0||y!=0) return 1e18;\n    double total=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        auto& T=times[i][j];\n        if(T.empty()) return 1e18;\n        vector<int> U;\n        U.reserve(T.size());\n        for(int t:T) if(t<L) U.push_back(t);\n        sort(U.begin(),U.end());\n        U.erase(unique(U.begin(),U.end()),U.end());\n        int k=U.size();\n        if(k==0) return 1e18;\n        long long sumSq=0;\n        for(int m=0;m<k;m++){\n            int g = (m+1<k? U[m+1]-U[m] : U[0]+L-U[m]);\n            sumSq += (long long)g*(g-1)/2;\n        }\n        total += (double)d[i][j] * sumSq;\n    }\n    return total / L;\n}\n\n// Greedy tour builder: repeatedly go to cell with best score\nvector<int> greedyTour(double alpha, int unvisitedBonus, mt19937& rng){\n    vector<vector<int>> last(N, vector<int>(N, 0));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    visited[0][0] = true;\n    int cx=0, cy=0;\n    int t=0;\n    vector<int> result;\n    int unvisitedCount = N*N - 1;\n    int maxLen = 90000;\n    \n    while(t < maxLen){\n        // If all visited, and we can return home, consider stopping\n        if(unvisitedCount == 0){\n            // check if enough iterations done \u2014 break if tour is \"long enough\"\n            // we want tour length ~ some target. Just break when visited all and at origin\n            if(cx==0 && cy==0 && t > 0) break;\n        }\n        \n        // pick best next target cell\n        double bestScore = -1;\n        int btx=-1, bty=-1;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            if(i==cx && j==cy) continue;\n            int dist = allD[cx][cy][i][j];\n            if(dist<=0 || dist==INT_MAX) continue;\n            int elapsed = t - last[i][j];\n            double score;\n            if(!visited[i][j]){\n                // high priority\n                score = (double)d[i][j] * elapsed * elapsed / dist + unvisitedBonus * 1.0 / dist;\n            } else {\n                score = (double)d[i][j] * pow(elapsed, alpha) / dist;\n            }\n            if(score > bestScore){\n                bestScore = score;\n                btx = i; bty = j;\n            }\n        }\n        if(btx<0) break;\n        \n        auto path = getPath(cx, cy, btx, bty);\n        if(path.empty()) break;\n        if(t + (int)path.size() > maxLen) break;\n        \n        for(int dr : path){\n            result.push_back(dr);\n            cx += dx[dr]; cy += dy[dr];\n            t++;\n            if(!visited[cx][cy]){ visited[cx][cy]=true; unvisitedCount--; }\n            last[cx][cy] = t;\n        }\n        \n        if(unvisitedCount == 0 && cx==0 && cy==0) break;\n    }\n    \n    // Return to origin\n    if(cx != 0 || cy != 0){\n        auto path = getPath(cx, cy, 0, 0);\n        for(int dr : path){\n            result.push_back(dr);\n            cx += dx[dr]; cy += dy[dr];\n        }\n    }\n    \n    // Check all visited\n    // If not all visited, fall back (shouldn't happen if we iterate long enough)\n    return result;\n}\n\nint main(){\n    cin>>N;\n    hh.resize(N-1); for(auto&s:hh)cin>>s;\n    vv.resize(N); for(auto&s:vv)cin>>s;\n    d.assign(N,vector<int>(N));\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>d[i][j];\n    \n    computeAllDist();\n    \n    auto startTime = chrono::steady_clock::now();\n    auto elapsed = [&](){\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now-startTime).count();\n    };\n    \n    mt19937 rng(12345);\n    \n    // Build baseline DFS\n    dfsVisited.assign(N,vector<bool>(N,false));\n    dfs(0,0);\n    \n    vector<int> tour = dfsResult;\n    double curScore = computeScore(tour);\n    \n    // Try greedy tours with different parameters\n    for(double alpha : {1.5, 2.0, 2.5}){\n        for(int ub : {1000000, 10000000}){\n            if(elapsed() > 0.5) break;\n            auto gt = greedyTour(alpha, ub, rng);\n            if(gt.empty() || gt.size() > 100000) continue;\n            // verify all visited\n            vector<vector<bool>> v(N,vector<bool>(N,false));\n            v[0][0]=true;\n            int x=0,y=0;\n            for(int dr : gt){ x+=dx[dr]; y+=dy[dr]; v[x][y]=true; }\n            bool ok = (x==0 && y==0);\n            for(int i=0;i<N&&ok;i++)for(int j=0;j<N&&ok;j++) if(!v[i][j]) ok=false;\n            if(!ok) continue;\n            double s = computeScore(gt);\n            if(s < curScore){\n                tour = gt;\n                curScore = s;\n            }\n        }\n    }\n    \n    vector<tuple<int,int,int>> cells;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) cells.push_back({d[i][j],i,j});\n    sort(cells.rbegin(),cells.rend());\n    \n    // Phase 1: systematic segment shortening\n    {\n        bool improved = true;\n        int passes = 0;\n        while(improved && passes < 10 && elapsed() < 0.8){\n            improved = false;\n            passes++;\n            int L = tour.size();\n            vector<pair<int,int>> pos(L+1);\n            pos[0] = {0,0};\n            for(int t=0;t<L;t++){ pos[t+1] = {pos[t].first+dx[tour[t]], pos[t].second+dy[tour[t]]}; }\n            \n            for(int a=0; a<L && elapsed()<0.8; a++){\n                int maxb = min(L, a+300);\n                for(int b=a+2; b<=maxb; b++){\n                    int dist = allD[pos[a].first][pos[a].second][pos[b].first][pos[b].second];\n                    if(dist >= b-a) continue;\n                    auto p = getPath(pos[a].first,pos[a].second,pos[b].first,pos[b].second);\n                    vector<int> newTour;\n                    newTour.reserve(L-(b-a)+p.size());\n                    for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n                    for(int x:p) newTour.push_back(x);\n                    for(int t=b;t<L;t++) newTour.push_back(tour[t]);\n                    double ns = computeScore(newTour);\n                    if(ns < curScore){\n                        tour = newTour;\n                        curScore = ns;\n                        improved = true;\n                        goto restart;\n                    }\n                }\n            }\n            restart:;\n        }\n    }\n    \n    // Phase 2: random local search\n    while(elapsed() < 1.85){\n        int mode = rng()%4;\n        int L = tour.size();\n        \n        if(mode==0){\n            int ci = rng() % min((int)cells.size(), 50);\n            auto [dv,ti,tj] = cells[ci];\n            if(L>95000) continue;\n            int pos_i = rng()%(L+1);\n            int cx=0,cy=0;\n            for(int t=0;t<pos_i;t++){ cx+=dx[tour[t]]; cy+=dy[tour[t]]; }\n            if(cx==ti&&cy==tj) continue;\n            auto p1 = getPath(cx,cy,ti,tj);\n            auto p2 = getPath(ti,tj,cx,cy);\n            if((int)(L+p1.size()+p2.size())>100000) continue;\n            vector<int> newTour;\n            newTour.reserve(L+p1.size()+p2.size());\n            for(int t=0;t<pos_i;t++) newTour.push_back(tour[t]);\n            for(int x:p1) newTour.push_back(x);\n            for(int x:p2) newTour.push_back(x);\n            for(int t=pos_i;t<L;t++) newTour.push_back(tour[t]);\n            double ns = computeScore(newTour);\n            if(ns<curScore){ tour=newTour; curScore=ns; }\n        } else if(mode==1){\n            if(L<10) continue;\n            int a=rng()%L;\n            int maxlen = min(500,L-a-1);\n            if(maxlen<2) continue;\n            int b=a+2+rng()%(maxlen-1);\n            if(b>L) continue;\n            int ax=0,ay=0;\n            for(int t=0;t<a;t++){ax+=dx[tour[t]];ay+=dy[tour[t]];}\n            int bx=ax,by=ay;\n            for(int t=a;t<b;t++){bx+=dx[tour[t]];by+=dy[tour[t]];}\n            int dist = allD[ax][ay][bx][by];\n            if(dist>=b-a) continue;\n            auto p = getPath(ax,ay,bx,by);\n            vector<int> newTour;\n            newTour.reserve(L-(b-a)+p.size());\n            for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n            for(int x:p) newTour.push_back(x);\n            for(int t=b;t<L;t++) newTour.push_back(tour[t]);\n            double ns = computeScore(newTour);\n            if(ns<curScore){ tour=newTour; curScore=ns; }\n        } else if(mode==2){\n            if(L<4) continue;\n            int a=rng()%(L-1);\n            if(tour[a]==(tour[a+1]^1)){\n                vector<int> newTour;\n                newTour.reserve(L-2);\n                for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n                for(int t=a+2;t<L;t++) newTour.push_back(tour[t]);\n                double ns = computeScore(newTour);\n                if(ns<curScore){ tour=newTour; curScore=ns; }\n            }\n        } else {\n            if(L>99998) continue;\n            int pos_i = rng()%(L+1);\n            int cx=0,cy=0;\n            for(int t=0;t<pos_i;t++){ cx+=dx[tour[t]]; cy+=dy[tour[t]]; }\n            vector<int> dirs;\n            for(int dr=0;dr<4;dr++) if(canMove(cx,cy,dr)) dirs.push_back(dr);\n            if(dirs.empty()) continue;\n            int dr = dirs[rng()%dirs.size()];\n            vector<int> newTour;\n            newTour.reserve(L+2);\n            for(int t=0;t<pos_i;t++) newTour.push_back(tour[t]);\n            newTour.push_back(dr);\n            newTour.push_back(dr^1);\n            for(int t=pos_i;t<L;t++) newTour.push_back(tour[t]);\n            double ns = computeScore(newTour);\n            if(ns<curScore){ tour=newTour; curScore=ns; }\n        }\n    }\n    \n    for(int dir:tour) cout<<DC[dir];\n    cout<<endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint si, sj;\nvector<string> grid;\nvector<string> words;\nvector<vector<pair<int,int>>> posOf(26);\n\ninline int distm(int r1,int c1,int r2,int c2){ return abs(r1-r2)+abs(c1-c2)+1; }\n\nvector<vector<int>> overlap;\nvector<vector<pair<int,int>>> lastPos;\n\nvector<vector<array<int,5>>> fromCost;\nvector<vector<array<int,5>>> fromEnd;\n\nint MAX_E;\nvector<int> costToEnd;\nint NC_global, M_global;\n\ninline int& CTE(int cIdx, int j, int ov, int e){\n    return costToEnd[((cIdx*M_global + j)*5 + ov)*MAX_E + e];\n}\n\nint computeOverlap(const string& a, const string& b){\n    for(int k=4;k>=1;k--){\n        if(a.substr(5-k)==b.substr(0,k)) return k;\n    }\n    return 0;\n}\n\nint main(){\n    auto start_time = chrono::steady_clock::now();\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin>>N>>M>>si>>sj;\n    M_global = M;\n    grid.resize(N);\n    for(int i=0;i<N;i++) cin>>grid[i];\n    words.resize(M);\n    for(int i=0;i<M;i++) cin>>words[i];\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) posOf[grid[i][j]-'A'].push_back({i,j});\n    \n    overlap.assign(M, vector<int>(M,0));\n    for(int i=0;i<M;i++)for(int j=0;j<M;j++){\n        if(i==j) continue;\n        overlap[i][j] = computeOverlap(words[i], words[j]);\n    }\n    \n    lastPos.resize(M);\n    for(int i=0;i<M;i++) lastPos[i] = posOf[words[i][4]-'A'];\n    \n    MAX_E = 1;\n    for(int i=0;i<M;i++) MAX_E = max(MAX_E, (int)lastPos[i].size());\n    \n    int NC = N*N;\n    NC_global = NC;\n    fromCost.assign(NC, vector<array<int,5>>(M));\n    fromEnd.assign(NC, vector<array<int,5>>(M));\n    costToEnd.assign((long long)NC * M * 5 * MAX_E, INT_MAX/2);\n    \n    for(int cIdx=0; cIdx<NC; cIdx++){\n        int pr = cIdx/N, pc = cIdx%N;\n        for(int j=0; j<M; j++){\n            const string& w = words[j];\n            for(int ov=0; ov<5; ov++){\n                int len = 5-ov;\n                static int dp[5][30];\n                int sizes[5];\n                for(int i=0;i<len;i++) sizes[i] = posOf[w[ov+i]-'A'].size();\n                {\n                    auto& pv = posOf[w[ov]-'A'];\n                    for(int k=0;k<sizes[0];k++) dp[0][k] = distm(pr,pc,pv[k].first,pv[k].second);\n                }\n                for(int i=1;i<len;i++){\n                    auto& pp = posOf[w[ov+i-1]-'A'];\n                    auto& pc2 = posOf[w[ov+i]-'A'];\n                    for(int k=0;k<sizes[i];k++){\n                        int r=pc2[k].first, c=pc2[k].second;\n                        int best=INT_MAX;\n                        for(int jj=0;jj<sizes[i-1];jj++){\n                            int nc = dp[i-1][jj] + distm(pp[jj].first,pp[jj].second,r,c);\n                            if(nc<best) best=nc;\n                        }\n                        dp[i][k]=best;\n                    }\n                }\n                int best=INT_MAX, bk=-1;\n                int finalSize = sizes[len-1];\n                for(int k=0;k<finalSize;k++){\n                    CTE(cIdx,j,ov,k) = dp[len-1][k];\n                    if(dp[len-1][k]<best){best=dp[len-1][k];bk=k;}\n                }\n                fromCost[cIdx][j][ov] = best;\n                fromEnd[cIdx][j][ov] = bk;\n            }\n        }\n    }\n    \n    auto evaluate = [&](const vector<int>& ord)->int{\n        if(ord.empty()) return 0;\n        int cIdx = si*N+sj;\n        int cost = fromCost[cIdx][ord[0]][0];\n        int endIdx = fromEnd[cIdx][ord[0]][0];\n        for(int i=1;i<(int)ord.size();i++){\n            auto& lp = lastPos[ord[i-1]][endIdx];\n            int cIdx2 = lp.first*N + lp.second;\n            int ov = overlap[ord[i-1]][ord[i]];\n            cost += fromCost[cIdx2][ord[i]][ov];\n            endIdx = fromEnd[cIdx2][ord[i]][ov];\n        }\n        return cost;\n    };\n    \n    vector<int> order;\n    {\n        vector<bool> used(M,false);\n        int cIdx = si*N+sj;\n        int bw=-1, bc=INT_MAX, be=-1;\n        for(int j=0;j<M;j++){\n            if(fromCost[cIdx][j][0]<bc){bc=fromCost[cIdx][j][0]; bw=j; be=fromEnd[cIdx][j][0];}\n        }\n        order.push_back(bw); used[bw]=true;\n        int curEnd = be;\n        int curWord = bw;\n        for(int step=1; step<M; step++){\n            auto& lp = lastPos[curWord][curEnd];\n            int ci = lp.first*N+lp.second;\n            int bw2=-1, bc2=INT_MAX, be2=-1;\n            for(int j=0;j<M;j++) if(!used[j]){\n                int ov = overlap[curWord][j];\n                if(fromCost[ci][j][ov]<bc2){\n                    bc2=fromCost[ci][j][ov]; bw2=j; be2=fromEnd[ci][j][ov];\n                }\n            }\n            order.push_back(bw2); used[bw2]=true;\n            curWord=bw2; curEnd=be2;\n        }\n    }\n    \n    int curCost = evaluate(order);\n    int bestCost = curCost;\n    vector<int> bestOrder = order;\n    \n    mt19937 rng(42);\n    auto time_ms = [&](){ return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-start_time).count(); };\n    \n    int total_time_budget = 1500;\n    int sz = order.size();\n    \n    while(time_ms() < total_time_budget){\n        int op = rng()%4;\n        if(op==0){\n            int a = rng()%sz, b = rng()%sz;\n            if(a==b) continue;\n            if(a>b) swap(a,b);\n            reverse(order.begin()+a, order.begin()+b+1);\n            int nc = evaluate(order);\n            if(nc < curCost){\n                curCost = nc;\n                if(nc<bestCost){bestCost=nc; bestOrder=order;}\n            } else {\n                reverse(order.begin()+a, order.begin()+b+1);\n            }\n        } else if(op==1){\n            int a = rng()%sz, b = rng()%sz;\n            if(a==b) continue;\n            int v = order[a];\n            if(a<b){\n                for(int i=a;i<b;i++) order[i]=order[i+1];\n                order[b]=v;\n            } else {\n                for(int i=a;i>b;i--) order[i]=order[i-1];\n                order[b]=v;\n            }\n            int nc = evaluate(order);\n            if(nc < curCost){\n                curCost = nc;\n                if(nc<bestCost){bestCost=nc; bestOrder=order;}\n            } else {\n                int v2 = order[b];\n                if(a<b){\n                    for(int i=b;i>a;i--) order[i]=order[i-1];\n                    order[a]=v2;\n                } else {\n                    for(int i=b;i<a;i++) order[i]=order[i+1];\n                    order[a]=v2;\n                }\n            }\n        } else if(op==2){\n            int a=rng()%sz, b=rng()%sz;\n            if(a==b) continue;\n            swap(order[a],order[b]);\n            int nc = evaluate(order);\n            if(nc < curCost){\n                curCost = nc;\n                if(nc<bestCost){bestCost=nc; bestOrder=order;}\n            } else {\n                swap(order[a],order[b]);\n            }\n        } else {\n            int L = 2+(rng()%2);\n            if(sz-L<1) continue;\n            int a = rng()%(sz-L+1);\n            int b = rng()%(sz-L+1);\n            if(a==b) continue;\n            vector<int> seg(order.begin()+a, order.begin()+a+L);\n            vector<int> rest;\n            rest.reserve(sz-L);\n            for(int i=0;i<sz;i++) if(i<a||i>=a+L) rest.push_back(order[i]);\n            int insPos = b; if(insPos>(int)rest.size()) insPos=rest.size();\n            vector<int> newOrd;\n            newOrd.reserve(sz);\n            for(int i=0;i<insPos;i++) newOrd.push_back(rest[i]);\n            for(int x:seg) newOrd.push_back(x);\n            for(int i=insPos;i<(int)rest.size();i++) newOrd.push_back(rest[i]);\n            int nc = evaluate(newOrd);\n            if(nc < curCost){\n                order = newOrd;\n                curCost = nc;\n                if(nc<bestCost){bestCost=nc; bestOrder=order;}\n            }\n        }\n    }\n    \n    order = bestOrder;\n    curCost = evaluate(order);\n    \n    // Post-processing: remove redundant words\n    auto buildString = [&](const vector<int>& ord)->string{\n        if(ord.empty()) return \"\";\n        string s = words[ord[0]];\n        for(int i=1;i<(int)ord.size();i++){\n            int ov = overlap[ord[i-1]][ord[i]];\n            s += words[ord[i]].substr(ov);\n        }\n        return s;\n    };\n    \n    bool changed = true;\n    int passes = 0;\n    while(changed && passes < 10 && time_ms() < 1800){\n        changed = false;\n        passes++;\n        for(int i=0;i<(int)order.size();){\n            vector<int> newOrd = order;\n            newOrd.erase(newOrd.begin()+i);\n            string s = buildString(newOrd);\n            if(s.find(words[order[i]]) != string::npos){\n                int newC = evaluate(newOrd);\n                if(newC < curCost){\n                    order = newOrd;\n                    curCost = newC;\n                    changed = true;\n                    continue;\n                }\n            }\n            i++;\n        }\n    }\n    \n    // Final path reconstruction using full DP\n    int osz = order.size();\n    vector<vector<int>> dpF(osz), parF(osz);\n    int startCell = si*N+sj;\n    {\n        int w0 = order[0];\n        int sz0 = lastPos[w0].size();\n        dpF[0].assign(sz0, INT_MAX/2);\n        parF[0].assign(sz0, -1);\n        for(int e=0;e<sz0;e++) dpF[0][e] = CTE(startCell, w0, 0, e);\n    }\n    for(int i=1;i<osz;i++){\n        int wp = order[i-1], wc = order[i];\n        int ov = overlap[wp][wc];\n        int szp = lastPos[wp].size();\n        int szc = lastPos[wc].size();\n        dpF[i].assign(szc, INT_MAX/2);\n        parF[i].assign(szc, -1);\n        for(int ep=0;ep<szp;ep++){\n            if(dpF[i-1][ep]>=INT_MAX/2) continue;\n            auto& lp = lastPos[wp][ep];\n            int ci = lp.first*N + lp.second;\n            for(int ec=0;ec<szc;ec++){\n                int v = dpF[i-1][ep] + CTE(ci, wc, ov, ec);\n                if(v < dpF[i][ec]){ dpF[i][ec] = v; parF[i][ec] = ep; }\n            }\n        }\n    }\n    int bestE = 0, bestV = INT_MAX;\n    for(int e=0;e<(int)dpF[osz-1].size();e++) if(dpF[osz-1][e]<bestV){bestV=dpF[osz-1][e]; bestE=e;}\n    vector<int> endIdxs(osz);\n    endIdxs[osz-1] = bestE;\n    for(int i=osz-1;i>0;i--) endIdxs[i-1] = parF[i][endIdxs[i]];\n    \n    auto reconstructWord = [&](int wj, int ov, int pr, int pc, int targetE)->vector<pair<int,int>>{\n        const string& w = words[wj];\n        int len = 5-ov;\n        vector<pair<int,int>> res;\n        if(len<=0) return res;\n        vector<vector<int>> dp(len), par(len);\n        for(int i=0;i<len;i++){\n            int szl = posOf[w[ov+i]-'A'].size();\n            dp[i].assign(szl,INT_MAX/2);\n            par[i].assign(szl,-1);\n        }\n        auto& p0 = posOf[w[ov]-'A'];\n        for(int k=0;k<(int)p0.size();k++) dp[0][k]=distm(pr,pc,p0[k].first,p0[k].second);\n        for(int i=1;i<len;i++){\n            auto& pp=posOf[w[ov+i-1]-'A'];\n            auto& pc2=posOf[w[ov+i]-'A'];\n            for(int k=0;k<(int)pc2.size();k++){\n                int r=pc2[k].first, c=pc2[k].second;\n                for(int j=0;j<(int)pp.size();j++){\n                    int nc=dp[i-1][j]+distm(pp[j].first,pp[j].second,r,c);\n                    if(nc<dp[i][k]){dp[i][k]=nc;par[i][k]=j;}\n                }\n            }\n        }\n        int bk = targetE;\n        vector<int> idx(len);\n        idx[len-1]=bk;\n        for(int i=len-1;i>0;i--) idx[i-1]=par[i][idx[i]];\n        res.resize(len);\n        for(int i=0;i<len;i++) res[i]=posOf[w[ov+i]-'A'][idx[i]];\n        return res;\n    };\n    \n    vector<pair<int,int>> output;\n    int curR=si, curC=sj;\n    for(int i=0;i<osz;i++){\n        int ov = (i==0)?0:overlap[order[i-1]][order[i]];\n        auto path = reconstructWord(order[i], ov, curR, curC, endIdxs[i]);\n        for(auto& p:path){ output.push_back(p); curR=p.first; curC=p.second; }\n    }\n    \n    for(auto& p:output) cout<<p.first<<\" \"<<p.second<<\"\\n\";\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, NN;\ndouble EPS;\nvector<vector<pair<int,int>>> polys;\nvector<vector<vector<int>>> placement_cells;\nvector<int> nPlace;\n\nstruct Query {\n    vector<int> cells;\n    int result;\n    bool exact;\n};\n\nvector<Query> queries;\ndouble total_cost = 0;\n\nauto START_TIME = chrono::steady_clock::now();\ndouble elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - START_TIME).count();\n}\n\nint do_drill(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int v; cin >> v;\n    total_cost += 1.0;\n    Query q; q.cells = {i*N+j}; q.result = v; q.exact = true;\n    queries.push_back(q);\n    return v;\n}\n\nint do_answer(vector<int>& cells) {\n    cout << \"a \" << cells.size();\n    for (int c : cells) cout << \" \" << c/N << \" \" << c%N;\n    cout << endl;\n    cout.flush();\n    int r; cin >> r;\n    return r;\n}\n\nlong long countTotal() {\n    long long t = 1;\n    for (int k = 0; k < M; k++) {\n        t *= nPlace[k];\n        if (t > (long long)1e10) return (long long)1e10;\n    }\n    return t;\n}\n\nint main() {\n    cin >> N >> M >> EPS;\n    NN = N * N;\n    polys.resize(M);\n    int totalOil = 0;\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        totalOil += d;\n        polys[k].resize(d);\n        for (int i = 0; i < d; i++) cin >> polys[k][i].first >> polys[k][i].second;\n    }\n    \n    placement_cells.resize(M);\n    nPlace.resize(M);\n    for (int k = 0; k < M; k++) {\n        int mi = 0, mj = 0;\n        for (auto& p : polys[k]) { mi = max(mi, p.first); mj = max(mj, p.second); }\n        for (int di = 0; di + mi < N; di++) {\n            for (int dj = 0; dj + mj < N; dj++) {\n                vector<int> cs;\n                for (auto& p : polys[k]) cs.push_back((p.first+di)*N + (p.second+dj));\n                placement_cells[k].push_back(cs);\n            }\n        }\n        nPlace[k] = placement_cells[k].size();\n    }\n    \n    long long totalConfigs = countTotal();\n    int maxQueries = 2*N*N;\n    \n    // ==== SMALL CASE: exact enumeration with drilling ====\n    if (totalConfigs <= 80000) {\n        int nConf = (int)totalConfigs;\n        vector<unsigned char> grids((size_t)nConf * NN, 0);\n        vector<vector<int>> allConfs;\n        allConfs.reserve(nConf);\n        \n        vector<int> cur(M, 0);\n        function<void(int)> gen = [&](int k) {\n            if (k == M) {\n                int idx = allConfs.size();\n                allConfs.push_back(cur);\n                size_t base = (size_t)idx * NN;\n                for (int kk = 0; kk < M; kk++) {\n                    for (int c : placement_cells[kk][cur[kk]]) grids[base + c]++;\n                }\n                return;\n            }\n            for (int i = 0; i < nPlace[k]; i++) { cur[k] = i; gen(k+1); }\n        };\n        gen(0);\n        \n        vector<char> alive(nConf, 1);\n        int aliveCount = nConf;\n        \n        while ((int)queries.size() < maxQueries - 1 && elapsed() < 2.3) {\n            int best = -1;\n            for (int c = 0; c < nConf; c++) if (alive[c]) { best = c; break; }\n            if (best == -1) break;\n            \n            if (aliveCount == 1) {\n                size_t base = (size_t)best * NN;\n                vector<int> ans;\n                for (int i = 0; i < NN; i++) if (grids[base + i] > 0) ans.push_back(i);\n                int r = do_answer(ans);\n                if (r == 1) return 0;\n                alive[best] = 0;\n                aliveCount--;\n                continue;\n            }\n            \n            vector<int> cntOil(NN, 0);\n            for (int c = 0; c < nConf; c++) {\n                if (!alive[c]) continue;\n                size_t base = (size_t)c * NN;\n                for (int i = 0; i < NN; i++) if (grids[base + i] > 0) cntOil[i]++;\n            }\n            \n            int bestCell = -1;\n            int bestDiff = INT_MAX;\n            for (int i = 0; i < NN; i++) {\n                if (cntOil[i] == 0 || cntOil[i] == aliveCount) continue;\n                int diff = abs(2*cntOil[i] - aliveCount);\n                if (diff < bestDiff) { bestDiff = diff; bestCell = i; }\n            }\n            \n            if (bestCell == -1) {\n                size_t base = (size_t)best * NN;\n                vector<int> ans;\n                for (int i = 0; i < NN; i++) if (grids[base + i] > 0) ans.push_back(i);\n                int r = do_answer(ans);\n                if (r == 1) return 0;\n                alive[best] = 0;\n                aliveCount--;\n                continue;\n            }\n            \n            int v = do_drill(bestCell / N, bestCell % N);\n            for (int c = 0; c < nConf; c++) {\n                if (!alive[c]) continue;\n                if ((int)grids[(size_t)c * NN + bestCell] != v) {\n                    alive[c] = 0;\n                    aliveCount--;\n                }\n            }\n        }\n        \n        int best = -1;\n        for (int c = 0; c < nConf; c++) if (alive[c]) { best = c; break; }\n        if (best == -1) best = 0;\n        size_t base = (size_t)best * NN;\n        vector<int> ans;\n        for (int i = 0; i < NN; i++) if (grids[base + i] > 0) ans.push_back(i);\n        do_answer(ans);\n        return 0;\n    }\n    \n    // ==== LARGE CASE: drill cells prioritized by placement heat ====\n    // Compute prior probability each cell has oil\n    vector<double> pOil(NN, 0.0);\n    for (int k = 0; k < M; k++) {\n        vector<int> covered(NN, 0);\n        for (int p = 0; p < nPlace[k]; p++) {\n            for (int c : placement_cells[k][p]) covered[c]++;\n        }\n        for (int i = 0; i < NN; i++) {\n            double pNotK = 1.0 - (double)covered[i] / nPlace[k];\n            // aggregate: prob this cell has NO oil from poly k is pNotK\n            // pOil combined = 1 - prod(pNotK)\n            if (k == 0) pOil[i] = 1.0 - pNotK;\n            else pOil[i] = 1.0 - (1.0 - pOil[i]) * pNotK;\n        }\n    }\n    \n    // Drill in order of descending pOil, until we've found totalOil oils OR run out of safe query budget\n    vector<int> order(NN);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) { return pOil[a] > pOil[b]; });\n    \n    vector<int> gridVal(NN, -1);\n    vector<int> ansCells;\n    int foundOil = 0;\n    int drilled = 0;\n    int budget = maxQueries - 2; // leave room for answer + possibly retry\n    \n    for (int idx = 0; idx < NN && drilled < budget; idx++) {\n        int cell = order[idx];\n        int v = do_drill(cell / N, cell % N);\n        gridVal[cell] = v;\n        drilled++;\n        if (v > 0) {\n            ansCells.push_back(cell);\n            foundOil += v;\n        }\n        if (foundOil >= totalOil) break;\n    }\n    \n    // If we haven't found all oil, we must drill remaining cells\n    if (foundOil < totalOil) {\n        for (int idx = 0; idx < NN && drilled < budget; idx++) {\n            int cell = order[idx];\n            if (gridVal[cell] >= 0) continue;\n            int v = do_drill(cell / N, cell % N);\n            gridVal[cell] = v;\n            drilled++;\n            if (v > 0) {\n                ansCells.push_back(cell);\n                foundOil += v;\n            }\n            if (foundOil >= totalOil) break;\n        }\n    }\n    \n    sort(ansCells.begin(), ansCells.end());\n    ansCells.erase(unique(ansCells.begin(), ansCells.end()), ansCells.end());\n    do_answer(ansCells);\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint W, D, N;\nvector<vector<int>> a;\n\nstruct Rect { int i0,j0,i1,j1; };\n\nvoid alignDividers(vector<int>& h, int W_col, const set<int>& prev_dividers) {\n    int m = h.size();\n    if (m == 0) return;\n    long long sum_h = 0;\n    for (int x : h) sum_h += x;\n    int slack = W_col - sum_h;\n    if (slack < 0) return;\n    \n    vector<int> prev_sorted(prev_dividers.begin(), prev_dividers.end());\n    int y = 0;\n    for (int i = 0; i < m - 1; i++) {\n        int natural = y + h[i];\n        auto it = lower_bound(prev_sorted.begin(), prev_sorted.end(), natural);\n        if (it != prev_sorted.end() && *it < W_col) {\n            int push = *it - natural;\n            if (push >= 0 && push <= slack) {\n                h[i] += push;\n                slack -= push;\n            }\n        }\n        y += h[i];\n    }\n    h[m-1] += slack;\n}\n\nlong long solveWithWidths(vector<int>& widths, vector<vector<Rect>>& final_rects, bool align = true) {\n    int C = widths.size();\n    vector<int> xs(C+1, 0);\n    for (int i = 0; i < C; i++) xs[i+1] = xs[i] + widths[i];\n    \n    vector<vector<set<int>>> dividers(D, vector<set<int>>(C));\n    long long deficit = 0;\n    \n    final_rects.assign(D, vector<Rect>(N));\n    \n    for (int d = 0; d < D; d++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        \n        vector<double> load(C, 0);\n        vector<vector<int>> col(C);\n        for (int k : order) {\n            int best = 0;\n            double bestVal = 1e18;\n            for (int c = 0; c < C; c++) {\n                double v = load[c] + (double)a[d][k] / widths[c];\n                if (v < bestVal) { bestVal = v; best = c; }\n            }\n            col[best].push_back(k);\n            load[best] += (double)a[d][k] / widths[best];\n        }\n        \n        for (int c = 0; c < C; c++) {\n            auto& items = col[c];\n            if (items.empty()) continue;\n            int w = widths[c];\n            int m = items.size();\n            if (m > W) return LLONG_MAX;\n            \n            vector<int> h(m);\n            long long total = 0;\n            for (int i = 0; i < m; i++) {\n                h[i] = max(1, (a[d][items[i]] + w - 1) / w);\n                total += h[i];\n            }\n            if (total > W) {\n                long long totA = 0;\n                for (int k : items) totA += a[d][k];\n                if (totA == 0) totA = 1;\n                vector<int> newH(m, 1);\n                int rem = W - m;\n                vector<double> frac(m);\n                for (int i = 0; i < m; i++) {\n                    frac[i] = (double)a[d][items[i]] / totA * rem;\n                }\n                int s = m;\n                for (int i = 0; i < m; i++) {\n                    int add = (int)frac[i];\n                    newH[i] += add;\n                    s += add;\n                }\n                vector<pair<double,int>> fr(m);\n                for (int i = 0; i < m; i++) fr[i] = {frac[i] - (int)frac[i], i};\n                sort(fr.begin(), fr.end(), greater<>());\n                int idx = 0;\n                while (s < W && idx < m) {\n                    newH[fr[idx].second]++;\n                    s++;\n                    idx++;\n                }\n                while (s < W) { newH[m-1]++; s++; }\n                h = newH;\n            } else {\n                if (align && d > 0) {\n                    alignDividers(h, W, dividers[d-1][c]);\n                } else {\n                    h[m-1] += (W - total);\n                }\n            }\n            int y = 0;\n            for (int i = 0; i < m; i++) {\n                int yEnd = y + h[i];\n                if (i == m-1) yEnd = W;\n                if (yEnd > W) yEnd = W;\n                final_rects[d][items[i]] = {y, xs[c], yEnd, xs[c+1]};\n                if (yEnd < W) dividers[d][c].insert(yEnd);\n                y = yEnd;\n            }\n            for (int idx : items) {\n                auto& r = final_rects[d][idx];\n                long long area = (long long)(r.i1-r.i0)*(r.j1-r.j0);\n                if (area < a[d][idx]) deficit += 100LL * (a[d][idx] - area);\n            }\n        }\n    }\n    \n    long long partCost = 0;\n    for (int d = 1; d < D; d++) {\n        for (int c = 0; c < C; c++) {\n            auto& prev = dividers[d-1][c];\n            auto& cur = dividers[d][c];\n            int w = widths[c];\n            int sd = 0;\n            for (int x : prev) if (!cur.count(x)) sd++;\n            for (int x : cur) if (!prev.count(x)) sd++;\n            partCost += (long long)sd * w;\n        }\n    }\n    \n    return deficit + partCost;\n}\n\nlong long solveFixedSingleCol(vector<vector<Rect>>& final_rects) {\n    vector<int> h(N);\n    for (int r = 0; r < N; r++) {\n        int mx = 1;\n        for (int d = 0; d < D; d++) {\n            int val = a[d][N-1-r];\n            int req = (val + W - 1) / W;\n            mx = max(mx, req);\n        }\n        h[r] = mx;\n    }\n    long long sum = 0;\n    for (int x : h) sum += x;\n    \n    if (sum > W) {\n        double ratio = (double)W / sum;\n        long long s = 0;\n        for (int& x : h) { x = max(1, (int)(x * ratio)); s += x; }\n        while (s > W) {\n            int mi = 0;\n            for (int i = 1; i < N; i++) if (h[i] > h[mi]) mi = i;\n            if (h[mi] > 1) { h[mi]--; s--; } else break;\n        }\n        while (s < W) { h[N-1]++; s++; }\n    } else {\n        h[N-1] += (W - sum);\n    }\n    \n    final_rects.assign(D, vector<Rect>(N));\n    long long deficit = 0;\n    for (int d = 0; d < D; d++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        \n        int y = 0;\n        for (int r = 0; r < N; r++) {\n            int yEnd = y + h[r];\n            if (r == N-1) yEnd = W;\n            int k = order[r];\n            final_rects[d][k] = {y, 0, yEnd, W};\n            long long area = (long long)(yEnd - y) * W;\n            if (area < a[d][k]) deficit += 100LL * (a[d][k] - area);\n            y = yEnd;\n        }\n    }\n    return deficit;\n}\n\nlong long solveFixedCols(vector<int>& widths, vector<vector<Rect>>& final_rects) {\n    int C = widths.size();\n    if (C > N) return LLONG_MAX;\n    vector<int> xs(C+1, 0);\n    for (int i = 0; i < C; i++) xs[i+1] = xs[i] + widths[i];\n    \n    vector<int> colOrder(C);\n    iota(colOrder.begin(), colOrder.end(), 0);\n    sort(colOrder.begin(), colOrder.end(), [&](int x, int y){ return widths[x] > widths[y]; });\n    \n    vector<vector<int>> colRanks(C);\n    for (int r = 0; r < N; r++) {\n        colRanks[colOrder[r % C]].push_back(r);\n    }\n    \n    vector<vector<int>> slotH(C);\n    for (int c = 0; c < C; c++) {\n        int w = widths[c];\n        int ns = colRanks[c].size();\n        slotH[c].assign(ns, 1);\n        for (int s = 0; s < ns; s++) {\n            int rank = colRanks[c][s];\n            int mx = 1;\n            for (int d = 0; d < D; d++) {\n                int val = a[d][N-1-rank];\n                int req = (val + w - 1) / w;\n                mx = max(mx, req);\n            }\n            slotH[c][s] = mx;\n        }\n    }\n    \n    for (int c = 0; c < C; c++) {\n        int ns = slotH[c].size();\n        if (ns == 0) continue;\n        long long sum = 0;\n        for (int x : slotH[c]) sum += x;\n        if (sum > W) {\n            double ratio = (double)W / sum;\n            long long s = 0;\n            for (int& x : slotH[c]) { x = max(1, (int)(x * ratio)); s += x; }\n            while (s > W) {\n                int mi = 0;\n                for (int i = 1; i < ns; i++) if (slotH[c][i] > slotH[c][mi]) mi = i;\n                if (slotH[c][mi] > 1) { slotH[c][mi]--; s--; } else break;\n            }\n            while (s < W) { slotH[c][ns-1]++; s++; }\n        } else {\n            slotH[c][ns-1] += (W - sum);\n        }\n    }\n    \n    final_rects.assign(D, vector<Rect>(N));\n    long long deficit = 0;\n    for (int d = 0; d < D; d++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        \n        for (int c = 0; c < C; c++) {\n            int y = 0;\n            int ns = colRanks[c].size();\n            for (int s = 0; s < ns; s++) {\n                int yEnd = y + slotH[c][s];\n                if (s == ns-1) yEnd = W;\n                int rank = colRanks[c][s];\n                int k = order[rank];\n                final_rects[d][k] = {y, xs[c], yEnd, xs[c+1]};\n                long long area = (long long)(yEnd - y) * widths[c];\n                if (area < a[d][k]) deficit += 100LL * (a[d][k] - area);\n                y = yEnd;\n            }\n        }\n    }\n    return deficit;\n}\n\nint main() {\n    cin >> W >> D >> N;\n    a.assign(D, vector<int>(N));\n    for (int d = 0; d < D; d++) for (int k = 0; k < N; k++) cin >> a[d][k];\n    \n    long long bestCost = LLONG_MAX;\n    vector<vector<Rect>> bestRects;\n    \n    auto tryResult = [&](long long cost, vector<vector<Rect>>& rects) {\n        if (cost < bestCost) {\n            bestCost = cost;\n            bestRects = rects;\n        }\n    };\n    \n    int maxC = min(N, 25);\n    \n    for (int C = 1; C <= maxC; C++) {\n        vector<int> widths(C);\n        int base = W / C, extra = W % C;\n        for (int i = 0; i < C; i++) widths[i] = base + (i < extra ? 1 : 0);\n        vector<vector<Rect>> rects;\n        long long cost = solveWithWidths(widths, rects, true);\n        tryResult(cost, rects);\n        long long cost2 = solveWithWidths(widths, rects, false);\n        tryResult(cost2, rects);\n    }\n    \n    {\n        vector<vector<Rect>> rects;\n        long long cost = solveFixedSingleCol(rects);\n        tryResult(cost, rects);\n    }\n    \n    for (int C = 2; C <= maxC; C++) {\n        vector<int> widths(C);\n        int base = W / C, extra = W % C;\n        for (int i = 0; i < C; i++) widths[i] = base + (i < extra ? 1 : 0);\n        vector<vector<Rect>> rects;\n        long long cost = solveFixedCols(widths, rects);\n        tryResult(cost, rects);\n    }\n    \n    mt19937 rng(42);\n    auto clock_start = chrono::steady_clock::now();\n    auto get_time = [&](){\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - clock_start).count();\n    };\n    \n    int trials = 0;\n    while (get_time() < 2500) {\n        trials++;\n        int C = 2 + rng() % (maxC - 1);\n        if (C > N) continue;\n        set<int> bs;\n        int guard = 0;\n        while ((int)bs.size() < C-1 && guard < 1000) {\n            int x = 10 + rng() % (W - 20);\n            bs.insert(x);\n            guard++;\n        }\n        if ((int)bs.size() < C-1) continue;\n        vector<int> breaks(bs.begin(), bs.end());\n        vector<int> widths(C);\n        int prev = 0;\n        for (int i = 0; i < C-1; i++) {\n            widths[i] = breaks[i] - prev;\n            prev = breaks[i];\n        }\n        widths[C-1] = W - prev;\n        bool ok = true;\n        for (int w : widths) if (w < 5) { ok = false; break; }\n        if (!ok) continue;\n        \n        vector<vector<Rect>> rects;\n        long long cost = solveFixedCols(widths, rects);\n        tryResult(cost, rects);\n        \n        if (trials % 2 == 0) {\n            long long cost2 = solveWithWidths(widths, rects, true);\n            tryResult(cost2, rects);\n        }\n    }\n    \n    if (bestRects.empty()) {\n        bestRects.assign(D, vector<Rect>(N));\n        for (int d = 0; d < D; d++) for (int k = 0; k < N; k++)\n            bestRects[d][k] = {k, 0, k+1, W};\n    }\n    \n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            auto& r = bestRects[d][k];\n            if (r.i0 >= r.i1 || r.j0 >= r.j1) r = {0, 0, 1, 1};\n            cout << r.i0 << \" \" << r.j0 << \" \" << r.i1 << \" \" << r.j1 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nconst long long MOD = 998244353;\n\nint N, M, K;\nlong long a0[9][9];\nlong long s[20][3][3];\n\nconst int MAX_K = 6;\n\nstruct Combo {\n    int8_t stamps[MAX_K];\n    int8_t k;\n    long long mat[9];\n};\n\nvector<Combo> combos_by_k[MAX_K+1];\n\nvoid gen_combos(){\n    Combo zero;\n    for(int i=0;i<MAX_K;i++) zero.stamps[i] = 0;\n    zero.k = 0;\n    for(int i=0;i<9;i++) zero.mat[i] = 0;\n    combos_by_k[0].push_back(zero);\n    for(int k=1; k<=MAX_K; k++){\n        for(auto& c : combos_by_k[k-1]){\n            int start = (k==1) ? 0 : c.stamps[k-2];\n            for(int m=start; m<M; m++){\n                Combo nc = c;\n                nc.stamps[k-1] = m;\n                nc.k = k;\n                for(int i=0;i<3;i++) for(int j=0;j<3;j++){\n                    nc.mat[i*3+j] += s[m][i][j];\n                }\n                combos_by_k[k].push_back(nc);\n            }\n        }\n    }\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    cin >> N >> M >> K;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>a0[i][j];\n    for(int m=0;m<M;m++) for(int i=0;i<3;i++) for(int j=0;j<3;j++) cin>>s[m][i][j];\n    \n    gen_combos();\n    \n    auto solve = [&](long long lambda) -> pair<long long, vector<tuple<int,int,int>>> {\n        long long a[9][9];\n        memcpy(a, a0, sizeof(a0));\n        vector<tuple<int,int,int>> ops;\n        int budget = K;\n        \n        for(int p=0;p<=N-3;p++){\n            for(int q=0;q<=N-3;q++){\n                int locked_indices[9];\n                int locked_di[9], locked_dj[9];\n                int nlocked = 0;\n                for(int di=0;di<3;di++) for(int dj=0;dj<3;dj++){\n                    int i = p+di, j = q+dj;\n                    if(min(6,i)==p && min(6,j)==q){\n                        locked_indices[nlocked] = di*3+dj;\n                        locked_di[nlocked] = di;\n                        locked_dj[nlocked] = dj;\n                        nlocked++;\n                    }\n                }\n                \n                int max_k;\n                if(nlocked == 1) max_k = 3;\n                else if(nlocked == 3) max_k = 4;\n                else max_k = MAX_K;\n                if(max_k > budget) max_k = budget;\n                if(max_k < 0) max_k = 0;\n                \n                long long curv[9];\n                for(int ii=0; ii<nlocked; ii++){\n                    curv[ii] = a[p+locked_di[ii]][q+locked_dj[ii]];\n                }\n                \n                int best_k = 0;\n                long long best_sc = LLONG_MIN;\n                const Combo* best_combo = &combos_by_k[0][0];\n                \n                for(int k=0; k<=max_k; k++){\n                    long long kl = (long long)k * lambda;\n                    for(auto& c : combos_by_k[k]){\n                        long long sum = 0;\n                        for(int ii=0; ii<nlocked; ii++){\n                            sum += (curv[ii] + c.mat[locked_indices[ii]]) % MOD;\n                        }\n                        long long sc = sum - kl;\n                        if(sc > best_sc){\n                            best_sc = sc;\n                            best_k = k;\n                            best_combo = &c;\n                        }\n                    }\n                }\n                \n                for(int ii=0; ii<best_k; ii++){\n                    int m = best_combo->stamps[ii];\n                    ops.push_back({m,p,q});\n                    for(int i=0;i<3;i++) for(int j=0;j<3;j++){\n                        a[p+i][q+j] = (a[p+i][q+j] + s[m][i][j]) % MOD;\n                    }\n                    budget--;\n                }\n            }\n        }\n        \n        long long score = 0;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++) score += a[i][j];\n        return {score, ops};\n    };\n    \n    long long best_score = -1;\n    vector<tuple<int,int,int>> best_ops;\n    \n    int num_lambdas = 60;\n    for(int step=0; step<=num_lambdas; step++){\n        long long lambda = (long long)((double)MOD * 0.4 * step / num_lambdas);\n        auto [sc, ops] = solve(lambda);\n        if((int)ops.size() <= K && sc > best_score){\n            best_score = sc;\n            best_ops = ops;\n        }\n    }\n    \n    cout << best_ops.size() << \"\\n\";\n    for(auto& [m,p,q] : best_ops) cout << m << \" \" << p << \" \" << q << \"\\n\";\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint A[5][5];\nint grid_[5][5];\nint cr_[5], cc_[5];\nbool hold_[5];\nint held_[5];\nint nin_[5];\nint nout_[5];\nvector<string> out_;\nint totalDisp = 0;\nint turns_ = 0;\n\nvoid doStep(const string& a) {\n    for(int i=0;i<5;i++){\n        if(nin_[i]>=5)continue;\n        if(grid_[i][0]!=-1)continue;\n        bool h=false;\n        for(int k=0;k<5;k++) if(cr_[k]==i&&cc_[k]==0&&hold_[k]){h=true;break;}\n        if(h)continue;\n        grid_[i][0]=A[i][nin_[i]++];\n    }\n    int nr[5], nc[5];\n    for(int i=0;i<5;i++){nr[i]=cr_[i];nc[i]=cc_[i];}\n    for(int i=0;i<5;i++){\n        if(cr_[i]==-1)continue;\n        char ch=a[i];\n        if(ch=='U')nr[i]--;\n        else if(ch=='D')nr[i]++;\n        else if(ch=='L')nc[i]--;\n        else if(ch=='R')nc[i]++;\n    }\n    for(int i=0;i<5;i++){cr_[i]=nr[i];cc_[i]=nc[i];}\n    for(int i=0;i<5;i++){\n        if(cr_[i]==-1)continue;\n        char ch=a[i];\n        if(ch=='P'){\n            held_[i]=grid_[cr_[i]][cc_[i]];\n            grid_[cr_[i]][cc_[i]]=-1;\n            hold_[i]=true;\n        } else if(ch=='Q'){\n            grid_[cr_[i]][cc_[i]]=held_[i];\n            held_[i]=-1;\n            hold_[i]=false;\n        } else if(ch=='B'){\n            cr_[i]=-1;cc_[i]=-1;\n        }\n    }\n    for(int i=0;i<5;i++) out_[i]+=a[i];\n    turns_++;\n    for(int i=0;i<5;i++){\n        if(grid_[i][4]!=-1){\n            int v=grid_[i][4];\n            grid_[i][4]=-1;\n            totalDisp++;\n            if(v/5==i) nout_[i]++;\n        }\n    }\n}\n\nvoid moveLarge(int tr, int tc) {\n    int guard=0;\n    while((cr_[0]!=tr || cc_[0]!=tc) && turns_<9950 && guard<200) {\n        string a=\".....\"; \n        char ch='.';\n        if(cr_[0]<tr) ch='D';\n        else if(cr_[0]>tr) ch='U';\n        else if(cc_[0]<tc) ch='R';\n        else if(cc_[0]>tc) ch='L';\n        a[0]=ch;\n        doStep(a);\n        guard++;\n    }\n}\n\nvoid P0(){ string a=\".....\"; a[0]='P'; doStep(a); }\nvoid Q0(){ string a=\".....\"; a[0]='Q'; doStep(a); }\n\nint main(){\n    int N; cin>>N;\n    for(int i=0;i<5;i++) for(int j=0;j<5;j++) cin>>A[i][j];\n    for(int i=0;i<5;i++)for(int j=0;j<5;j++)grid_[i][j]=-1;\n    for(int i=0;i<5;i++){cr_[i]=i;cc_[i]=0;hold_[i]=false;held_[i]=-1;nin_[i]=0;nout_[i]=0;}\n    out_.assign(5,\"\");\n    \n    doStep(\"PPPPP\");\n    doStep(\"RRRRR\");\n    doStep(\"RRRRR\");\n    doStep(\"QQQQQ\");\n    doStep(\"LLLLL\");\n    doStep(\"LLLLL\");\n    doStep(\"PPPPP\");\n    doStep(\"RRRRR\");\n    doStep(\"QQQQQ\");\n    doStep(\".BBBB\");\n    \n    int stuck=0;\n    while(totalDisp < 25 && turns_ < 9950) {\n        // Find closest available want in grid\n        int best_cost = INT_MAX;\n        int tr=-1, tc=-1, tgate=-1;\n        for(int g=0;g<5;g++){\n            if(nout_[g]>=5) continue;\n            int want = g*5 + nout_[g];\n            for(int r=0;r<5;r++) for(int c=0;c<5;c++) {\n                if(grid_[r][c]==want){\n                    int cost = abs(cr_[0]-r) + abs(cc_[0]-c) + abs(r-g) + abs(4-c);\n                    if(cost < best_cost) {\n                        best_cost = cost;\n                        tr=r; tc=c; tgate=g;\n                    }\n                }\n            }\n        }\n        if(tr!=-1) {\n            moveLarge(tr,tc);\n            P0();\n            moveLarge(tgate,4);\n            Q0();\n            stuck=0;\n        } else {\n            // Stash: prefer rows whose next-arrive is a pending want\n            int sr = -1;\n            int best_prio = INT_MAX;\n            for(int i=0;i<5;i++){\n                if(grid_[i][0]==-1) continue;\n                int prio;\n                if(nin_[i]>=5) prio = 10000;\n                else {\n                    int next = A[i][nin_[i]];\n                    bool isWant = false;\n                    for(int g=0;g<5;g++){\n                        if(nout_[g]<5 && g*5+nout_[g]==next){isWant=true; break;}\n                    }\n                    prio = isWant ? (-1000+next) : next;\n                }\n                if(prio < best_prio){\n                    best_prio = prio;\n                    sr = i;\n                }\n            }\n            if(sr==-1){\n                doStep(\".....\");\n                stuck++;\n                if(stuck>200) break;\n                continue;\n            }\n            int v = grid_[sr][0];\n            int tgt_row = v/5;\n            int dr=-1, dc=-1;\n            int colPref[] = {3,2,1};\n            for(int ci=0;ci<3;ci++){\n                int c=colPref[ci];\n                if(grid_[tgt_row][c]==-1){dr=tgt_row;dc=c;break;}\n            }\n            if(dr==-1) {\n                for(int ci=0;ci<3 && dr==-1;ci++){\n                    int c=colPref[ci];\n                    for(int r=0;r<5;r++) if(grid_[r][c]==-1){dr=r;dc=c;break;}\n                }\n            }\n            if(dr==-1){\n                doStep(\".....\");\n                stuck++;\n                if(stuck>200) break;\n                continue;\n            }\n            moveLarge(sr,0);\n            P0();\n            moveLarge(dr,dc);\n            Q0();\n            stuck=0;\n        }\n    }\n    \n    for(int i=0;i<5;i++) cout<<out_[i]<<\"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint H0[25][25];\n\nstruct Sim {\n    int h[25][25];\n    vector<string> ops;\n    int cr=0, cc=0;\n    long long load=0;\n    long long cost=0;\n    \n    void init(){\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)h[i][j]=H0[i][j];\n        ops.clear(); cr=cc=0; load=0; cost=0;\n    }\n    void mv(char d){\n        ops.push_back(string(1,d));\n        cost += 100+load;\n        if(d=='U')cr--; else if(d=='D')cr++; else if(d=='L')cc--; else cc++;\n    }\n    void doLoad(long long d){ if(d<=0)return; ops.push_back(\"+\"+to_string(d)); h[cr][cc]-=d; load+=d; cost+=d;}\n    void doUnload(long long d){ if(d<=0)return; ops.push_back(\"-\"+to_string(d)); h[cr][cc]+=d; load-=d; cost+=d;}\n    void moveTo(int tr,int tc){\n        while(cr!=tr){ if(cr<tr)mv('D'); else mv('U'); }\n        while(cc!=tc){ if(cc<tc)mv('R'); else mv('L'); }\n    }\n    bool done(){\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(h[i][j]!=0)return false;\n        return true;\n    }\n};\n\nvector<pair<int,int>> buildPath(bool rowMajor, bool startBot, bool startRight){\n    vector<pair<int,int>> path;\n    if(rowMajor){\n        for(int ii=0;ii<N;ii++){\n            int i = startBot ? N-1-ii : ii;\n            bool rev = (ii%2==1) ^ startRight;\n            if(!rev) for(int j=0;j<N;j++) path.push_back({i,j});\n            else for(int j=N-1;j>=0;j--) path.push_back({i,j});\n        }\n    } else {\n        for(int jj=0;jj<N;jj++){\n            int j = startRight ? N-1-jj : jj;\n            bool rev = (jj%2==1) ^ startBot;\n            if(!rev) for(int i=0;i<N;i++) path.push_back({i,j});\n            else for(int i=N-1;i>=0;i--) path.push_back({i,j});\n        }\n    }\n    return path;\n}\n\nvoid snakePass(Sim& s, vector<pair<int,int>>& path, bool rev){\n    if(!rev){\n        for(auto& p:path){\n            int r=p.first,c=p.second;\n            s.moveTo(r,c);\n            if(s.h[r][c]>0) s.doLoad(s.h[r][c]);\n            else if(s.h[r][c]<0) s.doUnload(min(s.load,(long long)-s.h[r][c]));\n        }\n    } else {\n        for(int i=(int)path.size()-1;i>=0;i--){\n            int r=path[i].first,c=path[i].second;\n            s.moveTo(r,c);\n            if(s.h[r][c]>0) s.doLoad(s.h[r][c]);\n            else if(s.h[r][c]<0) s.doUnload(min(s.load,(long long)-s.h[r][c]));\n        }\n    }\n}\n\nvoid smartSnakePass(Sim& s, vector<pair<int,int>>& path){\n    int n=path.size();\n    vector<long long> sufNeg(n+1,0);\n    for(int i=n-1;i>=0;i--){\n        int r=path[i].first,c=path[i].second;\n        sufNeg[i] = sufNeg[i+1] + max(0,-s.h[r][c]);\n    }\n    for(int idx=0;idx<n;idx++){\n        int r=path[idx].first,c=path[idx].second;\n        s.moveTo(r,c);\n        if(s.h[r][c]>0){\n            long long demand = sufNeg[idx+1];\n            long long toLoad = min((long long)s.h[r][c], max(0LL, demand - s.load));\n            s.doLoad(toLoad);\n        } else if(s.h[r][c]<0){\n            s.doUnload(min(s.load,(long long)-s.h[r][c]));\n        }\n    }\n}\n\nvoid greedyCleanup(Sim& s){\n    int guard=0;\n    while(!s.done() && guard++<5000){\n        int target=-1,td=INT_MAX;\n        if(s.load>0){\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                if(s.h[i][j]<0){\n                    int d=abs(i-s.cr)+abs(j-s.cc);\n                    if(d<td){td=d;target=i*N+j;}\n                }\n            }\n            if(target<0) break;\n        } else {\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                if(s.h[i][j]>0){\n                    int d=abs(i-s.cr)+abs(j-s.cc);\n                    if(d<td){td=d;target=i*N+j;}\n                }\n            }\n            if(target<0) break;\n        }\n        int tr=target/N, tc=target%N;\n        s.moveTo(tr,tc);\n        if(s.h[tr][tc]>0) s.doLoad(s.h[tr][tc]);\n        else if(s.h[tr][tc]<0) s.doUnload(min(s.load,(long long)-s.h[tr][tc]));\n    }\n}\n\nvoid pureGreedy(Sim& s){\n    int guard=0;\n    while(!s.done() && guard++<5000){\n        if(s.h[s.cr][s.cc]>0){\n            bool anyNeg=false;\n            for(int i=0;i<N && !anyNeg;i++)for(int j=0;j<N;j++)if(s.h[i][j]<0){anyNeg=true;break;}\n            if(anyNeg){s.doLoad(s.h[s.cr][s.cc]); continue;}\n        }\n        if(s.h[s.cr][s.cc]<0 && s.load>0){\n            s.doUnload(min(s.load,(long long)-s.h[s.cr][s.cc]));\n            continue;\n        }\n        int target=-1,td=INT_MAX;\n        if(s.load>0){\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                if(s.h[i][j]<0){\n                    int d=abs(i-s.cr)+abs(j-s.cc);\n                    if(d<td){td=d;target=i*N+j;}\n                }\n            }\n        } else {\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                if(s.h[i][j]>0){\n                    int d=abs(i-s.cr)+abs(j-s.cc);\n                    if(d<td){td=d;target=i*N+j;}\n                }\n            }\n        }\n        if(target<0) break;\n        s.moveTo(target/N, target%N);\n    }\n}\n\nvoid pairGreedy(Sim& s){\n    int guard=0;\n    while(!s.done() && guard++<5000){\n        if(s.h[s.cr][s.cc]<0 && s.load>0){\n            s.doUnload(min(s.load,(long long)-s.h[s.cr][s.cc]));\n            continue;\n        }\n        if(s.load>0){\n            int bi=-1,bj=-1,bd=INT_MAX;\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                if(s.h[i][j]<0){\n                    int d=abs(i-s.cr)+abs(j-s.cc);\n                    if(d<bd){bd=d;bi=i;bj=j;}\n                }\n            }\n            if(bi<0)break;\n            s.moveTo(bi,bj);\n            s.doUnload(min(s.load,(long long)-s.h[bi][bj]));\n        } else {\n            int bPi=-1,bPj=-1,bNi=-1,bNj=-1;\n            long long bestCost=LLONG_MAX;\n            for(int pi=0;pi<N;pi++)for(int pj=0;pj<N;pj++){\n                if(s.h[pi][pj]<=0)continue;\n                int d1 = abs(pi-s.cr)+abs(pj-s.cc);\n                for(int ni=0;ni<N;ni++)for(int nj=0;nj<N;nj++){\n                    if(s.h[ni][nj]>=0)continue;\n                    int d2 = abs(pi-ni)+abs(pj-nj);\n                    int amt = min(s.h[pi][pj],-s.h[ni][nj]);\n                    long long c = (long long)d1*100 + (long long)d2*(100+amt) + amt*2;\n                    if(c<bestCost){bestCost=c;bPi=pi;bPj=pj;bNi=ni;bNj=nj;}\n                }\n            }\n            if(bPi<0)break;\n            s.moveTo(bPi,bPj);\n            s.doLoad(s.h[bPi][bPj]);\n        }\n    }\n}\n\nlong long runConfig(int mode, bool rm, bool sb, bool sr, Sim& out){\n    Sim s; s.init();\n    auto path = buildPath(rm, sb, sr);\n    \n    if(mode==0){\n        snakePass(s, path, false);\n        greedyCleanup(s);\n    } else if(mode==1){\n        for(int it=0;it<20;it++){\n            if(s.done())break;\n            snakePass(s, path, it%2==1);\n        }\n    } else if(mode==2){\n        snakePass(s, path, false);\n        if(!s.done()) snakePass(s, path, true);\n        greedyCleanup(s);\n    } else if(mode==3){\n        smartSnakePass(s, path);\n        greedyCleanup(s);\n    } else if(mode==4){\n        pureGreedy(s);\n    } else if(mode==5){\n        pairGreedy(s);\n    }\n    \n    out = s;\n    return s.done() ? s.cost : LLONG_MAX;\n}\n\nint main(){\n    cin>>N;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>H0[i][j];\n    \n    Sim best, tmp;\n    long long bestCost = LLONG_MAX;\n    \n    for(int mode=4;mode<=5;mode++){\n        long long c = runConfig(mode,false,false,false,tmp);\n        if(c<bestCost){bestCost=c;best=tmp;}\n    }\n    \n    for(int rm=0;rm<2;rm++)for(int sb=0;sb<2;sb++)for(int sr=0;sr<2;sr++){\n        for(int mode=0;mode<4;mode++){\n            long long c = runConfig(mode,rm,sb,sr,tmp);\n            if(c < bestCost){ bestCost=c; best=tmp; }\n        }\n    }\n    for(auto&o:best.ops) cout<<o<<\"\\n\";\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, T, SC;\nvector<vector<int>> X;\nmt19937 rng(12345);\n\ninline int pairScore(int a, int b) {\n    int s = 0;\n    for (int l = 0; l < M; l++) s += max(X[a][l], X[b][l]);\n    return s;\n}\n\nint main() {\n    cin >> N >> M >> T;\n    SC = 2*N*(N-1);\n    X.assign(SC, vector<int>(M));\n    for (int i = 0; i < SC; i++)\n        for (int j = 0; j < M; j++) cin >> X[i][j];\n    \n    for (int t = 0; t < T; t++) {\n        vector<int> Xmax(M, 0);\n        for (int k = 0; k < SC; k++)\n            for (int l = 0; l < M; l++) Xmax[l] = max(Xmax[l], X[k][l]);\n        \n        vector<double> score(SC, 0);\n        for (int k = 0; k < SC; k++) {\n            for (int l = 0; l < M; l++) {\n                if (Xmax[l] > 0) {\n                    double r = (double)X[k][l] / Xmax[l];\n                    score[k] += r * r * Xmax[l];\n                }\n            }\n        }\n        \n        vector<int> idx(SC);\n        iota(idx.begin(), idx.end(), 0);\n        sort(idx.begin(), idx.end(), [&](int a, int b){ return score[a] > score[b]; });\n        vector<int> chosen(idx.begin(), idx.begin() + N*N);\n        \n        set<int> chosenSet(chosen.begin(), chosen.end());\n        for (int l = 0; l < M; l++) {\n            vector<int> maxSeeds;\n            for (int k = 0; k < SC; k++) if (X[k][l] == Xmax[l]) maxSeeds.push_back(k);\n            bool found = false;\n            for (int k : maxSeeds) if (chosenSet.count(k)) { found = true; break; }\n            if (!found && !maxSeeds.empty()) {\n                int best = maxSeeds[0];\n                for (int k : maxSeeds) if (score[k] > score[best]) best = k;\n                int worst = -1; double worstS = 1e18;\n                for (int c : chosen) {\n                    bool isUnique = false;\n                    for (int ll = 0; ll < M; ll++) {\n                        if (X[c][ll] == Xmax[ll]) {\n                            int cnt = 0;\n                            for (int kk : chosen) if (X[kk][ll] == Xmax[ll]) cnt++;\n                            if (cnt == 1) { isUnique = true; break; }\n                        }\n                    }\n                    if (isUnique) continue;\n                    if (score[c] < worstS) { worstS = score[c]; worst = c; }\n                }\n                if (worst >= 0) {\n                    auto it = find(chosen.begin(), chosen.end(), worst);\n                    *it = best;\n                    chosenSet.erase(worst); chosenSet.insert(best);\n                }\n            }\n        }\n        \n        int NN = N*N;\n        vector<vector<int>> P(NN, vector<int>(NN, 0));\n        for (int i = 0; i < NN; i++)\n            for (int j = 0; j < NN; j++)\n                P[i][j] = pairScore(chosen[i], chosen[j]);\n        \n        vector<int> sortedChosenIdx(NN);\n        iota(sortedChosenIdx.begin(), sortedChosenIdx.end(), 0);\n        sort(sortedChosenIdx.begin(), sortedChosenIdx.end(), [&](int a, int b){\n            return score[chosen[a]] > score[chosen[b]];\n        });\n        \n        vector<pair<int,int>> cells;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            int deg = (i>0)+(i<N-1)+(j>0)+(j<N-1);\n            cells.push_back({-deg, i*N+j});\n        }\n        sort(cells.begin(), cells.end());\n        \n        vector<vector<int>> A(N, vector<int>(N));\n        for (int c = 0; c < NN; c++) {\n            int p = cells[c].second;\n            A[p/N][p%N] = sortedChosenIdx[c];\n        }\n        \n        auto totalScoreA = [&](vector<vector<int>>& AA) {\n            int s = 0;\n            for (int i = 0; i < N; i++)\n                for (int j = 0; j < N; j++) {\n                    if (j+1 < N) s += P[AA[i][j]][AA[i][j+1]];\n                    if (i+1 < N) s += P[AA[i][j]][AA[i+1][j]];\n                }\n            return s;\n        };\n        \n        auto deltaSwap = [&](vector<vector<int>>& AA, int i1, int j1, int i2, int j2) {\n            static const int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};\n            int a1 = AA[i1][j1], a2 = AA[i2][j2];\n            int before = 0, after = 0;\n            for (int d = 0; d < 4; d++) {\n                int ni = i1+dr[d], nj = j1+dc[d];\n                if (ni<0||ni>=N||nj<0||nj>=N) continue;\n                if (ni==i2 && nj==j2) continue;\n                int nb = AA[ni][nj];\n                before += P[a1][nb];\n                after += P[a2][nb];\n            }\n            for (int d = 0; d < 4; d++) {\n                int ni = i2+dr[d], nj = j2+dc[d];\n                if (ni<0||ni>=N||nj<0||nj>=N) continue;\n                if (ni==i1 && nj==j1) continue;\n                int nb = AA[ni][nj];\n                before += P[a2][nb];\n                after += P[a1][nb];\n            }\n            return after - before;\n        };\n        \n        int curScore = totalScoreA(A);\n        int bestScore = curScore;\n        vector<vector<int>> bestA = A;\n        \n        auto start = chrono::steady_clock::now();\n        double timeLimit = 0.19;\n        double T0 = 30.0, T1 = 0.1;\n        double temp = T0;\n        int iters = 0;\n        \n        while (true) {\n            iters++;\n            if ((iters & 1023) == 0) {\n                auto now = chrono::steady_clock::now();\n                double elapsed = chrono::duration<double>(now-start).count();\n                if (elapsed > timeLimit) break;\n                double progress = elapsed / timeLimit;\n                temp = T0 * pow(T1/T0, progress);\n            }\n            \n            int p1 = rng() % NN;\n            int p2 = rng() % NN;\n            if (p1 == p2) continue;\n            int i1=p1/N, j1=p1%N, i2=p2/N, j2=p2%N;\n            int delta = deltaSwap(A, i1, j1, i2, j2);\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else {\n                double p = exp(delta / temp);\n                if ((double)(rng() & 0xFFFFFF) / (double)0x1000000 < p) accept = true;\n            }\n            if (accept) {\n                swap(A[i1][j1], A[i2][j2]);\n                curScore += delta;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestA = A;\n                }\n            }\n        }\n        \n        A = bestA;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << chosen[A[i][j]];\n                cout << (j==N-1 ? '\\n' : ' ');\n            }\n        }\n        cout.flush();\n        \n        for (int i = 0; i < SC; i++)\n            for (int j = 0; j < M; j++) cin >> X[i][j];\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V, Vp;\nint dx[4] = {0, 1, 0, -1};\nint dy[4] = {1, 0, -1, 0};\n\nint main() {\n    cin >> N >> M >> V;\n    vector<string> sg(N), tg(N);\n    for (auto& s : sg) cin >> s;\n    for (auto& s : tg) cin >> s;\n    \n    vector<vector<int>> has_(N, vector<int>(N, 0));\n    vector<vector<int>> isTarget(N, vector<int>(N, 0));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        has_[i][j] = sg[i][j]=='1';\n        isTarget[i][j] = tg[i][j]=='1';\n    }\n    \n    Vp = V;\n    int nFingers = Vp - 1;\n    \n    int maxL = min(4, N-1);\n    vector<int> L(nFingers);\n    for (int i = 0; i < nFingers; i++) L[i] = 1 + (i % maxL);\n    \n    cout << Vp << \"\\n\";\n    for (int i = 0; i < nFingers; i++) cout << 0 << \" \" << L[i] << \"\\n\";\n    \n    int rx = N/2, ry = N/2;\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<int> fdir(nFingers, 0);\n    vector<int> fhold(nFingers, 0);\n    \n    vector<string> ops;\n    \n    auto rotCost = [](int a, int b) {\n        return min((a-b+4)%4, (b-a+4)%4);\n    };\n    \n    auto doTurn = [&](char moveC, vector<char> rotC) {\n        if (moveC == 'U') rx--;\n        else if (moveC == 'D') rx++;\n        else if (moveC == 'L') ry--;\n        else if (moveC == 'R') ry++;\n        for (int i = 0; i < nFingers; i++) {\n            if (rotC[i] == 'R') fdir[i] = (fdir[i]+1)%4;\n            else if (rotC[i] == 'L') fdir[i] = (fdir[i]+3)%4;\n        }\n        vector<bool> actuallyP(nFingers, false);\n        for (int i = 0; i < nFingers; i++) {\n            int fx = rx + dx[fdir[i]]*L[i];\n            int fy = ry + dy[fdir[i]]*L[i];\n            if (fx<0||fx>=N||fy<0||fy>=N) continue;\n            if (fhold[i] == 0) {\n                if (has_[fx][fy] && !isTarget[fx][fy]) {\n                    has_[fx][fy] = 0;\n                    fhold[i] = 1;\n                    actuallyP[i] = true;\n                }\n            } else {\n                if (!has_[fx][fy] && isTarget[fx][fy]) {\n                    has_[fx][fy] = 1;\n                    fhold[i] = 0;\n                    actuallyP[i] = true;\n                }\n            }\n        }\n        string s(2*Vp, '.');\n        if (moveC != 0) s[0] = moveC;\n        for (int i = 0; i < nFingers; i++) if (rotC[i]) s[1+i] = rotC[i];\n        for (int i = 0; i < nFingers; i++) if (actuallyP[i]) s[Vp+1+i] = 'P';\n        ops.push_back(s);\n    };\n    \n    auto planAtPosition = [&](int rrx, int rry) {\n        int P = 0, maxRot = 0;\n        vector<int> tdir(nFingers, -1);\n        for (int fi = 0; fi < nFingers; fi++) {\n            int bestRot = INT_MAX, bestD = -1;\n            for (int d = 0; d < 4; d++) {\n                int fx = rrx + dx[d]*L[fi], fy = rry + dy[d]*L[fi];\n                if (fx<0||fx>=N||fy<0||fy>=N) continue;\n                bool useful = false;\n                if (fhold[fi] == 0) useful = has_[fx][fy] && !isTarget[fx][fy];\n                else useful = !has_[fx][fy] && isTarget[fx][fy];\n                if (useful) {\n                    int rc = rotCost(fdir[fi], d);\n                    if (rc < bestRot) { bestRot = rc; bestD = d; }\n                }\n            }\n            if (bestD != -1) {\n                P++;\n                maxRot = max(maxRot, bestRot);\n                tdir[fi] = bestD;\n            }\n        }\n        return make_tuple(P, maxRot, tdir);\n    };\n    \n    while (true) {\n        int srcCnt = 0, tgtCnt = 0;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (has_[i][j] && !isTarget[i][j]) srcCnt++;\n            if (!has_[i][j] && isTarget[i][j]) tgtCnt++;\n        }\n        int nHolding = 0;\n        for (int i = 0; i < nFingers; i++) nHolding += fhold[i];\n        \n        if (srcCnt == 0 && nHolding == 0) break;\n        if ((int)ops.size() > 95000) break;\n        \n        double bestScore = -1;\n        int bestP = 0;\n        int bestRx = rx, bestRy = ry;\n        vector<int> bestTargetDir;\n        \n        for (int rrx = 0; rrx < N; rrx++)\n        for (int rry = 0; rry < N; rry++) {\n            auto [P, maxRot, tdir] = planAtPosition(rrx, rry);\n            if (P == 0) continue;\n            int move = abs(rrx-rx) + abs(rry-ry);\n            int T = max(move, maxRot);\n            if (T == 0) T = 1;\n            double score = (double)P / T;\n            if (score > bestScore + 1e-9 || (abs(score - bestScore) < 1e-9 && P > bestP)) {\n                bestScore = score; bestP = P;\n                bestRx = rrx; bestRy = rry;\n                bestTargetDir = tdir;\n            }\n        }\n        \n        if (bestP == 0) break;\n        \n        int mv_dx = bestRx - rx, mv_dy = bestRy - ry;\n        vector<char> mvSeq;\n        for (int i = 0; i < abs(mv_dx); i++) mvSeq.push_back(mv_dx>0?'D':'U');\n        for (int i = 0; i < abs(mv_dy); i++) mvSeq.push_back(mv_dy>0?'R':'L');\n        \n        vector<vector<char>> rotSeq(nFingers);\n        int maxRotLen = 0;\n        for (int fi = 0; fi < nFingers; fi++) {\n            if (bestTargetDir[fi] == -1) continue;\n            int diff = (bestTargetDir[fi] - fdir[fi] + 4) % 4;\n            if (diff == 1) rotSeq[fi].push_back('R');\n            else if (diff == 2) { rotSeq[fi].push_back('R'); rotSeq[fi].push_back('R'); }\n            else if (diff == 3) rotSeq[fi].push_back('L');\n            maxRotLen = max(maxRotLen, (int)rotSeq[fi].size());\n        }\n        \n        int turns = max((int)mvSeq.size(), maxRotLen);\n        if (turns == 0) turns = 1;\n        \n        for (int t = 0; t < turns; t++) {\n            char mc = t < (int)mvSeq.size() ? mvSeq[t] : 0;\n            vector<char> rc(nFingers, 0);\n            for (int fi = 0; fi < nFingers; fi++)\n                if (t < (int)rotSeq[fi].size()) rc[fi] = rotSeq[fi][t];\n            doTurn(mc, rc);\n        }\n    }\n    \n    for (auto& o : ops) cout << o << \"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<int> X, Y;\n\nstruct Result {\n    vector<pair<int,int>> poly;\n    long long score;\n    long long perim;\n    bool valid;\n};\n\nResult checkResult(vector<pair<int,int>>& poly, long long score){\n    Result r;\n    r.poly = poly;\n    r.score = score;\n    long long perim=0;\n    int n=poly.size();\n    for(int i=0;i<n;i++){\n        auto& a=poly[i]; auto& b=poly[(i+1)%n];\n        perim += abs(a.first-b.first)+abs(a.second-b.second);\n    }\n    r.perim = perim;\n    set<pair<int,int>> seen;\n    bool distinct=true;\n    for(auto& p:poly){ if(seen.count(p)){distinct=false;break;} seen.insert(p); }\n    r.valid = distinct && perim<=400000 && n<=1000 && n>=4;\n    return r;\n}\n\nResult bestRectangle(int W, int H){\n    int cw = 100000/W, ch = 100000/H;\n    vector<vector<int>> grid(W, vector<int>(H,0));\n    for(int i=0;i<2*N;i++){\n        int c = min(W-1, X[i]/cw);\n        int rr = min(H-1, Y[i]/ch);\n        grid[c][rr] += (i<N) ? 1 : -1;\n    }\n    long long best = LLONG_MIN;\n    int bC1=0, bC2=0, bR1=0, bR2=0;\n    for(int r1=0;r1<H;r1++){\n        vector<int> colSum(W, 0);\n        for(int r2=r1;r2<H;r2++){\n            for(int c=0;c<W;c++) colSum[c] += grid[c][r2];\n            long long cs=0, bestSum=LLONG_MIN;\n            int curL=0, bL=0, bR=0;\n            for(int c=0;c<W;c++){\n                if(cs<=0){ cs=colSum[c]; curL=c; } else cs+=colSum[c];\n                if(cs>bestSum){ bestSum=cs; bL=curL; bR=c; }\n            }\n            if(bestSum>best){\n                best=bestSum; bC1=bL; bC2=bR; bR1=r1; bR2=r2;\n            }\n        }\n    }\n    int x1=bC1*cw, x2=(bC2+1)*cw, y1=bR1*ch, y2=(bR2+1)*ch;\n    vector<pair<int,int>> poly = {{x1,y1},{x2,y1},{x2,y2},{x1,y2}};\n    return checkResult(poly, best);\n}\n\nResult solveDir(int W, int H, bool swapXY){\n    int cw = 100000/W, ch = 100000/H;\n    vector<vector<int>> grid(W, vector<int>(H,0));\n    for(int i=0;i<2*N;i++){\n        int xx = swapXY ? Y[i] : X[i];\n        int yy = swapXY ? X[i] : Y[i];\n        int c = min(W-1, xx/cw);\n        int rr = min(H-1, yy/ch);\n        grid[c][rr] += (i<N) ? 1 : -1;\n    }\n    \n    vector<int> lo(W), hi(W), val(W);\n    for(int c=0;c<W;c++){\n        int bestSum = INT_MIN, bestL=0, bestR=-1;\n        int curSum=0, curL=0;\n        for(int rr=0;rr<H;rr++){\n            if(curSum <= 0){ curSum = grid[c][rr]; curL = rr; }\n            else curSum += grid[c][rr];\n            if(curSum > bestSum){ bestSum = curSum; bestL=curL; bestR=rr; }\n        }\n        lo[c]=bestL; hi[c]=bestR; val[c]=bestSum;\n    }\n    \n    int totBest=INT_MIN, cL=0, cR=0, csu=0, cSL=0;\n    for(int c=0;c<W;c++){\n        if(csu<=0){ csu=val[c]; cSL=c; } else csu+=val[c];\n        if(csu>totBest){ totBest=csu; cL=cSL; cR=c; }\n    }\n    \n    for(int c=cL+1;c<=cR;c++){\n        if(hi[c] < lo[c-1]) hi[c] = lo[c-1];\n        if(lo[c] > hi[c-1]) lo[c] = hi[c-1];\n    }\n    \n    vector<long long> colS(W+1, 0);\n    for(int c=0;c<W;c++){\n        long long s=0;\n        for(int rr=lo[c];rr<=hi[c];rr++) s+=grid[c][rr];\n        colS[c+1] = colS[c] + s;\n    }\n    vector<long long> transV(W+1, 0);\n    for(int c=1;c<W;c++){\n        transV[c+1] = transV[c] + (long long)(abs(lo[c]-lo[c-1])+abs(hi[c]-hi[c-1]))*ch;\n    }\n    auto scoreR=[&](int a,int b){ return colS[b+1]-colS[a]; };\n    auto perimR=[&](int a,int b){\n        long long horiz = 2LL*(b-a+1)*cw;\n        long long closeV = (long long)(hi[a]-lo[a]+1)*ch + (long long)(hi[b]-lo[b]+1)*ch;\n        long long internalV = transV[b+1] - transV[a+1];\n        return horiz + closeV + internalV;\n    };\n    \n    auto buildPoly=[&](int a,int b)->vector<pair<int,int>>{\n        vector<pair<int,int>> poly;\n        poly.push_back({a*cw, lo[a]*ch});\n        for(int c=a;c<=b;c++){\n            int yb = lo[c]*ch;\n            if(c>a && lo[c]!=lo[c-1]){\n                poly.push_back({c*cw, yb});\n            }\n            poly.push_back({(c+1)*cw, yb});\n        }\n        poly.push_back({(b+1)*cw, (hi[b]+1)*ch});\n        for(int c=b;c>=a;c--){\n            int yt = (hi[c]+1)*ch;\n            if(c<b && hi[c]!=hi[c+1]){\n                poly.push_back({(c+1)*cw, yt});\n            }\n            poly.push_back({c*cw, yt});\n        }\n        vector<pair<int,int>> cleanPoly;\n        for(auto& p : poly){\n            if(cleanPoly.empty() || cleanPoly.back()!=p) cleanPoly.push_back(p);\n        }\n        while(cleanPoly.size()>1 && cleanPoly.front()==cleanPoly.back()) cleanPoly.pop_back();\n        return cleanPoly;\n    };\n    \n    int a=cL, b=cR;\n    while(a<b && (perimR(a,b) > 400000 || 4*(b-a+1)+4 > 1000)){\n        if(val[a] < val[b]) a++;\n        else b--;\n    }\n    \n    auto poly = buildPoly(a,b);\n    long long sc = scoreR(a,b);\n    \n    if(swapXY) for(auto& p:poly) swap(p.first,p.second);\n    \n    return checkResult(poly, sc);\n}\n\nint main(){\n    scanf(\"%d\", &N);\n    X.resize(2*N); Y.resize(2*N);\n    for(int i=0;i<2*N;i++) scanf(\"%d %d\",&X[i],&Y[i]);\n    \n    Result best;\n    best.valid = false;\n    best.score = LLONG_MIN;\n    \n    for(int res : {50, 100, 200}){\n        if(100000%res != 0) continue;\n        Result r = bestRectangle(res, res);\n        if(r.valid && r.score > best.score) best = r;\n    }\n    \n    vector<pair<int,int>> configs;\n    for(int w : {20,25,40,50,80,100,125,200,250}){\n        for(int h : {20,25,40,50,80,100,125,200,250,500}){\n            if(100000%w==0 && 100000%h==0) configs.push_back({w,h});\n        }\n    }\n    for(auto [W,H] : configs){\n        for(int dir=0; dir<2; dir++){\n            Result r = solveDir(W,H,dir==1);\n            if(r.valid && r.score > best.score) best = r;\n        }\n    }\n    \n    if(!best.valid || best.poly.empty()){\n        best.poly = {{0,0},{1,0},{1,1},{0,1}};\n    }\n    \n    printf(\"%d\\n\",(int)best.poly.size());\n    for(auto& p : best.poly) printf(\"%d %d\\n\", p.first, p.second);\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, sigma;\nvector<int> W_, H_;\nmt19937 rng(42);\n\nstruct Rect { long long x1,y1,x2,y2; };\n\npair<long long,long long> simulate(const vector<tuple<int,int,char,int>>& ops, const vector<int>& ww, const vector<int>& hh) {\n    unordered_map<int, Rect> placed;\n    placed.reserve(ops.size()*2);\n    long long maxX=0, maxY=0;\n    for (auto& [p, r, d, b] : ops) {\n        long long w = r==0 ? ww[p] : hh[p];\n        long long h = r==0 ? hh[p] : ww[p];\n        if (d == 'U') {\n            long long x1 = (b == -1) ? 0 : placed[b].x2;\n            long long x2 = x1 + w;\n            long long y1 = 0;\n            for (auto& kv : placed) {\n                auto& rc = kv.second;\n                if (rc.x2 <= x1 || rc.x1 >= x2) continue;\n                y1 = max(y1, rc.y2);\n            }\n            long long y2 = y1 + h;\n            placed[p] = {x1,y1,x2,y2};\n            maxX = max(maxX, x2); maxY = max(maxY, y2);\n        } else {\n            long long y1 = (b == -1) ? 0 : placed[b].y2;\n            long long y2 = y1 + h;\n            long long x1 = 0;\n            for (auto& kv : placed) {\n                auto& rc = kv.second;\n                if (rc.y2 <= y1 || rc.y1 >= y2) continue;\n                x1 = max(x1, rc.x2);\n            }\n            long long x2 = x1 + w;\n            placed[p] = {x1,y1,x2,y2};\n            maxX = max(maxX, x2); maxY = max(maxY, y2);\n        }\n    }\n    return {maxX, maxY};\n}\n\nvector<tuple<int,int,char,int>> buildRowLayout(long long targetW, const vector<int>& ww, const vector<int>& hh, const vector<int>& rots) {\n    vector<tuple<int,int,char,int>> ops;\n    long long shelfX = 0;\n    int firstOfShelf = -1;\n    int prevOnShelf = -1;\n    for (int i = 0; i < N; i++) {\n        int rot = rots[i];\n        long long w = rot==0 ? ww[i] : hh[i];\n        if (firstOfShelf == -1) {\n            ops.push_back({i, rot, 'U', -1});\n            firstOfShelf = i; prevOnShelf = i; shelfX = w;\n        } else if (shelfX + w <= targetW) {\n            ops.push_back({i, rot, 'U', prevOnShelf});\n            prevOnShelf = i; shelfX += w;\n        } else {\n            ops.push_back({i, rot, 'L', firstOfShelf});\n            firstOfShelf = i; prevOnShelf = i; shelfX = w;\n        }\n    }\n    return ops;\n}\n\nint main() {\n    cin >> N >> T >> sigma;\n    W_.resize(N); H_.resize(N);\n    for (int i = 0; i < N; i++) cin >> W_[i] >> H_[i];\n    \n    long long totalArea = 0;\n    for (int i = 0; i < N; i++) totalArea += (long long)W_[i] * H_[i];\n    long long sideEst = (long long)sqrt((double)totalArea);\n    \n    vector<tuple<int,int,char,int>> best;\n    long long bestScore = LLONG_MAX;\n    \n    auto tryOps = [&](vector<tuple<int,int,char,int>>& ops) {\n        auto [w,h] = simulate(ops, W_, H_);\n        long long sc = w+h;\n        if (sc < bestScore) { bestScore = sc; best = ops; }\n    };\n    \n    for (double f = 0.5; f <= 2.0; f += 0.05) {\n        long long tw = (long long)(sideEst * f);\n        for (int mode = 0; mode < 3; mode++) {\n            vector<int> r(N);\n            for (int i = 0; i < N; i++) {\n                if (mode == 0) r[i] = 0;\n                else if (mode == 1) r[i] = (W_[i] > H_[i]) ? 1 : 0;\n                else r[i] = (W_[i] < H_[i]) ? 1 : 0;\n            }\n            auto ops = buildRowLayout(tw, W_, H_, r);\n            tryOps(ops);\n        }\n    }\n    \n    auto startTime = chrono::steady_clock::now();\n    auto elapsed = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - startTime).count();\n    };\n    \n    double totalTime = 2.5;\n    \n    for (int t = 0; t < T; t++) {\n        double deadline = totalTime * (t+1) / T;\n        while (elapsed() < deadline) {\n            vector<int> r(N);\n            for (int i = 0; i < N; i++) r[i] = rng()%2;\n            double f = 0.5 + (rng()%150)/100.0;\n            long long tw = (long long)(sideEst * f);\n            auto ops = buildRowLayout(tw, W_, H_, r);\n            tryOps(ops);\n        }\n        \n        cout << best.size() << \"\\n\";\n        for (auto& [p,r,d,b] : best) cout << p << \" \" << r << \" \" << d << \" \" << b << \"\\n\";\n        cout.flush();\n        long long wm, hm; cin >> wm >> hm;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, H;\nvector<int> A;\nvector<vector<int>> adj;\nvector<int> par, dep;\nvector<vector<int>> ch;\n\nvoid buildChildren() {\n    ch.assign(N, {});\n    for (int i = 0; i < N; i++) if (par[i] != -1) ch[par[i]].push_back(i);\n}\n\nvoid recomputeDepths() {\n    queue<int> q;\n    for (int i = 0; i < N; i++) {\n        if (par[i] == -1) { dep[i] = 0; q.push(i); }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int c : ch[u]) { dep[c] = dep[u]+1; q.push(c); }\n    }\n}\n\nlong long computeScore() {\n    long long s = 0;\n    for (int i = 0; i < N; i++) s += (long long)(dep[i]+1) * A[i];\n    return s;\n}\n\nmt19937 rng(12345);\nvector<char> inSub;\nvector<int> subBuf;\nvector<int> stk_;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    cin >> N >> M >> H;\n    A.resize(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    adj.assign(N, {});\n    for (int i = 0; i < M; i++) {\n        int u, v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<int> xs(N), ys(N);\n    for (int i = 0; i < N; i++) cin >> xs[i] >> ys[i];\n    \n    par.assign(N, -1);\n    dep.assign(N, 0);\n    buildChildren();\n    inSub.assign(N, 0);\n    \n    auto startTime = chrono::steady_clock::now();\n    auto timeMs = [&]() -> long long {\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - startTime).count();\n    };\n    \n    auto doPass = [&]() -> bool {\n        bool improved = false;\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n        for (int v : order) {\n            subBuf.clear();\n            int sumA = 0, maxD = dep[v];\n            stk_.clear(); stk_.push_back(v);\n            while (!stk_.empty()) {\n                int u = stk_.back(); stk_.pop_back();\n                subBuf.push_back(u);\n                inSub[u] = 1;\n                sumA += A[u];\n                if (dep[u] > maxD) maxD = dep[u];\n                for (int c : ch[u]) stk_.push_back(c);\n            }\n            int relMaxD = maxD - dep[v];\n            \n            int bestP = par[v];\n            long long bestDelta = 0;\n            int curDep = dep[v];\n            int oldP = par[v];\n            \n            if (oldP != -1) {\n                int delta = 0 - curDep;\n                long long change = (long long)delta * sumA;\n                if (change > bestDelta) { bestDelta = change; bestP = -1; }\n            }\n            for (int u : adj[v]) {\n                if (u == oldP) continue;\n                if (inSub[u]) continue;\n                int newDep = dep[u] + 1;\n                if (newDep + relMaxD > H) continue;\n                int delta = newDep - curDep;\n                long long change = (long long)delta * sumA;\n                if (change > bestDelta) { bestDelta = change; bestP = u; }\n            }\n            \n            for (int u : subBuf) inSub[u] = 0;\n            \n            if (bestDelta > 0) {\n                int oldP2 = par[v];\n                par[v] = bestP;\n                int newDep = (bestP == -1 ? 0 : dep[bestP] + 1);\n                int delta = newDep - curDep;\n                if (oldP2 != -1) {\n                    auto& vec = ch[oldP2];\n                    auto it = find(vec.begin(), vec.end(), v);\n                    if (it != vec.end()) vec.erase(it);\n                }\n                if (bestP != -1) ch[bestP].push_back(v);\n                stk_.clear(); stk_.push_back(v);\n                while (!stk_.empty()) {\n                    int u = stk_.back(); stk_.pop_back();\n                    dep[u] += delta;\n                    for (int c : ch[u]) stk_.push_back(c);\n                }\n                improved = true;\n            }\n        }\n        return improved;\n    };\n    \n    long long bestScore = computeScore();\n    vector<int> bestPar = par;\n    \n    while (timeMs() < 500 && doPass()) {}\n    {\n        long long sc = computeScore();\n        if (sc > bestScore) { bestScore = sc; bestPar = par; }\n    }\n    \n    int stuckCount = 0;\n    while (timeMs() < 1850) {\n        int K;\n        if (stuckCount >= 5) {\n            K = 150 + (int)(rng() % 350);\n            stuckCount = 0;\n        } else {\n            K = 20 + (int)(rng() % 80);\n        }\n        for (int t = 0; t < K; t++) {\n            int v = (int)(rng() % N);\n            if (par[v] != -1) {\n                auto& vec = ch[par[v]];\n                auto it = find(vec.begin(), vec.end(), v);\n                if (it != vec.end()) vec.erase(it);\n                par[v] = -1;\n            }\n        }\n        recomputeDepths();\n        \n        while (timeMs() < 1850 && doPass()) {}\n        long long sc2 = computeScore();\n        if (sc2 > bestScore) {\n            bestScore = sc2;\n            bestPar = par;\n            stuckCount = 0;\n        } else {\n            stuckCount++;\n            par = bestPar;\n            buildChildren();\n            recomputeDepths();\n        }\n    }\n    \n    par = bestPar;\n    for (int i = 0; i < N; i++) cout << par[i] << \" \\n\"[i==N-1];\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nusing Board = array<array<char, 20>, 20>;\nstruct Move { char d; int p; };\n\nchar shiftOp(Board& b, char d, int p) {\n    char rem;\n    if (d=='L') { rem=b[p][0]; for(int j=0;j<N-1;j++)b[p][j]=b[p][j+1]; b[p][N-1]='.'; }\n    else if (d=='R') { rem=b[p][N-1]; for(int j=N-1;j>0;j--)b[p][j]=b[p][j-1]; b[p][0]='.'; }\n    else if (d=='U') { rem=b[0][p]; for(int i=0;i<N-1;i++)b[i][p]=b[i+1][p]; b[N-1][p]='.'; }\n    else { rem=b[N-1][p]; for(int i=N-1;i>0;i--)b[i][p]=b[i-1][p]; b[0][p]='.'; }\n    return rem;\n}\n\nint countOni(const Board& b) {\n    int c=0;\n    for (int i=0;i<N;i++) for(int j=0;j<N;j++) if (b[i][j]=='x') c++;\n    return c;\n}\n\nint heuristic(const Board& b) {\n    int leftF[20], rightF[20], topF[20], botF[20];\n    for (int i = 0; i < N; i++) { leftF[i]=N; rightF[i]=-1; topF[i]=N; botF[i]=-1; }\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (b[i][j]=='o') {\n        if (j < leftF[i]) leftF[i]=j;\n        if (j > rightF[i]) rightF[i]=j;\n        if (i < topF[j]) topF[j]=i;\n        if (i > botF[j]) botF[j]=i;\n    }\n    int h = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (b[i][j]=='x') {\n        int best = 100;\n        if (leftF[i] > j) best = min(best, j+1);\n        if (rightF[i] < j) best = min(best, N-j);\n        if (topF[j] > i) best = min(best, i+1);\n        if (botF[j] < i) best = min(best, N-i);\n        h += best;\n    }\n    return h;\n}\n\nstruct Node {\n    Board board;\n    int cost;\n    int h;\n    int parent;\n    char d; int p; int k;\n};\n\nvector<Node> allNodes;\n\nvector<Move> reconstructPath(int nodeId) {\n    vector<vector<Move>> segs;\n    while (allNodes[nodeId].parent != -1) {\n        Node& n = allNodes[nodeId];\n        vector<Move> seg;\n        for (int i = 0; i < n.k; i++) seg.push_back({n.d, n.p});\n        segs.push_back(seg);\n        nodeId = n.parent;\n    }\n    reverse(segs.begin(), segs.end());\n    vector<Move> moves;\n    for (auto& s : segs) for (auto& m : s) moves.push_back(m);\n    return moves;\n}\n\nvector<Move> beamSearch(const Board& b0, int W, double alpha, int costLimit) {\n    allNodes.clear();\n    int totalOni = countOni(b0);\n    \n    vector<vector<int>> buckets(totalOni + 1);\n    \n    Node root;\n    root.board = b0; root.cost = 0; root.h = heuristic(b0); root.parent = -1;\n    root.d = 0; root.p = 0; root.k = 0;\n    allNodes.push_back(root);\n    buckets[totalOni].push_back(0);\n    \n    int bestFinal = -1;\n    int currentBest = costLimit;\n    \n    for (int level = totalOni; level > 0; level--) {\n        auto src = buckets[level];\n        if (src.empty()) continue;\n        \n        sort(src.begin(), src.end(), [&](int a, int b) {\n            double va = allNodes[a].cost + alpha * allNodes[a].h;\n            double vb = allNodes[b].cost + alpha * allNodes[b].h;\n            return va < vb;\n        });\n        if ((int)src.size() > W) src.resize(W);\n        \n        for (int sid : src) {\n            Board curBoard = allNodes[sid].board;\n            int curCost = allNodes[sid].cost;\n            if (curCost >= currentBest) continue;\n            \n            for (char d : {'L','R','U','D'}) {\n                for (int p = 0; p < N; p++) {\n                    Board tmp = curBoard;\n                    int oniRem = 0;\n                    for (int k = 1; k <= N; k++) {\n                        char r = shiftOp(tmp, d, p);\n                        if (r == 'o') break;\n                        if (r == 'x') oniRem++;\n                        if (oniRem > 0) {\n                            int newCost = curCost + k;\n                            if (newCost >= currentBest) continue;\n                            int hv = heuristic(tmp);\n                            int newLevel = level - oniRem;\n                            Node child;\n                            child.board = tmp; child.cost = newCost; child.h = hv;\n                            child.parent = sid; child.d = d; child.p = p; child.k = k;\n                            int nodeId = allNodes.size();\n                            allNodes.push_back(child);\n                            buckets[newLevel].push_back(nodeId);\n                            if (newLevel == 0 && newCost < currentBest) {\n                                currentBest = newCost;\n                                bestFinal = nodeId;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    if (bestFinal == -1) return {};\n    return reconstructPath(bestFinal);\n}\n\nvector<Move> hintSol(const Board& b) {\n    vector<Move> moves;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (b[i][j]=='x') {\n        bool up=true, down=true, left=true, right=true;\n        for (int r = 0; r < i; r++) if (b[r][j]=='o') up=false;\n        for (int r = i+1; r < N; r++) if (b[r][j]=='o') down=false;\n        for (int c = 0; c < j; c++) if (b[i][c]=='o') left=false;\n        for (int c = j+1; c < N; c++) if (b[i][c]=='o') right=false;\n        int bestCost = INT_MAX; char bestDir='?';\n        if (up && 2*(i+1) < bestCost) { bestCost=2*(i+1); bestDir='U'; }\n        if (down && 2*(N-i) < bestCost) { bestCost=2*(N-i); bestDir='D'; }\n        if (left && 2*(j+1) < bestCost) { bestCost=2*(j+1); bestDir='L'; }\n        if (right && 2*(N-j) < bestCost) { bestCost=2*(N-j); bestDir='R'; }\n        int k = bestCost/2;\n        char revD = (bestDir=='U'?'D':bestDir=='D'?'U':bestDir=='L'?'R':'L');\n        int p = (bestDir=='U'||bestDir=='D')?j:i;\n        for (int t = 0; t < k; t++) moves.push_back({bestDir, p});\n        for (int t = 0; t < k; t++) moves.push_back({revD, p});\n    }\n    return moves;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> N;\n    Board b0;\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) b0[i][j] = s[j];\n    }\n    \n    auto start = chrono::steady_clock::now();\n    auto elapsed = [&]() {\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-start).count();\n    };\n    \n    vector<Move> best = hintSol(b0);\n    int costLimit = best.size();\n    \n    vector<pair<int, double>> paramsList = {\n        {30, 1.0}, {30, 0.5}, {30, 1.5}, {50, 1.0}, {50, 0.7}, {50, 1.3}, {30, 2.0}, {30, 0.3}\n    };\n    for (auto [W, a] : paramsList) {\n        if (elapsed() > 1600) break;\n        auto m = beamSearch(b0, W, a, costLimit);\n        if (!m.empty() && (int)m.size() < (int)best.size()) {\n            best = m;\n            costLimit = best.size();\n        }\n    }\n    \n    for (auto& m : best) cout << m.d << \" \" << m.p << \"\\n\";\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, L;\nint Tg[128];\nint a[128], b[128];\nint cnt[128];\nint vp[128];\n\nlong long simError() {\n    for (int i = 0; i < N; i++) { cnt[i]=0; vp[i]=0; }\n    int x = 0;\n    for (int w = 0; w < L; w++) {\n        cnt[x]++;\n        vp[x] ^= 1;\n        x = vp[x] ? a[x] : b[x];\n    }\n    long long e = 0;\n    for (int i = 0; i < N; i++) e += abs(cnt[i] - Tg[i]);\n    return e;\n}\n\nint main() {\n    cin >> N >> L;\n    for (int i = 0; i < N; i++) cin >> Tg[i];\n    \n    vector<int> filled(N, 0);\n    filled[0] = 1;\n    \n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int x, int y){ return Tg[x] > Tg[y]; });\n    \n    for (int x : ord) {\n        int ca = (Tg[x] + 1) / 2;\n        int cb = Tg[x] / 2;\n        int besta = 0, bv = INT_MIN;\n        for (int i = 0; i < N; i++) {\n            int v = Tg[i] - filled[i];\n            if (v > bv) { bv = v; besta = i; }\n        }\n        a[x] = besta;\n        filled[besta] += ca;\n        int bestb = 0; bv = INT_MIN;\n        for (int i = 0; i < N; i++) {\n            int v = Tg[i] - filled[i];\n            if (v > bv) { bv = v; bestb = i; }\n        }\n        b[x] = bestb;\n        filled[bestb] += cb;\n    }\n    \n    long long bestE = simError();\n    \n    mt19937 rng(12345);\n    auto start = chrono::steady_clock::now();\n    \n    int iters = 0;\n    while (true) {\n        if ((iters & 7) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > 1.8) break;\n        }\n        iters++;\n        \n        int i = rng() % N;\n        int side = rng() % 2;\n        int newv = rng() % N;\n        int old;\n        if (side == 0) { old = a[i]; if (old == newv) continue; a[i] = newv; }\n        else { old = b[i]; if (old == newv) continue; b[i] = newv; }\n        \n        long long ne = simError();\n        if (ne <= bestE) {\n            bestE = ne;\n        } else {\n            if (side == 0) a[i] = old;\n            else b[i] = old;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> Gs;\nvector<int> lx, rx, ly, ry;\nvector<double> cx, cy;\nint queries_used = 0;\n\nvector<pair<int,int>> doQuery(vector<int> c) {\n    queries_used++;\n    cout << \"? \" << c.size();\n    for (int v : c) cout << \" \" << v;\n    cout << \"\\n\";\n    cout.flush();\n    vector<pair<int,int>> res(c.size()-1);\n    for (auto& p : res) cin >> p.first >> p.second;\n    return res;\n}\n\ndouble estDist(int i, int j) {\n    double dx = cx[i]-cx[j], dy = cy[i]-cy[j];\n    return sqrt(dx*dx+dy*dy);\n}\n\nvector<pair<int,int>> buildMST(int g, vector<int>& grp, set<pair<int,int>>& edgeSet) {\n    vector<tuple<double,int,int>> edges;\n    for (auto& p : edgeSet) edges.push_back({estDist(p.first, p.second), p.first, p.second});\n    sort(edges.begin(), edges.end());\n    \n    unordered_map<int,int> idx;\n    idx.reserve(g*2);\n    for (int i = 0; i < g; i++) idx[grp[i]] = i;\n    vector<int> par(g); iota(par.begin(), par.end(), 0);\n    function<int(int)> find = [&](int x){ return par[x]==x?x:par[x]=find(par[x]); };\n    \n    vector<pair<int,int>> mst;\n    for (auto& [d,u,v] : edges) {\n        int a = idx[u], b = idx[v];\n        int ra = find(a), rb = find(b);\n        if (ra != rb) {\n            par[ra] = rb;\n            mst.push_back({u,v});\n        }\n    }\n    if ((int)mst.size() < g - 1) {\n        vector<tuple<double,int,int>> allPairs;\n        for (int i = 0; i < g; i++) for (int j = i+1; j < g; j++) {\n            allPairs.push_back({estDist(grp[i], grp[j]), i, j});\n        }\n        sort(allPairs.begin(), allPairs.end());\n        for (auto& [d,a,b] : allPairs) {\n            int ra = find(a), rb = find(b);\n            if (ra != rb) {\n                par[ra] = rb;\n                mst.push_back({grp[a], grp[b]});\n            }\n        }\n    }\n    return mst;\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> Q >> L >> W;\n    Gs.resize(M);\n    for (auto& g : Gs) cin >> g;\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i]+rx[i])/2.0;\n        cy[i] = (ly[i]+ry[i])/2.0;\n    }\n    \n    vector<int> assigned(N, -1);\n    vector<vector<int>> groups(M);\n    \n    vector<int> gorder(M);\n    iota(gorder.begin(), gorder.end(), 0);\n    sort(gorder.begin(), gorder.end(), [&](int a, int b){ return Gs[a] > Gs[b]; });\n    \n    for (int gi : gorder) {\n        int sz = Gs[gi];\n        int seed = -1;\n        double bestv = 1e18;\n        for (int i = 0; i < N; i++) {\n            if (assigned[i] != -1) continue;\n            double v = cx[i] + cy[i]*0.0001;\n            if (v < bestv) { bestv = v; seed = i; }\n        }\n        vector<int>& grp = groups[gi];\n        grp.push_back(seed);\n        assigned[seed] = gi;\n        \n        vector<double> minD(N, 1e18);\n        for (int i = 0; i < N; i++) if (assigned[i] == -1) minD[i] = estDist(seed, i);\n        \n        while ((int)grp.size() < sz) {\n            int best = -1; double bd = 1e18;\n            for (int i = 0; i < N; i++) {\n                if (assigned[i] != -1) continue;\n                if (minD[i] < bd) { bd = minD[i]; best = i; }\n            }\n            grp.push_back(best);\n            assigned[best] = gi;\n            for (int i = 0; i < N; i++) {\n                if (assigned[i] == -1) {\n                    double d = estDist(best, i);\n                    if (d < minD[i]) minD[i] = d;\n                }\n            }\n        }\n    }\n    \n    vector<set<pair<int,int>>> edgeSets(M);\n    auto addEdgeSet = [](set<pair<int,int>>& es, int u, int v) {\n        if (u > v) swap(u,v);\n        es.insert({u,v});\n    };\n    \n    // Phase 1: chain queries for connectivity\n    for (int gi = 0; gi < M; gi++) {\n        int g = Gs[gi];\n        vector<int>& grp = groups[gi];\n        if (g <= 2) continue;\n        \n        vector<int> order;\n        vector<bool> used(g, false);\n        int start = 0;\n        double bv = 1e18;\n        for (int i = 0; i < g; i++) {\n            double v = cx[grp[i]] + cy[grp[i]]*0.0001;\n            if (v < bv) { bv = v; start = i; }\n        }\n        order.push_back(start); used[start] = true;\n        while ((int)order.size() < g) {\n            int last = order.back();\n            int best = -1; double bd = 1e18;\n            for (int i = 0; i < g; i++) {\n                if (used[i]) continue;\n                double d = estDist(grp[last], grp[i]);\n                if (d < bd) { bd = d; best = i; }\n            }\n            order.push_back(best); used[best] = true;\n        }\n        \n        int chunk_sz = L;\n        int step = max(1, L - 1);\n        for (int st = 0; st < g; st += step) {\n            int en = min(st + chunk_sz, g);\n            if (en - st < 2) break;\n            if (queries_used >= Q) break;\n            vector<int> q;\n            for (int i = st; i < en; i++) q.push_back(grp[order[i]]);\n            auto es = doQuery(q);\n            for (auto& [a,b] : es) addEdgeSet(edgeSets[gi], a, b);\n            if (en == g) break;\n        }\n    }\n    \n    // Phase 2: global edge-swap round-robin by longest MST edge\n    {\n        vector<vector<pair<int,int>>> currentMST(M);\n        vector<bool> mstDirty(M, true);\n        vector<set<pair<int,int>>> triedEdges(M);\n        int resets = 0;\n        \n        while (queries_used < Q) {\n            int bestGi = -1;\n            double bestLen = -1;\n            pair<int,int> bestEdge = {-1,-1};\n            \n            for (int gi = 0; gi < M; gi++) {\n                if (Gs[gi] < 3) continue;\n                if (mstDirty[gi]) {\n                    currentMST[gi] = buildMST(Gs[gi], groups[gi], edgeSets[gi]);\n                    mstDirty[gi] = false;\n                }\n                for (auto& [u,v] : currentMST[gi]) {\n                    int a = min(u,v), b = max(u,v);\n                    if (triedEdges[gi].count({a,b})) continue;\n                    double d = estDist(a,b);\n                    if (d > bestLen) {\n                        bestLen = d;\n                        bestGi = gi;\n                        bestEdge = {a,b};\n                    }\n                }\n            }\n            \n            if (bestGi == -1) {\n                if (resets >= 3) break;\n                resets++;\n                for (int gi = 0; gi < M; gi++) triedEdges[gi].clear();\n                continue;\n            }\n            \n            triedEdges[bestGi].insert(bestEdge);\n            \n            int eu = bestEdge.first, ev = bestEdge.second;\n            vector<int>& grp = groups[bestGi];\n            double mx = (cx[eu]+cx[ev])/2.0, my = (cy[eu]+cy[ev])/2.0;\n            vector<pair<double,int>> cand;\n            for (int c : grp) {\n                if (c == eu || c == ev) continue;\n                double dx = cx[c]-mx, dy = cy[c]-my;\n                cand.push_back({sqrt(dx*dx+dy*dy), c});\n            }\n            sort(cand.begin(), cand.end());\n            int take = min((int)cand.size(), L - 2);\n            vector<int> q = {eu, ev};\n            for (int i = 0; i < take; i++) q.push_back(cand[i].second);\n            if ((int)q.size() < 2) continue;\n            \n            auto es = doQuery(q);\n            bool newEdge = false;\n            for (auto& [a,b] : es) {\n                int x = min(a,b), y = max(a,b);\n                if (!edgeSets[bestGi].count({x,y})) newEdge = true;\n                addEdgeSet(edgeSets[bestGi], a, b);\n            }\n            if (newEdge) mstDirty[bestGi] = true;\n        }\n    }\n    \n    vector<vector<pair<int,int>>> allEdges(M);\n    \n    for (int gi = 0; gi < M; gi++) {\n        int g = Gs[gi];\n        vector<int>& grp = groups[gi];\n        if (g == 1) continue;\n        if (g == 2) {\n            allEdges[gi].push_back({grp[0], grp[1]});\n            continue;\n        }\n        allEdges[gi] = buildMST(g, grp, edgeSets[gi]);\n    }\n    \n    cout << \"!\\n\";\n    for (int gi = 0; gi < M; gi++) {\n        for (int i = 0; i < (int)groups[gi].size(); i++) {\n            cout << groups[gi][i];\n            if (i+1 < (int)groups[gi].size()) cout << \" \";\n        }\n        cout << \"\\n\";\n        for (auto& p : allEdges[gi]) cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint di[4]={-1,1,0,0}, dj[4]={0,0,-1,1};\nchar dch[4]={'U','D','L','R'};\nvector<vector<bool>> blk;\n\npair<int,int> slideEnd(int i,int j,int d){\n    while(true){\n        int ni=i+di[d],nj=j+dj[d];\n        if(ni<0||ni>=N||nj<0||nj>=N||blk[ni][nj])break;\n        i=ni;j=nj;\n    }\n    return {i,j};\n}\n\nint main(){\n    cin>>N>>M;\n    vector<pair<int,int>> pts(M);\n    for(auto&p:pts)cin>>p.first>>p.second;\n    blk.assign(N,vector<bool>(N,false));\n    vector<string> out;\n    int ci=pts[0].first, cj=pts[0].second;\n    \n    for(int t=1;t<M;t++){\n        int ti=pts[t].first, tj=pts[t].second;\n        vector<vector<int>> dist(N,vector<int>(N,INT_MAX));\n        vector<vector<tuple<int,int,string>>> par(N,vector<tuple<int,int,string>>(N));\n        dist[ci][cj]=0;\n        queue<pair<int,int>> q;\n        q.push({ci,cj});\n        while(!q.empty()){\n            auto [i,j]=q.front();q.pop();\n            int c=dist[i][j];\n            for(int d=0;d<4;d++){\n                int ni=i+di[d],nj=j+dj[d];\n                if(ni>=0&&ni<N&&nj>=0&&nj<N&&!blk[ni][nj]){\n                    if(c+1<dist[ni][nj]){\n                        dist[ni][nj]=c+1;\n                        par[ni][nj]={i,j,string(\"M\")+dch[d]};\n                        q.push({ni,nj});\n                    }\n                }\n                auto [si,sj]=slideEnd(i,j,d);\n                if((si!=i||sj!=j)&&c+1<dist[si][sj]){\n                    dist[si][sj]=c+1;\n                    par[si][sj]={i,j,string(\"S\")+dch[d]};\n                    q.push({si,sj});\n                }\n            }\n        }\n        if(dist[ti][tj]==INT_MAX)break;\n        vector<string> acts;\n        int ii=ti,jj=tj;\n        while(ii!=ci||jj!=cj){\n            auto[pi,pj,a]=par[ii][jj];\n            acts.push_back(a);\n            ii=pi;jj=pj;\n        }\n        reverse(acts.begin(),acts.end());\n        for(auto&a:acts)out.push_back(a);\n        ci=ti;cj=tj;\n    }\n    for(auto&s:out)cout<<s[0]<<\" \"<<s[1]<<\"\\n\";\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> X, Y, R;\nstruct Rect { int a, b, c, d; };\nvector<Rect> rects;\nconst int W = 10000;\n\ninline double score_one_of(int i, const Rect& r) {\n    if (X[i] < r.a || X[i] >= r.c || Y[i] < r.b || Y[i] >= r.d) return 0;\n    long long s = (long long)(r.c - r.a) * (r.d - r.b);\n    double mn = min((long long)R[i], s);\n    double mx = max((long long)R[i], s);\n    double t = 1.0 - mn/mx;\n    return 1.0 - t*t;\n}\n\nint main() {\n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    rects.resize(n);\n    for (int i = 0; i < n; i++) {\n        cin >> X[i] >> Y[i] >> R[i];\n        rects[i] = {X[i], Y[i], X[i]+1, Y[i]+1};\n    }\n    \n    auto start = chrono::steady_clock::now();\n    auto elapsed = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - start).count();\n    };\n    \n    mt19937 rng(42);\n    auto randd = [&]() { return (rng() & 0xffffff) / (double)0x1000000; };\n    \n    const double TIME_LIMIT = 4.8;\n    const double FINAL_LIMIT = 4.95;\n    \n    double T_start = 0.005;\n    double T_end = 0.00005;\n    \n    long long iters = 0;\n    double T = T_start;\n    double e = 0;\n    \n    while (true) {\n        if ((iters & 2047) == 0) {\n            e = elapsed();\n            if (e > TIME_LIMIT) break;\n            double progress = e / TIME_LIMIT;\n            T = T_start * pow(T_end / T_start, progress);\n        }\n        iters++;\n        \n        int i = rng() % n;\n        Rect& r = rects[i];\n        double old_sc = score_one_of(i, r);\n        long long curS = (long long)(r.c - r.a) * (r.d - r.b);\n        \n        // 10% chance to do a shift move, otherwise standard grow/shrink\n        int moveType = rng() % 100;\n        Rect saved = r;\n        \n        if (moveType < 10) {\n            // Shift move: expand one side and shrink opposite by same amount\n            int dir = rng() % 4;\n            int amt = 1 + rng() % 30;\n            if (dir == 0) { // shift left\n                r.a -= amt; r.c -= amt;\n                if (r.a < 0) { r.a = 0; r.c = saved.c - (saved.a - r.a); }\n            } else if (dir == 1) { // shift right\n                r.a += amt; r.c += amt;\n                if (r.c > W) { r.c = W; r.a = saved.a + (saved.c - r.c); }\n            } else if (dir == 2) { // shift down\n                r.b -= amt; r.d -= amt;\n                if (r.b < 0) { r.b = 0; r.d = saved.d - (saved.b - r.b); }\n            } else { // shift up\n                r.b += amt; r.d += amt;\n                if (r.d > W) { r.d = W; r.b = saved.b + (saved.d - r.d); }\n            }\n            if (r.a < 0 || r.b < 0 || r.c > W || r.d > W || r.a >= r.c || r.b >= r.d) { r = saved; continue; }\n            if (X[i] < r.a || X[i] >= r.c || Y[i] < r.b || Y[i] >= r.d) { r = saved; continue; }\n            \n            bool bad = false;\n            for (int j = 0; j < n; j++) {\n                if (j == i) continue;\n                const Rect& rj = rects[j];\n                if (r.c <= rj.a || rj.c <= r.a || r.d <= rj.b || rj.d <= r.b) continue;\n                bad = true; break;\n            }\n            if (bad) { r = saved; continue; }\n            // Score unchanged, accept. (but may enable future good moves)\n            continue;\n        }\n        \n        int move = rng() % 8;\n        bool expand = move < 4;\n        \n        int amt;\n        long long diff = expand ? max(0LL, (long long)R[i] - curS) : max(0LL, curS - (long long)R[i]);\n        \n        int rn = rng() % 100;\n        if (rn < 40 && diff > 0) {\n            int side;\n            if (move == 0 || move == 1 || move == 4 || move == 5) side = r.d - r.b;\n            else side = r.c - r.a;\n            if (side == 0) side = 1;\n            amt = max(1, (int)(diff / side));\n            amt = max(1, amt + (int)(rng() % 5) - 2);\n        } else if (rn < 80) {\n            amt = 1 + rng() % 20;\n        } else {\n            amt = 1 + rng() % 200;\n        }\n        \n        if (move == 0) { r.a -= amt; if (r.a < 0) r.a = 0; }\n        else if (move == 1) { r.c += amt; if (r.c > W) r.c = W; }\n        else if (move == 2) { r.b -= amt; if (r.b < 0) r.b = 0; }\n        else if (move == 3) { r.d += amt; if (r.d > W) r.d = W; }\n        else if (move == 4) { r.a += amt; if (r.a > X[i]) r.a = X[i]; }\n        else if (move == 5) { r.c -= amt; if (r.c < X[i]+1) r.c = X[i]+1; }\n        else if (move == 6) { r.b += amt; if (r.b > Y[i]) r.b = Y[i]; }\n        else { r.d -= amt; if (r.d < Y[i]+1) r.d = Y[i]+1; }\n        \n        if (saved.a == r.a && saved.b == r.b && saved.c == r.c && saved.d == r.d) continue;\n        \n        if (expand) {\n            bool bad = false;\n            for (int j = 0; j < n; j++) {\n                if (j == i) continue;\n                const Rect& rj = rects[j];\n                if (r.c <= rj.a || rj.c <= r.a || r.d <= rj.b || rj.d <= r.b) continue;\n                bad = true; break;\n            }\n            if (bad) { r = saved; continue; }\n        }\n        \n        double new_sc = score_one_of(i, r);\n        double delta = new_sc - old_sc;\n        \n        if (delta >= 0) {\n            // accept\n        } else {\n            double p = exp(delta / T);\n            if (randd() >= p) { r = saved; continue; }\n        }\n    }\n    \n    // Final hill-climbing\n    while (elapsed() < FINAL_LIMIT) {\n        int i = rng() % n;\n        Rect& r = rects[i];\n        double old_sc = score_one_of(i, r);\n        long long curS = (long long)(r.c - r.a) * (r.d - r.b);\n        \n        int move = rng() % 8;\n        Rect saved = r;\n        bool expand = move < 4;\n        int amt;\n        long long diff = expand ? max(0LL, (long long)R[i] - curS) : max(0LL, curS - (long long)R[i]);\n        int rn = rng() % 100;\n        if (rn < 50 && diff > 0) {\n            int side;\n            if (move == 0 || move == 1 || move == 4 || move == 5) side = r.d - r.b;\n            else side = r.c - r.a;\n            if (side == 0) side = 1;\n            amt = max(1, (int)(diff / side));\n        } else {\n            amt = 1 + rng() % 30;\n        }\n        \n        if (move == 0) { r.a -= amt; if (r.a < 0) r.a = 0; }\n        else if (move == 1) { r.c += amt; if (r.c > W) r.c = W; }\n        else if (move == 2) { r.b -= amt; if (r.b < 0) r.b = 0; }\n        else if (move == 3) { r.d += amt; if (r.d > W) r.d = W; }\n        else if (move == 4) { r.a += amt; if (r.a > X[i]) r.a = X[i]; }\n        else if (move == 5) { r.c -= amt; if (r.c < X[i]+1) r.c = X[i]+1; }\n        else if (move == 6) { r.b += amt; if (r.b > Y[i]) r.b = Y[i]; }\n        else { r.d -= amt; if (r.d < Y[i]+1) r.d = Y[i]+1; }\n        \n        if (saved.a == r.a && saved.b == r.b && saved.c == r.c && saved.d == r.d) continue;\n        \n        if (expand) {\n            bool bad = false;\n            for (int j = 0; j < n; j++) {\n                if (j == i) continue;\n                const Rect& rj = rects[j];\n                if (r.c <= rj.a || rj.c <= r.a || r.d <= rj.b || rj.d <= r.b) continue;\n                bad = true; break;\n            }\n            if (bad) { r = saved; continue; }\n        }\n        \n        double new_sc = score_one_of(i, r);\n        if (new_sc < old_sc - 1e-12) { r = saved; }\n    }\n    \n    for (int i = 0; i < n; i++) {\n        cout << rects[i].a << \" \" << rects[i].b << \" \" << rects[i].c << \" \" << rects[i].d << \"\\n\";\n    }\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nconst int N = 50;\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dch[] = {'U', 'D', 'L', 'R'};\n\ndouble getTime() {\n    return (double)clock() / CLOCKS_PER_SEC;\n}\n\nmt19937 rng(42);\n\nvector<pair<int,int>> path;\nvector<int> dirs;\nvector<bool> usedTile;\nint totalScore;\nint M;\n\nint targetR, targetC;\nint bestSegScore;\nvector<int> bestSegDirs;\nvector<int> curSegDirs;\nint curSegScore;\ndouble dfsDeadline;\nbool timeUp;\nint dfsCount;\nint maxDepth;\n\nvoid dfsSeg(int r, int c, int depth) {\n    dfsCount++;\n    if ((dfsCount & 4095) == 0) {\n        if (getTime() > dfsDeadline) { timeUp = true; return; }\n    }\n    if (timeUp) return;\n    \n    if (r == targetR && c == targetC) {\n        if (curSegScore > bestSegScore) {\n            bestSegScore = curSegScore;\n            bestSegDirs = curSegDirs;\n        }\n        return;\n    }\n    \n    if (depth >= maxDepth) return;\n    int md = abs(r - targetR) + abs(c - targetC);\n    if (depth + md > maxDepth) return;\n    \n    int order[4] = {0,1,2,3};\n    for (int k = 3; k > 0; k--) {\n        int j = rng() % (k+1);\n        int tmp = order[k]; order[k] = order[j]; order[j] = tmp;\n    }\n    for (int k = 0; k < 4; k++) {\n        int d = order[k];\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = t[nr][nc];\n        if (usedTile[tid]) continue;\n        usedTile[tid] = true;\n        curSegScore += p[nr][nc];\n        curSegDirs.push_back(d);\n        dfsSeg(nr, nc, depth+1);\n        curSegDirs.pop_back();\n        curSegScore -= p[nr][nc];\n        usedTile[tid] = false;\n        if (timeUp) return;\n    }\n}\n\nint bestTailScore;\nvector<int> bestTailDirs;\nvector<int> curTailDirs;\nint curTailScore;\n\nvoid dfsTail(int r, int c) {\n    dfsCount++;\n    if ((dfsCount & 4095) == 0) {\n        if (getTime() > dfsDeadline) { timeUp = true; return; }\n    }\n    if (timeUp) return;\n    \n    if (curTailScore > bestTailScore) {\n        bestTailScore = curTailScore;\n        bestTailDirs = curTailDirs;\n    }\n    \n    int order[4] = {0,1,2,3};\n    for (int k = 3; k > 0; k--) {\n        int j = rng() % (k+1);\n        int tmp = order[k]; order[k] = order[j]; order[j] = tmp;\n    }\n    for (int k = 0; k < 4; k++) {\n        int d = order[k];\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        int tid = t[nr][nc];\n        if (usedTile[tid]) continue;\n        usedTile[tid] = true;\n        curTailScore += p[nr][nc];\n        curTailDirs.push_back(d);\n        dfsTail(nr, nc);\n        curTailDirs.pop_back();\n        curTailScore -= p[nr][nc];\n        usedTile[tid] = false;\n        if (timeUp) return;\n    }\n}\n\nvoid rebuildUsedTiles() {\n    fill(usedTile.begin(), usedTile.end(), false);\n    for (auto& pp : path) usedTile[t[pp.first][pp.second]] = true;\n}\n\nbool validatePath() {\n    if (path.empty()) return false;\n    if (path[0].first != si || path[0].second != sj) return false;\n    if (path.size() != dirs.size() + 1) return false;\n    vector<bool> seen(M, false);\n    for (int k = 0; k < (int)path.size(); k++) {\n        int r = path[k].first, c = path[k].second;\n        if (r < 0 || r >= N || c < 0 || c >= N) return false;\n        if (seen[t[r][c]]) return false;\n        seen[t[r][c]] = true;\n        if (k > 0) {\n            int d = dirs[k-1];\n            int er = path[k-1].first + dr[d];\n            int ec = path[k-1].second + dc[d];\n            if (er != r || ec != c) return false;\n        }\n    }\n    return true;\n}\n\nvoid initialPath() {\n    path.clear();\n    dirs.clear();\n    fill(usedTile.begin(), usedTile.end(), false);\n    path.push_back({si, sj});\n    usedTile[t[si][sj]] = true;\n    totalScore = p[si][sj];\n    \n    int r = si, c = sj;\n    while (true) {\n        int cand[4], ncand = 0;\n        for (int d = 0; d < 4; d++) {\n            int nr = r+dr[d], nc = c+dc[d];\n            if (nr<0||nr>=N||nc<0||nc>=N) continue;\n            if (usedTile[t[nr][nc]]) continue;\n            cand[ncand++] = d;\n        }\n        if (ncand == 0) break;\n        int d = cand[rng()%ncand];\n        int nr = r+dr[d], nc = c+dc[d];\n        usedTile[t[nr][nc]] = true;\n        totalScore += p[nr][nc];\n        path.push_back({nr,nc});\n        dirs.push_back(d);\n        r = nr; c = nc;\n    }\n}\n\nint main() {\n    cin >> si >> sj;\n    M = 0;\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) {\n            cin >> t[i][j];\n            M = max(M, t[i][j]+1);\n        }\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++)\n            cin >> p[i][j];\n    \n    usedTile.assign(M, false);\n    \n    vector<pair<int,int>> bestPath;\n    vector<int> bestDirs;\n    int bestOverallScore = -1;\n    \n    double INIT_TIME = 0.03;\n    double initStart = getTime();\n    while (getTime() - initStart < INIT_TIME) {\n        initialPath();\n        if (totalScore > bestOverallScore) {\n            bestOverallScore = totalScore;\n            bestPath = path;\n            bestDirs = dirs;\n        }\n    }\n    \n    path = bestPath;\n    dirs = bestDirs;\n    totalScore = bestOverallScore;\n    rebuildUsedTiles();\n    \n    vector<pair<int,int>> savedPath = path;\n    vector<int> savedDirs = dirs;\n    int savedScore = totalScore;\n    \n    double TIME_LIMIT = 1.80;\n    double TIME_START = getTime();\n    int iter = 0;\n    \n    uniform_real_distribution<double> uni(0.0, 1.0);\n    \n    while (getTime() < TIME_LIMIT) {\n        iter++;\n        int L = path.size();\n        \n        double elapsed = (getTime() - TIME_START) / (TIME_LIMIT - TIME_START);\n        double T = 8.0 * (1.0 - elapsed);\n        if (T < 0.01) T = 0.01;\n        \n        int mode = rng() % 10;\n        \n        if (mode < 2) {\n            int i = rng() % L;\n            \n            int oldSuffixScore = 0;\n            for (int k = i+1; k < L; k++) oldSuffixScore += p[path[k].first][path[k].second];\n            \n            for (int k = i+1; k < L; k++) {\n                usedTile[t[path[k].first][path[k].second]] = false;\n            }\n            usedTile[t[path[i].first][path[i].second]] = true;\n            \n            bestTailScore = 0;\n            bestTailDirs.clear();\n            curTailScore = 0;\n            curTailDirs.clear();\n            timeUp = false;\n            dfsCount = 0;\n            \n            double remaining = TIME_LIMIT - getTime();\n            double budget = min(0.015, remaining * 0.015);\n            if (budget < 0.001) budget = 0.001;\n            dfsDeadline = getTime() + budget;\n            \n            dfsTail(path[i].first, path[i].second);\n            \n            int delta = bestTailScore - oldSuffixScore;\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else if (uni(rng) < exp((double)delta / T)) accept = true;\n            \n            if (accept) {\n                path.resize(i+1);\n                dirs.resize(i);\n                int r = path[i].first, c = path[i].second;\n                for (int d : bestTailDirs) {\n                    int nr = r+dr[d], nc = c+dc[d];\n                    path.push_back({nr,nc});\n                    dirs.push_back(d);\n                    usedTile[t[nr][nc]] = true;\n                    r = nr; c = nc;\n                }\n                totalScore = totalScore - oldSuffixScore + bestTailScore;\n            } else {\n                for (int k = i+1; k < L; k++) {\n                    usedTile[t[path[k].first][path[k].second]] = true;\n                }\n            }\n        } else {\n            int i = rng() % L;\n            int len;\n            int r_mode = rng() % 10;\n            if (r_mode < 5) len = 3 + rng() % 12;\n            else if (r_mode < 8) len = 8 + rng() % 25;\n            else len = 20 + rng() % 60;\n            \n            int j = min(L-1, i + len);\n            if (j - i < 2) continue;\n            \n            int tj = t[path[j].first][path[j].second];\n            if (j+1 < L && t[path[j+1].first][path[j+1].second] == tj) continue;\n            \n            int oldSegScore = 0;\n            for (int k = i+1; k <= j; k++) oldSegScore += p[path[k].first][path[k].second];\n            \n            for (int k = i+1; k <= j; k++) {\n                usedTile[t[path[k].first][path[k].second]] = false;\n            }\n            usedTile[t[path[i].first][path[i].second]] = true;\n            \n            targetR = path[j].first;\n            targetC = path[j].second;\n            \n            bestSegScore = -1;\n            bestSegDirs.clear();\n            curSegScore = 0;\n            curSegDirs.clear();\n            timeUp = false;\n            dfsCount = 0;\n            int baseLen = j - i;\n            maxDepth = baseLen + min(20, baseLen);\n            \n            double remaining = TIME_LIMIT - getTime();\n            double budget;\n            if (baseLen < 15) budget = 0.003;\n            else if (baseLen < 30) budget = 0.008;\n            else budget = 0.015;\n            budget = min(budget, remaining * 0.01);\n            if (budget < 0.0003) budget = 0.0003;\n            dfsDeadline = getTime() + budget;\n            \n            dfsSeg(path[i].first, path[i].second, 0);\n            \n            int delta = bestSegScore - oldSegScore;\n            bool accept = false;\n            if (bestSegScore >= 0 && !bestSegDirs.empty()) {\n                if (delta >= 0) accept = true;\n                else if (uni(rng) < exp((double)delta / T)) accept = true;\n            }\n            \n            if (accept) {\n                vector<pair<int,int>> newSeg;\n                {\n                    int r = path[i].first, c = path[i].second;\n                    for (int d : bestSegDirs) {\n                        int nr = r+dr[d], nc = c+dc[d];\n                        newSeg.push_back({nr, nc});\n                        r = nr; c = nc;\n                    }\n                }\n                \n                for (auto& pp : newSeg) usedTile[t[pp.first][pp.second]] = true;\n                \n                vector<pair<int,int>> newPath;\n                newPath.reserve(path.size() + newSeg.size());\n                vector<int> newDirs;\n                newDirs.reserve(dirs.size() + bestSegDirs.size());\n                for (int k = 0; k <= i; k++) newPath.push_back(path[k]);\n                for (int k = 0; k < i; k++) newDirs.push_back(dirs[k]);\n                for (int d : bestSegDirs) newDirs.push_back(d);\n                for (auto& pp : newSeg) newPath.push_back(pp);\n                for (int k = j+1; k < L; k++) newPath.push_back(path[k]);\n                for (int k = j; k < (int)dirs.size(); k++) newDirs.push_back(dirs[k]);\n                \n                path = std::move(newPath);\n                dirs = std::move(newDirs);\n                totalScore = totalScore - oldSegScore + bestSegScore;\n            } else {\n                for (int k = i+1; k <= j; k++) {\n                    usedTile[t[path[k].first][path[k].second]] = true;\n                }\n            }\n        }\n        \n        if (totalScore > bestOverallScore) {\n            bestOverallScore = totalScore;\n            bestPath = path;\n            bestDirs = dirs;\n        }\n        \n        if ((iter & 255) == 0) {\n            if (validatePath()) {\n                savedPath = path;\n                savedDirs = dirs;\n                savedScore = totalScore;\n            } else {\n                path = savedPath;\n                dirs = savedDirs;\n                totalScore = savedScore;\n                rebuildUsedTiles();\n            }\n        }\n    }\n    \n    string out;\n    for (int d : bestDirs) out += dch[d];\n    cout << out << endl;\n    \n    cerr << \"Score: \" << bestOverallScore << \" Iter: \" << iter << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\ndouble h[30][29];\ndouble v[29][30];\n\nstruct Obs {\n    vector<tuple<int,int,int>> edges;\n    double observed;\n};\n\nvector<Obs> history;\n\nvoid gs_update(const Obs& o, double alpha) {\n    double pred = 0;\n    for (auto& [t,i,j] : o.edges) {\n        if (t == 0) pred += h[i][j]; else pred += v[i][j];\n    }\n    int n = (int)o.edges.size();\n    if (n == 0) return;\n    double err = (o.observed - pred) / n;\n    double delta = alpha * err;\n    for (auto& [t,i,j] : o.edges) {\n        if (t == 0) {\n            h[i][j] += delta;\n            if (h[i][j] < 1000) h[i][j] = 1000;\n            if (h[i][j] > 9000) h[i][j] = 9000;\n        } else {\n            v[i][j] += delta;\n            if (v[i][j] < 1000) v[i][j] = 1000;\n            if (v[i][j] > 9000) v[i][j] = 9000;\n        }\n    }\n}\n\nstatic double h_delta[30][29], v_delta[29][30], h_wt[30][29], v_wt[29][30];\n\nvoid smooth_update(const Obs& o, double alpha, double sigma) {\n    double pred = 0;\n    for (auto& [t,i,j] : o.edges) {\n        if (t == 0) pred += h[i][j]; else pred += v[i][j];\n    }\n    if (pred < 1) return;\n    double rd = o.observed / pred - 1.0;\n    if (rd > 0.5) rd = 0.5;\n    if (rd < -0.4) rd = -0.4;\n    \n    memset(h_delta, 0, sizeof(h_delta));\n    memset(v_delta, 0, sizeof(v_delta));\n    memset(h_wt, 0, sizeof(h_wt));\n    memset(v_wt, 0, sizeof(v_wt));\n    \n    double inv2s2 = 1.0 / (2*sigma*sigma);\n    for (auto& [t,ei,ej] : o.edges) {\n        if (t == 0) {\n            for (int jj = 0; jj < 29; jj++) {\n                double d = jj - ej;\n                double w = exp(-d*d*inv2s2);\n                h_delta[ei][jj] += w * rd;\n                h_wt[ei][jj] += w;\n            }\n        } else {\n            for (int ii = 0; ii < 29; ii++) {\n                double d = ii - ei;\n                double w = exp(-d*d*inv2s2);\n                v_delta[ii][ej] += w * rd;\n                v_wt[ii][ej] += w;\n            }\n        }\n    }\n    \n    for (int i = 0; i < 30; i++) for (int j = 0; j < 29; j++) {\n        if (h_wt[i][j] > 0) {\n            double a = h_delta[i][j]/h_wt[i][j];\n            h[i][j] *= (1.0 + alpha * a);\n            if (h[i][j] < 1000) h[i][j] = 1000;\n            if (h[i][j] > 9000) h[i][j] = 9000;\n        }\n    }\n    for (int i = 0; i < 29; i++) for (int j = 0; j < 30; j++) {\n        if (v_wt[i][j] > 0) {\n            double a = v_delta[i][j]/v_wt[i][j];\n            v[i][j] *= (1.0 + alpha * a);\n            if (v[i][j] < 1000) v[i][j] = 1000;\n            if (v[i][j] > 9000) v[i][j] = 9000;\n        }\n    }\n}\n\nint main() {\n    for (int i = 0; i < 30; i++) for (int j = 0; j < 29; j++) h[i][j] = 5000;\n    for (int i = 0; i < 29; i++) for (int j = 0; j < 30; j++) v[i][j] = 5000;\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n        \n        vector<vector<double>> dist(30, vector<double>(30, 1e18));\n        vector<vector<int>> prv(30, vector<int>(30, -1));\n        priority_queue<tuple<double,int,int>, vector<tuple<double,int,int>>, greater<>> pq;\n        dist[si][sj] = 0;\n        pq.push({0.0, si, sj});\n        int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};\n        while (!pq.empty()) {\n            auto [d, r, c] = pq.top(); pq.pop();\n            if (d > dist[r][c]) continue;\n            for (int dir = 0; dir < 4; dir++) {\n                int nr = r+dr[dir], nc = c+dc[dir];\n                if (nr<0||nr>=30||nc<0||nc>=30) continue;\n                double w;\n                if (dir == 0) w = v[nr][c];\n                else if (dir == 1) w = v[r][c];\n                else if (dir == 2) w = h[r][nc];\n                else w = h[r][c];\n                if (dist[nr][nc] > d + w) {\n                    dist[nr][nc] = d + w;\n                    prv[nr][nc] = dir;\n                    pq.push({dist[nr][nc], nr, nc});\n                }\n            }\n        }\n        \n        vector<int> dirs;\n        int r = ti, c = tj;\n        while (!(r == si && c == sj)) {\n            int d = prv[r][c];\n            dirs.push_back(d);\n            r -= dr[d]; c -= dc[d];\n        }\n        reverse(dirs.begin(), dirs.end());\n        \n        string path;\n        char ch[] = {'U','D','L','R'};\n        for (int d : dirs) path += ch[d];\n        cout << path << endl;\n        cout.flush();\n        \n        long long b;\n        cin >> b;\n        \n        vector<tuple<int,int,int>> edges;\n        r = si; c = sj;\n        for (int d : dirs) {\n            int nr = r+dr[d], nc = c+dc[d];\n            if (d == 0) edges.push_back({1, nr, c});\n            else if (d == 1) edges.push_back({1, r, c});\n            else if (d == 2) edges.push_back({0, r, nc});\n            else edges.push_back({0, r, c});\n            r = nr; c = nc;\n        }\n        \n        history.push_back({edges, (double)b});\n        int N = (int)history.size();\n        \n        // Strong structural smoothing for new observation\n        smooth_update(history.back(), 0.15, 5.0);\n        \n        // Weak Gauss-Seidel over all history \u2014 handles M=2 without overfitting noise\n        for (int rep = 0; rep < 2; rep++) {\n            for (int idx = 0; idx < N; idx++) {\n                gs_update(history[idx], 0.1);\n            }\n        }\n        \n        // Additional smoothing reinforcement on recent observations\n        int sm_n = min(N, 50);\n        for (int rep = 0; rep < 2; rep++) {\n            for (int idx = N - sm_n; idx < N; idx++) {\n                smooth_update(history[idx], 0.03, 5.0);\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\nusing Clock = chrono::steady_clock;\n\nint N = 20;\nint M;\nvector<string> S;\nmt19937 rng(42);\n\nint ovlp(const string& a, const string& b) {\n    int m = min((int)a.size(), (int)b.size());\n    for (int k = m; k >= 1; k--) {\n        if (a.compare(a.size()-k, k, b, 0, k) == 0) return k;\n    }\n    return 0;\n}\n\nstruct AC {\n    struct Node {\n        int ch[9];\n        int fail;\n        vector<int> out;\n        Node() { for (int i = 0; i < 9; i++) ch[i] = -1; fail = 0; }\n    };\n    vector<Node> nd;\n    \n    void init() { nd.clear(); nd.push_back(Node()); }\n    int ci(char c) { return c == '.' ? 8 : c - 'A'; }\n    \n    void add(const string& p, int id) {\n        int cur = 0;\n        for (char c : p) {\n            int x = ci(c);\n            if (nd[cur].ch[x] == -1) { nd[cur].ch[x] = nd.size(); nd.push_back(Node()); }\n            cur = nd[cur].ch[x];\n        }\n        nd[cur].out.push_back(id);\n    }\n    \n    void build() {\n        queue<int> q;\n        nd[0].fail = 0;\n        for (int c = 0; c < 9; c++) {\n            if (nd[0].ch[c] == -1) nd[0].ch[c] = 0;\n            else { nd[nd[0].ch[c]].fail = 0; q.push(nd[0].ch[c]); }\n        }\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int c = 0; c < 9; c++) {\n                int v = nd[u].ch[c];\n                if (v == -1) nd[u].ch[c] = nd[nd[u].fail].ch[c];\n                else {\n                    nd[v].fail = nd[nd[u].fail].ch[c];\n                    for (int p : nd[nd[v].fail].out) nd[v].out.push_back(p);\n                    q.push(v);\n                }\n            }\n        }\n    }\n};\n\nAC ac;\n\nvector<string> makeTracks(const vector<string>& grid) {\n    vector<string> tracks(2*N);\n    for (int r = 0; r < N; r++) tracks[r] = grid[r] + grid[r].substr(0, 11);\n    for (int c = 0; c < N; c++) {\n        string col(N, '.');\n        for (int r = 0; r < N; r++) col[r] = grid[r][c];\n        tracks[N+c] = col + col.substr(0, 11);\n    }\n    return tracks;\n}\n\nint countMatches(const vector<string>& grid, const vector<int>& avail) {\n    auto tracks = makeTracks(grid);\n    int cnt = 0;\n    for (int i : avail) {\n        for (auto& t : tracks) {\n            if (t.find(S[i]) != string::npos) { cnt++; break; }\n        }\n    }\n    return cnt;\n}\n\nint tryPlace(vector<string>& grid, const string& s, int r, int c, int dir, bool doIt) {\n    int L = s.size();\n    int cost = 0;\n    for (int p = 0; p < L; p++) {\n        int rr, cc;\n        if (dir == 0) { rr = r; cc = (c+p) % N; }\n        else { rr = (r+p) % N; cc = c; }\n        if (grid[rr][cc] == '.') cost++;\n        else if (grid[rr][cc] != s[p]) return -1;\n    }\n    if (doIt) {\n        for (int p = 0; p < L; p++) {\n            int rr, cc;\n            if (dir == 0) { rr = r; cc = (c+p) % N; }\n            else { rr = (r+p) % N; cc = c; }\n            grid[rr][cc] = s[p];\n        }\n    }\n    return cost;\n}\n\nvoid updateCovered(vector<string>& grid, const vector<int>& avail, vector<bool>& placed) {\n    auto tracks = makeTracks(grid);\n    for (int i : avail) {\n        if (placed[i]) continue;\n        for (auto& t : tracks) {\n            if (t.find(S[i]) != string::npos) { placed[i] = true; break; }\n        }\n    }\n}\n\nvector<string> greedyBuild(const vector<int>& avail, const vector<bool>& redundant) {\n    vector<bool> used(M, false);\n    for (int i = 0; i < M; i++) if (redundant[i]) used[i] = true;\n    \n    vector<string> grid(N, string(N, '.'));\n    vector<int> order = avail;\n    shuffle(order.begin(), order.end(), rng);\n    \n    for (int r = 0; r < N; r++) {\n        int first = -1, bestLen = -1;\n        for (int i : order) if (!used[i]) {\n            if ((int)S[i].size() > bestLen) { bestLen = S[i].size(); first = i; }\n        }\n        if (first == -1) break;\n        vector<int> topCands;\n        for (int i : order) if (!used[i] && (int)S[i].size() >= bestLen) topCands.push_back(i);\n        if (topCands.empty()) break;\n        first = topCands[rng() % topCands.size()];\n        \n        string row = S[first];\n        used[first] = true;\n        if ((int)row.size() > N) row = row.substr(0, N);\n        \n        while ((int)row.size() < N) {\n            vector<tuple<int,int,int>> cands;\n            for (int i : order) if (!used[i]) {\n                int o = ovlp(row, S[i]);\n                int addLen = (int)S[i].size() - o;\n                if ((int)row.size() + addLen > N) continue;\n                int sc = o * 1000 + (int)S[i].size();\n                cands.push_back({sc, i, o});\n            }\n            if (cands.empty()) break;\n            sort(cands.begin(), cands.end(), greater<>());\n            int topk = min((int)cands.size(), 3);\n            auto [sc, best, o] = cands[rng() % topk];\n            row += S[best].substr(o);\n            used[best] = true;\n        }\n        \n        if ((int)row.size() == N) {\n            string cyc = row + row.substr(0, 11);\n            for (int i : avail) if (!used[i]) {\n                if (cyc.find(S[i]) != string::npos) used[i] = true;\n            }\n        }\n        \n        for (int j = 0; j < (int)row.size() && j < N; j++) grid[r][j] = row[j];\n    }\n    \n    updateCovered(grid, avail, used);\n    \n    vector<int> remaining;\n    for (int i : avail) if (!used[i]) remaining.push_back(i);\n    sort(remaining.begin(), remaining.end(), [](int a, int b){ return S[a].size() > S[b].size(); });\n    \n    for (int i : remaining) {\n        if (used[i]) continue;\n        const string& s = S[i];\n        int bestCost = INT_MAX;\n        int bestR = -1, bestC = -1, bestDir = -1;\n        for (int dir = 0; dir < 2; dir++) {\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    int cost = tryPlace(grid, s, r, c, dir, false);\n                    if (cost >= 0 && cost < bestCost) {\n                        bestCost = cost;\n                        bestR = r; bestC = c; bestDir = dir;\n                    }\n                }\n            }\n        }\n        if (bestR != -1) {\n            tryPlace(grid, s, bestR, bestC, bestDir, true);\n            used[i] = true;\n            updateCovered(grid, avail, used);\n        }\n    }\n    \n    return grid;\n}\n\nClock::time_point startTime;\ndouble timeUsed() { return chrono::duration<double>(Clock::now() - startTime).count(); }\n\nvoid hillClimb(vector<string>& grid, int& cur, const vector<int>& avail, double deadline) {\n    bool improved = true;\n    while (improved && timeUsed() < deadline) {\n        improved = false;\n        \n        for (int r = 0; r < N; r++) {\n            if (timeUsed() > deadline) break;\n            string orig = grid[r];\n            int bestShift = 0, bestSc = cur;\n            for (int sh = 1; sh < N; sh++) {\n                grid[r] = orig.substr(sh) + orig.substr(0, sh);\n                int sc = countMatches(grid, avail);\n                if (sc > bestSc) { bestSc = sc; bestShift = sh; }\n            }\n            grid[r] = orig.substr(bestShift) + orig.substr(0, bestShift);\n            if (bestShift != 0) { cur = bestSc; improved = true; }\n        }\n        \n        for (int c = 0; c < N; c++) {\n            if (timeUsed() > deadline) break;\n            string orig_col(N, '.');\n            for (int r = 0; r < N; r++) orig_col[r] = grid[r][c];\n            int bestShift = 0, bestSc = cur;\n            for (int sh = 1; sh < N; sh++) {\n                string nc = orig_col.substr(sh) + orig_col.substr(0, sh);\n                for (int r = 0; r < N; r++) grid[r][c] = nc[r];\n                int sc = countMatches(grid, avail);\n                if (sc > bestSc) { bestSc = sc; bestShift = sh; }\n            }\n            string nc = orig_col.substr(bestShift) + orig_col.substr(0, bestShift);\n            for (int r = 0; r < N; r++) grid[r][c] = nc[r];\n            if (bestShift != 0) { cur = bestSc; improved = true; }\n        }\n        \n        for (int r1 = 0; r1 < N && timeUsed() < deadline; r1++) {\n            for (int r2 = r1+1; r2 < N; r2++) {\n                swap(grid[r1], grid[r2]);\n                int sc = countMatches(grid, avail);\n                if (sc > cur) { cur = sc; improved = true; }\n                else swap(grid[r1], grid[r2]);\n            }\n        }\n        \n        for (int c1 = 0; c1 < N && timeUsed() < deadline; c1++) {\n            for (int c2 = c1+1; c2 < N; c2++) {\n                for (int r = 0; r < N; r++) swap(grid[r][c1], grid[r][c2]);\n                int sc = countMatches(grid, avail);\n                if (sc > cur) { cur = sc; improved = true; }\n                else for (int r = 0; r < N; r++) swap(grid[r][c1], grid[r][c2]);\n            }\n        }\n    }\n}\n\nbool insertUnmatched(vector<string>& grid, const vector<int>& avail) {\n    auto tracks = makeTracks(grid);\n    vector<bool> matched(M, false);\n    for (int i : avail) {\n        for (auto& t : tracks) {\n            if (t.find(S[i]) != string::npos) { matched[i] = true; break; }\n        }\n    }\n    \n    vector<int> unm;\n    for (int i : avail) if (!matched[i]) unm.push_back(i);\n    sort(unm.begin(), unm.end(), [](int a, int b){ return S[a].size() > S[b].size(); });\n    \n    bool anyPlaced = false;\n    for (int i : unm) {\n        const string& s = S[i];\n        int bestCost = INT_MAX;\n        int bestR = -1, bestC = -1, bestDir = -1;\n        for (int dir = 0; dir < 2; dir++) {\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    int cost = tryPlace(grid, s, r, c, dir, false);\n                    if (cost >= 0 && cost < bestCost) {\n                        bestCost = cost;\n                        bestR = r; bestC = c; bestDir = dir;\n                    }\n                }\n            }\n        }\n        if (bestR != -1) {\n            tryPlace(grid, s, bestR, bestC, bestDir, true);\n            anyPlaced = true;\n        }\n    }\n    return anyPlaced;\n}\n\nstruct State {\n    vector<string> grid;\n    vector<vector<int>> trackMatches;\n    vector<int> matchCount;\n    int totalMatched;\n    \n    vector<bool> seen;\n    vector<int> scratchMatches;\n    \n    void getTrackChars(int t, char* buf) {\n        if (t < N) {\n            for (int i = 0; i < N; i++) buf[i] = grid[t][i];\n        } else {\n            int c = t - N;\n            for (int i = 0; i < N; i++) buf[i] = grid[i][c];\n        }\n        for (int i = 0; i < 11; i++) buf[N+i] = buf[i];\n    }\n    \n    void recomputeTrack(int t) {\n        char buf[32];\n        getTrackChars(t, buf);\n        \n        scratchMatches.clear();\n        int cur = 0;\n        for (int i = 0; i < 31; i++) {\n            int x = buf[i] == '.' ? 8 : buf[i] - 'A';\n            cur = ac.nd[cur].ch[x];\n            for (int p : ac.nd[cur].out) {\n                if (!seen[p]) { seen[p] = true; scratchMatches.push_back(p); }\n            }\n        }\n        for (int p : scratchMatches) seen[p] = false;\n        sort(scratchMatches.begin(), scratchMatches.end());\n        \n        auto& oldM = trackMatches[t];\n        size_t i = 0, j = 0;\n        while (i < oldM.size() || j < scratchMatches.size()) {\n            if (i < oldM.size() && (j >= scratchMatches.size() || oldM[i] < scratchMatches[j])) {\n                int x = oldM[i++];\n                matchCount[x]--;\n                if (matchCount[x] == 0) totalMatched--;\n            } else if (j < scratchMatches.size() && (i >= oldM.size() || scratchMatches[j] < oldM[i])) {\n                int x = scratchMatches[j++];\n                if (matchCount[x] == 0) totalMatched++;\n                matchCount[x]++;\n            } else { i++; j++; }\n        }\n        oldM = scratchMatches;\n    }\n    \n    void init(const vector<string>& g) {\n        grid = g;\n        trackMatches.assign(2*N, vector<int>());\n        matchCount.assign(M, 0);\n        seen.assign(M, false);\n        totalMatched = 0;\n        for (int t = 0; t < 2*N; t++) recomputeTrack(t);\n    }\n};\n\nint main() {\n    cin >> N >> M;\n    S.resize(M);\n    for (auto& s : S) cin >> s;\n    \n    vector<bool> redundant(M, false);\n    vector<int> idxSort(M);\n    iota(idxSort.begin(), idxSort.end(), 0);\n    sort(idxSort.begin(), idxSort.end(), [](int a, int b){ return S[a].size() > S[b].size(); });\n    \n    for (int ii = 0; ii < M; ii++) {\n        int i = idxSort[ii];\n        if (redundant[i]) continue;\n        for (int jj = ii+1; jj < M; jj++) {\n            int j = idxSort[jj];\n            if (redundant[j]) continue;\n            if (S[i].find(S[j]) != string::npos) redundant[j] = true;\n        }\n    }\n    \n    vector<int> avail;\n    for (int i = 0; i < M; i++) if (!redundant[i]) avail.push_back(i);\n    \n    ac.init();\n    for (int i : avail) ac.add(S[i], i);\n    ac.build();\n    \n    startTime = Clock::now();\n    \n    vector<string> bestGrid(N, string(N, '.'));\n    int bestScore = -1;\n    int bestDots = -1;\n    \n    int trial = 0;\n    while (timeUsed() < 0.4) {\n        trial++;\n        vector<string> grid = greedyBuild(avail, redundant);\n        int score = countMatches(grid, avail);\n        int dots = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] == '.') dots++;\n        \n        if (score > bestScore || (score == bestScore && dots > bestDots)) {\n            bestScore = score;\n            bestDots = dots;\n            bestGrid = grid;\n        }\n    }\n    cerr << \"Phase 1 trials: \" << trial << \" best: \" << bestScore << \"/\" << avail.size() << \"\\n\";\n    \n    {\n        vector<string> grid = bestGrid;\n        int cur = bestScore;\n        \n        for (int iter = 0; iter < 3; iter++) {\n            if (timeUsed() > 0.8) break;\n            int before = cur;\n            hillClimb(grid, cur, avail, min(0.8, timeUsed() + 0.2));\n            bool placed = insertUnmatched(grid, avail);\n            cur = countMatches(grid, avail);\n            if (!placed && cur <= before) break;\n        }\n        \n        int dots = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] == '.') dots++;\n        if (cur > bestScore || (cur == bestScore && dots > bestDots)) {\n            bestScore = cur;\n            bestDots = dots;\n            bestGrid = grid;\n        }\n        cerr << \"After Phase 2: \" << cur << \"/\" << avail.size() << \"\\n\";\n    }\n    \n    {\n        State state;\n        state.init(bestGrid);\n        \n        int bestCur = state.totalMatched;\n        vector<string> savedBest = state.grid;\n        \n        cerr << \"Start SA: \" << state.totalMatched << \"\\n\";\n        \n        double tStart = timeUsed();\n        double tEnd = 2.75;\n        double tempStart = 3.0;\n        double tempEnd = 0.05;\n        \n        int iter = 0, accepted = 0, improvements = 0;\n        \n        int changeR[16], changeC[16];\n        char changeOld[16];\n        \n        while (timeUsed() < tEnd) {\n            iter++;\n            double progress = (timeUsed() - tStart) / (tEnd - tStart);\n            if (progress > 1) progress = 1;\n            double temp = tempStart * pow(tempEnd/tempStart, progress);\n            \n            int moveType = rng() % 10;\n            \n            if (moveType == 0) {\n                int r = rng() % N;\n                int c = rng() % N;\n                char oldCh = state.grid[r][c];\n                char newCh;\n                if (rng() % 10 == 0) newCh = '.';\n                else newCh = 'A' + (rng() % 8);\n                if (newCh == oldCh) continue;\n                \n                int before = state.totalMatched;\n                state.grid[r][c] = newCh;\n                state.recomputeTrack(r);\n                state.recomputeTrack(N + c);\n                int delta = state.totalMatched - before;\n                \n                bool accept = delta >= 0 || (rng() / (double)rng.max()) < exp(delta / temp);\n                if (!accept) {\n                    state.grid[r][c] = oldCh;\n                    state.recomputeTrack(r);\n                    state.recomputeTrack(N + c);\n                } else {\n                    accepted++;\n                    if (state.totalMatched > bestCur) {\n                        bestCur = state.totalMatched;\n                        savedBest = state.grid;\n                        improvements++;\n                    }\n                }\n            } else {\n                int i;\n                if (moveType <= 6) {\n                    int chosen = -1;\n                    for (int t = 0; t < 30; t++) {\n                        int x = avail[rng() % avail.size()];\n                        if (state.matchCount[x] == 0) { chosen = x; break; }\n                    }\n                    if (chosen == -1) chosen = avail[rng() % avail.size()];\n                    i = chosen;\n                } else {\n                    i = avail[rng() % avail.size()];\n                }\n                const string& s = S[i];\n                int L = s.size();\n                int dir = rng() % 2;\n                int rr = rng() % N;\n                int cc = rng() % N;\n                \n                int before = state.totalMatched;\n                int numChanges = 0;\n                uint64_t touchedMask = 0;\n                \n                for (int p = 0; p < L; p++) {\n                    int ar, ac_;\n                    if (dir == 0) { ar = rr; ac_ = (cc+p) % N; }\n                    else { ar = (rr+p) % N; ac_ = cc; }\n                    if (state.grid[ar][ac_] != s[p]) {\n                        changeR[numChanges] = ar;\n                        changeC[numChanges] = ac_;\n                        changeOld[numChanges] = state.grid[ar][ac_];\n                        numChanges++;\n                        state.grid[ar][ac_] = s[p];\n                        touchedMask |= (1ULL << ar);\n                        touchedMask |= (1ULL << (N + ac_));\n                    }\n                }\n                if (numChanges == 0) continue;\n                \n                for (int t = 0; t < 40; t++) {\n                    if (touchedMask & (1ULL << t)) state.recomputeTrack(t);\n                }\n                int delta = state.totalMatched - before;\n                \n                bool accept = delta >= 0 || (rng() / (double)rng.max()) < exp(delta / temp);\n                if (!accept) {\n                    for (int k = 0; k < numChanges; k++) {\n                        state.grid[changeR[k]][changeC[k]] = changeOld[k];\n                    }\n                    for (int t = 0; t < 40; t++) {\n                        if (touchedMask & (1ULL << t)) state.recomputeTrack(t);\n                    }\n                } else {\n                    accepted++;\n                    if (state.totalMatched > bestCur) {\n                        bestCur = state.totalMatched;\n                        savedBest = state.grid;\n                        improvements++;\n                    }\n                }\n            }\n        }\n        \n        cerr << \"SA iters: \" << iter << \" accepted: \" << accepted << \" improvements: \" << improvements << \" bestCur: \" << bestCur << \"\\n\";\n        \n        int dots = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (savedBest[r][c] == '.') dots++;\n        if (bestCur > bestScore || (bestCur == bestScore && dots > bestDots)) {\n            bestScore = bestCur;\n            bestDots = dots;\n            bestGrid = savedBest;\n        }\n    }\n    \n    if (timeUsed() < 2.88) {\n        vector<string> grid = bestGrid;\n        int cur = bestScore;\n        hillClimb(grid, cur, avail, 2.88);\n        int dots = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] == '.') dots++;\n        if (cur > bestScore || (cur == bestScore && dots > bestDots)) {\n            bestScore = cur;\n            bestDots = dots;\n            bestGrid = grid;\n        }\n    }\n    \n    if (bestScore == (int)avail.size()) {\n        int cur = bestScore;\n        vector<pair<int,int>> cells;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) cells.push_back({r,c});\n        shuffle(cells.begin(), cells.end(), rng);\n        for (auto [r, c] : cells) {\n            if (bestGrid[r][c] == '.') continue;\n            char orig = bestGrid[r][c];\n            bestGrid[r][c] = '.';\n            int nw = countMatches(bestGrid, avail);\n            if (nw < cur) bestGrid[r][c] = orig;\n            else cur = nw;\n        }\n    }\n    \n    cerr << \"Final: \" << bestScore << \"/\" << avail.size() << \"\\n\";\n    \n    for (int i = 0; i < N; i++) cout << bestGrid[i] << \"\\n\";\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> G;\nvector<vector<int>> id;\nvector<pair<int,int>> pos;\nvector<int> cost;\nint R;\n\nbool isRoad(int i,int j){ return i>=0&&i<N&&j>=0&&j<N&&G[i][j]!='#'; }\n\nchrono::steady_clock::time_point startT;\ndouble elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-startT).count();}\n\nint dx_[]={-1,1,0,0},dy_[]={0,0,-1,1};\n\nvoid dijkstra(int src, vector<int>&dist, vector<int>&prv){\n    dist.assign(R,INT_MAX);\n    prv.assign(R,-1);\n    dist[src]=0;\n    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>> pq;\n    pq.push({0,src});\n    while(!pq.empty()){\n        auto[d,u]=pq.top();pq.pop();\n        if(d>dist[u])continue;\n        auto[i,j]=pos[u];\n        for(int di=0;di<4;di++){\n            int x=i+dx_[di],y=j+dy_[di];\n            if(!isRoad(x,y))continue;\n            int v=id[x][y];\n            int nd=d+cost[v];\n            if(nd<dist[v]){\n                dist[v]=nd;\n                prv[v]=u;\n                pq.push({nd,v});\n            }\n        }\n    }\n}\n\nint main(){\n    startT=chrono::steady_clock::now();\n    cin>>N>>si>>sj;\n    G.resize(N);\n    for(auto&s:G)cin>>s;\n    id.assign(N,vector<int>(N,-1));\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(G[i][j]!='#'){\n        id[i][j]=pos.size();\n        pos.push_back({i,j});\n        cost.push_back(G[i][j]-'0');\n    }\n    R=pos.size();\n    \n    vector<vector<int>> visible(R);\n    vector<vector<char>> visMat(R, vector<char>(R, 0));\n    for(int k=0;k<R;k++){\n        auto[i,j]=pos[k];\n        visible[k].push_back(k);\n        visMat[k][k]=1;\n        for(int d=0;d<4;d++){\n            int x=i+dx_[d],y=j+dy_[d];\n            while(isRoad(x,y)){\n                int v=id[x][y];\n                visible[k].push_back(v);\n                visMat[k][v]=1;\n                x+=dx_[d];y+=dy_[d];\n            }\n        }\n    }\n    \n    int sid=id[si][sj];\n    \n    auto greedyCover=[&](unsigned seed)->vector<int>{\n        mt19937 rng(seed);\n        vector<bool> covered(R,false);\n        vector<int> uncovCount(R);\n        for(int k=0;k<R;k++)uncovCount[k]=visible[k].size();\n        vector<int> sel;\n        int nCov=0;\n        auto doSel=[&](int k){\n            sel.push_back(k);\n            for(int v:visible[k]){\n                if(!covered[v]){\n                    covered[v]=true;\n                    nCov++;\n                    for(int u:visible[v])uncovCount[u]--;\n                }\n            }\n        };\n        doSel(sid);\n        while(nCov<R){\n            int bc=-1;\n            vector<int> bests;\n            for(int k=0;k<R;k++){\n                if(uncovCount[k]>bc){bc=uncovCount[k];bests.clear();bests.push_back(k);}\n                else if(uncovCount[k]==bc)bests.push_back(k);\n            }\n            int pick=bests[rng()%bests.size()];\n            doSel(pick);\n        }\n        vector<int> coverCnt(R,0);\n        for(int s:sel)for(int v:visible[s])coverCnt[v]++;\n        vector<bool> keep(sel.size(),true);\n        vector<int> ord;\n        for(int i=1;i<(int)sel.size();i++)ord.push_back(i);\n        shuffle(ord.begin(),ord.end(),rng);\n        for(int i:ord){\n            int s=sel[i];\n            bool can=true;\n            for(int v:visible[s])if(coverCnt[v]<2){can=false;break;}\n            if(can){\n                keep[i]=false;\n                for(int v:visible[s])coverCnt[v]--;\n            }\n        }\n        vector<int> res;\n        for(int i=0;i<(int)sel.size();i++)if(keep[i])res.push_back(sel[i]);\n        return res;\n    };\n    \n    vector<int> selected = greedyCover(1);\n    for(int t=2;t<=10 && elapsed()<0.2;t++){\n        auto s2=greedyCover(t*7919u+1);\n        if(s2.size()<selected.size())selected=s2;\n    }\n    for(int i=0;i<(int)selected.size();i++)if(selected[i]==sid){swap(selected[0],selected[i]);break;}\n    \n    int K=selected.size();\n    vector<vector<int>> dist(K), prev_(K);\n    for(int s=0;s<K;s++)dijkstra(selected[s],dist[s],prev_[s]);\n    \n    vector<vector<int>> D(K,vector<int>(K));\n    for(int a=0;a<K;a++)for(int b=0;b<K;b++)D[a][b]=dist[a][selected[b]];\n    \n    auto tourLen=[&](const vector<int>&t){\n        int s=0;for(int i=0;i+1<(int)t.size();i++)s+=D[t[i]][t[i+1]];return s;\n    };\n    \n    auto twoOpt=[&](vector<int>&tour, double timeLimit){\n        int n=tour.size();\n        bool improved=true;\n        while(improved){\n            improved=false;\n            for(int i=1;i<n-2;i++){\n                if(elapsed()>=timeLimit)return;\n                for(int j=i+1;j<n-1;j++){\n                    int a=tour[i-1],b=tour[i],c=tour[j],d=tour[j+1];\n                    int delta=D[a][c]+D[b][d]-D[a][b]-D[c][d];\n                    if(delta<0){\n                        reverse(tour.begin()+i,tour.begin()+j+1);\n                        improved=true;\n                    }\n                }\n            }\n        }\n    };\n    \n    auto orOpt=[&](vector<int>&tour, double timeLimit){\n        int n=tour.size();\n        bool improved=true;\n        while(improved){\n            improved=false;\n            for(int segLen=1;segLen<=3;segLen++){\n                for(int i=1;i+segLen<n;i++){\n                    if(elapsed()>=timeLimit)return;\n                    int a=tour[i-1], b=tour[i], c=tour[i+segLen-1], d=tour[i+segLen];\n                    int removeCost=D[a][b]+D[c][d]-D[a][d];\n                    int bestDelta=0, bestJ=-1;\n                    bool bestRev=false;\n                    for(int j=0;j<n-1;j++){\n                        if(j>=i-1 && j<=i+segLen-1)continue;\n                        int e=tour[j], f=tour[j+1];\n                        int ic=D[e][b]+D[c][f]-D[e][f];\n                        int delta=ic-removeCost;\n                        if(delta<bestDelta){bestDelta=delta;bestJ=j;bestRev=false;}\n                        int ic2=D[e][c]+D[b][f]-D[e][f];\n                        int delta2=ic2-removeCost;\n                        if(delta2<bestDelta){bestDelta=delta2;bestJ=j;bestRev=true;}\n                    }\n                    if(bestJ>=0){\n                        vector<int> seg(tour.begin()+i, tour.begin()+i+segLen);\n                        if(bestRev)reverse(seg.begin(),seg.end());\n                        vector<int> nt;\n                        int j=bestJ;\n                        if(j<i-1){\n                            for(int k=0;k<=j;k++)nt.push_back(tour[k]);\n                            for(int x:seg)nt.push_back(x);\n                            for(int k=j+1;k<i;k++)nt.push_back(tour[k]);\n                            for(int k=i+segLen;k<n;k++)nt.push_back(tour[k]);\n                        } else {\n                            for(int k=0;k<i;k++)nt.push_back(tour[k]);\n                            for(int k=i+segLen;k<=j;k++)nt.push_back(tour[k]);\n                            for(int x:seg)nt.push_back(x);\n                            for(int k=j+1;k<n;k++)nt.push_back(tour[k]);\n                        }\n                        tour=nt;\n                        improved=true;\n                        break;\n                    }\n                }\n                if(improved)break;\n            }\n        }\n    };\n    \n    auto nearestNeighborFrom=[&](int startNeighbor){\n        vector<int> tour;\n        vector<bool> used(K,false);\n        used[0]=true;\n        tour.push_back(0);\n        if(startNeighbor!=0 && startNeighbor<K){\n            tour.push_back(startNeighbor);\n            used[startNeighbor]=true;\n        }\n        while((int)tour.size()<K){\n            int last=tour.back();\n            int bn=-1,bd=INT_MAX;\n            for(int j=0;j<K;j++)if(!used[j]&&D[last][j]<bd){bd=D[last][j];bn=j;}\n            tour.push_back(bn);used[bn]=true;\n        }\n        tour.push_back(0);\n        return tour;\n    };\n    \n    vector<int> bestTour = nearestNeighborFrom(0);\n    twoOpt(bestTour, 0.18);\n    orOpt(bestTour, 0.28);\n    twoOpt(bestTour, 0.35);\n    int bestLen = tourLen(bestTour);\n    \n    for(int s=1;s<K && elapsed()<0.5;s++){\n        vector<int> t = nearestNeighborFrom(s);\n        twoOpt(t, min(0.5, elapsed()+0.03));\n        int l=tourLen(t);\n        if(l<bestLen){bestLen=l;bestTour=t;}\n    }\n    \n    mt19937 rng(12345);\n    \n    while(elapsed()<0.7){\n        vector<int> t2 = bestTour;\n        int n = t2.size()-1;\n        if(n<8)break;\n        int p1=1+rng()%(n/4);\n        int p2=p1+1+rng()%(n/4);\n        int p3=p2+1+rng()%(n/4);\n        if(p3>=n)continue;\n        vector<int> nt;\n        nt.push_back(t2[0]);\n        for(int i=p3;i<n;i++)nt.push_back(t2[i]);\n        for(int i=p2;i<p3;i++)nt.push_back(t2[i]);\n        for(int i=p1;i<p2;i++)nt.push_back(t2[i]);\n        for(int i=1;i<p1;i++)nt.push_back(t2[i]);\n        nt.push_back(t2[0]);\n        double lim = min(0.7, elapsed()+0.06);\n        twoOpt(nt, lim);\n        orOpt(nt, min(0.7, elapsed()+0.03));\n        int l=tourLen(nt);\n        if(l<bestLen){bestLen=l;bestTour=nt;}\n    }\n    \n    auto tryGlobalReplacement=[&]()->int{\n        vector<int> coverCnt(R,0);\n        for(int s:selected)for(int v:visible[s])coverCnt[v]++;\n        \n        int changes=0;\n        vector<int> order;\n        for(int i=1;i<K;i++)order.push_back(i);\n        shuffle(order.begin(),order.end(),rng);\n        \n        for(int ti:order){\n            if(elapsed()>1.9)break;\n            if(ti>=K)continue;\n            int origPt = selected[ti];\n            vector<int> unique_sq;\n            for(int v:visible[origPt])if(coverCnt[v]==1)unique_sq.push_back(v);\n            \n            int pos_in_tour=-1;\n            for(int p=0;p<(int)bestTour.size();p++)if(bestTour[p]==ti){pos_in_tour=p;break;}\n            if(pos_in_tour<0)continue;\n            int prv = bestTour[pos_in_tour-1];\n            int nxt = bestTour[pos_in_tour+1];\n            int removeGain = D[prv][ti]+D[ti][nxt]-D[prv][nxt];\n            \n            if(unique_sq.empty()){\n                if(removeGain>0){\n                    int removedIdx = ti;\n                    vector<int> newSel;\n                    for(int i=0;i<K;i++)if(i!=removedIdx)newSel.push_back(selected[i]);\n                    vector<vector<int>> newDist(newSel.size()), newPrev(newSel.size());\n                    for(int s=0;s<(int)newSel.size();s++){\n                        int o = (s<removedIdx)?s:s+1;\n                        newDist[s] = dist[o];\n                        newPrev[s] = prev_[o];\n                    }\n                    selected = newSel;\n                    K = selected.size();\n                    dist = newDist; prev_ = newPrev;\n                    D.assign(K,vector<int>(K));\n                    for(int a=0;a<K;a++)for(int b=0;b<K;b++)D[a][b]=dist[a][selected[b]];\n                    vector<int> newTour;\n                    for(int x:bestTour){\n                        if(x==removedIdx)continue;\n                        newTour.push_back(x>removedIdx?x-1:x);\n                    }\n                    vector<int> nt2;\n                    for(int x:newTour){\n                        if(!nt2.empty() && nt2.back()==x)continue;\n                        nt2.push_back(x);\n                    }\n                    if(nt2.empty() || nt2[0]!=0)nt2.insert(nt2.begin(),0);\n                    if(nt2.back()!=0)nt2.push_back(0);\n                    bestTour = nt2;\n                    bestLen = tourLen(bestTour);\n                    changes++;\n                    return changes;\n                }\n                continue;\n            }\n            \n            vector<int> candidates;\n            int smallest=unique_sq[0];\n            for(int v:unique_sq)if((int)visible[v].size()<(int)visible[smallest].size())smallest=v;\n            for(int c:visible[smallest]){\n                bool ok=true;\n                for(int v:unique_sq)if(!visMat[c][v]){ok=false;break;}\n                if(ok)candidates.push_back(c);\n            }\n            \n            int bestDelta = 0;\n            int bestCand = -1;\n            int bestInsertPos = -2;\n            int n_tour = bestTour.size();\n            \n            for(int cand:candidates){\n                if(cand==origPt)continue;\n                for(int p=0;p+1<n_tour;p++){\n                    if(p==pos_in_tour-1 || p==pos_in_tour)continue;\n                    int ej = bestTour[p], fj = bestTour[p+1];\n                    int d1 = dist[ej][cand];\n                    if(d1>=INT_MAX/2)continue;\n                    int d2 = dist[fj][cand] - cost[selected[fj]] + cost[cand];\n                    int insertCost = d1 + d2 - D[ej][fj];\n                    int delta = -removeGain + insertCost;\n                    if(delta < bestDelta){\n                        bestDelta = delta;\n                        bestCand = cand;\n                        bestInsertPos = p;\n                    }\n                }\n                {\n                    int ej = prv, fj = nxt;\n                    int d1 = dist[ej][cand];\n                    if(d1<INT_MAX/2){\n                        int d2 = dist[fj][cand] - cost[selected[fj]] + cost[cand];\n                        int insertCost = d1 + d2 - D[prv][nxt];\n                        int delta = -removeGain + insertCost;\n                        if(delta < bestDelta){\n                            bestDelta = delta;\n                            bestCand = cand;\n                            bestInsertPos = -1;\n                        }\n                    }\n                }\n            }\n            \n            if(bestCand==-1)continue;\n            \n            int cand = bestCand;\n            for(int v:visible[origPt])coverCnt[v]--;\n            for(int v:visible[cand])coverCnt[v]++;\n            selected[ti]=cand;\n            dijkstra(cand, dist[ti], prev_[ti]);\n            for(int b=0;b<K;b++)D[ti][b]=dist[ti][selected[b]];\n            for(int b=0;b<K;b++){\n                if(b==ti)continue;\n                D[b][ti] = D[ti][b] + cost[cand] - cost[selected[b]];\n            }\n            if(bestInsertPos==-1){\n            } else {\n                vector<int> shortT;\n                for(int p=0;p<(int)bestTour.size();p++)if(p!=pos_in_tour)shortT.push_back(bestTour[p]);\n                int adjInsert = bestInsertPos;\n                if(bestInsertPos > pos_in_tour) adjInsert = bestInsertPos - 1;\n                vector<int> nt;\n                for(int p=0;p<=adjInsert;p++)nt.push_back(shortT[p]);\n                nt.push_back(ti);\n                for(int p=adjInsert+1;p<(int)shortT.size();p++)nt.push_back(shortT[p]);\n                bestTour = nt;\n            }\n            bestLen = tourLen(bestTour);\n            changes++;\n        }\n        return changes;\n    };\n    \n    // Phase 1: Global replacement rounds (NO path-based removal)\n    for(int round=0;round<40 && elapsed()<1.8;round++){\n        int ch1 = tryGlobalReplacement();\n        twoOpt(bestTour, min(2.0, elapsed()+0.06));\n        orOpt(bestTour, min(2.0, elapsed()+0.03));\n        bestLen = tourLen(bestTour);\n        if(ch1==0 && round>0)break;\n    }\n    \n    // More perturbations\n    while(elapsed()<2.1){\n        vector<int> t2 = bestTour;\n        int n = t2.size()-1;\n        if(n<8)break;\n        int p1=1+rng()%(n/4);\n        int p2=p1+1+rng()%(n/4);\n        int p3=p2+1+rng()%(n/4);\n        if(p3>=n)continue;\n        vector<int> nt;\n        nt.push_back(t2[0]);\n        for(int i=p3;i<n;i++)nt.push_back(t2[i]);\n        for(int i=p2;i<p3;i++)nt.push_back(t2[i]);\n        for(int i=p1;i<p2;i++)nt.push_back(t2[i]);\n        for(int i=1;i<p1;i++)nt.push_back(t2[i]);\n        nt.push_back(t2[0]);\n        double lim = min(2.1, elapsed()+0.07);\n        twoOpt(nt, lim);\n        orOpt(nt, min(2.1, elapsed()+0.03));\n        int l=tourLen(nt);\n        if(l<bestLen){bestLen=l;bestTour=nt;}\n    }\n    \n    // BACKUP - this is reliably covering\n    vector<int> backupSelected = selected;\n    vector<vector<int>> backupDist = dist;\n    vector<vector<int>> backupPrev = prev_;\n    vector<vector<int>> backupD = D;\n    vector<int> backupTour = bestTour;\n    int backupK = K;\n    \n    // Phase 2: PATH-BASED REMOVAL ONLY (NO tour modifications after)\n    auto tryPathBasedRemoval = [&]()->bool{\n        if(K<=2)return false;\n        vector<int> order;\n        for(int i=1;i<K;i++) order.push_back(i);\n        shuffle(order.begin(), order.end(), rng);\n        \n        for(int ti : order){\n            if(elapsed() > 2.7) return false;\n            int pt=-1;\n            for(int p=0;p<(int)bestTour.size();p++) if(bestTour[p]==ti){pt=p;break;}\n            if(pt<0) continue;\n            int prvI = bestTour[pt-1], nxtI = bestTour[pt+1];\n            int removeGain = D[prvI][ti]+D[ti][nxtI]-D[prvI][nxtI];\n            if(removeGain < 0) continue;\n            \n            vector<int> nt2;\n            for(int p=0;p<(int)bestTour.size();p++){\n                if(p==pt) continue;\n                int x = bestTour[p];\n                if(!nt2.empty() && nt2.back()==x) continue;\n                nt2.push_back(x);\n            }\n            if(nt2.empty())continue;\n            if(nt2.back() != nt2.front()) nt2.push_back(nt2.front());\n            if((int)nt2.size() < 2) continue;\n            \n            vector<char> cov(R, 0);\n            auto add = [&](int v){ \n                for(int u : visible[v]) cov[u]=1;\n            };\n            bool ok=true;\n            add(selected[nt2[0]]);\n            for(int i=0;i+1<(int)nt2.size();i++){\n                int ai = nt2[i], bi = nt2[i+1];\n                int a = selected[ai], b = selected[bi];\n                if(a==b) continue;\n                int cur = b;\n                int safety = 10*R;\n                while(cur != a){\n                    if(safety-- <= 0){ok=false;break;}\n                    add(cur);\n                    int nx = prev_[ai][cur];\n                    if(nx<0){ok=false;break;}\n                    cur = nx;\n                }\n                if(!ok) break;\n            }\n            if(!ok) continue;\n            \n            bool allCov = true;\n            for(int v=0;v<R;v++) if(!cov[v]){allCov=false;break;}\n            if(!allCov) continue;\n            \n            int removedIdx = ti;\n            vector<int> newSel;\n            for(int i=0;i<K;i++) if(i!=removedIdx) newSel.push_back(selected[i]);\n            vector<vector<int>> newDist(newSel.size()), newPrev(newSel.size());\n            for(int s=0;s<(int)newSel.size();s++){\n                int o = (s<removedIdx)?s:s+1;\n                newDist[s] = dist[o];\n                newPrev[s] = prev_[o];\n            }\n            vector<int> newTour;\n            for(int x : nt2) newTour.push_back(x > removedIdx ? x-1 : x);\n            \n            selected = newSel;\n            K = selected.size();\n            dist = newDist;\n            prev_ = newPrev;\n            D.assign(K, vector<int>(K));\n            for(int a=0;a<K;a++)for(int b=0;b<K;b++) D[a][b]=dist[a][selected[b]];\n            bestTour = newTour;\n            bestLen = tourLen(bestTour);\n            return true;\n        }\n        return false;\n    };\n    \n    // Phase 2: pure path-based removal, NO tour modifications afterward\n    while(elapsed()<2.7){\n        if(!tryPathBasedRemoval())break;\n    }\n    \n    // Phase 3: Verify, restore if broken\n    auto verifyCoverage = [&]()->bool{\n        vector<char> cov(R,0);\n        auto add=[&](int v){for(int u:visible[v])cov[u]=1;};\n        if(bestTour.empty())return false;\n        add(selected[bestTour[0]]);\n        for(int i=0;i+1<(int)bestTour.size();i++){\n            int a=selected[bestTour[i]], b=selected[bestTour[i+1]];\n            if(a==b)continue;\n            int s=bestTour[i];\n            int cur=b;\n            int safety=10*R;\n            while(cur!=a){\n                if(safety-- <= 0)return false;\n                add(cur);\n                int nx=prev_[s][cur];\n                if(nx<0)return false;\n                cur=nx;\n            }\n        }\n        for(int v=0;v<R;v++)if(!cov[v])return false;\n        return true;\n    };\n    \n    if(!verifyCoverage()){\n        selected = backupSelected;\n        dist = backupDist;\n        prev_ = backupPrev;\n        D = backupD;\n        bestTour = backupTour;\n        K = backupK;\n    }\n    \n    vector<int>& tour = bestTour;\n    \n    string result;\n    for(int i=0;i+1<(int)tour.size();i++){\n        int a=selected[tour[i]], b=selected[tour[i+1]];\n        if(a==b)continue;\n        int s=tour[i];\n        vector<int> path;\n        int cur=b;\n        while(cur!=a){\n            path.push_back(cur);\n            cur=prev_[s][cur];\n        }\n        reverse(path.begin(),path.end());\n        int px=pos[a].first, py=pos[a].second;\n        for(int nd:path){\n            int nx=pos[nd].first, ny=pos[nd].second;\n            if(nx==px-1)result+='U';\n            else if(nx==px+1)result+='D';\n            else if(ny==py-1)result+='L';\n            else result+='R';\n            px=nx;py=ny;\n        }\n    }\n    \n    cout<<result<<endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> D;\nvector<vector<int>> children;\nvector<int> indeg;\nvector<int> longestPath;\nvector<int> numDesc;\n\nvector<vector<int>> estS;\nvector<vector<pair<int,int>>> obs;\n\nint computeW(const vector<int>& d, const vector<int>& s) {\n    int w = 0;\n    for (int k = 0; k < K; k++) w += max(0, d[k] - s[k]);\n    return w;\n}\n\nint predictTime(int task, int member) {\n    int w = computeW(D[task], estS[member]);\n    return (w == 0) ? 1 : max(1, w);\n}\n\ndouble errorFor(int member, const vector<int>& s) {\n    double err = 0;\n    for (auto& p : obs[member]) {\n        int w = computeW(D[p.first], s);\n        int pred = (w == 0) ? 1 : max(1, w);\n        double diff = (double)pred - p.second;\n        err += diff * diff;\n    }\n    return err;\n}\n\nvoid updateSkills(int member) {\n    if (obs[member].empty()) return;\n    vector<int>& s = estS[member];\n    double best = errorFor(member, s);\n    for (int pass = 0; pass < 100; pass++) {\n        bool improved = false;\n        for (int k = 0; k < K; k++) {\n            for (int delta : {1, -1, 2, -2, 3, -3}) {\n                int old = s[k];\n                int nv = old + delta;\n                if (nv < 0 || nv > 50) continue;\n                s[k] = nv;\n                double e = errorFor(member, s);\n                if (e < best - 1e-9) {\n                    best = e;\n                    improved = true;\n                } else {\n                    s[k] = old;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> N >> M >> K >> R;\n    D.assign(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> D[i][k];\n    children.assign(N, {});\n    indeg.assign(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        children[u].push_back(v);\n        indeg[v]++;\n    }\n    \n    longestPath.assign(N, 0);\n    for (int i = N - 1; i >= 0; i--) {\n        int b = 0;\n        for (int ch : children[i]) b = max(b, longestPath[ch]);\n        longestPath[i] = b + 1;\n    }\n    \n    numDesc.assign(N, 0);\n    {\n        vector<bitset<1024>> reach(N);\n        for (int i = N - 1; i >= 0; i--) {\n            reach[i].set(i);\n            for (int ch : children[i]) reach[i] |= reach[ch];\n            numDesc[i] = reach[i].count();\n        }\n    }\n    \n    vector<double> priority(N);\n    for (int i = 0; i < N; i++) {\n        priority[i] = longestPath[i] + 0.1 * numDesc[i];\n    }\n    \n    estS.assign(M, vector<int>(K, 3));\n    obs.assign(M, {});\n    \n    vector<int> taskStatus(N, 0);\n    vector<int> memberTask(M, -1);\n    vector<int> memberStartDay(M, 0);\n    vector<int> remIndeg = indeg;\n    \n    for (int day = 1; day <= 2000; day++) {\n        vector<int> avail;\n        for (int i = 0; i < N; i++)\n            if (taskStatus[i] == 0 && remIndeg[i] == 0) avail.push_back(i);\n        \n        sort(avail.begin(), avail.end(), [&](int a, int b) {\n            return priority[a] > priority[b];\n        });\n        \n        vector<int> freeM;\n        for (int j = 0; j < M; j++) if (memberTask[j] == -1) freeM.push_back(j);\n        \n        vector<bool> memUsed(M, false);\n        vector<int> taskOfMem(M, -1);\n        \n        for (int task : avail) {\n            int bestMem = -1, bestTime = INT_MAX;\n            for (int j : freeM) {\n                if (memUsed[j]) continue;\n                int t = predictTime(task, j);\n                if (t < bestTime) { bestTime = t; bestMem = j; }\n            }\n            if (bestMem == -1) break;\n            memUsed[bestMem] = true;\n            taskOfMem[bestMem] = task;\n        }\n        \n        bool improved = true;\n        int iters = 0;\n        while (improved && iters < 50) {\n            improved = false;\n            iters++;\n            for (size_t a = 0; a < freeM.size(); a++) {\n                int ma = freeM[a];\n                if (taskOfMem[ma] == -1) continue;\n                for (size_t b = a+1; b < freeM.size(); b++) {\n                    int mb = freeM[b];\n                    if (taskOfMem[mb] == -1) continue;\n                    int ta = taskOfMem[ma], tb = taskOfMem[mb];\n                    double curr = (double)predictTime(ta, ma) * priority[ta] + (double)predictTime(tb, mb) * priority[tb];\n                    double swapped = (double)predictTime(tb, ma) * priority[tb] + (double)predictTime(ta, mb) * priority[ta];\n                    if (swapped < curr - 1e-9) {\n                        taskOfMem[ma] = tb;\n                        taskOfMem[mb] = ta;\n                        improved = true;\n                    }\n                }\n            }\n        }\n        \n        vector<pair<int,int>> assignments;\n        for (int j : freeM) {\n            if (taskOfMem[j] != -1) {\n                int task = taskOfMem[j];\n                assignments.push_back({j, task});\n                taskStatus[task] = 1;\n                memberTask[j] = task;\n                memberStartDay[j] = day;\n            }\n        }\n        \n        cout << assignments.size();\n        for (auto& p : assignments) cout << \" \" << (p.first+1) << \" \" << (p.second+1);\n        cout << \"\\n\";\n        cout.flush();\n        \n        int n; cin >> n;\n        if (n == -1) return 0;\n        for (int i = 0; i < n; i++) {\n            int f; cin >> f; f--;\n            int task = memberTask[f];\n            int daysTaken = day - memberStartDay[f] + 1;\n            obs[f].push_back({task, daysTaken});\n            taskStatus[task] = 2;\n            memberTask[f] = -1;\n            for (int ch : children[task]) remIndeg[ch]--;\n            updateSkills(f);\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint A[1000][4];\n\ninline int px(int id) { \n    if(id<=0) return 400;\n    if(id<=1000) return A[id-1][0];\n    return A[id-1001][2];\n}\ninline int py(int id) {\n    if(id<=0) return 400;\n    if(id<=1000) return A[id-1][1];\n    return A[id-1001][3];\n}\ninline int D(int a, int b) {\n    return abs(px(a)-px(b))+abs(py(a)-py(b));\n}\n\nint routeCost(const vector<int>& s){\n    int t=0;\n    for(int i=0;i+1<(int)s.size();i++) t+=D(s[i],s[i+1]);\n    return t;\n}\n\nint insertOrderBest(vector<int>& s, int oid){\n    int p = oid+1, dlv = oid+1001;\n    int n = s.size();\n    int best = INT_MAX;\n    int bi=1, bj=1;\n    \n    static int cost_p[128], cost_d[128];\n    for(int i=1;i<n;i++){\n        int dss = D(s[i-1], s[i]);\n        cost_p[i] = D(s[i-1], p) + D(p, s[i]) - dss;\n        cost_d[i] = D(s[i-1], dlv) + D(dlv, s[i]) - dss;\n    }\n    \n    int dpd = D(p, dlv);\n    for(int i=1;i<n;i++){\n        int delta = D(s[i-1], p) + dpd + D(dlv, s[i]) - D(s[i-1], s[i]);\n        if(delta < best){ best = delta; bi = i; bj = i; }\n    }\n    \n    int min_cp = INT_MAX, min_cp_i = -1;\n    for(int j=2;j<n;j++){\n        int ic = j-1;\n        if(cost_p[ic] < min_cp){ min_cp = cost_p[ic]; min_cp_i = ic; }\n        int delta = min_cp + cost_d[j];\n        if(delta < best){ best = delta; bi = min_cp_i; bj = j; }\n    }\n    \n    if(bi==bj){\n        s.insert(s.begin()+bi, dlv);\n        s.insert(s.begin()+bi, p);\n    } else {\n        s.insert(s.begin()+bj, dlv);\n        s.insert(s.begin()+bi, p);\n    }\n    return best;\n}\n\nint removeOrderDelta(vector<int>& s, int oid){\n    int p=oid+1, d=oid+1001;\n    int ip=-1, idx_=-1;\n    int n=s.size();\n    for(int i=0;i<n;i++){\n        if(s[i]==p) ip=i;\n        else if(s[i]==d) idx_=i;\n    }\n    int delta = 0;\n    if(idx_ == ip+1){\n        delta = D(s[ip-1], s[idx_+1]) - D(s[ip-1],p) - D(p,d) - D(d, s[idx_+1]);\n        s.erase(s.begin()+ip, s.begin()+idx_+1);\n    } else {\n        delta -= D(s[ip-1],p) + D(p, s[ip+1]);\n        delta += D(s[ip-1], s[ip+1]);\n        delta -= D(s[idx_-1], d) + D(d, s[idx_+1]);\n        delta += D(s[idx_-1], s[idx_+1]);\n        s.erase(s.begin()+idx_);\n        s.erase(s.begin()+ip);\n    }\n    return delta;\n}\n\nstatic int POS_[2001];\nstatic int PP_[128];\n\nint relocateOnce(vector<int>& s){\n    int n = s.size();\n    for(int i=0;i<n;i++) POS_[s[i]]=i;\n    for(int i=0;i<n;i++){\n        int id = s[i];\n        if(id<=0){ PP_[i]=-1; continue; }\n        int partner = (id<=1000) ? id+1000 : id-1000;\n        PP_[i] = POS_[partner];\n    }\n    int bestDelta = 0;\n    int bestFrom=-1, bestTo=-1;\n    for(int from=1;from<n-1;from++){\n        int id = s[from];\n        if(id<=0) continue;\n        bool isPickup = (id<=1000);\n        int pp = PP_[from];\n        int lo, hi;\n        if(isPickup){ lo=1; hi=pp; }\n        else { lo=pp+1; hi=n; }\n        int remGain = D(s[from-1],s[from])+D(s[from],s[from+1])-D(s[from-1],s[from+1]);\n        for(int to=lo;to<=hi;to++){\n            if(to==from || to==from+1) continue;\n            int aa = s[to-1], bb = s[to];\n            int insCost = D(aa,id)+D(id,bb)-D(aa,bb);\n            int delta = insCost - remGain;\n            if(delta < bestDelta){\n                bestDelta = delta;\n                bestFrom = from;\n                bestTo = to;\n            }\n        }\n    }\n    if(bestDelta<0){\n        int id = s[bestFrom];\n        s.erase(s.begin()+bestFrom);\n        int to = bestTo;\n        if(to>bestFrom) to--;\n        s.insert(s.begin()+to, id);\n        return bestDelta;\n    }\n    return 0;\n}\n\nint twoOptOnce(vector<int>& s){\n    int n = s.size();\n    for(int i=0;i<n;i++) POS_[s[i]]=i;\n    for(int i=0;i<n;i++){\n        int id = s[i];\n        if(id<=0){ PP_[i]=-1; continue; }\n        int partner = (id<=1000) ? id+1000 : id-1000;\n        PP_[i] = POS_[partner];\n    }\n    int bestDelta = 0;\n    int bi=-1, bj=-1;\n    for(int i=1;i<n-2;i++){\n        int pairCount = 0;\n        int si_1 = s[i-1], si = s[i];\n        int d_im1_i = D(si_1, si);\n        for(int j=i+1;j<n-1;j++){\n            if(PP_[j] >= i && PP_[j] < j) pairCount++;\n            if(pairCount == 0){\n                int sj = s[j], sj1 = s[j+1];\n                int delta = D(si_1, sj) + D(si, sj1) - d_im1_i - D(sj, sj1);\n                if(delta < bestDelta){ bestDelta = delta; bi=i; bj=j; }\n            }\n        }\n    }\n    if(bestDelta<0){\n        reverse(s.begin()+bi, s.begin()+bj+1);\n        return bestDelta;\n    }\n    return 0;\n}\n\nint main(){\n    auto start = steady_clock::now();\n    for(int i=0;i<1000;i++) for(int j=0;j<4;j++) cin>>A[i][j];\n    \n    vector<pair<int,int>> scored(1000);\n    for(int i=0;i<1000;i++){\n        int s = abs(A[i][0]-400)+abs(A[i][1]-400)+abs(A[i][2]-400)+abs(A[i][3]-400);\n        scored[i]={s,i};\n    }\n    sort(scored.begin(),scored.end());\n    \n    vector<bool> inChosen(1000,false);\n    vector<int> chosen;\n    for(int i=0;i<50;i++){ chosen.push_back(scored[i].second); inChosen[scored[i].second]=true; }\n    \n    vector<int> seq = {0, 0};\n    for(int oid : chosen) insertOrderBest(seq, oid);\n    int curCost = routeCost(seq);\n    \n    auto localOpt = [&](){\n        int d;\n        bool improved = true;\n        while(improved){\n            improved = false;\n            while((d = twoOptOnce(seq)) < 0){ curCost += d; improved = true; }\n            while((d = relocateOnce(seq)) < 0){ curCost += d; improved = true; }\n        }\n    };\n    \n    auto rebuildChosen = [&](){\n        chosen.clear();\n        fill(inChosen.begin(), inChosen.end(), false);\n        for(int id : seq){\n            if(id>=1 && id<=1000 && !inChosen[id-1]){\n                chosen.push_back(id-1);\n                inChosen[id-1] = true;\n            }\n        }\n    };\n    \n    localOpt();\n    \n    mt19937 rng(12345);\n    int timeLimit = 1850;\n    vector<int> backup;\n    backup.reserve(128);\n    int bestCost = curCost;\n    vector<int> bestSeq = seq;\n    \n    long long iter = 0;\n    long long elapsed_ms = 0;\n    double t0 = 40.0, t1 = 0.3;\n    int numCycles = 4;\n    double cycleLen = timeLimit / (double)numCycles;\n    int lastCycle = 0;\n    \n    while(true){\n        if((iter&255)==0){\n            elapsed_ms = duration_cast<milliseconds>(steady_clock::now()-start).count();\n            if(elapsed_ms>timeLimit) break;\n            int curCycle = (int)(elapsed_ms / cycleLen);\n            if(curCycle != lastCycle){\n                seq = bestSeq;\n                curCost = bestCost;\n                rebuildChosen();\n                lastCycle = curCycle;\n            }\n        }\n        iter++;\n        double cycleT = fmod((double)elapsed_ms, cycleLen) / cycleLen;\n        double temp = t0 * pow(t1/t0, cycleT);\n        \n        int moveType = rng()%10;\n        \n        if(moveType < 9){\n            int idx = rng()%50;\n            int oldOrd = chosen[idx];\n            int newOrd;\n            do { newOrd = rng()%1000; } while(inChosen[newOrd]);\n            \n            backup = seq;\n            int remDelta = removeOrderDelta(seq, oldOrd);\n            int insDelta = insertOrderBest(seq, newOrd);\n            int diff0 = remDelta + insDelta;\n            \n            bool tentative = false;\n            if(diff0 <= 0) tentative = true;\n            else {\n                double prob = exp(-diff0/temp);\n                if((rng()&0xFFFFFF)/(double)0x1000000 < prob) tentative = true;\n            }\n            \n            if(tentative){\n                curCost += diff0;\n                int d;\n                if((d = twoOptOnce(seq)) < 0) curCost += d;\n                if((d = relocateOnce(seq)) < 0) curCost += d;\n                if((d = twoOptOnce(seq)) < 0) curCost += d;\n                \n                inChosen[oldOrd] = false;\n                inChosen[newOrd] = true;\n                chosen[idx] = newOrd;\n                \n                if(curCost < bestCost){\n                    bestCost = curCost;\n                    bestSeq = seq;\n                }\n            } else {\n                seq = backup;\n            }\n        } else {\n            int idx = rng()%50;\n            int oid = chosen[idx];\n            int remDelta = removeOrderDelta(seq, oid);\n            int insDelta = insertOrderBest(seq, oid);\n            curCost += remDelta + insDelta;\n            int d;\n            if((d = twoOptOnce(seq)) < 0) curCost += d;\n            if((d = relocateOnce(seq)) < 0) curCost += d;\n            if(curCost < bestCost){\n                bestCost = curCost;\n                bestSeq = seq;\n            }\n        }\n    }\n    \n    seq = bestSeq;\n    curCost = bestCost;\n    localOpt();\n    \n    cout << 50;\n    vector<int> ords;\n    set<int> seen;\n    for(int id : seq){\n        if(id>=1 && id<=1000 && !seen.count(id-1)){\n            ords.push_back(id-1);\n            seen.insert(id-1);\n        }\n    }\n    for(int o : ords) cout << \" \" << (o+1);\n    cout << \"\\n\";\n    cout << seq.size();\n    for(int id : seq) cout << \" \" << px(id) << \" \" << py(id);\n    cout << \"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\n#include <sys/time.h>\nusing namespace std;\n\ndouble get_time(){\n    struct timeval tv;\n    gettimeofday(&tv, NULL);\n    return tv.tv_sec + tv.tv_usec * 1e-6;\n}\n\nstruct DSU {\n    int p[400], r[400];\n    void init(int n){ for(int i=0;i<n;i++){p[i]=i;r[i]=0;} }\n    int f(int x){ while(p[x]!=x){p[x]=p[p[x]];x=p[x];} return x; }\n    int u(int a,int b){ a=f(a);b=f(b); if(a==b)return 0; if(r[a]<r[b])swap(a,b); p[b]=a; if(r[a]==r[b])r[a]++; return 1; }\n};\n\nint N=400, M=1995;\nint X[400], Y[400];\nint U[2000], V[2000], D[2000];\n\nconst int WMAX = 4000;\nint bkt_head[WMAX+2];\nint bkt_next[2100];\nint ea[2100], eb[2100], ew[2100];\nDSU sim;\n\nint main(){\n    double startTime = get_time();\n    double timeLimit = 1.75;\n    double hardStop = 1.88;\n    \n    for(int i=0;i<N;i++) scanf(\"%d %d\", &X[i], &Y[i]);\n    for(int i=0;i<M;i++){\n        scanf(\"%d %d\", &U[i], &V[i]);\n        double dx=X[U[i]]-X[V[i]], dy=Y[U[i]]-Y[V[i]];\n        D[i] = (int)round(sqrt(dx*dx+dy*dy));\n        if(D[i]<1) D[i]=1;\n    }\n    \n    vector<tuple<int,int,int>> adoptedEdges;\n    DSU glob; glob.init(N);\n    \n    uint64_t rng_state = 88172645463325252ULL;\n    auto rnd = [&]() -> uint32_t {\n        rng_state ^= rng_state << 13;\n        rng_state ^= rng_state >> 7;\n        rng_state ^= rng_state << 17;\n        return (uint32_t)rng_state;\n    };\n    \n    for(int i=0;i<M;i++){\n        int l; scanf(\"%d\", &l);\n        \n        if(glob.f(U[i]) == glob.f(V[i])){\n            printf(\"0\\n\"); fflush(stdout);\n            continue;\n        }\n        \n        double nowElapsed = get_time() - startTime;\n        if(nowElapsed > hardStop){\n            bool adopt = (l < (int)(1.8 * D[i]));\n            if(adopt){\n                printf(\"1\\n\");\n                adoptedEdges.push_back({l, U[i], V[i]});\n                glob.u(U[i], V[i]);\n            } else {\n                printf(\"0\\n\");\n            }\n            fflush(stdout);\n            continue;\n        }\n        \n        int ui = U[i], vi = V[i];\n        \n        int cnt = 0;\n        int maxW = 0;\n        for(auto& [w,a,b]: adoptedEdges){\n            ew[cnt]=w; ea[cnt]=a; eb[cnt]=b; cnt++;\n            if(w>maxW) maxW=w;\n        }\n        int staticCnt = cnt;\n        \n        for(int j=i+1;j<M;j++){\n            ea[cnt]=U[j]; eb[cnt]=V[j]; cnt++;\n        }\n        \n        double remTime = timeLimit - nowElapsed;\n        int remEdges = M - i;\n        double perEdgeBudget = remTime > 0 ? remTime / remEdges : 0.00001;\n        double maxEdgeBudget = perEdgeBudget * 5;\n        \n        const int MAX_TRIALS = 500;\n        const int MIN_TRIALS = 12;\n        long long sumAlt = 0;\n        long long sumSq = 0;\n        int done = 0;\n        const int BIG = 10000;\n        double edgeStart = get_time();\n        \n        for(int t=0; t<MAX_TRIALS; t++){\n            int tmpMax = maxW;\n            for(int k=staticCnt; k<cnt; k++){\n                int j = i+1 + (k - staticCnt);\n                int range = 2*D[j]+1;\n                int w = D[j] + (int)(rnd() % (uint32_t)range);\n                ew[k] = w;\n                if(w > tmpMax) tmpMax = w;\n            }\n            \n            for(int w=0; w<=tmpMax; w++) bkt_head[w] = -1;\n            for(int k=0; k<cnt; k++){\n                bkt_next[k] = bkt_head[ew[k]];\n                bkt_head[ew[k]] = k;\n            }\n            \n            sim.init(N);\n            int altCost = BIG;\n            for(int w=0; w<=tmpMax; w++){\n                int head = bkt_head[w];\n                if(head == -1) continue;\n                for(int k=head; k!=-1; k=bkt_next[k]){\n                    sim.u(ea[k], eb[k]);\n                }\n                if(sim.f(ui) == sim.f(vi)){\n                    altCost = w;\n                    break;\n                }\n            }\n            \n            sumAlt += altCost;\n            sumSq += (long long)altCost * altCost;\n            done++;\n            \n            if(done >= MIN_TRIALS){\n                double mean = (double)sumAlt / done;\n                double denom = (double)(done > 1 ? done - 1 : 1);\n                double var = ((double)sumSq - (double)sumAlt * (double)sumAlt / done) / denom;\n                if(var < 0) var = 0;\n                double se = sqrt(var / done);\n                double diff = fabs(mean - l);\n                if(diff > 2.5 * se) break;\n                \n                if((done & 3) == 0){\n                    double glbNow = get_time();\n                    if(glbNow - startTime > hardStop) break;\n                    if(glbNow - edgeStart > maxEdgeBudget) break;\n                }\n            }\n        }\n        \n        double avgAlt = (double)sumAlt / done;\n        bool adopt = ((double)l < avgAlt);\n        \n        if(adopt){\n            printf(\"1\\n\");\n            adoptedEdges.push_back({l, U[i], V[i]});\n            glob.u(U[i], V[i]);\n        } else {\n            printf(\"0\\n\");\n        }\n        fflush(stdout);\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint pt[25];\nint hx[15], hy[15];\nint grid[32][32];\nvector<pair<int,int>> pets;\n\nint dx4[] = {-1,1,0,0};\nint dy4[] = {0,0,-1,1};\nchar mvch[] = {'U','D','L','R'};\n\nbool inb(int x, int y) { return x>=1 && x<=30 && y>=1 && y<=30; }\n\nbool canWall(int x, int y) {\n    if (!inb(x,y)) return false;\n    if (grid[x][y]) return false;\n    for (auto& p : pets) if (p.first==x && p.second==y) return false;\n    for (int i=0;i<M;i++) if (hx[i]==x && hy[i]==y) return false;\n    for (int d=0;d<4;d++) {\n        int nx=x+dx4[d], ny=y+dy4[d];\n        for (auto& p : pets) if (p.first==nx && p.second==ny) return false;\n    }\n    return true;\n}\n\nint TOP_WALL = 11;\nint BOT_WALL = 20;\n\nint main(){\n    cin >> N;\n    pets.resize(N);\n    for (int i=0;i<N;i++){\n        int x,y,t; cin >> x >> y >> t;\n        pets[i]={x,y}; pt[i]=t;\n    }\n    cin >> M;\n    for (int i=0;i<M;i++) cin >> hx[i] >> hy[i];\n    memset(grid,0,sizeof(grid));\n    \n    vector<int> topH, botH;\n    for (int i=0;i<M;i++){\n        if (hx[i] <= 15) topH.push_back(i);\n        else botH.push_back(i);\n    }\n    if (topH.empty() && !botH.empty()) {\n        int half = (botH.size()+1)/2;\n        for (int k=0;k<half;k++) topH.push_back(botH[k]);\n        botH.erase(botH.begin(), botH.begin()+half);\n    } else if (botH.empty() && !topH.empty()) {\n        int half = (topH.size()+1)/2;\n        for (int k=0;k<half;k++) botH.push_back(topH[k]);\n        topH.erase(topH.begin(), topH.begin()+half);\n    }\n    \n    sort(topH.begin(), topH.end(), [](int a, int b){return hy[a]<hy[b];});\n    sort(botH.begin(), botH.end(), [](int a, int b){return hy[a]<hy[b];});\n    \n    vector<vector<tuple<int,int,char>>> tasks(M);\n    \n    auto assignGroup = [&](vector<int>& group, int wallRow, int standDir) {\n        int n = group.size();\n        if (n == 0) return;\n        \n        for (int k=0; k<n; k++){\n            int cs = 1 + k*30/n, ce = (k+1)*30/n;\n            int hi = group[k];\n            int sr = wallRow + standDir;\n            char dir = (standDir == -1) ? 'd' : 'u';\n            vector<int> cols;\n            if (abs(hy[hi] - cs) < abs(hy[hi] - ce)){\n                for (int c = cs; c <= ce; c++) cols.push_back(c);\n            } else {\n                for (int c = ce; c >= cs; c--) cols.push_back(c);\n            }\n            for (int c : cols) tasks[hi].push_back({sr, c, dir});\n        }\n        \n        for (int k=0; k<n-1; k++){\n            int cs_k = 1 + k*30/n, ce_k = (k+1)*30/n;\n            if (ce_k - cs_k < 1) continue;\n            int hi = group[k];\n            int dividerCol = ce_k;\n            int standCol = dividerCol - 1;\n            char dir = 'r';\n            \n            int r_start, r_end, r_step;\n            if (standDir == -1) {\n                r_start = wallRow - 1; r_end = 1; r_step = -1;\n            } else {\n                r_start = wallRow + 1; r_end = 30; r_step = 1;\n            }\n            \n            for (int r = r_start; r != r_end + r_step; r += r_step){\n                tasks[hi].push_back({r, standCol, dir});\n            }\n        }\n    };\n    \n    assignGroup(topH, TOP_WALL, -1);\n    assignGroup(botH, BOT_WALL, +1);\n    \n    vector<int> taskIdx(M, 0);\n    \n    auto wallPos = [&](int sr, int sc, char dir) -> pair<int,int> {\n        if (dir == 'u') return {sr-1, sc};\n        if (dir == 'd') return {sr+1, sc};\n        if (dir == 'l') return {sr, sc-1};\n        return {sr, sc+1};\n    };\n    \n    for (int turn=0; turn<300; turn++){\n        string action(M,'.');\n        vector<pair<int,int>> newWalls;\n        vector<pair<int,int>> nextPos(M);\n        for (int i=0;i<M;i++) nextPos[i] = {hx[i], hy[i]};\n        \n        vector<bool> decided(M, false);\n        \n        for (int i=0;i<M;i++){\n            while (taskIdx[i] < (int)tasks[i].size()){\n                auto [sr, sc, dir] = tasks[i][taskIdx[i]];\n                auto [wr, wc] = wallPos(sr, sc, dir);\n                if (grid[wr][wc]) taskIdx[i]++;\n                else break;\n            }\n        }\n        \n        for (int i=0;i<M;i++){\n            int cx=hx[i], cy=hy[i];\n            if (taskIdx[i] >= (int)tasks[i].size()) { decided[i]=true; continue; }\n            auto [sr, sc, dir] = tasks[i][taskIdx[i]];\n            auto [wr, wc] = wallPos(sr, sc, dir);\n            \n            if (cx == sr && cy == sc){\n                if (canWall(wr, wc)){\n                    action[i] = dir;\n                    newWalls.push_back({wr, wc});\n                    taskIdx[i]++;\n                    decided[i] = true;\n                } else {\n                    action[i]='.';\n                    decided[i] = true;\n                }\n            }\n        }\n        \n        auto isPlannedWall = [&](int x, int y) {\n            for (auto& w : newWalls) if (w.first==x && w.second==y) return true;\n            return false;\n        };\n        auto isOtherDest = [&](int x, int y, int skip) {\n            for (int i=0;i<M;i++) if (i!=skip && nextPos[i].first==x && nextPos[i].second==y) return true;\n            return false;\n        };\n        \n        for (int i=0;i<M;i++){\n            if (decided[i]) continue;\n            int cx=hx[i], cy=hy[i];\n            if (taskIdx[i] >= (int)tasks[i].size()) continue;\n            auto [sr, sc, dir] = tasks[i][taskIdx[i]];\n            \n            vector<vector<int>> dist(32, vector<int>(32, -1));\n            if (inb(sr,sc) && !grid[sr][sc] && !isPlannedWall(sr,sc)){\n                queue<pair<int,int>> q;\n                dist[sr][sc]=0; q.push({sr,sc});\n                while(!q.empty()){\n                    auto [x,y]=q.front(); q.pop();\n                    for (int d=0;d<4;d++){\n                        int nx=x+dx4[d], ny=y+dy4[d];\n                        if (!inb(nx,ny)||grid[nx][ny]||dist[nx][ny]!=-1) continue;\n                        if (isPlannedWall(nx,ny)) continue;\n                        dist[nx][ny]=dist[x][y]+1;\n                        q.push({nx,ny});\n                    }\n                }\n            }\n            \n            bool moved = false;\n            if (dist[cx][cy] > 0){\n                for (int d=0;d<4;d++){\n                    int nx=cx+dx4[d], ny=cy+dy4[d];\n                    if (!inb(nx,ny)||grid[nx][ny]) continue;\n                    if (isPlannedWall(nx,ny)) continue;\n                    if (dist[nx][ny]==dist[cx][cy]-1 && !isOtherDest(nx,ny,i)){\n                        action[i]=mvch[d];\n                        nextPos[i]={nx,ny};\n                        moved = true;\n                        break;\n                    }\n                }\n            }\n            \n            if (!moved && dist[cx][cy] == -1) {\n                taskIdx[i]++;\n            }\n        }\n        \n        for (int i=0;i<M;i++){\n            char a = action[i];\n            if (a=='U'||a=='D'||a=='L'||a=='R'){\n                if (isPlannedWall(nextPos[i].first, nextPos[i].second)){\n                    action[i] = '.';\n                    nextPos[i] = {hx[i], hy[i]};\n                }\n            }\n        }\n        \n        cout << action << endl;\n        cout.flush();\n        \n        for (int i=0;i<M;i++){\n            char a = action[i];\n            if (a=='U'||a=='D'||a=='L'||a=='R'){\n                int d = (a=='U')?0:(a=='D')?1:(a=='L')?2:3;\n                hx[i]+=dx4[d]; hy[i]+=dy4[d];\n            }\n        }\n        for (auto& w : newWalls) grid[w.first][w.second]=1;\n        \n        for (int i=0;i<N;i++){\n            string s; cin >> s;\n            int x=pets[i].first, y=pets[i].second;\n            for (char c : s){\n                if (c=='U') x--;\n                else if (c=='D') x++;\n                else if (c=='L') y--;\n                else if (c=='R') y++;\n            }\n            pets[i]={x,y};\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si,sj,ti,tj;\ndouble p;\nint H[20][19], V[19][20];\nint nextIdx[4][400];\nint dirOf[256];\nint start_idx_g, goal_idx_g;\ndouble pp_g, q_g;\n\nvoid buildTransitions(){\n    for(int i=0;i<20;i++)for(int j=0;j<20;j++){\n        int idx=i*20+j;\n        if(i>0 && V[i-1][j]==0) nextIdx[0][idx]=(i-1)*20+j; else nextIdx[0][idx]=idx;\n        if(i<19 && V[i][j]==0) nextIdx[1][idx]=(i+1)*20+j; else nextIdx[1][idx]=idx;\n        if(j>0 && H[i][j-1]==0) nextIdx[2][idx]=i*20+(j-1); else nextIdx[2][idx]=idx;\n        if(j<19 && H[i][j]==0) nextIdx[3][idx]=i*20+(j+1); else nextIdx[3][idx]=idx;\n    }\n    dirOf[(int)'U']=0; dirOf[(int)'D']=1; dirOf[(int)'L']=2; dirOf[(int)'R']=3;\n}\n\ndouble evalScore(const string& s){\n    static double dist[400], nd[400];\n    for(int i=0;i<400;i++) dist[i]=0;\n    dist[start_idx_g]=1.0;\n    if(start_idx_g==goal_idx_g) return 400.0;\n    double score=0;\n    int L=s.size();\n    for(int t=0;t<L;t++){\n        int d=dirOf[(int)(unsigned char)s[t]];\n        const int* nxt=nextIdx[d];\n        for(int i=0;i<400;i++) nd[i]=0;\n        for(int idx=0;idx<400;idx++){\n            double dv=dist[idx];\n            if(dv==0) continue;\n            int nxi=nxt[idx];\n            if(nxi==idx){\n                nd[idx] += dv;\n            } else {\n                nd[idx] += dv*pp_g;\n                nd[nxi] += dv*q_g;\n            }\n        }\n        double arrived = nd[goal_idx_g];\n        score += arrived * (400 - t);\n        nd[goal_idx_g]=0;\n        memcpy(dist,nd,sizeof(dist));\n    }\n    return score;\n}\n\nbool canMove(int i,int j,char c){\n    int idx=i*20+j;\n    return nextIdx[dirOf[(int)(unsigned char)c]][idx]!=idx;\n}\npair<int,int> moveXY(int i,int j,char c){\n    int idx=i*20+j;\n    int nxi=nextIdx[dirOf[(int)(unsigned char)c]][idx];\n    return {nxi/20, nxi%20};\n}\n\nvector<string> findPaths(int maxPaths, mt19937& rng){\n    vector<string> paths;\n    set<string> seen;\n    string dirs=\"UDLR\";\n    auto bfsPath=[&](string order)->string{\n        vector<vector<int>> bd(20,vector<int>(20,-1));\n        vector<vector<pair<int,int>>> par(20,vector<pair<int,int>>(20,{-1,-1}));\n        vector<vector<char>> pc(20,vector<char>(20,0));\n        queue<pair<int,int>> q;\n        q.push({si,sj}); bd[si][sj]=0;\n        while(!q.empty()){\n            auto [i,j]=q.front(); q.pop();\n            for(char c:order){\n                if(canMove(i,j,c)){\n                    auto [ni,nj]=moveXY(i,j,c);\n                    if(bd[ni][nj]==-1){\n                        bd[ni][nj]=bd[i][j]+1;\n                        par[ni][nj]={i,j};\n                        pc[ni][nj]=c;\n                        q.push({ni,nj});\n                    }\n                }\n            }\n        }\n        if(bd[ti][tj]==-1) return \"\";\n        string path;\n        int ci=ti,cj=tj;\n        while(!(ci==si&&cj==sj)){\n            path+=pc[ci][cj];\n            auto [pi,pj]=par[ci][cj];\n            ci=pi; cj=pj;\n        }\n        reverse(path.begin(),path.end());\n        return path;\n    };\n    string p1=bfsPath(\"UDLR\");\n    paths.push_back(p1); seen.insert(p1);\n    int shortestLen=p1.size();\n    for(int attempt=0; attempt<500 && (int)paths.size()<maxPaths; attempt++){\n        string d=dirs;\n        shuffle(d.begin(),d.end(),rng);\n        string path=bfsPath(d);\n        if(!path.empty() && (int)path.size() <= shortestLen+6 && !seen.count(path)){\n            paths.push_back(path);\n            seen.insert(path);\n        }\n    }\n    return paths;\n}\n\nchrono::steady_clock::time_point g_start;\nlong long elapsedMs(){\n    auto now=chrono::steady_clock::now();\n    return (long long)chrono::duration_cast<chrono::milliseconds>(now-g_start).count();\n}\n\nstring g_best;\ndouble g_bestScore;\nstring dirs=\"UDLR\";\n\nvoid localSearch(string& cur, double& curScore, long long timeLimit){\n    bool improved=true;\n    while(improved && elapsedMs()<timeLimit){\n        improved=false;\n        // substitution\n        for(int pos=0;pos<(int)cur.size() && elapsedMs()<timeLimit;pos++){\n            char orig=cur[pos];\n            char bestC=orig;\n            double bestSc=curScore;\n            for(char c : dirs){\n                if(c==orig) continue;\n                cur[pos]=c;\n                double sc=evalScore(cur);\n                if(sc>bestSc+1e-9){bestSc=sc; bestC=c;}\n            }\n            cur[pos]=bestC;\n            if(bestC!=orig){curScore=bestSc; improved=true;}\n        }\n        // swap adjacent\n        for(int pos=0;pos+1<(int)cur.size() && elapsedMs()<timeLimit;pos++){\n            if(cur[pos]==cur[pos+1]) continue;\n            swap(cur[pos],cur[pos+1]);\n            double sc=evalScore(cur);\n            if(sc>curScore+1e-9){curScore=sc; improved=true;}\n            else swap(cur[pos],cur[pos+1]);\n        }\n        // single deletion\n        for(int pos=0;pos<(int)cur.size() && elapsedMs()<timeLimit;pos++){\n            string cand=cur;\n            cand.erase(cand.begin()+pos);\n            double sc=evalScore(cand);\n            if(sc>curScore+1e-9){curScore=sc; cur=cand; improved=true; pos--;}\n        }\n        // single insertion\n        for(int pos=0;pos<=(int)cur.size() && (int)cur.size()<200 && elapsedMs()<timeLimit;pos++){\n            char bestC=0;\n            double bestSc=curScore;\n            for(char c : dirs){\n                string cand=cur;\n                cand.insert(cand.begin()+pos,c);\n                double sc=evalScore(cand);\n                if(sc>bestSc+1e-9){bestSc=sc; bestC=c;}\n            }\n            if(bestC){\n                cur.insert(cur.begin()+pos,bestC);\n                curScore=bestSc;\n                improved=true;\n            }\n        }\n        // block deletion (2 chars)\n        for(int pos=0;pos+1<(int)cur.size() && elapsedMs()<timeLimit;pos++){\n            string cand=cur;\n            cand.erase(cand.begin()+pos, cand.begin()+pos+2);\n            double sc=evalScore(cand);\n            if(sc>curScore+1e-9){curScore=sc; cur=cand; improved=true; pos--;}\n        }\n        // block insertion (2 chars, same)\n        for(int pos=0;pos<=(int)cur.size() && (int)cur.size()+2<=200 && elapsedMs()<timeLimit;pos++){\n            char bestC=0;\n            double bestSc=curScore;\n            for(char c : dirs){\n                string cand=cur;\n                cand.insert(pos, 2, c);\n                double sc=evalScore(cand);\n                if(sc>bestSc+1e-9){bestSc=sc; bestC=c;}\n            }\n            if(bestC){\n                cur.insert(pos,2,bestC);\n                curScore=bestSc;\n                improved=true;\n            }\n        }\n    }\n    if(curScore > g_bestScore){\n        g_bestScore = curScore;\n        g_best = cur;\n    }\n}\n\nint main(){\n    cin>>si>>sj>>ti>>tj>>p;\n    for(int i=0;i<20;i++){\n        string s; cin>>s;\n        for(int j=0;j<19;j++) H[i][j]=s[j]-'0';\n    }\n    for(int i=0;i<19;i++){\n        string s; cin>>s;\n        for(int j=0;j<20;j++) V[i][j]=s[j]-'0';\n    }\n    buildTransitions();\n    start_idx_g = si*20+sj;\n    goal_idx_g = ti*20+tj;\n    pp_g = p; q_g = 1-p;\n    \n    g_start = chrono::steady_clock::now();\n    \n    mt19937 rng(42);\n    vector<string> paths = findPaths(25, rng);\n    \n    vector<pair<double,string>> candidates;\n    for(auto& path : paths){\n        int L=path.size();\n        if(L==0) continue;\n        for(int k=1; k*L<=200; k++){\n            string cand;\n            for(char c:path) for(int r=0;r<k;r++) cand+=c;\n            candidates.push_back({evalScore(cand), cand});\n        }\n        for(int k=1; k*L<=200; k++){\n            string cand;\n            for(char c:path) for(int r=0;r<k;r++) cand+=c;\n            while((int)cand.size()<200) cand+=path.back();\n            candidates.push_back({evalScore(cand), cand});\n        }\n    }\n    sort(candidates.begin(),candidates.end(),[](auto&a,auto&b){return a.first>b.first;});\n    \n    g_best = candidates[0].second;\n    g_bestScore = candidates[0].first;\n    \n    // Phase 1: Local search top candidate briefly\n    {\n        string cur = g_best;\n        double curScore = g_bestScore;\n        localSearch(cur, curScore, 600);\n    }\n    \n    // Phase 2: Try top-3 candidates if time permits\n    for(int ci=1; ci<3 && ci<(int)candidates.size() && elapsedMs()<900; ci++){\n        if(candidates[ci].first < g_bestScore * 0.7) break;\n        string cur = candidates[ci].second;\n        double curScore = candidates[ci].first;\n        long long budget = elapsedMs() + 200;\n        if(budget>900) budget=900;\n        localSearch(cur, curScore, budget);\n    }\n    \n    // Phase 3: Random perturbation restarts from best\n    int stuckCount=0;\n    while(elapsedMs() < 1850){\n        string cur = g_best;\n        double curScore = g_bestScore;\n        // Perturbation strength grows with stuck count\n        int strength = 3 + stuckCount;\n        if(strength > 12) strength = 12;\n        int numPerturb = strength + (int)(rng()%3);\n        for(int i=0;i<numPerturb;i++){\n            if(cur.empty()) break;\n            int op = (int)(rng()%5);\n            if(op==0){ // substitute\n                int pos=(int)(rng()%cur.size());\n                cur[pos]=dirs[rng()%4];\n            } else if(op==1 && (int)cur.size()>=2){ // swap\n                int pos=(int)(rng()%(cur.size()-1));\n                swap(cur[pos],cur[pos+1]);\n            } else if(op==2 && cur.size()>1){ // delete\n                int pos=(int)(rng()%cur.size());\n                cur.erase(cur.begin()+pos);\n            } else if(op==3 && (int)cur.size()<200){ // insert\n                int pos=(int)(rng()%(cur.size()+1));\n                cur.insert(cur.begin()+pos,dirs[rng()%4]);\n            } else { // block insert\n                if((int)cur.size()+2<=200){\n                    int pos=(int)(rng()%(cur.size()+1));\n                    char c=dirs[rng()%4];\n                    cur.insert(pos, 2, c);\n                }\n            }\n        }\n        curScore = evalScore(cur);\n        long long localBudget = elapsedMs() + 250;\n        if(localBudget > 1900) localBudget = 1900;\n        double prevBest = g_bestScore;\n        localSearch(cur, curScore, localBudget);\n        if(g_bestScore > prevBest + 1e-6){\n            stuckCount = 0;\n        } else {\n            stuckCount++;\n        }\n    }\n    \n    // Final polish\n    {\n        string cur = g_best;\n        double curScore = g_bestScore;\n        localSearch(cur, curScore, 1990);\n    }\n    \n    cout<<g_best<<endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int to_dir[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\nstatic const int di[4] = {0, -1, 0, 1};\nstatic const int dj[4] = {-1, 0, 1, 0};\nstatic const int rot1[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n\nstatic int tiles[30][30];\nstatic int visited[30][30][4];\nstatic int gen = 0;\n\nstruct EvalRes {\n    long long score;\n    long long sumSq;\n};\n\ninline EvalRes evaluate() {\n    gen++;\n    int L1 = 0, L2 = 0;\n    long long sumSq = 0;\n    for (int si = 0; si < 30; si++) {\n        for (int sj = 0; sj < 30; sj++) {\n            for (int sd = 0; sd < 4; sd++) {\n                if (visited[si][sj][sd] == gen) continue;\n                int i = si, j = sj, d = sd;\n                int len = 0;\n                while (true) {\n                    if (visited[i][j][d] == gen) break;\n                    visited[i][j][d] = gen;\n                    int d2 = to_dir[tiles[i][j]][d];\n                    if (d2 < 0) break;\n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if ((unsigned)ni >= 30 || (unsigned)nj >= 30) break;\n                    int nd = d2 ^ 2;\n                    len++;\n                    if (ni == si && nj == sj && nd == sd) {\n                        if (len > L1) { L2 = L1; L1 = len; }\n                        else if (len > L2) L2 = len;\n                        sumSq += (long long)len * len;\n                        break;\n                    }\n                    i = ni; j = nj; d = nd;\n                }\n            }\n        }\n    }\n    return {(long long)L1 * L2, sumSq};\n}\n\nstatic int rot[30][30];\nstatic int bestRot[30][30];\nstatic int inputG[30][30];\n\ninline void applyRot(int i, int j, int r) {\n    rot[i][j] = r;\n    int t = inputG[i][j];\n    for (int k = 0; k < r; k++) t = rot1[t];\n    tiles[i][j] = t;\n}\n\nstatic uint64_t xrand_state = 0x12345678abcdef01ULL;\ninline uint64_t xrand() {\n    uint64_t x = xrand_state;\n    x ^= x << 13;\n    x ^= x >> 7;\n    x ^= x << 17;\n    xrand_state = x;\n    return x;\n}\ninline double frand() {\n    return (double)(xrand() & 0xFFFFFFFFULL) / (double)0x100000000ULL;\n}\n\nint main() {\n    for (int i = 0; i < 30; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < 30; j++) inputG[i][j] = s[j]-'0';\n    }\n    \n    long long bestScore = 0;\n    long long bestSumSq = 0;\n    auto start = chrono::steady_clock::now();\n    double TL_SA = 1.80;\n    double TL_FINAL = 1.92;\n    \n    int restart = 0;\n    bool done = false;\n    while (!done) {\n        auto now = chrono::steady_clock::now();\n        double elapsedTotal = chrono::duration<double>(now-start).count();\n        if (elapsedTotal > TL_SA - 0.02) break;\n        \n        restart++;\n        for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) {\n            int r = (restart == 1) ? 0 : (int)(xrand()%4);\n            applyRot(i, j, r);\n        }\n        \n        auto cur = evaluate();\n        if (cur.score > bestScore || (cur.score == bestScore && cur.sumSq > bestSumSq)) {\n            bestScore = cur.score;\n            bestSumSq = cur.sumSq;\n            memcpy(bestRot, rot, sizeof(rot));\n        }\n        \n        double restartBudget = 0.90;\n        if (TL_SA - elapsedTotal < restartBudget) restartBudget = TL_SA - elapsedTotal;\n        if (restartBudget < 0.05) break;\n        double restartStart = elapsedTotal;\n        \n        double T0 = 2000.0, T1 = 1.0;\n        int iter = 0;\n        double localElapsed = 0;\n        double scoreWeight = 0.0;\n        \n        long long curProxyVal = cur.sumSq;\n        \n        while (true) {\n            iter++;\n            if ((iter & 255) == 0) {\n                double e = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n                localElapsed = e - restartStart;\n                if (e > TL_SA) { done = true; break; }\n                if (localElapsed > restartBudget) break;\n                double prog = localElapsed / restartBudget;\n                if (prog > 1) prog = 1;\n                if (prog < 0.5) scoreWeight = 0.0;\n                else {\n                    double r = (prog - 0.5) * 2.0;\n                    scoreWeight = 100.0 * r * r;\n                }\n                curProxyVal = cur.sumSq + (long long)(scoreWeight * (double)cur.score);\n            }\n            double progress = localElapsed / restartBudget;\n            if (progress > 1) progress = 1;\n            double T = T0 * pow(T1/T0, progress);\n            \n            int mtype = (int)(xrand()%10);\n            if (mtype < 7) {\n                int i = (int)(xrand()%30), j = (int)(xrand()%30);\n                int oldR = rot[i][j];\n                int newR = (oldR + 1 + (int)(xrand()%3)) & 3;\n                applyRot(i, j, newR);\n                auto nw = evaluate();\n                long long nwProxy = nw.sumSq + (long long)(scoreWeight * (double)nw.score);\n                long long delta = nwProxy - curProxyVal;\n                if (delta >= 0 || frand() < exp((double)delta/T)) {\n                    cur = nw;\n                    curProxyVal = nwProxy;\n                    if (nw.score > bestScore || (nw.score == bestScore && nw.sumSq > bestSumSq)) {\n                        bestScore = nw.score;\n                        bestSumSq = nw.sumSq;\n                        memcpy(bestRot, rot, sizeof(rot));\n                    }\n                } else {\n                    applyRot(i, j, oldR);\n                }\n            } else {\n                int i1 = (int)(xrand()%30), j1 = (int)(xrand()%30);\n                int i2 = (int)(xrand()%30), j2 = (int)(xrand()%30);\n                int oldR1 = rot[i1][j1], oldR2 = rot[i2][j2];\n                int newR1 = (oldR1 + 1 + (int)(xrand()%3)) & 3;\n                int newR2 = (oldR2 + 1 + (int)(xrand()%3)) & 3;\n                applyRot(i1, j1, newR1);\n                applyRot(i2, j2, newR2);\n                auto nw = evaluate();\n                long long nwProxy = nw.sumSq + (long long)(scoreWeight * (double)nw.score);\n                long long delta = nwProxy - curProxyVal;\n                if (delta >= 0 || frand() < exp((double)delta/T)) {\n                    cur = nw;\n                    curProxyVal = nwProxy;\n                    if (nw.score > bestScore || (nw.score == bestScore && nw.sumSq > bestSumSq)) {\n                        bestScore = nw.score;\n                        bestSumSq = nw.sumSq;\n                        memcpy(bestRot, rot, sizeof(rot));\n                    }\n                } else {\n                    applyRot(i1, j1, oldR1);\n                    applyRot(i2, j2, oldR2);\n                }\n            }\n        }\n    }\n    \n    // Final hill climb from bestRot, prioritizing score then sumSq\n    {\n        for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) {\n            if (rot[i][j] != bestRot[i][j]) applyRot(i, j, bestRot[i][j]);\n        }\n        auto cur = evaluate();\n        long long curObj = cur.score * 1000LL + cur.sumSq;\n        int iter = 0;\n        while (true) {\n            iter++;\n            if ((iter & 127) == 0) {\n                double e = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n                if (e > TL_FINAL) break;\n            }\n            int mtype = (int)(xrand()%10);\n            if (mtype < 8) {\n                int i = (int)(xrand()%30), j = (int)(xrand()%30);\n                int oldR = rot[i][j];\n                int newR = (oldR + 1 + (int)(xrand()%3)) & 3;\n                applyRot(i, j, newR);\n                auto nw = evaluate();\n                long long nwObj = nw.score * 1000LL + nw.sumSq;\n                if (nwObj >= curObj) {\n                    curObj = nwObj;\n                    if (nw.score > bestScore || (nw.score == bestScore && nw.sumSq > bestSumSq)) {\n                        bestScore = nw.score;\n                        bestSumSq = nw.sumSq;\n                        memcpy(bestRot, rot, sizeof(rot));\n                    }\n                } else {\n                    applyRot(i, j, oldR);\n                }\n            } else {\n                int i1 = (int)(xrand()%30), j1 = (int)(xrand()%30);\n                int i2 = (int)(xrand()%30), j2 = (int)(xrand()%30);\n                int oldR1 = rot[i1][j1], oldR2 = rot[i2][j2];\n                int newR1 = (oldR1 + 1 + (int)(xrand()%3)) & 3;\n                int newR2 = (oldR2 + 1 + (int)(xrand()%3)) & 3;\n                applyRot(i1, j1, newR1);\n                applyRot(i2, j2, newR2);\n                auto nw = evaluate();\n                long long nwObj = nw.score * 1000LL + nw.sumSq;\n                if (nwObj >= curObj) {\n                    curObj = nwObj;\n                    if (nw.score > bestScore || (nw.score == bestScore && nw.sumSq > bestSumSq)) {\n                        bestScore = nw.score;\n                        bestSumSq = nw.sumSq;\n                        memcpy(bestRot, rot, sizeof(rot));\n                    }\n                } else {\n                    applyRot(i1, j1, oldR1);\n                    applyRot(i2, j2, oldR2);\n                }\n            }\n        }\n    }\n    \n    string out;\n    for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) out += char('0'+bestRot[i][j]);\n    cout << out << endl;\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nmt19937 rng(98765);\nint er, ec;\nvector<vector<int>> board;\nvector<vector<int>> boardT;\nint erT, ecT;\n\nint computeTreeScore(const vector<vector<int>>& b) {\n    int n = N;\n    vector<int> par(n*n), sz(n*n, 1);\n    vector<bool> bad(n*n, false);\n    iota(par.begin(), par.end(), 0);\n    function<int(int)> find = [&](int x){ while(par[x]!=x){par[x]=par[par[x]];x=par[x];} return x;};\n    auto unite = [&](int a, int b){\n        int ra=find(a), rb=find(b);\n        if(ra==rb){ bad[ra]=true; return;}\n        bool nb = bad[ra]||bad[rb];\n        if(sz[ra]<sz[rb])swap(ra,rb);\n        par[rb]=ra; sz[ra]+=sz[rb]; bad[ra]=nb;\n    };\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        if(b[i][j]==0) continue;\n        if(j+1<n && b[i][j+1]!=0 && (b[i][j]&4) && (b[i][j+1]&1)) unite(i*n+j, i*n+j+1);\n        if(i+1<n && b[i+1][j]!=0 && (b[i][j]&8) && (b[i+1][j]&2)) unite(i*n+j, (i+1)*n+j);\n    }\n    int best=0;\n    for(int i=0;i<n*n;i++){\n        if(b[i/n][i%n]==0) continue;\n        if(find(i)==i && !bad[i]) best=max(best,sz[i]);\n    }\n    return best;\n}\n\nint computeBoundaryPenalty(const vector<vector<int>>& b) {\n    int n = N, penalty = 0;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        int v = b[i][j]; if(v==0) continue;\n        if((v&1) && j==0) penalty++;\n        if((v&2) && i==0) penalty++;\n        if((v&4) && j==n-1) penalty++;\n        if((v&8) && i==n-1) penalty++;\n    }\n    return penalty;\n}\n\nint computeManhattan(const vector<vector<int>>& tgt){\n    vector<vector<pair<int,int>>> boardPos(16), tgtPos(16);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(board[i][j]) boardPos[board[i][j]].push_back({i,j});\n        if(tgt[i][j]) tgtPos[tgt[i][j]].push_back({i,j});\n    }\n    int total = 0;\n    for(int tp=1; tp<16; tp++){\n        auto& posB = boardPos[tp];\n        auto& posT = tgtPos[tp];\n        if(posB.size() != posT.size()) return INT_MAX;\n        sort(posB.begin(), posB.end());\n        sort(posT.begin(), posT.end());\n        for(int k=0; k<(int)posB.size(); k++){\n            total += abs(posB[k].first - posT[k].first) + abs(posB[k].second - posT[k].second);\n        }\n    }\n    return total;\n}\n\nstring solveFromTargetRand(vector<vector<int>> tgt, vector<vector<int>> startBoard, int startR, int startC, int rseed){\n    mt19937 localRng(rseed);\n    vector<vector<int>> B = startBoard;\n    int br=startR, bc=startC;\n    string moves;\n    vector<vector<bool>> locked(N, vector<bool>(N, false));\n    bool solveFailed = false;\n    \n    auto posOk = [&](int r, int c){ return r>=0&&r<N&&c>=0&&c<N; };\n    \n    auto moveBlankTo = [&](int tr, int tc, int avoidR, int avoidC)->bool{\n        if(br==tr&&bc==tc) return true;\n        if(!posOk(tr,tc)) return false;\n        if(locked[tr][tc]) return false;\n        if(tr==avoidR&&tc==avoidC) return false;\n        vector<vector<int>> dist(N, vector<int>(N,-1));\n        vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N,{-1,-1}));\n        queue<pair<int,int>> q;\n        dist[br][bc]=0; q.push({br,bc});\n        int dirs[4] = {0,1,2,3};\n        for(int i=3;i>0;i--) swap(dirs[i], dirs[localRng()%(i+1)]);\n        int dr[]={-1,1,0,0}, dc[]={0,0,-1,1};\n        while(!q.empty()){\n            auto [r,c]=q.front(); q.pop();\n            for(int di=0;di<4;di++){\n                int d = dirs[di];\n                int nr=r+dr[d], nc=c+dc[d];\n                if(!posOk(nr,nc)) continue;\n                if(locked[nr][nc]) continue;\n                if(nr==avoidR&&nc==avoidC) continue;\n                if(dist[nr][nc]!=-1) continue;\n                dist[nr][nc]=dist[r][c]+1;\n                par[nr][nc]={r,c};\n                q.push({nr,nc});\n            }\n        }\n        if(dist[tr][tc]==-1) return false;\n        vector<pair<int,int>> path;\n        int r=tr,c=tc;\n        while(!(r==br&&c==bc)){\n            path.push_back({r,c});\n            auto [pr,pc]=par[r][c]; r=pr; c=pc;\n        }\n        reverse(path.begin(), path.end());\n        for(auto [nr,nc]:path){\n            char mv;\n            if(nr==br-1&&nc==bc) mv='U';\n            else if(nr==br+1&&nc==bc) mv='D';\n            else if(nc==bc-1&&nr==br) mv='L';\n            else mv='R';\n            moves.push_back(mv);\n            swap(B[br][bc], B[nr][nc]);\n            br=nr; bc=nc;\n        }\n        return true;\n    };\n    \n    auto findTile = [&](int type, int nearR, int nearC)->pair<int,int>{\n        int minD = INT_MAX;\n        vector<pair<int,int>> best;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            if(locked[i][j]) continue;\n            if(B[i][j]==type){\n                int d=abs(i-nearR)+abs(j-nearC);\n                if(d<minD){ minD=d; best.clear(); best.push_back({i,j}); }\n                else if(d==minD) best.push_back({i,j});\n            }\n        }\n        if(best.empty()) return {-1,-1};\n        return best[localRng()%best.size()];\n    };\n    \n    auto moveTileTo = [&](int& sr, int& sc, int tr, int tc)->bool{\n        int safety = 0;\n        while(sr!=tr || sc!=tc){\n            if(++safety > 4*N*N) return false;\n            vector<pair<int,int>> candidates;\n            if(sr!=tr){\n                if(sr<tr) candidates.push_back({sr+1, sc}); else candidates.push_back({sr-1, sc});\n            }\n            if(sc!=tc){\n                if(sc<tc) candidates.push_back({sr, sc+1}); else candidates.push_back({sr, sc-1});\n            }\n            if(candidates.size()==2 && (localRng()&1)) swap(candidates[0], candidates[1]);\n            bool moved=false;\n            for(auto [cnr, cnc] : candidates){\n                if(!posOk(cnr,cnc)) continue;\n                if(locked[cnr][cnc]) continue;\n                int saveBr=br, saveBc=bc;\n                size_t saveMl = moves.size();\n                auto saveB = B;\n                if(moveBlankTo(cnr,cnc,sr,sc)){\n                    moved=true; break;\n                }\n                br=saveBr; bc=saveBc; moves.resize(saveMl); B=saveB;\n            }\n            if(!moved) return false;\n            char mv;\n            if(sr==br-1&&sc==bc) mv='U';\n            else if(sr==br+1&&sc==bc) mv='D';\n            else if(sc==bc-1&&sr==br) mv='L';\n            else if(sc==bc+1&&sr==br) mv='R';\n            else return false;\n            moves.push_back(mv);\n            swap(B[br][bc], B[sr][sc]);\n            int obr=br, obc=bc;\n            br=sr; bc=sc;\n            sr=obr; sc=obc;\n        }\n        return true;\n    };\n    \n    for(int r=0; r<N-2 && !solveFailed; r++){\n        for(int c=0; c<N-2; c++){\n            int type = tgt[r][c];\n            auto [sr,sc] = findTile(type, r, c);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==r&&sc==c)){\n                if(!moveTileTo(sr,sc,r,c)){solveFailed=true; break;}\n            }\n            locked[r][c]=true;\n        }\n        if(solveFailed) break;\n        \n        int typeA = tgt[r][N-2];\n        int typeB = tgt[r][N-1];\n        \n        if(B[r][N-2]==typeA && B[r][N-1]==typeB){\n            locked[r][N-2]=true; locked[r][N-1]=true;\n            continue;\n        }\n        \n        {\n            auto [sr,sc] = findTile(typeA, r, N-1);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==r && sc==N-1)){\n                if(sr==r && sc==N-2){\n                    if(!moveTileTo(sr,sc, r+1, N-2)){solveFailed=true; break;}\n                    auto p = findTile(typeA, r, N-1);\n                    sr=p.first; sc=p.second;\n                    if(sr==-1){solveFailed=true; break;}\n                }\n                if(!moveTileTo(sr, sc, r, N-1)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[r][N-1]=true;\n        \n        {\n            auto [sr,sc] = findTile(typeB, r+1, N-1);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==r+1 && sc==N-1)){\n                if(!moveTileTo(sr, sc, r+1, N-1)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[r+1][N-1]=true;\n        \n        locked[r][N-1]=false; locked[r+1][N-1]=false;\n        \n        if(!moveBlankTo(r, N-2, -1, -1)){solveFailed=true; break;}\n        moves.push_back('R');\n        swap(B[br][bc], B[r][N-1]); br=r; bc=N-1;\n        moves.push_back('D');\n        swap(B[br][bc], B[r+1][N-1]); br=r+1; bc=N-1;\n        \n        locked[r][N-2]=true; locked[r][N-1]=true;\n    }\n    \n    for(int c=0; c<N-2 && !solveFailed; c++){\n        int typeA = tgt[N-2][c];\n        int typeB = tgt[N-1][c];\n        \n        if(B[N-2][c]==typeA && B[N-1][c]==typeB){\n            locked[N-2][c]=true; locked[N-1][c]=true;\n            continue;\n        }\n        \n        {\n            auto [sr,sc] = findTile(typeA, N-1, c);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==N-1 && sc==c)){\n                if(sr==N-2 && sc==c){\n                    if(!moveTileTo(sr,sc, N-2, c+1)){solveFailed=true; break;}\n                    auto p = findTile(typeA, N-1, c);\n                    sr=p.first; sc=p.second;\n                    if(sr==-1){solveFailed=true; break;}\n                }\n                if(!moveTileTo(sr, sc, N-1, c)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[N-1][c]=true;\n        \n        {\n            auto [sr,sc] = findTile(typeB, N-1, c+1);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==N-1 && sc==c+1)){\n                if(!moveTileTo(sr, sc, N-1, c+1)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[N-1][c+1]=true;\n        \n        locked[N-1][c]=false; locked[N-1][c+1]=false;\n        \n        if(!moveBlankTo(N-2, c, -1, -1)){solveFailed=true; break;}\n        moves.push_back('D'); swap(B[br][bc], B[N-1][c]); br=N-1; bc=c;\n        moves.push_back('R'); swap(B[br][bc], B[N-1][c+1]); br=N-1; bc=c+1;\n        locked[N-2][c]=true; locked[N-1][c]=true;\n    }\n    \n    if(!solveFailed){\n        for(int attempt=0; attempt<8; attempt++){\n            bool match = (B[N-2][N-2]==tgt[N-2][N-2]) && (B[N-2][N-1]==tgt[N-2][N-1]) && (B[N-1][N-2]==tgt[N-1][N-2]);\n            if(match && br==N-1 && bc==N-1) break;\n            if(br==N-1&&bc==N-1){ moves.push_back('U'); swap(B[br][bc],B[N-2][N-1]); br=N-2;bc=N-1;}\n            else if(br==N-2&&bc==N-1){ moves.push_back('L'); swap(B[br][bc],B[N-2][N-2]); br=N-2;bc=N-2;}\n            else if(br==N-2&&bc==N-2){ moves.push_back('D'); swap(B[br][bc],B[N-1][N-2]); br=N-1;bc=N-2;}\n            else if(br==N-1&&bc==N-2){ moves.push_back('R'); swap(B[br][bc],B[N-1][N-1]); br=N-1;bc=N-1;}\n        }\n    }\n    \n    return moves;\n}\n\nvector<vector<int>> transposeBoard(const vector<vector<int>>& b){\n    vector<vector<int>> res(N, vector<int>(N));\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        int v = b[j][i];\n        int nv = 0;\n        if(v&1) nv|=2;\n        if(v&2) nv|=1;\n        if(v&4) nv|=8;\n        if(v&8) nv|=4;\n        res[i][j] = nv;\n    }\n    return res;\n}\n\nstring transposeMoves(const string& mv){\n    string res;\n    res.reserve(mv.size());\n    for(char c:mv){\n        if(c=='U') res+='L';\n        else if(c=='L') res+='U';\n        else if(c=='D') res+='R';\n        else res+='D';\n    }\n    return res;\n}\n\nstring eliminateCycles(const string& mv){\n    vector<vector<int>> B = board;\n    int br=er, bc=ec;\n    auto hashState = [&]() -> uint64_t {\n        uint64_t h = 1469598103934665603ULL;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            h = h*131 + (uint64_t)B[i][j];\n        }\n        h = h*131 + (uint64_t)(br*N+bc);\n        return h;\n    };\n    vector<uint64_t> hashes;\n    hashes.reserve(mv.size()+1);\n    hashes.push_back(hashState());\n    for(int i=0;i<(int)mv.size();i++){\n        char m = mv[i];\n        int nr=br, nc=bc;\n        if(m=='U') nr--;\n        else if(m=='D') nr++;\n        else if(m=='L') nc--;\n        else nc++;\n        if(nr<0||nr>=N||nc<0||nc>=N) { hashes.push_back(hashes.back()); continue; }\n        swap(B[br][bc], B[nr][nc]);\n        br=nr; bc=nc;\n        hashes.push_back(hashState());\n    }\n    unordered_map<uint64_t, int> lastIdx;\n    lastIdx.reserve(hashes.size()*2);\n    for(int i=(int)hashes.size()-1;i>=0;i--){\n        if(lastIdx.find(hashes[i])==lastIdx.end()){\n            lastIdx[hashes[i]] = i;\n        }\n    }\n    string result;\n    int i = 0;\n    int total = (int)mv.size();\n    while(i < total){\n        auto it = lastIdx.find(hashes[i]);\n        int jump = (it != lastIdx.end()) ? it->second : i;\n        if(jump > i){\n            i = jump; continue;\n        }\n        result.push_back(mv[i]);\n        i++;\n    }\n    return result;\n}\n\npair<string,int> processMoves(const string& mv){\n    vector<vector<int>> BB = board;\n    int bbr=er, bbc=ec;\n    int curS = computeTreeScore(BB);\n    int bestS = curS;\n    int bestLen = 0;\n    int fullLen = mv.size();\n    int lim = min(fullLen, T);\n    for(int i=0;i<lim;i++){\n        char m = mv[i];\n        int nr=bbr, nc=bbc;\n        if(m=='U') nr--;\n        else if(m=='D') nr++;\n        else if(m=='L') nc--;\n        else nc++;\n        if(nr<0||nr>=N||nc<0||nc>=N) break;\n        swap(BB[bbr][bbc], BB[nr][nc]);\n        bbr=nr; bbc=nc;\n        curS = computeTreeScore(BB);\n        if(curS > bestS){ bestS=curS; bestLen=i+1; }\n        if(curS == N*N-1){\n            return {mv.substr(0, i+1), curS};\n        }\n    }\n    return {mv.substr(0, bestLen), bestS};\n}\n\ndouble evalResult(const string& mv, int s){\n    if(s == N*N-1 && (int)mv.size() <= T){\n        return 500000.0 * (2.0 - (double)mv.size()/T);\n    }\n    return 500000.0 * s / (N*N-1);\n}\n\nstring bestMoves = \"\";\nint bestFinalScore = 0;\nvector<vector<int>> bestTargetUsed;\n\nbool updateBest(const string& mv, int s, const vector<vector<int>>& tgt){\n    double ev = evalResult(mv, s);\n    double bv = evalResult(bestMoves, bestFinalScore);\n    if(ev > bv){\n        bestMoves = mv;\n        bestFinalScore = s;\n        bestTargetUsed = tgt;\n        return true;\n    }\n    return false;\n}\n\nvoid attemptSolve(const vector<vector<int>>& tgt, const vector<vector<int>>& tgtT, int seed){\n    {\n        string mv = solveFromTargetRand(tgt, board, er, ec, seed);\n        string mv2 = eliminateCycles(mv);\n        auto [f, s] = processMoves(mv2);\n        updateBest(f, s, tgt);\n    }\n    {\n        string mvT = solveFromTargetRand(tgtT, boardT, erT, ecT, seed+1);\n        string mv3 = transposeMoves(mvT);\n        string mv4 = eliminateCycles(mv3);\n        auto [f2, s2] = processMoves(mv4);\n        updateBest(f2, s2, tgt);\n    }\n}\n\nbool splitOptimize(){\n    if(bestTargetUsed.empty()) return false;\n    int len = bestMoves.size();\n    if(len < 30) return false;\n    if(bestFinalScore != N*N-1) return false;\n    \n    int i = rng() % (len - 20) + 10;\n    \n    vector<vector<int>> B = board;\n    int br=er, bc=ec;\n    for(int k=0; k<i; k++){\n        char m = bestMoves[k];\n        int nr=br, nc=bc;\n        if(m=='U') nr--;\n        else if(m=='D') nr++;\n        else if(m=='L') nc--;\n        else nc++;\n        if(nr<0||nr>=N||nc<0||nc>=N) return false;\n        swap(B[br][bc], B[nr][nc]);\n        br=nr; bc=nc;\n    }\n    \n    bool improved = false;\n    {\n        string tail = solveFromTargetRand(bestTargetUsed, B, br, bc, rng());\n        string combined = bestMoves.substr(0, i) + tail;\n        string elim = eliminateCycles(combined);\n        if((int)elim.size() < (int)bestMoves.size()){\n            auto [f, s] = processMoves(elim);\n            if(s == N*N-1 && (int)f.size() < (int)bestMoves.size()){\n                if(updateBest(f, s, bestTargetUsed)) improved = true;\n            }\n        }\n    }\n    {\n        auto Bt = transposeBoard(B);\n        auto tgtT = transposeBoard(bestTargetUsed);\n        string tailT = solveFromTargetRand(tgtT, Bt, bc, br, rng());\n        string tailUntr = transposeMoves(tailT);\n        string combined = bestMoves.substr(0, i) + tailUntr;\n        string elim = eliminateCycles(combined);\n        if((int)elim.size() < (int)bestMoves.size()){\n            auto [f, s] = processMoves(elim);\n            if(s == N*N-1 && (int)f.size() < (int)bestMoves.size()){\n                if(updateBest(f, s, bestTargetUsed)) improved = true;\n            }\n        }\n    }\n    return improved;\n}\n\nint main(){\n    cin>>N>>T;\n    vector<string> initial(N);\n    for(auto&s:initial) cin>>s;\n    \n    board.assign(N, vector<int>(N));\n    er=0; ec=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        char c = initial[i][j];\n        int v = (c>='0'&&c<='9')?c-'0':c-'a'+10;\n        board[i][j]=v;\n        if(v==0){er=i;ec=j;}\n    }\n    \n    boardT = transposeBoard(board);\n    erT = ec; ecT = er;\n    \n    bestMoves = \"\";\n    bestFinalScore = computeTreeScore(board);\n    \n    auto startT = chrono::steady_clock::now();\n    double totalTime = 2.7;\n    int goalTree = N*N-1;\n    \n    auto runSA = [&](double timeLimit, double weightMis, bool startShuffle) -> vector<vector<int>> {\n        auto t = board;\n        swap(t[er][ec], t[N-1][N-1]);\n        if(startShuffle){\n            for(int k=0;k<N*N*3;k++){\n                int i1,j1,i2,j2;\n                do { i1=rng()%N; j1=rng()%N; } while(i1==N-1&&j1==N-1);\n                do { i2=rng()%N; j2=rng()%N; } while((i2==N-1&&j2==N-1) || (i1==i2&&j1==j2));\n                swap(t[i1][j1], t[i2][j2]);\n            }\n        }\n        \n        int curMis=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) if(t[i][j]!=board[i][j]) curMis++;\n        int curTree = computeTreeScore(t);\n        int curPen = computeBoundaryPenalty(t);\n        auto obj = [&](int tree, int pen, int mis){ return (double)tree*10000 - weightMis*mis - pen; };\n        double curObj = obj(curTree, curPen, curMis);\n        int bestTree = curTree;\n        auto bestT = t;\n        double bestObj = curObj;\n        \n        auto saStart = chrono::steady_clock::now();\n        int it=0;\n        double temp0=2000.0, temp1=1.0;\n        while(true){\n            if((it&1023)==0){\n                double el = chrono::duration<double>(chrono::steady_clock::now()-saStart).count();\n                if(el>timeLimit) break;\n            }\n            it++;\n            int i1,j1,i2,j2;\n            do { i1=rng()%N; j1=rng()%N; } while(i1==N-1&&j1==N-1);\n            do { i2=rng()%N; j2=rng()%N; } while((i2==N-1&&j2==N-1) || (i1==i2&&j1==j2));\n            if(t[i1][j1]==t[i2][j2]) continue;\n            int v1=t[i1][j1], v2=t[i2][j2];\n            int b1=board[i1][j1], b2=board[i2][j2];\n            int oldMisDelta = (v1!=b1?1:0) + (v2!=b2?1:0);\n            int newMisDelta = (v2!=b1?1:0) + (v1!=b2?1:0);\n            int newMis = curMis - oldMisDelta + newMisDelta;\n            swap(t[i1][j1], t[i2][j2]);\n            int newTree = computeTreeScore(t);\n            int newPen = computeBoundaryPenalty(t);\n            double newObj = obj(newTree, newPen, newMis);\n            double el = chrono::duration<double>(chrono::steady_clock::now()-saStart).count();\n            double tt = temp0 * pow(temp1/temp0, el/timeLimit);\n            if(newObj>=curObj || (double)rng()/(double)rng.max() < exp((newObj-curObj)/tt)){\n                curTree=newTree; curPen=newPen; curMis=newMis; curObj=newObj;\n                if(newTree > bestTree || (newTree==bestTree && newObj>bestObj)){\n                    bestTree = newTree; bestObj = newObj; bestT = t;\n                }\n            } else {\n                swap(t[i1][j1], t[i2][j2]);\n            }\n        }\n        return bestT;\n    };\n    \n    set<vector<vector<int>>> seenTgt;\n    vector<pair<int, vector<vector<int>>>> goodTargets; // (manhattan, target)\n    \n    auto processTarget = [&](vector<vector<int>>& t){\n        if(!seenTgt.insert(t).second) return;\n        int tree = computeTreeScore(t);\n        if(tree == goalTree){\n            int man = computeManhattan(t);\n            goodTargets.push_back({man, t});\n        }\n    };\n    \n    // Phase 1: one longer SA\n    {\n        auto t = runSA(0.4, 0.0, false);\n        processTarget(t);\n        auto tT = transposeBoard(t);\n        for(int k=0;k<3;k++){\n            double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n            if(el > totalTime - 0.2) break;\n            attemptSolve(t, tT, rng());\n        }\n    }\n    \n    // Phase 2: collect many targets\n    double phase2End = 1.3;\n    while(true){\n        double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n        if(el > phase2End) break;\n        double w_options[] = {0.0, 0.0, 0.0, 3.0, 10.0};\n        double w = w_options[rng()%5];\n        bool shuf = (rng()%2)==0;\n        auto t = runSA(0.1, w, shuf);\n        if(seenTgt.find(t)==seenTgt.end()){\n            processTarget(t);\n            int tree = computeTreeScore(t);\n            if(tree == goalTree){\n                auto tT = transposeBoard(t);\n                for(int k=0;k<2;k++){\n                    double el2 = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n                    if(el2 > phase2End+0.1) break;\n                    attemptSolve(t, tT, rng());\n                }\n            }\n        }\n    }\n    \n    // Sort goodTargets by manhattan (low first)\n    sort(goodTargets.begin(), goodTargets.end(), [](const auto& a, const auto& b){\n        return a.first < b.first;\n    });\n    \n    // Phase 3: revisit top targets (low manhattan) with many seeds\n    double phase3End = 2.1;\n    int targetIdx = 0;\n    while(!goodTargets.empty()){\n        double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n        if(el > phase3End) break;\n        // Favor top targets (first few) more\n        int idx;\n        if(rng()%3 == 0){\n            idx = rng() % min((int)goodTargets.size(), 5);\n        } else {\n            idx = rng() % goodTargets.size();\n        }\n        auto& [man, t] = goodTargets[idx];\n        auto tT = transposeBoard(t);\n        attemptSolve(t, tT, rng());\n    }\n    \n    // Phase 4: split optimization\n    while(true){\n        double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n        if(el > totalTime - 0.1) break;\n        splitOptimize();\n    }\n    \n    cout << bestMoves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, K;\nint a[11];\nvector<int> sx_arr, sy_arr;\n\nint cnt[105][105];\nint bcnt[12];\nlong long curScoreVal;\nint nvG, nhG;\nvector<double> vcG, hcG;\nvector<int> sortedByX, sortedByY;\n\nvoid fullRecompute() {\n    nvG = vcG.size(); nhG = hcG.size();\n    for (int i = 0; i <= nvG; i++) for (int j = 0; j <= nhG; j++) cnt[i][j] = 0;\n    for (int i = 0; i < N; i++) {\n        int xi = upper_bound(vcG.begin(), vcG.end(), (double)sx_arr[i]) - vcG.begin();\n        int yi = upper_bound(hcG.begin(), hcG.end(), (double)sy_arr[i]) - hcG.begin();\n        cnt[xi][yi]++;\n    }\n    for (int d = 0; d < 12; d++) bcnt[d] = 0;\n    for (int i = 0; i <= nvG; i++)\n        for (int j = 0; j <= nhG; j++) {\n            int c = cnt[i][j];\n            if (c >= 1 && c <= 10) bcnt[c]++;\n        }\n    curScoreVal = 0;\n    for (int d = 1; d <= 10; d++) curScoreVal += min(a[d], bcnt[d]);\n}\n\ninline void updateCell(int col, int row, int delta) {\n    int oldv = cnt[col][row];\n    int newv = oldv + delta;\n    cnt[col][row] = newv;\n    if (oldv >= 1 && oldv <= 10) {\n        int before = min(a[oldv], bcnt[oldv]);\n        bcnt[oldv]--;\n        int after = min(a[oldv], bcnt[oldv]);\n        curScoreVal += after - before;\n    }\n    if (newv >= 1 && newv <= 10) {\n        int before = min(a[newv], bcnt[newv]);\n        bcnt[newv]++;\n        int after = min(a[newv], bcnt[newv]);\n        curScoreVal += after - before;\n    }\n}\n\nvoid moveVCut(int ci, double newVal) {\n    double oldVal = vcG[ci];\n    if (newVal == oldVal) return;\n    double lo = min(oldVal, newVal), hi = max(oldVal, newVal);\n    int l, r;\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sx_arr[sortedByX[m]] > lo) b2 = m; else a2 = m+1; }\n        l = a2;\n    }\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sx_arr[sortedByX[m]] >= hi) b2 = m; else a2 = m+1; }\n        r = a2;\n    }\n    int fromCol, toCol;\n    if (newVal > oldVal) { fromCol = ci + 1; toCol = ci; }\n    else { fromCol = ci; toCol = ci + 1; }\n    vcG[ci] = newVal;\n    for (int k = l; k < r; k++) {\n        int si = sortedByX[k];\n        int j = upper_bound(hcG.begin(), hcG.end(), (double)sy_arr[si]) - hcG.begin();\n        updateCell(fromCol, j, -1);\n        updateCell(toCol, j, +1);\n    }\n}\n\nvoid moveHCut(int ci, double newVal) {\n    double oldVal = hcG[ci];\n    if (newVal == oldVal) return;\n    double lo = min(oldVal, newVal), hi = max(oldVal, newVal);\n    int l, r;\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sy_arr[sortedByY[m]] > lo) b2 = m; else a2 = m+1; }\n        l = a2;\n    }\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sy_arr[sortedByY[m]] >= hi) b2 = m; else a2 = m+1; }\n        r = a2;\n    }\n    int fromRow, toRow;\n    if (newVal > oldVal) { fromRow = ci + 1; toRow = ci; }\n    else { fromRow = ci; toRow = ci + 1; }\n    hcG[ci] = newVal;\n    for (int k = l; k < r; k++) {\n        int si = sortedByY[k];\n        int j = upper_bound(vcG.begin(), vcG.end(), (double)sx_arr[si]) - vcG.begin();\n        updateCell(j, fromRow, -1);\n        updateCell(j, toRow, +1);\n    }\n}\n\nstruct XorShift {\n    uint64_t s;\n    XorShift(uint64_t seed): s(seed ? seed : 1) {}\n    inline uint32_t next() {\n        s ^= s << 13; s ^= s >> 7; s ^= s << 17;\n        return (uint32_t)s;\n    }\n    inline double nextDouble() {\n        return (double)(next() & 0xFFFFFF) / (double)(1 << 24);\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(0);\n    \n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    sx_arr.resize(N); sy_arr.resize(N);\n    for (int i = 0; i < N; i++) cin >> sx_arr[i] >> sy_arr[i];\n    \n    sortedByX.resize(N); sortedByY.resize(N);\n    iota(sortedByX.begin(), sortedByX.end(), 0);\n    iota(sortedByY.begin(), sortedByY.end(), 0);\n    sort(sortedByX.begin(), sortedByX.end(), [&](int x, int y){ return sx_arr[x] < sx_arr[y]; });\n    sort(sortedByY.begin(), sortedByY.end(), [&](int x, int y){ return sy_arr[x] < sy_arr[y]; });\n    \n    vector<int> xs = sx_arr, ys = sy_arr;\n    sort(xs.begin(), xs.end()); xs.erase(unique(xs.begin(), xs.end()), xs.end());\n    sort(ys.begin(), ys.end()); ys.erase(unique(ys.begin(), ys.end()), ys.end());\n    \n    vector<double> cand_x, cand_y;\n    for (int i = 0; i + 1 < (int)xs.size(); i++) cand_x.push_back((xs[i] + xs[i+1]) / 2.0);\n    for (int i = 0; i + 1 < (int)ys.size(); i++) cand_y.push_back((ys[i] + ys[i+1]) / 2.0);\n    \n    XorShift rng(1234567);\n    \n    auto pickEvenly = [&](vector<double>& cand, int k) {\n        vector<double> res;\n        if ((int)cand.size() <= k) res = cand;\n        else {\n            for (int i = 0; i < k; i++) {\n                int idx = (int)((long long)(i+1) * cand.size() / (k+1));\n                if (idx >= (int)cand.size()) idx = cand.size()-1;\n                res.push_back(cand[idx]);\n            }\n        }\n        sort(res.begin(), res.end());\n        res.erase(unique(res.begin(), res.end()), res.end());\n        return res;\n    };\n    \n    auto startTime = chrono::steady_clock::now();\n    double totalTime = 2.7;\n    \n    long long bestScore = -1;\n    vector<double> bestVC, bestHC;\n    \n    for (int kv = 30; kv <= 70; kv += 5) {\n        int kh = K - kv;\n        vcG = pickEvenly(cand_x, kv);\n        hcG = pickEvenly(cand_y, kh);\n        fullRecompute();\n        if (curScoreVal > bestScore) {\n            bestScore = curScoreVal;\n            bestVC = vcG; bestHC = hcG;\n        }\n    }\n    \n    vcG = bestVC; hcG = bestHC;\n    fullRecompute();\n    \n    double T0 = 3.0, T1 = 0.05;\n    long long iters = 0;\n    double cachedProgress = 0.0;\n    \n    auto tryInsertCut = [&](vector<double>& vec, double v) -> bool {\n        auto it = lower_bound(vec.begin(), vec.end(), v);\n        if (it != vec.end() && *it == v) return false;\n        vec.insert(it, v);\n        return true;\n    };\n    \n    while (true) {\n        iters++;\n        if ((iters & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - startTime).count();\n            if (elapsed > totalTime) break;\n            cachedProgress = elapsed / totalTime;\n        }\n        \n        double T = T0 * pow(T1/T0, cachedProgress);\n        \n        int op = rng.next() % 100;\n        \n        if (op < 48) {\n            if (vcG.empty() || cand_x.empty()) continue;\n            int i = rng.next() % vcG.size();\n            double lo_b = (i == 0) ? -1e18 : vcG[i-1];\n            double hi_b = (i == (int)vcG.size()-1) ? 1e18 : vcG[i+1];\n            auto itL = upper_bound(cand_x.begin(), cand_x.end(), lo_b);\n            auto itR = lower_bound(cand_x.begin(), cand_x.end(), hi_b);\n            if (itL >= itR) continue;\n            int numCand = itR - itL;\n            double newVal = *(itL + rng.next() % numCand);\n            if (newVal == vcG[i]) continue;\n            \n            long long prevScore = curScoreVal;\n            double prevVal = vcG[i];\n            moveVCut(i, newVal);\n            long long delta = curScoreVal - prevScore;\n            if (delta >= 0 || rng.nextDouble() < exp((double)delta / T)) {\n                if (curScoreVal > bestScore) {\n                    bestScore = curScoreVal;\n                    bestVC = vcG; bestHC = hcG;\n                }\n            } else {\n                moveVCut(i, prevVal);\n            }\n        } else if (op < 96) {\n            if (hcG.empty() || cand_y.empty()) continue;\n            int i = rng.next() % hcG.size();\n            double lo_b = (i == 0) ? -1e18 : hcG[i-1];\n            double hi_b = (i == (int)hcG.size()-1) ? 1e18 : hcG[i+1];\n            auto itL = upper_bound(cand_y.begin(), cand_y.end(), lo_b);\n            auto itR = lower_bound(cand_y.begin(), cand_y.end(), hi_b);\n            if (itL >= itR) continue;\n            int numCand = itR - itL;\n            double newVal = *(itL + rng.next() % numCand);\n            if (newVal == hcG[i]) continue;\n            \n            long long prevScore = curScoreVal;\n            double prevVal = hcG[i];\n            moveHCut(i, newVal);\n            long long delta = curScoreVal - prevScore;\n            if (delta >= 0 || rng.nextDouble() < exp((double)delta / T)) {\n                if (curScoreVal > bestScore) {\n                    bestScore = curScoreVal;\n                    bestVC = vcG; bestHC = hcG;\n                }\n            } else {\n                moveHCut(i, prevVal);\n            }\n        } else {\n            vector<double> saveVC = vcG, saveHC = hcG;\n            long long prevScoreFull = curScoreVal;\n            \n            int dir = rng.next() % 2;\n            bool ok = false;\n            if (dir == 0) {\n                if (!vcG.empty() && !cand_y.empty()) {\n                    int ri = rng.next() % vcG.size();\n                    vcG.erase(vcG.begin() + ri);\n                    double nv = cand_y[rng.next() % cand_y.size()];\n                    ok = tryInsertCut(hcG, nv);\n                }\n            } else {\n                if (!hcG.empty() && !cand_x.empty()) {\n                    int ri = rng.next() % hcG.size();\n                    hcG.erase(hcG.begin() + ri);\n                    double nv = cand_x[rng.next() % cand_x.size()];\n                    ok = tryInsertCut(vcG, nv);\n                }\n            }\n            if (!ok) { vcG = saveVC; hcG = saveHC; continue; }\n            \n            fullRecompute();\n            long long delta = curScoreVal - prevScoreFull;\n            if (delta >= 0 || rng.nextDouble() < exp((double)delta / T)) {\n                if (curScoreVal > bestScore) {\n                    bestScore = curScoreVal;\n                    bestVC = vcG; bestHC = hcG;\n                }\n            } else {\n                vcG = saveVC; hcG = saveHC;\n                fullRecompute();\n            }\n        }\n    }\n    \n    vcG = bestVC; hcG = bestHC;\n    \n    cout << vcG.size() + hcG.size() << \"\\n\";\n    for (double c : vcG) {\n        long long p = (long long)floor(c);\n        cout << p << \" \" << -1000000000LL << \" \" << p+1 << \" \" << 1000000000LL << \"\\n\";\n    }\n    for (double c : hcG) {\n        long long p = (long long)floor(c);\n        cout << -1000000000LL << \" \" << p << \" \" << 1000000000LL << \" \" << p+1 << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint cx;\nvector<uint8_t> has_dot;\nvector<uint8_t> edge_used;\nvector<short> next_dot;\nint dx8[8] = {1,1,0,-1,-1,-1,0,1};\nint dy8[8] = {0,1,1,1,0,-1,-1,-1};\n\ninline bool inside(int x, int y) { return 0<=x && x<N && 0<=y && y<N; }\ninline int weight(int x, int y) { return (x-cx)*(x-cx) + (y-cx)*(y-cx) + 1; }\n\nvoid initNextDot() {\n    next_dot.assign(N*N*8, 0);\n    for (int d = 0; d < 8; d++) {\n        for (int sx = 0; sx < N; sx++) for (int sy = 0; sy < N; sy++) {\n            int px = sx - dx8[d], py = sy - dy8[d];\n            if (inside(px, py)) continue;\n            vector<int> dotPos;\n            int steps = 0;\n            int cxx = sx, cyy = sy;\n            while (inside(cxx, cyy)) {\n                if (has_dot[cxx*N+cyy]) dotPos.push_back(steps);\n                steps++; cxx += dx8[d]; cyy += dy8[d];\n            }\n            cxx = sx; cyy = sy;\n            int ptr = 0;\n            for (int s = 0; s < steps; s++) {\n                while (ptr < (int)dotPos.size() && dotPos[ptr] <= s) ptr++;\n                if (ptr < (int)dotPos.size()) next_dot[(cxx*N+cyy)*8+d] = (short)(dotPos[ptr] - s);\n                else next_dot[(cxx*N+cyy)*8+d] = 0;\n                cxx += dx8[d]; cyy += dy8[d];\n            }\n        }\n    }\n}\n\nvoid updateNextDotAdd(int qx, int qy) {\n    for (int d = 0; d < 8; d++) {\n        int opp = (d+4)%8;\n        int cxx = qx + dx8[opp], cyy = qy + dy8[opp];\n        int dist = 1;\n        while (inside(cxx, cyy)) {\n            int cur = next_dot[(cxx*N+cyy)*8+d];\n            if (cur > 0 && cur < dist) break;\n            next_dot[(cxx*N+cyy)*8+d] = (short)dist;\n            if (has_dot[cxx*N+cyy]) break;\n            cxx += dx8[opp]; cyy += dy8[opp]; dist++;\n        }\n    }\n}\n\ninline int nearestDotFast(int x, int y, int d) {\n    int v = next_dot[(x*N+y)*8+d];\n    return v == 0 ? -1 : v;\n}\n\ninline bool checkSeg(int x, int y, int d, int len) {\n    int cxx = x, cyy = y;\n    int ddx = dx8[d], ddy = dy8[d];\n    for (int i = 0; i < len; i++) {\n        if (edge_used[(cxx*N+cyy)*8+d]) return false;\n        cxx += ddx; cyy += ddy;\n        if (i < len-1 && has_dot[cxx*N+cyy]) return false;\n    }\n    return true;\n}\n\nvoid markSeg(int x, int y, int d, int len) {\n    int cxx = x, cyy = y;\n    int dr = d^4;\n    int ddx = dx8[d], ddy = dy8[d];\n    for (int i = 0; i < len; i++) {\n        edge_used[(cxx*N+cyy)*8+d] = 1;\n        int nx = cxx + ddx, ny = cyy + ddy;\n        edge_used[(nx*N+ny)*8+dr] = 1;\n        cxx = nx; cyy = ny;\n    }\n}\n\nstruct Move {\n    int p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y;\n    int8_t d1, d2;\n    int len1, len2;\n};\n\nbool validateMove(const Move& m) {\n    if (has_dot[m.p1x*N+m.p1y]) return false;\n    if (!has_dot[m.p2x*N+m.p2y]) return false;\n    if (!has_dot[m.p3x*N+m.p3y]) return false;\n    if (!has_dot[m.p4x*N+m.p4y]) return false;\n    if (!checkSeg(m.p1x, m.p1y, m.d1, m.len1)) return false;\n    if (!checkSeg(m.p1x, m.p1y, m.d2, m.len2)) return false;\n    if (!checkSeg(m.p2x, m.p2y, m.d2, m.len2)) return false;\n    if (!checkSeg(m.p4x, m.p4y, m.d1, m.len1)) return false;\n    return true;\n}\n\nvoid applyMove(const Move& m) {\n    has_dot[m.p1x*N+m.p1y] = 1;\n    updateNextDotAdd(m.p1x, m.p1y);\n    markSeg(m.p1x, m.p1y, m.d1, m.len1);\n    markSeg(m.p1x, m.p1y, m.d2, m.len2);\n    markSeg(m.p2x, m.p2y, m.d2, m.len2);\n    markSeg(m.p4x, m.p4y, m.d1, m.len1);\n}\n\nmt19937 g_rng(12345);\nint g_noiseLevel = 0;\n\nlong long computePriority(const Move& m) {\n    long long w = weight(m.p1x, m.p1y);\n    long long size = m.len1 + m.len2;\n    long long key = w * 100000LL - size * 100LL;\n    if (g_noiseLevel > 0) {\n        key += (long long)(g_rng() % (g_noiseLevel * 300 + 100));\n    }\n    return key;\n}\n\nstruct PQItem {\n    long long key;\n    Move m;\n    bool operator<(const PQItem& o) const { return key < o.key; }\n};\n\nvoid addCandsWithDot(int qx, int qy, priority_queue<PQItem>& pq) {\n    auto tryAdd = [&](const Move& m) {\n        if (validateMove(m)) {\n            pq.push({computePriority(m), m});\n        }\n    };\n    \n    for (int d1 = 0; d1 < 8; d1++) {\n        int d2 = (d1+2)%8;\n        int opp1 = (d1+4)%8;\n        int l1max;\n        int nd = nearestDotFast(qx, qy, opp1);\n        if (nd < 0) {\n            l1max = 0;\n            int tx = qx + dx8[opp1], ty = qy + dy8[opp1];\n            while (inside(tx, ty)) { l1max++; tx += dx8[opp1]; ty += dy8[opp1]; }\n        } else l1max = nd - 1;\n        for (int l1 = 1; l1 <= l1max; l1++) {\n            int p1x = qx + dx8[opp1]*l1, p1y = qy + dy8[opp1]*l1;\n            int l2 = nearestDotFast(p1x, p1y, d2);\n            if (l2 < 0) continue;\n            int p4x = p1x + dx8[d2]*l2, p4y = p1y + dy8[d2]*l2;\n            int p3x = qx + dx8[d2]*l2, p3y = qy + dy8[d2]*l2;\n            if (!inside(p3x, p3y) || !has_dot[p3x*N+p3y]) continue;\n            Move m{p1x,p1y,qx,qy,p3x,p3y,p4x,p4y,(int8_t)d1,(int8_t)d2,l1,l2};\n            tryAdd(m);\n        }\n    }\n    for (int d1 = 0; d1 < 8; d1++) {\n        int d2 = (d1+2)%8;\n        int opp2 = (d2+4)%8;\n        int l2max;\n        int nd = nearestDotFast(qx, qy, opp2);\n        if (nd < 0) {\n            l2max = 0;\n            int tx = qx + dx8[opp2], ty = qy + dy8[opp2];\n            while (inside(tx, ty)) { l2max++; tx += dx8[opp2]; ty += dy8[opp2]; }\n        } else l2max = nd - 1;\n        for (int l2 = 1; l2 <= l2max; l2++) {\n            int p1x = qx + dx8[opp2]*l2, p1y = qy + dy8[opp2]*l2;\n            int l1 = nearestDotFast(p1x, p1y, d1);\n            if (l1 < 0) continue;\n            int p2x = p1x + dx8[d1]*l1, p2y = p1y + dy8[d1]*l1;\n            int p3x = qx + dx8[d1]*l1, p3y = qy + dy8[d1]*l1;\n            if (!inside(p3x, p3y) || !has_dot[p3x*N+p3y]) continue;\n            Move m{p1x,p1y,p2x,p2y,p3x,p3y,qx,qy,(int8_t)d1,(int8_t)d2,l1,l2};\n            tryAdd(m);\n        }\n    }\n    for (int d1 = 0; d1 < 8; d1++) {\n        int d2 = (d1+2)%8;\n        int opp1 = (d1+4)%8;\n        int opp2 = (d2+4)%8;\n        int l2 = nearestDotFast(qx, qy, opp2);\n        if (l2 < 0) continue;\n        int p2x = qx + dx8[opp2]*l2, p2y = qy + dy8[opp2]*l2;\n        int l1 = nearestDotFast(qx, qy, opp1);\n        if (l1 < 0) continue;\n        int p4x = qx + dx8[opp1]*l1, p4y = qy + dy8[opp1]*l1;\n        int p1x = p2x + dx8[opp1]*l1, p1y = p2y + dy8[opp1]*l1;\n        if (!inside(p1x, p1y) || has_dot[p1x*N+p1y]) continue;\n        Move m{p1x,p1y,p2x,p2y,qx,qy,p4x,p4y,(int8_t)d1,(int8_t)d2,l1,l2};\n        tryAdd(m);\n    }\n}\n\nint main() {\n    cin >> N >> M;\n    cx = (N-1)/2;\n    \n    auto startTime = chrono::steady_clock::now();\n    auto timeLeft = [&](){ return 4.7 - chrono::duration<double>(chrono::steady_clock::now() - startTime).count(); };\n    \n    vector<pair<int,int>> initial(M);\n    for (auto& p : initial) { cin >> p.first >> p.second; }\n    \n    auto resetState = [&]() {\n        has_dot.assign(N*N, 0);\n        edge_used.assign(N*N*8, 0);\n        for (auto& p : initial) has_dot[p.first*N+p.second] = 1;\n        initNextDot();\n    };\n    \n    vector<Move> bestMoves;\n    long long bestScore = -1;\n    \n    int iter = 0;\n    \n    while (timeLeft() > 0.3) {\n        resetState();\n        vector<Move> moves;\n        \n        g_noiseLevel = iter == 0 ? 0 : (1 + iter);\n        \n        priority_queue<PQItem> pq;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (has_dot[x*N+y]) continue;\n                for (int d1 = 0; d1 < 8; d1++) {\n                    int d2 = (d1+2)%8;\n                    int l1 = nearestDotFast(x, y, d1);\n                    if (l1 < 0) continue;\n                    int l2 = nearestDotFast(x, y, d2);\n                    if (l2 < 0) continue;\n                    int p2x = x + dx8[d1]*l1, p2y = y + dy8[d1]*l1;\n                    int p4x = x + dx8[d2]*l2, p4y = y + dy8[d2]*l2;\n                    int p3x = p2x + dx8[d2]*l2, p3y = p2y + dy8[d2]*l2;\n                    if (!inside(p3x, p3y) || !has_dot[p3x*N+p3y]) continue;\n                    Move m{x,y,p2x,p2y,p3x,p3y,p4x,p4y,(int8_t)d1,(int8_t)d2,l1,l2};\n                    if (validateMove(m)) pq.push({computePriority(m), m});\n                }\n            }\n        }\n        \n        while (!pq.empty() && timeLeft() > 0.2) {\n            PQItem top = pq.top(); pq.pop();\n            if (!validateMove(top.m)) continue;\n            applyMove(top.m);\n            moves.push_back(top.m);\n            addCandsWithDot(top.m.p1x, top.m.p1y, pq);\n        }\n        \n        long long sumW = 0;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) {\n            if (has_dot[x*N+y]) sumW += weight(x,y);\n        }\n        \n        if (sumW > bestScore) {\n            bestScore = sumW;\n            bestMoves = moves;\n        }\n        iter++;\n    }\n    \n    cout << bestMoves.size() << \"\\n\";\n    for (auto& m : bestMoves) {\n        cout << m.p1x << \" \" << m.p1y << \" \" << m.p2x << \" \" << m.p2y << \" \"\n             << m.p3x << \" \" << m.p3y << \" \" << m.p4x << \" \" << m.p4y << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef array<int,100> Board;\n\ninline void tilt(Board& b, int dir) {\n    if (dir == 0) {\n        for (int c = 0; c < 10; c++) {\n            int w = 0;\n            for (int r = 0; r < 10; r++) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w++;\n                }\n            }\n        }\n    } else if (dir == 1) {\n        for (int c = 0; c < 10; c++) {\n            int w = 9;\n            for (int r = 9; r >= 0; r--) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w--;\n                }\n            }\n        }\n    } else if (dir == 2) {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 0;\n            for (int c = 0; c < 10; c++) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w++;\n                }\n            }\n        }\n    } else {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w--;\n                }\n            }\n        }\n    }\n}\n\ninline int tilt_emp(Board& b, int dir, int* emp) {\n    int ec = 0;\n    if (dir == 0) {\n        for (int c = 0; c < 10; c++) {\n            int w = 0;\n            for (int r = 0; r < 10; r++) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w++;\n                }\n            }\n            for (int r = w; r < 10; r++) emp[ec++] = r*10+c;\n        }\n    } else if (dir == 1) {\n        for (int c = 0; c < 10; c++) {\n            int w = 9;\n            for (int r = 9; r >= 0; r--) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w--;\n                }\n            }\n            for (int r = 0; r <= w; r++) emp[ec++] = r*10+c;\n        }\n    } else if (dir == 2) {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 0;\n            for (int c = 0; c < 10; c++) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w++;\n                }\n            }\n            for (int c = w; c < 10; c++) emp[ec++] = rb+c;\n        }\n    } else {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w--;\n                }\n            }\n            for (int c = 0; c <= w; c++) emp[ec++] = rb+c;\n        }\n    }\n    return ec;\n}\n\nvoid placeCandy(Board& b, int p, int flavor) {\n    int cnt = 0;\n    for (int i = 0; i < 100; i++) {\n        if (!b[i]) {\n            cnt++;\n            if (cnt == p) {\n                b[i] = flavor;\n                return;\n            }\n        }\n    }\n}\n\nint computeScore(const Board& b) {\n    int vis[100] = {0};\n    int sum = 0;\n    int stk[100];\n    for (int i = 0; i < 100; i++) {\n        if (!vis[i] && b[i]) {\n            int flavor = b[i];\n            int sz = 0;\n            int top = 0;\n            stk[top++] = i;\n            vis[i] = 1;\n            while (top > 0) {\n                int x = stk[--top];\n                sz++;\n                int r = x/10, c = x%10;\n                if (r>0) { int ni = x-10; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (r<9) { int ni = x+10; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (c>0) { int ni = x-1; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (c<9) { int ni = x+1; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n            }\n            sum += sz*sz;\n        }\n    }\n    return sum;\n}\n\nmt19937 rng(12345);\n\nint policies[24][3] = {\n    {0,1,2}, {0,1,3}, {0,2,1}, {0,2,3}, {0,3,1}, {0,3,2},\n    {1,0,2}, {1,0,3}, {1,2,0}, {1,2,3}, {1,3,0}, {1,3,2},\n    {2,0,1}, {2,0,3}, {2,1,0}, {2,1,3}, {2,3,0}, {2,3,1},\n    {3,0,1}, {3,0,2}, {3,1,0}, {3,1,2}, {3,2,0}, {3,2,1},\n};\n\ninline int rollout_from(Board b, int startT, int endT, const vector<int>& f, const int* policy, const unsigned* rnd, int rndStart, int* emp, int ec) {\n    for (int k = startT; k < endT; k++) {\n        int flavor = f[k];\n        int pick = emp[rnd[rndStart + k - startT] % ec];\n        b[pick] = flavor;\n        if (k < endT - 1) {\n            ec = tilt_emp(b, policy[flavor-1], emp);\n        }\n    }\n    return computeScore(b);\n}\n\nint main() {\n    auto startTime = chrono::steady_clock::now();\n    \n    vector<int> f(100);\n    for (int i = 0; i < 100; i++) cin >> f[i];\n    \n    Board board;\n    board.fill(0);\n    \n    double totalBudget = 1.85;\n    \n    int bestPolicy = 0;\n    {\n        auto bs = chrono::steady_clock::now();\n        double evalBudget = 0.15;\n        long long ps[24] = {0};\n        int pt[24] = {0};\n        int ri = 0;\n        int emp[100];\n        while (true) {\n            if ((ri & 7) == 0) {\n                auto ns = chrono::steady_clock::now();\n                double el = chrono::duration<double>(ns - bs).count();\n                if (el >= evalBudget) break;\n            }\n            int pi = ri % 24;\n            ri++;\n            Board b;\n            b.fill(0);\n            int ec = 100;\n            for (int i = 0; i < 100; i++) emp[i] = i;\n            for (int k = 0; k < 100; k++) {\n                int flavor = f[k];\n                int pick = emp[rng() % ec];\n                b[pick] = flavor;\n                if (k < 99) {\n                    ec = tilt_emp(b, policies[pi][flavor-1], emp);\n                }\n            }\n            int sc = computeScore(b);\n            ps[pi] += sc;\n            pt[pi]++;\n        }\n        double bestAvg = -1;\n        for (int i = 0; i < 24; i++) {\n            if (pt[i] == 0) continue;\n            double avg = (double)ps[i] / pt[i];\n            if (avg > bestAvg) { bestAvg = avg; bestPolicy = i; }\n        }\n    }\n    \n    unsigned rnd[100];\n    \n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        placeCandy(board, p, f[t]);\n        \n        if (t == 99) break;\n        \n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        double remaining = totalBudget - elapsed;\n        int stepsLeft = 100 - t;\n        double perStep = remaining / stepsLeft;\n        if (perStep < 0.001) perStep = 0.001;\n        auto stepStart = chrono::steady_clock::now();\n        \n        long long scoreSum[4][4] = {{0}};\n        int trials[4][4] = {{0}};\n        long long scoreSum1[4] = {0,0,0,0};\n        int trials1[4] = {0,0,0,0};\n        \n        int iter = 0;\n        int remainingCandies = 99 - t;\n        bool canDo2Step = (remainingCandies >= 2);\n        \n        while (true) {\n            if ((iter & 1) == 0) {\n                auto nowS = chrono::steady_clock::now();\n                double el = chrono::duration<double>(nowS - stepStart).count();\n                if (el >= perStep) break;\n            }\n            iter++;\n            \n            for (int k = 0; k < remainingCandies; k++) rnd[k] = rng();\n            \n            for (int D1 = 0; D1 < 4; D1++) {\n                Board b1 = board;\n                int emp1[100];\n                int ec1 = tilt_emp(b1, D1, emp1);\n                \n                if (remainingCandies == 0) {\n                    int sc = computeScore(b1);\n                    scoreSum1[D1] += sc;\n                    trials1[D1]++;\n                    continue;\n                }\n                \n                int flavor = f[t+1];\n                int pick = emp1[rnd[0] % ec1];\n                b1[pick] = flavor;\n                \n                if (!canDo2Step) {\n                    int sc = computeScore(b1);\n                    scoreSum1[D1] += sc;\n                    trials1[D1]++;\n                    continue;\n                }\n                \n                for (int D2 = 0; D2 < 4; D2++) {\n                    Board b2 = b1;\n                    int emp2[100];\n                    int ec2 = tilt_emp(b2, D2, emp2);\n                    int sc;\n                    if (remainingCandies == 2) {\n                        int flavor2 = f[t+2];\n                        int pick2 = emp2[rnd[1] % ec2];\n                        b2[pick2] = flavor2;\n                        sc = computeScore(b2);\n                    } else {\n                        sc = rollout_from(b2, t+2, 100, f, policies[bestPolicy], rnd, 1, emp2, ec2);\n                    }\n                    scoreSum[D1][D2] += sc;\n                    trials[D1][D2]++;\n                }\n            }\n        }\n        \n        double bestScoreV = -1;\n        int bestDir = 0;\n        \n        if (canDo2Step) {\n            for (int d1 = 0; d1 < 4; d1++) {\n                double bestD2val = -1;\n                for (int d2 = 0; d2 < 4; d2++) {\n                    if (trials[d1][d2] == 0) continue;\n                    double avg = (double)scoreSum[d1][d2] / trials[d1][d2];\n                    if (avg > bestD2val) bestD2val = avg;\n                }\n                if (bestD2val > bestScoreV) {\n                    bestScoreV = bestD2val;\n                    bestDir = d1;\n                }\n            }\n        } else {\n            for (int d = 0; d < 4; d++) {\n                if (trials1[d] == 0) continue;\n                double avg = (double)scoreSum1[d] / trials1[d];\n                if (avg > bestScoreV) {\n                    bestScoreV = avg;\n                    bestDir = d;\n                }\n            }\n        }\n        \n        tilt(board, bestDir);\n        cout << \"FBLR\"[bestDir] << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint M; double eps;\n\nvector<vector<int>> genParts_(int N, int maxK){\n    vector<vector<int>> parts;\n    parts.push_back({});\n    function<void(vector<int>&, int, int, int)> rec = [&](vector<int>& cur, int minVal, int remaining, int depth){\n        if(!cur.empty()) parts.push_back(cur);\n        if(depth==maxK) return;\n        for(int v=minVal; v<=remaining; v++){\n            cur.push_back(v);\n            rec(cur, v, remaining-v, depth+1);\n            cur.pop_back();\n        }\n    };\n    vector<int> cur;\n    rec(cur, 2, N, 0);\n    return parts;\n}\n\nstruct Features {\n    vector<double> sortedDeg;\n    vector<double> sortedF2;\n};\n\nFeatures computeExpectedFeatures(const vector<int>& part, int N){\n    int C = part.size();\n    int sumCluster = 0; for(int s : part) sumCluster += s;\n    int n_iso = N - sumCluster;\n    vector<int> sizes(C+1);\n    for(int i=0;i<C;i++) sizes[i] = part[i];\n    sizes[C] = n_iso;\n    \n    vector<double> mu(C+1);\n    for(int t=0;t<=C;t++){\n        int s = sizes[t];\n        if(t < C){\n            mu[t] = (s-1)*(1-eps) + (N-s)*eps;\n        } else {\n            mu[t] = (N-1)*eps;\n        }\n    }\n    \n    vector<double> f2(C+1);\n    for(int t=0;t<=C;t++){\n        if(t < C){\n            int s = sizes[t];\n            double ff = (s-1)*(1-eps)*mu[t];\n            for(int tp=0;tp<=C;tp++){\n                if(tp==t) continue;\n                ff += sizes[tp] * eps * mu[tp];\n            }\n            f2[t] = ff;\n        } else {\n            double ff = 0;\n            for(int tp=0;tp<C;tp++) ff += sizes[tp] * eps * mu[tp];\n            if(sizes[C] > 0) ff += (sizes[C]-1) * eps * mu[C];\n            f2[t] = ff;\n        }\n    }\n    \n    Features feat;\n    feat.sortedDeg.reserve(N);\n    feat.sortedF2.reserve(N);\n    for(int t=0;t<=C;t++){\n        for(int i=0;i<sizes[t];i++){\n            feat.sortedDeg.push_back(mu[t]);\n            feat.sortedF2.push_back(f2[t]);\n        }\n    }\n    sort(feat.sortedDeg.begin(), feat.sortedDeg.end());\n    sort(feat.sortedF2.begin(), feat.sortedF2.end());\n    return feat;\n}\n\nFeatures computeObservedFeatures(const vector<vector<int>>& H, int N){\n    vector<int> deg(N, 0);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) deg[i] += H[i][j];\n    vector<double> f2v(N);\n    for(int v=0;v<N;v++){\n        double s=0;\n        for(int u=0;u<N;u++) if(H[v][u]) s += deg[u];\n        f2v[v] = s;\n    }\n    Features feat;\n    feat.sortedDeg.resize(N);\n    for(int i=0;i<N;i++) feat.sortedDeg[i] = deg[i];\n    feat.sortedF2 = f2v;\n    sort(feat.sortedDeg.begin(), feat.sortedDeg.end());\n    sort(feat.sortedF2.begin(), feat.sortedF2.end());\n    return feat;\n}\n\ndouble distDeg(const Features& a, const Features& b, int N){\n    double d = 0;\n    for(int i=0;i<N;i++){ double t=a.sortedDeg[i]-b.sortedDeg[i]; d += t*t; }\n    return d;\n}\ndouble distF2(const Features& a, const Features& b, int N){\n    double d = 0;\n    for(int i=0;i<N;i++){ double t=a.sortedF2[i]-b.sortedF2[i]; d += t*t; }\n    return d;\n}\n\nvector<int> selectPartitions(const vector<Features>& allFeat, int P, int N){\n    vector<int> chosen = {0};\n    vector<double> minD(P, 1e18);\n    vector<bool> used(P,false); used[0]=true;\n    for(int i=0;i<P;i++) if(!used[i]) minD[i] = distDeg(allFeat[0], allFeat[i], N);\n    while((int)chosen.size() < M && (int)chosen.size() < P){\n        int bi=-1; double bv=-1;\n        for(int i=0;i<P;i++){\n            if(used[i]) continue;\n            if(minD[i] > bv){ bv=minD[i]; bi=i; }\n        }\n        if(bi<0) break;\n        chosen.push_back(bi);\n        used[bi]=true;\n        for(int i=0;i<P;i++) if(!used[i]){\n            double d=distDeg(allFeat[bi], allFeat[i], N);\n            if(d<minD[i]) minD[i]=d;\n        }\n    }\n    while((int)chosen.size()<M){\n        for(int i=0;i<P;i++) if(!used[i]){ used[i]=true; chosen.push_back(i); break;}\n    }\n    return chosen;\n}\n\nint main(){\n    cin >> M >> eps;\n    \n    int bestN = 100, bestMaxK = 3;\n    double bestScore = -1;\n    double bestWF2 = 0;\n    \n    if(eps < 1e-9){\n        for(int mK : {3, 4}){\n            for(int n=4;n<=100;n++){\n                int ps = (int)genParts_(n, mK).size();\n                if(ps >= M){\n                    double score = 1.0/n;\n                    if(score > bestScore){ bestScore = score; bestN = n; bestMaxK = mK; bestWF2 = 0; }\n                    break;\n                }\n            }\n        }\n    } else {\n        auto start = chrono::steady_clock::now();\n        double timeBudget = 3.0;\n        \n        vector<int> Ns;\n        for(int n=8;n<=30;n+=2) Ns.push_back(n);\n        for(int n=35;n<=60;n+=5) Ns.push_back(n);\n        for(int n=70;n<=100;n+=10) Ns.push_back(n);\n        \n        int trials = 100;\n        \n        vector<double> wF2Candidates;\n        wF2Candidates.push_back(0.0);\n        for(double x = 1e-5; x <= 1.01; x *= 3.16228) wF2Candidates.push_back(x);\n        \n        bool stop=false;\n        for(int n : Ns){\n            if(stop) break;\n            for(int mK : {2, 3}){\n                auto elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n                if(elapsed > timeBudget){ stop=true; break; }\n                auto parts = genParts_(n, mK);\n                if((int)parts.size() < M) continue;\n                int P = parts.size();\n                vector<Features> allFeat(P);\n                for(int i=0;i<P;i++) allFeat[i] = computeExpectedFeatures(parts[i], n);\n                auto chosen = selectPartitions(allFeat, P, n);\n                \n                vector<vector<int>> clusterOf(M, vector<int>(n, -1));\n                for(int k=0;k<M;k++){\n                    const auto& part = parts[chosen[k]];\n                    int pos=0, cid=0;\n                    for(int s : part){\n                        for(int i=pos;i<pos+s;i++) clusterOf[k][i] = cid;\n                        pos += s; cid++;\n                    }\n                }\n                \n                mt19937 rng(12345);\n                uniform_real_distribution<double> ur(0,1);\n                vector<int> trueK(trials);\n                vector<Features> obsFeat(trials);\n                for(int t=0;t<trials;t++){\n                    int k = rng() % M;\n                    trueK[t] = k;\n                    vector<vector<int>> H(n, vector<int>(n, 0));\n                    for(int i=0;i<n;i++) for(int j=i+1;j<n;j++){\n                        int e = (clusterOf[k][i] == clusterOf[k][j] && clusterOf[k][i] >= 0) ? 1 : 0;\n                        if(ur(rng) < eps) e = 1-e;\n                        H[i][j] = H[j][i] = e;\n                    }\n                    obsFeat[t] = computeObservedFeatures(H, n);\n                }\n                \n                vector<vector<double>> dDeg(trials, vector<double>(M));\n                vector<vector<double>> dF2(trials, vector<double>(M));\n                for(int t=0;t<trials;t++){\n                    for(int k=0;k<M;k++){\n                        dDeg[t][k] = distDeg(obsFeat[t], allFeat[chosen[k]], n);\n                        dF2[t][k] = distF2(obsFeat[t], allFeat[chosen[k]], n);\n                    }\n                }\n                \n                for(double wF2 : wF2Candidates){\n                    int errors = 0;\n                    for(int t=0;t<trials;t++){\n                        int best=0; double bd=1e18;\n                        for(int k=0;k<M;k++){\n                            double d = dDeg[t][k] + wF2 * dF2[t][k];\n                            if(d<bd){bd=d; best=k;}\n                        }\n                        if(best != trueK[t]) errors++;\n                    }\n                    double err = (double)errors / trials;\n                    double score = pow(0.9, 100*err) / n;\n                    if(score > bestScore){\n                        bestScore = score;\n                        bestN = n;\n                        bestMaxK = mK;\n                        bestWF2 = wF2;\n                    }\n                }\n            }\n        }\n    }\n    \n    int N = bestN, maxK = bestMaxK;\n    double wF2 = bestWF2;\n    int E = N*(N-1)/2;\n    auto parts = genParts_(N, maxK);\n    int P = parts.size();\n    vector<Features> allFeat(P);\n    for(int i=0;i<P;i++) allFeat[i] = computeExpectedFeatures(parts[i], N);\n    auto chosen = selectPartitions(allFeat, P, N);\n    \n    vector<Features> targetFeat(M);\n    for(int k=0;k<M;k++) targetFeat[k] = allFeat[chosen[k]];\n    \n    cout << N << \"\\n\";\n    for(int k=0;k<M;k++){\n        const auto& part = parts[chosen[k]];\n        string s(E, '0');\n        int p=0;\n        vector<pair<int,int>> cliqueRange;\n        int pos=0;\n        for(int sz : part){\n            cliqueRange.push_back({pos, pos+sz});\n            pos += sz;\n        }\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){\n            bool edge=false;\n            for(auto& pr : cliqueRange){\n                if(i>=pr.first && i<pr.second && j>=pr.first && j<pr.second){ edge=true; break; }\n            }\n            s[p++] = edge?'1':'0';\n        }\n        cout << s << \"\\n\";\n    }\n    cout.flush();\n    \n    for(int q=0;q<100;q++){\n        string h; cin >> h;\n        vector<vector<int>> H(N, vector<int>(N, 0));\n        int p=0;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){\n            H[i][j] = H[j][i] = (h[p++]=='1') ? 1 : 0;\n        }\n        auto obs = computeObservedFeatures(H, N);\n        int best=0; double bd=1e18;\n        for(int k=0;k<M;k++){\n            double d = distDeg(obs, targetFeat[k], N) + wF2 * distF2(obs, targetFeat[k], N);\n            if(d<bd){bd=d; best=k;}\n        }\n        cout << best << \"\\n\";\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint N, M, D, K;\nvector<vector<pair<int,int>>> adj;\nvector<int> W, Eu, Ev;\nvector<int> sources;\nvector<vector<ll>> baseDist;\nvector<int> assign_;\nvector<vector<int>> dayEdges;\nint S;\nvector<char> removed;\n\nvoid dijkstra(int src, vector<ll>& dist) {\n    fill(dist.begin(), dist.end(), (ll)2e18);\n    priority_queue<pair<ll,int>, vector<pair<ll,int>>, greater<>> pq;\n    dist[src] = 0;\n    pq.push({0, src});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist[u]) continue;\n        for (auto [v, eid] : adj[u]) {\n            if (removed[eid]) continue;\n            ll nd = d + W[eid];\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                pq.push({nd, v});\n            }\n        }\n    }\n}\n\ndouble dayCost(int k) {\n    for (int e : dayEdges[k]) removed[e] = 1;\n    double total = 0;\n    static vector<ll> dist;\n    if ((int)dist.size() != N) dist.assign(N, 0);\n    for (int si = 0; si < S; si++) {\n        dijkstra(sources[si], dist);\n        const auto& bd = baseDist[si];\n        for (int v = 0; v < N; v++) {\n            ll dv = (dist[v] >= (ll)1e18) ? 1000000000LL : dist[v];\n            total += (double)(dv - bd[v]);\n        }\n    }\n    for (int e : dayEdges[k]) removed[e] = 0;\n    return total;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> M >> D >> K;\n    adj.assign(N, {});\n    W.resize(M); Eu.resize(M); Ev.resize(M);\n    for (int i = 0; i < M; i++) {\n        int u,v,w; cin >> u >> v >> w; u--; v--;\n        Eu[i]=u; Ev[i]=v; W[i]=w;\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n    }\n    vector<int> X(N), Y(N);\n    for (int i = 0; i < N; i++) cin >> X[i] >> Y[i];\n    \n    removed.assign(M, 0);\n    \n    mt19937 rng(12345);\n    S = min(N, 40);\n    vector<int> perm(N);\n    iota(perm.begin(), perm.end(), 0);\n    shuffle(perm.begin(), perm.end(), rng);\n    sources.assign(perm.begin(), perm.begin()+S);\n    \n    baseDist.assign(S, vector<ll>(N));\n    for (int i = 0; i < S; i++) dijkstra(sources[i], baseDist[i]);\n    \n    assign_.assign(M, 0);\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){\n        double xa = (X[Eu[a]]+X[Ev[a]])*0.5, ya=(Y[Eu[a]]+Y[Ev[a]])*0.5;\n        double xb = (X[Eu[b]]+X[Ev[b]])*0.5, yb=(Y[Eu[b]]+Y[Ev[b]])*0.5;\n        return xa+ya < xb+yb;\n    });\n    \n    vector<int> dayCount(D, 0);\n    for (int i = 0; i < M; i++) {\n        int e = order[i];\n        int d = i % D;\n        while (dayCount[d] >= K) d = (d+1) % D;\n        assign_[e] = d;\n        dayCount[d]++;\n    }\n    \n    dayEdges.assign(D, {});\n    for (int i = 0; i < M; i++) dayEdges[assign_[i]].push_back(i);\n    \n    vector<double> costs(D);\n    for (int k = 0; k < D; k++) costs[k] = dayCost(k);\n    \n    auto startT = chrono::steady_clock::now();\n    double TIME_LIMIT = 5.3;\n    auto getTime = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now() - startT).count();\n    };\n    \n    double curTotal = 0;\n    for (double c : costs) curTotal += c;\n    vector<int> bestAssign = assign_;\n    double bestTotal = curTotal;\n    \n    int iter = 0, accepted = 0;\n    while (getTime() < TIME_LIMIT) {\n        iter++;\n        int op = rng() % 4;\n        if (op == 0) {\n            int e1 = rng() % M;\n            int d1 = assign_[e1];\n            int d2 = rng() % D;\n            if (d1 == d2) continue;\n            if ((int)dayEdges[d2].size() >= K) continue;\n            \n            auto& v1 = dayEdges[d1];\n            auto it1 = find(v1.begin(), v1.end(), e1);\n            v1.erase(it1);\n            dayEdges[d2].push_back(e1);\n            assign_[e1] = d2;\n            \n            double nc1 = dayCost(d1);\n            double nc2 = dayCost(d2);\n            double delta = (nc1+nc2) - (costs[d1]+costs[d2]);\n            if (delta < 0) {\n                costs[d1]=nc1; costs[d2]=nc2;\n                curTotal += delta;\n                accepted++;\n                if (curTotal < bestTotal) { bestTotal = curTotal; bestAssign = assign_; }\n            } else {\n                dayEdges[d2].pop_back();\n                v1.push_back(e1);\n                assign_[e1] = d1;\n            }\n        } else {\n            int e1 = rng() % M;\n            int e2 = rng() % M;\n            if (e1 == e2) continue;\n            int d1 = assign_[e1], d2 = assign_[e2];\n            if (d1 == d2) continue;\n            auto& v1 = dayEdges[d1];\n            auto& v2 = dayEdges[d2];\n            *find(v1.begin(), v1.end(), e1) = e2;\n            *find(v2.begin(), v2.end(), e2) = e1;\n            assign_[e1] = d2;\n            assign_[e2] = d1;\n            \n            double nc1 = dayCost(d1);\n            double nc2 = dayCost(d2);\n            double delta = (nc1+nc2) - (costs[d1]+costs[d2]);\n            if (delta < 0) {\n                costs[d1]=nc1; costs[d2]=nc2;\n                curTotal += delta;\n                accepted++;\n                if (curTotal < bestTotal) { bestTotal = curTotal; bestAssign = assign_; }\n            } else {\n                *find(v1.begin(), v1.end(), e2) = e1;\n                *find(v2.begin(), v2.end(), e1) = e2;\n                assign_[e1] = d1;\n                assign_[e2] = d2;\n            }\n        }\n    }\n    \n    cerr << \"iter=\" << iter << \" acc=\" << accepted << endl;\n    \n    for (int i = 0; i < M; i++) cout << bestAssign[i]+1 << \" \\n\"[i==M-1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nint F[2][14][14], R[2][14][14];\nint occ[2][14][14][14];\nint bid[2][14][14][14];\nint best_bid[2][14][14][14];\nint occ_init[2][14][14][14];\n\nint dx6[6]={1,-1,0,0,0,0};\nint dy6[6]={0,0,1,-1,0,0};\nint dz6[6]={0,0,0,0,1,-1};\n\nbool inb(int x,int y,int z){return x>=0&&x<D&&y>=0&&y<D&&z>=0&&z<D;}\n\nint fcount[2][14][14];\nint rcount[2][14][14];\nint fcount_init[2][14][14];\nint rcount_init[2][14][14];\n\nbool canRemove(int i,int x,int y,int z){\n    if(!occ[i][x][y][z]) return false;\n    if(F[i][z][x] && fcount[i][x][z]==1) return false;\n    if(R[i][z][y] && rcount[i][y][z]==1) return false;\n    return true;\n}\nvoid removeCell(int i,int x,int y,int z){\n    occ[i][x][y][z]=0;\n    fcount[i][x][z]--;\n    rcount[i][y][z]--;\n}\n\nmt19937 rng(98765);\n\nint rots[24][9];\n\nvoid genRots(){\n    int perms[6][3] = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};\n    int permSign[6] = {1,-1,-1,1,1,-1};\n    int cnt=0;\n    for(int p=0;p<6;p++){\n        for(int s=0;s<8;s++){\n            int sx = (s&1)?-1:1;\n            int sy = (s&2)?-1:1;\n            int sz = (s&4)?-1:1;\n            if(permSign[p]*sx*sy*sz != 1) continue;\n            int M[9]={0,0,0,0,0,0,0,0,0};\n            int signs[3]={sx,sy,sz};\n            for(int row=0;row<3;row++){\n                M[row*3 + perms[p][row]] = signs[row];\n            }\n            for(int k=0;k<9;k++) rots[cnt][k]=M[k];\n            cnt++;\n        }\n    }\n}\n\ninline void applyRot(int ri, int x, int y, int z, int& ox, int& oy, int& oz){\n    int* M = rots[ri];\n    ox = M[0]*x + M[1]*y + M[2]*z;\n    oy = M[3]*x + M[4]*y + M[5]*z;\n    oz = M[6]*x + M[7]*y + M[8]*z;\n}\n\ndouble evalScore(int (*curbid)[14][14][14]){\n    int maxId = 0;\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        maxId = max(maxId, curbid[i][x][y][z]);\n    vector<int> v1(maxId+1,0), v2(maxId+1,0);\n    for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n        if(curbid[0][x][y][z]) v1[curbid[0][x][y][z]]++;\n        if(curbid[1][x][y][z]) v2[curbid[1][x][y][z]]++;\n    }\n    double score = 0;\n    for(int id=1;id<=maxId;id++){\n        if(v1[id]>0 && v2[id]>0) score += 1.0/v1[id];\n        else if(v1[id]>0) score += v1[id];\n        else if(v2[id]>0) score += v2[id];\n    }\n    return score;\n}\n\nint visited[32][32][32];\nint visGen = 0;\n\nint growMax(int x1,int y1,int z1,int x2,int y2,int z2, int ri, int maxV,\n            vector<tuple<int,int,int>>& outBlock){\n    visGen++;\n    outBlock.clear();\n    static tuple<int,int,int> stackArr[4096];\n    int sp = 0;\n    outBlock.push_back({0,0,0});\n    visited[D][D][D] = visGen;\n    stackArr[sp++] = {0,0,0};\n    while(sp>0 && (int)outBlock.size()<maxV){\n        auto [ox,oy,oz] = stackArr[--sp];\n        for(int k=0;k<6;k++){\n            int nx=ox+dx6[k],ny=oy+dy6[k],nz=oz+dz6[k];\n            if(nx<=-D || nx>=D || ny<=-D || ny>=D || nz<=-D || nz>=D) continue;\n            if(visited[nx+D][ny+D][nz+D] == visGen) continue;\n            int ax=x1+nx, ay=y1+ny, az=z1+nz;\n            int rx,ry,rz;\n            applyRot(ri, nx, ny, nz, rx, ry, rz);\n            int bx=x2+rx, by=y2+ry, bz=z2+rz;\n            if(!inb(ax,ay,az)||!inb(bx,by,bz)) continue;\n            if(!occ[0][ax][ay][az]||bid[0][ax][ay][az]) continue;\n            if(!occ[1][bx][by][bz]||bid[1][bx][by][bz]) continue;\n            visited[nx+D][ny+D][nz+D] = visGen;\n            outBlock.push_back({nx,ny,nz});\n            if((int)outBlock.size()>=maxV) break;\n            stackArr[sp++] = {nx,ny,nz};\n        }\n    }\n    return outBlock.size();\n}\n\nvoid greedyMatch(double timeLimit, chrono::steady_clock::time_point start, int maxV, int tryRots, int& nextId){\n    while(true){\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed>timeLimit) break;\n        \n        vector<tuple<int,int,int>> a1, a2;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(occ[0][x][y][z]&&!bid[0][x][y][z]) a1.push_back({x,y,z});\n            if(occ[1][x][y][z]&&!bid[1][x][y][z]) a2.push_back({x,y,z});\n        }\n        if(a1.empty()||a2.empty()) break;\n        \n        int bestVol = 0;\n        vector<tuple<int,int,int>> bestCells1, bestCells2;\n        \n        shuffle(a1.begin(),a1.end(),rng);\n        shuffle(a2.begin(),a2.end(),rng);\n        \n        int totalBudget = 400;\n        int seedsPerDim = max(3, (int)sqrt((double)totalBudget/max(1,tryRots)));\n        int tries1 = min((int)a1.size(), seedsPerDim);\n        int tries2 = min((int)a2.size(), seedsPerDim);\n        \n        for(int t1=0;t1<tries1;t1++){\n            auto [x1,y1,z1] = a1[t1];\n            for(int t2=0;t2<tries2;t2++){\n                auto [x2,y2,z2] = a2[t2];\n                int rotIds[24];\n                for(int i=0;i<24;i++) rotIds[i]=i;\n                for(int i=23;i>0;i--){int j=rng()%(i+1);swap(rotIds[i],rotIds[j]);}\n                int numRots = min(tryRots, 24);\n                for(int rr=0;rr<numRots;rr++){\n                    int ri = rotIds[rr];\n                    vector<tuple<int,int,int>> block;\n                    int v = growMax(x1,y1,z1,x2,y2,z2,ri,maxV,block);\n                    if(v > bestVol){\n                        bestVol = v;\n                        bestCells1.clear(); bestCells2.clear();\n                        for(auto [ox,oy,oz]:block){\n                            bestCells1.push_back({x1+ox,y1+oy,z1+oz});\n                            int rx,ry,rz;\n                            applyRot(ri, ox, oy, oz, rx, ry, rz);\n                            bestCells2.push_back({x2+rx,y2+ry,z2+rz});\n                        }\n                    }\n                }\n            }\n            double el = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n            if(el>timeLimit) break;\n        }\n        \n        if(bestVol==0) break;\n        int id = nextId++;\n        for(auto [x,y,z]:bestCells1) bid[0][x][y][z]=id;\n        for(auto [x,y,z]:bestCells2) bid[1][x][y][z]=id;\n    }\n}\n\nvoid finalize(int& nextId){\n    for(int i=0;i<2;i++){\n        vector<tuple<int,int,int>> cells;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(occ[i][x][y][z]&&!bid[i][x][y][z]) cells.push_back({x,y,z});\n        }\n        shuffle(cells.begin(),cells.end(),rng);\n        bool changed=true;\n        while(changed){\n            changed=false;\n            for(auto [x,y,z]:cells){\n                if(occ[i][x][y][z]&&!bid[i][x][y][z]&&canRemove(i,x,y,z)){\n                    removeCell(i,x,y,z);\n                    changed=true;\n                }\n            }\n        }\n    }\n    \n    for(int i=0;i<2;i++){\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(occ[i][x][y][z]&&!bid[i][x][y][z]){\n                bid[i][x][y][z] = nextId++;\n            }\n        }\n    }\n}\n\nvoid resetState(){\n    memcpy(occ, occ_init, sizeof(occ));\n    memcpy(fcount, fcount_init, sizeof(fcount));\n    memcpy(rcount, rcount_init, sizeof(rcount));\n    memset(bid, 0, sizeof(bid));\n}\n\nint destroyBlocks(int strategy){\n    int maxId = 0;\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        maxId = max(maxId, bid[i][x][y][z]);\n    vector<int> v1(maxId+1,0), v2(maxId+1,0);\n    for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n        if(bid[0][x][y][z]) v1[bid[0][x][y][z]]++;\n        if(bid[1][x][y][z]) v2[bid[1][x][y][z]]++;\n    }\n    \n    set<int> destroySet;\n    \n    if(strategy == 0){\n        for(int id=1;id<=maxId;id++){\n            if(v1[id]==0 || v2[id]==0) destroySet.insert(id);\n            else if(v1[id] <= 2 && rng()%2==0) destroySet.insert(id);\n            else if(rng()%5==0) destroySet.insert(id);\n        }\n    } else if(strategy == 1){\n        for(int id=1;id<=maxId;id++){\n            if(v1[id]==0 || v2[id]==0) destroySet.insert(id);\n            else if(v1[id] <= 3) destroySet.insert(id);\n        }\n    } else if(strategy == 2){\n        int cx = rng()%D, cy = rng()%D, cz = rng()%D;\n        int rad = 2 + rng()%3;\n        for(int i=0;i<2;i++){\n            for(int x=max(0,cx-rad);x<min(D,cx+rad+1);x++)\n                for(int y=max(0,cy-rad);y<min(D,cy+rad+1);y++)\n                    for(int z=max(0,cz-rad);z<min(D,cz+rad+1);z++){\n                        if(bid[i][x][y][z]) destroySet.insert(bid[i][x][y][z]);\n                    }\n        }\n    } else if(strategy == 3){\n        for(int id=1;id<=maxId;id++){\n            if(rng()%10 < 3) destroySet.insert(id);\n        }\n    } else if(strategy == 4){\n        for(int id=1;id<=maxId;id++){\n            if(v1[id]==0 || v2[id]==0) destroySet.insert(id);\n        }\n    } else if(strategy == 5){\n        for(int id=1;id<=maxId;id++){\n            if(v1[id]==0 || v2[id]==0) destroySet.insert(id);\n            else if(v1[id] <= 4 && rng()%3==0) destroySet.insert(id);\n        }\n    }\n    \n    for(int i=0;i<2;i++){\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(destroySet.count(bid[i][x][y][z])){\n                bid[i][x][y][z] = 0;\n            }\n        }\n    }\n    \n    int curMaxId = 0;\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        curMaxId = max(curMaxId, bid[i][x][y][z]);\n    return curMaxId;\n}\n\nint main(){\n    genRots();\n    cin>>D;\n    for(int i=0;i<2;i++){\n        for(int z=0;z<D;z++){string s;cin>>s;for(int x=0;x<D;x++)F[i][z][x]=s[x]-'0';}\n        for(int z=0;z<D;z++){string s;cin>>s;for(int y=0;y<D;y++)R[i][z][y]=s[y]-'0';}\n    }\n    for(int i=0;i<2;i++){\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(F[i][z][x]&&R[i][z][y]){\n                occ_init[i][x][y][z]=1;\n                fcount_init[i][x][z]++;\n                rcount_init[i][y][z]++;\n            }\n        }\n    }\n    \n    auto start = chrono::steady_clock::now();\n    double TL_total = 5.5;\n    \n    double bestScore = 1e18;\n    \n    double phase1_end = min(TL_total * 0.3, 1.8);\n    int iter = 0;\n    while(true){\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed > phase1_end) break;\n        \n        resetState();\n        \n        double iter_budget = min(phase1_end - elapsed, 0.4);\n        auto iter_start = chrono::steady_clock::now();\n        \n        int maxV, tryRots;\n        int mode = iter % 6;\n        switch(mode){\n            case 0: maxV=1000; tryRots=1; break;\n            case 1: maxV=1000; tryRots=6; break;\n            case 2: maxV=1000; tryRots=24; break;\n            case 3: maxV=1000; tryRots=2; break;\n            case 4: maxV=1000; tryRots=12; break;\n            case 5: maxV=1000; tryRots=4; break;\n        }\n        \n        int nextId = 1;\n        greedyMatch(iter_budget, iter_start, maxV, tryRots, nextId);\n        finalize(nextId);\n        \n        double sc = evalScore(bid);\n        if(sc < bestScore){\n            bestScore = sc;\n            memcpy(best_bid, bid, sizeof(bid));\n        }\n        iter++;\n    }\n    \n    int drIter = 0;\n    while(true){\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed > TL_total - 0.2) break;\n        \n        resetState();\n        memcpy(bid, best_bid, sizeof(bid));\n        \n        int strategy = drIter % 6;\n        int curMaxId = destroyBlocks(strategy);\n        int nextId = curMaxId + 1;\n        \n        double repair_budget = min(TL_total - elapsed - 0.15, 0.35);\n        \n        int maxV, tryRots;\n        int mode = drIter % 5;\n        switch(mode){\n            case 0: maxV=1000; tryRots=2; break;\n            case 1: maxV=1000; tryRots=1; break;\n            case 2: maxV=1000; tryRots=6; break;\n            case 3: maxV=1000; tryRots=12; break;\n            case 4: maxV=1000; tryRots=24; break;\n        }\n        \n        auto repair_start = chrono::steady_clock::now();\n        greedyMatch(repair_budget, repair_start, maxV, tryRots, nextId);\n        finalize(nextId);\n        \n        double sc = evalScore(bid);\n        if(sc < bestScore){\n            bestScore = sc;\n            memcpy(best_bid, bid, sizeof(bid));\n        }\n        drIter++;\n    }\n    \n    int maxId = 0;\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        maxId = max(maxId, best_bid[i][x][y][z]);\n    \n    vector<int> used(maxId+1, 0);\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        if(best_bid[i][x][y][z]) used[best_bid[i][x][y][z]]=1;\n    vector<int> remap(maxId+1, 0);\n    int cur = 0;\n    for(int id=1;id<=maxId;id++) if(used[id]) remap[id] = ++cur;\n    \n    cout << cur << \"\\n\";\n    for(int i=0;i<2;i++){\n        bool first=true;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(!first) cout<<\" \";\n            cout << remap[best_bid[i][x][y][z]];\n            first=false;\n        }\n        cout<<\"\\n\";\n    }\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K;\nvector<int> X, Y;\nvector<int> EU, EV;\nvector<long long> EW;\nvector<int> A, B;\nvector<vector<pair<int,int>>> adj;\nvector<vector<float>> vr;  // use float for speed\n\nfloat dist2(float x1,float y1,float x2,float y2){\n    return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));\n}\n\nchrono::steady_clock::time_point startT;\ndouble elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-startT).count();}\n\nlong long computeCost(const vector<int>& P, const vector<int>& edgeOn){\n    long long s=0;\n    for(int i=0;i<N;i++) s += (long long)P[i]*P[i];\n    for(int j=0;j<M;j++) if(edgeOn[j]) s += EW[j];\n    return s;\n}\n\npair<vector<int>, vector<char>> buildTree(const vector<char>& isTerm){\n    vector<int> terms;\n    for(int i=0;i<N;i++) if(isTerm[i]) terms.push_back(i);\n    vector<char> inTree(N,0);\n    inTree[0]=1;\n    vector<int> edgeOn(M,0);\n    \n    while(true){\n        vector<long long> d(N, LLONG_MAX);\n        vector<int> pe(N,-1), pv(N,-1);\n        priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;\n        for(int i=0;i<N;i++) if(inTree[i]){ d[i]=0; pq.push({0,i}); }\n        while(!pq.empty()){\n            auto [du,u]=pq.top(); pq.pop();\n            if(du>d[u]) continue;\n            for(auto [v,eid]:adj[u]){\n                long long nd = du + EW[eid];\n                if(nd<d[v]){ d[v]=nd; pe[v]=eid; pv[v]=u; pq.push({nd,v}); }\n            }\n        }\n        int target=-1; long long bestD=LLONG_MAX;\n        for(int t:terms) if(!inTree[t] && d[t]<bestD){bestD=d[t]; target=t;}\n        if(target==-1) break;\n        int cur=target;\n        while(!inTree[cur]){\n            edgeOn[pe[cur]]=1;\n            inTree[cur]=1;\n            cur = pv[cur];\n        }\n    }\n    return {edgeOn, inTree};\n}\n\nvoid pruneTree(vector<int>& edgeOn, vector<char>& inTree, const vector<char>& isTerm){\n    bool changed=true;\n    while(changed){\n        changed=false;\n        vector<int> deg(N,0);\n        for(int j=0;j<M;j++) if(edgeOn[j]){deg[EU[j]]++; deg[EV[j]]++;}\n        for(int i=1;i<N;i++){\n            if(inTree[i] && !isTerm[i] && deg[i]==1){\n                for(int j=0;j<M;j++) if(edgeOn[j] && (EU[j]==i||EV[j]==i)){\n                    edgeOn[j]=0;\n                    break;\n                }\n                inTree[i]=0;\n                changed=true;\n            }\n        }\n    }\n}\n\nvector<int> computePFromTreeSmart(const vector<char>& inTree){\n    vector<int> treeV;\n    for(int i=0;i<N;i++) if(inTree[i]) treeV.push_back(i);\n    if(treeV.empty()) return vector<int>(N,0);\n    int TV = treeV.size();\n    \n    // Compute nearest distance for each resident\n    vector<pair<float,int>> order(K);\n    for(int k=0;k<K;k++){\n        float bd=1e18f;\n        for(int v:treeV) if(vr[v][k]<bd) bd=vr[v][k];\n        order[k]={bd,k};\n    }\n    sort(order.begin(),order.end(),greater<>());\n    \n    vector<float> r(N,0);\n    for(auto [d_,k]:order){\n        int bestV=-1;\n        float bestInc=1e18f;\n        for(int v:treeV){\n            float cv = vr[v][k];\n            float newR = max(r[v], cv);\n            if(newR>5000) continue;\n            float inc = newR*newR - r[v]*r[v];\n            if(inc<bestInc){bestInc=inc; bestV=v;}\n            if(inc==0) break; // optimal, can't do better\n        }\n        if(bestV<0){\n            float bd=1e18f; int bv=-1;\n            for(int v:treeV) if(vr[v][k]<bd){bd=vr[v][k]; bv=v;}\n            bestV=bv;\n        }\n        if(vr[bestV][k] > r[bestV]) r[bestV] = vr[bestV][k];\n    }\n    \n    vector<int> P(N,0);\n    for(int i=0;i<N;i++){\n        P[i]=(int)ceilf(r[i]);\n        if(P[i]>5000) P[i]=5000;\n    }\n    return P;\n}\n\nint main(){\n    startT = chrono::steady_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    cin>>N>>M>>K;\n    X.resize(N); Y.resize(N);\n    for(int i=0;i<N;i++) cin>>X[i]>>Y[i];\n    EU.resize(M); EV.resize(M); EW.resize(M);\n    adj.assign(N,{});\n    for(int j=0;j<M;j++){\n        cin>>EU[j]>>EV[j]>>EW[j];\n        EU[j]--; EV[j]--;\n        adj[EU[j]].push_back({EV[j],j});\n        adj[EV[j]].push_back({EU[j],j});\n    }\n    A.resize(K); B.resize(K);\n    for(int k=0;k<K;k++) cin>>A[k]>>B[k];\n    \n    vr.assign(N, vector<float>(K));\n    for(int i=0;i<N;i++)\n        for(int k=0;k<K;k++)\n            vr[i][k] = dist2((float)X[i],(float)Y[i],(float)A[k],(float)B[k]);\n    \n    mt19937 rng(12345);\n    \n    // Initial: each resident's nearest vertex as terminals\n    vector<char> isTerm(N,0);\n    isTerm[0]=1;\n    for(int k=0;k<K;k++){\n        int best=0; float bd=vr[0][k];\n        for(int i=1;i<N;i++) if(vr[i][k]<bd){bd=vr[i][k]; best=i;}\n        isTerm[best]=1;\n    }\n    \n    auto [edgeOn0, inTree0] = buildTree(isTerm);\n    pruneTree(edgeOn0, inTree0, isTerm);\n    vector<int> P0 = computePFromTreeSmart(inTree0);\n    long long bestCost = computeCost(P0, edgeOn0);\n    vector<int> bestP = P0;\n    vector<int> bestEdge = edgeOn0;\n    vector<char> bestInTree = inTree0;\n    \n    vector<char> curTerm(N,0);\n    for(int i=0;i<N;i++) curTerm[i] = inTree0[i];\n    curTerm[0]=1;\n    long long curCost = bestCost;\n    \n    auto evaluate = [&](const vector<char>& nt) -> tuple<long long, vector<int>, vector<int>, vector<char>>{\n        auto [ne, inT] = buildTree(nt);\n        pruneTree(ne, inT, nt);\n        vector<int> np = computePFromTreeSmart(inT);\n        long long nc = computeCost(np, ne);\n        return {nc, np, ne, inT};\n    };\n    \n    // Hill climb: toggle each vertex\n    int noImproveRounds=0;\n    double phase1End = 0.8;\n    while(elapsed()<phase1End && noImproveRounds<2){\n        bool improved=false;\n        vector<int> order(N);\n        iota(order.begin(),order.end(),0);\n        shuffle(order.begin(),order.end(),rng);\n        for(int v: order){\n            if(v==0) continue;\n            if(elapsed()>phase1End) break;\n            vector<char> nt = curTerm;\n            nt[v] = 1-nt[v];\n            auto [nc, np, ne, inT] = evaluate(nt);\n            if(nc<curCost){\n                curCost=nc;\n                curTerm = nt;\n                for(int i=0;i<N;i++) if(!inT[i]) curTerm[i]=0;\n                curTerm[0]=1;\n                if(nc<bestCost){\n                    bestCost=nc;\n                    bestP=np;\n                    bestEdge=ne;\n                    bestInTree=inT;\n                }\n                improved=true;\n            }\n        }\n        if(!improved) noImproveRounds++;\n        else noImproveRounds=0;\n    }\n    \n    // SA phase\n    double TL = 1.85;\n    double T0=5e5, T1=1e2;\n    while(elapsed()<TL){\n        double t = (elapsed()-phase1End)/(TL-phase1End);\n        if(t<0) t=0; if(t>1) t=1;\n        double T = T0 * pow(T1/T0, t);\n        \n        // Move type: 1) toggle; 2) swap (add one, remove one)\n        int mt = rng()%3;\n        vector<char> nt = curTerm;\n        if(mt==0 || mt==1){\n            int v = rng()%N;\n            if(v==0) continue;\n            nt[v] = 1-nt[v];\n        } else {\n            // swap: remove a random term, add a non-term\n            vector<int> terms, nonterms;\n            for(int i=1;i<N;i++){\n                if(nt[i]) terms.push_back(i);\n                else nonterms.push_back(i);\n            }\n            if(terms.empty() || nonterms.empty()) continue;\n            int a = terms[rng()%terms.size()];\n            int b = nonterms[rng()%nonterms.size()];\n            nt[a]=0; nt[b]=1;\n        }\n        auto [nc, np, ne, inT] = evaluate(nt);\n        double delta = (double)(nc - curCost);\n        if(delta<0 || exp(-delta/T) > (double)(rng()%100000)/100000.0){\n            curCost=nc;\n            curTerm = nt;\n            for(int i=0;i<N;i++) if(!inT[i]) curTerm[i]=0;\n            curTerm[0]=1;\n            if(nc<bestCost){\n                bestCost=nc;\n                bestP=np;\n                bestEdge=ne;\n                bestInTree=inT;\n            }\n        }\n    }\n    \n    // Final coverage check\n    for(int k=0;k<K;k++){\n        bool ok=false;\n        for(int i=0;i<N;i++) if(bestInTree[i] && vr[i][k]<=bestP[i]+1e-6f){ok=true;break;}\n        if(!ok){\n            int bv=-1; float bd=1e18f;\n            for(int i=0;i<N;i++) if(bestInTree[i] && vr[i][k]<bd){bd=vr[i][k]; bv=i;}\n            if(bv>=0) bestP[bv]=min(5000,(int)ceilf(bd));\n        }\n    }\n    \n    for(int i=0;i<N;i++) cout<<bestP[i]<<\" \\n\"[i==N-1];\n    for(int j=0;j<M;j++) cout<<bestEdge[j]<<\" \\n\"[j==M-1];\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nint N=30;\nint init_grid[30][30];\nint grid[30][30];\npair<int,int> pos[465];\nbool filled[30][30];\nint dist_[30][30];\npair<int,int> prev_[30][30];\n\nint dx6[]={-1,-1,0,0,1,1};\nint dy6[]={-1,0,-1,1,0,1};\n\nbool isAvailable(int x, int y){\n    if(x>=29) return false;\n    if(filled[x][y]) return false;\n    if(x==0) return true;\n    if(y-1>=0 && !filled[x-1][y-1]) return false;\n    if(y<=x-1 && !filled[x-1][y]) return false;\n    return true;\n}\n\nvoid dijkstra(int sx,int sy, int baseK, int base, int window){\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)dist_[i][j]=INT_MAX;\n    priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n    dist_[sx][sy]=0; pq.push({0,sx,sy});\n    while(!pq.empty()){\n        auto [d,x,y]=pq.top(); pq.pop();\n        if(d>dist_[x][y]) continue;\n        for(int dr=0;dr<6;dr++){\n            int nx=x+dx6[dr], ny=y+dy6[dr];\n            if(nx<0||nx>=N||ny<0||ny>nx) continue;\n            if(filled[nx][ny]) continue;\n            int v = grid[nx][ny];\n            int penalty = (v - baseK <= window) ? 1 : 0;\n            int nd = d + base + penalty;\n            if(nd < dist_[nx][ny]){\n                dist_[nx][ny]=nd;\n                prev_[nx][ny]={x,y};\n                pq.push({nd,nx,ny});\n            }\n        }\n    }\n}\n\nvector<tuple<int,int,int,int>> run(int base, int window, int randomness, mt19937& rng){\n    for(int i=0;i<30;i++)for(int j=0;j<30;j++){\n        grid[i][j] = init_grid[i][j];\n        filled[i][j] = false;\n    }\n    for(int i=0;i<30;i++)for(int j=0;j<=i;j++) pos[grid[i][j]] = {i,j};\n    \n    vector<tuple<int,int,int,int>> local_ops;\n    \n    for(int k=0;k<435;k++){\n        auto [cx,cy]=pos[k];\n        dijkstra(cx,cy,k,base,window);\n        vector<tuple<int,int,int>> cands;\n        for(int x=0;x<29;x++)for(int y=0;y<=x;y++){\n            if(!isAvailable(x,y)) continue;\n            if(dist_[x][y]==INT_MAX) continue;\n            cands.push_back({dist_[x][y], x, y});\n        }\n        sort(cands.begin(), cands.end());\n        int pick_range = min((int)cands.size(), randomness);\n        int pick = (pick_range > 1) ? (rng() % pick_range) : 0;\n        int btx = get<1>(cands[pick]);\n        int bty = get<2>(cands[pick]);\n        \n        vector<pair<int,int>> path;\n        int x=btx,y=bty;\n        while(!(x==cx&&y==cy)){\n            path.push_back({x,y});\n            auto [px,py]=prev_[x][y];\n            x=px; y=py;\n        }\n        path.push_back({cx,cy});\n        reverse(path.begin(),path.end());\n        for(int i=0;i+1<(int)path.size();i++){\n            int x1=path[i].first, y1=path[i].second;\n            int x2=path[i+1].first, y2=path[i+1].second;\n            local_ops.push_back({x1,y1,x2,y2});\n            int v1=grid[x1][y1], v2=grid[x2][y2];\n            swap(grid[x1][y1],grid[x2][y2]);\n            pos[v1]={x2,y2}; pos[v2]={x1,y1};\n        }\n        filled[btx][bty]=true;\n    }\n    return local_ops;\n}\n\nint main(){\n    auto start_time = chrono::steady_clock::now();\n    for(int x=0;x<N;x++)for(int y=0;y<=x;y++){\n        cin>>init_grid[x][y];\n    }\n    \n    vector<tuple<int,int,int,int>> best;\n    int best_size = INT_MAX;\n    mt19937 rng(42);\n    \n    vector<pair<int,int>> params = {\n        {1000, 0}, {1000, 20}, {1000, 50}, {1000, 100},\n        {2, 20}, {3, 50}, {5, 30}, {10, 50}, {1, 30}, {1, 50}\n    };\n    for(auto [b,w] : params){\n        auto ops = run(b,w,1,rng);\n        if((int)ops.size() < best_size){ best_size = (int)ops.size(); best = ops; }\n    }\n    \n    while(true){\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now-start_time).count();\n        if(elapsed > 1.7) break;\n        int b = (rng()%2==0) ? 1000 : (1 + rng() % 10);\n        int w = rng() % 100;\n        int r = 1 + rng() % 4;\n        auto ops = run(b,w,r,rng);\n        if((int)ops.size() < best_size){ best_size = (int)ops.size(); best = ops; }\n    }\n    \n    cout<<best.size()<<\"\\n\";\n    for(auto[a,b,c,d]:best)cout<<a<<\" \"<<b<<\" \"<<c<<\" \"<<d<<\"\\n\";\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N;\nint obs[9][9];\nint filled[9][9];\nint cellVal[9][9];\nint dr[4] = {-1, 1, 0, 0};\nint dc[4] = {0, 0, -1, 1};\n\nvoid bfs_reach(int reach[9][9]) {\n    for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) reach[i][j] = 0;\n    queue<pair<int,int>> q;\n    reach[0][4] = 1;\n    q.push({0, 4});\n    while (!q.empty()) {\n        int r = q.front().first, c = q.front().second;\n        q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= 9 || nc < 0 || nc >= 9) continue;\n            if (reach[nr][nc] || obs[nr][nc] || filled[nr][nc]) continue;\n            reach[nr][nc] = 1;\n            q.push({nr, nc});\n        }\n    }\n}\n\nvector<pair<int,int>> sim_greedy() {\n    int f[9][9];\n    memcpy(f, filled, sizeof(f));\n    vector<pair<int,int>> ord;\n    int total = 0;\n    for (int r=0;r<9;r++) for (int c=0;c<9;c++) if (f[r][c]) total++;\n    for (int step = 0; step < total; step++) {\n        int ev[9][9];\n        for (int i=0;i<9;i++) for (int j=0;j<9;j++) ev[i][j]=0;\n        queue<pair<int,int>> q;\n        ev[0][4]=1; q.push({0,4});\n        while (!q.empty()) {\n            int r=q.front().first, c=q.front().second; q.pop();\n            for (int d=0; d<4; d++) {\n                int nr=r+dr[d], nc=c+dc[d];\n                if (nr<0||nr>=9||nc<0||nc>=9||ev[nr][nc]||obs[nr][nc]||f[nr][nc]) continue;\n                ev[nr][nc]=1; q.push({nr,nc});\n            }\n        }\n        int bv = INT_MAX, br=-1, bc=-1;\n        for (int r=0;r<9;r++) for (int c=0;c<9;c++) {\n            if (!f[r][c]) continue;\n            bool adj=false;\n            for (int d=0; d<4; d++) {\n                int nr=r+dr[d], nc=c+dc[d];\n                if (nr<0||nr>=9||nc<0||nc>=9) continue;\n                if (ev[nr][nc]) { adj=true; break; }\n            }\n            if (!adj) continue;\n            if (cellVal[r][c] < bv) { bv = cellVal[r][c]; br=r; bc=c; }\n        }\n        if (br==-1) break;\n        f[br][bc]=0;\n        ord.push_back({br,bc});\n    }\n    return ord;\n}\n\nvector<pair<int,int>> sim_smart() {\n    int f[9][9];\n    memcpy(f, filled, sizeof(f));\n    vector<pair<int,int>> ord;\n    while (true) {\n        int minV=INT_MAX, mr=-1, mc=-1;\n        for (int r=0;r<9;r++) for (int c=0;c<9;c++)\n            if (f[r][c] && cellVal[r][c]<minV) { minV=cellVal[r][c]; mr=r; mc=c; }\n        if (mr==-1) break;\n        int dist[9][9];\n        pair<int,int> prv[9][9];\n        for (int i=0;i<9;i++) for (int j=0;j<9;j++) { dist[i][j]=INT_MAX; prv[i][j]={-1,-1}; }\n        deque<pair<int,int>> dq;\n        dist[0][4]=0; dq.push_front({0,4});\n        while (!dq.empty()) {\n            int r=dq.front().first, c=dq.front().second; dq.pop_front();\n            for (int d=0; d<4; d++) {\n                int nr=r+dr[d], nc=c+dc[d];\n                if (nr<0||nr>=9||nc<0||nc>=9||obs[nr][nc]) continue;\n                int cost = f[nr][nc]?1:0;\n                if (dist[r][c]+cost < dist[nr][nc]) {\n                    dist[nr][nc]=dist[r][c]+cost;\n                    prv[nr][nc]={r,c};\n                    if (cost==0) dq.push_front({nr,nc});\n                    else dq.push_back({nr,nc});\n                }\n            }\n        }\n        vector<pair<int,int>> path;\n        pair<int,int> cur={mr,mc};\n        int safety=200;\n        while ((cur.first!=0||cur.second!=4) && safety-->0) {\n            path.push_back(cur);\n            auto nxt=prv[cur.first][cur.second];\n            if (nxt.first==-1) break;\n            cur=nxt;\n        }\n        reverse(path.begin(), path.end());\n        int sr=-1,scc=-1;\n        for (auto& p : path) if (f[p.first][p.second]) { sr=p.first; scc=p.second; break; }\n        if (sr==-1) { sr=mr; scc=mc; }\n        f[sr][scc]=0;\n        ord.push_back({sr,scc});\n    }\n    return ord;\n}\n\nlong long count_inv(vector<pair<int,int>>& ord) {\n    int M = ord.size();\n    long long inv = 0;\n    for (int i = 0; i < M; i++) for (int j = i+1; j < M; j++) {\n        if (cellVal[ord[i].first][ord[i].second] > cellVal[ord[j].first][ord[j].second]) inv++;\n    }\n    return inv;\n}\n\nbool shippable_state(int f[9][9], pair<int,int> p) {\n    if (!f[p.first][p.second]) return false;\n    int ev[9][9];\n    for (int i=0;i<9;i++) for (int j=0;j<9;j++) ev[i][j]=0;\n    queue<pair<int,int>> q;\n    ev[0][4]=1; q.push({0,4});\n    while (!q.empty()) {\n        int r=q.front().first, c=q.front().second; q.pop();\n        for (int d=0; d<4; d++) {\n            int nr=r+dr[d], nc=c+dc[d];\n            if (nr<0||nr>=9||nc<0||nc>=9||ev[nr][nc]||obs[nr][nc]||f[nr][nc]) continue;\n            ev[nr][nc]=1; q.push({nr,nc});\n        }\n    }\n    for (int d=0; d<4; d++) {\n        int nr=p.first+dr[d], nc=p.second+dc[d];\n        if (nr<0||nr>=9||nc<0||nc>=9) continue;\n        if (ev[nr][nc]) return true;\n    }\n    return false;\n}\n\nbool try_move_forward(vector<pair<int,int>>& ord, int i, int j) {\n    int f[9][9];\n    memcpy(f, filled, sizeof(f));\n    for (int k = 0; k < i; k++) f[ord[k].first][ord[k].second] = 0;\n    for (int k = i+1; k <= j; k++) {\n        if (!shippable_state(f, ord[k])) return false;\n        f[ord[k].first][ord[k].second] = 0;\n    }\n    if (!shippable_state(f, ord[i])) return false;\n    auto tmp = ord[i];\n    ord.erase(ord.begin() + i);\n    ord.insert(ord.begin() + j, tmp);\n    return true;\n}\n\nbool try_move_backward(vector<pair<int,int>>& ord, int i, int j) {\n    int f[9][9];\n    memcpy(f, filled, sizeof(f));\n    for (int k = 0; k < j; k++) f[ord[k].first][ord[k].second] = 0;\n    if (!shippable_state(f, ord[i])) return false;\n    f[ord[i].first][ord[i].second] = 0;\n    for (int k = j; k < i; k++) {\n        if (!shippable_state(f, ord[k])) return false;\n        f[ord[k].first][ord[k].second] = 0;\n    }\n    auto tmp = ord[i];\n    ord.erase(ord.begin() + i);\n    ord.insert(ord.begin() + j, tmp);\n    return true;\n}\n\nvoid improve_shipping(vector<pair<int,int>>& ord, chrono::steady_clock::time_point t0, double deadline) {\n    int M = ord.size();\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        if (chrono::duration<double>(chrono::steady_clock::now()-t0).count() > deadline) break;\n        \n        // Forward or-opt: for each i, find best j > i with delta < 0, try to apply\n        for (int i = 0; i < M-1; i++) {\n            if (chrono::duration<double>(chrono::steady_clock::now()-t0).count() > deadline) break;\n            int vi = cellVal[ord[i].first][ord[i].second];\n            vector<pair<int,int>> cands; // (delta, j)\n            int delta = 0;\n            for (int j = i+1; j < M; j++) {\n                int vj = cellVal[ord[j].first][ord[j].second];\n                if (vj > vi) delta += 1;\n                else delta -= 1;\n                if (delta < 0) cands.push_back({delta, j});\n            }\n            sort(cands.begin(), cands.end()); // best (most negative) first\n            for (auto& p : cands) {\n                if (try_move_forward(ord, i, p.second)) {\n                    improved = true;\n                    break;\n                }\n            }\n        }\n        \n        // Backward or-opt\n        for (int i = M-1; i >= 1; i--) {\n            if (chrono::duration<double>(chrono::steady_clock::now()-t0).count() > deadline) break;\n            int vi = cellVal[ord[i].first][ord[i].second];\n            vector<pair<int,int>> cands;\n            int delta = 0;\n            for (int j = i-1; j >= 0; j--) {\n                int vj = cellVal[ord[j].first][ord[j].second];\n                if (vi > vj) delta += 1;\n                else delta -= 1;\n                if (delta < 0) cands.push_back({delta, j});\n            }\n            sort(cands.begin(), cands.end());\n            for (auto& p : cands) {\n                if (try_move_backward(ord, i, p.second)) {\n                    improved = true;\n                    break;\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    cin >> D >> N;\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        obs[r][c] = 1;\n    }\n    int M = 81 - 1 - N;\n    for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) cellVal[i][j] = -1;\n    \n    auto t0 = chrono::steady_clock::now();\n    \n    vector<pair<int,int>> order_vec;\n    int vis[9][9];\n    for (int i=0;i<9;i++) for (int j=0;j<9;j++) vis[i][j]=0;\n    queue<pair<int,int>> bq;\n    bq.push({0,4}); vis[0][4]=1;\n    while (!bq.empty()) {\n        auto p = bq.front(); bq.pop();\n        int r=p.first, c=p.second;\n        if (!(r==0&&c==4)) order_vec.push_back({r,c});\n        for (int d=0; d<4; d++) {\n            int nr=r+dr[d], nc=c+dc[d];\n            if (nr<0||nr>=9||nc<0||nc>=9||vis[nr][nc]||obs[nr][nc]) continue;\n            vis[nr][nc]=1;\n            bq.push({nr,nc});\n        }\n    }\n    \n    int pidx[9][9];\n    for (int i=0;i<9;i++) for (int j=0;j<9;j++) pidx[i][j]=-1;\n    for (int k=0; k<(int)order_vec.size(); k++)\n        pidx[order_vec[k].first][order_vec[k].second] = k;\n    \n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n        int reach[9][9];\n        bfs_reach(reach);\n        \n        int totalReach = 0;\n        for (int r=0;r<9;r++) for (int c=0;c<9;c++)\n            if (reach[r][c] && !(r==0&&c==4)) totalReach++;\n        \n        int bestK=-1, bestDiff=INT_MAX;\n        int bestSafeK=-1, bestSafeDiff=INT_MAX;\n        int fbR=-1, fbC=-1;\n        \n        for (int r=0;r<9;r++) {\n            for (int c=0;c<9;c++) {\n                if (obs[r][c]||filled[r][c]) continue;\n                if (r==0&&c==4) continue;\n                if (!reach[r][c]) continue;\n                fbR=r; fbC=c;\n                int k=pidx[r][c];\n                if (k<0) continue;\n                int diff=abs(k-t);\n                if (diff<bestDiff) { bestDiff=diff; bestK=k; }\n                \n                if (totalReach==1) {\n                    if (diff<bestSafeDiff) { bestSafeDiff=diff; bestSafeK=k; }\n                    continue;\n                }\n                \n                filled[r][c]=1;\n                int reach2[9][9];\n                bfs_reach(reach2);\n                filled[r][c]=0;\n                int newReach=0;\n                for (int i=0;i<9;i++) for (int j=0;j<9;j++)\n                    if (reach2[i][j] && !(i==0&&j==4)) newReach++;\n                if (newReach==totalReach-1) {\n                    if (diff<bestSafeDiff) { bestSafeDiff=diff; bestSafeK=k; }\n                }\n            }\n        }\n        \n        int pr, pc;\n        if (bestSafeK>=0) { pr=order_vec[bestSafeK].first; pc=order_vec[bestSafeK].second; }\n        else if (bestK>=0) { pr=order_vec[bestK].first; pc=order_vec[bestK].second; }\n        else { pr=fbR; pc=fbC; }\n        filled[pr][pc]=1;\n        cellVal[pr][pc]=t;\n        cout<<pr<<\" \"<<pc<<\"\\n\";\n        cout.flush();\n    }\n    \n    auto g = sim_greedy();\n    auto s = sim_smart();\n    long long gi = count_inv(g);\n    long long si = count_inv(s);\n    auto best = (gi <= si) ? g : s;\n    \n    improve_shipping(best, t0, 1.85);\n    \n    for (auto& p : best) cout << p.first << \" \" << p.second << \"\\n\";\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nint grid[55][55];\nint bestGrid[55][55];\nint bestNonZero;\nint curNonZero;\nint DX[4]={-1,1,0,0}, DY[4]={0,0,-1,1};\nvector<vector<int>> origAdj;\nvector<vector<int>> cnt;\nbool visBuf[55][55];\n\nbool localConnected(int r, int c, int F){\n    auto at = [&](int x, int y)->int{\n        if(x<0||x>=n||y<0||y>=n) return -1;\n        return grid[x][y];\n    };\n    bool ring[8];\n    ring[0] = at(r-1,c)==F;\n    ring[1] = at(r-1,c+1)==F;\n    ring[2] = at(r,c+1)==F;\n    ring[3] = at(r+1,c+1)==F;\n    ring[4] = at(r+1,c)==F;\n    ring[5] = at(r+1,c-1)==F;\n    ring[6] = at(r,c-1)==F;\n    ring[7] = at(r-1,c-1)==F;\n    int orthCount = (int)ring[0]+ring[2]+ring[4]+ring[6];\n    if(orthCount==0) return false;\n    if(orthCount==1) return true;\n    int trans=0;\n    for(int i=0;i<8;i++)if(ring[i] != ring[(i+1)%8])trans++;\n    return trans<=2;\n}\n\nbool fullRemovableBFS(int r, int c, int F){\n    int sr=-1,sc=-1;\n    bool hasOther=false;\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&&grid[nr][nc]==F){\n            if(sr<0){sr=nr;sc=nc;}\n            else hasOther=true;\n        }\n    }\n    if(sr<0)return false;\n    if(!hasOther)return true;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)visBuf[i][j]=false;\n    static int qx[3000], qy[3000];\n    int qh=0,qt=0;\n    qx[qt]=sr;qy[qt]=sc;qt++;\n    visBuf[sr][sc]=true;\n    while(qh<qt){\n        int x=qx[qh],y=qy[qh];qh++;\n        for(int d=0;d<4;d++){\n            int nx=x+DX[d],ny=y+DY[d];\n            if(nx<0||nx>=n||ny<0||ny>=n)continue;\n            if(visBuf[nx][ny])continue;\n            if(nx==r&&ny==c)continue;\n            if(grid[nx][ny]!=F)continue;\n            visBuf[nx][ny]=true;\n            qx[qt]=nx;qy[qt]=ny;qt++;\n        }\n    }\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&&grid[nr][nc]==F && !visBuf[nr][nc])return false;\n    }\n    return true;\n}\n\nbool removable(int r, int c, int F){\n    if(localConnected(r,c,F))return true;\n    return fullRemovableBFS(r,c,F);\n}\n\nbool tryChange(int r, int c, int T){\n    int F = grid[r][c];\n    if(F==T)return false;\n    int nbrs[4];\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)nbrs[d]=0;\n        else nbrs[d]=grid[nr][nc];\n    }\n    bool tOk=false;\n    if(T==0){\n        if(r==0||r==n-1||c==0||c==n-1) tOk=true;\n        else for(int d=0;d<4;d++)if(nbrs[d]==0){tOk=true;break;}\n    } else {\n        for(int d=0;d<4;d++)if(nbrs[d]==T){tOk=true;break;}\n    }\n    if(!tOk) return false;\n    \n    for(int d=0;d<4;d++){\n        int N=nbrs[d];\n        if(F != N){ cnt[F][N]--; cnt[N][F]--; }\n        if(T != N){ cnt[T][N]++; cnt[N][T]++; }\n    }\n    \n    bool ok=true;\n    auto chk=[&](int a,int b)->bool{\n        if(a==b)return true;\n        return (origAdj[a][b]!=0)==(cnt[a][b]>0);\n    };\n    for(int d=0;d<4;d++){\n        int N=nbrs[d];\n        if(N!=F && !chk(F,N)){ok=false;break;}\n        if(ok && N!=T && !chk(T,N)){ok=false;break;}\n    }\n    if(ok && !chk(F,T))ok=false;\n    \n    auto revert=[&](){\n        for(int d=0;d<4;d++){\n            int N=nbrs[d];\n            if(T != N){ cnt[T][N]--; cnt[N][T]--; }\n            if(F != N){ cnt[F][N]++; cnt[N][F]++; }\n        }\n    };\n    \n    if(!ok){ revert(); return false; }\n    \n    grid[r][c]=T;\n    if(!removable(r,c,F)){\n        grid[r][c]=F;\n        revert();\n        return false;\n    }\n    if(F!=0 && T==0) curNonZero--;\n    else if(F==0 && T!=0) curNonZero++;\n    return true;\n}\n\nvoid saveBest(){\n    if(curNonZero < bestNonZero){\n        bestNonZero = curNonZero;\n        memcpy(bestGrid, grid, sizeof(grid));\n    }\n}\n\nstruct Edge { short r,c,d; };\nvector<Edge> edges;\nvoid collectEdges(){\n    edges.clear();\n    edges.reserve(8000);\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        int c_=grid[i][j];\n        for(int d=0;d<4;d++){\n            int ni=i+DX[d],nj=j+DY[d];\n            int nc = (ni<0||ni>=n||nj<0||nj>=n) ? 0 : grid[ni][nj];\n            if(c_ != nc) edges.push_back({(short)i,(short)j,(short)d});\n        }\n    }\n}\n\nint main(){\n    cin>>n>>m;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)cin>>grid[i][j];\n    \n    cnt.assign(m+1, vector<int>(m+1, 0));\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        int a=grid[i][j];\n        for(int d=0;d<4;d++){\n            int ni=i+DX[d],nj=j+DY[d];\n            if(ni<0||ni>=n||nj<0||nj>=n){\n                cnt[a][0]++; cnt[0][a]++;\n            } else {\n                int b=grid[ni][nj];\n                cnt[a][b]++;\n            }\n        }\n    }\n    origAdj.assign(m+1, vector<int>(m+1,0));\n    for(int a=0;a<=m;a++)for(int b=0;b<=m;b++)if(a!=b && cnt[a][b]>0)origAdj[a][b]=1;\n    \n    curNonZero=0;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(grid[i][j]!=0)curNonZero++;\n    \n    bestNonZero = curNonZero;\n    memcpy(bestGrid, grid, sizeof(grid));\n    \n    auto startTime = chrono::steady_clock::now();\n    auto elapsed = [&]()->long long{\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();\n    };\n    mt19937 rng(42);\n    uniform_real_distribution<double> urd(0.0, 1.0);\n    \n    // Initial greedy\n    for(int pass=0; pass<15 && elapsed()<250; pass++){\n        vector<pair<int,int>> cells;\n        for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(grid[i][j]!=0)cells.push_back({i,j});\n        shuffle(cells.begin(), cells.end(), rng);\n        bool any=false;\n        for(auto[r,c]:cells){\n            if(grid[r][c]==0)continue;\n            if(tryChange(r,c,0))any=true;\n        }\n        if(!any)break;\n    }\n    saveBest();\n    \n    long long TL = 1850;\n    double T_start = 1.5, T_end = 0.02;\n    int sinceCollect=0;\n    collectEdges();\n    \n    while(elapsed() < TL){\n        double progress = (double)elapsed() / (double)TL;\n        double Temp = T_start * pow(T_end/T_start, progress);\n        \n        for(int k=0;k<8000 && elapsed()<TL;k++){\n            if(edges.empty()){collectEdges(); if(edges.empty())break;}\n            int ei = rng()%edges.size();\n            Edge e = edges[ei];\n            int r=e.r, c=e.c, d=e.d;\n            int F = grid[r][c];\n            int ni=r+DX[d], nj=c+DY[d];\n            int T_color = (ni<0||ni>=n||nj<0||nj>=n) ? 0 : grid[ni][nj];\n            if(F==T_color) continue;\n            \n            int chosenR, chosenC, chosenT, chosenF;\n            // With some prob, do the reverse direction\n            bool reverseDir = (rng()%2 == 0) && !(ni<0||ni>=n||nj<0||nj>=n);\n            if(!reverseDir){\n                chosenR=r; chosenC=c; chosenT=T_color; chosenF=F;\n            } else {\n                chosenR=ni; chosenC=nj; chosenT=F; chosenF=T_color;\n            }\n            int delta = 0;\n            if(chosenF==0 && chosenT!=0) delta=1;\n            else if(chosenF!=0 && chosenT==0) delta=-1;\n            \n            if(delta > 0){\n                double p = exp(-(double)delta/Temp);\n                if(urd(rng) > p) continue;\n            }\n            \n            if(tryChange(chosenR,chosenC,chosenT)){\n                if(curNonZero < bestNonZero) saveBest();\n                sinceCollect++;\n                if(sinceCollect > 200){\n                    collectEdges();\n                    sinceCollect = 0;\n                }\n            }\n        }\n        \n        // Greedy 0-flip exploit\n        collectEdges();\n        vector<pair<int,int>> bdCells;\n        {\n            static bool seen_[55][55];\n            for(int i=0;i<n;i++)for(int j=0;j<n;j++)seen_[i][j]=false;\n            for(auto&e:edges){\n                if(grid[e.r][e.c]!=0 && !seen_[e.r][e.c]){\n                    seen_[e.r][e.c]=true;\n                    bdCells.push_back({e.r,e.c});\n                }\n            }\n        }\n        shuffle(bdCells.begin(), bdCells.end(), rng);\n        for(auto[r,c]:bdCells){\n            if(grid[r][c]==0)continue;\n            if(tryChange(r,c,0)){\n                if(curNonZero < bestNonZero) saveBest();\n            }\n        }\n        collectEdges();\n        sinceCollect = 0;\n    }\n    \n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            cout<<bestGrid[i][j]<<(j+1<n?' ':'\\n');\n        }\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\nint ask(const vector<int>& L, const vector<int>& R) {\n    queries_used++;\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << \"\\n\";\n    cout.flush();\n    char c; cin >> c;\n    if (c == '<') return -1;\n    if (c == '>') return 1;\n    return 0;\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    int expected_sort_cost = (int)(N * log2(max(2, N))) + 5;\n    int sort_budget;\n    if (Q >= 3 * expected_sort_cost) {\n        sort_budget = expected_sort_cost + N;\n    } else {\n        sort_budget = Q / 2;\n    }\n    int reserve = Q - sort_budget;\n    \n    function<vector<int>(vector<int>)> msort = [&](vector<int> v) -> vector<int> {\n        if (v.size() <= 1) return v;\n        int mid = v.size()/2;\n        vector<int> L(v.begin(), v.begin()+mid);\n        vector<int> R(v.begin()+mid, v.end());\n        L = msort(L);\n        R = msort(R);\n        vector<int> res;\n        int i=0,j=0;\n        while (i<(int)L.size() && j<(int)R.size()) {\n            if (queries_used >= Q - reserve) {\n                while (i<(int)L.size()) res.push_back(L[i++]);\n                while (j<(int)R.size()) res.push_back(R[j++]);\n                return res;\n            }\n            int c = ask({L[i]}, {R[j]});\n            if (c <= 0) res.push_back(L[i++]);\n            else res.push_back(R[j++]);\n        }\n        while (i<(int)L.size()) res.push_back(L[i++]);\n        while (j<(int)R.size()) res.push_back(R[j++]);\n        return res;\n    };\n    \n    vector<int> sorted_items = msort(items);\n    reverse(sorted_items.begin(), sorted_items.end());\n    \n    vector<double> est_weight(N);\n    for (int k = 0; k < N; k++) {\n        double s = 0;\n        for (int i = k+1; i <= N; i++) s += 1.0/i;\n        est_weight[sorted_items[k]] = s;\n    }\n    \n    auto gweight = [&](const vector<int>& g) {\n        double s = 0;\n        for (int x : g) s += est_weight[x];\n        return s;\n    };\n    \n    vector<vector<int>> groups(D);\n    for (int i = 0; i < N; i++) {\n        int best = 0;\n        double bestv = gweight(groups[0]);\n        for (int d = 1; d < D; d++) {\n            double v = gweight(groups[d]);\n            if (v < bestv) { bestv = v; best = d; }\n        }\n        groups[best].push_back(sorted_items[i]);\n    }\n    \n    auto try_move = [&](int heavy, int light, const vector<int>& from_h, const vector<int>& from_l) -> int {\n        if (queries_used >= Q) return -1;\n        int h_new = (int)groups[heavy].size() - (int)from_h.size() + (int)from_l.size();\n        int l_new = (int)groups[light].size() - (int)from_l.size() + (int)from_h.size();\n        if (h_new == 0 || l_new == 0) return -1;\n        \n        set<int> sh(from_h.begin(), from_h.end());\n        set<int> sl(from_l.begin(), from_l.end());\n        vector<int> nh, nl;\n        for (int z : groups[heavy]) if (!sh.count(z)) nh.push_back(z);\n        for (int y : from_l) nh.push_back(y);\n        for (int z : groups[light]) if (!sl.count(z)) nl.push_back(z);\n        for (int y : from_h) nl.push_back(y);\n        \n        int c = ask(nh, nl);\n        if (c >= 0) {\n            groups[heavy] = nh;\n            groups[light] = nl;\n            return c > 0 ? 1 : 0;\n        }\n        return -1;\n    };\n    \n    set<pair<int,int>> failed_pairs;\n    int total_resets = 0;\n    \n    auto clear_involving = [&](int a, int b) {\n        set<pair<int,int>> keep;\n        for (auto& p : failed_pairs) {\n            if (p.first != a && p.first != b && p.second != a && p.second != b) {\n                keep.insert(p);\n            }\n        }\n        failed_pairs = keep;\n    };\n    \n    while (queries_used < Q - 1) {\n        vector<int> order(D);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b){\n            return gweight(groups[a]) > gweight(groups[b]);\n        });\n        \n        int heavy = -1, light = -1;\n        for (int i = 0; i < D && heavy == -1; i++) {\n            for (int j = D-1; j > i && heavy == -1; j--) {\n                int A = order[i], B = order[j];\n                auto p = make_pair(min(A,B), max(A,B));\n                if (failed_pairs.count(p)) continue;\n                heavy = A;\n                light = B;\n            }\n        }\n        if (heavy == -1) {\n            failed_pairs.clear();\n            total_resets++;\n            if (total_resets > 3) break;\n            continue;\n        }\n        \n        if (queries_used >= Q) break;\n        int c = ask(groups[heavy], groups[light]);\n        auto pair_key = make_pair(min(heavy, light), max(heavy, light));\n        \n        if (c == 0) {\n            failed_pairs.insert(pair_key);\n            continue;\n        }\n        if (c < 0) swap(heavy, light);\n        \n        bool any_improved = false;\n        while (queries_used < Q) {\n            vector<int> hi = groups[heavy];\n            sort(hi.begin(), hi.end(), [&](int a, int b){ return est_weight[a] < est_weight[b]; });\n            \n            if ((int)groups[heavy].size() <= 1) break;\n            int x = hi[0];\n            \n            int r = try_move(heavy, light, {x}, {});\n            if (r >= 0) {\n                any_improved = true;\n                if (r == 0) break;\n                continue;\n            }\n            \n            bool sub_improved = false;\n            vector<int> li_sorted = groups[light];\n            sort(li_sorted.begin(), li_sorted.end(), [&](int a, int b){ return est_weight[a] < est_weight[b]; });\n            \n            double est_diff = gweight(groups[heavy]) - gweight(groups[light]);\n            if (est_diff < 0.01) est_diff = 0.01;\n            \n            vector<int> y_candidates;\n            for (int y : li_sorted) {\n                if (est_weight[y] < est_weight[x]) {\n                    y_candidates.push_back(y);\n                    break;\n                }\n            }\n            double target = est_weight[x] - est_diff / 2.0;\n            for (int y : li_sorted) {\n                if (est_weight[y] >= est_weight[x]) break;\n                if (est_weight[y] >= target) {\n                    if (y_candidates.empty() || y != y_candidates[0]) y_candidates.push_back(y);\n                    break;\n                }\n            }\n            \n            for (int y : y_candidates) {\n                if (queries_used >= Q) break;\n                int r2 = try_move(heavy, light, {x}, {y});\n                if (r2 >= 0) {\n                    any_improved = true;\n                    sub_improved = true;\n                    break;\n                }\n            }\n            if (sub_improved) continue;\n            \n            vector<tuple<double,int,int>> pairs;\n            for (int a : groups[heavy]) for (int b : groups[light]) {\n                if (est_weight[a] > est_weight[b]) {\n                    pairs.push_back({est_weight[a] - est_weight[b], a, b});\n                }\n            }\n            sort(pairs.begin(), pairs.end());\n            bool sw_improved = false;\n            for (auto& [diff, a, b] : pairs) {\n                if (queries_used >= Q) break;\n                int r2 = try_move(heavy, light, {a}, {b});\n                if (r2 >= 0) {\n                    any_improved = true;\n                    sw_improved = true;\n                    break;\n                }\n                break;\n            }\n            if (sw_improved) continue;\n            \n            break;\n        }\n        \n        if (any_improved) {\n            clear_involving(heavy, light);\n        } else {\n            failed_pairs.insert(pair_key);\n        }\n    }\n    \n    while (queries_used < Q) ask({0}, {1});\n    \n    vector<int> d(N, 0);\n    for (int g = 0; g < D; g++) for (int x : groups[g]) d[x] = g;\n    for (int i = 0; i < N; i++) {\n        cout << d[i];\n        cout << (i == N-1 ? '\\n' : ' ');\n    }\n    cout.flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\n\nstruct State {\n    vector<vector<int>> stk;\n    vector<int> posS, posD;\n    \n    void init(int sz) {\n        posS.assign(sz+1, -1);\n        posD.assign(sz+1, -1);\n    }\n    \n    void rebuildPos() {\n        for (int i = 0; i < (int)stk.size(); i++)\n            for (int j = 0; j < (int)stk[i].size(); j++) {\n                posS[stk[i][j]] = i;\n                posD[stk[i][j]] = j;\n            }\n    }\n    \n    void movePile(int si, int pos, int dest) {\n        int base = stk[dest].size();\n        int k = (int)stk[si].size() - pos - 1;\n        for (int j = 0; j < k; j++) {\n            int b = stk[si][pos + 1 + j];\n            stk[dest].push_back(b);\n            posS[b] = dest;\n            posD[b] = base + j;\n        }\n        stk[si].resize(pos + 1);\n    }\n    \n    void pop(int si) {\n        stk[si].pop_back();\n    }\n};\n\nint chooseDestination(State& st, int si, int pos) {\n    int maxMoved = 0;\n    for (int j = pos + 1; j < (int)st.stk[si].size(); j++)\n        maxMoved = max(maxMoved, st.stk[si][j]);\n    \n    int mins[16];\n    for (int i = 0; i < m; i++) {\n        if (st.stk[i].empty()) mins[i] = INT_MAX;\n        else {\n            int mn = INT_MAX;\n            for (int x : st.stk[i]) mn = min(mn, x);\n            mins[i] = mn;\n        }\n    }\n    \n    int best = -1;\n    int bestMin = INT_MAX;\n    int emptyStack = -1;\n    for (int i = 0; i < m; i++) {\n        if (i == si) continue;\n        if (st.stk[i].empty()) { if (emptyStack == -1) emptyStack = i; continue; }\n        if (mins[i] > maxMoved && mins[i] < bestMin) {\n            bestMin = mins[i]; best = i;\n        }\n    }\n    if (best == -1 && emptyStack != -1) best = emptyStack;\n    if (best == -1) {\n        int bestScore = INT_MAX, bestTop = -1;\n        for (int i = 0; i < m; i++) {\n            if (i == si) continue;\n            int mn = mins[i];\n            int above_mn = 0;\n            for (int j = (int)st.stk[i].size() - 1; j >= 0; j--) {\n                if (st.stk[i][j] == mn) break;\n                above_mn++;\n            }\n            int cnt = 0;\n            for (int j = pos + 1; j < (int)st.stk[si].size(); j++)\n                if (st.stk[si][j] > mn) cnt++;\n            int score = cnt + above_mn;\n            int t = st.stk[i].back();\n            if (score < bestScore || (score == bestScore && t > bestTop)) {\n                bestScore = score; best = i; bestTop = t;\n            }\n        }\n    }\n    return best;\n}\n\nint rolloutCost(State& st, int startV) {\n    int cost = 0;\n    for (int v = startV; v <= n; v++) {\n        int si = st.posS[v];\n        int pos = st.posD[v];\n        int sz = (int)st.stk[si].size();\n        int above = sz - 1 - pos;\n        if (above > 0) {\n            int dest = chooseDestination(st, si, pos);\n            cost += above + 1;\n            st.movePile(si, pos, dest);\n        }\n        st.pop(si);\n    }\n    return cost;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    cin >> n >> m;\n    State real;\n    real.stk.assign(m, {});\n    real.init(n);\n    for (int i = 0; i < m; i++) {\n        real.stk[i].resize(n/m);\n        for (int j = 0; j < n/m; j++) cin >> real.stk[i][j];\n    }\n    real.rebuildPos();\n    \n    auto startTime = chrono::steady_clock::now();\n    \n    vector<pair<int,int>> ops;\n    \n    for (int v = 1; v <= n; v++) {\n        int si = real.posS[v];\n        int pos = real.posD[v];\n        int sz = (int)real.stk[si].size();\n        int above = sz - 1 - pos;\n        \n        if (above > 0) {\n            int immCost = above + 1;\n            int movedBox = real.stk[si][pos + 1];\n            \n            double elapsed = chrono::duration<double>(chrono::steady_clock::now() - startTime).count();\n            bool twoStep = (elapsed < 1.5);\n            \n            int bestDest = -1;\n            int bestTotal = INT_MAX;\n            \n            for (int d1 = 0; d1 < m; d1++) {\n                if (d1 == si) continue;\n                State sim1 = real;\n                sim1.movePile(si, pos, d1);\n                sim1.pop(si);\n                \n                int w = v + 1;\n                while (w <= n) {\n                    int wi = sim1.posS[w];\n                    int wpos = sim1.posD[w];\n                    if (wpos == (int)sim1.stk[wi].size() - 1) {\n                        sim1.pop(wi);\n                        w++;\n                    } else break;\n                }\n                \n                int d1cost;\n                if (w > n) {\n                    d1cost = immCost;\n                } else if (!twoStep) {\n                    d1cost = immCost + rolloutCost(sim1, w);\n                } else {\n                    int wi = sim1.posS[w];\n                    int wpos = sim1.posD[w];\n                    int w_above = (int)sim1.stk[wi].size() - 1 - wpos;\n                    \n                    if (w_above == 0) {\n                        State sim2 = sim1;\n                        sim2.pop(wi);\n                        d1cost = immCost + rolloutCost(sim2, w + 1);\n                    } else {\n                        int wImm = w_above + 1;\n                        int bestW = INT_MAX;\n                        for (int d2 = 0; d2 < m; d2++) {\n                            if (d2 == wi) continue;\n                            State sim2 = sim1;\n                            sim2.movePile(wi, wpos, d2);\n                            sim2.pop(wi);\n                            int w2 = w + 1;\n                            while (w2 <= n) {\n                                int wi2 = sim2.posS[w2];\n                                int wpos2 = sim2.posD[w2];\n                                if (wpos2 == (int)sim2.stk[wi2].size() - 1) {\n                                    sim2.pop(wi2);\n                                    w2++;\n                                } else break;\n                            }\n                            int total = (w2 > n) ? wImm : wImm + rolloutCost(sim2, w2);\n                            if (total < bestW) bestW = total;\n                        }\n                        d1cost = immCost + bestW;\n                    }\n                }\n                \n                if (d1cost < bestTotal) { bestTotal = d1cost; bestDest = d1; }\n            }\n            \n            ops.push_back({movedBox, bestDest + 1});\n            real.movePile(si, pos, bestDest);\n        }\n        ops.push_back({v, 0});\n        real.pop(si);\n    }\n    \n    for (auto& [a, b] : ops) cout << a << \" \" << b << \"\\n\";\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> hh, vv;\nvector<vector<int>> d;\nint dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};\nchar DC[4]={'U','D','L','R'};\n\nbool canMove(int x,int y,int dir){\n    int nx=x+dx[dir], ny=y+dy[dir];\n    if(nx<0||nx>=N||ny<0||ny>=N) return false;\n    if(dir==0) return hh[nx][y]=='0';\n    if(dir==1) return hh[x][y]=='0';\n    if(dir==2) return vv[x][ny]=='0';\n    if(dir==3) return vv[x][y]=='0';\n    return false;\n}\n\nvector<vector<vector<vector<int>>>> allPar;\nvector<vector<vector<vector<int>>>> allD;\n\nvoid computeAllDist(){\n    allPar.assign(N,vector<vector<vector<int>>>(N,vector<vector<int>>(N,vector<int>(N,-1))));\n    allD.assign(N,vector<vector<vector<int>>>(N,vector<vector<int>>(N,vector<int>(N,INT_MAX))));\n    for(int sx=0;sx<N;sx++)for(int sy=0;sy<N;sy++){\n        auto& D=allD[sx][sy];\n        auto& P=allPar[sx][sy];\n        D[sx][sy]=0;\n        queue<pair<int,int>> q; q.push({sx,sy});\n        while(!q.empty()){\n            auto [x,y]=q.front(); q.pop();\n            for(int d2=0;d2<4;d2++) if(canMove(x,y,d2)){\n                int nx=x+dx[d2], ny=y+dy[d2];\n                if(D[nx][ny]>D[x][y]+1){ D[nx][ny]=D[x][y]+1; P[nx][ny]=d2; q.push({nx,ny}); }\n            }\n        }\n    }\n}\n\nvector<int> getPath(int sx,int sy,int tx,int ty){\n    vector<int> res;\n    int x=tx,y=ty;\n    while(!(x==sx&&y==sy)){\n        int dir=allPar[sx][sy][x][y];\n        if(dir<0) return {};\n        res.push_back(dir);\n        int rdir = dir^1;\n        x+=dx[rdir]; y+=dy[rdir];\n    }\n    reverse(res.begin(),res.end());\n    return res;\n}\n\nvector<int> dfsResult;\nvector<vector<bool>> dfsVisited;\nvoid dfs(int x,int y){\n    dfsVisited[x][y]=true;\n    for(int dir=0;dir<4;dir++){\n        if(canMove(x,y,dir)){\n            int nx=x+dx[dir],ny=y+dy[dir];\n            if(!dfsVisited[nx][ny]){\n                dfsResult.push_back(dir);\n                dfs(nx,ny);\n                dfsResult.push_back(dir^1);\n            }\n        }\n    }\n}\n\nstatic vector<vector<int>> timesFlat;\ndouble computeScore(const vector<int>& tr){\n    int L=tr.size();\n    if(L==0) return 1e18;\n    for(auto& v : timesFlat) v.clear();\n    int x=0,y=0;\n    timesFlat[0].push_back(0);\n    for(int t=0;t<L;t++){\n        x+=dx[tr[t]]; y+=dy[tr[t]];\n        timesFlat[x*N+y].push_back(t+1);\n    }\n    if(x!=0||y!=0) return 1e18;\n    double total=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        auto& T=timesFlat[i*N+j];\n        if(T.empty()) return 1e18;\n        int k = T.size();\n        int endIdx = k;\n        if(T[k-1] == L) endIdx = k-1;\n        if(endIdx == 0) return 1e18;\n        long long sumSq=0;\n        for(int m=0;m<endIdx;m++){\n            int g = (m+1<endIdx ? T[m+1]-T[m] : T[0]+L-T[m]);\n            sumSq += (long long)g*(g-1)/2;\n        }\n        total += (double)d[i][j] * sumSq;\n    }\n    return total / L;\n}\n\nvector<int> greedyTour(double alpha, double unvisitedBonus){\n    vector<vector<int>> last(N, vector<int>(N, 0));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    visited[0][0] = true;\n    int cx=0, cy=0;\n    int t=0;\n    vector<int> result;\n    int unvisitedCount = N*N - 1;\n    int maxLen = 90000;\n    \n    while(t < maxLen){\n        if(unvisitedCount == 0){\n            if(cx==0 && cy==0 && t > 0) break;\n        }\n        \n        double bestScore = -1;\n        int btx=-1, bty=-1;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            if(i==cx && j==cy) continue;\n            int dist = allD[cx][cy][i][j];\n            if(dist<=0 || dist==INT_MAX) continue;\n            int elapsed_v = t - last[i][j];\n            double score;\n            if(!visited[i][j]){\n                score = (double)d[i][j] * (double)elapsed_v * elapsed_v / dist + unvisitedBonus / dist;\n            } else {\n                score = (double)d[i][j] * pow((double)elapsed_v, alpha) / dist;\n            }\n            if(score > bestScore){\n                bestScore = score;\n                btx = i; bty = j;\n            }\n        }\n        if(btx<0) break;\n        \n        auto path = getPath(cx, cy, btx, bty);\n        if(path.empty()) break;\n        if(t + (int)path.size() > maxLen) break;\n        \n        for(int dr : path){\n            result.push_back(dr);\n            cx += dx[dr]; cy += dy[dr];\n            t++;\n            if(!visited[cx][cy]){ visited[cx][cy]=true; unvisitedCount--; }\n            last[cx][cy] = t;\n        }\n        \n        if(unvisitedCount == 0 && cx==0 && cy==0) break;\n    }\n    \n    if(cx != 0 || cy != 0){\n        auto path = getPath(cx, cy, 0, 0);\n        for(int dr : path){\n            result.push_back(dr);\n            cx += dx[dr]; cy += dy[dr];\n        }\n    }\n    \n    return result;\n}\n\nbool isValidTour(const vector<int>& tr){\n    if(tr.empty()) return false;\n    if((int)tr.size() > 100000) return false;\n    vector<vector<bool>> v(N,vector<bool>(N,false));\n    v[0][0]=true;\n    int x=0,y=0;\n    for(int dr : tr){\n        if(!canMove(x,y,dr)) return false;\n        x+=dx[dr]; y+=dy[dr]; v[x][y]=true;\n    }\n    if(x!=0 || y!=0) return false;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) if(!v[i][j]) return false;\n    return true;\n}\n\nvoid phase1_shorten(vector<int>& tour, double& curScore, double timeLimit, const function<double()>& elapsed){\n    bool improved = true;\n    int passes = 0;\n    while(improved && passes < 20 && elapsed() < timeLimit){\n        improved = false;\n        passes++;\n        int L = tour.size();\n        vector<pair<int,int>> pos(L+1);\n        pos[0] = {0,0};\n        for(int t=0;t<L;t++){ pos[t+1] = {pos[t].first+dx[tour[t]], pos[t].second+dy[tour[t]]}; }\n        \n        for(int a=0; a<L && elapsed()<timeLimit; a++){\n            int maxb = min(L, a+300);\n            for(int b=a+2; b<=maxb; b++){\n                int dist = allD[pos[a].first][pos[a].second][pos[b].first][pos[b].second];\n                if(dist >= b-a) continue;\n                auto p = getPath(pos[a].first,pos[a].second,pos[b].first,pos[b].second);\n                vector<int> newTour;\n                newTour.reserve(L-(b-a)+p.size());\n                for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n                for(int x:p) newTour.push_back(x);\n                for(int t=b;t<L;t++) newTour.push_back(tour[t]);\n                double ns = computeScore(newTour);\n                if(ns < curScore){\n                    tour = newTour;\n                    curScore = ns;\n                    improved = true;\n                    goto restart;\n                }\n            }\n        }\n        restart:;\n    }\n}\n\nint main(){\n    cin>>N;\n    hh.resize(N-1); for(auto&s:hh)cin>>s;\n    vv.resize(N); for(auto&s:vv)cin>>s;\n    d.assign(N,vector<int>(N));\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>d[i][j];\n    \n    computeAllDist();\n    timesFlat.assign(N*N, vector<int>());\n    \n    auto startTime = chrono::steady_clock::now();\n    function<double()> elapsed = [&](){\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now-startTime).count();\n    };\n    \n    mt19937 rng(12345);\n    \n    dfsVisited.assign(N,vector<bool>(N,false));\n    dfs(0,0);\n    \n    vector<int> tour = dfsResult;\n    double curScore = computeScore(tour);\n    \n    for(double alpha : {1.5, 2.0, 2.5, 3.0}){\n        for(double ub : {1000000.0, 10000000.0}){\n            if(elapsed() > 0.3) break;\n            auto gt = greedyTour(alpha, ub);\n            if(!isValidTour(gt)) continue;\n            double s = computeScore(gt);\n            if(s < curScore){\n                tour = gt;\n                curScore = s;\n            }\n        }\n    }\n    \n    vector<tuple<int,int,int>> cells;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) cells.push_back({d[i][j],i,j});\n    sort(cells.rbegin(),cells.rend());\n    \n    // Phase 1: systematic segment shortening\n    phase1_shorten(tour, curScore, 0.8, elapsed);\n    \n    // Phase 2: random local search (hill climbing)\n    double phase2EndTime = 1.7;\n    while(elapsed() < phase2EndTime){\n        int mode = rng()%5;\n        int L = tour.size();\n        \n        if(mode==0){\n            int ci = rng() % min((int)cells.size(), 50);\n            auto [dv,ti,tj] = cells[ci];\n            if(L>95000) continue;\n            int pos_i = rng()%(L+1);\n            int cx=0,cy=0;\n            for(int t=0;t<pos_i;t++){ cx+=dx[tour[t]]; cy+=dy[tour[t]]; }\n            if(cx==ti&&cy==tj) continue;\n            auto p1 = getPath(cx,cy,ti,tj);\n            auto p2 = getPath(ti,tj,cx,cy);\n            if((int)(L+p1.size()+p2.size())>100000) continue;\n            vector<int> newTour;\n            newTour.reserve(L+p1.size()+p2.size());\n            for(int t=0;t<pos_i;t++) newTour.push_back(tour[t]);\n            for(int x:p1) newTour.push_back(x);\n            for(int x:p2) newTour.push_back(x);\n            for(int t=pos_i;t<L;t++) newTour.push_back(tour[t]);\n            double ns = computeScore(newTour);\n            if(ns<curScore){ tour=newTour; curScore=ns; }\n        } else if(mode==1){\n            if(L<10) continue;\n            int a=rng()%L;\n            int maxlen = min(500,L-a-1);\n            if(maxlen<2) continue;\n            int b=a+2+rng()%(maxlen-1);\n            if(b>L) continue;\n            int ax=0,ay=0;\n            for(int t=0;t<a;t++){ax+=dx[tour[t]];ay+=dy[tour[t]];}\n            int bx=ax,by=ay;\n            for(int t=a;t<b;t++){bx+=dx[tour[t]];by+=dy[tour[t]];}\n            int dist = allD[ax][ay][bx][by];\n            if(dist>=b-a) continue;\n            auto p = getPath(ax,ay,bx,by);\n            vector<int> newTour;\n            newTour.reserve(L-(b-a)+p.size());\n            for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n            for(int x:p) newTour.push_back(x);\n            for(int t=b;t<L;t++) newTour.push_back(tour[t]);\n            double ns = computeScore(newTour);\n            if(ns<curScore){ tour=newTour; curScore=ns; }\n        } else if(mode==2){\n            if(L<4) continue;\n            int a=rng()%(L-1);\n            if(tour[a]==(tour[a+1]^1)){\n                vector<int> newTour;\n                newTour.reserve(L-2);\n                for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n                for(int t=a+2;t<L;t++) newTour.push_back(tour[t]);\n                double ns = computeScore(newTour);\n                if(ns<curScore){ tour=newTour; curScore=ns; }\n            }\n        } else if(mode==3){\n            if(L>99998) continue;\n            int pos_i = rng()%(L+1);\n            int cx=0,cy=0;\n            for(int t=0;t<pos_i;t++){ cx+=dx[tour[t]]; cy+=dy[tour[t]]; }\n            vector<int> dirs;\n            for(int dr=0;dr<4;dr++) if(canMove(cx,cy,dr)) dirs.push_back(dr);\n            if(dirs.empty()) continue;\n            int dr = dirs[rng()%dirs.size()];\n            vector<int> newTour;\n            newTour.reserve(L+2);\n            for(int t=0;t<pos_i;t++) newTour.push_back(tour[t]);\n            newTour.push_back(dr);\n            newTour.push_back(dr^1);\n            for(int t=pos_i;t<L;t++) newTour.push_back(tour[t]);\n            double ns = computeScore(newTour);\n            if(ns<curScore){ tour=newTour; curScore=ns; }\n        } else {\n            if(L<10 || L>98000) continue;\n            int a=rng()%L;\n            int maxlen = min(400,L-a-1);\n            if(maxlen<2) continue;\n            int b=a+2+rng()%(maxlen-1);\n            if(b>L) continue;\n            int ax=0,ay=0;\n            for(int t=0;t<a;t++){ax+=dx[tour[t]];ay+=dy[tour[t]];}\n            int bx=ax,by=ay;\n            for(int t=a;t<b;t++){bx+=dx[tour[t]];by+=dy[tour[t]];}\n            int ci = rng() % min((int)cells.size(), 30);\n            auto [dv,ti,tj] = cells[ci];\n            auto p1 = getPath(ax,ay,ti,tj);\n            auto p2 = getPath(ti,tj,bx,by);\n            int newseglen = p1.size() + p2.size();\n            if(newseglen == 0) continue;\n            int delta = newseglen - (b-a);\n            if(L + delta > 100000 || L + delta < 4) continue;\n            vector<int> newTour;\n            newTour.reserve(L + delta);\n            for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n            for(int x:p1) newTour.push_back(x);\n            for(int x:p2) newTour.push_back(x);\n            for(int t=b;t<L;t++) newTour.push_back(tour[t]);\n            double ns = computeScore(newTour);\n            if(ns<curScore){ tour=newTour; curScore=ns; }\n        }\n    }\n    \n    // Final phase 1 pass to clean up\n    phase1_shorten(tour, curScore, 1.92, elapsed);\n    \n    for(int dir:tour) cout<<DC[dir];\n    cout<<endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint si, sj;\nvector<string> grid;\nvector<string> words;\nvector<vector<pair<int,int>>> posOf(26);\n\ninline int distm(int r1,int c1,int r2,int c2){ return abs(r1-r2)+abs(c1-c2)+1; }\n\nvector<vector<int>> overlap;\nvector<vector<pair<int,int>>> lastPos;\n\nvector<vector<array<int,5>>> fromCost;\nvector<vector<array<int,5>>> fromEnd;\n\nint MAX_E;\nvector<int> costToEnd;\nint NC_global, M_global;\n\ninline int CTE(int cIdx, int j, int ov, int e){\n    return costToEnd[((cIdx*M_global + j)*5 + ov)*MAX_E + e];\n}\ninline void setCTE(int cIdx, int j, int ov, int e, int v){\n    costToEnd[((cIdx*M_global + j)*5 + ov)*MAX_E + e] = v;\n}\n\nint computeOverlap(const string& a, const string& b){\n    for(int k=4;k>=1;k--){\n        if(a.substr(5-k)==b.substr(0,k)) return k;\n    }\n    return 0;\n}\n\nint main(){\n    auto start_time = chrono::steady_clock::now();\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin>>N>>M>>si>>sj;\n    M_global = M;\n    grid.resize(N);\n    for(int i=0;i<N;i++) cin>>grid[i];\n    words.resize(M);\n    for(int i=0;i<M;i++) cin>>words[i];\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) posOf[grid[i][j]-'A'].push_back({i,j});\n    \n    overlap.assign(M, vector<int>(M,0));\n    for(int i=0;i<M;i++)for(int j=0;j<M;j++){\n        if(i==j) continue;\n        overlap[i][j] = computeOverlap(words[i], words[j]);\n    }\n    \n    lastPos.resize(M);\n    for(int i=0;i<M;i++) lastPos[i] = posOf[words[i][4]-'A'];\n    \n    MAX_E = 1;\n    for(int i=0;i<M;i++) MAX_E = max(MAX_E, (int)lastPos[i].size());\n    \n    int NC = N*N;\n    NC_global = NC;\n    fromCost.assign(NC, vector<array<int,5>>(M));\n    fromEnd.assign(NC, vector<array<int,5>>(M));\n    costToEnd.assign((long long)NC * M * 5 * MAX_E, INT_MAX/2);\n    \n    for(int cIdx=0; cIdx<NC; cIdx++){\n        int pr = cIdx/N, pc = cIdx%N;\n        for(int j=0; j<M; j++){\n            const string& w = words[j];\n            for(int ov=0; ov<5; ov++){\n                int len = 5-ov;\n                static int dp[5][30];\n                int sizes[5];\n                for(int i=0;i<len;i++) sizes[i] = posOf[w[ov+i]-'A'].size();\n                {\n                    auto& pv = posOf[w[ov]-'A'];\n                    for(int k=0;k<sizes[0];k++) dp[0][k] = distm(pr,pc,pv[k].first,pv[k].second);\n                }\n                for(int i=1;i<len;i++){\n                    auto& pp = posOf[w[ov+i-1]-'A'];\n                    auto& pc2 = posOf[w[ov+i]-'A'];\n                    for(int k=0;k<sizes[i];k++){\n                        int r=pc2[k].first, c=pc2[k].second;\n                        int best=INT_MAX;\n                        for(int jj=0;jj<sizes[i-1];jj++){\n                            int nc = dp[i-1][jj] + distm(pp[jj].first,pp[jj].second,r,c);\n                            if(nc<best) best=nc;\n                        }\n                        dp[i][k]=best;\n                    }\n                }\n                int best=INT_MAX, bk=-1;\n                int finalSize = sizes[len-1];\n                for(int k=0;k<finalSize;k++){\n                    setCTE(cIdx,j,ov,k, dp[len-1][k]);\n                    if(dp[len-1][k]<best){best=dp[len-1][k];bk=k;}\n                }\n                fromCost[cIdx][j][ov] = best;\n                fromEnd[cIdx][j][ov] = bk;\n            }\n        }\n    }\n    \n    auto evaluate = [&](const vector<int>& ord)->int{\n        if(ord.empty()) return 0;\n        int cIdx = si*N+sj;\n        int cost = fromCost[cIdx][ord[0]][0];\n        int endIdx = fromEnd[cIdx][ord[0]][0];\n        for(int i=1;i<(int)ord.size();i++){\n            auto& lp = lastPos[ord[i-1]][endIdx];\n            int cIdx2 = lp.first*N + lp.second;\n            int ov = overlap[ord[i-1]][ord[i]];\n            cost += fromCost[cIdx2][ord[i]][ov];\n            endIdx = fromEnd[cIdx2][ord[i]][ov];\n        }\n        return cost;\n    };\n    \n    auto buildString = [&](const vector<int>& ord)->string{\n        if(ord.empty()) return \"\";\n        string s = words[ord[0]];\n        for(int i=1;i<(int)ord.size();i++){\n            int ov = overlap[ord[i-1]][ord[i]];\n            s += words[ord[i]].substr(ov);\n        }\n        return s;\n    };\n    \n    auto verifyAll = [&](const vector<int>& ord)->bool{\n        string s = buildString(ord);\n        for(int j=0;j<M;j++) if(s.find(words[j])==string::npos) return false;\n        return true;\n    };\n    \n    mt19937 rng(42);\n    auto time_ms = [&](){ return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-start_time).count(); };\n    \n    auto buildGreedy = [&](){\n        vector<int> ord;\n        vector<bool> used(M,false);\n        int cIdx = si*N+sj;\n        int bw=-1, bc=INT_MAX, be=-1;\n        for(int j=0;j<M;j++){\n            if(fromCost[cIdx][j][0]<bc){bc=fromCost[cIdx][j][0]; bw=j; be=fromEnd[cIdx][j][0];}\n        }\n        ord.push_back(bw); used[bw]=true;\n        int curWord=bw, curEnd=be;\n        for(int step=1; step<M; step++){\n            auto& lp = lastPos[curWord][curEnd];\n            int ci = lp.first*N+lp.second;\n            int bw2=-1, bc2=INT_MAX, be2=-1;\n            for(int j=0;j<M;j++) if(!used[j]){\n                int ov = overlap[curWord][j];\n                if(fromCost[ci][j][ov]<bc2){\n                    bc2=fromCost[ci][j][ov]; bw2=j; be2=fromEnd[ci][j][ov];\n                }\n            }\n            ord.push_back(bw2); used[bw2]=true;\n            curWord=bw2; curEnd=be2;\n        }\n        return ord;\n    };\n    \n    auto runLS = [&](vector<int>& order, int& curCost, int& bestCost, vector<int>& bestOrder, int endTime){\n        while(time_ms() < endTime){\n            int sz = order.size();\n            if(sz<2) break;\n            int op = rng()%4;\n            if(op==0){\n                int a = rng()%sz, b = rng()%sz;\n                if(a==b) continue;\n                if(a>b) swap(a,b);\n                reverse(order.begin()+a, order.begin()+b+1);\n                int nc = evaluate(order);\n                if(nc < curCost){\n                    curCost = nc;\n                    if(nc<bestCost){bestCost=nc; bestOrder=order;}\n                } else {\n                    reverse(order.begin()+a, order.begin()+b+1);\n                }\n            } else if(op==1){\n                int a = rng()%sz, b = rng()%sz;\n                if(a==b) continue;\n                int v = order[a];\n                if(a<b){ for(int i=a;i<b;i++) order[i]=order[i+1]; order[b]=v; }\n                else { for(int i=a;i>b;i--) order[i]=order[i-1]; order[b]=v; }\n                int nc = evaluate(order);\n                if(nc < curCost){\n                    curCost = nc;\n                    if(nc<bestCost){bestCost=nc; bestOrder=order;}\n                } else {\n                    int v2 = order[b];\n                    if(a<b){ for(int i=b;i>a;i--) order[i]=order[i-1]; order[a]=v2; }\n                    else { for(int i=b;i<a;i++) order[i]=order[i+1]; order[a]=v2; }\n                }\n            } else if(op==2){\n                int a=rng()%sz, b=rng()%sz;\n                if(a==b) continue;\n                swap(order[a],order[b]);\n                int nc = evaluate(order);\n                if(nc < curCost){\n                    curCost = nc;\n                    if(nc<bestCost){bestCost=nc; bestOrder=order;}\n                } else {\n                    swap(order[a],order[b]);\n                }\n            } else {\n                int L = 2+(rng()%2);\n                if(sz-L<1) continue;\n                int a = rng()%(sz-L+1);\n                int b = rng()%(sz-L+1);\n                if(a==b) continue;\n                vector<int> seg(order.begin()+a, order.begin()+a+L);\n                vector<int> rest;\n                rest.reserve(sz-L);\n                for(int i=0;i<sz;i++) if(i<a||i>=a+L) rest.push_back(order[i]);\n                int insPos = b; if(insPos>(int)rest.size()) insPos=rest.size();\n                vector<int> newOrd;\n                newOrd.reserve(sz);\n                for(int i=0;i<insPos;i++) newOrd.push_back(rest[i]);\n                for(int x:seg) newOrd.push_back(x);\n                for(int i=insPos;i<(int)rest.size();i++) newOrd.push_back(rest[i]);\n                int nc = evaluate(newOrd);\n                if(nc < curCost){\n                    order = newOrd;\n                    curCost = nc;\n                    if(nc<bestCost){bestCost=nc; bestOrder=order;}\n                }\n            }\n        }\n    };\n    \n    auto removeRedundant = [&](vector<int>& order, int& curCost){\n        vector<bool> inOrder(M, false);\n        for(int w:order) inOrder[w]=true;\n        \n        bool changed = true;\n        int passes = 0;\n        while(changed && passes < 50){\n            changed = false;\n            passes++;\n            int bestIdx = -1, bestSave = 0;\n            \n            for(int i=0;i<(int)order.size();i++){\n                vector<int> newOrd = order;\n                newOrd.erase(newOrd.begin()+i);\n                string s = buildString(newOrd);\n                bool allIn = true;\n                for(int j=0;j<M;j++){\n                    if(!inOrder[j] || j==order[i]){\n                        if(s.find(words[j])==string::npos){ allIn=false; break; }\n                    }\n                }\n                if(allIn){\n                    int newC = evaluate(newOrd);\n                    int save = curCost - newC;\n                    if(save > bestSave){ bestSave = save; bestIdx = i; }\n                }\n            }\n            if(bestIdx >= 0){\n                inOrder[order[bestIdx]] = false;\n                order.erase(order.begin()+bestIdx);\n                curCost -= bestSave;\n                changed = true;\n            }\n        }\n    };\n    \n    vector<int> order = buildGreedy();\n    int curCost = evaluate(order);\n    int bestCost = curCost;\n    vector<int> bestOrder = order;\n    \n    runLS(order, curCost, bestCost, bestOrder, 1500);\n    order = bestOrder;\n    curCost = bestCost;\n    \n    vector<int> preRemoveOrder = order;\n    int preRemoveCost = curCost;\n    removeRedundant(order, curCost);\n    \n    if(!verifyAll(order)){\n        order = preRemoveOrder;\n        curCost = preRemoveCost;\n    }\n    \n    int osz = order.size();\n    vector<vector<int>> dpF(osz), parF(osz);\n    int startCell = si*N+sj;\n    {\n        int w0 = order[0];\n        int sz0 = lastPos[w0].size();\n        dpF[0].assign(sz0, INT_MAX/2);\n        parF[0].assign(sz0, -1);\n        for(int e=0;e<sz0;e++) dpF[0][e] = CTE(startCell, w0, 0, e);\n    }\n    for(int i=1;i<osz;i++){\n        int wp = order[i-1], wc = order[i];\n        int ov = overlap[wp][wc];\n        int szp = lastPos[wp].size();\n        int szc = lastPos[wc].size();\n        dpF[i].assign(szc, INT_MAX/2);\n        parF[i].assign(szc, -1);\n        for(int ep=0;ep<szp;ep++){\n            if(dpF[i-1][ep]>=INT_MAX/2) continue;\n            auto& lp = lastPos[wp][ep];\n            int ci = lp.first*N + lp.second;\n            for(int ec=0;ec<szc;ec++){\n                int v = dpF[i-1][ep] + CTE(ci, wc, ov, ec);\n                if(v < dpF[i][ec]){ dpF[i][ec] = v; parF[i][ec] = ep; }\n            }\n        }\n    }\n    int bestE = 0, bestV = INT_MAX;\n    for(int e=0;e<(int)dpF[osz-1].size();e++) if(dpF[osz-1][e]<bestV){bestV=dpF[osz-1][e]; bestE=e;}\n    vector<int> endIdxs(osz);\n    endIdxs[osz-1] = bestE;\n    for(int i=osz-1;i>0;i--) endIdxs[i-1] = parF[i][endIdxs[i]];\n    \n    auto reconstructWord = [&](int wj, int ov, int pr, int pc, int targetE)->vector<pair<int,int>>{\n        const string& w = words[wj];\n        int len = 5-ov;\n        vector<pair<int,int>> res;\n        if(len<=0) return res;\n        vector<vector<int>> dp(len), par(len);\n        for(int i=0;i<len;i++){\n            int szl = posOf[w[ov+i]-'A'].size();\n            dp[i].assign(szl,INT_MAX/2);\n            par[i].assign(szl,-1);\n        }\n        auto& p0 = posOf[w[ov]-'A'];\n        for(int k=0;k<(int)p0.size();k++) dp[0][k]=distm(pr,pc,p0[k].first,p0[k].second);\n        for(int i=1;i<len;i++){\n            auto& pp=posOf[w[ov+i-1]-'A'];\n            auto& pc2=posOf[w[ov+i]-'A'];\n            for(int k=0;k<(int)pc2.size();k++){\n                int r=pc2[k].first, c=pc2[k].second;\n                for(int j=0;j<(int)pp.size();j++){\n                    int nc=dp[i-1][j]+distm(pp[j].first,pp[j].second,r,c);\n                    if(nc<dp[i][k]){dp[i][k]=nc;par[i][k]=j;}\n                }\n            }\n        }\n        int bk = targetE;\n        vector<int> idx(len);\n        idx[len-1]=bk;\n        for(int i=len-1;i>0;i--) idx[i-1]=par[i][idx[i]];\n        res.resize(len);\n        for(int i=0;i<len;i++) res[i]=posOf[w[ov+i]-'A'][idx[i]];\n        return res;\n    };\n    \n    vector<pair<int,int>> output;\n    int curR=si, curC=sj;\n    for(int i=0;i<osz;i++){\n        int ov = (i==0)?0:overlap[order[i-1]][order[i]];\n        auto path = reconstructWord(order[i], ov, curR, curC, endIdxs[i]);\n        for(auto& p:path){ output.push_back(p); curR=p.first; curC=p.second; }\n    }\n    \n    for(auto& p:output) cout<<p.first<<\" \"<<p.second<<\"\\n\";\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, NN;\ndouble EPS;\nvector<vector<pair<int,int>>> polys;\nvector<vector<vector<int>>> placement_cells;\nvector<int> nPlace;\n\nstruct Query {\n    vector<int> cells;\n    int result;\n    bool exact;\n};\nvector<Query> queries;\ndouble total_cost = 0;\n\nauto START_TIME = chrono::steady_clock::now();\ndouble elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - START_TIME).count();\n}\n\nint do_drill(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl; cout.flush();\n    int v; cin >> v;\n    total_cost += 1.0;\n    Query q; q.cells = {i*N+j}; q.result = v; q.exact = true;\n    queries.push_back(q);\n    return v;\n}\n\nint do_answer(vector<int>& cells) {\n    cout << \"a \" << cells.size();\n    for (int c : cells) cout << \" \" << c/N << \" \" << c%N;\n    cout << endl; cout.flush();\n    int r; cin >> r;\n    return r;\n}\n\nlong long countTotal() {\n    long long t = 1;\n    for (int k = 0; k < M; k++) {\n        t *= nPlace[k];\n        if (t > (long long)1e10) return (long long)1e10;\n    }\n    return t;\n}\n\nint main() {\n    cin >> N >> M >> EPS;\n    NN = N * N;\n    polys.resize(M);\n    int totalOil = 0;\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        totalOil += d;\n        polys[k].resize(d);\n        for (int i = 0; i < d; i++) cin >> polys[k][i].first >> polys[k][i].second;\n    }\n    \n    placement_cells.resize(M);\n    nPlace.resize(M);\n    for (int k = 0; k < M; k++) {\n        int mi = 0, mj = 0;\n        for (auto& p : polys[k]) { mi = max(mi, p.first); mj = max(mj, p.second); }\n        for (int di = 0; di + mi < N; di++) {\n            for (int dj = 0; dj + mj < N; dj++) {\n                vector<int> cs;\n                for (auto& p : polys[k]) cs.push_back((p.first+di)*N + (p.second+dj));\n                placement_cells[k].push_back(cs);\n            }\n        }\n        nPlace[k] = placement_cells[k].size();\n    }\n    \n    vector<vector<vector<int>>> covers_cell(M, vector<vector<int>>(NN));\n    vector<vector<vector<char>>> place_covers_cell(M);\n    for (int k = 0; k < M; k++) {\n        place_covers_cell[k].assign(nPlace[k], vector<char>(NN, 0));\n        for (int p = 0; p < nPlace[k]; p++) {\n            for (int c : placement_cells[k][p]) {\n                place_covers_cell[k][p][c] = 1;\n                covers_cell[k][c].push_back(p);\n            }\n        }\n    }\n    \n    long long totalConfigs = countTotal();\n    int maxQueries = 2*N*N;\n    double TIME_LIMIT = 2.2;\n    \n    if (totalConfigs <= 80000) {\n        int nConf = (int)totalConfigs;\n        vector<unsigned char> grids((size_t)nConf * NN, 0);\n        vector<vector<int>> allConfs;\n        allConfs.reserve(nConf);\n        \n        vector<int> cur(M, 0);\n        function<void(int)> gen = [&](int k) {\n            if (k == M) {\n                int idx = allConfs.size();\n                allConfs.push_back(cur);\n                size_t base = (size_t)idx * NN;\n                for (int kk = 0; kk < M; kk++) {\n                    for (int c : placement_cells[kk][cur[kk]]) grids[base + c]++;\n                }\n                return;\n            }\n            for (int i = 0; i < nPlace[k]; i++) { cur[k] = i; gen(k+1); }\n        };\n        gen(0);\n        \n        vector<char> alive(nConf, 1);\n        int aliveCount = nConf;\n        \n        while ((int)queries.size() < maxQueries - 1 && elapsed() < TIME_LIMIT) {\n            int best = -1;\n            for (int c = 0; c < nConf; c++) if (alive[c]) { best = c; break; }\n            if (best == -1) break;\n            \n            if (aliveCount == 1) {\n                size_t base = (size_t)best * NN;\n                vector<int> ans;\n                for (int i = 0; i < NN; i++) if (grids[base + i] > 0) ans.push_back(i);\n                int r = do_answer(ans);\n                if (r == 1) return 0;\n                alive[best] = 0; aliveCount--;\n                continue;\n            }\n            \n            vector<int> cntOil(NN, 0);\n            for (int c = 0; c < nConf; c++) {\n                if (!alive[c]) continue;\n                size_t base = (size_t)c * NN;\n                for (int i = 0; i < NN; i++) if (grids[base + i] > 0) cntOil[i]++;\n            }\n            \n            int bestCell = -1;\n            int bestDiff = INT_MAX;\n            for (int i = 0; i < NN; i++) {\n                if (cntOil[i] == 0 || cntOil[i] == aliveCount) continue;\n                int diff = abs(2*cntOil[i] - aliveCount);\n                if (diff < bestDiff) { bestDiff = diff; bestCell = i; }\n            }\n            \n            if (bestCell == -1) {\n                size_t base = (size_t)best * NN;\n                vector<int> ans;\n                for (int i = 0; i < NN; i++) if (grids[base + i] > 0) ans.push_back(i);\n                int r = do_answer(ans);\n                if (r == 1) return 0;\n                alive[best] = 0; aliveCount--;\n                continue;\n            }\n            \n            int v = do_drill(bestCell / N, bestCell % N);\n            for (int c = 0; c < nConf; c++) {\n                if (!alive[c]) continue;\n                if ((int)grids[(size_t)c * NN + bestCell] != v) {\n                    alive[c] = 0; aliveCount--;\n                }\n            }\n        }\n        \n        int best = -1;\n        for (int c = 0; c < nConf; c++) if (alive[c]) { best = c; break; }\n        if (best == -1) best = 0;\n        size_t base = (size_t)best * NN;\n        vector<int> ans;\n        for (int i = 0; i < NN; i++) if (grids[base + i] > 0) ans.push_back(i);\n        do_answer(ans);\n        return 0;\n    }\n    \n    // LARGE CASE\n    vector<vector<char>> placeAlive(M);\n    vector<int> aliveCountK(M);\n    for (int k = 0; k < M; k++) {\n        placeAlive[k].assign(nPlace[k], 1);\n        aliveCountK[k] = nPlace[k];\n    }\n    \n    vector<vector<int>> coverCnt(M, vector<int>(NN, 0));\n    for (int k = 0; k < M; k++) {\n        for (int p = 0; p < nPlace[k]; p++) {\n            for (int c : placement_cells[k][p]) coverCnt[k][c]++;\n        }\n    }\n    \n    vector<int> drillVal(NN, -1);\n    vector<int> drilledCells;\n    \n    auto prunePlacement = [&](int k, int p) {\n        if (!placeAlive[k][p]) return;\n        placeAlive[k][p] = 0;\n        aliveCountK[k]--;\n        for (int c : placement_cells[k][p]) coverCnt[k][c]--;\n    };\n    \n    auto propagate = [&]() {\n        bool changed = true;\n        int iters = 0;\n        while (changed && iters < 20 && elapsed() < TIME_LIMIT) {\n            changed = false;\n            iters++;\n            for (int cell : drilledCells) {\n                int v = drillVal[cell];\n                int mustSum = 0, maySum = 0;\n                for (int k = 0; k < M; k++) {\n                    if (aliveCountK[k] == 0) continue;\n                    if (coverCnt[k][cell] > 0) maySum++;\n                    if (coverCnt[k][cell] == aliveCountK[k]) mustSum++;\n                }\n                if (mustSum > v || maySum < v) continue;\n                if (maySum == v) {\n                    for (int k = 0; k < M; k++) {\n                        if (aliveCountK[k] == 0) continue;\n                        if (coverCnt[k][cell] == 0) continue;\n                        if (coverCnt[k][cell] == aliveCountK[k]) continue;\n                        vector<int> toRemove;\n                        for (int p = 0; p < nPlace[k]; p++) {\n                            if (!placeAlive[k][p]) continue;\n                            if (!place_covers_cell[k][p][cell]) toRemove.push_back(p);\n                        }\n                        for (int p : toRemove) prunePlacement(k, p);\n                        if (!toRemove.empty()) changed = true;\n                    }\n                }\n                if (mustSum == v) {\n                    for (int k = 0; k < M; k++) {\n                        if (aliveCountK[k] == 0) continue;\n                        if (coverCnt[k][cell] == 0) continue;\n                        if (coverCnt[k][cell] == aliveCountK[k]) continue;\n                        vector<int> toRemove;\n                        for (int p : covers_cell[k][cell]) {\n                            if (placeAlive[k][p]) toRemove.push_back(p);\n                        }\n                        for (int p : toRemove) prunePlacement(k, p);\n                        if (!toRemove.empty()) changed = true;\n                    }\n                }\n            }\n        }\n    };\n    \n    vector<int> ansCells;\n    int foundOil = 0;\n    int drilled = 0;\n    int budget = maxQueries - 2;\n    vector<char> drilledMask(NN, 0);\n    \n    auto computeBestCell = [&]() {\n        int bestCell = -1;\n        double bestP = -1;\n        for (int i = 0; i < NN; i++) {\n            if (drilledMask[i]) continue;\n            double pNoOil = 1.0;\n            for (int k = 0; k < M; k++) {\n                if (aliveCountK[k] == 0) continue;\n                double pNotK = 1.0 - (double)coverCnt[k][i] / aliveCountK[k];\n                pNoOil *= pNotK;\n            }\n            double pO = 1.0 - pNoOil;\n            if (pO > bestP) { bestP = pO; bestCell = i; }\n        }\n        return bestCell;\n    };\n    \n    while (drilled < budget && foundOil < totalOil && elapsed() < TIME_LIMIT) {\n        int bestCell = computeBestCell();\n        if (bestCell == -1) break;\n        int v = do_drill(bestCell / N, bestCell % N);\n        drillVal[bestCell] = v;\n        drilledCells.push_back(bestCell);\n        drilledMask[bestCell] = 1;\n        drilled++;\n        if (v > 0) { ansCells.push_back(bestCell); foundOil += v; }\n        propagate();\n    }\n    \n    while (drilled < budget && foundOil < totalOil) {\n        int bestCell = -1;\n        for (int i = 0; i < NN; i++) {\n            if (drilledMask[i]) continue;\n            bool possible = false;\n            for (int k = 0; k < M; k++) if (coverCnt[k][i] > 0) { possible = true; break; }\n            if (possible) { bestCell = i; break; }\n        }\n        if (bestCell == -1) {\n            for (int i = 0; i < NN; i++) if (!drilledMask[i]) { bestCell = i; break; }\n        }\n        if (bestCell == -1) break;\n        int v = do_drill(bestCell / N, bestCell % N);\n        drillVal[bestCell] = v;\n        drilledCells.push_back(bestCell);\n        drilledMask[bestCell] = 1;\n        drilled++;\n        if (v > 0) { ansCells.push_back(bestCell); foundOil += v; }\n    }\n    \n    sort(ansCells.begin(), ansCells.end());\n    ansCells.erase(unique(ansCells.begin(), ansCells.end()), ansCells.end());\n    do_answer(ansCells);\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint W, D, N;\nvector<vector<int>> a;\n\nstruct Rect { int i0,j0,i1,j1; };\n\nvoid alignDividers(vector<int>& h, int W_col, const set<int>& prev_dividers) {\n    int m = h.size();\n    if (m == 0) return;\n    long long sum_h = 0;\n    for (int x : h) sum_h += x;\n    int slack = W_col - sum_h;\n    if (slack < 0) return;\n    \n    vector<int> prev_sorted(prev_dividers.begin(), prev_dividers.end());\n    int y = 0;\n    for (int i = 0; i < m - 1; i++) {\n        int natural = y + h[i];\n        auto it = lower_bound(prev_sorted.begin(), prev_sorted.end(), natural);\n        if (it != prev_sorted.end() && *it < W_col) {\n            int push = *it - natural;\n            if (push >= 0 && push <= slack) {\n                h[i] += push;\n                slack -= push;\n            }\n        }\n        y += h[i];\n    }\n    h[m-1] += slack;\n}\n\nlong long solveWithWidths(vector<int>& widths, vector<vector<Rect>>& final_rects, bool align = true) {\n    int C = widths.size();\n    vector<int> xs(C+1, 0);\n    for (int i = 0; i < C; i++) xs[i+1] = xs[i] + widths[i];\n    \n    vector<vector<set<int>>> dividers(D, vector<set<int>>(C));\n    long long deficit = 0;\n    \n    final_rects.assign(D, vector<Rect>(N));\n    \n    for (int d = 0; d < D; d++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        \n        vector<double> load(C, 0);\n        vector<vector<int>> col(C);\n        for (int k : order) {\n            int best = 0;\n            double bestVal = 1e18;\n            for (int c = 0; c < C; c++) {\n                double v = load[c] + (double)a[d][k] / widths[c];\n                if (v < bestVal) { bestVal = v; best = c; }\n            }\n            col[best].push_back(k);\n            load[best] += (double)a[d][k] / widths[best];\n        }\n        \n        for (int c = 0; c < C; c++) {\n            auto& items = col[c];\n            if (items.empty()) continue;\n            int w = widths[c];\n            int m = items.size();\n            if (m > W) return LLONG_MAX;\n            \n            vector<int> h(m);\n            long long total = 0;\n            for (int i = 0; i < m; i++) {\n                h[i] = max(1, (a[d][items[i]] + w - 1) / w);\n                total += h[i];\n            }\n            if (total > W) {\n                long long totA = 0;\n                for (int k : items) totA += a[d][k];\n                if (totA == 0) totA = 1;\n                vector<int> newH(m, 1);\n                int rem = W - m;\n                vector<double> frac(m);\n                for (int i = 0; i < m; i++) {\n                    frac[i] = (double)a[d][items[i]] / totA * rem;\n                }\n                int s = m;\n                for (int i = 0; i < m; i++) {\n                    int add = (int)frac[i];\n                    newH[i] += add;\n                    s += add;\n                }\n                vector<pair<double,int>> fr(m);\n                for (int i = 0; i < m; i++) fr[i] = {frac[i] - (int)frac[i], i};\n                sort(fr.begin(), fr.end(), greater<>());\n                int idx = 0;\n                while (s < W && idx < m) {\n                    newH[fr[idx].second]++;\n                    s++;\n                    idx++;\n                }\n                while (s < W) { newH[m-1]++; s++; }\n                h = newH;\n            } else {\n                if (align && d > 0) {\n                    alignDividers(h, W, dividers[d-1][c]);\n                } else {\n                    h[m-1] += (W - total);\n                }\n            }\n            int y = 0;\n            for (int i = 0; i < m; i++) {\n                int yEnd = y + h[i];\n                if (i == m-1) yEnd = W;\n                if (yEnd > W) yEnd = W;\n                final_rects[d][items[i]] = {y, xs[c], yEnd, xs[c+1]};\n                if (yEnd < W) dividers[d][c].insert(yEnd);\n                y = yEnd;\n            }\n            for (int idx : items) {\n                auto& r = final_rects[d][idx];\n                long long area = (long long)(r.i1-r.i0)*(r.j1-r.j0);\n                if (area < a[d][idx]) deficit += 100LL * (a[d][idx] - area);\n            }\n        }\n    }\n    \n    long long partCost = 0;\n    for (int d = 1; d < D; d++) {\n        for (int c = 0; c < C; c++) {\n            auto& prev = dividers[d-1][c];\n            auto& cur = dividers[d][c];\n            int w = widths[c];\n            int sd = 0;\n            for (int x : prev) if (!cur.count(x)) sd++;\n            for (int x : cur) if (!prev.count(x)) sd++;\n            partCost += (long long)sd * w;\n        }\n    }\n    \n    return deficit + partCost;\n}\n\nlong long solveFixedSingleCol(vector<vector<Rect>>& final_rects) {\n    vector<int> h(N);\n    for (int r = 0; r < N; r++) {\n        int mx = 1;\n        for (int d = 0; d < D; d++) {\n            int val = a[d][N-1-r];\n            int req = (val + W - 1) / W;\n            mx = max(mx, req);\n        }\n        h[r] = mx;\n    }\n    long long sum = 0;\n    for (int x : h) sum += x;\n    \n    if (sum > W) {\n        double ratio = (double)W / sum;\n        long long s = 0;\n        for (int& x : h) { x = max(1, (int)(x * ratio)); s += x; }\n        while (s > W) {\n            int mi = 0;\n            for (int i = 1; i < N; i++) if (h[i] > h[mi]) mi = i;\n            if (h[mi] > 1) { h[mi]--; s--; } else break;\n        }\n        while (s < W) { h[N-1]++; s++; }\n    } else {\n        h[N-1] += (W - sum);\n    }\n    \n    final_rects.assign(D, vector<Rect>(N));\n    long long deficit = 0;\n    for (int d = 0; d < D; d++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        \n        int y = 0;\n        for (int r = 0; r < N; r++) {\n            int yEnd = y + h[r];\n            if (r == N-1) yEnd = W;\n            int k = order[r];\n            final_rects[d][k] = {y, 0, yEnd, W};\n            long long area = (long long)(yEnd - y) * W;\n            if (area < a[d][k]) deficit += 100LL * (a[d][k] - area);\n            y = yEnd;\n        }\n    }\n    return deficit;\n}\n\nlong long solveFixedCols(vector<int>& widths, vector<vector<Rect>>& final_rects) {\n    int C = widths.size();\n    if (C > N) return LLONG_MAX;\n    vector<int> xs(C+1, 0);\n    for (int i = 0; i < C; i++) xs[i+1] = xs[i] + widths[i];\n    \n    vector<int> colOrder(C);\n    iota(colOrder.begin(), colOrder.end(), 0);\n    sort(colOrder.begin(), colOrder.end(), [&](int x, int y){ return widths[x] > widths[y]; });\n    \n    vector<vector<int>> colRanks(C);\n    for (int r = 0; r < N; r++) {\n        colRanks[colOrder[r % C]].push_back(r);\n    }\n    \n    vector<vector<int>> slotH(C);\n    for (int c = 0; c < C; c++) {\n        int w = widths[c];\n        int ns = colRanks[c].size();\n        slotH[c].assign(ns, 1);\n        for (int s = 0; s < ns; s++) {\n            int rank = colRanks[c][s];\n            int mx = 1;\n            for (int d = 0; d < D; d++) {\n                int val = a[d][N-1-rank];\n                int req = (val + w - 1) / w;\n                mx = max(mx, req);\n            }\n            slotH[c][s] = mx;\n        }\n    }\n    \n    for (int c = 0; c < C; c++) {\n        int ns = slotH[c].size();\n        if (ns == 0) continue;\n        long long sum = 0;\n        for (int x : slotH[c]) sum += x;\n        if (sum > W) {\n            double ratio = (double)W / sum;\n            long long s = 0;\n            for (int& x : slotH[c]) { x = max(1, (int)(x * ratio)); s += x; }\n            while (s > W) {\n                int mi = 0;\n                for (int i = 1; i < ns; i++) if (slotH[c][i] > slotH[c][mi]) mi = i;\n                if (slotH[c][mi] > 1) { slotH[c][mi]--; s--; } else break;\n            }\n            while (s < W) { slotH[c][ns-1]++; s++; }\n        } else {\n            slotH[c][ns-1] += (W - sum);\n        }\n    }\n    \n    final_rects.assign(D, vector<Rect>(N));\n    long long deficit = 0;\n    for (int d = 0; d < D; d++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        \n        for (int c = 0; c < C; c++) {\n            int y = 0;\n            int ns = colRanks[c].size();\n            for (int s = 0; s < ns; s++) {\n                int yEnd = y + slotH[c][s];\n                if (s == ns-1) yEnd = W;\n                int rank = colRanks[c][s];\n                int k = order[rank];\n                final_rects[d][k] = {y, xs[c], yEnd, xs[c+1]};\n                long long area = (long long)(yEnd - y) * widths[c];\n                if (area < a[d][k]) deficit += 100LL * (a[d][k] - area);\n                y = yEnd;\n            }\n        }\n    }\n    return deficit;\n}\n\nint main() {\n    cin >> W >> D >> N;\n    a.assign(D, vector<int>(N));\n    for (int d = 0; d < D; d++) for (int k = 0; k < N; k++) cin >> a[d][k];\n    \n    long long bestCost = LLONG_MAX;\n    vector<vector<Rect>> bestRects;\n    \n    auto tryResult = [&](long long cost, vector<vector<Rect>>& rects) {\n        if (cost < bestCost) {\n            bestCost = cost;\n            bestRects = rects;\n        }\n    };\n    \n    int maxC = min(N, 25);\n    \n    for (int C = 1; C <= maxC; C++) {\n        vector<int> widths(C);\n        int base = W / C, extra = W % C;\n        for (int i = 0; i < C; i++) widths[i] = base + (i < extra ? 1 : 0);\n        vector<vector<Rect>> rects;\n        long long cost = solveWithWidths(widths, rects, true);\n        tryResult(cost, rects);\n        long long cost2 = solveWithWidths(widths, rects, false);\n        tryResult(cost2, rects);\n    }\n    \n    {\n        vector<vector<Rect>> rects;\n        long long cost = solveFixedSingleCol(rects);\n        tryResult(cost, rects);\n    }\n    \n    for (int C = 2; C <= maxC; C++) {\n        vector<int> widths(C);\n        int base = W / C, extra = W % C;\n        for (int i = 0; i < C; i++) widths[i] = base + (i < extra ? 1 : 0);\n        vector<vector<Rect>> rects;\n        long long cost = solveFixedCols(widths, rects);\n        tryResult(cost, rects);\n    }\n    \n    mt19937 rng(42);\n    auto clock_start = chrono::steady_clock::now();\n    auto get_time = [&](){\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - clock_start).count();\n    };\n    \n    int trials = 0;\n    while (get_time() < 2500) {\n        trials++;\n        int C = 2 + rng() % (maxC - 1);\n        if (C > N) continue;\n        set<int> bs;\n        int guard = 0;\n        while ((int)bs.size() < C-1 && guard < 1000) {\n            int x = 10 + rng() % (W - 20);\n            bs.insert(x);\n            guard++;\n        }\n        if ((int)bs.size() < C-1) continue;\n        vector<int> breaks(bs.begin(), bs.end());\n        vector<int> widths(C);\n        int prev = 0;\n        for (int i = 0; i < C-1; i++) {\n            widths[i] = breaks[i] - prev;\n            prev = breaks[i];\n        }\n        widths[C-1] = W - prev;\n        bool ok = true;\n        for (int w : widths) if (w < 5) { ok = false; break; }\n        if (!ok) continue;\n        \n        vector<vector<Rect>> rects;\n        long long cost = solveFixedCols(widths, rects);\n        tryResult(cost, rects);\n        \n        if (trials % 2 == 0) {\n            long long cost2 = solveWithWidths(widths, rects, true);\n            tryResult(cost2, rects);\n        }\n    }\n    \n    if (bestRects.empty()) {\n        bestRects.assign(D, vector<Rect>(N));\n        for (int d = 0; d < D; d++) for (int k = 0; k < N; k++)\n            bestRects[d][k] = {k, 0, k+1, W};\n    }\n    \n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            auto& r = bestRects[d][k];\n            if (r.i0 >= r.i1 || r.j0 >= r.j1) r = {0, 0, 1, 1};\n            cout << r.i0 << \" \" << r.j0 << \" \" << r.i1 << \" \" << r.j1 << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\nconst int MAX_K = 6;\n\nint N, M, K;\nlong long a0[9][9];\nlong long ss[20][3][3];\nlong long ss_flat[20][9];\n\nvector<long long> combo_mats[MAX_K+1];\nvector<array<int8_t, MAX_K>> combo_stamps[MAX_K+1];\nint combo_count[MAX_K+1];\n\nstatic inline long long addmod(long long a, long long b){\n    long long v = a + b;\n    if(v >= MOD) v -= MOD;\n    return v;\n}\n\nstatic inline long long submod(long long a, long long b){\n    long long v = a - b;\n    if(v < 0) v += MOD;\n    return v;\n}\n\nvoid gen_combos(){\n    for(int m = 0; m < M; m++){\n        for(int i = 0; i < 3; i++){\n            for(int j = 0; j < 3; j++){\n                ss_flat[m][i*3+j] = ss[m][i][j];\n            }\n        }\n    }\n    \n    long long sizes[] = {1, 20, 210, 1540, 8855, 42504, 177100};\n    for(int k = 0; k <= MAX_K; k++){\n        combo_mats[k].reserve(sizes[k] * 9);\n        combo_stamps[k].reserve(sizes[k]);\n    }\n    \n    for(int i = 0; i < 9; i++) combo_mats[0].push_back(0);\n    array<int8_t, MAX_K> zs;\n    for(int i = 0; i < MAX_K; i++) zs[i] = 0;\n    combo_stamps[0].push_back(zs);\n    combo_count[0] = 1;\n    \n    for(int k = 1; k <= MAX_K; k++){\n        int prev_count = combo_count[k-1];\n        combo_count[k] = 0;\n        for(int idx = 0; idx < prev_count; idx++){\n            const long long* pmat = &combo_mats[k-1][idx * 9];\n            auto pstamps = combo_stamps[k-1][idx];\n            int start = (k == 1) ? 0 : (int)pstamps[k-2];\n            for(int m = start; m < M; m++){\n                for(int i = 0; i < 9; i++){\n                    long long v = pmat[i] + ss_flat[m][i];\n                    if(v >= MOD) v -= MOD;\n                    combo_mats[k].push_back(v);\n                }\n                array<int8_t, MAX_K> ns = pstamps;\n                ns[k-1] = (int8_t)m;\n                combo_stamps[k].push_back(ns);\n                combo_count[k]++;\n            }\n        }\n    }\n}\n\npair<long long, vector<tuple<int,int,int> > > greedy_solve(long long lambda){\n    long long a[9][9];\n    memcpy(a, a0, sizeof(a0));\n    vector<tuple<int,int,int> > ops;\n    int budget = K;\n    \n    for(int p = 0; p <= N-3; p++){\n        for(int q = 0; q <= N-3; q++){\n            int locked_indices[9];\n            int locked_di[9], locked_dj[9];\n            int nlocked = 0;\n            for(int di = 0; di < 3; di++){\n                for(int dj = 0; dj < 3; dj++){\n                    int i = p+di, j = q+dj;\n                    int mi = (i < 6) ? i : 6;\n                    int mj = (j < 6) ? j : 6;\n                    if(mi == p && mj == q){\n                        locked_indices[nlocked] = di*3+dj;\n                        locked_di[nlocked] = di;\n                        locked_dj[nlocked] = dj;\n                        nlocked++;\n                    }\n                }\n            }\n            \n            int max_k;\n            if(nlocked == 1) max_k = 3;\n            else if(nlocked == 3) max_k = 5;\n            else max_k = 6;\n            if(max_k > budget) max_k = budget;\n            if(max_k < 0) max_k = 0;\n            \n            long long curv[9];\n            for(int ii = 0; ii < nlocked; ii++){\n                curv[ii] = a[p+locked_di[ii]][q+locked_dj[ii]];\n            }\n            \n            int best_k = 0;\n            int best_idx = 0;\n            long long best_sc = LLONG_MIN;\n            \n            for(int k = 0; k <= max_k; k++){\n                long long kl = (long long)k * lambda;\n                int cnt = combo_count[k];\n                const long long* mats_ptr = combo_mats[k].data();\n                for(int idx = 0; idx < cnt; idx++){\n                    const long long* mat = mats_ptr + idx * 9;\n                    long long sum = 0;\n                    for(int ii = 0; ii < nlocked; ii++){\n                        long long v = curv[ii] + mat[locked_indices[ii]];\n                        if(v >= MOD) v -= MOD;\n                        sum += v;\n                    }\n                    long long sc = sum - kl;\n                    if(sc > best_sc){\n                        best_sc = sc;\n                        best_k = k;\n                        best_idx = idx;\n                    }\n                }\n            }\n            \n            const auto& best_stamps = combo_stamps[best_k][best_idx];\n            for(int ii = 0; ii < best_k; ii++){\n                int m = (int)best_stamps[ii];\n                ops.push_back(make_tuple(m, p, q));\n                for(int i = 0; i < 3; i++){\n                    for(int j = 0; j < 3; j++){\n                        a[p+i][q+j] = addmod(a[p+i][q+j], ss[m][i][j]);\n                    }\n                }\n                budget--;\n            }\n        }\n    }\n    \n    long long score = 0;\n    for(int i = 0; i < N; i++){\n        for(int j = 0; j < N; j++){\n            score += a[i][j];\n        }\n    }\n    return make_pair(score, ops);\n}\n\nlong long local_search(vector<tuple<int,int,int> >& ops, double time_limit_sec, chrono::steady_clock::time_point start_time){\n    long long stamp_sum[9][9];\n    for(int i = 0; i < 9; i++){\n        for(int j = 0; j < 9; j++){\n            stamp_sum[i][j] = 0;\n        }\n    }\n    for(size_t t = 0; t < ops.size(); t++){\n        int m = get<0>(ops[t]);\n        int p = get<1>(ops[t]);\n        int q = get<2>(ops[t]);\n        for(int i = 0; i < 3; i++){\n            for(int j = 0; j < 3; j++){\n                stamp_sum[p+i][q+j] = addmod(stamp_sum[p+i][q+j], ss[m][i][j]);\n            }\n        }\n    }\n    long long score = 0;\n    for(int i = 0; i < 9; i++){\n        for(int j = 0; j < 9; j++){\n            score += addmod(a0[i][j], stamp_sum[i][j]);\n        }\n    }\n    \n    auto elapsed_sec = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    };\n    \n    bool improved = true;\n    while(improved){\n        if(elapsed_sec() >= time_limit_sec) break;\n        improved = false;\n        \n        // Swap\n        for(int k = 0; k < (int)ops.size(); k++){\n            int mcur = get<0>(ops[k]);\n            int p = get<1>(ops[k]);\n            int q = get<2>(ops[k]);\n            int best_m = mcur;\n            long long best_delta = 0;\n            for(int m2 = 0; m2 < M; m2++){\n                if(m2 == mcur) continue;\n                long long delta = 0;\n                for(int i = 0; i < 3; i++){\n                    for(int j = 0; j < 3; j++){\n                        long long old_eff = stamp_sum[p+i][q+j];\n                        long long new_eff = addmod(submod(old_eff, ss[mcur][i][j]), ss[m2][i][j]);\n                        long long old_val = addmod(a0[p+i][q+j], old_eff);\n                        long long new_val = addmod(a0[p+i][q+j], new_eff);\n                        delta += new_val - old_val;\n                    }\n                }\n                if(delta > best_delta){\n                    best_delta = delta;\n                    best_m = m2;\n                }\n            }\n            if(best_m != mcur){\n                for(int i = 0; i < 3; i++){\n                    for(int j = 0; j < 3; j++){\n                        stamp_sum[p+i][q+j] = addmod(submod(stamp_sum[p+i][q+j], ss[mcur][i][j]), ss[best_m][i][j]);\n                    }\n                }\n                get<0>(ops[k]) = best_m;\n                score += best_delta;\n                improved = true;\n            }\n        }\n        \n        if(elapsed_sec() >= time_limit_sec) break;\n        \n        // Remove\n        for(int k = 0; k < (int)ops.size(); k++){\n            int mcur = get<0>(ops[k]);\n            int p = get<1>(ops[k]);\n            int q = get<2>(ops[k]);\n            long long delta = 0;\n            for(int i = 0; i < 3; i++){\n                for(int j = 0; j < 3; j++){\n                    long long old_eff = stamp_sum[p+i][q+j];\n                    long long new_eff = submod(old_eff, ss[mcur][i][j]);\n                    long long old_val = addmod(a0[p+i][q+j], old_eff);\n                    long long new_val = addmod(a0[p+i][q+j], new_eff);\n                    delta += new_val - old_val;\n                }\n            }\n            if(delta > 0){\n                for(int i = 0; i < 3; i++){\n                    for(int j = 0; j < 3; j++){\n                        stamp_sum[p+i][q+j] = submod(stamp_sum[p+i][q+j], ss[mcur][i][j]);\n                    }\n                }\n                ops.erase(ops.begin() + k);\n                k--;\n                score += delta;\n                improved = true;\n            }\n        }\n        \n        if(elapsed_sec() >= time_limit_sec) break;\n        \n        // Add\n        while((int)ops.size() < K){\n            int best_m = -1, best_p = 0, best_q = 0;\n            long long best_delta = 0;\n            for(int p = 0; p <= 6; p++){\n                for(int q = 0; q <= 6; q++){\n                    for(int m = 0; m < M; m++){\n                        long long delta = 0;\n                        for(int i = 0; i < 3; i++){\n                            for(int j = 0; j < 3; j++){\n                                long long old_eff = stamp_sum[p+i][q+j];\n                                long long new_eff = addmod(old_eff, ss[m][i][j]);\n                                long long old_val = addmod(a0[p+i][q+j], old_eff);\n                                long long new_val = addmod(a0[p+i][q+j], new_eff);\n                                delta += new_val - old_val;\n                            }\n                        }\n                        if(delta > best_delta){\n                            best_delta = delta;\n                            best_m = m;\n                            best_p = p;\n                            best_q = q;\n                        }\n                    }\n                }\n            }\n            if(best_m < 0) break;\n            for(int i = 0; i < 3; i++){\n                for(int j = 0; j < 3; j++){\n                    stamp_sum[best_p+i][best_q+j] = addmod(stamp_sum[best_p+i][best_q+j], ss[best_m][i][j]);\n                }\n            }\n            ops.push_back(make_tuple(best_m, best_p, best_q));\n            score += best_delta;\n            improved = true;\n        }\n        \n        if(elapsed_sec() >= time_limit_sec) break;\n        \n        // Relocate\n        for(int k = 0; k < (int)ops.size(); k++){\n            if(elapsed_sec() >= time_limit_sec) break;\n            \n            int mcur = get<0>(ops[k]);\n            int pcur = get<1>(ops[k]);\n            int qcur = get<2>(ops[k]);\n            long long rem_delta = 0;\n            long long backup[3][3];\n            for(int i = 0; i < 3; i++){\n                for(int j = 0; j < 3; j++){\n                    backup[i][j] = stamp_sum[pcur+i][qcur+j];\n                    long long new_eff = submod(backup[i][j], ss[mcur][i][j]);\n                    long long old_val = addmod(a0[pcur+i][qcur+j], backup[i][j]);\n                    long long new_val = addmod(a0[pcur+i][qcur+j], new_eff);\n                    rem_delta += new_val - old_val;\n                    stamp_sum[pcur+i][qcur+j] = new_eff;\n                }\n            }\n            \n            int best_m2 = mcur, best_p = pcur, best_q = qcur;\n            long long best_delta = 0;\n            for(int p2 = 0; p2 <= 6; p2++){\n                for(int q2 = 0; q2 <= 6; q2++){\n                    for(int m2 = 0; m2 < M; m2++){\n                        long long add_delta = 0;\n                        for(int i = 0; i < 3; i++){\n                            for(int j = 0; j < 3; j++){\n                                long long old_eff = stamp_sum[p2+i][q2+j];\n                                long long new_eff = addmod(old_eff, ss[m2][i][j]);\n                                long long old_val = addmod(a0[p2+i][q2+j], old_eff);\n                                long long new_val = addmod(a0[p2+i][q2+j], new_eff);\n                                add_delta += new_val - old_val;\n                            }\n                        }\n                        long long total_delta = rem_delta + add_delta;\n                        if(total_delta > best_delta){\n                            best_delta = total_delta;\n                            best_p = p2;\n                            best_q = q2;\n                            best_m2 = m2;\n                        }\n                    }\n                }\n            }\n            \n            if(best_delta > 0){\n                for(int i = 0; i < 3; i++){\n                    for(int j = 0; j < 3; j++){\n                        stamp_sum[best_p+i][best_q+j] = addmod(stamp_sum[best_p+i][best_q+j], ss[best_m2][i][j]);\n                    }\n                }\n                get<0>(ops[k]) = best_m2;\n                get<1>(ops[k]) = best_p;\n                get<2>(ops[k]) = best_q;\n                score += best_delta;\n                improved = true;\n            } else {\n                for(int i = 0; i < 3; i++){\n                    for(int j = 0; j < 3; j++){\n                        stamp_sum[pcur+i][qcur+j] = backup[i][j];\n                    }\n                }\n            }\n        }\n    }\n    \n    return score;\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    cin >> N >> M >> K;\n    for(int i = 0; i < N; i++){\n        for(int j = 0; j < N; j++){\n            cin >> a0[i][j];\n        }\n    }\n    for(int m = 0; m < M; m++){\n        for(int i = 0; i < 3; i++){\n            for(int j = 0; j < 3; j++){\n                cin >> ss[m][i][j];\n            }\n        }\n    }\n    \n    gen_combos();\n    \n    chrono::steady_clock::time_point start_time = chrono::steady_clock::now();\n    auto elapsed = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    };\n    \n    long long best_score = -1;\n    vector<tuple<int,int,int> > best_ops;\n    \n    // Phase 1: many lambdas\n    int num_lambdas = 100;\n    for(int step = 0; step <= num_lambdas; step++){\n        if(elapsed() > 0.9) break;\n        long long lambda = (long long)((double)MOD * 0.4 * step / num_lambdas);\n        auto res = greedy_solve(lambda);\n        long long sc = res.first;\n        auto& ops = res.second;\n        if((int)ops.size() > K) continue;\n        if(sc > best_score){\n            best_score = sc;\n            best_ops = ops;\n        }\n    }\n    \n    // Phase 2: LS on best\n    double ls_limit = elapsed() + 0.4;\n    if(ls_limit > 1.4) ls_limit = 1.4;\n    long long new_sc = local_search(best_ops, ls_limit, start_time);\n    if(new_sc > best_score) best_score = new_sc;\n    \n    // Phase 3: ILS with kicks from best\n    mt19937 rng(12345);\n    \n    while(elapsed() < 1.85){\n        vector<tuple<int,int,int> > cand = best_ops;  // always start from best\n        if(cand.empty()) break;\n        \n        // Random kick\n        int num_kicks = 2 + (rng() % 3);  // 2-4 kicks\n        for(int kk = 0; kk < num_kicks; kk++){\n            int idx = rng() % cand.size();\n            int choice = rng() % 3;\n            if(choice == 0){\n                get<0>(cand[idx]) = rng() % M;\n            } else if(choice == 1){\n                get<1>(cand[idx]) = rng() % 7;\n                get<2>(cand[idx]) = rng() % 7;\n            } else {\n                get<0>(cand[idx]) = rng() % M;\n                get<1>(cand[idx]) = rng() % 7;\n                get<2>(cand[idx]) = rng() % 7;\n            }\n        }\n        \n        double lt = elapsed() + 0.08;\n        if(lt > 1.85) lt = 1.85;\n        long long sc = local_search(cand, lt, start_time);\n        \n        if(sc > best_score){\n            best_score = sc;\n            best_ops = cand;\n        }\n    }\n    \n    cout << best_ops.size() << \"\\n\";\n    for(size_t t = 0; t < best_ops.size(); t++){\n        cout << get<0>(best_ops[t]) << \" \" << get<1>(best_ops[t]) << \" \" << get<2>(best_ops[t]) << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint A[5][5];\n\nstruct Run {\n    int grid[5][5];\n    int cr[5], cc[5];\n    bool hold[5];\n    int held[5];\n    int nin[5];\n    int nout[5];\n    vector<string> out;\n    int totalDisp;\n    int turns;\n    int stashCols[3];\n    int wantTieBreak;\n    \n    void init() {\n        for(int i=0;i<5;i++)for(int j=0;j<5;j++)grid[i][j]=-1;\n        for(int i=0;i<5;i++){cr[i]=i;cc[i]=0;hold[i]=false;held[i]=-1;nin[i]=0;nout[i]=0;}\n        out.assign(5,\"\");\n        totalDisp=0;\n        turns=0;\n    }\n    \n    void doStep(const string& a) {\n        for(int i=0;i<5;i++){\n            if(nin[i]>=5)continue;\n            if(grid[i][0]!=-1)continue;\n            bool h=false;\n            for(int k=0;k<5;k++) if(cr[k]==i&&cc[k]==0&&hold[k]){h=true;break;}\n            if(h)continue;\n            grid[i][0]=A[i][nin[i]++];\n        }\n        int nr[5], nc[5];\n        for(int i=0;i<5;i++){nr[i]=cr[i];nc[i]=cc[i];}\n        for(int i=0;i<5;i++){\n            if(cr[i]==-1)continue;\n            char ch=a[i];\n            if(ch=='U')nr[i]--;\n            else if(ch=='D')nr[i]++;\n            else if(ch=='L')nc[i]--;\n            else if(ch=='R')nc[i]++;\n        }\n        for(int i=0;i<5;i++){cr[i]=nr[i];cc[i]=nc[i];}\n        for(int i=0;i<5;i++){\n            if(cr[i]==-1)continue;\n            char ch=a[i];\n            if(ch=='P'){\n                held[i]=grid[cr[i]][cc[i]];\n                grid[cr[i]][cc[i]]=-1;\n                hold[i]=true;\n            } else if(ch=='Q'){\n                grid[cr[i]][cc[i]]=held[i];\n                held[i]=-1;\n                hold[i]=false;\n            } else if(ch=='B'){\n                cr[i]=-1;cc[i]=-1;\n            }\n        }\n        for(int i=0;i<5;i++) out[i]+=a[i];\n        turns++;\n        for(int i=0;i<5;i++){\n            if(grid[i][4]!=-1){\n                int v=grid[i][4];\n                grid[i][4]=-1;\n                totalDisp++;\n                if(v/5==i) nout[i]++;\n            }\n        }\n    }\n    \n    void moveLarge(int tr, int tc) {\n        int guard=0;\n        while((cr[0]!=tr || cc[0]!=tc) && turns<9900 && guard<200) {\n            string a=\".....\"; \n            char ch='.';\n            if(cr[0]<tr) ch='D';\n            else if(cr[0]>tr) ch='U';\n            else if(cc[0]<tc) ch='R';\n            else if(cc[0]>tc) ch='L';\n            a[0]=ch;\n            doStep(a);\n            guard++;\n        }\n    }\n    \n    void P0(){ string a=\".....\"; a[0]='P'; doStep(a); }\n    void Q0(){ string a=\".....\"; a[0]='Q'; doStep(a); }\n    \n    bool isSafeZone(int r, int c) { return r == 0 || c >= 3; }\n    \n    int safeDist(int sr, int sc, int tr, int tc) {\n        if(!isSafeZone(sr, sc) || !isSafeZone(tr, tc)) return INT_MAX;\n        int dist[5][5];\n        for(int r=0;r<5;r++) for(int c=0;c<5;c++) dist[r][c] = INT_MAX;\n        queue<pair<int,int>> q;\n        q.push({sr, sc});\n        dist[sr][sc] = 0;\n        int drs[] = {-1, 1, 0, 0};\n        int dcs[] = {0, 0, -1, 1};\n        while(!q.empty()){\n            auto [r, c] = q.front(); q.pop();\n            for(int k=0;k<4;k++){\n                int nr = r + drs[k], nc = c + dcs[k];\n                if(nr<0||nr>=5||nc<0||nc>=5) continue;\n                if(!isSafeZone(nr, nc)) continue;\n                if(dist[nr][nc] != INT_MAX) continue;\n                dist[nr][nc] = dist[r][c] + 1;\n                q.push({nr, nc});\n            }\n        }\n        return dist[tr][tc];\n    }\n    \n    char moveCharSafe(int tr, int tc) {\n        int drs[] = {-1, 1, 0, 0};\n        int dcs[] = {0, 0, -1, 1};\n        char cmds[] = {'U', 'D', 'L', 'R'};\n        int bestD = INT_MAX;\n        char bestCmd = '.';\n        for(int k=0;k<4;k++){\n            int nr = cr[0] + drs[k], nc = cc[0] + dcs[k];\n            if(nr<0||nr>=5||nc<0||nc>=5) continue;\n            if(!isSafeZone(nr, nc)) continue;\n            int d = safeDist(nr, nc, tr, tc);\n            if(d < bestD){\n                bestD = d;\n                bestCmd = cmds[k];\n            }\n        }\n        return bestCmd;\n    }\n    \n    char planCrane0Restricted() {\n        if(hold[0]){\n            int v = held[0];\n            int g = v / 5;\n            if(cr[0] == g && cc[0] == 4) return 'Q';\n            return moveCharSafe(g, 4);\n        }\n        int bestCost = INT_MAX;\n        int btr = -1, btc = -1;\n        for(int g=0; g<5; g++){\n            if(nout[g] >= 5) continue;\n            int w = g*5 + nout[g];\n            for(int r=0; r<5; r++) for(int c=0; c<5; c++){\n                if(grid[r][c] != w) continue;\n                if(!isSafeZone(r, c)) continue;\n                int d1 = safeDist(cr[0], cc[0], r, c);\n                if(d1 == INT_MAX) continue;\n                int d2 = safeDist(r, c, g, 4);\n                if(d2 == INT_MAX) continue;\n                int cost = d1 + d2;\n                if(cost < bestCost){\n                    bestCost = cost;\n                    btr = r; btc = c;\n                }\n            }\n        }\n        if(btr == -1) return '.';\n        if(cr[0] == btr && cc[0] == btc) return 'P';\n        return moveCharSafe(btr, btc);\n    }\n    \n    void phase1_2pass() {\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"QQQQQ\");\n        doStep(\"LLLLL\"); doStep(\"LLLLL\"); doStep(\"PPPPP\"); doStep(\"RRRRR\");\n        doStep(\"QQQQQ\"); doStep(\".BBBB\");\n    }\n    \n    void phase1_3pass() {\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"QQQQQ\");\n        doStep(\"LLLLL\"); doStep(\"LLLLL\"); doStep(\"LLLLL\");\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"QQQQQ\");\n        doStep(\"LLLLL\"); doStep(\"LLLLL\");\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"QQQQQ\"); doStep(\"LLLLL\");\n        doStep(\".BBBB\");\n    }\n    \n    void phase1_hybrid1() {\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"QRRRR\");\n        doStep(\"LQQQQ\"); doStep(\"LLLLL\"); doStep(\"PLLLL\"); doStep(\"RLLLL\");\n        doStep(\"QPPPP\"); doStep(\".RRRR\"); doStep(\".RRRR\"); doStep(\".QQQQ\");\n        doStep(\".LLLL\"); doStep(\".LLLL\"); doStep(\".PPPP\"); doStep(\".RRRR\");\n        doStep(\".QQQQ\"); doStep(\".LLLL\"); doStep(\".BBBB\");\n    }\n    \n    void phase1_hybrid1_active() {\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"QRRRR\");\n        doStep(\"LQQQQ\"); doStep(\"LLLLL\"); doStep(\"PLLLL\"); doStep(\"RLLLL\");\n        doStep(\"QPPPP\");\n        string smallActs[] = {\"RRRR\", \"RRRR\", \"QQQQ\", \"LLLL\", \"LLLL\", \"PPPP\", \"RRRR\", \"QQQQ\", \"LLLL\", \"BBBB\"};\n        for(int t = 0; t < 10; t++){\n            char act0 = planCrane0Restricted();\n            string a;\n            a += act0;\n            a += smallActs[t];\n            doStep(a);\n        }\n    }\n    \n    void phase1_hybrid2() {\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"QRRRQ\");\n        doStep(\"LQQQL\"); doStep(\"LLLLL\"); doStep(\"PLLLP\"); doStep(\"RLLLR\");\n        doStep(\"QPPPQ\"); doStep(\".RRRB\"); doStep(\".RRR.\"); doStep(\".QQQ.\");\n        doStep(\".LLL.\"); doStep(\".LLL.\"); doStep(\".PPP.\"); doStep(\".RRR.\");\n        doStep(\".QQQ.\"); doStep(\".LLL.\"); doStep(\".BBB.\");\n    }\n    \n    void phase2() {\n        int stuck=0;\n        while(totalDisp < 25 && turns < 9900) {\n            if(hold[0]){\n                int v = held[0];\n                int g = v / 5;\n                if(nout[g] < 5 && v == g*5+nout[g]){\n                    moveLarge(g, 4);\n                    Q0();\n                } else {\n                    int dr=-1, dc=-1;\n                    int tgt_row = v/5;\n                    for(int ci=0;ci<3;ci++){\n                        int c=stashCols[ci];\n                        if(grid[tgt_row][c]==-1){dr=tgt_row;dc=c;break;}\n                    }\n                    if(dr==-1) {\n                        for(int ci=0;ci<3 && dr==-1;ci++){\n                            int c=stashCols[ci];\n                            for(int r=0;r<5;r++) if(grid[r][c]==-1){dr=r;dc=c;break;}\n                        }\n                    }\n                    if(dr==-1) break;\n                    moveLarge(dr, dc);\n                    Q0();\n                }\n                continue;\n            }\n            \n            int best_cost = INT_MAX;\n            int tr=-1, tc=-1, tgate=-1;\n            for(int g=0;g<5;g++){\n                if(nout[g]>=5) continue;\n                int want = g*5 + nout[g];\n                for(int r=0;r<5;r++) for(int c=0;c<5;c++) {\n                    if(grid[r][c]==want){\n                        int cost;\n                        if(wantTieBreak == 0){\n                            cost = abs(cr[0]-r) + abs(cc[0]-c) + abs(r-g) + abs(4-c);\n                        } else {\n                            cost = g*100 + abs(cr[0]-r) + abs(cc[0]-c) + abs(r-g) + abs(4-c);\n                        }\n                        if(cost < best_cost) {\n                            best_cost = cost;\n                            tr=r; tc=c; tgate=g;\n                        }\n                    }\n                }\n            }\n            if(tr!=-1) {\n                moveLarge(tr,tc);\n                P0();\n                moveLarge(tgate,4);\n                Q0();\n                stuck=0;\n            } else {\n                int sr = -1;\n                int best_prio = INT_MAX;\n                for(int i=0;i<5;i++){\n                    if(grid[i][0]==-1) continue;\n                    int prio;\n                    if(nin[i]>=5) prio = 10000;\n                    else {\n                        int next = A[i][nin[i]];\n                        bool isWant = false;\n                        for(int g=0;g<5;g++){\n                            if(nout[g]<5 && g*5+nout[g]==next){isWant=true; break;}\n                        }\n                        prio = isWant ? (-1000+next) : next;\n                    }\n                    if(prio < best_prio){\n                        best_prio = prio;\n                        sr = i;\n                    }\n                }\n                if(sr==-1){\n                    doStep(\".....\");\n                    stuck++;\n                    if(stuck>200) break;\n                    continue;\n                }\n                int v = grid[sr][0];\n                int tgt_row = v/5;\n                int dr=-1, dc=-1;\n                for(int ci=0;ci<3;ci++){\n                    int c=stashCols[ci];\n                    if(grid[tgt_row][c]==-1){dr=tgt_row;dc=c;break;}\n                }\n                if(dr==-1) {\n                    for(int ci=0;ci<3 && dr==-1;ci++){\n                        int c=stashCols[ci];\n                        for(int r=0;r<5;r++) if(grid[r][c]==-1){dr=r;dc=c;break;}\n                    }\n                }\n                if(dr==-1){\n                    doStep(\".....\");\n                    stuck++;\n                    if(stuck>200) break;\n                    continue;\n                }\n                moveLarge(sr,0);\n                P0();\n                moveLarge(dr,dc);\n                Q0();\n                stuck=0;\n            }\n        }\n    }\n    \n    void phase2_tsp() {\n        int stuck=0;\n        while(totalDisp < 25 && turns < 9900) {\n            if(hold[0]){\n                int v = held[0];\n                int g = v / 5;\n                if(nout[g] < 5 && v == g*5+nout[g]){\n                    moveLarge(g, 4);\n                    Q0();\n                } else {\n                    int dr=-1, dc=-1;\n                    int tgt_row = v/5;\n                    for(int ci=0;ci<3;ci++){\n                        int c=stashCols[ci];\n                        if(grid[tgt_row][c]==-1){dr=tgt_row;dc=c;break;}\n                    }\n                    if(dr==-1) {\n                        for(int ci=0;ci<3 && dr==-1;ci++){\n                            int c=stashCols[ci];\n                            for(int r=0;r<5;r++) if(grid[r][c]==-1){dr=r;dc=c;break;}\n                        }\n                    }\n                    if(dr==-1) break;\n                    moveLarge(dr, dc);\n                    Q0();\n                }\n                continue;\n            }\n            \n            vector<tuple<int,int,int,int>> wants;\n            for(int g=0;g<5;g++){\n                if(nout[g]>=5) continue;\n                int w = g*5 + nout[g];\n                for(int r=0;r<5;r++) for(int c=0;c<5;c++){\n                    if(grid[r][c]==w) {\n                        wants.push_back({w, r, c, g});\n                    }\n                }\n            }\n            \n            if(!wants.empty()){\n                int n = wants.size();\n                vector<int> perm(n);\n                iota(perm.begin(), perm.end(), 0);\n                int bestCost = INT_MAX;\n                int bestFirst = 0;\n                do {\n                    int cost = 0;\n                    int curR = cr[0], curC = cc[0];\n                    for(int idx : perm){\n                        auto& [w, r, c, g] = wants[idx];\n                        cost += abs(curR - r) + abs(curC - c) + abs(r - g) + abs(4 - c);\n                        curR = g; curC = 4;\n                    }\n                    if(cost < bestCost){\n                        bestCost = cost;\n                        bestFirst = perm[0];\n                    }\n                } while(next_permutation(perm.begin(), perm.end()));\n                \n                auto& [w, r, c, g] = wants[bestFirst];\n                moveLarge(r, c);\n                P0();\n                moveLarge(g, 4);\n                Q0();\n                stuck=0;\n            } else {\n                int sr = -1;\n                int best_prio = INT_MAX;\n                for(int i=0;i<5;i++){\n                    if(grid[i][0]==-1) continue;\n                    int prio;\n                    if(nin[i]>=5) prio = 10000;\n                    else {\n                        int next = A[i][nin[i]];\n                        bool isWant = false;\n                        for(int g=0;g<5;g++){\n                            if(nout[g]<5 && g*5+nout[g]==next){isWant=true; break;}\n                        }\n                        prio = isWant ? (-1000+next) : next;\n                    }\n                    if(prio < best_prio){\n                        best_prio = prio;\n                        sr = i;\n                    }\n                }\n                if(sr==-1){\n                    doStep(\".....\");\n                    stuck++;\n                    if(stuck>200) break;\n                    continue;\n                }\n                int v = grid[sr][0];\n                int tgt_row = v/5;\n                int dr=-1, dc=-1;\n                for(int ci=0;ci<3;ci++){\n                    int c=stashCols[ci];\n                    if(grid[tgt_row][c]==-1){dr=tgt_row;dc=c;break;}\n                }\n                if(dr==-1) {\n                    for(int ci=0;ci<3 && dr==-1;ci++){\n                        int c=stashCols[ci];\n                        for(int r=0;r<5;r++) if(grid[r][c]==-1){dr=r;dc=c;break;}\n                    }\n                }\n                if(dr==-1){\n                    doStep(\".....\");\n                    stuck++;\n                    if(stuck>200) break;\n                    continue;\n                }\n                moveLarge(sr,0);\n                P0();\n                moveLarge(dr,dc);\n                Q0();\n                stuck=0;\n            }\n        }\n    }\n    \n    void solve(int p1type, int scOpt, int p2type) {\n        init();\n        if(p1type==0) phase1_2pass();\n        else if(p1type==1) phase1_3pass();\n        else if(p1type==2) phase1_hybrid1();\n        else if(p1type==3) phase1_hybrid2();\n        else phase1_hybrid1_active();\n        \n        int opts[][3] = {{3,2,1},{2,3,1},{3,1,2}};\n        for(int k=0;k<3;k++) stashCols[k] = opts[scOpt][k];\n        \n        if(p2type == 0) { wantTieBreak = 0; phase2(); }\n        else if(p2type == 1) { wantTieBreak = 1; phase2(); }\n        else phase2_tsp();\n    }\n};\n\nint main(){\n    int N; cin>>N;\n    for(int i=0;i<5;i++) for(int j=0;j<5;j++) cin>>A[i][j];\n    \n    int bestScore = INT_MAX;\n    Run best;\n    \n    for(int p1=0; p1<5; p1++) for(int sc=0; sc<3; sc++) for(int p2=0; p2<3; p2++) {\n        Run r;\n        r.solve(p1, sc, p2);\n        int score;\n        if(r.totalDisp == 25) score = r.turns;\n        else score = 1000000 - r.totalDisp;\n        if(score < bestScore){\n            bestScore = score;\n            best = r;\n        }\n    }\n    \n    for(int i=0;i<5;i++) cout<<best.out[i]<<\"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint H0[25][25];\n\nstruct Sim {\n    int h[25][25];\n    int negCount=0, posCount=0;\n    vector<string> ops;\n    int cr=0, cc=0;\n    long long load=0;\n    long long cost=0;\n    \n    void init(){\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)h[i][j]=H0[i][j];\n        ops.clear(); cr=cc=0; load=0; cost=0;\n        negCount=posCount=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            if(h[i][j]>0)posCount++;\n            else if(h[i][j]<0)negCount++;\n        }\n    }\n    void updateCount(int oldv, int newv){\n        if(oldv>0)posCount--; else if(oldv<0)negCount--;\n        if(newv>0)posCount++; else if(newv<0)negCount++;\n    }\n    void mv(char d){\n        ops.push_back(string(1,d));\n        cost += 100+load;\n        if(d=='U')cr--; else if(d=='D')cr++; else if(d=='L')cc--; else cc++;\n    }\n    void doLoad(long long d){\n        if(d<=0)return;\n        int oldv=h[cr][cc]; h[cr][cc]-=d; updateCount(oldv,h[cr][cc]);\n        ops.push_back(\"+\"+to_string(d)); load+=d; cost+=d;\n    }\n    void doUnload(long long d){\n        if(d<=0)return;\n        int oldv=h[cr][cc]; h[cr][cc]+=d; updateCount(oldv,h[cr][cc]);\n        ops.push_back(\"-\"+to_string(d)); load-=d; cost+=d;\n    }\n    void moveTo(int tr,int tc){\n        while(cr!=tr){ if(cr<tr)mv('D'); else mv('U'); }\n        while(cc!=tc){ if(cc<tc)mv('R'); else mv('L'); }\n    }\n    void actHere(){\n        if(h[cr][cc]<0 && load>0) doUnload(min(load,(long long)-h[cr][cc]));\n        if(h[cr][cc]>0 && negCount>0) doLoad(h[cr][cc]);\n    }\n    void smartMoveTo(int tr, int tc){\n        while(cr!=tr || cc!=tc){\n            actHere();\n            if(cr!=tr){ if(cr<tr)mv('D'); else mv('U'); }\n            else { if(cc<tc)mv('R'); else mv('L'); }\n        }\n    }\n    void bestMoveTo(int tr, int tc){\n        auto scorePath = [&](bool rowFirst)->long long{\n            long long sc=0;\n            int cr2=cr, cc2=cc;\n            auto step=[&](int r, int c){\n                if(h[r][c]<0 && load>0) sc+= min(load,(long long)-h[r][c]);\n                if(h[r][c]>0 && negCount>0) sc+= h[r][c];\n            };\n            if(rowFirst){\n                while(cr2!=tr){ step(cr2,cc2); if(cr2<tr)cr2++; else cr2--; }\n                while(cc2!=tc){ step(cr2,cc2); if(cc2<tc)cc2++; else cc2--; }\n            } else {\n                while(cc2!=tc){ step(cr2,cc2); if(cc2<tc)cc2++; else cc2--; }\n                while(cr2!=tr){ step(cr2,cc2); if(cr2<tr)cr2++; else cr2--; }\n            }\n            return sc;\n        };\n        bool rowFirst = scorePath(true) >= scorePath(false);\n        if(rowFirst){\n            while(cr!=tr){ actHere(); if(cr<tr)mv('D'); else mv('U'); }\n            while(cc!=tc){ actHere(); if(cc<tc)mv('R'); else mv('L'); }\n        } else {\n            while(cc!=tc){ actHere(); if(cc<tc)mv('R'); else mv('L'); }\n            while(cr!=tr){ actHere(); if(cr<tr)mv('D'); else mv('U'); }\n        }\n    }\n    bool done(){ return negCount==0 && posCount==0; }\n};\n\nvector<pair<int,int>> buildPath(bool rowMajor, bool startBot, bool startRight){\n    vector<pair<int,int>> path;\n    if(rowMajor){\n        for(int ii=0;ii<N;ii++){\n            int i = startBot ? N-1-ii : ii;\n            bool rev = (ii%2==1) ^ startRight;\n            if(!rev) for(int j=0;j<N;j++) path.push_back({i,j});\n            else for(int j=N-1;j>=0;j--) path.push_back({i,j});\n        }\n    } else {\n        for(int jj=0;jj<N;jj++){\n            int j = startRight ? N-1-jj : jj;\n            bool rev = (jj%2==1) ^ startBot;\n            if(!rev) for(int i=0;i<N;i++) path.push_back({i,j});\n            else for(int i=N-1;i>=0;i--) path.push_back({i,j});\n        }\n    }\n    return path;\n}\n\nvoid snakePass(Sim& s, vector<pair<int,int>>& path, bool rev){\n    if(!rev){\n        for(auto& p:path){\n            int r=p.first,c=p.second;\n            s.moveTo(r,c);\n            if(s.h[r][c]>0) s.doLoad(s.h[r][c]);\n            else if(s.h[r][c]<0) s.doUnload(min(s.load,(long long)-s.h[r][c]));\n        }\n    } else {\n        for(int i=(int)path.size()-1;i>=0;i--){\n            int r=path[i].first,c=path[i].second;\n            s.moveTo(r,c);\n            if(s.h[r][c]>0) s.doLoad(s.h[r][c]);\n            else if(s.h[r][c]<0) s.doUnload(min(s.load,(long long)-s.h[r][c]));\n        }\n    }\n}\n\nvoid smartSnakePass(Sim& s, vector<pair<int,int>>& path){\n    int n=path.size();\n    vector<long long> sufNeg(n+1,0);\n    for(int i=n-1;i>=0;i--){\n        int r=path[i].first,c=path[i].second;\n        sufNeg[i] = sufNeg[i+1] + max(0,-s.h[r][c]);\n    }\n    for(int idx=0;idx<n;idx++){\n        int r=path[idx].first,c=path[idx].second;\n        s.moveTo(r,c);\n        if(s.h[r][c]>0){\n            long long demand = sufNeg[idx+1];\n            long long toLoad = min((long long)s.h[r][c], max(0LL, demand - s.load));\n            s.doLoad(toLoad);\n        } else if(s.h[r][c]<0){\n            s.doUnload(min(s.load,(long long)-s.h[r][c]));\n        }\n    }\n}\n\nvoid trimmedRow(Sim& s, bool startBot){\n    for(int ri=0;ri<N;ri++){\n        int r = startBot ? N-1-ri : ri;\n        int lo=N, hi=-1;\n        for(int c=0;c<N;c++)if(s.h[r][c]!=0){ lo=min(lo,c); hi=max(hi,c); }\n        if(lo>hi) continue;\n        \n        bool leftFirst = abs(s.cc-lo) <= abs(s.cc-hi);\n        int startC = leftFirst ? lo : hi;\n        int endC = leftFirst ? hi : lo;\n        \n        s.moveTo(r, startC);\n        if(s.h[r][s.cc]>0) s.doLoad(s.h[r][s.cc]);\n        else if(s.h[r][s.cc]<0) s.doUnload(min(s.load,(long long)-s.h[r][s.cc]));\n        int dir = startC < endC ? 1 : -1;\n        while(s.cc != endC){\n            s.mv(dir==1?'R':'L');\n            if(s.h[r][s.cc]>0) s.doLoad(s.h[r][s.cc]);\n            else if(s.h[r][s.cc]<0) s.doUnload(min(s.load,(long long)-s.h[r][s.cc]));\n        }\n    }\n}\n\nvoid trimmedCol(Sim& s, bool startRight){\n    for(int ci=0;ci<N;ci++){\n        int c = startRight ? N-1-ci : ci;\n        int lo=N, hi=-1;\n        for(int r=0;r<N;r++)if(s.h[r][c]!=0){ lo=min(lo,r); hi=max(hi,r); }\n        if(lo>hi) continue;\n        \n        bool topFirst = abs(s.cr-lo) <= abs(s.cr-hi);\n        int startR = topFirst ? lo : hi;\n        int endR = topFirst ? hi : lo;\n        \n        s.moveTo(startR, c);\n        if(s.h[s.cr][c]>0) s.doLoad(s.h[s.cr][c]);\n        else if(s.h[s.cr][c]<0) s.doUnload(min(s.load,(long long)-s.h[s.cr][c]));\n        int dir = startR < endR ? 1 : -1;\n        while(s.cr != endR){\n            s.mv(dir==1?'D':'U');\n            if(s.h[s.cr][c]>0) s.doLoad(s.h[s.cr][c]);\n            else if(s.h[s.cr][c]<0) s.doUnload(min(s.load,(long long)-s.h[s.cr][c]));\n        }\n    }\n}\n\nvoid greedyCleanup(Sim& s, int mm){\n    int guard=0;\n    while(!s.done() && guard++<5000){\n        int target=-1,td=INT_MAX;\n        bool lookForNeg = (s.load>0);\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            bool match = lookForNeg ? s.h[i][j]<0 : s.h[i][j]>0;\n            if(match){\n                int d=abs(i-s.cr)+abs(j-s.cc);\n                if(d<td){td=d;target=i*N+j;}\n            }\n        }\n        if(target<0){\n            lookForNeg=!lookForNeg;\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                bool match = lookForNeg ? s.h[i][j]<0 : s.h[i][j]>0;\n                if(match){\n                    int d=abs(i-s.cr)+abs(j-s.cc);\n                    if(d<td){td=d;target=i*N+j;}\n                }\n            }\n            if(target<0)break;\n        }\n        int tr=target/N, tc=target%N;\n        if(mm==1) s.smartMoveTo(tr,tc);\n        else if(mm==2) s.bestMoveTo(tr,tc);\n        else s.moveTo(tr,tc);\n        if(s.h[tr][tc]>0) s.doLoad(s.h[tr][tc]);\n        else if(s.h[tr][tc]<0) s.doUnload(min(s.load,(long long)-s.h[tr][tc]));\n    }\n}\n\nvoid pureGreedy(Sim& s, int mm){\n    int guard=0;\n    while(!s.done() && guard++<5000){\n        if(s.h[s.cr][s.cc]>0 && s.negCount>0){\n            s.doLoad(s.h[s.cr][s.cc]); continue;\n        }\n        if(s.h[s.cr][s.cc]<0 && s.load>0){\n            s.doUnload(min(s.load,(long long)-s.h[s.cr][s.cc]));\n            continue;\n        }\n        int target=-1,td=INT_MAX;\n        if(s.load>0){\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                if(s.h[i][j]<0){\n                    int d=abs(i-s.cr)+abs(j-s.cc);\n                    if(d<td){td=d;target=i*N+j;}\n                }\n            }\n        } else {\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                if(s.h[i][j]>0){\n                    int d=abs(i-s.cr)+abs(j-s.cc);\n                    if(d<td){td=d;target=i*N+j;}\n                }\n            }\n        }\n        if(target<0) break;\n        int tr=target/N, tc=target%N;\n        if(mm==1) s.smartMoveTo(tr,tc);\n        else if(mm==2) s.bestMoveTo(tr,tc);\n        else s.moveTo(tr,tc);\n    }\n}\n\nint main(){\n    cin>>N;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>H0[i][j];\n    \n    Sim best;\n    long long bestCost = LLONG_MAX;\n    \n    auto tryIt = [&](Sim& s){\n        long long c = s.done() ? s.cost : LLONG_MAX;\n        if(c < bestCost){ bestCost = c; best = s; }\n    };\n    \n    for(int mm=0;mm<3;mm++){\n        Sim s; s.init(); pureGreedy(s, mm); tryIt(s);\n    }\n    \n    for(int rm=0;rm<2;rm++)for(int sb=0;sb<2;sb++)for(int sr=0;sr<2;sr++){\n        auto path = buildPath(rm, sb, sr);\n        \n        for(int mm=0;mm<3;mm++){\n            {Sim s; s.init(); snakePass(s, path, false); greedyCleanup(s, mm); tryIt(s);}\n            {Sim s; s.init(); smartSnakePass(s, path); greedyCleanup(s, mm); tryIt(s);}\n            {Sim s; s.init(); for(int it=0;it<10 && !s.done();it++){ if(rm)trimmedRow(s,sb^(it%2)); else trimmedCol(s,sr^(it%2));} greedyCleanup(s, mm); tryIt(s);}\n        }\n        {Sim s; s.init(); for(int it=0;it<20 && !s.done();it++) snakePass(s, path, it%2==1); tryIt(s);}\n        {Sim s; s.init(); snakePass(s, path, false); if(!s.done()) snakePass(s, path, true); greedyCleanup(s, 2); tryIt(s);}\n    }\n    \n    for(auto&o:best.ops) cout<<o<<\"\\n\";\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, T, SC;\nvector<vector<int>> X;\nmt19937 rng(12345);\n\ninline int pairScore(int a, int b) {\n    int s = 0;\n    for (int l = 0; l < M; l++) s += max(X[a][l], X[b][l]);\n    return s;\n}\n\nint main() {\n    cin >> N >> M >> T;\n    SC = 2*N*(N-1);\n    X.assign(SC, vector<int>(M));\n    for (int i = 0; i < SC; i++)\n        for (int j = 0; j < M; j++) cin >> X[i][j];\n    \n    for (int t = 0; t < T; t++) {\n        bool isLast = (t == T-1);\n        \n        vector<int> Xmax(M, 0);\n        for (int k = 0; k < SC; k++)\n            for (int l = 0; l < M; l++) Xmax[l] = max(Xmax[l], X[k][l]);\n        \n        vector<double> sscore(SC, 0);\n        for (int k = 0; k < SC; k++) {\n            for (int l = 0; l < M; l++) {\n                if (Xmax[l] > 0) {\n                    double r = (double)X[k][l] / Xmax[l];\n                    sscore[k] += r * r * Xmax[l];\n                }\n            }\n        }\n        \n        vector<int> idx(SC);\n        iota(idx.begin(), idx.end(), 0);\n        sort(idx.begin(), idx.end(), [&](int a, int b){ return sscore[a] > sscore[b]; });\n        vector<int> chosen(idx.begin(), idx.begin() + N*N);\n        \n        set<int> chosenSet(chosen.begin(), chosen.end());\n        for (int l = 0; l < M; l++) {\n            vector<int> maxSeeds;\n            for (int k = 0; k < SC; k++) if (X[k][l] == Xmax[l]) maxSeeds.push_back(k);\n            bool found = false;\n            for (int k : maxSeeds) if (chosenSet.count(k)) { found = true; break; }\n            if (!found && !maxSeeds.empty()) {\n                int best = maxSeeds[0];\n                for (int k : maxSeeds) if (sscore[k] > sscore[best]) best = k;\n                int worst = -1; double worstS = 1e18;\n                for (int c : chosen) {\n                    bool isUnique = false;\n                    for (int ll = 0; ll < M; ll++) {\n                        if (X[c][ll] == Xmax[ll]) {\n                            int cnt = 0;\n                            for (int kk : chosen) if (X[kk][ll] == Xmax[ll]) cnt++;\n                            if (cnt == 1) { isUnique = true; break; }\n                        }\n                    }\n                    if (isUnique) continue;\n                    if (sscore[c] < worstS) { worstS = sscore[c]; worst = c; }\n                }\n                if (worst >= 0) {\n                    auto it = find(chosen.begin(), chosen.end(), worst);\n                    *it = best;\n                    chosenSet.erase(worst); chosenSet.insert(best);\n                }\n            }\n        }\n        \n        int NN = N*N;\n        vector<vector<int>> P(NN, vector<int>(NN, 0));\n        for (int i = 0; i < NN; i++)\n            for (int j = 0; j < NN; j++) {\n                if (isLast) {\n                    int sum=0, diffSq=0;\n                    int a=chosen[i], b=chosen[j];\n                    for (int l = 0; l < M; l++) {\n                        sum += X[a][l] + X[b][l];\n                        int d = X[a][l]-X[b][l];\n                        diffSq += d*d;\n                    }\n                    double s = (sum + 2.0 * sqrt((double)diffSq)) * 0.5;\n                    P[i][j] = (int)(s * 100);\n                } else {\n                    P[i][j] = pairScore(chosen[i], chosen[j]);\n                }\n            }\n        \n        vector<int> chosenOrder(NN);\n        iota(chosenOrder.begin(), chosenOrder.end(), 0);\n        sort(chosenOrder.begin(), chosenOrder.end(), [&](int a, int b){\n            return sscore[chosen[a]] > sscore[chosen[b]];\n        });\n        \n        static const int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};\n        \n        auto totalScoreA = [&](vector<vector<int>>& AA) {\n            int s = 0;\n            for (int i = 0; i < N; i++)\n                for (int j = 0; j < N; j++) {\n                    if (j+1 < N) s += P[AA[i][j]][AA[i][j+1]];\n                    if (i+1 < N) s += P[AA[i][j]][AA[i+1][j]];\n                }\n            return s;\n        };\n        \n        auto deltaSwap = [&](vector<vector<int>>& AA, int i1, int j1, int i2, int j2) {\n            int a1 = AA[i1][j1], a2 = AA[i2][j2];\n            int before = 0, after = 0;\n            for (int d = 0; d < 4; d++) {\n                int ni = i1+dr[d], nj = j1+dc[d];\n                if (ni<0||ni>=N||nj<0||nj>=N) continue;\n                if (ni==i2 && nj==j2) continue;\n                int nb = AA[ni][nj];\n                before += P[a1][nb];\n                after += P[a2][nb];\n            }\n            for (int d = 0; d < 4; d++) {\n                int ni = i2+dr[d], nj = j2+dc[d];\n                if (ni<0||ni>=N||nj<0||nj>=N) continue;\n                if (ni==i1 && nj==j1) continue;\n                int nb = AA[ni][nj];\n                before += P[a2][nb];\n                after += P[a1][nb];\n            }\n            return after - before;\n        };\n        \n        vector<pair<int,int>> cells;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            int deg = (i>0)+(i<N-1)+(j>0)+(j<N-1);\n            cells.push_back({-deg, i*N+j});\n        }\n        sort(cells.begin(), cells.end());\n        \n        vector<vector<int>> A(N, vector<int>(N));\n        for (int c = 0; c < NN; c++) {\n            int p = cells[c].second;\n            A[p/N][p%N] = chosenOrder[c];\n        }\n        \n        int curScore = totalScoreA(A);\n        int bestScore = curScore;\n        vector<vector<int>> bestA = A;\n        \n        auto start = chrono::steady_clock::now();\n        double timeLimit = 0.19;\n        double T0 = isLast ? 3000.0 : 30.0;\n        double T1 = isLast ? 10.0 : 0.1;\n        double temp = T0;\n        int iters = 0;\n        \n        while (true) {\n            iters++;\n            if ((iters & 1023) == 0) {\n                auto now = chrono::steady_clock::now();\n                double elapsed = chrono::duration<double>(now-start).count();\n                if (elapsed > timeLimit) break;\n                double progress = elapsed / timeLimit;\n                temp = T0 * pow(T1/T0, progress);\n            }\n            \n            int p1 = rng() % NN;\n            int p2 = rng() % NN;\n            if (p1 == p2) continue;\n            int i1=p1/N, j1=p1%N, i2=p2/N, j2=p2%N;\n            int delta = deltaSwap(A, i1, j1, i2, j2);\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else {\n                double p = exp(delta / temp);\n                if ((double)(rng() & 0xFFFFFF) / (double)0x1000000 < p) accept = true;\n            }\n            if (accept) {\n                swap(A[i1][j1], A[i2][j2]);\n                curScore += delta;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestA = A;\n                }\n            }\n        }\n        \n        A = bestA;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << chosen[A[i][j]];\n                cout << (j==N-1 ? '\\n' : ' ');\n            }\n        }\n        cout.flush();\n        \n        for (int i = 0; i < SC; i++)\n            for (int j = 0; j < M; j++) cin >> X[i][j];\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V, Vp;\nint dx[4] = {0, 1, 0, -1};\nint dy[4] = {1, 0, -1, 0};\n\nint main() {\n    cin >> N >> M >> V;\n    vector<string> sg(N), tg(N);\n    for (auto& s : sg) cin >> s;\n    for (auto& s : tg) cin >> s;\n    \n    vector<vector<int>> has_(N, vector<int>(N, 0));\n    vector<vector<int>> isTarget(N, vector<int>(N, 0));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        has_[i][j] = sg[i][j]=='1';\n        isTarget[i][j] = tg[i][j]=='1';\n    }\n    \n    Vp = V;\n    int nFingers = Vp - 1;\n    \n    vector<int> L(nFingers);\n    for (int i = 0; i < nFingers; i++) L[i] = min(i + 1, N - 1);\n    \n    cout << Vp << \"\\n\";\n    for (int i = 0; i < nFingers; i++) cout << 0 << \" \" << L[i] << \"\\n\";\n    \n    long long sumX = 0, sumY = 0, cnt = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (has_[i][j] || isTarget[i][j]) {\n            sumX += i; sumY += j; cnt++;\n        }\n    }\n    int rx = cnt > 0 ? (int)(sumX / cnt) : N/2;\n    int ry = cnt > 0 ? (int)(sumY / cnt) : N/2;\n    rx = max(0, min(N-1, rx));\n    ry = max(0, min(N-1, ry));\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<int> fdir(nFingers, 0);\n    vector<int> fhold(nFingers, 0);\n    \n    vector<string> ops;\n    \n    auto rotCost = [](int a, int b) -> int {\n        int d = (a - b + 4) & 3;\n        return min(d, 4 - d);\n    };\n    \n    auto doTurn = [&](char moveC, vector<char>& rotC) {\n        if (moveC == 'U') rx--;\n        else if (moveC == 'D') rx++;\n        else if (moveC == 'L') ry--;\n        else if (moveC == 'R') ry++;\n        for (int i = 0; i < nFingers; i++) {\n            if (rotC[i] == 'R') fdir[i] = (fdir[i]+1)%4;\n            else if (rotC[i] == 'L') fdir[i] = (fdir[i]+3)%4;\n        }\n        vector<bool> actuallyP(nFingers, false);\n        for (int i = 0; i < nFingers; i++) {\n            int fx = rx + dx[fdir[i]]*L[i];\n            int fy = ry + dy[fdir[i]]*L[i];\n            if (fx<0||fx>=N||fy<0||fy>=N) continue;\n            if (fhold[i] == 0) {\n                if (has_[fx][fy] && !isTarget[fx][fy]) {\n                    has_[fx][fy] = 0; fhold[i] = 1; actuallyP[i] = true;\n                }\n            } else {\n                if (!has_[fx][fy] && isTarget[fx][fy]) {\n                    has_[fx][fy] = 1; fhold[i] = 0; actuallyP[i] = true;\n                }\n            }\n        }\n        string s(2*Vp, '.');\n        if (moveC != 0) s[0] = moveC;\n        for (int i = 0; i < nFingers; i++) if (rotC[i]) s[1+i] = rotC[i];\n        for (int i = 0; i < nFingers; i++) if (actuallyP[i]) s[Vp+1+i] = 'P';\n        ops.push_back(s);\n    };\n    \n    auto planFull = [&](int rrx, int rry, int& P, int& maxRot, vector<int>& tdir) {\n        P = 0; maxRot = 0;\n        for (int fi = 0; fi < nFingers; fi++) tdir[fi] = -1;\n        for (int fi = 0; fi < nFingers; fi++) {\n            int bestRot = INT_MAX, bestD = -1;\n            int Li = L[fi], fdi = fdir[fi], fhi = fhold[fi];\n            for (int d = 0; d < 4; d++) {\n                int fx = rrx + dx[d]*Li, fy = rry + dy[d]*Li;\n                if (fx<0||fx>=N||fy<0||fy>=N) continue;\n                bool useful = false;\n                if (fhi == 0) useful = has_[fx][fy] && !isTarget[fx][fy];\n                else useful = !has_[fx][fy] && isTarget[fx][fy];\n                if (useful) {\n                    int rc = rotCost(fdi, d);\n                    if (rc < bestRot) { bestRot = rc; bestD = d; }\n                }\n            }\n            if (bestD != -1) {\n                P++;\n                if (bestRot > maxRot) maxRot = bestRot;\n                tdir[fi] = bestD;\n            }\n        }\n    };\n    \n    auto planScore = [&](int rrx, int rry, int& P, int& maxRot) {\n        P = 0; maxRot = 0;\n        for (int fi = 0; fi < nFingers; fi++) {\n            int bestRot = INT_MAX, bestD = -1;\n            int Li = L[fi], fdi = fdir[fi], fhi = fhold[fi];\n            for (int d = 0; d < 4; d++) {\n                int fx = rrx + dx[d]*Li, fy = rry + dy[d]*Li;\n                if (fx<0||fx>=N||fy<0||fy>=N) continue;\n                bool useful = false;\n                if (fhi == 0) useful = has_[fx][fy] && !isTarget[fx][fy];\n                else useful = !has_[fx][fy] && isTarget[fx][fy];\n                if (useful) {\n                    int rc = rotCost(fdi, d);\n                    if (rc < bestRot) { bestRot = rc; bestD = d; }\n                }\n            }\n            if (bestD != -1) {\n                P++;\n                if (bestRot > maxRot) maxRot = bestRot;\n            }\n        }\n    };\n    \n    auto bestHeuristicDir = [&](int rrx, int rry, int fi) -> int {\n        int bestD = fdir[fi];\n        int bestRot = INT_MAX;\n        int Li = L[fi], fdi = fdir[fi], fhi = fhold[fi];\n        for (int d = 0; d < 4; d++) {\n            int fx = rrx + dx[d]*Li, fy = rry + dy[d]*Li;\n            if (fx<0||fx>=N||fy<0||fy>=N) continue;\n            bool useful = false;\n            if (fhi == 0) useful = has_[fx][fy] && !isTarget[fx][fy];\n            else useful = !has_[fx][fy] && isTarget[fx][fy];\n            if (useful) {\n                int rc = rotCost(fdi, d);\n                if (rc < bestRot) { bestRot = rc; bestD = d; }\n            }\n        }\n        return bestD;\n    };\n    \n    auto applyPlanToState = [&](int rrx, int rry, const vector<int>& tdir) {\n        rx = rrx; ry = rry;\n        for (int fi = 0; fi < nFingers; fi++) {\n            if (tdir[fi] != -1) fdir[fi] = tdir[fi];\n        }\n        for (int fi = 0; fi < nFingers; fi++) {\n            if (tdir[fi] == -1) continue;\n            int fx = rx + dx[fdir[fi]] * L[fi];\n            int fy = ry + dy[fdir[fi]] * L[fi];\n            if (fx<0||fx>=N||fy<0||fy>=N) continue;\n            if (fhold[fi] == 0) {\n                if (has_[fx][fy] && !isTarget[fx][fy]) {\n                    has_[fx][fy] = 0; fhold[fi] = 1;\n                }\n            } else {\n                if (!has_[fx][fy] && isTarget[fx][fy]) {\n                    has_[fx][fy] = 1; fhold[fi] = 0;\n                }\n            }\n        }\n    };\n    \n    auto clock_start = chrono::steady_clock::now();\n    auto elapsed_ms = [&]() {\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - clock_start).count();\n    };\n    \n    struct Cand {\n        double score;\n        int rrx, rry, P, T;\n        vector<int> tdir;\n    };\n    \n    vector<int> tdir_buf(nFingers);\n    \n    while (true) {\n        int srcCnt = 0;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (has_[i][j] && !isTarget[i][j]) srcCnt++;\n        }\n        int nHolding = 0;\n        for (int i = 0; i < nFingers; i++) nHolding += fhold[i];\n        \n        if (srcCnt == 0 && nHolding == 0) break;\n        if ((int)ops.size() > 95000) break;\n        \n        vector<Cand> cands;\n        cands.reserve(N*N);\n        for (int rrx = 0; rrx < N; rrx++)\n        for (int rry = 0; rry < N; rry++) {\n            int P, maxRot;\n            planFull(rrx, rry, P, maxRot, tdir_buf);\n            if (P == 0) continue;\n            int move = abs(rrx-rx) + abs(rry-ry);\n            int T = max(move, maxRot);\n            if (T == 0) T = 1;\n            double score = (double)P / T;\n            cands.push_back({score, rrx, rry, P, T, tdir_buf});\n        }\n        \n        if (cands.empty()) break;\n        \n        sort(cands.begin(), cands.end(), [](const Cand& a, const Cand& b) {\n            if (abs(a.score - b.score) > 1e-9) return a.score > b.score;\n            if (a.P != b.P) return a.P > b.P;\n            return a.T < b.T;\n        });\n        \n        int K = 10;\n        long long e = elapsed_ms();\n        if (e > 2000) K = 5;\n        if (e > 2500) K = 1;\n        K = min(K, (int)cands.size());\n        \n        int bestIdx = 0;\n        \n        if (K > 1) {\n            double bestCombined = -1;\n            for (int ci = 0; ci < K; ci++) {\n                auto& c = cands[ci];\n                auto save_has = has_;\n                auto save_fhold = fhold;\n                auto save_fdir = fdir;\n                int save_rx = rx, save_ry = ry;\n                \n                applyPlanToState(c.rrx, c.rry, c.tdir);\n                \n                int bestP2 = 0, bestT2 = 1;\n                double bestS2 = 0;\n                for (int r2x = 0; r2x < N; r2x++)\n                for (int r2y = 0; r2y < N; r2y++) {\n                    int P2, maxRot2;\n                    planScore(r2x, r2y, P2, maxRot2);\n                    if (P2 == 0) continue;\n                    int move2 = abs(r2x-rx) + abs(r2y-ry);\n                    int T2 = max(move2, maxRot2);\n                    if (T2 == 0) T2 = 1;\n                    double s2 = (double)P2 / T2;\n                    if (s2 > bestS2) { bestS2 = s2; bestP2 = P2; bestT2 = T2; }\n                }\n                \n                double combined = (double)(c.P + bestP2) / (c.T + bestT2);\n                \n                has_ = save_has;\n                fhold = save_fhold;\n                fdir = save_fdir;\n                rx = save_rx; ry = save_ry;\n                \n                if (combined > bestCombined) {\n                    bestCombined = combined;\n                    bestIdx = ci;\n                }\n            }\n        }\n        \n        auto& chosen = cands[bestIdx];\n        int bestRx = chosen.rrx, bestRy = chosen.rry;\n        vector<int>& bestTargetDir = chosen.tdir;\n        \n        int mv_dx = bestRx - rx, mv_dy = bestRy - ry;\n        vector<char> mvSeq;\n        for (int i = 0; i < abs(mv_dx); i++) mvSeq.push_back(mv_dx>0?'D':'U');\n        for (int i = 0; i < abs(mv_dy); i++) mvSeq.push_back(mv_dy>0?'R':'L');\n        \n        vector<vector<char>> rotSeq(nFingers);\n        int maxRotLen = 0;\n        for (int fi = 0; fi < nFingers; fi++) {\n            if (bestTargetDir[fi] == -1) continue;\n            int diff = (bestTargetDir[fi] - fdir[fi] + 4) % 4;\n            if (diff == 1) rotSeq[fi].push_back('R');\n            else if (diff == 2) { rotSeq[fi].push_back('R'); rotSeq[fi].push_back('R'); }\n            else if (diff == 3) rotSeq[fi].push_back('L');\n            maxRotLen = max(maxRotLen, (int)rotSeq[fi].size());\n        }\n        \n        int turns = max((int)mvSeq.size(), maxRotLen);\n        if (turns == 0) turns = 1;\n        \n        for (int t = 0; t < turns; t++) {\n            char mc = t < (int)mvSeq.size() ? mvSeq[t] : 0;\n            vector<char> rc(nFingers, 0);\n            for (int fi = 0; fi < nFingers; fi++)\n                if (t < (int)rotSeq[fi].size()) rc[fi] = rotSeq[fi][t];\n            \n            int next_rx = rx + (mc == 'D' ? 1 : mc == 'U' ? -1 : 0);\n            int next_ry = ry + (mc == 'R' ? 1 : mc == 'L' ? -1 : 0);\n            for (int fi = 0; fi < nFingers; fi++) {\n                if (rc[fi]) continue;\n                if (bestTargetDir[fi] != -1) continue;\n                int heurD = bestHeuristicDir(next_rx, next_ry, fi);\n                int diff = (heurD - fdir[fi] + 4) % 4;\n                if (diff == 1) rc[fi] = 'R';\n                else if (diff == 3) rc[fi] = 'L';\n                else if (diff == 2) rc[fi] = 'R';\n            }\n            \n            doTurn(mc, rc);\n        }\n    }\n    \n    for (auto& o : ops) cout << o << \"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<int> X, Y;\n\nstruct Result {\n    vector<pair<int,int>> poly;\n    long long score;\n    long long perim;\n    bool valid;\n};\n\nResult checkResult(vector<pair<int,int>> poly, long long score){\n    Result r;\n    r.poly = poly;\n    r.score = score;\n    long long perim=0;\n    int n=poly.size();\n    for(int i=0;i<n;i++){\n        auto& a=poly[i]; auto& b=poly[(i+1)%n];\n        perim += abs(a.first-b.first)+abs(a.second-b.second);\n    }\n    r.perim = perim;\n    set<pair<int,int>> seen;\n    bool distinct=true;\n    for(auto& p:poly){ if(seen.count(p)){distinct=false;break;} seen.insert(p); }\n    r.valid = distinct && perim<=400000 && n<=1000 && n>=4;\n    return r;\n}\n\nvector<pair<int,int>> traceOutline(vector<vector<char>>& in, int W, int H, int cw, int ch){\n    int sx=-1, sy=-1;\n    for(int r=0; r<H && sx<0; r++){\n        for(int c=0; c<W; c++){\n            if(in[c][r]){ sx=c; sy=r; break; }\n        }\n    }\n    if(sx<0) return {};\n    \n    auto isIn = [&](int c, int r)->bool{\n        if(c<0||c>=W||r<0||r>=H) return false;\n        return (bool)in[c][r];\n    };\n    \n    vector<pair<int,int>> corners;\n    int x = sx, y = sy, dir = 0;\n    corners.push_back({x, y});\n    \n    int maxSteps = 8*W*H + 100;\n    for(int step=0; step<maxSteps; step++){\n        if(dir==0) x++;\n        else if(dir==1) y++;\n        else if(dir==2) x--;\n        else y--;\n        \n        if(x == sx && y == sy) break;\n        \n        bool nw = isIn(x-1, y-1);\n        bool ne = isIn(x, y-1);\n        bool sw = isIn(x-1, y);\n        bool se = isIn(x, y);\n        \n        int nextDir;\n        if(dir == 0){\n            if(!se) nextDir = 1;\n            else if(!ne) nextDir = 0;\n            else nextDir = 3;\n        } else if(dir == 1){\n            if(!sw) nextDir = 2;\n            else if(!se) nextDir = 1;\n            else nextDir = 0;\n        } else if(dir == 2){\n            if(!nw) nextDir = 3;\n            else if(!sw) nextDir = 2;\n            else nextDir = 1;\n        } else {\n            if(!ne) nextDir = 0;\n            else if(!nw) nextDir = 3;\n            else nextDir = 2;\n        }\n        \n        if(nextDir != dir){\n            corners.push_back({x, y});\n            dir = nextDir;\n        }\n    }\n    \n    if(corners.size() < 4) return {};\n    \n    vector<pair<int,int>> poly;\n    for(auto& p : corners){\n        poly.push_back({p.first*cw, p.second*ch});\n    }\n    return poly;\n}\n\nbool isSimplyConnected(vector<vector<char>>& in, int W, int H, int totalIn){\n    if(totalIn==0) return false;\n    int startC=-1, startR=-1;\n    for(int c=0;c<W && startC<0;c++) for(int r=0;r<H;r++) if(in[c][r]){ startC=c; startR=r; break;}\n    \n    static int viscnt = 0;\n    static vector<vector<int>> vis;\n    static int viscnt2 = 0;\n    static vector<vector<int>> vis2;\n    static int bW=-1, bH=-1;\n    if(bW != W || bH != H){\n        vis.assign(W, vector<int>(H, 0));\n        vis2.assign(W+2, vector<int>(H+2, 0));\n        bW = W; bH = H;\n        viscnt = 0; viscnt2 = 0;\n    }\n    viscnt++;\n    \n    vector<pair<int,int>> stk;\n    stk.reserve(W*H);\n    stk.push_back({startC, startR}); vis[startC][startR]=viscnt;\n    int cnt=0;\n    int dx[]={1,-1,0,0}, dy[]={0,0,1,-1};\n    while(!stk.empty()){\n        auto [c,r] = stk.back(); stk.pop_back(); cnt++;\n        for(int d=0;d<4;d++){\n            int nc=c+dx[d], nr=r+dy[d];\n            if(nc<0||nc>=W||nr<0||nr>=H) continue;\n            if(!in[nc][nr]||vis[nc][nr]==viscnt) continue;\n            vis[nc][nr]=viscnt; stk.push_back({nc,nr});\n        }\n    }\n    if(cnt != totalIn) return false;\n    \n    viscnt2++;\n    int W2=W+2, H2=H+2;\n    stk.clear();\n    stk.push_back({0,0}); vis2[0][0]=viscnt2;\n    int expectedOut = (W*H - totalIn) + (2*W2 + 2*H2 - 4);\n    int reachedOut=0;\n    while(!stk.empty()){\n        auto [c,r] = stk.back(); stk.pop_back(); reachedOut++;\n        for(int d=0;d<4;d++){\n            int nc=c+dx[d], nr=r+dy[d];\n            if(nc<0||nc>=W2||nr<0||nr>=H2) continue;\n            if(vis2[nc][nr]==viscnt2) continue;\n            if(nc>=1 && nc<=W && nr>=1 && nr<=H && in[nc-1][nr-1]) continue;\n            vis2[nc][nr]=viscnt2; stk.push_back({nc,nr});\n        }\n    }\n    return reachedOut == expectedOut;\n}\n\nResult cellLocalSearch(vector<vector<char>> in, vector<vector<int>>& grid, int W, int H, int cw, int ch, int maxFlips){\n    int dx[]={1,-1,0,0}, dy[]={0,0,1,-1};\n    int totalIn = 0;\n    for(int c=0;c<W;c++) for(int r=0;r<H;r++) if(in[c][r]) totalIn++;\n    \n    if(!isSimplyConnected(in, W, H, totalIn)){\n        Result r; r.valid=false; r.score=LLONG_MIN; return r;\n    }\n    \n    auto buildResult = [&]()->Result{\n        auto poly = traceOutline(in, W, H, cw, ch);\n        long long s = 0;\n        for(int c=0;c<W;c++) for(int r=0;r<H;r++) if(in[c][r]) s += grid[c][r];\n        if(poly.empty()){ Result r; r.valid=false; r.score=LLONG_MIN; return r; }\n        return checkResult(poly, s);\n    };\n    \n    Result best = buildResult();\n    if(!best.valid) return best;\n    \n    int flipsDone = 0;\n    \n    for(int pass=0; pass<15 && flipsDone<maxFlips; pass++){\n        bool any=false;\n        for(int c=0;c<W && flipsDone<maxFlips;c++){\n            for(int r=0;r<H && flipsDone<maxFlips;r++){\n                int delta = in[c][r] ? -grid[c][r] : grid[c][r];\n                if(delta <= 0) continue;\n                \n                bool cur = in[c][r];\n                bool isB = false;\n                for(int d=0;d<4;d++){\n                    int nc=c+dx[d], nr=r+dy[d];\n                    if(nc<0||nc>=W||nr<0||nr>=H){ if(cur) isB=true; continue; }\n                    if((bool)in[nc][nr] != cur){ isB=true; break; }\n                }\n                if(!isB) continue;\n                \n                in[c][r] = 1 - in[c][r];\n                int newTotal = cur ? totalIn-1 : totalIn+1;\n                flipsDone++;\n                if(!isSimplyConnected(in, W, H, newTotal)){\n                    in[c][r] = 1 - in[c][r];\n                    continue;\n                }\n                Result cand = buildResult();\n                if(cand.valid && cand.score > best.score){\n                    best = cand;\n                    totalIn = newTotal;\n                    any = true;\n                } else {\n                    in[c][r] = 1 - in[c][r];\n                }\n            }\n        }\n        if(!any) break;\n    }\n    \n    return best;\n}\n\nResult bestRectangle(int W, int H){\n    int cw = 100000/W, ch = 100000/H;\n    vector<vector<int>> grid(W, vector<int>(H,0));\n    for(int i=0;i<2*N;i++){\n        int c = min(W-1, X[i]/cw);\n        int rr = min(H-1, Y[i]/ch);\n        grid[c][rr] += (i<N) ? 1 : -1;\n    }\n    long long best = LLONG_MIN;\n    int bC1=0, bC2=0, bR1=0, bR2=0;\n    for(int r1=0;r1<H;r1++){\n        vector<int> colSum(W, 0);\n        for(int r2=r1;r2<H;r2++){\n            for(int c=0;c<W;c++) colSum[c] += grid[c][r2];\n            long long cs=0, bestSum=LLONG_MIN;\n            int curL=0, bL=0, bR=0;\n            for(int c=0;c<W;c++){\n                if(cs<=0){ cs=colSum[c]; curL=c; } else cs+=colSum[c];\n                if(cs>bestSum){ bestSum=cs; bL=curL; bR=c; }\n            }\n            if(bestSum>best){\n                best=bestSum; bC1=bL; bC2=bR; bR1=r1; bR2=r2;\n            }\n        }\n    }\n    int x1=bC1*cw, x2=(bC2+1)*cw, y1=bR1*ch, y2=(bR2+1)*ch;\n    vector<pair<int,int>> poly = {{x1,y1},{x2,y1},{x2,y2},{x1,y2}};\n    return checkResult(poly, best);\n}\n\nvector<pair<int,int>> buildColPoly(vector<int>& lo, vector<int>& hi, int a, int b, int cw, int ch){\n    vector<pair<int,int>> poly;\n    poly.push_back({a*cw, lo[a]*ch});\n    for(int c=a;c<=b;c++){\n        int yb = lo[c]*ch;\n        if(c>a && lo[c]!=lo[c-1]){\n            poly.push_back({c*cw, yb});\n        }\n        poly.push_back({(c+1)*cw, yb});\n    }\n    poly.push_back({(b+1)*cw, (hi[b]+1)*ch});\n    for(int c=b;c>=a;c--){\n        int yt = (hi[c]+1)*ch;\n        if(c<b && hi[c]!=hi[c+1]){\n            poly.push_back({(c+1)*cw, yt});\n        }\n        poly.push_back({c*cw, yt});\n    }\n    vector<pair<int,int>> cleanPoly;\n    for(auto& p : poly){\n        if(cleanPoly.empty() || cleanPoly.back()!=p) cleanPoly.push_back(p);\n    }\n    while(cleanPoly.size()>1 && cleanPoly.front()==cleanPoly.back()) cleanPoly.pop_back();\n    return cleanPoly;\n}\n\nResult solveDirCol(int W, int H, bool swapXY){\n    int cw = 100000/W, ch = 100000/H;\n    vector<vector<int>> grid(W, vector<int>(H,0));\n    for(int i=0;i<2*N;i++){\n        int xx = swapXY ? Y[i] : X[i];\n        int yy = swapXY ? X[i] : Y[i];\n        int c = min(W-1, xx/cw);\n        int rr = min(H-1, yy/ch);\n        grid[c][rr] += (i<N) ? 1 : -1;\n    }\n    \n    vector<int> lo(W), hi(W), val(W);\n    for(int c=0;c<W;c++){\n        int bestSum = INT_MIN, bestL=0, bestR=-1;\n        int curSum=0, curL=0;\n        for(int rr=0;rr<H;rr++){\n            if(curSum <= 0){ curSum = grid[c][rr]; curL = rr; }\n            else curSum += grid[c][rr];\n            if(curSum > bestSum){ bestSum = curSum; bestL=curL; bestR=rr; }\n        }\n        lo[c]=bestL; hi[c]=bestR; val[c]=bestSum;\n    }\n    \n    int totBest=INT_MIN, cL=0, cR=0, csu=0, cSL=0;\n    for(int c=0;c<W;c++){\n        if(csu<=0){ csu=val[c]; cSL=c; } else csu+=val[c];\n        if(csu>totBest){ totBest=csu; cL=cSL; cR=c; }\n    }\n    \n    for(int c=cL+1;c<=cR;c++){\n        if(hi[c] < lo[c-1]) hi[c] = lo[c-1];\n        if(lo[c] > hi[c-1]) lo[c] = hi[c-1];\n    }\n    \n    auto makeResult = [&](int a, int b)->Result{\n        auto poly = buildColPoly(lo, hi, a, b, cw, ch);\n        long long s = 0;\n        for(int c=a;c<=b;c++) for(int r=lo[c]; r<=hi[c]; r++) s+=grid[c][r];\n        if(swapXY) for(auto& p:poly) swap(p.first,p.second);\n        return checkResult(poly, s);\n    };\n    \n    int a=cL, b=cR;\n    Result r = makeResult(a,b);\n    while(!r.valid && a<b){\n        if(val[a] < val[b]) a++;\n        else b--;\n        r = makeResult(a,b);\n    }\n    \n    if(!r.valid) return r;\n    \n    Result bestR = r;\n    \n    vector<vector<int>> pref(W, vector<int>(H+1, 0));\n    for(int c=0;c<W;c++){\n        for(int rr=0; rr<H; rr++) pref[c][rr+1] = pref[c][rr] + grid[c][rr];\n    }\n    \n    auto runLocal = [&](int a, int b){\n        for(int iter=0; iter<10; iter++){\n            bool any=false;\n            for(int c=a; c<=b; c++){\n                int maxLo = hi[c];\n                if(c>a) maxLo = min(maxLo, hi[c-1]);\n                if(c<b) maxLo = min(maxLo, hi[c+1]);\n                if(maxLo>=0){\n                    int nbL = lo[c], nbP = pref[c][lo[c]];\n                    for(int nlo=0; nlo<=maxLo; nlo++){\n                        if(pref[c][nlo] < nbP){ nbP = pref[c][nlo]; nbL = nlo; }\n                    }\n                    if(nbL != lo[c]){ lo[c] = nbL; any = true; }\n                }\n                int minHi = lo[c];\n                if(c>a) minHi = max(minHi, lo[c-1]);\n                if(c<b) minHi = max(minHi, lo[c+1]);\n                if(minHi<H){\n                    int nbH = hi[c], nbP = pref[c][hi[c]+1];\n                    for(int nhi=minHi; nhi<H; nhi++){\n                        if(pref[c][nhi+1] > nbP){ nbP = pref[c][nhi+1]; nbH = nhi; }\n                    }\n                    if(nbH != hi[c]){ hi[c] = nbH; any = true; }\n                }\n            }\n            if(!any) break;\n        }\n    };\n    \n    runLocal(a, b);\n    {\n        Result rc = makeResult(a,b);\n        if(rc.valid && rc.score > bestR.score) bestR = rc;\n    }\n    \n    for(int round=0; round<10; round++){\n        bool anyExt = false;\n        if(a > 0){\n            int na = a-1;\n            int tlo = lo[na], thi = hi[na];\n            if(thi < lo[a]) thi = lo[a];\n            if(tlo > hi[a]) tlo = hi[a];\n            int savLo = lo[na], savHi = hi[na];\n            lo[na] = tlo; hi[na] = thi;\n            Result rT = makeResult(a-1, b);\n            if(rT.valid && rT.score > bestR.score){\n                bestR = rT; a = a-1; anyExt = true;\n                runLocal(a,b);\n                Result rc = makeResult(a,b);\n                if(rc.valid && rc.score > bestR.score) bestR = rc;\n            } else {\n                lo[na] = savLo; hi[na] = savHi;\n            }\n        }\n        if(b < W-1){\n            int nb = b+1;\n            int tlo = lo[nb], thi = hi[nb];\n            if(thi < lo[b]) thi = lo[b];\n            if(tlo > hi[b]) tlo = hi[b];\n            int savLo = lo[nb], savHi = hi[nb];\n            lo[nb] = tlo; hi[nb] = thi;\n            Result rT = makeResult(a, b+1);\n            if(rT.valid && rT.score > bestR.score){\n                bestR = rT; b = b+1; anyExt = true;\n                runLocal(a,b);\n                Result rc = makeResult(a,b);\n                if(rc.valid && rc.score > bestR.score) bestR = rc;\n            } else {\n                lo[nb] = savLo; hi[nb] = savHi;\n            }\n        }\n        if(!anyExt) break;\n    }\n    \n    return bestR;\n}\n\nvector<vector<char>> rasterizePoly(vector<pair<int,int>>& poly, int W, int H){\n    int cw = 100000/W, ch = 100000/H;\n    vector<vector<char>> in(W, vector<char>(H, 0));\n    int n = poly.size();\n    for(int c=0;c<W;c++){\n        for(int r=0;r<H;r++){\n            int cx = c*cw + cw/2, cy = r*ch + ch/2;\n            int crossings = 0;\n            for(int i=0;i<n;i++){\n                int x1=poly[i].first, y1=poly[i].second;\n                int x2=poly[(i+1)%n].first, y2=poly[(i+1)%n].second;\n                if(x1==x2){\n                    if(x1 > cx){\n                        int ymin=min(y1,y2), ymax=max(y1,y2);\n                        if(ymin<=cy && cy<ymax) crossings++;\n                    }\n                }\n            }\n            if(crossings&1) in[c][r] = 1;\n        }\n    }\n    return in;\n}\n\nint main(){\n    scanf(\"%d\", &N);\n    X.resize(2*N); Y.resize(2*N);\n    for(int i=0;i<2*N;i++) scanf(\"%d %d\",&X[i],&Y[i]);\n    \n    Result best;\n    best.valid = false;\n    best.score = LLONG_MIN;\n    \n    for(int res : {50, 100, 200}){\n        if(100000%res != 0) continue;\n        Result r = bestRectangle(res, res);\n        if(r.valid && r.score > best.score) best = r;\n    }\n    \n    vector<pair<int,int>> configs;\n    for(int w : {20,25,40,50,80,100,125,160,200,250}){\n        for(int h : {20,25,40,50,80,100,125,160,200,250,500}){\n            if(100000%w==0 && 100000%h==0) configs.push_back({w,h});\n        }\n    }\n    for(auto [W,H] : configs){\n        for(int dir=0; dir<2; dir++){\n            Result r = solveDirCol(W,H,dir==1);\n            if(r.valid && r.score > best.score) best = r;\n        }\n    }\n    \n    // Multi-resolution cell LS\n    for(int MW : {100, 200, 400}){\n        if(100000%MW != 0) continue;\n        int MH = MW;\n        int cw = 100000/MW, ch = 100000/MH;\n        vector<vector<int>> grid(MW, vector<int>(MH,0));\n        for(int i=0;i<2*N;i++){\n            int c = min(MW-1, X[i]/cw);\n            int rr = min(MH-1, Y[i]/ch);\n            grid[c][rr] += (i<N) ? 1 : -1;\n        }\n        if(best.valid){\n            auto in = rasterizePoly(best.poly, MW, MH);\n            int maxF = (MW == 400) ? 500 : 2000;\n            Result rc = cellLocalSearch(in, grid, MW, MH, cw, ch, maxF);\n            if(rc.valid && rc.score > best.score) best = rc;\n        }\n    }\n    \n    if(!best.valid || best.poly.empty()){\n        best.poly = {{0,0},{1,0},{1,1},{0,1}};\n    }\n    \n    printf(\"%d\\n\",(int)best.poly.size());\n    for(auto& p : best.poly) printf(\"%d %d\\n\", p.first, p.second);\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, sigma;\nvector<int> W_, H_;\nmt19937 rng(42);\n\nstruct Rect { long long x1,y1,x2,y2; };\n\npair<long long,long long> simulate(const vector<tuple<int,int,char,int>>& ops, const vector<int>& ww, const vector<int>& hh) {\n    static vector<Rect> placed;\n    static vector<char> has;\n    if ((int)placed.size() < N) { placed.resize(N); has.resize(N); }\n    for (int i = 0; i < N; i++) has[i] = 0;\n    long long maxX=0, maxY=0;\n    for (auto& [p, r, d, b] : ops) {\n        long long w = r==0 ? ww[p] : hh[p];\n        long long h = r==0 ? hh[p] : ww[p];\n        if (d == 'U') {\n            long long x1 = (b == -1) ? 0 : placed[b].x2;\n            long long x2 = x1 + w;\n            long long y1 = 0;\n            for (int j = 0; j < N; j++) {\n                if (!has[j]) continue;\n                auto& rc = placed[j];\n                if (rc.x2 <= x1 || rc.x1 >= x2) continue;\n                if (rc.y2 > y1) y1 = rc.y2;\n            }\n            long long y2 = y1 + h;\n            placed[p] = {x1,y1,x2,y2};\n            has[p] = 1;\n            if (x2>maxX) maxX=x2; if (y2>maxY) maxY=y2;\n        } else {\n            long long y1 = (b == -1) ? 0 : placed[b].y2;\n            long long y2 = y1 + h;\n            long long x1 = 0;\n            for (int j = 0; j < N; j++) {\n                if (!has[j]) continue;\n                auto& rc = placed[j];\n                if (rc.y2 <= y1 || rc.y1 >= y2) continue;\n                if (rc.x2 > x1) x1 = rc.x2;\n            }\n            long long x2 = x1 + w;\n            placed[p] = {x1,y1,x2,y2};\n            has[p] = 1;\n            if (x2>maxX) maxX=x2; if (y2>maxY) maxY=y2;\n        }\n    }\n    return {maxX, maxY};\n}\n\nvector<tuple<int,int,char,int>> buildRowLayout(long long targetW, const vector<int>& ww, const vector<int>& hh, const vector<int>& rots) {\n    vector<tuple<int,int,char,int>> ops;\n    long long shelfX = 0;\n    int firstOfShelf = -1;\n    int prevOnShelf = -1;\n    for (int i = 0; i < N; i++) {\n        int rot = rots[i];\n        long long w = rot==0 ? ww[i] : hh[i];\n        if (firstOfShelf == -1) {\n            ops.push_back({i, rot, 'U', -1});\n            firstOfShelf = i; prevOnShelf = i; shelfX = w;\n        } else if (shelfX + w <= targetW) {\n            ops.push_back({i, rot, 'U', prevOnShelf});\n            prevOnShelf = i; shelfX += w;\n        } else {\n            ops.push_back({i, rot, 'L', firstOfShelf});\n            firstOfShelf = i; prevOnShelf = i; shelfX = w;\n        }\n    }\n    return ops;\n}\n\nuint64_t hashOps(const vector<tuple<int,int,char,int>>& ops) {\n    uint64_t h = 1469598103934665603ULL;\n    for (auto& [p,r,d,b] : ops) {\n        h ^= (uint64_t)p; h *= 1099511628211ULL;\n        h ^= (uint64_t)r; h *= 1099511628211ULL;\n        h ^= (uint64_t)d; h *= 1099511628211ULL;\n        h ^= (uint64_t)(b+2); h *= 1099511628211ULL;\n    }\n    return h;\n}\n\nint main() {\n    cin >> N >> T >> sigma;\n    W_.resize(N); H_.resize(N);\n    for (int i = 0; i < N; i++) cin >> W_[i] >> H_[i];\n    \n    long long totalArea = 0;\n    for (int i = 0; i < N; i++) totalArea += (long long)W_[i] * H_[i];\n    long long sideEst = (long long)sqrt((double)totalArea);\n    \n    using Cand = tuple<long long, uint64_t, vector<tuple<int,int,char,int>>>;\n    priority_queue<Cand> topK;\n    unordered_set<uint64_t> inQueue;\n    int maxK = max(T * 3 + 50, 200);\n    \n    auto tryOps = [&](vector<tuple<int,int,char,int>>& ops) {\n        auto [w,h] = simulate(ops, W_, H_);\n        long long sc = w+h;\n        uint64_t hh = hashOps(ops);\n        if (inQueue.count(hh)) return;\n        if ((int)topK.size() < maxK) {\n            topK.push({sc, hh, ops});\n            inQueue.insert(hh);\n        } else if (sc < get<0>(topK.top())) {\n            auto oldHash = get<1>(topK.top());\n            inQueue.erase(oldHash);\n            topK.pop();\n            topK.push({sc, hh, ops});\n            inQueue.insert(hh);\n        }\n    };\n    \n    for (double f = 0.5; f <= 2.0; f += 0.05) {\n        long long tw = (long long)(sideEst * f);\n        for (int mode = 0; mode < 3; mode++) {\n            vector<int> r(N);\n            for (int i = 0; i < N; i++) {\n                if (mode == 0) r[i] = 0;\n                else if (mode == 1) r[i] = (W_[i] > H_[i]) ? 1 : 0;\n                else r[i] = (W_[i] < H_[i]) ? 1 : 0;\n            }\n            auto ops = buildRowLayout(tw, W_, H_, r);\n            tryOps(ops);\n        }\n    }\n    \n    auto startTime = chrono::steady_clock::now();\n    auto elapsed = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - startTime).count();\n    };\n    \n    double searchTime = 2.3;\n    while (elapsed() < searchTime) {\n        vector<int> r(N);\n        for (int i = 0; i < N; i++) r[i] = rng()%2;\n        double f = 0.5 + (rng()%150)/100.0;\n        long long tw = (long long)(sideEst * f);\n        auto ops = buildRowLayout(tw, W_, H_, r);\n        tryOps(ops);\n    }\n    \n    vector<pair<long long, vector<tuple<int,int,char,int>>>> cands;\n    while (!topK.empty()) {\n        auto& top = topK.top();\n        cands.push_back({get<0>(top), get<2>(top)});\n        topK.pop();\n    }\n    sort(cands.begin(), cands.end(), [](const auto& a, const auto& b){ return a.first < b.first; });\n    \n    long long bestEst = cands[0].first;\n    long long noiseScale = (long long)(sqrt((double)N) * (double)sigma * 3.0);\n    long long threshold = bestEst + noiseScale;\n    \n    vector<int> selIdx;\n    for (int i = 0; i < (int)cands.size() && (int)selIdx.size() < T; i++) {\n        if (cands[i].first <= threshold) selIdx.push_back(i);\n        else break;\n    }\n    if (selIdx.empty()) selIdx.push_back(0);\n    \n    for (int t = 0; t < T; t++) {\n        int idx = (t < (int)selIdx.size()) ? selIdx[t] : selIdx[0];\n        auto& ops = cands[idx].second;\n        cout << ops.size() << \"\\n\";\n        for (auto& [p,r,d,b] : ops) cout << p << \" \" << r << \" \" << d << \" \" << b << \"\\n\";\n        cout.flush();\n        long long wm, hm; cin >> wm >> hm;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, H;\nvector<int> A;\nvector<vector<int>> adj;\nvector<int> par, dep;\nvector<vector<int>> ch;\n\nvoid buildChildren() {\n    ch.assign(N, {});\n    for (int i = 0; i < N; i++) if (par[i] != -1) ch[par[i]].push_back(i);\n}\n\nvoid recomputeDepths() {\n    queue<int> q;\n    for (int i = 0; i < N; i++) {\n        if (par[i] == -1) { dep[i] = 0; q.push(i); }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int c : ch[u]) { dep[c] = dep[u]+1; q.push(c); }\n    }\n}\n\nlong long computeScore() {\n    long long s = 0;\n    for (int i = 0; i < N; i++) s += (long long)(dep[i]+1) * A[i];\n    return s;\n}\n\nmt19937 rng(12345);\nvector<char> inSub;\nvector<int> subBuf;\nvector<int> stk_;\n\nbool doPass() {\n    bool improved = false;\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    shuffle(order.begin(), order.end(), rng);\n    \n    for (int v : order) {\n        subBuf.clear();\n        int sumA = 0, maxD = dep[v];\n        stk_.clear(); stk_.push_back(v);\n        while (!stk_.empty()) {\n            int u = stk_.back(); stk_.pop_back();\n            subBuf.push_back(u);\n            inSub[u] = 1;\n            sumA += A[u];\n            if (dep[u] > maxD) maxD = dep[u];\n            for (int cc : ch[u]) stk_.push_back(cc);\n        }\n        int relMaxD = maxD - dep[v];\n        int curDep = dep[v];\n        int oldP = par[v];\n        \n        vector<int> childList = ch[v];\n        int nCh = childList.size();\n        vector<int> childMaxDep(nCh), childSumA(nCh);\n        for (int i = 0; i < nCh; i++) {\n            int c = childList[i];\n            int smA = 0, mxD = dep[c];\n            stk_.clear(); stk_.push_back(c);\n            while (!stk_.empty()) {\n                int u = stk_.back(); stk_.pop_back();\n                smA += A[u];\n                if (dep[u] > mxD) mxD = dep[u];\n                for (int cc : ch[u]) stk_.push_back(cc);\n            }\n            childSumA[i] = smA;\n            childMaxDep[i] = mxD;\n        }\n        \n        long long bestNet = 0;\n        int bestP = oldP;\n        int bestDetachIdx = -1;\n        \n        // Move 1: standard re-parent\n        for (int u : adj[v]) {\n            if (u == oldP) continue;\n            if (inSub[u]) continue;\n            int newDep = dep[u] + 1;\n            if (newDep + relMaxD > H) continue;\n            int delta = newDep - curDep;\n            long long change = (long long)delta * sumA;\n            if (change > bestNet) { bestNet = change; bestP = u; bestDetachIdx = -1; }\n        }\n        \n        // Move 2: detach child + re-parent v\n        for (int i = 0; i < nCh; i++) {\n            int c = childList[i];\n            int relMax = 0;\n            for (int j = 0; j < nCh; j++) {\n                if (j == i) continue;\n                int rel = childMaxDep[j] - curDep;\n                if (rel > relMax) relMax = rel;\n            }\n            long long loss = (long long)dep[c] * childSumA[i];\n            long long newSumA = sumA - childSumA[i];\n            \n            for (int u : adj[v]) {\n                if (u == oldP) continue;\n                if (inSub[u]) continue;\n                int newDep = dep[u] + 1;\n                if (newDep + relMax > H) continue;\n                int delta = newDep - curDep;\n                long long change = (long long)delta * newSumA;\n                long long net = change - loss;\n                if (net > bestNet) { bestNet = net; bestP = u; bestDetachIdx = i; }\n            }\n        }\n        \n        for (int u : subBuf) inSub[u] = 0;\n        \n        if (bestNet > 0) {\n            if (bestDetachIdx >= 0) {\n                int c = childList[bestDetachIdx];\n                auto& vec = ch[v];\n                auto it = find(vec.begin(), vec.end(), c);\n                if (it != vec.end()) vec.erase(it);\n                par[c] = -1;\n                int dShift = -dep[c];\n                stk_.clear(); stk_.push_back(c);\n                while (!stk_.empty()) {\n                    int u = stk_.back(); stk_.pop_back();\n                    dep[u] += dShift;\n                    for (int cc : ch[u]) stk_.push_back(cc);\n                }\n            }\n            \n            int oldP2 = par[v];\n            par[v] = bestP;\n            int newDep = (bestP == -1 ? 0 : dep[bestP] + 1);\n            int delta = newDep - curDep;\n            if (oldP2 != -1) {\n                auto& vec = ch[oldP2];\n                auto it = find(vec.begin(), vec.end(), v);\n                if (it != vec.end()) vec.erase(it);\n            }\n            if (bestP != -1) ch[bestP].push_back(v);\n            stk_.clear(); stk_.push_back(v);\n            while (!stk_.empty()) {\n                int u = stk_.back(); stk_.pop_back();\n                dep[u] += delta;\n                for (int cc : ch[u]) stk_.push_back(cc);\n            }\n            improved = true;\n        }\n    }\n    return improved;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    cin >> N >> M >> H;\n    A.resize(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    adj.assign(N, {});\n    for (int i = 0; i < M; i++) {\n        int u, v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<int> xs(N), ys(N);\n    for (int i = 0; i < N; i++) cin >> xs[i] >> ys[i];\n    \n    par.assign(N, -1);\n    dep.assign(N, 0);\n    buildChildren();\n    inSub.assign(N, 0);\n    \n    auto startTime = chrono::steady_clock::now();\n    auto timeMs = [&]() -> long long {\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - startTime).count();\n    };\n    \n    long long bestScore = computeScore();\n    vector<int> bestPar = par;\n    \n    while (timeMs() < 500 && doPass()) {}\n    {\n        long long sc = computeScore();\n        if (sc > bestScore) { bestScore = sc; bestPar = par; }\n    }\n    \n    int stuckCount = 0;\n    while (timeMs() < 1850) {\n        int K;\n        if (stuckCount >= 5) {\n            K = 150 + (int)(rng() % 350);\n            stuckCount = 0;\n        } else {\n            K = 20 + (int)(rng() % 80);\n        }\n        for (int t = 0; t < K; t++) {\n            int v = (int)(rng() % N);\n            if (par[v] != -1) {\n                auto& vec = ch[par[v]];\n                auto it = find(vec.begin(), vec.end(), v);\n                if (it != vec.end()) vec.erase(it);\n                par[v] = -1;\n            }\n        }\n        recomputeDepths();\n        \n        while (timeMs() < 1850 && doPass()) {}\n        long long sc2 = computeScore();\n        if (sc2 > bestScore) {\n            bestScore = sc2;\n            bestPar = par;\n            stuckCount = 0;\n        } else {\n            stuckCount++;\n            par = bestPar;\n            buildChildren();\n            recomputeDepths();\n        }\n    }\n    \n    par = bestPar;\n    for (int i = 0; i < N; i++) cout << par[i] << \" \\n\"[i==N-1];\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nstruct State {\n    uint32_t oniRow[20], fukuRow[20];\n    uint32_t oniCol[20], fukuCol[20];\n};\nstruct Move { char d; int p; };\n\nint shiftOp(State& s, char d, int p) {\n    int rem = 0;\n    uint32_t mask = (1u << N) - 1;\n    uint32_t topBit = 1u << (N-1);\n    uint32_t clearP = ~(1u << p);\n    if (d == 'L') {\n        if (s.oniRow[p] & 1) rem = 1;\n        else if (s.fukuRow[p] & 1) rem = 2;\n        s.oniRow[p] >>= 1;\n        s.fukuRow[p] >>= 1;\n        for (int j = 0; j < N; j++) {\n            s.oniCol[j] = (s.oniCol[j] & clearP) | (((s.oniRow[p] >> j) & 1u) << p);\n            s.fukuCol[j] = (s.fukuCol[j] & clearP) | (((s.fukuRow[p] >> j) & 1u) << p);\n        }\n    } else if (d == 'R') {\n        if (s.oniRow[p] & topBit) rem = 1;\n        else if (s.fukuRow[p] & topBit) rem = 2;\n        s.oniRow[p] = (s.oniRow[p] << 1) & mask;\n        s.fukuRow[p] = (s.fukuRow[p] << 1) & mask;\n        for (int j = 0; j < N; j++) {\n            s.oniCol[j] = (s.oniCol[j] & clearP) | (((s.oniRow[p] >> j) & 1u) << p);\n            s.fukuCol[j] = (s.fukuCol[j] & clearP) | (((s.fukuRow[p] >> j) & 1u) << p);\n        }\n    } else if (d == 'U') {\n        if (s.oniCol[p] & 1) rem = 1;\n        else if (s.fukuCol[p] & 1) rem = 2;\n        s.oniCol[p] >>= 1;\n        s.fukuCol[p] >>= 1;\n        for (int i = 0; i < N; i++) {\n            s.oniRow[i] = (s.oniRow[i] & clearP) | (((s.oniCol[p] >> i) & 1u) << p);\n            s.fukuRow[i] = (s.fukuRow[i] & clearP) | (((s.fukuCol[p] >> i) & 1u) << p);\n        }\n    } else {\n        if (s.oniCol[p] & topBit) rem = 1;\n        else if (s.fukuCol[p] & topBit) rem = 2;\n        s.oniCol[p] = (s.oniCol[p] << 1) & mask;\n        s.fukuCol[p] = (s.fukuCol[p] << 1) & mask;\n        for (int i = 0; i < N; i++) {\n            s.oniRow[i] = (s.oniRow[i] & clearP) | (((s.oniCol[p] >> i) & 1u) << p);\n            s.fukuRow[i] = (s.fukuRow[i] & clearP) | (((s.fukuCol[p] >> i) & 1u) << p);\n        }\n    }\n    return rem;\n}\n\nint heuristic(const State& s) {\n    int leftF[20], rightF[20], topF[20], botF[20];\n    for (int i = 0; i < N; i++) {\n        leftF[i] = s.fukuRow[i] ? __builtin_ctz(s.fukuRow[i]) : N;\n        rightF[i] = s.fukuRow[i] ? 31 - __builtin_clz(s.fukuRow[i]) : -1;\n    }\n    for (int j = 0; j < N; j++) {\n        topF[j] = s.fukuCol[j] ? __builtin_ctz(s.fukuCol[j]) : N;\n        botF[j] = s.fukuCol[j] ? 31 - __builtin_clz(s.fukuCol[j]) : -1;\n    }\n    int h = 0;\n    for (int i = 0; i < N; i++) {\n        uint32_t o = s.oniRow[i];\n        while (o) {\n            int j = __builtin_ctz(o);\n            o &= o - 1;\n            int best = 100;\n            if (leftF[i] > j) best = min(best, j+1);\n            if (rightF[i] < j) best = min(best, N-j);\n            if (topF[j] > i) best = min(best, i+1);\n            if (botF[j] < i) best = min(best, N-i);\n            h += best;\n        }\n    }\n    return h;\n}\n\nint countOniRow(const uint32_t* oniRow) {\n    int c = 0;\n    for (int i = 0; i < N; i++) c += __builtin_popcount(oniRow[i]);\n    return c;\n}\n\nuint64_t hashRows(const uint32_t* oniRow, const uint32_t* fukuRow) {\n    uint64_t h = 0xcbf29ce484222325ULL;\n    for (int i = 0; i < N; i++) {\n        h ^= oniRow[i]; h *= 0x100000001b3ULL;\n        h ^= fukuRow[i]; h *= 0x100000001b3ULL;\n    }\n    return h;\n}\n\nstruct Node {\n    uint32_t oniRow[20], fukuRow[20];\n    int cost;\n    int h;\n    int parent;\n    int16_t p, k;\n    char d;\n};\n\nvector<Node> allNodes;\n\nvoid makeStateFromNode(State& s, const Node& n) {\n    memcpy(s.oniRow, n.oniRow, sizeof(s.oniRow));\n    memcpy(s.fukuRow, n.fukuRow, sizeof(s.fukuRow));\n    for (int j = 0; j < N; j++) { s.oniCol[j] = 0; s.fukuCol[j] = 0; }\n    for (int i = 0; i < N; i++) {\n        uint32_t o = s.oniRow[i], f = s.fukuRow[i];\n        while (o) { int j = __builtin_ctz(o); o &= o-1; s.oniCol[j] |= (1u << i); }\n        while (f) { int j = __builtin_ctz(f); f &= f-1; s.fukuCol[j] |= (1u << i); }\n    }\n}\n\nvector<Move> reconstructPath(int nodeId) {\n    vector<vector<Move>> segs;\n    while (allNodes[nodeId].parent != -1) {\n        Node& n = allNodes[nodeId];\n        vector<Move> seg;\n        for (int i = 0; i < n.k; i++) seg.push_back({n.d, (int)n.p});\n        segs.push_back(seg);\n        nodeId = n.parent;\n    }\n    reverse(segs.begin(), segs.end());\n    vector<Move> moves;\n    for (auto& s : segs) for (auto& m : s) moves.push_back(m);\n    return moves;\n}\n\nchrono::steady_clock::time_point g_start;\nint g_timeLimit;\n\nlong long elapsedMs() {\n    return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - g_start).count();\n}\n\nvector<Move> beamSearch(const State& s0_full, int W, double alpha, int costLimit, int maxNodes) {\n    allNodes.clear();\n    int totalOni = countOniRow(s0_full.oniRow);\n    vector<unordered_map<uint64_t, int>> bestIn(totalOni + 1);\n    Node root;\n    memcpy(root.oniRow, s0_full.oniRow, sizeof(root.oniRow));\n    memcpy(root.fukuRow, s0_full.fukuRow, sizeof(root.fukuRow));\n    root.cost = 0; root.h = heuristic(s0_full); root.parent = -1;\n    root.d = 0; root.p = 0; root.k = 0;\n    allNodes.push_back(root);\n    uint64_t rh = hashRows(root.oniRow, root.fukuRow);\n    bestIn[totalOni][rh] = 0;\n    int bestFinal = -1;\n    int currentBest = costLimit;\n    bool aborted = false;\n    for (int level = totalOni; level > 0 && !aborted; level--) {\n        if (elapsedMs() > g_timeLimit) break;\n        vector<int> src;\n        src.reserve(bestIn[level].size());\n        for (auto& kv : bestIn[level]) src.push_back(kv.second);\n        if (src.empty()) continue;\n        sort(src.begin(), src.end(), [&](int a, int b) {\n            double va = allNodes[a].cost + alpha * allNodes[a].h;\n            double vb = allNodes[b].cost + alpha * allNodes[b].h;\n            return va < vb;\n        });\n        if ((int)src.size() > W) src.resize(W);\n        bestIn[level].clear();\n        for (int sid : src) {\n            if (aborted) break;\n            int curCost = allNodes[sid].cost;\n            if (curCost >= currentBest) continue;\n            State curState;\n            makeStateFromNode(curState, allNodes[sid]);\n            for (char d : {'L','R','U','D'}) {\n                if (aborted) break;\n                for (int p = 0; p < N; p++) {\n                    State tmp = curState;\n                    int oniRem = 0;\n                    for (int k = 1; k <= N; k++) {\n                        int r = shiftOp(tmp, d, p);\n                        if (r == 2) break;\n                        if (r == 1) oniRem++;\n                        if (oniRem > 0) {\n                            int newCost = curCost + k;\n                            if (newCost >= currentBest) continue;\n                            int newLevel = level - oniRem;\n                            uint64_t hs = hashRows(tmp.oniRow, tmp.fukuRow);\n                            auto it = bestIn[newLevel].find(hs);\n                            if (it != bestIn[newLevel].end() && allNodes[it->second].cost <= newCost) continue;\n                            if ((int)allNodes.size() >= maxNodes) { aborted = true; break; }\n                            int hv = heuristic(tmp);\n                            Node child;\n                            memcpy(child.oniRow, tmp.oniRow, sizeof(child.oniRow));\n                            memcpy(child.fukuRow, tmp.fukuRow, sizeof(child.fukuRow));\n                            child.cost = newCost; child.h = hv;\n                            child.parent = sid; child.d = d; child.p = (int16_t)p; child.k = (int16_t)k;\n                            int nodeId = allNodes.size();\n                            allNodes.push_back(child);\n                            bestIn[newLevel][hs] = nodeId;\n                            if (newLevel == 0 && newCost < currentBest) {\n                                currentBest = newCost;\n                                bestFinal = nodeId;\n                            }\n                        }\n                    }\n                    if (aborted) break;\n                }\n            }\n        }\n    }\n    if (bestFinal == -1) return {};\n    return reconstructPath(bestFinal);\n}\n\nvector<Move> quickGreedy(State s, double alpha) {\n    vector<Move> moves;\n    int limit = 4*N*N;\n    while (countOniRow(s.oniRow) > 0) {\n        double bestSc = 1e18;\n        int bestK = 0;\n        char bestD = 0; int bestP = 0;\n        for (char d : {'L','R','U','D'}) {\n            for (int p = 0; p < N; p++) {\n                State tmp = s;\n                int oniRem = 0;\n                for (int k = 1; k <= N; k++) {\n                    int r = shiftOp(tmp, d, p);\n                    if (r == 2) break;\n                    if (r == 1) oniRem++;\n                    if (oniRem > 0) {\n                        int h = heuristic(tmp);\n                        double sc = k + alpha * h;\n                        if (sc < bestSc) {\n                            bestSc = sc; bestK = k;\n                            bestD = d; bestP = p;\n                        }\n                    }\n                }\n            }\n        }\n        if (bestK == 0) return {};\n        for (int i = 0; i < bestK; i++) {\n            shiftOp(s, bestD, bestP);\n            moves.push_back({bestD, bestP});\n            if ((int)moves.size() > limit) return {};\n        }\n    }\n    return moves;\n}\n\nvector<Move> hintSol(const vector<string>& b) {\n    vector<Move> moves;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (b[i][j]=='x') {\n        bool up=true, down=true, left=true, right=true;\n        for (int r = 0; r < i; r++) if (b[r][j]=='o') up=false;\n        for (int r = i+1; r < N; r++) if (b[r][j]=='o') down=false;\n        for (int c = 0; c < j; c++) if (b[i][c]=='o') left=false;\n        for (int c = j+1; c < N; c++) if (b[i][c]=='o') right=false;\n        int bestCost = INT_MAX; char bestDir='?';\n        if (up && 2*(i+1) < bestCost) { bestCost=2*(i+1); bestDir='U'; }\n        if (down && 2*(N-i) < bestCost) { bestCost=2*(N-i); bestDir='D'; }\n        if (left && 2*(j+1) < bestCost) { bestCost=2*(j+1); bestDir='L'; }\n        if (right && 2*(N-j) < bestCost) { bestCost=2*(N-j); bestDir='R'; }\n        int k = bestCost/2;\n        char revD = (bestDir=='U'?'D':bestDir=='D'?'U':bestDir=='L'?'R':'L');\n        int p = (bestDir=='U'||bestDir=='D')?j:i;\n        for (int t = 0; t < k; t++) moves.push_back({bestDir, p});\n        for (int t = 0; t < k; t++) moves.push_back({revD, p});\n    }\n    return moves;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> N;\n    vector<string> b(N);\n    for (int i = 0; i < N; i++) cin >> b[i];\n    State s0;\n    for (int i = 0; i < N; i++) { s0.oniRow[i] = s0.fukuRow[i] = s0.oniCol[i] = s0.fukuCol[i] = 0; }\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (b[i][j] == 'x') { s0.oniRow[i] |= (1u << j); s0.oniCol[j] |= (1u << i); }\n        else if (b[i][j] == 'o') { s0.fukuRow[i] |= (1u << j); s0.fukuCol[j] |= (1u << i); }\n    }\n    g_start = chrono::steady_clock::now();\n    g_timeLimit = 1750;\n    vector<Move> best = hintSol(b);\n    for (double a : {0.5, 1.0, 1.5, 2.0}) {\n        auto g = quickGreedy(s0, a);\n        if (!g.empty() && g.size() < best.size()) best = g;\n    }\n    int costLimit = best.size();\n    vector<tuple<int, double, int>> paramsList = {\n        make_tuple(30, 1.0, 150000), make_tuple(30, 0.5, 150000), make_tuple(30, 1.5, 150000),\n        make_tuple(50, 1.0, 300000), make_tuple(50, 0.7, 300000), make_tuple(50, 1.3, 300000),\n        make_tuple(30, 2.0, 150000), make_tuple(30, 0.3, 150000),\n        make_tuple(100, 1.0, 600000), make_tuple(100, 0.7, 600000), make_tuple(100, 1.3, 600000),\n        make_tuple(200, 1.0, 800000)\n    };\n    for (auto& tup : paramsList) {\n        int W = get<0>(tup);\n        double a = get<1>(tup);\n        int maxN = get<2>(tup);\n        if (elapsedMs() > g_timeLimit) break;\n        auto m = beamSearch(s0, W, a, costLimit, maxN);\n        if (!m.empty() && (int)m.size() < (int)best.size()) {\n            best = m;\n            costLimit = best.size();\n        }\n    }\n    for (auto& m : best) cout << m.d << \" \" << m.p << \"\\n\";\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, L;\nint Tg[128];\nint ab[256];\nint curC[128];\n\nlong long simError() {\n    int v[128] = {0};\n    for (int i = 0; i < N; i++) curC[i] = 0;\n    int x = 0;\n    for (int w = 0; w < L; w++) {\n        curC[x]++;\n        int p = v[x];\n        v[x] = p ^ 1;\n        x = ab[2*x + p];\n    }\n    long long e = 0;\n    for (int i = 0; i < N; i++) e += abs(curC[i] - Tg[i]);\n    return e;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> L;\n    for (int i = 0; i < N; i++) cin >> Tg[i];\n    \n    vector<int> filled(N, 0);\n    filled[0] = 1;\n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int x, int y){ return Tg[x] > Tg[y]; });\n    for (int x : ord) {\n        int ca = (Tg[x] + 1) / 2;\n        int cb = Tg[x] / 2;\n        int besta = 0, bv = INT_MIN;\n        for (int i = 0; i < N; i++) {\n            int vv = Tg[i] - filled[i];\n            if (vv > bv) { bv = vv; besta = i; }\n        }\n        ab[2*x] = besta;\n        filled[besta] += ca;\n        int bestb = 0; bv = INT_MIN;\n        for (int i = 0; i < N; i++) {\n            int vv = Tg[i] - filled[i];\n            if (vv > bv) { bv = vv; bestb = i; }\n        }\n        ab[2*x+1] = bestb;\n        filled[bestb] += cb;\n    }\n    \n    long long bestE = simError();\n    long long curE = bestE;\n    int bestAB[256];\n    memcpy(bestAB, ab, sizeof(ab));\n    int savedC[128];\n    memcpy(savedC, curC, sizeof(curC));\n    \n    mt19937 rng(12345);\n    auto start = chrono::steady_clock::now();\n    double TL = 1.80;\n    int iters = 0;\n    int stuck = 0;\n    \n    while (true) {\n        if ((iters & 3) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > TL) break;\n        }\n        iters++;\n        \n        int mtype = rng() % 10;\n        int idx1 = -1, idx2 = -1, old1 = 0, old2 = 0;\n        bool valid = false;\n        \n        if (mtype < 6) {\n            int highNodes[128], lowNodes[128];\n            int highWeights[128], lowWeights[128];\n            int numHigh = 0, numLow = 0;\n            int totalHigh = 0, totalLow = 0;\n            for (int i = 0; i < N; i++) {\n                int e = savedC[i] - Tg[i];\n                if (e > 0) {\n                    highNodes[numHigh] = i;\n                    highWeights[numHigh] = e;\n                    totalHigh += e;\n                    numHigh++;\n                } else if (e < 0) {\n                    lowNodes[numLow] = i;\n                    lowWeights[numLow] = -e;\n                    totalLow += -e;\n                    numLow++;\n                }\n            }\n            if (numHigh > 0 && numLow > 0) {\n                int rH = rng() % totalHigh;\n                int y = highNodes[0];\n                for (int k = 0; k < numHigh; k++) {\n                    rH -= highWeights[k];\n                    if (rH < 0) { y = highNodes[k]; break; }\n                }\n                int rL = rng() % totalLow;\n                int w = lowNodes[0];\n                for (int k = 0; k < numLow; k++) {\n                    rL -= lowWeights[k];\n                    if (rL < 0) { w = lowNodes[k]; break; }\n                }\n                \n                int cands[256], nc = 0;\n                for (int j = 0; j < 2*N; j++) if (ab[j] == y) cands[nc++] = j;\n                if (nc > 0) {\n                    idx1 = cands[rng() % nc];\n                    old1 = ab[idx1];\n                    if (old1 != w) {\n                        ab[idx1] = w;\n                        valid = true;\n                    }\n                }\n            }\n        }\n        \n        if (!valid && mtype < 9) {\n            idx1 = rng() % (2*N);\n            int newv = rng() % N;\n            old1 = ab[idx1];\n            if (old1 != newv) {\n                ab[idx1] = newv;\n                valid = true;\n            }\n        }\n        \n        if (!valid) {\n            int i = rng() % N;\n            if (ab[2*i] != ab[2*i+1]) {\n                idx1 = 2*i; idx2 = 2*i+1;\n                old1 = ab[idx1]; old2 = ab[idx2];\n                ab[idx1] = old2; ab[idx2] = old1;\n                valid = true;\n            }\n        }\n        \n        if (!valid) continue;\n        \n        long long ne = simError();\n        if (ne <= curE) {\n            curE = ne;\n            memcpy(savedC, curC, sizeof(curC));\n            if (ne < bestE) {\n                bestE = ne;\n                memcpy(bestAB, ab, sizeof(ab));\n            }\n            stuck = 0;\n        } else {\n            ab[idx1] = old1;\n            if (idx2 >= 0) ab[idx2] = old2;\n            stuck++;\n        }\n        \n        if (stuck > 200) {\n            memcpy(ab, bestAB, sizeof(ab));\n            int numPerturb = 2 + (rng() % 3);\n            for (int k = 0; k < numPerturb; k++) {\n                int j = rng() % (2*N);\n                ab[j] = rng() % N;\n            }\n            curE = simError();\n            memcpy(savedC, curC, sizeof(curC));\n            stuck = 0;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << bestAB[2*i] << \" \" << bestAB[2*i+1] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace std::chrono;\n\nint N, M, Q, L, W;\nvector<int> Gs;\nvector<int> lx, rx, ly, ry;\nvector<double> cx, cy;\nint queries_used = 0;\nsteady_clock::time_point start_time;\n\ndouble elapsed() {\n    return duration<double>(steady_clock::now() - start_time).count();\n}\n\nvector<pair<int,int>> doQuery(vector<int> c) {\n    queries_used++;\n    cout << \"? \" << c.size();\n    for (int v : c) cout << \" \" << v;\n    cout << \"\\n\";\n    cout.flush();\n    vector<pair<int,int>> res(c.size()-1);\n    for (auto& p : res) cin >> p.first >> p.second;\n    return res;\n}\n\ndouble estDist(int i, int j) {\n    double dx = cx[i]-cx[j], dy = cy[i]-cy[j];\n    return sqrt(dx*dx+dy*dy);\n}\n\ndouble groupCost(vector<int>& grp) {\n    int g = grp.size();\n    if (g <= 1) return 0;\n    vector<tuple<double,int,int>> edges;\n    edges.reserve((size_t)g*(g-1)/2);\n    for (int i = 0; i < g; i++) for (int j = i+1; j < g; j++) {\n        edges.push_back({estDist(grp[i], grp[j]), i, j});\n    }\n    sort(edges.begin(), edges.end());\n    vector<int> par(g); iota(par.begin(), par.end(), 0);\n    function<int(int)> find = [&](int x){ return par[x]==x?x:par[x]=find(par[x]); };\n    double total = 0;\n    int cnt = 0;\n    for (auto& [d, i, j] : edges) {\n        int ri = find(i), rj = find(j);\n        if (ri != rj) { par[ri] = rj; total += d; cnt++; if (cnt == g-1) break; }\n    }\n    return total;\n}\n\nvector<pair<int,int>> buildMST(int g, vector<int>& grp, set<pair<int,int>>& edgeSet) {\n    vector<tuple<double,int,int>> edges;\n    for (auto& p : edgeSet) edges.push_back({estDist(p.first, p.second), p.first, p.second});\n    sort(edges.begin(), edges.end());\n    \n    unordered_map<int,int> idx;\n    idx.reserve(g*2);\n    for (int i = 0; i < g; i++) idx[grp[i]] = i;\n    vector<int> par(g); iota(par.begin(), par.end(), 0);\n    function<int(int)> find = [&](int x){ return par[x]==x?x:par[x]=find(par[x]); };\n    \n    vector<pair<int,int>> mst;\n    for (auto& [d,u,v] : edges) {\n        int a = idx[u], b = idx[v];\n        int ra = find(a), rb = find(b);\n        if (ra != rb) {\n            par[ra] = rb;\n            mst.push_back({u,v});\n        }\n    }\n    if ((int)mst.size() < g - 1) {\n        vector<tuple<double,int,int>> allPairs;\n        for (int i = 0; i < g; i++) for (int j = i+1; j < g; j++) {\n            allPairs.push_back({estDist(grp[i], grp[j]), i, j});\n        }\n        sort(allPairs.begin(), allPairs.end());\n        for (auto& [d,a,b] : allPairs) {\n            int ra = find(a), rb = find(b);\n            if (ra != rb) {\n                par[ra] = rb;\n                mst.push_back({grp[a], grp[b]});\n            }\n        }\n    }\n    return mst;\n}\n\nint main(){\n    start_time = steady_clock::now();\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> Q >> L >> W;\n    Gs.resize(M);\n    for (auto& g : Gs) cin >> g;\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i]+rx[i])/2.0;\n        cy[i] = (ly[i]+ry[i])/2.0;\n    }\n    \n    vector<int> assigned(N, -1);\n    vector<vector<int>> groups(M);\n    \n    vector<int> gorder(M);\n    iota(gorder.begin(), gorder.end(), 0);\n    sort(gorder.begin(), gorder.end(), [&](int a, int b){ return Gs[a] > Gs[b]; });\n    \n    for (int gi : gorder) {\n        int sz = Gs[gi];\n        int seed = -1;\n        double bestv = 1e18;\n        for (int i = 0; i < N; i++) {\n            if (assigned[i] != -1) continue;\n            double v = cx[i] + cy[i]*0.0001;\n            if (v < bestv) { bestv = v; seed = i; }\n        }\n        vector<int>& grp = groups[gi];\n        grp.push_back(seed);\n        assigned[seed] = gi;\n        \n        vector<double> minD(N, 1e18);\n        for (int i = 0; i < N; i++) if (assigned[i] == -1) minD[i] = estDist(seed, i);\n        \n        while ((int)grp.size() < sz) {\n            int best = -1; double bd = 1e18;\n            for (int i = 0; i < N; i++) {\n                if (assigned[i] != -1) continue;\n                if (minD[i] < bd) { bd = minD[i]; best = i; }\n            }\n            grp.push_back(best);\n            assigned[best] = gi;\n            for (int i = 0; i < N; i++) {\n                if (assigned[i] == -1) {\n                    double d = estDist(best, i);\n                    if (d < minD[i]) minD[i] = d;\n                }\n            }\n        }\n    }\n    \n    // Grouping swap optimization\n    {\n        int K = min(20, N-1);\n        vector<vector<int>> knn(N);\n        for (int i = 0; i < N; i++) {\n            vector<pair<double,int>> dists;\n            dists.reserve(N-1);\n            for (int j = 0; j < N; j++) if (j != i) dists.push_back({estDist(i,j), j});\n            partial_sort(dists.begin(), dists.begin()+K, dists.end());\n            for (int k = 0; k < K; k++) knn[i].push_back(dists[k].second);\n        }\n        \n        int swapThresh = 50;\n        vector<double> gc(M, 0);\n        for (int gi = 0; gi < M; gi++) {\n            if ((int)groups[gi].size() <= swapThresh) gc[gi] = groupCost(groups[gi]);\n        }\n        \n        for (int iter = 0; iter < 8; iter++) {\n            if (elapsed() > 0.5) break;\n            bool improved = false;\n            for (int c = 0; c < N; c++) {\n                int gA = assigned[c];\n                if ((int)groups[gA].size() > swapThresh) continue;\n                for (int d : knn[c]) {\n                    int gB = assigned[d];\n                    if (gA == gB) continue;\n                    if ((int)groups[gB].size() > swapThresh) continue;\n                    \n                    auto& A = groups[gA]; auto& B = groups[gB];\n                    auto itA = find(A.begin(), A.end(), c);\n                    auto itB = find(B.begin(), B.end(), d);\n                    if (itA == A.end() || itB == B.end()) continue;\n                    *itA = d; *itB = c;\n                    double newA = groupCost(A), newB = groupCost(B);\n                    if (newA + newB < gc[gA] + gc[gB] - 0.001) {\n                        assigned[c] = gB; assigned[d] = gA;\n                        gc[gA] = newA; gc[gB] = newB;\n                        improved = true;\n                    } else {\n                        *itA = c; *itB = d;\n                    }\n                }\n            }\n            if (!improved) break;\n        }\n    }\n    \n    vector<set<pair<int,int>>> edgeSets(M);\n    auto addEdgeSet = [](set<pair<int,int>>& es, int u, int v) {\n        if (u > v) swap(u,v);\n        es.insert({u,v});\n    };\n    \n    // Phase 1: chain with 2-opt improved ordering\n    for (int gi = 0; gi < M; gi++) {\n        int g = Gs[gi];\n        vector<int>& grp = groups[gi];\n        if (g <= 2) continue;\n        \n        vector<int> order;\n        vector<bool> used(g, false);\n        int start = 0;\n        double bv = 1e18;\n        for (int i = 0; i < g; i++) {\n            double v = cx[grp[i]] + cy[grp[i]]*0.0001;\n            if (v < bv) { bv = v; start = i; }\n        }\n        order.push_back(start); used[start] = true;\n        while ((int)order.size() < g) {\n            int last = order.back();\n            int best = -1; double bd = 1e18;\n            for (int i = 0; i < g; i++) {\n                if (used[i]) continue;\n                double d = estDist(grp[last], grp[i]);\n                if (d < bd) { bd = d; best = i; }\n            }\n            order.push_back(best); used[best] = true;\n        }\n        \n        // 2-opt improvement\n        for (int iter = 0; iter < 3; iter++) {\n            bool imp = false;\n            for (int i = 0; i+1 < g; i++) {\n                for (int j = i+2; j < g; j++) {\n                    int a = order[i], b = order[i+1], cc = order[j];\n                    double oldC = estDist(grp[a], grp[b]);\n                    double newC = estDist(grp[a], grp[cc]);\n                    if (j+1 < g) {\n                        int dd = order[j+1];\n                        oldC += estDist(grp[cc], grp[dd]);\n                        newC += estDist(grp[b], grp[dd]);\n                    }\n                    if (newC < oldC - 1e-9) {\n                        reverse(order.begin()+i+1, order.begin()+j+1);\n                        imp = true;\n                    }\n                }\n            }\n            if (!imp) break;\n        }\n        \n        int chunk_sz = L;\n        int step = max(1, L - 1);\n        for (int st = 0; st < g; st += step) {\n            int en = min(st + chunk_sz, g);\n            if (en - st < 2) break;\n            if (queries_used >= Q) break;\n            vector<int> q;\n            for (int i = st; i < en; i++) q.push_back(grp[order[i]]);\n            auto es = doQuery(q);\n            for (auto& [a,b] : es) addEdgeSet(edgeSets[gi], a, b);\n            if (en == g) break;\n        }\n    }\n    \n    // Phase 2 with component-aware candidate selection\n    {\n        vector<vector<pair<int,int>>> currentMST(M);\n        vector<bool> mstDirty(M, true);\n        vector<set<pair<int,int>>> triedEdges(M);\n        int resets = 0;\n        \n        while (queries_used < Q) {\n            int bestGi = -1;\n            double bestLen = -1;\n            pair<int,int> bestEdge = {-1,-1};\n            \n            for (int gi = 0; gi < M; gi++) {\n                if (Gs[gi] < 3) continue;\n                if (mstDirty[gi]) {\n                    currentMST[gi] = buildMST(Gs[gi], groups[gi], edgeSets[gi]);\n                    mstDirty[gi] = false;\n                }\n                for (auto& [u,v] : currentMST[gi]) {\n                    int a = min(u,v), b = max(u,v);\n                    if (triedEdges[gi].count({a,b})) continue;\n                    double d = estDist(a,b);\n                    if (d > bestLen) {\n                        bestLen = d;\n                        bestGi = gi;\n                        bestEdge = {a,b};\n                    }\n                }\n            }\n            \n            if (bestGi == -1) {\n                if (resets >= 3) break;\n                resets++;\n                for (int gi = 0; gi < M; gi++) triedEdges[gi].clear();\n                continue;\n            }\n            \n            triedEdges[bestGi].insert(bestEdge);\n            \n            int eu = bestEdge.first, ev = bestEdge.second;\n            vector<int>& grp = groups[bestGi];\n            \n            // Find components by removing (eu,ev) from currentMST\n            unordered_map<int, vector<int>> adj;\n            for (auto& [u,v] : currentMST[bestGi]) {\n                if ((u == eu && v == ev) || (u == ev && v == eu)) continue;\n                adj[u].push_back(v);\n                adj[v].push_back(u);\n            }\n            set<int> compU;\n            {\n                queue<int> qq; qq.push(eu); compU.insert(eu);\n                while (!qq.empty()) {\n                    int x = qq.front(); qq.pop();\n                    for (int y : adj[x]) if (!compU.count(y)) { compU.insert(y); qq.push(y); }\n                }\n            }\n            \n            double mx = (cx[eu]+cx[ev])/2.0, my = (cy[eu]+cy[ev])/2.0;\n            vector<pair<double,int>> candU, candV;\n            for (int c : grp) {\n                if (c == eu || c == ev) continue;\n                double dx = cx[c]-mx, dy = cy[c]-my;\n                double d = sqrt(dx*dx+dy*dy);\n                if (compU.count(c)) candU.push_back({d, c});\n                else candV.push_back({d, c});\n            }\n            sort(candU.begin(), candU.end());\n            sort(candV.begin(), candV.end());\n            \n            int total = L - 2;\n            int tu = total / 2;\n            int tv = total - tu;\n            if ((int)candU.size() < tu) { tu = candU.size(); tv = min((int)candV.size(), total - tu); }\n            if ((int)candV.size() < tv) { tv = candV.size(); tu = min((int)candU.size(), total - tv); }\n            \n            vector<int> q = {eu, ev};\n            for (int i = 0; i < tu; i++) q.push_back(candU[i].second);\n            for (int i = 0; i < tv; i++) q.push_back(candV[i].second);\n            if ((int)q.size() < 2) continue;\n            \n            auto es = doQuery(q);\n            bool newEdge = false;\n            for (auto& [a,b] : es) {\n                int x = min(a,b), y = max(a,b);\n                if (!edgeSets[bestGi].count({x,y})) newEdge = true;\n                addEdgeSet(edgeSets[bestGi], a, b);\n            }\n            if (newEdge) mstDirty[bestGi] = true;\n        }\n    }\n    \n    vector<vector<pair<int,int>>> allEdges(M);\n    \n    for (int gi = 0; gi < M; gi++) {\n        int g = Gs[gi];\n        vector<int>& grp = groups[gi];\n        if (g == 1) continue;\n        if (g == 2) {\n            allEdges[gi].push_back({grp[0], grp[1]});\n            continue;\n        }\n        allEdges[gi] = buildMST(g, grp, edgeSets[gi]);\n    }\n    \n    cout << \"!\\n\";\n    for (int gi = 0; gi < M; gi++) {\n        for (int i = 0; i < (int)groups[gi].size(); i++) {\n            cout << groups[gi][i];\n            if (i+1 < (int)groups[gi].size()) cout << \" \";\n        }\n        cout << \"\\n\";\n        for (auto& p : allEdges[gi]) cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint di[4]={-1,1,0,0}, dj[4]={0,0,-1,1};\nchar dch[4]={'U','D','L','R'};\nvector<vector<bool>> blk;\n\npair<int,int> slideEnd(int i,int j,int d){\n    while(true){\n        int ni=i+di[d],nj=j+dj[d];\n        if(ni<0||ni>=N||nj<0||nj>=N||blk[ni][nj])break;\n        i=ni;j=nj;\n    }\n    return {i,j};\n}\n\nint main(){\n    cin>>N>>M;\n    vector<pair<int,int>> pts(M);\n    for(auto&p:pts)cin>>p.first>>p.second;\n    blk.assign(N,vector<bool>(N,false));\n    vector<string> out;\n    int ci=pts[0].first, cj=pts[0].second;\n    \n    for(int t=1;t<M;t++){\n        int ti=pts[t].first, tj=pts[t].second;\n        vector<vector<int>> dist(N,vector<int>(N,INT_MAX));\n        vector<vector<tuple<int,int,string>>> par(N,vector<tuple<int,int,string>>(N));\n        dist[ci][cj]=0;\n        queue<pair<int,int>> q;\n        q.push({ci,cj});\n        while(!q.empty()){\n            auto [i,j]=q.front();q.pop();\n            int c=dist[i][j];\n            for(int d=0;d<4;d++){\n                int ni=i+di[d],nj=j+dj[d];\n                if(ni>=0&&ni<N&&nj>=0&&nj<N&&!blk[ni][nj]){\n                    if(c+1<dist[ni][nj]){\n                        dist[ni][nj]=c+1;\n                        par[ni][nj]={i,j,string(\"M\")+dch[d]};\n                        q.push({ni,nj});\n                    }\n                }\n                auto [si,sj]=slideEnd(i,j,d);\n                if((si!=i||sj!=j)&&c+1<dist[si][sj]){\n                    dist[si][sj]=c+1;\n                    par[si][sj]={i,j,string(\"S\")+dch[d]};\n                    q.push({si,sj});\n                }\n            }\n        }\n        if(dist[ti][tj]==INT_MAX)break;\n        vector<string> acts;\n        int ii=ti,jj=tj;\n        while(ii!=ci||jj!=cj){\n            auto[pi,pj,a]=par[ii][jj];\n            acts.push_back(a);\n            ii=pi;jj=pj;\n        }\n        reverse(acts.begin(),acts.end());\n        for(auto&a:acts)out.push_back(a);\n        ci=ti;cj=tj;\n    }\n    for(auto&s:out)cout<<s[0]<<\" \"<<s[1]<<\"\\n\";\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> X, Y, R;\nstruct Rect { int a, b, c, d; };\nconst int W = 10000;\n\ninline double score_one_of_s(int i, const Rect& r) {\n    if (X[i] < r.a || X[i] >= r.c || Y[i] < r.b || Y[i] >= r.d) return 0;\n    long long s = (long long)(r.c - r.a) * (r.d - r.b);\n    double mn = min((long long)R[i], s);\n    double mx = max((long long)R[i], s);\n    double t = 1.0 - mn/mx;\n    return 1.0 - t*t;\n}\n\nstruct State {\n    vector<Rect> rects;\n    vector<double> sc;\n    double total;\n};\n\nchrono::steady_clock::time_point g_start;\ninline double g_elapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now() - g_start).count();\n}\n\nvoid run_sa(State& st, mt19937& rng, double start_time, double end_time,\n            double T_start = 0.005, double T_end = 0.00005) {\n    auto randd = [&]() { return (rng() & 0xffffff) / (double)0x1000000; };\n    \n    double time_budget = end_time - start_time;\n    \n    auto& rects = st.rects;\n    auto& sc = st.sc;\n    \n    long long iters = 0;\n    double T = T_start;\n    double e = start_time;\n    \n    double best_total = st.total;\n    vector<Rect> best_rects = rects;\n    vector<double> best_sc = sc;\n    \n    while (true) {\n        if ((iters & 2047) == 0) {\n            e = g_elapsed();\n            if (e > end_time) break;\n            double progress = (e - start_time) / time_budget;\n            T = T_start * pow(T_end / T_start, progress);\n        }\n        iters++;\n        \n        int i = rng() % n;\n        Rect& r = rects[i];\n        \n        int moveType = rng() % 100;\n        Rect saved = r;\n        \n        if (moveType < 10) {\n            int dir = rng() % 4;\n            int amt = 1 + rng() % 30;\n            \n            if (dir == 0) { r.a -= amt; r.c -= amt; }\n            else if (dir == 1) { r.a += amt; r.c += amt; }\n            else if (dir == 2) { r.b -= amt; r.d -= amt; }\n            else { r.b += amt; r.d += amt; }\n            \n            if (r.a < 0 || r.b < 0 || r.c > W || r.d > W) { r = saved; continue; }\n            if (X[i] < r.a || X[i] >= r.c || Y[i] < r.b || Y[i] >= r.d) { r = saved; continue; }\n            \n            bool bad = false;\n            for (int j = 0; j < n; j++) {\n                if (j == i) continue;\n                const Rect& rj = rects[j];\n                if (r.c <= rj.a || rj.c <= r.a || r.d <= rj.b || rj.d <= r.b) continue;\n                bad = true; break;\n            }\n            if (bad) { r = saved; continue; }\n            continue;\n        }\n        \n        double old_sc = sc[i];\n        long long curS = (long long)(r.c - r.a) * (r.d - r.b);\n        int move = rng() % 8;\n        bool expand = move < 4;\n        \n        int amt;\n        long long diff = expand ? max(0LL, (long long)R[i] - curS) : max(0LL, curS - (long long)R[i]);\n        \n        int rn = rng() % 100;\n        if (rn < 40 && diff > 0) {\n            int side;\n            if (move == 0 || move == 1 || move == 4 || move == 5) side = r.d - r.b;\n            else side = r.c - r.a;\n            if (side == 0) side = 1;\n            amt = max(1, (int)(diff / side));\n            amt = max(1, amt + (int)(rng() % 5) - 2);\n        } else if (rn < 80) {\n            amt = 1 + rng() % 20;\n        } else {\n            amt = 1 + rng() % 200;\n        }\n        \n        if (move == 0) { r.a -= amt; if (r.a < 0) r.a = 0; }\n        else if (move == 1) { r.c += amt; if (r.c > W) r.c = W; }\n        else if (move == 2) { r.b -= amt; if (r.b < 0) r.b = 0; }\n        else if (move == 3) { r.d += amt; if (r.d > W) r.d = W; }\n        else if (move == 4) { r.a += amt; if (r.a > X[i]) r.a = X[i]; }\n        else if (move == 5) { r.c -= amt; if (r.c < X[i]+1) r.c = X[i]+1; }\n        else if (move == 6) { r.b += amt; if (r.b > Y[i]) r.b = Y[i]; }\n        else { r.d -= amt; if (r.d < Y[i]+1) r.d = Y[i]+1; }\n        \n        if (saved.a == r.a && saved.b == r.b && saved.c == r.c && saved.d == r.d) continue;\n        \n        if (expand) {\n            bool bad = false;\n            for (int j = 0; j < n; j++) {\n                if (j == i) continue;\n                const Rect& rj = rects[j];\n                if (r.c <= rj.a || rj.c <= r.a || r.d <= rj.b || rj.d <= r.b) continue;\n                bad = true; break;\n            }\n            if (bad) { r = saved; continue; }\n        }\n        \n        double new_sc = score_one_of_s(i, r);\n        double delta = new_sc - old_sc;\n        \n        bool accept = false;\n        if (delta >= 0) accept = true;\n        else {\n            double p = exp(delta / T);\n            if (randd() < p) accept = true;\n        }\n        \n        if (!accept) { r = saved; continue; }\n        sc[i] = new_sc;\n        st.total += delta;\n        if (st.total > best_total) {\n            best_total = st.total;\n            best_rects = rects;\n            best_sc = sc;\n        }\n    }\n    \n    st.rects = best_rects;\n    st.sc = best_sc;\n    st.total = best_total;\n}\n\nvoid run_hc(State& st, mt19937& rng, double end_time) {\n    auto& rects = st.rects;\n    auto& sc = st.sc;\n    \n    while (g_elapsed() < end_time) {\n        int i = rng() % n;\n        Rect& r = rects[i];\n        \n        int moveType = rng() % 100;\n        Rect saved = r;\n        \n        if (moveType < 5) {\n            int dir = rng() % 4;\n            int amt = 1 + rng() % 20;\n            if (dir == 0) { r.a -= amt; r.c -= amt; }\n            else if (dir == 1) { r.a += amt; r.c += amt; }\n            else if (dir == 2) { r.b -= amt; r.d -= amt; }\n            else { r.b += amt; r.d += amt; }\n            \n            if (r.a < 0 || r.b < 0 || r.c > W || r.d > W ||\n                X[i] < r.a || X[i] >= r.c || Y[i] < r.b || Y[i] >= r.d) {\n                r = saved; continue;\n            }\n            bool bad = false;\n            for (int j = 0; j < n; j++) {\n                if (j == i) continue;\n                const Rect& rj = rects[j];\n                if (r.c <= rj.a || rj.c <= r.a || r.d <= rj.b || rj.d <= r.b) continue;\n                bad = true; break;\n            }\n            if (bad) { r = saved; continue; }\n            continue;\n        }\n        \n        double old_sc = sc[i];\n        long long curS = (long long)(r.c - r.a) * (r.d - r.b);\n        int move = rng() % 8;\n        bool expand = move < 4;\n        int amt;\n        long long diff = expand ? max(0LL, (long long)R[i] - curS) : max(0LL, curS - (long long)R[i]);\n        int rn = rng() % 100;\n        if (rn < 50 && diff > 0) {\n            int side;\n            if (move == 0 || move == 1 || move == 4 || move == 5) side = r.d - r.b;\n            else side = r.c - r.a;\n            if (side == 0) side = 1;\n            amt = max(1, (int)(diff / side));\n        } else {\n            amt = 1 + rng() % 30;\n        }\n        \n        if (move == 0) { r.a -= amt; if (r.a < 0) r.a = 0; }\n        else if (move == 1) { r.c += amt; if (r.c > W) r.c = W; }\n        else if (move == 2) { r.b -= amt; if (r.b < 0) r.b = 0; }\n        else if (move == 3) { r.d += amt; if (r.d > W) r.d = W; }\n        else if (move == 4) { r.a += amt; if (r.a > X[i]) r.a = X[i]; }\n        else if (move == 5) { r.c -= amt; if (r.c < X[i]+1) r.c = X[i]+1; }\n        else if (move == 6) { r.b += amt; if (r.b > Y[i]) r.b = Y[i]; }\n        else { r.d -= amt; if (r.d < Y[i]+1) r.d = Y[i]+1; }\n        \n        if (saved.a == r.a && saved.b == r.b && saved.c == r.c && saved.d == r.d) continue;\n        \n        if (expand) {\n            bool bad = false;\n            for (int j = 0; j < n; j++) {\n                if (j == i) continue;\n                const Rect& rj = rects[j];\n                if (r.c <= rj.a || rj.c <= r.a || r.d <= rj.b || rj.d <= r.b) continue;\n                bad = true; break;\n            }\n            if (bad) { r = saved; continue; }\n        }\n        \n        double new_sc = score_one_of_s(i, r);\n        if (new_sc < old_sc - 1e-12) { r = saved; }\n        else { \n            sc[i] = new_sc; \n            st.total += (new_sc - old_sc);\n        }\n    }\n}\n\nint main() {\n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    for (int i = 0; i < n; i++) cin >> X[i] >> Y[i] >> R[i];\n    \n    g_start = chrono::steady_clock::now();\n    \n    // 3 SA \u00d7 1.2s + reheat SA on best (0.7s) + HC 0.4s\n    State s1, s2, s3;\n    auto init = [&](State& st) {\n        st.rects.resize(n); st.sc.resize(n); st.total = 0;\n        for (int i = 0; i < n; i++) {\n            st.rects[i] = {X[i], Y[i], X[i]+1, Y[i]+1};\n            st.sc[i] = score_one_of_s(i, st.rects[i]);\n            st.total += st.sc[i];\n        }\n    };\n    init(s1); init(s2); init(s3);\n    \n    mt19937 rng1(42), rng2(1729), rng3(9999);\n    \n    run_sa(s1, rng1, 0.0, 1.2);\n    run_sa(s2, rng2, 1.2, 2.4);\n    run_sa(s3, rng3, 2.4, 3.6);\n    \n    State* best = &s1;\n    if (s2.total > best->total) best = &s2;\n    if (s3.total > best->total) best = &s3;\n    \n    // Reheat SA: moderate T start, cooling to very low\n    run_sa(*best, rng1, 3.6, 4.5, 0.001, 0.00002);\n    \n    run_hc(*best, rng1, 4.9);\n    \n    for (int i = 0; i < n; i++) {\n        cout << best->rects[i].a << \" \" << best->rects[i].b << \" \" << best->rects[i].c << \" \" << best->rects[i].d << \"\\n\";\n    }\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nconst int N = 50;\n\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dch[] = {'U', 'D', 'L', 'R'};\n\npair<int,int> partner[50][50];\n\nuint64_t rowUsed[50];\n\ninline bool isUsed(int r, int c) {\n    return (rowUsed[r] >> c) & 1ULL;\n}\n\ninline void markCell(int r, int c) {\n    rowUsed[r] |= (1ULL << c);\n    int pr = partner[r][c].first, pc = partner[r][c].second;\n    rowUsed[pr] |= (1ULL << pc);\n}\n\ninline void unmarkCell(int r, int c) {\n    rowUsed[r] &= ~(1ULL << c);\n    int pr = partner[r][c].first, pc = partner[r][c].second;\n    rowUsed[pr] &= ~(1ULL << pc);\n}\n\ndouble getTime() {\n    return (double)clock() / CLOCKS_PER_SEC;\n}\n\nmt19937 rng(42);\n\nvector<pair<int,int>> path;\nvector<int> dirs;\nint totalScore;\nint M;\n\nint targetR, targetC;\nint bestSegScore;\nvector<int> bestSegDirs;\nvector<int> curSegDirs;\nint curSegScore;\ndouble dfsDeadline;\nbool timeUp;\nint dfsCount;\nint maxDepth;\n\nvoid dfsSeg(int r, int c, int depth) {\n    dfsCount++;\n    if ((dfsCount & 4095) == 0) {\n        if (getTime() > dfsDeadline) { timeUp = true; return; }\n    }\n    if (timeUp) return;\n    \n    if (r == targetR && c == targetC) {\n        if (curSegScore > bestSegScore) {\n            bestSegScore = curSegScore;\n            bestSegDirs = curSegDirs;\n        }\n        return;\n    }\n    \n    if (depth >= maxDepth) return;\n    int md = abs(r - targetR) + abs(c - targetC);\n    if (depth + md > maxDepth) return;\n    \n    int order[4] = {0,1,2,3};\n    for (int k = 3; k > 0; k--) {\n        int j = rng() % (k+1);\n        int tmp = order[k]; order[k] = order[j]; order[j] = tmp;\n    }\n    for (int k = 0; k < 4; k++) {\n        int d = order[k];\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        if (isUsed(nr, nc)) continue;\n        markCell(nr, nc);\n        curSegScore += p[nr][nc];\n        curSegDirs.push_back(d);\n        dfsSeg(nr, nc, depth+1);\n        curSegDirs.pop_back();\n        curSegScore -= p[nr][nc];\n        unmarkCell(nr, nc);\n        if (timeUp) return;\n    }\n}\n\nint bestTailScore;\nvector<int> bestTailDirs;\nvector<int> curTailDirs;\nint curTailScore;\n\nvoid dfsTail(int r, int c) {\n    dfsCount++;\n    if ((dfsCount & 4095) == 0) {\n        if (getTime() > dfsDeadline) { timeUp = true; return; }\n    }\n    if (timeUp) return;\n    \n    if (curTailScore > bestTailScore) {\n        bestTailScore = curTailScore;\n        bestTailDirs = curTailDirs;\n    }\n    \n    int order[4] = {0,1,2,3};\n    for (int k = 3; k > 0; k--) {\n        int j = rng() % (k+1);\n        int tmp = order[k]; order[k] = order[j]; order[j] = tmp;\n    }\n    for (int k = 0; k < 4; k++) {\n        int d = order[k];\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n        if (isUsed(nr, nc)) continue;\n        markCell(nr, nc);\n        curTailScore += p[nr][nc];\n        curTailDirs.push_back(d);\n        dfsTail(nr, nc);\n        curTailDirs.pop_back();\n        curTailScore -= p[nr][nc];\n        unmarkCell(nr, nc);\n        if (timeUp) return;\n    }\n}\n\nvoid rebuildUsed() {\n    for (int i = 0; i < N; i++) rowUsed[i] = 0;\n    for (auto& pp : path) markCell(pp.first, pp.second);\n}\n\nbool validatePath() {\n    if (path.empty()) return false;\n    if (path[0].first != si || path[0].second != sj) return false;\n    if (path.size() != dirs.size() + 1) return false;\n    vector<bool> seen(M, false);\n    for (int k = 0; k < (int)path.size(); k++) {\n        int r = path[k].first, c = path[k].second;\n        if (r < 0 || r >= N || c < 0 || c >= N) return false;\n        if (seen[t[r][c]]) return false;\n        seen[t[r][c]] = true;\n        if (k > 0) {\n            int d = dirs[k-1];\n            int er = path[k-1].first + dr[d];\n            int ec = path[k-1].second + dc[d];\n            if (er != r || ec != c) return false;\n        }\n    }\n    return true;\n}\n\nvoid initialPath() {\n    path.clear();\n    dirs.clear();\n    for (int i = 0; i < N; i++) rowUsed[i] = 0;\n    path.push_back({si, sj});\n    markCell(si, sj);\n    totalScore = p[si][sj];\n    \n    int r = si, c = sj;\n    while (true) {\n        int cand[4], ncand = 0;\n        for (int d = 0; d < 4; d++) {\n            int nr = r+dr[d], nc = c+dc[d];\n            if (nr<0||nr>=N||nc<0||nc>=N) continue;\n            if (isUsed(nr, nc)) continue;\n            cand[ncand++] = d;\n        }\n        if (ncand == 0) break;\n        int d = cand[rng()%ncand];\n        int nr = r+dr[d], nc = c+dc[d];\n        markCell(nr, nc);\n        totalScore += p[nr][nc];\n        path.push_back({nr,nc});\n        dirs.push_back(d);\n        r = nr; c = nc;\n    }\n}\n\nint main() {\n    cin >> si >> sj;\n    M = 0;\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) {\n            cin >> t[i][j];\n            M = max(M, t[i][j]+1);\n        }\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++)\n            cin >> p[i][j];\n    \n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++)\n            partner[i][j] = {i, j};\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dr[d], nj = j + dc[d];\n                if (ni < 0 || ni >= 50 || nj < 0 || nj >= 50) continue;\n                if (t[ni][nj] == t[i][j]) {\n                    partner[i][j] = {ni, nj};\n                    break;\n                }\n            }\n        }\n    }\n    \n    vector<pair<int,int>> bestPath;\n    vector<int> bestDirs;\n    int bestOverallScore = -1;\n    \n    double INIT_TIME = 0.03;\n    double initStart = getTime();\n    while (getTime() - initStart < INIT_TIME) {\n        initialPath();\n        if (totalScore > bestOverallScore) {\n            bestOverallScore = totalScore;\n            bestPath = path;\n            bestDirs = dirs;\n        }\n    }\n    \n    path = bestPath;\n    dirs = bestDirs;\n    totalScore = bestOverallScore;\n    rebuildUsed();\n    \n    vector<pair<int,int>> savedPath = path;\n    vector<int> savedDirs = dirs;\n    int savedScore = totalScore;\n    \n    double TIME_LIMIT = 1.80;\n    double TIME_START = getTime();\n    int iter = 0;\n    \n    uniform_real_distribution<double> uni(0.0, 1.0);\n    \n    while (getTime() < TIME_LIMIT) {\n        iter++;\n        int L = path.size();\n        \n        double elapsed = (getTime() - TIME_START) / (TIME_LIMIT - TIME_START);\n        double T = 8.0 * (1.0 - elapsed);\n        if (T < 0.01) T = 0.01;\n        \n        int mode = rng() % 10;\n        \n        if (mode < 2) {\n            int i = rng() % L;\n            \n            int oldSuffixScore = 0;\n            for (int k = i+1; k < L; k++) oldSuffixScore += p[path[k].first][path[k].second];\n            \n            for (int k = i+1; k < L; k++) {\n                unmarkCell(path[k].first, path[k].second);\n            }\n            markCell(path[i].first, path[i].second);\n            \n            bestTailScore = 0;\n            bestTailDirs.clear();\n            curTailScore = 0;\n            curTailDirs.clear();\n            timeUp = false;\n            dfsCount = 0;\n            \n            double remaining = TIME_LIMIT - getTime();\n            double budget = min(0.015, remaining * 0.015);\n            if (budget < 0.001) budget = 0.001;\n            dfsDeadline = getTime() + budget;\n            \n            dfsTail(path[i].first, path[i].second);\n            \n            int delta = bestTailScore - oldSuffixScore;\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else if (uni(rng) < exp((double)delta / T)) accept = true;\n            \n            if (accept) {\n                path.resize(i+1);\n                dirs.resize(i);\n                int r = path[i].first, c = path[i].second;\n                for (int d : bestTailDirs) {\n                    int nr = r+dr[d], nc = c+dc[d];\n                    path.push_back({nr,nc});\n                    dirs.push_back(d);\n                    markCell(nr, nc);\n                    r = nr; c = nc;\n                }\n                totalScore = totalScore - oldSuffixScore + bestTailScore;\n            } else {\n                for (int k = i+1; k < L; k++) {\n                    markCell(path[k].first, path[k].second);\n                }\n            }\n        } else {\n            int i = rng() % L;\n            int len;\n            int r_mode = rng() % 10;\n            if (r_mode < 5) len = 3 + rng() % 12;\n            else if (r_mode < 8) len = 8 + rng() % 25;\n            else len = 20 + rng() % 60;\n            \n            int j = min(L-1, i + len);\n            if (j - i < 2) continue;\n            \n            int tj = t[path[j].first][path[j].second];\n            if (j+1 < L && t[path[j+1].first][path[j+1].second] == tj) continue;\n            \n            int oldSegScore = 0;\n            for (int k = i+1; k <= j; k++) oldSegScore += p[path[k].first][path[k].second];\n            \n            for (int k = i+1; k <= j; k++) {\n                unmarkCell(path[k].first, path[k].second);\n            }\n            markCell(path[i].first, path[i].second);\n            \n            targetR = path[j].first;\n            targetC = path[j].second;\n            \n            bestSegScore = -1;\n            bestSegDirs.clear();\n            curSegScore = 0;\n            curSegDirs.clear();\n            timeUp = false;\n            dfsCount = 0;\n            int baseLen = j - i;\n            maxDepth = baseLen + min(20, baseLen);\n            \n            double remaining = TIME_LIMIT - getTime();\n            double budget;\n            if (baseLen < 15) budget = 0.003;\n            else if (baseLen < 30) budget = 0.008;\n            else budget = 0.015;\n            budget = min(budget, remaining * 0.01);\n            if (budget < 0.0003) budget = 0.0003;\n            dfsDeadline = getTime() + budget;\n            \n            dfsSeg(path[i].first, path[i].second, 0);\n            \n            int delta = bestSegScore - oldSegScore;\n            bool accept = false;\n            if (bestSegScore >= 0 && !bestSegDirs.empty()) {\n                if (delta >= 0) accept = true;\n                else if (uni(rng) < exp((double)delta / T)) accept = true;\n            }\n            \n            if (accept) {\n                vector<pair<int,int>> newSeg;\n                {\n                    int r = path[i].first, c = path[i].second;\n                    for (int d : bestSegDirs) {\n                        int nr = r+dr[d], nc = c+dc[d];\n                        newSeg.push_back({nr, nc});\n                        r = nr; c = nc;\n                    }\n                }\n                \n                for (auto& pp : newSeg) markCell(pp.first, pp.second);\n                \n                vector<pair<int,int>> newPath;\n                newPath.reserve(path.size() + newSeg.size());\n                vector<int> newDirs;\n                newDirs.reserve(dirs.size() + bestSegDirs.size());\n                for (int k = 0; k <= i; k++) newPath.push_back(path[k]);\n                for (int k = 0; k < i; k++) newDirs.push_back(dirs[k]);\n                for (int d : bestSegDirs) newDirs.push_back(d);\n                for (auto& pp : newSeg) newPath.push_back(pp);\n                for (int k = j+1; k < L; k++) newPath.push_back(path[k]);\n                for (int k = j; k < (int)dirs.size(); k++) newDirs.push_back(dirs[k]);\n                \n                path = std::move(newPath);\n                dirs = std::move(newDirs);\n                totalScore = totalScore - oldSegScore + bestSegScore;\n            } else {\n                for (int k = i+1; k <= j; k++) {\n                    markCell(path[k].first, path[k].second);\n                }\n            }\n        }\n        \n        if (totalScore > bestOverallScore) {\n            bestOverallScore = totalScore;\n            bestPath = path;\n            bestDirs = dirs;\n        }\n        \n        if ((iter & 255) == 0) {\n            if (validatePath()) {\n                savedPath = path;\n                savedDirs = dirs;\n                savedScore = totalScore;\n            } else {\n                path = savedPath;\n                dirs = savedDirs;\n                totalScore = savedScore;\n                rebuildUsed();\n            }\n        }\n    }\n    \n    string out;\n    for (int d : bestDirs) out += dch[d];\n    cout << out << endl;\n    \n    cerr << \"Score: \" << bestOverallScore << \" Iter: \" << iter << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\ndouble h[30][29];\ndouble v[29][30];\n\nstruct Obs {\n    vector<tuple<int,int,int>> edges;\n    double observed;\n};\n\nvector<Obs> history;\n\nvoid gs_update(const Obs& o, double alpha) {\n    double pred = 0;\n    for (auto& [t,i,j] : o.edges) {\n        if (t == 0) pred += h[i][j]; else pred += v[i][j];\n    }\n    int n = (int)o.edges.size();\n    if (n == 0) return;\n    double err = (o.observed - pred) / n;\n    double delta = alpha * err;\n    for (auto& [t,i,j] : o.edges) {\n        if (t == 0) {\n            h[i][j] += delta;\n            if (h[i][j] < 1000) h[i][j] = 1000;\n            if (h[i][j] > 9000) h[i][j] = 9000;\n        } else {\n            v[i][j] += delta;\n            if (v[i][j] < 1000) v[i][j] = 1000;\n            if (v[i][j] > 9000) v[i][j] = 9000;\n        }\n    }\n}\n\nstatic double h_vals[30][32];\nstatic int h_nc[30];\nstatic double v_vals[30][32];\nstatic int v_nc[30];\n\nint get_centers(double* vals, int nc, double gap_thr, double uni_thr, double bi_thr,\n                double* cs, double* thr_out) {\n    if (nc == 0) return 0;\n    if (nc == 1) { cs[0] = vals[0]; thr_out[0] = uni_thr; return 1; }\n    sort(vals, vals + nc);\n    int split = -1;\n    double max_gap = 0;\n    for (int i = 1; i < nc; i++) {\n        double gap = vals[i] - vals[i-1];\n        if (gap > max_gap) { max_gap = gap; split = i; }\n    }\n    if (max_gap > gap_thr && split >= 2 && nc - split >= 2) {\n        double s1=0, s2=0;\n        for (int i = 0; i < split; i++) s1 += vals[i];\n        for (int i = split; i < nc; i++) s2 += vals[i];\n        cs[0] = s1 / split;\n        cs[1] = s2 / (nc - split);\n        thr_out[0] = bi_thr;\n        thr_out[1] = bi_thr;\n        return 2;\n    } else {\n        double s = 0;\n        for (int i = 0; i < nc; i++) s += vals[i];\n        cs[0] = s / nc;\n        thr_out[0] = uni_thr;\n        return 1;\n    }\n}\n\nvoid smooth_update(const Obs& o, double alpha) {\n    double pred = 0;\n    for (auto& [t,i,j] : o.edges) {\n        if (t == 0) pred += h[i][j]; else pred += v[i][j];\n    }\n    if (pred < 1) return;\n    double rd = o.observed / pred - 1.0;\n    if (rd > 0.5) rd = 0.5;\n    if (rd < -0.4) rd = -0.4;\n    \n    for (int i = 0; i < 30; i++) { h_nc[i] = 0; v_nc[i] = 0; }\n    for (auto& [t,ei,ej] : o.edges) {\n        if (t == 0) {\n            if (h_nc[ei] < 32) h_vals[ei][h_nc[ei]++] = h[ei][ej];\n        } else {\n            if (v_nc[ej] < 32) v_vals[ej][v_nc[ej]++] = v[ei][ej];\n        }\n    }\n    \n    const double GAP_THR = 3500.0;\n    const double UNI_THR = 3000.0;\n    const double BI_THR = 2500.0;\n    \n    double factor = 1.0 + alpha * rd;\n    double cs[2], thr_out[2];\n    for (int r = 0; r < 30; r++) {\n        if (h_nc[r] == 0) continue;\n        int ncs = get_centers(h_vals[r], h_nc[r], GAP_THR, UNI_THR, BI_THR, cs, thr_out);\n        for (int j = 0; j < 29; j++) {\n            double val = h[r][j];\n            bool ok = false;\n            for (int k = 0; k < ncs; k++) {\n                if (fabs(val - cs[k]) < thr_out[k]) { ok = true; break; }\n            }\n            if (ok) {\n                h[r][j] *= factor;\n                if (h[r][j] < 1000) h[r][j] = 1000;\n                if (h[r][j] > 9000) h[r][j] = 9000;\n            }\n        }\n    }\n    for (int c = 0; c < 30; c++) {\n        if (v_nc[c] == 0) continue;\n        int ncs = get_centers(v_vals[c], v_nc[c], GAP_THR, UNI_THR, BI_THR, cs, thr_out);\n        for (int i = 0; i < 29; i++) {\n            double val = v[i][c];\n            bool ok = false;\n            for (int k = 0; k < ncs; k++) {\n                if (fabs(val - cs[k]) < thr_out[k]) { ok = true; break; }\n            }\n            if (ok) {\n                v[i][c] *= factor;\n                if (v[i][c] < 1000) v[i][c] = 1000;\n                if (v[i][c] > 9000) v[i][c] = 9000;\n            }\n        }\n    }\n}\n\nint main() {\n    for (int i = 0; i < 30; i++) for (int j = 0; j < 29; j++) h[i][j] = 5000;\n    for (int i = 0; i < 29; i++) for (int j = 0; j < 30; j++) v[i][j] = 5000;\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        if (!(cin >> si >> sj >> ti >> tj)) break;\n        \n        vector<vector<double>> dist(30, vector<double>(30, 1e18));\n        vector<vector<int>> prv(30, vector<int>(30, -1));\n        priority_queue<tuple<double,int,int>, vector<tuple<double,int,int>>, greater<>> pq;\n        dist[si][sj] = 0;\n        pq.push({0.0, si, sj});\n        int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};\n        while (!pq.empty()) {\n            auto [d, r, c] = pq.top(); pq.pop();\n            if (d > dist[r][c]) continue;\n            for (int dir = 0; dir < 4; dir++) {\n                int nr = r+dr[dir], nc = c+dc[dir];\n                if (nr<0||nr>=30||nc<0||nc>=30) continue;\n                double w;\n                if (dir == 0) w = v[nr][c];\n                else if (dir == 1) w = v[r][c];\n                else if (dir == 2) w = h[r][nc];\n                else w = h[r][c];\n                if (dist[nr][nc] > d + w) {\n                    dist[nr][nc] = d + w;\n                    prv[nr][nc] = dir;\n                    pq.push({dist[nr][nc], nr, nc});\n                }\n            }\n        }\n        \n        vector<int> dirs;\n        int r = ti, c = tj;\n        while (!(r == si && c == sj)) {\n            int d = prv[r][c];\n            dirs.push_back(d);\n            r -= dr[d]; c -= dc[d];\n        }\n        reverse(dirs.begin(), dirs.end());\n        \n        string path;\n        char ch[] = {'U','D','L','R'};\n        for (int d : dirs) path += ch[d];\n        cout << path << endl;\n        cout.flush();\n        \n        long long b;\n        cin >> b;\n        \n        vector<tuple<int,int,int>> edges;\n        r = si; c = sj;\n        for (int d : dirs) {\n            int nr = r+dr[d], nc = c+dc[d];\n            if (d == 0) edges.push_back({1, nr, c});\n            else if (d == 1) edges.push_back({1, r, c});\n            else if (d == 2) edges.push_back({0, r, nc});\n            else edges.push_back({0, r, c});\n            r = nr; c = nc;\n        }\n        \n        history.push_back({edges, (double)b});\n        int N = (int)history.size();\n        \n        smooth_update(history.back(), 0.15);\n        \n        for (int rep = 0; rep < 2; rep++) {\n            for (int idx = 0; idx < N; idx++) {\n                gs_update(history[idx], 0.1);\n            }\n        }\n        \n        int sm_n = min(N, 50);\n        for (int rep = 0; rep < 2; rep++) {\n            for (int idx = N - sm_n; idx < N; idx++) {\n                smooth_update(history[idx], 0.03);\n            }\n        }\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\nusing Clock = chrono::steady_clock;\n\nint N = 20;\nint M;\nvector<string> S;\nmt19937 rng(42);\n\nint ovlp(const string& a, const string& b) {\n    int m = min((int)a.size(), (int)b.size());\n    for (int k = m; k >= 1; k--) {\n        if (a.compare(a.size()-k, k, b, 0, k) == 0) return k;\n    }\n    return 0;\n}\n\nstruct AC {\n    struct Node {\n        int ch[9];\n        int fail;\n        vector<int> out;\n        Node() { for (int i = 0; i < 9; i++) ch[i] = -1; fail = 0; }\n    };\n    vector<Node> nd;\n    \n    void init() { nd.clear(); nd.push_back(Node()); }\n    int ci(char c) { return c == '.' ? 8 : c - 'A'; }\n    \n    void add(const string& p, int id) {\n        int cur = 0;\n        for (char c : p) {\n            int x = ci(c);\n            if (nd[cur].ch[x] == -1) { nd[cur].ch[x] = nd.size(); nd.push_back(Node()); }\n            cur = nd[cur].ch[x];\n        }\n        nd[cur].out.push_back(id);\n    }\n    \n    void build() {\n        queue<int> q;\n        nd[0].fail = 0;\n        for (int c = 0; c < 9; c++) {\n            if (nd[0].ch[c] == -1) nd[0].ch[c] = 0;\n            else { nd[nd[0].ch[c]].fail = 0; q.push(nd[0].ch[c]); }\n        }\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int c = 0; c < 9; c++) {\n                int v = nd[u].ch[c];\n                if (v == -1) nd[u].ch[c] = nd[nd[u].fail].ch[c];\n                else {\n                    nd[v].fail = nd[nd[u].fail].ch[c];\n                    for (int p : nd[nd[v].fail].out) nd[v].out.push_back(p);\n                    q.push(v);\n                }\n            }\n        }\n    }\n};\n\nAC ac;\n\nvector<string> makeTracks(const vector<string>& grid) {\n    vector<string> tracks(2*N);\n    for (int r = 0; r < N; r++) tracks[r] = grid[r] + grid[r].substr(0, 11);\n    for (int c = 0; c < N; c++) {\n        string col(N, '.');\n        for (int r = 0; r < N; r++) col[r] = grid[r][c];\n        tracks[N+c] = col + col.substr(0, 11);\n    }\n    return tracks;\n}\n\nint countMatches(const vector<string>& grid, const vector<int>& avail) {\n    auto tracks = makeTracks(grid);\n    int cnt = 0;\n    for (int i : avail) {\n        for (auto& t : tracks) {\n            if (t.find(S[i]) != string::npos) { cnt++; break; }\n        }\n    }\n    return cnt;\n}\n\nint tryPlace(vector<string>& grid, const string& s, int r, int c, int dir, bool doIt) {\n    int L = s.size();\n    int cost = 0;\n    for (int p = 0; p < L; p++) {\n        int rr, cc;\n        if (dir == 0) { rr = r; cc = (c+p) % N; }\n        else { rr = (r+p) % N; cc = c; }\n        if (grid[rr][cc] == '.') cost++;\n        else if (grid[rr][cc] != s[p]) return -1;\n    }\n    if (doIt) {\n        for (int p = 0; p < L; p++) {\n            int rr, cc;\n            if (dir == 0) { rr = r; cc = (c+p) % N; }\n            else { rr = (r+p) % N; cc = c; }\n            grid[rr][cc] = s[p];\n        }\n    }\n    return cost;\n}\n\nvoid updateCovered(vector<string>& grid, const vector<int>& avail, vector<bool>& placed) {\n    auto tracks = makeTracks(grid);\n    for (int i : avail) {\n        if (placed[i]) continue;\n        for (auto& t : tracks) {\n            if (t.find(S[i]) != string::npos) { placed[i] = true; break; }\n        }\n    }\n}\n\nvector<string> greedyBuild(const vector<int>& avail, const vector<bool>& redundant) {\n    vector<bool> used(M, false);\n    for (int i = 0; i < M; i++) if (redundant[i]) used[i] = true;\n    \n    vector<string> grid(N, string(N, '.'));\n    vector<int> order = avail;\n    shuffle(order.begin(), order.end(), rng);\n    \n    for (int r = 0; r < N; r++) {\n        int first = -1, bestLen = -1;\n        for (int i : order) if (!used[i]) {\n            if ((int)S[i].size() > bestLen) { bestLen = S[i].size(); first = i; }\n        }\n        if (first == -1) break;\n        vector<int> topCands;\n        for (int i : order) if (!used[i] && (int)S[i].size() >= bestLen) topCands.push_back(i);\n        if (topCands.empty()) break;\n        first = topCands[rng() % topCands.size()];\n        \n        string row = S[first];\n        used[first] = true;\n        if ((int)row.size() > N) row = row.substr(0, N);\n        \n        while ((int)row.size() < N) {\n            vector<tuple<int,int,int>> cands;\n            for (int i : order) if (!used[i]) {\n                int o = ovlp(row, S[i]);\n                int addLen = (int)S[i].size() - o;\n                if ((int)row.size() + addLen > N) continue;\n                int sc = o * 1000 + (int)S[i].size();\n                cands.push_back({sc, i, o});\n            }\n            if (cands.empty()) break;\n            sort(cands.begin(), cands.end(), greater<>());\n            int topk = min((int)cands.size(), 3);\n            auto [sc, best, o] = cands[rng() % topk];\n            row += S[best].substr(o);\n            used[best] = true;\n        }\n        \n        if ((int)row.size() == N) {\n            string cyc = row + row.substr(0, 11);\n            for (int i : avail) if (!used[i]) {\n                if (cyc.find(S[i]) != string::npos) used[i] = true;\n            }\n        }\n        \n        for (int j = 0; j < (int)row.size() && j < N; j++) grid[r][j] = row[j];\n    }\n    \n    updateCovered(grid, avail, used);\n    \n    vector<int> remaining;\n    for (int i : avail) if (!used[i]) remaining.push_back(i);\n    sort(remaining.begin(), remaining.end(), [](int a, int b){ return S[a].size() > S[b].size(); });\n    \n    for (int i : remaining) {\n        if (used[i]) continue;\n        const string& s = S[i];\n        int bestCost = INT_MAX;\n        int bestR = -1, bestC = -1, bestDir = -1;\n        for (int dir = 0; dir < 2; dir++) {\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    int cost = tryPlace(grid, s, r, c, dir, false);\n                    if (cost >= 0 && cost < bestCost) {\n                        bestCost = cost;\n                        bestR = r; bestC = c; bestDir = dir;\n                    }\n                }\n            }\n        }\n        if (bestR != -1) {\n            tryPlace(grid, s, bestR, bestC, bestDir, true);\n            used[i] = true;\n            updateCovered(grid, avail, used);\n        }\n    }\n    \n    return grid;\n}\n\nClock::time_point startTime;\ndouble timeUsed() { return chrono::duration<double>(Clock::now() - startTime).count(); }\n\nvoid hillClimb(vector<string>& grid, int& cur, const vector<int>& avail, double deadline) {\n    bool improved = true;\n    while (improved && timeUsed() < deadline) {\n        improved = false;\n        \n        for (int r = 0; r < N; r++) {\n            if (timeUsed() > deadline) break;\n            string orig = grid[r];\n            int bestShift = 0, bestSc = cur;\n            for (int sh = 1; sh < N; sh++) {\n                grid[r] = orig.substr(sh) + orig.substr(0, sh);\n                int sc = countMatches(grid, avail);\n                if (sc > bestSc) { bestSc = sc; bestShift = sh; }\n            }\n            grid[r] = orig.substr(bestShift) + orig.substr(0, bestShift);\n            if (bestShift != 0) { cur = bestSc; improved = true; }\n        }\n        \n        for (int c = 0; c < N; c++) {\n            if (timeUsed() > deadline) break;\n            string orig_col(N, '.');\n            for (int r = 0; r < N; r++) orig_col[r] = grid[r][c];\n            int bestShift = 0, bestSc = cur;\n            for (int sh = 1; sh < N; sh++) {\n                string nc = orig_col.substr(sh) + orig_col.substr(0, sh);\n                for (int r = 0; r < N; r++) grid[r][c] = nc[r];\n                int sc = countMatches(grid, avail);\n                if (sc > bestSc) { bestSc = sc; bestShift = sh; }\n            }\n            string nc = orig_col.substr(bestShift) + orig_col.substr(0, bestShift);\n            for (int r = 0; r < N; r++) grid[r][c] = nc[r];\n            if (bestShift != 0) { cur = bestSc; improved = true; }\n        }\n        \n        for (int r1 = 0; r1 < N && timeUsed() < deadline; r1++) {\n            for (int r2 = r1+1; r2 < N; r2++) {\n                swap(grid[r1], grid[r2]);\n                int sc = countMatches(grid, avail);\n                if (sc > cur) { cur = sc; improved = true; }\n                else swap(grid[r1], grid[r2]);\n            }\n        }\n        \n        for (int c1 = 0; c1 < N && timeUsed() < deadline; c1++) {\n            for (int c2 = c1+1; c2 < N; c2++) {\n                for (int r = 0; r < N; r++) swap(grid[r][c1], grid[r][c2]);\n                int sc = countMatches(grid, avail);\n                if (sc > cur) { cur = sc; improved = true; }\n                else for (int r = 0; r < N; r++) swap(grid[r][c1], grid[r][c2]);\n            }\n        }\n    }\n}\n\nbool insertUnmatched(vector<string>& grid, const vector<int>& avail) {\n    auto tracks = makeTracks(grid);\n    vector<bool> matched(M, false);\n    for (int i : avail) {\n        for (auto& t : tracks) {\n            if (t.find(S[i]) != string::npos) { matched[i] = true; break; }\n        }\n    }\n    \n    vector<int> unm;\n    for (int i : avail) if (!matched[i]) unm.push_back(i);\n    sort(unm.begin(), unm.end(), [](int a, int b){ return S[a].size() > S[b].size(); });\n    \n    bool anyPlaced = false;\n    for (int i : unm) {\n        const string& s = S[i];\n        int bestCost = INT_MAX;\n        int bestR = -1, bestC = -1, bestDir = -1;\n        for (int dir = 0; dir < 2; dir++) {\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    int cost = tryPlace(grid, s, r, c, dir, false);\n                    if (cost >= 0 && cost < bestCost) {\n                        bestCost = cost;\n                        bestR = r; bestC = c; bestDir = dir;\n                    }\n                }\n            }\n        }\n        if (bestR != -1) {\n            tryPlace(grid, s, bestR, bestC, bestDir, true);\n            anyPlaced = true;\n        }\n    }\n    return anyPlaced;\n}\n\nusing BS = bitset<1024>;\n\nstruct State {\n    vector<string> grid;\n    BS trackMatch[40];\n    vector<int> matchCount;\n    int totalMatched;\n    \n    BS scratchNew, scratchDiff;\n    \n    void getTrackChars(int t, char* buf) {\n        if (t < N) {\n            for (int i = 0; i < N; i++) buf[i] = grid[t][i];\n        } else {\n            int c = t - N;\n            for (int i = 0; i < N; i++) buf[i] = grid[i][c];\n        }\n        for (int i = 0; i < 11; i++) buf[N+i] = buf[i];\n    }\n    \n    void recomputeTrack(int t) {\n        char buf[32];\n        getTrackChars(t, buf);\n        \n        scratchNew.reset();\n        int cur = 0;\n        for (int i = 0; i < 31; i++) {\n            int x = buf[i] == '.' ? 8 : buf[i] - 'A';\n            cur = ac.nd[cur].ch[x];\n            for (int p : ac.nd[cur].out) scratchNew.set(p);\n        }\n        \n        scratchDiff = trackMatch[t] ^ scratchNew;\n        for (size_t p = scratchDiff._Find_first(); p < scratchDiff.size(); p = scratchDiff._Find_next(p)) {\n            if (scratchNew[p]) {\n                if (matchCount[p] == 0) totalMatched++;\n                matchCount[p]++;\n            } else {\n                matchCount[p]--;\n                if (matchCount[p] == 0) totalMatched--;\n            }\n        }\n        \n        trackMatch[t] = scratchNew;\n    }\n    \n    void init(const vector<string>& g) {\n        grid = g;\n        for (int t = 0; t < 2*N; t++) trackMatch[t].reset();\n        matchCount.assign(M, 0);\n        totalMatched = 0;\n        for (int t = 0; t < 2*N; t++) recomputeTrack(t);\n    }\n};\n\nint main() {\n    cin >> N >> M;\n    S.resize(M);\n    for (auto& s : S) cin >> s;\n    \n    vector<bool> redundant(M, false);\n    vector<int> idxSort(M);\n    iota(idxSort.begin(), idxSort.end(), 0);\n    sort(idxSort.begin(), idxSort.end(), [](int a, int b){ return S[a].size() > S[b].size(); });\n    \n    for (int ii = 0; ii < M; ii++) {\n        int i = idxSort[ii];\n        if (redundant[i]) continue;\n        for (int jj = ii+1; jj < M; jj++) {\n            int j = idxSort[jj];\n            if (redundant[j]) continue;\n            if (S[i].find(S[j]) != string::npos) redundant[j] = true;\n        }\n    }\n    \n    vector<int> avail;\n    for (int i = 0; i < M; i++) if (!redundant[i]) avail.push_back(i);\n    \n    ac.init();\n    for (int i : avail) ac.add(S[i], i);\n    ac.build();\n    \n    startTime = Clock::now();\n    \n    vector<string> bestGrid(N, string(N, '.'));\n    int bestScore = -1;\n    int bestDots = -1;\n    \n    int trial = 0;\n    while (timeUsed() < 0.3) {\n        trial++;\n        vector<string> grid = greedyBuild(avail, redundant);\n        int score = countMatches(grid, avail);\n        int dots = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] == '.') dots++;\n        \n        if (score > bestScore || (score == bestScore && dots > bestDots)) {\n            bestScore = score;\n            bestDots = dots;\n            bestGrid = grid;\n        }\n    }\n    cerr << \"Phase 1 trials: \" << trial << \" best: \" << bestScore << \"/\" << avail.size() << \"\\n\";\n    \n    {\n        vector<string> grid = bestGrid;\n        int cur = bestScore;\n        \n        for (int iter = 0; iter < 3; iter++) {\n            if (timeUsed() > 0.55) break;\n            int before = cur;\n            hillClimb(grid, cur, avail, min(0.55, timeUsed() + 0.2));\n            bool placed = insertUnmatched(grid, avail);\n            cur = countMatches(grid, avail);\n            if (!placed && cur <= before) break;\n        }\n        \n        int dots = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] == '.') dots++;\n        if (cur > bestScore || (cur == bestScore && dots > bestDots)) {\n            bestScore = cur;\n            bestDots = dots;\n            bestGrid = grid;\n        }\n        cerr << \"After Phase 2: \" << cur << \"/\" << avail.size() << \"\\n\";\n    }\n    \n    {\n        State state;\n        state.init(bestGrid);\n        \n        int bestCur = state.totalMatched;\n        vector<string> savedBest = state.grid;\n        \n        cerr << \"Start SA: \" << state.totalMatched << \"\\n\";\n        \n        double tStart = timeUsed();\n        double tEnd = 2.85;\n        double tempStart = 3.0;\n        double tempEnd = 0.05;\n        \n        int iter = 0, accepted = 0, improvements = 0;\n        int lastImprovementIter = 0;\n        int restarts = 0;\n        \n        int changeR[16], changeC[16];\n        char changeOld[16];\n        \n        while (timeUsed() < tEnd) {\n            iter++;\n            double progress = (timeUsed() - tStart) / (tEnd - tStart);\n            if (progress > 1) progress = 1;\n            double temp = tempStart * pow(tempEnd/tempStart, progress);\n            \n            if (iter - lastImprovementIter > 100000) {\n                state.init(savedBest);\n                int nPerturb = 2 + (rng() % 3);\n                for (int k = 0; k < nPerturb; k++) {\n                    int r = rng() % N, c = rng() % N;\n                    char oldCh = state.grid[r][c];\n                    char newCh = rng() % 9 == 0 ? '.' : ('A' + (rng() % 8));\n                    if (newCh != oldCh) {\n                        state.grid[r][c] = newCh;\n                        state.recomputeTrack(r);\n                        state.recomputeTrack(N + c);\n                    }\n                }\n                lastImprovementIter = iter;\n                restarts++;\n            }\n            \n            int moveType = rng() % 10;\n            \n            if (moveType == 0) {\n                int r = rng() % N;\n                int c = rng() % N;\n                char oldCh = state.grid[r][c];\n                char newCh;\n                if (rng() % 10 == 0) newCh = '.';\n                else newCh = 'A' + (rng() % 8);\n                if (newCh == oldCh) continue;\n                \n                int before = state.totalMatched;\n                state.grid[r][c] = newCh;\n                state.recomputeTrack(r);\n                state.recomputeTrack(N + c);\n                int delta = state.totalMatched - before;\n                \n                bool accept = delta >= 0 || (rng() / (double)rng.max()) < exp(delta / temp);\n                if (!accept) {\n                    state.grid[r][c] = oldCh;\n                    state.recomputeTrack(r);\n                    state.recomputeTrack(N + c);\n                } else {\n                    accepted++;\n                    if (state.totalMatched > bestCur) {\n                        bestCur = state.totalMatched;\n                        savedBest = state.grid;\n                        improvements++;\n                        lastImprovementIter = iter;\n                    }\n                }\n            } else {\n                int i;\n                if (moveType <= 7) {\n                    int chosen = -1;\n                    for (int t = 0; t < 30; t++) {\n                        int x = avail[rng() % avail.size()];\n                        if (state.matchCount[x] == 0) { chosen = x; break; }\n                    }\n                    if (chosen == -1) chosen = avail[rng() % avail.size()];\n                    i = chosen;\n                } else {\n                    i = avail[rng() % avail.size()];\n                }\n                const string& s = S[i];\n                int L = s.size();\n                \n                int rr = rng() % N, cc = rng() % N, dir = rng() % 2;\n                bool useSmart = (moveType <= 6);\n                if (useSmart) {\n                    int bestSc = INT_MIN;\n                    int K = 10;\n                    for (int k = 0; k < K; k++) {\n                        int tryR = rng() % N, tryC = rng() % N, tryD = rng() % 2;\n                        int matches = 0, conflicts = 0;\n                        for (int p = 0; p < L; p++) {\n                            int ar = tryD == 0 ? tryR : (tryR+p)%N;\n                            int ac_ = tryD == 0 ? (tryC+p)%N : tryC;\n                            char existing = state.grid[ar][ac_];\n                            if (existing == s[p]) matches++;\n                            else if (existing != '.') conflicts++;\n                        }\n                        int sc = matches * 3 - conflicts * 2;\n                        if (sc > bestSc) {\n                            bestSc = sc;\n                            rr = tryR; cc = tryC; dir = tryD;\n                        }\n                    }\n                }\n                \n                int before = state.totalMatched;\n                int numChanges = 0;\n                uint64_t touchedMask = 0;\n                \n                for (int p = 0; p < L; p++) {\n                    int ar, ac_;\n                    if (dir == 0) { ar = rr; ac_ = (cc+p) % N; }\n                    else { ar = (rr+p) % N; ac_ = cc; }\n                    if (state.grid[ar][ac_] != s[p]) {\n                        changeR[numChanges] = ar;\n                        changeC[numChanges] = ac_;\n                        changeOld[numChanges] = state.grid[ar][ac_];\n                        numChanges++;\n                        state.grid[ar][ac_] = s[p];\n                        touchedMask |= (1ULL << ar);\n                        touchedMask |= (1ULL << (N + ac_));\n                    }\n                }\n                if (numChanges == 0) continue;\n                \n                for (int t = 0; t < 40; t++) {\n                    if (touchedMask & (1ULL << t)) state.recomputeTrack(t);\n                }\n                int delta = state.totalMatched - before;\n                \n                bool accept = delta >= 0 || (rng() / (double)rng.max()) < exp(delta / temp);\n                if (!accept) {\n                    for (int k = 0; k < numChanges; k++) {\n                        state.grid[changeR[k]][changeC[k]] = changeOld[k];\n                    }\n                    for (int t = 0; t < 40; t++) {\n                        if (touchedMask & (1ULL << t)) state.recomputeTrack(t);\n                    }\n                } else {\n                    accepted++;\n                    if (state.totalMatched > bestCur) {\n                        bestCur = state.totalMatched;\n                        savedBest = state.grid;\n                        improvements++;\n                        lastImprovementIter = iter;\n                    }\n                }\n            }\n        }\n        \n        cerr << \"SA iters: \" << iter << \" accepted: \" << accepted << \" improvements: \" << improvements << \" restarts: \" << restarts << \" bestCur: \" << bestCur << \"\\n\";\n        \n        int dots = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (savedBest[r][c] == '.') dots++;\n        if (bestCur > bestScore || (bestCur == bestScore && dots > bestDots)) {\n            bestScore = bestCur;\n            bestDots = dots;\n            bestGrid = savedBest;\n        }\n    }\n    \n    if (timeUsed() < 2.92) {\n        vector<string> grid = bestGrid;\n        int cur = bestScore;\n        hillClimb(grid, cur, avail, 2.92);\n        int dots = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (grid[r][c] == '.') dots++;\n        if (cur > bestScore || (cur == bestScore && dots > bestDots)) {\n            bestScore = cur;\n            bestDots = dots;\n            bestGrid = grid;\n        }\n    }\n    \n    if (bestScore == (int)avail.size()) {\n        int cur = bestScore;\n        vector<pair<int,int>> cells;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) cells.push_back({r,c});\n        shuffle(cells.begin(), cells.end(), rng);\n        for (auto [r, c] : cells) {\n            if (bestGrid[r][c] == '.') continue;\n            char orig = bestGrid[r][c];\n            bestGrid[r][c] = '.';\n            int nw = countMatches(bestGrid, avail);\n            if (nw < cur) bestGrid[r][c] = orig;\n            else cur = nw;\n        }\n    }\n    \n    cerr << \"Final: \" << bestScore << \"/\" << avail.size() << \"\\n\";\n    \n    for (int i = 0; i < N; i++) cout << bestGrid[i] << \"\\n\";\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> G;\nvector<vector<int>> id;\nvector<pair<int,int>> pos;\nvector<int> cost;\nint R;\n\nbool isRoad(int i,int j){ return i>=0&&i<N&&j>=0&&j<N&&G[i][j]!='#'; }\n\nchrono::steady_clock::time_point startT;\ndouble elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-startT).count();}\n\nint dx_[]={-1,1,0,0},dy_[]={0,0,-1,1};\n\nvoid dijkstra(int src, vector<int>&dist, vector<int>&prv){\n    dist.assign(R,INT_MAX);\n    prv.assign(R,-1);\n    dist[src]=0;\n    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>> pq;\n    pq.push({0,src});\n    while(!pq.empty()){\n        auto[d,u]=pq.top();pq.pop();\n        if(d>dist[u])continue;\n        auto[i,j]=pos[u];\n        for(int di=0;di<4;di++){\n            int x=i+dx_[di],y=j+dy_[di];\n            if(!isRoad(x,y))continue;\n            int v=id[x][y];\n            int nd=d+cost[v];\n            if(nd<dist[v]){\n                dist[v]=nd;\n                prv[v]=u;\n                pq.push({nd,v});\n            }\n        }\n    }\n}\n\nint main(){\n    startT=chrono::steady_clock::now();\n    cin>>N>>si>>sj;\n    G.resize(N);\n    for(auto&s:G)cin>>s;\n    id.assign(N,vector<int>(N,-1));\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(G[i][j]!='#'){\n        id[i][j]=pos.size();\n        pos.push_back({i,j});\n        cost.push_back(G[i][j]-'0');\n    }\n    R=pos.size();\n    \n    vector<vector<int>> visible(R);\n    vector<vector<char>> visMat(R, vector<char>(R, 0));\n    for(int k=0;k<R;k++){\n        auto[i,j]=pos[k];\n        visible[k].push_back(k);\n        visMat[k][k]=1;\n        for(int d=0;d<4;d++){\n            int x=i+dx_[d],y=j+dy_[d];\n            while(isRoad(x,y)){\n                int v=id[x][y];\n                visible[k].push_back(v);\n                visMat[k][v]=1;\n                x+=dx_[d];y+=dy_[d];\n            }\n        }\n    }\n    \n    int sid=id[si][sj];\n    \n    auto greedyCover=[&](unsigned seed)->vector<int>{\n        mt19937 rng(seed);\n        vector<bool> covered(R,false);\n        vector<int> uncovCount(R);\n        for(int k=0;k<R;k++)uncovCount[k]=visible[k].size();\n        vector<int> sel;\n        int nCov=0;\n        auto doSel=[&](int k){\n            sel.push_back(k);\n            for(int v:visible[k]){\n                if(!covered[v]){\n                    covered[v]=true;\n                    nCov++;\n                    for(int u:visible[v])uncovCount[u]--;\n                }\n            }\n        };\n        doSel(sid);\n        while(nCov<R){\n            int bc=-1;\n            vector<int> bests;\n            for(int k=0;k<R;k++){\n                if(uncovCount[k]>bc){bc=uncovCount[k];bests.clear();bests.push_back(k);}\n                else if(uncovCount[k]==bc)bests.push_back(k);\n            }\n            int pick=bests[rng()%bests.size()];\n            doSel(pick);\n        }\n        vector<int> coverCnt(R,0);\n        for(int s:sel)for(int v:visible[s])coverCnt[v]++;\n        vector<bool> keep(sel.size(),true);\n        vector<int> ord;\n        for(int i=1;i<(int)sel.size();i++)ord.push_back(i);\n        shuffle(ord.begin(),ord.end(),rng);\n        for(int i:ord){\n            int s=sel[i];\n            bool can=true;\n            for(int v:visible[s])if(coverCnt[v]<2){can=false;break;}\n            if(can){\n                keep[i]=false;\n                for(int v:visible[s])coverCnt[v]--;\n            }\n        }\n        vector<int> res;\n        for(int i=0;i<(int)sel.size();i++)if(keep[i])res.push_back(sel[i]);\n        return res;\n    };\n    \n    vector<int> selected = greedyCover(1);\n    for(int t=2;t<=10 && elapsed()<0.2;t++){\n        auto s2=greedyCover(t*7919u+1);\n        if(s2.size()<selected.size())selected=s2;\n    }\n    for(int i=0;i<(int)selected.size();i++)if(selected[i]==sid){swap(selected[0],selected[i]);break;}\n    \n    int K=selected.size();\n    vector<vector<int>> dist(K), prev_(K);\n    for(int s=0;s<K;s++)dijkstra(selected[s],dist[s],prev_[s]);\n    \n    vector<vector<int>> D(K,vector<int>(K));\n    for(int a=0;a<K;a++)for(int b=0;b<K;b++)D[a][b]=dist[a][selected[b]];\n    \n    auto tourLen=[&](const vector<int>&t){\n        int s=0;for(int i=0;i+1<(int)t.size();i++)s+=D[t[i]][t[i+1]];return s;\n    };\n    \n    auto twoOpt=[&](vector<int>&tour, double timeLimit){\n        int n=tour.size();\n        bool improved=true;\n        while(improved){\n            improved=false;\n            for(int i=1;i<n-2;i++){\n                if(elapsed()>=timeLimit)return;\n                for(int j=i+1;j<n-1;j++){\n                    int a=tour[i-1],b=tour[i],c=tour[j],d=tour[j+1];\n                    int delta=D[a][c]+D[b][d]-D[a][b]-D[c][d];\n                    if(delta<0){\n                        reverse(tour.begin()+i,tour.begin()+j+1);\n                        improved=true;\n                    }\n                }\n            }\n        }\n    };\n    \n    auto orOpt=[&](vector<int>&tour, double timeLimit){\n        int n=tour.size();\n        bool improved=true;\n        while(improved){\n            improved=false;\n            for(int segLen=1;segLen<=3;segLen++){\n                for(int i=1;i+segLen<n;i++){\n                    if(elapsed()>=timeLimit)return;\n                    int a=tour[i-1], b=tour[i], c=tour[i+segLen-1], d=tour[i+segLen];\n                    int removeCost=D[a][b]+D[c][d]-D[a][d];\n                    int bestDelta=0, bestJ=-1;\n                    bool bestRev=false;\n                    for(int j=0;j<n-1;j++){\n                        if(j>=i-1 && j<=i+segLen-1)continue;\n                        int e=tour[j], f=tour[j+1];\n                        int ic=D[e][b]+D[c][f]-D[e][f];\n                        int delta=ic-removeCost;\n                        if(delta<bestDelta){bestDelta=delta;bestJ=j;bestRev=false;}\n                        int ic2=D[e][c]+D[b][f]-D[e][f];\n                        int delta2=ic2-removeCost;\n                        if(delta2<bestDelta){bestDelta=delta2;bestJ=j;bestRev=true;}\n                    }\n                    if(bestJ>=0){\n                        vector<int> seg(tour.begin()+i, tour.begin()+i+segLen);\n                        if(bestRev)reverse(seg.begin(),seg.end());\n                        vector<int> nt;\n                        int j=bestJ;\n                        if(j<i-1){\n                            for(int k=0;k<=j;k++)nt.push_back(tour[k]);\n                            for(int x:seg)nt.push_back(x);\n                            for(int k=j+1;k<i;k++)nt.push_back(tour[k]);\n                            for(int k=i+segLen;k<n;k++)nt.push_back(tour[k]);\n                        } else {\n                            for(int k=0;k<i;k++)nt.push_back(tour[k]);\n                            for(int k=i+segLen;k<=j;k++)nt.push_back(tour[k]);\n                            for(int x:seg)nt.push_back(x);\n                            for(int k=j+1;k<n;k++)nt.push_back(tour[k]);\n                        }\n                        tour=nt;\n                        improved=true;\n                        break;\n                    }\n                }\n                if(improved)break;\n            }\n        }\n    };\n    \n    auto nearestNeighborFrom=[&](int startNeighbor){\n        vector<int> tour;\n        vector<bool> used(K,false);\n        used[0]=true;\n        tour.push_back(0);\n        if(startNeighbor!=0 && startNeighbor<K){\n            tour.push_back(startNeighbor);\n            used[startNeighbor]=true;\n        }\n        while((int)tour.size()<K){\n            int last=tour.back();\n            int bn=-1,bd=INT_MAX;\n            for(int j=0;j<K;j++)if(!used[j]&&D[last][j]<bd){bd=D[last][j];bn=j;}\n            tour.push_back(bn);used[bn]=true;\n        }\n        tour.push_back(0);\n        return tour;\n    };\n    \n    vector<int> bestTour = nearestNeighborFrom(0);\n    twoOpt(bestTour, 0.15);\n    orOpt(bestTour, 0.22);\n    twoOpt(bestTour, 0.28);\n    int bestLen = tourLen(bestTour);\n    \n    for(int s=1;s<K && elapsed()<0.4;s++){\n        vector<int> t = nearestNeighborFrom(s);\n        twoOpt(t, min(0.4, elapsed()+0.025));\n        int l=tourLen(t);\n        if(l<bestLen){bestLen=l;bestTour=t;}\n    }\n    \n    mt19937 rng(12345);\n    \n    while(elapsed()<0.55){\n        vector<int> t2 = bestTour;\n        int n = t2.size()-1;\n        if(n<8)break;\n        int p1=1+rng()%(n/4);\n        int p2=p1+1+rng()%(n/4);\n        int p3=p2+1+rng()%(n/4);\n        if(p3>=n)continue;\n        vector<int> nt;\n        nt.push_back(t2[0]);\n        for(int i=p3;i<n;i++)nt.push_back(t2[i]);\n        for(int i=p2;i<p3;i++)nt.push_back(t2[i]);\n        for(int i=p1;i<p2;i++)nt.push_back(t2[i]);\n        for(int i=1;i<p1;i++)nt.push_back(t2[i]);\n        nt.push_back(t2[0]);\n        double lim = min(0.55, elapsed()+0.05);\n        twoOpt(nt, lim);\n        orOpt(nt, min(0.55, elapsed()+0.025));\n        int l=tourLen(nt);\n        if(l<bestLen){bestLen=l;bestTour=nt;}\n    }\n    \n    auto tryGlobalReplacement=[&]()->int{\n        vector<int> coverCnt(R,0);\n        for(int s:selected)for(int v:visible[s])coverCnt[v]++;\n        \n        int changes=0;\n        vector<int> order;\n        for(int i=1;i<K;i++)order.push_back(i);\n        shuffle(order.begin(),order.end(),rng);\n        \n        for(int ti:order){\n            if(elapsed()>1.3)break;\n            if(ti>=K)continue;\n            int origPt = selected[ti];\n            vector<int> unique_sq;\n            for(int v:visible[origPt])if(coverCnt[v]==1)unique_sq.push_back(v);\n            \n            int pos_in_tour=-1;\n            for(int p=0;p<(int)bestTour.size();p++)if(bestTour[p]==ti){pos_in_tour=p;break;}\n            if(pos_in_tour<0)continue;\n            int prv = bestTour[pos_in_tour-1];\n            int nxt = bestTour[pos_in_tour+1];\n            int removeGain = D[prv][ti]+D[ti][nxt]-D[prv][nxt];\n            \n            if(unique_sq.empty()){\n                if(removeGain>0){\n                    int removedIdx = ti;\n                    vector<int> newSel;\n                    for(int i=0;i<K;i++)if(i!=removedIdx)newSel.push_back(selected[i]);\n                    vector<vector<int>> newDist(newSel.size()), newPrev(newSel.size());\n                    for(int s=0;s<(int)newSel.size();s++){\n                        int o = (s<removedIdx)?s:s+1;\n                        newDist[s] = dist[o];\n                        newPrev[s] = prev_[o];\n                    }\n                    selected = newSel;\n                    K = selected.size();\n                    dist = newDist; prev_ = newPrev;\n                    D.assign(K,vector<int>(K));\n                    for(int a=0;a<K;a++)for(int b=0;b<K;b++)D[a][b]=dist[a][selected[b]];\n                    vector<int> newTour;\n                    for(int x:bestTour){\n                        if(x==removedIdx)continue;\n                        newTour.push_back(x>removedIdx?x-1:x);\n                    }\n                    vector<int> nt2;\n                    for(int x:newTour){\n                        if(!nt2.empty() && nt2.back()==x)continue;\n                        nt2.push_back(x);\n                    }\n                    if(nt2.empty() || nt2[0]!=0)nt2.insert(nt2.begin(),0);\n                    if(nt2.back()!=0)nt2.push_back(0);\n                    bestTour = nt2;\n                    bestLen = tourLen(bestTour);\n                    changes++;\n                    return changes;\n                }\n                continue;\n            }\n            \n            vector<int> candidates;\n            int smallest=unique_sq[0];\n            for(int v:unique_sq)if((int)visible[v].size()<(int)visible[smallest].size())smallest=v;\n            for(int c:visible[smallest]){\n                bool ok=true;\n                for(int v:unique_sq)if(!visMat[c][v]){ok=false;break;}\n                if(ok)candidates.push_back(c);\n            }\n            \n            int bestDelta = 0;\n            int bestCand = -1;\n            int bestInsertPos = -2;\n            int n_tour = bestTour.size();\n            \n            for(int cand:candidates){\n                if(cand==origPt)continue;\n                for(int p=0;p+1<n_tour;p++){\n                    if(p==pos_in_tour-1 || p==pos_in_tour)continue;\n                    int ej = bestTour[p], fj = bestTour[p+1];\n                    int d1 = dist[ej][cand];\n                    if(d1>=INT_MAX/2)continue;\n                    int d2 = dist[fj][cand] - cost[selected[fj]] + cost[cand];\n                    int insertCost = d1 + d2 - D[ej][fj];\n                    int delta = -removeGain + insertCost;\n                    if(delta < bestDelta){\n                        bestDelta = delta;\n                        bestCand = cand;\n                        bestInsertPos = p;\n                    }\n                }\n                {\n                    int ej = prv, fj = nxt;\n                    int d1 = dist[ej][cand];\n                    if(d1<INT_MAX/2){\n                        int d2 = dist[fj][cand] - cost[selected[fj]] + cost[cand];\n                        int insertCost = d1 + d2 - D[prv][nxt];\n                        int delta = -removeGain + insertCost;\n                        if(delta < bestDelta){\n                            bestDelta = delta;\n                            bestCand = cand;\n                            bestInsertPos = -1;\n                        }\n                    }\n                }\n            }\n            \n            if(bestCand==-1)continue;\n            \n            int cand = bestCand;\n            for(int v:visible[origPt])coverCnt[v]--;\n            for(int v:visible[cand])coverCnt[v]++;\n            selected[ti]=cand;\n            dijkstra(cand, dist[ti], prev_[ti]);\n            for(int b=0;b<K;b++)D[ti][b]=dist[ti][selected[b]];\n            for(int b=0;b<K;b++){\n                if(b==ti)continue;\n                D[b][ti] = D[ti][b] + cost[cand] - cost[selected[b]];\n            }\n            if(bestInsertPos==-1){\n            } else {\n                vector<int> shortT;\n                for(int p=0;p<(int)bestTour.size();p++)if(p!=pos_in_tour)shortT.push_back(bestTour[p]);\n                int adjInsert = bestInsertPos;\n                if(bestInsertPos > pos_in_tour) adjInsert = bestInsertPos - 1;\n                vector<int> nt;\n                for(int p=0;p<=adjInsert;p++)nt.push_back(shortT[p]);\n                nt.push_back(ti);\n                for(int p=adjInsert+1;p<(int)shortT.size();p++)nt.push_back(shortT[p]);\n                bestTour = nt;\n            }\n            bestLen = tourLen(bestTour);\n            changes++;\n        }\n        return changes;\n    };\n    \n    // Phase 1: TSP + global replacement\n    for(int round=0;round<40 && elapsed()<1.25;round++){\n        int ch1 = tryGlobalReplacement();\n        twoOpt(bestTour, min(1.4, elapsed()+0.05));\n        orOpt(bestTour, min(1.4, elapsed()+0.025));\n        bestLen = tourLen(bestTour);\n        if(ch1==0 && round>0)break;\n    }\n    \n    while(elapsed()<1.5){\n        vector<int> t2 = bestTour;\n        int n = t2.size()-1;\n        if(n<8)break;\n        int p1=1+rng()%(n/4);\n        int p2=p1+1+rng()%(n/4);\n        int p3=p2+1+rng()%(n/4);\n        if(p3>=n)continue;\n        vector<int> nt;\n        nt.push_back(t2[0]);\n        for(int i=p3;i<n;i++)nt.push_back(t2[i]);\n        for(int i=p2;i<p3;i++)nt.push_back(t2[i]);\n        for(int i=p1;i<p2;i++)nt.push_back(t2[i]);\n        for(int i=1;i<p1;i++)nt.push_back(t2[i]);\n        nt.push_back(t2[0]);\n        double lim = min(1.5, elapsed()+0.06);\n        twoOpt(nt, lim);\n        orOpt(nt, min(1.5, elapsed()+0.025));\n        int l=tourLen(nt);\n        if(l<bestLen){bestLen=l;bestTour=nt;}\n    }\n    \n    vector<int> backupSelected = selected;\n    vector<vector<int>> backupDist = dist;\n    vector<vector<int>> backupPrev = prev_;\n    vector<vector<int>> backupD = D;\n    vector<int> backupTour = bestTour;\n    int backupK = K;\n    int backupLen = bestLen;\n    \n    auto tryPathBasedRemoval = [&](double timeLim)->bool{\n        if(K<=2)return false;\n        vector<pair<int,int>> cands;\n        for(int ti=1;ti<K;ti++){\n            int pt=-1;\n            for(int p=0;p<(int)bestTour.size();p++) if(bestTour[p]==ti){pt=p;break;}\n            if(pt<0) continue;\n            int prvI = bestTour[pt-1], nxtI = bestTour[pt+1];\n            int rg = D[prvI][ti]+D[ti][nxtI]-D[prvI][nxtI];\n            if(rg >= 0) cands.push_back({-rg, ti});\n        }\n        sort(cands.begin(), cands.end());\n        \n        for(auto [ng, ti] : cands){\n            if(elapsed() > timeLim) return false;\n            int pt=-1;\n            for(int p=0;p<(int)bestTour.size();p++) if(bestTour[p]==ti){pt=p;break;}\n            if(pt<0) continue;\n            \n            vector<int> nt2;\n            for(int p=0;p<(int)bestTour.size();p++){\n                if(p==pt) continue;\n                int x = bestTour[p];\n                if(!nt2.empty() && nt2.back()==x) continue;\n                nt2.push_back(x);\n            }\n            if(nt2.empty())continue;\n            if(nt2.back() != nt2.front()) nt2.push_back(nt2.front());\n            if((int)nt2.size() < 2) continue;\n            \n            vector<char> cov(R, 0);\n            auto add = [&](int v){ \n                for(int u : visible[v]) cov[u]=1;\n            };\n            bool ok=true;\n            add(selected[nt2[0]]);\n            for(int i=0;i+1<(int)nt2.size();i++){\n                int ai = nt2[i], bi = nt2[i+1];\n                int a = selected[ai], b = selected[bi];\n                if(a==b) continue;\n                int cur = b;\n                int safety = 10*R;\n                while(cur != a){\n                    if(safety-- <= 0){ok=false;break;}\n                    add(cur);\n                    int nx = prev_[ai][cur];\n                    if(nx<0){ok=false;break;}\n                    cur = nx;\n                }\n                if(!ok) break;\n            }\n            if(!ok) continue;\n            \n            bool allCov = true;\n            for(int v=0;v<R;v++) if(!cov[v]){allCov=false;break;}\n            if(!allCov) continue;\n            \n            int removedIdx = ti;\n            vector<int> newSel;\n            for(int i=0;i<K;i++) if(i!=removedIdx) newSel.push_back(selected[i]);\n            vector<vector<int>> newDist(newSel.size()), newPrev(newSel.size());\n            for(int s=0;s<(int)newSel.size();s++){\n                int o = (s<removedIdx)?s:s+1;\n                newDist[s] = dist[o];\n                newPrev[s] = prev_[o];\n            }\n            vector<int> newTour;\n            for(int x : nt2) newTour.push_back(x > removedIdx ? x-1 : x);\n            \n            selected = newSel;\n            K = selected.size();\n            dist = newDist;\n            prev_ = newPrev;\n            D.assign(K, vector<int>(K));\n            for(int a=0;a<K;a++)for(int b=0;b<K;b++) D[a][b]=dist[a][selected[b]];\n            bestTour = newTour;\n            bestLen = tourLen(bestTour);\n            return true;\n        }\n        return false;\n    };\n    \n    // Phase 2: path-based removal\n    while(elapsed()<2.4){\n        if(!tryPathBasedRemoval(2.4))break;\n    }\n    \n    auto verifyCoverage = [&]()->bool{\n        vector<char> cov(R,0);\n        auto add=[&](int v){for(int u:visible[v])cov[u]=1;};\n        if(bestTour.empty())return false;\n        add(selected[bestTour[0]]);\n        for(int i=0;i+1<(int)bestTour.size();i++){\n            int a=selected[bestTour[i]], b=selected[bestTour[i+1]];\n            if(a==b)continue;\n            int s=bestTour[i];\n            int cur=b;\n            int safety=10*R;\n            while(cur!=a){\n                if(safety-- <= 0)return false;\n                add(cur);\n                int nx=prev_[s][cur];\n                if(nx<0)return false;\n                cur=nx;\n            }\n        }\n        for(int v=0;v<R;v++)if(!cov[v])return false;\n        return true;\n    };\n    \n    if(!verifyCoverage()){\n        selected = backupSelected;\n        dist = backupDist;\n        prev_ = backupPrev;\n        D = backupD;\n        bestTour = backupTour;\n        K = backupK;\n        bestLen = backupLen;\n    }\n    \n    vector<int> backup2Selected = selected;\n    vector<vector<int>> backup2Dist = dist;\n    vector<vector<int>> backup2Prev = prev_;\n    vector<vector<int>> backup2D = D;\n    vector<int> backup2Tour = bestTour;\n    int backup2K = K;\n    int backup2Len = bestLen;\n    \n    auto coverageSafeTwoOpt = [&](double timeLim){\n        int n = bestTour.size();\n        bool improved = true;\n        while(improved && elapsed() < timeLim){\n            improved = false;\n            for(int i=1;i<n-2;i++){\n                if(elapsed() >= timeLim) return;\n                for(int j=i+1;j<n-1;j++){\n                    int a=bestTour[i-1], b=bestTour[i], c=bestTour[j], d=bestTour[j+1];\n                    int delta = D[a][c]+D[b][d]-D[a][b]-D[c][d];\n                    if(delta < 0){\n                        reverse(bestTour.begin()+i, bestTour.begin()+j+1);\n                        if(verifyCoverage()){\n                            improved = true;\n                            bestLen += delta;\n                        } else {\n                            reverse(bestTour.begin()+i, bestTour.begin()+j+1);\n                        }\n                    }\n                }\n            }\n        }\n    };\n    \n    // Phase 3: coverage-safe 2-opt\n    coverageSafeTwoOpt(2.6);\n    \n    // Phase 4: more path-based removal (2-opt may have enabled new removals)\n    while(elapsed()<2.8){\n        if(!tryPathBasedRemoval(2.8))break;\n    }\n    \n    // Phase 5: final coverage-safe 2-opt\n    coverageSafeTwoOpt(2.95);\n    \n    if(!verifyCoverage()){\n        selected = backup2Selected;\n        dist = backup2Dist;\n        prev_ = backup2Prev;\n        D = backup2D;\n        bestTour = backup2Tour;\n        K = backup2K;\n        bestLen = backup2Len;\n        if(!verifyCoverage()){\n            selected = backupSelected;\n            dist = backupDist;\n            prev_ = backupPrev;\n            D = backupD;\n            bestTour = backupTour;\n            K = backupK;\n            bestLen = backupLen;\n        }\n    }\n    \n    vector<int>& tour = bestTour;\n    \n    string result;\n    for(int i=0;i+1<(int)tour.size();i++){\n        int a=selected[tour[i]], b=selected[tour[i+1]];\n        if(a==b)continue;\n        int s=tour[i];\n        vector<int> path;\n        int cur=b;\n        while(cur!=a){\n            path.push_back(cur);\n            cur=prev_[s][cur];\n        }\n        reverse(path.begin(),path.end());\n        int px=pos[a].first, py=pos[a].second;\n        for(int nd:path){\n            int nx=pos[nd].first, ny=pos[nd].second;\n            if(nx==px-1)result+='U';\n            else if(nx==px+1)result+='D';\n            else if(ny==py-1)result+='L';\n            else result+='R';\n            px=nx;py=ny;\n        }\n    }\n    \n    cout<<result<<endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> D;\nvector<vector<int>> children;\nvector<int> indeg;\n\nvector<vector<int>> estS;\nvector<vector<pair<int,int>>> obs;\n\nint computeW(const vector<int>& d, const vector<int>& s) {\n    int w = 0;\n    for (int k = 0; k < K; k++) w += max(0, d[k] - s[k]);\n    return w;\n}\n\nint predictTime(int task, int member) {\n    int w = computeW(D[task], estS[member]);\n    return (w == 0) ? 1 : max(1, w);\n}\n\ndouble errorFor(int member, const vector<int>& s) {\n    double err = 0;\n    for (auto& p : obs[member]) {\n        int w = computeW(D[p.first], s);\n        int pred = (w == 0) ? 1 : max(1, w);\n        double diff = (double)pred - p.second;\n        err += diff * diff;\n    }\n    return err;\n}\n\nvoid updateSkills(int member) {\n    if (obs[member].empty()) return;\n    vector<int>& s = estS[member];\n    double best = errorFor(member, s);\n    for (int pass = 0; pass < 100; pass++) {\n        bool improved = false;\n        for (int k = 0; k < K; k++) {\n            for (int delta : {1, -1, 2, -2, 3, -3}) {\n                int old = s[k];\n                int nv = old + delta;\n                if (nv < 0 || nv > 50) continue;\n                s[k] = nv;\n                double e = errorFor(member, s);\n                if (e < best - 1e-9) {\n                    best = e;\n                    improved = true;\n                } else {\n                    s[k] = old;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> N >> M >> K >> R;\n    D.assign(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> D[i][k];\n    children.assign(N, {});\n    indeg.assign(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        children[u].push_back(v);\n        indeg[v]++;\n    }\n    \n    vector<int> numDesc(N, 0);\n    {\n        vector<bitset<1024>> reach(N);\n        for (int i = N - 1; i >= 0; i--) {\n            reach[i].set(i);\n            for (int ch : children[i]) reach[i] |= reach[ch];\n            numDesc[i] = reach[i].count();\n        }\n    }\n    \n    estS.assign(M, vector<int>(K, 3));\n    obs.assign(M, {});\n    \n    vector<int> taskStatus(N, 0);\n    vector<int> memberTask(M, -1);\n    vector<int> memberStartDay(M, 0);\n    vector<int> remIndeg = indeg;\n    \n    vector<double> priority(N);\n    \n    for (int day = 1; day <= 2000; day++) {\n        vector<double> minTime(N);\n        for (int i = 0; i < N; i++) {\n            double mt = 1e9;\n            for (int j = 0; j < M; j++) {\n                int pt = predictTime(i, j);\n                if (pt < mt) mt = pt;\n            }\n            minTime[i] = mt;\n        }\n        vector<double> wlp(N, 0);\n        for (int i = N - 1; i >= 0; i--) {\n            double b = 0;\n            for (int ch : children[i]) b = max(b, wlp[ch]);\n            wlp[i] = b + minTime[i];\n        }\n        for (int i = 0; i < N; i++) {\n            priority[i] = wlp[i] + 0.05 * numDesc[i];\n        }\n        \n        vector<int> avail;\n        for (int i = 0; i < N; i++)\n            if (taskStatus[i] == 0 && remIndeg[i] == 0) avail.push_back(i);\n        \n        sort(avail.begin(), avail.end(), [&](int a, int b) {\n            return priority[a] > priority[b];\n        });\n        \n        vector<int> freeM;\n        for (int j = 0; j < M; j++) if (memberTask[j] == -1) freeM.push_back(j);\n        \n        vector<bool> memUsed(M, false);\n        vector<int> taskOfMem(M, -1);\n        \n        for (int task : avail) {\n            int bestMem = -1, bestTime = INT_MAX;\n            for (int j : freeM) {\n                if (memUsed[j]) continue;\n                int t = predictTime(task, j);\n                if (t < bestTime) { bestTime = t; bestMem = j; }\n            }\n            if (bestMem == -1) break;\n            memUsed[bestMem] = true;\n            taskOfMem[bestMem] = task;\n        }\n        \n        bool improved = true;\n        int iters = 0;\n        while (improved && iters < 50) {\n            improved = false;\n            iters++;\n            for (size_t a = 0; a < freeM.size(); a++) {\n                int ma = freeM[a];\n                if (taskOfMem[ma] == -1) continue;\n                for (size_t b = a+1; b < freeM.size(); b++) {\n                    int mb = freeM[b];\n                    if (taskOfMem[mb] == -1) continue;\n                    int ta = taskOfMem[ma], tb = taskOfMem[mb];\n                    double curr = (double)predictTime(ta, ma) * priority[ta] + (double)predictTime(tb, mb) * priority[tb];\n                    double swapped = (double)predictTime(tb, ma) * priority[tb] + (double)predictTime(ta, mb) * priority[ta];\n                    if (swapped < curr - 1e-9) {\n                        taskOfMem[ma] = tb;\n                        taskOfMem[mb] = ta;\n                        improved = true;\n                    }\n                }\n            }\n        }\n        \n        vector<pair<int,int>> assignments;\n        for (int j : freeM) {\n            if (taskOfMem[j] != -1) {\n                int task = taskOfMem[j];\n                assignments.push_back({j, task});\n                taskStatus[task] = 1;\n                memberTask[j] = task;\n                memberStartDay[j] = day;\n            }\n        }\n        \n        cout << assignments.size();\n        for (auto& p : assignments) cout << \" \" << (p.first+1) << \" \" << (p.second+1);\n        cout << \"\\n\";\n        cout.flush();\n        \n        int n; cin >> n;\n        if (n == -1) return 0;\n        for (int i = 0; i < n; i++) {\n            int f; cin >> f; f--;\n            int task = memberTask[f];\n            int daysTaken = day - memberStartDay[f] + 1;\n            obs[f].push_back({task, daysTaken});\n            taskStatus[task] = 2;\n            memberTask[f] = -1;\n            for (int ch : children[task]) remIndeg[ch]--;\n            updateSkills(f);\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint A[1000][4];\n\ninline int px(int id) { \n    if(id<=0) return 400;\n    if(id<=1000) return A[id-1][0];\n    return A[id-1001][2];\n}\ninline int py(int id) {\n    if(id<=0) return 400;\n    if(id<=1000) return A[id-1][1];\n    return A[id-1001][3];\n}\ninline int D(int a, int b) {\n    return abs(px(a)-px(b))+abs(py(a)-py(b));\n}\n\nint routeCost(const vector<int>& s){\n    int t=0;\n    for(int i=0;i+1<(int)s.size();i++) t+=D(s[i],s[i+1]);\n    return t;\n}\n\nint insertOrderBest(vector<int>& s, int oid){\n    int p = oid+1, dlv = oid+1001;\n    int n = s.size();\n    int best = INT_MAX;\n    int bi=1, bj=1;\n    \n    static int cost_p[200], cost_d[200];\n    for(int i=1;i<n;i++){\n        int dss = D(s[i-1], s[i]);\n        cost_p[i] = D(s[i-1], p) + D(p, s[i]) - dss;\n        cost_d[i] = D(s[i-1], dlv) + D(dlv, s[i]) - dss;\n    }\n    \n    int dpd = D(p, dlv);\n    for(int i=1;i<n;i++){\n        int delta = D(s[i-1], p) + dpd + D(dlv, s[i]) - D(s[i-1], s[i]);\n        if(delta < best){ best = delta; bi = i; bj = i; }\n    }\n    \n    int min_cp = INT_MAX, min_cp_i = -1;\n    for(int j=2;j<n;j++){\n        int ic = j-1;\n        if(cost_p[ic] < min_cp){ min_cp = cost_p[ic]; min_cp_i = ic; }\n        int delta = min_cp + cost_d[j];\n        if(delta < best){ best = delta; bi = min_cp_i; bj = j; }\n    }\n    \n    if(bi==bj){\n        s.insert(s.begin()+bi, dlv);\n        s.insert(s.begin()+bi, p);\n    } else {\n        s.insert(s.begin()+bj, dlv);\n        s.insert(s.begin()+bi, p);\n    }\n    return best;\n}\n\nint removeOrderDelta(vector<int>& s, int oid){\n    int p=oid+1, d=oid+1001;\n    int ip=-1, idx_=-1;\n    int n=s.size();\n    for(int i=0;i<n;i++){\n        if(s[i]==p) ip=i;\n        else if(s[i]==d) idx_=i;\n    }\n    if(ip<0 || idx_<0) return 0;\n    int delta = 0;\n    if(idx_ == ip+1){\n        delta = D(s[ip-1], s[idx_+1]) - D(s[ip-1],p) - D(p,d) - D(d, s[idx_+1]);\n        s.erase(s.begin()+ip, s.begin()+idx_+1);\n    } else {\n        delta -= D(s[ip-1],p) + D(p, s[ip+1]);\n        delta += D(s[ip-1], s[ip+1]);\n        delta -= D(s[idx_-1], d) + D(d, s[idx_+1]);\n        delta += D(s[idx_-1], s[idx_+1]);\n        s.erase(s.begin()+idx_);\n        s.erase(s.begin()+ip);\n    }\n    return delta;\n}\n\nstatic int POS_[2001];\nstatic int PP_[200];\n\nint relocateOnce(vector<int>& s){\n    int n = s.size();\n    for(int i=0;i<n;i++) POS_[s[i]]=i;\n    for(int i=0;i<n;i++){\n        int id = s[i];\n        if(id<=0){ PP_[i]=-1; continue; }\n        int partner = (id<=1000) ? id+1000 : id-1000;\n        PP_[i] = POS_[partner];\n    }\n    int bestDelta = 0;\n    int bestFrom=-1, bestTo=-1;\n    for(int from=1;from<n-1;from++){\n        int id = s[from];\n        if(id<=0) continue;\n        bool isPickup = (id<=1000);\n        int pp = PP_[from];\n        int lo, hi;\n        if(isPickup){ lo=1; hi=pp; }\n        else { lo=pp+1; hi=n; }\n        int remGain = D(s[from-1],s[from])+D(s[from],s[from+1])-D(s[from-1],s[from+1]);\n        for(int to=lo;to<=hi;to++){\n            if(to==from || to==from+1) continue;\n            int aa = s[to-1], bb = s[to];\n            int insCost = D(aa,id)+D(id,bb)-D(aa,bb);\n            int delta = insCost - remGain;\n            if(delta < bestDelta){\n                bestDelta = delta;\n                bestFrom = from;\n                bestTo = to;\n            }\n        }\n    }\n    if(bestDelta<0){\n        int id = s[bestFrom];\n        s.erase(s.begin()+bestFrom);\n        int to = bestTo;\n        if(to>bestFrom) to--;\n        s.insert(s.begin()+to, id);\n        return bestDelta;\n    }\n    return 0;\n}\n\nint twoOptOnce(vector<int>& s){\n    int n = s.size();\n    for(int i=0;i<n;i++) POS_[s[i]]=i;\n    for(int i=0;i<n;i++){\n        int id = s[i];\n        if(id<=0){ PP_[i]=-1; continue; }\n        int partner = (id<=1000) ? id+1000 : id-1000;\n        PP_[i] = POS_[partner];\n    }\n    int bestDelta = 0;\n    int bi=-1, bj=-1;\n    for(int i=1;i<n-2;i++){\n        int pairCount = 0;\n        int si_1 = s[i-1], si = s[i];\n        int d_im1_i = D(si_1, si);\n        for(int j=i+1;j<n-1;j++){\n            if(PP_[j] >= i && PP_[j] < j) pairCount++;\n            if(pairCount == 0){\n                int sj = s[j], sj1 = s[j+1];\n                int delta = D(si_1, sj) + D(si, sj1) - d_im1_i - D(sj, sj1);\n                if(delta < bestDelta){ bestDelta = delta; bi=i; bj=j; }\n            }\n        }\n    }\n    if(bestDelta<0){\n        reverse(s.begin()+bi, s.begin()+bj+1);\n        return bestDelta;\n    }\n    return 0;\n}\n\nint main(){\n    auto start = steady_clock::now();\n    for(int i=0;i<1000;i++) for(int j=0;j<4;j++) cin>>A[i][j];\n    \n    vector<pair<int,int>> scored(1000);\n    for(int i=0;i<1000;i++){\n        int s = abs(A[i][0]-400)+abs(A[i][1]-400)+abs(A[i][2]-400)+abs(A[i][3]-400);\n        scored[i]={s,i};\n    }\n    sort(scored.begin(),scored.end());\n    \n    vector<bool> inChosen(1000,false);\n    vector<int> chosen;\n    for(int i=0;i<50;i++){ chosen.push_back(scored[i].second); inChosen[scored[i].second]=true; }\n    \n    vector<int> seq = {0, 0};\n    for(int oid : chosen) insertOrderBest(seq, oid);\n    int curCost = routeCost(seq);\n    \n    auto localOpt = [&](){\n        int d;\n        bool improved = true;\n        while(improved){\n            improved = false;\n            while((d = twoOptOnce(seq)) < 0){ curCost += d; improved = true; }\n            while((d = relocateOnce(seq)) < 0){ curCost += d; improved = true; }\n        }\n    };\n    \n    auto rebuildChosen = [&](){\n        chosen.clear();\n        fill(inChosen.begin(), inChosen.end(), false);\n        for(int id : seq){\n            if(id>=1 && id<=1000 && !inChosen[id-1]){\n                chosen.push_back(id-1);\n                inChosen[id-1] = true;\n            }\n        }\n    };\n    \n    localOpt();\n    \n    mt19937 rng(12345);\n    int timeLimit = 1750;\n    vector<int> backup;\n    backup.reserve(200);\n    int bestCost = curCost;\n    vector<int> bestSeq = seq;\n    \n    long long iter = 0;\n    long long elapsed_ms = 0;\n    double t0 = 40.0, t1 = 0.3;\n    int numCycles = 4;\n    double cycleLen = timeLimit / (double)numCycles;\n    int lastCycle = 0;\n    \n    while(true){\n        if((iter&63)==0){\n            elapsed_ms = duration_cast<milliseconds>(steady_clock::now()-start).count();\n            if(elapsed_ms>timeLimit) break;\n            int curCycle = (int)(elapsed_ms / cycleLen);\n            if(curCycle != lastCycle){\n                seq = bestSeq;\n                curCost = bestCost;\n                rebuildChosen();\n                lastCycle = curCycle;\n            }\n        }\n        iter++;\n        double cycleT = fmod((double)elapsed_ms, cycleLen) / cycleLen;\n        double temp = t0 * pow(t1/t0, cycleT);\n        \n        int moveType = rng()%20;\n        \n        if(moveType < 2){\n            int idx1 = rng()%50;\n            int idx2;\n            do { idx2 = rng()%50; } while(idx2 == idx1);\n            int old1 = chosen[idx1], old2 = chosen[idx2];\n            int new1, new2;\n            do { new1 = rng()%1000; } while(inChosen[new1]);\n            do { new2 = rng()%1000; } while(inChosen[new2] || new2 == new1);\n            \n            backup = seq;\n            int totalDelta = 0;\n            totalDelta += removeOrderDelta(seq, old1);\n            totalDelta += removeOrderDelta(seq, old2);\n            totalDelta += insertOrderBest(seq, new1);\n            totalDelta += insertOrderBest(seq, new2);\n            \n            bool tentative;\n            if(totalDelta <= 0) tentative = true;\n            else {\n                double prob = exp(-totalDelta/temp);\n                tentative = (rng()&0xFFFFFF)/(double)0x1000000 < prob;\n            }\n            \n            if(tentative){\n                curCost += totalDelta;\n                int d;\n                if((d = twoOptOnce(seq)) < 0) curCost += d;\n                if((d = relocateOnce(seq)) < 0) curCost += d;\n                if((d = twoOptOnce(seq)) < 0) curCost += d;\n                \n                inChosen[old1] = false;\n                inChosen[old2] = false;\n                inChosen[new1] = true;\n                inChosen[new2] = true;\n                chosen[idx1] = new1;\n                chosen[idx2] = new2;\n                \n                if(curCost < bestCost){ bestCost = curCost; bestSeq = seq; }\n            } else {\n                seq = backup;\n            }\n        }\n        else if(moveType < 19){\n            int idx = rng()%50;\n            int oldOrd = chosen[idx];\n            int newOrd;\n            do { newOrd = rng()%1000; } while(inChosen[newOrd]);\n            \n            backup = seq;\n            int remDelta = removeOrderDelta(seq, oldOrd);\n            int insDelta = insertOrderBest(seq, newOrd);\n            int diff0 = remDelta + insDelta;\n            \n            bool tentative = false;\n            if(diff0 <= 0) tentative = true;\n            else {\n                double prob = exp(-diff0/temp);\n                if((rng()&0xFFFFFF)/(double)0x1000000 < prob) tentative = true;\n            }\n            \n            if(tentative){\n                curCost += diff0;\n                int d;\n                if((d = twoOptOnce(seq)) < 0) curCost += d;\n                if((d = relocateOnce(seq)) < 0) curCost += d;\n                if((d = twoOptOnce(seq)) < 0) curCost += d;\n                \n                inChosen[oldOrd] = false;\n                inChosen[newOrd] = true;\n                chosen[idx] = newOrd;\n                \n                if(curCost < bestCost){ bestCost = curCost; bestSeq = seq; }\n            } else {\n                seq = backup;\n            }\n        } else {\n            int idx = rng()%50;\n            int oid = chosen[idx];\n            int remDelta = removeOrderDelta(seq, oid);\n            int insDelta = insertOrderBest(seq, oid);\n            curCost += remDelta + insDelta;\n            int d;\n            if((d = twoOptOnce(seq)) < 0) curCost += d;\n            if((d = relocateOnce(seq)) < 0) curCost += d;\n            if(curCost < bestCost){ bestCost = curCost; bestSeq = seq; }\n        }\n    }\n    \n    seq = bestSeq;\n    curCost = bestCost;\n    rebuildChosen();\n    localOpt();\n    \n    cout << 50;\n    vector<int> ords;\n    set<int> seen;\n    for(int id : seq){\n        if(id>=1 && id<=1000 && !seen.count(id-1)){\n            ords.push_back(id-1);\n            seen.insert(id-1);\n        }\n    }\n    for(int o : ords) cout << \" \" << (o+1);\n    cout << \"\\n\";\n    cout << seq.size();\n    for(int id : seq) cout << \" \" << px(id) << \" \" << py(id);\n    cout << \"\\n\";\n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\n#include <sys/time.h>\nusing namespace std;\n\ndouble get_time(){\n    struct timeval tv;\n    gettimeofday(&tv, NULL);\n    return tv.tv_sec + tv.tv_usec * 1e-6;\n}\n\nstruct DSU {\n    int p[400], r[400];\n    void init(int n){ for(int i=0;i<n;i++){p[i]=i;r[i]=0;} }\n    int f(int x){ while(p[x]!=x){p[x]=p[p[x]];x=p[x];} return x; }\n    int u(int a,int b){ a=f(a);b=f(b); if(a==b)return 0; if(r[a]<r[b])swap(a,b); p[b]=a; if(r[a]==r[b])r[a]++; return 1; }\n};\n\nint N=400, M=1995;\nint X[400], Y[400];\nint U[2000], V[2000], D[2000];\n\nconst int WMAX = 4000;\nint bkt_head[WMAX+2];\nint bkt_next[2100];\nint ea[2100], eb[2100], ew[2100];\nDSU sim;\n\nint main(){\n    double startTime = get_time();\n    double timeLimit = 1.78;\n    double hardStop = 1.90;\n    \n    for(int i=0;i<N;i++) scanf(\"%d %d\", &X[i], &Y[i]);\n    for(int i=0;i<M;i++){\n        scanf(\"%d %d\", &U[i], &V[i]);\n        double dx=X[U[i]]-X[V[i]], dy=Y[U[i]]-Y[V[i]];\n        D[i] = (int)round(sqrt(dx*dx+dy*dy));\n        if(D[i]<1) D[i]=1;\n    }\n    \n    vector<tuple<int,int,int>> adoptedEdges;\n    DSU glob; glob.init(N);\n    \n    uint64_t rng_state = 88172645463325252ULL;\n    auto rnd = [&]() -> uint32_t {\n        rng_state ^= rng_state << 13;\n        rng_state ^= rng_state >> 7;\n        rng_state ^= rng_state << 17;\n        return (uint32_t)rng_state;\n    };\n    \n    for(int i=0;i<M;i++){\n        int l; scanf(\"%d\", &l);\n        \n        if(glob.f(U[i]) == glob.f(V[i])){\n            printf(\"0\\n\"); fflush(stdout);\n            continue;\n        }\n        \n        double nowElapsed = get_time() - startTime;\n        if(nowElapsed > hardStop){\n            bool adopt = (l < (int)(1.8 * D[i]));\n            if(adopt){\n                printf(\"1\\n\");\n                adoptedEdges.push_back({l, U[i], V[i]});\n                glob.u(U[i], V[i]);\n            } else {\n                printf(\"0\\n\");\n            }\n            fflush(stdout);\n            continue;\n        }\n        \n        int ui = U[i], vi = V[i];\n        \n        int cnt = 0;\n        int maxW = 0;\n        for(auto& [w,a,b]: adoptedEdges){\n            ew[cnt]=w; ea[cnt]=a; eb[cnt]=b; cnt++;\n            if(w>maxW) maxW=w;\n        }\n        int staticCnt = cnt;\n        \n        for(int j=i+1;j<M;j++){\n            ea[cnt]=U[j]; eb[cnt]=V[j]; cnt++;\n        }\n        \n        double remTime = timeLimit - nowElapsed;\n        int remEdges = M - i;\n        double perEdgeBudget = remTime > 0 ? remTime / remEdges : 0.00001;\n        double maxEdgeBudget = perEdgeBudget * 5;\n        \n        const int MAX_TRIALS = 500;\n        const int MIN_TRIALS = 12;\n        long long sumAlt = 0;\n        long long sumSq = 0;\n        int done = 0;\n        const int BIG = 10000;\n        double edgeStart = get_time();\n        \n        for(int t=0; t<MAX_TRIALS; t++){\n            int tmpMax = maxW;\n            for(int k=staticCnt; k<cnt; k++){\n                int j = i+1 + (k - staticCnt);\n                int range = 2*D[j]+1;\n                int w = D[j] + (int)(rnd() % (uint32_t)range);\n                ew[k] = w;\n                if(w > tmpMax) tmpMax = w;\n            }\n            \n            for(int w=0; w<=tmpMax; w++) bkt_head[w] = -1;\n            for(int k=0; k<cnt; k++){\n                bkt_next[k] = bkt_head[ew[k]];\n                bkt_head[ew[k]] = k;\n            }\n            \n            sim.init(N);\n            int altCost = BIG;\n            for(int w=0; w<=tmpMax; w++){\n                int head = bkt_head[w];\n                if(head == -1) continue;\n                for(int k=head; k!=-1; k=bkt_next[k]){\n                    sim.u(ea[k], eb[k]);\n                }\n                if(sim.f(ui) == sim.f(vi)){\n                    altCost = w;\n                    break;\n                }\n            }\n            \n            sumAlt += altCost;\n            sumSq += (long long)altCost * altCost;\n            done++;\n            \n            if(done >= MIN_TRIALS){\n                double mean = (double)sumAlt / done;\n                double denom = (double)(done > 1 ? done - 1 : 1);\n                double var = ((double)sumSq - (double)sumAlt * (double)sumAlt / done) / denom;\n                if(var < 0) var = 0;\n                double se = sqrt(var / done);\n                double diff = fabs(mean - l);\n                if(diff > 2.5 * se) break;\n                \n                if((done & 3) == 0){\n                    double glbNow = get_time();\n                    if(glbNow - startTime > hardStop) break;\n                    if(glbNow - edgeStart > maxEdgeBudget) break;\n                }\n            }\n        }\n        \n        double avgAlt = (double)sumAlt / done;\n        bool adopt = ((double)l < avgAlt);\n        \n        if(adopt){\n            printf(\"1\\n\");\n            adoptedEdges.push_back({l, U[i], V[i]});\n            glob.u(U[i], V[i]);\n        } else {\n            printf(\"0\\n\");\n        }\n        fflush(stdout);\n    }\n    \n    return 0;\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint pt[25];\nint hx[15], hy[15];\nint grid[32][32];\nvector<pair<int,int>> pets;\n\nint dx4[] = {-1,1,0,0};\nint dy4[] = {0,0,-1,1};\nchar mvch[] = {'U','D','L','R'};\nchar wlch[] = {'u','d','l','r'};\n\nbool inb(int x, int y) { return x>=1 && x<=30 && y>=1 && y<=30; }\n\nbool canWall(int x, int y) {\n    if (!inb(x,y)) return false;\n    if (grid[x][y]) return false;\n    for (auto& p : pets) if (p.first==x && p.second==y) return false;\n    for (int i=0;i<M;i++) if (hx[i]==x && hy[i]==y) return false;\n    for (int d=0;d<4;d++) {\n        int nx=x+dx4[d], ny=y+dy4[d];\n        for (auto& p : pets) if (p.first==nx && p.second==ny) return false;\n    }\n    return true;\n}\n\nvoid bfsExtra(int sx, int sy, vector<vector<int>>& dist, const vector<pair<int,int>>& extra) {\n    dist.assign(32, vector<int>(32, -1));\n    static bool eb[32][32];\n    memset(eb, 0, sizeof(eb));\n    for (auto& w : extra) if (inb(w.first,w.second)) eb[w.first][w.second] = true;\n    if (!inb(sx,sy) || grid[sx][sy] || eb[sx][sy]) return;\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+dx4[d], ny=y+dy4[d];\n            if (!inb(nx,ny)||grid[nx][ny]||dist[nx][ny]!=-1) continue;\n            if (eb[nx][ny]) continue;\n            dist[nx][ny]=dist[x][y]+1;\n            q.push({nx,ny});\n        }\n    }\n}\n\nint TOP_WALL = 11;\nint BOT_WALL = 20;\n\nint main(){\n    cin >> N;\n    pets.resize(N);\n    for (int i=0;i<N;i++){\n        int x,y,t; cin >> x >> y >> t;\n        pets[i]={x,y}; pt[i]=t;\n    }\n    cin >> M;\n    for (int i=0;i<M;i++) cin >> hx[i] >> hy[i];\n    memset(grid,0,sizeof(grid));\n    \n    vector<int> topH, botH;\n    for (int i=0;i<M;i++){\n        if (hx[i] <= 15) topH.push_back(i);\n        else botH.push_back(i);\n    }\n    if (topH.empty() && !botH.empty()) {\n        int half = (botH.size()+1)/2;\n        for (int k=0;k<half;k++) topH.push_back(botH[k]);\n        botH.erase(botH.begin(), botH.begin()+half);\n    } else if (botH.empty() && !topH.empty()) {\n        int half = (topH.size()+1)/2;\n        for (int k=0;k<half;k++) botH.push_back(topH[k]);\n        topH.erase(topH.begin(), topH.begin()+half);\n    }\n    \n    sort(topH.begin(), topH.end(), [](int a, int b){return hy[a]<hy[b];});\n    sort(botH.begin(), botH.end(), [](int a, int b){return hy[a]<hy[b];});\n    \n    vector<vector<tuple<int,int,char,bool>>> tasks(M);\n    \n    auto assignGroup = [&](vector<int>& group, int wallRow, int standDir) {\n        int n = group.size();\n        if (n == 0) return;\n        \n        int P = (n <= 1) ? n : 2;\n        if (P == 0) P = 1;\n        \n        vector<vector<int>> penHumans(P);\n        for (int k = 0; k < P; k++){\n            int s = k * n / P, e = (k + 1) * n / P;\n            for (int j = s; j < e; j++) penHumans[k].push_back(group[j]);\n        }\n        \n        vector<pair<int,int>> penCol(P);\n        for (int k = 0; k < P; k++){\n            penCol[k] = {1 + k*30/P, (k+1)*30/P};\n        }\n        \n        for (int k = 0; k < P; k++){\n            int cs_p = penCol[k].first, ce_p = penCol[k].second;\n            int nh = penHumans[k].size();\n            if (nh == 0) continue;\n            int width = ce_p - cs_p + 1;\n            \n            for (int j = 0; j < nh; j++){\n                int hcs = cs_p + j * width / nh;\n                int hce = cs_p + (j+1) * width / nh - 1;\n                int hi = penHumans[k][j];\n                int sr = wallRow + standDir;\n                char dir = (standDir == -1) ? 'd' : 'u';\n                \n                bool isDoorBuilder = (j == nh - 1);\n                \n                vector<int> cols;\n                if (abs(hy[hi] - hcs) < abs(hy[hi] - hce)){\n                    for (int c = hcs; c <= hce; c++) cols.push_back(c);\n                } else {\n                    for (int c = hce; c >= hcs; c--) cols.push_back(c);\n                }\n                \n                int doorCol = -1;\n                if (isDoorBuilder){\n                    doorCol = cols.back();\n                }\n                \n                for (int c : cols){\n                    bool isDoor = (c == doorCol);\n                    tasks[hi].push_back({sr, c, dir, isDoor});\n                }\n            }\n        }\n        \n        for (int k = 0; k < P - 1; k++){\n            int ce_k = penCol[k].second;\n            if (ce_k <= 0 || ce_k > 30) continue;\n            if (penHumans[k].empty()) continue;\n            int hi = penHumans[k].back();\n            int dividerCol = ce_k;\n            int standCol = dividerCol - 1;\n            if (standCol < 1) continue;\n            char dir = 'r';\n            int r_start, r_end, r_step;\n            if (standDir == -1) {\n                r_start = wallRow - 1; r_end = 1; r_step = -1;\n            } else {\n                r_start = wallRow + 1; r_end = 30; r_step = 1;\n            }\n            for (int r = r_start; r != r_end + r_step; r += r_step){\n                tasks[hi].push_back({r, standCol, dir, false});\n            }\n        }\n    };\n    \n    assignGroup(topH, TOP_WALL, -1);\n    assignGroup(botH, BOT_WALL, +1);\n    \n    vector<int> taskIdx(M, 0);\n    \n    auto wallPos = [&](int sr, int sc, char dir) -> pair<int,int> {\n        if (dir == 'u') return {sr-1, sc};\n        if (dir == 'd') return {sr+1, sc};\n        if (dir == 'l') return {sr, sc-1};\n        return {sr, sc+1};\n    };\n    \n    auto getCurrentTask = [&](int i) -> int {\n        while (taskIdx[i] < (int)tasks[i].size()){\n            auto [sr, sc, dir, isDoor] = tasks[i][taskIdx[i]];\n            auto [wr, wc] = wallPos(sr, sc, dir);\n            if (grid[wr][wc]) { taskIdx[i]++; continue; }\n            break;\n        }\n        if (taskIdx[i] >= (int)tasks[i].size()) return -1;\n        \n        auto [sr, sc, dir, isDoor] = tasks[i][taskIdx[i]];\n        if (!isDoor) return taskIdx[i];\n        \n        for (int j = taskIdx[i]+1; j < (int)tasks[i].size(); j++){\n            auto [sr2, sc2, dir2, isDoor2] = tasks[i][j];\n            auto [wr2, wc2] = wallPos(sr2, sc2, dir2);\n            if (!grid[wr2][wc2] && !isDoor2){\n                return j;\n            }\n        }\n        return taskIdx[i];\n    };\n    \n    for (int turn=0; turn<300; turn++){\n        string action(M,'.');\n        vector<pair<int,int>> newWalls;\n        vector<pair<int,int>> nextPos(M);\n        for (int i=0;i<M;i++) nextPos[i] = {hx[i], hy[i]};\n        \n        vector<bool> decided(M, false);\n        vector<int> curT(M, -1);\n        for (int i=0;i<M;i++) curT[i] = getCurrentTask(i);\n        \n        int maxPetsAllowed;\n        if (turn < 270) maxPetsAllowed = 0;\n        else if (turn < 290) maxPetsAllowed = 1;\n        else maxPetsAllowed = 999;\n        \n        for (int i=0;i<M;i++){\n            int cx=hx[i], cy=hy[i];\n            int t = curT[i];\n            if (t == -1) continue;\n            auto [sr, sc, dir, isDoor] = tasks[i][t];\n            auto [wr, wc] = wallPos(sr, sc, dir);\n            \n            if (cx == sr && cy == sc){\n                if (isDoor){\n                    vector<pair<int,int>> extra = {{wr, wc}};\n                    vector<vector<int>> dist;\n                    bfsExtra(cx, cy, dist, extra);\n                    int petsInRegion = 0;\n                    for (auto& p : pets) if (inb(p.first,p.second) && dist[p.first][p.second] != -1) petsInRegion++;\n                    \n                    bool shouldBuild = (petsInRegion <= maxPetsAllowed);\n                    \n                    if (shouldBuild && canWall(wr, wc)){\n                        action[i] = dir;\n                        newWalls.push_back({wr, wc});\n                        decided[i] = true;\n                    } else {\n                        action[i]='.';\n                        decided[i] = true;\n                    }\n                } else {\n                    if (canWall(wr, wc)){\n                        action[i] = dir;\n                        newWalls.push_back({wr, wc});\n                        decided[i] = true;\n                    } else {\n                        action[i]='.';\n                        decided[i] = true;\n                    }\n                }\n            }\n        }\n        \n        auto isPlannedWall = [&](int x, int y) {\n            for (auto& w : newWalls) if (w.first==x && w.second==y) return true;\n            return false;\n        };\n        auto isOtherDest = [&](int x, int y, int skip) {\n            for (int i=0;i<M;i++) if (i!=skip && nextPos[i].first==x && nextPos[i].second==y) return true;\n            return false;\n        };\n        \n        for (int i=0;i<M;i++){\n            if (decided[i]) continue;\n            int cx=hx[i], cy=hy[i];\n            int t = curT[i];\n            if (t == -1) continue;\n            auto [sr, sc, dir, isDoor] = tasks[i][t];\n            \n            vector<vector<int>> dist(32, vector<int>(32, -1));\n            if (inb(sr,sc) && !grid[sr][sc] && !isPlannedWall(sr,sc)){\n                queue<pair<int,int>> q;\n                dist[sr][sc]=0; q.push({sr,sc});\n                while(!q.empty()){\n                    auto [x,y]=q.front(); q.pop();\n                    for (int d=0;d<4;d++){\n                        int nx=x+dx4[d], ny=y+dy4[d];\n                        if (!inb(nx,ny)||grid[nx][ny]||dist[nx][ny]!=-1) continue;\n                        if (isPlannedWall(nx,ny)) continue;\n                        dist[nx][ny]=dist[x][y]+1;\n                        q.push({nx,ny});\n                    }\n                }\n            }\n            \n            bool moved = false;\n            if (dist[cx][cy] > 0){\n                for (int d=0;d<4;d++){\n                    int nx=cx+dx4[d], ny=cy+dy4[d];\n                    if (!inb(nx,ny)||grid[nx][ny]) continue;\n                    if (isPlannedWall(nx,ny)) continue;\n                    if (dist[nx][ny]==dist[cx][cy]-1 && !isOtherDest(nx,ny,i)){\n                        action[i]=mvch[d];\n                        nextPos[i]={nx,ny};\n                        moved = true;\n                        decided[i] = true;\n                        break;\n                    }\n                }\n            }\n            \n            if (!moved && dist[cx][cy] == -1) {\n                if (t == taskIdx[i] && !isDoor){\n                    taskIdx[i]++;\n                }\n            }\n        }\n        \n        for (int i=0;i<M;i++){\n            char a = action[i];\n            if (a=='U'||a=='D'||a=='L'||a=='R'){\n                if (isPlannedWall(nextPos[i].first, nextPos[i].second)){\n                    action[i] = '.';\n                    nextPos[i] = {hx[i], hy[i]};\n                }\n            }\n        }\n        \n        cout << action << endl;\n        cout.flush();\n        \n        for (int i=0;i<M;i++){\n            char a = action[i];\n            if (a=='U'||a=='D'||a=='L'||a=='R'){\n                int d = (a=='U')?0:(a=='D')?1:(a=='L')?2:3;\n                hx[i]+=dx4[d]; hy[i]+=dy4[d];\n            }\n        }\n        for (auto& w : newWalls) grid[w.first][w.second]=1;\n        \n        for (int i=0;i<N;i++){\n            string s; cin >> s;\n            int x=pets[i].first, y=pets[i].second;\n            for (char c : s){\n                if (c=='U') x--;\n                else if (c=='D') x++;\n                else if (c=='L') y--;\n                else if (c=='R') y++;\n            }\n            pets[i]={x,y};\n        }\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si,sj,ti,tj;\ndouble p;\nint H[20][19], V[19][20];\nint nextIdx[4][400];\nint dirOf[256];\nint start_idx_g, goal_idx_g;\ndouble pp_g, q_g;\ndouble wStay[4][400], wMoveW[4][400];\nint bfsDistFromGoal[400];\n\nvoid buildTransitions(){\n    for(int i=0;i<20;i++)for(int j=0;j<20;j++){\n        int idx=i*20+j;\n        if(i>0 && V[i-1][j]==0) nextIdx[0][idx]=(i-1)*20+j; else nextIdx[0][idx]=idx;\n        if(i<19 && V[i][j]==0) nextIdx[1][idx]=(i+1)*20+j; else nextIdx[1][idx]=idx;\n        if(j>0 && H[i][j-1]==0) nextIdx[2][idx]=i*20+(j-1); else nextIdx[2][idx]=idx;\n        if(j<19 && H[i][j]==0) nextIdx[3][idx]=i*20+(j+1); else nextIdx[3][idx]=idx;\n    }\n    dirOf[(int)'U']=0; dirOf[(int)'D']=1; dirOf[(int)'L']=2; dirOf[(int)'R']=3;\n}\n\nvoid buildWeights(){\n    for(int d=0;d<4;d++){\n        for(int idx=0;idx<400;idx++){\n            if(nextIdx[d][idx]==idx){\n                wStay[d][idx]=1.0;\n                wMoveW[d][idx]=0.0;\n            } else {\n                wStay[d][idx]=pp_g;\n                wMoveW[d][idx]=q_g;\n            }\n        }\n    }\n}\n\nvoid computeBfsFromGoal(){\n    for(int i=0;i<400;i++) bfsDistFromGoal[i]=1000000;\n    queue<int> q;\n    q.push(goal_idx_g); bfsDistFromGoal[goal_idx_g]=0;\n    while(!q.empty()){\n        int idx=q.front(); q.pop();\n        for(int d=0;d<4;d++){\n            int nxi=nextIdx[d][idx];\n            if(nxi!=idx && bfsDistFromGoal[nxi]>bfsDistFromGoal[idx]+1){\n                bfsDistFromGoal[nxi]=bfsDistFromGoal[idx]+1;\n                q.push(nxi);\n            }\n        }\n    }\n}\n\ndouble evalScore(const string& s){\n    static double dist[400], nd[400];\n    for(int i=0;i<400;i++) dist[i]=0;\n    dist[start_idx_g]=1.0;\n    if(start_idx_g==goal_idx_g) return 400.0;\n    double score=0;\n    int L=s.size();\n    for(int t=0;t<L;t++){\n        int d=dirOf[(int)(unsigned char)s[t]];\n        const int* nxt=nextIdx[d];\n        const double* ws=wStay[d];\n        const double* wm=wMoveW[d];\n        for(int i=0;i<400;i++) nd[i]=0;\n        for(int idx=0;idx<400;idx++){\n            double dv=dist[idx];\n            if(dv==0) continue;\n            nd[idx] += dv * ws[idx];\n            nd[nxt[idx]] += dv * wm[idx];\n        }\n        double arrived = nd[goal_idx_g];\n        score += arrived * (400 - t);\n        nd[goal_idx_g]=0;\n        memcpy(dist,nd,sizeof(dist));\n    }\n    return score;\n}\n\nstring greedyConstruct(int maxLen, double alpha){\n    static double dist[400], nd[400], best_nd[400];\n    for(int i=0;i<400;i++) dist[i]=0;\n    dist[start_idx_g]=1.0;\n    if(start_idx_g==goal_idx_g) return \"\";\n    string result;\n    for(int t=0;t<maxLen;t++){\n        double sum_rem=0;\n        for(int i=0;i<400;i++) sum_rem+=dist[i];\n        if(sum_rem<1e-6) break;\n        int bestD=-1;\n        double bestVal=-1e18;\n        for(int d=0;d<4;d++){\n            const int* nxt=nextIdx[d];\n            const double* ws=wStay[d];\n            const double* wm=wMoveW[d];\n            for(int i=0;i<400;i++) nd[i]=0;\n            for(int idx=0;idx<400;idx++){\n                double dv=dist[idx];\n                if(dv==0) continue;\n                nd[idx] += dv * ws[idx];\n                nd[nxt[idx]] += dv * wm[idx];\n            }\n            double arrived = nd[goal_idx_g];\n            double step_score = arrived * (400 - t);\n            double val = step_score;\n            for(int i=0;i<400;i++){\n                if(i==goal_idx_g || nd[i]==0) continue;\n                double future_turn = (t+1) + bfsDistFromGoal[i] * alpha;\n                if(future_turn < 400){\n                    val += nd[i] * (400 - future_turn);\n                }\n            }\n            if(val > bestVal){\n                bestVal = val;\n                bestD = d;\n                memcpy(best_nd, nd, sizeof(nd));\n            }\n        }\n        if(bestD<0) break;\n        char chosen = \"UDLR\"[bestD];\n        result += chosen;\n        best_nd[goal_idx_g] = 0;\n        memcpy(dist, best_nd, sizeof(dist));\n    }\n    return result;\n}\n\nbool canMove(int i,int j,char c){\n    int idx=i*20+j;\n    return nextIdx[dirOf[(int)(unsigned char)c]][idx]!=idx;\n}\npair<int,int> moveXY(int i,int j,char c){\n    int idx=i*20+j;\n    int nxi=nextIdx[dirOf[(int)(unsigned char)c]][idx];\n    return {nxi/20, nxi%20};\n}\n\nvector<string> findPaths(int maxPaths, mt19937& rng){\n    vector<string> paths;\n    set<string> seen;\n    string dirs=\"UDLR\";\n    auto bfsPath=[&](string order)->string{\n        vector<vector<int>> bd(20,vector<int>(20,-1));\n        vector<vector<pair<int,int>>> par(20,vector<pair<int,int>>(20,{-1,-1}));\n        vector<vector<char>> pc(20,vector<char>(20,0));\n        queue<pair<int,int>> q;\n        q.push({si,sj}); bd[si][sj]=0;\n        while(!q.empty()){\n            auto [i,j]=q.front(); q.pop();\n            for(char c:order){\n                if(canMove(i,j,c)){\n                    auto [ni,nj]=moveXY(i,j,c);\n                    if(bd[ni][nj]==-1){\n                        bd[ni][nj]=bd[i][j]+1;\n                        par[ni][nj]={i,j};\n                        pc[ni][nj]=c;\n                        q.push({ni,nj});\n                    }\n                }\n            }\n        }\n        if(bd[ti][tj]==-1) return \"\";\n        string path;\n        int ci=ti,cj=tj;\n        while(!(ci==si&&cj==sj)){\n            path+=pc[ci][cj];\n            auto [pi,pj]=par[ci][cj];\n            ci=pi; cj=pj;\n        }\n        reverse(path.begin(),path.end());\n        return path;\n    };\n    string p1=bfsPath(\"UDLR\");\n    paths.push_back(p1); seen.insert(p1);\n    int shortestLen=p1.size();\n    for(int attempt=0; attempt<800 && (int)paths.size()<maxPaths; attempt++){\n        string d=dirs;\n        shuffle(d.begin(),d.end(),rng);\n        string path=bfsPath(d);\n        if(!path.empty() && (int)path.size() <= shortestLen+8 && !seen.count(path)){\n            paths.push_back(path);\n            seen.insert(path);\n        }\n    }\n    return paths;\n}\n\nchrono::steady_clock::time_point g_start;\nlong long elapsedMs(){\n    auto now=chrono::steady_clock::now();\n    return (long long)chrono::duration_cast<chrono::milliseconds>(now-g_start).count();\n}\n\nstring g_best;\ndouble g_bestScore;\nstring dirs=\"UDLR\";\n\nvoid localSearch(string& cur, double& curScore, long long timeLimit){\n    bool improved=true;\n    while(improved && elapsedMs()<timeLimit){\n        improved=false;\n        for(int pos=0;pos<(int)cur.size() && elapsedMs()<timeLimit;pos++){\n            char orig=cur[pos];\n            char bestC=orig;\n            double bestSc=curScore;\n            for(char c : dirs){\n                if(c==orig) continue;\n                cur[pos]=c;\n                double sc=evalScore(cur);\n                if(sc>bestSc+1e-9){bestSc=sc; bestC=c;}\n            }\n            cur[pos]=bestC;\n            if(bestC!=orig){curScore=bestSc; improved=true;}\n        }\n        for(int pos=0;pos+1<(int)cur.size() && elapsedMs()<timeLimit;pos++){\n            if(cur[pos]==cur[pos+1]) continue;\n            swap(cur[pos],cur[pos+1]);\n            double sc=evalScore(cur);\n            if(sc>curScore+1e-9){curScore=sc; improved=true;}\n            else swap(cur[pos],cur[pos+1]);\n        }\n        for(int pos=0;pos<(int)cur.size() && elapsedMs()<timeLimit;pos++){\n            string cand=cur;\n            cand.erase(cand.begin()+pos);\n            double sc=evalScore(cand);\n            if(sc>curScore+1e-9){curScore=sc; cur=cand; improved=true; pos--;}\n        }\n        for(int pos=0;pos<=(int)cur.size() && (int)cur.size()<200 && elapsedMs()<timeLimit;pos++){\n            char bestC=0;\n            double bestSc=curScore;\n            for(char c : dirs){\n                string cand=cur;\n                cand.insert(cand.begin()+pos,c);\n                double sc=evalScore(cand);\n                if(sc>bestSc+1e-9){bestSc=sc; bestC=c;}\n            }\n            if(bestC){\n                cur.insert(cur.begin()+pos,bestC);\n                curScore=bestSc;\n                improved=true;\n            }\n        }\n        for(int pos=0;pos+1<(int)cur.size() && elapsedMs()<timeLimit;pos++){\n            string cand=cur;\n            cand.erase(cand.begin()+pos, cand.begin()+pos+2);\n            double sc=evalScore(cand);\n            if(sc>curScore+1e-9){curScore=sc; cur=cand; improved=true; pos--;}\n        }\n        for(int pos=0;pos<=(int)cur.size() && (int)cur.size()+2<=200 && elapsedMs()<timeLimit;pos++){\n            char bestC=0;\n            double bestSc=curScore;\n            for(char c : dirs){\n                string cand=cur;\n                cand.insert(pos, 2, c);\n                double sc=evalScore(cand);\n                if(sc>bestSc+1e-9){bestSc=sc; bestC=c;}\n            }\n            if(bestC){\n                cur.insert(pos,2,bestC);\n                curScore=bestSc;\n                improved=true;\n            }\n        }\n    }\n    if(curScore > g_bestScore){\n        g_bestScore = curScore;\n        g_best = cur;\n    }\n}\n\nvoid doPerturbAndSearch(mt19937& rng, long long endTime){\n    int stuckCount=0;\n    while(elapsedMs() < endTime){\n        string cur = g_best;\n        double curScore = g_bestScore;\n        int strength = 3 + stuckCount;\n        if(strength > 12) strength = 12;\n        int numPerturb = strength + (int)(rng()%3);\n        for(int i=0;i<numPerturb;i++){\n            if(cur.empty()) break;\n            int op = (int)(rng()%5);\n            if(op==0){\n                int pos=(int)(rng()%cur.size());\n                cur[pos]=dirs[rng()%4];\n            } else if(op==1 && (int)cur.size()>=2){\n                int pos=(int)(rng()%(cur.size()-1));\n                swap(cur[pos],cur[pos+1]);\n            } else if(op==2 && cur.size()>1){\n                int pos=(int)(rng()%cur.size());\n                cur.erase(cur.begin()+pos);\n            } else if(op==3 && (int)cur.size()<200){\n                int pos=(int)(rng()%(cur.size()+1));\n                cur.insert(cur.begin()+pos,dirs[rng()%4]);\n            } else {\n                if((int)cur.size()+2<=200){\n                    int pos=(int)(rng()%(cur.size()+1));\n                    char c=dirs[rng()%4];\n                    cur.insert(pos, 2, c);\n                }\n            }\n        }\n        curScore = evalScore(cur);\n        long long localBudget = elapsedMs() + 250;\n        if(localBudget > endTime) localBudget = endTime;\n        double prevBest = g_bestScore;\n        localSearch(cur, curScore, localBudget);\n        if(g_bestScore > prevBest + 1e-6){\n            stuckCount = 0;\n        } else {\n            stuckCount++;\n        }\n    }\n}\n\nint main(){\n    cin>>si>>sj>>ti>>tj>>p;\n    for(int i=0;i<20;i++){\n        string s; cin>>s;\n        for(int j=0;j<19;j++) H[i][j]=s[j]-'0';\n    }\n    for(int i=0;i<19;i++){\n        string s; cin>>s;\n        for(int j=0;j<20;j++) V[i][j]=s[j]-'0';\n    }\n    buildTransitions();\n    start_idx_g = si*20+sj;\n    goal_idx_g = ti*20+tj;\n    pp_g = p; q_g = 1-p;\n    buildWeights();\n    computeBfsFromGoal();\n    \n    g_start = chrono::steady_clock::now();\n    \n    mt19937 rng(42);\n    vector<string> paths = findPaths(25, rng);\n    \n    vector<pair<double,string>> candidates;\n    for(auto& path : paths){\n        int L=path.size();\n        if(L==0) continue;\n        for(int k=1; k*L<=200; k++){\n            string cand;\n            for(char c:path) for(int r=0;r<k;r++) cand+=c;\n            candidates.push_back({evalScore(cand), cand});\n        }\n        for(int k=1; k*L<=200; k++){\n            string cand;\n            for(char c:path) for(int r=0;r<k;r++) cand+=c;\n            while((int)cand.size()<200) cand+=path.back();\n            candidates.push_back({evalScore(cand), cand});\n        }\n    }\n    sort(candidates.begin(),candidates.end(),[](auto&a,auto&b){return a.first>b.first;});\n    \n    g_best = candidates[0].second;\n    g_bestScore = candidates[0].first;\n    \n    // Phase 1: Local search on top BFS candidate\n    {\n        string cur = g_best;\n        double curScore = g_bestScore;\n        localSearch(cur, curScore, 500);\n    }\n    \n    // Phase 2: Local search on top-2 BFS candidates\n    for(int ci=1; ci<3 && ci<(int)candidates.size() && elapsedMs()<700; ci++){\n        if(candidates[ci].first < g_bestScore * 0.7) break;\n        string cur = candidates[ci].second;\n        double curScore = candidates[ci].first;\n        long long budget = elapsedMs() + 150;\n        if(budget>700) budget=700;\n        localSearch(cur, curScore, budget);\n    }\n    \n    // Phase 2.5: Greedy candidates (3 alphas, top 2 get local search)\n    vector<string> greedyCands;\n    for(double alpha : {1.0/(1-p), 1.2, 1.5}){\n        string g1 = greedyConstruct(200, alpha);\n        if(!g1.empty()) greedyCands.push_back(g1);\n    }\n    sort(greedyCands.begin(), greedyCands.end(), [](const string& a, const string& b){\n        return evalScore(a) > evalScore(b);\n    });\n    for(int gi=0; gi<(int)greedyCands.size() && gi<2 && elapsedMs()<950; gi++){\n        string cur = greedyCands[gi];\n        double curScore = evalScore(cur);\n        long long budget = elapsedMs() + 120;\n        if(budget > 950) budget = 950;\n        localSearch(cur, curScore, budget);\n    }\n    \n    // Phase 3: Perturbation restarts\n    mt19937 rng2(42);\n    doPerturbAndSearch(rng2, 1450);\n    \n    mt19937 rng3(7777);\n    doPerturbAndSearch(rng3, 1850);\n    \n    // Final polish\n    {\n        string cur = g_best;\n        double curScore = g_bestScore;\n        localSearch(cur, curScore, 1990);\n    }\n    \n    cout<<g_best<<endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic const int to_dir[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\nstatic const int di[4] = {0, -1, 0, 1};\nstatic const int dj[4] = {-1, 0, 1, 0};\nstatic const int rot1[8] = {1, 2, 3, 0, 5, 4, 7, 6};\n\nstatic int tiles[30][30];\nstatic int visited[30][30][4];\nstatic int gen = 0;\n\nstruct EvalRes {\n    long long score;\n    long long sumSq;\n};\n\ninline EvalRes evaluate() {\n    gen++;\n    int L1 = 0, L2 = 0;\n    long long sumSq = 0;\n    for (int si = 0; si < 30; si++) {\n        for (int sj = 0; sj < 30; sj++) {\n            for (int sd = 0; sd < 4; sd++) {\n                if (visited[si][sj][sd] == gen) continue;\n                int i = si, j = sj, d = sd;\n                int len = 0;\n                while (true) {\n                    if (visited[i][j][d] == gen) break;\n                    visited[i][j][d] = gen;\n                    int d2 = to_dir[tiles[i][j]][d];\n                    if (d2 < 0) break;\n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if ((unsigned)ni >= 30 || (unsigned)nj >= 30) break;\n                    int nd = d2 ^ 2;\n                    len++;\n                    if (ni == si && nj == sj && nd == sd) {\n                        if (len > L1) { L2 = L1; L1 = len; }\n                        else if (len > L2) L2 = len;\n                        sumSq += (long long)len * len;\n                        break;\n                    }\n                    i = ni; j = nj; d = nd;\n                }\n            }\n        }\n    }\n    return {(long long)L1 * L2, sumSq};\n}\n\nstatic int rot[30][30];\nstatic int bestRot[30][30];\nstatic int inputG[30][30];\n\ninline void applyRot(int i, int j, int r) {\n    rot[i][j] = r;\n    int t = inputG[i][j];\n    for (int k = 0; k < r; k++) t = rot1[t];\n    tiles[i][j] = t;\n}\n\nstatic uint64_t xrand_state = 0x12345678abcdef01ULL;\ninline uint64_t xrand() {\n    uint64_t x = xrand_state;\n    x ^= x << 13;\n    x ^= x >> 7;\n    x ^= x << 17;\n    xrand_state = x;\n    return x;\n}\ninline double frand() {\n    return (double)(xrand() & 0xFFFFFFFFULL) / (double)0x100000000ULL;\n}\n\nint main() {\n    for (int i = 0; i < 30; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < 30; j++) inputG[i][j] = s[j]-'0';\n    }\n    \n    long long bestScore = 0;\n    long long bestSumSq = 0;\n    auto start = chrono::steady_clock::now();\n    double TL_SA = 1.80;\n    double TL_FINAL = 1.94;\n    \n    int restart = 0;\n    bool done = false;\n    while (!done) {\n        auto now = chrono::steady_clock::now();\n        double elapsedTotal = chrono::duration<double>(now-start).count();\n        if (elapsedTotal > TL_SA - 0.02) break;\n        \n        restart++;\n        for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) {\n            int r = (restart == 1) ? 0 : (int)(xrand()%4);\n            applyRot(i, j, r);\n        }\n        \n        auto cur = evaluate();\n        if (cur.score > bestScore || (cur.score == bestScore && cur.sumSq > bestSumSq)) {\n            bestScore = cur.score;\n            bestSumSq = cur.sumSq;\n            memcpy(bestRot, rot, sizeof(rot));\n        }\n        \n        double restartBudget = 0.90;\n        if (TL_SA - elapsedTotal < restartBudget) restartBudget = TL_SA - elapsedTotal;\n        if (restartBudget < 0.05) break;\n        double restartStart = elapsedTotal;\n        \n        double T0 = 2000.0, T1 = 1.0;\n        int iter = 0;\n        double localElapsed = 0;\n        double scoreWeight = 0.0;\n        \n        long long curProxyVal = cur.sumSq;\n        \n        while (true) {\n            iter++;\n            if ((iter & 255) == 0) {\n                double e = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n                localElapsed = e - restartStart;\n                if (e > TL_SA) { done = true; break; }\n                if (localElapsed > restartBudget) break;\n                double prog = localElapsed / restartBudget;\n                if (prog > 1) prog = 1;\n                if (prog < 0.5) scoreWeight = 0.0;\n                else {\n                    double r = (prog - 0.5) * 2.0;\n                    scoreWeight = 100.0 * r * r;\n                }\n                curProxyVal = cur.sumSq + (long long)(scoreWeight * (double)cur.score);\n            }\n            double progress = localElapsed / restartBudget;\n            if (progress > 1) progress = 1;\n            double T = T0 * pow(T1/T0, progress);\n            \n            int mtype = (int)(xrand()%10);\n            if (mtype < 7) {\n                int i = (int)(xrand()%30), j = (int)(xrand()%30);\n                int oldR = rot[i][j];\n                int newR = (oldR + 1 + (int)(xrand()%3)) & 3;\n                applyRot(i, j, newR);\n                auto nw = evaluate();\n                long long nwProxy = nw.sumSq + (long long)(scoreWeight * (double)nw.score);\n                long long delta = nwProxy - curProxyVal;\n                if (delta >= 0 || frand() < exp((double)delta/T)) {\n                    cur = nw;\n                    curProxyVal = nwProxy;\n                    if (nw.score > bestScore || (nw.score == bestScore && nw.sumSq > bestSumSq)) {\n                        bestScore = nw.score;\n                        bestSumSq = nw.sumSq;\n                        memcpy(bestRot, rot, sizeof(rot));\n                    }\n                } else {\n                    applyRot(i, j, oldR);\n                }\n            } else {\n                int i1 = (int)(xrand()%30), j1 = (int)(xrand()%30);\n                int i2 = (int)(xrand()%30), j2 = (int)(xrand()%30);\n                int oldR1 = rot[i1][j1], oldR2 = rot[i2][j2];\n                int newR1 = (oldR1 + 1 + (int)(xrand()%3)) & 3;\n                int newR2 = (oldR2 + 1 + (int)(xrand()%3)) & 3;\n                applyRot(i1, j1, newR1);\n                applyRot(i2, j2, newR2);\n                auto nw = evaluate();\n                long long nwProxy = nw.sumSq + (long long)(scoreWeight * (double)nw.score);\n                long long delta = nwProxy - curProxyVal;\n                if (delta >= 0 || frand() < exp((double)delta/T)) {\n                    cur = nw;\n                    curProxyVal = nwProxy;\n                    if (nw.score > bestScore || (nw.score == bestScore && nw.sumSq > bestSumSq)) {\n                        bestScore = nw.score;\n                        bestSumSq = nw.sumSq;\n                        memcpy(bestRot, rot, sizeof(rot));\n                    }\n                } else {\n                    applyRot(i1, j1, oldR1);\n                    applyRot(i2, j2, oldR2);\n                }\n            }\n        }\n    }\n    \n    // Final hill climb from bestRot, prioritizing score then sumSq\n    {\n        for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) {\n            if (rot[i][j] != bestRot[i][j]) applyRot(i, j, bestRot[i][j]);\n        }\n        auto cur = evaluate();\n        long long curObj = cur.score * 1000LL + cur.sumSq;\n        int iter = 0;\n        while (true) {\n            iter++;\n            if ((iter & 127) == 0) {\n                double e = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n                if (e > TL_FINAL) break;\n            }\n            int mtype = (int)(xrand()%10);\n            if (mtype < 8) {\n                int i = (int)(xrand()%30), j = (int)(xrand()%30);\n                int oldR = rot[i][j];\n                int newR = (oldR + 1 + (int)(xrand()%3)) & 3;\n                applyRot(i, j, newR);\n                auto nw = evaluate();\n                long long nwObj = nw.score * 1000LL + nw.sumSq;\n                if (nwObj >= curObj) {\n                    curObj = nwObj;\n                    if (nw.score > bestScore || (nw.score == bestScore && nw.sumSq > bestSumSq)) {\n                        bestScore = nw.score;\n                        bestSumSq = nw.sumSq;\n                        memcpy(bestRot, rot, sizeof(rot));\n                    }\n                } else {\n                    applyRot(i, j, oldR);\n                }\n            } else {\n                int i1 = (int)(xrand()%30), j1 = (int)(xrand()%30);\n                int i2 = (int)(xrand()%30), j2 = (int)(xrand()%30);\n                int oldR1 = rot[i1][j1], oldR2 = rot[i2][j2];\n                int newR1 = (oldR1 + 1 + (int)(xrand()%3)) & 3;\n                int newR2 = (oldR2 + 1 + (int)(xrand()%3)) & 3;\n                applyRot(i1, j1, newR1);\n                applyRot(i2, j2, newR2);\n                auto nw = evaluate();\n                long long nwObj = nw.score * 1000LL + nw.sumSq;\n                if (nwObj >= curObj) {\n                    curObj = nwObj;\n                    if (nw.score > bestScore || (nw.score == bestScore && nw.sumSq > bestSumSq)) {\n                        bestScore = nw.score;\n                        bestSumSq = nw.sumSq;\n                        memcpy(bestRot, rot, sizeof(rot));\n                    }\n                } else {\n                    applyRot(i1, j1, oldR1);\n                    applyRot(i2, j2, oldR2);\n                }\n            }\n        }\n    }\n    \n    string out;\n    for (int i = 0; i < 30; i++) for (int j = 0; j < 30; j++) out += char('0'+bestRot[i][j]);\n    cout << out << endl;\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nmt19937 rng(98765);\nint er, ec;\nvector<vector<int>> board;\nvector<vector<int>> boardT;\nint erT, ecT;\n\nint computeTreeScore(const vector<vector<int>>& b) {\n    int n = N;\n    vector<int> par(n*n), sz(n*n, 1);\n    vector<bool> bad(n*n, false);\n    iota(par.begin(), par.end(), 0);\n    function<int(int)> find = [&](int x){ while(par[x]!=x){par[x]=par[par[x]];x=par[x];} return x;};\n    auto unite = [&](int a, int b){\n        int ra=find(a), rb=find(b);\n        if(ra==rb){ bad[ra]=true; return;}\n        bool nb = bad[ra]||bad[rb];\n        if(sz[ra]<sz[rb])swap(ra,rb);\n        par[rb]=ra; sz[ra]+=sz[rb]; bad[ra]=nb;\n    };\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        if(b[i][j]==0) continue;\n        if(j+1<n && b[i][j+1]!=0 && (b[i][j]&4) && (b[i][j+1]&1)) unite(i*n+j, i*n+j+1);\n        if(i+1<n && b[i+1][j]!=0 && (b[i][j]&8) && (b[i+1][j]&2)) unite(i*n+j, (i+1)*n+j);\n    }\n    int best=0;\n    for(int i=0;i<n*n;i++){\n        if(b[i/n][i%n]==0) continue;\n        if(find(i)==i && !bad[i]) best=max(best,sz[i]);\n    }\n    return best;\n}\n\nint computeBoundaryPenalty(const vector<vector<int>>& b) {\n    int n = N, penalty = 0;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        int v = b[i][j]; if(v==0) continue;\n        if((v&1) && j==0) penalty++;\n        if((v&2) && i==0) penalty++;\n        if((v&4) && j==n-1) penalty++;\n        if((v&8) && i==n-1) penalty++;\n    }\n    return penalty;\n}\n\nint computeManhattan(const vector<vector<int>>& tgt){\n    vector<vector<pair<int,int>>> boardPos(16), tgtPos(16);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(board[i][j]) boardPos[board[i][j]].push_back({i,j});\n        if(tgt[i][j]) tgtPos[tgt[i][j]].push_back({i,j});\n    }\n    int total = 0;\n    for(int tp=1; tp<16; tp++){\n        auto& posB = boardPos[tp];\n        auto& posT = tgtPos[tp];\n        if(posB.size() != posT.size()) return INT_MAX;\n        sort(posB.begin(), posB.end());\n        sort(posT.begin(), posT.end());\n        for(int k=0; k<(int)posB.size(); k++){\n            total += abs(posB[k].first - posT[k].first) + abs(posB[k].second - posT[k].second);\n        }\n    }\n    return total;\n}\n\nstring solveFromTargetRand(vector<vector<int>> tgt, vector<vector<int>> startBoard, int startR, int startC, int rseed){\n    mt19937 localRng(rseed);\n    vector<vector<int>> B = startBoard;\n    int br=startR, bc=startC;\n    string moves;\n    vector<vector<bool>> locked(N, vector<bool>(N, false));\n    bool solveFailed = false;\n    \n    auto posOk = [&](int r, int c){ return r>=0&&r<N&&c>=0&&c<N; };\n    \n    auto moveBlankTo = [&](int tr, int tc, int avoidR, int avoidC)->bool{\n        if(br==tr&&bc==tc) return true;\n        if(!posOk(tr,tc)) return false;\n        if(locked[tr][tc]) return false;\n        if(tr==avoidR&&tc==avoidC) return false;\n        vector<vector<int>> dist(N, vector<int>(N,-1));\n        vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N,{-1,-1}));\n        queue<pair<int,int>> q;\n        dist[br][bc]=0; q.push({br,bc});\n        int dirs[4] = {0,1,2,3};\n        for(int i=3;i>0;i--) swap(dirs[i], dirs[localRng()%(i+1)]);\n        int dr[]={-1,1,0,0}, dc[]={0,0,-1,1};\n        while(!q.empty()){\n            auto [r,c]=q.front(); q.pop();\n            for(int di=0;di<4;di++){\n                int d = dirs[di];\n                int nr=r+dr[d], nc=c+dc[d];\n                if(!posOk(nr,nc)) continue;\n                if(locked[nr][nc]) continue;\n                if(nr==avoidR&&nc==avoidC) continue;\n                if(dist[nr][nc]!=-1) continue;\n                dist[nr][nc]=dist[r][c]+1;\n                par[nr][nc]={r,c};\n                q.push({nr,nc});\n            }\n        }\n        if(dist[tr][tc]==-1) return false;\n        vector<pair<int,int>> path;\n        int r=tr,c=tc;\n        while(!(r==br&&c==bc)){\n            path.push_back({r,c});\n            auto [pr,pc]=par[r][c]; r=pr; c=pc;\n        }\n        reverse(path.begin(), path.end());\n        for(auto [nr,nc]:path){\n            char mv;\n            if(nr==br-1&&nc==bc) mv='U';\n            else if(nr==br+1&&nc==bc) mv='D';\n            else if(nc==bc-1&&nr==br) mv='L';\n            else mv='R';\n            moves.push_back(mv);\n            swap(B[br][bc], B[nr][nc]);\n            br=nr; bc=nc;\n        }\n        return true;\n    };\n    \n    auto findTile = [&](int type, int nearR, int nearC)->pair<int,int>{\n        int minD = INT_MAX;\n        vector<pair<int,int>> best;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            if(locked[i][j]) continue;\n            if(B[i][j]==type){\n                int d=abs(i-nearR)+abs(j-nearC);\n                if(d<minD){ minD=d; best.clear(); best.push_back({i,j}); }\n                else if(d==minD) best.push_back({i,j});\n            }\n        }\n        if(best.empty()) return {-1,-1};\n        return best[localRng()%best.size()];\n    };\n    \n    auto moveTileTo = [&](int& sr, int& sc, int tr, int tc)->bool{\n        int safety = 0;\n        while(sr!=tr || sc!=tc){\n            if(++safety > 4*N*N) return false;\n            vector<pair<int,int>> candidates;\n            if(sr!=tr){\n                if(sr<tr) candidates.push_back({sr+1, sc}); else candidates.push_back({sr-1, sc});\n            }\n            if(sc!=tc){\n                if(sc<tc) candidates.push_back({sr, sc+1}); else candidates.push_back({sr, sc-1});\n            }\n            if(candidates.size()==2 && (localRng()&1)) swap(candidates[0], candidates[1]);\n            bool moved=false;\n            for(auto [cnr, cnc] : candidates){\n                if(!posOk(cnr,cnc)) continue;\n                if(locked[cnr][cnc]) continue;\n                int saveBr=br, saveBc=bc;\n                size_t saveMl = moves.size();\n                auto saveB = B;\n                if(moveBlankTo(cnr,cnc,sr,sc)){\n                    moved=true; break;\n                }\n                br=saveBr; bc=saveBc; moves.resize(saveMl); B=saveB;\n            }\n            if(!moved) return false;\n            char mv;\n            if(sr==br-1&&sc==bc) mv='U';\n            else if(sr==br+1&&sc==bc) mv='D';\n            else if(sc==bc-1&&sr==br) mv='L';\n            else if(sc==bc+1&&sr==br) mv='R';\n            else return false;\n            moves.push_back(mv);\n            swap(B[br][bc], B[sr][sc]);\n            int obr=br, obc=bc;\n            br=sr; bc=sc;\n            sr=obr; sc=obc;\n        }\n        return true;\n    };\n    \n    for(int r=0; r<N-2 && !solveFailed; r++){\n        for(int c=0; c<N-2; c++){\n            int type = tgt[r][c];\n            auto [sr,sc] = findTile(type, r, c);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==r&&sc==c)){\n                if(!moveTileTo(sr,sc,r,c)){solveFailed=true; break;}\n            }\n            locked[r][c]=true;\n        }\n        if(solveFailed) break;\n        \n        int typeA = tgt[r][N-2];\n        int typeB = tgt[r][N-1];\n        \n        if(B[r][N-2]==typeA && B[r][N-1]==typeB){\n            locked[r][N-2]=true; locked[r][N-1]=true;\n            continue;\n        }\n        \n        {\n            auto [sr,sc] = findTile(typeA, r, N-1);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==r && sc==N-1)){\n                if(sr==r && sc==N-2){\n                    if(!moveTileTo(sr,sc, r+1, N-2)){solveFailed=true; break;}\n                    auto p = findTile(typeA, r, N-1);\n                    sr=p.first; sc=p.second;\n                    if(sr==-1){solveFailed=true; break;}\n                }\n                if(!moveTileTo(sr, sc, r, N-1)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[r][N-1]=true;\n        \n        {\n            auto [sr,sc] = findTile(typeB, r+1, N-1);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==r+1 && sc==N-1)){\n                if(!moveTileTo(sr, sc, r+1, N-1)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[r+1][N-1]=true;\n        \n        locked[r][N-1]=false; locked[r+1][N-1]=false;\n        \n        if(!moveBlankTo(r, N-2, -1, -1)){solveFailed=true; break;}\n        moves.push_back('R');\n        swap(B[br][bc], B[r][N-1]); br=r; bc=N-1;\n        moves.push_back('D');\n        swap(B[br][bc], B[r+1][N-1]); br=r+1; bc=N-1;\n        \n        locked[r][N-2]=true; locked[r][N-1]=true;\n    }\n    \n    for(int c=0; c<N-2 && !solveFailed; c++){\n        int typeA = tgt[N-2][c];\n        int typeB = tgt[N-1][c];\n        \n        if(B[N-2][c]==typeA && B[N-1][c]==typeB){\n            locked[N-2][c]=true; locked[N-1][c]=true;\n            continue;\n        }\n        \n        {\n            auto [sr,sc] = findTile(typeA, N-1, c);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==N-1 && sc==c)){\n                if(sr==N-2 && sc==c){\n                    if(!moveTileTo(sr,sc, N-2, c+1)){solveFailed=true; break;}\n                    auto p = findTile(typeA, N-1, c);\n                    sr=p.first; sc=p.second;\n                    if(sr==-1){solveFailed=true; break;}\n                }\n                if(!moveTileTo(sr, sc, N-1, c)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[N-1][c]=true;\n        \n        {\n            auto [sr,sc] = findTile(typeB, N-1, c+1);\n            if(sr==-1){solveFailed=true; break;}\n            if(!(sr==N-1 && sc==c+1)){\n                if(!moveTileTo(sr, sc, N-1, c+1)){solveFailed=true; break;}\n            }\n        }\n        if(solveFailed) break;\n        locked[N-1][c+1]=true;\n        \n        locked[N-1][c]=false; locked[N-1][c+1]=false;\n        \n        if(!moveBlankTo(N-2, c, -1, -1)){solveFailed=true; break;}\n        moves.push_back('D'); swap(B[br][bc], B[N-1][c]); br=N-1; bc=c;\n        moves.push_back('R'); swap(B[br][bc], B[N-1][c+1]); br=N-1; bc=c+1;\n        locked[N-2][c]=true; locked[N-1][c]=true;\n    }\n    \n    if(!solveFailed){\n        for(int attempt=0; attempt<8; attempt++){\n            bool match = (B[N-2][N-2]==tgt[N-2][N-2]) && (B[N-2][N-1]==tgt[N-2][N-1]) && (B[N-1][N-2]==tgt[N-1][N-2]);\n            if(match && br==N-1 && bc==N-1) break;\n            if(br==N-1&&bc==N-1){ moves.push_back('U'); swap(B[br][bc],B[N-2][N-1]); br=N-2;bc=N-1;}\n            else if(br==N-2&&bc==N-1){ moves.push_back('L'); swap(B[br][bc],B[N-2][N-2]); br=N-2;bc=N-2;}\n            else if(br==N-2&&bc==N-2){ moves.push_back('D'); swap(B[br][bc],B[N-1][N-2]); br=N-1;bc=N-2;}\n            else if(br==N-1&&bc==N-2){ moves.push_back('R'); swap(B[br][bc],B[N-1][N-1]); br=N-1;bc=N-1;}\n        }\n    }\n    \n    return moves;\n}\n\nvector<vector<int>> transposeBoard(const vector<vector<int>>& b){\n    vector<vector<int>> res(N, vector<int>(N));\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        int v = b[j][i];\n        int nv = 0;\n        if(v&1) nv|=2;\n        if(v&2) nv|=1;\n        if(v&4) nv|=8;\n        if(v&8) nv|=4;\n        res[i][j] = nv;\n    }\n    return res;\n}\n\nstring transposeMoves(const string& mv){\n    string res;\n    res.reserve(mv.size());\n    for(char c:mv){\n        if(c=='U') res+='L';\n        else if(c=='L') res+='U';\n        else if(c=='D') res+='R';\n        else res+='D';\n    }\n    return res;\n}\n\nstring eliminateCycles(const string& mv){\n    vector<vector<int>> B = board;\n    int br=er, bc=ec;\n    auto hashState = [&]() -> uint64_t {\n        uint64_t h = 1469598103934665603ULL;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            h = h*131 + (uint64_t)B[i][j];\n        }\n        h = h*131 + (uint64_t)(br*N+bc);\n        return h;\n    };\n    vector<uint64_t> hashes;\n    hashes.reserve(mv.size()+1);\n    hashes.push_back(hashState());\n    for(int i=0;i<(int)mv.size();i++){\n        char m = mv[i];\n        int nr=br, nc=bc;\n        if(m=='U') nr--;\n        else if(m=='D') nr++;\n        else if(m=='L') nc--;\n        else nc++;\n        if(nr<0||nr>=N||nc<0||nc>=N) { hashes.push_back(hashes.back()); continue; }\n        swap(B[br][bc], B[nr][nc]);\n        br=nr; bc=nc;\n        hashes.push_back(hashState());\n    }\n    unordered_map<uint64_t, int> lastIdx;\n    lastIdx.reserve(hashes.size()*2);\n    for(int i=(int)hashes.size()-1;i>=0;i--){\n        if(lastIdx.find(hashes[i])==lastIdx.end()){\n            lastIdx[hashes[i]] = i;\n        }\n    }\n    string result;\n    int i = 0;\n    int total = (int)mv.size();\n    while(i < total){\n        auto it = lastIdx.find(hashes[i]);\n        int jump = (it != lastIdx.end()) ? it->second : i;\n        if(jump > i){\n            i = jump; continue;\n        }\n        result.push_back(mv[i]);\n        i++;\n    }\n    return result;\n}\n\npair<string,int> processMoves(const string& mv){\n    vector<vector<int>> BB = board;\n    int bbr=er, bbc=ec;\n    int curS = computeTreeScore(BB);\n    int bestS = curS;\n    int bestLen = 0;\n    int fullLen = mv.size();\n    int lim = min(fullLen, T);\n    for(int i=0;i<lim;i++){\n        char m = mv[i];\n        int nr=bbr, nc=bbc;\n        if(m=='U') nr--;\n        else if(m=='D') nr++;\n        else if(m=='L') nc--;\n        else nc++;\n        if(nr<0||nr>=N||nc<0||nc>=N) break;\n        swap(BB[bbr][bbc], BB[nr][nc]);\n        bbr=nr; bbc=nc;\n        curS = computeTreeScore(BB);\n        if(curS > bestS){ bestS=curS; bestLen=i+1; }\n        if(curS == N*N-1){\n            return {mv.substr(0, i+1), curS};\n        }\n    }\n    return {mv.substr(0, bestLen), bestS};\n}\n\ndouble evalResult(const string& mv, int s){\n    if(s == N*N-1 && (int)mv.size() <= T){\n        return 500000.0 * (2.0 - (double)mv.size()/T);\n    }\n    return 500000.0 * s / (N*N-1);\n}\n\nstring bestRawMoves = \"\";\nstring bestMoves = \"\";\nint bestFinalScore = 0;\nvector<vector<int>> bestTargetUsed;\n\nbool updateBest(const string& rawMv, const vector<vector<int>>& tgt){\n    auto [f, s] = processMoves(rawMv);\n    double ev = evalResult(f, s);\n    double bv = evalResult(bestMoves, bestFinalScore);\n    if(ev > bv){\n        bestRawMoves = rawMv;\n        bestMoves = f;\n        bestFinalScore = s;\n        bestTargetUsed = tgt;\n        return true;\n    }\n    return false;\n}\n\nvoid attemptSolve(const vector<vector<int>>& tgt, const vector<vector<int>>& tgtT, int seed){\n    {\n        string mv = solveFromTargetRand(tgt, board, er, ec, seed);\n        string mv2 = eliminateCycles(mv);\n        updateBest(mv2, tgt);\n    }\n    {\n        string mvT = solveFromTargetRand(tgtT, boardT, erT, ecT, seed+1);\n        string mv3 = transposeMoves(mvT);\n        string mv4 = eliminateCycles(mv3);\n        updateBest(mv4, tgt);\n    }\n}\n\nbool splitOptimize(){\n    if(bestTargetUsed.empty()) return false;\n    int len = bestRawMoves.size();\n    if(len < 30) return false;\n    \n    int i = rng() % (len - 20) + 10;\n    \n    vector<vector<int>> B = board;\n    int br=er, bc=ec;\n    for(int k=0; k<i; k++){\n        char m = bestRawMoves[k];\n        int nr=br, nc=bc;\n        if(m=='U') nr--;\n        else if(m=='D') nr++;\n        else if(m=='L') nc--;\n        else nc++;\n        if(nr<0||nr>=N||nc<0||nc>=N) return false;\n        swap(B[br][bc], B[nr][nc]);\n        br=nr; bc=nc;\n    }\n    \n    bool improved = false;\n    {\n        string tail = solveFromTargetRand(bestTargetUsed, B, br, bc, rng());\n        string combined = bestRawMoves.substr(0, i) + tail;\n        string elim = eliminateCycles(combined);\n        if(updateBest(elim, bestTargetUsed)) improved = true;\n    }\n    {\n        auto Bt = transposeBoard(B);\n        auto tgtT = transposeBoard(bestTargetUsed);\n        string tailT = solveFromTargetRand(tgtT, Bt, bc, br, rng());\n        string tailUntr = transposeMoves(tailT);\n        string combined = bestRawMoves.substr(0, i) + tailUntr;\n        string elim = eliminateCycles(combined);\n        if(updateBest(elim, bestTargetUsed)) improved = true;\n    }\n    return improved;\n}\n\nuint64_t hashBoardState(const vector<vector<int>>& B, int br, int bc){\n    uint64_t h = 1469598103934665603ULL;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        h = h*131 + (uint64_t)B[i][j];\n    }\n    h = h*131 + (uint64_t)(br*N+bc);\n    return h;\n}\n\nbool dfsFind(vector<vector<int>>& B, int& br, int& bc, int depth, int maxDepth, \n             uint64_t endHash, string& path, int prevMove){\n    if(depth == maxDepth){\n        return hashBoardState(B, br, bc) == endHash;\n    }\n    int dr[]={-1,1,0,0}, dc[]={0,0,-1,1};\n    char mvCh[]={'U','D','L','R'};\n    int inv[]={1,0,3,2};\n    for(int d=0; d<4; d++){\n        if(d == prevMove) continue;\n        int nr=br+dr[d], nc=bc+dc[d];\n        if(nr<0||nr>=N||nc<0||nc>=N) continue;\n        swap(B[br][bc], B[nr][nc]);\n        int obr=br, obc=bc;\n        br=nr; bc=nc;\n        path.push_back(mvCh[d]);\n        bool found = dfsFind(B, br, bc, depth+1, maxDepth, endHash, path, inv[d]);\n        if(!found) path.pop_back();\n        swap(B[obr][obc], B[br][bc]);\n        br=obr; bc=obc;\n        if(found) return true;\n    }\n    return false;\n}\n\nstring bfsOptimizePass(const string& mv, int W, chrono::steady_clock::time_point start, double timeLimit){\n    if((int)mv.size() < W) return mv;\n    string result = mv;\n    int i = 0;\n    while(i + W <= (int)result.size()){\n        double el = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(el > timeLimit) break;\n        \n        vector<vector<int>> B = board;\n        int br=er, bc=ec;\n        bool valid = true;\n        for(int k=0; k<i; k++){\n            char m = result[k];\n            int nr=br, nc=bc;\n            if(m=='U') nr--;\n            else if(m=='D') nr++;\n            else if(m=='L') nc--;\n            else nc++;\n            if(nr<0||nr>=N||nc<0||nc>=N){ valid=false; break; }\n            swap(B[br][bc], B[nr][nc]);\n            br=nr; bc=nc;\n        }\n        if(!valid){ break; }\n        \n        vector<vector<int>> Be = B;\n        int bre=br, bce=bc;\n        for(int k=i; k<i+W; k++){\n            char m = result[k];\n            int nr=bre, nc=bce;\n            if(m=='U') nr--;\n            else if(m=='D') nr++;\n            else if(m=='L') nc--;\n            else nc++;\n            if(nr<0||nr>=N||nc<0||nc>=N){ valid=false; break; }\n            swap(Be[bre][bce], Be[nr][nc]);\n            bre=nr; bce=nc;\n        }\n        if(!valid){ break; }\n        \n        uint64_t endHash = hashBoardState(Be, bre, bce);\n        string shorter;\n        for(int targetDepth = 1; targetDepth < W; targetDepth++){\n            string path;\n            int bbr = br, bbc = bc;\n            vector<vector<int>> BB = B;\n            if(dfsFind(BB, bbr, bbc, 0, targetDepth, endHash, path, -1)){\n                shorter = path;\n                break;\n            }\n        }\n        if(!shorter.empty() && (int)shorter.size() < W){\n            result = result.substr(0, i) + shorter + result.substr(i + W);\n            i = max(0, i - W/2);\n        } else {\n            i++;\n        }\n    }\n    return result;\n}\n\nint main(){\n    cin>>N>>T;\n    vector<string> initial(N);\n    for(auto&s:initial) cin>>s;\n    \n    board.assign(N, vector<int>(N));\n    er=0; ec=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        char c = initial[i][j];\n        int v = (c>='0'&&c<='9')?c-'0':c-'a'+10;\n        board[i][j]=v;\n        if(v==0){er=i;ec=j;}\n    }\n    \n    boardT = transposeBoard(board);\n    erT = ec; ecT = er;\n    \n    bestMoves = \"\";\n    bestFinalScore = computeTreeScore(board);\n    bestRawMoves = \"\";\n    \n    auto startT = chrono::steady_clock::now();\n    double totalTime = 2.7;\n    int goalTree = N*N-1;\n    \n    auto runSA = [&](double timeLimit, double weightMis, bool startShuffle) -> vector<vector<int>> {\n        auto t = board;\n        swap(t[er][ec], t[N-1][N-1]);\n        if(startShuffle){\n            for(int k=0;k<N*N*3;k++){\n                int i1,j1,i2,j2;\n                do { i1=rng()%N; j1=rng()%N; } while(i1==N-1&&j1==N-1);\n                do { i2=rng()%N; j2=rng()%N; } while((i2==N-1&&j2==N-1) || (i1==i2&&j1==j2));\n                swap(t[i1][j1], t[i2][j2]);\n            }\n        }\n        \n        int curMis=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) if(t[i][j]!=board[i][j]) curMis++;\n        int curTree = computeTreeScore(t);\n        int curPen = computeBoundaryPenalty(t);\n        auto obj = [&](int tree, int pen, int mis){ return (double)tree*10000 - weightMis*mis - pen; };\n        double curObj = obj(curTree, curPen, curMis);\n        int bestTree = curTree;\n        auto bestT = t;\n        double bestObj = curObj;\n        \n        auto saStart = chrono::steady_clock::now();\n        int it=0;\n        double temp0=2000.0, temp1=1.0;\n        while(true){\n            if((it&1023)==0){\n                double el = chrono::duration<double>(chrono::steady_clock::now()-saStart).count();\n                if(el>timeLimit) break;\n            }\n            it++;\n            int i1,j1,i2,j2;\n            do { i1=rng()%N; j1=rng()%N; } while(i1==N-1&&j1==N-1);\n            do { i2=rng()%N; j2=rng()%N; } while((i2==N-1&&j2==N-1) || (i1==i2&&j1==j2));\n            if(t[i1][j1]==t[i2][j2]) continue;\n            int v1=t[i1][j1], v2=t[i2][j2];\n            int b1=board[i1][j1], b2=board[i2][j2];\n            int oldMisDelta = (v1!=b1?1:0) + (v2!=b2?1:0);\n            int newMisDelta = (v2!=b1?1:0) + (v1!=b2?1:0);\n            int newMis = curMis - oldMisDelta + newMisDelta;\n            swap(t[i1][j1], t[i2][j2]);\n            int newTree = computeTreeScore(t);\n            int newPen = computeBoundaryPenalty(t);\n            double newObj = obj(newTree, newPen, newMis);\n            double el = chrono::duration<double>(chrono::steady_clock::now()-saStart).count();\n            double tt = temp0 * pow(temp1/temp0, el/timeLimit);\n            if(newObj>=curObj || (double)rng()/(double)rng.max() < exp((newObj-curObj)/tt)){\n                curTree=newTree; curPen=newPen; curMis=newMis; curObj=newObj;\n                if(newTree > bestTree || (newTree==bestTree && newObj>bestObj)){\n                    bestTree = newTree; bestObj = newObj; bestT = t;\n                }\n            } else {\n                swap(t[i1][j1], t[i2][j2]);\n            }\n        }\n        return bestT;\n    };\n    \n    set<vector<vector<int>>> seenTgt;\n    vector<pair<int, vector<vector<int>>>> goodTargets;\n    \n    auto tryAddTarget = [&](vector<vector<int>>& t){\n        if(!seenTgt.insert(t).second) return false;\n        if(computeTreeScore(t) == goalTree){\n            int man = computeManhattan(t);\n            goodTargets.push_back({man, t});\n            return true;\n        }\n        return false;\n    };\n    \n    // Phase 1\n    {\n        auto t = runSA(0.4, 0.0, false);\n        tryAddTarget(t);\n        auto tT = transposeBoard(t);\n        for(int k=0;k<3;k++){\n            double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n            if(el > totalTime - 0.3) break;\n            attemptSolve(t, tT, rng());\n        }\n    }\n    \n    // Phase 2\n    double phase2End = 1.2;\n    while(true){\n        double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n        if(el > phase2End) break;\n        double w_options[] = {0.0, 0.0, 0.0, 3.0, 10.0};\n        double w = w_options[rng()%5];\n        bool shuf = (rng()%2)==0;\n        auto t = runSA(0.1, w, shuf);\n        if(tryAddTarget(t)){\n            auto tT = transposeBoard(t);\n            for(int k=0;k<2;k++){\n                double el2 = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n                if(el2 > phase2End+0.1) break;\n                attemptSolve(t, tT, rng());\n            }\n        } else {\n            auto tT = transposeBoard(t);\n            double el2 = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n            if(el2 < phase2End+0.1) attemptSolve(t, tT, rng());\n        }\n    }\n    \n    sort(goodTargets.begin(), goodTargets.end(), [](const auto& a, const auto& b){\n        return a.first < b.first;\n    });\n    \n    // Phase 3a\n    double phase3aEnd = 1.65;\n    for(auto& [man, t] : goodTargets){\n        double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n        if(el > phase3aEnd) break;\n        auto tT = transposeBoard(t);\n        attemptSolve(t, tT, rng());\n    }\n    \n    // Phase 3b\n    double phase3End = 1.95;\n    while(!goodTargets.empty()){\n        double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n        if(el > phase3End) break;\n        int idx;\n        if(rng()%3 == 0){\n            idx = rng() % min((int)goodTargets.size(), 5);\n        } else {\n            idx = rng() % goodTargets.size();\n        }\n        auto& [man, t] = goodTargets[idx];\n        auto tT = transposeBoard(t);\n        attemptSolve(t, tT, rng());\n    }\n    \n    // Phase 4: split optimization\n    double phase4End = 2.15;\n    while(true){\n        double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n        if(el > phase4End) break;\n        splitOptimize();\n    }\n    \n    // Phase 5: BFS window optimization + cycle elim, multiple passes\n    if(!bestRawMoves.empty()){\n        int windows[] = {6, 7, 6, 8};\n        for(int idx = 0; idx < 4; idx++){\n            double el = chrono::duration<double>(chrono::steady_clock::now()-startT).count();\n            if(el > totalTime - 0.1) break;\n            int W = windows[idx];\n            string optimized = bfsOptimizePass(bestRawMoves, W, startT, totalTime - 0.1);\n            // Apply cycle elim on result\n            string elim = eliminateCycles(optimized);\n            auto [f, s] = processMoves(elim);\n            double ev = evalResult(f, s);\n            double bv = evalResult(bestMoves, bestFinalScore);\n            if(ev > bv){\n                bestRawMoves = elim;\n                bestMoves = f;\n                bestFinalScore = s;\n            } else {\n                // Even if eval didn't improve, maybe shorter sequence \u2014 keep for next pass\n                if((int)elim.size() < (int)bestRawMoves.size()){\n                    // Check it still reaches same (or better) score\n                    if(s >= bestFinalScore){\n                        bestRawMoves = elim;\n                    }\n                }\n            }\n        }\n    }\n    \n    cout << bestMoves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, K;\nint a[11];\nvector<int> sx_arr, sy_arr;\n\nint cnt[105][105];\nint bcnt[12];\nlong long curScoreVal;\nint nvG, nhG;\nvector<double> vcG, hcG;\nvector<int> sortedByX, sortedByY;\n\nvoid fullRecompute() {\n    nvG = vcG.size(); nhG = hcG.size();\n    for (int i = 0; i <= nvG; i++) for (int j = 0; j <= nhG; j++) cnt[i][j] = 0;\n    for (int i = 0; i < N; i++) {\n        int xi = upper_bound(vcG.begin(), vcG.end(), (double)sx_arr[i]) - vcG.begin();\n        int yi = upper_bound(hcG.begin(), hcG.end(), (double)sy_arr[i]) - hcG.begin();\n        cnt[xi][yi]++;\n    }\n    for (int d = 0; d < 12; d++) bcnt[d] = 0;\n    for (int i = 0; i <= nvG; i++)\n        for (int j = 0; j <= nhG; j++) {\n            int c = cnt[i][j];\n            if (c >= 1 && c <= 10) bcnt[c]++;\n        }\n    curScoreVal = 0;\n    for (int d = 1; d <= 10; d++) curScoreVal += min(a[d], bcnt[d]);\n}\n\ninline void updateCell(int col, int row, int delta) {\n    int oldv = cnt[col][row];\n    int newv = oldv + delta;\n    cnt[col][row] = newv;\n    if (oldv >= 1 && oldv <= 10) {\n        int before = min(a[oldv], bcnt[oldv]);\n        bcnt[oldv]--;\n        int after = min(a[oldv], bcnt[oldv]);\n        curScoreVal += after - before;\n    }\n    if (newv >= 1 && newv <= 10) {\n        int before = min(a[newv], bcnt[newv]);\n        bcnt[newv]++;\n        int after = min(a[newv], bcnt[newv]);\n        curScoreVal += after - before;\n    }\n}\n\nvoid moveVCut(int ci, double newVal) {\n    double oldVal = vcG[ci];\n    if (newVal == oldVal) return;\n    double lo = min(oldVal, newVal), hi = max(oldVal, newVal);\n    int l, r;\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sx_arr[sortedByX[m]] > lo) b2 = m; else a2 = m+1; }\n        l = a2;\n    }\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sx_arr[sortedByX[m]] >= hi) b2 = m; else a2 = m+1; }\n        r = a2;\n    }\n    int fromCol, toCol;\n    if (newVal > oldVal) { fromCol = ci + 1; toCol = ci; }\n    else { fromCol = ci; toCol = ci + 1; }\n    vcG[ci] = newVal;\n    for (int k = l; k < r; k++) {\n        int si = sortedByX[k];\n        int j = upper_bound(hcG.begin(), hcG.end(), (double)sy_arr[si]) - hcG.begin();\n        updateCell(fromCol, j, -1);\n        updateCell(toCol, j, +1);\n    }\n}\n\nvoid moveHCut(int ci, double newVal) {\n    double oldVal = hcG[ci];\n    if (newVal == oldVal) return;\n    double lo = min(oldVal, newVal), hi = max(oldVal, newVal);\n    int l, r;\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sy_arr[sortedByY[m]] > lo) b2 = m; else a2 = m+1; }\n        l = a2;\n    }\n    {\n        int a2 = 0, b2 = N;\n        while (a2 < b2) { int m=(a2+b2)/2; if ((double)sy_arr[sortedByY[m]] >= hi) b2 = m; else a2 = m+1; }\n        r = a2;\n    }\n    int fromRow, toRow;\n    if (newVal > oldVal) { fromRow = ci + 1; toRow = ci; }\n    else { fromRow = ci; toRow = ci + 1; }\n    hcG[ci] = newVal;\n    for (int k = l; k < r; k++) {\n        int si = sortedByY[k];\n        int j = upper_bound(vcG.begin(), vcG.end(), (double)sx_arr[si]) - vcG.begin();\n        updateCell(j, fromRow, -1);\n        updateCell(j, toRow, +1);\n    }\n}\n\nstruct XorShift {\n    uint64_t s;\n    XorShift(uint64_t seed): s(seed ? seed : 1) {}\n    inline uint32_t next() {\n        s ^= s << 13; s ^= s >> 7; s ^= s << 17;\n        return (uint32_t)s;\n    }\n    inline double nextDouble() {\n        return (double)(next() & 0xFFFFFF) / (double)(1 << 24);\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(0);\n    \n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    sx_arr.resize(N); sy_arr.resize(N);\n    for (int i = 0; i < N; i++) cin >> sx_arr[i] >> sy_arr[i];\n    \n    sortedByX.resize(N); sortedByY.resize(N);\n    iota(sortedByX.begin(), sortedByX.end(), 0);\n    iota(sortedByY.begin(), sortedByY.end(), 0);\n    sort(sortedByX.begin(), sortedByX.end(), [&](int x, int y){ return sx_arr[x] < sx_arr[y]; });\n    sort(sortedByY.begin(), sortedByY.end(), [&](int x, int y){ return sy_arr[x] < sy_arr[y]; });\n    \n    vector<int> xs = sx_arr, ys = sy_arr;\n    sort(xs.begin(), xs.end()); xs.erase(unique(xs.begin(), xs.end()), xs.end());\n    sort(ys.begin(), ys.end()); ys.erase(unique(ys.begin(), ys.end()), ys.end());\n    \n    vector<double> cand_x, cand_y;\n    for (int i = 0; i + 1 < (int)xs.size(); i++) cand_x.push_back((xs[i] + xs[i+1]) / 2.0);\n    for (int i = 0; i + 1 < (int)ys.size(); i++) cand_y.push_back((ys[i] + ys[i+1]) / 2.0);\n    \n    XorShift rng(1234567);\n    \n    auto pickEvenly = [&](vector<double>& cand, int k) {\n        vector<double> res;\n        if ((int)cand.size() <= k) res = cand;\n        else {\n            for (int i = 0; i < k; i++) {\n                int idx = (int)((long long)(i+1) * cand.size() / (k+1));\n                if (idx >= (int)cand.size()) idx = cand.size()-1;\n                res.push_back(cand[idx]);\n            }\n        }\n        sort(res.begin(), res.end());\n        res.erase(unique(res.begin(), res.end()), res.end());\n        return res;\n    };\n    \n    auto startTime = chrono::steady_clock::now();\n    double saTime = 2.55;\n    double totalTime = 2.85;\n    \n    long long bestScore = -1;\n    vector<double> bestVC, bestHC;\n    \n    for (int kv = 30; kv <= 70; kv += 5) {\n        int kh = K - kv;\n        vcG = pickEvenly(cand_x, kv);\n        hcG = pickEvenly(cand_y, kh);\n        fullRecompute();\n        if (curScoreVal > bestScore) {\n            bestScore = curScoreVal;\n            bestVC = vcG; bestHC = hcG;\n        }\n    }\n    \n    vcG = bestVC; hcG = bestHC;\n    fullRecompute();\n    \n    double T0 = 3.0, T1 = 0.05;\n    long long iters = 0;\n    double cachedProgress = 0.0;\n    \n    auto tryInsertCut = [&](vector<double>& vec, double v) -> bool {\n        auto it = lower_bound(vec.begin(), vec.end(), v);\n        if (it != vec.end() && *it == v) return false;\n        vec.insert(it, v);\n        return true;\n    };\n    \n    while (true) {\n        iters++;\n        if ((iters & 1023) == 0) {\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - startTime).count();\n            if (elapsed > saTime) break;\n            cachedProgress = elapsed / saTime;\n        }\n        \n        double T = T0 * pow(T1/T0, cachedProgress);\n        \n        int op = rng.next() % 100;\n        \n        if (op < 48) {\n            if (vcG.empty() || cand_x.empty()) continue;\n            int i = rng.next() % vcG.size();\n            double lo_b = (i == 0) ? -1e18 : vcG[i-1];\n            double hi_b = (i == (int)vcG.size()-1) ? 1e18 : vcG[i+1];\n            auto itL = upper_bound(cand_x.begin(), cand_x.end(), lo_b);\n            auto itR = lower_bound(cand_x.begin(), cand_x.end(), hi_b);\n            if (itL >= itR) continue;\n            int numCand = itR - itL;\n            double newVal = *(itL + rng.next() % numCand);\n            if (newVal == vcG[i]) continue;\n            \n            long long prevScore = curScoreVal;\n            double prevVal = vcG[i];\n            moveVCut(i, newVal);\n            long long delta = curScoreVal - prevScore;\n            if (delta >= 0 || rng.nextDouble() < exp((double)delta / T)) {\n                if (curScoreVal > bestScore) {\n                    bestScore = curScoreVal;\n                    bestVC = vcG; bestHC = hcG;\n                }\n            } else {\n                moveVCut(i, prevVal);\n            }\n        } else if (op < 96) {\n            if (hcG.empty() || cand_y.empty()) continue;\n            int i = rng.next() % hcG.size();\n            double lo_b = (i == 0) ? -1e18 : hcG[i-1];\n            double hi_b = (i == (int)hcG.size()-1) ? 1e18 : hcG[i+1];\n            auto itL = upper_bound(cand_y.begin(), cand_y.end(), lo_b);\n            auto itR = lower_bound(cand_y.begin(), cand_y.end(), hi_b);\n            if (itL >= itR) continue;\n            int numCand = itR - itL;\n            double newVal = *(itL + rng.next() % numCand);\n            if (newVal == hcG[i]) continue;\n            \n            long long prevScore = curScoreVal;\n            double prevVal = hcG[i];\n            moveHCut(i, newVal);\n            long long delta = curScoreVal - prevScore;\n            if (delta >= 0 || rng.nextDouble() < exp((double)delta / T)) {\n                if (curScoreVal > bestScore) {\n                    bestScore = curScoreVal;\n                    bestVC = vcG; bestHC = hcG;\n                }\n            } else {\n                moveHCut(i, prevVal);\n            }\n        } else {\n            vector<double> saveVC = vcG, saveHC = hcG;\n            long long prevScoreFull = curScoreVal;\n            \n            int dir = rng.next() % 2;\n            bool ok = false;\n            if (dir == 0) {\n                if (!vcG.empty() && !cand_y.empty()) {\n                    int ri = rng.next() % vcG.size();\n                    vcG.erase(vcG.begin() + ri);\n                    double nv = cand_y[rng.next() % cand_y.size()];\n                    ok = tryInsertCut(hcG, nv);\n                }\n            } else {\n                if (!hcG.empty() && !cand_x.empty()) {\n                    int ri = rng.next() % hcG.size();\n                    hcG.erase(hcG.begin() + ri);\n                    double nv = cand_x[rng.next() % cand_x.size()];\n                    ok = tryInsertCut(vcG, nv);\n                }\n            }\n            if (!ok) { vcG = saveVC; hcG = saveHC; continue; }\n            \n            fullRecompute();\n            long long delta = curScoreVal - prevScoreFull;\n            if (delta >= 0 || rng.nextDouble() < exp((double)delta / T)) {\n                if (curScoreVal > bestScore) {\n                    bestScore = curScoreVal;\n                    bestVC = vcG; bestHC = hcG;\n                }\n            } else {\n                vcG = saveVC; hcG = saveHC;\n                fullRecompute();\n            }\n        }\n    }\n    \n    // Final greedy polishing\n    vcG = bestVC; hcG = bestHC;\n    fullRecompute();\n    \n    bool globalImproved = true;\n    while (globalImproved) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        if (elapsed > totalTime) break;\n        \n        globalImproved = false;\n        for (int dir = 0; dir < 2; dir++) {\n            vector<double>& cuts = (dir == 0) ? vcG : hcG;\n            vector<double>& cand = (dir == 0) ? cand_x : cand_y;\n            int nc = cuts.size();\n            for (int i = 0; i < nc; i++) {\n                auto ncheck = chrono::steady_clock::now();\n                double el = chrono::duration<double>(ncheck - startTime).count();\n                if (el > totalTime) { globalImproved = false; goto done_greedy; }\n                \n                double lo_b = (i == 0) ? -1e18 : cuts[i-1];\n                double hi_b = (i == (int)cuts.size()-1) ? 1e18 : cuts[i+1];\n                auto itL = upper_bound(cand.begin(), cand.end(), lo_b);\n                auto itR = lower_bound(cand.begin(), cand.end(), hi_b);\n                if (itL >= itR) continue;\n                \n                double origVal = cuts[i];\n                long long origScore = curScoreVal;\n                double bestVal = origVal;\n                long long bestLocalScore = origScore;\n                \n                for (auto it = itL; it != itR; ++it) {\n                    double nv = *it;\n                    if (nv == origVal) continue;\n                    if (dir == 0) moveVCut(i, nv);\n                    else moveHCut(i, nv);\n                    if (curScoreVal > bestLocalScore) {\n                        bestLocalScore = curScoreVal;\n                        bestVal = nv;\n                    }\n                }\n                if (cuts[i] != bestVal) {\n                    if (dir == 0) moveVCut(i, bestVal);\n                    else moveHCut(i, bestVal);\n                }\n                \n                if (bestLocalScore > bestScore) {\n                    bestScore = bestLocalScore;\n                    bestVC = vcG; bestHC = hcG;\n                    globalImproved = true;\n                }\n            }\n        }\n    }\n    done_greedy:;\n    \n    vcG = bestVC; hcG = bestHC;\n    \n    cout << vcG.size() + hcG.size() << \"\\n\";\n    for (double c : vcG) {\n        long long p = (long long)floor(c);\n        cout << p << \" \" << -1000000000LL << \" \" << p+1 << \" \" << 1000000000LL << \"\\n\";\n    }\n    for (double c : hcG) {\n        long long p = (long long)floor(c);\n        cout << -1000000000LL << \" \" << p << \" \" << 1000000000LL << \" \" << p+1 << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint cx;\nvector<uint8_t> has_dot;\nvector<uint8_t> edge_used;\nvector<short> next_dot;\nint dx8[8] = {1,1,0,-1,-1,-1,0,1};\nint dy8[8] = {0,1,1,1,0,-1,-1,-1};\n\ninline bool inside(int x, int y) { return 0<=x && x<N && 0<=y && y<N; }\ninline int weight(int x, int y) { return (x-cx)*(x-cx) + (y-cx)*(y-cx) + 1; }\n\nvoid initNextDot() {\n    next_dot.assign(N*N*8, 0);\n    for (int d = 0; d < 8; d++) {\n        for (int sx = 0; sx < N; sx++) for (int sy = 0; sy < N; sy++) {\n            int px = sx - dx8[d], py = sy - dy8[d];\n            if (inside(px, py)) continue;\n            vector<int> dotPos;\n            int steps = 0;\n            int cxx = sx, cyy = sy;\n            while (inside(cxx, cyy)) {\n                if (has_dot[cxx*N+cyy]) dotPos.push_back(steps);\n                steps++; cxx += dx8[d]; cyy += dy8[d];\n            }\n            cxx = sx; cyy = sy;\n            int ptr = 0;\n            for (int s = 0; s < steps; s++) {\n                while (ptr < (int)dotPos.size() && dotPos[ptr] <= s) ptr++;\n                if (ptr < (int)dotPos.size()) next_dot[(cxx*N+cyy)*8+d] = (short)(dotPos[ptr] - s);\n                else next_dot[(cxx*N+cyy)*8+d] = 0;\n                cxx += dx8[d]; cyy += dy8[d];\n            }\n        }\n    }\n}\n\nvoid updateNextDotAdd(int qx, int qy) {\n    for (int d = 0; d < 8; d++) {\n        int opp = (d+4)%8;\n        int cxx = qx + dx8[opp], cyy = qy + dy8[opp];\n        int dist = 1;\n        while (inside(cxx, cyy)) {\n            int cur = next_dot[(cxx*N+cyy)*8+d];\n            if (cur > 0 && cur < dist) break;\n            next_dot[(cxx*N+cyy)*8+d] = (short)dist;\n            if (has_dot[cxx*N+cyy]) break;\n            cxx += dx8[opp]; cyy += dy8[opp]; dist++;\n        }\n    }\n}\n\ninline int nearestDotFast(int x, int y, int d) {\n    int v = next_dot[(x*N+y)*8+d];\n    return v == 0 ? -1 : v;\n}\n\ninline bool checkSeg(int x, int y, int d, int len) {\n    int cxx = x, cyy = y;\n    int ddx = dx8[d], ddy = dy8[d];\n    for (int i = 0; i < len; i++) {\n        if (edge_used[(cxx*N+cyy)*8+d]) return false;\n        cxx += ddx; cyy += ddy;\n        if (i < len-1 && has_dot[cxx*N+cyy]) return false;\n    }\n    return true;\n}\n\nvoid markSeg(int x, int y, int d, int len) {\n    int cxx = x, cyy = y;\n    int dr = d^4;\n    int ddx = dx8[d], ddy = dy8[d];\n    for (int i = 0; i < len; i++) {\n        edge_used[(cxx*N+cyy)*8+d] = 1;\n        int nx = cxx + ddx, ny = cyy + ddy;\n        edge_used[(nx*N+ny)*8+dr] = 1;\n        cxx = nx; cyy = ny;\n    }\n}\n\nstruct Move {\n    int p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y;\n    int8_t d1, d2;\n    int len1, len2;\n};\n\nbool validateMove(const Move& m) {\n    if (has_dot[m.p1x*N+m.p1y]) return false;\n    if (!has_dot[m.p2x*N+m.p2y]) return false;\n    if (!has_dot[m.p3x*N+m.p3y]) return false;\n    if (!has_dot[m.p4x*N+m.p4y]) return false;\n    if (!checkSeg(m.p1x, m.p1y, m.d1, m.len1)) return false;\n    if (!checkSeg(m.p1x, m.p1y, m.d2, m.len2)) return false;\n    if (!checkSeg(m.p2x, m.p2y, m.d2, m.len2)) return false;\n    if (!checkSeg(m.p4x, m.p4y, m.d1, m.len1)) return false;\n    return true;\n}\n\nvoid applyMove(const Move& m) {\n    has_dot[m.p1x*N+m.p1y] = 1;\n    updateNextDotAdd(m.p1x, m.p1y);\n    markSeg(m.p1x, m.p1y, m.d1, m.len1);\n    markSeg(m.p1x, m.p1y, m.d2, m.len2);\n    markSeg(m.p2x, m.p2y, m.d2, m.len2);\n    markSeg(m.p4x, m.p4y, m.d1, m.len1);\n}\n\nmt19937 g_rng(12345);\nint g_noiseLevel = 0;\n\nlong long computePriority(const Move& m) {\n    long long w = weight(m.p1x, m.p1y);\n    long long size = m.len1 + m.len2;\n    long long key = w * 100000LL - size * 100LL;\n    if (g_noiseLevel > 0) {\n        key += (long long)(g_rng() % (g_noiseLevel * 300 + 100));\n    }\n    return key;\n}\n\nstruct PQItem {\n    long long key;\n    Move m;\n    bool operator<(const PQItem& o) const { return key < o.key; }\n};\n\nvoid addCandsWithDot(int qx, int qy, priority_queue<PQItem>& pq) {\n    auto tryAdd = [&](const Move& m) {\n        if (validateMove(m)) {\n            pq.push({computePriority(m), m});\n        }\n    };\n    \n    for (int d1 = 0; d1 < 8; d1++) {\n        int d2 = (d1+2)%8;\n        int opp1 = (d1+4)%8;\n        int l1max;\n        int nd = nearestDotFast(qx, qy, opp1);\n        if (nd < 0) {\n            l1max = 0;\n            int tx = qx + dx8[opp1], ty = qy + dy8[opp1];\n            while (inside(tx, ty)) { l1max++; tx += dx8[opp1]; ty += dy8[opp1]; }\n        } else l1max = nd - 1;\n        for (int l1 = 1; l1 <= l1max; l1++) {\n            int p1x = qx + dx8[opp1]*l1, p1y = qy + dy8[opp1]*l1;\n            int l2 = nearestDotFast(p1x, p1y, d2);\n            if (l2 < 0) continue;\n            int p4x = p1x + dx8[d2]*l2, p4y = p1y + dy8[d2]*l2;\n            int p3x = qx + dx8[d2]*l2, p3y = qy + dy8[d2]*l2;\n            if (!inside(p3x, p3y) || !has_dot[p3x*N+p3y]) continue;\n            Move m{p1x,p1y,qx,qy,p3x,p3y,p4x,p4y,(int8_t)d1,(int8_t)d2,l1,l2};\n            tryAdd(m);\n        }\n    }\n    for (int d1 = 0; d1 < 8; d1++) {\n        int d2 = (d1+2)%8;\n        int opp2 = (d2+4)%8;\n        int l2max;\n        int nd = nearestDotFast(qx, qy, opp2);\n        if (nd < 0) {\n            l2max = 0;\n            int tx = qx + dx8[opp2], ty = qy + dy8[opp2];\n            while (inside(tx, ty)) { l2max++; tx += dx8[opp2]; ty += dy8[opp2]; }\n        } else l2max = nd - 1;\n        for (int l2 = 1; l2 <= l2max; l2++) {\n            int p1x = qx + dx8[opp2]*l2, p1y = qy + dy8[opp2]*l2;\n            int l1 = nearestDotFast(p1x, p1y, d1);\n            if (l1 < 0) continue;\n            int p2x = p1x + dx8[d1]*l1, p2y = p1y + dy8[d1]*l1;\n            int p3x = qx + dx8[d1]*l1, p3y = qy + dy8[d1]*l1;\n            if (!inside(p3x, p3y) || !has_dot[p3x*N+p3y]) continue;\n            Move m{p1x,p1y,p2x,p2y,p3x,p3y,qx,qy,(int8_t)d1,(int8_t)d2,l1,l2};\n            tryAdd(m);\n        }\n    }\n    for (int d1 = 0; d1 < 8; d1++) {\n        int d2 = (d1+2)%8;\n        int opp1 = (d1+4)%8;\n        int opp2 = (d2+4)%8;\n        int l2 = nearestDotFast(qx, qy, opp2);\n        if (l2 < 0) continue;\n        int p2x = qx + dx8[opp2]*l2, p2y = qy + dy8[opp2]*l2;\n        int l1 = nearestDotFast(qx, qy, opp1);\n        if (l1 < 0) continue;\n        int p4x = qx + dx8[opp1]*l1, p4y = qy + dy8[opp1]*l1;\n        int p1x = p2x + dx8[opp1]*l1, p1y = p2y + dy8[opp1]*l1;\n        if (!inside(p1x, p1y) || has_dot[p1x*N+p1y]) continue;\n        Move m{p1x,p1y,p2x,p2y,qx,qy,p4x,p4y,(int8_t)d1,(int8_t)d2,l1,l2};\n        tryAdd(m);\n    }\n}\n\nint main() {\n    cin >> N >> M;\n    cx = (N-1)/2;\n    \n    auto startTime = chrono::steady_clock::now();\n    auto timeLeft = [&](){ return 4.7 - chrono::duration<double>(chrono::steady_clock::now() - startTime).count(); };\n    \n    vector<pair<int,int>> initial(M);\n    for (auto& p : initial) { cin >> p.first >> p.second; }\n    \n    auto resetState = [&]() {\n        has_dot.assign(N*N, 0);\n        edge_used.assign(N*N*8, 0);\n        for (auto& p : initial) has_dot[p.first*N+p.second] = 1;\n        initNextDot();\n    };\n    \n    vector<Move> bestMoves;\n    long long bestScore = -1;\n    \n    int iter = 0;\n    \n    while (timeLeft() > 0.3) {\n        resetState();\n        vector<Move> moves;\n        \n        g_noiseLevel = iter == 0 ? 0 : (1 + iter);\n        \n        priority_queue<PQItem> pq;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (has_dot[x*N+y]) continue;\n                for (int d1 = 0; d1 < 8; d1++) {\n                    int d2 = (d1+2)%8;\n                    int l1 = nearestDotFast(x, y, d1);\n                    if (l1 < 0) continue;\n                    int l2 = nearestDotFast(x, y, d2);\n                    if (l2 < 0) continue;\n                    int p2x = x + dx8[d1]*l1, p2y = y + dy8[d1]*l1;\n                    int p4x = x + dx8[d2]*l2, p4y = y + dy8[d2]*l2;\n                    int p3x = p2x + dx8[d2]*l2, p3y = p2y + dy8[d2]*l2;\n                    if (!inside(p3x, p3y) || !has_dot[p3x*N+p3y]) continue;\n                    Move m{x,y,p2x,p2y,p3x,p3y,p4x,p4y,(int8_t)d1,(int8_t)d2,l1,l2};\n                    if (validateMove(m)) pq.push({computePriority(m), m});\n                }\n            }\n        }\n        \n        while (!pq.empty() && timeLeft() > 0.2) {\n            PQItem top = pq.top(); pq.pop();\n            if (!validateMove(top.m)) continue;\n            applyMove(top.m);\n            moves.push_back(top.m);\n            addCandsWithDot(top.m.p1x, top.m.p1y, pq);\n        }\n        \n        long long sumW = 0;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) {\n            if (has_dot[x*N+y]) sumW += weight(x,y);\n        }\n        \n        if (sumW > bestScore) {\n            bestScore = sumW;\n            bestMoves = moves;\n        }\n        iter++;\n    }\n    \n    cout << bestMoves.size() << \"\\n\";\n    for (auto& m : bestMoves) {\n        cout << m.p1x << \" \" << m.p1y << \" \" << m.p2x << \" \" << m.p2y << \" \"\n             << m.p3x << \" \" << m.p3y << \" \" << m.p4x << \" \" << m.p4y << \"\\n\";\n    }\n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef array<int,100> Board;\n\ninline void tilt(Board& b, int dir) {\n    if (dir == 0) {\n        for (int c = 0; c < 10; c++) {\n            int w = 0;\n            for (int r = 0; r < 10; r++) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w++;\n                }\n            }\n        }\n    } else if (dir == 1) {\n        for (int c = 0; c < 10; c++) {\n            int w = 9;\n            for (int r = 9; r >= 0; r--) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w--;\n                }\n            }\n        }\n    } else if (dir == 2) {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 0;\n            for (int c = 0; c < 10; c++) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w++;\n                }\n            }\n        }\n    } else {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w--;\n                }\n            }\n        }\n    }\n}\n\ninline int tilt_emp(Board& b, int dir, int* emp) {\n    int ec = 0;\n    if (dir == 0) {\n        for (int c = 0; c < 10; c++) {\n            int w = 0;\n            for (int r = 0; r < 10; r++) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w++;\n                }\n            }\n            for (int r = w; r < 10; r++) emp[ec++] = r*10+c;\n        }\n    } else if (dir == 1) {\n        for (int c = 0; c < 10; c++) {\n            int w = 9;\n            for (int r = 9; r >= 0; r--) {\n                int idx = r*10+c;\n                if (b[idx]) {\n                    if (w != r) { b[w*10+c] = b[idx]; b[idx] = 0; }\n                    w--;\n                }\n            }\n            for (int r = 0; r <= w; r++) emp[ec++] = r*10+c;\n        }\n    } else if (dir == 2) {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 0;\n            for (int c = 0; c < 10; c++) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w++;\n                }\n            }\n            for (int c = w; c < 10; c++) emp[ec++] = rb+c;\n        }\n    } else {\n        for (int r = 0; r < 10; r++) {\n            int rb = r*10;\n            int w = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (b[rb+c]) {\n                    if (w != c) { b[rb+w] = b[rb+c]; b[rb+c] = 0; }\n                    w--;\n                }\n            }\n            for (int c = 0; c <= w; c++) emp[ec++] = rb+c;\n        }\n    }\n    return ec;\n}\n\nvoid placeCandy(Board& b, int p, int flavor) {\n    int cnt = 0;\n    for (int i = 0; i < 100; i++) {\n        if (!b[i]) {\n            cnt++;\n            if (cnt == p) {\n                b[i] = flavor;\n                return;\n            }\n        }\n    }\n}\n\nint computeScore(const Board& b) {\n    int vis[100] = {0};\n    int sum = 0;\n    int stk[100];\n    for (int i = 0; i < 100; i++) {\n        if (!vis[i] && b[i]) {\n            int flavor = b[i];\n            int sz = 0;\n            int top = 0;\n            stk[top++] = i;\n            vis[i] = 1;\n            while (top > 0) {\n                int x = stk[--top];\n                sz++;\n                int r = x/10, c = x%10;\n                if (r>0) { int ni = x-10; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (r<9) { int ni = x+10; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (c>0) { int ni = x-1; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n                if (c<9) { int ni = x+1; if (!vis[ni] && b[ni]==flavor) { vis[ni]=1; stk[top++]=ni; } }\n            }\n            sum += sz*sz;\n        }\n    }\n    return sum;\n}\n\nmt19937 rng(12345);\n\nint policies[24][3] = {\n    {0,1,2}, {0,1,3}, {0,2,1}, {0,2,3}, {0,3,1}, {0,3,2},\n    {1,0,2}, {1,0,3}, {1,2,0}, {1,2,3}, {1,3,0}, {1,3,2},\n    {2,0,1}, {2,0,3}, {2,1,0}, {2,1,3}, {2,3,0}, {2,3,1},\n    {3,0,1}, {3,0,2}, {3,1,0}, {3,1,2}, {3,2,0}, {3,2,1},\n};\n\ninline int rollout_from(Board b, int startT, int endT, const vector<int>& f, const int* policy, const unsigned* rnd, int rndStart, int* emp, int ec) {\n    for (int k = startT; k < endT; k++) {\n        int flavor = f[k];\n        int pick = emp[rnd[rndStart + k - startT] % ec];\n        b[pick] = flavor;\n        if (k < endT - 1) {\n            ec = tilt_emp(b, policy[flavor-1], emp);\n        }\n    }\n    return computeScore(b);\n}\n\nint main() {\n    auto startTime = chrono::steady_clock::now();\n    \n    vector<int> f(100);\n    for (int i = 0; i < 100; i++) cin >> f[i];\n    \n    Board board;\n    board.fill(0);\n    \n    double totalBudget = 1.85;\n    \n    int bestPolicy = 0;\n    {\n        auto bs = chrono::steady_clock::now();\n        double evalBudget = 0.15;\n        long long ps[24] = {0};\n        int pt[24] = {0};\n        int ri = 0;\n        int emp[100];\n        while (true) {\n            if ((ri & 7) == 0) {\n                auto ns = chrono::steady_clock::now();\n                double el = chrono::duration<double>(ns - bs).count();\n                if (el >= evalBudget) break;\n            }\n            int pi = ri % 24;\n            ri++;\n            Board b;\n            b.fill(0);\n            int ec = 100;\n            for (int i = 0; i < 100; i++) emp[i] = i;\n            for (int k = 0; k < 100; k++) {\n                int flavor = f[k];\n                int pick = emp[rng() % ec];\n                b[pick] = flavor;\n                if (k < 99) {\n                    ec = tilt_emp(b, policies[pi][flavor-1], emp);\n                }\n            }\n            int sc = computeScore(b);\n            ps[pi] += sc;\n            pt[pi]++;\n        }\n        double bestAvg = -1;\n        for (int i = 0; i < 24; i++) {\n            if (pt[i] == 0) continue;\n            double avg = (double)ps[i] / pt[i];\n            if (avg > bestAvg) { bestAvg = avg; bestPolicy = i; }\n        }\n    }\n    \n    unsigned rnd[100];\n    \n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        placeCandy(board, p, f[t]);\n        \n        if (t == 99) break;\n        \n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - startTime).count();\n        double remaining = totalBudget - elapsed;\n        int stepsLeft = 100 - t;\n        double perStep = remaining / stepsLeft;\n        if (perStep < 0.001) perStep = 0.001;\n        auto stepStart = chrono::steady_clock::now();\n        \n        long long scoreSum[4][4] = {{0}};\n        int trials[4][4] = {{0}};\n        long long scoreSum1[4] = {0,0,0,0};\n        int trials1[4] = {0,0,0,0};\n        \n        int iter = 0;\n        int remainingCandies = 99 - t;\n        bool canDo2Step = (remainingCandies >= 2);\n        \n        while (true) {\n            if ((iter & 1) == 0) {\n                auto nowS = chrono::steady_clock::now();\n                double el = chrono::duration<double>(nowS - stepStart).count();\n                if (el >= perStep) break;\n            }\n            iter++;\n            \n            for (int k = 0; k < remainingCandies; k++) rnd[k] = rng();\n            \n            for (int D1 = 0; D1 < 4; D1++) {\n                Board b1 = board;\n                int emp1[100];\n                int ec1 = tilt_emp(b1, D1, emp1);\n                \n                if (remainingCandies == 0) {\n                    int sc = computeScore(b1);\n                    scoreSum1[D1] += sc;\n                    trials1[D1]++;\n                    continue;\n                }\n                \n                int flavor = f[t+1];\n                int pick = emp1[rnd[0] % ec1];\n                b1[pick] = flavor;\n                \n                if (!canDo2Step) {\n                    int sc = computeScore(b1);\n                    scoreSum1[D1] += sc;\n                    trials1[D1]++;\n                    continue;\n                }\n                \n                for (int D2 = 0; D2 < 4; D2++) {\n                    Board b2 = b1;\n                    int emp2[100];\n                    int ec2 = tilt_emp(b2, D2, emp2);\n                    int sc;\n                    if (remainingCandies == 2) {\n                        int flavor2 = f[t+2];\n                        int pick2 = emp2[rnd[1] % ec2];\n                        b2[pick2] = flavor2;\n                        sc = computeScore(b2);\n                    } else {\n                        sc = rollout_from(b2, t+2, 100, f, policies[bestPolicy], rnd, 1, emp2, ec2);\n                    }\n                    scoreSum[D1][D2] += sc;\n                    trials[D1][D2]++;\n                }\n            }\n        }\n        \n        double bestScoreV = -1;\n        int bestDir = 0;\n        \n        if (canDo2Step) {\n            for (int d1 = 0; d1 < 4; d1++) {\n                double bestD2val = -1;\n                for (int d2 = 0; d2 < 4; d2++) {\n                    if (trials[d1][d2] == 0) continue;\n                    double avg = (double)scoreSum[d1][d2] / trials[d1][d2];\n                    if (avg > bestD2val) bestD2val = avg;\n                }\n                if (bestD2val > bestScoreV) {\n                    bestScoreV = bestD2val;\n                    bestDir = d1;\n                }\n            }\n        } else {\n            for (int d = 0; d < 4; d++) {\n                if (trials1[d] == 0) continue;\n                double avg = (double)scoreSum1[d] / trials1[d];\n                if (avg > bestScoreV) {\n                    bestScoreV = avg;\n                    bestDir = d;\n                }\n            }\n        }\n        \n        tilt(board, bestDir);\n        cout << \"FBLR\"[bestDir] << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint M; double eps;\n\nvector<vector<int>> genParts_(int N, int maxK){\n    vector<vector<int>> parts;\n    parts.push_back({});\n    function<void(vector<int>&, int, int, int)> rec = [&](vector<int>& cur, int minVal, int remaining, int depth){\n        if(!cur.empty()) parts.push_back(cur);\n        if(depth==maxK) return;\n        for(int v=minVal; v<=remaining; v++){\n            cur.push_back(v);\n            rec(cur, v, remaining-v, depth+1);\n            cur.pop_back();\n        }\n    };\n    vector<int> cur;\n    rec(cur, 2, N, 0);\n    return parts;\n}\n\nstruct Features {\n    vector<double> sortedDeg;\n    vector<double> sortedF2;\n};\n\nFeatures computeExpectedFeatures(const vector<int>& part, int N){\n    int C = part.size();\n    int sumCluster = 0; for(int s : part) sumCluster += s;\n    int n_iso = N - sumCluster;\n    vector<int> sizes(C+1);\n    for(int i=0;i<C;i++) sizes[i] = part[i];\n    sizes[C] = n_iso;\n    \n    vector<double> mu(C+1);\n    for(int t=0;t<=C;t++){\n        int s = sizes[t];\n        if(t < C) mu[t] = (s-1)*(1-eps) + (N-s)*eps;\n        else mu[t] = (N-1)*eps;\n    }\n    \n    vector<double> f2(C+1);\n    for(int t=0;t<=C;t++){\n        if(t < C){\n            int s = sizes[t];\n            double ff = (s-1)*(1-eps)*mu[t];\n            for(int tp=0;tp<=C;tp++){\n                if(tp==t) continue;\n                ff += sizes[tp] * eps * mu[tp];\n            }\n            f2[t] = ff;\n        } else {\n            double ff = 0;\n            for(int tp=0;tp<C;tp++) ff += sizes[tp] * eps * mu[tp];\n            if(sizes[C] > 0) ff += (sizes[C]-1) * eps * mu[C];\n            f2[t] = ff;\n        }\n    }\n    \n    Features feat;\n    feat.sortedDeg.reserve(N);\n    feat.sortedF2.reserve(N);\n    for(int t=0;t<=C;t++){\n        for(int i=0;i<sizes[t];i++){\n            feat.sortedDeg.push_back(mu[t]);\n            feat.sortedF2.push_back(f2[t]);\n        }\n    }\n    sort(feat.sortedDeg.begin(), feat.sortedDeg.end());\n    sort(feat.sortedF2.begin(), feat.sortedF2.end());\n    return feat;\n}\n\nFeatures computeObservedFeatures(const vector<vector<int>>& H, int N){\n    vector<int> deg(N, 0);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) deg[i] += H[i][j];\n    vector<double> f2v(N);\n    for(int v=0;v<N;v++){\n        double s=0;\n        for(int u=0;u<N;u++) if(H[v][u]) s += deg[u];\n        f2v[v] = s;\n    }\n    Features feat;\n    feat.sortedDeg.resize(N);\n    for(int i=0;i<N;i++) feat.sortedDeg[i] = deg[i];\n    feat.sortedF2 = f2v;\n    sort(feat.sortedDeg.begin(), feat.sortedDeg.end());\n    sort(feat.sortedF2.begin(), feat.sortedF2.end());\n    return feat;\n}\n\ndouble distDeg(const Features& a, const Features& b, int N){\n    double d = 0;\n    for(int i=0;i<N;i++){ double t=a.sortedDeg[i]-b.sortedDeg[i]; d += t*t; }\n    return d;\n}\ndouble distF2(const Features& a, const Features& b, int N){\n    double d = 0;\n    for(int i=0;i<N;i++){ double t=a.sortedF2[i]-b.sortedF2[i]; d += t*t; }\n    return d;\n}\n\nvector<int> selectPartitions(const vector<Features>& allFeat, int P, int N){\n    vector<int> chosen = {0};\n    vector<double> minD(P, 1e18);\n    vector<bool> used(P,false); used[0]=true;\n    for(int i=0;i<P;i++) if(!used[i]) minD[i] = distDeg(allFeat[0], allFeat[i], N);\n    while((int)chosen.size() < M && (int)chosen.size() < P){\n        int bi=-1; double bv=-1;\n        for(int i=0;i<P;i++){\n            if(used[i]) continue;\n            if(minD[i] > bv){ bv=minD[i]; bi=i; }\n        }\n        if(bi<0) break;\n        chosen.push_back(bi);\n        used[bi]=true;\n        for(int i=0;i<P;i++) if(!used[i]){\n            double d=distDeg(allFeat[bi], allFeat[i], N);\n            if(d<minD[i]) minD[i]=d;\n        }\n    }\n    while((int)chosen.size()<M){\n        for(int i=0;i<P;i++) if(!used[i]){ used[i]=true; chosen.push_back(i); break;}\n    }\n    return chosen;\n}\n\ndouble localSearchScore(const vector<vector<int>>& H, int N, vector<int>& assign, int C, int maxIter){\n    vector<vector<double>> S(N, vector<double>(C, 0.0));\n    for(int x=0;x<N;x++){\n        for(int y=0;y<N;y++){\n            if(y==x) continue;\n            if(assign[y] >= 0){\n                S[x][assign[y]] += 2.0*H[x][y] - 1.0;\n            }\n        }\n    }\n    \n    double totalScore = 0;\n    for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){\n        if(assign[i] >= 0 && assign[i] == assign[j]) totalScore += 2.0*H[i][j] - 1.0;\n    }\n    \n    for(int it=0; it<maxIter; it++){\n        bool improved = false;\n        for(int u=0; u<N && !improved; u++){\n            for(int v=u+1; v<N && !improved; v++){\n                int cu = assign[u], cv = assign[v];\n                if(cu == cv) continue;\n                double huv = 2.0*H[u][v] - 1.0;\n                double delta;\n                if(cu >= 0 && cv >= 0){\n                    delta = S[u][cv] + S[v][cu] - S[u][cu] - S[v][cv] - 2*huv;\n                } else if(cu < 0 && cv >= 0){\n                    delta = (S[u][cv] - huv) - S[v][cv];\n                } else if(cu >= 0 && cv < 0){\n                    delta = (S[v][cu] - huv) - S[u][cu];\n                } else continue;\n                \n                if(delta > 1e-9){\n                    for(int w=0;w<N;w++){\n                        if(w==u || w==v) continue;\n                        double hwu = 2.0*H[w][u]-1.0;\n                        double hwv = 2.0*H[w][v]-1.0;\n                        if(cu >= 0){ S[w][cu] += (hwv - hwu); }\n                        if(cv >= 0){ S[w][cv] += (hwu - hwv); }\n                    }\n                    swap(assign[u], assign[v]);\n                    for(int c=0;c<C;c++){ S[u][c] = 0; S[v][c] = 0; }\n                    for(int y=0;y<N;y++){\n                        if(y != u && assign[y] >= 0) S[u][assign[y]] += 2.0*H[u][y]-1.0;\n                        if(y != v && assign[y] >= 0) S[v][assign[y]] += 2.0*H[v][y]-1.0;\n                    }\n                    totalScore += delta;\n                    improved = true;\n                }\n            }\n        }\n        if(!improved) break;\n    }\n    \n    return totalScore;\n}\n\ndouble iteratedLS(const vector<vector<int>>& H, int N, const vector<int>& initAssign, int C, int maxIter, int numStarts, mt19937& rng){\n    vector<int> bestA = initAssign;\n    double bestSc = localSearchScore(H, N, bestA, C, maxIter);\n    \n    for(int r=1; r<numStarts; r++){\n        vector<int> cur = bestA;\n        int numPerturb = 4;\n        for(int p=0; p<numPerturb; p++){\n            int u = rng() % N, v = rng() % N;\n            for(int tries=0; tries<10 && cur[u]==cur[v]; tries++) v = rng() % N;\n            if(cur[u] != cur[v]) swap(cur[u], cur[v]);\n        }\n        double sc = localSearchScore(H, N, cur, C, maxIter);\n        if(sc > bestSc){ bestSc = sc; bestA = cur; }\n    }\n    \n    return bestSc;\n}\n\nint main(){\n    cin >> M >> eps;\n    \n    int bestN = 100, bestMaxK = 3;\n    double bestScore = -1;\n    double bestWF2 = 0;\n    \n    auto t_start = chrono::steady_clock::now();\n    \n    if(eps < 1e-9){\n        for(int mK : {3, 4, 5}){\n            for(int n=4;n<=100;n++){\n                int ps = (int)genParts_(n, mK).size();\n                if(ps >= M){\n                    double score = 1.0/n;\n                    if(score > bestScore){ bestScore = score; bestN = n; bestMaxK = mK; bestWF2 = 0; }\n                    break;\n                }\n            }\n        }\n    } else {\n        double timeBudget = 1.8;\n        \n        vector<int> Ns;\n        for(int n=8;n<=30;n+=2) Ns.push_back(n);\n        for(int n=35;n<=60;n+=5) Ns.push_back(n);\n        for(int n=70;n<=100;n+=10) Ns.push_back(n);\n        \n        int trials = 150;\n        \n        vector<double> wF2Candidates;\n        wF2Candidates.push_back(0.0);\n        for(double x = 1e-5; x <= 1.01; x *= 3.16228) wF2Candidates.push_back(x);\n        \n        vector<int> maxKOpts;\n        if(eps < 0.10) maxKOpts = {2, 3, 4};\n        else maxKOpts = {2, 3};\n        \n        bool stop=false;\n        for(int n : Ns){\n            if(stop) break;\n            for(int mK : maxKOpts){\n                auto elapsed = chrono::duration<double>(chrono::steady_clock::now() - t_start).count();\n                if(elapsed > timeBudget){ stop=true; break; }\n                auto parts = genParts_(n, mK);\n                if((int)parts.size() < M) continue;\n                int P = parts.size();\n                vector<Features> allFeat(P);\n                for(int i=0;i<P;i++) allFeat[i] = computeExpectedFeatures(parts[i], n);\n                auto chosen = selectPartitions(allFeat, P, n);\n                \n                vector<vector<int>> clusterOf(M, vector<int>(n, -1));\n                for(int k=0;k<M;k++){\n                    vector<int> part = parts[chosen[k]];\n                    sort(part.rbegin(), part.rend());\n                    int pos=0, cid=0;\n                    for(int s : part){\n                        for(int i=pos;i<pos+s;i++) clusterOf[k][i] = cid;\n                        pos += s; cid++;\n                    }\n                }\n                \n                mt19937 rng(12345);\n                uniform_real_distribution<double> ur(0,1);\n                vector<int> trueK(trials);\n                vector<Features> obsFeat(trials);\n                for(int t=0;t<trials;t++){\n                    int k = rng() % M;\n                    trueK[t] = k;\n                    vector<vector<int>> H(n, vector<int>(n, 0));\n                    for(int i=0;i<n;i++) for(int j=i+1;j<n;j++){\n                        int e = (clusterOf[k][i] == clusterOf[k][j] && clusterOf[k][i] >= 0) ? 1 : 0;\n                        if(ur(rng) < eps) e = 1-e;\n                        H[i][j] = H[j][i] = e;\n                    }\n                    obsFeat[t] = computeObservedFeatures(H, n);\n                }\n                \n                vector<vector<double>> dDeg(trials, vector<double>(M));\n                vector<vector<double>> dF2(trials, vector<double>(M));\n                for(int t=0;t<trials;t++){\n                    for(int k=0;k<M;k++){\n                        dDeg[t][k] = distDeg(obsFeat[t], allFeat[chosen[k]], n);\n                        dF2[t][k] = distF2(obsFeat[t], allFeat[chosen[k]], n);\n                    }\n                }\n                \n                for(double wF2 : wF2Candidates){\n                    int errors = 0;\n                    for(int t=0;t<trials;t++){\n                        int best=0; double bd=1e18;\n                        for(int k=0;k<M;k++){\n                            double d = dDeg[t][k] + wF2 * dF2[t][k];\n                            if(d<bd){bd=d; best=k;}\n                        }\n                        if(best != trueK[t]) errors++;\n                    }\n                    double err = (double)errors / trials;\n                    double score = pow(0.9, 100*err) / n;\n                    if(score > bestScore){\n                        bestScore = score; bestN = n; bestMaxK = mK; bestWF2 = wF2;\n                    }\n                }\n            }\n        }\n    }\n    \n    int N = bestN, maxK = bestMaxK;\n    double wF2 = bestWF2;\n    int E = N*(N-1)/2;\n    auto parts = genParts_(N, maxK);\n    int P = parts.size();\n    vector<Features> allFeat(P);\n    for(int i=0;i<P;i++) allFeat[i] = computeExpectedFeatures(parts[i], N);\n    auto chosen = selectPartitions(allFeat, P, N);\n    \n    vector<vector<int>> clusterOf(M, vector<int>(N, -1));\n    vector<int> numClusters(M);\n    vector<vector<int>> partsK(M);\n    for(int k=0;k<M;k++){\n        vector<int> part = parts[chosen[k]];\n        sort(part.rbegin(), part.rend());\n        partsK[k] = part;\n        int pos=0, cid=0;\n        for(int s : part){\n            for(int i=pos;i<pos+s;i++) clusterOf[k][i] = cid;\n            pos += s; cid++;\n        }\n        numClusters[k] = cid;\n    }\n    \n    vector<Features> targetFeat(M);\n    for(int k=0;k<M;k++) targetFeat[k] = allFeat[chosen[k]];\n    \n    bool useLS = false;\n    int lsT = 8;\n    int lsMaxIter = 25;\n    int iterTopK = 2;\n    int iterStarts = 2;\n    if(eps > 0.05){\n        auto elapsed = chrono::duration<double>(chrono::steady_clock::now() - t_start).count();\n        if(elapsed < 2.5){\n            int trials_ls = 35;\n            mt19937 rng(999);\n            mt19937 lsRng(777);\n            uniform_real_distribution<double> ur(0,1);\n            int errors_ls = 0, errors_nls = 0;\n            for(int t=0;t<trials_ls;t++){\n                int k_true = rng() % M;\n                vector<vector<int>> H(N, vector<int>(N, 0));\n                for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){\n                    int e = (clusterOf[k_true][i] == clusterOf[k_true][j] && clusterOf[k_true][i] >= 0) ? 1 : 0;\n                    if(ur(rng) < eps) e = 1-e;\n                    H[i][j] = H[j][i] = e;\n                }\n                auto obs = computeObservedFeatures(H, N);\n                \n                vector<double> dD(M), dF(M);\n                int best_nls = 0; double bd = 1e18;\n                for(int k=0;k<M;k++){\n                    dD[k] = distDeg(obs, targetFeat[k], N);\n                    dF[k] = distF2(obs, targetFeat[k], N);\n                    double d = dD[k] + wF2 * dF[k];\n                    if(d<bd){bd=d; best_nls=k;}\n                }\n                if(best_nls != k_true) errors_nls++;\n                \n                vector<pair<double,int>> ranked(M);\n                for(int k=0;k<M;k++) ranked[k] = {dD[k] + wF2*dF[k], k};\n                int T_use = min(lsT, M);\n                nth_element(ranked.begin(), ranked.begin()+T_use, ranked.end());\n                sort(ranked.begin(), ranked.begin()+T_use);\n                \n                vector<int> deg(N, 0);\n                for(int i=0;i<N;i++) for(int j=0;j<N;j++) deg[i] += H[i][j];\n                vector<int> order(N);\n                iota(order.begin(), order.end(), 0);\n                sort(order.begin(), order.end(), [&](int a, int b){ return deg[a] > deg[b]; });\n                \n                double bestLL = -1e18; int bestK_ls = ranked[0].second;\n                for(int ti=0; ti<T_use; ti++){\n                    int k = ranked[ti].second;\n                    int C = numClusters[k];\n                    vector<int> assign(N);\n                    for(int pos=0;pos<N;pos++) assign[order[pos]] = clusterOf[k][pos];\n                    double sc;\n                    if(ti < iterTopK){\n                        sc = iteratedLS(H, N, assign, C, lsMaxIter, iterStarts, lsRng);\n                    } else {\n                        sc = localSearchScore(H, N, assign, C, lsMaxIter);\n                    }\n                    if(sc > bestLL){ bestLL = sc; bestK_ls = k; }\n                }\n                if(bestK_ls != k_true) errors_ls++;\n            }\n            if(errors_ls < errors_nls) useLS = true;\n        }\n    }\n    \n    cout << N << \"\\n\";\n    for(int k=0;k<M;k++){\n        const auto& part = partsK[k];\n        string s(E, '0');\n        int p=0;\n        vector<pair<int,int>> cliqueRange;\n        int pos=0;\n        for(int sz : part){\n            cliqueRange.push_back({pos, pos+sz});\n            pos += sz;\n        }\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){\n            bool edge=false;\n            for(auto& pr : cliqueRange){\n                if(i>=pr.first && i<pr.second && j>=pr.first && j<pr.second){ edge=true; break; }\n            }\n            s[p++] = edge?'1':'0';\n        }\n        cout << s << \"\\n\";\n    }\n    cout.flush();\n    \n    mt19937 qRng(424242);\n    for(int q=0;q<100;q++){\n        string h; cin >> h;\n        vector<vector<int>> H(N, vector<int>(N, 0));\n        int p=0;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){\n            H[i][j] = H[j][i] = (h[p++]=='1') ? 1 : 0;\n        }\n        auto obs = computeObservedFeatures(H, N);\n        \n        vector<double> dD(M), dF(M);\n        for(int k=0;k<M;k++){\n            dD[k] = distDeg(obs, targetFeat[k], N);\n            dF[k] = distF2(obs, targetFeat[k], N);\n        }\n        \n        int best = 0;\n        if(!useLS){\n            double bd = 1e18;\n            for(int k=0;k<M;k++){\n                double d = dD[k] + wF2 * dF[k];\n                if(d < bd){ bd = d; best = k; }\n            }\n        } else {\n            vector<pair<double,int>> ranked(M);\n            for(int k=0;k<M;k++) ranked[k] = {dD[k] + wF2*dF[k], k};\n            int T_use = min(lsT, M);\n            nth_element(ranked.begin(), ranked.begin()+T_use, ranked.end());\n            sort(ranked.begin(), ranked.begin()+T_use);\n            \n            vector<int> deg(N, 0);\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++) deg[i] += H[i][j];\n            vector<int> order(N);\n            iota(order.begin(), order.end(), 0);\n            sort(order.begin(), order.end(), [&](int a, int b){ return deg[a] > deg[b]; });\n            \n            double bestLL = -1e18; best = ranked[0].second;\n            for(int ti=0; ti<T_use; ti++){\n                int k = ranked[ti].second;\n                int C = numClusters[k];\n                vector<int> assign(N);\n                for(int pos=0;pos<N;pos++) assign[order[pos]] = clusterOf[k][pos];\n                double sc;\n                if(ti < iterTopK){\n                    sc = iteratedLS(H, N, assign, C, lsMaxIter, iterStarts, qRng);\n                } else {\n                    sc = localSearchScore(H, N, assign, C, lsMaxIter);\n                }\n                if(sc > bestLL){ bestLL = sc; best = k; }\n            }\n        }\n        \n        cout << best << \"\\n\";\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint N, M, D, K;\nvector<vector<pair<int,int>>> adj;\nvector<int> W, Eu, Ev;\nvector<int> sources;\nvector<vector<ll>> baseDist;\nvector<ll> baseSum;\nvector<int> assign_;\nvector<vector<int>> dayEdges;\nint S;\nvector<char> removed;\nvector<ll> distBuf;\n\nvoid dijkstra(int src, vector<ll>& dist) {\n    fill(dist.begin(), dist.end(), (ll)2e18);\n    priority_queue<pair<ll,int>, vector<pair<ll,int>>, greater<>> pq;\n    dist[src] = 0;\n    pq.push({0, src});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist[u]) continue;\n        for (auto [v, eid] : adj[u]) {\n            if (removed[eid]) continue;\n            ll nd = d + W[eid];\n            if (nd < dist[v]) {\n                dist[v] = nd;\n                pq.push({nd, v});\n            }\n        }\n    }\n}\n\nll dayCost(int k) {\n    for (int e : dayEdges[k]) removed[e] = 1;\n    ll total = 0;\n    for (int si = 0; si < S; si++) {\n        dijkstra(sources[si], distBuf);\n        ll sum = 0;\n        for (int v = 0; v < N; v++) {\n            ll dv = (distBuf[v] >= (ll)1e18) ? 1000000000LL : distBuf[v];\n            sum += dv;\n        }\n        total += sum - baseSum[si];\n    }\n    for (int e : dayEdges[k]) removed[e] = 0;\n    return total;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> M >> D >> K;\n    adj.assign(N, {});\n    W.resize(M); Eu.resize(M); Ev.resize(M);\n    for (int i = 0; i < M; i++) {\n        int u,v,w; cin >> u >> v >> w; u--; v--;\n        Eu[i]=u; Ev[i]=v; W[i]=w;\n        adj[u].push_back({v, i});\n        adj[v].push_back({u, i});\n    }\n    vector<int> X(N), Y(N);\n    for (int i = 0; i < N; i++) cin >> X[i] >> Y[i];\n    \n    removed.assign(M, 0);\n    distBuf.assign(N, 0);\n    \n    mt19937 rng(12345);\n    S = min(N, 40);\n    vector<int> perm(N);\n    iota(perm.begin(), perm.end(), 0);\n    shuffle(perm.begin(), perm.end(), rng);\n    sources.assign(perm.begin(), perm.begin()+S);\n    \n    baseDist.assign(S, vector<ll>(N));\n    baseSum.assign(S, 0);\n    for (int i = 0; i < S; i++) {\n        dijkstra(sources[i], baseDist[i]);\n        ll sum = 0;\n        for (int v = 0; v < N; v++) sum += baseDist[i][v];\n        baseSum[i] = sum;\n    }\n    \n    assign_.assign(M, 0);\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){\n        double xa = (X[Eu[a]]+X[Ev[a]])*0.5, ya=(Y[Eu[a]]+Y[Ev[a]])*0.5;\n        double xb = (X[Eu[b]]+X[Ev[b]])*0.5, yb=(Y[Eu[b]]+Y[Ev[b]])*0.5;\n        return xa+ya < xb+yb;\n    });\n    \n    vector<int> dayCount(D, 0);\n    for (int i = 0; i < M; i++) {\n        int e = order[i];\n        int d = i % D;\n        while (dayCount[d] >= K) d = (d+1) % D;\n        assign_[e] = d;\n        dayCount[d]++;\n    }\n    \n    dayEdges.assign(D, {});\n    for (int i = 0; i < M; i++) dayEdges[assign_[i]].push_back(i);\n    \n    vector<ll> costs(D);\n    for (int k = 0; k < D; k++) costs[k] = dayCost(k);\n    \n    auto startT = chrono::steady_clock::now();\n    double TIME_LIMIT = 5.7;\n    auto getTime = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now() - startT).count();\n    };\n    \n    ll curTotal = 0;\n    for (ll c : costs) curTotal += c;\n    vector<int> bestAssign = assign_;\n    ll bestTotal = curTotal;\n    \n    int iter = 0, accepted = 0;\n    while (getTime() < TIME_LIMIT) {\n        iter++;\n        int op = rng() % 4;\n        if (op == 0) {\n            int e1 = rng() % M;\n            int d1 = assign_[e1];\n            int d2 = rng() % D;\n            if (d1 == d2) continue;\n            if ((int)dayEdges[d2].size() >= K) continue;\n            \n            auto& v1 = dayEdges[d1];\n            auto it1 = find(v1.begin(), v1.end(), e1);\n            v1.erase(it1);\n            dayEdges[d2].push_back(e1);\n            assign_[e1] = d2;\n            \n            ll nc1 = dayCost(d1);\n            ll nc2 = dayCost(d2);\n            ll delta = (nc1+nc2) - (costs[d1]+costs[d2]);\n            if (delta < 0) {\n                costs[d1]=nc1; costs[d2]=nc2;\n                curTotal += delta;\n                accepted++;\n                if (curTotal < bestTotal) { bestTotal = curTotal; bestAssign = assign_; }\n            } else {\n                dayEdges[d2].pop_back();\n                v1.push_back(e1);\n                assign_[e1] = d1;\n            }\n        } else {\n            int e1 = rng() % M;\n            int e2 = rng() % M;\n            if (e1 == e2) continue;\n            int d1 = assign_[e1], d2 = assign_[e2];\n            if (d1 == d2) continue;\n            auto& v1 = dayEdges[d1];\n            auto& v2 = dayEdges[d2];\n            *find(v1.begin(), v1.end(), e1) = e2;\n            *find(v2.begin(), v2.end(), e2) = e1;\n            assign_[e1] = d2;\n            assign_[e2] = d1;\n            \n            ll nc1 = dayCost(d1);\n            ll nc2 = dayCost(d2);\n            ll delta = (nc1+nc2) - (costs[d1]+costs[d2]);\n            if (delta < 0) {\n                costs[d1]=nc1; costs[d2]=nc2;\n                curTotal += delta;\n                accepted++;\n                if (curTotal < bestTotal) { bestTotal = curTotal; bestAssign = assign_; }\n            } else {\n                *find(v1.begin(), v1.end(), e2) = e1;\n                *find(v2.begin(), v2.end(), e1) = e2;\n                assign_[e1] = d1;\n                assign_[e2] = d2;\n            }\n        }\n    }\n    \n    cerr << \"iter=\" << iter << \" acc=\" << accepted << endl;\n    \n    for (int i = 0; i < M; i++) cout << bestAssign[i]+1 << \" \\n\"[i==M-1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nint F[2][14][14], R[2][14][14];\nint occ[2][14][14][14];\nint bid[2][14][14][14];\nint best_bid[2][14][14][14];\nint occ_init[2][14][14][14];\n\nint dx6[6]={1,-1,0,0,0,0};\nint dy6[6]={0,0,1,-1,0,0};\nint dz6[6]={0,0,0,0,1,-1};\n\nbool inb(int x,int y,int z){return x>=0&&x<D&&y>=0&&y<D&&z>=0&&z<D;}\n\nint fcount[2][14][14];\nint rcount[2][14][14];\nint fcount_init[2][14][14];\nint rcount_init[2][14][14];\n\nbool canRemove(int i,int x,int y,int z){\n    if(!occ[i][x][y][z]) return false;\n    if(F[i][z][x] && fcount[i][x][z]==1) return false;\n    if(R[i][z][y] && rcount[i][y][z]==1) return false;\n    return true;\n}\nvoid removeCell(int i,int x,int y,int z){\n    occ[i][x][y][z]=0;\n    fcount[i][x][z]--;\n    rcount[i][y][z]--;\n}\n\nmt19937 rng(98765);\n\nint rots[24][9];\n\nvoid genRots(){\n    int perms[6][3] = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};\n    int permSign[6] = {1,-1,-1,1,1,-1};\n    int cnt=0;\n    for(int p=0;p<6;p++){\n        for(int s=0;s<8;s++){\n            int sx = (s&1)?-1:1;\n            int sy = (s&2)?-1:1;\n            int sz = (s&4)?-1:1;\n            if(permSign[p]*sx*sy*sz != 1) continue;\n            int M[9]={0,0,0,0,0,0,0,0,0};\n            int signs[3]={sx,sy,sz};\n            for(int row=0;row<3;row++){\n                M[row*3 + perms[p][row]] = signs[row];\n            }\n            for(int k=0;k<9;k++) rots[cnt][k]=M[k];\n            cnt++;\n        }\n    }\n}\n\ninline void applyRot(int ri, int x, int y, int z, int& ox, int& oy, int& oz){\n    int* M = rots[ri];\n    ox = M[0]*x + M[1]*y + M[2]*z;\n    oy = M[3]*x + M[4]*y + M[5]*z;\n    oz = M[6]*x + M[7]*y + M[8]*z;\n}\n\ndouble evalScore(int (*curbid)[14][14][14]){\n    int maxId = 0;\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        maxId = max(maxId, curbid[i][x][y][z]);\n    vector<int> v1(maxId+1,0), v2(maxId+1,0);\n    for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n        if(curbid[0][x][y][z]) v1[curbid[0][x][y][z]]++;\n        if(curbid[1][x][y][z]) v2[curbid[1][x][y][z]]++;\n    }\n    double score = 0;\n    for(int id=1;id<=maxId;id++){\n        if(v1[id]>0 && v2[id]>0) score += 1.0/v1[id];\n        else if(v1[id]>0) score += v1[id];\n        else if(v2[id]>0) score += v2[id];\n    }\n    return score;\n}\n\nint visited[32][32][32];\nint visGen = 0;\n\nint growMax(int x1,int y1,int z1,int x2,int y2,int z2, int ri, int maxV,\n            vector<tuple<int,int,int>>& outBlock){\n    visGen++;\n    outBlock.clear();\n    static tuple<int,int,int> stackArr[4096];\n    int sp = 0;\n    outBlock.push_back({0,0,0});\n    visited[D][D][D] = visGen;\n    stackArr[sp++] = {0,0,0};\n    while(sp>0 && (int)outBlock.size()<maxV){\n        auto [ox,oy,oz] = stackArr[--sp];\n        for(int k=0;k<6;k++){\n            int nx=ox+dx6[k],ny=oy+dy6[k],nz=oz+dz6[k];\n            if(nx<=-D || nx>=D || ny<=-D || ny>=D || nz<=-D || nz>=D) continue;\n            if(visited[nx+D][ny+D][nz+D] == visGen) continue;\n            int ax=x1+nx, ay=y1+ny, az=z1+nz;\n            int rx,ry,rz;\n            applyRot(ri, nx, ny, nz, rx, ry, rz);\n            int bx=x2+rx, by=y2+ry, bz=z2+rz;\n            if(!inb(ax,ay,az)||!inb(bx,by,bz)) continue;\n            if(!occ[0][ax][ay][az]||bid[0][ax][ay][az]) continue;\n            if(!occ[1][bx][by][bz]||bid[1][bx][by][bz]) continue;\n            visited[nx+D][ny+D][nz+D] = visGen;\n            outBlock.push_back({nx,ny,nz});\n            if((int)outBlock.size()>=maxV) break;\n            stackArr[sp++] = {nx,ny,nz};\n        }\n    }\n    return outBlock.size();\n}\n\nvoid greedyMatch(double timeLimit, chrono::steady_clock::time_point start, int maxV, int tryRots, int& nextId){\n    while(true){\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed>timeLimit) break;\n        \n        vector<tuple<int,int,int>> a1, a2;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(occ[0][x][y][z]&&!bid[0][x][y][z]) a1.push_back({x,y,z});\n            if(occ[1][x][y][z]&&!bid[1][x][y][z]) a2.push_back({x,y,z});\n        }\n        if(a1.empty()||a2.empty()) break;\n        \n        int bestVol = 0;\n        vector<tuple<int,int,int>> bestCells1, bestCells2;\n        \n        shuffle(a1.begin(),a1.end(),rng);\n        shuffle(a2.begin(),a2.end(),rng);\n        \n        int totalBudget = 400;\n        int seedsPerDim = max(3, (int)sqrt((double)totalBudget/max(1,tryRots)));\n        int tries1 = min((int)a1.size(), seedsPerDim);\n        int tries2 = min((int)a2.size(), seedsPerDim);\n        \n        for(int t1=0;t1<tries1;t1++){\n            auto [x1,y1,z1] = a1[t1];\n            for(int t2=0;t2<tries2;t2++){\n                auto [x2,y2,z2] = a2[t2];\n                int rotIds[24];\n                for(int i=0;i<24;i++) rotIds[i]=i;\n                for(int i=23;i>0;i--){int j=rng()%(i+1);swap(rotIds[i],rotIds[j]);}\n                int numRots = min(tryRots, 24);\n                for(int rr=0;rr<numRots;rr++){\n                    int ri = rotIds[rr];\n                    vector<tuple<int,int,int>> block;\n                    int v = growMax(x1,y1,z1,x2,y2,z2,ri,maxV,block);\n                    if(v > bestVol){\n                        bestVol = v;\n                        bestCells1.clear(); bestCells2.clear();\n                        for(auto [ox,oy,oz]:block){\n                            bestCells1.push_back({x1+ox,y1+oy,z1+oz});\n                            int rx,ry,rz;\n                            applyRot(ri, ox, oy, oz, rx, ry, rz);\n                            bestCells2.push_back({x2+rx,y2+ry,z2+rz});\n                        }\n                    }\n                }\n            }\n            double el = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n            if(el>timeLimit) break;\n        }\n        \n        if(bestVol==0) break;\n        int id = nextId++;\n        for(auto [x,y,z]:bestCells1) bid[0][x][y][z]=id;\n        for(auto [x,y,z]:bestCells2) bid[1][x][y][z]=id;\n    }\n}\n\nvoid finalize(int& nextId){\n    for(int i=0;i<2;i++){\n        vector<tuple<int,int,int>> cells;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(occ[i][x][y][z]&&!bid[i][x][y][z]) cells.push_back({x,y,z});\n        }\n        shuffle(cells.begin(),cells.end(),rng);\n        bool changed=true;\n        while(changed){\n            changed=false;\n            for(auto [x,y,z]:cells){\n                if(occ[i][x][y][z]&&!bid[i][x][y][z]&&canRemove(i,x,y,z)){\n                    removeCell(i,x,y,z);\n                    changed=true;\n                }\n            }\n        }\n    }\n    \n    for(int i=0;i<2;i++){\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(occ[i][x][y][z]&&!bid[i][x][y][z]){\n                bid[i][x][y][z] = nextId++;\n            }\n        }\n    }\n}\n\nvoid resetState(){\n    memcpy(occ, occ_init, sizeof(occ));\n    memcpy(fcount, fcount_init, sizeof(fcount));\n    memcpy(rcount, rcount_init, sizeof(rcount));\n    memset(bid, 0, sizeof(bid));\n}\n\nint destroyBlocks(int strategy){\n    int maxId = 0;\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        maxId = max(maxId, bid[i][x][y][z]);\n    vector<int> v1(maxId+1,0), v2(maxId+1,0);\n    for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n        if(bid[0][x][y][z]) v1[bid[0][x][y][z]]++;\n        if(bid[1][x][y][z]) v2[bid[1][x][y][z]]++;\n    }\n    \n    set<int> destroySet;\n    \n    if(strategy == 0){\n        for(int id=1;id<=maxId;id++){\n            if(v1[id]==0 || v2[id]==0) destroySet.insert(id);\n            else if(v1[id] <= 2 && rng()%2==0) destroySet.insert(id);\n            else if(rng()%5==0) destroySet.insert(id);\n        }\n    } else if(strategy == 1){\n        for(int id=1;id<=maxId;id++){\n            if(v1[id]==0 || v2[id]==0) destroySet.insert(id);\n            else if(v1[id] <= 3) destroySet.insert(id);\n        }\n    } else if(strategy == 2){\n        int cx = rng()%D, cy = rng()%D, cz = rng()%D;\n        int rad = 2 + rng()%3;\n        for(int i=0;i<2;i++){\n            for(int x=max(0,cx-rad);x<min(D,cx+rad+1);x++)\n                for(int y=max(0,cy-rad);y<min(D,cy+rad+1);y++)\n                    for(int z=max(0,cz-rad);z<min(D,cz+rad+1);z++){\n                        if(bid[i][x][y][z]) destroySet.insert(bid[i][x][y][z]);\n                    }\n        }\n    } else if(strategy == 3){\n        for(int id=1;id<=maxId;id++){\n            if(rng()%10 < 3) destroySet.insert(id);\n        }\n    } else if(strategy == 4){\n        for(int id=1;id<=maxId;id++){\n            if(v1[id]==0 || v2[id]==0) destroySet.insert(id);\n        }\n    } else if(strategy == 5){\n        for(int id=1;id<=maxId;id++){\n            if(v1[id]==0 || v2[id]==0) destroySet.insert(id);\n            else if(v1[id] <= 4 && rng()%3==0) destroySet.insert(id);\n        }\n    }\n    \n    for(int i=0;i<2;i++){\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(destroySet.count(bid[i][x][y][z])){\n                bid[i][x][y][z] = 0;\n            }\n        }\n    }\n    \n    int curMaxId = 0;\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        curMaxId = max(curMaxId, bid[i][x][y][z]);\n    return curMaxId;\n}\n\nint main(){\n    genRots();\n    cin>>D;\n    for(int i=0;i<2;i++){\n        for(int z=0;z<D;z++){string s;cin>>s;for(int x=0;x<D;x++)F[i][z][x]=s[x]-'0';}\n        for(int z=0;z<D;z++){string s;cin>>s;for(int y=0;y<D;y++)R[i][z][y]=s[y]-'0';}\n    }\n    for(int i=0;i<2;i++){\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(F[i][z][x]&&R[i][z][y]){\n                occ_init[i][x][y][z]=1;\n                fcount_init[i][x][z]++;\n                rcount_init[i][y][z]++;\n            }\n        }\n    }\n    \n    auto start = chrono::steady_clock::now();\n    double TL_total = 5.5;\n    \n    double bestScore = 1e18;\n    \n    double phase1_end = min(TL_total * 0.3, 1.8);\n    int iter = 0;\n    while(true){\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed > phase1_end) break;\n        \n        resetState();\n        \n        double iter_budget = min(phase1_end - elapsed, 0.4);\n        auto iter_start = chrono::steady_clock::now();\n        \n        int maxV, tryRots;\n        int mode = iter % 6;\n        switch(mode){\n            case 0: maxV=1000; tryRots=1; break;\n            case 1: maxV=1000; tryRots=6; break;\n            case 2: maxV=1000; tryRots=24; break;\n            case 3: maxV=1000; tryRots=2; break;\n            case 4: maxV=1000; tryRots=12; break;\n            case 5: maxV=1000; tryRots=4; break;\n        }\n        \n        int nextId = 1;\n        greedyMatch(iter_budget, iter_start, maxV, tryRots, nextId);\n        finalize(nextId);\n        \n        double sc = evalScore(bid);\n        if(sc < bestScore){\n            bestScore = sc;\n            memcpy(best_bid, bid, sizeof(bid));\n        }\n        iter++;\n    }\n    \n    int drIter = 0;\n    while(true){\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed > TL_total - 0.2) break;\n        \n        resetState();\n        memcpy(bid, best_bid, sizeof(bid));\n        \n        int strategy = drIter % 6;\n        int curMaxId = destroyBlocks(strategy);\n        int nextId = curMaxId + 1;\n        \n        double repair_budget = min(TL_total - elapsed - 0.15, 0.35);\n        \n        int maxV, tryRots;\n        int mode = drIter % 5;\n        switch(mode){\n            case 0: maxV=1000; tryRots=2; break;\n            case 1: maxV=1000; tryRots=1; break;\n            case 2: maxV=1000; tryRots=6; break;\n            case 3: maxV=1000; tryRots=12; break;\n            case 4: maxV=1000; tryRots=24; break;\n        }\n        \n        auto repair_start = chrono::steady_clock::now();\n        greedyMatch(repair_budget, repair_start, maxV, tryRots, nextId);\n        finalize(nextId);\n        \n        double sc = evalScore(bid);\n        if(sc < bestScore){\n            bestScore = sc;\n            memcpy(best_bid, bid, sizeof(bid));\n        }\n        drIter++;\n    }\n    \n    int maxId = 0;\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        maxId = max(maxId, best_bid[i][x][y][z]);\n    \n    vector<int> used(maxId+1, 0);\n    for(int i=0;i<2;i++)for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)\n        if(best_bid[i][x][y][z]) used[best_bid[i][x][y][z]]=1;\n    vector<int> remap(maxId+1, 0);\n    int cur = 0;\n    for(int id=1;id<=maxId;id++) if(used[id]) remap[id] = ++cur;\n    \n    cout << cur << \"\\n\";\n    for(int i=0;i<2;i++){\n        bool first=true;\n        for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n            if(!first) cout<<\" \";\n            cout << remap[best_bid[i][x][y][z]];\n            first=false;\n        }\n        cout<<\"\\n\";\n    }\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K;\nvector<int> X, Y;\nvector<int> EU, EV;\nvector<long long> EW;\nvector<int> A, B;\nvector<vector<pair<int,int>>> adj;\nvector<vector<float>> vr;\n\nfloat dist2(float x1,float y1,float x2,float y2){\n    return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));\n}\n\nchrono::steady_clock::time_point startT;\ndouble elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-startT).count();}\n\nlong long computeCost(const vector<int>& P, const vector<int>& edgeOn){\n    long long s=0;\n    for(int i=0;i<N;i++) s += (long long)P[i]*P[i];\n    for(int j=0;j<M;j++) if(edgeOn[j]) s += EW[j];\n    return s;\n}\n\npair<vector<int>, vector<char>> buildTree(const vector<char>& isTerm){\n    vector<int> terms;\n    for(int i=0;i<N;i++) if(isTerm[i]) terms.push_back(i);\n    vector<char> inTree(N,0);\n    inTree[0]=1;\n    vector<int> edgeOn(M,0);\n    while(true){\n        vector<long long> d(N, LLONG_MAX);\n        vector<int> pe(N,-1), pv(N,-1);\n        priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;\n        for(int i=0;i<N;i++) if(inTree[i]){ d[i]=0; pq.push({0,i}); }\n        while(!pq.empty()){\n            auto [du,u]=pq.top(); pq.pop();\n            if(du>d[u]) continue;\n            for(auto [v,eid]:adj[u]){\n                long long nd = du + EW[eid];\n                if(nd<d[v]){ d[v]=nd; pe[v]=eid; pv[v]=u; pq.push({nd,v}); }\n            }\n        }\n        int target=-1; long long bestD=LLONG_MAX;\n        for(int t:terms) if(!inTree[t] && d[t]<bestD){bestD=d[t]; target=t;}\n        if(target==-1) break;\n        int cur=target;\n        while(!inTree[cur]){\n            edgeOn[pe[cur]]=1;\n            inTree[cur]=1;\n            cur = pv[cur];\n        }\n    }\n    return {edgeOn, inTree};\n}\n\nvoid pruneTree(vector<int>& edgeOn, vector<char>& inTree, const vector<char>& isTerm){\n    bool changed=true;\n    while(changed){\n        changed=false;\n        vector<int> deg(N,0);\n        for(int j=0;j<M;j++) if(edgeOn[j]){deg[EU[j]]++; deg[EV[j]]++;}\n        for(int i=1;i<N;i++){\n            if(inTree[i] && !isTerm[i] && deg[i]==1){\n                for(int j=0;j<M;j++) if(edgeOn[j] && (EU[j]==i||EV[j]==i)){\n                    edgeOn[j]=0;\n                    break;\n                }\n                inTree[i]=0;\n                changed=true;\n            }\n        }\n    }\n}\n\npair<vector<int>, bool> computePFromTreeSmart(const vector<char>& inTree){\n    bool allCov = true;\n    vector<int> treeV;\n    for(int i=0;i<N;i++) if(inTree[i]) treeV.push_back(i);\n    if(treeV.empty()) return {vector<int>(N,0), false};\n    \n    vector<pair<float,int>> order(K);\n    for(int k=0;k<K;k++){\n        float bd=1e18f;\n        for(int v:treeV) if(vr[v][k]<bd) bd=vr[v][k];\n        order[k]={bd,k};\n        if(bd > 5000.0f) allCov=false;\n    }\n    if(!allCov) return {vector<int>(N,0), false};\n    \n    sort(order.begin(),order.end(),greater<>());\n    \n    vector<float> r(N,0);\n    for(auto [d_,k]:order){\n        int bestV=-1;\n        float bestInc=1e18f;\n        for(int v:treeV){\n            float cv = vr[v][k];\n            if(cv <= r[v]){ bestV=v; bestInc=0; break; }\n            float newR = cv;\n            if(newR>5000.0f) continue;\n            float inc = newR*newR - r[v]*r[v];\n            if(inc<bestInc){bestInc=inc; bestV=v;}\n        }\n        if(bestV<0){\n            allCov=false;\n            float bd=1e18f; int bv=-1;\n            for(int v:treeV) if(vr[v][k]<bd){bd=vr[v][k]; bv=v;}\n            bestV=bv;\n        }\n        if(vr[bestV][k] > r[bestV]) r[bestV] = vr[bestV][k];\n    }\n    \n    vector<int> P(N,0);\n    for(int i=0;i<N;i++){\n        P[i]=(int)ceilf(r[i]);\n        if(P[i]>5000) P[i]=5000;\n    }\n    // Verify coverage with the ceilf'd P values\n    if(allCov){\n        for(int k=0;k<K;k++){\n            bool ok=false;\n            for(int v:treeV) if(vr[v][k]<=(float)P[v]+1e-4f){ok=true;break;}\n            if(!ok){allCov=false; break;}\n        }\n    }\n    return {P, allCov};\n}\n\nint main(){\n    startT = chrono::steady_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    cin>>N>>M>>K;\n    X.resize(N); Y.resize(N);\n    for(int i=0;i<N;i++) cin>>X[i]>>Y[i];\n    EU.resize(M); EV.resize(M); EW.resize(M);\n    adj.assign(N,{});\n    for(int j=0;j<M;j++){\n        cin>>EU[j]>>EV[j]>>EW[j];\n        EU[j]--; EV[j]--;\n        adj[EU[j]].push_back({EV[j],j});\n        adj[EV[j]].push_back({EU[j],j});\n    }\n    A.resize(K); B.resize(K);\n    for(int k=0;k<K;k++) cin>>A[k]>>B[k];\n    \n    vr.assign(N, vector<float>(K));\n    for(int i=0;i<N;i++)\n        for(int k=0;k<K;k++)\n            vr[i][k] = dist2((float)X[i],(float)Y[i],(float)A[k],(float)B[k]);\n    \n    mt19937 rng(12345);\n    \n    vector<char> isTerm(N,0);\n    isTerm[0]=1;\n    for(int k=0;k<K;k++){\n        int best=0; float bd=vr[0][k];\n        for(int i=1;i<N;i++) if(vr[i][k]<bd){bd=vr[i][k]; best=i;}\n        isTerm[best]=1;\n    }\n    \n    auto evaluate = [&](const vector<char>& nt) -> tuple<long long, vector<int>, vector<int>, vector<char>, bool>{\n        auto [ne, inT] = buildTree(nt);\n        pruneTree(ne, inT, nt);\n        auto [np, cov] = computePFromTreeSmart(inT);\n        long long nc = computeCost(np, ne);\n        return {nc, np, ne, inT, cov};\n    };\n    \n    auto [bestCost0, bestP0, bestEdge0, bestInTree0, cov0] = evaluate(isTerm);\n    // Initial should be covered\n    long long bestCost = bestCost0;\n    vector<int> bestP = bestP0;\n    vector<int> bestEdge = bestEdge0;\n    vector<char> bestInTree = bestInTree0;\n    \n    if(!cov0){\n        // Shouldn't happen but safety: force P=5000 everywhere\n        for(int i=0;i<N;i++) bestP[i]=5000;\n    }\n    \n    vector<char> curTerm(N,0);\n    for(int i=0;i<N;i++) curTerm[i] = bestInTree[i];\n    curTerm[0]=1;\n    long long curCost = bestCost;\n    \n    // Hill climb with feasibility filter\n    int noImproveRounds=0;\n    double phase1End = 0.8;\n    while(elapsed()<phase1End && noImproveRounds<2){\n        bool improved=false;\n        vector<int> order(N);\n        iota(order.begin(),order.end(),0);\n        shuffle(order.begin(),order.end(),rng);\n        for(int v: order){\n            if(v==0) continue;\n            if(elapsed()>phase1End) break;\n            vector<char> nt = curTerm;\n            nt[v] = 1-nt[v];\n            auto [nc, np, ne, inT, cov] = evaluate(nt);\n            if(!cov) continue;\n            if(nc<curCost){\n                curCost=nc;\n                curTerm = nt;\n                for(int i=0;i<N;i++) if(!inT[i]) curTerm[i]=0;\n                curTerm[0]=1;\n                if(nc<bestCost){\n                    bestCost=nc; bestP=np; bestEdge=ne; bestInTree=inT;\n                }\n                improved=true;\n            }\n        }\n        if(!improved) noImproveRounds++;\n        else noImproveRounds=0;\n    }\n    \n    // SA phase\n    double TL = 1.85;\n    double T0=5e5, T1=1e2;\n    int iterSinceBest=0;\n    while(elapsed()<TL){\n        double t = (elapsed()-phase1End)/(TL-phase1End);\n        if(t<0) t=0; if(t>1) t=1;\n        double T = T0 * pow(T1/T0, t);\n        \n        int mt = rng()%3;\n        vector<char> nt = curTerm;\n        if(mt==0 || mt==1){\n            int v = 1 + rng()%(N-1);\n            nt[v] = 1-nt[v];\n        } else {\n            vector<int> terms, nonterms;\n            for(int i=1;i<N;i++){\n                if(nt[i]) terms.push_back(i);\n                else nonterms.push_back(i);\n            }\n            if(terms.empty() || nonterms.empty()) continue;\n            int a = terms[rng()%terms.size()];\n            int b = nonterms[rng()%nonterms.size()];\n            nt[a]=0; nt[b]=1;\n        }\n        auto [nc, np, ne, inT, cov] = evaluate(nt);\n        if(!cov) continue; // reject infeasible\n        double delta = (double)(nc - curCost);\n        if(delta<0 || exp(-delta/T) > (double)(rng()%100000)/100000.0){\n            curCost=nc;\n            curTerm = nt;\n            for(int i=0;i<N;i++) if(!inT[i]) curTerm[i]=0;\n            curTerm[0]=1;\n            if(nc<bestCost){\n                bestCost=nc; bestP=np; bestEdge=ne; bestInTree=inT;\n                iterSinceBest=0;\n            }\n        }\n        iterSinceBest++;\n        if(iterSinceBest > 500){\n            curCost = bestCost;\n            for(int i=0;i<N;i++) curTerm[i] = bestInTree[i];\n            curTerm[0]=1;\n            iterSinceBest=0;\n        }\n    }\n    \n    // Final verification with output\n    // Compute coverage based on bestEdge (true reachability from 0)\n    vector<char> reach(N,0);\n    reach[0]=1;\n    {\n        queue<int> q; q.push(0);\n        while(!q.empty()){\n            int u=q.front(); q.pop();\n            for(auto [v,eid]:adj[u]) if(bestEdge[eid] && !reach[v]){reach[v]=1; q.push(v);}\n        }\n    }\n    // Zero out P for unreachable\n    for(int i=0;i<N;i++) if(!reach[i]) bestP[i]=0;\n    // Check coverage, fix if needed\n    vector<char> uncovered(K,1);\n    for(int k=0;k<K;k++){\n        for(int i=0;i<N;i++) if(reach[i] && vr[i][k]<=(float)bestP[i]+1e-4f){uncovered[k]=0; break;}\n    }\n    // Fix uncovered by boosting P\n    for(int k=0;k<K;k++) if(uncovered[k]){\n        int bv=-1; float bd=1e18f;\n        for(int i=0;i<N;i++) if(reach[i] && vr[i][k]<bd){bd=vr[i][k]; bv=i;}\n        if(bv>=0){\n            int needed = (int)ceilf(bd);\n            if(needed>5000) needed=5000;\n            if(needed>bestP[bv]) bestP[bv]=needed;\n        }\n    }\n    \n    for(int i=0;i<N;i++) cout<<bestP[i]<<\" \\n\"[i==N-1];\n    for(int j=0;j<M;j++) cout<<bestEdge[j]<<\" \\n\"[j==M-1];\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nint N=30;\nint init_grid[30][30];\nint grid[30][30];\npair<int,int> pos[465];\nbool filled[30][30];\nint dist_[30][30];\npair<int,int> prev_[30][30];\n\nint dx6[]={-1,-1,0,0,1,1};\nint dy6[]={-1,0,-1,1,0,1};\n\nmt19937 g_rng(42);\n\ninline bool isAvailable(int x, int y){\n    if(x>=29) return false;\n    if(filled[x][y]) return false;\n    if(x==0) return true;\n    if(y-1>=0 && !filled[x-1][y-1]) return false;\n    if(y<=x-1 && !filled[x-1][y]) return false;\n    return true;\n}\n\nvoid dijkstra(int sx,int sy, int curK, int base, int window, int pw, bool rand_dir){\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)dist_[i][j]=INT_MAX;\n    priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n    dist_[sx][sy]=0; pq.push(make_tuple(0,sx,sy));\n    while(!pq.empty()){\n        tuple<int,int,int> t=pq.top(); pq.pop();\n        int d=get<0>(t), x=get<1>(t), y=get<2>(t);\n        if(d>dist_[x][y]) continue;\n        int perm[6] = {0,1,2,3,4,5};\n        if(rand_dir){\n            for(int i=5; i>0; i--){\n                int j = g_rng() % (i+1);\n                swap(perm[i], perm[j]);\n            }\n        }\n        for(int pi=0;pi<6;pi++){\n            int dr = perm[pi];\n            int nx=x+dx6[dr], ny=y+dy6[dr];\n            if(nx<0||nx>=N||ny<0||ny>nx) continue;\n            if(filled[nx][ny]) continue;\n            int v = grid[nx][ny];\n            int penalty = 0;\n            if(pw > 0 && v - curK <= window) penalty = pw;\n            int nd = d + base + penalty;\n            if(nd < dist_[nx][ny]){\n                dist_[nx][ny]=nd;\n                prev_[nx][ny]=make_pair(x,y);\n                pq.push(make_tuple(nd,nx,ny));\n            }\n        }\n    }\n}\n\nbool validate(){\n    for(int x=0; x<29; x++)for(int y=0; y<=x; y++){\n        if(grid[x][y] >= grid[x+1][y]) return false;\n        if(grid[x][y] >= grid[x+1][y+1]) return false;\n    }\n    return true;\n}\n\nvector<tuple<int,int,int,int>> run(int base, int window, int pw, int rand_tgt_range, bool rand_dir){\n    for(int i=0;i<30;i++)for(int j=0;j<30;j++){\n        grid[i][j] = init_grid[i][j];\n        filled[i][j] = false;\n    }\n    for(int i=0;i<30;i++)for(int j=0;j<=i;j++) pos[grid[i][j]] = make_pair(i,j);\n    \n    vector<tuple<int,int,int,int>> local_ops;\n    local_ops.reserve(5000);\n    \n    for(int k = 0; k < 435; k++){\n        int cx = pos[k].first, cy = pos[k].second;\n        dijkstra(cx, cy, k, base, window, pw, rand_dir);\n        \n        vector<tuple<int,int,int>> cands;\n        for(int x=0; x<29; x++)for(int y=0; y<=x; y++){\n            if(!isAvailable(x,y)) continue;\n            if(dist_[x][y] == INT_MAX) continue;\n            cands.push_back(make_tuple(dist_[x][y], x, y));\n        }\n        if(cands.empty()) return vector<tuple<int,int,int,int>>();\n        sort(cands.begin(), cands.end());\n        int R = min((int)cands.size(), rand_tgt_range);\n        int pick = (R > 1) ? (int)(g_rng() % R) : 0;\n        int btx = get<1>(cands[pick]);\n        int bty = get<2>(cands[pick]);\n        \n        vector<pair<int,int>> path;\n        int x=btx, y=bty;\n        while(!(x==cx && y==cy)){\n            path.push_back(make_pair(x,y));\n            pair<int,int> pp = prev_[x][y];\n            x = pp.first; y = pp.second;\n        }\n        path.push_back(make_pair(cx,cy));\n        reverse(path.begin(), path.end());\n        for(int i=0;i+1<(int)path.size();i++){\n            int x1=path[i].first, y1=path[i].second;\n            int x2=path[i+1].first, y2=path[i+1].second;\n            local_ops.push_back(make_tuple(x1,y1,x2,y2));\n            int v1=grid[x1][y1], v2=grid[x2][y2];\n            swap(grid[x1][y1], grid[x2][y2]);\n            pos[v1] = make_pair(x2,y2); pos[v2] = make_pair(x1,y1);\n        }\n        filled[btx][bty] = true;\n    }\n    \n    return local_ops;\n}\n\nint main(){\n    auto start_time = chrono::steady_clock::now();\n    for(int x=0;x<N;x++)for(int y=0;y<=x;y++){\n        cin>>init_grid[x][y];\n    }\n    \n    vector<tuple<int,int,int,int>> best;\n    int best_size = INT_MAX;\n    \n    vector<tuple<int,int,int>> det_params;\n    det_params.push_back(make_tuple(10000, 0, 0));\n    det_params.push_back(make_tuple(10000, 20, 1));\n    det_params.push_back(make_tuple(10000, 30, 1));\n    det_params.push_back(make_tuple(10000, 50, 1));\n    det_params.push_back(make_tuple(10000, 80, 1));\n    det_params.push_back(make_tuple(10000, 100, 1));\n    det_params.push_back(make_tuple(10, 30, 1));\n    det_params.push_back(make_tuple(10, 50, 1));\n    det_params.push_back(make_tuple(5, 50, 1));\n    det_params.push_back(make_tuple(5, 30, 1));\n    det_params.push_back(make_tuple(1000, 30, 3));\n    det_params.push_back(make_tuple(1000, 50, 3));\n    det_params.push_back(make_tuple(15, 50, 1));\n    det_params.push_back(make_tuple(3, 50, 1));\n    \n    for(size_t idx=0; idx<det_params.size(); idx++){\n        chrono::steady_clock::time_point now = chrono::steady_clock::now();\n        if(chrono::duration<double>(now-start_time).count() > 0.5) break;\n        int b=get<0>(det_params[idx]), w=get<1>(det_params[idx]), p=get<2>(det_params[idx]);\n        vector<tuple<int,int,int,int>> ops = run(b,w,p,1,false);\n        if(ops.empty()) continue;\n        if(!validate()) continue;\n        if((int)ops.size() < best_size){ best_size = (int)ops.size(); best = ops; }\n    }\n    \n    int b_choices[] = {10000, 1000, 500, 100, 50, 30, 20, 10, 7, 5, 3};\n    while(true){\n        chrono::steady_clock::time_point now = chrono::steady_clock::now();\n        if(chrono::duration<double>(now-start_time).count() > 1.7) break;\n        int b = b_choices[g_rng() % 11];\n        int w = 10 + (int)(g_rng() % 120);\n        int p = 1 + (int)(g_rng() % 3);\n        int R = 1 + (int)(g_rng() % 4);\n        bool rd = (g_rng() % 2) == 0;\n        vector<tuple<int,int,int,int>> ops = run(b,w,p,R,rd);\n        if(ops.empty()) continue;\n        if(!validate()) continue;\n        if((int)ops.size() < best_size){ best_size = (int)ops.size(); best = ops; }\n    }\n    \n    cout<<best.size()<<\"\\n\";\n    for(size_t idx=0; idx<best.size(); idx++){\n        int a=get<0>(best[idx]), b=get<1>(best[idx]), c=get<2>(best[idx]), d=get<3>(best[idx]);\n        cout<<a<<\" \"<<b<<\" \"<<c<<\" \"<<d<<\"\\n\";\n    }\n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D, N;\nint obs[9][9];\nint filled[9][9];\nint cellVal[9][9];\nint pidx[9][9];\nint dr[4] = {-1, 1, 0, 0};\nint dc[4] = {0, 0, -1, 1};\n\nvoid bfs_reach(int reach[9][9]) {\n    for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) reach[i][j] = 0;\n    queue<pair<int,int>> q;\n    reach[0][4] = 1;\n    q.push({0, 4});\n    while (!q.empty()) {\n        int r = q.front().first, c = q.front().second;\n        q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d], nc = c + dc[d];\n            if (nr < 0 || nr >= 9 || nc < 0 || nc >= 9) continue;\n            if (reach[nr][nc] || obs[nr][nc] || filled[nr][nc]) continue;\n            reach[nr][nc] = 1;\n            q.push({nr, nc});\n        }\n    }\n}\n\nvector<pair<int,int>> sim_greedy() {\n    int f[9][9];\n    memcpy(f, filled, sizeof(f));\n    vector<pair<int,int>> ord;\n    int total = 0;\n    for (int r=0;r<9;r++) for (int c=0;c<9;c++) if (f[r][c]) total++;\n    for (int step = 0; step < total; step++) {\n        int ev[9][9];\n        for (int i=0;i<9;i++) for (int j=0;j<9;j++) ev[i][j]=0;\n        queue<pair<int,int>> q;\n        ev[0][4]=1; q.push({0,4});\n        while (!q.empty()) {\n            int r=q.front().first, c=q.front().second; q.pop();\n            for (int d=0; d<4; d++) {\n                int nr=r+dr[d], nc=c+dc[d];\n                if (nr<0||nr>=9||nc<0||nc>=9||ev[nr][nc]||obs[nr][nc]||f[nr][nc]) continue;\n                ev[nr][nc]=1; q.push({nr,nc});\n            }\n        }\n        int bv = INT_MAX, br=-1, bc=-1;\n        for (int r=0;r<9;r++) for (int c=0;c<9;c++) {\n            if (!f[r][c]) continue;\n            bool adj=false;\n            for (int d=0; d<4; d++) {\n                int nr=r+dr[d], nc=c+dc[d];\n                if (nr<0||nr>=9||nc<0||nc>=9) continue;\n                if (ev[nr][nc]) { adj=true; break; }\n            }\n            if (!adj) continue;\n            if (cellVal[r][c] < bv) { bv = cellVal[r][c]; br=r; bc=c; }\n        }\n        if (br==-1) break;\n        f[br][bc]=0;\n        ord.push_back({br,bc});\n    }\n    return ord;\n}\n\nvector<pair<int,int>> sim_smart() {\n    int f[9][9];\n    memcpy(f, filled, sizeof(f));\n    vector<pair<int,int>> ord;\n    while (true) {\n        int minV=INT_MAX, mr=-1, mc=-1;\n        for (int r=0;r<9;r++) for (int c=0;c<9;c++)\n            if (f[r][c] && cellVal[r][c]<minV) { minV=cellVal[r][c]; mr=r; mc=c; }\n        if (mr==-1) break;\n        int dist[9][9];\n        pair<int,int> prv[9][9];\n        for (int i=0;i<9;i++) for (int j=0;j<9;j++) { dist[i][j]=INT_MAX; prv[i][j]={-1,-1}; }\n        deque<pair<int,int>> dq;\n        dist[0][4]=0; dq.push_front({0,4});\n        while (!dq.empty()) {\n            int r=dq.front().first, c=dq.front().second; dq.pop_front();\n            for (int d=0; d<4; d++) {\n                int nr=r+dr[d], nc=c+dc[d];\n                if (nr<0||nr>=9||nc<0||nc>=9||obs[nr][nc]) continue;\n                int cost = f[nr][nc]?1:0;\n                if (dist[r][c]+cost < dist[nr][nc]) {\n                    dist[nr][nc]=dist[r][c]+cost;\n                    prv[nr][nc]={r,c};\n                    if (cost==0) dq.push_front({nr,nc});\n                    else dq.push_back({nr,nc});\n                }\n            }\n        }\n        vector<pair<int,int>> path;\n        pair<int,int> cur={mr,mc};\n        int safety=200;\n        while ((cur.first!=0||cur.second!=4) && safety-->0) {\n            path.push_back(cur);\n            auto nxt=prv[cur.first][cur.second];\n            if (nxt.first==-1) break;\n            cur=nxt;\n        }\n        reverse(path.begin(), path.end());\n        int sr=-1,scc=-1;\n        for (auto& p : path) if (f[p.first][p.second]) { sr=p.first; scc=p.second; break; }\n        if (sr==-1) { sr=mr; scc=mc; }\n        f[sr][scc]=0;\n        ord.push_back({sr,scc});\n    }\n    return ord;\n}\n\nlong long count_inv(vector<pair<int,int>>& ord) {\n    int M = ord.size();\n    long long inv = 0;\n    for (int i = 0; i < M; i++) for (int j = i+1; j < M; j++) {\n        if (cellVal[ord[i].first][ord[i].second] > cellVal[ord[j].first][ord[j].second]) inv++;\n    }\n    return inv;\n}\n\nbool shippable_state(int f[9][9], pair<int,int> p) {\n    if (!f[p.first][p.second]) return false;\n    int ev[9][9];\n    for (int i=0;i<9;i++) for (int j=0;j<9;j++) ev[i][j]=0;\n    queue<pair<int,int>> q;\n    ev[0][4]=1; q.push({0,4});\n    while (!q.empty()) {\n        int r=q.front().first, c=q.front().second; q.pop();\n        for (int d=0; d<4; d++) {\n            int nr=r+dr[d], nc=c+dc[d];\n            if (nr<0||nr>=9||nc<0||nc>=9||ev[nr][nc]||obs[nr][nc]||f[nr][nc]) continue;\n            ev[nr][nc]=1; q.push({nr,nc});\n        }\n    }\n    for (int d=0; d<4; d++) {\n        int nr=p.first+dr[d], nc=p.second+dc[d];\n        if (nr<0||nr>=9||nc<0||nc>=9) continue;\n        if (ev[nr][nc]) return true;\n    }\n    return false;\n}\n\nbool try_move_forward(vector<pair<int,int>>& ord, int i, int j) {\n    int f[9][9];\n    memcpy(f, filled, sizeof(f));\n    for (int k = 0; k < i; k++) f[ord[k].first][ord[k].second] = 0;\n    for (int k = i+1; k <= j; k++) {\n        if (!shippable_state(f, ord[k])) return false;\n        f[ord[k].first][ord[k].second] = 0;\n    }\n    if (!shippable_state(f, ord[i])) return false;\n    auto tmp = ord[i];\n    ord.erase(ord.begin() + i);\n    ord.insert(ord.begin() + j, tmp);\n    return true;\n}\n\nbool try_move_backward(vector<pair<int,int>>& ord, int i, int j) {\n    int f[9][9];\n    memcpy(f, filled, sizeof(f));\n    for (int k = 0; k < j; k++) f[ord[k].first][ord[k].second] = 0;\n    if (!shippable_state(f, ord[i])) return false;\n    f[ord[i].first][ord[i].second] = 0;\n    for (int k = j; k < i; k++) {\n        if (!shippable_state(f, ord[k])) return false;\n        f[ord[k].first][ord[k].second] = 0;\n    }\n    auto tmp = ord[i];\n    ord.erase(ord.begin() + i);\n    ord.insert(ord.begin() + j, tmp);\n    return true;\n}\n\nbool try_pair_swap(vector<pair<int,int>>& ord, int i, int j) {\n    int f[9][9];\n    memcpy(f, filled, sizeof(f));\n    for (int k = 0; k < i; k++) f[ord[k].first][ord[k].second] = 0;\n    if (!shippable_state(f, ord[j])) return false;\n    f[ord[j].first][ord[j].second] = 0;\n    for (int k = i+1; k < j; k++) {\n        if (!shippable_state(f, ord[k])) return false;\n        f[ord[k].first][ord[k].second] = 0;\n    }\n    if (!shippable_state(f, ord[i])) return false;\n    swap(ord[i], ord[j]);\n    return true;\n}\n\nbool try_segment_reverse(vector<pair<int,int>>& ord, int i, int j) {\n    int f[9][9];\n    memcpy(f, filled, sizeof(f));\n    for (int k = 0; k < i; k++) f[ord[k].first][ord[k].second] = 0;\n    for (int k = j; k >= i; k--) {\n        if (!shippable_state(f, ord[k])) return false;\n        f[ord[k].first][ord[k].second] = 0;\n    }\n    reverse(ord.begin() + i, ord.begin() + j + 1);\n    return true;\n}\n\nint pair_swap_delta(vector<pair<int,int>>& ord, int i, int j) {\n    int v_i = cellVal[ord[i].first][ord[i].second];\n    int v_j = cellVal[ord[j].first][ord[j].second];\n    int change = 0;\n    change += (v_j > v_i ? 1 : 0) - (v_i > v_j ? 1 : 0);\n    for (int k = i+1; k < j; k++) {\n        int v_k = cellVal[ord[k].first][ord[k].second];\n        change += (v_j > v_k ? 1 : 0) - (v_i > v_k ? 1 : 0);\n        change += (v_k > v_i ? 1 : 0) - (v_k > v_j ? 1 : 0);\n    }\n    return change;\n}\n\nvoid improve_shipping(vector<pair<int,int>>& ord, chrono::steady_clock::time_point t0, double deadline) {\n    int M = ord.size();\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        if (chrono::duration<double>(chrono::steady_clock::now()-t0).count() > deadline) break;\n        \n        for (int i = 0; i < M-1; i++) {\n            if (chrono::duration<double>(chrono::steady_clock::now()-t0).count() > deadline) goto done;\n            int vi = cellVal[ord[i].first][ord[i].second];\n            vector<pair<int,int>> cands;\n            int delta = 0;\n            for (int j = i+1; j < M; j++) {\n                int vj = cellVal[ord[j].first][ord[j].second];\n                if (vj > vi) delta += 1;\n                else delta -= 1;\n                if (delta < 0) cands.push_back({delta, j});\n            }\n            sort(cands.begin(), cands.end());\n            for (auto& p : cands) {\n                if (try_move_forward(ord, i, p.second)) {\n                    improved = true;\n                    break;\n                }\n            }\n        }\n        \n        for (int i = M-1; i >= 1; i--) {\n            if (chrono::duration<double>(chrono::steady_clock::now()-t0).count() > deadline) goto done;\n            int vi = cellVal[ord[i].first][ord[i].second];\n            vector<pair<int,int>> cands;\n            int delta = 0;\n            for (int j = i-1; j >= 0; j--) {\n                int vj = cellVal[ord[j].first][ord[j].second];\n                if (vi > vj) delta += 1;\n                else delta -= 1;\n                if (delta < 0) cands.push_back({delta, j});\n            }\n            sort(cands.begin(), cands.end());\n            for (auto& p : cands) {\n                if (try_move_backward(ord, i, p.second)) {\n                    improved = true;\n                    break;\n                }\n            }\n        }\n        \n        for (int i = 0; i < M-1; i++) {\n            if (chrono::duration<double>(chrono::steady_clock::now()-t0).count() > deadline) goto done;\n            int vi = cellVal[ord[i].first][ord[i].second];\n            for (int j = i+2; j < M; j++) {\n                int vj = cellVal[ord[j].first][ord[j].second];\n                if (vi <= vj) continue;\n                int delta = pair_swap_delta(ord, i, j);\n                if (delta < 0) {\n                    if (try_pair_swap(ord, i, j)) {\n                        improved = true;\n                        vi = cellVal[ord[i].first][ord[i].second];\n                    }\n                }\n            }\n        }\n        \n        // Segment reversal\n        bool seg_improved = false;\n        for (int i = 0; i < M-1 && !seg_improved; i++) {\n            if (chrono::duration<double>(chrono::steady_clock::now()-t0).count() > deadline) goto done;\n            int inv_in_seg = 0;\n            for (int j = i+1; j < M; j++) {\n                int vj = cellVal[ord[j].first][ord[j].second];\n                int cnt = 0;\n                for (int k = i; k < j; k++) {\n                    if (cellVal[ord[k].first][ord[k].second] > vj) cnt++;\n                }\n                inv_in_seg += cnt;\n                int L = j - i + 1;\n                int total = L * (L - 1) / 2;\n                int change = total - 2 * inv_in_seg;\n                if (change < 0 && try_segment_reverse(ord, i, j)) {\n                    improved = true;\n                    seg_improved = true;\n                    break;\n                }\n            }\n        }\n    }\n    done:;\n}\n\nvoid perturb(vector<pair<int,int>>& ord, mt19937& rng, int num_moves) {\n    int M = ord.size();\n    for (int p = 0; p < num_moves; p++) {\n        int move_type = rng() % 4;\n        if (move_type == 0) {\n            int i = rng() % (M - 1);\n            int j = rng() % (M - i - 1) + i + 1;\n            try_move_forward(ord, i, j);\n        } else if (move_type == 1) {\n            int i = rng() % (M - 1);\n            int j = rng() % (M - i - 1) + i + 1;\n            try_move_backward(ord, j, i);\n        } else if (move_type == 2) {\n            if (M >= 3) {\n                int i = rng() % (M - 2);\n                int j = rng() % (M - i - 2) + i + 2;\n                try_pair_swap(ord, i, j);\n            }\n        } else {\n            int i = rng() % (M - 1);\n            int j = rng() % (M - i - 1) + i + 1;\n            try_segment_reverse(ord, i, j);\n        }\n    }\n}\n\nint main() {\n    cin >> D >> N;\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        obs[r][c] = 1;\n    }\n    int M = 81 - 1 - N;\n    for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) cellVal[i][j] = -1;\n    \n    auto t0 = chrono::steady_clock::now();\n    \n    vector<pair<int,int>> order_vec;\n    int vis[9][9];\n    for (int i=0;i<9;i++) for (int j=0;j<9;j++) vis[i][j]=0;\n    queue<pair<int,int>> bq;\n    bq.push({0,4}); vis[0][4]=1;\n    while (!bq.empty()) {\n        auto p = bq.front(); bq.pop();\n        int r=p.first, c=p.second;\n        if (!(r==0&&c==4)) order_vec.push_back({r,c});\n        for (int d=0; d<4; d++) {\n            int nr=r+dr[d], nc=c+dc[d];\n            if (nr<0||nr>=9||nc<0||nc>=9||vis[nr][nc]||obs[nr][nc]) continue;\n            vis[nr][nc]=1;\n            bq.push({nr,nc});\n        }\n    }\n    \n    for (int i=0;i<9;i++) for (int j=0;j<9;j++) pidx[i][j]=-1;\n    for (int k=0; k<(int)order_vec.size(); k++)\n        pidx[order_vec[k].first][order_vec[k].second] = k;\n    \n    for (int d = 0; d < M; d++) {\n        int t;\n        cin >> t;\n        int reach[9][9];\n        bfs_reach(reach);\n        \n        int totalReach = 0;\n        for (int r=0;r<9;r++) for (int c=0;c<9;c++)\n            if (reach[r][c] && !(r==0&&c==4)) totalReach++;\n        \n        int bestK=-1, bestDiff=INT_MAX;\n        int bestSafeK=-1, bestSafeDiff=INT_MAX;\n        int fbR=-1, fbC=-1;\n        \n        for (int r=0;r<9;r++) {\n            for (int c=0;c<9;c++) {\n                if (obs[r][c]||filled[r][c]) continue;\n                if (r==0&&c==4) continue;\n                if (!reach[r][c]) continue;\n                fbR=r; fbC=c;\n                int k=pidx[r][c];\n                if (k<0) continue;\n                int diff=abs(k-t);\n                if (diff<bestDiff || (diff==bestDiff && k>bestK)) { bestDiff=diff; bestK=k; }\n                \n                if (totalReach==1) {\n                    if (diff<bestSafeDiff || (diff==bestSafeDiff && k>bestSafeK)) { bestSafeDiff=diff; bestSafeK=k; }\n                    continue;\n                }\n                \n                filled[r][c]=1;\n                int reach2[9][9];\n                bfs_reach(reach2);\n                filled[r][c]=0;\n                int newReach=0;\n                for (int i=0;i<9;i++) for (int j=0;j<9;j++)\n                    if (reach2[i][j] && !(i==0&&j==4)) newReach++;\n                if (newReach==totalReach-1) {\n                    if (diff<bestSafeDiff || (diff==bestSafeDiff && k>bestSafeK)) { bestSafeDiff=diff; bestSafeK=k; }\n                }\n            }\n        }\n        \n        int pr, pc;\n        if (bestSafeK>=0) { pr=order_vec[bestSafeK].first; pc=order_vec[bestSafeK].second; }\n        else if (bestK>=0) { pr=order_vec[bestK].first; pc=order_vec[bestK].second; }\n        else { pr=fbR; pc=fbC; }\n        filled[pr][pc]=1;\n        cellVal[pr][pc]=t;\n        cout<<pr<<\" \"<<pc<<\"\\n\";\n        cout.flush();\n    }\n    \n    auto g = sim_greedy();\n    auto s = sim_smart();\n    long long gi = count_inv(g);\n    long long si = count_inv(s);\n    auto best = (gi <= si) ? g : s;\n    \n    improve_shipping(best, t0, 0.8);\n    long long best_inv = count_inv(best);\n    \n    mt19937 rng(12345);\n    int iters_without_improve = 0;\n    while (chrono::duration<double>(chrono::steady_clock::now()-t0).count() < 1.85) {\n        auto candidate = best;\n        int nm = 3 + min(iters_without_improve / 3, 10);\n        perturb(candidate, rng, nm);\n        improve_shipping(candidate, t0, 1.85);\n        long long ci = count_inv(candidate);\n        if (ci < best_inv) {\n            best_inv = ci;\n            best = candidate;\n            iters_without_improve = 0;\n        } else {\n            iters_without_improve++;\n        }\n    }\n    \n    for (auto& p : best) cout << p.first << \" \" << p.second << \"\\n\";\n    cout.flush();\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nint grid[55][55];\nint bestGrid[55][55];\nint bestNonZero;\nint curNonZero;\nint DX[4]={-1,1,0,0}, DY[4]={0,0,-1,1};\nvector<vector<int>> origAdj;\nvector<vector<int>> cnt;\nint visVer[55][55];\nint visCur = 0;\n\nbool localConnected(int r, int c, int F){\n    auto at = [&](int x, int y)->int{\n        if(x<0||x>=n||y<0||y>=n) return -1;\n        return grid[x][y];\n    };\n    bool ring[8];\n    ring[0] = at(r-1,c)==F;\n    ring[1] = at(r-1,c+1)==F;\n    ring[2] = at(r,c+1)==F;\n    ring[3] = at(r+1,c+1)==F;\n    ring[4] = at(r+1,c)==F;\n    ring[5] = at(r+1,c-1)==F;\n    ring[6] = at(r,c-1)==F;\n    ring[7] = at(r-1,c-1)==F;\n    int orthCount = (int)ring[0]+ring[2]+ring[4]+ring[6];\n    if(orthCount==0) return false;\n    if(orthCount==1) return true;\n    int trans=0;\n    for(int i=0;i<8;i++)if(ring[i] != ring[(i+1)%8])trans++;\n    return trans<=2;\n}\n\nbool fullRemovableBFS(int r, int c, int F){\n    int sames_r[4], sames_c[4], nsames=0;\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&&grid[nr][nc]==F){\n            sames_r[nsames]=nr; sames_c[nsames]=nc; nsames++;\n        }\n    }\n    if(nsames==0) return false;\n    if(nsames==1) return true;\n    visCur++;\n    static int qx[3000], qy[3000];\n    int qh=0,qt=0;\n    qx[qt]=sames_r[0];qy[qt]=sames_c[0];qt++;\n    visVer[sames_r[0]][sames_c[0]]=visCur;\n    int found=1;\n    while(qh<qt && found<nsames){\n        int x=qx[qh],y=qy[qh];qh++;\n        for(int d=0;d<4;d++){\n            int nx=x+DX[d],ny=y+DY[d];\n            if(nx<0||nx>=n||ny<0||ny>=n)continue;\n            if(visVer[nx][ny]==visCur)continue;\n            if(nx==r&&ny==c)continue;\n            if(grid[nx][ny]!=F)continue;\n            visVer[nx][ny]=visCur;\n            qx[qt]=nx;qy[qt]=ny;qt++;\n            for(int i=0;i<nsames;i++){\n                if(sames_r[i]==nx&&sames_c[i]==ny){found++;break;}\n            }\n        }\n    }\n    return found==nsames;\n}\n\nbool removable(int r, int c, int F){\n    if(localConnected(r,c,F))return true;\n    return fullRemovableBFS(r,c,F);\n}\n\nbool tryChange(int r, int c, int T){\n    int F = grid[r][c];\n    if(F==T)return false;\n    int nbrs[4];\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)nbrs[d]=0;\n        else nbrs[d]=grid[nr][nc];\n    }\n    bool tOk=false;\n    if(T==0){\n        if(r==0||r==n-1||c==0||c==n-1) tOk=true;\n        else for(int d=0;d<4;d++)if(nbrs[d]==0){tOk=true;break;}\n    } else {\n        for(int d=0;d<4;d++)if(nbrs[d]==T){tOk=true;break;}\n    }\n    if(!tOk) return false;\n    \n    for(int d=0;d<4;d++){\n        int N=nbrs[d];\n        if(F != N){ cnt[F][N]--; cnt[N][F]--; }\n        if(T != N){ cnt[T][N]++; cnt[N][T]++; }\n    }\n    \n    bool ok=true;\n    auto chk=[&](int a,int b)->bool{\n        if(a==b)return true;\n        return (origAdj[a][b]!=0)==(cnt[a][b]>0);\n    };\n    for(int d=0;d<4;d++){\n        int N=nbrs[d];\n        if(N!=F && !chk(F,N)){ok=false;break;}\n        if(ok && N!=T && !chk(T,N)){ok=false;break;}\n    }\n    if(ok && !chk(F,T))ok=false;\n    \n    auto revert=[&](){\n        for(int d=0;d<4;d++){\n            int N=nbrs[d];\n            if(T != N){ cnt[T][N]--; cnt[N][T]--; }\n            if(F != N){ cnt[F][N]++; cnt[N][F]++; }\n        }\n    };\n    \n    if(!ok){ revert(); return false; }\n    \n    grid[r][c]=T;\n    if(!removable(r,c,F)){\n        grid[r][c]=F;\n        revert();\n        return false;\n    }\n    if(F!=0 && T==0) curNonZero--;\n    else if(F==0 && T!=0) curNonZero++;\n    return true;\n}\n\nvoid saveBest(){\n    if(curNonZero < bestNonZero){\n        bestNonZero = curNonZero;\n        memcpy(bestGrid, grid, sizeof(grid));\n    }\n}\n\nstruct Edge { short r,c,d; };\nvector<Edge> edges;\nvoid collectEdges(){\n    edges.clear();\n    edges.reserve(8000);\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        int c_=grid[i][j];\n        for(int d=0;d<4;d++){\n            int ni=i+DX[d],nj=j+DY[d];\n            int nc = (ni<0||ni>=n||nj<0||nj>=n) ? 0 : grid[ni][nj];\n            if(c_ != nc) edges.push_back({(short)i,(short)j,(short)d});\n        }\n    }\n}\n\nint main(){\n    cin>>n>>m;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)cin>>grid[i][j];\n    for(int i=0;i<55;i++)for(int j=0;j<55;j++)visVer[i][j]=0;\n    \n    cnt.assign(m+1, vector<int>(m+1, 0));\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        int a=grid[i][j];\n        for(int d=0;d<4;d++){\n            int ni=i+DX[d],nj=j+DY[d];\n            if(ni<0||ni>=n||nj<0||nj>=n){\n                cnt[a][0]++; cnt[0][a]++;\n            } else {\n                int b=grid[ni][nj];\n                cnt[a][b]++;\n            }\n        }\n    }\n    origAdj.assign(m+1, vector<int>(m+1,0));\n    for(int a=0;a<=m;a++)for(int b=0;b<=m;b++)if(a!=b && cnt[a][b]>0)origAdj[a][b]=1;\n    \n    curNonZero=0;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(grid[i][j]!=0)curNonZero++;\n    \n    bestNonZero = curNonZero;\n    memcpy(bestGrid, grid, sizeof(grid));\n    \n    auto startTime = chrono::steady_clock::now();\n    auto elapsed = [&]()->long long{\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();\n    };\n    mt19937 rng(42);\n    uniform_real_distribution<double> urd(0.0, 1.0);\n    \n    // Initial greedy\n    for(int pass=0; pass<15 && elapsed()<200; pass++){\n        vector<pair<int,int>> cells;\n        for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(grid[i][j]!=0)cells.push_back({i,j});\n        shuffle(cells.begin(), cells.end(), rng);\n        bool any=false;\n        for(auto[r,c]:cells){\n            if(grid[r][c]==0)continue;\n            if(tryChange(r,c,0))any=true;\n        }\n        if(!any)break;\n    }\n    saveBest();\n    \n    long long TL = 1900;\n    double T_start = 1.5, T_end = 0.02;\n    int sinceCollect=0;\n    collectEdges();\n    \n    while(elapsed() < TL){\n        double progress = (double)elapsed() / (double)TL;\n        double Temp = T_start * pow(T_end/T_start, progress);\n        bool preferZeroFlip = (Temp < 0.2);\n        \n        for(int k=0;k<15000 && elapsed()<TL;k++){\n            if(edges.empty()){collectEdges(); if(edges.empty())break;}\n            int ei = rng()%edges.size();\n            Edge e = edges[ei];\n            int r=e.r, c=e.c, d=e.d;\n            int F = grid[r][c];\n            int ni=r+DX[d], nj=c+DY[d];\n            bool outside = (ni<0||ni>=n||nj<0||nj>=n);\n            int T_color = outside ? 0 : grid[ni][nj];\n            if(F==T_color) continue;\n            \n            int chosenR, chosenC, chosenT, chosenF;\n            bool reverseDir;\n            if(preferZeroFlip){\n                if(F!=0 && T_color==0){\n                    reverseDir = false;\n                } else if(F==0 && T_color!=0){\n                    reverseDir = !outside;\n                } else {\n                    reverseDir = (rng()&1) && !outside;\n                }\n            } else {\n                reverseDir = (rng()&1) && !outside;\n            }\n            \n            if(!reverseDir){\n                chosenR=r; chosenC=c; chosenT=T_color; chosenF=F;\n            } else {\n                chosenR=ni; chosenC=nj; chosenT=F; chosenF=T_color;\n            }\n            int delta = 0;\n            if(chosenF==0 && chosenT!=0) delta=1;\n            else if(chosenF!=0 && chosenT==0) delta=-1;\n            \n            if(delta > 0){\n                double p = exp(-(double)delta/Temp);\n                if(urd(rng) > p) continue;\n            }\n            \n            if(tryChange(chosenR,chosenC,chosenT)){\n                if(curNonZero < bestNonZero) saveBest();\n                sinceCollect++;\n                if(sinceCollect > 200){\n                    collectEdges();\n                    sinceCollect = 0;\n                }\n            }\n        }\n        \n        // Greedy 0-flip exploit pass\n        collectEdges();\n        static bool seen_[55][55];\n        for(int i=0;i<n;i++)for(int j=0;j<n;j++)seen_[i][j]=false;\n        vector<pair<int,int>> bdCells;\n        for(auto&e:edges){\n            if(grid[e.r][e.c]!=0 && !seen_[e.r][e.c]){\n                seen_[e.r][e.c]=true;\n                bdCells.push_back({e.r,e.c});\n            }\n        }\n        shuffle(bdCells.begin(), bdCells.end(), rng);\n        for(auto[r,c]:bdCells){\n            if(grid[r][c]==0)continue;\n            if(tryChange(r,c,0)){\n                if(curNonZero < bestNonZero) saveBest();\n            }\n        }\n        collectEdges();\n        sinceCollect = 0;\n    }\n    \n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            cout<<bestGrid[i][j]<<(j+1<n?' ':'\\n');\n        }\n    }\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\nint ask(const vector<int>& L, const vector<int>& R) {\n    queries_used++;\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << \"\\n\";\n    cout.flush();\n    char c; cin >> c;\n    if (c == '<') return -1;\n    if (c == '>') return 1;\n    return 0;\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    int expected_sort_cost = (int)(N * log2(max(2, N))) + N;\n    int sort_budget = min((int)(Q * 0.7), expected_sort_cost);\n    int reserve = Q - sort_budget;\n    \n    function<vector<int>(vector<int>)> msort = [&](vector<int> v) -> vector<int> {\n        if (v.size() <= 1) return v;\n        int mid = v.size()/2;\n        vector<int> L(v.begin(), v.begin()+mid);\n        vector<int> R(v.begin()+mid, v.end());\n        L = msort(L);\n        R = msort(R);\n        vector<int> res;\n        int i=0,j=0;\n        while (i<(int)L.size() && j<(int)R.size()) {\n            if (queries_used >= Q - reserve) {\n                while (i<(int)L.size()) res.push_back(L[i++]);\n                while (j<(int)R.size()) res.push_back(R[j++]);\n                return res;\n            }\n            int c = ask({L[i]}, {R[j]});\n            if (c <= 0) res.push_back(L[i++]);\n            else res.push_back(R[j++]);\n        }\n        while (i<(int)L.size()) res.push_back(L[i++]);\n        while (j<(int)R.size()) res.push_back(R[j++]);\n        return res;\n    };\n    \n    vector<int> sorted_items = msort(items);\n    reverse(sorted_items.begin(), sorted_items.end());\n    \n    vector<double> est_weight(N);\n    for (int k = 0; k < N; k++) {\n        double s = 0;\n        for (int i = k+1; i <= N; i++) s += 1.0/i;\n        est_weight[sorted_items[k]] = s;\n    }\n    \n    auto gweight = [&](const vector<int>& g) {\n        double s = 0;\n        for (int x : g) s += est_weight[x];\n        return s;\n    };\n    \n    vector<vector<int>> groups(D);\n    for (int i = 0; i < N; i++) {\n        int best = 0;\n        double bestv = gweight(groups[0]);\n        for (int d = 1; d < D; d++) {\n            double v = gweight(groups[d]);\n            if (v < bestv) { bestv = v; best = d; }\n        }\n        groups[best].push_back(sorted_items[i]);\n    }\n    \n    auto try_move = [&](int heavy, int light, const vector<int>& from_h, const vector<int>& from_l) -> int {\n        if (queries_used >= Q) return -1;\n        int h_new = (int)groups[heavy].size() - (int)from_h.size() + (int)from_l.size();\n        int l_new = (int)groups[light].size() - (int)from_l.size() + (int)from_h.size();\n        if (h_new == 0 || l_new == 0) return -1;\n        \n        set<int> sh(from_h.begin(), from_h.end());\n        set<int> sl(from_l.begin(), from_l.end());\n        vector<int> nh, nl;\n        for (int z : groups[heavy]) if (!sh.count(z)) nh.push_back(z);\n        for (int y : from_l) nh.push_back(y);\n        for (int z : groups[light]) if (!sl.count(z)) nl.push_back(z);\n        for (int y : from_h) nl.push_back(y);\n        \n        int c = ask(nh, nl);\n        if (c >= 0) {\n            groups[heavy] = nh;\n            groups[light] = nl;\n            return c > 0 ? 1 : 0;\n        }\n        return -1;\n    };\n    \n    set<pair<int,int>> failed_pairs;\n    int total_resets = 0;\n    \n    auto clear_involving = [&](int a, int b) {\n        set<pair<int,int>> keep;\n        for (auto& p : failed_pairs) {\n            if (p.first != a && p.first != b && p.second != a && p.second != b) {\n                keep.insert(p);\n            }\n        }\n        failed_pairs = keep;\n    };\n    \n    while (queries_used < Q - 1) {\n        vector<int> order(D);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b){\n            return gweight(groups[a]) > gweight(groups[b]);\n        });\n        \n        int heavy = -1, light = -1;\n        for (int i = 0; i < D && heavy == -1; i++) {\n            for (int j = D-1; j > i && heavy == -1; j--) {\n                int A = order[i], B = order[j];\n                auto p = make_pair(min(A,B), max(A,B));\n                if (failed_pairs.count(p)) continue;\n                heavy = A;\n                light = B;\n            }\n        }\n        if (heavy == -1) {\n            failed_pairs.clear();\n            total_resets++;\n            if (total_resets > 3) break;\n            continue;\n        }\n        \n        if (queries_used >= Q) break;\n        int c = ask(groups[heavy], groups[light]);\n        auto pair_key = make_pair(min(heavy, light), max(heavy, light));\n        \n        if (c == 0) {\n            failed_pairs.insert(pair_key);\n            continue;\n        }\n        if (c < 0) swap(heavy, light);\n        \n        bool any_improved = false;\n        while (queries_used < Q) {\n            vector<int> hi = groups[heavy];\n            sort(hi.begin(), hi.end(), [&](int a, int b){ return est_weight[a] < est_weight[b]; });\n            \n            if ((int)groups[heavy].size() <= 1) break;\n            int x = hi[0];\n            \n            int r = try_move(heavy, light, {x}, {});\n            if (r >= 0) {\n                any_improved = true;\n                if (r == 0) break;\n                continue;\n            }\n            \n            bool sub_improved = false;\n            vector<int> li_sorted = groups[light];\n            sort(li_sorted.begin(), li_sorted.end(), [&](int a, int b){ return est_weight[a] < est_weight[b]; });\n            \n            double est_diff = gweight(groups[heavy]) - gweight(groups[light]);\n            if (est_diff < 0.01) est_diff = 0.01;\n            \n            vector<int> y_candidates;\n            for (int y : li_sorted) {\n                if (est_weight[y] < est_weight[x]) {\n                    y_candidates.push_back(y);\n                    break;\n                }\n            }\n            double target = est_weight[x] - est_diff / 2.0;\n            for (int y : li_sorted) {\n                if (est_weight[y] >= est_weight[x]) break;\n                if (est_weight[y] >= target) {\n                    if (y_candidates.empty() || y != y_candidates[0]) y_candidates.push_back(y);\n                    break;\n                }\n            }\n            \n            for (int y : y_candidates) {\n                if (queries_used >= Q) break;\n                int r2 = try_move(heavy, light, {x}, {y});\n                if (r2 >= 0) {\n                    any_improved = true;\n                    sub_improved = true;\n                    break;\n                }\n            }\n            if (sub_improved) continue;\n            \n            vector<tuple<double,int,int>> pairs;\n            for (int a : groups[heavy]) for (int b : groups[light]) {\n                if (est_weight[a] > est_weight[b]) {\n                    pairs.push_back({est_weight[a] - est_weight[b], a, b});\n                }\n            }\n            sort(pairs.begin(), pairs.end());\n            bool sw_improved = false;\n            for (auto& [diff, a, b] : pairs) {\n                if (queries_used >= Q) break;\n                int r2 = try_move(heavy, light, {a}, {b});\n                if (r2 >= 0) {\n                    any_improved = true;\n                    sw_improved = true;\n                    break;\n                }\n                break;\n            }\n            if (sw_improved) continue;\n            \n            break;\n        }\n        \n        if (any_improved) {\n            clear_involving(heavy, light);\n        } else {\n            failed_pairs.insert(pair_key);\n        }\n    }\n    \n    while (queries_used < Q) ask({0}, {1});\n    \n    vector<int> d(N, 0);\n    for (int g = 0; g < D; g++) for (int x : groups[g]) d[x] = g;\n    for (int i = 0; i < N; i++) {\n        cout << d[i];\n        cout << (i == N-1 ? '\\n' : ' ');\n    }\n    cout.flush();\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nmt19937 rng(42);\n\nconst int MAXN = 210;\nconst int MAXM = 12;\nconst int MAXST = 210;\nconst int MAX_SPLIT_OPTS = 3;\n\nstruct State {\n    int stk[MAXM][MAXST];\n    int sz[MAXM];\n    int posS[MAXN], posD[MAXN];\n};\n\nState gst, savedInit;\n\nstruct Action {\n    int type, si, pos, dest, k, box;\n};\n\nvector<Action> log_;\n\ninline void doMove(int si, int pos, int dest) {\n    int k = gst.sz[si] - pos - 1;\n    log_.push_back({0, si, pos, dest, k, 0});\n    int base = gst.sz[dest];\n    for (int j = 0; j < k; j++) {\n        int b = gst.stk[si][pos + 1 + j];\n        gst.stk[dest][base + j] = b;\n        gst.posS[b] = dest;\n        gst.posD[b] = base + j;\n    }\n    gst.sz[dest] += k;\n    gst.sz[si] = pos + 1;\n}\n\ninline void doPop(int si) {\n    int b = gst.stk[si][gst.sz[si] - 1];\n    log_.push_back({1, si, 0, 0, 0, b});\n    gst.sz[si]--;\n}\n\ninline void undoOne() {\n    Action a = log_.back(); log_.pop_back();\n    if (a.type == 1) {\n        gst.stk[a.si][gst.sz[a.si]] = a.box;\n        gst.posS[a.box] = a.si;\n        gst.posD[a.box] = gst.sz[a.si];\n        gst.sz[a.si]++;\n    } else {\n        int basedest = gst.sz[a.dest] - a.k;\n        for (int j = 0; j < a.k; j++) {\n            int b = gst.stk[a.dest][basedest + j];\n            gst.stk[a.si][a.pos + 1 + j] = b;\n            gst.posS[b] = a.si;\n            gst.posD[b] = a.pos + 1 + j;\n        }\n        gst.sz[a.si] += a.k;\n        gst.sz[a.dest] -= a.k;\n    }\n}\n\ninline void undoTo(int mark) {\n    while ((int)log_.size() > mark) undoOne();\n}\n\nint chooseDestination(int si, int pos, int jitter) {\n    int maxMoved = 0;\n    for (int j = pos + 1; j < gst.sz[si]; j++)\n        if (gst.stk[si][j] > maxMoved) maxMoved = gst.stk[si][j];\n    \n    int mins[MAXM];\n    for (int i = 0; i < m; i++) {\n        if (gst.sz[i] == 0) mins[i] = INT_MAX;\n        else {\n            int mn = INT_MAX;\n            for (int j = 0; j < gst.sz[i]; j++)\n                if (gst.stk[i][j] < mn) mn = gst.stk[i][j];\n            mins[i] = mn;\n        }\n    }\n    \n    int best = -1;\n    int bestScore = INT_MAX;\n    int emptyStack = -1;\n    for (int i = 0; i < m; i++) {\n        if (i == si) continue;\n        if (gst.sz[i] == 0) { if (emptyStack == -1) emptyStack = i; continue; }\n        if (mins[i] > maxMoved) {\n            int score = mins[i] - maxMoved;\n            if (jitter > 0) score += (int)(rng() % (jitter + 1));\n            if (score < bestScore) { bestScore = score; best = i; }\n        }\n    }\n    if (best == -1 && emptyStack != -1) best = emptyStack;\n    if (best == -1) {\n        bestScore = INT_MAX;\n        int bestTop = -1;\n        for (int i = 0; i < m; i++) {\n            if (i == si) continue;\n            int mn = mins[i];\n            int above_mn = 0;\n            for (int j = gst.sz[i] - 1; j >= 0; j--) {\n                if (gst.stk[i][j] == mn) break;\n                above_mn++;\n            }\n            int cnt = 0;\n            for (int j = pos + 1; j < gst.sz[si]; j++)\n                if (gst.stk[si][j] > mn) cnt++;\n            int score = cnt + above_mn;\n            if (jitter > 0) score += (int)(rng() % (jitter + 1));\n            int t = gst.stk[i][gst.sz[i] - 1];\n            if (score < bestScore || (score == bestScore && t > bestTop)) {\n                bestScore = score; best = i; bestTop = t;\n            }\n        }\n    }\n    return best;\n}\n\nint rolloutCost(int startV, int jitter) {\n    int cost = 0;\n    int mark = log_.size();\n    for (int v = startV; v <= n; v++) {\n        int si = gst.posS[v];\n        int pos = gst.posD[v];\n        int above = gst.sz[si] - 1 - pos;\n        if (above > 0) {\n            int dest = chooseDestination(si, pos, jitter);\n            cost += above + 1;\n            doMove(si, pos, dest);\n        }\n        doPop(si);\n    }\n    undoTo(mark);\n    return cost;\n}\n\nint autoExtract(int w) {\n    while (w <= n) {\n        int wi = gst.posS[w];\n        int wpos = gst.posD[w];\n        if (wpos == gst.sz[wi] - 1) { doPop(wi); w++; }\n        else break;\n    }\n    return w;\n}\n\nstruct Option {\n    int type;\n    int d1;\n    int j, d_top, d_rem;\n    int actionCost;\n};\n\nint generateOptions(int si, int pos, Option* opts, bool allowSplit) {\n    int numOpts = 0;\n    int k = gst.sz[si] - pos - 1;\n    \n    int mins[MAXM];\n    for (int i = 0; i < m; i++) {\n        if (gst.sz[i] == 0) mins[i] = INT_MAX;\n        else { int mn = INT_MAX; for (int j = 0; j < gst.sz[i]; j++) if (gst.stk[i][j] < mn) mn = gst.stk[i][j]; mins[i] = mn; }\n    }\n    \n    for (int d = 0; d < m; d++) {\n        if (d == si) continue;\n        opts[numOpts].type = 0;\n        opts[numOpts].d1 = d;\n        opts[numOpts].actionCost = k + 1;\n        numOpts++;\n    }\n    \n    if (!allowSplit || k < 2) return numOpts;\n    \n    int sufMax[MAXST + 2];\n    sufMax[k] = 0;\n    for (int j = k - 1; j >= 0; j--)\n        sufMax[j] = max(sufMax[j+1], gst.stk[si][pos + 1 + j]);\n    int preMax[MAXST + 2];\n    preMax[0] = 0;\n    for (int j = 0; j < k; j++)\n        preMax[j+1] = max(preMax[j], gst.stk[si][pos + 1 + j]);\n    \n    struct SplitCand { int j, dt, dr, score; };\n    SplitCand cands[500];\n    int nCands = 0;\n    \n    for (int j = 1; j < k; j++) {\n        int mxTop = sufMax[j];\n        int mxPre = preMax[j];\n        for (int dt = 0; dt < m; dt++) {\n            if (dt == si) continue;\n            if (mins[dt] <= mxTop) continue;  // d_top must be safe\n            // Find best d_rem: safe if possible, else best unsafe\n            int dr_safe = -1, dr_safe_min = INT_MAX;\n            for (int i = 0; i < m; i++) {\n                if (i == si || i == dt) continue;\n                if (mins[i] > mxPre && mins[i] < dr_safe_min) { dr_safe_min = mins[i]; dr_safe = i; }\n            }\n            int dr, scoreMod;\n            if (dr_safe != -1) {\n                dr = dr_safe;\n                scoreMod = dr_safe_min;\n            } else {\n                // Unsafe rem: pick stack with largest mins\n                int dr_best = -1, dr_best_min = -1;\n                for (int i = 0; i < m; i++) {\n                    if (i == si || i == dt) continue;\n                    int mn = (mins[i] == INT_MAX) ? (n + 10) : mins[i];\n                    if (mn > dr_best_min) { dr_best_min = mn; dr_best = i; }\n                }\n                if (dr_best == -1) continue;\n                dr = dr_best;\n                scoreMod = 1000;  // penalty\n            }\n            int score = mins[dt] + scoreMod;\n            if (nCands < 500) cands[nCands++] = {j, dt, dr, score};\n        }\n    }\n    \n    int take = min(MAX_SPLIT_OPTS, nCands);\n    if (take > 0) {\n        partial_sort(cands, cands + take, cands + nCands,\n                     [](const SplitCand& a, const SplitCand& b) { return a.score < b.score; });\n        for (int i = 0; i < take; i++) {\n            opts[numOpts].type = 1;\n            opts[numOpts].j = cands[i].j;\n            opts[numOpts].d_top = cands[i].dt;\n            opts[numOpts].d_rem = cands[i].dr;\n            opts[numOpts].actionCost = k + 2;\n            numOpts++;\n        }\n    }\n    \n    return numOpts;\n}\n\nvoid applyOption(const Option& o, int si, int pos) {\n    if (o.type == 0) {\n        doMove(si, pos, o.d1);\n    } else {\n        int splitPos = pos + o.j;\n        doMove(si, splitPos, o.d_top);\n        doMove(si, pos, o.d_rem);\n    }\n}\n\npair<int, vector<pair<int,int>>> runOnce(int mainJitter, int rollJitter, bool useSplit) {\n    gst = savedInit;\n    log_.clear();\n    int totalCost = 0;\n    vector<pair<int,int>> ops;\n    ops.reserve(2000);\n    \n    Option opts[100];\n    \n    for (int v = 1; v <= n; v++) {\n        int si = gst.posS[v];\n        int pos = gst.posD[v];\n        int sz = gst.sz[si];\n        int above = sz - 1 - pos;\n        \n        if (above > 0) {\n            int numOpts = generateOptions(si, pos, opts, useSplit);\n            \n            int bestIdx = -1;\n            int bestTotal = INT_MAX;\n            \n            for (int oi = 0; oi < numOpts; oi++) {\n                const Option& o = opts[oi];\n                int markL1 = log_.size();\n                applyOption(o, si, pos);\n                doPop(si);\n                \n                int w = autoExtract(v + 1);\n                \n                int oCost;\n                if (w > n) { oCost = o.actionCost; }\n                else {\n                    int wi = gst.posS[w];\n                    int wpos = gst.posD[w];\n                    int w_above = gst.sz[wi] - 1 - wpos;\n                    \n                    if (w_above == 0) {\n                        int markL2 = log_.size();\n                        doPop(wi);\n                        int w2 = autoExtract(w + 1);\n                        oCost = o.actionCost + ((w2 > n) ? 0 : rolloutCost(w2, rollJitter));\n                        undoTo(markL2);\n                    } else {\n                        int wImm = w_above + 1;\n                        int bestW = INT_MAX;\n                        for (int d2 = 0; d2 < m; d2++) {\n                            if (d2 == wi) continue;\n                            int markL2 = log_.size();\n                            doMove(wi, wpos, d2);\n                            doPop(wi);\n                            int w2 = autoExtract(w + 1);\n                            int total = (w2 > n) ? wImm : wImm + rolloutCost(w2, rollJitter);\n                            if (total < bestW) bestW = total;\n                            undoTo(markL2);\n                        }\n                        oCost = o.actionCost + bestW;\n                    }\n                }\n                \n                if (mainJitter > 0) oCost += (int)(rng() % (mainJitter + 1));\n                if (oCost < bestTotal) { bestTotal = oCost; bestIdx = oi; }\n                \n                undoTo(markL1);\n            }\n            \n            const Option& best = opts[bestIdx];\n            totalCost += best.actionCost;\n            if (best.type == 0) {\n                int movedBoxTop = gst.stk[si][pos + 1];\n                ops.push_back({movedBoxTop, best.d1 + 1});\n            } else {\n                int splitPos = pos + best.j;\n                int topBox = gst.stk[si][splitPos + 1];\n                int remBox = gst.stk[si][pos + 1];\n                ops.push_back({topBox, best.d_top + 1});\n                ops.push_back({remBox, best.d_rem + 1});\n            }\n            applyOption(best, si, pos);\n        }\n        ops.push_back({v, 0});\n        doPop(si);\n    }\n    \n    return {totalCost, ops};\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    cin >> n >> m;\n    memset(gst.sz, 0, sizeof(gst.sz));\n    memset(gst.posS, -1, sizeof(gst.posS));\n    memset(gst.posD, -1, sizeof(gst.posD));\n    \n    for (int i = 0; i < m; i++) {\n        int sz = n / m;\n        for (int j = 0; j < sz; j++) {\n            int b; cin >> b;\n            gst.stk[i][j] = b;\n            gst.posS[b] = i;\n            gst.posD[b] = j;\n            gst.sz[i] = j + 1;\n        }\n    }\n    savedInit = gst;\n    \n    auto startTime = chrono::steady_clock::now();\n    \n    auto [c0, ops0] = runOnce(0, 0, false);\n    int bestCost = c0;\n    vector<pair<int,int>> bestOps = ops0;\n    \n    double elapsed = chrono::duration<double>(chrono::steady_clock::now() - startTime).count();\n    if (elapsed < 0.9) {\n        auto [c1, ops1] = runOnce(0, 0, true);\n        if (c1 < bestCost) { bestCost = c1; bestOps = ops1; }\n    }\n    \n    for (auto& [a, b] : bestOps) cout << a << \" \" << b << \"\\n\";\n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> hh, vv;\nvector<vector<int>> d;\nint dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};\nchar DC[4]={'U','D','L','R'};\n\nbool canMove(int x,int y,int dir){\n    int nx=x+dx[dir], ny=y+dy[dir];\n    if(nx<0||nx>=N||ny<0||ny>=N) return false;\n    if(dir==0) return hh[nx][y]=='0';\n    if(dir==1) return hh[x][y]=='0';\n    if(dir==2) return vv[x][ny]=='0';\n    if(dir==3) return vv[x][y]=='0';\n    return false;\n}\n\nvector<vector<vector<vector<int>>>> allPar;\nvector<vector<vector<vector<int>>>> allD;\n\nvoid computeAllDist(){\n    allPar.assign(N,vector<vector<vector<int>>>(N,vector<vector<int>>(N,vector<int>(N,-1))));\n    allD.assign(N,vector<vector<vector<int>>>(N,vector<vector<int>>(N,vector<int>(N,INT_MAX))));\n    for(int sx=0;sx<N;sx++)for(int sy=0;sy<N;sy++){\n        auto& D=allD[sx][sy];\n        auto& P=allPar[sx][sy];\n        D[sx][sy]=0;\n        queue<pair<int,int>> q; q.push({sx,sy});\n        while(!q.empty()){\n            auto [x,y]=q.front(); q.pop();\n            for(int d2=0;d2<4;d2++) if(canMove(x,y,d2)){\n                int nx=x+dx[d2], ny=y+dy[d2];\n                if(D[nx][ny]>D[x][y]+1){ D[nx][ny]=D[x][y]+1; P[nx][ny]=d2; q.push({nx,ny}); }\n            }\n        }\n    }\n}\n\nvector<int> getPath(int sx,int sy,int tx,int ty){\n    vector<int> res;\n    int x=tx,y=ty;\n    while(!(x==sx&&y==sy)){\n        int dir=allPar[sx][sy][x][y];\n        if(dir<0) return {};\n        res.push_back(dir);\n        int rdir = dir^1;\n        x+=dx[rdir]; y+=dy[rdir];\n    }\n    reverse(res.begin(),res.end());\n    return res;\n}\n\nvector<int> dfsResult;\nvector<vector<bool>> dfsVisited;\nvoid dfs(int x,int y){\n    dfsVisited[x][y]=true;\n    for(int dir=0;dir<4;dir++){\n        if(canMove(x,y,dir)){\n            int nx=x+dx[dir],ny=y+dy[dir];\n            if(!dfsVisited[nx][ny]){\n                dfsResult.push_back(dir);\n                dfs(nx,ny);\n                dfsResult.push_back(dir^1);\n            }\n        }\n    }\n}\n\nstatic vector<vector<int>> timesFlat;\ndouble computeScore(const vector<int>& tr){\n    int L=tr.size();\n    if(L==0) return 1e18;\n    for(auto& v : timesFlat) v.clear();\n    int x=0,y=0;\n    timesFlat[0].push_back(0);\n    for(int t=0;t<L;t++){\n        x+=dx[tr[t]]; y+=dy[tr[t]];\n        timesFlat[x*N+y].push_back(t+1);\n    }\n    if(x!=0||y!=0) return 1e18;\n    double total=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        auto& T=timesFlat[i*N+j];\n        if(T.empty()) return 1e18;\n        int k = T.size();\n        int endIdx = k;\n        if(T[k-1] == L) endIdx = k-1;\n        if(endIdx == 0) return 1e18;\n        long long sumSq=0;\n        for(int m=0;m<endIdx;m++){\n            int g = (m+1<endIdx ? T[m+1]-T[m] : T[0]+L-T[m]);\n            sumSq += (long long)g*(g-1)/2;\n        }\n        total += (double)d[i][j] * sumSq;\n    }\n    return total / L;\n}\n\nvector<int> greedyTour(double alpha, double unvisitedBonus){\n    vector<vector<int>> last(N, vector<int>(N, 0));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    visited[0][0] = true;\n    int cx=0, cy=0;\n    int t=0;\n    vector<int> result;\n    int unvisitedCount = N*N - 1;\n    int maxLen = 90000;\n    \n    while(t < maxLen){\n        if(unvisitedCount == 0){\n            if(cx==0 && cy==0 && t > 0) break;\n        }\n        \n        double bestScore = -1;\n        int btx=-1, bty=-1;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            if(i==cx && j==cy) continue;\n            int dist = allD[cx][cy][i][j];\n            if(dist<=0 || dist==INT_MAX) continue;\n            int elapsed_v = t - last[i][j];\n            double score;\n            if(!visited[i][j]){\n                score = (double)d[i][j] * (double)elapsed_v * elapsed_v / dist + unvisitedBonus / dist;\n            } else {\n                score = (double)d[i][j] * pow((double)elapsed_v, alpha) / dist;\n            }\n            if(score > bestScore){\n                bestScore = score;\n                btx = i; bty = j;\n            }\n        }\n        if(btx<0) break;\n        \n        auto path = getPath(cx, cy, btx, bty);\n        if(path.empty()) break;\n        if(t + (int)path.size() > maxLen) break;\n        \n        for(int dr : path){\n            result.push_back(dr);\n            cx += dx[dr]; cy += dy[dr];\n            t++;\n            if(!visited[cx][cy]){ visited[cx][cy]=true; unvisitedCount--; }\n            last[cx][cy] = t;\n        }\n        \n        if(unvisitedCount == 0 && cx==0 && cy==0) break;\n    }\n    \n    if(cx != 0 || cy != 0){\n        auto path = getPath(cx, cy, 0, 0);\n        for(int dr : path){\n            result.push_back(dr);\n            cx += dx[dr]; cy += dy[dr];\n        }\n    }\n    \n    return result;\n}\n\nbool isValidTour(const vector<int>& tr){\n    if(tr.empty()) return false;\n    if((int)tr.size() > 100000) return false;\n    vector<vector<bool>> v(N,vector<bool>(N,false));\n    v[0][0]=true;\n    int x=0,y=0;\n    for(int dr : tr){\n        if(!canMove(x,y,dr)) return false;\n        x+=dx[dr]; y+=dy[dr]; v[x][y]=true;\n    }\n    if(x!=0 || y!=0) return false;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) if(!v[i][j]) return false;\n    return true;\n}\n\nvector<pair<int,int>> posCache;\nvoid recomputePos(const vector<int>& tour){\n    int L = tour.size();\n    posCache.resize(L+1);\n    posCache[0] = {0,0};\n    for(int t=0;t<L;t++){\n        posCache[t+1] = {posCache[t].first+dx[tour[t]], posCache[t].second+dy[tour[t]]};\n    }\n}\n\nvoid phase1_shorten(vector<int>& tour, double& curScore, double timeLimit, const function<double()>& elapsed){\n    bool improved = true;\n    int passes = 0;\n    while(improved && passes < 20 && elapsed() < timeLimit){\n        improved = false;\n        passes++;\n        int L = tour.size();\n        recomputePos(tour);\n        \n        for(int a=0; a<L; a++){\n            if(elapsed() >= timeLimit) return;\n            int maxb = min(L, a+300);\n            for(int b=a+2; b<=maxb; b++){\n                int dist = allD[posCache[a].first][posCache[a].second][posCache[b].first][posCache[b].second];\n                if(dist >= b-a) continue;\n                auto p = getPath(posCache[a].first,posCache[a].second,posCache[b].first,posCache[b].second);\n                vector<int> newTour;\n                newTour.reserve(L-(b-a)+p.size());\n                for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n                for(int x:p) newTour.push_back(x);\n                for(int t=b;t<L;t++) newTour.push_back(tour[t]);\n                double ns = computeScore(newTour);\n                if(ns < curScore){\n                    tour = newTour;\n                    curScore = ns;\n                    improved = true;\n                    goto restart;\n                }\n            }\n        }\n        restart:;\n    }\n}\n\nint main(){\n    cin>>N;\n    hh.resize(N-1); for(auto&s:hh)cin>>s;\n    vv.resize(N); for(auto&s:vv)cin>>s;\n    d.assign(N,vector<int>(N));\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>d[i][j];\n    \n    computeAllDist();\n    timesFlat.assign(N*N, vector<int>());\n    \n    auto startTime = chrono::steady_clock::now();\n    function<double()> elapsed = [&](){\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now-startTime).count();\n    };\n    \n    mt19937 rng(12345);\n    \n    dfsVisited.assign(N,vector<bool>(N,false));\n    dfs(0,0);\n    \n    vector<int> tour = dfsResult;\n    double curScore = computeScore(tour);\n    \n    for(double alpha : {1.5, 2.0, 2.5, 3.0}){\n        for(double ub : {1000000.0, 10000000.0}){\n            if(elapsed() > 0.3) goto done_greedy;\n            auto gt = greedyTour(alpha, ub);\n            if(!isValidTour(gt)) continue;\n            double s = computeScore(gt);\n            if(s < curScore){\n                tour = gt;\n                curScore = s;\n            }\n        }\n    }\n    done_greedy:;\n    \n    vector<tuple<int,int,int>> cells;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) cells.push_back({d[i][j],i,j});\n    sort(cells.rbegin(),cells.rend());\n    \n    phase1_shorten(tour, curScore, 0.8, elapsed);\n    \n    // Track best\n    vector<int> bestTour = tour;\n    double bestScore = curScore;\n    \n    recomputePos(tour);\n    \n    // SA with small temperature\n    double phase2EndTime = 1.7;\n    double phase2StartTime = elapsed();\n    \n    // Temperature: accept small degradations only\n    // delta scale: even small changes can yield delta of ~100 to ~10000 in score.\n    // Use T ~ avg d value\n    double sumD = 0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) sumD += d[i][j];\n    double avgD = sumD / (N*N);\n    double T0 = avgD * 10.0;\n    double T_end = 0.1;\n    \n    while(elapsed() < phase2EndTime){\n        double progress = (elapsed() - phase2StartTime) / (phase2EndTime - phase2StartTime);\n        if(progress > 1) progress = 1;\n        double T = T0 * pow(T_end/T0, progress);\n        \n        int mode = rng()%5;\n        int L = tour.size();\n        bool accepted = false;\n        vector<int> newTour;\n        double ns = -1;\n        \n        if(mode==0){\n            int ci = rng() % min((int)cells.size(), 50);\n            auto [dv,ti,tj] = cells[ci];\n            if(L>95000) continue;\n            int pos_i = rng()%(L+1);\n            int cx=posCache[pos_i].first, cy=posCache[pos_i].second;\n            if(cx==ti&&cy==tj) continue;\n            auto p1 = getPath(cx,cy,ti,tj);\n            auto p2 = getPath(ti,tj,cx,cy);\n            if((int)(L+p1.size()+p2.size())>100000) continue;\n            newTour.reserve(L+p1.size()+p2.size());\n            for(int t=0;t<pos_i;t++) newTour.push_back(tour[t]);\n            for(int x:p1) newTour.push_back(x);\n            for(int x:p2) newTour.push_back(x);\n            for(int t=pos_i;t<L;t++) newTour.push_back(tour[t]);\n        } else if(mode==1){\n            if(L<10) continue;\n            int a=rng()%L;\n            int maxlen = min(500,L-a-1);\n            if(maxlen<2) continue;\n            int b=a+2+rng()%(maxlen-1);\n            if(b>L) continue;\n            int ax=posCache[a].first, ay=posCache[a].second;\n            int bx=posCache[b].first, by=posCache[b].second;\n            int dist = allD[ax][ay][bx][by];\n            if(dist>=b-a) continue;\n            auto p = getPath(ax,ay,bx,by);\n            newTour.reserve(L-(b-a)+p.size());\n            for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n            for(int x:p) newTour.push_back(x);\n            for(int t=b;t<L;t++) newTour.push_back(tour[t]);\n        } else if(mode==2){\n            if(L<4) continue;\n            int a=rng()%(L-1);\n            if(tour[a]==(tour[a+1]^1)){\n                newTour.reserve(L-2);\n                for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n                for(int t=a+2;t<L;t++) newTour.push_back(tour[t]);\n            } else continue;\n        } else if(mode==3){\n            if(L>99998) continue;\n            int pos_i = rng()%(L+1);\n            int cx=posCache[pos_i].first, cy=posCache[pos_i].second;\n            int dirs[4]; int ndir=0;\n            for(int dr=0;dr<4;dr++) if(canMove(cx,cy,dr)) dirs[ndir++]=dr;\n            if(ndir==0) continue;\n            int dr = dirs[rng()%ndir];\n            newTour.reserve(L+2);\n            for(int t=0;t<pos_i;t++) newTour.push_back(tour[t]);\n            newTour.push_back(dr);\n            newTour.push_back(dr^1);\n            for(int t=pos_i;t<L;t++) newTour.push_back(tour[t]);\n        } else {\n            if(L<10 || L>98000) continue;\n            int a=rng()%L;\n            int maxlen = min(400,L-a-1);\n            if(maxlen<2) continue;\n            int b=a+2+rng()%(maxlen-1);\n            if(b>L) continue;\n            int ax=posCache[a].first, ay=posCache[a].second;\n            int bx=posCache[b].first, by=posCache[b].second;\n            int ci = rng() % min((int)cells.size(), 30);\n            auto [dv,ti,tj] = cells[ci];\n            auto p1 = getPath(ax,ay,ti,tj);\n            auto p2 = getPath(ti,tj,bx,by);\n            int newseglen = p1.size() + p2.size();\n            if(newseglen == 0) continue;\n            int delta_len = newseglen - (b-a);\n            if(L + delta_len > 100000 || L + delta_len < 4) continue;\n            newTour.reserve(L + delta_len);\n            for(int t=0;t<a;t++) newTour.push_back(tour[t]);\n            for(int x:p1) newTour.push_back(x);\n            for(int x:p2) newTour.push_back(x);\n            for(int t=b;t<L;t++) newTour.push_back(tour[t]);\n        }\n        \n        if(newTour.empty()) continue;\n        ns = computeScore(newTour);\n        double delta = ns - curScore;\n        bool accept = false;\n        if(delta <= 0) accept = true;\n        else if(T > 0){\n            double p = exp(-delta/T);\n            if((rng()&0xFFFF)/65535.0 < p) accept = true;\n        }\n        if(accept){\n            tour = move(newTour);\n            curScore = ns;\n            accepted = true;\n            if(curScore < bestScore){\n                bestScore = curScore;\n                bestTour = tour;\n            }\n        }\n        if(accepted) recomputePos(tour);\n    }\n    \n    tour = bestTour;\n    curScore = bestScore;\n    \n    phase1_shorten(tour, curScore, 1.85, elapsed);\n    \n    for(int dir:tour) cout<<DC[dir];\n    cout<<endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint si, sj;\nvector<string> grid;\nvector<string> words;\nvector<vector<pair<int,int>>> posOf(26);\n\ninline int distm(int r1,int c1,int r2,int c2){ return abs(r1-r2)+abs(c1-c2)+1; }\n\nvector<vector<int>> overlap;\nvector<vector<pair<int,int>>> lastPos;\n\nvector<vector<array<int,5>>> fromCost;\nvector<vector<array<int,5>>> fromEnd;\n\nint MAX_E;\nvector<int> costToEnd;\nint NC_global, M_global;\n\ninline int CTE(int cIdx, int j, int ov, int e){\n    return costToEnd[((cIdx*M_global + j)*5 + ov)*MAX_E + e];\n}\ninline void setCTE(int cIdx, int j, int ov, int e, int v){\n    costToEnd[((cIdx*M_global + j)*5 + ov)*MAX_E + e] = v;\n}\n\nint computeOverlap(const string& a, const string& b){\n    for(int k=4;k>=1;k--){\n        if(a.substr(5-k)==b.substr(0,k)) return k;\n    }\n    return 0;\n}\n\nstatic int dpArrG[2][256];\n\nint main(){\n    auto start_time = chrono::steady_clock::now();\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin>>N>>M>>si>>sj;\n    M_global = M;\n    grid.resize(N);\n    for(int i=0;i<N;i++) cin>>grid[i];\n    words.resize(M);\n    for(int i=0;i<M;i++) cin>>words[i];\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) posOf[grid[i][j]-'A'].push_back({i,j});\n    \n    overlap.assign(M, vector<int>(M,0));\n    for(int i=0;i<M;i++)for(int j=0;j<M;j++){\n        if(i==j) continue;\n        overlap[i][j] = computeOverlap(words[i], words[j]);\n    }\n    \n    lastPos.resize(M);\n    for(int i=0;i<M;i++) lastPos[i] = posOf[words[i][4]-'A'];\n    \n    MAX_E = 1;\n    for(int i=0;i<M;i++) MAX_E = max(MAX_E, (int)lastPos[i].size());\n    \n    int NC = N*N;\n    NC_global = NC;\n    fromCost.assign(NC, vector<array<int,5>>(M));\n    fromEnd.assign(NC, vector<array<int,5>>(M));\n    costToEnd.assign((long long)NC * M * 5 * MAX_E, INT_MAX/2);\n    \n    for(int cIdx=0; cIdx<NC; cIdx++){\n        int pr = cIdx/N, pc = cIdx%N;\n        for(int j=0; j<M; j++){\n            const string& w = words[j];\n            for(int ov=0; ov<5; ov++){\n                int len = 5-ov;\n                static int dp[5][30];\n                int sizes[5];\n                for(int i=0;i<len;i++) sizes[i] = posOf[w[ov+i]-'A'].size();\n                {\n                    auto& pv = posOf[w[ov]-'A'];\n                    for(int k=0;k<sizes[0];k++) dp[0][k] = distm(pr,pc,pv[k].first,pv[k].second);\n                }\n                for(int i=1;i<len;i++){\n                    auto& pp = posOf[w[ov+i-1]-'A'];\n                    auto& pc2 = posOf[w[ov+i]-'A'];\n                    for(int k=0;k<sizes[i];k++){\n                        int r=pc2[k].first, c=pc2[k].second;\n                        int best=INT_MAX;\n                        for(int jj=0;jj<sizes[i-1];jj++){\n                            int nc = dp[i-1][jj] + distm(pp[jj].first,pp[jj].second,r,c);\n                            if(nc<best) best=nc;\n                        }\n                        dp[i][k]=best;\n                    }\n                }\n                int best=INT_MAX, bk=-1;\n                int finalSize = sizes[len-1];\n                for(int k=0;k<finalSize;k++){\n                    setCTE(cIdx,j,ov,k, dp[len-1][k]);\n                    if(dp[len-1][k]<best){best=dp[len-1][k];bk=k;}\n                }\n                fromCost[cIdx][j][ov] = best;\n                fromEnd[cIdx][j][ov] = bk;\n            }\n        }\n    }\n    \n    auto evaluate = [&](const vector<int>& ord)->int{\n        if(ord.empty()) return 0;\n        int cIdx = si*N+sj;\n        int cost = fromCost[cIdx][ord[0]][0];\n        int endIdx = fromEnd[cIdx][ord[0]][0];\n        for(int i=1;i<(int)ord.size();i++){\n            auto& lp = lastPos[ord[i-1]][endIdx];\n            int cIdx2 = lp.first*N + lp.second;\n            int ov = overlap[ord[i-1]][ord[i]];\n            cost += fromCost[cIdx2][ord[i]][ov];\n            endIdx = fromEnd[cIdx2][ord[i]][ov];\n        }\n        return cost;\n    };\n    \n    auto evaluateDP = [&](const vector<int>& ord)->int{\n        if(ord.empty()) return 0;\n        int cIdx = si*N+sj;\n        int w0 = ord[0];\n        int sz0 = lastPos[w0].size();\n        int cur = 0;\n        int base0 = ((cIdx*M_global + w0)*5 + 0)*MAX_E;\n        for(int e=0;e<sz0;e++) dpArrG[cur][e] = costToEnd[base0 + e];\n        int prev_sz = sz0;\n        int prev_w = w0;\n        int osz = ord.size();\n        for(int i=1;i<osz;i++){\n            int wc = ord[i];\n            int ov = overlap[prev_w][wc];\n            int szc = lastPos[wc].size();\n            int nxt = 1-cur;\n            for(int ec=0;ec<szc;ec++) dpArrG[nxt][ec] = INT_MAX/2;\n            auto& lpArr = lastPos[prev_w];\n            for(int ep=0;ep<prev_sz;ep++){\n                int dep = dpArrG[cur][ep];\n                if(dep >= INT_MAX/2) continue;\n                auto& lp = lpArr[ep];\n                int ci = lp.first*N + lp.second;\n                int base = ((ci*M_global + wc)*5 + ov)*MAX_E;\n                for(int ec=0;ec<szc;ec++){\n                    int v = dep + costToEnd[base + ec];\n                    if(v < dpArrG[nxt][ec]) dpArrG[nxt][ec] = v;\n                }\n            }\n            cur = nxt;\n            prev_sz = szc;\n            prev_w = wc;\n        }\n        int best = INT_MAX;\n        for(int e=0;e<prev_sz;e++) if(dpArrG[cur][e]<best) best=dpArrG[cur][e];\n        return best;\n    };\n    \n    auto buildString = [&](const vector<int>& ord)->string{\n        if(ord.empty()) return \"\";\n        string s = words[ord[0]];\n        for(int i=1;i<(int)ord.size();i++){\n            int ov = overlap[ord[i-1]][ord[i]];\n            s += words[ord[i]].substr(ov);\n        }\n        return s;\n    };\n    \n    auto verifyAll = [&](const vector<int>& ord)->bool{\n        string s = buildString(ord);\n        for(int j=0;j<M;j++) if(s.find(words[j])==string::npos) return false;\n        return true;\n    };\n    \n    mt19937 rng(42);\n    auto time_ms = [&]()->long long{ return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-start_time).count(); };\n    \n    auto buildGreedy = [&](){\n        vector<int> ord;\n        vector<bool> used(M,false);\n        int cIdx = si*N+sj;\n        int bw=-1, bc=INT_MAX, be=-1;\n        for(int j=0;j<M;j++){\n            if(fromCost[cIdx][j][0]<bc){bc=fromCost[cIdx][j][0]; bw=j; be=fromEnd[cIdx][j][0];}\n        }\n        ord.push_back(bw); used[bw]=true;\n        int curWord=bw, curEnd=be;\n        for(int step=1; step<M; step++){\n            auto& lp = lastPos[curWord][curEnd];\n            int ci = lp.first*N+lp.second;\n            int bw2=-1, bc2=INT_MAX, be2=-1;\n            for(int j=0;j<M;j++) if(!used[j]){\n                int ov = overlap[curWord][j];\n                if(fromCost[ci][j][ov]<bc2){\n                    bc2=fromCost[ci][j][ov]; bw2=j; be2=fromEnd[ci][j][ov];\n                }\n            }\n            ord.push_back(bw2); used[bw2]=true;\n            curWord=bw2; curEnd=be2;\n        }\n        return ord;\n    };\n    \n    vector<int> order = buildGreedy();\n    int curCost = evaluate(order);\n    int bestCost = curCost;\n    vector<int> bestOrder = order;\n    \n    // Phase 1: Random LS with greedy evaluate - most of the time\n    auto doLS = [&](vector<int>& order, int& curCost, int& bestCost, vector<int>& bestOrder, auto&& evalFn, long long endTime){\n        while(time_ms() < endTime){\n            int sz = order.size();\n            if(sz<2) break;\n            int op = rng()%4;\n            if(op==0){\n                int a = rng()%sz, b = rng()%sz;\n                if(a==b) continue;\n                if(a>b) swap(a,b);\n                reverse(order.begin()+a, order.begin()+b+1);\n                int nc = evalFn(order);\n                if(nc < curCost){\n                    curCost = nc;\n                    if(nc<bestCost){bestCost=nc; bestOrder=order;}\n                } else {\n                    reverse(order.begin()+a, order.begin()+b+1);\n                }\n            } else if(op==1){\n                int a = rng()%sz, b = rng()%sz;\n                if(a==b) continue;\n                int v = order[a];\n                if(a<b){ for(int i=a;i<b;i++) order[i]=order[i+1]; order[b]=v; }\n                else { for(int i=a;i>b;i--) order[i]=order[i-1]; order[b]=v; }\n                int nc = evalFn(order);\n                if(nc < curCost){\n                    curCost = nc;\n                    if(nc<bestCost){bestCost=nc; bestOrder=order;}\n                } else {\n                    int v2 = order[b];\n                    if(a<b){ for(int i=b;i>a;i--) order[i]=order[i-1]; order[a]=v2; }\n                    else { for(int i=b;i<a;i++) order[i]=order[i+1]; order[a]=v2; }\n                }\n            } else if(op==2){\n                int a=rng()%sz, b=rng()%sz;\n                if(a==b) continue;\n                swap(order[a],order[b]);\n                int nc = evalFn(order);\n                if(nc < curCost){\n                    curCost = nc;\n                    if(nc<bestCost){bestCost=nc; bestOrder=order;}\n                } else {\n                    swap(order[a],order[b]);\n                }\n            } else {\n                int L = 2+(rng()%2);\n                if(sz-L<1) continue;\n                int a = rng()%(sz-L+1);\n                int b = rng()%(sz-L+1);\n                if(a==b) continue;\n                vector<int> seg(order.begin()+a, order.begin()+a+L);\n                vector<int> rest;\n                rest.reserve(sz-L);\n                for(int i=0;i<sz;i++) if(i<a||i>=a+L) rest.push_back(order[i]);\n                int insPos = b; if(insPos>(int)rest.size()) insPos=rest.size();\n                vector<int> newOrd;\n                newOrd.reserve(sz);\n                for(int i=0;i<insPos;i++) newOrd.push_back(rest[i]);\n                for(int x:seg) newOrd.push_back(x);\n                for(int i=insPos;i<(int)rest.size();i++) newOrd.push_back(rest[i]);\n                int nc = evalFn(newOrd);\n                if(nc < curCost){\n                    order = newOrd;\n                    curCost = nc;\n                    if(nc<bestCost){bestCost=nc; bestOrder=order;}\n                }\n            }\n        }\n    };\n    \n    // Phase 1: greedy evaluate LS\n    doLS(order, curCost, bestCost, bestOrder, evaluate, 1200);\n    order = bestOrder;\n    // Recompute curCost with DP evaluate for Phase 2\n    curCost = evaluateDP(order);\n    bestCost = curCost;\n    bestOrder = order;\n    \n    // Phase 2: DP evaluate LS\n    doLS(order, curCost, bestCost, bestOrder, evaluateDP, 1700);\n    order = bestOrder;\n    curCost = bestCost;\n    \n    // Removal\n    auto removeRedundant = [&](vector<int>& order, int& curCost){\n        vector<bool> inOrder(M, false);\n        for(int w:order) inOrder[w]=true;\n        \n        bool changed = true;\n        int passes = 0;\n        while(changed && passes < 50 && time_ms() < 1900){\n            changed = false;\n            passes++;\n            int bestIdx = -1, bestSave = 0;\n            \n            for(int i=0;i<(int)order.size();i++){\n                vector<int> newOrd = order;\n                newOrd.erase(newOrd.begin()+i);\n                string s = buildString(newOrd);\n                bool allIn = true;\n                for(int j=0;j<M;j++){\n                    if(!inOrder[j] || j==order[i]){\n                        if(s.find(words[j])==string::npos){ allIn=false; break; }\n                    }\n                }\n                if(allIn){\n                    int newC = evaluateDP(newOrd);\n                    int save = curCost - newC;\n                    if(save > bestSave){ bestSave = save; bestIdx = i; }\n                }\n            }\n            if(bestIdx >= 0){\n                inOrder[order[bestIdx]] = false;\n                order.erase(order.begin()+bestIdx);\n                curCost -= bestSave;\n                changed = true;\n            }\n        }\n    };\n    \n    vector<int> preRemoveOrder = order;\n    int preRemoveCost = curCost;\n    removeRedundant(order, curCost);\n    \n    if(!verifyAll(order)){\n        order = preRemoveOrder;\n        curCost = preRemoveCost;\n    }\n    \n    int osz = order.size();\n    vector<vector<int>> dpF(osz), parF(osz);\n    int startCell = si*N+sj;\n    {\n        int w0 = order[0];\n        int sz0 = lastPos[w0].size();\n        dpF[0].assign(sz0, INT_MAX/2);\n        parF[0].assign(sz0, -1);\n        for(int e=0;e<sz0;e++) dpF[0][e] = CTE(startCell, w0, 0, e);\n    }\n    for(int i=1;i<osz;i++){\n        int wp = order[i-1], wc = order[i];\n        int ov = overlap[wp][wc];\n        int szp = lastPos[wp].size();\n        int szc = lastPos[wc].size();\n        dpF[i].assign(szc, INT_MAX/2);\n        parF[i].assign(szc, -1);\n        for(int ep=0;ep<szp;ep++){\n            if(dpF[i-1][ep]>=INT_MAX/2) continue;\n            auto& lp = lastPos[wp][ep];\n            int ci = lp.first*N + lp.second;\n            for(int ec=0;ec<szc;ec++){\n                int v = dpF[i-1][ep] + CTE(ci, wc, ov, ec);\n                if(v < dpF[i][ec]){ dpF[i][ec] = v; parF[i][ec] = ep; }\n            }\n        }\n    }\n    int bestE = 0, bestV = INT_MAX;\n    for(int e=0;e<(int)dpF[osz-1].size();e++) if(dpF[osz-1][e]<bestV){bestV=dpF[osz-1][e]; bestE=e;}\n    vector<int> endIdxs(osz);\n    endIdxs[osz-1] = bestE;\n    for(int i=osz-1;i>0;i--) endIdxs[i-1] = parF[i][endIdxs[i]];\n    \n    auto reconstructWord = [&](int wj, int ov, int pr, int pc, int targetE)->vector<pair<int,int>>{\n        const string& w = words[wj];\n        int len = 5-ov;\n        vector<pair<int,int>> res;\n        if(len<=0) return res;\n        vector<vector<int>> dp(len), par(len);\n        for(int i=0;i<len;i++){\n            int szl = posOf[w[ov+i]-'A'].size();\n            dp[i].assign(szl,INT_MAX/2);\n            par[i].assign(szl,-1);\n        }\n        auto& p0 = posOf[w[ov]-'A'];\n        for(int k=0;k<(int)p0.size();k++) dp[0][k]=distm(pr,pc,p0[k].first,p0[k].second);\n        for(int i=1;i<len;i++){\n            auto& pp=posOf[w[ov+i-1]-'A'];\n            auto& pc2=posOf[w[ov+i]-'A'];\n            for(int k=0;k<(int)pc2.size();k++){\n                int r=pc2[k].first, c=pc2[k].second;\n                for(int j=0;j<(int)pp.size();j++){\n                    int nc=dp[i-1][j]+distm(pp[j].first,pp[j].second,r,c);\n                    if(nc<dp[i][k]){dp[i][k]=nc;par[i][k]=j;}\n                }\n            }\n        }\n        int bk = targetE;\n        vector<int> idx(len);\n        idx[len-1]=bk;\n        for(int i=len-1;i>0;i--) idx[i-1]=par[i][idx[i]];\n        res.resize(len);\n        for(int i=0;i<len;i++) res[i]=posOf[w[ov+i]-'A'][idx[i]];\n        return res;\n    };\n    \n    vector<pair<int,int>> output;\n    int curR=si, curC=sj;\n    for(int i=0;i<osz;i++){\n        int ov = (i==0)?0:overlap[order[i-1]][order[i]];\n        auto path = reconstructWord(order[i], ov, curR, curC, endIdxs[i]);\n        for(auto& p:path){ output.push_back(p); curR=p.first; curC=p.second; }\n    }\n    \n    for(auto& p:output) cout<<p.first<<\" \"<<p.second<<\"\\n\";\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, NN;\ndouble EPS;\nvector<vector<pair<int,int>>> polys;\nvector<vector<vector<int>>> placement_cells;\nvector<int> nPlace;\n\nstruct Query { vector<int> cells; int result; bool exact; };\nvector<Query> queries;\ndouble total_cost = 0;\n\nauto START_TIME = chrono::steady_clock::now();\ndouble elapsed() { return chrono::duration<double>(chrono::steady_clock::now() - START_TIME).count(); }\n\nint do_drill(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl; cout.flush();\n    int v; cin >> v;\n    total_cost += 1.0;\n    Query q; q.cells = {i*N+j}; q.result = v; q.exact = true;\n    queries.push_back(q);\n    return v;\n}\n\nint do_answer(vector<int>& cells) {\n    cout << \"a \" << cells.size();\n    for (int c : cells) cout << \" \" << c/N << \" \" << c%N;\n    cout << endl; cout.flush();\n    int r; cin >> r;\n    return r;\n}\n\nlong long countTotal() {\n    long long t = 1;\n    for (int k = 0; k < M; k++) { t *= nPlace[k]; if (t > (long long)1e10) return (long long)1e10; }\n    return t;\n}\n\nvoid enumerationLoop(const vector<vector<int>>& alivePl, vector<int>& drillVal, vector<char>& drilledMask, int& drilled, int budget, double TIME_LIMIT) {\n    int M_ = alivePl.size();\n    vector<int> szs(M_);\n    long long total = 1;\n    for (int k = 0; k < M_; k++) { szs[k] = alivePl[k].size(); total *= szs[k]; }\n    \n    vector<vector<int>> confs;\n    confs.reserve((size_t)min(total, (long long)300000));\n    vector<int> cur(M_);\n    vector<int> cellAcc(NN, 0);\n    function<void(int)> gen = [&](int k) {\n        if (k == M_) {\n            bool ok = true;\n            for (int c = 0; c < NN; c++) {\n                if (drilledMask[c] && cellAcc[c] != drillVal[c]) { ok = false; break; }\n            }\n            if (ok) confs.push_back(cur);\n            return;\n        }\n        for (int i = 0; i < szs[k]; i++) {\n            int pidx = alivePl[k][i];\n            cur[k] = pidx;\n            for (int cc : placement_cells[k][pidx]) cellAcc[cc]++;\n            gen(k+1);\n            for (int cc : placement_cells[k][pidx]) cellAcc[cc]--;\n        }\n    };\n    gen(0);\n    \n    int nConf = confs.size();\n    if (nConf == 0) {\n        vector<int> ans;\n        for (int c = 0; c < NN; c++) if (drilledMask[c] && drillVal[c] > 0) ans.push_back(c);\n        do_answer(ans);\n        exit(0);\n    }\n    \n    vector<unsigned char> grids((size_t)nConf * NN, 0);\n    for (int c = 0; c < nConf; c++) {\n        size_t base = (size_t)c * NN;\n        for (int k = 0; k < M_; k++) {\n            for (int cc : placement_cells[k][confs[c][k]]) grids[base + cc]++;\n        }\n    }\n    \n    vector<char> alive(nConf, 1);\n    int aliveCount = nConf;\n    int maxQueries = 2*N*N;\n    \n    while ((int)queries.size() < maxQueries - 1 && elapsed() < TIME_LIMIT) {\n        int best = -1;\n        for (int c = 0; c < nConf; c++) if (alive[c]) { best = c; break; }\n        if (best == -1) break;\n        \n        if (aliveCount == 1) {\n            size_t base = (size_t)best * NN;\n            vector<int> ans;\n            for (int i = 0; i < NN; i++) if (grids[base + i] > 0) ans.push_back(i);\n            int r = do_answer(ans);\n            if (r == 1) exit(0);\n            alive[best] = 0; aliveCount--;\n            continue;\n        }\n        \n        vector<int> cntOil(NN, 0);\n        for (int c = 0; c < nConf; c++) {\n            if (!alive[c]) continue;\n            size_t base = (size_t)c * NN;\n            for (int i = 0; i < NN; i++) if (grids[base + i] > 0) cntOil[i]++;\n        }\n        \n        int bestCell = -1;\n        int bestDiff = INT_MAX;\n        for (int i = 0; i < NN; i++) {\n            if (drilledMask[i]) continue;\n            if (cntOil[i] == 0 || cntOil[i] == aliveCount) continue;\n            int diff = abs(2*cntOil[i] - aliveCount);\n            if (diff < bestDiff) { bestDiff = diff; bestCell = i; }\n        }\n        \n        if (bestCell == -1) {\n            size_t base = (size_t)best * NN;\n            vector<int> ans;\n            for (int i = 0; i < NN; i++) if (grids[base + i] > 0) ans.push_back(i);\n            int r = do_answer(ans);\n            if (r == 1) exit(0);\n            alive[best] = 0; aliveCount--;\n            continue;\n        }\n        \n        int v = do_drill(bestCell / N, bestCell % N);\n        drillVal[bestCell] = v;\n        drilledMask[bestCell] = 1;\n        drilled++;\n        for (int c = 0; c < nConf; c++) {\n            if (!alive[c]) continue;\n            if ((int)grids[(size_t)c * NN + bestCell] != v) { alive[c] = 0; aliveCount--; }\n        }\n    }\n    \n    int best = -1;\n    for (int c = 0; c < nConf; c++) if (alive[c]) { best = c; break; }\n    if (best == -1) best = 0;\n    size_t base = (size_t)best * NN;\n    vector<int> ans;\n    for (int i = 0; i < NN; i++) if (grids[base + i] > 0) ans.push_back(i);\n    do_answer(ans);\n    exit(0);\n}\n\nint main() {\n    cin >> N >> M >> EPS;\n    NN = N * N;\n    polys.resize(M);\n    int totalOil = 0;\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        totalOil += d;\n        polys[k].resize(d);\n        for (int i = 0; i < d; i++) cin >> polys[k][i].first >> polys[k][i].second;\n    }\n    \n    placement_cells.resize(M);\n    nPlace.resize(M);\n    for (int k = 0; k < M; k++) {\n        int mi = 0, mj = 0;\n        for (auto& p : polys[k]) { mi = max(mi, p.first); mj = max(mj, p.second); }\n        for (int di = 0; di + mi < N; di++) {\n            for (int dj = 0; dj + mj < N; dj++) {\n                vector<int> cs;\n                for (auto& p : polys[k]) cs.push_back((p.first+di)*N + (p.second+dj));\n                placement_cells[k].push_back(cs);\n            }\n        }\n        nPlace[k] = placement_cells[k].size();\n    }\n    \n    vector<vector<vector<int>>> covers_cell(M, vector<vector<int>>(NN));\n    vector<vector<vector<char>>> place_covers_cell(M);\n    for (int k = 0; k < M; k++) {\n        place_covers_cell[k].assign(nPlace[k], vector<char>(NN, 0));\n        for (int p = 0; p < nPlace[k]; p++) {\n            for (int c : placement_cells[k][p]) {\n                place_covers_cell[k][p][c] = 1;\n                covers_cell[k][c].push_back(p);\n            }\n        }\n    }\n    \n    long long totalConfigs = countTotal();\n    int maxQueries = 2*N*N;\n    double TIME_LIMIT = 2.2;\n    \n    if (totalConfigs <= 100000) {\n        vector<vector<int>> alivePl(M);\n        for (int k = 0; k < M; k++) for (int p = 0; p < nPlace[k]; p++) alivePl[k].push_back(p);\n        vector<int> drillVal(NN, -1);\n        vector<char> drilledMask(NN, 0);\n        int drilled = 0;\n        enumerationLoop(alivePl, drillVal, drilledMask, drilled, maxQueries - 2, TIME_LIMIT);\n        return 0;\n    }\n    \n    // LARGE CASE\n    vector<vector<char>> placeAlive(M);\n    vector<int> aliveCountK(M);\n    for (int k = 0; k < M; k++) {\n        placeAlive[k].assign(nPlace[k], 1);\n        aliveCountK[k] = nPlace[k];\n    }\n    \n    vector<vector<int>> coverCnt(M, vector<int>(NN, 0));\n    for (int k = 0; k < M; k++) {\n        for (int p = 0; p < nPlace[k]; p++) {\n            for (int c : placement_cells[k][p]) coverCnt[k][c]++;\n        }\n    }\n    \n    vector<int> drillVal(NN, -1);\n    vector<int> drilledCells;\n    vector<char> drilledMask(NN, 0);\n    \n    auto prunePlacement = [&](int k, int p) {\n        if (!placeAlive[k][p]) return;\n        placeAlive[k][p] = 0;\n        aliveCountK[k]--;\n        for (int c : placement_cells[k][p]) coverCnt[k][c]--;\n    };\n    \n    auto propagate = [&]() {\n        bool changed = true;\n        int iters = 0;\n        while (changed && iters < 20 && elapsed() < TIME_LIMIT) {\n            changed = false;\n            iters++;\n            for (int cell : drilledCells) {\n                int v = drillVal[cell];\n                int mustSum = 0, maySum = 0;\n                for (int k = 0; k < M; k++) {\n                    if (aliveCountK[k] == 0) continue;\n                    if (coverCnt[k][cell] > 0) maySum++;\n                    if (coverCnt[k][cell] == aliveCountK[k]) mustSum++;\n                }\n                if (mustSum > v || maySum < v) continue;\n                if (maySum == v) {\n                    for (int k = 0; k < M; k++) {\n                        if (aliveCountK[k] == 0) continue;\n                        if (coverCnt[k][cell] == 0) continue;\n                        if (coverCnt[k][cell] == aliveCountK[k]) continue;\n                        vector<int> toRemove;\n                        for (int p = 0; p < nPlace[k]; p++) {\n                            if (!placeAlive[k][p]) continue;\n                            if (!place_covers_cell[k][p][cell]) toRemove.push_back(p);\n                        }\n                        for (int p : toRemove) prunePlacement(k, p);\n                        if (!toRemove.empty()) changed = true;\n                    }\n                }\n                if (mustSum == v) {\n                    for (int k = 0; k < M; k++) {\n                        if (aliveCountK[k] == 0) continue;\n                        if (coverCnt[k][cell] == 0) continue;\n                        if (coverCnt[k][cell] == aliveCountK[k]) continue;\n                        vector<int> toRemove;\n                        for (int p : covers_cell[k][cell]) {\n                            if (placeAlive[k][p]) toRemove.push_back(p);\n                        }\n                        for (int p : toRemove) prunePlacement(k, p);\n                        if (!toRemove.empty()) changed = true;\n                    }\n                }\n            }\n        }\n    };\n    \n    vector<int> ansCells;\n    int foundOil = 0;\n    int drilled = 0;\n    int budget = maxQueries - 2;\n    \n    auto computeBestCell = [&]() {\n        int bestCell = -1;\n        double bestScore = -1;\n        for (int i = 0; i < NN; i++) {\n            if (drilledMask[i]) continue;\n            double variance = 0.0;\n            double pNoOil = 1.0;\n            for (int k = 0; k < M; k++) {\n                if (aliveCountK[k] == 0) continue;\n                double p = (double)coverCnt[k][i] / aliveCountK[k];\n                variance += p * (1.0 - p);\n                pNoOil *= (1.0 - p);\n            }\n            double pO = 1.0 - pNoOil;\n            double score = variance + 0.001 * pO;\n            if (score > bestScore) { bestScore = score; bestCell = i; }\n        }\n        return bestCell;\n    };\n    \n    auto computeBestCellOil = [&]() {\n        int bestCell = -1;\n        double bestP = -1;\n        for (int i = 0; i < NN; i++) {\n            if (drilledMask[i]) continue;\n            double pNoOil = 1.0;\n            for (int k = 0; k < M; k++) {\n                if (aliveCountK[k] == 0) continue;\n                double pNotK = 1.0 - (double)coverCnt[k][i] / aliveCountK[k];\n                pNoOil *= pNotK;\n            }\n            double pO = 1.0 - pNoOil;\n            if (pO > bestP) { bestP = pO; bestCell = i; }\n        }\n        return bestCell;\n    };\n    \n    while (drilled < budget && foundOil < totalOil && elapsed() < TIME_LIMIT) {\n        long long rem = 1;\n        bool overflow = false;\n        for (int k = 0; k < M; k++) {\n            rem *= aliveCountK[k];\n            if (rem > 300000) { overflow = true; break; }\n        }\n        if (!overflow && rem > 0 && rem <= 80000) {\n            vector<vector<int>> alivePl(M);\n            for (int k = 0; k < M; k++) for (int p = 0; p < nPlace[k]; p++) if (placeAlive[k][p]) alivePl[k].push_back(p);\n            enumerationLoop(alivePl, drillVal, drilledMask, drilled, budget, TIME_LIMIT);\n            return 0;\n        }\n        \n        int bestCell;\n        if (overflow || rem > 1000) bestCell = computeBestCell();\n        else bestCell = computeBestCellOil();\n        if (bestCell == -1) break;\n        int v = do_drill(bestCell / N, bestCell % N);\n        drillVal[bestCell] = v;\n        drilledCells.push_back(bestCell);\n        drilledMask[bestCell] = 1;\n        drilled++;\n        if (v > 0) { ansCells.push_back(bestCell); foundOil += v; }\n        propagate();\n    }\n    \n    while (drilled < budget && foundOil < totalOil) {\n        int bestCell = -1;\n        for (int i = 0; i < NN; i++) {\n            if (drilledMask[i]) continue;\n            bool possible = false;\n            for (int k = 0; k < M; k++) if (coverCnt[k][i] > 0) { possible = true; break; }\n            if (possible) { bestCell = i; break; }\n        }\n        if (bestCell == -1) {\n            for (int i = 0; i < NN; i++) if (!drilledMask[i]) { bestCell = i; break; }\n        }\n        if (bestCell == -1) break;\n        int v = do_drill(bestCell / N, bestCell % N);\n        drillVal[bestCell] = v;\n        drilledCells.push_back(bestCell);\n        drilledMask[bestCell] = 1;\n        drilled++;\n        if (v > 0) { ansCells.push_back(bestCell); foundOil += v; }\n    }\n    \n    sort(ansCells.begin(), ansCells.end());\n    ansCells.erase(unique(ansCells.begin(), ansCells.end()), ansCells.end());\n    do_answer(ansCells);\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint W, D, N;\nvector<vector<int>> a;\n\nstruct Rect { int i0,j0,i1,j1; };\n\nvoid alignDividers(vector<int>& h, int W_col, const set<int>& prev_dividers) {\n    int m = h.size();\n    if (m == 0) return;\n    long long sum_h = 0;\n    for (int x : h) sum_h += x;\n    int slack = W_col - sum_h;\n    if (slack < 0) return;\n    vector<int> prev_sorted(prev_dividers.begin(), prev_dividers.end());\n    int y = 0;\n    for (int i = 0; i < m - 1; i++) {\n        int natural = y + h[i];\n        auto it = lower_bound(prev_sorted.begin(), prev_sorted.end(), natural);\n        if (it != prev_sorted.end() && *it < W_col) {\n            int push = *it - natural;\n            if (push >= 0 && push <= slack) { h[i] += push; slack -= push; }\n        }\n        y += h[i];\n    }\n    h[m-1] += slack;\n}\n\nlong long solveWithWidths(vector<int>& widths, vector<vector<Rect>>& final_rects, bool align, int tightMode) {\n    int C = widths.size();\n    vector<int> xs(C+1, 0);\n    for (int i = 0; i < C; i++) xs[i+1] = xs[i] + widths[i];\n    vector<vector<set<int>>> dividers(D, vector<set<int>>(C));\n    long long deficit = 0;\n    final_rects.assign(D, vector<Rect>(N));\n    for (int d = 0; d < D; d++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        vector<double> load(C, 0);\n        vector<vector<int>> col(C);\n        for (int k : order) {\n            int best = 0; double bestVal = 1e18;\n            for (int c = 0; c < C; c++) {\n                double v = load[c] + (double)a[d][k] / widths[c];\n                if (v < bestVal) { bestVal = v; best = c; }\n            }\n            col[best].push_back(k);\n            load[best] += (double)a[d][k] / widths[best];\n        }\n        for (int c = 0; c < C; c++) {\n            auto& items = col[c];\n            if (items.empty()) continue;\n            int w = widths[c];\n            int m = items.size();\n            if (m > W) return LLONG_MAX;\n            vector<int> h(m);\n            long long total = 0;\n            for (int i = 0; i < m; i++) {\n                h[i] = max(1, (a[d][items[i]] + w - 1) / w);\n                total += h[i];\n            }\n            if (total > W) {\n                if (tightMode == 0) {\n                    long long totA = 0;\n                    for (int k : items) totA += a[d][k];\n                    if (totA == 0) totA = 1;\n                    vector<int> newH(m, 1);\n                    int rem = W - m;\n                    vector<double> frac(m);\n                    for (int i = 0; i < m; i++) frac[i] = (double)a[d][items[i]] / totA * rem;\n                    int s = m;\n                    for (int i = 0; i < m; i++) { int add = (int)frac[i]; newH[i] += add; s += add; }\n                    vector<pair<double,int>> fr(m);\n                    for (int i = 0; i < m; i++) fr[i] = {frac[i] - (int)frac[i], i};\n                    sort(fr.begin(), fr.end(), greater<>());\n                    int idx = 0;\n                    while (s < W && idx < m) { newH[fr[idx].second]++; s++; idx++; }\n                    while (s < W) { newH[m-1]++; s++; }\n                    h = newH;\n                } else {\n                    vector<int> sortedIdx(m);\n                    iota(sortedIdx.begin(), sortedIdx.end(), 0);\n                    sort(sortedIdx.begin(), sortedIdx.end(), [&](int x, int y){\n                        int cx = (a[d][items[x]] + w - 1) / w;\n                        int cy = (a[d][items[y]] + w - 1) / w;\n                        return cx < cy;\n                    });\n                    vector<int> newH(m, 1);\n                    long long budget = W - m;\n                    for (int idx : sortedIdx) {\n                        if (budget <= 0) break;\n                        int req = (a[d][items[idx]] + w - 1) / w;\n                        int need = req - 1;\n                        if (need <= 0) continue;\n                        int give = (int)min((long long)need, budget);\n                        newH[idx] += give;\n                        budget -= give;\n                    }\n                    if (budget > 0) newH[m-1] += budget;\n                    h = newH;\n                }\n            } else {\n                if (align && d > 0) alignDividers(h, W, dividers[d-1][c]);\n                else h[m-1] += (W - total);\n            }\n            int y = 0;\n            for (int i = 0; i < m; i++) {\n                int yEnd = y + h[i];\n                if (i == m-1) yEnd = W;\n                if (yEnd > W) yEnd = W;\n                final_rects[d][items[i]] = {y, xs[c], yEnd, xs[c+1]};\n                if (yEnd < W) dividers[d][c].insert(yEnd);\n                y = yEnd;\n            }\n            for (int idx : items) {\n                auto& r = final_rects[d][idx];\n                long long area = (long long)(r.i1-r.i0)*(r.j1-r.j0);\n                if (area < a[d][idx]) deficit += 100LL * (a[d][idx] - area);\n            }\n        }\n    }\n    long long partCost = 0;\n    for (int d = 1; d < D; d++) {\n        for (int c = 0; c < C; c++) {\n            auto& prev = dividers[d-1][c];\n            auto& cur = dividers[d][c];\n            int w = widths[c];\n            int sd = 0;\n            for (int x : prev) if (!cur.count(x)) sd++;\n            for (int x : cur) if (!prev.count(x)) sd++;\n            partCost += (long long)sd * w;\n        }\n    }\n    return deficit + partCost;\n}\n\nlong long solveFixedSingleCol(vector<vector<Rect>>& final_rects) {\n    vector<int> h(N);\n    for (int r = 0; r < N; r++) {\n        int mx = 1;\n        for (int d = 0; d < D; d++) {\n            int val = a[d][N-1-r];\n            int req = (val + W - 1) / W;\n            mx = max(mx, req);\n        }\n        h[r] = mx;\n    }\n    long long sum = 0; for (int x : h) sum += x;\n    if (sum > W) {\n        double ratio = (double)W / sum;\n        long long s = 0;\n        for (int& x : h) { x = max(1, (int)(x * ratio)); s += x; }\n        while (s > W) {\n            int mi = 0;\n            for (int i = 1; i < N; i++) if (h[i] > h[mi]) mi = i;\n            if (h[mi] > 1) { h[mi]--; s--; } else break;\n        }\n        while (s < W) { h[N-1]++; s++; }\n    } else h[N-1] += (W - sum);\n    final_rects.assign(D, vector<Rect>(N));\n    long long deficit = 0;\n    for (int d = 0; d < D; d++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        int y = 0;\n        for (int r = 0; r < N; r++) {\n            int yEnd = y + h[r];\n            if (r == N-1) yEnd = W;\n            int k = order[r];\n            final_rects[d][k] = {y, 0, yEnd, W};\n            long long area = (long long)(yEnd - y) * W;\n            if (area < a[d][k]) deficit += 100LL * (a[d][k] - area);\n            y = yEnd;\n        }\n    }\n    return deficit;\n}\n\nlong long solveFixedCols(vector<int>& widths, vector<vector<Rect>>& final_rects) {\n    int C = widths.size();\n    if (C > N) return LLONG_MAX;\n    vector<int> xs(C+1, 0);\n    for (int i = 0; i < C; i++) xs[i+1] = xs[i] + widths[i];\n    vector<int> colOrder(C);\n    iota(colOrder.begin(), colOrder.end(), 0);\n    sort(colOrder.begin(), colOrder.end(), [&](int x, int y){ return widths[x] > widths[y]; });\n    vector<vector<int>> colRanks(C);\n    for (int r = 0; r < N; r++) colRanks[colOrder[r % C]].push_back(r);\n    vector<vector<int>> slotH(C);\n    for (int c = 0; c < C; c++) {\n        int w = widths[c];\n        int ns = colRanks[c].size();\n        slotH[c].assign(ns, 1);\n        for (int s = 0; s < ns; s++) {\n            int rank = colRanks[c][s];\n            int mx = 1;\n            for (int d = 0; d < D; d++) {\n                int val = a[d][N-1-rank];\n                int req = (val + w - 1) / w;\n                mx = max(mx, req);\n            }\n            slotH[c][s] = mx;\n        }\n    }\n    for (int c = 0; c < C; c++) {\n        int ns = slotH[c].size();\n        if (ns == 0) continue;\n        long long sum = 0;\n        for (int x : slotH[c]) sum += x;\n        if (sum > W) {\n            double ratio = (double)W / sum;\n            long long s = 0;\n            for (int& x : slotH[c]) { x = max(1, (int)(x * ratio)); s += x; }\n            while (s > W) {\n                int mi = 0;\n                for (int i = 1; i < ns; i++) if (slotH[c][i] > slotH[c][mi]) mi = i;\n                if (slotH[c][mi] > 1) { slotH[c][mi]--; s--; } else break;\n            }\n            while (s < W) { slotH[c][ns-1]++; s++; }\n        } else slotH[c][ns-1] += (W - sum);\n    }\n    final_rects.assign(D, vector<Rect>(N));\n    long long deficit = 0;\n    for (int d = 0; d < D; d++) {\n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int x, int y){ return a[d][x] > a[d][y]; });\n        for (int c = 0; c < C; c++) {\n            int y = 0;\n            int ns = colRanks[c].size();\n            for (int s = 0; s < ns; s++) {\n                int yEnd = y + slotH[c][s];\n                if (s == ns-1) yEnd = W;\n                int rank = colRanks[c][s];\n                int k = order[rank];\n                final_rects[d][k] = {y, xs[c], yEnd, xs[c+1]};\n                long long area = (long long)(yEnd - y) * widths[c];\n                if (area < a[d][k]) deficit += 100LL * (a[d][k] - area);\n                y = yEnd;\n            }\n        }\n    }\n    return deficit;\n}\n\nint main() {\n    cin >> W >> D >> N;\n    a.assign(D, vector<int>(N));\n    for (int d = 0; d < D; d++) for (int k = 0; k < N; k++) cin >> a[d][k];\n    \n    long long bestCost = LLONG_MAX;\n    vector<vector<Rect>> bestRects;\n    auto tryResult = [&](long long cost, vector<vector<Rect>>& rects) {\n        if (cost < bestCost && !rects.empty()) { bestCost = cost; bestRects = rects; }\n    };\n    \n    mt19937 rng(42);\n    int maxC = min(N, 25);\n    \n    for (int C = 1; C <= maxC; C++) {\n        vector<int> widths(C);\n        int base = W / C, extra = W % C;\n        for (int i = 0; i < C; i++) widths[i] = base + (i < extra ? 1 : 0);\n        vector<vector<Rect>> rects;\n        long long cost = solveWithWidths(widths, rects, true, 0);\n        tryResult(cost, rects);\n        long long cost_asc = solveWithWidths(widths, rects, true, 1);\n        tryResult(cost_asc, rects);\n        long long cost2 = solveWithWidths(widths, rects, false, 0);\n        tryResult(cost2, rects);\n        long long cost2_asc = solveWithWidths(widths, rects, false, 1);\n        tryResult(cost2_asc, rects);\n    }\n    \n    {\n        vector<vector<Rect>> rects;\n        long long cost = solveFixedSingleCol(rects);\n        tryResult(cost, rects);\n    }\n    for (int C = 2; C <= maxC; C++) {\n        vector<int> widths(C);\n        int base = W / C, extra = W % C;\n        for (int i = 0; i < C; i++) widths[i] = base + (i < extra ? 1 : 0);\n        vector<vector<Rect>> rects;\n        long long cost = solveFixedCols(widths, rects);\n        tryResult(cost, rects);\n    }\n    \n    auto clock_start = chrono::steady_clock::now();\n    auto get_time = [&](){ return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - clock_start).count(); };\n    \n    int trials = 0;\n    while (get_time() < 2500) {\n        trials++;\n        int C = 2 + rng() % (maxC - 1);\n        if (C > N) continue;\n        set<int> bs;\n        int guard = 0;\n        while ((int)bs.size() < C-1 && guard < 1000) {\n            int x = 10 + rng() % (W - 20);\n            bs.insert(x); guard++;\n        }\n        if ((int)bs.size() < C-1) continue;\n        vector<int> breaks(bs.begin(), bs.end());\n        vector<int> widths(C);\n        int prev = 0;\n        for (int i = 0; i < C-1; i++) { widths[i] = breaks[i] - prev; prev = breaks[i]; }\n        widths[C-1] = W - prev;\n        bool ok = true;\n        for (int w : widths) if (w < 5) { ok = false; break; }\n        if (!ok) continue;\n        vector<vector<Rect>> rects;\n        long long cost = solveFixedCols(widths, rects);\n        tryResult(cost, rects);\n        if (trials % 2 == 0) {\n            long long cost2 = solveWithWidths(widths, rects, true, 0);\n            tryResult(cost2, rects);\n        }\n    }\n    \n    // Extra tightMode=1 phase\n    while (get_time() < 2700) {\n        int C = 2 + rng() % (maxC - 1);\n        if (C > N) continue;\n        set<int> bs;\n        int guard = 0;\n        while ((int)bs.size() < C-1 && guard < 1000) {\n            int x = 10 + rng() % (W - 20);\n            bs.insert(x); guard++;\n        }\n        if ((int)bs.size() < C-1) continue;\n        vector<int> breaks(bs.begin(), bs.end());\n        vector<int> widths(C);\n        int prev = 0;\n        for (int i = 0; i < C-1; i++) { widths[i] = breaks[i] - prev; prev = breaks[i]; }\n        widths[C-1] = W - prev;\n        bool ok = true;\n        for (int w : widths) if (w < 5) { ok = false; break; }\n        if (!ok) continue;\n        vector<vector<Rect>> rects;\n        long long cost = solveWithWidths(widths, rects, true, 1);\n        tryResult(cost, rects);\n        long long cost2 = solveWithWidths(widths, rects, false, 1);\n        tryResult(cost2, rects);\n    }\n    \n    if (bestRects.empty()) {\n        bestRects.assign(D, vector<Rect>(N));\n        for (int d = 0; d < D; d++) for (int k = 0; k < N; k++) bestRects[d][k] = {k, 0, k+1, W};\n    }\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            auto& r = bestRects[d][k];\n            if (r.i0 >= r.i1 || r.j0 >= r.j1) r = {0, 0, 1, 1};\n            cout << r.i0 << \" \" << r.j0 << \" \" << r.i1 << \" \" << r.j1 << \"\\n\";\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\nconst int MAX_K = 6;\n\nint N, M, K;\nlong long a0[9][9];\nlong long ss[20][3][3];\nlong long ss_flat[20][9];\n\nvector<long long> combo_mats[MAX_K+1];\nvector<array<int8_t, MAX_K>> combo_stamps[MAX_K+1];\nint combo_count[MAX_K+1];\n\nstatic inline long long addmod(long long a, long long b){\n    long long v = a + b;\n    if(v >= MOD) v -= MOD;\n    return v;\n}\n\nstatic inline long long submod(long long a, long long b){\n    long long v = a - b;\n    if(v < 0) v += MOD;\n    return v;\n}\n\nvoid gen_combos(){\n    for(int m = 0; m < M; m++){\n        for(int i = 0; i < 3; i++){\n            for(int j = 0; j < 3; j++){\n                ss_flat[m][i*3+j] = ss[m][i][j];\n            }\n        }\n    }\n    \n    long long sizes[] = {1, 20, 210, 1540, 8855, 42504, 177100};\n    for(int k = 0; k <= MAX_K; k++){\n        combo_mats[k].reserve(sizes[k] * 9);\n        combo_stamps[k].reserve(sizes[k]);\n    }\n    \n    for(int i = 0; i < 9; i++) combo_mats[0].push_back(0);\n    array<int8_t, MAX_K> zs;\n    for(int i = 0; i < MAX_K; i++) zs[i] = 0;\n    combo_stamps[0].push_back(zs);\n    combo_count[0] = 1;\n    \n    for(int k = 1; k <= MAX_K; k++){\n        int prev_count = combo_count[k-1];\n        combo_count[k] = 0;\n        for(int idx = 0; idx < prev_count; idx++){\n            const long long* pmat = &combo_mats[k-1][idx * 9];\n            auto pstamps = combo_stamps[k-1][idx];\n            int start = (k == 1) ? 0 : (int)pstamps[k-2];\n            for(int m = start; m < M; m++){\n                for(int i = 0; i < 9; i++){\n                    long long v = pmat[i] + ss_flat[m][i];\n                    if(v >= MOD) v -= MOD;\n                    combo_mats[k].push_back(v);\n                }\n                array<int8_t, MAX_K> ns = pstamps;\n                ns[k-1] = (int8_t)m;\n                combo_stamps[k].push_back(ns);\n                combo_count[k]++;\n            }\n        }\n    }\n}\n\npair<long long, vector<tuple<int,int,int> > > greedy_solve(long long lambda){\n    long long a[9][9];\n    memcpy(a, a0, sizeof(a0));\n    vector<tuple<int,int,int> > ops;\n    int budget = K;\n    \n    for(int p = 0; p <= N-3; p++){\n        for(int q = 0; q <= N-3; q++){\n            int locked_indices[9];\n            int locked_di[9], locked_dj[9];\n            int nlocked = 0;\n            for(int di = 0; di < 3; di++){\n                for(int dj = 0; dj < 3; dj++){\n                    int i = p+di, j = q+dj;\n                    int mi = (i < 6) ? i : 6;\n                    int mj = (j < 6) ? j : 6;\n                    if(mi == p && mj == q){\n                        locked_indices[nlocked] = di*3+dj;\n                        locked_di[nlocked] = di;\n                        locked_dj[nlocked] = dj;\n                        nlocked++;\n                    }\n                }\n            }\n            \n            int max_k;\n            if(nlocked == 1) max_k = 3;\n            else if(nlocked == 3) max_k = 5;\n            else max_k = 6;\n            if(max_k > budget) max_k = budget;\n            if(max_k < 0) max_k = 0;\n            \n            long long curv[9];\n            for(int ii = 0; ii < nlocked; ii++){\n                curv[ii] = a[p+locked_di[ii]][q+locked_dj[ii]];\n            }\n            \n            int best_k = 0;\n            int best_idx = 0;\n            long long best_sc = LLONG_MIN;\n            \n            for(int k = 0; k <= max_k; k++){\n                long long kl = (long long)k * lambda;\n                int cnt = combo_count[k];\n                const long long* mats_ptr = combo_mats[k].data();\n                for(int idx = 0; idx < cnt; idx++){\n                    const long long* mat = mats_ptr + idx * 9;\n                    long long sum = 0;\n                    for(int ii = 0; ii < nlocked; ii++){\n                        long long v = curv[ii] + mat[locked_indices[ii]];\n                        if(v >= MOD) v -= MOD;\n                        sum += v;\n                    }\n                    long long sc = sum - kl;\n                    if(sc > best_sc){\n                        best_sc = sc;\n                        best_k = k;\n                        best_idx = idx;\n                    }\n                }\n            }\n            \n            const auto& best_stamps = combo_stamps[best_k][best_idx];\n            for(int ii = 0; ii < best_k; ii++){\n                int m = (int)best_stamps[ii];\n                ops.push_back(make_tuple(m, p, q));\n                for(int i = 0; i < 3; i++){\n                    for(int j = 0; j < 3; j++){\n                        a[p+i][q+j] = addmod(a[p+i][q+j], ss[m][i][j]);\n                    }\n                }\n                budget--;\n            }\n        }\n    }\n    \n    long long score = 0;\n    for(int i = 0; i < N; i++){\n        for(int j = 0; j < N; j++){\n            score += a[i][j];\n        }\n    }\n    return make_pair(score, ops);\n}\n\nlong long g_best_sum;\nint g_best_k;\nint8_t g_best_stamps[16];\nint8_t g_cur_stamps[16];\nlong long g_curv[9];\n\nvoid dfs_position(int depth, int max_k, int start_m, long long* mat_mod){\n    long long sum = 0;\n    for(int i = 0; i < 9; i++){\n        long long v = g_curv[i] + mat_mod[i];\n        if(v >= MOD) v -= MOD;\n        sum += v;\n    }\n    if(sum > g_best_sum){\n        g_best_sum = sum;\n        g_best_k = depth;\n        memcpy(g_best_stamps, g_cur_stamps, depth);\n    }\n    if(depth >= max_k) return;\n    \n    for(int m = start_m; m < M; m++){\n        long long new_mat[9];\n        for(int i = 0; i < 9; i++){\n            long long v = mat_mod[i] + ss_flat[m][i];\n            if(v >= MOD) v -= MOD;\n            new_mat[i] = v;\n        }\n        g_cur_stamps[depth] = (int8_t)m;\n        dfs_position(depth+1, max_k, m, new_mat);\n    }\n}\n\nvoid resolve_position(vector<tuple<int,int,int> >& ops, int pp, int qq, int max_k_cap){\n    vector<tuple<int,int,int> > kept;\n    for(size_t t = 0; t < ops.size(); t++){\n        if(get<1>(ops[t]) == pp && get<2>(ops[t]) == qq){\n            // skip\n        } else {\n            kept.push_back(ops[t]);\n        }\n    }\n    \n    long long curv[9];\n    for(int i = 0; i < 3; i++){\n        for(int j = 0; j < 3; j++){\n            curv[i*3+j] = a0[pp+i][qq+j];\n        }\n    }\n    for(size_t t = 0; t < kept.size(); t++){\n        int m = get<0>(kept[t]);\n        int p = get<1>(kept[t]);\n        int q = get<2>(kept[t]);\n        for(int i = 0; i < 3; i++){\n            for(int j = 0; j < 3; j++){\n                int r = p+i, c = q+j;\n                if(r >= pp && r <= pp+2 && c >= qq && c <= qq+2){\n                    curv[(r-pp)*3+(c-qq)] = addmod(curv[(r-pp)*3+(c-qq)], ss[m][i][j]);\n                }\n            }\n        }\n    }\n    \n    int max_k = K - (int)kept.size();\n    if(max_k > max_k_cap) max_k = max_k_cap;\n    if(max_k < 0) max_k = 0;\n    \n    for(int i = 0; i < 9; i++) g_curv[i] = curv[i];\n    g_best_sum = 0;\n    for(int i = 0; i < 9; i++) g_best_sum += curv[i];\n    g_best_k = 0;\n    \n    long long mat_mod[9];\n    for(int i = 0; i < 9; i++) mat_mod[i] = 0;\n    \n    dfs_position(0, max_k, 0, mat_mod);\n    \n    ops = kept;\n    for(int i = 0; i < g_best_k; i++){\n        ops.push_back(make_tuple((int)g_best_stamps[i], pp, qq));\n    }\n}\n\nlong long compute_score(vector<tuple<int,int,int> >& ops){\n    long long stamp_sum[9][9];\n    for(int i = 0; i < 9; i++){\n        for(int j = 0; j < 9; j++){\n            stamp_sum[i][j] = 0;\n        }\n    }\n    for(size_t t = 0; t < ops.size(); t++){\n        int m = get<0>(ops[t]);\n        int p = get<1>(ops[t]);\n        int q = get<2>(ops[t]);\n        for(int i = 0; i < 3; i++){\n            for(int j = 0; j < 3; j++){\n                stamp_sum[p+i][q+j] = addmod(stamp_sum[p+i][q+j], ss[m][i][j]);\n            }\n        }\n    }\n    long long score = 0;\n    for(int i = 0; i < 9; i++){\n        for(int j = 0; j < 9; j++){\n            score += addmod(a0[i][j], stamp_sum[i][j]);\n        }\n    }\n    return score;\n}\n\nvoid resolve_all_critical(vector<tuple<int,int,int> >& ops){\n    // Corner\n    resolve_position(ops, 6, 6, 7);\n    // Boundaries\n    for(int q = 0; q < 6; q++){\n        resolve_position(ops, 6, q, 6);\n    }\n    for(int p = 0; p < 6; p++){\n        resolve_position(ops, p, 6, 6);\n    }\n}\n\nlong long local_search(vector<tuple<int,int,int> >& ops, double time_limit_sec, chrono::steady_clock::time_point start_time){\n    long long stamp_sum[9][9];\n    for(int i = 0; i < 9; i++){\n        for(int j = 0; j < 9; j++){\n            stamp_sum[i][j] = 0;\n        }\n    }\n    for(size_t t = 0; t < ops.size(); t++){\n        int m = get<0>(ops[t]);\n        int p = get<1>(ops[t]);\n        int q = get<2>(ops[t]);\n        for(int i = 0; i < 3; i++){\n            for(int j = 0; j < 3; j++){\n                stamp_sum[p+i][q+j] = addmod(stamp_sum[p+i][q+j], ss[m][i][j]);\n            }\n        }\n    }\n    long long score = 0;\n    for(int i = 0; i < 9; i++){\n        for(int j = 0; j < 9; j++){\n            score += addmod(a0[i][j], stamp_sum[i][j]);\n        }\n    }\n    \n    auto elapsed_sec = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    };\n    \n    bool improved = true;\n    while(improved){\n        if(elapsed_sec() >= time_limit_sec) break;\n        improved = false;\n        \n        for(int k = 0; k < (int)ops.size(); k++){\n            int mcur = get<0>(ops[k]);\n            int p = get<1>(ops[k]);\n            int q = get<2>(ops[k]);\n            int best_m = mcur;\n            long long best_delta = 0;\n            for(int m2 = 0; m2 < M; m2++){\n                if(m2 == mcur) continue;\n                long long delta = 0;\n                for(int i = 0; i < 3; i++){\n                    for(int j = 0; j < 3; j++){\n                        long long old_eff = stamp_sum[p+i][q+j];\n                        long long new_eff = addmod(submod(old_eff, ss[mcur][i][j]), ss[m2][i][j]);\n                        long long old_val = addmod(a0[p+i][q+j], old_eff);\n                        long long new_val = addmod(a0[p+i][q+j], new_eff);\n                        delta += new_val - old_val;\n                    }\n                }\n                if(delta > best_delta){\n                    best_delta = delta;\n                    best_m = m2;\n                }\n            }\n            if(best_m != mcur){\n                for(int i = 0; i < 3; i++){\n                    for(int j = 0; j < 3; j++){\n                        stamp_sum[p+i][q+j] = addmod(submod(stamp_sum[p+i][q+j], ss[mcur][i][j]), ss[best_m][i][j]);\n                    }\n                }\n                get<0>(ops[k]) = best_m;\n                score += best_delta;\n                improved = true;\n            }\n        }\n        \n        if(elapsed_sec() >= time_limit_sec) break;\n        \n        for(int k = 0; k < (int)ops.size(); k++){\n            int mcur = get<0>(ops[k]);\n            int p = get<1>(ops[k]);\n            int q = get<2>(ops[k]);\n            long long delta = 0;\n            for(int i = 0; i < 3; i++){\n                for(int j = 0; j < 3; j++){\n                    long long old_eff = stamp_sum[p+i][q+j];\n                    long long new_eff = submod(old_eff, ss[mcur][i][j]);\n                    long long old_val = addmod(a0[p+i][q+j], old_eff);\n                    long long new_val = addmod(a0[p+i][q+j], new_eff);\n                    delta += new_val - old_val;\n                }\n            }\n            if(delta > 0){\n                for(int i = 0; i < 3; i++){\n                    for(int j = 0; j < 3; j++){\n                        stamp_sum[p+i][q+j] = submod(stamp_sum[p+i][q+j], ss[mcur][i][j]);\n                    }\n                }\n                ops.erase(ops.begin() + k);\n                k--;\n                score += delta;\n                improved = true;\n            }\n        }\n        \n        if(elapsed_sec() >= time_limit_sec) break;\n        \n        while((int)ops.size() < K){\n            int best_m = -1, best_p = 0, best_q = 0;\n            long long best_delta = 0;\n            for(int p = 0; p <= 6; p++){\n                for(int q = 0; q <= 6; q++){\n                    for(int m = 0; m < M; m++){\n                        long long delta = 0;\n                        for(int i = 0; i < 3; i++){\n                            for(int j = 0; j < 3; j++){\n                                long long old_eff = stamp_sum[p+i][q+j];\n                                long long new_eff = addmod(old_eff, ss[m][i][j]);\n                                long long old_val = addmod(a0[p+i][q+j], old_eff);\n                                long long new_val = addmod(a0[p+i][q+j], new_eff);\n                                delta += new_val - old_val;\n                            }\n                        }\n                        if(delta > best_delta){\n                            best_delta = delta;\n                            best_m = m;\n                            best_p = p;\n                            best_q = q;\n                        }\n                    }\n                }\n            }\n            if(best_m < 0) break;\n            for(int i = 0; i < 3; i++){\n                for(int j = 0; j < 3; j++){\n                    stamp_sum[best_p+i][best_q+j] = addmod(stamp_sum[best_p+i][best_q+j], ss[best_m][i][j]);\n                }\n            }\n            ops.push_back(make_tuple(best_m, best_p, best_q));\n            score += best_delta;\n            improved = true;\n        }\n        \n        if(elapsed_sec() >= time_limit_sec) break;\n        \n        for(int k = 0; k < (int)ops.size(); k++){\n            if(elapsed_sec() >= time_limit_sec) break;\n            \n            int mcur = get<0>(ops[k]);\n            int pcur = get<1>(ops[k]);\n            int qcur = get<2>(ops[k]);\n            long long rem_delta = 0;\n            long long backup[3][3];\n            for(int i = 0; i < 3; i++){\n                for(int j = 0; j < 3; j++){\n                    backup[i][j] = stamp_sum[pcur+i][qcur+j];\n                    long long new_eff = submod(backup[i][j], ss[mcur][i][j]);\n                    long long old_val = addmod(a0[pcur+i][qcur+j], backup[i][j]);\n                    long long new_val = addmod(a0[pcur+i][qcur+j], new_eff);\n                    rem_delta += new_val - old_val;\n                    stamp_sum[pcur+i][qcur+j] = new_eff;\n                }\n            }\n            \n            int best_m2 = mcur, best_p = pcur, best_q = qcur;\n            long long best_delta = 0;\n            for(int p2 = 0; p2 <= 6; p2++){\n                for(int q2 = 0; q2 <= 6; q2++){\n                    for(int m2 = 0; m2 < M; m2++){\n                        long long add_delta = 0;\n                        for(int i = 0; i < 3; i++){\n                            for(int j = 0; j < 3; j++){\n                                long long old_eff = stamp_sum[p2+i][q2+j];\n                                long long new_eff = addmod(old_eff, ss[m2][i][j]);\n                                long long old_val = addmod(a0[p2+i][q2+j], old_eff);\n                                long long new_val = addmod(a0[p2+i][q2+j], new_eff);\n                                add_delta += new_val - old_val;\n                            }\n                        }\n                        long long total_delta = rem_delta + add_delta;\n                        if(total_delta > best_delta){\n                            best_delta = total_delta;\n                            best_p = p2;\n                            best_q = q2;\n                            best_m2 = m2;\n                        }\n                    }\n                }\n            }\n            \n            if(best_delta > 0){\n                for(int i = 0; i < 3; i++){\n                    for(int j = 0; j < 3; j++){\n                        stamp_sum[best_p+i][best_q+j] = addmod(stamp_sum[best_p+i][best_q+j], ss[best_m2][i][j]);\n                    }\n                }\n                get<0>(ops[k]) = best_m2;\n                get<1>(ops[k]) = best_p;\n                get<2>(ops[k]) = best_q;\n                score += best_delta;\n                improved = true;\n            } else {\n                for(int i = 0; i < 3; i++){\n                    for(int j = 0; j < 3; j++){\n                        stamp_sum[pcur+i][qcur+j] = backup[i][j];\n                    }\n                }\n            }\n        }\n    }\n    \n    return score;\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    cin >> N >> M >> K;\n    for(int i = 0; i < N; i++){\n        for(int j = 0; j < N; j++){\n            cin >> a0[i][j];\n        }\n    }\n    for(int m = 0; m < M; m++){\n        for(int i = 0; i < 3; i++){\n            for(int j = 0; j < 3; j++){\n                cin >> ss[m][i][j];\n            }\n        }\n    }\n    \n    gen_combos();\n    \n    chrono::steady_clock::time_point start_time = chrono::steady_clock::now();\n    auto elapsed = [&](){\n        return chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n    };\n    \n    long long best_score = -1;\n    vector<tuple<int,int,int> > best_ops;\n    \n    int num_lambdas = 100;\n    for(int step = 0; step <= num_lambdas; step++){\n        if(elapsed() > 0.75) break;\n        long long lambda = (long long)((double)MOD * 0.4 * step / num_lambdas);\n        auto res = greedy_solve(lambda);\n        long long sc = res.first;\n        auto& ops = res.second;\n        if((int)ops.size() > K) continue;\n        if(sc > best_score){\n            best_score = sc;\n            best_ops = ops;\n        }\n    }\n    \n    // LS\n    double ls_limit = elapsed() + 0.3;\n    if(ls_limit > 1.1) ls_limit = 1.1;\n    long long new_sc = local_search(best_ops, ls_limit, start_time);\n    if(new_sc > best_score) best_score = new_sc;\n    \n    // Resolve all critical\n    resolve_all_critical(best_ops);\n    long long rs_score = compute_score(best_ops);\n    if(rs_score > best_score) best_score = rs_score;\n    \n    // More LS\n    ls_limit = elapsed() + 0.2;\n    if(ls_limit > 1.4) ls_limit = 1.4;\n    new_sc = local_search(best_ops, ls_limit, start_time);\n    if(new_sc > best_score) best_score = new_sc;\n    \n    // Resolve again\n    resolve_all_critical(best_ops);\n    rs_score = compute_score(best_ops);\n    if(rs_score > best_score) best_score = rs_score;\n    \n    // Kicks\n    mt19937 rng(12345);\n    \n    while(elapsed() < 1.8){\n        vector<tuple<int,int,int> > cand = best_ops;\n        if(cand.empty()) break;\n        \n        int num_kicks = 2 + (rng() % 3);\n        for(int kk = 0; kk < num_kicks; kk++){\n            int idx = rng() % cand.size();\n            int choice = rng() % 3;\n            if(choice == 0){\n                get<0>(cand[idx]) = rng() % M;\n            } else if(choice == 1){\n                get<1>(cand[idx]) = rng() % 7;\n                get<2>(cand[idx]) = rng() % 7;\n            } else {\n                get<0>(cand[idx]) = rng() % M;\n                get<1>(cand[idx]) = rng() % 7;\n                get<2>(cand[idx]) = rng() % 7;\n            }\n        }\n        \n        double lt = elapsed() + 0.08;\n        if(lt > 1.8) lt = 1.8;\n        long long sc = local_search(cand, lt, start_time);\n        \n        // Also resolve corner quickly\n        resolve_position(cand, 6, 6, 7);\n        sc = compute_score(cand);\n        \n        if(sc > best_score){\n            best_score = sc;\n            best_ops = cand;\n        }\n    }\n    \n    // Final resolve\n    if(elapsed() < 1.92){\n        resolve_all_critical(best_ops);\n        rs_score = compute_score(best_ops);\n        if(rs_score > best_score) best_score = rs_score;\n    }\n    \n    cout << best_ops.size() << \"\\n\";\n    for(size_t t = 0; t < best_ops.size(); t++){\n        cout << get<0>(best_ops[t]) << \" \" << get<1>(best_ops[t]) << \" \" << get<2>(best_ops[t]) << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nint A[5][5];\n\nstruct Run {\n    int grid[5][5];\n    int cr[5], cc[5];\n    bool hold[5];\n    int held[5];\n    int nin[5];\n    int nout[5];\n    vector<string> out;\n    int totalDisp;\n    int turns;\n    int stashCols[3];\n    int wantTieBreak;\n    \n    void init() {\n        for(int i=0;i<5;i++)for(int j=0;j<5;j++)grid[i][j]=-1;\n        for(int i=0;i<5;i++){cr[i]=i;cc[i]=0;hold[i]=false;held[i]=-1;nin[i]=0;nout[i]=0;}\n        out.assign(5,\"\");\n        totalDisp=0;\n        turns=0;\n    }\n    \n    void doStep(const string& a) {\n        for(int i=0;i<5;i++){\n            if(nin[i]>=5)continue;\n            if(grid[i][0]!=-1)continue;\n            bool h=false;\n            for(int k=0;k<5;k++) if(cr[k]==i&&cc[k]==0&&hold[k]){h=true;break;}\n            if(h)continue;\n            grid[i][0]=A[i][nin[i]++];\n        }\n        int nr[5], nc[5];\n        for(int i=0;i<5;i++){nr[i]=cr[i];nc[i]=cc[i];}\n        for(int i=0;i<5;i++){\n            if(cr[i]==-1)continue;\n            char ch=a[i];\n            if(ch=='U')nr[i]--;\n            else if(ch=='D')nr[i]++;\n            else if(ch=='L')nc[i]--;\n            else if(ch=='R')nc[i]++;\n        }\n        for(int i=0;i<5;i++){cr[i]=nr[i];cc[i]=nc[i];}\n        for(int i=0;i<5;i++){\n            if(cr[i]==-1)continue;\n            char ch=a[i];\n            if(ch=='P'){\n                held[i]=grid[cr[i]][cc[i]];\n                grid[cr[i]][cc[i]]=-1;\n                hold[i]=true;\n            } else if(ch=='Q'){\n                grid[cr[i]][cc[i]]=held[i];\n                held[i]=-1;\n                hold[i]=false;\n            } else if(ch=='B'){\n                cr[i]=-1;cc[i]=-1;\n            }\n        }\n        for(int i=0;i<5;i++) out[i]+=a[i];\n        turns++;\n        for(int i=0;i<5;i++){\n            if(grid[i][4]!=-1){\n                int v=grid[i][4];\n                grid[i][4]=-1;\n                totalDisp++;\n                if(v/5==i) nout[i]++;\n            }\n        }\n    }\n    \n    void moveLarge(int tr, int tc) {\n        int guard=0;\n        while((cr[0]!=tr || cc[0]!=tc) && turns<9900 && guard<200) {\n            string a=\".....\"; \n            char ch='.';\n            if(cr[0]<tr) ch='D';\n            else if(cr[0]>tr) ch='U';\n            else if(cc[0]<tc) ch='R';\n            else if(cc[0]>tc) ch='L';\n            a[0]=ch;\n            doStep(a);\n            guard++;\n        }\n    }\n    \n    void P0(){ string a=\".....\"; a[0]='P'; doStep(a); }\n    void Q0(){ string a=\".....\"; a[0]='Q'; doStep(a); }\n    \n    bool isSafeZone(int r, int c) { return r == 0 || c >= 3; }\n    \n    int safeDist(int sr, int sc, int tr, int tc) {\n        if(!isSafeZone(sr, sc) || !isSafeZone(tr, tc)) return INT_MAX;\n        int dist[5][5];\n        for(int r=0;r<5;r++) for(int c=0;c<5;c++) dist[r][c] = INT_MAX;\n        queue<pair<int,int>> q;\n        q.push({sr, sc});\n        dist[sr][sc] = 0;\n        int drs[] = {-1, 1, 0, 0};\n        int dcs[] = {0, 0, -1, 1};\n        while(!q.empty()){\n            auto [r, c] = q.front(); q.pop();\n            for(int k=0;k<4;k++){\n                int nr = r + drs[k], nc = c + dcs[k];\n                if(nr<0||nr>=5||nc<0||nc>=5) continue;\n                if(!isSafeZone(nr, nc)) continue;\n                if(dist[nr][nc] != INT_MAX) continue;\n                dist[nr][nc] = dist[r][c] + 1;\n                q.push({nr, nc});\n            }\n        }\n        return dist[tr][tc];\n    }\n    \n    char moveCharSafe(int tr, int tc) {\n        int drs[] = {-1, 1, 0, 0};\n        int dcs[] = {0, 0, -1, 1};\n        char cmds[] = {'U', 'D', 'L', 'R'};\n        int bestD = INT_MAX;\n        char bestCmd = '.';\n        for(int k=0;k<4;k++){\n            int nr = cr[0] + drs[k], nc = cc[0] + dcs[k];\n            if(nr<0||nr>=5||nc<0||nc>=5) continue;\n            if(!isSafeZone(nr, nc)) continue;\n            int d = safeDist(nr, nc, tr, tc);\n            if(d < bestD){\n                bestD = d;\n                bestCmd = cmds[k];\n            }\n        }\n        return bestCmd;\n    }\n    \n    char planCrane0Restricted() {\n        if(hold[0]){\n            int v = held[0];\n            int g = v / 5;\n            if(cr[0] == g && cc[0] == 4) return 'Q';\n            return moveCharSafe(g, 4);\n        }\n        int bestCost = INT_MAX;\n        int btr = -1, btc = -1;\n        for(int g=0; g<5; g++){\n            if(nout[g] >= 5) continue;\n            int w = g*5 + nout[g];\n            for(int r=0; r<5; r++) for(int c=0; c<5; c++){\n                if(grid[r][c] != w) continue;\n                if(!isSafeZone(r, c)) continue;\n                int d1 = safeDist(cr[0], cc[0], r, c);\n                if(d1 == INT_MAX) continue;\n                int d2 = safeDist(r, c, g, 4);\n                if(d2 == INT_MAX) continue;\n                int cost = d1 + d2;\n                if(cost < bestCost){\n                    bestCost = cost;\n                    btr = r; btc = c;\n                }\n            }\n        }\n        if(btr == -1) return '.';\n        if(cr[0] == btr && cc[0] == btc) return 'P';\n        return moveCharSafe(btr, btc);\n    }\n    \n    void phase1_2pass() {\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"QQQQQ\");\n        doStep(\"LLLLL\"); doStep(\"LLLLL\"); doStep(\"PPPPP\"); doStep(\"RRRRR\");\n        doStep(\"QQQQQ\"); doStep(\".BBBB\");\n    }\n    \n    void phase1_3pass() {\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"QQQQQ\");\n        doStep(\"LLLLL\"); doStep(\"LLLLL\"); doStep(\"LLLLL\");\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"QQQQQ\");\n        doStep(\"LLLLL\"); doStep(\"LLLLL\");\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"QQQQQ\");\n        doStep(\".BBBB\");\n    }\n    \n    void phase1_hybrid1() {\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"QRRRR\");\n        doStep(\"LQQQQ\"); doStep(\"LLLLL\"); doStep(\"PLLLL\"); doStep(\"RLLLL\");\n        doStep(\"QPPPP\"); doStep(\".RRRR\"); doStep(\".RRRR\"); doStep(\".QQQQ\");\n        doStep(\".LLLL\"); doStep(\".LLLL\"); doStep(\".PPPP\"); doStep(\".RRRR\");\n        doStep(\".QQQQ\"); doStep(\".BBBB\");\n    }\n    \n    void phase1_hybrid1_active() {\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"QRRRR\");\n        doStep(\"LQQQQ\"); doStep(\"LLLLL\"); doStep(\"PLLLL\"); doStep(\"RLLLL\");\n        doStep(\"QPPPP\");\n        string smallActs[] = {\"RRRR\", \"RRRR\", \"QQQQ\", \"LLLL\", \"LLLL\", \"PPPP\", \"RRRR\", \"QQQQ\", \"BBBB\"};\n        for(int t = 0; t < 9; t++){\n            char act0 = planCrane0Restricted();\n            string a;\n            a += act0;\n            a += smallActs[t];\n            doStep(a);\n        }\n    }\n    \n    void phase1_hybrid2() {\n        doStep(\"PPPPP\"); doStep(\"RRRRR\"); doStep(\"RRRRR\"); doStep(\"QRRRQ\");\n        doStep(\"LQQQL\"); doStep(\"LLLLL\"); doStep(\"PLLLP\"); doStep(\"RLLLR\");\n        doStep(\"QPPPQ\"); doStep(\".RRRB\"); doStep(\".RRR.\"); doStep(\".QQQ.\");\n        doStep(\".LLL.\"); doStep(\".LLL.\"); doStep(\".PPP.\"); doStep(\".RRR.\");\n        doStep(\".QQQ.\"); doStep(\".BBB.\");\n    }\n    \n    void deliverHeldOrStash() {\n        int v = held[0];\n        int g = v / 5;\n        if(nout[g] < 5 && v == g*5+nout[g]){\n            moveLarge(g, 4);\n            Q0();\n        } else {\n            int dr=-1, dc=-1;\n            int tgt_row = v/5;\n            for(int ci=0;ci<3;ci++){\n                int c=stashCols[ci];\n                if(grid[tgt_row][c]==-1){dr=tgt_row;dc=c;break;}\n            }\n            if(dr==-1) {\n                for(int ci=0;ci<3 && dr==-1;ci++){\n                    int c=stashCols[ci];\n                    for(int r=0;r<5;r++) if(grid[r][c]==-1){dr=r;dc=c;break;}\n                }\n            }\n            if(dr!=-1) {\n                moveLarge(dr, dc);\n                Q0();\n            }\n        }\n    }\n    \n    bool doStash() {\n        int sr = -1;\n        int best_prio = INT_MAX;\n        for(int i=0;i<5;i++){\n            if(grid[i][0]==-1) continue;\n            int prio;\n            if(nin[i]>=5) prio = 10000;\n            else {\n                int next = A[i][nin[i]];\n                bool isWant = false;\n                for(int g=0;g<5;g++){\n                    if(nout[g]<5 && g*5+nout[g]==next){isWant=true; break;}\n                }\n                prio = isWant ? (-1000+next) : next;\n            }\n            if(prio < best_prio){\n                best_prio = prio;\n                sr = i;\n            }\n        }\n        if(sr==-1) return false;\n        int v = grid[sr][0];\n        int tgt_row = v/5;\n        int dr=-1, dc=-1;\n        for(int ci=0;ci<3;ci++){\n            int c=stashCols[ci];\n            if(grid[tgt_row][c]==-1){dr=tgt_row;dc=c;break;}\n        }\n        if(dr==-1) {\n            for(int ci=0;ci<3 && dr==-1;ci++){\n                int c=stashCols[ci];\n                for(int r=0;r<5;r++) if(grid[r][c]==-1){dr=r;dc=c;break;}\n            }\n        }\n        if(dr==-1) return false;\n        moveLarge(sr,0);\n        P0();\n        moveLarge(dr,dc);\n        Q0();\n        return true;\n    }\n    \n    void phase2() {\n        int stuck=0;\n        while(totalDisp < 25 && turns < 9900) {\n            if(hold[0]){ deliverHeldOrStash(); continue; }\n            int best_cost = INT_MAX;\n            int tr=-1, tc=-1, tgate=-1;\n            for(int g=0;g<5;g++){\n                if(nout[g]>=5) continue;\n                int want = g*5 + nout[g];\n                for(int r=0;r<5;r++) for(int c=0;c<5;c++) {\n                    if(grid[r][c]==want){\n                        int cost;\n                        if(wantTieBreak == 0){\n                            cost = abs(cr[0]-r) + abs(cc[0]-c) + abs(r-g) + abs(4-c);\n                        } else {\n                            cost = g*100 + abs(cr[0]-r) + abs(cc[0]-c) + abs(r-g) + abs(4-c);\n                        }\n                        if(cost < best_cost) {\n                            best_cost = cost;\n                            tr=r; tc=c; tgate=g;\n                        }\n                    }\n                }\n            }\n            if(tr!=-1) {\n                moveLarge(tr,tc);\n                P0();\n                moveLarge(tgate,4);\n                Q0();\n                stuck=0;\n            } else {\n                if (!doStash()) {\n                    doStep(\".....\");\n                    stuck++;\n                    if(stuck>200) break;\n                }\n            }\n        }\n    }\n    \n    void phase2_tsp() {\n        int stuck=0;\n        while(totalDisp < 25 && turns < 9900) {\n            if(hold[0]){ deliverHeldOrStash(); continue; }\n            vector<tuple<int,int,int,int>> wants;\n            for(int g=0;g<5;g++){\n                if(nout[g]>=5) continue;\n                int w = g*5 + nout[g];\n                for(int r=0;r<5;r++) for(int c=0;c<5;c++){\n                    if(grid[r][c]==w) wants.push_back({w, r, c, g});\n                }\n            }\n            if(!wants.empty()){\n                int n = wants.size();\n                vector<int> perm(n);\n                iota(perm.begin(), perm.end(), 0);\n                int bestCost = INT_MAX;\n                int bestFirst = 0;\n                do {\n                    int cost = 0;\n                    int curR = cr[0], curC = cc[0];\n                    for(int idx : perm){\n                        auto& [w, r, c, g] = wants[idx];\n                        cost += abs(curR - r) + abs(curC - c) + abs(r - g) + abs(4 - c);\n                        curR = g; curC = 4;\n                    }\n                    if(cost < bestCost){\n                        bestCost = cost;\n                        bestFirst = perm[0];\n                    }\n                } while(next_permutation(perm.begin(), perm.end()));\n                auto& [w, r, c, g] = wants[bestFirst];\n                moveLarge(r, c);\n                P0();\n                moveLarge(g, 4);\n                Q0();\n                stuck=0;\n            } else {\n                if (!doStash()) {\n                    doStep(\".....\");\n                    stuck++;\n                    if(stuck>200) break;\n                }\n            }\n        }\n    }\n    \n    void phase2_3step() {\n        int stuck=0;\n        while(totalDisp < 25 && turns < 9900) {\n            if(hold[0]){ deliverHeldOrStash(); continue; }\n            \n            vector<tuple<int,int,int,int>> initialWants;\n            for(int g=0;g<5;g++){\n                if(nout[g]>=5) continue;\n                int w = g*5 + nout[g];\n                for(int r=0;r<5;r++) for(int c=0;c<5;c++){\n                    if(grid[r][c]==w) initialWants.push_back({g, r, c, w});\n                }\n            }\n            \n            if(initialWants.empty()){\n                if (!doStash()) {\n                    doStep(\".....\");\n                    stuck++;\n                    if(stuck>200) break;\n                }\n                continue;\n            }\n            \n            int bestCost = INT_MAX;\n            int bestIdx = 0;\n            int tempNout[5];\n            \n            for(int i1=0; i1<(int)initialWants.size(); i1++){\n                auto [g1, r1, c1, w1] = initialWants[i1];\n                int cost1 = abs(cr[0]-r1) + abs(cc[0]-c1) + abs(r1-g1) + abs(4-c1);\n                memcpy(tempNout, nout, sizeof(nout));\n                tempNout[g1]++;\n                \n                vector<tuple<int,int,int,int>> wants2;\n                for(int g=0;g<5;g++){\n                    if(tempNout[g]>=5) continue;\n                    int w = g*5 + tempNout[g];\n                    for(int r=0;r<5;r++) for(int c=0;c<5;c++){\n                        if(grid[r][c]==w && !(r==r1&&c==c1)) wants2.push_back({g, r, c, w});\n                    }\n                }\n                \n                if(wants2.empty()){\n                    if(cost1 < bestCost){ bestCost = cost1; bestIdx = i1; }\n                    continue;\n                }\n                \n                for(int i2=0; i2<(int)wants2.size(); i2++){\n                    auto [g2, r2, c2, w2] = wants2[i2];\n                    int cost2 = abs(g1-r2) + abs(4-c2) + abs(r2-g2) + abs(4-c2);\n                    int prev2 = tempNout[g2];\n                    tempNout[g2]++;\n                    \n                    int minVal = INT_MAX;\n                    bool has3 = false;\n                    for(int g=0;g<5;g++){\n                        if(tempNout[g]>=5) continue;\n                        int w = g*5 + tempNout[g];\n                        for(int r=0;r<5;r++) for(int c=0;c<5;c++){\n                            if(grid[r][c]==w && !(r==r1&&c==c1) && !(r==r2&&c==c2)){\n                                int ccc = abs(g2-r) + abs(4-c) + abs(r-g) + abs(4-c);\n                                if(ccc<minVal){minVal=ccc; has3=true;}\n                            }\n                        }\n                    }\n                    int minCost3 = has3 ? minVal : 0;\n                    \n                    int total = cost1 + cost2 + minCost3;\n                    if(total < bestCost){ bestCost = total; bestIdx = i1; }\n                    \n                    tempNout[g2] = prev2;\n                }\n            }\n            \n            auto [g, r, c, w] = initialWants[bestIdx];\n            moveLarge(r, c);\n            P0();\n            moveLarge(g, 4);\n            Q0();\n            stuck=0;\n        }\n    }\n    \n    void applyCandInline(int type, int r, int c, int g, int sr, int dr, int dc) {\n        if (type == 0) {\n            moveLarge(r, c); P0();\n            moveLarge(g, 4); Q0();\n        } else {\n            moveLarge(sr, 0); P0();\n            moveLarge(dr, dc); Q0();\n        }\n    }\n    \n    vector<tuple<int,int,int,int,int,int,int>> genCandidates(int maxDestPerSource) {\n        vector<tuple<int,int,int,int,int,int,int>> cands;\n        for (int g=0; g<5; g++) {\n            if (nout[g] >= 5) continue;\n            int w = g*5 + nout[g];\n            for (int r=0; r<5; r++) for (int c=0; c<5; c++) {\n                if (grid[r][c] == w) {\n                    cands.push_back(make_tuple(0, r, c, g, -1, -1, -1));\n                }\n            }\n        }\n        for (int sr=0; sr<5; sr++) {\n            if (grid[sr][0] == -1) continue;\n            int v = grid[sr][0];\n            int tgt_row = v/5;\n            vector<pair<int,int>> dests;\n            for (int ci=0; ci<3; ci++) {\n                int c = stashCols[ci];\n                if (grid[tgt_row][c] == -1) {\n                    dests.push_back({tgt_row, c});\n                }\n            }\n            for (int ci=0; ci<3; ci++) {\n                int c = stashCols[ci];\n                for (int dr=0; dr<5; dr++) {\n                    if (dr == tgt_row) continue;\n                    if (grid[dr][c] == -1) {\n                        dests.push_back({dr, c});\n                    }\n                }\n            }\n            int nDest = min(maxDestPerSource, (int)dests.size());\n            for (int i=0; i<nDest; i++) {\n                cands.push_back(make_tuple(1, -1, -1, -1, sr, dests[i].first, dests[i].second));\n            }\n        }\n        return cands;\n    }\n    \n    void phase2_rollout() {\n        int stuck = 0;\n        while (totalDisp < 25 && turns < 9900) {\n            if (hold[0]) { deliverHeldOrStash(); continue; }\n            auto cands = genCandidates(2);\n            if (cands.empty()) { doStep(\".....\"); stuck++; if(stuck>200) break; continue; }\n            if (cands.size() == 1) {\n                int t, r, c, g, sr2, dr, dc;\n                tie(t, r, c, g, sr2, dr, dc) = cands[0];\n                applyCandInline(t, r, c, g, sr2, dr, dc);\n                stuck = 0;\n                continue;\n            }\n            int bestIdx = 0;\n            int bestScore = INT_MAX;\n            for (int i=0; i<(int)cands.size(); i++) {\n                Run copyRun = *this;\n                int t, r, c, g, sr2, dr, dc;\n                tie(t, r, c, g, sr2, dr, dc) = cands[i];\n                copyRun.applyCandInline(t, r, c, g, sr2, dr, dc);\n                copyRun.phase2_tsp();\n                int score = (copyRun.totalDisp==25) ? copyRun.turns : (1000000 - copyRun.totalDisp);\n                if (score < bestScore) { bestScore = score; bestIdx = i; }\n            }\n            int t, r, c, g, sr2, dr, dc;\n            tie(t, r, c, g, sr2, dr, dc) = cands[bestIdx];\n            applyCandInline(t, r, c, g, sr2, dr, dc);\n            stuck = 0;\n        }\n    }\n    \n    void phase2_rollout_3step() {\n        int stuck = 0;\n        while (totalDisp < 25 && turns < 9900) {\n            if (hold[0]) { deliverHeldOrStash(); continue; }\n            auto cands = genCandidates(2);\n            if (cands.empty()) { doStep(\".....\"); stuck++; if(stuck>200) break; continue; }\n            if (cands.size() == 1) {\n                int t, r, c, g, sr2, dr, dc;\n                tie(t, r, c, g, sr2, dr, dc) = cands[0];\n                applyCandInline(t, r, c, g, sr2, dr, dc);\n                stuck = 0;\n                continue;\n            }\n            int bestIdx = 0;\n            int bestScore = INT_MAX;\n            for (int i=0; i<(int)cands.size(); i++) {\n                Run copyRun = *this;\n                int t, r, c, g, sr2, dr, dc;\n                tie(t, r, c, g, sr2, dr, dc) = cands[i];\n                copyRun.applyCandInline(t, r, c, g, sr2, dr, dc);\n                copyRun.phase2_3step();\n                int score = (copyRun.totalDisp==25) ? copyRun.turns : (1000000 - copyRun.totalDisp);\n                if (score < bestScore) { bestScore = score; bestIdx = i; }\n            }\n            int t, r, c, g, sr2, dr, dc;\n            tie(t, r, c, g, sr2, dr, dc) = cands[bestIdx];\n            applyCandInline(t, r, c, g, sr2, dr, dc);\n            stuck = 0;\n        }\n    }\n    \n    void phase2_rollout2() {\n        int stuck = 0;\n        while (totalDisp < 25 && turns < 9900) {\n            if (hold[0]) { deliverHeldOrStash(); continue; }\n            auto cands = genCandidates(2);\n            if (cands.empty()) { doStep(\".....\"); stuck++; if(stuck>200) break; continue; }\n            if (cands.size() == 1) {\n                int t, r, c, g, sr2, dr, dc;\n                tie(t, r, c, g, sr2, dr, dc) = cands[0];\n                applyCandInline(t, r, c, g, sr2, dr, dc);\n                stuck = 0;\n                continue;\n            }\n            int bestIdx = 0;\n            int bestScore = INT_MAX;\n            for (int i=0; i<(int)cands.size(); i++) {\n                Run c1 = *this;\n                int t, r, c, g, sr2, dr, dc;\n                tie(t, r, c, g, sr2, dr, dc) = cands[i];\n                c1.applyCandInline(t, r, c, g, sr2, dr, dc);\n                int iBestScore = INT_MAX;\n                if (c1.totalDisp >= 25) {\n                    iBestScore = c1.turns;\n                } else {\n                    auto cands2 = c1.genCandidates(2);\n                    if (cands2.empty()) {\n                        Run c2 = c1;\n                        c2.phase2_tsp();\n                        iBestScore = (c2.totalDisp==25) ? c2.turns : (1000000 - c2.totalDisp);\n                    } else {\n                        for (int j=0; j<(int)cands2.size(); j++) {\n                            Run c2 = c1;\n                            int t2, r2, cc2, g2, sr22, dr2, dc2;\n                            tie(t2, r2, cc2, g2, sr22, dr2, dc2) = cands2[j];\n                            c2.applyCandInline(t2, r2, cc2, g2, sr22, dr2, dc2);\n                            c2.phase2_tsp();\n                            int score = (c2.totalDisp==25) ? c2.turns : (1000000 - c2.totalDisp);\n                            if (score < iBestScore) iBestScore = score;\n                        }\n                    }\n                }\n                if (iBestScore < bestScore) { bestScore = iBestScore; bestIdx = i; }\n            }\n            int t, r, c, g, sr2, dr, dc;\n            tie(t, r, c, g, sr2, dr, dc) = cands[bestIdx];\n            applyCandInline(t, r, c, g, sr2, dr, dc);\n            stuck = 0;\n        }\n    }\n    \n    void solve(int p1type, int scOpt, int p2type) {\n        init();\n        if(p1type==0) phase1_2pass();\n        else if(p1type==1) phase1_3pass();\n        else if(p1type==2) phase1_hybrid1();\n        else if(p1type==3) phase1_hybrid2();\n        else phase1_hybrid1_active();\n        \n        int opts[6][3] = {\n            {1,2,3}, {1,3,2}, {2,1,3}, {2,3,1}, {3,1,2}, {3,2,1}\n        };\n        for(int k=0;k<3;k++) stashCols[k] = opts[scOpt][k];\n        \n        if(p2type == 0) { wantTieBreak = 0; phase2(); }\n        else if(p2type == 1) { wantTieBreak = 1; phase2(); }\n        else if(p2type == 2) phase2_tsp();\n        else if(p2type == 3) phase2_3step();\n        else if(p2type == 4) phase2_rollout();\n        else if(p2type == 5) phase2_rollout_3step();\n        else phase2_rollout2();\n    }\n};\n\nint main(){\n    int N; cin>>N;\n    for(int i=0;i<5;i++) for(int j=0;j<5;j++) cin>>A[i][j];\n    \n    int bestScore = INT_MAX;\n    Run best;\n    \n    for(int p1=0; p1<5; p1++) for(int sc=0; sc<6; sc++) for(int p2=0; p2<4; p2++) {\n        Run r;\n        r.solve(p1, sc, p2);\n        int score;\n        if(r.totalDisp == 25) score = r.turns;\n        else score = 1000000 - r.totalDisp;\n        if(score < bestScore){ bestScore = score; best = r; }\n    }\n    \n    for(int p1=0; p1<5; p1++) for(int sc=0; sc<6; sc++) {\n        Run r;\n        r.solve(p1, sc, 4);\n        int score;\n        if(r.totalDisp == 25) score = r.turns;\n        else score = 1000000 - r.totalDisp;\n        if(score < bestScore){ bestScore = score; best = r; }\n    }\n    \n    for(int p1=0; p1<5; p1++) for(int sc=0; sc<6; sc++) {\n        Run r;\n        r.solve(p1, sc, 5);\n        int score;\n        if(r.totalDisp == 25) score = r.turns;\n        else score = 1000000 - r.totalDisp;\n        if(score < bestScore){ bestScore = score; best = r; }\n    }\n    \n    // 2-step rollout: 3 chosen phase 1 variants\n    int p1_choices[3] = {1, 2, 4};\n    for(int pp = 0; pp < 3; pp++) {\n        int p1 = p1_choices[pp];\n        Run r;\n        r.solve(p1, 5, 6);\n        int score;\n        if(r.totalDisp == 25) score = r.turns;\n        else score = 1000000 - r.totalDisp;\n        if(score < bestScore){ bestScore = score; best = r; }\n    }\n    \n    for(int i=0;i<5;i++) cout<<best.out[i]<<\"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint H0[25][25];\n\nstruct Sim {\n    int h[25][25];\n    int negCount=0, posCount=0;\n    vector<string> ops;\n    int cr=0, cc=0;\n    long long load=0;\n    long long cost=0;\n    \n    void init(){\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)h[i][j]=H0[i][j];\n        ops.clear(); cr=cc=0; load=0; cost=0;\n        negCount=posCount=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            if(h[i][j]>0)posCount++;\n            else if(h[i][j]<0)negCount++;\n        }\n    }\n    void updateCount(int oldv, int newv){\n        if(oldv>0)posCount--; else if(oldv<0)negCount--;\n        if(newv>0)posCount++; else if(newv<0)negCount++;\n    }\n    void mv(char d){\n        ops.push_back(string(1,d));\n        cost += 100+load;\n        if(d=='U')cr--; else if(d=='D')cr++; else if(d=='L')cc--; else cc++;\n    }\n    void doLoad(long long d){\n        if(d<=0)return;\n        int oldv=h[cr][cc]; h[cr][cc]-=d; updateCount(oldv,h[cr][cc]);\n        ops.push_back(\"+\"+to_string(d)); load+=d; cost+=d;\n    }\n    void doUnload(long long d){\n        if(d<=0)return;\n        int oldv=h[cr][cc]; h[cr][cc]+=d; updateCount(oldv,h[cr][cc]);\n        ops.push_back(\"-\"+to_string(d)); load-=d; cost+=d;\n    }\n    void moveTo(int tr,int tc){\n        while(cr!=tr){ if(cr<tr)mv('D'); else mv('U'); }\n        while(cc!=tc){ if(cc<tc)mv('R'); else mv('L'); }\n    }\n    void actHere(){\n        if(h[cr][cc]<0 && load>0) doUnload(min(load,(long long)-h[cr][cc]));\n        if(h[cr][cc]>0 && negCount>0) doLoad(h[cr][cc]);\n    }\n    void smartMoveTo(int tr, int tc){\n        while(cr!=tr || cc!=tc){\n            actHere();\n            if(cr!=tr){ if(cr<tr)mv('D'); else mv('U'); }\n            else { if(cc<tc)mv('R'); else mv('L'); }\n        }\n    }\n    void bestMoveTo(int tr, int tc){\n        auto scorePath = [&](bool rowFirst)->long long{\n            long long sc=0;\n            int cr2=cr, cc2=cc;\n            auto step=[&](int r, int c){\n                if(h[r][c]<0 && load>0) sc+= min(load,(long long)-h[r][c]);\n                if(h[r][c]>0 && negCount>0) sc+= h[r][c];\n            };\n            if(rowFirst){\n                while(cr2!=tr){ step(cr2,cc2); if(cr2<tr)cr2++; else cr2--; }\n                while(cc2!=tc){ step(cr2,cc2); if(cc2<tc)cc2++; else cc2--; }\n            } else {\n                while(cc2!=tc){ step(cr2,cc2); if(cc2<tc)cc2++; else cc2--; }\n                while(cr2!=tr){ step(cr2,cc2); if(cr2<tr)cr2++; else cr2--; }\n            }\n            return sc;\n        };\n        bool rowFirst = scorePath(true) >= scorePath(false);\n        if(rowFirst){\n            while(cr!=tr){ actHere(); if(cr<tr)mv('D'); else mv('U'); }\n            while(cc!=tc){ actHere(); if(cc<tc)mv('R'); else mv('L'); }\n        } else {\n            while(cc!=tc){ actHere(); if(cc<tc)mv('R'); else mv('L'); }\n            while(cr!=tr){ actHere(); if(cr<tr)mv('D'); else mv('U'); }\n        }\n    }\n    void dpMoveTo(int tr, int tc){\n        if(cr == tr && cc == tc){ return; }\n        int r1=cr, c1=cc;\n        int dr_dir = tr >= r1 ? 1 : -1;\n        int dc_dir = tc >= c1 ? 1 : -1;\n        int H = abs(tr-r1)+1, W = abs(tc-c1)+1;\n        \n        static long long dp[25][25];\n        static int par[25][25];\n        \n        auto cellBenefit = [&](int r, int c)->long long {\n            long long b = 0;\n            if(h[r][c]<0 && load>0) b += min(load,(long long)-h[r][c]);\n            if(h[r][c]>0 && negCount>0) b += h[r][c];\n            return b;\n        };\n        \n        dp[0][0] = cellBenefit(r1, c1);\n        par[0][0] = -1;\n        for(int r=0;r<H;r++) for(int c=0;c<W;c++){\n            if(r==0 && c==0) continue;\n            int ar = r1 + r*dr_dir;\n            int ac = c1 + c*dc_dir;\n            long long best = LLONG_MIN; int p = -1;\n            long long cb = cellBenefit(ar, ac);\n            if(r > 0){\n                long long v = dp[r-1][c] + cb;\n                if(v > best){ best = v; p = 0; }\n            }\n            if(c > 0){\n                long long v = dp[r][c-1] + cb;\n                if(v > best){ best = v; p = 1; }\n            }\n            dp[r][c] = best;\n            par[r][c] = p;\n        }\n        \n        vector<pair<int,int>> moves;\n        int rr = H-1, ccx = W-1;\n        while(rr>0 || ccx>0){\n            if(par[rr][ccx] == 0){ moves.push_back({dr_dir, 0}); rr--; }\n            else { moves.push_back({0, dc_dir}); ccx--; }\n        }\n        reverse(moves.begin(), moves.end());\n        \n        for(auto& pp : moves){\n            int ddr = pp.first, ddc = pp.second;\n            actHere();\n            if(ddr == 1) mv('D');\n            else if(ddr == -1) mv('U');\n            else if(ddc == 1) mv('R');\n            else mv('L');\n        }\n    }\n    bool done(){ return negCount==0 && posCount==0; }\n};\n\nvector<pair<int,int>> buildPath(bool rowMajor, bool startBot, bool startRight){\n    vector<pair<int,int>> path;\n    if(rowMajor){\n        for(int ii=0;ii<N;ii++){\n            int i = startBot ? N-1-ii : ii;\n            bool rev = (ii%2==1) ^ startRight;\n            if(!rev) for(int j=0;j<N;j++) path.push_back({i,j});\n            else for(int j=N-1;j>=0;j--) path.push_back({i,j});\n        }\n    } else {\n        for(int jj=0;jj<N;jj++){\n            int j = startRight ? N-1-jj : jj;\n            bool rev = (jj%2==1) ^ startBot;\n            if(!rev) for(int i=0;i<N;i++) path.push_back({i,j});\n            else for(int i=N-1;i>=0;i--) path.push_back({i,j});\n        }\n    }\n    return path;\n}\n\nvector<pair<int,int>> buildStripRow(int stripW, bool startBot, bool startRight){\n    vector<pair<int,int>> path;\n    int numStrips = (N + stripW - 1) / stripW;\n    for(int si=0; si<numStrips; si++){\n        int rs = si*stripW;\n        int rStart, rEnd;\n        if(startBot){\n            rStart = N - min(rs+stripW, N);\n            rEnd = N - rs;\n        } else {\n            rStart = rs;\n            rEnd = min(rs+stripW, N);\n        }\n        bool colRev = (si%2==1) ^ startRight;\n        for(int cIdx=0; cIdx<N; cIdx++){\n            int c = colRev ? N-1-cIdx : cIdx;\n            bool goDown = (cIdx%2==0);\n            if(goDown) for(int r=rStart; r<rEnd; r++) path.push_back({r,c});\n            else for(int r=rEnd-1; r>=rStart; r--) path.push_back({r,c});\n        }\n    }\n    return path;\n}\n\nvector<pair<int,int>> buildStripCol(int stripW, bool startRight, bool startBot){\n    vector<pair<int,int>> path;\n    int numStrips = (N + stripW - 1) / stripW;\n    for(int si=0; si<numStrips; si++){\n        int cs = si*stripW;\n        int cStart, cEnd;\n        if(startRight){\n            cStart = N - min(cs+stripW, N);\n            cEnd = N - cs;\n        } else {\n            cStart = cs;\n            cEnd = min(cs+stripW, N);\n        }\n        bool rowRev = (si%2==1) ^ startBot;\n        for(int rIdx=0; rIdx<N; rIdx++){\n            int r = rowRev ? N-1-rIdx : rIdx;\n            bool goRight = (rIdx%2==0);\n            if(goRight) for(int c=cStart; c<cEnd; c++) path.push_back({r,c});\n            else for(int c=cEnd-1; c>=cStart; c--) path.push_back({r,c});\n        }\n    }\n    return path;\n}\n\nvector<pair<int,int>> buildSpiralCW(int rot, bool inward){\n    vector<pair<int,int>> path;\n    int lo_r=0, hi_r=N-1, lo_c=0, hi_c=N-1;\n    while(lo_r <= hi_r && lo_c <= hi_c){\n        for(int c=lo_c; c<=hi_c; c++) path.push_back({lo_r, c});\n        lo_r++;\n        if(lo_r > hi_r) break;\n        for(int r=lo_r; r<=hi_r; r++) path.push_back({r, hi_c});\n        hi_c--;\n        if(lo_c > hi_c) break;\n        for(int c=hi_c; c>=lo_c; c--) path.push_back({hi_r, c});\n        hi_r--;\n        if(lo_r > hi_r) break;\n        for(int r=hi_r; r>=lo_r; r--) path.push_back({r, lo_c});\n        lo_c++;\n    }\n    if(rot != 0){\n        for(auto& p : path){\n            int r=p.first, c=p.second;\n            for(int k=0;k<rot;k++){\n                int nr=c, nc=N-1-r;\n                r=nr; c=nc;\n            }\n            p = {r,c};\n        }\n    }\n    if(!inward) reverse(path.begin(), path.end());\n    return path;\n}\n\nvector<pair<int,int>> buildSpiralCCW(int rot, bool inward){\n    vector<pair<int,int>> path;\n    int lo_r=0, hi_r=N-1, lo_c=0, hi_c=N-1;\n    while(lo_r <= hi_r && lo_c <= hi_c){\n        for(int r=lo_r; r<=hi_r; r++) path.push_back({r, lo_c});\n        lo_c++;\n        if(lo_c > hi_c) break;\n        for(int c=lo_c; c<=hi_c; c++) path.push_back({hi_r, c});\n        hi_r--;\n        if(lo_r > hi_r) break;\n        for(int r=hi_r; r>=lo_r; r--) path.push_back({r, hi_c});\n        hi_c--;\n        if(lo_c > hi_c) break;\n        for(int c=hi_c; c>=lo_c; c--) path.push_back({lo_r, c});\n        lo_r++;\n    }\n    if(rot != 0){\n        for(auto& p : path){\n            int r=p.first, c=p.second;\n            for(int k=0;k<rot;k++){\n                int nr=c, nc=N-1-r;\n                r=nr; c=nc;\n            }\n            p = {r,c};\n        }\n    }\n    if(!inward) reverse(path.begin(), path.end());\n    return path;\n}\n\nvoid snakePass(Sim& s, vector<pair<int,int>>& path, bool rev){\n    if(!rev){\n        for(auto& p:path){\n            int r=p.first,c=p.second;\n            s.moveTo(r,c);\n            if(s.h[r][c]>0) s.doLoad(s.h[r][c]);\n            else if(s.h[r][c]<0) s.doUnload(min(s.load,(long long)-s.h[r][c]));\n        }\n    } else {\n        for(int i=(int)path.size()-1;i>=0;i--){\n            int r=path[i].first,c=path[i].second;\n            s.moveTo(r,c);\n            if(s.h[r][c]>0) s.doLoad(s.h[r][c]);\n            else if(s.h[r][c]<0) s.doUnload(min(s.load,(long long)-s.h[r][c]));\n        }\n    }\n}\n\nvoid smartSnakePass(Sim& s, vector<pair<int,int>>& path){\n    int n=path.size();\n    vector<long long> sufNeg(n+1,0);\n    for(int i=n-1;i>=0;i--){\n        int r=path[i].first,c=path[i].second;\n        sufNeg[i] = sufNeg[i+1] + max(0,-s.h[r][c]);\n    }\n    for(int idx=0;idx<n;idx++){\n        int r=path[idx].first,c=path[idx].second;\n        s.moveTo(r,c);\n        if(s.h[r][c]>0){\n            long long demand = sufNeg[idx+1];\n            long long toLoad = min((long long)s.h[r][c], max(0LL, demand - s.load));\n            s.doLoad(toLoad);\n        } else if(s.h[r][c]<0){\n            s.doUnload(min(s.load,(long long)-s.h[r][c]));\n        }\n    }\n}\n\nvoid trimmedRow(Sim& s, bool startBot){\n    for(int ri=0;ri<N;ri++){\n        int r = startBot ? N-1-ri : ri;\n        int lo=N, hi=-1;\n        for(int c=0;c<N;c++)if(s.h[r][c]!=0){ lo=min(lo,c); hi=max(hi,c); }\n        if(lo>hi) continue;\n        bool leftFirst = abs(s.cc-lo) <= abs(s.cc-hi);\n        int startC = leftFirst ? lo : hi;\n        int endC = leftFirst ? hi : lo;\n        s.moveTo(r, startC);\n        if(s.h[r][s.cc]>0) s.doLoad(s.h[r][s.cc]);\n        else if(s.h[r][s.cc]<0) s.doUnload(min(s.load,(long long)-s.h[r][s.cc]));\n        int dir = startC < endC ? 1 : -1;\n        while(s.cc != endC){\n            s.mv(dir==1?'R':'L');\n            if(s.h[r][s.cc]>0) s.doLoad(s.h[r][s.cc]);\n            else if(s.h[r][s.cc]<0) s.doUnload(min(s.load,(long long)-s.h[r][s.cc]));\n        }\n    }\n}\n\nvoid trimmedCol(Sim& s, bool startRight){\n    for(int ci=0;ci<N;ci++){\n        int c = startRight ? N-1-ci : ci;\n        int lo=N, hi=-1;\n        for(int r=0;r<N;r++)if(s.h[r][c]!=0){ lo=min(lo,r); hi=max(hi,r); }\n        if(lo>hi) continue;\n        bool topFirst = abs(s.cr-lo) <= abs(s.cr-hi);\n        int startR = topFirst ? lo : hi;\n        int endR = topFirst ? hi : lo;\n        s.moveTo(startR, c);\n        if(s.h[s.cr][c]>0) s.doLoad(s.h[s.cr][c]);\n        else if(s.h[s.cr][c]<0) s.doUnload(min(s.load,(long long)-s.h[s.cr][c]));\n        int dir = startR < endR ? 1 : -1;\n        while(s.cr != endR){\n            s.mv(dir==1?'D':'U');\n            if(s.h[s.cr][c]>0) s.doLoad(s.h[s.cr][c]);\n            else if(s.h[s.cr][c]<0) s.doUnload(min(s.load,(long long)-s.h[s.cr][c]));\n        }\n    }\n}\n\nvoid greedyCleanup(Sim& s, int mm){\n    int guard=0;\n    while(!s.done() && guard++<5000){\n        int target=-1,td=INT_MAX;\n        bool lookForNeg = (s.load>0);\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            bool match = lookForNeg ? s.h[i][j]<0 : s.h[i][j]>0;\n            if(match){\n                int d=abs(i-s.cr)+abs(j-s.cc);\n                if(d<td){td=d;target=i*N+j;}\n            }\n        }\n        if(target<0){\n            lookForNeg=!lookForNeg;\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                bool match = lookForNeg ? s.h[i][j]<0 : s.h[i][j]>0;\n                if(match){\n                    int d=abs(i-s.cr)+abs(j-s.cc);\n                    if(d<td){td=d;target=i*N+j;}\n                }\n            }\n            if(target<0)break;\n        }\n        int tr=target/N, tc=target%N;\n        if(mm==1) s.smartMoveTo(tr,tc);\n        else if(mm==2) s.bestMoveTo(tr,tc);\n        else if(mm==3) s.dpMoveTo(tr,tc);\n        else s.moveTo(tr,tc);\n        if(s.h[tr][tc]>0) s.doLoad(s.h[tr][tc]);\n        else if(s.h[tr][tc]<0) s.doUnload(min(s.load,(long long)-s.h[tr][tc]));\n    }\n}\n\nvoid pureGreedy(Sim& s, int mm){\n    int guard=0;\n    while(!s.done() && guard++<5000){\n        if(s.h[s.cr][s.cc]>0 && s.negCount>0){\n            s.doLoad(s.h[s.cr][s.cc]); continue;\n        }\n        if(s.h[s.cr][s.cc]<0 && s.load>0){\n            s.doUnload(min(s.load,(long long)-s.h[s.cr][s.cc]));\n            continue;\n        }\n        int target=-1,td=INT_MAX;\n        if(s.load>0){\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                if(s.h[i][j]<0){\n                    int d=abs(i-s.cr)+abs(j-s.cc);\n                    if(d<td){td=d;target=i*N+j;}\n                }\n            }\n        } else {\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                if(s.h[i][j]>0){\n                    int d=abs(i-s.cr)+abs(j-s.cc);\n                    if(d<td){td=d;target=i*N+j;}\n                }\n            }\n        }\n        if(target<0) break;\n        int tr=target/N, tc=target%N;\n        if(mm==1) s.smartMoveTo(tr,tc);\n        else if(mm==2) s.bestMoveTo(tr,tc);\n        else if(mm==3) s.dpMoveTo(tr,tc);\n        else s.moveTo(tr,tc);\n    }\n}\n\nint main(){\n    cin>>N;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>H0[i][j];\n    \n    Sim best;\n    long long bestCost = LLONG_MAX;\n    \n    auto tryIt = [&](Sim& s){\n        long long c = s.done() ? s.cost : LLONG_MAX;\n        if(c < bestCost){ bestCost = c; best = s; }\n    };\n    \n    for(int mm=0;mm<4;mm++){\n        Sim s; s.init(); pureGreedy(s, mm); tryIt(s);\n    }\n    \n    vector<vector<pair<int,int>>> paths;\n    for(int rm=0;rm<2;rm++)for(int sb=0;sb<2;sb++)for(int sr=0;sr<2;sr++){\n        paths.push_back(buildPath(rm, sb, sr));\n    }\n    for(int sb=0;sb<2;sb++)for(int sr=0;sr<2;sr++){\n        for(int w : {2, 3, 4, 5, 6, 7, 10}){\n            paths.push_back(buildStripRow(w, sb, sr));\n            paths.push_back(buildStripCol(w, sr, sb));\n        }\n    }\n    for(int rot=0; rot<4; rot++){\n        for(int inw=0; inw<2; inw++){\n            paths.push_back(buildSpiralCW(rot, inw==1));\n            paths.push_back(buildSpiralCCW(rot, inw==1));\n        }\n    }\n    \n    for(auto& path : paths){\n        for(int mm=0;mm<4;mm++){\n            {Sim s; s.init(); snakePass(s, path, false); greedyCleanup(s, mm); tryIt(s);}\n            {Sim s; s.init(); smartSnakePass(s, path); greedyCleanup(s, mm); tryIt(s);}\n        }\n    }\n    \n    for(int rm=0;rm<2;rm++)for(int sb=0;sb<2;sb++)for(int sr=0;sr<2;sr++){\n        for(int mm=0;mm<4;mm++){\n            Sim s; s.init();\n            for(int it=0;it<10 && !s.done();it++){\n                if(rm) trimmedRow(s, sb^(it%2));\n                else trimmedCol(s, sr^(it%2));\n            }\n            greedyCleanup(s, mm);\n            tryIt(s);\n        }\n    }\n    \n    for(auto&o:best.ops) cout<<o<<\"\\n\";\n}","ahc035":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, T, SC;\nvector<vector<int>> X;\nmt19937 rng(12345);\n\ninline int pairScore(int a, int b) {\n    int s = 0;\n    for (int l = 0; l < M; l++) s += max(X[a][l], X[b][l]);\n    return s;\n}\n\nint main() {\n    cin >> N >> M >> T;\n    SC = 2*N*(N-1);\n    X.assign(SC, vector<int>(M));\n    for (int i = 0; i < SC; i++)\n        for (int j = 0; j < M; j++) cin >> X[i][j];\n    \n    for (int t = 0; t < T; t++) {\n        bool isLast = (t == T-1);\n        \n        vector<int> Xmax(M, 0);\n        for (int k = 0; k < SC; k++)\n            for (int l = 0; l < M; l++) Xmax[l] = max(Xmax[l], X[k][l]);\n        \n        vector<double> sscore(SC, 0);\n        for (int k = 0; k < SC; k++) {\n            for (int l = 0; l < M; l++) {\n                if (Xmax[l] > 0) {\n                    double r = (double)X[k][l] / Xmax[l];\n                    sscore[k] += r * r * Xmax[l];\n                }\n            }\n        }\n        \n        vector<int> idx(SC);\n        iota(idx.begin(), idx.end(), 0);\n        sort(idx.begin(), idx.end(), [&](int a, int b){ return sscore[a] > sscore[b]; });\n        vector<int> chosen(idx.begin(), idx.begin() + N*N);\n        \n        set<int> chosenSet(chosen.begin(), chosen.end());\n        for (int l = 0; l < M; l++) {\n            vector<int> maxSeeds;\n            for (int k = 0; k < SC; k++) if (X[k][l] == Xmax[l]) maxSeeds.push_back(k);\n            bool found = false;\n            for (int k : maxSeeds) if (chosenSet.count(k)) { found = true; break; }\n            if (!found && !maxSeeds.empty()) {\n                int best = maxSeeds[0];\n                for (int k : maxSeeds) if (sscore[k] > sscore[best]) best = k;\n                int worst = -1; double worstS = 1e18;\n                for (int c : chosen) {\n                    bool isUnique = false;\n                    for (int ll = 0; ll < M; ll++) {\n                        if (X[c][ll] == Xmax[ll]) {\n                            int cnt = 0;\n                            for (int kk : chosen) if (X[kk][ll] == Xmax[ll]) cnt++;\n                            if (cnt == 1) { isUnique = true; break; }\n                        }\n                    }\n                    if (isUnique) continue;\n                    if (sscore[c] < worstS) { worstS = sscore[c]; worst = c; }\n                }\n                if (worst >= 0) {\n                    auto it = find(chosen.begin(), chosen.end(), worst);\n                    *it = best;\n                    chosenSet.erase(worst); chosenSet.insert(best);\n                }\n            }\n        }\n        \n        int NN = N*N;\n        vector<vector<int>> P(NN, vector<int>(NN, 0));\n        for (int i = 0; i < NN; i++)\n            for (int j = 0; j < NN; j++) {\n                if (isLast) {\n                    int sum=0, diffSq=0;\n                    int a=chosen[i], b=chosen[j];\n                    for (int l = 0; l < M; l++) {\n                        sum += X[a][l] + X[b][l];\n                        int d = X[a][l]-X[b][l];\n                        diffSq += d*d;\n                    }\n                    double s = (sum + 2.0 * sqrt((double)diffSq)) * 0.5;\n                    P[i][j] = (int)(s * 100);\n                } else {\n                    P[i][j] = pairScore(chosen[i], chosen[j]);\n                }\n            }\n        \n        vector<int> chosenOrder(NN);\n        iota(chosenOrder.begin(), chosenOrder.end(), 0);\n        sort(chosenOrder.begin(), chosenOrder.end(), [&](int a, int b){\n            return sscore[chosen[a]] > sscore[chosen[b]];\n        });\n        \n        static const int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};\n        \n        auto totalScoreA = [&](vector<vector<int>>& AA) {\n            int s = 0;\n            for (int i = 0; i < N; i++)\n                for (int j = 0; j < N; j++) {\n                    if (j+1 < N) s += P[AA[i][j]][AA[i][j+1]];\n                    if (i+1 < N) s += P[AA[i][j]][AA[i+1][j]];\n                }\n            return s;\n        };\n        \n        auto deltaSwap = [&](vector<vector<int>>& AA, int i1, int j1, int i2, int j2) {\n            int a1 = AA[i1][j1], a2 = AA[i2][j2];\n            int before = 0, after = 0;\n            for (int d = 0; d < 4; d++) {\n                int ni = i1+dr[d], nj = j1+dc[d];\n                if (ni<0||ni>=N||nj<0||nj>=N) continue;\n                if (ni==i2 && nj==j2) continue;\n                int nb = AA[ni][nj];\n                before += P[a1][nb];\n                after += P[a2][nb];\n            }\n            for (int d = 0; d < 4; d++) {\n                int ni = i2+dr[d], nj = j2+dc[d];\n                if (ni<0||ni>=N||nj<0||nj>=N) continue;\n                if (ni==i1 && nj==j1) continue;\n                int nb = AA[ni][nj];\n                before += P[a2][nb];\n                after += P[a1][nb];\n            }\n            return after - before;\n        };\n        \n        vector<pair<int,int>> cells;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            int deg = (i>0)+(i<N-1)+(j>0)+(j<N-1);\n            cells.push_back({-deg, i*N+j});\n        }\n        sort(cells.begin(), cells.end());\n        \n        vector<vector<int>> A(N, vector<int>(N));\n        for (int c = 0; c < NN; c++) {\n            int p = cells[c].second;\n            A[p/N][p%N] = chosenOrder[c];\n        }\n        \n        int curScore = totalScoreA(A);\n        int bestScore = curScore;\n        vector<vector<int>> bestA = A;\n        \n        auto start = chrono::steady_clock::now();\n        double timeLimit = 0.19;\n        double T0 = isLast ? 3000.0 : 30.0;\n        double T1 = isLast ? 10.0 : 0.1;\n        double temp = T0;\n        int iters = 0;\n        \n        while (true) {\n            iters++;\n            if ((iters & 1023) == 0) {\n                auto now = chrono::steady_clock::now();\n                double elapsed = chrono::duration<double>(now-start).count();\n                if (elapsed > timeLimit) break;\n                double progress = elapsed / timeLimit;\n                temp = T0 * pow(T1/T0, progress);\n            }\n            \n            int p1 = rng() % NN;\n            int p2 = rng() % NN;\n            if (p1 == p2) continue;\n            int i1=p1/N, j1=p1%N, i2=p2/N, j2=p2%N;\n            int delta = deltaSwap(A, i1, j1, i2, j2);\n            bool accept = false;\n            if (delta >= 0) accept = true;\n            else {\n                double p = exp(delta / temp);\n                if ((double)(rng() & 0xFFFFFF) / (double)0x1000000 < p) accept = true;\n            }\n            if (accept) {\n                swap(A[i1][j1], A[i2][j2]);\n                curScore += delta;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestA = A;\n                }\n            }\n        }\n        \n        A = bestA;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << chosen[A[i][j]];\n                cout << (j==N-1 ? '\\n' : ' ');\n            }\n        }\n        cout.flush();\n        \n        for (int i = 0; i < SC; i++)\n            for (int j = 0; j < M; j++) cin >> X[i][j];\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n    vector<string> sg(N), tg(N);\n    for (auto& s : sg) cin >> s;\n    for (auto& s : tg) cin >> s;\n    \n    vector<vector<int>> init_has(N, vector<int>(N, 0));\n    vector<vector<int>> isTarget(N, vector<int>(N, 0));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        init_has[i][j] = sg[i][j]=='1';\n        isTarget[i][j] = tg[i][j]=='1';\n    }\n    \n    int Vp = V;\n    int nFingers = Vp - 1;\n    \n    int maxL = max(1, N/2);\n    int numLens = min(maxL, nFingers);\n    if (numLens < 1) numLens = 1;\n    vector<int> L(nFingers);\n    for (int i = 0; i < nFingers; i++) L[i] = (i % numLens) + 1;\n    \n    int dx[4] = {0, 1, 0, -1};\n    int dy[4] = {1, 0, -1, 0};\n    \n    auto clock_start = chrono::steady_clock::now();\n    auto elapsed_ms = [&]() -> long long {\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - clock_start).count();\n    };\n    \n    auto rotCost = [](int a, int b) -> int {\n        int d = (a - b + 4) & 3;\n        return min(d, 4 - d);\n    };\n    \n    auto solve = [&](int startRx, int startRy, int K_lookahead, long long deadline_ms, uint32_t seed) -> pair<vector<string>, int> {\n        mt19937 rng(seed);\n        auto has_ = init_has;\n        int rx = startRx, ry = startRy;\n        vector<int> fdir(nFingers, 0);\n        vector<int> fhold(nFingers, 0);\n        vector<string> ops;\n        \n        auto doTurn = [&](char moveC, vector<char>& rotC) {\n            if (moveC == 'U') rx--;\n            else if (moveC == 'D') rx++;\n            else if (moveC == 'L') ry--;\n            else if (moveC == 'R') ry++;\n            for (int i = 0; i < nFingers; i++) {\n                if (rotC[i] == 'R') fdir[i] = (fdir[i]+1)%4;\n                else if (rotC[i] == 'L') fdir[i] = (fdir[i]+3)%4;\n            }\n            vector<bool> actuallyP(nFingers, false);\n            for (int i = 0; i < nFingers; i++) {\n                int fx = rx + dx[fdir[i]]*L[i];\n                int fy = ry + dy[fdir[i]]*L[i];\n                if (fx<0||fx>=N||fy<0||fy>=N) continue;\n                if (fhold[i] == 0) {\n                    if (has_[fx][fy] && !isTarget[fx][fy]) {\n                        has_[fx][fy] = 0; fhold[i] = 1; actuallyP[i] = true;\n                    }\n                } else {\n                    if (!has_[fx][fy] && isTarget[fx][fy]) {\n                        has_[fx][fy] = 1; fhold[i] = 0; actuallyP[i] = true;\n                    }\n                }\n            }\n            string s(2*Vp, '.');\n            if (moveC != 0) s[0] = moveC;\n            for (int i = 0; i < nFingers; i++) if (rotC[i]) s[1+i] = rotC[i];\n            for (int i = 0; i < nFingers; i++) if (actuallyP[i]) s[Vp+1+i] = 'P';\n            ops.push_back(s);\n        };\n        \n        auto planFull = [&](int rrx, int rry, int& P, int& maxRot, vector<int>& tdir) {\n            P = 0; maxRot = 0;\n            for (int fi = 0; fi < nFingers; fi++) tdir[fi] = -1;\n            vector<long long> claimed;\n            claimed.reserve(nFingers);\n            \n            for (int fi = 0; fi < nFingers; fi++) {\n                int bestRot = INT_MAX, bestD = -1;\n                long long bestKey = -1;\n                int Li = L[fi], fdi = fdir[fi], fhi = fhold[fi];\n                for (int d = 0; d < 4; d++) {\n                    int fx = rrx + dx[d]*Li, fy = rry + dy[d]*Li;\n                    if (fx<0||fx>=N||fy<0||fy>=N) continue;\n                    long long key = (long long)fx * N + fy;\n                    bool alreadyClaimed = false;\n                    for (auto k : claimed) if (k == key) { alreadyClaimed = true; break; }\n                    if (alreadyClaimed) continue;\n                    bool useful = false;\n                    if (fhi == 0) useful = has_[fx][fy] && !isTarget[fx][fy];\n                    else useful = !has_[fx][fy] && isTarget[fx][fy];\n                    if (useful) {\n                        int rc = rotCost(fdi, d);\n                        if (rc < bestRot) { bestRot = rc; bestD = d; bestKey = key; }\n                    }\n                }\n                if (bestD != -1) {\n                    P++;\n                    if (bestRot > maxRot) maxRot = bestRot;\n                    tdir[fi] = bestD;\n                    claimed.push_back(bestKey);\n                }\n            }\n        };\n        \n        auto planScore = [&](int rrx, int rry, int& P, int& maxRot) {\n            P = 0; maxRot = 0;\n            vector<long long> claimed;\n            claimed.reserve(nFingers);\n            \n            for (int fi = 0; fi < nFingers; fi++) {\n                int bestRot = INT_MAX, bestD = -1;\n                long long bestKey = -1;\n                int Li = L[fi], fdi = fdir[fi], fhi = fhold[fi];\n                for (int d = 0; d < 4; d++) {\n                    int fx = rrx + dx[d]*Li, fy = rry + dy[d]*Li;\n                    if (fx<0||fx>=N||fy<0||fy>=N) continue;\n                    long long key = (long long)fx * N + fy;\n                    bool alreadyClaimed = false;\n                    for (auto k : claimed) if (k == key) { alreadyClaimed = true; break; }\n                    if (alreadyClaimed) continue;\n                    bool useful = false;\n                    if (fhi == 0) useful = has_[fx][fy] && !isTarget[fx][fy];\n                    else useful = !has_[fx][fy] && isTarget[fx][fy];\n                    if (useful) {\n                        int rc = rotCost(fdi, d);\n                        if (rc < bestRot) { bestRot = rc; bestD = d; bestKey = key; }\n                    }\n                }\n                if (bestD != -1) {\n                    P++;\n                    if (bestRot > maxRot) maxRot = bestRot;\n                    claimed.push_back(bestKey);\n                }\n            }\n        };\n        \n        auto bestHeuristicDir = [&](int rrx, int rry, int fi) -> int {\n            int bestD = fdir[fi];\n            int bestRot = INT_MAX;\n            int Li = L[fi], fdi = fdir[fi], fhi = fhold[fi];\n            for (int d = 0; d < 4; d++) {\n                int fx = rrx + dx[d]*Li, fy = rry + dy[d]*Li;\n                if (fx<0||fx>=N||fy<0||fy>=N) continue;\n                bool useful = false;\n                if (fhi == 0) useful = has_[fx][fy] && !isTarget[fx][fy];\n                else useful = !has_[fx][fy] && isTarget[fx][fy];\n                if (useful) {\n                    int rc = rotCost(fdi, d);\n                    if (rc < bestRot) { bestRot = rc; bestD = d; }\n                }\n            }\n            return bestD;\n        };\n        \n        auto applyPlanToState = [&](int rrx, int rry, const vector<int>& tdir) {\n            rx = rrx; ry = rry;\n            for (int fi = 0; fi < nFingers; fi++) {\n                if (tdir[fi] != -1) fdir[fi] = tdir[fi];\n            }\n            for (int fi = 0; fi < nFingers; fi++) {\n                if (tdir[fi] == -1) continue;\n                int fx = rx + dx[fdir[fi]] * L[fi];\n                int fy = ry + dy[fdir[fi]] * L[fi];\n                if (fx<0||fx>=N||fy<0||fy>=N) continue;\n                if (fhold[fi] == 0) {\n                    if (has_[fx][fy] && !isTarget[fx][fy]) {\n                        has_[fx][fy] = 0; fhold[fi] = 1;\n                    }\n                } else {\n                    if (!has_[fx][fy] && isTarget[fx][fy]) {\n                        has_[fx][fy] = 1; fhold[fi] = 0;\n                    }\n                }\n            }\n        };\n        \n        struct Cand {\n            double score;\n            uint32_t tiebreak;\n            int rrx, rry, P, T;\n            vector<int> tdir;\n        };\n        \n        vector<int> tdir_buf(nFingers);\n        \n        while (true) {\n            int srcCnt = 0;\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n                if (has_[i][j] && !isTarget[i][j]) srcCnt++;\n            }\n            int nHolding = 0;\n            for (int i = 0; i < nFingers; i++) nHolding += fhold[i];\n            \n            if (srcCnt == 0 && nHolding == 0) break;\n            if ((int)ops.size() > 95000) break;\n            if (elapsed_ms() > deadline_ms) break;\n            \n            vector<Cand> cands;\n            cands.reserve(N*N);\n            for (int rrx = 0; rrx < N; rrx++)\n            for (int rry = 0; rry < N; rry++) {\n                int P, maxRot;\n                planFull(rrx, rry, P, maxRot, tdir_buf);\n                if (P == 0) continue;\n                int move = abs(rrx-rx) + abs(rry-ry);\n                int T = max(move, maxRot);\n                if (T == 0) T = 1;\n                double score = (double)P / T;\n                cands.push_back({score, (uint32_t)rng(), rrx, rry, P, T, tdir_buf});\n            }\n            \n            if (cands.empty()) break;\n            \n            sort(cands.begin(), cands.end(), [](const Cand& a, const Cand& b) {\n                if (abs(a.score - b.score) > 1e-9) return a.score > b.score;\n                if (a.P != b.P) return a.P > b.P;\n                if (a.T != b.T) return a.T < b.T;\n                return a.tiebreak < b.tiebreak;\n            });\n            \n            int K = min(K_lookahead, (int)cands.size());\n            int bestIdx = 0;\n            \n            if (K > 1) {\n                double bestCombined = -1;\n                for (int ci = 0; ci < K; ci++) {\n                    Cand& c = cands[ci];\n                    auto save_has = has_;\n                    auto save_fhold = fhold;\n                    auto save_fdir = fdir;\n                    int save_rx = rx, save_ry = ry;\n                    \n                    applyPlanToState(c.rrx, c.rry, c.tdir);\n                    \n                    int bestP2 = 0, bestT2 = 1;\n                    double bestS2 = 0;\n                    for (int r2x = 0; r2x < N; r2x++)\n                    for (int r2y = 0; r2y < N; r2y++) {\n                        int P2, maxRot2;\n                        planScore(r2x, r2y, P2, maxRot2);\n                        if (P2 == 0) continue;\n                        int move2 = abs(r2x-rx) + abs(r2y-ry);\n                        int T2 = max(move2, maxRot2);\n                        if (T2 == 0) T2 = 1;\n                        double s2 = (double)P2 / T2;\n                        if (s2 > bestS2) { bestS2 = s2; bestP2 = P2; bestT2 = T2; }\n                    }\n                    \n                    double combined = (double)(c.P + bestP2) / (c.T + bestT2);\n                    \n                    has_ = save_has;\n                    fhold = save_fhold;\n                    fdir = save_fdir;\n                    rx = save_rx; ry = save_ry;\n                    \n                    if (combined > bestCombined) {\n                        bestCombined = combined;\n                        bestIdx = ci;\n                    }\n                }\n            }\n            \n            Cand& chosen = cands[bestIdx];\n            int bestRx = chosen.rrx, bestRy = chosen.rry;\n            vector<int>& bestTargetDir = chosen.tdir;\n            \n            int mv_dx = bestRx - rx, mv_dy = bestRy - ry;\n            vector<char> mvSeq;\n            for (int i = 0; i < abs(mv_dx); i++) mvSeq.push_back(mv_dx>0?'D':'U');\n            for (int i = 0; i < abs(mv_dy); i++) mvSeq.push_back(mv_dy>0?'R':'L');\n            \n            vector<vector<char>> rotSeq(nFingers);\n            int maxRotLen = 0;\n            for (int fi = 0; fi < nFingers; fi++) {\n                if (bestTargetDir[fi] == -1) continue;\n                int diff = (bestTargetDir[fi] - fdir[fi] + 4) % 4;\n                if (diff == 1) rotSeq[fi].push_back('R');\n                else if (diff == 2) { rotSeq[fi].push_back('R'); rotSeq[fi].push_back('R'); }\n                else if (diff == 3) rotSeq[fi].push_back('L');\n                maxRotLen = max(maxRotLen, (int)rotSeq[fi].size());\n            }\n            \n            int turns = max((int)mvSeq.size(), maxRotLen);\n            if (turns == 0) turns = 1;\n            \n            for (int t = 0; t < turns; t++) {\n                char mc = t < (int)mvSeq.size() ? mvSeq[t] : 0;\n                vector<char> rc(nFingers, 0);\n                for (int fi = 0; fi < nFingers; fi++)\n                    if (t < (int)rotSeq[fi].size()) rc[fi] = rotSeq[fi][t];\n                \n                int next_rx = rx + (mc == 'D' ? 1 : mc == 'U' ? -1 : 0);\n                int next_ry = ry + (mc == 'R' ? 1 : mc == 'L' ? -1 : 0);\n                for (int fi = 0; fi < nFingers; fi++) {\n                    if (rc[fi]) continue;\n                    if (bestTargetDir[fi] != -1) continue;\n                    int heurD = bestHeuristicDir(next_rx, next_ry, fi);\n                    int diff = (heurD - fdir[fi] + 4) % 4;\n                    if (diff == 1) rc[fi] = 'R';\n                    else if (diff == 3) rc[fi] = 'L';\n                    else if (diff == 2) rc[fi] = 'R';\n                }\n                \n                doTurn(mc, rc);\n            }\n        }\n        \n        int remaining = 0;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (has_[i][j] && !isTarget[i][j]) remaining++;\n        }\n        int finalScore = (int)ops.size();\n        if (remaining > 0) finalScore += 100000 + 1000 * remaining;\n        \n        return make_pair(ops, finalScore);\n    };\n    \n    long long sumX = 0, sumY = 0, cnt = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (init_has[i][j] || isTarget[i][j]) {\n            sumX += i; sumY += j; cnt++;\n        }\n    }\n    int com_x = cnt > 0 ? (int)(sumX / cnt) : N/2;\n    int com_y = cnt > 0 ? (int)(sumY / cnt) : N/2;\n    com_x = max(0, min(N-1, com_x));\n    com_y = max(0, min(N-1, com_y));\n    \n    long long TL = 2700;\n    vector<string> bestOps;\n    int bestScore = INT_MAX;\n    int bestStartRx = com_x, bestStartRy = com_y;\n    \n    // Step 1: fast greedy baseline\n    {\n        auto r = solve(com_x, com_y, 1, TL - 500, 1);\n        if (r.second < bestScore) {\n            bestOps = r.first;\n            bestScore = r.second;\n        }\n    }\n    \n    // Step 2: main lookahead run\n    if (TL - elapsed_ms() > 800) {\n        auto r = solve(com_x, com_y, 5, TL - 300, 42);\n        if (r.second < 100000 && r.second < bestScore) {\n            bestOps = r.first;\n            bestScore = r.second;\n        }\n    }\n    \n    // Step 3+: additional random runs\n    if (bestScore < 100000) {\n        vector<pair<pair<int,int>, uint32_t>> alt_runs = {\n            {{N/2, N/2}, 123},\n            {{com_x, com_y}, 456},\n            {{0, 0}, 789},\n            {{N-1, N-1}, 1011},\n        };\n        \n        for (auto& alt : alt_runs) {\n            int sx = alt.first.first;\n            int sy = alt.first.second;\n            uint32_t seed = alt.second;\n            long long rem = TL - elapsed_ms();\n            if (rem < 500) break;\n            \n            auto r = solve(sx, sy, 5, TL - 200, seed);\n            if (r.second < 100000 && r.second < bestScore) {\n                bestOps = r.first;\n                bestScore = r.second;\n                bestStartRx = sx;\n                bestStartRy = sy;\n            }\n        }\n    }\n    \n    cout << Vp << \"\\n\";\n    for (int i = 0; i < nFingers; i++) cout << 0 << \" \" << L[i] << \"\\n\";\n    cout << bestStartRx << \" \" << bestStartRy << \"\\n\";\n    for (auto& o : bestOps) cout << o << \"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\n\nint N;\nvector<int> X, Y;\n\nauto g_startTime = chrono::steady_clock::now();\nlong long elapsedMs(){ return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-g_startTime).count(); }\n\nstruct Result {\n    vector<pair<int,int>> poly;\n    long long score;\n    long long perim;\n    bool valid;\n};\n\nResult checkResult(vector<pair<int,int>> poly, long long score){\n    Result r;\n    r.poly = poly;\n    r.score = score;\n    long long perim=0;\n    int n=poly.size();\n    for(int i=0;i<n;i++){\n        auto& a=poly[i]; auto& b=poly[(i+1)%n];\n        perim += abs(a.first-b.first)+abs(a.second-b.second);\n    }\n    r.perim = perim;\n    set<pair<int,int>> seen;\n    bool distinct=true;\n    for(auto& p:poly){ if(seen.count(p)){distinct=false;break;} seen.insert(p); }\n    r.valid = distinct && perim<=400000 && n<=1000 && n>=4;\n    return r;\n}\n\nvector<pair<int,int>> traceOutline(vector<vector<char>>& in, int W, int H, int cw, int ch){\n    int sx=-1, sy=-1;\n    for(int r=0; r<H && sx<0; r++){\n        for(int c=0; c<W; c++){\n            if(in[c][r]){ sx=c; sy=r; break; }\n        }\n    }\n    if(sx<0) return {};\n    \n    auto isIn = [&](int c, int r)->bool{\n        if(c<0||c>=W||r<0||r>=H) return false;\n        return (bool)in[c][r];\n    };\n    \n    vector<pair<int,int>> corners;\n    int x = sx, y = sy, dir = 0;\n    corners.push_back({x, y});\n    \n    int maxSteps = 8*W*H + 100;\n    for(int step=0; step<maxSteps; step++){\n        if(dir==0) x++;\n        else if(dir==1) y++;\n        else if(dir==2) x--;\n        else y--;\n        \n        if(x == sx && y == sy) break;\n        \n        bool nw = isIn(x-1, y-1);\n        bool ne = isIn(x, y-1);\n        bool sw = isIn(x-1, y);\n        bool se = isIn(x, y);\n        \n        int nextDir;\n        if(dir == 0){\n            if(!se) nextDir = 1;\n            else if(!ne) nextDir = 0;\n            else nextDir = 3;\n        } else if(dir == 1){\n            if(!sw) nextDir = 2;\n            else if(!se) nextDir = 1;\n            else nextDir = 0;\n        } else if(dir == 2){\n            if(!nw) nextDir = 3;\n            else if(!sw) nextDir = 2;\n            else nextDir = 1;\n        } else {\n            if(!ne) nextDir = 0;\n            else if(!nw) nextDir = 3;\n            else nextDir = 2;\n        }\n        \n        if(nextDir != dir){\n            corners.push_back({x, y});\n            dir = nextDir;\n        }\n    }\n    \n    if(corners.size() < 4) return {};\n    \n    vector<pair<int,int>> poly;\n    for(auto& p : corners){\n        poly.push_back({p.first*cw, p.second*ch});\n    }\n    return poly;\n}\n\nbool isSimplyConnected(vector<vector<char>>& in, int W, int H, int totalIn){\n    if(totalIn<=0) return false;\n    int startC=-1, startR=-1;\n    for(int c=0;c<W && startC<0;c++) for(int r=0;r<H;r++) if(in[c][r]){ startC=c; startR=r; break;}\n    \n    static int tag = 0;\n    static vector<vector<int>> vis;\n    static vector<vector<int>> vis2;\n    static int bW=-1, bH=-1;\n    if(bW != W || bH != H){\n        vis.assign(W, vector<int>(H, 0));\n        vis2.assign(W+2, vector<int>(H+2, 0));\n        bW = W; bH = H;\n        tag = 0;\n    }\n    tag += 2;\n    int tagA = tag, tagB = tag+1;\n    \n    vector<pair<int,int>> stk;\n    stk.reserve(W*H);\n    stk.push_back({startC, startR}); vis[startC][startR]=tagA;\n    int cnt=0;\n    int dx[]={1,-1,0,0}, dy[]={0,0,1,-1};\n    while(!stk.empty()){\n        auto [c,r] = stk.back(); stk.pop_back(); cnt++;\n        for(int d=0;d<4;d++){\n            int nc=c+dx[d], nr=r+dy[d];\n            if(nc<0||nc>=W||nr<0||nr>=H) continue;\n            if(!in[nc][nr]||vis[nc][nr]==tagA) continue;\n            vis[nc][nr]=tagA; stk.push_back({nc,nr});\n        }\n    }\n    if(cnt != totalIn) return false;\n    \n    int W2=W+2, H2=H+2;\n    stk.clear();\n    stk.push_back({0,0}); vis2[0][0]=tagB;\n    int expectedOut = (W*H - totalIn) + (2*W2 + 2*H2 - 4);\n    int reachedOut=0;\n    while(!stk.empty()){\n        auto [c,r] = stk.back(); stk.pop_back(); reachedOut++;\n        for(int d=0;d<4;d++){\n            int nc=c+dx[d], nr=r+dy[d];\n            if(nc<0||nc>=W2||nr<0||nr>=H2) continue;\n            if(vis2[nc][nr]==tagB) continue;\n            if(nc>=1 && nc<=W && nr>=1 && nr<=H && in[nc-1][nr-1]) continue;\n            vis2[nc][nr]=tagB; stk.push_back({nc,nr});\n        }\n    }\n    return reachedOut == expectedOut;\n}\n\nResult cellLocalSearch(vector<vector<char>> in, vector<vector<int>>& grid, int W, int H, int cw, int ch, int maxFlips, bool do2cell, long long deadline){\n    int dx[]={1,-1,0,0}, dy[]={0,0,1,-1};\n    int totalIn = 0;\n    for(int c=0;c<W;c++) for(int r=0;r<H;r++) if(in[c][r]) totalIn++;\n    \n    if(!isSimplyConnected(in, W, H, totalIn)){\n        Result r; r.valid=false; r.score=LLONG_MIN; return r;\n    }\n    \n    auto buildResult = [&]()->Result{\n        auto poly = traceOutline(in, W, H, cw, ch);\n        long long s = 0;\n        for(int c=0;c<W;c++) for(int r=0;r<H;r++) if(in[c][r]) s += grid[c][r];\n        if(poly.empty()){ Result r; r.valid=false; r.score=LLONG_MIN; return r; }\n        return checkResult(poly, s);\n    };\n    \n    Result best = buildResult();\n    if(!best.valid) return best;\n    \n    int flipsDone = 0;\n    \n    auto isBoundary = [&](int c, int r){\n        bool cur = in[c][r];\n        for(int d=0;d<4;d++){\n            int nc=c+dx[d], nr=r+dy[d];\n            if(nc<0||nc>=W||nr<0||nr>=H){ if(cur) return true; continue; }\n            if((bool)in[nc][nr] != cur) return true;\n        }\n        return false;\n    };\n    \n    for(int megaPass=0; megaPass<2 && flipsDone<maxFlips && elapsedMs()<deadline; megaPass++){\n        bool megaAny = false;\n        \n        for(int pass=0; pass<15 && flipsDone<maxFlips && elapsedMs()<deadline; pass++){\n            bool any=false;\n            for(int c=0;c<W && flipsDone<maxFlips && elapsedMs()<deadline;c++){\n                for(int r=0;r<H && flipsDone<maxFlips;r++){\n                    int delta = in[c][r] ? -grid[c][r] : grid[c][r];\n                    if(delta <= 0) continue;\n                    if(!isBoundary(c,r)) continue;\n                    \n                    bool cur = in[c][r];\n                    in[c][r] = 1 - cur;\n                    int newTotal = cur ? totalIn-1 : totalIn+1;\n                    flipsDone++;\n                    if(!isSimplyConnected(in, W, H, newTotal)){\n                        in[c][r] = cur;\n                        continue;\n                    }\n                    Result cand = buildResult();\n                    if(cand.valid && cand.score > best.score){\n                        best = cand;\n                        totalIn = newTotal;\n                        any = true;\n                    } else {\n                        in[c][r] = cur;\n                    }\n                }\n            }\n            if(!any) break;\n            megaAny = true;\n        }\n        \n        if(do2cell && flipsDone<maxFlips && elapsedMs()<deadline){\n            for(int pass=0; pass<2 && flipsDone<maxFlips && elapsedMs()<deadline; pass++){\n                bool any=false;\n                for(int c=0;c<W && flipsDone<maxFlips && elapsedMs()<deadline;c++){\n                    for(int r=0;r<H && flipsDone<maxFlips;r++){\n                        if(!isBoundary(c,r)) continue;\n                        \n                        for(int d=0;d<4;d++){\n                            int nc=c+dx[d], nr=r+dy[d];\n                            if(nc<0||nc>=W||nr<0||nr>=H) continue;\n                            \n                            int delta = (in[c][r] ? -grid[c][r] : grid[c][r])\n                                      + (in[nc][nr] ? -grid[nc][nr] : grid[nc][nr]);\n                            if(delta <= 0) continue;\n                            \n                            bool sc = in[c][r], snc = in[nc][nr];\n                            in[c][r] = 1 - sc;\n                            in[nc][nr] = 1 - snc;\n                            int newTotal = totalIn + (sc ? -1 : 1) + (snc ? -1 : 1);\n                            flipsDone++;\n                            \n                            if(newTotal <= 0 || !isSimplyConnected(in, W, H, newTotal)){\n                                in[c][r] = sc; in[nc][nr] = snc;\n                                continue;\n                            }\n                            Result cand = buildResult();\n                            if(cand.valid && cand.score > best.score){\n                                best = cand;\n                                totalIn = newTotal;\n                                any = true;\n                                break;\n                            } else {\n                                in[c][r] = sc; in[nc][nr] = snc;\n                            }\n                        }\n                    }\n                }\n                if(!any) break;\n                megaAny = true;\n            }\n        }\n        \n        if(!megaAny) break;\n    }\n    \n    return best;\n}\n\nResult bestRectangle(int W, int H){\n    int cw = 100000/W, ch = 100000/H;\n    vector<vector<int>> grid(W, vector<int>(H,0));\n    for(int i=0;i<2*N;i++){\n        int c = min(W-1, X[i]/cw);\n        int rr = min(H-1, Y[i]/ch);\n        grid[c][rr] += (i<N) ? 1 : -1;\n    }\n    long long best = LLONG_MIN;\n    int bC1=0, bC2=0, bR1=0, bR2=0;\n    for(int r1=0;r1<H;r1++){\n        vector<int> colSum(W, 0);\n        for(int r2=r1;r2<H;r2++){\n            for(int c=0;c<W;c++) colSum[c] += grid[c][r2];\n            long long cs=0, bestSum=LLONG_MIN;\n            int curL=0, bL=0, bR=0;\n            for(int c=0;c<W;c++){\n                if(cs<=0){ cs=colSum[c]; curL=c; } else cs+=colSum[c];\n                if(cs>bestSum){ bestSum=cs; bL=curL; bR=c; }\n            }\n            if(bestSum>best){\n                best=bestSum; bC1=bL; bC2=bR; bR1=r1; bR2=r2;\n            }\n        }\n    }\n    int x1=bC1*cw, x2=(bC2+1)*cw, y1=bR1*ch, y2=(bR2+1)*ch;\n    vector<pair<int,int>> poly = {{x1,y1},{x2,y1},{x2,y2},{x1,y2}};\n    return checkResult(poly, best);\n}\n\nResult solveDirColGeneric(int W_orig, int H_orig, bool swapXY, int xoff, int yoff){\n    int cw = 100000/W_orig, ch = 100000/H_orig;\n    int W = (xoff > 0) ? W_orig - 1 : W_orig;\n    int H = (yoff > 0) ? H_orig - 1 : H_orig;\n    if(W <= 0 || H <= 0){ Result r; r.valid=false; r.score=LLONG_MIN; return r; }\n    \n    vector<vector<int>> grid(W, vector<int>(H,0));\n    for(int i=0;i<2*N;i++){\n        int xx = swapXY ? Y[i] : X[i];\n        int yy = swapXY ? X[i] : Y[i];\n        int ddx = xx - xoff;\n        int ddy = yy - yoff;\n        if(ddx<0 || ddx >= W*cw || ddy<0 || ddy >= H*ch) continue;\n        int c = ddx/cw;\n        int rr = ddy/ch;\n        grid[c][rr] += (i<N) ? 1 : -1;\n    }\n    \n    vector<int> lo(W), hi(W), val(W);\n    for(int c=0;c<W;c++){\n        int bestSum = INT_MIN, bestL=0, bestR=-1;\n        int curSum=0, curL=0;\n        for(int rr=0;rr<H;rr++){\n            if(curSum <= 0){ curSum = grid[c][rr]; curL = rr; }\n            else curSum += grid[c][rr];\n            if(curSum > bestSum){ bestSum = curSum; bestL=curL; bestR=rr; }\n        }\n        lo[c]=bestL; hi[c]=bestR; val[c]=bestSum;\n    }\n    \n    int totBest=INT_MIN, cL=0, cR=0, csu=0, cSL=0;\n    for(int c=0;c<W;c++){\n        if(csu<=0){ csu=val[c]; cSL=c; } else csu+=val[c];\n        if(csu>totBest){ totBest=csu; cL=cSL; cR=c; }\n    }\n    \n    for(int c=cL+1;c<=cR;c++){\n        if(hi[c] < lo[c-1]) hi[c] = lo[c-1];\n        if(lo[c] > hi[c-1]) lo[c] = hi[c-1];\n    }\n    \n    auto buildPoly = [&](int a, int b)->vector<pair<int,int>>{\n        vector<pair<int,int>> poly;\n        poly.push_back({a*cw + xoff, lo[a]*ch + yoff});\n        for(int c=a;c<=b;c++){\n            int yb = lo[c]*ch + yoff;\n            if(c>a && lo[c]!=lo[c-1]){\n                poly.push_back({c*cw + xoff, yb});\n            }\n            poly.push_back({(c+1)*cw + xoff, yb});\n        }\n        poly.push_back({(b+1)*cw + xoff, (hi[b]+1)*ch + yoff});\n        for(int c=b;c>=a;c--){\n            int yt = (hi[c]+1)*ch + yoff;\n            if(c<b && hi[c]!=hi[c+1]){\n                poly.push_back({(c+1)*cw + xoff, yt});\n            }\n            poly.push_back({c*cw + xoff, yt});\n        }\n        vector<pair<int,int>> cleanPoly;\n        for(auto& p : poly){\n            if(cleanPoly.empty() || cleanPoly.back()!=p) cleanPoly.push_back(p);\n        }\n        while(cleanPoly.size()>1 && cleanPoly.front()==cleanPoly.back()) cleanPoly.pop_back();\n        return cleanPoly;\n    };\n    \n    auto makeResult = [&](int a, int b)->Result{\n        auto poly = buildPoly(a, b);\n        long long s = 0;\n        for(int c=a;c<=b;c++) for(int r=lo[c]; r<=hi[c]; r++) s+=grid[c][r];\n        if(swapXY) for(auto& p:poly) swap(p.first,p.second);\n        return checkResult(poly, s);\n    };\n    \n    int a=cL, b=cR;\n    Result r = makeResult(a,b);\n    while(!r.valid && a<b){\n        if(val[a] < val[b]) a++;\n        else b--;\n        r = makeResult(a,b);\n    }\n    \n    if(!r.valid) return r;\n    \n    Result bestR = r;\n    \n    vector<vector<int>> pref(W, vector<int>(H+1, 0));\n    for(int c=0;c<W;c++){\n        for(int rr=0; rr<H; rr++) pref[c][rr+1] = pref[c][rr] + grid[c][rr];\n    }\n    \n    auto runLocal = [&](int a, int b){\n        for(int iter=0; iter<10; iter++){\n            bool any=false;\n            for(int c=a; c<=b; c++){\n                int maxLo = hi[c];\n                if(c>a) maxLo = min(maxLo, hi[c-1]);\n                if(c<b) maxLo = min(maxLo, hi[c+1]);\n                if(maxLo>=0){\n                    int nbL = lo[c], nbP = pref[c][lo[c]];\n                    for(int nlo=0; nlo<=maxLo; nlo++){\n                        if(pref[c][nlo] < nbP){ nbP = pref[c][nlo]; nbL = nlo; }\n                    }\n                    if(nbL != lo[c]){ lo[c] = nbL; any = true; }\n                }\n                int minHi = lo[c];\n                if(c>a) minHi = max(minHi, lo[c-1]);\n                if(c<b) minHi = max(minHi, lo[c+1]);\n                if(minHi<H){\n                    int nbH = hi[c], nbP = pref[c][hi[c]+1];\n                    for(int nhi=minHi; nhi<H; nhi++){\n                        if(pref[c][nhi+1] > nbP){ nbP = pref[c][nhi+1]; nbH = nhi; }\n                    }\n                    if(nbH != hi[c]){ hi[c] = nbH; any = true; }\n                }\n            }\n            if(!any) break;\n        }\n    };\n    \n    runLocal(a, b);\n    {\n        Result rc = makeResult(a,b);\n        if(rc.valid && rc.score > bestR.score) bestR = rc;\n    }\n    \n    for(int round=0; round<10; round++){\n        bool anyExt = false;\n        if(a > 0){\n            int na = a-1;\n            int tlo = lo[na], thi = hi[na];\n            if(thi < lo[a]) thi = lo[a];\n            if(tlo > hi[a]) tlo = hi[a];\n            int savLo = lo[na], savHi = hi[na];\n            lo[na] = tlo; hi[na] = thi;\n            Result rT = makeResult(a-1, b);\n            if(rT.valid && rT.score > bestR.score){\n                bestR = rT; a = a-1; anyExt = true;\n                runLocal(a,b);\n                Result rc = makeResult(a,b);\n                if(rc.valid && rc.score > bestR.score) bestR = rc;\n            } else {\n                lo[na] = savLo; hi[na] = savHi;\n            }\n        }\n        if(b < W-1){\n            int nb = b+1;\n            int tlo = lo[nb], thi = hi[nb];\n            if(thi < lo[b]) thi = lo[b];\n            if(tlo > hi[b]) tlo = hi[b];\n            int savLo = lo[nb], savHi = hi[nb];\n            lo[nb] = tlo; hi[nb] = thi;\n            Result rT = makeResult(a, b+1);\n            if(rT.valid && rT.score > bestR.score){\n                bestR = rT; b = b+1; anyExt = true;\n                runLocal(a,b);\n                Result rc = makeResult(a,b);\n                if(rc.valid && rc.score > bestR.score) bestR = rc;\n            } else {\n                lo[nb] = savLo; hi[nb] = savHi;\n            }\n        }\n        if(!anyExt) break;\n    }\n    \n    return bestR;\n}\n\nvector<vector<char>> rasterizePoly(vector<pair<int,int>>& poly, int W, int H){\n    int cw = 100000/W, ch = 100000/H;\n    vector<vector<char>> in(W, vector<char>(H, 0));\n    int n = poly.size();\n    for(int c=0;c<W;c++){\n        for(int r=0;r<H;r++){\n            int cx = c*cw + cw/2, cy = r*ch + ch/2;\n            int crossings = 0;\n            for(int i=0;i<n;i++){\n                int x1=poly[i].first, y1=poly[i].second;\n                int x2=poly[(i+1)%n].first, y2=poly[(i+1)%n].second;\n                if(x1==x2){\n                    if(x1 > cx){\n                        int ymin=min(y1,y2), ymax=max(y1,y2);\n                        if(ymin<=cy && cy<ymax) crossings++;\n                    }\n                }\n            }\n            if(crossings&1) in[c][r] = 1;\n        }\n    }\n    return in;\n}\n\nint main(){\n    g_startTime = chrono::steady_clock::now();\n    \n    scanf(\"%d\", &N);\n    X.resize(2*N); Y.resize(2*N);\n    for(int i=0;i<2*N;i++) scanf(\"%d %d\",&X[i],&Y[i]);\n    \n    Result best;\n    best.valid = false;\n    best.score = LLONG_MIN;\n    \n    for(int res : {50, 100, 200}){\n        if(100000%res != 0) continue;\n        if(elapsedMs() > 1400) break;\n        Result r = bestRectangle(res, res);\n        if(r.valid && r.score > best.score) best = r;\n    }\n    \n    vector<pair<int,int>> configs;\n    for(int w : {20,25,40,50,80,100,125,160,200,250}){\n        for(int h : {20,25,40,50,80,100,125,160,200,250,500}){\n            if(100000%w==0 && 100000%h==0) configs.push_back({w,h});\n        }\n    }\n    for(auto& cfg : configs){\n        int W = cfg.first, H = cfg.second;\n        if(elapsedMs() > 1100) break;\n        for(int dir=0; dir<2; dir++){\n            if(elapsedMs() > 1100) break;\n            Result r = solveDirColGeneric(W,H,dir==1,0,0);\n            if(r.valid && r.score > best.score) best = r;\n        }\n    }\n    \n    // Offset configs (limited set: cw/2 only)\n    vector<pair<int,int>> offsetCfgs = {{50,50},{80,80},{100,100},{125,125},{200,200}};\n    for(auto& cfg : offsetCfgs){\n        int W = cfg.first, H = cfg.second;\n        if(elapsedMs() > 1400) break;\n        if(100000%W != 0 || 100000%H != 0) continue;\n        int cw = 100000/W, ch = 100000/H;\n        vector<pair<int,int>> offsets = {{cw/2, 0}, {0, ch/2}, {cw/2, ch/2}};\n        for(auto& off : offsets){\n            if(elapsedMs() > 1400) break;\n            int xo = off.first, yo = off.second;\n            for(int dir=0; dir<2; dir++){\n                if(elapsedMs() > 1400) break;\n                Result r = solveDirColGeneric(W, H, dir==1, xo, yo);\n                if(r.valid && r.score > best.score) best = r;\n            }\n        }\n    }\n    \n    // Cyclic cell LS\n    long long csDeadline = 1800;\n    for(int round=0; round<3; round++){\n        if(elapsedMs() >= csDeadline) break;\n        bool improved = false;\n        for(int MW : {100, 200, 400}){\n            if(100000%MW != 0) continue;\n            if(elapsedMs() >= csDeadline) break;\n            if(!best.valid) break;\n            int MH = MW;\n            int cw = 100000/MW, ch = 100000/MH;\n            vector<vector<int>> grid(MW, vector<int>(MH,0));\n            for(int i=0;i<2*N;i++){\n                int c = min(MW-1, X[i]/cw);\n                int rr = min(MH-1, Y[i]/ch);\n                grid[c][rr] += (i<N) ? 1 : -1;\n            }\n            auto in = rasterizePoly(best.poly, MW, MH);\n            bool do2 = (MW == 100 && round == 0);\n            int maxF = (MW == 100) ? 1500 : (MW == 200 ? 800 : 300);\n            long long perCallBudget = (MW == 400) ? 200 : 150;\n            long long localDeadline = min(csDeadline, elapsedMs() + perCallBudget);\n            Result rc = cellLocalSearch(in, grid, MW, MH, cw, ch, maxF, do2, localDeadline);\n            if(rc.valid && rc.score > best.score){\n                best = rc;\n                improved = true;\n            }\n        }\n        if(!improved) break;\n    }\n    \n    if(!best.valid || best.poly.empty()){\n        best.poly = {{0,0},{1,0},{1,1},{0,1}};\n    }\n    \n    printf(\"%d\\n\",(int)best.poly.size());\n    for(auto& p : best.poly) printf(\"%d %d\\n\", p.first, p.second);\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, sigma;\nvector<int> W_, H_;\nmt19937 rng(42);\n\nstruct Rect { long long x1,y1,x2,y2; };\n\npair<long long,long long> simulate(const vector<tuple<int,int,char,int>>& ops, const vector<int>& ww, const vector<int>& hh) {\n    static vector<Rect> placed;\n    static vector<char> has;\n    if ((int)placed.size() < N) { placed.resize(N); has.resize(N); }\n    for (int i = 0; i < N; i++) has[i] = 0;\n    long long maxX=0, maxY=0;\n    for (auto& [p, r, d, b] : ops) {\n        long long w = r==0 ? ww[p] : hh[p];\n        long long h = r==0 ? hh[p] : ww[p];\n        if (d == 'U') {\n            long long x1 = (b == -1) ? 0 : placed[b].x2;\n            long long x2 = x1 + w;\n            long long y1 = 0;\n            for (int j = 0; j < N; j++) {\n                if (!has[j]) continue;\n                auto& rc = placed[j];\n                if (rc.x2 <= x1 || rc.x1 >= x2) continue;\n                if (rc.y2 > y1) y1 = rc.y2;\n            }\n            long long y2 = y1 + h;\n            placed[p] = {x1,y1,x2,y2};\n            has[p] = 1;\n            if (x2>maxX) maxX=x2; if (y2>maxY) maxY=y2;\n        } else {\n            long long y1 = (b == -1) ? 0 : placed[b].y2;\n            long long y2 = y1 + h;\n            long long x1 = 0;\n            for (int j = 0; j < N; j++) {\n                if (!has[j]) continue;\n                auto& rc = placed[j];\n                if (rc.y2 <= y1 || rc.y1 >= y2) continue;\n                if (rc.x2 > x1) x1 = rc.x2;\n            }\n            long long x2 = x1 + w;\n            placed[p] = {x1,y1,x2,y2};\n            has[p] = 1;\n            if (x2>maxX) maxX=x2; if (y2>maxY) maxY=y2;\n        }\n    }\n    return {maxX, maxY};\n}\n\nvector<tuple<int,int,char,int>> buildRowLayout(long long targetW, const vector<int>& ww, const vector<int>& hh, const vector<int>& rots) {\n    vector<tuple<int,int,char,int>> ops;\n    long long shelfX = 0;\n    int firstOfShelf = -1;\n    int prevOnShelf = -1;\n    for (int i = 0; i < N; i++) {\n        int rot = rots[i];\n        long long w = rot==0 ? ww[i] : hh[i];\n        if (firstOfShelf == -1) {\n            ops.push_back({i, rot, 'U', -1});\n            firstOfShelf = i; prevOnShelf = i; shelfX = w;\n        } else if (shelfX + w <= targetW) {\n            ops.push_back({i, rot, 'U', prevOnShelf});\n            prevOnShelf = i; shelfX += w;\n        } else {\n            ops.push_back({i, rot, 'L', firstOfShelf});\n            firstOfShelf = i; prevOnShelf = i; shelfX = w;\n        }\n    }\n    return ops;\n}\n\nstruct Choice { double sc; int b; char d; long long x1, y1; };\n\nvector<tuple<int,int,char,int>> buildGreedy(const vector<int>& ww, const vector<int>& hh, const vector<int>& rots, double weightW, double weightH, int randTopK = 1) {\n    vector<tuple<int,int,char,int>> ops;\n    vector<Rect> placed(N);\n    vector<char> has(N, 0);\n    long long maxX = 0, maxY = 0;\n    vector<Choice> choices;\n    choices.reserve(2*N);\n    for (int i = 0; i < N; i++) {\n        int rot = rots[i];\n        long long w = rot==0 ? ww[i] : hh[i];\n        long long h = rot==0 ? hh[i] : ww[i];\n        choices.clear();\n        for (int di = 0; di < 2; di++) {\n            char d = di == 0 ? 'U' : 'L';\n            for (int b = -1; b < i; b++) {\n                if (b >= 0 && !has[b]) continue;\n                long long x1, y1;\n                if (d == 'U') {\n                    x1 = (b == -1) ? 0 : placed[b].x2;\n                    long long x2 = x1 + w;\n                    y1 = 0;\n                    for (int j = 0; j < i; j++) {\n                        if (!has[j]) continue;\n                        auto& rc = placed[j];\n                        if (rc.x2 <= x1 || rc.x1 >= x2) continue;\n                        if (rc.y2 > y1) y1 = rc.y2;\n                    }\n                } else {\n                    y1 = (b == -1) ? 0 : placed[b].y2;\n                    long long y2t = y1 + h;\n                    x1 = 0;\n                    for (int j = 0; j < i; j++) {\n                        if (!has[j]) continue;\n                        auto& rc = placed[j];\n                        if (rc.y2 <= y1 || rc.y1 >= y2t) continue;\n                        if (rc.x2 > x1) x1 = rc.x2;\n                    }\n                }\n                long long x2 = x1 + w, y2 = y1 + h;\n                long long newMaxX = max(maxX, x2);\n                long long newMaxY = max(maxY, y2);\n                double sc = weightW * (double)newMaxX + weightH * (double)newMaxY;\n                choices.push_back({sc, b, d, x1, y1});\n            }\n        }\n        int pick = 0;\n        if (randTopK > 1 && (int)choices.size() > 1) {\n            int k = min(randTopK, (int)choices.size());\n            partial_sort(choices.begin(), choices.begin()+k, choices.end(),\n                [](const Choice& a, const Choice& b){ return a.sc < b.sc; });\n            pick = rng() % k;\n        } else {\n            int minI = 0;\n            for (int j = 1; j < (int)choices.size(); j++) {\n                if (choices[j].sc < choices[minI].sc) minI = j;\n            }\n            pick = minI;\n        }\n        auto& c = choices[pick];\n        placed[i] = {c.x1, c.y1, c.x1 + w, c.y1 + h};\n        has[i] = 1;\n        if (placed[i].x2 > maxX) maxX = placed[i].x2;\n        if (placed[i].y2 > maxY) maxY = placed[i].y2;\n        ops.push_back({i, rot, c.d, c.b});\n    }\n    return ops;\n}\n\nuint64_t hashOps(const vector<tuple<int,int,char,int>>& ops) {\n    uint64_t h = 1469598103934665603ULL;\n    for (auto& [p,r,d,b] : ops) {\n        h ^= (uint64_t)p; h *= 1099511628211ULL;\n        h ^= (uint64_t)r; h *= 1099511628211ULL;\n        h ^= (uint64_t)d; h *= 1099511628211ULL;\n        h ^= (uint64_t)(b+2); h *= 1099511628211ULL;\n    }\n    return h;\n}\n\nlong long simScore(const vector<tuple<int,int,char,int>>& ops) {\n    auto [w, h] = simulate(ops, W_, H_);\n    return w + h;\n}\n\nlong long hillClimb1(vector<tuple<int,int,char,int>>& ops, int maxPasses) {\n    long long curScore = simScore(ops);\n    int n = ops.size();\n    for (int pass = 0; pass < maxPasses; pass++) {\n        bool improved = false;\n        for (int i = 0; i < n; i++) {\n            get<1>(ops[i]) ^= 1;\n            long long newSc = simScore(ops);\n            if (newSc < curScore) {\n                curScore = newSc;\n                improved = true;\n            } else {\n                get<1>(ops[i]) ^= 1;\n            }\n        }\n        if (!improved) break;\n    }\n    return curScore;\n}\n\nint main() {\n    cin >> N >> T >> sigma;\n    W_.resize(N); H_.resize(N);\n    for (int i = 0; i < N; i++) cin >> W_[i] >> H_[i];\n    \n    long long totalArea = 0;\n    for (int i = 0; i < N; i++) totalArea += (long long)W_[i] * H_[i];\n    long long sideEst = (long long)sqrt((double)totalArea);\n    \n    using Cand = tuple<long long, uint64_t, vector<tuple<int,int,char,int>>>;\n    priority_queue<Cand> topK;\n    unordered_set<uint64_t> inQueue;\n    int maxK = max(T * 3 + 50, 200);\n    \n    auto tryOps = [&](vector<tuple<int,int,char,int>>& ops) {\n        uint64_t hh = hashOps(ops);\n        if (inQueue.count(hh)) return;\n        auto [w,h] = simulate(ops, W_, H_);\n        long long sc = w+h;\n        if ((int)topK.size() < maxK) {\n            topK.push({sc, hh, ops});\n            inQueue.insert(hh);\n        } else if (sc < get<0>(topK.top())) {\n            auto oldHash = get<1>(topK.top());\n            inQueue.erase(oldHash);\n            topK.pop();\n            topK.push({sc, hh, ops});\n            inQueue.insert(hh);\n        }\n    };\n    \n    for (double f = 0.5; f <= 2.0; f += 0.05) {\n        long long tw = (long long)(sideEst * f);\n        for (int mode = 0; mode < 3; mode++) {\n            vector<int> r(N);\n            for (int i = 0; i < N; i++) {\n                if (mode == 0) r[i] = 0;\n                else if (mode == 1) r[i] = (W_[i] > H_[i]) ? 1 : 0;\n                else r[i] = (W_[i] < H_[i]) ? 1 : 0;\n            }\n            auto ops = buildRowLayout(tw, W_, H_, r);\n            tryOps(ops);\n        }\n    }\n    \n    for (int mode = 0; mode < 3; mode++) {\n        vector<int> r(N);\n        for (int i = 0; i < N; i++) {\n            if (mode == 0) r[i] = 0;\n            else if (mode == 1) r[i] = (W_[i] > H_[i]) ? 1 : 0;\n            else r[i] = (W_[i] < H_[i]) ? 1 : 0;\n        }\n        for (double wRatio : {0.3, 0.5, 0.75, 1.0, 1.5, 2.0, 3.0}) {\n            auto ops = buildGreedy(W_, H_, r, wRatio, 1.0, 1);\n            tryOps(ops);\n        }\n    }\n    \n    auto startTime = chrono::steady_clock::now();\n    auto elapsed = [&]() {\n        return chrono::duration<double>(chrono::steady_clock::now() - startTime).count();\n    };\n    \n    double searchTime = 2.3;\n    while (elapsed() < searchTime) {\n        int strat = rng() % 10;\n        vector<int> r(N);\n        if (strat < 5) {\n            for (int i = 0; i < N; i++) r[i] = rng()%2;\n            double f = 0.5 + (rng()%150)/100.0;\n            long long tw = (long long)(sideEst * f);\n            auto ops = buildRowLayout(tw, W_, H_, r);\n            tryOps(ops);\n        } else {\n            int rmode = rng() % 3;\n            for (int i = 0; i < N; i++) {\n                if (rmode == 0) r[i] = rng()%2;\n                else if (rmode == 1) r[i] = (W_[i] > H_[i]) ? 1 : 0;\n                else r[i] = (W_[i] < H_[i]) ? 1 : 0;\n                if (rmode != 0 && (rng()%8 == 0)) r[i] ^= 1;\n            }\n            double wW = 0.3 + (rng()%270)/100.0;\n            double wH = 0.3 + (rng()%270)/100.0;\n            int randTopK = 1;\n            int rr = rng() % 6;\n            if (rr == 0) randTopK = 2;\n            else if (rr == 1) randTopK = 3;\n            auto ops = buildGreedy(W_, H_, r, wW, wH, randTopK);\n            tryOps(ops);\n        }\n    }\n    \n    vector<pair<long long, vector<tuple<int,int,char,int>>>> cands;\n    while (!topK.empty()) {\n        auto& top = topK.top();\n        cands.push_back({get<0>(top), get<2>(top)});\n        topK.pop();\n    }\n    sort(cands.begin(), cands.end(), [](const auto& a, const auto& b){ return a.first < b.first; });\n    \n    double lsDeadline = 2.6;\n    int topToRefine = min((int)cands.size(), 8);\n    for (int i = 0; i < topToRefine; i++) {\n        if (elapsed() > lsDeadline) break;\n        long long newSc = hillClimb1(cands[i].second, 3);\n        cands[i].first = newSc;\n    }\n    sort(cands.begin(), cands.end(), [](const auto& a, const auto& b){ return a.first < b.first; });\n    \n    long long bestEst = cands[0].first;\n    long long noiseScale = (long long)(sqrt((double)N) * (double)sigma * 3.0);\n    long long threshold = bestEst + noiseScale;\n    \n    vector<int> selIdx;\n    for (int i = 0; i < (int)cands.size() && (int)selIdx.size() < T; i++) {\n        if (cands[i].first <= threshold) selIdx.push_back(i);\n        else break;\n    }\n    if (selIdx.empty()) selIdx.push_back(0);\n    \n    for (int t = 0; t < T; t++) {\n        int idx = (t < (int)selIdx.size()) ? selIdx[t] : selIdx[0];\n        auto& ops = cands[idx].second;\n        cout << ops.size() << \"\\n\";\n        for (auto& [p,r,d,b] : ops) cout << p << \" \" << r << \" \" << d << \" \" << b << \"\\n\";\n        cout.flush();\n        long long wm, hm; cin >> wm >> hm;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, H;\nvector<int> A;\nvector<vector<int>> adj;\nvector<int> par, dep;\nvector<vector<int>> ch;\n\nvoid buildChildren() {\n    ch.assign(N, {});\n    for (int i = 0; i < N; i++) if (par[i] != -1) ch[par[i]].push_back(i);\n}\n\nvoid recomputeDepths() {\n    queue<int> q;\n    for (int i = 0; i < N; i++) {\n        if (par[i] == -1) { dep[i] = 0; q.push(i); }\n    }\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (int c : ch[u]) { dep[c] = dep[u]+1; q.push(c); }\n    }\n}\n\nlong long computeScore() {\n    long long s = 0;\n    for (int i = 0; i < N; i++) s += (long long)(dep[i]+1) * A[i];\n    return s;\n}\n\nmt19937 rng(12345);\nvector<char> inSub;\nvector<int> sSumA, sMaxDep, mxDepExcl;\nvector<int> stk_;\nvector<int> orderBuf;\nvector<int> subBuf;\n\nbool doPass() {\n    bool improved = false;\n    shuffle(orderBuf.begin(), orderBuf.end(), rng);\n    \n    for (int v : orderBuf) {\n        subBuf.clear();\n        subBuf.push_back(v);\n        inSub[v] = 1;\n        for (int i = 0; i < (int)subBuf.size(); i++) {\n            int u = subBuf[i];\n            for (int c : ch[u]) {\n                subBuf.push_back(c);\n                inSub[c] = 1;\n            }\n        }\n        \n        for (int i = (int)subBuf.size() - 1; i >= 0; i--) {\n            int u = subBuf[i];\n            sSumA[u] = A[u];\n            sMaxDep[u] = dep[u];\n            for (int c : ch[u]) {\n                sSumA[u] += sSumA[c];\n                if (sMaxDep[c] > sMaxDep[u]) sMaxDep[u] = sMaxDep[c];\n            }\n        }\n        \n        for (int u : subBuf) {\n            int mx1 = INT_MIN, mx2 = INT_MIN, mx1Child = -1;\n            for (int c : ch[u]) {\n                if (sMaxDep[c] > mx1) { mx2 = mx1; mx1 = sMaxDep[c]; mx1Child = c; }\n                else if (sMaxDep[c] > mx2) { mx2 = sMaxDep[c]; }\n            }\n            for (int c : ch[u]) {\n                int baseExcl = (u == v) ? dep[v] : mxDepExcl[u];\n                int x = baseExcl;\n                if (dep[u] > x) x = dep[u];\n                int otherChMax = (c == mx1Child) ? mx2 : mx1;\n                if (otherChMax != INT_MIN && otherChMax > x) x = otherChMax;\n                mxDepExcl[c] = x;\n            }\n        }\n        \n        long long bestNet = 0;\n        int bestP = par[v];\n        int bestDetach = -1;\n        int curDep = dep[v];\n        int oldP = par[v];\n        long long sumA = sSumA[v];\n        int relMaxD = sMaxDep[v] - dep[v];\n        \n        for (int u : adj[v]) {\n            if (u == oldP) continue;\n            if (inSub[u]) continue;\n            int newDep = dep[u] + 1;\n            if (newDep + relMaxD > H) continue;\n            int delta = newDep - curDep;\n            long long change = (long long)delta * sumA;\n            if (change > bestNet) { bestNet = change; bestP = u; bestDetach = -1; }\n        }\n        \n        for (int d : subBuf) {\n            if (d == v) continue;\n            long long loss = (long long)dep[d] * sSumA[d];\n            long long newSumA = sumA - sSumA[d];\n            int newRelMax = mxDepExcl[d] - dep[v];\n            if (newRelMax < 0) newRelMax = 0;\n            \n            for (int u : adj[v]) {\n                if (u == oldP) continue;\n                if (inSub[u]) continue;\n                int newDep = dep[u] + 1;\n                if (newDep + newRelMax > H) continue;\n                int delta = newDep - curDep;\n                long long change = (long long)delta * newSumA;\n                long long net = change - loss;\n                if (net > bestNet) { bestNet = net; bestP = u; bestDetach = d; }\n            }\n        }\n        \n        for (int u : subBuf) inSub[u] = 0;\n        \n        if (bestNet > 0) {\n            if (bestDetach != -1) {\n                int d = bestDetach;\n                int dPar = par[d];\n                auto& vec = ch[dPar];\n                auto it = find(vec.begin(), vec.end(), d);\n                if (it != vec.end()) vec.erase(it);\n                par[d] = -1;\n                int dShift = -dep[d];\n                stk_.clear(); stk_.push_back(d);\n                while (!stk_.empty()) {\n                    int u = stk_.back(); stk_.pop_back();\n                    dep[u] += dShift;\n                    for (int c : ch[u]) stk_.push_back(c);\n                }\n            }\n            \n            int oldP2 = par[v];\n            par[v] = bestP;\n            int newDep = (bestP == -1 ? 0 : dep[bestP] + 1);\n            int delta = newDep - curDep;\n            if (oldP2 != -1) {\n                auto& vec = ch[oldP2];\n                auto it = find(vec.begin(), vec.end(), v);\n                if (it != vec.end()) vec.erase(it);\n            }\n            if (bestP != -1) ch[bestP].push_back(v);\n            stk_.clear(); stk_.push_back(v);\n            while (!stk_.empty()) {\n                int u = stk_.back(); stk_.pop_back();\n                dep[u] += delta;\n                for (int c : ch[u]) stk_.push_back(c);\n            }\n            improved = true;\n        }\n    }\n    return improved;\n}\n\nvoid perturbRandom(int K) {\n    for (int t = 0; t < K; t++) {\n        int v = (int)(rng() % N);\n        if (par[v] != -1) {\n            auto& vec = ch[par[v]];\n            auto it = find(vec.begin(), vec.end(), v);\n            if (it != vec.end()) vec.erase(it);\n            par[v] = -1;\n        }\n    }\n}\n\nvoid perturbResetTree() {\n    int v = (int)(rng() % N);\n    int root = v;\n    while (par[root] != -1) root = par[root];\n    stk_.clear(); stk_.push_back(root);\n    vector<int> treeV;\n    while (!stk_.empty()) {\n        int u = stk_.back(); stk_.pop_back();\n        treeV.push_back(u);\n        for (int c : ch[u]) stk_.push_back(c);\n    }\n    for (int u : treeV) {\n        if (par[u] != -1) {\n            auto& vec = ch[par[u]];\n            auto it = find(vec.begin(), vec.end(), u);\n            if (it != vec.end()) vec.erase(it);\n            par[u] = -1;\n        }\n    }\n}\n\nvoid fullRestart() {\n    par.assign(N, -1);\n    buildChildren();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    cin >> N >> M >> H;\n    A.resize(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    adj.assign(N, {});\n    for (int i = 0; i < M; i++) {\n        int u, v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    vector<int> xs(N), ys(N);\n    for (int i = 0; i < N; i++) cin >> xs[i] >> ys[i];\n    \n    par.assign(N, -1);\n    dep.assign(N, 0);\n    buildChildren();\n    inSub.assign(N, 0);\n    sSumA.assign(N, 0);\n    sMaxDep.assign(N, 0);\n    mxDepExcl.assign(N, 0);\n    orderBuf.resize(N);\n    iota(orderBuf.begin(), orderBuf.end(), 0);\n    \n    auto startTime = chrono::steady_clock::now();\n    auto timeMs = [&]() -> long long {\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - startTime).count();\n    };\n    \n    long long bestScore = computeScore();\n    vector<int> bestPar = par;\n    \n    while (timeMs() < 500 && doPass()) {}\n    {\n        long long sc = computeScore();\n        if (sc > bestScore) { bestScore = sc; bestPar = par; }\n    }\n    \n    int stuckCount = 0;\n    while (timeMs() < 1850) {\n        // Escalating perturbation\n        if (stuckCount >= 12) {\n            fullRestart();\n            stuckCount = 0;\n        } else if (stuckCount >= 7) {\n            // Reset a few trees\n            int resets = 2 + (int)(rng() % 3);\n            for (int r = 0; r < resets; r++) perturbResetTree();\n        } else if (stuckCount >= 4) {\n            // Bigger random\n            int K = 100 + (int)(rng() % 200);\n            perturbRandom(K);\n        } else {\n            // Small random\n            int K = 20 + (int)(rng() % 80);\n            perturbRandom(K);\n        }\n        recomputeDepths();\n        \n        while (timeMs() < 1850 && doPass()) {}\n        long long sc2 = computeScore();\n        if (sc2 > bestScore) {\n            bestScore = sc2;\n            bestPar = par;\n            stuckCount = 0;\n        } else {\n            stuckCount++;\n            par = bestPar;\n            buildChildren();\n            recomputeDepths();\n        }\n    }\n    \n    par = bestPar;\n    for (int i = 0; i < N; i++) cout << par[i] << \" \\n\"[i==N-1];\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nstruct State {\n    uint32_t oniRow[20], fukuRow[20];\n    uint32_t oniCol[20], fukuCol[20];\n};\nstruct Move { char d; int p; };\n\nint shiftOp(State& s, char d, int p) {\n    int rem = 0;\n    uint32_t mask = (1u << N) - 1;\n    uint32_t topBit = 1u << (N-1);\n    uint32_t clearP = ~(1u << p);\n    if (d == 'L') {\n        if (s.oniRow[p] & 1) rem = 1;\n        else if (s.fukuRow[p] & 1) rem = 2;\n        s.oniRow[p] >>= 1;\n        s.fukuRow[p] >>= 1;\n        for (int j = 0; j < N; j++) {\n            s.oniCol[j] = (s.oniCol[j] & clearP) | (((s.oniRow[p] >> j) & 1u) << p);\n            s.fukuCol[j] = (s.fukuCol[j] & clearP) | (((s.fukuRow[p] >> j) & 1u) << p);\n        }\n    } else if (d == 'R') {\n        if (s.oniRow[p] & topBit) rem = 1;\n        else if (s.fukuRow[p] & topBit) rem = 2;\n        s.oniRow[p] = (s.oniRow[p] << 1) & mask;\n        s.fukuRow[p] = (s.fukuRow[p] << 1) & mask;\n        for (int j = 0; j < N; j++) {\n            s.oniCol[j] = (s.oniCol[j] & clearP) | (((s.oniRow[p] >> j) & 1u) << p);\n            s.fukuCol[j] = (s.fukuCol[j] & clearP) | (((s.fukuRow[p] >> j) & 1u) << p);\n        }\n    } else if (d == 'U') {\n        if (s.oniCol[p] & 1) rem = 1;\n        else if (s.fukuCol[p] & 1) rem = 2;\n        s.oniCol[p] >>= 1;\n        s.fukuCol[p] >>= 1;\n        for (int i = 0; i < N; i++) {\n            s.oniRow[i] = (s.oniRow[i] & clearP) | (((s.oniCol[p] >> i) & 1u) << p);\n            s.fukuRow[i] = (s.fukuRow[i] & clearP) | (((s.fukuCol[p] >> i) & 1u) << p);\n        }\n    } else {\n        if (s.oniCol[p] & topBit) rem = 1;\n        else if (s.fukuCol[p] & topBit) rem = 2;\n        s.oniCol[p] = (s.oniCol[p] << 1) & mask;\n        s.fukuCol[p] = (s.fukuCol[p] << 1) & mask;\n        for (int i = 0; i < N; i++) {\n            s.oniRow[i] = (s.oniRow[i] & clearP) | (((s.oniCol[p] >> i) & 1u) << p);\n            s.fukuRow[i] = (s.fukuRow[i] & clearP) | (((s.fukuCol[p] >> i) & 1u) << p);\n        }\n    }\n    return rem;\n}\n\nint heuristic(const State& s) {\n    int leftF[20], rightF[20], topF[20], botF[20];\n    for (int i = 0; i < N; i++) {\n        leftF[i] = s.fukuRow[i] ? __builtin_ctz(s.fukuRow[i]) : N;\n        rightF[i] = s.fukuRow[i] ? 31 - __builtin_clz(s.fukuRow[i]) : -1;\n    }\n    for (int j = 0; j < N; j++) {\n        topF[j] = s.fukuCol[j] ? __builtin_ctz(s.fukuCol[j]) : N;\n        botF[j] = s.fukuCol[j] ? 31 - __builtin_clz(s.fukuCol[j]) : -1;\n    }\n    int h = 0;\n    for (int i = 0; i < N; i++) {\n        uint32_t o = s.oniRow[i];\n        while (o) {\n            int j = __builtin_ctz(o);\n            o &= o - 1;\n            int best = 100;\n            if (leftF[i] > j) best = min(best, j+1);\n            if (rightF[i] < j) best = min(best, N-j);\n            if (topF[j] > i) best = min(best, i+1);\n            if (botF[j] < i) best = min(best, N-i);\n            h += best;\n        }\n    }\n    return h;\n}\n\nint countOniRow(const uint32_t* oniRow) {\n    int c = 0;\n    for (int i = 0; i < N; i++) c += __builtin_popcount(oniRow[i]);\n    return c;\n}\n\nuint64_t hashRows(const uint32_t* oniRow, const uint32_t* fukuRow) {\n    uint64_t h = 0xcbf29ce484222325ULL;\n    for (int i = 0; i < N; i++) {\n        h ^= oniRow[i]; h *= 0x100000001b3ULL;\n        h ^= fukuRow[i]; h *= 0x100000001b3ULL;\n    }\n    return h;\n}\n\nstruct Node {\n    uint32_t oniRow[20], fukuRow[20];\n    int cost;\n    int h;\n    int parent;\n    int16_t p, k;\n    char d;\n};\n\nvector<Node> allNodes;\n\nvoid makeStateFromNode(State& s, const Node& n) {\n    memcpy(s.oniRow, n.oniRow, sizeof(s.oniRow));\n    memcpy(s.fukuRow, n.fukuRow, sizeof(s.fukuRow));\n    for (int j = 0; j < N; j++) { s.oniCol[j] = 0; s.fukuCol[j] = 0; }\n    for (int i = 0; i < N; i++) {\n        uint32_t o = s.oniRow[i], f = s.fukuRow[i];\n        while (o) { int j = __builtin_ctz(o); o &= o-1; s.oniCol[j] |= (1u << i); }\n        while (f) { int j = __builtin_ctz(f); f &= f-1; s.fukuCol[j] |= (1u << i); }\n    }\n}\n\nvector<Move> reconstructPath(int nodeId) {\n    vector<vector<Move>> segs;\n    while (allNodes[nodeId].parent != -1) {\n        Node& n = allNodes[nodeId];\n        vector<Move> seg;\n        for (int i = 0; i < n.k; i++) seg.push_back({n.d, (int)n.p});\n        segs.push_back(seg);\n        nodeId = n.parent;\n    }\n    reverse(segs.begin(), segs.end());\n    vector<Move> moves;\n    for (auto& s : segs) for (auto& m : s) moves.push_back(m);\n    return moves;\n}\n\nchrono::steady_clock::time_point g_start;\nint g_timeLimit;\n\nlong long elapsedMs() {\n    return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - g_start).count();\n}\n\nvector<Move> beamSearch(const State& s0_full, int W, double alpha, int costLimit, int maxNodes) {\n    allNodes.clear();\n    int totalOni = countOniRow(s0_full.oniRow);\n    if (totalOni == 0) return {};\n    vector<unordered_map<uint64_t, int>> bestIn(totalOni + 1);\n    Node root;\n    memcpy(root.oniRow, s0_full.oniRow, sizeof(root.oniRow));\n    memcpy(root.fukuRow, s0_full.fukuRow, sizeof(root.fukuRow));\n    root.cost = 0; root.h = heuristic(s0_full); root.parent = -1;\n    root.d = 0; root.p = 0; root.k = 0;\n    allNodes.push_back(root);\n    uint64_t rh = hashRows(root.oniRow, root.fukuRow);\n    bestIn[totalOni][rh] = 0;\n    int bestFinal = -1;\n    int currentBest = costLimit;\n    bool aborted = false;\n    for (int level = totalOni; level > 0 && !aborted; level--) {\n        if (elapsedMs() > g_timeLimit) break;\n        vector<int> src;\n        src.reserve(bestIn[level].size());\n        for (auto& kv : bestIn[level]) src.push_back(kv.second);\n        if (src.empty()) continue;\n        sort(src.begin(), src.end(), [&](int a, int b) {\n            double va = allNodes[a].cost + alpha * allNodes[a].h;\n            double vb = allNodes[b].cost + alpha * allNodes[b].h;\n            return va < vb;\n        });\n        if ((int)src.size() > W) src.resize(W);\n        bestIn[level].clear();\n        for (int sid : src) {\n            if (aborted) break;\n            int curCost = allNodes[sid].cost;\n            if (curCost >= currentBest) continue;\n            State curState;\n            makeStateFromNode(curState, allNodes[sid]);\n            for (char d : {'L','R','U','D'}) {\n                if (aborted) break;\n                for (int p = 0; p < N; p++) {\n                    State tmp = curState;\n                    int oniRem = 0;\n                    for (int k = 1; k <= N; k++) {\n                        int r = shiftOp(tmp, d, p);\n                        if (r == 2) break;\n                        if (r == 1) oniRem++;\n                        if (oniRem > 0) {\n                            int newCost = curCost + k;\n                            if (newCost >= currentBest) continue;\n                            int newLevel = level - oniRem;\n                            uint64_t hs = hashRows(tmp.oniRow, tmp.fukuRow);\n                            auto it = bestIn[newLevel].find(hs);\n                            if (it != bestIn[newLevel].end() && allNodes[it->second].cost <= newCost) continue;\n                            if ((int)allNodes.size() >= maxNodes) { aborted = true; break; }\n                            int hv = heuristic(tmp);\n                            Node child;\n                            memcpy(child.oniRow, tmp.oniRow, sizeof(child.oniRow));\n                            memcpy(child.fukuRow, tmp.fukuRow, sizeof(child.fukuRow));\n                            child.cost = newCost; child.h = hv;\n                            child.parent = sid; child.d = d; child.p = (int16_t)p; child.k = (int16_t)k;\n                            int nodeId = allNodes.size();\n                            allNodes.push_back(child);\n                            bestIn[newLevel][hs] = nodeId;\n                            if (newLevel == 0 && newCost < currentBest) {\n                                currentBest = newCost;\n                                bestFinal = nodeId;\n                            }\n                        }\n                    }\n                    if (aborted) break;\n                }\n            }\n        }\n    }\n    if (bestFinal == -1) return {};\n    return reconstructPath(bestFinal);\n}\n\nvector<Move> quickGreedy(State s, double alpha) {\n    vector<Move> moves;\n    int limit = 4*N*N;\n    while (countOniRow(s.oniRow) > 0) {\n        double bestSc = 1e18;\n        int bestK = 0;\n        char bestD = 0; int bestP = 0;\n        for (char d : {'L','R','U','D'}) {\n            for (int p = 0; p < N; p++) {\n                State tmp = s;\n                int oniRem = 0;\n                for (int k = 1; k <= N; k++) {\n                    int r = shiftOp(tmp, d, p);\n                    if (r == 2) break;\n                    if (r == 1) oniRem++;\n                    if (oniRem > 0) {\n                        int h = heuristic(tmp);\n                        double sc = k + alpha * h;\n                        if (sc < bestSc) {\n                            bestSc = sc; bestK = k;\n                            bestD = d; bestP = p;\n                        }\n                    }\n                }\n            }\n        }\n        if (bestK == 0) return {};\n        for (int i = 0; i < bestK; i++) {\n            shiftOp(s, bestD, bestP);\n            moves.push_back({bestD, bestP});\n            if ((int)moves.size() > limit) return {};\n        }\n    }\n    return moves;\n}\n\nvector<Move> hintSol(const vector<string>& b) {\n    vector<Move> moves;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (b[i][j]=='x') {\n        bool up=true, down=true, left=true, right=true;\n        for (int r = 0; r < i; r++) if (b[r][j]=='o') up=false;\n        for (int r = i+1; r < N; r++) if (b[r][j]=='o') down=false;\n        for (int c = 0; c < j; c++) if (b[i][c]=='o') left=false;\n        for (int c = j+1; c < N; c++) if (b[i][c]=='o') right=false;\n        int bestCost = INT_MAX; char bestDir='?';\n        if (up && 2*(i+1) < bestCost) { bestCost=2*(i+1); bestDir='U'; }\n        if (down && 2*(N-i) < bestCost) { bestCost=2*(N-i); bestDir='D'; }\n        if (left && 2*(j+1) < bestCost) { bestCost=2*(j+1); bestDir='L'; }\n        if (right && 2*(N-j) < bestCost) { bestCost=2*(N-j); bestDir='R'; }\n        int k = bestCost/2;\n        char revD = (bestDir=='U'?'D':bestDir=='D'?'U':bestDir=='L'?'R':'L');\n        int p = (bestDir=='U'||bestDir=='D')?j:i;\n        for (int t = 0; t < k; t++) moves.push_back({bestDir, p});\n        for (int t = 0; t < k; t++) moves.push_back({revD, p});\n    }\n    return moves;\n}\n\nbool checkValid(const State& s0, const vector<Move>& moves, const vector<bool>& active) {\n    State s = s0;\n    for (size_t j = 0; j < moves.size(); j++) {\n        if (!active[j]) continue;\n        int r = shiftOp(s, moves[j].d, moves[j].p);\n        if (r == 2) return false;\n    }\n    return countOniRow(s.oniRow) == 0;\n}\n\nvector<Move> dropReduce(const State& s0, vector<Move> moves) {\n    vector<bool> active(moves.size(), true);\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (size_t i = 0; i < moves.size(); i++) {\n            if (!active[i]) continue;\n            active[i] = false;\n            if (checkValid(s0, moves, active)) {\n                improved = true;\n            } else {\n                active[i] = true;\n            }\n        }\n    }\n    vector<Move> result;\n    for (size_t i = 0; i < moves.size(); i++) if (active[i]) result.push_back(moves[i]);\n    return result;\n}\n\nvector<Move> dropReducePairs(const State& s0, vector<Move> moves) {\n    vector<bool> active(moves.size(), true);\n    bool improved = true;\n    int iter = 0;\n    while (improved && iter < 100) {\n        improved = false;\n        iter++;\n        for (size_t i = 0; i < moves.size(); i++) {\n            if (!active[i]) continue;\n            for (size_t j = i+1; j < moves.size(); j++) {\n                if (!active[j]) continue;\n                active[i] = false;\n                active[j] = false;\n                if (checkValid(s0, moves, active)) {\n                    improved = true;\n                    break;\n                } else {\n                    active[i] = true;\n                    active[j] = true;\n                }\n            }\n            if (improved) break;\n        }\n    }\n    vector<Move> result;\n    for (size_t i = 0; i < moves.size(); i++) if (active[i]) result.push_back(moves[i]);\n    return result;\n}\n\nvector<Move> dropConsecutive(const State& s0, vector<Move> moves, int K) {\n    vector<bool> active(moves.size(), true);\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (size_t i = 0; i + K <= moves.size(); i++) {\n            bool allActive = true;\n            for (int kk = 0; kk < K; kk++) if (!active[i+kk]) { allActive = false; break; }\n            if (!allActive) continue;\n            for (int kk = 0; kk < K; kk++) active[i+kk] = false;\n            if (checkValid(s0, moves, active)) {\n                improved = true;\n            } else {\n                for (int kk = 0; kk < K; kk++) active[i+kk] = true;\n            }\n        }\n    }\n    vector<Move> result;\n    for (size_t i = 0; i < moves.size(); i++) if (active[i]) result.push_back(moves[i]);\n    return result;\n}\n\nvector<Move> postProcess(const State& s0, vector<Move> best) {\n    if (best.empty()) return best;\n    best = dropReduce(s0, best);\n    auto b2 = dropReducePairs(s0, best);\n    if (b2.size() < best.size()) best = b2;\n    best = dropReduce(s0, best);\n    best = dropConsecutive(s0, best, 3);\n    best = dropReduce(s0, best);\n    return best;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(0);\n    cin >> N;\n    vector<string> b(N);\n    for (int i = 0; i < N; i++) cin >> b[i];\n    State s0;\n    for (int i = 0; i < N; i++) { s0.oniRow[i] = s0.fukuRow[i] = s0.oniCol[i] = s0.fukuCol[i] = 0; }\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (b[i][j] == 'x') { s0.oniRow[i] |= (1u << j); s0.oniCol[j] |= (1u << i); }\n        else if (b[i][j] == 'o') { s0.fukuRow[i] |= (1u << j); s0.fukuCol[j] |= (1u << i); }\n    }\n    g_start = chrono::steady_clock::now();\n    g_timeLimit = 1100;\n    vector<Move> best = hintSol(b);\n    for (double a : {0.5, 1.0, 1.5, 2.0}) {\n        auto g = quickGreedy(s0, a);\n        if (!g.empty() && g.size() < best.size()) best = g;\n    }\n    int costLimit = best.size();\n    \n    struct P { int W; double alpha; int maxN; };\n    vector<P> paramsList = {\n        {30, 1.0, 150000}, {30, 0.5, 150000}, {30, 1.5, 150000},\n        {50, 1.0, 300000}, {50, 0.7, 300000}, {50, 1.3, 300000},\n        {30, 2.0, 150000}, {30, 0.3, 150000},\n        {100, 1.0, 600000}, {100, 0.7, 600000}, {100, 1.3, 600000},\n        {200, 1.0, 900000}\n    };\n    \n    for (auto& pr : paramsList) {\n        if (elapsedMs() > g_timeLimit) break;\n        auto m = beamSearch(s0, pr.W, pr.alpha, costLimit, pr.maxN);\n        if (!m.empty() && (int)m.size() < (int)best.size()) {\n            best = m;\n            costLimit = best.size();\n        }\n    }\n    \n    best = postProcess(s0, best);\n    costLimit = best.size();\n    \n    mt19937 rng(42);\n    double ilsAlphas[] = {1.0, 0.5, 1.5, 0.7, 1.3, 2.0};\n    int ilsWs[] = {30, 50, 70, 100};\n    int ilsIter = 0;\n    while (elapsedMs() < 1850) {\n        if (best.empty() || best.size() < 5) break;\n        int cut = rng() % (int)(best.size() - 1);\n        State s = s0;\n        bool valid = true;\n        for (int i = 0; i < cut; i++) {\n            if (shiftOp(s, best[i].d, best[i].p) == 2) { valid = false; break; }\n        }\n        if (!valid) { ilsIter++; continue; }\n        int remainingOni = countOniRow(s.oniRow);\n        if (remainingOni == 0) {\n            vector<Move> truncated(best.begin(), best.begin() + cut);\n            if (truncated.size() < best.size()) {\n                best = truncated;\n                costLimit = best.size();\n            }\n            ilsIter++;\n            continue;\n        }\n        int budget = (int)best.size() - cut;\n        g_timeLimit = (int)elapsedMs() + 70;\n        double alpha = ilsAlphas[ilsIter % 6];\n        int W = ilsWs[ilsIter % 4];\n        auto comp = beamSearch(s, W, alpha, budget, 40000);\n        if (!comp.empty()) {\n            vector<Move> combined(best.begin(), best.begin() + cut);\n            combined.insert(combined.end(), comp.begin(), comp.end());\n            combined = dropReduce(s0, combined);\n            if (combined.size() < best.size()) {\n                best = combined;\n                costLimit = best.size();\n            }\n        }\n        ilsIter++;\n    }\n    \n    if (elapsedMs() < 1950) {\n        best = dropReduce(s0, best);\n        if (elapsedMs() < 1970) {\n            auto b2 = dropReducePairs(s0, best);\n            if (b2.size() < best.size()) best = b2;\n            best = dropReduce(s0, best);\n        }\n    }\n    \n    for (auto& m : best) cout << m.d << \" \" << m.p << \"\\n\";\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, L;\nint Tg[128];\nint ab[256];\nint curC[128];\n\nlong long simError() {\n    int c[128] = {0};\n    int v[128] = {0};\n    int x = 0;\n    for (int w = 0; w < L; w++) {\n        c[x]++;\n        int p = v[x];\n        v[x] = p ^ 1;\n        x = ab[2*x + p];\n    }\n    for (int i = 0; i < N; i++) curC[i] = c[i];\n    long long e = 0;\n    for (int i = 0; i < N; i++) e += abs(c[i] - Tg[i]);\n    return e;\n}\n\nvoid greedyFromOrder(const vector<int>& ord) {\n    int filled[128] = {0};\n    filled[0] = 1;\n    for (int x : ord) {\n        int ca = (Tg[x] + 1) / 2;\n        int cb = Tg[x] / 2;\n        int besta = 0, bv = INT_MIN;\n        for (int i = 0; i < N; i++) {\n            int vv = Tg[i] - filled[i];\n            if (vv > bv) { bv = vv; besta = i; }\n        }\n        ab[2*x] = besta;\n        filled[besta] += ca;\n        int bestb = 0; bv = INT_MIN;\n        for (int i = 0; i < N; i++) {\n            int vv = Tg[i] - filled[i];\n            if (vv > bv) { bv = vv; bestb = i; }\n        }\n        ab[2*x+1] = bestb;\n        filled[bestb] += cb;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> L;\n    for (int i = 0; i < N; i++) cin >> Tg[i];\n    \n    mt19937 rng(12345);\n    auto start = chrono::steady_clock::now();\n    \n    long long bestInitE = LLONG_MAX;\n    int bestInitAB[256];\n    \n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    \n    sort(ord.begin(), ord.end(), [&](int x, int y){ return Tg[x] > Tg[y]; });\n    greedyFromOrder(ord);\n    long long e = simError();\n    bestInitE = e;\n    memcpy(bestInitAB, ab, sizeof(ab));\n    \n    for (int trial = 0; trial < 60; trial++) {\n        int kind = trial % 4;\n        if (kind == 3) {\n            shuffle(ord.begin(), ord.end(), rng);\n        } else {\n            int noiseLevel = (kind == 0) ? 500 : (kind == 1 ? 2000 : 5000);\n            vector<pair<int,int>> scored(N);\n            for (int i = 0; i < N; i++) {\n                int noise = (int)(rng() % (2*noiseLevel+1)) - noiseLevel;\n                scored[i] = {-(Tg[i] + noise), i};\n            }\n            sort(scored.begin(), scored.end());\n            for (int i = 0; i < N; i++) ord[i] = scored[i].second;\n        }\n        greedyFromOrder(ord);\n        e = simError();\n        if (e < bestInitE) {\n            bestInitE = e;\n            memcpy(bestInitAB, ab, sizeof(ab));\n        }\n    }\n    \n    memcpy(ab, bestInitAB, sizeof(ab));\n    long long bestE = simError();\n    long long curE = bestE;\n    int bestAB[256];\n    memcpy(bestAB, ab, sizeof(ab));\n    int savedC[128];\n    memcpy(savedC, curC, sizeof(curC));\n    \n    double TL = 1.80;\n    int stuck = 0;\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > TL) break;\n        \n        int mtype = rng() % 10;\n        int idx1 = -1, idx2 = -1, old1 = 0, old2 = 0;\n        bool valid = false;\n        \n        if (mtype < 9) {\n            int highNodes[128], lowNodes[128];\n            int highWeights[128], lowWeights[128];\n            int numHigh = 0, numLow = 0;\n            int totalHigh = 0, totalLow = 0;\n            for (int i = 0; i < N; i++) {\n                int ee = savedC[i] - Tg[i];\n                if (ee > 0) {\n                    highNodes[numHigh] = i;\n                    highWeights[numHigh] = ee;\n                    totalHigh += ee;\n                    numHigh++;\n                } else if (ee < 0) {\n                    lowNodes[numLow] = i;\n                    lowWeights[numLow] = -ee;\n                    totalLow += -ee;\n                    numLow++;\n                }\n            }\n            if (numHigh > 0 && numLow > 0) {\n                int rH = rng() % totalHigh;\n                int y = highNodes[0], yw = 0;\n                for (int k = 0; k < numHigh; k++) {\n                    rH -= highWeights[k];\n                    if (rH < 0) { y = highNodes[k]; yw = highWeights[k]; break; }\n                }\n                int rL = rng() % totalLow;\n                int w = lowNodes[0];\n                for (int k = 0; k < numLow; k++) {\n                    rL -= lowWeights[k];\n                    if (rL < 0) { w = lowNodes[k]; break; }\n                }\n                \n                int cands[256], nc = 0;\n                for (int j = 0; j < 2*N; j++) if (ab[j] == y) cands[nc++] = j;\n                if (nc > 0) {\n                    int choose_j;\n                    int sub = mtype % 3;\n                    if (sub == 0) {\n                        int best_diff = INT_MAX;\n                        choose_j = cands[0];\n                        for (int ci = 0; ci < nc; ci++) {\n                            int j = cands[ci];\n                            int flow = savedC[j/2] / 2;\n                            int diff = abs(flow - yw);\n                            if (diff < best_diff) { best_diff = diff; choose_j = j; }\n                        }\n                    } else {\n                        choose_j = cands[rng() % nc];\n                    }\n                    idx1 = choose_j;\n                    old1 = ab[idx1];\n                    if (old1 != w) {\n                        ab[idx1] = w;\n                        valid = true;\n                    }\n                }\n            }\n        }\n        \n        if (!valid) {\n            int mv = rng() % 3;\n            if (mv < 2) {\n                idx1 = rng() % (2*N);\n                int newv = rng() % N;\n                old1 = ab[idx1];\n                if (old1 != newv) {\n                    ab[idx1] = newv;\n                    valid = true;\n                }\n            } else {\n                int i = rng() % N;\n                if (ab[2*i] != ab[2*i+1]) {\n                    idx1 = 2*i; idx2 = 2*i+1;\n                    old1 = ab[idx1]; old2 = ab[idx2];\n                    ab[idx1] = old2; ab[idx2] = old1;\n                    valid = true;\n                }\n            }\n        }\n        \n        if (!valid) continue;\n        \n        long long ne = simError();\n        if (ne <= curE) {\n            curE = ne;\n            memcpy(savedC, curC, sizeof(curC));\n            if (ne < bestE) {\n                bestE = ne;\n                memcpy(bestAB, ab, sizeof(ab));\n            }\n            stuck = 0;\n        } else {\n            ab[idx1] = old1;\n            if (idx2 >= 0) ab[idx2] = old2;\n            stuck++;\n        }\n        \n        if (stuck > 400) {\n            memcpy(ab, bestAB, sizeof(ab));\n            int numPerturb = 3 + (rng() % 5);\n            for (int k = 0; k < numPerturb; k++) {\n                int j = rng() % (2*N);\n                ab[j] = rng() % N;\n            }\n            curE = simError();\n            memcpy(savedC, curC, sizeof(curC));\n            stuck = 0;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << bestAB[2*i] << \" \" << bestAB[2*i+1] << \"\\n\";\n    }\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\n#include <chrono>\nusing namespace std;\nusing namespace std::chrono;\n\nint N, M, Q, L, W;\nvector<int> Gs;\nvector<int> lx, rx, ly, ry;\nvector<double> cx, cy;\nint queries_used = 0;\nsteady_clock::time_point start_time;\n\ndouble elapsed() {\n    return duration<double>(steady_clock::now() - start_time).count();\n}\n\nvector<pair<int,int>> doQuery(vector<int> c) {\n    queries_used++;\n    cout << \"? \" << c.size();\n    for (int v : c) cout << \" \" << v;\n    cout << \"\\n\";\n    cout.flush();\n    vector<pair<int,int>> res(c.size()-1);\n    for (auto& p : res) cin >> p.first >> p.second;\n    return res;\n}\n\ndouble estDist(int i, int j) {\n    double dx = cx[i]-cx[j], dy = cy[i]-cy[j];\n    return sqrt(dx*dx+dy*dy);\n}\n\ndouble groupCost(vector<int>& grp) {\n    int g = grp.size();\n    if (g <= 1) return 0;\n    vector<tuple<double,int,int>> edges;\n    edges.reserve((size_t)g*(g-1)/2);\n    for (int i = 0; i < g; i++) for (int j = i+1; j < g; j++) {\n        edges.push_back({estDist(grp[i], grp[j]), i, j});\n    }\n    sort(edges.begin(), edges.end());\n    vector<int> par(g); iota(par.begin(), par.end(), 0);\n    function<int(int)> fnd = [&](int x){ return par[x]==x?x:par[x]=fnd(par[x]); };\n    double total = 0;\n    int cnt = 0;\n    for (auto& [d, i, j] : edges) {\n        int ri = fnd(i), rj = fnd(j);\n        if (ri != rj) { par[ri] = rj; total += d; cnt++; if (cnt == g-1) break; }\n    }\n    return total;\n}\n\nvector<pair<int,int>> buildMST(int g, vector<int>& grp, set<pair<int,int>>& edgeSet, set<pair<int,int>>& ruledOut) {\n    vector<tuple<double,int,int>> edges;\n    for (auto& p : edgeSet) {\n        if (ruledOut.count(p)) continue;\n        edges.push_back({estDist(p.first, p.second), p.first, p.second});\n    }\n    sort(edges.begin(), edges.end());\n    \n    unordered_map<int,int> idx;\n    idx.reserve(g*2);\n    for (int i = 0; i < g; i++) idx[grp[i]] = i;\n    vector<int> par(g); iota(par.begin(), par.end(), 0);\n    function<int(int)> fnd = [&](int x){ return par[x]==x?x:par[x]=fnd(par[x]); };\n    \n    vector<pair<int,int>> mst;\n    for (auto& [d,u,v] : edges) {\n        int a = idx[u], b = idx[v];\n        int ra = fnd(a), rb = fnd(b);\n        if (ra != rb) {\n            par[ra] = rb;\n            mst.push_back({u,v});\n        }\n    }\n    if ((int)mst.size() < g - 1) {\n        vector<tuple<double,int,int>> allPairs;\n        for (int i = 0; i < g; i++) for (int j = i+1; j < g; j++) {\n            int a = min(grp[i], grp[j]), b = max(grp[i], grp[j]);\n            if (ruledOut.count({a,b})) continue;\n            allPairs.push_back({estDist(grp[i], grp[j]), i, j});\n        }\n        sort(allPairs.begin(), allPairs.end());\n        for (auto& [d,a,b] : allPairs) {\n            int ra = fnd(a), rb = fnd(b);\n            if (ra != rb) {\n                par[ra] = rb;\n                mst.push_back({grp[a], grp[b]});\n            }\n        }\n    }\n    if ((int)mst.size() < g - 1) {\n        vector<tuple<double,int,int>> allPairs;\n        for (int i = 0; i < g; i++) for (int j = i+1; j < g; j++) {\n            allPairs.push_back({estDist(grp[i], grp[j]), i, j});\n        }\n        sort(allPairs.begin(), allPairs.end());\n        for (auto& [d,a,b] : allPairs) {\n            int ra = fnd(a), rb = fnd(b);\n            if (ra != rb) {\n                par[ra] = rb;\n                mst.push_back({grp[a], grp[b]});\n            }\n        }\n    }\n    return mst;\n}\n\nint main(){\n    start_time = steady_clock::now();\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M >> Q >> L >> W;\n    Gs.resize(M);\n    for (auto& g : Gs) cin >> g;\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i]+rx[i])/2.0;\n        cy[i] = (ly[i]+ry[i])/2.0;\n    }\n    \n    vector<int> assigned(N, -1);\n    vector<vector<int>> groups(M);\n    \n    auto runGrouping = [&](function<double(int)> seedScore) -> pair<vector<vector<int>>, vector<int>> {\n        vector<vector<int>> gr(M);\n        vector<int> asg(N, -1);\n        vector<int> gord(M);\n        iota(gord.begin(), gord.end(), 0);\n        sort(gord.begin(), gord.end(), [&](int a, int b){ return Gs[a] > Gs[b]; });\n        vector<double> minD(N);\n        for (int gi : gord) {\n            int sz = Gs[gi];\n            int seed = -1;\n            double bestv = 1e18;\n            for (int i = 0; i < N; i++) {\n                if (asg[i] != -1) continue;\n                double v = seedScore(i);\n                if (v < bestv) { bestv = v; seed = i; }\n            }\n            gr[gi].push_back(seed);\n            asg[seed] = gi;\n            fill(minD.begin(), minD.end(), 1e18);\n            for (int i = 0; i < N; i++) if (asg[i] == -1) minD[i] = estDist(seed, i);\n            while ((int)gr[gi].size() < sz) {\n                int best = -1; double bd = 1e18;\n                for (int i = 0; i < N; i++) {\n                    if (asg[i] != -1) continue;\n                    if (minD[i] < bd) { bd = minD[i]; best = i; }\n                }\n                gr[gi].push_back(best);\n                asg[best] = gi;\n                for (int i = 0; i < N; i++) {\n                    if (asg[i] == -1) {\n                        double d = estDist(best, i);\n                        if (d < minD[i]) minD[i] = d;\n                    }\n                }\n            }\n        }\n        return {gr, asg};\n    };\n    \n    auto evalGrouping = [&](vector<vector<int>>& gr) {\n        double total = 0;\n        for (auto& g : gr) total += groupCost(g);\n        return total;\n    };\n    \n    vector<function<double(int)>> strats;\n    strats.push_back([&](int i){ return cx[i] + cy[i]*0.0001; });\n    strats.push_back([&](int i){ return cy[i] + cx[i]*0.0001; });\n    strats.push_back([&](int i){ return -cx[i] + cy[i]*0.0001; });\n    strats.push_back([&](int i){ return -cy[i] + cx[i]*0.0001; });\n    strats.push_back([&](int i){ return cx[i] + cy[i]; });\n    strats.push_back([&](int i){ return cx[i] - cy[i]; });\n    strats.push_back([&](int i){ return -cx[i] - cy[i]; });\n    strats.push_back([&](int i){ return -cx[i] + cy[i]; });\n    \n    double bestTotal = 1e18;\n    for (auto& s : strats) {\n        if (elapsed() > 0.3) break;\n        auto [gr, asg] = runGrouping(s);\n        double t = evalGrouping(gr);\n        if (t < bestTotal) {\n            bestTotal = t;\n            groups = gr;\n            assigned = asg;\n        }\n    }\n    \n    // Grouping swap optimization\n    {\n        int K = min(25, N-1);\n        vector<vector<int>> knn(N);\n        for (int i = 0; i < N; i++) {\n            vector<pair<double,int>> dists;\n            dists.reserve(N-1);\n            for (int j = 0; j < N; j++) if (j != i) dists.push_back({estDist(i,j), j});\n            partial_sort(dists.begin(), dists.begin()+K, dists.end());\n            for (int k = 0; k < K; k++) knn[i].push_back(dists[k].second);\n        }\n        \n        int swapThresh = 50;\n        vector<double> gc(M, 0);\n        for (int gi = 0; gi < M; gi++) {\n            if ((int)groups[gi].size() <= swapThresh) gc[gi] = groupCost(groups[gi]);\n        }\n        \n        for (int iter = 0; iter < 10; iter++) {\n            if (elapsed() > 0.6) break;\n            bool improved = false;\n            for (int c = 0; c < N; c++) {\n                int gA = assigned[c];\n                if ((int)groups[gA].size() > swapThresh) continue;\n                for (int d : knn[c]) {\n                    int gB = assigned[d];\n                    if (gA == gB) continue;\n                    if ((int)groups[gB].size() > swapThresh) continue;\n                    \n                    auto& A = groups[gA]; auto& B = groups[gB];\n                    auto itA = find(A.begin(), A.end(), c);\n                    auto itB = find(B.begin(), B.end(), d);\n                    if (itA == A.end() || itB == B.end()) continue;\n                    *itA = d; *itB = c;\n                    double newA = groupCost(A), newB = groupCost(B);\n                    if (newA + newB < gc[gA] + gc[gB] - 0.001) {\n                        assigned[c] = gB; assigned[d] = gA;\n                        gc[gA] = newA; gc[gB] = newB;\n                        improved = true;\n                    } else {\n                        *itA = c; *itB = d;\n                    }\n                }\n            }\n            if (!improved) break;\n        }\n    }\n    \n    vector<set<pair<int,int>>> edgeSets(M);\n    vector<set<pair<int,int>>> ruledOut(M);\n    vector<set<pair<int,int>>> covered(M);\n    \n    auto processQueryResult = [&](int gi, vector<int>& q, vector<pair<int,int>>& es) {\n        set<pair<int,int>> mstHere;\n        for (auto& [a,b] : es) {\n            int x = min(a,b), y = max(a,b);\n            mstHere.insert({x,y});\n            if (!ruledOut[gi].count({x,y})) edgeSets[gi].insert({x,y});\n        }\n        for (int i = 0; i < (int)q.size(); i++) {\n            for (int j = i+1; j < (int)q.size(); j++) {\n                int a = min(q[i], q[j]), b = max(q[i], q[j]);\n                covered[gi].insert({a,b});\n                if (!mstHere.count({a,b})) {\n                    ruledOut[gi].insert({a,b});\n                    edgeSets[gi].erase({a,b});\n                }\n            }\n        }\n    };\n    \n    auto computeChain = [&](vector<int>& grp, int startIdx) -> pair<vector<int>, double> {\n        int g = grp.size();\n        vector<int> order;\n        vector<bool> used(g, false);\n        order.push_back(startIdx); used[startIdx] = true;\n        while ((int)order.size() < g) {\n            int last = order.back();\n            int best = -1; double bd = 1e18;\n            for (int i = 0; i < g; i++) {\n                if (used[i]) continue;\n                double d = estDist(grp[last], grp[i]);\n                if (d < bd) { bd = d; best = i; }\n            }\n            order.push_back(best); used[best] = true;\n        }\n        for (int iter = 0; iter < 5; iter++) {\n            bool imp = false;\n            for (int i = 0; i+1 < g; i++) {\n                for (int j = i+2; j < g; j++) {\n                    int a = order[i], b = order[i+1], cc = order[j];\n                    double oldC = estDist(grp[a], grp[b]);\n                    double newC = estDist(grp[a], grp[cc]);\n                    if (j+1 < g) {\n                        int dd = order[j+1];\n                        oldC += estDist(grp[cc], grp[dd]);\n                        newC += estDist(grp[b], grp[dd]);\n                    }\n                    if (newC < oldC - 1e-9) {\n                        reverse(order.begin()+i+1, order.begin()+j+1);\n                        imp = true;\n                    }\n                }\n            }\n            if (!imp) break;\n        }\n        double cost = 0;\n        for (int i = 0; i+1 < g; i++) cost += estDist(grp[order[i]], grp[order[i+1]]);\n        return {order, cost};\n    };\n    \n    // Phase 1: chain queries with multi-start + 2-opt\n    for (int gi = 0; gi < M; gi++) {\n        int g = Gs[gi];\n        vector<int>& grp = groups[gi];\n        if (g <= 2) continue;\n        \n        // Find starting points: extreme cities\n        vector<int> startCandidates;\n        if (g <= 4) {\n            startCandidates.push_back(0);\n        } else {\n            int lmost=0, rmost=0, tmost=0, bmost=0;\n            for (int i = 1; i < g; i++) {\n                if (cx[grp[i]] < cx[grp[lmost]]) lmost = i;\n                if (cx[grp[i]] > cx[grp[rmost]]) rmost = i;\n                if (cy[grp[i]] > cy[grp[tmost]]) tmost = i;\n                if (cy[grp[i]] < cy[grp[bmost]]) bmost = i;\n            }\n            startCandidates = {lmost, rmost, tmost, bmost};\n            sort(startCandidates.begin(), startCandidates.end());\n            startCandidates.erase(unique(startCandidates.begin(), startCandidates.end()), startCandidates.end());\n        }\n        \n        vector<int> bestOrder;\n        double bestChainCost = 1e18;\n        for (int s : startCandidates) {\n            auto [order, cost] = computeChain(grp, s);\n            if (cost < bestChainCost) {\n                bestChainCost = cost;\n                bestOrder = order;\n            }\n        }\n        \n        int chunk_sz = L;\n        int step = max(1, L - 1);\n        for (int st = 0; st < g; st += step) {\n            int en = min(st + chunk_sz, g);\n            if (en - st < 2) break;\n            if (queries_used >= Q) break;\n            vector<int> q;\n            for (int i = st; i < en; i++) q.push_back(grp[bestOrder[i]]);\n            auto es = doQuery(q);\n            processQueryResult(gi, q, es);\n            if (en == g) break;\n        }\n    }\n    \n    // Phase 2: component-aware edge-swap\n    {\n        vector<vector<pair<int,int>>> currentMST(M);\n        vector<bool> mstDirty(M, true);\n        vector<set<pair<int,int>>> triedEdges(M);\n        int resets = 0;\n        \n        while (queries_used < Q) {\n            int bestGi = -1;\n            double bestLen = -1;\n            pair<int,int> bestEdge = {-1,-1};\n            \n            for (int gi = 0; gi < M; gi++) {\n                if (Gs[gi] < 3) continue;\n                if (mstDirty[gi]) {\n                    currentMST[gi] = buildMST(Gs[gi], groups[gi], edgeSets[gi], ruledOut[gi]);\n                    mstDirty[gi] = false;\n                }\n                for (auto& [u,v] : currentMST[gi]) {\n                    int a = min(u,v), b = max(u,v);\n                    if (triedEdges[gi].count({a,b})) continue;\n                    double d = estDist(a,b);\n                    if (d > bestLen) {\n                        bestLen = d;\n                        bestGi = gi;\n                        bestEdge = {a,b};\n                    }\n                }\n            }\n            \n            if (bestGi == -1) {\n                if (resets >= 3) break;\n                resets++;\n                for (int gi = 0; gi < M; gi++) triedEdges[gi].clear();\n                continue;\n            }\n            \n            triedEdges[bestGi].insert(bestEdge);\n            \n            int eu = bestEdge.first, ev = bestEdge.second;\n            vector<int>& grp = groups[bestGi];\n            \n            unordered_map<int, vector<int>> adj;\n            for (auto& [u,v] : currentMST[bestGi]) {\n                if ((u == eu && v == ev) || (u == ev && v == eu)) continue;\n                adj[u].push_back(v);\n                adj[v].push_back(u);\n            }\n            set<int> compU;\n            {\n                queue<int> qq; qq.push(eu); compU.insert(eu);\n                while (!qq.empty()) {\n                    int x = qq.front(); qq.pop();\n                    for (int y : adj[x]) if (!compU.count(y)) { compU.insert(y); qq.push(y); }\n                }\n            }\n            \n            double mx = (cx[eu]+cx[ev])/2.0, my = (cy[eu]+cy[ev])/2.0;\n            vector<pair<double,int>> candU, candV;\n            for (int c : grp) {\n                if (c == eu || c == ev) continue;\n                double dx = cx[c]-mx, dy = cy[c]-my;\n                double d = sqrt(dx*dx+dy*dy);\n                if (compU.count(c)) candU.push_back({d, c});\n                else candV.push_back({d, c});\n            }\n            sort(candU.begin(), candU.end());\n            sort(candV.begin(), candV.end());\n            \n            int total = L - 2;\n            int tu = total / 2;\n            int tv = total - tu;\n            if ((int)candU.size() < tu) { tu = candU.size(); tv = min((int)candV.size(), total - tu); }\n            if ((int)candV.size() < tv) { tv = candV.size(); tu = min((int)candU.size(), total - tv); }\n            \n            vector<int> q = {eu, ev};\n            for (int i = 0; i < tu; i++) q.push_back(candU[i].second);\n            for (int i = 0; i < tv; i++) q.push_back(candV[i].second);\n            if ((int)q.size() < 2) continue;\n            \n            int beforeEdges = edgeSets[bestGi].size();\n            int beforeRuled = ruledOut[bestGi].size();\n            auto es = doQuery(q);\n            processQueryResult(bestGi, q, es);\n            if (edgeSets[bestGi].size() != (size_t)beforeEdges || ruledOut[bestGi].size() != (size_t)beforeRuled) {\n                mstDirty[bestGi] = true;\n            }\n        }\n    }\n    \n    // Phase 3: coverage-based queries\n    {\n        vector<tuple<double, int, int, int>> uncov;\n        for (int gi = 0; gi < M; gi++) {\n            int g = Gs[gi];\n            if (g <= L) continue;\n            vector<int>& grp = groups[gi];\n            for (int i = 0; i < g; i++) for (int j = i+1; j < g; j++) {\n                int a = min(grp[i], grp[j]), b = max(grp[i], grp[j]);\n                if (covered[gi].count({a,b}) || ruledOut[gi].count({a,b})) continue;\n                uncov.push_back({estDist(a, b), gi, a, b});\n            }\n        }\n        sort(uncov.begin(), uncov.end());\n        \n        for (auto& [d, gi, u, v] : uncov) {\n            if (queries_used >= Q) break;\n            if (covered[gi].count({u,v}) || ruledOut[gi].count({u,v})) continue;\n            vector<int>& grp = groups[gi];\n            double mx = (cx[u]+cx[v])/2.0, my = (cy[u]+cy[v])/2.0;\n            vector<pair<double,int>> cand;\n            for (int c : grp) {\n                if (c == u || c == v) continue;\n                double dx = cx[c]-mx, dy = cy[c]-my;\n                cand.push_back({sqrt(dx*dx+dy*dy), c});\n            }\n            sort(cand.begin(), cand.end());\n            vector<int> q = {u, v};\n            int take = min((int)cand.size(), L - 2);\n            for (int i = 0; i < take; i++) q.push_back(cand[i].second);\n            if ((int)q.size() < 2) continue;\n            auto es = doQuery(q);\n            processQueryResult(gi, q, es);\n        }\n    }\n    \n    vector<vector<pair<int,int>>> allEdges(M);\n    \n    for (int gi = 0; gi < M; gi++) {\n        int g = Gs[gi];\n        vector<int>& grp = groups[gi];\n        if (g == 1) continue;\n        if (g == 2) {\n            allEdges[gi].push_back({grp[0], grp[1]});\n            continue;\n        }\n        allEdges[gi] = buildMST(g, grp, edgeSets[gi], ruledOut[gi]);\n    }\n    \n    cout << \"!\\n\";\n    for (int gi = 0; gi < M; gi++) {\n        for (int i = 0; i < (int)groups[gi].size(); i++) {\n            cout << groups[gi][i];\n            if (i+1 < (int)groups[gi].size()) cout << \" \";\n        }\n        cout << \"\\n\";\n        for (auto& p : allEdges[gi]) cout << p.first << \" \" << p.second << \"\\n\";\n    }\n    cout.flush();\n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint di[4]={-1,1,0,0}, dj[4]={0,0,-1,1};\nchar dch[4]={'U','D','L','R'};\nvector<vector<bool>> blk;\n\npair<int,int> slideEnd(int i,int j,int d){\n    while(true){\n        int ni=i+di[d],nj=j+dj[d];\n        if(ni<0||ni>=N||nj<0||nj>=N||blk[ni][nj])break;\n        i=ni;j=nj;\n    }\n    return {i,j};\n}\n\nint main(){\n    cin>>N>>M;\n    vector<pair<int,int>> pts(M);\n    for(auto&p:pts)cin>>p.first>>p.second;\n    blk.assign(N,vector<bool>(N,false));\n    vector<string> out;\n    int ci=pts[0].first, cj=pts[0].second;\n    \n    for(int t=1;t<M;t++){\n        int ti=pts[t].first, tj=pts[t].second;\n        vector<vector<int>> dist(N,vector<int>(N,INT_MAX));\n        vector<vector<tuple<int,int,string>>> par(N,vector<tuple<int,int,string>>(N));\n        dist[ci][cj]=0;\n        queue<pair<int,int>> q;\n        q.push({ci,cj});\n        while(!q.empty()){\n            auto [i,j]=q.front();q.pop();\n            int c=dist[i][j];\n            for(int d=0;d<4;d++){\n                int ni=i+di[d],nj=j+dj[d];\n                if(ni>=0&&ni<N&&nj>=0&&nj<N&&!blk[ni][nj]){\n                    if(c+1<dist[ni][nj]){\n                        dist[ni][nj]=c+1;\n                        par[ni][nj]={i,j,string(\"M\")+dch[d]};\n                        q.push({ni,nj});\n                    }\n                }\n                auto [si,sj]=slideEnd(i,j,d);\n                if((si!=i||sj!=j)&&c+1<dist[si][sj]){\n                    dist[si][sj]=c+1;\n                    par[si][sj]={i,j,string(\"S\")+dch[d]};\n                    q.push({si,sj});\n                }\n            }\n        }\n        if(dist[ti][tj]==INT_MAX)break;\n        vector<string> acts;\n        int ii=ti,jj=tj;\n        while(ii!=ci||jj!=cj){\n            auto[pi,pj,a]=par[ii][jj];\n            acts.push_back(a);\n            ii=pi;jj=pj;\n        }\n        reverse(acts.begin(),acts.end());\n        for(auto&a:acts)out.push_back(a);\n        ci=ti;cj=tj;\n    }\n    for(auto&s:out)cout<<s[0]<<\" \"<<s[1]<<\"\\n\";\n}"}}}