{"model_name":"claude-4.6-opus-no-thinking","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    vector<int> x(n), y(n);\n    vector<long long> r(n);\n    for(int i=0;i<n;i++) cin >> x[i] >> y[i] >> r[i];\n    \n    // Rectangle: a,b,c,d where a<c, b<d\n    vector<int> a(n),b(n),c(n),d(n);\n    for(int i=0;i<n;i++){\n        a[i]=x[i]; b[i]=y[i]; c[i]=x[i]+1; d[i]=y[i]+1;\n    }\n    \n    auto intersects = [&](int i, int j) -> bool {\n        return a[i]<c[j] && a[j]<c[i] && b[i]<d[j] && b[j]<d[i];\n    };\n    \n    auto canExpand = [&](int i, int na, int nb, int nc, int nd) -> bool {\n        if(na<0||nb<0||nc>10000||nd>10000||na>=nc||nb>=nd) return false;\n        for(int j=0;j<n;j++){\n            if(j==i) continue;\n            if(na<c[j] && a[j]<nc && nb<d[j] && b[j]<nd) return false;\n        }\n        return true;\n    };\n    \n    auto area = [&](int i) -> long long {\n        return (long long)(c[i]-a[i])*(d[i]-b[i]);\n    };\n    \n    auto score = [&](int i) -> double {\n        long long s = area(i);\n        double ratio = min(r[i],s)*1.0/max(r[i],s);\n        return 1.0 - (1.0-ratio)*(1.0-ratio);\n    };\n    \n    // Greedy expansion with random direction attempts\n    mt19937 rng(42);\n    auto start = chrono::steady_clock::now();\n    \n    while(true){\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now-start).count();\n        if(elapsed > 4.5) break;\n        \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 i : order){\n            long long s = area(i);\n            if(s >= r[i]) continue;\n            double curScore = score(i);\n            \n            // Try 4 directions: expand left, right, up, down\n            int dirs[4][4];\n            // left: a-step\n            int step = max(1, (int)min((long long)100, (r[i]-s)/max(1LL,(long long)(d[i]-b[i]))));\n            dirs[0][0]=a[i]-step; dirs[0][1]=b[i]; dirs[0][2]=c[i]; dirs[0][3]=d[i];\n            dirs[1][0]=a[i]; dirs[1][1]=b[i]; dirs[1][2]=c[i]+step; dirs[1][3]=d[i];\n            dirs[2][0]=a[i]; dirs[2][1]=b[i]-step; dirs[2][2]=c[i]; dirs[2][3]=d[i];\n            dirs[3][0]=a[i]; dirs[3][1]=b[i]; dirs[3][2]=c[i]; dirs[3][3]=d[i]+step;\n            \n            int bestDir = -1; double bestScore = curScore;\n            for(int dd=0;dd<4;dd++){\n                if(canExpand(i, dirs[dd][0], dirs[dd][1], dirs[dd][2], dirs[dd][3])){\n                    long long ns = (long long)(dirs[dd][2]-dirs[dd][0])*(dirs[dd][3]-dirs[dd][1]);\n                    double rat = min(r[i],ns)*1.0/max(r[i],ns);\n                    double sc = 1.0-(1.0-rat)*(1.0-rat);\n                    if(sc > bestScore){ bestScore=sc; bestDir=dd; }\n                }\n            }\n            if(bestDir>=0){\n                a[i]=dirs[bestDir][0]; b[i]=dirs[bestDir][1];\n                c[i]=dirs[bestDir][2]; d[i]=dirs[bestDir][3];\n                improved=true;\n            }\n        }\n        if(!improved) break;\n    }\n    \n    for(int i=0;i<n;i++) cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int si,sj;\n    scanf(\"%d%d\",&si,&sj);\n    int t[50][50], p[50][50];\n    for(int i=0;i<50;i++) for(int j=0;j<50;j++) scanf(\"%d\",&t[i][j]);\n    for(int i=0;i<50;i++) for(int j=0;j<50;j++) scanf(\"%d\",&p[i][j]);\n    \n    int M=0;\n    for(int i=0;i<50;i++) for(int j=0;j<50;j++) M=max(M,t[i][j]+1);\n    \n    int dx[]={-1,1,0,0};\n    int dy[]={0,0,-1,1};\n    char dc[]={'U','D','L','R'};\n    \n    // Greedy beam search\n    struct State {\n        int x,y,score;\n        vector<bool> used; // tile used\n        string path;\n    };\n    \n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(1900);\n    \n    string bestPath;\n    int bestScore = 0;\n    \n    int beamWidth = 150;\n    \n    vector<State> beam(1);\n    beam[0].x=si; beam[0].y=sj; beam[0].score=p[si][sj];\n    beam[0].used.assign(M,false);\n    beam[0].used[t[si][sj]]=true;\n    beam[0].path=\"\";\n    \n    bestScore=beam[0].score; bestPath=\"\";\n    \n    for(int step=0; step<2500 && !beam.empty(); step++){\n        if(chrono::steady_clock::now()>deadline) break;\n        vector<State> next;\n        next.reserve(beam.size()*4);\n        for(auto &s: beam){\n            for(int d=0;d<4;d++){\n                int nx=s.x+dx[d], ny=s.y+dy[d];\n                if(nx<0||nx>=50||ny<0||ny>=50) continue;\n                int tid=t[nx][ny];\n                if(s.used[tid]) continue;\n                State ns;\n                ns.x=nx; ns.y=ny;\n                ns.score=s.score+p[nx][ny];\n                ns.used=s.used;\n                ns.used[tid]=true;\n                ns.path=s.path+dc[d];\n                next.push_back(move(ns));\n            }\n        }\n        if(next.empty()) break;\n        // Keep top beamWidth\n        if((int)next.size()>beamWidth){\n            partial_sort(next.begin(), next.begin()+beamWidth, next.end(),\n                [](const State&a, const State&b){return a.score>b.score;});\n            next.resize(beamWidth);\n        }\n        for(auto &s: next){\n            if(s.score>bestScore){bestScore=s.score; bestPath=s.path;}\n        }\n        beam=move(next);\n    }\n    \n    printf(\"%s\\n\", bestPath.c_str());\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\ndouble h[N][N-1], v[N-1][N]; // estimated weights\nint cnt_h[N][N-1], cnt_v[N-1][N];\n\nint idx(int i, int j) { return i * N + j; }\n\nvector<pair<int,int>> dijkstra(int si, int sj, int ti, int tj) {\n    vector<double> dist(N*N, 1e18);\n    vector<int> prev_node(N*N, -1), prev_dir(N*N, -1);\n    priority_queue<pair<double,int>, vector<pair<double,int>>, greater<>> pq;\n    int s = idx(si, sj), t = idx(ti, tj);\n    dist[s] = 0;\n    pq.push({0, s});\n    int di[] = {-1, 1, 0, 0};\n    int dj[] = {0, 0, -1, 1};\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist[u]) continue;\n        int ci = u / N, cj = u % N;\n        for (int dir = 0; dir < 4; dir++) {\n            int ni = ci + di[dir], nj = cj + dj[dir];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            double w;\n            if (dir == 0) w = v[ni][cj]; // U: (ni,cj)-(ci,cj)\n            else if (dir == 1) w = v[ci][cj]; // D: (ci,cj)-(ni,cj)\n            else if (dir == 2) w = h[ci][nj]; // L: (ci,nj)-(ci,cj)\n            else w = h[ci][cj]; // R: (ci,cj)-(ci,nj)\n            int nv = idx(ni, nj);\n            if (dist[u] + w < dist[nv]) {\n                dist[nv] = dist[u] + w;\n                prev_node[nv] = u;\n                prev_dir[nv] = dir;\n                pq.push({dist[nv], nv});\n            }\n        }\n    }\n    vector<pair<int,int>> path;\n    int cur = t;\n    while (cur != s) {\n        path.push_back({prev_node[cur], prev_dir[cur]});\n        cur = prev_node[cur];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint main() {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N-1; j++) { h[i][j] = 5000; cnt_h[i][j] = 0; }\n    for (int i = 0; i < N-1; i++) for (int j = 0; j < N; j++) { v[i][j] = 5000; cnt_v[i][j] = 0; }\n    \n    char dirs[] = \"UDLR\";\n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        scanf(\"%d%d%d%d\", &si, &sj, &ti, &tj);\n        auto path = dijkstra(si, sj, ti, tj);\n        string ans;\n        vector<pair<int,int>> edges; // edge type and indices\n        double est = 0;\n        for (auto [node, dir] : path) {\n            ans += dirs[dir];\n            int ci = node / N, cj = node % N;\n            if (dir == 0) { edges.push_back({0, (ci-1)*N+cj}); est += v[ci-1][cj]; }\n            else if (dir == 1) { edges.push_back({1, ci*N+cj}); est += v[ci][cj]; }\n            else if (dir == 2) { edges.push_back({2, ci*N+(cj-1)}); est += h[ci][cj-1]; }\n            else { edges.push_back({3, ci*N+cj}); est += h[ci][cj]; }\n        }\n        printf(\"%s\\n\", ans.c_str()); fflush(stdout);\n        int obs; scanf(\"%d\", &obs);\n        double ratio = (double)obs / est;\n        double lr = 0.1;\n        for (auto [type, eid] : edges) {\n            if (type == 0 || type == 1) { int i = eid/N, j = eid%N; v[i][j] += lr*(v[i][j]*ratio - v[i][j]); v[i][j] = max(1000.0, min(9000.0, v[i][j])); }\n            else { int i = eid/N, j = eid%N; h[i][j] += lr*(h[i][j]*ratio - h[i][j]); h[i][j] = max(1000.0, min(9000.0, h[i][j])); }\n        }\n    }\n}","ahc004":"#include<bits/stdc++.h>\nusing namespace std;int N,M;string S[801];char G[20][20];mt19937 rng(42);bool ck(int s){int k=S[s].size();for(int i=0;i<N;i++)for(int j=0;j<N;j++){bool h=1,v=1;for(int p=0;p<k;p++){if(G[i][(j+p)%N]!=S[s][p])h=0;if(G[(i+p)%N][j]!=S[s][p])v=0;if(!h&&!v)break;}if(h||v)return 1;}return 0;}int main(){ios::sync_with_stdio(0);cin.tie(0);cin>>N>>M;for(int i=0;i<M;i++)cin>>S[i];for(int i=0;i<N;i++)for(int j=0;j<N;j++)G[i][j]='A'+rng()%8;vector<vector<int>>cell2str(400);for(int s=0;s<M;s++){int k=S[s].size();set<int>cs;for(int i=0;i<N;i++)for(int j=0;j<N;j++){for(int p=0;p<k;p++){cs.insert(i*20+(j+p)%N);cs.insert(((i+p)%N)*20+j);}}for(int c:cs)cell2str[c].push_back(s);}vector<int>matched(M);int tot=0;for(int i=0;i<M;i++){matched[i]=ck(i);tot+=matched[i];}auto t0=chrono::steady_clock::now();for(long long it=0;;it++){if(it%500==0){auto now=chrono::steady_clock::now();if(chrono::duration<double>(now-t0).count()>2.7)break;}int ci=rng()%N,cj=rng()%N;char oc=G[ci][cj],nc='A'+rng()%8;if(nc==oc)continue;auto&aff=cell2str[ci*20+cj];int om=0;for(int s:aff)om+=matched[s];G[ci][cj]=nc;int nm=0;vector<int>nv(aff.size());for(int i=0;i<(int)aff.size();i++){nv[i]=ck(aff[i]);nm+=nv[i];}if(nm>=om){for(int i=0;i<(int)aff.size();i++)matched[aff[i]]=nv[i];tot+=nm-om;}else G[ci][cj]=oc;}for(int i=0;i<N;i++){for(int j=0;j<N;j++)cout<<G[i][j];cout<<'\\n';}}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nchar grid[70][70];\nint cost[70][70];\nint dist[70*70][70*70]; // too large, use on-demand Dijkstra\n\nstruct State { int d, i, j; };\n\nvector<pair<int,int>> visible_from[70][70];\nbool seen[70][70];\n\nint encode(int i, int j) { return i*N+j; }\n\nvector<int> dijkstra_path(int si, int sj, int ti, int tj) {\n    vector<vector<int>> d(N, vector<int>(N, INT_MAX));\n    vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N, {-1,-1}));\n    priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n    d[si][sj] = 0;\n    pq.push({0, si, sj});\n    int dx[]={-1,1,0,0}, dy[]={0,0,-1,1};\n    while (!pq.empty()) {\n        auto [dd, ci, cj] = pq.top(); pq.pop();\n        if (dd > d[ci][cj]) continue;\n        if (ci==ti && cj==tj) break;\n        for (int k=0;k<4;k++){\n            int ni=ci+dx[k], nj=cj+dy[k];\n            if (ni<0||ni>=N||nj<0||nj>=N||grid[ni][nj]=='#') continue;\n            int nd = dd + cost[ni][nj];\n            if (nd < d[ni][nj]) { d[ni][nj]=nd; par[ni][nj]={ci,cj}; pq.push({nd,ni,nj}); }\n        }\n    }\n    vector<int> path;\n    if (d[ti][tj]==INT_MAX) return path;\n    int ci=ti, cj=tj;\n    vector<pair<int,int>> pts;\n    while (!(ci==si && cj==sj)) { pts.push_back({ci,cj}); auto [pi,pj]=par[ci][cj]; ci=pi; cj=pj; }\n    pts.push_back({si,sj});\n    reverse(pts.begin(), pts.end());\n    // convert to moves\n    string dirs = \"UDLR\";\n    for (int i=1;i<(int)pts.size();i++){\n        int di=pts[i].first-pts[i-1].first, dj=pts[i].second-pts[i-1].second;\n        if(di==-1) path.push_back(0);\n        else if(di==1) path.push_back(1);\n        else if(dj==-1) path.push_back(2);\n        else path.push_back(3);\n    }\n    return path;\n}\n\nvoid compute_visibility(int i, int j) {\n    if (grid[i][j]=='#') return;\n    visible_from[i][j].push_back({i,j});\n    for (int dj=j-1;dj>=0;dj--){ if(grid[i][dj]=='#') break; visible_from[i][j].push_back({i,dj}); }\n    for (int dj=j+1;dj<N;dj++){ if(grid[i][dj]=='#') break; visible_from[i][j].push_back({i,dj}); }\n    for (int di=i-1;di>=0;di--){ if(grid[di][j]=='#') break; visible_from[i][j].push_back({di,j}); }\n    for (int di=i+1;di<N;di++){ if(grid[di][j]=='#') break; visible_from[i][j].push_back({di,j}); }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> si >> sj;\n    for (int i=0;i<N;i++){\n        string s; cin >> s;\n        for (int j=0;j<N;j++){\n            grid[i][j]=s[j];\n            if (s[j]!='#') cost[i][j]=s[j]-'0';\n        }\n    }\n    for (int i=0;i<N;i++) for (int j=0;j<N;j++) compute_visibility(i,j);\n    \n    memset(seen, false, sizeof(seen));\n    // Mark visible from start\n    int ci=si, cj=sj;\n    for (auto [vi,vj]: visible_from[ci][cj]) seen[vi][vj]=true;\n    \n    int total_road=0;\n    for (int i=0;i<N;i++) for (int j=0;j<N;j++) if(grid[i][j]!='#') total_road++;\n    \n    string result;\n    string dirs = \"UDLR\";\n    int dx[]={-1,1,0,0}, dy[]={0,0,-1,1};\n    \n    auto count_unseen = [&]() {\n        int c=0;\n        for (int i=0;i<N;i++) for (int j=0;j<N;j++) if(grid[i][j]!='#' && !seen[i][j]) c++;\n        return c;\n    };\n    \n    while (count_unseen() > 0) {\n        // Find best target: highest unseen_coverage / distance\n        int bestI=-1, bestJ=-1;\n        double bestScore = -1;\n        \n        // BFS/Dijkstra from current position\n        vector<vector<int>> d(N, vector<int>(N, INT_MAX));\n        vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N, {-1,-1}));\n        priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n        d[ci][cj]=0; pq.push({0,ci,cj});\n        while (!pq.empty()){\n            auto [dd,i,j]=pq.top(); pq.pop();\n            if (dd>d[i][j]) continue;\n            for (int k=0;k<4;k++){\n                int ni=i+dx[k],nj=j+dy[k];\n                if(ni<0||ni>=N||nj<0||nj>=N||grid[ni][nj]=='#') continue;\n                int nd=dd+cost[ni][nj];\n                if(nd<d[ni][nj]){d[ni][nj]=nd;par[ni][nj]={i,j};pq.push({nd,ni,nj});}\n            }\n        }\n        \n        for (int i=0;i<N;i++) for (int j=0;j<N;j++) if(grid[i][j]!='#' && d[i][j]<INT_MAX){\n            int unseen_cnt=0;\n            for (auto [vi,vj]: visible_from[i][j]) if(!seen[vi][vj]) unseen_cnt++;\n            if (unseen_cnt==0) continue;\n            double score = (double)unseen_cnt / max(1, d[i][j]);\n            if (score > bestScore){ bestScore=score; bestI=i; bestJ=j; }\n        }\n        \n        if (bestI==-1) break;\n        \n        // Trace path\n        vector<pair<int,int>> pts;\n        int ti=bestI, tj=bestJ;\n        while(!(ti==ci&&tj==cj)){pts.push_back({ti,tj});auto[pi,pj]=par[ti][tj];ti=pi;tj=pj;}\n        reverse(pts.begin(),pts.end());\n        for (auto [pi,pj]: pts){\n            int di=pi-ci, dj=pj-cj;\n            if(di==-1) result+='U'; else if(di==1) result+='D'; else if(dj==-1) result+='L'; else result+='R';\n            ci=pi; cj=pj;\n            for (auto [vi,vj]: visible_from[ci][cj]) seen[vi][vj]=true;\n        }\n    }\n    \n    // Return to start\n    auto path = dijkstra_path(ci, cj, si, sj);\n    for (int m: path) result += dirs[m];\n    \n    cout << result << endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    \n    int N,M,K,R;\n    scanf(\"%d%d%d%d\",&N,&M,&K,&R);\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for(int i=0;i<N;i++) for(int j=0;j<K;j++) scanf(\"%d\",&d[i][j]);\n    \n    vector<vector<int>> deps(N), rdeps(N);\n    for(int i=0;i<R;i++){\n        int u,v; scanf(\"%d%d\",&u,&v); u--;v--;\n        deps[v].push_back(u);\n        rdeps[u].push_back(v);\n    }\n    \n    // Compute longest path from each node to any sink (priority)\n    vector<int> priority(N,0);\n    {\n        vector<int> topo;\n        vector<int> indeg(N,0);\n        for(int i=0;i<N;i++) for(int j:rdeps[i]) indeg[j]++;\n        queue<int> q;\n        for(int i=0;i<N;i++) if(indeg[i]==0) q.push(i);\n        while(!q.empty()){int u=q.front();q.pop();topo.push_back(u);for(int v:rdeps[u])if(--indeg[v]==0)q.push(v);}\n        for(int i=N-1;i>=0;i--){\n            int u=topo[i];\n            priority[u]=0;\n            for(int v:rdeps[u]) priority[u]=max(priority[u],priority[v]+1);\n        }\n    }\n    \n    // Skill estimation\n    vector<vector<double>> s_est(M, vector<double>(K, 15.0)); // initial guess\n    vector<vector<double>> s_low(M, vector<double>(K, 0.0));\n    \n    // State\n    vector<int> task_status(N, -1); // -1=not started, 0=in progress, 1=done\n    vector<int> member_task(M, -1);\n    vector<int> member_start(M, -1);\n    \n    auto est_time = [&](int task, int member) -> double {\n        double w = 0;\n        for(int k=0;k<K;k++) w += max(0.0, d[task][k] - s_est[member][k]);\n        return max(1.0, w);\n    };\n    \n    auto can_start = [&](int task) -> bool {\n        if(task_status[task]!=-1) return false;\n        for(int dep : deps[task]) if(task_status[dep]!=1) return false;\n        return true;\n    };\n    \n    for(int day=1; day<=2000; day++){\n        vector<int> free_members;\n        for(int j=0;j<M;j++) if(member_task[j]==-1) free_members.push_back(j);\n        \n        vector<int> avail_tasks;\n        for(int i=0;i<N;i++) if(can_start(i)) avail_tasks.push_back(i);\n        \n        sort(avail_tasks.begin(), avail_tasks.end(), [&](int a, int b){ return priority[a]>priority[b]; });\n        \n        vector<pair<int,int>> assignments;\n        set<int> used_members;\n        for(int task : avail_tasks){\n            if(used_members.size()==free_members.size()) break;\n            int best_m=-1; double best_t=1e18;\n            for(int j : free_members){\n                if(used_members.count(j)) continue;\n                double t = est_time(task, j);\n                if(t < best_t){ best_t=t; best_m=j; }\n            }\n            if(best_m>=0){\n                assignments.push_back({best_m, task});\n                used_members.insert(best_m);\n                task_status[task]=0;\n                member_task[best_m]=task;\n                member_start[best_m]=day;\n            }\n        }\n        \n        printf(\"%d\", (int)assignments.size());\n        for(auto [a,b]:assignments) printf(\" %d %d\", a+1, b+1);\n        printf(\"\\n\");\n        fflush(stdout);\n        \n        int n_done; scanf(\"%d\",&n_done);\n        if(n_done==-1) return 0;\n        for(int i=0;i<n_done;i++){\n            int f; scanf(\"%d\",&f); f--;\n            int task=member_task[f];\n            int t_obs=day - member_start[f]+1;\n            task_status[task]=1;\n            member_task[f]=-1;\n            \n            if(t_obs==1){\n                for(int k=0;k<K;k++) s_low[f][k]=max(s_low[f][k],(double)d[task][k]);\n            } else {\n                double w_est = t_obs; // w \u2248 t \u00b1 3\n                double w_cur=0;\n                for(int k=0;k<K;k++) w_cur+=max(0.0, d[task][k]-s_est[f][k]);\n                if(w_cur>0){\n                    double ratio = w_est / w_cur;\n                    for(int k=0;k<K;k++){\n                        double gap = d[task][k]-s_est[f][k];\n                        if(gap>0){\n                            double new_s = d[task][k] - gap*ratio;\n                            s_est[f][k] = s_est[f][k]*0.7 + new_s*0.3;\n                        }\n                    }\n                }\n            }\n            for(int k=0;k<K;k++) s_est[f][k]=max(s_est[f][k], s_low[f][k]);\n        }\n    }\n    \n    // Read final -1\n    int dummy; scanf(\"%d\",&dummy);\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N=1000, M=50;\n    vector<int> a(N),b(N),c(N),d(N);\n    for(int i=0;i<N;i++) cin>>a[i]>>b[i]>>c[i]>>d[i];\n    \n    auto mdist=[](int x1,int y1,int x2,int y2){return abs(x1-x2)+abs(y1-y2);};\n    \n    // Score orders: prefer short orders close to center\n    // cost ~ dist(400,400,a,b) + dist(a,b,c,d) + dist(c,d,400,400) but shared routes reduce this\n    vector<double> score(N);\n    for(int i=0;i<N;i++){\n        int dd = mdist(400,400,a[i],b[i]) + mdist(a[i],b[i],c[i],d[i]) + mdist(c[i],d[i],400,400);\n        score[i] = dd;\n    }\n    \n    // Select 50 with smallest score\n    vector<int> idx(N);\n    iota(idx.begin(),idx.end(),0);\n    sort(idx.begin(),idx.end(),[&](int i,int j){return score[i]<score[j];});\n    \n    auto solveRoute=[&](vector<int>& chosen) -> pair<int,vector<int>> {\n        // 2*M locations: chosen[i] pickup=2i, delivery=2i+1\n        int K=2*M;\n        vector<int> px(K),py(K);\n        for(int i=0;i<M;i++){\n            int o=chosen[i];\n            px[2*i]=a[o]; py[2*i]=b[o];\n            px[2*i+1]=c[o]; py[2*i+1]=d[o];\n        }\n        \n        // Greedy nearest neighbor with precedence\n        vector<int> route;\n        vector<bool> visited(K,false);\n        vector<bool> picked(M,false);\n        int cx=400,cy=400;\n        for(int step=0;step<K;step++){\n            int best=-1, bestd=INT_MAX;\n            for(int j=0;j<K;j++){\n                if(visited[j]) continue;\n                int ord=j/2; bool isDel=(j%2==1);\n                if(isDel && !picked[ord]) continue;\n                int d2=mdist(cx,cy,px[j],py[j]);\n                if(d2<bestd){bestd=d2;best=j;}\n            }\n            visited[best]=true;\n            if(best%2==0) picked[best/2]=true;\n            route.push_back(best);\n            cx=px[best]; cy=py[best];\n        }\n        \n        // 2-opt local search\n        auto calcCost=[&](vector<int>& r)->int{\n            int t=mdist(400,400,px[r[0]],py[r[0]]);\n            for(int i=0;i+1<K;i++) t+=mdist(px[r[i]],py[r[i]],px[r[i+1]],py[r[i+1]]);\n            t+=mdist(px[r.back()],py[r.back()],400,400);\n            return t;\n        };\n        \n        auto feasible=[&](vector<int>& r)->bool{\n            vector<int> pos(K);\n            for(int i=0;i<K;i++) pos[r[i]]=i;\n            for(int i=0;i<M;i++) if(pos[2*i]>pos[2*i+1]) return false;\n            return true;\n        };\n        \n        int bestCost=calcCost(route);\n        auto deadline=chrono::steady_clock::now()+chrono::milliseconds(1800);\n        mt19937 rng(42);\n        while(chrono::steady_clock::now()<deadline){\n            int i=rng()%K, j=rng()%K;\n            if(i>j) swap(i,j); if(i==j) continue;\n            reverse(route.begin()+i,route.begin()+j+1);\n            if(feasible(route)){int nc=calcCost(route);if(nc<bestCost){bestCost=nc;}else reverse(route.begin()+i,route.begin()+j+1);}\n            else reverse(route.begin()+i,route.begin()+j+1);\n        }\n        return {bestCost,route};\n    };\n    \n    vector<int> chosen(idx.begin(),idx.begin()+M);\n    auto [cost,route]=solveRoute(chosen);\n    \n    int K=2*M;\n    vector<int> px(K),py(K);\n    for(int i=0;i<M;i++){px[2*i]=a[chosen[i]];py[2*i]=b[chosen[i]];px[2*i+1]=c[chosen[i]];py[2*i+1]=d[chosen[i]];}\n    \n    cout<<M;for(int i=0;i<M;i++) cout<<\" \"<<chosen[i]+1;cout<<\"\\n\";\n    int n=K+2;\n    cout<<n<<\" 400 400\";\n    for(int j=0;j<K;j++) cout<<\" \"<<px[route[j]]<<\" \"<<py[route[j]];\n    cout<<\" 400 400\\n\";\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n): p(n), sz(n,1) { iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a, int b){ a=find(a);b=find(b);if(a==b)return false;if(sz[a]<sz[b])swap(a,b);p[b]=a;sz[a]+=sz[b];return true; }\n    bool same(int a,int b){return find(a)==find(b);}\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    int N=400, M=1995;\n    vector<int> x(N),y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n    vector<int> U(M),V(M);\n    vector<double> D(M);\n    for(int i=0;i<M;i++){\n        cin>>U[i]>>V[i];\n        double dx=x[U[i]]-x[V[i]], dy=y[U[i]]-y[V[i]];\n        D[i]=round(sqrt(dx*dx+dy*dy));\n    }\n    \n    // For each pair of vertices, collect future edge indices\n    // We need to track remaining edges between component pairs\n    DSU dsu(N);\n    int components = N;\n    \n    for(int i=0;i<M;i++){\n        int l; cin>>l;\n        \n        if(dsu.same(U[i],V[i])){\n            cout<<0<<\"\\n\"<<flush;\n            continue;\n        }\n        \n        // Count remaining edges (after this one) that cross between these two components\n        int fu=dsu.find(U[i]), fv=dsu.find(V[i]);\n        int remaining=0;\n        double best_expected=1e18;\n        for(int j=i+1;j<M;j++){\n            int a=dsu.find(U[j]), b=dsu.find(V[j]);\n            if((a==fu&&b==fv)||(a==fv&&b==fu)){\n                remaining++;\n                best_expected=min(best_expected, D[j]*2.0);\n            }\n        }\n        \n        double ratio = (double)l / D[i];\n        // threshold: if few remaining alternatives, accept more readily\n        double threshold;\n        if(remaining==0) threshold=3.01;\n        else if(remaining<=2) threshold=2.2;\n        else if(remaining<=5) threshold=1.8;\n        else threshold=1.5;\n        \n        if(ratio<=threshold || (components==2)){\n            cout<<1<<\"\\n\"<<flush;\n            dsu.unite(U[i],V[i]);\n            components--;\n        } else {\n            cout<<0<<\"\\n\"<<flush;\n        }\n    }\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint px[25], py[25], pt[25];\nint hx[15], hy[15];\nbool wall[35][35];\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dmc[] = {'U','D','L','R'};\nchar dpc[] = {'u','d','l','r'};\n\nbool inBounds(int x, int y) { return x>=1 && x<=30 && y>=1 && y<=30; }\n\nbool petAdjacent(int x, int y) {\n    if (!inBounds(x,y)) return false;\n    for (int i=0;i<N;i++) {\n        if (px[i]==x && py[i]==y) return true;\n        for (int d=0;d<4;d++) {\n            if (px[i]==x+dx[d] && py[i]==y+dy[d]) return true; // wait no, the adjacent check is: can't choose square whose adjacent square contains pet\n        }\n    }\n    // Actually: can't place wall on square that contains pet/human, AND can't place wall on square adjacent to a pet\n    for (int i=0;i<N;i++) {\n        if (abs(px[i]-x)+abs(py[i]-y)<=1) return true;\n    }\n    return false;\n}\n\nbool humanOn(int x, int y) {\n    for (int i=0;i<M;i++) if (hx[i]==x && hy[i]==y) return true;\n    return false;\n}\n\n// BFS to find path from (sx,sy) to (tx,ty) on passable squares\nvector<pair<int,int>> bfsPath(int sx, int sy, int tx, int ty) {\n    if (sx==tx && sy==ty) return {};\n    int prev[31][31][2];\n    memset(prev, -1, sizeof(prev));\n    queue<pair<int,int>> q;\n    q.push({sx,sy});\n    prev[sx][sy][0] = sx; prev[sx][sy][1] = sy;\n    while (!q.empty()) {\n        auto [cx,cy] = q.front(); q.pop();\n        for (int d=0;d<4;d++) {\n            int nx=cx+dx[d], ny=cy+dy[d];\n            if (inBounds(nx,ny) && !wall[nx][ny] && prev[nx][ny][0]==-1) {\n                prev[nx][ny][0]=cx; prev[nx][ny][1]=cy;\n                if (nx==tx && ny==ty) {\n                    vector<pair<int,int>> path;\n                    int x=tx, y=ty;\n                    while (x!=sx || y!=sy) {\n                        path.push_back({x,y});\n                        int px2=prev[x][y][0], py2=prev[x][y][1];\n                        x=px2; y=py2;\n                    }\n                    reverse(path.begin(), path.end());\n                    return path;\n                }\n                q.push({nx,ny});\n            }\n        }\n    }\n    return {};\n}\n\n// Strategy: build walls to create grid partitions\n// Target wall lines: rows 6,7 and 24,25 and cols 6,7 and 24,25 (creating a border)\n// Simpler: each person builds walls greedily around nearest pets\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    for (int i=0;i<N;i++) cin >> px[i] >> py[i] >> pt[i];\n    cin >> M;\n    for (int i=0;i<M;i++) cin >> hx[i] >> hy[i];\n    \n    memset(wall, false, sizeof(wall));\n    \n    // Wall target lines - build walls along certain rows/columns to partition grid\n    // Let's try to build walls to trap pets\n    // Strategy: each person moves toward their assigned wall-building tasks\n    \n    // Simple greedy: each turn, each person tries to place a wall adjacent to them\n    // that is valid (not adjacent to pet), preferring squares that help block pets.\n    // If no good wall placement, move toward a useful position.\n    \n    for (int turn=0; turn<300; turn++) {\n        string actions(M, '.');\n        \n        for (int p=0; p<M; p++) {\n            int bx = hx[p], by = hy[p];\n            \n            // Try to place a wall\n            int bestD = -1;\n            int bestScore = -1;\n            \n            for (int d=0; d<4; d++) {\n                int nx = bx+dx[d], ny = by+dy[d];\n                if (!inBounds(nx,ny)) continue;\n                if (wall[nx][ny]) continue;\n                if (humanOn(nx,ny)) continue;\n                if (petAdjacent(nx,ny)) continue;\n                \n                // Score: prefer squares that help block pets\n                // Count how many pets are \"beyond\" this wall\n                int score = 0;\n                // Prefer placing walls that are between us and pets\n                for (int i=0;i<N;i++) {\n                    int dist_pet = abs(px[i]-nx)+abs(py[i]-ny);\n                    if (dist_pet <= 5) score += (6-dist_pet)*10;\n                }\n                // Prefer walls that extend existing walls (create lines)\n                for (int dd=0;dd<4;dd++) {\n                    int ax=nx+dx[dd], ay=ny+dy[dd];\n                    if (!inBounds(ax,ay) || wall[ax][ay]) score += 5;\n                }\n                \n                if (score > bestScore) {\n                    bestScore = score;\n                    bestD = d;\n                }\n            }\n            \n            if (bestD >= 0 && bestScore > 0) {\n                actions[p] = dpc[bestD];\n            } else {\n                // Move toward nearest pet to build walls near it\n                int bestDist = 1e9;\n                int targetPet = -1;\n                for (int i=0;i<N;i++) {\n                    int d2 = abs(px[i]-bx)+abs(py[i]-by);\n                    if (d2 > 3 && d2 < bestDist) { // not too close\n                        bestDist = d2;\n                        targetPet = i;\n                    }\n                }\n                if (targetPet >= 0) {\n                    auto path = bfsPath(bx, by, px[targetPet], py[targetPet]);\n                    if (path.size() > 1) {\n                        int nx2=path[0].first, ny2=path[0].second;\n                        if (!wall[nx2][ny2]) {\n                            for (int d=0;d<4;d++) {\n                                if (bx+dx[d]==nx2 && by+dy[d]==ny2) {\n                                    actions[p] = dmc[d];\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Apply actions\n        for (int p=0;p<M;p++) {\n            char a = actions[p];\n            for (int d=0;d<4;d++) {\n                if (a==dpc[d]) { int nx=hx[p]+dx[d], ny=hy[p]+dy[d]; if(inBounds(nx,ny)) wall[nx][ny]=true; }\n                if (a==dmc[d]) { hx[p]+=dx[d]; hy[p]+=dy[d]; }\n            }\n        }\n        \n        cout << actions << \"\\n\";\n        cout.flush();\n        \n        // Read pet movements\n        for (int i=0;i<N;i++) {\n            string s; cin >> s;\n            for (char c : s) {\n                for (int d=0;d<4;d++) if (c==dmc[d]) { px[i]+=dx[d]; py[i]+=dy[d]; }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int si,sj,ti,tj;\n    double p;\n    scanf(\"%d%d%d%d%lf\",&si,&sj,&ti,&tj,&p);\n    \n    bool hwall[20][19], vwall[19][20];\n    for(int i=0;i<20;i++){\n        char s[25]; scanf(\"%s\",s);\n        for(int j=0;j<19;j++) hwall[i][j]=(s[j]=='1');\n    }\n    for(int i=0;i<19;i++){\n        char s[25]; scanf(\"%s\",s);\n        for(int j=0;j<20;j++) vwall[i][j]=(s[j]=='1');\n    }\n    \n    // BFS shortest path\n    int dist[20][20]; memset(dist,-1,sizeof(dist));\n    int prev_dir[20][20]; memset(prev_dir,-1,sizeof(prev_dir));\n    pair<int,int> par[20][20];\n    queue<pair<int,int>> Q;\n    dist[si][sj]=0; Q.push({si,sj});\n    int di[]={-1,1,0,0}, dj[]={0,0,-1,1}; // U D L R\n    while(!Q.empty()){\n        auto [ci,cj]=Q.front(); Q.pop();\n        for(int d=0;d<4;d++){\n            int ni=ci+di[d], nj=cj+dj[d];\n            if(ni<0||ni>=20||nj<0||nj>=20) continue;\n            if(d==0&&vwall[ni][nj]) continue;\n            if(d==1&&vwall[ci][cj]) continue;\n            if(d==2&&hwall[ci][nj]) continue;\n            if(d==3&&hwall[ci][cj]) continue;\n            if(dist[ni][nj]>=0) continue;\n            dist[ni][nj]=dist[ci][cj]+1;\n            prev_dir[ni][nj]=d; par[ni][nj]={ci,cj};\n            Q.push({ni,nj});\n        }\n    }\n    \n    string path;\n    int ci=ti,cj=tj;\n    while(ci!=si||cj!=sj){\n        path+=\"UDLR\"[prev_dir[ci][cj]];\n        tie(ci,cj)=par[ci][cj];\n    }\n    reverse(path.begin(),path.end());\n    \n    int L=path.size();\n    int k=min(200/L, 200/L); // max repetition\n    \n    string best;\n    for(int rep=1; rep<=k && rep*L<=200; rep++){\n        string s;\n        for(char c:path) for(int r=0;r<rep;r++) s+=c;\n        if(s.size()<=200 && (best.empty() || true)) best=s;\n    }\n    // Try all valid k, pick best by simulation\n    // For simplicity, use k = 200/L\n    string ans;\n    for(char c:path) for(int r=0;r<k;r++) ans+=c;\n    printf(\"%s\\n\",ans.c_str());\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint tiles[N][N];\nint di[] = {0, -1, 0, 1};\nint dj[] = {-1, 0, 1, 0};\nint to_dir[8][4] = {\n    {1,0,-1,-1}, {3,-1,-1,0}, {-1,-1,3,2}, {-1,2,1,-1},\n    {1,0,3,2}, {3,2,1,0}, {2,-1,0,-1}, {-1,3,-1,1}\n};\nint orig[N][N];\n\nint rotate_tile(int t, int r) {\n    for (int k = 0; k < r; k++) {\n        if (t < 4) t = (t + 1) % 4;\n        else if (t == 4) t = 5;\n        else if (t == 5) t = 4;\n        else if (t == 6) t = 7;\n        else t = 6;\n    }\n    return t;\n}\n\npair<long long, pair<int,int>> calc_score() {\n    vector<int> lengths;\n    bool visited[N][N][4] = {};\n    for (int si = 0; si < N; si++) for (int sj = 0; sj < N; sj++) for (int sd = 0; sd < 4; sd++) {\n        if (visited[si][sj][sd]) continue;\n        int i = si, j = sj, d = sd, len = 0;\n        bool ok = true;\n        do {\n            int d2 = to_dir[tiles[i][j]][d];\n            if (d2 == -1) { ok = false; break; }\n            i += di[d2]; j += dj[d2];\n            if (i<0||i>=N||j<0||j>=N) { ok = false; break; }\n            d = (d2+2)%4;\n            len++;\n            visited[i][j][d] = true;\n        } while (!(i==si && j==sj && d==sd));\n        if (ok && len > 0) lengths.push_back(len);\n    }\n    sort(lengths.rbegin(), lengths.rend());\n    if (lengths.size() < 2) return {0, {0,0}};\n    return {(long long)lengths[0]*lengths[1], {lengths[0], lengths[1]}};\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    for(int i=0;i<N;i++){string s;cin>>s;for(int j=0;j<N;j++){orig[i][j]=s[j]-'0';tiles[i][j]=orig[i][j];}}\n    int rot[N][N]={};\n    auto [best_score, best_pair] = calc_score();\n    long long cur_score = best_score;\n    int best_rot[N][N]={};\n    mt19937 rng(42);\n    auto start = chrono::steady_clock::now();\n    for(long long iter=0;;iter++){\n        if(iter%1000==0){\n            auto now=chrono::steady_clock::now();\n            if(chrono::duration_cast<chrono::milliseconds>(now-start).count()>1900)break;\n        }\n        int ci=rng()%N, cj=rng()%N;\n        int dr=1+rng()%3;\n        int old_t=tiles[ci][cj], old_r=rot[ci][cj];\n        int new_r=(old_r+dr)%4;\n        tiles[ci][cj]=rotate_tile(orig[ci][cj],new_r);\n        rot[ci][cj]=new_r;\n        auto [ns,np]=calc_score();\n        double temp=1e4*max(0.0,1.0-(double)chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-start).count()/1900.0)+1;\n        if(ns>=cur_score||rng()%10000<10000*exp((double)(ns-cur_score)/temp)){\n            cur_score=ns;\n            if(ns>best_score){best_score=ns;memcpy(best_rot,rot,sizeof(rot));}\n        } else {\n            tiles[ci][cj]=old_t; rot[ci][cj]=old_r;\n        }\n    }\n    string ans(900,'0');\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)ans[i*30+j]='0'+best_rot[i][j];\n    cout<<ans<<endl;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nint board[10][10];\nint ei, ej; // empty position\n\nint largest_tree() {\n    int id[10][10];\n    int cnt = 0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(board[i][j]!=0) id[i][j]=cnt++; else id[i][j]=-1;\n    vector<vector<int>> adj(cnt);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) {\n        if(board[i][j]==0) continue;\n        if(i+1<N && board[i+1][j]!=0 && (board[i][j]&8) && (board[i+1][j]&2))\n            adj[id[i][j]].push_back(id[i+1][j]), adj[id[i+1][j]].push_back(id[i][j]);\n        if(j+1<N && board[i][j+1]!=0 && (board[i][j]&4) && (board[i][j+1]&1))\n            adj[id[i][j]].push_back(id[i][j+1]), adj[id[i][j+1]].push_back(id[i][j]);\n    }\n    int best=0;\n    vector<bool> vis(cnt,false);\n    for(int s=0;s<cnt;s++) if(!vis[s]) {\n        queue<int> q; q.push(s); vis[s]=true;\n        int sz=0; int edges=0;\n        vector<int> comp;\n        while(!q.empty()){int u=q.front();q.pop();sz++;comp.push_back(u);for(int v:adj[u])if(!vis[v]){vis[v]=true;q.push(v);}}\n        for(int u:comp) edges+=adj[u].size(); edges/=2;\n        if(edges<sz) best=max(best,sz); // it's a tree/forest, take sz\n        else { /* has cycle, need to find largest tree component via DFS */ }\n    }\n    // Actually need to check each component: if edges==sz-1 it's a tree\n    // Redo properly\n    fill(vis.begin(),vis.end(),false);\n    best=0;\n    for(int s=0;s<cnt;s++) if(!vis[s]) {\n        queue<int> q; q.push(s); vis[s]=true;\n        vector<int> comp; int edg=0;\n        while(!q.empty()){int u=q.front();q.pop();comp.push_back(u);for(int v:adj[u]){edg++;if(!vis[v]){vis[v]=true;q.push(v);}}}\n        edg/=2;\n        if(edg==(int)comp.size()-1) best=max(best,(int)comp.size());\n    }\n    return best;\n}\n\nconst char* dirs=\"UDLR\";\nint di[]={-1,1,0,0}, dj[]={0,0,-1,1};\nint opp[]={1,0,3,2};\n\nint main(){\n    scanf(\"%d%d\",&N,&T);\n    for(int i=0;i<N;i++){char s[20];scanf(\"%s\",s);for(int j=0;j<N;j++){char c=s[j];board[i][j]=(c>='a'?c-'a'+10:c-'0');if(board[i][j]==0){ei=i;ej=j;}}}\n    string ans;\n    mt19937 rng(42);\n    int cur=largest_tree();\n    auto start=chrono::steady_clock::now();\n    while((int)ans.size()<T){\n        auto now=chrono::steady_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-start).count()>2800) break;\n        int bd=-1,bm=-1;\n        for(int d=0;d<4;d++){int ni=ei+di[d],nj=ej+dj[d];if(ni<0||ni>=N||nj<0||nj>=N)continue;swap(board[ei][ej],board[ni][nj]);int v=largest_tree();if(v>bd||(v==bd&&rng()%2)){bd=v;bm=d;}swap(board[ei][ej],board[ni][nj]);}\n        if(bm<0) break;\n        int ni=ei+di[bm],nj=ej+dj[bm];swap(board[ei][ej],board[ni][nj]);ei=ni;ej=nj;ans+=dirs[bm];cur=bd;\n        if(cur==N*N-1) break;\n    }\n    printf(\"%s\\n\",ans.empty()?\"U\":ans.c_str());\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    for(int d=1;d<=10;d++) cin >> a[d];\n    vector<long long> sx(N), sy(N);\n    for(int i=0;i<N;i++) cin >> sx[i] >> sy[i];\n    \n    auto evaluate = [&](vector<array<long long,4>>& lines) -> int {\n        int k = lines.size();\n        map<vector<int8_t>, int> regions;\n        for(int i=0;i<N;i++){\n            vector<int8_t> key(k);\n            bool on_line = false;\n            for(int j=0;j<k;j++){\n                long long dx = lines[j][2]-lines[j][0], dy = lines[j][3]-lines[j][1];\n                long long cross = dx*(sy[i]-lines[j][1]) - dy*(sx[i]-lines[j][0]);\n                if(cross == 0){ on_line = true; break; }\n                key[j] = cross > 0 ? 1 : -1;\n            }\n            if(!on_line) regions[key]++;\n        }\n        vector<int> bd(11,0);\n        for(auto&[k,v]:regions) if(v>=1&&v<=10) bd[v]++;\n        int score = 0;\n        for(int d=1;d<=10;d++) score += min(a[d], bd[d]);\n        return score;\n    };\n    \n    mt19937 rng(42);\n    auto randline = [&]() -> array<long long,4> {\n        long long px = rng()%20001-10000, py = rng()%20001-10000;\n        long long qx = rng()%20001-10000, qy = rng()%20001-10000;\n        while(px==qx && py==qy){ qx = rng()%20001-10000; qy = rng()%20001-10000; }\n        return {px,py,qx,qy};\n    };\n    \n    vector<array<long long,4>> best_lines;\n    int best_score = 0;\n    \n    int num_lines = min(K, 100);\n    vector<array<long long,4>> lines(num_lines);\n    for(int i=0;i<num_lines;i++) lines[i] = randline();\n    best_score = evaluate(lines);\n    best_lines = lines;\n    \n    auto start = chrono::steady_clock::now();\n    while(true){\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now-start).count();\n        if(elapsed > 2.8) break;\n        double temp = 2.0 * (1.0 - elapsed/2.8) + 0.01;\n        int idx = rng() % num_lines;\n        auto old = lines[idx];\n        lines[idx] = randline();\n        int sc = evaluate(lines);\n        if(sc > best_score || (rng()%1000 < 1000*exp((sc-best_score)/temp))){\n            if(sc > best_score){ best_score = sc; best_lines = lines; }\n        } else {\n            lines[idx] = old;\n        }\n    }\n    \n    cout << best_lines.size() << \"\\n\";\n    for(auto& l : best_lines){\n        cout << l[0] << \" \" << l[1] << \" \" << l[2] << \" \" << l[3] << \"\\n\";\n    }\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    vector<vector<bool>> dot(N, vector<bool>(N, false));\n    for(int i=0;i<M;i++){\n        int x,y; cin>>x>>y;\n        dot[x][y]=true;\n    }\n    \n    // segments used: store as set of pairs of grid points\n    // A segment from (x1,y1) to (x2,y2) on grid lines\n    // For axis-aligned rect, segments are horizontal/vertical\n    // For 45-deg rect, segments are diagonal (slope \u00b11)\n    \n    set<tuple<int,int,int,int>> used_segs; // normalized segments\n    \n    auto norm_seg=[](int x1,int y1,int x2,int y2)->tuple<int,int,int,int>{\n        if(make_pair(x1,y1)>make_pair(x2,y2)) swap(x1,x2),swap(y1,y2);\n        return {x1,y1,x2,y2};\n    };\n    \n    // Get all grid points on segment from (x1,y1) to (x2,y2)\n    // Only works for axis-aligned or 45-degree segments\n    auto get_seg_points=[](int x1,int y1,int x2,int y2,bool include_endpoints)->vector<pair<int,int>>{\n        vector<pair<int,int>> pts;\n        int dx=x2-x1, dy=y2-y1;\n        int g=__gcd(abs(dx),abs(dy));\n        if(g==0) return pts;\n        int sx=dx/g, sy=dy/g;\n        for(int i=(include_endpoints?0:1);i<=(include_endpoints?g:g-1);i++){\n            pts.push_back({x1+sx*i, y1+sy*i});\n        }\n        return pts;\n    };\n    \n    // Collect all unit segments on the perimeter of rectangle p1-p2-p3-p4\n    auto get_rect_segments=[&](int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4)->vector<tuple<int,int,int,int>>{\n        vector<tuple<int,int,int,int>> segs;\n        int pts[][2]={{x1,y1},{x2,y2},{x3,y3},{x4,y4},{x1,y1}};\n        for(int i=0;i<4;i++){\n            int ax=pts[i][0],ay=pts[i][1],bx=pts[i+1][0],by=pts[i+1][1];\n            int dx=bx-ax,dy=by-ay;\n            int g=__gcd(abs(dx),abs(dy));\n            if(g==0) continue;\n            int sx=dx/g,sy=dy/g;\n            for(int j=0;j<g;j++){\n                segs.push_back(norm_seg(ax+sx*j,ay+sy*j,ax+sx*(j+1),ay+sy*(j+1)));\n            }\n        }\n        return segs;\n    };\n    \n    // Check perimeter points for dots (excluding the 4 corners)\n    auto check_no_dots_on_perimeter=[&](int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4)->bool{\n        set<pair<int,int>> corners={{x1,y1},{x2,y2},{x3,y3},{x4,y4}};\n        int pts[][2]={{x1,y1},{x2,y2},{x3,y3},{x4,y4},{x1,y1}};\n        for(int i=0;i<4;i++){\n            auto pp=get_seg_points(pts[i][0],pts[i][1],pts[i+1][0],pts[i+1][1],true);\n            for(auto&[px,py]:pp){\n                if(corners.count({px,py})) continue;\n                if(px<0||py<0||px>=N||py>=N) continue;\n                if(dot[px][py]) return false;\n            }\n        }\n        return true;\n    };\n    \n    auto check_no_seg_overlap=[&](const vector<tuple<int,int,int,int>>& segs)->bool{\n        for(auto&s:segs) if(used_segs.count(s)) return false;\n        return true;\n    };\n    \n    auto in_bounds=[&](int x,int y)->bool{\n        return x>=0&&y>=0&&x<N&&y<N;\n    };\n    \n    double c=(N-1)/2.0;\n    auto weight=[&](int x,int y)->double{\n        return (x-c)*(x-c)+(y-c)*(y-c)+1;\n    };\n    \n    vector<tuple<int,int,int,int,int,int,int,int>> ops;\n    \n    auto try_place=[&]()->bool{\n        // Try all pairs of dots, try to form rectangles\n        // Collect dot positions\n        vector<pair<int,int>> dots_list;\n        for(int x=0;x<N;x++) for(int y=0;y<N;y++) if(dot[x][y]) dots_list.push_back({x,y});\n        \n        // For each pair, try axis-aligned and 45-degree rectangles\n        // Rectangle types: given two adjacent vertices, determine possible rectangles\n        \n        struct Cand {\n            double w;\n            int x1,y1,x2,y2,x3,y3,x4,y4;\n        };\n        \n        vector<Cand> cands;\n        \n        // For each dot as corner, try small displacements\n        for(auto&[ax,ay]:dots_list){\n            // Try vectors for rectangle sides\n            static int dvecs[][2]={{1,0},{0,1},{-1,0},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};\n            for(int len=1;len<N;len++){\n                for(auto&dv:dvecs){\n                    int dx=dv[0]*len, dy=dv[1]*len;\n                    // Two perpendicular directions for rectangle\n                    // perp to (dx,dy): (-dy,dx) and (dy,-dx)\n                    for(int len2=1;len2<N;len2++){\n                        for(int s:{-1,1}){\n                            int ex=s*(-dy)/abs(__gcd(abs(dx),abs(dy)))*len2;\n                            // This gets complicated. Let me simplify.\n                            // Skip, use simpler approach\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Simpler: for each triple of dots, check if they form 3 corners of valid rect\n        // Too expensive for large dot sets. Use pair-based approach.\n        \n        // For pairs forming an edge, try perpendicular offsets\n        // ... (time constrained, output greedy with small rects)\n        return false;\n    };\n    \n    auto start=chrono::steady_clock::now();\n    \n    // Simple greedy: try axis-aligned rectangles with small side lengths\n    while(chrono::duration<double>(chrono::steady_clock::now()-start).count()<4.5){\n        bool found=false;\n        vector<pair<int,int>> dots_list;\n        for(int x=0;x<N;x++) for(int y=0;y<N;y++) if(dot[x][y]) dots_list.push_back({x,y});\n        \n        double best_w=-1;\n        tuple<int,int,int,int,int,int,int,int> best_op;\n        \n        for(auto&[ax,ay]:dots_list){\n            for(int dx=-N;dx<N;dx++) for(int dy=-N;dy<N;dy++){\n                if(dx==0&&dy==0) continue;\n                // Only axis-aligned or 45-degree sides\n                if(!(dx==0||dy==0||abs(dx)==abs(dy))) continue;\n                int bx=ax+dx,by=ay+dy;\n                if(!in_bounds(bx,by)||!dot[bx][by]) continue;\n                // Try perpendicular vectors\n                int pdx=-dy,pdy=dx; // one perp\n                for(int s:{-1,1}){\n                    int edx=s*pdx, edy=s*pdy;\n                    // Check if this perp is axis-aligned or 45-deg\n                    if(!(edx==0||edy==0||abs(edx)==abs(edy))) continue;\n                    int cx_=bx+edx,cy_=by+edy;\n                    int dx_=ax+edx,dy_=ay+edy;\n                    if(!in_bounds(cx_,cy_)||!in_bounds(dx_,dy_)) continue;\n                    // Need exactly one of cx_,cy_ / dx_,dy_ to be new dot\n                    // p1=new, p2,p3,p4=existing\n                    // Order: p1,p2,p3,p4 form rectangle\n                    // Try dx_,dy_ as new point\n                    if(!dot[dx_][dy_]&&dot[ax][ay]&&dot[bx][by]&&dot[cx_][cy_]){\n                        // rect: dx_,dy_ -> ax,ay -> bx,by -> cx_,cy_\n                        if(check_no_dots_on_perimeter(dx_,dy_,ax,ay,bx,by,cx_,cy_)){\n                            auto segs=get_rect_segments(dx_,dy_,ax,ay,bx,by,cx_,cy_);\n                            if(check_no_seg_overlap(segs)){\n                                double w=weight(dx_,dy_);\n                                if(w>best_w){\n                                    best_w=w;\n                                    best_op={dx_,dy_,ax,ay,bx,by,cx_,cy_};\n                                }\n                            }\n                        }\n                    }\n                    if(!dot[cx_][cy_]&&dot[ax][ay]&&dot[bx][by]&&dot[dx_][dy_]){\n                        if(check_no_dots_on_perimeter(cx_,cy_,bx,by,ax,ay,dx_,dy_)){\n                            auto segs=get_rect_segments(cx_,cy_,bx,by,ax,ay,dx_,dy_);\n                            if(check_no_seg_overlap(segs)){\n                                double w=weight(cx_,cy_);\n                                if(w>best_w){\n                                    best_w=w;\n                                    best_op={cx_,cy_,bx,by,ax,ay,dx_,dy_};\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            if(chrono::duration<double>(chrono::steady_clock::now()-start).count()>4.0) break;\n        }\n        if(best_w>0){\n            auto&[a,b,c1,d,e,f,g,h]=best_op;\n            dot[a][b]=true;\n            auto segs=get_rect_segments(a,b,c1,d,e,f,g,h);\n            for(auto&s:segs) used_segs.insert(s);\n            ops.push_back(best_op);\n            found=true;\n        }\n        if(!found) break;\n    }\n    \n    cout<<ops.size()<<\"\\n\";\n    for(auto&[a,b,c1,d,e,f,g,h]:ops){\n        cout<<a<<\" \"<<b<<\" \"<<c1<<\" \"<<d<<\" \"<<e<<\" \"<<f<<\" \"<<g<<\" \"<<h<<\"\\n\";\n    }\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nint grid[10][10]; // 0=empty, 1-3=flavor\n\nvoid tilt(int g[10][10], char dir) {\n    if (dir == 'F') { // forward = row 0 direction (up)\n        for (int c = 0; c < 10; c++) {\n            int pos = 0;\n            for (int r = 0; r < 10; r++) {\n                if (g[r][c]) { g[pos][c] = (pos==r)?g[r][c]:g[r][c]; if(pos!=r){g[pos][c]=g[r][c];g[r][c]=0;} pos++; }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int c = 0; c < 10; c++) {\n            int pos = 9;\n            for (int r = 9; r >= 0; r--) {\n                if (g[r][c]) { if(pos!=r){g[pos][c]=g[r][c];g[r][c]=0;} pos--; }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int r = 0; r < 10; r++) {\n            int pos = 0;\n            for (int c = 0; c < 10; c++) {\n                if (g[r][c]) { if(pos!=c){g[r][pos]=g[r][c];g[r][c]=0;} pos++; }\n            }\n        }\n    } else { // R\n        for (int r = 0; r < 10; r++) {\n            int pos = 9;\n            for (int c = 9; c >= 0; c--) {\n                if (g[r][c]) { if(pos!=c){g[r][pos]=g[r][c];g[r][c]=0;} pos--; }\n            }\n        }\n    }\n}\n\nint eval(int g[10][10]) {\n    bool vis[10][10]={};\n    int score=0;\n    int dx[]={0,0,1,-1}, dy[]={1,-1,0,0};\n    for(int i=0;i<10;i++) for(int j=0;j<10;j++) if(g[i][j]&&!vis[i][j]){\n        int fl=g[i][j], cnt=0;\n        queue<pair<int,int>> q; q.push({i,j}); vis[i][j]=1;\n        while(!q.empty()){auto[r,c]=q.front();q.pop();cnt++;\n            for(int d=0;d<4;d++){int nr=r+dx[d],nc=c+dy[d];\n                if(nr>=0&&nr<10&&nc>=0&&nc<10&&!vis[nr][nc]&&g[nr][nc]==fl){vis[nr][nc]=1;q.push({nr,nc});}}}\n        score+=cnt*cnt;\n    }\n    return score;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    int f[100]; for(int i=0;i<100;i++) cin>>f[i];\n    memset(grid,0,sizeof(grid));\n    string dirs=\"FBLR\";\n    for(int t=0;t<100;t++){\n        int p; cin>>p; p--;\n        int cnt=0,pr=-1,pc=-1;\n        for(int r=0;r<10;r++) for(int c=0;c<10;c++) if(!grid[r][c]){if(cnt==p){pr=r;pc=c;} cnt++;}\n        grid[pr][pc]=f[t];\n        int best=-1; char bestd='F';\n        for(char d:dirs){\n            int tmp[10][10]; memcpy(tmp,grid,sizeof(grid));\n            tilt(tmp,d);\n            int s=eval(tmp);\n            if(s>best){best=s;bestd=d;}\n        }\n        tilt(grid,bestd);\n        cout<<bestd<<\"\\n\"<<flush;\n    }\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M; double eps;\n    cin >> M >> eps;\n    \n    // Choose N based on M and eps\n    int N;\n    if(eps <= 0.01) N = max(4, (int)ceil(sqrt(2.0*M))+2);\n    else if(eps <= 0.1) N = min(100, max(10, (int)(1.5*sqrt(M))+5));\n    else if(eps <= 0.2) N = min(100, max(15, (int)(2.0*sqrt(M))+8));\n    else if(eps <= 0.3) N = min(100, max(25, (int)(3.0*sqrt(M))+10));\n    else N = min(100, max(35, (int)(4.0*sqrt(M))+15));\n    \n    N = min(N, 100);\n    N = max(N, 4);\n    \n    int E = N*(N-1)/2;\n    \n    // Generate M graphs with well-separated edge densities\n    // Graph k has approximately k*(E)/(M-1) edges if M>1\n    // But we want well-separated degree sequences\n    \n    mt19937 rng(42);\n    \n    auto get_deg_seq = [&](vector<vector<int>>& adj) -> vector<int> {\n        vector<int> deg(N,0);\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) if(adj[i][j]) deg[i]++, deg[j]++;\n        sort(deg.begin(), deg.end());\n        return deg;\n    };\n    \n    auto to_string_graph = [&](vector<vector<int>>& adj) -> string {\n        string s;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) s += (char)('0'+adj[i][j]);\n        return s;\n    };\n    \n    // For each graph k, target edge count = round(k * E / (M-1)) if M>1\n    vector<string> graphs(M);\n    vector<vector<int>> deg_seqs(M);\n    vector<vector<vector<int>>> adjs(M, vector<vector<int>>(N, vector<int>(N,0)));\n    \n    for(int k=0;k<M;k++){\n        int target_edges = (M>1) ? (int)round((double)k*E/(M-1)) : E/2;\n        // Create graph with exactly target_edges edges randomly\n        vector<pair<int,int>> all_edges;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) all_edges.push_back({i,j});\n        shuffle(all_edges.begin(), all_edges.end(), rng);\n        for(int e=0;e<target_edges;e++) adjs[k][all_edges[e].first][all_edges[e].second] = adjs[k][all_edges[e].second][all_edges[e].first] = 1;\n        deg_seqs[k] = get_deg_seq(adjs[k]);\n        graphs[k] = to_string_graph(adjs[k]);\n    }\n    \n    cout << N << \"\\n\";\n    for(int k=0;k<M;k++) cout << graphs[k] << \"\\n\";\n    cout.flush();\n    \n    for(int q=0;q<100;q++){\n        string h; cin >> h;\n        vector<vector<int>> hadj(N, vector<int>(N,0));\n        int idx=0;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){ hadj[i][j]=hadj[j][i]=h[idx++]-'0'; }\n        vector<int> hd(N,0);\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) if(hadj[i][j]) hd[i]++,hd[j]++;\n        sort(hd.begin(),hd.end());\n        \n        int best=-1; double bestd=1e18;\n        for(int k=0;k<M;k++){\n            double d=0;\n            for(int i=0;i<N;i++) d+=(hd[i]-deg_seqs[k][i])*(hd[i]-deg_seqs[k][i]);\n            if(d<bestd){ bestd=d; best=k; }\n        }\n        cout << best << \"\\n\";\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M,D,K;\n    cin>>N>>M>>D>>K;\n    \n    vector<int> U(M),V(M),W(M);\n    for(int i=0;i<M;i++) cin>>U[i]>>V[i]>>W[i], U[i]--, V[i]--;\n    \n    vector<int> X(N),Y(N);\n    for(int i=0;i<N;i++) cin>>X[i]>>Y[i];\n    \n    // Adjacency list with edge indices\n    vector<vector<pair<int,int>>> adj(N); // adj[u] = {(v, edge_idx)}\n    for(int i=0;i<M;i++){\n        adj[U[i]].push_back({V[i],i});\n        adj[V[i]].push_back({U[i],i});\n    }\n    \n    // Sample source vertices for evaluation\n    mt19937 rng(42);\n    int nSample = min(N, 40);\n    vector<int> samples(N);\n    iota(samples.begin(), samples.end(), 0);\n    shuffle(samples.begin(), samples.end(), rng);\n    samples.resize(nSample);\n    \n    // Compute original SSSP from sample sources\n    vector<vector<long long>> origDist(nSample, vector<long long>(N, 1e18));\n    auto dijkstra = [&](int src, vector<long long>& dist, const vector<bool>& removed){\n        fill(dist.begin(), dist.end(), (long long)1e18);\n        dist[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 [d,u]=pq.top(); pq.pop();\n            if(d>dist[u]) continue;\n            for(auto [v,ei]:adj[u]){\n                if(removed[ei]) continue;\n                long long nd=d+W[ei];\n                if(nd<dist[v]){\n                    dist[v]=nd;\n                    pq.push({nd,v});\n                }\n            }\n        }\n    };\n    \n    vector<bool> noRemove(M, false);\n    for(int i=0;i<nSample;i++) dijkstra(samples[i], origDist[i], noRemove);\n    \n    // Edge betweenness approximation using sampled SSSP\n    vector<double> importance(M, 0);\n    for(int si=0;si<nSample;si++){\n        // BFS/Dijkstra tree edges get importance\n        for(int v=0;v<N;v++){\n            if(v==samples[si]) continue;\n            // find edge on shortest path\n            for(auto [u,ei]:adj[v]){\n                if(origDist[si][u]+W[ei]==origDist[si][v]){\n                    importance[ei]+=1.0;\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Initial assignment: sort edges by importance desc, assign round-robin\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){ return importance[a]>importance[b]; });\n    \n    vector<int> assign(M);\n    vector<int> dayCnt(D,0);\n    for(int i=0;i<M;i++){\n        int day = i % D;\n        assign[order[i]] = day;\n        dayCnt[day]++;\n    }\n    \n    // Output\n    for(int i=0;i<M;i++){\n        cout << assign[i]+1;\n        if(i<M-1) cout << ' ';\n    }\n    cout << endl;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\nint main(){\n    int D;\n    scanf(\"%d\",&D);\n    vector<string> f1(D),r1(D),f2(D),r2(D);\n    for(int i=0;i<D;i++) cin>>f1[i];\n    for(int i=0;i<D;i++) cin>>r1[i];\n    for(int i=0;i<D;i++) cin>>f2[i];\n    for(int i=0;i<D;i++) cin>>r2[i];\n    \n    vector<int> b1(D*D*D,0), b2(D*D*D,0);\n    int n=0;\n    // Config 1\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++){\n        if(f1[z][x]=='1' && r1[z][y]=='1'){\n            n++;\n            b1[x*D*D+y*D+z]=n;\n        }\n    }\n    // Config 2\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++){\n        if(f2[z][x]=='1' && r2[z][y]=='1'){\n            n++;\n            b2[x*D*D+y*D+z]=n;\n        }\n    }\n    printf(\"%d\\n\",n);\n    for(int i=0;i<D*D*D;i++) printf(\"%d%c\",b1[i],\" \\n\"[i==D*D*D-1]);\n    for(int i=0;i<D*D*D;i++) printf(\"%d%c\",b2[i],\" \\n\"[i==D*D*D-1]);\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M,K;\n    cin>>N>>M>>K;\n    \n    vector<long long> x(N),y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n    \n    vector<int> U(M),V(M);\n    vector<long long> W(M);\n    for(int j=0;j<M;j++){\n        cin>>U[j]>>V[j]>>W[j];\n        U[j]--;V[j]--;\n    }\n    \n    vector<long long> a(K),b(K);\n    for(int k=0;k<K;k++) cin>>a[k]>>b[k];\n    \n    // Adjacency list\n    vector<vector<pair<int,int>>> adj(N); // node, edge_idx\n    for(int j=0;j<M;j++){\n        adj[U[j]].push_back({V[j],j});\n        adj[V[j]].push_back({U[j],j});\n    }\n    \n    // Shortest paths (Dijkstra from each node)\n    vector<vector<long long>> dist(N, vector<long long>(N, 1e18));\n    vector<vector<int>> par(N, vector<int>(N,-1)); // parent edge\n    for(int s=0;s<N;s++){\n        priority_queue<pair<long long,int>,vector<pair<long long,int>>,greater<>> pq;\n        dist[s][s]=0;\n        pq.push({0,s});\n        while(!pq.empty()){\n            auto [d,u]=pq.top();pq.pop();\n            if(d>dist[s][u]) continue;\n            for(auto [v,eid]:adj[u]){\n                long long nd=d+W[eid];\n                if(nd<dist[s][v]){\n                    dist[s][v]=nd;\n                    par[s][v]=eid;\n                    pq.push({nd,v});\n                }\n            }\n        }\n    }\n    \n    // For each resident, distances to each vertex\n    vector<vector<double>> rdist(K, vector<double>(N));\n    vector<vector<int>> cands(K); // vertices that can cover resident k\n    for(int k=0;k<K;k++){\n        for(int i=0;i<N;i++){\n            double dx=x[i]-a[k], dy=y[i]-b[k];\n            rdist[k][i]=sqrt(dx*dx+dy*dy);\n            if(rdist[k][i]<=5000.0+1e-9) cands[k].push_back(i);\n        }\n    }\n    \n    // Compute needed radius for each vertex to cover each resident\n    // P_i = ceil(rdist[k][i])\n    auto needed_radius = [&](int k, int i) -> int {\n        double d = rdist[k][i];\n        return (int)ceil(d - 1e-9);\n    };\n    \n    // Greedy: assign each resident to cheapest vertex, then build Steiner tree\n    // Try multiple strategies\n    \n    auto solve = [&]() -> pair<long long, pair<vector<int>,vector<int>>> {\n        // For each resident, find the vertex with minimum marginal cost\n        // We'll use iterative approach\n        \n        // Start: all vertices potentially active\n        // Assign each resident to vertex minimizing radius needed\n        // Then figure out which vertices are actually used and connect them\n        \n        vector<int> assign(K); // which vertex covers resident k\n        vector<int> P(N, 0);\n        \n        // Initial assignment: each resident to nearest vertex\n        for(int k=0;k<K;k++){\n            int best=-1; double bestd=1e18;\n            for(int i:cands[k]){\n                if(rdist[k][i]<bestd){\n                    bestd=rdist[k][i];\n                    best=i;\n                }\n            }\n            assign[k]=best;\n        }\n        \n        // Compute P for each vertex\n        auto recompute_P = [&](){\n            fill(P.begin(),P.end(),0);\n            for(int k=0;k<K;k++){\n                int i=assign[k];\n                int r=needed_radius(k,i);\n                P[i]=max(P[i],r);\n            }\n        };\n        recompute_P();\n        \n        // Find active vertices\n        auto get_active = [&]() -> vector<bool> {\n            vector<bool> act(N,false);\n            for(int i=0;i<N;i++) if(P[i]>0) act[i]=true;\n            act[0]=true;\n            return act;\n        };\n        \n        // Build Steiner tree connecting active vertices through vertex 0\n        auto build_tree = [&](vector<bool>& act) -> pair<long long, vector<bool>> {\n            // Prim-like: grow tree from vertex 0\n            vector<bool> inTree(N,false);\n            vector<bool> edgeUsed(M,false);\n            long long treeCost=0;\n            \n            // Need to connect all active vertices\n            // Use shortest path based Steiner tree approximation\n            vector<int> targets;\n            for(int i=0;i<N;i++) if(act[i] && i!=0) targets.push_back(i);\n            \n            inTree[0]=true;\n            while(!targets.empty()){\n                // Find nearest target to current tree\n                int bestT=-1; long long bestD=1e18; int bestNode=-1;\n                for(int t:targets){\n                    for(int i=0;i<N;i++){\n                        if(inTree[i] && dist[i][t]<bestD){\n                            bestD=dist[i][t];\n                            bestT=t;\n                            bestNode=i;\n                        }\n                    }\n                }\n                // Trace path from bestNode to bestT using par\n                // Actually we need to reconstruct path from bestNode's Dijkstra\n                int cur=bestT;\n                while(cur!=bestNode){\n                    // find edge from par[bestNode][cur]\n                    int eid=par[bestNode][cur];\n                    if(!edgeUsed[eid]){\n                        edgeUsed[eid]=true;\n                        treeCost+=W[eid];\n                    }\n                    int u=U[eid],v=V[eid];\n                    if(u==cur) cur=v; else cur=u;\n                    inTree[cur]=true;\n                }\n                inTree[bestT]=true;\n                targets.erase(remove(targets.begin(),targets.end(),bestT),targets.end());\n            }\n            return {treeCost, edgeUsed};\n        };\n        \n        auto act = get_active();\n        auto [tc, eu] = build_tree(act);\n        \n        // Now reassign residents considering vertex costs\n        // Vertices in tree are \"free\" to use (edges already paid)\n        vector<bool> inTree(N,false);\n        inTree[0]=true;\n        for(int j=0;j<M;j++) if(eu[j]){ inTree[U[j]]=true; inTree[V[j]]=true; }\n        \n        // Reassign: for each resident, pick vertex in tree minimizing P cost increase\n        for(int iter=0;iter<5;iter++){\n            fill(P.begin(),P.end(),0);\n            for(int k=0;k<K;k++){\n                int best=-1; double bestd=1e18;\n                for(int i:cands[k]){\n                    if(inTree[i] && rdist[k][i]<bestd){\n                        bestd=rdist[k][i];\n                        best=i;\n                    }\n                }\n                if(best==-1){ best=assign[k]; }\n                assign[k]=best;\n            }\n            recompute_P();\n            act=get_active();\n            auto [tc2,eu2]=build_tree(act);\n            tc=tc2; eu=eu2;\n            fill(inTree.begin(),inTree.end(),false);\n            inTree[0]=true;\n            for(int j=0;j<M;j++) if(eu[j]){ inTree[U[j]]=true; inTree[V[j]]=true; }\n        }\n        \n        recompute_P();\n        long long S=0;\n        for(int i=0;i<N;i++) S+=(long long)P[i]*P[i];\n        S+=tc;\n        \n        vector<int> B(M);\n        for(int j=0;j<M;j++) B[j]=eu[j]?1:0;\n        return {S,{P,B}};\n    };\n    \n    auto [score, result] = solve();\n    auto& [P,B] = result;\n    \n    for(int i=0;i<N;i++) cout<<P[i]<<\" \\n\"[i==N-1];\n    for(int j=0;j<M;j++) cout<<B[j]<<\" \\n\"[j==M-1];\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N=30;\nint grid[30][30];\nint pos_of_val[465]; // encoded as x*100+y\nvector<tuple<int,int,int,int>> ops;\n\nvoid do_swap(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_of_val[v1]=x2*100+y2;\n    pos_of_val[v2]=x1*100+y1;\n}\n\n// Move ball at (sx,sy) to (tx,ty), only moving through positions at tier >= minTier\nvoid move_ball(int sx,int sy,int tx,int ty,int minTier){\n    while(sx!=tx||sy!=ty){\n        int bx=-1,by=-1;\n        // greedy: move closer\n        int dx=tx-sx, dy=ty-sy;\n        // Try all 6 neighbors, pick one that reduces distance and respects minTier\n        int dirs[6][2]={{-1,-1},{-1,0},{0,-1},{0,1},{1,0},{1,1}};\n        int best=-1; double bd=1e9;\n        for(int d=0;d<6;d++){\n            int nx=sx+dirs[d][0], ny=sy+dirs[d][1];\n            if(nx<0||nx>=N||ny<0||ny>nx||nx<minTier) continue;\n            double dist=abs(tx-nx)+abs(ty-ny)+abs((tx-ty)-(nx-ny));\n            if(dist<bd){bd=dist;best=d;}\n        }\n        bx=sx+dirs[best][0]; by=sy+dirs[best][1];\n        do_swap(sx,sy,bx,by);\n        sx=bx; sy=by;\n    }\n}\n\nint main(){\n    for(int x=0;x<N;x++) for(int y=0;y<=x;y++){\n        scanf(\"%d\",&grid[x][y]);\n        pos_of_val[grid[x][y]]=x*100+y;\n    }\n    // Place tier by tier\n    for(int x=0;x<N-1;x++){\n        vector<int> need;\n        for(int y=0;y<=x;y++) need.push_back(grid[x][y]);\n        // Find which values should go here: collect all values in tier>=x, pick smallest x+1\n        vector<int> avail;\n        for(int r=x;r<N;r++) for(int c=0;c<=r;c++) avail.push_back(grid[r][c]);\n        sort(avail.begin(),avail.end());\n        for(int y=0;y<=x;y++){\n            int target=avail[y];\n            int p=pos_of_val[target];\n            move_ball(p/100,p%100,x,y,x);\n        }\n    }\n    printf(\"%d\\n\",(int)ops.size());\n    for(auto&[a,b,c,d]:ops) printf(\"%d %d %d %d\\n\",a,b,c,d);\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nint grid[9][9]; // -2=obstacle, -1=empty, >=0 container number\nint dx[]={-1,1,0,0}, dy[]={0,0,-1,1};\nint ei,ej;\n\nbool reachable(int si,int sj,int ti,int tj){\n    bool vis[9][9]={};\n    queue<pair<int,int>> q;\n    q.push({si,sj}); vis[si][sj]=1;\n    while(!q.empty()){\n        auto [x,y]=q.front();q.pop();\n        if(x==ti&&y==tj) return true;\n        for(int d=0;d<4;d++){\n            int nx=x+dx[d],ny=y+dy[d];\n            if(nx<0||nx>=D||ny<0||ny>=D) continue;\n            if(vis[nx][ny]||grid[nx][ny]==-2) continue;\n            if(!(nx==ti&&ny==tj) && grid[nx][ny]>=0) continue;\n            vis[nx][ny]=1; q.push({nx,ny});\n        }\n    }\n    return false;\n}\n\nvector<pair<int,int>> reachable_containers(){\n    bool vis[9][9]={};\n    queue<pair<int,int>> q;\n    q.push({ei,ej}); vis[ei][ej]=1;\n    vector<pair<int,int>> res;\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>=D||ny<0||ny>=D||vis[nx][ny]||grid[nx][ny]==-2) continue;\n            vis[nx][ny]=1;\n            if(grid[nx][ny]>=0) res.push_back({nx,ny});\n            else q.push({nx,ny});\n        }\n    }\n    return res;\n}\n\nint main(){\n    int N; scanf(\"%d%d\",&D,&N);\n    ei=0; ej=(D-1)/2;\n    memset(grid,-1,sizeof(grid));\n    for(int i=0;i<N;i++){int r,c;scanf(\"%d%d\",&r,&c);grid[r][c]=-2;}\n    \n    vector<pair<int,pair<int,int>>> cells;\n    for(int i=0;i<D;i++) for(int j=0;j<D;j++){\n        if(grid[i][j]==-2||(i==ei&&j==ej)) continue;\n        int dist=abs(i-ei)+abs(j-ej);\n        cells.push_back({dist,{i,j}});\n    }\n    sort(cells.begin(),cells.end());\n    int M=D*D-1-N;\n    vector<pair<int,int>> target(M);\n    for(int t=0;t<M;t++) target[t]=cells[t].second;\n    \n    for(int d=0;d<M;d++){\n        int t; scanf(\"%d\",&t);\n        auto [ti,tj]=target[t];\n        if(grid[ti][tj]==-1 && reachable(ei,ej,ti,tj)){\n            grid[ti][tj]=t; printf(\"%d %d\\n\",ti,tj); fflush(stdout);\n        } else {\n            // find nearest reachable empty cell to target\n            int best=-1; double bd=1e9; pair<int,int> bp;\n            for(auto&c:cells){\n                auto [ci,cj]=c.second;\n                if(grid[ci][cj]!=-1) continue;\n                if(!reachable(ei,ej,ci,cj)) continue;\n                double dd=abs(ci-ti)+abs(cj-tj);\n                if(dd<bd){bd=dd;bp={ci,cj};best=1;}\n            }\n            grid[bp.first][bp.second]=t;\n            printf(\"%d %d\\n\",bp.first,bp.second); fflush(stdout);\n        }\n    }\n    for(int i=0;i<M;i++){\n        auto rc=reachable_containers();\n        int best=-1; pair<int,int> bp;\n        for(auto [r,c]:rc) if(best<0||grid[r][c]<best){best=grid[r][c];bp={r,c};}\n        printf(\"%d %d\\n\",bp.first,bp.second);\n        grid[bp.first][bp.second]=-1;\n    }\n    fflush(stdout);\n}","ahc024":"#include<bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n,m;\n    cin>>n>>m;\n    \n    vector<vector<int>> c(n,vector<int>(n));\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>c[i][j];\n    \n    // Just output the original map - score = 1 (minimum zeros = 0)\n    // Actually we want to MAXIMIZE zeros. But let's start with a valid baseline.\n    \n    // Output original map as baseline\n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            cout<<c[i][j];\n            if(j<n-1) cout<<' ';\n        }\n        cout<<'\\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\nchar query(vector<int>& L, vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << \"\\n\" << flush;\n    queries_used++;\n    char c; cin >> c;\n    return c;\n}\n\n// Returns true if sum of weights[L] < sum of weights[R]\n// '<' means L < R\nchar compare(vector<int> L, vector<int> R) {\n    return query(L, R);\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin >> N >> D >> Q;\n    \n    // Merge sort\n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    // merge sort with counting\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> left(v.begin(), v.begin()+mid), right(v.begin()+mid, v.end());\n        left = msort(left); right = msort(right);\n        vector<int> res;\n        int i=0,j=0;\n        while(i<(int)left.size()&&j<(int)right.size()){\n            if(queries_used>=Q){res.push_back(left[i++]);continue;}\n            vector<int> L={left[i]}, R={right[j]};\n            char c=compare(L,R);\n            if(c=='<'||c=='=') res.push_back(left[i++]);\n            else res.push_back(right[j++]);\n        }\n        while(i<(int)left.size()) res.push_back(left[i++]);\n        while(j<(int)right.size()) res.push_back(right[j++]);\n        return res;\n    };\n    \n    vector<int> sorted_items = msort(items);\n    \n    // Estimate weights using binary search against smallest items\n    vector<double> w(N, 1.0);\n    for(int i=0;i<N;i++) w[sorted_items[i]] = i+1; // rough estimate\n    \n    // Use remaining queries: compare item against groups of smallest\n    // Use LPT (Longest Processing Time first) for partition\n    // Sort descending by weight\n    vector<int> order(sorted_items.rbegin(), sorted_items.rend());\n    vector<double> group_w(D, 0);\n    vector<int> assign(N, 0);\n    for(int idx : order){\n        int best = min_element(group_w.begin(), group_w.end()) - group_w.begin();\n        assign[idx] = best;\n        group_w[best] += w[idx];\n    }\n    \n    // Use remaining queries as dummy\n    while(queries_used < Q){\n        vector<int> L={0}, R={1};\n        compare(L, R);\n    }\n    \n    for(int i=0;i<N;i++) cout << assign[i] << \" \\n\"[i==N-1];\n    cout << flush;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int n, m;\n    scanf(\"%d%d\", &n, &m);\n    \n    vector<vector<int>> stacks(m);\n    vector<int> box_stack(n+1), box_pos(n+1);\n    \n    for(int i = 0; i < m; i++){\n        stacks[i].resize(n/m);\n        for(int j = 0; j < n/m; j++){\n            scanf(\"%d\", &stacks[i][j]);\n            box_stack[stacks[i][j]] = i;\n        }\n    }\n    \n    vector<pair<int,int>> ops;\n    \n    for(int v = 1; v <= n; v++){\n        // Find which stack v is in and its position\n        int si = -1, sj = -1;\n        for(int i = 0; i < m; i++){\n            for(int j = 0; j < (int)stacks[i].size(); j++){\n                if(stacks[i][j] == v){ si = i; sj = j; break; }\n            }\n            if(si >= 0) break;\n        }\n        \n        // If v is on top, just carry it out\n        if(sj == (int)stacks[si].size() - 1){\n            ops.push_back({v, 0});\n            stacks[si].pop_back();\n            continue;\n        }\n        \n        // Need to move boxes above v to some other stack\n        // Chunk: stacks[si][sj+1 .. end]\n        vector<int> chunk(stacks[si].begin() + sj + 1, stacks[si].end());\n        int chunk_max = *max_element(chunk.begin(), chunk.end());\n        int chunk_min = *min_element(chunk.begin(), chunk.end());\n        \n        // Choose best destination\n        int best_dest = -1;\n        int best_score = INT_MAX;\n        \n        for(int i = 0; i < m; i++){\n            if(i == si) continue;\n            int top = stacks[i].empty() ? INT_MAX : stacks[i].back();\n            // Prefer: top > chunk_max, then smallest top\n            if(top > chunk_max){\n                int score = top;\n                if(score < best_score){ best_score = score; best_dest = i; }\n            }\n        }\n        \n        if(best_dest == -1){\n            // Pick stack with largest top or empty stack\n            int best_top = -1;\n            for(int i = 0; i < m; i++){\n                if(i == si) continue;\n                int top = stacks[i].empty() ? n+1 : stacks[i].back();\n                if(top > best_top){ best_top = top; best_dest = i; }\n            }\n        }\n        \n        // Move chunk to best_dest\n        int bottom_box = stacks[si][sj+1];\n        ops.push_back({bottom_box, best_dest + 1});\n        for(auto x : chunk) stacks[best_dest].push_back(x);\n        stacks[si].resize(sj + 1);\n        \n        // Now carry out v\n        ops.push_back({v, 0});\n        stacks[si].pop_back();\n    }\n    \n    for(auto& [a,b] : ops) printf(\"%d %d\\n\", a, b);\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nstring h[40], v[40];\nint d[40][40];\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\nchar dc[]={'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 h[x-1][y]=='0';\n    if(dir==1) return h[x][y]=='0';\n    if(dir==2) return v[x][y-1]=='0';\n    if(dir==3) return v[x][y]=='0';\n    return false;\n}\n\nstring bfs_path(int sx,int sy,int gx,int gy){\n    vector<vector<int>> prev(N,vector<int>(N,-1));\n    vector<vector<bool>> vis(N,vector<bool>(N,false));\n    queue<pair<int,int>> q;\n    q.push({sx,sy}); vis[sx][sy]=true;\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        if(x==gx&&y==gy) break;\n        for(int dir=0;dir<4;dir++){\n            int nx=x+dx[dir],ny=y+dy[dir];\n            if(nx>=0&&nx<N&&ny>=0&&ny<N&&!vis[nx][ny]&&canMove(x,y,dir)){\n                vis[nx][ny]=true; prev[nx][ny]=dir;\n                q.push({nx,ny});\n            }\n        }\n    }\n    string path;\n    int cx=gx,cy=gy;\n    while(cx!=sx||cy!=sy){\n        int dir=prev[cx][cy];\n        path+=dc[dir];\n        cx-=dx[dir]; cy-=dy[dir];\n    }\n    reverse(path.begin(),path.end());\n    return path;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin>>N;\n    for(int i=0;i<N-1;i++) cin>>h[i];\n    for(int i=0;i<N;i++) cin>>v[i];\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>d[i][j];\n    \n    // Greedy nearest-neighbor with dirt priority\n    vector<vector<bool>> vis(N,vector<bool>(N,false));\n    string route;\n    int cx=0,cy=0;\n    vis[0][0]=true;\n    int visited=1, total=N*N;\n    while(visited<total){\n        // BFS to find nearest unvisited, weighted by dirt\n        // Just find nearest unvisited with highest d/dist ratio\n        // Simple: go to nearest unvisited\n        int bestx=-1,besty=-1; double bestScore=-1;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(!vis[i][j]){\n            int dist=abs(i-cx)+abs(j-cy);\n            double score=(double)d[i][j]/(dist+1);\n            if(score>bestScore){bestScore=score;bestx=i;besty=j;}\n        }\n        string p=bfs_path(cx,cy,bestx,besty);\n        for(char c:p){int dir=find(dc,dc+4,c)-dc;cx+=dx[dir];cy+=dy[dir];if(!vis[cx][cy]){vis[cx][cy]=true;visited++;}}\n        route+=p;\n    }\n    route+=bfs_path(cx,cy,0,0);\n    cout<<route<<endl;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N, M;\n    cin >> N >> M;\n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<string> grid(N);\n    for(int i=0;i<N;i++) cin >> grid[i];\n    \n    vector<string> words(M);\n    for(int i=0;i<M;i++) cin >> words[i];\n    \n    // Map: char -> list of (i,j)\n    vector<vector<pair<int,int>>> charpos(26);\n    for(int i=0;i<N;i++)\n        for(int j=0;j<N;j++)\n            charpos[grid[i][j]-'A'].push_back({i,j});\n    \n    // Greedy shortest superstring\n    auto getOverlap = [](const string& a, const string& b) -> int {\n        int maxov = min(a.size(), b.size());\n        for(int ov=maxov; ov>=1; ov--){\n            if(a.substr(a.size()-ov) == b.substr(0, ov)) return ov;\n        }\n        return 0;\n    };\n    \n    // Remove words contained in other words\n    vector<bool> removed(M, false);\n    for(int i=0;i<M;i++) if(!removed[i])\n        for(int j=0;j<M;j++) if(i!=j && !removed[j])\n            if(words[i].find(words[j]) != string::npos) removed[j]=true;\n    \n    vector<string> ws;\n    for(int i=0;i<M;i++) if(!removed[i]) ws.push_back(words[i]);\n    \n    int n = ws.size();\n    // Greedy merge\n    while(n > 1){\n        int bi=-1, bj=-1, bov=-1;\n        for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j){\n            int ov = getOverlap(ws[i], ws[j]);\n            if(ov > bov){ bov=ov; bi=i; bj=j; }\n        }\n        if(bov <= 0) break;\n        string merged = ws[bi] + ws[bj].substr(bov);\n        ws[bi] = merged;\n        ws.erase(ws.begin()+bj);\n        n = ws.size();\n    }\n    \n    string target;\n    for(auto& w : ws) target += w;\n    \n    // DP to find best positions\n    int L = target.size();\n    if(L > 5000) target = target.substr(0, 5000);\n    L = target.size();\n    \n    vector<pair<int,int>> result(L);\n    // Greedy: for each character, pick closest position\n    int ci=si, cj=sj;\n    for(int p=0;p<L;p++){\n        int ch = target[p]-'A';\n        int bestcost = INT_MAX;\n        pair<int,int> best;\n        for(auto [ni,nj] : charpos[ch]){\n            int cost = abs(ni-ci)+abs(nj-cj)+1;\n            if(cost < bestcost){ bestcost=cost; best={ni,nj}; }\n        }\n        result[p] = best;\n        ci=best.first; cj=best.second;\n    }\n    \n    for(int p=0;p<L;p++) cout << result[p].first << \" \" << result[p].second << \"\\n\";\n}","ahc030":"#include<bits/stdc++.h>\nusing namespace std;\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M;double eps;\n    cin>>N>>M>>eps;\n    vector<vector<pair<int,int>>>fields(M);\n    for(int k=0;k<M;k++){int d;cin>>d;fields[k].resize(d);for(int i=0;i<d;i++)cin>>fields[k][i].first>>fields[k][i].second;}\n    vector<vector<int>>known(N,vector<int>(N,-1));\n    vector<pair<int,int>>has_oil;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        cout<<\"q 1 \"<<i<<\" \"<<j<<endl;\n        int v;cin>>v;known[i][j]=v;\n        if(v>0)has_oil.push_back({i,j});\n    }\n    cout<<\"a \"<<has_oil.size();\n    for(auto&[i,j]:has_oil)cout<<\" \"<<i<<\" \"<<j;\n    cout<<endl;\n    int r;cin>>r;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint W, D, N;\nvector<vector<int>> a;\nstruct Rect { int i0,j0,i1,j1; };\n\nvoid partition(vector<pair<int,int>>& items, int r0, int c0, int r1, int c1, vector<Rect>& result, bool hsplit) {\n    if (items.size() == 1) {\n        result[items[0].second] = {r0, c0, r1, c1};\n        return;\n    }\n    long long total = 0;\n    for (auto& p : items) total += p.first;\n    if (total == 0) total = 1;\n    \n    int n = items.size();\n    int mid = n / 2;\n    long long left_sum = 0;\n    for (int i = 0; i < mid; i++) left_sum += items[i].first;\n    \n    vector<pair<int,int>> left_items(items.begin(), items.begin()+mid);\n    vector<pair<int,int>> right_items(items.begin()+mid, items.end());\n    \n    if (hsplit) {\n        int split = r0 + max(1, min(r1-r0-1, (int)round((double)left_sum / total * (r1-r0))));\n        if (r1 - split < (int)right_items.size()) split = r1 - (int)right_items.size();\n        if (split - r0 < (int)left_items.size()) split = r0 + (int)left_items.size();\n        split = max(r0+1, min(r1-1, split));\n        partition(left_items, r0, c0, split, c1, result, !hsplit);\n        partition(right_items, split, c0, r1, c1, result, !hsplit);\n    } else {\n        int split = c0 + max(1, min(c1-c0-1, (int)round((double)left_sum / total * (c1-c0))));\n        if (c1 - split < (int)right_items.size()) split = c1 - (int)right_items.size();\n        if (split - c0 < (int)left_items.size()) split = c0 + (int)left_items.size();\n        split = max(c0+1, min(c1-1, split));\n        partition(left_items, r0, c0, r1, split, result, !hsplit);\n        partition(right_items, r0, split, r1, c1, result, !hsplit);\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> W >> D >> N;\n    a.resize(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    for(int d=0;d<D;d++){\n        vector<pair<int,int>> items(N);\n        for(int k=0;k<N;k++) items[k]={a[d][k], k};\n        vector<Rect> res(N);\n        partition(items, 0, 0, W, W, res, true);\n        for(int k=0;k<N;k++){\n            cout<<res[k].i0<<\" \"<<res[k].j0<<\" \"<<res[k].i1<<\" \"<<res[k].j1<<\"\\n\";\n        }\n    }\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<vector<long long>> a(N, vector<long long>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin >> a[i][j];\n    \n    vector<vector<vector<long long>>> s(M, vector<vector<long long>>(3, vector<long long>(3)));\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    // Greedy: pick best operation each step\n    auto calcScore = [&](vector<vector<long long>>& b) -> long long {\n        long long sc = 0;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++) sc += b[i][j] % MOD;\n        return sc;\n    };\n    \n    auto calcDelta = [&](vector<vector<long long>>& b, int m, int p, int q) -> long long {\n        long long delta = 0;\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++){\n            long long old_v = b[p+i][q+j] % MOD;\n            long long new_v = (b[p+i][q+j] + s[m][i][j]) % MOD;\n            delta += new_v - old_v;\n        }\n        return delta;\n    };\n    \n    vector<vector<long long>> best_b = a;\n    vector<tuple<int,int,int>> best_ops;\n    long long best_score = calcScore(best_b);\n    \n    // Greedy\n    auto b = a;\n    vector<tuple<int,int,int>> ops;\n    for(int step=0; step<K; step++){\n        int bm=-1, bp=-1, bq=-1;\n        long long bd = 0;\n        for(int m=0;m<M;m++) for(int p=0;p<=N-3;p++) for(int q=0;q<=N-3;q++){\n            long long d = calcDelta(b, m, p, q);\n            if(d > bd){ bd=d; bm=m; bp=p; bq=q; }\n        }\n        if(bd <= 0) break;\n        ops.push_back({bm, bp, bq});\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[bp+i][bq+j] += s[bm][i][j];\n    }\n    long long sc = calcScore(b);\n    if(sc > best_score){ best_score=sc; best_b=b; best_ops=ops; }\n    \n    cout << best_ops.size() << \"\\n\";\n    for(auto&[m,p,q]: best_ops) cout << m << \" \" << p << \" \" << q << \"\\n\";\n}","ahc033":"#include<bits/stdc++.h>\nusing namespace std;\n\nint N;\nint A[5][5];\nint grid[5][5]; // -1=empty, else container id\nint cr[5],cc[5],ch[5]; // crane row,col,holding (-1=none)\nbool calive[5];\nint recv_idx[5];\nint next_disp[5]; // next container to dispatch from each row\nstring act[5];\nint total_dispatched=0;\n\nvoid do_receive(){\n    for(int i=0;i<N;i++){\n        if(recv_idx[i]>=N) continue;\n        if(grid[i][0]!=-1) continue;\n        bool blocked=false;\n        for(int c=0;c<N;c++){\n            if(calive[c]&&cr[c]==i&&cc[c]==0&&ch[c]!=-1) {blocked=true;break;}\n        }\n        if(!blocked){\n            grid[i][0]=A[i][recv_idx[i]];\n            recv_idx[i]++;\n        }\n    }\n}\n\nvoid do_dispatch(){\n    for(int i=0;i<N;i++){\n        if(grid[i][N-1]!=-1){\n            grid[i][N-1]=-1;\n            total_dispatched++;\n        }\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    cin>>N;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>A[i][j];\n    memset(grid,-1,sizeof(grid));\n    for(int i=0;i<N;i++){cr[i]=i;cc[i]=0;ch[i]=-1;calive[i]=true;}\n    for(int i=0;i<N;i++){recv_idx[i]=0;next_disp[i]=i*N;}\n    \n    // Bomb small cranes turn 1, but first let receiving happen\n    // Turn 1: receive, then bomb small cranes\n    // We simulate turn by turn\n    \n    auto find_container=[&](int id)->pair<int,int>{\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(grid[i][j]==id)return{i,j};\n        return{-1,-1};\n    };\n    \n    // Use large crane (0) only. Bomb others first.\n    string turn1=\"\";\n    // On turn 1, small cranes bomb\n    // But we need to be careful about the sequence\n    \n    int T=0;\n    // First, bomb small cranes\n    // Turn 1\n    do_receive();\n    for(int i=1;i<N;i++){act[i]+=\"B\";calive[i]=false;}\n    act[0]+=\".\";\n    // execute crane 0: stay\n    do_dispatch();\n    T++;\n    \n    // Now only crane 0 at (0,0)\n    // Greedy: find a container that's needed, pick it up, deliver it\n    \n    auto move_crane=[&](int from_r,int from_c,int to_r,int to_c,bool carrying)->string{\n        // BFS considering grid (if carrying with large crane, can move over containers)\n        // Large crane can always move over containers\n        string path=\"\";\n        int dr=to_r-from_r, dc=to_c-from_c;\n        while(from_r!=to_r||from_c!=to_c){\n            if(from_r<to_r){path+=\"D\";from_r++;}\n            else if(from_r>to_r){path+=\"U\";from_r--;}\n            else if(from_c<to_c){path+=\"R\";from_c++;}\n            else{path+=\"L\";from_c--;}\n        }\n        return path;\n    };\n    \n    // Main loop: deliver containers in order\n    for(int iter=0;iter<500&&T<9900;iter++){\n        // Find best target: a container on the grid that some dispatch gate needs next\n        int best_id=-1,best_r=-1,best_c=-1,best_tr=-1;\n        int best_cost=1e9;\n        \n        for(int row=0;row<N;row++){\n            int need=next_disp[row];\n            if(need>=row*N+N) continue;\n            auto [r,c]=find_container(need);\n            if(r==-1) continue; // not on grid yet\n            int cost=abs(cr[0]-r)+abs(cc[0]-c)+abs(r-row)+abs(c-(N-1));\n            if(cost<best_cost){best_cost=cost;best_id=need;best_r=r;best_c=c;best_tr=row;}\n        }\n        \n        if(best_id==-1){\n            // No needed container on grid. Wait for one.\n            do_receive();\n            act[0]+=\".\";for(int i=1;i<N;i++)act[i]+=\".\";\n            do_dispatch();T++;\n            continue;\n        }\n        \n        // Move to container\n        string path1=move_crane(cr[0],cc[0],best_r,best_c,false);\n        for(char c:path1){\n            do_receive();\n            act[0]+=c;for(int i=1;i<N;i++)act[i]+=\".\";\n            if(c=='U')cr[0]--;else if(c=='D')cr[0]++;else if(c=='L')cc[0]--;else if(c=='R')cc[0]++;\n            do_dispatch();T++;\n        }\n        \n        // Pick up\n        if(grid[cr[0]][cc[0]]==best_id){\n            do_receive();\n            act[0]+=\"P\";for(int i=1;i<N;i++)act[i]+=\".\";\n            ch[0]=best_id;grid[cr[0]][cc[0]]=-1;\n            do_dispatch();T++;\n            \n            // Move to dispatch gate\n            // Need to place at (best_tr, N-1)\n            // But if there's a container there, we need to find temp storage\n            string path2=move_crane(cr[0],cc[0],best_tr,N-1,true);\n            for(char c:path2){\n                do_receive();\n                act[0]+=string(1,c);for(int i=1;i<N;i++)act[i]+=\".\";\n                if(c=='U')cr[0]--;else if(c=='D')cr[0]++;else if(c=='L')cc[0]--;else if(c=='R')cc[0]++;\n                do_dispatch();T++;\n            }\n            \n            // If destination has container, drop in adjacent empty\n            if(grid[cr[0]][cc[0]]!=-1){\n                // find adjacent empty\n                bool placed=false;\n                for(auto [dr,dc,ch2]:vector<tuple<int,int,char>>{{-1,0,'U'},{1,0,'D'},{0,-1,'L'},{0,1,'R'}}){\n                    int nr=cr[0]+dr,nc=cc[0]+dc;\n                    if(nr>=0&&nr<N&&nc>=0&&nc<N&&grid[nr][nc]==-1){\n                        do_receive();\n                        act[0]+=string(1,ch2);for(int i=1;i<N;i++)act[i]+=\".\";\n                        cr[0]=nr;cc[0]=nc;\n                        do_dispatch();T++;\n                        break;\n                    }\n                }\n            }\n            \n            if(grid[cr[0]][cc[0]]==-1&&ch[0]!=-1){\n                do_receive();\n                act[0]+=\"Q\";for(int i=1;i<N;i++)act[i]+=\".\";\n                grid[cr[0]][cc[0]]=ch[0];ch[0]=-1;\n                do_dispatch();T++;\n                \n                if(cr[0]==best_tr&&cc[0]==N-1){\n                    // dispatched!\n                    next_disp[best_tr]++;\n                }\n            }\n        }\n    }\n    \n    // Pad all actions to same length\n    int maxlen=0;\n    for(int i=0;i<N;i++)maxlen=max(maxlen,(int)act[i].size());\n    for(int i=0;i<N;i++)while((int)act[i].size()<maxlen)act[i]+=\".\";\n    \n    for(int i=0;i<N;i++)cout<<act[i]<<\"\\n\";\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\nint cx, cy, load_amt;\nvector<string> ops;\n\nvoid move_to(int tx, int ty) {\n    while (cy > ty) { ops.push_back(\"U\"); cy--; }\n    while (cy < ty) { ops.push_back(\"D\"); cy++; }\n    while (cx > tx) { ops.push_back(\"L\"); cx--; }\n    while (cx < tx) { ops.push_back(\"R\"); cx++; }\n}\n\nint dist(int x1, int y1, int x2, int y2) {\n    return abs(x1-x2) + abs(y1-y2);\n}\n\nint main(){\n    scanf(\"%d\", &N);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) scanf(\"%d\",&h[i][j]);\n    \n    cx=0; cy=0; load_amt=0;\n    \n    // Greedy: repeatedly find nearest positive cell, load, find nearest negative cell, unload\n    while(true){\n        // Find nearest positive cell\n        int best_sd = INT_MAX, bsx=-1, bsy=-1;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            if(h[i][j]>0){\n                int d = dist(cx,cy,j,i);\n                if(d < best_sd){ best_sd=d; bsx=j; bsy=i; }\n            }\n        }\n        if(bsx==-1) break;\n        \n        // Move to source\n        move_to(bsx, bsy);\n        int amt = h[bsy][bsx];\n        ops.push_back(\"+\"+to_string(amt));\n        h[bsy][bsx] = 0;\n        load_amt += amt;\n        \n        // Now deliver to nearest negative cells until empty\n        while(load_amt > 0){\n            int best_dd = INT_MAX, bdx=-1, bdy=-1;\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n                if(h[i][j]<0){\n                    int d = dist(cx,cy,j,i);\n                    if(d < best_dd){ best_dd=d; bdx=j; bdy=i; }\n                }\n            }\n            if(bdx==-1) break;\n            move_to(bdx, bdy);\n            int unload = min(load_amt, -h[bdy][bdx]);\n            ops.push_back(\"-\"+to_string(unload));\n            h[bdy][bdx] += unload;\n            load_amt -= unload;\n        }\n    }\n    \n    for(auto& s : ops) printf(\"%s\\n\", s.c_str());\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,T;\n    cin>>N>>M>>T;\n    int SC=2*N*(N-1);\n    vector<vector<int>>X(SC,vector<int>(M));\n    for(int i=0;i<SC;i++) for(int j=0;j<M;j++) cin>>X[i][j];\n    \n    mt19937 rng(42);\n    \n    for(int t=0;t<T;t++){\n        // Select top 36 seeds by value\n        vector<int> vals(SC);\n        for(int i=0;i<SC;i++) for(int j=0;j<M;j++) vals[i]+=X[i][j];\n        vector<int> idx(SC); iota(idx.begin(),idx.end(),0);\n        sort(idx.begin(),idx.end(),[&](int a,int b){return vals[a]>vals[b];});\n        \n        vector<int> sel(idx.begin(),idx.begin()+N*N);\n        // grid assignment: SA to maximize sum over edges of sum_l max(x[a][l],x[b][l])\n        vector<int> perm(N*N); iota(perm.begin(),perm.end(),0);\n        auto score=[&](vector<int>&p)->long long{\n            long long s=0;\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n                int a=sel[p[i*N+j]];\n                if(j+1<N){int b=sel[p[i*N+j+1]];for(int l=0;l<M;l++) s+=max(X[a][l],X[b][l]);}\n                if(i+1<N){int b=sel[p[(i+1)*N+j]];for(int l=0;l<M;l++) s+=max(X[a][l],X[b][l]);}\n            }\n            return s;\n        };\n        long long cs=score(perm);\n        auto st=chrono::steady_clock::now();\n        for(int it=0;it<200000;it++){\n            int a=rng()%(N*N),b=rng()%(N*N);\n            if(a==b) continue;\n            swap(perm[a],perm[b]);\n            long long ns=score(perm);\n            double temp=100.0*(1.0-it/200000.0)+0.1;\n            if(ns>=cs||rng()%10000<10000*exp((ns-cs)/temp)){cs=ns;}\n            else swap(perm[a],perm[b]);\n        }\n        for(int i=0;i<N;i++){for(int j=0;j<N;j++){if(j) cout<<' ';cout<<sel[perm[i*N+j]];}cout<<'\\n';}\n        cout.flush();\n        for(int i=0;i<SC;i++) for(int j=0;j<M;j++) cin>>X[i][j];\n    }\n}","ahc038":"#include<bits/stdc++.h>\nusing namespace std;\nint main(){\n    int N,M,V;scanf(\"%d%d%d\",&N,&M,&V);\n    vector<string>s(N),t(N);\n    for(int i=0;i<N;i++)cin>>s[i];\n    for(int i=0;i<N;i++)cin>>t[i];\n    vector<pair<int,int>>src,tgt;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(s[i][j]=='1'&&t[i][j]=='0')src.push_back({i,j});\n        if(s[i][j]=='0'&&t[i][j]=='1')tgt.push_back({i,j});\n    }\n    printf(\"2\\n0 1\\n0 0\\n\");\n    int rx=0,ry=0,dir=0;\n    int dx[]={0,1,0,-1},dy[]={1,0,-1,0};\n    char DS[]=\"RDLU\";\n    vector<string>ops;\n    auto rot=[&](int nd){while(dir!=nd){int r=(nd-dir+4)%4;if(r<=2){ops.push_back(string(\".R..\"));dir=(dir+1)%4;}else{ops.push_back(string(\".L..\"));dir=(dir+3)%4;}}};\n    auto mv=[&](int gx,int gy){while(rx<gx){ops.push_back(string(1,'D')+\"...\");rx++;}while(rx>gx){ops.push_back(string(1,'U')+\"...\");rx--;}while(ry<gy){ops.push_back(string(1,'R')+\"...\");ry++;}while(ry>gy){ops.push_back(string(1,'L')+\"...\");ry--;}};\n    auto pickup=[&](){ops.push_back(\"..\" \".P\");};\n    vector<bool>used(src.size());\n    for(int i=0;i<(int)tgt.size()&&i<(int)src.size();i++){\n        int best=-1,bd=1e9;for(int j=0;j<(int)src.size();j++)if(!used[j]){int d=abs(src[j].first-rx)+abs(src[j].second-ry);if(d<bd){bd=d;best=j;}}\n        used[best]=true;auto[sx,sy]=src[best];auto[tx,ty]=tgt[i];\n        int nd=0;for(int d=0;d<4;d++){int px=sx-dx[d],py=sy-dy[d];if(px>=0&&px<N&&py>=0&&py<N){nd=d;break;}}\n        rot(nd);mv(sx-dx[nd],sy-dy[nd]);pickup();\n        nd=0;for(int d=0;d<4;d++){int px=tx-dx[d],py=ty-dy[d];if(px>=0&&px<N&&py>=0&&py<N){nd=d;break;}}\n        rot(nd);mv(tx-dx[nd],ty-dy[nd]);pickup();\n    }\n    for(auto&o:ops)printf(\"%s\\n\",o.c_str());\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N; cin>>N;\n    vector<int> x(2*N), y(2*N);\n    for(int i=0;i<2*N;i++) cin>>x[i]>>y[i];\n    \n    // mackerels: 0..N-1, sardines: N..2N-1\n    // Try grid-based Kadane's approach\n    const int G = 300; // grid size\n    const int MX = 100000;\n    double step = (double)MX / G;\n    \n    // val[gx][gy] = mackerels - sardines in cell [gx, gx+1) x [gy, gy+1)\n    vector<vector<int>> val(G+1, vector<int>(G+1, 0));\n    for(int i=0;i<2*N;i++){\n        int gx = min((int)(x[i]/step), G-1);\n        int gy = min((int)(y[i]/step), G-1);\n        val[gx][gy] += (i < N) ? 1 : -1;\n    }\n    \n    int best = INT_MIN, bx1=0,bx2=G-1,by1=0,by2=G-1;\n    for(int lx=0;lx<G;lx++){\n        vector<int> colsum(G,0);\n        for(int rx=lx;rx<G;rx++){\n            for(int gy=0;gy<G;gy++) colsum[gy]+=val[rx][gy];\n            // Kadane on colsum\n            int cur=0, start=0;\n            for(int gy=0;gy<G;gy++){\n                cur+=colsum[gy];\n                if(cur>best){best=cur;bx1=lx;bx2=rx;by1=start;by2=gy;}\n                if(cur<0){cur=0;start=gy+1;}\n            }\n        }\n    }\n    \n    int ax1=max(0,(int)(bx1*step)-1), ax2=min(MX,(int)((bx2+1)*step)+1);\n    int ay1=max(0,(int)(by1*step)-1), ay2=min(MX,(int)((by2+1)*step)+1);\n    \n    cout<<4<<\"\\n\";\n    cout<<ax1<<\" \"<<ay1<<\"\\n\";\n    cout<<ax2<<\" \"<<ay1<<\"\\n\";\n    cout<<ax2<<\" \"<<ay2<<\"\\n\";\n    cout<<ax1<<\" \"<<ay2<<\"\\n\";\n}","ahc040":"#include<bits/stdc++.h>\nusing namespace std;\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    int N,T,sigma;\n    cin>>N>>T>>sigma;\n    vector<long long>w(N),h(N);\n    for(int i=0;i<N;i++)cin>>w[i]>>h[i];\n    mt19937 rng(12345);\n    for(int t=0;t<T;t++){\n        vector<tuple<int,int,char,int>>ops;\n        for(int i=0;i<N;i++){\n            int rot=rng()%2;\n            if(i==0){ops.push_back({i,rot,'U',-1});}\n            else{\n                int ref=rng()%i;\n                char d=(rng()%2)?'U':'L';\n                ops.push_back({i,rot,d,ref});\n            }\n        }\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 W,H;cin>>W>>H;\n    }\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    \n    vector<int> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\n    \n    vector<vector<int>> adj(N);\n    for(int i=0;i<M;i++){\n        int u,v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++) cin >> x[i] >> y[i];\n    \n    // State: parent[v], depth[v]\n    vector<int> par(N, -1), dep(N, 0);\n    vector<vector<int>> children(N);\n    \n    auto calc_score = [&]() -> long long {\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    \n    // Greedy: sort vertices by beauty descending, try to place them deep\n    // BFS tree building from low-beauty roots\n    \n    // Sort vertices by A ascending (low beauty = good root candidates)\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){ return A[a] < A[b]; });\n    \n    vector<bool> used(N, false);\n    \n    for(int r : order){\n        if(used[r]) continue;\n        used[r] = true;\n        par[r] = -1; dep[r] = 0;\n        queue<int> q;\n        q.push(r);\n        while(!q.empty()){\n            int u = q.front(); q.pop();\n            if(dep[u] >= H) continue;\n            // Sort neighbors by A descending\n            vector<int> nbrs;\n            for(int v : adj[u]) if(!used[v]) nbrs.push_back(v);\n            sort(nbrs.begin(), nbrs.end(), [&](int a, int b){ return A[a] > A[b]; });\n            for(int v : nbrs){\n                if(used[v]) continue;\n                used[v] = true;\n                par[v] = u;\n                dep[v] = dep[u]+1;\n                children[u].push_back(v);\n                q.push(v);\n            }\n        }\n    }\n    \n    // Local search: try reparenting\n    auto get_subtree = [&](int v, auto& self) -> vector<int> {\n        vector<int> res = {v};\n        for(int c : children[v]){\n            auto sub = self(c, self);\n            res.insert(res.end(), sub.begin(), sub.end());\n        }\n        return res;\n    };\n    \n    auto update_depths = [&](int v, int d, auto& self) -> void {\n        dep[v] = d;\n        for(int c : children[v]) self(c, d+1, self);\n    };\n    \n    auto detach = [&](int v){\n        int p = par[v];\n        if(p == -1) return;\n        auto& ch = children[p];\n        ch.erase(find(ch.begin(), ch.end(), v));\n        par[v] = -1;\n        update_depths(v, 0, update_depths);\n    };\n    \n    auto max_depth_subtree = [&](int v, auto& self) -> int {\n        int mx = dep[v];\n        for(int c : children[v]) mx = max(mx, self(c, self));\n        return mx;\n    };\n    \n    auto subtree_score = [&](int v, auto& self) -> long long {\n        long long s = (long long)(dep[v]+1)*A[v];\n        for(int c : children[v]) s += self(c, self);\n        return s;\n    };\n    \n    // Build adjacency set for O(1) lookup\n    vector<set<int>> adjset(N);\n    for(int i=0;i<N;i++) for(int j : adj[i]) adjset[i].insert(j);\n    \n    long long best_score = calc_score();\n    vector<int> best_par = par;\n    \n    mt19937 rng(42);\n    \n    auto try_reparent = [&](int v, int new_par) -> long long {\n        // Check edge exists\n        if(!adjset[v].count(new_par)) return -1;\n        // Check new_par is not in subtree of v\n        int tmp = new_par;\n        while(tmp != -1){\n            if(tmp == v) return -1;\n            tmp = par[tmp];\n        }\n        // Check depth constraint\n        int subtree_depth = max_depth_subtree(v, max_depth_subtree) - dep[v];\n        int new_dep = dep[new_par] + 1;\n        if(new_dep + subtree_depth > H) return -1;\n        \n        long long old_sub = subtree_score(v, subtree_score);\n        // New score change\n        int depth_change = new_dep - dep[v];\n        // Calculate new subtree score\n        auto calc_delta = [&](int u, int dd, auto& self) -> long long {\n            long long d = (long long)dd * A[u];\n            for(int c : children[u]) d += self(c, dd, self);\n            return d;\n        };\n        long long delta = calc_delta(v, depth_change, calc_delta);\n        return delta;\n    };\n    \n    auto do_reparent = [&](int v, int new_par){\n        detach(v);\n        par[v] = new_par;\n        children[new_par].push_back(v);\n        int new_dep = dep[new_par] + 1;\n        int dd = new_dep - dep[v];\n        // Fix: dep[v] is already 0 after detach, recalculate\n        update_depths(v, new_dep, update_depths);\n    };\n    \n    // Simulated annealing\n    auto start_time = chrono::steady_clock::now();\n    double time_limit = 1.9;\n    long long cur_score = best_score;\n    \n    for(int iter = 0; ; iter++){\n        if(iter % 1000 == 0){\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if(elapsed > time_limit) break;\n        }\n        \n        int v = rng() % N;\n        // Try reparenting v to a random neighbor\n        if(adj[v].empty()) continue;\n        int ni = rng() % adj[v].size();\n        int new_p = adj[v][ni];\n        \n        long long delta = try_reparent(v, new_p);\n        if(delta > 0 || (delta == 0 && (int)(rng()%2)==0)){\n            int old_par = par[v];\n            do_reparent(v, new_p);\n            cur_score = calc_score();\n            if(cur_score > best_score){\n                best_score = cur_score;\n                best_par = par;\n            }\n        }\n    }\n    \n    for(int i=0;i<N;i++){\n        cout << best_par[i];\n        if(i<N-1) cout << ' ';\n    }\n    cout << '\\n';\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N;\n    cin>>N;\n    vector<string> board(N);\n    for(int i=0;i<N;i++) cin>>board[i];\n    \n    // For each oni, find valid directions and costs\n    struct Oni { int r,c; };\n    vector<Oni> onis;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(board[i][j]=='x') onis.push_back({i,j});\n    \n    // For each oni, find best direction considering grouping\n    // Group by (direction, line_index)\n    // direction: U->col, D->col, L->row, R->row\n    // cost of group = 2*(max_dist+1)\n    \n    // Use greedy: assign each oni to best group\n    // key: (dir, line), value: list of onis, max_dist\n    // Try all 4 directions, pick assignment minimizing total ops\n    \n    // Simple approach: for each oni pick cheapest valid direction\n    vector<tuple<char,int,int>> ops; // dir, index, count\n    \n    // Group approach with DP is complex; let's use the simple per-oni approach with best direction\n    vector<pair<string,int>> result;\n    \n    for(auto&o:onis){\n        int r=o.r, c=o.c;\n        // Check 4 directions\n        struct Option{ char d; int line; int dist; };\n        vector<Option> opts;\n        auto clear=[&](char d)->bool{\n            if(d=='U'){ for(int i=0;i<r;i++) if(board[i][c]=='o') return false; return true; }\n            if(d=='D'){ for(int i=r+1;i<N;i++) if(board[i][c]=='o') return false; return true; }\n            if(d=='L'){ for(int j=0;j<c;j++) if(board[r][j]=='o') return false; return true; }\n            if(d=='R'){ for(int j=c+1;j<N;j++) if(board[r][j]=='o') return false; return true; }\n            return false;\n        };\n        if(clear('U')) opts.push_back({'U',c,r+1});\n        if(clear('D')) opts.push_back({'D',c,N-r});\n        if(clear('L')) opts.push_back({'L',r,c+1});\n        if(clear('R')) opts.push_back({'R',r,N-c});\n        sort(opts.begin(),opts.end(),[](auto&a,auto&b){return a.dist<b.dist;});\n        auto&best=opts[0];\n        char fd=best.d, rd=(fd=='U'?'D':fd=='D'?'U':fd=='L'?'R':'L');\n        for(int k=0;k<best.dist;k++) result.push_back({string(1,fd),best.line});\n        for(int k=0;k<best.dist;k++) result.push_back({string(1,rd),best.line});\n    }\n    for(auto&[d,p]:result) cout<<d<<\" \"<<p<<\"\\n\";\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N, L;\n    scanf(\"%d%d\", &N, &L);\n    vector<int> T(N);\n    for(int i=0;i<N;i++) scanf(\"%d\", &T[i]);\n    \n    vector<int> a(N), b(N);\n    \n    // Initialize randomly weighted by T\n    mt19937 rng(42);\n    \n    auto pick = [&]() -> int {\n        int r = rng() % L;\n        int s = 0;\n        for(int i=0;i<N;i++){s+=T[i]; if(r<s) return i;}\n        return N-1;\n    };\n    \n    for(int i=0;i<N;i++){a[i]=pick(); b[i]=pick();}\n    \n    auto simulate = [&](vector<int>& cnt) -> long long {\n        cnt.assign(N, 0);\n        vector<int> vis(N, 0);\n        int x = 0;\n        for(int w=0;w<L;w++){\n            cnt[x]++;\n            vis[x]++;\n            int t = vis[x];\n            x = (t%2==1) ? a[x] : b[x];\n        }\n        long long err = 0;\n        for(int i=0;i<N;i++) err += abs(cnt[i]-T[i]);\n        return err;\n    };\n    \n    vector<int> cnt;\n    long long bestErr = simulate(cnt);\n    vector<int> bestA=a, bestB=b;\n    \n    auto start = chrono::steady_clock::now();\n    double timeLimit = 1.9;\n    \n    for(int iter=0;;iter++){\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now-start).count();\n        if(elapsed > timeLimit) break;\n        double temp = 10.0 * (1.0 - elapsed/timeLimit) + 0.1;\n        \n        int i = rng() % N;\n        int which = rng() % 2;\n        int oldVal = which ? b[i] : a[i];\n        int newVal = pick();\n        if(which) b[i]=newVal; else a[i]=newVal;\n        \n        vector<int> cnt2;\n        long long err2 = simulate(cnt2);\n        double delta = err2 - bestErr;\n        if(delta < 0 || (rng()%1000000) < 1000000*exp(-delta/temp)){\n            bestErr = err2; bestA=a; bestB=b;\n        } else {\n            if(which) b[i]=oldVal; else a[i]=oldVal;\n            a=bestA; b=bestB;\n        }\n    }\n    \n    a=bestA; b=bestB;\n    for(int i=0;i<N;i++) printf(\"%d %d\\n\", a[i], b[i]);\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M,Q,L,W;\n    cin>>N>>M>>Q>>L>>W;\n    vector<int> G(M);\n    for(auto &g:G) cin>>g;\n    vector<int> lx(N),rx(N),ly(N),ry(N);\n    for(int i=0;i<N;i++) cin>>lx[i]>>rx[i]>>ly[i]>>ry[i];\n    \n    vector<double> cx(N),cy(N);\n    for(int i=0;i<N;i++){\n        cx[i]=(lx[i]+rx[i])/2.0;\n        cy[i]=(ly[i]+ry[i])/2.0;\n    }\n    \n    // Build MST on estimated positions to get a good global structure\n    // Then partition the MST into groups\n    \n    // Greedy clustering: sort groups by size descending, pick cluster centers\n    // Use a simpler approach: build full MST, then cut largest edges to form M components of right sizes\n    \n    // Actually, let's do a nearest-neighbor grouping\n    // Sort cities spatially and assign greedily\n    \n    // First, let's try to use queries wisely\n    // We'll do clustering first, then use queries within clusters\n    \n    auto edist = [&](int a, int b) -> double {\n        double dx=cx[a]-cx[b], dy=cy[a]-cy[b];\n        return sqrt(dx*dx+dy*dy);\n    };\n    \n    // K-means style clustering based on group sizes\n    // Sort groups descending by size, greedily assign nearest unassigned cities\n    \n    // Use a priority-queue based approach: \n    // 1. Pick M seed cities spread out (farthest-first traversal)\n    // 2. Assign cities to nearest seed, respecting group sizes\n    \n    // Pair group indices with sizes, sort descending\n    vector<int> gidx(M);\n    iota(gidx.begin(),gidx.end(),0);\n    \n    // Farthest-first traversal for seeds\n    vector<int> seeds(M);\n    vector<bool> used(N,false);\n    seeds[0]=0;\n    used[0]=true;\n    vector<double> minD(N,1e18);\n    for(int i=1;i<M;i++){\n        int prev=seeds[i-1];\n        for(int j=0;j<N;j++) if(!used[j]){\n            minD[j]=min(minD[j],edist(prev,j));\n        }\n        int best=-1;\n        for(int j=0;j<N;j++) if(!used[j]){\n            if(best<0||minD[j]>minD[best]) best=j;\n        }\n        seeds[i]=best;\n        used[best]=true;\n    }\n    \n    // Assign cities to groups greedily\n    // Sort groups by size descending for assignment\n    vector<vector<int>> groups(M);\n    vector<int> cap(M);\n    for(int i=0;i<M;i++) cap[i]=G[i];\n    \n    // For each seed, add it to its group\n    fill(used.begin(),used.end(),false);\n    for(int i=0;i<M;i++){\n        groups[i].push_back(seeds[i]);\n        cap[i]--;\n        used[seeds[i]]=true;\n    }\n    \n    // Priority queue: (distance, city, group)\n    using T=tuple<double,int,int>;\n    priority_queue<T,vector<T>,greater<T>> pq;\n    for(int i=0;i<M;i++){\n        for(int j=0;j<N;j++) if(!used[j]){\n            pq.push({edist(seeds[i],j),j,i});\n        }\n    }\n    \n    while(!pq.empty()){\n        auto [d,c,g]=pq.top(); pq.pop();\n        if(used[c]||cap[g]<=0) continue;\n        groups[g].push_back(c);\n        cap[g]--;\n        used[c]=true;\n        if(cap[g]>0){\n            for(int j=0;j<N;j++) if(!used[j]){\n                pq.push({edist(c,j),j,g});\n            }\n        }\n    }\n    \n    // Now use queries within each group to find good MST edges\n    // Store known edges with true MST structure\n    // For each group, query subsets of size L\n    \n    int queriesLeft=Q;\n    // Collect MST edges from queries\n    // edges[group] = list of (u,v) pairs from oracle\n    vector<set<pair<int,int>>> knownEdges(M);\n    \n    for(int g=0;g<M;g++){\n        int sz=groups[g].size();\n        if(sz<=1) continue;\n        \n        // Allocate queries proportional to group size\n        // But be smart: query sliding windows of L cities sorted by position\n        auto &grp=groups[g];\n        // Sort group cities by estimated position\n        sort(grp.begin(),grp.end(),[&](int a,int b){\n            if(cx[a]!=cx[b]) return cx[a]<cx[b];\n            return cy[a]<cy[b];\n        });\n        \n        // Query windows of size L with stride L/2\n        int stride=max(1,L-1);\n        for(int i=0;i+1<sz&&queriesLeft>0;i+=stride){\n            int end=min(i+L,sz);\n            if(end-i<2) break;\n            vector<int> subset(grp.begin()+i,grp.begin()+end);\n            cout<<\"? \"<<subset.size();\n            for(int c:subset) cout<<\" \"<<c;\n            cout<<\"\\n\"<<flush;\n            queriesLeft--;\n            for(int e=0;e<(int)subset.size()-1;e++){\n                int a,b; cin>>a>>b;\n                if(a>b) swap(a,b);\n                knownEdges[g].insert({a,b});\n            }\n        }\n    }\n    \n    // Build spanning tree for each group using known edges first, then estimated\n    cout<<\"!\"<<endl;\n    \n    for(int g=0;g<M;g++){\n        auto &grp=groups[g];\n        int sz=grp.size();\n        for(int c:grp) cout<<c<<\" \\n\"[c==grp.back()];\n        \n        if(sz<=1) continue;\n        \n        // Kruskal: known edges first (weight 0 priority), then estimated\n        map<int,int> id;\n        for(int i=0;i<sz;i++) id[grp[i]]=i;\n        \n        vector<int> par(sz);\n        iota(par.begin(),par.end(),0);\n        function<int(int)> find=[&](int x)->int{return par[x]==x?x:par[x]=find(par[x]);};\n        \n        vector<tuple<double,int,int>> edges;\n        for(auto [a,b]:knownEdges[g]){\n            if(id.count(a)&&id.count(b))\n                edges.push_back({-1,id[a],id[b]}); // priority\n        }\n        for(int i=0;i<sz;i++)\n            for(int j=i+1;j<sz;j++)\n                edges.push_back({edist(grp[i],grp[j]),i,j});\n        \n        sort(edges.begin(),edges.end());\n        \n        vector<pair<int,int>> tree;\n        for(auto [w,i,j]:edges){\n            int fi=find(i),fj=find(j);\n            if(fi!=fj){\n                par[fi]=fj;\n                tree.push_back({grp[i],grp[j]});\n                if((int)tree.size()==sz-1) break;\n            }\n        }\n        for(auto [a,b]:tree) cout<<a<<\" \"<<b<<\"\\n\";\n    }\n    cout<<flush;\n    return 0;\n}","ahc046":"#include<bits/stdc++.h>\nusing namespace std;\nint main(){\n    int N,M;\n    scanf(\"%d%d\",&N,&M);\n    vector<int>ti(M),tj(M);\n    for(int k=0;k<M;k++)scanf(\"%d%d\",&ti[k],&tj[k]);\n    int ci=ti[0],cj=tj[0];\n    vector<vector<bool>>block(N,vector<bool>(N,false));\n    vector<string>actions;\n    int dx[]={-1,1,0,0},dy[]={0,0,-1,1};\n    char dc[]={'U','D','L','R'};\n    for(int k=1;k<M;k++){\n        int gi=ti[k],gj=tj[k];\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        vector<vector<int>>pdir(N,vector<int>(N,-1));\n        queue<pair<int,int>>q;\n        dist[ci][cj]=0;q.push({ci,cj});\n        while(!q.empty()){\n            auto[x,y]=q.front();q.pop();\n            if(x==gi&&y==gj)break;\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&&!block[nx][ny]&&dist[nx][ny]<0){\n                    dist[nx][ny]=dist[x][y]+1;par[nx][ny]={x,y};pdir[nx][ny]=d;q.push({nx,ny});\n                }\n            }\n        }\n        vector<int>path;\n        int x=gi,y=gj;\n        while(x!=ci||y!=cj){int d=pdir[x][y];path.push_back(d);auto[px,py]=par[x][y];x=px;y=py;}\n        reverse(path.begin(),path.end());\n        for(int d:path){string s=\"M \";s+=dc[d];actions.push_back(s);}\n        ci=gi;cj=gj;\n    }\n    for(auto&s:actions)printf(\"%s\\n\",s.c_str());\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    vector<int> x(n), y(n);\n    vector<long long> r(n);\n    for(int i=0;i<n;i++) cin >> x[i] >> y[i] >> r[i];\n    \n    // Rectangle: a,b,c,d where a<c, b<d\n    vector<int> a(n),b(n),c(n),d(n);\n    for(int i=0;i<n;i++){\n        a[i]=x[i]; b[i]=y[i]; c[i]=x[i]+1; d[i]=y[i]+1;\n    }\n    \n    auto intersects = [&](int i, int j) -> bool {\n        return a[i]<c[j] && a[j]<c[i] && b[i]<d[j] && b[j]<d[i];\n    };\n    \n    auto canExpand = [&](int i, int na, int nb, int nc, int nd) -> bool {\n        if(na<0||nb<0||nc>10000||nd>10000||na>=nc||nb>=nd) return false;\n        for(int j=0;j<n;j++){\n            if(j==i) continue;\n            if(na<c[j] && a[j]<nc && nb<d[j] && b[j]<nd) return false;\n        }\n        return true;\n    };\n    \n    auto area = [&](int i) -> long long {\n        return (long long)(c[i]-a[i])*(d[i]-b[i]);\n    };\n    \n    auto score = [&](int i) -> double {\n        long long s = area(i);\n        double ratio = min(r[i],s)*1.0/max(r[i],s);\n        return 1.0 - (1.0-ratio)*(1.0-ratio);\n    };\n    \n    // Greedy expansion with random direction attempts\n    mt19937 rng(42);\n    auto start = chrono::steady_clock::now();\n    \n    while(true){\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now-start).count();\n        if(elapsed > 4.5) break;\n        \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 i : order){\n            long long s = area(i);\n            if(s >= r[i]) continue;\n            double curScore = score(i);\n            \n            // Try 4 directions: expand left, right, up, down\n            int dirs[4][4];\n            // left: a-step\n            int step = max(1, (int)min((long long)100, (r[i]-s)/max(1LL,(long long)(d[i]-b[i]))));\n            dirs[0][0]=a[i]-step; dirs[0][1]=b[i]; dirs[0][2]=c[i]; dirs[0][3]=d[i];\n            dirs[1][0]=a[i]; dirs[1][1]=b[i]; dirs[1][2]=c[i]+step; dirs[1][3]=d[i];\n            dirs[2][0]=a[i]; dirs[2][1]=b[i]-step; dirs[2][2]=c[i]; dirs[2][3]=d[i];\n            dirs[3][0]=a[i]; dirs[3][1]=b[i]; dirs[3][2]=c[i]; dirs[3][3]=d[i]+step;\n            \n            int bestDir = -1; double bestScore = curScore;\n            for(int dd=0;dd<4;dd++){\n                if(canExpand(i, dirs[dd][0], dirs[dd][1], dirs[dd][2], dirs[dd][3])){\n                    long long ns = (long long)(dirs[dd][2]-dirs[dd][0])*(dirs[dd][3]-dirs[dd][1]);\n                    double rat = min(r[i],ns)*1.0/max(r[i],ns);\n                    double sc = 1.0-(1.0-rat)*(1.0-rat);\n                    if(sc > bestScore){ bestScore=sc; bestDir=dd; }\n                }\n            }\n            if(bestDir>=0){\n                a[i]=dirs[bestDir][0]; b[i]=dirs[bestDir][1];\n                c[i]=dirs[bestDir][2]; d[i]=dirs[bestDir][3];\n                improved=true;\n            }\n        }\n        if(!improved) break;\n    }\n    \n    for(int i=0;i<n;i++) cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint t[50][50], p[50][50];\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\nchar dc[]={'U','D','L','R'};\n\nint main(){\n    int si,sj;\n    scanf(\"%d%d\",&si,&sj);\n    for(int i=0;i<50;i++) for(int j=0;j<50;j++) scanf(\"%d\",&t[i][j]);\n    for(int i=0;i<50;i++) for(int j=0;j<50;j++) scanf(\"%d\",&p[i][j]);\n    \n    int M=0;\n    for(int i=0;i<50;i++) for(int j=0;j<50;j++) M=max(M,t[i][j]+1);\n    \n    // Parent-based path storage\n    struct Node {\n        int parent;\n        char dir;\n    };\n    vector<Node> tree;\n    tree.reserve(5000000);\n    \n    struct State {\n        int x,y,score;\n        bitset<2500> used;\n        int nodeIdx; // index in tree\n    };\n    \n    auto getPath = [&](int idx) -> string {\n        string s;\n        while(idx > 0) {\n            s += tree[idx].dir;\n            idx = tree[idx].parent;\n        }\n        reverse(s.begin(), s.end());\n        return s;\n    };\n    \n    tree.push_back({-1, ' '}); // root node (index 0)\n    \n    int beamWidth = 300;\n    \n    vector<State> beam(1);\n    beam[0].x=si; beam[0].y=sj; beam[0].score=p[si][sj];\n    beam[0].used.reset();\n    beam[0].used.set(t[si][sj]);\n    beam[0].nodeIdx=0;\n    \n    int bestScore=beam[0].score;\n    int bestNode=0;\n    \n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(1850);\n    \n    for(int step=0; step<2500 && !beam.empty(); step++){\n        if(step % 50 == 0 && chrono::steady_clock::now()>deadline) break;\n        \n        vector<State> next;\n        next.reserve(beam.size()*4);\n        \n        for(auto &s: beam){\n            for(int d=0;d<4;d++){\n                int nx=s.x+dx[d], ny=s.y+dy[d];\n                if(nx<0||nx>=50||ny<0||ny>=50) continue;\n                int tid=t[nx][ny];\n                if(s.used.test(tid)) continue;\n                \n                int ni = (int)tree.size();\n                tree.push_back({s.nodeIdx, dc[d]});\n                \n                State ns;\n                ns.x=nx; ns.y=ny;\n                ns.score=s.score+p[nx][ny];\n                ns.used=s.used;\n                ns.used.set(tid);\n                ns.nodeIdx=ni;\n                next.push_back(move(ns));\n            }\n        }\n        if(next.empty()) break;\n        \n        if((int)next.size()>beamWidth){\n            nth_element(next.begin(), next.begin()+beamWidth, next.end(),\n                [](const State&a, const State&b){return a.score>b.score;});\n            next.resize(beamWidth);\n        }\n        \n        for(auto &s: next){\n            if(s.score>bestScore){bestScore=s.score; bestNode=s.nodeIdx;}\n        }\n        beam=move(next);\n    }\n    \n    string ans = getPath(bestNode);\n    printf(\"%s\\n\", ans.c_str());\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\nconst int N = 30;\ndouble h[N][N-1], v[N-1][N];\nint cnt_h[N][N-1], cnt_v[N-1][N];\ndouble sum_h[N][N-1], sum_v[N-1][N]; // sum of observed per-edge estimates\n\nint idx(int i,int j){return i*N+j;}\nchar dirs[]=\"UDLR\";\nint di[]={-1,1,0,0}, dj[]={0,0,-1,1};\n\nstruct Edge { int type; int ei, ej; };\n\ndouble getW(int type, int ci, int cj) {\n    if(type==0) return v[ci-1][cj];\n    if(type==1) return v[ci][cj];\n    if(type==2) return h[ci][cj-1];\n    return h[ci][cj];\n}\n\npair<string, vector<Edge>> dijkstra(int si,int sj,int ti,int tj){\n    vector<double> dist(N*N,1e18);\n    vector<int> pn(N*N,-1), pd(N*N,-1);\n    priority_queue<pair<double,int>,vector<pair<double,int>>,greater<>> pq;\n    int s=idx(si,sj), t=idx(ti,tj);\n    dist[s]=0; pq.push({0,s});\n    while(!pq.empty()){\n        auto[d,u]=pq.top();pq.pop();\n        if(d>dist[u])continue;\n        int ci=u/N,cj=u%N;\n        for(int dir=0;dir<4;dir++){\n            int ni=ci+di[dir],nj=cj+dj[dir];\n            if(ni<0||ni>=N||nj<0||nj>=N)continue;\n            double w=getW(dir,ci,cj);\n            int nv=idx(ni,nj);\n            if(dist[u]+w<dist[nv]){dist[nv]=dist[u]+w;pn[nv]=u;pd[nv]=dir;pq.push({dist[nv],nv});}\n        }\n    }\n    string ans; vector<Edge> edges;\n    int cur=t;\n    vector<pair<int,int>> path;\n    while(cur!=s){path.push_back({pn[cur],pd[cur]});cur=pn[cur];}\n    reverse(path.begin(),path.end());\n    for(auto[node,dir]:path){\n        ans+=dirs[dir];\n        int ci=node/N,cj=node%N;\n        Edge e;e.type=dir;\n        if(dir==0){e.ei=ci-1;e.ej=cj;}\n        else if(dir==1){e.ei=ci;e.ej=cj;}\n        else if(dir==2){e.ei=ci;e.ej=cj-1;}\n        else{e.ei=ci;e.ej=cj;}\n        edges.push_back(e);\n    }\n    return {ans,edges};\n}\n\nint main(){\n    for(int i=0;i<N;i++)for(int j=0;j<N-1;j++){h[i][j]=5000;cnt_h[i][j]=0;}\n    for(int i=0;i<N-1;i++)for(int j=0;j<N;j++){v[i][j]=5000;cnt_v[i][j]=0;}\n    for(int q=0;q<1000;q++){\n        int si,sj,ti,tj;scanf(\"%d%d%d%d\",&si,&sj,&ti,&tj);\n        auto[ans,edges]=dijkstra(si,sj,ti,tj);\n        printf(\"%s\\n\",ans.c_str());fflush(stdout);\n        int obs;scanf(\"%d\",&obs);\n        double est=0;\n        for(auto&e:edges){\n            if(e.type<=1)est+=v[e.ei][e.ej];\n            else est+=h[e.ei][e.ej];\n        }\n        double ratio=(double)obs/est;\n        for(auto&e:edges){\n            double lr;\n            if(e.type<=1){int c=cnt_v[e.ei][e.ej];lr=1.0/(c+2);cnt_v[e.ei][e.ej]++;v[e.ei][e.ej]*=(1.0-lr)+lr*ratio;}\n            else{int c=cnt_h[e.ei][e.ej];lr=1.0/(c+2);cnt_h[e.ei][e.ej]++;h[e.ei][e.ej]*=(1.0-lr)+lr*ratio;}\n        }\n    }\n}","ahc004":"#include<bits/stdc++.h>\nusing namespace std;\nint main(){\n    ios::sync_with_stdio(0);cin.tie(0);\n    int N,M; cin>>N>>M;\n    vector<string> S(M);\n    for(int i=0;i<M;i++) cin>>S[i];\n    \n    mt19937 rng(42);\n    char G[20][20];\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) G[i][j]='A'+rng()%8;\n    \n    // placement = (string_idx, dir, i, j)\n    // For each cell, list of placement indices that use it\n    struct Placement { int s,d,i,j; };\n    vector<Placement> placements;\n    vector<vector<int>> cell2pl(400);\n    \n    for(int s=0;s<M;s++){\n        int k=S[s].size();\n        for(int d=0;d<2;d++) for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            int pidx=placements.size();\n            placements.push_back({s,d,i,j});\n            for(int p=0;p<k;p++){\n                int ci,cj;\n                if(d==0){ci=i;cj=(j+p)%N;}\n                else{ci=(i+p)%N;cj=j;}\n                cell2pl[ci*N+cj].push_back(pidx);\n            }\n        }\n    }\n    \n    int P=placements.size();\n    vector<int> pl_ok(P);\n    vector<int> str_cnt(M,0); // how many placements match for each string\n    \n    auto checkPl=[&](int pidx)->int{\n        auto&pl=placements[pidx];\n        int k=S[pl.s].size();\n        for(int p=0;p<k;p++){\n            int ci,cj;\n            if(pl.d==0){ci=pl.i;cj=(pl.j+p)%N;}\n            else{ci=(pl.i+p)%N;cj=pl.j;}\n            if(G[ci][cj]!=S[pl.s][p]) return 0;\n        }\n        return 1;\n    };\n    \n    for(int p=0;p<P;p++){\n        pl_ok[p]=checkPl(p);\n        if(pl_ok[p]) str_cnt[placements[p].s]++;\n    }\n    int tot=0;\n    for(int s=0;s<M;s++) if(str_cnt[s]>0) tot++;\n    \n    auto t0=chrono::steady_clock::now();\n    \n    while(true){\n        auto now=chrono::steady_clock::now();\n        if(chrono::duration<double>(now-t0).count()>2.6) break;\n        \n        for(int rep=0;rep<200;rep++){\n            int ci=rng()%N, cj=rng()%N;\n            char oc=G[ci][cj], nc='A'+rng()%8;\n            if(nc==oc) continue;\n            \n            auto&aff=cell2pl[ci*N+cj];\n            // Save old state, apply change\n            int delta=0;\n            vector<pair<int,int>> changes;\n            G[ci][cj]=nc;\n            for(int pidx:aff){\n                int nv=checkPl(pidx);\n                if(nv!=pl_ok[pidx]){\n                    int s=placements[pidx].s;\n                    int old_matched=(str_cnt[s]>0);\n                    str_cnt[s]+=nv-pl_ok[pidx];\n                    int new_matched=(str_cnt[s]>0);\n                    delta+=new_matched-old_matched;\n                    changes.push_back({pidx,pl_ok[pidx]});\n                    pl_ok[pidx]=nv;\n                }\n            }\n            if(delta>=0){\n                tot+=delta;\n            } else {\n                G[ci][cj]=oc;\n                for(auto&[pidx,ov]:changes){\n                    str_cnt[placements[pidx].s]+=ov-pl_ok[pidx];\n                    pl_ok[pidx]=ov;\n                }\n            }\n        }\n    }\n    \n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++) cout<<G[i][j];\n        cout<<'\\n';\n    }\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nchar grid[70][70];\nint cost[70][70];\nint dist[70*70][70*70]; // too large, use on-demand Dijkstra\n\nstruct State { int d, i, j; };\n\nvector<pair<int,int>> visible_from[70][70];\nbool seen[70][70];\n\nint encode(int i, int j) { return i*N+j; }\n\nvector<int> dijkstra_path(int si, int sj, int ti, int tj) {\n    vector<vector<int>> d(N, vector<int>(N, INT_MAX));\n    vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N, {-1,-1}));\n    priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n    d[si][sj] = 0;\n    pq.push({0, si, sj});\n    int dx[]={-1,1,0,0}, dy[]={0,0,-1,1};\n    while (!pq.empty()) {\n        auto [dd, ci, cj] = pq.top(); pq.pop();\n        if (dd > d[ci][cj]) continue;\n        if (ci==ti && cj==tj) break;\n        for (int k=0;k<4;k++){\n            int ni=ci+dx[k], nj=cj+dy[k];\n            if (ni<0||ni>=N||nj<0||nj>=N||grid[ni][nj]=='#') continue;\n            int nd = dd + cost[ni][nj];\n            if (nd < d[ni][nj]) { d[ni][nj]=nd; par[ni][nj]={ci,cj}; pq.push({nd,ni,nj}); }\n        }\n    }\n    vector<int> path;\n    if (d[ti][tj]==INT_MAX) return path;\n    int ci=ti, cj=tj;\n    vector<pair<int,int>> pts;\n    while (!(ci==si && cj==sj)) { pts.push_back({ci,cj}); auto [pi,pj]=par[ci][cj]; ci=pi; cj=pj; }\n    pts.push_back({si,sj});\n    reverse(pts.begin(), pts.end());\n    // convert to moves\n    string dirs = \"UDLR\";\n    for (int i=1;i<(int)pts.size();i++){\n        int di=pts[i].first-pts[i-1].first, dj=pts[i].second-pts[i-1].second;\n        if(di==-1) path.push_back(0);\n        else if(di==1) path.push_back(1);\n        else if(dj==-1) path.push_back(2);\n        else path.push_back(3);\n    }\n    return path;\n}\n\nvoid compute_visibility(int i, int j) {\n    if (grid[i][j]=='#') return;\n    visible_from[i][j].push_back({i,j});\n    for (int dj=j-1;dj>=0;dj--){ if(grid[i][dj]=='#') break; visible_from[i][j].push_back({i,dj}); }\n    for (int dj=j+1;dj<N;dj++){ if(grid[i][dj]=='#') break; visible_from[i][j].push_back({i,dj}); }\n    for (int di=i-1;di>=0;di--){ if(grid[di][j]=='#') break; visible_from[i][j].push_back({di,j}); }\n    for (int di=i+1;di<N;di++){ if(grid[di][j]=='#') break; visible_from[i][j].push_back({di,j}); }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> si >> sj;\n    for (int i=0;i<N;i++){\n        string s; cin >> s;\n        for (int j=0;j<N;j++){\n            grid[i][j]=s[j];\n            if (s[j]!='#') cost[i][j]=s[j]-'0';\n        }\n    }\n    for (int i=0;i<N;i++) for (int j=0;j<N;j++) compute_visibility(i,j);\n    \n    memset(seen, false, sizeof(seen));\n    // Mark visible from start\n    int ci=si, cj=sj;\n    for (auto [vi,vj]: visible_from[ci][cj]) seen[vi][vj]=true;\n    \n    int total_road=0;\n    for (int i=0;i<N;i++) for (int j=0;j<N;j++) if(grid[i][j]!='#') total_road++;\n    \n    string result;\n    string dirs = \"UDLR\";\n    int dx[]={-1,1,0,0}, dy[]={0,0,-1,1};\n    \n    auto count_unseen = [&]() {\n        int c=0;\n        for (int i=0;i<N;i++) for (int j=0;j<N;j++) if(grid[i][j]!='#' && !seen[i][j]) c++;\n        return c;\n    };\n    \n    while (count_unseen() > 0) {\n        // Find best target: highest unseen_coverage / distance\n        int bestI=-1, bestJ=-1;\n        double bestScore = -1;\n        \n        // BFS/Dijkstra from current position\n        vector<vector<int>> d(N, vector<int>(N, INT_MAX));\n        vector<vector<pair<int,int>>> par(N, vector<pair<int,int>>(N, {-1,-1}));\n        priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n        d[ci][cj]=0; pq.push({0,ci,cj});\n        while (!pq.empty()){\n            auto [dd,i,j]=pq.top(); pq.pop();\n            if (dd>d[i][j]) continue;\n            for (int k=0;k<4;k++){\n                int ni=i+dx[k],nj=j+dy[k];\n                if(ni<0||ni>=N||nj<0||nj>=N||grid[ni][nj]=='#') continue;\n                int nd=dd+cost[ni][nj];\n                if(nd<d[ni][nj]){d[ni][nj]=nd;par[ni][nj]={i,j};pq.push({nd,ni,nj});}\n            }\n        }\n        \n        for (int i=0;i<N;i++) for (int j=0;j<N;j++) if(grid[i][j]!='#' && d[i][j]<INT_MAX){\n            int unseen_cnt=0;\n            for (auto [vi,vj]: visible_from[i][j]) if(!seen[vi][vj]) unseen_cnt++;\n            if (unseen_cnt==0) continue;\n            double score = (double)unseen_cnt / max(1, d[i][j]);\n            if (score > bestScore){ bestScore=score; bestI=i; bestJ=j; }\n        }\n        \n        if (bestI==-1) break;\n        \n        // Trace path\n        vector<pair<int,int>> pts;\n        int ti=bestI, tj=bestJ;\n        while(!(ti==ci&&tj==cj)){pts.push_back({ti,tj});auto[pi,pj]=par[ti][tj];ti=pi;tj=pj;}\n        reverse(pts.begin(),pts.end());\n        for (auto [pi,pj]: pts){\n            int di=pi-ci, dj=pj-cj;\n            if(di==-1) result+='U'; else if(di==1) result+='D'; else if(dj==-1) result+='L'; else result+='R';\n            ci=pi; cj=pj;\n            for (auto [vi,vj]: visible_from[ci][cj]) seen[vi][vj]=true;\n        }\n    }\n    \n    // Return to start\n    auto path = dijkstra_path(ci, cj, si, sj);\n    for (int m: path) result += dirs[m];\n    \n    cout << result << endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    \n    int N,M,K,R;\n    scanf(\"%d%d%d%d\",&N,&M,&K,&R);\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for(int i=0;i<N;i++) for(int j=0;j<K;j++) scanf(\"%d\",&d[i][j]);\n    \n    vector<vector<int>> deps(N), rdeps(N);\n    for(int i=0;i<R;i++){\n        int u,v; scanf(\"%d%d\",&u,&v); u--;v--;\n        deps[v].push_back(u);\n        rdeps[u].push_back(v);\n    }\n    \n    // Compute longest path from each node to any sink (priority)\n    vector<int> priority(N,0);\n    {\n        vector<int> topo;\n        vector<int> indeg(N,0);\n        for(int i=0;i<N;i++) for(int j:rdeps[i]) indeg[j]++;\n        queue<int> q;\n        for(int i=0;i<N;i++) if(indeg[i]==0) q.push(i);\n        while(!q.empty()){int u=q.front();q.pop();topo.push_back(u);for(int v:rdeps[u])if(--indeg[v]==0)q.push(v);}\n        for(int i=N-1;i>=0;i--){\n            int u=topo[i];\n            priority[u]=0;\n            for(int v:rdeps[u]) priority[u]=max(priority[u],priority[v]+1);\n        }\n    }\n    \n    // Skill estimation\n    vector<vector<double>> s_est(M, vector<double>(K, 15.0)); // initial guess\n    vector<vector<double>> s_low(M, vector<double>(K, 0.0));\n    \n    // State\n    vector<int> task_status(N, -1); // -1=not started, 0=in progress, 1=done\n    vector<int> member_task(M, -1);\n    vector<int> member_start(M, -1);\n    \n    auto est_time = [&](int task, int member) -> double {\n        double w = 0;\n        for(int k=0;k<K;k++) w += max(0.0, d[task][k] - s_est[member][k]);\n        return max(1.0, w);\n    };\n    \n    auto can_start = [&](int task) -> bool {\n        if(task_status[task]!=-1) return false;\n        for(int dep : deps[task]) if(task_status[dep]!=1) return false;\n        return true;\n    };\n    \n    for(int day=1; day<=2000; day++){\n        vector<int> free_members;\n        for(int j=0;j<M;j++) if(member_task[j]==-1) free_members.push_back(j);\n        \n        vector<int> avail_tasks;\n        for(int i=0;i<N;i++) if(can_start(i)) avail_tasks.push_back(i);\n        \n        sort(avail_tasks.begin(), avail_tasks.end(), [&](int a, int b){ return priority[a]>priority[b]; });\n        \n        vector<pair<int,int>> assignments;\n        set<int> used_members;\n        for(int task : avail_tasks){\n            if(used_members.size()==free_members.size()) break;\n            int best_m=-1; double best_t=1e18;\n            for(int j : free_members){\n                if(used_members.count(j)) continue;\n                double t = est_time(task, j);\n                if(t < best_t){ best_t=t; best_m=j; }\n            }\n            if(best_m>=0){\n                assignments.push_back({best_m, task});\n                used_members.insert(best_m);\n                task_status[task]=0;\n                member_task[best_m]=task;\n                member_start[best_m]=day;\n            }\n        }\n        \n        printf(\"%d\", (int)assignments.size());\n        for(auto [a,b]:assignments) printf(\" %d %d\", a+1, b+1);\n        printf(\"\\n\");\n        fflush(stdout);\n        \n        int n_done; scanf(\"%d\",&n_done);\n        if(n_done==-1) return 0;\n        for(int i=0;i<n_done;i++){\n            int f; scanf(\"%d\",&f); f--;\n            int task=member_task[f];\n            int t_obs=day - member_start[f]+1;\n            task_status[task]=1;\n            member_task[f]=-1;\n            \n            if(t_obs==1){\n                for(int k=0;k<K;k++) s_low[f][k]=max(s_low[f][k],(double)d[task][k]);\n            } else {\n                double w_est = t_obs; // w \u2248 t \u00b1 3\n                double w_cur=0;\n                for(int k=0;k<K;k++) w_cur+=max(0.0, d[task][k]-s_est[f][k]);\n                if(w_cur>0){\n                    double ratio = w_est / w_cur;\n                    for(int k=0;k<K;k++){\n                        double gap = d[task][k]-s_est[f][k];\n                        if(gap>0){\n                            double new_s = d[task][k] - gap*ratio;\n                            s_est[f][k] = s_est[f][k]*0.7 + new_s*0.3;\n                        }\n                    }\n                }\n            }\n            for(int k=0;k<K;k++) s_est[f][k]=max(s_est[f][k], s_low[f][k]);\n        }\n    }\n    \n    // Read final -1\n    int dummy; scanf(\"%d\",&dummy);\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto t0=chrono::steady_clock::now();\n    auto elapsed=[&](){return chrono::duration<double>(chrono::steady_clock::now()-t0).count();};\n    \n    int N=1000, M=50;\n    vector<int> a(N),b(N),c(N),d(N);\n    for(int i=0;i<N;i++) cin>>a[i]>>b[i]>>c[i]>>d[i];\n    \n    auto md=[](int x1,int y1,int x2,int y2){return abs(x1-x2)+abs(y1-y2);};\n    \n    // Score orders\n    vector<double> score(N);\n    for(int i=0;i<N;i++){\n        score[i] = md(400,400,a[i],b[i]) + md(a[i],b[i],c[i],d[i]) + md(c[i],d[i],400,400);\n    }\n    vector<int> idx(N);\n    iota(idx.begin(),idx.end(),0);\n    sort(idx.begin(),idx.end(),[&](int i,int j){return score[i]<score[j];});\n    \n    vector<int> chosen(idx.begin(),idx.begin()+M);\n    \n    // Build route with points: depot, pickup_0, delivery_0, ..., pickup_49, delivery_49, depot\n    // Route is a sequence of \"node ids\": node 0..2M-1 where even=pickup, odd=delivery\n    // Plus implicit depot at start and end\n    \n    auto solveRoute=[&](vector<int>& ch, double timeLimit) -> pair<int,vector<int>> {\n        int K=2*M;\n        vector<int> px(K),py(K);\n        for(int i=0;i<M;i++){\n            px[2*i]=a[ch[i]]; py[2*i]=b[ch[i]];\n            px[2*i+1]=c[ch[i]]; py[2*i+1]=d[ch[i]];\n        }\n        \n        // Greedy nearest neighbor\n        vector<int> route;\n        vector<bool> visited(K,false);\n        vector<bool> picked(M,false);\n        int cx=400,cy=400;\n        for(int step=0;step<K;step++){\n            int best=-1, bestd=INT_MAX;\n            for(int j=0;j<K;j++){\n                if(visited[j]) continue;\n                int ord=j/2; bool isDel=(j%2==1);\n                if(isDel && !picked[ord]) continue;\n                int d2=md(cx,cy,px[j],py[j]);\n                if(d2<bestd){bestd=d2;best=j;}\n            }\n            visited[best]=true;\n            if(best%2==0) picked[best/2]=true;\n            route.push_back(best);\n            cx=px[best]; cy=py[best];\n        }\n        \n        // Cost calculation helpers\n        auto getX=[&](int node)->int{ return node<0?400:px[node]; };\n        auto getY=[&](int node)->int{ return node<0?400:py[node]; };\n        auto dist=[&](int u,int v)->int{\n            return abs(getX(u)-getX(v))+abs(getY(u)-getY(v));\n        };\n        \n        auto calcCost=[&](vector<int>& r)->int{\n            int t=dist(-1,r[0]);\n            for(int i=0;i+1<K;i++) t+=dist(r[i],r[i+1]);\n            t+=dist(r.back(),-1);\n            return t;\n        };\n        \n        // Position array for feasibility\n        auto checkFeasible=[&](vector<int>& r)->bool{\n            vector<int> pos(K);\n            for(int i=0;i<K;i++) pos[r[i]]=i;\n            for(int i=0;i<M;i++) if(pos[2*i]>pos[2*i+1]) return false;\n            return true;\n        };\n        \n        int bestCost=calcCost(route);\n        vector<int> bestRoute=route;\n        mt19937 rng(12345);\n        \n        // Or-opt: remove node and reinsert at best position\n        auto tryRelocate=[&]()->bool{\n            int K2=K;\n            for(int ii=0;ii<K2;ii++){\n                int i=rng()%K2;\n                int node=route[i];\n                int ord=node/2;\n                bool isDel=(node%2==1);\n                \n                // Remove node i\n                int prevN=(i==0)?-1:route[i-1];\n                int nextN=(i==K2-1)?-1:route[i+1];\n                int oldCost=dist(prevN,node)+dist(node,nextN);\n                int newLink=dist(prevN,nextN);\n                int saving=oldCost-newLink;\n                \n                // Find best insertion position\n                // Must respect: if pickup, must be before its delivery\n                // If delivery, must be after its pickup\n                vector<int> pos(K);\n                for(int j=0;j<K;j++) pos[route[j]]=j;\n                \n                int lo=0, hi=K2-1;\n                if(isDel){\n                    lo=pos[2*ord]+1; // after pickup (but pickup might shift)\n                } else {\n                    hi=pos[2*ord+1]-1; // before delivery\n                }\n                // Adjust for removal\n                // After removing position i, positions shift\n                // Let's just do it directly\n                vector<int> tmp;\n                tmp.reserve(K2-1);\n                for(int j=0;j<K2;j++) if(j!=i) tmp.push_back(route[j]);\n                \n                // Find partner position in tmp\n                int partner = isDel ? 2*ord : 2*ord+1;\n                int partnerPos=-1;\n                for(int j=0;j<(int)tmp.size();j++) if(tmp[j]==partner) {partnerPos=j;break;}\n                \n                int bestIns=-1, bestDelta=0;\n                int K3=K2-1;\n                for(int j=0;j<=K3;j++){\n                    // Insert before position j means between j-1 and j\n                    if(isDel && j<=partnerPos) continue;\n                    if(!isDel && j>partnerPos) continue;\n                    int pv=(j==0)?-1:tmp[j-1];\n                    int nx=(j==K3)?-1:tmp[j];\n                    int addCost=dist(pv,node)+dist(node,nx)-dist(pv,nx);\n                    int delta=addCost-saving;\n                    if(delta<bestDelta){bestDelta=delta;bestIns=j;}\n                }\n                if(bestIns>=0){\n                    tmp.insert(tmp.begin()+bestIns,node);\n                    route=tmp;\n                    bestCost+=bestDelta;\n                    return true;\n                }\n            }\n            return false;\n        };\n        \n        while(elapsed()<timeLimit){\n            // 2-opt\n            int i=rng()%K, j=rng()%K;\n            if(i>j) swap(i,j); if(i==j) continue;\n            // Delta cost for reversing [i..j]\n            int prevI=(i==0)?-1:route[i-1];\n            int nextJ=(j==K-1)?-1:route[j+1];\n            int oldC=dist(prevI,route[i])+dist(route[j],nextJ);\n            int newC=dist(prevI,route[j])+dist(route[i],nextJ);\n            int delta=newC-oldC;\n            if(delta<0){\n                reverse(route.begin()+i,route.begin()+j+1);\n                if(checkFeasible(route)){bestCost+=delta;}\n                else reverse(route.begin()+i,route.begin()+j+1);\n            }\n            // Occasionally try relocate\n            if(rng()%5==0) tryRelocate();\n        }\n        if(bestCost>calcCost(bestRoute)) return {calcCost(bestRoute),bestRoute};\n        return {bestCost,route};\n    };\n    \n    auto [cost,route]=solveRoute(chosen,1.8);\n    \n    int K=2*M;\n    vector<int> px(K),py(K);\n    for(int i=0;i<M;i++){px[2*i]=a[chosen[i]];py[2*i]=b[chosen[i]];px[2*i+1]=c[chosen[i]];py[2*i+1]=d[chosen[i]];}\n    \n    cout<<M;\n    for(int i=0;i<M;i++) cout<<\" \"<<chosen[i]+1;\n    cout<<\"\\n\";\n    int n=K+2;\n    cout<<n<<\" 400 400\";\n    for(int j=0;j<K;j++) cout<<\" \"<<px[route[j]]<<\" \"<<py[route[j]];\n    cout<<\" 400 400\\n\";\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n): p(n), sz(n,1) { iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a, int b){ a=find(a);b=find(b);if(a==b)return false;if(sz[a]<sz[b])swap(a,b);p[b]=a;sz[a]+=sz[b];return true; }\n    bool same(int a,int b){return find(a)==find(b);}\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    int N=400, M=1995;\n    vector<int> x(N),y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n    vector<int> U(M),V(M);\n    vector<double> D(M);\n    for(int i=0;i<M;i++){\n        cin>>U[i]>>V[i];\n        double dx=x[U[i]]-x[V[i]], dy=y[U[i]]-y[V[i]];\n        D[i]=round(sqrt(dx*dx+dy*dy));\n    }\n    \n    // For each pair of vertices, collect future edge indices\n    // We need to track remaining edges between component pairs\n    DSU dsu(N);\n    int components = N;\n    \n    for(int i=0;i<M;i++){\n        int l; cin>>l;\n        \n        if(dsu.same(U[i],V[i])){\n            cout<<0<<\"\\n\"<<flush;\n            continue;\n        }\n        \n        // Count remaining edges (after this one) that cross between these two components\n        int fu=dsu.find(U[i]), fv=dsu.find(V[i]);\n        int remaining=0;\n        double best_expected=1e18;\n        for(int j=i+1;j<M;j++){\n            int a=dsu.find(U[j]), b=dsu.find(V[j]);\n            if((a==fu&&b==fv)||(a==fv&&b==fu)){\n                remaining++;\n                best_expected=min(best_expected, D[j]*2.0);\n            }\n        }\n        \n        double ratio = (double)l / D[i];\n        // threshold: if few remaining alternatives, accept more readily\n        double threshold;\n        if(remaining==0) threshold=3.01;\n        else if(remaining<=2) threshold=2.2;\n        else if(remaining<=5) threshold=1.8;\n        else threshold=1.5;\n        \n        if(ratio<=threshold || (components==2)){\n            cout<<1<<\"\\n\"<<flush;\n            dsu.unite(U[i],V[i]);\n            components--;\n        } else {\n            cout<<0<<\"\\n\"<<flush;\n        }\n    }\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint px[25], py[25], pt[25];\nint hx[15], hy[15];\nbool wall[35][35];\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dmc[] = {'U','D','L','R'};\nchar dpc[] = {'u','d','l','r'};\n\nbool inBounds(int x, int y) { return x>=1 && x<=30 && y>=1 && y<=30; }\n\nbool petAdjacent(int x, int y) {\n    if (!inBounds(x,y)) return false;\n    for (int i=0;i<N;i++) {\n        if (px[i]==x && py[i]==y) return true;\n        for (int d=0;d<4;d++) {\n            if (px[i]==x+dx[d] && py[i]==y+dy[d]) return true; // wait no, the adjacent check is: can't choose square whose adjacent square contains pet\n        }\n    }\n    // Actually: can't place wall on square that contains pet/human, AND can't place wall on square adjacent to a pet\n    for (int i=0;i<N;i++) {\n        if (abs(px[i]-x)+abs(py[i]-y)<=1) return true;\n    }\n    return false;\n}\n\nbool humanOn(int x, int y) {\n    for (int i=0;i<M;i++) if (hx[i]==x && hy[i]==y) return true;\n    return false;\n}\n\n// BFS to find path from (sx,sy) to (tx,ty) on passable squares\nvector<pair<int,int>> bfsPath(int sx, int sy, int tx, int ty) {\n    if (sx==tx && sy==ty) return {};\n    int prev[31][31][2];\n    memset(prev, -1, sizeof(prev));\n    queue<pair<int,int>> q;\n    q.push({sx,sy});\n    prev[sx][sy][0] = sx; prev[sx][sy][1] = sy;\n    while (!q.empty()) {\n        auto [cx,cy] = q.front(); q.pop();\n        for (int d=0;d<4;d++) {\n            int nx=cx+dx[d], ny=cy+dy[d];\n            if (inBounds(nx,ny) && !wall[nx][ny] && prev[nx][ny][0]==-1) {\n                prev[nx][ny][0]=cx; prev[nx][ny][1]=cy;\n                if (nx==tx && ny==ty) {\n                    vector<pair<int,int>> path;\n                    int x=tx, y=ty;\n                    while (x!=sx || y!=sy) {\n                        path.push_back({x,y});\n                        int px2=prev[x][y][0], py2=prev[x][y][1];\n                        x=px2; y=py2;\n                    }\n                    reverse(path.begin(), path.end());\n                    return path;\n                }\n                q.push({nx,ny});\n            }\n        }\n    }\n    return {};\n}\n\n// Strategy: build walls to create grid partitions\n// Target wall lines: rows 6,7 and 24,25 and cols 6,7 and 24,25 (creating a border)\n// Simpler: each person builds walls greedily around nearest pets\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    for (int i=0;i<N;i++) cin >> px[i] >> py[i] >> pt[i];\n    cin >> M;\n    for (int i=0;i<M;i++) cin >> hx[i] >> hy[i];\n    \n    memset(wall, false, sizeof(wall));\n    \n    // Wall target lines - build walls along certain rows/columns to partition grid\n    // Let's try to build walls to trap pets\n    // Strategy: each person moves toward their assigned wall-building tasks\n    \n    // Simple greedy: each turn, each person tries to place a wall adjacent to them\n    // that is valid (not adjacent to pet), preferring squares that help block pets.\n    // If no good wall placement, move toward a useful position.\n    \n    for (int turn=0; turn<300; turn++) {\n        string actions(M, '.');\n        \n        for (int p=0; p<M; p++) {\n            int bx = hx[p], by = hy[p];\n            \n            // Try to place a wall\n            int bestD = -1;\n            int bestScore = -1;\n            \n            for (int d=0; d<4; d++) {\n                int nx = bx+dx[d], ny = by+dy[d];\n                if (!inBounds(nx,ny)) continue;\n                if (wall[nx][ny]) continue;\n                if (humanOn(nx,ny)) continue;\n                if (petAdjacent(nx,ny)) continue;\n                \n                // Score: prefer squares that help block pets\n                // Count how many pets are \"beyond\" this wall\n                int score = 0;\n                // Prefer placing walls that are between us and pets\n                for (int i=0;i<N;i++) {\n                    int dist_pet = abs(px[i]-nx)+abs(py[i]-ny);\n                    if (dist_pet <= 5) score += (6-dist_pet)*10;\n                }\n                // Prefer walls that extend existing walls (create lines)\n                for (int dd=0;dd<4;dd++) {\n                    int ax=nx+dx[dd], ay=ny+dy[dd];\n                    if (!inBounds(ax,ay) || wall[ax][ay]) score += 5;\n                }\n                \n                if (score > bestScore) {\n                    bestScore = score;\n                    bestD = d;\n                }\n            }\n            \n            if (bestD >= 0 && bestScore > 0) {\n                actions[p] = dpc[bestD];\n            } else {\n                // Move toward nearest pet to build walls near it\n                int bestDist = 1e9;\n                int targetPet = -1;\n                for (int i=0;i<N;i++) {\n                    int d2 = abs(px[i]-bx)+abs(py[i]-by);\n                    if (d2 > 3 && d2 < bestDist) { // not too close\n                        bestDist = d2;\n                        targetPet = i;\n                    }\n                }\n                if (targetPet >= 0) {\n                    auto path = bfsPath(bx, by, px[targetPet], py[targetPet]);\n                    if (path.size() > 1) {\n                        int nx2=path[0].first, ny2=path[0].second;\n                        if (!wall[nx2][ny2]) {\n                            for (int d=0;d<4;d++) {\n                                if (bx+dx[d]==nx2 && by+dy[d]==ny2) {\n                                    actions[p] = dmc[d];\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Apply actions\n        for (int p=0;p<M;p++) {\n            char a = actions[p];\n            for (int d=0;d<4;d++) {\n                if (a==dpc[d]) { int nx=hx[p]+dx[d], ny=hy[p]+dy[d]; if(inBounds(nx,ny)) wall[nx][ny]=true; }\n                if (a==dmc[d]) { hx[p]+=dx[d]; hy[p]+=dy[d]; }\n            }\n        }\n        \n        cout << actions << \"\\n\";\n        cout.flush();\n        \n        // Read pet movements\n        for (int i=0;i<N;i++) {\n            string s; cin >> s;\n            for (char c : s) {\n                for (int d=0;d<4;d++) if (c==dmc[d]) { px[i]+=dx[d]; py[i]+=dy[d]; }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int si,sj,ti,tj;\n    double p;\n    scanf(\"%d%d%d%d%lf\",&si,&sj,&ti,&tj,&p);\n    \n    bool hwall[20][19], vwall[19][20];\n    for(int i=0;i<20;i++){\n        char s[25]; scanf(\"%s\",s);\n        for(int j=0;j<19;j++) hwall[i][j]=(s[j]=='1');\n    }\n    for(int i=0;i<19;i++){\n        char s[25]; scanf(\"%s\",s);\n        for(int j=0;j<20;j++) vwall[i][j]=(s[j]=='1');\n    }\n    \n    // BFS shortest path\n    int dist[20][20]; memset(dist,-1,sizeof(dist));\n    int prev_dir[20][20]; memset(prev_dir,-1,sizeof(prev_dir));\n    pair<int,int> par[20][20];\n    queue<pair<int,int>> Q;\n    dist[si][sj]=0; Q.push({si,sj});\n    int di[]={-1,1,0,0}, dj[]={0,0,-1,1}; // U D L R\n    while(!Q.empty()){\n        auto [ci,cj]=Q.front(); Q.pop();\n        for(int d=0;d<4;d++){\n            int ni=ci+di[d], nj=cj+dj[d];\n            if(ni<0||ni>=20||nj<0||nj>=20) continue;\n            if(d==0&&vwall[ni][nj]) continue;\n            if(d==1&&vwall[ci][cj]) continue;\n            if(d==2&&hwall[ci][nj]) continue;\n            if(d==3&&hwall[ci][cj]) continue;\n            if(dist[ni][nj]>=0) continue;\n            dist[ni][nj]=dist[ci][cj]+1;\n            prev_dir[ni][nj]=d; par[ni][nj]={ci,cj};\n            Q.push({ni,nj});\n        }\n    }\n    \n    string path;\n    int ci=ti,cj=tj;\n    while(ci!=si||cj!=sj){\n        path+=\"UDLR\"[prev_dir[ci][cj]];\n        tie(ci,cj)=par[ci][cj];\n    }\n    reverse(path.begin(),path.end());\n    \n    int L=path.size();\n    int k=min(200/L, 200/L); // max repetition\n    \n    string best;\n    for(int rep=1; rep<=k && rep*L<=200; rep++){\n        string s;\n        for(char c:path) for(int r=0;r<rep;r++) s+=c;\n        if(s.size()<=200 && (best.empty() || true)) best=s;\n    }\n    // Try all valid k, pick best by simulation\n    // For simplicity, use k = 200/L\n    string ans;\n    for(char c:path) for(int r=0;r<k;r++) ans+=c;\n    printf(\"%s\\n\",ans.c_str());\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\nconst int N=30;\nint tiles[N][N],orig[N][N],rot[N][N],best_rot[N][N];\nint di[]={0,-1,0,1},dj[]={-1,0,1,0};\nint to_dir[8][4]={{1,0,-1,-1},{3,-1,-1,0},{-1,-1,3,2},{-1,2,1,-1},{1,0,3,2},{3,2,1,0},{2,-1,0,-1},{-1,3,-1,1}};\n\nint rotate_tile(int t,int r){for(int k=0;k<r;k++){if(t<4)t=(t+1)%4;else if(t==4)t=5;else if(t==5)t=4;else if(t==6)t=7;else t=6;}return t;}\n\nlong long calc_score(){\n    vector<int> lens;\n    bool vis[N][N][4]={};\n    for(int si=0;si<N;si++)for(int sj=0;sj<N;sj++)for(int sd=0;sd<4;sd++){\n        if(vis[si][sj][sd])continue;\n        int i=si,j=sj,d=sd,len=0;bool ok=true;\n        do{\n            int d2=to_dir[tiles[i][j]][d];\n            if(d2<0){ok=false;break;}\n            i+=di[d2];j+=dj[d2];\n            if(i<0||i>=N||j<0||j>=N){ok=false;break;}\n            d=(d2+2)%4;len++;\n            vis[i][j][d]=true;\n        }while(!(i==si&&j==sj&&d==sd));\n        if(ok&&len>0)lens.push_back(len);\n    }\n    sort(lens.rbegin(),lens.rend());\n    if(lens.size()<2)return 0;\n    return(long long)lens[0]*lens[1];\n}\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(0);\n    for(int i=0;i<N;i++){string s;cin>>s;for(int j=0;j<N;j++)orig[i][j]=s[j]-'0';}\n    // Greedy init: try each rotation, pick best local connectivity\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){tiles[i][j]=orig[i][j];rot[i][j]=0;}\n    long long best_score=calc_score();\n    memcpy(best_rot,rot,sizeof(rot));\n    mt19937 rng(123);\n    auto start=chrono::steady_clock::now();\n    double timelimit=1.9;\n    long long cur_score=best_score;\n    for(long long iter=0;;iter++){\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-start).count();\n        if(elapsed>timelimit)break;\n        double T=5000.0*(1.0-elapsed/timelimit)+0.1;\n        // Pick 1-3 random tiles to change\n        int nc=1+(rng()%100<10?1:0);\n        int ci[3],cj[3],or_[3],ot[3],nr[3];\n        for(int k=0;k<nc;k++){\n            ci[k]=rng()%N;cj[k]=rng()%N;\n            or_[k]=rot[ci[k]][cj[k]];ot[k]=tiles[ci[k]][cj[k]];\n            nr[k]=(or_[k]+1+rng()%3)%4;\n            rot[ci[k]][cj[k]]=nr[k];\n            tiles[ci[k]][cj[k]]=rotate_tile(orig[ci[k]][cj[k]],nr[k]);\n        }\n        long long ns=calc_score();\n        if(ns>=cur_score||(double)(rng()%1000000)/1000000.0<exp((double)(ns-cur_score)/T)){\n            cur_score=ns;\n            if(ns>best_score){best_score=ns;memcpy(best_rot,rot,sizeof(rot));}\n        }else{\n            for(int k=0;k<nc;k++){rot[ci[k]][cj[k]]=or_[k];tiles[ci[k]][cj[k]]=ot[k];}\n        }\n    }\n    string ans(900,'0');\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)ans[i*30+j]='0'+best_rot[i][j];\n    cout<<ans<<endl;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N,T;\nint board[10][10];\nint ei,ej;\nint di[]={-1,1,0,0},dj[]={0,0,-1,1};\nint opp[]={1,0,3,2};\nconst char* dirs=\"UDLR\";\n\nint largest_tree(){\n    int id[10][10],cnt=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(board[i][j])id[i][j]=cnt++;else id[i][j]=-1;\n    vector<vector<int>>adj(cnt);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(!board[i][j])continue;\n        if(i+1<N&&board[i+1][j]&&(board[i][j]&8)&&(board[i+1][j]&2)){adj[id[i][j]].push_back(id[i+1][j]);adj[id[i+1][j]].push_back(id[i][j]);}\n        if(j+1<N&&board[i][j+1]&&(board[i][j]&4)&&(board[i][j+1]&1)){adj[id[i][j]].push_back(id[i][j+1]);adj[id[i][j+1]].push_back(id[i][j]);}\n    }\n    vector<bool>vis(cnt,false);\n    int best=0;\n    for(int s=0;s<cnt;s++)if(!vis[s]){\n        queue<int>q;q.push(s);vis[s]=true;\n        vector<int>comp;int edg=0;\n        while(!q.empty()){int u=q.front();q.pop();comp.push_back(u);for(int v:adj[u]){edg++;if(!vis[v]){vis[v]=true;q.push(v);}}}\n        edg/=2;\n        if(edg==(int)comp.size()-1)best=max(best,(int)comp.size());\n    }\n    return best;\n}\n\nint main(){\n    scanf(\"%d%d\",&N,&T);\n    for(int i=0;i<N;i++){char s[20];scanf(\"%s\",s);for(int j=0;j<N;j++){char c=s[j];board[i][j]=(c>='a'?c-'a'+10:c-'0');if(!board[i][j]){ei=i;ej=j;}}}\n    \n    string ans;\n    mt19937 rng(12345);\n    int cur=largest_tree();\n    int bestScore=cur;\n    string bestAns;\n    int bestBoard[10][10];int bestEi=ei,bestEj=ej;\n    memcpy(bestBoard,board,sizeof(board));\n    int lastDir=-1;\n    \n    auto start=chrono::steady_clock::now();\n    double timeLimit=2.7;\n    \n    while((int)ans.size()<T){\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-start).count();\n        if(elapsed>timeLimit)break;\n        double temp=max(0.1, 5.0*(1.0-elapsed/timeLimit));\n        \n        vector<int>cands;\n        for(int d=0;d<4;d++){\n            if(d==lastDir)continue;// avoid reversal (opp of last would undo)\n            if(lastDir>=0&&d==opp[lastDir])continue;\n            int ni=ei+di[d],nj=ej+dj[d];\n            if(ni>=0&&ni<N&&nj>=0&&nj<N)cands.push_back(d);\n        }\n        if(cands.empty())for(int d=0;d<4;d++){int ni=ei+di[d],nj=ej+dj[d];if(ni>=0&&ni<N&&nj>=0&&nj<N)cands.push_back(d);}\n        \n        int d=cands[rng()%cands.size()];\n        int ni=ei+di[d],nj=ej+dj[d];\n        swap(board[ei][ej],board[ni][nj]);\n        int nv=largest_tree();\n        double delta=nv-cur;\n        if(delta>=0||uniform_real_distribution<>(0,1)(rng)<exp(delta/temp)){\n            ei=ni;ej=nj;ans+=dirs[d];cur=nv;lastDir=d;\n            if(cur>bestScore){bestScore=cur;bestAns=ans;memcpy(bestBoard,board,sizeof(board));bestEi=ei;bestEj=ej;}\n            if(cur==N*N-1)break;\n        }else{\n            swap(board[ei][ej],board[ni][nj]);\n        }\n    }\n    if(bestScore>largest_tree()||true){\n        // Use best found\n        memcpy(board,bestBoard,sizeof(board));\n        printf(\"%s\\n\",bestAns.empty()?\"U\":bestAns.c_str());\n    }else printf(\"%s\\n\",ans.empty()?\"U\":ans.c_str());\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    for(int d=1;d<=10;d++) cin >> a[d];\n    vector<long long> sx(N), sy(N);\n    for(int i=0;i<N;i++) cin >> sx[i] >> sy[i];\n    \n    mt19937 rng(42);\n    int num_lines = min(K, 100);\n    \n    // For each line and each point, store the sign (+1 or -1, 0 = on line)\n    // Use random hash per line per side to compute region hash\n    vector<array<long long,4>> lines(num_lines);\n    vector<uint64_t> hash_pos(num_lines), hash_neg(num_lines);\n    for(int j=0;j<num_lines;j++){\n        hash_pos[j] = rng() | 1ULL;\n        hash_neg[j] = rng() | 1ULL;\n    }\n    \n    // signs[i][j]: sign of point i w.r.t. line j\n    vector<vector<int8_t>> signs(N, vector<int8_t>(num_lines));\n    vector<uint64_t> phash(N, 0);\n    vector<bool> on_any(N, false);\n    \n    auto compute_sign = [&](int i, int j) -> int8_t {\n        long long dx = lines[j][2]-lines[j][0], dy = lines[j][3]-lines[j][1];\n        long long cross = dx*(sy[i]-lines[j][1]) - dy*(sx[i]-lines[j][0]);\n        if(cross > 0) return 1;\n        if(cross < 0) return -1;\n        return 0;\n    };\n    \n    auto rebuild_hashes = [&](){\n        for(int i=0;i<N;i++){\n            phash[i] = 0;\n            on_any[i] = false;\n            for(int j=0;j<num_lines;j++){\n                signs[i][j] = compute_sign(i, j);\n                if(signs[i][j] == 0) on_any[i] = true;\n                else if(signs[i][j] > 0) phash[i] ^= hash_pos[j];\n                else phash[i] ^= hash_neg[j];\n            }\n        }\n    };\n    \n    auto calc_score = [&]() -> int {\n        unordered_map<uint64_t, int> regions;\n        regions.reserve(N*2);\n        for(int i=0;i<N;i++){\n            if(!on_any[i]) regions[phash[i]]++;\n        }\n        int score = 0;\n        vector<int> bd(11,0);\n        for(auto&[k,v]:regions) if(v>=1&&v<=10) bd[v]++;\n        for(int d=1;d<=10;d++) score += min(a[d], bd[d]);\n        return score;\n    };\n    \n    auto randline = [&]() -> array<long long,4> {\n        long long px = (rng()%20001)-10000, py = (rng()%20001)-10000;\n        long long qx = (rng()%20001)-10000, qy = (rng()%20001)-10000;\n        while(px==qx && py==qy){ qx=(rng()%20001)-10000; qy=(rng()%20001)-10000; }\n        return {px,py,qx,qy};\n    };\n    \n    for(int j=0;j<num_lines;j++) lines[j] = randline();\n    rebuild_hashes();\n    \n    int best_score = calc_score();\n    auto best_lines = lines;\n    \n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    while(true){\n        if((++iter & 63) == 0){\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n            if(elapsed > 2.85) break;\n        }\n        int idx = rng() % num_lines;\n        auto old_line = lines[idx];\n        vector<int8_t> old_signs(N);\n        vector<uint64_t> old_phash(N);\n        vector<bool> old_on(N);\n        \n        lines[idx] = randline();\n        for(int i=0;i<N;i++){\n            old_signs[i] = signs[i][idx];\n            old_phash[i] = phash[i];\n            old_on[i] = on_any[i];\n            // remove old contribution\n            if(old_signs[i] > 0) phash[i] ^= hash_pos[idx];\n            else if(old_signs[i] < 0) phash[i] ^= hash_neg[idx];\n            // compute new\n            signs[i][idx] = compute_sign(i, idx);\n            if(signs[i][idx] == 0){ on_any[i] = true; }\n            else {\n                if(old_signs[i] == 0){\n                    // recheck on_any\n                    on_any[i] = false;\n                    for(int j=0;j<num_lines;j++) if(signs[i][j]==0){on_any[i]=true;break;}\n                }\n                if(signs[i][idx] > 0) phash[i] ^= hash_pos[idx];\n                else phash[i] ^= hash_neg[idx];\n            }\n        }\n        int sc = calc_score();\n        if(sc >= best_score){\n            best_score = sc;\n            best_lines = lines;\n        } else {\n            // revert\n            lines[idx] = old_line;\n            for(int i=0;i<N;i++){\n                signs[i][idx] = old_signs[i];\n                phash[i] = old_phash[i];\n                on_any[i] = old_on[i];\n            }\n        }\n    }\n    \n    cout << best_lines.size() << \"\\n\";\n    for(auto& l : best_lines)\n        cout << l[0] << \" \" << l[1] << \" \" << l[2] << \" \" << l[3] << \"\\n\";\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nbool dot_grid[62][62];\nset<tuple<int,int,int,int>> used_segs;\n\nauto norm_seg(int x1,int y1,int x2,int y2){\n    if(make_pair(x1,y1)>make_pair(x2,y2)){swap(x1,x2);swap(y1,y2);}\n    return make_tuple(x1,y1,x2,y2);\n}\n\nbool in_bounds(int x,int y){return x>=0&&y>=0&&x<N&&y<N;}\n\n// Get interior points of segment (excluding endpoints)\nvector<pair<int,int>> seg_interior(int x1,int y1,int x2,int y2){\n    vector<pair<int,int>> pts;\n    int dx=x2-x1, dy=y2-y1;\n    int g=__gcd(abs(dx),abs(dy));\n    if(g<=1) return pts;\n    int sx=dx/g, sy=dy/g;\n    for(int i=1;i<g;i++) pts.push_back({x1+sx*i,y1+sy*i});\n    return pts;\n}\n\n// Get unit segments of a side\nvector<tuple<int,int,int,int>> side_units(int x1,int y1,int x2,int y2){\n    vector<tuple<int,int,int,int>> res;\n    int dx=x2-x1, dy=y2-y1;\n    int g=__gcd(abs(dx),abs(dy));\n    if(g==0) return res;\n    int sx=dx/g, sy=dy/g;\n    for(int i=0;i<g;i++)\n        res.push_back(norm_seg(x1+sx*i,y1+sy*i,x1+sx*(i+1),y1+sy*(i+1)));\n    return res;\n}\n\nstruct Op { int x1,y1,x2,y2,x3,y3,x4,y4; };\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin>>N>>M;\n    memset(dot_grid,0,sizeof(dot_grid));\n    for(int i=0;i<M;i++){\n        int x,y; cin>>x>>y;\n        dot_grid[x][y]=true;\n    }\n    \n    double c=(N-1)/2.0;\n    auto weight=[&](int x,int y)->double{\n        return (x-c)*(x-c)+(y-c)*(y-c)+1;\n    };\n    \n    vector<Op> ops;\n    auto start=chrono::steady_clock::now();\n    \n    // Directions for rectangle sides: axis-aligned and 45-degree\n    // (dx,dy) and perpendicular (px,py)\n    // For axis-aligned: (1,0)&(0,1), etc.\n    // For 45-degree: (1,1)&(1,-1), etc.\n    struct RectType { int dx,dy,px,py; };\n    vector<RectType> rect_types;\n    // axis-aligned\n    rect_types.push_back({1,0,0,1});\n    rect_types.push_back({1,0,0,-1});\n    rect_types.push_back({0,1,1,0});\n    rect_types.push_back({0,1,-1,0});\n    // 45-degree\n    rect_types.push_back({1,1,1,-1});\n    rect_types.push_back({1,1,-1,1});\n    rect_types.push_back({1,-1,1,1});\n    rect_types.push_back({1,-1,-1,-1});\n    \n    bool changed = true;\n    while(changed && chrono::duration<double>(chrono::steady_clock::now()-start).count()<4.3){\n        changed = false;\n        \n        // Collect all candidates\n        struct Cand {\n            double w;\n            Op op;\n            vector<tuple<int,int,int,int>> segs;\n        };\n        vector<Cand> cands;\n        \n        for(auto& rt : rect_types){\n            for(int len1=1; len1<=N; len1++){\n                for(int len2=1; len2<=N; len2++){\n                    int ddx=rt.dx*len1, ddy=rt.dy*len1;\n                    int ppx=rt.px*len2, ppy=rt.py*len2;\n                    \n                    for(int ax=0;ax<N;ax++) for(int ay=0;ay<N;ay++){\n                        if(!dot_grid[ax][ay]) continue;\n                        // A = (ax,ay), B = A + (ddx,ddy), C = B + (ppx,ppy), D = A + (ppx,ppy)\n                        int bx=ax+ddx,by=ay+ddy;\n                        int dx_=ax+ppx,dy_=ay+ppy;\n                        int cx=bx+ppx,cy=by+ppy;\n                        \n                        if(!in_bounds(bx,by)||!in_bounds(cx,cy)||!in_bounds(dx_,dy_)) continue;\n                        \n                        // Count how many corners have dots, exactly one must not\n                        int has[4]={dot_grid[ax][ay],dot_grid[bx][by],dot_grid[cx][cy],dot_grid[dx_][dy_]};\n                        int cnt=has[0]+has[1]+has[2]+has[3];\n                        if(cnt!=3) continue;\n                        \n                        // Find the one without dot\n                        int pts[4][2]={{ax,ay},{bx,by},{cx,cy},{dx_,dy_}};\n                        int ni=-1;\n                        for(int i=0;i<4;i++) if(!has[i]){ni=i;break;}\n                        \n                        // p1=new, then p2,p3,p4 = next vertices in order\n                        int p1x=pts[ni][0], p1y=pts[ni][1];\n                        int p2x=pts[(ni+1)%4][0], p2y=pts[(ni+1)%4][1];\n                        int p3x=pts[(ni+2)%4][0], p3y=pts[(ni+2)%4][1];\n                        int p4x=pts[(ni+3)%4][0], p4y=pts[(ni+3)%4][1];\n                        \n                        // Check no dots on perimeter (interior of sides)\n                        bool ok=true;\n                        int sides[4][4]={{p1x,p1y,p2x,p2y},{p2x,p2y,p3x,p3y},{p3x,p3y,p4x,p4y},{p4x,p4y,p1x,p1y}};\n                        for(int i=0;i<4&&ok;i++){\n                            auto inter=seg_interior(sides[i][0],sides[i][1],sides[i][2],sides[i][3]);\n                            for(auto&[px,py]:inter){\n                                if(in_bounds(px,py)&&dot_grid[px][py]){ok=false;break;}\n                            }\n                        }\n                        if(!ok) continue;\n                        \n                        // Get unit segments, check overlap\n                        vector<tuple<int,int,int,int>> all_segs;\n                        for(int i=0;i<4;i++){\n                            auto us=side_units(sides[i][0],sides[i][1],sides[i][2],sides[i][3]);\n                            for(auto&s:us) all_segs.push_back(s);\n                        }\n                        bool seg_ok=true;\n                        for(auto&s:all_segs) if(used_segs.count(s)){seg_ok=false;break;}\n                        if(!seg_ok) continue;\n                        \n                        cands.push_back({weight(p1x,p1y),{p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y},all_segs});\n                    }\n                    if(chrono::duration<double>(chrono::steady_clock::now()-start).count()>4.3) goto done_collect;\n                }\n            }\n        }\n        done_collect:\n        \n        // Sort by weight descending\n        sort(cands.begin(),cands.end(),[](auto&a,auto&b){return a.w>b.w;});\n        \n        for(auto& cd : cands){\n            auto& op=cd.op;\n            if(dot_grid[op.x1][op.y1]) continue;\n            if(!dot_grid[op.x2][op.y2]||!dot_grid[op.x3][op.y3]||!dot_grid[op.x4][op.y4]) continue;\n            \n            // Recheck perimeter dots and segments\n            int sides[4][4]={{op.x1,op.y1,op.x2,op.y2},{op.x2,op.y2,op.x3,op.y3},{op.x3,op.y3,op.x4,op.y4},{op.x4,op.y4,op.x1,op.y1}};\n            bool ok=true;\n            set<pair<int,int>> corners={{op.x1,op.y1},{op.x2,op.y2},{op.x3,op.y3},{op.x4,op.y4}};\n            for(int i=0;i<4&&ok;i++){\n                auto inter=seg_interior(sides[i][0],sides[i][1],sides[i][2],sides[i][3]);\n                for(auto&[px,py]:inter) if(in_bounds(px,py)&&dot_grid[px][py]){ok=false;break;}\n            }\n            if(!ok) continue;\n            bool seg_ok=true;\n            for(auto&s:cd.segs) if(used_segs.count(s)){seg_ok=false;break;}\n            if(!seg_ok) continue;\n            \n            dot_grid[op.x1][op.y1]=true;\n            for(auto&s:cd.segs) used_segs.insert(s);\n            ops.push_back(op);\n            changed=true;\n        }\n    }\n    \n    cout<<ops.size()<<\"\\n\";\n    for(auto&op:ops){\n        cout<<op.x1<<\" \"<<op.y1<<\" \"<<op.x2<<\" \"<<op.y2<<\" \"<<op.x3<<\" \"<<op.y3<<\" \"<<op.x4<<\" \"<<op.y4<<\"\\n\";\n    }\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nint grid[10][10];\n\nvoid tilt(int g[10][10], char dir) {\n    if (dir == 'F') {\n        for (int c = 0; c < 10; c++) { int pos = 0; for (int r = 0; r < 10; r++) if (g[r][c]) { if(pos!=r){g[pos][c]=g[r][c];g[r][c]=0;} pos++; } }\n    } else if (dir == 'B') {\n        for (int c = 0; c < 10; c++) { int pos = 9; for (int r = 9; r >= 0; r--) if (g[r][c]) { if(pos!=r){g[pos][c]=g[r][c];g[r][c]=0;} pos--; } }\n    } else if (dir == 'L') {\n        for (int r = 0; r < 10; r++) { int pos = 0; for (int c = 0; c < 10; c++) if (g[r][c]) { if(pos!=c){g[r][pos]=g[r][c];g[r][c]=0;} pos++; } }\n    } else {\n        for (int r = 0; r < 10; r++) { int pos = 9; for (int c = 9; c >= 0; c--) if (g[r][c]) { if(pos!=c){g[r][pos]=g[r][c];g[r][c]=0;} pos--; } }\n    }\n}\n\nint connectivity(int g[10][10]) {\n    bool vis[10][10]={};\n    int score=0;\n    int dx[]={0,0,1,-1}, dy[]={1,-1,0,0};\n    for(int i=0;i<10;i++) for(int j=0;j<10;j++) if(g[i][j]&&!vis[i][j]){\n        int fl=g[i][j], cnt=0;\n        queue<pair<int,int>> q; q.push({i,j}); vis[i][j]=1;\n        while(!q.empty()){auto[r,c]=q.front();q.pop();cnt++;\n            for(int d=0;d<4;d++){int nr=r+dx[d],nc=c+dy[d];\n                if(nr>=0&&nr<10&&nc>=0&&nc<10&&!vis[nr][nc]&&g[nr][nc]==fl){vis[nr][nc]=1;q.push({nr,nc});}}}\n        score+=cnt*cnt;\n    }\n    return score;\n}\n\n// Target centers for 3 regions - several layouts to try\n// Layout: 3 horizontal bands, 3 vertical bands, 3 corners, etc.\nstruct Layout {\n    double tr[4], tc[4]; // target row, col for flavor 1,2,3 (index 1-3)\n};\n\ndouble distScore(int g[10][10], const Layout& lay) {\n    double s = 0;\n    for (int r = 0; r < 10; r++) for (int c = 0; c < 10; c++) if (g[r][c]) {\n        int f = g[r][c];\n        double dr = r - lay.tr[f], dc = c - lay.tc[f];\n        s -= (dr*dr + dc*dc);\n    }\n    return s;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    int f[100]; for(int i=0;i<100;i++) cin>>f[i];\n    memset(grid,0,sizeof(grid));\n    \n    // Try multiple region assignments\n    // Regions: top-left(2,2), top-right(2,7), bottom-center(7,4.5)\n    // Also try horizontal bands and vertical bands\n    vector<Layout> layouts;\n    double centers[3][2] = {{1.5,4.5},{4.5,0.5},{7.5,8.0}};\n    // Generate all 6 permutations of flavor-to-region\n    int perm[3] = {0,1,2};\n    do {\n        Layout lay;\n        for(int i=0;i<3;i++){lay.tr[i+1]=centers[perm[i]][0];lay.tc[i+1]=centers[perm[i]][1];}\n        layouts.push_back(lay);\n    } while(next_permutation(perm,perm+3));\n    \n    // More region configs\n    double c2[3][2] = {{4.5,1.0},{4.5,4.5},{4.5,8.0}}; // 3 vertical bands\n    perm[0]=0;perm[1]=1;perm[2]=2;\n    do {\n        Layout lay;\n        for(int i=0;i<3;i++){lay.tr[i+1]=c2[perm[i]][0];lay.tc[i+1]=c2[perm[i]][1];}\n        layouts.push_back(lay);\n    } while(next_permutation(perm,perm+3));\n    \n    double c3[3][2] = {{1.0,4.5},{4.5,4.5},{8.0,4.5}}; // 3 horizontal bands\n    perm[0]=0;perm[1]=1;perm[2]=2;\n    do {\n        Layout lay;\n        for(int i=0;i<3;i++){lay.tr[i+1]=c3[perm[i]][0];lay.tc[i+1]=c3[perm[i]][1];}\n        layouts.push_back(lay);\n    } while(next_permutation(perm,perm+3));\n    \n    double c4[3][2] = {{1.5,1.5},{1.5,7.5},{8.0,4.5}}; // 2 top corners + bottom\n    perm[0]=0;perm[1]=1;perm[2]=2;\n    do {\n        Layout lay;\n        for(int i=0;i<3;i++){lay.tr[i+1]=c4[perm[i]][0];lay.tc[i+1]=c4[perm[i]][1];}\n        layouts.push_back(lay);\n    } while(next_permutation(perm,perm+3));\n    \n    string dirs=\"FBLR\";\n    \n    // We'll track best layout dynamically\n    for(int t=0;t<100;t++){\n        int p; cin>>p; p--;\n        int cnt=0,pr=-1,pc=-1;\n        for(int r=0;r<10;r++) for(int c=0;c<10;c++) if(!grid[r][c]){if(cnt==p){pr=r;pc=c;} cnt++;}\n        grid[pr][pc]=f[t];\n        \n        double progress = (t+1)/100.0;\n        double alpha = 2.0 + 18.0 * progress; // connectivity weight grows\n        double beta = 1.0 * (1.0 - progress * 0.5); // distance weight shrinks\n        \n        double bestVal = -1e18;\n        char bestd = 'F';\n        \n        for(char d:dirs){\n            int tmp[10][10]; memcpy(tmp,grid,sizeof(grid));\n            tilt(tmp,d);\n            int conn = connectivity(tmp);\n            \n            // Find best layout for this tilt\n            double bestLayout = -1e18;\n            for(auto& lay : layouts){\n                double ds = distScore(tmp, lay);\n                double val = alpha * conn + beta * ds;\n                bestLayout = max(bestLayout, val);\n            }\n            if(bestLayout > bestVal){bestVal=bestLayout; bestd=d;}\n        }\n        tilt(grid,bestd);\n        cout<<bestd<<\"\\n\"<<flush;\n    }\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M; double eps;\n    cin >> M >> eps;\n    \n    // Choose N based on M and eps\n    int N;\n    if(eps <= 0.01) N = max(4, (int)ceil(sqrt(2.0*M))+2);\n    else if(eps <= 0.1) N = min(100, max(10, (int)(1.5*sqrt(M))+5));\n    else if(eps <= 0.2) N = min(100, max(15, (int)(2.0*sqrt(M))+8));\n    else if(eps <= 0.3) N = min(100, max(25, (int)(3.0*sqrt(M))+10));\n    else N = min(100, max(35, (int)(4.0*sqrt(M))+15));\n    \n    N = min(N, 100);\n    N = max(N, 4);\n    \n    int E = N*(N-1)/2;\n    \n    // Generate M graphs with well-separated edge densities\n    // Graph k has approximately k*(E)/(M-1) edges if M>1\n    // But we want well-separated degree sequences\n    \n    mt19937 rng(42);\n    \n    auto get_deg_seq = [&](vector<vector<int>>& adj) -> vector<int> {\n        vector<int> deg(N,0);\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) if(adj[i][j]) deg[i]++, deg[j]++;\n        sort(deg.begin(), deg.end());\n        return deg;\n    };\n    \n    auto to_string_graph = [&](vector<vector<int>>& adj) -> string {\n        string s;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) s += (char)('0'+adj[i][j]);\n        return s;\n    };\n    \n    // For each graph k, target edge count = round(k * E / (M-1)) if M>1\n    vector<string> graphs(M);\n    vector<vector<int>> deg_seqs(M);\n    vector<vector<vector<int>>> adjs(M, vector<vector<int>>(N, vector<int>(N,0)));\n    \n    for(int k=0;k<M;k++){\n        int target_edges = (M>1) ? (int)round((double)k*E/(M-1)) : E/2;\n        // Create graph with exactly target_edges edges randomly\n        vector<pair<int,int>> all_edges;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) all_edges.push_back({i,j});\n        shuffle(all_edges.begin(), all_edges.end(), rng);\n        for(int e=0;e<target_edges;e++) adjs[k][all_edges[e].first][all_edges[e].second] = adjs[k][all_edges[e].second][all_edges[e].first] = 1;\n        deg_seqs[k] = get_deg_seq(adjs[k]);\n        graphs[k] = to_string_graph(adjs[k]);\n    }\n    \n    cout << N << \"\\n\";\n    for(int k=0;k<M;k++) cout << graphs[k] << \"\\n\";\n    cout.flush();\n    \n    for(int q=0;q<100;q++){\n        string h; cin >> h;\n        vector<vector<int>> hadj(N, vector<int>(N,0));\n        int idx=0;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){ hadj[i][j]=hadj[j][i]=h[idx++]-'0'; }\n        vector<int> hd(N,0);\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) if(hadj[i][j]) hd[i]++,hd[j]++;\n        sort(hd.begin(),hd.end());\n        \n        int best=-1; double bestd=1e18;\n        for(int k=0;k<M;k++){\n            double d=0;\n            for(int i=0;i<N;i++) d+=(hd[i]-deg_seqs[k][i])*(hd[i]-deg_seqs[k][i]);\n            if(d<bestd){ bestd=d; best=k; }\n        }\n        cout << best << \"\\n\";\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N,M,D,K;\nvector<int> eu,ev,ew;\nvector<vector<pair<int,int>>> adj;\n\nint nSample;\nvector<int> samples;\nvector<vector<long long>> origDist;\n\nvoid dijkstra(int src, vector<long long>& dist, const vector<bool>& removed){\n    fill(dist.begin(), dist.end(), (long long)1e18);\n    dist[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 [d,u]=pq.top(); pq.pop();\n        if(d>dist[u]) continue;\n        for(auto& [v,ei]:adj[u]){\n            if(removed[ei]) continue;\n            long long nd=d+ew[ei];\n            if(nd<dist[v]){\n                dist[v]=nd;\n                pq.push({nd,v});\n            }\n        }\n    }\n}\n\ndouble evalDay(const vector<int>& edges_on_day){\n    vector<bool> removed(M, false);\n    for(int e : edges_on_day) removed[e] = true;\n    \n    double total = 0;\n    vector<long long> dist(N);\n    for(int si=0; si<nSample; si++){\n        dijkstra(samples[si], dist, removed);\n        for(int j=0; j<N; j++){\n            long long dd = (dist[j] >= 1e18) ? (long long)1e9 : dist[j];\n            total += (double)(dd - origDist[si][j]);\n        }\n    }\n    return total;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin>>N>>M>>D>>K;\n    eu.resize(M); ev.resize(M); ew.resize(M);\n    adj.resize(N);\n    for(int i=0;i<M;i++){\n        cin>>eu[i]>>ev[i]>>ew[i];\n        eu[i]--; ev[i]--;\n        adj[eu[i]].push_back({ev[i],i});\n        adj[ev[i]].push_back({eu[i],i});\n    }\n    vector<int> X(N),Y(N);\n    for(int i=0;i<N;i++) cin>>X[i]>>Y[i];\n    \n    mt19937 rng(12345);\n    nSample = min(N, 30);\n    samples.resize(N);\n    iota(samples.begin(), samples.end(), 0);\n    shuffle(samples.begin(), samples.end(), rng);\n    samples.resize(nSample);\n    \n    origDist.assign(nSample, vector<long long>(N));\n    vector<bool> noRem(M, false);\n    for(int i=0;i<nSample;i++) dijkstra(samples[i], origDist[i], noRem);\n    \n    // Edge importance\n    vector<double> importance(M, 0);\n    for(int si=0;si<nSample;si++){\n        for(int v=0;v<N;v++){\n            if(v==samples[si]) continue;\n            for(auto& [u,ei]:adj[v]){\n                if(origDist[si][u]+ew[ei]==origDist[si][v]){\n                    importance[ei]+=1.0;\n                    break;\n                }\n            }\n        }\n    }\n    \n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){ return importance[a]>importance[b]; });\n    \n    vector<int> assign(M);\n    vector<vector<int>> dayEdges(D);\n    for(int i=0;i<M;i++){\n        int day = i % D;\n        assign[order[i]] = day;\n        dayEdges[day].push_back(order[i]);\n    }\n    \n    // Evaluate all days\n    vector<double> dayScore(D);\n    double totalScore = 0;\n    for(int d=0;d<D;d++){\n        dayScore[d] = evalDay(dayEdges[d]);\n        totalScore += dayScore[d];\n    }\n    \n    // Simulated annealing\n    auto startTime = chrono::steady_clock::now();\n    double timeLimit = 5.5;\n    int iter = 0;\n    double temp = totalScore / (D * 100);\n    \n    auto getTime = [&](){\n        auto now = chrono::steady_clock::now();\n        return chrono::duration<double>(now - startTime).count();\n    };\n    \n    while(true){\n        double t = getTime();\n        if(t > timeLimit) break;\n        double progress = t / timeLimit;\n        double curTemp = temp * (1.0 - progress) + 0.01;\n        \n        int e = rng() % M;\n        int oldDay = assign[e];\n        int newDay = rng() % D;\n        if(newDay == oldDay) continue;\n        if((int)dayEdges[newDay].size() >= K) continue;\n        \n        // Remove e from oldDay, add to newDay\n        auto& oldVec = dayEdges[oldDay];\n        oldVec.erase(find(oldVec.begin(), oldVec.end(), e));\n        dayEdges[newDay].push_back(e);\n        \n        double newOldScore = evalDay(oldVec);\n        double newNewScore = evalDay(dayEdges[newDay]);\n        double delta = (newOldScore + newNewScore) - (dayScore[oldDay] + dayScore[newDay]);\n        \n        if(delta < 0 || (curTemp > 0 && exp(-delta/curTemp) > (double)(rng()%1000000)/1000000.0)){\n            assign[e] = newDay;\n            dayScore[oldDay] = newOldScore;\n            dayScore[newDay] = newNewScore;\n            totalScore += delta;\n        } else {\n            dayEdges[newDay].pop_back();\n            oldVec.push_back(e);\n        }\n        iter++;\n    }\n    \n    for(int i=0;i<M;i++){\n        cout << assign[i]+1;\n        if(i<M-1) cout << ' ';\n    }\n    cout << '\\n';\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\nint main(){\n    int D;\n    scanf(\"%d\",&D);\n    vector<string> f1(D),r1(D),f2(D),r2(D);\n    for(int i=0;i<D;i++) cin>>f1[i];\n    for(int i=0;i<D;i++) cin>>r1[i];\n    for(int i=0;i<D;i++) cin>>f2[i];\n    for(int i=0;i<D;i++) cin>>r2[i];\n    \n    vector<int> b1(D*D*D,0), b2(D*D*D,0);\n    int n=0;\n    // Config 1\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++){\n        if(f1[z][x]=='1' && r1[z][y]=='1'){\n            n++;\n            b1[x*D*D+y*D+z]=n;\n        }\n    }\n    // Config 2\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++){\n        if(f2[z][x]=='1' && r2[z][y]=='1'){\n            n++;\n            b2[x*D*D+y*D+z]=n;\n        }\n    }\n    printf(\"%d\\n\",n);\n    for(int i=0;i<D*D*D;i++) printf(\"%d%c\",b1[i],\" \\n\"[i==D*D*D-1]);\n    for(int i=0;i<D*D*D;i++) printf(\"%d%c\",b2[i],\" \\n\"[i==D*D*D-1]);\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M,K;\n    cin>>N>>M>>K;\n    \n    vector<ll> x(N),y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n    \n    vector<int> eu(M),ev(M);\n    vector<ll> ew(M);\n    for(int j=0;j<M;j++){\n        cin>>eu[j]>>ev[j]>>ew[j];\n        eu[j]--;ev[j]--;\n    }\n    \n    vector<ll> a(K),b(K);\n    for(int k=0;k<K;k++) cin>>a[k]>>b[k];\n    \n    vector<vector<pair<int,int>>> adj(N);\n    for(int j=0;j<M;j++){\n        adj[eu[j]].push_back({ev[j],j});\n        adj[ev[j]].push_back({eu[j],j});\n    }\n    \n    // Shortest paths between all pairs\n    const ll INF = 1e18;\n    vector<vector<ll>> spd(N, vector<ll>(N, INF));\n    vector<vector<int>> spp(N, vector<int>(N,-1)); // parent edge in shortest path tree from s\n    for(int s=0;s<N;s++){\n        priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<>> pq;\n        spd[s][s]=0;\n        pq.push({0,s});\n        while(!pq.empty()){\n            auto [d,u]=pq.top();pq.pop();\n            if(d>spd[s][u]) continue;\n            for(auto [v,eid]:adj[u]){\n                ll nd=d+ew[eid];\n                if(nd<spd[s][v]){\n                    spd[s][v]=nd;\n                    spp[s][v]=eid;\n                    pq.push({nd,v});\n                }\n            }\n        }\n    }\n    \n    // For each resident, compute distance to each vertex and candidate vertices\n    vector<vector<int>> cands(K);\n    vector<vector<int>> rdist_ceil(K, vector<int>(N, 10000));\n    for(int k=0;k<K;k++){\n        for(int i=0;i<N;i++){\n            double dx=x[i]-a[k], dy=y[i]-b[k];\n            double d=sqrt(dx*dx+dy*dy);\n            int r=(int)ceil(d-1e-9);\n            rdist_ceil[k][i]=r;\n            if(r<=5000) cands[k].push_back(i);\n        }\n    }\n    \n    // For each vertex, which residents it can cover\n    vector<vector<int>> vtx_residents(N);\n    for(int k=0;k<K;k++)\n        for(int i:cands[k])\n            vtx_residents[i].push_back(k);\n    \n    // Build Steiner tree connecting a set of active vertices via vertex 0\n    auto build_steiner = [&](vector<bool>& active) -> pair<ll, vector<bool>> {\n        vector<bool> inTree(N,false);\n        vector<bool> edgeUsed(M,false);\n        ll treeCost=0;\n        inTree[0]=true;\n        \n        vector<int> targets;\n        for(int i=0;i<N;i++) if(active[i]&&i!=0) targets.push_back(i);\n        \n        while(!targets.empty()){\n            int bestT=-1; ll bestD=INF;\n            int bestSrc=-1;\n            for(int t:targets){\n                for(int i=0;i<N;i++){\n                    if(inTree[i]&&spd[i][t]<bestD){\n                        bestD=spd[i][t];\n                        bestT=t;\n                        bestSrc=i;\n                    }\n                }\n            }\n            // Trace path\n            int cur=bestT;\n            while(cur!=bestSrc){\n                int eid=spp[bestSrc][cur];\n                if(!edgeUsed[eid]){\n                    edgeUsed[eid]=true;\n                    treeCost+=ew[eid];\n                }\n                int u=eu[eid],v=ev[eid];\n                cur=(u==cur)?v:u;\n                inTree[cur]=true;\n            }\n            inTree[bestT]=true;\n            targets.erase(remove(targets.begin(),targets.end(),bestT),targets.end());\n        }\n        return {treeCost, edgeUsed};\n    };\n    \n    // Get tree vertices from edge set\n    auto get_tree_vertices = [&](vector<bool>& edgeUsed) -> vector<bool> {\n        // BFS from 0 using only edgeUsed edges\n        vector<bool> vis(N,false);\n        queue<int> q;\n        q.push(0); vis[0]=true;\n        while(!q.empty()){\n            int u=q.front();q.pop();\n            for(auto [v,eid]:adj[u]){\n                if(edgeUsed[eid]&&!vis[v]){\n                    vis[v]=true;\n                    q.push(v);\n                }\n            }\n        }\n        return vis;\n    };\n    \n    auto compute_cost = [&](vector<int>& P, vector<bool>& edgeUsed) -> ll {\n        ll S=0;\n        for(int i=0;i<N;i++) S+=(ll)P[i]*P[i];\n        for(int j=0;j<M;j++) if(edgeUsed[j]) S+=ew[j];\n        return S;\n    };\n    \n    // Assign residents to tree vertices minimizing marginal P\u00b2 cost\n    auto assign_residents = [&](vector<bool>& inTree, vector<int>& P) {\n        fill(P.begin(),P.end(),0);\n        // Sort residents by max needed radius (hardest first)\n        vector<int> order(K);\n        iota(order.begin(),order.end(),0);\n        \n        // First pass: assign each to vertex that minimizes marginal cost\n        vector<int> assign(K,-1);\n        for(int k=0;k<K;k++){\n            int best=-1; ll bestMarg=INF;\n            for(int i:cands[k]){\n                if(!inTree[i]) continue;\n                int r=rdist_ceil[k][i];\n                ll marg=(ll)max(r,P[i])*(ll)max(r,P[i])-(ll)P[i]*P[i];\n                if(marg<bestMarg||(marg==bestMarg&&best==-1)){\n                    bestMarg=marg;\n                    best=i;\n                }\n            }\n            if(best>=0){\n                assign[k]=best;\n                P[best]=max(P[best],rdist_ceil[k][best]);\n            }\n        }\n        \n        // Multi-pass refinement\n        for(int iter=0;iter<10;iter++){\n            bool changed=false;\n            // Recompute P from scratch\n            fill(P.begin(),P.end(),0);\n            for(int k=0;k<K;k++) if(assign[k]>=0) P[assign[k]]=max(P[assign[k]],rdist_ceil[k][assign[k]]);\n            \n            for(int k=0;k<K;k++){\n                int cur=assign[k];\n                int curR=rdist_ceil[k][cur];\n                // Check if removing k from cur changes P[cur]\n                // Recompute P[cur] without k\n                int maxOther=0;\n                for(int k2:vtx_residents[cur]){\n                    if(k2!=k&&assign[k2]==cur) maxOther=max(maxOther,rdist_ceil[k2][cur]);\n                }\n                ll removeSave=(ll)P[cur]*P[cur]-(ll)max(maxOther,0)*(ll)max(maxOther,0);\n                // Try other vertices\n                int bestV=cur; ll bestCost=0; // net change\n                for(int i:cands[k]){\n                    if(!inTree[i]) continue;\n                    if(i==cur) continue;\n                    int r=rdist_ceil[k][i];\n                    ll addCost=(ll)max(r,P[i])*(ll)max(r,P[i])-(ll)P[i]*P[i];\n                    ll net=addCost-removeSave;\n                    if(net<bestCost){\n                        bestCost=net;\n                        bestV=i;\n                    }\n                }\n                if(bestV!=cur){\n                    assign[k]=bestV;\n                    P[cur]=maxOther;\n                    P[bestV]=max(P[bestV],rdist_ceil[k][bestV]);\n                    changed=true;\n                }\n            }\n            if(!changed) break;\n        }\n    };\n    \n    // Main optimization\n    vector<int> bestP(N,0);\n    vector<bool> bestEdge(M,false);\n    ll bestCost=INF;\n    \n    // Strategy: try different subsets of vertices\n    // First: use all vertices reachable cheaply\n    {\n        // Initial: assign each resident to nearest vertex\n        vector<int> P(N,0);\n        vector<int> assign(K);\n        for(int k=0;k<K;k++){\n            int best=-1; int bestR=10000;\n            for(int i:cands[k]){\n                if(rdist_ceil[k][i]<bestR){\n                    bestR=rdist_ceil[k][i];\n                    best=i;\n                }\n            }\n            assign[k]=best;\n            P[best]=max(P[best],bestR);\n        }\n        \n        vector<bool> active(N,false);\n        active[0]=true;\n        for(int i=0;i<N;i++) if(P[i]>0) active[i]=true;\n        \n        auto [tc,edgeUsed]=build_steiner(active);\n        auto inTree=get_tree_vertices(edgeUsed);\n        \n        // Reassign with tree info\n        assign_residents(inTree, P);\n        \n        // Rebuild tree with only needed vertices\n        for(int rep=0;rep<3;rep++){\n            fill(active.begin(),active.end(),false);\n            active[0]=true;\n            for(int i=0;i<N;i++) if(P[i]>0) active[i]=true;\n            auto [tc2,eu2]=build_steiner(active);\n            auto inTree2=get_tree_vertices(eu2);\n            assign_residents(inTree2,P);\n            edgeUsed=eu2;\n            inTree=inTree2;\n        }\n        \n        ll cost=compute_cost(P,edgeUsed);\n        if(cost<bestCost){\n            bestCost=cost;\n            bestP=P;\n            bestEdge=edgeUsed;\n        }\n    }\n    \n    // Try removing vertices: for each active vertex, check if removing it improves cost\n    {\n        vector<int> P=bestP;\n        vector<bool> edgeUsed=bestEdge;\n        \n        auto tryRemoveVertex = [&]() -> bool {\n            auto inTree=get_tree_vertices(edgeUsed);\n            bool improved=false;\n            \n            for(int v=1;v<N;v++){\n                if(P[v]==0) continue;\n                // Check if any resident assigned to v can be reassigned\n                // Save P[v]^2, but residents need new homes\n                vector<int> affected;\n                for(int k:vtx_residents[v]){\n                    // check if currently assigned to v\n                    if(rdist_ceil[k][v]<=P[v]){\n                        // Could be assigned here, check\n                        bool hasOther=false;\n                        for(int i:cands[k]){\n                            if(i!=v&&inTree[i]) { hasOther=true; break; }\n                        }\n                        if(!hasOther) goto next_v;\n                    }\n                }\n                // Try full reassignment without v\n                {\n                    vector<bool> act(N,false); act[0]=true;\n                    for(int i=0;i<N;i++) if(i!=v&&P[i]>0) act[i]=true;\n                    // Check feasibility quickly\n                    // ... skip full rebuild for speed\n                }\n                next_v:;\n            }\n            return improved;\n        };\n        (void)tryRemoveVertex;\n    }\n    \n    // Simulated annealing: try adding extra tree vertices to reduce P costs\n    {\n        vector<int> P=bestP;\n        vector<bool> edgeUsed=bestEdge;\n        \n        auto inTree=get_tree_vertices(edgeUsed);\n        \n        // For each non-active vertex in tree, it's already free to use\n        // Set optimal P for it\n        for(int i=0;i<N;i++){\n            if(inTree[i]&&P[i]==0){\n                // Check if any resident benefits\n                int bestSave=0; int bestR=0;\n                // For each resident that could use this vertex\n                for(int k:vtx_residents[i]){\n                    // Find current assignment\n                    // This is expensive, skip for now\n                }\n            }\n        }\n        \n        // Better: full reassign with all tree vertices\n        assign_residents(inTree, P);\n        ll cost=compute_cost(P,edgeUsed);\n        if(cost<bestCost){\n            bestCost=cost;\n            bestP=P;\n            bestEdge=edgeUsed;\n        }\n    }\n    \n    // Output\n    for(int i=0;i<N;i++) cout<<bestP[i]<<\" \\n\"[i==N-1];\n    vector<int> B(M);\n    for(int j=0;j<M;j++) B[j]=bestEdge[j]?1:0;\n    for(int j=0;j<M;j++) cout<<B[j]<<\" \\n\"[j==M-1];\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N=30;\nint grid[30][30];\nvector<tuple<int,int,int,int>> ops;\n\nvoid do_swap(int x1,int y1,int x2,int y2){\n    ops.push_back({x1,y1,x2,y2});\n    swap(grid[x1][y1],grid[x2][y2]);\n}\n\nint main(){\n    for(int x=0;x<N;x++) for(int y=0;y<=x;y++) scanf(\"%d\",&grid[x][y]);\n    \n    // Repeated passes: for each parent-child pair, if parent > child, swap them\n    // Do this until no violations or we run out of operations\n    bool changed = true;\n    while(changed && (int)ops.size() < 9900){\n        changed = false;\n        // Top-down pass: sift down\n        for(int x=0;x<N-1 && (int)ops.size()<9900;x++){\n            for(int y=0;y<=x && (int)ops.size()<9900;y++){\n                // Children: (x+1,y) and (x+1,y+1)\n                // Sift down: while current > min child, swap with min child\n                int cx=x, cy=y;\n                while(cx<N-1 && (int)ops.size()<9900){\n                    int c1=grid[cx+1][cy], c2=grid[cx+1][cy+1];\n                    int cur=grid[cx][cy];\n                    if(cur<=c1 && cur<=c2) break;\n                    if(c1<=c2){\n                        do_swap(cx,cy,cx+1,cy);\n                        cx=cx+1; // cy stays\n                    } else {\n                        do_swap(cx,cy,cx+1,cy+1);\n                        cx=cx+1; cy=cy+1;\n                    }\n                    changed=true;\n                }\n            }\n        }\n        // Bottom-up pass: sift up\n        for(int x=N-1;x>=1 && (int)ops.size()<9900;x--){\n            for(int y=x;y>=0 && (int)ops.size()<9900;y--){\n                int cx=x, cy=y;\n                while(cx>0 && (int)ops.size()<9900){\n                    // Parents: (cx-1,cy-1) if cy>0, (cx-1,cy) if cy<cx\n                    int best_px=-1,best_py=-1,best_pv=grid[cx][cy];\n                    if(cy>0 && grid[cx-1][cy-1]>best_pv){best_px=cx-1;best_py=cy-1;best_pv=grid[cx-1][cy-1];}\n                    if(cy<cx && grid[cx-1][cy]>best_pv){best_px=cx-1;best_py=cy;best_pv=grid[cx-1][cy];}\n                    if(best_px==-1) break;\n                    do_swap(cx,cy,best_px,best_py);\n                    cx=best_px; cy=best_py;\n                    changed=true;\n                }\n            }\n        }\n    }\n    \n    printf(\"%d\\n\",(int)ops.size());\n    for(auto&[a,b,c,d]:ops) printf(\"%d %d %d %d\\n\",a,b,c,d);\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nint grid[9][9]; // -2=obstacle, -1=empty, >=0 container number\nint dx[]={-1,1,0,0}, dy[]={0,0,-1,1};\nint ei,ej;\n\nbool reachable(int si,int sj,int ti,int tj){\n    bool vis[9][9]={};\n    queue<pair<int,int>> q;\n    q.push({si,sj}); vis[si][sj]=1;\n    while(!q.empty()){\n        auto [x,y]=q.front();q.pop();\n        if(x==ti&&y==tj) return true;\n        for(int d=0;d<4;d++){\n            int nx=x+dx[d],ny=y+dy[d];\n            if(nx<0||nx>=D||ny<0||ny>=D) continue;\n            if(vis[nx][ny]||grid[nx][ny]==-2) continue;\n            if(!(nx==ti&&ny==tj) && grid[nx][ny]>=0) continue;\n            vis[nx][ny]=1; q.push({nx,ny});\n        }\n    }\n    return false;\n}\n\nvector<pair<int,int>> reachable_containers(){\n    bool vis[9][9]={};\n    queue<pair<int,int>> q;\n    q.push({ei,ej}); vis[ei][ej]=1;\n    vector<pair<int,int>> res;\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>=D||ny<0||ny>=D||vis[nx][ny]||grid[nx][ny]==-2) continue;\n            vis[nx][ny]=1;\n            if(grid[nx][ny]>=0) res.push_back({nx,ny});\n            else q.push({nx,ny});\n        }\n    }\n    return res;\n}\n\nint main(){\n    int N; scanf(\"%d%d\",&D,&N);\n    ei=0; ej=(D-1)/2;\n    memset(grid,-1,sizeof(grid));\n    for(int i=0;i<N;i++){int r,c;scanf(\"%d%d\",&r,&c);grid[r][c]=-2;}\n    \n    vector<pair<int,pair<int,int>>> cells;\n    for(int i=0;i<D;i++) for(int j=0;j<D;j++){\n        if(grid[i][j]==-2||(i==ei&&j==ej)) continue;\n        int dist=abs(i-ei)+abs(j-ej);\n        cells.push_back({dist,{i,j}});\n    }\n    sort(cells.begin(),cells.end());\n    int M=D*D-1-N;\n    vector<pair<int,int>> target(M);\n    for(int t=0;t<M;t++) target[t]=cells[t].second;\n    \n    for(int d=0;d<M;d++){\n        int t; scanf(\"%d\",&t);\n        auto [ti,tj]=target[t];\n        if(grid[ti][tj]==-1 && reachable(ei,ej,ti,tj)){\n            grid[ti][tj]=t; printf(\"%d %d\\n\",ti,tj); fflush(stdout);\n        } else {\n            // find nearest reachable empty cell to target\n            int best=-1; double bd=1e9; pair<int,int> bp;\n            for(auto&c:cells){\n                auto [ci,cj]=c.second;\n                if(grid[ci][cj]!=-1) continue;\n                if(!reachable(ei,ej,ci,cj)) continue;\n                double dd=abs(ci-ti)+abs(cj-tj);\n                if(dd<bd){bd=dd;bp={ci,cj};best=1;}\n            }\n            grid[bp.first][bp.second]=t;\n            printf(\"%d %d\\n\",bp.first,bp.second); fflush(stdout);\n        }\n    }\n    for(int i=0;i<M;i++){\n        auto rc=reachable_containers();\n        int best=-1; pair<int,int> bp;\n        for(auto [r,c]:rc) if(best<0||grid[r][c]<best){best=grid[r][c];bp={r,c};}\n        printf(\"%d %d\\n\",bp.first,bp.second);\n        grid[bp.first][bp.second]=-1;\n    }\n    fflush(stdout);\n}","ahc024":"#include<bits/stdc++.h>\nusing namespace std;\nint N,M;\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\n\nvector<vector<int>> grid;\n\nbool is_connected(int color){\n    // Find all cells of this color\n    vector<pair<int,int>> cells;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++)\n        if(grid[i][j]==color) cells.push_back({i,j});\n    if(cells.empty()) return true;\n    if(color==0){\n        // color 0 connects through outside\n        // BFS including virtual outside node\n        set<pair<int,int>> cset(cells.begin(),cells.end());\n        set<pair<int,int>> visited;\n        queue<pair<int,int>> q;\n        // start from any boundary 0-cell or if none, check connectivity through outside\n        // Actually all boundary cells connect to outside, and outside connects them\n        // So color-0 is connected if every interior 0-cell can reach a boundary 0-cell or boundary\n        // Simpler: add a virtual node connected to all boundary cells\n        // BFS from virtual node through 0-cells\n        visited.clear();\n        // Start: all boundary 0-cells and all 0-cells adjacent to boundary\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            if(grid[i][j]==0 && (i==0||i==N-1||j==0||j==N-1)){\n                if(!visited.count({i,j})){\n                    visited.insert({i,j});\n                    q.push({i,j});\n                }\n            }\n        }\n        // Also any cell adjacent to outside (boundary) that is 0\n        // already covered above\n        // If no boundary 0-cells exist but there are 0-cells, they must connect to boundary through adjacency to boundary (outside)\n        // Actually outside is one big connected region. Any 0-cell on boundary connects to outside.\n        // Interior 0-cells need path to boundary through other 0-cells.\n        if(q.empty() && !cells.empty()){\n            // no boundary 0-cells, check if all 0-cells are interior - they can't connect to outside\n            return false;\n        }\n        while(!q.empty()){\n            auto [ci,cj]=q.front(); q.pop();\n            for(int d=0;d<4;d++){\n                int ni=ci+dx[d],nj=cj+dy[d];\n                if(ni<0||ni>=N||nj<0||nj>=N) continue;\n                if(grid[ni][nj]==0 && !visited.count({ni,nj})){\n                    visited.insert({ni,nj});\n                    q.push({ni,nj});\n                }\n            }\n        }\n        return (int)visited.size()==(int)cells.size();\n    }\n    // Normal color\n    if(cells.size()<=1) return true;\n    set<pair<int,int>> cset(cells.begin(),cells.end());\n    set<pair<int,int>> visited;\n    queue<pair<int,int>> q;\n    q.push(cells[0]);\n    visited.insert(cells[0]);\n    while(!q.empty()){\n        auto [ci,cj]=q.front(); q.pop();\n        for(int d=0;d<4;d++){\n            int ni=ci+dx[d],nj=cj+dy[d];\n            if(ni<0||ni>=N||nj<0||nj>=N) continue;\n            if(grid[ni][nj]==color && !visited.count({ni,nj})){\n                visited.insert({ni,nj});\n                q.push({ni,nj});\n            }\n        }\n    }\n    return (int)visited.size()==(int)cells.size();\n}\n\nset<pair<int,int>> get_adj_set(){\n    set<pair<int,int>> s;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        if(i==0||i==N-1||j==0||j==N-1){\n            if(grid[i][j]!=0){\n                int a=min(0,grid[i][j]),b=max(0,grid[i][j]);\n                s.insert({a,b});\n            }\n        }\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) continue;\n            if(grid[i][j]!=grid[ni][nj]){\n                int a=min(grid[i][j],grid[ni][nj]),b=max(grid[i][j],grid[ni][nj]);\n                s.insert({a,b});\n            }\n        }\n    }\n    return s;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \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    // Extract target adjacency\n    set<pair<int,int>> target_adj = get_adj_set();\n    // Note: in original map there are no 0-cells, so adj with 0 = boundary colors\n    \n    auto best_grid = grid;\n    int best_zeros = 0;\n    \n    // Greedy: try to convert cells to 0, check validity\n    // Shuffle order, repeat\n    mt19937 rng(42);\n    \n    auto start = chrono::steady_clock::now();\n    \n    vector<pair<int,int>> order;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) order.push_back({i,j});\n    \n    for(int iter=0;;iter++){\n        auto now = chrono::steady_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-start).count()>1800) break;\n        \n        grid = best_grid; // start fresh each iteration? Or from current best\n        if(iter>0) shuffle(order.begin(),order.end(),rng);\n        \n        for(auto&[i,j]:order){\n            if(grid[i][j]==0) continue;\n            int old_color = grid[i][j];\n            \n            // Check: does this color have more than 1 cell?\n            // Quick check neighbors for adjacency preservation\n            grid[i][j]=0;\n            \n            // Check adjacency: old_color's adjacencies must still hold\n            // Check connectivity of old_color\n            // Check no new adjacencies created\n            // Check color 0 connectivity\n            \n            // Fast check: would removing this cell disconnect old_color?\n            // Count cells of old_color\n            // Also check adjacency changes\n            \n            bool ok = true;\n            \n            // Check: old_color still exists?\n            bool exists = false;\n            for(int ii=max(0,i-25);ii<min(N,i+25)&&!exists;ii++)\n                for(int jj=0;jj<N&&!exists;jj++)\n                    if(grid[ii][jj]==old_color) exists=true;\n            if(!exists){ grid[i][j]=old_color; continue; }\n            \n            // Check connectivity of old_color (articulation point check)\n            if(!is_connected(old_color)){ ok=false; }\n            \n            if(ok){\n                // Check no new adjacencies: neighbors of (i,j) that are non-zero and non-old_color\n                // now become adjacent to 0\n                // Was old_color adjacent to 0 before? Check target\n                // New adj: 0 <-> neighbor colors, and also 0 <-> colors adjacent to this cell\n                // We need: the new adjacency set == target\n                // Quick: check local changes\n                set<int> new_neighbors;\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) continue;\n                    if(grid[ni][nj]!=0) new_neighbors.insert(grid[ni][nj]);\n                }\n                // boundary\n                if(i==0||i==N-1||j==0||j==N-1){\n                    // 0-cell on boundary is fine (connects to outside)\n                }\n                \n                // Check: for each new neighbor color c, is (0,c) in target?\n                for(int nc : new_neighbors){\n                    int a=min(0,nc),b=max(0,nc);\n                    if(!target_adj.count({a,b})){ ok=false; break; }\n                }\n                \n                // Check: did we lose any required adjacency of old_color?\n                // old_color was adjacent to some colors through this cell\n                // Need to verify those adjacencies still exist elsewhere\n                if(ok){\n                    // Check all required adjacencies of old_color still present\n                    set<int> required_adj_of_old;\n                    for(auto&[a,b]:target_adj){\n                        if(a==old_color) required_adj_of_old.insert(b);\n                        if(b==old_color) required_adj_of_old.insert(a);\n                    }\n                    // Find current adjacencies of old_color\n                    set<int> current_adj_of_old;\n                    for(int ii=0;ii<N;ii++) for(int jj=0;jj<N;jj++){\n                        if(grid[ii][jj]!=old_color) continue;\n                        if(ii==0||ii==N-1||jj==0||jj==N-1) current_adj_of_old.insert(0);\n                        for(int d=0;d<4;d++){\n                            int ni2=ii+dx[d],nj2=jj+dy[d];\n                            if(ni2<0||ni2>=N||nj2<0||nj2>=N) continue;\n                            if(grid[ni2][nj2]!=old_color) current_adj_of_old.insert(grid[ni2][nj2]);\n                        }\n                    }\n                    for(int r:required_adj_of_old){\n                        if(!current_adj_of_old.count(r)){ ok=false; break; }\n                    }\n                }\n                \n                // Check color 0 connectivity\n                if(ok && !is_connected(0)) ok=false;\n            }\n            \n            if(!ok) grid[i][j]=old_color;\n        }\n        \n        int zeros=0;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(grid[i][j]==0) zeros++;\n        if(zeros>best_zeros){\n            best_zeros=zeros;\n            best_grid=grid;\n        }\n    }\n    \n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            cout<<best_grid[i][j];\n            if(j<N-1) cout<<' ';\n        }\n        cout<<'\\n';\n    }\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\nchar query(vector<int>& L, vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << \"\\n\" << flush;\n    queries_used++;\n    char c; cin >> c;\n    return c;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\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> left(v.begin(), v.begin()+mid), right(v.begin()+mid, v.end());\n        left = msort(left); right = msort(right);\n        vector<int> res;\n        int i=0,j=0;\n        while(i<(int)left.size()&&j<(int)right.size()){\n            if(queries_used>=Q){res.push_back(left[i++]);continue;}\n            vector<int> L={left[i]}, R={right[j]};\n            char c=query(L,R);\n            if(c=='<'||c=='=') res.push_back(left[i++]);\n            else res.push_back(right[j++]);\n        }\n        while(i<(int)left.size()) res.push_back(left[i++]);\n        while(j<(int)right.size()) res.push_back(right[j++]);\n        return res;\n    };\n    \n    vector<int> si = msort(items); // sorted ascending\n    \n    // Estimate weights: w[si[0]]=1, for each i, binary search how many smallest items equal it\n    vector<double> w(N, 1.0);\n    // cumulative weight estimate\n    vector<double> cum(N+1, 0);\n    cum[1] = 1.0;\n    \n    for(int i=1; i<N && queries_used<Q; i++){\n        // Binary search: find k in [1, i] such that sum of si[0..k-1] ~ si[i]\n        int lo=1, hi=i, best=0;\n        while(lo<=hi && queries_used<Q){\n            int mid=(lo+hi)/2;\n            vector<int> L={si[i]}, R;\n            for(int j=0;j<mid;j++) R.push_back(si[j]);\n            char c=query(L,R);\n            if(c=='>') { best=mid; lo=mid+1; }\n            else if(c=='<') { hi=mid-1; }\n            else { best=mid; break; }\n        }\n        w[si[i]] = (best>0) ? cum[best] + (cum[best]-cum[max(0,best-1)])*0.5 : cum[1]*0.5;\n        if(best>=i) w[si[i]] = cum[i] + (cum[i]-cum[max(0,i-1)])*0.5;\n        cum[i+1] = cum[i] + w[si[i]];\n    }\n    for(int i=1;i<N;i++) if(cum[i+1]==0) { w[si[i]]=w[si[i-1]]; cum[i+1]=cum[i]+w[si[i]]; }\n    \n    while(queries_used<Q){ vector<int> L={0},R={1}; query(L,R); }\n    \n    // LPT partition\n    vector<int> order(si.rbegin(), si.rend());\n    vector<double> gw(D,0);\n    vector<int> assign(N,0);\n    for(int idx:order){ int b=min_element(gw.begin(),gw.end())-gw.begin(); assign[idx]=b; gw[b]+=w[idx]; }\n    \n    for(int i=0;i<N;i++) cout<<assign[i]<<\" \\n\"[i==N-1];\n    cout<<flush;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int n, m;\n    scanf(\"%d%d\", &n, &m);\n    \n    vector<vector<int>> stacks(m);\n    vector<int> box_stack(n+1), box_pos(n+1);\n    \n    for(int i = 0; i < m; i++){\n        stacks[i].resize(n/m);\n        for(int j = 0; j < n/m; j++){\n            scanf(\"%d\", &stacks[i][j]);\n            box_stack[stacks[i][j]] = i;\n        }\n    }\n    \n    vector<pair<int,int>> ops;\n    \n    for(int v = 1; v <= n; v++){\n        // Find which stack v is in and its position\n        int si = -1, sj = -1;\n        for(int i = 0; i < m; i++){\n            for(int j = 0; j < (int)stacks[i].size(); j++){\n                if(stacks[i][j] == v){ si = i; sj = j; break; }\n            }\n            if(si >= 0) break;\n        }\n        \n        // If v is on top, just carry it out\n        if(sj == (int)stacks[si].size() - 1){\n            ops.push_back({v, 0});\n            stacks[si].pop_back();\n            continue;\n        }\n        \n        // Need to move boxes above v to some other stack\n        // Chunk: stacks[si][sj+1 .. end]\n        vector<int> chunk(stacks[si].begin() + sj + 1, stacks[si].end());\n        int chunk_max = *max_element(chunk.begin(), chunk.end());\n        int chunk_min = *min_element(chunk.begin(), chunk.end());\n        \n        // Choose best destination\n        int best_dest = -1;\n        int best_score = INT_MAX;\n        \n        for(int i = 0; i < m; i++){\n            if(i == si) continue;\n            int top = stacks[i].empty() ? INT_MAX : stacks[i].back();\n            // Prefer: top > chunk_max, then smallest top\n            if(top > chunk_max){\n                int score = top;\n                if(score < best_score){ best_score = score; best_dest = i; }\n            }\n        }\n        \n        if(best_dest == -1){\n            // Pick stack with largest top or empty stack\n            int best_top = -1;\n            for(int i = 0; i < m; i++){\n                if(i == si) continue;\n                int top = stacks[i].empty() ? n+1 : stacks[i].back();\n                if(top > best_top){ best_top = top; best_dest = i; }\n            }\n        }\n        \n        // Move chunk to best_dest\n        int bottom_box = stacks[si][sj+1];\n        ops.push_back({bottom_box, best_dest + 1});\n        for(auto x : chunk) stacks[best_dest].push_back(x);\n        stacks[si].resize(sj + 1);\n        \n        // Now carry out v\n        ops.push_back({v, 0});\n        stacks[si].pop_back();\n    }\n    \n    for(auto& [a,b] : ops) printf(\"%d %d\\n\", a, b);\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nstring h_wall[40], v_wall[40];\nint d[40][40];\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\nchar dc[]={'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 h_wall[x-1][y]=='0';\n    if(dir==1) return h_wall[x][y]=='0';\n    if(dir==2) return v_wall[x][y-1]=='0';\n    if(dir==3) return v_wall[x][y]=='0';\n    return false;\n}\n\n// BFS shortest path, returns sequence of directions\nvector<int> bfs_path(int sx,int sy,int gx,int gy){\n    if(sx==gx&&sy==gy) return {};\n    vector<vector<int>> prev(N,vector<int>(N,-1));\n    vector<vector<bool>> vis(N,vector<bool>(N,false));\n    queue<pair<int,int>> q;\n    q.push({sx,sy}); vis[sx][sy]=true;\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        if(x==gx&&y==gy) break;\n        for(int dir=0;dir<4;dir++){\n            if(!canMove(x,y,dir)) continue;\n            int nx=x+dx[dir],ny=y+dy[dir];\n            if(!vis[nx][ny]){\n                vis[nx][ny]=true; prev[nx][ny]=dir;\n                q.push({nx,ny});\n            }\n        }\n    }\n    vector<int> path;\n    int cx=gx,cy=gy;\n    while(cx!=sx||cy!=sy){\n        int dir=prev[cx][cy];\n        path.push_back(dir);\n        cx-=dx[dir]; cy-=dy[dir];\n    }\n    reverse(path.begin(),path.end());\n    return path;\n}\n\n// BFS distance from a source to all cells\nvector<vector<int>> bfs_dist(int sx, int sy){\n    vector<vector<int>> dist(N, vector<int>(N, 1e9));\n    dist[sx][sy] = 0;\n    queue<pair<int,int>> q;\n    q.push({sx,sy});\n    while(!q.empty()){\n        auto [x,y] = q.front(); q.pop();\n        for(int dir=0;dir<4;dir++){\n            if(!canMove(x,y,dir)) continue;\n            int nx=x+dx[dir], ny=y+dy[dir];\n            if(dist[nx][ny] > dist[x][y]+1){\n                dist[nx][ny] = dist[x][y]+1;\n                q.push({nx,ny});\n            }\n        }\n    }\n    return dist;\n}\n\nlong long totalD;\n\n// Compute average dirtiness for a given route (as directions)\ndouble computeScore(const vector<int>& route){\n    int L = route.size();\n    // For each cell, find when it's visited\n    // S_t = sum of all dirtiness after step t\n    // After step t, cell (i,j) has dirtiness = d[i][j] * (t - last_clean_time(i,j,t))\n    // where last_clean_time is the last time cell was visited (cleaned) at or before t\n    // Actually at t=0 all are 0. Each step: all cells += d[i][j], then visited cell = 0\n    // So after steady state (repeating), we need sum over t=L..2L-1 of S_t / L\n    \n    // Simulate second iteration\n    // First, simulate first iteration to get state at t=L\n    vector<vector<int>> dirty(N, vector<int>(N, 0));\n    int cx=0, cy=0;\n    for(int t=0; t<L; t++){\n        int dir = route[t];\n        // all cells gain dirt\n        // then visited cell becomes 0\n        cx += dx[dir]; cy += dy[dir];\n        // Instead of updating all cells, track last visit time\n    }\n    \n    // More efficient: track last visit time for each cell\n    // dirtiness of (i,j) at time t = d[i][j] * (t - last_visit[i][j])\n    // S_t = sum d[i][j] * (t - last_visit[i][j])\n    // But last_visit changes when we step on a cell\n    \n    // For the second pass (t=L..2L-1), last_visit starts from first pass positions\n    // Let's just track last_visit times\n    \n    vector<vector<int>> lastVisit(N, vector<int>(N, -1));\n    // cell (0,0) is visited at t=0 (start)\n    // Actually, at t=0, dirtiness is 0 for all. The route starts at (0,0).\n    // \"After the move\" = after step t (1-indexed?), no it says t-th move\n    // a_{0,i,j} = 0 for all\n    // After move t: dirtiness of moved-to cell = 0, all others += d[i][j]\n    \n    // Let me just do it step by step for two iterations\n    // But N can be 40, so N^2=1600 cells, L up to 100000\n    // 1600 * 200000 = too much\n    \n    // Better approach: for each cell, collect visit times in second pass\n    // Contribution of cell (i,j) = d[i,j] * sum over gaps of g*(g-1)/2 summed, /L\n    // Actually let me think again...\n    \n    // In steady state, cell (i,j) is visited at certain positions in the cycle\n    // Between consecutive visits (gap g), contribution to sum of S_t over those g steps\n    // = d[i][j] * (1 + 2 + ... + (g-1)) if not the visited cell\n    // Wait, when we visit cell c at time t, c's dirtiness becomes 0\n    // At time t+1, we move to some cell, all cells including c gain d, then the new cell is set to 0\n    // So for cell c visited at times t1, t2, ... with gaps g = t2-t1:\n    // At times t1+1, t1+2, ..., t2-1, t2: dirtiness is d*1, d*2, ..., d*(g-1), then at t2 it becomes 0\n    // Wait at t2 it's cleaned. So dirtiness values are d*1, d*2, ..., d*(g-1), 0\n    // Sum = d * g*(g-1)/2\n    \n    // So total sum over one cycle = sum over all cells sum over all gaps: d[i][j] * g*(g-1)/2\n    // Average = (1/L) * sum\n    \n    // For cells never revisited in the cycle (visited once), gap = L\n    // Contribution = d[i][j] * L*(L-1)/2 / L \u2248 d[i][j]*L/2\n    \n    // For cells visited k times equally spaced, gap = L/k each\n    // Contribution = k * d[i][j] * (L/k)*((L/k)-1)/2 / L \u2248 d[i][j]*L/(2k)\n    \n    // So visiting a cell twice halves its contribution!\n    \n    // Now I need to find visit times. Let me collect them.\n    cx=0; cy=0;\n    // positions: at time 0, we're at (0,0)\n    // visit at time 0: (0,0)\n    // after move t, we're at new position, that position is cleaned\n    \n    vector<vector<vector<int>>> visitTimes(N, vector<vector<int>>(N));\n    visitTimes[0][0].push_back(0);\n    for(int t=0; t<L; t++){\n        int dir = route[t];\n        cx += dx[dir]; cy += dy[dir];\n        visitTimes[cx][cy].push_back(t+1);\n    }\n    \n    double total = 0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        auto& vt = visitTimes[i][j];\n        // In steady state, visits repeat with period L\n        // Gaps between consecutive visits (cyclic)\n        int k = vt.size();\n        if(k == 0){\n            // never visited - shouldn't happen\n            total += (double)d[i][j] * L * (L-1) / 2.0;\n            continue;\n        }\n        for(int a=0; a<k; a++){\n            int gap;\n            if(a+1 < k) gap = vt[a+1] - vt[a];\n            else gap = L - vt[a] + vt[0]; // wrap around\n            total += (double)d[i][j] * gap * (gap-1) / 2.0;\n        }\n    }\n    return total / L;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto startTime = chrono::steady_clock::now();\n    \n    cin>>N;\n    for(int i=0;i<N-1;i++) cin>>h_wall[i];\n    for(int i=0;i<N;i++) cin>>v_wall[i];\n    totalD = 0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        cin>>d[i][j];\n        totalD += d[i][j];\n    }\n    \n    // Precompute BFS distances from every cell\n    vector<vector<vector<vector<int>>>> dist(N, vector<vector<vector<int>>>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++)\n        dist[i][j] = bfs_dist(i,j);\n    \n    // Build a base tour using DFS\n    vector<int> baseTour;\n    {\n        vector<vector<bool>> vis(N, vector<bool>(N, false));\n        // DFS from (0,0)\n        function<void(int,int)> dfs = [&](int x, int y){\n            vis[x][y] = true;\n            // Sort neighbors by d value (visit high-d first? or some heuristic)\n            vector<pair<int,int>> neighbors;\n            for(int dir=0;dir<4;dir++){\n                if(!canMove(x,y,dir)) continue;\n                int nx=x+dx[dir], ny=y+dy[dir];\n                if(!vis[nx][ny]) neighbors.push_back({dir, d[nx][ny]});\n            }\n            // Visit high-d neighbors first so they appear earlier\n            sort(neighbors.begin(), neighbors.end(), [](auto&a, auto&b){return a.second > b.second;});\n            for(auto [dir, _] : neighbors){\n                int nx=x+dx[dir], ny=y+dy[dir];\n                if(!vis[nx][ny]){\n                    baseTour.push_back(dir);\n                    dfs(nx, ny);\n                    baseTour.push_back(dir^1); // reverse direction\n                }\n            }\n        };\n        dfs(0,0);\n    }\n    \n    // Now baseTour visits all cells, length ~2*(N^2-1)\n    // Try to build a better route: TSP-style ordering then add revisits\n    \n    // Collect all cells sorted by d value\n    vector<pair<int,int>> cells;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cells.push_back({i,j});\n    sort(cells.begin(), cells.end(), [](auto&a, auto&b){\n        return d[a.first][a.second] > d[b.first][b.second];\n    });\n    \n    // Strategy: Build route as sequence of waypoints to visit\n    // Start with all cells as waypoints (must visit each at least once)\n    // Then add extra visits to high-d cells\n    // Order waypoints to minimize total path length (greedy nearest neighbor weighted by dirt)\n    \n    // Build initial waypoint list: greedy TSP\n    auto buildRoute = [&](vector<pair<int,int>>& waypoints) -> vector<int> {\n        vector<int> route;\n        int cx=0, cy=0;\n        for(auto [wx, wy] : waypoints){\n            auto p = bfs_path(cx, cy, wx, wy);\n            for(int dir : p) route.push_back(dir);\n            cx = wx; cy = wy;\n        }\n        // Return to (0,0)\n        auto p = bfs_path(cx, cy, 0, 0);\n        for(int dir : p) route.push_back(dir);\n        return route;\n    };\n    \n    // Greedy nearest neighbor with d-weight\n    auto greedyOrder = [&]() -> vector<pair<int,int>> {\n        vector<vector<bool>> vis(N, vector<bool>(N, false));\n        vis[0][0] = true;\n        vector<pair<int,int>> order;\n        int cx=0, cy=0;\n        int remaining = N*N - 1;\n        while(remaining > 0){\n            int bestx=-1, besty=-1;\n            double bestScore = -1;\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n                if(vis[i][j]) continue;\n                int dd = dist[cx][cy][i][j];\n                double score = (double)d[i][j] / (dd + 1);\n                if(score > bestScore){\n                    bestScore = score;\n                    bestx = i; besty = j;\n                }\n            }\n            // Also add intermediate unvisited cells on the path\n            auto p = bfs_path(cx, cy, bestx, besty);\n            int tx=cx, ty=cy;\n            for(int dir : p){\n                tx += dx[dir]; ty += dy[dir];\n                if(!vis[tx][ty]){\n                    vis[tx][ty] = true;\n                    remaining--;\n                    order.push_back({tx, ty});\n                }\n            }\n            cx = bestx; cy = besty;\n        }\n        return order;\n    };\n    \n    vector<pair<int,int>> waypoints = greedyOrder();\n    vector<int> bestRoute = buildRoute(waypoints);\n    double bestScore = computeScore(bestRoute);\n    \n    // Also try DFS-based route\n    {\n        double dfsScore = computeScore(baseTour);\n        if(dfsScore < bestScore){\n            bestScore = dfsScore;\n            bestRoute = baseTour;\n        }\n    }\n    \n    // Now try adding extra visits to high-d cells\n    // The idea: insert detours to high-d cells at various points in the route\n    // For a cell visited k times with equal spacing, contribution \u2248 d * L / (2k)\n    // Adding one more visit (round-trip cost 2*dist) increases L by 2*dist but makes it k+1 visits\n    // New contribution \u2248 d * (L + 2*dist) / (2*(k+1))\n    // Benefit = d*L/(2k) - d*(L+2*dist)/(2*(k+1)) = d/(2k(k+1)) * (L - 2k*dist)\n    // Worth it if L > 2k*dist\n    \n    // Let's try a different approach: build the route from scratch with planned revisits\n    // For each cell, determine optimal number of visits k_i proportional to sqrt(d[i][j])\n    // Then total path length should accommodate these visits\n    \n    // Simpler iterative approach: given current route, find the best detour to insert\n    auto insertDetours = [&](vector<int>& route) {\n        int L = route.size();\n        if(L >= 99000) return;\n        \n        // Compute visit times for each cell\n        vector<vector<vector<int>>> visitTimes(N, vector<vector<int>>(N));\n        int cx=0, cy=0;\n        visitTimes[0][0].push_back(0);\n        vector<pair<int,int>> positions;\n        positions.push_back({0,0});\n        for(int t=0; t<L; t++){\n            cx += dx[route[t]]; cy += dy[route[t]];\n            visitTimes[cx][cy].push_back(t+1);\n            positions.push_back({cx,cy});\n        }\n        \n        // For each cell, compute current contribution\n        // Find the cell+position combination that gives best improvement\n        // Try inserting a round-trip detour to a high-d cell at some point in the route\n        \n        // Score improvement for inserting a detour of cost C at position t in the route\n        // to visit cell (gi, gj):\n        // This splits some gap for (gi,gj) and adds C to all gaps' effective L\n        // Complex to compute exactly, so let's use the approximation\n        \n        // Find max-contribution cell\n        double maxContrib = -1;\n        int mi=-1, mj=-1;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            auto& vt = visitTimes[i][j];\n            int k = vt.size();\n            double contrib = 0;\n            for(int a=0;a<k;a++){\n                int gap = (a+1<k) ? vt[a+1]-vt[a] : L-vt[a]+vt[0];\n                contrib += (double)d[i][j] * gap * (gap-1) / 2.0;\n            }\n            contrib /= L;\n            if(contrib > maxContrib){\n                maxContrib = contrib;\n                mi = i; mj = j;\n            }\n        }\n        \n        // Find the largest gap for this cell\n        auto& vt = visitTimes[mi][mj];\n        int bestGapStart = -1, bestGapLen = 0;\n        int k = vt.size();\n        for(int a=0;a<k;a++){\n            int gap = (a+1<k) ? vt[a+1]-vt[a] : L-vt[a]+vt[0];\n            if(gap > bestGapLen){\n                bestGapLen = gap;\n                bestGapStart = a;\n            }\n        }\n        \n        // Insert at middle of this gap\n        int insertTime;\n        if(bestGapStart+1 < k){\n            insertTime = (vt[bestGapStart] + vt[bestGapStart+1]) / 2;\n        } else {\n            insertTime = (vt[bestGapStart] + L + vt[0]) / 2;\n            if(insertTime >= L) insertTime -= L;\n        }\n        \n        // Position at insertTime\n        auto [px, py] = positions[insertTime];\n        int detourCost = 2 * dist[px][py][mi][mj];\n        \n        if((int)route.size() + detourCost > 99000) return;\n        \n        // Build detour path\n        auto pathTo = bfs_path(px, py, mi, mj);\n        auto pathBack = bfs_path(mi, mj, px, py);\n        \n        // Insert into route at position insertTime\n        vector<int> newRoute;\n        for(int t=0; t<insertTime; t++) newRoute.push_back(route[t]);\n        for(int dir : pathTo) newRoute.push_back(dir);\n        for(int dir : pathBack) newRoute.push_back(dir);\n        for(int t=insertTime; t<L; t++) newRoute.push_back(route[t]);\n        \n        double newScore = computeScore(newRoute);\n        if(newScore < bestScore){\n            bestScore = newScore;\n            route = newRoute;\n            bestRoute = newRoute;\n        }\n    };\n    \n    // Repeatedly insert detours\n    for(int iter=0; iter<2000; iter++){\n        auto elapsed = chrono::steady_clock::now() - startTime;\n        if(chrono::duration_cast<chrono::milliseconds>(elapsed).count() > 1800) break;\n        int oldSize = bestRoute.size();\n        insertDetours(bestRoute);\n        if((int)bestRoute.size() == oldSize) break; // no improvement\n    }\n    \n    // Output\n    string ans;\n    for(int dir : bestRoute) ans += dc[dir];\n    cout << ans << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N, M;\n    cin >> N >> M;\n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<string> grid(N);\n    for(int i=0;i<N;i++) cin >> grid[i];\n    \n    vector<string> words(M);\n    for(int i=0;i<M;i++) cin >> words[i];\n    \n    vector<vector<pair<int,int>>> charpos(26);\n    for(int i=0;i<N;i++)\n        for(int j=0;j<N;j++)\n            charpos[grid[i][j]-'A'].push_back({i,j});\n    \n    // Remove words contained in other words\n    vector<bool> removed(M, false);\n    for(int i=0;i<M;i++) if(!removed[i])\n        for(int j=0;j<M;j++) if(i!=j && !removed[j])\n            if(words[i].find(words[j]) != string::npos) removed[j]=true;\n    \n    vector<string> ws;\n    vector<int> origIdx;\n    for(int i=0;i<M;i++) if(!removed[i]) { ws.push_back(words[i]); origIdx.push_back(i); }\n    \n    int n = ws.size();\n    \n    // Compute overlap matrix\n    vector<vector<int>> ov(n, vector<int>(n, 0));\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j){\n        int maxo = min(ws[i].size(), ws[j].size());\n        for(int o=maxo; o>=1; o--){\n            bool match=true;\n            for(int k=0;k<o;k++) if(ws[i][ws[i].size()-o+k]!=ws[j][k]){match=false;break;}\n            if(match){ov[i][j]=o;break;}\n        }\n    }\n    \n    // Greedy superstring with overlap matrix\n    vector<bool> used(n,false);\n    vector<int> nxt(n,-1), prv(n,-1);\n    \n    // Collect all (overlap, i, j) pairs sorted by overlap desc\n    vector<tuple<int,int,int>> edges;\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j && ov[i][j]>0)\n        edges.push_back({ov[i][j],i,j});\n    sort(edges.rbegin(), edges.rend());\n    \n    vector<bool> hasNext(n,false), hasPrev(n,false);\n    // Union-find to prevent cycles\n    vector<int> par(n);\n    iota(par.begin(),par.end(),0);\n    function<int(int)> find=[&](int x)->int{return par[x]==x?x:par[x]=find(par[x]);};\n    \n    for(auto [o,i,j]:edges){\n        if(hasNext[i]||hasPrev[j]) continue;\n        if(find(i)==find(j)) continue;\n        nxt[i]=j; prv[j]=i;\n        hasNext[i]=true; hasPrev[j]=true;\n        par[find(i)]=find(j);\n    }\n    \n    // Build chains\n    vector<int> starts;\n    for(int i=0;i<n;i++) if(!hasPrev[i]) starts.push_back(i);\n    \n    string target;\n    for(int s:starts){\n        int cur=s;\n        bool first=true;\n        while(cur!=-1){\n            if(first){ target+=ws[cur]; first=false; }\n            else{\n                int p=prv[cur]!=-1?prv[cur]:-1;\n                // we know nxt[prev]==cur\n                // find the overlap between prev and cur\n                int prev=-1;\n                for(int i=0;i<n;i++) if(nxt[i]==cur){prev=i;break;}\n                if(prev>=0) target+=ws[cur].substr(ov[prev][cur]);\n                else target+=ws[cur];\n            }\n            cur=nxt[cur];\n        }\n    }\n    \n    if((int)target.size()>5000) target=target.substr(0,5000);\n    int L=target.size();\n    \n    // Beam search for grid positions\n    // State: position (i,j), encoded as i*N+j\n    int BEAM=200;\n    \n    struct State {\n        int pos; // i*N+j\n        int cost;\n        int parent;\n    };\n    \n    vector<vector<State>> layers(L+1);\n    // Initial layer\n    layers[0].push_back({si*N+sj, 0, -1});\n    \n    for(int step=0;step<L;step++){\n        int ch=target[step]-'A';\n        auto& cur=layers[step];\n        // For each state in cur, expand to all positions with char ch\n        map<int, pair<int,int>> best; // pos -> (cost, parent_idx)\n        for(int idx=0;idx<(int)cur.size();idx++){\n            int ci2=cur[idx].pos/N, cj2=cur[idx].pos%N;\n            int cc=cur[idx].cost;\n            for(auto [ni,nj]:charpos[ch]){\n                int nc=cc+abs(ni-ci2)+abs(nj-cj2)+1;\n                int npos=ni*N+nj;\n                auto it=best.find(npos);\n                if(it==best.end()||nc<it->second.first){\n                    best[npos]={nc,idx};\n                }\n            }\n        }\n        // Keep top BEAM by cost\n        vector<tuple<int,int,int>> candidates; // cost, pos, parent\n        for(auto& [pos,ci3]:best) candidates.push_back({ci3.first,pos,ci3.second});\n        sort(candidates.begin(),candidates.end());\n        if((int)candidates.size()>BEAM) candidates.resize(BEAM);\n        \n        for(auto& [c,p,par]:candidates){\n            layers[step+1].push_back({p,c,par});\n        }\n    }\n    \n    // Find best final state\n    int bestIdx=0;\n    for(int i=1;i<(int)layers[L].size();i++)\n        if(layers[L][i].cost<layers[L][bestIdx].cost) bestIdx=i;\n    \n    // Trace back\n    vector<pair<int,int>> result(L);\n    int idx=bestIdx;\n    for(int step=L;step>=1;step--){\n        int pos=layers[step][idx].pos;\n        result[step-1]={pos/N, pos%N};\n        idx=layers[step][idx].parent;\n    }\n    \n    for(int p=0;p<L;p++) cout<<result[p].first<<\" \"<<result[p].second<<\"\\n\";\n}","ahc030":"#include<bits/stdc++.h>\nusing namespace std;\nmt19937 rng(42);\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M; double eps;\n    cin>>N>>M>>eps;\n    \n    vector<vector<pair<int,int>>> fields(M);\n    for(int k=0;k<M;k++){\n        int d; cin>>d; fields[k].resize(d);\n        for(int i=0;i<d;i++) cin>>fields[k][i].first>>fields[k][i].second;\n    }\n    \n    // Enumerate placements\n    vector<vector<int>> place_id(M);\n    // For each field k, placement p: bitmask or grid contribution\n    // Store as vector of (i,j)\n    vector<vector<vector<pair<int,int>>>> psquares(M);\n    \n    for(int k=0;k<M;k++){\n        int maxi=0,maxj=0;\n        for(auto&[r,c]:fields[k]){maxi=max(maxi,r);maxj=max(maxj,c);}\n        for(int di=0;di+maxi<N;di++){\n            for(int dj=0;dj+maxj<N;dj++){\n                vector<pair<int,int>> sq;\n                for(auto&[r,c]:fields[k]) sq.push_back({r+di,c+dj});\n                psquares[k].push_back(sq);\n            }\n        }\n    }\n    \n    // Precompute row sums and col sums for each placement\n    int nrows=N, ncols=N;\n    vector<vector<vector<int>>> prow(M), pcol(M);\n    for(int k=0;k<M;k++){\n        int np=psquares[k].size();\n        prow[k].resize(np,vector<int>(N,0));\n        pcol[k].resize(np,vector<int>(N,0));\n        for(int p=0;p<np;p++){\n            for(auto&[r,c]:psquares[k][p]){\n                prow[k][p][r]++;\n                pcol[k][p][c]++;\n            }\n        }\n    }\n    \n    // Query rows via divination\n    vector<int> row_obs(N), col_obs(N);\n    double total_cost = 0;\n    \n    // For small eps, divination is accurate. Query each row.\n    auto query_set = [&](vector<pair<int,int>>& S) -> int {\n        int d=S.size();\n        cout<<\"q \"<<d;\n        for(auto&[i,j]:S) cout<<\" \"<<i<<\" \"<<j;\n        cout<<endl;\n        int v; cin>>v;\n        return v;\n    };\n    \n    // Query rows\n    for(int i=0;i<N;i++){\n        vector<pair<int,int>> S;\n        for(int j=0;j<N;j++) S.push_back({i,j});\n        row_obs[i]=query_set(S);\n        total_cost += 1.0/sqrt(N);\n    }\n    // Query cols\n    for(int j=0;j<N;j++){\n        vector<pair<int,int>> S;\n        for(int i=0;i<N;i++) S.push_back({i,j});\n        col_obs[j]=query_set(S);\n        total_cost += 1.0/sqrt(N);\n    }\n    \n    // Multiple row/col queries for better accuracy when eps is large\n    int extra_rounds = (eps > 0.1) ? 2 : 0;\n    vector<vector<int>> row_obs_all(N), col_obs_all(N);\n    for(int i=0;i<N;i++) row_obs_all[i].push_back(row_obs[i]);\n    for(int j=0;j<N;j++) col_obs_all[j].push_back(col_obs[j]);\n    \n    for(int r=0;r<extra_rounds;r++){\n        for(int i=0;i<N;i++){\n            vector<pair<int,int>> S;\n            for(int j=0;j<N;j++) S.push_back({i,j});\n            int v=query_set(S);\n            row_obs_all[i].push_back(v);\n            total_cost+=1.0/sqrt(N);\n        }\n        for(int j=0;j<N;j++){\n            vector<pair<int,int>> S;\n            for(int i=0;i<N;i++) S.push_back({i,j});\n            int v=query_set(S);\n            col_obs_all[j].push_back(v);\n            total_cost+=1.0/sqrt(N);\n        }\n    }\n    \n    // Use median of observations\n    for(int i=0;i<N;i++){\n        sort(row_obs_all[i].begin(),row_obs_all[i].end());\n        row_obs[i]=row_obs_all[i][row_obs_all[i].size()/2];\n    }\n    for(int j=0;j<N;j++){\n        sort(col_obs_all[j].begin(),col_obs_all[j].end());\n        col_obs[j]=col_obs_all[j][col_obs_all[j].size()/2];\n    }\n    \n    // Log-likelihood of observing row_obs given true sum v(S) with k=N squares\n    // Mean = (N - v(S))*eps + v(S)*(1-eps) = N*eps + v(S)*(1-2*eps)\n    // Variance = N*eps*(1-eps)\n    auto log_prob_obs = [&](int obs, int true_sum, int k) -> double {\n        double mu = (double)(k - true_sum)*eps + (double)true_sum*(1.0-eps);\n        double sigma2 = (double)k * eps * (1.0-eps);\n        double sigma = sqrt(sigma2);\n        // obs is round(x) where x ~ N(mu, sigma2), then max(0,.)\n        // P(obs) \u2248 Phi((obs+0.5-mu)/sigma) - Phi((obs-0.5-mu)/sigma)\n        // For obs=0, P(0) = Phi((0.5-mu)/sigma)\n        double lo = (obs - 0.5 - mu)/sigma;\n        double hi = (obs + 0.5 - mu)/sigma;\n        if(obs==0) lo = -1e9;\n        double p = 0.5*erfc(-hi/sqrt(2.0)) - 0.5*erfc(-lo/sqrt(2.0));\n        if(p < 1e-300) p = 1e-300;\n        return log(p);\n    };\n    \n    // MCMC: sample placement indices for each field\n    // State: choice[k] = index of placement for field k\n    vector<int> choice(M);\n    for(int k=0;k<M;k++) choice[k] = rng()%psquares[k].size();\n    \n    auto compute_ll = [&](vector<int>& ch) -> double {\n        double ll=0;\n        for(int i=0;i<N;i++){\n            int s=0;\n            for(int k=0;k<M;k++) s+=prow[k][ch[k]][i];\n            for(auto& obs:row_obs_all[i])\n                ll+=log_prob_obs(obs,s,N);\n        }\n        for(int j=0;j<N;j++){\n            int s=0;\n            for(int k=0;k<M;k++) s+=pcol[k][ch[k]][j];\n            for(auto& obs:col_obs_all[j])\n                ll+=log_prob_obs(obs,s,N);\n        }\n        return ll;\n    };\n    \n    double cur_ll = compute_ll(choice);\n    \n    // Count how often each cell is occupied\n    vector<vector<double>> occ_count(N, vector<double>(N,0));\n    int samples=0;\n    int total_iters=200000;\n    int burnin=50000;\n    \n    for(int iter=0;iter<total_iters;iter++){\n        int k=rng()%M;\n        int old_p=choice[k];\n        int new_p=rng()%psquares[k].size();\n        choice[k]=new_p;\n        double new_ll=compute_ll(choice);\n        double accept = exp(min(0.0, new_ll-cur_ll));\n        if(uniform_real_distribution<double>(0,1)(rng) < accept){\n            cur_ll=new_ll;\n        } else {\n            choice[k]=old_p;\n        }\n        \n        if(iter>=burnin){\n            for(int kk=0;kk<M;kk++){\n                for(auto&[r,c]:psquares[kk][choice[kk]]){\n                    occ_count[r][c]+=1.0;\n                }\n            }\n            samples++;\n        }\n    }\n    \n    // Normalize\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) occ_count[i][j]/=samples;\n    \n    // Track drilled squares and known oil\n    vector<vector<int>> known(N, vector<int>(N,-1));\n    set<pair<int,int>> confirmed_oil;\n    set<pair<int,int>> confirmed_empty;\n    int ops_used = N*(1+extra_rounds)*2; // row+col queries\n    int max_ops = 2*N*N;\n    \n    // Drill uncertain squares (probability between 0.1 and 0.9)\n    vector<tuple<double,int,int>> uncertain;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        double p=occ_count[i][j];\n        double unc = min(p, 1-p);\n        if(unc > 0.01) uncertain.push_back({-unc,i,j}); // sort by most uncertain first... actually sort by closest to 0.5\n    }\n    sort(uncertain.begin(),uncertain.end()); // most uncertain first (most negative = highest unc)\n    \n    // Drill the most uncertain ones\n    for(auto&[u,i,j]:uncertain){\n        if(ops_used >= max_ops-1) break;\n        cout<<\"q 1 \"<<i<<\" \"<<j<<endl;\n        int v; cin>>v;\n        known[i][j]=v;\n        ops_used++;\n        if(v>0) confirmed_oil.insert({i,j});\n        else confirmed_empty.insert({i,j});\n    }\n    \n    // Re-run MCMC with drilling constraints\n    // Reset\n    for(int k=0;k<M;k++) choice[k]=rng()%psquares[k].size();\n    \n    auto is_consistent = [&](vector<int>& ch) -> bool {\n        vector<vector<int>> grid(N, vector<int>(N,0));\n        for(int kk=0;kk<M;kk++)\n            for(auto&[r,c]:psquares[kk][ch[kk]]) grid[r][c]++;\n        for(auto&[r,c]:confirmed_oil) if(grid[r][c]==0) return false;\n        for(auto&[r,c]:confirmed_empty) if(grid[r][c]!=0) return false;\n        return true;\n    };\n    \n    // Find a consistent starting point\n    for(int t=0;t<1000000;t++){\n        int k=rng()%M;\n        choice[k]=rng()%psquares[k].size();\n        if(is_consistent(choice)) break;\n    }\n    \n    cur_ll=compute_ll(choice);\n    fill(occ_count.begin(),occ_count.end(),vector<double>(N,0));\n    samples=0;\n    \n    for(int iter=0;iter<total_iters;iter++){\n        int k=rng()%M;\n        int old_p=choice[k];\n        int new_p=rng()%psquares[k].size();\n        choice[k]=new_p;\n        if(!is_consistent(choice)){\n            choice[k]=old_p;\n            continue;\n        }\n        double new_ll=compute_ll(choice);\n        double accept=exp(min(0.0,new_ll-cur_ll));\n        if(uniform_real_distribution<double>(0,1)(rng)<accept){\n            cur_ll=new_ll;\n        } else {\n            choice[k]=old_p;\n        }\n        if(iter>=burnin){\n            for(int kk=0;kk<M;kk++)\n                for(auto&[r,c]:psquares[kk][choice[kk]])\n                    occ_count[r][c]+=1.0;\n            samples++;\n        }\n    }\n    if(samples>0) for(int i=0;i<N;i++)for(int j=0;j<N;j++) occ_count[i][j]/=samples;\n    \n    // Guess: squares with probability > 0.5, plus all confirmed oil\n    vector<pair<int,int>> ans;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(confirmed_oil.count({i,j}) || (occ_count[i][j]>0.5 && !confirmed_empty.count({i,j})))\n            ans.push_back({i,j});\n    }\n    \n    // Make sure confirmed oil is included\n    for(auto&p:confirmed_oil){\n        bool found=false;\n        for(auto&q:ans) if(q==p) found=true;\n        if(!found) ans.push_back(p);\n    }\n    \n    cout<<\"a \"<<ans.size();\n    for(auto&[i,j]:ans) cout<<\" \"<<i<<\" \"<<j;\n    cout<<endl;\n    int resp; cin>>resp;\n    if(resp==1) return 0;\n    \n    // Fallback: drill remaining\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(known[i][j]>=0) continue;\n        if(ops_used>=max_ops-1) break;\n        cout<<\"q 1 \"<<i<<\" \"<<j<<endl;\n        int v; cin>>v;\n        known[i][j]=v;\n        ops_used++;\n        if(v>0) confirmed_oil.insert({i,j});\n    }\n    \n    vector<pair<int,int>> ans2;\n    for(auto&p:confirmed_oil) ans2.push_back(p);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(known[i][j]<0 && occ_count[i][j]>0.5) ans2.push_back({i,j});\n    }\n    // deduplicate\n    sort(ans2.begin(),ans2.end());\n    ans2.erase(unique(ans2.begin(),ans2.end()),ans2.end());\n    \n    cout<<\"a \"<<ans2.size();\n    for(auto&[i,j]:ans2) cout<<\" \"<<i<<\" \"<<j;\n    cout<<endl;\n    cin>>resp;\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint W, D, N;\nvector<vector<int>> a;\nstruct Rect { int i0,j0,i1,j1; };\n\nvoid partition(vector<pair<int,int>>& items, int r0, int c0, int r1, int c1, vector<Rect>& result, bool hsplit) {\n    if (items.size() == 1) {\n        result[items[0].second] = {r0, c0, r1, c1};\n        return;\n    }\n    long long total = 0;\n    for (auto& p : items) total += p.first;\n    if (total == 0) total = 1;\n    \n    int n = items.size();\n    int mid = n / 2;\n    long long left_sum = 0;\n    for (int i = 0; i < mid; i++) left_sum += items[i].first;\n    \n    vector<pair<int,int>> left_items(items.begin(), items.begin()+mid);\n    vector<pair<int,int>> right_items(items.begin()+mid, items.end());\n    \n    if (hsplit) {\n        int split = r0 + max(1, min(r1-r0-1, (int)round((double)left_sum / total * (r1-r0))));\n        if (r1 - split < (int)right_items.size()) split = r1 - (int)right_items.size();\n        if (split - r0 < (int)left_items.size()) split = r0 + (int)left_items.size();\n        split = max(r0+1, min(r1-1, split));\n        partition(left_items, r0, c0, split, c1, result, !hsplit);\n        partition(right_items, split, c0, r1, c1, result, !hsplit);\n    } else {\n        int split = c0 + max(1, min(c1-c0-1, (int)round((double)left_sum / total * (c1-c0))));\n        if (c1 - split < (int)right_items.size()) split = c1 - (int)right_items.size();\n        if (split - c0 < (int)left_items.size()) split = c0 + (int)left_items.size();\n        split = max(c0+1, min(c1-1, split));\n        partition(left_items, r0, c0, r1, split, result, !hsplit);\n        partition(right_items, r0, split, r1, c1, result, !hsplit);\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> W >> D >> N;\n    a.resize(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    for(int d=0;d<D;d++){\n        vector<pair<int,int>> items(N);\n        for(int k=0;k<N;k++) items[k]={a[d][k], k};\n        vector<Rect> res(N);\n        partition(items, 0, 0, W, W, res, true);\n        for(int k=0;k<N;k++){\n            cout<<res[k].i0<<\" \"<<res[k].j0<<\" \"<<res[k].i1<<\" \"<<res[k].j1<<\"\\n\";\n        }\n    }\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<vector<long long>> a(N, vector<long long>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin >> a[i][j];\n    \n    vector<array<array<long long,3>,3>> s(M);\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    auto rebuild = [&](vector<vector<long long>>& b, const vector<tuple<int,int,int>>& ops){\n        b = a;\n        for(auto&[m,p,q]: ops)\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++)\n                b[p+i][q+j] += s[m][i][j];\n    };\n    \n    auto calcScore = [&](vector<vector<long long>>& b) -> long long {\n        long long sc = 0;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++) sc += b[i][j] % MOD;\n        return sc;\n    };\n    \n    // Greedy initial solution\n    vector<vector<long long>> b = a;\n    vector<tuple<int,int,int>> ops;\n    for(int step=0; step<K; step++){\n        int bm=-1,bp=-1,bq=-1; long long bd=0;\n        for(int m=0;m<M;m++) for(int p=0;p<=N-3;p++) for(int q=0;q<=N-3;q++){\n            long long d=0;\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++){\n                long long ov=b[p+i][q+j]%MOD, nv=(b[p+i][q+j]+s[m][i][j])%MOD;\n                d+=nv-ov;\n            }\n            if(d>bd){bd=d;bm=m;bp=p;bq=q;}\n        }\n        if(bd<=0) break;\n        ops.push_back({bm,bp,bq});\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[bp+i][bq+j]+=s[bm][i][j];\n    }\n    \n    long long bestScore = calcScore(b);\n    auto bestOps = ops;\n    \n    // SA: iteratively re-optimize each slot\n    mt19937 rng(42);\n    auto startTime = chrono::steady_clock::now();\n    \n    while(true){\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now-startTime).count();\n        if(elapsed > 1.85) break;\n        \n        // Re-optimize each operation in order\n        bool improved = false;\n        for(int idx=0; idx<(int)ops.size(); idx++){\n            rebuild(b, ops);\n            auto [om,op,oq]=ops[idx];\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[op+i][oq+j]-=s[om][i][j];\n            int bm=-1,bp=-1,bq=-1; long long bd=0;\n            for(int m=0;m<M;m++) for(int p=0;p<=N-3;p++) for(int q=0;q<=N-3;q++){\n                long long d=0;\n                for(int i=0;i<3;i++) for(int j=0;j<3;j++){\n                    long long ov=b[p+i][q+j]%MOD, nv=(b[p+i][q+j]+s[m][i][j])%MOD;\n                    d+=nv-ov;\n                }\n                if(d>bd){bd=d;bm=m;bp=p;bq=q;}\n            }\n            if(bm>=0 && (bm!=om||bp!=op||bq!=oq)){ops[idx]={bm,bp,bq}; improved=true;}\n        }\n        if(!improved) break;\n        rebuild(b,ops);\n        long long sc=calcScore(b);\n        if(sc>bestScore){bestScore=sc;bestOps=ops;}\n    }\n    \n    cout << bestOps.size() << \"\\n\";\n    for(auto&[m,p,q]: bestOps) cout << m << \" \" << p << \" \" << q << \"\\n\";\n}","ahc033":"#include<bits/stdc++.h>\nusing namespace std;\n\nconst int N=5;\nint A[N][N];\nint grid[N][N]; // -1=empty\nint cr[N],cc[N],ch[N];\nbool calive[N];\nint recv_idx[N];\nint next_disp[N];\nstring act[N];\nint dispatched_count[N]; // how many dispatched from each gate\nvector<int> dispatch_order[N]; // what was dispatched from each gate\n\nvoid do_receive(){\n    for(int i=0;i<N;i++){\n        if(recv_idx[i]>=N) continue;\n        if(grid[i][0]!=-1) continue;\n        bool blocked=false;\n        for(int c=0;c<N;c++){\n            if(calive[c]&&cr[c]==i&&cc[c]==0&&ch[c]!=-1){blocked=true;break;}\n        }\n        if(!blocked){\n            grid[i][0]=A[i][recv_idx[i]];\n            recv_idx[i]++;\n        }\n    }\n}\n\nvoid do_dispatch(){\n    for(int i=0;i<N;i++){\n        if(grid[i][N-1]!=-1){\n            dispatch_order[i].push_back(grid[i][N-1]);\n            grid[i][N-1]=-1;\n            dispatched_count[i]++;\n        }\n    }\n}\n\nvoid add_action(int turn_actions[N]){\n    // turn_actions: 0='.', 1='P', 2='Q', 3='U', 4='D', 5='L', 6='R', 7='B'\n    const char chars[]={'.','P','Q','U','D','L','R','B'};\n    for(int i=0;i<N;i++) act[i]+=chars[turn_actions[i]];\n}\n\nvoid do_turn(string actions_str){\n    // actions_str is length N\n    do_receive();\n    for(int i=0;i<N;i++){\n        char c=actions_str[i];\n        act[i]+=c;\n        if(!calive[i]) continue;\n        switch(c){\n            case 'P': ch[i]=grid[cr[i]][cc[i]]; grid[cr[i]][cc[i]]=-1; break;\n            case 'Q': grid[cr[i]][cc[i]]=ch[i]; ch[i]=-1; break;\n            case 'U': cr[i]--; break;\n            case 'D': cr[i]++; break;\n            case 'L': cc[i]--; break;\n            case 'R': cc[i]++; break;\n            case 'B': calive[i]=false; break;\n            case '.': break;\n        }\n    }\n    do_dispatch();\n}\n\n// BFS for large crane (crane 0) - can move over containers even while carrying\nvector<char> bfs_path(int sr,int sc,int tr,int tc){\n    if(sr==tr&&sc==tc) return {};\n    int dist[N][N];\n    int prev_dir[N][N];\n    memset(dist,-1,sizeof(dist));\n    dist[sr][sc]=0;\n    queue<pair<int,int>> q;\n    q.push({sr,sc});\n    int dr[]={-1,1,0,0};\n    int dc[]={0,0,-1,1};\n    char dm[]={'U','D','L','R'};\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>=N||nc<0||nc>=N) continue;\n            if(dist[nr][nc]!=-1) continue;\n            // Check no other alive crane at (nr,nc)\n            bool crane_there=false;\n            for(int k=1;k<N;k++){\n                if(calive[k]&&cr[k]==nr&&cc[k]==nc){crane_there=true;break;}\n            }\n            if(crane_there) continue;\n            dist[nr][nc]=dist[r][c]+1;\n            prev_dir[nr][nc]=d;\n            q.push({nr,nc});\n        }\n    }\n    if(dist[tr][tc]==-1) return {'X'}; // unreachable\n    vector<char> path;\n    int r=tr,c=tc;\n    while(r!=sr||c!=sc){\n        int d=prev_dir[r][c];\n        path.push_back(dm[d]);\n        r-=dr[d]; c-=dc[d];\n    }\n    reverse(path.begin(),path.end());\n    return path;\n}\n\nvoid execute_crane0_move(char c){\n    string s(N,'.');\n    s[0]=c;\n    do_turn(s);\n}\n\nvoid execute_crane0_path(vector<char>& path){\n    for(char c:path) execute_crane0_move(c);\n}\n\nbool move_crane0_to(int tr,int tc){\n    auto path=bfs_path(cr[0],cc[0],tr,tc);\n    if(!path.empty()&&path[0]=='X') return false;\n    execute_crane0_path(path);\n    return true;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    int n; cin>>n;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>A[i][j];\n    memset(grid,-1,sizeof(grid));\n    for(int i=0;i<N;i++){cr[i]=i;cc[i]=0;ch[i]=-1;calive[i]=true;}\n    for(int i=0;i<N;i++){recv_idx[i]=0;next_disp[i]=i*N;dispatched_count[i]=0;}\n\n    // Bomb small cranes immediately\n    {\n        string s(N,'B');\n        s[0]='.';\n        do_turn(s);\n    }\n\n    // Now use large crane only\n    // Strategy: repeatedly find the most valuable container to deliver\n    // Value: containers needed at dispatch gates now are highest priority\n    // Also need to clear receiving gates to get more containers in\n\n    // Location tracking for containers\n    auto find_container=[&](int id)->pair<int,int>{\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(grid[i][j]==id)return{i,j};\n        return{-1,-1};\n    };\n\n    auto find_empty=[&](int pref_r, int pref_c)->pair<int,int>{\n        // Find empty cell closest to (pref_r,pref_c), avoid column N-1 (dispatch gates)\n        int best_d=1000,br=-1,bc=-1;\n        for(int i=0;i<N;i++)for(int j=0;j<N-1;j++){\n            if(grid[i][j]!=-1) continue;\n            bool crane_there=false;\n            for(int k=0;k<N;k++) if(calive[k]&&cr[k]==i&&cc[k]==j){crane_there=true;break;}\n            if(crane_there) continue;\n            int d=abs(i-pref_r)+abs(j-pref_c);\n            if(d<best_d){best_d=d;br=i;bc=j;}\n        }\n        return{br,bc};\n    };\n\n    int turns=1;\n    int max_turns=9500;\n\n    while(turns<max_turns){\n        // Check if all dispatched\n        int total_left=0;\n        for(int i=0;i<N;i++) total_left+=(N-dispatched_count[i]);\n        // Also count containers held or on grid or not yet received\n        int on_grid=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++) if(grid[i][j]!=-1) on_grid++;\n        int not_recv=0;\n        for(int i=0;i<N;i++) not_recv+=(N-recv_idx[i]);\n        int held=(ch[0]!=-1)?1:0;\n        if(on_grid+not_recv+held==0) break;\n\n        // Priority 1: deliver a container that's next needed at its dispatch gate\n        int best_id=-1,best_r=-1,best_c=-1,best_tr=-1,best_cost=1e9;\n        \n        for(int row=0;row<N;row++){\n            int need=next_disp[row];\n            if(need>=row*N+N) continue;\n            auto [r,c]=find_container(need);\n            if(r==-1) continue;\n            int cost=abs(cr[0]-r)+abs(cc[0]-c)+abs(r-row)+(N-1-c);\n            if(cost<best_cost){best_cost=cost;best_id=need;best_r=r;best_c=c;best_tr=row;}\n        }\n\n        if(best_id!=-1){\n            // Go pick it up and deliver to (best_tr, N-1)\n            if(!move_crane0_to(best_r,best_c)){execute_crane0_move('.');turns++;continue;}\n            turns+=best_cost; // approximate\n            \n            if(cr[0]==best_r&&cc[0]==best_c&&grid[cr[0]][cc[0]]==best_id){\n                execute_crane0_move('P');turns++;\n                \n                // Now move to dispatch gate\n                int tr=best_tr,tc=N-1;\n                // If dispatch gate has a container, it'll be dispatched at end of turn\n                // So we might need to wait or go to adjacent\n                \n                // Move toward dispatch gate\n                auto path=bfs_path(cr[0],cc[0],tr,tc);\n                if(!path.empty()&&path[0]=='X'){\n                    // Can't reach, drop somewhere\n                    auto [er,ec]=find_empty(cr[0],cc[0]);\n                    if(er!=-1){\n                        move_crane0_to(er,ec);\n                        execute_crane0_move('Q');turns++;\n                    }\n                    continue;\n                }\n                execute_crane0_path(path);\n                turns+=path.size();\n                \n                // Check if we can place\n                if(grid[cr[0]][cc[0]]==-1){\n                    execute_crane0_move('Q');turns++;\n                    // It will be dispatched at end of this turn\n                    next_disp[best_tr]++;\n                } else {\n                    // Gate occupied, wait one turn for it to dispatch\n                    execute_crane0_move('.');turns++;\n                    if(grid[cr[0]][cc[0]]==-1){\n                        execute_crane0_move('Q');turns++;\n                        next_disp[best_tr]++;\n                    } else {\n                        auto [er,ec]=find_empty(tr,tc);\n                        if(er!=-1){\n                            move_crane0_to(er,ec);\n                            execute_crane0_move('Q');turns++;\n                        }\n                    }\n                }\n                continue;\n            }\n        }\n\n        // Priority 2: Move a container from receiving gate to buffer to free up gates\n        bool moved=false;\n        for(int i=0;i<N;i++){\n            if(grid[i][0]!=-1){\n                // Move this container to buffer\n                auto path=bfs_path(cr[0],cc[0],i,0);\n                if(!path.empty()&&path[0]=='X') continue;\n                execute_crane0_path(path);\n                if(cr[0]==i&&cc[0]==0&&grid[i][0]!=-1){\n                    execute_crane0_move('P');\n                    // Find buffer spot\n                    auto [er,ec]=find_empty(i,2);\n                    if(er!=-1){\n                        move_crane0_to(er,ec);\n                        execute_crane0_move('Q');\n                        moved=true;\n                        break;\n                    } else {\n                        // Nowhere to put it, try dispatch gate directly\n                        int target_row=ch[0]/N;\n                        move_crane0_to(target_row,N-1);\n                        if(grid[cr[0]][cc[0]]==-1){\n                            execute_crane0_move('Q');\n                        } else {\n                            execute_crane0_move('.');\n                            if(grid[cr[0]][cc[0]]==-1) execute_crane0_move('Q');\n                        }\n                        moved=true;break;\n                    }\n                }\n            }\n        }\n        if(moved) continue;\n\n        // Nothing to do, wait\n        execute_crane0_move('.');\n        turns++;\n    }\n\n    int maxlen=0;\n    for(int i=0;i<N;i++) maxlen=max(maxlen,(int)act[i].size());\n    for(int i=0;i<N;i++) while((int)act[i].size()<maxlen) act[i]+=\".\";\n    for(int i=0;i<N;i++) cout<<act[i]<<\"\\n\";\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\nint cx, cy, load_amt;\nvector<string> ops;\n\nvoid move_to(int tx, int ty) {\n    while (cy > ty) { ops.push_back(\"U\"); cy--; }\n    while (cy < ty) { ops.push_back(\"D\"); cy++; }\n    while (cx > tx) { ops.push_back(\"L\"); cx--; }\n    while (cx < tx) { ops.push_back(\"R\"); cx++; }\n}\n\nint dist(int x1, int y1, int x2, int y2) {\n    return abs(x1-x2) + abs(y1-y2);\n}\n\nint main(){\n    scanf(\"%d\", &N);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) scanf(\"%d\",&h[i][j]);\n    \n    cx=0; cy=0; load_amt=0;\n    \n    // Greedy: repeatedly find nearest positive cell, load, find nearest negative cell, unload\n    while(true){\n        // Find nearest positive cell\n        int best_sd = INT_MAX, bsx=-1, bsy=-1;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            if(h[i][j]>0){\n                int d = dist(cx,cy,j,i);\n                if(d < best_sd){ best_sd=d; bsx=j; bsy=i; }\n            }\n        }\n        if(bsx==-1) break;\n        \n        // Move to source\n        move_to(bsx, bsy);\n        int amt = h[bsy][bsx];\n        ops.push_back(\"+\"+to_string(amt));\n        h[bsy][bsx] = 0;\n        load_amt += amt;\n        \n        // Now deliver to nearest negative cells until empty\n        while(load_amt > 0){\n            int best_dd = INT_MAX, bdx=-1, bdy=-1;\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n                if(h[i][j]<0){\n                    int d = dist(cx,cy,j,i);\n                    if(d < best_dd){ best_dd=d; bdx=j; bdy=i; }\n                }\n            }\n            if(bdx==-1) break;\n            move_to(bdx, bdy);\n            int unload = min(load_amt, -h[bdy][bdx]);\n            ops.push_back(\"-\"+to_string(unload));\n            h[bdy][bdx] += unload;\n            load_amt -= unload;\n        }\n    }\n    \n    for(auto& s : ops) printf(\"%s\\n\", s.c_str());\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <cmath>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,T;\n    cin>>N>>M>>T;\n    int SC=2*N*(N-1); // 60\n    vector<vector<int>>X(SC,vector<int>(M));\n    for(int i=0;i<SC;i++) for(int j=0;j<M;j++) cin>>X[i][j];\n    mt19937 rng(12345);\n    \n    for(int t=0;t<T;t++){\n        auto t0=chrono::steady_clock::now();\n        double tlimit = (t<T-1)?0.15:0.15;\n        \n        // For each criterion, find max value\n        vector<int> maxV(M,0);\n        for(int i=0;i<SC;i++) for(int l=0;l<M;l++) maxV[l]=max(maxV[l],X[i][l]);\n        \n        // Score each seed: sum of how close each criterion is to max\n        vector<int> vals(SC);\n        for(int i=0;i<SC;i++) for(int j=0;j<M;j++) vals[i]+=X[i][j];\n        vector<int> idx(SC); iota(idx.begin(),idx.end(),0);\n        sort(idx.begin(),idx.end(),[&](int a,int b){return vals[a]>vals[b];});\n        vector<int> sel(idx.begin(),idx.begin()+N*N);\n        \n        // Build adjacency list for grid\n        vector<vector<int>> adj(N*N);\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            int p=i*N+j;\n            if(j+1<N) adj[p].push_back(i*N+j+1), adj[i*N+j+1].push_back(p);\n            if(i+1<N) adj[p].push_back((i+1)*N+j), adj[(i+1)*N+j].push_back(p);\n        }\n        // Remove duplicates\n        for(auto&v:adj){sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());}\n        \n        vector<int> perm(N*N); iota(perm.begin(),perm.end(),0);\n        auto nodeScore=[&](int pos,vector<int>&p)->long long{\n            long long s=0; int a=sel[p[pos]];\n            for(int nb:adj[pos]){int b=sel[p[nb]];for(int l=0;l<M;l++) s+=max(X[a][l],X[b][l]);}\n            return s;\n        };\n        long long cs=0;\n        for(int i=0;i<N*N;i++) cs+=nodeScore(i,perm);\n        cs/=2;\n        \n        int iter=0;\n        while(true){\n            if((++iter&1023)==0){auto now=chrono::steady_clock::now();if(chrono::duration<double>(now-t0).count()>tlimit) break;}\n            int a=rng()%(N*N),b=rng()%(N*N); if(a==b) continue;\n            long long old=nodeScore(a,perm)+nodeScore(b,perm);\n            // subtract shared edge\n            bool shared=false; for(int nb:adj[a]) if(nb==b){shared=true;break;}\n            if(shared){int aa=sel[perm[a]],bb=sel[perm[b]];for(int l=0;l<M;l++) old-=max(X[aa][l],X[bb][l]);}\n            swap(perm[a],perm[b]);\n            long long nw=nodeScore(a,perm)+nodeScore(b,perm);\n            if(shared){int aa=sel[perm[a]],bb=sel[perm[b]];for(int l=0;l<M;l++) nw-=max(X[aa][l],X[bb][l]);}\n            double temp=50.0*(1.0-chrono::duration<double>(chrono::steady_clock::now()-t0).count()/tlimit)+0.1;\n            if(nw>=old||(uniform_real_distribution<>()(rng)<exp((nw-old)/temp))){cs+=(nw-old);}\n            else swap(perm[a],perm[b]);\n        }\n        for(int i=0;i<N;i++){for(int j=0;j<N;j++){if(j) cout<<' ';cout<<sel[perm[i*N+j]];}cout<<'\\n';}\n        cout.flush();\n        for(int i=0;i<SC;i++) for(int j=0;j<M;j++) cin>>X[i][j];\n    }\n}","ahc038":"#include<bits/stdc++.h>\nusing namespace std;\nint main(){\n    int N,M,V;scanf(\"%d%d%d\",&N,&M,&V);\n    vector<string>s(N),t(N);\n    for(int i=0;i<N;i++)cin>>s[i];\n    for(int i=0;i<N;i++)cin>>t[i];\n    vector<pair<int,int>>src,tgt;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(s[i][j]=='1'&&t[i][j]=='0')src.push_back({i,j});\n        if(s[i][j]=='0'&&t[i][j]=='1')tgt.push_back({i,j});\n    }\n    // Use star arm: root + (V-1) leaves, each length 1\n    int nleaves=min(V-1,4); // max 4 useful directions with length 1\n    // Actually let's use a chain: root->v1(len1)->v2(len1) giving reach of 2\n    // Or better: root + multiple leaves\n    // For multiple leaves with length 1, they can be at 4 cardinal directions\n    // But after rotation they might overlap - let's use simpler approach\n    \n    // Strategy: single fingertip, but combine rotation+movement\n    printf(\"2\\n0 1\\n0 0\\n\");\n    int rx=0,ry=0,dir=0; // 0=R,1=D,2=L,3=U\n    int dx[]={0,1,0,-1},dy[]={1,0,-1,0};\n    vector<string>ops;\n    \n    auto addOp=[&](char mv,char rot,bool pick){\n        string o(4,'.');\n        o[0]=mv;o[1]=rot;o[3]=pick?'P':'.';\n        ops.push_back(o);\n    };\n    \n    auto rotTo=[&](int nd,char mvch='.',int*prx=nullptr,int*pry=nullptr){\n        while(dir!=nd){\n            int r=(nd-dir+4)%4;\n            char rc=(r<=2)?'R':'L';\n            dir=(r<=2)?(dir+1)%4:(dir+3)%4;\n            addOp(mvch,rc,false);\n            mvch='.';\n            if(prx)*prx=rx;if(pry)*pry=ry;\n        }\n    };\n    \n    // Hungarian-style matching: greedy with reassignment\n    int K=src.size();\n    vector<int>match(K);\n    // Simple: sort targets, match by min cost greedily\n    // Use repeated nearest neighbor from last position\n    vector<bool>us(K),ut(K);\n    vector<int>order;\n    int cx=0,cy=0;\n    for(int i=0;i<K;i++){\n        int bs=-1,bt=-1,bd=1e9;\n        for(int j=0;j<K;j++)if(!us[j]){\n            int ds=abs(src[j].first-cx)+abs(src[j].second-cy);\n            for(int k=0;k<K;k++)if(!ut[k]){\n                int dt=abs(tgt[k].first-src[j].first)+abs(tgt[k].second-src[j].second);\n                if(ds+dt<bd){bd=ds+dt;bs=j;bt=k;}\n            }\n        }\n        us[bs]=ut[bt]=true;\n        order.push_back(bs);match[bs]=bt;\n        cx=tgt[bt].first;cy=tgt[bt].second;\n    }\n    \n    for(int i=0;i<K;i++){\n        int si=order[i],ti=match[si];\n        auto[sx,sy]=src[si];auto[tx,ty]=tgt[ti];\n        // Move to adjacent of source, pick up, move to adjacent of target, drop\n        // Find best direction for source\n        auto bestDir=[&](int px,int py)->int{\n            for(int d=0;d<4;d++){int nx=px-dx[d],ny=py-dy[d];if(nx>=0&&nx<N&&ny>=0&&ny<N)return d;}return 0;\n        };\n        int sd=bestDir(sx,sy);\n        // Navigate + rotate\n        int gx=sx-dx[sd],gy=sy-dy[sd];\n        // Combine first move with rotation if needed\n        while(rx!=gx||ry!=gy||dir!=sd){\n            char mc='.';\n            if(rx<gx){mc='D';rx++;}else if(rx>gx){mc='U';rx--;}else if(ry<gy){mc='R';ry++;}else if(ry>gy){mc='L';ry--;}\n            char rc='.';\n            if(dir!=sd){int r=(sd-dir+4)%4;if(r<=2){rc='R';dir=(dir+1)%4;}else{rc='L';dir=(dir+3)%4;}}\n            addOp(mc,rc,false);\n        }\n        addOp('.','.', true); // pick up\n        \n        int td=bestDir(tx,ty);\n        gx=tx-dx[td];gy=ty-dy[td];\n        while(rx!=gx||ry!=gy||dir!=td){\n            char mc='.';\n            if(rx<gx){mc='D';rx++;}else if(rx>gx){mc='U';rx--;}else if(ry<gy){mc='R';ry++;}else if(ry>gy){mc='L';ry--;}\n            char rc='.';\n            if(dir!=td){int r=(td-dir+4)%4;if(r<=2){rc='R';dir=(dir+1)%4;}else{rc='L';dir=(dir+3)%4;}}\n            addOp(mc,rc,false);\n        }\n        addOp('.','.', true); // drop\n    }\n    for(auto&o:ops)printf(\"%s\\n\",o.c_str());\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N; cin>>N;\n    vector<int> x(2*N), y(2*N);\n    for(int i=0;i<2*N;i++) cin>>x[i]>>y[i];\n    \n    // mackerels: 0..N-1, sardines: N..2N-1\n    // Try grid-based Kadane's approach\n    const int G = 300; // grid size\n    const int MX = 100000;\n    double step = (double)MX / G;\n    \n    // val[gx][gy] = mackerels - sardines in cell [gx, gx+1) x [gy, gy+1)\n    vector<vector<int>> val(G+1, vector<int>(G+1, 0));\n    for(int i=0;i<2*N;i++){\n        int gx = min((int)(x[i]/step), G-1);\n        int gy = min((int)(y[i]/step), G-1);\n        val[gx][gy] += (i < N) ? 1 : -1;\n    }\n    \n    int best = INT_MIN, bx1=0,bx2=G-1,by1=0,by2=G-1;\n    for(int lx=0;lx<G;lx++){\n        vector<int> colsum(G,0);\n        for(int rx=lx;rx<G;rx++){\n            for(int gy=0;gy<G;gy++) colsum[gy]+=val[rx][gy];\n            // Kadane on colsum\n            int cur=0, start=0;\n            for(int gy=0;gy<G;gy++){\n                cur+=colsum[gy];\n                if(cur>best){best=cur;bx1=lx;bx2=rx;by1=start;by2=gy;}\n                if(cur<0){cur=0;start=gy+1;}\n            }\n        }\n    }\n    \n    int ax1=max(0,(int)(bx1*step)-1), ax2=min(MX,(int)((bx2+1)*step)+1);\n    int ay1=max(0,(int)(by1*step)-1), ay2=min(MX,(int)((by2+1)*step)+1);\n    \n    cout<<4<<\"\\n\";\n    cout<<ax1<<\" \"<<ay1<<\"\\n\";\n    cout<<ax2<<\" \"<<ay1<<\"\\n\";\n    cout<<ax2<<\" \"<<ay2<<\"\\n\";\n    cout<<ax1<<\" \"<<ay2<<\"\\n\";\n}","ahc040":"#include<bits/stdc++.h>\nusing namespace std;\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    int N,T,sigma;\n    cin>>N>>T>>sigma;\n    vector<long long>w(N),h(N);\n    for(int i=0;i<N;i++)cin>>w[i]>>h[i];\n    mt19937 rng(12345);\n    for(int t=0;t<T;t++){\n        vector<tuple<int,int,char,int>>ops;\n        for(int i=0;i<N;i++){\n            int rot=rng()%2;\n            if(i==0){ops.push_back({i,rot,'U',-1});}\n            else{\n                int ref=rng()%i;\n                char d=(rng()%2)?'U':'L';\n                ops.push_back({i,rot,d,ref});\n            }\n        }\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 W,H;cin>>W>>H;\n    }\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    \n    vector<int> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\n    \n    vector<vector<int>> adj(N);\n    for(int i=0;i<M;i++){\n        int u,v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++) cin >> x[i] >> y[i];\n    \n    // State: parent[v], depth[v]\n    vector<int> par(N, -1), dep(N, 0);\n    vector<vector<int>> children(N);\n    \n    auto calc_score = [&]() -> long long {\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    \n    // Greedy: sort vertices by beauty descending, try to place them deep\n    // BFS tree building from low-beauty roots\n    \n    // Sort vertices by A ascending (low beauty = good root candidates)\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){ return A[a] < A[b]; });\n    \n    vector<bool> used(N, false);\n    \n    for(int r : order){\n        if(used[r]) continue;\n        used[r] = true;\n        par[r] = -1; dep[r] = 0;\n        queue<int> q;\n        q.push(r);\n        while(!q.empty()){\n            int u = q.front(); q.pop();\n            if(dep[u] >= H) continue;\n            // Sort neighbors by A descending\n            vector<int> nbrs;\n            for(int v : adj[u]) if(!used[v]) nbrs.push_back(v);\n            sort(nbrs.begin(), nbrs.end(), [&](int a, int b){ return A[a] > A[b]; });\n            for(int v : nbrs){\n                if(used[v]) continue;\n                used[v] = true;\n                par[v] = u;\n                dep[v] = dep[u]+1;\n                children[u].push_back(v);\n                q.push(v);\n            }\n        }\n    }\n    \n    // Local search: try reparenting\n    auto get_subtree = [&](int v, auto& self) -> vector<int> {\n        vector<int> res = {v};\n        for(int c : children[v]){\n            auto sub = self(c, self);\n            res.insert(res.end(), sub.begin(), sub.end());\n        }\n        return res;\n    };\n    \n    auto update_depths = [&](int v, int d, auto& self) -> void {\n        dep[v] = d;\n        for(int c : children[v]) self(c, d+1, self);\n    };\n    \n    auto detach = [&](int v){\n        int p = par[v];\n        if(p == -1) return;\n        auto& ch = children[p];\n        ch.erase(find(ch.begin(), ch.end(), v));\n        par[v] = -1;\n        update_depths(v, 0, update_depths);\n    };\n    \n    auto max_depth_subtree = [&](int v, auto& self) -> int {\n        int mx = dep[v];\n        for(int c : children[v]) mx = max(mx, self(c, self));\n        return mx;\n    };\n    \n    auto subtree_score = [&](int v, auto& self) -> long long {\n        long long s = (long long)(dep[v]+1)*A[v];\n        for(int c : children[v]) s += self(c, self);\n        return s;\n    };\n    \n    // Build adjacency set for O(1) lookup\n    vector<set<int>> adjset(N);\n    for(int i=0;i<N;i++) for(int j : adj[i]) adjset[i].insert(j);\n    \n    long long best_score = calc_score();\n    vector<int> best_par = par;\n    \n    mt19937 rng(42);\n    \n    auto try_reparent = [&](int v, int new_par) -> long long {\n        // Check edge exists\n        if(!adjset[v].count(new_par)) return -1;\n        // Check new_par is not in subtree of v\n        int tmp = new_par;\n        while(tmp != -1){\n            if(tmp == v) return -1;\n            tmp = par[tmp];\n        }\n        // Check depth constraint\n        int subtree_depth = max_depth_subtree(v, max_depth_subtree) - dep[v];\n        int new_dep = dep[new_par] + 1;\n        if(new_dep + subtree_depth > H) return -1;\n        \n        long long old_sub = subtree_score(v, subtree_score);\n        // New score change\n        int depth_change = new_dep - dep[v];\n        // Calculate new subtree score\n        auto calc_delta = [&](int u, int dd, auto& self) -> long long {\n            long long d = (long long)dd * A[u];\n            for(int c : children[u]) d += self(c, dd, self);\n            return d;\n        };\n        long long delta = calc_delta(v, depth_change, calc_delta);\n        return delta;\n    };\n    \n    auto do_reparent = [&](int v, int new_par){\n        detach(v);\n        par[v] = new_par;\n        children[new_par].push_back(v);\n        int new_dep = dep[new_par] + 1;\n        int dd = new_dep - dep[v];\n        // Fix: dep[v] is already 0 after detach, recalculate\n        update_depths(v, new_dep, update_depths);\n    };\n    \n    // Simulated annealing\n    auto start_time = chrono::steady_clock::now();\n    double time_limit = 1.9;\n    long long cur_score = best_score;\n    \n    for(int iter = 0; ; iter++){\n        if(iter % 1000 == 0){\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if(elapsed > time_limit) break;\n        }\n        \n        int v = rng() % N;\n        // Try reparenting v to a random neighbor\n        if(adj[v].empty()) continue;\n        int ni = rng() % adj[v].size();\n        int new_p = adj[v][ni];\n        \n        long long delta = try_reparent(v, new_p);\n        if(delta > 0 || (delta == 0 && (int)(rng()%2)==0)){\n            int old_par = par[v];\n            do_reparent(v, new_p);\n            cur_score = calc_score();\n            if(cur_score > best_score){\n                best_score = cur_score;\n                best_par = par;\n            }\n        }\n    }\n    \n    for(int i=0;i<N;i++){\n        cout << best_par[i];\n        if(i<N-1) cout << ' ';\n    }\n    cout << '\\n';\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N;\n    cin>>N;\n    vector<string> board(N);\n    for(int i=0;i<N;i++) cin>>board[i];\n    \n    // For each oni, find valid directions and costs\n    struct Oni { int r,c; };\n    vector<Oni> onis;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(board[i][j]=='x') onis.push_back({i,j});\n    \n    // For each oni, find best direction considering grouping\n    // Group by (direction, line_index)\n    // direction: U->col, D->col, L->row, R->row\n    // cost of group = 2*(max_dist+1)\n    \n    // Use greedy: assign each oni to best group\n    // key: (dir, line), value: list of onis, max_dist\n    // Try all 4 directions, pick assignment minimizing total ops\n    \n    // Simple approach: for each oni pick cheapest valid direction\n    vector<tuple<char,int,int>> ops; // dir, index, count\n    \n    // Group approach with DP is complex; let's use the simple per-oni approach with best direction\n    vector<pair<string,int>> result;\n    \n    for(auto&o:onis){\n        int r=o.r, c=o.c;\n        // Check 4 directions\n        struct Option{ char d; int line; int dist; };\n        vector<Option> opts;\n        auto clear=[&](char d)->bool{\n            if(d=='U'){ for(int i=0;i<r;i++) if(board[i][c]=='o') return false; return true; }\n            if(d=='D'){ for(int i=r+1;i<N;i++) if(board[i][c]=='o') return false; return true; }\n            if(d=='L'){ for(int j=0;j<c;j++) if(board[r][j]=='o') return false; return true; }\n            if(d=='R'){ for(int j=c+1;j<N;j++) if(board[r][j]=='o') return false; return true; }\n            return false;\n        };\n        if(clear('U')) opts.push_back({'U',c,r+1});\n        if(clear('D')) opts.push_back({'D',c,N-r});\n        if(clear('L')) opts.push_back({'L',r,c+1});\n        if(clear('R')) opts.push_back({'R',r,N-c});\n        sort(opts.begin(),opts.end(),[](auto&a,auto&b){return a.dist<b.dist;});\n        auto&best=opts[0];\n        char fd=best.d, rd=(fd=='U'?'D':fd=='D'?'U':fd=='L'?'R':'L');\n        for(int k=0;k<best.dist;k++) result.push_back({string(1,fd),best.line});\n        for(int k=0;k<best.dist;k++) result.push_back({string(1,rd),best.line});\n    }\n    for(auto&[d,p]:result) cout<<d<<\" \"<<p<<\"\\n\";\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N, L;\n    scanf(\"%d%d\", &N, &L);\n    vector<int> T(N);\n    for(int i=0;i<N;i++) scanf(\"%d\", &T[i]);\n    \n    int a[100], b[100];\n    mt19937 rng(12345);\n    \n    // Flow-based initialization: node i sends ceil(T[i]/2) to a[i], floor(T[i]/2) to b[i]\n    // We have \"half-flows\" to assign to targets\n    // Greedily assign: maintain deficit[j] = T[j] - assigned_incoming[j]\n    vector<int> deficit(N);\n    for(int i=0;i<N;i++) deficit[i] = T[i];\n    \n    // Sort nodes by T descending for greedy assignment\n    vector<int> order(N); iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),[&](int x,int y){return T[x]>T[y];});\n    \n    for(int i : order){\n        int ha = (T[i]+1)/2, hb = T[i]/2;\n        // Assign a[i] to node with largest deficit\n        int best=-1; for(int j=0;j<N;j++) if(best<0||deficit[j]>deficit[best]) best=j;\n        a[i]=best; deficit[best]-=ha;\n        best=-1; for(int j=0;j<N;j++) if(best<0||deficit[j]>deficit[best]) best=j;\n        b[i]=best; deficit[best]-=hb;\n    }\n    \n    auto simulate = [&]() -> long long {\n        int cnt[100]={}, vis[100]={};\n        int x=0;\n        for(int w=0;w<L;w++){\n            cnt[x]++; vis[x]++;\n            x = (vis[x]%2==1) ? a[x] : b[x];\n        }\n        long long err=0;\n        for(int i=0;i<N;i++) err+=abs(cnt[i]-T[i]);\n        return err;\n    };\n    \n    long long bestErr = simulate();\n    int bestA[100], bestB[100];\n    memcpy(bestA,a,sizeof(a)); memcpy(bestB,b,sizeof(b));\n    \n    auto start = chrono::steady_clock::now();\n    \n    for(int iter=0;;iter++){\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed > 1.85) break;\n        double temp = max(0.5, 50.0*(1.0-elapsed/1.85));\n        \n        memcpy(a,bestA,sizeof(a)); memcpy(b,bestB,sizeof(b));\n        \n        int i = rng()%N;\n        int which = rng()%2;\n        int oldVal = which ? b[i] : a[i];\n        int newVal = rng()%N;\n        if(which) b[i]=newVal; else a[i]=newVal;\n        \n        long long err2 = simulate();\n        double delta = err2 - bestErr;\n        if(delta<=0 || (double)(rng()%1000000)/1000000.0 < exp(-delta/temp)){\n            bestErr=err2;\n            memcpy(bestA,a,sizeof(a)); memcpy(bestB,b,sizeof(b));\n        }\n    }\n    \n    for(int i=0;i<N;i++) printf(\"%d %d\\n\", bestA[i], bestB[i]);\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n): p(n), r(n,0) { iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a, int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a;\n        if(r[a]==r[b]) r[a]++;\n        return true;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M,Q,L,W;\n    cin>>N>>M>>Q>>L>>W;\n    vector<int> G(M);\n    for(auto &g:G) cin>>g;\n    vector<int> lx(N),rx(N),ly(N),ry(N);\n    for(int i=0;i<N;i++) cin>>lx[i]>>rx[i]>>ly[i]>>ry[i];\n    \n    vector<double> cx(N),cy(N);\n    for(int i=0;i<N;i++){\n        cx[i]=(lx[i]+rx[i])/2.0;\n        cy[i]=(ly[i]+ry[i])/2.0;\n    }\n    \n    auto edist = [&](int a, int b) -> double {\n        double dx=cx[a]-cx[b], dy=cy[a]-cy[b];\n        return sqrt(dx*dx+dy*dy);\n    };\n    \n    // Build a k-d tree or just use sorted neighbor lists\n    // For each city, find its nearest neighbors by estimated distance\n    \n    // Phase 1: Use queries to discover true short edges\n    // Strategy: find clusters of L nearby cities and query them\n    \n    // Build nearest neighbor graph\n    // For efficiency, compute all pairwise distances (800*800 = 640K, fine)\n    vector<vector<pair<double,int>>> nn(N);\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++) if(i!=j){\n            nn[i].push_back({edist(i,j),j});\n        }\n        sort(nn[i].begin(),nn[i].end());\n    }\n    \n    // Discovered edges with oracle-confirmed MST relationships\n    set<pair<int,int>> oracleEdges;\n    // Also store actual distance bounds from oracle MST edges\n    \n    int queriesUsed = 0;\n    \n    // Strategy: query groups of L nearby cities\n    // Use a greedy approach: pick the city with least oracle coverage, query its L-1 nearest neighbors\n    \n    vector<int> oracleCoverage(N, 0); // how many oracle edges touch this city\n    \n    // Phase 1: Global exploration queries\n    // We want to cover as many cities as possible with oracle queries\n    // Each query covers L cities with L-1 edges\n    \n    // Sort cities by coverage, pick least covered, query with nearest neighbors\n    // But we need to be smart about which queries to use\n    \n    // Let's reserve some queries for within-group refinement\n    int phase1Queries = Q * 2 / 3;\n    int phase2Queries = Q - phase1Queries;\n    \n    // For phase 1, use queries on clusters of nearby cities\n    vector<bool> queriedSet(N, false);\n    \n    // Greedy: repeatedly pick the city with lowest coverage and query its neighborhood\n    auto doQuery = [&](vector<int>& subset) -> vector<pair<int,int>> {\n        cout << \"? \" << subset.size();\n        for(int c : subset) cout << \" \" << c;\n        cout << \"\\n\" << flush;\n        queriesUsed++;\n        vector<pair<int,int>> res;\n        for(int e = 0; e < (int)subset.size()-1; e++){\n            int a, b; cin >> a >> b;\n            if(a > b) swap(a, b);\n            oracleEdges.insert({a, b});\n            oracleCoverage[a]++;\n            oracleCoverage[b]++;\n            res.push_back({a, b});\n        }\n        return res;\n    };\n    \n    // Phase 1: Cover cities broadly\n    // Use a set-cover like approach\n    for(int q = 0; q < phase1Queries; q++){\n        // Find least covered city\n        int best = -1;\n        for(int i = 0; i < N; i++){\n            if(best < 0 || oracleCoverage[i] < oracleCoverage[best])\n                best = i;\n        }\n        \n        // Query best + its L-1 nearest uncovered/least-covered neighbors\n        vector<int> subset;\n        subset.push_back(best);\n        \n        // Pick nearest neighbors preferring low coverage\n        vector<pair<pair<int,double>,int>> candidates;\n        for(auto [d, j] : nn[best]){\n            candidates.push_back({{oracleCoverage[j], d}, j});\n        }\n        sort(candidates.begin(), candidates.end());\n        \n        set<int> inSubset;\n        inSubset.insert(best);\n        for(auto& [key, j] : candidates){\n            if((int)subset.size() >= L) break;\n            if(!inSubset.count(j)){\n                subset.push_back(j);\n                inSubset.insert(j);\n            }\n        }\n        \n        if((int)subset.size() < 2) break;\n        doQuery(subset);\n    }\n    \n    // Now do clustering using oracle edges + estimated distances\n    // Build a weighted graph: oracle edges get weight = estimated distance (they're MST edges so they're good)\n    // Other edges get estimated distance\n    \n    // Use a modified MST-based clustering:\n    // Build global MST using oracle edges with bonus (lower weight), cut into M components\n    \n    // Build edge list: oracle edges with slight discount\n    vector<tuple<double,int,int>> allEdges;\n    for(auto [a,b] : oracleEdges){\n        allEdges.push_back({edist(a,b) * 0.8, a, b}); // trust oracle edges more\n    }\n    // Add all estimated edges\n    for(int i = 0; i < N; i++){\n        // Only add nearest ~50 neighbors to keep it manageable\n        for(int k = 0; k < min((int)nn[i].size(), 50); k++){\n            int j = nn[i][k].second;\n            if(i < j){\n                allEdges.push_back({edist(i,j), i, j});\n            }\n        }\n    }\n    sort(allEdges.begin(), allEdges.end());\n    \n    // Build MST of all N cities\n    DSU dsu(N);\n    vector<tuple<double,int,int>> mstEdges;\n    for(auto& [w, a, b] : allEdges){\n        if(dsu.unite(a, b)){\n            mstEdges.push_back({w, a, b});\n            if((int)mstEdges.size() == N-1) break;\n        }\n    }\n    \n    // If MST not complete, add remaining edges\n    if((int)mstEdges.size() < N-1){\n        for(int i = 0; i < N; i++){\n            for(auto [d, j] : nn[i]){\n                if(i < j){\n                    DSU tmp = dsu;\n                    if(tmp.unite(i, j)){\n                        dsu.unite(i, j);\n                        mstEdges.push_back({d, i, j});\n                        if((int)mstEdges.size() == N-1) break;\n                    }\n                }\n            }\n            if((int)mstEdges.size() == N-1) break;\n        }\n    }\n    \n    // Now partition into M groups by cutting M-1 heaviest edges\n    // But we need specific group sizes G[0..M-1]\n    \n    // Sort group sizes\n    vector<int> gsorted(M);\n    iota(gsorted.begin(), gsorted.end(), 0);\n    \n    // Build adjacency from MST\n    vector<vector<pair<int,double>>> adj(N);\n    // Sort MST edges by weight descending, try removing edges and check if resulting component sizes match G\n    \n    // This is tricky with arbitrary group sizes. Let's use a different approach:\n    // Hierarchical clustering with MST, then assign group sizes optimally\n    \n    // Simple approach: sort MST edges by weight desc, remove top M-1 to get M components\n    // Then match components to group sizes\n    \n    sort(mstEdges.begin(), mstEdges.end(), [](auto& a, auto& b){ return get<0>(a) > get<0>(b); });\n    \n    DSU dsu2(N);\n    // Add all but top M-1 edges (i.e., add edges from index M-1 onwards)\n    for(int i = M-1; i < (int)mstEdges.size(); i++){\n        auto [w, a, b] = mstEdges[i];\n        dsu2.unite(a, b);\n    }\n    \n    // Find components\n    map<int, vector<int>> components;\n    for(int i = 0; i < N; i++){\n        components[dsu2.find(i)].push_back(i);\n    }\n    \n    // We have some components, but their sizes may not match G exactly\n    // Need to split large components or merge small ones\n    \n    // Collect component sizes\n    vector<vector<int>> comps;\n    for(auto& [root, cities] : components){\n        comps.push_back(cities);\n    }\n    \n    // Sort components by size descending\n    sort(comps.begin(), comps.end(), [](auto& a, auto& b){ return a.size() > b.size(); });\n    \n    // Sort G descending for matching\n    vector<int> Gsorted(G);\n    sort(Gsorted.rbegin(), Gsorted.rend());\n    \n    // This matching is complex. Let me use a simpler but effective approach:\n    // Just do balanced clustering from scratch using assignment\n    \n    // Alternative: Use a proper balanced k-means / assignment approach\n    // Let me try a different strategy entirely:\n    \n    // 1. Compute estimated all-pairs distances\n    // 2. Sort all edges by estimated distance\n    // 3. Use a constrained clustering: greedily merge nearest cities/clusters\n    //    but don't let any cluster exceed the largest remaining group size needed\n    \n    // Actually, let's use a cleaner approach:\n    // Assign cities to groups using a greedy nearest-center approach with balanced sizes\n    \n    // Pick initial centers using k-means++ on estimated positions\n    vector<int> centers(M);\n    vector<double> minDist(N, 1e18);\n    \n    // First center: random (pick city 0 or centroid-closest)\n    {\n        double avgx=0, avgy=0;\n        for(int i=0;i<N;i++){ avgx+=cx[i]; avgy+=cy[i]; }\n        avgx/=N; avgy/=N;\n        int best=0;\n        for(int i=1;i<N;i++){\n            double d1=(cx[i]-avgx)*(cx[i]-avgx)+(cy[i]-avgy)*(cy[i]-avgy);\n            double d0=(cx[best]-avgx)*(cx[best]-avgx)+(cy[best]-avgy)*(cy[best]-avgy);\n            if(d1<d0) best=i;\n        }\n        centers[0]=best;\n    }\n    \n    vector<bool> isCenter(N, false);\n    isCenter[centers[0]] = true;\n    for(int i=0;i<N;i++) minDist[i]=edist(i,centers[0]);\n    \n    for(int c=1;c<M;c++){\n        int best=-1;\n        for(int i=0;i<N;i++) if(!isCenter[i]){\n            if(best<0 || minDist[i]>minDist[best]) best=i;\n        }\n        centers[c]=best;\n        isCenter[best]=true;\n        for(int i=0;i<N;i++){\n            minDist[i]=min(minDist[i], edist(i,best));\n        }\n    }\n    \n    // Now assign cities to nearest center, respecting group sizes\n    // Use min-cost bipartite matching approximation\n    // Priority queue approach: for each city-group pair, compute distance to center\n    \n    // Sort G indices so we assign largest groups first? Or use auction/Hungarian?\n    // Simple approach: iterative assignment\n    \n    // For each group, compute center position as the seed\n    vector<double> gcx(M), gcy(M);\n    for(int i=0;i<M;i++){\n        gcx[i]=cx[centers[i]];\n        gcy[i]=cy[centers[i]];\n    }\n    \n    // K-means iterations\n    vector<int> assignment(N, -1);\n    \n    for(int iter = 0; iter < 10; iter++){\n        // Assign each city to nearest center, respecting capacities\n        // Use a priority queue\n        using T = tuple<double, int, int>; // dist, city, group\n        priority_queue<T, vector<T>, greater<T>> pq;\n        \n        for(int i = 0; i < N; i++){\n            for(int g = 0; g < M; g++){\n                double dx = cx[i]-gcx[g], dy = cy[i]-gcy[g];\n                pq.push({sqrt(dx*dx+dy*dy), i, g});\n            }\n        }\n        \n        fill(assignment.begin(), assignment.end(), -1);\n        vector<int> cap(G.begin(), G.end());\n        vector<vector<int>> grps(M);\n        int assigned = 0;\n        \n        while(!pq.empty() && assigned < N){\n            auto [d, c, g] = pq.top(); pq.pop();\n            if(assignment[c] != -1 || cap[g] <= 0) continue;\n            assignment[c] = g;\n            grps[g].push_back(c);\n            cap[g]--;\n            assigned++;\n        }\n        \n        // Update centers\n        bool changed = false;\n        for(int g = 0; g < M; g++){\n            if(grps[g].empty()) continue;\n            double nx=0, ny=0;\n            for(int c : grps[g]){ nx+=cx[c]; ny+=cy[c]; }\n            nx/=grps[g].size(); ny/=grps[g].size();\n            if(abs(gcx[g]-nx)>0.1 || abs(gcy[g]-ny)>0.1) changed=true;\n            gcx[g]=nx; gcy[g]=ny;\n        }\n        if(!changed) break;\n    }\n    \n    // Build final groups\n    vector<vector<int>> groups(M);\n    for(int i = 0; i < N; i++){\n        groups[assignment[i]].push_back(i);\n    }\n    \n    // Phase 2: Use remaining queries within groups\n    for(int g = 0; g < M && queriesUsed < Q; g++){\n        auto& grp = groups[g];\n        int sz = grp.size();\n        if(sz <= 1) continue;\n        \n        // Sort by estimated position within group\n        sort(grp.begin(), grp.end(), [&](int a, int b){\n            double da = (cx[a]-gcx[g])*(cx[a]-gcx[g])+(cy[a]-gcy[g])*(cy[a]-gcy[g]);\n            double db = (cx[b]-gcx[g])*(cx[b]-gcx[g])+(cy[b]-gcy[g])*(cy[b]-gcy[g]);\n            return atan2(cy[a]-gcy[g],cx[a]-gcx[g]) < atan2(cy[b]-gcy[g],cx[b]-gcx[g]);\n        });\n        \n        // Query sliding windows\n        int stride = max(1, L-1);\n        for(int i = 0; i + 1 < sz && queriesUsed < Q; i += stride){\n            int end = min(i+L, sz);\n            if(end - i < 2) break;\n            vector<int> subset(grp.begin()+i, grp.begin()+end);\n            doQuery(subset);\n        }\n    }\n    \n    // Build spanning trees for each group\n    // Use Kruskal with oracle edges prioritized\n    cout << \"!\" << endl;\n    \n    for(int g = 0; g < M; g++){\n        auto& grp = groups[g];\n        int sz = grp.size();\n        \n        for(int i = 0; i < sz; i++){\n            if(i) cout << \" \";\n            cout << grp[i];\n        }\n        cout << \"\\n\";\n        \n        if(sz <= 1) continue;\n        \n        set<int> inGrp(grp.begin(), grp.end());\n        map<int,int> id;\n        for(int i = 0; i < sz; i++) id[grp[i]] = i;\n        \n        // Collect edges: oracle edges within this group get priority\n        vector<tuple<double,int,int>> edges;\n        for(auto [a, b] : oracleEdges){\n            if(inGrp.count(a) && inGrp.count(b)){\n                edges.push_back({edist(a,b) * 0.5, a, b}); // strong priority\n            }\n        }\n        // All pairs within group\n        for(int i = 0; i < sz; i++){\n            for(int j = i+1; j < sz; j++){\n                edges.push_back({edist(grp[i], grp[j]), grp[i], grp[j]});\n            }\n        }\n        \n        sort(edges.begin(), edges.end());\n        \n        DSU gdsu(N);\n        vector<pair<int,int>> tree;\n        for(auto& [w, a, b] : edges){\n            if(gdsu.unite(a, b)){\n                tree.push_back({a, b});\n                if((int)tree.size() == sz-1) break;\n            }\n        }\n        \n        for(auto [a, b] : tree){\n            cout << a << \" \" << b << \"\\n\";\n        }\n    }\n    \n    cout << flush;\n    return 0;\n}","ahc046":"#include<bits/stdc++.h>\nusing namespace std;\nint main(){\n    int N,M;\n    scanf(\"%d%d\",&N,&M);\n    vector<int>ti(M),tj(M);\n    for(int k=0;k<M;k++)scanf(\"%d%d\",&ti[k],&tj[k]);\n    int ci=ti[0],cj=tj[0];\n    vector<vector<bool>>block(N,vector<bool>(N,false));\n    vector<string>actions;\n    int dx[]={-1,1,0,0},dy[]={0,0,-1,1};\n    char dc[]={'U','D','L','R'};\n    for(int k=1;k<M;k++){\n        int gi=ti[k],gj=tj[k];\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        vector<vector<int>>pdir(N,vector<int>(N,-1));\n        queue<pair<int,int>>q;\n        dist[ci][cj]=0;q.push({ci,cj});\n        while(!q.empty()){\n            auto[x,y]=q.front();q.pop();\n            if(x==gi&&y==gj)break;\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&&!block[nx][ny]&&dist[nx][ny]<0){\n                    dist[nx][ny]=dist[x][y]+1;par[nx][ny]={x,y};pdir[nx][ny]=d;q.push({nx,ny});\n                }\n            }\n        }\n        vector<int>path;\n        int x=gi,y=gj;\n        while(x!=ci||y!=cj){int d=pdir[x][y];path.push_back(d);auto[px,py]=par[x][y];x=px;y=py;}\n        reverse(path.begin(),path.end());\n        for(int d:path){string s=\"M \";s+=dc[d];actions.push_back(s);}\n        ci=gi;cj=gj;\n    }\n    for(auto&s:actions)printf(\"%s\\n\",s.c_str());\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    vector<int> x(n), y(n);\n    vector<long long> r(n);\n    for(int i=0;i<n;i++) cin >> x[i] >> y[i] >> r[i];\n    \n    // Rectangle: a,b,c,d where a<c, b<d\n    vector<int> a(n),b(n),c(n),d(n);\n    for(int i=0;i<n;i++){\n        a[i]=x[i]; b[i]=y[i]; c[i]=x[i]+1; d[i]=y[i]+1;\n    }\n    \n    auto intersects = [&](int i, int j) -> bool {\n        return a[i]<c[j] && a[j]<c[i] && b[i]<d[j] && b[j]<d[i];\n    };\n    \n    auto canExpand = [&](int i, int na, int nb, int nc, int nd) -> bool {\n        if(na<0||nb<0||nc>10000||nd>10000||na>=nc||nb>=nd) return false;\n        for(int j=0;j<n;j++){\n            if(j==i) continue;\n            if(na<c[j] && a[j]<nc && nb<d[j] && b[j]<nd) return false;\n        }\n        return true;\n    };\n    \n    auto area = [&](int i) -> long long {\n        return (long long)(c[i]-a[i])*(d[i]-b[i]);\n    };\n    \n    auto score = [&](int i) -> double {\n        long long s = area(i);\n        double ratio = min(r[i],s)*1.0/max(r[i],s);\n        return 1.0 - (1.0-ratio)*(1.0-ratio);\n    };\n    \n    // Greedy expansion with random direction attempts\n    mt19937 rng(42);\n    auto start = chrono::steady_clock::now();\n    \n    while(true){\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now-start).count();\n        if(elapsed > 4.5) break;\n        \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 i : order){\n            long long s = area(i);\n            if(s >= r[i]) continue;\n            double curScore = score(i);\n            \n            // Try 4 directions: expand left, right, up, down\n            int dirs[4][4];\n            // left: a-step\n            int step = max(1, (int)min((long long)100, (r[i]-s)/max(1LL,(long long)(d[i]-b[i]))));\n            dirs[0][0]=a[i]-step; dirs[0][1]=b[i]; dirs[0][2]=c[i]; dirs[0][3]=d[i];\n            dirs[1][0]=a[i]; dirs[1][1]=b[i]; dirs[1][2]=c[i]+step; dirs[1][3]=d[i];\n            dirs[2][0]=a[i]; dirs[2][1]=b[i]-step; dirs[2][2]=c[i]; dirs[2][3]=d[i];\n            dirs[3][0]=a[i]; dirs[3][1]=b[i]; dirs[3][2]=c[i]; dirs[3][3]=d[i]+step;\n            \n            int bestDir = -1; double bestScore = curScore;\n            for(int dd=0;dd<4;dd++){\n                if(canExpand(i, dirs[dd][0], dirs[dd][1], dirs[dd][2], dirs[dd][3])){\n                    long long ns = (long long)(dirs[dd][2]-dirs[dd][0])*(dirs[dd][3]-dirs[dd][1]);\n                    double rat = min(r[i],ns)*1.0/max(r[i],ns);\n                    double sc = 1.0-(1.0-rat)*(1.0-rat);\n                    if(sc > bestScore){ bestScore=sc; bestDir=dd; }\n                }\n            }\n            if(bestDir>=0){\n                a[i]=dirs[bestDir][0]; b[i]=dirs[bestDir][1];\n                c[i]=dirs[bestDir][2]; d[i]=dirs[bestDir][3];\n                improved=true;\n            }\n        }\n        if(!improved) break;\n    }\n    \n    for(int i=0;i<n;i++) cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint t[50][50], p[50][50];\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\nchar dc[]={'U','D','L','R'};\n\nint main(){\n    int si,sj;\n    scanf(\"%d%d\",&si,&sj);\n    for(int i=0;i<50;i++) for(int j=0;j<50;j++) scanf(\"%d\",&t[i][j]);\n    for(int i=0;i<50;i++) for(int j=0;j<50;j++) scanf(\"%d\",&p[i][j]);\n    \n    int M=0;\n    for(int i=0;i<50;i++) for(int j=0;j<50;j++) M=max(M,t[i][j]+1);\n    \n    // Tree for path reconstruction\n    struct Node { int parent; char dir; };\n    vector<Node> tree;\n    tree.reserve(8000000);\n    tree.push_back({-1,' '});\n    \n    auto getPath = [&](int idx) -> string {\n        string s;\n        while(idx > 0) { s += tree[idx].dir; idx = tree[idx].parent; }\n        reverse(s.begin(), s.end());\n        return s;\n    };\n    \n    // Use short arrays for used tiles (M <= ~1700)\n    // Store used sets in a pool\n    int usedSize = (M+63)/64;\n    vector<vector<uint64_t>> pool;\n    pool.reserve(2000000);\n    \n    auto allocUsed = [&]() -> int {\n        int id = pool.size();\n        pool.emplace_back(usedSize, 0ULL);\n        return id;\n    };\n    auto copyUsed = [&](int src) -> int {\n        int id = pool.size();\n        pool.push_back(pool[src]);\n        return id;\n    };\n    auto setBit = [&](int id, int bit) { pool[id][bit/64] |= 1ULL<<(bit%64); };\n    auto testBit = [&](int id, int bit) -> bool { return (pool[id][bit/64]>>(bit%64))&1; };\n    \n    struct State {\n        int x, y, score, usedId, nodeIdx;\n    };\n    \n    int bestScore = p[si][sj];\n    int bestNode = 0;\n    \n    int initUsed = allocUsed();\n    setBit(initUsed, t[si][sj]);\n    \n    // Beam with position diversity: keep top-K per position\n    int perPos = 3;\n    int totalBeam = 400;\n    \n    vector<State> beam;\n    beam.push_back({si, sj, p[si][sj], initUsed, 0});\n    \n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(1880);\n    \n    for(int step=0; step<2500 && !beam.empty(); step++){\n        if(step%20==0 && chrono::steady_clock::now()>deadline) break;\n        \n        // Clear pool except what beam uses (can't easily, skip)\n        vector<State> next;\n        next.reserve(beam.size()*4);\n        \n        for(auto &s: beam){\n            for(int d=0;d<4;d++){\n                int nx=s.x+dx[d], ny=s.y+dy[d];\n                if(nx<0||nx>=50||ny<0||ny>=50) continue;\n                int tid=t[nx][ny];\n                if(testBit(s.usedId, tid)) continue;\n                int ni=tree.size();\n                tree.push_back({s.nodeIdx, dc[d]});\n                int nu=copyUsed(s.usedId);\n                setBit(nu, tid);\n                next.push_back({nx,ny,s.score+p[nx][ny],nu,ni});\n            }\n        }\n        if(next.empty()) break;\n        \n        // Position-based diversity selection\n        sort(next.begin(), next.end(), [](const State&a,const State&b){return a.score>b.score;});\n        int cnt[50][50]={};\n        vector<State> selected;\n        for(auto &s: next){\n            if(cnt[s.x][s.y]<perPos && (int)selected.size()<totalBeam){\n                cnt[s.x][s.y]++;\n                selected.push_back(s);\n            }\n        }\n        \n        for(auto &s: selected)\n            if(s.score>bestScore){bestScore=s.score; bestNode=s.nodeIdx;}\n        \n        beam=move(selected);\n    }\n    \n    printf(\"%s\\n\", getPath(bestNode).c_str());\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\nconst int N=30;\ndouble h[N][N-1],v[N-1][N];\nint cnt_h[N][N-1],cnt_v[N-1][N];\n\nstruct Obs{vector<pair<int,int>> he,ve; double cost;};\nvector<Obs> observations;\n\nint di[]={-1,1,0,0},dj[]={0,0,-1,1};\nchar dirs[]=\"UDLR\";\n\nstruct Edge{int type,ei,ej;};\n\nvoid updateRowColAverages(){\n    // Update unvisited h edges with row average\n    for(int i=0;i<N;i++){\n        double sum=0;int cnt=0;\n        for(int j=0;j<N-1;j++)if(cnt_h[i][j]>0){sum+=h[i][j];cnt++;}\n        if(cnt>0){\n            double avg=sum/cnt;\n            for(int j=0;j<N-1;j++)if(cnt_h[i][j]==0)h[i][j]=avg;\n        }\n    }\n    // Update unvisited v edges with column average\n    for(int j=0;j<N;j++){\n        double sum=0;int cnt=0;\n        for(int i=0;i<N-1;i++)if(cnt_v[i][j]>0){sum+=v[i][j];cnt++;}\n        if(cnt>0){\n            double avg=sum/cnt;\n            for(int i=0;i<N-1;i++)if(cnt_v[i][j]==0)v[i][j]=avg;\n        }\n    }\n}\n\npair<string,vector<Edge>> dijkstra(int si,int sj,int ti,int tj){\n    vector<double> dist(N*N,1e18);\n    vector<int> pn(N*N,-1),pd(N*N,-1);\n    priority_queue<pair<double,int>,vector<pair<double,int>>,greater<>> pq;\n    int s=si*N+sj,t=ti*N+tj;\n    dist[s]=0;pq.push({0,s});\n    while(!pq.empty()){\n        auto[d,u]=pq.top();pq.pop();\n        if(d>dist[u])continue;\n        int ci=u/N,cj=u%N;\n        for(int dir=0;dir<4;dir++){\n            int ni=ci+di[dir],nj=cj+dj[dir];\n            if(ni<0||ni>=N||nj<0||nj>=N)continue;\n            double w;\n            if(dir==0)w=v[ni][cj];else if(dir==1)w=v[ci][cj];\n            else if(dir==2)w=h[ci][nj];else w=h[ci][cj];\n            int nv=ni*N+nj;\n            if(dist[u]+w<dist[nv]){dist[nv]=dist[u]+w;pn[nv]=u;pd[nv]=dir;pq.push({dist[nv],nv});}\n        }\n    }\n    string ans;vector<Edge> edges;\n    int cur=t;\n    vector<pair<int,int>> path;\n    while(cur!=s){path.push_back({pn[cur],pd[cur]});cur=pn[cur];}\n    reverse(path.begin(),path.end());\n    for(auto[node,dir]:path){\n        ans+=dirs[dir];\n        int ci=node/N,cj=node%N;\n        Edge e;e.type=dir;\n        if(dir==0){e.ei=ci-1;e.ej=cj;}\n        else if(dir==1){e.ei=ci;e.ej=cj;}\n        else if(dir==2){e.ei=ci;e.ej=cj-1;}\n        else{e.ei=ci;e.ej=cj;}\n        edges.push_back(e);\n    }\n    return{ans,edges};\n}\n\nvoid refine(int iters){\n    for(int it=0;it<iters;it++){\n        for(auto&obs:observations){\n            double est=0;\n            for(auto[i,j]:obs.he)est+=h[i][j];\n            for(auto[i,j]:obs.ve)est+=v[i][j];\n            if(est<1)continue;\n            double ratio=obs.cost/est;\n            double lr=0.05;\n            for(auto[i,j]:obs.he)h[i][j]*=(1.0+lr*(ratio-1.0));\n            for(auto[i,j]:obs.ve)v[i][j]*=(1.0+lr*(ratio-1.0));\n        }\n    }\n}\n\nint main(){\n    for(int i=0;i<N;i++)for(int j=0;j<N-1;j++){h[i][j]=5000;cnt_h[i][j]=0;}\n    for(int i=0;i<N-1;i++)for(int j=0;j<N;j++){v[i][j]=5000;cnt_v[i][j]=0;}\n    \n    for(int q=0;q<1000;q++){\n        int si,sj,ti,tj;scanf(\"%d%d%d%d\",&si,&sj,&ti,&tj);\n        auto[ans,edges]=dijkstra(si,sj,ti,tj);\n        printf(\"%s\\n\",ans.c_str());fflush(stdout);\n        int obs;scanf(\"%d\",&obs);\n        \n        double est=0;\n        Obs ob;\n        for(auto&e:edges){\n            if(e.type<=1){est+=v[e.ei][e.ej];ob.ve.push_back({e.ei,e.ej});}\n            else{est+=h[e.ei][e.ej];ob.he.push_back({e.ei,e.ej});}\n        }\n        ob.cost=(double)obs;\n        observations.push_back(ob);\n        \n        // Online update with adaptive lr\n        double ratio=(double)obs/est;\n        for(auto&e:edges){\n            if(e.type<=1){\n                int c=++cnt_v[e.ei][e.ej];\n                double lr=1.5/(c+2);\n                v[e.ei][e.ej]*=(1.0-lr)+lr*ratio;\n                v[e.ei][e.ej]=max(1000.0,min(9000.0,v[e.ei][e.ej]));\n            }else{\n                int c=++cnt_h[e.ei][e.ej];\n                double lr=1.5/(c+2);\n                h[e.ei][e.ej]*=(1.0-lr)+lr*ratio;\n                h[e.ei][e.ej]=max(1000.0,min(9000.0,h[e.ei][e.ej]));\n            }\n        }\n        \n        // Update unvisited edges with row/col averages\n        if(q%20==19) updateRowColAverages();\n        \n        // Batch refinement periodically\n        if(q==99||q==299||q==499||q==749||q==999){\n            refine(3);\n            updateRowColAverages();\n        }\n    }\n}","ahc004":"#include<bits/stdc++.h>\nusing namespace std;\n\nint N,M;\nchar G[20][20];\n\nint main(){\n    ios::sync_with_stdio(0);cin.tie(0);\n    cin>>N>>M;\n    vector<string> S(M);\n    for(int i=0;i<M;i++) cin>>S[i];\n    mt19937 rng(12345);\n    \n    // Initialize with '?' meaning unset\n    memset(G,0,sizeof(G));\n    \n    // Greedy placement: try to place strings one by one\n    // Sort strings by length descending for better constraints\n    vector<int> order(M);\n    iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),[&](int a,int b){return S[a].size()>S[b].size();});\n    \n    // Try to place each string greedily\n    for(int si:order){\n        int k=S[si].size();\n        int bestScore=-1, bestD=-1, bestI=-1, bestJ=-1;\n        for(int d=0;d<2;d++) for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            int score=0; bool ok=true;\n            for(int p=0;p<k;p++){\n                int ci,cj;\n                if(d==0){ci=i;cj=(j+p)%N;}\n                else{ci=(i+p)%N;cj=j;}\n                if(G[ci][cj]==S[si][p]) score+=2;\n                else if(G[ci][cj]==0) score+=0;\n                else {ok=false;break;}\n            }\n            if(ok && score>bestScore){\n                bestScore=score; bestD=d; bestI=i; bestJ=j;\n            }\n        }\n        if(bestD>=0){\n            for(int p=0;p<k;p++){\n                int ci,cj;\n                if(bestD==0){ci=bestI;cj=(bestJ+p)%N;}\n                else{ci=(bestI+p)%N;cj=bestJ;}\n                G[ci][cj]=S[si][p];\n            }\n        }\n    }\n    // Fill remaining with random\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++)\n        if(G[i][j]==0) G[i][j]='A'+rng()%8;\n    \n    // Build placement structures\n    struct Placement { int s; uint8_t d,i,j; };\n    vector<Placement> placements;\n    vector<vector<int>> cell2pl(400);\n    \n    for(int s=0;s<M;s++){\n        int k=S[s].size();\n        for(int d=0;d<2;d++) for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            int pidx=placements.size();\n            placements.push_back({s,(uint8_t)d,(uint8_t)i,(uint8_t)j});\n            for(int p=0;p<k;p++){\n                int ci,cj;\n                if(d==0){ci=i;cj=(j+p)%N;}\n                else{ci=(i+p)%N;cj=j;}\n                cell2pl[ci*N+cj].push_back(pidx);\n            }\n        }\n    }\n    \n    int P=placements.size();\n    vector<int8_t> pl_ok(P);\n    vector<int> str_cnt(M,0);\n    \n    auto checkPl=[&](int pidx)->int{\n        auto&pl=placements[pidx];\n        int k=S[pl.s].size();\n        if(pl.d==0){\n            for(int p=0;p<k;p++)\n                if(G[pl.i][(pl.j+p)%N]!=S[pl.s][p]) return 0;\n        } else {\n            for(int p=0;p<k;p++)\n                if(G[(pl.i+p)%N][pl.j]!=S[pl.s][p]) return 0;\n        }\n        return 1;\n    };\n    \n    for(int p=0;p<P;p++){\n        pl_ok[p]=checkPl(p);\n        if(pl_ok[p]) str_cnt[placements[p].s]++;\n    }\n    int tot=0;\n    for(int s=0;s<M;s++) if(str_cnt[s]>0) tot++;\n    \n    int best_tot=tot;\n    char bestG[20][20];\n    memcpy(bestG,G,sizeof(G));\n    \n    // Collect unmatched strings for targeting\n    vector<int> unmatched;\n    for(int s=0;s<M;s++) if(str_cnt[s]==0) unmatched.push_back(s);\n    \n    auto t0=chrono::steady_clock::now();\n    \n    static vector<pair<int,int8_t>> changes;\n    \n    while(true){\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-t0).count();\n        if(elapsed>2.7) break;\n        \n        for(int rep=0;rep<300;rep++){\n            int ci=rng()%N, cj=rng()%N;\n            char oc=G[ci][cj], nc='A'+rng()%8;\n            if(nc==oc) continue;\n            \n            auto&aff=cell2pl[ci*N+cj];\n            int delta=0;\n            G[ci][cj]=nc;\n            changes.clear();\n            \n            for(int pidx:aff){\n                int nv=checkPl(pidx);\n                if(nv!=pl_ok[pidx]){\n                    int s=placements[pidx].s;\n                    int om=(str_cnt[s]>0);\n                    str_cnt[s]+=nv-pl_ok[pidx];\n                    int nm=(str_cnt[s]>0);\n                    delta+=nm-om;\n                    changes.push_back({pidx,pl_ok[pidx]});\n                    pl_ok[pidx]=nv;\n                }\n            }\n            \n            if(delta>=0){\n                tot+=delta;\n                if(tot>best_tot){best_tot=tot;memcpy(bestG,G,sizeof(G));}\n            } else {\n                G[ci][cj]=oc;\n                for(auto&[pidx,ov]:changes){\n                    str_cnt[placements[pidx].s]+=ov-pl_ok[pidx];\n                    pl_ok[pidx]=ov;\n                }\n            }\n        }\n    }\n    \n    memcpy(G,bestG,sizeof(G));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++) cout<<G[i][j];\n        cout<<'\\n';\n    }\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nchar grid[70][70];\nint costg[70][70];\nvector<pair<int,int>> vis_from[70][70];\nbool seen[70][70];\nint dx[]={-1,1,0,0}, dy[]={0,0,-1,1};\n\nvoid dijkstra_from(int s, int t, vector<vector<int>>& d, vector<vector<pair<int,int>>>& par) {\n    d.assign(N, vector<int>(N, INT_MAX));\n    par.assign(N, vector<pair<int,int>>(N, {-1,-1}));\n    priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n    d[s][t] = 0;\n    pq.push({0, s, t});\n    while (!pq.empty()) {\n        auto [dd, ci, cj] = pq.top(); pq.pop();\n        if (dd > d[ci][cj]) continue;\n        for (int k = 0; k < 4; k++) {\n            int ni = ci+dx[k], nj = cj+dy[k];\n            if (ni<0||ni>=N||nj<0||nj>=N||grid[ni][nj]=='#') continue;\n            int nd = dd + costg[ni][nj];\n            if (nd < d[ni][nj]) {\n                d[ni][nj] = nd;\n                par[ni][nj] = {ci, cj};\n                pq.push({nd, ni, nj});\n            }\n        }\n    }\n}\n\nvector<pair<int,int>> trace_path(const vector<vector<int>>& d, const vector<vector<pair<int,int>>>& par, int s, int t, int ti, int tj) {\n    vector<pair<int,int>> pts;\n    if (d[ti][tj] == INT_MAX) return pts;\n    int ci = ti, cj = tj;\n    while (!(ci==s && cj==t)) {\n        pts.push_back({ci, cj});\n        auto [pi, pj] = par[ci][cj];\n        ci = pi; cj = pj;\n    }\n    reverse(pts.begin(), pts.end());\n    return pts;\n}\n\nstring path_to_string(const vector<pair<int,int>>& route) {\n    string result;\n    for (int i = 1; i < (int)route.size(); i++) {\n        int di = route[i].first - route[i-1].first;\n        int dj = route[i].second - route[i-1].second;\n        if (di==-1) result+='U';\n        else if (di==1) result+='D';\n        else if (dj==-1) result+='L';\n        else result+='R';\n    }\n    return result;\n}\n\nint route_cost(const vector<pair<int,int>>& route) {\n    int t = 0;\n    for (int i = 1; i < (int)route.size(); i++) t += costg[route[i].first][route[i].second];\n    return t;\n}\n\nbool check_full_coverage(const vector<pair<int,int>>& route) {\n    static int mark[70][70];\n    static int mid = 0; mid++;\n    for (auto& [pi,pj] : route)\n        for (auto& [vi,vj] : vis_from[pi][pj]) mark[vi][vj] = mid;\n    for (int r=0;r<N;r++) for (int c=0;c<N;c++)\n        if (grid[r][c]!='#' && mark[r][c]!=mid) return false;\n    return true;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto start_time = chrono::steady_clock::now();\n    auto elapsed = [&]() {\n        return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n    };\n    \n    cin >> N >> si >> sj;\n    for (int i=0;i<N;i++){\n        string s; cin >> s;\n        for (int j=0;j<N;j++){\n            grid[i][j]=s[j];\n            if (s[j]!='#') costg[i][j]=s[j]-'0';\n        }\n    }\n    \n    for (int i=0;i<N;i++) for (int j=0;j<N;j++) {\n        if (grid[i][j]=='#') continue;\n        vis_from[i][j].push_back({i,j});\n        for (int dj=j-1;dj>=0;dj--){ if(grid[i][dj]=='#') break; vis_from[i][j].push_back({i,dj}); }\n        for (int dj=j+1;dj<N;dj++){ if(grid[i][dj]=='#') break; vis_from[i][j].push_back({i,dj}); }\n        for (int di=i-1;di>=0;di--){ if(grid[di][j]=='#') break; vis_from[i][j].push_back({di,j}); }\n        for (int di=i+1;di<N;di++){ if(grid[di][j]=='#') break; vis_from[i][j].push_back({di,j}); }\n    }\n    \n    memset(seen, false, sizeof(seen));\n    int ci=si, cj=sj;\n    for (auto& [vi,vj]: vis_from[ci][cj]) seen[vi][vj]=true;\n    \n    // Store waypoints (greedy targets)\n    vector<pair<int,int>> waypoints;\n    waypoints.push_back({si, sj});\n    \n    auto count_unseen = [&]() {\n        int c=0;\n        for (int i=0;i<N;i++) for (int j=0;j<N;j++) if(grid[i][j]!='#' && !seen[i][j]) c++;\n        return c;\n    };\n    \n    while (count_unseen() > 0) {\n        vector<vector<int>> d;\n        vector<vector<pair<int,int>>> par;\n        dijkstra_from(ci, cj, d, par);\n        \n        int bestI=-1, bestJ=-1;\n        double bestScore = -1;\n        \n        for (int i=0;i<N;i++) for (int j=0;j<N;j++) {\n            if (grid[i][j]=='#' || d[i][j]==INT_MAX) continue;\n            int unseen_cnt=0;\n            for (auto& [vi,vj]: vis_from[i][j]) if(!seen[vi][vj]) unseen_cnt++;\n            if (unseen_cnt==0) continue;\n            double score = (double)unseen_cnt / max(1, d[i][j]);\n            if (score > bestScore){ bestScore=score; bestI=i; bestJ=j; }\n        }\n        \n        if (bestI==-1) break;\n        \n        auto path = trace_path(d, par, ci, cj, bestI, bestJ);\n        for (auto& [pi,pj] : path) {\n            for (auto& [vi,vj]: vis_from[pi][pj]) seen[vi][vj]=true;\n        }\n        ci = bestI; cj = bestJ;\n        waypoints.push_back({ci, cj});\n    }\n    \n    waypoints.push_back({si, sj}); // return to start\n    \n    // Build full route from waypoints\n    auto build_route = [&](const vector<pair<int,int>>& wps) -> vector<pair<int,int>> {\n        vector<pair<int,int>> full_route;\n        full_route.push_back(wps[0]);\n        for (int w = 1; w < (int)wps.size(); w++) {\n            vector<vector<int>> d;\n            vector<vector<pair<int,int>>> par;\n            dijkstra_from(full_route.back().first, full_route.back().second, d, par);\n            auto path = trace_path(d, par, full_route.back().first, full_route.back().second, wps[w].first, wps[w].second);\n            for (auto& p : path) full_route.push_back(p);\n        }\n        return full_route;\n    };\n    \n    vector<pair<int,int>> full_route = build_route(waypoints);\n    int best_cost = route_cost(full_route);\n    \n    // Optimization 1: Try removing each waypoint (except first and last)\n    for (int iter = 0; iter < 5 && elapsed() < 2200; iter++) {\n        bool improved = false;\n        for (int w = (int)waypoints.size()-2; w >= 1 && elapsed() < 2200; w--) {\n            vector<pair<int,int>> new_wps;\n            for (int i = 0; i < (int)waypoints.size(); i++) {\n                if (i != w) new_wps.push_back(waypoints[i]);\n            }\n            auto new_route = build_route(new_wps);\n            if (check_full_coverage(new_route)) {\n                int new_cost = route_cost(new_route);\n                if (new_cost < best_cost) {\n                    waypoints = new_wps;\n                    full_route = new_route;\n                    best_cost = new_cost;\n                    improved = true;\n                    break; // restart\n                }\n            }\n        }\n        if (!improved) break;\n    }\n    \n    // Optimization 2: Try swapping adjacent waypoints (2-opt style)\n    for (int iter = 0; iter < 3 && elapsed() < 2600; iter++) {\n        bool improved = false;\n        for (int w = 1; w+1 < (int)waypoints.size()-1 && elapsed() < 2600; w++) {\n            vector<pair<int,int>> new_wps = waypoints;\n            swap(new_wps[w], new_wps[w+1]);\n            auto new_route = build_route(new_wps);\n            if (check_full_coverage(new_route)) {\n                int new_cost = route_cost(new_route);\n                if (new_cost < best_cost) {\n                    waypoints = new_wps;\n                    full_route = new_route;\n                    best_cost = new_cost;\n                    improved = true;\n                    break;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n    \n    // Optimization 3: For each segment, try shortcutting through intermediate positions\n    // Try pairwise shortcutting on the full route\n    while (elapsed() < 2800) {\n        bool improved = false;\n        int rs = (int)full_route.size();\n        // Try larger jumps\n        for (int step = rs/4; step >= 2 && elapsed() < 2800; step = step * 2 / 3) {\n            for (int i = 0; i + step < rs && elapsed() < 2800; i += max(1, step/3)) {\n                int j = min(i + step, rs - 1);\n                vector<vector<int>> d;\n                vector<vector<pair<int,int>>> par;\n                dijkstra_from(full_route[i].first, full_route[i].second, d, par);\n                auto shortcut = trace_path(d, par, full_route[i].first, full_route[i].second, full_route[j].first, full_route[j].second);\n                \n                int old_cost = 0;\n                for (int k=i+1;k<=j;k++) old_cost += costg[full_route[k].first][full_route[k].second];\n                int new_cost = 0;\n                for (auto& [pi,pj] : shortcut) new_cost += costg[pi][pj];\n                \n                if (new_cost >= old_cost) continue;\n                \n                // Build new route and check coverage\n                vector<pair<int,int>> new_route;\n                for (int k=0;k<=i;k++) new_route.push_back(full_route[k]);\n                for (auto& p : shortcut) new_route.push_back(p);\n                for (int k=j+1;k<rs;k++) new_route.push_back(full_route[k]);\n                \n                if (check_full_coverage(new_route)) {\n                    full_route = new_route;\n                    best_cost = route_cost(full_route);\n                    improved = true;\n                    break;\n                }\n            }\n            if (improved) break;\n        }\n        if (!improved) break;\n    }\n    \n    cout << path_to_string(full_route) << endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N,M,K,R;\n    scanf(\"%d%d%d%d\",&N,&M,&K,&R);\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for(int i=0;i<N;i++) for(int j=0;j<K;j++) scanf(\"%d\",&d[i][j]);\n    \n    vector<vector<int>> deps(N), rdeps(N);\n    for(int i=0;i<R;i++){\n        int u,v; scanf(\"%d%d\",&u,&v); u--;v--;\n        deps[v].push_back(u);\n        rdeps[u].push_back(v);\n    }\n    \n    // Skill estimation\n    vector<vector<double>> s_est(M, vector<double>(K, 0.0));\n    {\n        // Mean of |N(0,1)| = sqrt(2/pi) \u2248 0.798\n        // E[q] = 40, E[norm] = sqrt(K * 2/pi)\n        // E[s_k] = 40 * sqrt(2/pi) / sqrt(K * 2/pi) = 40/sqrt(K)\n        // But actually q * |N|/norm has complex distribution\n        // Start with moderate estimate\n        double base = 35.0 / sqrt((double)K) * sqrt(2.0/M_PI);\n        for(int j=0;j<M;j++) for(int k=0;k<K;k++) s_est[j][k] = base;\n    }\n    \n    vector<vector<double>> s_low(M, vector<double>(K, 0.0));\n    \n    vector<int> task_status(N, -1); // -1=not started, 0=in progress, 1=done\n    vector<int> member_task(M, -1);\n    vector<int> member_start(M, -1);\n    \n    auto est_w = [&](int task, int member) -> double {\n        double w = 0;\n        for(int k=0;k<K;k++) w += max(0.0, (double)d[task][k] - s_est[member][k]);\n        return w;\n    };\n    \n    auto est_time_val = [&](int task, int member) -> double {\n        double w = est_w(task, member);\n        return max(1.0, w);\n    };\n    \n    auto can_start = [&](int task) -> bool {\n        if(task_status[task]!=-1) return false;\n        for(int dep : deps[task]) if(task_status[dep]!=1) return false;\n        return true;\n    };\n    \n    // Compute critical path length from each task to end using estimated min times\n    auto compute_cp = [&]() -> vector<double> {\n        vector<double> cp(N, 0.0);\n        vector<int> indeg(N,0);\n        for(int i=0;i<N;i++) for(int j:rdeps[i]) indeg[j]++;\n        queue<int> q;\n        for(int i=0;i<N;i++) if(indeg[i]==0) q.push(i);\n        vector<int> topo;\n        while(!q.empty()){int u=q.front();q.pop();topo.push_back(u);for(int v:rdeps[u])if(--indeg[v]==0)q.push(v);}\n        \n        for(int i=N-1;i>=0;i--){\n            int u=topo[i];\n            if(task_status[u]==1){ cp[u]=0; continue; }\n            double min_t = 1e9;\n            for(int j=0;j<M;j++) min_t = min(min_t, est_time_val(u, j));\n            cp[u] = min_t;\n            for(int v:rdeps[u]) cp[u] = max(cp[u], min_t + cp[v]);\n        }\n        return cp;\n    };\n    \n    // Hungarian algorithm for min cost assignment\n    // Assigns up to min(n_tasks, n_members) pairs minimizing total cost\n    auto hungarian = [&](vector<vector<double>>& cost, int nrow, int ncol) -> vector<int> {\n        // cost[i][j] = cost of assigning row i to col j\n        // Returns assignment[i] = j or -1\n        // Simple O(n^3) Hungarian\n        int n = max(nrow, ncol);\n        vector<vector<double>> a(n+1, vector<double>(n+1, 0));\n        for(int i=1;i<=nrow;i++) for(int j=1;j<=ncol;j++) a[i][j] = cost[i-1][j-1];\n        \n        vector<double> u(n+1,0), v(n+1,0);\n        vector<int> p(n+1,0), way(n+1,0);\n        \n        for(int i=1;i<=n;i++){\n            p[0]=i;\n            int j0=0;\n            vector<double> minv(n+1, 1e18);\n            vector<bool> used(n+1, false);\n            do {\n                used[j0]=true;\n                int i0=p[j0], j1=-1;\n                double delta=1e18;\n                for(int j=1;j<=n;j++){\n                    if(!used[j]){\n                        double cur=a[i0][j]-u[i0]-v[j];\n                        if(cur<minv[j]){minv[j]=cur;way[j]=j0;}\n                        if(minv[j]<delta){delta=minv[j];j1=j;}\n                    }\n                }\n                for(int j=0;j<=n;j++){\n                    if(used[j]){u[p[j]]+=delta;v[j]-=delta;}\n                    else minv[j]-=delta;\n                }\n                j0=j1;\n            } while(p[j0]!=0);\n            do {int j1=way[j0];p[j0]=p[j1];j0=j1;} while(j0);\n        }\n        \n        vector<int> ans(nrow, -1);\n        for(int j=1;j<=n;j++) if(p[j]>0 && p[j]<=nrow && j<=ncol) ans[p[j]-1]=j-1;\n        return ans;\n    };\n    \n    auto update_skills = [&](int member, int task, int t_obs) {\n        if(t_obs == 1) {\n            for(int k=0;k<K;k++) {\n                s_low[member][k] = max(s_low[member][k], (double)d[task][k]);\n                s_est[member][k] = max(s_est[member][k], (double)d[task][k]);\n            }\n        } else {\n            double w_target = (double)t_obs;\n            double w_cur = 0;\n            vector<int> active_k;\n            for(int k=0;k<K;k++) {\n                double gap = (double)d[task][k] - s_est[member][k];\n                if(gap > 0) { w_cur += gap; active_k.push_back(k); }\n            }\n            \n            if(active_k.empty()) {\n                double total_d = 0;\n                for(int k=0;k<K;k++) total_d += d[task][k];\n                if(total_d > 0) {\n                    for(int k=0;k<K;k++) {\n                        if(d[task][k] > 0) {\n                            double reduction = w_target * d[task][k] / total_d;\n                            double new_s = (double)d[task][k] - reduction;\n                            double blend = s_est[member][k] * 0.6 + new_s * 0.4;\n                            s_est[member][k] = max(blend, s_low[member][k]);\n                        }\n                    }\n                }\n            } else if(w_cur > 0) {\n                double ratio = w_target / w_cur;\n                double alpha = 0.35;\n                for(int k : active_k) {\n                    double gap = (double)d[task][k] - s_est[member][k];\n                    double new_gap = gap * ratio;\n                    double new_s = (double)d[task][k] - new_gap;\n                    s_est[member][k] = s_est[member][k] * (1.0-alpha) + new_s * alpha;\n                    s_est[member][k] = max(s_est[member][k], s_low[member][k]);\n                    s_est[member][k] = max(s_est[member][k], 0.0);\n                }\n                // Also update non-active: they're confirmed >= d[task][k]\n                for(int k=0;k<K;k++){\n                    if((double)d[task][k] - s_est[member][k] <= 0 && d[task][k] > 0) {\n                        // skill was sufficient, this is consistent\n                    }\n                }\n            }\n        }\n    };\n    \n    for(int day=1; day<=2000; day++){\n        vector<double> cp = compute_cp();\n        \n        vector<int> free_members;\n        for(int j=0;j<M;j++) if(member_task[j]==-1) free_members.push_back(j);\n        \n        vector<int> avail_tasks;\n        for(int i=0;i<N;i++) if(can_start(i)) avail_tasks.push_back(i);\n        \n        // Sort by critical path descending\n        sort(avail_tasks.begin(), avail_tasks.end(), [&](int a, int b){ return cp[a]>cp[b]; });\n        \n        vector<pair<int,int>> assignments;\n        \n        int fm = free_members.size();\n        int at = min((int)avail_tasks.size(), fm);\n        \n        if(fm > 0 && at > 0) {\n            // Take top tasks (up to 3x members for Hungarian flexibility)\n            int n_tasks = min((int)avail_tasks.size(), fm * 3);\n            n_tasks = min(n_tasks, 60);\n            vector<int> cand(avail_tasks.begin(), avail_tasks.begin() + n_tasks);\n            \n            // Use Hungarian if manageable\n            if(n_tasks <= 60 && fm <= 20) {\n                // Cost: est_time - bonus for critical path\n                // We want to minimize total completion time weighted by criticality\n                vector<vector<double>> cost(n_tasks, vector<double>(fm));\n                for(int i=0;i<n_tasks;i++){\n                    for(int j=0;j<fm;j++){\n                        double t = est_time_val(cand[i], free_members[j]);\n                        // Penalize not assigning critical tasks: use large cost for dummy\n                        cost[i][j] = t - cp[cand[i]] * 0.1;\n                    }\n                }\n                \n                auto asgn = hungarian(cost, n_tasks, fm);\n                \n                // Collect valid assignments (only top fm tasks get assigned)\n                vector<pair<double,int>> scored;\n                for(int i=0;i<n_tasks;i++){\n                    if(asgn[i]>=0 && asgn[i]<fm){\n                        scored.push_back({cost[i][asgn[i]], i});\n                    }\n                }\n                sort(scored.begin(), scored.end());\n                \n                set<int> used_m;\n                for(auto& [sc, ti] : scored){\n                    if((int)used_m.size() >= fm) break;\n                    int mi = asgn[ti];\n                    if(used_m.count(mi)) continue;\n                    used_m.insert(mi);\n                    int task = cand[ti];\n                    int mem = free_members[mi];\n                    assignments.push_back({mem, task});\n                    task_status[task] = 0;\n                    member_task[mem] = task;\n                    member_start[mem] = day;\n                }\n            }\n        }\n        \n        printf(\"%d\", (int)assignments.size());\n        for(auto& [a,b] : assignments) printf(\" %d %d\", a+1, b+1);\n        printf(\"\\n\");\n        fflush(stdout);\n        \n        int n_done; scanf(\"%d\",&n_done);\n        if(n_done==-1) return 0;\n        for(int i=0;i<n_done;i++){\n            int f; scanf(\"%d\",&f); f--;\n            int task = member_task[f];\n            int t_obs = day - member_start[f] + 1;\n            task_status[task] = 1;\n            member_task[f] = -1;\n            update_skills(f, task, t_obs);\n        }\n    }\n    \n    int dummy; scanf(\"%d\",&dummy);\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto t0=chrono::steady_clock::now();\n    auto elapsed=[&](){return chrono::duration<double>(chrono::steady_clock::now()-t0).count();};\n    \n    const int N=1000, M=50, K=2*M;\n    vector<int> a(N),b(N),c(N),d(N);\n    for(int i=0;i<N;i++) cin>>a[i]>>b[i]>>c[i]>>d[i];\n    \n    auto md=[](int x1,int y1,int x2,int y2)->int{return abs(x1-x2)+abs(y1-y2);};\n    \n    vector<double> sc(N);\n    for(int i=0;i<N;i++){\n        sc[i] = md(400,400,a[i],b[i]) + md(a[i],b[i],c[i],d[i]) + md(c[i],d[i],400,400);\n    }\n    vector<int> sidx(N);\n    iota(sidx.begin(),sidx.end(),0);\n    sort(sidx.begin(),sidx.end(),[&](int i,int j){return sc[i]<sc[j];});\n    \n    vector<int> chosen(sidx.begin(),sidx.begin()+M);\n    \n    mt19937 rng(42);\n    vector<int> px(K),py(K);\n    \n    auto setupCoords=[&](){\n        for(int i=0;i<M;i++){\n            px[2*i]=a[chosen[i]]; py[2*i]=b[chosen[i]];\n            px[2*i+1]=c[chosen[i]]; py[2*i+1]=d[chosen[i]];\n        }\n    };\n    \n    auto gdist=[&](int u, int v)->int{\n        int x1=u<0?400:px[u], y1=u<0?400:py[u];\n        int x2=v<0?400:px[v], y2=v<0?400:py[v];\n        return abs(x1-x2)+abs(y1-y2);\n    };\n    \n    auto greedyRoute=[&]()->vector<int>{\n        vector<int> route;\n        vector<bool> visited(K,false);\n        vector<bool> picked(M,false);\n        int cx=400,cy=400;\n        for(int step=0;step<K;step++){\n            int best=-1, bestd=INT_MAX;\n            for(int j=0;j<K;j++){\n                if(visited[j]) continue;\n                int ord=j/2; bool isDel=(j%2==1);\n                if(isDel && !picked[ord]) continue;\n                int d2=md(cx,cy,px[j],py[j]);\n                if(d2<bestd){bestd=d2;best=j;}\n            }\n            visited[best]=true;\n            if(best%2==0) picked[best/2]=true;\n            route.push_back(best);\n            cx=px[best]; cy=py[best];\n        }\n        return route;\n    };\n    \n    auto calcCost=[&](vector<int>& r)->int{\n        int t=gdist(-1,r[0]);\n        for(int i=0;i+1<K;i++) t+=gdist(r[i],r[i+1]);\n        t+=gdist(r.back(),-1);\n        return t;\n    };\n    \n    auto checkFeasible=[&](vector<int>& r)->bool{\n        vector<int> pos(K);\n        for(int i=0;i<K;i++) pos[r[i]]=i;\n        for(int i=0;i<M;i++) if(pos[2*i]>pos[2*i+1]) return false;\n        return true;\n    };\n    \n    setupCoords();\n    vector<int> route=greedyRoute();\n    int curCost=calcCost(route);\n    \n    vector<int> bestRoute=route;\n    vector<int> bestChosen=chosen;\n    int bestGlobalCost=curCost;\n    \n    // SA on route\n    auto optimizeRoute=[&](vector<int>& rt, double tl)->int{\n        int cost=calcCost(rt);\n        vector<int> pos(K);\n        for(int i=0;i<K;i++) pos[rt[i]]=i;\n        \n        int localBestCost=cost;\n        vector<int> localBestRoute=rt;\n        \n        while(elapsed()<tl){\n            double ratio=(tl-elapsed())/(tl-0.0);\n            if(ratio<0) break;\n            double temp=150.0*ratio;\n            \n            // Do a batch\n            for(int iter=0;iter<500;iter++){\n                int op=rng()%10;\n                \n                if(op<6){\n                    // 2-opt\n                    int i=rng()%K, j=rng()%K;\n                    if(i>j) swap(i,j);\n                    if(i==j||j-i>=K-1) continue;\n                    \n                    int pI=(i==0)?-1:rt[i-1];\n                    int nJ=(j==K-1)?-1:rt[j+1];\n                    int delta=gdist(pI,rt[j])+gdist(rt[i],nJ)-gdist(pI,rt[i])-gdist(rt[j],nJ);\n                    \n                    bool accept=(delta<0)||(temp>0.01 && (rng()%1000000)<1000000.0*exp(-(double)delta/temp));\n                    if(!accept) continue;\n                    \n                    // Check feasibility\n                    bool ok=true;\n                    for(int p=i;p<=j&&ok;p++){\n                        int node=rt[p];\n                        int ord=node/2;\n                        int partner=(node%2==0)?node+1:node-1;\n                        int pp=pos[partner];\n                        int np=i+j-p;\n                        if(pp>=i && pp<=j){\n                            int npp=i+j-pp;\n                            if(node%2==0){ if(np>=npp) ok=false; }\n                            else { if(np<=npp) ok=false; }\n                        } else {\n                            if(node%2==0){ if(np>=pp) ok=false; }\n                            else { if(np<=pp) ok=false; }\n                        }\n                    }\n                    if(ok){\n                        reverse(rt.begin()+i,rt.begin()+j+1);\n                        for(int p=i;p<=j;p++) pos[rt[p]]=p;\n                        cost+=delta;\n                        if(cost<localBestCost){localBestCost=cost;localBestRoute=rt;}\n                    }\n                } else {\n                    // Relocate\n                    int i=rng()%K;\n                    int node=rt[i];\n                    int ord=node/2;\n                    bool isDel=(node%2==1);\n                    int partnerPos=pos[isDel?(2*ord):(2*ord+1)];\n                    \n                    int pI=(i==0)?-1:rt[i-1];\n                    int nI=(i==K-1)?-1:rt[i+1];\n                    int remSave=gdist(pI,node)+gdist(node,nI)-gdist(pI,nI);\n                    \n                    // Pick random target\n                    int j=rng()%(K-1);\n                    // j is insert position in the array after removal\n                    // Adjust: after removing pos i, array shrinks\n                    // Precedence: pickup before delivery\n                    int adjPartner=partnerPos>(i)?partnerPos-1:partnerPos;\n                    if(isDel){ if(j<=adjPartner) continue; }\n                    else { if(j>adjPartner) continue; }\n                    \n                    // Compute insert cost\n                    // Build temp array mentally\n                    // After removing i, element at new pos j-1 and j\n                    // We need actual nodes at those positions\n                    // Remove rt[i], positions shift\n                    int pJ,nJ_node;\n                    {\n                        // Map j in reduced array back\n                        int rj=j; // position in reduced array\n                        if(rj==0) pJ=-1;\n                        else {\n                            int orig=rj; if(orig>=i) orig++; \n                            // Wait, let me just be careful\n                            // reduced[k] = rt[k] if k<i, rt[k+1] if k>=i\n                            int prevOrig=(rj-1<i)?(rj-1):(rj);\n                            pJ=rt[prevOrig];\n                        }\n                        if(rj==K-1) nJ_node=-1;\n                        else {\n                            int nextOrig=(rj<i)?rj:(rj+1);\n                            nJ_node=rt[nextOrig];\n                        }\n                    }\n                    int insCost=gdist(pJ,node)+gdist(node,nJ_node)-gdist(pJ,nJ_node);\n                    int delta=insCost-remSave;\n                    \n                    bool accept=(delta<0)||(temp>0.01 && (rng()%1000000)<1000000.0*exp(-(double)delta/temp));\n                    if(!accept) continue;\n                    \n                    // Actually do it\n                    rt.erase(rt.begin()+i);\n                    int insertPos=j;\n                    rt.insert(rt.begin()+insertPos,node);\n                    for(int p=0;p<K;p++) pos[rt[p]]=p;\n                    cost+=delta;\n                    if(cost<localBestCost){localBestCost=cost;localBestRoute=rt;}\n                }\n            }\n            // Periodically fix cost drift\n            cost=calcCost(rt);\n        }\n        rt=localBestRoute;\n        return localBestCost;\n    };\n    \n    curCost=optimizeRoute(route,0.8);\n    if(curCost<bestGlobalCost){\n        bestGlobalCost=curCost; bestRoute=route; bestChosen=chosen;\n    }\n    \n    // Try order swaps\n    set<int> inSet(chosen.begin(),chosen.end());\n    vector<int> notChosen;\n    for(int i=0;i<N;i++) if(!inSet.count(i)) notChosen.push_back(i);\n    \n    while(elapsed()<1.85){\n        int ci=rng()%M, ni=rng()%(int)notChosen.size();\n        int oldOrd=chosen[ci], newOrd=notChosen[ni];\n        chosen[ci]=newOrd;\n        setupCoords();\n        auto rt=greedyRoute();\n        double budget=min(elapsed()+0.08, 1.85);\n        int c=optimizeRoute(rt,budget);\n        if(c<bestGlobalCost){\n            bestGlobalCost=c; bestRoute=rt; bestChosen=chosen;\n            inSet.erase(oldOrd); inSet.insert(newOrd);\n            notChosen[ni]=oldOrd;\n        } else {\n            chosen[ci]=oldOrd;\n        }\n    }\n    \n    // Restore best\n    chosen=bestChosen;\n    setupCoords();\n    route=bestRoute;\n    \n    // Validate\n    assert(checkFeasible(route));\n    assert((int)route.size()==K);\n    \n    cout<<M;\n    for(int i=0;i<M;i++) cout<<\" \"<<chosen[i]+1;\n    cout<<\"\\n\";\n    cout<<K+2<<\" 400 400\";\n    for(int j=0;j<K;j++) cout<<\" \"<<px[route[j]]<<\" \"<<py[route[j]];\n    cout<<\" 400 400\\n\";\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n): p(n), sz(n,1) { iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a, int b){ a=find(a);b=find(b);if(a==b)return false;if(sz[a]<sz[b])swap(a,b);p[b]=a;sz[a]+=sz[b];return true; }\n    bool same(int a,int b){return find(a)==find(b);}\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    int N=400, M=1995;\n    vector<int> x(N),y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n    vector<int> U(M),V(M);\n    vector<double> D(M);\n    for(int i=0;i<M;i++){\n        cin>>U[i]>>V[i];\n        double dx=x[U[i]]-x[V[i]], dy=y[U[i]]-y[V[i]];\n        D[i]=round(sqrt(dx*dx+dy*dy));\n    }\n    \n    DSU dsu(N);\n    \n    for(int i=0;i<M;i++){\n        int l; cin>>l;\n        \n        if(dsu.same(U[i],V[i])){\n            cout<<0<<\"\\n\"<<flush;\n            continue;\n        }\n        \n        int fu=dsu.find(U[i]), fv=dsu.find(V[i]);\n        \n        // Collect future alternatives directly connecting these two components\n        vector<double> alt_d;\n        DSU tmp(N);\n        for(int j=i+1;j<M;j++){\n            if(!dsu.same(U[j],V[j])){\n                tmp.unite(dsu.find(U[j]), dsu.find(V[j]));\n            }\n            int a=dsu.find(U[j]), b=dsu.find(V[j]);\n            if((a==fu&&b==fv)||(a==fv&&b==fu)){\n                alt_d.push_back(D[j]);\n            }\n        }\n        \n        bool still_connected = tmp.same(fu, fv);\n        \n        if(!still_connected){\n            // Must accept\n            cout<<1<<\"\\n\"<<flush;\n            dsu.unite(U[i],V[i]);\n            continue;\n        }\n        \n        // Compute probability that no alternative beats l_i\n        // Alternative j has cost uniform in [d_j, 3*d_j]\n        // P(alt_j >= l) = min(1, max(0, (3*d_j - l + 1) / (2*d_j + 1))) ... wait, need P(alt_j > l)\n        // Actually P(alt_j <= l) = clamp((l - d_j + 1)/(2*d_j + 1), 0, 1) approximately\n        // P(all alts > l) = prod(1 - P(alt_j <= l))\n        \n        // But we want expected min. Let me compute: should I accept l or wait?\n        // Accept if l <= E[min of alternatives that I'd actually pick]\n        // Simpler: probability none is <= l\n        double prob_all_worse = 1.0;\n        for(double dj : alt_d){\n            // cost uniform in [dj, 3*dj]\n            double p_better = 0;\n            if(l > 3*dj) p_better = 1.0;\n            else if(l > dj) p_better = (double)(l - dj) / (2.0*dj);\n            // else p_better = 0\n            prob_all_worse *= (1.0 - p_better);\n        }\n        \n        // If prob_all_worse is high, no alternative likely beats l, so accept\n        // If prob_all_worse is low, likely something better exists, so reject\n        // But we also need to account for: if we reject, we still need SOME edge\n        // The expected cost of the best alternative when we wait\n        \n        // Simple threshold: accept if prob_all_worse > some value\n        // Or better: accept if l is good relative to expected min\n        \n        // Expected min of alternatives\n        // For uniform [dj, 3dj], E[X] = 2dj\n        // Sort alt_d, the smallest d gives cheapest expected\n        \n        // Use threshold on prob_all_worse adjusted by ratio\n        double ratio = (double)l / D[i];\n        \n        // Dynamic threshold based on prob_all_worse and ratio\n        // Accept if unlikely to find better AND ratio is reasonable\n        if(prob_all_worse > 0.4 || ratio <= 1.1){\n            cout<<1<<\"\\n\"<<flush;\n            dsu.unite(U[i],V[i]);\n        } else {\n            cout<<0<<\"\\n\"<<flush;\n        }\n    }\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GS=30;\nint N,M;\nint px[25],py[25],ptype[25];\nint hx[15],hy[15];\nbool wall_[35][35];\n\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\nchar dmc[]={'U','D','L','R'};\nchar dpc[]={'u','d','l','r'};\n\nbool inB(int x,int y){return x>=1&&x<=GS&&y>=1&&y<=GS;}\n\nbool hasPetAdjacentOrOn(int x,int y){\n    for(int i=0;i<N;i++)\n        if(abs(px[i]-x)+abs(py[i]-y)<=1) return true;\n    return false;\n}\nbool hasHumanAt(int x,int y){\n    for(int i=0;i<M;i++) if(hx[i]==x&&hy[i]==y) return true;\n    return false;\n}\n\nint bfsDist(int sx,int sy,int tx,int ty){\n    if(sx==tx&&sy==ty) return 0;\n    int dist[31][31];\n    memset(dist,-1,sizeof(dist));\n    dist[sx][sy]=0;\n    queue<pair<int,int>> q;\n    q.push({sx,sy});\n    while(!q.empty()){\n        auto [cx,cy]=q.front();q.pop();\n        for(int d=0;d<4;d++){\n            int nx=cx+dx[d],ny=cy+dy[d];\n            if(inB(nx,ny)&&!wall_[nx][ny]&&dist[nx][ny]==-1){\n                dist[nx][ny]=dist[cx][cy]+1;\n                if(nx==tx&&ny==ty) return dist[nx][ny];\n                q.push({nx,ny});\n            }\n        }\n    }\n    return 1e9;\n}\n\nvector<pair<int,int>> bfsPath(int sx,int sy,int tx,int ty){\n    if(sx==tx&&sy==ty) return {};\n    int prev[31][31];\n    memset(prev,-1,sizeof(prev));\n    prev[sx][sy]=-2;\n    queue<pair<int,int>> q;\n    q.push({sx,sy});\n    while(!q.empty()){\n        auto [cx,cy]=q.front();q.pop();\n        for(int d=0;d<4;d++){\n            int nx=cx+dx[d],ny=cy+dy[d];\n            if(inB(nx,ny)&&!wall_[nx][ny]&&prev[nx][ny]==-1){\n                prev[nx][ny]=d;\n                if(nx==tx&&ny==ty){\n                    vector<pair<int,int>> path;\n                    int x=tx,y=ty;\n                    while(x!=sx||y!=sy){\n                        path.push_back({x,y});\n                        int dd=prev[x][y];\n                        x-=dx[dd];y-=dy[dd];\n                    }\n                    reverse(path.begin(),path.end());\n                    return path;\n                }\n                q.push({nx,ny});\n            }\n        }\n    }\n    return {};\n}\n\n// Evaluate a rectangular safe region bounded by walls (and grid edges)\n// safeR1..safeR2, safeC1..safeC2 is the interior\n// wallRows/wallCols are the rows/cols that need walls\nstruct Plan {\n    int safeR1,safeR2,safeC1,safeC2;\n    vector<pair<int,int>> wallCells;\n    double score;\n    int petsInside, humansInside;\n    int area;\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin>>N;\n    for(int i=0;i<N;i++) cin>>px[i]>>py[i]>>ptype[i];\n    cin>>M;\n    for(int i=0;i<M;i++) cin>>hx[i]>>hy[i];\n    \n    memset(wall_,false,sizeof(wall_));\n    \n    // Evaluate rectangular regions that use grid edges + wall lines\n    // A region can be: corner (2 wall lines), edge strip (1 wall line), or band (2 parallel lines)\n    \n    Plan bestPlan;\n    bestPlan.score = -1e18;\n    \n    auto evaluate = [&](int r1, int r2, int c1, int c2) {\n        // Safe interior: r1..r2, c1..c2\n        // Walls needed: row r1-1 if r1>1, row r2+1 if r2<30, col c1-1 if c1>1, col c2+1 if c2<30\n        Plan p;\n        p.safeR1=r1; p.safeR2=r2; p.safeC1=c1; p.safeC2=c2;\n        p.wallCells.clear();\n        \n        // Top wall\n        if(r1>1) for(int c=max(1,c1-1);c<=min(30,c2+1);c++) p.wallCells.push_back({r1-1,c});\n        // Bottom wall\n        if(r2<30) for(int c=max(1,c1-1);c<=min(30,c2+1);c++) p.wallCells.push_back({r2+1,c});\n        // Left wall\n        if(c1>1) for(int r=r1;r<=r2;r++) p.wallCells.push_back({r,c1-1});\n        // Right wall\n        if(c2<30) for(int r=r1;r<=r2;r++) p.wallCells.push_back({r,c2+1});\n        \n        p.petsInside=0;\n        for(int i=0;i<N;i++)\n            if(px[i]>=r1&&px[i]<=r2&&py[i]>=c1&&py[i]<=c2) p.petsInside++;\n        p.humansInside=0;\n        for(int i=0;i<M;i++)\n            if(hx[i]>=r1&&hx[i]<=r2&&hy[i]>=c1&&hy[i]<=c2) p.humansInside++;\n        \n        p.area=(r2-r1+1)*(c2-c1+1);\n        int wallCount=(int)p.wallCells.size();\n        \n        // Each person can build ~1 wall/turn, but needs to travel\n        // Estimate turns to complete: wallCount/M + travel time\n        // People inside can build, people outside need to get inside first\n        int humansOutside = M - p.humansInside;\n        double turnsEstimate = (double)wallCount / M + humansOutside * 5;\n        \n        // If too many walls for available turns, penalize\n        if(turnsEstimate > 250) {\n            p.score = -1e18;\n        } else {\n            // Score ~ area/900 * 2^(-petsInside) * humansInside/M\n            // But pets inside will likely leave if we build walls after they leave\n            // Pets outside won't get in once walls are built\n            // Key: minimize initial pets inside (they might escape during building)\n            double areaScore = (double)p.area / 900.0;\n            double petPenalty = pow(2.0, -(double)p.petsInside);\n            double humanFrac = (double)max(p.humansInside,1) / M;\n            p.score = areaScore * petPenalty * humanFrac * 1000 - wallCount * 0.1;\n            // Bonus for using edges (fewer walls needed)\n            if(r1==1) p.score *= 1.1;\n            if(r2==30) p.score *= 1.1;\n            if(c1==1) p.score *= 1.1;\n            if(c2==30) p.score *= 1.1;\n        }\n        \n        return p;\n    };\n    \n    // Try various rectangular regions\n    // Edge strips (1 wall line)\n    for(int w=3;w<=28;w++){\n        // Top strip: rows 1..w\n        auto p=evaluate(1,w,1,30); if(p.score>bestPlan.score) bestPlan=p;\n        // Bottom strip\n        p=evaluate(31-w,30,1,30); if(p.score>bestPlan.score) bestPlan=p;\n        // Left strip\n        p=evaluate(1,30,1,w); if(p.score>bestPlan.score) bestPlan=p;\n        // Right strip\n        p=evaluate(1,30,31-w,30); if(p.score>bestPlan.score) bestPlan=p;\n    }\n    \n    // Corner regions (2 wall lines)\n    for(int h=4;h<=25;h++){\n        for(int w=4;w<=25;w++){\n            auto p=evaluate(1,h,1,w); if(p.score>bestPlan.score) bestPlan=p;\n            p=evaluate(1,h,31-w,30); if(p.score>bestPlan.score) bestPlan=p;\n            p=evaluate(31-h,30,1,w); if(p.score>bestPlan.score) bestPlan=p;\n            p=evaluate(31-h,30,31-w,30); if(p.score>bestPlan.score) bestPlan=p;\n        }\n    }\n    \n    // Band regions (2 wall lines, center)\n    for(int r1=3;r1<=15;r1++){\n        for(int r2=r1+3;r2<=28;r2++){\n            auto p=evaluate(r1,r2,1,30); if(p.score>bestPlan.score) bestPlan=p;\n        }\n    }\n    for(int c1=3;c1<=15;c1++){\n        for(int c2=c1+3;c2<=28;c2++){\n            auto p=evaluate(1,30,c1,c2); if(p.score>bestPlan.score) bestPlan=p;\n        }\n    }\n    \n    // Now execute the plan\n    set<pair<int,int>> wallNeeded;\n    for(auto& wc: bestPlan.wallCells) wallNeeded.insert(wc);\n    \n    int sR1=bestPlan.safeR1, sR2=bestPlan.safeR2, sC1=bestPlan.safeC1, sC2=bestPlan.safeC2;\n    \n    auto inSafe=[&](int r,int c)->bool{\n        return r>=sR1&&r<=sR2&&c>=sC1&&c<=sC2;\n    };\n    \n    // Phase approach:\n    // Phase 1: Move all people toward safe zone (or toward wall building positions)\n    // Phase 2: Build walls\n    // Phase 3: Stay safe\n    \n    for(int turn=0;turn<300;turn++){\n        string actions(M,'.');\n        \n        // Remove completed walls\n        {\n            vector<pair<int,int>> rem;\n            for(auto& w:wallNeeded) if(wall_[w.first][w.second]) rem.push_back(w);\n            for(auto& w:rem) wallNeeded.erase(w);\n        }\n        \n        set<pair<int,int>> newWallsThisTurn;\n        set<pair<int,int>> movingTo; // squares people are moving to\n        \n        // Assign each person\n        for(int p=0;p<M;p++){\n            int bx=hx[p],by=hy[p];\n            \n            // Try to build adjacent wall cell\n            // Prefer building from safe side\n            int bestD=-1;\n            int bestPri=-1;\n            for(int d=0;d<4;d++){\n                int nx=bx+dx[d],ny=by+dy[d];\n                if(!inB(nx,ny)) continue;\n                if(!wallNeeded.count({nx,ny})) continue;\n                if(wall_[nx][ny]) continue;\n                if(hasPetAdjacentOrOn(nx,ny)) continue;\n                if(hasHumanAt(nx,ny)) continue;\n                int pri=1;\n                if(inSafe(bx,by)) pri=10; // building from safe side is better\n                if(pri>bestPri){bestPri=pri;bestD=d;}\n            }\n            \n            if(bestD>=0){\n                int nx=bx+dx[bestD],ny=by+dy[bestD];\n                actions[p]=dpc[bestD];\n                newWallsThisTurn.insert({nx,ny});\n                wallNeeded.erase({nx,ny});\n                continue;\n            }\n            \n            // If in safe zone and walls are done, stay\n            if(wallNeeded.empty() && inSafe(bx,by)){\n                actions[p]='.';\n                continue;\n            }\n            \n            // Move toward: nearest wall cell build position (on safe side), or safe zone\n            pair<int,int> bestTgt={-1,-1};\n            int bestDist=1e9;\n            \n            if(!wallNeeded.empty()){\n                for(auto& wc:wallNeeded){\n                    for(int d=0;d<4;d++){\n                        int ax=wc.first+dx[d],ay=wc.second+dy[d];\n                        if(!inB(ax,ay)||wall_[ax][ay]) continue;\n                        // Prefer safe side positions\n                        int pri=0;\n                        if(inSafe(ax,ay)) pri=-100;\n                        int dist=abs(bx-ax)+abs(by-ay)+pri;\n                        if(dist<bestDist){bestDist=dist;bestTgt={ax,ay};}\n                    }\n                }\n            }\n            \n            if(bestTgt.first==-1){\n                // Move toward center of safe zone\n                int tr=(sR1+sR2)/2,tc=(sC1+sC2)/2;\n                bestTgt={tr,tc};\n            }\n            \n            if(bestTgt.first==bx&&bestTgt.second==by){\n                actions[p]='.';\n                continue;\n            }\n            \n            auto path=bfsPath(bx,by,bestTgt.first,bestTgt.second);\n            if(!path.empty()){\n                int nx=path[0].first,ny=path[0].second;\n                if(inB(nx,ny)&&!wall_[nx][ny]&&!newWallsThisTurn.count({nx,ny})){\n                    for(int d=0;d<4;d++){\n                        if(bx+dx[d]==nx&&by+dy[d]==ny){\n                            actions[p]=dmc[d];\n                            movingTo.insert({nx,ny});\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Apply\n        for(int p=0;p<M;p++){\n            char a=actions[p];\n            bool acted=false;\n            for(int d=0;d<4;d++){\n                if(a==dpc[d]){\n                    int nx=hx[p]+dx[d],ny=hy[p]+dy[d];\n                    if(inB(nx,ny)) wall_[nx][ny]=true;\n                    acted=true;\n                }\n                if(a==dmc[d]){\n                    int nx=hx[p]+dx[d],ny=hy[p]+dy[d];\n                    if(inB(nx,ny)&&!wall_[nx][ny]){\n                        hx[p]=nx;hy[p]=ny;\n                    }\n                    acted=true;\n                }\n            }\n        }\n        \n        cout<<actions<<\"\\n\";\n        cout.flush();\n        \n        for(int i=0;i<N;i++){\n            string s;cin>>s;\n            for(char c:s){\n                for(int d=0;d<4;d++){\n                    if(c==dmc[d]){px[i]+=dx[d];py[i]+=dy[d];}\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si,sj,ti,tj;\ndouble p;\nbool hwall[20][19], vwall[19][20];\nint di[]={-1,1,0,0}, dj[]={0,0,-1,1};\n\nbool can_move(int i, int j, int d){\n    if(d==0) return i>0 && !vwall[i-1][j];\n    if(d==1) return i<19 && !vwall[i][j];\n    if(d==2) return j>0 && !hwall[i][j-1];\n    if(d==3) return j<19 && !hwall[i][j];\n    return false;\n}\n\nint bfs_dist[20][20];\n\nvoid compute_bfs(){\n    memset(bfs_dist,-1,sizeof(bfs_dist));\n    queue<pair<int,int>> Q;\n    bfs_dist[ti][tj]=0; Q.push({ti,tj});\n    while(!Q.empty()){\n        auto [ci,cj]=Q.front(); Q.pop();\n        for(int d=0;d<4;d++){\n            if(!can_move(ci,cj,d)) continue;\n            int ni=ci+di[d], nj=cj+dj[d];\n            if(bfs_dist[ni][nj]>=0) continue;\n            bfs_dist[ni][nj]=bfs_dist[ci][cj]+1;\n            Q.push({ni,nj});\n        }\n    }\n}\n\ndouble evaluate_greedy(string& ans, double alpha){\n    double prob[20][20]={};\n    prob[si][sj]=1.0;\n    ans.clear();\n    double total_score=0;\n    \n    for(int t=0;t<200;t++){\n        double rem_prob=0;\n        for(int i=0;i<20;i++) for(int j=0;j<20;j++) rem_prob+=prob[i][j];\n        if(rem_prob<1e-12) break;\n        \n        int bestd=-1; double bestval=-1e18;\n        for(int d=0;d<4;d++){\n            double arrival=0, expected_dist=0;\n            for(int i=0;i<20;i++) for(int j=0;j<20;j++) if(prob[i][j]>1e-15){\n                expected_dist += prob[i][j]*p*bfs_dist[i][j];\n                if(can_move(i,j,d)){\n                    int ni=i+di[d], nj=j+dj[d];\n                    if(ni==ti&&nj==tj){\n                        arrival += prob[i][j]*(1-p);\n                    } else {\n                        expected_dist += prob[i][j]*(1-p)*bfs_dist[ni][nj];\n                    }\n                } else {\n                    expected_dist += prob[i][j]*(1-p)*bfs_dist[i][j];\n                }\n            }\n            double val = arrival*(401.0-(t+1))*alpha - expected_dist;\n            if(val>bestval){bestval=val;bestd=d;}\n        }\n        ans+=\"UDLR\"[bestd];\n        double nprob[20][20]={};\n        for(int i=0;i<20;i++) for(int j=0;j<20;j++) if(prob[i][j]>1e-15){\n            nprob[i][j]+=prob[i][j]*p;\n            if(can_move(i,j,bestd)){\n                int ni=i+di[bestd], nj=j+dj[bestd];\n                if(ni==ti&&nj==tj) total_score+=prob[i][j]*(1-p)*(401-(t+1));\n                else nprob[ni][nj]+=prob[i][j]*(1-p);\n            } else {\n                nprob[i][j]+=prob[i][j]*(1-p);\n            }\n        }\n        memcpy(prob,nprob,sizeof(prob));\n    }\n    return total_score;\n}\n\nint main(){\n    scanf(\"%d%d%d%d%lf\",&si,&sj,&ti,&tj,&p);\n    for(int i=0;i<20;i++){\n        char s[25]; scanf(\"%s\",s);\n        for(int j=0;j<19;j++) hwall[i][j]=(s[j]=='1');\n    }\n    for(int i=0;i<19;i++){\n        char s[25]; scanf(\"%s\",s);\n        for(int j=0;j<20;j++) vwall[i][j]=(s[j]=='1');\n    }\n    compute_bfs();\n    \n    string best_ans;\n    double best_score=-1;\n    \n    // Try different alpha values\n    for(double alpha : {0.0, 0.001, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 50.0, 100.0}){\n        string ans;\n        double sc = evaluate_greedy(ans, alpha);\n        if(sc > best_score){\n            best_score = sc;\n            best_ans = ans;\n        }\n    }\n    \n    printf(\"%s\\n\", best_ans.c_str());\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\nconst int N=30;\nint tiles[N][N],orig[N][N],rot[N][N],best_rot[N][N];\nconst int di[]={0,-1,0,1},dj[]={-1,0,1,0};\nconst int to_dir[8][4]={{1,0,-1,-1},{3,-1,-1,0},{-1,-1,3,2},{-1,2,1,-1},{1,0,3,2},{3,2,1,0},{2,-1,0,-1},{-1,3,-1,1}};\n\nint rotate_tile(int t,int r){\n    static const int rtab[8][4]={{0,1,2,3},{1,2,3,0},{2,3,0,1},{3,0,1,2},{4,5,4,5},{5,4,5,4},{6,7,6,7},{7,6,7,6}};\n    return rtab[t][r];\n}\n\n// loop_id for each port, loop_len for each loop_id\nint loop_id[N][N][4]; // -1 = no loop\nmap<int,int> loop_lengths; // id -> length\nint next_id=0;\n\nint trace_loop(int si,int sj,int sd){\n    int i=si,j=sj,d=sd,len=0;\n    do{\n        int d2=to_dir[tiles[i][j]][d];\n        if(d2<0)return 0;\n        int ni=i+di[d2],nj=j+dj[d2];\n        if((unsigned)ni>=N||(unsigned)nj>=N)return 0;\n        d=(d2+2)&3;i=ni;j=nj;len++;\n    }while(!(i==si&&j==sj&&d==sd));\n    return len;\n}\n\nvoid assign_loop(int si,int sj,int sd,int id,int len){\n    int i=si,j=sj,d=sd;\n    do{\n        loop_id[i][j][d]=id;\n        int d2=to_dir[tiles[i][j]][d];\n        i+=di[d2];j+=dj[d2];\n        d=(d2+2)&3;\n    }while(!(i==si&&j==sj&&d==sd));\n    loop_lengths[id]=len;\n}\n\nvoid clear_loop(int id){loop_lengths.erase(id);}\n\npair<long long,long long> get_score(){\n    if(loop_lengths.size()<2)return{0,0};\n    int m1=0,m2=0;\n    long long s2=0;\n    for(auto&[id,l]:loop_lengths){\n        s2+=(long long)l*l;\n        if(l>=m1){m2=m1;m1=l;}else if(l>m2)m2=l;\n    }\n    return{(long long)m1*m2,s2};\n}\n\nvoid init_all(){\n    memset(loop_id,-1,sizeof(loop_id));\n    loop_lengths.clear();next_id=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)for(int d=0;d<4;d++){\n        if(loop_id[i][j][d]>=0)continue;\n        int len=trace_loop(i,j,d);\n        if(len>0){int id=next_id++;assign_loop(i,j,d,id,len);}\n    }\n}\n\nset<int> get_affected(int ci,int cj){\n    set<int>s;\n    for(int d=0;d<4;d++)if(loop_id[ci][cj][d]>=0)s.insert(loop_id[ci][cj][d]);\n    // Also check neighbors whose port enters (ci,cj)\n    for(int d2=0;d2<4;d2++){\n        int ni=ci+di[d2],nj=cj+dj[d2];\n        if((unsigned)ni<N&&(unsigned)nj<N){\n            int nd=(d2+2)&3;\n            if(loop_id[ni][nj][nd]>=0)s.insert(loop_id[ni][nj][nd]);\n        }\n    }\n    return s;\n}\n\nstruct LoopStart{int i,j,d;};\nvector<LoopStart> find_starts(int id){\n    vector<LoopStart> r;\n    // find any port with this id\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)for(int d=0;d<4;d++)\n        if(loop_id[i][j][d]==id){r.push_back({i,j,d});return r;}\n    return r;\n}\n\nvoid remove_loop(int id){\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)for(int d=0;d<4;d++)\n        if(loop_id[i][j][d]==id)loop_id[i][j][d]=-1;\n    clear_loop(id);\n}\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(0);\n    for(int i=0;i<N;i++){string s;cin>>s;for(int j=0;j<N;j++)orig[i][j]=s[j]-'0';}\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){tiles[i][j]=orig[i][j];rot[i][j]=0;}\n    \n    // Just use fast full recompute SA - optimize the inner loop\n    memset(best_rot,0,sizeof(best_rot));\n    long long best=0;\n    \n    // Full recompute approach but optimized\n    auto calc=[&]()->pair<long long,long long>{\n        static bool vis[N*N*4];\n        memset(vis,0,sizeof(vis));\n        int m1=0,m2=0;long long s2=0;\n        for(int si=0;si<N;si++)for(int sj=0;sj<N;sj++){\n            int t=tiles[si][sj];\n            for(int sd=0;sd<4;sd++){\n                if(vis[si*N*4+sj*4+sd])continue;\n                if(to_dir[t][sd]<0)continue;\n                int i=si,j=sj,d=sd,len=0;bool ok=true;\n                do{\n                    int d2=to_dir[tiles[i][j]][d];\n                    if(d2<0){ok=false;break;}\n                    int ni=i+di[d2],nj=j+dj[d2];\n                    if((unsigned)ni>=N||(unsigned)nj>=N){ok=false;break;}\n                    d=(d2+2)&3;i=ni;j=nj;len++;\n                    vis[i*N*4+j*4+d]=true;\n                }while(!(i==si&&j==sj&&d==sd));\n                if(ok&&len>0){\n                    s2+=(long long)len*len;\n                    if(len>=m1){m2=m1;m1=len;}else if(len>m2)m2=len;\n                }\n            }\n        }\n        return{(long long)m1*m2,s2};\n    };\n    \n    auto[cs,cs2]=calc();\n    best=cs;long long cur=cs,cur2=cs2;\n    mt19937 rng(42);\n    auto start=chrono::steady_clock::now();\n    int iters=0;\n    while(true){\n        double el=chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(el>1.9)break;\n        double T=2000.0*(1.0-el/1.92)+0.5;\n        int ci=rng()%N,cj=rng()%N;\n        int or_=rot[ci][cj],ot=tiles[ci][cj];\n        int nr=(or_+1+rng()%3)%4;\n        rot[ci][cj]=nr;tiles[ci][cj]=rotate_tile(orig[ci][cj],nr);\n        auto[ns,ns2]=calc();\n        double ov=(double)cur+cur2*0.01,nv=(double)ns+ns2*0.01;\n        if(nv>=ov||(rng()%10000)<10000*exp((nv-ov)/T)){\n            cur=ns;cur2=ns2;\n            if(ns>best){best=ns;memcpy(best_rot,rot,sizeof(rot));}\n        }else{rot[ci][cj]=or_;tiles[ci][cj]=ot;}\n        iters++;\n    }\n    string ans(900,'0');\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)ans[i*30+j]='0'+best_rot[i][j];\n    cout<<ans<<endl;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N,T;\nint board[10][10];\nint ei,ej;\nint di[]={-1,1,0,0},dj[]={0,0,-1,1};\nint opp[]={1,0,3,2};\nconst char* dirs=\"UDLR\";\n\nint largest_tree(){\n    int id[10][10],cnt=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(board[i][j])id[i][j]=cnt++;else id[i][j]=-1;\n    vector<vector<int>>adj(cnt);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(!board[i][j])continue;\n        if(i+1<N&&board[i+1][j]&&(board[i][j]&8)&&(board[i+1][j]&2)){adj[id[i][j]].push_back(id[i+1][j]);adj[id[i+1][j]].push_back(id[i][j]);}\n        if(j+1<N&&board[i][j+1]&&(board[i][j]&4)&&(board[i][j+1]&1)){adj[id[i][j]].push_back(id[i][j+1]);adj[id[i][j+1]].push_back(id[i][j]);}\n    }\n    vector<bool>vis(cnt,false);\n    int best=0;\n    for(int s=0;s<cnt;s++)if(!vis[s]){\n        queue<int>q;q.push(s);vis[s]=true;\n        vector<int>comp;int edg=0;\n        while(!q.empty()){int u=q.front();q.pop();comp.push_back(u);for(int v:adj[u]){edg++;if(!vis[v]){vis[v]=true;q.push(v);}}}\n        edg/=2;\n        if(edg==(int)comp.size()-1)best=max(best,(int)comp.size());\n    }\n    return best;\n}\n\nint main(){\n    scanf(\"%d%d\",&N,&T);\n    for(int i=0;i<N;i++){char s[20];scanf(\"%s\",s);for(int j=0;j<N;j++){char c=s[j];board[i][j]=(c>='a'?c-'a'+10:c-'0');if(!board[i][j]){ei=i;ej=j;}}}\n    \n    string ans;\n    mt19937 rng(12345);\n    int cur=largest_tree();\n    int bestScore=cur;\n    string bestAns;\n    int bestBoard[10][10];int bestEi=ei,bestEj=ej;\n    memcpy(bestBoard,board,sizeof(board));\n    int lastDir=-1;\n    \n    auto start=chrono::steady_clock::now();\n    double timeLimit=2.7;\n    \n    while((int)ans.size()<T){\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-start).count();\n        if(elapsed>timeLimit)break;\n        double temp=max(0.1, 5.0*(1.0-elapsed/timeLimit));\n        \n        vector<int>cands;\n        for(int d=0;d<4;d++){\n            if(d==lastDir)continue;// avoid reversal (opp of last would undo)\n            if(lastDir>=0&&d==opp[lastDir])continue;\n            int ni=ei+di[d],nj=ej+dj[d];\n            if(ni>=0&&ni<N&&nj>=0&&nj<N)cands.push_back(d);\n        }\n        if(cands.empty())for(int d=0;d<4;d++){int ni=ei+di[d],nj=ej+dj[d];if(ni>=0&&ni<N&&nj>=0&&nj<N)cands.push_back(d);}\n        \n        int d=cands[rng()%cands.size()];\n        int ni=ei+di[d],nj=ej+dj[d];\n        swap(board[ei][ej],board[ni][nj]);\n        int nv=largest_tree();\n        double delta=nv-cur;\n        if(delta>=0||uniform_real_distribution<>(0,1)(rng)<exp(delta/temp)){\n            ei=ni;ej=nj;ans+=dirs[d];cur=nv;lastDir=d;\n            if(cur>bestScore){bestScore=cur;bestAns=ans;memcpy(bestBoard,board,sizeof(board));bestEi=ei;bestEj=ej;}\n            if(cur==N*N-1)break;\n        }else{\n            swap(board[ei][ej],board[ni][nj]);\n        }\n    }\n    if(bestScore>largest_tree()||true){\n        // Use best found\n        memcpy(board,bestBoard,sizeof(board));\n        printf(\"%s\\n\",bestAns.empty()?\"U\":bestAns.c_str());\n    }else printf(\"%s\\n\",ans.empty()?\"U\":ans.c_str());\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    int total_a = 0;\n    for(int d=1;d<=10;d++){ cin >> a[d]; total_a += a[d]; }\n    vector<long long> sx(N), sy(N);\n    for(int i=0;i<N;i++) cin >> sx[i] >> sy[i];\n    \n    mt19937 rng(12345);\n    int num_lines = min(K, 100);\n    \n    vector<uint64_t> hash_pos(num_lines), hash_neg(num_lines);\n    for(int j=0;j<num_lines;j++){\n        hash_pos[j] = ((uint64_t)rng() << 32) | rng();\n        hash_neg[j] = ((uint64_t)rng() << 32) | rng();\n    }\n    \n    vector<array<long long,4>> lines(num_lines);\n    vector<vector<int8_t>> signs(N, vector<int8_t>(num_lines));\n    vector<uint64_t> phash(N, 0);\n    vector<int> on_count(N, 0); // count of lines passing through point\n    \n    auto compute_sign = [&](int i, int j) -> int8_t {\n        long long dx = lines[j][2]-lines[j][0], dy = lines[j][3]-lines[j][1];\n        __int128 cross = (__int128)dx*(sy[i]-lines[j][1]) - (__int128)dy*(sx[i]-lines[j][0]);\n        if(cross > 0) return 1;\n        if(cross < 0) return -1;\n        return 0;\n    };\n    \n    auto calc_score = [&]() -> int {\n        unordered_map<uint64_t, int> regions;\n        regions.reserve(N*2);\n        for(int i=0;i<N;i++){\n            if(on_count[i]==0) regions[phash[i]]++;\n        }\n        int score = 0;\n        vector<int> bd(11,0);\n        for(auto&[k,v]:regions) if(v>=1&&v<=10) bd[v]++;\n        for(int d=1;d<=10;d++) score += min(a[d], bd[d]);\n        return score;\n    };\n    \n    // Generate line crossing the cake area\n    auto randline = [&]() -> array<long long,4> {\n        // Generate line by picking angle and offset\n        double angle = (rng() % 100000) / 100000.0 * M_PI;\n        double offset = ((int)(rng() % 20001) - 10000);\n        double ca = cos(angle), sa = sin(angle);\n        long long px = llround(-sa * offset + ca * 20000);\n        long long py = llround(ca * offset + sa * 20000);\n        long long qx = llround(-sa * offset - ca * 20000);\n        long long qy = llround(ca * offset - sa * 20000);\n        if(px==qx && py==qy) qx++;\n        return {px, py, qx, qy};\n    };\n    \n    auto perturbline = [&](int idx) -> array<long long,4> {\n        auto l = lines[idx];\n        // Small perturbation\n        int r = rng() % 3;\n        long long delta = (rng() % 2001) - 1000;\n        if(r == 0){ l[0] += delta; l[2] += delta; }\n        else if(r == 1){ l[1] += delta; l[3] += delta; }\n        else {\n            // rotate slightly around midpoint\n            double mx = (l[0]+l[2])/2.0, my = (l[1]+l[3])/2.0;\n            double dx = l[2]-l[0], dy = l[3]-l[1];\n            double ang = (rng()%2001 - 1000) / 10000.0;\n            double c=cos(ang), s=sin(ang);\n            l[0] = llround(mx + c*(l[0]-mx) - s*(l[1]-my));\n            l[1] = llround(my + s*(l[0]-mx) + c*(l[1]-my));\n            l[2] = llround(mx + c*(l[2]-mx) - s*(l[3]-my));\n            l[3] = llround(my + s*(l[2]-mx) + c*(l[3]-my));\n        }\n        if(l[0]==l[2] && l[1]==l[3]) l[2]++;\n        return l;\n    };\n    \n    for(int j=0;j<num_lines;j++) lines[j] = randline();\n    \n    // Build initial state\n    for(int i=0;i<N;i++){\n        phash[i] = 0; on_count[i] = 0;\n        for(int j=0;j<num_lines;j++){\n            signs[i][j] = compute_sign(i,j);\n            if(signs[i][j]==0) on_count[i]++;\n            else if(signs[i][j]>0) phash[i] ^= hash_pos[j];\n            else phash[i] ^= hash_neg[j];\n        }\n    }\n    \n    int cur_score = calc_score();\n    int best_score = cur_score;\n    auto best_lines = lines;\n    \n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    \n    while(true){\n        if((++iter & 127) == 0){\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n            if(elapsed > 2.85) break;\n        }\n        \n        int idx = rng() % num_lines;\n        auto old_line = lines[idx];\n        \n        // Choose perturbation type\n        bool do_perturb = (rng() % 4) != 0; // 75% perturb, 25% random\n        lines[idx] = do_perturb ? perturbline(idx) : randline();\n        \n        // Save and update incrementally\n        static vector<int8_t> old_signs(N);\n        static vector<uint64_t> old_phash(N);\n        static vector<int> old_oncount(N);\n        \n        for(int i=0;i<N;i++){\n            old_signs[i] = signs[i][idx];\n            old_phash[i] = phash[i];\n            old_oncount[i] = on_count[i];\n            \n            if(old_signs[i] > 0) phash[i] ^= hash_pos[idx];\n            else if(old_signs[i] < 0) phash[i] ^= hash_neg[idx];\n            if(old_signs[i] == 0) on_count[i]--;\n            \n            signs[i][idx] = compute_sign(i, idx);\n            if(signs[i][idx] == 0) on_count[i]++;\n            else if(signs[i][idx] > 0) phash[i] ^= hash_pos[idx];\n            else phash[i] ^= hash_neg[idx];\n        }\n        \n        int sc = calc_score();\n        \n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        double temp = 3.0 * max(0.0, 1.0 - elapsed / 2.85);\n        \n        bool accept = sc > cur_score || (temp > 0.001 && (rng()%10000) < 10000*exp((sc-cur_score)/temp));\n        \n        if(accept){\n            cur_score = sc;\n            if(sc > best_score){ best_score = sc; best_lines = lines; }\n        } else {\n            lines[idx] = old_line;\n            for(int i=0;i<N;i++){\n                signs[i][idx] = old_signs[i];\n                phash[i] = old_phash[i];\n                on_count[i] = old_oncount[i];\n            }\n        }\n    }\n    \n    cout << best_lines.size() << \"\\n\";\n    for(auto& l : best_lines)\n        cout << l[0] << \" \" << l[1] << \" \" << l[2] << \" \" << l[3] << \"\\n\";\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nbool dot_grid[62][62];\nunordered_set<uint64_t> used_segs;\n\ninline uint64_t seg_key(int x1,int y1,int x2,int y2){\n    if(x1>x2||(x1==x2&&y1>y2)){swap(x1,x2);swap(y1,y2);}\n    return ((uint64_t)x1<<48)|((uint64_t)y1<<32)|((uint64_t)x2<<16)|(uint64_t)(unsigned short)y2;\n}\n\ninline bool in_bounds(int x,int y){return (unsigned)x<(unsigned)N&&(unsigned)y<(unsigned)N;}\n\nbool check_seg_interior_dots(int x1,int y1,int x2,int y2){\n    int dx=x2-x1, dy=y2-y1;\n    int g=__gcd(abs(dx),abs(dy));\n    if(g<=1) return true;\n    int sx=dx/g, sy=dy/g;\n    for(int i=1;i<g;i++){\n        int px=x1+sx*i, py=y1+sy*i;\n        if(in_bounds(px,py)&&dot_grid[px][py]) return false;\n    }\n    return true;\n}\n\nbool check_and_collect_segs(int x1,int y1,int x2,int y2, vector<uint64_t>& out){\n    int dx=x2-x1, dy=y2-y1;\n    int g=__gcd(abs(dx),abs(dy));\n    if(g==0) return true;\n    int sx=dx/g, sy=dy/g;\n    size_t start=out.size();\n    for(int i=0;i<g;i++){\n        uint64_t k=seg_key(x1+sx*i,y1+sy*i,x1+sx*(i+1),y1+sy*(i+1));\n        if(used_segs.count(k)){out.resize(start);return false;}\n        out.push_back(k);\n    }\n    return true;\n}\n\nstruct Op{int x1,y1,x2,y2,x3,y3,x4,y4;};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    cin>>N>>M;\n    memset(dot_grid,0,sizeof(dot_grid));\n    vector<pair<int,int>> initial_dots;\n    for(int i=0;i<M;i++){\n        int x,y;cin>>x>>y;\n        dot_grid[x][y]=true;\n        initial_dots.push_back({x,y});\n    }\n    \n    double c=(N-1)/2.0;\n    auto weight=[&](int x,int y)->double{return (x-c)*(x-c)+(y-c)*(y-c)+1;};\n    \n    vector<Op> ops;\n    auto start_time=chrono::steady_clock::now();\n    \n    // Direction pairs: (side_dir, perp_dir)\n    // Axis-aligned and 45-degree\n    int udirs[4][2]={{1,0},{0,1},{1,1},{1,-1}};\n    int uperp[4][2]={{0,1},{-1,0},{1,-1},{1,1}};\n    \n    // For incremental: track all dot positions\n    // Use a priority queue approach: find all valid candidates, pick best\n    \n    struct Cand{\n        double w;\n        int p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y;\n        bool operator<(const Cand&o)const{return w<o.w;}\n    };\n    \n    auto try_rect=[&](int ax,int ay,int bx,int by,int cx,int cy,int dx,int dy, priority_queue<Cand>&pq){\n        int has[4]={(int)dot_grid[ax][ay],(int)dot_grid[bx][by],(int)dot_grid[cx][cy],(int)dot_grid[dx][dy]};\n        int cnt=has[0]+has[1]+has[2]+has[3];\n        if(cnt!=3) return;\n        \n        int pts[4][2]={{ax,ay},{bx,by},{cx,cy},{dx,dy}};\n        int ni=-1;\n        for(int i=0;i<4;i++) if(!has[i]){ni=i;break;}\n        \n        int p1x=pts[ni][0],p1y=pts[ni][1];\n        int p2x=pts[(ni+1)%4][0],p2y=pts[(ni+1)%4][1];\n        int p3x=pts[(ni+2)%4][0],p3y=pts[(ni+2)%4][1];\n        int p4x=pts[(ni+3)%4][0],p4y=pts[(ni+3)%4][1];\n        \n        if(!check_seg_interior_dots(p1x,p1y,p2x,p2y)) return;\n        if(!check_seg_interior_dots(p2x,p2y,p3x,p3y)) return;\n        if(!check_seg_interior_dots(p3x,p3y,p4x,p4y)) return;\n        if(!check_seg_interior_dots(p4x,p4y,p1x,p1y)) return;\n        \n        vector<uint64_t> segs;\n        if(!check_and_collect_segs(p1x,p1y,p2x,p2y,segs)) return;\n        if(!check_and_collect_segs(p2x,p2y,p3x,p3y,segs)) return;\n        if(!check_and_collect_segs(p3x,p3y,p4x,p4y,segs)) return;\n        if(!check_and_collect_segs(p4x,p4y,p1x,p1y,segs)) return;\n        \n        pq.push({weight(p1x,p1y),p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y});\n    };\n    \n    auto find_cands_for_dot=[&](int ax,int ay, priority_queue<Cand>&pq){\n        for(int di=0;di<4;di++){\n            int ux=udirs[di][0],uy=udirs[di][1];\n            int px=uperp[di][0],py=uperp[di][1];\n            for(int s1:{-1,1}) for(int s2:{-1,1}){\n                int sx=ux*s1, sy=uy*s1, qx=px*s2, qy=py*s2;\n                for(int l1=1;l1<N;l1++){\n                    int bx=ax+sx*l1, by=ay+sy*l1;\n                    if(!in_bounds(bx,by)) break;\n                    for(int l2=1;l2<N;l2++){\n                        int dx2=ax+qx*l2, dy2=ay+qy*l2;\n                        int cx2=bx+qx*l2, cy2=by+qy*l2;\n                        if(!in_bounds(dx2,dy2)||!in_bounds(cx2,cy2)) break;\n                        // Rectangle A-B-C-D\n                        int has=dot_grid[ax][ay]+dot_grid[bx][by]+dot_grid[cx2][cy2]+dot_grid[dx2][dy2];\n                        if(has==3) try_rect(ax,ay,bx,by,cx2,cy2,dx2,dy2,pq);\n                    }\n                }\n            }\n        }\n    };\n    \n    // Initial full scan\n    priority_queue<Cand> pq;\n    for(int x=0;x<N;x++) for(int y=0;y<N;y++){\n        if(!dot_grid[x][y]) continue;\n        find_cands_for_dot(x,y,pq);\n    }\n    \n    while(!pq.empty()){\n        if(chrono::duration<double>(chrono::steady_clock::now()-start_time).count()>4.5) break;\n        auto cd=pq.top(); pq.pop();\n        \n        if(dot_grid[cd.p1x][cd.p1y]) continue;\n        if(!dot_grid[cd.p2x][cd.p2y]||!dot_grid[cd.p3x][cd.p3y]||!dot_grid[cd.p4x][cd.p4y]) continue;\n        \n        int sides[4][4]={{cd.p1x,cd.p1y,cd.p2x,cd.p2y},{cd.p2x,cd.p2y,cd.p3x,cd.p3y},\n                         {cd.p3x,cd.p3y,cd.p4x,cd.p4y},{cd.p4x,cd.p4y,cd.p1x,cd.p1y}};\n        bool ok=true;\n        for(int i=0;i<4&&ok;i++) ok=check_seg_interior_dots(sides[i][0],sides[i][1],sides[i][2],sides[i][3]);\n        if(!ok) continue;\n        \n        vector<uint64_t> segs;\n        ok=true;\n        for(int i=0;i<4&&ok;i++) ok=check_and_collect_segs(sides[i][0],sides[i][1],sides[i][2],sides[i][3],segs);\n        if(!ok) continue;\n        \n        dot_grid[cd.p1x][cd.p1y]=true;\n        for(auto k:segs) used_segs.insert(k);\n        ops.push_back({cd.p1x,cd.p1y,cd.p2x,cd.p2y,cd.p3x,cd.p3y,cd.p4x,cd.p4y});\n        \n        // Find new candidates involving the new dot\n        find_cands_for_dot(cd.p1x,cd.p1y,pq);\n    }\n    \n    cout<<ops.size()<<\"\\n\";\n    for(auto&op:ops)\n        cout<<op.x1<<\" \"<<op.y1<<\" \"<<op.x2<<\" \"<<op.y2<<\" \"<<op.x3<<\" \"<<op.y3<<\" \"<<op.x4<<\" \"<<op.y4<<\"\\n\";\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic mt19937 rng(42);\n\nint G[10][10];\n\nvoid tilt(int g[10][10], char dir) {\n    if (dir == 'F') {\n        for(int c=0;c<10;c++){int pos=0;for(int r=0;r<10;r++)if(g[r][c]){if(pos!=r){g[pos][c]=g[r][c];g[r][c]=0;}pos++;}}\n    } else if (dir == 'B') {\n        for(int c=0;c<10;c++){int pos=9;for(int r=9;r>=0;r--)if(g[r][c]){if(pos!=r){g[pos][c]=g[r][c];g[r][c]=0;}pos--;}}\n    } else if (dir == 'L') {\n        for(int r=0;r<10;r++){int pos=0;for(int c=0;c<10;c++)if(g[r][c]){if(pos!=c){g[r][pos]=g[r][c];g[r][c]=0;}pos++;}}\n    } else {\n        for(int r=0;r<10;r++){int pos=9;for(int c=9;c>=0;c--)if(g[r][c]){if(pos!=c){g[r][pos]=g[r][c];g[r][c]=0;}pos--;}}\n    }\n}\n\nint adjacency(int g[10][10]) {\n    int s=0;\n    for(int r=0;r<10;r++) for(int c=0;c<10;c++) if(g[r][c]){\n        if(r+1<10 && g[r+1][c]==g[r][c]) s++;\n        if(c+1<10 && g[r][c+1]==g[r][c]) s++;\n    }\n    return s;\n}\n\nint connectivity(int g[10][10]) {\n    bool vis[10][10]={};\n    int score=0;\n    int dx[]={0,0,1,-1},dy[]={1,-1,0,0};\n    for(int i=0;i<10;i++) for(int j=0;j<10;j++) if(g[i][j]&&!vis[i][j]){\n        int fl=g[i][j],cnt=0;\n        queue<pair<int,int>>q;q.push({i,j});vis[i][j]=1;\n        while(!q.empty()){auto[r,c]=q.front();q.pop();cnt++;\n            for(int d=0;d<4;d++){int nr=r+dx[d],nc=c+dy[d];\n                if(nr>=0&&nr<10&&nc>=0&&nc<10&&!vis[nr][nc]&&g[nr][nc]==fl){vis[nr][nc]=1;q.push({nr,nc});}}}\n        score+=cnt*cnt;\n    }\n    return score;\n}\n\nint countEmpty(int g[10][10]) {\n    int c=0;for(int r=0;r<10;r++)for(int j=0;j<10;j++)if(!g[r][j])c++;return c;\n}\n\nvoid placeCandy(int g[10][10], int p, int flavor) {\n    int cnt=0;\n    for(int r=0;r<10;r++) for(int c=0;c<10;c++) if(!g[r][c]){\n        if(cnt==p){g[r][c]=flavor;return;}cnt++;\n    }\n}\n\nconst char dirs[]={'F','B','L','R'};\n\n// Fast rollout: random directions\nint simulate(int g[10][10], const int* flavors, int from, int total, int depth) {\n    int tmp[10][10];\n    memcpy(tmp,g,sizeof(int)*100);\n    int end = min(total, from+depth);\n    for(int t=from;t<end;t++){\n        int empty=countEmpty(tmp);\n        if(empty==0) break;\n        int p=rng()%empty;\n        placeCandy(tmp,p,flavors[t]);\n        // Use adjacency-greedy (fast)\n        int bestA=-1; char bestD='F';\n        for(int d=0;d<4;d++){\n            int tt[10][10];memcpy(tt,tmp,sizeof(int)*100);\n            tilt(tt,dirs[d]);\n            int a=adjacency(tt);\n            if(a>bestA){bestA=a;bestD=dirs[d];}\n        }\n        tilt(tmp,bestD);\n    }\n    return connectivity(tmp);\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    int f[100];for(int i=0;i<100;i++)cin>>f[i];\n    memset(G,0,sizeof(G));\n    \n    auto startTime = chrono::steady_clock::now();\n    \n    for(int t=0;t<100;t++){\n        int p;cin>>p;p--;\n        placeCandy(G,p,f[t]);\n        \n        int remaining=100-t-1;\n        int depth = min(remaining, 15);\n        \n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now-startTime).count();\n        double timeLeft = 1.9 - elapsed;\n        double timePerStep = timeLeft / max(1, 100-t);\n        \n        double bestVal=-1e18; char bestd='F';\n        \n        if(depth >= 3 && timePerStep > 0.001) {\n            // Monte Carlo with time budget\n            auto stepStart = chrono::steady_clock::now();\n            double scores[4]={};\n            int counts[4]={};\n            \n            // First do one rollout per direction\n            for(int d=0;d<4;d++){\n                int tmp[10][10];memcpy(tmp,G,sizeof(int)*100);\n                tilt(tmp,dirs[d]);\n                scores[d] += simulate(tmp,f,t+1,100,depth);\n                counts[d]++;\n            }\n            \n            // Keep rolling out until time budget spent\n            while(true){\n                auto cur = chrono::steady_clock::now();\n                double dt = chrono::duration<double>(cur-stepStart).count();\n                if(dt > timePerStep) break;\n                int d = rng()%4;\n                int tmp[10][10];memcpy(tmp,G,sizeof(int)*100);\n                tilt(tmp,dirs[d]);\n                scores[d] += simulate(tmp,f,t+1,100,depth);\n                counts[d]++;\n            }\n            \n            for(int d=0;d<4;d++){\n                double val = scores[d]/max(1,counts[d]);\n                if(val>bestVal){bestVal=val;bestd=dirs[d];}\n            }\n        } else {\n            // Pure greedy: connectivity + adjacency\n            for(int d=0;d<4;d++){\n                int tmp[10][10];memcpy(tmp,G,sizeof(int)*100);\n                tilt(tmp,dirs[d]);\n                double val = connectivity(tmp) + 0.5*adjacency(tmp);\n                if(val>bestVal){bestVal=val;bestd=dirs[d];}\n            }\n        }\n        \n        tilt(G,bestd);\n        cout<<bestd<<\"\\n\"<<flush;\n    }\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N_global;\n\nvector<double> get_features(vector<vector<int>>& adj, int N){\n    vector<int> deg(N,0);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(adj[i][j]) deg[i]++;\n    vector<int> sdeg=deg; sort(sdeg.begin(),sdeg.end());\n    \n    vector<int> tri(N,0);\n    for(int i=0;i<N;i++)\n        for(int j=0;j<N;j++) if(adj[i][j])\n            for(int k=j+1;k<N;k++) if(adj[i][k]&&adj[j][k])\n                tri[i]++;\n    vector<int> stri=tri; sort(stri.begin(),stri.end());\n    \n    vector<double> ndeg(N,0);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(adj[i][j]) ndeg[i]+=deg[j];\n    vector<double> sndeg=ndeg; sort(sndeg.begin(),sndeg.end());\n    \n    // Degree histogram\n    vector<int> dhist(N,0);\n    for(int i=0;i<N;i++) dhist[deg[i]]++;\n    \n    vector<double> feat;\n    for(int i=0;i<N;i++) feat.push_back(sdeg[i]);\n    for(int i=0;i<N;i++) feat.push_back(stri[i]*0.4);\n    for(int i=0;i<N;i++) feat.push_back(sndeg[i]*0.03);\n    for(int i=0;i<N;i++) feat.push_back(dhist[i]*1.0);\n    return feat;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M; double eps;\n    cin >> M >> eps;\n    \n    // For eps=0, we just need M non-isomorphic graphs with smallest N\n    // For eps>0, we need noise robustness\n    \n    int N;\n    if(eps < 0.001){\n        // Need N such that number of non-isomorphic graphs >= M\n        // For small M, small N suffices\n        if(M<=4) N=4;\n        else if(M<=10) N=5;\n        else if(M<=34) N=6;\n        else if(M<=100) N=7;\n        else N=8;\n    } else if(eps <= 0.05){\n        N = min(100, max(8, (int)(2.5*sqrt((double)M))+3));\n    } else if(eps <= 0.15){\n        N = min(100, max(12, (int)(3.0*sqrt((double)M))+5));\n    } else if(eps <= 0.25){\n        N = min(100, max(18, (int)(3.5*sqrt((double)M))+8));\n    } else if(eps <= 0.35){\n        N = min(100, max(25, (int)(4.0*sqrt((double)M))+10));\n    } else {\n        N = min(100, max(35, (int)(5.0*sqrt((double)M))+12));\n    }\n    N = max(N, 4);\n    N_global = N;\n    \n    int E = N*(N-1)/2;\n    mt19937 rng(42);\n    \n    auto to_str = [&](vector<vector<int>>& adj) -> string {\n        string s;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) s+=(char)('0'+adj[i][j]);\n        return s;\n    };\n    \n    // For eps=0, use canonical form based hashing to ensure non-isomorphic\n    // Generate many random graphs, compute features, keep M most separated\n    \n    vector<vector<vector<int>>> adjs(M);\n    vector<vector<double>> features(M);\n    \n    if(eps < 0.001){\n        // Generate non-isomorphic graphs\n        // Use sorted degree sequence + sorted adjacency as canonical form approximation\n        auto canonical = [&](vector<vector<int>>& adj) -> string {\n            // Try all permutations for small N, or use degree-based ordering\n            vector<int> deg(N,0);\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(adj[i][j]) deg[i]++;\n            \n            // Sort vertices by (degree, neighbor degrees, ...)\n            // Use iterative refinement\n            vector<vector<int>> labels(N);\n            for(int i=0;i<N;i++) labels[i]={deg[i]};\n            \n            for(int iter=0;iter<5;iter++){\n                vector<vector<int>> nlabels(N);\n                for(int i=0;i<N;i++){\n                    vector<vector<int>> nbr_labels;\n                    for(int j=0;j<N;j++) if(adj[i][j]) nbr_labels.push_back(labels[j]);\n                    sort(nbr_labels.begin(), nbr_labels.end());\n                    nlabels[i] = labels[i];\n                    for(auto& nl:nbr_labels){\n                        nlabels[i].push_back(-1);\n                        for(int x:nl) nlabels[i].push_back(x);\n                    }\n                }\n                labels = nlabels;\n            }\n            \n            vector<int> order(N);\n            iota(order.begin(),order.end(),0);\n            sort(order.begin(),order.end(),[&](int a,int b){return labels[a]<labels[b];});\n            \n            string can;\n            for(int i=0;i<N;i++) for(int j=i+1;j<N;j++)\n                can += (char)('0'+adj[order[i]][order[j]]);\n            return can;\n        };\n        \n        set<string> used;\n        int found=0;\n        int attempts=0;\n        while(found<M && attempts<1000000){\n            attempts++;\n            vector<vector<int>> adj(N, vector<int>(N,0));\n            // Random graph with random edge count\n            int ne = rng()%(E+1);\n            vector<pair<int,int>> all_e;\n            for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) all_e.push_back({i,j});\n            shuffle(all_e.begin(),all_e.end(),rng);\n            for(int e=0;e<ne;e++){adj[all_e[e].first][all_e[e].second]=1;adj[all_e[e].second][all_e[e].first]=1;}\n            \n            string c = canonical(adj);\n            if(!used.count(c)){\n                used.insert(c);\n                adjs[found]=adj;\n                features[found]=get_features(adj,N);\n                found++;\n            }\n        }\n        // If not enough, increase N and retry (shouldn't happen with our N choices)\n    } else {\n        // Generate M well-separated graphs\n        int trials = max(30, min(200, 3000/M));\n        \n        for(int k=0;k<M;k++){\n            double density = (k+0.5)/M;\n            int target = max(0, min(E, (int)round(density*E)));\n            \n            vector<vector<int>> best_adj;\n            vector<double> best_feat;\n            double best_min_dist = -1;\n            \n            for(int t=0;t<trials;t++){\n                vector<vector<int>> adj(N,vector<int>(N,0));\n                vector<pair<int,int>> all_e;\n                for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) all_e.push_back({i,j});\n                shuffle(all_e.begin(),all_e.end(),rng);\n                for(int e=0;e<target;e++){adj[all_e[e].first][all_e[e].second]=1;adj[all_e[e].second][all_e[e].first]=1;}\n                auto feat=get_features(adj,N);\n                \n                double min_dist=1e18;\n                for(int j=0;j<k;j++){\n                    double d=0;\n                    for(size_t f=0;f<feat.size();f++){double diff=feat[f]-features[j][f];d+=diff*diff;}\n                    min_dist=min(min_dist,d);\n                }\n                if(min_dist>best_min_dist){best_min_dist=min_dist;best_adj=adj;best_feat=feat;}\n            }\n            adjs[k]=best_adj;\n            features[k]=best_feat;\n        }\n    }\n    \n    cout<<N<<\"\\n\";\n    for(int k=0;k<M;k++) cout<<to_str(adjs[k])<<\"\\n\";\n    cout.flush();\n    \n    for(int q=0;q<100;q++){\n        string h; cin>>h;\n        vector<vector<int>> hadj(N,vector<int>(N,0));\n        int idx=0;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){hadj[i][j]=hadj[j][i]=h[idx++]-'0';}\n        auto hfeat=get_features(hadj,N);\n        int best=-1;double bestd=1e18;\n        for(int k=0;k<M;k++){\n            double d=0;\n            for(size_t f=0;f<hfeat.size();f++){double diff=hfeat[f]-features[k][f];d+=diff*diff;}\n            if(d<bestd){bestd=d;best=k;}\n        }\n        cout<<best<<\"\\n\";\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N,M,D,K;\nint eu[3001],ev[3001],ew[3001];\nvector<pair<int,int>> adj[1001];\nint nSample;\nint samples[1001];\nlong long origDist[50][1001];\nlong long tmpDist[1001];\nbool removed[3001];\n\nvoid dijkstra(int src, long long* dist){\n    for(int i=0;i<N;i++) dist[i]=1e18;\n    dist[src]=0;\n    // Use bucket queue / priority queue\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 [d,u]=pq.top(); pq.pop();\n        if(d>dist[u]) continue;\n        for(auto& [v,ei]:adj[u]){\n            if(removed[ei]) continue;\n            long long nd=d+ew[ei];\n            if(nd<dist[v]){\n                dist[v]=nd;\n                pq.push({nd,v});\n            }\n        }\n    }\n}\n\ndouble evalDayInline(const vector<int>& edges_on_day){\n    for(int e : edges_on_day) removed[e] = true;\n    double total = 0;\n    for(int si=0; si<nSample; si++){\n        dijkstra(samples[si], tmpDist);\n        for(int j=0; j<N; j++){\n            long long dd = (tmpDist[j] >= (long long)1e18) ? (long long)1e9 : tmpDist[j];\n            total += (double)(dd - origDist[si][j]);\n        }\n    }\n    for(int e : edges_on_day) removed[e] = false;\n    return total;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin>>N>>M>>D>>K;\n    for(int i=0;i<M;i++){\n        cin>>eu[i]>>ev[i]>>ew[i];\n        eu[i]--; ev[i]--;\n        adj[eu[i]].push_back({ev[i],i});\n        adj[ev[i]].push_back({eu[i],i});\n    }\n    {int x,y; for(int i=0;i<N;i++) cin>>x>>y;}\n    \n    mt19937 rng(42);\n    nSample = min(N, 15);\n    {\n        vector<int> tmp(N);\n        iota(tmp.begin(),tmp.end(),0);\n        shuffle(tmp.begin(),tmp.end(),rng);\n        for(int i=0;i<nSample;i++) samples[i]=tmp[i];\n    }\n    \n    memset(removed,0,sizeof(removed));\n    for(int i=0;i<nSample;i++) dijkstra(samples[i], origDist[i]);\n    \n    // Edge importance\n    vector<double> importance(M, 0);\n    for(int si=0;si<nSample;si++){\n        vector<int> idx(N); iota(idx.begin(),idx.end(),0);\n        sort(idx.begin(),idx.end(),[&](int a,int b){return origDist[si][a]<origDist[si][b];});\n        vector<double> sub(N, 1.0);\n        for(int i=N-1;i>=0;i--){\n            int v=idx[i];\n            if(v==samples[si]) continue;\n            for(auto& [u,ei]:adj[v]){\n                if(origDist[si][u]+ew[ei]==origDist[si][v]){\n                    sub[u]+=sub[v];\n                    importance[ei]+=sub[v];\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Initial: spread important edges round-robin\n    vector<int> order(M);\n    iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),[&](int a,int b){return importance[a]>importance[b];});\n    \n    vector<int> asgn(M);\n    vector<vector<int>> dayEdges(D);\n    for(int i=0;i<M;i++){\n        int day=i%D;\n        asgn[order[i]]=day;\n        dayEdges[day].push_back(order[i]);\n    }\n    \n    vector<double> dayScore(D);\n    double totalScore=0;\n    for(int d=0;d<D;d++){\n        dayScore[d]=evalDayInline(dayEdges[d]);\n        totalScore+=dayScore[d];\n    }\n    \n    double bestTotal=totalScore;\n    vector<int> bestAsgn=asgn;\n    \n    auto startTime=chrono::steady_clock::now();\n    double timeLimit=5.3;\n    \n    auto getTime=[&](){\n        return chrono::duration<double>(chrono::steady_clock::now()-startTime).count();\n    };\n    \n    // Pre-compute max day for targeting\n    auto worstDay=[&]()->int{\n        return max_element(dayScore.begin(),dayScore.end())-dayScore.begin();\n    };\n    \n    int iter=0;\n    while(true){\n        double t=getTime();\n        if(t>timeLimit) break;\n        double progress=t/timeLimit;\n        double startTemp=bestTotal/(D*10.0);\n        double endTemp=bestTotal/(D*10000.0);\n        double curTemp=startTemp*pow(endTemp/max(startTemp,1.0),progress);\n        \n        // 50% target worst day, 50% random\n        int moveType=rng()%4;\n        \n        if(moveType<3){\n            // Swap two edges between two days\n            int d1,d2;\n            if(moveType==0){\n                d1=worstDay();\n                d2=rng()%D;\n            } else {\n                d1=rng()%D;\n                d2=rng()%D;\n            }\n            if(d1==d2||dayEdges[d1].empty()||dayEdges[d2].empty()) continue;\n            int i1=rng()%dayEdges[d1].size();\n            int i2=rng()%dayEdges[d2].size();\n            int e1=dayEdges[d1][i1], e2=dayEdges[d2][i2];\n            \n            dayEdges[d1][i1]=e2;\n            dayEdges[d2][i2]=e1;\n            \n            double ns1=evalDayInline(dayEdges[d1]);\n            double ns2=evalDayInline(dayEdges[d2]);\n            double delta=(ns1+ns2)-(dayScore[d1]+dayScore[d2]);\n            \n            if(delta<0||exp(-delta/curTemp)>(rng()%1000000)/1000000.0){\n                asgn[e1]=d2; asgn[e2]=d1;\n                dayScore[d1]=ns1; dayScore[d2]=ns2;\n                totalScore+=delta;\n                if(totalScore<bestTotal){bestTotal=totalScore;bestAsgn=asgn;}\n            } else {\n                dayEdges[d1][i1]=e1; dayEdges[d2][i2]=e2;\n            }\n        } else {\n            // Move edge\n            int e=rng()%M;\n            int od=asgn[e], nd=rng()%D;\n            if(od==nd||(int)dayEdges[nd].size()>=K) continue;\n            auto& ov=dayEdges[od];\n            int pos=find(ov.begin(),ov.end(),e)-ov.begin();\n            ov[pos]=ov.back(); ov.pop_back();\n            dayEdges[nd].push_back(e);\n            double ns1=evalDayInline(ov);\n            double ns2=evalDayInline(dayEdges[nd]);\n            double delta=(ns1+ns2)-(dayScore[od]+dayScore[nd]);\n            if(delta<0||exp(-delta/curTemp)>(rng()%1000000)/1000000.0){\n                asgn[e]=nd; dayScore[od]=ns1; dayScore[nd]=ns2; totalScore+=delta;\n                if(totalScore<bestTotal){bestTotal=totalScore;bestAsgn=asgn;}\n            } else {\n                dayEdges[nd].pop_back(); ov.push_back(e);\n            }\n        }\n        iter++;\n    }\n    \n    for(int i=0;i<M;i++){\n        cout<<bestAsgn[i]+1;\n        if(i<M-1) cout<<' ';\n    }\n    cout<<'\\n';\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\nint main(){\n    int D;\n    scanf(\"%d\",&D);\n    vector<string> f1(D),r1(D),f2(D),r2(D);\n    for(int i=0;i<D;i++) cin>>f1[i];\n    for(int i=0;i<D;i++) cin>>r1[i];\n    for(int i=0;i<D;i++) cin>>f2[i];\n    for(int i=0;i<D;i++) cin>>r2[i];\n    \n    vector<int> b1(D*D*D,0), b2(D*D*D,0);\n    vector<int> cells1, cells2;\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++){\n        if(f1[z][x]=='1' && r1[z][y]=='1') cells1.push_back(x*D*D+y*D+z);\n    }\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++){\n        if(f2[z][x]=='1' && r2[z][y]=='1') cells2.push_back(x*D*D+y*D+z);\n    }\n    \n    int M1=cells1.size(), M2=cells2.size();\n    int shared=min(M1,M2);\n    int n=0;\n    \n    // First 'shared' blocks are shared unit blocks (used in both configs)\n    for(int i=0;i<shared;i++){\n        n++;\n        b1[cells1[i]]=n;\n        b2[cells2[i]]=n;\n    }\n    // Remaining cells in the larger config get their own unit blocks\n    if(M1>M2){\n        for(int i=shared;i<M1;i++){\n            n++;\n            b1[cells1[i]]=n;\n        }\n    } else {\n        for(int i=shared;i<M2;i++){\n            n++;\n            b2[cells2[i]]=n;\n        }\n    }\n    \n    printf(\"%d\\n\",n);\n    for(int i=0;i<D*D*D;i++) printf(\"%d%c\",b1[i],\" \\n\"[i==D*D*D-1]);\n    for(int i=0;i<D*D*D;i++) printf(\"%d%c\",b2[i],\" \\n\"[i==D*D*D-1]);\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint N,M,K;\nvector<ll> vx,vy;\nvector<int> eu_,ev_;\nvector<ll> ew_;\nvector<ll> ra,rb;\nvector<vector<pair<int,int>>> adj;\nvector<vector<ll>> spd;\nvector<vector<int>> spp;\nvector<vector<int>> cands; // cands[k] = vertices that can cover resident k\nvector<vector<int>> rdist_c; // rdist_c[k][i] = ceil dist from resident k to vertex i\n\nmt19937 rng(42);\n\nvoid dijkstra(int s){\n    priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<>> pq;\n    spd[s][s]=0;\n    pq.push({0,s});\n    while(!pq.empty()){\n        auto [d,u]=pq.top();pq.pop();\n        if(d>spd[s][u]) continue;\n        for(auto&[v,eid]:adj[u]){\n            ll nd=d+ew_[eid];\n            if(nd<spd[s][v]){\n                spd[s][v]=nd;\n                spp[s][v]=eid;\n                pq.push({nd,v});\n            }\n        }\n    }\n}\n\nvector<bool> get_tree_verts(vector<bool>& edgeUsed){\n    vector<bool> vis(N,false);\n    queue<int> q;\n    q.push(0);vis[0]=true;\n    while(!q.empty()){\n        int u=q.front();q.pop();\n        for(auto&[v,eid]:adj[u])\n            if(edgeUsed[eid]&&!vis[v]){vis[v]=true;q.push(v);}\n    }\n    return vis;\n}\n\n// Build Steiner tree connecting active vertices through 0\n// Returns (cost, edgeUsed)\npair<ll,vector<bool>> build_steiner(vector<bool>& active){\n    vector<bool> inTree(N,false);\n    vector<bool> edgeUsed(M,false);\n    ll treeCost=0;\n    inTree[0]=true;\n    \n    // Collect targets\n    vector<int> targets;\n    for(int i=0;i<N;i++) if(active[i]&&i!=0) targets.push_back(i);\n    \n    // Precompute min dist from each target to tree\n    int nt=targets.size();\n    vector<ll> minDist(nt);\n    vector<int> minSrc(nt);\n    for(int t=0;t<nt;t++){\n        minDist[t]=spd[0][targets[t]];\n        minSrc[t]=0;\n    }\n    \n    vector<bool> added(nt,false);\n    \n    for(int step=0;step<nt;step++){\n        // Find nearest target\n        int bestIdx=-1; ll bestD=1e18;\n        for(int t=0;t<nt;t++){\n            if(!added[t]&&minDist[t]<bestD){\n                bestD=minDist[t];\n                bestIdx=t;\n            }\n        }\n        added[bestIdx]=true;\n        int tgt=targets[bestIdx];\n        int src=minSrc[bestIdx];\n        \n        // Trace path from src to tgt\n        vector<int> pathNodes;\n        int cur=tgt;\n        while(cur!=src){\n            int eid=spp[src][cur];\n            if(!edgeUsed[eid]){\n                edgeUsed[eid]=true;\n                treeCost+=ew_[eid];\n            }\n            int u=eu_[eid],v=ev_[eid];\n            int nxt=(u==cur)?v:u;\n            if(!inTree[cur]) pathNodes.push_back(cur);\n            inTree[cur]=true;\n            cur=nxt;\n        }\n        inTree[tgt]=true;\n        \n        // Update minDist for remaining targets\n        // New tree nodes added: pathNodes + tgt\n        pathNodes.push_back(tgt);\n        for(int t=0;t<nt;t++){\n            if(added[t]) continue;\n            for(int nn:pathNodes){\n                if(spd[nn][targets[t]]<minDist[t]){\n                    minDist[t]=spd[nn][targets[t]];\n                    minSrc[t]=nn;\n                }\n            }\n        }\n    }\n    return {treeCost,edgeUsed};\n}\n\nstruct Solution {\n    vector<int> P;\n    vector<bool> edgeUsed;\n    vector<bool> inTree;\n    vector<int> assign; // assign[k] = vertex covering resident k\n    ll edgeCost;\n    ll pCost;\n    ll totalCost;\n    \n    void recompute_P(){\n        fill(P.begin(),P.end(),0);\n        for(int k=0;k<K;k++){\n            int i=assign[k];\n            P[i]=max(P[i],rdist_c[k][i]);\n        }\n    }\n    \n    void recompute_costs(){\n        pCost=0;\n        for(int i=0;i<N;i++) pCost+=(ll)P[i]*P[i];\n        edgeCost=0;\n        for(int j=0;j<M;j++) if(edgeUsed[j]) edgeCost+=ew_[j];\n        totalCost=pCost+edgeCost;\n    }\n    \n    // Assign residents optimally to inTree vertices\n    void optimize_assignment(){\n        // Sort residents by difficulty (fewest candidates first)\n        vector<int> order(K);\n        iota(order.begin(),order.end(),0);\n        // Multiple passes\n        for(int pass=0;pass<20;pass++){\n            if(pass>0) shuffle(order.begin(),order.end(),rng);\n            \n            fill(P.begin(),P.end(),0);\n            for(int k:order){\n                int bestV=-1; ll bestMarg=1e18;\n                for(int i:cands[k]){\n                    if(!inTree[i]) continue;\n                    int r=rdist_c[k][i];\n                    int newP=max(P[i],r);\n                    ll marg=(ll)newP*newP-(ll)P[i]*P[i];\n                    if(marg<bestMarg){\n                        bestMarg=marg;\n                        bestV=i;\n                    }\n                }\n                assign[k]=bestV;\n                P[bestV]=max(P[bestV],rdist_c[k][bestV]);\n            }\n        }\n        recompute_costs();\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin>>N>>M>>K;\n    vx.resize(N);vy.resize(N);\n    for(int i=0;i<N;i++) cin>>vx[i]>>vy[i];\n    eu_.resize(M);ev_.resize(M);ew_.resize(M);\n    for(int j=0;j<M;j++){cin>>eu_[j]>>ev_[j]>>ew_[j];eu_[j]--;ev_[j]--;}\n    ra.resize(K);rb.resize(K);\n    for(int k=0;k<K;k++) cin>>ra[k]>>rb[k];\n    \n    adj.resize(N);\n    for(int j=0;j<M;j++){\n        adj[eu_[j]].push_back({ev_[j],j});\n        adj[ev_[j]].push_back({eu_[j],j});\n    }\n    \n    spd.assign(N,vector<ll>(N,1e18));\n    spp.assign(N,vector<int>(N,-1));\n    for(int s=0;s<N;s++) dijkstra(s);\n    \n    cands.resize(K);\n    rdist_c.assign(K,vector<int>(N,10000));\n    for(int k=0;k<K;k++){\n        for(int i=0;i<N;i++){\n            double dx=vx[i]-ra[k],dy=vy[i]-rb[k];\n            double d=sqrt(dx*dx+dy*dy);\n            int r=(int)ceil(d-1e-9);\n            rdist_c[k][i]=r;\n            if(r<=5000) cands[k].push_back(i);\n        }\n    }\n    \n    // Initial solution: assign to nearest, build tree, reassign\n    Solution best;\n    best.P.resize(N,0);\n    best.assign.resize(K);\n    best.edgeUsed.resize(M,false);\n    best.inTree.resize(N,false);\n    \n    auto run_solution = [&](vector<bool>& initActive) -> Solution {\n        Solution sol;\n        sol.P.resize(N,0);\n        sol.assign.resize(K,-1);\n        \n        auto [tc,eu2]=build_steiner(initActive);\n        sol.edgeUsed=eu2;\n        sol.edgeCost=tc;\n        sol.inTree=get_tree_verts(sol.edgeUsed);\n        sol.optimize_assignment();\n        \n        // Rebuild with only needed vertices\n        for(int rep=0;rep<3;rep++){\n            vector<bool> act(N,false);\n            act[0]=true;\n            for(int i=0;i<N;i++) if(sol.P[i]>0) act[i]=true;\n            auto [tc2,eu3]=build_steiner(act);\n            sol.edgeUsed=eu3;\n            sol.edgeCost=tc2;\n            sol.inTree=get_tree_verts(sol.edgeUsed);\n            sol.optimize_assignment();\n        }\n        return sol;\n    };\n    \n    // Strategy 1: nearest vertex assignment\n    {\n        vector<bool> active(N,false);\n        active[0]=true;\n        vector<int> tmpP(N,0);\n        for(int k=0;k<K;k++){\n            int best=-1;int bestR=10000;\n            for(int i:cands[k]) if(rdist_c[k][i]<bestR){bestR=rdist_c[k][i];best=i;}\n            tmpP[best]=max(tmpP[best],bestR);\n        }\n        for(int i=0;i<N;i++) if(tmpP[i]>0) active[i]=true;\n        Solution sol=run_solution(active);\n        if(sol.totalCost<best.totalCost||best.totalCost==0) best=sol;\n    }\n    \n    // Strategy 2: all vertices active\n    {\n        vector<bool> active(N,true);\n        Solution sol=run_solution(active);\n        if(sol.totalCost<best.totalCost) best=sol;\n    }\n    \n    // Local search: try adding/removing vertices\n    auto start_time=chrono::steady_clock::now();\n    \n    Solution cur=best;\n    for(int iter=0;;iter++){\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-start_time).count();\n        if(elapsed>1.8) break;\n        \n        double temp=1e7*(1.0-elapsed/1.8)+1e4;\n        \n        // Random perturbation\n        int action=rng()%3;\n        Solution next=cur;\n        \n        if(action==0){\n            // Toggle a random vertex\n            int v=rng()%N;\n            if(v==0) continue;\n            vector<bool> act(N,false);\n            act[0]=true;\n            for(int i=0;i<N;i++) if(cur.P[i]>0&&i!=v) act[i]=true;\n            if(!act[v]){\n                // Try adding v\n                act[v]=true;\n            }\n            next=run_solution(act);\n        } else if(action==1){\n            // Try a random subset: remove random active vertex\n            int v=-1;\n            vector<int> actives;\n            for(int i=1;i<N;i++) if(cur.P[i]>0) actives.push_back(i);\n            if(actives.empty()) continue;\n            v=actives[rng()%actives.size()];\n            \n            vector<bool> act(N,false);\n            act[0]=true;\n            for(int i:actives) if(i!=v) act[i]=true;\n            // Check if all residents can be covered\n            bool ok=true;\n            for(int k=0;k<K;k++){\n                bool covered=false;\n                for(int i:cands[k]) if(act[i]||i==0){covered=true;break;}\n                // Actually need to be in tree, just try\n            }\n            if(!ok) continue;\n            next=run_solution(act);\n        } else {\n            // Add a random non-active vertex\n            vector<int> inactives;\n            for(int i=1;i<N;i++) if(cur.P[i]==0) inactives.push_back(i);\n            if(inactives.empty()) continue;\n            int v=inactives[rng()%inactives.size()];\n            vector<bool> act(N,false);\n            act[0]=true;\n            for(int i=0;i<N;i++) if(cur.P[i]>0) act[i]=true;\n            act[v]=true;\n            next=run_solution(act);\n        }\n        \n        ll delta=next.totalCost-cur.totalCost;\n        if(delta<0||(temp>0&&exp(-delta/temp)>((double)(rng()%10000)/10000.0))){\n            cur=next;\n            if(cur.totalCost<best.totalCost) best=cur;\n        }\n    }\n    \n    // Output\n    for(int i=0;i<N;i++) cout<<best.P[i]<<\" \\n\"[i==N-1];\n    for(int j=0;j<M;j++) cout<<(best.edgeUsed[j]?1:0)<<\" \\n\"[j==M-1];\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N=30;\nint grid[30][30];\nvector<tuple<int,int,int,int>> ops;\n\nvoid do_swap(int x1,int y1,int x2,int y2){\n    ops.push_back({x1,y1,x2,y2});\n    swap(grid[x1][y1],grid[x2][y2]);\n}\n\nvoid sift_down(int x, int y){\n    while(x < N-1 && (int)ops.size() < 9900){\n        int cur = grid[x][y];\n        int c1 = grid[x+1][y], c2 = grid[x+1][y+1];\n        if(cur <= c1 && cur <= c2) break;\n        if(c1 <= c2){\n            do_swap(x,y,x+1,y);\n            x = x+1;\n        } else {\n            do_swap(x,y,x+1,y+1);\n            x = x+1; y = y+1;\n        }\n    }\n}\n\nvoid sift_up(int x, int y){\n    while(x > 0 && (int)ops.size() < 9900){\n        int cur = grid[x][y];\n        int best_px=-1, best_py=-1, best_pv=cur;\n        if(y > 0 && grid[x-1][y-1] > best_pv){ best_px=x-1; best_py=y-1; best_pv=grid[x-1][y-1]; }\n        if(y < x && grid[x-1][y] > best_pv){ best_px=x-1; best_py=y; best_pv=grid[x-1][y]; }\n        if(best_px == -1) break;\n        do_swap(x,y,best_px,best_py);\n        x = best_px; y = best_py;\n    }\n}\n\nint main(){\n    for(int x=0;x<N;x++) for(int y=0;y<=x;y++) scanf(\"%d\",&grid[x][y]);\n    \n    // Bottom-up heapify: sift down each node from tier N-2 to 0\n    for(int x=N-2; x>=0; x--)\n        for(int y=x; y>=0; y--)\n            sift_down(x, y);\n    \n    // Fix remaining violations with targeted passes\n    for(int iter=0; iter<20 && (int)ops.size()<9900; iter++){\n        bool changed = false;\n        // Sift up pass (bottom to top)\n        for(int x=N-1; x>=1 && (int)ops.size()<9900; x--)\n            for(int y=x; y>=0 && (int)ops.size()<9900; y--){\n                int prev = (int)ops.size();\n                sift_up(x, y);\n                if((int)ops.size() > prev) changed = true;\n            }\n        // Sift down pass (top to bottom)\n        for(int x=0; x<N-1 && (int)ops.size()<9900; x++)\n            for(int y=0; y<=x && (int)ops.size()<9900; y++){\n                int prev = (int)ops.size();\n                sift_down(x, y);\n                if((int)ops.size() > prev) changed = true;\n            }\n        if(!changed) break;\n    }\n    \n    printf(\"%d\\n\",(int)ops.size());\n    for(auto&[a,b,c,d]:ops) printf(\"%d %d %d %d\\n\",a,b,c,d);\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nint grid[9][9]; // -2=obstacle, -1=empty, >=0 container number\nint dx[]={-1,1,0,0}, dy[]={0,0,-1,1};\nint ei,ej;\n\nbool reachable(int si,int sj,int ti,int tj){\n    bool vis[9][9]={};\n    queue<pair<int,int>> q;\n    q.push({si,sj}); vis[si][sj]=1;\n    while(!q.empty()){\n        auto [x,y]=q.front();q.pop();\n        if(x==ti&&y==tj) return true;\n        for(int d=0;d<4;d++){\n            int nx=x+dx[d],ny=y+dy[d];\n            if(nx<0||nx>=D||ny<0||ny>=D) continue;\n            if(vis[nx][ny]||grid[nx][ny]==-2) continue;\n            if(!(nx==ti&&ny==tj) && grid[nx][ny]>=0) continue;\n            vis[nx][ny]=1; q.push({nx,ny});\n        }\n    }\n    return false;\n}\n\nvector<pair<int,int>> reachable_containers(){\n    bool vis[9][9]={};\n    queue<pair<int,int>> q;\n    q.push({ei,ej}); vis[ei][ej]=1;\n    vector<pair<int,int>> res;\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>=D||ny<0||ny>=D||vis[nx][ny]||grid[nx][ny]==-2) continue;\n            vis[nx][ny]=1;\n            if(grid[nx][ny]>=0) res.push_back({nx,ny});\n            else q.push({nx,ny});\n        }\n    }\n    return res;\n}\n\nint main(){\n    int N; scanf(\"%d%d\",&D,&N);\n    ei=0; ej=(D-1)/2;\n    memset(grid,-1,sizeof(grid));\n    for(int i=0;i<N;i++){int r,c;scanf(\"%d%d\",&r,&c);grid[r][c]=-2;}\n    \n    vector<pair<int,pair<int,int>>> cells;\n    for(int i=0;i<D;i++) for(int j=0;j<D;j++){\n        if(grid[i][j]==-2||(i==ei&&j==ej)) continue;\n        int dist=abs(i-ei)+abs(j-ej);\n        cells.push_back({dist,{i,j}});\n    }\n    sort(cells.begin(),cells.end());\n    int M=D*D-1-N;\n    vector<pair<int,int>> target(M);\n    for(int t=0;t<M;t++) target[t]=cells[t].second;\n    \n    for(int d=0;d<M;d++){\n        int t; scanf(\"%d\",&t);\n        auto [ti,tj]=target[t];\n        if(grid[ti][tj]==-1 && reachable(ei,ej,ti,tj)){\n            grid[ti][tj]=t; printf(\"%d %d\\n\",ti,tj); fflush(stdout);\n        } else {\n            // find nearest reachable empty cell to target\n            int best=-1; double bd=1e9; pair<int,int> bp;\n            for(auto&c:cells){\n                auto [ci,cj]=c.second;\n                if(grid[ci][cj]!=-1) continue;\n                if(!reachable(ei,ej,ci,cj)) continue;\n                double dd=abs(ci-ti)+abs(cj-tj);\n                if(dd<bd){bd=dd;bp={ci,cj};best=1;}\n            }\n            grid[bp.first][bp.second]=t;\n            printf(\"%d %d\\n\",bp.first,bp.second); fflush(stdout);\n        }\n    }\n    for(int i=0;i<M;i++){\n        auto rc=reachable_containers();\n        int best=-1; pair<int,int> bp;\n        for(auto [r,c]:rc) if(best<0||grid[r][c]<best){best=grid[r][c];bp={r,c};}\n        printf(\"%d %d\\n\",bp.first,bp.second);\n        grid[bp.first][bp.second]=-1;\n    }\n    fflush(stdout);\n}","ahc024":"#include<bits/stdc++.h>\nusing namespace std;\nint N,M;\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\n\nvector<vector<int>> grid;\n\nbool is_connected(int color){\n    // Find all cells of this color\n    vector<pair<int,int>> cells;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++)\n        if(grid[i][j]==color) cells.push_back({i,j});\n    if(cells.empty()) return true;\n    if(color==0){\n        // color 0 connects through outside\n        // BFS including virtual outside node\n        set<pair<int,int>> cset(cells.begin(),cells.end());\n        set<pair<int,int>> visited;\n        queue<pair<int,int>> q;\n        // start from any boundary 0-cell or if none, check connectivity through outside\n        // Actually all boundary cells connect to outside, and outside connects them\n        // So color-0 is connected if every interior 0-cell can reach a boundary 0-cell or boundary\n        // Simpler: add a virtual node connected to all boundary cells\n        // BFS from virtual node through 0-cells\n        visited.clear();\n        // Start: all boundary 0-cells and all 0-cells adjacent to boundary\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            if(grid[i][j]==0 && (i==0||i==N-1||j==0||j==N-1)){\n                if(!visited.count({i,j})){\n                    visited.insert({i,j});\n                    q.push({i,j});\n                }\n            }\n        }\n        // Also any cell adjacent to outside (boundary) that is 0\n        // already covered above\n        // If no boundary 0-cells exist but there are 0-cells, they must connect to boundary through adjacency to boundary (outside)\n        // Actually outside is one big connected region. Any 0-cell on boundary connects to outside.\n        // Interior 0-cells need path to boundary through other 0-cells.\n        if(q.empty() && !cells.empty()){\n            // no boundary 0-cells, check if all 0-cells are interior - they can't connect to outside\n            return false;\n        }\n        while(!q.empty()){\n            auto [ci,cj]=q.front(); q.pop();\n            for(int d=0;d<4;d++){\n                int ni=ci+dx[d],nj=cj+dy[d];\n                if(ni<0||ni>=N||nj<0||nj>=N) continue;\n                if(grid[ni][nj]==0 && !visited.count({ni,nj})){\n                    visited.insert({ni,nj});\n                    q.push({ni,nj});\n                }\n            }\n        }\n        return (int)visited.size()==(int)cells.size();\n    }\n    // Normal color\n    if(cells.size()<=1) return true;\n    set<pair<int,int>> cset(cells.begin(),cells.end());\n    set<pair<int,int>> visited;\n    queue<pair<int,int>> q;\n    q.push(cells[0]);\n    visited.insert(cells[0]);\n    while(!q.empty()){\n        auto [ci,cj]=q.front(); q.pop();\n        for(int d=0;d<4;d++){\n            int ni=ci+dx[d],nj=cj+dy[d];\n            if(ni<0||ni>=N||nj<0||nj>=N) continue;\n            if(grid[ni][nj]==color && !visited.count({ni,nj})){\n                visited.insert({ni,nj});\n                q.push({ni,nj});\n            }\n        }\n    }\n    return (int)visited.size()==(int)cells.size();\n}\n\nset<pair<int,int>> get_adj_set(){\n    set<pair<int,int>> s;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        if(i==0||i==N-1||j==0||j==N-1){\n            if(grid[i][j]!=0){\n                int a=min(0,grid[i][j]),b=max(0,grid[i][j]);\n                s.insert({a,b});\n            }\n        }\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) continue;\n            if(grid[i][j]!=grid[ni][nj]){\n                int a=min(grid[i][j],grid[ni][nj]),b=max(grid[i][j],grid[ni][nj]);\n                s.insert({a,b});\n            }\n        }\n    }\n    return s;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \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    // Extract target adjacency\n    set<pair<int,int>> target_adj = get_adj_set();\n    // Note: in original map there are no 0-cells, so adj with 0 = boundary colors\n    \n    auto best_grid = grid;\n    int best_zeros = 0;\n    \n    // Greedy: try to convert cells to 0, check validity\n    // Shuffle order, repeat\n    mt19937 rng(42);\n    \n    auto start = chrono::steady_clock::now();\n    \n    vector<pair<int,int>> order;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) order.push_back({i,j});\n    \n    for(int iter=0;;iter++){\n        auto now = chrono::steady_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-start).count()>1800) break;\n        \n        grid = best_grid; // start fresh each iteration? Or from current best\n        if(iter>0) shuffle(order.begin(),order.end(),rng);\n        \n        for(auto&[i,j]:order){\n            if(grid[i][j]==0) continue;\n            int old_color = grid[i][j];\n            \n            // Check: does this color have more than 1 cell?\n            // Quick check neighbors for adjacency preservation\n            grid[i][j]=0;\n            \n            // Check adjacency: old_color's adjacencies must still hold\n            // Check connectivity of old_color\n            // Check no new adjacencies created\n            // Check color 0 connectivity\n            \n            // Fast check: would removing this cell disconnect old_color?\n            // Count cells of old_color\n            // Also check adjacency changes\n            \n            bool ok = true;\n            \n            // Check: old_color still exists?\n            bool exists = false;\n            for(int ii=max(0,i-25);ii<min(N,i+25)&&!exists;ii++)\n                for(int jj=0;jj<N&&!exists;jj++)\n                    if(grid[ii][jj]==old_color) exists=true;\n            if(!exists){ grid[i][j]=old_color; continue; }\n            \n            // Check connectivity of old_color (articulation point check)\n            if(!is_connected(old_color)){ ok=false; }\n            \n            if(ok){\n                // Check no new adjacencies: neighbors of (i,j) that are non-zero and non-old_color\n                // now become adjacent to 0\n                // Was old_color adjacent to 0 before? Check target\n                // New adj: 0 <-> neighbor colors, and also 0 <-> colors adjacent to this cell\n                // We need: the new adjacency set == target\n                // Quick: check local changes\n                set<int> new_neighbors;\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) continue;\n                    if(grid[ni][nj]!=0) new_neighbors.insert(grid[ni][nj]);\n                }\n                // boundary\n                if(i==0||i==N-1||j==0||j==N-1){\n                    // 0-cell on boundary is fine (connects to outside)\n                }\n                \n                // Check: for each new neighbor color c, is (0,c) in target?\n                for(int nc : new_neighbors){\n                    int a=min(0,nc),b=max(0,nc);\n                    if(!target_adj.count({a,b})){ ok=false; break; }\n                }\n                \n                // Check: did we lose any required adjacency of old_color?\n                // old_color was adjacent to some colors through this cell\n                // Need to verify those adjacencies still exist elsewhere\n                if(ok){\n                    // Check all required adjacencies of old_color still present\n                    set<int> required_adj_of_old;\n                    for(auto&[a,b]:target_adj){\n                        if(a==old_color) required_adj_of_old.insert(b);\n                        if(b==old_color) required_adj_of_old.insert(a);\n                    }\n                    // Find current adjacencies of old_color\n                    set<int> current_adj_of_old;\n                    for(int ii=0;ii<N;ii++) for(int jj=0;jj<N;jj++){\n                        if(grid[ii][jj]!=old_color) continue;\n                        if(ii==0||ii==N-1||jj==0||jj==N-1) current_adj_of_old.insert(0);\n                        for(int d=0;d<4;d++){\n                            int ni2=ii+dx[d],nj2=jj+dy[d];\n                            if(ni2<0||ni2>=N||nj2<0||nj2>=N) continue;\n                            if(grid[ni2][nj2]!=old_color) current_adj_of_old.insert(grid[ni2][nj2]);\n                        }\n                    }\n                    for(int r:required_adj_of_old){\n                        if(!current_adj_of_old.count(r)){ ok=false; break; }\n                    }\n                }\n                \n                // Check color 0 connectivity\n                if(ok && !is_connected(0)) ok=false;\n            }\n            \n            if(!ok) grid[i][j]=old_color;\n        }\n        \n        int zeros=0;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(grid[i][j]==0) zeros++;\n        if(zeros>best_zeros){\n            best_zeros=zeros;\n            best_grid=grid;\n        }\n    }\n    \n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++){\n            cout<<best_grid[i][j];\n            if(j<N-1) cout<<' ';\n        }\n        cout<<'\\n';\n    }\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\nchar query(vector<int>& L, vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << \"\\n\" << flush;\n    queries_used++;\n    char c; cin >> c;\n    return c;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\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> left(v.begin(), v.begin()+mid), right(v.begin()+mid, v.end());\n        left = msort(left); right = msort(right);\n        vector<int> res;\n        int i=0,j=0;\n        while(i<(int)left.size()&&j<(int)right.size()){\n            if(queries_used>=Q){res.push_back(left[i++]);continue;}\n            vector<int> L={left[i]}, R={right[j]};\n            char c=query(L,R);\n            if(c=='<'||c=='=') res.push_back(left[i++]);\n            else res.push_back(right[j++]);\n        }\n        while(i<(int)left.size()) res.push_back(left[i++]);\n        while(j<(int)right.size()) res.push_back(right[j++]);\n        return res;\n    };\n    \n    vector<int> si = msort(items); // sorted ascending\n    \n    // Estimate weights: w[si[0]]=1, for each i, binary search how many smallest items equal it\n    vector<double> w(N, 1.0);\n    // cumulative weight estimate\n    vector<double> cum(N+1, 0);\n    cum[1] = 1.0;\n    \n    for(int i=1; i<N && queries_used<Q; i++){\n        // Binary search: find k in [1, i] such that sum of si[0..k-1] ~ si[i]\n        int lo=1, hi=i, best=0;\n        while(lo<=hi && queries_used<Q){\n            int mid=(lo+hi)/2;\n            vector<int> L={si[i]}, R;\n            for(int j=0;j<mid;j++) R.push_back(si[j]);\n            char c=query(L,R);\n            if(c=='>') { best=mid; lo=mid+1; }\n            else if(c=='<') { hi=mid-1; }\n            else { best=mid; break; }\n        }\n        w[si[i]] = (best>0) ? cum[best] + (cum[best]-cum[max(0,best-1)])*0.5 : cum[1]*0.5;\n        if(best>=i) w[si[i]] = cum[i] + (cum[i]-cum[max(0,i-1)])*0.5;\n        cum[i+1] = cum[i] + w[si[i]];\n    }\n    for(int i=1;i<N;i++) if(cum[i+1]==0) { w[si[i]]=w[si[i-1]]; cum[i+1]=cum[i]+w[si[i]]; }\n    \n    while(queries_used<Q){ vector<int> L={0},R={1}; query(L,R); }\n    \n    // LPT partition\n    vector<int> order(si.rbegin(), si.rend());\n    vector<double> gw(D,0);\n    vector<int> assign(N,0);\n    for(int idx:order){ int b=min_element(gw.begin(),gw.end())-gw.begin(); assign[idx]=b; gw[b]+=w[idx]; }\n    \n    for(int i=0;i<N;i++) cout<<assign[i]<<\" \\n\"[i==N-1];\n    cout<<flush;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int n, m;\n    scanf(\"%d%d\", &n, &m);\n    \n    vector<vector<int>> stacks(m);\n    \n    for(int i = 0; i < m; i++){\n        stacks[i].resize(n/m);\n        for(int j = 0; j < n/m; j++){\n            scanf(\"%d\", &stacks[i][j]);\n        }\n    }\n    \n    vector<pair<int,int>> ops;\n    \n    auto find_box = [&](int v) -> pair<int,int> {\n        for(int i = 0; i < m; i++)\n            for(int j = 0; j < (int)stacks[i].size(); j++)\n                if(stacks[i][j] == v) return {i, j};\n        return {-1,-1};\n    };\n    \n    for(int v = 1; v <= n; v++){\n        auto [si, sj] = find_box(v);\n        \n        if(sj == (int)stacks[si].size() - 1){\n            ops.push_back({v, 0});\n            stacks[si].pop_back();\n            // Check if more boxes can be carried out\n            continue;\n        }\n        \n        // Move everything above v to best destination\n        vector<int> chunk(stacks[si].begin() + sj + 1, stacks[si].end());\n        int chunk_max = *max_element(chunk.begin(), chunk.end());\n        int chunk_min = *min_element(chunk.begin(), chunk.end());\n        int chunk_sz = chunk.size();\n        \n        int best_dest = -1;\n        double best_score = -1e18;\n        \n        for(int d = 0; d < m; d++){\n            if(d == si) continue;\n            int top = stacks[d].empty() ? n+1 : stacks[d].back();\n            double score = 0;\n            \n            if(top > chunk_max){\n                // Good: chunk won't block anything below in dest\n                score += 10000;\n                // Prefer tighter fit (smallest top that's still > chunk_max)\n                score -= top;\n            } else {\n                // Bad: chunk blocks some elements. Prefer dest where top is large\n                score += top;\n            }\n            \n            // Prefer shorter destination stacks (easier to access later)\n            score -= stacks[d].size() * 5;\n            \n            // Prefer empty stacks slightly less (save them as buffers)\n            if(stacks[d].empty()) score -= 50;\n            \n            if(score > best_score){\n                best_score = score;\n                best_dest = d;\n            }\n        }\n        \n        int bottom_box = chunk[0];\n        ops.push_back({bottom_box, best_dest + 1});\n        for(auto x : chunk) stacks[best_dest].push_back(x);\n        stacks[si].resize(sj + 1);\n        \n        ops.push_back({v, 0});\n        stacks[si].pop_back();\n    }\n    \n    for(auto& [a,b] : ops) printf(\"%d %d\\n\", a, b);\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nstring h_wall[40], v_wall[40];\nint d[40][40];\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\nchar dc[]={'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 h_wall[x-1][y]=='0';\n    if(dir==1) return h_wall[x][y]=='0';\n    if(dir==2) return v_wall[x][y-1]=='0';\n    if(dir==3) return v_wall[x][y]=='0';\n    return false;\n}\n\n// BFS shortest path, returns sequence of directions\nvector<int> bfs_path(int sx,int sy,int gx,int gy){\n    if(sx==gx&&sy==gy) return {};\n    vector<vector<int>> prev(N,vector<int>(N,-1));\n    vector<vector<bool>> vis(N,vector<bool>(N,false));\n    queue<pair<int,int>> q;\n    q.push({sx,sy}); vis[sx][sy]=true;\n    while(!q.empty()){\n        auto [x,y]=q.front(); q.pop();\n        if(x==gx&&y==gy) break;\n        for(int dir=0;dir<4;dir++){\n            if(!canMove(x,y,dir)) continue;\n            int nx=x+dx[dir],ny=y+dy[dir];\n            if(!vis[nx][ny]){\n                vis[nx][ny]=true; prev[nx][ny]=dir;\n                q.push({nx,ny});\n            }\n        }\n    }\n    vector<int> path;\n    int cx=gx,cy=gy;\n    while(cx!=sx||cy!=sy){\n        int dir=prev[cx][cy];\n        path.push_back(dir);\n        cx-=dx[dir]; cy-=dy[dir];\n    }\n    reverse(path.begin(),path.end());\n    return path;\n}\n\n// BFS distance from a source to all cells\nvector<vector<int>> bfs_dist(int sx, int sy){\n    vector<vector<int>> dist(N, vector<int>(N, 1e9));\n    dist[sx][sy] = 0;\n    queue<pair<int,int>> q;\n    q.push({sx,sy});\n    while(!q.empty()){\n        auto [x,y] = q.front(); q.pop();\n        for(int dir=0;dir<4;dir++){\n            if(!canMove(x,y,dir)) continue;\n            int nx=x+dx[dir], ny=y+dy[dir];\n            if(dist[nx][ny] > dist[x][y]+1){\n                dist[nx][ny] = dist[x][y]+1;\n                q.push({nx,ny});\n            }\n        }\n    }\n    return dist;\n}\n\nlong long totalD;\n\n// Compute average dirtiness for a given route (as directions)\ndouble computeScore(const vector<int>& route){\n    int L = route.size();\n    // For each cell, find when it's visited\n    // S_t = sum of all dirtiness after step t\n    // After step t, cell (i,j) has dirtiness = d[i][j] * (t - last_clean_time(i,j,t))\n    // where last_clean_time is the last time cell was visited (cleaned) at or before t\n    // Actually at t=0 all are 0. Each step: all cells += d[i][j], then visited cell = 0\n    // So after steady state (repeating), we need sum over t=L..2L-1 of S_t / L\n    \n    // Simulate second iteration\n    // First, simulate first iteration to get state at t=L\n    vector<vector<int>> dirty(N, vector<int>(N, 0));\n    int cx=0, cy=0;\n    for(int t=0; t<L; t++){\n        int dir = route[t];\n        // all cells gain dirt\n        // then visited cell becomes 0\n        cx += dx[dir]; cy += dy[dir];\n        // Instead of updating all cells, track last visit time\n    }\n    \n    // More efficient: track last visit time for each cell\n    // dirtiness of (i,j) at time t = d[i][j] * (t - last_visit[i][j])\n    // S_t = sum d[i][j] * (t - last_visit[i][j])\n    // But last_visit changes when we step on a cell\n    \n    // For the second pass (t=L..2L-1), last_visit starts from first pass positions\n    // Let's just track last_visit times\n    \n    vector<vector<int>> lastVisit(N, vector<int>(N, -1));\n    // cell (0,0) is visited at t=0 (start)\n    // Actually, at t=0, dirtiness is 0 for all. The route starts at (0,0).\n    // \"After the move\" = after step t (1-indexed?), no it says t-th move\n    // a_{0,i,j} = 0 for all\n    // After move t: dirtiness of moved-to cell = 0, all others += d[i][j]\n    \n    // Let me just do it step by step for two iterations\n    // But N can be 40, so N^2=1600 cells, L up to 100000\n    // 1600 * 200000 = too much\n    \n    // Better approach: for each cell, collect visit times in second pass\n    // Contribution of cell (i,j) = d[i,j] * sum over gaps of g*(g-1)/2 summed, /L\n    // Actually let me think again...\n    \n    // In steady state, cell (i,j) is visited at certain positions in the cycle\n    // Between consecutive visits (gap g), contribution to sum of S_t over those g steps\n    // = d[i][j] * (1 + 2 + ... + (g-1)) if not the visited cell\n    // Wait, when we visit cell c at time t, c's dirtiness becomes 0\n    // At time t+1, we move to some cell, all cells including c gain d, then the new cell is set to 0\n    // So for cell c visited at times t1, t2, ... with gaps g = t2-t1:\n    // At times t1+1, t1+2, ..., t2-1, t2: dirtiness is d*1, d*2, ..., d*(g-1), then at t2 it becomes 0\n    // Wait at t2 it's cleaned. So dirtiness values are d*1, d*2, ..., d*(g-1), 0\n    // Sum = d * g*(g-1)/2\n    \n    // So total sum over one cycle = sum over all cells sum over all gaps: d[i][j] * g*(g-1)/2\n    // Average = (1/L) * sum\n    \n    // For cells never revisited in the cycle (visited once), gap = L\n    // Contribution = d[i][j] * L*(L-1)/2 / L \u2248 d[i][j]*L/2\n    \n    // For cells visited k times equally spaced, gap = L/k each\n    // Contribution = k * d[i][j] * (L/k)*((L/k)-1)/2 / L \u2248 d[i][j]*L/(2k)\n    \n    // So visiting a cell twice halves its contribution!\n    \n    // Now I need to find visit times. Let me collect them.\n    cx=0; cy=0;\n    // positions: at time 0, we're at (0,0)\n    // visit at time 0: (0,0)\n    // after move t, we're at new position, that position is cleaned\n    \n    vector<vector<vector<int>>> visitTimes(N, vector<vector<int>>(N));\n    visitTimes[0][0].push_back(0);\n    for(int t=0; t<L; t++){\n        int dir = route[t];\n        cx += dx[dir]; cy += dy[dir];\n        visitTimes[cx][cy].push_back(t+1);\n    }\n    \n    double total = 0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        auto& vt = visitTimes[i][j];\n        // In steady state, visits repeat with period L\n        // Gaps between consecutive visits (cyclic)\n        int k = vt.size();\n        if(k == 0){\n            // never visited - shouldn't happen\n            total += (double)d[i][j] * L * (L-1) / 2.0;\n            continue;\n        }\n        for(int a=0; a<k; a++){\n            int gap;\n            if(a+1 < k) gap = vt[a+1] - vt[a];\n            else gap = L - vt[a] + vt[0]; // wrap around\n            total += (double)d[i][j] * gap * (gap-1) / 2.0;\n        }\n    }\n    return total / L;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto startTime = chrono::steady_clock::now();\n    \n    cin>>N;\n    for(int i=0;i<N-1;i++) cin>>h_wall[i];\n    for(int i=0;i<N;i++) cin>>v_wall[i];\n    totalD = 0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        cin>>d[i][j];\n        totalD += d[i][j];\n    }\n    \n    // Precompute BFS distances from every cell\n    vector<vector<vector<vector<int>>>> dist(N, vector<vector<vector<int>>>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++)\n        dist[i][j] = bfs_dist(i,j);\n    \n    // Build a base tour using DFS\n    vector<int> baseTour;\n    {\n        vector<vector<bool>> vis(N, vector<bool>(N, false));\n        // DFS from (0,0)\n        function<void(int,int)> dfs = [&](int x, int y){\n            vis[x][y] = true;\n            // Sort neighbors by d value (visit high-d first? or some heuristic)\n            vector<pair<int,int>> neighbors;\n            for(int dir=0;dir<4;dir++){\n                if(!canMove(x,y,dir)) continue;\n                int nx=x+dx[dir], ny=y+dy[dir];\n                if(!vis[nx][ny]) neighbors.push_back({dir, d[nx][ny]});\n            }\n            // Visit high-d neighbors first so they appear earlier\n            sort(neighbors.begin(), neighbors.end(), [](auto&a, auto&b){return a.second > b.second;});\n            for(auto [dir, _] : neighbors){\n                int nx=x+dx[dir], ny=y+dy[dir];\n                if(!vis[nx][ny]){\n                    baseTour.push_back(dir);\n                    dfs(nx, ny);\n                    baseTour.push_back(dir^1); // reverse direction\n                }\n            }\n        };\n        dfs(0,0);\n    }\n    \n    // Now baseTour visits all cells, length ~2*(N^2-1)\n    // Try to build a better route: TSP-style ordering then add revisits\n    \n    // Collect all cells sorted by d value\n    vector<pair<int,int>> cells;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cells.push_back({i,j});\n    sort(cells.begin(), cells.end(), [](auto&a, auto&b){\n        return d[a.first][a.second] > d[b.first][b.second];\n    });\n    \n    // Strategy: Build route as sequence of waypoints to visit\n    // Start with all cells as waypoints (must visit each at least once)\n    // Then add extra visits to high-d cells\n    // Order waypoints to minimize total path length (greedy nearest neighbor weighted by dirt)\n    \n    // Build initial waypoint list: greedy TSP\n    auto buildRoute = [&](vector<pair<int,int>>& waypoints) -> vector<int> {\n        vector<int> route;\n        int cx=0, cy=0;\n        for(auto [wx, wy] : waypoints){\n            auto p = bfs_path(cx, cy, wx, wy);\n            for(int dir : p) route.push_back(dir);\n            cx = wx; cy = wy;\n        }\n        // Return to (0,0)\n        auto p = bfs_path(cx, cy, 0, 0);\n        for(int dir : p) route.push_back(dir);\n        return route;\n    };\n    \n    // Greedy nearest neighbor with d-weight\n    auto greedyOrder = [&]() -> vector<pair<int,int>> {\n        vector<vector<bool>> vis(N, vector<bool>(N, false));\n        vis[0][0] = true;\n        vector<pair<int,int>> order;\n        int cx=0, cy=0;\n        int remaining = N*N - 1;\n        while(remaining > 0){\n            int bestx=-1, besty=-1;\n            double bestScore = -1;\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n                if(vis[i][j]) continue;\n                int dd = dist[cx][cy][i][j];\n                double score = (double)d[i][j] / (dd + 1);\n                if(score > bestScore){\n                    bestScore = score;\n                    bestx = i; besty = j;\n                }\n            }\n            // Also add intermediate unvisited cells on the path\n            auto p = bfs_path(cx, cy, bestx, besty);\n            int tx=cx, ty=cy;\n            for(int dir : p){\n                tx += dx[dir]; ty += dy[dir];\n                if(!vis[tx][ty]){\n                    vis[tx][ty] = true;\n                    remaining--;\n                    order.push_back({tx, ty});\n                }\n            }\n            cx = bestx; cy = besty;\n        }\n        return order;\n    };\n    \n    vector<pair<int,int>> waypoints = greedyOrder();\n    vector<int> bestRoute = buildRoute(waypoints);\n    double bestScore = computeScore(bestRoute);\n    \n    // Also try DFS-based route\n    {\n        double dfsScore = computeScore(baseTour);\n        if(dfsScore < bestScore){\n            bestScore = dfsScore;\n            bestRoute = baseTour;\n        }\n    }\n    \n    // Now try adding extra visits to high-d cells\n    // The idea: insert detours to high-d cells at various points in the route\n    // For a cell visited k times with equal spacing, contribution \u2248 d * L / (2k)\n    // Adding one more visit (round-trip cost 2*dist) increases L by 2*dist but makes it k+1 visits\n    // New contribution \u2248 d * (L + 2*dist) / (2*(k+1))\n    // Benefit = d*L/(2k) - d*(L+2*dist)/(2*(k+1)) = d/(2k(k+1)) * (L - 2k*dist)\n    // Worth it if L > 2k*dist\n    \n    // Let's try a different approach: build the route from scratch with planned revisits\n    // For each cell, determine optimal number of visits k_i proportional to sqrt(d[i][j])\n    // Then total path length should accommodate these visits\n    \n    // Simpler iterative approach: given current route, find the best detour to insert\n    auto insertDetours = [&](vector<int>& route) {\n        int L = route.size();\n        if(L >= 99000) return;\n        \n        // Compute visit times for each cell\n        vector<vector<vector<int>>> visitTimes(N, vector<vector<int>>(N));\n        int cx=0, cy=0;\n        visitTimes[0][0].push_back(0);\n        vector<pair<int,int>> positions;\n        positions.push_back({0,0});\n        for(int t=0; t<L; t++){\n            cx += dx[route[t]]; cy += dy[route[t]];\n            visitTimes[cx][cy].push_back(t+1);\n            positions.push_back({cx,cy});\n        }\n        \n        // For each cell, compute current contribution\n        // Find the cell+position combination that gives best improvement\n        // Try inserting a round-trip detour to a high-d cell at some point in the route\n        \n        // Score improvement for inserting a detour of cost C at position t in the route\n        // to visit cell (gi, gj):\n        // This splits some gap for (gi,gj) and adds C to all gaps' effective L\n        // Complex to compute exactly, so let's use the approximation\n        \n        // Find max-contribution cell\n        double maxContrib = -1;\n        int mi=-1, mj=-1;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            auto& vt = visitTimes[i][j];\n            int k = vt.size();\n            double contrib = 0;\n            for(int a=0;a<k;a++){\n                int gap = (a+1<k) ? vt[a+1]-vt[a] : L-vt[a]+vt[0];\n                contrib += (double)d[i][j] * gap * (gap-1) / 2.0;\n            }\n            contrib /= L;\n            if(contrib > maxContrib){\n                maxContrib = contrib;\n                mi = i; mj = j;\n            }\n        }\n        \n        // Find the largest gap for this cell\n        auto& vt = visitTimes[mi][mj];\n        int bestGapStart = -1, bestGapLen = 0;\n        int k = vt.size();\n        for(int a=0;a<k;a++){\n            int gap = (a+1<k) ? vt[a+1]-vt[a] : L-vt[a]+vt[0];\n            if(gap > bestGapLen){\n                bestGapLen = gap;\n                bestGapStart = a;\n            }\n        }\n        \n        // Insert at middle of this gap\n        int insertTime;\n        if(bestGapStart+1 < k){\n            insertTime = (vt[bestGapStart] + vt[bestGapStart+1]) / 2;\n        } else {\n            insertTime = (vt[bestGapStart] + L + vt[0]) / 2;\n            if(insertTime >= L) insertTime -= L;\n        }\n        \n        // Position at insertTime\n        auto [px, py] = positions[insertTime];\n        int detourCost = 2 * dist[px][py][mi][mj];\n        \n        if((int)route.size() + detourCost > 99000) return;\n        \n        // Build detour path\n        auto pathTo = bfs_path(px, py, mi, mj);\n        auto pathBack = bfs_path(mi, mj, px, py);\n        \n        // Insert into route at position insertTime\n        vector<int> newRoute;\n        for(int t=0; t<insertTime; t++) newRoute.push_back(route[t]);\n        for(int dir : pathTo) newRoute.push_back(dir);\n        for(int dir : pathBack) newRoute.push_back(dir);\n        for(int t=insertTime; t<L; t++) newRoute.push_back(route[t]);\n        \n        double newScore = computeScore(newRoute);\n        if(newScore < bestScore){\n            bestScore = newScore;\n            route = newRoute;\n            bestRoute = newRoute;\n        }\n    };\n    \n    // Repeatedly insert detours\n    for(int iter=0; iter<2000; iter++){\n        auto elapsed = chrono::steady_clock::now() - startTime;\n        if(chrono::duration_cast<chrono::milliseconds>(elapsed).count() > 1800) break;\n        int oldSize = bestRoute.size();\n        insertDetours(bestRoute);\n        if((int)bestRoute.size() == oldSize) break; // no improvement\n    }\n    \n    // Output\n    string ans;\n    for(int dir : bestRoute) ans += dc[dir];\n    cout << ans << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N,M;\n    cin>>N>>M;\n    int si,sj;\n    cin>>si>>sj;\n    \n    vector<string> grid(N);\n    for(int i=0;i<N;i++) cin>>grid[i];\n    \n    vector<string> words(M);\n    for(int i=0;i<M;i++) cin>>words[i];\n    \n    vector<vector<pair<int,int>>> charpos(26);\n    for(int i=0;i<N;i++)\n        for(int j=0;j<N;j++)\n            charpos[grid[i][j]-'A'].push_back({i,j});\n    \n    // mindist[a][b] for chars\n    vector<vector<int>> mindist(26,vector<int>(26,100));\n    for(int a=0;a<26;a++) for(int b=0;b<26;b++){\n        for(auto&[ai,aj]:charpos[a]) for(auto&[bi,bj]:charpos[b])\n            mindist[a][b]=min(mindist[a][b],abs(ai-bi)+abs(aj-bj)+1);\n    }\n    // mindist from position to char\n    // minFromPos[pos][c] = min cost to go from pos to any cell with char c\n    vector<vector<int>> minFromPos(N*N, vector<int>(26,100));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        int pos=i*N+j;\n        for(int c=0;c<26;c++){\n            for(auto&[ci,cj]:charpos[c])\n                minFromPos[pos][c]=min(minFromPos[pos][c],abs(i-ci)+abs(j-cj)+1);\n        }\n    }\n    \n    // Remove contained words\n    vector<bool> removed(M,false);\n    for(int i=0;i<M;i++) if(!removed[i])\n        for(int j=0;j<M;j++) if(i!=j&&!removed[j])\n            if(words[i].find(words[j])!=string::npos) removed[j]=true;\n    \n    vector<string> ws;\n    for(int i=0;i<M;i++) if(!removed[i]) ws.push_back(words[i]);\n    int n=ws.size();\n    \n    // Overlap matrix\n    vector<vector<int>> ov(n,vector<int>(n,0));\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j){\n        int maxo=min((int)ws[i].size(),(int)ws[j].size());\n        for(int o=maxo;o>=1;o--){\n            if(ws[i].compare(ws[i].size()-o,o,ws[j],0,o)==0){ov[i][j]=o;break;}\n        }\n    }\n    \n    // Greedy superstring - merge pairs with max overlap, break ties by grid cost\n    vector<int> nxtW(n,-1), prvW(n,-1);\n    vector<bool> hasNext(n,false),hasPrev(n,false);\n    vector<int> ufpar(n);\n    iota(ufpar.begin(),ufpar.end(),0);\n    function<int(int)> ufFind=[&](int x)->int{return ufpar[x]==x?x:ufpar[x]=ufFind(ufpar[x]);};\n    \n    // Sort edges by overlap desc, then by grid cost asc for ties\n    vector<tuple<int,int,int,int>> edges;\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j&&ov[i][j]>0){\n        // transition cost: last char of i to first new char of j\n        int transC = mindist[ws[i].back()-'A'][ws[j][ov[i][j]<(int)ws[j].size()?ov[i][j]:ws[j].size()-1]-'A'];\n        edges.push_back({ov[i][j],-transC,i,j});\n    }\n    sort(edges.rbegin(),edges.rend());\n    \n    for(auto&[o,neg_tc,i,j]:edges){\n        if(hasNext[i]||hasPrev[j]) continue;\n        if(ufFind(i)==ufFind(j)) continue;\n        nxtW[i]=j; prvW[j]=i;\n        hasNext[i]=true; hasPrev[j]=true;\n        ufpar[ufFind(i)]=ufFind(j);\n    }\n    \n    // Build chains\n    vector<string> chains;\n    for(int i=0;i<n;i++) if(!hasPrev[i]){\n        string s=ws[i];\n        int cur=nxtW[i];\n        int prev=i;\n        while(cur!=-1){\n            s+=ws[cur].substr(ov[prev][cur]);\n            prev=cur;\n            cur=nxtW[cur];\n        }\n        chains.push_back(s);\n    }\n    \n    int nc=chains.size();\n    \n    // Order chains by nearest neighbor using grid cost estimate\n    auto chainStartMinDist=[&](int pos, const string& s)->int{\n        return minFromPos[pos][s[0]-'A'];\n    };\n    \n    // Build target by trying all permutation orderings (NN + swap improvement)\n    vector<bool> usedC(nc,false);\n    vector<int> order;\n    {\n        int bestc=-1,bestv=INT_MAX;\n        for(int i=0;i<nc;i++){\n            int v=0;\n            for(auto&[ci,cj]:charpos[chains[i][0]-'A'])\n                v=min(v==0?INT_MAX:v, abs(ci-si)+abs(cj-sj)+1);\n            if(v<bestv){bestv=v;bestc=i;}\n        }\n        order.push_back(bestc);usedC[bestc]=true;\n    }\n    while((int)order.size()<nc){\n        int last=order.back();\n        char lc=chains[last].back();\n        int bestc=-1,bestv=INT_MAX;\n        for(int i=0;i<nc;i++) if(!usedC[i]){\n            int v=mindist[lc-'A'][chains[i][0]-'A'];\n            if(v<bestv){bestv=v;bestc=i;}\n        }\n        order.push_back(bestc);usedC[bestc]=true;\n    }\n    \n    // Swap improvement\n    auto getCost=[&]()->int{\n        int c=0;\n        for(int i=0;i<nc;i++){\n            if(i==0){\n                for(auto&[ci,cj]:charpos[chains[order[0]][0]-'A'])\n                    c=min(c==0?INT_MAX:c,abs(ci-si)+abs(cj-sj)+1);\n            } else {\n                c+=mindist[chains[order[i-1]].back()-'A'][chains[order[i]][0]-'A'];\n            }\n        }\n        return c;\n    };\n    for(int it=0;it<2000;it++){\n        bool imp=false;\n        for(int i=0;i<nc&&!imp;i++) for(int j=i+1;j<nc&&!imp;j++){\n            swap(order[i],order[j]);\n            if(getCost()<(swap(order[i],order[j]),getCost())){swap(order[i],order[j]);imp=true;}\n        }\n        if(!imp) break;\n    }\n    \n    string target;\n    for(int i:order) target+=chains[i];\n    if((int)target.size()>5000) target.resize(5000);\n    int L=target.size();\n    \n    // Beam search with heuristic\n    // Precompute suffix heuristic: sum of mindist for remaining chars\n    vector<int> suffixH(L+1,0);\n    for(int i=L-1;i>=1;i--) suffixH[i]=suffixH[i+1]+mindist[target[i-1]-'A'][target[i]-'A'];\n    \n    int BEAM=225;\n    vector<vector<pair<int,int>>> layers(L+1); // (cost, parent_idx) per position slot\n    // For each layer, store states indexed by grid position\n    // layers[step]: vector of (cost, parent_idx), one per state\n    // Also need position mapping\n    struct St { int pos,cost,par; };\n    vector<vector<St>> lyr(L+1);\n    lyr[0].push_back({si*N+sj,0,-1});\n    \n    for(int step=0;step<L;step++){\n        int ch=target[step]-'A';\n        auto&cur=lyr[step];\n        // best[npos] = {cost, parent_idx}\n        int bestCost[225]; int bestPar[225];\n        fill(bestCost,bestCost+225,INT_MAX);\n        for(int idx=0;idx<(int)cur.size();idx++){\n            int ci=cur[idx].pos/N,cj=cur[idx].pos%N,cc=cur[idx].cost;\n            for(auto&[ni,nj]:charpos[ch]){\n                int nc=cc+abs(ni-ci)+abs(nj-cj)+1;\n                int np=ni*N+nj;\n                if(nc<bestCost[np]){bestCost[np]=nc;bestPar[np]=idx;}\n            }\n        }\n        vector<tuple<int,int,int>> cands;\n        for(int p=0;p<N*N;p++) if(bestCost[p]<INT_MAX)\n            cands.push_back({bestCost[p],p,bestPar[p]});\n        // Sort by cost + heuristic from this position\n        sort(cands.begin(),cands.end(),[&](auto&a,auto&b){\n            int ha=get<0>(a)+(step+1<L?minFromPos[get<1>(a)][target[step+1]-'A']:0);\n            int hb=get<0>(b)+(step+1<L?minFromPos[get<1>(b)][target[step+1]-'A']:0);\n            return ha<hb;\n        });\n        if((int)cands.size()>BEAM) cands.resize(BEAM);\n        for(auto&[c,p,par]:cands) lyr[step+1].push_back({p,c,par});\n    }\n    \n    int bestIdx=0;\n    for(int i=1;i<(int)lyr[L].size();i++)\n        if(lyr[L][i].cost<lyr[L][bestIdx].cost) bestIdx=i;\n    \n    vector<pair<int,int>> result(L);\n    int idx=bestIdx;\n    for(int step=L;step>=1;step--){\n        result[step-1]={lyr[step][idx].pos/N,lyr[step][idx].pos%N};\n        idx=lyr[step][idx].par;\n    }\n    \n    for(int p=0;p<L;p++) cout<<result[p].first<<\" \"<<result[p].second<<\"\\n\";\n}","ahc030":"#include<bits/stdc++.h>\nusing namespace std;\nmt19937 rng(42);\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M; double eps;\n    cin>>N>>M>>eps;\n    \n    vector<vector<pair<int,int>>> fields(M);\n    for(int k=0;k<M;k++){\n        int d; cin>>d; fields[k].resize(d);\n        for(int i=0;i<d;i++) cin>>fields[k][i].first>>fields[k][i].second;\n    }\n    \n    // Enumerate placements\n    vector<vector<int>> place_id(M);\n    // For each field k, placement p: bitmask or grid contribution\n    // Store as vector of (i,j)\n    vector<vector<vector<pair<int,int>>>> psquares(M);\n    \n    for(int k=0;k<M;k++){\n        int maxi=0,maxj=0;\n        for(auto&[r,c]:fields[k]){maxi=max(maxi,r);maxj=max(maxj,c);}\n        for(int di=0;di+maxi<N;di++){\n            for(int dj=0;dj+maxj<N;dj++){\n                vector<pair<int,int>> sq;\n                for(auto&[r,c]:fields[k]) sq.push_back({r+di,c+dj});\n                psquares[k].push_back(sq);\n            }\n        }\n    }\n    \n    // Precompute row sums and col sums for each placement\n    int nrows=N, ncols=N;\n    vector<vector<vector<int>>> prow(M), pcol(M);\n    for(int k=0;k<M;k++){\n        int np=psquares[k].size();\n        prow[k].resize(np,vector<int>(N,0));\n        pcol[k].resize(np,vector<int>(N,0));\n        for(int p=0;p<np;p++){\n            for(auto&[r,c]:psquares[k][p]){\n                prow[k][p][r]++;\n                pcol[k][p][c]++;\n            }\n        }\n    }\n    \n    // Query rows via divination\n    vector<int> row_obs(N), col_obs(N);\n    double total_cost = 0;\n    \n    // For small eps, divination is accurate. Query each row.\n    auto query_set = [&](vector<pair<int,int>>& S) -> int {\n        int d=S.size();\n        cout<<\"q \"<<d;\n        for(auto&[i,j]:S) cout<<\" \"<<i<<\" \"<<j;\n        cout<<endl;\n        int v; cin>>v;\n        return v;\n    };\n    \n    // Query rows\n    for(int i=0;i<N;i++){\n        vector<pair<int,int>> S;\n        for(int j=0;j<N;j++) S.push_back({i,j});\n        row_obs[i]=query_set(S);\n        total_cost += 1.0/sqrt(N);\n    }\n    // Query cols\n    for(int j=0;j<N;j++){\n        vector<pair<int,int>> S;\n        for(int i=0;i<N;i++) S.push_back({i,j});\n        col_obs[j]=query_set(S);\n        total_cost += 1.0/sqrt(N);\n    }\n    \n    // Multiple row/col queries for better accuracy when eps is large\n    int extra_rounds = (eps > 0.1) ? 2 : 0;\n    vector<vector<int>> row_obs_all(N), col_obs_all(N);\n    for(int i=0;i<N;i++) row_obs_all[i].push_back(row_obs[i]);\n    for(int j=0;j<N;j++) col_obs_all[j].push_back(col_obs[j]);\n    \n    for(int r=0;r<extra_rounds;r++){\n        for(int i=0;i<N;i++){\n            vector<pair<int,int>> S;\n            for(int j=0;j<N;j++) S.push_back({i,j});\n            int v=query_set(S);\n            row_obs_all[i].push_back(v);\n            total_cost+=1.0/sqrt(N);\n        }\n        for(int j=0;j<N;j++){\n            vector<pair<int,int>> S;\n            for(int i=0;i<N;i++) S.push_back({i,j});\n            int v=query_set(S);\n            col_obs_all[j].push_back(v);\n            total_cost+=1.0/sqrt(N);\n        }\n    }\n    \n    // Use median of observations\n    for(int i=0;i<N;i++){\n        sort(row_obs_all[i].begin(),row_obs_all[i].end());\n        row_obs[i]=row_obs_all[i][row_obs_all[i].size()/2];\n    }\n    for(int j=0;j<N;j++){\n        sort(col_obs_all[j].begin(),col_obs_all[j].end());\n        col_obs[j]=col_obs_all[j][col_obs_all[j].size()/2];\n    }\n    \n    // Log-likelihood of observing row_obs given true sum v(S) with k=N squares\n    // Mean = (N - v(S))*eps + v(S)*(1-eps) = N*eps + v(S)*(1-2*eps)\n    // Variance = N*eps*(1-eps)\n    auto log_prob_obs = [&](int obs, int true_sum, int k) -> double {\n        double mu = (double)(k - true_sum)*eps + (double)true_sum*(1.0-eps);\n        double sigma2 = (double)k * eps * (1.0-eps);\n        double sigma = sqrt(sigma2);\n        // obs is round(x) where x ~ N(mu, sigma2), then max(0,.)\n        // P(obs) \u2248 Phi((obs+0.5-mu)/sigma) - Phi((obs-0.5-mu)/sigma)\n        // For obs=0, P(0) = Phi((0.5-mu)/sigma)\n        double lo = (obs - 0.5 - mu)/sigma;\n        double hi = (obs + 0.5 - mu)/sigma;\n        if(obs==0) lo = -1e9;\n        double p = 0.5*erfc(-hi/sqrt(2.0)) - 0.5*erfc(-lo/sqrt(2.0));\n        if(p < 1e-300) p = 1e-300;\n        return log(p);\n    };\n    \n    // MCMC: sample placement indices for each field\n    // State: choice[k] = index of placement for field k\n    vector<int> choice(M);\n    for(int k=0;k<M;k++) choice[k] = rng()%psquares[k].size();\n    \n    auto compute_ll = [&](vector<int>& ch) -> double {\n        double ll=0;\n        for(int i=0;i<N;i++){\n            int s=0;\n            for(int k=0;k<M;k++) s+=prow[k][ch[k]][i];\n            for(auto& obs:row_obs_all[i])\n                ll+=log_prob_obs(obs,s,N);\n        }\n        for(int j=0;j<N;j++){\n            int s=0;\n            for(int k=0;k<M;k++) s+=pcol[k][ch[k]][j];\n            for(auto& obs:col_obs_all[j])\n                ll+=log_prob_obs(obs,s,N);\n        }\n        return ll;\n    };\n    \n    double cur_ll = compute_ll(choice);\n    \n    // Count how often each cell is occupied\n    vector<vector<double>> occ_count(N, vector<double>(N,0));\n    int samples=0;\n    int total_iters=200000;\n    int burnin=50000;\n    \n    for(int iter=0;iter<total_iters;iter++){\n        int k=rng()%M;\n        int old_p=choice[k];\n        int new_p=rng()%psquares[k].size();\n        choice[k]=new_p;\n        double new_ll=compute_ll(choice);\n        double accept = exp(min(0.0, new_ll-cur_ll));\n        if(uniform_real_distribution<double>(0,1)(rng) < accept){\n            cur_ll=new_ll;\n        } else {\n            choice[k]=old_p;\n        }\n        \n        if(iter>=burnin){\n            for(int kk=0;kk<M;kk++){\n                for(auto&[r,c]:psquares[kk][choice[kk]]){\n                    occ_count[r][c]+=1.0;\n                }\n            }\n            samples++;\n        }\n    }\n    \n    // Normalize\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++) occ_count[i][j]/=samples;\n    \n    // Track drilled squares and known oil\n    vector<vector<int>> known(N, vector<int>(N,-1));\n    set<pair<int,int>> confirmed_oil;\n    set<pair<int,int>> confirmed_empty;\n    int ops_used = N*(1+extra_rounds)*2; // row+col queries\n    int max_ops = 2*N*N;\n    \n    // Drill uncertain squares (probability between 0.1 and 0.9)\n    vector<tuple<double,int,int>> uncertain;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        double p=occ_count[i][j];\n        double unc = min(p, 1-p);\n        if(unc > 0.01) uncertain.push_back({-unc,i,j}); // sort by most uncertain first... actually sort by closest to 0.5\n    }\n    sort(uncertain.begin(),uncertain.end()); // most uncertain first (most negative = highest unc)\n    \n    // Drill the most uncertain ones\n    for(auto&[u,i,j]:uncertain){\n        if(ops_used >= max_ops-1) break;\n        cout<<\"q 1 \"<<i<<\" \"<<j<<endl;\n        int v; cin>>v;\n        known[i][j]=v;\n        ops_used++;\n        if(v>0) confirmed_oil.insert({i,j});\n        else confirmed_empty.insert({i,j});\n    }\n    \n    // Re-run MCMC with drilling constraints\n    // Reset\n    for(int k=0;k<M;k++) choice[k]=rng()%psquares[k].size();\n    \n    auto is_consistent = [&](vector<int>& ch) -> bool {\n        vector<vector<int>> grid(N, vector<int>(N,0));\n        for(int kk=0;kk<M;kk++)\n            for(auto&[r,c]:psquares[kk][ch[kk]]) grid[r][c]++;\n        for(auto&[r,c]:confirmed_oil) if(grid[r][c]==0) return false;\n        for(auto&[r,c]:confirmed_empty) if(grid[r][c]!=0) return false;\n        return true;\n    };\n    \n    // Find a consistent starting point\n    for(int t=0;t<1000000;t++){\n        int k=rng()%M;\n        choice[k]=rng()%psquares[k].size();\n        if(is_consistent(choice)) break;\n    }\n    \n    cur_ll=compute_ll(choice);\n    fill(occ_count.begin(),occ_count.end(),vector<double>(N,0));\n    samples=0;\n    \n    for(int iter=0;iter<total_iters;iter++){\n        int k=rng()%M;\n        int old_p=choice[k];\n        int new_p=rng()%psquares[k].size();\n        choice[k]=new_p;\n        if(!is_consistent(choice)){\n            choice[k]=old_p;\n            continue;\n        }\n        double new_ll=compute_ll(choice);\n        double accept=exp(min(0.0,new_ll-cur_ll));\n        if(uniform_real_distribution<double>(0,1)(rng)<accept){\n            cur_ll=new_ll;\n        } else {\n            choice[k]=old_p;\n        }\n        if(iter>=burnin){\n            for(int kk=0;kk<M;kk++)\n                for(auto&[r,c]:psquares[kk][choice[kk]])\n                    occ_count[r][c]+=1.0;\n            samples++;\n        }\n    }\n    if(samples>0) for(int i=0;i<N;i++)for(int j=0;j<N;j++) occ_count[i][j]/=samples;\n    \n    // Guess: squares with probability > 0.5, plus all confirmed oil\n    vector<pair<int,int>> ans;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(confirmed_oil.count({i,j}) || (occ_count[i][j]>0.5 && !confirmed_empty.count({i,j})))\n            ans.push_back({i,j});\n    }\n    \n    // Make sure confirmed oil is included\n    for(auto&p:confirmed_oil){\n        bool found=false;\n        for(auto&q:ans) if(q==p) found=true;\n        if(!found) ans.push_back(p);\n    }\n    \n    cout<<\"a \"<<ans.size();\n    for(auto&[i,j]:ans) cout<<\" \"<<i<<\" \"<<j;\n    cout<<endl;\n    int resp; cin>>resp;\n    if(resp==1) return 0;\n    \n    // Fallback: drill remaining\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(known[i][j]>=0) continue;\n        if(ops_used>=max_ops-1) break;\n        cout<<\"q 1 \"<<i<<\" \"<<j<<endl;\n        int v; cin>>v;\n        known[i][j]=v;\n        ops_used++;\n        if(v>0) confirmed_oil.insert({i,j});\n    }\n    \n    vector<pair<int,int>> ans2;\n    for(auto&p:confirmed_oil) ans2.push_back(p);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(known[i][j]<0 && occ_count[i][j]>0.5) ans2.push_back({i,j});\n    }\n    // deduplicate\n    sort(ans2.begin(),ans2.end());\n    ans2.erase(unique(ans2.begin(),ans2.end()),ans2.end());\n    \n    cout<<\"a \"<<ans2.size();\n    for(auto&[i,j]:ans2) cout<<\" \"<<i<<\" \"<<j;\n    cout<<endl;\n    cin>>resp;\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint W, D, N;\nvector<vector<int>> a;\nstruct Rect { int i0,j0,i1,j1; };\n\nvoid partition(vector<pair<int,int>>& items, int r0, int c0, int r1, int c1, vector<Rect>& result, bool hsplit) {\n    if (items.size() == 1) {\n        result[items[0].second] = {r0, c0, r1, c1};\n        return;\n    }\n    long long total = 0;\n    for (auto& p : items) total += p.first;\n    if (total == 0) total = 1;\n    \n    int n = items.size();\n    int mid = n / 2;\n    long long left_sum = 0;\n    for (int i = 0; i < mid; i++) left_sum += items[i].first;\n    \n    vector<pair<int,int>> left_items(items.begin(), items.begin()+mid);\n    vector<pair<int,int>> right_items(items.begin()+mid, items.end());\n    \n    if (hsplit) {\n        int split = r0 + max(1, min(r1-r0-1, (int)round((double)left_sum / total * (r1-r0))));\n        if (r1 - split < (int)right_items.size()) split = r1 - (int)right_items.size();\n        if (split - r0 < (int)left_items.size()) split = r0 + (int)left_items.size();\n        split = max(r0+1, min(r1-1, split));\n        partition(left_items, r0, c0, split, c1, result, !hsplit);\n        partition(right_items, split, c0, r1, c1, result, !hsplit);\n    } else {\n        int split = c0 + max(1, min(c1-c0-1, (int)round((double)left_sum / total * (c1-c0))));\n        if (c1 - split < (int)right_items.size()) split = c1 - (int)right_items.size();\n        if (split - c0 < (int)left_items.size()) split = c0 + (int)left_items.size();\n        split = max(c0+1, min(c1-1, split));\n        partition(left_items, r0, c0, r1, split, result, !hsplit);\n        partition(right_items, r0, split, r1, c1, result, !hsplit);\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> W >> D >> N;\n    a.resize(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    for(int d=0;d<D;d++){\n        vector<pair<int,int>> items(N);\n        for(int k=0;k<N;k++) items[k]={a[d][k], k};\n        vector<Rect> res(N);\n        partition(items, 0, 0, W, W, res, true);\n        for(int k=0;k<N;k++){\n            cout<<res[k].i0<<\" \"<<res[k].j0<<\" \"<<res[k].i1<<\" \"<<res[k].j1<<\"\\n\";\n        }\n    }\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nconst long long MOD = 998244353;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M,K;\n    cin>>N>>M>>K;\n    \n    long long a[9][9];\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>a[i][j];\n    \n    long long s[20][3][3];\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    // Greedy initial\n    long long b[9][9];\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) b[i][j]=a[i][j];\n    vector<tuple<int,int,int>> ops;\n    for(int step=0;step<K;step++){\n        int bm=0,bp=0,bq=0; long long bd=LLONG_MIN;\n        for(int m=0;m<M;m++) for(int p=0;p<=N-3;p++) for(int q=0;q<=N-3;q++){\n            long long d=0;\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++){\n                long long ov=b[p+i][q+j]%MOD, nv=(b[p+i][q+j]+s[m][i][j])%MOD;\n                d+=nv-ov;\n            }\n            if(d>bd){bd=d;bm=m;bp=p;bq=q;}\n        }\n        ops.push_back({bm,bp,bq});\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[bp+i][bq+j]+=s[bm][i][j];\n    }\n    \n    long long curScore=0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) curScore+=b[i][j]%MOD;\n    \n    auto bestOps=ops; long long bestScore=curScore;\n    long long bestB[9][9]; memcpy(bestB,b,sizeof(b));\n    \n    mt19937 rng(42);\n    auto startTime=chrono::steady_clock::now();\n    \n    int iter=0;\n    double curTime=0;\n    \n    while(true){\n        if((iter&1023)==0){\n            curTime=chrono::duration<double>(chrono::steady_clock::now()-startTime).count();\n            if(curTime>1.9) break;\n        }\n        iter++;\n        double temp=5e8*pow(1e5/(5e8), curTime/1.9);\n        \n        int idx=rng()%K;\n        auto [om,op,oq]=ops[idx];\n        int nm=rng()%M, np=rng()%7, nq=rng()%7;\n        \n        // Compute delta incrementally\n        // Collect affected cells, compute old mod, apply change, compute new mod\n        long long delta=0;\n        // Undo old stamp, apply new stamp, track changes\n        // Cells affected: old (op..op+2, oq..oq+2) and new (np..np+2, nq..nq+2)\n        bool visited[9][9]={};\n        long long saved[9][9];\n        \n        // Process old stamp removal\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++){\n            int r=op+i,c=oq+j;\n            if(!visited[r][c]){visited[r][c]=true;saved[r][c]=b[r][c];delta-=b[r][c]%MOD;}\n            b[r][c]-=s[om][i][j];\n        }\n        // Process new stamp addition\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++){\n            int r=np+i,c=nq+j;\n            if(!visited[r][c]){visited[r][c]=true;saved[r][c]=b[r][c];delta-=b[r][c]%MOD;}\n            b[r][c]+=s[nm][i][j];\n        }\n        // Compute new contributions\n        for(int i=0;i<9;i++) for(int j=0;j<9;j++) if(visited[i][j]) delta+=b[i][j]%MOD;\n        \n        if(delta>0||(delta>-1e9 && (rng()%1000000)<1000000.0*exp((double)delta/temp))){\n            curScore+=delta;\n            ops[idx]={nm,np,nq};\n            if(curScore>bestScore){bestScore=curScore;bestOps=ops;memcpy(bestB,b,sizeof(b));}\n        } else {\n            // Restore\n            for(int i=0;i<9;i++) for(int j=0;j<9;j++) if(visited[i][j]) b[i][j]=saved[i][j];\n        }\n    }\n    \n    cout<<bestOps.size()<<\"\\n\";\n    for(auto&[m,p,q]:bestOps) cout<<m<<\" \"<<p<<\" \"<<q<<\"\\n\";\n}","ahc033":"#include<bits/stdc++.h>\nusing namespace std;\n\nconst int N=5;\nint A[N][N];\nint grid[N][N];\nint cr[N],cc[N],ch[N];\nbool calive[N];\nbool cbombed[N];\nint recv_idx[N];\nint next_disp[N];\nstring act[N];\nint turn_count=0;\n\nvoid do_receive(){\n    for(int i=0;i<N;i++){\n        if(recv_idx[i]>=N) continue;\n        if(grid[i][0]!=-1) continue;\n        bool blocked=false;\n        for(int c=0;c<N;c++){\n            if(calive[c]&&cr[c]==i&&cc[c]==0&&ch[c]!=-1){blocked=true;break;}\n        }\n        if(!blocked){\n            grid[i][0]=A[i][recv_idx[i]];\n            recv_idx[i]++;\n        }\n    }\n}\n\nvoid do_dispatch(){\n    for(int i=0;i<N;i++){\n        if(grid[i][N-1]!=-1){\n            grid[i][N-1]=-1;\n        }\n    }\n}\n\nvoid do_turn(string s){\n    do_receive();\n    for(int i=0;i<N;i++){\n        char c=s[i];\n        act[i]+=c;\n        if(!calive[i]) continue;\n        switch(c){\n            case 'P': ch[i]=grid[cr[i]][cc[i]]; grid[cr[i]][cc[i]]=-1; break;\n            case 'Q': grid[cr[i]][cc[i]]=ch[i]; ch[i]=-1; break;\n            case 'U': cr[i]--; break;\n            case 'D': cr[i]++; break;\n            case 'L': cc[i]--; break;\n            case 'R': cr[i]++; break; // BUG: should be cc[i]++\n            case 'B': calive[i]=false; cbombed[i]=true; break;\n            case '.': break;\n        }\n    }\n    do_dispatch();\n    turn_count++;\n}\n\n// Actually let me rewrite from scratch more carefully\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    int n; cin>>n;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>A[i][j];\n    \n    memset(grid,-1,sizeof(grid));\n    memset(cbombed,0,sizeof(cbombed));\n    for(int i=0;i<N;i++){cr[i]=i;cc[i]=0;ch[i]=-1;calive[i]=true;}\n    for(int i=0;i<N;i++){recv_idx[i]=0;next_disp[i]=i*N;}\n    \n    // Precompute: where is each container in the input?\n    int cont_row[25], cont_idx[25]; // container c is at A[cont_row[c]][cont_idx[c]]\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        cont_row[A[i][j]]=i;\n        cont_idx[A[i][j]]=j;\n    }\n    \n    // Simulation functions\n    auto crane_at=[&](int r,int c)->int{\n        for(int k=0;k<N;k++) if(calive[k]&&cr[k]==r&&cc[k]==c) return k;\n        return -1;\n    };\n    \n    auto find_container=[&](int id)->pair<int,int>{\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(grid[i][j]==id)return{i,j};\n        // Check if held by crane\n        for(int k=0;k<N;k++) if(calive[k]&&ch[k]==id) return{-2,-2};\n        return{-1,-1};\n    };\n    \n    auto sim_turn=[&](string s){\n        // Validate and execute\n        do_receive();\n        for(int i=0;i<N;i++){\n            char c=s[i];\n            act[i]+=c;\n            if(!calive[i]) continue;\n            switch(c){\n                case 'P': ch[i]=grid[cr[i]][cc[i]]; grid[cr[i]][cc[i]]=-1; break;\n                case 'Q': grid[cr[i]][cc[i]]=ch[i]; ch[i]=-1; break;\n                case 'U': cr[i]--; break;\n                case 'D': cr[i]++; break;\n                case 'L': cc[i]--; break;\n                case 'R': cc[i]++; break;\n                case 'B': calive[i]=false; cbombed[i]=true; break;\n                case '.': break;\n            }\n        }\n        do_dispatch();\n        turn_count++;\n    };\n    \n    // Strategy: bomb small cranes, use large crane efficiently\n    // But try to optimize the delivery order\n    \n    // Bomb small cranes\n    {\n        string s(N,'.');\n        for(int i=1;i<N;i++) s[i]='B';\n        sim_turn(s);\n    }\n    \n    // BFS for crane 0 (large crane, can move over containers)\n    auto bfs=[&](int sr,int sc,int tr,int tc)->vector<char>{\n        if(sr==tr&&sc==tc) return {};\n        int dist[N][N]; memset(dist,-1,sizeof(dist));\n        int pdir[N][N];\n        dist[sr][sc]=0;\n        queue<pair<int,int>> q;\n        q.push({sr,sc});\n        int dr[]={-1,1,0,0};\n        int dc[]={0,0,-1,1};\n        char dm[]={'U','D','L','R'};\n        while(!q.empty()){\n            auto[r,c]=q.front();q.pop();\n            if(r==tr&&c==tc) break;\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||dist[nr][nc]!=-1) continue;\n                dist[nr][nc]=dist[r][c]+1;\n                pdir[nr][nc]=d;\n                q.push({nr,nc});\n            }\n        }\n        if(dist[tr][tc]==-1) return {'X'};\n        vector<char> path;\n        int r=tr,c=tc;\n        while(r!=sr||c!=sc){\n            int d=pdir[r][c];\n            path.push_back(dm[d]);\n            r-=dr[d];c-=dc[d];\n        }\n        reverse(path.begin(),path.end());\n        return path;\n    };\n    \n    auto move0=[&](char c){\n        string s(N,'.');\n        s[0]=c;\n        sim_turn(s);\n    };\n    \n    auto move0_to=[&](int tr,int tc){\n        auto path=bfs(cr[0],cc[0],tr,tc);\n        for(char c:path) move0(c);\n    };\n    \n    auto find_empty=[&](int pref_r,int pref_c,bool avoid_dispatch=true)->pair<int,int>{\n        int best_d=1000,br=-1,bc=-1;\n        for(int i=0;i<N;i++)for(int j=0;j<(avoid_dispatch?N-1:N);j++){\n            if(grid[i][j]!=-1) continue;\n            if(crane_at(i,j)!=-1) continue;\n            int d=abs(i-pref_r)+abs(j-pref_c);\n            if(d<best_d){best_d=d;br=i;bc=j;}\n        }\n        return{br,bc};\n    };\n    \n    // Main loop: deliver containers\n    // Better scheduling: compute cost for each deliverable container and pick cheapest\n    \n    int max_turns=9500;\n    int total_delivered=0;\n    \n    while(turn_count<max_turns && total_delivered<N*N){\n        // Find all containers on grid that are \"next needed\" at some dispatch gate\n        struct Candidate {\n            int id, r, c, target_row;\n            int cost;\n        };\n        vector<Candidate> cands;\n        \n        for(int row=0;row<N;row++){\n            int need=next_disp[row];\n            if(need>=row*N+N) continue;\n            auto [r,c]=find_container(need);\n            if(r<0) continue; // not on grid or held\n            int cost=abs(cr[0]-r)+abs(cc[0]-c) + abs(r-row)+(N-1-c);\n            cands.push_back({need,r,c,row,cost});\n        }\n        \n        if(!cands.empty()){\n            // Pick cheapest\n            sort(cands.begin(),cands.end(),[](auto&a,auto&b){return a.cost<b.cost;});\n            auto& best=cands[0];\n            \n            // Go pick up\n            move0_to(best.r,best.c);\n            if(cr[0]==best.r&&cc[0]==best.c&&grid[cr[0]][cc[0]]==best.id){\n                move0('P');\n                \n                int tr=best.target_row, tc=N-1;\n                move0_to(tr,tc);\n                \n                if(grid[cr[0]][cc[0]]==-1){\n                    move0('Q');\n                    next_disp[tr]++;\n                    total_delivered++;\n                } else {\n                    // Wait for dispatch\n                    move0('.');\n                    if(grid[cr[0]][cc[0]]==-1){\n                        move0('Q');\n                        next_disp[tr]++;\n                        total_delivered++;\n                    } else {\n                        // Drop in buffer near target\n                        auto [er,ec]=find_empty(tr,2);\n                        if(er>=0){\n                            move0_to(er,ec);\n                            move0('Q');\n                        } else {\n                            auto [er2,ec2]=find_empty(cr[0],cc[0],false);\n                            if(er2>=0){\n                                move0_to(er2,ec2);\n                                move0('Q');\n                                if(er2==tr&&ec2==N-1){next_disp[tr]++;total_delivered++;}\n                            }\n                        }\n                    }\n                }\n                continue;\n            }\n        }\n        \n        // No ready containers - move containers from receiving gates to buffer\n        bool did_something=false;\n        \n        // Find container on grid closest to crane to move to buffer\n        int best_d=1000,bi=-1,bj=-1;\n        for(int i=0;i<N;i++){\n            if(grid[i][0]!=-1){\n                int d=abs(cr[0]-i)+abs(cc[0]-0);\n                if(d<best_d){best_d=d;bi=i;bj=0;}\n            }\n        }\n        \n        if(bi>=0){\n            move0_to(bi,bj);\n            if(cr[0]==bi&&cc[0]==bj&&grid[bi][bj]!=-1){\n                int cid=grid[bi][bj];\n                move0('P');\n                // Place near target row\n                int trow=cid/N;\n                auto [er,ec]=find_empty(trow,2);\n                if(er>=0){\n                    move0_to(er,ec);\n                    move0('Q');\n                    if(er==trow&&ec==N-1){next_disp[trow]++;total_delivered++;}\n                    did_something=true;\n                } else {\n                    auto [er2,ec2]=find_empty(cr[0],cc[0],false);\n                    if(er2>=0){\n                        move0_to(er2,ec2);\n                        move0('Q');\n                        if(er2==cid/N&&ec2==N-1){next_disp[cid/N]++;total_delivered++;}\n                        did_something=true;\n                    }\n                }\n            }\n        }\n        \n        if(!did_something){\n            move0('.');\n        }\n    }\n    \n    int maxlen=0;\n    for(int i=0;i<N;i++) maxlen=max(maxlen,(int)act[i].size());\n    for(int i=0;i<N;i++) while((int)act[i].size()<maxlen) act[i]+=\".\";\n    for(int i=0;i<N;i++) cout<<act[i]<<\"\\n\";\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\nvector<string> ops;\nint cx, cy, cur_load;\n\nvoid move_to(int tx, int ty) {\n    while(cy < ty) { ops.push_back(\"D\"); cy++; }\n    while(cy > ty) { ops.push_back(\"U\"); cy--; }\n    while(cx < tx) { ops.push_back(\"R\"); cx++; }\n    while(cx > tx) { ops.push_back(\"L\"); cx--; }\n}\n\nint mdist(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\n\nint main(){\n    scanf(\"%d\", &N);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) scanf(\"%d\",&h[i][j]);\n    \n    cx=0; cy=0; cur_load=0;\n    \n    while(true) {\n        // Find nearest positive cell from current position\n        int best_d = INT_MAX, bx=-1, by=-1;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            if(h[i][j]>0){\n                int d = mdist(cx,cy,j,i);\n                if(d < best_d){ best_d=d; bx=j; by=i; }\n            }\n        }\n        if(bx==-1) break;\n        \n        // Move to nearest source and pick up\n        move_to(bx, by);\n        int amt = h[by][bx];\n        ops.push_back(\"+\"+to_string(amt));\n        h[by][bx] = 0;\n        cur_load += amt;\n        \n        // Also pick up from very nearby sources (distance <= 3)\n        bool found = true;\n        while(found && cur_load < 200) {\n            found = false;\n            int bd2=4, bx2=-1,by2=-1;\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n                if(h[i][j]>0){\n                    int d=mdist(cx,cy,j,i);\n                    if(d<bd2){bd2=d;bx2=j;by2=i;found=true;}\n                }\n            }\n            if(found && bx2!=-1){\n                move_to(bx2,by2);\n                ops.push_back(\"+\"+to_string(h[by2][bx2]));\n                cur_load+=h[by2][bx2];\n                h[by2][bx2]=0;\n            }\n        }\n        \n        // Deliver to nearest negative cells until empty\n        while(cur_load > 0){\n            int bd=INT_MAX, dx=-1,dy=-1;\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n                if(h[i][j]<0){\n                    int d=mdist(cx,cy,j,i);\n                    if(d<bd){bd=d;dx=j;dy=i;}\n                }\n            }\n            if(dx==-1) break;\n            move_to(dx,dy);\n            int unload=min(cur_load,-h[dy][dx]);\n            ops.push_back(\"-\"+to_string(unload));\n            h[dy][dx]+=unload;\n            cur_load-=unload;\n        }\n    }\n    \n    for(auto& s : ops) printf(\"%s\\n\", s.c_str());\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <cstring>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,T;\n    cin>>N>>M>>T;\n    int SC=2*N*(N-1);\n    vector<vector<int>>X(SC,vector<int>(M));\n    for(int i=0;i<SC;i++) for(int j=0;j<M;j++) cin>>X[i][j];\n    mt19937 rng(42);\n    \n    for(int t=0;t<T;t++){\n        auto t0=chrono::steady_clock::now();\n        double tlimit=0.17;\n        \n        vector<int> maxV(M,0);\n        for(int i=0;i<SC;i++) for(int l=0;l<M;l++) maxV[l]=max(maxV[l],X[i][l]);\n        \n        // Compute pairwise edge value for all seed pairs: sum_l max(x[a][l], x[b][l])\n        // Pick best pair as \"core edge\", then build grid around it\n        \n        // Score seeds by total value\n        vector<int> vals(SC,0);\n        for(int i=0;i<SC;i++) for(int l=0;l<M;l++) vals[i]+=X[i][l];\n        \n        // Select seeds: must include seeds with criterion maxima\n        vector<bool> mustInclude(SC,false);\n        for(int l=0;l<M;l++){\n            int best=-1;\n            for(int i=0;i<SC;i++) if(X[i][l]==maxV[l]){\n                if(best<0||vals[i]>vals[best]) best=i;\n            }\n            mustInclude[best]=true;\n        }\n        \n        vector<int> sel;\n        for(int i=0;i<SC;i++) if(mustInclude[i]) sel.push_back(i);\n        \n        vector<int> idx(SC); iota(idx.begin(),idx.end(),0);\n        sort(idx.begin(),idx.end(),[&](int a,int b){return vals[a]>vals[b];});\n        for(int i:idx){\n            if((int)sel.size()>=N*N) break;\n            if(!mustInclude[i]) sel.push_back(i);\n        }\n        sel.resize(N*N);\n        \n        // Precompute edge values between selected seeds\n        int NN=N*N;\n        vector<vector<int>> ev(NN,vector<int>(NN,0));\n        for(int a=0;a<NN;a++) for(int b=a+1;b<NN;b++){\n            int s=0;\n            for(int l=0;l<M;l++) s+=max(X[sel[a]][l],X[sel[b]][l]);\n            ev[a][b]=ev[b][a]=s;\n        }\n        \n        // Grid edges\n        vector<pair<int,int>> edges;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            int p=i*N+j;\n            if(j+1<N) edges.push_back({p,i*N+j+1});\n            if(i+1<N) edges.push_back({p,(i+1)*N+j});\n        }\n        \n        vector<int> perm(NN); iota(perm.begin(),perm.end(),0);\n        \n        // Objective: maximize max edge value + alpha * sum edge values\n        auto compScore=[&](vector<int>&p)->pair<int,long long>{\n            int mx=0; long long sm=0;\n            for(auto&[a,b]:edges){int v=ev[p[a]][p[b]]; mx=max(mx,v); sm+=v;}\n            return {mx,sm};\n        };\n        auto [cmx,csm]=compScore(perm);\n        \n        int iter=0;\n        while(true){\n            if((++iter&2047)==0){if(chrono::duration<double>(chrono::steady_clock::now()-t0).count()>tlimit) break;}\n            int a=rng()%NN,b=rng()%NN; if(a==b) continue;\n            swap(perm[a],perm[b]);\n            auto [nmx,nsm]=compScore(perm);\n            double temp=30.0*max(0.0,1.0-chrono::duration<double>(chrono::steady_clock::now()-t0).count()/tlimit)+0.01;\n            double oldS=cmx*100.0+csm*0.1;\n            double newS=nmx*100.0+nsm*0.1;\n            if(newS>=oldS||(uniform_real_distribution<>()(rng)<exp((newS-oldS)/temp))){cmx=nmx;csm=nsm;}\n            else swap(perm[a],perm[b]);\n        }\n        for(int i=0;i<N;i++){for(int j=0;j<N;j++){if(j) cout<<' ';cout<<sel[perm[i*N+j]];}cout<<'\\n';}\n        cout.flush();\n        for(int i=0;i<SC;i++) for(int j=0;j<M;j++) cin>>X[i][j];\n    }\n}","ahc038":"#include<bits/stdc++.h>\nusing namespace std;\n\nvector<int> hungarian(const vector<vector<int>>& cost){\n    int n=cost.size(),m=cost[0].size();\n    vector<int>u(n+1),v(m+1),p(m+1),way(m+1);\n    for(int i=1;i<=n;i++){\n        p[0]=i;int j0=0;\n        vector<int>minv(m+1,INT_MAX);\n        vector<bool>used(m+1,false);\n        do{\n            used[j0]=true;int i0=p[j0],delta=INT_MAX,j1=-1;\n            for(int j=1;j<=m;j++)if(!used[j]){\n                int cur=cost[i0-1][j-1]-u[i0]-v[j];\n                if(cur<minv[j]){minv[j]=cur;way[j]=j0;}\n                if(minv[j]<delta){delta=minv[j];j1=j;}\n            }\n            for(int j=0;j<=m;j++)if(used[j]){u[p[j]]+=delta;v[j]-=delta;}else minv[j]-=delta;\n            j0=j1;\n        }while(p[j0]!=0);\n        do{int j1=way[j0];p[j0]=p[j1];j0=j1;}while(j0);\n    }\n    vector<int>ans(n);\n    for(int j=1;j<=m;j++)if(p[j])ans[p[j]-1]=j-1;\n    return ans;\n}\n\nint main(){\n    int N,M,V;scanf(\"%d%d%d\",&N,&M,&V);\n    vector<string>s(N),t(N);\n    for(int i=0;i<N;i++)cin>>s[i];\n    for(int i=0;i<N;i++)cin>>t[i];\n    vector<pair<int,int>>src,tgt;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(s[i][j]=='1'&&t[i][j]=='0')src.push_back({i,j});\n        if(s[i][j]=='0'&&t[i][j]=='1')tgt.push_back({i,j});\n    }\n    int K=src.size();\n    \n    vector<int>match_arr;\n    if(K>0){\n        vector<vector<int>>cost(K,vector<int>(K));\n        for(int i=0;i<K;i++)for(int j=0;j<K;j++)\n            cost[i][j]=abs(src[i].first-tgt[j].first)+abs(src[i].second-tgt[j].second);\n        match_arr=hungarian(cost);\n    }\n    \n    // Simple arm: root + 1 leaf\n    printf(\"2\\n0 1\\n0 0\\n\");\n    \n    int rx=0,ry=0,dir=0;\n    int dx[]={0,1,0,-1},dy[]={1,0,-1,0};\n    vector<string>ops;\n    \n    // Compute trip cost: travel from (fx,fy) to pick src[i], deliver to tgt[match[i]], return end pos\n    auto tripCost=[&](int fx,int fy,int i)->int{\n        auto[sx,sy]=src[i];auto[tx,ty]=tgt[match_arr[i]];\n        return abs(fx-sx)+abs(fy-sy)+abs(sx-tx)+abs(sy-ty)+2+2; // approx\n    };\n    \n    // Greedy nearest neighbor TSP\n    vector<bool>done(K,false);\n    vector<int>order;\n    int cx=0,cy=0;\n    for(int i=0;i<K;i++){\n        int best=-1,bd=1e9;\n        for(int j=0;j<K;j++)if(!done[j]){\n            int d=abs(src[j].first-cx)+abs(src[j].second-cy)\n                  +abs(src[j].first-tgt[match_arr[j]].first)+abs(src[j].second-tgt[match_arr[j]].second);\n            if(d<bd){bd=d;best=j;}\n        }\n        done[best]=true;\n        order.push_back(best);\n        cx=tgt[match_arr[best]].first;\n        cy=tgt[match_arr[best]].second;\n    }\n    \n    // 2-opt improvement\n    // cost of ordering: sum of travel from end of trip[i] to start of trip[i+1]\n    auto seqCost=[&](vector<int>&ord)->int{\n        int c=0;\n        int px=0,py=0;\n        for(int idx=0;idx<K;idx++){\n            int i=ord[idx];\n            auto[sx,sy]=src[i];auto[tx,ty]=tgt[match_arr[i]];\n            c+=abs(px-sx)+abs(py-sy)+abs(sx-tx)+abs(sy-ty);\n            px=tx;py=ty;\n        }\n        return c;\n    };\n    \n    // Segment cost from position to through segment [l,r]\n    auto segStart=[&](int idx,int px,int py)->pair<int,pair<int,int>>{\n        int i=order[idx];\n        auto[sx,sy]=src[i];auto[tx,ty]=tgt[match_arr[i]];\n        int c=abs(px-sx)+abs(py-sy)+abs(sx-tx)+abs(sy-ty);\n        return {c,{tx,ty}};\n    };\n    \n    // 2-opt\n    auto startTime=chrono::steady_clock::now();\n    bool improved=true;\n    while(improved){\n        improved=false;\n        auto now=chrono::steady_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-startTime).count()>1500) break;\n        for(int i=0;i<K-1&&!improved;i++){\n            for(int j=i+1;j<K;j++){\n                // Try reversing segment [i,j]\n                // Current cost through segment\n                auto now2=chrono::steady_clock::now();\n                if(chrono::duration_cast<chrono::milliseconds>(now2-startTime).count()>1500) goto done2;\n                \n                // Get position before i\n                // This is expensive to compute naively, let's precompute\n                // Simple: just try swap and compare\n                reverse(order.begin()+i,order.begin()+j+1);\n                int newC=seqCost(order);\n                reverse(order.begin()+i,order.begin()+j+1);\n                int oldC=seqCost(order);\n                if(newC<oldC){\n                    reverse(order.begin()+i,order.begin()+j+1);\n                    improved=true;\n                    break;\n                }\n            }\n        }\n    }\n    done2:\n    \n    // Also try swapping match assignments with 2-opt on matching\n    // (swap targets between two sources if it reduces total cost)\n    improved=true;\n    while(improved){\n        improved=false;\n        auto now=chrono::steady_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-startTime).count()>2200) break;\n        for(int i=0;i<K&&!improved;i++){\n            for(int j=i+1;j<K;j++){\n                auto now2=chrono::steady_clock::now();\n                if(chrono::duration_cast<chrono::milliseconds>(now2-startTime).count()>2200) goto done3;\n                int oldC=abs(src[i].first-tgt[match_arr[i]].first)+abs(src[i].second-tgt[match_arr[i]].second)\n                        +abs(src[j].first-tgt[match_arr[j]].first)+abs(src[j].second-tgt[match_arr[j]].second);\n                int newC=abs(src[i].first-tgt[match_arr[j]].first)+abs(src[i].second-tgt[match_arr[j]].second)\n                        +abs(src[j].first-tgt[match_arr[i]].first)+abs(src[j].second-tgt[match_arr[i]].second);\n                if(newC<oldC){\n                    swap(match_arr[i],match_arr[j]);\n                    improved=true;break;\n                }\n            }\n        }\n    }\n    done3:\n    \n    // Redo TSP ordering after match changes\n    fill(done.begin(),done.end(),false);\n    order.clear();\n    cx=0;cy=0;\n    for(int i=0;i<K;i++){\n        int best=-1,bd=1e9;\n        for(int j=0;j<K;j++)if(!done[j]){\n            int d=abs(src[j].first-cx)+abs(src[j].second-cy);\n            if(d<bd){bd=d;best=j;}\n        }\n        done[best]=true;\n        order.push_back(best);\n        cx=tgt[match_arr[best]].first;\n        cy=tgt[match_arr[best]].second;\n    }\n    \n    // 2-opt again\n    improved=true;\n    while(improved){\n        improved=false;\n        auto now=chrono::steady_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-startTime).count()>2700) break;\n        for(int i=0;i<K-1&&!improved;i++){\n            for(int j=i+1;j<K;j++){\n                auto now2=chrono::steady_clock::now();\n                if(chrono::duration_cast<chrono::milliseconds>(now2-startTime).count()>2700) goto done4;\n                reverse(order.begin()+i,order.begin()+j+1);\n                int newC=seqCost(order);\n                reverse(order.begin()+i,order.begin()+j+1);\n                int oldC=seqCost(order);\n                if(newC<oldC){\n                    reverse(order.begin()+i,order.begin()+j+1);\n                    improved=true;break;\n                }\n            }\n        }\n    }\n    done4:\n    \n    // Execute\n    auto emitTurn=[&](char mv, char rc, bool pick){\n        string o=\"....\";\n        o[0]=mv;o[1]=rc;o[3]=pick?'P':'.';\n        ops.push_back(o);\n    };\n    \n    for(int idx=0;idx<K;idx++){\n        int si=order[idx],ti=match_arr[si];\n        auto[sx,sy]=src[si];auto[tx,ty]=tgt[ti];\n        \n        auto bestDir=[&](int px,int py,int ntx,int nty)->int{\n            int best=0,bd=1e9;\n            for(int d=0;d<4;d++){\n                int nx=px-dx[d],ny=py-dy[d];\n                if(nx>=0&&nx<N&&ny>=0&&ny<N){\n                    int cost=abs(nx-rx)+abs(ny-ry)+((d!=dir)?1:0)+abs(ntx-nx)+abs(nty-ny);\n                    if(cost<bd){bd=cost;best=d;}\n                }\n            }\n            return best;\n        };\n        \n        int sd=bestDir(sx,sy,tx,ty);\n        int gx=sx-dx[sd],gy=sy-dy[sd];\n        while(rx!=gx||ry!=gy||dir!=sd){\n            char mc='.';char rc='.';\n            if(dir!=sd){int r=(sd-dir+4)%4;if(r<=2){rc='R';dir=(dir+1)%4;}else{rc='L';dir=(dir+3)%4;}}\n            if(rx<gx){mc='D';rx++;}else if(rx>gx){mc='U';rx--;}else if(ry<gy){mc='R';ry++;}else if(ry>gy){mc='L';ry--;}\n            emitTurn(mc,rc,false);\n        }\n        emitTurn('.','.', true);\n        \n        // Next source after this\n        int nsx=0,nsy=0;\n        if(idx+1<K){nsx=src[order[idx+1]].first;nsy=src[order[idx+1]].second;}\n        \n        int td=bestDir(tx,ty,nsx,nsy);\n        gx=tx-dx[td];gy=ty-dy[td];\n        while(rx!=gx||ry!=gy||dir!=td){\n            char mc='.';char rc='.';\n            if(dir!=td){int r=(td-dir+4)%4;if(r<=2){rc='R';dir=(dir+1)%4;}else{rc='L';dir=(dir+3)%4;}}\n            if(rx<gx){mc='D';rx++;}else if(rx>gx){mc='U';rx--;}else if(ry<gy){mc='R';ry++;}else if(ry>gy){mc='L';ry--;}\n            emitTurn(mc,rc,false);\n        }\n        emitTurn('.','.', true);\n    }\n    for(auto&o:ops)printf(\"%s\\n\",o.c_str());\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N; cin>>N;\n    vector<int> fx(2*N), fy(2*N);\n    for(int i=0;i<2*N;i++) cin>>fx[i]>>fy[i];\n    \n    const int MX = 100000;\n    const int G = 350;\n    double step = (double)MX / G;\n    \n    vector<vector<int>> val(G, vector<int>(G, 0));\n    for(int i=0;i<2*N;i++){\n        int gx = min((int)(fx[i]/step), G-1);\n        int gy = min((int)(fy[i]/step), G-1);\n        val[gx][gy] += (i < N) ? 1 : -1;\n    }\n    \n    int best = INT_MIN, bx1=0,bx2=G-1,by1=0,by2=G-1;\n    for(int lx=0;lx<G;lx++){\n        vector<int> colsum(G,0);\n        for(int rx=lx;rx<G;rx++){\n            for(int gy=0;gy<G;gy++) colsum[gy]+=val[rx][gy];\n            int cur=0, start=0;\n            for(int gy=0;gy<G;gy++){\n                cur+=colsum[gy];\n                if(cur>best){best=cur;bx1=lx;bx2=rx;by1=start;by2=gy;}\n                if(cur<0){cur=0;start=gy+1;}\n            }\n        }\n    }\n    \n    int rx1 = max(0, (int)(bx1*step) - 1);\n    int rx2 = min(MX, (int)((bx2+1)*step) + 1);\n    int ry1 = max(0, (int)(by1*step) - 1);\n    int ry2 = min(MX, (int)((by2+1)*step) + 1);\n    \n    // Fast boundary refinement using prefix sums\n    // Sort fish by x, then by y for efficient counting\n    // For each candidate x1, count mackerels and sardines with x >= x1, x <= rx2, y in [ry1,ry2]\n    {\n        // Collect fish in broad region\n        struct FishInfo { int x, y, w; };\n        vector<FishInfo> fish;\n        for(int i=0;i<2*N;i++){\n            fish.push_back({fx[i], fy[i], (i<N)?1:-1});\n        }\n        \n        // Try adjusting boundaries using fish coordinates\n        // For left boundary: sort by x, sweep\n        auto inRect = [&](int x1, int y1, int x2, int y2, int i) -> bool {\n            return fx[i]>=x1 && fx[i]<=x2 && fy[i]>=y1 && fy[i]<=y2;\n        };\n        \n        // Compute base score\n        int baseS = 0;\n        for(int i=0;i<2*N;i++)\n            if(inRect(rx1,ry1,rx2,ry2,i)) baseS += (i<N)?1:-1;\n        \n        // Try moving left boundary right: fish sorted by x\n        // Fish with x in [rx1, rx2] and y in [ry1, ry2], sorted by x\n        vector<pair<int,int>> leftFish; // (x, w)\n        for(int i=0;i<2*N;i++){\n            if(fx[i]>=rx1 && fx[i]<=rx2 && fy[i]>=ry1 && fy[i]<=ry2)\n                leftFish.push_back({fx[i], (i<N)?1:-1});\n        }\n        sort(leftFish.begin(), leftFish.end());\n        \n        int bestS = baseS;\n        int cumW = 0;\n        int prevX = rx1;\n        for(int j=0;j<(int)leftFish.size();j++){\n            // Try x1 = leftFish[j].first + 1 (exclude this fish)\n            // But only if this fish is a sardine\n            cumW += leftFish[j].second;\n            if(baseS - cumW > bestS){\n                bestS = baseS - cumW;\n                rx1 = leftFish[j].first + 1;\n            }\n        }\n        \n        // Recompute base\n        baseS = bestS;\n        \n        // Try moving right boundary left\n        vector<pair<int,int>> rightFish;\n        for(int i=0;i<2*N;i++){\n            if(fx[i]>=rx1 && fx[i]<=rx2 && fy[i]>=ry1 && fy[i]<=ry2)\n                rightFish.push_back({fx[i], (i<N)?1:-1});\n        }\n        sort(rightFish.begin(), rightFish.end());\n        \n        cumW = 0;\n        for(int j=(int)rightFish.size()-1;j>=0;j--){\n            cumW += rightFish[j].second;\n            if(baseS - cumW > bestS){\n                bestS = baseS - cumW;\n                rx2 = rightFish[j].first - 1;\n            }\n        }\n        baseS = bestS;\n        \n        // Try moving top boundary down\n        vector<pair<int,int>> topFish;\n        for(int i=0;i<2*N;i++){\n            if(fx[i]>=rx1 && fx[i]<=rx2 && fy[i]>=ry1 && fy[i]<=ry2)\n                topFish.push_back({fy[i], (i<N)?1:-1});\n        }\n        sort(topFish.begin(), topFish.end());\n        \n        cumW = 0;\n        for(int j=(int)topFish.size()-1;j>=0;j--){\n            cumW += topFish[j].second;\n            if(baseS - cumW > bestS){\n                bestS = baseS - cumW;\n                ry2 = topFish[j].first - 1;\n            }\n        }\n        baseS = bestS;\n        \n        // Try moving bottom boundary up\n        vector<pair<int,int>> botFish;\n        for(int i=0;i<2*N;i++){\n            if(fx[i]>=rx1 && fx[i]<=rx2 && fy[i]>=ry1 && fy[i]<=ry2)\n                botFish.push_back({fy[i], (i<N)?1:-1});\n        }\n        sort(botFish.begin(), botFish.end());\n        \n        cumW = 0;\n        for(int j=0;j<(int)botFish.size();j++){\n            cumW += botFish[j].second;\n            if(baseS - cumW > bestS){\n                bestS = baseS - cumW;\n                ry1 = botFish[j].first + 1;\n            }\n        }\n    }\n    \n    // Now try strip-based optimization\n    // Collect fish inside rectangle, sorted by y\n    struct Fish { int x, y, w; };\n    vector<Fish> inside;\n    for(int i=0;i<2*N;i++){\n        if(fx[i]>=rx1 && fx[i]<=rx2 && fy[i]>=ry1 && fy[i]<=ry2)\n            inside.push_back({fx[i], fy[i], (i<N)?1:-1});\n    }\n    sort(inside.begin(), inside.end(), [](const Fish&a, const Fish&b){ return a.y < b.y; });\n    \n    // Divide into ~120 strips (gives ~480 vertices + 4 base \u2248 484)\n    int nStrips = min(120, max(1, (int)inside.size()/10));\n    int fishPerStrip = max(1, (int)inside.size() / nStrips);\n    \n    struct Strip { int y1, y2, xl, xr; };\n    vector<Strip> strips;\n    \n    int fi = 0;\n    while(fi < (int)inside.size()){\n        int end = min(fi + fishPerStrip, (int)inside.size());\n        // Ensure we don't split fish with same y\n        while(end < (int)inside.size() && inside[end].y == inside[end-1].y) end++;\n        \n        int sy1 = (fi == 0) ? ry1 : (inside[fi-1].y + inside[fi].y) / 2 + 1;\n        int sy2 = (end >= (int)inside.size()) ? ry2 : (inside[end-1].y + inside[end].y) / 2;\n        \n        if(strips.empty()) sy1 = ry1;\n        \n        // Collect strip fish\n        vector<pair<int,int>> sf;\n        for(int j=fi;j<end;j++) sf.push_back({inside[j].x, inside[j].w});\n        sort(sf.begin(), sf.end());\n        \n        int totalW = 0;\n        for(auto&[x,w]:sf) totalW += w;\n        int bestW = totalW, bestXL = rx1, bestXR = rx2;\n        \n        // Try trim left\n        int cumW = 0;\n        for(int j=0;j<(int)sf.size();j++){\n            cumW += sf[j].second;\n            if(totalW - cumW > bestW){\n                bestW = totalW - cumW;\n                bestXL = sf[j].first + 1;\n                bestXR = rx2;\n            }\n        }\n        \n        // Try trim right\n        cumW = 0;\n        for(int j=(int)sf.size()-1;j>=0;j--){\n            cumW += sf[j].second;\n            if(totalW - cumW > bestW){\n                bestW = totalW - cumW;\n                bestXR = sf[j].first - 1;\n                bestXL = rx1;\n            }\n        }\n        \n        // Try trim both (Kadane's on x)\n        // Find max subarray\n        if(sf.size() > 0){\n            int maxSum = 0, curSum = 0;\n            int sBest = -1, sStart = 0, sEnd = -1;\n            for(int j=0;j<(int)sf.size();j++){\n                curSum += sf[j].second;\n                if(curSum > maxSum){\n                    maxSum = curSum;\n                    sBest = maxSum;\n                    sEnd = j;\n                    sBest = maxSum; // redundant but clear\n                }\n                if(curSum < 0){ curSum = 0; sStart = j+1; }\n            }\n            // Recompute to get sStart\n            curSum = 0; maxSum = 0; sStart = 0;\n            int finalStart = 0, finalEnd = 0;\n            for(int j=0;j<(int)sf.size();j++){\n                curSum += sf[j].second;\n                if(curSum > maxSum){\n                    maxSum = curSum;\n                    finalStart = sStart;\n                    finalEnd = j;\n                }\n                if(curSum < 0){ curSum = 0; sStart = j+1; }\n            }\n            if(maxSum > bestW){\n                bestW = maxSum;\n                bestXL = (finalStart > 0) ? sf[finalStart].first : rx1;\n                bestXR = (finalEnd < (int)sf.size()-1) ? sf[finalEnd].first : rx2;\n            }\n        }\n        \n        if(bestW >= totalW){\n            strips.push_back({sy1, sy2, bestXL, bestXR});\n        } else {\n            strips.push_back({sy1, sy2, rx1, rx2});\n        }\n        \n        fi = end;\n    }\n    \n    if(strips.empty()) strips.push_back({ry1, ry2, rx1, rx2});\n    strips.front().y1 = ry1;\n    strips.back().y2 = ry2;\n    \n    // Merge adjacent strips with same x-range\n    vector<Strip> merged;\n    for(auto&s:strips){\n        if(!merged.empty() && merged.back().xl==s.xl && merged.back().xr==s.xr){\n            merged.back().y2 = s.y2;\n        } else {\n            merged.push_back(s);\n        }\n    }\n    strips = merged;\n    \n    // Build polygon from strips (guaranteed non-self-intersecting)\n    // Each strip is [xl, xr] x [y1, y2]\n    // Ensure all xl <= xr, y1 <= y2\n    for(auto&s:strips){\n        s.xl = max(0, min(s.xl, rx2));\n        s.xr = max(s.xl, min(s.xr, MX));\n    }\n    \n    // Build right contour (top to bottom), then left contour (bottom to top)\n    vector<pair<int,int>> poly;\n    \n    // Top edge\n    poly.push_back({strips[0].xl, strips[0].y1});\n    poly.push_back({strips[0].xr, strips[0].y1});\n    \n    // Right side going down\n    for(int i=0;i<(int)strips.size();i++){\n        if(i > 0 && strips[i].xr != strips[i-1].xr){\n            poly.push_back({strips[i-1].xr, strips[i].y1});\n            poly.push_back({strips[i].xr, strips[i].y1});\n        }\n        poly.push_back({strips[i].xr, strips[i].y2});\n    }\n    \n    // Bottom-right to bottom-left\n    poly.push_back({strips.back().xl, strips.back().y2});\n    \n    // Left side going up\n    for(int i=(int)strips.size()-1;i>=0;i--){\n        if(i < (int)strips.size()-1 && strips[i].xl != strips[i+1].xl){\n            poly.push_back({strips[i+1].xl, strips[i].y2});\n            poly.push_back({strips[i].xl, strips[i].y2});\n        }\n        poly.push_back({strips[i].xl, strips[i].y1});\n    }\n    \n    // Remove consecutive duplicates\n    vector<pair<int,int>> cleaned;\n    for(auto&p:poly){\n        if(!cleaned.empty() && cleaned.back()==p) continue;\n        cleaned.push_back(p);\n    }\n    if(cleaned.size()>1 && cleaned.front()==cleaned.back()) cleaned.pop_back();\n    \n    // Remove collinear points\n    {\n        bool changed = true;\n        while(changed){\n            changed = false;\n            vector<pair<int,int>> res;\n            int n = cleaned.size();\n            for(int i=0;i<n;i++){\n                auto [px,py] = cleaned[(i+n-1)%n];\n                auto [cx,cy] = cleaned[i];\n                auto [nx,ny] = cleaned[(i+1)%n];\n                if((px==cx&&cx==nx)||(py==cy&&cy==ny)){\n                    changed = true;\n                } else {\n                    res.push_back(cleaned[i]);\n                }\n            }\n            cleaned = res;\n        }\n    }\n    \n    // Verify constraints\n    long long perim = 0;\n    int cn = cleaned.size();\n    bool valid = cn >= 4 && cn <= 1000;\n    for(int i=0;i<cn&&valid;i++){\n        int ni=(i+1)%cn;\n        int dx = abs(cleaned[i].first-cleaned[ni].first);\n        int dy = abs(cleaned[i].second-cleaned[ni].second);\n        if((dx>0)+(dy>0)!=1) valid=false;\n        perim += dx+dy;\n    }\n    if(perim>400000) valid=false;\n    \n    // Also output the simple rectangle as first solution\n    cout<<4<<\"\\n\";\n    cout<<rx1<<\" \"<<ry1<<\"\\n\";\n    cout<<rx2<<\" \"<<ry1<<\"\\n\";\n    cout<<rx2<<\" \"<<ry2<<\"\\n\";\n    cout<<rx1<<\" \"<<ry2<<\"\\n\";\n    \n    if(valid && cn>=4){\n        cout<<cn<<\"\\n\";\n        for(auto&[a,b]:cleaned) cout<<a<<\" \"<<b<<\"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include<bits/stdc++.h>\nusing namespace std;\n\nstruct Rect { long long x1,y1,x2,y2; };\nstruct Placement { int p,r; char d; int b; };\n\npair<long long,long long> simulate(const vector<Placement>& ops, const vector<long long>& w, const vector<long long>& h) {\n    int n = ops.size();\n    vector<Rect> rects(n);\n    long long maxX=0, maxY=0;\n    \n    for(int i=0;i<n;i++){\n        auto& op = ops[i];\n        long long wi = op.r ? h[op.p] : w[op.p];\n        long long hi = op.r ? w[op.p] : h[op.p];\n        long long x1,y1,x2,y2;\n        \n        if(op.d == 'U') {\n            if(op.b == -1) x1 = 0;\n            else {\n                // find rect for op.b\n                int bi = -1;\n                for(int j=0;j<i;j++) if(ops[j].p==op.b){bi=j;break;}\n                x1 = rects[bi].x2;\n            }\n            x2 = x1 + wi;\n            y1 = 0;\n            for(int j=0;j<i;j++){\n                if(rects[j].x1 < x2 && rects[j].x2 > x1)\n                    y1 = max(y1, rects[j].y2);\n            }\n            y2 = y1 + hi;\n        } else {\n            if(op.b == -1) y1 = 0;\n            else {\n                int bi = -1;\n                for(int j=0;j<i;j++) if(ops[j].p==op.b){bi=j;break;}\n                y1 = rects[bi].y2;\n            }\n            y2 = y1 + hi;\n            x1 = 0;\n            for(int j=0;j<i;j++){\n                if(rects[j].y1 < y2 && rects[j].y2 > y1)\n                    x1 = max(x1, rects[j].x2);\n            }\n            x2 = x1 + wi;\n        }\n        rects[i] = {x1,y1,x2,y2};\n        maxX = max(maxX, x2);\n        maxY = max(maxY, y2);\n    }\n    return {maxX, maxY};\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N,T,sigma;\n    cin>>N>>T>>sigma;\n    vector<long long> w(N),h(N);\n    for(int i=0;i<N;i++) cin>>w[i]>>h[i];\n    \n    vector<long long> ew(w), eh(h);\n    mt19937 rng(42);\n    \n    auto startTime = chrono::steady_clock::now();\n    auto elapsed = [&]() -> double {\n        return chrono::duration<double>(chrono::steady_clock::now()-startTime).count();\n    };\n    \n    auto evalOps = [&](const vector<Placement>& ops) -> long long {\n        auto [W,H] = simulate(ops, ew, eh);\n        return W + H;\n    };\n    \n    // Greedy construction with limited refs\n    auto genGreedy = [&](int maxRefs) -> vector<Placement> {\n        vector<Placement> ops;\n        for(int i=0;i<N;i++){\n            long long bestLocal = LLONG_MAX;\n            Placement bestOp{i,0,'U',-1};\n            \n            vector<int> refs;\n            refs.push_back(-1);\n            int start = max(0, (int)ops.size() - maxRefs);\n            for(int j=start;j<(int)ops.size();j++) refs.push_back(ops[j].p);\n            \n            for(int r=0;r<2;r++){\n                for(int dd=0;dd<2;dd++){\n                    char dir = dd?'U':'L';\n                    for(int b : refs){\n                        Placement op{i,r,dir,b};\n                        ops.push_back(op);\n                        long long score = evalOps(ops);\n                        if(score < bestLocal){\n                            bestLocal = score;\n                            bestOp = op;\n                        }\n                        ops.pop_back();\n                    }\n                }\n            }\n            ops.push_back(bestOp);\n        }\n        return ops;\n    };\n    \n    vector<Placement> bestOps = genGreedy(10);\n    long long bestScore = evalOps(bestOps);\n    \n    // Local search\n    auto localSearch = [&](vector<Placement>& ops, double timeLimit) {\n        long long curScore = evalOps(ops);\n        while(elapsed() < timeLimit) {\n            int idx = rng() % N;\n            Placement old = ops[idx];\n            \n            int r = rng()%2;\n            char d = (rng()%2)?'U':'L';\n            int b = -1;\n            if(idx > 0 && rng()%3 != 0) {\n                b = ops[rng() % idx].p;\n            }\n            ops[idx] = {ops[idx].p, r, d, b};\n            long long newScore = evalOps(ops);\n            if(newScore <= curScore) {\n                curScore = newScore;\n            } else {\n                ops[idx] = old;\n            }\n        }\n        if(curScore < bestScore) { bestScore=curScore; bestOps=ops; }\n    };\n    \n    double timePerTurn = 2.5 / T;\n    \n    for(int t=0; t<T; t++){\n        double tEnd = min(elapsed() + timePerTurn, 2.7);\n        \n        auto ops = bestOps;\n        localSearch(ops, tEnd);\n        \n        cout << bestOps.size() << \"\\n\";\n        for(auto& op : bestOps)\n            cout << op.p << \" \" << op.r << \" \" << op.d << \" \" << op.b << \"\\n\";\n        cout.flush();\n        long long W, H;\n        cin >> W >> H;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    \n    vector<int> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\n    \n    vector<vector<int>> adj(N);\n    for(int i=0;i<M;i++){\n        int u,v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++) cin >> x[i] >> y[i];\n    \n    // State: parent[v], depth[v]\n    vector<int> par(N, -1), dep(N, 0);\n    vector<vector<int>> children(N);\n    \n    auto calc_score = [&]() -> long long {\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    \n    // Greedy: sort vertices by beauty descending, try to place them deep\n    // BFS tree building from low-beauty roots\n    \n    // Sort vertices by A ascending (low beauty = good root candidates)\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){ return A[a] < A[b]; });\n    \n    vector<bool> used(N, false);\n    \n    for(int r : order){\n        if(used[r]) continue;\n        used[r] = true;\n        par[r] = -1; dep[r] = 0;\n        queue<int> q;\n        q.push(r);\n        while(!q.empty()){\n            int u = q.front(); q.pop();\n            if(dep[u] >= H) continue;\n            // Sort neighbors by A descending\n            vector<int> nbrs;\n            for(int v : adj[u]) if(!used[v]) nbrs.push_back(v);\n            sort(nbrs.begin(), nbrs.end(), [&](int a, int b){ return A[a] > A[b]; });\n            for(int v : nbrs){\n                if(used[v]) continue;\n                used[v] = true;\n                par[v] = u;\n                dep[v] = dep[u]+1;\n                children[u].push_back(v);\n                q.push(v);\n            }\n        }\n    }\n    \n    // Local search: try reparenting\n    auto get_subtree = [&](int v, auto& self) -> vector<int> {\n        vector<int> res = {v};\n        for(int c : children[v]){\n            auto sub = self(c, self);\n            res.insert(res.end(), sub.begin(), sub.end());\n        }\n        return res;\n    };\n    \n    auto update_depths = [&](int v, int d, auto& self) -> void {\n        dep[v] = d;\n        for(int c : children[v]) self(c, d+1, self);\n    };\n    \n    auto detach = [&](int v){\n        int p = par[v];\n        if(p == -1) return;\n        auto& ch = children[p];\n        ch.erase(find(ch.begin(), ch.end(), v));\n        par[v] = -1;\n        update_depths(v, 0, update_depths);\n    };\n    \n    auto max_depth_subtree = [&](int v, auto& self) -> int {\n        int mx = dep[v];\n        for(int c : children[v]) mx = max(mx, self(c, self));\n        return mx;\n    };\n    \n    auto subtree_score = [&](int v, auto& self) -> long long {\n        long long s = (long long)(dep[v]+1)*A[v];\n        for(int c : children[v]) s += self(c, self);\n        return s;\n    };\n    \n    // Build adjacency set for O(1) lookup\n    vector<set<int>> adjset(N);\n    for(int i=0;i<N;i++) for(int j : adj[i]) adjset[i].insert(j);\n    \n    long long best_score = calc_score();\n    vector<int> best_par = par;\n    \n    mt19937 rng(42);\n    \n    auto try_reparent = [&](int v, int new_par) -> long long {\n        // Check edge exists\n        if(!adjset[v].count(new_par)) return -1;\n        // Check new_par is not in subtree of v\n        int tmp = new_par;\n        while(tmp != -1){\n            if(tmp == v) return -1;\n            tmp = par[tmp];\n        }\n        // Check depth constraint\n        int subtree_depth = max_depth_subtree(v, max_depth_subtree) - dep[v];\n        int new_dep = dep[new_par] + 1;\n        if(new_dep + subtree_depth > H) return -1;\n        \n        long long old_sub = subtree_score(v, subtree_score);\n        // New score change\n        int depth_change = new_dep - dep[v];\n        // Calculate new subtree score\n        auto calc_delta = [&](int u, int dd, auto& self) -> long long {\n            long long d = (long long)dd * A[u];\n            for(int c : children[u]) d += self(c, dd, self);\n            return d;\n        };\n        long long delta = calc_delta(v, depth_change, calc_delta);\n        return delta;\n    };\n    \n    auto do_reparent = [&](int v, int new_par){\n        detach(v);\n        par[v] = new_par;\n        children[new_par].push_back(v);\n        int new_dep = dep[new_par] + 1;\n        int dd = new_dep - dep[v];\n        // Fix: dep[v] is already 0 after detach, recalculate\n        update_depths(v, new_dep, update_depths);\n    };\n    \n    // Simulated annealing\n    auto start_time = chrono::steady_clock::now();\n    double time_limit = 1.9;\n    long long cur_score = best_score;\n    \n    for(int iter = 0; ; iter++){\n        if(iter % 1000 == 0){\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if(elapsed > time_limit) break;\n        }\n        \n        int v = rng() % N;\n        // Try reparenting v to a random neighbor\n        if(adj[v].empty()) continue;\n        int ni = rng() % adj[v].size();\n        int new_p = adj[v][ni];\n        \n        long long delta = try_reparent(v, new_p);\n        if(delta > 0 || (delta == 0 && (int)(rng()%2)==0)){\n            int old_par = par[v];\n            do_reparent(v, new_p);\n            cur_score = calc_score();\n            if(cur_score > best_score){\n                best_score = cur_score;\n                best_par = par;\n            }\n        }\n    }\n    \n    for(int i=0;i<N;i++){\n        cout << best_par[i];\n        if(i<N-1) cout << ' ';\n    }\n    cout << '\\n';\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N;\n    cin>>N;\n    vector<string> board(N);\n    for(int i=0;i<N;i++) cin>>board[i];\n    \n    vector<pair<int,int>> onis;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(board[i][j]=='x') onis.push_back({i,j});\n    int nOni = onis.size();\n    \n    // Direction: 0=U, 1=D, 2=L, 3=R\n    // Group key: (dir, line) encoded as dir*N + line\n    int MAXG = 4*N;\n    \n    // valid options per oni: list of (group_id, dist)\n    vector<vector<pair<int,int>>> oniOpts(nOni);\n    \n    for(int idx=0;idx<nOni;idx++){\n        int r=onis[idx].first, c=onis[idx].second;\n        bool canU=true;\n        for(int i=0;i<r;i++) if(board[i][c]=='o'){canU=false;break;}\n        if(canU) oniOpts[idx].push_back({0*N+c, r+1});\n        bool canD=true;\n        for(int i=r+1;i<N;i++) if(board[i][c]=='o'){canD=false;break;}\n        if(canD) oniOpts[idx].push_back({1*N+c, N-r});\n        bool canL=true;\n        for(int j=0;j<c;j++) if(board[r][j]=='o'){canL=false;break;}\n        if(canL) oniOpts[idx].push_back({2*N+r, c+1});\n        bool canR=true;\n        for(int j=c+1;j<N;j++) if(board[r][j]=='o'){canR=false;break;}\n        if(canR) oniOpts[idx].push_back({3*N+r, N-c});\n    }\n    \n    // Assignment\n    vector<int> assign(nOni), assignDist(nOni);\n    // groupMaxCnt[g][d] = count of onis with that dist in group g\n    // groupMax[g] = current max dist in group g\n    // groupSize[g] = number of onis in group g\n    vector<array<int,22>> groupCnt(MAXG);\n    for(auto& a:groupCnt) a.fill(0);\n    vector<int> groupMax(MAXG, 0), groupSize(MAXG, 0);\n    \n    int totalCost = 0;\n    \n    auto addToGroup = [&](int g, int d) {\n        int oldMax = groupMax[g];\n        groupCnt[g][d]++;\n        groupSize[g]++;\n        if(d > oldMax) groupMax[g] = d;\n        totalCost += 2*(groupMax[g] - oldMax);\n    };\n    \n    auto removeFromGroup = [&](int g, int d) {\n        groupCnt[g][d]--;\n        groupSize[g]--;\n        if(groupSize[g]==0){\n            totalCost -= 2*groupMax[g];\n            groupMax[g]=0;\n            return;\n        }\n        int oldMax = groupMax[g];\n        if(d==oldMax && groupCnt[g][d]==0){\n            while(groupMax[g]>0 && groupCnt[g][groupMax[g]]==0) groupMax[g]--;\n            totalCost += 2*(groupMax[g]-oldMax);\n        }\n    };\n    \n    // Initial: pick cheapest direction per oni\n    for(int i=0;i<nOni;i++){\n        int bestD=INT_MAX, bestG=-1;\n        for(auto&[g,d]:oniOpts[i]) if(d<bestD){bestD=d;bestG=g;}\n        assign[i]=bestG; assignDist[i]=bestD;\n        addToGroup(bestG, bestD);\n    }\n    \n    // SA\n    mt19937 rng(42);\n    int bestCost = totalCost;\n    vector<int> bestAssign = assign;\n    \n    for(int iter=0;iter<5000000;iter++){\n        double temp = 30.0 * (1.0 - (double)iter/5000000);\n        int oni = rng() % nOni;\n        if(oniOpts[oni].size()<=1) continue;\n        int ci = rng() % oniOpts[oni].size();\n        auto [newG, newD] = oniOpts[oni][ci];\n        int oldG = assign[oni], oldD = assignDist[oni];\n        if(newG==oldG) continue;\n        \n        int oldCost = totalCost;\n        removeFromGroup(oldG, oldD);\n        addToGroup(newG, newD);\n        int delta = totalCost - oldCost;\n        \n        if(delta<=0 || (temp>0.01 && (double)(rng()%10000)/10000.0 < exp(-delta/temp))){\n            assign[oni]=newG; assignDist[oni]=newD;\n            if(totalCost<bestCost){bestCost=totalCost; bestAssign=assign;}\n        } else {\n            removeFromGroup(newG, newD);\n            addToGroup(oldG, oldD);\n        }\n    }\n    \n    // Reconstruct from bestAssign\n    string dirC=\"UDLR\", revC=\"DURL\";\n    map<int,int> gMax;\n    for(int i=0;i<nOni;i++){\n        int g=bestAssign[i], d=0;\n        for(auto&[gg,dd]:oniOpts[i]) if(gg==g){d=dd;break;}\n        gMax[g]=max(gMax[g],d);\n    }\n    \n    for(auto&[g,mx]:gMax){\n        int dir=g/N, line=g%N;\n        for(int k=0;k<mx;k++) cout<<dirC[dir]<<\" \"<<line<<\"\\n\";\n        for(int k=0;k<mx;k++) cout<<revC[dir]<<\" \"<<line<<\"\\n\";\n    }\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N, L;\n    scanf(\"%d%d\", &N, &L);\n    vector<int> T(N);\n    for(int i=0;i<N;i++) scanf(\"%d\", &T[i]);\n    \n    int a[100], b[100];\n    mt19937 rng(12345);\n    \n    // Flow-based initialization: node i sends ceil(T[i]/2) to a[i], floor(T[i]/2) to b[i]\n    // We have \"half-flows\" to assign to targets\n    // Greedily assign: maintain deficit[j] = T[j] - assigned_incoming[j]\n    vector<int> deficit(N);\n    for(int i=0;i<N;i++) deficit[i] = T[i];\n    \n    // Sort nodes by T descending for greedy assignment\n    vector<int> order(N); iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),[&](int x,int y){return T[x]>T[y];});\n    \n    for(int i : order){\n        int ha = (T[i]+1)/2, hb = T[i]/2;\n        // Assign a[i] to node with largest deficit\n        int best=-1; for(int j=0;j<N;j++) if(best<0||deficit[j]>deficit[best]) best=j;\n        a[i]=best; deficit[best]-=ha;\n        best=-1; for(int j=0;j<N;j++) if(best<0||deficit[j]>deficit[best]) best=j;\n        b[i]=best; deficit[best]-=hb;\n    }\n    \n    auto simulate = [&]() -> long long {\n        int cnt[100]={}, vis[100]={};\n        int x=0;\n        for(int w=0;w<L;w++){\n            cnt[x]++; vis[x]++;\n            x = (vis[x]%2==1) ? a[x] : b[x];\n        }\n        long long err=0;\n        for(int i=0;i<N;i++) err+=abs(cnt[i]-T[i]);\n        return err;\n    };\n    \n    long long bestErr = simulate();\n    int bestA[100], bestB[100];\n    memcpy(bestA,a,sizeof(a)); memcpy(bestB,b,sizeof(b));\n    \n    auto start = chrono::steady_clock::now();\n    \n    for(int iter=0;;iter++){\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed > 1.85) break;\n        double temp = max(0.5, 50.0*(1.0-elapsed/1.85));\n        \n        memcpy(a,bestA,sizeof(a)); memcpy(b,bestB,sizeof(b));\n        \n        int i = rng()%N;\n        int which = rng()%2;\n        int oldVal = which ? b[i] : a[i];\n        int newVal = rng()%N;\n        if(which) b[i]=newVal; else a[i]=newVal;\n        \n        long long err2 = simulate();\n        double delta = err2 - bestErr;\n        if(delta<=0 || (double)(rng()%1000000)/1000000.0 < exp(-delta/temp)){\n            bestErr=err2;\n            memcpy(bestA,a,sizeof(a)); memcpy(bestB,b,sizeof(b));\n        }\n    }\n    \n    for(int i=0;i<N;i++) printf(\"%d %d\\n\", bestA[i], bestB[i]);\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(int n): p(n), r(n,0) { iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a, int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a;\n        if(r[a]==r[b]) r[a]++;\n        return true;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M,Q,L,W;\n    cin>>N>>M>>Q>>L>>W;\n    vector<int> G(M);\n    for(auto &g:G) cin>>g;\n    vector<int> lx(N),rx(N),ly(N),ry(N);\n    for(int i=0;i<N;i++) cin>>lx[i]>>rx[i]>>ly[i]>>ry[i];\n    \n    vector<double> cx(N),cy(N);\n    for(int i=0;i<N;i++){\n        cx[i]=(lx[i]+rx[i])/2.0;\n        cy[i]=(ly[i]+ry[i])/2.0;\n    }\n    \n    auto edist = [&](int a, int b) -> double {\n        double dx=cx[a]-cx[b], dy=cy[a]-cy[b];\n        return sqrt(dx*dx+dy*dy);\n    };\n    \n    // Build a k-d tree or just use sorted neighbor lists\n    // For each city, find its nearest neighbors by estimated distance\n    \n    // Phase 1: Use queries to discover true short edges\n    // Strategy: find clusters of L nearby cities and query them\n    \n    // Build nearest neighbor graph\n    // For efficiency, compute all pairwise distances (800*800 = 640K, fine)\n    vector<vector<pair<double,int>>> nn(N);\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++) if(i!=j){\n            nn[i].push_back({edist(i,j),j});\n        }\n        sort(nn[i].begin(),nn[i].end());\n    }\n    \n    // Discovered edges with oracle-confirmed MST relationships\n    set<pair<int,int>> oracleEdges;\n    // Also store actual distance bounds from oracle MST edges\n    \n    int queriesUsed = 0;\n    \n    // Strategy: query groups of L nearby cities\n    // Use a greedy approach: pick the city with least oracle coverage, query its L-1 nearest neighbors\n    \n    vector<int> oracleCoverage(N, 0); // how many oracle edges touch this city\n    \n    // Phase 1: Global exploration queries\n    // We want to cover as many cities as possible with oracle queries\n    // Each query covers L cities with L-1 edges\n    \n    // Sort cities by coverage, pick least covered, query with nearest neighbors\n    // But we need to be smart about which queries to use\n    \n    // Let's reserve some queries for within-group refinement\n    int phase1Queries = Q * 2 / 3;\n    int phase2Queries = Q - phase1Queries;\n    \n    // For phase 1, use queries on clusters of nearby cities\n    vector<bool> queriedSet(N, false);\n    \n    // Greedy: repeatedly pick the city with lowest coverage and query its neighborhood\n    auto doQuery = [&](vector<int>& subset) -> vector<pair<int,int>> {\n        cout << \"? \" << subset.size();\n        for(int c : subset) cout << \" \" << c;\n        cout << \"\\n\" << flush;\n        queriesUsed++;\n        vector<pair<int,int>> res;\n        for(int e = 0; e < (int)subset.size()-1; e++){\n            int a, b; cin >> a >> b;\n            if(a > b) swap(a, b);\n            oracleEdges.insert({a, b});\n            oracleCoverage[a]++;\n            oracleCoverage[b]++;\n            res.push_back({a, b});\n        }\n        return res;\n    };\n    \n    // Phase 1: Cover cities broadly\n    // Use a set-cover like approach\n    for(int q = 0; q < phase1Queries; q++){\n        // Find least covered city\n        int best = -1;\n        for(int i = 0; i < N; i++){\n            if(best < 0 || oracleCoverage[i] < oracleCoverage[best])\n                best = i;\n        }\n        \n        // Query best + its L-1 nearest uncovered/least-covered neighbors\n        vector<int> subset;\n        subset.push_back(best);\n        \n        // Pick nearest neighbors preferring low coverage\n        vector<pair<pair<int,double>,int>> candidates;\n        for(auto [d, j] : nn[best]){\n            candidates.push_back({{oracleCoverage[j], d}, j});\n        }\n        sort(candidates.begin(), candidates.end());\n        \n        set<int> inSubset;\n        inSubset.insert(best);\n        for(auto& [key, j] : candidates){\n            if((int)subset.size() >= L) break;\n            if(!inSubset.count(j)){\n                subset.push_back(j);\n                inSubset.insert(j);\n            }\n        }\n        \n        if((int)subset.size() < 2) break;\n        doQuery(subset);\n    }\n    \n    // Now do clustering using oracle edges + estimated distances\n    // Build a weighted graph: oracle edges get weight = estimated distance (they're MST edges so they're good)\n    // Other edges get estimated distance\n    \n    // Use a modified MST-based clustering:\n    // Build global MST using oracle edges with bonus (lower weight), cut into M components\n    \n    // Build edge list: oracle edges with slight discount\n    vector<tuple<double,int,int>> allEdges;\n    for(auto [a,b] : oracleEdges){\n        allEdges.push_back({edist(a,b) * 0.8, a, b}); // trust oracle edges more\n    }\n    // Add all estimated edges\n    for(int i = 0; i < N; i++){\n        // Only add nearest ~50 neighbors to keep it manageable\n        for(int k = 0; k < min((int)nn[i].size(), 50); k++){\n            int j = nn[i][k].second;\n            if(i < j){\n                allEdges.push_back({edist(i,j), i, j});\n            }\n        }\n    }\n    sort(allEdges.begin(), allEdges.end());\n    \n    // Build MST of all N cities\n    DSU dsu(N);\n    vector<tuple<double,int,int>> mstEdges;\n    for(auto& [w, a, b] : allEdges){\n        if(dsu.unite(a, b)){\n            mstEdges.push_back({w, a, b});\n            if((int)mstEdges.size() == N-1) break;\n        }\n    }\n    \n    // If MST not complete, add remaining edges\n    if((int)mstEdges.size() < N-1){\n        for(int i = 0; i < N; i++){\n            for(auto [d, j] : nn[i]){\n                if(i < j){\n                    DSU tmp = dsu;\n                    if(tmp.unite(i, j)){\n                        dsu.unite(i, j);\n                        mstEdges.push_back({d, i, j});\n                        if((int)mstEdges.size() == N-1) break;\n                    }\n                }\n            }\n            if((int)mstEdges.size() == N-1) break;\n        }\n    }\n    \n    // Now partition into M groups by cutting M-1 heaviest edges\n    // But we need specific group sizes G[0..M-1]\n    \n    // Sort group sizes\n    vector<int> gsorted(M);\n    iota(gsorted.begin(), gsorted.end(), 0);\n    \n    // Build adjacency from MST\n    vector<vector<pair<int,double>>> adj(N);\n    // Sort MST edges by weight descending, try removing edges and check if resulting component sizes match G\n    \n    // This is tricky with arbitrary group sizes. Let's use a different approach:\n    // Hierarchical clustering with MST, then assign group sizes optimally\n    \n    // Simple approach: sort MST edges by weight desc, remove top M-1 to get M components\n    // Then match components to group sizes\n    \n    sort(mstEdges.begin(), mstEdges.end(), [](auto& a, auto& b){ return get<0>(a) > get<0>(b); });\n    \n    DSU dsu2(N);\n    // Add all but top M-1 edges (i.e., add edges from index M-1 onwards)\n    for(int i = M-1; i < (int)mstEdges.size(); i++){\n        auto [w, a, b] = mstEdges[i];\n        dsu2.unite(a, b);\n    }\n    \n    // Find components\n    map<int, vector<int>> components;\n    for(int i = 0; i < N; i++){\n        components[dsu2.find(i)].push_back(i);\n    }\n    \n    // We have some components, but their sizes may not match G exactly\n    // Need to split large components or merge small ones\n    \n    // Collect component sizes\n    vector<vector<int>> comps;\n    for(auto& [root, cities] : components){\n        comps.push_back(cities);\n    }\n    \n    // Sort components by size descending\n    sort(comps.begin(), comps.end(), [](auto& a, auto& b){ return a.size() > b.size(); });\n    \n    // Sort G descending for matching\n    vector<int> Gsorted(G);\n    sort(Gsorted.rbegin(), Gsorted.rend());\n    \n    // This matching is complex. Let me use a simpler but effective approach:\n    // Just do balanced clustering from scratch using assignment\n    \n    // Alternative: Use a proper balanced k-means / assignment approach\n    // Let me try a different strategy entirely:\n    \n    // 1. Compute estimated all-pairs distances\n    // 2. Sort all edges by estimated distance\n    // 3. Use a constrained clustering: greedily merge nearest cities/clusters\n    //    but don't let any cluster exceed the largest remaining group size needed\n    \n    // Actually, let's use a cleaner approach:\n    // Assign cities to groups using a greedy nearest-center approach with balanced sizes\n    \n    // Pick initial centers using k-means++ on estimated positions\n    vector<int> centers(M);\n    vector<double> minDist(N, 1e18);\n    \n    // First center: random (pick city 0 or centroid-closest)\n    {\n        double avgx=0, avgy=0;\n        for(int i=0;i<N;i++){ avgx+=cx[i]; avgy+=cy[i]; }\n        avgx/=N; avgy/=N;\n        int best=0;\n        for(int i=1;i<N;i++){\n            double d1=(cx[i]-avgx)*(cx[i]-avgx)+(cy[i]-avgy)*(cy[i]-avgy);\n            double d0=(cx[best]-avgx)*(cx[best]-avgx)+(cy[best]-avgy)*(cy[best]-avgy);\n            if(d1<d0) best=i;\n        }\n        centers[0]=best;\n    }\n    \n    vector<bool> isCenter(N, false);\n    isCenter[centers[0]] = true;\n    for(int i=0;i<N;i++) minDist[i]=edist(i,centers[0]);\n    \n    for(int c=1;c<M;c++){\n        int best=-1;\n        for(int i=0;i<N;i++) if(!isCenter[i]){\n            if(best<0 || minDist[i]>minDist[best]) best=i;\n        }\n        centers[c]=best;\n        isCenter[best]=true;\n        for(int i=0;i<N;i++){\n            minDist[i]=min(minDist[i], edist(i,best));\n        }\n    }\n    \n    // Now assign cities to nearest center, respecting group sizes\n    // Use min-cost bipartite matching approximation\n    // Priority queue approach: for each city-group pair, compute distance to center\n    \n    // Sort G indices so we assign largest groups first? Or use auction/Hungarian?\n    // Simple approach: iterative assignment\n    \n    // For each group, compute center position as the seed\n    vector<double> gcx(M), gcy(M);\n    for(int i=0;i<M;i++){\n        gcx[i]=cx[centers[i]];\n        gcy[i]=cy[centers[i]];\n    }\n    \n    // K-means iterations\n    vector<int> assignment(N, -1);\n    \n    for(int iter = 0; iter < 10; iter++){\n        // Assign each city to nearest center, respecting capacities\n        // Use a priority queue\n        using T = tuple<double, int, int>; // dist, city, group\n        priority_queue<T, vector<T>, greater<T>> pq;\n        \n        for(int i = 0; i < N; i++){\n            for(int g = 0; g < M; g++){\n                double dx = cx[i]-gcx[g], dy = cy[i]-gcy[g];\n                pq.push({sqrt(dx*dx+dy*dy), i, g});\n            }\n        }\n        \n        fill(assignment.begin(), assignment.end(), -1);\n        vector<int> cap(G.begin(), G.end());\n        vector<vector<int>> grps(M);\n        int assigned = 0;\n        \n        while(!pq.empty() && assigned < N){\n            auto [d, c, g] = pq.top(); pq.pop();\n            if(assignment[c] != -1 || cap[g] <= 0) continue;\n            assignment[c] = g;\n            grps[g].push_back(c);\n            cap[g]--;\n            assigned++;\n        }\n        \n        // Update centers\n        bool changed = false;\n        for(int g = 0; g < M; g++){\n            if(grps[g].empty()) continue;\n            double nx=0, ny=0;\n            for(int c : grps[g]){ nx+=cx[c]; ny+=cy[c]; }\n            nx/=grps[g].size(); ny/=grps[g].size();\n            if(abs(gcx[g]-nx)>0.1 || abs(gcy[g]-ny)>0.1) changed=true;\n            gcx[g]=nx; gcy[g]=ny;\n        }\n        if(!changed) break;\n    }\n    \n    // Build final groups\n    vector<vector<int>> groups(M);\n    for(int i = 0; i < N; i++){\n        groups[assignment[i]].push_back(i);\n    }\n    \n    // Phase 2: Use remaining queries within groups\n    for(int g = 0; g < M && queriesUsed < Q; g++){\n        auto& grp = groups[g];\n        int sz = grp.size();\n        if(sz <= 1) continue;\n        \n        // Sort by estimated position within group\n        sort(grp.begin(), grp.end(), [&](int a, int b){\n            double da = (cx[a]-gcx[g])*(cx[a]-gcx[g])+(cy[a]-gcy[g])*(cy[a]-gcy[g]);\n            double db = (cx[b]-gcx[g])*(cx[b]-gcx[g])+(cy[b]-gcy[g])*(cy[b]-gcy[g]);\n            return atan2(cy[a]-gcy[g],cx[a]-gcx[g]) < atan2(cy[b]-gcy[g],cx[b]-gcx[g]);\n        });\n        \n        // Query sliding windows\n        int stride = max(1, L-1);\n        for(int i = 0; i + 1 < sz && queriesUsed < Q; i += stride){\n            int end = min(i+L, sz);\n            if(end - i < 2) break;\n            vector<int> subset(grp.begin()+i, grp.begin()+end);\n            doQuery(subset);\n        }\n    }\n    \n    // Build spanning trees for each group\n    // Use Kruskal with oracle edges prioritized\n    cout << \"!\" << endl;\n    \n    for(int g = 0; g < M; g++){\n        auto& grp = groups[g];\n        int sz = grp.size();\n        \n        for(int i = 0; i < sz; i++){\n            if(i) cout << \" \";\n            cout << grp[i];\n        }\n        cout << \"\\n\";\n        \n        if(sz <= 1) continue;\n        \n        set<int> inGrp(grp.begin(), grp.end());\n        map<int,int> id;\n        for(int i = 0; i < sz; i++) id[grp[i]] = i;\n        \n        // Collect edges: oracle edges within this group get priority\n        vector<tuple<double,int,int>> edges;\n        for(auto [a, b] : oracleEdges){\n            if(inGrp.count(a) && inGrp.count(b)){\n                edges.push_back({edist(a,b) * 0.5, a, b}); // strong priority\n            }\n        }\n        // All pairs within group\n        for(int i = 0; i < sz; i++){\n            for(int j = i+1; j < sz; j++){\n                edges.push_back({edist(grp[i], grp[j]), grp[i], grp[j]});\n            }\n        }\n        \n        sort(edges.begin(), edges.end());\n        \n        DSU gdsu(N);\n        vector<pair<int,int>> tree;\n        for(auto& [w, a, b] : edges){\n            if(gdsu.unite(a, b)){\n                tree.push_back({a, b});\n                if((int)tree.size() == sz-1) break;\n            }\n        }\n        \n        for(auto [a, b] : tree){\n            cout << a << \" \" << b << \"\\n\";\n        }\n    }\n    \n    cout << flush;\n    return 0;\n}","ahc046":"#include<bits/stdc++.h>\nusing namespace std;\nint N,M;\nint dx[]={-1,1,0,0},dy[]={0,0,-1,1};\nchar dc[]={'U','D','L','R'};\n\n// BFS shortest path avoiding blocks using only Move\nvector<pair<int,int>> bfsMove(int ci,int cj,int gi,int gj, vector<vector<bool>>&blk){\n    vector<vector<int>>dist(N,vector<int>(N,-1));\n    vector<vector<int>>pdir(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[ci][cj]=0;q.push({ci,cj});\n    while(!q.empty()){\n        auto[x,y]=q.front();q.pop();\n        if(x==gi&&y==gj)break;\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&&!blk[nx][ny]&&dist[nx][ny]<0){\n                dist[nx][ny]=dist[x][y]+1;par[nx][ny]={x,y};pdir[nx][ny]=d;q.push({nx,ny});\n            }\n        }\n    }\n    vector<pair<int,int>>acts;\n    if(dist[gi][gj]<0)return acts;\n    int x=gi,y=gj;\n    while(x!=ci||y!=cj){\n        acts.push_back({0,pdir[x][y]});\n        auto[px,py]=par[x][y];x=px;y=py;\n    }\n    reverse(acts.begin(),acts.end());\n    return acts;\n}\n\n// Simulate slide from (x,y) in direction d, return end position\npair<int,int> simSlide(int x,int y,int d,vector<vector<bool>>&blk){\n    while(true){\n        int nx=x+dx[d],ny=y+dy[d];\n        if(nx<0||nx>=N||ny<0||ny>=N||blk[nx][ny])break;\n        x=nx;y=ny;\n    }\n    return{x,y};\n}\n\nint main(){\n    scanf(\"%d%d\",&N,&M);\n    vector<int>ti(M),tj(M);\n    for(int k=0;k<M;k++)scanf(\"%d%d\",&ti[k],&tj[k]);\n    \n    int ci=ti[0],cj=tj[0];\n    vector<vector<bool>>blk(N,vector<bool>(N,false));\n    vector<pair<int,int>>allActs;\n    \n    for(int k=1;k<M;k++){\n        int gi=ti[k],gj=tj[k];\n        \n        // Strategy 1: Pure Move BFS\n        auto best=bfsMove(ci,cj,gi,gj,blk);\n        int bestCost=(int)best.size();\n        \n        // Strategy 2: Move to alignment point, then slide\n        // Try all 4 slide directions into target\n        for(int sd=0;sd<4;sd++){\n            // We slide in direction sd and stop at (gi,gj)\n            // Need block/wall at (gi+dx[sd],gj+dy[sd])\n            int bx=gi+dx[sd],by=gj+dy[sd];\n            bool stopped=(bx<0||bx>=N||by<0||by>=N||blk[bx][by]);\n            if(!stopped)continue;\n            \n            // Start sliding from some point along opposite direction\n            // slide direction sd from (sx,sy) must end at (gi,gj)\n            // The start must be on the line from (gi,gj) in opposite direction\n            int oppd=sd^1;\n            // Try starting from (ci,cj) aligned to target's row or col\n            // For vertical slides (sd=0 up, sd=1 down): same column gj\n            // For horizontal slides (sd=2 left, sd=3 right): same row gi\n            \n            if(sd<2){\n                // same column gj, start row = ci or move vertically first\n                // Try: move horizontally to column gj, then slide\n                int sx=ci,sy=gj;\n                // Check slide from (sx,sy) in direction sd\n                auto[ex,ey]=simSlide(sx,sy,sd,blk);\n                if(ex==gi&&ey==gj){\n                    // Cost: move from (ci,cj) to (sx,sy) + 1 slide\n                    auto moveActs=bfsMove(ci,cj,sx,sy,blk);\n                    if(!moveActs.empty()||((sx==ci)&&(sy==cj))){\n                        int cost=(int)moveActs.size()+1;\n                        if(cost<bestCost){\n                            bestCost=cost;\n                            best=moveActs;\n                            best.push_back({1,sd});\n                        }\n                    }\n                }\n            } else {\n                // same row gi\n                int sx=gi,sy=cj;\n                auto[ex,ey]=simSlide(sx,sy,sd,blk);\n                if(ex==gi&&ey==gj){\n                    auto moveActs=bfsMove(ci,cj,sx,sy,blk);\n                    if(!moveActs.empty()||((sx==ci)&&(sy==cj))){\n                        int cost=(int)moveActs.size()+1;\n                        if(cost<bestCost){\n                            bestCost=cost;\n                            best=moveActs;\n                            best.push_back({1,sd});\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Strategy 3: Place a block, then slide\n        for(int sd=0;sd<4;sd++){\n            int bx=gi+dx[sd],by=gj+dy[sd];\n            if(bx<0||bx>=N||by<0||by>=N)continue;\n            if(blk[bx][by])continue; // already handled in strategy 2\n            \n            // Need to place block at (bx,by)\n            // Must be adjacent to (bx,by) to alter\n            // Place from (bx-dx[sd],by-dy[sd])=(gi,gj) dir sd -- circular\n            // Place from other adjacent squares\n            for(int ad=0;ad<4;ad++){\n                int ax=bx+dx[ad^1],ay=by+dy[ad^1]; // position to alter from\n                if(ax<0||ax>=N||ay<0||ay>=N)continue;\n                if(blk[ax][ay])continue;\n                if(ax==gi&&ay==gj)continue; // can't stand on target to place\n                \n                // Move to (ax,ay), alter direction ad^0 to place block at (bx,by)\n                // Wait: from (ax,ay) direction (ad^1)^1=ad goes to (bx,by)? \n                // From (ax,ay), direction d2 such that ax+dx[d2]=bx, ay+dy[d2]=by\n                int d2=-1;\n                for(int dd=0;dd<4;dd++){\n                    if(ax+dx[dd]==bx&&ay+dy[dd]==by){d2=dd;break;}\n                }\n                if(d2<0)continue;\n                \n                auto moveToAlter=bfsMove(ci,cj,ax,ay,blk);\n                if(moveToAlter.empty()&&!(ax==ci&&ay==cj))continue;\n                \n                // After placing block, simulate slide\n                blk[bx][by]=true;\n                // Now find slide start point\n                // slide in direction sd into (gi,gj)\n                // Try a few start points\n                vector<pair<int,int>> slideStarts;\n                if(sd<2){ // vertical\n                    slideStarts.push_back({ax,gj});\n                    slideStarts.push_back({ci,gj});\n                } else {\n                    slideStarts.push_back({gi,ay});\n                    slideStarts.push_back({gi,cj});\n                }\n                \n                for(auto[sx,sy]:slideStarts){\n                    if(sx<0||sx>=N||sy<0||sy>=N)continue;\n                    if(blk[sx][sy])continue;\n                    auto[ex,ey]=simSlide(sx,sy,sd,blk);\n                    if(ex==gi&&ey==gj&&!(sx==gi&&sy==gj)){\n                        auto moveToStart=bfsMove(ax,ay,sx,sy,blk);\n                        if(moveToStart.empty()&&!(ax==sx&&ay==sy))continue;\n                        int cost=(int)moveToAlter.size()+1+(int)moveToStart.size()+1;\n                        if(cost<bestCost){\n                            bestCost=cost;\n                            best=moveToAlter;\n                            best.push_back({2,d2}); // alter\n                            for(auto&a:moveToStart)best.push_back(a);\n                            best.push_back({1,sd}); // slide\n                        }\n                    }\n                }\n                blk[bx][by]=false;\n            }\n        }\n        \n        // Execute best actions and update state\n        int px=ci,py=cj;\n        for(auto&[a,d]:best){\n            if(a==0){ // Move\n                px+=dx[d];py+=dy[d];\n            } else if(a==1){ // Slide\n                tie(px,py)=simSlide(px,py,d,blk);\n            } else { // Alter\n                int bx2=px+dx[d],by2=py+dy[d];\n                blk[bx2][by2]=!blk[bx2][by2];\n            }\n            allActs.push_back({a,d});\n        }\n        ci=px;cj=py;\n    }\n    \n    for(auto&[a,d]:allActs){\n        char ac=(a==0?'M':(a==1?'S':'A'));\n        printf(\"%c %c\\n\",ac,dc[d]);\n    }\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    vector<int> x(n), y(n);\n    vector<long long> r(n);\n    for(int i=0;i<n;i++) cin >> x[i] >> y[i] >> r[i];\n    \n    vector<int> a(n),b(n),c(n),d(n);\n    for(int i=0;i<n;i++){\n        a[i]=x[i]; b[i]=y[i]; c[i]=x[i]+1; d[i]=y[i]+1;\n    }\n    \n    auto canExpand = [&](int i, int na, int nb, int nc, int nd) -> bool {\n        if(na<0||nb<0||nc>10000||nd>10000||na>=nc||nb>=nd) return false;\n        for(int j=0;j<n;j++){\n            if(j==i) continue;\n            if(na<c[j] && a[j]<nc && nb<d[j] && b[j]<nd) return false;\n        }\n        return true;\n    };\n    \n    auto start = chrono::steady_clock::now();\n    mt19937 rng(42);\n    \n    while(true){\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now-start).count();\n        if(elapsed > 4.5) break;\n        \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 i : order){\n            long long s = (long long)(c[i]-a[i])*(d[i]-b[i]);\n            \n            if(s < r[i]){\n                int w = c[i]-a[i], h = d[i]-b[i];\n                long long deficit = r[i] - s;\n                int stepH = max(1, min(200, (int)(deficit / max(1, h))));\n                int stepV = max(1, min(200, (int)(deficit / max(1, w))));\n                \n                // Try each direction, apply all that work\n                // Left\n                for(int st = stepH; st >= 1; st = (st > 1 ? max(1, st/2) : 0)){\n                    if(canExpand(i, a[i]-st, b[i], c[i], d[i])){\n                        a[i]-=st; improved=true; break;\n                    }\n                }\n                // Right\n                for(int st = stepH; st >= 1; st = (st > 1 ? max(1, st/2) : 0)){\n                    if(canExpand(i, a[i], b[i], c[i]+st, d[i])){\n                        c[i]+=st; improved=true; break;\n                    }\n                }\n                // Up\n                for(int st = stepV; st >= 1; st = (st > 1 ? max(1, st/2) : 0)){\n                    if(canExpand(i, a[i], b[i]-st, c[i], d[i])){\n                        b[i]-=st; improved=true; break;\n                    }\n                }\n                // Down\n                for(int st = stepV; st >= 1; st = (st > 1 ? max(1, st/2) : 0)){\n                    if(canExpand(i, a[i], b[i], c[i], d[i]+st)){\n                        d[i]+=st; improved=true; break;\n                    }\n                }\n            }\n            \n            // Shrink if oversized\n            s = (long long)(c[i]-a[i])*(d[i]-b[i]);\n            if(s > r[i]){\n                int w=c[i]-a[i], h=d[i]-b[i];\n                long long excess = s - r[i];\n                auto sc = [&]() -> double {\n                    long long ss=(long long)(c[i]-a[i])*(d[i]-b[i]);\n                    double rat=(double)min(r[i],ss)/(double)max(r[i],ss);\n                    return 1.0-(1.0-rat)*(1.0-rat);\n                };\n                double cur = sc();\n                \n                int stepH = max(1, (int)(excess / max(1, h)));\n                int stepV = max(1, (int)(excess / max(1, w)));\n                \n                // Try shrink left edge\n                {int ns=min(stepH, x[i]-a[i]); if(ns>0){a[i]+=ns; if(sc()<=cur)a[i]-=ns; else{cur=sc();improved=true;}}}\n                {int ns=min(stepH, c[i]-(x[i]+1)); if(ns>0){c[i]-=ns; if(sc()<=cur)c[i]+=ns; else{cur=sc();improved=true;}}}\n                {int ns=min(stepV, y[i]-b[i]); if(ns>0){b[i]+=ns; if(sc()<=cur)b[i]-=ns; else{cur=sc();improved=true;}}}\n                {int ns=min(stepV, d[i]-(y[i]+1)); if(ns>0){d[i]-=ns; if(sc()<=cur)d[i]+=ns; else{cur=sc();improved=true;}}}\n            }\n        }\n        if(!improved) break;\n    }\n    \n    for(int i=0;i<n;i++) cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint t[50][50], p[50][50];\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\nchar dc[]={'U','D','L','R'};\n\nint main(){\n    int si,sj;\n    scanf(\"%d%d\",&si,&sj);\n    for(int i=0;i<50;i++) for(int j=0;j<50;j++) scanf(\"%d\",&t[i][j]);\n    for(int i=0;i<50;i++) for(int j=0;j<50;j++) scanf(\"%d\",&p[i][j]);\n    \n    int M=0;\n    for(int i=0;i<50;i++) for(int j=0;j<50;j++) M=max(M,t[i][j]+1);\n    \n    int usedWords=(M+63)/64;\n    \n    struct Node{int parent;char dir;};\n    vector<Node> tree;\n    tree.reserve(6000000);\n    tree.push_back({-1,' '});\n    \n    auto getPath=[&](int idx)->string{\n        string s;\n        while(idx>0){s+=tree[idx].dir;idx=tree[idx].parent;}\n        reverse(s.begin(),s.end());\n        return s;\n    };\n    \n    struct State{\n        int x,y,score,nodeIdx,usedIdx;\n        int eval;\n    };\n    \n    int bestScore=p[si][sj],bestNode=0;\n    \n    int totalBeam=900;\n    int perPos=5;\n    \n    // Pre-allocate pool for beam states\n    // Two buffers: current and next\n    size_t maxPool=(size_t)(totalBeam+10)*usedWords;\n    size_t maxNextPool=(size_t)(totalBeam*4+10)*usedWords;\n    vector<uint64_t> curPool(maxPool,0);\n    vector<uint64_t> nextPool;\n    nextPool.reserve(maxNextPool);\n    vector<uint64_t> selPool;\n    selPool.reserve(maxPool);\n    \n    // Initialize\n    {\n        int tid0=t[si][sj];\n        curPool[tid0/64]|=1ULL<<(tid0%64);\n    }\n    \n    vector<State> beam;\n    beam.push_back({si,sj,p[si][sj],0,0,0});\n    \n    auto deadline=chrono::steady_clock::now()+chrono::milliseconds(1860);\n    \n    for(int step=0;step<2500&&!beam.empty();step++){\n        if(step%8==0&&chrono::steady_clock::now()>deadline) break;\n        \n        vector<State> next;\n        next.reserve(beam.size()*4);\n        nextPool.clear();\n        \n        for(auto&s:beam){\n            const uint64_t*uptr=&curPool[(size_t)s.usedIdx*usedWords];\n            for(int d=0;d<4;d++){\n                int nx=s.x+dx[d],ny=s.y+dy[d];\n                if(nx<0||nx>=50||ny<0||ny>=50) continue;\n                int tid=t[nx][ny];\n                if((uptr[tid/64]>>(tid%64))&1) continue;\n                \n                int ni=(int)tree.size();\n                tree.push_back({s.nodeIdx,dc[d]});\n                \n                int newIdx=(int)(nextPool.size()/usedWords);\n                size_t base=nextPool.size();\n                nextPool.resize(base+usedWords);\n                memcpy(&nextPool[base],uptr,usedWords*8);\n                nextPool[base+tid/64]|=1ULL<<(tid%64);\n                \n                int sc=s.score+p[nx][ny];\n                \n                // Heuristic: future mobility + value\n                int futureVal=0,freeMoves=0;\n                const uint64_t*nptr=&nextPool[base];\n                for(int d2=0;d2<4;d2++){\n                    int nnx=nx+dx[d2],nny=ny+dy[d2];\n                    if(nnx<0||nnx>=50||nny<0||nny>=50) continue;\n                    int tid2=t[nnx][nny];\n                    if(!((nptr[tid2/64]>>(tid2%64))&1)){\n                        freeMoves++;\n                        futureVal+=p[nnx][nny];\n                        // 2nd level lookahead\n                        for(int d3=0;d3<4;d3++){\n                            int n3x=nnx+dx[d3],n3y=nny+dy[d3];\n                            if(n3x<0||n3x>=50||n3y<0||n3y>=50) continue;\n                            int tid3=t[n3x][n3y];\n                            if(tid3!=tid2&&!((nptr[tid3/64]>>(tid3%64))&1)){\n                                futureVal+=p[n3x][n3y]/4;\n                            }\n                        }\n                    }\n                }\n                \n                int ev=sc*4+futureVal+freeMoves*20;\n                next.push_back({nx,ny,sc,ni,newIdx,ev});\n            }\n        }\n        if(next.empty()) break;\n        \n        sort(next.begin(),next.end(),[](const State&a,const State&b){return a.eval>b.eval;});\n        \n        int cnt[50][50]={};\n        vector<State> selected;\n        selPool.clear();\n        selected.reserve(totalBeam);\n        \n        for(auto&s:next){\n            if(cnt[s.x][s.y]<perPos&&(int)selected.size()<totalBeam){\n                cnt[s.x][s.y]++;\n                int newIdx=(int)(selPool.size()/usedWords);\n                size_t base=selPool.size();\n                selPool.resize(base+usedWords);\n                memcpy(&selPool[base],&nextPool[(size_t)s.usedIdx*usedWords],usedWords*8);\n                s.usedIdx=newIdx;\n                selected.push_back(s);\n                if(s.score>bestScore){bestScore=s.score;bestNode=s.nodeIdx;}\n            }\n        }\n        \n        beam=move(selected);\n        curPool=move(selPool);\n        selPool=vector<uint64_t>();\n        selPool.reserve(maxPool);\n    }\n    \n    printf(\"%s\\n\",getPath(bestNode).c_str());\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\nconst int N=30;\ndouble h[N][N-1],v[N-1][N];\nint cnt_h[N][N-1],cnt_v[N-1][N];\n\nstruct Obs{\n    vector<pair<int,int>> he,ve;\n    double cost;\n};\nvector<Obs> observations;\n\nint di[]={-1,1,0,0},dj[]={0,0,-1,1};\nchar dirs[]=\"UDLR\";\nstruct Edge{int type,ei,ej;};\n\nvoid fillUnvisited(){\n    for(int i=0;i<N;i++){\n        double s=0;int c=0;\n        for(int j=0;j<N-1;j++) if(cnt_h[i][j]>0){s+=h[i][j];c++;}\n        if(c>0){double a=s/c; for(int j=0;j<N-1;j++) if(cnt_h[i][j]==0) h[i][j]=a;}\n    }\n    for(int j=0;j<N;j++){\n        double s=0;int c=0;\n        for(int i=0;i<N-1;i++) if(cnt_v[i][j]>0){s+=v[i][j];c++;}\n        if(c>0){double a=s/c; for(int i=0;i<N-1;i++) if(cnt_v[i][j]==0) v[i][j]=a;}\n    }\n}\n\npair<string,vector<Edge>> dijkstra(int si,int sj,int ti,int tj){\n    vector<double> dist(N*N,1e18);\n    vector<int> pn(N*N,-1),pd(N*N,-1);\n    priority_queue<pair<double,int>,vector<pair<double,int>>,greater<>> pq;\n    int s=si*N+sj,t=ti*N+tj;\n    dist[s]=0;pq.push({0,s});\n    while(!pq.empty()){\n        auto[d,u]=pq.top();pq.pop();\n        if(d>dist[u])continue;\n        int ci=u/N,cj=u%N;\n        for(int dir=0;dir<4;dir++){\n            int ni=ci+di[dir],nj=cj+dj[dir];\n            if(ni<0||ni>=N||nj<0||nj>=N)continue;\n            double w;\n            if(dir==0)w=v[ni][cj];else if(dir==1)w=v[ci][cj];\n            else if(dir==2)w=h[ci][nj];else w=h[ci][cj];\n            int nv=ni*N+nj;\n            if(dist[u]+w<dist[nv]){dist[nv]=dist[u]+w;pn[nv]=u;pd[nv]=dir;pq.push({dist[nv],nv});}\n        }\n    }\n    string ans;vector<Edge> edges;\n    int cur=t;\n    vector<pair<int,int>> pp;\n    while(cur!=s){pp.push_back({pn[cur],pd[cur]});cur=pn[cur];}\n    reverse(pp.begin(),pp.end());\n    for(auto&[node,dir]:pp){\n        ans+=dirs[dir];\n        int ci=node/N,cj=node%N;\n        Edge e{dir,0,0};\n        if(dir==0){e.ei=ci-1;e.ej=cj;}\n        else if(dir==1){e.ei=ci;e.ej=cj;}\n        else if(dir==2){e.ei=ci;e.ej=cj-1;}\n        else{e.ei=ci;e.ej=cj;}\n        edges.push_back(e);\n    }\n    return{ans,edges};\n}\n\nvoid refine(int iters){\n    for(int it=0;it<iters;it++){\n        double lr = 0.06 / (1.0 + it * 0.01);\n        for(auto&obs:observations){\n            double est=0;\n            for(auto&[i,j]:obs.he) est+=h[i][j];\n            for(auto&[i,j]:obs.ve) est+=v[i][j];\n            if(est<1)continue;\n            double r = lr*(obs.cost/est - 1.0);\n            for(auto&[i,j]:obs.he){ h[i][j]*=(1.0+r); h[i][j]=max(1000.0,min(9000.0,h[i][j])); }\n            for(auto&[i,j]:obs.ve){ v[i][j]*=(1.0+r); v[i][j]=max(1000.0,min(9000.0,v[i][j])); }\n        }\n    }\n}\n\nint main(){\n    for(int i=0;i<N;i++)for(int j=0;j<N-1;j++){h[i][j]=5000;cnt_h[i][j]=0;}\n    for(int i=0;i<N-1;i++)for(int j=0;j<N;j++){v[i][j]=5000;cnt_v[i][j]=0;}\n    \n    auto startTime = chrono::steady_clock::now();\n    \n    for(int q=0;q<1000;q++){\n        int si,sj,ti,tj;\n        scanf(\"%d%d%d%d\",&si,&sj,&ti,&tj);\n        auto[ans,edges]=dijkstra(si,sj,ti,tj);\n        printf(\"%s\\n\",ans.c_str());fflush(stdout);\n        int obs;scanf(\"%d\",&obs);\n        \n        double est=0;\n        Obs ob;\n        for(auto&e:edges){\n            if(e.type<=1){est+=v[e.ei][e.ej];ob.ve.push_back({e.ei,e.ej});}\n            else{est+=h[e.ei][e.ej];ob.he.push_back({e.ei,e.ej});}\n        }\n        ob.cost=(double)obs;\n        observations.push_back(ob);\n        \n        // Online update\n        double ratio=(double)obs/est;\n        for(auto&e:edges){\n            if(e.type<=1){\n                int c=++cnt_v[e.ei][e.ej];\n                double lr=1.5/(c+2);\n                v[e.ei][e.ej]*=(1.0-lr)+lr*ratio;\n                v[e.ei][e.ej]=max(1000.0,min(9000.0,v[e.ei][e.ej]));\n            }else{\n                int c=++cnt_h[e.ei][e.ej];\n                double lr=1.5/(c+2);\n                h[e.ei][e.ej]*=(1.0-lr)+lr*ratio;\n                h[e.ei][e.ej]=max(1000.0,min(9000.0,h[e.ei][e.ej]));\n            }\n        }\n        \n        fillUnvisited();\n        \n        // Time-aware batch refinement\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now-startTime).count();\n        double timePerQuery = (q<999) ? (1.8 - elapsed)/(999.0-q) : 0;\n        \n        if(q<50 && q%5==4){\n            refine(10);\n            fillUnvisited();\n        } else if(q<200 && q%10==9){\n            refine(8);\n            fillUnvisited();\n        } else if(q%25==24 && elapsed<1.5){\n            refine(6);\n            fillUnvisited();\n        }\n    }\n}","ahc004":"#include<bits/stdc++.h>\nusing namespace std;\n\nint N=20, M;\nchar G[20][20];\n\nint main(){\n    ios::sync_with_stdio(0);cin.tie(0);\n    cin>>N>>M;\n    vector<string> S(M);\n    for(int i=0;i<M;i++) cin>>S[i];\n    mt19937 rng(12345);\n    \n    auto t0=chrono::steady_clock::now();\n    auto elapsed=[&](){return chrono::duration<double>(chrono::steady_clock::now()-t0).count();};\n\n    // For each line (0..19 = rows, 20..39 = cols), for each string, \n    // store possible offsets where the string fits\n    // A placement: line L, offset j means string s matches line L starting at position j\n    \n    // We'll try to reconstruct each of 40 lines independently using beam search\n    // Then merge rows and columns (each cell gets two constraints)\n    \n    // For beam search on a line: build cyclic string of length 20\n    // matching as many strings as possible\n    \n    // First, assign each string to candidate lines\n    // A string of length k on row r at offset j: cells (r,j), (r,j+1%20), ...\n    // A string of length k on col c at offset i: cells (i,c), (i+1%20,c), ...\n    \n    // Strategy: greedy init + hill climbing (best so far)\n    // But improve greedy init with multiple passes\n    \n    auto greedyInit=[&](mt19937&gen) -> int {\n        memset(G,0,sizeof(G));\n        vector<int> order(M);\n        iota(order.begin(),order.end(),0);\n        shuffle(order.begin(),order.end(),gen);\n        stable_sort(order.begin(),order.end(),[&](int a,int b){return S[a].size()>S[b].size();});\n        \n        vector<bool> placed(M,false);\n        int nplaced=0;\n        \n        // Multiple passes\n        for(int pass=0;pass<3;pass++){\n            for(int si:order){\n                if(placed[si]) continue;\n                int k=S[si].size();\n                int bestScore=-1,bestD=-1,bestI=-1,bestJ=-1;\n                for(int d=0;d<2;d++) for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n                    int score=0; bool ok=true;\n                    for(int p=0;p<k;p++){\n                        int ci,cj;\n                        if(d==0){ci=i;cj=(j+p)%N;}\n                        else{ci=(i+p)%N;cj=j;}\n                        char c=G[ci][cj];\n                        if(c==S[si][p]) score+=3;\n                        else if(c==0) score+=0;\n                        else{ok=false;break;}\n                    }\n                    if(ok&&score>bestScore){bestScore=score;bestD=d;bestI=i;bestJ=j;}\n                }\n                // Only place if we have some overlap (pass>0) or first pass\n                if(bestD>=0 && (pass==0 || bestScore>0)){\n                    for(int p=0;p<k;p++){\n                        int ci,cj;\n                        if(bestD==0){ci=bestI;cj=(bestJ+p)%N;}\n                        else{ci=(bestI+p)%N;cj=bestJ;}\n                        G[ci][cj]=S[si][p];\n                    }\n                    placed[si]=true;\n                    nplaced++;\n                }\n            }\n        }\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++)\n            if(!G[i][j]) G[i][j]='A'+gen()%8;\n        return nplaced;\n    };\n    \n    // Build SA structures\n    int P=0;\n    vector<int> pl_s, pl_d, pl_i, pl_j;\n    vector<vector<int>> cell2pl(400);\n    \n    for(int s=0;s<M;s++){\n        int k=S[s].size();\n        for(int d=0;d<2;d++) for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            int pidx=P++;\n            pl_s.push_back(s); pl_d.push_back(d);\n            pl_i.push_back(i); pl_j.push_back(j);\n            for(int p=0;p<k;p++){\n                int ci,cj;\n                if(d==0){ci=i;cj=(j+p)%N;}\n                else{ci=(i+p)%N;cj=j;}\n                cell2pl[ci*20+cj].push_back(pidx);\n            }\n        }\n    }\n    \n    vector<int8_t> pl_ok(P);\n    vector<int> str_cnt(M,0);\n    int* pls=pl_s.data();\n    \n    auto checkPl=[&](int pidx)->int{\n        int s=pl_s[pidx];\n        const char*ss=S[s].c_str();\n        int k=S[s].size(),si=pl_i[pidx],sj=pl_j[pidx];\n        if(pl_d[pidx]==0){\n            for(int p=0;p<k;p++) if(G[si][(sj+p)%20]!=ss[p]) return 0;\n        } else {\n            for(int p=0;p<k;p++) if(G[(si+p)%20][sj]!=ss[p]) return 0;\n        }\n        return 1;\n    };\n    \n    auto initAll=[&](){\n        fill(str_cnt.begin(),str_cnt.end(),0);\n        for(int p=0;p<P;p++){\n            pl_ok[p]=checkPl(p);\n            if(pl_ok[p]) str_cnt[pls[p]]++;\n        }\n    };\n    \n    auto countMatched=[&]()->int{\n        int t=0;for(int s=0;s<M;s++) if(str_cnt[s]>0) t++;return t;\n    };\n    \n    int best_tot=0;\n    char bestG[20][20];\n    \n    for(int trial=0;trial<30&&elapsed()<0.7;trial++){\n        mt19937 gen(trial*17+3);\n        greedyInit(gen);\n        initAll();\n        int t=countMatched();\n        if(t>best_tot){best_tot=t;memcpy(bestG,G,sizeof(G));}\n    }\n    \n    memcpy(G,bestG,sizeof(G));\n    initAll();\n    int tot=countMatched();\n    best_tot=tot;\n    \n    int chBuf[4000]; int8_t chOld[4000]; int chSz;\n    \n    while(true){\n        if(elapsed()>2.75) break;\n        \n        for(int rep=0;rep<400;rep++){\n            if(rng()%3==0 && tot<M){\n                int si=rng()%M;\n                for(int t=0;t<10&&str_cnt[si]>0;t++) si=rng()%M;\n                if(str_cnt[si]==0){\n                    int k=S[si].size();\n                    int d=rng()%2,ri=rng()%N,rj=rng()%N;\n                    int mm=0;\n                    struct CC{int ci,cj;char oc,nc;} ccs[12]; int ncc=0;\n                    for(int p=0;p<k&&mm<=2;p++){\n                        int ci,cj;\n                        if(d==0){ci=ri;cj=(rj+p)%N;} else{ci=(ri+p)%N;cj=rj;}\n                        if(G[ci][cj]!=S[si][p]) ccs[ncc++]={ci,cj,G[ci][cj],S[si][p]}, mm++;\n                    }\n                    if(mm>=1&&mm<=2){\n                        int totalDelta=0, allSz=0;\n                        int cStarts[3],cLens[3];\n                        for(int ic=0;ic<ncc;ic++){\n                            cStarts[ic]=allSz;\n                            auto&aff=cell2pl[ccs[ic].ci*20+ccs[ic].cj];\n                            G[ccs[ic].ci][ccs[ic].cj]=ccs[ic].nc;\n                            int lc=0;\n                            for(int pidx:aff){\n                                int nv=checkPl(pidx);\n                                if(nv!=pl_ok[pidx]){\n                                    int om=(str_cnt[pls[pidx]]>0);\n                                    str_cnt[pls[pidx]]+=nv-pl_ok[pidx];\n                                    int nm=(str_cnt[pls[pidx]]>0);\n                                    totalDelta+=nm-om;\n                                    chBuf[allSz]=pidx; chOld[allSz]=pl_ok[pidx];\n                                    allSz++; lc++; pl_ok[pidx]=nv;\n                                }\n                            }\n                            cLens[ic]=lc;\n                        }\n                        if(totalDelta>=0){\n                            tot+=totalDelta;\n                            if(tot>best_tot){best_tot=tot;memcpy(bestG,G,sizeof(G));}\n                        } else {\n                            for(int ic=ncc-1;ic>=0;ic--){\n                                G[ccs[ic].ci][ccs[ic].cj]=ccs[ic].oc;\n                                for(int x=cStarts[ic]+cLens[ic]-1;x>=cStarts[ic];x--){\n                                    str_cnt[pls[chBuf[x]]]+=chOld[x]-pl_ok[chBuf[x]];\n                                    pl_ok[chBuf[x]]=chOld[x];\n                                }\n                            }\n                        }\n                    }\n                    continue;\n                }\n            }\n            \n            int ci=rng()%N,cj=rng()%N;\n            char oc=G[ci][cj],nc='A'+rng()%8;\n            if(nc==oc) continue;\n            auto&aff=cell2pl[ci*20+cj];\n            int delta=0;\n            G[ci][cj]=nc; chSz=0;\n            for(int pidx:aff){\n                int nv=checkPl(pidx);\n                if(nv!=pl_ok[pidx]){\n                    int om=(str_cnt[pls[pidx]]>0);\n                    str_cnt[pls[pidx]]+=nv-pl_ok[pidx];\n                    int nm=(str_cnt[pls[pidx]]>0);\n                    delta+=nm-om;\n                    chBuf[chSz]=pidx; chOld[chSz]=pl_ok[pidx]; chSz++;\n                    pl_ok[pidx]=nv;\n                }\n            }\n            if(delta>=0){\n                tot+=delta;\n                if(tot>best_tot){best_tot=tot;memcpy(bestG,G,sizeof(G));}\n            } else {\n                G[ci][cj]=oc;\n                for(int x=0;x<chSz;x++){\n                    str_cnt[pls[chBuf[x]]]+=chOld[x]-pl_ok[chBuf[x]];\n                    pl_ok[chBuf[x]]=chOld[x];\n                }\n            }\n        }\n    }\n    \n    memcpy(G,bestG,sizeof(G));\n    for(int i=0;i<N;i++){\n        for(int j=0;j<N;j++) cout<<G[i][j];\n        cout<<'\\n';\n    }\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nchar grid[70][70];\nint costg[70][70];\nvector<pair<int,int>> vis_from[70][70];\nint dx[]={-1,1,0,0}, dy[]={0,0,-1,1};\n\nvoid dijkstra_from(int s, int t, vector<vector<int>>& d, vector<vector<pair<int,int>>>& par) {\n    d.assign(N, vector<int>(N, INT_MAX));\n    par.assign(N, vector<pair<int,int>>(N, {-1,-1}));\n    priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n    d[s][t] = 0;\n    pq.push({0, s, t});\n    while (!pq.empty()) {\n        auto [dd, ci, cj] = pq.top(); pq.pop();\n        if (dd > d[ci][cj]) continue;\n        for (int k = 0; k < 4; k++) {\n            int ni = ci+dx[k], nj = cj+dy[k];\n            if (ni<0||ni>=N||nj<0||nj>=N||grid[ni][nj]=='#') continue;\n            int nd = dd + costg[ni][nj];\n            if (nd < d[ni][nj]) {\n                d[ni][nj] = nd;\n                par[ni][nj] = {ci, cj};\n                pq.push({nd, ni, nj});\n            }\n        }\n    }\n}\n\nvoid dijkstra_dist(int s, int t, vector<vector<int>>& d) {\n    d.assign(N, vector<int>(N, INT_MAX));\n    priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n    d[s][t] = 0;\n    pq.push({0, s, t});\n    while (!pq.empty()) {\n        auto [dd, ci, cj] = pq.top(); pq.pop();\n        if (dd > d[ci][cj]) continue;\n        for (int k = 0; k < 4; k++) {\n            int ni = ci+dx[k], nj = cj+dy[k];\n            if (ni<0||ni>=N||nj<0||nj>=N||grid[ni][nj]=='#') continue;\n            int nd = dd + costg[ni][nj];\n            if (nd < d[ni][nj]) {\n                d[ni][nj] = nd;\n                pq.push({nd, ni, nj});\n            }\n        }\n    }\n}\n\nvector<pair<int,int>> trace_path(const vector<vector<int>>& d, const vector<vector<pair<int,int>>>& par, int s, int t, int ti, int tj) {\n    vector<pair<int,int>> pts;\n    if (d[ti][tj] == INT_MAX) return pts;\n    int ci = ti, cj = tj;\n    while (!(ci==s && cj==t)) {\n        pts.push_back({ci, cj});\n        auto [pi, pj] = par[ci][cj];\n        ci = pi; cj = pj;\n    }\n    reverse(pts.begin(), pts.end());\n    return pts;\n}\n\nstring path_to_string(const vector<pair<int,int>>& route) {\n    string result;\n    for (int i = 1; i < (int)route.size(); i++) {\n        int di = route[i].first - route[i-1].first;\n        int dj = route[i].second - route[i-1].second;\n        if (di==-1) result+='U';\n        else if (di==1) result+='D';\n        else if (dj==-1) result+='L';\n        else result+='R';\n    }\n    return result;\n}\n\nint route_cost(const vector<pair<int,int>>& route) {\n    int t = 0;\n    for (int i = 1; i < (int)route.size(); i++) t += costg[route[i].first][route[i].second];\n    return t;\n}\n\nstatic int mark[70][70];\nstatic int mid = 0;\n\nbool check_full_coverage(const vector<pair<int,int>>& route) {\n    mid++;\n    for (auto& [pi,pj] : route)\n        for (auto& [vi,vj] : vis_from[pi][pj]) mark[vi][vj] = mid;\n    for (int r=0;r<N;r++) for (int c=0;c<N;c++)\n        if (grid[r][c]!='#' && mark[r][c]!=mid) return false;\n    return true;\n}\n\nchrono::steady_clock::time_point start_time;\nlong long elapsed() {\n    return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n}\n\n// Segment between two waypoints\nvector<pair<int,int>> get_segment(pair<int,int> from, pair<int,int> to) {\n    vector<vector<int>> d;\n    vector<vector<pair<int,int>>> par;\n    dijkstra_from(from.first, from.second, d, par);\n    return trace_path(d, par, from.first, from.second, to.first, to.second);\n}\n\nint get_dist(pair<int,int> from, pair<int,int> to) {\n    vector<vector<int>> d;\n    dijkstra_dist(from.first, from.second, d);\n    return d[to.first][to.second];\n}\n\n// Build full route from waypoints\nvector<pair<int,int>> build_route(const vector<pair<int,int>>& wps) {\n    vector<pair<int,int>> full_route;\n    full_route.push_back(wps[0]);\n    for (int w = 1; w < (int)wps.size(); w++) {\n        auto seg = get_segment(full_route.back(), wps[w]);\n        for (auto& p : seg) full_route.push_back(p);\n    }\n    return full_route;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    start_time = chrono::steady_clock::now();\n    \n    cin >> N >> si >> sj;\n    for (int i=0;i<N;i++){\n        string s; cin >> s;\n        for (int j=0;j<N;j++){\n            grid[i][j]=s[j];\n            if (s[j]!='#') costg[i][j]=s[j]-'0';\n        }\n    }\n    \n    for (int i=0;i<N;i++) for (int j=0;j<N;j++) {\n        if (grid[i][j]=='#') continue;\n        vis_from[i][j].push_back({i,j});\n        for (int dj=j-1;dj>=0;dj--){ if(grid[i][dj]=='#') break; vis_from[i][j].push_back({i,dj}); }\n        for (int dj=j+1;dj<N;dj++){ if(grid[i][dj]=='#') break; vis_from[i][j].push_back({i,dj}); }\n        for (int di=i-1;di>=0;di--){ if(grid[di][j]=='#') break; vis_from[i][j].push_back({di,j}); }\n        for (int di=i+1;di<N;di++){ if(grid[di][j]=='#') break; vis_from[i][j].push_back({di,j}); }\n    }\n    \n    // Greedy construction with path visibility\n    bool seen[70][70];\n    memset(seen, false, sizeof(seen));\n    int ci=si, cj=sj;\n    for (auto& [vi,vj]: vis_from[ci][cj]) seen[vi][vj]=true;\n    \n    vector<pair<int,int>> waypoints;\n    waypoints.push_back({si, sj});\n    \n    auto count_unseen = [&]() {\n        int c=0;\n        for (int i=0;i<N;i++) for (int j=0;j<N;j++) if(grid[i][j]!='#' && !seen[i][j]) c++;\n        return c;\n    };\n    \n    while (count_unseen() > 0) {\n        vector<vector<int>> d;\n        vector<vector<pair<int,int>>> par;\n        dijkstra_from(ci, cj, d, par);\n        \n        // Collect candidates\n        struct Cand { int i, j, unseen; double score; };\n        vector<Cand> candidates;\n        for (int i=0;i<N;i++) for (int j=0;j<N;j++) {\n            if (grid[i][j]=='#' || d[i][j]==INT_MAX) continue;\n            int unseen_cnt=0;\n            for (auto& [vi,vj]: vis_from[i][j]) if(!seen[vi][vj]) unseen_cnt++;\n            if (unseen_cnt==0) continue;\n            double score = (double)unseen_cnt / max(1, d[i][j]);\n            candidates.push_back({i, j, unseen_cnt, score});\n        }\n        \n        sort(candidates.begin(), candidates.end(), [](const Cand& a, const Cand& b){ return a.score > b.score; });\n        \n        // Evaluate top candidates with path visibility\n        int bestI=-1, bestJ=-1;\n        double bestScore = -1;\n        int eval_count = min((int)candidates.size(), 30);\n        \n        static int vm[70][70];\n        static int vmid = 0;\n        \n        for (int idx = 0; idx < eval_count; idx++) {\n            auto& c = candidates[idx];\n            auto path = trace_path(d, par, ci, cj, c.i, c.j);\n            vmid++;\n            int path_vis = 0;\n            for (auto& [pi,pj] : path) {\n                for (auto& [vi,vj] : vis_from[pi][pj]) {\n                    if (!seen[vi][vj] && vm[vi][vj] != vmid) {\n                        vm[vi][vj] = vmid;\n                        path_vis++;\n                    }\n                }\n            }\n            double score = (double)path_vis / max(1, d[c.i][c.j]);\n            if (score > bestScore) { bestScore = score; bestI = c.i; bestJ = c.j; }\n        }\n        \n        if (bestI==-1 && !candidates.empty()) {\n            bestI = candidates[0].i; bestJ = candidates[0].j;\n        }\n        if (bestI==-1) break;\n        \n        auto path = trace_path(d, par, ci, cj, bestI, bestJ);\n        for (auto& [pi,pj] : path) {\n            for (auto& [vi,vj]: vis_from[pi][pj]) seen[vi][vj]=true;\n        }\n        ci = bestI; cj = bestJ;\n        waypoints.push_back({ci, cj});\n    }\n    \n    waypoints.push_back({si, sj});\n    \n    vector<pair<int,int>> best_route = build_route(waypoints);\n    int best_cost = route_cost(best_route);\n    vector<pair<int,int>> best_wps = waypoints;\n    \n    // Optimization: iteratively remove waypoints\n    for (int iter = 0; iter < 20 && elapsed() < 1500; iter++) {\n        bool improved = false;\n        for (int w = (int)best_wps.size()-2; w >= 1 && elapsed() < 1500; w--) {\n            vector<pair<int,int>> new_wps;\n            for (int i = 0; i < (int)best_wps.size(); i++)\n                if (i != w) new_wps.push_back(best_wps[i]);\n            \n            // Quick distance check: is shortcut likely shorter?\n            auto new_route = build_route(new_wps);\n            int new_cost = route_cost(new_route);\n            if (new_cost < best_cost && check_full_coverage(new_route)) {\n                best_wps = new_wps;\n                best_route = new_route;\n                best_cost = new_cost;\n                improved = true;\n                break;\n            }\n        }\n        if (!improved) break;\n    }\n    \n    // Optimization: 2-opt on waypoints\n    for (int iter = 0; iter < 10 && elapsed() < 2000; iter++) {\n        bool improved = false;\n        int nw = (int)best_wps.size();\n        for (int i = 1; i < nw-2 && elapsed() < 2000; i++) {\n            for (int j = i+1; j < nw-1 && elapsed() < 2000; j++) {\n                // Reverse segment [i, j]\n                vector<pair<int,int>> new_wps = best_wps;\n                reverse(new_wps.begin()+i, new_wps.begin()+j+1);\n                auto new_route = build_route(new_wps);\n                int new_cost = route_cost(new_route);\n                if (new_cost < best_cost && check_full_coverage(new_route)) {\n                    best_wps = new_wps;\n                    best_route = new_route;\n                    best_cost = new_cost;\n                    improved = true;\n                    break;\n                }\n            }\n            if (improved) break;\n        }\n        if (!improved) break;\n    }\n    \n    // Optimization: swap adjacent waypoints\n    for (int iter = 0; iter < 10 && elapsed() < 2300; iter++) {\n        bool improved = false;\n        for (int w = 1; w+1 < (int)best_wps.size()-1 && elapsed() < 2300; w++) {\n            vector<pair<int,int>> new_wps = best_wps;\n            swap(new_wps[w], new_wps[w+1]);\n            auto new_route = build_route(new_wps);\n            int new_cost = route_cost(new_route);\n            if (new_cost < best_cost && check_full_coverage(new_route)) {\n                best_wps = new_wps;\n                best_route = new_route;\n                best_cost = new_cost;\n                improved = true;\n                break;\n            }\n        }\n        if (!improved) break;\n    }\n    \n    // Final shortcutting on full route\n    while (elapsed() < 2800) {\n        bool improved = false;\n        int rs = (int)best_route.size();\n        for (int step = max(2, rs/5); step >= 2 && elapsed() < 2800; step = step*2/3) {\n            for (int i = 0; i + step < rs && elapsed() < 2800; i += max(1, step/4)) {\n                int j = min(i + step, rs - 1);\n                vector<vector<int>> d;\n                vector<vector<pair<int,int>>> par;\n                dijkstra_from(best_route[i].first, best_route[i].second, d, par);\n                auto shortcut = trace_path(d, par, best_route[i].first, best_route[i].second, best_route[j].first, best_route[j].second);\n                \n                int old_cost = 0;\n                for (int k=i+1;k<=j;k++) old_cost += costg[best_route[k].first][best_route[k].second];\n                int new_cost = 0;\n                for (auto& [pi,pj] : shortcut) new_cost += costg[pi][pj];\n                \n                if (new_cost >= old_cost) continue;\n                \n                vector<pair<int,int>> new_route;\n                for (int k=0;k<=i;k++) new_route.push_back(best_route[k]);\n                for (auto& p : shortcut) new_route.push_back(p);\n                for (int k=j+1;k<rs;k++) new_route.push_back(best_route[k]);\n                \n                if (check_full_coverage(new_route)) {\n                    best_route = new_route;\n                    best_cost = route_cost(best_route);\n                    improved = true;\n                    break;\n                }\n            }\n            if (improved) break;\n        }\n        if (!improved) break;\n    }\n    \n    cout << path_to_string(best_route) << endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N,M,K,R;\n    scanf(\"%d%d%d%d\",&N,&M,&K,&R);\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for(int i=0;i<N;i++) for(int j=0;j<K;j++) scanf(\"%d\",&d[i][j]);\n    \n    vector<vector<int>> deps(N), rdeps(N);\n    for(int i=0;i<R;i++){\n        int u,v; scanf(\"%d%d\",&u,&v); u--;v--;\n        deps[v].push_back(u);\n        rdeps[u].push_back(v);\n    }\n    \n    double init_skill = 35.0 / sqrt((double)K) * sqrt(2.0/M_PI);\n    vector<vector<double>> s_est(M, vector<double>(K, init_skill));\n    vector<vector<double>> s_low(M, vector<double>(K, 0.0));\n    \n    vector<int> task_status(N, -1);\n    vector<int> member_task(M, -1);\n    vector<int> member_start(M, -1);\n    \n    // Per-member observation history for better estimation\n    struct Obs { int task; int t_obs; };\n    vector<vector<Obs>> all_obs(M);\n    \n    auto est_time_val = [&](int task, int member) -> double {\n        double w = 0;\n        for(int k=0;k<K;k++) w += max(0.0, (double)d[task][k] - s_est[member][k]);\n        return max(1.0, w);\n    };\n    \n    auto can_start = [&](int task) -> bool {\n        if(task_status[task]!=-1) return false;\n        for(int dep : deps[task]) if(task_status[dep]!=1) return false;\n        return true;\n    };\n    \n    // Compute CP with estimated durations\n    auto compute_cp = [&]() -> vector<double> {\n        vector<double> cp(N, 0.0);\n        vector<int> indeg(N,0);\n        for(int i=0;i<N;i++) for(int j:rdeps[i]) indeg[j]++;\n        queue<int> q;\n        for(int i=0;i<N;i++) if(indeg[i]==0) q.push(i);\n        vector<int> topo;\n        while(!q.empty()){int u=q.front();q.pop();topo.push_back(u);for(int v:rdeps[u])if(--indeg[v]==0)q.push(v);}\n        for(int i=N-1;i>=0;i--){\n            int u=topo[i];\n            if(task_status[u]==1){cp[u]=0;continue;}\n            double min_t=1e9;\n            for(int j=0;j<M;j++) min_t=min(min_t, est_time_val(u,j));\n            cp[u]=min_t;\n            for(int v:rdeps[u]) cp[u]=max(cp[u], min_t+cp[v]);\n        }\n        return cp;\n    };\n    \n    // Hungarian O(n^3) - minimization\n    auto hungarian_min = [&](vector<vector<double>>& cost, int n) -> vector<int> {\n        vector<double> u(n+1,0), v(n+1,0);\n        vector<int> p(n+1,0), way(n+1,0);\n        for(int i=1;i<=n;i++){\n            p[0]=i; int j0=0;\n            vector<double> minv(n+1,1e18);\n            vector<bool> used(n+1,false);\n            do {\n                used[j0]=true;\n                int i0=p[j0],j1=-1;\n                double delta=1e18;\n                for(int j=1;j<=n;j++){\n                    if(!used[j]){\n                        double cur=cost[i0-1][j-1]-u[i0]-v[j];\n                        if(cur<minv[j]){minv[j]=cur;way[j]=j0;}\n                        if(minv[j]<delta){delta=minv[j];j1=j;}\n                    }\n                }\n                for(int j=0;j<=n;j++){\n                    if(used[j]){u[p[j]]+=delta;v[j]-=delta;}\n                    else minv[j]-=delta;\n                }\n                j0=j1;\n            } while(p[j0]!=0);\n            do{int j1=way[j0];p[j0]=p[j1];j0=j1;}while(j0);\n        }\n        vector<int> ans(n); // ans[row] = col\n        for(int j=1;j<=n;j++) ans[p[j]-1]=j-1;\n        return ans;\n    };\n    \n    // Batch reestimate using simple iterative approach\n    auto batch_reestimate = [&](int member) {\n        auto& obs = all_obs[member];\n        if(obs.size() < 3) return;\n        \n        vector<double>& s = s_est[member];\n        vector<double> best_s = s;\n        double best_loss = 1e18;\n        \n        // Compute loss\n        auto compute_loss = [&](vector<double>& sv) -> double {\n            double loss = 0;\n            for(auto& ob : obs) {\n                double w = 0;\n                for(int k=0;k<K;k++) w += max(0.0, (double)d[ob.task][k] - sv[k]);\n                double target = (ob.t_obs == 1) ? 0.0 : (double)ob.t_obs;\n                double diff = w - target;\n                loss += diff * diff;\n            }\n            // Regularization toward current estimate\n            for(int k=0;k<K;k++) loss += 0.1 * (sv[k] - init_skill) * (sv[k] - init_skill);\n            return loss;\n        };\n        \n        best_loss = compute_loss(s);\n        \n        // Coordinate descent\n        for(int iter=0; iter<20; iter++){\n            bool improved = false;\n            for(int k=0;k<K;k++){\n                double orig = s[k];\n                // Try a few values\n                double best_val = orig;\n                double best_l = best_loss;\n                \n                for(double delta : {-2.0, -1.0, -0.5, 0.5, 1.0, 2.0}){\n                    s[k] = max(s_low[member][k], orig + delta);\n                    s[k] = min(s[k], 60.0);\n                    double l = compute_loss(s);\n                    if(l < best_l){\n                        best_l = l;\n                        best_val = s[k];\n                        improved = true;\n                    }\n                }\n                s[k] = best_val;\n                best_loss = best_l;\n            }\n            if(!improved) break;\n        }\n        \n        for(int k=0;k<K;k++) s[k] = max(s[k], s_low[member][k]);\n    };\n    \n    auto update_skills = [&](int member, int task, int t_obs) {\n        // Quick single-observation update\n        if(t_obs == 1) {\n            for(int k=0;k<K;k++){\n                s_low[member][k] = max(s_low[member][k], (double)d[task][k]);\n                s_est[member][k] = max(s_est[member][k], (double)d[task][k]);\n            }\n        } else {\n            double w_target = (double)t_obs;\n            double w_cur = 0;\n            vector<int> active_k;\n            for(int k=0;k<K;k++){\n                double gap = (double)d[task][k] - s_est[member][k];\n                if(gap > 0){w_cur += gap; active_k.push_back(k);}\n            }\n            if(active_k.empty()){\n                double total_d = 0;\n                for(int k=0;k<K;k++) total_d += max(1,d[task][k]);\n                for(int k=0;k<K;k++){\n                    if(d[task][k]>0){\n                        double frac = (double)d[task][k]/total_d;\n                        double new_s = (double)d[task][k] - w_target*frac;\n                        s_est[member][k] = s_est[member][k]*0.65 + new_s*0.35;\n                        s_est[member][k] = max(s_est[member][k], s_low[member][k]);\n                    }\n                }\n            } else {\n                double ratio = w_target/w_cur;\n                for(int k:active_k){\n                    double gap = (double)d[task][k]-s_est[member][k];\n                    double new_s = (double)d[task][k] - gap*ratio;\n                    s_est[member][k] = s_est[member][k]*0.65 + new_s*0.35;\n                    s_est[member][k] = max(s_est[member][k], s_low[member][k]);\n                    s_est[member][k] = max(s_est[member][k], 0.0);\n                }\n            }\n        }\n        \n        all_obs[member].push_back({task, t_obs});\n        \n        // Batch reestimate periodically\n        int n_obs = all_obs[member].size();\n        if(n_obs == 5 || n_obs == 10 || n_obs == 20 || n_obs % 15 == 0){\n            batch_reestimate(member);\n        }\n    };\n    \n    for(int day=1; day<=2000; day++){\n        vector<double> cp = compute_cp();\n        \n        vector<int> free_members;\n        for(int j=0;j<M;j++) if(member_task[j]==-1) free_members.push_back(j);\n        int fm = free_members.size();\n        \n        vector<int> avail_tasks;\n        for(int i=0;i<N;i++) if(can_start(i)) avail_tasks.push_back(i);\n        int at = avail_tasks.size();\n        \n        sort(avail_tasks.begin(), avail_tasks.end(), [&](int a, int b){return cp[a]>cp[b];});\n        \n        vector<pair<int,int>> assignments;\n        \n        if(fm > 0 && at > 0){\n            int assign_count = min(fm, at);\n            \n            // Two-phase: first select top tasks by CP, then Hungarian match\n            // But also try extending candidates slightly for better matching\n            int n_cand = min(at, assign_count * 2);\n            n_cand = min(n_cand, 40);\n            n_cand = max(n_cand, assign_count);\n            \n            // Run Hungarian on n_cand \u00d7 fm, padded to n = max(n_cand, fm)\n            int n = max(n_cand, fm);\n            vector<vector<double>> cost(n, vector<double>(n, 0.0));\n            \n            for(int i=0;i<n_cand;i++){\n                for(int j=0;j<fm;j++){\n                    double t = est_time_val(avail_tasks[i], free_members[j]);\n                    // Subtract CP bonus to incentivize picking critical tasks\n                    cost[i][j] = t - cp[avail_tasks[i]] * 0.12;\n                }\n                for(int j=fm;j<n;j++) cost[i][j] = 300.0; // penalty for unassigned real task\n            }\n            // Dummy task rows (idle member is OK if no tasks)\n            for(int i=n_cand;i<n;i++)\n                for(int j=0;j<n;j++) cost[i][j] = 0.0;\n            \n            auto asgn = hungarian_min(cost, n);\n            \n            set<int> used_m;\n            for(int i=0;i<n_cand;i++){\n                int j = asgn[i];\n                if(j < fm && !used_m.count(j)){\n                    used_m.insert(j);\n                    int task = avail_tasks[i];\n                    int mem = free_members[j];\n                    assignments.push_back({mem, task});\n                    task_status[task]=0;\n                    member_task[mem]=task;\n                    member_start[mem]=day;\n                }\n            }\n            \n            // Fill remaining members greedily\n            for(int i=0;i<at && (int)used_m.size()<fm;i++){\n                int task = avail_tasks[i];\n                if(task_status[task]!=-1) continue;\n                int best_m=-1; double best_t=1e18;\n                for(int jj=0;jj<fm;jj++){\n                    if(used_m.count(jj)) continue;\n                    double t = est_time_val(task, free_members[jj]);\n                    if(t<best_t){best_t=t;best_m=jj;}\n                }\n                if(best_m>=0){\n                    used_m.insert(best_m);\n                    int mem = free_members[best_m];\n                    assignments.push_back({mem, task});\n                    task_status[task]=0;\n                    member_task[mem]=task;\n                    member_start[mem]=day;\n                }\n            }\n        }\n        \n        printf(\"%d\",(int)assignments.size());\n        for(auto&[a,b]:assignments) printf(\" %d %d\",a+1,b+1);\n        printf(\"\\n\");\n        fflush(stdout);\n        \n        int n_done; scanf(\"%d\",&n_done);\n        if(n_done==-1) return 0;\n        for(int i=0;i<n_done;i++){\n            int f; scanf(\"%d\",&f); f--;\n            int task=member_task[f];\n            int t_obs=day-member_start[f]+1;\n            task_status[task]=1;\n            member_task[f]=-1;\n            update_skills(f, task, t_obs);\n        }\n    }\n    \n    int dummy; scanf(\"%d\",&dummy);\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto t0=chrono::steady_clock::now();\n    auto elapsed=[&](){return chrono::duration<double>(chrono::steady_clock::now()-t0).count();};\n    \n    const int N=1000, M=50, K=2*M;\n    vector<int> a(N),b(N),c(N),d(N);\n    for(int i=0;i<N;i++) cin>>a[i]>>b[i]>>c[i]>>d[i];\n    \n    auto md=[](int x1,int y1,int x2,int y2)->int{return abs(x1-x2)+abs(y1-y2);};\n    \n    vector<double> sc(N);\n    for(int i=0;i<N;i++){\n        sc[i] = md(400,400,a[i],b[i]) + md(a[i],b[i],c[i],d[i]) + md(c[i],d[i],400,400);\n    }\n    vector<int> sidx(N);\n    iota(sidx.begin(),sidx.end(),0);\n    sort(sidx.begin(),sidx.end(),[&](int i,int j){return sc[i]<sc[j];});\n    \n    vector<int> chosen(sidx.begin(),sidx.begin()+M);\n    \n    mt19937 rng(42);\n    vector<int> px(K),py(K);\n    \n    auto setupCoords=[&](){\n        for(int i=0;i<M;i++){\n            px[2*i]=a[chosen[i]]; py[2*i]=b[chosen[i]];\n            px[2*i+1]=c[chosen[i]]; py[2*i+1]=d[chosen[i]];\n        }\n    };\n    \n    auto gdist=[&](int u, int v)->int{\n        int x1=u<0?400:px[u], y1=u<0?400:py[u];\n        int x2=v<0?400:px[v], y2=v<0?400:py[v];\n        return abs(x1-x2)+abs(y1-y2);\n    };\n    \n    auto greedyRoute=[&]()->vector<int>{\n        vector<int> route;\n        vector<bool> visited(K,false);\n        vector<bool> picked(M,false);\n        int cx=400,cy=400;\n        for(int step=0;step<K;step++){\n            int best=-1, bestd=INT_MAX;\n            for(int j=0;j<K;j++){\n                if(visited[j]) continue;\n                int ord=j/2; bool isDel=(j%2==1);\n                if(isDel && !picked[ord]) continue;\n                int d2=md(cx,cy,px[j],py[j]);\n                if(d2<bestd){bestd=d2;best=j;}\n            }\n            visited[best]=true;\n            if(best%2==0) picked[best/2]=true;\n            route.push_back(best);\n            cx=px[best]; cy=py[best];\n        }\n        return route;\n    };\n    \n    auto calcCost=[&](vector<int>& r)->int{\n        int t=gdist(-1,r[0]);\n        for(int i=0;i+1<K;i++) t+=gdist(r[i],r[i+1]);\n        t+=gdist(r.back(),-1);\n        return t;\n    };\n    \n    auto checkFeasible=[&](vector<int>& r)->bool{\n        vector<int> pos(K);\n        for(int i=0;i<K;i++) pos[r[i]]=i;\n        for(int i=0;i<M;i++) if(pos[2*i]>pos[2*i+1]) return false;\n        return true;\n    };\n    \n    setupCoords();\n    vector<int> route=greedyRoute();\n    int curCost=calcCost(route);\n    \n    vector<int> bestRoute=route;\n    vector<int> bestChosen=chosen;\n    int bestGlobalCost=curCost;\n    \n    // SA on route\n    auto optimizeRoute=[&](vector<int>& rt, double tl)->int{\n        int cost=calcCost(rt);\n        vector<int> pos(K);\n        for(int i=0;i<K;i++) pos[rt[i]]=i;\n        \n        int localBestCost=cost;\n        vector<int> localBestRoute=rt;\n        \n        while(elapsed()<tl){\n            double ratio=(tl-elapsed())/(tl-0.0);\n            if(ratio<0) break;\n            double temp=150.0*ratio;\n            \n            // Do a batch\n            for(int iter=0;iter<500;iter++){\n                int op=rng()%10;\n                \n                if(op<6){\n                    // 2-opt\n                    int i=rng()%K, j=rng()%K;\n                    if(i>j) swap(i,j);\n                    if(i==j||j-i>=K-1) continue;\n                    \n                    int pI=(i==0)?-1:rt[i-1];\n                    int nJ=(j==K-1)?-1:rt[j+1];\n                    int delta=gdist(pI,rt[j])+gdist(rt[i],nJ)-gdist(pI,rt[i])-gdist(rt[j],nJ);\n                    \n                    bool accept=(delta<0)||(temp>0.01 && (rng()%1000000)<1000000.0*exp(-(double)delta/temp));\n                    if(!accept) continue;\n                    \n                    // Check feasibility\n                    bool ok=true;\n                    for(int p=i;p<=j&&ok;p++){\n                        int node=rt[p];\n                        int ord=node/2;\n                        int partner=(node%2==0)?node+1:node-1;\n                        int pp=pos[partner];\n                        int np=i+j-p;\n                        if(pp>=i && pp<=j){\n                            int npp=i+j-pp;\n                            if(node%2==0){ if(np>=npp) ok=false; }\n                            else { if(np<=npp) ok=false; }\n                        } else {\n                            if(node%2==0){ if(np>=pp) ok=false; }\n                            else { if(np<=pp) ok=false; }\n                        }\n                    }\n                    if(ok){\n                        reverse(rt.begin()+i,rt.begin()+j+1);\n                        for(int p=i;p<=j;p++) pos[rt[p]]=p;\n                        cost+=delta;\n                        if(cost<localBestCost){localBestCost=cost;localBestRoute=rt;}\n                    }\n                } else {\n                    // Relocate\n                    int i=rng()%K;\n                    int node=rt[i];\n                    int ord=node/2;\n                    bool isDel=(node%2==1);\n                    int partnerPos=pos[isDel?(2*ord):(2*ord+1)];\n                    \n                    int pI=(i==0)?-1:rt[i-1];\n                    int nI=(i==K-1)?-1:rt[i+1];\n                    int remSave=gdist(pI,node)+gdist(node,nI)-gdist(pI,nI);\n                    \n                    // Pick random target\n                    int j=rng()%(K-1);\n                    // j is insert position in the array after removal\n                    // Adjust: after removing pos i, array shrinks\n                    // Precedence: pickup before delivery\n                    int adjPartner=partnerPos>(i)?partnerPos-1:partnerPos;\n                    if(isDel){ if(j<=adjPartner) continue; }\n                    else { if(j>adjPartner) continue; }\n                    \n                    // Compute insert cost\n                    // Build temp array mentally\n                    // After removing i, element at new pos j-1 and j\n                    // We need actual nodes at those positions\n                    // Remove rt[i], positions shift\n                    int pJ,nJ_node;\n                    {\n                        // Map j in reduced array back\n                        int rj=j; // position in reduced array\n                        if(rj==0) pJ=-1;\n                        else {\n                            int orig=rj; if(orig>=i) orig++; \n                            // Wait, let me just be careful\n                            // reduced[k] = rt[k] if k<i, rt[k+1] if k>=i\n                            int prevOrig=(rj-1<i)?(rj-1):(rj);\n                            pJ=rt[prevOrig];\n                        }\n                        if(rj==K-1) nJ_node=-1;\n                        else {\n                            int nextOrig=(rj<i)?rj:(rj+1);\n                            nJ_node=rt[nextOrig];\n                        }\n                    }\n                    int insCost=gdist(pJ,node)+gdist(node,nJ_node)-gdist(pJ,nJ_node);\n                    int delta=insCost-remSave;\n                    \n                    bool accept=(delta<0)||(temp>0.01 && (rng()%1000000)<1000000.0*exp(-(double)delta/temp));\n                    if(!accept) continue;\n                    \n                    // Actually do it\n                    rt.erase(rt.begin()+i);\n                    int insertPos=j;\n                    rt.insert(rt.begin()+insertPos,node);\n                    for(int p=0;p<K;p++) pos[rt[p]]=p;\n                    cost+=delta;\n                    if(cost<localBestCost){localBestCost=cost;localBestRoute=rt;}\n                }\n            }\n            // Periodically fix cost drift\n            cost=calcCost(rt);\n        }\n        rt=localBestRoute;\n        return localBestCost;\n    };\n    \n    curCost=optimizeRoute(route,0.8);\n    if(curCost<bestGlobalCost){\n        bestGlobalCost=curCost; bestRoute=route; bestChosen=chosen;\n    }\n    \n    // Try order swaps\n    set<int> inSet(chosen.begin(),chosen.end());\n    vector<int> notChosen;\n    for(int i=0;i<N;i++) if(!inSet.count(i)) notChosen.push_back(i);\n    \n    while(elapsed()<1.85){\n        int ci=rng()%M, ni=rng()%(int)notChosen.size();\n        int oldOrd=chosen[ci], newOrd=notChosen[ni];\n        chosen[ci]=newOrd;\n        setupCoords();\n        auto rt=greedyRoute();\n        double budget=min(elapsed()+0.08, 1.85);\n        int c=optimizeRoute(rt,budget);\n        if(c<bestGlobalCost){\n            bestGlobalCost=c; bestRoute=rt; bestChosen=chosen;\n            inSet.erase(oldOrd); inSet.insert(newOrd);\n            notChosen[ni]=oldOrd;\n        } else {\n            chosen[ci]=oldOrd;\n        }\n    }\n    \n    // Restore best\n    chosen=bestChosen;\n    setupCoords();\n    route=bestRoute;\n    \n    // Validate\n    assert(checkFeasible(route));\n    assert((int)route.size()==K);\n    \n    cout<<M;\n    for(int i=0;i<M;i++) cout<<\" \"<<chosen[i]+1;\n    cout<<\"\\n\";\n    cout<<K+2<<\" 400 400\";\n    for(int j=0;j<K;j++) cout<<\" \"<<px[route[j]]<<\" \"<<py[route[j]];\n    cout<<\" 400 400\\n\";\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, sz;\n    DSU(int n): p(n), sz(n,1) { iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a, int b){ a=find(a);b=find(b);if(a==b)return false;if(sz[a]<sz[b])swap(a,b);p[b]=a;sz[a]+=sz[b];return true;}\n    bool same(int a,int b){return find(a)==find(b);}\n};\n\n// Compute expected online cost for k edges with given d values\n// Using optimal stopping: for each edge seen, accept if cost <= threshold\n// We approximate with expected min * correction factor\ndouble compute_online_expected(vector<double>& dvec) {\n    if(dvec.empty()) return 1e18;\n    int k = dvec.size();\n    \n    // Compute expected min via integration\n    double lo = 1e18, hi = 0;\n    for(double d : dvec) { lo = min(lo, d); hi = max(hi, 3*d); }\n    \n    int steps = 200;\n    double dt = (hi - lo) / steps;\n    double em = 0;\n    for(int s = 0; s < steps; s++) {\n        double t = lo + (s + 0.5) * dt;\n        double p = 1.0;\n        for(double d : dvec) {\n            if(t < d) continue;\n            else if(t >= 3*d) { p = 0; break; }\n            else p *= (3*d - t) / (2*d);\n        }\n        em += p * dt;\n    }\n    em += lo;\n    \n    // Online penalty: with k options seen sequentially,\n    // optimal online strategy pays roughly E[min] * (1 + c/sqrt(k)) more\n    // For small k, the penalty is larger\n    // Empirically calibrated:\n    double online_factor;\n    if(k == 1) online_factor = 1.0; // must take whatever comes, expected = 2*d\n    else if(k == 2) online_factor = 1.08;\n    else if(k <= 4) online_factor = 1.05;\n    else online_factor = 1.03;\n    \n    return em * online_factor;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    int N = 400, M = 1995;\n    vector<int> x(N), y(N);\n    for(int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    vector<int> U(M), V(M);\n    vector<double> D(M);\n    for(int i = 0; i < M; i++){\n        cin >> U[i] >> V[i];\n        double dx = x[U[i]] - x[V[i]], dy = y[U[i]] - y[V[i]];\n        D[i] = round(sqrt(dx*dx + dy*dy));\n    }\n    \n    DSU dsu(N);\n    \n    for(int i = 0; i < M; i++){\n        int l; cin >> l;\n        \n        if(dsu.same(U[i], V[i])){\n            cout << 0 << \"\\n\" << flush;\n            continue;\n        }\n        \n        int fu = dsu.find(U[i]), fv = dsu.find(V[i]);\n        \n        // Build component graph from remaining future edges\n        map<pair<int,int>, vector<double>> comp_edges;\n        DSU tmp(N);\n        \n        for(int j = i+1; j < M; j++){\n            int a = dsu.find(U[j]), b = dsu.find(V[j]);\n            if(a == b) continue;\n            tmp.unite(a, b);\n            if(a > b) swap(a, b);\n            comp_edges[{a, b}].push_back(D[j]);\n        }\n        \n        bool still_connected = tmp.same(fu, fv);\n        if(!still_connected){\n            cout << 1 << \"\\n\" << flush;\n            dsu.unite(U[i], V[i]);\n            continue;\n        }\n        \n        // Build adjacency for Dijkstra on components\n        map<int, int> cmap;\n        int nc = 0;\n        auto get_id = [&](int c) -> int {\n            auto it = cmap.find(c);\n            if(it == cmap.end()) { cmap[c] = nc; return nc++; }\n            return it->second;\n        };\n        get_id(fu); get_id(fv);\n        \n        for(auto& [pr, dvec] : comp_edges) {\n            get_id(pr.first); get_id(pr.second);\n        }\n        \n        vector<vector<pair<int, double>>> adj(nc);\n        for(auto& [pr, dvec] : comp_edges) {\n            double cost = compute_online_expected(dvec);\n            int a = cmap[pr.first], b = cmap[pr.second];\n            adj[a].push_back({b, cost});\n            adj[b].push_back({a, cost});\n        }\n        \n        // Dijkstra from fu to fv\n        vector<double> dist(nc, 1e18);\n        int src = cmap[fu], dst = cmap[fv];\n        priority_queue<pair<double,int>, vector<pair<double,int>>, greater<>> pq;\n        dist[src] = 0; 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, w] : adj[u]){\n                if(dist[u] + w < dist[v]){\n                    dist[v] = dist[u] + w;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        double alt_path_cost = dist[dst];\n        \n        // Accept if l is at most alt_path_cost\n        // Slight adjustment: if l is close to alt_path_cost, we're indifferent\n        // Being slightly generous with acceptance helps avoid being stuck\n        if((double)l <= alt_path_cost * 1.0){\n            cout << 1 << \"\\n\" << flush;\n            dsu.unite(U[i], V[i]);\n        } else {\n            cout << 0 << \"\\n\" << flush;\n        }\n    }\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int GS=30;\nint N,M;\nint px[25],py[25],ptype[25];\nint hx[15],hy[15];\nbool wall_[35][35];\n\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\nchar dmc[]={'U','D','L','R'};\nchar dpc[]={'u','d','l','r'};\n\nbool inB(int x,int y){return x>=1&&x<=GS&&y>=1&&y<=GS;}\n\nbool hasPetAdjacentOrOn(int x,int y){\n    for(int i=0;i<N;i++)\n        if(abs(px[i]-x)+abs(py[i]-y)<=1) return true;\n    return false;\n}\nbool hasHumanAt(int x,int y){\n    for(int i=0;i<M;i++) if(hx[i]==x&&hy[i]==y) return true;\n    return false;\n}\n\nint bfsDist(int sx,int sy,int tx,int ty){\n    if(sx==tx&&sy==ty) return 0;\n    int dist[31][31];\n    memset(dist,-1,sizeof(dist));\n    dist[sx][sy]=0;\n    queue<pair<int,int>> q;\n    q.push({sx,sy});\n    while(!q.empty()){\n        auto [cx,cy]=q.front();q.pop();\n        for(int d=0;d<4;d++){\n            int nx=cx+dx[d],ny=cy+dy[d];\n            if(inB(nx,ny)&&!wall_[nx][ny]&&dist[nx][ny]==-1){\n                dist[nx][ny]=dist[cx][cy]+1;\n                if(nx==tx&&ny==ty) return dist[nx][ny];\n                q.push({nx,ny});\n            }\n        }\n    }\n    return 1e9;\n}\n\nvector<pair<int,int>> bfsPath(int sx,int sy,int tx,int ty){\n    if(sx==tx&&sy==ty) return {};\n    int prev[31][31];\n    memset(prev,-1,sizeof(prev));\n    prev[sx][sy]=-2;\n    queue<pair<int,int>> q;\n    q.push({sx,sy});\n    while(!q.empty()){\n        auto [cx,cy]=q.front();q.pop();\n        for(int d=0;d<4;d++){\n            int nx=cx+dx[d],ny=cy+dy[d];\n            if(inB(nx,ny)&&!wall_[nx][ny]&&prev[nx][ny]==-1){\n                prev[nx][ny]=d;\n                if(nx==tx&&ny==ty){\n                    vector<pair<int,int>> path;\n                    int x=tx,y=ty;\n                    while(x!=sx||y!=sy){\n                        path.push_back({x,y});\n                        int dd=prev[x][y];\n                        x-=dx[dd];y-=dy[dd];\n                    }\n                    reverse(path.begin(),path.end());\n                    return path;\n                }\n                q.push({nx,ny});\n            }\n        }\n    }\n    return {};\n}\n\n// Evaluate a rectangular safe region bounded by walls (and grid edges)\n// safeR1..safeR2, safeC1..safeC2 is the interior\n// wallRows/wallCols are the rows/cols that need walls\nstruct Plan {\n    int safeR1,safeR2,safeC1,safeC2;\n    vector<pair<int,int>> wallCells;\n    double score;\n    int petsInside, humansInside;\n    int area;\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin>>N;\n    for(int i=0;i<N;i++) cin>>px[i]>>py[i]>>ptype[i];\n    cin>>M;\n    for(int i=0;i<M;i++) cin>>hx[i]>>hy[i];\n    \n    memset(wall_,false,sizeof(wall_));\n    \n    // Evaluate rectangular regions that use grid edges + wall lines\n    // A region can be: corner (2 wall lines), edge strip (1 wall line), or band (2 parallel lines)\n    \n    Plan bestPlan;\n    bestPlan.score = -1e18;\n    \n    auto evaluate = [&](int r1, int r2, int c1, int c2) {\n        // Safe interior: r1..r2, c1..c2\n        // Walls needed: row r1-1 if r1>1, row r2+1 if r2<30, col c1-1 if c1>1, col c2+1 if c2<30\n        Plan p;\n        p.safeR1=r1; p.safeR2=r2; p.safeC1=c1; p.safeC2=c2;\n        p.wallCells.clear();\n        \n        // Top wall\n        if(r1>1) for(int c=max(1,c1-1);c<=min(30,c2+1);c++) p.wallCells.push_back({r1-1,c});\n        // Bottom wall\n        if(r2<30) for(int c=max(1,c1-1);c<=min(30,c2+1);c++) p.wallCells.push_back({r2+1,c});\n        // Left wall\n        if(c1>1) for(int r=r1;r<=r2;r++) p.wallCells.push_back({r,c1-1});\n        // Right wall\n        if(c2<30) for(int r=r1;r<=r2;r++) p.wallCells.push_back({r,c2+1});\n        \n        p.petsInside=0;\n        for(int i=0;i<N;i++)\n            if(px[i]>=r1&&px[i]<=r2&&py[i]>=c1&&py[i]<=c2) p.petsInside++;\n        p.humansInside=0;\n        for(int i=0;i<M;i++)\n            if(hx[i]>=r1&&hx[i]<=r2&&hy[i]>=c1&&hy[i]<=c2) p.humansInside++;\n        \n        p.area=(r2-r1+1)*(c2-c1+1);\n        int wallCount=(int)p.wallCells.size();\n        \n        // Each person can build ~1 wall/turn, but needs to travel\n        // Estimate turns to complete: wallCount/M + travel time\n        // People inside can build, people outside need to get inside first\n        int humansOutside = M - p.humansInside;\n        double turnsEstimate = (double)wallCount / M + humansOutside * 5;\n        \n        // If too many walls for available turns, penalize\n        if(turnsEstimate > 250) {\n            p.score = -1e18;\n        } else {\n            // Score ~ area/900 * 2^(-petsInside) * humansInside/M\n            // But pets inside will likely leave if we build walls after they leave\n            // Pets outside won't get in once walls are built\n            // Key: minimize initial pets inside (they might escape during building)\n            double areaScore = (double)p.area / 900.0;\n            double petPenalty = pow(2.0, -(double)p.petsInside);\n            double humanFrac = (double)max(p.humansInside,1) / M;\n            p.score = areaScore * petPenalty * humanFrac * 1000 - wallCount * 0.1;\n            // Bonus for using edges (fewer walls needed)\n            if(r1==1) p.score *= 1.1;\n            if(r2==30) p.score *= 1.1;\n            if(c1==1) p.score *= 1.1;\n            if(c2==30) p.score *= 1.1;\n        }\n        \n        return p;\n    };\n    \n    // Try various rectangular regions\n    // Edge strips (1 wall line)\n    for(int w=3;w<=28;w++){\n        // Top strip: rows 1..w\n        auto p=evaluate(1,w,1,30); if(p.score>bestPlan.score) bestPlan=p;\n        // Bottom strip\n        p=evaluate(31-w,30,1,30); if(p.score>bestPlan.score) bestPlan=p;\n        // Left strip\n        p=evaluate(1,30,1,w); if(p.score>bestPlan.score) bestPlan=p;\n        // Right strip\n        p=evaluate(1,30,31-w,30); if(p.score>bestPlan.score) bestPlan=p;\n    }\n    \n    // Corner regions (2 wall lines)\n    for(int h=4;h<=25;h++){\n        for(int w=4;w<=25;w++){\n            auto p=evaluate(1,h,1,w); if(p.score>bestPlan.score) bestPlan=p;\n            p=evaluate(1,h,31-w,30); if(p.score>bestPlan.score) bestPlan=p;\n            p=evaluate(31-h,30,1,w); if(p.score>bestPlan.score) bestPlan=p;\n            p=evaluate(31-h,30,31-w,30); if(p.score>bestPlan.score) bestPlan=p;\n        }\n    }\n    \n    // Band regions (2 wall lines, center)\n    for(int r1=3;r1<=15;r1++){\n        for(int r2=r1+3;r2<=28;r2++){\n            auto p=evaluate(r1,r2,1,30); if(p.score>bestPlan.score) bestPlan=p;\n        }\n    }\n    for(int c1=3;c1<=15;c1++){\n        for(int c2=c1+3;c2<=28;c2++){\n            auto p=evaluate(1,30,c1,c2); if(p.score>bestPlan.score) bestPlan=p;\n        }\n    }\n    \n    // Now execute the plan\n    set<pair<int,int>> wallNeeded;\n    for(auto& wc: bestPlan.wallCells) wallNeeded.insert(wc);\n    \n    int sR1=bestPlan.safeR1, sR2=bestPlan.safeR2, sC1=bestPlan.safeC1, sC2=bestPlan.safeC2;\n    \n    auto inSafe=[&](int r,int c)->bool{\n        return r>=sR1&&r<=sR2&&c>=sC1&&c<=sC2;\n    };\n    \n    // Phase approach:\n    // Phase 1: Move all people toward safe zone (or toward wall building positions)\n    // Phase 2: Build walls\n    // Phase 3: Stay safe\n    \n    for(int turn=0;turn<300;turn++){\n        string actions(M,'.');\n        \n        // Remove completed walls\n        {\n            vector<pair<int,int>> rem;\n            for(auto& w:wallNeeded) if(wall_[w.first][w.second]) rem.push_back(w);\n            for(auto& w:rem) wallNeeded.erase(w);\n        }\n        \n        set<pair<int,int>> newWallsThisTurn;\n        set<pair<int,int>> movingTo; // squares people are moving to\n        \n        // Assign each person\n        for(int p=0;p<M;p++){\n            int bx=hx[p],by=hy[p];\n            \n            // Try to build adjacent wall cell\n            // Prefer building from safe side\n            int bestD=-1;\n            int bestPri=-1;\n            for(int d=0;d<4;d++){\n                int nx=bx+dx[d],ny=by+dy[d];\n                if(!inB(nx,ny)) continue;\n                if(!wallNeeded.count({nx,ny})) continue;\n                if(wall_[nx][ny]) continue;\n                if(hasPetAdjacentOrOn(nx,ny)) continue;\n                if(hasHumanAt(nx,ny)) continue;\n                int pri=1;\n                if(inSafe(bx,by)) pri=10; // building from safe side is better\n                if(pri>bestPri){bestPri=pri;bestD=d;}\n            }\n            \n            if(bestD>=0){\n                int nx=bx+dx[bestD],ny=by+dy[bestD];\n                actions[p]=dpc[bestD];\n                newWallsThisTurn.insert({nx,ny});\n                wallNeeded.erase({nx,ny});\n                continue;\n            }\n            \n            // If in safe zone and walls are done, stay\n            if(wallNeeded.empty() && inSafe(bx,by)){\n                actions[p]='.';\n                continue;\n            }\n            \n            // Move toward: nearest wall cell build position (on safe side), or safe zone\n            pair<int,int> bestTgt={-1,-1};\n            int bestDist=1e9;\n            \n            if(!wallNeeded.empty()){\n                for(auto& wc:wallNeeded){\n                    for(int d=0;d<4;d++){\n                        int ax=wc.first+dx[d],ay=wc.second+dy[d];\n                        if(!inB(ax,ay)||wall_[ax][ay]) continue;\n                        // Prefer safe side positions\n                        int pri=0;\n                        if(inSafe(ax,ay)) pri=-100;\n                        int dist=abs(bx-ax)+abs(by-ay)+pri;\n                        if(dist<bestDist){bestDist=dist;bestTgt={ax,ay};}\n                    }\n                }\n            }\n            \n            if(bestTgt.first==-1){\n                // Move toward center of safe zone\n                int tr=(sR1+sR2)/2,tc=(sC1+sC2)/2;\n                bestTgt={tr,tc};\n            }\n            \n            if(bestTgt.first==bx&&bestTgt.second==by){\n                actions[p]='.';\n                continue;\n            }\n            \n            auto path=bfsPath(bx,by,bestTgt.first,bestTgt.second);\n            if(!path.empty()){\n                int nx=path[0].first,ny=path[0].second;\n                if(inB(nx,ny)&&!wall_[nx][ny]&&!newWallsThisTurn.count({nx,ny})){\n                    for(int d=0;d<4;d++){\n                        if(bx+dx[d]==nx&&by+dy[d]==ny){\n                            actions[p]=dmc[d];\n                            movingTo.insert({nx,ny});\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Apply\n        for(int p=0;p<M;p++){\n            char a=actions[p];\n            bool acted=false;\n            for(int d=0;d<4;d++){\n                if(a==dpc[d]){\n                    int nx=hx[p]+dx[d],ny=hy[p]+dy[d];\n                    if(inB(nx,ny)) wall_[nx][ny]=true;\n                    acted=true;\n                }\n                if(a==dmc[d]){\n                    int nx=hx[p]+dx[d],ny=hy[p]+dy[d];\n                    if(inB(nx,ny)&&!wall_[nx][ny]){\n                        hx[p]=nx;hy[p]=ny;\n                    }\n                    acted=true;\n                }\n            }\n        }\n        \n        cout<<actions<<\"\\n\";\n        cout.flush();\n        \n        for(int i=0;i<N;i++){\n            string s;cin>>s;\n            for(char c:s){\n                for(int d=0;d<4;d++){\n                    if(c==dmc[d]){px[i]+=dx[d];py[i]+=dy[d];}\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint si,sj,ti,tj;\ndouble p;\nbool hwall[20][19], vwall[19][20];\nint di_[]={-1,1,0,0}, dj_[]={0,0,-1,1};\nint bfs_dist[20][20];\n\nbool can_move(int i,int j,int d){\n    if(d==0) return i>0 && !vwall[i-1][j];\n    if(d==1) return i<19 && !vwall[i][j];\n    if(d==2) return j>0 && !hwall[i][j-1];\n    if(d==3) return j<19 && !hwall[i][j];\n    return false;\n}\n\nvoid compute_bfs(){\n    memset(bfs_dist,-1,sizeof(bfs_dist));\n    queue<pair<int,int>> Q;\n    bfs_dist[ti][tj]=0; Q.push({ti,tj});\n    while(!Q.empty()){\n        auto [ci,cj]=Q.front(); Q.pop();\n        for(int d=0;d<4;d++){\n            if(!can_move(ci,cj,d)) continue;\n            int ni=ci+di_[d], nj=cj+dj_[d];\n            if(bfs_dist[ni][nj]>=0) continue;\n            bfs_dist[ni][nj]=bfs_dist[ci][cj]+1;\n            Q.push({ni,nj});\n        }\n    }\n}\n\n// prob snapshots: snap[t] = probability distribution before step t\ndouble snap[201][20][20];\n\ndouble full_evaluate(const vector<int>& dirs){\n    memset(snap,0,sizeof(snap));\n    snap[0][si][sj]=1.0;\n    double total=0;\n    int L=dirs.size();\n    for(int t=0;t<L;t++){\n        int d=dirs[t];\n        double reward=401.0-(t+1);\n        memset(snap[t+1],0,sizeof(snap[t+1]));\n        for(int i=0;i<20;i++) for(int j=0;j<20;j++) if(snap[t][i][j]>1e-15){\n            snap[t+1][i][j]+=snap[t][i][j]*p;\n            if(can_move(i,j,d)){\n                int ni=i+di_[d],nj=j+dj_[d];\n                if(ni==ti&&nj==tj) total+=snap[t][i][j]*(1-p)*reward;\n                else snap[t+1][ni][nj]+=snap[t][i][j]*(1-p);\n            } else snap[t+1][i][j]+=snap[t][i][j]*(1-p);\n        }\n    }\n    return total;\n}\n\n// Evaluate score from step 'start' given probability at start\ndouble eval_from(const vector<int>& dirs, int start){\n    // Uses snap[start] as starting distribution\n    double prob[20][20];\n    memcpy(prob, snap[start], sizeof(prob));\n    double total=0;\n    int L=dirs.size();\n    for(int t=start;t<L;t++){\n        int d=dirs[t];\n        double reward=401.0-(t+1);\n        double nprob[20][20]={};\n        for(int i=0;i<20;i++) for(int j=0;j<20;j++) if(prob[i][j]>1e-15){\n            nprob[i][j]+=prob[i][j]*p;\n            if(can_move(i,j,d)){\n                int ni=i+di_[d],nj=j+dj_[d];\n                if(ni==ti&&nj==tj) total+=prob[i][j]*(1-p)*reward;\n                else nprob[ni][nj]+=prob[i][j]*(1-p);\n            } else nprob[i][j]+=prob[i][j]*(1-p);\n        }\n        memcpy(prob,nprob,sizeof(prob));\n    }\n    return total;\n}\n\nvector<int> greedy_solution(double alpha){\n    double prob[20][20]={};\n    prob[si][sj]=1.0;\n    vector<int> dirs;\n    for(int t=0;t<200;t++){\n        double reward=401.0-(t+1);\n        int bestd=0; double bestval=-1e18;\n        for(int d=0;d<4;d++){\n            double arrival=0,expected_dist=0;\n            for(int i=0;i<20;i++) for(int j=0;j<20;j++) if(prob[i][j]>1e-15){\n                expected_dist+=prob[i][j]*p*bfs_dist[i][j];\n                if(can_move(i,j,d)){\n                    int ni=i+di_[d],nj=j+dj_[d];\n                    if(ni==ti&&nj==tj) arrival+=prob[i][j]*(1-p);\n                    else expected_dist+=prob[i][j]*(1-p)*bfs_dist[ni][nj];\n                } else expected_dist+=prob[i][j]*(1-p)*bfs_dist[i][j];\n            }\n            double val=arrival*reward*alpha-expected_dist;\n            if(val>bestval){bestval=val;bestd=d;}\n        }\n        dirs.push_back(bestd);\n        double nprob[20][20]={};\n        for(int i=0;i<20;i++) for(int j=0;j<20;j++) if(prob[i][j]>1e-15){\n            nprob[i][j]+=prob[i][j]*p;\n            if(can_move(i,j,bestd)){\n                int ni=i+di_[bestd],nj=j+dj_[bestd];\n                if(!(ni==ti&&nj==tj)) nprob[ni][nj]+=prob[i][j]*(1-p);\n            } else nprob[i][j]+=prob[i][j]*(1-p);\n        }\n        memcpy(prob,nprob,sizeof(prob));\n    }\n    return dirs;\n}\n\nint main(){\n    auto t0=steady_clock::now();\n    scanf(\"%d%d%d%d%lf\",&si,&sj,&ti,&tj,&p);\n    for(int i=0;i<20;i++){\n        char s[25]; scanf(\"%s\",s);\n        for(int j=0;j<19;j++) hwall[i][j]=(s[j]=='1');\n    }\n    for(int i=0;i<19;i++){\n        char s[25]; scanf(\"%s\",s);\n        for(int j=0;j<20;j++) vwall[i][j]=(s[j]=='1');\n    }\n    compute_bfs();\n    \n    vector<int> best_dirs;\n    double best_score=-1;\n    \n    double alphas[]={0.0,0.001,0.002,0.005,0.01,0.02,0.03,0.05,0.07,0.1,0.15,0.2,0.3,0.5,0.7,1.0,1.5,2.0,3.0,5.0,7.0,10.0,15.0,20.0,30.0,50.0,75.0,100.0,200.0,500.0};\n    for(double alpha:alphas){\n        auto dirs=greedy_solution(alpha);\n        double sc=full_evaluate(dirs);\n        if(sc>best_score){best_score=sc;best_dirs=dirs;}\n    }\n    \n    // Local search\n    full_evaluate(best_dirs); // fills snap\n    \n    for(int iter=0;iter<100;iter++){\n        auto elapsed=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n        if(elapsed>1700) break;\n        \n        bool improved=false;\n        for(int t=0;t<200;t++){\n            auto elapsed2=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n            if(elapsed2>1700) break;\n            \n            int orig_d=best_dirs[t];\n            double orig_sc=eval_from(best_dirs,t);\n            int bestd=orig_d;\n            double bestsc=orig_sc;\n            \n            for(int d=0;d<4;d++){\n                if(d==orig_d) continue;\n                best_dirs[t]=d;\n                double sc=eval_from(best_dirs,t);\n                if(sc>bestsc){bestsc=sc;bestd=d;}\n            }\n            best_dirs[t]=bestd;\n            if(bestd!=orig_d){\n                improved=true;\n                // Recompute snapshots from t+1\n                full_evaluate(best_dirs);\n            }\n        }\n        if(!improved) break;\n    }\n    \n    string ans;\n    for(int d:best_dirs) ans+=\"UDLR\"[d];\n    printf(\"%s\\n\",ans.c_str());\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\nconst int N=30;\nint tiles[N][N],orig[N][N],rot[N][N],best_rot[N][N];\nconst int di[]={0,-1,0,1},dj[]={-1,0,1,0};\nconst int TD[8][4]={{1,0,-1,-1},{3,-1,-1,0},{-1,-1,3,2},{-1,2,1,-1},{1,0,3,2},{3,2,1,0},{2,-1,0,-1},{-1,3,-1,1}};\nconst int RT[8][4]={{0,1,2,3},{1,2,3,0},{2,3,0,1},{3,0,1,2},{4,5,4,5},{5,4,5,4},{6,7,6,7},{7,6,7,6}};\n\nint lid[N*N*4]; // port -> loop_id (-1 if none)\nmap<int,int> llen; // loop_id -> length  \nmap<int,vector<int>> lports; // loop_id -> list of ports\nmultiset<int> lens;\nint nid=0;\n\ninline int port(int i,int j,int d){return(i*N+j)*4+d;}\n\nint trace_len(int si,int sj,int sd){\n    int i=si,j=sj,d=sd,len=0;\n    do{\n        int d2=TD[tiles[i][j]][d];\n        if(d2<0)return 0;\n        i+=di[d2];j+=dj[d2];\n        if((unsigned)i>=N||(unsigned)j>=N)return 0;\n        d=(d2+2)&3;len++;\n    }while(!(i==si&&j==sj&&d==sd));\n    return len;\n}\n\nvoid add_loop(int si,int sj,int sd){\n    int len=trace_len(si,sj,sd);\n    if(len<=0)return;\n    int id=nid++;\n    vector<int> pts;\n    int i=si,j=sj,d=sd;\n    do{\n        int p=port(i,j,d);\n        lid[p]=id;\n        pts.push_back(p);\n        int d2=TD[tiles[i][j]][d];\n        i+=di[d2];j+=dj[d2];\n        d=(d2+2)&3;\n    }while(!(i==si&&j==sj&&d==sd));\n    llen[id]=len;lports[id]=move(pts);lens.insert(len);\n}\n\nvoid rem_loop(int id){\n    for(int p:lports[id])lid[p]=-1;\n    lens.erase(lens.find(llen[id]));\n    llen.erase(id);lports.erase(id);\n}\n\nlong long score(){\n    if((int)lens.size()<2)return 0;\n    auto it=lens.end();--it;int a=*it;--it;return(long long)a*(*it);\n}\nlong long sscore(){long long s=0;for(int v:lens)s+=(long long)v*v;return s;}\n\nvoid init(){\n    memset(lid,-1,sizeof(lid));\n    llen.clear();lports.clear();lens.clear();nid=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)for(int d=0;d<4;d++){\n        if(lid[port(i,j,d)]>=0)continue;\n        if(TD[tiles[i][j]][d]<0)continue;\n        add_loop(i,j,d);\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(0);\n    for(int i=0;i<N;i++){string s;cin>>s;for(int j=0;j<N;j++)orig[i][j]=s[j]-'0';}\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){tiles[i][j]=orig[i][j];rot[i][j]=0;}\n    init();\n    long long bs=score(),cs=bs,css=sscore();\n    memcpy(best_rot,rot,sizeof(rot));\n    mt19937 rng(42);\n    auto start=chrono::steady_clock::now();\n    \n    while(true){\n        double el=chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(el>1.88)break;\n        double T=5000.0*(1.0-el/1.92)+1.0;\n        int ci=rng()%N,cj=rng()%N;\n        int or_=rot[ci][cj],ot=tiles[ci][cj];\n        int nr=(or_+1+rng()%3)%4;\n        \n        // Collect affected loop ids\n        set<int> aff;\n        for(int d=0;d<4;d++){\n            int p=port(ci,cj,d);\n            if(lid[p]>=0)aff.insert(lid[p]);\n            int ni=ci+di[d],nj=cj+dj[d];\n            if((unsigned)ni<N&&(unsigned)nj<N){\n                int np=port(ni,nj,(d+2)&3);\n                if(lid[np]>=0)aff.insert(lid[np]);\n            }\n        }\n        \n        // Save affected loops\n        struct SavedLoop{int id,len;vector<int>pts;};\n        vector<SavedLoop> saved;\n        for(int id:aff)saved.push_back({id,llen[id],lports[id]});\n        \n        // Find retrace starts (ports not at (ci,cj) for affected loops)\n        vector<pair<int,int>> retrace; // (port, after_change: i,j,d)\n        for(auto&sl:saved){\n            for(int p:sl.pts){\n                int i=p/4/N,j=(p/4)%N,d=p%4;\n                if(i!=ci||j!=cj){retrace.push_back({p,0});break;}\n            }\n        }\n        // Also need starts from neighbors pointing into (ci,cj)\n        vector<tuple<int,int,int>> nbr_starts;\n        for(int d=0;d<4;d++){\n            int ni=ci+di[d],nj=cj+dj[d];\n            if((unsigned)ni<N&&(unsigned)nj<N){\n                nbr_starts.push_back({ni,nj,(d+2)&3});\n            }\n        }\n        \n        // Remove affected loops\n        for(int id:aff)rem_loop(id);\n        \n        // Apply change\n        rot[ci][cj]=nr;\n        tiles[ci][cj]=RT[orig[ci][cj]][nr];\n        \n        // Retrace from saved starts and neighbor starts and cell ports\n        for(auto&[p,_]:retrace){\n            int i=p/4/N,j=(p/4)%N,d=p%4;\n            if(lid[port(i,j,d)]>=0)continue;\n            if(TD[tiles[i][j]][d]<0)continue;\n            add_loop(i,j,d);\n        }\n        for(auto&[i,j,d]:nbr_starts){\n            if(lid[port(i,j,d)]>=0)continue;\n            if(TD[tiles[i][j]][d]<0)continue;\n            add_loop(i,j,d);\n        }\n        for(int d=0;d<4;d++){\n            if(lid[port(ci,cj,d)]>=0)continue;\n            if(TD[tiles[ci][cj]][d]<0)continue;\n            add_loop(ci,cj,d);\n        }\n        \n        long long ns=score(),nss=sscore();\n        double ov=(double)cs+css*0.01,nv=(double)ns+nss*0.01;\n        if(nv>=ov||(rng()%10000)<10000*exp((nv-ov)/T)){\n            cs=ns;css=nss;\n            if(ns>bs){bs=ns;memcpy(best_rot,rot,sizeof(rot));}\n        }else{\n            // Undo: remove new loops at/around (ci,cj), restore old\n            set<int> new_aff;\n            for(int d=0;d<4;d++){\n                int p=port(ci,cj,d);\n                if(lid[p]>=0)new_aff.insert(lid[p]);\n                int ni=ci+di[d],nj=cj+dj[d];\n                if((unsigned)ni<N&&(unsigned)nj<N){\n                    int np=port(ni,nj,(d+2)&3);\n                    if(lid[np]>=0)new_aff.insert(lid[np]);\n                }\n            }\n            for(int id:new_aff)rem_loop(id);\n            \n            rot[ci][cj]=or_;tiles[ci][cj]=ot;\n            \n            // Restore saved loops\n            for(auto&sl:saved){\n                for(int p:sl.pts)lid[p]=sl.id;\n                llen[sl.id]=sl.len;lports[sl.id]=sl.pts;lens.insert(sl.len);\n            }\n        }\n    }\n    string ans(900,'0');\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)ans[i*30+j]='0'+best_rot[i][j];\n    cout<<ans<<endl;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N,T;\nint board[10][10];\nint ei,ej;\nint di[]={-1,1,0,0},dj[]={0,0,-1,1};\nint opp[]={1,0,3,2};\nconst char* dirs=\"UDLR\";\n\nint largest_tree(){\n    int id[10][10],cnt=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(board[i][j])id[i][j]=cnt++;else id[i][j]=-1;\n    vector<vector<int>>adj(cnt);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(!board[i][j])continue;\n        if(i+1<N&&board[i+1][j]&&(board[i][j]&8)&&(board[i+1][j]&2)){adj[id[i][j]].push_back(id[i+1][j]);adj[id[i+1][j]].push_back(id[i][j]);}\n        if(j+1<N&&board[i][j+1]&&(board[i][j]&4)&&(board[i][j+1]&1)){adj[id[i][j]].push_back(id[i][j+1]);adj[id[i][j+1]].push_back(id[i][j]);}\n    }\n    vector<bool>vis(cnt,false);\n    int best=0;\n    for(int s=0;s<cnt;s++)if(!vis[s]){\n        queue<int>q;q.push(s);vis[s]=true;\n        vector<int>comp;int edg=0;\n        while(!q.empty()){int u=q.front();q.pop();comp.push_back(u);for(int v:adj[u]){edg++;if(!vis[v]){vis[v]=true;q.push(v);}}}\n        edg/=2;\n        if(edg==(int)comp.size()-1)best=max(best,(int)comp.size());\n    }\n    return best;\n}\n\nint main(){\n    scanf(\"%d%d\",&N,&T);\n    for(int i=0;i<N;i++){char s[20];scanf(\"%s\",s);for(int j=0;j<N;j++){char c=s[j];board[i][j]=(c>='a'?c-'a'+10:c-'0');if(!board[i][j]){ei=i;ej=j;}}}\n    \n    string ans;\n    mt19937 rng(12345);\n    int cur=largest_tree();\n    int bestScore=cur;\n    string bestAns;\n    int bestBoard[10][10];int bestEi=ei,bestEj=ej;\n    memcpy(bestBoard,board,sizeof(board));\n    int lastDir=-1;\n    \n    auto start=chrono::steady_clock::now();\n    double timeLimit=2.7;\n    \n    while((int)ans.size()<T){\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-start).count();\n        if(elapsed>timeLimit)break;\n        double temp=max(0.1, 5.0*(1.0-elapsed/timeLimit));\n        \n        vector<int>cands;\n        for(int d=0;d<4;d++){\n            if(d==lastDir)continue;// avoid reversal (opp of last would undo)\n            if(lastDir>=0&&d==opp[lastDir])continue;\n            int ni=ei+di[d],nj=ej+dj[d];\n            if(ni>=0&&ni<N&&nj>=0&&nj<N)cands.push_back(d);\n        }\n        if(cands.empty())for(int d=0;d<4;d++){int ni=ei+di[d],nj=ej+dj[d];if(ni>=0&&ni<N&&nj>=0&&nj<N)cands.push_back(d);}\n        \n        int d=cands[rng()%cands.size()];\n        int ni=ei+di[d],nj=ej+dj[d];\n        swap(board[ei][ej],board[ni][nj]);\n        int nv=largest_tree();\n        double delta=nv-cur;\n        if(delta>=0||uniform_real_distribution<>(0,1)(rng)<exp(delta/temp)){\n            ei=ni;ej=nj;ans+=dirs[d];cur=nv;lastDir=d;\n            if(cur>bestScore){bestScore=cur;bestAns=ans;memcpy(bestBoard,board,sizeof(board));bestEi=ei;bestEj=ej;}\n            if(cur==N*N-1)break;\n        }else{\n            swap(board[ei][ej],board[ni][nj]);\n        }\n    }\n    if(bestScore>largest_tree()||true){\n        // Use best found\n        memcpy(board,bestBoard,sizeof(board));\n        printf(\"%s\\n\",bestAns.empty()?\"U\":bestAns.c_str());\n    }else printf(\"%s\\n\",ans.empty()?\"U\":ans.c_str());\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, K;\n    cin >> N >> K;\n    vector<int> a(11);\n    int total_a = 0;\n    for(int d=1;d<=10;d++){ cin >> a[d]; total_a += a[d]; }\n    vector<int> sx(N), sy(N);\n    for(int i=0;i<N;i++) cin >> sx[i] >> sy[i];\n    \n    mt19937 rng(42);\n    int num_lines = min(K, 100);\n    \n    vector<uint64_t> hash_pos(num_lines), hash_neg(num_lines);\n    for(int j=0;j<num_lines;j++){\n        hash_pos[j] = ((uint64_t)rng() << 32) ^ rng() ^ (1ULL << 63);\n        hash_neg[j] = ((uint64_t)rng() << 32) ^ rng() ^ (1ULL << 63);\n    }\n    \n    vector<array<long long,4>> lines(num_lines);\n    vector<int8_t> signs(N * num_lines);\n    vector<uint64_t> phash(N, 0);\n    vector<int> on_count(N, 0);\n    \n    auto compute_sign = [&](int i, int j) -> int8_t {\n        long long dx = lines[j][2]-lines[j][0], dy = lines[j][3]-lines[j][1];\n        long long cross = dx*((long long)sy[i]-lines[j][1]) - dy*((long long)sx[i]-lines[j][0]);\n        if(cross > 0) return 1;\n        if(cross < 0) return -1;\n        return 0;\n    };\n    \n    vector<uint64_t> tmp_hashes;\n    auto calc_score = [&]() -> int {\n        tmp_hashes.clear();\n        for(int i=0;i<N;i++){\n            if(on_count[i]==0) tmp_hashes.push_back(phash[i]);\n        }\n        sort(tmp_hashes.begin(), tmp_hashes.end());\n        vector<int> bd(11,0);\n        int n = tmp_hashes.size();\n        int i = 0;\n        while(i < n){\n            int j = i+1;\n            while(j < n && tmp_hashes[j] == tmp_hashes[i]) j++;\n            int cnt = j - i;\n            if(cnt >= 1 && cnt <= 10) bd[cnt]++;\n            i = j;\n        }\n        int score = 0;\n        for(int d=1;d<=10;d++) score += min(a[d], bd[d]);\n        return score;\n    };\n    \n    auto make_random_line = [&]() -> array<long long,4> {\n        while(true){\n            int method = rng() % 3;\n            if(method == 0 && N >= 2){\n                int ia = rng() % N, ib = rng() % N;\n                while(ib == ia) ib = rng() % N;\n                long long mx2 = sx[ia]+sx[ib], my2 = sy[ia]+sy[ib];\n                long long ddx = sx[ib]-sx[ia], ddy = sy[ib]-sy[ia];\n                long long px = mx2 - 2*ddy, py = my2 + 2*ddx;\n                long long qx = mx2 + 2*ddy, qy = my2 - 2*ddx;\n                if(px!=qx || py!=qy) return {px, py, qx, qy};\n            } else if(method == 1 && N >= 1){\n                double angle = (rng() % 100000) / 100000.0 * M_PI;\n                double ca = cos(angle), sa = sin(angle);\n                int idx2 = rng() % N;\n                double off = (int)(rng() % 21) - 10;\n                double cx = sx[idx2] + off * ca;\n                double cy = sy[idx2] + off * sa;\n                long long px = llround(cx - sa * 30000);\n                long long py = llround(cy + ca * 30000);\n                long long qx = llround(cx + sa * 30000);\n                long long qy = llround(cy - ca * 30000);\n                if(px!=qx || py!=qy) return {px, py, qx, qy};\n            } else {\n                double angle = (rng() % 100000) / 100000.0 * M_PI;\n                double offset = ((int)(rng() % 20001) - 10000);\n                double ca = cos(angle), sa = sin(angle);\n                long long px = llround(-sa * offset + ca * 20000);\n                long long py = llround(ca * offset + sa * 20000);\n                long long qx = llround(-sa * offset - ca * 20000);\n                long long qy = llround(ca * offset - sa * 20000);\n                if(px!=qx || py!=qy) return {px, py, qx, qy};\n            }\n        }\n    };\n    \n    auto perturbline = [&](int idx) -> array<long long,4> {\n        auto l = lines[idx];\n        int r = rng() % 4;\n        if(r < 2){\n            long long delta = (int)(rng() % 2001) - 1000;\n            if(r==0){ l[0] += delta; l[2] += delta; }\n            else { l[1] += delta; l[3] += delta; }\n        } else {\n            double mx = (l[0]+l[2])/2.0, my = (l[1]+l[3])/2.0;\n            double dx0 = l[0]-mx, dy0 = l[1]-my;\n            double dx2 = l[2]-mx, dy2 = l[3]-my;\n            double ang = ((int)(rng()%2001) - 1000) / 10000.0;\n            double c=cos(ang), s=sin(ang);\n            l[0] = llround(mx + c*dx0 - s*dy0);\n            l[1] = llround(my + s*dx0 + c*dy0);\n            l[2] = llround(mx + c*dx2 - s*dy2);\n            l[3] = llround(my + s*dx2 + c*dy2);\n        }\n        if(l[0]==l[2] && l[1]==l[3]) l[2]++;\n        return l;\n    };\n    \n    for(int j=0;j<num_lines;j++) lines[j] = make_random_line();\n    \n    for(int i=0;i<N;i++){\n        phash[i] = 0; on_count[i] = 0;\n        for(int j=0;j<num_lines;j++){\n            int8_t s = compute_sign(i,j);\n            signs[i*num_lines+j] = s;\n            if(s==0) on_count[i]++;\n            else if(s>0) phash[i] ^= hash_pos[j];\n            else phash[i] ^= hash_neg[j];\n        }\n    }\n    \n    int cur_score = calc_score();\n    int best_score = cur_score;\n    auto best_lines = lines;\n    \n    vector<int8_t> old_s(N);\n    vector<uint64_t> old_ph(N);\n    vector<int> old_oc(N);\n    \n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    \n    while(true){\n        if((++iter & 255) == 0){\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n            if(elapsed > 2.85) break;\n        }\n        \n        int idx = rng() % num_lines;\n        auto old_line = lines[idx];\n        \n        bool do_perturb = (rng() % 5) >= 1;\n        lines[idx] = do_perturb ? perturbline(idx) : make_random_line();\n        \n        for(int i=0;i<N;i++){\n            int off = i*num_lines+idx;\n            old_s[i] = signs[off];\n            old_ph[i] = phash[i];\n            old_oc[i] = on_count[i];\n            \n            if(old_s[i] > 0) phash[i] ^= hash_pos[idx];\n            else if(old_s[i] < 0) phash[i] ^= hash_neg[idx];\n            if(old_s[i] == 0) on_count[i]--;\n            \n            int8_t ns = compute_sign(i, idx);\n            signs[off] = ns;\n            if(ns == 0) on_count[i]++;\n            else if(ns > 0) phash[i] ^= hash_pos[idx];\n            else phash[i] ^= hash_neg[idx];\n        }\n        \n        int sc = calc_score();\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        double temp = 2.0 * max(0.0, 1.0 - elapsed / 2.85);\n        \n        bool accept = sc >= cur_score || (temp > 0.001 && exp((sc-cur_score)/temp) > (rng()%10000)/10000.0);\n        \n        if(accept){\n            cur_score = sc;\n            if(sc > best_score){ best_score = sc; best_lines = lines; }\n        } else {\n            lines[idx] = old_line;\n            for(int i=0;i<N;i++){\n                signs[i*num_lines+idx] = old_s[i];\n                phash[i] = old_ph[i];\n                on_count[i] = old_oc[i];\n            }\n        }\n    }\n    \n    cout << best_lines.size() << \"\\n\";\n    for(auto& l : best_lines)\n        cout << l[0] << \" \" << l[1] << \" \" << l[2] << \" \" << l[3] << \"\\n\";\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\nint N;\nbool dg[62][62];\nunordered_set<uint64_t> used_segs;\ninline uint64_t sk(int x1,int y1,int x2,int y2){\n    if(x1>x2||(x1==x2&&y1>y2)){swap(x1,x2);swap(y1,y2);}\n    return ((uint64_t)x1<<48)|((uint64_t)y1<<32)|((uint64_t)x2<<16)|(uint64_t)(uint16_t)y2;\n}\ninline bool ib(int x,int y){return (unsigned)x<(unsigned)N&&(unsigned)y<(unsigned)N;}\nbool csid(int x1,int y1,int x2,int y2){\n    int dx=x2-x1,dy=y2-y1,g=__gcd(abs(dx),abs(dy));\n    if(g<=1)return true;\n    int sx=dx/g,sy=dy/g;\n    for(int i=1;i<g;i++){int px=x1+sx*i,py=y1+sy*i;if(ib(px,py)&&dg[px][py])return false;}\n    return true;\n}\nbool cacs(int x1,int y1,int x2,int y2,vector<uint64_t>&out){\n    int dx=x2-x1,dy=y2-y1,g=__gcd(abs(dx),abs(dy));\n    if(!g)return true;\n    int sx=dx/g,sy=dy/g;size_t st=out.size();\n    for(int i=0;i<g;i++){uint64_t k=sk(x1+sx*i,y1+sy*i,x1+sx*(i+1),y1+sy*(i+1));\n        if(used_segs.count(k)){out.resize(st);return false;}out.push_back(k);}\n    return true;\n}\nstruct Op{int x1,y1,x2,y2,x3,y3,x4,y4;};\nstruct Cand{\n    double score;\n    int p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y;\n    int perim;\n    bool operator<(const Cand&o)const{return score<o.score;}\n};\n\nint udirs[4][2]={{1,0},{0,1},{1,1},{1,-1}};\nint uperp[4][2]={{0,1},{-1,0},{1,-1},{1,1}};\n\ndouble cc;\ninline double wt(int x,int y){return (x-cc)*(x-cc)+(y-cc)*(y-cc)+1;}\n\npriority_queue<Cand> pq;\nint cur_phase=0; // 0=small rects, 1=all rects weighted\n\nvoid try_rect(int ax,int ay,int bx,int by,int cx,int cy,int dx,int dy,int l1,int l2,int dir_type){\n    int h[4]={(int)dg[ax][ay],(int)dg[bx][by],(int)dg[cx][cy],(int)dg[dx][dy]};\n    if(h[0]+h[1]+h[2]+h[3]!=3)return;\n    int pts[4][2]={{ax,ay},{bx,by},{cx,cy},{dx,dy}};\n    int ni=-1;for(int i=0;i<4;i++)if(!h[i]){ni=i;break;}\n    int p1x=pts[ni][0],p1y=pts[ni][1];\n    int p2x=pts[(ni+1)%4][0],p2y=pts[(ni+1)%4][1];\n    int p3x=pts[(ni+2)%4][0],p3y=pts[(ni+2)%4][1];\n    int p4x=pts[(ni+3)%4][0],p4y=pts[(ni+3)%4][1];\n    \n    // Compute perimeter in unit segments\n    int perim;\n    if(dir_type<2) perim=2*(l1+l2); // axis-aligned\n    else perim=2*(l1+l2); // diagonal, each unit is sqrt(2) but segments count is same\n    \n    // Score: weight / perimeter (more weight per segment used = better)\n    double w=wt(p1x,p1y);\n    double sc = w / (perim + 1.0); // efficiency metric\n    \n    pq.push({sc,p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y,perim});\n}\n\nvoid find_cands(int ax,int ay){\n    for(int di=0;di<4;di++){\n        int ux=udirs[di][0],uy=udirs[di][1],px=uperp[di][0],py=uperp[di][1];\n        for(int s1:{-1,1})for(int s2:{-1,1}){\n            int sx=ux*s1,sy=uy*s1,qx=px*s2,qy=py*s2;\n            for(int l1=1;l1<N;l1++){\n                int bx=ax+sx*l1,by=ay+sy*l1;\n                if(!ib(bx,by))break;\n                for(int l2=1;l2<N;l2++){\n                    int dxp=ax+qx*l2,dyp=ay+qy*l2;\n                    int cxp=bx+qx*l2,cyp=by+qy*l2;\n                    if(!ib(dxp,dyp)||!ib(cxp,cyp))break;\n                    int h=dg[ax][ay]+dg[bx][by]+dg[cxp][cyp]+dg[dxp][dyp];\n                    if(h==3)try_rect(ax,ay,bx,by,cxp,cyp,dxp,dyp,l1,l2,di);\n                }\n            }\n        }\n    }\n}\n\nbool full_validate(Cand&cd,vector<uint64_t>&segs){\n    if(dg[cd.p1x][cd.p1y])return false;\n    if(!dg[cd.p2x][cd.p2y]||!dg[cd.p3x][cd.p3y]||!dg[cd.p4x][cd.p4y])return false;\n    int s[4][4]={{cd.p1x,cd.p1y,cd.p2x,cd.p2y},{cd.p2x,cd.p2y,cd.p3x,cd.p3y},\n                 {cd.p3x,cd.p3y,cd.p4x,cd.p4y},{cd.p4x,cd.p4y,cd.p1x,cd.p1y}};\n    for(int i=0;i<4;i++)if(!csid(s[i][0],s[i][1],s[i][2],s[i][3]))return false;\n    segs.clear();\n    for(int i=0;i<4;i++)if(!cacs(s[i][0],s[i][1],s[i][2],s[i][3],segs))return false;\n    return true;\n}\n\nvoid run_with_scoring(auto score_fn, vector<Op>&ops, auto&st, double time_limit){\n    // Rebuild queue\n    while(!pq.empty())pq.pop();\n    for(int x=0;x<N;x++)for(int y=0;y<N;y++)if(dg[x][y])find_cands(x,y);\n    \n    int rounds=0;\n    while(!pq.empty()){\n        if((++rounds&511)==0 && chrono::duration<double>(chrono::steady_clock::now()-st).count()>time_limit)break;\n        auto cd=pq.top();pq.pop();\n        vector<uint64_t> segs;\n        if(!full_validate(cd,segs))continue;\n        dg[cd.p1x][cd.p1y]=true;\n        for(auto k:segs)used_segs.insert(k);\n        ops.push_back({cd.p1x,cd.p1y,cd.p2x,cd.p2y,cd.p3x,cd.p3y,cd.p4x,cd.p4y});\n        find_cands(cd.p1x,cd.p1y);\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    int M;cin>>N>>M;cc=(N-1)/2.0;\n    memset(dg,0,sizeof(dg));\n    \n    // Save initial state for potential restarts\n    bool init_dg[62][62];\n    memset(init_dg,0,sizeof(init_dg));\n    for(int i=0;i<M;i++){int x,y;cin>>x>>y;dg[x][y]=true;init_dg[x][y]=true;}\n    \n    auto st=chrono::steady_clock::now();\n    \n    // Try approach: weight/perimeter efficiency scoring\n    vector<Op> best_ops;\n    double best_score=-1;\n    \n    // Approach 1: Pure weight\n    {\n        memcpy(dg,init_dg,sizeof(dg));\n        used_segs.clear();\n        vector<Op> ops;\n        while(!pq.empty())pq.pop();\n        // Temporarily change scoring to pure weight\n        for(int x=0;x<N;x++)for(int y=0;y<N;y++)if(dg[x][y]){\n            // Inline find_cands but with pure weight scoring\n            find_cands(x,y);\n        }\n        int rounds=0;\n        while(!pq.empty()){\n            if((++rounds&511)==0&&chrono::duration<double>(chrono::steady_clock::now()-st).count()>2.0)break;\n            auto cd=pq.top();pq.pop();\n            vector<uint64_t> segs;\n            if(!full_validate(cd,segs))continue;\n            dg[cd.p1x][cd.p1y]=true;\n            for(auto k:segs)used_segs.insert(k);\n            ops.push_back({cd.p1x,cd.p1y,cd.p2x,cd.p2y,cd.p3x,cd.p3y,cd.p4x,cd.p4y});\n            find_cands(cd.p1x,cd.p1y);\n        }\n        // Second pass\n        for(int x=0;x<N;x++)for(int y=0;y<N;y++)if(dg[x][y])find_cands(x,y);\n        while(!pq.empty()){\n            if((++rounds&511)==0&&chrono::duration<double>(chrono::steady_clock::now()-st).count()>4.0)break;\n            auto cd=pq.top();pq.pop();\n            vector<uint64_t> segs;\n            if(!full_validate(cd,segs))continue;\n            dg[cd.p1x][cd.p1y]=true;\n            for(auto k:segs)used_segs.insert(k);\n            ops.push_back({cd.p1x,cd.p1y,cd.p2x,cd.p2y,cd.p3x,cd.p3y,cd.p4x,cd.p4y});\n            find_cands(cd.p1x,cd.p1y);\n        }\n        // Compute score\n        double S=0,Q=0;\n        for(int x=0;x<N;x++)for(int y=0;y<N;y++){S+=wt(x,y);if(dg[x][y])Q+=wt(x,y);}\n        double sc=(double)N*N/M*Q/S;\n        if(sc>best_score){best_score=sc;best_ops=ops;}\n    }\n    \n    cout<<best_ops.size()<<\"\\n\";\n    for(auto&op:best_ops)\n        cout<<op.x1<<\" \"<<op.y1<<\" \"<<op.x2<<\" \"<<op.y2<<\" \"<<op.x3<<\" \"<<op.y3<<\" \"<<op.x4<<\" \"<<op.y4<<\"\\n\";\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nstatic mt19937 rng(42);\n\nint G[10][10];\n\nvoid tilt(int g[10][10], int dir) {\n    if (dir == 0) {\n        for(int c=0;c<10;c++){int p=0;for(int r=0;r<10;r++)if(g[r][c]){if(p!=r){g[p][c]=g[r][c];g[r][c]=0;}p++;}}\n    } else if (dir == 1) {\n        for(int c=0;c<10;c++){int p=9;for(int r=9;r>=0;r--)if(g[r][c]){if(p!=r){g[p][c]=g[r][c];g[r][c]=0;}p--;}}\n    } else if (dir == 2) {\n        for(int r=0;r<10;r++){int p=0;for(int c=0;c<10;c++)if(g[r][c]){if(p!=c){g[r][p]=g[r][c];g[r][c]=0;}p++;}}\n    } else {\n        for(int r=0;r<10;r++){int p=9;for(int c=9;c>=0;c--)if(g[r][c]){if(p!=c){g[r][p]=g[r][c];g[r][c]=0;}p--;}}\n    }\n}\n\nint adjacency(const int g[10][10]) {\n    int s=0;\n    for(int r=0;r<10;r++) for(int c=0;c<10;c++) if(g[r][c]){\n        if(r+1<10 && g[r+1][c]==g[r][c]) s++;\n        if(c+1<10 && g[r][c+1]==g[r][c]) s++;\n    }\n    return s;\n}\n\nint connectivity(const int g[10][10]) {\n    bool vis[10][10]={};\n    int score=0;\n    static pair<int,int> stk[100];\n    int dx[]={0,0,1,-1},dy[]={1,-1,0,0};\n    for(int i=0;i<10;i++) for(int j=0;j<10;j++) if(g[i][j]&&!vis[i][j]){\n        int fl=g[i][j],cnt=0,top=0;\n        stk[top++]={i,j};vis[i][j]=1;\n        while(top>0){\n            auto[r,c]=stk[--top];cnt++;\n            for(int d=0;d<4;d++){int nr=r+dx[d],nc=c+dy[d];\n                if(nr>=0&&nr<10&&nc>=0&&nc<10&&!vis[nr][nc]&&g[nr][nc]==fl){vis[nr][nc]=1;stk[top++]={nr,nc};}}\n        }\n        score+=cnt*cnt;\n    }\n    return score;\n}\n\nint countEmpty(const int g[10][10]) {\n    int c=0;for(int r=0;r<10;r++)for(int j=0;j<10;j++)if(!g[r][j])c++;return c;\n}\n\nvoid placeAt(int g[10][10], int p, int flavor) {\n    int cnt=0;\n    for(int r=0;r<10;r++) for(int c=0;c<10;c++) if(!g[r][c]){\n        if(cnt==p){g[r][c]=flavor;return;}cnt++;\n    }\n}\n\nint greedyTilt(int g[10][10]) {\n    int bestA=-1, bestD=0;\n    for(int d=0;d<4;d++){\n        int tmp[10][10];memcpy(tmp,g,400);\n        tilt(tmp,d);\n        int a=adjacency(tmp);\n        if(a>bestA){bestA=a;bestD=d;}\n    }\n    return bestD;\n}\n\nint simulate(int g[10][10], const int* flavors, int from, int total, int depth) {\n    int tmp[10][10];\n    memcpy(tmp,g,400);\n    int end = min(total, from+depth);\n    for(int t=from;t<end;t++){\n        int empty=countEmpty(tmp);\n        if(empty==0) break;\n        int p=rng()%empty;\n        placeAt(tmp,p,flavors[t]);\n        int d=greedyTilt(tmp);\n        tilt(tmp,d);\n    }\n    return connectivity(tmp);\n}\n\nconst char dirC[]={'F','B','L','R'};\n\nint main(){\n    ios::sync_with_stdio(false);\n    int f[100];for(int i=0;i<100;i++)cin>>f[i];\n    memset(G,0,sizeof(G));\n    \n    auto startTime = chrono::steady_clock::now();\n    \n    for(int t=0;t<100;t++){\n        int p;cin>>p;p--;\n        placeAt(G,p,f[t]);\n        \n        int remaining=100-t-1;\n        \n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now-startTime).count();\n        double timeLeft = 1.85 - elapsed;\n        double timePerStep = timeLeft / max(1, 100-t);\n        \n        int depth = min(remaining, 15);\n        \n        double bestVal=-1e18; int bestd=0;\n        \n        if(remaining >= 3 && timePerStep > 0.001) {\n            auto stepStart = chrono::steady_clock::now();\n            double scores[4]={};\n            int counts[4]={};\n            \n            for(int d=0;d<4;d++){\n                int tmp[10][10];memcpy(tmp,G,400);\n                tilt(tmp,d);\n                scores[d] += simulate(tmp,f,t+1,100,depth);\n                counts[d]++;\n            }\n            \n            while(true){\n                auto cur = chrono::steady_clock::now();\n                double dt = chrono::duration<double>(cur-stepStart).count();\n                if(dt > timePerStep) break;\n                int d = rng()%4;\n                int tmp[10][10];memcpy(tmp,G,400);\n                tilt(tmp,d);\n                scores[d] += simulate(tmp,f,t+1,100,depth);\n                counts[d]++;\n            }\n            \n            for(int d=0;d<4;d++){\n                double val = scores[d]/max(1,counts[d]);\n                if(val>bestVal){bestVal=val;bestd=d;}\n            }\n        } else {\n            for(int d=0;d<4;d++){\n                int tmp[10][10];memcpy(tmp,G,400);\n                tilt(tmp,d);\n                double val = connectivity(tmp) + 0.5*adjacency(tmp);\n                if(val>bestVal){bestVal=val;bestd=d;}\n            }\n        }\n        \n        tilt(G,bestd);\n        cout<<dirC[bestd]<<\"\\n\"<<flush;\n    }\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\n\nint N;\n\nvector<double> get_features(vector<vector<int>>& adj){\n    vector<int> deg(N,0);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(adj[i][j]) deg[i]++;\n    vector<int> sdeg=deg; sort(sdeg.begin(),sdeg.end());\n    \n    vector<int> tri(N,0);\n    for(int i=0;i<N;i++)\n        for(int j=0;j<N;j++) if(adj[i][j])\n            for(int k=j+1;k<N;k++) if(adj[i][k]&&adj[j][k])\n                tri[i]++;\n    vector<int> stri=tri; sort(stri.begin(),stri.end());\n    \n    vector<double> ndeg(N,0);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(adj[i][j]) ndeg[i]+=deg[j];\n    vector<double> sndeg=ndeg; sort(sndeg.begin(),sndeg.end());\n    \n    // Eigenvalues of adjacency matrix\n    Eigen::MatrixXd A(N,N);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) A(i,j)=adj[i][j];\n    Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(A);\n    auto evals = es.eigenvalues();\n    vector<double> eigvals(N);\n    for(int i=0;i<N;i++) eigvals[i]=evals(i);\n    sort(eigvals.begin(),eigvals.end());\n    \n    vector<double> feat;\n    // Degree sequence\n    for(int i=0;i<N;i++) feat.push_back(sdeg[i]);\n    // Triangle counts\n    for(int i=0;i<N;i++) feat.push_back(stri[i]*0.3);\n    // Neighbor degree sums\n    for(int i=0;i<N;i++) feat.push_back(sndeg[i]*0.02);\n    // Eigenvalues (very discriminative)\n    for(int i=0;i<N;i++) feat.push_back(eigvals[i]*0.8);\n    \n    return feat;\n}\n\nstring canonical_form(vector<vector<int>>& adj){\n    vector<int> deg(N,0);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(adj[i][j]) deg[i]++;\n    \n    vector<vector<int>> labels(N);\n    for(int i=0;i<N;i++) labels[i]={deg[i]};\n    \n    for(int iter=0;iter<8;iter++){\n        vector<vector<int>> nlabels(N);\n        for(int i=0;i<N;i++){\n            vector<vector<int>> nbr;\n            for(int j=0;j<N;j++) if(adj[i][j]) nbr.push_back(labels[j]);\n            sort(nbr.begin(),nbr.end());\n            nlabels[i]=labels[i];\n            nlabels[i].push_back(-1);\n            for(auto& nl:nbr) for(int x:nl) nlabels[i].push_back(x);\n        }\n        labels=nlabels;\n    }\n    \n    vector<int> order(N);\n    iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),[&](int a,int b){return labels[a]<labels[b];});\n    \n    string can;\n    for(int i=0;i<N;i++) for(int j=i+1;j<N;j++)\n        can+=(char)('0'+adj[order[i]][order[j]]);\n    return can;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M; double eps;\n    cin >> M >> eps;\n    \n    if(eps < 0.001){\n        if(M<=6) N=4;\n        else if(M<=15) N=5;\n        else if(M<=50) N=6;\n        else N=7;\n    } else if(eps <= 0.03){\n        N = min(100, max(6, (int)(2.0*sqrt((double)M))+2));\n    } else if(eps <= 0.08){\n        N = min(100, max(8, (int)(2.2*sqrt((double)M))+3));\n    } else if(eps <= 0.15){\n        N = min(100, max(10, (int)(2.5*sqrt((double)M))+4));\n    } else if(eps <= 0.25){\n        N = min(100, max(15, (int)(3.0*sqrt((double)M))+6));\n    } else if(eps <= 0.35){\n        N = min(100, max(22, (int)(3.5*sqrt((double)M))+8));\n    } else {\n        N = min(100, max(30, (int)(4.5*sqrt((double)M))+10));\n    }\n    N = max(N, 4);\n    \n    int E = N*(N-1)/2;\n    mt19937 rng(42);\n    \n    auto to_str = [&](vector<vector<int>>& adj) -> string {\n        string s;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) s+=(char)('0'+adj[i][j]);\n        return s;\n    };\n    \n    vector<vector<vector<int>>> adjs(M);\n    vector<vector<double>> features(M);\n    \n    if(eps < 0.001){\n        set<string> used;\n        int found=0;\n        int attempts=0;\n        while(found<M && attempts<2000000){\n            attempts++;\n            vector<vector<int>> adj(N,vector<int>(N,0));\n            int ne = rng()%(E+1);\n            vector<pair<int,int>> all_e;\n            for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) all_e.push_back({i,j});\n            shuffle(all_e.begin(),all_e.end(),rng);\n            for(int e=0;e<ne;e++){adj[all_e[e].first][all_e[e].second]=1;adj[all_e[e].second][all_e[e].first]=1;}\n            string c=canonical_form(adj);\n            if(!used.count(c)){\n                used.insert(c);\n                adjs[found]=adj;\n                features[found]=get_features(adj);\n                found++;\n            }\n        }\n    } else {\n        // Generate well-separated graphs\n        // Use varied structures, not just ER with different densities\n        int trials = max(20, min(300, 5000/M));\n        \n        for(int k=0;k<M;k++){\n            double density = (k+0.5)/M;\n            int target = max(0, min(E, (int)round(density*E)));\n            \n            vector<vector<int>> best_adj;\n            vector<double> best_feat;\n            double best_min_dist = -1;\n            \n            for(int t=0;t<trials;t++){\n                vector<vector<int>> adj(N,vector<int>(N,0));\n                vector<pair<int,int>> all_e;\n                for(int i=0;i<N;i++) for(int j=i+1;j<N;j++) all_e.push_back({i,j});\n                shuffle(all_e.begin(),all_e.end(),rng);\n                // Vary target slightly for diversity\n                int tgt = target + (int)(rng()%5) - 2;\n                tgt = max(0, min(E, tgt));\n                for(int e=0;e<tgt;e++){adj[all_e[e].first][all_e[e].second]=1;adj[all_e[e].second][all_e[e].first]=1;}\n                auto feat=get_features(adj);\n                \n                double min_dist=1e18;\n                for(int j=0;j<k;j++){\n                    double d=0;\n                    for(size_t f=0;f<feat.size();f++){double diff=feat[f]-features[j][f];d+=diff*diff;}\n                    min_dist=min(min_dist,d);\n                }\n                if(min_dist>best_min_dist){best_min_dist=min_dist;best_adj=adj;best_feat=feat;}\n            }\n            adjs[k]=best_adj;\n            features[k]=best_feat;\n        }\n    }\n    \n    cout<<N<<\"\\n\";\n    for(int k=0;k<M;k++) cout<<to_str(adjs[k])<<\"\\n\";\n    cout.flush();\n    \n    for(int q=0;q<100;q++){\n        string h; cin>>h;\n        vector<vector<int>> hadj(N,vector<int>(N,0));\n        int idx=0;\n        for(int i=0;i<N;i++) for(int j=i+1;j<N;j++){hadj[i][j]=hadj[j][i]=h[idx++]-'0';}\n        auto hfeat=get_features(hadj);\n        int best=-1;double bestd=1e18;\n        for(int k=0;k<M;k++){\n            double d=0;\n            for(size_t f=0;f<hfeat.size();f++){double diff=hfeat[f]-features[k][f];d+=diff*diff;}\n            if(d<bestd){bestd=d;best=k;}\n        }\n        cout<<best<<\"\\n\";\n        cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N,M,D,K;\nint eu[3001],ev[3001],ew[3001];\nvector<pair<int,int>> adj[1001];\nint nSample;\nint samples[1001];\nlong long origDist[50][1001];\nlong long tmpDist[1001];\nbool removed[3001];\n\nvoid dijkstra(int src, long long* dist){\n    for(int i=0;i<N;i++) dist[i]=1e18;\n    dist[src]=0;\n    // Use bucket queue / priority queue\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 [d,u]=pq.top(); pq.pop();\n        if(d>dist[u]) continue;\n        for(auto& [v,ei]:adj[u]){\n            if(removed[ei]) continue;\n            long long nd=d+ew[ei];\n            if(nd<dist[v]){\n                dist[v]=nd;\n                pq.push({nd,v});\n            }\n        }\n    }\n}\n\ndouble evalDayInline(const vector<int>& edges_on_day){\n    for(int e : edges_on_day) removed[e] = true;\n    double total = 0;\n    for(int si=0; si<nSample; si++){\n        dijkstra(samples[si], tmpDist);\n        for(int j=0; j<N; j++){\n            long long dd = (tmpDist[j] >= (long long)1e18) ? (long long)1e9 : tmpDist[j];\n            total += (double)(dd - origDist[si][j]);\n        }\n    }\n    for(int e : edges_on_day) removed[e] = false;\n    return total;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin>>N>>M>>D>>K;\n    for(int i=0;i<M;i++){\n        cin>>eu[i]>>ev[i]>>ew[i];\n        eu[i]--; ev[i]--;\n        adj[eu[i]].push_back({ev[i],i});\n        adj[ev[i]].push_back({eu[i],i});\n    }\n    {int x,y; for(int i=0;i<N;i++) cin>>x>>y;}\n    \n    mt19937 rng(42);\n    nSample = min(N, 15);\n    {\n        vector<int> tmp(N);\n        iota(tmp.begin(),tmp.end(),0);\n        shuffle(tmp.begin(),tmp.end(),rng);\n        for(int i=0;i<nSample;i++) samples[i]=tmp[i];\n    }\n    \n    memset(removed,0,sizeof(removed));\n    for(int i=0;i<nSample;i++) dijkstra(samples[i], origDist[i]);\n    \n    // Edge importance\n    vector<double> importance(M, 0);\n    for(int si=0;si<nSample;si++){\n        vector<int> idx(N); iota(idx.begin(),idx.end(),0);\n        sort(idx.begin(),idx.end(),[&](int a,int b){return origDist[si][a]<origDist[si][b];});\n        vector<double> sub(N, 1.0);\n        for(int i=N-1;i>=0;i--){\n            int v=idx[i];\n            if(v==samples[si]) continue;\n            for(auto& [u,ei]:adj[v]){\n                if(origDist[si][u]+ew[ei]==origDist[si][v]){\n                    sub[u]+=sub[v];\n                    importance[ei]+=sub[v];\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Initial: spread important edges round-robin\n    vector<int> order(M);\n    iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),[&](int a,int b){return importance[a]>importance[b];});\n    \n    vector<int> asgn(M);\n    vector<vector<int>> dayEdges(D);\n    for(int i=0;i<M;i++){\n        int day=i%D;\n        asgn[order[i]]=day;\n        dayEdges[day].push_back(order[i]);\n    }\n    \n    vector<double> dayScore(D);\n    double totalScore=0;\n    for(int d=0;d<D;d++){\n        dayScore[d]=evalDayInline(dayEdges[d]);\n        totalScore+=dayScore[d];\n    }\n    \n    double bestTotal=totalScore;\n    vector<int> bestAsgn=asgn;\n    \n    auto startTime=chrono::steady_clock::now();\n    double timeLimit=5.3;\n    \n    auto getTime=[&](){\n        return chrono::duration<double>(chrono::steady_clock::now()-startTime).count();\n    };\n    \n    // Pre-compute max day for targeting\n    auto worstDay=[&]()->int{\n        return max_element(dayScore.begin(),dayScore.end())-dayScore.begin();\n    };\n    \n    int iter=0;\n    while(true){\n        double t=getTime();\n        if(t>timeLimit) break;\n        double progress=t/timeLimit;\n        double startTemp=bestTotal/(D*10.0);\n        double endTemp=bestTotal/(D*10000.0);\n        double curTemp=startTemp*pow(endTemp/max(startTemp,1.0),progress);\n        \n        // 50% target worst day, 50% random\n        int moveType=rng()%4;\n        \n        if(moveType<3){\n            // Swap two edges between two days\n            int d1,d2;\n            if(moveType==0){\n                d1=worstDay();\n                d2=rng()%D;\n            } else {\n                d1=rng()%D;\n                d2=rng()%D;\n            }\n            if(d1==d2||dayEdges[d1].empty()||dayEdges[d2].empty()) continue;\n            int i1=rng()%dayEdges[d1].size();\n            int i2=rng()%dayEdges[d2].size();\n            int e1=dayEdges[d1][i1], e2=dayEdges[d2][i2];\n            \n            dayEdges[d1][i1]=e2;\n            dayEdges[d2][i2]=e1;\n            \n            double ns1=evalDayInline(dayEdges[d1]);\n            double ns2=evalDayInline(dayEdges[d2]);\n            double delta=(ns1+ns2)-(dayScore[d1]+dayScore[d2]);\n            \n            if(delta<0||exp(-delta/curTemp)>(rng()%1000000)/1000000.0){\n                asgn[e1]=d2; asgn[e2]=d1;\n                dayScore[d1]=ns1; dayScore[d2]=ns2;\n                totalScore+=delta;\n                if(totalScore<bestTotal){bestTotal=totalScore;bestAsgn=asgn;}\n            } else {\n                dayEdges[d1][i1]=e1; dayEdges[d2][i2]=e2;\n            }\n        } else {\n            // Move edge\n            int e=rng()%M;\n            int od=asgn[e], nd=rng()%D;\n            if(od==nd||(int)dayEdges[nd].size()>=K) continue;\n            auto& ov=dayEdges[od];\n            int pos=find(ov.begin(),ov.end(),e)-ov.begin();\n            ov[pos]=ov.back(); ov.pop_back();\n            dayEdges[nd].push_back(e);\n            double ns1=evalDayInline(ov);\n            double ns2=evalDayInline(dayEdges[nd]);\n            double delta=(ns1+ns2)-(dayScore[od]+dayScore[nd]);\n            if(delta<0||exp(-delta/curTemp)>(rng()%1000000)/1000000.0){\n                asgn[e]=nd; dayScore[od]=ns1; dayScore[nd]=ns2; totalScore+=delta;\n                if(totalScore<bestTotal){bestTotal=totalScore;bestAsgn=asgn;}\n            } else {\n                dayEdges[nd].pop_back(); ov.push_back(e);\n            }\n        }\n        iter++;\n    }\n    \n    for(int i=0;i<M;i++){\n        cout<<bestAsgn[i]+1;\n        if(i<M-1) cout<<' ';\n    }\n    cout<<'\\n';\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\nint main(){\n    int D;\n    scanf(\"%d\",&D);\n    vector<string> f1(D),r1(D),f2(D),r2(D);\n    for(int i=0;i<D;i++) cin>>f1[i];\n    for(int i=0;i<D;i++) cin>>r1[i];\n    for(int i=0;i<D;i++) cin>>f2[i];\n    for(int i=0;i<D;i++) cin>>r2[i];\n    \n    vector<int> b1(D*D*D,0), b2(D*D*D,0);\n    vector<int> cells1, cells2;\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++){\n        if(f1[z][x]=='1' && r1[z][y]=='1') cells1.push_back(x*D*D+y*D+z);\n    }\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++){\n        if(f2[z][x]=='1' && r2[z][y]=='1') cells2.push_back(x*D*D+y*D+z);\n    }\n    \n    int M1=cells1.size(), M2=cells2.size();\n    int shared=min(M1,M2);\n    int n=0;\n    \n    // First 'shared' blocks are shared unit blocks (used in both configs)\n    for(int i=0;i<shared;i++){\n        n++;\n        b1[cells1[i]]=n;\n        b2[cells2[i]]=n;\n    }\n    // Remaining cells in the larger config get their own unit blocks\n    if(M1>M2){\n        for(int i=shared;i<M1;i++){\n            n++;\n            b1[cells1[i]]=n;\n        }\n    } else {\n        for(int i=shared;i<M2;i++){\n            n++;\n            b2[cells2[i]]=n;\n        }\n    }\n    \n    printf(\"%d\\n\",n);\n    for(int i=0;i<D*D*D;i++) printf(\"%d%c\",b1[i],\" \\n\"[i==D*D*D-1]);\n    for(int i=0;i<D*D*D;i++) printf(\"%d%c\",b2[i],\" \\n\"[i==D*D*D-1]);\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint N,M,K;\nvector<ll> vx,vy;\nvector<int> eu_,ev_;\nvector<ll> ew_;\nvector<ll> ra,rb;\nvector<vector<pair<int,int>>> adj;\nvector<vector<ll>> spd;\nvector<vector<int>> spp;\nvector<vector<int>> cands;\nvector<vector<int>> rdist_c;\nvector<vector<int>> vtx_res;\n\nmt19937 rng(42);\nchrono::steady_clock::time_point start_time;\ndouble elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-start_time).count();}\n\nvoid dijkstra(int s){\n    priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<>> pq;\n    spd[s][s]=0;pq.push({0,s});\n    while(!pq.empty()){\n        auto[d,u]=pq.top();pq.pop();\n        if(d>spd[s][u]) continue;\n        for(auto&[v,eid]:adj[u]){\n            ll nd=d+ew_[eid];\n            if(nd<spd[s][v]){spd[s][v]=nd;spp[s][v]=eid;pq.push({nd,v});}\n        }\n    }\n}\n\nvector<bool> get_tree_verts(vector<bool>& edgeUsed){\n    vector<bool> vis(N,false);\n    queue<int> q;q.push(0);vis[0]=true;\n    while(!q.empty()){\n        int u=q.front();q.pop();\n        for(auto&[v,eid]:adj[u])\n            if(edgeUsed[eid]&&!vis[v]){vis[v]=true;q.push(v);}\n    }\n    return vis;\n}\n\npair<ll,vector<bool>> build_steiner(vector<bool>& active){\n    vector<bool> inTree(N,false),edgeUsed(M,false);\n    ll treeCost=0;inTree[0]=true;\n    vector<int> targets;\n    for(int i=0;i<N;i++) if(active[i]&&i!=0) targets.push_back(i);\n    int nt=targets.size();\n    vector<ll> minDist(nt);vector<int> minSrc(nt);\n    for(int t=0;t<nt;t++){minDist[t]=spd[0][targets[t]];minSrc[t]=0;}\n    vector<bool> added(nt,false);\n    for(int step=0;step<nt;step++){\n        int bi=-1;ll bd=1e18;\n        for(int t=0;t<nt;t++) if(!added[t]&&minDist[t]<bd){bd=minDist[t];bi=t;}\n        if(bi<0) break;\n        added[bi]=true;\n        int tgt=targets[bi],src=minSrc[bi];\n        vector<int> nn;int cur=tgt;\n        while(cur!=src){\n            int eid=spp[src][cur];\n            if(!edgeUsed[eid]){edgeUsed[eid]=true;treeCost+=ew_[eid];}\n            int u=eu_[eid],v=ev_[eid],nxt=(u==cur)?v:u;\n            if(!inTree[cur]) nn.push_back(cur);\n            inTree[cur]=true;cur=nxt;\n        }\n        inTree[tgt]=true;nn.push_back(tgt);\n        for(int t=0;t<nt;t++){\n            if(added[t]) continue;\n            for(int n2:nn) if(spd[n2][targets[t]]<minDist[t]){minDist[t]=spd[n2][targets[t]];minSrc[t]=n2;}\n        }\n    }\n    return{treeCost,edgeUsed};\n}\n\n// Greedy marginal assignment\nstruct AssignResult{\n    vector<int> P,assign;ll pCost;int covered;\n};\n\nAssignResult do_assign(vector<bool>& inTree, int passes){\n    vector<int> bestP(N,0),bestA(K,-1);ll bestPC=1e18;int bestC=0;\n    vector<int> order(K);iota(order.begin(),order.end(),0);\n    \n    for(int pass=0;pass<passes;pass++){\n        if(pass>0) shuffle(order.begin(),order.end(),rng);\n        vector<int> curP(N,0),curA(K,-1);int curC=0;\n        for(int k:order){\n            int bv=-1;ll bm=1e18;\n            for(int i:cands[k]){\n                if(!inTree[i]) continue;\n                int r=rdist_c[k][i],np=max(curP[i],r);\n                ll m=(ll)np*np-(ll)curP[i]*curP[i];\n                if(m<bm){bm=m;bv=i;}\n            }\n            if(bv>=0){curA[k]=bv;curP[bv]=max(curP[bv],rdist_c[k][bv]);curC++;}\n        }\n        ll pc=0;for(int i=0;i<N;i++) pc+=(ll)curP[i]*curP[i];\n        if(curC>bestC||(curC==bestC&&pc<bestPC)){bestPC=pc;bestP=curP;bestA=curA;bestC=curC;}\n    }\n    return{bestP,bestA,bestPC,bestC};\n}\n\n// Quick iterative improvement on assignment (lightweight)\nvoid improve_assign(vector<bool>& inTree, vector<int>& P, vector<int>& assign, ll& pCost){\n    // Build per-vertex sorted list of assigned resident distances\n    vector<vector<int>> va(N); // assigned resident indices per vertex\n    for(int k=0;k<K;k++) if(assign[k]>=0) va[assign[k]].push_back(k);\n    \n    // For each vertex, precompute max and second max\n    vector<int> mx1(N,0),mx2(N,0);\n    for(int i=0;i<N;i++){\n        for(int k:va[i]){\n            int r=rdist_c[k][i];\n            if(r>=mx1[i]){mx2[i]=mx1[i];mx1[i]=r;}\n            else if(r>mx2[i]) mx2[i]=r;\n        }\n    }\n    \n    for(int iter=0;iter<5;iter++){\n        bool changed=false;\n        for(int i=0;i<N;i++){\n            if(P[i]==0||va[i].empty()) continue;\n            // Find the resident determining P[i]\n            int farthest=-1;\n            for(int k:va[i]) if(rdist_c[k][i]==mx1[i]){farthest=k;break;}\n            if(farthest<0) continue;\n            \n            int k=farthest;\n            ll savings=(ll)mx1[i]*mx1[i]-(ll)mx2[i]*mx2[i];\n            \n            int bestAlt=-1;ll bestAC=1e18;\n            for(int j:cands[k]){\n                if(j==i||!inTree[j]) continue;\n                int r=rdist_c[k][j],np=max(P[j],r);\n                ll ac=(ll)np*np-(ll)P[j]*P[j];\n                if(ac<bestAC){bestAC=ac;bestAlt=j;}\n            }\n            if(bestAlt>=0&&bestAC<savings){\n                // Move k from i to bestAlt\n                assign[k]=bestAlt;\n                va[i].erase(find(va[i].begin(),va[i].end(),k));\n                va[bestAlt].push_back(k);\n                int r=rdist_c[k][bestAlt];\n                if(r>=mx1[bestAlt]){mx2[bestAlt]=mx1[bestAlt];mx1[bestAlt]=r;}\n                else if(r>mx2[bestAlt]) mx2[bestAlt]=r;\n                P[bestAlt]=mx1[bestAlt];\n                // Recompute for i\n                mx1[i]=mx2[i]=0;\n                for(int kk:va[i]){\n                    int rr=rdist_c[kk][i];\n                    if(rr>=mx1[i]){mx2[i]=mx1[i];mx1[i]=rr;}\n                    else if(rr>mx2[i]) mx2[i]=rr;\n                }\n                P[i]=mx1[i];\n                changed=true;\n            }\n        }\n        if(!changed) break;\n    }\n    pCost=0;for(int i=0;i<N;i++) pCost+=(ll)P[i]*P[i];\n}\n\nstruct Solution{\n    vector<int> P;vector<bool> edgeUsed,inTree;vector<int> assign;\n    ll totalCost;int covered;\n    bool valid()const{return covered==K;}\n};\n\nSolution run_solution(vector<bool>& initActive, int passes=5, int rebuilds=1){\n    Solution sol;\n    auto[tc,eu2]=build_steiner(initActive);\n    sol.edgeUsed=eu2;sol.inTree=get_tree_verts(sol.edgeUsed);\n    auto ar=do_assign(sol.inTree,passes);\n    sol.P=ar.P;sol.assign=ar.assign;sol.covered=ar.covered;\n    ll pc=ar.pCost;\n    improve_assign(sol.inTree,sol.P,sol.assign,pc);\n    ll ec=0;for(int j=0;j<M;j++) if(sol.edgeUsed[j]) ec+=ew_[j];\n    sol.totalCost=pc+ec;\n    \n    for(int rep=0;rep<rebuilds;rep++){\n        vector<bool> act(N,false);act[0]=true;\n        for(int i=0;i<N;i++) if(sol.P[i]>0) act[i]=true;\n        auto[tc2,eu3]=build_steiner(act);\n        sol.edgeUsed=eu3;sol.inTree=get_tree_verts(sol.edgeUsed);\n        auto ar2=do_assign(sol.inTree,passes);\n        sol.P=ar2.P;sol.assign=ar2.assign;sol.covered=ar2.covered;\n        pc=ar2.pCost;\n        improve_assign(sol.inTree,sol.P,sol.assign,pc);\n        ec=0;for(int j=0;j<M;j++) if(sol.edgeUsed[j]) ec+=ew_[j];\n        sol.totalCost=pc+ec;\n    }\n    return sol;\n}\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    start_time=chrono::steady_clock::now();\n    \n    cin>>N>>M>>K;\n    vx.resize(N);vy.resize(N);\n    for(int i=0;i<N;i++) cin>>vx[i]>>vy[i];\n    eu_.resize(M);ev_.resize(M);ew_.resize(M);\n    for(int j=0;j<M;j++){cin>>eu_[j]>>ev_[j]>>ew_[j];eu_[j]--;ev_[j]--;}\n    ra.resize(K);rb.resize(K);\n    for(int k=0;k<K;k++) cin>>ra[k]>>rb[k];\n    \n    adj.resize(N);\n    for(int j=0;j<M;j++){adj[eu_[j]].push_back({ev_[j],j});adj[ev_[j]].push_back({eu_[j],j});}\n    \n    spd.assign(N,vector<ll>(N,1e18));spp.assign(N,vector<int>(N,-1));\n    for(int s=0;s<N;s++) dijkstra(s);\n    \n    cands.resize(K);rdist_c.assign(K,vector<int>(N,10000));vtx_res.resize(N);\n    for(int k=0;k<K;k++){\n        for(int i=0;i<N;i++){\n            double dx=vx[i]-ra[k],dy=vy[i]-rb[k];\n            double d=sqrt(dx*dx+dy*dy);\n            int r=(int)ceil(d-1e-9);\n            rdist_c[k][i]=r;\n            if(r<=5000){cands[k].push_back(i);vtx_res[i].push_back(k);}\n        }\n    }\n    \n    Solution best;best.totalCost=1e18;best.covered=0;\n    best.P.assign(N,0);best.edgeUsed.assign(M,false);best.inTree.assign(N,false);best.assign.assign(K,-1);\n    \n    auto try_update=[&](Solution& s){if(s.valid()&&(!best.valid()||s.totalCost<best.totalCost)) best=s;};\n    \n    {vector<bool> a(N,true);auto s=run_solution(a,5,1);try_update(s);}\n    {\n        vector<bool> a(N,false);a[0]=true;\n        for(int k=0;k<K;k++){int b2=-1,br=10000;for(int i:cands[k]) if(rdist_c[k][i]<br){br=rdist_c[k][i];b2=i;}if(b2>=0) a[b2]=true;}\n        auto s=run_solution(a,5,1);try_update(s);\n    }\n    {\n        vector<bool> cov(K,false);vector<bool> a(N,false);a[0]=true;int nc=0;\n        while(nc<K){\n            int bv=-1;double br=1e18;\n            for(int i=0;i<N;i++){\n                int mx=0,cnt=0;\n                for(int k:vtx_res[i]) if(!cov[k]){cnt++;mx=max(mx,rdist_c[k][i]);}\n                if(!cnt) continue;\n                ll ac=(ll)mx*mx;\n                if(!a[i]){ll me=1e18;for(int j=0;j<N;j++) if(a[j]) me=min(me,spd[j][i]);ac+=me;}\n                double r=(double)ac/cnt;if(r<br){br=r;bv=i;}\n            }\n            if(bv<0) break;a[bv]=true;\n            for(int k:vtx_res[bv]) if(!cov[k]){cov[k]=true;nc++;}\n        }\n        auto s=run_solution(a,5,1);try_update(s);\n    }\n    \n    if(best.valid()){\n        Solution cur=best;\n        for(int iter=0;;iter++){\n            if(elapsed()>1.6) break;\n            vector<bool> act(N,false);act[0]=true;\n            for(int i=0;i<N;i++) if(cur.P[i]>0) act[i]=true;\n            int action=rng()%100;\n            if(action<35){\n                vector<int> ac2;for(int i=1;i<N;i++) if(act[i]) ac2.push_back(i);\n                if(ac2.empty()) continue;\n                int v=ac2[rng()%ac2.size()];\n                bool ok=true;\n                for(int k:vtx_res[v]){if(cur.assign[k]!=v) continue;bool f=false;for(int i:cands[k]) if(i!=v&&act[i]){f=true;break;}if(!f){ok=false;break;}}\n                if(!ok) continue;act[v]=false;\n            } else if(action<65){\n                vector<int> ia;for(int i=1;i<N;i++) if(!act[i]) ia.push_back(i);\n                if(ia.empty()) continue;act[ia[rng()%ia.size()]]=true;\n            } else {\n                vector<int> ac2,ia;for(int i=1;i<N;i++){if(cur.P[i]>0) ac2.push_back(i);else if(!act[i]) ia.push_back(i);}\n                if(ac2.empty()||ia.empty()) continue;act[ac2[rng()%ac2.size()]]=false;act[ia[rng()%ia.size()]]=true;\n            }\n            Solution next=run_solution(act,3,1);\n            if(!next.valid()) continue;\n            double temp=2e6*(1.0-elapsed()/1.65)+1e3;\n            ll delta=next.totalCost-cur.totalCost;\n            if(delta<0||(temp>0&&(rng()%1000000)/1e6<exp(-(double)delta/temp))){cur=next;if(cur.totalCost<best.totalCost) best=cur;}\n        }\n    }\n    \n    for(int i=0;i<N;i++) cout<<best.P[i]<<\" \\n\"[i==N-1];\n    for(int j=0;j<M;j++) cout<<(best.edgeUsed[j]?1:0)<<\" \\n\"[j==M-1];\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\nint N=30;\nint grid[30][30];\nint posx[465], posy[465];\nvector<tuple<int,int,int,int>> ops;\n\nvoid do_swap(int x1,int y1,int x2,int y2){\n    ops.push_back({x1,y1,x2,y2});\n    int a=grid[x1][y1], b=grid[x2][y2];\n    swap(grid[x1][y1],grid[x2][y2]);\n    posx[a]=x2; posy[a]=y2;\n    posx[b]=x1; posy[b]=y1;\n}\n\nvoid sift_up(int x, int y){\n    while(x > 0 && (int)ops.size() < 9950){\n        int cur = grid[x][y];\n        // Two parents: (x-1, y-1) if y>0, (x-1, y) if y<x\n        int bpx=-1, bpy=-1, bpv=cur;\n        if(y > 0 && grid[x-1][y-1] > bpv){ bpx=x-1; bpy=y-1; bpv=grid[x-1][y-1]; }\n        if(y < x && grid[x-1][y] > bpv){ bpx=x-1; bpy=y; bpv=grid[x-1][y]; }\n        if(bpx==-1) break;\n        do_swap(x,y,bpx,bpy);\n        x=bpx; y=bpy;\n    }\n}\n\nvoid sift_down(int x, int y){\n    while(x < N-1 && (int)ops.size() < 9950){\n        int cur = grid[x][y];\n        int c1 = grid[x+1][y], c2 = grid[x+1][y+1];\n        if(cur <= c1 && cur <= c2) break;\n        if(c1 <= c2){\n            do_swap(x,y,x+1,y);\n            x=x+1;\n        } else {\n            do_swap(x,y,x+1,y+1);\n            x=x+1; y=y+1;\n        }\n    }\n}\n\nint main(){\n    for(int x=0;x<N;x++) for(int y=0;y<=x;y++){\n        scanf(\"%d\",&grid[x][y]);\n        posx[grid[x][y]]=x; posy[grid[x][y]]=y;\n    }\n    \n    // Sift up each value from smallest to largest\n    for(int v=0; v<465 && (int)ops.size()<9900; v++){\n        sift_up(posx[v], posy[v]);\n    }\n    \n    // Clean up with sift-down passes\n    for(int iter=0; iter<10 && (int)ops.size()<9900; iter++){\n        bool changed=false;\n        for(int x=0;x<N-1 && (int)ops.size()<9900;x++)\n            for(int y=0;y<=x && (int)ops.size()<9900;y++){\n                int prev=ops.size();\n                sift_down(x,y);\n                if((int)ops.size()>prev) changed=true;\n            }\n        if(!changed) break;\n        for(int x=N-1;x>=1 && (int)ops.size()<9900;x--)\n            for(int y=0;y<=x && (int)ops.size()<9900;y++){\n                int prev=ops.size();\n                sift_up(x,y);\n                if((int)ops.size()>prev) changed=true;\n            }\n        if(!changed) break;\n    }\n    \n    printf(\"%d\\n\",(int)ops.size());\n    for(auto&[a,b,c,d]:ops) printf(\"%d %d %d %d\\n\",a,b,c,d);\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\nint D,N;\nint grid[9][9];\nint dx[]={-1,1,0,0},dy[]={0,0,-1,1};\nint ei,ej;\n\nvector<pair<int,int>> get_reachable_empty(){\n    bool vis[9][9]={};\n    queue<pair<int,int>> q;\n    q.push({ei,ej}); vis[ei][ej]=1;\n    vector<pair<int,int>> res;\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>=D||ny<0||ny>=D||vis[nx][ny]) continue;\n            if(grid[nx][ny]!=-1) continue;\n            vis[nx][ny]=1;\n            res.push_back({nx,ny});\n            q.push({nx,ny});\n        }\n    }\n    return res;\n}\n\nint count_reachable_from(int br, int bc){\n    // Count empty cells reachable from entrance if (br,bc) is blocked\n    grid[br][bc]=9999;\n    bool vis[9][9]={};\n    queue<pair<int,int>> q;\n    q.push({ei,ej}); vis[ei][ej]=1;\n    int cnt=0;\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>=D||ny<0||ny>=D||vis[nx][ny]) continue;\n            if(grid[nx][ny]!=-1) continue;\n            vis[nx][ny]=1; cnt++; q.push({nx,ny});\n        }\n    }\n    grid[br][bc]=-1;\n    return cnt;\n}\n\nbool is_safe(int r,int c,int remaining){\n    if(remaining<=1) return true;\n    int cnt=count_reachable_from(r,c);\n    return cnt==remaining-1;\n}\n\nvector<pair<int,int>> get_reachable_containers(){\n    bool vis[9][9]={};\n    queue<pair<int,int>> q;\n    q.push({ei,ej}); vis[ei][ej]=1;\n    vector<pair<int,int>> res;\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>=D||ny<0||ny>=D||vis[nx][ny]||grid[nx][ny]==-2) continue;\n            vis[nx][ny]=1;\n            if(grid[nx][ny]>=0) res.push_back({nx,ny});\n            else q.push({nx,ny});\n        }\n    }\n    return res;\n}\n\nint main(){\n    scanf(\"%d%d\",&D,&N);\n    ei=0;ej=(D-1)/2;\n    memset(grid,-1,sizeof(grid));\n    for(int i=0;i<N;i++){int r,c;scanf(\"%d%d\",&r,&c);grid[r][c]=-2;}\n    int M=D*D-1-N;\n    \n    // Pre-compute a \"fill order\" - DFS from entrance, filling leaves first\n    // This gives us an ordering of cells: cell filled at position k will be extracted at position k\n    \n    for(int d=0;d<M;d++){\n        int t; scanf(\"%d\",&t);\n        int remaining=M-d;\n        auto empties=get_reachable_empty();\n        \n        vector<pair<int,int>> safe_cells;\n        for(auto&[r,c]:empties){\n            if(is_safe(r,c,remaining)) safe_cells.push_back({r,c});\n        }\n        if(safe_cells.empty()) safe_cells=empties;\n        \n        // Sort safe cells by BFS distance (farthest first = extracted earliest)\n        // Among safe cells, the one placed now will be on boundary = extracted early\n        // So for low t, we want to place now (any safe cell, prefer farthest)\n        // For high t, we want to delay placement to later (place at nearest safe cell)\n        \n        // The d-th placed container will be roughly extracted at position d\n        // We want extraction position d to have container number close to d\n        // Since t is the container number, ideal: t \u2248 d means place at farthest safe cell\n        // If t < d: this container should've been placed earlier (farther), place far\n        // If t > d: this container should be placed later (nearer), place near\n        \n        // Simple heuristic: sort by distance, pick based on t relative to remaining\n        sort(safe_cells.begin(), safe_cells.end(), [&](auto&a, auto&b){\n            int da=abs(a.first-ei)+abs(a.second-ej);\n            int db=abs(b.first-ei)+abs(b.second-ej);\n            return da>db;\n        });\n        \n        // Low t -> pick from front (far), high t -> pick from back (near)\n        int idx;\n        if(safe_cells.size()==1) idx=0;\n        else idx=(int)((long long)t*(safe_cells.size()-1)/(M-1));\n        \n        auto [ci,cj]=safe_cells[idx];\n        grid[ci][cj]=t;\n        printf(\"%d %d\\n\",ci,cj);\n        fflush(stdout);\n    }\n    \n    for(int i=0;i<M;i++){\n        auto rc=get_reachable_containers();\n        int best=1e9;pair<int,int> bp;\n        for(auto&[r,c]:rc) if(grid[r][c]<best){best=grid[r][c];bp={r,c};}\n        printf(\"%d %d\\n\",bp.first,bp.second);\n        grid[bp.first][bp.second]=-1;\n    }\n    fflush(stdout);\n}","ahc024":"#include<bits/stdc++.h>\nusing namespace std;\n\nint n,m;\nint grid[50][50];\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\n\nint adj_cnt[102][102];\nbool target_adj[102][102];\nint csz[102];\n\nvoid ae(int a,int b){if(a!=b)adj_cnt[a][b]++,adj_cnt[b][a]++;}\nvoid re(int a,int b){if(a!=b)adj_cnt[a][b]--,adj_cnt[b][a]--;}\n\n// Check if color c is connected after cell (ri,rj) was set to 0\n// Only need to verify among same-color neighbors of (ri,rj)\nbool check_conn_local(int c, int ri, int rj){\n    // Find all c-colored neighbors of (ri,rj)\n    vector<pair<int,int>> cnbrs;\n    for(int d=0;d<4;d++){\n        int ni=ri+dx[d],nj=rj+dy[d];\n        if(ni<0||ni>=n||nj<0||nj>=n) continue;\n        if(grid[ni][nj]==c) cnbrs.push_back({ni,nj});\n    }\n    if(cnbrs.size()<=1) return true;\n    \n    // BFS from first c-neighbor, check all others reachable\n    bool vis[50][50]={};\n    queue<pair<int,int>> q;\n    q.push(cnbrs[0]); vis[cnbrs[0].first][cnbrs[0].second]=true;\n    int found=1;\n    while(!q.empty()){\n        auto[ci,cj]=q.front();q.pop();\n        for(int d=0;d<4;d++){\n            int ni=ci+dx[d],nj=cj+dy[d];\n            if(ni<0||ni>=n||nj<0||nj>=n) continue;\n            if(grid[ni][nj]==c&&!vis[ni][nj]){\n                vis[ni][nj]=true;q.push({ni,nj});\n                // Check if this is one of the neighbors\n                for(int k=1;k<(int)cnbrs.size();k++){\n                    if(ni==cnbrs[k].first&&nj==cnbrs[k].second) found++;\n                }\n            }\n        }\n    }\n    return found==(int)cnbrs.size();\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \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    memset(target_adj,0,sizeof(target_adj));\n    memset(adj_cnt,0,sizeof(adj_cnt));\n    memset(csz,0,sizeof(csz));\n    \n    for(int i=0;i<n;i++) for(int j=0;j<n;j++){\n        csz[grid[i][j]]++;\n        if(i==0||i==n-1||j==0||j==n-1){\n            int a=0,b=grid[i][j];\n            target_adj[a][b]=target_adj[b][a]=true;\n        }\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) continue;\n            int a=grid[i][j],b=grid[ni][nj];\n            if(a!=b) target_adj[a][b]=target_adj[b][a]=true;\n        }\n    }\n    \n    for(int i=0;i<n;i++) for(int j=0;j<n;j++){\n        if(i==0||i==n-1||j==0||j==n-1) ae(0,grid[i][j]);\n        if(i+1<n) ae(grid[i][j],grid[i+1][j]);\n        if(j+1<n) ae(grid[i][j],grid[i][j+1]);\n    }\n    \n    int best_grid[50][50];\n    memcpy(best_grid,grid,sizeof(grid));\n    int best_zeros=0;\n    \n    mt19937 rng(42);\n    auto start=chrono::steady_clock::now();\n    \n    auto try_remove=[&](int i, int j) -> bool {\n        int c=grid[i][j];\n        if(c==0) return false;\n        if(csz[c]<=1) return false;\n        \n        bool on_bnd=(i==0||i==n-1||j==0||j==n-1);\n        \n        // Check adjacency loss: edges this cell contributes\n        if(on_bnd && target_adj[0][c] && adj_cnt[0][c]<=1) return false;\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) continue;\n            int nc=grid[ni][nj];\n            if(nc!=c && target_adj[c][nc] && adj_cnt[c][nc]<=1) return false;\n        }\n        \n        // Check bad new adjacency (0 <-> neighbor)\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) continue;\n            int nc=grid[ni][nj];\n            if(nc!=0 && !target_adj[0][nc]) return false;\n        }\n        \n        // 0-connectivity: interior cell needs a 0-neighbor or boundary\n        if(!on_bnd){\n            bool has0=false;\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) continue;\n                if(grid[ni][nj]==0){has0=true;break;}\n            }\n            if(!has0) return false;\n        }\n        \n        // Tentatively remove\n        if(on_bnd) re(0,c);\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) continue;\n            re(c,grid[ni][nj]);\n        }\n        grid[i][j]=0; csz[c]--; csz[0]++;\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) continue;\n            ae(0,grid[ni][nj]);\n        }\n        \n        // Check color c connectivity\n        if(!check_conn_local(c,i,j)){\n            // Revert\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) continue;\n                re(0,grid[ni][nj]);\n            }\n            grid[i][j]=c; csz[c]++; csz[0]--;\n            if(on_bnd) ae(0,c);\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) continue;\n                ae(c,grid[ni][nj]);\n            }\n            return false;\n        }\n        \n        // Check no required adjacency was lost\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) continue;\n            int nc=grid[ni][nj];\n            if(nc!=c && nc!=0 && target_adj[c][nc] && adj_cnt[c][nc]<=0){\n                // Lost adjacency c-nc, revert\n                for(int dd=0;dd<4;dd++){\n                    int ni2=i+dx[dd],nj2=j+dy[dd];\n                    if(ni2<0||ni2>=n||nj2<0||nj2>=n) continue;\n                    re(0,grid[ni2][nj2]);\n                }\n                grid[i][j]=c; csz[c]++; csz[0]--;\n                if(on_bnd) ae(0,c);\n                for(int dd=0;dd<4;dd++){\n                    int ni2=i+dx[dd],nj2=j+dy[dd];\n                    if(ni2<0||ni2>=n||nj2<0||nj2>=n) continue;\n                    ae(c,grid[ni2][nj2]);\n                }\n                return false;\n            }\n        }\n        \n        return true;\n    };\n    \n    vector<pair<int,int>> order;\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) order.push_back({i,j});\n    \n    for(int iter=0;;iter++){\n        auto now=chrono::steady_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-start).count()>1700) break;\n        \n        if(iter>0){\n            memcpy(grid,best_grid,sizeof(grid));\n            memset(adj_cnt,0,sizeof(adj_cnt));\n            memset(csz,0,sizeof(csz));\n            for(int i=0;i<n;i++) for(int j=0;j<n;j++){\n                csz[grid[i][j]]++;\n                if(i==0||i==n-1||j==0||j==n-1) ae(0,grid[i][j]);\n                if(i+1<n) ae(grid[i][j],grid[i+1][j]);\n                if(j+1<n) ae(grid[i][j],grid[i][j+1]);\n            }\n        }\n        \n        shuffle(order.begin(),order.end(),rng);\n        \n        bool changed=true;\n        while(changed){\n            auto now2=chrono::steady_clock::now();\n            if(chrono::duration_cast<chrono::milliseconds>(now2-start).count()>1700) break;\n            changed=false;\n            for(auto&[i,j]:order){\n                if(grid[i][j]!=0 && try_remove(i,j)) changed=true;\n            }\n        }\n        \n        if(csz[0]>best_zeros){\n            best_zeros=csz[0];\n            memcpy(best_grid,grid,sizeof(grid));\n        }\n    }\n    \n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            cout<<best_grid[i][j];\n            if(j<n-1) cout<<' ';\n        }\n        cout<<'\\n';\n    }\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\nchar query(vector<int>& L, vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << \"\\n\" << flush;\n    queries_used++;\n    char c; cin >> c;\n    return c;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\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> left(v.begin(), v.begin()+mid), right(v.begin()+mid, v.end());\n        left = msort(left); right = msort(right);\n        vector<int> res;\n        int i=0,j=0;\n        while(i<(int)left.size()&&j<(int)right.size()){\n            if(queries_used>=Q){res.push_back(left[i++]);continue;}\n            vector<int> L={left[i]}, R={right[j]};\n            char c=query(L,R);\n            if(c=='<'||c=='=') res.push_back(left[i++]);\n            else res.push_back(right[j++]);\n        }\n        while(i<(int)left.size()) res.push_back(left[i++]);\n        while(j<(int)right.size()) res.push_back(right[j++]);\n        return res;\n    };\n    \n    vector<int> si = msort(items); // sorted ascending\n    \n    // Estimate weights: w[si[0]]=1, for each i, binary search how many smallest items equal it\n    vector<double> w(N, 1.0);\n    // cumulative weight estimate\n    vector<double> cum(N+1, 0);\n    cum[1] = 1.0;\n    \n    for(int i=1; i<N && queries_used<Q; i++){\n        // Binary search: find k in [1, i] such that sum of si[0..k-1] ~ si[i]\n        int lo=1, hi=i, best=0;\n        while(lo<=hi && queries_used<Q){\n            int mid=(lo+hi)/2;\n            vector<int> L={si[i]}, R;\n            for(int j=0;j<mid;j++) R.push_back(si[j]);\n            char c=query(L,R);\n            if(c=='>') { best=mid; lo=mid+1; }\n            else if(c=='<') { hi=mid-1; }\n            else { best=mid; break; }\n        }\n        w[si[i]] = (best>0) ? cum[best] + (cum[best]-cum[max(0,best-1)])*0.5 : cum[1]*0.5;\n        if(best>=i) w[si[i]] = cum[i] + (cum[i]-cum[max(0,i-1)])*0.5;\n        cum[i+1] = cum[i] + w[si[i]];\n    }\n    for(int i=1;i<N;i++) if(cum[i+1]==0) { w[si[i]]=w[si[i-1]]; cum[i+1]=cum[i]+w[si[i]]; }\n    \n    while(queries_used<Q){ vector<int> L={0},R={1}; query(L,R); }\n    \n    // LPT partition\n    vector<int> order(si.rbegin(), si.rend());\n    vector<double> gw(D,0);\n    vector<int> assign(N,0);\n    for(int idx:order){ int b=min_element(gw.begin(),gw.end())-gw.begin(); assign[idx]=b; gw[b]+=w[idx]; }\n    \n    for(int i=0;i<N;i++) cout<<assign[i]<<\" \\n\"[i==N-1];\n    cout<<flush;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int n, m;\n    scanf(\"%d%d\", &n, &m);\n    \n    vector<vector<int>> stacks(m);\n    for(int i = 0; i < m; i++){\n        stacks[i].resize(n/m);\n        for(int j = 0; j < n/m; j++)\n            scanf(\"%d\", &stacks[i][j]);\n    }\n    \n    vector<pair<int,int>> ops;\n    \n    auto find_box = [&](int v) -> pair<int,int> {\n        for(int i = 0; i < m; i++)\n            for(int j = 0; j < (int)stacks[i].size(); j++)\n                if(stacks[i][j] == v) return {i, j};\n        return {-1,-1};\n    };\n    \n    // Evaluate state quality: sum of \"depth cost\" for each remaining box\n    // Box v at position j from top costs approximately (j) * urgency\n    auto eval_state = [&](const vector<vector<int>>& st, int next_v) -> double {\n        double cost = 0;\n        for(int i = 0; i < m; i++){\n            int sz = st[i].size();\n            for(int j = 0; j < sz; j++){\n                int v = st[i][j];\n                if(v < next_v) continue;\n                int depth = sz - 1 - j; // 0 = top\n                // Urgency: smaller v needs to come out sooner\n                double urgency = 1.0 / (1.0 + v - next_v);\n                cost += depth * urgency;\n            }\n            // Bonus for sorted portions at top (descending = good)\n            for(int j = sz-1; j >= 1; j--){\n                if(st[i][j] < st[i][j-1]) cost -= 0.5;\n                else break;\n            }\n        }\n        return cost;\n    };\n    \n    int v = 1;\n    while(v <= n){\n        bool found = true;\n        while(found && v <= n){\n            found = false;\n            for(int i = 0; i < m; i++){\n                if(!stacks[i].empty() && stacks[i].back() == v){\n                    ops.push_back({v, 0});\n                    stacks[i].pop_back();\n                    v++; found = true; break;\n                }\n            }\n        }\n        if(v > n) break;\n        \n        auto [si, sj] = find_box(v);\n        int above_cnt = (int)stacks[si].size() - sj - 1;\n        \n        // Try each destination and evaluate resulting state\n        int best_dest = -1;\n        double best_eval = 1e18;\n        \n        for(int d = 0; d < m; d++){\n            if(d == si) continue;\n            auto tmp = stacks;\n            for(int j = sj+1; j < (int)tmp[si].size(); j++)\n                tmp[d].push_back(tmp[si][j]);\n            tmp[si].resize(sj+1);\n            tmp[si].pop_back();\n            \n            double e = eval_state(tmp, v+1) + (above_cnt + 1);\n            if(e < best_eval){ best_eval = e; best_dest = d; }\n        }\n        \n        ops.push_back({stacks[si][sj+1], best_dest+1});\n        for(int j = sj+1; j < (int)stacks[si].size(); j++)\n            stacks[best_dest].push_back(stacks[si][j]);\n        stacks[si].resize(sj+1);\n        \n        ops.push_back({v, 0});\n        stacks[si].pop_back();\n        v++;\n    }\n    \n    for(auto& [a,b] : ops) printf(\"%d %d\\n\", a, b);\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nstring h_wall[40], v_wall[40];\nint d[40][40];\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\nchar dc[]={'U','D','L','R'};\nint distAll[40][40][40][40];\nlong long totalD;\n\nchrono::steady_clock::time_point startTime;\nlong long elapsed_ms(){\n    return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();\n}\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 h_wall[x-1][y]=='0';\n    if(dir==1) return h_wall[x][y]=='0';\n    if(dir==2) return v_wall[x][y-1]=='0';\n    if(dir==3) return v_wall[x][y]=='0';\n    return false;\n}\n\nvoid bfs_dist(int sx,int sy){\n    auto& dd=distAll[sx][sy];\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) dd[i][j]=999999;\n    dd[sx][sy]=0;\n    queue<pair<int,int>> q;\n    q.push({sx,sy});\n    while(!q.empty()){\n        auto [x,y]=q.front();q.pop();\n        for(int dir=0;dir<4;dir++){\n            if(!canMove(x,y,dir)) continue;\n            int nx=x+dx[dir],ny=y+dy[dir];\n            if(dd[nx][ny]>dd[x][y]+1){dd[nx][ny]=dd[x][y]+1;q.push({nx,ny});}\n        }\n    }\n}\n\nvector<int> bfs_path(int sx,int sy,int gx,int gy){\n    if(sx==gx&&sy==gy) return {};\n    int prev[40][40];\n    memset(prev,-1,sizeof(prev));\n    bool vis[40][40]={};\n    queue<pair<int,int>> q;\n    q.push({sx,sy});vis[sx][sy]=true;\n    while(!q.empty()){\n        auto [x,y]=q.front();q.pop();\n        if(x==gx&&y==gy) break;\n        for(int dir=0;dir<4;dir++){\n            if(!canMove(x,y,dir)) continue;\n            int nx=x+dx[dir],ny=y+dy[dir];\n            if(!vis[nx][ny]){vis[nx][ny]=true;prev[nx][ny]=dir;q.push({nx,ny});}\n        }\n    }\n    vector<int> path;\n    int cx=gx,cy=gy;\n    while(cx!=sx||cy!=sy){int dd=prev[cx][cy];path.push_back(dd);cx-=dx[dd];cy-=dy[dd];}\n    reverse(path.begin(),path.end());\n    return path;\n}\n\ndouble fastScore(const vector<int>& route){\n    int L=route.size();\n    int lastVis[40][40], firstVis[40][40];\n    memset(lastVis,-1,sizeof(lastVis));\n    memset(firstVis,-1,sizeof(firstVis));\n    double rawS=0;\n    lastVis[0][0]=0; firstVis[0][0]=0;\n    int cx=0,cy=0;\n    for(int t=0;t<L;t++){\n        cx+=dx[route[t]];cy+=dy[route[t]];\n        if(lastVis[cx][cy]>=0){\n            int gap=t+1-lastVis[cx][cy];\n            rawS+=(double)d[cx][cy]*gap*(gap-1)/2.0;\n        }\n        if(firstVis[cx][cy]<0) firstVis[cx][cy]=t+1;\n        lastVis[cx][cy]=t+1;\n    }\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n        if(firstVis[i][j]<0) rawS+=(double)d[i][j]*L*(L-1)/2.0;\n        else{int gap=L-lastVis[i][j]+firstVis[i][j];rawS+=(double)d[i][j]*gap*(gap-1)/2.0;}\n    }\n    return rawS/L;\n}\n\nstruct State {\n    vector<int> route;\n    vector<pair<int,int>> positions;\n    vector<vector<int>> vt;\n    double score;\n    int L;\n    \n    void build(){\n        L=route.size();\n        positions.resize(L+1);\n        vt.assign(N*N,vector<int>());\n        int cx=0,cy=0;\n        positions[0]={0,0};\n        vt[0].push_back(0);\n        for(int t=0;t<L;t++){\n            cx+=dx[route[t]];cy+=dy[route[t]];\n            positions[t+1]={cx,cy};\n            vt[cx*N+cy].push_back(t+1);\n        }\n        score=fastScore(route);\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    startTime=chrono::steady_clock::now();\n    \n    cin>>N;\n    for(int i=0;i<N-1;i++) cin>>h_wall[i];\n    for(int i=0;i<N;i++) cin>>v_wall[i];\n    totalD=0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++){cin>>d[i][j];totalD+=d[i][j];}\n    \n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) bfs_dist(i,j);\n    \n    auto dfsRoute=[&](bool highFirst)->vector<int>{\n        vector<int> route;\n        vector<vector<bool>> vis(N,vector<bool>(N,false));\n        function<void(int,int)> dfs=[&](int x,int y){\n            vis[x][y]=true;\n            vector<pair<int,int>> nb;\n            for(int dir=0;dir<4;dir++){\n                if(!canMove(x,y,dir)) continue;\n                int nx=x+dx[dir],ny=y+dy[dir];\n                if(!vis[nx][ny]) nb.push_back({dir,d[nx][ny]});\n            }\n            if(highFirst) sort(nb.begin(),nb.end(),[](auto&a,auto&b){return a.second>b.second;});\n            else sort(nb.begin(),nb.end(),[](auto&a,auto&b){return a.second<b.second;});\n            for(auto&[dir,_]:nb){\n                int nx=x+dx[dir],ny=y+dy[dir];\n                if(!vis[nx][ny]){route.push_back(dir);dfs(nx,ny);route.push_back(dir^1);}\n            }\n        };\n        dfs(0,0);\n        return route;\n    };\n    \n    auto greedyRoute=[&](double power)->vector<int>{\n        vector<vector<bool>> vis(N,vector<bool>(N,false));\n        vis[0][0]=true;\n        vector<int> route;\n        int cx=0,cy=0,rem=N*N-1;\n        while(rem>0){\n            int bx=-1,by=-1;double bs=-1;\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n                if(vis[i][j]) continue;\n                int dd=distAll[cx][cy][i][j];\n                double sc=pow((double)d[i][j],power)/(dd+1);\n                if(sc>bs){bs=sc;bx=i;by=j;}\n            }\n            auto p=bfs_path(cx,cy,bx,by);\n            int tx=cx,ty=cy;\n            for(int dir:p){route.push_back(dir);tx+=dx[dir];ty+=dy[dir];if(!vis[tx][ty]){vis[tx][ty]=true;rem--;}}\n            cx=bx;cy=by;\n        }\n        auto p=bfs_path(cx,cy,0,0);\n        for(int dir:p) route.push_back(dir);\n        return route;\n    };\n    \n    State best;\n    best.score=1e18;\n    \n    auto tryRoute=[&](vector<int> r){\n        State s;s.route=r;s.build();\n        if(s.score<best.score) best=s;\n    };\n    \n    tryRoute(greedyRoute(1.0));\n    tryRoute(greedyRoute(0.5));\n    tryRoute(greedyRoute(1.5));\n    tryRoute(greedyRoute(2.0));\n    tryRoute(greedyRoute(0.3));\n    tryRoute(dfsRoute(true));\n    tryRoute(dfsRoute(false));\n    \n    // Main detour insertion loop\n    int noImprove=0;\n    \n    while(elapsed_ms()<1750){\n        int L=best.L;\n        if(L>=95000){\n            break;\n        }\n        \n        // Collect ALL gaps sorted by d*gap^2\n        struct GapInfo{int ci,cj,gap,gapIdx;double pot;};\n        vector<GapInfo> allGaps;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            auto& v=best.vt[i*N+j];\n            int k=v.size();\n            if(k==0) continue;\n            for(int a=0;a<k;a++){\n                int gap=(a+1<k)?v[a+1]-v[a]:L-v[a]+v[0];\n                if(gap>=3) allGaps.push_back({i,j,gap,a,(double)d[i][j]*gap*(double)gap});\n            }\n        }\n        sort(allGaps.begin(),allGaps.end(),[](auto&a,auto&b){return a.pot>b.pot;});\n        \n        int maxTry=min((int)allGaps.size(),40);\n        if(maxTry==0) break;\n        \n        double bestNewScore=best.score;\n        vector<int> bestNewRoute;\n        \n        for(int c=0;c<maxTry;c++){\n            if(elapsed_ms()>1750) break;\n            auto& gi=allGaps[c];\n            auto& v=best.vt[gi.ci*N+gi.cj];\n            int k=v.size();\n            int tStart=v[gi.gapIdx];\n            int tEnd=(gi.gapIdx+1<k)?v[gi.gapIdx+1]:v[0]+L;\n            \n            // Try insertion at 1/2 of gap\n            for(int num=1;num<=1;num++){\n                int insertTime=tStart+(tEnd-tStart)/2;\n                if(insertTime>=L) insertTime-=L;\n                if(insertTime<0) insertTime=0;\n                \n                auto [px,py]=best.positions[insertTime];\n                int dd=distAll[px][py][gi.ci][gi.cj];\n                int detourCost=2*dd;\n                if(detourCost==0||L+detourCost>99000) continue;\n                \n                // Quick estimate filter\n                double g=(double)gi.gap;\n                double saving=(double)d[gi.ci][gi.cj]*(g*g/4.0); // approx\n                double cost_inc=(double)totalD*detourCost; // very rough\n                // Be lenient with filter\n                if(saving < cost_inc*0.3) continue;\n                \n                auto pathTo=bfs_path(px,py,gi.ci,gi.cj);\n                auto pathBack=bfs_path(gi.ci,gi.cj,px,py);\n                \n                vector<int> newRoute;\n                newRoute.reserve(L+detourCost);\n                newRoute.insert(newRoute.end(),best.route.begin(),best.route.begin()+insertTime);\n                newRoute.insert(newRoute.end(),pathTo.begin(),pathTo.end());\n                newRoute.insert(newRoute.end(),pathBack.begin(),pathBack.end());\n                newRoute.insert(newRoute.end(),best.route.begin()+insertTime,best.route.end());\n                \n                double ns=fastScore(newRoute);\n                if(ns<bestNewScore){\n                    bestNewScore=ns;\n                    bestNewRoute=move(newRoute);\n                }\n            }\n        }\n        \n        if(!bestNewRoute.empty() && bestNewScore<best.score){\n            best.route=move(bestNewRoute);\n            best.build();\n            noImprove=0;\n        } else {\n            noImprove++;\n            if(noImprove>=3) break;\n        }\n    }\n    \n    // Phase 2: Try swapping detour targets / local search\n    // Try removing segments and see if score improves (shortening route)\n    // For each pair of positions close together in the route, try shortcutting\n    if(elapsed_ms()<1700 && best.L > 2*N*N){\n        // Try random segment removals\n        mt19937 rng(12345);\n        int attempts=0;\n        while(elapsed_ms()<1750 && attempts<500){\n            attempts++;\n            int L=best.L;\n            // Pick a random position in route\n            int t1=rng()%L;\n            // Find if we revisit the same position later\n            auto [x1,y1]=best.positions[t1];\n            // Search for another time we're at (x1,y1)\n            auto& vlist=best.vt[x1*N+y1];\n            if(vlist.size()<2) continue;\n            // Find t1 in vlist\n            auto it=lower_bound(vlist.begin(),vlist.end(),t1);\n            if(it==vlist.end()||*it!=t1) continue;\n            int idx=it-vlist.begin();\n            if(idx+1>=(int)vlist.size()) continue;\n            int t2=vlist[idx+1];\n            int segLen=t2-t1;\n            if(segLen<2||segLen>L/2) continue;\n            \n            // Try removing segment [t1, t2) - we skip from position t1 directly to t2\n            // This works because positions[t1] == positions[t2]  (same cell)\n            // But we need to check all cells are still visited\n            vector<int> newRoute;\n            newRoute.reserve(L-segLen);\n            for(int t=0;t<t1;t++) newRoute.push_back(best.route[t]);\n            for(int t=t2;t<L;t++) newRoute.push_back(best.route[t]);\n            \n            // Check all cells visited\n            bool allVis[40][40]={};\n            allVis[0][0]=true;\n            int cx=0,cy=0;\n            bool valid=true;\n            for(int t=0;t<(int)newRoute.size();t++){\n                cx+=dx[newRoute[t]];cy+=dy[newRoute[t]];\n                if(cx<0||cx>=N||cy<0||cy>=N){valid=false;break;}\n                allVis[cx][cy]=true;\n            }\n            if(!valid||cx!=0||cy!=0) continue;\n            bool allOk=true;\n            for(int i=0;i<N&&allOk;i++) for(int j=0;j<N&&allOk;j++) if(!allVis[i][j]) allOk=false;\n            if(!allOk) continue;\n            \n            double ns=fastScore(newRoute);\n            if(ns<best.score){\n                best.route=move(newRoute);\n                best.build();\n            }\n        }\n    }\n    \n    // Phase 3: More detour insertions with remaining time\n    noImprove=0;\n    while(elapsed_ms()<1800){\n        int L=best.L;\n        if(L>=95000) break;\n        \n        struct GapInfo{int ci,cj,gap,gapIdx;double pot;};\n        vector<GapInfo> allGaps;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            auto& v=best.vt[i*N+j];\n            int k=v.size();\n            if(k==0) continue;\n            for(int a=0;a<k;a++){\n                int gap=(a+1<k)?v[a+1]-v[a]:L-v[a]+v[0];\n                if(gap>=3) allGaps.push_back({i,j,gap,a,(double)d[i][j]*gap*(double)gap});\n            }\n        }\n        sort(allGaps.begin(),allGaps.end(),[](auto&a,auto&b){return a.pot>b.pot;});\n        \n        int maxTry=min((int)allGaps.size(),20);\n        if(maxTry==0) break;\n        \n        double bestNewScore=best.score;\n        vector<int> bestNewRoute;\n        \n        for(int c=0;c<maxTry;c++){\n            if(elapsed_ms()>1800) break;\n            auto& gi=allGaps[c];\n            auto& v=best.vt[gi.ci*N+gi.cj];\n            int k=v.size();\n            int tStart=v[gi.gapIdx];\n            int tEnd=(gi.gapIdx+1<k)?v[gi.gapIdx+1]:v[0]+L;\n            int insertTime=(tStart+tEnd)/2;\n            if(insertTime>=L) insertTime-=L;\n            \n            auto [px,py]=best.positions[insertTime];\n            int detourCost=2*distAll[px][py][gi.ci][gi.cj];\n            if(detourCost==0||L+detourCost>99000) continue;\n            \n            auto pathTo=bfs_path(px,py,gi.ci,gi.cj);\n            auto pathBack=bfs_path(gi.ci,gi.cj,px,py);\n            \n            vector<int> newRoute;\n            newRoute.reserve(L+detourCost);\n            newRoute.insert(newRoute.end(),best.route.begin(),best.route.begin()+insertTime);\n            newRoute.insert(newRoute.end(),pathTo.begin(),pathTo.end());\n            newRoute.insert(newRoute.end(),pathBack.begin(),pathBack.end());\n            newRoute.insert(newRoute.end(),best.route.begin()+insertTime,best.route.end());\n            \n            double ns=fastScore(newRoute);\n            if(ns<bestNewScore){bestNewScore=ns;bestNewRoute=move(newRoute);}\n        }\n        \n        if(!bestNewRoute.empty()&&bestNewScore<best.score){\n            best.route=move(bestNewRoute);\n            best.build();\n            noImprove=0;\n        } else {\n            noImprove++;\n            if(noImprove>=3) break;\n        }\n    }\n    \n    string ans;\n    for(int dir:best.route) ans+=dc[dir];\n    cout<<ans<<endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint N;\nvector<vector<pair<int,int>>> charpos(26);\nvector<string> gridv;\n\npair<int,int> typeStringCostDP(const string& s, int sp){\n    if(s.empty()) return {0, sp};\n    int len=s.size();\n    int NN=N*N;\n    vector<int> cur(NN, INT_MAX);\n    int spi=sp/N, spj=sp%N;\n    for(auto&[ni,nj]:charpos[s[0]-'A']){\n        int cost=abs(ni-spi)+abs(nj-spj)+1;\n        int np=ni*N+nj;\n        cur[np]=min(cur[np],cost);\n    }\n    for(int k=1;k<len;k++){\n        vector<int> nxt(NN, INT_MAX);\n        int ck=s[k]-'A';\n        for(auto&[pi,pj]:charpos[s[k-1]-'A']){\n            int pp=pi*N+pj;\n            if(cur[pp]==INT_MAX) continue;\n            for(auto&[ni,nj]:charpos[ck]){\n                int cost=cur[pp]+abs(ni-pi)+abs(nj-pj)+1;\n                int np=ni*N+nj;\n                nxt[np]=min(nxt[np],cost);\n            }\n        }\n        cur=nxt;\n    }\n    int bestC=INT_MAX,bestP=-1;\n    for(auto&[ei,ej]:charpos[s.back()-'A']){\n        int ep=ei*N+ej;\n        if(cur[ep]<bestC){bestC=cur[ep];bestP=ep;}\n    }\n    return {bestC,bestP};\n}\n\nvector<pair<int,int>> typeStringPath(const string& s, int sp){\n    if(s.empty()) return {};\n    int len=s.size();\n    int NN=N*N;\n    vector<vector<pair<int,int>>> alldp(len, vector<pair<int,int>>(NN,{INT_MAX,-1}));\n    int spi=sp/N,spj=sp%N;\n    for(auto&[ni,nj]:charpos[s[0]-'A']){\n        int cost=abs(ni-spi)+abs(nj-spj)+1;\n        int np=ni*N+nj;\n        if(cost<alldp[0][np].first) alldp[0][np]={cost,-1};\n    }\n    for(int k=1;k<len;k++){\n        int ck=s[k]-'A';\n        for(auto&[pi,pj]:charpos[s[k-1]-'A']){\n            int pp=pi*N+pj;\n            if(alldp[k-1][pp].first==INT_MAX) continue;\n            for(auto&[ni,nj]:charpos[ck]){\n                int cost=alldp[k-1][pp].first+abs(ni-pi)+abs(nj-pj)+1;\n                int np=ni*N+nj;\n                if(cost<alldp[k][np].first) alldp[k][np]={cost,pp};\n            }\n        }\n    }\n    int bestP=-1,bestC=INT_MAX;\n    for(auto&[ei,ej]:charpos[s.back()-'A']){\n        int ep=ei*N+ej;\n        if(alldp[len-1][ep].first<bestC){bestC=alldp[len-1][ep].first;bestP=ep;}\n    }\n    vector<pair<int,int>> path(len);\n    int cp=bestP;\n    for(int k=len-1;k>=0;k--){\n        path[k]={cp/N,cp%N};\n        if(k>0) cp=alldp[k][cp].second;\n    }\n    return path;\n}\n\nint main(){\n    auto t0=steady_clock::now();\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int M;\n    cin>>N>>M;\n    int si,sj;\n    cin>>si>>sj;\n    \n    gridv.resize(N);\n    for(int i=0;i<N;i++) cin>>gridv[i];\n    \n    vector<string> words(M);\n    for(int i=0;i<M;i++) cin>>words[i];\n    \n    for(int i=0;i<N;i++)\n        for(int j=0;j<N;j++)\n            charpos[gridv[i][j]-'A'].push_back({i,j});\n    \n    int NN=N*N;\n    \n    // Remove contained words\n    vector<bool> removed(M,false);\n    for(int i=0;i<M;i++) if(!removed[i])\n        for(int j=0;j<M;j++) if(i!=j&&!removed[j])\n            if(words[i].find(words[j])!=string::npos) removed[j]=true;\n    \n    vector<string> ws;\n    for(int i=0;i<M;i++) if(!removed[i]) ws.push_back(words[i]);\n    int n=ws.size();\n    \n    // Overlap matrix\n    vector<vector<int>> ov(n,vector<int>(n,0));\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j){\n        int maxo=min((int)ws[i].size(),(int)ws[j].size());\n        for(int o=maxo;o>=1;o--){\n            if(ws[i].compare(ws[i].size()-o,o,ws[j],0,o)==0){ov[i][j]=o;break;}\n        }\n    }\n    \n    // Precompute: for each word w and overlap value o (0..4),\n    // table[w][o] maps start_pos -> (cost, end_pos)\n    // suffix = ws[w].substr(o)\n    // For o >= len(ws[w]), suffix is empty -> cost=0, end=start\n    \n    // table[w][o][sp] = {cost, end_pos}\n    vector<vector<vector<pair<int,int>>>> table(n, vector<vector<pair<int,int>>>(6));\n    \n    for(int w=0;w<n;w++){\n        int wlen=ws[w].size();\n        for(int o=0;o<=min(4,wlen);o++){\n            string sub=ws[w].substr(o);\n            table[w][o].resize(NN);\n            if(sub.empty()){\n                for(int sp=0;sp<NN;sp++) table[w][o][sp]={0,sp};\n                continue;\n            }\n            int slen=sub.size();\n            for(int sp=0;sp<NN;sp++){\n                vector<int> cur(NN,INT_MAX);\n                int spi=sp/N,spj=sp%N;\n                for(auto&[ni,nj]:charpos[sub[0]-'A']){\n                    int cost=abs(ni-spi)+abs(nj-spj)+1;\n                    cur[ni*N+nj]=min(cur[ni*N+nj],cost);\n                }\n                for(int k=1;k<slen;k++){\n                    vector<int> nxt(NN,INT_MAX);\n                    int ck=sub[k]-'A';\n                    for(auto&[pi,pj]:charpos[sub[k-1]-'A']){\n                        int pp=pi*N+pj;\n                        if(cur[pp]==INT_MAX) continue;\n                        for(auto&[ni,nj]:charpos[ck]){\n                            int cost=cur[pp]+abs(ni-pi)+abs(nj-pj)+1;\n                            nxt[ni*N+nj]=min(nxt[ni*N+nj],cost);\n                        }\n                    }\n                    cur=nxt;\n                }\n                int bestC=INT_MAX,bestP=-1;\n                for(auto&[ei,ej]:charpos[sub.back()-'A']){\n                    int ep=ei*N+ej;\n                    if(cur[ep]<bestC){bestC=cur[ep];bestP=ep;}\n                }\n                table[w][o][sp]={bestC,bestP};\n            }\n        }\n    }\n    \n    int startPos=si*N+sj;\n    \n    // Fast evaluate\n    auto evaluate=[&](const vector<int>& ord) -> pair<int,vector<int>> {\n        int cp=startPos, total=0;\n        vector<int> ep(ord.size());\n        for(int i=0;i<(int)ord.size();i++){\n            int w=ord[i];\n            int o=(i>0)?ov[ord[i-1]][w]:0;\n            auto [c,e]=table[w][o][cp];\n            total+=c; cp=e; ep[i]=e;\n        }\n        return {total,ep};\n    };\n    \n    // Greedy nearest neighbor\n    auto greedyOrder=[&](int firstW=-1) -> vector<int> {\n        vector<bool> used(n,false);\n        vector<int> ord;\n        int cp=startPos;\n        \n        if(firstW<0){\n            int bestW=-1,bestC=INT_MAX,bestE=-1;\n            for(int w=0;w<n;w++){\n                auto [c,e]=table[w][0][cp];\n                if(c<bestC){bestC=c;bestW=w;bestE=e;}\n            }\n            firstW=bestW;\n        }\n        ord.push_back(firstW); used[firstW]=true;\n        cp=table[firstW][0][startPos].second;\n        \n        while((int)ord.size()<n){\n            int prev=ord.back();\n            int bestW=-1,bestC=INT_MAX,bestE=-1;\n            for(int w=0;w<n;w++) if(!used[w]){\n                int o=ov[prev][w];\n                auto [c,e]=table[w][o][cp];\n                if(c<bestC){bestC=c;bestW=w;bestE=e;}\n            }\n            ord.push_back(bestW); used[bestW]=true;\n            cp=bestE;\n        }\n        return ord;\n    };\n    \n    // Try multiple starting words\n    auto bestOrder=greedyOrder(-1);\n    auto [bestCost,bestEP]=evaluate(bestOrder);\n    \n    for(int fw=0;fw<n;fw++){\n        auto elapsed=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n        if(elapsed>600) break;\n        auto ord=greedyOrder(fw);\n        auto [c,ep]=evaluate(ord);\n        if(c<bestCost){bestCost=c;bestOrder=ord;bestEP=ep;}\n    }\n    \n    // Aggressive local search: swap, or-opt, 2-opt\n    for(int round=0;;round++){\n        auto elapsed=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n        if(elapsed>1600) break;\n        bool improved=false;\n        \n        // Swap\n        for(int i=0;i<n&&!improved;i++){\n            for(int j=i+1;j<n&&!improved;j++){\n                swap(bestOrder[i],bestOrder[j]);\n                auto [nc,ne]=evaluate(bestOrder);\n                if(nc<bestCost){bestCost=nc;bestEP=ne;improved=true;}\n                else swap(bestOrder[i],bestOrder[j]);\n            }\n        }\n        \n        // Or-opt: move element i to position j\n        if(!improved){\n            for(int i=0;i<n&&!improved;i++){\n                int w=bestOrder[i];\n                auto newOrd=bestOrder;\n                newOrd.erase(newOrd.begin()+i);\n                for(int j=0;j<=n-1&&!improved;j++){\n                    if(j==i) continue;\n                    auto tryOrd=newOrd;\n                    int ins=j>i?j-1:j;\n                    tryOrd.insert(tryOrd.begin()+ins,w);\n                    auto [nc,ne]=evaluate(tryOrd);\n                    if(nc<bestCost){bestCost=nc;bestOrder=tryOrd;bestEP=ne;improved=true;}\n                }\n            }\n        }\n        \n        if(!improved) break;\n    }\n    \n    // Reconstruct path\n    vector<pair<int,int>> result;\n    int cp=startPos;\n    string S;\n    for(int i=0;i<(int)bestOrder.size();i++){\n        int w=bestOrder[i];\n        int o=(i>0)?ov[bestOrder[i-1]][w]:0;\n        string sub=ws[w].substr(o);\n        if(sub.empty()) continue;\n        auto path=typeStringPath(sub, cp);\n        for(auto&p:path){result.push_back(p);S+=gridv[p.first][p.second];}\n        if(!path.empty()) cp=path.back().first*N+path.back().second;\n    }\n    \n    // Add missing words\n    for(auto&w:words){\n        if(S.find(w)==string::npos){\n            int bestOv=0;\n            int maxo=min((int)S.size(),(int)w.size());\n            for(int o=maxo;o>=1;o--){\n                if(S.compare(S.size()-o,o,w,0,o)==0){bestOv=o;break;}\n            }\n            string sub=w.substr(bestOv);\n            if(sub.empty()) continue;\n            auto path=typeStringPath(sub, cp);\n            for(auto&p:path){result.push_back(p);S+=gridv[p.first][p.second];}\n            if(!path.empty()) cp=path.back().first*N+path.back().second;\n        }\n    }\n    \n    for(auto&[r,c]:result) cout<<r<<\" \"<<c<<\"\\n\";\n}","ahc030":"#include<bits/stdc++.h>\nusing namespace std;\nmt19937 rng(42);\nint N,M;double eps_;\nchrono::steady_clock::time_point t0;\ndouble elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-t0).count();}\n\ndouble log_prob(int obs,int ts,int kk){\n    double mu=(kk-ts)*eps_+ts*(1.0-eps_);\n    double s2=kk*eps_*(1.0-eps_);\n    double s=sqrt(s2);\n    if(s<1e-12)return obs==(int)round(mu)?0.0:-1e15;\n    double lo=obs==0?-40.0:(obs-0.5-mu)/s;\n    double hi=(obs+0.5-mu)/s;\n    double p=0.5*erfc(-hi*M_SQRT1_2)-0.5*erfc(-lo*M_SQRT1_2);\n    return p<1e-300?-690.0:log(p);\n}\n\nint main(){\n    t0=chrono::steady_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin>>N>>M>>eps_;\n    int NN=N*N;\n    \n    vector<vector<pair<int,int>>>fields(M);\n    for(int k=0;k<M;k++){\n        int d;cin>>d;fields[k].resize(d);\n        for(int i=0;i<d;i++)cin>>fields[k][i].first>>fields[k][i].second;\n    }\n    \n    vector<vector<vector<int>>>pflat(M);\n    for(int k=0;k<M;k++){\n        int mi=0,mj=0;\n        for(auto&[r,c]:fields[k]){mi=max(mi,r);mj=max(mj,c);}\n        for(int di=0;di+mi<N;di++)\n            for(int dj=0;dj+mj<N;dj++){\n                vector<int>sq;\n                for(auto&[r,c]:fields[k])sq.push_back((r+di)*N+(c+dj));\n                pflat[k].push_back(sq);\n            }\n    }\n    \n    int ops=0,maxops=2*NN;\n    vector<int>known(NN,-1);\n    vector<bool>is_oil(NN,false),is_empty(NN,false);\n    \n    auto query_grp=[&](vector<int>&S)->int{\n        cout<<\"q \"<<S.size();\n        for(int x:S)cout<<\" \"<<x/N<<\" \"<<x%N;\n        cout<<\"\\n\"<<flush;\n        int v;cin>>v;ops++;return v;\n    };\n    auto drill=[&](int idx)->int{\n        vector<int>S={idx};int v=query_grp(S);\n        known[idx]=v;\n        if(v>0)is_oil[idx]=true;else is_empty[idx]=true;\n        return v;\n    };\n    auto guess=[&](vector<int>&ans)->bool{\n        set<int>as(ans.begin(),ans.end());\n        for(int i=0;i<NN;i++)if(is_oil[i])as.insert(i);\n        ans.assign(as.begin(),as.end());\n        cout<<\"a \"<<ans.size();\n        for(int x:ans)cout<<\" \"<<x/N<<\" \"<<x%N;\n        cout<<\"\\n\"<<flush;\n        int r;cin>>r;ops++;return r==1;\n    };\n    \n    // Precompute row/col contributions for each placement\n    // row_ct[k][p][i] = how many cells of placement p of field k are in row i\n    vector<vector<vector<short>>>row_ct(M),col_ct(M);\n    for(int k=0;k<M;k++){\n        int np=pflat[k].size();\n        row_ct[k].assign(np,vector<short>(N,0));\n        col_ct[k].assign(np,vector<short>(N,0));\n        for(int p=0;p<np;p++)\n            for(int idx:pflat[k][p]){\n                row_ct[k][p][idx/N]++;\n                col_ct[k][p][idx%N]++;\n            }\n    }\n    \n    // Query rows and columns\n    int rep=1;\n    if(eps_>=0.10)rep=2;\n    if(eps_>=0.17)rep=3;\n    \n    vector<vector<int>>row_obs(N),col_obs(N);\n    for(int rr=0;rr<rep;rr++){\n        for(int i=0;i<N;i++){\n            vector<int>S;for(int j=0;j<N;j++)S.push_back(i*N+j);\n            row_obs[i].push_back(query_grp(S));\n        }\n        for(int j=0;j<N;j++){\n            vector<int>S;for(int i=0;i<N;i++)S.push_back(i*N+j);\n            col_obs[j].push_back(query_grp(S));\n        }\n    }\n    \n    // Compute LL contribution from rows and cols\n    // row_sum[i] = sum of row_ct[k][ch[k]][i] for all k\n    // col_sum[j] = sum of col_ct[k][ch[k]][j] for all k\n    \n    vector<int>vl_all[20]; // valid list per field\n    auto upd_valid=[&](){\n        for(int k=0;k<M;k++){\n            vl_all[k].clear();\n            for(int p=0;p<(int)pflat[k].size();p++){\n                bool ok=true;\n                for(int idx:pflat[k][p])\n                    if(is_empty[idx]){ok=false;break;}\n                if(ok)vl_all[k].push_back(p);\n            }\n            if(vl_all[k].empty())\n                for(int p=0;p<(int)pflat[k].size();p++)vl_all[k].push_back(p);\n        }\n    };\n    upd_valid();\n    \n    vector<int>ch(M);\n    vector<int>rsum(N,0),csum(N,0);\n    vector<int>grid(NN,0);\n    \n    auto full_init=[&](){\n        fill(rsum.begin(),rsum.end(),0);\n        fill(csum.begin(),csum.end(),0);\n        fill(grid.begin(),grid.end(),0);\n        for(int k=0;k<M;k++){\n            for(int i=0;i<N;i++){rsum[i]+=row_ct[k][ch[k]][i];csum[i]+=col_ct[k][ch[k]][i];}\n            for(int idx:pflat[k][ch[k]])grid[idx]++;\n        }\n    };\n    \n    auto compute_ll=[&]()->double{\n        double ll=0;\n        for(int i=0;i<N;i++)for(int v:row_obs[i])ll+=log_prob(v,rsum[i],N);\n        for(int j=0;j<N;j++)for(int v:col_obs[j])ll+=log_prob(v,csum[j],N);\n        return ll;\n    };\n    \n    // Row LL per row, col LL per col - for incremental\n    vector<double>rll(N),cll(N);\n    double tll;\n    auto compute_all_ll=[&](){\n        tll=0;\n        for(int i=0;i<N;i++){rll[i]=0;for(int v:row_obs[i])rll[i]+=log_prob(v,rsum[i],N);tll+=rll[i];}\n        for(int j=0;j<N;j++){cll[j]=0;for(int v:col_obs[j])cll[j]+=log_prob(v,csum[j],N);tll+=cll[j];}\n    };\n    \n    for(int k=0;k<M;k++)ch[k]=vl_all[k][rng()%vl_all[k].size()];\n    full_init();\n    compute_all_ll();\n    \n    double best_ll=tll;\n    vector<int>best_ch=ch;\n    \n    // Gibbs-like MCMC: for field k, compute conditional score for each valid placement\n    // Only recompute affected rows/cols\n    \n    auto mcmc_step=[&](bool gibbs)->bool{\n        int k=rng()%M;\n        int vsz=vl_all[k].size();\n        if(vsz<=1)return false;\n        int op=ch[k];\n        \n        if(!gibbs){\n            // Metropolis\n            int np=vl_all[k][rng()%vsz];\n            if(np==op)return false;\n            \n            // Check oil constraint\n            for(int idx:pflat[k][op])\n                if(is_oil[idx]&&grid[idx]==1){\n                    bool covers=false;\n                    for(int idx2:pflat[k][np])if(idx2==idx){covers=true;break;}\n                    if(!covers)return false;\n                }\n            \n            // Compute delta incrementally\n            // Affected rows/cols\n            double delta=0;\n            // Remove old row/col contributions, add new\n            // Find which rows/cols are affected\n            static vector<int>arows,acols;\n            arows.clear();acols.clear();\n            for(int i=0;i<N;i++){\n                if(row_ct[k][op][i]!=row_ct[k][np][i])arows.push_back(i);\n                if(col_ct[k][op][i]!=col_ct[k][np][i])acols.push_back(i);\n            }\n            \n            // Update and compute new LL for affected rows\n            vector<pair<int,int>>row_save,col_save;\n            vector<pair<int,double>>rll_save,cll_save;\n            for(int i:arows){\n                row_save.push_back({i,rsum[i]});\n                rll_save.push_back({i,rll[i]});\n                rsum[i]+=row_ct[k][np][i]-row_ct[k][op][i];\n                double nrl=0;for(int v:row_obs[i])nrl+=log_prob(v,rsum[i],N);\n                delta+=nrl-rll[i];\n                rll[i]=nrl;\n            }\n            for(int j:acols){\n                col_save.push_back({j,csum[j]});\n                cll_save.push_back({j,cll[j]});\n                csum[j]+=col_ct[k][np][j]-col_ct[k][op][j];\n                double ncl=0;for(int v:col_obs[j])ncl+=log_prob(v,csum[j],N);\n                delta+=ncl-cll[j];\n                cll[j]=ncl;\n            }\n            \n            if(delta>0||log(uniform_real_distribution<double>(1e-300,1)(rng))<delta){\n                for(int idx:pflat[k][op])grid[idx]--;\n                for(int idx:pflat[k][np])grid[idx]++;\n                ch[k]=np;tll+=delta;\n                if(tll>best_ll){best_ll=tll;best_ch=ch;}\n                return true;\n            }else{\n                for(auto&[i,v]:row_save)rsum[i]=v;\n                for(auto&[i,v]:rll_save)rll[i]=v;\n                for(auto&[j,v]:col_save)csum[j]=v;\n                for(auto&[j,v]:cll_save)cll[j]=v;\n                return false;\n            }\n        }else{\n            // Gibbs: compute score for each valid placement of field k\n            // Remove field k contribution\n            for(int i=0;i<N;i++){rsum[i]-=row_ct[k][op][i];csum[i]-=col_ct[k][op][i];}\n            for(int idx:pflat[k][op])grid[idx]--;\n            \n            // Score each placement\n            static vector<double>scores;\n            scores.resize(vsz);\n            double maxs=-1e18;\n            for(int vi=0;vi<vsz;vi++){\n                int p=vl_all[k][vi];\n                // Check oil constraint\n                bool ok=true;\n                // Actually checking all oil cells is expensive, skip for gibbs\n                // We'll handle via filtering\n                \n                double s=0;\n                for(int i=0;i<N;i++){\n                    int ns=rsum[i]+row_ct[k][p][i];\n                    for(int v:row_obs[i])s+=log_prob(v,ns,N);\n                    int nc=csum[i]+col_ct[k][p][i];\n                    for(int v:col_obs[i])s+=log_prob(v,nc,N);\n                }\n                scores[vi]=s;\n                if(s>maxs)maxs=s;\n            }\n            \n            // Sample proportional to exp(score)\n            double sum=0;\n            for(int vi=0;vi<vsz;vi++){\n                scores[vi]=exp(scores[vi]-maxs);\n                sum+=scores[vi];\n            }\n            \n            double r2=uniform_real_distribution<double>(0,sum)(rng);\n            int chosen=0;\n            double acc=0;\n            for(int vi=0;vi<vsz;vi++){\n                acc+=scores[vi];\n                if(acc>=r2){chosen=vi;break;}\n            }\n            \n            int np=vl_all[k][chosen];\n            ch[k]=np;\n            for(int i=0;i<N;i++){rsum[i]+=row_ct[k][np][i];csum[i]+=col_ct[k][np][i];}\n            for(int idx:pflat[k][np])grid[idx]++;\n            \n            // Recompute LL\n            compute_all_ll();\n            if(tll>best_ll){best_ll=tll;best_ch=ch;}\n            return true;\n        }\n    };\n    \n    auto run_mcmc=[&](double tlim,vector<double>&occ,int&samp){\n        samp=0;int it=0;int warmup=1000;\n        while(elapsed()<tlim){\n            for(int b=0;b<500;b++){\n                it++;\n                // Use Gibbs every 10th step if not too many placements\n                bool use_gibbs=(it%5==0);\n                int k=rng()%M;\n                if(use_gibbs&&(int)vl_all[k].size()>500)use_gibbs=false;\n                if(use_gibbs&&(int)vl_all[k].size()*N*rep>50000)use_gibbs=false;\n                \n                if(use_gibbs){\n                    // Gibbs for random field\n                    int op=ch[k];\n                    int vsz=vl_all[k].size();\n                    if(vsz<=1){mcmc_step(false);goto sample;}\n                    for(int i=0;i<N;i++){rsum[i]-=row_ct[k][op][i];csum[i]-=col_ct[k][op][i];}\n                    for(int idx:pflat[k][op])grid[idx]--;\n                    \n                    {\n                        vector<double>sc(vsz);\n                        double mx=-1e18;\n                        for(int vi=0;vi<vsz;vi++){\n                            int p=vl_all[k][vi];\n                            double s=0;\n                            for(int i=0;i<N;i++){\n                                for(int v:row_obs[i])s+=log_prob(v,rsum[i]+row_ct[k][p][i],N);\n                                for(int v:col_obs[i])s+=log_prob(v,csum[i]+col_ct[k][p][i],N);\n                            }\n                            sc[vi]=s;if(s>mx)mx=s;\n                        }\n                        double sm=0;\n                        for(int vi=0;vi<vsz;vi++){sc[vi]=exp(sc[vi]-mx);sm+=sc[vi];}\n                        double r2=uniform_real_distribution<double>(0,sm)(rng);\n                        int ci=0;double ac=0;\n                        for(int vi=0;vi<vsz;vi++){ac+=sc[vi];if(ac>=r2){ci=vi;break;}}\n                        int np=vl_all[k][ci];\n                        ch[k]=np;\n                        for(int i=0;i<N;i++){rsum[i]+=row_ct[k][np][i];csum[i]+=col_ct[k][np][i];}\n                        for(int idx:pflat[k][np])grid[idx]++;\n                        compute_all_ll();\n                        if(tll>best_ll){best_ll=tll;best_ch=ch;}\n                    }\n                }else{\n                    mcmc_step(false);\n                }\n                sample:\n                if(it>warmup){\n                    for(int kk=0;kk<M;kk++)\n                        for(int idx:pflat[kk][ch[kk]])\n                            occ[idx]+=1;\n                    samp++;\n                }\n            }\n        }\n    };\n    \n    vector<double>occ(NN,0);int samp=0;\n    run_mcmc(1.2,occ,samp);\n    \n    auto try_guess=[&]()->bool{\n        if(ops>=maxops||samp==0)return false;\n        vector<int>ans;\n        double thr=0.5;\n        for(int i=0;i<NN;i++)\n            if(occ[i]/samp>thr||is_oil[i])ans.push_back(i);\n        return guess(ans);\n    };\n    if(try_guess())return 0;\n    \n    // Drill uncertain + re-MCMC loop\n    for(int phase=0;phase<5&&ops<maxops-2&&elapsed()<2.6;phase++){\n        vector<pair<double,int>>td;\n        for(int i=0;i<NN;i++){\n            if(known[i]>=0)continue;\n            double p=samp?occ[i]/samp:0.5;\n            td.push_back({fabs(p-0.5),i});\n        }\n        sort(td.begin(),td.end());\n        int bud=min((int)td.size(),max(5,(maxops-ops-2)/(7-phase)));\n        for(int d=0;d<bud&&ops<maxops-2;d++)drill(td[d].second);\n        \n        upd_valid();\n        for(int k=0;k<M;k++){\n            bool ok=false;for(int p:vl_all[k])if(p==ch[k]){ok=true;break;}\n            if(!ok)ch[k]=vl_all[k][rng()%vl_all[k].size()];\n        }\n        full_init();compute_all_ll();\n        best_ll=tll;best_ch=ch;\n        \n        fill(occ.begin(),occ.end(),0);samp=0;\n        run_mcmc(min(elapsed()+0.3,2.8),occ,samp);\n        if(try_guess())return 0;\n    }\n    \n    // Fallback\n    for(int i=0;i<NN;i++){\n        if(known[i]>=0)continue;\n        if(ops>=maxops-1)break;\n        drill(i);\n    }\n    vector<int>ans;\n    for(int i=0;i<NN;i++)if(is_oil[i])ans.push_back(i);\n    if(ops<maxops)guess(ans);\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint W, D, N;\nint a[55][55];\nstruct Rect { int r0,c0,r1,c1; int area() const { return (r1-r0)*(c1-c0); } };\n\n// Given areas and order, pack into strips within [r0, W) x [0, W)\n// Returns total area penalty\nvoid stripPack(int* areas, int* order, Rect* result, int startRow = 0) {\n    // order[0..N-1] gives the indices sorted by area descending\n    // We'll pack them into horizontal strips\n    \n    // Strategy: dynamic programming or greedy\n    // Greedy: for each group of consecutive reservations, find optimal strip height\n    \n    int curRow = startRow;\n    int idx = 0;\n    \n    while(idx < N && curRow < W) {\n        int remaining = N - idx;\n        int rowsLeft = W - curRow;\n        \n        // Try different numbers of items in this strip\n        int bestItems = 1;\n        ll bestPenalty = LLONG_MAX;\n        int bestHeight = 1;\n        \n        for(int cnt = 1; cnt <= remaining; cnt++) {\n            // Need to fit cnt items in a strip of some height h\n            // Each item i gets width w_i = ceil(areas[order[idx+i]] / h)\n            // Sum of w_i <= W\n            // Also need enough rows left for remaining items after this strip\n            \n            int minRowsForRest = (remaining - cnt > 0) ? 1 : 0; // at least 1 row per remaining strip\n            int maxH = rowsLeft - minRowsForRest;\n            if(maxH < 1) break;\n            \n            // Binary search for minimum h such that items fit in width W\n            int lo = 1, hi = maxH;\n            // Check if items fit at height h\n            auto fits = [&](int h) -> bool {\n                int totalW = 0;\n                for(int i = 0; i < cnt; i++) {\n                    int ai = areas[order[idx+i]];\n                    int wi = (ai + h - 1) / h; // ceil(ai/h)\n                    wi = max(wi, 1);\n                    totalW += wi;\n                    if(totalW > W) return false;\n                }\n                return true;\n            };\n            \n            // Find minimum h that fits\n            int minH = maxH + 1;\n            if(fits(1)) minH = 1;\n            else if(!fits(maxH)) {\n                // Can't fit even at max height, skip this cnt\n                // Actually at large h, widths are small, so should fit\n                // Unless cnt > W\n                if(cnt > W) break;\n                lo = 1; hi = maxH;\n                while(lo < hi) {\n                    int mid = (lo+hi)/2;\n                    if(fits(mid)) hi = mid; else lo = mid+1;\n                }\n                minH = lo;\n                if(minH > maxH) break;\n            }\n            \n            // At minH, all items fit. Use height = minH to minimize wasted space\n            // But also try maxH for zero penalty\n            // Actually, try to use maxH that minimizes total cost\n            \n            // Compute penalty for a given height\n            auto calcPenalty = [&](int h) -> ll {\n                ll pen = 0;\n                int totalW = 0;\n                for(int i = 0; i < cnt; i++) {\n                    int ai = areas[order[idx+i]];\n                    int wi = max(1, (ai + h - 1) / h);\n                    totalW += wi;\n                }\n                if(totalW > W) return LLONG_MAX;\n                // Distribute leftover width proportionally\n                int leftover = W - totalW;\n                // For now, just give each item its minimum width\n                // Penalty: max(0, ai - wi*h) * 100\n                for(int i = 0; i < cnt; i++) {\n                    int ai = areas[order[idx+i]];\n                    int wi = max(1, (ai + h - 1) / h);\n                    int area = wi * h;\n                    if(ai > area) pen += 100LL * (ai - area);\n                }\n                return pen;\n            };\n            \n            // Try h = minH ... min(minH+some, maxH)\n            // Best h is likely around minH or slightly above\n            for(int h = max(1, minH); h <= maxH; h++) {\n                if(!fits(h)) continue;\n                ll pen = calcPenalty(h);\n                if(pen < bestPenalty || (pen == bestPenalty && cnt > bestItems)) {\n                    bestPenalty = pen;\n                    bestItems = cnt;\n                    bestHeight = h;\n                }\n                if(pen == 0) break; // can't do better\n            }\n            if(bestPenalty == 0 && cnt >= remaining) break;\n        }\n        \n        // Place bestItems items in strip [curRow, curRow+bestHeight) x [0, W)\n        int h = bestHeight;\n        // Compute widths\n        vector<int> widths(bestItems);\n        int totalW = 0;\n        for(int i = 0; i < bestItems; i++) {\n            int ai = areas[order[idx+i]];\n            widths[i] = max(1, (ai + h - 1) / h);\n            totalW += widths[i];\n        }\n        // Distribute leftover\n        int leftover = W - totalW;\n        // Give leftover to items that need it most (largest area first, which they already are)\n        for(int i = 0; i < bestItems && leftover > 0; i++) {\n            int give = leftover / (bestItems - i);\n            widths[i] += give;\n            leftover -= give;\n        }\n        \n        int curCol = 0;\n        for(int i = 0; i < bestItems; i++) {\n            int k = order[idx+i];\n            result[k] = {curRow, curCol, curRow + h, curCol + widths[i]};\n            curCol += widths[i];\n        }\n        \n        curRow += h;\n        idx += bestItems;\n    }\n    \n    // If we ran out of rows, assign remaining to last row (1 pixel high)\n    if(idx < N) {\n        int w = max(1, W / (N - idx));\n        int col = 0;\n        for(int i = idx; i < N; i++) {\n            int k = order[i];\n            int c1 = (i == N-1) ? W : min(W, col + w);\n            result[k] = {W-1, col, W, c1};\n            col = c1;\n        }\n    }\n}\n\nll computeChangeCost(Rect* prev, Rect* cur) {\n    ll cost = 0;\n    static vector<vector<pair<int,int>>> hp, hc, vp, vc;\n    hp.assign(W+1, {}); hc.assign(W+1, {});\n    vp.assign(W+1, {}); vc.assign(W+1, {});\n    \n    for(int k=0;k<N;k++){\n        auto& r = prev[k];\n        if(r.r0>0) hp[r.r0].push_back({r.c0, r.c1});\n        if(r.r1<W) hp[r.r1].push_back({r.c0, r.c1});\n        if(r.c0>0) vp[r.c0].push_back({r.r0, r.r1});\n        if(r.c1<W) vp[r.c1].push_back({r.r0, r.r1});\n    }\n    for(int k=0;k<N;k++){\n        auto& r = cur[k];\n        if(r.r0>0) hc[r.r0].push_back({r.c0, r.c1});\n        if(r.r1<W) hc[r.r1].push_back({r.c0, r.c1});\n        if(r.c0>0) vc[r.c0].push_back({r.r0, r.r1});\n        if(r.c1<W) vc[r.c1].push_back({r.r0, r.r1});\n    }\n    \n    auto merge = [](vector<pair<int,int>>& iv) {\n        if(iv.empty()) return;\n        sort(iv.begin(), iv.end());\n        int n=0;\n        for(auto& p : iv){\n            if(n>0 && iv[n-1].second >= p.first) iv[n-1].second = max(iv[n-1].second, p.second);\n            else iv[n++] = p;\n        }\n        iv.resize(n);\n    };\n    \n    auto symmDiff = [&](vector<pair<int,int>>& A, vector<pair<int,int>>& B) -> int {\n        merge(A); merge(B);\n        int la=0, lb=0, inter=0;\n        for(auto& p : A) la += p.second-p.first;\n        for(auto& p : B) lb += p.second-p.first;\n        int i=0,j=0;\n        while(i<(int)A.size() && j<(int)B.size()){\n            int lo = max(A[i].first, B[j].first);\n            int hi = min(A[i].second, B[j].second);\n            if(lo<hi) inter += hi-lo;\n            if(A[i].second < B[j].second) i++; else j++;\n        }\n        return la+lb-2*inter;\n    };\n    \n    for(int i=1;i<W;i++) { cost += symmDiff(hp[i], hc[i]); hp[i].clear(); hc[i].clear(); }\n    for(int j=1;j<W;j++) { cost += symmDiff(vp[j], vc[j]); vp[j].clear(); vc[j].clear(); }\n    return cost;\n}\n\nll areaCost(int d, Rect* rects) {\n    ll cost = 0;\n    for(int k=0;k<N;k++){\n        int area = rects[k].area();\n        if(a[d][k] > area) cost += 100LL * (a[d][k] - area);\n    }\n    return cost;\n}\n\nmt19937 rng(42);\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> W >> D >> N;\n    for(int d=0;d<D;d++) for(int k=0;k<N;k++) cin>>a[d][k];\n    \n    auto startTime = chrono::steady_clock::now();\n    \n    // Method 1: Recursive bisection (original)\n    // Method 2: Strip packing\n    // Method 3: Fixed layout with optimal assignment\n    \n    Rect bestOutput[55][55];\n    ll bestCost = LLONG_MAX;\n    \n    // Try strip packing with different orderings\n    auto tryLayout = [&](function<void(int,Rect*)> layoutFn) {\n        Rect rects[55][55];\n        for(int d=0;d<D;d++) layoutFn(d, rects[d]);\n        ll cost = 0;\n        for(int d=0;d<D;d++){\n            cost += areaCost(d, rects[d]);\n            if(d>0) cost += computeChangeCost(rects[d-1], rects[d]);\n        }\n        if(cost < bestCost){\n            bestCost = cost;\n            memcpy(bestOutput, rects, sizeof(rects));\n        }\n    };\n    \n    // Strip pack: sort by area descending\n    tryLayout([&](int d, Rect* result) {\n        int order[55];\n        vector<pair<int,int>> sorted(N);\n        for(int k=0;k<N;k++) sorted[k] = {-a[d][k], k};\n        sort(sorted.begin(), sorted.end());\n        for(int i=0;i<N;i++) order[i] = sorted[i].second;\n        stripPack(a[d], order, result);\n    });\n    \n    // Also try bisection approach\n    {\n        struct CNode { int l=-1,r=-1; bool hs; int leaf=-1; vector<int> lvs; };\n        vector<CNode> cn;\n        function<int(vector<int>&,int)> build = [&](vector<int>& ids, int dep) -> int {\n            int idx = cn.size(); cn.push_back({});\n            if((int)ids.size()==1){ cn[idx].leaf=ids[0]; cn[idx].lvs={ids[0]}; return idx; }\n            cn[idx].hs = (dep%2==0);\n            int m=ids.size()/2;\n            vector<int> L(ids.begin(),ids.begin()+m), R(ids.begin()+m,ids.end());\n            cn[idx].l = build(L,dep+1); cn[idx].r = build(R,dep+1);\n            cn[idx].lvs = cn[cn[idx].l].lvs;\n            for(int v:cn[cn[idx].r].lvs) cn[idx].lvs.push_back(v);\n            return idx;\n        };\n        vector<int> ids(N); iota(ids.begin(),ids.end(),0);\n        build(ids,0);\n        \n        function<void(int,int,int,int,int,int*,Rect*)> lay = [&](int ni, int r0, int c0, int r1, int c1, int* areas, Rect* res){\n            auto& nd = cn[ni];\n            if(nd.leaf>=0){ res[nd.leaf]={r0,c0,r1,c1}; return; }\n            ll ls=0,rs=0;\n            for(int v:cn[nd.l].lvs) ls+=areas[v];\n            for(int v:cn[nd.r].lvs) rs+=areas[v];\n            ll t=ls+rs; if(!t)t=1;\n            if(nd.hs){ int h=r1-r0,s=r0+max(1,min(h-1,(int)((ls*h+t/2)/t))); lay(nd.l,r0,c0,s,c1,areas,res); lay(nd.r,s,c0,r1,c1,areas,res); }\n            else { int w=c1-c0,s=c0+max(1,min(w-1,(int)((ls*w+t/2)/t))); lay(nd.l,r0,c0,r1,s,areas,res); lay(nd.r,r0,s,r1,c1,areas,res); }\n        };\n        \n        // Try different blend factors\n        for(double alpha = 0.0; alpha <= 1.001; alpha += 0.05) {\n            double elapsed = chrono::duration<double>(chrono::steady_clock::now()-startTime).count();\n            if(elapsed > 2.0) break;\n            \n            double avg[55]={};\n            for(int k=0;k<N;k++){ for(int d=0;d<D;d++) avg[k]+=a[d][k]; avg[k]/=D; }\n            \n            Rect rects[55][55];\n            for(int d=0;d<D;d++){\n                int blended[55];\n                for(int k=0;k<N;k++) blended[k] = max(1,(int)round((1-alpha)*a[d][k]+alpha*avg[k]));\n                lay(0,0,0,W,W,blended,rects[d]);\n            }\n            // Greedy assignment\n            for(int d=0;d<D;d++){\n                vector<pair<int,int>> sa(N), sr(N);\n                for(int i=0;i<N;i++) sa[i]={rects[d][i].area(),i};\n                for(int i=0;i<N;i++) sr[i]={a[d][i],i};\n                sort(sa.begin(),sa.end()); sort(sr.begin(),sr.end());\n                Rect tmp[55];\n                for(int i=0;i<N;i++) tmp[sr[i].second] = rects[d][sa[i].second];\n                memcpy(rects[d],tmp,sizeof(tmp));\n            }\n            ll cost=0;\n            for(int d=0;d<D;d++){\n                cost += areaCost(d,rects[d]);\n                if(d>0) cost += computeChangeCost(rects[d-1],rects[d]);\n            }\n            if(cost < bestCost){ bestCost=cost; memcpy(bestOutput,rects,sizeof(rects)); }\n        }\n    }\n    \n    for(int d=0;d<D;d++)\n        for(int k=0;k<N;k++){\n            auto& r = bestOutput[d][k];\n            cout << r.r0 << \" \" << r.c0 << \" \" << r.r1 << \" \" << r.c1 << \"\\n\";\n        }\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nconst long long MOD = 998244353;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M,K;\n    cin>>N>>M>>K;\n    \n    long long a[9][9];\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>a[i][j];\n    \n    long long s[20][3][3];\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    long long b[9][9];\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) b[i][j]=a[i][j];\n    vector<tuple<int,int,int>> ops;\n    \n    // Greedy init\n    for(int step=0;step<K;step++){\n        int bm=0,bp=0,bq=0; long long bd=LLONG_MIN;\n        for(int m=0;m<M;m++) for(int p=0;p<=6;p++) for(int q=0;q<=6;q++){\n            long long d=0;\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++)\n                d+=(b[p+i][q+j]+s[m][i][j])%MOD - b[p+i][q+j]%MOD;\n            if(d>bd){bd=d;bm=m;bp=p;bq=q;}\n        }\n        ops.push_back({bm,bp,bq});\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[bp+i][bq+j]+=s[bm][i][j];\n    }\n    \n    auto optSlot = [&](int idx) -> bool {\n        auto [om,op,oq]=ops[idx];\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[op+i][oq+j]-=s[om][i][j];\n        int bm=om,bp=op,bq=oq; long long bd=LLONG_MIN;\n        for(int m=0;m<M;m++) for(int p=0;p<=6;p++) for(int q=0;q<=6;q++){\n            long long d=0;\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++)\n                d+=(b[p+i][q+j]+s[m][i][j])%MOD - b[p+i][q+j]%MOD;\n            if(d>bd){bd=d;bm=m;bp=p;bq=q;}\n        }\n        bool changed=(bm!=om||bp!=op||bq!=oq);\n        ops[idx]={bm,bp,bq};\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[bp+i][bq+j]+=s[bm][i][j];\n        return changed;\n    };\n    \n    // Compute the \"value\" of a slot - how much score we lose removing it\n    auto slotValue = [&](int idx) -> long long {\n        auto [om,op,oq]=ops[idx];\n        long long val=0;\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++){\n            long long cur=b[op+i][oq+j]%MOD;\n            long long without=(b[op+i][oq+j]-s[om][i][j])%MOD;\n            // Note: without could be computed differently since values could be huge\n            // Actually we need (b - s) mod MOD\n            val += cur - ((b[op+i][oq+j]-s[om][i][j])%MOD + MOD)%MOD;\n        }\n        return val; // positive = slot is helpful\n    };\n    \n    auto calcScore=[&]()->long long{\n        long long sc=0;\n        for(int i=0;i<9;i++) for(int j=0;j<9;j++) sc+=b[i][j]%MOD;\n        return sc;\n    };\n    \n    auto startTime=chrono::steady_clock::now();\n    auto elapsed=[&]()->double{\n        return chrono::duration<double>(chrono::steady_clock::now()-startTime).count();\n    };\n    \n    // Initial local opt\n    for(int pass=0;pass<100;pass++){\n        bool any=false;\n        for(int idx=0;idx<K;idx++) if(optSlot(idx)) any=true;\n        if(!any) break;\n        if(elapsed()>0.2) break;\n    }\n    \n    long long bestScore=calcScore();\n    auto bestOps=ops;\n    long long bestB[9][9]; memcpy(bestB,b,sizeof(b));\n    \n    mt19937 rng(42);\n    int kickCount=0;\n    \n    while(elapsed()<1.85){\n        kickCount++;\n        // Always restart from best\n        ops=bestOps; memcpy(b,bestB,sizeof(b));\n        \n        // Vary kick size: alternate between small and large\n        int nkick;\n        if(kickCount%5==0) nkick=10+rng()%15; // large exploration kick\n        else if(kickCount%3==0) nkick=5+rng()%6;\n        else nkick=2+rng()%4; // small exploitation kick\n        \n        // For small kicks, prefer kicking low-value slots\n        vector<int> indices(K);\n        iota(indices.begin(),indices.end(),0);\n        \n        if(nkick<=5){\n            // Kick random slots\n            shuffle(indices.begin(),indices.end(),rng);\n        } else {\n            shuffle(indices.begin(),indices.end(),rng);\n        }\n        \n        for(int k=0;k<nkick;k++){\n            int idx=indices[k];\n            auto [om,op,oq]=ops[idx];\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[op+i][oq+j]-=s[om][i][j];\n            int nm=rng()%M,np=rng()%7,nq=rng()%7;\n            ops[idx]={nm,np,nq};\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[np+i][nq+j]+=s[nm][i][j];\n        }\n        \n        // Re-optimize - focus on kicked slots first, then full passes\n        for(int k=0;k<nkick;k++) optSlot(indices[k]);\n        \n        for(int pass=0;pass<30;pass++){\n            bool any=false;\n            for(int idx=0;idx<K;idx++) if(optSlot(idx)) any=true;\n            if(!any) break;\n            if(elapsed()>1.85) break;\n        }\n        \n        long long sc=calcScore();\n        if(sc>bestScore){\n            bestScore=sc; bestOps=ops; memcpy(bestB,b,sizeof(b));\n        }\n    }\n    \n    cout<<bestOps.size()<<\"\\n\";\n    for(auto&[m,p,q]:bestOps) cout<<m<<\" \"<<p<<\" \"<<q<<\"\\n\";\n}","ahc033":"#include<bits/stdc++.h>\nusing namespace std;\n\nconst int N=5;\nint A[N][N];\nint grid[N][N];\nint cr[N],cc[N],ch[N];\nbool calive[N];\nbool cbombed[N];\nint recv_idx[N];\nint next_disp[N];\nstring act[N];\nint turn_count=0;\n\nvoid do_receive(){\n    for(int i=0;i<N;i++){\n        if(recv_idx[i]>=N) continue;\n        if(grid[i][0]!=-1) continue;\n        bool blocked=false;\n        for(int c=0;c<N;c++){\n            if(calive[c]&&cr[c]==i&&cc[c]==0&&ch[c]!=-1){blocked=true;break;}\n        }\n        if(!blocked){\n            grid[i][0]=A[i][recv_idx[i]];\n            recv_idx[i]++;\n        }\n    }\n}\n\nvoid do_dispatch(){\n    for(int i=0;i<N;i++){\n        if(grid[i][N-1]!=-1){\n            grid[i][N-1]=-1;\n        }\n    }\n}\n\nvoid do_turn(string s){\n    do_receive();\n    for(int i=0;i<N;i++){\n        char c=s[i];\n        act[i]+=c;\n        if(!calive[i]) continue;\n        switch(c){\n            case 'P': ch[i]=grid[cr[i]][cc[i]]; grid[cr[i]][cc[i]]=-1; break;\n            case 'Q': grid[cr[i]][cc[i]]=ch[i]; ch[i]=-1; break;\n            case 'U': cr[i]--; break;\n            case 'D': cr[i]++; break;\n            case 'L': cc[i]--; break;\n            case 'R': cr[i]++; break; // BUG: should be cc[i]++\n            case 'B': calive[i]=false; cbombed[i]=true; break;\n            case '.': break;\n        }\n    }\n    do_dispatch();\n    turn_count++;\n}\n\n// Actually let me rewrite from scratch more carefully\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    int n; cin>>n;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cin>>A[i][j];\n    \n    memset(grid,-1,sizeof(grid));\n    memset(cbombed,0,sizeof(cbombed));\n    for(int i=0;i<N;i++){cr[i]=i;cc[i]=0;ch[i]=-1;calive[i]=true;}\n    for(int i=0;i<N;i++){recv_idx[i]=0;next_disp[i]=i*N;}\n    \n    // Precompute: where is each container in the input?\n    int cont_row[25], cont_idx[25]; // container c is at A[cont_row[c]][cont_idx[c]]\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        cont_row[A[i][j]]=i;\n        cont_idx[A[i][j]]=j;\n    }\n    \n    // Simulation functions\n    auto crane_at=[&](int r,int c)->int{\n        for(int k=0;k<N;k++) if(calive[k]&&cr[k]==r&&cc[k]==c) return k;\n        return -1;\n    };\n    \n    auto find_container=[&](int id)->pair<int,int>{\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(grid[i][j]==id)return{i,j};\n        // Check if held by crane\n        for(int k=0;k<N;k++) if(calive[k]&&ch[k]==id) return{-2,-2};\n        return{-1,-1};\n    };\n    \n    auto sim_turn=[&](string s){\n        // Validate and execute\n        do_receive();\n        for(int i=0;i<N;i++){\n            char c=s[i];\n            act[i]+=c;\n            if(!calive[i]) continue;\n            switch(c){\n                case 'P': ch[i]=grid[cr[i]][cc[i]]; grid[cr[i]][cc[i]]=-1; break;\n                case 'Q': grid[cr[i]][cc[i]]=ch[i]; ch[i]=-1; break;\n                case 'U': cr[i]--; break;\n                case 'D': cr[i]++; break;\n                case 'L': cc[i]--; break;\n                case 'R': cc[i]++; break;\n                case 'B': calive[i]=false; cbombed[i]=true; break;\n                case '.': break;\n            }\n        }\n        do_dispatch();\n        turn_count++;\n    };\n    \n    // Strategy: bomb small cranes, use large crane efficiently\n    // But try to optimize the delivery order\n    \n    // Bomb small cranes\n    {\n        string s(N,'.');\n        for(int i=1;i<N;i++) s[i]='B';\n        sim_turn(s);\n    }\n    \n    // BFS for crane 0 (large crane, can move over containers)\n    auto bfs=[&](int sr,int sc,int tr,int tc)->vector<char>{\n        if(sr==tr&&sc==tc) return {};\n        int dist[N][N]; memset(dist,-1,sizeof(dist));\n        int pdir[N][N];\n        dist[sr][sc]=0;\n        queue<pair<int,int>> q;\n        q.push({sr,sc});\n        int dr[]={-1,1,0,0};\n        int dc[]={0,0,-1,1};\n        char dm[]={'U','D','L','R'};\n        while(!q.empty()){\n            auto[r,c]=q.front();q.pop();\n            if(r==tr&&c==tc) break;\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||dist[nr][nc]!=-1) continue;\n                dist[nr][nc]=dist[r][c]+1;\n                pdir[nr][nc]=d;\n                q.push({nr,nc});\n            }\n        }\n        if(dist[tr][tc]==-1) return {'X'};\n        vector<char> path;\n        int r=tr,c=tc;\n        while(r!=sr||c!=sc){\n            int d=pdir[r][c];\n            path.push_back(dm[d]);\n            r-=dr[d];c-=dc[d];\n        }\n        reverse(path.begin(),path.end());\n        return path;\n    };\n    \n    auto move0=[&](char c){\n        string s(N,'.');\n        s[0]=c;\n        sim_turn(s);\n    };\n    \n    auto move0_to=[&](int tr,int tc){\n        auto path=bfs(cr[0],cc[0],tr,tc);\n        for(char c:path) move0(c);\n    };\n    \n    auto find_empty=[&](int pref_r,int pref_c,bool avoid_dispatch=true)->pair<int,int>{\n        int best_d=1000,br=-1,bc=-1;\n        for(int i=0;i<N;i++)for(int j=0;j<(avoid_dispatch?N-1:N);j++){\n            if(grid[i][j]!=-1) continue;\n            if(crane_at(i,j)!=-1) continue;\n            int d=abs(i-pref_r)+abs(j-pref_c);\n            if(d<best_d){best_d=d;br=i;bc=j;}\n        }\n        return{br,bc};\n    };\n    \n    // Main loop: deliver containers\n    // Better scheduling: compute cost for each deliverable container and pick cheapest\n    \n    int max_turns=9500;\n    int total_delivered=0;\n    \n    while(turn_count<max_turns && total_delivered<N*N){\n        // Find all containers on grid that are \"next needed\" at some dispatch gate\n        struct Candidate {\n            int id, r, c, target_row;\n            int cost;\n        };\n        vector<Candidate> cands;\n        \n        for(int row=0;row<N;row++){\n            int need=next_disp[row];\n            if(need>=row*N+N) continue;\n            auto [r,c]=find_container(need);\n            if(r<0) continue; // not on grid or held\n            int cost=abs(cr[0]-r)+abs(cc[0]-c) + abs(r-row)+(N-1-c);\n            cands.push_back({need,r,c,row,cost});\n        }\n        \n        if(!cands.empty()){\n            // Pick cheapest\n            sort(cands.begin(),cands.end(),[](auto&a,auto&b){return a.cost<b.cost;});\n            auto& best=cands[0];\n            \n            // Go pick up\n            move0_to(best.r,best.c);\n            if(cr[0]==best.r&&cc[0]==best.c&&grid[cr[0]][cc[0]]==best.id){\n                move0('P');\n                \n                int tr=best.target_row, tc=N-1;\n                move0_to(tr,tc);\n                \n                if(grid[cr[0]][cc[0]]==-1){\n                    move0('Q');\n                    next_disp[tr]++;\n                    total_delivered++;\n                } else {\n                    // Wait for dispatch\n                    move0('.');\n                    if(grid[cr[0]][cc[0]]==-1){\n                        move0('Q');\n                        next_disp[tr]++;\n                        total_delivered++;\n                    } else {\n                        // Drop in buffer near target\n                        auto [er,ec]=find_empty(tr,2);\n                        if(er>=0){\n                            move0_to(er,ec);\n                            move0('Q');\n                        } else {\n                            auto [er2,ec2]=find_empty(cr[0],cc[0],false);\n                            if(er2>=0){\n                                move0_to(er2,ec2);\n                                move0('Q');\n                                if(er2==tr&&ec2==N-1){next_disp[tr]++;total_delivered++;}\n                            }\n                        }\n                    }\n                }\n                continue;\n            }\n        }\n        \n        // No ready containers - move containers from receiving gates to buffer\n        bool did_something=false;\n        \n        // Find container on grid closest to crane to move to buffer\n        int best_d=1000,bi=-1,bj=-1;\n        for(int i=0;i<N;i++){\n            if(grid[i][0]!=-1){\n                int d=abs(cr[0]-i)+abs(cc[0]-0);\n                if(d<best_d){best_d=d;bi=i;bj=0;}\n            }\n        }\n        \n        if(bi>=0){\n            move0_to(bi,bj);\n            if(cr[0]==bi&&cc[0]==bj&&grid[bi][bj]!=-1){\n                int cid=grid[bi][bj];\n                move0('P');\n                // Place near target row\n                int trow=cid/N;\n                auto [er,ec]=find_empty(trow,2);\n                if(er>=0){\n                    move0_to(er,ec);\n                    move0('Q');\n                    if(er==trow&&ec==N-1){next_disp[trow]++;total_delivered++;}\n                    did_something=true;\n                } else {\n                    auto [er2,ec2]=find_empty(cr[0],cc[0],false);\n                    if(er2>=0){\n                        move0_to(er2,ec2);\n                        move0('Q');\n                        if(er2==cid/N&&ec2==N-1){next_disp[cid/N]++;total_delivered++;}\n                        did_something=true;\n                    }\n                }\n            }\n        }\n        \n        if(!did_something){\n            move0('.');\n        }\n    }\n    \n    int maxlen=0;\n    for(int i=0;i<N;i++) maxlen=max(maxlen,(int)act[i].size());\n    for(int i=0;i<N;i++) while((int)act[i].size()<maxlen) act[i]+=\".\";\n    for(int i=0;i<N;i++) cout<<act[i]<<\"\\n\";\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint orig_h[20][20];\nint h[20][20];\nint cx, cy, cur_load;\n\nint mdist(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); }\n\nstruct Solution {\n    vector<string> ops;\n    long long cost;\n};\n\nvoid do_move(vector<string>& ops, char c, int& px, int& py, int& load) {\n    ops.push_back(string(1,c));\n    if(c=='U') py--; else if(c=='D') py++;\n    else if(c=='L') px--; else if(c=='R') px++;\n}\n\nvoid interact(vector<string>& ops, int grid[20][20], int px, int py, int& load) {\n    if(grid[py][px] > 0) {\n        ops.push_back(\"+\"+to_string(grid[py][px]));\n        load += grid[py][px];\n        grid[py][px] = 0;\n    }\n    if(grid[py][px] < 0 && load > 0) {\n        int amt = min(load, -grid[py][px]);\n        ops.push_back(\"-\"+to_string(amt));\n        grid[py][px] += amt;\n        load -= amt;\n    }\n}\n\nvoid move_to_smart(vector<string>& ops, int grid[20][20], int& px, int& py, int& load, int tx, int ty) {\n    while(px != tx || py != ty) {\n        vector<pair<int,char>> dirs;\n        if(px < tx) dirs.push_back({0,'R'});\n        if(px > tx) dirs.push_back({0,'L'});\n        if(py < ty) dirs.push_back({0,'D'});\n        if(py > ty) dirs.push_back({0,'U'});\n        \n        for(auto& [score, c] : dirs) {\n            int nx=px, ny=py;\n            if(c=='R') nx++; else if(c=='L') nx--;\n            else if(c=='D') ny++; else if(c=='U') ny--;\n            if(grid[ny][nx] > 0) score -= 20;\n            if(grid[ny][nx] < 0 && load > 0) score -= min(load, -grid[ny][nx]);\n        }\n        sort(dirs.begin(), dirs.end());\n        do_move(ops, dirs[0].second, px, py, load);\n        interact(ops, grid, px, py, load);\n    }\n}\n\nlong long calc_cost(vector<string>& ops) {\n    long long cost = 0;\n    int load = 0;\n    for(auto& s : ops) {\n        if(s[0] == '+') { int d = stoi(s.substr(1)); cost += d; load += d; }\n        else if(s[0] == '-') { int d = stoi(s.substr(1)); cost += d; load -= d; }\n        else { cost += 100 + load; }\n    }\n    return cost;\n}\n\nSolution solve(int pickup_radius, int load_cap) {\n    int grid[20][20];\n    memcpy(grid, orig_h, sizeof(orig_h));\n    vector<string> ops;\n    int px=0, py=0, load=0;\n    interact(ops, grid, px, py, load);\n    \n    while(true) {\n        if(load == 0) {\n            int best_d=INT_MAX, bx=-1, by=-1;\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n                if(grid[i][j]>0){\n                    int d=mdist(px,py,j,i);\n                    if(d<best_d){best_d=d;bx=j;by=i;}\n                }\n            }\n            if(bx==-1) break;\n            move_to_smart(ops, grid, px, py, load, bx, by);\n            \n            bool found=true;\n            while(found && load < load_cap) {\n                found=false;\n                int bd=pickup_radius,bx2=-1,by2=-1;\n                for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n                    if(grid[i][j]>0){\n                        int d=mdist(px,py,j,i);\n                        if(d<bd){bd=d;bx2=j;by2=i;found=true;}\n                    }\n                }\n                if(found) move_to_smart(ops, grid, px, py, load, bx2, by2);\n            }\n        } else {\n            int bd=INT_MAX, dx=-1,dy=-1;\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n                if(grid[i][j]<0){\n                    int d=mdist(px,py,j,i);\n                    if(d<bd){bd=d;dx=j;dy=i;}\n                }\n            }\n            if(dx==-1) break;\n            move_to_smart(ops, grid, px, py, load, dx, dy);\n        }\n    }\n    \n    long long cost = calc_cost(ops);\n    // Check diff\n    long long diff = 0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++)\n        if(grid[i][j]!=0) diff += 100*abs(grid[i][j])+10000;\n    \n    return {ops, cost+diff};\n}\n\nint main(){\n    scanf(\"%d\", &N);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) scanf(\"%d\",&orig_h[i][j]);\n    \n    Solution best;\n    best.cost = LLONG_MAX;\n    \n    // Try different parameter combinations\n    for(int radius : {3, 4, 5, 6, 8, 10, 20}) {\n        for(int cap : {50, 100, 150, 200, 300, 500, 1000}) {\n            auto sol = solve(radius, cap);\n            if(sol.cost < best.cost) best = sol;\n        }\n    }\n    \n    for(auto& s : best.ops) printf(\"%s\\n\", s.c_str());\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <cstring>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,T;\n    cin>>N>>M>>T;\n    int SC=2*N*(N-1);\n    vector<vector<int>>X(SC,vector<int>(M));\n    for(int i=0;i<SC;i++) for(int j=0;j<M;j++) cin>>X[i][j];\n    mt19937 rng(42);\n    \n    for(int t=0;t<T;t++){\n        auto t0=chrono::steady_clock::now();\n        double tlimit=0.17;\n        \n        vector<int> maxV(M,0);\n        for(int i=0;i<SC;i++) for(int l=0;l<M;l++) maxV[l]=max(maxV[l],X[i][l]);\n        \n        // Compute pairwise edge value for all seed pairs: sum_l max(x[a][l], x[b][l])\n        // Pick best pair as \"core edge\", then build grid around it\n        \n        // Score seeds by total value\n        vector<int> vals(SC,0);\n        for(int i=0;i<SC;i++) for(int l=0;l<M;l++) vals[i]+=X[i][l];\n        \n        // Select seeds: must include seeds with criterion maxima\n        vector<bool> mustInclude(SC,false);\n        for(int l=0;l<M;l++){\n            int best=-1;\n            for(int i=0;i<SC;i++) if(X[i][l]==maxV[l]){\n                if(best<0||vals[i]>vals[best]) best=i;\n            }\n            mustInclude[best]=true;\n        }\n        \n        vector<int> sel;\n        for(int i=0;i<SC;i++) if(mustInclude[i]) sel.push_back(i);\n        \n        vector<int> idx(SC); iota(idx.begin(),idx.end(),0);\n        sort(idx.begin(),idx.end(),[&](int a,int b){return vals[a]>vals[b];});\n        for(int i:idx){\n            if((int)sel.size()>=N*N) break;\n            if(!mustInclude[i]) sel.push_back(i);\n        }\n        sel.resize(N*N);\n        \n        // Precompute edge values between selected seeds\n        int NN=N*N;\n        vector<vector<int>> ev(NN,vector<int>(NN,0));\n        for(int a=0;a<NN;a++) for(int b=a+1;b<NN;b++){\n            int s=0;\n            for(int l=0;l<M;l++) s+=max(X[sel[a]][l],X[sel[b]][l]);\n            ev[a][b]=ev[b][a]=s;\n        }\n        \n        // Grid edges\n        vector<pair<int,int>> edges;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            int p=i*N+j;\n            if(j+1<N) edges.push_back({p,i*N+j+1});\n            if(i+1<N) edges.push_back({p,(i+1)*N+j});\n        }\n        \n        vector<int> perm(NN); iota(perm.begin(),perm.end(),0);\n        \n        // Objective: maximize max edge value + alpha * sum edge values\n        auto compScore=[&](vector<int>&p)->pair<int,long long>{\n            int mx=0; long long sm=0;\n            for(auto&[a,b]:edges){int v=ev[p[a]][p[b]]; mx=max(mx,v); sm+=v;}\n            return {mx,sm};\n        };\n        auto [cmx,csm]=compScore(perm);\n        \n        int iter=0;\n        while(true){\n            if((++iter&2047)==0){if(chrono::duration<double>(chrono::steady_clock::now()-t0).count()>tlimit) break;}\n            int a=rng()%NN,b=rng()%NN; if(a==b) continue;\n            swap(perm[a],perm[b]);\n            auto [nmx,nsm]=compScore(perm);\n            double temp=30.0*max(0.0,1.0-chrono::duration<double>(chrono::steady_clock::now()-t0).count()/tlimit)+0.01;\n            double oldS=cmx*100.0+csm*0.1;\n            double newS=nmx*100.0+nsm*0.1;\n            if(newS>=oldS||(uniform_real_distribution<>()(rng)<exp((newS-oldS)/temp))){cmx=nmx;csm=nsm;}\n            else swap(perm[a],perm[b]);\n        }\n        for(int i=0;i<N;i++){for(int j=0;j<N;j++){if(j) cout<<' ';cout<<sel[perm[i*N+j]];}cout<<'\\n';}\n        cout.flush();\n        for(int i=0;i<SC;i++) for(int j=0;j<M;j++) cin>>X[i][j];\n    }\n}","ahc038":"#include<bits/stdc++.h>\nusing namespace std;\n\nvector<int> hungarian(const vector<vector<int>>& cost){\n    int n=cost.size(),m=cost[0].size();\n    vector<int>u(n+1),v(m+1),p(m+1),way(m+1);\n    for(int i=1;i<=n;i++){\n        p[0]=i;int j0=0;\n        vector<int>minv(m+1,INT_MAX);\n        vector<bool>used(m+1,false);\n        do{\n            used[j0]=true;int i0=p[j0],delta=INT_MAX,j1=-1;\n            for(int j=1;j<=m;j++)if(!used[j]){\n                int cur=cost[i0-1][j-1]-u[i0]-v[j];\n                if(cur<minv[j]){minv[j]=cur;way[j]=j0;}\n                if(minv[j]<delta){delta=minv[j];j1=j;}\n            }\n            for(int j=0;j<=m;j++)if(used[j]){u[p[j]]+=delta;v[j]-=delta;}else minv[j]-=delta;\n            j0=j1;\n        }while(p[j0]!=0);\n        do{int j1=way[j0];p[j0]=p[j1];j0=j1;}while(j0);\n    }\n    vector<int>ans(n);\n    for(int j=1;j<=m;j++)if(p[j])ans[p[j]-1]=j-1;\n    return ans;\n}\n\nint N,M,V;\nint dx[]={0,1,0,-1},dy[]={1,0,-1,0};\n\nint main(){\n    auto startTime=chrono::steady_clock::now();\n    auto ms=[&]()->int{return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-startTime).count();};\n    \n    scanf(\"%d%d%d\",&N,&M,&V);\n    vector<string>s(N),t(N);\n    for(int i=0;i<N;i++)cin>>s[i];\n    for(int i=0;i<N;i++)cin>>t[i];\n    \n    // Track grid state\n    vector<vector<int>>grid(N,vector<int>(N,0));\n    vector<vector<int>>target(N,vector<int>(N,0));\n    \n    vector<pair<int,int>>src,tgt;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(s[i][j]=='1') grid[i][j]=1;\n        if(t[i][j]=='1') target[i][j]=1;\n        if(s[i][j]=='1'&&t[i][j]=='0')src.push_back({i,j});\n        if(s[i][j]=='0'&&t[i][j]=='1')tgt.push_back({i,j});\n    }\n    int K=src.size();\n    \n    vector<int>ma;\n    if(K>0){\n        vector<vector<int>>cost(K,vector<int>(K));\n        for(int i=0;i<K;i++)for(int j=0;j<K;j++)\n            cost[i][j]=abs(src[i].first-tgt[j].first)+abs(src[i].second-tgt[j].second);\n        ma=hungarian(cost);\n    }\n    \n    struct Job{int sx,sy,tx,ty;};\n    vector<Job>jobs(K);\n    for(int i=0;i<K;i++) jobs[i]={src[i].first,src[i].second,tgt[ma[i]].first,tgt[ma[i]].second};\n    \n    int F=min(V-1, max(1,min(K,14)));\n    int VP=F+1; // total vertices\n    \n    // Output tree\n    printf(\"%d\\n\",VP);\n    for(int i=0;i<F;i++) printf(\"0 1\\n\");\n    printf(\"0 0\\n\"); // initial position\n    \n    int rx=0,ry=0;\n    vector<int>fdir(F,0); // all start right\n    vector<int>holding(F,-1);\n    \n    vector<string>ops;\n    \n    // String format: length 2*VP\n    // [0]=move, [1..F]=rotations of vertices 1..F, [VP+0]=root action, [VP+1..VP+F]=leaf actions\n    auto emitTurn=[&](char mv, vector<char>&rots, vector<bool>&picks){\n        string o(2*VP,'.');\n        o[0]=mv;\n        for(int i=0;i<F;i++) o[1+i]=rots[i];\n        // o[VP]='.'; // root not a leaf (has children)\n        for(int i=0;i<F;i++) if(picks[i]) o[VP+1+i]='P';\n        ops.push_back(o);\n    };\n    \n    auto doNothing=[&](){\n        vector<char>rots(F,'.');vector<bool>picks(F,false);\n        emitTurn('.',rots,picks);\n    };\n    \n    // Navigate to (gx,gy) while optionally rotating fingertip fi to direction td\n    auto navigateAndRotate=[&](int gx, int gy, int fi, int td){\n        while(rx!=gx||ry!=gy||(fi>=0&&fdir[fi]!=td)){\n            char mv='.';\n            vector<char>rots(F,'.');\n            vector<bool>picks(F,false);\n            \n            if(fi>=0&&fdir[fi]!=td){\n                int r=(td-fdir[fi]+4)%4;\n                if(r<=2){rots[fi]='R';fdir[fi]=(fdir[fi]+1)%4;}\n                else{rots[fi]='L';fdir[fi]=(fdir[fi]+3)%4;}\n            }\n            \n            if(rx<gx){mv='D';rx++;}\n            else if(rx>gx){mv='U';rx--;}\n            else if(ry<gy){mv='R';ry++;}\n            else if(ry>gy){mv='L';ry--;}\n            \n            emitTurn(mv,rots,picks);\n        }\n    };\n    \n    auto pickOrDrop=[&](int fi){\n        vector<char>rots(F,'.');vector<bool>picks(F,false);\n        picks[fi]=true;\n        emitTurn('.',rots,picks);\n    };\n    \n    auto bestDir=[&](int px, int py)->int{\n        int best=0,bd=1e9;\n        for(int d=0;d<4;d++){\n            int nx=px-dx[d],ny=py-dy[d];\n            if(nx>=0&&nx<N&&ny>=0&&ny<N){\n                int cost=abs(nx-rx)+abs(ny-ry);\n                if(cost<bd){bd=cost;best=d;}\n            }\n        }\n        return best;\n    };\n    \n    // Greedy NN ordering\n    vector<int>order;\n    {\n        vector<bool>done2(K,false);\n        int cx2=0,cy2=0;\n        for(int i=0;i<K;i++){\n            int best=-1,bd=1e9;\n            for(int j=0;j<K;j++)if(!done2[j]){\n                int d=abs(jobs[j].sx-cx2)+abs(jobs[j].sy-cy2);\n                if(d<bd){bd=d;best=j;}\n            }\n            done2[best]=true;\n            order.push_back(best);\n            cx2=jobs[best].tx;cy2=jobs[best].ty;\n        }\n    }\n    \n    // Or-opt improvement\n    while(ms()<2000){\n        bool imp=false;\n        for(int i=0;i<K&&ms()<2000;i++){\n            int pTx=i>0?jobs[order[i-1]].tx:0, pTy=i>0?jobs[order[i-1]].ty:0;\n            int nSx=i+1<K?jobs[order[i+1]].sx:0, nSy=i+1<K?jobs[order[i+1]].sy:0;\n            int ji=order[i];\n            int oldCostRem=abs(pTx-jobs[ji].sx)+abs(pTy-jobs[ji].sy)\n                          +(i+1<K?abs(jobs[ji].tx-nSx)+abs(jobs[ji].ty-nSy):0);\n            int newBridge=(i+1<K?abs(pTx-nSx)+abs(pTy-nSy):0);\n            int removeSave=oldCostRem-newBridge;\n            \n            int bestJ=-1,bestIns=1e9;\n            for(int j=0;j<=K;j++){\n                if(j==i||j==i+1) continue;\n                int rj=(j>i)?j-1:j;\n                auto getItem=[&](int pos)->int{return pos<i?order[pos]:order[pos+1];};\n                int pTx2=rj>0?jobs[getItem(rj-1)].tx:0, pTy2=rj>0?jobs[getItem(rj-1)].ty:0;\n                int nSx2=rj<K-1?jobs[getItem(rj)].sx:0, nSy2=rj<K-1?jobs[getItem(rj)].sy:0;\n                int ins=abs(pTx2-jobs[ji].sx)+abs(pTy2-jobs[ji].sy)\n                       +(rj<K-1?abs(jobs[ji].tx-nSx2)+abs(jobs[ji].ty-nSy2):0)\n                       -(rj<K-1?abs(pTx2-nSx2)+abs(pTy2-nSy2):0);\n                if(ins<bestIns){bestIns=ins;bestJ=j;}\n            }\n            if(bestIns-removeSave<0){\n                order.erase(order.begin()+i);\n                int insPos=(bestJ>i)?bestJ-1:bestJ;\n                order.insert(order.begin()+insPos,ji);\n                imp=true;\n            }\n        }\n        if(!imp) break;\n    }\n    \n    // Execute with F fingertips in batches\n    for(int b=0;b<K;b+=F){\n        int bEnd=min(b+F,K);\n        int bSize=bEnd-b;\n        \n        // Pickup phase: nearest neighbor order\n        vector<int>batchJobs;\n        for(int i=b;i<bEnd;i++) batchJobs.push_back(order[i]);\n        \n        vector<bool>picked(bSize,false);\n        vector<int>pickOrder;\n        vector<int>fiAssign(bSize); // which fingertip assigned to which batch item\n        \n        int tcx=rx,tcy=ry;\n        for(int p=0;p<bSize;p++){\n            int best=-1,bd=1e9;\n            for(int q=0;q<bSize;q++)if(!picked[q]){\n                int ji=batchJobs[q];\n                int d=abs(jobs[ji].sx-tcx)+abs(jobs[ji].sy-tcy);\n                if(d<bd){bd=d;best=q;}\n            }\n            picked[best]=true;\n            pickOrder.push_back(best);\n            fiAssign[best]=p; // fingertip p handles batch item best\n            tcx=jobs[batchJobs[best]].sx;\n            tcy=jobs[batchJobs[best]].sy;\n        }\n        \n        // Execute pickups\n        for(int p=0;p<bSize;p++){\n            int bidx=pickOrder[p];\n            int ji=batchJobs[bidx];\n            int fi=fiAssign[bidx];\n            int sx=jobs[ji].sx,sy=jobs[ji].sy;\n            int sd=bestDir(sx,sy);\n            int gx=sx-dx[sd],gy=sy-dy[sd];\n            navigateAndRotate(gx,gy,fi,sd);\n            pickOrDrop(fi);\n            holding[fi]=ji;\n        }\n        \n        // Dropoff phase: nearest neighbor order\n        vector<bool>dropped(bSize,false);\n        for(int p=0;p<bSize;p++){\n            int best=-1,bd=1e9;\n            for(int q=0;q<bSize;q++)if(!dropped[q]){\n                int ji=batchJobs[q];\n                int d=abs(jobs[ji].tx-rx)+abs(jobs[ji].ty-ry);\n                if(d<bd){bd=d;best=q;}\n            }\n            dropped[best]=true;\n            int ji=batchJobs[best];\n            int fi=fiAssign[best];\n            int tx=jobs[ji].tx,ty=jobs[ji].ty;\n            int td=bestDir(tx,ty);\n            int gx=tx-dx[td],gy=ty-dy[td];\n            navigateAndRotate(gx,gy,fi,td);\n            pickOrDrop(fi);\n            holding[fi]=-1;\n        }\n    }\n    \n    for(auto&o:ops) printf(\"%s\\n\",o.c_str());\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N; cin>>N;\n    vector<int> fx(2*N), fy(2*N);\n    for(int i=0;i<2*N;i++) cin>>fx[i]>>fy[i];\n    \n    const int MX = 100000;\n    const int G = 350;\n    double step = (double)MX / G;\n    \n    vector<vector<int>> val(G, vector<int>(G, 0));\n    for(int i=0;i<2*N;i++){\n        int gx = min((int)(fx[i]/step), G-1);\n        int gy = min((int)(fy[i]/step), G-1);\n        val[gx][gy] += (i < N) ? 1 : -1;\n    }\n    \n    int best = INT_MIN, bx1=0,bx2=G-1,by1=0,by2=G-1;\n    for(int lx=0;lx<G;lx++){\n        vector<int> colsum(G,0);\n        for(int rx=lx;rx<G;rx++){\n            for(int gy=0;gy<G;gy++) colsum[gy]+=val[rx][gy];\n            int cur=0, start=0;\n            for(int gy=0;gy<G;gy++){\n                cur+=colsum[gy];\n                if(cur>best){best=cur;bx1=lx;bx2=rx;by1=start;by2=gy;}\n                if(cur<0){cur=0;start=gy+1;}\n            }\n        }\n    }\n    \n    int rx1 = max(0, (int)(bx1*step) - 1);\n    int rx2 = min(MX, (int)((bx2+1)*step) + 1);\n    int ry1 = max(0, (int)(by1*step) - 1);\n    int ry2 = min(MX, (int)((by2+1)*step) + 1);\n    \n    // Fast boundary refinement using prefix sums\n    // Sort fish by x, then by y for efficient counting\n    // For each candidate x1, count mackerels and sardines with x >= x1, x <= rx2, y in [ry1,ry2]\n    {\n        // Collect fish in broad region\n        struct FishInfo { int x, y, w; };\n        vector<FishInfo> fish;\n        for(int i=0;i<2*N;i++){\n            fish.push_back({fx[i], fy[i], (i<N)?1:-1});\n        }\n        \n        // Try adjusting boundaries using fish coordinates\n        // For left boundary: sort by x, sweep\n        auto inRect = [&](int x1, int y1, int x2, int y2, int i) -> bool {\n            return fx[i]>=x1 && fx[i]<=x2 && fy[i]>=y1 && fy[i]<=y2;\n        };\n        \n        // Compute base score\n        int baseS = 0;\n        for(int i=0;i<2*N;i++)\n            if(inRect(rx1,ry1,rx2,ry2,i)) baseS += (i<N)?1:-1;\n        \n        // Try moving left boundary right: fish sorted by x\n        // Fish with x in [rx1, rx2] and y in [ry1, ry2], sorted by x\n        vector<pair<int,int>> leftFish; // (x, w)\n        for(int i=0;i<2*N;i++){\n            if(fx[i]>=rx1 && fx[i]<=rx2 && fy[i]>=ry1 && fy[i]<=ry2)\n                leftFish.push_back({fx[i], (i<N)?1:-1});\n        }\n        sort(leftFish.begin(), leftFish.end());\n        \n        int bestS = baseS;\n        int cumW = 0;\n        int prevX = rx1;\n        for(int j=0;j<(int)leftFish.size();j++){\n            // Try x1 = leftFish[j].first + 1 (exclude this fish)\n            // But only if this fish is a sardine\n            cumW += leftFish[j].second;\n            if(baseS - cumW > bestS){\n                bestS = baseS - cumW;\n                rx1 = leftFish[j].first + 1;\n            }\n        }\n        \n        // Recompute base\n        baseS = bestS;\n        \n        // Try moving right boundary left\n        vector<pair<int,int>> rightFish;\n        for(int i=0;i<2*N;i++){\n            if(fx[i]>=rx1 && fx[i]<=rx2 && fy[i]>=ry1 && fy[i]<=ry2)\n                rightFish.push_back({fx[i], (i<N)?1:-1});\n        }\n        sort(rightFish.begin(), rightFish.end());\n        \n        cumW = 0;\n        for(int j=(int)rightFish.size()-1;j>=0;j--){\n            cumW += rightFish[j].second;\n            if(baseS - cumW > bestS){\n                bestS = baseS - cumW;\n                rx2 = rightFish[j].first - 1;\n            }\n        }\n        baseS = bestS;\n        \n        // Try moving top boundary down\n        vector<pair<int,int>> topFish;\n        for(int i=0;i<2*N;i++){\n            if(fx[i]>=rx1 && fx[i]<=rx2 && fy[i]>=ry1 && fy[i]<=ry2)\n                topFish.push_back({fy[i], (i<N)?1:-1});\n        }\n        sort(topFish.begin(), topFish.end());\n        \n        cumW = 0;\n        for(int j=(int)topFish.size()-1;j>=0;j--){\n            cumW += topFish[j].second;\n            if(baseS - cumW > bestS){\n                bestS = baseS - cumW;\n                ry2 = topFish[j].first - 1;\n            }\n        }\n        baseS = bestS;\n        \n        // Try moving bottom boundary up\n        vector<pair<int,int>> botFish;\n        for(int i=0;i<2*N;i++){\n            if(fx[i]>=rx1 && fx[i]<=rx2 && fy[i]>=ry1 && fy[i]<=ry2)\n                botFish.push_back({fy[i], (i<N)?1:-1});\n        }\n        sort(botFish.begin(), botFish.end());\n        \n        cumW = 0;\n        for(int j=0;j<(int)botFish.size();j++){\n            cumW += botFish[j].second;\n            if(baseS - cumW > bestS){\n                bestS = baseS - cumW;\n                ry1 = botFish[j].first + 1;\n            }\n        }\n    }\n    \n    // Now try strip-based optimization\n    // Collect fish inside rectangle, sorted by y\n    struct Fish { int x, y, w; };\n    vector<Fish> inside;\n    for(int i=0;i<2*N;i++){\n        if(fx[i]>=rx1 && fx[i]<=rx2 && fy[i]>=ry1 && fy[i]<=ry2)\n            inside.push_back({fx[i], fy[i], (i<N)?1:-1});\n    }\n    sort(inside.begin(), inside.end(), [](const Fish&a, const Fish&b){ return a.y < b.y; });\n    \n    // Divide into ~120 strips (gives ~480 vertices + 4 base \u2248 484)\n    int nStrips = min(120, max(1, (int)inside.size()/10));\n    int fishPerStrip = max(1, (int)inside.size() / nStrips);\n    \n    struct Strip { int y1, y2, xl, xr; };\n    vector<Strip> strips;\n    \n    int fi = 0;\n    while(fi < (int)inside.size()){\n        int end = min(fi + fishPerStrip, (int)inside.size());\n        // Ensure we don't split fish with same y\n        while(end < (int)inside.size() && inside[end].y == inside[end-1].y) end++;\n        \n        int sy1 = (fi == 0) ? ry1 : (inside[fi-1].y + inside[fi].y) / 2 + 1;\n        int sy2 = (end >= (int)inside.size()) ? ry2 : (inside[end-1].y + inside[end].y) / 2;\n        \n        if(strips.empty()) sy1 = ry1;\n        \n        // Collect strip fish\n        vector<pair<int,int>> sf;\n        for(int j=fi;j<end;j++) sf.push_back({inside[j].x, inside[j].w});\n        sort(sf.begin(), sf.end());\n        \n        int totalW = 0;\n        for(auto&[x,w]:sf) totalW += w;\n        int bestW = totalW, bestXL = rx1, bestXR = rx2;\n        \n        // Try trim left\n        int cumW = 0;\n        for(int j=0;j<(int)sf.size();j++){\n            cumW += sf[j].second;\n            if(totalW - cumW > bestW){\n                bestW = totalW - cumW;\n                bestXL = sf[j].first + 1;\n                bestXR = rx2;\n            }\n        }\n        \n        // Try trim right\n        cumW = 0;\n        for(int j=(int)sf.size()-1;j>=0;j--){\n            cumW += sf[j].second;\n            if(totalW - cumW > bestW){\n                bestW = totalW - cumW;\n                bestXR = sf[j].first - 1;\n                bestXL = rx1;\n            }\n        }\n        \n        // Try trim both (Kadane's on x)\n        // Find max subarray\n        if(sf.size() > 0){\n            int maxSum = 0, curSum = 0;\n            int sBest = -1, sStart = 0, sEnd = -1;\n            for(int j=0;j<(int)sf.size();j++){\n                curSum += sf[j].second;\n                if(curSum > maxSum){\n                    maxSum = curSum;\n                    sBest = maxSum;\n                    sEnd = j;\n                    sBest = maxSum; // redundant but clear\n                }\n                if(curSum < 0){ curSum = 0; sStart = j+1; }\n            }\n            // Recompute to get sStart\n            curSum = 0; maxSum = 0; sStart = 0;\n            int finalStart = 0, finalEnd = 0;\n            for(int j=0;j<(int)sf.size();j++){\n                curSum += sf[j].second;\n                if(curSum > maxSum){\n                    maxSum = curSum;\n                    finalStart = sStart;\n                    finalEnd = j;\n                }\n                if(curSum < 0){ curSum = 0; sStart = j+1; }\n            }\n            if(maxSum > bestW){\n                bestW = maxSum;\n                bestXL = (finalStart > 0) ? sf[finalStart].first : rx1;\n                bestXR = (finalEnd < (int)sf.size()-1) ? sf[finalEnd].first : rx2;\n            }\n        }\n        \n        if(bestW >= totalW){\n            strips.push_back({sy1, sy2, bestXL, bestXR});\n        } else {\n            strips.push_back({sy1, sy2, rx1, rx2});\n        }\n        \n        fi = end;\n    }\n    \n    if(strips.empty()) strips.push_back({ry1, ry2, rx1, rx2});\n    strips.front().y1 = ry1;\n    strips.back().y2 = ry2;\n    \n    // Merge adjacent strips with same x-range\n    vector<Strip> merged;\n    for(auto&s:strips){\n        if(!merged.empty() && merged.back().xl==s.xl && merged.back().xr==s.xr){\n            merged.back().y2 = s.y2;\n        } else {\n            merged.push_back(s);\n        }\n    }\n    strips = merged;\n    \n    // Build polygon from strips (guaranteed non-self-intersecting)\n    // Each strip is [xl, xr] x [y1, y2]\n    // Ensure all xl <= xr, y1 <= y2\n    for(auto&s:strips){\n        s.xl = max(0, min(s.xl, rx2));\n        s.xr = max(s.xl, min(s.xr, MX));\n    }\n    \n    // Build right contour (top to bottom), then left contour (bottom to top)\n    vector<pair<int,int>> poly;\n    \n    // Top edge\n    poly.push_back({strips[0].xl, strips[0].y1});\n    poly.push_back({strips[0].xr, strips[0].y1});\n    \n    // Right side going down\n    for(int i=0;i<(int)strips.size();i++){\n        if(i > 0 && strips[i].xr != strips[i-1].xr){\n            poly.push_back({strips[i-1].xr, strips[i].y1});\n            poly.push_back({strips[i].xr, strips[i].y1});\n        }\n        poly.push_back({strips[i].xr, strips[i].y2});\n    }\n    \n    // Bottom-right to bottom-left\n    poly.push_back({strips.back().xl, strips.back().y2});\n    \n    // Left side going up\n    for(int i=(int)strips.size()-1;i>=0;i--){\n        if(i < (int)strips.size()-1 && strips[i].xl != strips[i+1].xl){\n            poly.push_back({strips[i+1].xl, strips[i].y2});\n            poly.push_back({strips[i].xl, strips[i].y2});\n        }\n        poly.push_back({strips[i].xl, strips[i].y1});\n    }\n    \n    // Remove consecutive duplicates\n    vector<pair<int,int>> cleaned;\n    for(auto&p:poly){\n        if(!cleaned.empty() && cleaned.back()==p) continue;\n        cleaned.push_back(p);\n    }\n    if(cleaned.size()>1 && cleaned.front()==cleaned.back()) cleaned.pop_back();\n    \n    // Remove collinear points\n    {\n        bool changed = true;\n        while(changed){\n            changed = false;\n            vector<pair<int,int>> res;\n            int n = cleaned.size();\n            for(int i=0;i<n;i++){\n                auto [px,py] = cleaned[(i+n-1)%n];\n                auto [cx,cy] = cleaned[i];\n                auto [nx,ny] = cleaned[(i+1)%n];\n                if((px==cx&&cx==nx)||(py==cy&&cy==ny)){\n                    changed = true;\n                } else {\n                    res.push_back(cleaned[i]);\n                }\n            }\n            cleaned = res;\n        }\n    }\n    \n    // Verify constraints\n    long long perim = 0;\n    int cn = cleaned.size();\n    bool valid = cn >= 4 && cn <= 1000;\n    for(int i=0;i<cn&&valid;i++){\n        int ni=(i+1)%cn;\n        int dx = abs(cleaned[i].first-cleaned[ni].first);\n        int dy = abs(cleaned[i].second-cleaned[ni].second);\n        if((dx>0)+(dy>0)!=1) valid=false;\n        perim += dx+dy;\n    }\n    if(perim>400000) valid=false;\n    \n    // Also output the simple rectangle as first solution\n    cout<<4<<\"\\n\";\n    cout<<rx1<<\" \"<<ry1<<\"\\n\";\n    cout<<rx2<<\" \"<<ry1<<\"\\n\";\n    cout<<rx2<<\" \"<<ry2<<\"\\n\";\n    cout<<rx1<<\" \"<<ry2<<\"\\n\";\n    \n    if(valid && cn>=4){\n        cout<<cn<<\"\\n\";\n        for(auto&[a,b]:cleaned) cout<<a<<\" \"<<b<<\"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include<bits/stdc++.h>\nusing namespace std;\nstruct Placement{int p,r;char d;int b;};\n\nlong long simEval(const vector<Placement>&ops,const vector<long long>&w,const vector<long long>&h){\n    int n=ops.size();\n    int idToIdx[101];\n    memset(idToIdx,-1,sizeof(idToIdx));\n    struct R{long long x1,y1,x2,y2;} rects[100];\n    long long mx=0,my=0;\n    for(int i=0;i<n;i++){\n        auto&op=ops[i];\n        long long wi=op.r?h[op.p]:w[op.p];\n        long long hi=op.r?w[op.p]:h[op.p];\n        if(op.d=='U'){\n            long long x1=(op.b==-1)?0:rects[idToIdx[op.b]].x2;\n            long long x2=x1+wi;\n            long long y1=0;\n            for(int j=0;j<i;j++)\n                if(rects[j].x1<x2&&rects[j].x2>x1)y1=max(y1,rects[j].y2);\n            rects[i]={x1,y1,x2,y1+hi};\n        }else{\n            long long y1=(op.b==-1)?0:rects[idToIdx[op.b]].y2;\n            long long y2=y1+hi;\n            long long x1=0;\n            for(int j=0;j<i;j++)\n                if(rects[j].y1<y2&&rects[j].y2>y1)x1=max(x1,rects[j].x2);\n            rects[i]={x1,y1,x1+wi,y2};\n        }\n        idToIdx[op.p]=i;\n        mx=max(mx,rects[i].x2);my=max(my,rects[i].y2);\n    }\n    return mx+my;\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    int N,T,sigma;\n    cin>>N>>T>>sigma;\n    vector<long long>w(N),h(N);\n    for(int i=0;i<N;i++)cin>>w[i]>>h[i];\n    \n    mt19937 rng(42);\n    auto t0=chrono::steady_clock::now();\n    auto elapsed=[&]()->double{return chrono::duration<double>(chrono::steady_clock::now()-t0).count();};\n    \n    auto genGreedy=[&](int maxRefs)->vector<Placement>{\n        vector<Placement>ops;\n        for(int i=0;i<N;i++){\n            long long best=LLONG_MAX;\n            Placement bestOp{i,0,'U',-1};\n            vector<int>refs;\n            refs.push_back(-1);\n            int st=max(0,(int)ops.size()-maxRefs);\n            for(int j=st;j<(int)ops.size();j++)refs.push_back(ops[j].p);\n            for(int r2=0;r2<2;r2++)\n                for(int dd=0;dd<2;dd++){\n                    char dir=dd?'U':'L';\n                    for(int b:refs){\n                        ops.push_back({i,r2,dir,b});\n                        long long sc=simEval(ops,w,h);\n                        if(sc<best){best=sc;bestOp={i,r2,dir,b};}\n                        ops.pop_back();\n                    }\n                }\n            ops.push_back(bestOp);\n        }\n        return ops;\n    };\n    \n    vector<Placement>bestOps=genGreedy(10);\n    long long bestScore=simEval(bestOps,w,h);\n    \n    if(elapsed()<0.3){\n        auto o2=genGreedy(20);\n        long long s2=simEval(o2,w,h);\n        if(s2<bestScore){bestScore=s2;bestOps=o2;}\n    }\n    \n    // Hill climbing: random single-rect change\n    auto hillClimb=[&](vector<Placement>&ops,double tEnd)->long long{\n        long long cur=simEval(ops,w,h);\n        while(elapsed()<tEnd){\n            int idx=rng()%N;\n            Placement old=ops[idx];\n            int r2=rng()%2;\n            char d2=(rng()%2)?'U':'L';\n            int b2=-1;\n            if(idx>0&&rng()%3!=0)b2=ops[rng()%idx].p;\n            ops[idx]={old.p,r2,d2,b2};\n            long long nsc=simEval(ops,w,h);\n            if(nsc<=cur)cur=nsc;\n            else ops[idx]=old;\n        }\n        return cur;\n    };\n    \n    double totalTime=2.7;\n    double perTurn=(totalTime-elapsed())/T;\n    \n    for(int t=0;t<T;t++){\n        double tEnd=min(elapsed()+perTurn,totalTime);\n        \n        // Every few turns, try a perturbed restart\n        if(t%5==0&&t>0){\n            auto ops=bestOps;\n            int np=3+rng()%5;\n            for(int k=0;k<np;k++){\n                int idx=rng()%N;\n                ops[idx].r=rng()%2;\n                ops[idx].d=(rng()%2)?'U':'L';\n                if(idx>0)ops[idx].b=(rng()%3==0)?-1:ops[rng()%idx].p;\n            }\n            long long sc=hillClimb(ops,tEnd);\n            if(sc<bestScore){bestScore=sc;bestOps=ops;}\n        } else {\n            auto ops=bestOps;\n            long long sc=hillClimb(ops,tEnd);\n            if(sc<bestScore){bestScore=sc;bestOps=ops;}\n        }\n        \n        cout<<(int)bestOps.size()<<\"\\n\";\n        for(auto&op:bestOps)\n            cout<<op.p<<\" \"<<op.r<<\" \"<<op.d<<\" \"<<op.b<<\"\\n\";\n        cout.flush();\n        long long W,H;\n        cin>>W>>H;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    \n    vector<int> A(N);\n    for(int i=0;i<N;i++) cin >> A[i];\n    \n    vector<vector<int>> adj(N);\n    for(int i=0;i<M;i++){\n        int u,v; cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    vector<int> x(N), y(N);\n    for(int i=0;i<N;i++) cin >> x[i] >> y[i];\n    \n    // State: parent[v], depth[v]\n    vector<int> par(N, -1), dep(N, 0);\n    vector<vector<int>> children(N);\n    \n    auto calc_score = [&]() -> long long {\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    \n    // Greedy: sort vertices by beauty descending, try to place them deep\n    // BFS tree building from low-beauty roots\n    \n    // Sort vertices by A ascending (low beauty = good root candidates)\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b){ return A[a] < A[b]; });\n    \n    vector<bool> used(N, false);\n    \n    for(int r : order){\n        if(used[r]) continue;\n        used[r] = true;\n        par[r] = -1; dep[r] = 0;\n        queue<int> q;\n        q.push(r);\n        while(!q.empty()){\n            int u = q.front(); q.pop();\n            if(dep[u] >= H) continue;\n            // Sort neighbors by A descending\n            vector<int> nbrs;\n            for(int v : adj[u]) if(!used[v]) nbrs.push_back(v);\n            sort(nbrs.begin(), nbrs.end(), [&](int a, int b){ return A[a] > A[b]; });\n            for(int v : nbrs){\n                if(used[v]) continue;\n                used[v] = true;\n                par[v] = u;\n                dep[v] = dep[u]+1;\n                children[u].push_back(v);\n                q.push(v);\n            }\n        }\n    }\n    \n    // Local search: try reparenting\n    auto get_subtree = [&](int v, auto& self) -> vector<int> {\n        vector<int> res = {v};\n        for(int c : children[v]){\n            auto sub = self(c, self);\n            res.insert(res.end(), sub.begin(), sub.end());\n        }\n        return res;\n    };\n    \n    auto update_depths = [&](int v, int d, auto& self) -> void {\n        dep[v] = d;\n        for(int c : children[v]) self(c, d+1, self);\n    };\n    \n    auto detach = [&](int v){\n        int p = par[v];\n        if(p == -1) return;\n        auto& ch = children[p];\n        ch.erase(find(ch.begin(), ch.end(), v));\n        par[v] = -1;\n        update_depths(v, 0, update_depths);\n    };\n    \n    auto max_depth_subtree = [&](int v, auto& self) -> int {\n        int mx = dep[v];\n        for(int c : children[v]) mx = max(mx, self(c, self));\n        return mx;\n    };\n    \n    auto subtree_score = [&](int v, auto& self) -> long long {\n        long long s = (long long)(dep[v]+1)*A[v];\n        for(int c : children[v]) s += self(c, self);\n        return s;\n    };\n    \n    // Build adjacency set for O(1) lookup\n    vector<set<int>> adjset(N);\n    for(int i=0;i<N;i++) for(int j : adj[i]) adjset[i].insert(j);\n    \n    long long best_score = calc_score();\n    vector<int> best_par = par;\n    \n    mt19937 rng(42);\n    \n    auto try_reparent = [&](int v, int new_par) -> long long {\n        // Check edge exists\n        if(!adjset[v].count(new_par)) return -1;\n        // Check new_par is not in subtree of v\n        int tmp = new_par;\n        while(tmp != -1){\n            if(tmp == v) return -1;\n            tmp = par[tmp];\n        }\n        // Check depth constraint\n        int subtree_depth = max_depth_subtree(v, max_depth_subtree) - dep[v];\n        int new_dep = dep[new_par] + 1;\n        if(new_dep + subtree_depth > H) return -1;\n        \n        long long old_sub = subtree_score(v, subtree_score);\n        // New score change\n        int depth_change = new_dep - dep[v];\n        // Calculate new subtree score\n        auto calc_delta = [&](int u, int dd, auto& self) -> long long {\n            long long d = (long long)dd * A[u];\n            for(int c : children[u]) d += self(c, dd, self);\n            return d;\n        };\n        long long delta = calc_delta(v, depth_change, calc_delta);\n        return delta;\n    };\n    \n    auto do_reparent = [&](int v, int new_par){\n        detach(v);\n        par[v] = new_par;\n        children[new_par].push_back(v);\n        int new_dep = dep[new_par] + 1;\n        int dd = new_dep - dep[v];\n        // Fix: dep[v] is already 0 after detach, recalculate\n        update_depths(v, new_dep, update_depths);\n    };\n    \n    // Simulated annealing\n    auto start_time = chrono::steady_clock::now();\n    double time_limit = 1.9;\n    long long cur_score = best_score;\n    \n    for(int iter = 0; ; iter++){\n        if(iter % 1000 == 0){\n            auto now = chrono::steady_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if(elapsed > time_limit) break;\n        }\n        \n        int v = rng() % N;\n        // Try reparenting v to a random neighbor\n        if(adj[v].empty()) continue;\n        int ni = rng() % adj[v].size();\n        int new_p = adj[v][ni];\n        \n        long long delta = try_reparent(v, new_p);\n        if(delta > 0 || (delta == 0 && (int)(rng()%2)==0)){\n            int old_par = par[v];\n            do_reparent(v, new_p);\n            cur_score = calc_score();\n            if(cur_score > best_score){\n                best_score = cur_score;\n                best_par = par;\n            }\n        }\n    }\n    \n    for(int i=0;i<N;i++){\n        cout << best_par[i];\n        if(i<N-1) cout << ' ';\n    }\n    cout << '\\n';\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N;\n    cin>>N;\n    vector<string> board(N);\n    for(int i=0;i<N;i++) cin>>board[i];\n    \n    vector<pair<int,int>> onis;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(board[i][j]=='x') onis.push_back({i,j});\n    int nOni = onis.size();\n    \n    // Direction: 0=U, 1=D, 2=L, 3=R\n    // Group key: (dir, line) encoded as dir*N + line\n    int MAXG = 4*N;\n    \n    // valid options per oni: list of (group_id, dist)\n    vector<vector<pair<int,int>>> oniOpts(nOni);\n    \n    for(int idx=0;idx<nOni;idx++){\n        int r=onis[idx].first, c=onis[idx].second;\n        bool canU=true;\n        for(int i=0;i<r;i++) if(board[i][c]=='o'){canU=false;break;}\n        if(canU) oniOpts[idx].push_back({0*N+c, r+1});\n        bool canD=true;\n        for(int i=r+1;i<N;i++) if(board[i][c]=='o'){canD=false;break;}\n        if(canD) oniOpts[idx].push_back({1*N+c, N-r});\n        bool canL=true;\n        for(int j=0;j<c;j++) if(board[r][j]=='o'){canL=false;break;}\n        if(canL) oniOpts[idx].push_back({2*N+r, c+1});\n        bool canR=true;\n        for(int j=c+1;j<N;j++) if(board[r][j]=='o'){canR=false;break;}\n        if(canR) oniOpts[idx].push_back({3*N+r, N-c});\n    }\n    \n    // Assignment\n    vector<int> assign(nOni), assignDist(nOni);\n    // groupMaxCnt[g][d] = count of onis with that dist in group g\n    // groupMax[g] = current max dist in group g\n    // groupSize[g] = number of onis in group g\n    vector<array<int,22>> groupCnt(MAXG);\n    for(auto& a:groupCnt) a.fill(0);\n    vector<int> groupMax(MAXG, 0), groupSize(MAXG, 0);\n    \n    int totalCost = 0;\n    \n    auto addToGroup = [&](int g, int d) {\n        int oldMax = groupMax[g];\n        groupCnt[g][d]++;\n        groupSize[g]++;\n        if(d > oldMax) groupMax[g] = d;\n        totalCost += 2*(groupMax[g] - oldMax);\n    };\n    \n    auto removeFromGroup = [&](int g, int d) {\n        groupCnt[g][d]--;\n        groupSize[g]--;\n        if(groupSize[g]==0){\n            totalCost -= 2*groupMax[g];\n            groupMax[g]=0;\n            return;\n        }\n        int oldMax = groupMax[g];\n        if(d==oldMax && groupCnt[g][d]==0){\n            while(groupMax[g]>0 && groupCnt[g][groupMax[g]]==0) groupMax[g]--;\n            totalCost += 2*(groupMax[g]-oldMax);\n        }\n    };\n    \n    // Initial: pick cheapest direction per oni\n    for(int i=0;i<nOni;i++){\n        int bestD=INT_MAX, bestG=-1;\n        for(auto&[g,d]:oniOpts[i]) if(d<bestD){bestD=d;bestG=g;}\n        assign[i]=bestG; assignDist[i]=bestD;\n        addToGroup(bestG, bestD);\n    }\n    \n    // SA\n    mt19937 rng(42);\n    int bestCost = totalCost;\n    vector<int> bestAssign = assign;\n    \n    for(int iter=0;iter<5000000;iter++){\n        double temp = 30.0 * (1.0 - (double)iter/5000000);\n        int oni = rng() % nOni;\n        if(oniOpts[oni].size()<=1) continue;\n        int ci = rng() % oniOpts[oni].size();\n        auto [newG, newD] = oniOpts[oni][ci];\n        int oldG = assign[oni], oldD = assignDist[oni];\n        if(newG==oldG) continue;\n        \n        int oldCost = totalCost;\n        removeFromGroup(oldG, oldD);\n        addToGroup(newG, newD);\n        int delta = totalCost - oldCost;\n        \n        if(delta<=0 || (temp>0.01 && (double)(rng()%10000)/10000.0 < exp(-delta/temp))){\n            assign[oni]=newG; assignDist[oni]=newD;\n            if(totalCost<bestCost){bestCost=totalCost; bestAssign=assign;}\n        } else {\n            removeFromGroup(newG, newD);\n            addToGroup(oldG, oldD);\n        }\n    }\n    \n    // Reconstruct from bestAssign\n    string dirC=\"UDLR\", revC=\"DURL\";\n    map<int,int> gMax;\n    for(int i=0;i<nOni;i++){\n        int g=bestAssign[i], d=0;\n        for(auto&[gg,dd]:oniOpts[i]) if(gg==g){d=dd;break;}\n        gMax[g]=max(gMax[g],d);\n    }\n    \n    for(auto&[g,mx]:gMax){\n        int dir=g/N, line=g%N;\n        for(int k=0;k<mx;k++) cout<<dirC[dir]<<\" \"<<line<<\"\\n\";\n        for(int k=0;k<mx;k++) cout<<revC[dir]<<\" \"<<line<<\"\\n\";\n    }\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N,L;\n    scanf(\"%d%d\",&N,&L);\n    int T[100];\n    for(int i=0;i<N;i++) scanf(\"%d\",&T[i]);\n    \n    int bestA[100],bestB[100];\n    long long bestErr=1e18;\n    mt19937 rng(42);\n    \n    auto simulate = [&](int*a,int*b) -> long long {\n        int cnt[100]={}, vis[100]={};\n        int x=0;\n        for(int w=0;w<L;w++){\n            cnt[x]++;\n            vis[x]++;\n            x=(vis[x]&1)?a[x]:b[x];\n        }\n        long long err=0;\n        for(int i=0;i<N;i++) err+=abs(cnt[i]-T[i]);\n        return err;\n    };\n    \n    auto greedyInit = [&](int*a,int*b,mt19937&gen) {\n        int deficit[100];\n        for(int i=0;i<N;i++) deficit[i]=T[i];\n        vector<int> order(N);\n        iota(order.begin(),order.end(),0);\n        shuffle(order.begin(),order.end(),gen);\n        // Sort by T descending but with some randomness\n        sort(order.begin(),order.end(),[&](int x,int y){return T[x]>T[y];});\n        \n        for(int idx=0;idx<N;idx++){\n            int i=order[idx];\n            int ha=(T[i]+1)/2, hb=T[i]/2;\n            int best=-1;\n            for(int j=0;j<N;j++) if(best<0||deficit[j]>deficit[best]) best=j;\n            a[i]=best; deficit[best]-=ha;\n            best=-1;\n            for(int j=0;j<N;j++) if(best<0||deficit[j]>deficit[best]) best=j;\n            b[i]=best; deficit[best]-=hb;\n        }\n    };\n    \n    int a[100],b[100];\n    \n    // Try multiple greedy inits\n    for(int trial=0;trial<5;trial++){\n        mt19937 gen(trial*1000+7);\n        greedyInit(a,b,gen);\n        long long err=simulate(a,b);\n        if(err<bestErr){\n            bestErr=err;\n            memcpy(bestA,a,sizeof(a));\n            memcpy(bestB,b,sizeof(b));\n        }\n    }\n    \n    auto start=chrono::steady_clock::now();\n    \n    while(true){\n        double elapsed=chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        if(elapsed>1.82) break;\n        double temp=max(0.5, 60.0*(1.0-elapsed/1.85));\n        \n        memcpy(a,bestA,sizeof(a));\n        memcpy(b,bestB,sizeof(b));\n        \n        // Pick a random edge to change\n        int i=rng()%N;\n        int which=rng()%2;\n        int newVal=rng()%N;\n        if(which) b[i]=newVal; else a[i]=newVal;\n        \n        long long err2=simulate(a,b);\n        double delta=(double)(err2-bestErr);\n        if(delta<=0||(rng()%1000000)<(int)(1000000.0*exp(-delta/temp))){\n            bestErr=err2;\n            memcpy(bestA,a,sizeof(a));\n            memcpy(bestB,b,sizeof(b));\n        }\n    }\n    \n    for(int i=0;i<N;i++) printf(\"%d %d\\n\",bestA[i],bestB[i]);\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(){}\n    DSU(int n): p(n), r(n,0) { iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a, int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a;\n        if(r[a]==r[b]) r[a]++;\n        return true;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M,Q,L,W;\n    cin>>N>>M>>Q>>L>>W;\n    vector<int> G(M);\n    for(auto &g:G) cin>>g;\n    vector<int> lx(N),rx(N),ly(N),ry(N);\n    for(int i=0;i<N;i++) cin>>lx[i]>>rx[i]>>ly[i]>>ry[i];\n    \n    vector<double> cx(N),cy(N);\n    for(int i=0;i<N;i++){\n        cx[i]=(lx[i]+rx[i])/2.0;\n        cy[i]=(ly[i]+ry[i])/2.0;\n    }\n    \n    auto edist = [&](int a, int b) -> double {\n        double dx=cx[a]-cx[b], dy=cy[a]-cy[b];\n        return sqrt(dx*dx+dy*dy);\n    };\n    \n    set<pair<int,int>> oracleEdges;\n    int queriesUsed=0;\n    \n    auto doQuery = [&](vector<int>& subset) {\n        cout<<\"? \"<<subset.size();\n        for(int c:subset) cout<<\" \"<<c;\n        cout<<\"\\n\"<<flush;\n        queriesUsed++;\n        for(int e=0;e<(int)subset.size()-1;e++){\n            int a,b; cin>>a>>b;\n            if(a>b) swap(a,b);\n            oracleEdges.insert({a,b});\n        }\n    };\n    \n    // ---- PHASE 1: Small global exploration ----\n    // Quick targeted queries to discover true neighborhoods\n    vector<int> oracleCov(N, 0);\n    \n    // Precompute nearest neighbors\n    vector<vector<int>> knn(N);\n    for(int i=0;i<N;i++){\n        vector<pair<double,int>> ds;\n        for(int j=0;j<N;j++) if(i!=j) ds.push_back({edist(i,j),j});\n        sort(ds.begin(),ds.end());\n        int k=min((int)ds.size(),30);\n        for(int j=0;j<k;j++) knn[i].push_back(ds[j].second);\n    }\n    \n    int phase1Q = min(Q/3, N/L + 5);\n    \n    for(int q=0; q<phase1Q; q++){\n        int best=-1;\n        for(int i=0;i<N;i++)\n            if(best<0 || oracleCov[i]<oracleCov[best]) best=i;\n        \n        vector<int> subset;\n        subset.push_back(best);\n        set<int> inS;\n        inS.insert(best);\n        \n        vector<pair<pair<int,double>,int>> cands;\n        for(int j:knn[best])\n            cands.push_back({{oracleCov[j],edist(best,j)},j});\n        sort(cands.begin(),cands.end());\n        \n        for(auto&[key,j]:cands){\n            if((int)subset.size()>=L) break;\n            if(!inS.count(j)){ subset.push_back(j); inS.insert(j); }\n        }\n        if((int)subset.size()<L){\n            for(int j=0;j<N&&(int)subset.size()<L;j++)\n                if(!inS.count(j)){ subset.push_back(j); inS.insert(j); }\n        }\n        \n        if((int)subset.size()<2) break;\n        doQuery(subset);\n        for(int c:subset) oracleCov[c]++;\n    }\n    \n    // ---- CLUSTERING ----\n    vector<int> centers(M);\n    vector<double> minDistC(N,1e18);\n    vector<bool> isCenter(N,false);\n    \n    centers[0]=0; isCenter[0]=true;\n    for(int i=0;i<N;i++) minDistC[i]=edist(i,0);\n    for(int c=1;c<M;c++){\n        int best=-1;\n        for(int i=0;i<N;i++) if(!isCenter[i])\n            if(best<0||minDistC[i]>minDistC[best]) best=i;\n        centers[c]=best; isCenter[best]=true;\n        for(int i=0;i<N;i++) minDistC[i]=min(minDistC[i],edist(i,best));\n    }\n    \n    vector<double> gcx(M),gcy(M);\n    for(int i=0;i<M;i++){ gcx[i]=cx[centers[i]]; gcy[i]=cy[centers[i]]; }\n    \n    vector<int> assignment(N,-1);\n    for(int iter=0;iter<30;iter++){\n        using T=tuple<double,int,int>;\n        priority_queue<T,vector<T>,greater<T>> pq;\n        for(int i=0;i<N;i++)\n            for(int g=0;g<M;g++){\n                double dx=cx[i]-gcx[g],dy=cy[i]-gcy[g];\n                pq.push({dx*dx+dy*dy,i,g});\n            }\n        fill(assignment.begin(),assignment.end(),-1);\n        vector<int> cap(G.begin(),G.end());\n        int assigned=0;\n        while(!pq.empty()&&assigned<N){\n            auto[d,c,g]=pq.top();pq.pop();\n            if(assignment[c]!=-1||cap[g]<=0) continue;\n            assignment[c]=g;cap[g]--;assigned++;\n        }\n        bool changed=false;\n        for(int g=0;g<M;g++){\n            double nx=0,ny=0;int cnt=0;\n            for(int i=0;i<N;i++) if(assignment[i]==g){nx+=cx[i];ny+=cy[i];cnt++;}\n            if(!cnt) continue;\n            nx/=cnt;ny/=cnt;\n            if(abs(gcx[g]-nx)>0.01||abs(gcy[g]-ny)>0.01) changed=true;\n            gcx[g]=nx;gcy[g]=ny;\n        }\n        if(!changed) break;\n    }\n    \n    vector<vector<int>> groups(M);\n    for(int i=0;i<N;i++) groups[assignment[i]].push_back(i);\n    \n    // ---- PHASE 2: ALL remaining queries within groups ----\n    // Allocate queries to groups\n    // Priority: larger groups get more queries\n    // Groups with sz<=L need just 1 query for perfect MST\n    \n    int qLeft = Q - queriesUsed;\n    \n    // Sort groups by size descending for allocation\n    vector<int> gorder(M);\n    iota(gorder.begin(),gorder.end(),0);\n    sort(gorder.begin(),gorder.end(),[&](int a,int b){return groups[a].size()>groups[b].size();});\n    \n    // First: give 1 query to each group with 2<=sz<=L\n    vector<int> qalloc(M,0);\n    for(int g=0;g<M;g++){\n        int sz=groups[g].size();\n        if(sz>=2 && sz<=L){\n            qalloc[g]=1;\n            qLeft--;\n        }\n    }\n    \n    // Distribute remaining to groups with sz>L\n    // Each group can use multiple queries with different sort orders\n    // Budget per group ~ proportional to sz\n    if(qLeft>0){\n        double totalSz=0;\n        for(int g=0;g<M;g++) if((int)groups[g].size()>L) totalSz+=groups[g].size();\n        if(totalSz>0){\n            // Give proportional, at least 1\n            int used=0;\n            for(int g=0;g<M;g++){\n                int sz=groups[g].size();\n                if(sz>L){\n                    qalloc[g]=max(1,(int)(qLeft*sz/totalSz));\n                    used+=qalloc[g];\n                }\n            }\n            // Adjust\n            while(used>qLeft){\n                int best=-1;\n                for(int g=0;g<M;g++) if((int)groups[g].size()>L && qalloc[g]>1)\n                    if(best<0||qalloc[g]>qalloc[best]) best=g;\n                if(best<0) break;\n                qalloc[best]--;used--;\n            }\n            while(used<qLeft){\n                int best=-1;double bestR=-1;\n                for(int g=0;g<M;g++) if((int)groups[g].size()>L){\n                    double r=(double)groups[g].size()/(qalloc[g]+1);\n                    if(r>bestR){bestR=r;best=g;}\n                }\n                if(best<0) break;\n                qalloc[best]++;used++;\n            }\n        }\n    }\n    \n    // Execute within-group queries\n    // For each group, use multiple sort orders to get diverse oracle edges\n    auto queryGroup = [&](int g, int numQ){\n        auto& grp = groups[g];\n        int sz = grp.size();\n        if(sz<=1 || numQ<=0) return;\n        \n        if(sz<=L){\n            vector<int> subset(grp.begin(),grp.end());\n            doQuery(subset);\n            return;\n        }\n        \n        // Distribute queries across sort orders\n        // Sort orders: x+y, x, y, x-y\n        vector<vector<int>> sortOrders;\n        \n        {auto s=grp; sort(s.begin(),s.end(),[&](int a,int b){return cx[a]+cy[a]<cx[b]+cy[b];}); sortOrders.push_back(s);}\n        {auto s=grp; sort(s.begin(),s.end(),[&](int a,int b){return cx[a]<cx[b];}); sortOrders.push_back(s);}\n        {auto s=grp; sort(s.begin(),s.end(),[&](int a,int b){return cy[a]<cy[b];}); sortOrders.push_back(s);}\n        {auto s=grp; sort(s.begin(),s.end(),[&](int a,int b){return cx[a]-cy[a]<cx[b]-cy[b];}); sortOrders.push_back(s);}\n        \n        int qPerOrder = max(1, numQ / (int)sortOrders.size());\n        int qUsedHere = 0;\n        \n        for(int so=0; so<(int)sortOrders.size() && qUsedHere<numQ && queriesUsed<Q; so++){\n            auto& sorted = sortOrders[so];\n            int thisQ = (so < (int)sortOrders.size()-1) ? qPerOrder : (numQ - qUsedHere);\n            \n            // Evenly space windows\n            for(int q=0; q<thisQ && queriesUsed<Q; q++){\n                int start;\n                if(thisQ==1) start=0;\n                else{\n                    double step = (double)(sz-L)/(thisQ-1);\n                    start = (int)(q*step);\n                }\n                start = max(0,min(start,sz-L));\n                int end = min(start+L,sz);\n                if(end-start<2) continue;\n                vector<int> subset(sorted.begin()+start, sorted.begin()+end);\n                doQuery(subset);\n                qUsedHere++;\n            }\n        }\n    };\n    \n    for(int g=0;g<M;g++){\n        queryGroup(g, qalloc[g]);\n    }\n    \n    // Use any truly remaining queries\n    while(queriesUsed<Q){\n        // Find group with best ratio of size to oracle edges\n        int bestG=-1; double bestV=-1;\n        for(int g=0;g<M;g++){\n            int sz=groups[g].size();\n            if(sz<=1) continue;\n            if(sz<=L){\n                // Check if already queried\n                // Count oracle edges in group\n                set<int> inG(groups[g].begin(),groups[g].end());\n                int oe=0;\n                for(auto[a,b]:oracleEdges) if(inG.count(a)&&inG.count(b)) oe++;\n                if(oe>=sz-1) continue;\n            }\n            double v=(double)sz;\n            if(v>bestV){bestV=v;bestG=g;}\n        }\n        if(bestG<0) break;\n        \n        auto& grp=groups[bestG];\n        int sz=grp.size();\n        \n        // Pick a random-ish subset: city with fewest oracle edges + its nearest neighbors in group\n        map<int,int> grpOE;\n        set<int> inG(grp.begin(),grp.end());\n        for(int c:grp) grpOE[c]=0;\n        for(auto[a,b]:oracleEdges){\n            if(inG.count(a)) grpOE[a]++;\n            if(inG.count(b)) grpOE[b]++;\n        }\n        \n        int pivot=-1;\n        for(int c:grp)\n            if(pivot<0||grpOE[c]<grpOE[pivot]) pivot=c;\n        \n        vector<pair<double,int>> dists;\n        for(int c:grp) dists.push_back({edist(pivot,c),c});\n        sort(dists.begin(),dists.end());\n        \n        vector<int> subset;\n        for(int i=0;i<min(L,sz);i++) subset.push_back(dists[i].second);\n        if((int)subset.size()<2) break;\n        doQuery(subset);\n    }\n    \n    // ---- BUILD SPANNING TREES ----\n    cout<<\"!\"<<endl;\n    \n    for(int g=0;g<M;g++){\n        auto& grp=groups[g];\n        int sz=grp.size();\n        \n        for(int i=0;i<sz;i++){\n            if(i) cout<<\" \";\n            cout<<grp[i];\n        }\n        cout<<\"\\n\";\n        \n        if(sz<=1) continue;\n        \n        set<int> inGrp(grp.begin(),grp.end());\n        \n        vector<tuple<double,int,int>> edges;\n        for(auto[a,b]:oracleEdges)\n            if(inGrp.count(a)&&inGrp.count(b))\n                edges.push_back({edist(a,b)*0.5, a, b});\n        \n        for(int i=0;i<sz;i++)\n            for(int j=i+1;j<sz;j++)\n                edges.push_back({edist(grp[i],grp[j]), grp[i], grp[j]});\n        \n        sort(edges.begin(),edges.end());\n        \n        DSU gdsu(N);\n        vector<pair<int,int>> tree;\n        for(auto&[w,a,b]:edges){\n            if(gdsu.unite(a,b)){\n                tree.push_back({a,b});\n                if((int)tree.size()==sz-1) break;\n            }\n        }\n        \n        for(auto[a,b]:tree) cout<<a<<\" \"<<b<<\"\\n\";\n    }\n    \n    cout<<flush;\n    return 0;\n}","ahc046":"#include<bits/stdc++.h>\nusing namespace std;\nint N,M;\nint dx[]={-1,1,0,0},dy[]={0,0,-1,1};\nchar dc[]={'U','D','L','R'};\nuint64_t zobrist[400];\n\nstruct BS7{\n    uint64_t w[7]={};\n    bool get(int i)const{return (w[i/64]>>(i%64))&1;}\n    void flip(int i){w[i/64]^=(1ULL<<(i%64));}\n};\n\npair<int,int> doSlide(int x,int y,int d,BS7&bs){\n    while(true){\n        int nx=x+dx[d],ny=y+dy[d];\n        if(nx<0||nx>=N||ny<0||ny>=N||bs.get(nx*N+ny))break;\n        x=nx;y=ny;\n    }\n    return{x,y};\n}\n\nvector<pair<int,int>> bfsMoveOnly(int ci,int cj,int gi,int gj,BS7&bs){\n    if(ci==gi&&cj==gj)return{};\n    int dist[20][20];\n    memset(dist,-1,sizeof(dist));\n    int pdir[20][20];\n    pair<int,int> par[20][20];\n    queue<pair<int,int>>q;\n    dist[ci][cj]=0;q.push({ci,cj});\n    while(!q.empty()){\n        auto[x,y]=q.front();q.pop();\n        if(x==gi&&y==gj)break;\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&&!bs.get(nx*N+ny)&&dist[nx][ny]<0){\n                dist[nx][ny]=dist[x][y]+1;par[nx][ny]={x,y};pdir[nx][ny]=d;q.push({nx,ny});\n            }\n        }\n    }\n    vector<pair<int,int>>acts;\n    if(dist[gi][gj]<0)return acts;\n    int x=gi,y=gj;\n    while(x!=ci||y!=cj){acts.push_back({0,pdir[x][y]});auto[px,py]=par[x][y];x=px;y=py;}\n    reverse(acts.begin(),acts.end());\n    return acts;\n}\n\nint main(){\n    mt19937_64 rng(12345);\n    for(int i=0;i<400;i++) zobrist[i]=rng();\n    \n    scanf(\"%d%d\",&N,&M);\n    vector<int>ti(M),tj(M);\n    for(int k=0;k<M;k++)scanf(\"%d%d\",&ti[k],&tj[k]);\n    \n    int ci=ti[0],cj=tj[0];\n    BS7 curBs;\n    uint64_t curHash=0;\n    vector<pair<int,int>>allActs;\n    \n    for(int k=1;k<M;k++){\n        int gi=ti[k],gj=tj[k];\n        \n        // BFS over (x,y,blockState)\n        // Store nodes in vector, careful with references\n        struct Node{\n            int x,y;\n            uint64_t bh;\n            BS7 bs;\n            int parent;\n            int action,dir;\n        };\n        \n        const int NODE_LIMIT = 40000;\n        vector<Node> nd;\n        nd.reserve(NODE_LIMIT+100);\n        unordered_map<uint64_t,bool> vis;\n        \n        auto sk=[](int x,int y,uint64_t bh)->uint64_t{\n            // Better hash to avoid collisions\n            uint64_t h = bh;\n            h ^= (uint64_t)x * 6364136223846793005ULL + 1442695040888963407ULL;\n            h ^= (uint64_t)y * 2862933555777941757ULL + 3037000493ULL;\n            return h;\n        };\n        \n        nd.push_back({ci,cj,curHash,curBs,-1,-1,-1});\n        vis[sk(ci,cj,curHash)]=true;\n        \n        int foundNode=-1;\n        int head=0;\n        \n        while(head<(int)nd.size()&&(int)nd.size()<NODE_LIMIT){\n            // Copy current node data to avoid dangling reference\n            int cx=nd[head].x, cy=nd[head].y;\n            uint64_t cbh=nd[head].bh;\n            BS7 cbs=nd[head].bs;\n            \n            if(cx==gi&&cy==gj){foundNode=head;break;}\n            \n            for(int d=0;d<4;d++){\n                int nx=cx+dx[d],ny=cy+dy[d];\n                \n                // Move\n                if(nx>=0&&nx<N&&ny>=0&&ny<N&&!cbs.get(nx*N+ny)){\n                    uint64_t key=sk(nx,ny,cbh);\n                    if(!vis.count(key)){\n                        vis[key]=true;\n                        nd.push_back({nx,ny,cbh,cbs,head,0,d});\n                    }\n                }\n                \n                // Slide\n                auto[sx,sy]=doSlide(cx,cy,d,cbs);\n                if(sx!=cx||sy!=cy){\n                    uint64_t key=sk(sx,sy,cbh);\n                    if(!vis.count(key)){\n                        vis[key]=true;\n                        nd.push_back({sx,sy,cbh,cbs,head,1,d});\n                    }\n                }\n                \n                // Alter\n                if(nx>=0&&nx<N&&ny>=0&&ny<N){\n                    uint64_t nh=cbh^zobrist[nx*N+ny];\n                    uint64_t key=sk(cx,cy,nh);\n                    if(!vis.count(key)){\n                        vis[key]=true;\n                        BS7 nbs=cbs;\n                        nbs.flip(nx*N+ny);\n                        nd.push_back({cx,cy,nh,nbs,head,2,d});\n                    }\n                }\n            }\n            head++;\n        }\n        \n        if(foundNode<0){\n            for(int i=head;i<(int)nd.size();i++){\n                if(nd[i].x==gi&&nd[i].y==gj){foundNode=i;break;}\n            }\n        }\n        \n        vector<pair<int,int>> path;\n        \n        if(foundNode>=0){\n            int c=foundNode;\n            while(nd[c].parent>=0){\n                path.push_back({nd[c].action,nd[c].dir});\n                c=nd[c].parent;\n            }\n            reverse(path.begin(),path.end());\n            curBs=nd[foundNode].bs;\n            curHash=nd[foundNode].bh;\n            ci=gi;cj=gj;\n        } else {\n            // Fallback: move-only BFS\n            path=bfsMoveOnly(ci,cj,gi,gj,curBs);\n            ci=gi;cj=gj;\n        }\n        \n        for(auto&a:path) allActs.push_back(a);\n    }\n    \n    for(auto&[a,d]:allActs){\n        char ac=(a==0?'M':(a==1?'S':'A'));\n        printf(\"%c %c\\n\",ac,dc[d]);\n    }\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    vector<int> x(n),y(n);\n    vector<long long> r(n);\n    for(int i=0;i<n;i++) cin>>x[i]>>y[i]>>r[i];\n    \n    vector<int> a(n),b(n),c(n),d(n);\n    for(int i=0;i<n;i++){a[i]=x[i];b[i]=y[i];c[i]=x[i]+1;d[i]=y[i]+1;}\n    \n    auto scoreOf=[&](int i)->double{\n        long long s=(long long)(c[i]-a[i])*(d[i]-b[i]);\n        double rat=(double)min(r[i],s)/(double)max(r[i],s);\n        return 1.0-(1.0-rat)*(1.0-rat);\n    };\n    \n    auto start=chrono::steady_clock::now();\n    mt19937 rng(42);\n    auto elapsed=[&]()->double{return chrono::duration<double>(chrono::steady_clock::now()-start).count();};\n    \n    // Phase 1: Greedy\n    while(elapsed()<0.7){\n        bool imp=false;\n        vector<int> order(n);\n        iota(order.begin(),order.end(),0);\n        shuffle(order.begin(),order.end(),rng);\n        for(int i:order){\n            long long s=(long long)(c[i]-a[i])*(d[i]-b[i]);\n            if(s<r[i]){\n                int w=c[i]-a[i],h=d[i]-b[i];\n                long long def=r[i]-s;\n                int sH=max(1,min(200,(int)(def/max(1,h))));\n                int sV=max(1,min(200,(int)(def/max(1,w))));\n                auto ok=[&](int na,int nb,int nc,int nd)->bool{\n                    if(na<0||nb<0||nc>10000||nd>10000||na>=nc||nb>=nd)return false;\n                    for(int j=0;j<n;j++){if(j==i)continue;if(na<c[j]&&a[j]<nc&&nb<d[j]&&b[j]<nd)return false;}return true;\n                };\n                for(int st=sH;st>=1;st=(st>1?max(1,st/2):0)){if(ok(a[i]-st,b[i],c[i],d[i])){a[i]-=st;imp=true;break;}}\n                for(int st=sH;st>=1;st=(st>1?max(1,st/2):0)){if(ok(a[i],b[i],c[i]+st,d[i])){c[i]+=st;imp=true;break;}}\n                for(int st=sV;st>=1;st=(st>1?max(1,st/2):0)){if(ok(a[i],b[i]-st,c[i],d[i])){b[i]-=st;imp=true;break;}}\n                for(int st=sV;st>=1;st=(st>1?max(1,st/2):0)){if(ok(a[i],b[i],c[i],d[i]+st)){d[i]+=st;imp=true;break;}}\n            }\n            s=(long long)(c[i]-a[i])*(d[i]-b[i]);\n            if(s>r[i]){\n                long long exc=s-r[i];int w=c[i]-a[i],h=d[i]-b[i];double cur=scoreOf(i);\n                int sH=max(1,(int)(exc/max(1,h))),sV=max(1,(int)(exc/max(1,w)));\n                int dl=x[i]-a[i],dr=c[i]-(x[i]+1),du=y[i]-b[i],dd2=d[i]-(y[i]+1);\n                {int ns=min(sH,dl);if(ns>0){a[i]+=ns;if(scoreOf(i)<=cur)a[i]-=ns;else{cur=scoreOf(i);imp=true;}}}\n                {int ns=min(sH,dr);if(ns>0){c[i]-=ns;if(scoreOf(i)<=cur)c[i]+=ns;else{cur=scoreOf(i);imp=true;}}}\n                {int ns=min(sV,du);if(ns>0){b[i]+=ns;if(scoreOf(i)<=cur)b[i]-=ns;else{cur=scoreOf(i);imp=true;}}}\n                {int ns=min(sV,dd2);if(ns>0){d[i]-=ns;if(scoreOf(i)<=cur)d[i]+=ns;else{cur=scoreOf(i);imp=true;}}}\n            }\n        }\n        if(!imp)break;\n    }\n    \n    vector<double> scores(n);\n    double totalS=0;\n    for(int i=0;i<n;i++){scores[i]=scoreOf(i);totalS+=scores[i];}\n    vector<int> ba=a,bb=b,bc=c,bd=d;\n    double bestTotal=totalS;\n    \n    // Find adjacent pairs for boundary moves\n    // Two rectangles share a boundary if they touch on an edge\n    \n    // Phase 2: SA with single-edge moves and boundary moves\n    double saStart=elapsed(),saEnd=4.7;\n    double T0=0.08,T1=0.0005;\n    vector<int> sqrtR(n);\n    for(int i=0;i<n;i++)sqrtR[i]=max(1,(int)sqrt((double)r[i]));\n    \n    while(true){\n        double now=elapsed();\n        if(now>=saEnd)break;\n        double t=(now-saStart)/(saEnd-saStart);\n        double T=T0*pow(T1/T0,t);\n        \n        int i=rng()%n;\n        int oa=a[i],ob=b[i],oc=c[i],od=d[i];\n        int maxD=max(1,sqrtR[i]/3);\n        int mt2=rng()%5;\n        \n        if(mt2<4){\n            int delta=(int)(rng()%(2*maxD+1))-maxD;\n            if(!delta)delta=1;\n            if(mt2==0)a[i]+=delta;\n            else if(mt2==1)c[i]+=delta;\n            else if(mt2==2)b[i]+=delta;\n            else d[i]+=delta;\n        }else{\n            int dx=(int)(rng()%(2*maxD+1))-maxD;\n            int dy=(int)(rng()%(2*maxD+1))-maxD;\n            a[i]+=dx;c[i]+=dx;b[i]+=dy;d[i]+=dy;\n        }\n        \n        if(a[i]<0||b[i]<0||c[i]>10000||d[i]>10000||a[i]>=c[i]||b[i]>=d[i]||\n           a[i]>x[i]||c[i]<=x[i]||b[i]>y[i]||d[i]<=y[i]){\n            a[i]=oa;b[i]=ob;c[i]=oc;d[i]=od;continue;\n        }\n        \n        // Check overlap - collect conflicting rectangles\n        bool ok=true;\n        int conf=-1;\n        int nconf=0;\n        for(int j=0;j<n;j++){\n            if(j==i)continue;\n            if(a[i]<c[j]&&a[j]<c[i]&&b[i]<d[j]&&b[j]<d[i]){\n                nconf++;\n                if(nconf==1)conf=j; else{ok=false;break;}\n            }\n        }\n        \n        if(!ok||nconf>1){a[i]=oa;b[i]=ob;c[i]=oc;d[i]=od;continue;}\n        \n        if(nconf==0){\n            // No conflict - standard SA accept\n            double ns=scoreOf(i),diff=ns-scores[i];\n            if(diff>0||(rng()&0xFFFFFF)<(unsigned)(exp(diff/T)*(1<<24))){\n                totalS+=diff;scores[i]=ns;\n                if(totalS>bestTotal){bestTotal=totalS;ba=a;bb=b;bc=c;bd=d;}\n            }else{a[i]=oa;b[i]=ob;c[i]=oc;d[i]=od;}\n        } else {\n            // One conflict with j=conf - try shrinking j to resolve\n            int j=conf;\n            int ja=a[j],jb=b[j],jc=c[j],jd=d[j];\n            \n            // Find which edge of j to shrink\n            bool resolved=false;\n            // Try adjusting j's edges to not overlap with new i\n            // The overlap region: max(a[i],a[j]) to min(c[i],c[j]) x max(b[i],b[j]) to min(d[i],d[j])\n            int ox1=max(a[i],a[j]),ox2=min(c[i],c[j]),oy1=max(b[i],b[j]),oy2=min(d[i],d[j]);\n            \n            // Try 4 ways to resolve by moving one edge of j\n            struct Fix{int *edge;int val;};\n            Fix fixes[]={{&a[j],ox2},{&c[j],ox1},{&b[j],oy2},{&d[j],oy1}};\n            \n            double bestDiff=-1e18;\n            int bestFix=-1;\n            for(int f=0;f<4;f++){\n                int old=*fixes[f].edge;\n                *fixes[f].edge=fixes[f].val;\n                if(a[j]>=c[j]||b[j]>=d[j]||a[j]>x[j]||c[j]<=x[j]||b[j]>y[j]||d[j]<=y[j]){\n                    *fixes[f].edge=old;continue;\n                }\n                // Check j doesn't overlap others\n                bool jok=true;\n                for(int k=0;k<n;k++){\n                    if(k==j&&k==i)continue;\n                    if(k==j||k==i)continue;\n                    if(a[j]<c[k]&&a[k]<c[j]&&b[j]<d[k]&&b[k]<d[j]){jok=false;break;}\n                }\n                if(jok){\n                    double di=scoreOf(i)-scores[i];\n                    double dj=scoreOf(j)-scores[j];\n                    if(di+dj>bestDiff){bestDiff=di+dj;bestFix=f;}\n                }\n                *fixes[f].edge=old;\n            }\n            \n            if(bestFix>=0 && (bestDiff>0||(rng()&0xFFFFFF)<(unsigned)(exp(bestDiff/T)*(1<<24)))){\n                *fixes[bestFix].edge=fixes[bestFix].val;\n                double nsi=scoreOf(i),nsj=scoreOf(j);\n                totalS+=(nsi-scores[i])+(nsj-scores[j]);\n                scores[i]=nsi;scores[j]=nsj;\n                if(totalS>bestTotal){bestTotal=totalS;ba=a;bb=b;bc=c;bd=d;}\n            } else {\n                a[i]=oa;b[i]=ob;c[i]=oc;d[i]=od;\n                a[j]=ja;b[j]=jb;c[j]=jc;d[j]=jd;\n            }\n        }\n    }\n    \n    a=ba;b=bb;c=bc;d=bd;\n    for(int i=0;i<n;i++)cout<<a[i]<<\" \"<<b[i]<<\" \"<<c[i]<<\" \"<<d[i]<<\"\\n\";\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\nint t[50][50],p[50][50];\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\nchar dc[]={'U','D','L','R'};\nint M,UW;\nstruct Node{int parent;char dir;};\nvector<Node> tree;\nstruct NInfo{int nx,ny,tid,dir;};\nvector<NInfo> nbr[50][50];\n\nstring getPath(int idx){\n    string s;\n    while(idx>0){s+=tree[idx].dir;idx=tree[idx].parent;}\n    reverse(s.begin(),s.end());return s;\n}\nstruct State{int x,y,score,nodeIdx,usedIdx,eval;};\n\nint globalBest=0,globalBestNode=0;\n\nvoid greedyExtend(int cx,int cy,int score,int nodeIdx,const uint64_t*used){\n    // Make local copy\n    vector<uint64_t> u(used,used+UW);\n    int sc=score;int cn=nodeIdx;\n    while(true){\n        int bestD=-1,bestVal=-1;\n        for(auto&nb:nbr[cx][cy]){\n            if((u[nb.tid/64]>>(nb.tid%64))&1)continue;\n            int v=p[nb.nx][nb.ny];\n            int fm=0;\n            for(auto&nb2:nbr[nb.nx][nb.ny])\n                if(nb2.tid!=nb.tid&&!((u[nb2.tid/64]>>(nb2.tid%64))&1))fm++;\n            int val=v+fm*30;\n            if(val>bestVal){bestVal=val;bestD=nb.dir;}\n        }\n        if(bestD<0)break;\n        int nx2=cx+dx[bestD],ny2=cy+dy[bestD];\n        int tid=t[nx2][ny2];\n        u[tid/64]|=1ULL<<(tid%64);\n        sc+=p[nx2][ny2];\n        int ni=(int)tree.size();\n        tree.push_back({cn,dc[bestD]});\n        cn=ni;cx=nx2;cy=ny2;\n    }\n    if(sc>globalBest){globalBest=sc;globalBestNode=cn;}\n}\n\nvoid runBeam(int si,int sj,int BEAM,int PERPOS,int scoreW,int futW,int freeW,int fut2W,\n            chrono::steady_clock::time_point deadline){\n    size_t UB=(size_t)UW*8;\n    vector<uint64_t> curPool(UW,0);\n    {int tid0=t[si][sj];curPool[tid0/64]|=1ULL<<(tid0%64);}\n    vector<State> beam;\n    beam.push_back({si,sj,p[si][sj],0,0,0});\n    \n    for(int step=0;step<2500&&!beam.empty();step++){\n        if(step%10==0&&chrono::steady_clock::now()>deadline)break;\n        vector<State> next;\n        next.reserve(beam.size()*4);\n        vector<uint64_t> nxPool;\n        nxPool.reserve(beam.size()*4*UW);\n        for(auto&s:beam){\n            const uint64_t*uptr=&curPool[(size_t)s.usedIdx*UW];\n            for(auto&nb:nbr[s.x][s.y]){\n                if((uptr[nb.tid/64]>>(nb.tid%64))&1)continue;\n                int ni=(int)tree.size();\n                tree.push_back({s.nodeIdx,dc[nb.dir]});\n                int newIdx=(int)(nxPool.size()/UW);\n                size_t base=nxPool.size();\n                nxPool.resize(base+UW);\n                memcpy(&nxPool[base],uptr,UB);\n                nxPool[base+nb.tid/64]|=1ULL<<(nb.tid%64);\n                int sc=s.score+p[nb.nx][nb.ny];\n                int futureVal=0,freeMoves=0;\n                const uint64_t*nptr=&nxPool[base];\n                for(auto&nb2:nbr[nb.nx][nb.ny]){\n                    if(!((nptr[nb2.tid/64]>>(nb2.tid%64))&1)){\n                        freeMoves++;futureVal+=p[nb2.nx][nb2.ny];\n                        for(auto&nb3:nbr[nb2.nx][nb2.ny])\n                            if(nb3.tid!=nb2.tid&&!((nptr[nb3.tid/64]>>(nb3.tid%64))&1))\n                                futureVal+=p[nb3.nx][nb3.ny]*fut2W/16;\n                    }\n                }\n                int ev=sc*scoreW+futureVal*futW/4+freeMoves*freeW;\n                next.push_back({nb.nx,nb.ny,sc,ni,newIdx,ev});\n            }\n        }\n        if(next.empty())break;\n        sort(next.begin(),next.end(),[](const State&a,const State&b){return a.eval>b.eval;});\n        int cnt[50][50]={};\n        vector<State> sel;vector<uint64_t> selPool;\n        sel.reserve(BEAM);selPool.reserve((size_t)BEAM*UW);\n        for(auto&s:next){\n            if(cnt[s.x][s.y]<PERPOS&&(int)sel.size()<BEAM){\n                cnt[s.x][s.y]++;\n                int ni2=(int)(selPool.size()/UW);\n                size_t base=selPool.size();\n                selPool.resize(base+UW);\n                memcpy(&selPool[base],&nxPool[(size_t)s.usedIdx*UW],UB);\n                s.usedIdx=ni2;sel.push_back(s);\n                if(s.score>globalBest){globalBest=s.score;globalBestNode=s.nodeIdx;}\n            }\n        }\n        beam=move(sel);curPool=move(selPool);\n    }\n    // Greedy extend top beam states\n    int extN=min((int)beam.size(),50);\n    for(int i=0;i<extN;i++){\n        auto&s=beam[i];\n        greedyExtend(s.x,s.y,s.score,s.nodeIdx,&curPool[(size_t)s.usedIdx*UW]);\n    }\n}\n\nint main(){\n    int si,sj;\n    scanf(\"%d%d\",&si,&sj);\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++)scanf(\"%d\",&t[i][j]);\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++)scanf(\"%d\",&p[i][j]);\n    M=0;\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++)M=max(M,t[i][j]+1);\n    UW=(M+63)/64;\n    tree.reserve(15000000);tree.push_back({-1,' '});\n    for(int i=0;i<50;i++)for(int j=0;j<50;j++)\n        for(int d=0;d<4;d++){\n            int ni=i+dx[d],nj=j+dy[d];\n            if(ni>=0&&ni<50&&nj>=0&&nj<50)\n                nbr[i][j].push_back({ni,nj,t[ni][nj],d});\n        }\n    auto start=chrono::steady_clock::now();\n    struct Config{int beam,perpos,sw,fw,frw,f2w;};\n    vector<Config> configs={\n        {900,5,4,4,20,4},\n        {900,5,3,4,25,4},\n        {900,5,5,4,15,4},\n        {900,4,4,4,20,6},\n        {1200,6,4,4,20,4},\n        {900,5,4,6,20,4},\n        {900,5,4,4,30,2},\n        {900,5,4,4,20,8},\n        {900,5,6,4,10,4},\n        {900,3,4,4,20,4},\n    };\n    globalBest=p[si][sj];globalBestNode=0;\n    int N=(int)configs.size();\n    for(int c=0;c<N;c++){\n        if(chrono::steady_clock::now()>=start+chrono::milliseconds(1850))break;\n        auto&cf=configs[c];\n        auto dl=start+chrono::milliseconds(1850*(c+1)/N);\n        runBeam(si,sj,cf.beam,cf.perpos,cf.sw,cf.fw,cf.frw,cf.f2w,dl);\n    }\n    printf(\"%s\\n\",getPath(globalBestNode).c_str());\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\nconst int N=30;\ndouble h[N][N-1],v[N-1][N];\nint cnt_h[N][N-1],cnt_v[N-1][N];\n\nstruct Obs{vector<pair<int,int>> he,ve; double cost;};\nvector<Obs> observations;\n\nint di[]={-1,1,0,0},dj[]={0,0,-1,1};\nchar dirs[]=\"UDLR\";\nstruct Edge{int type,ei,ej;};\n\nvoid fillFromRowCol(){\n    for(int i=0;i<N;i++){\n        double s=0;int c=0;\n        for(int j=0;j<N-1;j++) if(cnt_h[i][j]>0){s+=h[i][j];c++;}\n        if(c>0){double a=s/c; for(int j=0;j<N-1;j++) if(cnt_h[i][j]==0) h[i][j]=a;}\n    }\n    for(int j=0;j<N;j++){\n        double s=0;int c=0;\n        for(int i=0;i<N-1;i++) if(cnt_v[i][j]>0){s+=v[i][j];c++;}\n        if(c>0){double a=s/c; for(int i=0;i<N-1;i++) if(cnt_v[i][j]==0) v[i][j]=a;}\n    }\n}\n\npair<string,vector<Edge>> dijkstra(int si,int sj,int ti,int tj){\n    vector<double> dist(N*N,1e18);\n    vector<int> pn(N*N,-1),pd(N*N,-1);\n    priority_queue<pair<double,int>,vector<pair<double,int>>,greater<>> pq;\n    int s=si*N+sj,t=ti*N+tj;\n    dist[s]=0;pq.push({0,s});\n    while(!pq.empty()){\n        auto[d,u]=pq.top();pq.pop();\n        if(d>dist[u])continue;\n        int ci=u/N,cj=u%N;\n        for(int dir=0;dir<4;dir++){\n            int ni=ci+di[dir],nj=cj+dj[dir];\n            if(ni<0||ni>=N||nj<0||nj>=N)continue;\n            double w;\n            if(dir==0)w=v[ni][cj];else if(dir==1)w=v[ci][cj];\n            else if(dir==2)w=h[ci][nj];else w=h[ci][cj];\n            int nv=ni*N+nj;\n            if(dist[u]+w<dist[nv]){dist[nv]=dist[u]+w;pn[nv]=u;pd[nv]=dir;pq.push({dist[nv],nv});}\n        }\n    }\n    string ans;vector<Edge> edges;\n    int cur=t;\n    vector<pair<int,int>> pp;\n    while(cur!=s){pp.push_back({pn[cur],pd[cur]});cur=pn[cur];}\n    reverse(pp.begin(),pp.end());\n    for(auto&[node,dir]:pp){\n        ans+=dirs[dir];\n        int ci=node/N,cj=node%N;\n        Edge e{dir,0,0};\n        if(dir==0){e.ei=ci-1;e.ej=cj;}\n        else if(dir==1){e.ei=ci;e.ej=cj;}\n        else if(dir==2){e.ei=ci;e.ej=cj-1;}\n        else{e.ei=ci;e.ej=cj;}\n        edges.push_back(e);\n    }\n    return{ans,edges};\n}\n\ndouble measureError(){\n    double totalErr=0;\n    for(auto&obs:observations){\n        double est=0;\n        for(auto&[i,j]:obs.he) est+=h[i][j];\n        for(auto&[i,j]:obs.ve) est+=v[i][j];\n        double r=obs.cost-est;\n        totalErr+=r*r;\n    }\n    return observations.empty()?1e18:totalErr/observations.size();\n}\n\nvoid refine_iter(double lr, double reg){\n    for(auto&obs:observations){\n        double est=0;int ne=0;\n        for(auto&[i,j]:obs.he){est+=h[i][j];ne++;}\n        for(auto&[i,j]:obs.ve){est+=v[i][j];ne++;}\n        if(est<1||ne==0)continue;\n        double delta=lr*(obs.cost-est)/ne;\n        for(auto&[i,j]:obs.he){h[i][j]+=delta;h[i][j]=max(1000.0,min(9000.0,h[i][j]));}\n        for(auto&[i,j]:obs.ve){v[i][j]+=delta;v[i][j]=max(1000.0,min(9000.0,v[i][j]));}\n    }\n    if(reg>0){\n        for(int i=0;i<N;i++){\n            double s=0;int c=0;\n            for(int j=0;j<N-1;j++)if(cnt_h[i][j]>0){s+=h[i][j];c++;}\n            if(c>1){double a=s/c;for(int j=0;j<N-1;j++)if(cnt_h[i][j]>0)h[i][j]+=reg*(a-h[i][j]);}\n        }\n        for(int j=0;j<N;j++){\n            double s=0;int c=0;\n            for(int i=0;i<N-1;i++)if(cnt_v[i][j]>0){s+=v[i][j];c++;}\n            if(c>1){double a=s/c;for(int i=0;i<N-1;i++)if(cnt_v[i][j]>0)v[i][j]+=reg*(a-v[i][j]);}\n        }\n    }\n}\n\nvoid doRefine(int maxIters, double startLr, double reg, double timeLimitSec){\n    auto st=chrono::steady_clock::now();\n    double lr=startLr;\n    for(int it=0;it<maxIters;it++){\n        auto now=chrono::steady_clock::now();\n        if(chrono::duration<double>(now-st).count()>timeLimitSec) break;\n        refine_iter(lr, reg);\n        lr*=0.95;\n    }\n    fillFromRowCol();\n}\n\nint main(){\n    for(int i=0;i<N;i++)for(int j=0;j<N-1;j++){h[i][j]=5000;cnt_h[i][j]=0;}\n    for(int i=0;i<N-1;i++)for(int j=0;j<N;j++){v[i][j]=5000;cnt_v[i][j]=0;}\n    \n    auto t0=chrono::steady_clock::now();\n    int totalRefineCount=0;\n    \n    for(int q=0;q<1000;q++){\n        int si,sj,ti,tj;\n        scanf(\"%d%d%d%d\",&si,&sj,&ti,&tj);\n        auto[ans,edges]=dijkstra(si,sj,ti,tj);\n        printf(\"%s\\n\",ans.c_str());fflush(stdout);\n        int obs_val;scanf(\"%d\",&obs_val);\n        \n        double est=0;\n        Obs ob;\n        for(auto&e:edges){\n            if(e.type<=1){est+=v[e.ei][e.ej];ob.ve.push_back({e.ei,e.ej});}\n            else{est+=h[e.ei][e.ej];ob.he.push_back({e.ei,e.ej});}\n        }\n        ob.cost=(double)obs_val;\n        observations.push_back(ob);\n        \n        // Online update - lighter to not disturb batch results\n        double ratio=(double)obs_val/est;\n        for(auto&e:edges){\n            if(e.type<=1){\n                int c=++cnt_v[e.ei][e.ej];\n                double lr=1.0/(c+3);\n                v[e.ei][e.ej]*=(1.0-lr)+lr*ratio;\n                v[e.ei][e.ej]=max(1000.0,min(9000.0,v[e.ei][e.ej]));\n            }else{\n                int c=++cnt_h[e.ei][e.ej];\n                double lr=1.0/(c+3);\n                h[e.ei][e.ej]*=(1.0-lr)+lr*ratio;\n                h[e.ei][e.ej]=max(1000.0,min(9000.0,h[e.ei][e.ej]));\n            }\n        }\n        \n        fillFromRowCol();\n        \n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-t0).count();\n        \n        bool doRef=false;\n        if(q<100 && q%10==9) doRef=true;\n        else if(q<300 && q%20==19) doRef=true;\n        else if(q%50==49) doRef=true;\n        \n        if(doRef && elapsed<1.5){\n            double timeForThis=min(0.08, (1.75-elapsed)*0.15);\n            doRefine(15, 0.15, 0.02, timeForThis);\n        }\n    }\n}","ahc004":"#include<bits/stdc++.h>\nusing namespace std;\nint N=20,M;\nchar G[20][20],bestG[20][20];\n\nint main(){\n    ios::sync_with_stdio(0);cin.tie(0);\n    cin>>N>>M;\n    vector<string>S(M);\n    for(int i=0;i<M;i++)cin>>S[i];\n    mt19937 rng(42);\n    auto t0=chrono::steady_clock::now();\n    auto elapsed=[&](){return chrono::duration<double>(chrono::steady_clock::now()-t0).count();};\n    \n    // Phase 1: Cluster strings into lines using pairwise compatibility\n    // For each pair of strings, for each offset delta, check compatibility\n    // on a cyclic line of length 20\n    \n    // compatibility(s1, o1, s2, o2) on a line:\n    // s1 at offset o1 covers positions o1..o1+len1-1 mod 20\n    // s2 at offset o2 covers positions o2..o2+len2-1 mod 20\n    // They're compatible if overlapping positions have same char\n    \n    // Equivalently: fix s1 at offset 0, s2 at offset delta = o2-o1\n    // Then s1 covers [0, len1) and s2 covers [delta, delta+len2) mod 20\n    // Check overlap agreement\n    \n    auto compatible=[&](int a, int oa, int b, int ob) -> bool {\n        // String a at offset oa, string b at offset ob on a cyclic line of length 20\n        int ka=S[a].size(), kb=S[b].size();\n        for(int pa=0;pa<ka;pa++){\n            int pos=(oa+pa)%N;\n            for(int pb=0;pb<kb;pb++){\n                int pos2=(ob+pb)%N;\n                if(pos==pos2 && S[a][pa]!=S[b][pb]) return false;\n            }\n        }\n        return true;\n    };\n    \n    // For efficiency, precompute: for string s at offset o, \n    // which positions map to which characters\n    // pos_char[s][o] = array of (pos, char) pairs\n    vector<vector<vector<pair<int,char>>>> pos_char(M);\n    for(int s=0;s<M;s++){\n        int k=S[s].size();\n        pos_char[s].resize(N);\n        for(int o=0;o<N;o++){\n            for(int p=0;p<k;p++)\n                pos_char[s][o].push_back({(o+p)%N, S[s][p]});\n        }\n    }\n    \n    // For faster compatibility: for string s at offset o, create char_at[pos] or -1\n    // Then two placements are compatible if no position has conflicting chars\n    \n    // Greedy clustering approach:\n    // Maintain 40 lines, each with a set of (string, offset) assignments\n    // and a partial character assignment (20 positions)\n    \n    struct Line {\n        char content[20]; // 0 = unknown\n        vector<pair<int,int>> assignments; // (string_idx, offset)\n    };\n    \n    auto tryAssign=[&](Line& line, int s, int o) -> bool {\n        int k=S[s].size();\n        for(int p=0;p<k;p++){\n            int pos=(o+p)%N;\n            if(line.content[pos]!=0 && line.content[pos]!=S[s][p]) return false;\n        }\n        return true;\n    };\n    \n    auto doAssign=[&](Line& line, int s, int o) {\n        int k=S[s].size();\n        for(int p=0;p<k;p++){\n            int pos=(o+p)%N;\n            line.content[pos]=S[s][p];\n        }\n        line.assignments.push_back({s,o});\n    };\n    \n    // Score a line: count how many additional unmatched strings it could match\n    // (strings not yet assigned to any line)\n    \n    int best_tot=0;\n    \n    // Try multiple clustering attempts\n    for(int trial=0; trial<20 && elapsed()<1.5; trial++){\n        mt19937 gen(trial*53+17);\n        \n        vector<Line> lines(40);\n        for(auto&l:lines) memset(l.content,0,20);\n        \n        vector<bool> assigned(M, false);\n        vector<int> order(M);\n        iota(order.begin(),order.end(),0);\n        shuffle(order.begin(),order.end(),gen);\n        // Sort by length desc for better constraints\n        int strat=gen()%3;\n        if(strat==0) stable_sort(order.begin(),order.end(),[&](int a,int b){return S[a].size()>S[b].size();});\n        if(strat==1) stable_sort(order.begin(),order.end(),[&](int a,int b){return S[a].size()<S[b].size();});\n        \n        for(int si:order){\n            if(assigned[si]) continue;\n            // Find best line and offset to assign this string\n            int bestLine=-1, bestOff=-1, bestScore=-1;\n            for(int l=0;l<40;l++){\n                for(int o=0;o<N;o++){\n                    if(!tryAssign(lines[l],si,o)) continue;\n                    // Score: how many positions match existing content\n                    int k=S[si].size();\n                    int score=0;\n                    for(int p=0;p<k;p++){\n                        int pos=(o+p)%N;\n                        if(lines[l].content[pos]==S[si][p]) score+=3;\n                    }\n                    if(score>bestScore){bestScore=score;bestLine=l;bestOff=o;}\n                }\n            }\n            if(bestLine>=0){\n                doAssign(lines[bestLine],si,bestOff);\n                assigned[si]=true;\n            }\n        }\n        \n        // Build grid from lines\n        // Lines 0-19 = rows, lines 20-39 = columns\n        memset(G,0,400);\n        \n        // First assign rows\n        for(int r=0;r<20;r++){\n            for(int j=0;j<20;j++){\n                if(lines[r].content[j]) G[r][j]=lines[r].content[j];\n            }\n        }\n        // Then overlay columns (resolve conflicts by majority or row preference)\n        for(int c=0;c<20;c++){\n            for(int i=0;i<20;i++){\n                char colChar=lines[20+c].content[i];\n                if(colChar){\n                    if(G[i][c]==0) G[i][c]=colChar;\n                    // If conflict, keep row (or could do smarter)\n                }\n            }\n        }\n        // Fill remaining\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++)\n            if(!G[i][j]) G[i][j]='A'+gen()%8;\n        \n        // Count matches\n        int matched=0;\n        for(int s=0;s<M;s++){\n            int k=S[s].size();\n            bool found=false;\n            for(int d=0;d<2&&!found;d++)for(int i=0;i<N&&!found;i++)for(int j=0;j<N&&!found;j++){\n                bool ok=true;\n                if(d==0){for(int p=0;p<k&&ok;p++)if(G[i][(j+p)%N]!=S[s][p])ok=false;}\n                else{for(int p=0;p<k&&ok;p++)if(G[(i+p)%N][j]!=S[s][p])ok=false;}\n                if(ok)found=true;\n            }\n            if(found)matched++;\n        }\n        if(matched>best_tot){best_tot=matched;memcpy(bestG,G,400);}\n    }\n    \n    // Also try greedy init (proven approach)\n    auto greedyInit=[&](mt19937&gen){\n        memset(G,0,400);\n        vector<int>ord(M);iota(ord.begin(),ord.end(),0);shuffle(ord.begin(),ord.end(),gen);\n        int st=gen()%3;\n        if(st==0)stable_sort(ord.begin(),ord.end(),[&](int a,int b){return S[a].size()>S[b].size();});\n        if(st==1)stable_sort(ord.begin(),ord.end(),[&](int a,int b){return S[a].size()<S[b].size();});\n        for(int si:ord){int k=S[si].size();\n            int bs=-1,bd=-1,bi=-1,bj=-1;\n            for(int d=0;d<2;d++)for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                int s2=0;bool ok=true;\n                for(int p=0;p<k;p++){int ci,cj;\n                    if(d==0){ci=i;cj=(j+p)%N;}else{ci=(i+p)%N;cj=j;}\n                    char c=G[ci][cj];if(c==S[si][p])s2+=3;else if(c)ok=false;if(!ok)break;}\n                if(ok&&s2>bs){bs=s2;bd=d;bi=i;bj=j;}}\n            if(bd>=0)for(int p=0;p<k;p++){int ci,cj;\n                if(bd==0){ci=bi;cj=(bj+p)%N;}else{ci=(bi+p)%N;cj=bj;}G[ci][cj]=S[si][p];}}\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(!G[i][j])G[i][j]='A'+gen()%8;};\n    \n    for(int t=0;t<40&&elapsed()<1.8;t++){\n        mt19937 g(t*31+7);greedyInit(g);\n        int matched=0;\n        for(int s=0;s<M;s++){int k=S[s].size();bool f=false;\n            for(int d=0;d<2&&!f;d++)for(int i=0;i<N&&!f;i++)for(int j=0;j<N&&!f;j++){\n                bool ok=true;\n                if(d==0){for(int p=0;p<k&&ok;p++)if(G[i][(j+p)%N]!=S[s][p])ok=false;}\n                else{for(int p=0;p<k&&ok;p++)if(G[(i+p)%N][j]!=S[s][p])ok=false;}\n                if(ok)f=true;}if(f)matched++;}\n        if(matched>best_tot){best_tot=matched;memcpy(bestG,G,400);}\n    }\n    \n    // Phase 2: SA hill climbing\n    memcpy(G,bestG,400);\n    int P=0;\n    vector<int>pS,pD,pI,pJ;\n    vector<vector<int>>c2p(400);\n    for(int s=0;s<M;s++){int k=S[s].size();\n        for(int d=0;d<2;d++)for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            int pid=P++;pS.push_back(s);pD.push_back(d);pI.push_back(i);pJ.push_back(j);\n            for(int p=0;p<k;p++){int ci,cj;\n                if(d==0){ci=i;cj=(j+p)%N;}else{ci=(i+p)%N;cj=j;}\n                c2p[ci*20+cj].push_back(pid);}}}\n    vector<int8_t>pok(P);vector<int>sc(M,0);\n    auto ckp=[&](int pid)->int{int s=pS[pid],k=S[s].size(),si=pI[pid],sj=pJ[pid];const char*ss=S[s].c_str();\n        if(pD[pid]==0){for(int p=0;p<k;p++)if(G[si][(sj+p)%20]!=ss[p])return 0;}\n        else{for(int p=0;p<k;p++)if(G[(si+p)%20][sj]!=ss[p])return 0;}return 1;};\n    fill(sc.begin(),sc.end(),0);for(int p=0;p<P;p++){pok[p]=ckp(p);if(pok[p])sc[pS[p]]++;}\n    int tot=0;for(int s=0;s<M;s++)if(sc[s]>0)tot++;\n    best_tot=tot;memcpy(bestG,G,400);\n    int cB[8000];int8_t cO[8000];int cZ;\n    struct CC{int ci,cj;char oc,nc;};\n    auto apM=[&](CC*cs,int n)->bool{\n        static int cSt[20],cLn[20];int td=0,az=0;\n        for(int i=0;i<n;i++){cSt[i]=az;auto&af=c2p[cs[i].ci*20+cs[i].cj];\n            G[cs[i].ci][cs[i].cj]=cs[i].nc;int lc=0;\n            for(int pid:af){int nv=ckp(pid);if(nv!=pok[pid]){\n                int om=(sc[pS[pid]]>0);sc[pS[pid]]+=nv-pok[pid];int nm=(sc[pS[pid]]>0);\n                td+=nm-om;cB[az]=pid;cO[az]=pok[pid];az++;lc++;pok[pid]=nv;}}cLn[i]=lc;}\n        if(td>=0){tot+=td;if(tot>best_tot){best_tot=tot;memcpy(bestG,G,400);}return true;}\n        for(int i=n-1;i>=0;i--){G[cs[i].ci][cs[i].cj]=cs[i].oc;\n            for(int x=cSt[i]+cLn[i]-1;x>=cSt[i];x--){sc[pS[cB[x]]]+=cO[x]-pok[cB[x]];pok[cB[x]]=cO[x];}}return false;};\n    \n    while(elapsed()<2.75){for(int r=0;r<400;r++){\n        if(rng()%2==0&&tot<M){int si=rng()%M;for(int t=0;t<20&&sc[si]>0;t++)si=rng()%M;\n            if(sc[si]==0){int k=S[si].size();const char*ss=S[si].c_str();\n                int bm=4,bd=-1,bi=-1,bj=-1;\n                for(int d=0;d<2;d++)for(int i=0;i<N;i++)for(int j=0;j<N;j++){int mm=0;\n                    if(d==0){for(int p=0;p<k&&mm<bm;p++)if(G[i][(j+p)%20]!=ss[p])mm++;}\n                    else{for(int p=0;p<k&&mm<bm;p++)if(G[(i+p)%20][j]!=ss[p])mm++;}\n                    if(mm<bm){bm=mm;bd=d;bi=i;bj=j;}if(!mm)goto dn;}\n                dn:if(bm>=1&&bm<=3){CC cs[12];int nc=0;\n                    for(int p=0;p<k;p++){int ci,cj;if(bd==0){ci=bi;cj=(bj+p)%N;}else{ci=(bi+p)%N;cj=bj;}\n                        if(G[ci][cj]!=ss[p])cs[nc++]={ci,cj,G[ci][cj],ss[p]};}apM(cs,nc);}continue;}}\n        int ci=rng()%N,cj=rng()%N;char oc=G[ci][cj],nc='A'+rng()%8;if(nc==oc)continue;\n        auto&af=c2p[ci*20+cj];int dl=0;G[ci][cj]=nc;cZ=0;\n        for(int pid:af){int nv=ckp(pid);if(nv!=pok[pid]){\n            int om=(sc[pS[pid]]>0);sc[pS[pid]]+=nv-pok[pid];int nm=(sc[pS[pid]]>0);\n            dl+=nm-om;cB[cZ]=pid;cO[cZ]=pok[pid];cZ++;pok[pid]=nv;}}\n        if(dl>=0){tot+=dl;if(tot>best_tot){best_tot=tot;memcpy(bestG,G,400);}}\n        else{G[ci][cj]=oc;for(int x=0;x<cZ;x++){sc[pS[cB[x]]]+=cO[x]-pok[cB[x]];pok[cB[x]]=cO[x];}}}}\n    memcpy(G,bestG,400);\n    for(int i=0;i<N;i++){for(int j=0;j<N;j++)cout<<G[i][j];cout<<'\\n';}\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nchar grid[70][70];\nint costg[70][70];\nvector<pair<int,int>> vis_from[70][70];\nint dx[]={-1,1,0,0}, dy[]={0,0,-1,1};\n\nchrono::steady_clock::time_point start_time;\nlong long elapsed() {\n    return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n}\n\nstruct DijkData {\n    int dist[70][70];\n    pair<short,short> par[70][70];\n};\n\nunordered_map<int, DijkData*> dijk_cache;\n\nint encode(int i, int j) { return i * 70 + j; }\n\nDijkData* get_dijkstra(int si2, int sj2) {\n    int key = encode(si2, sj2);\n    auto it = dijk_cache.find(key);\n    if (it != dijk_cache.end()) return it->second;\n    \n    // Memory limit: keep cache manageable\n    if (dijk_cache.size() > 500) {\n        for (auto& [k,v] : dijk_cache) delete v;\n        dijk_cache.clear();\n    }\n    \n    auto* res = new DijkData();\n    for (int i=0;i<N;i++) for (int j=0;j<N;j++) { res->dist[i][j] = INT_MAX; res->par[i][j] = {-1,-1}; }\n    priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n    res->dist[si2][sj2] = 0;\n    pq.push({0, si2, sj2});\n    while (!pq.empty()) {\n        auto [dd, ci, cj] = pq.top(); pq.pop();\n        if (dd > res->dist[ci][cj]) continue;\n        for (int k = 0; k < 4; k++) {\n            int ni = ci+dx[k], nj = cj+dy[k];\n            if (ni<0||ni>=N||nj<0||nj>=N||grid[ni][nj]=='#') continue;\n            int nd = dd + costg[ni][nj];\n            if (nd < res->dist[ni][nj]) {\n                res->dist[ni][nj] = nd;\n                res->par[ni][nj] = {(short)ci, (short)cj};\n                pq.push({nd, ni, nj});\n            }\n        }\n    }\n    dijk_cache[key] = res;\n    return res;\n}\n\nvector<pair<int,int>> trace_path(DijkData* dr, int s, int t, int ti, int tj) {\n    vector<pair<int,int>> pts;\n    if (dr->dist[ti][tj] == INT_MAX) return pts;\n    int ci = ti, cj = tj;\n    while (!(ci==s && cj==t)) {\n        pts.push_back({ci, cj});\n        auto [pi, pj] = dr->par[ci][cj];\n        ci = pi; cj = pj;\n    }\n    reverse(pts.begin(), pts.end());\n    return pts;\n}\n\nstring path_to_string(const vector<pair<int,int>>& route) {\n    string result;\n    for (int i = 1; i < (int)route.size(); i++) {\n        int di = route[i].first - route[i-1].first;\n        int dj = route[i].second - route[i-1].second;\n        if (di==-1) result+='U';\n        else if (di==1) result+='D';\n        else if (dj==-1) result+='L';\n        else result+='R';\n    }\n    return result;\n}\n\nint route_cost(const vector<pair<int,int>>& route) {\n    int t = 0;\n    for (int i = 1; i < (int)route.size(); i++) t += costg[route[i].first][route[i].second];\n    return t;\n}\n\nstatic int mark_arr[70][70];\nstatic int mark_id_g = 0;\n\nbool check_full_coverage(const vector<pair<int,int>>& route) {\n    mark_id_g++;\n    for (auto& [pi,pj] : route)\n        for (auto& [vi,vj] : vis_from[pi][pj]) mark_arr[vi][vj] = mark_id_g;\n    for (int r=0;r<N;r++) for (int c=0;c<N;c++)\n        if (grid[r][c]!='#' && mark_arr[r][c]!=mark_id_g) return false;\n    return true;\n}\n\nvector<pair<int,int>> build_route(const vector<pair<int,int>>& wps) {\n    vector<pair<int,int>> full_route;\n    full_route.push_back(wps[0]);\n    for (int w = 1; w < (int)wps.size(); w++) {\n        auto* dr = get_dijkstra(full_route.back().first, full_route.back().second);\n        auto seg = trace_path(dr, full_route.back().first, full_route.back().second, wps[w].first, wps[w].second);\n        for (auto& p : seg) full_route.push_back(p);\n    }\n    return full_route;\n}\n\nint wp_cost(const vector<pair<int,int>>& wps) {\n    int total = 0;\n    for (int i = 0; i+1 < (int)wps.size(); i++) {\n        auto* dr = get_dijkstra(wps[i].first, wps[i].second);\n        total += dr->dist[wps[i+1].first][wps[i+1].second];\n    }\n    return total;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    start_time = chrono::steady_clock::now();\n    \n    cin >> N >> si >> sj;\n    for (int i=0;i<N;i++){\n        string s; cin >> s;\n        for (int j=0;j<N;j++){\n            grid[i][j]=s[j];\n            if (s[j]!='#') costg[i][j]=s[j]-'0';\n        }\n    }\n    \n    for (int i=0;i<N;i++) for (int j=0;j<N;j++) {\n        if (grid[i][j]=='#') continue;\n        vis_from[i][j].push_back({i,j});\n        for (int dj2=j-1;dj2>=0;dj2--){ if(grid[i][dj2]=='#') break; vis_from[i][j].push_back({i,dj2}); }\n        for (int dj2=j+1;dj2<N;dj2++){ if(grid[i][dj2]=='#') break; vis_from[i][j].push_back({i,dj2}); }\n        for (int di2=i-1;di2>=0;di2--){ if(grid[di2][j]=='#') break; vis_from[i][j].push_back({di2,j}); }\n        for (int di2=i+1;di2<N;di2++){ if(grid[di2][j]=='#') break; vis_from[i][j].push_back({di2,j}); }\n    }\n    \n    bool seen[70][70];\n    memset(seen, false, sizeof(seen));\n    int ci=si, cj=sj;\n    for (auto& [vi,vj]: vis_from[ci][cj]) seen[vi][vj]=true;\n    \n    vector<pair<int,int>> waypoints;\n    waypoints.push_back({si, sj});\n    \n    static int vm[70][70];\n    static int vmid = 0;\n    \n    while (true) {\n        int unseen_count = 0;\n        for (int i=0;i<N;i++) for (int j=0;j<N;j++) if(grid[i][j]!='#' && !seen[i][j]) unseen_count++;\n        if (unseen_count == 0) break;\n        \n        auto* dr = get_dijkstra(ci, cj);\n        \n        struct Cand { int i, j; double score; };\n        vector<Cand> candidates;\n        for (int i=0;i<N;i++) for (int j=0;j<N;j++) {\n            if (grid[i][j]=='#' || dr->dist[i][j]==INT_MAX) continue;\n            int uc=0;\n            for (auto& [vi,vj]: vis_from[i][j]) if(!seen[vi][vj]) uc++;\n            if (uc==0) continue;\n            double score = (double)uc / max(1, dr->dist[i][j]);\n            candidates.push_back({i, j, score});\n        }\n        \n        sort(candidates.begin(), candidates.end(), [](const Cand& a, const Cand& b){ return a.score > b.score; });\n        \n        int bestI=-1, bestJ=-1;\n        double bestScore = -1;\n        int eval_count = min((int)candidates.size(), 30);\n        \n        for (int idx = 0; idx < eval_count; idx++) {\n            auto& c = candidates[idx];\n            auto path = trace_path(dr, ci, cj, c.i, c.j);\n            vmid++;\n            int path_vis = 0;\n            for (auto& [pi,pj] : path)\n                for (auto& [vi,vj] : vis_from[pi][pj])\n                    if (!seen[vi][vj] && vm[vi][vj] != vmid) { vm[vi][vj] = vmid; path_vis++; }\n            double score = (double)path_vis / max(1, dr->dist[c.i][c.j]);\n            if (score > bestScore) { bestScore = score; bestI = c.i; bestJ = c.j; }\n        }\n        \n        if (bestI==-1 && !candidates.empty()) { bestI = candidates[0].i; bestJ = candidates[0].j; }\n        if (bestI==-1) break;\n        \n        auto path = trace_path(dr, ci, cj, bestI, bestJ);\n        for (auto& [pi,pj] : path)\n            for (auto& [vi,vj]: vis_from[pi][pj]) seen[vi][vj]=true;\n        ci = bestI; cj = bestJ;\n        waypoints.push_back({ci, cj});\n    }\n    \n    waypoints.push_back({si, sj});\n    \n    auto best_route = build_route(waypoints);\n    int best_cost = route_cost(best_route);\n    auto best_wps = waypoints;\n    \n    // Waypoint removal - multiple passes\n    for (int iter = 0; iter < 50 && elapsed() < 1400; iter++) {\n        bool improved = false;\n        for (int w = (int)best_wps.size()-2; w >= 1 && elapsed() < 1400; w--) {\n            // Quick cost check: removing w means connecting w-1 to w+1\n            auto* dr = get_dijkstra(best_wps[w-1].first, best_wps[w-1].second);\n            int new_seg = dr->dist[best_wps[w+1].first][best_wps[w+1].second];\n            auto* dr1 = get_dijkstra(best_wps[w-1].first, best_wps[w-1].second);\n            int old_seg1 = dr1->dist[best_wps[w].first][best_wps[w].second];\n            auto* dr2 = get_dijkstra(best_wps[w].first, best_wps[w].second);\n            int old_seg2 = dr2->dist[best_wps[w+1].first][best_wps[w+1].second];\n            \n            if (new_seg > old_seg1 + old_seg2) continue; // Can't be shorter\n            \n            vector<pair<int,int>> new_wps;\n            for (int i = 0; i < (int)best_wps.size(); i++)\n                if (i != w) new_wps.push_back(best_wps[i]);\n            auto new_route = build_route(new_wps);\n            int new_cost = route_cost(new_route);\n            if (new_cost < best_cost && check_full_coverage(new_route)) {\n                best_wps = new_wps;\n                best_route = new_route;\n                best_cost = new_cost;\n                improved = true;\n                break;\n            }\n        }\n        if (!improved) break;\n    }\n    \n    // 2-opt on waypoints\n    for (int iter = 0; iter < 10 && elapsed() < 1900; iter++) {\n        bool improved = false;\n        int nw = (int)best_wps.size();\n        for (int i = 1; i < nw-2 && elapsed() < 1900; i++) {\n            for (int j = i+1; j < nw-1 && elapsed() < 1900; j++) {\n                // Quick cost estimate\n                auto* d1 = get_dijkstra(best_wps[i-1].first, best_wps[i-1].second);\n                auto* d2 = get_dijkstra(best_wps[j].first, best_wps[j].second);\n                int old_c1 = d1->dist[best_wps[i].first][best_wps[i].second];\n                int new_c1 = d1->dist[best_wps[j].first][best_wps[j].second];\n                int old_c2 = (j+1<nw) ? get_dijkstra(best_wps[j].first,best_wps[j].second)->dist[best_wps[j+1].first][best_wps[j+1].second] : 0;\n                int new_c2 = (j+1<nw) ? get_dijkstra(best_wps[i].first,best_wps[i].second)->dist[best_wps[j+1].first][best_wps[j+1].second] : 0;\n                \n                if (new_c1 + new_c2 >= old_c1 + old_c2 + 10) continue; // unlikely to help\n                \n                vector<pair<int,int>> new_wps = best_wps;\n                reverse(new_wps.begin()+i, new_wps.begin()+j+1);\n                auto new_route = build_route(new_wps);\n                int new_cost = route_cost(new_route);\n                if (new_cost < best_cost && check_full_coverage(new_route)) {\n                    best_wps = new_wps;\n                    best_route = new_route;\n                    best_cost = new_cost;\n                    improved = true;\n                    break;\n                }\n            }\n            if (improved) break;\n        }\n        if (!improved) break;\n    }\n    \n    // Or-opt\n    for (int iter = 0; iter < 5 && elapsed() < 2300; iter++) {\n        bool improved = false;\n        int nw = (int)best_wps.size();\n        for (int w = 1; w < nw-1 && elapsed() < 2300; w++) {\n            for (int pos = 1; pos < nw-1 && elapsed() < 2300; pos++) {\n                if (pos == w || pos == w+1) continue;\n                vector<pair<int,int>> new_wps;\n                for (int i = 0; i < nw; i++) if (i != w) new_wps.push_back(best_wps[i]);\n                int ip = pos < w ? pos : pos-1;\n                new_wps.insert(new_wps.begin()+ip, best_wps[w]);\n                auto new_route = build_route(new_wps);\n                int new_cost = route_cost(new_route);\n                if (new_cost < best_cost && check_full_coverage(new_route)) {\n                    best_wps = new_wps;\n                    best_route = new_route;\n                    best_cost = new_cost;\n                    improved = true;\n                    break;\n                }\n            }\n            if (improved) break;\n        }\n        if (!improved) break;\n    }\n    \n    // Full route shortcutting with random sampling\n    mt19937 rng(12345);\n    while (elapsed() < 2850) {\n        bool improved = false;\n        int rs = (int)best_route.size();\n        if (rs < 4) break;\n        \n        // Systematic pass\n        for (int step = max(3, rs/3); step >= 3; step = max(step-1, step*2/3)) {\n            if (step < 3) break;\n            if (elapsed() > 2850) break;\n            int stride = max(1, step/4);\n            for (int i = 0; i + step < rs && elapsed() < 2850; i += stride) {\n                int j = i + step;\n                auto* dr = get_dijkstra(best_route[i].first, best_route[i].second);\n                int old_cost_seg = 0;\n                for (int k=i+1;k<=j;k++) old_cost_seg += costg[best_route[k].first][best_route[k].second];\n                int new_dist = dr->dist[best_route[j].first][best_route[j].second];\n                \n                if (new_dist >= old_cost_seg) continue;\n                \n                auto shortcut = trace_path(dr, best_route[i].first, best_route[i].second, best_route[j].first, best_route[j].second);\n                int new_cost_seg = 0;\n                for (auto& [pi,pj] : shortcut) new_cost_seg += costg[pi][pj];\n                \n                if (new_cost_seg >= old_cost_seg) continue;\n                \n                vector<pair<int,int>> new_route;\n                new_route.reserve(rs);\n                for (int k=0;k<=i;k++) new_route.push_back(best_route[k]);\n                for (auto& p : shortcut) new_route.push_back(p);\n                for (int k=j+1;k<rs;k++) new_route.push_back(best_route[k]);\n                \n                if (check_full_coverage(new_route)) {\n                    best_route = new_route;\n                    best_cost = route_cost(best_route);\n                    improved = true;\n                    break;\n                }\n            }\n            if (improved) break;\n        }\n        if (!improved) {\n            // Random sampling\n            int tries = 0;\n            while (elapsed() < 2850 && tries < 100) {\n                tries++;\n                int rs2 = (int)best_route.size();\n                if (rs2 < 4) break;\n                int i = rng() % (rs2 - 2);\n                int j = i + 2 + rng() % min(rs2 - i - 2, max(1, rs2/3));\n                if (j >= rs2) j = rs2 - 1;\n                \n                auto* dr = get_dijkstra(best_route[i].first, best_route[i].second);\n                int old_cost_seg = 0;\n                for (int k=i+1;k<=j;k++) old_cost_seg += costg[best_route[k].first][best_route[k].second];\n                int new_dist = dr->dist[best_route[j].first][best_route[j].second];\n                \n                if (new_dist >= old_cost_seg) continue;\n                \n                auto shortcut = trace_path(dr, best_route[i].first, best_route[i].second, best_route[j].first, best_route[j].second);\n                int new_cost_seg = 0;\n                for (auto& [pi,pj] : shortcut) new_cost_seg += costg[pi][pj];\n                if (new_cost_seg >= old_cost_seg) continue;\n                \n                vector<pair<int,int>> new_route;\n                new_route.reserve(rs2);\n                for (int k=0;k<=i;k++) new_route.push_back(best_route[k]);\n                for (auto& p : shortcut) new_route.push_back(p);\n                for (int k=j+1;k<rs2;k++) new_route.push_back(best_route[k]);\n                \n                if (check_full_coverage(new_route)) {\n                    best_route = new_route;\n                    best_cost = route_cost(best_route);\n                    improved = true;\n                    break;\n                }\n            }\n            if (!improved) break;\n        }\n    }\n    \n    cout << path_to_string(best_route) << endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    int N,M,K,R;\n    scanf(\"%d%d%d%d\",&N,&M,&K,&R);\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    for(int i=0;i<N;i++) for(int j=0;j<K;j++) scanf(\"%d\",&d[i][j]);\n    \n    vector<vector<int>> deps(N), rdeps(N);\n    for(int i=0;i<R;i++){\n        int u,v; scanf(\"%d%d\",&u,&v); u--;v--;\n        deps[v].push_back(u);\n        rdeps[u].push_back(v);\n    }\n    \n    // Topological order (precompute once)\n    vector<int> topo_order;\n    {\n        vector<int> indeg(N,0);\n        for(int i=0;i<N;i++) for(int j:rdeps[i]) indeg[j]++;\n        queue<int> q;\n        for(int i=0;i<N;i++) if(indeg[i]==0) q.push(i);\n        while(!q.empty()){int u=q.front();q.pop();topo_order.push_back(u);for(int v:rdeps[u])if(--indeg[v]==0)q.push(v);}\n    }\n    \n    double init_skill = 35.0 / sqrt((double)K) * sqrt(2.0/M_PI);\n    vector<vector<double>> s_est(M, vector<double>(K, init_skill));\n    vector<vector<double>> s_low(M, vector<double>(K, 0.0));\n    \n    vector<int> task_status(N, -1);\n    vector<int> member_task(M, -1);\n    vector<int> member_start(M, -1);\n    \n    struct Obs { int task; int t_obs; };\n    vector<vector<Obs>> all_obs(M);\n    \n    auto est_time_val = [&](int task, int member) -> double {\n        double w = 0;\n        for(int k=0;k<K;k++) w += max(0.0, (double)d[task][k] - s_est[member][k]);\n        return max(1.0, w);\n    };\n    \n    auto can_start = [&](int task) -> bool {\n        if(task_status[task]!=-1) return false;\n        for(int dep : deps[task]) if(task_status[dep]!=1) return false;\n        return true;\n    };\n    \n    // Use average of top-3 member times for CP estimation (more realistic)\n    auto compute_cp = [&]() -> vector<double> {\n        vector<double> cp(N, 0.0);\n        for(int i=N-1;i>=0;i--){\n            int u = topo_order[i];\n            if(task_status[u]==1){cp[u]=0;continue;}\n            // Use median-ish estimate: average of top 3 best members\n            double times[M];\n            for(int j=0;j<M;j++) times[j] = est_time_val(u,j);\n            sort(times, times+M);\n            double avg_t = 0;\n            int cnt = min(3, M);\n            for(int j=0;j<cnt;j++) avg_t += times[j];\n            avg_t /= cnt;\n            \n            cp[u]=avg_t;\n            for(int v:rdeps[u]) cp[u]=max(cp[u], avg_t+cp[v]);\n        }\n        return cp;\n    };\n    \n    auto hungarian_min = [&](vector<vector<double>>& cost, int n) -> vector<int> {\n        vector<double> u(n+1,0), v(n+1,0);\n        vector<int> p(n+1,0), way(n+1,0);\n        for(int i=1;i<=n;i++){\n            p[0]=i; int j0=0;\n            vector<double> minv(n+1,1e18);\n            vector<bool> used(n+1,false);\n            do {\n                used[j0]=true;\n                int i0=p[j0],j1=-1;\n                double delta=1e18;\n                for(int j=1;j<=n;j++){\n                    if(!used[j]){\n                        double cur=cost[i0-1][j-1]-u[i0]-v[j];\n                        if(cur<minv[j]){minv[j]=cur;way[j]=j0;}\n                        if(minv[j]<delta){delta=minv[j];j1=j;}\n                    }\n                }\n                for(int j=0;j<=n;j++){\n                    if(used[j]){u[p[j]]+=delta;v[j]-=delta;}\n                    else minv[j]-=delta;\n                }\n                j0=j1;\n            } while(p[j0]!=0);\n            do{int j1=way[j0];p[j0]=p[j1];j0=j1;}while(j0);\n        }\n        vector<int> ans(n);\n        for(int j=1;j<=n;j++) ans[p[j]-1]=j-1;\n        return ans;\n    };\n    \n    auto batch_reestimate = [&](int member) {\n        auto& obs = all_obs[member];\n        if(obs.size() < 2) return;\n        \n        vector<double>& s = s_est[member];\n        \n        auto compute_loss = [&]() -> double {\n            double loss = 0;\n            for(auto& ob : obs) {\n                double w = 0;\n                for(int k=0;k<K;k++) w += max(0.0, (double)d[ob.task][k] - s[k]);\n                double target = (ob.t_obs == 1) ? 0.0 : (double)ob.t_obs;\n                double diff = w - target;\n                if(abs(diff) <= 4.0) loss += diff * diff;\n                else loss += 8.0 * abs(diff) - 16.0;\n            }\n            return loss;\n        };\n        \n        double best_loss = compute_loss();\n        \n        // Multi-scale coordinate descent\n        vector<double> deltas = {-4.0, -2.0, -1.0, -0.5, -0.2, -0.1, 0.1, 0.2, 0.5, 1.0, 2.0, 4.0};\n        \n        for(int iter=0; iter<30; iter++){\n            bool improved = false;\n            for(int k=0;k<K;k++){\n                double orig = s[k];\n                double best_val = orig;\n                \n                for(double delta : deltas){\n                    double nv = orig + delta;\n                    nv = max(nv, s_low[member][k]);\n                    nv = min(nv, 60.0);\n                    nv = max(nv, 0.0);\n                    if(abs(nv - best_val) < 1e-9) continue;\n                    s[k] = nv;\n                    double l = compute_loss();\n                    if(l < best_loss - 1e-9){\n                        best_loss = l;\n                        best_val = nv;\n                        improved = true;\n                    }\n                }\n                s[k] = best_val;\n            }\n            if(!improved) break;\n        }\n    };\n    \n    auto update_skills = [&](int member, int task, int t_obs) {\n        // Quick online update first\n        if(t_obs == 1) {\n            for(int k=0;k<K;k++){\n                s_low[member][k] = max(s_low[member][k], (double)d[task][k]);\n                s_est[member][k] = max(s_est[member][k], (double)d[task][k]);\n            }\n        } else {\n            double w_target = (double)t_obs;\n            double w_cur = 0;\n            vector<int> active_k;\n            for(int k=0;k<K;k++){\n                double gap = (double)d[task][k] - s_est[member][k];\n                if(gap > 0){w_cur += gap; active_k.push_back(k);}\n            }\n            if(active_k.empty()){\n                double total_d = 0;\n                for(int k=0;k<K;k++) total_d += max(1,d[task][k]);\n                for(int k=0;k<K;k++){\n                    if(d[task][k]>0){\n                        double frac = (double)d[task][k]/total_d;\n                        double new_s = (double)d[task][k] - w_target*frac;\n                        s_est[member][k] = s_est[member][k]*0.6 + new_s*0.4;\n                        s_est[member][k] = max(s_est[member][k], s_low[member][k]);\n                    }\n                }\n            } else {\n                double ratio = w_target/w_cur;\n                for(int k:active_k){\n                    double gap = (double)d[task][k]-s_est[member][k];\n                    double new_s = (double)d[task][k] - gap*ratio;\n                    s_est[member][k] = s_est[member][k]*0.65 + new_s*0.35;\n                    s_est[member][k] = max(s_est[member][k], s_low[member][k]);\n                    s_est[member][k] = max(s_est[member][k], 0.0);\n                }\n            }\n        }\n        \n        all_obs[member].push_back({task, t_obs});\n        // Always batch reestimate when we have enough data\n        if(all_obs[member].size() >= 2){\n            batch_reestimate(member);\n        }\n    };\n    \n    // Count how many descendants each task has (for tie-breaking)\n    vector<int> n_desc(N, 0);\n    for(int i=N-1;i>=0;i--){\n        int u = topo_order[i];\n        for(int v:rdeps[u]) n_desc[u] += 1 + n_desc[v];\n    }\n    \n    for(int day=1; day<=2000; day++){\n        vector<double> cp = compute_cp();\n        \n        vector<int> free_members;\n        for(int j=0;j<M;j++) if(member_task[j]==-1) free_members.push_back(j);\n        int fm = free_members.size();\n        \n        vector<int> avail_tasks;\n        for(int i=0;i<N;i++) if(can_start(i)) avail_tasks.push_back(i);\n        int at = avail_tasks.size();\n        \n        // Sort by CP descending, break ties by number of descendants\n        sort(avail_tasks.begin(), avail_tasks.end(), [&](int a, int b){\n            if(abs(cp[a]-cp[b]) > 0.5) return cp[a]>cp[b];\n            return n_desc[a]>n_desc[b];\n        });\n        \n        vector<pair<int,int>> assignments;\n        \n        if(fm > 0 && at > 0){\n            int n_cand = min(at, fm * 3);\n            n_cand = min(n_cand, 50);\n            n_cand = max(n_cand, min(at, fm));\n            \n            int n = max(n_cand, fm);\n            vector<vector<double>> cost(n, vector<double>(n, 0.0));\n            \n            double max_cp_val = 0;\n            for(int i=0;i<n_cand;i++) max_cp_val = max(max_cp_val, cp[avail_tasks[i]]);\n            \n            for(int i=0;i<n_cand;i++){\n                for(int j=0;j<fm;j++){\n                    double t = est_time_val(avail_tasks[i], free_members[j]);\n                    // Incentivize critical tasks\n                    cost[i][j] = t - cp[avail_tasks[i]] * 0.1;\n                }\n                for(int j=fm;j<n;j++) cost[i][j] = 300.0;\n            }\n            for(int i=n_cand;i<n;i++)\n                for(int j=0;j<n;j++) cost[i][j] = 0.0;\n            \n            auto asgn = hungarian_min(cost, n);\n            \n            set<int> used_m;\n            for(int i=0;i<n_cand;i++){\n                int j = asgn[i];\n                if(j < fm && !used_m.count(j)){\n                    used_m.insert(j);\n                    int task = avail_tasks[i];\n                    int mem = free_members[j];\n                    assignments.push_back({mem, task});\n                    task_status[task]=0;\n                    member_task[mem]=task;\n                    member_start[mem]=day;\n                }\n            }\n            \n            // Fill remaining\n            for(int i=0;i<at && (int)used_m.size()<fm;i++){\n                int task = avail_tasks[i];\n                if(task_status[task]!=-1) continue;\n                int best_m=-1; double best_t=1e18;\n                for(int jj=0;jj<fm;jj++){\n                    if(used_m.count(jj)) continue;\n                    double t = est_time_val(task, free_members[jj]);\n                    if(t<best_t){best_t=t;best_m=jj;}\n                }\n                if(best_m>=0){\n                    used_m.insert(best_m);\n                    assignments.push_back({free_members[best_m], task});\n                    task_status[task]=0;\n                    member_task[free_members[best_m]]=task;\n                    member_start[free_members[best_m]]=day;\n                }\n            }\n        }\n        \n        printf(\"%d\",(int)assignments.size());\n        for(auto&[a,b]:assignments) printf(\" %d %d\",a+1,b+1);\n        printf(\"\\n\");\n        fflush(stdout);\n        \n        int n_done; scanf(\"%d\",&n_done);\n        if(n_done==-1) return 0;\n        for(int i=0;i<n_done;i++){\n            int f; scanf(\"%d\",&f); f--;\n            int task=member_task[f];\n            int t_obs=day-member_start[f]+1;\n            task_status[task]=1;\n            member_task[f]=-1;\n            update_skills(f, task, t_obs);\n        }\n    }\n    \n    int dummy; scanf(\"%d\",&dummy);\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto t0=chrono::steady_clock::now();\n    auto elapsed=[&](){return chrono::duration<double>(chrono::steady_clock::now()-t0).count();};\n    \n    const int N=1000, M=50, K=2*M;\n    vector<int> a(N),b(N),c(N),d(N);\n    for(int i=0;i<N;i++) cin>>a[i]>>b[i]>>c[i]>>d[i];\n    \n    auto md=[](int x1,int y1,int x2,int y2)->int{return abs(x1-x2)+abs(y1-y2);};\n    \n    vector<double> sc(N);\n    for(int i=0;i<N;i++){\n        sc[i] = md(400,400,a[i],b[i]) + md(a[i],b[i],c[i],d[i]) + md(c[i],d[i],400,400);\n    }\n    vector<int> sidx(N);\n    iota(sidx.begin(),sidx.end(),0);\n    sort(sidx.begin(),sidx.end(),[&](int i,int j){return sc[i]<sc[j];});\n    \n    vector<int> chosen(sidx.begin(),sidx.begin()+M);\n    \n    mt19937 rng(42);\n    vector<int> px(K),py(K);\n    \n    auto setupCoords=[&](){\n        for(int i=0;i<M;i++){\n            px[2*i]=a[chosen[i]]; py[2*i]=b[chosen[i]];\n            px[2*i+1]=c[chosen[i]]; py[2*i+1]=d[chosen[i]];\n        }\n    };\n    \n    auto gdist=[&](int u, int v)->int{\n        int x1=u<0?400:px[u], y1=u<0?400:py[u];\n        int x2=v<0?400:px[v], y2=v<0?400:py[v];\n        return abs(x1-x2)+abs(y1-y2);\n    };\n    \n    auto greedyRoute=[&]()->vector<int>{\n        vector<int> route;\n        vector<bool> visited(K,false);\n        vector<bool> picked(M,false);\n        int cx=400,cy=400;\n        for(int step=0;step<K;step++){\n            int best=-1, bestd=INT_MAX;\n            for(int j=0;j<K;j++){\n                if(visited[j]) continue;\n                int ord=j/2; bool isDel=(j%2==1);\n                if(isDel && !picked[ord]) continue;\n                int d2=md(cx,cy,px[j],py[j]);\n                if(d2<bestd){bestd=d2;best=j;}\n            }\n            visited[best]=true;\n            if(best%2==0) picked[best/2]=true;\n            route.push_back(best);\n            cx=px[best]; cy=py[best];\n        }\n        return route;\n    };\n    \n    auto calcCost=[&](vector<int>& r)->int{\n        int t=gdist(-1,r[0]);\n        for(int i=0;i+1<K;i++) t+=gdist(r[i],r[i+1]);\n        t+=gdist(r.back(),-1);\n        return t;\n    };\n    \n    auto checkFeasible=[&](vector<int>& r)->bool{\n        vector<int> pos(K);\n        for(int i=0;i<K;i++) pos[r[i]]=i;\n        for(int i=0;i<M;i++) if(pos[2*i]>pos[2*i+1]) return false;\n        return true;\n    };\n    \n    setupCoords();\n    vector<int> route=greedyRoute();\n    int curCost=calcCost(route);\n    \n    vector<int> bestRoute=route;\n    vector<int> bestChosen=chosen;\n    int bestGlobalCost=curCost;\n    \n    // SA on route\n    auto optimizeRoute=[&](vector<int>& rt, double tl)->int{\n        int cost=calcCost(rt);\n        vector<int> pos(K);\n        for(int i=0;i<K;i++) pos[rt[i]]=i;\n        \n        int localBestCost=cost;\n        vector<int> localBestRoute=rt;\n        \n        while(elapsed()<tl){\n            double ratio=(tl-elapsed())/(tl-0.0);\n            if(ratio<0) break;\n            double temp=150.0*ratio;\n            \n            // Do a batch\n            for(int iter=0;iter<500;iter++){\n                int op=rng()%10;\n                \n                if(op<6){\n                    // 2-opt\n                    int i=rng()%K, j=rng()%K;\n                    if(i>j) swap(i,j);\n                    if(i==j||j-i>=K-1) continue;\n                    \n                    int pI=(i==0)?-1:rt[i-1];\n                    int nJ=(j==K-1)?-1:rt[j+1];\n                    int delta=gdist(pI,rt[j])+gdist(rt[i],nJ)-gdist(pI,rt[i])-gdist(rt[j],nJ);\n                    \n                    bool accept=(delta<0)||(temp>0.01 && (rng()%1000000)<1000000.0*exp(-(double)delta/temp));\n                    if(!accept) continue;\n                    \n                    // Check feasibility\n                    bool ok=true;\n                    for(int p=i;p<=j&&ok;p++){\n                        int node=rt[p];\n                        int ord=node/2;\n                        int partner=(node%2==0)?node+1:node-1;\n                        int pp=pos[partner];\n                        int np=i+j-p;\n                        if(pp>=i && pp<=j){\n                            int npp=i+j-pp;\n                            if(node%2==0){ if(np>=npp) ok=false; }\n                            else { if(np<=npp) ok=false; }\n                        } else {\n                            if(node%2==0){ if(np>=pp) ok=false; }\n                            else { if(np<=pp) ok=false; }\n                        }\n                    }\n                    if(ok){\n                        reverse(rt.begin()+i,rt.begin()+j+1);\n                        for(int p=i;p<=j;p++) pos[rt[p]]=p;\n                        cost+=delta;\n                        if(cost<localBestCost){localBestCost=cost;localBestRoute=rt;}\n                    }\n                } else {\n                    // Relocate\n                    int i=rng()%K;\n                    int node=rt[i];\n                    int ord=node/2;\n                    bool isDel=(node%2==1);\n                    int partnerPos=pos[isDel?(2*ord):(2*ord+1)];\n                    \n                    int pI=(i==0)?-1:rt[i-1];\n                    int nI=(i==K-1)?-1:rt[i+1];\n                    int remSave=gdist(pI,node)+gdist(node,nI)-gdist(pI,nI);\n                    \n                    // Pick random target\n                    int j=rng()%(K-1);\n                    // j is insert position in the array after removal\n                    // Adjust: after removing pos i, array shrinks\n                    // Precedence: pickup before delivery\n                    int adjPartner=partnerPos>(i)?partnerPos-1:partnerPos;\n                    if(isDel){ if(j<=adjPartner) continue; }\n                    else { if(j>adjPartner) continue; }\n                    \n                    // Compute insert cost\n                    // Build temp array mentally\n                    // After removing i, element at new pos j-1 and j\n                    // We need actual nodes at those positions\n                    // Remove rt[i], positions shift\n                    int pJ,nJ_node;\n                    {\n                        // Map j in reduced array back\n                        int rj=j; // position in reduced array\n                        if(rj==0) pJ=-1;\n                        else {\n                            int orig=rj; if(orig>=i) orig++; \n                            // Wait, let me just be careful\n                            // reduced[k] = rt[k] if k<i, rt[k+1] if k>=i\n                            int prevOrig=(rj-1<i)?(rj-1):(rj);\n                            pJ=rt[prevOrig];\n                        }\n                        if(rj==K-1) nJ_node=-1;\n                        else {\n                            int nextOrig=(rj<i)?rj:(rj+1);\n                            nJ_node=rt[nextOrig];\n                        }\n                    }\n                    int insCost=gdist(pJ,node)+gdist(node,nJ_node)-gdist(pJ,nJ_node);\n                    int delta=insCost-remSave;\n                    \n                    bool accept=(delta<0)||(temp>0.01 && (rng()%1000000)<1000000.0*exp(-(double)delta/temp));\n                    if(!accept) continue;\n                    \n                    // Actually do it\n                    rt.erase(rt.begin()+i);\n                    int insertPos=j;\n                    rt.insert(rt.begin()+insertPos,node);\n                    for(int p=0;p<K;p++) pos[rt[p]]=p;\n                    cost+=delta;\n                    if(cost<localBestCost){localBestCost=cost;localBestRoute=rt;}\n                }\n            }\n            // Periodically fix cost drift\n            cost=calcCost(rt);\n        }\n        rt=localBestRoute;\n        return localBestCost;\n    };\n    \n    curCost=optimizeRoute(route,0.8);\n    if(curCost<bestGlobalCost){\n        bestGlobalCost=curCost; bestRoute=route; bestChosen=chosen;\n    }\n    \n    // Try order swaps\n    set<int> inSet(chosen.begin(),chosen.end());\n    vector<int> notChosen;\n    for(int i=0;i<N;i++) if(!inSet.count(i)) notChosen.push_back(i);\n    \n    while(elapsed()<1.85){\n        int ci=rng()%M, ni=rng()%(int)notChosen.size();\n        int oldOrd=chosen[ci], newOrd=notChosen[ni];\n        chosen[ci]=newOrd;\n        setupCoords();\n        auto rt=greedyRoute();\n        double budget=min(elapsed()+0.08, 1.85);\n        int c=optimizeRoute(rt,budget);\n        if(c<bestGlobalCost){\n            bestGlobalCost=c; bestRoute=rt; bestChosen=chosen;\n            inSet.erase(oldOrd); inSet.insert(newOrd);\n            notChosen[ni]=oldOrd;\n        } else {\n            chosen[ci]=oldOrd;\n        }\n    }\n    \n    // Restore best\n    chosen=bestChosen;\n    setupCoords();\n    route=bestRoute;\n    \n    // Validate\n    assert(checkFeasible(route));\n    assert((int)route.size()==K);\n    \n    cout<<M;\n    for(int i=0;i<M;i++) cout<<\" \"<<chosen[i]+1;\n    cout<<\"\\n\";\n    cout<<K+2<<\" 400 400\";\n    for(int j=0;j<K;j++) cout<<\" \"<<px[route[j]]<<\" \"<<py[route[j]];\n    cout<<\" 400 400\\n\";\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, sz;\n    DSU(){}\n    DSU(int n): p(n), sz(n,1) { iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a, int b){ a=find(a);b=find(b);if(a==b)return false;if(sz[a]<sz[b])swap(a,b);p[b]=a;sz[a]+=sz[b];return true;}\n    bool same(int a,int b){return find(a)==find(b);}\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    int N = 400, M = 1995;\n    vector<int> x(N), y(N);\n    for(int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    vector<int> U(M), V(M);\n    vector<double> D(M);\n    for(int i = 0; i < M; i++){\n        cin >> U[i] >> V[i];\n        double dx = x[U[i]] - x[V[i]], dy = y[U[i]] - y[V[i]];\n        D[i] = round(sqrt(dx*dx + dy*dy));\n    }\n    \n    DSU dsu(N);\n    \n    for(int i = 0; i < M; i++){\n        int l; cin >> l;\n        \n        if(dsu.same(U[i], V[i])){\n            cout << \"0\\n\" << flush;\n            continue;\n        }\n        \n        int fu = dsu.find(U[i]), fv = dsu.find(V[i]);\n        \n        unordered_map<long long, vector<double>> comp_edges;\n        DSU tmp(N);\n        \n        for(int j = i+1; j < M; j++){\n            int a = dsu.find(U[j]), b = dsu.find(V[j]);\n            if(a == b) continue;\n            tmp.unite(a, b);\n            if(a > b) swap(a, b);\n            long long key = (long long)a * N + b;\n            comp_edges[key].push_back(D[j]);\n        }\n        \n        if(!tmp.same(fu, fv)){\n            cout << \"1\\n\" << flush;\n            dsu.unite(U[i], V[i]);\n            continue;\n        }\n        \n        unordered_map<int,int> cmap;\n        int nc = 0;\n        auto get_id = [&](int c) -> int {\n            auto it = cmap.find(c);\n            if(it == cmap.end()) { int id=nc++; cmap[c]=id; return id; }\n            return it->second;\n        };\n        get_id(fu); get_id(fv);\n        \n        vector<tuple<int,int,double>> elist;\n        for(auto& [key, dvec] : comp_edges) {\n            int a = key / N, b = key % N;\n            int ia = get_id(a), ib = get_id(b);\n            \n            double lo = 1e18, hi = 0;\n            for(double d : dvec) { lo = min(lo, d); hi = max(hi, 3*d); }\n            int steps = 100;\n            double dt = (hi - lo) / steps;\n            double emin = lo;\n            for(int s = 0; s < steps; s++) {\n                double t = lo + (s + 0.5) * dt;\n                double p = 1.0;\n                for(double d : dvec) {\n                    if(t < d) continue;\n                    else if(t >= 3*d) { p = 0; break; }\n                    else p *= (3*d - t) / (2*d);\n                }\n                emin += p * dt;\n            }\n            elist.push_back({ia, ib, emin});\n        }\n        \n        vector<vector<pair<int,double>>> adj(nc);\n        for(auto& [a,b,c] : elist){\n            adj[a].push_back({b,c});\n            adj[b].push_back({a,c});\n        }\n        \n        vector<double> dist(nc, 1e18);\n        vector<int> hops(nc, 0);\n        int src = cmap[fu], dst = cmap[fv];\n        priority_queue<pair<double,int>, vector<pair<double,int>>, greater<>> pq;\n        dist[src] = 0; 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, w] : adj[u]){\n                if(dist[u] + w < dist[v]){\n                    dist[v] = dist[u] + w;\n                    hops[v] = hops[u] + 1;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        double alt = dist[dst];\n        int ah = hops[dst];\n        // Try: no hop penalty, threshold 0.86\n        // The hop penalty was 1.05^(h-1), with threshold 0.88 gave 3.770\n        // For 2 hops: effective = emin * 1.05 * 0.88 = emin * 0.924\n        // For 1 hop: effective = emin * 0.88\n        // So multi-hop gets higher effective threshold - makes sense\n        // Let me try: per-hop threshold adjustment\n        // 1 hop: 0.88, 2 hops: 0.88*1.05=0.924, 3 hops: 0.88*1.1025=0.9702\n        double effective_threshold = 0.88 * pow(1.05, max(0, ah-1));\n        effective_threshold = min(effective_threshold, 1.0);\n        \n        if((double)l <= alt * effective_threshold){\n            cout << \"1\\n\" << flush;\n            dsu.unite(U[i], V[i]);\n        } else {\n            cout << \"0\\n\" << flush;\n        }\n    }\n}","ahc008":"#include <bits/stdc++.h>\nusing namespace std;\nconst int GS=30;\nint N,M;\nint px[25],py[25],ptype[25];\nint hx[15],hy[15];\nbool wall_[35][35];\nint dx[]={-1,1,0,0};\nint dy[]={0,0,-1,1};\nchar dmc[]={'U','D','L','R'};\nchar dpc[]={'u','d','l','r'};\nbool inB(int x,int y){return x>=1&&x<=GS&&y>=1&&y<=GS;}\nbool hasPetAdjacentOrOn(int x,int y){\n    for(int i=0;i<N;i++) if(abs(px[i]-x)+abs(py[i]-y)<=1) return true;\n    return false;\n}\nbool hasHumanAt(int x,int y,int excl=-1){\n    for(int i=0;i<M;i++){if(i==excl)continue;if(hx[i]==x&&hy[i]==y)return true;}\n    return false;\n}\nset<pair<int,int>> gNW;\nvector<pair<int,int>> bfsPath(int sx,int sy,int tx,int ty){\n    if(sx==tx&&sy==ty)return{};\n    int prev[31][31];memset(prev,-1,sizeof(prev));prev[sx][sy]=-2;\n    queue<pair<int,int>>q;q.push({sx,sy});\n    while(!q.empty()){\n        auto[cx,cy]=q.front();q.pop();\n        for(int d=0;d<4;d++){\n            int nx=cx+dx[d],ny=cy+dy[d];\n            if(inB(nx,ny)&&!wall_[nx][ny]&&!gNW.count({nx,ny})&&prev[nx][ny]==-1){\n                prev[nx][ny]=d;\n                if(nx==tx&&ny==ty){\n                    vector<pair<int,int>>path;int x=tx,y=ty;\n                    while(x!=sx||y!=sy){path.push_back({x,y});int dd=prev[x][y];x-=dx[dd];y-=dy[dd];}\n                    reverse(path.begin(),path.end());return path;\n                }\n                q.push({nx,ny});\n            }\n        }\n    }\n    return{};\n}\n\n// BFS distance from a point to all cells\nvoid bfsDistAll(int sx,int sy,int dist[31][31]){\n    memset(dist,-1,sizeof(int)*31*31);\n    dist[sx][sy]=0;\n    queue<pair<int,int>>q;q.push({sx,sy});\n    while(!q.empty()){\n        auto[cx,cy]=q.front();q.pop();\n        for(int d=0;d<4;d++){\n            int nx=cx+dx[d],ny=cy+dy[d];\n            if(inB(nx,ny)&&!wall_[nx][ny]&&dist[nx][ny]==-1){\n                dist[nx][ny]=dist[cx][cy]+1;\n                q.push({nx,ny});\n            }\n        }\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    cin>>N;\n    for(int i=0;i<N;i++)cin>>px[i]>>py[i]>>ptype[i];\n    cin>>M;\n    for(int i=0;i<M;i++)cin>>hx[i]>>hy[i];\n    memset(wall_,false,sizeof(wall_));\n    \n    // Compute \"danger\" of each pet (based on speed)\n    // cow=1, pig=2, rabbit=3, dog=2, cat=2\n    int petSpeed[25];\n    for(int i=0;i<N;i++){\n        if(ptype[i]==1)petSpeed[i]=1;\n        else if(ptype[i]==2)petSpeed[i]=2;\n        else if(ptype[i]==3)petSpeed[i]=3;\n        else petSpeed[i]=2; // dog and cat\n    }\n    \n    double bestScore=-1e18;\n    int bsR1=1,bsR2=15,bsC1=1,bsC2=30;\n    vector<pair<int,int>> bestWC;\n    \n    auto tryRegion=[&](int r1,int r2,int c1,int c2){\n        vector<pair<int,int>>wc;\n        if(r1>1)for(int c=max(1,c1-1);c<=min(30,c2+1);c++)wc.push_back({r1-1,c});\n        if(r2<30)for(int c=max(1,c1-1);c<=min(30,c2+1);c++)wc.push_back({r2+1,c});\n        if(c1>1)for(int r=r1;r<=r2;r++)wc.push_back({r,c1-1});\n        if(c2<30)for(int r=r1;r<=r2;r++)wc.push_back({r,c2+1});\n        sort(wc.begin(),wc.end());wc.erase(unique(wc.begin(),wc.end()),wc.end());\n        \n        int petsIn=0;\n        for(int i=0;i<N;i++)if(px[i]>=r1&&px[i]<=r2&&py[i]>=c1&&py[i]<=c2)petsIn++;\n        int humIn=0;double humDistSum=0,maxHumDist=0;\n        for(int i=0;i<M;i++){\n            if(hx[i]>=r1&&hx[i]<=r2&&hy[i]>=c1&&hy[i]<=c2)humIn++;\n            int dr=max(0,max(r1-hx[i],hx[i]-r2));\n            int dc=max(0,max(c1-hy[i],hy[i]-c2));\n            humDistSum+=dr+dc;\n            maxHumDist=max(maxHumDist,(double)(dr+dc));\n        }\n        int area=(r2-r1+1)*(c2-c1+1);\n        int wCnt=(int)wc.size();\n        double buildTime=(double)wCnt/max(1,M)+humDistSum/(M*2.0);\n        if(buildTime>250)return;\n        \n        // Better leak estimate: consider pet speeds and distance to wall\n        double leakScore=0;\n        for(int i=0;i<N;i++){\n            if(px[i]>=r1&&px[i]<=r2&&py[i]>=c1&&py[i]<=c2)continue;\n            // Distance from pet to nearest wall cell\n            int minDist=1e9;\n            for(auto&w:wc){\n                int d2=abs(px[i]-w.first)+abs(py[i]-w.second);\n                minDist=min(minDist,d2);\n            }\n            // Probability pet reaches wall gap before it's sealed\n            double reachTime=(double)minDist/petSpeed[i];\n            if(reachTime<buildTime) leakScore+=max(0.0,1.0-reachTime/buildTime)*0.5;\n        }\n        double totalPets=petsIn+leakScore;\n        double sc=(double)area/900.0*pow(2.0,-totalPets);\n        sc*=(0.3+0.7*(double)humIn/M);\n        if(sc>bestScore){bestScore=sc;bsR1=r1;bsR2=r2;bsC1=c1;bsC2=c2;bestWC=wc;}\n    };\n    \n    for(int w=2;w<=29;w++){\n        tryRegion(1,w,1,30);tryRegion(31-w,30,1,30);\n        tryRegion(1,30,1,w);tryRegion(1,30,31-w,30);\n    }\n    for(int h=3;h<=28;h++)for(int w=3;w<=28;w++){\n        tryRegion(1,h,1,w);tryRegion(1,h,31-w,30);\n        tryRegion(31-h,30,1,w);tryRegion(31-h,30,31-w,30);\n    }\n    for(int r1=3;r1<=15;r1++)for(int r2=r1+3;r2<=28;r2++)tryRegion(r1,r2,1,30);\n    for(int c1=3;c1<=15;c1++)for(int c2=c1+3;c2<=28;c2++)tryRegion(1,30,c1,c2);\n    \n    auto inSafe=[&](int r,int c){return r>=bsR1&&r<=bsR2&&c>=bsC1&&c<=bsC2;};\n    set<pair<int,int>>wallNeeded(bestWC.begin(),bestWC.end());\n    \n    for(int turn=0;turn<300;turn++){\n        string actions(M,'.');\n        {vector<pair<int,int>>rem;for(auto&w:wallNeeded)if(wall_[w.first][w.second])rem.push_back(w);for(auto&w:rem)wallNeeded.erase(w);}\n        gNW.clear();\n        \n        // Compute danger priority for each wall cell based on nearby pets\n        map<pair<int,int>,int> wallDanger;\n        for(auto&wc:wallNeeded){\n            int danger=0;\n            for(int i=0;i<N;i++){\n                if(inSafe(px[i],py[i]))continue;\n                int dist=abs(px[i]-wc.first)+abs(py[i]-wc.second);\n                if(dist<=petSpeed[i]*3) danger+=100/(dist+1)*petSpeed[i];\n            }\n            wallDanger[wc]=danger;\n        }\n        \n        // Pass 1: Wall placements - prioritize dangerous gaps\n        for(int p=0;p<M;p++){\n            int bx=hx[p],by=hy[p];\n            int bestD=-1,bestPri=-1;\n            for(int d=0;d<4;d++){\n                int nx=bx+dx[d],ny=by+dy[d];\n                if(!inB(nx,ny)||wall_[nx][ny]||gNW.count({nx,ny}))continue;\n                if(!wallNeeded.count({nx,ny}))continue;\n                if(hasPetAdjacentOrOn(nx,ny)||hasHumanAt(nx,ny,p))continue;\n                int pri=wallDanger[{nx,ny}];\n                for(int dd=0;dd<4;dd++){int nr=nx+dx[dd],nc=ny+dy[dd];if(!inB(nr,nc)||wall_[nr][nc]||gNW.count({nr,nc}))pri+=3;}\n                if(inSafe(bx,by))pri+=50;\n                if(pri>bestPri){bestPri=pri;bestD=d;}\n            }\n            if(bestD>=0){\n                int nx=bx+dx[bestD],ny=by+dy[bestD];\n                actions[p]=dpc[bestD];gNW.insert({nx,ny});wallNeeded.erase({nx,ny});\n            }\n        }\n        \n        // Pass 2: Movements - distribute people across wall gaps\n        // First, collect remaining wall cells and their build positions\n        vector<pair<pair<int,int>,int>> wallsWithDanger;\n        for(auto&wc:wallNeeded){\n            if(wall_[wc.first][wc.second])continue;\n            wallsWithDanger.push_back({wc, wallDanger.count(wc)?wallDanger[wc]:0});\n        }\n        sort(wallsWithDanger.begin(),wallsWithDanger.end(),[](auto&a,auto&b){return a.second>b.second;});\n        \n        // Assign people to wall cells greedily by danger\n        set<int> assignedPeople;\n        map<int,pair<int,int>> personTarget;\n        \n        for(auto&[wc,danger]:wallsWithDanger){\n            int bestP=-1,bestDist=1e9;\n            for(int p=0;p<M;p++){\n                if(actions[p]!='.'||assignedPeople.count(p))continue;\n                int dist=abs(hx[p]-wc.first)+abs(hy[p]-wc.second);\n                if(dist<bestDist){bestDist=dist;bestP=p;}\n            }\n            if(bestP>=0){\n                // Find best adjacent cell to stand at\n                int bd=1e9;pair<int,int>bt={-1,-1};\n                for(int d=0;d<4;d++){\n                    int ax=wc.first+dx[d],ay=wc.second+dy[d];\n                    if(!inB(ax,ay)||wall_[ax][ay]||gNW.count({ax,ay}))continue;\n                    int dist=abs(hx[bestP]-ax)+abs(hy[bestP]-ay);\n                    if(inSafe(ax,ay))dist-=5;\n                    if(dist<bd){bd=dist;bt={ax,ay};}\n                }\n                if(bt.first!=-1){\n                    personTarget[bestP]=bt;\n                    assignedPeople.insert(bestP);\n                }\n            }\n        }\n        \n        for(int p=0;p<M;p++){\n            if(actions[p]!='.')continue;\n            int bx=hx[p],by=hy[p];\n            pair<int,int>tgt={-1,-1};\n            \n            if(personTarget.count(p)){\n                tgt=personTarget[p];\n            } else if(!wallNeeded.empty()){\n                int bd=1e9;\n                for(auto&wc:wallNeeded){\n                    for(int d=0;d<4;d++){\n                        int ax=wc.first+dx[d],ay=wc.second+dy[d];\n                        if(!inB(ax,ay)||wall_[ax][ay]||gNW.count({ax,ay}))continue;\n                        int dist=abs(bx-ax)+abs(by-ay);\n                        if(inSafe(ax,ay))dist-=5;\n                        if(dist<bd){bd=dist;tgt={ax,ay};}\n                    }\n                }\n            } else if(!inSafe(bx,by)){\n                tgt={(bsR1+bsR2)/2,(bsC1+bsC2)/2};\n            }\n            \n            if(tgt.first!=-1&&(tgt.first!=bx||tgt.second!=by)){\n                auto path=bfsPath(bx,by,tgt.first,tgt.second);\n                if(!path.empty()){\n                    int nx=path[0].first,ny=path[0].second;\n                    if(inB(nx,ny)&&!wall_[nx][ny]&&!gNW.count({nx,ny})){\n                        for(int d=0;d<4;d++)if(bx+dx[d]==nx&&by+dy[d]==ny){actions[p]=dmc[d];break;}\n                    }\n                }\n            }\n        }\n        \n        for(int p=0;p<M;p++){\n            char a=actions[p];\n            for(int d=0;d<4;d++){\n                if(a==dpc[d]){int nx=hx[p]+dx[d],ny=hy[p]+dy[d];if(inB(nx,ny))wall_[nx][ny]=true;}\n                if(a==dmc[d]){int nx=hx[p]+dx[d],ny=hy[p]+dy[d];if(inB(nx,ny)&&!wall_[nx][ny]){hx[p]=nx;hy[p]=ny;}}\n            }\n        }\n        cout<<actions<<\"\\n\";cout.flush();\n        for(int i=0;i<N;i++){string s;cin>>s;for(char c:s)for(int d=0;d<4;d++)if(c==dmc[d]){px[i]+=dx[d];py[i]+=dy[d];}}\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint si,sj,ti,tj;\ndouble p;\nbool hwall[20][19], vwall[19][20];\nint di_[]={-1,1,0,0}, dj_[]={0,0,-1,1};\nint bfs_dist[20][20];\n\nbool can_move(int i,int j,int d){\n    if(d==0) return i>0 && !vwall[i-1][j];\n    if(d==1) return i<19 && !vwall[i][j];\n    if(d==2) return j>0 && !hwall[i][j-1];\n    if(d==3) return j<19 && !hwall[i][j];\n    return false;\n}\n\nvoid compute_bfs(){\n    memset(bfs_dist,-1,sizeof(bfs_dist));\n    queue<pair<int,int>> Q;\n    bfs_dist[ti][tj]=0; Q.push({ti,tj});\n    while(!Q.empty()){\n        auto [ci,cj]=Q.front(); Q.pop();\n        for(int d=0;d<4;d++){\n            if(!can_move(ci,cj,d)) continue;\n            int ni=ci+di_[d],nj=cj+dj_[d];\n            if(bfs_dist[ni][nj]>=0) continue;\n            bfs_dist[ni][nj]=bfs_dist[ci][cj]+1;\n            Q.push({ni,nj});\n        }\n    }\n}\n\ndouble snap[201][20][20];\ndouble back_val[201][20][20];\n\nvoid do_snap_step(const vector<int>& dirs, int t){\n    int d=dirs[t];\n    memset(snap[t+1],0,sizeof(snap[t+1]));\n    for(int i=0;i<20;i++) for(int j=0;j<20;j++){\n        double v=snap[t][i][j]; if(v<1e-15) continue;\n        snap[t+1][i][j]+=v*p;\n        if(can_move(i,j,d)){\n            int ni=i+di_[d],nj=j+dj_[d];\n            if(!(ni==ti&&nj==tj)) snap[t+1][ni][nj]+=v*(1-p);\n        } else snap[t+1][i][j]+=v*(1-p);\n    }\n}\n\nvoid init_snaps(const vector<int>& dirs){\n    memset(snap[0],0,sizeof(snap[0]));\n    snap[0][si][sj]=1.0;\n    for(int t=0;t<(int)dirs.size();t++) do_snap_step(dirs,t);\n}\n\nvoid compute_back(const vector<int>& dirs){\n    int L=dirs.size();\n    memset(back_val[L],0,sizeof(back_val[L]));\n    for(int t=L-1;t>=0;t--){\n        int d=dirs[t];\n        double reward=401.0-(t+1);\n        for(int i=0;i<20;i++) for(int j=0;j<20;j++){\n            if(i==ti&&j==tj){back_val[t][i][j]=0;continue;}\n            double val=p*back_val[t+1][i][j];\n            if(can_move(i,j,d)){\n                int ni=i+di_[d],nj=j+dj_[d];\n                if(ni==ti&&nj==tj) val+=(1-p)*reward;\n                else val+=(1-p)*back_val[t+1][ni][nj];\n            } else val+=(1-p)*back_val[t+1][i][j];\n            back_val[t][i][j]=val;\n        }\n    }\n}\n\ndouble score_at_dir(int t, int d){\n    double reward=401.0-(t+1);\n    double total=0;\n    for(int i=0;i<20;i++) for(int j=0;j<20;j++){\n        double v=snap[t][i][j]; if(v<1e-15) continue;\n        double val=p*back_val[t+1][i][j];\n        if(can_move(i,j,d)){\n            int ni=i+di_[d],nj=j+dj_[d];\n            if(ni==ti&&nj==tj) val+=(1-p)*reward;\n            else val+=(1-p)*back_val[t+1][ni][nj];\n        } else val+=(1-p)*back_val[t+1][i][j];\n        total+=v*val;\n    }\n    return total;\n}\n\ndouble eval_from(const vector<int>& dirs, int start){\n    double prob[20][20];\n    memcpy(prob,snap[start],sizeof(prob));\n    double total=0;\n    int L=dirs.size();\n    for(int t=start;t<L;t++){\n        int d=dirs[t];\n        double reward=401.0-(t+1);\n        double nprob[20][20]={};\n        for(int i=0;i<20;i++) for(int j=0;j<20;j++){\n            double v=prob[i][j]; if(v<1e-15) continue;\n            nprob[i][j]+=v*p;\n            if(can_move(i,j,d)){\n                int ni=i+di_[d],nj=j+dj_[d];\n                if(ni==ti&&nj==tj) total+=v*(1-p)*reward;\n                else nprob[ni][nj]+=v*(1-p);\n            } else nprob[i][j]+=v*(1-p);\n        }\n        memcpy(prob,nprob,sizeof(prob));\n    }\n    return total;\n}\n\nvector<int> greedy_solution(double alpha){\n    double prob[20][20]={};\n    prob[si][sj]=1.0;\n    vector<int> dirs;\n    for(int t=0;t<200;t++){\n        double reward=401.0-(t+1);\n        int bestd=0; double bestval=-1e18;\n        for(int d=0;d<4;d++){\n            double arrival=0,ed=0;\n            for(int i=0;i<20;i++) for(int j=0;j<20;j++){\n                double v=prob[i][j]; if(v<1e-15) continue;\n                ed+=v*p*bfs_dist[i][j];\n                if(can_move(i,j,d)){\n                    int ni=i+di_[d],nj=j+dj_[d];\n                    if(ni==ti&&nj==tj) arrival+=v*(1-p);\n                    else ed+=v*(1-p)*bfs_dist[ni][nj];\n                } else ed+=v*(1-p)*bfs_dist[i][j];\n            }\n            double val=arrival*reward*alpha-ed;\n            if(val>bestval){bestval=val;bestd=d;}\n        }\n        dirs.push_back(bestd);\n        double nprob[20][20]={};\n        for(int i=0;i<20;i++) for(int j=0;j<20;j++){\n            double v=prob[i][j]; if(v<1e-15) continue;\n            nprob[i][j]+=v*p;\n            if(can_move(i,j,bestd)){\n                int ni=i+di_[bestd],nj=j+dj_[bestd];\n                if(!(ni==ti&&nj==tj)) nprob[ni][nj]+=v*(1-p);\n            } else nprob[i][j]+=v*(1-p);\n        }\n        memcpy(prob,nprob,sizeof(prob));\n    }\n    return dirs;\n}\n\nint main(){\n    auto t0=steady_clock::now();\n    scanf(\"%d%d%d%d%lf\",&si,&sj,&ti,&tj,&p);\n    for(int i=0;i<20;i++){\n        char s[25]; scanf(\"%s\",s);\n        for(int j=0;j<19;j++) hwall[i][j]=(s[j]=='1');\n    }\n    for(int i=0;i<19;i++){\n        char s[25]; scanf(\"%s\",s);\n        for(int j=0;j<20;j++) vwall[i][j]=(s[j]=='1');\n    }\n    compute_bfs();\n    \n    vector<int> best_dirs;\n    double best_score=-1;\n    \n    double alphas[]={0.0,0.001,0.003,0.005,0.01,0.02,0.03,0.05,0.07,0.1,0.15,0.2,0.3,0.5,0.7,1.0,1.5,2.0,3.0,5.0,7.0,10.0,15.0,20.0,30.0,50.0,75.0,100.0,200.0,500.0};\n    for(double alpha:alphas){\n        auto dirs=greedy_solution(alpha);\n        init_snaps(dirs);\n        compute_back(dirs);\n        double sc=0;\n        for(int i=0;i<20;i++) for(int j=0;j<20;j++) sc+=snap[0][i][j]*back_val[0][i][j];\n        if(sc>best_score){best_score=sc;best_dirs=dirs;}\n    }\n    \n    // Fast forward sweep using back values, then recompute back\n    for(int iter=0;iter<500;iter++){\n        auto elapsed=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n        if(elapsed>600) break;\n        \n        init_snaps(best_dirs);\n        compute_back(best_dirs);\n        bool improved=false;\n        \n        for(int t=0;t<200;t++){\n            int orig_d=best_dirs[t];\n            int bestd=orig_d;\n            double bestsc=score_at_dir(t,orig_d);\n            for(int d=0;d<4;d++){\n                if(d==orig_d) continue;\n                double sc=score_at_dir(t,d);\n                if(sc>bestsc){bestsc=sc;bestd=d;}\n            }\n            if(bestd!=orig_d){\n                best_dirs[t]=bestd;\n                improved=true;\n            }\n            do_snap_step(best_dirs,t);\n        }\n        if(!improved) break;\n    }\n    \n    // Precise local search with eval_from\n    init_snaps(best_dirs);\n    for(int iter=0;iter<100;iter++){\n        auto elapsed=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n        if(elapsed>1200) break;\n        bool improved=false;\n        for(int t=0;t<200;t++){\n            int orig_d=best_dirs[t];\n            double orig_sc=eval_from(best_dirs,t);\n            int bestd=orig_d; double bestsc=orig_sc;\n            for(int d=0;d<4;d++){\n                if(d==orig_d) continue;\n                best_dirs[t]=d;\n                double sc=eval_from(best_dirs,t);\n                if(sc>bestsc){bestsc=sc;bestd=d;}\n            }\n            best_dirs[t]=bestd;\n            if(bestd!=orig_d){\n                improved=true;\n                for(int tt=t;tt<200;tt++) do_snap_step(best_dirs,tt);\n            }\n        }\n        if(!improved) break;\n    }\n    \n    // 2-position search\n    init_snaps(best_dirs);\n    for(int iter=0;iter<10;iter++){\n        auto elapsed=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n        if(elapsed>1700) break;\n        bool improved=false;\n        for(int t=0;t<199;t++){\n            auto el=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n            if(el>1700) break;\n            int od1=best_dirs[t],od2=best_dirs[t+1];\n            double orig_sc=eval_from(best_dirs,t);\n            int bd1=od1,bd2=od2; double bsc=orig_sc;\n            for(int d1=0;d1<4;d1++) for(int d2=0;d2<4;d2++){\n                if(d1==od1&&d2==od2) continue;\n                best_dirs[t]=d1;best_dirs[t+1]=d2;\n                double sc=eval_from(best_dirs,t);\n                if(sc>bsc){bsc=sc;bd1=d1;bd2=d2;}\n            }\n            best_dirs[t]=bd1;best_dirs[t+1]=bd2;\n            if(bd1!=od1||bd2!=od2){\n                improved=true;\n                for(int tt=t;tt<200;tt++) do_snap_step(best_dirs,tt);\n            }\n        }\n        if(!improved) break;\n    }\n    \n    // Final single pass\n    init_snaps(best_dirs);\n    for(int iter=0;iter<10;iter++){\n        auto elapsed=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n        if(elapsed>1900) break;\n        bool improved=false;\n        for(int t=0;t<200;t++){\n            auto el=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n            if(el>1900) break;\n            int orig_d=best_dirs[t];\n            double orig_sc=eval_from(best_dirs,t);\n            int bestd=orig_d; double bestsc=orig_sc;\n            for(int d=0;d<4;d++){\n                if(d==orig_d) continue;\n                best_dirs[t]=d;\n                double sc=eval_from(best_dirs,t);\n                if(sc>bestsc){bestsc=sc;bestd=d;}\n            }\n            best_dirs[t]=bestd;\n            if(bestd!=orig_d){\n                improved=true;\n                for(int tt=t;tt<200;tt++) do_snap_step(best_dirs,tt);\n            }\n        }\n        if(!improved) break;\n    }\n    \n    string ans;\n    for(int d:best_dirs) ans+=\"UDLR\"[d];\n    printf(\"%s\\n\",ans.c_str());\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\nconst int N=30,MAXID=2000;\nint tiles[N][N],orig[N][N],rot[N][N],best_rot[N][N];\nconst int di[]={0,-1,0,1},dj[]={-1,0,1,0};\nconst int TD[8][4]={{1,0,-1,-1},{3,-1,-1,0},{-1,-1,3,2},{-1,2,1,-1},{1,0,3,2},{3,2,1,0},{2,-1,0,-1},{-1,3,-1,1}};\nconst int RT[8][4]={{0,1,2,3},{1,2,3,0},{2,3,0,1},{3,0,1,2},{4,5,4,5},{5,4,5,4},{6,7,6,7},{7,6,7,6}};\n\nint lid[3600],llen_a[MAXID],lstp_a[MAXID];\nint nid=0;\nint freeq[MAXID],ftop=0;\nmultiset<int> lens;\nlong long sum_sq=0;\n\ninline int P(int i,int j,int d){return(i*30+j)*4+d;}\nint get_id(){return ftop>0?freeq[--ftop]:nid++;}\nvoid ret_id(int id){freeq[ftop++]=id;}\n\nvoid unmark_loop(int id){\n    int p=lstp_a[id],si=p/120,sj=(p/4)%30,sd=p%4;\n    int i=si,j=sj,d=sd;\n    do{\n        lid[P(i,j,d)]=-1;\n        int d2=TD[tiles[i][j]][d];\n        i+=di[d2];j+=dj[d2];d=(d2+2)&3;\n    }while(!(i==si&&j==sj&&d==sd));\n    lens.erase(lens.find(llen_a[id]));\n    sum_sq-=(long long)llen_a[id]*llen_a[id];\n}\n\nvoid remark_loop(int id,int len,int stp){\n    int si=stp/120,sj=(stp/4)%30,sd=stp%4;\n    int i=si,j=sj,d=sd;\n    do{\n        lid[P(i,j,d)]=id;\n        int d2=TD[tiles[i][j]][d];\n        i+=di[d2];j+=dj[d2];d=(d2+2)&3;\n    }while(!(i==si&&j==sj&&d==sd));\n    llen_a[id]=len;lstp_a[id]=stp;\n    lens.insert(len);\n    sum_sq+=(long long)len*len;\n}\n\nint add_loop(int si,int sj,int sd){\n    int i=si,j=sj,d=sd,len=0;\n    do{\n        int d2=TD[tiles[i][j]][d];\n        if(d2<0)return -1;\n        i+=di[d2];j+=dj[d2];\n        if((unsigned)i>=N||(unsigned)j>=N)return -1;\n        d=(d2+2)&3;len++;\n    }while(!(i==si&&j==sj&&d==sd));\n    int id=get_id();\n    i=si;j=sj;d=sd;\n    do{\n        lid[P(i,j,d)]=id;\n        int d2=TD[tiles[i][j]][d];\n        i+=di[d2];j+=dj[d2];d=(d2+2)&3;\n    }while(!(i==si&&j==sj&&d==sd));\n    llen_a[id]=len;lstp_a[id]=P(si,sj,sd);\n    lens.insert(len);sum_sq+=(long long)len*len;\n    return id;\n}\n\ndouble ev(){\n    if((int)lens.size()<2)return sum_sq*0.005;\n    auto it=lens.end();--it;double a=*it;--it;return a*(*it)+sum_sq*0.005;\n}\n\nlong long psc(){\n    if((int)lens.size()<2)return 0;\n    auto it=lens.end();--it;long long a=*it;--it;return a*(*it);\n}\n\nvoid init_all(){\n    memset(lid,-1,sizeof(lid));\n    lens.clear();sum_sq=0;nid=0;ftop=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)for(int d=0;d<4;d++){\n        if(lid[P(i,j,d)]>=0||TD[tiles[i][j]][d]<0)continue;\n        add_loop(i,j,d);\n    }\n}\n\n// Fast RNG\nuint64_t rng_s=123456789;\ninline uint32_t xrng(){rng_s^=rng_s<<13;rng_s^=rng_s>>7;rng_s^=rng_s<<17;return(uint32_t)rng_s;}\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(0);\n    for(int i=0;i<N;i++){string s;cin>>s;for(int j=0;j<N;j++)orig[i][j]=s[j]-'0';}\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){tiles[i][j]=orig[i][j];rot[i][j]=0;}\n    init_all();\n    long long bs=psc();double ce=ev();\n    memcpy(best_rot,rot,sizeof(rot));\n    auto start=chrono::steady_clock::now();\n\n    for(int iter=0;;iter++){\n        if((iter&0xFFF)==0)\n            if(chrono::duration<double>(chrono::steady_clock::now()-start).count()>1.85)break;\n        double el=chrono::duration<double>(chrono::steady_clock::now()-start).count();\n        double T=500.0*(1.0-el/1.88)+1.0;\n\n        int ci=xrng()%N,cj=xrng()%N;\n        int or_=rot[ci][cj],ot=tiles[ci][cj];\n        int nr=(or_+1+xrng()%3)%4;\n        int nt=RT[orig[ci][cj]][nr];\n        if(nt==ot)continue;\n\n        int af[8],na=0;\n        for(int d=0;d<4;d++){\n            int v=lid[P(ci,cj,d)];\n            if(v>=0){bool f=false;for(int k=0;k<na;k++)if(af[k]==v){f=true;break;}if(!f)af[na++]=v;}\n            int ni=ci+di[d],nj=cj+dj[d];\n            if((unsigned)ni<N&&(unsigned)nj<N){\n                v=lid[P(ni,nj,(d+2)&3)];\n                if(v>=0){bool f=false;for(int k=0;k<na;k++)if(af[k]==v){f=true;break;}if(!f)af[na++]=v;}\n            }\n        }\n        int slen[8],sstp[8],ext[8][3];int ne=0;\n        for(int k=0;k<na;k++){\n            slen[k]=llen_a[af[k]];sstp[k]=lstp_a[af[k]];\n            int si=sstp[k]/120,sj=(sstp[k]/4)%30,sd=sstp[k]%4;\n            int ii=si,jj=sj,dd=sd;\n            do{\n                if(ii!=ci||jj!=cj){ext[ne][0]=ii;ext[ne][1]=jj;ext[ne][2]=dd;ne++;break;}\n                int d2=TD[tiles[ii][jj]][dd];ii+=di[d2];jj+=dj[d2];dd=(d2+2)&3;\n            }while(!(ii==si&&jj==sj&&dd==sd));\n        }\n        for(int k=0;k<na;k++){unmark_loop(af[k]);ret_id(af[k]);}\n        rot[ci][cj]=nr;tiles[ci][cj]=nt;\n\n        int ni_ids[20];int nn=0;\n        for(int k=0;k<ne;k++){\n            if(lid[P(ext[k][0],ext[k][1],ext[k][2])]>=0)continue;\n            int id=add_loop(ext[k][0],ext[k][1],ext[k][2]);if(id>=0)ni_ids[nn++]=id;\n        }\n        for(int d=0;d<4;d++){\n            int ni=ci+di[d],nj=cj+dj[d];\n            if((unsigned)ni<N&&(unsigned)nj<N){\n                int nd=(d+2)&3;\n                if(lid[P(ni,nj,nd)]<0&&TD[tiles[ni][nj]][nd]>=0){int id=add_loop(ni,nj,nd);if(id>=0)ni_ids[nn++]=id;}\n            }\n            if(lid[P(ci,cj,d)]<0&&TD[nt][d]>=0){int id=add_loop(ci,cj,d);if(id>=0)ni_ids[nn++]=id;}\n        }\n\n        double ne_=ev();\n        if(ne_>=ce||exp((ne_-ce)/T)>(xrng()%10000)/10000.0){\n            ce=ne_;\n            long long ps=psc();\n            if(ps>bs){bs=ps;memcpy(best_rot,rot,sizeof(rot));}\n        }else{\n            for(int k=0;k<nn;k++){unmark_loop(ni_ids[k]);ret_id(ni_ids[k]);}\n            rot[ci][cj]=or_;tiles[ci][cj]=ot;\n            for(int k=0;k<na;k++){\n                int id=get_id();\n                remark_loop(id,slen[k],sstp[k]);\n            }\n            ce=ev(); // need this since floating point\n        }\n    }\n    string ans(900,'0');\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)ans[i*30+j]='0'+best_rot[i][j];\n    cout<<ans<<endl;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nint board[10][10];\nint origBoard[10][10];\nint ei, ej, origEi, origEj;\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nint opp[] = {1, 0, 3, 2};\nconst char* dirs = \"UDLR\";\n\nint uf_par[100], uf_sz[100];\ninline int uf_find(int x) { while (uf_par[x] != x) x = uf_par[x] = uf_par[uf_par[x]]; return x; }\ninline void uf_unite(int a, int b) {\n    a = uf_find(a); b = uf_find(b);\n    if (a == b) return;\n    if (uf_sz[a] < uf_sz[b]) swap(a, b);\n    uf_par[b] = a; uf_sz[a] += uf_sz[b];\n}\n\nint idd[10][10];\n\nint eval_full(int &largest_tree) {\n    int cnt = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j]) idd[i][j] = cnt++;\n            else idd[i][j] = -1;\n    for (int i = 0; i < cnt; i++) { uf_par[i] = i; uf_sz[i] = 1; }\n    int ec[100];\n    memset(ec, 0, cnt * sizeof(int));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            if (!board[i][j]) continue;\n            if (i+1<N && board[i+1][j] && (board[i][j]&8) && (board[i+1][j]&2)) {\n                ec[idd[i][j]]++; ec[idd[i+1][j]]++;\n                uf_unite(idd[i][j], idd[i+1][j]);\n            }\n            if (j+1<N && board[i][j+1] && (board[i][j]&4) && (board[i][j+1]&1)) {\n                ec[idd[i][j]]++; ec[idd[i][j+1]]++;\n                uf_unite(idd[i][j], idd[i][j+1]);\n            }\n        }\n    int cv[100], ce[100];\n    memset(cv, 0, cnt * sizeof(int));\n    memset(ce, 0, cnt * sizeof(int));\n    for (int i = 0; i < cnt; i++) { int r = uf_find(i); cv[r]++; ce[r] += ec[i]; }\n    largest_tree = 0;\n    int smooth = 0;\n    for (int i = 0; i < cnt; i++) {\n        if (uf_find(i) != i) continue;\n        int e = ce[i]/2, v = cv[i];\n        if (e == v-1) {\n            largest_tree = max(largest_tree, v);\n            smooth += v * v * v;\n        } else {\n            // Component with cycles: give some credit\n            smooth += v * v;\n        }\n        smooth += e * 10;\n    }\n    return smooth;\n}\n\nint main() {\n    scanf(\"%d%d\", &N, &T);\n    for (int i = 0; i < N; i++) {\n        char s[20]; scanf(\"%s\", s);\n        for (int j = 0; j < N; j++) {\n            char c = s[j];\n            board[i][j] = (c >= 'a' ? c - 'a' + 10 : c - '0');\n            origBoard[i][j] = board[i][j];\n            if (board[i][j] == 0) { ei = i; ej = j; origEi = i; origEj = j; }\n        }\n    }\n\n    mt19937 rng(42);\n    auto start = chrono::steady_clock::now();\n    \n    int globalBestTree = 0;\n    string globalBestAns;\n    int globalBestSmooth = -1;\n    \n    for (int attempt = 0; ; attempt++) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n        if (elapsed > 2.5) break;\n        \n        memcpy(board, origBoard, sizeof(board));\n        ei = origEi; ej = origEj;\n        \n        string ans;\n        ans.reserve(T);\n        int lt;\n        int curSmooth = eval_full(lt);\n        int curTree = lt;\n        int lastDir = -1;\n        int bestTree = curTree;\n        int bestSmooth = curSmooth;\n        string bestAns;\n        \n        double baseTemp = 3.0 + attempt * 2.0;\n        \n        while ((int)ans.size() < T - 1) {\n            double el2 = chrono::duration<double>(chrono::steady_clock::now() - start).count();\n            if (el2 > 2.5) break;\n            double progress = el2 / 2.5;\n            double temp = max(0.001, baseTemp * (1.0 - progress));\n            \n            int ncands = 0, cands[4];\n            for (int d = 0; d < 4; d++) {\n                if (lastDir >= 0 && d == opp[lastDir]) continue;\n                int ni = ei + di[d], nj = ej + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) cands[ncands++] = d;\n            }\n            if (ncands == 0) {\n                for (int d = 0; d < 4; d++) {\n                    int ni = ei + di[d], nj = ej + dj[d];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N) cands[ncands++] = d;\n                }\n            }\n            \n            // Pick random candidate\n            int idx = rng() % ncands;\n            int d = cands[idx];\n            int ni = ei + di[d], nj = ej + dj[d];\n            swap(board[ei][ej], board[ni][nj]);\n            int newSmooth = eval_full(lt);\n            int newTree = lt;\n            \n            double delta = newSmooth - curSmooth;\n            bool accepted = false;\n            if (delta >= 0) {\n                accepted = true;\n            } else {\n                uint32_t r = rng();\n                accepted = (r & 0xFFFF) < (uint32_t)(65536.0 * exp(delta / temp));\n            }\n            \n            if (accepted) {\n                ei = ni; ej = nj;\n                ans += dirs[d];\n                curSmooth = newSmooth;\n                curTree = newTree;\n                lastDir = d;\n            } else {\n                swap(board[ei][ej], board[ni][nj]);\n                // Pick best candidate instead\n                int bestD2 = -1, bestV2 = -999999;\n                for (int k = 0; k < ncands; k++) {\n                    int dd = cands[k];\n                    int nni = ei + di[dd], nnj = ej + dj[dd];\n                    swap(board[ei][ej], board[nni][nnj]);\n                    int s2 = eval_full(lt);\n                    if (s2 > bestV2) { bestV2 = s2; bestD2 = k; }\n                    swap(board[ei][ej], board[nni][nnj]);\n                }\n                d = cands[bestD2];\n                ni = ei + di[d]; nj = ej + dj[d];\n                swap(board[ei][ej], board[ni][nj]);\n                curSmooth = eval_full(lt);\n                curTree = lt;\n                ei = ni; ej = nj;\n                ans += dirs[d];\n                lastDir = d;\n            }\n            \n            if (curTree > bestTree || (curTree == bestTree && curSmooth > bestSmooth)) {\n                bestTree = curTree;\n                bestSmooth = curSmooth;\n                bestAns = ans;\n            }\n            if (curTree == N*N-1) break;\n        }\n        \n        if (bestTree > globalBestTree || (bestTree == globalBestTree && bestSmooth > globalBestSmooth)) {\n            globalBestTree = bestTree;\n            globalBestSmooth = bestSmooth;\n            globalBestAns = bestAns;\n        }\n        if (globalBestTree == N*N-1) break;\n    }\n    \n    if (globalBestAns.empty()) {\n        for (int d = 0; d < 4; d++) {\n            int ni = origEi + di[d], nj = origEj + dj[d];\n            if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                globalBestAns = string(1, dirs[d]);\n                break;\n            }\n        }\n    }\n    \n    puts(globalBestAns.c_str());\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,K;\n    cin>>N>>K;\n    int a[11];\n    for(int d=1;d<=10;d++) cin>>a[d];\n    vector<int> sx(N),sy(N);\n    for(int i=0;i<N;i++) cin>>sx[i]>>sy[i];\n    mt19937 rng(42);\n    int NL=min(K,100);\n    \n    uint64_t hp2[100],hn2[100];\n    for(int j=0;j<NL;j++){\n        hp2[j]=((uint64_t)rng()<<32)^rng()|1;\n        hn2[j]=((uint64_t)rng()<<32)^rng()|1;\n    }\n    \n    vector<array<long long,4>> lines(NL);\n    vector<int8_t> sgn(N*NL);\n    vector<uint64_t> ph(N);\n    vector<int> oc(N);\n    \n    auto csign=[&](int i,int j)->int8_t{\n        long long dx=lines[j][2]-lines[j][0],dy=lines[j][3]-lines[j][1];\n        long long cr=dx*((long long)sy[i]-lines[j][1])-dy*((long long)sx[i]-lines[j][0]);\n        return cr>0?1:(cr<0?-1:0);\n    };\n    \n    // Radix sort for uint64_t\n    vector<uint64_t> tmp, buf;\n    auto radix_sort=[&](){\n        int n=tmp.size();\n        if(n<=1) return;\n        buf.resize(n);\n        for(int shift=0;shift<64;shift+=8){\n            int cnt[256]={};\n            for(int i=0;i<n;i++) cnt[(tmp[i]>>shift)&255]++;\n            int pf[256]; pf[0]=0;\n            for(int i=1;i<256;i++) pf[i]=pf[i-1]+cnt[i-1];\n            for(int i=0;i<n;i++) buf[pf[(tmp[i]>>shift)&255]++]=tmp[i];\n            swap(tmp,buf);\n        }\n    };\n    \n    auto calc=[&]()->int{\n        tmp.clear();\n        for(int i=0;i<N;i++) if(!oc[i]) tmp.push_back(ph[i]);\n        int n=tmp.size();\n        if(n==0) return 0;\n        // For small n, std::sort is fine; for large n, radix sort\n        if(n>500) radix_sort();\n        else sort(tmp.begin(),tmp.end());\n        int bd[11]={},s=0;\n        for(int i=0;i<n;){\n            int j=i+1;\n            while(j<n&&tmp[j]==tmp[i])j++;\n            int c=j-i;if(c<=10)bd[c]++;\n            i=j;\n        }\n        for(int d=1;d<=10;d++) s+=min(a[d],bd[d]);\n        return s;\n    };\n    \n    auto mkline=[&]()->array<long long,4>{\n        for(;;){\n            int m=rng()%4;\n            if(m==0&&N>=2){\n                int ia=rng()%N,ib=rng()%N;while(ib==ia)ib=rng()%N;\n                long long mx=(long long)sx[ia]+sx[ib],my=(long long)sy[ia]+sy[ib];\n                long long dx=(long long)sx[ib]-sx[ia],dy=(long long)sy[ib]-sy[ia];\n                long long px=mx-2*dy,py=my+2*dx,qx=mx+2*dy,qy=my-2*dx;\n                if(px!=qx||py!=qy)return{px,py,qx,qy};\n            }else if(m==1&&N>=1){\n                double ag=(rng()%100000)/100000.0*M_PI,ca=cos(ag),sa=sin(ag);\n                int id=rng()%N;double of2=(int)(rng()%21)-10;\n                double cx=sx[id]+of2*(-sa),cy=sy[id]+of2*ca;\n                long long px=llround(cx+ca*30000),py=llround(cy+sa*30000);\n                long long qx=llround(cx-ca*30000),qy=llround(cy-sa*30000);\n                if(px!=qx||py!=qy)return{px,py,qx,qy};\n            }else if(m==2&&N>=2){\n                int ia=rng()%N,ib=rng()%N;while(ib==ia)ib=rng()%N;\n                long long dx=(long long)sx[ib]-sx[ia],dy=(long long)sy[ib]-sy[ia];\n                double ln=sqrt((double)dx*dx+(double)dy*dy);if(ln<1)continue;\n                double of2=(int)(rng()%21)-10;\n                long long ox=llround(-dy/ln*of2),oy=llround(dx/ln*of2);\n                long long px=sx[ia]+ox,py=sy[ia]+oy,qx=sx[ib]+ox,qy=sy[ib]+oy;\n                if(px!=qx||py!=qy)return{px,py,qx,qy};\n            }else{\n                double ag=(rng()%100000)/100000.0*M_PI;\n                double of2=((int)(rng()%20001)-10000);\n                double ca=cos(ag),sa=sin(ag);\n                long long px=llround(-sa*of2+ca*20000),py=llround(ca*of2+sa*20000);\n                long long qx=llround(-sa*of2-ca*20000),qy=llround(ca*of2-sa*20000);\n                if(px!=qx||py!=qy)return{px,py,qx,qy};\n            }\n        }\n    };\n    \n    auto pert=[&](int id)->array<long long,4>{\n        auto l=lines[id];int r=rng()%4;\n        if(r<2){\n            long long d=(int)(rng()%2001)-1000;\n            if(r==0){l[0]+=d;l[2]+=d;}else{l[1]+=d;l[3]+=d;}\n        }else{\n            double mx=(l[0]+l[2])/2.0,my=(l[1]+l[3])/2.0;\n            double d0=l[0]-mx,e0=l[1]-my,d2=l[2]-mx,e2=l[3]-my;\n            double ag=((int)(rng()%2001)-1000)/10000.0,c=cos(ag),s=sin(ag);\n            l[0]=llround(mx+c*d0-s*e0);l[1]=llround(my+s*d0+c*e0);\n            l[2]=llround(mx+c*d2-s*e2);l[3]=llround(my+s*d2+c*e2);\n        }\n        if(l[0]==l[2]&&l[1]==l[3])l[2]++;\n        return l;\n    };\n    \n    for(int j=0;j<NL;j++) lines[j]=mkline();\n    for(int i=0;i<N;i++){\n        ph[i]=0;oc[i]=0;\n        for(int j=0;j<NL;j++){\n            int8_t s=csign(i,j);sgn[i*NL+j]=s;\n            if(!s)oc[i]++;else if(s>0)ph[i]^=hp2[j];else ph[i]^=hn2[j];\n        }\n    }\n    \n    int cs=calc(),bs=cs;\n    auto bl=lines;\n    vector<int8_t> os(N);vector<uint64_t> op(N);vector<int> oo(N);\n    auto st=chrono::steady_clock::now();\n    double el=0;int it=0;\n    \n    while(true){\n        if((++it&255)==0){\n            el=chrono::duration<double>(chrono::steady_clock::now()-st).count();\n            if(el>2.85)break;\n        }\n        double prog=el/2.85;\n        double tp=1.0*(1.0-prog)+0.01;\n        \n        int id=rng()%NL;auto ol=lines[id];\n        lines[id]=(rng()%5)?pert(id):mkline();\n        \n        for(int i=0;i<N;i++){\n            int o=i*NL+id;os[i]=sgn[o];op[i]=ph[i];oo[i]=oc[i];\n            if(os[i]>0)ph[i]^=hp2[id];else if(os[i]<0)ph[i]^=hn2[id];\n            if(!os[i])oc[i]--;\n            int8_t ns=csign(i,id);sgn[o]=ns;\n            if(!ns)oc[i]++;else if(ns>0)ph[i]^=hp2[id];else ph[i]^=hn2[id];\n        }\n        int sc=calc();\n        if(sc>=cs||(exp((sc-cs)/tp)>(rng()%10000)/10000.0)){\n            cs=sc;if(sc>bs){bs=sc;bl=lines;}\n        }else{\n            lines[id]=ol;\n            for(int i=0;i<N;i++){sgn[i*NL+id]=os[i];ph[i]=op[i];oc[i]=oo[i];}\n        }\n    }\n    \n    cout<<NL<<\"\\n\";\n    for(auto&l:bl) cout<<l[0]<<\" \"<<l[1]<<\" \"<<l[2]<<\" \"<<l[3]<<\"\\n\";\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble cc;\nbool init_dg[62][62];\n\ninline uint64_t sk(int x1,int y1,int x2,int y2){\n    if(x1>x2||(x1==x2&&y1>y2)){swap(x1,x2);swap(y1,y2);}\n    return ((uint64_t)x1<<48)|((uint64_t)y1<<32)|((uint64_t)x2<<16)|(uint64_t)(uint16_t)y2;\n}\ninline bool ib(int x,int y){return (unsigned)x<(unsigned)N&&(unsigned)y<(unsigned)N;}\ninline double wt(int x,int y){return (x-cc)*(x-cc)+(y-cc)*(y-cc)+1;}\n\nint udirs[4][2]={{1,0},{0,1},{1,1},{1,-1}};\nint uperp[4][2]={{0,1},{-1,0},{1,-1},{1,1}};\n\nstruct Op{int x1,y1,x2,y2,x3,y3,x4,y4;};\nstruct Cand{\n    double score;\n    int p1x,p1y,p2x,p2y,p3x,p3y,p4x,p4y;\n    bool operator<(const Cand&o)const{return score<o.score;}\n};\n\nchrono::steady_clock::time_point gst;\ninline double elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-gst).count();}\n\nstruct State{\n    bool dg[62][62];\n    unordered_set<uint64_t> used_segs;\n    priority_queue<Cand> pq;\n    vector<Op> ops;\n    int strategy;\n    mt19937 rng;\n    \n    bool csid2(int x1,int y1,int x2,int y2){\n        int dx=x2-x1,dy=y2-y1,g=__gcd(abs(dx),abs(dy));\n        if(g<=1)return true;\n        int sx=dx/g,sy=dy/g;\n        for(int i=1;i<g;i++){int px=x1+sx*i,py=y1+sy*i;if(ib(px,py)&&dg[px][py])return false;}\n        return true;\n    }\n    bool cacs2(int x1,int y1,int x2,int y2,vector<uint64_t>&out){\n        int dx=x2-x1,dy=y2-y1,g=__gcd(abs(dx),abs(dy));\n        if(!g)return true;\n        int sx=dx/g,sy=dy/g;size_t st=out.size();\n        for(int i=0;i<g;i++){\n            uint64_t k=sk(x1+sx*i,y1+sy*i,x1+sx*(i+1),y1+sy*(i+1));\n            if(used_segs.count(k)){out.resize(st);return false;}out.push_back(k);\n        }\n        return true;\n    }\n    \n    double calc_score(double w, int l1, int l2){\n        double perim=2.0*(l1+l2);\n        switch(strategy){\n            case 0: return w/(perim+1.0);\n            case 1: return w;\n            case 2: return -perim+w*0.0001;\n            case 3: return sqrt(w)/(perim+1.0);\n            case 4: return w/(perim*perim+1.0);\n            default: // randomized\n                return w/(perim+1.0) * (0.5 + (rng()%1000)/1000.0);\n        }\n    }\n    \n    void try_rect(int ax,int ay,int bx,int by,int cx,int cy,int dx2,int dy2,int l1,int l2){\n        int h[4]={dg[ax][ay],dg[bx][by],dg[cx][cy],dg[dx2][dy2]};\n        if(h[0]+h[1]+h[2]+h[3]!=3)return;\n        int pts[4][2]={{ax,ay},{bx,by},{cx,cy},{dx2,dy2}};\n        int ni=-1;for(int i=0;i<4;i++)if(!h[i]){ni=i;break;}\n        double w=wt(pts[ni][0],pts[ni][1]);\n        pq.push({calc_score(w,l1,l2),pts[ni][0],pts[ni][1],pts[(ni+1)%4][0],pts[(ni+1)%4][1],\n                 pts[(ni+2)%4][0],pts[(ni+2)%4][1],pts[(ni+3)%4][0],pts[(ni+3)%4][1]});\n    }\n    \n    void find_cands(int ax,int ay){\n        for(int di=0;di<4;di++){\n            int ux=udirs[di][0],uy=udirs[di][1],px=uperp[di][0],py=uperp[di][1];\n            for(int s1:{-1,1})for(int s2:{-1,1}){\n                int sx=ux*s1,sy=uy*s1,qx=px*s2,qy=py*s2;\n                for(int l1=1;l1<N;l1++){\n                    int bx=ax+sx*l1,by=ay+sy*l1;\n                    if(!ib(bx,by))break;\n                    for(int l2=1;l2<N;l2++){\n                        int dxp=ax+qx*l2,dyp=ay+qy*l2;\n                        int cxp=bx+qx*l2,cyp=by+qy*l2;\n                        if(!ib(dxp,dyp)||!ib(cxp,cyp))break;\n                        int h=dg[ax][ay]+dg[bx][by]+dg[cxp][cyp]+dg[dxp][dyp];\n                        if(h==3)try_rect(ax,ay,bx,by,cxp,cyp,dxp,dyp,l1,l2);\n                    }\n                }\n            }\n        }\n    }\n    \n    bool full_validate(Cand&cd,vector<uint64_t>&segs){\n        if(dg[cd.p1x][cd.p1y])return false;\n        if(!dg[cd.p2x][cd.p2y]||!dg[cd.p3x][cd.p3y]||!dg[cd.p4x][cd.p4y])return false;\n        int s[4][4]={{cd.p1x,cd.p1y,cd.p2x,cd.p2y},{cd.p2x,cd.p2y,cd.p3x,cd.p3y},\n                     {cd.p3x,cd.p3y,cd.p4x,cd.p4y},{cd.p4x,cd.p4y,cd.p1x,cd.p1y}};\n        for(int i=0;i<4;i++)if(!csid2(s[i][0],s[i][1],s[i][2],s[i][3]))return false;\n        segs.clear();\n        for(int i=0;i<4;i++)if(!cacs2(s[i][0],s[i][1],s[i][2],s[i][3],segs))return false;\n        return true;\n    }\n    \n    double run(double time_limit){\n        memcpy(dg,init_dg,sizeof(dg));\n        used_segs.clear();\n        used_segs.reserve(N*N*4);\n        while(!pq.empty())pq.pop();\n        ops.clear();\n        \n        for(int x=0;x<N;x++)for(int y=0;y<N;y++)if(dg[x][y])find_cands(x,y);\n        \n        int rounds=0;\n        auto drain=[&](){\n            while(!pq.empty()){\n                if((++rounds&127)==0&&elapsed()>time_limit)return false;\n                auto cd=pq.top();pq.pop();\n                vector<uint64_t> segs;\n                if(!full_validate(cd,segs))continue;\n                dg[cd.p1x][cd.p1y]=true;\n                for(auto k:segs)used_segs.insert(k);\n                ops.push_back({cd.p1x,cd.p1y,cd.p2x,cd.p2y,cd.p3x,cd.p3y,cd.p4x,cd.p4y});\n                find_cands(cd.p1x,cd.p1y);\n            }\n            return true;\n        };\n        if(!drain()) goto done;\n        \n        for(int pass=0;pass<20;pass++){\n            if(elapsed()>time_limit-0.08)break;\n            int before=ops.size();\n            for(int x=0;x<N;x++)for(int y=0;y<N;y++)if(dg[x][y])find_cands(x,y);\n            if(!drain()) break;\n            if((int)ops.size()==before)break;\n        }\n        done:\n        double S=0,Q=0;\n        for(int x=0;x<N;x++)for(int y=0;y<N;y++){S+=wt(x,y);if(dg[x][y])Q+=wt(x,y);}\n        return (double)N*N/M*Q/S;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    cin>>N>>M;cc=(N-1)/2.0;\n    memset(init_dg,0,sizeof(init_dg));\n    for(int i=0;i<M;i++){int x,y;cin>>x>>y;init_dg[x][y]=true;}\n    \n    gst=chrono::steady_clock::now();\n    \n    double best_sc=-1;\n    vector<Op> best_ops;\n    \n    // Deterministic strategies: 0-4, then random variants\n    int sid=0;\n    while(elapsed()<4.35){\n        // Estimate time needed per run based on N\n        double est_time = (sid < 5) ? 0.5 : 0.35;\n        double tl = min(elapsed() + est_time, 4.45);\n        \n        State state;\n        state.strategy = (sid < 5) ? sid : 5;\n        state.rng = mt19937(sid * 98765 + 13);\n        \n        double sc = state.run(tl);\n        if(sc > best_sc){best_sc = sc; best_ops = state.ops;}\n        sid++;\n    }\n    \n    cout<<best_ops.size()<<\"\\n\";\n    for(auto&op:best_ops)\n        cout<<op.x1<<\" \"<<op.y1<<\" \"<<op.x2<<\" \"<<op.y2<<\" \"<<op.x3<<\" \"<<op.y3<<\" \"<<op.x4<<\" \"<<op.y4<<\"\\n\";\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\nstatic mt19937 rng(42);\n\nint G[10][10];\n\ninline void tilt(int g[10][10], int dir) {\n    if (dir == 0) {\n        for(int c=0;c<10;c++){int p=0;for(int r=0;r<10;r++)if(g[r][c]){if(p!=r){g[p][c]=g[r][c];g[r][c]=0;}p++;}}\n    } else if (dir == 1) {\n        for(int c=0;c<10;c++){int p=9;for(int r=9;r>=0;r--)if(g[r][c]){if(p!=r){g[p][c]=g[r][c];g[r][c]=0;}p--;}}\n    } else if (dir == 2) {\n        for(int r=0;r<10;r++){int p=0;for(int c=0;c<10;c++)if(g[r][c]){if(p!=c){g[r][p]=g[r][c];g[r][c]=0;}p++;}}\n    } else {\n        for(int r=0;r<10;r++){int p=9;for(int c=9;c>=0;c--)if(g[r][c]){if(p!=c){g[r][p]=g[r][c];g[r][c]=0;}p--;}}\n    }\n}\n\ninline int adjacency(const int g[10][10]) {\n    int s=0;\n    for(int r=0;r<10;r++) for(int c=0;c<10;c++) if(g[r][c]){\n        if(r<9 && g[r+1][c]==g[r][c]) s++;\n        if(c<9 && g[r][c+1]==g[r][c]) s++;\n    }\n    return s;\n}\n\nint connectivity(const int g[10][10]) {\n    bool vis[10][10]={};\n    int score=0;\n    pair<int,int> stk[100];\n    for(int i=0;i<10;i++) for(int j=0;j<10;j++) if(g[i][j]&&!vis[i][j]){\n        int fl=g[i][j],cnt=0,top=0;\n        stk[top++]={i,j};vis[i][j]=1;\n        while(top>0){\n            auto[r,c]=stk[--top];cnt++;\n            if(r>0&&!vis[r-1][c]&&g[r-1][c]==fl){vis[r-1][c]=1;stk[top++]={r-1,c};}\n            if(r<9&&!vis[r+1][c]&&g[r+1][c]==fl){vis[r+1][c]=1;stk[top++]={r+1,c};}\n            if(c>0&&!vis[r][c-1]&&g[r][c-1]==fl){vis[r][c-1]=1;stk[top++]={r,c-1};}\n            if(c<9&&!vis[r][c+1]&&g[r][c+1]==fl){vis[r][c+1]=1;stk[top++]={r,c+1};}\n        }\n        score+=cnt*cnt;\n    }\n    return score;\n}\n\ninline void placeAt(int g[10][10], int p, int flavor) {\n    for(int r=0;r<10;r++) for(int c=0;c<10;c++) if(!g[r][c]){\n        if(p==0){g[r][c]=flavor;return;}p--;\n    }\n}\n\ninline int countEmpty(const int g[10][10]) {\n    int c=0;for(int i=0;i<100;i++) if(((const int*)g)[i]==0) c++;return c;\n}\n\n// Use adjacency for speed in rollout greedy\nint adjGreedyTilt(int g[10][10]) {\n    int bestA=-1, bestD=0, tmp[10][10];\n    for(int d=0;d<4;d++){\n        memcpy(tmp,g,400); tilt(tmp,d);\n        int a=adjacency(tmp);\n        if(a>bestA){bestA=a;bestD=d;}\n    }\n    return bestD;\n}\n\n// Use connectivity for better quality\nint connGreedyTilt(int g[10][10]) {\n    int bestA=-1, bestD=0, tmp[10][10];\n    for(int d=0;d<4;d++){\n        memcpy(tmp,g,400); tilt(tmp,d);\n        int a=connectivity(tmp);\n        if(a>bestA){bestA=a;bestD=d;}\n    }\n    return bestD;\n}\n\nint simulate(const int g[10][10], const int* flavors, int from, int total, int depth, bool useConn) {\n    int tmp[10][10];\n    memcpy(tmp,g,400);\n    int end=min(total,from+depth);\n    for(int t=from;t<end;t++){\n        int empty=countEmpty(tmp);\n        if(empty<=0) break;\n        placeAt(tmp,rng()%empty,flavors[t]);\n        if(useConn)\n            tilt(tmp,connGreedyTilt(tmp));\n        else\n            tilt(tmp,adjGreedyTilt(tmp));\n    }\n    return connectivity(tmp);\n}\n\nconst char dirC[]={'F','B','L','R'};\n\nint main(){\n    ios::sync_with_stdio(false);\n    int f[100]; for(int i=0;i<100;i++) cin>>f[i];\n    memset(G,0,sizeof(G));\n\n    auto startTime=chrono::steady_clock::now();\n\n    for(int t=0;t<100;t++){\n        int p; cin>>p; p--;\n        placeAt(G,p,f[t]);\n\n        int remaining=100-t-1;\n        auto now=chrono::steady_clock::now();\n        double elapsed=chrono::duration<double>(now-startTime).count();\n        double timeLeft=1.85-elapsed;\n        double timePerStep=timeLeft/max(1,100-t);\n\n        // Use connectivity-based greedy for small depths, adjacency for larger\n        bool useConn = (remaining <= 12);\n        int depth = min(remaining, useConn ? 12 : 15);\n\n        double bestVal=-1e18; int bestd=0;\n\n        if(remaining>=3 && timePerStep>0.0005) {\n            auto stepStart=chrono::steady_clock::now();\n            double scores[4]={}; int counts[4]={};\n\n            for(int d=0;d<4;d++){\n                int tmp[10][10]; memcpy(tmp,G,400);\n                tilt(tmp,d);\n                scores[d]+=simulate(tmp,f,t+1,100,depth,useConn);\n                counts[d]++;\n            }\n\n            int batch=0;\n            while(true){\n                for(int d=0;d<4;d++){\n                    int tmp[10][10]; memcpy(tmp,G,400);\n                    tilt(tmp,d);\n                    scores[d]+=simulate(tmp,f,t+1,100,depth,useConn);\n                    counts[d]++;\n                }\n                batch++;\n                if(batch%2==0){\n                    auto cur=chrono::steady_clock::now();\n                    if(chrono::duration<double>(cur-stepStart).count()>timePerStep) break;\n                }\n            }\n\n            for(int d=0;d<4;d++){\n                double val=scores[d]/(double)counts[d];\n                if(val>bestVal){bestVal=val;bestd=d;}\n            }\n        } else {\n            for(int d=0;d<4;d++){\n                int tmp[10][10]; memcpy(tmp,G,400);\n                tilt(tmp,d);\n                double val=connectivity(tmp)+0.5*adjacency(tmp);\n                if(val>bestVal){bestVal=val;bestd=d;}\n            }\n        }\n\n        tilt(G,bestd);\n        cout<<dirC[bestd]<<\"\\n\"<<flush;\n    }\n}","ahc016":"#include <bits/stdc++.h>\n#include <Eigen/Dense>\nusing namespace std;\n\nint N;\n\nvector<double> get_features(vector<vector<int>>& adj){\n    int n=N;\n    vector<int> deg(n,0);\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(adj[i][j]) deg[i]++;\n    vector<int> sdeg=deg; sort(sdeg.begin(),sdeg.end());\n    \n    vector<int> tri(n,0);\n    if(n<=60){\n        for(int i=0;i<n;i++)\n            for(int j=0;j<n;j++) if(adj[i][j])\n                for(int k=j+1;k<n;k++) if(adj[i][k]&&adj[j][k])\n                    tri[i]++;\n    }\n    vector<int> stri=tri; sort(stri.begin(),stri.end());\n    \n    vector<double> ndeg(n,0);\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(adj[i][j]) ndeg[i]+=deg[j];\n    vector<double> sndeg=ndeg; sort(sndeg.begin(),sndeg.end());\n    \n    Eigen::MatrixXd A(n,n);\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) A(i,j)=adj[i][j];\n    Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> es(A, Eigen::EigenvaluesOnly);\n    auto evals=es.eigenvalues();\n    vector<double> eigvals(n);\n    for(int i=0;i<n;i++) eigvals[i]=evals(i);\n    sort(eigvals.begin(),eigvals.end());\n    \n    vector<double> feat;\n    for(int i=0;i<n;i++) feat.push_back(sdeg[i]);\n    for(int i=0;i<n;i++) feat.push_back(eigvals[i]*1.0);\n    if(n<=60) for(int i=0;i<n;i++) feat.push_back(stri[i]*0.3);\n    for(int i=0;i<n;i++) feat.push_back(sndeg[i]*0.02);\n    return feat;\n}\n\nsize_t wl_hash(vector<vector<int>>& adj){\n    int n=N;\n    vector<int> color(n);\n    vector<int> deg(n,0);\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(adj[i][j]) deg[i]++;\n    for(int i=0;i<n;i++) color[i]=deg[i];\n    for(int iter=0;iter<15;iter++){\n        map<pair<int,vector<int>>,int> mp;\n        vector<int> nc(n);\n        for(int i=0;i<n;i++){\n            vector<int> nb;\n            for(int j=0;j<n;j++) if(adj[i][j]) nb.push_back(color[j]);\n            sort(nb.begin(),nb.end());\n            auto key=make_pair(color[i],nb);\n            if(!mp.count(key)){int s=(int)mp.size();mp[key]=s;}\n            nc[i]=mp[key];\n        }\n        color=nc;\n    }\n    vector<int> sc=color; sort(sc.begin(),sc.end());\n    size_t h=0;\n    for(int c:sc){h^=hash<int>()(c)+0x9e3779b9+(h<<6)+(h>>2);}\n    return h;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto t0=chrono::steady_clock::now();\n    auto elapsed=[&]()->double{return chrono::duration<double>(chrono::steady_clock::now()-t0).count();};\n    \n    int M; double eps;\n    cin>>M>>eps;\n    \n    if(eps<0.001){\n        // Conservative: plenty of non-isomorphic graphs\n        if(M<=6) N=4;\n        else if(M<=15) N=5;\n        else if(M<=50) N=6;\n        else N=7;\n    } else if(eps<=0.02){\n        N=min(100,max(6,(int)(1.8*sqrt((double)M))+2));\n    } else if(eps<=0.05){\n        N=min(100,max(8,(int)(2.0*sqrt((double)M))+3));\n    } else if(eps<=0.10){\n        N=min(100,max(10,(int)(2.3*sqrt((double)M))+4));\n    } else if(eps<=0.15){\n        N=min(100,max(12,(int)(2.5*sqrt((double)M))+5));\n    } else if(eps<=0.20){\n        N=min(100,max(14,(int)(2.8*sqrt((double)M))+6));\n    } else if(eps<=0.25){\n        N=min(100,max(18,(int)(3.2*sqrt((double)M))+7));\n    } else if(eps<=0.30){\n        N=min(100,max(22,(int)(3.5*sqrt((double)M))+8));\n    } else if(eps<=0.35){\n        N=min(100,max(28,(int)(4.0*sqrt((double)M))+9));\n    } else {\n        N=min(100,max(35,(int)(4.5*sqrt((double)M))+12));\n    }\n    N=max(N,4);\n    \n    int E=N*(N-1)/2;\n    mt19937 rng(42);\n    \n    auto to_str=[&](vector<vector<int>>&adj)->string{\n        string s;for(int i=0;i<N;i++)for(int j=i+1;j<N;j++)s+=(char)('0'+adj[i][j]);return s;\n    };\n    \n    auto make_random_graph=[&](int ne)->vector<vector<int>>{\n        vector<vector<int>> adj(N,vector<int>(N,0));\n        vector<pair<int,int>> ae;\n        for(int i=0;i<N;i++)for(int j=i+1;j<N;j++)ae.push_back({i,j});\n        shuffle(ae.begin(),ae.end(),rng);\n        ne=max(0,min(E,ne));\n        for(int e=0;e<ne;e++){adj[ae[e].first][ae[e].second]=1;adj[ae[e].second][ae[e].first]=1;}\n        return adj;\n    };\n    \n    vector<vector<vector<int>>> adjs(M);\n    vector<vector<double>> features(M);\n    \n    if(eps<0.001){\n        // Use both WL hash and feature vector for uniqueness\n        set<size_t> used_h;\n        vector<vector<double>> used_f;\n        int found=0;\n        while(found<M && elapsed()<2.0){\n            int ne=rng()%(E+1);\n            auto adj=make_random_graph(ne);\n            size_t h=wl_hash(adj);\n            if(!used_h.count(h)){\n                auto feat=get_features(adj);\n                bool dup=false;\n                for(auto&uf:used_f){\n                    double d=0;\n                    for(size_t f=0;f<feat.size();f++){double df=feat[f]-uf[f];d+=df*df;}\n                    if(d<1e-6){dup=true;break;}\n                }\n                if(!dup){\n                    used_h.insert(h);\n                    used_f.push_back(feat);\n                    adjs[found]=adj;features[found]=feat;found++;\n                }\n            }\n        }\n        while(found<M){\n            adjs[found]=make_random_graph(found*E/M);\n            features[found]=get_features(adjs[found]);\n            found++;\n        }\n    } else {\n        int trials=max(30,min(500,8000/M));\n        for(int k=0;k<M;k++){\n            double density=(k+0.5)/M;\n            int target=max(0,min(E,(int)round(density*E)));\n            vector<vector<int>> best_adj;\n            vector<double> best_feat;\n            double best_min_dist=-1;\n            for(int t=0;t<trials && elapsed()<3.8;t++){\n                vector<vector<int>> adj(N,vector<int>(N,0));\n                if(t%3==0){\n                    adj=make_random_graph(target+((int)(rng()%5))-2);\n                } else if(t%3==1){\n                    int kh=max(1,min(N-1,(int)(density*N)));\n                    for(int i=0;i<kh;i++)for(int j=kh;j<N;j++) if((int)(rng()%1000)<(int)(density*1500)){adj[i][j]=adj[j][i]=1;}\n                    for(int i=0;i<kh;i++)for(int j=i+1;j<kh;j++) if((int)(rng()%1000)<(int)(density*2000)){adj[i][j]=adj[j][i]=1;}\n                } else {\n                    for(int i=0;i<N;i++){double pi=density*(0.3+1.4*i/N);for(int j=i+1;j<N;j++)if((int)(rng()%10000)<(int)(pi*10000)){adj[i][j]=adj[j][i]=1;}}\n                }\n                auto feat=get_features(adj);\n                double min_dist=1e18;\n                for(int j=0;j<k;j++){\n                    double d=0;for(size_t f=0;f<feat.size();f++){double df=feat[f]-features[j][f];d+=df*df;}\n                    min_dist=min(min_dist,d);\n                }\n                if(min_dist>best_min_dist){best_min_dist=min_dist;best_adj=adj;best_feat=feat;}\n            }\n            adjs[k]=best_adj;features[k]=best_feat;\n        }\n    }\n    \n    cout<<N<<\"\\n\";\n    for(int k=0;k<M;k++) cout<<to_str(adjs[k])<<\"\\n\";\n    cout.flush();\n    \n    for(int q=0;q<100;q++){\n        string h;cin>>h;\n        vector<vector<int>> hadj(N,vector<int>(N,0));\n        int idx=0;\n        for(int i=0;i<N;i++)for(int j=i+1;j<N;j++){hadj[i][j]=hadj[j][i]=h[idx++]-'0';}\n        auto hfeat=get_features(hadj);\n        int best=-1;double bestd=1e18;\n        for(int k=0;k<M;k++){\n            double d=0;\n            for(size_t f=0;f<hfeat.size();f++){double df=hfeat[f]-features[k][f];d+=df*df;}\n            if(d<bestd){bestd=d;best=k;}\n        }\n        cout<<best<<\"\\n\";cout.flush();\n    }\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N,M,D,K;\nint eu[3001],ev[3001],ew[3001];\nvector<pair<int,int>> adj[1001];\nint nSample;\nint samples[1001];\nlong long origDist[50][1001];\nlong long tmpDist[1001];\nbool removed[3001];\n\nvoid dijkstra(int src, long long* dist){\n    for(int i=0;i<N;i++) dist[i]=1e18;\n    dist[src]=0;\n    // Use bucket queue / priority queue\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 [d,u]=pq.top(); pq.pop();\n        if(d>dist[u]) continue;\n        for(auto& [v,ei]:adj[u]){\n            if(removed[ei]) continue;\n            long long nd=d+ew[ei];\n            if(nd<dist[v]){\n                dist[v]=nd;\n                pq.push({nd,v});\n            }\n        }\n    }\n}\n\ndouble evalDayInline(const vector<int>& edges_on_day){\n    for(int e : edges_on_day) removed[e] = true;\n    double total = 0;\n    for(int si=0; si<nSample; si++){\n        dijkstra(samples[si], tmpDist);\n        for(int j=0; j<N; j++){\n            long long dd = (tmpDist[j] >= (long long)1e18) ? (long long)1e9 : tmpDist[j];\n            total += (double)(dd - origDist[si][j]);\n        }\n    }\n    for(int e : edges_on_day) removed[e] = false;\n    return total;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin>>N>>M>>D>>K;\n    for(int i=0;i<M;i++){\n        cin>>eu[i]>>ev[i]>>ew[i];\n        eu[i]--; ev[i]--;\n        adj[eu[i]].push_back({ev[i],i});\n        adj[ev[i]].push_back({eu[i],i});\n    }\n    {int x,y; for(int i=0;i<N;i++) cin>>x>>y;}\n    \n    mt19937 rng(42);\n    nSample = min(N, 15);\n    {\n        vector<int> tmp(N);\n        iota(tmp.begin(),tmp.end(),0);\n        shuffle(tmp.begin(),tmp.end(),rng);\n        for(int i=0;i<nSample;i++) samples[i]=tmp[i];\n    }\n    \n    memset(removed,0,sizeof(removed));\n    for(int i=0;i<nSample;i++) dijkstra(samples[i], origDist[i]);\n    \n    // Edge importance\n    vector<double> importance(M, 0);\n    for(int si=0;si<nSample;si++){\n        vector<int> idx(N); iota(idx.begin(),idx.end(),0);\n        sort(idx.begin(),idx.end(),[&](int a,int b){return origDist[si][a]<origDist[si][b];});\n        vector<double> sub(N, 1.0);\n        for(int i=N-1;i>=0;i--){\n            int v=idx[i];\n            if(v==samples[si]) continue;\n            for(auto& [u,ei]:adj[v]){\n                if(origDist[si][u]+ew[ei]==origDist[si][v]){\n                    sub[u]+=sub[v];\n                    importance[ei]+=sub[v];\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Initial: spread important edges round-robin\n    vector<int> order(M);\n    iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),[&](int a,int b){return importance[a]>importance[b];});\n    \n    vector<int> asgn(M);\n    vector<vector<int>> dayEdges(D);\n    for(int i=0;i<M;i++){\n        int day=i%D;\n        asgn[order[i]]=day;\n        dayEdges[day].push_back(order[i]);\n    }\n    \n    vector<double> dayScore(D);\n    double totalScore=0;\n    for(int d=0;d<D;d++){\n        dayScore[d]=evalDayInline(dayEdges[d]);\n        totalScore+=dayScore[d];\n    }\n    \n    double bestTotal=totalScore;\n    vector<int> bestAsgn=asgn;\n    \n    auto startTime=chrono::steady_clock::now();\n    double timeLimit=5.3;\n    \n    auto getTime=[&](){\n        return chrono::duration<double>(chrono::steady_clock::now()-startTime).count();\n    };\n    \n    // Pre-compute max day for targeting\n    auto worstDay=[&]()->int{\n        return max_element(dayScore.begin(),dayScore.end())-dayScore.begin();\n    };\n    \n    int iter=0;\n    while(true){\n        double t=getTime();\n        if(t>timeLimit) break;\n        double progress=t/timeLimit;\n        double startTemp=bestTotal/(D*10.0);\n        double endTemp=bestTotal/(D*10000.0);\n        double curTemp=startTemp*pow(endTemp/max(startTemp,1.0),progress);\n        \n        // 50% target worst day, 50% random\n        int moveType=rng()%4;\n        \n        if(moveType<3){\n            // Swap two edges between two days\n            int d1,d2;\n            if(moveType==0){\n                d1=worstDay();\n                d2=rng()%D;\n            } else {\n                d1=rng()%D;\n                d2=rng()%D;\n            }\n            if(d1==d2||dayEdges[d1].empty()||dayEdges[d2].empty()) continue;\n            int i1=rng()%dayEdges[d1].size();\n            int i2=rng()%dayEdges[d2].size();\n            int e1=dayEdges[d1][i1], e2=dayEdges[d2][i2];\n            \n            dayEdges[d1][i1]=e2;\n            dayEdges[d2][i2]=e1;\n            \n            double ns1=evalDayInline(dayEdges[d1]);\n            double ns2=evalDayInline(dayEdges[d2]);\n            double delta=(ns1+ns2)-(dayScore[d1]+dayScore[d2]);\n            \n            if(delta<0||exp(-delta/curTemp)>(rng()%1000000)/1000000.0){\n                asgn[e1]=d2; asgn[e2]=d1;\n                dayScore[d1]=ns1; dayScore[d2]=ns2;\n                totalScore+=delta;\n                if(totalScore<bestTotal){bestTotal=totalScore;bestAsgn=asgn;}\n            } else {\n                dayEdges[d1][i1]=e1; dayEdges[d2][i2]=e2;\n            }\n        } else {\n            // Move edge\n            int e=rng()%M;\n            int od=asgn[e], nd=rng()%D;\n            if(od==nd||(int)dayEdges[nd].size()>=K) continue;\n            auto& ov=dayEdges[od];\n            int pos=find(ov.begin(),ov.end(),e)-ov.begin();\n            ov[pos]=ov.back(); ov.pop_back();\n            dayEdges[nd].push_back(e);\n            double ns1=evalDayInline(ov);\n            double ns2=evalDayInline(dayEdges[nd]);\n            double delta=(ns1+ns2)-(dayScore[od]+dayScore[nd]);\n            if(delta<0||exp(-delta/curTemp)>(rng()%1000000)/1000000.0){\n                asgn[e]=nd; dayScore[od]=ns1; dayScore[nd]=ns2; totalScore+=delta;\n                if(totalScore<bestTotal){bestTotal=totalScore;bestAsgn=asgn;}\n            } else {\n                dayEdges[nd].pop_back(); ov.push_back(e);\n            }\n        }\n        iter++;\n    }\n    \n    for(int i=0;i<M;i++){\n        cout<<bestAsgn[i]+1;\n        if(i<M-1) cout<<' ';\n    }\n    cout<<'\\n';\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct HopcroftKarp {\n    int n,m;\n    vector<vector<int>> adj;\n    vector<int> matchL,matchR,dist;\n    HopcroftKarp(int n,int m):n(n),m(m),adj(n),matchL(n,-1),matchR(m,-1),dist(n){}\n    void addEdge(int u,int v){adj[u].push_back(v);}\n    bool bfs(){\n        queue<int>q;\n        for(int u=0;u<n;u++){if(matchL[u]<0){dist[u]=0;q.push(u);}else dist[u]=1e9;}\n        bool found=false;\n        while(!q.empty()){int u=q.front();q.pop();for(int v:adj[u]){int w=matchR[v];if(w<0)found=true;else if(dist[w]>dist[u]+1){dist[w]=dist[u]+1;q.push(w);}}}\n        return found;\n    }\n    bool dfs(int u){\n        for(int v:adj[u]){int w=matchR[v];if(w<0||(dist[w]==dist[u]+1&&dfs(w))){matchL[u]=v;matchR[v]=u;return true;}}\n        dist[u]=1e9;return false;\n    }\n    int maxMatch(){int res=0;while(bfs())for(int u=0;u<n;u++)if(matchL[u]<0)res+=dfs(u);return res;}\n};\n\nint D,D3;\n\nint main(){\n    scanf(\"%d\",&D);D3=D*D*D;\n    vector<string> f[2],r[2];\n    for(int i=0;i<2;i++){f[i].resize(D);for(int k=0;k<D;k++)cin>>f[i][k];r[i].resize(D);for(int k=0;k<D;k++)cin>>r[i][k];}\n    int dxs[]={1,-1,0,0,0,0},dys[]={0,0,1,-1,0,0},dzs[]={0,0,0,0,1,-1};\n    auto idx=[&](int x,int y,int z){return x*D*D+y*D+z;};\n    \n    vector<bool> valid[2];\n    vector<int> cells[2];\n    for(int ci=0;ci<2;ci++){\n        valid[ci].assign(D3,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(f[ci][z][x]=='1'&&r[ci][z][y]=='1'){valid[ci][idx(x,y,z)]=true;cells[ci].push_back(idx(x,y,z));}\n    }\n\n    auto maxDominoes=[&](int ci)->pair<vector<pair<int,int>>,vector<int>>{\n        vector<int> black,white;\n        map<int,int> bIdx,wIdx;\n        for(int c:cells[ci]){int x=c/(D*D),y=(c/D)%D,z=c%D;if((x+y+z)%2==0){bIdx[c]=(int)black.size();black.push_back(c);}else{wIdx[c]=(int)white.size();white.push_back(c);}}\n        HopcroftKarp hk((int)black.size(),(int)white.size());\n        for(int i=0;i<(int)black.size();i++){\n            int c=black[i];int x=c/(D*D),y=(c/D)%D,z=c%D;\n            for(int d=0;d<6;d++){int nx=x+dxs[d],ny=y+dys[d],nz=z+dzs[d];\n                if(nx>=0&&ny>=0&&nz>=0&&nx<D&&ny<D&&nz<D){auto it=wIdx.find(idx(nx,ny,nz));if(it!=wIdx.end())hk.addEdge(i,it->second);}}\n        }\n        hk.maxMatch();\n        vector<pair<int,int>> doms;vector<bool> used(D3,false);\n        for(int i=0;i<(int)black.size();i++)if(hk.matchL[i]>=0){doms.push_back({black[i],white[hk.matchL[i]]});used[black[i]]=used[white[hk.matchL[i]]]=true;}\n        vector<int> singles;for(int c:cells[ci])if(!used[c])singles.push_back(c);\n        return{doms,singles};\n    };\n\n    auto[dom0,sin0]=maxDominoes(0);\n    auto[dom1,sin1]=maxDominoes(1);\n    int nd0=dom0.size(),nd1=dom1.size();\n    int shared=min(nd0,nd1);\n\n    // For each domino, determine its axis (direction)\n    auto getAxis=[&](pair<int,int>&d)->int{\n        int c1=d.first,c2=d.second;\n        int x1=c1/(D*D),y1=(c1/D)%D,z1=c1%D;\n        int x2=c2/(D*D),y2=(c2/D)%D,z2=c2%D;\n        if(x1!=x2)return 0;if(y1!=y2)return 1;return 2;\n    };\n    \n    // For each domino, get its \"line key\": (axis, min coord along other axes, min coord along axis)\n    auto getLineKey=[&](pair<int,int>&d)->tuple<int,int,int,int>{\n        int c1=d.first,c2=d.second;\n        int x1=c1/(D*D),y1=(c1/D)%D,z1=c1%D;\n        int x2=c2/(D*D),y2=(c2/D)%D,z2=c2%D;\n        int axis=getAxis(d);\n        if(axis==0)return{0,y1,z1,min(x1,x2)};\n        if(axis==1)return{1,x1,z1,min(y1,y2)};\n        return{2,x1,y1,min(z1,z2)};\n    };\n    \n    // For merging: two dominoes can merge into a line of 4 if they're on the same axis,\n    // same cross-section, and adjacent along that axis\n    // domino at positions [a,a+1] and [a+2,a+3] merge into [a,a+1,a+2,a+3]\n    \n    // Build merge graph for shared dominoes\n    // shared domino i: dom0[i] in config0, dom1[i] in config1\n    // We can merge shared domino i and j if they can merge in BOTH configs\n    \n    // For each config, group dominoes by (axis, cross-section)\n    // Within each group, sort by position along axis\n    // Adjacent dominoes in this sorted order can potentially merge\n    \n    // First, let's build adjacency for shared dominoes in each config\n    auto buildAdj=[&](vector<pair<int,int>>&doms,int count)->vector<vector<int>>{\n        // For each domino, compute (axis, cross1, cross2, minPos)\n        map<tuple<int,int,int>,vector<pair<int,int>>> groups; // key->(pos,domIdx)\n        for(int i=0;i<count;i++){\n            auto[axis,c1,c2,pos]=getLineKey(doms[i]);\n            groups[{axis,c1,c2}].push_back({pos,i});\n        }\n        vector<vector<int>> adj(count);\n        for(auto&[key,vec]:groups){\n            sort(vec.begin(),vec.end());\n            for(int i=0;i+1<(int)vec.size();i++){\n                if(vec[i+1].first==vec[i].first+2){\n                    adj[vec[i].second].push_back(vec[i+1].second);\n                    adj[vec[i+1].second].push_back(vec[i].second);\n                }\n            }\n        }\n        return adj;\n    };\n    \n    auto adj0=buildAdj(dom0,shared);\n    auto adj1=buildAdj(dom1,shared);\n    \n    // Find edges present in BOTH adjacency lists\n    // Then find chains (paths) in this intersection graph\n    // Greedily form longest chains -> merge into lines\n    \n    vector<set<int>> bothAdj(shared);\n    for(int i=0;i<shared;i++){\n        set<int> s0(adj0[i].begin(),adj0[i].end());\n        for(int j:adj1[i])if(s0.count(j))bothAdj[i].insert(j);\n    }\n    \n    // Each node has degree <= 2 in each config's adjacency (it's a line graph)\n    // In the intersection, degree can be <= 2\n    // Find chains greedily\n    vector<bool> visited(shared,false);\n    vector<vector<int>> chains;\n    for(int i=0;i<shared;i++){\n        if(visited[i])continue;\n        if(bothAdj[i].empty()){chains.push_back({i});visited[i]=true;continue;}\n        // Find one end of chain\n        int start=i;\n        // BFS/DFS to find chain\n        vector<int> chain;\n        int prev=-1,cur=start;\n        while(true){\n            visited[cur]=true;\n            chain.push_back(cur);\n            int next=-1;\n            for(int nb:bothAdj[cur])if(nb!=prev&&!visited[nb]){next=nb;break;}\n            if(next<0)break;\n            prev=cur;cur=next;\n        }\n        chains.push_back(chain);\n    }\n    \n    // Now assign blocks\n    vector<int> b1(D3,0),b2(D3,0);\n    int n=0;\n    double score=0;\n    \n    for(auto&chain:chains){\n        // This chain of dominoes forms a line of length 2*chain.size() in both configs\n        int len=2*(int)chain.size();\n        n++;\n        for(int di:chain){\n            b1[dom0[di].first]=n;b1[dom0[di].second]=n;\n            b2[dom1[di].first]=n;b2[dom1[di].second]=n;\n        }\n        score+=1.0/len;\n    }\n    \n    // Remaining: unshared dominoes + singles\n    vector<int> flat0,flat1;\n    for(int i=shared;i<nd0;i++){flat0.push_back(dom0[i].first);flat0.push_back(dom0[i].second);}\n    for(int c:sin0)flat0.push_back(c);\n    for(int i=shared;i<nd1;i++){flat1.push_back(dom1[i].first);flat1.push_back(dom1[i].second);}\n    for(int c:sin1)flat1.push_back(c);\n    \n    int su=min((int)flat0.size(),(int)flat1.size());\n    for(int i=0;i<su;i++){n++;b1[flat0[i]]=n;b2[flat1[i]]=n;score+=1.0;}\n    if((int)flat0.size()>su)for(int i=su;i<(int)flat0.size();i++){n++;b1[flat0[i]]=n;score+=1.0;}\n    else for(int i=su;i<(int)flat1.size();i++){n++;b2[flat1[i]]=n;score+=1.0;}\n    \n    printf(\"%d\\n\",n);\n    for(int i=0;i<D3;i++)printf(\"%d%c\",b1[i],\" \\n\"[i==D3-1]);\n    for(int i=0;i<D3;i++)printf(\"%d%c\",b2[i],\" \\n\"[i==D3-1]);\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint N,M,K;\nvector<ll> vx,vy;\nvector<int> eu_,ev_;\nvector<ll> ew_;\nvector<ll> ra,rb;\nvector<vector<pair<int,int>>> adj;\nvector<vector<ll>> spd;\nvector<vector<int>> spp;\nvector<vector<int>> cands;\nvector<vector<int>> rdist_c;\nvector<vector<int>> vtx_res;\n\nmt19937 rng(42);\nchrono::steady_clock::time_point t0;\ndouble elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-t0).count();}\n\nvoid dijkstra(int s){\n    priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<>> pq;\n    spd[s][s]=0;pq.push({0,s});\n    while(!pq.empty()){\n        auto[d,u]=pq.top();pq.pop();\n        if(d>spd[s][u]) continue;\n        for(auto&[v,eid]:adj[u]){\n            ll nd=d+ew_[eid];\n            if(nd<spd[s][v]){spd[s][v]=nd;spp[s][v]=eid;pq.push({nd,v});}\n        }\n    }\n}\n\nvector<bool> bfs_tree(const vector<bool>& eu){\n    vector<bool> vis(N,false);\n    queue<int> q;q.push(0);vis[0]=true;\n    while(!q.empty()){\n        int u=q.front();q.pop();\n        for(auto&[v,eid]:adj[u])\n            if(eu[eid]&&!vis[v]){vis[v]=true;q.push(v);}\n    }\n    return vis;\n}\n\npair<ll,vector<bool>> build_steiner(const vector<bool>& active){\n    vector<bool> inT(N,false),eU(M,false);\n    ll cost=0;inT[0]=true;\n    vector<int> tg;\n    for(int i=0;i<N;i++) if(active[i]&&i!=0) tg.push_back(i);\n    int nt=(int)tg.size();\n    vector<ll> md(nt);vector<int> ms(nt);\n    for(int t=0;t<nt;t++){md[t]=spd[0][tg[t]];ms[t]=0;}\n    vector<bool> added(nt,false);\n    for(int step=0;step<nt;step++){\n        int bi=-1;ll bd=1e18;\n        for(int t=0;t<nt;t++) if(!added[t]&&md[t]<bd){bd=md[t];bi=t;}\n        if(bi<0) break;added[bi]=true;\n        int tgt=tg[bi],src=ms[bi];\n        vector<int> nn;int cur=tgt;\n        while(cur!=src){\n            int eid=spp[src][cur];\n            if(!eU[eid]){eU[eid]=true;cost+=ew_[eid];}\n            int u=eu_[eid],v=ev_[eid];\n            if(!inT[cur]) nn.push_back(cur);\n            inT[cur]=true;cur=(u==cur)?v:u;\n        }\n        inT[tgt]=true;nn.push_back(tgt);\n        for(int t=0;t<nt;t++){\n            if(added[t]) continue;\n            for(int n2:nn) if(spd[n2][tg[t]]<md[t]){md[t]=spd[n2][tg[t]];ms[t]=n2;}\n        }\n    }\n    return{cost,eU};\n}\n\nstruct Sol{\n    vector<int> P, assign;\n    vector<bool> edgeUsed, inTree;\n    ll totalCost;\n    int covered;\n    bool valid()const{return covered==K;}\n};\n\n// Safe greedy assignment\nvoid greedy_assign(Sol& s, int passes, ll eCost){\n    vector<int> bestA(K,-1);ll bestPC=1e18;int bestC=0;\n    vector<int> order(K);iota(order.begin(),order.end(),0);\n    for(int pass=0;pass<passes;pass++){\n        if(pass>0) shuffle(order.begin(),order.end(),rng);\n        vector<int> curP(N,0),curA(K,-1);int curC=0;\n        for(int k:order){\n            int bv=-1;ll bm=1e18;\n            for(int i:cands[k]){\n                if(!s.inTree[i]) continue;\n                int r=rdist_c[k][i],np=max(curP[i],r);\n                ll m=(ll)np*np-(ll)curP[i]*curP[i];\n                if(m<bm){bm=m;bv=i;}\n            }\n            if(bv>=0){curA[k]=bv;curP[bv]=max(curP[bv],rdist_c[k][bv]);curC++;}\n        }\n        ll pc=0;for(int i=0;i<N;i++) pc+=(ll)curP[i]*curP[i];\n        if(curC>bestC||(curC==bestC&&pc<bestPC)){bestPC=pc;bestA=curA;bestC=curC;}\n    }\n    s.assign=bestA;s.covered=bestC;\n    s.P.assign(N,0);\n    for(int k=0;k<K;k++) if(s.assign[k]>=0) s.P[s.assign[k]]=max(s.P[s.assign[k]],rdist_c[k][s.assign[k]]);\n    s.totalCost=bestPC+eCost;\n}\n\n// Safe improvement: try to move farthest resident from each vertex\nvoid safe_improve(Sol& s, ll eCost){\n    for(int iter=0;iter<15;iter++){\n        bool changed=false;\n        \n        // Rebuild P and find per-vertex info\n        s.P.assign(N,0);\n        for(int k=0;k<K;k++) if(s.assign[k]>=0)\n            s.P[s.assign[k]]=max(s.P[s.assign[k]],rdist_c[k][s.assign[k]]);\n        \n        for(int i=0;i<N;i++){\n            if(s.P[i]==0) continue;\n            \n            // Find farthest resident and second farthest\n            int mx1=0,mx2=0,fk=-1;\n            bool multi=false;\n            for(int k:vtx_res[i]){\n                if(s.assign[k]!=i) continue;\n                int r=rdist_c[k][i];\n                if(r>mx1){mx2=mx1;mx1=r;fk=k;multi=false;}\n                else if(r==mx1){multi=true;}\n                else if(r>mx2) mx2=r;\n            }\n            \n            if(fk<0||multi) continue;\n            \n            ll savings=(ll)mx1*mx1-(ll)mx2*mx2;\n            int ba=-1;ll bac=1e18;\n            for(int j:cands[fk]){\n                if(j==i||!s.inTree[j]) continue;\n                int r=rdist_c[fk][j],np=max(s.P[j],r);\n                ll ac=(ll)np*np-(ll)s.P[j]*s.P[j];\n                if(ac<bac){bac=ac;ba=j;}\n            }\n            if(ba>=0&&bac<savings){\n                s.assign[fk]=ba;\n                changed=true;\n            }\n        }\n        \n        if(!changed) break;\n        \n        // Recompute P and cost from scratch\n        s.P.assign(N,0);\n        for(int k=0;k<K;k++) if(s.assign[k]>=0)\n            s.P[s.assign[k]]=max(s.P[s.assign[k]],rdist_c[k][s.assign[k]]);\n        ll pc=0;for(int i=0;i<N;i++) pc+=(ll)s.P[i]*s.P[i];\n        s.totalCost=pc+eCost;\n    }\n}\n\nSol make_sol(const vector<bool>& active, int passes){\n    Sol s;\n    auto[tc,eu]=build_steiner(active);\n    s.edgeUsed=eu;\n    s.inTree=bfs_tree(s.edgeUsed);\n    greedy_assign(s,passes,tc);\n    safe_improve(s,tc);\n    return s;\n}\n\nSol run_sol(const vector<bool>& active, int passes, int rebuilds){\n    Sol s=make_sol(active,passes);\n    for(int r=0;r<rebuilds;r++){\n        vector<bool> a2(N,false);a2[0]=true;\n        for(int i=0;i<N;i++) if(s.P[i]>0) a2[i]=true;\n        s=make_sol(a2,passes);\n    }\n    return s;\n}\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    t0=chrono::steady_clock::now();\n    \n    cin>>N>>M>>K;\n    vx.resize(N);vy.resize(N);\n    for(int i=0;i<N;i++) cin>>vx[i]>>vy[i];\n    eu_.resize(M);ev_.resize(M);ew_.resize(M);\n    for(int j=0;j<M;j++){cin>>eu_[j]>>ev_[j]>>ew_[j];eu_[j]--;ev_[j]--;}\n    ra.resize(K);rb.resize(K);\n    for(int k=0;k<K;k++) cin>>ra[k]>>rb[k];\n    \n    adj.resize(N);\n    for(int j=0;j<M;j++){adj[eu_[j]].push_back({ev_[j],j});adj[ev_[j]].push_back({eu_[j],j});}\n    spd.assign(N,vector<ll>(N,1e18));spp.assign(N,vector<int>(N,-1));\n    for(int s=0;s<N;s++) dijkstra(s);\n    \n    cands.resize(K);rdist_c.assign(K,vector<int>(N,60000));vtx_res.resize(N);\n    for(int k=0;k<K;k++){\n        for(int i=0;i<N;i++){\n            double dx=(double)(vx[i]-ra[k]),dy=(double)(vy[i]-rb[k]);\n            double d=sqrt(dx*dx+dy*dy);\n            int r=(int)ceil(d-1e-9);\n            rdist_c[k][i]=r;\n            if(r<=5000){cands[k].push_back(i);vtx_res[i].push_back(k);}\n        }\n    }\n    \n    Sol best;best.totalCost=1e18;best.covered=0;\n    best.P.assign(N,0);best.edgeUsed.assign(M,false);best.inTree.assign(N,false);best.assign.assign(K,-1);\n    \n    auto upd=[&](Sol& s){if(s.valid()&&(!best.valid()||s.totalCost<best.totalCost)) best=s;};\n    \n    {vector<bool> a(N,true);auto s=run_sol(a,5,2);upd(s);}\n    {\n        vector<bool> a(N,false);a[0]=true;\n        for(int k=0;k<K;k++){int b2=-1,br=60000;for(int i:cands[k]) if(rdist_c[k][i]<br){br=rdist_c[k][i];b2=i;}if(b2>=0) a[b2]=true;}\n        auto s=run_sol(a,5,2);upd(s);\n    }\n    {\n        vector<bool> cov(K,false);vector<bool> a(N,false);a[0]=true;int nc=0;\n        while(nc<K){\n            int bv=-1;double br=1e18;\n            for(int i=0;i<N;i++){\n                int mx=0,cnt=0;\n                for(int k:vtx_res[i]) if(!cov[k]){cnt++;mx=max(mx,rdist_c[k][i]);}\n                if(!cnt) continue;\n                ll ac=(ll)mx*mx;\n                if(!a[i]){ll me=1e18;for(int j=0;j<N;j++) if(a[j]) me=min(me,spd[j][i]);ac+=me;}\n                double r=(double)ac/cnt;if(r<br){br=r;bv=i;}\n            }\n            if(bv<0) break;a[bv]=true;\n            for(int k:vtx_res[bv]) if(!cov[k]){cov[k]=true;nc++;}\n        }\n        auto s=run_sol(a,5,2);upd(s);\n    }\n    \n    if(best.valid()){\n        Sol cur=best;\n        int it=0;\n        while(true){\n            it++;\n            if(it%3==0&&elapsed()>1.6) break;\n            \n            vector<bool> act(N,false);act[0]=true;\n            for(int i=0;i<N;i++) if(cur.P[i]>0||cur.inTree[i]) act[i]=true;\n            \n            int action=rng()%100;\n            if(action<35){\n                vector<int> ac2;for(int i=1;i<N;i++) if(act[i]) ac2.push_back(i);\n                if(ac2.empty()) continue;\n                int v=ac2[rng()%ac2.size()];\n                bool ok=true;\n                for(int k:vtx_res[v]){if(cur.assign[k]!=v) continue;bool f=false;for(int i:cands[k]) if(i!=v&&act[i]){f=true;break;}if(!f){ok=false;break;}}\n                if(!ok) continue;act[v]=false;\n            } else if(action<65){\n                vector<int> ia;for(int i=1;i<N;i++) if(!act[i]) ia.push_back(i);\n                if(ia.empty()) continue;act[ia[rng()%ia.size()]]=true;\n            } else {\n                vector<int> ac2,ia;for(int i=1;i<N;i++){if(cur.P[i]>0) ac2.push_back(i);else if(!act[i]) ia.push_back(i);}\n                if(ac2.empty()||ia.empty()) continue;act[ac2[rng()%ac2.size()]]=false;act[ia[rng()%ia.size()]]=true;\n            }\n            Sol next=run_sol(act,3,1);\n            if(!next.valid()) continue;\n            double temp=2e6*(1.0-elapsed()/1.65)+1e3;\n            ll delta=next.totalCost-cur.totalCost;\n            if(delta<0||(temp>0&&(double)(rng()%1000000)/1e6<exp(-(double)delta/temp))){\n                cur=next;if(cur.totalCost<best.totalCost) best=cur;\n            }\n        }\n    }\n    \n    for(int i=0;i<N;i++) cout<<best.P[i]<<\" \\n\"[i==N-1];\n    for(int j=0;j<M;j++) cout<<(best.edgeUsed[j]?1:0)<<\" \\n\"[j==M-1];\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\nint N=30;\nint orig[30][30];\n\nstruct State {\n    int grid[30][30];\n    int posx[465], posy[465];\n    vector<pair<int,int>> ops; // encoded as single pairs\n    vector<tuple<int,int,int,int>> swaps;\n    \n    void init(){\n        memcpy(grid,orig,sizeof(grid));\n        for(int x=0;x<N;x++) for(int y=0;y<=x;y++){\n            posx[grid[x][y]]=x; posy[grid[x][y]]=y;\n        }\n        swaps.clear();\n    }\n    void do_swap(int x1,int y1,int x2,int y2){\n        swaps.push_back({x1,y1,x2,y2});\n        int a=grid[x1][y1], b=grid[x2][y2];\n        swap(grid[x1][y1],grid[x2][y2]);\n        posx[a]=x2; posy[a]=y2;\n        posx[b]=x1; posy[b]=y1;\n    }\n    void sift_up(int x,int y){\n        while(x>0){\n            int cur=grid[x][y],bpx=-1,bpy=-1,bpv=cur;\n            if(y>0&&grid[x-1][y-1]>bpv){bpx=x-1;bpy=y-1;bpv=grid[x-1][y-1];}\n            if(y<x&&grid[x-1][y]>bpv){bpx=x-1;bpy=y;bpv=grid[x-1][y];}\n            if(bpx==-1)break;\n            do_swap(x,y,bpx,bpy); x=bpx;y=bpy;\n        }\n    }\n    void sift_down(int x,int y){\n        while(x<N-1){\n            int cur=grid[x][y],c1=grid[x+1][y],c2=grid[x+1][y+1];\n            if(cur<=c1&&cur<=c2)break;\n            if(c1<=c2){do_swap(x,y,x+1,y);x++;}\n            else{do_swap(x,y,x+1,y+1);x++;y++;}\n        }\n    }\n    // For each position top-down, pull minimum from subtree\n    void pull_min(int x, int y){\n        // Find min in subtree, sift it up\n        int mx=x, my=y;\n        // Find minimum value reachable by going down\n        function<void(int,int)> findmin=[&](int cx,int cy){\n            if(grid[cx][cy]<grid[mx][my]){mx=cx;my=cy;}\n            if(cx<N-1){findmin(cx+1,cy);findmin(cx+1,cy+1);}\n        };\n        // Too expensive for full subtree, just sift up from bottom\n    }\n    void cleanup(){\n        for(int it=0;it<5;it++){\n            bool ch=false;\n            for(int x=0;x<N-1;x++) for(int y=0;y<=x;y++){\n                int p=swaps.size();sift_down(x,y);if((int)swaps.size()>p)ch=true;\n            }\n            for(int v=0;v<465;v++){\n                int p=swaps.size();sift_up(posx[v],posy[v]);if((int)swaps.size()>p)ch=true;\n            }\n            if(!ch)break;\n        }\n    }\n    int score(){\n        int E=0;\n        for(int x=0;x<N-1;x++) for(int y=0;y<=x;y++){\n            if(grid[x][y]>grid[x+1][y])E++;\n            if(grid[x][y]>grid[x+1][y+1])E++;\n        }\n        if(E==0) return 100000-5*(int)swaps.size();\n        return 50000-50*E;\n    }\n};\n\nint main(){\n    for(int x=0;x<N;x++) for(int y=0;y<=x;y++) scanf(\"%d\",&orig[x][y]);\n    \n    mt19937 rng(42);\n    \n    State best;\n    best.init();\n    // Strategy A: sift up by value\n    for(int v=0;v<465;v++) best.sift_up(best.posx[v],best.posy[v]);\n    best.cleanup();\n    int bestScore = best.score();\n    \n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(1800);\n    \n    while(chrono::steady_clock::now() < deadline){\n        State s;\n        s.init();\n        \n        // Random strategy: shuffle order of values but keep roughly sorted\n        vector<int> order(465);\n        iota(order.begin(),order.end(),0);\n        \n        // Partially shuffle: swap adjacent values with some probability\n        for(int i=0;i<464;i++){\n            if(rng()%3==0) swap(order[i],order[i+1]);\n        }\n        \n        for(int v : order) s.sift_up(s.posx[v],s.posy[v]);\n        s.cleanup();\n        int sc = s.score();\n        if(sc > bestScore){\n            bestScore = sc;\n            best = s;\n        }\n    }\n    \n    printf(\"%d\\n\",(int)best.swaps.size());\n    for(auto&[a,b,c,d]:best.swaps) printf(\"%d %d %d %d\\n\",a,b,c,d);\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\nint D,N;\nint grid[9][9];\nint dx[]={-1,1,0,0},dy[]={0,0,-1,1};\nint ei,ej;\n\nvector<pair<int,int>> get_reachable_empty(){\n    bool vis[9][9]={};\n    queue<pair<int,int>> q;\n    q.push({ei,ej}); vis[ei][ej]=1;\n    vector<pair<int,int>> res;\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>=D||ny<0||ny>=D||vis[nx][ny]) continue;\n            if(grid[nx][ny]!=-1) continue;\n            vis[nx][ny]=1;\n            res.push_back({nx,ny});\n            q.push({nx,ny});\n        }\n    }\n    return res;\n}\n\nbool is_safe(int r,int c,int remaining){\n    if(remaining<=1) return true;\n    grid[r][c]=9999;\n    bool vis[9][9]={};\n    queue<pair<int,int>> q;\n    q.push({ei,ej}); vis[ei][ej]=1;\n    int cnt=0;\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>=D||ny<0||ny>=D||vis[nx][ny]) continue;\n            if(grid[nx][ny]!=-1) continue;\n            vis[nx][ny]=1; cnt++; q.push({nx,ny});\n        }\n    }\n    grid[r][c]=-1;\n    return cnt==remaining-1;\n}\n\nvector<pair<int,int>> get_reachable_containers(){\n    bool vis[9][9]={};\n    queue<pair<int,int>> q;\n    q.push({ei,ej}); vis[ei][ej]=1;\n    vector<pair<int,int>> res;\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>=D||ny<0||ny>=D||vis[nx][ny]||grid[nx][ny]==-2) continue;\n            vis[nx][ny]=1;\n            if(grid[nx][ny]>=0) res.push_back({nx,ny});\n            else q.push({nx,ny});\n        }\n    }\n    return res;\n}\n\n// Compute extraction rank for remaining empty cells\n// Simulate: fill all empty cells with dummy, then extract greedily (farthest first)\n// This gives rank[r][c] = extraction order of cell (r,c)\nvoid compute_extraction_rank(int rank[9][9]){\n    // Save grid state\n    int save[9][9];\n    memcpy(save,grid,sizeof(grid));\n    \n    // Fill all empty cells (except entrance) with dummy containers\n    vector<pair<int,int>> empties;\n    for(int i=0;i<D;i++) for(int j=0;j<D;j++){\n        if(grid[i][j]==-1 && !(i==ei&&j==ej)){\n            empties.push_back({i,j});\n            grid[i][j]=0;\n        }\n    }\n    \n    memset(rank,-1,sizeof(int)*81);\n    int M2=empties.size();\n    \n    for(int k=0;k<M2;k++){\n        // Find reachable containers (boundary)\n        auto rc=get_reachable_containers();\n        // Pick the one with max BFS distance from entrance in original empty grid\n        // Use simple heuristic: pick farthest (Manhattan) from entrance\n        int bestd=-1; pair<int,int> bp;\n        for(auto&[r,c]:rc){\n            int dd=abs(r-ei)+abs(c-ej);\n            if(dd>bestd){bestd=dd;bp={r,c};}\n        }\n        rank[bp.first][bp.second]=k;\n        grid[bp.first][bp.second]=-1;\n    }\n    \n    memcpy(grid,save,sizeof(grid));\n}\n\nint main(){\n    scanf(\"%d%d\",&D,&N);\n    ei=0;ej=(D-1)/2;\n    memset(grid,-1,sizeof(grid));\n    for(int i=0;i<N;i++){int r,c;scanf(\"%d%d\",&r,&c);grid[r][c]=-2;}\n    int M=D*D-1-N;\n    \n    for(int d=0;d<M;d++){\n        int t; scanf(\"%d\",&t);\n        int remaining=M-d;\n        \n        auto empties=get_reachable_empty();\n        \n        vector<pair<int,int>> safe_cells;\n        for(auto&[r,c]:empties){\n            if(is_safe(r,c,remaining)) safe_cells.push_back({r,c});\n        }\n        if(safe_cells.empty()) safe_cells=empties;\n        \n        // Compute extraction rank for current empty cells\n        int rank[9][9];\n        compute_extraction_rank(rank);\n        \n        // Container t should be extracted at position t among all M containers\n        // Currently d containers are placed, remaining empty = M-d\n        // The extraction rank among remaining empty cells: we want the cell\n        // whose rank maps to extraction position t\n        // Scale: t maps to rank position (t - number_of_already_placed_with_lower_id) among remaining\n        // Simpler: among remaining cells, rank goes 0..remaining-1\n        // We want cell with rank closest to t * remaining / M\n        \n        double target_rank = (double)t * (remaining-1) / (M-1);\n        \n        pair<int,int> best={-1,-1}; double bestdiff=1e18;\n        for(auto&[r,c]:safe_cells){\n            if(rank[r][c]<0) continue;\n            double diff=abs(rank[r][c]-target_rank);\n            if(diff<bestdiff){bestdiff=diff;best={r,c};}\n        }\n        if(best.first==-1){\n            // fallback\n            for(auto&[r,c]:safe_cells){\n                int dd=abs(r-ei)+abs(c-ej);\n                double diff=abs(dd*1.0-target_rank);\n                if(diff<bestdiff){bestdiff=diff;best={r,c};}\n            }\n        }\n        \n        grid[best.first][best.second]=t;\n        printf(\"%d %d\\n\",best.first,best.second);\n        fflush(stdout);\n    }\n    \n    for(int i=0;i<M;i++){\n        auto rc=get_reachable_containers();\n        int best=1e9;pair<int,int> bp;\n        for(auto&[r,c]:rc) if(grid[r][c]<best){best=grid[r][c];bp={r,c};}\n        printf(\"%d %d\\n\",bp.first,bp.second);\n        grid[bp.first][bp.second]=-1;\n    }\n    fflush(stdout);\n}","ahc024":"#include<bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nint orig[50][50], grid[50][50], best[50][50];\nint dx[]={-1,1,0,0}, dy[]={0,0,-1,1};\nbool target_adj[102][102];\nint adj_cnt[102][102];\nint csz[102];\n\nvoid init_adj(){\n    memset(adj_cnt,0,sizeof(adj_cnt));\n    memset(csz,0,sizeof(csz));\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++){\n        int c=grid[i][j]; csz[c]++;\n        if(i==0){adj_cnt[0][c]++;adj_cnt[c][0]++;}\n        if(i==n-1){adj_cnt[0][c]++;adj_cnt[c][0]++;}\n        if(j==0){adj_cnt[0][c]++;adj_cnt[c][0]++;}\n        if(j==n-1){adj_cnt[0][c]++;adj_cnt[c][0]++;}\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) continue;\n            if(c!=grid[ni][nj]) adj_cnt[c][grid[ni][nj]]++;\n        }\n    }\n}\n\nbool check_conn_local(int c, int ri, int rj){\n    pair<int,int> cn[4]; int nc=0;\n    for(int d=0;d<4;d++){\n        int ni=ri+dx[d],nj=rj+dy[d];\n        if(ni>=0&&ni<n&&nj>=0&&nj<n&&grid[ni][nj]==c)\n            cn[nc++]={ni,nj};\n    }\n    if(nc<=1) return true;\n    static bool vis[50][50];\n    vector<pair<int,int>> stk;\n    stk.reserve(64);\n    queue<pair<int,int>> q;\n    q.push(cn[0]); vis[cn[0].first][cn[0].second]=true;\n    stk.push_back(cn[0]);\n    int found=1;\n    while(!q.empty()&&found<nc){\n        auto[ci,cj]=q.front();q.pop();\n        for(int d=0;d<4;d++){\n            int ni=ci+dx[d],nj=cj+dy[d];\n            if(ni<0||ni>=n||nj<0||nj>=n) continue;\n            if(grid[ni][nj]==c&&!vis[ni][nj]){\n                vis[ni][nj]=true;stk.push_back({ni,nj});q.push({ni,nj});\n                for(int k=1;k<nc;k++)\n                    if(ni==cn[k].first&&nj==cn[k].second){found++;break;}\n            }\n        }\n    }\n    for(auto&[a,b]:stk) vis[a][b]=false;\n    return found==nc;\n}\n\nvoid do_remove(int i, int j){\n    int c=grid[i][j];\n    if(i==0){adj_cnt[0][c]--;adj_cnt[c][0]--;}\n    if(i==n-1){adj_cnt[0][c]--;adj_cnt[c][0]--;}\n    if(j==0){adj_cnt[0][c]--;adj_cnt[c][0]--;}\n    if(j==n-1){adj_cnt[0][c]--;adj_cnt[c][0]--;}\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) continue;\n        int nc=grid[ni][nj];\n        if(nc!=c){adj_cnt[c][nc]--;adj_cnt[nc][c]--;}\n    }\n    grid[i][j]=0;csz[c]--;csz[0]++;\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) continue;\n        int nc=grid[ni][nj];\n        if(nc!=0){adj_cnt[0][nc]++;adj_cnt[nc][0]++;}\n    }\n}\n\nvoid do_add(int i, int j, int c){\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) continue;\n        int nc=grid[ni][nj];\n        if(nc!=0){adj_cnt[0][nc]--;adj_cnt[nc][0]--;}\n    }\n    grid[i][j]=c;csz[0]--;csz[c]++;\n    if(i==0){adj_cnt[0][c]++;adj_cnt[c][0]++;}\n    if(i==n-1){adj_cnt[0][c]++;adj_cnt[c][0]++;}\n    if(j==0){adj_cnt[0][c]++;adj_cnt[c][0]++;}\n    if(j==n-1){adj_cnt[0][c]++;adj_cnt[c][0]++;}\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) continue;\n        int nc=grid[ni][nj];\n        if(nc!=c){adj_cnt[c][nc]++;adj_cnt[nc][c]++;}\n    }\n}\n\nbool try_remove(int i, int j){\n    int c=grid[i][j];\n    if(c==0||csz[c]<=1) return false;\n    int be=(i==0)+(i==n-1)+(j==0)+(j==n-1);\n    if(be>0&&target_adj[0][c]&&adj_cnt[0][c]<=be) return false;\n    int lose[102]={};\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) continue;\n        int nc=grid[ni][nj];\n        if(nc!=c){\n            if(nc!=0&&!target_adj[0][nc]) return false;\n            lose[nc]++;\n        }\n    }\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) continue;\n        int nc=grid[ni][nj];\n        if(nc!=c&&target_adj[c][nc]&&adj_cnt[c][nc]<=lose[nc]) return false;\n    }\n    if(be==0){\n        bool has0=false;\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) continue;\n            if(grid[ni][nj]==0){has0=true;break;}\n        }\n        if(!has0) return false;\n    }\n    do_remove(i,j);\n    if(!check_conn_local(c,i,j)){\n        do_add(i,j,c);\n        return false;\n    }\n    return true;\n}\n\n// Try swap: move a non-zero cell to an adjacent 0-cell\nbool try_swap(int fi, int fj, int ti, int tj){\n    // fi,fj has color c, ti,tj has color 0, they're adjacent\n    int c=grid[fi][fj];\n    if(c==0||grid[ti][tj]!=0) return false;\n    \n    // Check if we can add c at (ti,tj) and remove c at (fi,fj)\n    // First add, then remove\n    \n    // Check add constraints\n    for(int d=0;d<4;d++){\n        int ni=ti+dx[d],nj=tj+dy[d];\n        if(ni<0||ni>=n||nj<0||nj>=n) continue;\n        int nc=grid[ni][nj];\n        if(nc!=c&&nc!=0&&!target_adj[c][nc]) return false;\n    }\n    int be_t=(ti==0)+(ti==n-1)+(tj==0)+(tj==n-1);\n    if(be_t>0&&!target_adj[0][c]) return false;\n    \n    // Do add\n    do_add(ti,tj,c);\n    \n    // Now check remove constraints for (fi,fj)\n    int be_f=(fi==0)+(fi==n-1)+(fj==0)+(fj==n-1);\n    bool can_rem=true;\n    if(csz[c]<=1){can_rem=false;}\n    if(can_rem&&be_f>0&&target_adj[0][c]&&adj_cnt[0][c]<=be_f){can_rem=false;}\n    if(can_rem){\n        int lose2[102]={};\n        for(int d=0;d<4;d++){\n            int ni=fi+dx[d],nj=fj+dy[d];\n            if(ni<0||ni>=n||nj<0||nj>=n) continue;\n            int nc=grid[ni][nj];\n            if(nc!=c){\n                if(nc!=0&&!target_adj[0][nc]){can_rem=false;break;}\n                lose2[nc]++;\n            }\n        }\n        if(can_rem){\n            for(int d=0;d<4;d++){\n                int ni=fi+dx[d],nj=fj+dy[d];\n                if(ni<0||ni>=n||nj<0||nj>=n) continue;\n                int nc=grid[ni][nj];\n                if(nc!=c&&target_adj[c][nc]&&adj_cnt[c][nc]<=lose2[nc]){can_rem=false;break;}\n            }\n        }\n        if(can_rem&&be_f==0){\n            bool has0=false;\n            for(int d=0;d<4;d++){\n                int ni=fi+dx[d],nj=fj+dy[d];\n                if(ni<0||ni>=n||nj<0||nj>=n) continue;\n                if(grid[ni][nj]==0){has0=true;break;}\n            }\n            if(!has0) can_rem=false;\n        }\n    }\n    \n    if(!can_rem){\n        do_remove(ti,tj); // undo add\n        return false;\n    }\n    \n    do_remove(fi,fj);\n    if(!check_conn_local(c,fi,fj)){\n        // undo: add back fi,fj, remove ti,tj\n        do_add(fi,fj,c);\n        do_remove(ti,tj);\n        return false;\n    }\n    return true; // Net effect: cell moved from (fi,fj) to (ti,tj), zero count unchanged\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin>>n>>m;\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>orig[i][j];\n    \n    memset(target_adj,0,sizeof(target_adj));\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++){\n        if(i==0||i==n-1||j==0||j==n-1)\n            target_adj[0][orig[i][j]]=target_adj[orig[i][j]][0]=true;\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) continue;\n            if(orig[i][j]!=orig[ni][nj])\n                target_adj[orig[i][j]][orig[ni][nj]]=target_adj[orig[ni][nj]][orig[i][j]]=true;\n        }\n    }\n    \n    mt19937 rng(42);\n    auto start=chrono::steady_clock::now();\n    memcpy(best,orig,sizeof(orig));\n    int best_zeros=0;\n    \n    vector<pair<int,int>> order;\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) order.push_back({i,j});\n    \n    for(int iter=0;;iter++){\n        auto now=chrono::steady_clock::now();\n        int ms=chrono::duration_cast<chrono::milliseconds>(now-start).count();\n        if(ms>1800) break;\n        \n        // Start from original each time with different ordering\n        memcpy(grid,orig,sizeof(orig));\n        init_adj();\n        shuffle(order.begin(),order.end(),rng);\n        \n        // Greedy erosion\n        bool changed=true;\n        while(changed){\n            auto now2=chrono::steady_clock::now();\n            if(chrono::duration_cast<chrono::milliseconds>(now2-start).count()>1800) break;\n            changed=false;\n            for(auto&[i,j]:order)\n                if(grid[i][j]!=0&&try_remove(i,j)) changed=true;\n        }\n        \n        // Swap phase: move frontier cells to compact wards\n        for(int sp=0;sp<3;sp++){\n            auto now3=chrono::steady_clock::now();\n            if(chrono::duration_cast<chrono::milliseconds>(now3-start).count()>1800) break;\n            \n            bool any_swap=false;\n            shuffle(order.begin(),order.end(),rng);\n            for(auto&[i,j]:order){\n                if(grid[i][j]==0) continue;\n                // Try swapping with adjacent 0-cell\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&&grid[ni][nj]==0){\n                        if(try_swap(i,j,ni,nj)){\n                            any_swap=true;\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            // Erosion after swaps\n            changed=true;\n            while(changed){\n                auto now4=chrono::steady_clock::now();\n                if(chrono::duration_cast<chrono::milliseconds>(now4-start).count()>1800) break;\n                changed=false;\n                for(auto&[i,j]:order)\n                    if(grid[i][j]!=0&&try_remove(i,j)) changed=true;\n            }\n            if(!any_swap) break;\n        }\n        \n        if(csz[0]>best_zeros){\n            best_zeros=csz[0];\n            memcpy(best,grid,sizeof(grid));\n        }\n    }\n    \n    for(int i=0;i<n;i++){\n        for(int j=0;j<n;j++){\n            cout<<best[i][j];\n            if(j<n-1) cout<<' ';\n        }\n        cout<<'\\n';\n    }\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint queries_used = 0;\n\nchar query(vector<int>& L, vector<int>& R) {\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << \"\\n\" << flush;\n    queries_used++;\n    char c; cin >> c;\n    return c;\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\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> left(v.begin(), v.begin()+mid), right(v.begin()+mid, v.end());\n        left = msort(left); right = msort(right);\n        vector<int> res;\n        int i=0,j=0;\n        while(i<(int)left.size()&&j<(int)right.size()){\n            if(queries_used>=Q){res.push_back(left[i++]);continue;}\n            vector<int> L={left[i]}, R={right[j]};\n            char c=query(L,R);\n            if(c=='<'||c=='=') res.push_back(left[i++]);\n            else res.push_back(right[j++]);\n        }\n        while(i<(int)left.size()) res.push_back(left[i++]);\n        while(j<(int)right.size()) res.push_back(right[j++]);\n        return res;\n    };\n    \n    vector<int> si = msort(items); // sorted ascending\n    \n    // Estimate weights: w[si[0]]=1, for each i, binary search how many smallest items equal it\n    vector<double> w(N, 1.0);\n    // cumulative weight estimate\n    vector<double> cum(N+1, 0);\n    cum[1] = 1.0;\n    \n    for(int i=1; i<N && queries_used<Q; i++){\n        // Binary search: find k in [1, i] such that sum of si[0..k-1] ~ si[i]\n        int lo=1, hi=i, best=0;\n        while(lo<=hi && queries_used<Q){\n            int mid=(lo+hi)/2;\n            vector<int> L={si[i]}, R;\n            for(int j=0;j<mid;j++) R.push_back(si[j]);\n            char c=query(L,R);\n            if(c=='>') { best=mid; lo=mid+1; }\n            else if(c=='<') { hi=mid-1; }\n            else { best=mid; break; }\n        }\n        w[si[i]] = (best>0) ? cum[best] + (cum[best]-cum[max(0,best-1)])*0.5 : cum[1]*0.5;\n        if(best>=i) w[si[i]] = cum[i] + (cum[i]-cum[max(0,i-1)])*0.5;\n        cum[i+1] = cum[i] + w[si[i]];\n    }\n    for(int i=1;i<N;i++) if(cum[i+1]==0) { w[si[i]]=w[si[i-1]]; cum[i+1]=cum[i]+w[si[i]]; }\n    \n    while(queries_used<Q){ vector<int> L={0},R={1}; query(L,R); }\n    \n    // LPT partition\n    vector<int> order(si.rbegin(), si.rend());\n    vector<double> gw(D,0);\n    vector<int> assign(N,0);\n    for(int idx:order){ int b=min_element(gw.begin(),gw.end())-gw.begin(); assign[idx]=b; gw[b]+=w[idx]; }\n    \n    for(int i=0;i<N;i++) cout<<assign[i]<<\" \\n\"[i==N-1];\n    cout<<flush;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\nint n, m;\n\ndouble stack_cost(const vector<int>& st, int nv){\n    double cost = 0;\n    int sz = st.size();\n    for(int j = 0; j < sz; j++){\n        int v = st[j];\n        if(v < nv) continue;\n        int blocking = 0;\n        for(int k = j+1; k < sz; k++){\n            if(st[k] >= nv && st[k] > v) blocking++;\n        }\n        if(blocking > 0){\n            cost += (blocking + 1.0) / (1.0 + (v - nv) * 0.12);\n        }\n    }\n    return cost;\n}\n\nint main(){\n    scanf(\"%d%d\", &n, &m);\n    vector<vector<int>> stacks(m);\n    for(int i = 0; i < m; i++){\n        stacks[i].resize(n/m);\n        for(int j = 0; j < n/m; j++)\n            scanf(\"%d\", &stacks[i][j]);\n    }\n    \n    vector<pair<int,int>> ops;\n    vector<double> scost(m);\n    \n    int v = 1;\n    \n    while(v <= n){\n        bool found = true;\n        while(found && v <= n){\n            found = false;\n            for(int i = 0; i < m; i++){\n                if(!stacks[i].empty() && stacks[i].back() == v){\n                    ops.push_back({v, 0});\n                    stacks[i].pop_back();\n                    v++; found = true; break;\n                }\n            }\n        }\n        if(v > n) break;\n        \n        int nv = v + 1;\n        double total = 0;\n        for(int i = 0; i < m; i++){ scost[i] = stack_cost(stacks[i], nv); total += scost[i]; }\n        \n        int si=-1, sj=-1;\n        for(int i = 0; i < m; i++)\n            for(int j = 0; j < (int)stacks[i].size(); j++)\n                if(stacks[i][j] == v){ si=i; sj=j; goto done; }\n        done:;\n        \n        int top = (int)stacks[si].size();\n        int above = top - sj - 1;\n        \n        vector<int> si_after(stacks[si].begin(), stacks[si].begin()+sj);\n        double si_ac = stack_cost(si_after, nv);\n        double base = total - scost[si] + si_ac;\n        \n        double best_eval = 1e18;\n        int btype=0, bd1=0, bd2=0, bd3=0, bsp1=0, bsp2=0;\n        \n        // Precompute dest costs for chunks appended\n        // Single move: append chunk [sj+1..top) to dest d\n        for(int d = 0; d < m; d++){\n            if(d == si) continue;\n            vector<int> nd(stacks[d]);\n            for(int j=sj+1;j<top;j++) nd.push_back(stacks[si][j]);\n            double e = (above+1) + base - scost[d] + stack_cost(nd, nv);\n            if(e < best_eval){ best_eval=e; btype=0; bd1=d; }\n        }\n        \n        // 2-way split\n        if(above >= 2){\n            for(int sp = sj+2; sp < top; sp++){\n                int k1=top-sp, k2=sp-sj-1, mc=(k1+1)+(k2+1);\n                // Pruning: mc + base - max_possible_savings >= best_eval \u2192 skip\n                // Loose prune: if mc alone > best_eval, skip\n                if(mc > best_eval) continue;\n                \n                vector<int> c1(stacks[si].begin()+sp, stacks[si].end());\n                vector<int> c2(stacks[si].begin()+sj+1, stacks[si].begin()+sp);\n                \n                // Precompute d1 costs\n                double d_costs[10];\n                for(int d1=0;d1<m;d1++){\n                    if(d1==si){d_costs[d1]=1e18;continue;}\n                    vector<int> nd(stacks[d1]);\n                    for(auto x:c1) nd.push_back(x);\n                    d_costs[d1] = stack_cost(nd, nv);\n                }\n                \n                for(int d1=0;d1<m;d1++){\n                    if(d1==si) continue;\n                    for(int d2=0;d2<m;d2++){\n                        if(d2==si) continue;\n                        double e;\n                        if(d1==d2){\n                            vector<int> nd(stacks[d1]);\n                            for(auto x:c1)nd.push_back(x);\n                            for(auto x:c2)nd.push_back(x);\n                            e = mc + base - scost[d1] + stack_cost(nd,nv);\n                        } else {\n                            vector<int> nd2(stacks[d2]);\n                            for(auto x:c2)nd2.push_back(x);\n                            e = mc + base - scost[d1] - scost[d2] + d_costs[d1] + stack_cost(nd2,nv);\n                        }\n                        if(e < best_eval){best_eval=e;btype=1;bd1=d1;bd2=d2;bsp1=sp;}\n                    }\n                }\n            }\n        }\n        \n        // 3-way split\n        if(above >= 4 && above <= 14){\n            for(int sp2=sj+2;sp2<top-1;sp2++){\n                for(int sp1=sp2+1;sp1<top;sp1++){\n                    int k1=top-sp1,k2=sp1-sp2,k3=sp2-sj-1;\n                    int mc=(k1+1)+(k2+1)+(k3+1);\n                    if(mc>best_eval) continue;\n                    \n                    vector<int> c1(stacks[si].begin()+sp1,stacks[si].end());\n                    vector<int> c2(stacks[si].begin()+sp2,stacks[si].begin()+sp1);\n                    vector<int> c3(stacks[si].begin()+sj+1,stacks[si].begin()+sp2);\n                    \n                    for(int d1=0;d1<m;d1++){\n                        if(d1==si)continue;\n                        vector<int> nd1(stacks[d1]); for(auto x:c1)nd1.push_back(x);\n                        double nd1c=stack_cost(nd1,nv);\n                        for(int d2=0;d2<m;d2++){\n                            if(d2==si)continue;\n                            vector<int> nd2(d2==d1?nd1:stacks[d2]); for(auto x:c2)nd2.push_back(x);\n                            double nd2c=stack_cost(nd2,nv);\n                            for(int d3=0;d3<m;d3++){\n                                if(d3==si)continue;\n                                vector<int> nd3;\n                                if(d3==d1&&d3==d2) nd3=nd2;\n                                else if(d3==d1){nd3=nd1;}\n                                else if(d3==d2){nd3=nd2;}\n                                else nd3=stacks[d3];\n                                for(auto x:c3)nd3.push_back(x);\n                                double nd3c=stack_cost(nd3,nv);\n                                set<int> ds={d1,d2,d3};ds.erase(si);\n                                // This is getting complex; use full recompute for affected stacks\n                                // Actually just build final state for changed stacks\n                                double rem=base;\n                                for(int dd:ds) rem-=scost[dd];\n                                // Recompute: tricky with overlaps. Use simpler approach.\n                                // Skip 3-way for now if too complex\n                                // Let's just do full copy\n                                auto tmp=stacks;\n                                for(int j=sp1;j<top;j++)tmp[d1].push_back(tmp[si][j]);\n                                tmp[si].resize(sp1);\n                                for(int j=sp2;j<(int)tmp[si].size();j++)tmp[d2].push_back(tmp[si][j]);\n                                tmp[si].resize(sp2);\n                                for(int j=sj+1;j<(int)tmp[si].size();j++)tmp[d3].push_back(tmp[si][j]);\n                                tmp[si].resize(sj+1);tmp[si].pop_back();\n                                double e2=mc;\n                                for(int ii=0;ii<m;ii++)e2+=stack_cost(tmp[ii],nv);\n                                if(e2<best_eval){best_eval=e2;btype=2;bd1=d1;bd2=d2;bd3=d3;bsp1=sp1;bsp2=sp2;}\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if(btype==0){\n            ops.push_back({stacks[si][sj+1],bd1+1});\n            for(int j=sj+1;j<top;j++)stacks[bd1].push_back(stacks[si][j]);\n            stacks[si].resize(sj+1);\n        }else if(btype==1){\n            ops.push_back({stacks[si][bsp1],bd1+1});\n            for(int j=bsp1;j<top;j++)stacks[bd1].push_back(stacks[si][j]);\n            stacks[si].resize(bsp1);\n            ops.push_back({stacks[si][sj+1],bd2+1});\n            for(int j=sj+1;j<(int)stacks[si].size();j++)stacks[bd2].push_back(stacks[si][j]);\n            stacks[si].resize(sj+1);\n        }else{\n            ops.push_back({stacks[si][bsp1],bd1+1});\n            for(int j=bsp1;j<top;j++)stacks[bd1].push_back(stacks[si][j]);\n            stacks[si].resize(bsp1);\n            ops.push_back({stacks[si][bsp2],bd2+1});\n            for(int j=bsp2;j<(int)stacks[si].size();j++)stacks[bd2].push_back(stacks[si][j]);\n            stacks[si].resize(bsp2);\n            ops.push_back({stacks[si][sj+1],bd3+1});\n            for(int j=sj+1;j<(int)stacks[si].size();j++)stacks[bd3].push_back(stacks[si][j]);\n            stacks[si].resize(sj+1);\n        }\n        ops.push_back({v,0});\n        stacks[si].pop_back();\n        v++;\n    }\n    for(auto&[a,b]:ops)printf(\"%d %d\\n\",a,b);\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\nint N;\nstring hw[40],vw[40];\nint d[40][40],da[40][40][40][40];\nint dx[]={-1,1,0,0},dy[]={0,0,-1,1};\nchar dc[]={'U','D','L','R'};\nlong long totalD;\nchrono::steady_clock::time_point T0;\nlong long ems(){return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-T0).count();}\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 hw[x-1][y]=='0';\n    if(dir==1)return hw[x][y]=='0';\n    if(dir==2)return vw[x][y-1]=='0';\n    return vw[x][y]=='0';\n}\nvoid bfs_dist(int sx,int sy){\n    auto&dd=da[sx][sy];for(int i=0;i<N;i++)for(int j=0;j<N;j++)dd[i][j]=999999;\n    dd[sx][sy]=0;queue<pair<int,int>>q;q.push({sx,sy});\n    while(!q.empty()){auto[x,y]=q.front();q.pop();for(int dir=0;dir<4;dir++){if(!canMove(x,y,dir))continue;int nx=x+dx[dir],ny=y+dy[dir];if(dd[nx][ny]>dd[x][y]+1){dd[nx][ny]=dd[x][y]+1;q.push({nx,ny});}}}\n}\nvector<int> bfs_path(int sx,int sy,int gx,int gy){\n    if(sx==gx&&sy==gy)return{};\n    int pv[40][40];memset(pv,-1,sizeof(pv));bool vi[40][40]={};\n    queue<pair<int,int>>q;q.push({sx,sy});vi[sx][sy]=true;\n    while(!q.empty()){auto[x,y]=q.front();q.pop();if(x==gx&&y==gy)break;\n        for(int dir=0;dir<4;dir++){if(!canMove(x,y,dir))continue;int nx=x+dx[dir],ny=y+dy[dir];\n            if(!vi[nx][ny]){vi[nx][ny]=true;pv[nx][ny]=dir;q.push({nx,ny});}}}\n    vector<int>p;int cx=gx,cy=gy;while(cx!=sx||cy!=sy){int dd=pv[cx][cy];p.push_back(dd);cx-=dx[dd];cy-=dy[dd];}\n    reverse(p.begin(),p.end());return p;\n}\ndouble fastScore(const vector<int>&r){\n    int L=r.size();int lv[40][40],fv[40][40];memset(lv,-1,sizeof(lv));memset(fv,-1,sizeof(fv));\n    double s=0;lv[0][0]=0;fv[0][0]=0;int cx=0,cy=0;\n    for(int t=0;t<L;t++){cx+=dx[r[t]];cy+=dy[r[t]];\n        if(lv[cx][cy]>=0){int g=t+1-lv[cx][cy];s+=(double)d[cx][cy]*g*(g-1)/2.0;}\n        if(fv[cx][cy]<0)fv[cx][cy]=t+1;lv[cx][cy]=t+1;}\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(fv[i][j]<0)s+=(double)d[i][j]*L*(L-1)/2.0;\n        else{int g=L-lv[i][j]+fv[i][j];s+=(double)d[i][j]*g*(g-1)/2.0;}}\n    return s/L;\n}\n\nstruct State{\n    vector<int>route;\n    vector<pair<int,int>>pos;\n    vector<vector<int>>vt;\n    double score;int L;\n    void build(){\n        L=route.size();pos.resize(L+1);vt.assign(N*N,{});\n        int cx=0,cy=0;pos[0]={0,0};vt[0].push_back(0);\n        for(int t=0;t<L;t++){cx+=dx[route[t]];cy+=dy[route[t]];pos[t+1]={cx,cy};vt[cx*N+cy].push_back(t+1);}\n        score=fastScore(route);\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    T0=chrono::steady_clock::now();\n    cin>>N;for(int i=0;i<N-1;i++)cin>>hw[i];\n    for(int i=0;i<N;i++)cin>>vw[i];\n    totalD=0;for(int i=0;i<N;i++)for(int j=0;j<N;j++){cin>>d[i][j];totalD+=d[i][j];}\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)bfs_dist(i,j);\n    \n    auto dfsR=[&](bool hf)->vector<int>{\n        vector<int>r;vector<vector<bool>>vi(N,vector<bool>(N,false));\n        function<void(int,int)>go=[&](int x,int y){vi[x][y]=true;\n            vector<pair<int,int>>nb;for(int dir=0;dir<4;dir++){if(!canMove(x,y,dir))continue;int nx=x+dx[dir],ny=y+dy[dir];if(!vi[nx][ny])nb.push_back({dir,d[nx][ny]});}\n            if(hf)sort(nb.begin(),nb.end(),[](auto&a,auto&b){return a.second>b.second;});\n            else sort(nb.begin(),nb.end(),[](auto&a,auto&b){return a.second<b.second;});\n            for(auto&[dir,_]:nb){int nx=x+dx[dir],ny=y+dy[dir];if(!vi[nx][ny]){r.push_back(dir);go(nx,ny);r.push_back(dir^1);}}};\n        go(0,0);return r;};\n    \n    auto greedyR=[&](double pw)->vector<int>{\n        vector<vector<bool>>vi(N,vector<bool>(N,false));vi[0][0]=true;\n        vector<int>r;int cx=0,cy=0,rem=N*N-1;\n        while(rem>0){int bx=-1,by=-1;double bs=-1;\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){if(vi[i][j])continue;int dd=da[cx][cy][i][j];\n                double sc=pow((double)d[i][j],pw)/(dd+1);if(sc>bs){bs=sc;bx=i;by=j;}}\n            auto p=bfs_path(cx,cy,bx,by);int tx=cx,ty=cy;\n            for(int dir:p){r.push_back(dir);tx+=dx[dir];ty+=dy[dir];if(!vi[tx][ty]){vi[tx][ty]=true;rem--;}}\n            cx=bx;cy=by;}\n        auto p=bfs_path(cx,cy,0,0);for(int dir:p)r.push_back(dir);return r;};\n    \n    State best;best.score=1e18;\n    auto tryR=[&](vector<int>r){State s;s.route=r;s.build();if(s.score<best.score)best=s;};\n    for(double pw:{0.3,0.5,0.7,1.0,1.5,2.0})tryR(greedyR(pw));\n    tryR(dfsR(true));tryR(dfsR(false));\n    \n    mt19937 rng(42);\n    int skipIdx=0;\n    \n    while(ems()<1850){\n        int L=best.L;\n        if(L>=96000){\n            // Try segment removal to make room\n            bool removed=false;\n            for(int att=0;att<300&&ems()<1850;att++){\n                int t1=rng()%L;\n                auto[x1,y1]=best.pos[t1];\n                auto&vl=best.vt[x1*N+y1];\n                if(vl.size()<2)continue;\n                auto it=lower_bound(vl.begin(),vl.end(),t1);\n                if(it==vl.end()||*it!=t1)continue;\n                int idx=it-vl.begin();\n                if(idx+1>=(int)vl.size())continue;\n                int t2=vl[idx+1];int seg=t2-t1;if(seg<2||seg>L/3)continue;\n                vector<int>nr;nr.reserve(L-seg);\n                for(int t=0;t<t1;t++)nr.push_back(best.route[t]);\n                for(int t=t2;t<L;t++)nr.push_back(best.route[t]);\n                bool av[40][40]={};av[0][0]=true;int cx=0,cy=0;bool ok=true;\n                for(int t=0;t<(int)nr.size();t++){cx+=dx[nr[t]];cy+=dy[nr[t]];if(cx<0||cx>=N||cy<0||cy>=N){ok=false;break;}av[cx][cy]=true;}\n                if(!ok||cx!=0||cy!=0)continue;\n                bool allOk=true;for(int i=0;i<N&&allOk;i++)for(int j=0;j<N&&allOk;j++)if(!av[i][j])allOk=false;\n                if(!allOk)continue;\n                double ns=fastScore(nr);\n                if(ns<best.score){best.route=move(nr);best.build();removed=true;skipIdx=0;break;}\n            }\n            if(!removed)break;\n            continue;\n        }\n        \n        // Collect top gap candidates\n        struct G{int ci,cj,gap,gi;double pot;};\n        vector<G>gs;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n            auto&v=best.vt[i*N+j];int k=v.size();if(k==0)continue;\n            for(int a=0;a<k;a++){\n                int gap=(a+1<k)?v[a+1]-v[a]:L-v[a]+v[0];\n                if(gap>=3)gs.push_back({i,j,gap,a,(double)d[i][j]*gap*(double)gap});}}\n        sort(gs.begin(),gs.end(),[](auto&a,auto&b){return a.pot>b.pot;});\n        \n        int sz=gs.size();if(sz==0)break;\n        int tryFrom=skipIdx,tryTo=min(sz,tryFrom+50);\n        if(tryFrom>=sz){\n            // Try segment removal\n            bool removed=false;\n            for(int att=0;att<500&&ems()<1850;att++){\n                int t1=rng()%L;auto[x1,y1]=best.pos[t1];\n                auto&vl=best.vt[x1*N+y1];if(vl.size()<2)continue;\n                auto it=lower_bound(vl.begin(),vl.end(),t1);\n                if(it==vl.end()||*it!=t1)continue;\n                int idx=it-vl.begin();if(idx+1>=(int)vl.size())continue;\n                int t2=vl[idx+1];int seg=t2-t1;if(seg<2||seg>L/3)continue;\n                vector<int>nr;nr.reserve(L-seg);\n                for(int t=0;t<t1;t++)nr.push_back(best.route[t]);\n                for(int t=t2;t<L;t++)nr.push_back(best.route[t]);\n                bool av[40][40]={};av[0][0]=true;int cx=0,cy=0;bool ok=true;\n                for(int t=0;t<(int)nr.size();t++){cx+=dx[nr[t]];cy+=dy[nr[t]];if(cx<0||cx>=N||cy<0||cy>=N){ok=false;break;}av[cx][cy]=true;}\n                if(!ok||cx!=0||cy!=0)continue;\n                bool allOk=true;for(int i=0;i<N&&allOk;i++)for(int j=0;j<N&&allOk;j++)if(!av[i][j])allOk=false;\n                if(!allOk)continue;\n                double ns=fastScore(nr);\n                if(ns<best.score){best.route=move(nr);best.build();removed=true;break;}\n            }\n            if(removed){skipIdx=0;continue;}\n            break;\n        }\n        \n        double bns=best.score;vector<int>bnr;\n        \n        for(int c=tryFrom;c<tryTo;c++){\n            if(ems()>1850)break;\n            auto&gi=gs[c];\n            auto&v=best.vt[gi.ci*N+gi.cj];int k=v.size();\n            int tS=v[gi.gi],tE=(gi.gi+1<k)?v[gi.gi+1]:v[0]+L;\n            int gapLen=tE-tS;\n            \n            // Find best insertion point: scan positions within gap for closest to target\n            int bestDist=999999,bestIns=-1;\n            // Sample up to 30 points\n            int step=max(1,gapLen/30);\n            for(int off=step;off<gapLen;off+=step){\n                int tt=(tS+off)%L;\n                auto[px,py]=best.pos[tt];\n                int dd=da[px][py][gi.ci][gi.cj];\n                if(dd<bestDist){bestDist=dd;bestIns=tt;}\n            }\n            // Also check midpoint explicitly\n            {int tt=((tS+tE)/2)%L;auto[px,py]=best.pos[tt];\n             int dd=da[px][py][gi.ci][gi.cj];if(dd<bestDist){bestDist=dd;bestIns=tt;}}\n            \n            if(bestIns<0||bestDist==0||L+2*bestDist>99000)continue;\n            \n            auto[px,py]=best.pos[bestIns];\n            auto pTo=bfs_path(px,py,gi.ci,gi.cj);\n            auto pBk=bfs_path(gi.ci,gi.cj,px,py);\n            int addL=pTo.size()+pBk.size();\n            if(L+addL>99000)continue;\n            \n            vector<int>nr;nr.reserve(L+addL);\n            nr.insert(nr.end(),best.route.begin(),best.route.begin()+bestIns);\n            nr.insert(nr.end(),pTo.begin(),pTo.end());\n            nr.insert(nr.end(),pBk.begin(),pBk.end());\n            nr.insert(nr.end(),best.route.begin()+bestIns,best.route.end());\n            \n            double ns=fastScore(nr);\n            if(ns<bns){bns=ns;bnr=move(nr);}\n        }\n        \n        if(!bnr.empty()&&bns<best.score){\n            best.route=move(bnr);best.build();skipIdx=0;\n        } else {\n            skipIdx=tryTo;\n        }\n    }\n    \n    string ans;for(int dir:best.route)ans+=dc[dir];\n    cout<<ans<<endl;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint main(){\n    auto t0=steady_clock::now();\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    int N,M;\n    cin>>N>>M;\n    int si,sj;\n    cin>>si>>sj;\n    \n    vector<string> grid(N);\n    for(int i=0;i<N;i++) cin>>grid[i];\n    \n    vector<string> words(M);\n    for(int i=0;i<M;i++) cin>>words[i];\n    \n    int NN=N*N;\n    vector<vector<pair<int,int>>> charpos(26);\n    for(int i=0;i<N;i++)\n        for(int j=0;j<N;j++)\n            charpos[grid[i][j]-'A'].push_back({i,j});\n    \n    vector<bool> removed(M,false);\n    for(int i=0;i<M;i++) if(!removed[i])\n        for(int j=0;j<M;j++) if(i!=j&&!removed[j])\n            if(words[i].find(words[j])!=string::npos) removed[j]=true;\n    \n    vector<string> ws;\n    for(int i=0;i<M;i++) if(!removed[i]) ws.push_back(words[i]);\n    int n=ws.size();\n    \n    vector<vector<int>> ov(n,vector<int>(n,0));\n    for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j){\n        int maxo=min((int)ws[i].size(),(int)ws[j].size());\n        for(int o=maxo;o>=1;o--){\n            if(ws[i].compare(ws[i].size()-o,o,ws[j],0,o)==0){ov[i][j]=o;break;}\n        }\n    }\n    \n    // Precompute: for each unique suffix, build table[sp] -> (cost, end_pos)\n    // Map suffix string -> index\n    map<string, int> suffMap;\n    vector<string> suffList;\n    auto getSuffIdx = [&](const string& s) -> int {\n        auto it = suffMap.find(s);\n        if(it != suffMap.end()) return it->second;\n        int idx = suffList.size();\n        suffMap[s] = idx;\n        suffList.push_back(s);\n        return idx;\n    };\n    \n    // word w, overlap o -> suffix index\n    vector<vector<int>> wordSuffIdx(n, vector<int>(5));\n    for(int w=0;w<n;w++){\n        for(int o=0;o<5;o++){\n            if(o>=(int)ws[w].size()) wordSuffIdx[w][o] = getSuffIdx(\"\");\n            else wordSuffIdx[w][o] = getSuffIdx(ws[w].substr(o));\n        }\n    }\n    \n    int nSuff = suffList.size();\n    \n    // table[suffIdx][sp] = {cost, end_pos}\n    // Use flat arrays\n    vector<int> tCost(nSuff * NN);\n    vector<short> tEnd(nSuff * NN);\n    \n    // DP arrays - reuse\n    vector<int> dpA(NN), dpB(NN);\n    \n    for(int si2=0; si2<nSuff; si2++){\n        const string& s = suffList[si2];\n        int slen = s.size();\n        if(slen==0){\n            for(int sp=0;sp<NN;sp++){\n                tCost[si2*NN+sp]=0;\n                tEnd[si2*NN+sp]=sp;\n            }\n            continue;\n        }\n        \n        for(int sp=0;sp<NN;sp++){\n            int spi=sp/N, spj=sp%N;\n            \n            // Use dpA for current\n            // Only touch positions of relevant chars\n            // Clear only positions we'll use\n            int c0=s[0]-'A';\n            auto& cp0=charpos[c0];\n            for(auto&[ni,nj]:cp0) dpA[ni*N+nj]=INT_MAX;\n            for(auto&[ni,nj]:cp0){\n                int cost=abs(ni-spi)+abs(nj-spj)+1;\n                int np=ni*N+nj;\n                if(cost<dpA[np]) dpA[np]=cost;\n            }\n            \n            for(int k=1;k<slen;k++){\n                int ck=s[k]-'A';\n                int pk=s[k-1]-'A';\n                auto& cpC=charpos[ck];\n                auto& cpP=charpos[pk];\n                for(auto&[ni,nj]:cpC) dpB[ni*N+nj]=INT_MAX;\n                for(auto&[pi,pj]:cpP){\n                    int pp=pi*N+pj;\n                    if(dpA[pp]==INT_MAX) continue;\n                    for(auto&[ni,nj]:cpC){\n                        int cost=dpA[pp]+abs(ni-pi)+abs(nj-pj)+1;\n                        int np=ni*N+nj;\n                        if(cost<dpB[np]) dpB[np]=cost;\n                    }\n                }\n                swap(dpA,dpB);\n            }\n            \n            int lc=s.back()-'A';\n            int bestC=INT_MAX, bestP=0;\n            for(auto&[ei,ej]:charpos[lc]){\n                int ep=ei*N+ej;\n                if(dpA[ep]<bestC){bestC=dpA[ep];bestP=ep;}\n            }\n            tCost[si2*NN+sp]=bestC;\n            tEnd[si2*NN+sp]=(short)bestP;\n        }\n    }\n    \n    auto elapsed1=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n    \n    int startPos=si*N+sj;\n    \n    // Inline table lookup\n    auto getCost=[&](int w, int o, int sp) -> int {\n        return tCost[wordSuffIdx[w][o]*NN+sp];\n    };\n    auto getEnd=[&](int w, int o, int sp) -> int {\n        return tEnd[wordSuffIdx[w][o]*NN+sp];\n    };\n    \n    // Prefix arrays\n    vector<int> pfxCost(n), pfxEnd(n);\n    \n    auto rebuildFrom=[&](const vector<int>& ord, int from){\n        int cp=(from>0)?pfxEnd[from-1]:startPos;\n        int total=(from>0)?pfxCost[from-1]:0;\n        for(int i=from;i<n;i++){\n            int w=ord[i];\n            int o=(i>0)?min(4,ov[ord[i-1]][w]):0;\n            total+=getCost(w,o,cp);\n            cp=getEnd(w,o,cp);\n            pfxCost[i]=total;\n            pfxEnd[i]=cp;\n        }\n    };\n    \n    // Evaluate from position, with early termination\n    auto evalFromET=[&](const vector<int>& ord, int from, int limit) -> int {\n        int cp=(from>0)?pfxEnd[from-1]:startPos;\n        int total=(from>0)?pfxCost[from-1]:0;\n        for(int i=from;i<n;i++){\n            int w=ord[i];\n            int o=(i>0)?min(4,ov[ord[i-1]][w]):0;\n            total+=getCost(w,o,cp);\n            if(total>=limit) return total;\n            cp=getEnd(w,o,cp);\n        }\n        return total;\n    };\n    \n    // Greedy nearest neighbor\n    auto greedyOrder=[&](int firstW) -> vector<int> {\n        vector<bool> used(n,false);\n        vector<int> ord;\n        ord.push_back(firstW); used[firstW]=true;\n        int cp=getEnd(firstW,0,startPos);\n        while((int)ord.size()<n){\n            int prev=ord.back();\n            int bestW=-1,bestC=INT_MAX;\n            for(int w=0;w<n;w++) if(!used[w]){\n                int o=min(4,ov[prev][w]);\n                int c=getCost(w,o,cp);\n                if(c<bestC){bestC=c;bestW=w;}\n            }\n            ord.push_back(bestW); used[bestW]=true;\n            cp=getEnd(bestW,min(4,ov[prev][bestW]),cp);\n        }\n        return ord;\n    };\n    \n    vector<int> bestOrder;\n    int bestCost=INT_MAX;\n    \n    for(int fw=0;fw<n;fw++){\n        auto elapsed2=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n        if(elapsed2>elapsed1+200) break;\n        auto ord=greedyOrder(fw);\n        rebuildFrom(ord,0);\n        int c=pfxCost[n-1];\n        if(c<bestCost){bestCost=c;bestOrder=ord;}\n    }\n    rebuildFrom(bestOrder,0);\n    \n    // Local search\n    for(int round=0;;round++){\n        auto elapsed2=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n        if(elapsed2>1850) break;\n        bool improved=false;\n        \n        // Adjacent swaps\n        for(int i=0;i<n-1;i++){\n            swap(bestOrder[i],bestOrder[i+1]);\n            int nc=evalFromET(bestOrder, i, bestCost);\n            if(nc<bestCost){\n                bestCost=nc;\n                rebuildFrom(bestOrder, i);\n                improved=true;\n            } else {\n                swap(bestOrder[i],bestOrder[i+1]);\n            }\n        }\n        \n        // Non-adjacent swaps\n        for(int i=0;i<n-1&&!improved;i++){\n            auto elapsed3=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n            if(elapsed3>1850) break;\n            for(int j=i+2;j<n;j++){\n                swap(bestOrder[i],bestOrder[j]);\n                int nc=evalFromET(bestOrder, i, bestCost);\n                if(nc<bestCost){\n                    bestCost=nc;\n                    rebuildFrom(bestOrder, i);\n                    improved=true;\n                    break;\n                } else {\n                    swap(bestOrder[i],bestOrder[j]);\n                }\n            }\n        }\n        \n        // Or-opt: move element i to position j (using rotate)\n        for(int i=0;i<n&&!improved;i++){\n            auto elapsed3=duration_cast<milliseconds>(steady_clock::now()-t0).count();\n            if(elapsed3>1850) break;\n            for(int j=0;j<n;j++){\n                if(j==i||j==i+1) continue;\n                // Move element at position i to position j\n                auto saved=bestOrder;\n                if(j<i){\n                    rotate(bestOrder.begin()+j, bestOrder.begin()+i, bestOrder.begin()+i+1);\n                } else {\n                    rotate(bestOrder.begin()+i, bestOrder.begin()+i+1, bestOrder.begin()+j);\n                }\n                int from=min(i,j);\n                int nc=evalFromET(bestOrder, from, bestCost);\n                if(nc<bestCost){\n                    bestCost=nc;\n                    rebuildFrom(bestOrder, from);\n                    improved=true;\n                    break;\n                } else {\n                    bestOrder=saved;\n                }\n            }\n            if(improved) break;\n        }\n        \n        if(!improved) break;\n    }\n    \n    // Reconstruct path\n    auto typeStringPath=[&](const string& s, int sp) -> vector<pair<int,int>> {\n        if(s.empty()) return {};\n        int slen=s.size();\n        int spi=sp/N,spj=sp%N;\n        vector<vector<pair<int,int>>> alldp(slen);\n        auto& cp0=charpos[s[0]-'A'];\n        alldp[0].resize(cp0.size());\n        for(int k=0;k<(int)cp0.size();k++){\n            auto&[ni,nj]=cp0[k];\n            alldp[0][k]={abs(ni-spi)+abs(nj-spj)+1,-1};\n        }\n        for(int step=1;step<slen;step++){\n            auto& cpP=charpos[s[step-1]-'A'];\n            auto& cpC=charpos[s[step]-'A'];\n            alldp[step].resize(cpC.size(),{INT_MAX,-1});\n            for(int pi=0;pi<(int)cpP.size();pi++){\n                if(alldp[step-1][pi].first==INT_MAX) continue;\n                auto&[pr,pc]=cpP[pi];\n                for(int ci=0;ci<(int)cpC.size();ci++){\n                    auto&[nr,nc2]=cpC[ci];\n                    int cost=alldp[step-1][pi].first+abs(nr-pr)+abs(nc2-pc)+1;\n                    if(cost<alldp[step][ci].first) alldp[step][ci]={cost,pi};\n                }\n            }\n        }\n        auto& cpL=charpos[s.back()-'A'];\n        int bestIdx=-1,bestC2=INT_MAX;\n        for(int k=0;k<(int)cpL.size();k++)\n            if(alldp[slen-1][k].first<bestC2){bestC2=alldp[slen-1][k].first;bestIdx=k;}\n        vector<pair<int,int>> path(slen);\n        int idx=bestIdx;\n        for(int step=slen-1;step>=0;step--){\n            path[step]=charpos[s[step]-'A'][idx];\n            if(step>0) idx=alldp[step][idx].second;\n        }\n        return path;\n    };\n    \n    vector<pair<int,int>> result;\n    int cp=startPos;\n    string S;\n    for(int i=0;i<n;i++){\n        int w=bestOrder[i];\n        int o=(i>0)?min(4,ov[bestOrder[i-1]][w]):0;\n        string sub=ws[w].substr(o);\n        if(sub.empty()) continue;\n        auto path=typeStringPath(sub, cp);\n        for(auto&p:path){result.push_back(p);S+=grid[p.first][p.second];}\n        if(!path.empty()) cp=path.back().first*N+path.back().second;\n    }\n    \n    for(auto&w:words){\n        if(S.find(w)==string::npos){\n            int bestOv=0;\n            for(int o=min((int)S.size(),(int)w.size());o>=1;o--)\n                if(S.compare(S.size()-o,o,w,0,o)==0){bestOv=o;break;}\n            string sub=w.substr(bestOv);\n            if(sub.empty()) continue;\n            auto path=typeStringPath(sub,cp);\n            for(auto&p:path){result.push_back(p);S+=grid[p.first][p.second];}\n            if(!path.empty()) cp=path.back().first*N+path.back().second;\n        }\n    }\n    \n    for(auto&[r,c]:result) cout<<r<<\" \"<<c<<\"\\n\";\n}","ahc030":"#include<bits/stdc++.h>\nusing namespace std;\nmt19937 rng(42);\nint N,M;double eps_;\nchrono::steady_clock::time_point t0;\ndouble elapsed(){return chrono::duration<double>(chrono::steady_clock::now()-t0).count();}\n\ndouble log_prob(int obs,int ts,int kk){\n    double mu=(kk-ts)*eps_+ts*(1.0-eps_);\n    double s2=kk*eps_*(1.0-eps_);\n    double s=sqrt(s2);\n    if(s<1e-12)return obs==(int)round(mu)?0.0:-1e15;\n    double lo=obs==0?-40.0:(obs-0.5-mu)/s;\n    double hi=(obs+0.5-mu)/s;\n    double p=0.5*erfc(-hi*M_SQRT1_2)-0.5*erfc(-lo*M_SQRT1_2);\n    return p<1e-300?-690.0:log(p);\n}\n\nint main(){\n    t0=chrono::steady_clock::now();\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin>>N>>M>>eps_;\n    int NN=N*N;\n    \n    vector<vector<pair<int,int>>>fields(M);\n    for(int k=0;k<M;k++){\n        int d;cin>>d;fields[k].resize(d);\n        for(int i=0;i<d;i++)cin>>fields[k][i].first>>fields[k][i].second;\n    }\n    \n    vector<vector<vector<int>>>pflat(M);\n    for(int k=0;k<M;k++){\n        int mi=0,mj=0;\n        for(auto&[r,c]:fields[k]){mi=max(mi,r);mj=max(mj,c);}\n        for(int di=0;di+mi<N;di++)\n            for(int dj=0;dj+mj<N;dj++){\n                vector<int>sq;\n                for(auto&[r,c]:fields[k])sq.push_back((r+di)*N+(c+dj));\n                pflat[k].push_back(sq);\n            }\n    }\n    \n    int ops=0,maxops=2*NN;\n    vector<int>known(NN,-1);\n    vector<bool>is_oil(NN,false),is_empty(NN,false);\n    \n    auto query_grp=[&](vector<int>&S)->int{\n        cout<<\"q \"<<S.size();\n        for(int x:S)cout<<\" \"<<x/N<<\" \"<<x%N;\n        cout<<\"\\n\"<<flush;\n        int v;cin>>v;ops++;return v;\n    };\n    auto drill=[&](int idx)->int{\n        vector<int>S={idx};int v=query_grp(S);\n        known[idx]=v;\n        if(v>0)is_oil[idx]=true;else is_empty[idx]=true;\n        return v;\n    };\n    auto guess=[&](vector<int>&ans)->bool{\n        set<int>as(ans.begin(),ans.end());\n        for(int i=0;i<NN;i++)if(is_oil[i])as.insert(i);\n        ans.assign(as.begin(),as.end());\n        cout<<\"a \"<<ans.size();\n        for(int x:ans)cout<<\" \"<<x/N<<\" \"<<x%N;\n        cout<<\"\\n\"<<flush;\n        int r;cin>>r;ops++;return r==1;\n    };\n    \n    // Precompute row/col contributions for each placement\n    // row_ct[k][p][i] = how many cells of placement p of field k are in row i\n    vector<vector<vector<short>>>row_ct(M),col_ct(M);\n    for(int k=0;k<M;k++){\n        int np=pflat[k].size();\n        row_ct[k].assign(np,vector<short>(N,0));\n        col_ct[k].assign(np,vector<short>(N,0));\n        for(int p=0;p<np;p++)\n            for(int idx:pflat[k][p]){\n                row_ct[k][p][idx/N]++;\n                col_ct[k][p][idx%N]++;\n            }\n    }\n    \n    // Query rows and columns\n    int rep=1;\n    if(eps_>=0.10)rep=2;\n    if(eps_>=0.17)rep=3;\n    \n    vector<vector<int>>row_obs(N),col_obs(N);\n    for(int rr=0;rr<rep;rr++){\n        for(int i=0;i<N;i++){\n            vector<int>S;for(int j=0;j<N;j++)S.push_back(i*N+j);\n            row_obs[i].push_back(query_grp(S));\n        }\n        for(int j=0;j<N;j++){\n            vector<int>S;for(int i=0;i<N;i++)S.push_back(i*N+j);\n            col_obs[j].push_back(query_grp(S));\n        }\n    }\n    \n    // Compute LL contribution from rows and cols\n    // row_sum[i] = sum of row_ct[k][ch[k]][i] for all k\n    // col_sum[j] = sum of col_ct[k][ch[k]][j] for all k\n    \n    vector<int>vl_all[20]; // valid list per field\n    auto upd_valid=[&](){\n        for(int k=0;k<M;k++){\n            vl_all[k].clear();\n            for(int p=0;p<(int)pflat[k].size();p++){\n                bool ok=true;\n                for(int idx:pflat[k][p])\n                    if(is_empty[idx]){ok=false;break;}\n                if(ok)vl_all[k].push_back(p);\n            }\n            if(vl_all[k].empty())\n                for(int p=0;p<(int)pflat[k].size();p++)vl_all[k].push_back(p);\n        }\n    };\n    upd_valid();\n    \n    vector<int>ch(M);\n    vector<int>rsum(N,0),csum(N,0);\n    vector<int>grid(NN,0);\n    \n    auto full_init=[&](){\n        fill(rsum.begin(),rsum.end(),0);\n        fill(csum.begin(),csum.end(),0);\n        fill(grid.begin(),grid.end(),0);\n        for(int k=0;k<M;k++){\n            for(int i=0;i<N;i++){rsum[i]+=row_ct[k][ch[k]][i];csum[i]+=col_ct[k][ch[k]][i];}\n            for(int idx:pflat[k][ch[k]])grid[idx]++;\n        }\n    };\n    \n    auto compute_ll=[&]()->double{\n        double ll=0;\n        for(int i=0;i<N;i++)for(int v:row_obs[i])ll+=log_prob(v,rsum[i],N);\n        for(int j=0;j<N;j++)for(int v:col_obs[j])ll+=log_prob(v,csum[j],N);\n        return ll;\n    };\n    \n    // Row LL per row, col LL per col - for incremental\n    vector<double>rll(N),cll(N);\n    double tll;\n    auto compute_all_ll=[&](){\n        tll=0;\n        for(int i=0;i<N;i++){rll[i]=0;for(int v:row_obs[i])rll[i]+=log_prob(v,rsum[i],N);tll+=rll[i];}\n        for(int j=0;j<N;j++){cll[j]=0;for(int v:col_obs[j])cll[j]+=log_prob(v,csum[j],N);tll+=cll[j];}\n    };\n    \n    for(int k=0;k<M;k++)ch[k]=vl_all[k][rng()%vl_all[k].size()];\n    full_init();\n    compute_all_ll();\n    \n    double best_ll=tll;\n    vector<int>best_ch=ch;\n    \n    // Gibbs-like MCMC: for field k, compute conditional score for each valid placement\n    // Only recompute affected rows/cols\n    \n    auto mcmc_step=[&](bool gibbs)->bool{\n        int k=rng()%M;\n        int vsz=vl_all[k].size();\n        if(vsz<=1)return false;\n        int op=ch[k];\n        \n        if(!gibbs){\n            // Metropolis\n            int np=vl_all[k][rng()%vsz];\n            if(np==op)return false;\n            \n            // Check oil constraint\n            for(int idx:pflat[k][op])\n                if(is_oil[idx]&&grid[idx]==1){\n                    bool covers=false;\n                    for(int idx2:pflat[k][np])if(idx2==idx){covers=true;break;}\n                    if(!covers)return false;\n                }\n            \n            // Compute delta incrementally\n            // Affected rows/cols\n            double delta=0;\n            // Remove old row/col contributions, add new\n            // Find which rows/cols are affected\n            static vector<int>arows,acols;\n            arows.clear();acols.clear();\n            for(int i=0;i<N;i++){\n                if(row_ct[k][op][i]!=row_ct[k][np][i])arows.push_back(i);\n                if(col_ct[k][op][i]!=col_ct[k][np][i])acols.push_back(i);\n            }\n            \n            // Update and compute new LL for affected rows\n            vector<pair<int,int>>row_save,col_save;\n            vector<pair<int,double>>rll_save,cll_save;\n            for(int i:arows){\n                row_save.push_back({i,rsum[i]});\n                rll_save.push_back({i,rll[i]});\n                rsum[i]+=row_ct[k][np][i]-row_ct[k][op][i];\n                double nrl=0;for(int v:row_obs[i])nrl+=log_prob(v,rsum[i],N);\n                delta+=nrl-rll[i];\n                rll[i]=nrl;\n            }\n            for(int j:acols){\n                col_save.push_back({j,csum[j]});\n                cll_save.push_back({j,cll[j]});\n                csum[j]+=col_ct[k][np][j]-col_ct[k][op][j];\n                double ncl=0;for(int v:col_obs[j])ncl+=log_prob(v,csum[j],N);\n                delta+=ncl-cll[j];\n                cll[j]=ncl;\n            }\n            \n            if(delta>0||log(uniform_real_distribution<double>(1e-300,1)(rng))<delta){\n                for(int idx:pflat[k][op])grid[idx]--;\n                for(int idx:pflat[k][np])grid[idx]++;\n                ch[k]=np;tll+=delta;\n                if(tll>best_ll){best_ll=tll;best_ch=ch;}\n                return true;\n            }else{\n                for(auto&[i,v]:row_save)rsum[i]=v;\n                for(auto&[i,v]:rll_save)rll[i]=v;\n                for(auto&[j,v]:col_save)csum[j]=v;\n                for(auto&[j,v]:cll_save)cll[j]=v;\n                return false;\n            }\n        }else{\n            // Gibbs: compute score for each valid placement of field k\n            // Remove field k contribution\n            for(int i=0;i<N;i++){rsum[i]-=row_ct[k][op][i];csum[i]-=col_ct[k][op][i];}\n            for(int idx:pflat[k][op])grid[idx]--;\n            \n            // Score each placement\n            static vector<double>scores;\n            scores.resize(vsz);\n            double maxs=-1e18;\n            for(int vi=0;vi<vsz;vi++){\n                int p=vl_all[k][vi];\n                // Check oil constraint\n                bool ok=true;\n                // Actually checking all oil cells is expensive, skip for gibbs\n                // We'll handle via filtering\n                \n                double s=0;\n                for(int i=0;i<N;i++){\n                    int ns=rsum[i]+row_ct[k][p][i];\n                    for(int v:row_obs[i])s+=log_prob(v,ns,N);\n                    int nc=csum[i]+col_ct[k][p][i];\n                    for(int v:col_obs[i])s+=log_prob(v,nc,N);\n                }\n                scores[vi]=s;\n                if(s>maxs)maxs=s;\n            }\n            \n            // Sample proportional to exp(score)\n            double sum=0;\n            for(int vi=0;vi<vsz;vi++){\n                scores[vi]=exp(scores[vi]-maxs);\n                sum+=scores[vi];\n            }\n            \n            double r2=uniform_real_distribution<double>(0,sum)(rng);\n            int chosen=0;\n            double acc=0;\n            for(int vi=0;vi<vsz;vi++){\n                acc+=scores[vi];\n                if(acc>=r2){chosen=vi;break;}\n            }\n            \n            int np=vl_all[k][chosen];\n            ch[k]=np;\n            for(int i=0;i<N;i++){rsum[i]+=row_ct[k][np][i];csum[i]+=col_ct[k][np][i];}\n            for(int idx:pflat[k][np])grid[idx]++;\n            \n            // Recompute LL\n            compute_all_ll();\n            if(tll>best_ll){best_ll=tll;best_ch=ch;}\n            return true;\n        }\n    };\n    \n    auto run_mcmc=[&](double tlim,vector<double>&occ,int&samp){\n        samp=0;int it=0;int warmup=1000;\n        while(elapsed()<tlim){\n            for(int b=0;b<500;b++){\n                it++;\n                // Use Gibbs every 10th step if not too many placements\n                bool use_gibbs=(it%5==0);\n                int k=rng()%M;\n                if(use_gibbs&&(int)vl_all[k].size()>500)use_gibbs=false;\n                if(use_gibbs&&(int)vl_all[k].size()*N*rep>50000)use_gibbs=false;\n                \n                if(use_gibbs){\n                    // Gibbs for random field\n                    int op=ch[k];\n                    int vsz=vl_all[k].size();\n                    if(vsz<=1){mcmc_step(false);goto sample;}\n                    for(int i=0;i<N;i++){rsum[i]-=row_ct[k][op][i];csum[i]-=col_ct[k][op][i];}\n                    for(int idx:pflat[k][op])grid[idx]--;\n                    \n                    {\n                        vector<double>sc(vsz);\n                        double mx=-1e18;\n                        for(int vi=0;vi<vsz;vi++){\n                            int p=vl_all[k][vi];\n                            double s=0;\n                            for(int i=0;i<N;i++){\n                                for(int v:row_obs[i])s+=log_prob(v,rsum[i]+row_ct[k][p][i],N);\n                                for(int v:col_obs[i])s+=log_prob(v,csum[i]+col_ct[k][p][i],N);\n                            }\n                            sc[vi]=s;if(s>mx)mx=s;\n                        }\n                        double sm=0;\n                        for(int vi=0;vi<vsz;vi++){sc[vi]=exp(sc[vi]-mx);sm+=sc[vi];}\n                        double r2=uniform_real_distribution<double>(0,sm)(rng);\n                        int ci=0;double ac=0;\n                        for(int vi=0;vi<vsz;vi++){ac+=sc[vi];if(ac>=r2){ci=vi;break;}}\n                        int np=vl_all[k][ci];\n                        ch[k]=np;\n                        for(int i=0;i<N;i++){rsum[i]+=row_ct[k][np][i];csum[i]+=col_ct[k][np][i];}\n                        for(int idx:pflat[k][np])grid[idx]++;\n                        compute_all_ll();\n                        if(tll>best_ll){best_ll=tll;best_ch=ch;}\n                    }\n                }else{\n                    mcmc_step(false);\n                }\n                sample:\n                if(it>warmup){\n                    for(int kk=0;kk<M;kk++)\n                        for(int idx:pflat[kk][ch[kk]])\n                            occ[idx]+=1;\n                    samp++;\n                }\n            }\n        }\n    };\n    \n    vector<double>occ(NN,0);int samp=0;\n    run_mcmc(1.2,occ,samp);\n    \n    auto try_guess=[&]()->bool{\n        if(ops>=maxops||samp==0)return false;\n        vector<int>ans;\n        double thr=0.5;\n        for(int i=0;i<NN;i++)\n            if(occ[i]/samp>thr||is_oil[i])ans.push_back(i);\n        return guess(ans);\n    };\n    if(try_guess())return 0;\n    \n    // Drill uncertain + re-MCMC loop\n    for(int phase=0;phase<5&&ops<maxops-2&&elapsed()<2.6;phase++){\n        vector<pair<double,int>>td;\n        for(int i=0;i<NN;i++){\n            if(known[i]>=0)continue;\n            double p=samp?occ[i]/samp:0.5;\n            td.push_back({fabs(p-0.5),i});\n        }\n        sort(td.begin(),td.end());\n        int bud=min((int)td.size(),max(5,(maxops-ops-2)/(7-phase)));\n        for(int d=0;d<bud&&ops<maxops-2;d++)drill(td[d].second);\n        \n        upd_valid();\n        for(int k=0;k<M;k++){\n            bool ok=false;for(int p:vl_all[k])if(p==ch[k]){ok=true;break;}\n            if(!ok)ch[k]=vl_all[k][rng()%vl_all[k].size()];\n        }\n        full_init();compute_all_ll();\n        best_ll=tll;best_ch=ch;\n        \n        fill(occ.begin(),occ.end(),0);samp=0;\n        run_mcmc(min(elapsed()+0.3,2.8),occ,samp);\n        if(try_guess())return 0;\n    }\n    \n    // Fallback\n    for(int i=0;i<NN;i++){\n        if(known[i]>=0)continue;\n        if(ops>=maxops-1)break;\n        drill(i);\n    }\n    vector<int>ans;\n    for(int i=0;i<NN;i++)if(is_oil[i])ans.push_back(i);\n    if(ops<maxops)guess(ans);\n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\nusing ll = long long;\n\nint W, D, N;\nint a_val[55][55];\nstruct Rect { int r0,c0,r1,c1; int area() const { return (r1-r0)*(c1-c0); } };\n\nstruct Node {\n    int left=-1, right=-1;\n    bool hsplit;\n    int leafIdx=-1;\n    vector<int> leftLeaves, rightLeaves, allLeaves;\n    int cutId=-1;\n};\n\nint NC;\n\nvoid layoutWithCuts(vector<Node>& tree, int ni, int r0, int c0, int r1, int c1, double* cuts, Rect* res) {\n    auto& nd = tree[ni];\n    if(nd.leafIdx>=0){ res[nd.leafIdx]={r0,c0,r1,c1}; return; }\n    if(nd.hsplit){\n        int h=r1-r0;\n        int sp = r0 + max(1, min(h-1, (int)round(cuts[nd.cutId]*h)));\n        layoutWithCuts(tree, nd.left, r0,c0,sp,c1, cuts, res);\n        layoutWithCuts(tree, nd.right, sp,c0,r1,c1, cuts, res);\n    } else {\n        int w=c1-c0;\n        int sp = c0 + max(1, min(w-1, (int)round(cuts[nd.cutId]*w)));\n        layoutWithCuts(tree, nd.left, r0,c0,r1,sp, cuts, res);\n        layoutWithCuts(tree, nd.right, r0,sp,r1,c1, cuts, res);\n    }\n}\n\nvoid computeCuts(vector<Node>& tree, int ni, int* areas, double* cuts) {\n    auto& nd = tree[ni];\n    if(nd.leafIdx>=0) return;\n    ll ls=0, rs=0;\n    for(int v : nd.leftLeaves) ls += areas[v];\n    for(int v : nd.rightLeaves) rs += areas[v];\n    ll t = ls+rs;\n    cuts[nd.cutId] = (t>0) ? (double)ls/t : 0.5;\n    computeCuts(tree, nd.left, areas, cuts);\n    computeCuts(tree, nd.right, areas, cuts);\n}\n\nll areaCost(int d, Rect* rects) {\n    ll cost=0;\n    for(int k=0;k<N;k++){\n        int ar = rects[k].area();\n        if(a_val[d][k]>ar) cost += 100LL*(a_val[d][k]-ar);\n    }\n    return cost;\n}\n\n// Use arrays instead of vectors for change cost computation\nstatic int usedRows[1001]; // which rows have edges\nstatic int usedCols[1001];\nstatic int nUsedRows, nUsedCols;\n\n// Store edges as small vectors per row/col\nstatic vector<pair<int,int>> hpEdges[1001], hcEdges[1001];\nstatic vector<pair<int,int>> vpEdges[1001], vcEdges[1001];\n\nll computeChangeCost(Rect* prev, Rect* cur) {\n    nUsedRows = nUsedCols = 0;\n    \n    for(int k=0;k<N;k++){\n        auto& r=prev[k];\n        if(r.r0>0){ if(hpEdges[r.r0].empty() && hcEdges[r.r0].empty()) usedRows[nUsedRows++]=r.r0; hpEdges[r.r0].push_back({r.c0,r.c1}); }\n        if(r.r1<W){ if(hpEdges[r.r1].empty() && hcEdges[r.r1].empty()) usedRows[nUsedRows++]=r.r1; hpEdges[r.r1].push_back({r.c0,r.c1}); }\n        if(r.c0>0){ if(vpEdges[r.c0].empty() && vcEdges[r.c0].empty()) usedCols[nUsedCols++]=r.c0; vpEdges[r.c0].push_back({r.r0,r.r1}); }\n        if(r.c1<W){ if(vpEdges[r.c1].empty() && vcEdges[r.c1].empty()) usedCols[nUsedCols++]=r.c1; vpEdges[r.c1].push_back({r.r0,r.r1}); }\n    }\n    for(int k=0;k<N;k++){\n        auto& r=cur[k];\n        if(r.r0>0){ if(hpEdges[r.r0].empty() && hcEdges[r.r0].empty()) usedRows[nUsedRows++]=r.r0; hcEdges[r.r0].push_back({r.c0,r.c1}); }\n        if(r.r1<W){ if(hpEdges[r.r1].empty() && hcEdges[r.r1].empty()) usedRows[nUsedRows++]=r.r1; hcEdges[r.r1].push_back({r.c0,r.c1}); }\n        if(r.c0>0){ if(vpEdges[r.c0].empty() && vcEdges[r.c0].empty()) usedCols[nUsedCols++]=r.c0; vcEdges[r.c0].push_back({r.r0,r.r1}); }\n        if(r.c1<W){ if(vpEdges[r.c1].empty() && vcEdges[r.c1].empty()) usedCols[nUsedCols++]=r.c1; vcEdges[r.c1].push_back({r.r0,r.r1}); }\n    }\n    \n    auto merge=[](vector<pair<int,int>>& iv){\n        if(iv.empty()) return;\n        sort(iv.begin(),iv.end());\n        int n=0;\n        for(auto& p:iv){\n            if(n>0&&iv[n-1].second>=p.first) iv[n-1].second=max(iv[n-1].second,p.second);\n            else iv[n++]=p;\n        }\n        iv.resize(n);\n    };\n    \n    auto sd=[&](vector<pair<int,int>>& A, vector<pair<int,int>>& B)->int{\n        merge(A); merge(B);\n        int la=0,lb=0,inter=0;\n        for(auto& p:A) la+=p.second-p.first;\n        for(auto& p:B) lb+=p.second-p.first;\n        int i=0,j=0;\n        while(i<(int)A.size()&&j<(int)B.size()){\n            int lo=max(A[i].first,B[j].first), hi=min(A[i].second,B[j].second);\n            if(lo<hi) inter+=hi-lo;\n            if(A[i].second<B[j].second) i++; else j++;\n        }\n        int r = la+lb-2*inter;\n        A.clear(); B.clear();\n        return r;\n    };\n    \n    ll cost=0;\n    for(int idx=0;idx<nUsedRows;idx++){\n        int i=usedRows[idx];\n        cost+=sd(hpEdges[i],hcEdges[i]);\n    }\n    for(int idx=0;idx<nUsedCols;idx++){\n        int j=usedCols[idx];\n        cost+=sd(vpEdges[j],vcEdges[j]);\n    }\n    return cost;\n}\n\nvoid assignRects(int d, Rect* rects) {\n    vector<pair<int,int>> sa(N), sr(N);\n    for(int i=0;i<N;i++) sa[i]={rects[i].area(),i};\n    for(int i=0;i<N;i++) sr[i]={a_val[d][i],i};\n    sort(sa.begin(),sa.end());\n    sort(sr.begin(),sr.end());\n    Rect tmp[55];\n    for(int i=0;i<N;i++) tmp[sr[i].second]=rects[sa[i].second];\n    memcpy(rects,tmp,N*sizeof(Rect));\n}\n\nmt19937 rng(42);\nauto startTime = chrono::steady_clock::now();\ndouble getElapsed() {\n    return chrono::duration<double>(chrono::steady_clock::now()-startTime).count();\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin>>W>>D>>N;\n    for(int d=0;d<D;d++) for(int k=0;k<N;k++) cin>>a_val[d][k];\n    \n    Rect bestOutput[55][55];\n    ll bestCost = LLONG_MAX;\n    \n    vector<Node> bestTree;\n    vector<vector<double>> bestCutsStore;\n    \n    for(int treeType = 0; treeType < 8 && getElapsed() < 1.2; treeType++) {\n        vector<Node> tree;\n        NC = 0;\n        \n        vector<int> ids(N);\n        iota(ids.begin(), ids.end(), 0);\n        \n        bool rev = (treeType >= 4);\n        int splitBias = treeType % 2;\n        int splitMode = (treeType / 2) % 2;\n        \n        if(rev) reverse(ids.begin(), ids.end());\n        \n        function<int(vector<int>&,int)> bt = [&](vector<int>& ids, int dep) -> int {\n            int idx = tree.size();\n            tree.push_back({});\n            if((int)ids.size()==1){\n                tree[idx].leafIdx=ids[0]; tree[idx].allLeaves={ids[0]}; return idx;\n            }\n            tree[idx].hsplit = ((dep+splitBias)%2==0);\n            tree[idx].cutId = NC++;\n            int m;\n            if(splitMode==0) m = ids.size()/2;\n            else m = max(1, (int)ids.size()/3);\n            vector<int> L(ids.begin(),ids.begin()+m), R(ids.begin()+m,ids.end());\n            tree[idx].left = bt(L, dep+1);\n            tree[idx].right = bt(R, dep+1);\n            tree[idx].leftLeaves = tree[tree[idx].left].allLeaves;\n            tree[idx].rightLeaves = tree[tree[idx].right].allLeaves;\n            tree[idx].allLeaves = tree[idx].leftLeaves;\n            for(int v:tree[idx].rightLeaves) tree[idx].allLeaves.push_back(v);\n            return idx;\n        };\n        bt(ids, 0);\n        \n        int nc = NC;\n        vector<vector<double>> dayCuts(D, vector<double>(nc));\n        for(int d=0;d<D;d++) computeCuts(tree, 0, a_val[d], dayCuts[d].data());\n        \n        vector<double> avgCuts(nc, 0);\n        for(int c=0;c<nc;c++){\n            for(int d=0;d<D;d++) avgCuts[c] += dayCuts[d][c];\n            avgCuts[c] /= D;\n        }\n        \n        for(double alpha = 0.0; alpha <= 1.001 && getElapsed() < 1.2; alpha += 0.02) {\n            vector<vector<double>> cuts(D, vector<double>(nc));\n            for(int d=0;d<D;d++)\n                for(int c=0;c<nc;c++)\n                    cuts[d][c] = (1-alpha)*dayCuts[d][c] + alpha*avgCuts[c];\n            \n            Rect rects[55][55];\n            for(int d=0;d<D;d++){\n                layoutWithCuts(tree, 0, 0,0,W,W, cuts[d].data(), rects[d]);\n                assignRects(d, rects[d]);\n            }\n            \n            ll cost=0;\n            for(int d=0;d<D;d++){\n                cost+=areaCost(d,rects[d]);\n                if(d>0) cost+=computeChangeCost(rects[d-1],rects[d]);\n            }\n            if(cost<bestCost){\n                bestCost=cost;\n                memcpy(bestOutput,rects,sizeof(rects));\n                bestTree = tree;\n                bestCutsStore = cuts;\n            }\n        }\n    }\n    \n    // Phase 2: SA on cut positions\n    if(!bestCutsStore.empty() && !bestTree.empty()) {\n        int nc = (int)bestCutsStore[0].size();\n        auto curCuts = bestCutsStore;\n        Rect curRects[55][55];\n        memcpy(curRects, bestOutput, sizeof(curRects));\n        ll curCost = bestCost;\n        \n        ll dayAC[55], dayCC[55];\n        for(int d=0;d<D;d++){\n            dayAC[d]=areaCost(d,curRects[d]);\n            dayCC[d]=(d>0)?computeChangeCost(curRects[d-1],curRects[d]):0;\n        }\n        \n        while(getElapsed() < 2.8){\n            int d = rng()%D;\n            int c = rng()%nc;\n            double oldVal = curCuts[d][c];\n            double delta_cut = ((int)(rng()%2001) - 1000) / 10000.0;\n            double newVal = max(0.01, min(0.99, oldVal + delta_cut));\n            curCuts[d][c] = newVal;\n            \n            Rect newR[55];\n            layoutWithCuts(bestTree, 0, 0,0,W,W, curCuts[d].data(), newR);\n            assignRects(d, newR);\n            \n            ll newAC = areaCost(d, newR);\n            ll newCCp = (d>0)?computeChangeCost(curRects[d-1],newR):0;\n            ll newCCn = (d<D-1)?computeChangeCost(newR,curRects[d+1]):0;\n            \n            ll oldL = dayAC[d]+dayCC[d]+(d<D-1?dayCC[d+1]:0);\n            ll newL = newAC+newCCp+newCCn;\n            ll dlt = newL-oldL;\n            \n            double temp = 300.0*max(0.0,1.0-getElapsed()/2.8);\n            \n            if(dlt<=0 || (temp>0.01 && (int)(rng()%10000)<(int)(10000*exp(-(double)dlt/temp)))){\n                curCost+=dlt;\n                memcpy(curRects[d],newR,N*sizeof(Rect));\n                dayAC[d]=newAC; dayCC[d]=newCCp;\n                if(d<D-1) dayCC[d+1]=newCCn;\n                if(curCost<bestCost){\n                    bestCost=curCost;\n                    memcpy(bestOutput,curRects,sizeof(curRects));\n                }\n            } else {\n                curCuts[d][c] = oldVal;\n            }\n        }\n    }\n    \n    for(int d=0;d<D;d++)\n        for(int k=0;k<N;k++){\n            auto& r=bestOutput[d][k];\n            cout<<r.r0<<\" \"<<r.c0<<\" \"<<r.r1<<\" \"<<r.c1<<\"\\n\";\n        }\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\nconst long long MOD = 998244353;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M,K;\n    cin>>N>>M>>K;\n    \n    long long a[9][9];\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cin>>a[i][j];\n    \n    long long s[20][3][3];\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    // Precompute stamp sums for quick \"value\" estimation\n    long long b[9][9];\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) b[i][j]=a[i][j];\n    vector<tuple<int,int,int>> ops;\n    \n    for(int step=0;step<K;step++){\n        int bm=0,bp=0,bq=0; long long bd=LLONG_MIN;\n        for(int m=0;m<M;m++) for(int p=0;p<=6;p++) for(int q=0;q<=6;q++){\n            long long d=0;\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++)\n                d+=(b[p+i][q+j]+s[m][i][j])%MOD - b[p+i][q+j]%MOD;\n            if(d>bd){bd=d;bm=m;bp=p;bq=q;}\n        }\n        ops.push_back({bm,bp,bq});\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[bp+i][bq+j]+=s[bm][i][j];\n    }\n    \n    // Precompute stamp mod values for each position\n    // smod[m][p][q][i][j] = s[m][i][j] but we just use s directly\n    \n    auto optSlot = [&](int idx) -> bool {\n        auto& [om,op,oq]=ops[idx];\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[op+i][oq+j]-=s[om][i][j];\n        \n        // Precompute mods for the board\n        long long bmod[9][9];\n        for(int i=0;i<9;i++) for(int j=0;j<9;j++) bmod[i][j]=b[i][j]%MOD;\n        \n        int bm=om,bp=op,bq=oq; long long bd=LLONG_MIN;\n        for(int m=0;m<M;m++){\n            for(int p=0;p<=6;p++) for(int q=0;q<=6;q++){\n                long long d=0;\n                for(int i=0;i<3;i++) for(int j=0;j<3;j++)\n                    d+=(b[p+i][q+j]+s[m][i][j])%MOD - bmod[p+i][q+j];\n                if(d>bd){bd=d;bm=m;bp=p;bq=q;}\n            }\n        }\n        bool changed=(bm!=om||bp!=op||bq!=oq);\n        om=bm; op=bp; oq=bq;\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[bp+i][bq+j]+=s[bm][i][j];\n        return changed;\n    };\n    \n    auto optSlot2 = [&](int idx1, int idx2) -> bool {\n        auto& [om1,op1,oq1]=ops[idx1];\n        auto& [om2,op2,oq2]=ops[idx2];\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[op1+i][oq1+j]-=s[om1][i][j];\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[op2+i][oq2+j]-=s[om2][i][j];\n        \n        long long bmod[9][9];\n        for(int i=0;i<9;i++) for(int j=0;j<9;j++) bmod[i][j]=b[i][j]%MOD;\n        \n        // Try all pairs - too expensive (980^2). Instead, find best for slot1, then best for slot2\n        // Iterate: optimize slot1, then slot2, repeat\n        int cm1=om1,cp1=op1,cq1=oq1,cm2=om2,cp2=op2,cq2=oq2;\n        for(int iter=0;iter<3;iter++){\n            // Opt slot1 given slot2\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[cp2+i][cq2+j]+=s[cm2][i][j];\n            long long bd=LLONG_MIN;\n            for(int i=0;i<9;i++) for(int j=0;j<9;j++) bmod[i][j]=b[i][j]%MOD;\n            for(int m=0;m<M;m++) for(int p=0;p<=6;p++) for(int q=0;q<=6;q++){\n                long long d=0;\n                for(int i=0;i<3;i++) for(int j=0;j<3;j++)\n                    d+=(b[p+i][q+j]+s[m][i][j])%MOD - bmod[p+i][q+j];\n                if(d>bd){bd=d;cm1=m;cp1=p;cq1=q;}\n            }\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[cp2+i][cq2+j]-=s[cm2][i][j];\n            \n            // Opt slot2 given slot1\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[cp1+i][cq1+j]+=s[cm1][i][j];\n            bd=LLONG_MIN;\n            for(int i=0;i<9;i++) for(int j=0;j<9;j++) bmod[i][j]=b[i][j]%MOD;\n            for(int m=0;m<M;m++) for(int p=0;p<=6;p++) for(int q=0;q<=6;q++){\n                long long d=0;\n                for(int i=0;i<3;i++) for(int j=0;j<3;j++)\n                    d+=(b[p+i][q+j]+s[m][i][j])%MOD - bmod[p+i][q+j];\n                if(d>bd){bd=d;cm2=m;cp2=p;cq2=q;}\n            }\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[cp1+i][cq1+j]-=s[cm1][i][j];\n        }\n        bool changed=(cm1!=om1||cp1!=op1||cq1!=oq1||cm2!=om2||cp2!=op2||cq2!=oq2);\n        om1=cm1;op1=cp1;oq1=cq1;\n        om2=cm2;op2=cp2;oq2=cq2;\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[op1+i][oq1+j]+=s[om1][i][j];\n        for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[op2+i][oq2+j]+=s[om2][i][j];\n        return changed;\n    };\n    \n    auto calcScore=[&]()->long long{\n        long long sc=0;\n        for(int i=0;i<9;i++) for(int j=0;j<9;j++) sc+=b[i][j]%MOD;\n        return sc;\n    };\n    \n    auto elapsed=[&](auto& st)->double{\n        return chrono::duration<double>(chrono::steady_clock::now()-st).count();\n    };\n    auto startTime=chrono::steady_clock::now();\n    \n    // Initial local opt\n    for(int pass=0;pass<100;pass++){\n        bool any=false;\n        for(int idx=0;idx<K;idx++) if(optSlot(idx)) any=true;\n        if(!any) break;\n        if(elapsed(startTime)>0.15) break;\n    }\n    \n    long long bestScore=calcScore();\n    auto bestOps=ops;\n    long long bestB[9][9]; memcpy(bestB,b,sizeof(b));\n    \n    mt19937 rng(42);\n    \n    while(elapsed(startTime)<1.85){\n        ops=bestOps; memcpy(b,bestB,sizeof(b));\n        \n        int nkick=2+rng()%8;\n        \n        vector<int> perm(K); iota(perm.begin(),perm.end(),0);\n        shuffle(perm.begin(),perm.end(),rng);\n        \n        for(int k=0;k<nkick;k++){\n            int idx=perm[k];\n            auto& [om,op,oq]=ops[idx];\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[op+i][oq+j]-=s[om][i][j];\n            om=rng()%M; op=rng()%7; oq=rng()%7;\n            for(int i=0;i<3;i++) for(int j=0;j<3;j++) b[op+i][oq+j]+=s[om][i][j];\n        }\n        \n        // Re-optimize kicked slots first\n        for(int k=0;k<nkick;k++) optSlot(perm[k]);\n        \n        for(int pass=0;pass<20;pass++){\n            bool any=false;\n            for(int idx=0;idx<K;idx++) if(optSlot(idx)) any=true;\n            if(!any) break;\n            if(elapsed(startTime)>1.85) break;\n        }\n        \n        // Try pair optimization on random pairs\n        if(elapsed(startTime)<1.8){\n            for(int t=0;t<5;t++){\n                int i1=rng()%K, i2=rng()%K;\n                if(i1!=i2) optSlot2(i1,i2);\n            }\n            // One more single pass\n            for(int idx=0;idx<K;idx++) optSlot(idx);\n        }\n        \n        long long sc=calcScore();\n        if(sc>bestScore){\n            bestScore=sc; bestOps=ops; memcpy(bestB,b,sizeof(b));\n        }\n    }\n    \n    cout<<bestOps.size()<<\"\\n\";\n    for(auto&[m,p,q]:bestOps) cout<<m<<\" \"<<p<<\" \"<<q<<\"\\n\";\n}","ahc033":"#include<bits/stdc++.h>\nusing namespace std;\nconst int N=5;\nint A[N][N],grid[N][N];\nint cr_r,cr_c,cr_h;\nint recv_idx[N],next_disp[N];\nstring act[N];\nint turn_count=0;\nint cont_gate[25],cont_ord[25];\n\nvoid do_receive(){\n    for(int i=0;i<N;i++){\n        if(recv_idx[i]>=N||grid[i][0]!=-1)continue;\n        if(cr_r==i&&cr_c==0&&cr_h!=-1)continue;\n        grid[i][0]=A[i][recv_idx[i]];recv_idx[i]++;\n    }\n}\nvoid do_dispatch(){\n    for(int i=0;i<N;i++){\n        if(grid[i][N-1]!=-1){\n            if(grid[i][N-1]==next_disp[i])next_disp[i]++;\n            grid[i][N-1]=-1;\n        }\n    }\n}\nvoid step(char c){\n    do_receive();\n    act[0]+=c;for(int i=1;i<N;i++)act[i]+='.';\n    switch(c){\n        case'P':cr_h=grid[cr_r][cr_c];grid[cr_r][cr_c]=-1;break;\n        case'Q':grid[cr_r][cr_c]=cr_h;cr_h=-1;break;\n        case'U':cr_r--;break;case'D':cr_r++;break;\n        case'L':cr_c--;break;case'R':cr_c++;break;\n        default:break;\n    }\n    do_dispatch();\n    turn_count++;\n}\npair<int,int>fc(int id){\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(grid[i][j]==id)return{i,j};\n    return{-1,-1};\n}\nbool all_done(){for(int i=0;i<N;i++)if(next_disp[i]<i*N+N)return false;return true;}\n\npair<int,int>fem(int pr,int pc){\n    int best=999,br=-1,bc=-1;\n    for(int i=0;i<N;i++)for(int j=0;j<N-1;j++){\n        if(grid[i][j]!=-1||(cr_r==i&&cr_c==j))continue;\n        int d=abs(i-pr)+abs(j-pc);\n        if(d<best){best=d;br=i;bc=j;}\n    }\n    return{br,bc};\n}\n\nvoid go(int tr,int tc){\n    while(cr_r<tr)step('D');while(cr_r>tr)step('U');\n    while(cr_c<tc)step('R');while(cr_c>tc)step('L');\n}\n\nbool deliver_to_gate(int trow){\n    // Move row first, then col, to avoid passing through other dispatch gates\n    while(cr_r<trow)step('D');while(cr_r>trow)step('U');\n    while(cr_c<N-1)step('R');\n    // Now at (trow, N-1)\n    if(grid[cr_r][cr_c]==-1){step('Q');return true;}\n    step('.');\n    if(grid[cr_r][cr_c]==-1){step('Q');return true;}\n    // Still blocked - buffer nearby\n    step('L');\n    if(grid[cr_r][cr_c]==-1){step('Q');return true;}\n    auto[er,ec]=fem(trow,N-2);\n    if(er>=0){go(er,ec);if(grid[cr_r][cr_c]==-1){step('Q');return true;}}\n    return false;\n}\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(0);\n    int n;cin>>n;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        cin>>A[i][j];cont_gate[A[i][j]]=i;cont_ord[A[i][j]]=j;\n    }\n    memset(grid,-1,sizeof(grid));\n    cr_r=0;cr_c=0;cr_h=-1;\n    for(int i=0;i<N;i++){recv_idx[i]=0;next_disp[i]=i*N;}\n    \n    // Bomb small cranes\n    do_receive();act[0]+='.';for(int i=1;i<N;i++)act[i]+=\"B\";do_dispatch();turn_count++;\n\n    while(turn_count<9400&&!all_done()){\n        // Try to deliver next-needed containers\n        // Evaluate: for each row, the cost to deliver its next-needed container\n        // Also evaluate: combined cost of \"pickup A, deliver A, then pickup B nearby\"\n        \n        struct Task{\n            int id,sr,sc,trow;\n            int pickup_dist,deliver_dist,total;\n        };\n        vector<Task> tasks;\n        \n        for(int row=0;row<N;row++){\n            int need=next_disp[row];\n            if(need>=row*N+N)continue;\n            auto[r,c]=fc(need);\n            if(r<0)continue;\n            int pd=abs(cr_r-r)+abs(cr_c-c);\n            int dd=abs(r-row)+(N-1-c);\n            tasks.push_back({need,r,c,row,pd,dd,pd+dd});\n        }\n        \n        if(!tasks.empty()){\n            // Pick task with lowest total cost\n            sort(tasks.begin(),tasks.end(),[](auto&a,auto&b){return a.total<b.total;});\n            \n            // But also consider: after delivering task[0], where will crane be?\n            // And what's the best next task from there?\n            // Simple 2-step lookahead\n            int best_combined=999;\n            int best_idx=0;\n            \n            for(int t=0;t<min((int)tasks.size(),3);t++){\n                int after_r=tasks[t].trow, after_c=N-1;\n                int cost1=tasks[t].total+2; // +2 for P,Q\n                \n                // Best next task from (after_r, after_c)\n                int best_next=0;\n                for(int row=0;row<N;row++){\n                    if(row==tasks[t].trow)continue; // might advance after delivery\n                    int need=next_disp[row];\n                    if(need>=row*N+N)continue;\n                    auto[r,c]=fc(need);\n                    if(r<0)continue;\n                    int pd2=abs(after_r-r)+abs(after_c-c);\n                    int dd2=abs(r-row)+(N-1-c);\n                    best_next=max(0,min(best_next?best_next:999,pd2+dd2));\n                }\n                \n                int combined=cost1+best_next;\n                if(combined<best_combined){best_combined=combined;best_idx=t;}\n            }\n            \n            auto&t=tasks[best_idx];\n            go(t.sr,t.sc);\n            if(grid[cr_r][cr_c]==t.id){\n                step('P');\n                deliver_to_gate(t.trow);\n            }\n            continue;\n        }\n        \n        // No deliverable container on grid - clear receiving gates\n        // Find most urgent gate to clear\n        int best_gate=-1,best_cost=999;\n        for(int i=0;i<N;i++){\n            if(grid[i][0]==-1)continue;\n            // Check if clearing this helps (more containers behind it)\n            if(recv_idx[i]>=N)continue; // nothing more to receive\n            int cost=abs(cr_r-i)+cr_c;\n            // Bonus: if a needed container is behind this one\n            for(int row=0;row<N;row++){\n                int need=next_disp[row];\n                if(need>=row*N+N)continue;\n                if(cont_gate[need]==i&&cont_ord[need]>=recv_idx[i]){\n                    cost-=5; // urgency bonus\n                    break;\n                }\n            }\n            if(cost<best_cost){best_cost=cost;best_gate=i;}\n        }\n        \n        if(best_gate>=0){\n            int cid=grid[best_gate][0];\n            int trow=cid/N;\n            go(best_gate,0);\n            if(grid[cr_r][cr_c]==cid){\n                step('P');\n                if(cid==next_disp[trow]){\n                    deliver_to_gate(trow);\n                } else {\n                    // Buffer in target row, high column\n                    int br=-1,bc=-1;\n                    for(int c2=N-2;c2>=1;c2--){\n                        if(grid[trow][c2]==-1&&!(cr_r==trow&&cr_c==c2)){br=trow;bc=c2;break;}\n                    }\n                    if(bc<0){\n                        // Any nearby empty\n                        auto[er,ec]=fem(trow,2);\n                        br=er;bc=ec;\n                    }\n                    if(br>=0){go(br,bc);if(grid[cr_r][cr_c]==-1)step('Q');\n                    else{auto[er,ec]=fem(cr_r,cr_c);if(er>=0){go(er,ec);step('Q');}}}\n                }\n            }\n            continue;\n        }\n        \n        // Clear gates with no more pending (lower priority)\n        for(int i=0;i<N;i++){\n            if(grid[i][0]==-1)continue;\n            int cid=grid[i][0];\n            int trow=cid/N;\n            go(i,0);\n            if(grid[cr_r][cr_c]==cid){\n                step('P');\n                if(cid==next_disp[trow])deliver_to_gate(trow);\n                else{\n                    auto[er,ec]=fem(trow,2);\n                    if(er>=0){go(er,ec);step('Q');}\n                    else{auto[er2,ec2]=fem(cr_r,cr_c);if(er2>=0){go(er2,ec2);step('Q');}}\n                }\n            }\n            break;\n        }\n        \n        if(cr_h!=-1){\n            // Still holding somehow - emergency drop\n            auto[er,ec]=fem(cr_r,cr_c);\n            if(er>=0){go(er,ec);step('Q');}\n            else step('.');\n        } else {\n            step('.');\n        }\n    }\n\n    int mx=0;for(int i=0;i<N;i++)mx=max(mx,(int)act[i].size());\n    for(int i=0;i<N;i++)while((int)act[i].size()<mx)act[i]+=\".\";\n    for(int i=0;i<N;i++)cout<<act[i]<<\"\\n\";\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\nint N;\nint orig_h[20][20];\n\ninline int mdist(int r1,int c1,int r2,int c2){return abs(r1-r2)+abs(c1-c2);}\n\nstruct Op { char type; int val; };\n\nstruct State {\n    vector<Op> ops;\n    int grid[20][20];\n    int px,py,load;\n    long long cost;\n    \n    void init(){\n        memcpy(grid,orig_h,sizeof(orig_h));\n        px=py=load=0; cost=0;\n        ops.clear();\n        interact();\n    }\n    \n    inline void interact(){\n        if(grid[py][px]>0){\n            ops.push_back({1,grid[py][px]});\n            cost+=grid[py][px]; load+=grid[py][px]; grid[py][px]=0;\n        }\n        if(grid[py][px]<0&&load>0){\n            int a=min(load,-grid[py][px]);\n            ops.push_back({2,a});\n            cost+=a; grid[py][px]+=a; load-=a;\n        }\n    }\n    \n    void move_to(int tx,int ty){\n        static const int dx[]={0,0,-1,1}, dy[]={-1,1,0,0};\n        while(px!=tx||py!=ty){\n            int best_score=INT_MAX, best_d=-1;\n            for(int d=0;d<4;d++){\n                int nx=px+dx[d], ny=py+dy[d];\n                if(nx<0||nx>=N||ny<0||ny>=N) continue;\n                if(mdist(nx,ny,tx,ty)>=mdist(px,py,tx,ty)) continue;\n                int score=0;\n                if(grid[ny][nx]>0) score-=grid[ny][nx];\n                if(grid[ny][nx]<0&&load>0) score-=min(load,-grid[ny][nx]);\n                if(score<best_score){best_score=score;best_d=d;}\n            }\n            ops.push_back({0,best_d});\n            cost+=100+load;\n            px+=dx[best_d]; py+=dy[best_d];\n            interact();\n        }\n    }\n    \n    long long total_cost(){\n        long long diff=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)\n            if(grid[i][j]!=0) diff+=100LL*abs(grid[i][j])+10000;\n        return cost+diff;\n    }\n};\n\nvoid output_ops(vector<Op>& ops){\n    static const char* dirs=\"UDLR\";\n    for(auto&op:ops){\n        if(op.type==0) putchar(dirs[op.val]),putchar('\\n');\n        else if(op.type==1) printf(\"+%d\\n\",op.val);\n        else printf(\"-%d\\n\",op.val);\n    }\n}\n\nvoid solve(vector<Op>&best_ops,long long&best_cost,mt19937&rng,int pr,int lc,double rf){\n    State st; st.init();\n    \n    while((int)st.ops.size()<99000){\n        if(st.load==0){\n            double bs=1e18; int bx=-1,by=-1;\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                if(st.grid[i][j]<=0) continue;\n                int d=mdist(st.py,st.px,i,j);\n                double score=(d+1.0)*100.0/st.grid[i][j];\n                if(rf>0) score*=(1.0+rf*((int)(rng()%1000)-500)/1000.0);\n                if(score<bs){bs=score;bx=j;by=i;}\n            }\n            if(bx==-1) break;\n            st.move_to(bx,by);\n            \n            bool found=true;\n            while(found&&st.load<lc&&(int)st.ops.size()<99000){\n                found=false;\n                int bd=pr,bx2=-1,by2=-1;\n                for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                    if(st.grid[i][j]>0){\n                        int d=mdist(st.py,st.px,i,j);\n                        if(d<bd){bd=d;bx2=j;by2=i;found=true;}\n                    }\n                }\n                if(found) st.move_to(bx2,by2);\n            }\n        } else {\n            int bd=INT_MAX,dx=-1,dy=-1;\n            for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n                if(st.grid[i][j]<0){\n                    int d=mdist(st.py,st.px,i,j);\n                    if(d<bd){bd=d;dx=j;dy=i;}\n                }\n            }\n            if(dx==-1) break;\n            st.move_to(dx,dy);\n        }\n    }\n    \n    long long c=st.total_cost();\n    if(c<best_cost){best_cost=c;best_ops=st.ops;}\n}\n\nint main(){\n    scanf(\"%d\",&N);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)scanf(\"%d\",&orig_h[i][j]);\n    \n    vector<Op> best_ops;\n    long long best_cost=LLONG_MAX;\n    mt19937 rng(42);\n    \n    auto t0=chrono::steady_clock::now();\n    auto elapsed=[&](){return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-t0).count();};\n    \n    // Small deterministic sweep\n    for(int r:{3,5,8,15})\n        for(int c:{80,150,300,1000})\n            solve(best_ops,best_cost,rng,r,c,0.0);\n    \n    // Track best params\n    int best_r=5, best_c=150;\n    \n    // Random restarts - maximize iterations\n    while(elapsed()<1900){\n        int radius, cap;\n        double rf;\n        if(rng()%3==0){\n            // Explore near best params\n            radius=max(2,best_r+(int)(rng()%7)-3);\n            cap=max(20,best_c+(int)(rng()%201)-100);\n            rf=0.02+0.3*(rng()%1000)/1000.0;\n        } else {\n            radius=3+rng()%18;\n            cap=30+rng()%600;\n            rf=0.02+0.5*(rng()%1000)/1000.0;\n        }\n        long long prev=best_cost;\n        solve(best_ops,best_cost,rng,radius,cap,rf);\n        if(best_cost<prev){\n            best_r=radius; best_c=cap;\n        }\n    }\n    \n    output_ops(best_ops);\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <cstring>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,T;\n    cin>>N>>M>>T;\n    int SC=2*N*(N-1);\n    vector<vector<int>>X(SC,vector<int>(M));\n    for(int i=0;i<SC;i++) for(int j=0;j<M;j++) cin>>X[i][j];\n    mt19937 rng(42);\n    \n    for(int t=0;t<T;t++){\n        auto t0=chrono::steady_clock::now();\n        double tlimit=0.17;\n        \n        vector<int> maxV(M,0);\n        for(int i=0;i<SC;i++) for(int l=0;l<M;l++) maxV[l]=max(maxV[l],X[i][l]);\n        \n        // Compute pairwise edge value for all seed pairs: sum_l max(x[a][l], x[b][l])\n        // Pick best pair as \"core edge\", then build grid around it\n        \n        // Score seeds by total value\n        vector<int> vals(SC,0);\n        for(int i=0;i<SC;i++) for(int l=0;l<M;l++) vals[i]+=X[i][l];\n        \n        // Select seeds: must include seeds with criterion maxima\n        vector<bool> mustInclude(SC,false);\n        for(int l=0;l<M;l++){\n            int best=-1;\n            for(int i=0;i<SC;i++) if(X[i][l]==maxV[l]){\n                if(best<0||vals[i]>vals[best]) best=i;\n            }\n            mustInclude[best]=true;\n        }\n        \n        vector<int> sel;\n        for(int i=0;i<SC;i++) if(mustInclude[i]) sel.push_back(i);\n        \n        vector<int> idx(SC); iota(idx.begin(),idx.end(),0);\n        sort(idx.begin(),idx.end(),[&](int a,int b){return vals[a]>vals[b];});\n        for(int i:idx){\n            if((int)sel.size()>=N*N) break;\n            if(!mustInclude[i]) sel.push_back(i);\n        }\n        sel.resize(N*N);\n        \n        // Precompute edge values between selected seeds\n        int NN=N*N;\n        vector<vector<int>> ev(NN,vector<int>(NN,0));\n        for(int a=0;a<NN;a++) for(int b=a+1;b<NN;b++){\n            int s=0;\n            for(int l=0;l<M;l++) s+=max(X[sel[a]][l],X[sel[b]][l]);\n            ev[a][b]=ev[b][a]=s;\n        }\n        \n        // Grid edges\n        vector<pair<int,int>> edges;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            int p=i*N+j;\n            if(j+1<N) edges.push_back({p,i*N+j+1});\n            if(i+1<N) edges.push_back({p,(i+1)*N+j});\n        }\n        \n        vector<int> perm(NN); iota(perm.begin(),perm.end(),0);\n        \n        // Objective: maximize max edge value + alpha * sum edge values\n        auto compScore=[&](vector<int>&p)->pair<int,long long>{\n            int mx=0; long long sm=0;\n            for(auto&[a,b]:edges){int v=ev[p[a]][p[b]]; mx=max(mx,v); sm+=v;}\n            return {mx,sm};\n        };\n        auto [cmx,csm]=compScore(perm);\n        \n        int iter=0;\n        while(true){\n            if((++iter&2047)==0){if(chrono::duration<double>(chrono::steady_clock::now()-t0).count()>tlimit) break;}\n            int a=rng()%NN,b=rng()%NN; if(a==b) continue;\n            swap(perm[a],perm[b]);\n            auto [nmx,nsm]=compScore(perm);\n            double temp=30.0*max(0.0,1.0-chrono::duration<double>(chrono::steady_clock::now()-t0).count()/tlimit)+0.01;\n            double oldS=cmx*100.0+csm*0.1;\n            double newS=nmx*100.0+nsm*0.1;\n            if(newS>=oldS||(uniform_real_distribution<>()(rng)<exp((newS-oldS)/temp))){cmx=nmx;csm=nsm;}\n            else swap(perm[a],perm[b]);\n        }\n        for(int i=0;i<N;i++){for(int j=0;j<N;j++){if(j) cout<<' ';cout<<sel[perm[i*N+j]];}cout<<'\\n';}\n        cout.flush();\n        for(int i=0;i<SC;i++) for(int j=0;j<M;j++) cin>>X[i][j];\n    }\n}","ahc038":"#include<bits/stdc++.h>\nusing namespace std;\nvector<int> hungarian(const vector<vector<int>>& cost){\n    int n=cost.size(),m=cost[0].size();\n    vector<int>u(n+1),v(m+1),p(m+1),way(m+1);\n    for(int i=1;i<=n;i++){\n        p[0]=i;int j0=0;\n        vector<int>minv(m+1,INT_MAX);\n        vector<bool>used(m+1,false);\n        do{\n            used[j0]=true;int i0=p[j0],delta=INT_MAX,j1=-1;\n            for(int j=1;j<=m;j++)if(!used[j]){\n                int cur=cost[i0-1][j-1]-u[i0]-v[j];\n                if(cur<minv[j]){minv[j]=cur;way[j]=j0;}\n                if(minv[j]<delta){delta=minv[j];j1=j;}\n            }\n            for(int j=0;j<=m;j++)if(used[j]){u[p[j]]+=delta;v[j]-=delta;}else minv[j]-=delta;\n            j0=j1;\n        }while(p[j0]!=0);\n        do{int j1=way[j0];p[j0]=p[j1];j0=j1;}while(j0);\n    }\n    vector<int>ans(n);\n    for(int j=1;j<=m;j++)if(p[j])ans[p[j]-1]=j-1;\n    return ans;\n}\nint N,M,V;\nint ddx[]={0,1,0,-1},ddy[]={1,0,-1,0};\n\nint main(){\n    auto T0=chrono::steady_clock::now();\n    auto ms=[&]()->int{return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-T0).count();};\n    \n    scanf(\"%d%d%d\",&N,&M,&V);\n    vector<string>s(N),t(N);\n    for(int i=0;i<N;i++)cin>>s[i];\n    for(int i=0;i<N;i++)cin>>t[i];\n    vector<pair<int,int>>src,tgt;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(s[i][j]=='1'&&t[i][j]=='0')src.push_back({i,j});\n        if(s[i][j]=='0'&&t[i][j]=='1')tgt.push_back({i,j});\n    }\n    int K=src.size();\n    if(K==0){printf(\"2\\n0 1\\n0 0\\n\");return 0;}\n    \n    vector<int>ma;\n    {\n        vector<vector<int>>cost(K,vector<int>(K));\n        for(int i=0;i<K;i++)for(int j=0;j<K;j++)\n            cost[i][j]=abs(src[i].first-tgt[j].first)+abs(src[i].second-tgt[j].second);\n        ma=hungarian(cost);\n    }\n    \n    struct Job{int sx,sy,tx,ty;};\n    vector<Job>jobs(K);\n    for(int i=0;i<K;i++) jobs[i]={src[i].first,src[i].second,tgt[ma[i]].first,tgt[ma[i]].second};\n    \n    int F=min(V-1,max(1,min(K,14)));\n    int VP=F+1;\n    printf(\"%d\\n\",VP);\n    for(int i=0;i<F;i++) printf(\"0 1\\n\");\n    printf(\"0 0\\n\");\n    \n    int rx=0,ry=0;\n    vector<int>fdir(F,0);\n    vector<string>ops;\n    \n    auto emitTurn=[&](char mv,vector<char>&rots,vector<bool>&picks){\n        string o(2*VP,'.');\n        o[0]=mv;\n        for(int i=0;i<F;i++) o[1+i]=rots[i];\n        for(int i=0;i<F;i++) if(picks[i]) o[VP+1+i]='P';\n        if(mv=='U')rx--;else if(mv=='D')rx++;else if(mv=='L')ry--;else if(mv=='R')ry++;\n        for(int i=0;i<F;i++){\n            if(rots[i]=='R')fdir[i]=(fdir[i]+1)%4;\n            else if(rots[i]=='L')fdir[i]=(fdir[i]+3)%4;\n        }\n        ops.push_back(o);\n    };\n    \n    auto navigateMulti=[&](int gx,int gy,vector<pair<int,int>>rotNeeds){\n        while(rx!=gx||ry!=gy){\n            char mv='.';\n            vector<char>rots(F,'.');\n            vector<bool>picks(F,false);\n            for(auto it=rotNeeds.begin();it!=rotNeeds.end();){\n                int fi=it->first,td=it->second;\n                if(fdir[fi]==td){it=rotNeeds.erase(it);continue;}\n                int r=(td-fdir[fi]+4)%4;\n                if(r<=2)rots[fi]='R';else rots[fi]='L';\n                ++it;\n            }\n            if(rx<gx)mv='D';else if(rx>gx)mv='U';else if(ry<gy)mv='R';else if(ry>gy)mv='L';\n            emitTurn(mv,rots,picks);\n        }\n        while(!rotNeeds.empty()){\n            vector<char>rots(F,'.');\n            vector<bool>picks(F,false);\n            bool any=false;\n            for(auto it=rotNeeds.begin();it!=rotNeeds.end();){\n                int fi=it->first,td=it->second;\n                if(fdir[fi]==td){it=rotNeeds.erase(it);continue;}\n                int r=(td-fdir[fi]+4)%4;\n                if(r<=2)rots[fi]='R';else rots[fi]='L';\n                any=true;++it;\n            }\n            if(!any)break;\n            emitTurn('.',rots,picks);\n        }\n    };\n    \n    auto doPickMulti=[&](vector<int>&fis){\n        vector<char>rots(F,'.');\n        vector<bool>picks(F,false);\n        for(int fi:fis) picks[fi]=true;\n        emitTurn('.',rots,picks);\n    };\n    \n    // Cluster considering both source and target proximity\n    vector<bool>assigned(K,false);\n    vector<vector<int>>batches;\n    int cx2=0,cy2=0;\n    while(true){\n        int first=-1,bd=1e9;\n        for(int j=0;j<K;j++)if(!assigned[j]){\n            int d=abs(jobs[j].sx-cx2)+abs(jobs[j].sy-cy2);\n            if(d<bd){bd=d;first=j;}\n        }\n        if(first<0)break;\n        // Score candidates by source proximity + target proximity to first's target\n        vector<pair<int,int>>cands;\n        for(int j=0;j<K;j++)if(!assigned[j]){\n            int ds=abs(jobs[j].sx-jobs[first].sx)+abs(jobs[j].sy-jobs[first].sy);\n            int dt=abs(jobs[j].tx-jobs[first].tx)+abs(jobs[j].ty-jobs[first].ty);\n            cands.push_back({ds+dt/2,j}); // weight source more\n        }\n        sort(cands.begin(),cands.end());\n        vector<int>batch;\n        for(int i=0;i<min(F,(int)cands.size());i++){\n            batch.push_back(cands[i].second);\n            assigned[cands[i].second]=true;\n        }\n        batches.push_back(batch);\n        int stx=0,sty=0;\n        for(int j:batch){stx+=jobs[j].tx;sty+=jobs[j].ty;}\n        cx2=stx/(int)batch.size();cy2=sty/(int)batch.size();\n    }\n    \n    // Order batches\n    {\n        int nb=batches.size();\n        vector<bool>used(nb,false);\n        vector<vector<int>>newB;\n        cx2=0;cy2=0;\n        for(int i=0;i<nb;i++){\n            int best=-1,bd=1e9;\n            for(int j=0;j<nb;j++)if(!used[j]){\n                int s3=0,s4=0;\n                for(int k:batches[j]){s3+=jobs[k].sx;s4+=jobs[k].sy;}\n                s3/=(int)batches[j].size();s4/=(int)batches[j].size();\n                int d=abs(s3-cx2)+abs(s4-cy2);\n                if(d<bd){bd=d;best=j;}\n            }\n            used[best]=true;\n            newB.push_back(batches[best]);\n            int t3=0,t4=0;\n            for(int k:batches[best]){t3+=jobs[k].tx;t4+=jobs[k].ty;}\n            cx2=t3/(int)batches[best].size();cy2=t4/(int)batches[best].size();\n        }\n        batches=newB;\n    }\n    \n    // Or-opt on batch order\n    {\n        auto batchCost=[&]()->int{\n            int c=0,px=0,py=0;\n            for(auto&batch:batches){\n                int s3=0,s4=0;\n                for(int k:batch){s3+=jobs[k].sx;s4+=jobs[k].sy;}\n                s3/=(int)batch.size();s4/=(int)batch.size();\n                c+=abs(s3-px)+abs(s4-py);\n                int t3=0,t4=0;\n                for(int k:batch){t3+=jobs[k].tx;t4+=jobs[k].ty;}\n                px=t3/(int)batch.size();py=t4/(int)batch.size();\n                // Add internal batch cost estimate\n                for(int k:batch) c+=abs(jobs[k].sx-jobs[k].tx)+abs(jobs[k].sy-jobs[k].ty);\n            }\n            return c;\n        };\n        \n        bool imp=true;\n        while(imp&&ms()<1500){\n            imp=false;\n            int nb=batches.size();\n            for(int i=0;i<nb&&ms()<1500;i++){\n                for(int j=i+2;j<nb;j++){\n                    // Try swap\n                    swap(batches[i],batches[j]);\n                    int nc=batchCost();\n                    swap(batches[i],batches[j]);\n                    int oc=batchCost();\n                    if(nc<oc){swap(batches[i],batches[j]);imp=true;break;}\n                }\n                if(imp)break;\n            }\n        }\n    }\n    \n    // Execute\n    for(auto&batch:batches){\n        int bSize=batch.size();\n        vector<int>fiAssign(bSize,-1);\n        vector<bool>picked(bSize,false);\n        int nextFi=0;\n        \n        // Pickup with simultaneous operations\n        while(true){\n            vector<int>remaining;\n            for(int q=0;q<bSize;q++)if(!picked[q])remaining.push_back(q);\n            if(remaining.empty())break;\n            \n            int availFi=F-nextFi;\n            if(availFi<=0)break;\n            \n            // Find best root position for simultaneous pickup\n            // Candidate positions: neighbors of remaining sources\n            map<pair<int,int>,vector<pair<int,int>>>posItems; // pos -> list of (bidx, dir)\n            for(int q:remaining){\n                int sx=jobs[batch[q]].sx,sy=jobs[batch[q]].sy;\n                for(int d=0;d<4;d++){\n                    int nr=sx-ddx[d],nc=sy-ddy[d];\n                    if(nr>=0&&nr<N&&nc>=0&&nc<N)\n                        posItems[{nr,nc}].push_back({q,d});\n                }\n            }\n            \n            int bestRX=-1,bestRY=-1;\n            int bestScore=-1;\n            vector<pair<int,int>>bestItems;\n            \n            for(auto&[pos,items]:posItems){\n                // Deduplicate: one item per direction, up to availFi\n                bool usedDir[4]={};\n                set<int>usedIdx;\n                vector<pair<int,int>>chosen;\n                for(auto&[bidx,dir]:items){\n                    if(!usedDir[dir]&&usedIdx.count(bidx)==0&&(int)chosen.size()<availFi){\n                        usedDir[dir]=true;\n                        usedIdx.insert(bidx);\n                        chosen.push_back({bidx,dir});\n                    }\n                }\n                int cnt=chosen.size();\n                int moveCost=abs(pos.first-rx)+abs(pos.second-ry);\n                // Score: more items is better; for same count, less move cost\n                // Effective turns saved = (cnt-1)*avg_single_cost - moveCost\n                int score=cnt*1000-moveCost;\n                if(score>bestScore){\n                    bestScore=score;bestRX=pos.first;bestRY=pos.second;bestItems=chosen;\n                }\n            }\n            \n            vector<pair<int,int>>rotNeeds;\n            vector<int>pickFis;\n            for(auto&[bidx,dir]:bestItems){\n                int fi=nextFi++;\n                fiAssign[bidx]=fi;\n                picked[bidx]=true;\n                rotNeeds.push_back({fi,dir});\n                pickFis.push_back(fi);\n            }\n            \n            navigateMulti(bestRX,bestRY,rotNeeds);\n            doPickMulti(pickFis);\n        }\n        \n        // Dropoff with simultaneous operations\n        vector<bool>dropped(bSize,false);\n        while(true){\n            vector<int>remaining;\n            for(int q=0;q<bSize;q++)if(!dropped[q])remaining.push_back(q);\n            if(remaining.empty())break;\n            \n            map<pair<int,int>,vector<pair<int,int>>>posItems;\n            for(int q:remaining){\n                int tx=jobs[batch[q]].tx,ty=jobs[batch[q]].ty;\n                for(int d=0;d<4;d++){\n                    int nr=tx-ddx[d],nc=ty-ddy[d];\n                    if(nr>=0&&nr<N&&nc>=0&&nc<N)\n                        posItems[{nr,nc}].push_back({q,d});\n                }\n            }\n            \n            int bestRX=-1,bestRY=-1,bestScore=-1;\n            vector<pair<int,int>>bestItems;\n            \n            for(auto&[pos,items]:posItems){\n                bool usedDir[4]={};\n                set<int>usedIdx,usedFi;\n                vector<pair<int,int>>chosen;\n                for(auto&[bidx,dir]:items){\n                    int fi=fiAssign[bidx];\n                    if(!usedDir[dir]&&usedIdx.count(bidx)==0&&usedFi.count(fi)==0&&(int)chosen.size()<F){\n                        usedDir[dir]=true;\n                        usedIdx.insert(bidx);\n                        usedFi.insert(fi);\n                        chosen.push_back({bidx,dir});\n                    }\n                }\n                int cnt=chosen.size();\n                int moveCost=abs(pos.first-rx)+abs(pos.second-ry);\n                int score=cnt*1000-moveCost;\n                if(score>bestScore){\n                    bestScore=score;bestRX=pos.first;bestRY=pos.second;bestItems=chosen;\n                }\n            }\n            \n            vector<pair<int,int>>rotNeeds;\n            vector<int>dropFis;\n            for(auto&[bidx,dir]:bestItems){\n                int fi=fiAssign[bidx];\n                rotNeeds.push_back({fi,dir});\n                dropFis.push_back(fi);\n                dropped[bidx]=true;\n            }\n            \n            navigateMulti(bestRX,bestRY,rotNeeds);\n            doPickMulti(dropFis);\n        }\n    }\n    \n    for(auto&o:ops)printf(\"%s\\n\",o.c_str());\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N; cin>>N;\n    vector<int> fx(2*N), fy(2*N);\n    for(int i=0;i<2*N;i++) cin>>fx[i]>>fy[i];\n    \n    const int MX=100000;\n    \n    int bestScore=0;\n    int brx1=0,bry1=0,brx2=MX,bry2=MX;\n    \n    for(int G:{150,250,350}){\n        double step=(double)MX/G;\n        vector<vector<int>> val(G,vector<int>(G,0));\n        for(int i=0;i<2*N;i++){\n            int gx=min((int)(fx[i]/step),G-1);\n            int gy=min((int)(fy[i]/step),G-1);\n            val[gx][gy]+=(i<N)?1:-1;\n        }\n        for(int lx=0;lx<G;lx++){\n            vector<int> cs(G,0);\n            for(int rx=lx;rx<G;rx++){\n                for(int gy=0;gy<G;gy++) cs[gy]+=val[rx][gy];\n                int cur=0,start=0;\n                for(int gy=0;gy<G;gy++){\n                    cur+=cs[gy];\n                    if(cur>bestScore){\n                        bestScore=cur;\n                        brx1=max(0,(int)(lx*step)-1);\n                        brx2=min(MX,(int)((rx+1)*step)+1);\n                        bry1=max(0,(int)(start*step)-1);\n                        bry2=min(MX,(int)((gy+1)*step)+1);\n                    }\n                    if(cur<0){cur=0;start=gy+1;}\n                }\n            }\n        }\n    }\n    \n    int rx1=brx1,ry1=bry1,rx2=brx2,ry2=bry2;\n    for(int iter=0;iter<5;iter++){\n        for(int side=0;side<4;side++){\n            vector<pair<int,int>> flist;\n            for(int i=0;i<2*N;i++){\n                if(fx[i]>=rx1&&fx[i]<=rx2&&fy[i]>=ry1&&fy[i]<=ry2){\n                    int w=(i<N)?1:-1;\n                    if(side<=1) flist.push_back({fx[i],w});\n                    else flist.push_back({fy[i],w});\n                }\n            }\n            if(side==0||side==2) sort(flist.begin(),flist.end());\n            else sort(flist.begin(),flist.end(),greater<>());\n            int total=0;\n            for(auto&[c,w]:flist) total+=w;\n            int best=total,cum=0;\n            for(auto&[c,w]:flist){\n                cum+=w;\n                if(total-cum>best){\n                    best=total-cum;\n                    if(side==0) rx1=c+1;\n                    else if(side==1) rx2=c-1;\n                    else if(side==2) ry1=c+1;\n                    else ry2=c-1;\n                }\n            }\n        }\n    }\n    \n    int rectScore=0;\n    for(int i=0;i<2*N;i++)\n        if(fx[i]>=rx1&&fx[i]<=rx2&&fy[i]>=ry1&&fy[i]<=ry2)\n            rectScore+=(i<N)?1:-1;\n    \n    int dx4[]={0,0,1,-1},dy4[]={1,-1,0,0};\n    \n    auto scorePolyGrid=[&](const vector<vector<bool>>&sel,int GS,double cW,double cH,double ox,double oy)->int{\n        int sc=0;\n        for(int i=0;i<2*N;i++){\n            int gx=(int)((fx[i]-ox)/cW);\n            int gy=(int)((fy[i]-oy)/cH);\n            if(gx>=0&&gx<GS&&gy>=0&&gy<GS&&sel[gx][gy])\n                sc+=(i<N)?1:-1;\n        }\n        return sc;\n    };\n    \n    auto findArticulation=[&](vector<vector<bool>>&sel,int GS)->vector<vector<bool>>{\n        vector<vector<bool>> isArt(GS,vector<bool>(GS,false));\n        vector<vector<int>> disc(GS,vector<int>(GS,-1));\n        vector<vector<int>> low(GS,vector<int>(GS,-1));\n        int timer=0;\n        int si=-1,sj=-1;\n        for(int i=0;i<GS&&si<0;i++)\n            for(int j=0;j<GS&&si<0;j++)\n                if(sel[i][j]){si=i;sj=j;}\n        if(si<0) return isArt;\n        struct Frame{int x,y,d,px,py,children;};\n        stack<Frame> stk;\n        stk.push({si,sj,0,-1,-1,0});\n        disc[si][sj]=low[si][sj]=timer++;\n        while(!stk.empty()){\n            auto&f=stk.top();\n            if(f.d<4){\n                int nx=f.x+dx4[f.d],ny=f.y+dy4[f.d];\n                f.d++;\n                if(nx>=0&&nx<GS&&ny>=0&&ny<GS&&sel[nx][ny]){\n                    if(disc[nx][ny]<0){\n                        disc[nx][ny]=low[nx][ny]=timer++;\n                        stk.push({nx,ny,0,f.x,f.y,0});\n                    } else if(nx!=f.px||ny!=f.py){\n                        low[f.x][f.y]=min(low[f.x][f.y],disc[nx][ny]);\n                    }\n                }\n            } else {\n                int x=f.x,y=f.y,px=f.px,py=f.py;\n                stk.pop();\n                if(!stk.empty()){\n                    auto&pf=stk.top();\n                    low[pf.x][pf.y]=min(low[pf.x][pf.y],low[x][y]);\n                    pf.children++;\n                    if(pf.px>=0&&low[x][y]>=disc[pf.x][pf.y])\n                        isArt[pf.x][pf.y]=true;\n                    if(pf.px<0&&pf.children>1)\n                        isArt[pf.x][pf.y]=true;\n                }\n            }\n        }\n        return isArt;\n    };\n    \n    auto tracePoly=[&](vector<vector<bool>>&finalSel,int GS,double cellW,double cellH,double ox,double oy)->vector<pair<int,int>>{\n        auto isSel=[&](int i,int j)->bool{return i>=0&&i<GS&&j>=0&&j<GS&&finalSel[i][j];};\n        int si2=-1,sj2=-1;\n        for(int i=0;i<GS&&si2<0;i++)\n            for(int j=0;j<GS&&si2<0;j++)\n                if(finalSel[i][j]){si2=i;sj2=j;}\n        if(si2<0) return {};\n        \n        int dir=1,gx=si2,gy=sj2;\n        int ddx[]={1,0,-1,0},ddy[]={0,1,0,-1};\n        auto intCell=[](int px,int py,int d)->pair<int,int>{\n            if(d==0)return{px,py-1};if(d==1)return{px,py};\n            if(d==2)return{px-1,py};return{px-1,py-1};\n        };\n        auto extCell=[](int px,int py,int d)->pair<int,int>{\n            if(d==0)return{px,py};if(d==1)return{px-1,py};\n            if(d==2)return{px-1,py-1};return{px,py-1};\n        };\n        \n        vector<pair<int,int>> bnd;\n        bnd.push_back({gx,gy});\n        for(int step=0;step<4*GS*GS+100;step++){\n            int ngx=gx+ddx[dir],ngy=gy+ddy[dir];\n            int rdir=(dir+3)%4;\n            auto[ri,rj]=intCell(ngx,ngy,rdir);\n            auto[re,rf]=extCell(ngx,ngy,rdir);\n            if(isSel(ri,rj)&&!isSel(re,rf)) dir=rdir;\n            else{\n                auto[s3,t3]=intCell(ngx,ngy,dir);\n                auto[u3,v3]=extCell(ngx,ngy,dir);\n                if(isSel(s3,t3)&&!isSel(u3,v3)){}\n                else{\n                    int ldir=(dir+1)%4;\n                    auto[li,lj]=intCell(ngx,ngy,ldir);\n                    auto[le,lf]=extCell(ngx,ngy,ldir);\n                    if(isSel(li,lj)&&!isSel(le,lf)) dir=ldir;\n                    else dir=(dir+2)%4;\n                }\n            }\n            gx=ngx;gy=ngy;\n            bnd.push_back({gx,gy});\n            if(gx==si2&&gy==sj2&&dir==1) break;\n        }\n        if(bnd.size()>1&&bnd.front()==bnd.back()) bnd.pop_back();\n        \n        vector<pair<int,int>> rp;\n        for(auto&[g1,g2]:bnd){\n            int rpx=max(0,min(MX,(int)round(g1*cellW+ox)));\n            int rpy=max(0,min(MX,(int)round(g2*cellH+oy)));\n            rp.push_back({rpx,rpy});\n        }\n        \n        vector<pair<int,int>> cl;\n        for(auto&p:rp){if(!cl.empty()&&cl.back()==p)continue;cl.push_back(p);}\n        if(cl.size()>1&&cl.front()==cl.back())cl.pop_back();\n        \n        for(int pass=0;pass<5;pass++){\n            vector<pair<int,int>>res;int nn=cl.size();if(nn<=4)break;bool ch=false;\n            for(int i=0;i<nn;i++){\n                auto[px,py]=cl[(i+nn-1)%nn];auto[cx2,cy2]=cl[i];auto[nx2,ny2]=cl[(i+1)%nn];\n                if((px==cx2&&cx2==nx2)||(py==cy2&&cy2==ny2))ch=true;\n                else res.push_back(cl[i]);\n            }\n            cl=res;if(!ch)break;\n        }\n        \n        int cn=cl.size();\n        if(cn<4||cn>1000) return {};\n        long long perim=0;bool valid=true;\n        set<pair<int,int>>seen;\n        for(auto&p:cl)if(!seen.insert(p).second)valid=false;\n        for(int i=0;i<cn;i++){\n            int ni=(i+1)%cn;\n            int dx2=abs(cl[i].first-cl[ni].first);\n            int dy2=abs(cl[i].second-cl[ni].second);\n            if(dx2==0&&dy2==0)valid=false;\n            if(dx2>0&&dy2>0)valid=false;\n            perim+=dx2+dy2;\n        }\n        if(perim>400000||!valid) return {};\n        return cl;\n    };\n    \n    auto tryGrid=[&](int GS,double ox,double oy)->pair<int,vector<pair<int,int>>>{\n        double cellW=(double)MX/GS;\n        double cellH=(double)MX/GS;\n        \n        vector<vector<int>> grid(GS,vector<int>(GS,0));\n        for(int i=0;i<2*N;i++){\n            int gx=(int)((fx[i]-ox)/cellW);\n            int gy=(int)((fy[i]-oy)/cellH);\n            if(gx<0)gx=0; if(gx>=GS)gx=GS-1;\n            if(gy<0)gy=0; if(gy>=GS)gy=GS-1;\n            grid[gx][gy]+=(i<N)?1:-1;\n        }\n        \n        vector<vector<bool>> sel(GS,vector<bool>(GS,false));\n        for(int i=0;i<GS;i++)\n            for(int j=0;j<GS;j++)\n                if(grid[i][j]>0) sel[i][j]=true;\n        \n        vector<vector<int>> comp(GS,vector<int>(GS,-1));\n        int ncomp=0;\n        vector<int> compScore;\n        vector<vector<pair<int,int>>> compCells;\n        for(int i=0;i<GS;i++){\n            for(int j=0;j<GS;j++){\n                if(sel[i][j]&&comp[i][j]<0){\n                    int sc=0;\n                    vector<pair<int,int>> cells;\n                    queue<pair<int,int>> q;\n                    q.push({i,j});comp[i][j]=ncomp;\n                    while(!q.empty()){\n                        auto[x,y]=q.front();q.pop();\n                        sc+=grid[x][y];cells.push_back({x,y});\n                        for(int d=0;d<4;d++){\n                            int nx=x+dx4[d],ny=y+dy4[d];\n                            if(nx>=0&&nx<GS&&ny>=0&&ny<GS&&sel[nx][ny]&&comp[nx][ny]<0){\n                                comp[nx][ny]=ncomp;q.push({nx,ny});\n                            }\n                        }\n                    }\n                    compScore.push_back(sc);\n                    compCells.push_back(cells);\n                    ncomp++;\n                }\n            }\n        }\n        \n        if(ncomp==0) return {0,{}};\n        \n        // Try top-3 components\n        vector<int> order(ncomp);\n        iota(order.begin(),order.end(),0);\n        sort(order.begin(),order.end(),[&](int a,int b){return compScore[a]>compScore[b];});\n        \n        int bestSc=0;\n        vector<pair<int,int>> bestPoly;\n        \n        int tryCount=min(ncomp,3);\n        for(int t=0;t<tryCount;t++){\n            int startComp=order[t];\n            if(compScore[startComp]<=0) break;\n            \n            vector<vector<bool>> finalSel(GS,vector<bool>(GS,false));\n            for(auto&[ci,cj]:compCells[startComp]) finalSel[ci][cj]=true;\n            \n            // Bridge expansion\n            for(int pass=0;pass<15;pass++){\n                bool changed=false;\n                for(int i=0;i<GS;i++){\n                    for(int j=0;j<GS;j++){\n                        if(finalSel[i][j]) continue;\n                        bool adj=false;\n                        for(int d=0;d<4;d++){\n                            int ni=i+dx4[d],nj=j+dy4[d];\n                            if(ni>=0&&ni<GS&&nj>=0&&nj<GS&&finalSel[ni][nj]){adj=true;break;}\n                        }\n                        if(!adj) continue;\n                        int gain=grid[i][j];\n                        set<int> bridged;\n                        for(int d=0;d<4;d++){\n                            int ni=i+dx4[d],nj=j+dy4[d];\n                            if(ni>=0&&ni<GS&&nj>=0&&nj<GS&&!finalSel[ni][nj]&&comp[ni][nj]>=0&&compScore[comp[ni][nj]]>0)\n                                bridged.insert(comp[ni][nj]);\n                        }\n                        for(int c:bridged) gain+=compScore[c];\n                        if(gain>0){\n                            finalSel[i][j]=true;\n                            for(int c:bridged)\n                                for(auto&[ci,cj]:compCells[c]) finalSel[ci][cj]=true;\n                            changed=true;\n                        }\n                    }\n                }\n                if(!changed) break;\n            }\n            \n            // Greedy removal\n            for(int pass=0;pass<10;pass++){\n                auto isArt=findArticulation(finalSel,GS);\n                bool changed=false;\n                vector<tuple<int,int,int>> cands;\n                for(int i=0;i<GS;i++){\n                    for(int j=0;j<GS;j++){\n                        if(!finalSel[i][j]||grid[i][j]>=0||isArt[i][j]) continue;\n                        bool boundary=false;\n                        for(int d=0;d<4;d++){\n                            int ni=i+dx4[d],nj=j+dy4[d];\n                            if(ni<0||ni>=GS||nj<0||nj>=GS||!finalSel[ni][nj]){boundary=true;break;}\n                        }\n                        if(boundary) cands.push_back({grid[i][j],i,j});\n                    }\n                }\n                sort(cands.begin(),cands.end());\n                for(auto&[v,ci,cj]:cands){\n                    if(!finalSel[ci][cj]) continue;\n                    int selNbrs=0;\n                    for(int d=0;d<4;d++){\n                        int ni=ci+dx4[d],nj=cj+dy4[d];\n                        if(ni>=0&&ni<GS&&nj>=0&&nj<GS&&finalSel[ni][nj]) selNbrs++;\n                    }\n                    if(selNbrs<=1){\n                        finalSel[ci][cj]=false;\n                        changed=true;\n                    }\n                }\n                if(!changed){\n                    isArt=findArticulation(finalSel,GS);\n                    for(auto&[v,ci,cj]:cands){\n                        if(!finalSel[ci][cj]||isArt[ci][cj]) continue;\n                        finalSel[ci][cj]=false;\n                        changed=true;\n                    }\n                }\n                if(!changed) break;\n            }\n            \n            int gs=scorePolyGrid(finalSel,GS,cellW,cellH,ox,oy);\n            if(gs>bestSc){\n                auto poly=tracePoly(finalSel,GS,cellW,cellH,ox,oy);\n                if(!poly.empty()){\n                    bestSc=gs;\n                    bestPoly=poly;\n                }\n            }\n        }\n        return {bestSc,bestPoly};\n    };\n    \n    cout<<4<<\"\\n\";\n    cout<<rx1<<\" \"<<ry1<<\"\\n\";\n    cout<<rx2<<\" \"<<ry1<<\"\\n\";\n    cout<<rx2<<\" \"<<ry2<<\"\\n\";\n    cout<<rx1<<\" \"<<ry2<<\"\\n\";\n    \n    int bestOverall=rectScore;\n    vector<pair<int,int>> bestPoly;\n    \n    auto elapsed=[start=chrono::steady_clock::now()]()->double{\n        return chrono::duration<double>(chrono::steady_clock::now()-start).count();\n    };\n    \n    vector<int> gridSizes={25,30,35,40,45,50,55,60,70,80,100};\n    \n    for(int GS:gridSizes){\n        if(elapsed()>1.5) break;\n        double cellW=(double)MX/GS;\n        // Try original and half-offset\n        for(int off=0;off<4;off++){\n            if(elapsed()>1.5) break;\n            double ox=(off&1)?cellW*0.5:0;\n            double oy=(off&2)?cellW*0.5:0;\n            auto[sc,poly]=tryGrid(GS,ox,oy);\n            if(!poly.empty()&&sc>bestOverall){\n                bestOverall=sc;\n                bestPoly=poly;\n            }\n        }\n    }\n    \n    if(!bestPoly.empty()){\n        cout<<bestPoly.size()<<\"\\n\";\n        for(auto&[a,b]:bestPoly) cout<<a<<\" \"<<b<<\"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include<bits/stdc++.h>\nusing namespace std;\nstruct Placement{int p,r;char d;int b;};\n\nlong long simEval(const Placement* ops,int n,const long long* w,const long long* h){\n    int idToIdx[101];\n    memset(idToIdx,-1,sizeof(idToIdx));\n    long long rx1[100],ry1[100],rx2[100],ry2[100];\n    long long mx=0,my=0;\n    for(int i=0;i<n;i++){\n        const auto&op=ops[i];\n        long long wi=op.r?h[op.p]:w[op.p];\n        long long hi=op.r?w[op.p]:h[op.p];\n        if(op.d=='U'){\n            long long x1=(op.b==-1)?0:rx2[idToIdx[op.b]];\n            long long x2=x1+wi;\n            long long y1=0;\n            for(int j=0;j<i;j++)\n                if(rx1[j]<x2&&rx2[j]>x1)y1=max(y1,ry2[j]);\n            rx1[i]=x1;ry1[i]=y1;rx2[i]=x2;ry2[i]=y1+hi;\n        }else{\n            long long y1=(op.b==-1)?0:ry2[idToIdx[op.b]];\n            long long y2=y1+hi;\n            long long x1=0;\n            for(int j=0;j<i;j++)\n                if(ry1[j]<y2&&ry2[j]>y1)x1=max(x1,rx2[j]);\n            rx1[i]=x1;ry1[i]=y1;rx2[i]=x1+wi;ry2[i]=y2;\n        }\n        idToIdx[op.p]=i;\n        mx=max(mx,rx2[i]);my=max(my,ry2[i]);\n    }\n    return mx+my;\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    int N,T,sigma;\n    cin>>N>>T>>sigma;\n    long long w[100],h[100];\n    for(int i=0;i<N;i++)cin>>w[i]>>h[i];\n    \n    mt19937 rng(42);\n    auto t0=chrono::steady_clock::now();\n    auto elapsed=[&]()->double{return chrono::duration<double>(chrono::steady_clock::now()-t0).count();};\n    \n    auto genGreedy=[&](int maxRefs,const long long*uw,const long long*uh)->vector<Placement>{\n        vector<Placement>ops;\n        for(int i=0;i<N;i++){\n            long long best=LLONG_MAX;\n            Placement bestOp{i,0,'U',-1};\n            int nrefs=0,refs[102];\n            refs[nrefs++]=-1;\n            int st=max(0,(int)ops.size()-maxRefs);\n            for(int j=st;j<(int)ops.size();j++)refs[nrefs++]=ops[j].p;\n            int sz=(int)ops.size();\n            ops.push_back({0,0,'U',-1});\n            for(int r2=0;r2<2;r2++)\n                for(int dd=0;dd<2;dd++){\n                    char dir=dd?'U':'L';\n                    for(int ri=0;ri<nrefs;ri++){\n                        ops[sz]={i,r2,dir,refs[ri]};\n                        long long sc=simEval(ops.data(),sz+1,uw,uh);\n                        if(sc<best){best=sc;bestOp=ops[sz];}\n                    }\n                }\n            ops[sz]=bestOp;\n        }\n        return ops;\n    };\n    \n    // Build multiple good solutions\n    vector<vector<Placement>> solutions;\n    vector<long long> scores;\n    \n    auto addSol=[&](vector<Placement>&ops,const long long*uw,const long long*uh){\n        long long sc=simEval(ops.data(),N,uw,uh);\n        solutions.push_back(ops);\n        scores.push_back(sc);\n    };\n    \n    {auto o=genGreedy(10,w,h);addSol(o,w,h);}\n    if(elapsed()<0.2){auto o=genGreedy(15,w,h);addSol(o,w,h);}\n    if(elapsed()<0.35){auto o=genGreedy(20,w,h);addSol(o,w,h);}\n    if(elapsed()<0.5&&N<=50){auto o=genGreedy(N,w,h);addSol(o,w,h);}\n    \n    int bestIdx=0;\n    for(int i=1;i<(int)scores.size();i++)\n        if(scores[i]<scores[bestIdx])bestIdx=i;\n    \n    auto hillClimb=[&](vector<Placement>&ops,double tEnd,const long long*uw,const long long*uh)->long long{\n        long long cur=simEval(ops.data(),N,uw,uh);\n        while(elapsed()<tEnd){\n            int idx=rng()%N;\n            Placement old=ops[idx];\n            int mv=rng()%4;\n            if(mv==0)ops[idx].r^=1;\n            else if(mv==1)ops[idx].d=(ops[idx].d=='U')?'L':'U';\n            else if(mv==2){\n                if(idx>0)ops[idx].b=(rng()%3==0)?-1:ops[rng()%idx].p;\n            }else{\n                ops[idx].r=rng()%2;\n                ops[idx].d=(rng()%2)?'U':'L';\n                if(idx>0)ops[idx].b=(rng()%3==0)?-1:ops[rng()%idx].p;\n                else ops[idx].b=-1;\n            }\n            long long nsc=simEval(ops.data(),N,uw,uh);\n            if(nsc<=cur)cur=nsc;\n            else ops[idx]=old;\n        }\n        return cur;\n    };\n    \n    // Optimize best solution\n    {\n        auto ops=solutions[bestIdx];\n        long long sc=hillClimb(ops,min(elapsed()+0.8,1.5),w,h);\n        solutions[bestIdx]=ops;scores[bestIdx]=sc;\n    }\n    \n    // Re-find best\n    for(int i=0;i<(int)scores.size();i++)\n        if(scores[i]<scores[bestIdx])bestIdx=i;\n    \n    double totalTime=2.7;\n    \n    for(int t=0;t<T;t++){\n        double remain=totalTime-elapsed();\n        double perTurn=remain/max(1,T-t);\n        double tEnd=min(elapsed()+perTurn,totalTime);\n        \n        // Decide which solution to output and optimize\n        int solIdx=bestIdx;\n        \n        if(elapsed()<tEnd-0.002){\n            if(t%3==0&&t>0){\n                // Perturbed from best\n                auto ops=solutions[bestIdx];\n                int np=2+rng()%5;\n                for(int k=0;k<np;k++){\n                    int idx=rng()%N;\n                    ops[idx].r=rng()%2;\n                    ops[idx].d=(rng()%2)?'U':'L';\n                    if(idx>0)ops[idx].b=(rng()%3==0)?-1:ops[rng()%idx].p;\n                }\n                long long sc=hillClimb(ops,tEnd,w,h);\n                solutions.push_back(ops);scores.push_back(sc);\n                if(sc<scores[bestIdx])bestIdx=(int)scores.size()-1;\n                solIdx=(int)scores.size()-1;\n            }else{\n                auto ops=solutions[bestIdx];\n                long long sc=hillClimb(ops,tEnd,w,h);\n                solutions[bestIdx]=ops;scores[bestIdx]=sc;\n                solIdx=bestIdx;\n            }\n        }\n        \n        // Output best known solution\n        for(int i=0;i<(int)scores.size();i++)\n            if(scores[i]<scores[bestIdx])bestIdx=i;\n        \n        auto&out=solutions[bestIdx];\n        cout<<N<<\"\\n\";\n        for(int i=0;i<N;i++)\n            cout<<out[i].p<<\" \"<<out[i].r<<\" \"<<out[i].d<<\" \"<<out[i].b<<\"\\n\";\n        cout.flush();\n        long long W,H;\n        cin>>W>>H;\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\nint N,M,H,A[1000];\nvector<int> adj[1000];\nint par[1000],dep[1000];\nvector<int> ch[1000];\nlong long sa[1000];\nint mrd[1000];\n\nvoid rebuild(int v,int d){\n    dep[v]=d;sa[v]=A[v];mrd[v]=0;\n    for(int c:ch[v]){rebuild(c,d+1);sa[v]+=sa[c];mrd[v]=max(mrd[v],1+mrd[c]);}\n}\nvoid shift_dep(int v,int dd){\n    dep[v]+=dd;\n    for(int c:ch[v])shift_dep(c,dd);\n}\nvoid fix_up(int v){\n    while(v!=-1){sa[v]=A[v];mrd[v]=0;\n        for(int c:ch[v]){sa[v]+=sa[c];mrd[v]=max(mrd[v],1+mrd[c]);}\n        v=par[v];}\n}\nlong long total_score(){long long s=0;for(int i=0;i<N;i++)s+=(long long)(dep[i]+1)*A[i];return s;}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin>>N>>M>>H;\n    for(int i=0;i<N;i++)cin>>A[i];\n    for(int i=0;i<M;i++){int u,v;cin>>u>>v;adj[u].push_back(v);adj[v].push_back(u);}\n    int xx[1000],yy[1000];\n    for(int i=0;i<N;i++)cin>>xx[i]>>yy[i];\n    mt19937 rng(42);\n    auto t0=chrono::steady_clock::now();\n    auto elapsed=[&](){return chrono::duration<double>(chrono::steady_clock::now()-t0).count();};\n    \n    int bp[1000];long long best_score=0;\n    \n    auto do_bfs=[&](vector<int>&order){\n        for(int i=0;i<N;i++){par[i]=-1;dep[i]=0;ch[i].clear();}\n        vector<bool>used(N,false);\n        for(int r:order){if(used[r])continue;used[r]=true;\n            queue<int>q;q.push(r);\n            while(!q.empty()){int u=q.front();q.pop();if(dep[u]>=H)continue;\n                vector<int>nbrs;for(int v:adj[u])if(!used[v])nbrs.push_back(v);\n                sort(nbrs.begin(),nbrs.end(),[](int a,int b){return A[a]>A[b];});\n                for(int v:nbrs){if(used[v])continue;used[v]=true;par[v]=u;dep[v]=dep[u]+1;ch[u].push_back(v);q.push(v);}\n            }\n        }\n    };\n    auto do_dfs=[&](vector<int>&order){\n        for(int i=0;i<N;i++){par[i]=-1;dep[i]=0;ch[i].clear();}\n        vector<bool>used(N,false);\n        for(int r:order){if(used[r])continue;used[r]=true;\n            stack<int>stk;stk.push(r);\n            while(!stk.empty()){int u=stk.top();int bn=-1,ba=-1;\n                if(dep[u]<H)for(int v:adj[u])if(!used[v]&&A[v]>ba){ba=A[v];bn=v;}\n                if(bn!=-1){used[bn]=true;par[bn]=u;dep[bn]=dep[u]+1;ch[u].push_back(bn);stk.push(bn);}else stk.pop();\n            }\n        }\n    };\n    \n    for(int t=0;elapsed()<0.12;t++){\n        vector<int>ord(N);iota(ord.begin(),ord.end(),0);\n        if(t==0)sort(ord.begin(),ord.end(),[](int a,int b){return A[a]<A[b];});\n        else{vector<int>key(N);for(int i=0;i<N;i++)key[i]=A[i]+(int)(rng()%80);sort(ord.begin(),ord.end(),[&](int a,int b){return key[a]<key[b];});}\n        do_bfs(ord);long long sc=total_score();if(sc>best_score){best_score=sc;for(int i=0;i<N;i++)bp[i]=par[i];}\n        do_dfs(ord);sc=total_score();if(sc>best_score){best_score=sc;for(int i=0;i<N;i++)bp[i]=par[i];}\n    }\n    \n    // SA\n    for(int i=0;i<N;i++){par[i]=bp[i];ch[i].clear();}\n    for(int i=0;i<N;i++)if(par[i]!=-1)ch[par[i]].push_back(i);\n    for(int i=0;i<N;i++)if(par[i]==-1)rebuild(i,0);\n    long long cur_score=best_score;\n    \n    double time_limit=1.9;\n    double sa_start=elapsed();\n    double sa_dur=time_limit-sa_start;\n    \n    while(elapsed()<time_limit){\n        double progress=(elapsed()-sa_start)/sa_dur;\n        double T=20.0*(1.0-progress);\n        \n        int v=rng()%N;\n        if(adj[v].empty())continue;\n        int nb=adj[v][rng()%adj[v].size()];\n        if(nb==par[v])continue;\n        \n        // Check v not ancestor of nb\n        {bool bad=false;int c=nb;for(int i=0;i<=H;i++){if(c==v){bad=true;break;}if(c==-1)break;c=par[c];}if(bad)continue;}\n        \n        int nd=dep[nb]+1;\n        if(nd+mrd[v]>H)continue;\n        \n        long long delta=(long long)(nd-dep[v])*sa[v];\n        \n        bool accept=false;\n        if(delta>0)accept=true;\n        else if(delta==0)accept=(rng()%3==0);\n        else if(T>0.05){\n            // Fast acceptance check\n            int r=rng()%10000;\n            double p=exp(delta/T);\n            if(r<(int)(p*10000))accept=true;\n        }\n        if(!accept)continue;\n        \n        int old_p=par[v];\n        int dd=nd-dep[v];\n        \n        // Detach\n        if(old_p!=-1){auto&cv=ch[old_p];cv.erase(find(cv.begin(),cv.end(),v));}\n        // Attach\n        par[v]=nb;ch[nb].push_back(v);\n        // Shift depths (sa[v] and mrd[v] unchanged)\n        shift_dep(v,dd);\n        // Fix ancestors\n        if(old_p!=-1)fix_up(old_p);\n        fix_up(nb);\n        \n        cur_score+=delta;\n        if(cur_score>best_score){best_score=cur_score;for(int i=0;i<N;i++)bp[i]=par[i];}\n    }\n    \n    for(int i=0;i<N;i++){if(i)cout<<' ';cout<<bp[i];}\n    cout<<'\\n';\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\n\nstruct State {\n    vector<vector<char>> gl;\n    vector<pair<char,int>> ops;\n    int oniCount;\n};\n\nint main(){\n    cin>>N;\n    vector<string> board(N);\n    for(int i=0;i<N;i++) cin>>board[i];\n    \n    vector<vector<char>> origGrid(N, vector<char>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) origGrid[i][j]=board[i][j];\n    \n    string dirC=\"UDLR\", revC=\"DURL\";\n    \n    auto simulate=[&](mt19937& rn, double randScale) -> pair<int, vector<pair<char,int>>> {\n        auto gl=origGrid;\n        vector<pair<char,int>> ops;\n        \n        auto push=[&](int dir, int line) -> char {\n            char ch;\n            if(dir==0){ch=gl[0][line];for(int i=0;i<N-1;i++)gl[i][line]=gl[i+1][line];gl[N-1][line]='.';}\n            else if(dir==1){ch=gl[N-1][line];for(int i=N-1;i>0;i--)gl[i][line]=gl[i-1][line];gl[0][line]='.';}\n            else if(dir==2){ch=gl[line][0];for(int j=0;j<N-1;j++)gl[line][j]=gl[line][j+1];gl[line][N-1]='.';}\n            else{ch=gl[line][N-1];for(int j=N-1;j>0;j--)gl[line][j]=gl[line][j-1];gl[line][0]='.';}\n            return ch;\n        };\n        \n        // Count clear directions for an oni\n        auto countClearDirs=[&](int r, int c) -> int {\n            int cnt=0; bool ok;\n            ok=true;for(int i=0;i<r;i++)if(gl[i][c]=='o'){ok=false;break;}if(ok)cnt++;\n            ok=true;for(int i=r+1;i<N;i++)if(gl[i][c]=='o'){ok=false;break;}if(ok)cnt++;\n            ok=true;for(int j=0;j<c;j++)if(gl[r][j]=='o'){ok=false;break;}if(ok)cnt++;\n            ok=true;for(int j=c+1;j<N;j++)if(gl[r][j]=='o'){ok=false;break;}if(ok)cnt++;\n            return cnt;\n        };\n        \n        auto fDirs=[&](int r, int c) -> vector<pair<int,int>> {\n            vector<pair<int,int>> res; bool ok;\n            ok=true;for(int i=0;i<r;i++)if(gl[i][c]=='o'){ok=false;break;}if(ok)res.push_back({0,r+1});\n            ok=true;for(int i=r+1;i<N;i++)if(gl[i][c]=='o'){ok=false;break;}if(ok)res.push_back({1,N-r});\n            ok=true;for(int j=0;j<c;j++)if(gl[r][j]=='o'){ok=false;break;}if(ok)res.push_back({2,c+1});\n            ok=true;for(int j=c+1;j<N;j++)if(gl[r][j]=='o'){ok=false;break;}if(ok)res.push_back({3,N-c});\n            return res;\n        };\n        \n        while(true){\n            vector<pair<int,int>> oniList;\n            for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(gl[i][j]=='x') oniList.push_back({i,j});\n            if(oniList.empty()) break;\n            \n            struct Cand{int r,c,dir,dist,oniRem;double score;};\n            vector<Cand> cands;\n            \n            for(auto&[r,c]:oniList){\n                auto dirs=fDirs(r,c);\n                for(auto&[d,dist]:dirs){\n                    int oni=0;\n                    if(d==0) for(int ii=0;ii<=r;ii++){if(gl[ii][c]=='x')oni++;}\n                    else if(d==1) for(int ii=r;ii<N;ii++){if(gl[ii][c]=='x')oni++;}\n                    else if(d==2) for(int jj=0;jj<=c;jj++){if(gl[r][jj]=='x')oni++;}\n                    else for(int jj=c;jj<N;jj++){if(gl[r][jj]=='x')oni++;}\n                    \n                    // Evaluate impact: simulate the push, check how many oni lose all directions\n                    // This is expensive but N is small\n                    auto backup=gl;\n                    int line=(d<=1)?c:r;\n                    for(int k=0;k<dist;k++){\n                        if(d==0)gl[0][line]='.',({for(int ii=0;ii<N-1;ii++)gl[ii][line]=backup[ii][line];});\n                        // Too complex inline, just do push\n                    }\n                    gl=backup; // restore\n                    \n                    // Simpler heuristic: prefer high oni/dist ratio, penalize blocking\n                    // Check if any oni on the same line might lose directions\n                    // For now: use oni*1000 - dist + randomness\n                    double score=(double)oni*1000.0-(double)dist;\n                    score += randScale * ((double)(rn()%1000)-500.0)/500.0*100.0;\n                    \n                    // Bonus: prefer oni with fewer clear directions (urgent)\n                    int cd = countClearDirs(r,c);\n                    if(cd==1) score += 500; // urgent - only 1 direction\n                    \n                    cands.push_back({r,c,d,dist,oni,score});\n                }\n            }\n            \n            if(cands.empty()) return {-1, ops};\n            \n            sort(cands.begin(),cands.end(),[](auto&a,auto&b){return a.score>b.score;});\n            auto&best=cands[0];\n            int line=(best.dir<=1)?best.c:best.r;\n            for(int k=0;k<best.dist;k++){\n                push(best.dir,line);\n                ops.push_back({dirC[best.dir],line});\n            }\n            if((int)ops.size()>4*N*N) return {-1, ops};\n        }\n        return {(int)ops.size(), ops};\n    };\n    \n    auto startTime=chrono::steady_clock::now();\n    int bestOps=INT_MAX;\n    vector<pair<char,int>> bestResult;\n    \n    // SA grouping baseline\n    {\n        int MAXG=4*N;\n        set<pair<int,int>> fSet;\n        vector<pair<int,int>> oList;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++){\n            if(board[i][j]=='o') fSet.insert({i,j});\n            if(board[i][j]=='x') oList.push_back({i,j});\n        }\n        int nO=oList.size();\n        vector<vector<pair<int,int>>> oOpts(nO);\n        for(int idx=0;idx<nO;idx++){\n            int r=oList[idx].first,c=oList[idx].second;bool ok;\n            ok=true;for(int i=0;i<r;i++)if(fSet.count({i,c})){ok=false;break;}if(ok)oOpts[idx].push_back({0*N+c,r+1});\n            ok=true;for(int i=r+1;i<N;i++)if(fSet.count({i,c})){ok=false;break;}if(ok)oOpts[idx].push_back({1*N+c,N-r});\n            ok=true;for(int j=0;j<c;j++)if(fSet.count({r,j})){ok=false;break;}if(ok)oOpts[idx].push_back({2*N+r,c+1});\n            ok=true;for(int j=c+1;j<N;j++)if(fSet.count({r,j})){ok=false;break;}if(ok)oOpts[idx].push_back({3*N+r,N-c});\n        }\n        vector<int> asgn(nO),ad(nO);\n        vector<array<int,22>> gC(MAXG);for(auto&a:gC)a.fill(0);\n        vector<int> gM(MAXG,0),gS(MAXG,0);int tc=0;\n        auto aG=[&](int g,int d){int om=gM[g];gC[g][d]++;gS[g]++;if(d>om)gM[g]=d;tc+=2*(gM[g]-om);};\n        auto rGf=[&](int g,int d){gC[g][d]--;gS[g]--;if(gS[g]==0){tc-=2*gM[g];gM[g]=0;return;}int om=gM[g];if(d==om&&gC[g][d]==0){while(gM[g]>0&&gC[g][gM[g]]==0)gM[g]--;tc+=2*(gM[g]-om);}};\n        for(int i=0;i<nO;i++){int bd=99,bg=-1;for(auto&[g,d]:oOpts[i])if(d<bd){bd=d;bg=g;}asgn[i]=bg;ad[i]=bd;aG(bg,bd);}\n        mt19937 rn(42);int btc=tc;auto ba=asgn,bad=ad;\n        for(int it=0;;it++){\n            if(it%500000==0){if(chrono::duration<double>(chrono::steady_clock::now()-startTime).count()>0.5)break;}\n            double t=40.0*(1.0-(double)it/8000000);if(t<0.1)t=0.1;\n            int o=rn()%nO;if(oOpts[o].size()<=1)continue;\n            int ci=rn()%oOpts[o].size();auto[nG,nD]=oOpts[o][ci];int oG=asgn[o],oD=ad[o];if(nG==oG)continue;\n            int oc=tc;rGf(oG,oD);aG(nG,nD);int d=tc-oc;\n            if(d<=0||(t>0.01&&(rn()%10000)<(int)(10000*exp(-d/t)))){asgn[o]=nG;ad[o]=nD;if(tc<btc){btc=tc;ba=asgn;bad=ad;}}\n            else{rGf(nG,nD);aG(oG,oD);}\n        }\n        map<int,int> gMD;for(int i=0;i<nO;i++)gMD[ba[i]]=max(gMD[ba[i]],bad[i]);\n        vector<pair<char,int>> res;\n        for(auto&[g,mx]:gMD){int dir=g/N,line=g%N;for(int k=0;k<mx;k++)res.push_back({dirC[dir],line});for(int k=0;k<mx;k++)res.push_back({revC[dir],line});}\n        bestOps=res.size();bestResult=res;\n    }\n    \n    // Non-restore trials with varying randomness\n    for(int trial=0;;trial++){\n        if(chrono::duration<double>(chrono::steady_clock::now()-startTime).count()>1.75) break;\n        mt19937 rn(trial*97+13);\n        double scale = 50.0 + (trial%20)*20.0;\n        auto[ops,res]=simulate(rn, scale);\n        if(ops>0&&ops<=4*N*N&&ops<bestOps){bestOps=ops;bestResult=res;}\n    }\n    \n    for(auto&[d,p]:bestResult) cout<<d<<\" \"<<p<<\"\\n\";\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\nint N,L,T[100];\n\nlong long sim_full(int*a,int*b,int*cnt){\n    memset(cnt,0,400);\n    int vis[100]={};\n    int x=0;\n    for(int w=0;w<L;w++){\n        cnt[x]++;vis[x]++;\n        x=(vis[x]&1)?a[x]:b[x];\n    }\n    long long e=0;\n    for(int i=0;i<N;i++)e+=abs(cnt[i]-T[i]);\n    return e;\n}\n\n// Partial simulation for quick screening\nlong long sim_partial(int*a,int*b,int steps){\n    int cnt[100]={},vis[100]={};\n    int x=0;\n    for(int w=0;w<steps;w++){\n        cnt[x]++;vis[x]++;\n        x=(vis[x]&1)?a[x]:b[x];\n    }\n    long long e=0;\n    double scale=(double)L/steps;\n    for(int i=0;i<N;i++)e+=abs((int)(cnt[i]*scale+0.5)-T[i]);\n    return e;\n}\n\nvoid flowAssign(int*a,int*b,const int*w){\n    double cap[100];\n    for(int j=0;j<N;j++)cap[j]=T[j];\n    struct Item{int node,which;double weight;};\n    vector<Item> items;\n    for(int i=0;i<N;i++){\n        items.push_back({i,0,(w[i]+1)/2.0});\n        items.push_back({i,1,w[i]/2.0});\n    }\n    sort(items.begin(),items.end(),[](const Item&a,const Item&b){return a.weight>b.weight;});\n    for(auto&it:items){\n        int best=0;\n        for(int j=1;j<N;j++)if(cap[j]>cap[best])best=j;\n        if(it.which==0)a[it.node]=best;else b[it.node]=best;\n        cap[best]-=it.weight;\n    }\n}\n\nint main(){\n    scanf(\"%d%d\",&N,&L);\n    for(int i=0;i<N;i++)scanf(\"%d\",&T[i]);\n    \n    int bestA[100],bestB[100],a[100],b[100],cnt[100];\n    long long bestErr=2000000000LL;\n    mt19937 rng(42);\n    auto start=chrono::steady_clock::now();\n    auto elapsed=[&]()->double{return chrono::duration<double>(chrono::steady_clock::now()-start).count();};\n    \n    // Iterative refinement init\n    for(int restart=0;restart<3&&elapsed()<0.4;restart++){\n        int weights[100];\n        for(int i=0;i<N;i++) weights[i]=T[i];\n        if(restart>0) for(int i=0;i<N;i++) weights[i]=max(0,T[i]+(int)(rng()%201)-100);\n        for(int round=0;round<12&&elapsed()<0.4;round++){\n            flowAssign(a,b,weights);\n            long long err=sim_full(a,b,cnt);\n            if(err<bestErr){bestErr=err;memcpy(bestA,a,sizeof(a));memcpy(bestB,b,sizeof(b));}\n            for(int i=0;i<N;i++) weights[i]=max(0,(int)(weights[i]+0.5*(T[i]-cnt[i])));\n        }\n    }\n    \n    // SA with partial sim screening\n    long long bestPartial=sim_partial(bestA,bestB,50000);\n    \n    while(true){\n        double el=elapsed();\n        if(el>1.83)break;\n        double temp=max(0.2,40.0*(1.0-el/1.85));\n        memcpy(a,bestA,sizeof(a));memcpy(b,bestB,sizeof(b));\n        \n        int r=rng()%3;\n        if(r==0){\n            int i=rng()%N,j=rng()%N;\n            int wi=rng()%2,wj=rng()%2;\n            swap(wi?b[i]:a[i],wj?b[j]:a[j]);\n        } else {\n            int i=rng()%N;\n            if(rng()&1)b[i]=rng()%N;else a[i]=rng()%N;\n        }\n        \n        // Quick screen with partial sim\n        long long p=sim_partial(a,b,50000);\n        double pdelta=(double)(p-bestPartial);\n        if(pdelta>temp*20)continue; // skip if clearly worse\n        \n        // Full simulation\n        long long err2=sim_full(a,b,cnt);\n        double delta=(double)(err2-bestErr);\n        if(delta<=0||(int)(rng()%1000000)<(int)(1000000.0*exp(-delta/temp))){\n            bestErr=err2;\n            bestPartial=p;\n            memcpy(bestA,a,sizeof(a));memcpy(bestB,b,sizeof(b));\n        }\n    }\n    for(int i=0;i<N;i++)printf(\"%d %d\\n\",bestA[i],bestB[i]);\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct DSU {\n    vector<int> p, r;\n    DSU(){}\n    DSU(int n): p(n), r(n,0) { iota(p.begin(),p.end(),0); }\n    int find(int x){ return p[x]==x?x:p[x]=find(p[x]); }\n    bool unite(int a, int b){\n        a=find(a); b=find(b);\n        if(a==b) return false;\n        if(r[a]<r[b]) swap(a,b);\n        p[b]=a;\n        if(r[a]==r[b]) r[a]++;\n        return true;\n    }\n};\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N,M,Q,L,W;\n    cin>>N>>M>>Q>>L>>W;\n    vector<int> G(M);\n    for(auto &g:G) cin>>g;\n    vector<int> lx(N),rx(N),ly(N),ry(N);\n    for(int i=0;i<N;i++) cin>>lx[i]>>rx[i]>>ly[i]>>ry[i];\n    \n    vector<double> cx(N),cy(N);\n    for(int i=0;i<N;i++){\n        cx[i]=(lx[i]+rx[i])/2.0;\n        cy[i]=(ly[i]+ry[i])/2.0;\n    }\n    \n    auto edist = [&](int a, int b) -> double {\n        double dx=cx[a]-cx[b], dy=cy[a]-cy[b];\n        return sqrt(dx*dx+dy*dy);\n    };\n    \n    // Precompute nearest neighbors\n    vector<vector<int>> knn(N);\n    for(int i=0;i<N;i++){\n        vector<pair<double,int>> ds;\n        for(int j=0;j<N;j++) if(i!=j) ds.push_back({edist(i,j),j});\n        sort(ds.begin(),ds.end());\n        int k=min((int)ds.size(),30);\n        for(int j=0;j<k;j++) knn[i].push_back(ds[j].second);\n    }\n    \n    set<pair<int,int>> oracleEdges;\n    int queriesUsed=0;\n    vector<int> oracleCov(N,0);\n    \n    auto doQuery = [&](vector<int>& subset){\n        cout<<\"? \"<<subset.size();\n        for(int c:subset) cout<<\" \"<<c;\n        cout<<\"\\n\"<<flush;\n        queriesUsed++;\n        for(int e=0;e<(int)subset.size()-1;e++){\n            int a,b;cin>>a>>b;\n            if(a>b) swap(a,b);\n            oracleEdges.insert({a,b});\n        }\n        for(int c:subset) oracleCov[c]++;\n    };\n    \n    // ---- PHASE 1: Targeted global exploration ----\n    int phase1Q = Q * 3 / 5;\n    \n    for(int q=0;q<phase1Q;q++){\n        int best=-1;\n        for(int i=0;i<N;i++)\n            if(best<0||oracleCov[i]<oracleCov[best]) best=i;\n        \n        vector<int> subset;\n        subset.push_back(best);\n        set<int> inS;\n        inS.insert(best);\n        \n        // Pick nearest neighbors preferring low coverage\n        vector<pair<pair<int,double>,int>> cands;\n        for(int j:knn[best])\n            cands.push_back({{oracleCov[j],edist(best,j)},j});\n        sort(cands.begin(),cands.end());\n        \n        for(auto&[key,j]:cands){\n            if((int)subset.size()>=L) break;\n            if(!inS.count(j)){subset.push_back(j);inS.insert(j);}\n        }\n        if((int)subset.size()<L){\n            vector<pair<double,int>> more;\n            for(int j=0;j<N;j++) if(!inS.count(j))\n                more.push_back({edist(best,j),j});\n            sort(more.begin(),more.end());\n            for(auto&[d,j]:more){\n                if((int)subset.size()>=L) break;\n                subset.push_back(j);inS.insert(j);\n            }\n        }\n        \n        if((int)subset.size()<2) break;\n        doQuery(subset);\n    }\n    \n    // ---- Position refinement using oracle edges ----\n    // Oracle MST edges connect truly close cities.\n    // If two cities have oracle edge, adjust their positions toward each other slightly.\n    // Use spring-like relaxation.\n    {\n        // Build adjacency from oracle edges\n        vector<vector<int>> oAdj(N);\n        for(auto [a,b]:oracleEdges){\n            oAdj[a].push_back(b);\n            oAdj[b].push_back(a);\n        }\n        \n        // Simple spring relaxation: move each city toward its oracle neighbors\n        double alpha = 0.05; // small step\n        for(int iter=0;iter<20;iter++){\n            vector<double> nx(N),ny(N);\n            for(int i=0;i<N;i++){nx[i]=cx[i];ny[i]=cy[i];}\n            \n            for(int i=0;i<N;i++){\n                if(oAdj[i].empty()) continue;\n                double fx=0,fy=0;\n                for(int j:oAdj[i]){\n                    fx+=cx[j]-cx[i];\n                    fy+=cy[j]-cy[i];\n                }\n                fx/=oAdj[i].size();\n                fy/=oAdj[i].size();\n                \n                double newx=cx[i]+alpha*fx;\n                double newy=cy[i]+alpha*fy;\n                \n                // Clamp to rectangle\n                newx=max((double)lx[i],min((double)rx[i],newx));\n                newy=max((double)ly[i],min((double)ry[i],newy));\n                \n                nx[i]=newx;\n                ny[i]=newy;\n            }\n            cx=nx;cy=ny;\n        }\n        \n        // Rebuild knn with updated positions\n        for(int i=0;i<N;i++){\n            vector<pair<double,int>> ds;\n            for(int j=0;j<N;j++) if(i!=j) ds.push_back({edist(i,j),j});\n            sort(ds.begin(),ds.end());\n            knn[i].clear();\n            int k=min((int)ds.size(),30);\n            for(int j=0;j<k;j++) knn[i].push_back(ds[j].second);\n        }\n    }\n    \n    // ---- CLUSTERING ----\n    vector<int> centers(M);\n    vector<double> minD(N,1e18);\n    vector<bool> isC(N,false);\n    centers[0]=0;isC[0]=true;\n    for(int i=0;i<N;i++) minD[i]=edist(i,0);\n    for(int c=1;c<M;c++){\n        int best=-1;\n        for(int i=0;i<N;i++) if(!isC[i])\n            if(best<0||minD[i]>minD[best]) best=i;\n        centers[c]=best;isC[best]=true;\n        for(int i=0;i<N;i++) minD[i]=min(minD[i],edist(i,best));\n    }\n    \n    vector<double> gcx(M),gcy(M);\n    for(int i=0;i<M;i++){gcx[i]=cx[centers[i]];gcy[i]=cy[centers[i]];}\n    \n    vector<int> assignment(N,-1);\n    for(int iter=0;iter<30;iter++){\n        using T=tuple<double,int,int>;\n        priority_queue<T,vector<T>,greater<T>> pq;\n        for(int i=0;i<N;i++)\n            for(int g=0;g<M;g++){\n                double dx=cx[i]-gcx[g],dy=cy[i]-gcy[g];\n                pq.push({dx*dx+dy*dy,i,g});\n            }\n        fill(assignment.begin(),assignment.end(),-1);\n        vector<int> cap(G.begin(),G.end());\n        int assigned=0;\n        while(!pq.empty()&&assigned<N){\n            auto[d,c,g]=pq.top();pq.pop();\n            if(assignment[c]!=-1||cap[g]<=0) continue;\n            assignment[c]=g;cap[g]--;assigned++;\n        }\n        bool changed=false;\n        for(int g=0;g<M;g++){\n            double nx=0,ny=0;int cnt=0;\n            for(int i=0;i<N;i++) if(assignment[i]==g){nx+=cx[i];ny+=cy[i];cnt++;}\n            if(!cnt) continue;\n            nx/=cnt;ny/=cnt;\n            if(abs(gcx[g]-nx)>0.01||abs(gcy[g]-ny)>0.01) changed=true;\n            gcx[g]=nx;gcy[g]=ny;\n        }\n        if(!changed) break;\n    }\n    \n    vector<vector<int>> groups(M);\n    for(int i=0;i<N;i++) groups[assignment[i]].push_back(i);\n    \n    // ---- PHASE 2: Within-group queries ----\n    for(int g=0;g<M && queriesUsed<Q;g++){\n        auto& grp=groups[g];\n        int sz=grp.size();\n        if(sz<=1) continue;\n        \n        sort(grp.begin(),grp.end(),[&](int a,int b){\n            return cx[a]+cy[a]<cx[b]+cy[b];\n        });\n        \n        if(sz<=L){\n            vector<int> subset(grp.begin(),grp.end());\n            doQuery(subset);\n        } else {\n            int stride=max(1,L/2);\n            for(int i=0;i+1<sz && queriesUsed<Q;i+=stride){\n                int end=min(i+L,sz);\n                if(end-i<2) break;\n                vector<int> subset(grp.begin()+i,grp.begin()+end);\n                doQuery(subset);\n            }\n        }\n    }\n    \n    // More passes with different sort orders\n    for(int pass=0;pass<3 && queriesUsed<Q;pass++){\n        for(int g=0;g<M && queriesUsed<Q;g++){\n            auto grp=groups[g];\n            int sz=grp.size();\n            if(sz<=L) continue;\n            \n            if(pass==0) sort(grp.begin(),grp.end(),[&](int a,int b){return cx[a]<cx[b];});\n            else if(pass==1) sort(grp.begin(),grp.end(),[&](int a,int b){return cy[a]<cy[b];});\n            else sort(grp.begin(),grp.end(),[&](int a,int b){return cx[a]-cy[a]<cx[b]-cy[b];});\n            \n            int stride=max(1,L-1);\n            for(int i=0;i+1<sz && queriesUsed<Q;i+=stride){\n                int end=min(i+L,sz);\n                if(end-i<2) break;\n                vector<int> subset(grp.begin()+i,grp.begin()+end);\n                doQuery(subset);\n            }\n        }\n    }\n    \n    // ---- BUILD SPANNING TREES ----\n    // Oracle discount depends on W - larger W means estimates are less reliable\n    // so trust oracle edges more\n    double discount = max(0.2, min(0.7, 0.5 * (1.0 - W/5000.0) + 0.3));\n    // W=500 -> discount~0.62, W=2500 -> discount~0.38\n    // Actually simpler: discount = 0.3 + 0.4*(500.0/max(500,W))\n    // W=500 -> 0.7, W=2500 -> 0.38\n    discount = 0.3 + 0.3 * (500.0 / max(500, W));\n    \n    cout<<\"!\"<<endl;\n    \n    for(int g=0;g<M;g++){\n        auto& grp=groups[g];\n        int sz=grp.size();\n        for(int i=0;i<sz;i++){\n            if(i) cout<<\" \";\n            cout<<grp[i];\n        }\n        cout<<\"\\n\";\n        if(sz<=1) continue;\n        \n        set<int> inGrp(grp.begin(),grp.end());\n        \n        vector<tuple<double,int,int>> edges;\n        for(auto[a,b]:oracleEdges)\n            if(inGrp.count(a)&&inGrp.count(b))\n                edges.push_back({edist(a,b)*discount,a,b});\n        \n        for(int i=0;i<sz;i++)\n            for(int j=i+1;j<sz;j++)\n                edges.push_back({edist(grp[i],grp[j]),grp[i],grp[j]});\n        \n        sort(edges.begin(),edges.end());\n        \n        DSU gdsu(N);\n        vector<pair<int,int>> tree;\n        for(auto&[w,a,b]:edges){\n            if(gdsu.unite(a,b)){\n                tree.push_back({a,b});\n                if((int)tree.size()==sz-1) break;\n            }\n        }\n        for(auto[a,b]:tree) cout<<a<<\" \"<<b<<\"\\n\";\n    }\n    \n    cout<<flush;\n    return 0;\n}","ahc046":"#include<bits/stdc++.h>\nusing namespace std;\nint N,M;\nint dx[]={-1,1,0,0},dy[]={0,0,-1,1};\nchar dc[]={'U','D','L','R'};\nuint64_t zobrist[400];\n\nstruct BS7{\n    uint64_t w[7]={};\n    bool get(int i)const{return (w[i/64]>>(i%64))&1;}\n    void flip(int i){w[i/64]^=(1ULL<<(i%64));}\n};\n\npair<int,int> doSlide(int x,int y,int d,const BS7&bs){\n    while(true){\n        int nx=x+dx[d],ny=y+dy[d];\n        if(nx<0||nx>=N||ny<0||ny>=N||bs.get(nx*N+ny))break;\n        x=nx;y=ny;\n    }\n    return{x,y};\n}\n\nvector<pair<int,int>> bfsMoveOnly(int ci,int cj,int gi,int gj,BS7&bs){\n    if(ci==gi&&cj==gj)return{};\n    int dist[20][20];\n    memset(dist,-1,sizeof(dist));\n    int pdir[20][20];\n    pair<int,int> par[20][20];\n    queue<pair<int,int>>q;\n    dist[ci][cj]=0;q.push({ci,cj});\n    while(!q.empty()){\n        auto[x,y]=q.front();q.pop();\n        if(x==gi&&y==gj)break;\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&&!bs.get(nx*N+ny)&&dist[nx][ny]<0){\n                dist[nx][ny]=dist[x][y]+1;par[nx][ny]={x,y};pdir[nx][ny]=d;q.push({nx,ny});\n            }\n        }\n    }\n    vector<pair<int,int>>acts;\n    if(dist[gi][gj]<0)return acts;\n    int x=gi,y=gj;\n    while(x!=ci||y!=cj){acts.push_back({0,pdir[x][y]});auto[px,py]=par[x][y];x=px;y=py;}\n    reverse(acts.begin(),acts.end());\n    return acts;\n}\n\nint main(){\n    mt19937_64 rng(12345);\n    for(int i=0;i<400;i++) zobrist[i]=rng();\n    \n    scanf(\"%d%d\",&N,&M);\n    vector<int>ti(M),tj(M);\n    for(int k=0;k<M;k++)scanf(\"%d%d\",&ti[k],&tj[k]);\n    \n    int ci=ti[0],cj=tj[0];\n    BS7 curBs;\n    uint64_t curHash=0;\n    vector<pair<int,int>>allActs;\n    \n    for(int k=1;k<M;k++){\n        int gi=ti[k],gj=tj[k];\n        \n        struct Node{\n            int x,y;\n            uint64_t bh;\n            BS7 bs;\n            int parent;\n            int action,dir;\n            int g; // cost so far\n        };\n        \n        const int NODE_LIMIT = 60000;\n        vector<Node> nd;\n        nd.reserve(NODE_LIMIT+200);\n        unordered_map<uint64_t,int> vis; // key -> best g\n        \n        auto sk=[](int x,int y,uint64_t bh)->uint64_t{\n            uint64_t h = bh;\n            h ^= (uint64_t)x * 6364136223846793005ULL + 1442695040888963407ULL;\n            h ^= (uint64_t)y * 2862933555777941757ULL + 3037000493ULL;\n            return h;\n        };\n        \n        auto heur=[&](int x,int y)->int{\n            return abs(x-gi)+abs(y-gj);\n        };\n        \n        // A* with priority queue\n        // pq entries: (f, node_index)\n        priority_queue<pair<int,int>,vector<pair<int,int>>,greater<>> pq;\n        \n        nd.push_back({ci,cj,curHash,curBs,-1,-1,-1,0});\n        uint64_t key0=sk(ci,cj,curHash);\n        vis[key0]=0;\n        pq.push({heur(ci,cj),0});\n        \n        int foundNode=-1;\n        int expanded=0;\n        \n        // Get baseline cost (move-only) as upper bound\n        auto basePath=bfsMoveOnly(ci,cj,gi,gj,curBs);\n        int upperBound=(int)basePath.size();\n        \n        while(!pq.empty()&&(int)nd.size()<NODE_LIMIT&&expanded<NODE_LIMIT){\n            auto[f,idx]=pq.top();pq.pop();\n            \n            if(nd[idx].g > f - heur(nd[idx].x,nd[idx].y) + 1) {\n                // Check if this node was superseded\n                uint64_t key=sk(nd[idx].x,nd[idx].y,nd[idx].bh);\n                auto it=vis.find(key);\n                if(it!=vis.end()&&it->second<nd[idx].g) continue;\n            }\n            \n            int cx=nd[idx].x, cy=nd[idx].y;\n            uint64_t cbh=nd[idx].bh;\n            int cg=nd[idx].g;\n            \n            if(cx==gi&&cy==gj){foundNode=idx;break;}\n            if(cg>=upperBound) continue; // Can't beat baseline\n            \n            BS7 cbs=nd[idx].bs;\n            expanded++;\n            \n            for(int d=0;d<4;d++){\n                int nx=cx+dx[d],ny=cy+dy[d];\n                \n                // Move\n                if(nx>=0&&nx<N&&ny>=0&&ny<N&&!cbs.get(nx*N+ny)){\n                    int ng=cg+1;\n                    int nf=ng+heur(nx,ny);\n                    if(nf<=upperBound){\n                        uint64_t key=sk(nx,ny,cbh);\n                        auto it=vis.find(key);\n                        if(it==vis.end()||it->second>ng){\n                            vis[key]=ng;\n                            int nid=(int)nd.size();\n                            nd.push_back({nx,ny,cbh,cbs,idx,0,d,ng});\n                            pq.push({nf,nid});\n                        }\n                    }\n                }\n                \n                // Slide\n                auto[sx,sy]=doSlide(cx,cy,d,cbs);\n                if(sx!=cx||sy!=cy){\n                    int ng=cg+1;\n                    int nf=ng+heur(sx,sy);\n                    if(nf<=upperBound){\n                        uint64_t key=sk(sx,sy,cbh);\n                        auto it=vis.find(key);\n                        if(it==vis.end()||it->second>ng){\n                            vis[key]=ng;\n                            int nid=(int)nd.size();\n                            nd.push_back({sx,sy,cbh,cbs,idx,1,d,ng});\n                            pq.push({nf,nid});\n                        }\n                    }\n                }\n                \n                // Alter - only if promising\n                if(nx>=0&&nx<N&&ny>=0&&ny<N){\n                    // Prune: only alter near the target or on lines to target\n                    // Allow alters within a few cells of target or on same row/col\n                    bool promising = false;\n                    if(abs(nx-gi)<=2&&abs(ny-gj)<=2) promising=true;\n                    if(nx==gi||ny==gj) promising=true;\n                    if(cx==gi||cy==gj) promising=true;\n                    // Also allow if removing a block on the path\n                    if(cbs.get(nx*N+ny)) promising=true; // removing blocks is often useful\n                    \n                    if(promising){\n                        uint64_t nh=cbh^zobrist[nx*N+ny];\n                        int ng=cg+1;\n                        // Heuristic doesn't change for position\n                        int nf=ng+heur(cx,cy);\n                        if(nf<=upperBound){\n                            uint64_t key=sk(cx,cy,nh);\n                            auto it=vis.find(key);\n                            if(it==vis.end()||it->second>ng){\n                                vis[key]=ng;\n                                BS7 nbs=cbs;\n                                nbs.flip(nx*N+ny);\n                                int nid=(int)nd.size();\n                                nd.push_back({cx,cy,nh,nbs,idx,2,d,ng});\n                                pq.push({nf,nid});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        vector<pair<int,int>> path;\n        \n        if(foundNode>=0 && nd[foundNode].g < upperBound){\n            int c=foundNode;\n            while(nd[c].parent>=0){\n                path.push_back({nd[c].action,nd[c].dir});\n                c=nd[c].parent;\n            }\n            reverse(path.begin(),path.end());\n            curBs=nd[foundNode].bs;\n            curHash=nd[foundNode].bh;\n            ci=gi;cj=gj;\n        } else {\n            path=basePath;\n            // Execute moves on curBs (no block changes)\n            ci=gi;cj=gj;\n        }\n        \n        for(auto&a:path) allActs.push_back(a);\n    }\n    \n    for(auto&[a,d]:allActs){\n        char ac=(a==0?'M':(a==1?'S':'A'));\n        printf(\"%c %c\\n\",ac,dc[d]);\n    }\n}"}}}