{"model_name":"glm-5","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> X, Y;\nvector<long long> R;\nvector<int> a, b, c, d;\n\nvoid solve(int L, int Rb, int B, int T, vector<int> ids) {\n    if (ids.empty()) return;\n    \n    if (ids.size() == 1) {\n        int i = ids[0];\n        a[i] = L; b[i] = B; c[i] = Rb; d[i] = T;\n        return;\n    }\n    \n    int W = Rb - L, H = T - B;\n    bool vertical = (W >= H);\n    \n    sort(ids.begin(), ids.end(), [&](int i, int j) {\n        return vertical ? X[i] < X[j] : Y[i] < Y[j];\n    });\n    \n    long long total = 0;\n    for (int i : ids) total += R[i];\n    \n    long long acc = 0;\n    size_t splitIdx = ids.size();\n    \n    for (size_t idx = 0; idx + 1 < ids.size(); idx++) {\n        int leftVal = vertical ? X[ids[idx]] : Y[ids[idx]];\n        int rightVal = vertical ? X[ids[idx + 1]] : Y[ids[idx + 1]];\n        \n        if (leftVal < rightVal) {\n            if (splitIdx == ids.size() && acc * 2 >= total) {\n                splitIdx = idx + 1;\n            }\n        }\n        acc += R[ids[idx]];\n    }\n    \n    if (splitIdx == ids.size() || splitIdx == 0) {\n        for (size_t idx = 0; idx + 1 < ids.size(); idx++) {\n            int leftVal = vertical ? X[ids[idx]] : Y[ids[idx]];\n            int rightVal = vertical ? X[ids[idx + 1]] : Y[ids[idx + 1]];\n            if (leftVal < rightVal) {\n                splitIdx = idx + 1;\n                break;\n            }\n        }\n    }\n    if (splitIdx == ids.size() || splitIdx == 0) splitIdx = ids.size() / 2;\n    \n    vector<int> leftIds(ids.begin(), ids.begin() + splitIdx);\n    vector<int> rightIds(ids.begin() + splitIdx, ids.end());\n    \n    int leftMax = vertical ? X[ids[splitIdx - 1]] : Y[ids[splitIdx - 1]];\n    int rightMin = vertical ? X[ids[splitIdx]] : Y[ids[splitIdx]];\n    int split = (leftMax + rightMin + 1) / 2;\n    \n    if (vertical) {\n        split = max(L + 1, min(Rb - 1, split));\n        solve(L, split, B, T, leftIds);\n        solve(split, Rb, B, T, rightIds);\n    } else {\n        split = max(B + 1, min(T - 1, split));\n        solve(L, Rb, B, split, leftIds);\n        solve(L, Rb, split, T, rightIds);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    a.resize(n); b.resize(n); c.resize(n); d.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> X[i] >> Y[i] >> R[i];\n    }\n    \n    vector<int> ids(n);\n    iota(ids.begin(), ids.end(), 0);\n    \n    solve(0, 10000, 0, 10000, ids);\n    \n    for (int i = 0; i < n; i++) {\n        cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<vector<int>> t(50, vector<int>(50)), p(50, vector<int>(50));\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) cin >> t[i][j];\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) cin >> p[i][j];\n    \n    map<int, vector<pair<int,int>>> tileSquares;\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++)\n            tileSquares[t[i][j]].push_back({i, j});\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    set<int> visited;\n    string path;\n    int ci = si, cj = sj;\n    visited.insert(t[ci][cj]);\n    \n    auto& startSquares = tileSquares[t[ci][cj]];\n    if (startSquares.size() == 2) {\n        auto [oi, oj] = (startSquares[0].first == ci && startSquares[0].second == cj) \n            ? make_pair(startSquares[1].first, startSquares[1].second) \n            : make_pair(startSquares[0].first, startSquares[0].second);\n        path += (oi < ci ? 'U' : oi > ci ? 'D' : oj < cj ? 'L' : 'R');\n        ci = oi; cj = oj;\n    }\n    \n    while (true) {\n        int bestDir = -1, bestExitI = -1, bestExitJ = -1;\n        string bestTilePath;\n        double bestValue = -1e18;\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = ci + di[d], nj = cj + dj[d];\n            if (ni < 0 || ni >= 50 || nj < 0 || nj >= 50 || visited.count(t[ni][nj])) continue;\n            \n            int tileId = t[ni][nj];\n            auto& sq = tileSquares[tileId];\n            int tileScore = 0;\n            for (auto& [ti, tj] : sq) tileScore += p[ti][tj];\n            \n            for (size_t ei = 0; ei < sq.size(); ei++) {\n                int exi = sq[ei].first, exj = sq[ei].second;\n                visited.insert(tileId);\n                int future = 0;\n                for (int d2 = 0; d2 < 4; d2++) {\n                    int n2i = exi + di[d2], n2j = exj + dj[d2];\n                    if (n2i >= 0 && n2i < 50 && n2j >= 0 && n2j < 50 && !visited.count(t[n2i][n2j])) future++;\n                }\n                visited.erase(tileId);\n                \n                double value = tileScore + (future == 0 ? -1000.0 : future * 10.0);\n                string tilePath;\n                if (sq.size() == 2) {\n                    int oi = sq[1-ei].first, oj = sq[1-ei].second;\n                    if (ni == exi && nj == exj) {\n                        char to = (oi < exi ? 'U' : oi > exi ? 'D' : oj < exj ? 'L' : 'R');\n                        char back = (to == 'U' ? 'D' : to == 'D' ? 'U' : to == 'L' ? 'R' : 'L');\n                        tilePath = string(1, to) + string(1, back);\n                    } else {\n                        tilePath = string(1, (exi < ni ? 'U' : exi > ni ? 'D' : exj < nj ? 'L' : 'R'));\n                    }\n                }\n                if (value > bestValue) { bestValue = value; bestDir = d; bestExitI = exi; bestExitJ = exj; bestTilePath = tilePath; }\n            }\n        }\n        if (bestDir == -1) break;\n        visited.insert(t[ci + di[bestDir]][cj + dj[bestDir]]);\n        path += dc[bestDir]; path += bestTilePath;\n        ci = bestExitI; cj = bestExitJ;\n    }\n    cout << path << endl;\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 30;\n\ndouble h[N][N-1]; // h[i][j] = edge between (i,j) and (i,j+1)\ndouble v[N-1][N]; // v[i][j] = edge between (i,j) and (i+1,j)\nint cnt_h[N][N-1], cnt_v[N-1][N];\n\nconst char dc[] = {'U', 'D', 'L', 'R'};\n\npair<string, vector<tuple<int,int,int>>> dijkstra(int si, int sj, int ti, int tj, int query_num) {\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<int>> prev_dir(N, vector<int>(N, -1));\n    double explore = max(0.0, 500.0 * (1.0 - query_num / 300.0));\n    \n    priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n    dist[si][sj] = 0;\n    pq.push({0.0, si, sj});\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top(); pq.pop();\n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n        \n        if (i > 0) { double c = v[i-1][j] - (explore > 0 && cnt_v[i-1][j] < 3 ? explore/(cnt_v[i-1][j]+1) : 0);\n            if (dist[i-1][j] > d + c) { dist[i-1][j] = d + c; prev_dir[i-1][j] = 0; pq.push({dist[i-1][j], i-1, j}); }}\n        if (i < N-1) { double c = v[i][j] - (explore > 0 && cnt_v[i][j] < 3 ? explore/(cnt_v[i][j]+1) : 0);\n            if (dist[i+1][j] > d + c) { dist[i+1][j] = d + c; prev_dir[i+1][j] = 1; pq.push({dist[i+1][j], i+1, j}); }}\n        if (j > 0) { double c = h[i][j-1] - (explore > 0 && cnt_h[i][j-1] < 3 ? explore/(cnt_h[i][j-1]+1) : 0);\n            if (dist[i][j-1] > d + c) { dist[i][j-1] = d + c; prev_dir[i][j-1] = 2; pq.push({dist[i][j-1], i, j-1}); }}\n        if (j < N-1) { double c = h[i][j] - (explore > 0 && cnt_h[i][j] < 3 ? explore/(cnt_h[i][j]+1) : 0);\n            if (dist[i][j+1] > d + c) { dist[i][j+1] = d + c; prev_dir[i][j+1] = 3; pq.push({dist[i][j+1], i, j+1}); }}\n    }\n    \n    string path = \"\"; vector<tuple<int,int,int>> edges;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int dir = prev_dir[ci][cj]; path = dc[dir] + path;\n        if (dir == 0) { edges.push_back({1, ci, cj}); ci++; }\n        else if (dir == 1) { edges.push_back({1, ci-1, cj}); ci--; }\n        else if (dir == 2) { edges.push_back({0, ci, cj}); cj++; }\n        else { edges.push_back({0, ci, cj-1}); cj--; }\n    }\n    return {path, edges};\n}\n\nvoid update_estimates(const vector<tuple<int,int,int>>& edges, int observed) {\n    if (edges.empty()) return;\n    double estimated_sum = 0;\n    for (auto [type, i, j] : edges) estimated_sum += (type == 0) ? h[i][j] : v[i][j];\n    double ratio = observed / estimated_sum;\n    for (auto [type, i, j] : edges) {\n        double& val = (type == 0) ? h[i][j] : v[i][j];\n        int& cnt = (type == 0) ? cnt_h[i][j] : cnt_v[i][j];\n        cnt++;\n        double alpha = 0.3 / sqrt((double)cnt);\n        val = val * (1 - alpha) + val * ratio * alpha;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N-1; j++) { h[i][j] = 5000.0; 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.0; cnt_v[i][j] = 0; }\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj; cin >> si >> sj >> ti >> tj;\n        auto [path, edges] = dijkstra(si, sj, ti, tj, k);\n        cout << path << endl; cout.flush();\n        int observed; cin >> observed;\n        update_estimates(edges, observed);\n    }\n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nint M;\nvector<string> s;\nvector<string> grid;\nvector<bitset<800>> cellToStrings;\nvector<bool> matched;\nmt19937 rng(42);\n\nbool matches(int r, int c, int dir, const string& str) {\n    int len = str.size();\n    for (int p = 0; p < len; p++) {\n        int nr = (dir == 0) ? r : (r + p) % N;\n        int nc = (dir == 0) ? (c + p) % N : c;\n        if (grid[nr][nc] != str[p]) return false;\n    }\n    return true;\n}\n\nbool stringMatches(int idx) {\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (matches(r, c, 0, s[idx]) || matches(r, c, 1, s[idx])) return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n >> M;\n    s.resize(M);\n    matched.resize(M);\n    for (int i = 0; i < M; i++) cin >> s[i];\n    \n    // Precompute which strings could include each cell\n    cellToStrings.resize(N * N);\n    for (int i = 0; i < M; i++) {\n        int len = s[i].size();\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                for (int p = 0; p < len; p++) {\n                    cellToStrings[r * N + ((c + p) % N)][i] = 1;\n                    cellToStrings[((r + p) % N) * N + c][i] = 1;\n                }\n            }\n        }\n    }\n    \n    // Voting initialization\n    vector<vector<array<int, 8>>> votes(N, vector<array<int, 8>>(N));\n    for (auto& str : s) {\n        int len = str.size();\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                for (int p = 0; p < len; p++) {\n                    votes[r][(c + p) % N][str[p] - 'A']++;\n                    votes[(r + p) % N][c][str[p] - 'A']++;\n                }\n            }\n        }\n    }\n    \n    grid.assign(N, string(N, '.'));\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            int maxVote = -1;\n            for (int ch = 0; ch < 8; ch++) {\n                if (votes[r][c][ch] > maxVote) {\n                    maxVote = votes[r][c][ch];\n                    grid[r][c] = 'A' + ch;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < M; i++) matched[i] = stringMatches(i);\n    int score = count(matched.begin(), matched.end(), true);\n    vector<string> bestGrid = grid;\n    int bestScore = score;\n    \n    // Simulated annealing with incremental updates\n    double T = 5.0;\n    for (int iter = 0; iter < 100000; iter++) {\n        int r = rng() % N;\n        int c = rng() % N;\n        char old = grid[r][c];\n        char newChar = 'A' + (rng() % 8);\n        if (newChar == old) continue;\n        \n        grid[r][c] = newChar;\n        \n        int delta = 0;\n        bitset<800>& affected = cellToStrings[r * N + c];\n        for (int i = 0; i < M; i++) {\n            if (affected[i]) {\n                bool was = matched[i];\n                bool now = stringMatches(i);\n                if (was && !now) delta--;\n                if (!was && now) delta++;\n                matched[i] = now;\n            }\n        }\n        \n        if (delta > 0 || (delta == 0 && (rng() % 2)) || \n            (delta < 0 && exp(delta / T) > (double)rng() / rng.max())) {\n            score += delta;\n            if (score > bestScore) { bestScore = score; bestGrid = grid; }\n        } else {\n            grid[r][c] = old;\n            for (int i = 0; i < M; i++) {\n                if (affected[i]) matched[i] = stringMatches(i);\n            }\n        }\n        T *= 0.99995;\n    }\n    \n    for (int r = 0; r < N; r++) cout << bestGrid[r] << '\\n';\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> grid;\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dc[] = {'U', 'D', 'L', 'R'};\n\ninline bool isRoad(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\ninline int w(int i, int j) { return grid[i][j] - '0'; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    vector<pair<int,int>> roads;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (isRoad(i, j)) roads.push_back({i, j});\n    \n    int totalRoads = roads.size();\n    \n    vector<vector<vector<pair<int,int>>>> visList(N, vector<vector<pair<int,int>>>(N));\n    for (auto& [i, j] : roads) {\n        visList[i][j].push_back({i, j});\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            while (isRoad(ni, nj)) {\n                visList[i][j].push_back({ni, nj});\n                ni += di[d]; nj += dj[d];\n            }\n        }\n    }\n    \n    vector<vector<bool>> covered(N, vector<bool>(N, false));\n    int numCovered = 0;\n    \n    auto doCover = [&](int i, int j) {\n        if (!isRoad(i, j)) return;\n        for (auto& [ni, nj] : visList[i][j])\n            if (!covered[ni][nj]) { covered[ni][nj] = true; numCovered++; }\n    };\n    \n    auto countNewCover = [&](int i, int j) {\n        int cnt = 0;\n        for (auto& [ni, nj] : visList[i][j])\n            if (!covered[ni][nj]) cnt++;\n        return cnt;\n    };\n    \n    vector<vector<int>> dist(N, vector<int>(N));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N));\n    vector<vector<int>> parentDir(N, vector<int>(N));\n    \n    auto dijkstra = [&](int si, int sj) {\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) { dist[i][j] = INT_MAX; parent[i][j] = {-1, -1}; parentDir[i][j] = -1; }\n        priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n        dist[si][sj] = 0;\n        pq.push({0, si, sj});\n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top(); pq.pop();\n            if (d > dist[i][j]) continue;\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (isRoad(ni, nj)) {\n                    int nd = d + w(ni, nj);\n                    if (nd < dist[ni][nj]) {\n                        dist[ni][nj] = nd; parent[ni][nj] = {i, j}; parentDir[ni][nj] = k;\n                        pq.push({nd, ni, nj});\n                    }\n                }\n            }\n        }\n    };\n    \n    string route;\n    int ci = si, cj = sj;\n    doCover(ci, cj);\n    \n    while (numCovered < totalRoads) {\n        dijkstra(ci, cj);\n        int bestScore = -1, besti = -1, bestj = -1;\n        for (auto& [i, j] : roads) {\n            if (dist[i][j] == INT_MAX) continue;\n            int newC = countNewCover(i, j);\n            if (newC == 0) continue;\n            int score = newC * 10000 / max(1, dist[i][j]);\n            if (score > bestScore) { bestScore = score; besti = i; bestj = j; }\n        }\n        if (besti == -1) break;\n        \n        vector<int> pathDir;\n        int ti = besti, tj = bestj;\n        while (ti != ci || tj != cj) {\n            pathDir.push_back(parentDir[ti][tj]);\n            auto [pi, pj] = parent[ti][tj]; ti = pi; tj = pj;\n        }\n        reverse(pathDir.begin(), pathDir.end());\n        \n        for (int d : pathDir) {\n            route += dc[d]; ci += di[d]; cj += dj[d]; doCover(ci, cj);\n        }\n    }\n    \n    dijkstra(ci, cj);\n    vector<int> pathDir;\n    int ti = si, tj = sj;\n    while (ti != ci || tj != cj) {\n        pathDir.push_back(parentDir[ti][tj]);\n        auto [pi, pj] = parent[ti][tj]; ti = pi; tj = pj;\n    }\n    reverse(pathDir.begin(), pathDir.end());\n    for (int d : pathDir) route += dc[d];\n    \n    cout << route << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <set>\n#include <queue>\n#include <cmath>\n\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> d, deps, reverse_deps;\nvector<vector<double>> s_est;\nvector<int> in_degree, task_start_day, task_status, member_task, critical_len;\nset<int> ready_tasks;\n\nint estimate_time(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++)\n        w += max(0.0, (double)d[task][k] - s_est[member][k]);\n    return max(1, (int)(w + 0.5));\n}\n\nvoid update_skills(int member, int task, int duration) {\n    int w_est = max(0, duration - 2);\n    double cur_w = 0;\n    for (int k = 0; k < K; k++)\n        cur_w += max(0.0, (double)d[task][k] - s_est[member][k]);\n    \n    double error = w_est - cur_w;\n    if (error <= 0) return;\n    \n    int cnt = 0;\n    for (int k = 0; k < K; k++) if (d[task][k] > 0) cnt++;\n    if (cnt == 0) return;\n    \n    double dec = error / cnt;\n    for (int k = 0; k < K; k++)\n        if (d[task][k] > 0)\n            s_est[member][k] = max(0.0, s_est[member][k] - dec);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K >> R;\n    d.resize(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> d[i][k];\n    \n    deps.resize(N); reverse_deps.resize(N); in_degree.assign(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u); reverse_deps[u].push_back(v);\n        in_degree[v]++;\n    }\n    \n    vector<int> order, td = in_degree;\n    queue<int> q;\n    for (int i = 0; i < N; i++) if (td[i] == 0) q.push(i);\n    while (!q.empty()) {\n        int u = q.front(); q.pop(); order.push_back(u);\n        for (int v : reverse_deps[u]) if (--td[v] == 0) q.push(v);\n    }\n    \n    critical_len.assign(N, 0);\n    for (int i = N - 1; i >= 0; i--)\n        for (int v : reverse_deps[order[i]])\n            critical_len[order[i]] = max(critical_len[order[i]], critical_len[v] + 1);\n    \n    s_est.assign(M, vector<double>(K, 15.0));\n    task_status.assign(N, -1); task_start_day.assign(N, -1); member_task.assign(M, -1);\n    for (int i = 0; i < N; i++) if (in_degree[i] == 0) ready_tasks.insert(i);\n    \n    int day = 0;\n    while (true) {\n        day++;\n        vector<pair<int,int>> assignments;\n        set<int> assigned;\n        \n        while (true) {\n            double best_score = 1e18; int best_m = -1, best_t = -1;\n            for (int m = 0; m < M; m++) {\n                if (member_task[m] != -1) continue;\n                for (int t : ready_tasks) {\n                    if (assigned.count(t)) continue;\n                    double score = estimate_time(t, m) - critical_len[t] * 0.25;\n                    if (score < best_score) { best_score = score; best_m = m; best_t = t; }\n                }\n            }\n            if (best_m == -1) break;\n            assignments.push_back({best_m + 1, best_t + 1});\n            member_task[best_m] = best_t;\n            task_status[best_t] = 0;\n            task_start_day[best_t] = day;\n            assigned.insert(best_t);\n        }\n        \n        for (auto& p : assignments) ready_tasks.erase(p.second - 1);\n        \n        cout << assignments.size();\n        for (auto& p : assignments) cout << \" \" << p.first << \" \" << p.second;\n        cout << \"\\n\" << flush;\n        \n        int n; cin >> n;\n        if (n == -1) break;\n        \n        for (int i = 0; i < n; i++) {\n            int f; cin >> f; f--;\n            int task = member_task[f];\n            member_task[f] = -1;\n            int duration = day - task_start_day[task] + 1;\n            task_status[task] = 1;\n            update_skills(f, task, duration);\n            for (int v : reverse_deps[task]) {\n                in_degree[v]--;\n                if (in_degree[v] == 0 && task_status[v] == -1) ready_tasks.insert(v);\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(42);\nconst int DEPOT = 400;\nconst double TIME_LIMIT = 1.85;\n\nint dist(int x1, int y1, int x2, int y2) { return abs(x1-x2) + abs(y1-y2); }\n\nstruct Solver {\n    vector<array<int,4>> orders;\n    vector<int> selected, route, pickup_pos, delivery_pos;\n    chrono::time_point<chrono::steady_clock> start_time;\n    int best_dist;\n    vector<int> best_selected, best_route;\n    \n    void read_input() {\n        orders.resize(1000);\n        for(int i=0;i<1000;i++) cin>>orders[i][0]>>orders[i][1]>>orders[i][2]>>orders[i][3];\n        start_time = chrono::steady_clock::now();\n    }\n    \n    double elapsed() { return chrono::duration<double>(chrono::steady_clock::now()-start_time).count(); }\n    \n    pair<int,int> get_coords(int loc) {\n        if(loc==-1) return {DEPOT,DEPOT};\n        if(loc<50) return {orders[selected[loc]][0], orders[selected[loc]][1]};\n        return {orders[selected[loc-50]][2], orders[selected[loc-50]][3]};\n    }\n    \n    int route_distance() {\n        int d=0;\n        for(int i=0;i+1<(int)route.size();i++) {\n            auto[x1,y1]=get_coords(route[i]); auto[x2,y2]=get_coords(route[i+1]);\n            d+=dist(x1,y1,x2,y2);\n        }\n        return d;\n    }\n    \n    void update_positions() {\n        pickup_pos.assign(50,-1); delivery_pos.assign(50,-1);\n        for(int k=0;k<(int)route.size();k++) {\n            int loc=route[k]; if(loc==-1) continue;\n            if(loc<50) pickup_pos[loc]=k; else delivery_pos[loc-50]=k;\n        }\n    }\n    \n    void save_best() { best_dist=route_distance(); best_selected=selected; best_route=route; }\n    void load_best() { selected=best_selected; route=best_route; update_positions(); }\n    \n    void select_orders_greedy() {\n        vector<pair<int,int>> scored;\n        for(int i=0;i<1000;i++) {\n            int ax=orders[i][0],ay=orders[i][1],bx=orders[i][2],by=orders[i][3];\n            scored.push_back({dist(DEPOT,DEPOT,ax,ay)+dist(ax,ay,bx,by)+dist(bx,by,DEPOT,DEPOT),i});\n        }\n        sort(scored.begin(),scored.end());\n        for(int i=0;i<50;i++) selected.push_back(scored[i].second);\n    }\n    \n    void build_route_nn() {\n        set<int> pending_pickups, pending_deliveries;\n        for(int i=0;i<50;i++) pending_pickups.insert(i);\n        route={-1}; int cx=DEPOT,cy=DEPOT;\n        while(!pending_pickups.empty()||!pending_deliveries.empty()) {\n            int best=-1,best_d=INT_MAX;\n            for(int i:pending_pickups) { auto[x,y]=get_coords(i); int d=dist(cx,cy,x,y); if(d<best_d){best_d=d;best=i;} }\n            for(int i:pending_deliveries) { auto[x,y]=get_coords(i+50); int d=dist(cx,cy,x,y); if(d<best_d){best_d=d;best=i+50;} }\n            route.push_back(best);\n            if(best<50){pending_pickups.erase(best);pending_deliveries.insert(best);}\n            else pending_deliveries.erase(best-50);\n            tie(cx,cy)=get_coords(best);\n        }\n        route.push_back(-1); update_positions();\n    }\n    \n    bool is_valid_2opt(int i,int j) {\n        for(int o=0;o<50;o++) {\n            int p=pickup_pos[o], d=delivery_pos[o];\n            bool pi=(p>=i&&p<=j), di=(d>=i&&d<=j);\n            if((pi&&di)||(pi&&d<i)||(di&&p>j)) return false;\n        }\n        return true;\n    }\n    \n    void local_search_2opt() {\n        int n=route.size(); bool improved=true;\n        while(improved) { improved=false;\n            for(int i=1;i<n-2;i++) for(int j=i+1;j<n-1;j++) {\n                if(!is_valid_2opt(i,j)) continue;\n                auto[xip,yip]=get_coords(route[i-1]); auto[xjn,yjn]=get_coords(route[j+1]);\n                auto[xi,yi]=get_coords(route[i]); auto[xj,yj]=get_coords(route[j]);\n                if(dist(xip,yip,xj,yj)+dist(xi,yi,xjn,yjn) < dist(xip,yip,xi,yi)+dist(xj,yj,xjn,yjn)) {\n                    reverse(route.begin()+i,route.begin()+j+1); update_positions(); improved=true; n=route.size(); break;\n                }\n                if(improved) break;\n            }\n        }\n    }\n    \n    void local_search_relocate() {\n        int n=route.size(); bool improved=true;\n        while(improved) { improved=false;\n            for(int i=1;i<n-1;i++) { int loc=route[i]; if(loc==-1) continue;\n                int ol=(loc<50)?loc:loc-50; bool is_p=loc<50;\n                int op=is_p?delivery_pos[ol]:pickup_pos[ol];\n                int minp=is_p?1:op+1, maxp=is_p?op-1:n-2;\n                for(int np=minp;np<=maxp;np++) { if(np==i||np==i-1) continue;\n                    auto[xp,yp]=get_coords(route[i-1]); auto[xc,yc]=get_coords(route[i]); auto[xn,yn]=get_coords(route[i+1]);\n                    int od=dist(xp,yp,xc,yc)+dist(xc,yc,xn,yn), ndr=dist(xp,yp,xn,yn);\n                    int ip=(np<i)?np+1:np; auto[xi,yi]=get_coords(route[ip-1]); auto[xin,yin]=get_coords(route[ip]);\n                    int odi=dist(xi,yi,xin,yin), ndi=dist(xi,yi,xc,yc)+dist(xc,yc,xin,yin);\n                    if(ndr+ndi<od+odi) {\n                        route.erase(route.begin()+i);\n                        if(np<i) route.insert(route.begin()+np+1,loc); else route.insert(route.begin()+np,loc);\n                        update_positions(); improved=true; n=route.size(); break;\n                    }\n                }\n                if(improved) break;\n            }\n        }\n    }\n    \n    void run_sa() {\n        set<int> sel_set(selected.begin(),selected.end()); save_best();\n        double temp=10000;\n        while(elapsed()<TIME_LIMIT) {\n            int old_dist=route_distance(); auto old_sel=selected, old_rt=route;\n            int out_idx=rng()%50, out_ord=selected[out_idx], in_ord;\n            do{in_ord=rng()%1000;}while(sel_set.count(in_ord));\n            sel_set.erase(out_ord); sel_set.insert(in_ord); selected[out_idx]=in_ord;\n            build_route_nn(); local_search_2opt(); local_search_relocate();\n            int new_dist=route_distance();\n            if(new_dist<old_dist || (double)(rng()%1000000)/1000000.0<exp(-(new_dist-old_dist)/temp)) {\n                if(new_dist<best_dist) save_best();\n            } else { sel_set.erase(in_ord); sel_set.insert(out_ord); selected=old_sel; route=old_rt; update_positions(); }\n            temp*=0.999;\n        }\n        load_best();\n    }\n    \n    void output() {\n        cout<<50; for(int i:selected) cout<<\" \"<<i+1; cout<<\"\\n\";\n        cout<<route.size(); for(int loc:route){auto[x,y]=get_coords(loc);cout<<\" \"<<x<<\" \"<<y;} cout<<\"\\n\";\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    Solver solver; solver.read_input(); solver.select_orders_greedy();\n    solver.build_route_nn(); solver.local_search_2opt(); solver.local_search_relocate(); solver.run_sa();\n    solver.output();\n    return 0;\n}","ahc007":"","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <set>\n#include <tuple>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char WALL[] = {'u', 'd', 'l', 'r'};\nconst char MOVE[] = {'U', 'D', 'L', 'R'};\n\nint N, M;\nvector<tuple<int,int,int>> pets_data;\nvector<pair<int,int>> humans_data;\n\nstruct Solver {\n    vector<vector<bool>> wall;\n    vector<tuple<int,int,int>> pets;\n    vector<pair<int,int>> humans;\n    \n    void init() {\n        wall.assign(SIZE, vector<bool>(SIZE, false));\n        pets = pets_data;\n        humans = humans_data;\n    }\n    \n    bool ok(int x, int y) const { return x >= 0 && x < SIZE && y >= 0 && y < SIZE; }\n    \n    bool petAt(int x, int y) const {\n        for (auto& [px, py, pt] : pets) if (px == x && py == y) return true;\n        return false;\n    }\n    \n    bool humanAt(int x, int y) const {\n        for (auto& [hx, hy] : humans) if (hx == x && hy == y) return true;\n        return false;\n    }\n    \n    bool nearPet(int x, int y) const {\n        for (int d = 0; d < 4; d++) if (petAt(x + dx[d], y + dy[d])) return true;\n        return false;\n    }\n    \n    bool canBuild(int h, int d, const set<pair<int,int>>& pw) const {\n        int x = humans[h].first + dx[d];\n        int y = humans[h].second + dy[d];\n        return ok(x, y) && !wall[x][y] && !petAt(x, y) && !humanAt(x, y) && !nearPet(x, y) && !pw.count({x, y});\n    }\n    \n    bool canMove(int h, int d, const set<pair<int,int>>& pw) const {\n        int x = humans[h].first + dx[d];\n        int y = humans[h].second + dy[d];\n        return ok(x, y) && !wall[x][y] && !pw.count({x, y});\n    }\n    \n    vector<vector<int>> dists(int sx, int sy) const {\n        vector<vector<int>> d(SIZE, vector<int>(SIZE, -1));\n        queue<pair<int,int>> q;\n        q.push({sx, sy});\n        d[sx][sy] = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            for (int i = 0; i < 4; i++) {\n                int nx = x + dx[i], ny = y + dy[i];\n                if (ok(nx, ny) && d[nx][ny] < 0 && !wall[nx][ny]) {\n                    d[nx][ny] = d[x][y] + 1;\n                    q.push({nx, ny});\n                }\n            }\n        }\n        return d;\n    }\n    \n    pair<int, vector<vector<bool>>> reach(int h) const {\n        int sx = humans[h].first, sy = humans[h].second;\n        vector<vector<bool>> vis(SIZE, vector<bool>(SIZE, false));\n        queue<pair<int,int>> q;\n        q.push({sx, sy});\n        vis[sx][sy] = true;\n        int cnt = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            cnt++;\n            for (int i = 0; i < 4; i++) {\n                int nx = x + dx[i], ny = y + dy[i];\n                if (ok(nx, ny) && !vis[nx][ny] && !wall[nx][ny]) {\n                    vis[nx][ny] = true;\n                    q.push({nx, ny});\n                }\n            }\n        }\n        return {cnt, vis};\n    }\n    \n    double calcScore(int h) const {\n        auto [area, vis] = reach(h);\n        int np = 0;\n        for (auto& [px, py, pt] : pets) if (vis[px][py]) np++;\n        return (double)area / (SIZE * SIZE) * pow(0.5, np);\n    }\n    \n    int minPetDist(int h) const {\n        auto d = dists(humans[h].first, humans[h].second);\n        int mnd = SIZE * SIZE;\n        for (auto& [px, py, pt] : pets) if (d[px][py] >= 0) mnd = min(mnd, d[px][py]);\n        return mnd;\n    }\n    \n    char decide(int h, const set<pair<int,int>>& pw, int turn) {\n        double best = -1e9;\n        char bestA = '.';\n        int bestD = -1;\n        int mpd = minPetDist(h);\n        \n        for (int d = 0; d < 4; d++) {\n            if (canBuild(h, d, pw)) {\n                int wx = humans[h].first + dx[d], wy = humans[h].second + dy[d];\n                wall[wx][wy] = true;\n                double s = calcScore(h);\n                wall[wx][wy] = false;\n                s += 0.0002 * mpd;\n                if (s > best) { best = s; bestA = WALL[d]; bestD = d; }\n            }\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            if (canMove(h, d, pw)) {\n                auto old = humans[h];\n                humans[h].first += dx[d]; humans[h].second += dy[d];\n                double s = calcScore(h);\n                int newMpd = minPetDist(h);\n                humans[h] = old;\n                if (newMpd > mpd) s += 0.001;\n                if (s > best) { best = s; bestA = MOVE[d]; bestD = d; }\n            }\n        }\n        return bestA;\n    }\n    \n    void apply(int h, char a, int d) {\n        if (a >= 'a' && a <= 'z') wall[humans[h].first + dx[d]][humans[h].second + dy[d]] = true;\n        else if (a != '.') { humans[h].first += dx[d]; humans[h].second += dy[d]; }\n    }\n    \n    void readPets() {\n        for (int i = 0; i < N; i++) {\n            string m; cin >> m;\n            auto& [px, py, pt] = pets[i];\n            for (char c : m) {\n                if (c == 'U') px--; else if (c == 'D') px++;\n                else if (c == 'L') py--; else if (c == 'R') py++;\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N; pets_data.resize(N);\n    for (int i = 0; i < N; i++) { int x, y, t; cin >> x >> y >> t; pets_data[i] = {x - 1, y - 1, t}; }\n    cin >> M; humans_data.resize(M);\n    for (int i = 0; i < M; i++) { int x, y; cin >> x >> y; humans_data[i] = {x - 1, y - 1}; }\n    \n    Solver sol; sol.init();\n    \n    for (int t = 0; t < 300; t++) {\n        string act(M, '.'); set<pair<int,int>> pw; vector<int> dirs(M, -1);\n        for (int h = 0; h < M; h++) {\n            char a = sol.decide(h, pw, t); act[h] = a;\n            for (int d = 0; d < 4; d++) if (a == WALL[d] || a == MOVE[d]) { dirs[h] = d; break; }\n            if (dirs[h] >= 0 && act[h] >= 'a') pw.insert({sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]});\n        }\n        for (int h = 0; h < M; h++) if (dirs[h] >= 0) sol.apply(h, act[h], dirs[h]);\n        cout << act << endl; cout.flush();\n        sol.readPets();\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj, ti, tj;\ndouble p;\nvector<string> h(20), v(19);\nvector<vector<int>> dist_to_goal;\n\nbool can_move(int i, int j, char d) {\n    if (d == 'U') return i > 0 && v[i-1][j] == '0';\n    if (d == 'D') return i < 19 && v[i][j] == '0';\n    if (d == 'L') return j > 0 && h[i][j-1] == '0';\n    if (d == 'R') return j < 19 && h[i][j] == '0';\n    return false;\n}\n\nvoid compute_dist() {\n    dist_to_goal.assign(20, vector<int>(20, 1000));\n    queue<pair<int,int>> q;\n    q.push({ti, tj});\n    dist_to_goal[ti][tj] = 0;\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (char d : {'U', 'D', 'L', 'R'}) {\n            if (!can_move(i, j, d)) continue;\n            int ni = i + (d == 'D') - (d == 'U');\n            int nj = j + (d == 'R') - (d == 'L');\n            if (dist_to_goal[ni][nj] > dist_to_goal[i][j] + 1) {\n                dist_to_goal[ni][nj] = dist_to_goal[i][j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n}\n\nstring bfs_path() {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<char>> pmove(20, vector<char>(20, ' '));\n    queue<pair<int,int>> q;\n    q.push({si, sj});\n    dist[si][sj] = 0;\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        if (i == ti && j == tj) break;\n        for (char d : {'U', 'D', 'L', 'R'}) {\n            if (!can_move(i, j, d)) continue;\n            int ni = i + (d == 'D') - (d == 'U');\n            int nj = j + (d == 'R') - (d == 'L');\n            if (dist[ni][nj] < 0) {\n                dist[ni][nj] = dist[i][j] + 1;\n                pmove[ni][nj] = d;\n                q.push({ni, nj});\n            }\n        }\n    }\n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        char d = pmove[ci][cj];\n        path = d + path;\n        ci += (d == 'U') - (d == 'D');\n        cj += (d == 'L') - (d == 'R');\n    }\n    return path;\n}\n\ndouble simulate(const string& s) {\n    vector<vector<double>> prob(20, vector<double>(20, 0));\n    prob[si][sj] = 1.0;\n    double total_score = 0, reached = 0;\n    for (int t = 0; t < (int)s.size(); t++) {\n        vector<vector<double>> newp(20, vector<double>(20, 0));\n        char mv = s[t];\n        for (int i = 0; i < 20; i++)\n            for (int j = 0; j < 20; j++)\n                if (prob[i][j] > 1e-15) {\n                    newp[i][j] += p * prob[i][j];\n                    int ni = i, nj = j;\n                    if (can_move(i, j, mv)) {\n                        ni += (mv == 'D') - (mv == 'U');\n                        nj += (mv == 'R') - (mv == 'L');\n                    }\n                    newp[ni][nj] += (1-p) * prob[i][j];\n                }\n        prob = newp;\n        double nr = prob[ti][tj] * (1 - reached);\n        total_score += nr * (401 - (t+1));\n        reached += nr;\n        prob[ti][tj] = 0;\n    }\n    return total_score;\n}\n\nstring greedy_construct() {\n    vector<vector<double>> prob(20, vector<double>(20, 0));\n    prob[si][sj] = 1.0;\n    string result;\n    for (int t = 0; t < 200; t++) {\n        double best = -1e18; char bm = 'U';\n        for (char mv : {'U', 'D', 'L', 'R'}) {\n            double rp = 0, ed = 0;\n            for (int i = 0; i < 20; i++)\n                for (int j = 0; j < 20; j++)\n                    if (prob[i][j] > 1e-15) {\n                        ed += p * prob[i][j] * dist_to_goal[i][j];\n                        int ni = i, nj = j;\n                        if (can_move(i, j, mv)) {\n                            ni += (mv == 'D') - (mv == 'U');\n                            nj += (mv == 'R') - (mv == 'L');\n                        }\n                        if (ni == ti && nj == tj) rp += (1-p) * prob[i][j];\n                        ed += (1-p) * prob[i][j] * dist_to_goal[ni][nj];\n                    }\n            double sc = rp * (401-t) * 10 - ed;\n            if (sc > best) { best = sc; bm = mv; }\n        }\n        result += bm;\n        vector<vector<double>> newp(20, vector<double>(20, 0));\n        for (int i = 0; i < 20; i++)\n            for (int j = 0; j < 20; j++)\n                if (prob[i][j] > 1e-15) {\n                    newp[i][j] += p * prob[i][j];\n                    int ni = i, nj = j;\n                    if (can_move(i, j, bm)) {\n                        ni += (bm == 'D') - (bm == 'U');\n                        nj += (bm == 'R') - (bm == 'L');\n                    }\n                    newp[ni][nj] += (1-p) * prob[i][j];\n                }\n        prob = newp;\n        prob[ti][tj] = 0;\n    }\n    return result;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> si >> sj >> ti >> tj >> p;\n    for (int i = 0; i < 20; i++) cin >> h[i];\n    for (int i = 0; i < 19; i++) cin >> v[i];\n    compute_dist();\n    string path = bfs_path();\n    string best; double bsc = -1;\n    auto try_s = [&](string s) { double sc = simulate(s); if (sc > bsc) { bsc = sc; best = s; } };\n    { string s; while (s.size() + path.size() <= 200) s += path; try_s(s); }\n    for (int r = 1; r <= 6; r++) {\n        string rb;\n        for (char c : path) rb += string(r, c);\n        string s; while (s.size() + rb.size() <= 200) s += rb;\n        try_s(s);\n    }\n    try_s(greedy_construct());\n    cout << best << endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint tiles[N][N], rotations[N][N], best_rotations[N][N];\nint di[] = {0, -1, 0, 1}, dj[] = {-1, 0, 1, 0};\nint to[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}};\nint rot_table[8][4];\n\nvoid init_rot_table() {\n    int rot[8] = {1,2,3,0,5,4,7,6};\n    for (int t = 0; t < 8; t++) {\n        rot_table[t][0] = t;\n        for (int r = 1; r < 4; r++) rot_table[t][r] = rot[rot_table[t][r-1]];\n    }\n}\n\nlong long compute_score() {\n    static bool visited[N][N][4];\n    memset(visited, 0, sizeof(visited));\n    int max1 = 0, max2 = 0;\n    \n    for (int si = 0; si < N; si++) {\n        for (int sj = 0; sj < N; sj++) {\n            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                \n                while (true) {\n                    if (visited[i][j][d]) { len = 0; break; }\n                    visited[i][j][d] = true;\n                    int t = rot_table[tiles[i][j]][rotations[i][j]];\n                    int d2 = to[t][d];\n                    if (d2 == -1) { len = 0; break; }\n                    i += di[d2]; j += dj[d2];\n                    if (i < 0 || i >= N || j < 0 || j >= N) { len = 0; break; }\n                    d = (d2 + 2) % 4; len++;\n                    if (i == si && j == sj && d == sd) break;\n                }\n                \n                if (len > max1) { max2 = max1; max1 = len; }\n                else if (len > max2) max2 = len;\n            }\n        }\n    }\n    return max2 == 0 ? 0 : (long long)max1 * max2;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    init_rot_table();\n    \n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) tiles[i][j] = s[j] - '0';\n    }\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> dist01(0.0, 1.0);\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) rotations[i][j] = rng() % 4;\n    \n    long long cur_score = compute_score(), best_score = cur_score;\n    memcpy(best_rotations, rotations, sizeof(rotations));\n    \n    double temp = 50000.0;\n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(1950);\n    \n    while (chrono::steady_clock::now() < deadline) {\n        int ri = rng() % N, rj = rng() % N;\n        int old_rot = rotations[ri][rj];\n        rotations[ri][rj] = rng() % 4;\n        \n        long long new_score = compute_score();\n        double delta = (double)(new_score - cur_score);\n        \n        if (delta >= 0 || dist01(rng) < exp(delta / temp)) {\n            cur_score = new_score;\n            if (cur_score > best_score) {\n                best_score = cur_score;\n                memcpy(best_rotations, rotations, sizeof(rotations));\n            }\n        } else rotations[ri][rj] = old_rot;\n        \n        temp *= 0.99992;\n    }\n    \n    string result;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) result += char('0' + best_rotations[i][j]);\n    cout << result << endl;\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> board;\nint er, ec;\nstring result;\n\nconst int DR[] = {0, -1, 0, 1};\nconst int DC[] = {-1, 0, 1, 0};\nconst char DCS[] = \"LURD\";\n\nint hval(char c) { return c >= 'a' ? c - 'a' + 10 : c - '0'; }\nbool ib(int r, int c) { return r >= 0 && r < N && c >= 0 && c < N; }\n\nvoid applyMove(int d) {\n    int nr = er + DR[d], nc = ec + DC[d];\n    swap(board[er][ec], board[nr][nc]);\n    er = nr; ec = nc;\n    result += DCS[d];\n}\n\nint countGoodEdges() {\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] == '0') continue;\n            int v = hval(board[i][j]);\n            if ((v & 4) && j + 1 < N && board[i][j+1] != '0') {\n                int nv = hval(board[i][j+1]);\n                if (nv & 1) cnt++;\n            }\n            if ((v & 8) && i + 1 < N && board[i+1][j] != '0') {\n                int nv = hval(board[i+1][j]);\n                if (nv & 2) cnt++;\n            }\n        }\n    }\n    return cnt;\n}\n\nint eval() {\n    vector<int> comp(N*N, -1), compSz(N*N, 0), compEd(N*N, 0);\n    int nc = 0;\n    auto idx = [](int r, int c) { return r * N + c; };\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] != '0' && comp[idx(i,j)] == -1) {\n                queue<pair<int,int>> q;\n                q.push({i,j});\n                comp[idx(i,j)] = nc;\n                while (!q.empty()) {\n                    auto [r,c] = q.front(); q.pop();\n                    compSz[nc]++;\n                    int v = hval(board[r][c]);\n                    auto check = [&](int nr, int nc, int fb, int tb) {\n                        if (ib(nr,nc) && board[nr][nc] != '0') {\n                            int nv = hval(board[nr][nc]);\n                            if ((v & fb) && (nv & tb)) {\n                                compEd[nc]++;\n                                if (comp[idx(nr,nc)] == -1) {\n                                    comp[idx(nr,nc)] = nc;\n                                    q.push({nr,nc});\n                                }\n                            }\n                        }\n                    };\n                    check(r,c-1,1,4); check(r-1,c,2,8);\n                    check(r,c+1,4,1); check(r+1,c,8,2);\n                }\n                nc++;\n            }\n        }\n    }\n    int best = 0;\n    for (int c = 0; c < nc; c++)\n        if (compEd[c]/2 == compSz[c] - 1) best = max(best, compSz[c]);\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> T;\n    board.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n        for (int j = 0; j < N; j++)\n            if (board[i][j] == '0') { er = i; ec = j; }\n    }\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> prob(0, 1);\n    int bestScore = eval(), lastDir = -1;\n    double temp = 5.0;\n    \n    for (int step = 0; step < T && (int)result.size() < T; step++) {\n        vector<int> valid;\n        for (int d = 0; d < 4; d++)\n            if (ib(er + DR[d], ec + DC[d])) valid.push_back(d);\n        if (valid.empty()) break;\n        \n        int bestD = -1, bestEdgeDelta = -100;\n        for (int d : valid) {\n            int nr = er + DR[d], nc = ec + DC[d];\n            swap(board[er][ec], board[nr][nc]);\n            int delta = countGoodEdges();\n            swap(board[er][ec], board[nr][nc]);\n            if (delta > bestEdgeDelta || (delta == bestEdgeDelta && prob(rng) < 0.3)) {\n                bestEdgeDelta = delta;\n                bestD = d;\n            }\n        }\n        \n        applyMove(bestD);\n        int score = (step % 10 == 0) ? eval() : bestScore;\n        if (step % 10 == 0) score = eval();\n        if (score > bestScore) bestScore = score;\n        temp *= 0.999;\n        if (bestScore == N*N - 1) break;\n    }\n    \n    cout << result << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\ntypedef pair<ll, ll> PLL;\n\nll cross(PLL a, PLL b) {\n    return a.first * b.second - a.second * b.first;\n}\n\nint side(PLL p1, PLL p2, PLL q) {\n    PLL d = {p2.first - p1.first, p2.second - p1.second};\n    PLL e = {q.first - p1.first, q.second - p1.second};\n    ll c = cross(d, e);\n    if (c > 0) return 1;\n    if (c < 0) return -1;\n    return 0;\n}\n\nint N, K;\nint a[11];\nvector<PLL> S;\n\nint computeScore(const vector<pair<PLL, PLL>>& lines) {\n    map<vector<int>, int> cells;\n    for (const auto& s : S) {\n        vector<int> sides;\n        bool isCut = false;\n        for (const auto& [p1, p2] : lines) {\n            int sd = side(p1, p2, s);\n            if (sd == 0) { isCut = true; break; }\n            sides.push_back(sd);\n        }\n        if (!isCut) cells[sides]++;\n    }\n    int b[11] = {0};\n    for (const auto& [k, v] : cells) if (v >= 1 && v <= 10) b[v]++;\n    int score = 0;\n    for (int d = 1; d <= 10; d++) score += min(a[d], b[d]);\n    return score;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    S.resize(N);\n    for (int i = 0; i < N; i++) cin >> S[i].first >> S[i].second;\n    \n    mt19937_64 rng(12345);\n    uniform_int_distribution<ll> bigCoord(-1000000000, 1000000000);\n    \n    vector<pair<PLL, PLL>> bestCuts;\n    int bestScore = 0;\n    auto startTime = chrono::steady_clock::now();\n    auto timeout = chrono::milliseconds(2900);\n    \n    while (chrono::steady_clock::now() - startTime < timeout) {\n        vector<pair<PLL, PLL>> cuts;\n        int currentScore = computeScore(cuts);\n        \n        for (int cutNum = 0; cutNum < K; cutNum++) {\n            pair<PLL, PLL> bestCut = {{0, 0}, {1, 0}};\n            int bestNewScore = currentScore; bool found = false;\n            \n            for (int iter = 0; iter < 300; iter++) {\n                PLL p1, p2; int strat = rng() % 5;\n                if (strat <= 2 && N >= 2) {\n                    int i = rng() % N, j = rng() % N;\n                    if (i != j) {\n                        ll mx = S[i].first + S[j].first, my = S[i].second + S[j].second;\n                        ll dx = S[j].first - S[i].first, dy = S[j].second - S[i].second;\n                        p1 = {mx + dy, my - dx}; p2 = {mx - dy, my + dx};\n                    } else continue;\n                } else if (strat == 3 && N >= 1) {\n                    int i = rng() % N; ll dx = bigCoord(rng), dy = bigCoord(rng);\n                    if (dx == 0 && dy == 0) continue;\n                    p1 = {S[i].first - dx, S[i].second - dy};\n                    p2 = {S[i].first + dx, S[i].second + dy};\n                } else { p1 = {bigCoord(rng), bigCoord(rng)}; p2 = {bigCoord(rng), bigCoord(rng)}; }\n                if (p1 == p2) continue;\n                auto newCuts = cuts; newCuts.emplace_back(p1, p2);\n                int score = computeScore(newCuts);\n                if (score > bestNewScore) { bestNewScore = score; bestCut = {p1, p2}; found = true; }\n            }\n            if (found) { cuts.push_back(bestCut); currentScore = bestNewScore; }\n        }\n        \n        for (int ls = 0; ls < 10000; ls++) {\n            if (cuts.empty()) break;\n            int idx = rng() % cuts.size(); auto oldCut = cuts[idx];\n            PLL p1, p2; int strat = rng() % 5;\n            if (strat <= 2 && N >= 2) {\n                int i = rng() % N, j = rng() % N;\n                if (i != j) {\n                    ll mx = S[i].first + S[j].first, my = S[i].second + S[j].second;\n                    ll dx = S[j].first - S[i].first, dy = S[j].second - S[i].second;\n                    p1 = {mx + dy, my - dx}; p2 = {mx - dy, my + dx};\n                } else continue;\n            } else if (strat == 3 && N >= 1) {\n                int i = rng() % N; ll dx = bigCoord(rng), dy = bigCoord(rng);\n                if (dx == 0 && dy == 0) continue;\n                p1 = {S[i].first - dx, S[i].second - dy}; p2 = {S[i].first + dx, S[i].second + dy};\n            } else { p1 = {bigCoord(rng), bigCoord(rng)}; p2 = {bigCoord(rng), bigCoord(rng)}; }\n            if (p1 == p2) continue;\n            cuts[idx] = {p1, p2}; int score = computeScore(cuts);\n            if (score >= currentScore) currentScore = score;\n            else cuts[idx] = oldCut;\n        }\n        if (currentScore > bestScore) { bestScore = currentScore; bestCuts = cuts; }\n    }\n    \n    cout << bestCuts.size() << \"\\n\";\n    for (const auto& [p1, p2] : bestCuts)\n        cout << p1.first << \" \" << p1.second << \" \" << p2.first << \" \" << p2.second << \"\\n\";\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble C;\nvector<vector<bool>> dot;\nset<tuple<int,int,int,int>> used_edges;\nvector<array<int,8>> ops;\nchrono::steady_clock::time_point T0;\n\ndouble elapsed() { return chrono::duration<double>(chrono::steady_clock::now() - T0).count(); }\nint wt(int x, int y) { return (x-C)*(x-C) + (y-C)*(y-C) + 1; }\nbool inB(int x, int y) { return x >= 0 && x < N && y >= 0 && y < N; }\n\nauto normE(int x1, int y1, int x2, int y2) {\n    if (make_pair(x1,y1) > make_pair(x2,y2)) swap(x1,y1), swap(x2,y2);\n    return make_tuple(x1,y1,x2,y2);\n}\n\nbool segClear(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    dx /= g; dy /= g;\n    for (int x = x1+dx, y = y1+dy; x != x2 || y != y2; x += dx, y += dy)\n        if (dot[x][y]) return false;\n    return true;\n}\n\nbool tryRect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    vector<pair<int,int>> P = {{x1,y1},{x2,y2},{x3,y3},{x4,y4}};\n    vector<int> ord = {0,1,2,3};\n    do {\n        int px[4], py[4];\n        for (int i = 0; i < 4; i++) tie(px[i], py[i]) = P[ord[i]];\n        if (dot[px[0]][py[0]]) continue;\n        if (!dot[px[1]][py[1]] || !dot[px[2]][py[2]] || !dot[px[3]][py[3]]) continue;\n        bool ok = true; vector<tuple<int,int,int,int>> E;\n        for (int i = 0; i < 4 && ok; i++) {\n            int dx = px[(i+1)%4] - px[i], dy = py[(i+1)%4] - py[i];\n            if (dx == 0 && dy == 0) ok = false;\n            else if (!(dx == 0 || dy == 0) && abs(dx) != abs(dy)) ok = false;\n            if (ok) E.push_back(normE(px[i], py[i], px[(i+1)%4], py[(i+1)%4]));\n        }\n        if (!ok) continue;\n        for (int i = 0; i < 4 && ok; i++) {\n            int dx1 = px[(i+1)%4] - px[i], dy1 = py[(i+1)%4] - py[i];\n            int dx2 = px[(i+2)%4] - px[(i+1)%4], dy2 = py[(i+2)%4] - py[(i+1)%4];\n            if (dx1*dx2 + dy1*dy2 != 0) ok = false;\n        }\n        if (!ok) continue;\n        for (int i = 0; i < 4 && ok; i++)\n            if (!segClear(px[i], py[i], px[(i+1)%4], py[(i+1)%4])) ok = false;\n        if (!ok) continue;\n        for (auto& e : E) if (used_edges.count(e)) { ok = false; break; }\n        if (!ok) continue;\n        dot[px[0]][py[0]] = true;\n        for (auto& e : E) used_edges.insert(e);\n        ops.push_back({px[0], py[0], px[1], py[1], px[2], py[2], px[3], py[3]});\n        return true;\n    } while (next_permutation(ord.begin(), ord.end()));\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    T0 = chrono::steady_clock::now();\n    cin >> N >> M; C = (N - 1) / 2.0;\n    dot.assign(N, vector<bool>(N, false));\n    for (int i = 0; i < M; i++) { int x, y; cin >> x >> y; dot[x][y] = true; }\n    vector<vector<int>> R(N), Cc(N), Dp(2*N), Dm(2*N);\n    for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (dot[x][y]) {\n        R[y].push_back(x); Cc[x].push_back(y);\n        Dp[x+y].push_back(x); Dm[x-y+N-1].push_back(x);\n    }\n    while (elapsed() < 4.5) {\n        vector<pair<int,int>> E;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (!dot[x][y]) E.push_back({x,y});\n        sort(E.begin(), E.end(), [](auto& a, auto& b) { return wt(a.first,a.second) > wt(b.first,b.second); });\n        bool found = false;\n        for (auto& [nx, ny] : E) {\n            for (int x2 : R[ny]) { if (x2 == nx) continue;\n                for (int y3 : Cc[nx]) { if (y3 == ny) continue;\n                    if (dot[x2][y3] && tryRect(nx, ny, x2, ny, x2, y3, nx, y3)) {\n                        R[ny].push_back(nx); Cc[nx].push_back(ny);\n                        Dp[nx+ny].push_back(nx); Dm[nx-ny+N-1].push_back(nx);\n                        found = true; goto next;\n                    }\n                }\n            }\n            int ds = nx + ny, dm = nx - ny + N - 1;\n            for (int x2 : Dm[dm]) { int y2 = x2 - (nx - ny); if (x2 == nx) continue;\n                for (int x4 : Dp[ds]) { int y4 = ds - x4; if (x4 == nx) continue;\n                    int x3 = x2 + x4 - nx, y3 = y2 + y4 - ny;\n                    if (inB(x3, y3) && dot[x3][y3] && tryRect(nx, ny, x2, y2, x3, y3, x4, y4)) {\n                        R[ny].push_back(nx); Cc[nx].push_back(ny);\n                        Dp[nx+ny].push_back(nx); Dm[nx-ny+N-1].push_back(nx);\n                        found = true; goto next;\n                    }\n                }\n            }\n        }\n        next:; if (!found) break;\n    }\n    cout << ops.size() << \"\\n\";\n    for (auto& o : ops) { for (int i = 0; i < 8; i++) cout << o[i] << \" \\n\"[i == 7]; }\n    return 0;\n}","ahc015":"#include <iostream>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nint flavors[100];\n\nvoid tilt(int g[N][N], int dir) {\n    int ng[N][N] = {};\n    if (dir == 0) { // F (up)\n        for (int c = 0; c < N; c++) {\n            int wr = 0;\n            for (int r = 0; r < N; r++)\n                if (g[r][c]) ng[wr++][c] = g[r][c];\n        }\n    } else if (dir == 1) { // B (down)\n        for (int c = 0; c < N; c++) {\n            int wr = N-1;\n            for (int r = N-1; r >= 0; r--)\n                if (g[r][c]) ng[wr--][c] = g[r][c];\n        }\n    } else if (dir == 2) { // L (left)\n        for (int r = 0; r < N; r++) {\n            int wc = 0;\n            for (int c = 0; c < N; c++)\n                if (g[r][c]) ng[r][wc++] = g[r][c];\n        }\n    } else { // R (right)\n        for (int r = 0; r < N; r++) {\n            int wc = N-1;\n            for (int c = N-1; c >= 0; c--)\n                if (g[r][c]) ng[r][wc--] = g[r][c];\n        }\n    }\n    memcpy(g, ng, sizeof(ng));\n}\n\nlong long calcScore(int g[N][N]) {\n    int vis[N][N] = {};\n    long long score = 0;\n    const int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n    \n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (!g[r][c] || vis[r][c]) continue;\n            int f = g[r][c], sz = 0;\n            int qr[100], qc[100], qh = 0, qt = 0;\n            qr[qt] = r; qc[qt++] = c; vis[r][c] = 1;\n            while (qh < qt) {\n                int cr = qr[qh], cc = qc[qh++];\n                sz++;\n                for (int d = 0; d < 4; d++) {\n                    int nr = cr + dr[d], nc = cc + dc[d];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && !vis[nr][nc] && g[nr][nc] == f) {\n                        vis[nr][nc] = 1; qr[qt] = nr; qc[qt++] = nc;\n                    }\n                }\n            }\n            score += (long long)sz * sz;\n        }\n    }\n    return score;\n}\n\nint main() {\n    for (int i = 0; i < 100; i++) cin >> flavors[i];\n    \n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        int cnt = 0;\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (!grid[r][c] && ++cnt == p) { grid[r][c] = flavors[t]; r = N; break; }\n            }\n        }\n        \n        long long best = -1; int bestDir = 0;\n        int temp[N][N];\n        for (int d = 0; d < 4; d++) {\n            memcpy(temp, grid, sizeof(grid));\n            tilt(temp, d);\n            long long score = calcScore(temp);\n            if (score > best) { best = score; bestDir = d; }\n        }\n        \n        tilt(grid, bestDir);\n        cout << \"FBLR\"[bestDir] << endl;\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint M; double eps; int N, total_edges;\nvector<vector<bool>> G;\nvector<vector<int>> deg_seqs;\nvector<int> edge_counts;\nvector<long long> tri_counts;\n\nint idx(int i, int j) {\n    if (i > j) swap(i, j);\n    return i * (2*N - i - 1) / 2 + (j - i - 1);\n}\n\nlong long count_triangles(const vector<bool>& g) {\n    long long cnt = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = i+1; j < N; j++)\n            if (g[idx(i,j)])\n                for (int k = j+1; k < N; k++)\n                    if (g[idx(i,k)] && g[idx(j,k)]) cnt++;\n    return cnt;\n}\n\nvoid compute_features(int k) {\n    edge_counts[k] = count(G[k].begin(), G[k].end(), true);\n    vector<int> deg(N, 0);\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (i != j && G[k][idx(i, j)]) deg[i]++;\n    sort(deg.begin(), deg.end());\n    deg_seqs[k] = deg;\n    tri_counts[k] = count_triangles(G[k]);\n}\n\nvoid generate_graphs() {\n    total_edges = N * (N - 1) / 2;\n    G.assign(M, vector<bool>(total_edges, false));\n    deg_seqs.resize(M); edge_counts.resize(M); tri_counts.resize(M);\n    for (int k = 0; k < M; k++) {\n        double frac = (M > 1) ? (double)k / (M - 1) : 0.5;\n        int target = (int)round(frac * total_edges), cnt = 0;\n        for (int i = 0; i < N && cnt < target; i++)\n            for (int j = i + 1; j < N && cnt < target; j++)\n                G[k][idx(i, j)] = true, cnt++;\n        compute_features(k);\n    }\n}\n\nint match(const string& H) {\n    vector<bool> h(total_edges);\n    for (int i = 0; i < total_edges; i++) h[i] = (H[i] == '1');\n    int h_edges = count(h.begin(), h.end(), true);\n    vector<int> h_deg(N, 0);\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (i != j && h[idx(i, j)]) h_deg[i]++;\n    sort(h_deg.begin(), h_deg.end());\n    long long h_tri = count_triangles(h);\n    long long total_tri = (long long)N * (N-1) * (N-2) / 6;\n    \n    int best = 0; double best_dist = 1e18;\n    double scale = max(0.01, 1 - 2*eps), shift = eps * (N - 1);\n    double tri_factor = pow(1-eps, 3) - pow(eps, 3);\n    double edge_sd = sqrt(max(1e-10, eps * (1-eps) * total_edges));\n    double tri_sd = sqrt(max(1e-10, (double)total_tri * eps * (1-eps)));\n    \n    for (int k = 0; k < M; k++) {\n        double exp_edges = edge_counts[k] * scale + eps * total_edges;\n        double edge_dist = abs(h_edges - exp_edges) / edge_sd;\n        double deg_dist = 0;\n        for (int i = 0; i < N; i++)\n            deg_dist += abs(h_deg[i] - (deg_seqs[k][i] * scale + shift));\n        deg_dist /= N;\n        double exp_tri = tri_counts[k] * tri_factor + total_tri * pow(eps, 3);\n        double tri_dist = abs(h_tri - exp_tri) / max(1.0, tri_sd);\n        double dist = edge_dist + deg_dist * 2 + tri_dist * 0.3;\n        if (dist < best_dist) { best_dist = dist; best = k; }\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> M >> eps;\n    N = max(4, min(100, (int)ceil(sqrt(2.0 * M)) + 5));\n    if (eps > 0.15) N = min(100, N + 5);\n    if (eps > 0.25) N = min(100, N + 5);\n    if (eps > 0.35) N = min(100, N + 5);\n    generate_graphs();\n    cout << N << \"\\n\";\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < total_edges; i++) cout << (G[k][i] ? '1' : '0');\n        cout << \"\\n\";\n    }\n    cout << flush;\n    for (int q = 0; q < 100; q++) {\n        string H; cin >> H;\n        cout << match(H) << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\ntypedef pair<ll, int> pli;\n\nconst ll INF = 1e18;\n\nint N, M, D, K;\nvector<int> eu, ev;\nvector<ll> ew;\nvector<vector<pair<int, int>>> adj;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto start_time = chrono::steady_clock::now();\n    \n    cin >> N >> M >> D >> K;\n    \n    eu.resize(M); ev.resize(M); ew.resize(M);\n    adj.resize(N);\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    \n    for (int i = 0; i < N; i++) { int x, y; cin >> x >> y; }\n    \n    // Compute edge betweenness\n    vector<ll> edge_imp(M, 0);\n    \n    for (int s = 0; s < N; s++) {\n        vector<ll> dist(N, INF);\n        vector<int> pred(N, -1);\n        dist[s] = 0;\n        priority_queue<pli, vector<pli>, greater<pli>> pq;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            \n            for (auto& [v, eid] : adj[u]) {\n                ll nd = d + ew[eid];\n                if (dist[v] > nd) {\n                    dist[v] = nd;\n                    pred[v] = u;\n                    pq.push({nd, v});\n                }\n            }\n        }\n        \n        for (int t = 0; t < N; t++) {\n            if (t == s || pred[t] == -1) continue;\n            int p = pred[t];\n            for (auto& [v, eid] : adj[p]) {\n                if (v == t) { edge_imp[eid]++; break; }\n            }\n        }\n    }\n    \n    // Sort by importance (descending)\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) { return edge_imp[a] > edge_imp[b]; });\n    \n    // Greedy assignment - spread high importance edges across days\n    vector<int> assign(M, -1);\n    vector<int> cnt(D, 0);\n    vector<ll> day_imp(D, 0);\n    \n    for (int eid : order) {\n        int best = 0;\n        for (int d = 1; d < D; d++) {\n            if (cnt[d] < K && (cnt[best] >= K || day_imp[d] < day_imp[best])) {\n                best = d;\n            }\n        }\n        assign[eid] = best;\n        cnt[best]++;\n        day_imp[best] += edge_imp[eid];\n    }\n    \n    // Local search to balance day importance\n    mt19937 rng(42);\n    uniform_int_distribution<int> dist_m(0, M - 1);\n    uniform_int_distribution<int> dist_d(0, D - 1);\n    \n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 5500) {\n        int e = dist_m(rng);\n        int d_old = assign[e];\n        int d_new = dist_d(rng);\n        \n        if (d_new == d_old || cnt[d_new] >= K) continue;\n        \n        ll old_var = 0, new_var = 0;\n        for (int d = 0; d < D; d++) {\n            old_var += day_imp[d] * day_imp[d];\n            ll nv = day_imp[d];\n            if (d == d_old) nv -= edge_imp[e];\n            if (d == d_new) nv += edge_imp[e];\n            new_var += nv * nv;\n        }\n        \n        if (new_var < old_var || rng() % 100 < 5) {\n            day_imp[d_old] -= edge_imp[e];\n            day_imp[d_new] += edge_imp[e];\n            cnt[d_old]--; cnt[d_new]++;\n            assign[e] = d_new;\n        }\n    }\n    \n    for (int i = 0; i < M; i++) {\n        cout << assign[i] + 1 << (i == M - 1 ? '\\n' : ' ');\n    }\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f[2], r[2];\nint valid[2][15][15][15];\nint visited[15][15][15];\nint b[2][15][15][15];\nint blockId;\n\nint dx[] = {1, -1, 0, 0, 0, 0};\nint dy[] = {0, 0, 1, -1, 0, 0};\nint dz[] = {0, 0, 0, 0, 1, -1};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> D;\n    for (int i = 0; i < 2; i++) {\n        f[i].resize(D);\n        r[i].resize(D);\n        for (int z = 0; z < D; z++) cin >> f[i][z];\n        for (int z = 0; z < D; z++) cin >> r[i][z];\n    }\n    \n    for (int i = 0; i < 2; i++) {\n        for (int x = 0; x < D; x++)\n            for (int y = 0; y < D; y++)\n                for (int z = 0; z < D; z++)\n                    valid[i][x][y][z] = (f[i][z][x] == '1' && r[i][z][y] == '1') ? 1 : 0;\n    }\n    \n    memset(b, 0, sizeof(b));\n    blockId = 0;\n    \n    // Process intersection (shared blocks)\n    memset(visited, 0, sizeof(visited));\n    for (int x = 0; x < D; x++)\n        for (int y = 0; y < D; y++)\n            for (int z = 0; z < D; z++)\n                if (valid[0][x][y][z] && valid[1][x][y][z] && !visited[x][y][z]) {\n                    blockId++;\n                    queue<array<int,3>> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = 1;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        b[0][cx][cy][cz] = blockId;\n                        b[1][cx][cy][cz] = blockId;\n                        for (int d = 0; d < 6; d++) {\n                            int nx = cx+dx[d], ny = cy+dy[d], nz = cz+dz[d];\n                            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D \n                                && !visited[nx][ny][nz] && valid[0][nx][ny][nz] && valid[1][nx][ny][nz]) {\n                                visited[nx][ny][nz] = 1;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                }\n    \n    // Process V_1 \\ I\n    memset(visited, 0, sizeof(visited));\n    for (int x = 0; x < D; x++)\n        for (int y = 0; y < D; y++)\n            for (int z = 0; z < D; z++)\n                if (valid[0][x][y][z] && !valid[1][x][y][z] && !visited[x][y][z]) {\n                    blockId++;\n                    queue<array<int,3>> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = 1;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        b[0][cx][cy][cz] = blockId;\n                        for (int d = 0; d < 6; d++) {\n                            int nx = cx+dx[d], ny = cy+dy[d], nz = cz+dz[d];\n                            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D \n                                && !visited[nx][ny][nz] && valid[0][nx][ny][nz] && !valid[1][nx][ny][nz]) {\n                                visited[nx][ny][nz] = 1;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                }\n    \n    // Process V_2 \\ I\n    memset(visited, 0, sizeof(visited));\n    for (int x = 0; x < D; x++)\n        for (int y = 0; y < D; y++)\n            for (int z = 0; z < D; z++)\n                if (!valid[0][x][y][z] && valid[1][x][y][z] && !visited[x][y][z]) {\n                    blockId++;\n                    queue<array<int,3>> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = 1;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        b[1][cx][cy][cz] = blockId;\n                        for (int d = 0; d < 6; d++) {\n                            int nx = cx+dx[d], ny = cy+dy[d], nz = cz+dz[d];\n                            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D \n                                && !visited[nx][ny][nz] && !valid[0][nx][ny][nz] && valid[1][nx][ny][nz]) {\n                                visited[nx][ny][nz] = 1;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                }\n    \n    cout << blockId << \"\\n\";\n    for (int x = 0; x < D; x++)\n        for (int y = 0; y < D; y++)\n            for (int z = 0; z < D; z++)\n                cout << (x||y||z ? \" \" : \"\") << b[0][x][y][z];\n    cout << \"\\n\";\n    for (int x = 0; x < D; x++)\n        for (int y = 0; y < D; y++)\n            for (int z = 0; z < D; z++)\n                cout << (x||y||z ? \" \" : \"\") << b[1][x][y][z];\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\ntypedef pair<ll, int> pli;\n\nint N, M, K;\nvector<int> x, y;\nvector<tuple<int, int, ll>> edges;\nvector<int> a, b;\nvector<vector<pair<int, int>>> adj;\n\nint calcDist(int x1, int y1, int x2, int y2) {\n    return (int)round(sqrt((ll)(x1-x2)*(x1-x2) + (ll)(y1-y2)*(y1-y2)));\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K;\n    x.resize(N); y.resize(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    edges.resize(M); adj.resize(N);\n    for (int j = 0; j < M; j++) {\n        int uj, vj; ll wj;\n        cin >> uj >> vj >> wj;\n        uj--; vj--;\n        edges[j] = {uj, vj, wj};\n        adj[uj].push_back({vj, j});\n        adj[vj].push_back({uj, j});\n    }\n    \n    a.resize(K); b.resize(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    // Dijkstra from vertex 0\n    vector<ll> distTo0(N, LLONG_MAX);\n    vector<int> parent(N, -1), parent_edge(N, -1);\n    priority_queue<pli, vector<pli>, greater<pli>> pq;\n    distTo0[0] = 0; pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > distTo0[u]) continue;\n        for (auto [v, ej] : adj[u]) {\n            ll wj = get<2>(edges[ej]);\n            if (distTo0[u] + wj < distTo0[v]) {\n                distTo0[v] = distTo0[u] + wj;\n                parent[v] = u; parent_edge[v] = ej;\n                pq.push({distTo0[v], v});\n            }\n        }\n    }\n    \n    // Assign each resident to nearest station\n    vector<int> station_power(N, 0);\n    for (int k = 0; k < K; k++) {\n        int best = -1, bestd = INT_MAX;\n        for (int i = 0; i < N; i++) {\n            int d = calcDist(a[k], b[k], x[i], y[i]);\n            if (d < bestd) { bestd = d; best = i; }\n        }\n        if (best != -1) station_power[best] = max(station_power[best], bestd);\n    }\n    \n    // Collect active stations\n    vector<int> active_stations;\n    for (int i = 0; i < N; i++) if (station_power[i] > 0) active_stations.push_back(i);\n    \n    // Connect active stations to vertex 0\n    vector<int> B(M, 0);\n    for (int i : active_stations) {\n        int cur = i;\n        while (parent[cur] != -1) { B[parent_edge[cur]] = 1; cur = parent[cur]; }\n    }\n    \n    // Remove redundant edges (highest weight first)\n    vector<int> edge_order(M);\n    iota(edge_order.begin(), edge_order.end(), 0);\n    sort(edge_order.begin(), edge_order.end(), [&](int j1, int j2) {\n        return get<2>(edges[j1]) > get<2>(edges[j2]);\n    });\n    \n    for (int j : edge_order) {\n        if (B[j] == 0) continue;\n        B[j] = 0;\n        \n        vector<vector<int>> g(N);\n        for (int jj = 0; jj < M; jj++) if (B[jj]) {\n            auto [u, v, w] = edges[jj];\n            g[u].push_back(v); g[v].push_back(u);\n        }\n        \n        vector<bool> visited(N, false);\n        queue<int> q; q.push(0); visited[0] = true;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v : g[u]) if (!visited[v]) { visited[v] = true; q.push(v); }\n        }\n        \n        for (int i : active_stations) if (!visited[i]) { B[j] = 1; break; }\n    }\n    \n    for (int i = 0; i < N; i++) cout << station_power[i] << (i < N-1 ? \" \" : \"\\n\");\n    for (int j = 0; j < M; j++) cout << B[j] << (j < M-1 ? \" \" : \"\\n\");\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2;\n\nint pyramid[N][N];\nint pos[TOTAL];\nint dist[TOTAL], parent[TOTAL];\n\nint idx(int x, int y) { return x * (x + 1) / 2 + y; }\n\npair<int,int> coord(int i) {\n    int x = (int)(sqrt(2.0 * i + 0.25) - 0.5);\n    while (idx(x + 1, 0) <= i) x++;\n    return {x, i - idx(x, 0)};\n}\n\nvoid bfs(int s) {\n    fill(dist, dist + TOTAL, -1);\n    fill(parent, parent + TOTAL, -1);\n    queue<int> q;\n    q.push(s);\n    dist[s] = 0;\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        auto [x, y] = coord(u);\n        vector<pair<int,int>> neighbors;\n        if (x > 0 && y > 0) neighbors.push_back({x-1, y-1});\n        if (x > 0 && y < x) neighbors.push_back({x-1, y});\n        if (y > 0) neighbors.push_back({x, y-1});\n        if (y < x) neighbors.push_back({x, y+1});\n        if (x < N-1) neighbors.push_back({x+1, y});\n        if (x < N-1) neighbors.push_back({x+1, y+1});\n        for (auto [nx, ny] : neighbors) {\n            int v = idx(nx, ny);\n            if (dist[v] == -1) {\n                dist[v] = dist[u] + 1;\n                parent[v] = u;\n                q.push(v);\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n            pos[pyramid[x][y]] = idx(x, y);\n        }\n    }\n    \n    vector<array<int,4>> moves;\n    \n    for (int v = 0; v < TOTAL && (int)moves.size() < 10000; v++) {\n        int cur = pos[v];\n        if (cur == v) continue;\n        \n        bfs(cur);\n        \n        vector<int> path;\n        for (int u = v; u != -1; u = parent[u]) path.push_back(u);\n        reverse(path.begin(), path.end());\n        \n        for (size_t i = 0; i+1 < path.size() && (int)moves.size() < 10000; i++) {\n            auto [x1, y1] = coord(path[i]);\n            auto [x2, y2] = coord(path[i+1]);\n            int v1 = pyramid[x1][y1], v2 = pyramid[x2][y2];\n            pos[v1] = path[i+1];\n            pos[v2] = path[i];\n            swap(pyramid[x1][y1], pyramid[x2][y2]);\n            moves.push_back({x1, y1, x2, y2});\n        }\n    }\n    \n    cout << moves.size() << \"\\n\";\n    for (auto& m : moves) {\n        cout << m[0] << \" \" << m[1] << \" \" << m[2] << \" \" << m[3] << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D, N;\n    cin >> D >> N;\n    \n    set<pair<int,int>> obstacles;\n    for (int i = 0; i < N; i++) {\n        int ri, rj; cin >> ri >> rj;\n        obstacles.insert({ri, rj});\n    }\n    \n    int entrance_j = (D - 1) / 2;\n    int M = D * D - 1 - N;\n    \n    vector<pair<int,int>> cells;\n    map<pair<int,int>, int> cell_to_idx;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (!(i == 0 && j == entrance_j) && !obstacles.count({i, j})) {\n                cell_to_idx[{i, j}] = cells.size();\n                cells.push_back({i, j});\n            }\n    \n    int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n    auto valid = [&](int i, int j) { return i >= 0 && i < D && j >= 0 && j < D; };\n    \n    vector<vector<int>> dist(D, vector<int>(D, INT_MAX));\n    queue<pair<int,int>> q; q.push({0, entrance_j}); dist[0][entrance_j] = 0;\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (valid(ni, nj) && dist[ni][nj] == INT_MAX && !obstacles.count({ni, nj})) {\n                dist[ni][nj] = dist[i][j] + 1; q.push({ni, nj});\n            }\n        }\n    }\n    \n    vector<int> downstream(cells.size(), 0);\n    for (size_t c = 0; c < cells.size(); c++) {\n        auto [ci, cj] = cells[c];\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<pair<int,int>> bq; bq.push({0, entrance_j});\n        visited[0][entrance_j] = true; visited[ci][cj] = true;\n        while (!bq.empty()) {\n            auto [i, j] = bq.front(); bq.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (valid(ni, nj) && !visited[ni][nj] && !obstacles.count({ni, nj})) {\n                    visited[ni][nj] = true; bq.push({ni, nj});\n                }\n            }\n        }\n        for (size_t cc = 0; cc < cells.size(); cc++)\n            if (!visited[cells[cc].first][cells[cc].second]) downstream[c]++;\n    }\n    \n    vector<int> order(cells.size()); iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        int da = dist[cells[a].first][cells[a].second], db = dist[cells[b].first][cells[b].second];\n        return da != db ? da < db : (downstream[a] != downstream[b] ? downstream[a] > downstream[b] : cells[a] < cells[b]);\n    });\n    vector<int> cell_rank(cells.size());\n    for (size_t i = 0; i < order.size(); i++) cell_rank[order[i]] = i;\n    \n    vector<int> container_at_cell(cells.size(), -1), container_cell(M, -1);\n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        vector<int> available;\n        for (size_t c = 0; c < cells.size(); c++) if (container_at_cell[c] == -1) available.push_back(c);\n        sort(available.begin(), available.end(), [&](int a, int b) { return cell_rank[a] < cell_rank[b]; });\n        int idx = (M == 1) ? 0 : min((int)available.size()-1, max(0, (int)round((double)t/(M-1)*(available.size()-1))));\n        container_at_cell[available[idx]] = t; container_cell[t] = available[idx];\n        cout << cells[available[idx]].first << \" \" << cells[available[idx]].second << \"\\n\" << flush;\n    }\n    \n    vector<bool> present(M, true);\n    for (int step = 0; step < M; step++) {\n        set<int> reachable;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<pair<int,int>> bq; bq.push({0, entrance_j}); visited[0][entrance_j] = true;\n        while (!bq.empty()) {\n            auto [i, j] = bq.front(); bq.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (!valid(ni, nj) || visited[ni][nj] || obstacles.count({ni, nj})) continue;\n                auto it = cell_to_idx.find({ni, nj});\n                if (it == cell_to_idx.end()) { visited[ni][nj] = true; bq.push({ni, nj}); }\n                else if (present[container_at_cell[it->second]]) reachable.insert(container_at_cell[it->second]);\n                else { visited[ni][nj] = true; bq.push({ni, nj}); }\n            }\n        }\n        int best = *reachable.begin(); present[best] = false;\n        cout << cells[container_cell[best]].first << \" \" << cells[container_cell[best]].second << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> g(n, vector<int>(n));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            cin >> g[i][j];\n    \n    int dx[] = {0, 0, 1, -1};\n    int dy[] = {1, -1, 0, 0};\n    auto inside = [&](int x, int y) { return x >= 0 && x < n && y >= 0 && y < n; };\n    \n    set<pair<int,int>> origAdj;\n    map<pair<int,int>, int> adjCnt;\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                int nc = inside(ni, nj) ? g[ni][nj] : 0;\n                if (nc != g[i][j]) {\n                    int a = g[i][j], b = nc;\n                    if (a > b) swap(a, b);\n                    origAdj.insert({a, b});\n                    adjCnt[{a, b}]++;\n                }\n            }\n        }\n    }\n    \n    auto connected = [&](int c) {\n        if (c == 0) return true;\n        int st = -1, cnt = 0;\n        for (int i = 0; i < n; i++)\n            for (int j = 0; j < n; j++)\n                if (g[i][j] == c) { if (st == -1) st = i*n+j; cnt++; }\n        if (cnt <= 1) return true;\n        queue<int> q; vector<bool> vis(n*n, false);\n        q.push(st); vis[st] = true;\n        int visCnt = 0;\n        while (!q.empty()) {\n            int cur = q.front(); q.pop(); visCnt++;\n            for (int d = 0; d < 4; d++) {\n                int nx = cur/n + dx[d], ny = cur%n + dy[d];\n                if (inside(nx, ny) && g[nx][ny] == c && !vis[nx*n+ny]) {\n                    vis[nx*n+ny] = true; q.push(nx*n+ny);\n                }\n            }\n        }\n        return visCnt == cnt;\n    };\n    \n    bool changed = true;\n    while (changed) {\n        changed = false;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (g[i][j] == 0) continue;\n                int c = g[i][j];\n                vector<pair<pair<int,int>, int>> delta;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    int nc = inside(ni, nj) ? g[ni][nj] : 0;\n                    if (nc != c) { int a=c,b=nc; if(a>b) swap(a,b); delta.push_back({{a,b},-1}); }\n                    if (nc != 0) { int a=0,b=nc; if(a>b) swap(a,b); delta.push_back({{a,b},1}); }\n                }\n                bool ok = true;\n                for (auto& [p, d] : delta) {\n                    int newCnt = adjCnt[p] + d;\n                    if (newCnt > 0 && !origAdj.count(p)) { ok = false; break; }\n                    if (newCnt == 0 && origAdj.count(p)) { ok = false; break; }\n                }\n                if (ok) {\n                    g[i][j] = 0;\n                    if (connected(c)) {\n                        for (auto& [p, d] : delta) adjCnt[p] += d;\n                        changed = true;\n                    } else { g[i][j] = c; }\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++)\n            cout << g[i][j] << (j == n-1 ? \"\\n\" : \" \");\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\nint N, D, Q;\nint qc = 0;\nvector<vector<int>> cmp_res;\n\nchar query(const vector<int>& L, const vector<int>& R) {\n    qc++;\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    char r; cin >> r;\n    return r;\n}\n\nint cmp_items(int a, int b) {\n    if (cmp_res[a][b] != 0) return cmp_res[a][b];\n    char r = query({a}, {b});\n    cmp_res[a][b] = (r == '<') ? 1 : (r == '=') ? 2 : 3;\n    cmp_res[b][a] = (r == '>') ? 1 : (r == '=') ? 2 : 3;\n    return cmp_res[a][b];\n}\n\nbool le(int a, int b) {\n    int r = cmp_items(a, b);\n    return r == 1 || r == 2;\n}\n\nvoid merge_sort(vector<int>& arr, int l, int r) {\n    if (l >= r) return;\n    int m = (l + r) / 2;\n    merge_sort(arr, l, m);\n    merge_sort(arr, m + 1, r);\n    vector<int> tmp;\n    int i = l, j = m + 1;\n    while (i <= m && j <= r) {\n        if (le(arr[i], arr[j])) tmp.push_back(arr[i++]);\n        else tmp.push_back(arr[j++]);\n    }\n    while (i <= m) tmp.push_back(arr[i++]);\n    while (j <= r) tmp.push_back(arr[j++]);\n    for (int k = l; k <= r; k++) arr[k] = tmp[k - l];\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    cmp_res.assign(N, vector<int>(N, 0));\n    \n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    merge_sort(order, 0, N - 1);\n    \n    vector<double> ew(N);\n    for (int i = 0; i < N; i++) ew[order[i]] = i + 1;\n    \n    vector<double> sw(D, 0);\n    vector<int> ans(N);\n    vector<vector<int>> sets(D);\n    \n    for (int i = N - 1; i >= 0; i--) {\n        int item = order[i];\n        int ms = 0;\n        for (int d = 1; d < D; d++) if (sw[d] < sw[ms]) ms = d;\n        ans[item] = ms;\n        sets[ms].push_back(item);\n        sw[ms] += ew[item];\n    }\n    \n    for (int d = 0; d < D; d++)\n        sort(sets[d].begin(), sets[d].end(), [&](int a, int b) { return ew[a] < ew[b]; });\n    \n    while (qc + 1 <= Q) {\n        int heavy = 0, light = 0;\n        for (int d = 1; d < D; d++) {\n            if (sw[d] > sw[heavy]) heavy = d;\n            if (sw[d] < sw[light]) light = d;\n        }\n        \n        if (heavy == light || sets[heavy].empty()) break;\n        \n        char result = query(sets[heavy], sets[light]);\n        if (result == '=') break;\n        if (result == '<') swap(heavy, light);\n        \n        int to_move = sets[heavy][0];\n        sets[heavy].erase(sets[heavy].begin());\n        \n        auto it = lower_bound(sets[light].begin(), sets[light].end(), to_move,\n                              [&](int a, int b) { return ew[a] < ew[b]; });\n        sets[light].insert(it, to_move);\n        \n        sw[heavy] -= ew[to_move];\n        sw[light] += ew[to_move];\n        ans[to_move] = light;\n    }\n    \n    while (qc < Q) query({0}, {1});\n    \n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << ans[i];\n    }\n    cout << \"\\n\" << flush;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> st(m);\n    for (int i = 0; i < m; i++) {\n        st[i].resize(n/m);\n        for (int j = 0; j < n/m; j++) {\n            cin >> st[i][j];\n        }\n    }\n    \n    vector<pair<int, int>> ops;\n    \n    for (int v = 1; v <= n; v++) {\n        // Find position of box v\n        int si = -1, pos = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)st[i].size(); j++) {\n                if (st[i][j] == v) {\n                    si = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (si != -1) break;\n        }\n        \n        if (si == -1) continue;\n        \n        // Move boxes above v if any\n        if (pos < (int)st[si].size() - 1) {\n            int maxMoved = INT_MIN, minMoved = INT_MAX;\n            for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                maxMoved = max(maxMoved, st[si][j]);\n                minMoved = min(minMoved, st[si][j]);\n            }\n            \n            // Find best destination using scoring heuristic\n            int dest = -1;\n            int bestScore = INT_MIN;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == si) continue;\n                \n                int score;\n                if (st[i].empty()) {\n                    score = 100;  // Empty stacks are good\n                } else {\n                    int top = st[i].back();\n                    if (top > maxMoved) {\n                        score = 200 + top;  // Best: all moved boxes smaller than top\n                    } else if (top < minMoved) {\n                        score = -1000;  // Worst: would block access to top\n                    } else {\n                        score = 50 - top;  // Mixed case\n                    }\n                }\n                \n                if (score > bestScore) {\n                    bestScore = score;\n                    dest = i;\n                }\n            }\n            \n            // Move all boxes above v to destination\n            int boxAbove = st[si][pos + 1];\n            ops.push_back({boxAbove, dest + 1});  // dest+1 for 1-indexed output\n            \n            for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                st[dest].push_back(st[si][j]);\n            }\n            st[si].resize(pos + 1);\n        }\n        \n        // Carry out box v (now at top)\n        ops.push_back({v, 0});\n        st[si].pop_back();\n    }\n    \n    for (auto& [a, b] : ops) {\n        cout << a << \" \" << b << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#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<string> h(N-1), v(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};\n    char dir[] = {'R', 'D', 'L', 'U'};\n    \n    auto canMove = [&](int i, int j, int k) -> bool {\n        int ni = i + di[k], nj = j + dj[k];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n        if (di[k] != 0) return h[min(i, ni)][j] == '0';\n        return v[i][min(j, nj)] == '0';\n    };\n    \n    vector visited(N, vector<bool>(N, false));\n    string tour;\n    \n    auto dfs = [&](auto& self, int i, int j) -> void {\n        visited[i][j] = true;\n        vector<tuple<int,int,int>> nb;\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (canMove(i, j, k) && !visited[ni][nj])\n                nb.emplace_back(-d[ni][nj], ni, nj);\n        }\n        sort(nb.begin(), nb.end());\n        for (auto [_, ni, nj] : nb) {\n            for (int k = 0; k < 4; k++)\n                if (i + di[k] == ni && j + dj[k] == nj) {\n                    tour += dir[k]; self(self, ni, nj); tour += dir[(k+2)%4];\n                    break;\n                }\n        }\n    };\n    dfs(dfs, 0, 0);\n    \n    vector dist0(N, vector<int>(N, -1)), prevDir(N, vector<int>(N, -1));\n    queue<pair<int,int>> q; q.push({0,0}); dist0[0][0] = 0;\n    while (!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (canMove(i,j,k) && dist0[ni][nj] < 0) {\n                dist0[ni][nj] = dist0[i][j] + 1; prevDir[ni][nj] = k; q.push({ni,nj});\n            }\n        }\n    }\n    \n    vector visitCount(N, vector<int>(N, 1));\n    int budget = 100000 - (int)tour.size();\n    priority_queue<tuple<double,int,int,int>> pq;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if ((i||j) && dist0[i][j] > 0) pq.push({(double)d[i][j]/2/dist0[i][j], 1, i, j});\n    }\n    \n    while (!pq.empty() && budget > 10) {\n        auto [score, vc, i, j] = pq.top(); pq.pop();\n        if (vc != visitCount[i][j]) continue;\n        int cost = 2 * dist0[i][j];\n        if (cost > budget) continue;\n        \n        string fwd; int ci = i, cj = j;\n        while (ci || cj) { int k = prevDir[ci][cj]; fwd += dir[k]; ci -= di[k]; cj -= dj[k]; }\n        reverse(fwd.begin(), fwd.end());\n        string back = fwd; reverse(back.begin(), back.end());\n        for (char& c : back) { if(c=='R')c='L'; else if(c=='L')c='R'; else if(c=='U')c='D'; else c='U'; }\n        \n        tour += fwd + back; visitCount[i][j]++; budget -= cost;\n        int nv = visitCount[i][j];\n        pq.push({(double)d[i][j]/(nv*(nv+1))/cost, nv, i, j});\n    }\n    \n    cout << tour << '\\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(nullptr);\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<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 * N + j);\n    \n    auto getCoord = [N](int idx) { return make_pair(idx / N, idx % N); };\n    \n    auto computeOverlap = [](const string& a, const string& b) {\n        for (int len = (int)min(a.size(), b.size()); len >= 0; len--) {\n            bool match = true;\n            for (int i = 0; i < len && match; i++)\n                if (a[a.size() - len + i] != b[i]) match = false;\n            if (match) return len;\n        }\n        return 0;\n    };\n    \n    string superstring = words[0];\n    vector<bool> used(M, false);\n    used[0] = true;\n    \n    for (int k = 1; k < M; k++) {\n        int best_idx = -1, best_overlap = -1;\n        bool appendBack = true;\n        \n        for (int i = 0; i < M; i++) {\n            if (used[i]) continue;\n            int o1 = computeOverlap(superstring, words[i]);\n            int o2 = computeOverlap(words[i], superstring);\n            if (o1 > best_overlap) { best_overlap = o1; best_idx = i; appendBack = true; }\n            if (o2 > best_overlap) { best_overlap = o2; best_idx = i; appendBack = false; }\n        }\n        \n        if (appendBack) superstring += words[best_idx].substr(best_overlap);\n        else superstring = words[best_idx] + superstring.substr(best_overlap);\n        used[best_idx] = true;\n    }\n    \n    int L = superstring.size();\n    vector<pair<int, int>> dp;\n    \n    for (int cell : charPos[superstring[0] - 'A']) {\n        auto [ci, cj] = getCoord(cell);\n        dp.emplace_back(cell, abs(ci - si) + abs(cj - sj) + 1);\n    }\n    \n    vector<unordered_map<int, int>> parent(L);\n    \n    for (int idx = 1; idx < L; idx++) {\n        vector<pair<int, int>> newDp;\n        for (int cell : charPos[superstring[idx] - 'A']) {\n            auto [ci, cj] = getCoord(cell);\n            int minCost = INT_MAX, bestPrev = -1;\n            for (auto& [prevCell, cost] : dp) {\n                auto [pi, pj] = getCoord(prevCell);\n                int newCost = cost + abs(ci - pi) + abs(cj - pj) + 1;\n                if (newCost < minCost) { minCost = newCost; bestPrev = prevCell; }\n            }\n            if (bestPrev != -1) {\n                newDp.emplace_back(cell, minCost);\n                parent[idx][cell] = bestPrev;\n            }\n        }\n        dp = move(newDp);\n    }\n    \n    int endCell = min_element(dp.begin(), dp.end(), [](auto& a, auto& b) { return a.second < b.second; })->first;\n    \n    vector<int> path(L);\n    path[L - 1] = endCell;\n    for (int idx = L - 2; idx >= 0; idx--)\n        path[idx] = parent[idx + 1][path[idx + 1]];\n    \n    for (int cell : path) {\n        auto [i, j] = getCoord(cell);\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<set<pair<int,int>>> shapes;\nvector<vector<int>> obs;\nint Q = 0;\n\npair<int,int> getShapeBB(int k) {\n    int maxI = 0, maxJ = 0;\n    for (auto& p : shapes[k]) {\n        maxI = max(maxI, p.first);\n        maxJ = max(maxJ, p.second);\n    }\n    return {maxI, maxJ};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> eps;\n    shapes.resize(M);\n    obs.assign(N, vector<int>(N, -1));\n    \n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        for (int i = 0; i < d; i++) {\n            int r, c; cin >> r >> c;\n            shapes[k].insert({r, c});\n        }\n    }\n    \n    auto drill = [&](int i, int j) -> int {\n        if (obs[i][j] != -1) return obs[i][j];\n        if (Q >= 2*N*N - 1) return -1;\n        cout << \"q 1 \" << i << \" \" << j << endl;\n        int r; cin >> r;\n        obs[i][j] = r;\n        Q++;\n        return r;\n    };\n    \n    auto divine = [&](const vector<pair<int,int>>& sq) -> int {\n        if (sq.size() < 2 || Q >= 2*N*N - 1) return -1;\n        cout << \"q \" << sq.size();\n        for (auto& p : sq) cout << \" \" << p.first << \" \" << p.second;\n        cout << endl;\n        int r; cin >> r;\n        Q++;\n        return r;\n    };\n    \n    // Phase 1: Divine blocks to estimate oil distribution\n    vector<vector<double>> oilProb(N, vector<double>(N, 0.5));\n    int BS = max(3, N / 3);\n    \n    for (int bi = 0; bi < N && Q < N; bi += BS) {\n        for (int bj = 0; bj < N && Q < N; bj += BS) {\n            vector<pair<int,int>> block;\n            for (int i = bi; i < min(N, bi+BS); i++)\n                for (int j = bj; j < min(N, bj+BS); j++)\n                    block.push_back({i,j});\n            if (block.size() >= 2) {\n                int r = divine(block);\n                if (r >= 0) {\n                    double est = max(0.0, (r - (int)block.size() * eps) / (1 - 2*eps));\n                    double p = min(1.0, est / block.size());\n                    for (auto& sq : block) oilProb[sq.first][sq.second] = p;\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Drill high probability squares\n    vector<tuple<double,int,int>> order;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            order.push_back({oilProb[i][j], i, j});\n    sort(order.rbegin(), order.rend());\n    \n    for (auto& [p, i, j] : order) {\n        if (Q < N*N) drill(i, j);\n    }\n    \n    // Phase 3: Shape-based inference for remaining unknowns\n    for (int iter = 0; iter < 5 && Q < 2*N*N - N; iter++) {\n        set<pair<int,int>> inferred;\n        for (int k = 0; k < M; k++) {\n            auto [maxI, maxJ] = getShapeBB(k);\n            for (int di = 0; di <= N-1-maxI; di++) {\n                for (int dj = 0; dj <= N-1-maxJ; dj++) {\n                    bool hasOil = false, valid = true;\n                    for (auto& p : shapes[k]) {\n                        int ni = p.first + di, nj = p.second + dj;\n                        if (obs[ni][nj] == 0) valid = false;\n                        if (obs[ni][nj] > 0) hasOil = true;\n                    }\n                    if (valid && hasOil) {\n                        for (auto& p : shapes[k]) {\n                            int ni = p.first + di, nj = p.second + dj;\n                            if (obs[ni][nj] == -1) inferred.insert({ni, nj});\n                        }\n                    }\n                }\n            }\n        }\n        for (auto& sq : inferred) if (Q < 2*N*N - 1) drill(sq.first, sq.second);\n    }\n    \n    // Phase 4: Fill remaining\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (obs[i][j] == -1 && Q < 2*N*N - 1) drill(i, j);\n    \n    // Answer\n    vector<pair<int,int>> oil;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (obs[i][j] > 0) oil.push_back({i,j});\n    \n    cout << \"a \" << oil.size();\n    for (auto& p : oil) cout << \" \" << p.first << \" \" << p.second;\n    cout << endl;\n    int r; cin >> r;\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    vector<vector<array<int, 4>>> rect(D, vector<array<int, 4>>(N));\n    vector<int> cumY(N); // cumulative y-positions (partition locations)\n    \n    for (int d = 0; d < D; d++) {\n        vector<int> h(N);\n        \n        // Check if previous partition positions work for current day\n        bool reuse = false;\n        if (d > 0) {\n            reuse = true;\n            for (int k = 0; k < N; k++) {\n                int hk = (k == 0) ? cumY[0] : cumY[k] - cumY[k-1];\n                if ((long long)hk * W < a[d][k]) {\n                    reuse = false;\n                    break;\n                }\n            }\n        }\n        \n        if (reuse) {\n            h[0] = cumY[0];\n            for (int k = 1; k < N; k++) h[k] = cumY[k] - cumY[k-1];\n        } else {\n            // Compute base heights using floor division\n            for (int k = 0; k < N; k++) h[k] = a[d][k] / W;\n            \n            int totalH = 0;\n            for (int k = 0; k < N; k++) totalH += h[k];\n            int rem = W - totalH;\n            \n            // Distribute remaining height to cover deficits (priority: larger deficit)\n            priority_queue<pair<int, int>> pq;\n            for (int k = 0; k < N; k++) {\n                int def = a[d][k] - h[k] * W;\n                if (def > 0) pq.push({def, k});\n            }\n            \n            while (rem > 0 && !pq.empty()) {\n                auto [def, k] = pq.top(); pq.pop();\n                h[k]++;\n                rem--;\n                int newDef = a[d][k] - h[k] * W;\n                if (newDef > 0) pq.push({newDef, k});\n            }\n            \n            // Fill remaining height\n            for (int k = 0; k < N && rem > 0; k++) {\n                h[k]++;\n                rem--;\n            }\n            \n            totalH = 0;\n            for (int k = 0; k < N; k++) totalH += h[k];\n            if (totalH < W) h[N-1] += W - totalH;\n        }\n        \n        // Assign rectangles\n        int y = 0;\n        for (int k = 0; k < N; k++) {\n            rect[d][k] = {y, 0, y + h[k], W};\n            y += h[k];\n        }\n        \n        // Update cumulative positions\n        cumY[0] = h[0];\n        for (int k = 1; k < N; k++) cumY[k] = cumY[k-1] + h[k];\n    }\n    \n    // Output\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << rect[d][k][0] << \" \" << rect[d][k][1] << \" \"\n                 << rect[d][k][2] << \" \" << rect[d][k][3] << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <climits>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const long long MOD = 998244353;\n    const int N = 9;\n    const int M = 20;\n    const int K = 81;\n    \n    int n, m, k;\n    cin >> n >> m >> k;\n    \n    long long board[N][N];\n    long long stamps[M][3][3];\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    for (int s = 0; s < M; s++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[s][i][j];\n            }\n        }\n    }\n    \n    vector<tuple<int, int, int>> operations;\n    \n    for (int op = 0; op < K; op++) {\n        int bestStamp = -1, bestP = -1, bestQ = -1;\n        long long bestGain = LLONG_MIN;\n        \n        for (int s = 0; s < M; s++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    long long gain = 0;\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            int ni = p + i, nj = q + j;\n                            long long oldRem = board[ni][nj] % MOD;\n                            long long newRem = (board[ni][nj] + stamps[s][i][j]) % MOD;\n                            gain += newRem - oldRem;\n                        }\n                    }\n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestStamp = s;\n                        bestP = p;\n                        bestQ = q;\n                    }\n                }\n            }\n        }\n        \n        if (bestGain <= 0) break;\n        \n        operations.emplace_back(bestStamp, bestP, bestQ);\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                board[bestP + i][bestQ + j] += stamps[bestStamp][i][j];\n            }\n        }\n    }\n    \n    cout << operations.size() << \"\\n\";\n    for (const auto& [stamp, p, q] : operations) {\n        cout << stamp << \" \" << p << \" \" << q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <queue>\nusing namespace std;\n\nconst int N = 5;\nconst int MAXT = 10000;\nint A[N][N];\nint grid[N][N], cr[N], cc[N], ch[N], dnext[N], ridx[N];\nbool alive[N];\n\nbool occupied(int r, int c, int excl = -1) {\n    for (int i = 0; i < N; i++)\n        if (i != excl && alive[i] && cr[i] == r && cc[i] == c) return true;\n    return false;\n}\n\nbool canMove(int ci, int nr, int nc) {\n    if (nr < 0 || nr >= N || nc < 0 || nc >= N) return false;\n    if (occupied(nr, nc, ci)) return false;\n    if (ci != 0 && ch[ci] != -1 && grid[nr][nc] != -1) return false;\n    return true;\n}\n\nchar findMove(int ci, int tr, int tc) {\n    if (cr[ci] == tr && cc[ci] == tc) return '.';\n    static int dist[N][N]; static char first[N][N];\n    memset(dist, -1, sizeof(dist));\n    queue<pair<int,int>> q;\n    const int DR[] = {-1, 1, 0, 0}, DC[] = {0, 0, -1, 1};\n    const char D[] = {'U', 'D', 'L', 'R'};\n    for (int d = 0; d < 4; d++) {\n        int nr = cr[ci] + DR[d], nc = cc[ci] + DC[d];\n        if (canMove(ci, nr, nc)) { dist[nr][nc] = 1; first[nr][nc] = D[d]; q.push({nr, nc}); }\n    }\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == tr && c == tc) return first[r][c];\n        for (int d = 0; d < 4; d++) {\n            int nr = r + DR[d], nc = c + DC[d];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && dist[nr][nc] == -1 && !occupied(nr, nc)) {\n                dist[nr][nc] = dist[r][c] + 1; first[nr][nc] = first[r][c]; q.push({nr, nc});\n            }\n        }\n    }\n    return '.';\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\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; alive[i] = true; ridx[i] = 0; dnext[i] = i * N; }\n    vector<string> out(N, \"\");\n    \n    for (int t = 0; t < MAXT; t++) {\n        string act(N, '.'); int newr[N], newc[N];\n        for (int i = 0; i < N; i++) { newr[i] = cr[i]; newc[i] = cc[i]; }\n        \n        for (int i = 0; i < N; i++)\n            if (ridx[i] < N && grid[i][0] == -1 && !occupied(i, 0)) grid[i][0] = A[i][ridx[i]++];\n        \n        for (int i = 0; i < N; i++) {\n            if (!alive[i]) continue;\n            if (ch[i] != -1) {\n                int tr = ch[i] / N; bool is_next = (ch[i] == dnext[tr]);\n                int sr = tr, sc = -1;\n                for (int c = N-2; c >= 1; c--) if (grid[sr][c] == -1 && !occupied(sr, c)) { sc = c; break; }\n                int dr = tr, dc = (is_next || sc == -1) ? N-1 : sc;\n                if (cr[i] == dr && cc[i] == dc) act[i] = 'Q';\n                else act[i] = findMove(i, dr, dc);\n                if (act[i] == 'U') newr[i]--; else if (act[i] == 'D') newr[i]++;\n                else if (act[i] == 'L') newc[i]--; else if (act[i] == 'R') newc[i]++;\n            } else {\n                if (grid[cr[i]][cc[i]] != -1) act[i] = 'P';\n                else {\n                    int bestc = -1, bestd = 100;\n                    for (int c = 0; c < N; c++) {\n                        if (grid[cr[i]][c] != -1 && (cr[i] != c || c != N-1)) {\n                            int d = abs(c - cc[i]); if (d < bestd) { bestd = d; bestc = c; }\n                        }\n                    }\n                    act[i] = findMove(i, cr[i], bestc != -1 ? bestc : 0);\n                    if (act[i] == 'U') newr[i]--; else if (act[i] == 'D') newr[i]++;\n                    else if (act[i] == 'L') newc[i]--; else if (act[i] == 'R') newc[i]++;\n                }\n            }\n        }\n        \n        for (int i = 0; i < N; i++) for (int j = i+1; j < N; j++) {\n            if (!alive[i] || !alive[j]) continue;\n            if (cr[i] == newr[j] && cc[i] == newc[j] && cr[j] == newr[i] && cc[j] == newc[i])\n                { act[j] = '.'; newr[j] = cr[j]; newc[j] = cc[j]; }\n        }\n        for (int i = 0; i < N; i++) for (int j = i+1; j < N; j++) {\n            if (!alive[i] || !alive[j]) continue;\n            if (newr[i] == newr[j] && newc[i] == newc[j])\n                { act[j] = '.'; newr[j] = cr[j]; newc[j] = cc[j]; }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            if (!alive[i]) continue;\n            if (act[i] == 'P' && ch[i] == -1 && grid[cr[i]][cc[i]] != -1) { ch[i] = grid[cr[i]][cc[i]]; grid[cr[i]][cc[i]] = -1; }\n            else if (act[i] == 'Q' && ch[i] != -1 && grid[cr[i]][cc[i]] == -1) { grid[cr[i]][cc[i]] = ch[i]; ch[i] = -1; }\n        }\n        for (int i = 0; i < N; i++) { if (!alive[i]) continue; if (!canMove(i, newr[i], newc[i])) { act[i] = '.'; newr[i] = cr[i]; newc[i] = cc[i]; } }\n        for (int i = 0; i < N; i++) { if (!alive[i]) continue; cr[i] = newr[i]; cc[i] = newc[i]; }\n        \n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) { int c = grid[i][N-1]; if (c == dnext[i]) dnext[i]++; grid[i][N-1] = -1; }\n        }\n        for (int i = 0; i < N; i++) out[i] += act[i];\n        \n        bool done = true;\n        for (int i = 0; i < N; i++) if (ridx[i] < N) done = false;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (grid[i][j] != -1) done = false;\n        for (int i = 0; i < N; i++) if (ch[i] != -1) done = false;\n        if (done) break;\n    }\n    for (int i = 0; i < N; i++) cout << out[i] << \"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\nlong long truck_load = 0;\nint cur_i = 0, cur_j = 0;\nvector<string> ops;\n\nvoid add_op(const string& s) { ops.push_back(s); }\n\nvoid move_to(int ni, int nj) {\n    while (cur_i < ni) { add_op(\"D\"); cur_i++; }\n    while (cur_i > ni) { add_op(\"U\"); cur_i--; }\n    while (cur_j < nj) { add_op(\"R\"); cur_j++; }\n    while (cur_j > nj) { add_op(\"L\"); cur_j--; }\n}\n\nint dist(int i1, int j1, int i2, int j2) {\n    return abs(i1 - i2) + abs(j1 - j2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cin >> h[i][j];\n    \n    while (true) {\n        bool has_pos = false, has_neg = false;\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) {\n                if (h[i][j] > 0) has_pos = true;\n                if (h[i][j] < 0) has_neg = true;\n            }\n        \n        if (!has_pos && !has_neg) break;\n        \n        if (truck_load == 0 && has_pos) {\n            long long best_cost = LLONG_MAX;\n            int best_i = -1, best_j = -1;\n            \n            for (int i = 0; i < N; i++)\n                for (int j = 0; j < N; j++)\n                    if (h[i][j] > 0) {\n                        int amt = h[i][j];\n                        int d1 = dist(cur_i, cur_j, i, j);\n                        \n                        int d2 = INT_MAX;\n                        for (int ii = 0; ii < N; ii++)\n                            for (int jj = 0; jj < N; jj++)\n                                if (h[ii][jj] < 0)\n                                    d2 = min(d2, dist(i, j, ii, jj));\n                        \n                        if (d2 == INT_MAX) d2 = 0;\n                        \n                        long long cost = 100LL * d1 + (100LL + amt) * d2;\n                        \n                        if (cost < best_cost) {\n                            best_cost = cost;\n                            best_i = i; best_j = j;\n                        }\n                    }\n            \n            if (best_i == -1) break;\n            \n            move_to(best_i, best_j);\n            int amt = h[best_i][best_j];\n            add_op(\"+\" + to_string(amt));\n            h[best_i][best_j] = 0;\n            truck_load += amt;\n        } else if (truck_load > 0 && has_neg) {\n            int best_d = INT_MAX, best_i = -1, best_j = -1;\n            for (int i = 0; i < N; i++)\n                for (int j = 0; j < N; j++)\n                    if (h[i][j] < 0) {\n                        int d = dist(cur_i, cur_j, i, j);\n                        if (d < best_d) {\n                            best_d = d;\n                            best_i = i; best_j = j;\n                        }\n                    }\n            \n            if (best_i == -1) break;\n            \n            move_to(best_i, best_j);\n            int amt = min(truck_load, (long long)-h[best_i][best_j]);\n            add_op(\"-\" + to_string(amt));\n            h[best_i][best_j] += amt;\n            truck_load -= amt;\n        } else {\n            break;\n        }\n    }\n    \n    for (auto& s : ops) cout << s << \"\\n\";\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n    int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> X(seed_count, vector<int>(M));\n    \n    for (int i = 0; i < seed_count; i++)\n        for (int j = 0; j < M; j++)\n            cin >> X[i][j];\n    \n    mt19937 rng(42);\n    uniform_int_distribution<int> distPos(0, N * N - 1);\n    uniform_real_distribution<double> uni(0, 1);\n    \n    for (int t = 0; t < T; t++) {\n        vector<int> order(seed_count);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            int sa = 0, sb = 0;\n            for (int l = 0; l < M; l++) { sa += X[a][l]; sb += X[b][l]; }\n            return sa > sb;\n        });\n        \n        vector<int> flat(order.begin(), order.begin() + N * N);\n        \n        auto pot = [&](int a, int b) -> int {\n            int p = 0;\n            for (int l = 0; l < M; l++) p += max(X[a][l], X[b][l]);\n            return p;\n        };\n        \n        auto contrib = [&](int idx) -> int {\n            int i = idx / N, j = idx % N, c = 0;\n            if (j > 0) c += pot(flat[idx], flat[idx - 1]);\n            if (j < N - 1) c += pot(flat[idx], flat[idx + 1]);\n            if (i > 0) c += pot(flat[idx], flat[idx - N]);\n            if (i < N - 1) c += pot(flat[idx], flat[idx + N]);\n            return c;\n        };\n        \n        int score = 0;\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N - 1; j++) score += pot(flat[i*N+j], flat[i*N+j+1]);\n        for (int i = 0; i < N - 1; i++)\n            for (int j = 0; j < N; j++) score += pot(flat[i*N+j], flat[(i+1)*N+j]);\n        \n        int bestScore = score;\n        vector<int> bestFlat = flat;\n        \n        double temp = 10.0;\n        for (int iter = 0; iter < 50000; iter++) {\n            int p1 = distPos(rng), p2 = distPos(rng);\n            if (p1 == p2) continue;\n            \n            int r1 = p1/N, c1 = p1%N, r2 = p2/N, c2 = p2%N;\n            bool adj = (abs(r1-r2)==1 && c1==c2) || (abs(c1-c2)==1 && r1==r2);\n            \n            int old = contrib(p1) + contrib(p2);\n            if (adj) old -= pot(flat[p1], flat[p2]);\n            \n            swap(flat[p1], flat[p2]);\n            \n            int nw = contrib(p1) + contrib(p2);\n            if (adj) nw -= pot(flat[p1], flat[p2]);\n            \n            int delta = nw - old;\n            \n            if (delta > 0 || uni(rng) < exp(delta / temp)) {\n                score += delta;\n                if (score > bestScore) { bestScore = score; bestFlat = flat; }\n            } else {\n                swap(flat[p1], flat[p2]);\n            }\n            temp *= 0.9999;\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << bestFlat[i * N + j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n        \n        for (int i = 0; i < seed_count; i++)\n            for (int j = 0; j < M; j++)\n                cin >> X[i][j];\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<string> S, T;\n\nconst int DX[] = {1, 0, -1, 0};\nconst int DY[] = {0, 1, 0, -1};\nconst char DIR_C[] = \"RDLU\";\n\nstruct Robot {\n    int V;\n    vector<int> par, len;\n    vector<vector<int>> child;\n    vector<int> leaves;\n    int rx, ry;\n    vector<int> edir;\n    \n    void init(int v) {\n        V = v;\n        par.resize(V, -1); len.resize(V); child.resize(V); edir.resize(V, 0);\n    }\n    \n    void build() {\n        int nb = min(V - 1, 4);\n        int blen = max(2, N / 4);\n        for (int i = 1; i <= nb && i < V; i++) {\n            par[i] = 0; len[i] = blen; child[0].push_back(i);\n        }\n        for (int i = nb + 1; i < V; i++) {\n            par[i] = (i - 2) % nb + 1; len[i] = 2;\n            child[par[i]].push_back(i);\n        }\n        for (int i = 0; i < V; i++) if (child[i].empty()) leaves.push_back(i);\n    }\n    \n    pair<int,int> pos(int v) const {\n        if (par[v] < 0) return {rx, ry};\n        auto [px, py] = pos(par[v]);\n        return {px + DX[edir[v]] * len[v], py + DY[edir[v]] * len[v]};\n    }\n    \n    void rot_subtree(int u, int d) {\n        queue<int> q; q.push(u);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (par[v] >= 0) edir[v] = (edir[v] + d + 4) % 4;\n            for (int c : child[v]) q.push(c);\n        }\n    }\n    void move(int d) { rx += DX[d]; ry += DY[d]; }\n};\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> V;\n    S.resize(N); T.resize(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    Robot rob; rob.init(V); rob.build();\n    \n    long long sx = 0, sy = 0, cnt = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (S[i][j] == '1') { sx += i; sy += j; cnt++; }\n    rob.rx = (cnt > 0) ? sx / cnt : N / 2;\n    rob.ry = (cnt > 0) ? sy / cnt : N / 2;\n    rob.rx = max(0, min(N - 1, rob.rx)); rob.ry = max(0, min(N - 1, rob.ry));\n    \n    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) cout << rob.par[i] << \" \" << rob.len[i] << \"\\n\";\n    cout << rob.rx << \" \" << rob.ry << \"\\n\";\n    \n    vector<vector<int>> grid(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) grid[i][j] = (S[i][j] == '1');\n    \n    set<pair<int,int>> usrc, utgt;\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') usrc.insert({i, j});\n        if (T[i][j] == '1' && S[i][j] == '0') utgt.insert({i, j});\n    }\n    \n    map<int, bool> hold;\n    for (int l : rob.leaves) hold[l] = false;\n    \n    auto find_nearest = [&](int x, int y, bool need_src) -> int {\n        int mn = INT_MAX;\n        if (need_src) for (auto [r, c] : usrc) if (grid[r][c] == 1) mn = min(mn, abs(x-r) + abs(y-c));\n        else for (auto [r, c] : utgt) if (grid[r][c] == 0) mn = min(mn, abs(x-r) + abs(y-c));\n        return mn;\n    };\n    \n    auto score = [&]() -> long long {\n        long long s = 0;\n        for (int l : rob.leaves) { auto [x, y] = rob.pos(l); int d = find_nearest(x, y, !hold[l]); if (d < INT_MAX) s += d; }\n        return s;\n    };\n    \n    for (int t = 0; t < 100000; t++) {\n        bool done = true;\n        for (auto [r, c] : utgt) if (grid[r][c] == 0) { done = false; break; }\n        if (done) break;\n        \n        string cmd(2 * V, '.');\n        \n        for (int l : rob.leaves) {\n            auto [x, y] = rob.pos(l);\n            if (x < 0 || x >= N || y < 0 || y >= N) continue;\n            if (!hold[l] && grid[x][y] == 1 && T[x][y] == '0') { cmd[V + l] = 'P'; hold[l] = true; grid[x][y] = 0; usrc.erase({x, y}); }\n            else if (hold[l] && grid[x][y] == 0 && T[x][y] == '1') { cmd[V + l] = 'P'; hold[l] = false; grid[x][y] = 1; utgt.erase({x, y}); }\n        }\n        \n        int bd = -1; long long bs = LLONG_MAX;\n        for (int d = 0; d < 4; d++) {\n            int nx = rob.rx + DX[d], ny = rob.ry + DY[d];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            rob.move(d); long long s = score(); rob.move((d + 2) % 4);\n            if (s < bs) { bs = s; bd = d; }\n        }\n        if (bd >= 0) { cmd[0] = DIR_C[bd]; rob.move(bd); }\n        \n        for (int u = 1; u < V; u++) {\n            auto orig = rob.edir; long long so = score();\n            rob.rot_subtree(u, 3); long long sl = score();\n            rob.edir = orig; rob.rot_subtree(u, 1); long long sr = score();\n            if (sl < so && sl <= sr) { rob.edir = orig; rob.rot_subtree(u, 3); cmd[u] = 'L'; }\n            else if (sr < so) cmd[u] = 'R';\n            else rob.edir = orig;\n        }\n        cout << cmd << \"\\n\";\n    }\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAXC = 100000;\nint N;\nvector<pair<int,int>> mac, sar;\n\nint cnt(int x1, int y1, int x2, int y2, const vector<pair<int,int>>& pts) {\n    int c = 0;\n    for (auto& [x,y] : pts) if (x >= x1 && x <= x2 && y >= y1 && y <= y2) c++;\n    return c;\n}\n\nint eval(int x1, int y1, int x2, int y2) {\n    return cnt(x1,y1,x2,y2,mac) - cnt(x1,y1,x2,y2,sar);\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N;\n    mac.resize(N); sar.resize(N);\n    for (int i = 0; i < N; i++) cin >> mac[i].first >> mac[i].second;\n    for (int i = 0; i < N; i++) cin >> sar[i].first >> sar[i].second;\n    \n    set<int> xs_set, ys_set;\n    for (auto& [x,y] : mac) { xs_set.insert(x); ys_set.insert(y); }\n    for (auto& [x,y] : sar) { xs_set.insert(x); ys_set.insert(y); }\n    vector<int> xs(xs_set.begin(), xs_set.end()), ys(ys_set.begin(), ys_set.end());\n    \n    int best = -N, bx1 = 0, by1 = 0, bx2 = MAXC, by2 = MAXC;\n    \n    for (int GS : {40, 80, 160}) {\n        int CS = MAXC / GS + 1;\n        vector diff(GS+1, vector<int>(GS+1, 0));\n        for (auto& [x,y] : mac) diff[min(x/CS,GS-1)][min(y/CS,GS-1)]++;\n        for (auto& [x,y] : sar) diff[min(x/CS,GS-1)][min(y/CS,GS-1)]--;\n        \n        vector pref(GS+2, vector<int>(GS+2, 0));\n        for (int i = 1; i <= GS; i++)\n            for (int j = 1; j <= GS; j++)\n                pref[i][j] = diff[i-1][j-1] + pref[i-1][j] + pref[i][j-1] - pref[i-1][j-1];\n        \n        auto sum = [&](int x1, int y1, int x2, int y2) {\n            return pref[x2][y2] - pref[x1][y2] - pref[x2][y1] + pref[x1][y1];\n        };\n        \n        for (int x1 = 0; x1 < GS; x1++) {\n            for (int x2 = x1+1; x2 <= GS; x2++) {\n                int minPref = 0, minIdx = 0, cs = 0;\n                for (int y2 = 1; y2 <= GS; y2++) {\n                    cs += sum(x1, y2-1, x2, y2);\n                    if (cs - minPref > best) {\n                        best = cs - minPref;\n                        bx1 = x1 * CS; by1 = minIdx * CS;\n                        bx2 = min(x2 * CS, MAXC); by2 = min(y2 * CS, MAXC);\n                    }\n                    if (cs < minPref) { minPref = cs; minIdx = y2; }\n                }\n            }\n        }\n    }\n    \n    for (int it = 0; it < 30; it++) {\n        for (int x : xs) {\n            if (x >= 0 && x < bx2) { int s = eval(x,by1,bx2,by2); if (s > best) { best = s; bx1 = x; } }\n            if (x > bx1 && x <= MAXC) { int s = eval(bx1,by1,x,by2); if (s > best) { best = s; bx2 = x; } }\n        }\n        for (int y : ys) {\n            if (y >= 0 && y < by2) { int s = eval(bx1,y,bx2,by2); if (s > best) { best = s; by1 = y; } }\n            if (y > by1 && y <= MAXC) { int s = eval(bx1,by1,bx2,y); if (s > best) { best = s; by2 = y; } }\n        }\n    }\n    \n    cout << 4 << \"\\n\" << bx1 << \" \" << by1 << \"\\n\" << bx2 << \" \" << by1 << \"\\n\"\n         << bx2 << \" \" << by2 << \"\\n\" << bx1 << \" \" << by2 << \"\\n\";\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, sigma;\nvector<long long> w_est, h_est;\nmt19937_64 rng(42);\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T >> sigma;\n    w_est.resize(N);\n    h_est.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w_est[i] >> h_est[i];\n    }\n    \n    vector<int> best_order(N), best_rot(N, 0), best_dir(N, 0), best_ref(N, -1);\n    iota(best_order.begin(), best_order.end(), 0);\n    sort(best_order.begin(), best_order.end(), [](int a, int b) {\n        return w_est[a] + h_est[a] > w_est[b] + h_est[b];\n    });\n    \n    auto simulate = [&](const vector<int>& ord, const vector<int>& ro, const vector<int>& di, const vector<int>& re) -> long long {\n        vector<long long> x1(N), y1(N), x2(N), y2(N);\n        vector<bool> placed(N, false);\n        long long W = 0, H = 0;\n        for (int step = 0; step < N; step++) {\n            int idx = ord[step];\n            long long w = (ro[step] == 0) ? w_est[idx] : h_est[idx];\n            long long h = (ro[step] == 0) ? h_est[idx] : w_est[idx];\n            long long x0, y0;\n            if (di[step] == 0) {\n                x0 = (re[step] == -1) ? 0 : x2[re[step]];\n                y0 = 0;\n                for (int i = 0; i < N; i++)\n                    if (placed[i] && x0 < x2[i] && x0 + w > x1[i]) y0 = max(y0, y2[i]);\n            } else {\n                y0 = (re[step] == -1) ? 0 : y2[re[step]];\n                x0 = 0;\n                for (int i = 0; i < N; i++)\n                    if (placed[i] && y0 < y2[i] && y0 + h > y1[i]) x0 = max(x0, x2[i]);\n            }\n            x1[idx] = x0; y1[idx] = y0;\n            x2[idx] = x0 + w; y2[idx] = y0 + h;\n            placed[idx] = true;\n            W = max(W, x2[idx]); H = max(H, y2[idx]);\n        }\n        return W + H;\n    };\n    \n    for (int step = 1; step < N; step++) {\n        long long best = LLONG_MAX; int br = 0, bd = 0, bf = -1;\n        for (int r = 0; r < 2; r++) for (int d = 0; d < 2; d++) for (int rf : {-1, best_order[step-1]}) {\n            best_rot[step] = r; best_dir[step] = d; best_ref[step] = rf;\n            long long s = simulate(best_order, best_rot, best_dir, best_ref);\n            if (s < best) { best = s; br = r; bd = d; bf = rf; }\n        }\n        best_rot[step] = br; best_dir[step] = bd; best_ref[step] = bf;\n    }\n    \n    long long best_score = simulate(best_order, best_rot, best_dir, best_ref);\n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(2800);\n    uniform_real_distribution<double> uni(0.0, 1.0);\n    \n    for (int turn = 0; turn < T; turn++) {\n        auto ord = best_order, ro = best_rot, di = best_dir, re = best_ref;\n        long long curr_score = best_score;\n        for (int iter = 0; chrono::steady_clock::now() < deadline; iter++) {\n            auto new_ord = ord, new_ro = ro, new_di = di, new_re = re;\n            int op = rng() % 4;\n            if (op == 0 && N >= 2) { int i = 1 + rng() % (N-1), j = 1 + rng() % (N-1); swap(new_ord[i], new_ord[j]); }\n            else if (op == 1) { int s = rng() % N; new_ro[s] ^= 1; }\n            else if (op == 2) { int s = rng() % N; new_di[s] ^= 1; }\n            else { int s = rng() % N; new_re[s] = (s == 0 || uni(rng) < 0.3) ? -1 : new_ord[rng() % s]; }\n            \n            long long new_score = simulate(new_ord, new_ro, new_di, new_re);\n            double temp = max(1.0, 1e9 * exp(-iter / 5000.0));\n            if (new_score < curr_score || uni(rng) < exp(-(double)(new_score - curr_score) / temp)) {\n                ord = new_ord; ro = new_ro; di = new_di; re = new_re; curr_score = new_score;\n                if (new_score < best_score) {\n                    best_order = new_ord; best_rot = new_ro; best_dir = new_di; best_ref = new_re; best_score = new_score;\n                }\n            }\n        }\n        cout << N << \"\\n\";\n        for (int s = 0; s < N; s++) {\n            cout << best_order[s] << \" \" << best_rot[s] << \" \" << (best_dir[s] == 0 ? 'U' : 'L') << \" \" << best_ref[s] << \"\\n\";\n        }\n        cout.flush();\n        long long Wp, Hp; cin >> Wp >> Hp;\n    }\n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nint main() {\n    ios_base::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;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    vector<int> best_parent(N, -1);\n    long long best_score = 0;\n    \n    auto start_time = chrono::steady_clock::now();\n    double time_limit = 1.8;\n    \n    vector<int> sorted_by_beauty(N);\n    for (int i = 0; i < N; i++) sorted_by_beauty[i] = i;\n    sort(sorted_by_beauty.begin(), sorted_by_beauty.end(), [&](int a, int b) { return A[a] < A[b]; });\n    \n    while (true) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - start_time).count();\n        if (elapsed > time_limit) break;\n        \n        vector<int> parent(N, -1), height(N, -1);\n        vector<bool> assigned(N, false);\n        \n        vector<int> order = sorted_by_beauty;\n        shuffle(order.begin(), order.end(), rng);\n        \n        for (int v : order) {\n            if (assigned[v]) continue;\n            int best_p = -1, best_h = -1;\n            for (int u : adj[v]) {\n                if (assigned[u] && height[u] < H && height[u] + 1 > best_h) {\n                    best_h = height[u] + 1;\n                    best_p = u;\n                }\n            }\n            parent[v] = best_p;\n            height[v] = (best_p == -1) ? 0 : best_h;\n            assigned[v] = true;\n        }\n        \n        vector<vector<int>> children(N);\n        for (int v = 0; v < N; v++)\n            if (parent[v] != -1) children[parent[v]].push_back(v);\n        \n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int v = 0; v < N; v++) {\n                if (!children[v].empty()) continue;\n                int old_h = height[v], old_p = parent[v];\n                for (int u : adj[v]) {\n                    if (u == old_p || height[u] + 1 > H) continue;\n                    int new_h = height[u] + 1;\n                    if (new_h > old_h) {\n                        if (old_p != -1)\n                            children[old_p].erase(remove(children[old_p].begin(), children[old_p].end(), v), children[old_p].end());\n                        parent[v] = u;\n                        height[v] = new_h;\n                        children[u].push_back(v);\n                        improved = true;\n                        break;\n                    }\n                }\n            }\n        }\n        \n        long long score = 0;\n        for (int v = 0; v < N; v++) score += (long long)(height[v] + 1) * A[v];\n        \n        if (score > best_score) {\n            best_score = score;\n            best_parent = parent;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << best_parent[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n\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<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    vector<pair<int,int>> onis, fukus;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j] == 'x') onis.emplace_back(i, j);\n            else if (board[i][j] == 'o') fukus.emplace_back(i, j);\n    \n    int num_onis = onis.size();\n    vector<bool> safe_up(num_onis), safe_down(num_onis), safe_left(num_onis), safe_right(num_onis);\n    \n    for (int idx = 0; idx < num_onis; idx++) {\n        auto [i, j] = onis[idx];\n        safe_up[idx] = true; for (auto& [fi, fj] : fukus) if (fj == j && fi < i) { safe_up[idx] = false; break; }\n        safe_down[idx] = true; for (auto& [fi, fj] : fukus) if (fj == j && fi > i) { safe_down[idx] = false; break; }\n        safe_left[idx] = true; for (auto& [fi, fj] : fukus) if (fi == i && fj < j) { safe_left[idx] = false; break; }\n        safe_right[idx] = true; for (auto& [fi, fj] : fukus) if (fi == i && fj > j) { safe_right[idx] = false; break; }\n    }\n    \n    struct BatchOp { char dir; int idx; int cost; set<int> onis_removed; };\n    vector<BatchOp> ops;\n    \n    for (int j = 0; j < N; j++) {\n        set<int> batch; int max_row = -1;\n        for (int idx = 0; idx < num_onis; idx++)\n            if (onis[idx].second == j && safe_up[idx]) { batch.insert(idx); max_row = max(max_row, onis[idx].first); }\n        if (!batch.empty()) ops.push_back({'U', j, 2 * (max_row + 1), batch});\n    }\n    for (int j = 0; j < N; j++) {\n        set<int> batch; int min_row = N;\n        for (int idx = 0; idx < num_onis; idx++)\n            if (onis[idx].second == j && safe_down[idx]) { batch.insert(idx); min_row = min(min_row, onis[idx].first); }\n        if (!batch.empty()) ops.push_back({'D', j, 2 * (N - min_row), batch});\n    }\n    for (int i = 0; i < N; i++) {\n        set<int> batch; int max_col = -1;\n        for (int idx = 0; idx < num_onis; idx++)\n            if (onis[idx].first == i && safe_left[idx]) { batch.insert(idx); max_col = max(max_col, onis[idx].second); }\n        if (!batch.empty()) ops.push_back({'L', i, 2 * (max_col + 1), batch});\n    }\n    for (int i = 0; i < N; i++) {\n        set<int> batch; int min_col = N;\n        for (int idx = 0; idx < num_onis; idx++)\n            if (onis[idx].first == i && safe_right[idx]) { batch.insert(idx); min_col = min(min_col, onis[idx].second); }\n        if (!batch.empty()) ops.push_back({'R', i, 2 * (N - min_col), batch});\n    }\n    \n    set<int> remaining;\n    for (int idx = 0; idx < num_onis; idx++) remaining.insert(idx);\n    \n    vector<pair<char, int>> result;\n    \n    while (!remaining.empty()) {\n        int best_cnt = 0, best_cost = 1, best_op = -1;\n        for (int op_idx = 0; op_idx < (int)ops.size(); op_idx++) {\n            auto& op = ops[op_idx];\n            int cnt = 0;\n            for (int oni_idx : op.onis_removed) if (remaining.count(oni_idx)) cnt++;\n            if (cnt == 0) continue;\n            if (best_op == -1 || (long long)cnt * best_cost > (long long)best_cnt * op.cost) {\n                best_cnt = cnt; best_cost = op.cost; best_op = op_idx;\n            }\n        }\n        if (best_op == -1) break;\n        \n        auto& op = ops[best_op];\n        for (int oni_idx : op.onis_removed) remaining.erase(oni_idx);\n        \n        int shifts = op.cost / 2;\n        char d = op.dir, rev_d = (d == 'U' ? 'D' : d == 'D' ? 'U' : d == 'L' ? 'R' : 'L');\n        for (int k = 0; k < shifts; k++) result.emplace_back(d, op.idx);\n        for (int k = 0; k < shifts; k++) result.emplace_back(rev_d, op.idx);\n    }\n    \n    for (auto& [d, p] : result) cout << d << \" \" << p << \"\\n\";\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, L;\nint T[100], a[100], b[100], visits[100];\n\nlong long simulate() {\n    memset(visits, 0, sizeof(visits));\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        int t = ++visits[cur];\n        cur = (t & 1) ? a[cur] : b[cur];\n    }\n    long long err = 0;\n    for (int i = 0; i < n; i++) err += abs(visits[i] - T[i]);\n    return err;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> L;\n    for (int i = 0; i < n; i++) cin >> T[i];\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> urd(0.0, 1.0);\n    \n    // Initialize with cycle through all employees\n    for (int i = 0; i < n; i++) a[i] = b[i] = (i + 1) % n;\n    \n    long long cur_err = simulate(), best_err = cur_err;\n    int best_a[100], best_b[100];\n    memcpy(best_a, a, sizeof(a));\n    memcpy(best_b, b, sizeof(b));\n    \n    double temp = 100000.0;\n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(1800);\n    \n    while (chrono::steady_clock::now() < deadline) {\n        int i = rng() % n;\n        int old_a = a[i], old_b = b[i];\n        \n        // Randomly modify a[i] and/or b[i]\n        if (rng() & 1) a[i] = rng() % n;\n        if (rng() & 1) b[i] = rng() % n;\n        \n        long long new_err = simulate();\n        double delta = (double)(new_err - cur_err);\n        \n        // Accept if better or probabilistically based on temperature\n        if (delta < 0 || exp(-delta / temp) > urd(rng)) {\n            cur_err = new_err;\n            if (new_err < best_err) {\n                best_err = new_err;\n                memcpy(best_a, a, sizeof(a));\n                memcpy(best_b, b, sizeof(b));\n            }\n        } else {\n            a[i] = old_a; b[i] = old_b;\n        }\n        temp = max(1.0, temp * 0.995);\n    }\n    \n    for (int i = 0; i < n; i++) cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<double> cx, cy;\n\nstruct UnionFind {\n    vector<int> p, r;\n    UnionFind(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 x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (r[x] < r[y]) swap(x, y);\n        p[y] = x;\n        if (r[x] == r[y]) r[x]++;\n        return true;\n    }\n};\n\ndouble estDist(int i, int j) {\n    double dx = cx[i] - cx[j], dy = cy[i] - cy[j];\n    return sqrt(dx*dx + dy*dy);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        int lxi, rxi, lyi, ryi;\n        cin >> lxi >> rxi >> lyi >> ryi;\n        cx[i] = (lxi + rxi) / 2.0;\n        cy[i] = (lyi + ryi) / 2.0;\n    }\n    \n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [](int a, int b) {\n        return make_pair(cx[a], cy[a]) < make_pair(cx[b], cy[b]);\n    });\n    \n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; i++) {\n        groups[i].assign(order.begin() + idx, order.begin() + idx + G[i]);\n        idx += G[i];\n    }\n    \n    int qUsed = 0;\n    vector<vector<pair<int,int>>> ans(M);\n    \n    for (int g = 0; g < M; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        set<pair<int,int>> goodEdges;\n        \n        if (sz <= L && qUsed < Q) {\n            cout << \"? \" << sz;\n            for (int c : groups[g]) cout << \" \" << c;\n            cout << endl;\n            \n            for (int i = 0; i < sz - 1; i++) {\n                int a, b;\n                cin >> a >> b;\n                goodEdges.insert({min(a, b), max(a, b)});\n            }\n            qUsed++;\n        } else if (sz > L) {\n            for (int start = 0; start < sz && qUsed < Q; start += L - 1) {\n                int end = min(start + L, sz);\n                if (end - start < 2) break;\n                \n                cout << \"? \" << (end - start);\n                for (int i = start; i < end; i++) cout << \" \" << groups[g][i];\n                cout << endl;\n                \n                for (int i = 0; i < (end - start) - 1; i++) {\n                    int a, b;\n                    cin >> a >> b;\n                    goodEdges.insert({min(a, b), max(a, b)});\n                }\n                qUsed++;\n            }\n        }\n        \n        vector<tuple<double,int,int>> edges;\n        for (int i = 0; i < sz; i++) {\n            for (int j = i + 1; j < sz; j++) {\n                int ci = groups[g][i], cj = groups[g][j];\n                double d = estDist(ci, cj);\n                auto key = make_pair(min(ci, cj), max(ci, cj));\n                if (goodEdges.count(key)) d -= 1e9;\n                edges.push_back({d, i, j});\n            }\n        }\n        sort(edges.begin(), edges.end());\n        \n        UnionFind uf(sz);\n        for (auto& [d, i, j] : edges) {\n            if (uf.unite(i, j)) {\n                ans[g].push_back({groups[g][i], groups[g][j]});\n            }\n        }\n    }\n    \n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        for (int i = 0; i < (int)groups[g].size(); i++) {\n            if (i > 0) cout << \" \";\n            cout << groups[g][i];\n        }\n        cout << endl;\n        for (auto& [a, b] : ans[g]) {\n            cout << a << \" \" << b << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\npair<int, int> slide_end(int r, int c, int d, const vector<vector<bool>>& blocks) {\n    while (true) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N || blocks[nr][nc]) return {r, c};\n        r = nr; c = nc;\n    }\n}\n\nint get_dir_idx(char d) {\n    for (int i = 0; i < 4; i++) if (dir_char[i] == d) return i;\n    return -1;\n}\n\nvector<pair<char, char>> bfs(int sr, int sc, int tr, int tc, const vector<vector<bool>>& blocks) {\n    if (sr == tr && sc == tc) return {};\n    \n    vector<vector<int>> dist(N, vector<int>(N, -1));\n    vector<vector<tuple<int,int,char,char>>> prev(N, vector<tuple<int,int,char,char>>(N, {-1, -1, ' ', ' '}));\n    \n    queue<pair<int,int>> q;\n    q.push({sr, sc});\n    dist[sr][sc] = 0;\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == tr && c == tc) {\n            vector<pair<char, char>> path;\n            int cr = tr, cc = tc;\n            while (cr != sr || cc != sc) {\n                auto [pr, pc, a, d] = prev[cr][cc];\n                path.push_back({a, d});\n                cr = pr; cc = pc;\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \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 && !blocks[nr][nc] && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1;\n                prev[nr][nc] = {r, c, 'M', dir_char[d]};\n                q.push({nr, nc});\n            }\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            auto [nr, nc] = slide_end(r, c, d, blocks);\n            if (dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1;\n                prev[nr][nc] = {r, c, 'S', dir_char[d]};\n                q.push({nr, nc});\n            }\n        }\n    }\n    return {};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M;\n    vector<pair<int, int>> targets(M);\n    for (int i = 0; i < M; i++) cin >> targets[i].first >> targets[i].second;\n    \n    vector<vector<bool>> blocks(N, vector<bool>(N, false));\n    int cr = targets[0].first, cc = targets[0].second;\n    vector<pair<char, char>> actions;\n    \n    for (int t = 1; t < M; t++) {\n        int tr = targets[t].first, tc = targets[t].second;\n        auto path = bfs(cr, cc, tr, tc, blocks);\n        for (auto [a, d] : path) {\n            actions.push_back({a, d});\n            int di = get_dir_idx(d);\n            if (a == 'M') { cr += dr[di]; cc += dc[di]; }\n            else if (a == 'S') tie(cr, cc) = slide_end(cr, cc, di, blocks);\n        }\n    }\n    \n    for (auto [a, d] : actions) cout << a << ' ' << d << '\\n';\n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> X, Y;\nvector<long long> R;\nvector<int> a, b, c, d;\n\nvoid solve(int L, int Rb, int B, int T, vector<int> ids) {\n    if (ids.empty()) return;\n    \n    if (ids.size() == 1) {\n        int i = ids[0];\n        a[i] = L; b[i] = B; c[i] = Rb; d[i] = T;\n        return;\n    }\n    \n    int W = Rb - L, H = T - B;\n    bool vertical = (W >= H);\n    \n    sort(ids.begin(), ids.end(), [&](int i, int j) {\n        return vertical ? X[i] < X[j] : Y[i] < Y[j];\n    });\n    \n    long long total = 0;\n    for (int i : ids) total += R[i];\n    \n    long long acc = 0;\n    size_t splitIdx = ids.size();\n    \n    for (size_t idx = 0; idx + 1 < ids.size(); idx++) {\n        int leftVal = vertical ? X[ids[idx]] : Y[ids[idx]];\n        int rightVal = vertical ? X[ids[idx + 1]] : Y[ids[idx + 1]];\n        \n        if (leftVal < rightVal) {\n            if (splitIdx == ids.size() && acc * 2 >= total) {\n                splitIdx = idx + 1;\n            }\n        }\n        acc += R[ids[idx]];\n    }\n    \n    if (splitIdx == ids.size() || splitIdx == 0) {\n        for (size_t idx = 0; idx + 1 < ids.size(); idx++) {\n            int leftVal = vertical ? X[ids[idx]] : Y[ids[idx]];\n            int rightVal = vertical ? X[ids[idx + 1]] : Y[ids[idx + 1]];\n            if (leftVal < rightVal) {\n                splitIdx = idx + 1;\n                break;\n            }\n        }\n    }\n    if (splitIdx == ids.size() || splitIdx == 0) splitIdx = ids.size() / 2;\n    \n    vector<int> leftIds(ids.begin(), ids.begin() + splitIdx);\n    vector<int> rightIds(ids.begin() + splitIdx, ids.end());\n    \n    int leftMax = vertical ? X[ids[splitIdx - 1]] : Y[ids[splitIdx - 1]];\n    int rightMin = vertical ? X[ids[splitIdx]] : Y[ids[splitIdx]];\n    int split = (leftMax + rightMin + 1) / 2;\n    \n    if (vertical) {\n        split = max(L + 1, min(Rb - 1, split));\n        solve(L, split, B, T, leftIds);\n        solve(split, Rb, B, T, rightIds);\n    } else {\n        split = max(B + 1, min(T - 1, split));\n        solve(L, Rb, B, split, leftIds);\n        solve(L, Rb, split, T, rightIds);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    a.resize(n); b.resize(n); c.resize(n); d.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> X[i] >> Y[i] >> R[i];\n    }\n    \n    vector<int> ids(n);\n    iota(ids.begin(), ids.end(), 0);\n    \n    solve(0, 10000, 0, 10000, ids);\n    \n    for (int i = 0; i < n; i++) {\n        cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<vector<int>> t(50, vector<int>(50)), p(50, vector<int>(50));\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) cin >> t[i][j];\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) cin >> p[i][j];\n    \n    map<int, vector<pair<int,int>>> tileSquares;\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++)\n            tileSquares[t[i][j]].push_back({i, j});\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    set<int> visited;\n    string path;\n    int ci = si, cj = sj;\n    visited.insert(t[ci][cj]);\n    \n    auto& startSquares = tileSquares[t[ci][cj]];\n    if (startSquares.size() == 2) {\n        auto [oi, oj] = (startSquares[0].first == ci && startSquares[0].second == cj) \n            ? make_pair(startSquares[1].first, startSquares[1].second) \n            : make_pair(startSquares[0].first, startSquares[0].second);\n        path += (oi < ci ? 'U' : oi > ci ? 'D' : oj < cj ? 'L' : 'R');\n        ci = oi; cj = oj;\n    }\n    \n    while (true) {\n        int bestDir = -1, bestExitI = -1, bestExitJ = -1;\n        string bestTilePath;\n        double bestValue = -1e18;\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = ci + di[d], nj = cj + dj[d];\n            if (ni < 0 || ni >= 50 || nj < 0 || nj >= 50 || visited.count(t[ni][nj])) continue;\n            \n            int tileId = t[ni][nj];\n            auto& sq = tileSquares[tileId];\n            int tileScore = 0;\n            for (auto& [ti, tj] : sq) tileScore += p[ti][tj];\n            \n            for (size_t ei = 0; ei < sq.size(); ei++) {\n                int exi = sq[ei].first, exj = sq[ei].second;\n                visited.insert(tileId);\n                int future = 0;\n                for (int d2 = 0; d2 < 4; d2++) {\n                    int n2i = exi + di[d2], n2j = exj + dj[d2];\n                    if (n2i >= 0 && n2i < 50 && n2j >= 0 && n2j < 50 && !visited.count(t[n2i][n2j])) future++;\n                }\n                visited.erase(tileId);\n                \n                double value = tileScore + (future == 0 ? -1000.0 : future * 10.0);\n                string tilePath;\n                if (sq.size() == 2) {\n                    int oi = sq[1-ei].first, oj = sq[1-ei].second;\n                    if (ni == exi && nj == exj) {\n                        char to = (oi < exi ? 'U' : oi > exi ? 'D' : oj < exj ? 'L' : 'R');\n                        char back = (to == 'U' ? 'D' : to == 'D' ? 'U' : to == 'L' ? 'R' : 'L');\n                        tilePath = string(1, to) + string(1, back);\n                    } else {\n                        tilePath = string(1, (exi < ni ? 'U' : exi > ni ? 'D' : exj < nj ? 'L' : 'R'));\n                    }\n                }\n                if (value > bestValue) { bestValue = value; bestDir = d; bestExitI = exi; bestExitJ = exj; bestTilePath = tilePath; }\n            }\n        }\n        if (bestDir == -1) break;\n        visited.insert(t[ci + di[bestDir]][cj + dj[bestDir]]);\n        path += dc[bestDir]; path += bestTilePath;\n        ci = bestExitI; cj = bestExitJ;\n    }\n    cout << path << endl;\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 30;\n\ndouble h[N][N-1], v[N-1][N];\nint cnt_h[N][N-1], cnt_v[N-1][N];\n\nconst char dc[] = {'U', 'D', 'L', 'R'};\n\npair<string, vector<tuple<int,int,int>>> dijkstra(int si, int sj, int ti, int tj, double explore_mult) {\n    auto get_cost = [&](int type, int i, int j) -> double {\n        double mean = (type == 0) ? h[i][j] : v[i][j];\n        int cnt = (type == 0) ? cnt_h[i][j] : cnt_v[i][j];\n        // Scale exploration bonus by mean to handle varying edge lengths\n        double bonus = explore_mult * sqrt(mean / 5000.0) / sqrt(cnt + 1.0);\n        return mean - bonus;\n    };\n    \n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<int>> prev_dir(N, vector<int>(N, -1));\n    \n    priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n    dist[si][sj] = 0;\n    pq.push({0.0, si, sj});\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top(); pq.pop();\n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n        \n        if (i > 0) { double c = get_cost(1, i-1, j); if (dist[i-1][j] > d + c) { dist[i-1][j] = d + c; prev_dir[i-1][j] = 0; pq.push({dist[i-1][j], i-1, j}); } }\n        if (i < N-1) { double c = get_cost(1, i, j); if (dist[i+1][j] > d + c) { dist[i+1][j] = d + c; prev_dir[i+1][j] = 1; pq.push({dist[i+1][j], i+1, j}); } }\n        if (j > 0) { double c = get_cost(0, i, j-1); if (dist[i][j-1] > d + c) { dist[i][j-1] = d + c; prev_dir[i][j-1] = 2; pq.push({dist[i][j-1], i, j-1}); } }\n        if (j < N-1) { double c = get_cost(0, i, j); if (dist[i][j+1] > d + c) { dist[i][j+1] = d + c; prev_dir[i][j+1] = 3; pq.push({dist[i][j+1], i, j+1}); } }\n    }\n    \n    string path = \"\";\n    vector<tuple<int,int,int>> edges;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int dir = prev_dir[ci][cj];\n        path = dc[dir] + path;\n        if (dir == 0) { edges.push_back({1, ci, cj}); ci++; }\n        else if (dir == 1) { edges.push_back({1, ci-1, cj}); ci--; }\n        else if (dir == 2) { edges.push_back({0, ci, cj}); cj++; }\n        else { edges.push_back({0, ci, cj-1}); cj--; }\n    }\n    return {path, edges};\n}\n\nvoid update_estimates(const vector<tuple<int,int,int>>& edges, int observed) {\n    if (edges.empty()) return;\n    \n    double estimated_sum = 0;\n    for (auto [type, i, j] : edges) estimated_sum += (type == 0) ? h[i][j] : v[i][j];\n    \n    double ratio = observed / estimated_sum;\n    \n    for (auto [type, i, j] : edges) {\n        double& mean = (type == 0) ? h[i][j] : v[i][j];\n        int& cnt = (type == 0) ? cnt_h[i][j] : cnt_v[i][j];\n        cnt++;\n        \n        // Higher learning rate initially, decreasing with observations\n        double alpha = min(0.6, 0.6 / sqrt((double)cnt));\n        mean = mean * (1 - alpha) + mean * ratio * alpha;\n        \n        // Clamp to reasonable range based on problem constraints\n        mean = max(500.0, min(12000.0, mean));\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    // Initialize with middle of expected range\n    for (int i = 0; i < N; i++) for (int j = 0; j < N-1; j++) { h[i][j] = 5000.0; 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.0; cnt_v[i][j] = 0; }\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj; \n        cin >> si >> sj >> ti >> tj;\n        \n        // Strong exploration early (queries 0-200), then transition to exploitation\n        // Decay faster initially to quickly learn edge values\n        double explore = max(20.0, 800.0 * exp(-k / 80.0));\n        \n        auto [path, edges] = dijkstra(si, sj, ti, tj, explore);\n        \n        cout << path << endl;\n        cout.flush();\n        \n        int observed;\n        cin >> observed;\n        \n        update_estimates(edges, observed);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nint M;\nvector<string> s;\nvector<string> grid;\nvector<bitset<800>> cellToStrings;\nvector<bool> matched;\nmt19937 rng(42);\n\nbool matches(int r, int c, int dir, const string& str) {\n    int len = str.size();\n    for (int p = 0; p < len; p++) {\n        int nr = (dir == 0) ? r : (r + p) % N;\n        int nc = (dir == 0) ? (c + p) % N : c;\n        if (grid[nr][nc] != str[p]) return false;\n    }\n    return true;\n}\n\nbool stringMatches(int idx) {\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (matches(r, c, 0, s[idx]) || matches(r, c, 1, s[idx])) return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n >> M;\n    s.resize(M);\n    matched.resize(M);\n    for (int i = 0; i < M; i++) cin >> s[i];\n    \n    // Precompute which strings could include each cell\n    cellToStrings.resize(N * N);\n    for (int i = 0; i < M; i++) {\n        int len = s[i].size();\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                for (int p = 0; p < len; p++) {\n                    cellToStrings[r * N + ((c + p) % N)][i] = 1;\n                    cellToStrings[((r + p) % N) * N + c][i] = 1;\n                }\n            }\n        }\n    }\n    \n    // Voting initialization\n    vector<vector<array<int, 8>>> votes(N, vector<array<int, 8>>(N));\n    for (auto& str : s) {\n        int len = str.size();\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                for (int p = 0; p < len; p++) {\n                    votes[r][(c + p) % N][str[p] - 'A']++;\n                    votes[(r + p) % N][c][str[p] - 'A']++;\n                }\n            }\n        }\n    }\n    \n    grid.assign(N, string(N, '.'));\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            int maxVote = -1;\n            for (int ch = 0; ch < 8; ch++) {\n                if (votes[r][c][ch] > maxVote) {\n                    maxVote = votes[r][c][ch];\n                    grid[r][c] = 'A' + ch;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < M; i++) matched[i] = stringMatches(i);\n    int score = count(matched.begin(), matched.end(), true);\n    vector<string> bestGrid = grid;\n    int bestScore = score;\n    \n    // Simulated annealing with incremental updates\n    double T = 5.0;\n    for (int iter = 0; iter < 100000; iter++) {\n        int r = rng() % N;\n        int c = rng() % N;\n        char old = grid[r][c];\n        char newChar = 'A' + (rng() % 8);\n        if (newChar == old) continue;\n        \n        grid[r][c] = newChar;\n        \n        int delta = 0;\n        bitset<800>& affected = cellToStrings[r * N + c];\n        for (int i = 0; i < M; i++) {\n            if (affected[i]) {\n                bool was = matched[i];\n                bool now = stringMatches(i);\n                if (was && !now) delta--;\n                if (!was && now) delta++;\n                matched[i] = now;\n            }\n        }\n        \n        if (delta > 0 || (delta == 0 && (rng() % 2)) || \n            (delta < 0 && exp(delta / T) > (double)rng() / rng.max())) {\n            score += delta;\n            if (score > bestScore) { bestScore = score; bestGrid = grid; }\n        } else {\n            grid[r][c] = old;\n            for (int i = 0; i < M; i++) {\n                if (affected[i]) matched[i] = stringMatches(i);\n            }\n        }\n        T *= 0.99995;\n    }\n    \n    for (int r = 0; r < N; r++) cout << bestGrid[r] << '\\n';\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> grid;\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dc[] = {'U', 'D', 'L', 'R'};\n\ninline bool isRoad(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\ninline int w(int i, int j) { return grid[i][j] - '0'; }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    vector<pair<int,int>> roads;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (isRoad(i, j)) roads.push_back({i, j});\n    \n    int totalRoads = roads.size();\n    \n    vector<vector<vector<pair<int,int>>>> visList(N, vector<vector<pair<int,int>>>(N));\n    for (auto& [i, j] : roads) {\n        visList[i][j].push_back({i, j});\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            while (isRoad(ni, nj)) {\n                visList[i][j].push_back({ni, nj});\n                ni += di[d]; nj += dj[d];\n            }\n        }\n    }\n    \n    vector<vector<bool>> covered(N, vector<bool>(N, false));\n    int numCovered = 0;\n    \n    auto doCover = [&](int i, int j) {\n        if (!isRoad(i, j)) return;\n        for (auto& [ni, nj] : visList[i][j])\n            if (!covered[ni][nj]) { covered[ni][nj] = true; numCovered++; }\n    };\n    \n    auto countNewCover = [&](int i, int j) {\n        int cnt = 0;\n        for (auto& [ni, nj] : visList[i][j])\n            if (!covered[ni][nj]) cnt++;\n        return cnt;\n    };\n    \n    vector<vector<int>> dist(N, vector<int>(N));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N));\n    vector<vector<int>> parentDir(N, vector<int>(N));\n    \n    auto dijkstra = [&](int si, int sj) {\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) { dist[i][j] = INT_MAX; parent[i][j] = {-1, -1}; parentDir[i][j] = -1; }\n        priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n        dist[si][sj] = 0;\n        pq.push({0, si, sj});\n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top(); pq.pop();\n            if (d > dist[i][j]) continue;\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (isRoad(ni, nj)) {\n                    int nd = d + w(ni, nj);\n                    if (nd < dist[ni][nj]) {\n                        dist[ni][nj] = nd; parent[ni][nj] = {i, j}; parentDir[ni][nj] = k;\n                        pq.push({nd, ni, nj});\n                    }\n                }\n            }\n        }\n    };\n    \n    string route;\n    int ci = si, cj = sj;\n    doCover(ci, cj);\n    \n    while (numCovered < totalRoads) {\n        dijkstra(ci, cj);\n        int bestScore = -1, besti = -1, bestj = -1;\n        for (auto& [i, j] : roads) {\n            if (dist[i][j] == INT_MAX) continue;\n            int newC = countNewCover(i, j);\n            if (newC == 0) continue;\n            int score = newC * 10000 / max(1, dist[i][j]);\n            if (score > bestScore) { bestScore = score; besti = i; bestj = j; }\n        }\n        if (besti == -1) break;\n        \n        vector<int> pathDir;\n        int ti = besti, tj = bestj;\n        while (ti != ci || tj != cj) {\n            pathDir.push_back(parentDir[ti][tj]);\n            auto [pi, pj] = parent[ti][tj]; ti = pi; tj = pj;\n        }\n        reverse(pathDir.begin(), pathDir.end());\n        \n        for (int d : pathDir) {\n            route += dc[d]; ci += di[d]; cj += dj[d]; doCover(ci, cj);\n        }\n    }\n    \n    dijkstra(ci, cj);\n    vector<int> pathDir;\n    int ti = si, tj = sj;\n    while (ti != ci || tj != cj) {\n        pathDir.push_back(parentDir[ti][tj]);\n        auto [pi, pj] = parent[ti][tj]; ti = pi; tj = pj;\n    }\n    reverse(pathDir.begin(), pathDir.end());\n    for (int d : pathDir) route += dc[d];\n    \n    cout << route << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <set>\n#include <queue>\n#include <cmath>\n\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> d, deps, reverse_deps;\nvector<vector<double>> s_est;\nvector<int> in_degree, task_start_day, task_status, member_task, critical_len;\nset<int> ready_tasks;\n\nint estimate_time(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++)\n        w += max(0.0, (double)d[task][k] - s_est[member][k]);\n    return max(1, (int)(w + 0.5));\n}\n\nvoid update_skills(int member, int task, int duration) {\n    int w_est = max(0, duration - 2);\n    double cur_w = 0;\n    for (int k = 0; k < K; k++)\n        cur_w += max(0.0, (double)d[task][k] - s_est[member][k]);\n    \n    double error = w_est - cur_w;\n    if (error <= 0) return;\n    \n    int cnt = 0;\n    for (int k = 0; k < K; k++) if (d[task][k] > 0) cnt++;\n    if (cnt == 0) return;\n    \n    double dec = error / cnt;\n    for (int k = 0; k < K; k++)\n        if (d[task][k] > 0)\n            s_est[member][k] = max(0.0, s_est[member][k] - dec);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K >> R;\n    d.resize(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> d[i][k];\n    \n    deps.resize(N); reverse_deps.resize(N); in_degree.assign(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u); reverse_deps[u].push_back(v);\n        in_degree[v]++;\n    }\n    \n    vector<int> order, td = in_degree;\n    queue<int> q;\n    for (int i = 0; i < N; i++) if (td[i] == 0) q.push(i);\n    while (!q.empty()) {\n        int u = q.front(); q.pop(); order.push_back(u);\n        for (int v : reverse_deps[u]) if (--td[v] == 0) q.push(v);\n    }\n    \n    critical_len.assign(N, 0);\n    for (int i = N - 1; i >= 0; i--)\n        for (int v : reverse_deps[order[i]])\n            critical_len[order[i]] = max(critical_len[order[i]], critical_len[v] + 1);\n    \n    s_est.assign(M, vector<double>(K, 15.0));\n    task_status.assign(N, -1); task_start_day.assign(N, -1); member_task.assign(M, -1);\n    for (int i = 0; i < N; i++) if (in_degree[i] == 0) ready_tasks.insert(i);\n    \n    int day = 0;\n    while (true) {\n        day++;\n        vector<pair<int,int>> assignments;\n        set<int> assigned;\n        \n        while (true) {\n            double best_score = 1e18; int best_m = -1, best_t = -1;\n            for (int m = 0; m < M; m++) {\n                if (member_task[m] != -1) continue;\n                for (int t : ready_tasks) {\n                    if (assigned.count(t)) continue;\n                    double score = estimate_time(t, m) - critical_len[t] * 0.25;\n                    if (score < best_score) { best_score = score; best_m = m; best_t = t; }\n                }\n            }\n            if (best_m == -1) break;\n            assignments.push_back({best_m + 1, best_t + 1});\n            member_task[best_m] = best_t;\n            task_status[best_t] = 0;\n            task_start_day[best_t] = day;\n            assigned.insert(best_t);\n        }\n        \n        for (auto& p : assignments) ready_tasks.erase(p.second - 1);\n        \n        cout << assignments.size();\n        for (auto& p : assignments) cout << \" \" << p.first << \" \" << p.second;\n        cout << \"\\n\" << flush;\n        \n        int n; cin >> n;\n        if (n == -1) break;\n        \n        for (int i = 0; i < n; i++) {\n            int f; cin >> f; f--;\n            int task = member_task[f];\n            member_task[f] = -1;\n            int duration = day - task_start_day[task] + 1;\n            task_status[task] = 1;\n            update_skills(f, task, duration);\n            for (int v : reverse_deps[task]) {\n                in_degree[v]--;\n                if (in_degree[v] == 0 && task_status[v] == -1) ready_tasks.insert(v);\n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(42);\nconst int DEPOT = 400;\nconst double TIME_LIMIT = 1.85;\n\nint dist(int x1, int y1, int x2, int y2) { return abs(x1-x2) + abs(y1-y2); }\n\nstruct Solver {\n    vector<array<int,4>> orders;\n    vector<int> selected, route, pickup_pos, delivery_pos;\n    chrono::time_point<chrono::steady_clock> start_time;\n    int best_dist;\n    vector<int> best_selected, best_route;\n    \n    void read_input() {\n        orders.resize(1000);\n        for(int i=0;i<1000;i++) cin>>orders[i][0]>>orders[i][1]>>orders[i][2]>>orders[i][3];\n        start_time = chrono::steady_clock::now();\n    }\n    \n    double elapsed() { return chrono::duration<double>(chrono::steady_clock::now()-start_time).count(); }\n    \n    pair<int,int> get_coords(int loc) {\n        if(loc==-1) return {DEPOT,DEPOT};\n        if(loc<50) return {orders[selected[loc]][0], orders[selected[loc]][1]};\n        return {orders[selected[loc-50]][2], orders[selected[loc-50]][3]};\n    }\n    \n    int route_distance() {\n        int d=0;\n        for(int i=0;i+1<(int)route.size();i++) {\n            auto[x1,y1]=get_coords(route[i]); auto[x2,y2]=get_coords(route[i+1]);\n            d+=dist(x1,y1,x2,y2);\n        }\n        return d;\n    }\n    \n    void update_positions() {\n        pickup_pos.assign(50,-1); delivery_pos.assign(50,-1);\n        for(int k=0;k<(int)route.size();k++) {\n            int loc=route[k]; if(loc==-1) continue;\n            if(loc<50) pickup_pos[loc]=k; else delivery_pos[loc-50]=k;\n        }\n    }\n    \n    void save_best() { best_dist=route_distance(); best_selected=selected; best_route=route; }\n    void load_best() { selected=best_selected; route=best_route; update_positions(); }\n    \n    void select_orders_greedy() {\n        vector<pair<int,int>> scored;\n        for(int i=0;i<1000;i++) {\n            int ax=orders[i][0],ay=orders[i][1],bx=orders[i][2],by=orders[i][3];\n            scored.push_back({dist(DEPOT,DEPOT,ax,ay)+dist(ax,ay,bx,by)+dist(bx,by,DEPOT,DEPOT),i});\n        }\n        sort(scored.begin(),scored.end());\n        for(int i=0;i<50;i++) selected.push_back(scored[i].second);\n    }\n    \n    void build_route_nn() {\n        set<int> pending_pickups, pending_deliveries;\n        for(int i=0;i<50;i++) pending_pickups.insert(i);\n        route={-1}; int cx=DEPOT,cy=DEPOT;\n        while(!pending_pickups.empty()||!pending_deliveries.empty()) {\n            int best=-1,best_d=INT_MAX;\n            for(int i:pending_pickups) { auto[x,y]=get_coords(i); int d=dist(cx,cy,x,y); if(d<best_d){best_d=d;best=i;} }\n            for(int i:pending_deliveries) { auto[x,y]=get_coords(i+50); int d=dist(cx,cy,x,y); if(d<best_d){best_d=d;best=i+50;} }\n            route.push_back(best);\n            if(best<50){pending_pickups.erase(best);pending_deliveries.insert(best);}\n            else pending_deliveries.erase(best-50);\n            tie(cx,cy)=get_coords(best);\n        }\n        route.push_back(-1); update_positions();\n    }\n    \n    bool is_valid_2opt(int i,int j) {\n        for(int o=0;o<50;o++) {\n            int p=pickup_pos[o], d=delivery_pos[o];\n            bool pi=(p>=i&&p<=j), di=(d>=i&&d<=j);\n            if((pi&&di)||(pi&&d<i)||(di&&p>j)) return false;\n        }\n        return true;\n    }\n    \n    void local_search_2opt() {\n        int n=route.size(); bool improved=true;\n        while(improved) { improved=false;\n            for(int i=1;i<n-2;i++) for(int j=i+1;j<n-1;j++) {\n                if(!is_valid_2opt(i,j)) continue;\n                auto[xip,yip]=get_coords(route[i-1]); auto[xjn,yjn]=get_coords(route[j+1]);\n                auto[xi,yi]=get_coords(route[i]); auto[xj,yj]=get_coords(route[j]);\n                if(dist(xip,yip,xj,yj)+dist(xi,yi,xjn,yjn) < dist(xip,yip,xi,yi)+dist(xj,yj,xjn,yjn)) {\n                    reverse(route.begin()+i,route.begin()+j+1); update_positions(); improved=true; n=route.size(); break;\n                }\n                if(improved) break;\n            }\n        }\n    }\n    \n    void local_search_relocate() {\n        int n=route.size(); bool improved=true;\n        while(improved) { improved=false;\n            for(int i=1;i<n-1;i++) { int loc=route[i]; if(loc==-1) continue;\n                int ol=(loc<50)?loc:loc-50; bool is_p=loc<50;\n                int op=is_p?delivery_pos[ol]:pickup_pos[ol];\n                int minp=is_p?1:op+1, maxp=is_p?op-1:n-2;\n                for(int np=minp;np<=maxp;np++) { if(np==i||np==i-1) continue;\n                    auto[xp,yp]=get_coords(route[i-1]); auto[xc,yc]=get_coords(route[i]); auto[xn,yn]=get_coords(route[i+1]);\n                    int od=dist(xp,yp,xc,yc)+dist(xc,yc,xn,yn), ndr=dist(xp,yp,xn,yn);\n                    int ip=(np<i)?np+1:np; auto[xi,yi]=get_coords(route[ip-1]); auto[xin,yin]=get_coords(route[ip]);\n                    int odi=dist(xi,yi,xin,yin), ndi=dist(xi,yi,xc,yc)+dist(xc,yc,xin,yin);\n                    if(ndr+ndi<od+odi) {\n                        route.erase(route.begin()+i);\n                        if(np<i) route.insert(route.begin()+np+1,loc); else route.insert(route.begin()+np,loc);\n                        update_positions(); improved=true; n=route.size(); break;\n                    }\n                }\n                if(improved) break;\n            }\n        }\n    }\n    \n    void run_sa() {\n        set<int> sel_set(selected.begin(),selected.end()); save_best();\n        double temp=10000;\n        while(elapsed()<TIME_LIMIT) {\n            int old_dist=route_distance(); auto old_sel=selected, old_rt=route;\n            int out_idx=rng()%50, out_ord=selected[out_idx], in_ord;\n            do{in_ord=rng()%1000;}while(sel_set.count(in_ord));\n            sel_set.erase(out_ord); sel_set.insert(in_ord); selected[out_idx]=in_ord;\n            build_route_nn(); local_search_2opt(); local_search_relocate();\n            int new_dist=route_distance();\n            if(new_dist<old_dist || (double)(rng()%1000000)/1000000.0<exp(-(new_dist-old_dist)/temp)) {\n                if(new_dist<best_dist) save_best();\n            } else { sel_set.erase(in_ord); sel_set.insert(out_ord); selected=old_sel; route=old_rt; update_positions(); }\n            temp*=0.999;\n        }\n        load_best();\n    }\n    \n    void output() {\n        cout<<50; for(int i:selected) cout<<\" \"<<i+1; cout<<\"\\n\";\n        cout<<route.size(); for(int loc:route){auto[x,y]=get_coords(loc);cout<<\" \"<<x<<\" \"<<y;} cout<<\"\\n\";\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    Solver solver; solver.read_input(); solver.select_orders_greedy();\n    solver.build_route_nn(); solver.local_search_2opt(); solver.local_search_relocate(); solver.run_sa();\n    solver.output();\n    return 0;\n}","ahc007":"","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <set>\n#include <tuple>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char WALL[] = {'u', 'd', 'l', 'r'};\nconst char MOVE[] = {'U', 'D', 'L', 'R'};\n\nint N, M;\nvector<tuple<int,int,int>> pets_data;\nvector<pair<int,int>> humans_data;\n\nstruct Solver {\n    vector<vector<bool>> wall;\n    vector<tuple<int,int,int>> pets;\n    vector<pair<int,int>> humans;\n    \n    void init() {\n        wall.assign(SIZE, vector<bool>(SIZE, false));\n        pets = pets_data;\n        humans = humans_data;\n    }\n    \n    bool ok(int x, int y) const { return x >= 0 && x < SIZE && y >= 0 && y < SIZE; }\n    \n    bool petAt(int x, int y) const {\n        for (auto& [px, py, pt] : pets) if (px == x && py == y) return true;\n        return false;\n    }\n    \n    bool humanAt(int x, int y) const {\n        for (auto& [hx, hy] : humans) if (hx == x && hy == y) return true;\n        return false;\n    }\n    \n    bool nearPet(int x, int y) const {\n        for (int d = 0; d < 4; d++) if (petAt(x + dx[d], y + dy[d])) return true;\n        return false;\n    }\n    \n    bool canBuild(int h, int d, const set<pair<int,int>>& pw) const {\n        int x = humans[h].first + dx[d];\n        int y = humans[h].second + dy[d];\n        return ok(x, y) && !wall[x][y] && !petAt(x, y) && !humanAt(x, y) && !nearPet(x, y) && !pw.count({x, y});\n    }\n    \n    bool canMove(int h, int d, const set<pair<int,int>>& pw) const {\n        int x = humans[h].first + dx[d];\n        int y = humans[h].second + dy[d];\n        return ok(x, y) && !wall[x][y] && !pw.count({x, y});\n    }\n    \n    vector<vector<int>> dists(int sx, int sy) const {\n        vector<vector<int>> d(SIZE, vector<int>(SIZE, -1));\n        queue<pair<int,int>> q;\n        q.push({sx, sy});\n        d[sx][sy] = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            for (int i = 0; i < 4; i++) {\n                int nx = x + dx[i], ny = y + dy[i];\n                if (ok(nx, ny) && d[nx][ny] < 0 && !wall[nx][ny]) {\n                    d[nx][ny] = d[x][y] + 1;\n                    q.push({nx, ny});\n                }\n            }\n        }\n        return d;\n    }\n    \n    pair<int, vector<vector<bool>>> reach(int h) const {\n        int sx = humans[h].first, sy = humans[h].second;\n        vector<vector<bool>> vis(SIZE, vector<bool>(SIZE, false));\n        queue<pair<int,int>> q;\n        q.push({sx, sy});\n        vis[sx][sy] = true;\n        int cnt = 0;\n        while (!q.empty()) {\n            auto [x, y] = q.front(); q.pop();\n            cnt++;\n            for (int i = 0; i < 4; i++) {\n                int nx = x + dx[i], ny = y + dy[i];\n                if (ok(nx, ny) && !vis[nx][ny] && !wall[nx][ny]) {\n                    vis[nx][ny] = true;\n                    q.push({nx, ny});\n                }\n            }\n        }\n        return {cnt, vis};\n    }\n    \n    double calcScore(int h) const {\n        auto [area, vis] = reach(h);\n        int np = 0;\n        for (auto& [px, py, pt] : pets) if (vis[px][py]) np++;\n        return (double)area / (SIZE * SIZE) * pow(0.5, np);\n    }\n    \n    int minPetDist(int h) const {\n        auto d = dists(humans[h].first, humans[h].second);\n        int mnd = SIZE * SIZE;\n        for (auto& [px, py, pt] : pets) if (d[px][py] >= 0) mnd = min(mnd, d[px][py]);\n        return mnd;\n    }\n    \n    char decide(int h, const set<pair<int,int>>& pw, int turn) {\n        double best = -1e9;\n        char bestA = '.';\n        int bestD = -1;\n        int mpd = minPetDist(h);\n        \n        for (int d = 0; d < 4; d++) {\n            if (canBuild(h, d, pw)) {\n                int wx = humans[h].first + dx[d], wy = humans[h].second + dy[d];\n                wall[wx][wy] = true;\n                double s = calcScore(h);\n                wall[wx][wy] = false;\n                s += 0.0002 * mpd;\n                if (s > best) { best = s; bestA = WALL[d]; bestD = d; }\n            }\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            if (canMove(h, d, pw)) {\n                auto old = humans[h];\n                humans[h].first += dx[d]; humans[h].second += dy[d];\n                double s = calcScore(h);\n                int newMpd = minPetDist(h);\n                humans[h] = old;\n                if (newMpd > mpd) s += 0.001;\n                if (s > best) { best = s; bestA = MOVE[d]; bestD = d; }\n            }\n        }\n        return bestA;\n    }\n    \n    void apply(int h, char a, int d) {\n        if (a >= 'a' && a <= 'z') wall[humans[h].first + dx[d]][humans[h].second + dy[d]] = true;\n        else if (a != '.') { humans[h].first += dx[d]; humans[h].second += dy[d]; }\n    }\n    \n    void readPets() {\n        for (int i = 0; i < N; i++) {\n            string m; cin >> m;\n            auto& [px, py, pt] = pets[i];\n            for (char c : m) {\n                if (c == 'U') px--; else if (c == 'D') px++;\n                else if (c == 'L') py--; else if (c == 'R') py++;\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N; pets_data.resize(N);\n    for (int i = 0; i < N; i++) { int x, y, t; cin >> x >> y >> t; pets_data[i] = {x - 1, y - 1, t}; }\n    cin >> M; humans_data.resize(M);\n    for (int i = 0; i < M; i++) { int x, y; cin >> x >> y; humans_data[i] = {x - 1, y - 1}; }\n    \n    Solver sol; sol.init();\n    \n    for (int t = 0; t < 300; t++) {\n        string act(M, '.'); set<pair<int,int>> pw; vector<int> dirs(M, -1);\n        \n        for (int h = 0; h < M; h++) {\n            char a = sol.decide(h, pw, t); act[h] = a;\n            for (int d = 0; d < 4; d++) if (a == WALL[d] || a == MOVE[d]) { dirs[h] = d; break; }\n            if (dirs[h] >= 0 && act[h] >= 'a') pw.insert({sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]});\n        }\n        \n        // Resolve conflicts: if move targets a square being built on, cancel the move\n        set<pair<int,int>> builds;\n        for (int h = 0; h < M; h++) {\n            if (dirs[h] >= 0 && act[h] >= 'a' && act[h] <= 'z') {\n                builds.insert({sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]});\n            }\n        }\n        for (int h = 0; h < M; h++) {\n            if (dirs[h] >= 0 && act[h] >= 'A' && act[h] <= 'Z') {\n                pair<int,int> target = {sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]};\n                if (builds.count(target)) {\n                    act[h] = '.';\n                    dirs[h] = -1;\n                }\n            }\n        }\n        \n        for (int h = 0; h < M; h++) if (dirs[h] >= 0) sol.apply(h, act[h], dirs[h]);\n        cout << act << endl; cout.flush();\n        sol.readPets();\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj, ti, tj;\ndouble p, q; // q = 1-p\nvector<string> h(20), v(19);\nvector<vector<int>> dist_to_goal;\nconstexpr int di[] = {-1, 1, 0, 0};\nconstexpr int dj[] = {0, 0, -1, 1};\nconstexpr char dirs[] = \"UDLR\";\n\ninline bool can_move(int i, int j, int d) {\n    if (d == 0) return i > 0 && v[i-1][j] == '0';\n    if (d == 1) return i < 19 && v[i][j] == '0';\n    if (d == 2) return j > 0 && h[i][j-1] == '0';\n    return j < 19 && h[i][j] == '0';\n}\n\nvoid compute_dist() {\n    dist_to_goal.assign(20, vector<int>(20, 1000));\n    queue<pair<int,int>> qq;\n    qq.push({ti, tj});\n    dist_to_goal[ti][tj] = 0;\n    while (!qq.empty()) {\n        auto [i, j] = qq.front(); qq.pop();\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if (dist_to_goal[ni][nj] > dist_to_goal[i][j] + 1) {\n                dist_to_goal[ni][nj] = dist_to_goal[i][j] + 1;\n                qq.push({ni, nj});\n            }\n        }\n    }\n}\n\nstring bfs_path() {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<int>> pm(20, vector<int>(20, -1));\n    queue<pair<int,int>> qq;\n    qq.push({si, sj});\n    dist[si][sj] = 0;\n    while (!qq.empty()) {\n        auto [i, j] = qq.front(); qq.pop();\n        if (i == ti && j == tj) break;\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if (dist[ni][nj] < 0) {\n                dist[ni][nj] = dist[i][j] + 1;\n                pm[ni][nj] = d;\n                qq.push({ni, nj});\n            }\n        }\n    }\n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int d = pm[ci][cj];\n        path = dirs[d] + path;\n        ci -= di[d]; cj -= dj[d];\n    }\n    return path;\n}\n\ndouble simulate(const string& s) {\n    vector<double> prob(400, 0), np(400);\n    prob[si * 20 + sj] = 1.0;\n    double total = 0, reached = 0;\n    int goal = ti * 20 + tj;\n    \n    for (int t = 0; t < (int)s.size(); t++) {\n        fill(np.begin(), np.end(), 0);\n        int mv = string(\"UDLR\").find(s[t]);\n        \n        for (int idx = 0; idx < 400; idx++) {\n            if (prob[idx] < 1e-16) continue;\n            int i = idx / 20, j = idx % 20;\n            np[idx] += p * prob[idx];\n            int ni = i, nj = j;\n            if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n            np[ni * 20 + nj] += q * prob[idx];\n        }\n        swap(prob, np);\n        double nr = prob[goal] * (1 - reached);\n        total += nr * (401 - t - 1);\n        reached += nr;\n        prob[goal] = 0;\n    }\n    return total;\n}\n\nstring greedy_construct() {\n    vector<double> prob(400, 0), np(400);\n    prob[si * 20 + sj] = 1.0;\n    string result;\n    double reached = 0, total = 0;\n    int goal = ti * 20 + tj;\n    \n    for (int t = 0; t < 200; t++) {\n        double best = -1e18; int bm = 0;\n        \n        for (int mv = 0; mv < 4; mv++) {\n            double rp = 0, ed = 0;\n            for (int idx = 0; idx < 400; idx++) {\n                if (prob[idx] < 1e-16) continue;\n                int i = idx / 20, j = idx % 20;\n                ed += p * prob[idx] * dist_to_goal[i][j];\n                int ni = i, nj = j;\n                if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n                if (ni == ti && nj == tj) rp += q * prob[idx];\n                ed += q * prob[idx] * dist_to_goal[ni][nj];\n            }\n            double sc = rp * (401 - t - 1) * 5 - ed * (1 + p);\n            if (sc > best) { best = sc; bm = mv; }\n        }\n        result += dirs[bm];\n        \n        fill(np.begin(), np.end(), 0);\n        for (int idx = 0; idx < 400; idx++) {\n            if (prob[idx] < 1e-16) continue;\n            int i = idx / 20, j = idx % 20;\n            np[idx] += p * prob[idx];\n            int ni = i, nj = j;\n            if (can_move(i, j, bm)) { ni += di[bm]; nj += dj[bm]; }\n            np[ni * 20 + nj] += q * prob[idx];\n        }\n        swap(prob, np);\n        double nr = prob[goal] * (1 - reached);\n        total += nr * (401 - t - 1);\n        reached += nr;\n        prob[goal] = 0;\n    }\n    return result;\n}\n\nstring beam_search(int width) {\n    struct State {\n        string s;\n        vector<float> prob;\n        double score;\n    };\n    \n    vector<State> beam;\n    beam.push_back({{}, vector<float>(400, 0), 0});\n    beam[0].prob[si * 20 + sj] = 1.0;\n    int goal = ti * 20 + tj;\n    \n    for (int t = 0; t < 200; t++) {\n        vector<State> next;\n        next.reserve(beam.size() * 4);\n        \n        for (auto& st : beam) {\n            for (int mv = 0; mv < 4; mv++) {\n                State ns;\n                ns.s = st.s + dirs[mv];\n                ns.prob.assign(400, 0);\n                ns.score = st.score;\n                \n                double nr = 0;\n                for (int idx = 0; idx < 400; idx++) {\n                    if (st.prob[idx] < 1e-12f) continue;\n                    int i = idx / 20, j = idx % 20;\n                    ns.prob[idx] += p * st.prob[idx];\n                    int ni = i, nj = j;\n                    if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n                    int nidx = ni * 20 + nj;\n                    if (nidx == goal) nr += q * st.prob[idx];\n                    else ns.prob[nidx] += q * st.prob[idx];\n                }\n                ns.score += nr * (401 - t - 1);\n                next.push_back(move(ns));\n            }\n        }\n        \n        if ((int)next.size() > width) {\n            partial_sort(next.begin(), next.begin() + width, next.end(),\n                [](const State& a, const State& b) { return a.score > b.score; });\n            next.resize(width);\n        }\n        beam = move(next);\n    }\n    return beam[0].s;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> si >> sj >> ti >> tj >> p;\n    q = 1 - p;\n    for (int i = 0; i < 20; i++) cin >> h[i];\n    for (int i = 0; i < 19; i++) cin >> v[i];\n    compute_dist();\n    string path = bfs_path();\n    string best; double bsc = -1;\n    \n    auto try_s = [&](const string& s) { \n        double sc = simulate(s); \n        if (sc > bsc) { bsc = sc; best = s; } \n    };\n    \n    // Repeat whole path\n    { string s; while ((int)s.size() + (int)path.size() <= 200) s += path; try_s(s); }\n    \n    // Repeat each move r times\n    for (int r = 1; r <= 8; r++) {\n        string rb;\n        for (char c : path) rb += string(r, c);\n        string s; while ((int)s.size() + (int)rb.size() <= 200) s += rb;\n        if (!s.empty()) try_s(s);\n    }\n    \n    // Greedy\n    try_s(greedy_construct());\n    \n    // Beam search with different widths\n    try_s(beam_search(20));\n    try_s(beam_search(40));\n    \n    // Hybrid: repeat path prefix then greedy\n    for (int rep = 1; rep <= 3; rep++) {\n        string prefix;\n        for (int k = 0; k < rep && (int)prefix.size() < 180; k++)\n            for (char c : path) if ((int)prefix.size() < 180) prefix += c;\n        vector<double> prob(400, 0); prob[si * 20 + sj] = 1.0;\n        for (char mv : prefix) {\n            vector<double> np(400, 0);\n            int d = string(\"UDLR\").find(mv);\n            for (int idx = 0; idx < 400; idx++) {\n                if (prob[idx] < 1e-16) continue;\n                int i = idx / 20, j = idx % 20;\n                np[idx] += p * prob[idx];\n                int ni = i, nj = j;\n                if (can_move(i, j, d)) { ni += di[d]; nj += dj[d]; }\n                np[ni * 20 + nj] += q * prob[idx];\n            }\n            prob = np; prob[ti * 20 + tj] = 0;\n        }\n        // Continue with greedy\n        for (int t = prefix.size(); t < 200; t++) {\n            double best_sc = -1e18; int bm = 0;\n            for (int mv = 0; mv < 4; mv++) {\n                double ed = 0;\n                for (int idx = 0; idx < 400; idx++) {\n                    if (prob[idx] < 1e-16) continue;\n                    int i = idx / 20, j = idx % 20;\n                    ed += p * prob[idx] * dist_to_goal[i][j];\n                    int ni = i, nj = j;\n                    if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n                    ed += q * prob[idx] * dist_to_goal[ni][nj];\n                }\n                if (ed < best_sc) { best_sc = ed; bm = mv; }\n            }\n            prefix += dirs[bm];\n            vector<double> np(400, 0);\n            for (int idx = 0; idx < 400; idx++) {\n                if (prob[idx] < 1e-16) continue;\n                int i = idx / 20, j = idx % 20;\n                np[idx] += p * prob[idx];\n                int ni = i, nj = j;\n                if (can_move(i, j, bm)) { ni += di[bm]; nj += dj[bm]; }\n                np[ni * 20 + nj] += q * prob[idx];\n            }\n            prob = np; prob[ti * 20 + tj] = 0;\n        }\n        try_s(prefix);\n    }\n    \n    cout << best << endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint tiles[N][N], rotations[N][N], best_rotations[N][N];\nint di[] = {0, -1, 0, 1}, dj[] = {-1, 0, 1, 0};\nint to[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}};\nint rot_table[8][4];\n\nvoid init_rot_table() {\n    int rot[8] = {1,2,3,0,5,4,7,6};\n    for (int t = 0; t < 8; t++) {\n        rot_table[t][0] = t;\n        for (int r = 1; r < 4; r++) rot_table[t][r] = rot[rot_table[t][r-1]];\n    }\n}\n\nlong long compute_score() {\n    static bool visited[N][N][4];\n    memset(visited, 0, sizeof(visited));\n    int max1 = 0, max2 = 0;\n    \n    for (int si = 0; si < N; si++) {\n        for (int sj = 0; sj < N; sj++) {\n            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                \n                while (true) {\n                    if (visited[i][j][d]) { len = 0; break; }\n                    visited[i][j][d] = true;\n                    int t = rot_table[tiles[i][j]][rotations[i][j]];\n                    int d2 = to[t][d];\n                    if (d2 == -1) { len = 0; break; }\n                    i += di[d2]; j += dj[d2];\n                    if (i < 0 || i >= N || j < 0 || j >= N) { len = 0; break; }\n                    d = (d2 + 2) % 4; len++;\n                    if (i == si && j == sj && d == sd) break;\n                }\n                \n                if (len > max1) { max2 = max1; max1 = len; }\n                else if (len > max2) max2 = len;\n            }\n        }\n    }\n    return max2 == 0 ? 0 : (long long)max1 * max2;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    init_rot_table();\n    \n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) tiles[i][j] = s[j] - '0';\n    }\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> dist01(0.0, 1.0);\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) rotations[i][j] = rng() % 4;\n    \n    long long cur_score = compute_score(), best_score = cur_score;\n    memcpy(best_rotations, rotations, sizeof(rotations));\n    \n    double temp = 50000.0;\n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(1950);\n    \n    while (chrono::steady_clock::now() < deadline) {\n        int ri = rng() % N, rj = rng() % N;\n        int old_rot = rotations[ri][rj];\n        rotations[ri][rj] = rng() % 4;\n        \n        long long new_score = compute_score();\n        double delta = (double)(new_score - cur_score);\n        \n        if (delta >= 0 || dist01(rng) < exp(delta / temp)) {\n            cur_score = new_score;\n            if (cur_score > best_score) {\n                best_score = cur_score;\n                memcpy(best_rotations, rotations, sizeof(rotations));\n            }\n        } else rotations[ri][rj] = old_rot;\n        \n        temp *= 0.99992;\n    }\n    \n    string result;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) result += char('0' + best_rotations[i][j]);\n    cout << result << endl;\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> board;\nint er, ec;\nstring result;\n\nconst int DR[] = {0, -1, 0, 1};\nconst int DC[] = {-1, 0, 1, 0};\nconst char DCS[] = \"LURD\";\n\nint hval(char c) { return c >= 'a' ? c - 'a' + 10 : c - '0'; }\nbool ib(int r, int c) { return r >= 0 && r < N && c >= 0 && c < N; }\n\npair<int,int> evalFull() {\n    vector<int> comp(N*N, -1), compEdges(N*N, 0), compSize(N*N, 0);\n    int numComp = 0;\n    auto idx = [](int r, int c) { return r * N + c; };\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == '0' || comp[idx(i,j)] != -1) continue;\n            queue<pair<int,int>> q;\n            q.push({i,j});\n            comp[idx(i,j)] = numComp;\n            while (!q.empty()) {\n                auto [r,c] = q.front(); q.pop();\n                compSize[comp[idx(r,c)]]++;\n                int v = hval(board[r][c]);\n                auto tc = [&](int nr, int nc, int fb, int tb) {\n                    if (!ib(nr,nc) || board[nr][nc] == '0') return;\n                    int nv = hval(board[nr][nc]);\n                    if ((v & fb) && (nv & tb)) {\n                        compEdges[comp[idx(r,c)]]++;\n                        if (comp[idx(nr,nc)] == -1) {\n                            comp[idx(nr,nc)] = comp[idx(r,c)];\n                            q.push({nr,nc});\n                        }\n                    }\n                };\n                tc(r,c-1,1,4); tc(r-1,c,2,8); tc(r,c+1,4,1); tc(r+1,c,8,2);\n            }\n            numComp++;\n        }\n    }\n    \n    int best = 0, edges = 0;\n    for (int c = 0; c < numComp; c++) {\n        edges += compEdges[c] / 2;\n        if (compEdges[c]/2 == compSize[c] - 1)\n            best = max(best, compSize[c]);\n    }\n    return {best, edges};\n}\n\nint countEdges() {\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] == '0') continue;\n            int v = hval(board[i][j]);\n            if ((v & 4) && j+1 < N && board[i][j+1] != '0' && (hval(board[i][j+1]) & 1)) cnt++;\n            if ((v & 8) && i+1 < N && board[i+1][j] != '0' && (hval(board[i+1][j]) & 2)) cnt++;\n        }\n    }\n    return cnt;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> T;\n    board.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n        for (int j = 0; j < N; j++)\n            if (board[i][j] == '0') { er = i; ec = j; }\n    }\n    \n    mt19937 rng(42);\n    \n    vector<string> bestBoard = board;\n    int bestEr = er, bestEc = ec;\n    string bestResult;\n    int bestTree = evalFull().first;\n    \n    int lastDir = -1;\n    \n    for (int step = 0; step < T && (int)result.size() < T; step++) {\n        vector<pair<int,int>> candidates;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = er + DR[d], nc = ec + DC[d];\n            if (!ib(nr, nc)) continue;\n            \n            int v = hval(board[nr][nc]);\n            int gain = 0;\n            \n            auto check = [&](int r, int c, int fb, int tb, int mul) {\n                if (!ib(r,c) || board[r][c] == '0') return;\n                int nv = hval(board[r][c]);\n                if ((v & fb) && (nv & tb)) gain += mul;\n            };\n            check(er, ec-1, 1, 4, 1);\n            check(er-1, ec, 2, 8, 1);\n            check(er, ec+1, 4, 1, 1);\n            check(er+1, ec, 8, 2, 1);\n            check(nr, nc-1, 1, 4, -1);\n            check(nr-1, nc, 2, 8, -1);\n            check(nr, nc+1, 4, 1, -1);\n            check(nr+1, nc, 8, 2, -1);\n            \n            if (d == (lastDir + 2) % 4) gain -= 3;\n            \n            candidates.push_back({d, gain});\n        }\n        \n        if (candidates.empty()) break;\n        \n        sort(candidates.begin(), candidates.end(), [](auto& a, auto& b) { return a.second > b.second; });\n        \n        int d;\n        double temp = max(0.1, 1.0 - (double)step / T * 0.9);\n        if (rng() % 100 < (int)(temp * 25) && candidates.size() > 1) {\n            d = candidates[1 + rng() % (candidates.size() - 1)].first;\n        } else {\n            d = candidates[0].first;\n        }\n        \n        int nr = er + DR[d], nc = ec + DC[d];\n        swap(board[er][ec], board[nr][nc]);\n        er = nr; ec = nc;\n        result += DCS[d];\n        lastDir = d;\n        \n        if (step % 15 == 14) {\n            auto [treeScore, _] = evalFull();\n            if (treeScore > bestTree) {\n                bestTree = treeScore;\n                bestBoard = board;\n                bestEr = er;\n                bestEc = ec;\n                bestResult = result;\n            }\n            if (treeScore == N*N - 1) { bestResult = result; break; }\n        }\n    }\n    \n    if (bestResult.empty()) bestResult = result;\n    cout << bestResult << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\ntypedef pair<ll, ll> PLL;\n\nll cross(PLL a, PLL b) {\n    return a.first * b.second - a.second * b.first;\n}\n\nint side(PLL p1, PLL p2, PLL q) {\n    PLL d = {p2.first - p1.first, p2.second - p1.second};\n    PLL e = {q.first - p1.first, q.second - p1.second};\n    ll c = cross(d, e);\n    if (c > 0) return 1;\n    if (c < 0) return -1;\n    return 0;\n}\n\nint N, K;\nint a[11];\nvector<PLL> S;\n\nint computeScore(const vector<pair<PLL, PLL>>& lines) {\n    map<vector<int>, int> cells;\n    for (const auto& s : S) {\n        vector<int> sides;\n        bool isCut = false;\n        for (const auto& [p1, p2] : lines) {\n            int sd = side(p1, p2, s);\n            if (sd == 0) { isCut = true; break; }\n            sides.push_back(sd);\n        }\n        if (!isCut) cells[sides]++;\n    }\n    int b[11] = {0};\n    for (const auto& [k, v] : cells) if (v >= 1 && v <= 10) b[v]++;\n    int score = 0;\n    for (int d = 1; d <= 10; d++) score += min(a[d], b[d]);\n    return score;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    S.resize(N);\n    for (int i = 0; i < N; i++) cin >> S[i].first >> S[i].second;\n    \n    mt19937_64 rng(12345);\n    uniform_int_distribution<ll> bigCoord(-1000000000, 1000000000);\n    \n    vector<pair<PLL, PLL>> bestCuts;\n    int bestScore = 0;\n    auto startTime = chrono::steady_clock::now();\n    auto timeout = chrono::milliseconds(2900);\n    \n    while (chrono::steady_clock::now() - startTime < timeout) {\n        vector<pair<PLL, PLL>> cuts;\n        int currentScore = computeScore(cuts);\n        \n        for (int cutNum = 0; cutNum < K; cutNum++) {\n            pair<PLL, PLL> bestCut = {{0, 0}, {1, 0}};\n            int bestNewScore = currentScore; bool found = false;\n            \n            for (int iter = 0; iter < 300; iter++) {\n                PLL p1, p2; int strat = rng() % 5;\n                if (strat <= 2 && N >= 2) {\n                    int i = rng() % N, j = rng() % N;\n                    if (i != j) {\n                        ll mx = S[i].first + S[j].first, my = S[i].second + S[j].second;\n                        ll dx = S[j].first - S[i].first, dy = S[j].second - S[i].second;\n                        p1 = {mx + dy, my - dx}; p2 = {mx - dy, my + dx};\n                    } else continue;\n                } else if (strat == 3 && N >= 1) {\n                    int i = rng() % N; ll dx = bigCoord(rng), dy = bigCoord(rng);\n                    if (dx == 0 && dy == 0) continue;\n                    p1 = {S[i].first - dx, S[i].second - dy};\n                    p2 = {S[i].first + dx, S[i].second + dy};\n                } else { p1 = {bigCoord(rng), bigCoord(rng)}; p2 = {bigCoord(rng), bigCoord(rng)}; }\n                if (p1 == p2) continue;\n                auto newCuts = cuts; newCuts.emplace_back(p1, p2);\n                int score = computeScore(newCuts);\n                if (score > bestNewScore) { bestNewScore = score; bestCut = {p1, p2}; found = true; }\n            }\n            if (found) { cuts.push_back(bestCut); currentScore = bestNewScore; }\n        }\n        \n        for (int ls = 0; ls < 10000; ls++) {\n            if (cuts.empty()) break;\n            int idx = rng() % cuts.size(); auto oldCut = cuts[idx];\n            PLL p1, p2; int strat = rng() % 5;\n            if (strat <= 2 && N >= 2) {\n                int i = rng() % N, j = rng() % N;\n                if (i != j) {\n                    ll mx = S[i].first + S[j].first, my = S[i].second + S[j].second;\n                    ll dx = S[j].first - S[i].first, dy = S[j].second - S[i].second;\n                    p1 = {mx + dy, my - dx}; p2 = {mx - dy, my + dx};\n                } else continue;\n            } else if (strat == 3 && N >= 1) {\n                int i = rng() % N; ll dx = bigCoord(rng), dy = bigCoord(rng);\n                if (dx == 0 && dy == 0) continue;\n                p1 = {S[i].first - dx, S[i].second - dy}; p2 = {S[i].first + dx, S[i].second + dy};\n            } else { p1 = {bigCoord(rng), bigCoord(rng)}; p2 = {bigCoord(rng), bigCoord(rng)}; }\n            if (p1 == p2) continue;\n            cuts[idx] = {p1, p2}; int score = computeScore(cuts);\n            if (score >= currentScore) currentScore = score;\n            else cuts[idx] = oldCut;\n        }\n        if (currentScore > bestScore) { bestScore = currentScore; bestCuts = cuts; }\n    }\n    \n    cout << bestCuts.size() << \"\\n\";\n    for (const auto& [p1, p2] : bestCuts)\n        cout << p1.first << \" \" << p1.second << \" \" << p2.first << \" \" << p2.second << \"\\n\";\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble C;\nvector<vector<bool>> dot;\nset<tuple<int,int,int,int>> used_edges;\nvector<array<int,8>> ops;\nchrono::steady_clock::time_point T0;\n\ndouble elapsed() { return chrono::duration<double>(chrono::steady_clock::now() - T0).count(); }\nint wt(int x, int y) { return (x-C)*(x-C) + (y-C)*(y-C) + 1; }\nbool inB(int x, int y) { return x >= 0 && x < N && y >= 0 && y < N; }\n\nauto normE(int x1, int y1, int x2, int y2) {\n    if (make_pair(x1,y1) > make_pair(x2,y2)) swap(x1,y1), swap(x2,y2);\n    return make_tuple(x1,y1,x2,y2);\n}\n\nbool segClear(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    dx /= g; dy /= g;\n    for (int x = x1+dx, y = y1+dy; x != x2 || y != y2; x += dx, y += dy)\n        if (dot[x][y]) return false;\n    return true;\n}\n\nbool tryRect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    vector<pair<int,int>> P = {{x1,y1},{x2,y2},{x3,y3},{x4,y4}};\n    vector<int> ord = {0,1,2,3};\n    do {\n        int px[4], py[4];\n        for (int i = 0; i < 4; i++) tie(px[i], py[i]) = P[ord[i]];\n        if (dot[px[0]][py[0]]) continue;\n        if (!dot[px[1]][py[1]] || !dot[px[2]][py[2]] || !dot[px[3]][py[3]]) continue;\n        bool ok = true; vector<tuple<int,int,int,int>> E;\n        for (int i = 0; i < 4 && ok; i++) {\n            int dx = px[(i+1)%4] - px[i], dy = py[(i+1)%4] - py[i];\n            if (dx == 0 && dy == 0) ok = false;\n            else if (!(dx == 0 || dy == 0) && abs(dx) != abs(dy)) ok = false;\n            if (ok) E.push_back(normE(px[i], py[i], px[(i+1)%4], py[(i+1)%4]));\n        }\n        if (!ok) continue;\n        for (int i = 0; i < 4 && ok; i++) {\n            int dx1 = px[(i+1)%4] - px[i], dy1 = py[(i+1)%4] - py[i];\n            int dx2 = px[(i+2)%4] - px[(i+1)%4], dy2 = py[(i+2)%4] - py[(i+1)%4];\n            if (dx1*dx2 + dy1*dy2 != 0) ok = false;\n        }\n        if (!ok) continue;\n        for (int i = 0; i < 4 && ok; i++)\n            if (!segClear(px[i], py[i], px[(i+1)%4], py[(i+1)%4])) ok = false;\n        if (!ok) continue;\n        for (auto& e : E) if (used_edges.count(e)) { ok = false; break; }\n        if (!ok) continue;\n        dot[px[0]][py[0]] = true;\n        for (auto& e : E) used_edges.insert(e);\n        ops.push_back({px[0], py[0], px[1], py[1], px[2], py[2], px[3], py[3]});\n        return true;\n    } while (next_permutation(ord.begin(), ord.end()));\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    T0 = chrono::steady_clock::now();\n    cin >> N >> M; C = (N - 1) / 2.0;\n    dot.assign(N, vector<bool>(N, false));\n    for (int i = 0; i < M; i++) { int x, y; cin >> x >> y; dot[x][y] = true; }\n    vector<vector<int>> R(N), Cc(N), Dp(2*N), Dm(2*N);\n    for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (dot[x][y]) {\n        R[y].push_back(x); Cc[x].push_back(y);\n        Dp[x+y].push_back(x); Dm[x-y+N-1].push_back(x);\n    }\n    while (elapsed() < 4.5) {\n        vector<pair<int,int>> E;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (!dot[x][y]) E.push_back({x,y});\n        sort(E.begin(), E.end(), [](auto& a, auto& b) { return wt(a.first,a.second) > wt(b.first,b.second); });\n        bool found = false;\n        for (auto& [nx, ny] : E) {\n            for (int x2 : R[ny]) { if (x2 == nx) continue;\n                for (int y3 : Cc[nx]) { if (y3 == ny) continue;\n                    if (dot[x2][y3] && tryRect(nx, ny, x2, ny, x2, y3, nx, y3)) {\n                        R[ny].push_back(nx); Cc[nx].push_back(ny);\n                        Dp[nx+ny].push_back(nx); Dm[nx-ny+N-1].push_back(nx);\n                        found = true; goto next;\n                    }\n                }\n            }\n            int ds = nx + ny, dm = nx - ny + N - 1;\n            for (int x2 : Dm[dm]) { int y2 = x2 - (nx - ny); if (x2 == nx) continue;\n                for (int x4 : Dp[ds]) { int y4 = ds - x4; if (x4 == nx) continue;\n                    int x3 = x2 + x4 - nx, y3 = y2 + y4 - ny;\n                    if (inB(x3, y3) && dot[x3][y3] && tryRect(nx, ny, x2, y2, x3, y3, x4, y4)) {\n                        R[ny].push_back(nx); Cc[nx].push_back(ny);\n                        Dp[nx+ny].push_back(nx); Dm[nx-ny+N-1].push_back(nx);\n                        found = true; goto next;\n                    }\n                }\n            }\n        }\n        next:; if (!found) break;\n    }\n    cout << ops.size() << \"\\n\";\n    for (auto& o : ops) { for (int i = 0; i < 8; i++) cout << o[i] << \" \\n\"[i == 7]; }\n    return 0;\n}","ahc015":"#include <iostream>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nint flavors[100];\n\nvoid tilt(int g[N][N], int dir) {\n    int ng[N][N] = {};\n    if (dir == 0) { // F (up)\n        for (int c = 0; c < N; c++) {\n            int wr = 0;\n            for (int r = 0; r < N; r++)\n                if (g[r][c]) ng[wr++][c] = g[r][c];\n        }\n    } else if (dir == 1) { // B (down)\n        for (int c = 0; c < N; c++) {\n            int wr = N-1;\n            for (int r = N-1; r >= 0; r--)\n                if (g[r][c]) ng[wr--][c] = g[r][c];\n        }\n    } else if (dir == 2) { // L (left)\n        for (int r = 0; r < N; r++) {\n            int wc = 0;\n            for (int c = 0; c < N; c++)\n                if (g[r][c]) ng[r][wc++] = g[r][c];\n        }\n    } else { // R (right)\n        for (int r = 0; r < N; r++) {\n            int wc = N-1;\n            for (int c = N-1; c >= 0; c--)\n                if (g[r][c]) ng[r][wc--] = g[r][c];\n        }\n    }\n    memcpy(g, ng, sizeof(ng));\n}\n\nlong long calcScore(int g[N][N]) {\n    int vis[N][N] = {};\n    long long score = 0;\n    const int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n    \n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (!g[r][c] || vis[r][c]) continue;\n            int f = g[r][c], sz = 0;\n            int qr[100], qc[100], qh = 0, qt = 0;\n            qr[qt] = r; qc[qt++] = c; vis[r][c] = 1;\n            while (qh < qt) {\n                int cr = qr[qh], cc = qc[qh++];\n                sz++;\n                for (int d = 0; d < 4; d++) {\n                    int nr = cr + dr[d], nc = cc + dc[d];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && !vis[nr][nc] && g[nr][nc] == f) {\n                        vis[nr][nc] = 1; qr[qt] = nr; qc[qt++] = nc;\n                    }\n                }\n            }\n            score += (long long)sz * sz;\n        }\n    }\n    return score;\n}\n\nint main() {\n    for (int i = 0; i < 100; i++) cin >> flavors[i];\n    \n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        int cnt = 0;\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (!grid[r][c] && ++cnt == p) { grid[r][c] = flavors[t]; r = N; break; }\n            }\n        }\n        \n        long long best = -1; int bestDir = 0;\n        int temp[N][N];\n        for (int d = 0; d < 4; d++) {\n            memcpy(temp, grid, sizeof(grid));\n            tilt(temp, d);\n            long long score = calcScore(temp);\n            if (score > best) { best = score; bestDir = d; }\n        }\n        \n        tilt(grid, bestDir);\n        cout << \"FBLR\"[bestDir] << endl;\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint M, N, total_edges;\ndouble eps;\nvector<string> G;\nvector<int> edge_counts;\nvector<vector<int>> deg_seqs;\nvector<long long> tri_counts;\n\nint idx(int i, int j) {\n    if (i > j) swap(i, j);\n    return i * (2 * N - i - 1) / 2 + (j - i - 1);\n}\n\nlong long count_triangles(const string& g) {\n    long long cnt = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = i+1; j < N; j++)\n            if (g[idx(i,j)] == '1')\n                for (int k = j+1; k < N; k++)\n                    if (g[idx(i,k)] == '1' && g[idx(j,k)] == '1') cnt++;\n    return cnt;\n}\n\nvoid compute_features(int k) {\n    edge_counts[k] = count(G[k].begin(), G[k].end(), '1');\n    vector<int> deg(N, 0);\n    for (int i = 0; i < N; i++)\n        for (int j = i+1; j < N; j++)\n            if (G[k][idx(i,j)] == '1') { deg[i]++; deg[j]++; }\n    sort(deg.begin(), deg.end());\n    deg_seqs[k] = deg;\n    tri_counts[k] = count_triangles(G[k]);\n}\n\nvoid generate_graphs() {\n    total_edges = N * (N - 1) / 2;\n    G.assign(M, string(total_edges, '0'));\n    edge_counts.resize(M);\n    deg_seqs.assign(M, vector<int>(N));\n    tri_counts.resize(M);\n    \n    for (int k = 0; k < M; k++) {\n        double frac = (M > 1) ? (double)k / (M - 1) : 0.5;\n        int target = (int)round(frac * total_edges * 0.95 + total_edges * 0.025);\n        int added = 0;\n        \n        // Use different patterns based on k for structural diversity\n        if (k % 3 == 0) {\n            // Clique-based: dense cluster at start\n            int sz = min(N, (int)ceil(sqrt(2.0 * target)));\n            for (int i = 0; i < sz && added < target; i++)\n                for (int j = i+1; j < sz && added < target; j++, added++)\n                    G[k][idx(i,j)] = '1';\n        } else if (k % 3 == 1) {\n            // Star-based: one hub connected to many\n            int hub = k % N;\n            for (int j = 0; j < N && added < target; j++)\n                if (j != hub) { G[k][idx(hub,j)] = '1'; added++; }\n        }\n        // Fill remaining edges lexicographically\n        for (int i = 0; i < N && added < target; i++)\n            for (int j = i+1; j < N && added < target; j++)\n                if (G[k][idx(i,j)] == '0') { G[k][idx(i,j)] = '1'; added++; }\n        \n        compute_features(k);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> M >> eps;\n    \n    // Improved N selection\n    N = max(4, min(100, (int)ceil(sqrt(2.0*M) + M*0.15 + eps*25)));\n    if (M > 60) N = min(100, N + 5);\n    if (eps > 0.25) N = min(100, N + 8);\n    \n    generate_graphs();\n    \n    cout << N << \"\\n\";\n    for (int k = 0; k < M; k++) cout << G[k] << \"\\n\";\n    cout << flush;\n    \n    double scale = max(0.001, 1 - 2*eps);\n    long long total_tri = (long long)N*(N-1)*(N-2)/6;\n    double tri_factor = pow(1-eps,3) - pow(eps,3);\n    double edge_sd = sqrt(max(1.0, eps*(1-eps)*total_edges));\n    double tri_sd = sqrt(max(1.0, (double)total_tri*eps*(1-eps)));\n    \n    for (int q = 0; q < 100; q++) {\n        string H; cin >> H;\n        \n        int h_edges = count(H.begin(), H.end(), '1');\n        vector<int> h_deg(N, 0);\n        for (int i = 0; i < N; i++)\n            for (int j = i+1; j < N; j++)\n                if (H[idx(i,j)] == '1') { h_deg[i]++; h_deg[j]++; }\n        sort(h_deg.begin(), h_deg.end());\n        long long h_tri = count_triangles(H);\n        \n        int best = 0; double best_dist = 1e18;\n        for (int k = 0; k < M; k++) {\n            double exp_edges = edge_counts[k]*scale + eps*total_edges;\n            double edge_z = abs(h_edges - exp_edges) / edge_sd;\n            \n            double deg_dist = 0;\n            for (int i = 0; i < N; i++) {\n                double exp_deg = deg_seqs[k][i]*scale + eps*(N-1);\n                deg_dist += abs(h_deg[i] - exp_deg);\n            }\n            \n            double exp_tri = tri_counts[k]*tri_factor + total_tri*pow(eps,3);\n            double tri_z = abs(h_tri - exp_tri) / max(1.0, tri_sd);\n            \n            double dist = edge_z*10 + deg_dist*0.5 + tri_z*0.5;\n            if (dist < best_dist) { best_dist = dist; best = k; }\n        }\n        cout << best << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\ntypedef pair<ll, int> pli;\nconst ll INF = 1e18;\n\nint N, M, D, K;\nvector<int> eu, ev, ew;\nvector<vector<pair<int, int>>> adj;\n\nvector<ll> dijkstra(int s, int skip_edge = -1) {\n    vector<ll> dist(N, INF);\n    dist[s] = 0;\n    priority_queue<pli, vector<pli>, greater<pli>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist[u]) continue;\n        for (auto& [v, eid] : adj[u]) {\n            if (eid == skip_edge) continue;\n            ll nd = d + ew[eid];\n            if (dist[v] > nd) {\n                dist[v] = nd;\n                pq.push({nd, v});\n            }\n        }\n    }\n    return dist;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto start = chrono::steady_clock::now();\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    for (int i = 0; i < N; i++) { int x, y; cin >> x >> y; }\n    \n    // Compute edge betweenness (count all shortest paths using each edge)\n    vector<ll> betw(M, 0);\n    for (int s = 0; s < N; s++) {\n        vector<ll> dist(N, INF);\n        vector<vector<int>> pred(N);\n        dist[s] = 0;\n        priority_queue<pli, vector<pli>, greater<pli>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& [v, eid] : adj[u]) {\n                ll nd = d + ew[eid];\n                if (dist[v] > nd) {\n                    dist[v] = nd;\n                    pred[v].clear();\n                    pred[v].push_back(u);\n                    pq.push({nd, v});\n                } else if (dist[v] == nd) {\n                    pred[v].push_back(u);\n                }\n            }\n        }\n        for (int t = 0; t < N; t++) {\n            if (t == s || pred[t].empty()) continue;\n            vector<bool> vis(N, false);\n            queue<int> q; q.push(t); vis[t] = true;\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                for (int p : pred[u]) {\n                    for (auto& [v, eid] : adj[p]) if (v == u) { betw[eid]++; break; }\n                    if (!vis[p]) { vis[p] = true; q.push(p); }\n                }\n            }\n        }\n    }\n    \n    // Compute detour ratio for each edge\n    vector<ll> detour(M, 0);\n    int samples = min(M, 500);\n    vector<int> sample_edges(M);\n    iota(sample_edges.begin(), sample_edges.end(), 0);\n    shuffle(sample_edges.begin(), sample_edges.end(), mt19937(123));\n    sample_edges.resize(samples);\n    \n    for (int e : sample_edges) {\n        vector<ll> dist_u = dijkstra(eu[e], e);\n        detour[e] = dist_u[ev[e]];\n    }\n    \n    // Combined importance\n    vector<ll> imp(M);\n    ll max_betw = *max_element(betw.begin(), betw.end());\n    ll max_det = *max_element(detour.begin(), detour.end());\n    for (int e = 0; e < M; e++) {\n        imp[e] = betw[e] * 1000 / max(1LL, max_betw) + detour[e] * 100 / max(1LL, max_det);\n    }\n    \n    // Sort by importance\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) { return imp[a] > imp[b]; });\n    \n    // Assign to days greedily - minimize max day importance\n    vector<int> assign(M);\n    vector<int> cnt(D, 0);\n    vector<ll> day_imp(D, 0);\n    for (int e : order) {\n        int best = 0;\n        for (int d = 1; d < D; d++) {\n            if (cnt[d] < K && (cnt[best] >= K || day_imp[d] < day_imp[best])) best = d;\n        }\n        assign[e] = best;\n        cnt[best]++;\n        day_imp[best] += imp[e];\n    }\n    \n    // Local search\n    mt19937 rng(42);\n    uniform_int_distribution<int> de(0, M-1);\n    \n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() < 5700) {\n        int e1 = de(rng), e2 = de(rng);\n        int d1 = assign[e1], d2 = assign[e2];\n        if (d1 == d2) continue;\n        \n        ll old_var = 0, new_var = 0;\n        for (int d = 0; d < D; d++) {\n            old_var += day_imp[d] * day_imp[d];\n            ll nv = day_imp[d];\n            if (d == d1) nv = nv - imp[e1] + imp[e2];\n            if (d == d2) nv = nv - imp[e2] + imp[e1];\n            new_var += nv * nv;\n        }\n        \n        if (new_var < old_var) {\n            day_imp[d1] = day_imp[d1] - imp[e1] + imp[e2];\n            day_imp[d2] = day_imp[d2] - imp[e2] + imp[e1];\n            swap(assign[e1], assign[e2]);\n        }\n    }\n    \n    for (int i = 0; i < M; i++) cout << assign[i] + 1 << \" \\n\"[i == M-1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f[2], r[2];\nint valid[2][15][15][15];\nint visited[15][15][15];\nint b[2][15][15][15];\nint blockId;\n\nint dx[] = {1, -1, 0, 0, 0, 0};\nint dy[] = {0, 0, 1, -1, 0, 0};\nint dz[] = {0, 0, 0, 0, 1, -1};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> D;\n    for (int i = 0; i < 2; i++) {\n        f[i].resize(D);\n        r[i].resize(D);\n        for (int z = 0; z < D; z++) cin >> f[i][z];\n        for (int z = 0; z < D; z++) cin >> r[i][z];\n    }\n    \n    for (int i = 0; i < 2; i++) {\n        for (int x = 0; x < D; x++)\n            for (int y = 0; y < D; y++)\n                for (int z = 0; z < D; z++)\n                    valid[i][x][y][z] = (f[i][z][x] == '1' && r[i][z][y] == '1') ? 1 : 0;\n    }\n    \n    memset(b, 0, sizeof(b));\n    blockId = 0;\n    \n    // Process intersection (shared blocks)\n    memset(visited, 0, sizeof(visited));\n    for (int x = 0; x < D; x++)\n        for (int y = 0; y < D; y++)\n            for (int z = 0; z < D; z++)\n                if (valid[0][x][y][z] && valid[1][x][y][z] && !visited[x][y][z]) {\n                    blockId++;\n                    queue<array<int,3>> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = 1;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        b[0][cx][cy][cz] = blockId;\n                        b[1][cx][cy][cz] = blockId;\n                        for (int d = 0; d < 6; d++) {\n                            int nx = cx+dx[d], ny = cy+dy[d], nz = cz+dz[d];\n                            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D \n                                && !visited[nx][ny][nz] && valid[0][nx][ny][nz] && valid[1][nx][ny][nz]) {\n                                visited[nx][ny][nz] = 1;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                }\n    \n    // Process V_1 \\ I\n    memset(visited, 0, sizeof(visited));\n    for (int x = 0; x < D; x++)\n        for (int y = 0; y < D; y++)\n            for (int z = 0; z < D; z++)\n                if (valid[0][x][y][z] && !valid[1][x][y][z] && !visited[x][y][z]) {\n                    blockId++;\n                    queue<array<int,3>> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = 1;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        b[0][cx][cy][cz] = blockId;\n                        for (int d = 0; d < 6; d++) {\n                            int nx = cx+dx[d], ny = cy+dy[d], nz = cz+dz[d];\n                            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D \n                                && !visited[nx][ny][nz] && valid[0][nx][ny][nz] && !valid[1][nx][ny][nz]) {\n                                visited[nx][ny][nz] = 1;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                }\n    \n    // Process V_2 \\ I\n    memset(visited, 0, sizeof(visited));\n    for (int x = 0; x < D; x++)\n        for (int y = 0; y < D; y++)\n            for (int z = 0; z < D; z++)\n                if (!valid[0][x][y][z] && valid[1][x][y][z] && !visited[x][y][z]) {\n                    blockId++;\n                    queue<array<int,3>> q;\n                    q.push({x, y, z});\n                    visited[x][y][z] = 1;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        b[1][cx][cy][cz] = blockId;\n                        for (int d = 0; d < 6; d++) {\n                            int nx = cx+dx[d], ny = cy+dy[d], nz = cz+dz[d];\n                            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D \n                                && !visited[nx][ny][nz] && !valid[0][nx][ny][nz] && valid[1][nx][ny][nz]) {\n                                visited[nx][ny][nz] = 1;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                }\n    \n    cout << blockId << \"\\n\";\n    for (int x = 0; x < D; x++)\n        for (int y = 0; y < D; y++)\n            for (int z = 0; z < D; z++)\n                cout << (x||y||z ? \" \" : \"\") << b[0][x][y][z];\n    cout << \"\\n\";\n    for (int x = 0; x < D; x++)\n        for (int y = 0; y < D; y++)\n            for (int z = 0; z < D; z++)\n                cout << (x||y||z ? \" \" : \"\") << b[1][x][y][z];\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\ntypedef pair<ll, int> pli;\ntypedef pair<int, int> pii;\n\nint N, M, K;\nvector<int> x, y;\nvector<tuple<int, int, ll>> edges;\nvector<int> a, b;\nvector<vector<pii>> adj;\nvector<ll> distTo0;\nvector<int> parent, parent_edge;\n\nint calcDist(int x1, int y1, int x2, int y2) {\n    return (int)round(sqrt((ll)(x1-x2)*(x1-x2) + (ll)(y1-y2)*(y1-y2)));\n}\n\nvoid runDijkstra() {\n    distTo0.assign(N, LLONG_MAX);\n    parent.assign(N, -1);\n    parent_edge.assign(N, -1);\n    priority_queue<pli, vector<pli>, greater<pli>> pq;\n    distTo0[0] = 0; pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > distTo0[u]) continue;\n        for (auto [v, ej] : adj[u]) {\n            ll wj = get<2>(edges[ej]);\n            if (distTo0[u] + wj < distTo0[v]) {\n                distTo0[v] = distTo0[u] + wj;\n                parent[v] = u; parent_edge[v] = ej;\n                pq.push({distTo0[v], v});\n            }\n        }\n    }\n}\n\nvector<bool> getReachable(const vector<int>& B) {\n    vector<bool> visited(N, false);\n    queue<int> q; q.push(0); visited[0] = true;\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        for (auto [v, ej] : adj[u]) if (B[ej] && !visited[v]) { visited[v] = true; q.push(v); }\n    }\n    return visited;\n}\n\nll computeCost(const vector<int>& P, const vector<int>& B) {\n    ll cost = 0;\n    for (int i = 0; i < N; i++) cost += (ll)P[i] * P[i];\n    for (int j = 0; j < M; j++) if (B[j]) cost += get<2>(edges[j]);\n    return cost;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K;\n    x.resize(N); y.resize(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    edges.resize(M); adj.resize(N);\n    for (int j = 0; j < M; j++) {\n        int uj, vj; ll wj;\n        cin >> uj >> vj >> wj;\n        uj--; vj--;\n        edges[j] = {uj, vj, wj};\n        adj[uj].push_back({vj, j});\n        adj[vj].push_back({uj, j});\n    }\n    \n    a.resize(K); b.resize(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    runDijkstra();\n    \n    // Precompute distances from residents to stations\n    vector<vector<int>> resToStation(K, vector<int>(N));\n    for (int k = 0; k < K; k++) {\n        for (int i = 0; i < N; i++) {\n            resToStation[k][i] = calcDist(a[k], b[k], x[i], y[i]);\n        }\n    }\n    \n    // Initial assignment: nearest station\n    vector<int> station_power(N, 0);\n    vector<int> res_station(K);\n    for (int k = 0; k < K; k++) {\n        int best = 0, bestd = INT_MAX;\n        for (int i = 0; i < N; i++) {\n            if (resToStation[k][i] < bestd) { bestd = resToStation[k][i]; best = i; }\n        }\n        res_station[k] = best;\n        station_power[best] = max(station_power[best], bestd);\n    }\n    \n    // Build initial edge set\n    vector<int> B(M, 0);\n    auto updateEdges = [&](const vector<int>& active) {\n        fill(B.begin(), B.end(), 0);\n        for (int i : active) {\n            int cur = i;\n            while (parent[cur] != -1) { B[parent_edge[cur]] = 1; cur = parent[cur]; }\n        }\n    };\n    \n    vector<int> active;\n    for (int i = 0; i < N; i++) if (station_power[i] > 0) active.push_back(i);\n    updateEdges(active);\n    \n    // Remove redundant edges\n    auto removeRedundantEdges = [&]() {\n        vector<int> edge_order(M);\n        iota(edge_order.begin(), edge_order.end(), 0);\n        sort(edge_order.begin(), edge_order.end(), [&](int j1, int j2) {\n            return get<2>(edges[j1]) > get<2>(edges[j2]);\n        });\n        set<int> activeSet(active.begin(), active.end());\n        for (int j : edge_order) {\n            if (B[j] == 0) continue;\n            B[j] = 0;\n            auto visited = getReachable(B);\n            bool all_ok = true;\n            for (int i : activeSet) if (!visited[i]) { all_ok = false; break; }\n            if (!all_ok) B[j] = 1;\n        }\n    };\n    removeRedundantEdges();\n    \n    // Local search: try removing stations\n    sort(active.begin(), active.end(), [&](int i1, int i2) {\n        return (ll)station_power[i1]*station_power[i1] > (ll)station_power[i2]*station_power[i2];\n    });\n    \n    set<int> activeSet(active.begin(), active.end());\n    \n    for (int idx = 0; idx < (int)active.size(); idx++) {\n        int i = active[idx];\n        if (activeSet.find(i) == activeSet.end()) continue;\n        \n        auto reachable = getReachable(B);\n        \n        // Find residents covered by station i\n        vector<int> my_residents;\n        for (int k = 0; k < K; k++) {\n            if (res_station[k] == i) my_residents.push_back(k);\n        }\n        \n        // Try to reassign to other stations\n        vector<pair<int,int>> reassign;\n        bool ok = true;\n        \n        for (int k : my_residents) {\n            int best_j = -1;\n            ll best_cost = LLONG_MAX;\n            for (int j = 0; j < N; j++) {\n                if (j == i) continue;\n                int d = resToStation[k][j];\n                if (d > 5000) continue;\n                ll cost;\n                if (activeSet.count(j) || j == 0) {\n                    int new_p = max(station_power[j], d);\n                    cost = (ll)new_p*new_p - (ll)station_power[j]*station_power[j];\n                } else {\n                    cost = distTo0[j] + (ll)d*d;\n                }\n                if (cost < best_cost) { best_cost = cost; best_j = j; }\n            }\n            if (best_j == -1) { ok = false; break; }\n            reassign.push_back({best_j, resToStation[k][best_j]});\n        }\n        \n        if (ok) {\n            ll old_c = (ll)station_power[i]*station_power[i];\n            ll new_c = 0;\n            map<int,int> newP;\n            for (auto [j, d] : reassign) {\n                if (activeSet.count(j) || j == 0) {\n                    newP[j] = max(newP.count(j) ? newP[j] : station_power[j], d);\n                } else {\n                    newP[j] = d;\n                    new_c += distTo0[j];\n                }\n            }\n            for (auto& [j, np] : newP) {\n                if (activeSet.count(j) || j == 0) {\n                    new_c += (ll)np*np - (ll)station_power[j]*station_power[j];\n                } else {\n                    new_c += (ll)np*np;\n                }\n            }\n            \n            if (new_c < old_c) {\n                station_power[i] = 0;\n                activeSet.erase(i);\n                for (auto [j, d] : reassign) {\n                    station_power[j] = max(station_power[j], d);\n                    for (int k : my_residents) {\n                        if (resToStation[k][j] == d && res_station[k] == i) res_station[k] = j;\n                    }\n                    activeSet.insert(j);\n                }\n                vector<int> newActive(activeSet.begin(), activeSet.end());\n                updateEdges(newActive);\n                active = newActive;\n                removeRedundantEdges();\n            }\n        }\n    }\n    \n    // Final cleanup: reduce power if possible\n    for (int i = 0; i < N; i++) {\n        if (station_power[i] == 0) continue;\n        int maxd = 0;\n        for (int k = 0; k < K; k++) {\n            if (res_station[k] == i) maxd = max(maxd, resToStation[k][i]);\n        }\n        station_power[i] = maxd;\n    }\n    \n    for (int i = 0; i < N; i++) cout << station_power[i] << (i < N-1 ? \" \" : \"\\n\");\n    for (int j = 0; j < M; j++) cout << B[j] << (j < M-1 ? \" \" : \"\\n\");\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2;\n\nint pyramid[N][N];\nint pos[TOTAL];\nint dist[TOTAL], parent[TOTAL];\n\nint idx(int x, int y) { return x * (x + 1) / 2 + y; }\n\npair<int,int> coord(int i) {\n    int x = (int)(sqrt(2.0 * i + 0.25) - 0.5);\n    while (idx(x + 1, 0) <= i) x++;\n    return {x, i - idx(x, 0)};\n}\n\nvoid bfs(int s, int target) {\n    fill(dist, dist + TOTAL, -1);\n    fill(parent, parent + TOTAL, -1);\n    queue<int> q;\n    q.push(s);\n    dist[s] = 0;\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        auto [x, y] = coord(u);\n        vector<pair<int,int>> neighbors;\n        if (x > 0 && y > 0) neighbors.push_back({x-1, y-1});\n        if (x > 0 && y < x) neighbors.push_back({x-1, y});\n        if (y > 0) neighbors.push_back({x, y-1});\n        if (y < x) neighbors.push_back({x, y+1});\n        if (x < N-1) neighbors.push_back({x+1, y});\n        if (x < N-1) neighbors.push_back({x+1, y+1});\n        for (auto [nx, ny] : neighbors) {\n            int p = idx(nx, ny);\n            // Block positions that have their correct values and are before target\n            if (pyramid[nx][ny] == p && p < target) continue;\n            if (dist[p] == -1) {\n                dist[p] = dist[u] + 1;\n                parent[p] = u;\n                q.push(p);\n            }\n        }\n    }\n}\n\nint count_violations() {\n    int E = 0;\n    for (int x = 0; x < N-1; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) E++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) E++;\n        }\n    }\n    return E;\n}\n\nint count_edges(int x, int y) {\n    int cnt = 0;\n    if (x > 0) {\n        if (y > 0 && pyramid[x-1][y-1] > pyramid[x][y]) cnt++;\n        if (y < x && pyramid[x-1][y] > pyramid[x][y]) cnt++;\n    }\n    if (x < N-1) {\n        if (pyramid[x][y] > pyramid[x+1][y]) cnt++;\n        if (pyramid[x][y] > pyramid[x+1][y+1]) cnt++;\n    }\n    return cnt;\n}\n\nvector<pair<int,int>> get_neighbors(int x, int y) {\n    vector<pair<int,int>> neighbors;\n    if (x > 0 && y > 0) neighbors.push_back({x-1, y-1});\n    if (x > 0 && y < x) neighbors.push_back({x-1, y});\n    if (y > 0) neighbors.push_back({x, y-1});\n    if (y < x) neighbors.push_back({x, y+1});\n    if (x < N-1) neighbors.push_back({x+1, y});\n    if (x < N-1) neighbors.push_back({x+1, y+1});\n    return neighbors;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n            pos[pyramid[x][y]] = idx(x, y);\n        }\n    }\n    \n    vector<array<int,4>> moves;\n    \n    // Phase 1: Greedy placement with blocking\n    for (int v = 0; v < TOTAL && (int)moves.size() < 9800; v++) {\n        int cur = pos[v];\n        if (cur == v) continue;\n        \n        bfs(cur, v);\n        \n        if (dist[v] == -1) continue;\n        \n        vector<int> path;\n        for (int u = v; u != -1; u = parent[u]) path.push_back(u);\n        reverse(path.begin(), path.end());\n        \n        for (size_t i = 0; i+1 < path.size() && (int)moves.size() < 9800; i++) {\n            auto [x1, y1] = coord(path[i]);\n            auto [x2, y2] = coord(path[i+1]);\n            int v1 = pyramid[x1][y1], v2 = pyramid[x2][y2];\n            pos[v1] = path[i+1];\n            pos[v2] = path[i];\n            swap(pyramid[x1][y1], pyramid[x2][y2]);\n            moves.push_back({x1, y1, x2, y2});\n        }\n    }\n    \n    // Phase 2: Local improvement\n    while ((int)moves.size() < 10000) {\n        int best_delta = 0;\n        array<int, 4> best_move;\n        \n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y <= x; y++) {\n                auto neighbors = get_neighbors(x, y);\n                for (auto [nx, ny] : neighbors) {\n                    if (nx < x || (nx == x && ny < y)) continue;\n                    \n                    int before = count_edges(x, y) + count_edges(nx, ny);\n                    swap(pyramid[x][y], pyramid[nx][ny]);\n                    int after = count_edges(x, y) + count_edges(nx, ny);\n                    swap(pyramid[x][y], pyramid[nx][ny]);\n                    \n                    int delta = before - after;\n                    if (delta > best_delta) {\n                        best_delta = delta;\n                        best_move = {x, y, nx, ny};\n                    }\n                }\n            }\n        }\n        \n        if (best_delta <= 0) break;\n        \n        int x = best_move[0], y = best_move[1], nx = best_move[2], ny = best_move[3];\n        swap(pyramid[x][y], pyramid[nx][ny]);\n        moves.push_back(best_move);\n    }\n    \n    cout << moves.size() << \"\\n\";\n    for (auto& m : moves) {\n        cout << m[0] << \" \" << m[1] << \" \" << m[2] << \" \" << m[3] << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D, N;\n    cin >> D >> N;\n    \n    set<pair<int,int>> obstacles;\n    for (int i = 0; i < N; i++) {\n        int ri, rj; cin >> ri >> rj;\n        obstacles.insert({ri, rj});\n    }\n    \n    int entrance_j = (D - 1) / 2;\n    int M = D * D - 1 - N;\n    \n    vector<pair<int,int>> cells;\n    map<pair<int,int>, int> cell_to_idx;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (!(i == 0 && j == entrance_j) && !obstacles.count({i, j})) {\n                cell_to_idx[{i, j}] = cells.size();\n                cells.push_back({i, j});\n            }\n    \n    int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n    auto valid = [&](int i, int j) { return i >= 0 && i < D && j >= 0 && j < D; };\n    \n    vector<vector<int>> dist(D, vector<int>(D, INT_MAX));\n    queue<pair<int,int>> q; q.push({0, entrance_j}); dist[0][entrance_j] = 0;\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (valid(ni, nj) && dist[ni][nj] == INT_MAX && !obstacles.count({ni, nj})) {\n                dist[ni][nj] = dist[i][j] + 1; q.push({ni, nj});\n            }\n        }\n    }\n    \n    vector<int> downstream(cells.size(), 0);\n    for (size_t c = 0; c < cells.size(); c++) {\n        auto [ci, cj] = cells[c];\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<pair<int,int>> bq; bq.push({0, entrance_j});\n        visited[0][entrance_j] = true; visited[ci][cj] = true;\n        while (!bq.empty()) {\n            auto [i, j] = bq.front(); bq.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (valid(ni, nj) && !visited[ni][nj] && !obstacles.count({ni, nj})) {\n                    visited[ni][nj] = true; bq.push({ni, nj});\n                }\n            }\n        }\n        for (size_t cc = 0; cc < cells.size(); cc++)\n            if (!visited[cells[cc].first][cells[cc].second]) downstream[c]++;\n    }\n    \n    vector<int> order(cells.size()); iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        int da = dist[cells[a].first][cells[a].second], db = dist[cells[b].first][cells[b].second];\n        return da != db ? da < db : (downstream[a] != downstream[b] ? downstream[a] > downstream[b] : cells[a] < cells[b]);\n    });\n    vector<int> cell_rank(cells.size());\n    for (size_t i = 0; i < order.size(); i++) cell_rank[order[i]] = i;\n    \n    vector<int> container_at_cell(cells.size(), -1), container_cell(M, -1);\n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        vector<int> available;\n        for (size_t c = 0; c < cells.size(); c++) if (container_at_cell[c] == -1) available.push_back(c);\n        sort(available.begin(), available.end(), [&](int a, int b) { return cell_rank[a] < cell_rank[b]; });\n        int idx = (M == 1) ? 0 : min((int)available.size()-1, max(0, (int)round((double)t/(M-1)*(available.size()-1))));\n        container_at_cell[available[idx]] = t; container_cell[t] = available[idx];\n        cout << cells[available[idx]].first << \" \" << cells[available[idx]].second << \"\\n\" << flush;\n    }\n    \n    vector<bool> present(M, true);\n    for (int step = 0; step < M; step++) {\n        set<int> reachable;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<pair<int,int>> bq; bq.push({0, entrance_j}); visited[0][entrance_j] = true;\n        while (!bq.empty()) {\n            auto [i, j] = bq.front(); bq.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (!valid(ni, nj) || visited[ni][nj] || obstacles.count({ni, nj})) continue;\n                auto it = cell_to_idx.find({ni, nj});\n                if (it == cell_to_idx.end()) { visited[ni][nj] = true; bq.push({ni, nj}); }\n                else if (present[container_at_cell[it->second]]) reachable.insert(container_at_cell[it->second]);\n                else { visited[ni][nj] = true; bq.push({ni, nj}); }\n            }\n        }\n        int best = *reachable.begin(); present[best] = false;\n        cout << cells[container_cell[best]].first << \" \" << cells[container_cell[best]].second << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> g(n, vector<int>(n));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            cin >> g[i][j];\n    \n    int dx[] = {0, 0, 1, -1};\n    int dy[] = {1, -1, 0, 0};\n    auto inside = [&](int x, int y) { return x >= 0 && x < n && y >= 0 && y < n; };\n    \n    set<pair<int,int>> origAdj;\n    map<pair<int,int>, int> adjCnt;\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                int nc = inside(ni, nj) ? g[ni][nj] : 0;\n                if (nc != g[i][j]) {\n                    int a = g[i][j], b = nc;\n                    if (a > b) swap(a, b);\n                    origAdj.insert({a, b});\n                    adjCnt[{a, b}]++;\n                }\n            }\n        }\n    }\n    \n    auto connected = [&](int c) {\n        if (c == 0) return true;\n        int st = -1, cnt = 0;\n        for (int i = 0; i < n; i++)\n            for (int j = 0; j < n; j++)\n                if (g[i][j] == c) { if (st == -1) st = i*n+j; cnt++; }\n        if (cnt <= 1) return true;\n        queue<int> q; vector<bool> vis(n*n, false);\n        q.push(st); vis[st] = true;\n        int visCnt = 0;\n        while (!q.empty()) {\n            int cur = q.front(); q.pop(); visCnt++;\n            for (int d = 0; d < 4; d++) {\n                int nx = cur/n + dx[d], ny = cur%n + dy[d];\n                if (inside(nx, ny) && g[nx][ny] == c && !vis[nx*n+ny]) {\n                    vis[nx*n+ny] = true; q.push(nx*n+ny);\n                }\n            }\n        }\n        return visCnt == cnt;\n    };\n    \n    bool changed = true;\n    while (changed) {\n        changed = false;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (g[i][j] == 0) continue;\n                int c = g[i][j];\n                vector<pair<pair<int,int>, int>> delta;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    int nc = inside(ni, nj) ? g[ni][nj] : 0;\n                    if (nc != c) { int a=c,b=nc; if(a>b) swap(a,b); delta.push_back({{a,b},-1}); }\n                    if (nc != 0) { int a=0,b=nc; if(a>b) swap(a,b); delta.push_back({{a,b},1}); }\n                }\n                bool ok = true;\n                for (auto& [p, d] : delta) {\n                    int newCnt = adjCnt[p] + d;\n                    if (newCnt > 0 && !origAdj.count(p)) { ok = false; break; }\n                    if (newCnt == 0 && origAdj.count(p)) { ok = false; break; }\n                }\n                if (ok) {\n                    g[i][j] = 0;\n                    if (connected(c)) {\n                        for (auto& [p, d] : delta) adjCnt[p] += d;\n                        changed = true;\n                    } else { g[i][j] = c; }\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++)\n            cout << g[i][j] << (j == n-1 ? \"\\n\" : \" \");\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\nint N, D, Q;\nint qc = 0;\nvector<vector<int>> cmp_res;\n\nchar query(const vector<int>& L, const vector<int>& R) {\n    qc++;\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    char r; cin >> r;\n    return r;\n}\n\nint cmp_items(int a, int b) {\n    if (cmp_res[a][b] != 0) return cmp_res[a][b];\n    char r = query({a}, {b});\n    cmp_res[a][b] = (r == '<') ? 1 : (r == '=') ? 2 : 3;\n    cmp_res[b][a] = (r == '>') ? 1 : (r == '=') ? 2 : 3;\n    return cmp_res[a][b];\n}\n\nbool le(int a, int b) {\n    int r = cmp_items(a, b);\n    return r == 1 || r == 2;\n}\n\nvoid merge_sort(vector<int>& arr, int l, int r) {\n    if (l >= r) return;\n    int m = (l + r) / 2;\n    merge_sort(arr, l, m);\n    merge_sort(arr, m + 1, r);\n    vector<int> tmp;\n    int i = l, j = m + 1;\n    while (i <= m && j <= r) {\n        if (le(arr[i], arr[j])) tmp.push_back(arr[i++]);\n        else tmp.push_back(arr[j++]);\n    }\n    while (i <= m) tmp.push_back(arr[i++]);\n    while (j <= r) tmp.push_back(arr[j++]);\n    for (int k = l; k <= r; k++) arr[k] = tmp[k - l];\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    cmp_res.assign(N, vector<int>(N, 0));\n    \n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    merge_sort(order, 0, N - 1);\n    \n    vector<double> ew(N);\n    for (int i = 0; i < N; i++) ew[order[i]] = i + 1;\n    \n    vector<double> sw(D, 0);\n    vector<int> ans(N);\n    vector<vector<int>> sets(D);\n    \n    for (int i = N - 1; i >= 0; i--) {\n        int item = order[i];\n        int ms = 0;\n        for (int d = 1; d < D; d++) if (sw[d] < sw[ms]) ms = d;\n        ans[item] = ms;\n        sets[ms].push_back(item);\n        sw[ms] += ew[item];\n    }\n    \n    for (int d = 0; d < D; d++)\n        sort(sets[d].begin(), sets[d].end(), [&](int a, int b) { return ew[a] < ew[b]; });\n    \n    while (qc + 1 <= Q) {\n        int heavy = 0, light = 0;\n        for (int d = 1; d < D; d++) {\n            if (sw[d] > sw[heavy]) heavy = d;\n            if (sw[d] < sw[light]) light = d;\n        }\n        \n        if (heavy == light || sets[heavy].empty()) break;\n        \n        char result = query(sets[heavy], sets[light]);\n        if (result == '=') break;\n        if (result == '<') swap(heavy, light);\n        \n        int to_move = sets[heavy][0];\n        sets[heavy].erase(sets[heavy].begin());\n        \n        auto it = lower_bound(sets[light].begin(), sets[light].end(), to_move,\n                              [&](int a, int b) { return ew[a] < ew[b]; });\n        sets[light].insert(it, to_move);\n        \n        sw[heavy] -= ew[to_move];\n        sw[light] += ew[to_move];\n        ans[to_move] = light;\n    }\n    \n    while (qc < Q) query({0}, {1});\n    \n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << ans[i];\n    }\n    cout << \"\\n\" << flush;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> st(m);\n    for (int i = 0; i < m; i++) {\n        st[i].resize(n/m);\n        for (int j = 0; j < n/m; j++) {\n            cin >> st[i][j];\n        }\n    }\n    \n    vector<pair<int, int>> ops;\n    \n    for (int v = 1; v <= n; v++) {\n        // Find position of box v\n        int si = -1, pos = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)st[i].size(); j++) {\n                if (st[i][j] == v) {\n                    si = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (si != -1) break;\n        }\n        \n        if (si == -1) continue;\n        \n        // Move boxes above v if any\n        if (pos < (int)st[si].size() - 1) {\n            int maxMoved = INT_MIN, minMoved = INT_MAX;\n            for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                maxMoved = max(maxMoved, st[si][j]);\n                minMoved = min(minMoved, st[si][j]);\n            }\n            \n            // Find best destination using scoring heuristic\n            int dest = -1;\n            int bestScore = INT_MIN;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == si) continue;\n                \n                int score;\n                if (st[i].empty()) {\n                    score = 100;  // Empty stacks are good\n                } else {\n                    int top = st[i].back();\n                    if (top > maxMoved) {\n                        score = 200 + top;  // Best: all moved boxes smaller than top\n                    } else if (top < minMoved) {\n                        score = -1000;  // Worst: would block access to top\n                    } else {\n                        score = 50 - top;  // Mixed case\n                    }\n                }\n                \n                if (score > bestScore) {\n                    bestScore = score;\n                    dest = i;\n                }\n            }\n            \n            // Move all boxes above v to destination\n            int boxAbove = st[si][pos + 1];\n            ops.push_back({boxAbove, dest + 1});  // dest+1 for 1-indexed output\n            \n            for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                st[dest].push_back(st[si][j]);\n            }\n            st[si].resize(pos + 1);\n        }\n        \n        // Carry out box v (now at top)\n        ops.push_back({v, 0});\n        st[si].pop_back();\n    }\n    \n    for (auto& [a, b] : ops) {\n        cout << a << \" \" << b << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#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<string> h(N-1), v(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};\n    char dir[] = {'R', 'D', 'L', 'U'};\n    \n    auto canMove = [&](int i, int j, int k) -> bool {\n        int ni = i + di[k], nj = j + dj[k];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n        if (di[k] != 0) return h[min(i, ni)][j] == '0';\n        return v[i][min(j, nj)] == '0';\n    };\n    \n    vector visited(N, vector<bool>(N, false));\n    string tour;\n    \n    auto dfs = [&](auto& self, int i, int j) -> void {\n        visited[i][j] = true;\n        vector<tuple<int,int,int>> nb;\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (canMove(i, j, k) && !visited[ni][nj])\n                nb.emplace_back(-d[ni][nj], ni, nj);\n        }\n        sort(nb.begin(), nb.end());\n        for (auto [_, ni, nj] : nb) {\n            for (int k = 0; k < 4; k++)\n                if (i + di[k] == ni && j + dj[k] == nj) {\n                    tour += dir[k]; self(self, ni, nj); tour += dir[(k+2)%4];\n                    break;\n                }\n        }\n    };\n    dfs(dfs, 0, 0);\n    \n    vector dist0(N, vector<int>(N, -1)), prevDir(N, vector<int>(N, -1));\n    queue<pair<int,int>> q; q.push({0,0}); dist0[0][0] = 0;\n    while (!q.empty()) {\n        auto [i,j] = q.front(); q.pop();\n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (canMove(i,j,k) && dist0[ni][nj] < 0) {\n                dist0[ni][nj] = dist0[i][j] + 1; prevDir[ni][nj] = k; q.push({ni,nj});\n            }\n        }\n    }\n    \n    vector visitCount(N, vector<int>(N, 1));\n    int budget = 100000 - (int)tour.size();\n    priority_queue<tuple<double,int,int,int>> pq;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if ((i||j) && dist0[i][j] > 0) pq.push({(double)d[i][j]/2/dist0[i][j], 1, i, j});\n    }\n    \n    while (!pq.empty() && budget > 10) {\n        auto [score, vc, i, j] = pq.top(); pq.pop();\n        if (vc != visitCount[i][j]) continue;\n        int cost = 2 * dist0[i][j];\n        if (cost > budget) continue;\n        \n        string fwd; int ci = i, cj = j;\n        while (ci || cj) { int k = prevDir[ci][cj]; fwd += dir[k]; ci -= di[k]; cj -= dj[k]; }\n        reverse(fwd.begin(), fwd.end());\n        string back = fwd; reverse(back.begin(), back.end());\n        for (char& c : back) { if(c=='R')c='L'; else if(c=='L')c='R'; else if(c=='U')c='D'; else c='U'; }\n        \n        tour += fwd + back; visitCount[i][j]++; budget -= cost;\n        int nv = visitCount[i][j];\n        pq.push({(double)d[i][j]/(nv*(nv+1))/cost, nv, i, j});\n    }\n    \n    cout << tour << '\\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(nullptr);\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<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 * N + j);\n    \n    auto getCoord = [N](int idx) { return make_pair(idx / N, idx % N); };\n    \n    auto computeOverlap = [](const string& a, const string& b) {\n        for (int len = (int)min(a.size(), b.size()); len >= 0; len--) {\n            bool match = true;\n            for (int i = 0; i < len && match; i++)\n                if (a[a.size() - len + i] != b[i]) match = false;\n            if (match) return len;\n        }\n        return 0;\n    };\n    \n    string superstring = words[0];\n    vector<bool> used(M, false);\n    used[0] = true;\n    \n    for (int k = 1; k < M; k++) {\n        int best_idx = -1, best_overlap = -1;\n        bool appendBack = true;\n        \n        for (int i = 0; i < M; i++) {\n            if (used[i]) continue;\n            int o1 = computeOverlap(superstring, words[i]);\n            int o2 = computeOverlap(words[i], superstring);\n            if (o1 > best_overlap) { best_overlap = o1; best_idx = i; appendBack = true; }\n            if (o2 > best_overlap) { best_overlap = o2; best_idx = i; appendBack = false; }\n        }\n        \n        if (appendBack) superstring += words[best_idx].substr(best_overlap);\n        else superstring = words[best_idx] + superstring.substr(best_overlap);\n        used[best_idx] = true;\n    }\n    \n    int L = superstring.size();\n    vector<pair<int, int>> dp;\n    \n    for (int cell : charPos[superstring[0] - 'A']) {\n        auto [ci, cj] = getCoord(cell);\n        dp.emplace_back(cell, abs(ci - si) + abs(cj - sj) + 1);\n    }\n    \n    vector<unordered_map<int, int>> parent(L);\n    \n    for (int idx = 1; idx < L; idx++) {\n        vector<pair<int, int>> newDp;\n        for (int cell : charPos[superstring[idx] - 'A']) {\n            auto [ci, cj] = getCoord(cell);\n            int minCost = INT_MAX, bestPrev = -1;\n            for (auto& [prevCell, cost] : dp) {\n                auto [pi, pj] = getCoord(prevCell);\n                int newCost = cost + abs(ci - pi) + abs(cj - pj) + 1;\n                if (newCost < minCost) { minCost = newCost; bestPrev = prevCell; }\n            }\n            if (bestPrev != -1) {\n                newDp.emplace_back(cell, minCost);\n                parent[idx][cell] = bestPrev;\n            }\n        }\n        dp = move(newDp);\n    }\n    \n    int endCell = min_element(dp.begin(), dp.end(), [](auto& a, auto& b) { return a.second < b.second; })->first;\n    \n    vector<int> path(L);\n    path[L - 1] = endCell;\n    for (int idx = L - 2; idx >= 0; idx--)\n        path[idx] = parent[idx + 1][path[idx + 1]];\n    \n    for (int cell : path) {\n        auto [i, j] = getCoord(cell);\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<set<pair<int,int>>> shapes;\nvector<vector<int>> obs;\nint Q = 0;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> eps;\n    shapes.resize(M);\n    obs.assign(N, vector<int>(N, -1));\n    \n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        for (int i = 0; i < d; i++) {\n            int r, c; cin >> r >> c;\n            shapes[k].insert({r, c});\n        }\n    }\n    \n    auto drill = [&](int i, int j) -> int {\n        if (obs[i][j] != -1) return obs[i][j];\n        if (Q >= 2*N*N - 1) return -1;\n        cout << \"q 1 \" << i << \" \" << j << endl;\n        int r; cin >> r;\n        obs[i][j] = r;\n        Q++;\n        return r;\n    };\n    \n    auto divine = [&](const vector<pair<int,int>>& sq) -> int {\n        if (sq.size() < 2 || Q >= 2*N*N - 1) return -1;\n        cout << \"q \" << sq.size();\n        for (auto& p : sq) cout << \" \" << p.first << \" \" << p.second;\n        cout << endl;\n        int r; cin >> r;\n        Q++;\n        return r;\n    };\n    \n    auto getCoverage = [&]() -> vector<vector<double>> {\n        vector<vector<double>> cov(N, vector<double>(N, 0));\n        for (int k = 0; k < M; k++) {\n            int maxI = 0, maxJ = 0;\n            for (auto& p : shapes[k]) {\n                maxI = max(maxI, p.first);\n                maxJ = max(maxJ, p.second);\n            }\n            int validCount = 0;\n            vector<vector<bool>> validPlace(N, vector<bool>(N, false));\n            \n            for (int di = 0; di <= N-1-maxI; di++) {\n                for (int dj = 0; dj <= N-1-maxJ; dj++) {\n                    bool valid = true;\n                    for (auto& p : shapes[k]) {\n                        if (obs[p.first + di][p.second + dj] == 0) {\n                            valid = false;\n                            break;\n                        }\n                    }\n                    if (valid) {\n                        validCount++;\n                        for (auto& p : shapes[k]) {\n                            validPlace[p.first + di][p.second + dj] = true;\n                        }\n                    }\n                }\n            }\n            \n            if (validCount > 0) {\n                for (int i = 0; i < N; i++)\n                    for (int j = 0; j < N; j++)\n                        if (validPlace[i][j]) cov[i][j] += 1.0;\n            }\n        }\n        return cov;\n    };\n    \n    // Phase 1: Divine entire island (very cheap for large N)\n    vector<pair<int,int>> allSquares;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            allSquares.push_back({i,j});\n    \n    if (eps < 0.25 && Q < 2*N*N - 1) {\n        divine(allSquares);\n    }\n    \n    // Phase 2: Divine blocks to estimate local oil\n    int blockSize = max(3, N / 3);\n    vector<vector<double>> oilEst(N, vector<double>(N, 0.5));\n    \n    for (int bi = 0; bi < N && Q < N; bi += blockSize) {\n        for (int bj = 0; bj < N && Q < N; bj += blockSize) {\n            vector<pair<int,int>> block;\n            for (int i = bi; i < min(N, bi + blockSize); i++)\n                for (int j = bj; j < min(N, bj + blockSize); j++)\n                    if (obs[i][j] == -1) block.push_back({i, j});\n            \n            if (block.size() >= 2) {\n                int r = divine(block);\n                if (r >= 0 && block.size() > 0) {\n                    double est = max(0.0, min((double)block.size(), \n                        (r - block.size() * eps) / (1 - 2*eps)));\n                    double prob = est / block.size();\n                    for (auto& p : block)\n                        oilEst[p.first][p.second] = prob;\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Drill strategically\n    while (Q < N * N) {\n        auto cov = getCoverage();\n        \n        double bestScore = -1e18;\n        int bestI = -1, bestJ = -1;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (obs[i][j] == -1) {\n                    double score = cov[i][j] * (1 + oilEst[i][j]);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestI = i;\n                        bestJ = j;\n                    }\n                }\n            }\n        }\n        \n        if (bestI < 0) break;\n        int r = drill(bestI, bestJ);\n        if (r >= 0) oilEst[bestI][bestJ] = r > 0 ? 1.0 : 0.0;\n    }\n    \n    // Phase 4: Fill remaining\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (obs[i][j] == -1 && Q < 2*N*N - 1) drill(i, j);\n    \n    // Answer\n    vector<pair<int,int>> oil;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (obs[i][j] > 0) oil.push_back({i, j});\n    \n    cout << \"a \" << oil.size();\n    for (auto& p : oil) cout << \" \" << p.first << \" \" << p.second;\n    cout << endl;\n    int r; cin >> r;\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    vector<vector<array<int, 4>>> rect(D, vector<array<int, 4>>(N));\n    vector<int> prevH(N);\n    \n    for (int d = 0; d < D; d++) {\n        vector<int> h(N);\n        \n        // Check if previous heights work for current day\n        bool reuse = false;\n        if (d > 0) {\n            reuse = true;\n            for (int k = 0; k < N; k++) {\n                if ((long long)prevH[k] * W < a[d][k]) {\n                    reuse = false;\n                    break;\n                }\n            }\n        }\n        \n        if (reuse) {\n            h = prevH;\n        } else {\n            // Start with minimum height 1 for each rectangle\n            for (int k = 0; k < N; k++) h[k] = 1;\n            \n            // Priority queue for distributing remaining height (larger deficit first)\n            priority_queue<pair<long long, int>> pq;\n            for (int k = 0; k < N; k++) {\n                long long def = max(0LL, (long long)a[d][k] - W);\n                pq.push({def, k});\n            }\n            \n            int rem = W - N;\n            while (rem > 0) {\n                if (pq.empty() || pq.top().first == 0) {\n                    h[N-1] += rem;\n                    break;\n                }\n                auto [def, k] = pq.top(); pq.pop();\n                h[k]++;\n                rem--;\n                long long newDef = def - W;\n                if (newDef > 0) pq.push({newDef, k});\n            }\n            \n            int totalH = 0;\n            for (int k = 0; k < N; k++) totalH += h[k];\n            if (totalH < W) h[N-1] += W - totalH;\n        }\n        \n        int y = 0;\n        for (int k = 0; k < N; k++) {\n            rect[d][k] = {y, 0, y + h[k], W};\n            y += h[k];\n        }\n        \n        prevH = h;\n    }\n    \n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << rect[d][k][0] << \" \" << rect[d][k][1] << \" \"\n                 << rect[d][k][2] << \" \" << rect[d][k][3] << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <random>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\nconst long long MOD = 998244353;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nlong long board[N][N];\nlong long stamps[M][3][3];\nlong long current[N][N];\nlong long bestScore = 0;\nvector<tuple<int, int, int>> bestOps;\n\nvoid resetBoard() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            current[i][j] = board[i][j];\n}\n\nlong long computeScore() {\n    long long s = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            s += current[i][j] % MOD;\n    return s;\n}\n\nlong long computeGain(int s, int p, int q) {\n    long long gain = 0;\n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            long long oldRem = current[p + i][q + j] % MOD;\n            long long newRem = (current[p + i][q + j] + stamps[s][i][j]) % MOD;\n            gain += newRem - oldRem;\n        }\n    }\n    return gain;\n}\n\nvoid applyStamp(int s, int p, int q) {\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 3; j++)\n            current[p + i][q + j] += stamps[s][i][j];\n}\n\nvoid greedyRun(mt19937& rng, bool useLookahead, bool randomize) {\n    resetBoard();\n    vector<tuple<int, int, int>> ops;\n    \n    while ((int)ops.size() < K) {\n        vector<tuple<long long, int, int, int>> candidates;\n        \n        for (int s = 0; s < M; s++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    long long gain = computeGain(s, p, q);\n                    \n                    if (useLookahead && gain > -(long long)MOD / 10) {\n                        applyStamp(s, p, q);\n                        long long bestG2 = 0;\n                        for (int s2 = 0; s2 < M; s2++)\n                            for (int p2 = 0; p2 <= N - 3; p2++)\n                                for (int q2 = 0; q2 <= N - 3; q2++)\n                                    bestG2 = max(bestG2, computeGain(s2, p2, q2));\n                        for (int i = 0; i < 3; i++)\n                            for (int j = 0; j < 3; j++)\n                                current[p + i][q + j] -= stamps[s][i][j];\n                        gain = gain + bestG2 * 0.5;\n                    }\n                    \n                    if (gain > 0)\n                        candidates.emplace_back(gain, s, p, q);\n                }\n            }\n        }\n        \n        if (candidates.empty()) break;\n        \n        sort(candidates.begin(), candidates.end(), greater<>());\n        \n        int idx = 0;\n        if (randomize && candidates.size() > 1) {\n            uniform_int_distribution<int> dist(0, min(3, (int)candidates.size() - 1));\n            idx = dist(rng);\n        }\n        \n        auto [g, s, p, q] = candidates[idx];\n        ops.emplace_back(s, p, q);\n        applyStamp(s, p, q);\n    }\n    \n    long long score = computeScore();\n    if (score > bestScore) {\n        bestScore = score;\n        bestOps = ops;\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m, k;\n    cin >> n >> m >> k;\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cin >> board[i][j];\n    \n    for (int s = 0; s < M; s++)\n        for (int i = 0; i < 3; i++)\n            for (int j = 0; j < 3; j++)\n                cin >> stamps[s][i][j];\n    \n    resetBoard();\n    bestScore = computeScore();\n    \n    mt19937 rng(42);\n    \n    // Deterministic greedy first\n    greedyRun(rng, false, false);\n    \n    // Use lookahead\n    greedyRun(rng, true, false);\n    \n    // Randomized restarts\n    auto startTime = chrono::steady_clock::now();\n    int mode = 0;\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - startTime).count() < 1900) {\n        greedyRun(rng, mode % 2 == 0, true);\n        mode++;\n    }\n    \n    cout << bestOps.size() << \"\\n\";\n    for (const auto& [stamp, p, q] : bestOps) {\n        cout << stamp << \" \" << p << \" \" << q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <queue>\nusing namespace std;\n\nconst int N = 5;\nconst int MAXT = 10000;\nint A[N][N];\nint grid[N][N], cr[N], cc[N], ch[N], dnext[N], ridx[N];\nbool alive[N];\n\nbool occupied(int r, int c, int excl = -1) {\n    for (int i = 0; i < N; i++)\n        if (i != excl && alive[i] && cr[i] == r && cc[i] == c) return true;\n    return false;\n}\n\nbool canMove(int ci, int nr, int nc) {\n    if (nr < 0 || nr >= N || nc < 0 || nc >= N) return false;\n    if (occupied(nr, nc, ci)) return false;\n    if (ci != 0 && ch[ci] != -1 && grid[nr][nc] != -1) return false;\n    return true;\n}\n\nchar findMove(int ci, int tr, int tc) {\n    if (cr[ci] == tr && cc[ci] == tc) return '.';\n    static int dist[N][N]; static char first[N][N];\n    memset(dist, -1, sizeof(dist));\n    queue<pair<int,int>> q;\n    const int DR[] = {-1, 1, 0, 0}, DC[] = {0, 0, -1, 1};\n    const char D[] = {'U', 'D', 'L', 'R'};\n    for (int d = 0; d < 4; d++) {\n        int nr = cr[ci] + DR[d], nc = cc[ci] + DC[d];\n        if (canMove(ci, nr, nc)) { dist[nr][nc] = 1; first[nr][nc] = D[d]; q.push({nr, nc}); }\n    }\n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == tr && c == tc) return first[r][c];\n        for (int d = 0; d < 4; d++) {\n            int nr = r + DR[d], nc = c + DC[d];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && dist[nr][nc] == -1 && !occupied(nr, nc)) {\n                dist[nr][nc] = dist[r][c] + 1; first[nr][nc] = first[r][c]; q.push({nr, nc});\n            }\n        }\n    }\n    return '.';\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\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; alive[i] = true; ridx[i] = 0; dnext[i] = i * N; }\n    vector<string> out(N, \"\");\n    \n    for (int t = 0; t < MAXT; t++) {\n        string act(N, '.'); int newr[N], newc[N];\n        for (int i = 0; i < N; i++) { newr[i] = cr[i]; newc[i] = cc[i]; }\n        \n        for (int i = 0; i < N; i++)\n            if (ridx[i] < N && grid[i][0] == -1 && !occupied(i, 0)) grid[i][0] = A[i][ridx[i]++];\n        \n        for (int i = 0; i < N; i++) {\n            if (!alive[i]) continue;\n            if (ch[i] != -1) {\n                int tr = ch[i] / N; bool is_next = (ch[i] == dnext[tr]);\n                int sr = tr, sc = -1;\n                for (int c = N-2; c >= 1; c--) if (grid[sr][c] == -1 && !occupied(sr, c)) { sc = c; break; }\n                int dr = tr, dc = (is_next || sc == -1) ? N-1 : sc;\n                if (cr[i] == dr && cc[i] == dc) act[i] = 'Q';\n                else act[i] = findMove(i, dr, dc);\n                if (act[i] == 'U') newr[i]--; else if (act[i] == 'D') newr[i]++;\n                else if (act[i] == 'L') newc[i]--; else if (act[i] == 'R') newc[i]++;\n            } else {\n                if (grid[cr[i]][cc[i]] != -1) act[i] = 'P';\n                else {\n                    int bestc = -1, bestd = 100;\n                    for (int c = 0; c < N; c++) {\n                        if (grid[cr[i]][c] != -1 && (cr[i] != c || c != N-1)) {\n                            int d = abs(c - cc[i]); if (d < bestd) { bestd = d; bestc = c; }\n                        }\n                    }\n                    act[i] = findMove(i, cr[i], bestc != -1 ? bestc : 0);\n                    if (act[i] == 'U') newr[i]--; else if (act[i] == 'D') newr[i]++;\n                    else if (act[i] == 'L') newc[i]--; else if (act[i] == 'R') newc[i]++;\n                }\n            }\n        }\n        \n        for (int i = 0; i < N; i++) for (int j = i+1; j < N; j++) {\n            if (!alive[i] || !alive[j]) continue;\n            if (cr[i] == newr[j] && cc[i] == newc[j] && cr[j] == newr[i] && cc[j] == newc[i])\n                { act[j] = '.'; newr[j] = cr[j]; newc[j] = cc[j]; }\n        }\n        for (int i = 0; i < N; i++) for (int j = i+1; j < N; j++) {\n            if (!alive[i] || !alive[j]) continue;\n            if (newr[i] == newr[j] && newc[i] == newc[j])\n                { act[j] = '.'; newr[j] = cr[j]; newc[j] = cc[j]; }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            if (!alive[i]) continue;\n            if (act[i] == 'P' && ch[i] == -1 && grid[cr[i]][cc[i]] != -1) { ch[i] = grid[cr[i]][cc[i]]; grid[cr[i]][cc[i]] = -1; }\n            else if (act[i] == 'Q' && ch[i] != -1 && grid[cr[i]][cc[i]] == -1) { grid[cr[i]][cc[i]] = ch[i]; ch[i] = -1; }\n        }\n        for (int i = 0; i < N; i++) { if (!alive[i]) continue; if (!canMove(i, newr[i], newc[i])) { act[i] = '.'; newr[i] = cr[i]; newc[i] = cc[i]; } }\n        for (int i = 0; i < N; i++) { if (!alive[i]) continue; cr[i] = newr[i]; cc[i] = newc[i]; }\n        \n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) { int c = grid[i][N-1]; if (c == dnext[i]) dnext[i]++; grid[i][N-1] = -1; }\n        }\n        for (int i = 0; i < N; i++) out[i] += act[i];\n        \n        bool done = true;\n        for (int i = 0; i < N; i++) if (ridx[i] < N) done = false;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (grid[i][j] != -1) done = false;\n        for (int i = 0; i < N; i++) if (ch[i] != -1) done = false;\n        if (done) break;\n    }\n    for (int i = 0; i < N; i++) cout << out[i] << \"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\nlong long truck_load = 0;\nint cur_i = 0, cur_j = 0;\nvector<string> ops;\n\nvoid add_op(const string& s) { ops.push_back(s); }\n\nvoid move_to(int ni, int nj) {\n    while (cur_i < ni) { add_op(\"D\"); cur_i++; }\n    while (cur_i > ni) { add_op(\"U\"); cur_i--; }\n    while (cur_j < nj) { add_op(\"R\"); cur_j++; }\n    while (cur_j > nj) { add_op(\"L\"); cur_j--; }\n}\n\nint dist(int i1, int j1, int i2, int j2) {\n    return abs(i1 - i2) + abs(j1 - j2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cin >> h[i][j];\n    \n    while (true) {\n        bool has_pos = false, has_neg = false;\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) {\n                if (h[i][j] > 0) has_pos = true;\n                if (h[i][j] < 0) has_neg = true;\n            }\n        \n        if (!has_pos && !has_neg) break;\n        \n        if (truck_load == 0 && has_pos) {\n            long long best_cost = LLONG_MAX;\n            int best_i = -1, best_j = -1;\n            \n            for (int i = 0; i < N; i++)\n                for (int j = 0; j < N; j++)\n                    if (h[i][j] > 0) {\n                        int amt = h[i][j];\n                        int d1 = dist(cur_i, cur_j, i, j);\n                        \n                        int d2 = INT_MAX;\n                        for (int ii = 0; ii < N; ii++)\n                            for (int jj = 0; jj < N; jj++)\n                                if (h[ii][jj] < 0)\n                                    d2 = min(d2, dist(i, j, ii, jj));\n                        \n                        if (d2 == INT_MAX) d2 = 0;\n                        \n                        long long cost = 100LL * d1 + (100LL + amt) * d2;\n                        \n                        if (cost < best_cost) {\n                            best_cost = cost;\n                            best_i = i; best_j = j;\n                        }\n                    }\n            \n            if (best_i == -1) break;\n            \n            move_to(best_i, best_j);\n            int amt = h[best_i][best_j];\n            add_op(\"+\" + to_string(amt));\n            h[best_i][best_j] = 0;\n            truck_load += amt;\n        } else if (truck_load > 0 && has_neg) {\n            int best_d = INT_MAX, best_i = -1, best_j = -1;\n            for (int i = 0; i < N; i++)\n                for (int j = 0; j < N; j++)\n                    if (h[i][j] < 0) {\n                        int d = dist(cur_i, cur_j, i, j);\n                        if (d < best_d) {\n                            best_d = d;\n                            best_i = i; best_j = j;\n                        }\n                    }\n            \n            if (best_i == -1) break;\n            \n            move_to(best_i, best_j);\n            int amt = min(truck_load, (long long)-h[best_i][best_j]);\n            add_op(\"-\" + to_string(amt));\n            h[best_i][best_j] += amt;\n            truck_load -= amt;\n        } else {\n            break;\n        }\n    }\n    \n    for (auto& s : ops) cout << s << \"\\n\";\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n    int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> X(seed_count, vector<int>(M));\n    \n    for (int i = 0; i < seed_count; i++)\n        for (int j = 0; j < M; j++)\n            cin >> X[i][j];\n    \n    mt19937 rng(42);\n    uniform_int_distribution<int> distPos(0, N * N - 1);\n    uniform_real_distribution<double> uni(0, 1);\n    \n    for (int t = 0; t < T; t++) {\n        vector<int> order(seed_count);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            int sa = 0, sb = 0;\n            for (int l = 0; l < M; l++) { sa += X[a][l]; sb += X[b][l]; }\n            return sa > sb;\n        });\n        \n        vector<int> flat(order.begin(), order.begin() + N * N);\n        \n        auto pot = [&](int a, int b) -> int {\n            int p = 0;\n            for (int l = 0; l < M; l++) p += max(X[a][l], X[b][l]);\n            return p;\n        };\n        \n        auto contrib = [&](int idx) -> int {\n            int i = idx / N, j = idx % N, c = 0;\n            if (j > 0) c += pot(flat[idx], flat[idx - 1]);\n            if (j < N - 1) c += pot(flat[idx], flat[idx + 1]);\n            if (i > 0) c += pot(flat[idx], flat[idx - N]);\n            if (i < N - 1) c += pot(flat[idx], flat[idx + N]);\n            return c;\n        };\n        \n        int score = 0;\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N - 1; j++) score += pot(flat[i*N+j], flat[i*N+j+1]);\n        for (int i = 0; i < N - 1; i++)\n            for (int j = 0; j < N; j++) score += pot(flat[i*N+j], flat[(i+1)*N+j]);\n        \n        int bestScore = score;\n        vector<int> bestFlat = flat;\n        \n        double temp = 10.0;\n        for (int iter = 0; iter < 50000; iter++) {\n            int p1 = distPos(rng), p2 = distPos(rng);\n            if (p1 == p2) continue;\n            \n            int r1 = p1/N, c1 = p1%N, r2 = p2/N, c2 = p2%N;\n            bool adj = (abs(r1-r2)==1 && c1==c2) || (abs(c1-c2)==1 && r1==r2);\n            \n            int old = contrib(p1) + contrib(p2);\n            if (adj) old -= pot(flat[p1], flat[p2]);\n            \n            swap(flat[p1], flat[p2]);\n            \n            int nw = contrib(p1) + contrib(p2);\n            if (adj) nw -= pot(flat[p1], flat[p2]);\n            \n            int delta = nw - old;\n            \n            if (delta > 0 || uni(rng) < exp(delta / temp)) {\n                score += delta;\n                if (score > bestScore) { bestScore = score; bestFlat = flat; }\n            } else {\n                swap(flat[p1], flat[p2]);\n            }\n            temp *= 0.9999;\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << bestFlat[i * N + j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n        \n        for (int i = 0; i < seed_count; i++)\n            for (int j = 0; j < M; j++)\n                cin >> X[i][j];\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<string> S, T;\n\nconst int DX[] = {1, 0, -1, 0};\nconst int DY[] = {0, 1, 0, -1};\nconst char DIR_C[] = \"RDLU\";\n\nstruct Robot {\n    int V;\n    vector<int> par, len;\n    vector<vector<int>> child;\n    vector<int> leaves;\n    int rx, ry;\n    vector<int> edir;\n    \n    void init(int v) {\n        V = v;\n        par.resize(V, -1); len.resize(V); child.resize(V); edir.resize(V, 0);\n    }\n    \n    void build() {\n        int nb = min(V - 1, 4);\n        int blen = max(2, N / 4);\n        for (int i = 1; i <= nb && i < V; i++) {\n            par[i] = 0; len[i] = blen; child[0].push_back(i);\n        }\n        for (int i = nb + 1; i < V; i++) {\n            par[i] = (i - 2) % nb + 1; len[i] = 2;\n            child[par[i]].push_back(i);\n        }\n        for (int i = 0; i < V; i++) if (child[i].empty()) leaves.push_back(i);\n    }\n    \n    pair<int,int> pos(int v) const {\n        if (par[v] < 0) return {rx, ry};\n        auto [px, py] = pos(par[v]);\n        return {px + DX[edir[v]] * len[v], py + DY[edir[v]] * len[v]};\n    }\n    \n    void rot_subtree(int u, int d) {\n        queue<int> q; q.push(u);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (par[v] >= 0) edir[v] = (edir[v] + d + 4) % 4;\n            for (int c : child[v]) q.push(c);\n        }\n    }\n    void move(int d) { rx += DX[d]; ry += DY[d]; }\n};\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> V;\n    S.resize(N); T.resize(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    Robot rob; rob.init(V); rob.build();\n    \n    long long sx = 0, sy = 0, cnt = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (S[i][j] == '1') { sx += i; sy += j; cnt++; }\n    rob.rx = (cnt > 0) ? sx / cnt : N / 2;\n    rob.ry = (cnt > 0) ? sy / cnt : N / 2;\n    rob.rx = max(0, min(N - 1, rob.rx)); rob.ry = max(0, min(N - 1, rob.ry));\n    \n    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) cout << rob.par[i] << \" \" << rob.len[i] << \"\\n\";\n    cout << rob.rx << \" \" << rob.ry << \"\\n\";\n    \n    vector<vector<int>> grid(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) grid[i][j] = (S[i][j] == '1');\n    \n    set<pair<int,int>> usrc, utgt;\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') usrc.insert({i, j});\n        if (T[i][j] == '1' && S[i][j] == '0') utgt.insert({i, j});\n    }\n    \n    map<int, bool> hold;\n    for (int l : rob.leaves) hold[l] = false;\n    \n    auto find_nearest = [&](int x, int y, bool need_src) -> int {\n        int mn = INT_MAX;\n        if (need_src) for (auto [r, c] : usrc) if (grid[r][c] == 1) mn = min(mn, abs(x-r) + abs(y-c));\n        else for (auto [r, c] : utgt) if (grid[r][c] == 0) mn = min(mn, abs(x-r) + abs(y-c));\n        return mn;\n    };\n    \n    auto score = [&]() -> long long {\n        long long s = 0;\n        for (int l : rob.leaves) { auto [x, y] = rob.pos(l); int d = find_nearest(x, y, !hold[l]); if (d < INT_MAX) s += d; }\n        return s;\n    };\n    \n    for (int t = 0; t < 100000; t++) {\n        bool done = true;\n        for (auto [r, c] : utgt) if (grid[r][c] == 0) { done = false; break; }\n        if (done) break;\n        \n        string cmd(2 * V, '.');\n        \n        for (int l : rob.leaves) {\n            auto [x, y] = rob.pos(l);\n            if (x < 0 || x >= N || y < 0 || y >= N) continue;\n            if (!hold[l] && grid[x][y] == 1 && T[x][y] == '0') { cmd[V + l] = 'P'; hold[l] = true; grid[x][y] = 0; usrc.erase({x, y}); }\n            else if (hold[l] && grid[x][y] == 0 && T[x][y] == '1') { cmd[V + l] = 'P'; hold[l] = false; grid[x][y] = 1; utgt.erase({x, y}); }\n        }\n        \n        int bd = -1; long long bs = LLONG_MAX;\n        for (int d = 0; d < 4; d++) {\n            int nx = rob.rx + DX[d], ny = rob.ry + DY[d];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            rob.move(d); long long s = score(); rob.move((d + 2) % 4);\n            if (s < bs) { bs = s; bd = d; }\n        }\n        if (bd >= 0) { cmd[0] = DIR_C[bd]; rob.move(bd); }\n        \n        for (int u = 1; u < V; u++) {\n            auto orig = rob.edir; long long so = score();\n            rob.rot_subtree(u, 3); long long sl = score();\n            rob.edir = orig; rob.rot_subtree(u, 1); long long sr = score();\n            if (sl < so && sl <= sr) { rob.edir = orig; rob.rot_subtree(u, 3); cmd[u] = 'L'; }\n            else if (sr < so) cmd[u] = 'R';\n            else rob.edir = orig;\n        }\n        cout << cmd << \"\\n\";\n    }\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    int N; cin >> N;\n    vector<int> mx(N), my(N), sx(N), sy(N);\n    for (int i = 0; i < N; i++) cin >> mx[i] >> my[i];\n    for (int i = 0; i < N; i++) cin >> sx[i] >> sy[i];\n    \n    const int MAXC = 100000;\n    const int GS = 150;\n    const int CS = MAXC / GS + 1;\n    \n    static int diff[160][160], pref[161][161];\n    memset(diff, 0, sizeof(diff));\n    memset(pref, 0, sizeof(pref));\n    \n    for (int i = 0; i < N; i++) diff[min(mx[i]/CS, GS-1)][min(my[i]/CS, GS-1)]++;\n    for (int i = 0; i < N; i++) diff[min(sx[i]/CS, GS-1)][min(sy[i]/CS, GS-1)]--;\n    \n    for (int i = 0; i < GS; i++)\n        for (int j = 0; j < GS; j++)\n            pref[i+1][j+1] = diff[i][j] + pref[i][j+1] + pref[i+1][j] - pref[i][j];\n    \n    int best = 0, bx1 = 0, by1 = 0, bx2 = -1, by2 = -1;\n    \n    for (int x1 = 0; x1 < GS; x1++) {\n        for (int x2 = x1; x2 < GS; x2++) {\n            int minPref = 0, minIdx = -1, cs = 0;\n            for (int y2 = 0; y2 < GS; y2++) {\n                cs += pref[x2+1][y2+1] - pref[x1][y2+1] - pref[x2+1][y2] + pref[x1][y2];\n                if (cs - minPref > best) {\n                    best = cs - minPref;\n                    bx1 = x1; by1 = minIdx + 1;\n                    bx2 = x2; by2 = y2;\n                }\n                if (cs < minPref) { minPref = cs; minIdx = y2; }\n            }\n        }\n    }\n    \n    if (best <= 0) {\n        cout << 4 << \"\\n0 0\\n0 1\\n1 1\\n1 0\\n\";\n    } else {\n        int ox1 = bx1 * CS, oy1 = by1 * CS;\n        int ox2 = min((bx2 + 1) * CS - 1, MAXC), oy2 = min((by2 + 1) * CS - 1, MAXC);\n        cout << 4 << \"\\n\" << ox1 << \" \" << oy1 << \"\\n\" << ox2 << \" \" << oy1 << \"\\n\"\n             << ox2 << \" \" << oy2 << \"\\n\" << ox1 << \" \" << oy2 << \"\\n\";\n    }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, sigma;\nvector<long long> w, h;\nmt19937_64 rng(42);\n\nlong long simulate(const vector<int>& rot, const vector<int>& dir, const vector<int>& ref) {\n    vector<long long> x1(N), y1(N), x2(N), y2(N);\n    long long W = 0, H = 0;\n    for (int i = 0; i < N; i++) {\n        long long width = rot[i] ? h[i] : w[i];\n        long long height = rot[i] ? w[i] : h[i];\n        long long x0, y0;\n        if (dir[i] == 0) { // U\n            x0 = (ref[i] < 0) ? 0 : x2[ref[i]];\n            y0 = 0;\n            for (int j = 0; j < i; j++)\n                if (x0 < x2[j] && x0 + width > x1[j])\n                    y0 = max(y0, y2[j]);\n        } else { // L\n            y0 = (ref[i] < 0) ? 0 : y2[ref[i]];\n            x0 = 0;\n            for (int j = 0; j < i; j++)\n                if (y0 < y2[j] && y0 + height > y1[j])\n                    x0 = max(x0, x2[j]);\n        }\n        x1[i] = x0; y1[i] = y0;\n        x2[i] = x0 + width; y2[i] = y0 + height;\n        W = max(W, x2[i]); H = max(H, y2[i]);\n    }\n    return W + H;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T >> sigma;\n    w.resize(N); h.resize(N);\n    for (int i = 0; i < N; i++) cin >> w[i] >> h[i];\n    \n    vector<int> rot(N, 0), dir(N, 0), ref(N, -1);\n    \n    // Greedy initialization\n    for (int i = 1; i < N; i++) {\n        long long min_score = LLONG_MAX;\n        int br = 0, bd = 0, bf = -1;\n        for (int r = 0; r < 2; r++)\n            for (int d = 0; d < 2; d++)\n                for (int f = -1; f < i; f++) {\n                    rot[i] = r; dir[i] = d; ref[i] = f;\n                    long long s = simulate(rot, dir, ref);\n                    if (s < min_score) { min_score = s; br = r; bd = d; bf = f; }\n                }\n        rot[i] = br; dir[i] = bd; ref[i] = bf;\n    }\n    \n    long long curr_score = simulate(rot, dir, ref);\n    long long best_score = curr_score;\n    vector<int> best_rot = rot, best_dir = dir, best_ref = ref;\n    \n    uniform_real_distribution<double> uni(0.0, 1.0);\n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(2700);\n    int total_iter = 0;\n    \n    for (int turn = 0; turn < T; turn++) {\n        for (int iter = 0; iter < 30 && chrono::steady_clock::now() < deadline; iter++) {\n            total_iter++;\n            double temp = max(1.0, 1e8 * pow(0.9995, total_iter));\n            \n            int idx = 1 + rng() % (N - 1);\n            int op = rng() % 3;\n            int old_r = rot[idx], old_d = dir[idx], old_f = ref[idx];\n            \n            if (op == 0) rot[idx] ^= 1;\n            else if (op == 1) dir[idx] ^= 1;\n            else ref[idx] = (uni(rng) < 0.3) ? -1 : (int)(rng() % idx);\n            \n            long long s = simulate(rot, dir, ref);\n            long long delta = s - curr_score;\n            \n            if (delta <= 0 || uni(rng) < exp(-delta / temp)) {\n                curr_score = s;\n                if (s < best_score) {\n                    best_score = s;\n                    best_rot = rot; best_dir = dir; best_ref = ref;\n                }\n            } else {\n                rot[idx] = old_r; dir[idx] = old_d; ref[idx] = old_f;\n            }\n        }\n        \n        cout << N << \"\\n\";\n        for (int i = 0; i < N; i++)\n            cout << i << \" \" << best_rot[i] << \" \" << (best_dir[i] ? 'L' : 'U') << \" \" << best_ref[i] << \"\\n\";\n        cout.flush();\n        \n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    int N, M, H; cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int& a : A) cin >> a;\n    \n    vector<vector<int>> adj(N);\n    vector<int> x(N), y(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    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    vector<int> sorted_by_beauty(N);\n    iota(sorted_by_beauty.begin(), sorted_by_beauty.end(), 0);\n    sort(sorted_by_beauty.begin(), sorted_by_beauty.end(), [&](int i, int j) { return A[i] < A[j]; });\n    \n    vector<int> best_parent(N, -1);\n    long long best_score = 0;\n    \n    auto start = chrono::steady_clock::now();\n    \n    auto solve = [&](const vector<int>& order, bool use_coords) -> pair<vector<int>, long long> {\n        vector<int> parent(N, -1), height(N, 0);\n        vector<bool> used(N, false);\n        \n        for (int v : order) {\n            int best_p = -1, best_h = 0, best_beauty = INT_MAX;\n            double best_dist = 1e18;\n            \n            for (int u : adj[v]) {\n                if (!used[u] || height[u] + 1 > H) continue;\n                int h = height[u] + 1;\n                int b = A[u];\n                double d = hypot(x[v] - x[u], y[v] - y[u]);\n                \n                if (h > best_h || (h == best_h && (b < best_beauty || (b == best_beauty && d < best_dist)))) {\n                    best_h = h;\n                    best_p = u;\n                    best_beauty = b;\n                    best_dist = d;\n                }\n            }\n            parent[v] = best_p;\n            height[v] = best_h;\n            used[v] = true;\n        }\n        \n        // Build children list\n        vector<vector<int>> children(N);\n        for (int v = 0; v < N; v++)\n            if (parent[v] != -1) children[parent[v]].push_back(v);\n        \n        // Local search - move leaves higher\n        for (int iter = 0; iter < 100; iter++) {\n            bool changed = false;\n            for (int v = 0; v < N; v++) {\n                if (!children[v].empty()) continue;\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    if (height[u] + 1 <= H && height[u] + 1 > height[v]) {\n                        if (parent[v] != -1) {\n                            auto& c = children[parent[v]];\n                            c.erase(remove(c.begin(), c.end(), v), c.end());\n                        }\n                        parent[v] = u;\n                        height[v] = height[u] + 1;\n                        children[u].push_back(v);\n                        changed = true;\n                        break;\n                    }\n                }\n            }\n            if (!changed) break;\n        }\n        \n        long long score = 0;\n        for (int v = 0; v < N; v++) score += (long long)(height[v] + 1) * A[v];\n        return {parent, score};\n    };\n    \n    // Try multiple strategies\n    tie(best_parent, best_score) = solve(sorted_by_beauty, false);\n    \n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < 1.9) {\n        vector<int> order = sorted_by_beauty;\n        \n        // Shuffle within same-beauty groups\n        for (int i = 0, j; i < N; i = j) {\n            j = i + 1;\n            while (j < N && A[order[j]] == A[order[i]]) j++;\n            if (j - i > 1) shuffle(order.begin() + i, order.begin() + j, rng);\n        }\n        \n        bool use_coords = (rng() % 3 == 0);\n        auto [p, s] = solve(order, use_coords);\n        if (s > best_score) { best_score = s; best_parent = p; }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << best_parent[i] << \" \\n\"[i == N-1];\n    }\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <algorithm>\n\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<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    vector<pair<int,int>> onis, fukus;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j] == 'x') onis.emplace_back(i, j);\n            else if (board[i][j] == 'o') fukus.emplace_back(i, j);\n    \n    int num_onis = onis.size();\n    vector<bool> safe_up(num_onis, true), safe_down(num_onis, true);\n    vector<bool> safe_left(num_onis, true), safe_right(num_onis, true);\n    \n    for (int idx = 0; idx < num_onis; idx++) {\n        auto [i, j] = onis[idx];\n        for (auto& [fi, fj] : fukus) {\n            if (fj == j && fi < i) safe_up[idx] = false;\n            if (fj == j && fi > i) safe_down[idx] = false;\n            if (fi == i && fj < j) safe_left[idx] = false;\n            if (fi == i && fj > j) safe_right[idx] = false;\n        }\n    }\n    \n    set<int> remaining;\n    for (int idx = 0; idx < num_onis; idx++) remaining.insert(idx);\n    \n    vector<pair<char, int>> result;\n    \n    while (!remaining.empty()) {\n        struct Op { double eff; int cost; char dir; int idx; vector<int> batch; };\n        vector<Op> ops;\n        \n        // Column up - dynamically compute based on remaining Onis\n        for (int j = 0; j < N; j++) {\n            vector<int> batch;\n            int max_row = -1;\n            for (int idx : remaining)\n                if (onis[idx].second == j && safe_up[idx]) {\n                    batch.push_back(idx);\n                    max_row = max(max_row, onis[idx].first);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (max_row + 1);\n                ops.push_back({(double)batch.size() / cost, cost, 'U', j, batch});\n            }\n        }\n        // Column down\n        for (int j = 0; j < N; j++) {\n            vector<int> batch;\n            int min_row = N;\n            for (int idx : remaining)\n                if (onis[idx].second == j && safe_down[idx]) {\n                    batch.push_back(idx);\n                    min_row = min(min_row, onis[idx].first);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (N - min_row);\n                ops.push_back({(double)batch.size() / cost, cost, 'D', j, batch});\n            }\n        }\n        // Row left\n        for (int i = 0; i < N; i++) {\n            vector<int> batch;\n            int max_col = -1;\n            for (int idx : remaining)\n                if (onis[idx].first == i && safe_left[idx]) {\n                    batch.push_back(idx);\n                    max_col = max(max_col, onis[idx].second);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (max_col + 1);\n                ops.push_back({(double)batch.size() / cost, cost, 'L', i, batch});\n            }\n        }\n        // Row right\n        for (int i = 0; i < N; i++) {\n            vector<int> batch;\n            int min_col = N;\n            for (int idx : remaining)\n                if (onis[idx].first == i && safe_right[idx]) {\n                    batch.push_back(idx);\n                    min_col = min(min_col, onis[idx].second);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (N - min_col);\n                ops.push_back({(double)batch.size() / cost, cost, 'R', i, batch});\n            }\n        }\n        \n        if (ops.empty()) break;\n        \n        // Find best operation by efficiency\n        int best = 0;\n        for (int i = 1; i < (int)ops.size(); i++)\n            if (ops[i].eff > ops[best].eff || \n                (ops[i].eff == ops[best].eff && ops[i].cost < ops[best].cost))\n                best = i;\n        \n        for (int oni_idx : ops[best].batch) remaining.erase(oni_idx);\n        \n        int shifts = ops[best].cost / 2;\n        char dir = ops[best].dir, rev_dir = (dir == 'U' ? 'D' : dir == 'D' ? 'U' : dir == 'L' ? 'R' : 'L');\n        for (int k = 0; k < shifts; k++) result.emplace_back(dir, ops[best].idx);\n        for (int k = 0; k < shifts; k++) result.emplace_back(rev_dir, ops[best].idx);\n    }\n    \n    for (auto& [d, p] : result) cout << d << \" \" << p << \"\\n\";\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, L;\nint T[100], a[100], b[100], visits[100];\nlong long cur_err, best_err;\nint best_a[100], best_b[100];\n\nlong long simulate() {\n    memset(visits, 0, sizeof(visits));\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        int t = ++visits[cur];\n        cur = (t & 1) ? a[cur] : b[cur];\n    }\n    long long err = 0;\n    for (int i = 0; i < n; i++) err += abs(visits[i] - T[i]);\n    return err;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n >> L;\n    for (int i = 0; i < n; i++) cin >> T[i];\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> urd(0.0, 1.0);\n    \n    // Smart initialization: cycle through active employees\n    vector<int> active;\n    for (int i = 0; i < n; i++) if (T[i] > 0) active.push_back(i);\n    if (active.empty()) active.push_back(0);\n    \n    for (int i = 0; i < n; i++) a[i] = b[i] = active[0];\n    for (int idx = 0; idx < (int)active.size(); idx++) {\n        int cur = active[idx];\n        int nxt = active[(idx + 1) % active.size()];\n        a[cur] = b[cur] = nxt;\n    }\n    if (T[0] == 0) a[0] = b[0] = active[0];\n    \n    best_err = cur_err = simulate();\n    memcpy(best_a, a, sizeof(a));\n    memcpy(best_b, b, sizeof(b));\n    \n    double temp = 20000.0;\n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(1750);\n    int no_improve = 0;\n    \n    while (chrono::steady_clock::now() < deadline) {\n        int i = rng() % n;\n        int old_a = a[i], old_b = b[i];\n        \n        int r = rng() % 10;\n        if (r < 4) a[i] = rng() % n;\n        else if (r < 8) b[i] = rng() % n;\n        else { a[i] = rng() % n; b[i] = rng() % n; }\n        \n        long long new_err = simulate();\n        \n        if (new_err <= cur_err || exp(-(double)(new_err - cur_err) / temp) > urd(rng)) {\n            cur_err = new_err;\n            if (new_err < best_err) {\n                best_err = new_err;\n                memcpy(best_a, a, sizeof(a));\n                memcpy(best_b, b, sizeof(b));\n                no_improve = 0;\n            } else no_improve++;\n        } else {\n            a[i] = old_a; b[i] = old_b;\n            no_improve++;\n        }\n        \n        if (no_improve > 3000) {\n            memcpy(a, best_a, sizeof(a));\n            memcpy(b, best_b, sizeof(b));\n            cur_err = best_err;\n            temp = min(20000.0, temp * 3.0);\n            no_improve = 0;\n        }\n        \n        temp = max(0.01, temp * 0.99995);\n    }\n    \n    // Greedy local search\n    memcpy(a, best_a, sizeof(a));\n    memcpy(b, best_b, sizeof(b));\n    cur_err = best_err;\n    deadline = chrono::steady_clock::now() + chrono::milliseconds(50);\n    \n    while (chrono::steady_clock::now() < deadline) {\n        int i = rng() % n;\n        int old_a = a[i], old_b = b[i];\n        \n        for (int trial = 0; trial < 5; trial++) {\n            if (trial < 2) a[i] = rng() % n;\n            else if (trial < 4) b[i] = rng() % n;\n            else { a[i] = rng() % n; b[i] = rng() % n; }\n            \n            long long new_err = simulate();\n            if (new_err < cur_err) {\n                cur_err = new_err;\n                best_err = new_err;\n                memcpy(best_a, a, sizeof(a));\n                memcpy(best_b, b, sizeof(b));\n            } else {\n                a[i] = old_a; b[i] = old_b;\n            }\n        }\n    }\n    \n    for (int i = 0; i < n; i++) cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<double> cx, cy;\n\nstruct UnionFind {\n    vector<int> p, r;\n    UnionFind(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 x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (r[x] < r[y]) swap(x, y);\n        p[y] = x;\n        if (r[x] == r[y]) r[x]++;\n        return true;\n    }\n};\n\ndouble estDist(int i, int j) {\n    double dx = cx[i] - cx[j], dy = cy[i] - cy[j];\n    return sqrt(dx*dx + dy*dy);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    cx.resize(N); cy.resize(N);\n    for (int i = 0; i < N; i++) {\n        int lxi, rxi, lyi, ryi;\n        cin >> lxi >> rxi >> lyi >> ryi;\n        cx[i] = (lxi + rxi) / 2.0;\n        cy[i] = (lyi + ryi) / 2.0;\n    }\n    \n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [](int a, int b) {\n        return make_pair(cx[a], cy[a]) < make_pair(cx[b], cy[b]);\n    });\n    \n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; i++) {\n        groups[i].assign(order.begin() + idx, order.begin() + idx + G[i]);\n        idx += G[i];\n    }\n    \n    int qUsed = 0;\n    vector<vector<pair<int,int>>> ans(M);\n    \n    for (int g = 0; g < M; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        set<pair<int,int>> goodEdges;\n        \n        if (sz <= L && qUsed < Q) {\n            cout << \"? \" << sz;\n            for (int c : groups[g]) cout << \" \" << c;\n            cout << endl;\n            \n            for (int i = 0; i < sz - 1; i++) {\n                int a, b;\n                cin >> a >> b;\n                goodEdges.insert({min(a, b), max(a, b)});\n            }\n            qUsed++;\n        } else if (sz > L) {\n            for (int start = 0; start < sz && qUsed < Q; start += L - 1) {\n                int end = min(start + L, sz);\n                if (end - start < 2) break;\n                \n                cout << \"? \" << (end - start);\n                for (int i = start; i < end; i++) cout << \" \" << groups[g][i];\n                cout << endl;\n                \n                for (int i = 0; i < (end - start) - 1; i++) {\n                    int a, b;\n                    cin >> a >> b;\n                    goodEdges.insert({min(a, b), max(a, b)});\n                }\n                qUsed++;\n            }\n        }\n        \n        vector<tuple<double,int,int>> edges;\n        for (int i = 0; i < sz; i++) {\n            for (int j = i + 1; j < sz; j++) {\n                int ci = groups[g][i], cj = groups[g][j];\n                double d = estDist(ci, cj);\n                auto key = make_pair(min(ci, cj), max(ci, cj));\n                if (goodEdges.count(key)) d -= 1e9;\n                edges.push_back({d, i, j});\n            }\n        }\n        sort(edges.begin(), edges.end());\n        \n        UnionFind uf(sz);\n        for (auto& [d, i, j] : edges) {\n            if (uf.unite(i, j)) {\n                ans[g].push_back({groups[g][i], groups[g][j]});\n            }\n        }\n    }\n    \n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        for (int i = 0; i < (int)groups[g].size(); i++) {\n            if (i > 0) cout << \" \";\n            cout << groups[g][i];\n        }\n        cout << endl;\n        for (auto& [a, b] : ans[g]) {\n            cout << a << \" \" << b << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\npair<int, int> slide_end(int r, int c, int d, const vector<vector<bool>>& blocks) {\n    while (true) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N || blocks[nr][nc]) return {r, c};\n        r = nr; c = nc;\n    }\n}\n\nint get_dir_idx(char d) {\n    for (int i = 0; i < 4; i++) if (dir_char[i] == d) return i;\n    return -1;\n}\n\nvector<pair<char, char>> bfs(int sr, int sc, int tr, int tc, const vector<vector<bool>>& blocks) {\n    if (sr == tr && sc == tc) return {};\n    \n    vector<vector<int>> dist(N, vector<int>(N, -1));\n    vector<vector<tuple<int,int,char,char>>> prev(N, vector<tuple<int,int,char,char>>(N, {-1, -1, ' ', ' '}));\n    \n    queue<pair<int,int>> q;\n    q.push({sr, sc});\n    dist[sr][sc] = 0;\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == tr && c == tc) {\n            vector<pair<char, char>> path;\n            int cr = tr, cc = tc;\n            while (cr != sr || cc != sc) {\n                auto [pr, pc, a, d] = prev[cr][cc];\n                path.push_back({a, d});\n                cr = pr; cc = pc;\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \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 && !blocks[nr][nc] && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1;\n                prev[nr][nc] = {r, c, 'M', dir_char[d]};\n                q.push({nr, nc});\n            }\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            auto [nr, nc] = slide_end(r, c, d, blocks);\n            if (dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1;\n                prev[nr][nc] = {r, c, 'S', dir_char[d]};\n                q.push({nr, nc});\n            }\n        }\n    }\n    return {};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M;\n    vector<pair<int, int>> targets(M);\n    for (int i = 0; i < M; i++) cin >> targets[i].first >> targets[i].second;\n    \n    vector<vector<bool>> blocks(N, vector<bool>(N, false));\n    int cr = targets[0].first, cc = targets[0].second;\n    vector<pair<char, char>> actions;\n    \n    for (int t = 1; t < M; t++) {\n        int tr = targets[t].first, tc = targets[t].second;\n        \n        // Try Alter + Slide from start position\n        bool found_quick = false;\n        for (int d1 = 0; d1 < 4 && !found_quick; d1++) {\n            int br = cr + dr[d1], bc = cc + dc[d1];\n            if (br < 0 || br >= N || bc < 0 || bc >= N || blocks[br][bc]) continue;\n            \n            blocks[br][bc] = true;\n            for (int d2 = 0; d2 < 4 && !found_quick; d2++) {\n                auto [nr, nc] = slide_end(cr, cc, d2, blocks);\n                if (nr == tr && nc == tc) {\n                    actions.push_back({'A', dir_char[d1]});\n                    actions.push_back({'S', dir_char[d2]});\n                    cr = tr; cc = tc;\n                    found_quick = true;\n                }\n            }\n            if (!found_quick) blocks[br][bc] = false;\n        }\n        \n        if (!found_quick) {\n            auto path = bfs(cr, cc, tr, tc, blocks);\n            for (auto [a, d] : path) {\n                actions.push_back({a, d});\n                int di = get_dir_idx(d);\n                if (a == 'M') { cr += dr[di]; cc += dc[di]; }\n                else if (a == 'S') tie(cr, cc) = slide_end(cr, cc, di, blocks);\n            }\n        }\n    }\n    \n    for (auto [a, d] : actions) cout << a << ' ' << d << '\\n';\n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> X, Y;\nvector<long long> R;\nvector<int> a, b, c, d;\nmt19937 rng(42);\n\ndouble getScore(int i) {\n    long long area = (long long)(c[i] - a[i]) * (d[i] - b[i]);\n    long long mn = min(R[i], area);\n    long long mx = max(R[i], area);\n    return 1.0 - pow(1.0 - (double)mn / mx, 2);\n}\n\ndouble totalScore() {\n    double s = 0;\n    for (int i = 0; i < n; i++) s += getScore(i);\n    return s;\n}\n\nvoid solve(int L, int Rb, int B, int T, vector<int> ids) {\n    if (ids.empty()) return;\n    if (ids.size() == 1) {\n        int i = ids[0];\n        a[i] = L; b[i] = B; c[i] = Rb; d[i] = T;\n        return;\n    }\n    \n    int W = Rb - L, H = T - B;\n    long long totalTarget = 0;\n    for (int i : ids) totalTarget += R[i];\n    \n    double bestCost = 1e18;\n    bool bestVertical = false;\n    vector<int> bestLeftIds, bestRightIds;\n    int bestSplit = -1;\n    \n    for (int dir = 0; dir < 2; dir++) {\n        bool vertical = (dir == 0);\n        if (vertical && W < 2) continue;\n        if (!vertical && H < 2) continue;\n        \n        vector<int> sortedIds = ids;\n        sort(sortedIds.begin(), sortedIds.end(), [&](int i, int j) {\n            return vertical ? X[i] < X[j] : Y[i] < Y[j];\n        });\n        \n        long long acc = 0;\n        for (size_t idx = 1; idx < sortedIds.size(); idx++) {\n            acc += R[sortedIds[idx - 1]];\n            \n            int leftMax = vertical ? X[sortedIds[idx - 1]] : Y[sortedIds[idx - 1]];\n            int rightMin = vertical ? X[sortedIds[idx]] : Y[sortedIds[idx]];\n            \n            if (leftMax >= rightMin) continue;\n            \n            long long leftTarget = acc;\n            long long rightTarget = totalTarget - acc;\n            \n            int minSplit = leftMax + 1;\n            int maxSplit = rightMin;\n            \n            int idealSplit;\n            if (vertical) {\n                idealSplit = L + (long long)leftTarget / H;\n            } else {\n                idealSplit = B + (long long)leftTarget / W;\n            }\n            \n            int split = max(minSplit, min(maxSplit, idealSplit));\n            \n            long long bestAreaCost = LLONG_MAX;\n            int bestS = split;\n            for (int s = max(minSplit, split - 5); s <= min(maxSplit, split + 5); s++) {\n                if (vertical) {\n                    if (s <= L || s >= Rb) continue;\n                } else {\n                    if (s <= B || s >= T) continue;\n                }\n                \n                long long leftArea, rightArea;\n                if (vertical) {\n                    leftArea = (long long)(s - L) * H;\n                    rightArea = (long long)(Rb - s) * H;\n                } else {\n                    leftArea = (long long)(s - B) * W;\n                    rightArea = (long long)(T - s) * W;\n                }\n                \n                long long cost = abs(leftArea - leftTarget) + abs(rightArea - rightTarget);\n                if (cost < bestAreaCost) {\n                    bestAreaCost = cost;\n                    bestS = s;\n                }\n            }\n            split = bestS;\n            \n            long long leftArea, rightArea;\n            if (vertical) {\n                leftArea = (long long)(split - L) * H;\n                rightArea = (long long)(Rb - split) * H;\n            } else {\n                leftArea = (long long)(split - B) * W;\n                rightArea = (long long)(T - split) * W;\n            }\n            \n            double cost = (double)abs(leftArea - leftTarget) + (double)abs(rightArea - rightTarget);\n            \n            if (cost < bestCost) {\n                bestCost = cost;\n                bestVertical = vertical;\n                bestLeftIds = vector<int>(sortedIds.begin(), sortedIds.begin() + idx);\n                bestRightIds = vector<int>(sortedIds.begin() + idx, sortedIds.end());\n                bestSplit = split;\n            }\n        }\n    }\n    \n    if (bestSplit < 0) {\n        bool vertical = (W >= H);\n        vector<int> sortedIds = ids;\n        sort(sortedIds.begin(), sortedIds.end(), [&](int i, int j) {\n            return vertical ? X[i] < X[j] : Y[i] < Y[j];\n        });\n        \n        size_t splitIdx = sortedIds.size() / 2;\n        bestLeftIds = vector<int>(sortedIds.begin(), sortedIds.begin() + splitIdx);\n        bestRightIds = vector<int>(sortedIds.begin() + splitIdx, sortedIds.end());\n        bestVertical = vertical;\n        \n        int leftMax = 0, rightMin = 10000;\n        for (int i : bestLeftIds) leftMax = max(leftMax, vertical ? X[i] : Y[i]);\n        for (int i : bestRightIds) rightMin = min(rightMin, vertical ? X[i] : Y[i]);\n        \n        bestSplit = (leftMax + rightMin + 1) / 2;\n        if (vertical) bestSplit = max(L + 1, min(Rb - 1, bestSplit));\n        else bestSplit = max(B + 1, min(T - 1, bestSplit));\n    }\n    \n    if (bestVertical) {\n        solve(L, bestSplit, B, T, bestLeftIds);\n        solve(bestSplit, Rb, B, T, bestRightIds);\n    } else {\n        solve(L, Rb, B, bestSplit, bestLeftIds);\n        solve(L, Rb, bestSplit, T, bestRightIds);\n    }\n}\n\nbool overlaps(int i, int j) {\n    return a[i] < c[j] && c[i] > a[j] && b[i] < d[j] && d[i] > b[j];\n}\n\nbool isValid(int i) {\n    if (a[i] < 0 || b[i] < 0 || c[i] > 10000 || d[i] > 10000) return false;\n    if (c[i] - a[i] < 1 || d[i] - b[i] < 1) return false;\n    if (X[i] < a[i] || X[i] >= c[i] || Y[i] < b[i] || Y[i] >= d[i]) return false;\n    for (int j = 0; j < n; j++) {\n        if (i != j && overlaps(i, j)) return false;\n    }\n    return true;\n}\n\nvoid anneal() {\n    double bestTotal = totalScore();\n    vector<int> bestA = a, bestB = b, bestC = c, bestD = d;\n    \n    double temp = 1.0;\n    const double decay = 0.9999;\n    const int maxIter = 100000;\n    \n    uniform_int_distribution<int> distIdx(0, n - 1);\n    uniform_int_distribution<int> distDir(0, 7);\n    uniform_int_distribution<int> distAmt(1, 50);\n    \n    for (int iter = 0; iter < maxIter; iter++) {\n        int i = distIdx(rng);\n        int oldA = a[i], oldB = b[i], oldC = c[i], oldD = d[i];\n        double oldScore = getScore(i);\n        \n        int dir = distDir(rng);\n        int amt = distAmt(rng);\n        \n        if (dir == 0) a[i] -= amt;\n        else if (dir == 1) b[i] -= amt;\n        else if (dir == 2) c[i] += amt;\n        else if (dir == 3) d[i] += amt;\n        else if (dir == 4) a[i] += amt;\n        else if (dir == 5) b[i] += amt;\n        else if (dir == 6) c[i] -= amt;\n        else d[i] -= amt;\n        \n        if (isValid(i)) {\n            double newScore = getScore(i);\n            double delta = newScore - oldScore;\n            \n            if (delta > 0 || (double)rng() / rng.max() < exp(delta * 100 / temp)) {\n                // Accept move\n                double newTotal = totalScore();\n                if (newTotal > bestTotal) {\n                    bestTotal = newTotal;\n                    bestA = a; bestB = b; bestC = c; bestD = d;\n                }\n            } else {\n                a[i] = oldA; b[i] = oldB; c[i] = oldC; d[i] = oldD;\n            }\n        } else {\n            a[i] = oldA; b[i] = oldB; c[i] = oldC; d[i] = oldD;\n        }\n        \n        temp *= decay;\n    }\n    \n    a = bestA; b = bestB; c = bestC; d = bestD;\n}\n\nvoid localSearch() {\n    for (int iter = 0; iter < 500; iter++) {\n        bool changed = false;\n        for (int i = 0; i < n; i++) {\n            double currentScore = getScore(i);\n            long long target = R[i];\n            \n            for (int dir = 0; dir < 8; dir++) {\n                int oldA = a[i], oldB = b[i], oldC = c[i], oldD = d[i];\n                \n                if (dir == 0) a[i]--;\n                else if (dir == 1) b[i]--;\n                else if (dir == 2) c[i]++;\n                else if (dir == 3) d[i]++;\n                else if (dir == 4) a[i]++;\n                else if (dir == 5) b[i]++;\n                else if (dir == 6) c[i]--;\n                else d[i]--;\n                \n                if (isValid(i)) {\n                    long long newArea = (long long)(c[i] - a[i]) * (d[i] - b[i]);\n                    double newScore = 1.0 - pow(1.0 - (double)min(target, newArea) / max(target, newArea), 2);\n                    \n                    if (newScore > currentScore + 1e-9) {\n                        changed = true;\n                        break;\n                    }\n                }\n                \n                a[i] = oldA; b[i] = oldB; c[i] = oldC; d[i] = oldD;\n            }\n        }\n        if (!changed) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    a.resize(n); b.resize(n); c.resize(n); d.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> X[i] >> Y[i] >> R[i];\n    }\n    \n    vector<int> ids(n);\n    iota(ids.begin(), ids.end(), 0);\n    \n    solve(0, 10000, 0, 10000, ids);\n    localSearch();\n    anneal();\n    localSearch();\n    \n    for (int i = 0; i < n; i++) {\n        cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<vector<int>> t(50, vector<int>(50)), p(50, vector<int>(50));\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) cin >> t[i][j];\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) cin >> p[i][j];\n    \n    map<int, vector<pair<int,int>>> tileSquares;\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++)\n            tileSquares[t[i][j]].push_back({i, j});\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    set<int> visited;\n    string path;\n    int ci = si, cj = sj;\n    visited.insert(t[ci][cj]);\n    \n    auto& startSquares = tileSquares[t[ci][cj]];\n    if (startSquares.size() == 2) {\n        auto [oi, oj] = (startSquares[0].first == ci && startSquares[0].second == cj) \n            ? make_pair(startSquares[1].first, startSquares[1].second) \n            : make_pair(startSquares[0].first, startSquares[0].second);\n        path += (oi < ci ? 'U' : oi > ci ? 'D' : oj < cj ? 'L' : 'R');\n        ci = oi; cj = oj;\n    }\n    \n    while (true) {\n        int bestDir = -1, bestExitI = -1, bestExitJ = -1;\n        string bestTilePath;\n        double bestValue = -1e18;\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = ci + di[d], nj = cj + dj[d];\n            if (ni < 0 || ni >= 50 || nj < 0 || nj >= 50 || visited.count(t[ni][nj])) continue;\n            \n            int tileId = t[ni][nj];\n            auto& sq = tileSquares[tileId];\n            int tileScore = 0;\n            for (auto& [ti, tj] : sq) tileScore += p[ti][tj];\n            \n            for (size_t ei = 0; ei < sq.size(); ei++) {\n                int exi = sq[ei].first, exj = sq[ei].second;\n                visited.insert(tileId);\n                int future = 0;\n                for (int d2 = 0; d2 < 4; d2++) {\n                    int n2i = exi + di[d2], n2j = exj + dj[d2];\n                    if (n2i >= 0 && n2i < 50 && n2j >= 0 && n2j < 50 && !visited.count(t[n2i][n2j])) future++;\n                }\n                visited.erase(tileId);\n                \n                double value = tileScore + (future == 0 ? -1000.0 : future * 10.0);\n                string tilePath;\n                if (sq.size() == 2) {\n                    int oi = sq[1-ei].first, oj = sq[1-ei].second;\n                    if (ni == exi && nj == exj) {\n                        char to = (oi < exi ? 'U' : oi > exi ? 'D' : oj < exj ? 'L' : 'R');\n                        char back = (to == 'U' ? 'D' : to == 'D' ? 'U' : to == 'L' ? 'R' : 'L');\n                        tilePath = string(1, to) + string(1, back);\n                    } else {\n                        tilePath = string(1, (exi < ni ? 'U' : exi > ni ? 'D' : exj < nj ? 'L' : 'R'));\n                    }\n                }\n                if (value > bestValue) { bestValue = value; bestDir = d; bestExitI = exi; bestExitJ = exj; bestTilePath = tilePath; }\n            }\n        }\n        if (bestDir == -1) break;\n        visited.insert(t[ci + di[bestDir]][cj + dj[bestDir]]);\n        path += dc[bestDir]; path += bestTilePath;\n        ci = bestExitI; cj = bestExitJ;\n    }\n    cout << path << endl;\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 30;\n\ndouble h[N][N-1], v[N-1][N];\nint cnt_h[N][N-1], cnt_v[N-1][N];\n\nconst char dc[] = {'U', 'D', 'L', 'R'};\n\npair<string, vector<tuple<int,int,int>>> dijkstra(int si, int sj, int ti, int tj, double exploration) {\n    auto get_cost = [&](int type, int i, int j) -> double {\n        double mean = (type == 0) ? h[i][j] : v[i][j];\n        int cnt = (type == 0) ? cnt_h[i][j] : cnt_v[i][j];\n        // Exploration bonus scales with edge cost, decreases with sqrt of count\n        return mean - exploration * sqrt(mean / 5000.0) / sqrt(cnt + 1.0);\n    };\n    \n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<int>> prev_dir(N, vector<int>(N, -1));\n    \n    priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n    dist[si][sj] = 0;\n    pq.push({0.0, si, sj});\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top(); pq.pop();\n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n        \n        if (i > 0) { double c = get_cost(1, i-1, j); if (dist[i-1][j] > d + c) { dist[i-1][j] = d + c; prev_dir[i-1][j] = 0; pq.push({dist[i-1][j], i-1, j}); } }\n        if (i < N-1) { double c = get_cost(1, i, j); if (dist[i+1][j] > d + c) { dist[i+1][j] = d + c; prev_dir[i+1][j] = 1; pq.push({dist[i+1][j], i+1, j}); } }\n        if (j > 0) { double c = get_cost(0, i, j-1); if (dist[i][j-1] > d + c) { dist[i][j-1] = d + c; prev_dir[i][j-1] = 2; pq.push({dist[i][j-1], i, j-1}); } }\n        if (j < N-1) { double c = get_cost(0, i, j); if (dist[i][j+1] > d + c) { dist[i][j+1] = d + c; prev_dir[i][j+1] = 3; pq.push({dist[i][j+1], i, j+1}); } }\n    }\n    \n    string path = \"\";\n    vector<tuple<int,int,int>> edges;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int dir = prev_dir[ci][cj];\n        path = dc[dir] + path;\n        if (dir == 0) { edges.push_back({1, ci, cj}); ci++; }\n        else if (dir == 1) { edges.push_back({1, ci-1, cj}); ci--; }\n        else if (dir == 2) { edges.push_back({0, ci, cj}); cj++; }\n        else { edges.push_back({0, ci, cj-1}); cj--; }\n    }\n    return {path, edges};\n}\n\nvoid update_estimates(const vector<tuple<int,int,int>>& edges, int observed) {\n    if (edges.empty()) return;\n    \n    double estimated_sum = 0;\n    for (auto [type, i, j] : edges) estimated_sum += (type == 0) ? h[i][j] : v[i][j];\n    \n    double ratio = observed / estimated_sum;\n    \n    for (auto [type, i, j] : edges) {\n        double& mean = (type == 0) ? h[i][j] : v[i][j];\n        int& cnt = (type == 0) ? cnt_h[i][j] : cnt_v[i][j];\n        cnt++;\n        \n        // Faster initial learning, then stabilize\n        double alpha = min(0.6, 0.6 / pow(cnt, 0.4));\n        mean *= (1.0 - alpha + alpha * ratio);\n        \n        // Clamp to problem-consistent range\n        mean = max(500.0, min(12000.0, mean));\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++) for (int j = 0; j < N-1; j++) { h[i][j] = 5000.0; 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.0; cnt_v[i][j] = 0; }\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj; \n        cin >> si >> sj >> ti >> tj;\n        \n        // Three-phase exploration: strong early, moderate transition, minimal late\n        double exploration;\n        if (k < 80) exploration = 2500.0;              // Strong exploration\n        else if (k < 200) exploration = 1200.0;        // Moderate exploration\n        else if (k < 400) exploration = 400.0;         // Light exploration\n        else exploration = max(30.0, 150.0 * exp(-(k-400)/200.0)); // Decay to exploitation\n        \n        auto [path, edges] = dijkstra(si, sj, ti, tj, exploration);\n        \n        cout << path << endl;\n        cout.flush();\n        \n        int observed;\n        cin >> observed;\n        \n        update_estimates(edges, observed);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nint M;\nvector<string> s;\nvector<string> grid;\nvector<bitset<800>> cellToStrings;\nvector<bool> matched;\nmt19937 rng(42);\n\nbool matches(int r, int c, int dir, const string& str) {\n    int len = str.size();\n    for (int p = 0; p < len; p++) {\n        int nr = (dir == 0) ? r : (r + p) % N;\n        int nc = (dir == 0) ? (c + p) % N : c;\n        if (grid[nr][nc] != str[p]) return false;\n    }\n    return true;\n}\n\nbool stringMatches(int idx) {\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (matches(r, c, 0, s[idx]) || matches(r, c, 1, s[idx])) return true;\n        }\n    }\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n >> M;\n    s.resize(M);\n    matched.resize(M);\n    for (int i = 0; i < M; i++) cin >> s[i];\n    \n    // Precompute which strings could include each cell\n    cellToStrings.resize(N * N);\n    for (int i = 0; i < M; i++) {\n        int len = s[i].size();\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                for (int p = 0; p < len; p++) {\n                    cellToStrings[r * N + ((c + p) % N)][i] = 1;\n                    cellToStrings[((r + p) % N) * N + c][i] = 1;\n                }\n            }\n        }\n    }\n    \n    // Voting initialization\n    vector<vector<array<int, 8>>> votes(N, vector<array<int, 8>>(N));\n    for (auto& str : s) {\n        int len = str.size();\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                for (int p = 0; p < len; p++) {\n                    votes[r][(c + p) % N][str[p] - 'A']++;\n                    votes[(r + p) % N][c][str[p] - 'A']++;\n                }\n            }\n        }\n    }\n    \n    grid.assign(N, string(N, '.'));\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            int maxVote = -1;\n            for (int ch = 0; ch < 8; ch++) {\n                if (votes[r][c][ch] > maxVote) {\n                    maxVote = votes[r][c][ch];\n                    grid[r][c] = 'A' + ch;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < M; i++) matched[i] = stringMatches(i);\n    int score = count(matched.begin(), matched.end(), true);\n    vector<string> bestGrid = grid;\n    int bestScore = score;\n    \n    // Simulated annealing with incremental updates\n    double T = 5.0;\n    for (int iter = 0; iter < 100000; iter++) {\n        int r = rng() % N;\n        int c = rng() % N;\n        char old = grid[r][c];\n        char newChar = 'A' + (rng() % 8);\n        if (newChar == old) continue;\n        \n        grid[r][c] = newChar;\n        \n        int delta = 0;\n        bitset<800>& affected = cellToStrings[r * N + c];\n        for (int i = 0; i < M; i++) {\n            if (affected[i]) {\n                bool was = matched[i];\n                bool now = stringMatches(i);\n                if (was && !now) delta--;\n                if (!was && now) delta++;\n                matched[i] = now;\n            }\n        }\n        \n        if (delta > 0 || (delta == 0 && (rng() % 2)) || \n            (delta < 0 && exp(delta / T) > (double)rng() / rng.max())) {\n            score += delta;\n            if (score > bestScore) { bestScore = score; bestGrid = grid; }\n        } else {\n            grid[r][c] = old;\n            for (int i = 0; i < M; i++) {\n                if (affected[i]) matched[i] = stringMatches(i);\n            }\n        }\n        T *= 0.99995;\n    }\n    \n    for (int r = 0; r < N; r++) cout << bestGrid[r] << '\\n';\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> grid;\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dc[] = {'U', 'D', 'L', 'R'};\n\ninline bool isRoad(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\ninline int w(int i, int j) { return grid[i][j] - '0'; }\n\nvector<vector<vector<pair<int,int>>>> visList;\nvector<pair<int,int>> roads;\nint totalRoads;\n\nstring solve(int si, int sj, double distWeight, double coverWeight) {\n    vector<vector<bool>> covered(N, vector<bool>(N, false));\n    int numCovered = 0;\n    \n    auto doCover = [&](int i, int j) {\n        for (auto& [ni, nj] : visList[i][j])\n            if (!covered[ni][nj]) { covered[ni][nj] = true; numCovered++; }\n    };\n    \n    auto countNewCover = [&](int i, int j) {\n        int cnt = 0;\n        for (auto& [ni, nj] : visList[i][j])\n            if (!covered[ni][nj]) cnt++;\n        return cnt;\n    };\n    \n    vector<vector<int>> dist(N, vector<int>(N));\n    vector<vector<int>> parentDir(N, vector<int>(N));\n    \n    auto dijkstra = [&](int si, int sj) {\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) { dist[i][j] = INT_MAX; parentDir[i][j] = -1; }\n        priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n        dist[si][sj] = 0;\n        pq.push({0, si, sj});\n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top(); pq.pop();\n            if (d > dist[i][j]) continue;\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (isRoad(ni, nj)) {\n                    int nd = d + w(ni, nj);\n                    if (nd < dist[ni][nj]) {\n                        dist[ni][nj] = nd; parentDir[ni][nj] = k;\n                        pq.push({nd, ni, nj});\n                    }\n                }\n            }\n        }\n    };\n    \n    string route;\n    int ci = si, cj = sj;\n    doCover(ci, cj);\n    \n    while (numCovered < totalRoads) {\n        dijkstra(ci, cj);\n        \n        double bestScore = -1;\n        int besti = -1, bestj = -1;\n        for (auto& [i, j] : roads) {\n            if (dist[i][j] == INT_MAX) continue;\n            int newC = countNewCover(i, j);\n            if (newC == 0) continue;\n            double score = pow((double)newC, coverWeight) * 10000.0 / pow((double)max(1, dist[i][j]), distWeight);\n            if (score > bestScore) { bestScore = score; besti = i; bestj = j; }\n        }\n        \n        if (besti == -1) break;\n        \n        vector<int> pathDir;\n        int ti = besti, tj = bestj;\n        while (ti != ci || tj != cj) {\n            int d = parentDir[ti][tj];\n            pathDir.push_back(d);\n            ti -= di[d]; tj -= dj[d];\n        }\n        reverse(pathDir.begin(), pathDir.end());\n        \n        for (int d : pathDir) {\n            route += dc[d]; ci += di[d]; cj += dj[d]; doCover(ci, cj);\n        }\n    }\n    \n    dijkstra(ci, cj);\n    vector<int> pathDir;\n    int ti = si, tj = sj;\n    while (ti != ci || tj != cj) {\n        int d = parentDir[ti][tj];\n        pathDir.push_back(d);\n        ti -= di[d]; tj -= dj[d];\n    }\n    reverse(pathDir.begin(), pathDir.end());\n    for (int d : pathDir) route += dc[d];\n    \n    return route;\n}\n\nint computeTime(const string& route, int si, int sj) {\n    int t = 0, ci = si, cj = sj;\n    for (char c : route) {\n        int d = string(\"UDLR\").find(c);\n        ci += di[d]; cj += dj[d];\n        t += w(ci, cj);\n    }\n    return t;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (isRoad(i, j)) roads.push_back({i, j});\n    \n    totalRoads = roads.size();\n    \n    visList.assign(N, vector<vector<pair<int,int>>>(N));\n    for (auto& [i, j] : roads) {\n        visList[i][j].push_back({i, j});\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            while (isRoad(ni, nj)) {\n                visList[i][j].push_back({ni, nj});\n                ni += di[d]; nj += dj[d];\n            }\n        }\n    }\n    \n    string bestRoute;\n    int bestTime = INT_MAX;\n    \n    // Parameter sweep\n    for (double dw = 0.8; dw <= 1.4; dw += 0.1) {\n        for (double cw = 0.8; cw <= 1.4; cw += 0.1) {\n            string route = solve(si, sj, dw, cw);\n            int t = computeTime(route, si, sj);\n            if (t < bestTime) {\n                bestTime = t;\n                bestRoute = route;\n            }\n        }\n    }\n    \n    cout << bestRoute << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <set>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> d, deps, reverse_deps;\nvector<vector<double>> s_est;\nvector<int> in_degree, task_start_day, task_status, member_task, critical_len;\nset<int> ready_tasks;\nvector<int> tasks_done_count;\n\nint estimate_time(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++)\n        w += max(0.0, (double)d[task][k] - s_est[member][k]);\n    return max(1, (int)round(w));\n}\n\ndouble estimate_w(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++)\n        w += max(0.0, (double)d[task][k] - s_est[member][k]);\n    return w;\n}\n\nvoid update_skills(int member, int task, int duration) {\n    // Key insight: if duration == 1, then w = 0, meaning s[k] >= d[k] for all k\n    if (duration == 1) {\n        for (int k = 0; k < K; k++) {\n            s_est[member][k] = max(s_est[member][k], (double)d[task][k]);\n        }\n        return;\n    }\n    \n    // For duration > 1, estimate w\n    // t = max(1, w + r) where r ~ U[-3,3]\n    // w \u2248 t when t > 1 (E[r] = 0, but we can estimate w \u2248 t - 0.5)\n    double obs_w = max(1.0, (double)duration - 1.0);\n    \n    // Calculate predicted w and contributions\n    double pred_w = 0;\n    vector<double> contrib(K, 0);\n    for (int k = 0; k < K; k++) {\n        contrib[k] = max(0.0, (double)d[task][k] - s_est[member][k]);\n        pred_w += contrib[k];\n    }\n    \n    if (pred_w < 0.5) {\n        // Predicted to be fast but was slow - skills are overestimated\n        double total_d = 0;\n        for (int k = 0; k < K; k++) total_d += d[task][k];\n        if (total_d > 0) {\n            double dec = obs_w / K * 0.5;\n            for (int k = 0; k < K; k++) {\n                if (d[task][k] > 0) {\n                    s_est[member][k] = max(0.0, s_est[member][k] - dec);\n                }\n            }\n        }\n        return;\n    }\n    \n    double error = obs_w - pred_w;\n    \n    // Learning rate decreases with more observations\n    double lr = 0.5 / (1.0 + tasks_done_count[member] * 0.05);\n    \n    for (int k = 0; k < K; k++) {\n        if (contrib[k] > 1e-9) {\n            double weight = contrib[k] / pred_w;\n            if (error > 0) {\n                // Skills overestimated - decrease\n                s_est[member][k] = max(0.0, s_est[member][k] - error * weight * lr);\n            } else {\n                // Skills underestimated - increase slightly\n                s_est[member][k] -= error * weight * lr * 0.3;\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K >> R;\n    d.resize(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> d[i][k];\n    \n    deps.resize(N); reverse_deps.resize(N); in_degree.assign(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u); reverse_deps[u].push_back(v);\n        in_degree[v]++;\n    }\n    \n    // Topological sort\n    vector<int> order, td = in_degree;\n    queue<int> q;\n    for (int i = 0; i < N; i++) if (td[i] == 0) q.push(i);\n    while (!q.empty()) {\n        int u = q.front(); q.pop(); order.push_back(u);\n        for (int v : reverse_deps[u]) if (--td[v] == 0) q.push(v);\n    }\n    \n    // Critical path length\n    critical_len.assign(N, 0);\n    for (int i = N - 1; i >= 0; i--)\n        for (int v : reverse_deps[order[i]])\n            critical_len[order[i]] = max(critical_len[order[i]], critical_len[v] + 1);\n    \n    // Compute task difficulty statistics\n    double avg_total_d = 0, max_total_d = 0;\n    for (int i = 0; i < N; i++) {\n        double sum = 0;\n        for (int k = 0; k < K; k++) sum += d[i][k];\n        avg_total_d += sum;\n        max_total_d = max(max_total_d, sum);\n    }\n    avg_total_d /= N;\n    \n    // Initialize skill estimates\n    // From problem: skill magnitudes are 20-60, task magnitudes are 10-40\n    // So skills should generally be higher than task requirements\n    s_est.assign(M, vector<double>(K, avg_total_d / K * 0.8));\n    tasks_done_count.assign(M, 0);\n    \n    task_status.assign(N, -1); \n    task_start_day.assign(N, -1); \n    member_task.assign(M, -1);\n    \n    for (int i = 0; i < N; i++) \n        if (in_degree[i] == 0) \n            ready_tasks.insert(i);\n    \n    int day = 0;\n    \n    while (true) {\n        day++;\n        vector<pair<int,int>> assignments;\n        set<int> assigned;\n        \n        // Greedy assignment with exploration bonus\n        while (true) {\n            double best_score = 1e18; \n            int best_m = -1, best_t = -1;\n            \n            for (int m = 0; m < M; m++) {\n                if (member_task[m] != -1) continue;\n                \n                for (int t : ready_tasks) {\n                    if (assigned.count(t)) continue;\n                    \n                    double est_time = estimate_time(t, m);\n                    \n                    // Critical path priority\n                    double priority = critical_len[t] * 0.12;\n                    \n                    // Exploration bonus for members with few tasks\n                    double exploration = 0;\n                    if (tasks_done_count[m] < 5) {\n                        exploration = 2.0 * (5 - tasks_done_count[m]);\n                    }\n                    \n                    double score = est_time - priority - exploration;\n                    \n                    if (score < best_score) {\n                        best_score = score;\n                        best_m = m;\n                        best_t = t;\n                    }\n                }\n            }\n            \n            if (best_m == -1) break;\n            \n            assignments.push_back({best_m + 1, best_t + 1});\n            member_task[best_m] = best_t;\n            task_status[best_t] = 0;\n            task_start_day[best_t] = day;\n            assigned.insert(best_t);\n        }\n        \n        for (auto& p : assignments) \n            ready_tasks.erase(p.second - 1);\n        \n        cout << assignments.size();\n        for (auto& p : assignments) \n            cout << \" \" << p.first << \" \" << p.second;\n        cout << \"\\n\" << flush;\n        \n        int n; \n        cin >> n;\n        if (n == -1) break;\n        \n        for (int i = 0; i < n; i++) {\n            int f; cin >> f; f--;\n            int task = member_task[f];\n            member_task[f] = -1;\n            \n            int duration = day - task_start_day[task] + 1;\n            task_status[task] = 1;\n            tasks_done_count[f]++;\n            \n            // Update skills based on observation\n            update_skills(f, task, duration);\n            \n            // Release dependent tasks\n            for (int v : reverse_deps[task]) {\n                in_degree[v]--;\n                if (in_degree[v] == 0 && task_status[v] == -1) \n                    ready_tasks.insert(v);\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(42);\nconst int DEPOT = 400;\nconst double TIME_LIMIT = 1.85;\n\nint dist(int x1, int y1, int x2, int y2) { return abs(x1-x2) + abs(y1-y2); }\n\nstruct Solver {\n    vector<array<int,4>> orders;\n    vector<int> selected, route, pickup_pos, delivery_pos;\n    chrono::time_point<chrono::steady_clock> start_time;\n    int best_dist;\n    vector<int> best_selected, best_route;\n    \n    void read_input() {\n        orders.resize(1000);\n        for(int i=0;i<1000;i++) cin>>orders[i][0]>>orders[i][1]>>orders[i][2]>>orders[i][3];\n        start_time = chrono::steady_clock::now();\n    }\n    \n    double elapsed() { return chrono::duration<double>(chrono::steady_clock::now()-start_time).count(); }\n    \n    pair<int,int> get_coords(int loc) {\n        if(loc==-1) return {DEPOT,DEPOT};\n        if(loc<50) return {orders[selected[loc]][0], orders[selected[loc]][1]};\n        return {orders[selected[loc-50]][2], orders[selected[loc-50]][3]};\n    }\n    \n    int route_distance() {\n        int d=0;\n        for(int i=0;i+1<(int)route.size();i++) {\n            auto[x1,y1]=get_coords(route[i]); auto[x2,y2]=get_coords(route[i+1]);\n            d+=dist(x1,y1,x2,y2);\n        }\n        return d;\n    }\n    \n    void update_positions() {\n        pickup_pos.assign(50,-1); delivery_pos.assign(50,-1);\n        for(int k=0;k<(int)route.size();k++) {\n            int loc=route[k]; if(loc==-1) continue;\n            if(loc<50) pickup_pos[loc]=k; else delivery_pos[loc-50]=k;\n        }\n    }\n    \n    void save_best() { best_dist=route_distance(); best_selected=selected; best_route=route; }\n    void load_best() { selected=best_selected; route=best_route; update_positions(); }\n    \n    void select_orders_greedy() {\n        vector<pair<int,int>> scored;\n        for(int i=0;i<1000;i++) {\n            int ax=orders[i][0],ay=orders[i][1],bx=orders[i][2],by=orders[i][3];\n            scored.push_back({dist(DEPOT,DEPOT,ax,ay)+dist(ax,ay,bx,by)+dist(bx,by,DEPOT,DEPOT),i});\n        }\n        sort(scored.begin(),scored.end());\n        for(int i=0;i<50;i++) selected.push_back(scored[i].second);\n    }\n    \n    void build_route_nn() {\n        set<int> pending_pickups, pending_deliveries;\n        for(int i=0;i<50;i++) pending_pickups.insert(i);\n        route={-1}; int cx=DEPOT,cy=DEPOT;\n        while(!pending_pickups.empty()||!pending_deliveries.empty()) {\n            int best=-1,best_d=INT_MAX;\n            for(int i:pending_pickups) { auto[x,y]=get_coords(i); int d=dist(cx,cy,x,y); if(d<best_d){best_d=d;best=i;} }\n            for(int i:pending_deliveries) { auto[x,y]=get_coords(i+50); int d=dist(cx,cy,x,y); if(d<best_d){best_d=d;best=i+50;} }\n            route.push_back(best);\n            if(best<50){pending_pickups.erase(best);pending_deliveries.insert(best);}\n            else pending_deliveries.erase(best-50);\n            tie(cx,cy)=get_coords(best);\n        }\n        route.push_back(-1); update_positions();\n    }\n    \n    bool is_valid_2opt(int i,int j) {\n        for(int o=0;o<50;o++) {\n            int p=pickup_pos[o], d=delivery_pos[o];\n            bool pi=(p>=i&&p<=j), di=(d>=i&&d<=j);\n            if((pi&&di)||(pi&&d<i)||(di&&p>j)) return false;\n        }\n        return true;\n    }\n    \n    void local_search_2opt() {\n        int n=route.size(); bool improved=true;\n        while(improved) { improved=false;\n            for(int i=1;i<n-2;i++) for(int j=i+1;j<n-1;j++) {\n                if(!is_valid_2opt(i,j)) continue;\n                auto[xip,yip]=get_coords(route[i-1]); auto[xjn,yjn]=get_coords(route[j+1]);\n                auto[xi,yi]=get_coords(route[i]); auto[xj,yj]=get_coords(route[j]);\n                if(dist(xip,yip,xj,yj)+dist(xi,yi,xjn,yjn) < dist(xip,yip,xi,yi)+dist(xj,yj,xjn,yjn)) {\n                    reverse(route.begin()+i,route.begin()+j+1); update_positions(); improved=true; n=route.size(); break;\n                }\n                if(improved) break;\n            }\n        }\n    }\n    \n    void local_search_relocate() {\n        int n=route.size(); bool improved=true;\n        while(improved) { improved=false;\n            for(int i=1;i<n-1;i++) { int loc=route[i]; if(loc==-1) continue;\n                int ol=(loc<50)?loc:loc-50; bool is_p=loc<50;\n                int op=is_p?delivery_pos[ol]:pickup_pos[ol];\n                int minp=is_p?1:op+1, maxp=is_p?op-1:n-2;\n                for(int np=minp;np<=maxp;np++) { if(np==i||np==i-1) continue;\n                    auto[xp,yp]=get_coords(route[i-1]); auto[xc,yc]=get_coords(route[i]); auto[xn,yn]=get_coords(route[i+1]);\n                    int od=dist(xp,yp,xc,yc)+dist(xc,yc,xn,yn), ndr=dist(xp,yp,xn,yn);\n                    int ip=(np<i)?np+1:np; auto[xi,yi]=get_coords(route[ip-1]); auto[xin,yin]=get_coords(route[ip]);\n                    int odi=dist(xi,yi,xin,yin), ndi=dist(xi,yi,xc,yc)+dist(xc,yc,xin,yin);\n                    if(ndr+ndi<od+odi) {\n                        route.erase(route.begin()+i);\n                        if(np<i) route.insert(route.begin()+np+1,loc); else route.insert(route.begin()+np,loc);\n                        update_positions(); improved=true; n=route.size(); break;\n                    }\n                }\n                if(improved) break;\n            }\n        }\n    }\n    \n    void run_sa() {\n        set<int> sel_set(selected.begin(),selected.end()); save_best();\n        double temp=10000;\n        while(elapsed()<TIME_LIMIT) {\n            int old_dist=route_distance(); auto old_sel=selected, old_rt=route;\n            int out_idx=rng()%50, out_ord=selected[out_idx], in_ord;\n            do{in_ord=rng()%1000;}while(sel_set.count(in_ord));\n            sel_set.erase(out_ord); sel_set.insert(in_ord); selected[out_idx]=in_ord;\n            build_route_nn(); local_search_2opt(); local_search_relocate();\n            int new_dist=route_distance();\n            if(new_dist<old_dist || (double)(rng()%1000000)/1000000.0<exp(-(new_dist-old_dist)/temp)) {\n                if(new_dist<best_dist) save_best();\n            } else { sel_set.erase(in_ord); sel_set.insert(out_ord); selected=old_sel; route=old_rt; update_positions(); }\n            temp*=0.999;\n        }\n        load_best();\n    }\n    \n    void output() {\n        cout<<50; for(int i:selected) cout<<\" \"<<i+1; cout<<\"\\n\";\n        cout<<route.size(); for(int loc:route){auto[x,y]=get_coords(loc);cout<<\" \"<<x<<\" \"<<y;} cout<<\"\\n\";\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    Solver solver; solver.read_input(); solver.select_orders_greedy();\n    solver.build_route_nn(); solver.local_search_2opt(); solver.local_search_relocate(); solver.run_sa();\n    solver.output();\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent, rnk;\npublic:\n    UnionFind(int n) : parent(n), rnk(n, 0) {\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        if (rnk[px] < rnk[py]) swap(px, py);\n        parent[py] = px;\n        if (rnk[px] == rnk[py]) rnk[px]++;\n        return true;\n    }\n    \n    bool same(int x, int y) {\n        return find(x) == find(y);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400;\n    const int M = 1995;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    vector<int> u(M), v(M), d(M);\n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        double dx = (double)(x[u[i]] - x[v[i]]);\n        double dy = (double)(y[u[i]] - y[v[i]]);\n        d[i] = max(1, (int)round(sqrt(dx*dx + dy*dy)));\n    }\n    \n    UnionFind uf(N);\n    int need = N - 1;\n    \n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        int decision = 0;\n        \n        if (!uf.same(u[i], v[i])) {\n            double ratio = (double)l / d[i];\n            int rem = M - i - 1;\n            \n            // Progressive threshold: start selective, become less selective\n            // threshold ranges from 2.0 (early) to 3.0 (late)\n            double progress = (double)i / M;\n            double threshold = 2.0 + 1.0 * progress;\n            \n            // Safety: accept all when running critically low\n            if (rem <= need + 50) {\n                threshold = 3.0;\n            }\n            \n            if (ratio <= threshold) {\n                decision = 1;\n                uf.unite(u[i], v[i]);\n                need--;\n            }\n        }\n        \n        cout << decision << endl;\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <set>\n#include <tuple>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char WALL[] = {'u', 'd', 'l', 'r'};\nconst char MOVE[] = {'U', 'D', 'L', 'R'};\n\nint N, M;\nvector<tuple<int,int,int>> pets_data;\nvector<pair<int,int>> humans_data;\n\nstruct Solver {\n    vector<vector<bool>> wall;\n    vector<tuple<int,int,int>> pets;\n    vector<pair<int,int>> humans;\n    \n    void init() {\n        wall.assign(SIZE, vector<bool>(SIZE, false));\n        pets = pets_data;\n        humans = humans_data;\n    }\n    \n    bool ok(int x, int y) const { return x >= 0 && x < SIZE && y >= 0 && y < SIZE; }\n    \n    bool petAt(int x, int y) const {\n        for (auto& [px, py, pt] : pets) if (px == x && py == y) return true;\n        return false;\n    }\n    \n    bool humanAt(int x, int y) const {\n        for (auto& [hx, hy] : humans) if (hx == x && hy == y) return true;\n        return false;\n    }\n    \n    bool nearPet(int x, int y) const {\n        for (int d = 0; d < 4; d++) if (petAt(x + dx[d], y + dy[d])) return true;\n        return false;\n    }\n    \n    bool canBuild(int h, int d, const set<pair<int,int>>& pw) const {\n        int x = humans[h].first + dx[d];\n        int y = humans[h].second + dy[d];\n        return ok(x, y) && !wall[x][y] && !petAt(x, y) && !humanAt(x, y) && !nearPet(x, y) && !pw.count({x, y});\n    }\n    \n    bool canMove(int h, int d, const set<pair<int,int>>& pw) const {\n        int x = humans[h].first + dx[d];\n        int y = humans[h].second + dy[d];\n        return ok(x, y) && !wall[x][y] && !pw.count({x, y});\n    }\n    \n    pair<int, vector<vector<bool>>> getReach(int sx, int sy) const {\n        vector<vector<bool>> vis(SIZE, vector<bool>(SIZE, false));\n        queue<pair<int,int>> q;\n        q.push({sx, sy});\n        vis[sx][sy] = true;\n        int cnt = 0;\n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop();\n            cnt++;\n            for (int i = 0; i < 4; i++) {\n                int nx = cx + dx[i], ny = cy + dy[i];\n                if (ok(nx, ny) && !vis[nx][ny] && !wall[nx][ny]) {\n                    vis[nx][ny] = true;\n                    q.push({nx, ny});\n                }\n            }\n        }\n        return {cnt, vis};\n    }\n    \n    tuple<int, int, int> analyze(int h) const {\n        auto [area, vis] = getReach(humans[h].first, humans[h].second);\n        int inside = 0, bordering = 0;\n        for (auto& [px, py, pt] : pets) {\n            if (vis[px][py]) inside++;\n            else {\n                for (int d = 0; d < 4; d++) {\n                    if (ok(px + dx[d], py + dy[d]) && vis[px + dx[d]][py + dy[d]]) {\n                        bordering++;\n                        break;\n                    }\n                }\n            }\n        }\n        return {area, inside, bordering};\n    }\n    \n    double scoreState(int h) const {\n        auto [area, inside, bordering] = analyze(h);\n        if (inside > 0) return -1000 - inside; // Very bad to have pets inside\n        return (double)area / (SIZE * SIZE) - 0.01 * bordering;\n    }\n    \n    int minPetDist(int hx, int hy) const {\n        int mnd = SIZE * SIZE;\n        for (auto& [px, py, pt] : pets) mnd = min(mnd, abs(px - hx) + abs(py - hy));\n        return mnd;\n    }\n    \n    char decide(int h, const set<pair<int,int>>& pw) {\n        auto [area, inside, bordering] = analyze(h);\n        int hx = humans[h].first, hy = humans[h].second;\n        int mpd = minPetDist(hx, hy);\n        \n        double best = -1e9;\n        char bestA = '.';\n        int bestD = -1;\n        \n        // Try building walls - much higher priority when pets are far\n        for (int d = 0; d < 4; d++) {\n            if (canBuild(h, d, pw)) {\n                int wx = hx + dx[d], wy = hy + dy[d];\n                wall[wx][wy] = true;\n                double s = scoreState(h);\n                auto [na, ni, nb] = analyze(h);\n                wall[wx][wy] = false;\n                \n                // Strong bonus for blocking bordering pets\n                if (nb < bordering) s += 0.05 * (bordering - nb);\n                \n                // Strong bonus for keeping pets out\n                if (ni == 0 && inside == 0) s += 0.02;\n                \n                if (s > best) { best = s; bestA = WALL[d]; bestD = d; }\n            }\n        }\n        \n        // Try moving\n        for (int d = 0; d < 4; d++) {\n            if (canMove(h, d, pw)) {\n                auto old = humans[h];\n                humans[h].first += dx[d]; humans[h].second += dy[d];\n                double s = scoreState(h);\n                int newMpd = minPetDist(humans[h].first, humans[h].second);\n                humans[h] = old;\n                \n                // If pets inside, try to move away from them\n                if (inside > 0) {\n                    if (newMpd > mpd) s += 0.1;\n                } else {\n                    // If no pets inside, stay close to guard\n                    if (mpd < 4 && newMpd > mpd) s += 0.02;\n                }\n                \n                if (s > best) { best = s; bestA = MOVE[d]; bestD = d; }\n            }\n        }\n        \n        return bestA;\n    }\n    \n    void apply(int h, char a, int d) {\n        if (a >= 'a' && a <= 'z') wall[humans[h].first + dx[d]][humans[h].second + dy[d]] = true;\n        else if (a != '.') { humans[h].first += dx[d]; humans[h].second += dy[d]; }\n    }\n    \n    void readPets() {\n        for (int i = 0; i < N; i++) {\n            string m; cin >> m;\n            auto& [px, py, pt] = pets[i];\n            for (char c : m) {\n                if (c == 'U') px--; else if (c == 'D') px++;\n                else if (c == 'L') py--; else if (c == 'R') py++;\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N; pets_data.resize(N);\n    for (int i = 0; i < N; i++) { int x, y, t; cin >> x >> y >> t; pets_data[i] = {x - 1, y - 1, t}; }\n    cin >> M; humans_data.resize(M);\n    for (int i = 0; i < M; i++) { int x, y; cin >> x >> y; humans_data[i] = {x - 1, y - 1}; }\n    \n    Solver sol; sol.init();\n    \n    for (int t = 0; t < 300; t++) {\n        string act(M, '.'); set<pair<int,int>> pw; vector<int> dirs(M, -1);\n        \n        for (int h = 0; h < M; h++) {\n            char a = sol.decide(h, pw); act[h] = a;\n            for (int d = 0; d < 4; d++) if (a == WALL[d] || a == MOVE[d]) { dirs[h] = d; break; }\n            if (dirs[h] >= 0 && act[h] >= 'a') pw.insert({sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]});\n        }\n        \n        set<pair<int,int>> builds;\n        for (int h = 0; h < M; h++)\n            if (dirs[h] >= 0 && act[h] >= 'a' && act[h] <= 'z')\n                builds.insert({sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]});\n        \n        for (int h = 0; h < M; h++) {\n            if (dirs[h] >= 0 && act[h] >= 'A' && act[h] <= 'Z') {\n                pair<int,int> target = {sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]};\n                if (builds.count(target)) { act[h] = '.'; dirs[h] = -1; }\n            }\n        }\n        \n        for (int h = 0; h < M; h++) if (dirs[h] >= 0) sol.apply(h, act[h], dirs[h]);\n        cout << act << endl; cout.flush();\n        sol.readPets();\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj, ti, tj;\ndouble p, q;\nvector<string> h(20), v(19);\nvector<vector<int>> dist_to_goal;\nconstexpr int di[] = {-1, 1, 0, 0};\nconstexpr int dj[] = {0, 0, -1, 1};\nconstexpr char dirs[] = \"UDLR\";\nmt19937 rng(12345);\n\ninline bool can_move(int i, int j, int d) {\n    if (d == 0) return i > 0 && v[i-1][j] == '0';\n    if (d == 1) return i < 19 && v[i][j] == '0';\n    if (d == 2) return j > 0 && h[i][j-1] == '0';\n    return j < 19 && h[i][j] == '0';\n}\n\nvoid compute_dist() {\n    dist_to_goal.assign(20, vector<int>(20, 1000));\n    queue<pair<int,int>> qq;\n    qq.push({ti, tj});\n    dist_to_goal[ti][tj] = 0;\n    while (!qq.empty()) {\n        auto [i, j] = qq.front(); qq.pop();\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if (dist_to_goal[ni][nj] > dist_to_goal[i][j] + 1) {\n                dist_to_goal[ni][nj] = dist_to_goal[i][j] + 1;\n                qq.push({ni, nj});\n            }\n        }\n    }\n}\n\nstring bfs_path() {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<int>> pm(20, vector<int>(20, -1));\n    queue<pair<int,int>> qq;\n    qq.push({si, sj});\n    dist[si][sj] = 0;\n    while (!qq.empty()) {\n        auto [i, j] = qq.front(); qq.pop();\n        if (i == ti && j == tj) break;\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if (dist[ni][nj] < 0) {\n                dist[ni][nj] = dist[i][j] + 1;\n                pm[ni][nj] = d;\n                qq.push({ni, nj});\n            }\n        }\n    }\n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int d = pm[ci][cj];\n        path = dirs[d] + path;\n        ci -= di[d]; cj -= dj[d];\n    }\n    return path;\n}\n\ndouble simulate(const string& s) {\n    vector<double> prob(400, 0), np(400);\n    prob[si * 20 + sj] = 1.0;\n    double total = 0, reached = 0;\n    int goal = ti * 20 + tj;\n    \n    for (int t = 0; t < (int)s.size(); t++) {\n        fill(np.begin(), np.end(), 0);\n        int mv = string(\"UDLR\").find(s[t]);\n        \n        for (int idx = 0; idx < 400; idx++) {\n            if (prob[idx] < 1e-16) continue;\n            int i = idx / 20, j = idx % 20;\n            np[idx] += p * prob[idx];\n            int ni = i, nj = j;\n            if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n            np[ni * 20 + nj] += q * prob[idx];\n        }\n        swap(prob, np);\n        double nr = prob[goal] * (1 - reached);\n        total += nr * (401 - t - 1);\n        reached += nr;\n        prob[goal] = 0;\n    }\n    return total;\n}\n\n// Fast simulation for beam search\ninline double fast_sim(const vector<float>& prob, int mv, float& nr, vector<float>& np, int t) {\n    nr = 0;\n    double score = 0;\n    int goal = ti * 20 + tj;\n    fill(np.begin(), np.end(), 0);\n    \n    for (int idx = 0; idx < 400; idx++) {\n        if (prob[idx] < 1e-10f) continue;\n        int i = idx / 20, j = idx % 20;\n        np[idx] += p * prob[idx];\n        int ni = i, nj = j;\n        if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n        int nidx = ni * 20 + nj;\n        if (nidx == goal) nr += q * prob[idx];\n        else np[nidx] += q * prob[idx];\n    }\n    return nr * (401 - t - 1);\n}\n\nstring greedy_construct_optimal() {\n    vector<float> prob(400, 0), np(400);\n    prob[si * 20 + sj] = 1.0f;\n    string result;\n    double cumulative_score = 0;\n    int goal = ti * 20 + tj;\n    \n    for (int t = 0; t < 200; t++) {\n        double best_score = -1e18; int bm = 0;\n        float best_nr = 0;\n        vector<float> best_np;\n        \n        for (int mv = 0; mv < 4; mv++) {\n            float nr;\n            double add_score = fast_sim(prob, mv, nr, np, t);\n            \n            // Estimate future value\n            double future = 0;\n            for (int idx = 0; idx < 400; idx++) {\n                if (np[idx] < 1e-10f) continue;\n                int i = idx / 20, j = idx % 20;\n                future += np[idx] * (100 - dist_to_goal[i][j]);\n            }\n            \n            double total = add_score + future * 0.5;\n            if (total > best_score) {\n                best_score = total;\n                bm = mv;\n                best_nr = nr;\n                best_np = np;\n            }\n        }\n        result += dirs[bm];\n        cumulative_score += best_nr * (401 - t - 1);\n        \n        // Update prob, setting goal prob to 0\n        for (int idx = 0; idx < 400; idx++) {\n            prob[idx] = best_np[idx];\n        }\n        prob[goal] = 0;\n    }\n    return result;\n}\n\nstring beam_search_optimal(int width) {\n    struct State {\n        vector<uint8_t> s;\n        vector<float> prob;\n        double score;\n    };\n    \n    vector<State> beam;\n    beam.push_back({{}, vector<float>(400, 0), 0});\n    beam[0].prob[si * 20 + sj] = 1.0f;\n    int goal = ti * 20 + tj;\n    \n    for (int t = 0; t < 200; t++) {\n        vector<State> next;\n        next.reserve(beam.size() * 4);\n        \n        for (auto& st : beam) {\n            for (int mv = 0; mv < 4; mv++) {\n                State ns;\n                ns.s = st.s;\n                ns.s.push_back(mv);\n                ns.prob.resize(400);\n                ns.score = st.score;\n                \n                float nr = 0;\n                fill(ns.prob.begin(), ns.prob.end(), 0);\n                for (int idx = 0; idx < 400; idx++) {\n                    if (st.prob[idx] < 1e-12f) continue;\n                    int i = idx / 20, j = idx % 20;\n                    ns.prob[idx] += p * st.prob[idx];\n                    int ni = i, nj = j;\n                    if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n                    int nidx = ni * 20 + nj;\n                    if (nidx == goal) nr += q * st.prob[idx];\n                    else ns.prob[nidx] += q * st.prob[idx];\n                }\n                ns.score += nr * (401 - t - 1);\n                ns.prob[goal] = 0;\n                next.push_back(move(ns));\n            }\n        }\n        \n        if ((int)next.size() > width) {\n            partial_sort(next.begin(), next.begin() + width, next.end(),\n                [](const State& a, const State& b) { return a.score > b.score; });\n            next.resize(width);\n        }\n        beam = move(next);\n    }\n    \n    string result;\n    for (auto c : beam[0].s) result += dirs[c];\n    return result;\n}\n\nstring sa_improve(string cur, double time_limit) {\n    double cur_score = simulate(cur);\n    string best = cur;\n    double best_score = cur_score;\n    double temp = 500;\n    int iter = 0;\n    auto start = chrono::steady_clock::now();\n    \n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < time_limit) {\n        string ns = cur;\n        int op = rng() % 5;\n        \n        if (op < 2 && !ns.empty()) { // Change\n            int pos = rng() % ns.size();\n            ns[pos] = dirs[rng() % 4];\n        } else if (op < 3 && (int)ns.size() < 200) { // Insert\n            int pos = rng() % (ns.size() + 1);\n            ns.insert(ns.begin() + pos, dirs[rng() % 4]);\n        } else if (op < 4 && !ns.empty()) { // Delete\n            int pos = rng() % ns.size();\n            ns.erase(pos, 1);\n        } else { // Swap adjacent\n            int pos = rng() % max(1, (int)ns.size() - 1);\n            swap(ns[pos], ns[pos + 1]);\n        }\n        \n        double ns_score = simulate(ns);\n        double delta = ns_score - cur_score;\n        \n        if (delta > 0 || exp(delta / temp) > (double)rng() / rng.max()) {\n            cur = ns;\n            cur_score = ns_score;\n            if (cur_score > best_score) {\n                best = cur;\n                best_score = cur_score;\n            }\n        }\n        temp *= 0.998;\n        iter++;\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> si >> sj >> ti >> tj >> p;\n    q = 1 - p;\n    for (int i = 0; i < 20; i++) cin >> h[i];\n    for (int i = 0; i < 19; i++) cin >> v[i];\n    compute_dist();\n    string path = bfs_path();\n    int path_len = path.size();\n    \n    string best; double bsc = -1;\n    auto try_s = [&](const string& s) { \n        if (s.empty() || s.size() > 200) return;\n        double sc = simulate(s); \n        if (sc > bsc) { bsc = sc; best = s; } \n    };\n    \n    // Adaptive repetition count based on p\n    int rep_count = (int)ceil(1.0 / q);\n    rep_count = min(rep_count, 12);\n    \n    // Strategy 1: Repeat whole path\n    { string s; while ((int)s.size() + path_len <= 200) s += path; try_s(s); }\n    \n    // Strategy 2: Adaptive repetition\n    for (int r = max(1, rep_count - 2); r <= rep_count + 2; r++) {\n        string rb;\n        for (char c : path) rb += string(r, c);\n        string s; while ((int)s.size() + (int)rb.size() <= 200) s += rb;\n        try_s(s);\n    }\n    \n    // Strategy 3: Greedy\n    try_s(greedy_construct_optimal());\n    \n    // Strategy 4: Beam search\n    for (int w : {40, 70, 100}) {\n        try_s(beam_search_optimal(w));\n    }\n    \n    // Strategy 5: Multi-start SA\n    vector<string> sa_starts = {best, greedy_construct_optimal()};\n    for (int i = 0; i < 3; i++) {\n        string s = path;\n        for (int j = 0; j < 50 && s.size() < 200; j++) s += path;\n        if (s.size() > 200) s = s.substr(0, 200);\n        sa_starts.push_back(s);\n    }\n    \n    for (auto& start : sa_starts) {\n        string res = sa_improve(start, 0.12);\n        try_s(res);\n    }\n    \n    cout << best << endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint tiles[N][N], rotations[N][N], best_rotations[N][N];\nconstexpr int di[] = {0, -1, 0, 1}, dj[] = {-1, 0, 1, 0};\nconstexpr int to[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}};\nconstexpr int rot_table[8][4] = {\n    {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};\n\npair<long long, long long> compute_loops() {\n    static bool visited[N][N][4];\n    memset(visited, 0, sizeof(visited));\n    long long max1 = 0, max2 = 0;\n    \n    for (int si = 0; si < N; si++) {\n        for (int sj = 0; sj < N; sj++) {\n            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                \n                while (true) {\n                    if (visited[i][j][d]) { len = 0; break; }\n                    visited[i][j][d] = true;\n                    int t = rot_table[tiles[i][j]][rotations[i][j]];\n                    int d2 = to[t][d];\n                    if (d2 == -1) { len = 0; break; }\n                    i += di[d2]; j += dj[d2];\n                    if ((unsigned)i >= N || (unsigned)j >= N) { len = 0; break; }\n                    d = (d2 + 2) & 3; len++;\n                    if (i == si && j == sj && d == sd) break;\n                }\n                \n                if (len > max1) { max2 = max1; max1 = len; }\n                else if (len > max2) max2 = len;\n            }\n        }\n    }\n    return {max1, max2};\n}\n\nlong long compute_score() {\n    auto [max1, max2] = compute_loops();\n    return max2 > 0 ? max1 * max2 : max1;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) tiles[i][j] = s[j] - '0';\n    }\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> rand01(0, 1);\n    uniform_int_distribution<int> randN(0, N-1);\n    uniform_int_distribution<int> rand4(0, 3);\n    \n    long long best_score = 0;\n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(1950);\n    int iterations = 0;\n    \n    while (chrono::steady_clock::now() < deadline) {\n        iterations++;\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) rotations[i][j] = rand4(rng);\n        \n        long long cur_score = compute_score();\n        if (cur_score > best_score) {\n            best_score = cur_score;\n            memcpy(best_rotations, rotations, sizeof(rotations));\n        }\n        \n        double temp = 10000.0;\n        long long local_best = cur_score;\n        int local_best_rot[N][N];\n        memcpy(local_best_rot, rotations, sizeof(rotations));\n        \n        while (temp > 0.1 && chrono::steady_clock::now() < deadline) {\n            int ri = randN(rng), rj = randN(rng);\n            int old = rotations[ri][rj];\n            rotations[ri][rj] = rand4(rng);\n            \n            long long new_score = compute_score();\n            \n            if (new_score > cur_score || rand01(rng) < exp((double)(new_score - cur_score) / temp)) {\n                cur_score = new_score;\n                if (cur_score > local_best) {\n                    local_best = cur_score;\n                    memcpy(local_best_rot, rotations, sizeof(rotations));\n                    if (local_best > best_score) {\n                        best_score = local_best;\n                        memcpy(best_rotations, local_best_rot, sizeof(rotations));\n                    }\n                }\n            } else {\n                rotations[ri][rj] = old;\n            }\n            \n            temp *= 0.9999;\n        }\n    }\n    \n    string result;\n    result.reserve(900);\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) result += char('0' + best_rotations[i][j]);\n    cout << result << '\\n';\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> board;\nint er, ec;\nstring result;\n\nconst int DR[] = {0, -1, 0, 1};\nconst int DC[] = {-1, 0, 1, 0};\nconst char DCS[] = \"LURD\";\n\nint hval(char c) { return c >= 'a' ? c - 'a' + 10 : c - '0'; }\nbool ib(int r, int c) { return r >= 0 && r < N && c >= 0 && c < N; }\n\npair<int,int> evalFull() {\n    vector<int> comp(N*N, -1), compEdges(N*N, 0), compSize(N*N, 0);\n    int numComp = 0;\n    auto idx = [](int r, int c) { return r * N + c; };\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == '0' || comp[idx(i,j)] != -1) continue;\n            queue<pair<int,int>> q;\n            q.push({i,j});\n            comp[idx(i,j)] = numComp;\n            while (!q.empty()) {\n                auto [r,c] = q.front(); q.pop();\n                compSize[comp[idx(r,c)]]++;\n                int v = hval(board[r][c]);\n                auto tc = [&](int nr, int nc, int fb, int tb) {\n                    if (!ib(nr,nc) || board[nr][nc] == '0') return;\n                    int nv = hval(board[nr][nc]);\n                    if ((v & fb) && (nv & tb)) {\n                        compEdges[comp[idx(r,c)]]++;\n                        if (comp[idx(nr,nc)] == -1) {\n                            comp[idx(nr,nc)] = comp[idx(r,c)];\n                            q.push({nr,nc});\n                        }\n                    }\n                };\n                tc(r,c-1,1,4); tc(r-1,c,2,8); tc(r,c+1,4,1); tc(r+1,c,8,2);\n            }\n            numComp++;\n        }\n    }\n    \n    int best = 0, edges = 0;\n    for (int c = 0; c < numComp; c++) {\n        edges += compEdges[c] / 2;\n        if (compEdges[c]/2 == compSize[c] - 1)\n            best = max(best, compSize[c]);\n    }\n    return {best, edges};\n}\n\nint countEdges() {\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] == '0') continue;\n            int v = hval(board[i][j]);\n            if ((v & 4) && j+1 < N && board[i][j+1] != '0' && (hval(board[i][j+1]) & 1)) cnt++;\n            if ((v & 8) && i+1 < N && board[i+1][j] != '0' && (hval(board[i+1][j]) & 2)) cnt++;\n        }\n    }\n    return cnt;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> T;\n    board.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n        for (int j = 0; j < N; j++)\n            if (board[i][j] == '0') { er = i; ec = j; }\n    }\n    \n    mt19937 rng(42);\n    \n    vector<string> bestBoard = board;\n    int bestEr = er, bestEc = ec;\n    string bestResult;\n    int bestTree = evalFull().first;\n    \n    int lastDir = -1;\n    \n    for (int step = 0; step < T && (int)result.size() < T; step++) {\n        vector<pair<int,int>> candidates;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = er + DR[d], nc = ec + DC[d];\n            if (!ib(nr, nc)) continue;\n            \n            int v = hval(board[nr][nc]);\n            int gain = 0;\n            \n            auto check = [&](int r, int c, int fb, int tb, int mul) {\n                if (!ib(r,c) || board[r][c] == '0') return;\n                int nv = hval(board[r][c]);\n                if ((v & fb) && (nv & tb)) gain += mul;\n            };\n            check(er, ec-1, 1, 4, 1);\n            check(er-1, ec, 2, 8, 1);\n            check(er, ec+1, 4, 1, 1);\n            check(er+1, ec, 8, 2, 1);\n            check(nr, nc-1, 1, 4, -1);\n            check(nr-1, nc, 2, 8, -1);\n            check(nr, nc+1, 4, 1, -1);\n            check(nr+1, nc, 8, 2, -1);\n            \n            if (d == (lastDir + 2) % 4) gain -= 3;\n            \n            candidates.push_back({d, gain});\n        }\n        \n        if (candidates.empty()) break;\n        \n        sort(candidates.begin(), candidates.end(), [](auto& a, auto& b) { return a.second > b.second; });\n        \n        int d;\n        double temp = max(0.1, 1.0 - (double)step / T * 0.9);\n        if (rng() % 100 < (int)(temp * 25) && candidates.size() > 1) {\n            d = candidates[1 + rng() % (candidates.size() - 1)].first;\n        } else {\n            d = candidates[0].first;\n        }\n        \n        int nr = er + DR[d], nc = ec + DC[d];\n        swap(board[er][ec], board[nr][nc]);\n        er = nr; ec = nc;\n        result += DCS[d];\n        lastDir = d;\n        \n        if (step % 15 == 14) {\n            auto [treeScore, _] = evalFull();\n            if (treeScore > bestTree) {\n                bestTree = treeScore;\n                bestBoard = board;\n                bestEr = er;\n                bestEc = ec;\n                bestResult = result;\n            }\n            if (treeScore == N*N - 1) { bestResult = result; break; }\n        }\n    }\n    \n    if (bestResult.empty()) bestResult = result;\n    cout << bestResult << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\ntypedef pair<ll, ll> PLL;\n\nconst ll LIM = 1000000000LL;\n\nll cross(PLL a, PLL b) { return a.first * b.second - a.second * b.first; }\n\nint side(PLL p1, PLL p2, PLL q) {\n    PLL d = {p2.first - p1.first, p2.second - p1.second};\n    PLL e = {q.first - p1.first, q.second - p1.second};\n    ll c = cross(d, e);\n    return (c > 0) ? 1 : (c < 0) ? -1 : 0;\n}\n\nint N, K;\nint a[11];\nvector<PLL> S;\nint maxScore;\n\nstruct VectorHash {\n    size_t operator()(const vector<int>& v) const {\n        size_t h = 0;\n        for (int x : v) h = h * 3 + (x + 1);\n        return h;\n    }\n};\n\nint computeScore(const vector<pair<PLL, PLL>>& lines) {\n    int L = lines.size();\n    unordered_map<vector<int>, int, VectorHash> cells;\n    cells.reserve(N * 2);\n    vector<int> sides;\n    for (const auto& s : S) {\n        sides.clear();\n        bool cut = false;\n        for (int i = 0; i < L; i++) {\n            int sd = side(lines[i].first, lines[i].second, s);\n            if (sd == 0) { cut = true; break; }\n            sides.push_back(sd);\n        }\n        if (!cut) cells[sides]++;\n    }\n    int b[11] = {0};\n    for (auto& p : cells) if (p.second >= 1 && p.second <= 10) b[p.second]++;\n    int score = 0;\n    for (int d = 1; d <= 10; d++) score += min(a[d], b[d]);\n    return score;\n}\n\nll clampCoord(ll x) { return max(-LIM, min(LIM, x)); }\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    S.resize(N);\n    for (int i = 0; i < N; i++) cin >> S[i].first >> S[i].second;\n    maxScore = accumulate(a + 1, a + 11, 0);\n    \n    mt19937 rng(42);\n    uniform_int_distribution<ll> coordDist(-LIM, LIM);\n    auto randCoord = [&]() { return coordDist(rng); };\n    \n    vector<pair<PLL, PLL>> bestCuts;\n    int bestScore = 0;\n    clock_t start = clock();\n    const double timeLimit = 2.5;\n    \n    while ((double)(clock() - start) / CLOCKS_PER_SEC < timeLimit && bestScore < maxScore) {\n        vector<pair<PLL, PLL>> cuts;\n        int curScore = 0;\n        \n        for (int i = 0; i < K; i++) {\n            if ((double)(clock() - start) / CLOCKS_PER_SEC >= timeLimit) break;\n            \n            pair<PLL, PLL> bestLine;\n            int bestNew = curScore; bool found = false;\n            \n            for (int t = 0; t < 50; t++) {\n                PLL p1, p2;\n                if (N >= 2 && (rng() & 3)) {\n                    int i1 = rng() % N, i2 = rng() % N;\n                    if (i1 == i2) continue;\n                    ll mx = S[i1].first + S[i2].first;\n                    ll my = S[i1].second + S[i2].second;\n                    ll dx = S[i2].first - S[i1].first;\n                    ll dy = S[i2].second - S[i1].second;\n                    p1 = {clampCoord(mx + dy), clampCoord(my - dx)};\n                    p2 = {clampCoord(mx - dy), clampCoord(my + dx)};\n                } else {\n                    p1 = {randCoord(), randCoord()};\n                    p2 = {randCoord(), randCoord()};\n                }\n                if (p1 == p2) continue;\n                \n                cuts.push_back({p1, p2});\n                int sc = computeScore(cuts);\n                cuts.pop_back();\n                if (sc > bestNew) { bestNew = sc; bestLine = {p1, p2}; found = true; }\n            }\n            if (found) { cuts.push_back(bestLine); curScore = bestNew; }\n            if (curScore > bestScore) { bestScore = curScore; bestCuts = cuts; }\n        }\n        \n        for (int ls = 0; ls < 500; ls++) {\n            if ((double)(clock() - start) / CLOCKS_PER_SEC >= timeLimit) break;\n            if (cuts.empty()) break;\n            int idx = rng() % cuts.size(); auto old = cuts[idx];\n            PLL p1, p2;\n            if (N >= 2 && (rng() & 3)) {\n                int i1 = rng() % N, i2 = rng() % N;\n                if (i1 == i2) continue;\n                ll mx = S[i1].first + S[i2].first;\n                ll my = S[i1].second + S[i2].second;\n                ll dx = S[i2].first - S[i1].first;\n                ll dy = S[i2].second - S[i1].second;\n                p1 = {clampCoord(mx + dy), clampCoord(my - dx)};\n                p2 = {clampCoord(mx - dy), clampCoord(my + dx)};\n            } else {\n                p1 = {randCoord(), randCoord()};\n                p2 = {randCoord(), randCoord()};\n            }\n            if (p1 == p2) continue;\n            \n            cuts[idx] = {p1, p2};\n            int sc = computeScore(cuts);\n            if (sc >= curScore) {\n                curScore = sc;\n                if (curScore > bestScore) { bestScore = curScore; bestCuts = cuts; }\n            } else {\n                cuts[idx] = old;\n            }\n        }\n    }\n    \n    cout << bestCuts.size() << \"\\n\";\n    for (auto& l : bestCuts) {\n        cout << l.first.first << \" \" << l.first.second << \" \" \n             << l.second.first << \" \" << l.second.second << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble C;\nvector<vector<bool>> dot;\nset<array<int, 4>> used_edges;\nvector<array<int, 8>> ops;\nchrono::steady_clock::time_point T0;\nmt19937 rng(42);\n\ndouble elapsed() { return chrono::duration<double>(chrono::steady_clock::now() - T0).count(); }\nint wt(int x, int y) { return (int)((x-C)*(x-C) + (y-C)*(y-C) + 1); }\nbool inB(int x, int y) { return x >= 0 && x < N && y >= 0 && y < N; }\n\nint myGcd(int a, int b) { a=abs(a); b=abs(b); while(b){a%=b; swap(a,b);} return a; }\n\narray<int,4> normE(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) { swap(x1,x2); swap(y1,y2); }\n    return {x1, y1, x2, y2};\n}\n\nbool pathClear(int x1, int y1, int x2, int y2) {\n    int dx = x2-x1, dy = y2-y1, g = myGcd(dx, dy);\n    if (g <= 1) return true;\n    int sx = dx/g, sy = dy/g;\n    for (int i = 1; i < g; i++) if (dot[x1+i*sx][y1+i*sy]) return false;\n    return true;\n}\n\nbool canAddEdge(int x1, int y1, int x2, int y2) {\n    int dx = x2-x1, dy = y2-y1, g = myGcd(dx, dy);\n    if (g == 0) return true;\n    int sx = dx/g, sy = dy/g;\n    for (int i = 0; i < g; i++) {\n        if (used_edges.count(normE(x1+i*sx, y1+i*sy, x1+(i+1)*sx, y1+(i+1)*sy))) return false;\n    }\n    return true;\n}\n\nvoid addEdge(int x1, int y1, int x2, int y2) {\n    int dx = x2-x1, dy = y2-y1, g = myGcd(dx, dy);\n    if (g == 0) return;\n    int sx = dx/g, sy = dy/g;\n    for (int i = 0; i < g; i++) used_edges.insert(normE(x1+i*sx, y1+i*sy, x1+(i+1)*sx, y1+(i+1)*sy));\n}\n\nbool tryAddRect(int px[4], int py[4]) {\n    int perm[] = {0,1,2,3};\n    do {\n        int cx[4], cy[4];\n        for (int i = 0; i < 4; i++) { cx[i] = px[perm[i]]; cy[i] = py[perm[i]]; }\n        if (dot[cx[0]][cy[0]]) continue;\n        bool ok = true;\n        for (int i = 1; i < 4 && ok; i++) if (!dot[cx[i]][cy[i]]) ok = false;\n        if (!ok) continue;\n        for (int i = 0; i < 4 && ok; i++) {\n            int dx = cx[(i+1)%4]-cx[i], dy = cy[(i+1)%4]-cy[i];\n            if (dx==0 && dy==0) ok = false;\n            else if (dx!=0 && dy!=0 && abs(dx)!=abs(dy)) ok = false;\n        }\n        if (!ok) continue;\n        for (int i = 0; i < 4 && ok; i++) {\n            int dx1=cx[(i+1)%4]-cx[i], dy1=cy[(i+1)%4]-cy[i];\n            int dx2=cx[(i+2)%4]-cx[(i+1)%4], dy2=cy[(i+2)%4]-cy[(i+1)%4];\n            if (dx1*dx2 + dy1*dy2 != 0) ok = false;\n        }\n        if (!ok) continue;\n        for (int i = 0; i < 4 && ok; i++) if (!pathClear(cx[i],cy[i],cx[(i+1)%4],cy[(i+1)%4])) ok = false;\n        if (!ok) continue;\n        for (int i = 0; i < 4 && ok; i++) if (!canAddEdge(cx[i],cy[i],cx[(i+1)%4],cy[(i+1)%4])) ok = false;\n        if (!ok) continue;\n        dot[cx[0]][cy[0]] = true;\n        for (int i = 0; i < 4; i++) addEdge(cx[i],cy[i],cx[(i+1)%4],cy[(i+1)%4]);\n        ops.push_back({cx[0],cy[0],cx[1],cy[1],cx[2],cy[2],cx[3],cy[3]});\n        return true;\n    } while (next_permutation(perm, perm+4));\n    return false;\n}\n\nvector<array<int,8>> solve(vector<vector<bool>>& initDot, bool randomize) {\n    dot = initDot;\n    used_edges.clear();\n    ops.clear();\n    \n    vector<vector<int>> byR(N), byC(N), byDP(2*N), byDM(2*N);\n    for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (dot[x][y]) {\n        byR[y].push_back(x); byC[x].push_back(y);\n        byDP[x+y].push_back(x); byDM[x-y+N-1].push_back(x);\n    }\n    \n    while (elapsed() < 4.5) {\n        vector<pair<int,int>> E;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (!dot[x][y]) E.push_back({x,y});\n        if (randomize) shuffle(E.begin(), E.end(), rng);\n        else sort(E.begin(), E.end(), [](auto& a, auto& b){ return wt(a.first,a.second) > wt(b.first,b.second); });\n        \n        bool found = false;\n        for (auto& [nx,ny] : E) {\n            for (int x2 : byR[ny]) { if (x2 == nx) continue;\n                for (int y3 : byC[nx]) { if (y3 == ny) continue;\n                    if (dot[x2][y3]) {\n                        int px[]={nx,x2,x2,nx}, py[]={ny,ny,y3,y3};\n                        if (tryAddRect(px,py)) {\n                            byR[ny].push_back(nx); byC[nx].push_back(ny);\n                            byDP[nx+ny].push_back(nx); byDM[nx-ny+N-1].push_back(nx);\n                            found = true; goto next;\n                        }\n                    }\n                }\n            }\n            for (int x2 : byDM[nx-ny+N-1]) { int y2 = x2-(nx-ny); if (x2==nx) continue;\n                for (int x4 : byDP[nx+ny]) { int y4 = nx+ny-x4; if (x4==nx) continue;\n                    int x3 = x2+x4-nx, y3 = y2+y4-ny;\n                    if (inB(x3,y3) && dot[x3][y3]) {\n                        int px[]={nx,x2,x3,x4}, py[]={ny,y2,y3,y4};\n                        if (tryAddRect(px,py)) {\n                            byR[ny].push_back(nx); byC[nx].push_back(ny);\n                            byDP[nx+ny].push_back(nx); byDM[nx-ny+N-1].push_back(nx);\n                            found = true; goto next;\n                        }\n                    }\n                }\n            }\n        }\n        next:; if (!found) break;\n    }\n    return ops;\n}\n\nint calcScore(vector<vector<bool>>& d) {\n    int score = 0;\n    for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (d[x][y]) score += wt(x,y);\n    return score;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    T0 = chrono::steady_clock::now();\n    cin >> N >> M; C = (N-1)/2.0;\n    vector<vector<bool>> initDot(N, vector<bool>(N, false));\n    for (int i = 0; i < M; i++) { int x,y; cin >> x >> y; initDot[x][y] = true; }\n    \n    auto bestOps = solve(initDot, false);\n    auto bestDot = dot;\n    int bestScore = calcScore(bestDot);\n    \n    while (elapsed() < 4.3) {\n        auto curOps = solve(initDot, true);\n        auto curDot = dot;\n        int curScore = calcScore(curDot);\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestOps = curOps;\n            bestDot = curDot;\n        }\n    }\n    \n    cout << bestOps.size() << \"\\n\";\n    for (auto& o : bestOps) { for (int i = 0; i < 8; i++) cout << o[i] << \" \\n\"[i==7]; }\n    return 0;\n}","ahc015":"#include <iostream>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nint flavors[100];\n\nvoid tilt(int g[N][N], int dir) {\n    int ng[N][N] = {};\n    if (dir == 0) { // F (up)\n        for (int c = 0; c < N; c++) {\n            int wr = 0;\n            for (int r = 0; r < N; r++)\n                if (g[r][c]) ng[wr++][c] = g[r][c];\n        }\n    } else if (dir == 1) { // B (down)\n        for (int c = 0; c < N; c++) {\n            int wr = N-1;\n            for (int r = N-1; r >= 0; r--)\n                if (g[r][c]) ng[wr--][c] = g[r][c];\n        }\n    } else if (dir == 2) { // L (left)\n        for (int r = 0; r < N; r++) {\n            int wc = 0;\n            for (int c = 0; c < N; c++)\n                if (g[r][c]) ng[r][wc++] = g[r][c];\n        }\n    } else { // R (right)\n        for (int r = 0; r < N; r++) {\n            int wc = N-1;\n            for (int c = N-1; c >= 0; c--)\n                if (g[r][c]) ng[r][wc--] = g[r][c];\n        }\n    }\n    memcpy(g, ng, sizeof(ng));\n}\n\nlong long calcScore(int g[N][N]) {\n    int vis[N][N] = {};\n    long long score = 0;\n    const int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n    \n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (!g[r][c] || vis[r][c]) continue;\n            int f = g[r][c], sz = 0;\n            int qr[100], qc[100], qh = 0, qt = 0;\n            qr[qt] = r; qc[qt++] = c; vis[r][c] = 1;\n            while (qh < qt) {\n                int cr = qr[qh], cc = qc[qh++];\n                sz++;\n                for (int d = 0; d < 4; d++) {\n                    int nr = cr + dr[d], nc = cc + dc[d];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && !vis[nr][nc] && g[nr][nc] == f) {\n                        vis[nr][nc] = 1; qr[qt] = nr; qc[qt++] = nc;\n                    }\n                }\n            }\n            score += (long long)sz * sz;\n        }\n    }\n    return score;\n}\n\nint main() {\n    for (int i = 0; i < 100; i++) cin >> flavors[i];\n    \n    for (int t = 0; t < 100; t++) {\n        int p; cin >> p;\n        int cnt = 0;\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (!grid[r][c] && ++cnt == p) { grid[r][c] = flavors[t]; r = N; break; }\n            }\n        }\n        \n        long long best = -1; int bestDir = 0;\n        int temp[N][N];\n        for (int d = 0; d < 4; d++) {\n            memcpy(temp, grid, sizeof(grid));\n            tilt(temp, d);\n            long long score = calcScore(temp);\n            if (score > best) { best = score; bestDir = d; }\n        }\n        \n        tilt(grid, bestDir);\n        cout << \"FBLR\"[bestDir] << endl;\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint M, N, total_edges;\ndouble eps;\nvector<string> G;\nvector<int> edge_counts;\nvector<vector<int>> deg_seqs;\nvector<long long> tri_counts;\n\nint idx(int i, int j) {\n    if (i > j) swap(i, j);\n    return i * (2 * N - i - 1) / 2 + (j - i - 1);\n}\n\nlong long count_triangles(const string& g) {\n    long long cnt = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = i+1; j < N; j++)\n            if (g[idx(i,j)] == '1')\n                for (int k = j+1; k < N; k++)\n                    if (g[idx(i,k)] == '1' && g[idx(j,k)] == '1') cnt++;\n    return cnt;\n}\n\nvoid compute_features(int k) {\n    edge_counts[k] = count(G[k].begin(), G[k].end(), '1');\n    vector<int> deg(N, 0);\n    for (int i = 0; i < N; i++)\n        for (int j = i+1; j < N; j++)\n            if (G[k][idx(i,j)] == '1') { deg[i]++; deg[j]++; }\n    sort(deg.begin(), deg.end());\n    deg_seqs[k] = deg;\n    tri_counts[k] = count_triangles(G[k]);\n}\n\nvoid generate_graphs() {\n    total_edges = N * (N - 1) / 2;\n    G.assign(M, string(total_edges, '0'));\n    edge_counts.resize(M);\n    deg_seqs.assign(M, vector<int>(N));\n    tri_counts.resize(M);\n    \n    for (int k = 0; k < M; k++) {\n        double frac = (M > 1) ? (double)k / (M - 1) : 0.5;\n        int target = (int)round(frac * total_edges);\n        int added = 0;\n        for (int i = 0; i < N && added < target; i++)\n            for (int j = i+1; j < N && added < target; j++, added++)\n                G[k][idx(i,j)] = '1';\n        compute_features(k);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> M >> eps;\n    \n    // N selection: balance between small N (high score) and discrimination power\n    int base_n = max(4, (int)ceil(sqrt(2.0 * M)));\n    if (eps < 0.001) {\n        N = base_n;\n    } else if (eps < 0.1) {\n        N = min(100, base_n + (int)(eps * 40));\n    } else if (eps < 0.2) {\n        N = min(100, base_n + (int)(eps * 50));\n    } else if (eps < 0.3) {\n        N = min(100, base_n + (int)(eps * 60));\n    } else {\n        N = min(100, base_n + (int)(eps * 70));\n    }\n    N = max(N, (int)ceil(sqrt(M) * 1.5));\n    \n    generate_graphs();\n    \n    cout << N << \"\\n\";\n    for (int k = 0; k < M; k++) cout << G[k] << \"\\n\";\n    cout << flush;\n    \n    double scale = max(0.001, 1 - 2*eps);\n    double edge_sd = sqrt(max(1.0, eps * (1-eps) * total_edges));\n    \n    for (int q = 0; q < 100; q++) {\n        string H; cin >> H;\n        \n        int h_edges = count(H.begin(), H.end(), '1');\n        vector<int> h_deg(N, 0);\n        for (int i = 0; i < N; i++)\n            for (int j = i+1; j < N; j++)\n                if (H[idx(i,j)] == '1') { h_deg[i]++; h_deg[j]++; }\n        sort(h_deg.begin(), h_deg.end());\n        \n        // Find the graph with closest expected edge count\n        int best = 0;\n        double best_diff = 1e18;\n        \n        for (int k = 0; k < M; k++) {\n            double exp_e = edge_counts[k] * scale + eps * total_edges;\n            double diff = abs(h_edges - exp_e);\n            if (diff < best_diff) { best_diff = diff; best = k; }\n        }\n        \n        // Refine with degree sequence for lower epsilon\n        if (eps < 0.25) {\n            double best_score = 1e18;\n            for (int k = max(0, best-2); k <= min(M-1, best+2); k++) {\n                double exp_e = edge_counts[k] * scale + eps * total_edges;\n                double edge_z = abs(h_edges - exp_e) / max(0.1, edge_sd);\n                double deg_diff = 0;\n                for (int i = 0; i < N; i++) {\n                    double exp_deg = deg_seqs[k][i] * scale + eps * (N-1);\n                    deg_diff += abs(h_deg[i] - exp_deg);\n                }\n                deg_diff /= N;\n                double score = edge_z + deg_diff * (eps < 0.1 ? 2.0 : 1.0);\n                if (score < best_score) { best_score = score; best = k; }\n            }\n        }\n        \n        cout << best << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\ntypedef pair<ll, int> pli;\nconst ll INF = 1e18;\n\nint N, M, D, K;\nvector<int> eu, ev, ew;\nvector<vector<pair<int, int>>> adj;\n\nvector<ll> dijkstra_skip(int s, int skip) {\n    vector<ll> dist(N, INF);\n    dist[s] = 0;\n    priority_queue<pli, vector<pli>, greater<pli>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist[u]) continue;\n        for (auto& [v, eid] : adj[u]) {\n            if (eid == skip) continue;\n            ll nd = d + ew[eid];\n            if (dist[v] > nd) { dist[v] = nd; pq.push({nd, v}); }\n        }\n    }\n    return dist;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto start = chrono::steady_clock::now();\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    for (int i = 0; i < N; i++) { int x, y; cin >> x >> y; }\n    \n    // Compute edge betweenness and detour ratios\n    vector<ll> betw(M, 0), detour(M, 0);\n    vector<ll> dist_sum(N, 0);\n    \n    for (int s = 0; s < N; s++) {\n        vector<ll> dist(N, INF);\n        vector<int> pred(N, -1);\n        dist[s] = 0;\n        priority_queue<pli, vector<pli>, greater<pli>> pq;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& [v, eid] : adj[u]) {\n                ll nd = d + ew[eid];\n                if (dist[v] > nd) {\n                    dist[v] = nd;\n                    pred[v] = eid;\n                    pq.push({nd, v});\n                }\n            }\n        }\n        \n        for (int t = 0; t < N; t++) {\n            if (t == s || pred[t] == -1) continue;\n            int p = pred[t];\n            betw[p]++;\n            dist_sum[s] += dist[t];\n        }\n    }\n    \n    // Sample detour ratios\n    mt19937 rng_det(456);\n    uniform_int_distribution<int> dist_m(0, M-1);\n    for (int trial = 0; trial < min(M, 300); trial++) {\n        int e = dist_m(rng_det);\n        if (detour[e] > 0) continue;\n        vector<ll> d1 = dijkstra_skip(eu[e], e);\n        detour[e] = d1[ev[e]] - ew[e];\n    }\n    \n    // Normalize and combine metrics\n    ll max_b = *max_element(betw.begin(), betw.end());\n    ll max_d = *max_element(detour.begin(), detour.end());\n    vector<ll> imp(M);\n    for (int i = 0; i < M; i++) {\n        imp[i] = betw[i] * 1000 / max(1LL, max_b) + (detour[i] * 500) / max(1LL, max_d);\n    }\n    \n    // Sort by importance\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) { return imp[a] > imp[b]; });\n    \n    // Round-robin with importance weighting\n    vector<int> assign(M, -1);\n    vector<int> cnt(D, 0);\n    vector<ll> day_imp(D, 0);\n    \n    for (int e : order) {\n        int best = 0;\n        for (int d = 1; d < D; d++) {\n            if (cnt[d] < K && (cnt[best] >= K || day_imp[d] < day_imp[best])) best = d;\n        }\n        assign[e] = best;\n        cnt[best]++;\n        day_imp[best] += imp[e];\n    }\n    \n    // Fast local search\n    mt19937 rng(42);\n    uniform_int_distribution<int> rand_e(0, M-1);\n    \n    // Precompute conflicts (sparse)\n    vector<unordered_map<int, ll>> conf(M);\n    for (int s = 0; s < min(N, 200); s++) {\n        vector<ll> dist(N, INF);\n        vector<vector<int>> pred(N);\n        dist[s] = 0;\n        priority_queue<pli, vector<pli>, greater<pli>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& [v, eid] : adj[u]) {\n                ll nd = d + ew[eid];\n                if (dist[v] > nd) {\n                    dist[v] = nd; pred[v].clear(); pred[v].push_back(eid);\n                    pq.push({nd, v});\n                } else if (dist[v] == nd) pred[v].push_back(eid);\n            }\n        }\n        for (int t = 0; t < N; t++) {\n            set<int> edges;\n            queue<int> q; vector<bool> vis(N, false);\n            q.push(t); vis[t] = true;\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                for (int eid : pred[u]) {\n                    edges.insert(eid);\n                    int p = (eu[eid] == u) ? ev[eid] : eu[eid];\n                    if (!vis[p]) { vis[p] = true; q.push(p); }\n                }\n            }\n            vector<int> ev(edges.begin(), edges.end());\n            for (int i = 0; i < ev.size(); i++)\n                for (int j = i+1; j < ev.size(); j++)\n                    conf[min(ev[i],ev[j])][max(ev[i],ev[j])]++;\n        }\n    }\n    \n    // Score function\n    auto score = [&]() {\n        vector<ll> day_c(D, 0);\n        for (int i = 0; i < M; i++) day_c[assign[i]] += imp[i];\n        for (int i = 0; i < M; i++) {\n            if (conf[i].empty()) continue;\n            for (auto& [j, c] : conf[i]) {\n                if (assign[i] == assign[j]) day_c[assign[i]] += c;\n            }\n        }\n        ll t = 0;\n        for (int d = 0; d < D; d++) t += day_c[d] * day_c[d];\n        return t;\n    };\n    \n    ll cur_score = score();\n    int iter = 0;\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() < 5750) {\n        int e1 = rand_e(rng), e2 = rand_e(rng);\n        if (e1 == e2 || assign[e1] == assign[e2]) continue;\n        \n        swap(assign[e1], assign[e2]);\n        ll new_score = score();\n        \n        if (new_score < cur_score) cur_score = new_score;\n        else swap(assign[e1], assign[e2]);\n        iter++;\n    }\n    \n    for (int i = 0; i < M; i++) cout << assign[i] + 1 << \" \\n\"[i == M-1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f[2], r[2];\nint valid[2][15][15][15];\nint visited[15][15][15];\nint b[2][15][15][15];\nint dx[] = {1,-1,0,0,0,0}, dy[] = {0,0,1,-1,0,0}, dz[] = {0,0,0,0,1,-1};\nvector<array<array<int,3>,3>> rotations;\n\nvoid generateRotations() {\n    vector<array<int,3>> perms = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};\n    for (int s0 : {-1,1}) for (int s1 : {-1,1}) for (int s2 : {-1,1}) {\n        int sp = s0*s1*s2;\n        for (auto& p : perms) {\n            int inv = 0; for (int i=0;i<3;i++) for (int j=i+1;j<3;j++) if (p[i]>p[j]) inv++;\n            if ((inv%2==0) == (sp==1)) {\n                array<array<int,3>,3> R = {};\n                R[0][p[0]]=s0; R[1][p[1]]=s1; R[2][p[2]]=s2;\n                rotations.push_back(R);\n            }\n        }\n    }\n}\n\nset<array<int,3>> normalize(const vector<array<int,3>>& s) {\n    int mX=INT_MAX,mY=INT_MAX,mZ=INT_MAX;\n    for (auto& p : s) { mX=min(mX,p[0]); mY=min(mY,p[1]); mZ=min(mZ,p[2]); }\n    set<array<int,3>> r;\n    for (auto& p : s) r.insert({p[0]-mX, p[1]-mY, p[2]-mZ});\n    return r;\n}\n\nset<array<int,3>> rotate(const set<array<int,3>>& s, const array<array<int,3>,3>& R) {\n    vector<array<int,3>> rot;\n    for (auto& p : s) rot.push_back({R[0][0]*p[0]+R[0][1]*p[1]+R[0][2]*p[2], R[1][0]*p[0]+R[1][1]*p[1]+R[1][2]*p[2], R[2][0]*p[0]+R[2][1]*p[1]+R[2][2]*p[2]});\n    return normalize(rot);\n}\n\nset<array<int,3>> canonical(const set<array<int,3>>& s) {\n    set<array<int,3>> best = s;\n    for (auto& R : rotations) { auto r = rotate(s,R); if (r < best) best = r; }\n    return best;\n}\n\nvector<array<int,3>> bfs(int sel, int sx, int sy, int sz, int interMode) {\n    vector<array<int,3>> comp;\n    queue<array<int,3>> q;\n    q.push({sx,sy,sz});\n    visited[sx][sy][sz] = 1;\n    while (!q.empty()) {\n        auto [x,y,z] = q.front(); q.pop();\n        comp.push_back({x,y,z});\n        for (int d = 0; d < 6; d++) {\n            int nx=x+dx[d], ny=y+dy[d], nz=z+dz[d];\n            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && !visited[nx][ny][nz]) {\n                bool in0 = valid[0][nx][ny][nz], in1 = valid[1][nx][ny][nz];\n                bool ok = false;\n                if (interMode == 0) ok = (sel==0 ? in0&&!in1 : !in0&&in1);\n                else ok = in0 && in1;\n                if (ok) { visited[nx][ny][nz] = 1; q.push({nx,ny,nz}); }\n            }\n        }\n    }\n    return comp;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    generateRotations();\n    cin >> D;\n    for (int i = 0; i < 2; i++) {\n        f[i].resize(D); r[i].resize(D);\n        for (int z = 0; z < D; z++) cin >> f[i][z];\n        for (int z = 0; z < D; z++) cin >> r[i][z];\n    }\n    for (int i = 0; i < 2; i++)\n        for (int x = 0; x < D; x++)\n            for (int y = 0; y < D; y++)\n                for (int z = 0; z < D; z++)\n                    valid[i][x][y][z] = (f[i][z][x]=='1' && r[i][z][y]=='1');\n    \n    vector<vector<array<int,3>>> inter_comps, v1_comps, v2_comps;\n    memset(visited, 0, sizeof(visited));\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++)\n        if (valid[0][x][y][z] && valid[1][x][y][z] && !visited[x][y][z])\n            inter_comps.push_back(bfs(0,x,y,z,1));\n    \n    memset(visited, 0, sizeof(visited));\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++)\n        if (valid[0][x][y][z] && !valid[1][x][y][z] && !visited[x][y][z])\n            v1_comps.push_back(bfs(0,x,y,z,0));\n    \n    memset(visited, 0, sizeof(visited));\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++)\n        if (!valid[0][x][y][z] && valid[1][x][y][z] && !visited[x][y][z])\n            v2_comps.push_back(bfs(1,x,y,z,0));\n    \n    map<set<array<int,3>>, vector<int>> can_v1, can_v2;\n    for (int i = 0; i < (int)v1_comps.size(); i++) can_v1[canonical(normalize(v1_comps[i]))].push_back(i);\n    for (int i = 0; i < (int)v2_comps.size(); i++) can_v2[canonical(normalize(v2_comps[i]))].push_back(i);\n    \n    vector<int> m1(v1_comps.size(),-1), m2(v2_comps.size(),-1);\n    for (auto& [c, idx1] : can_v1) {\n        if (can_v2.count(c)) {\n            auto& idx2 = can_v2[c];\n            for (int k = 0; k < (int)min(idx1.size(), idx2.size()); k++) { m1[idx1[k]] = idx2[k]; m2[idx2[k]] = idx1[k]; }\n        }\n    }\n    \n    memset(b, 0, sizeof(b));\n    int bid = 0;\n    for (auto& c : inter_comps) { bid++; for (auto& p : c) b[0][p[0]][p[1]][p[2]] = b[1][p[0]][p[1]][p[2]] = bid; }\n    for (int i = 0; i < (int)v1_comps.size(); i++) {\n        bid++;\n        for (auto& p : v1_comps[i]) b[0][p[0]][p[1]][p[2]] = bid;\n        if (m1[i] >= 0) for (auto& p : v2_comps[m1[i]]) b[1][p[0]][p[1]][p[2]] = bid;\n    }\n    for (int i = 0; i < (int)v2_comps.size(); i++) if (m2[i] < 0) {\n        bid++;\n        for (auto& p : v2_comps[i]) b[1][p[0]][p[1]][p[2]] = bid;\n    }\n    \n    cout << bid << \"\\n\";\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++) cout << (x||y||z?\" \":\"\") << b[0][x][y][z];\n    cout << \"\\n\";\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++) cout << (x||y||z?\" \":\"\") << b[1][x][y][z];\n    cout << \"\\n\";\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\ntypedef pair<ll, int> pli;\ntypedef pair<int, int> pii;\n\nint N, M, K;\nvector<int> x, y;\nvector<tuple<int, int, ll>> edges;\nvector<int> a, b;\nvector<vector<pii>> adj;\nvector<ll> distTo0;\nvector<int> parent, parent_edge;\n\nint calcDist(int x1, int y1, int x2, int y2) {\n    ll dx = x1 - x2, dy = y1 - y2;\n    return (int)round(sqrt(dx*dx + dy*dy));\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K;\n    x.resize(N); y.resize(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    edges.resize(M); adj.resize(N);\n    for (int j = 0; j < M; j++) {\n        int uj, vj; ll wj;\n        cin >> uj >> vj >> wj;\n        uj--; vj--;\n        edges[j] = {uj, vj, wj};\n        adj[uj].push_back({vj, j});\n        adj[vj].push_back({uj, j});\n    }\n    \n    a.resize(K); b.resize(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    // Dijkstra from vertex 0\n    distTo0.assign(N, LLONG_MAX);\n    parent.assign(N, -1);\n    parent_edge.assign(N, -1);\n    priority_queue<pli, vector<pli>, greater<pli>> pq;\n    distTo0[0] = 0; pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > distTo0[u]) continue;\n        for (auto [v, ej] : adj[u]) {\n            ll wj = get<2>(edges[ej]);\n            if (distTo0[u] + wj < distTo0[v]) {\n                distTo0[v] = distTo0[u] + wj;\n                parent[v] = u; parent_edge[v] = ej;\n                pq.push({distTo0[v], v});\n            }\n        }\n    }\n    \n    // Precompute distances\n    vector<vector<int>> resToStation(K, vector<int>(N));\n    for (int k = 0; k < K; k++) {\n        for (int i = 0; i < N; i++) {\n            resToStation[k][i] = calcDist(a[k], b[k], x[i], y[i]);\n        }\n    }\n    \n    // Cost-aware greedy assignment\n    vector<int> res_station(K);\n    vector<int> station_power(N, 0);\n    set<int> active;\n    \n    // Process residents by difficulty (farthest first)\n    vector<int> order(K);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int k1, int k2) {\n        int m1 = *min_element(resToStation[k1].begin(), resToStation[k1].end());\n        int m2 = *min_element(resToStation[k2].begin(), resToStation[k2].end());\n        return m1 > m2;\n    });\n    \n    for (int k : order) {\n        ll bestCost = LLONG_MAX;\n        int bestStation = -1;\n        \n        for (int i = 0; i < N; i++) {\n            int d = resToStation[k][i];\n            if (d > 5000) continue;\n            \n            ll cost;\n            if (active.count(i)) {\n                int newP = max(station_power[i], d);\n                cost = (ll)newP * newP - (ll)station_power[i] * station_power[i];\n            } else {\n                cost = distTo0[i] + (ll)d * d;\n            }\n            \n            if (cost < bestCost) {\n                bestCost = cost;\n                bestStation = i;\n            }\n        }\n        \n        if (bestStation >= 0) {\n            res_station[k] = bestStation;\n            station_power[bestStation] = max(station_power[bestStation], resToStation[k][bestStation]);\n            active.insert(bestStation);\n        }\n    }\n    \n    // Build edge set\n    vector<int> B(M, 0);\n    auto buildEdges = [&]() {\n        fill(B.begin(), B.end(), 0);\n        for (int i : active) {\n            int cur = i;\n            while (parent[cur] != -1) {\n                B[parent_edge[cur]] = 1;\n                cur = parent[cur];\n            }\n        }\n    };\n    buildEdges();\n    \n    // Remove redundant edges\n    auto getReachable = [&]() {\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(0);\n        visited[0] = true;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (auto [v, ej] : adj[u]) {\n                if (B[ej] && !visited[v]) {\n                    visited[v] = true;\n                    q.push(v);\n                }\n            }\n        }\n        return visited;\n    };\n    \n    auto removeRedundantEdges = [&]() {\n        vector<int> edgeOrder(M);\n        iota(edgeOrder.begin(), edgeOrder.end(), 0);\n        sort(edgeOrder.begin(), edgeOrder.end(), [&](int j1, int j2) {\n            return get<2>(edges[j1]) > get<2>(edges[j2]);\n        });\n        for (int j : edgeOrder) {\n            if (!B[j]) continue;\n            B[j] = 0;\n            auto visited = getReachable();\n            for (int i : active) {\n                if (!visited[i]) { B[j] = 1; break; }\n            }\n        }\n    };\n    removeRedundantEdges();\n    \n    // Local search: remove expensive stations\n    for (int iter = 0; iter < 50; iter++) {\n        bool improved = false;\n        vector<int> stationList(active.begin(), active.end());\n        sort(stationList.begin(), stationList.end(), [&](int i1, int i2) {\n            return (ll)station_power[i1]*station_power[i1] > (ll)station_power[i2]*station_power[i2];\n        });\n        \n        for (int si : stationList) {\n            if (si == 0) continue;\n            \n            vector<int> myRes;\n            for (int k = 0; k < K; k++) if (res_station[k] == si) myRes.push_back(k);\n            if (myRes.empty()) continue;\n            \n            map<int, int> newPowers;\n            vector<int> newAssign(myRes.size());\n            bool ok = true;\n            \n            for (int idx = 0; idx < (int)myRes.size(); idx++) {\n                int k = myRes[idx];\n                ll bestCost = LLONG_MAX;\n                int bestJ = -1;\n                \n                for (int j = 0; j < N; j++) {\n                    if (j == si) continue;\n                    int d = resToStation[k][j];\n                    if (d > 5000) continue;\n                    \n                    int curP = station_power[j];\n                    if (newPowers.count(j)) curP = newPowers[j];\n                    int newP = max(curP, d);\n                    ll cost = (ll)newP*newP - (ll)curP*curP;\n                    if (!active.count(j) && j != 0) cost += distTo0[j];\n                    \n                    if (cost < bestCost) { bestCost = cost; bestJ = j; }\n                }\n                \n                if (bestJ < 0) { ok = false; break; }\n                newAssign[idx] = bestJ;\n                int d = resToStation[k][bestJ];\n                int curP = station_power[bestJ];\n                if (newPowers.count(bestJ)) curP = newPowers[bestJ];\n                newPowers[bestJ] = max(curP, d);\n            }\n            \n            if (!ok) continue;\n            \n            set<int> newActive = active;\n            newActive.erase(si);\n            for (auto& [j, p] : newPowers) if (!active.count(j) && j != 0) newActive.insert(j);\n            \n            ll oldCost = (ll)station_power[si]*station_power[si] + distTo0[si];\n            ll newCost = 0;\n            for (auto& [j, p] : newPowers) {\n                newCost += (ll)p*p - (ll)station_power[j]*station_power[j];\n                if (!active.count(j) && j != 0) newCost += distTo0[j];\n            }\n            \n            if (newCost < oldCost) {\n                improved = true;\n                active = newActive;\n                station_power[si] = 0;\n                for (int idx = 0; idx < (int)myRes.size(); idx++) {\n                    res_station[myRes[idx]] = newAssign[idx];\n                }\n                for (auto& [j, p] : newPowers) station_power[j] = p;\n                buildEdges();\n                removeRedundantEdges();\n            }\n        }\n        if (!improved) break;\n    }\n    \n    for (int i = 0; i < N; i++) cout << station_power[i] << (i < N-1 ? \" \" : \"\\n\");\n    for (int j = 0; j < M; j++) cout << B[j] << (j < M-1 ? \" \" : \"\\n\");\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2;\n\nint pyramid[N][N];\nint pos[TOTAL];\nint dist[TOTAL], parent[TOTAL];\n\nint idx(int x, int y) { return x * (x + 1) / 2 + y; }\n\npair<int,int> coord(int i) {\n    int x = (int)(sqrt(2.0 * i + 0.25) - 0.5);\n    while (idx(x + 1, 0) <= i) x++;\n    return {x, i - idx(x, 0)};\n}\n\nvoid bfs(int s, int target) {\n    fill(dist, dist + TOTAL, -1);\n    fill(parent, parent + TOTAL, -1);\n    queue<int> q;\n    q.push(s);\n    dist[s] = 0;\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        auto [x, y] = coord(u);\n        vector<pair<int,int>> neighbors;\n        if (x > 0 && y > 0) neighbors.push_back({x-1, y-1});\n        if (x > 0 && y < x) neighbors.push_back({x-1, y});\n        if (y > 0) neighbors.push_back({x, y-1});\n        if (y < x) neighbors.push_back({x, y+1});\n        if (x < N-1) neighbors.push_back({x+1, y});\n        if (x < N-1) neighbors.push_back({x+1, y+1});\n        for (auto [nx, ny] : neighbors) {\n            int p = idx(nx, ny);\n            // Block positions that have their correct values and are before target\n            if (pyramid[nx][ny] == p && p < target) continue;\n            if (dist[p] == -1) {\n                dist[p] = dist[u] + 1;\n                parent[p] = u;\n                q.push(p);\n            }\n        }\n    }\n}\n\nint count_violations() {\n    int E = 0;\n    for (int x = 0; x < N-1; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) E++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) E++;\n        }\n    }\n    return E;\n}\n\nint count_edges(int x, int y) {\n    int cnt = 0;\n    if (x > 0) {\n        if (y > 0 && pyramid[x-1][y-1] > pyramid[x][y]) cnt++;\n        if (y < x && pyramid[x-1][y] > pyramid[x][y]) cnt++;\n    }\n    if (x < N-1) {\n        if (pyramid[x][y] > pyramid[x+1][y]) cnt++;\n        if (pyramid[x][y] > pyramid[x+1][y+1]) cnt++;\n    }\n    return cnt;\n}\n\nvector<pair<int,int>> get_neighbors(int x, int y) {\n    vector<pair<int,int>> neighbors;\n    if (x > 0 && y > 0) neighbors.push_back({x-1, y-1});\n    if (x > 0 && y < x) neighbors.push_back({x-1, y});\n    if (y > 0) neighbors.push_back({x, y-1});\n    if (y < x) neighbors.push_back({x, y+1});\n    if (x < N-1) neighbors.push_back({x+1, y});\n    if (x < N-1) neighbors.push_back({x+1, y+1});\n    return neighbors;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n            pos[pyramid[x][y]] = idx(x, y);\n        }\n    }\n    \n    vector<array<int,4>> moves;\n    \n    // Phase 1: Greedy placement with blocking\n    for (int v = 0; v < TOTAL && (int)moves.size() < 9800; v++) {\n        int cur = pos[v];\n        if (cur == v) continue;\n        \n        bfs(cur, v);\n        \n        if (dist[v] == -1) continue;\n        \n        vector<int> path;\n        for (int u = v; u != -1; u = parent[u]) path.push_back(u);\n        reverse(path.begin(), path.end());\n        \n        for (size_t i = 0; i+1 < path.size() && (int)moves.size() < 9800; i++) {\n            auto [x1, y1] = coord(path[i]);\n            auto [x2, y2] = coord(path[i+1]);\n            int v1 = pyramid[x1][y1], v2 = pyramid[x2][y2];\n            pos[v1] = path[i+1];\n            pos[v2] = path[i];\n            swap(pyramid[x1][y1], pyramid[x2][y2]);\n            moves.push_back({x1, y1, x2, y2});\n        }\n    }\n    \n    // Phase 2: Local improvement\n    while ((int)moves.size() < 10000) {\n        int best_delta = 0;\n        array<int, 4> best_move;\n        \n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y <= x; y++) {\n                auto neighbors = get_neighbors(x, y);\n                for (auto [nx, ny] : neighbors) {\n                    if (nx < x || (nx == x && ny < y)) continue;\n                    \n                    int before = count_edges(x, y) + count_edges(nx, ny);\n                    swap(pyramid[x][y], pyramid[nx][ny]);\n                    int after = count_edges(x, y) + count_edges(nx, ny);\n                    swap(pyramid[x][y], pyramid[nx][ny]);\n                    \n                    int delta = before - after;\n                    if (delta > best_delta) {\n                        best_delta = delta;\n                        best_move = {x, y, nx, ny};\n                    }\n                }\n            }\n        }\n        \n        if (best_delta <= 0) break;\n        \n        int x = best_move[0], y = best_move[1], nx = best_move[2], ny = best_move[3];\n        swap(pyramid[x][y], pyramid[nx][ny]);\n        moves.push_back(best_move);\n    }\n    \n    cout << moves.size() << \"\\n\";\n    for (auto& m : moves) {\n        cout << m[0] << \" \" << m[1] << \" \" << m[2] << \" \" << m[3] << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D, N;\n    cin >> D >> N;\n    \n    set<pair<int,int>> obstacles;\n    for (int i = 0; i < N; i++) {\n        int ri, rj; cin >> ri >> rj;\n        obstacles.insert({ri, rj});\n    }\n    \n    int entrance_j = (D - 1) / 2;\n    int M = D * D - 1 - N;\n    \n    vector<pair<int,int>> cells;\n    map<pair<int,int>, int> cell_to_idx;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (!(i == 0 && j == entrance_j) && !obstacles.count({i, j})) {\n                cell_to_idx[{i, j}] = cells.size();\n                cells.push_back({i, j});\n            }\n    \n    int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n    auto valid = [&](int i, int j) { return i >= 0 && i < D && j >= 0 && j < D; };\n    \n    vector<vector<int>> dist(D, vector<int>(D, INT_MAX));\n    queue<pair<int,int>> q; q.push({0, entrance_j}); dist[0][entrance_j] = 0;\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (valid(ni, nj) && dist[ni][nj] == INT_MAX && !obstacles.count({ni, nj})) {\n                dist[ni][nj] = dist[i][j] + 1; q.push({ni, nj});\n            }\n        }\n    }\n    \n    vector<int> downstream(cells.size(), 0);\n    for (size_t c = 0; c < cells.size(); c++) {\n        auto [ci, cj] = cells[c];\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<pair<int,int>> bq; bq.push({0, entrance_j});\n        visited[0][entrance_j] = true; visited[ci][cj] = true;\n        while (!bq.empty()) {\n            auto [i, j] = bq.front(); bq.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (valid(ni, nj) && !visited[ni][nj] && !obstacles.count({ni, nj})) {\n                    visited[ni][nj] = true; bq.push({ni, nj});\n                }\n            }\n        }\n        for (size_t cc = 0; cc < cells.size(); cc++)\n            if (!visited[cells[cc].first][cells[cc].second]) downstream[c]++;\n    }\n    \n    vector<int> order(cells.size()); iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        int da = dist[cells[a].first][cells[a].second], db = dist[cells[b].first][cells[b].second];\n        return da != db ? da < db : (downstream[a] != downstream[b] ? downstream[a] > downstream[b] : cells[a] < cells[b]);\n    });\n    vector<int> cell_rank(cells.size());\n    for (size_t i = 0; i < order.size(); i++) cell_rank[order[i]] = i;\n    \n    vector<int> container_at_cell(cells.size(), -1), container_cell(M, -1);\n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        vector<int> available;\n        for (size_t c = 0; c < cells.size(); c++) if (container_at_cell[c] == -1) available.push_back(c);\n        sort(available.begin(), available.end(), [&](int a, int b) { return cell_rank[a] < cell_rank[b]; });\n        int idx = (M == 1) ? 0 : min((int)available.size()-1, max(0, (int)round((double)t/(M-1)*(available.size()-1))));\n        container_at_cell[available[idx]] = t; container_cell[t] = available[idx];\n        cout << cells[available[idx]].first << \" \" << cells[available[idx]].second << \"\\n\" << flush;\n    }\n    \n    vector<bool> present(M, true);\n    for (int step = 0; step < M; step++) {\n        set<int> reachable;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<pair<int,int>> bq; bq.push({0, entrance_j}); visited[0][entrance_j] = true;\n        while (!bq.empty()) {\n            auto [i, j] = bq.front(); bq.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (!valid(ni, nj) || visited[ni][nj] || obstacles.count({ni, nj})) continue;\n                auto it = cell_to_idx.find({ni, nj});\n                if (it == cell_to_idx.end()) { visited[ni][nj] = true; bq.push({ni, nj}); }\n                else if (present[container_at_cell[it->second]]) reachable.insert(container_at_cell[it->second]);\n                else { visited[ni][nj] = true; bq.push({ni, nj}); }\n            }\n        }\n        int best = *reachable.begin(); present[best] = false;\n        cout << cells[container_cell[best]].first << \" \" << cells[container_cell[best]].second << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    auto start = chrono::steady_clock::now();\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> orig(n, vector<int>(n));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            cin >> orig[i][j];\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    auto inside = [](int x, int y, int N) { return x >= 0 && x < N && y >= 0 && y < N; };\n    \n    set<pair<int,int>> origAdjSet;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                int nc = inside(ni, nj, n) ? orig[ni][nj] : 0;\n                if (nc != orig[i][j]) {\n                    int a = orig[i][j], b = nc;\n                    if (a > b) swap(a, b);\n                    origAdjSet.insert({a, b});\n                }\n            }\n        }\n    }\n    \n    mt19937 rng(12345);\n    vector<pair<int,int>> baseOrder;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            baseOrder.push_back({i, j});\n    \n    auto solve = [&](vector<pair<int,int>> order) -> pair<int, vector<vector<int>>> {\n        vector g = orig;\n        map<pair<int,int>, int> adjCnt;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    int nc = inside(ni, nj, n) ? g[ni][nj] : 0;\n                    if (nc != g[i][j]) {\n                        int a = g[i][j], b = nc;\n                        if (a > b) swap(a, b);\n                        adjCnt[{a, b}]++;\n                    }\n                }\n            }\n        }\n        \n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (auto [i, j] : order) {\n                if (g[i][j] == 0) continue;\n                int c = g[i][j];\n                \n                bool conn0 = (i == 0 || i == n-1 || j == 0 || j == n-1);\n                if (!conn0) {\n                    for (int d = 0; d < 4; d++) {\n                        int ni = i + dx[d], nj = j + dy[d];\n                        if (inside(ni, nj, n) && g[ni][nj] == 0) { conn0 = true; break; }\n                    }\n                }\n                if (!conn0) continue;\n                \n                map<pair<int,int>, int> delta;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    bool in = inside(ni, nj, n);\n                    int nc = in ? g[ni][nj] : 0;\n                    if (nc != c) {\n                        int a = c, b = nc;\n                        if (a > b) swap(a, b);\n                        delta[{a, b}]--;\n                        if (in) delta[{a, b}]--;\n                    }\n                    if (nc != 0) {\n                        int a = 0, b = nc;\n                        if (a > b) swap(a, b);\n                        delta[{a, b}] += 2;\n                    }\n                }\n                \n                bool ok = true;\n                for (auto& [p, ch] : delta) {\n                    int newCnt = adjCnt[p] + ch;\n                    if (newCnt > 0 && origAdjSet.count(p) == 0) { ok = false; break; }\n                    if (newCnt == 0 && origAdjSet.count(p) > 0) { ok = false; break; }\n                }\n                if (!ok) continue;\n                \n                vector<pair<int,int>> sameColorNbrs;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    if (inside(ni, nj, n) && g[ni][nj] == c)\n                        sameColorNbrs.push_back({ni, nj});\n                }\n                \n                bool connected = true;\n                if (sameColorNbrs.size() > 1) {\n                    g[i][j] = 0;\n                    queue<int> q;\n                    vector<bool> vis(n * n, false);\n                    q.push(sameColorNbrs[0].first * n + sameColorNbrs[0].second);\n                    vis[sameColorNbrs[0].first * n + sameColorNbrs[0].second] = true;\n                    while (!q.empty()) {\n                        int cur = q.front(); q.pop();\n                        int x = cur / n, y = cur % n;\n                        for (int d = 0; d < 4; d++) {\n                            int nx = x + dx[d], ny = y + dy[d];\n                            if (inside(nx, ny, n) && g[nx][ny] == c && !vis[nx * n + ny]) {\n                                vis[nx * n + ny] = true;\n                                q.push(nx * n + ny);\n                            }\n                        }\n                    }\n                    for (auto& p : sameColorNbrs) {\n                        if (!vis[p.first * n + p.second]) { connected = false; break; }\n                    }\n                    g[i][j] = c;\n                }\n                \n                if (connected) {\n                    g[i][j] = 0;\n                    for (auto& [p, ch] : delta) adjCnt[p] += ch;\n                    changed = true;\n                }\n            }\n        }\n        \n        int score = 0;\n        for (int i = 0; i < n; i++)\n            for (int j = 0; j < n; j++)\n                if (g[i][j] == 0) score++;\n        \n        return {score, g};\n    };\n    \n    int bestScore = -1;\n    vector<vector<int>> bestG;\n    \n    auto check = [&](vector<pair<int,int>> order) {\n        auto [s, g] = solve(order);\n        if (s > bestScore) { bestScore = s; bestG = g; }\n    };\n    \n    check(baseOrder);\n    auto rev = baseOrder; reverse(rev.begin(), rev.end()); check(rev);\n    \n    vector<pair<int,int>> colMajor;\n    for (int j = 0; j < n; j++) for (int i = 0; i < n; i++) colMajor.push_back({i, j});\n    check(colMajor); reverse(colMajor.begin(), colMajor.end()); check(colMajor);\n    \n    // Spiral\n    {\n        vector<pair<int,int>> spiral;\n        int t = 0, b = n-1, l = 0, r = n-1;\n        while (t <= b && l <= r) {\n            for (int j = l; j <= r; j++) spiral.push_back({t, j});\n            t++;\n            for (int i = t; i <= b; i++) spiral.push_back({i, r});\n            r--;\n            if (t <= b) { for (int j = r; j >= l; j--) spiral.push_back({b, j}); b--; }\n            if (l <= r) { for (int i = b; i >= t; i--) spiral.push_back({i, l}); l++; }\n        }\n        check(spiral); reverse(spiral.begin(), spiral.end()); check(spiral);\n    }\n    \n    // Diagonal\n    {\n        vector<pair<int,int>> diag;\n        for (int s = 0; s < 2*n-1; s++)\n            for (int i = 0; i < n; i++) {\n                int j = s - i;\n                if (j >= 0 && j < n) diag.push_back({i, j});\n            }\n        check(diag); reverse(diag.begin(), diag.end()); check(diag);\n    }\n    \n    // Random with time limit\n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < 1.8) {\n        auto randOrder = baseOrder;\n        shuffle(randOrder.begin(), randOrder.end(), rng);\n        check(randOrder);\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << bestG[i][j];\n            if (j < n - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\nint N, D, Q;\nint qc = 0;\nvector<vector<int>> cmp_res;\n\nchar query(const vector<int>& L, const vector<int>& R) {\n    qc++;\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    char r; cin >> r;\n    return r;\n}\n\nint cmp_items(int a, int b) {\n    if (cmp_res[a][b] != 0) return cmp_res[a][b];\n    char r = query({a}, {b});\n    cmp_res[a][b] = (r == '<') ? 1 : (r == '=') ? 2 : 3;\n    cmp_res[b][a] = (r == '>') ? 1 : (r == '=') ? 2 : 3;\n    return cmp_res[a][b];\n}\n\nbool le(int a, int b) {\n    int r = cmp_items(a, b);\n    return r == 1 || r == 2;\n}\n\nvoid merge_sort(vector<int>& arr, int l, int r) {\n    if (l >= r) return;\n    int m = (l + r) / 2;\n    merge_sort(arr, l, m);\n    merge_sort(arr, m + 1, r);\n    vector<int> tmp;\n    int i = l, j = m + 1;\n    while (i <= m && j <= r) {\n        if (le(arr[i], arr[j])) tmp.push_back(arr[i++]);\n        else tmp.push_back(arr[j++]);\n    }\n    while (i <= m) tmp.push_back(arr[i++]);\n    while (j <= r) tmp.push_back(arr[j++]);\n    for (int k = l; k <= r; k++) arr[k] = tmp[k - l];\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    cmp_res.assign(N, vector<int>(N, 0));\n    \n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    merge_sort(order, 0, N - 1);\n    \n    vector<double> ew(N);\n    for (int i = 0; i < N; i++) ew[order[i]] = i + 1;\n    \n    vector<double> sw(D, 0);\n    vector<int> ans(N);\n    vector<vector<int>> sets(D);\n    \n    for (int i = N - 1; i >= 0; i--) {\n        int item = order[i];\n        int ms = 0;\n        for (int d = 1; d < D; d++) if (sw[d] < sw[ms]) ms = d;\n        ans[item] = ms;\n        sets[ms].push_back(item);\n        sw[ms] += ew[item];\n    }\n    \n    for (int d = 0; d < D; d++)\n        sort(sets[d].begin(), sets[d].end(), [&](int a, int b) { return ew[a] < ew[b]; });\n    \n    while (qc + 1 <= Q) {\n        int heavy = 0, light = 0;\n        for (int d = 1; d < D; d++) {\n            if (sw[d] > sw[heavy]) heavy = d;\n            if (sw[d] < sw[light]) light = d;\n        }\n        \n        if (heavy == light || sets[heavy].empty()) break;\n        \n        char result = query(sets[heavy], sets[light]);\n        if (result == '=') break;\n        if (result == '<') swap(heavy, light);\n        \n        int to_move = sets[heavy][0];\n        sets[heavy].erase(sets[heavy].begin());\n        \n        auto it = lower_bound(sets[light].begin(), sets[light].end(), to_move,\n                              [&](int a, int b) { return ew[a] < ew[b]; });\n        sets[light].insert(it, to_move);\n        \n        sw[heavy] -= ew[to_move];\n        sw[light] += ew[to_move];\n        ans[to_move] = light;\n    }\n    \n    while (qc < Q) query({0}, {1});\n    \n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << ans[i];\n    }\n    cout << \"\\n\" << flush;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> st(m);\n    for (int i = 0; i < m; i++) {\n        st[i].resize(n/m);\n        for (int j = 0; j < n/m; j++) {\n            cin >> st[i][j];\n        }\n    }\n    \n    vector<pair<int, int>> ops;\n    \n    for (int v = 1; v <= n; v++) {\n        int si = -1, pos = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)st[i].size(); j++) {\n                if (st[i][j] == v) {\n                    si = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (si != -1) break;\n        }\n        \n        if (si == -1) continue;\n        \n        if (pos < (int)st[si].size() - 1) {\n            int maxMoved = INT_MIN, minMoved = INT_MAX;\n            int movedSize = st[si].size() - pos - 1;\n            for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                maxMoved = max(maxMoved, st[si][j]);\n                minMoved = min(minMoved, st[si][j]);\n            }\n            \n            int dest = -1;\n            int bestCost = INT_MAX;\n            int bestTiebreaker = INT_MIN;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == si) continue;\n                \n                int cost;\n                int tiebreaker;\n                \n                if (st[i].empty()) {\n                    cost = 0;\n                    tiebreaker = 100000;\n                } else {\n                    int top = st[i].back();\n                    if (top > maxMoved) {\n                        cost = 0;\n                        tiebreaker = top * 1000 + (200 - st[i].size());\n                    } else if (top < minMoved) {\n                        cost = movedSize;\n                        tiebreaker = -st[i].size();\n                    } else {\n                        int blockingCount = 0;\n                        for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                            if (st[si][j] > top) blockingCount++;\n                        }\n                        cost = blockingCount;\n                        tiebreaker = top - st[i].size();\n                    }\n                }\n                \n                if (cost < bestCost || (cost == bestCost && tiebreaker > bestTiebreaker)) {\n                    bestCost = cost;\n                    bestTiebreaker = tiebreaker;\n                    dest = i;\n                }\n            }\n            \n            int boxAbove = st[si][pos + 1];\n            ops.push_back({boxAbove, dest + 1});\n            \n            for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                st[dest].push_back(st[si][j]);\n            }\n            st[si].resize(pos + 1);\n        }\n        \n        ops.push_back({v, 0});\n        st[si].pop_back();\n    }\n    \n    for (auto& [a, b] : ops) {\n        cout << a << \" \" << b << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#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<string> h(N-1), v(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};\n    char dirChar[] = {'R', 'D', 'L', 'U'};\n    \n    auto canMove = [&](int i, int j, int k) -> bool {\n        int ni = i + di[k], nj = j + dj[k];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n        if (di[k] != 0) return h[min(i, ni)][j] == '0';\n        return v[i][min(j, nj)] == '0';\n    };\n    \n    // BFS from origin to compute distances\n    vector<vector<int>> dist0(N, vector<int>(N, -1));\n    vector<vector<int>> prevDir(N, vector<int>(N, -1));\n    queue<pair<int,int>> qu;\n    qu.push({0, 0});\n    dist0[0][0] = 0;\n    while (!qu.empty()) {\n        auto [i, j] = qu.front(); qu.pop();\n        for (int k = 0; k < 4; k++) {\n            if (!canMove(i, j, k)) continue;\n            int ni = i + di[k], nj = j + dj[k];\n            if (dist0[ni][nj] < 0) {\n                dist0[ni][nj] = dist0[i][j] + 1;\n                prevDir[ni][nj] = k;\n                qu.push({ni, nj});\n            }\n        }\n    }\n    \n    // DFS tour prioritizing high-d cells\n    vector visited(N, vector<bool>(N, false));\n    string tour;\n    \n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        vector<tuple<int,int,int,int>> neighbors;\n        for (int k = 0; k < 4; k++) {\n            if (!canMove(i, j, k)) continue;\n            int ni = i + di[k], nj = j + dj[k];\n            if (!visited[ni][nj]) {\n                neighbors.emplace_back(-d[ni][nj], dist0[ni][nj], ni, nj);\n            }\n        }\n        sort(neighbors.begin(), neighbors.end());\n        for (auto& [_, __, ni, nj] : neighbors) {\n            for (int k = 0; k < 4; k++) {\n                if (i + di[k] == ni && j + dj[k] == nj) {\n                    tour += dirChar[k];\n                    dfs(ni, nj);\n                    tour += dirChar[(k+2)%4];\n                    break;\n                }\n            }\n        }\n    };\n    dfs(0, 0);\n    \n    // Greedy addition of round trips\n    vector visitCount(N, vector<int>(N, 1));\n    int budget = 100000 - (int)tour.size();\n    \n    // Compute sum of d[i][j]/v[i][j] for global scaling\n    double sumWeightedInv = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            sumWeightedInv += (double)d[i][j] / visitCount[i][j];\n    \n    long long L = tour.size();\n    \n    auto addRoundTrip = [&](int ti, int tj) {\n        string fwd;\n        int ci = ti, cj = tj;\n        while (ci != 0 || cj != 0) {\n            int k = prevDir[ci][cj];\n            fwd += dirChar[k];\n            ci -= di[k];\n            cj -= dj[k];\n        }\n        reverse(fwd.begin(), fwd.end());\n        string back = fwd;\n        reverse(back.begin(), back.end());\n        for (char& c : back) {\n            if (c == 'R') c = 'L';\n            else if (c == 'L') c = 'R';\n            else if (c == 'U') c = 'D';\n            else c = 'U';\n        }\n        tour += fwd + back;\n    };\n    \n    // Benefit = improvement at target cell - global penalty\n    auto computeBenefit = [&](int i, int j, int v, double sumWI) -> double {\n        int cost = 2 * dist0[i][j];\n        if (cost <= 0) return -1e18;\n        // Improvement at cell (i,j): d * L / (2*v*(v+1))\n        double improvement = (double)d[i][j] * L / (2.0 * v * (v + 1));\n        // Global penalty: cost * sumWeightedInv / 2\n        double penalty = cost * sumWI / 2.0;\n        return improvement - penalty;\n    };\n    \n    priority_queue<tuple<double, int, int, int>> pq;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == 0 && j == 0) continue;\n            double benefit = computeBenefit(i, j, 1, sumWeightedInv);\n            if (benefit > 0) pq.push({benefit, 1, i, j});\n        }\n    }\n    \n    while (!pq.empty() && budget > 10) {\n        auto [oldBenefit, v, i, j] = pq.top(); pq.pop();\n        \n        if (v != visitCount[i][j]) continue;\n        \n        int cost = 2 * dist0[i][j];\n        if (cost > budget) continue;\n        \n        double benefit = computeBenefit(i, j, v, sumWeightedInv);\n        if (benefit <= 0) continue;\n        \n        // Update sumWeightedInv\n        sumWeightedInv -= (double)d[i][j] / v;\n        sumWeightedInv += (double)d[i][j] / (v + 1);\n        \n        addRoundTrip(i, j);\n        visitCount[i][j]++;\n        L += cost;\n        budget -= cost;\n        \n        int nv = visitCount[i][j];\n        double newBenefit = computeBenefit(i, j, nv, sumWeightedInv);\n        if (newBenefit > 0) pq.push({newBenefit, nv, i, j});\n    }\n    \n    cout << tour << '\\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(nullptr);\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<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 * N + j);\n    \n    auto getCoord = [N](int idx) { return make_pair(idx / N, idx % N); };\n    \n    auto computeOverlap = [](const string& a, const string& b) {\n        for (int len = (int)min(a.size(), b.size()); len >= 0; len--) {\n            bool match = true;\n            for (int i = 0; i < len && match; i++)\n                if (a[a.size() - len + i] != b[i]) match = false;\n            if (match) return len;\n        }\n        return 0;\n    };\n    \n    string superstring = words[0];\n    vector<bool> used(M, false);\n    used[0] = true;\n    \n    for (int k = 1; k < M; k++) {\n        int best_idx = -1, best_overlap = -1;\n        bool appendBack = true;\n        \n        for (int i = 0; i < M; i++) {\n            if (used[i]) continue;\n            int o1 = computeOverlap(superstring, words[i]);\n            int o2 = computeOverlap(words[i], superstring);\n            if (o1 > best_overlap) { best_overlap = o1; best_idx = i; appendBack = true; }\n            if (o2 > best_overlap) { best_overlap = o2; best_idx = i; appendBack = false; }\n        }\n        \n        if (appendBack) superstring += words[best_idx].substr(best_overlap);\n        else superstring = words[best_idx] + superstring.substr(best_overlap);\n        used[best_idx] = true;\n    }\n    \n    int L = superstring.size();\n    vector<pair<int, int>> dp;\n    \n    for (int cell : charPos[superstring[0] - 'A']) {\n        auto [ci, cj] = getCoord(cell);\n        dp.emplace_back(cell, abs(ci - si) + abs(cj - sj) + 1);\n    }\n    \n    vector<unordered_map<int, int>> parent(L);\n    \n    for (int idx = 1; idx < L; idx++) {\n        vector<pair<int, int>> newDp;\n        for (int cell : charPos[superstring[idx] - 'A']) {\n            auto [ci, cj] = getCoord(cell);\n            int minCost = INT_MAX, bestPrev = -1;\n            for (auto& [prevCell, cost] : dp) {\n                auto [pi, pj] = getCoord(prevCell);\n                int newCost = cost + abs(ci - pi) + abs(cj - pj) + 1;\n                if (newCost < minCost) { minCost = newCost; bestPrev = prevCell; }\n            }\n            if (bestPrev != -1) {\n                newDp.emplace_back(cell, minCost);\n                parent[idx][cell] = bestPrev;\n            }\n        }\n        dp = move(newDp);\n    }\n    \n    int endCell = min_element(dp.begin(), dp.end(), [](auto& a, auto& b) { return a.second < b.second; })->first;\n    \n    vector<int> path(L);\n    path[L - 1] = endCell;\n    for (int idx = L - 2; idx >= 0; idx--)\n        path[idx] = parent[idx + 1][path[idx + 1]];\n    \n    for (int cell : path) {\n        auto [i, j] = getCoord(cell);\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<set<pair<int,int>>> shapes;\nvector<vector<int>> obs;\nint Q = 0;\n\npair<int,int> getBB(int k) {\n    int maxI = 0, maxJ = 0;\n    for (auto& p : shapes[k]) {\n        maxI = max(maxI, p.first);\n        maxJ = max(maxJ, p.second);\n    }\n    return {maxI, maxJ};\n}\n\nvector<pair<int,int>> getValidPlacements(int k) {\n    auto [maxI, maxJ] = getBB(k);\n    vector<pair<int,int>> valid;\n    for (int di = 0; di <= N-1-maxI; di++) {\n        for (int dj = 0; dj <= N-1-maxJ; dj++) {\n            bool ok = true;\n            for (auto& p : shapes[k]) {\n                if (obs[p.first + di][p.second + dj] == 0) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) valid.push_back({di, dj});\n        }\n    }\n    return valid;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> eps;\n    shapes.resize(M);\n    obs.assign(N, vector<int>(N, -1));\n    \n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        for (int i = 0; i < d; i++) {\n            int r, c; cin >> r >> c;\n            shapes[k].insert({r, c});\n        }\n    }\n    \n    auto drill = [&](int i, int j) -> int {\n        if (obs[i][j] != -1) return obs[i][j];\n        if (Q >= 2*N*N - 1) return -1;\n        cout << \"q 1 \" << i << \" \" << j << endl;\n        int r; cin >> r;\n        obs[i][j] = r;\n        Q++;\n        return r;\n    };\n    \n    // Main drilling loop\n    while (Q < N * N) {\n        vector<vector<pair<int,int>>> valid(M);\n        for (int k = 0; k < M; k++) valid[k] = getValidPlacements(k);\n        \n        // Classify squares: find those that need drilling\n        vector<int> needDrill;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (obs[i][j] != -1) continue;\n                \n                bool guaranteedOil = false;\n                bool guaranteedEmpty = true;\n                for (int k = 0; k < M; k++) {\n                    if (valid[k].empty()) continue;\n                    bool allCover = true;\n                    bool anyCover = false;\n                    for (auto& [di, dj] : valid[k]) {\n                        if (shapes[k].count({i-di, j-dj})) anyCover = true;\n                        else allCover = false;\n                    }\n                    if (allCover) guaranteedOil = true;\n                    if (anyCover) guaranteedEmpty = false;\n                }\n                \n                if (!guaranteedOil && !guaranteedEmpty) {\n                    needDrill.push_back(i * N + j);\n                }\n            }\n        }\n        \n        if (needDrill.empty()) break;\n        \n        // Drill square with highest coverage (eliminates most placements)\n        int bestIdx = -1, bestCover = -1;\n        for (int idx : needDrill) {\n            int i = idx / N, j = idx % N;\n            int cover = 0;\n            for (int k = 0; k < M; k++) {\n                for (auto& [di, dj] : valid[k]) {\n                    if (shapes[k].count({i-di, j-dj})) cover++;\n                }\n            }\n            if (cover > bestCover) {\n                bestCover = cover;\n                bestIdx = idx;\n            }\n        }\n        \n        if (bestIdx < 0 || drill(bestIdx / N, bestIdx % N) == -1) break;\n    }\n    \n    // Final deduction and answer\n    vector<vector<pair<int,int>>> valid(M);\n    for (int k = 0; k < M; k++) valid[k] = getValidPlacements(k);\n    \n    set<pair<int,int>> oil;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (obs[i][j] > 0) {\n                oil.insert({i, j});\n            } else if (obs[i][j] == -1) {\n                for (int k = 0; k < M; k++) {\n                    if (valid[k].empty()) continue;\n                    bool allCover = true;\n                    for (auto& [di, dj] : valid[k]) {\n                        if (shapes[k].count({i-di, j-dj}) == 0) {\n                            allCover = false;\n                            break;\n                        }\n                    }\n                    if (allCover) {\n                        oil.insert({i, j});\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    \n    cout << \"a \" << oil.size();\n    for (auto& p : oil) cout << \" \" << p.first << \" \" << p.second;\n    cout << endl;\n    int r; cin >> r;\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    vector<vector<array<int, 4>>> rect(D, vector<array<int, 4>>(N));\n    vector<int> prevCum(N + 1);\n    prevCum[0] = 0;\n    \n    for (int d = 0; d < D; d++) {\n        vector<int> h(N, 1);\n        bool reused = false;\n        \n        // Try to reuse previous heights if they satisfy current requirements\n        if (d > 0) {\n            bool ok = true;\n            for (int k = 0; k < N; k++) {\n                int hk = prevCum[k + 1] - prevCum[k];\n                if ((long long)hk * W < a[d][k]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) {\n                for (int k = 0; k < N; k++) {\n                    h[k] = prevCum[k + 1] - prevCum[k];\n                }\n                reused = true;\n            }\n        }\n        \n        if (!reused) {\n            // Compute minimum heights to satisfy requirements\n            for (int k = 0; k < N; k++) {\n                h[k] = max(1, (a[d][k] + W - 1) / W);\n            }\n            \n            int totalH = accumulate(h.begin(), h.end(), 0);\n            \n            if (totalH > W) {\n                // Reduce heights - choose reductions that minimize total deficit\n                int reduce = totalH - W;\n                while (reduce > 0) {\n                    int bestK = -1;\n                    long long minDeficitInc = LLONG_MAX;\n                    for (int k = 0; k < N; k++) {\n                        if (h[k] > 1) {\n                            long long newArea = (long long)(h[k] - 1) * W;\n                            long long deficitInc = max(0LL, (long long)a[d][k] - newArea);\n                            if (deficitInc < minDeficitInc) {\n                                minDeficitInc = deficitInc;\n                                bestK = k;\n                            }\n                        }\n                    }\n                    if (bestK >= 0) {\n                        h[bestK]--;\n                        reduce--;\n                    } else {\n                        break;\n                    }\n                }\n            } else if (totalH < W) {\n                int extra = W - totalH;\n                \n                if (d > 0) {\n                    // Compute current cumulative positions\n                    vector<int> cum(N);\n                    cum[0] = h[0];\n                    for (int k = 1; k < N; k++) cum[k] = cum[k - 1] + h[k];\n                    \n                    // Distribute extra to match previous partition positions\n                    for (int i = 0; i < extra; i++) {\n                        int bestK = N - 1;\n                        int bestImp = 0;\n                        \n                        for (int k = 0; k < N - 1; k++) {\n                            int imp = 0;\n                            for (int j = k; j < N - 1; j++) {\n                                imp += abs(cum[j] - prevCum[j + 1]) - abs(cum[j] + 1 - prevCum[j + 1]);\n                            }\n                            if (imp > bestImp) {\n                                bestImp = imp;\n                                bestK = k;\n                            }\n                        }\n                        \n                        h[bestK]++;\n                        for (int j = bestK; j < N - 1; j++) cum[j]++;\n                    }\n                } else {\n                    h[N - 1] += extra;\n                }\n            }\n        }\n        \n        // Ensure total height equals W\n        int finalH = accumulate(h.begin(), h.end(), 0);\n        if (finalH < W) h[N - 1] += W - finalH;\n        else if (finalH > W) {\n            for (int k = N - 1; k >= 0 && finalH > W; k--) {\n                int decr = min(h[k] - 1, finalH - W);\n                h[k] -= decr;\n                finalH -= decr;\n            }\n        }\n        \n        // Assign rectangles\n        int y = 0;\n        for (int k = 0; k < N; k++) {\n            rect[d][k] = {y, 0, y + h[k], W};\n            y += h[k];\n        }\n        \n        // Update cumulative positions\n        prevCum[0] = 0;\n        for (int k = 0; k < N; k++) {\n            prevCum[k + 1] = prevCum[k] + h[k];\n        }\n    }\n    \n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << rect[d][k][0] << \" \" << rect[d][k][1] << \" \"\n                 << rect[d][k][2] << \" \" << rect[d][k][3] << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <random>\n#include <algorithm>\n#include <chrono>\n#include <climits>\n\nusing namespace std;\n\nconst long long MOD = 998244353;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nlong long board[N][N];\nlong long stamps[M][3][3];\nlong long current[N][N];\nlong long bestScore = 0;\nvector<tuple<int, int, int>> bestOps;\ndouble cellWeight[N][N];\n\nvoid initWeights() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int count = 0;\n            for (int p = max(0, i - 2); p <= min(N - 3, i); p++)\n                for (int q = max(0, j - 2); q <= min(N - 3, j); q++)\n                    count++;\n            cellWeight[i][j] = 9.0 / count;\n        }\n    }\n}\n\nvoid resetBoard() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            current[i][j] = board[i][j];\n}\n\nlong long computeScore() {\n    long long s = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            s += current[i][j] % MOD;\n    return s;\n}\n\nlong long computeGain(int s, int p, int q) {\n    long long gain = 0;\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 3; j++) {\n            long long oldRem = current[p + i][q + j] % MOD;\n            long long newRem = (current[p + i][q + j] + stamps[s][i][j]) % MOD;\n            gain += newRem - oldRem;\n        }\n    return gain;\n}\n\ndouble computeWeightedGain(int s, int p, int q) {\n    double gain = 0;\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 3; j++) {\n            long long oldRem = current[p + i][q + j] % MOD;\n            long long newRem = (current[p + i][q + j] + stamps[s][i][j]) % MOD;\n            gain += (newRem - oldRem) * cellWeight[p + i][q + j];\n        }\n    return gain;\n}\n\nvoid applyStamp(int s, int p, int q, int sign = 1) {\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 3; j++)\n            current[p + i][q + j] += sign * stamps[s][i][j];\n}\n\nvoid greedyRun(mt19937& rng, int topK, bool useWeights) {\n    resetBoard();\n    vector<tuple<int, int, int>> ops;\n    \n    while ((int)ops.size() < K) {\n        vector<tuple<double, long long, int, int, int>> candidates;\n        \n        for (int s = 0; s < M; s++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    long long rawGain = computeGain(s, p, q);\n                    double weightGain = useWeights ? computeWeightedGain(s, p, q) : rawGain;\n                    candidates.emplace_back(weightGain, rawGain, s, p, q);\n                }\n            }\n        }\n        \n        sort(candidates.begin(), candidates.end(), greater<>());\n        \n        int validCount = 0;\n        for (auto& [wg, rg, s, p, q] : candidates) {\n            if (rg <= 0) break;\n            validCount++;\n        }\n        \n        if (validCount == 0) break;\n        \n        int idx = uniform_int_distribution<int>(0, min(topK, validCount) - 1)(rng);\n        auto [wg, rg, s, p, q] = candidates[idx];\n        ops.emplace_back(s, p, q);\n        applyStamp(s, p, q);\n    }\n    \n    long long score = computeScore();\n    if (score > bestScore) {\n        bestScore = score;\n        bestOps = ops;\n    }\n}\n\nvoid improveSolution() {\n    resetBoard();\n    for (auto [s, p, q] : bestOps)\n        applyStamp(s, p, q);\n    \n    // Try to add more operations\n    while ((int)bestOps.size() < K) {\n        long long bestGain = 0;\n        int bestS = -1, bestP = -1, bestQ = -1;\n        \n        for (int s = 0; s < M; s++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    long long gain = computeGain(s, p, q);\n                    if (gain > bestGain) {\n                        bestGain = gain;\n                        bestS = s; bestP = p; bestQ = q;\n                    }\n                }\n            }\n        }\n        \n        if (bestGain <= 0) break;\n        bestOps.emplace_back(bestS, bestP, bestQ);\n        applyStamp(bestS, bestP, bestQ);\n    }\n    \n    bestScore = computeScore();\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m, k;\n    cin >> n >> m >> k;\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cin >> board[i][j];\n    \n    for (int s = 0; s < M; s++)\n        for (int i = 0; i < 3; i++)\n            for (int j = 0; j < 3; j++)\n                cin >> stamps[s][i][j];\n    \n    initWeights();\n    resetBoard();\n    bestScore = computeScore();\n    \n    mt19937 rng(42);\n    \n    auto startTime = chrono::steady_clock::now();\n    int iter = 0;\n    \n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - startTime).count() < 1850) {\n        int mode = iter % 4;\n        int topK = (mode == 0) ? 1 : (mode == 1) ? 3 : (mode == 2) ? 5 : 10;\n        bool useWeights = (iter % 3 == 0);\n        greedyRun(rng, topK, useWeights);\n        iter++;\n    }\n    \n    improveSolution();\n    \n    cout << bestOps.size() << \"\\n\";\n    for (const auto& [stamp, p, q] : bestOps) {\n        cout << stamp << \" \" << p << \" \" << q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N], G[N][N], CR[N], CC[N], CH[N], RI[N], DN[N];\n\nbool hasCrane(int r, int c, int ex = -1) {\n    for (int i = 0; i < N; i++) if (i != ex && CR[i] == r && CC[i] == c) return true;\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> A[i][j];\n    memset(G, -1, sizeof(G));\n    for (int i = 0; i < N; i++) { CR[i] = i; CC[i] = 0; CH[i] = -1; RI[i] = 0; DN[i] = i * N; }\n    vector<string> O(N, \"\");\n    \n    for (int T = 0; T < 10000; T++) {\n        string act(N, '.');\n        \n        // Step 1: Receive containers at column 0\n        for (int i = 0; i < N; i++) {\n            if (RI[i] < N && G[i][0] < 0) {\n                bool blocked = false;\n                for (int j = 0; j < N; j++) \n                    if (CR[j] == i && CC[j] == 0 && CH[j] >= 0) blocked = true;\n                if (!blocked) G[i][0] = A[i][RI[i]++];\n            }\n        }\n        \n        // Step 2: Decide actions\n        int NR[N], NC[N];\n        for (int i = 0; i < N; i++) { NR[i] = CR[i]; NC[i] = CC[i]; }\n        \n        for (int i = 0; i < N; i++) {\n            if (CH[i] >= 0) {\n                int tr = CH[i] / N; // Target row\n                bool next = (CH[i] == DN[tr]);\n                // Move toward dispatch or storage\n                if (CR[i] != tr) {\n                    int dr = (CR[i] < tr) ? 1 : -1;\n                    int nr = CR[i] + dr;\n                    if (!hasCrane(nr, CC[i], i) && (i == 0 || G[nr][CC[i]] < 0)) {\n                        act[i] = (dr > 0) ? 'D' : 'U'; NR[i] = nr;\n                    }\n                } else if (CC[i] < N-1) {\n                    int nc = CC[i] + 1;\n                    bool cango = !hasCrane(CR[i], nc, i) && (i == 0 || G[CR[i]][nc] < 0);\n                    // Can always reach dispatch gate if target is next\n                    if (cango || (next && nc == N-1 && !hasCrane(CR[i], nc, i))) {\n                        act[i] = 'R'; NC[i] = nc;\n                    }\n                } else if (CC[i] == N-1 && G[CR[i]][CC[i]] < 0) {\n                    act[i] = 'Q';\n                }\n            } else if (G[CR[i]][CC[i]] >= 0) {\n                act[i] = 'P';\n            } else if (CC[i] > 0) {\n                int nc = CC[i] - 1;\n                if (!hasCrane(CR[i], nc, i)) { act[i] = 'L'; NC[i] = nc; }\n            }\n        }\n        \n        // Collision resolution\n        for (int it = 0; it < 3; it++)\n            for (int i = 0; i < N; i++) for (int j = i+1; j < N; j++) {\n                if (NR[i] == NR[j] && NC[i] == NC[j]) { act[j] = '.'; NR[j] = CR[j]; NC[j] = CC[j]; }\n                if (CR[i] == NR[j] && CC[i] == NC[j] && CR[j] == NR[i] && CC[j] == NC[i]) \n                    { act[j] = '.'; NR[j] = CR[j]; NC[j] = CC[j]; }\n            }\n        \n        // Apply actions\n        for (int i = 0; i < N; i++) {\n            if (act[i] == 'P' && CH[i] < 0 && G[CR[i]][CC[i]] >= 0) { CH[i] = G[CR[i]][CC[i]]; G[CR[i]][CC[i]] = -1; }\n            else if (act[i] == 'Q' && CH[i] >= 0 && G[CR[i]][CC[i]] < 0) { G[CR[i]][CC[i]] = CH[i]; CH[i] = -1; }\n            else if (act[i] == 'R') CC[i]++;\n            else if (act[i] == 'L') CC[i]--;\n            else if (act[i] == 'U') CR[i]--;\n            else if (act[i] == 'D') CR[i]++;\n        }\n        \n        // Step 3: Dispatch\n        for (int i = 0; i < N; i++) if (G[i][N-1] >= 0) {\n            int c = G[i][N-1];\n            if (c >= i*N && c < (i+1)*N && c == DN[i]) DN[i]++;\n            G[i][N-1] = -1;\n        }\n        \n        for (int i = 0; i < N; i++) O[i] += act[i];\n        \n        bool done = true;\n        for (int i = 0; i < N; i++) if (RI[i] < N) done = false;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (G[i][j] >= 0) done = false;\n        for (int i = 0; i < N; i++) if (CH[i] >= 0) done = false;\n        if (done) break;\n    }\n    \n    for (int i = 0; i < N; i++) cout << O[i] << \"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\n\nint dist(int i1, int j1, int i2, int j2) {\n    return abs(i1 - i2) + abs(j1 - j2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cin >> h[i][j];\n    \n    vector<string> ops;\n    long long truck_load = 0;\n    int cur_i = 0, cur_j = 0;\n    \n    auto move_to = [&](int ni, int nj) {\n        while (cur_i < ni) { ops.push_back(\"D\"); cur_i++; }\n        while (cur_i > ni) { ops.push_back(\"U\"); cur_i--; }\n        while (cur_j < nj) { ops.push_back(\"R\"); cur_j++; }\n        while (cur_j > nj) { ops.push_back(\"L\"); cur_j--; }\n    };\n    \n    while (true) {\n        vector<pair<int, int>> sources, sinks;\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) {\n                if (h[i][j] > 0) sources.push_back({i, j});\n                if (h[i][j] < 0) sinks.push_back({i, j});\n            }\n        \n        if (sources.empty() && sinks.empty()) break;\n        \n        if (truck_load == 0 && !sources.empty()) {\n            long long best_cost = LLONG_MAX;\n            int best_i = -1, best_j = -1;\n            \n            for (auto& [si, sj] : sources) {\n                int amt = h[si][sj];\n                int d_empty = dist(cur_i, cur_j, si, sj);\n                \n                int d_loaded = INT_MAX;\n                for (auto& [ti, tj] : sinks) {\n                    d_loaded = min(d_loaded, dist(si, sj, ti, tj));\n                }\n                if (d_loaded == INT_MAX) d_loaded = 0;\n                \n                long long cost = 100LL * d_empty + (100LL + amt) * d_loaded;\n                \n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_i = si; best_j = sj;\n                }\n            }\n            \n            if (best_i == -1) break;\n            move_to(best_i, best_j);\n            int amt = h[best_i][best_j];\n            ops.push_back(\"+\" + to_string(amt));\n            h[best_i][best_j] = 0;\n            truck_load += amt;\n            \n            // Chain nearby sources if beneficial\n            while (truck_load > 0) {\n                int best_d = INT_MAX, ni = -1, nj = -1;\n                for (int i = 0; i < N; i++)\n                    for (int j = 0; j < N; j++)\n                        if (h[i][j] > 0) {\n                            int d = dist(cur_i, cur_j, i, j);\n                            if (d < best_d) { best_d = d; ni = i; nj = j; }\n                        }\n                int sink_d = INT_MAX;\n                for (int i = 0; i < N; i++)\n                    for (int j = 0; j < N; j++)\n                        if (h[i][j] < 0) sink_d = min(sink_d, dist(cur_i, cur_j, i, j));\n                \n                if (ni >= 0 && best_d <= 2 && best_d < sink_d) {\n                    move_to(ni, nj);\n                    int amt2 = h[ni][nj];\n                    ops.push_back(\"+\" + to_string(amt2));\n                    h[ni][nj] = 0;\n                    truck_load += amt2;\n                } else break;\n            }\n        } else if (truck_load > 0 && !sinks.empty()) {\n            int best_d = INT_MAX, best_i = -1, best_j = -1;\n            \n            for (auto& [ti, tj] : sinks) {\n                int d = dist(cur_i, cur_j, ti, tj);\n                if (d < best_d) { best_d = d; best_i = ti; best_j = tj; }\n            }\n            \n            if (best_i == -1) break;\n            move_to(best_i, best_j);\n            int amt = min(truck_load, (long long)-h[best_i][best_j]);\n            ops.push_back(\"-\" + to_string(amt));\n            h[best_i][best_j] += amt;\n            truck_load -= amt;\n            \n            // Chain nearby sinks\n            while (truck_load > 0) {\n                int best_d2 = INT_MAX, ni = -1, nj = -1;\n                for (int i = 0; i < N; i++)\n                    for (int j = 0; j < N; j++)\n                        if (h[i][j] < 0) {\n                            int d = dist(cur_i, cur_j, i, j);\n                            if (d < best_d2) { best_d2 = d; ni = i; nj = j; }\n                        }\n                if (ni >= 0 && best_d2 <= 2) {\n                    move_to(ni, nj);\n                    int amt2 = min(truck_load, (long long)-h[ni][nj]);\n                    ops.push_back(\"-\" + to_string(amt2));\n                    h[ni][nj] += amt2;\n                    truck_load -= amt2;\n                } else break;\n            }\n        } else break;\n    }\n    \n    for (auto& s : ops) cout << s << \"\\n\";\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n    const int seed_count = 2 * N * (N - 1);\n    const int grid_size = N * N;\n    vector<vector<int>> X(seed_count, vector<int>(M));\n    \n    for (int i = 0; i < seed_count; i++)\n        for (int j = 0; j < M; j++)\n            cin >> X[i][j];\n    \n    mt19937 rng(42);\n    uniform_int_distribution<int> distPos(0, grid_size - 1);\n    uniform_real_distribution<double> uni(0, 1);\n    \n    for (int t = 0; t < T; t++) {\n        // Select top seeds by total value\n        vector<int> order(seed_count);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            int sa = 0, sb = 0;\n            for (int l = 0; l < M; l++) { sa += X[a][l]; sb += X[b][l]; }\n            return sa > sb;\n        });\n        \n        vector<int> flat(order.begin(), order.begin() + grid_size);\n        \n        auto pot = [&](int a, int b) -> int {\n            int p = 0;\n            for (int l = 0; l < M; l++) p += max(X[a][l], X[b][l]);\n            return p;\n        };\n        \n        auto contrib = [&](int idx) -> int {\n            int i = idx / N, j = idx % N, c = 0;\n            int seed = flat[idx];\n            if (j > 0) c += pot(seed, flat[idx - 1]);\n            if (j < N - 1) c += pot(seed, flat[idx + 1]);\n            if (i > 0) c += pot(seed, flat[idx - N]);\n            if (i < N - 1) c += pot(seed, flat[idx + N]);\n            return c;\n        };\n        \n        int currentScore = 0;\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N - 1; j++) currentScore += pot(flat[i*N+j], flat[i*N+j+1]);\n        for (int i = 0; i < N - 1; i++)\n            for (int j = 0; j < N; j++) currentScore += pot(flat[i*N+j], flat[(i+1)*N+j]);\n        \n        int bestScore = currentScore;\n        vector<int> bestFlat = flat;\n        \n        // Simulated annealing with multiple phases\n        for (int phase = 0; phase < 4; phase++) {\n            double temp = 80.0 / (phase + 1);\n            for (int iter = 0; iter < 150000; iter++) {\n                int p1 = distPos(rng), p2 = distPos(rng);\n                if (p1 == p2) continue;\n                \n                int r1 = p1/N, c1 = p1%N, r2 = p2/N, c2 = p2%N;\n                bool adj = (abs(r1-r2)==1 && c1==c2) || (abs(c1-c2)==1 && r1==r2);\n                \n                int old = contrib(p1) + contrib(p2);\n                if (adj) old -= pot(flat[p1], flat[p2]);\n                \n                swap(flat[p1], flat[p2]);\n                \n                int nw = contrib(p1) + contrib(p2);\n                if (adj) nw -= pot(flat[p1], flat[p2]);\n                \n                int delta = nw - old;\n                \n                if (delta > 0 || uni(rng) < exp(delta / temp)) {\n                    currentScore += delta;\n                    if (currentScore > bestScore) {\n                        bestScore = currentScore;\n                        bestFlat = flat;\n                    }\n                } else {\n                    swap(flat[p1], flat[p2]);\n                }\n                temp *= 0.99995;\n            }\n            // Restart from best for next phase\n            flat = bestFlat;\n            currentScore = bestScore;\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << bestFlat[i * N + j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n        \n        for (int i = 0; i < seed_count; i++)\n            for (int j = 0; j < M; j++)\n                cin >> X[i][j];\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<string> S, T;\n\nconst int DX[] = {1, 0, -1, 0};\nconst int DY[] = {0, 1, 0, -1};\nconst char DIR_C[] = \"RDLU\";\n\nstruct Robot {\n    int V;\n    vector<int> par, len;\n    vector<vector<int>> child;\n    vector<int> leaves;\n    int rx, ry;\n    vector<int> edir;\n    \n    void init(int v) {\n        V = v;\n        par.resize(V, -1); len.resize(V); child.resize(V); edir.resize(V, 0);\n    }\n    \n    void build() {\n        int nb = min(V - 1, 4);\n        int blen = max(2, N / 4);\n        for (int i = 1; i <= nb && i < V; i++) {\n            par[i] = 0; len[i] = blen; child[0].push_back(i);\n        }\n        for (int i = nb + 1; i < V; i++) {\n            par[i] = (i - 2) % nb + 1; len[i] = 2;\n            child[par[i]].push_back(i);\n        }\n        for (int i = 0; i < V; i++) if (child[i].empty()) leaves.push_back(i);\n    }\n    \n    pair<int,int> pos(int v) const {\n        if (par[v] < 0) return {rx, ry};\n        auto [px, py] = pos(par[v]);\n        return {px + DX[edir[v]] * len[v], py + DY[edir[v]] * len[v]};\n    }\n    \n    void rot_subtree(int u, int d) {\n        queue<int> q; q.push(u);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (par[v] >= 0) edir[v] = (edir[v] + d + 4) % 4;\n            for (int c : child[v]) q.push(c);\n        }\n    }\n    void move(int d) { rx += DX[d]; ry += DY[d]; }\n};\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> V;\n    S.resize(N); T.resize(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    Robot rob; rob.init(V); rob.build();\n    \n    long long sx = 0, sy = 0, cnt = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (S[i][j] == '1') { sx += i; sy += j; cnt++; }\n    rob.rx = (cnt > 0) ? sx / cnt : N / 2;\n    rob.ry = (cnt > 0) ? sy / cnt : N / 2;\n    rob.rx = max(0, min(N - 1, rob.rx)); rob.ry = max(0, min(N - 1, rob.ry));\n    \n    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) cout << rob.par[i] << \" \" << rob.len[i] << \"\\n\";\n    cout << rob.rx << \" \" << rob.ry << \"\\n\";\n    \n    vector<vector<int>> grid(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) grid[i][j] = (S[i][j] == '1');\n    \n    set<pair<int,int>> usrc, utgt;\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') usrc.insert({i, j});\n        if (T[i][j] == '1' && S[i][j] == '0') utgt.insert({i, j});\n    }\n    \n    map<int, bool> hold;\n    for (int l : rob.leaves) hold[l] = false;\n    \n    auto find_nearest = [&](int x, int y, bool need_src) -> int {\n        int mn = INT_MAX;\n        if (need_src) for (auto [r, c] : usrc) if (grid[r][c] == 1) mn = min(mn, abs(x-r) + abs(y-c));\n        else for (auto [r, c] : utgt) if (grid[r][c] == 0) mn = min(mn, abs(x-r) + abs(y-c));\n        return mn;\n    };\n    \n    auto score = [&]() -> long long {\n        long long s = 0;\n        for (int l : rob.leaves) { auto [x, y] = rob.pos(l); int d = find_nearest(x, y, !hold[l]); if (d < INT_MAX) s += d; }\n        return s;\n    };\n    \n    for (int t = 0; t < 100000; t++) {\n        bool done = true;\n        for (auto [r, c] : utgt) if (grid[r][c] == 0) { done = false; break; }\n        if (done) break;\n        \n        string cmd(2 * V, '.');\n        \n        for (int l : rob.leaves) {\n            auto [x, y] = rob.pos(l);\n            if (x < 0 || x >= N || y < 0 || y >= N) continue;\n            if (!hold[l] && grid[x][y] == 1 && T[x][y] == '0') { cmd[V + l] = 'P'; hold[l] = true; grid[x][y] = 0; usrc.erase({x, y}); }\n            else if (hold[l] && grid[x][y] == 0 && T[x][y] == '1') { cmd[V + l] = 'P'; hold[l] = false; grid[x][y] = 1; utgt.erase({x, y}); }\n        }\n        \n        int bd = -1; long long bs = LLONG_MAX;\n        for (int d = 0; d < 4; d++) {\n            int nx = rob.rx + DX[d], ny = rob.ry + DY[d];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            rob.move(d); long long s = score(); rob.move((d + 2) % 4);\n            if (s < bs) { bs = s; bd = d; }\n        }\n        if (bd >= 0) { cmd[0] = DIR_C[bd]; rob.move(bd); }\n        \n        for (int u = 1; u < V; u++) {\n            auto orig = rob.edir; long long so = score();\n            rob.rot_subtree(u, 3); long long sl = score();\n            rob.edir = orig; rob.rot_subtree(u, 1); long long sr = score();\n            if (sl < so && sl <= sr) { rob.edir = orig; rob.rot_subtree(u, 3); cmd[u] = 'L'; }\n            else if (sr < so) cmd[u] = 'R';\n            else rob.edir = orig;\n        }\n        cout << cmd << \"\\n\";\n    }\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    int N; cin >> N;\n    vector<int> mx(N), my(N), sx(N), sy(N);\n    for (int i = 0; i < N; i++) cin >> mx[i] >> my[i];\n    for (int i = 0; i < N; i++) cin >> sx[i] >> sy[i];\n    \n    const int MAXC = 100000;\n    \n    auto cnt = [&](int x1, int y1, int x2, int y2) {\n        int c = 0;\n        for (int i = 0; i < N; i++) {\n            if (mx[i] >= x1 && mx[i] <= x2 && my[i] >= y1 && my[i] <= y2) c++;\n            if (sx[i] >= x1 && sx[i] <= x2 && sy[i] >= y1 && sy[i] <= y2) c--;\n        }\n        return c;\n    };\n    \n    int best = 0, bx1 = 0, by1 = 0, bx2 = MAXC, by2 = MAXC;\n    int bestCS = MAXC;\n    \n    // Grid search with high resolution\n    for (int GS : {200, 150}) {\n        int CS = (MAXC + GS - 1) / GS;\n        vector<vector<int>> diff(GS, vector<int>(GS, 0));\n        \n        for (int i = 0; i < N; i++) diff[min(mx[i]/CS, GS-1)][min(my[i]/CS, GS-1)]++;\n        for (int i = 0; i < N; i++) diff[min(sx[i]/CS, GS-1)][min(sy[i]/CS, GS-1)]--;\n        \n        vector<vector<int>> pref(GS+1, vector<int>(GS+1, 0));\n        for (int i = 0; i < GS; i++)\n            for (int j = 0; j < GS; j++)\n                pref[i+1][j+1] = diff[i][j] + pref[i][j+1] + pref[i+1][j] - pref[i][j];\n        \n        for (int x1 = 0; x1 < GS; x1++) {\n            for (int x2 = x1; x2 < GS; x2++) {\n                int minPref = 0, minIdx = -1, cs = 0;\n                for (int y2 = 0; y2 < GS; y2++) {\n                    cs += pref[x2+1][y2+1] - pref[x1][y2+1] - pref[x2+1][y2] + pref[x1][y2];\n                    int cur = cs - minPref;\n                    if (cur > best) {\n                        best = cur;\n                        bx1 = x1 * CS; by1 = (minIdx + 1) * CS;\n                        bx2 = min((x2 + 1) * CS - 1, MAXC);\n                        by2 = min((y2 + 1) * CS - 1, MAXC);\n                        bestCS = CS;\n                    }\n                    if (cs < minPref) { minPref = cs; minIdx = y2; }\n                }\n            }\n        }\n    }\n    \n    // Collect fish coordinates near boundaries\n    set<int> xcs = {bx1, bx2, 0, MAXC}, ycs = {by1, by2, 0, MAXC};\n    for (int i = 0; i < N; i++) {\n        if (abs(mx[i] - bx1) <= bestCS || abs(mx[i] - bx2) <= bestCS) xcs.insert(mx[i]);\n        if (abs(my[i] - by1) <= bestCS || abs(my[i] - by2) <= bestCS) ycs.insert(my[i]);\n        if (abs(sx[i] - bx1) <= bestCS || abs(sx[i] - bx2) <= bestCS) xcs.insert(sx[i]);\n        if (abs(sy[i] - by1) <= bestCS || abs(sy[i] - by2) <= bestCS) ycs.insert(sy[i]);\n    }\n    \n    // Multi-pass refinement\n    for (int it = 0; it < 3; it++) {\n        for (int x : xcs) {\n            if (x >= 0 && x <= bx2) { int v = cnt(x, by1, bx2, by2); if (v > best) { best = v; bx1 = x; } }\n            if (x >= bx1 && x <= MAXC) { int v = cnt(bx1, by1, x, by2); if (v > best) { best = v; bx2 = x; } }\n        }\n        for (int y : ycs) {\n            if (y >= 0 && y <= by2) { int v = cnt(bx1, y, bx2, by2); if (v > best) { best = v; by1 = y; } }\n            if (y >= by1 && y <= MAXC) { int v = cnt(bx1, by1, bx2, y); if (v > best) { best = v; by2 = y; } }\n        }\n    }\n    \n    if (best <= 0) {\n        cout << 4 << \"\\n0 0\\n0 1\\n1 1\\n1 0\\n\";\n    } else {\n        cout << 4 << \"\\n\" << bx1 << \" \" << by1 << \"\\n\" << bx2 << \" \" << by1 << \"\\n\"\n             << bx2 << \" \" << by2 << \"\\n\" << bx1 << \" \" << by2 << \"\\n\";\n    }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, sigma;\nvector<long long> w, h;\nmt19937_64 rng(42);\n\nstruct State {\n    vector<long long> x1, y1, x2, y2;\n    long long W = 0, H = 0;\n    \n    State() { x1.resize(100); y1.resize(100); x2.resize(100); y2.resize(100); }\n    \n    void place(int i, int rot, int dir, int ref) {\n        long long width = rot ? h[i] : w[i];\n        long long height = rot ? w[i] : h[i];\n        long long x0, y0;\n        \n        if (dir == 0) { // U\n            x0 = (ref < 0) ? 0 : x2[ref];\n            y0 = 0;\n            for (int j = 0; j < i; j++)\n                if (x0 < x2[j] && x0 + width > x1[j]) y0 = max(y0, y2[j]);\n        } else { // L\n            y0 = (ref < 0) ? 0 : y2[ref];\n            x0 = 0;\n            for (int j = 0; j < i; j++)\n                if (y0 < y2[j] && y0 + height > y1[j]) x0 = max(x0, x2[j]);\n        }\n        \n        x1[i] = x0; y1[i] = y0;\n        x2[i] = x0 + width; y2[i] = y0 + height;\n        W = max(W, x2[i]); H = max(H, y2[i]);\n    }\n    \n    long long score() const { return W + H; }\n};\n\nlong long simulate(const vector<int>& rot, const vector<int>& dir, const vector<int>& ref) {\n    State s;\n    for (int i = 0; i < N; i++) s.place(i, rot[i], dir[i], ref[i]);\n    return s.score();\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T >> sigma;\n    w.resize(N); h.resize(N);\n    for (int i = 0; i < N; i++) cin >> w[i] >> h[i];\n    \n    vector<int> rot(N, 0), dir(N, 0), ref(N, -1);\n    \n    // Greedy init - for each position, try all options and pick best\n    for (int i = 1; i < N; i++) {\n        long long best = LLONG_MAX;\n        int br = 0, bd = 0, bf = -1;\n        for (int r = 0; r < 2; r++)\n            for (int d = 0; d < 2; d++)\n                for (int f = -1; f < i; f++) {\n                    rot[i] = r; dir[i] = d; ref[i] = f;\n                    long long s = simulate(rot, dir, ref);\n                    if (s < best) { best = s; br = r; bd = d; bf = f; }\n                }\n        rot[i] = br; dir[i] = bd; ref[i] = bf;\n    }\n    \n    long long curr = simulate(rot, dir, ref);\n    long long best = curr;\n    auto best_rot = rot, best_dir = dir, best_ref = ref;\n    \n    uniform_real_distribution<double> uni(0.0, 1.0);\n    \n    // Time management: use ~2.7 seconds total\n    auto start = chrono::steady_clock::now();\n    auto deadline = start + chrono::milliseconds(2700);\n    int total_iter = 0;\n    int turn = 0;\n    \n    while (turn < T) {\n        auto now = chrono::steady_clock::now();\n        auto remaining = deadline - now;\n        auto per_turn = remaining / (T - turn);\n        auto turn_end = now + per_turn;\n        \n        while (chrono::steady_clock::now() < turn_end) {\n            total_iter++;\n            double temp = max(1.0, 5e6 * pow(0.99997, total_iter));\n            \n            int idx = 1 + rng() % (N - 1);\n            int op = rng() % 4;\n            int old_r = rot[idx], old_d = dir[idx], old_f = ref[idx];\n            \n            if (op == 0) rot[idx] ^= 1;\n            else if (op == 1) dir[idx] ^= 1;\n            else if (op == 2) ref[idx] = (uni(rng) < 0.35) ? -1 : (int)(rng() % idx);\n            else { // combined move\n                if (uni(rng) < 0.5) rot[idx] ^= 1;\n                if (uni(rng) < 0.5) dir[idx] ^= 1;\n                ref[idx] = (uni(rng) < 0.35) ? -1 : (int)(rng() % idx);\n            }\n            \n            long long s = simulate(rot, dir, ref);\n            if (s <= curr || uni(rng) < exp(-(s - curr) / temp)) {\n                curr = s;\n                if (s < best) { best = s; best_rot = rot; best_dir = dir; best_ref = ref; }\n            } else {\n                rot[idx] = old_r; dir[idx] = old_d; ref[idx] = old_f;\n            }\n        }\n        \n        cout << N << \"\\n\";\n        for (int i = 0; i < N; i++)\n            cout << i << \" \" << best_rot[i] << \" \" << (best_dir[i] ? 'L' : 'U') << \" \" << best_ref[i] << \"\\n\";\n        cout.flush();\n        \n        long long Wp, Hp; cin >> Wp >> Hp;\n        turn++;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    int N, M, H; cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int& a : A) cin >> a;\n    \n    vector<vector<int>> adj(N);\n    vector<int> x(N), y(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    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    vector<int> sorted_by_beauty(N);\n    iota(sorted_by_beauty.begin(), sorted_by_beauty.end(), 0);\n    sort(sorted_by_beauty.begin(), sorted_by_beauty.end(), [&](int i, int j) { return A[i] < A[j]; });\n    \n    vector<int> best_parent(N, -1);\n    long long best_score = 0;\n    \n    auto start = chrono::steady_clock::now();\n    \n    auto solve = [&](const vector<int>& order, bool use_coords) -> pair<vector<int>, long long> {\n        vector<int> parent(N, -1), height(N, 0);\n        vector<bool> used(N, false);\n        \n        for (int v : order) {\n            int best_p = -1, best_h = 0, best_beauty = INT_MAX;\n            double best_dist = 1e18;\n            \n            for (int u : adj[v]) {\n                if (!used[u] || height[u] + 1 > H) continue;\n                int h = height[u] + 1;\n                int b = A[u];\n                double d = hypot(x[v] - x[u], y[v] - y[u]);\n                \n                if (h > best_h || (h == best_h && (b < best_beauty || (b == best_beauty && d < best_dist)))) {\n                    best_h = h;\n                    best_p = u;\n                    best_beauty = b;\n                    best_dist = d;\n                }\n            }\n            parent[v] = best_p;\n            height[v] = best_h;\n            used[v] = true;\n        }\n        \n        // Build children list\n        vector<vector<int>> children(N);\n        for (int v = 0; v < N; v++)\n            if (parent[v] != -1) children[parent[v]].push_back(v);\n        \n        // Local search - move leaves higher\n        for (int iter = 0; iter < 100; iter++) {\n            bool changed = false;\n            for (int v = 0; v < N; v++) {\n                if (!children[v].empty()) continue;\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    if (height[u] + 1 <= H && height[u] + 1 > height[v]) {\n                        if (parent[v] != -1) {\n                            auto& c = children[parent[v]];\n                            c.erase(remove(c.begin(), c.end(), v), c.end());\n                        }\n                        parent[v] = u;\n                        height[v] = height[u] + 1;\n                        children[u].push_back(v);\n                        changed = true;\n                        break;\n                    }\n                }\n            }\n            if (!changed) break;\n        }\n        \n        long long score = 0;\n        for (int v = 0; v < N; v++) score += (long long)(height[v] + 1) * A[v];\n        return {parent, score};\n    };\n    \n    // Try multiple strategies\n    tie(best_parent, best_score) = solve(sorted_by_beauty, false);\n    \n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < 1.9) {\n        vector<int> order = sorted_by_beauty;\n        \n        // Shuffle within same-beauty groups\n        for (int i = 0, j; i < N; i = j) {\n            j = i + 1;\n            while (j < N && A[order[j]] == A[order[i]]) j++;\n            if (j - i > 1) shuffle(order.begin() + i, order.begin() + j, rng);\n        }\n        \n        bool use_coords = (rng() % 3 == 0);\n        auto [p, s] = solve(order, use_coords);\n        if (s > best_score) { best_score = s; best_parent = p; }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << best_parent[i] << \" \\n\"[i == N-1];\n    }\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <set>\n\nusing namespace std;\n\nvector<pair<char,int>> solve_greedy(int N, const vector<pair<int,int>>& onis,\n                                    const vector<bool>& safe_up, const vector<bool>& safe_down,\n                                    const vector<bool>& safe_left, const vector<bool>& safe_right,\n                                    int variant) {\n    int num_onis = onis.size();\n    set<int> remaining;\n    for (int idx = 0; idx < num_onis; idx++) remaining.insert(idx);\n    \n    vector<pair<char, int>> result;\n    \n    while (!remaining.empty()) {\n        struct Op { double eff; int cost; char dir; int idx; vector<int> batch; };\n        vector<Op> ops;\n        \n        for (int j = 0; j < N; j++) {\n            vector<int> batch; int max_row = -1;\n            for (int idx : remaining)\n                if (onis[idx].second == j && safe_up[idx]) {\n                    batch.push_back(idx); max_row = max(max_row, onis[idx].first);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (max_row + 1);\n                double eff = (variant == 0) ? (double)batch.size() / cost :\n                             (variant == 1) ? (double)batch.size() / (cost * cost) :\n                             (double)batch.size();\n                ops.push_back({eff, cost, 'U', j, batch});\n            }\n        }\n        for (int j = 0; j < N; j++) {\n            vector<int> batch; int min_row = N;\n            for (int idx : remaining)\n                if (onis[idx].second == j && safe_down[idx]) {\n                    batch.push_back(idx); min_row = min(min_row, onis[idx].first);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (N - min_row);\n                double eff = (variant == 0) ? (double)batch.size() / cost :\n                             (variant == 1) ? (double)batch.size() / (cost * cost) :\n                             (double)batch.size();\n                ops.push_back({eff, cost, 'D', j, batch});\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            vector<int> batch; int max_col = -1;\n            for (int idx : remaining)\n                if (onis[idx].first == i && safe_left[idx]) {\n                    batch.push_back(idx); max_col = max(max_col, onis[idx].second);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (max_col + 1);\n                double eff = (variant == 0) ? (double)batch.size() / cost :\n                             (variant == 1) ? (double)batch.size() / (cost * cost) :\n                             (double)batch.size();\n                ops.push_back({eff, cost, 'L', i, batch});\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            vector<int> batch; int min_col = N;\n            for (int idx : remaining)\n                if (onis[idx].first == i && safe_right[idx]) {\n                    batch.push_back(idx); min_col = min(min_col, onis[idx].second);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (N - min_col);\n                double eff = (variant == 0) ? (double)batch.size() / cost :\n                             (variant == 1) ? (double)batch.size() / (cost * cost) :\n                             (double)batch.size();\n                ops.push_back({eff, cost, 'R', i, batch});\n            }\n        }\n        \n        if (ops.empty()) break;\n        \n        int best = 0;\n        for (int i = 1; i < (int)ops.size(); i++)\n            if (ops[i].eff > ops[best].eff)\n                best = i;\n        \n        for (int oni_idx : ops[best].batch) remaining.erase(oni_idx);\n        \n        int shifts = ops[best].cost / 2;\n        char dir = ops[best].dir, rev_dir = (dir == 'U' ? 'D' : dir == 'D' ? 'U' : dir == 'L' ? 'R' : 'L');\n        for (int k = 0; k < shifts; k++) result.emplace_back(dir, ops[best].idx);\n        for (int k = 0; k < shifts; k++) result.emplace_back(rev_dir, ops[best].idx);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \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++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j] == 'x') onis.emplace_back(i, j);\n    \n    int num_onis = onis.size();\n    vector<bool> safe_up(num_onis, true), safe_down(num_onis, true);\n    vector<bool> safe_left(num_onis, true), safe_right(num_onis, true);\n    \n    for (int idx = 0; idx < num_onis; idx++) {\n        auto [i, j] = onis[idx];\n        for (int fi = 0; fi < N; fi++)\n            for (int fj = 0; fj < N; fj++)\n                if (board[fi][fj] == 'o') {\n                    if (fj == j && fi < i) safe_up[idx] = false;\n                    if (fj == j && fi > i) safe_down[idx] = false;\n                    if (fi == i && fj < j) safe_left[idx] = false;\n                    if (fi == i && fj > j) safe_right[idx] = false;\n                }\n    }\n    \n    vector<pair<char,int>> best_result;\n    int best_cost = 1e9;\n    \n    for (int v = 0; v < 3; v++) {\n        auto result = solve_greedy(N, onis, safe_up, safe_down, safe_left, safe_right, v);\n        if ((int)result.size() < best_cost) {\n            best_cost = result.size();\n            best_result = result;\n        }\n    }\n    \n    for (auto& [d, p] : best_result) cout << d << \" \" << p << \"\\n\";\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 100;\nconstexpr int L = 500000;\n\nint T[N], a[N], b[N], v[N], ba[N], bb[N];\n\nstruct RNG {\n    uint64_t s;\n    RNG(uint64_t seed = 88172645463325252ULL) : s(seed) {}\n    uint64_t next() { s ^= s << 7; s ^= s >> 9; return s; }\n    int operator()(int n) { return next() % n; }\n    double dbl() { return (double)next() / UINT64_MAX; }\n} rng;\n\ninline long long simulate() {\n    memset(v, 0, sizeof(v));\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        int t = ++v[cur];\n        cur = (t & 1) ? a[cur] : b[cur];\n    }\n    long long err = 0;\n    for (int i = 0; i < N; i++) err += abs(v[i] - T[i]);\n    return err;\n}\n\nvoid init_cycle() {\n    vector<int> active;\n    for (int i = 0; i < N; i++) if (T[i] > 0) active.push_back(i);\n    if (active.empty()) active.push_back(0);\n    for (int i = 0; i < N; i++) a[i] = b[i] = active[0];\n    for (size_t i = 0; i < active.size(); i++) {\n        a[active[i]] = b[active[i]] = active[(i + 1) % active.size()];\n    }\n}\n\nlong long sa(double duration_ms, uint64_t seed) {\n    rng = RNG(seed);\n    init_cycle();\n    \n    long long cur = simulate(), best = cur;\n    memcpy(ba, a, sizeof(a)); memcpy(bb, b, sizeof(b));\n    \n    double temp = 50000.0;\n    auto dl = chrono::steady_clock::now() + chrono::milliseconds((long long)duration_ms);\n    int stuck = 0;\n    \n    while (chrono::steady_clock::now() < dl) {\n        int i = rng(N), oa = a[i], ob = b[i];\n        int mt = rng(10);\n        if (mt < 4) a[i] = rng(N);\n        else if (mt < 8) b[i] = rng(N);\n        else { a[i] = rng(N); b[i] = rng(N); }\n        \n        long long ne = simulate();\n        if (ne <= cur || exp(-(ne - cur) / temp) > rng.dbl()) {\n            cur = ne; stuck = 0;\n            if (ne < best) { best = ne; memcpy(ba, a, sizeof(a)); memcpy(bb, b, sizeof(b)); }\n        } else { a[i] = oa; b[i] = ob; stuck++; }\n        \n        if (stuck > 1500) {\n            memcpy(a, ba, sizeof(a)); memcpy(b, bb, sizeof(b));\n            cur = best; temp = min(50000.0, temp * 4.0); stuck = 0;\n        }\n        temp = max(0.1, temp * 0.99997);\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n_, L_; cin >> n_ >> L_;\n    for (int i = 0; i < N; i++) cin >> T[i];\n    \n    long long best_err = LLONG_MAX;\n    int best_a[N], best_b[N];\n    \n    // Multiple short runs with different seeds\n    for (int run = 0; run < 5; run++) {\n        long long err = sa(350, 12345 + run * 7919);\n        if (err < best_err) {\n            best_err = err;\n            memcpy(best_a, ba, sizeof(ba));\n            memcpy(best_b, bb, sizeof(bb));\n        }\n    }\n    \n    // Final greedy refinement\n    memcpy(a, best_a, sizeof(a));\n    memcpy(b, best_b, sizeof(b));\n    auto dl = chrono::steady_clock::now() + chrono::milliseconds(150);\n    long long cur = simulate();\n    \n    while (chrono::steady_clock::now() < dl) {\n        int i = rng(N), oa = a[i], ob = b[i];\n        a[i] = rng(N);\n        long long ne = simulate();\n        if (ne < cur) { cur = ne; if (ne < best_err) { best_err = ne; memcpy(best_a, a, sizeof(a)); memcpy(best_b, b, sizeof(b)); } }\n        else a[i] = oa;\n        \n        b[i] = rng(N);\n        ne = simulate();\n        if (ne < cur) { cur = ne; if (ne < best_err) { best_err = ne; memcpy(best_a, a, sizeof(a)); memcpy(best_b, b, sizeof(b)); } }\n        else b[i] = ob;\n    }\n    \n    for (int i = 0; i < N; i++) cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<double> cx, cy;\nvector<int> lx, rx, ly, ry;\n\nstruct UnionFind {\n    vector<int> p;\n    UnionFind(int n) : p(n) { 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 x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        p[y] = x;\n        return true;\n    }\n};\n\ninline double estDist(int i, int j) {\n    double dx = cx[i] - cx[j], dy = cy[i] - cy[j];\n    return sqrt(dx*dx + dy*dy);\n}\n\ninline int minDist(int i, int j) {\n    int dx = 0, dy = 0;\n    if (rx[i] < lx[j]) dx = lx[j] - rx[i];\n    else if (rx[j] < lx[i]) dx = lx[i] - rx[j];\n    if (ry[i] < ly[j]) dy = ly[j] - ry[i];\n    else if (ry[j] < ly[i]) dy = ly[i] - ry[j];\n    return (int)sqrt((double)dx*dx + dy*dy);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    cx.resize(N); cy.resize(N);\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i] + rx[i]) / 2.0;\n        cy[i] = (ly[i] + ry[i]) / 2.0;\n    }\n    \n    // Greedy nearest-neighbor grouping\n    vector<int> assignment(N, -1);\n    vector<vector<int>> groups(M);\n    \n    // Sort groups by size (larger groups are harder to fill optimally)\n    vector<int> groupOrder(M);\n    iota(groupOrder.begin(), groupOrder.end(), 0);\n    sort(groupOrder.begin(), groupOrder.end(), [](int a, int b) { return G[a] > G[b]; });\n    \n    for (int gIdx = 0; gIdx < M; gIdx++) {\n        int g = groupOrder[gIdx];\n        \n        // Find unassigned city closest to origin as seed\n        int seed = -1;\n        double bestDist = 1e18;\n        for (int i = 0; i < N; i++) {\n            if (assignment[i] == -1) {\n                double d = cx[i] * cx[i] + cy[i] * cy[i];\n                if (d < bestDist) {\n                    bestDist = d;\n                    seed = i;\n                }\n            }\n        }\n        \n        if (seed == -1) break;\n        assignment[seed] = g;\n        groups[g].push_back(seed);\n        \n        // Greedily add nearest unassigned city\n        while ((int)groups[g].size() < G[g]) {\n            double best = 1e18;\n            int bestCity = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (assignment[i] == -1) {\n                    for (int c : groups[g]) {\n                        double d = estDist(i, c);\n                        if (d < best) {\n                            best = d;\n                            bestCity = i;\n                        }\n                    }\n                }\n            }\n            \n            if (bestCity != -1) {\n                assignment[bestCity] = g;\n                groups[g].push_back(bestCity);\n            } else break;\n        }\n    }\n    \n    // Query each group\n    set<pair<int,int>> verifiedEdges;\n    int qUsed = 0;\n    \n    for (int g = 0; g < M && qUsed < Q; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        if (sz <= L) {\n            cout << \"? \" << sz;\n            for (int c : groups[g]) cout << \" \" << c;\n            cout << endl;\n            \n            for (int i = 0; i < sz - 1; i++) {\n                int a, b;\n                cin >> a >> b;\n                verifiedEdges.insert({min(a, b), max(a, b)});\n            }\n            qUsed++;\n        } else {\n            // Sort group members by position for better query coverage\n            sort(groups[g].begin(), groups[g].end(), [](int a, int b) {\n                return make_pair(cx[a], cy[a]) < make_pair(cx[b], cy[b]);\n            });\n            \n            for (int start = 0; start < sz - 1 && qUsed < Q; start += L - 1) {\n                int end = min(start + L, sz);\n                cout << \"? \" << (end - start);\n                for (int i = start; i < end; i++) cout << \" \" << groups[g][i];\n                cout << endl;\n                \n                for (int i = 0; i < (end - start) - 1; i++) {\n                    int a, b;\n                    cin >> a >> b;\n                    verifiedEdges.insert({min(a, b), max(a, b)});\n                }\n                qUsed++;\n            }\n        }\n    }\n    \n    // Build MST for each group\n    vector<vector<pair<int,int>>> ans(M);\n    \n    for (int g = 0; g < M; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        vector<tuple<int, double, int, int>> edges;\n        for (int i = 0; i < sz; i++) {\n            for (int j = i + 1; j < sz; j++) {\n                int ci = groups[g][i], cj = groups[g][j];\n                int minD = minDist(ci, cj);\n                double estD = estDist(ci, cj);\n                edges.push_back({minD, estD, i, j});\n            }\n        }\n        sort(edges.begin(), edges.end());\n        \n        UnionFind uf(sz);\n        for (auto& [minD, estD, i, j] : edges) {\n            if (uf.unite(i, j)) {\n                ans[g].push_back({groups[g][i], groups[g][j]});\n                if (ans[g].size() == sz - 1) break;\n            }\n        }\n    }\n    \n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        for (int i = 0; i < (int)groups[g].size(); i++) {\n            if (i > 0) cout << \" \";\n            cout << groups[g][i];\n        }\n        cout << endl;\n        for (auto& [a, b] : ans[g]) {\n            cout << a << \" \" << b << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\npair<int, int> slide_end(int r, int c, int d, const vector<vector<bool>>& blocks) {\n    while (true) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N || blocks[nr][nc]) return {r, c};\n        r = nr; c = nc;\n    }\n}\n\nint get_dir_idx(char d) {\n    for (int i = 0; i < 4; i++) if (dir_char[i] == d) return i;\n    return -1;\n}\n\nvector<pair<char, char>> bfs(int sr, int sc, int tr, int tc, const vector<vector<bool>>& blocks) {\n    if (sr == tr && sc == tc) return {};\n    \n    vector<vector<int>> dist(N, vector<int>(N, -1));\n    vector<vector<tuple<int,int,char,char>>> prev(N, vector<tuple<int,int,char,char>>(N, {-1, -1, ' ', ' '}));\n    \n    queue<pair<int,int>> q;\n    q.push({sr, sc});\n    dist[sr][sc] = 0;\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == tr && c == tc) {\n            vector<pair<char, char>> path;\n            int cr = tr, cc = tc;\n            while (cr != sr || cc != sc) {\n                auto [pr, pc, a, d] = prev[cr][cc];\n                path.push_back({a, d});\n                cr = pr; cc = pc;\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \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 && !blocks[nr][nc] && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1;\n                prev[nr][nc] = {r, c, 'M', dir_char[d]};\n                q.push({nr, nc});\n            }\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            auto [nr, nc] = slide_end(r, c, d, blocks);\n            if (dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1;\n                prev[nr][nc] = {r, c, 'S', dir_char[d]};\n                q.push({nr, nc});\n            }\n        }\n    }\n    return {};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M;\n    vector<pair<int, int>> targets(M);\n    for (int i = 0; i < M; i++) cin >> targets[i].first >> targets[i].second;\n    \n    vector<vector<bool>> blocks(N, vector<bool>(N, false));\n    int cr = targets[0].first, cc = targets[0].second;\n    vector<pair<char, char>> actions;\n    \n    for (int t = 1; t < M; t++) {\n        int tr = targets[t].first, tc = targets[t].second;\n        \n        // Try Alter + Slide from start position\n        bool found_quick = false;\n        for (int d1 = 0; d1 < 4 && !found_quick; d1++) {\n            int br = cr + dr[d1], bc = cc + dc[d1];\n            if (br < 0 || br >= N || bc < 0 || bc >= N || blocks[br][bc]) continue;\n            \n            blocks[br][bc] = true;\n            for (int d2 = 0; d2 < 4 && !found_quick; d2++) {\n                auto [nr, nc] = slide_end(cr, cc, d2, blocks);\n                if (nr == tr && nc == tc) {\n                    actions.push_back({'A', dir_char[d1]});\n                    actions.push_back({'S', dir_char[d2]});\n                    cr = tr; cc = tc;\n                    found_quick = true;\n                }\n            }\n            if (!found_quick) blocks[br][bc] = false;\n        }\n        \n        if (!found_quick) {\n            auto path = bfs(cr, cc, tr, tc, blocks);\n            for (auto [a, d] : path) {\n                actions.push_back({a, d});\n                int di = get_dir_idx(d);\n                if (a == 'M') { cr += dr[di]; cc += dc[di]; }\n                else if (a == 'S') tie(cr, cc) = slide_end(cr, cc, di, blocks);\n            }\n        }\n    }\n    \n    for (auto [a, d] : actions) cout << a << ' ' << d << '\\n';\n    return 0;\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> X, Y;\nvector<long long> R;\nvector<int> a, b, c, d;\nvector<vector<vector<int>>> grid;\nmt19937 rng(42);\n\nvoid buildGrid() {\n    grid.assign(100, vector<vector<int>>(100));\n    for (int i = 0; i < n; i++) {\n        for (int x = max(0, a[i]/100); x <= min(99, (c[i]-1)/100); x++) {\n            for (int y = max(0, b[i]/100); y <= min(99, (d[i]-1)/100); y++) {\n                grid[x][y].push_back(i);\n            }\n        }\n    }\n}\n\nvoid removeFromGrid(int i) {\n    for (int x = max(0, a[i]/100); x <= min(99, (c[i]-1)/100); x++) {\n        for (int y = max(0, b[i]/100); y <= min(99, (d[i]-1)/100); y++) {\n            auto& v = grid[x][y];\n            v.erase(remove(v.begin(), v.end(), i), v.end());\n        }\n    }\n}\n\nvoid addToGrid(int i) {\n    for (int x = max(0, a[i]/100); x <= min(99, (c[i]-1)/100); x++) {\n        for (int y = max(0, b[i]/100); y <= min(99, (d[i]-1)/100); y++) {\n            grid[x][y].push_back(i);\n        }\n    }\n}\n\ndouble getScore(int i) {\n    long long area = (long long)(c[i] - a[i]) * (d[i] - b[i]);\n    long long mn = min(R[i], area);\n    long long mx = max(R[i], area);\n    return 1.0 - pow(1.0 - (double)mn / mx, 2);\n}\n\ndouble totalScore() {\n    double s = 0;\n    for (int i = 0; i < n; i++) s += getScore(i);\n    return s;\n}\n\nvoid solve(int L, int Rb, int B, int T, vector<int> ids) {\n    if (ids.empty()) return;\n    if (ids.size() == 1) {\n        int i = ids[0];\n        a[i] = L; b[i] = B; c[i] = Rb; d[i] = T;\n        return;\n    }\n    \n    int W = Rb - L, H = T - B;\n    long long totalTarget = 0;\n    for (int i : ids) totalTarget += R[i];\n    \n    double bestCost = 1e18;\n    bool bestVertical = false;\n    vector<int> bestLeftIds, bestRightIds;\n    int bestSplit = -1;\n    \n    for (int dir = 0; dir < 2; dir++) {\n        bool vertical = (dir == 0);\n        if (vertical && W < 2) continue;\n        if (!vertical && H < 2) continue;\n        \n        vector<int> sortedIds = ids;\n        sort(sortedIds.begin(), sortedIds.end(), [&](int i, int j) {\n            return vertical ? X[i] < X[j] : Y[i] < Y[j];\n        });\n        \n        long long acc = 0;\n        for (size_t idx = 1; idx < sortedIds.size(); idx++) {\n            acc += R[sortedIds[idx - 1]];\n            \n            int leftMax = vertical ? X[sortedIds[idx - 1]] : Y[sortedIds[idx - 1]];\n            int rightMin = vertical ? X[sortedIds[idx]] : Y[sortedIds[idx]];\n            \n            if (leftMax >= rightMin) continue;\n            \n            long long leftTarget = acc;\n            long long rightTarget = totalTarget - acc;\n            \n            int minSplit = leftMax + 1;\n            int maxSplit = rightMin;\n            \n            long long bestAreaCost = LLONG_MAX;\n            int bestS = -1;\n            \n            for (int s = minSplit; s <= maxSplit; s++) {\n                long long leftArea, rightArea;\n                if (vertical) {\n                    leftArea = (long long)(s - L) * H;\n                    rightArea = (long long)(Rb - s) * H;\n                } else {\n                    leftArea = (long long)(s - B) * W;\n                    rightArea = (long long)(T - s) * W;\n                }\n                \n                long long cost = abs(leftArea - leftTarget) + abs(rightArea - rightTarget);\n                if (cost < bestAreaCost) {\n                    bestAreaCost = cost;\n                    bestS = s;\n                }\n            }\n            \n            if (bestS < 0) continue;\n            \n            double cost = (double)bestAreaCost;\n            \n            if (cost < bestCost) {\n                bestCost = cost;\n                bestVertical = vertical;\n                bestLeftIds = vector<int>(sortedIds.begin(), sortedIds.begin() + idx);\n                bestRightIds = vector<int>(sortedIds.begin() + idx, sortedIds.end());\n                bestSplit = bestS;\n            }\n        }\n    }\n    \n    if (bestSplit < 0) {\n        bool vertical = (W >= H);\n        vector<int> sortedIds = ids;\n        sort(sortedIds.begin(), sortedIds.end(), [&](int i, int j) {\n            return vertical ? X[i] < X[j] : Y[i] < Y[j];\n        });\n        \n        size_t splitIdx = sortedIds.size() / 2;\n        bestLeftIds = vector<int>(sortedIds.begin(), sortedIds.begin() + splitIdx);\n        bestRightIds = vector<int>(sortedIds.begin() + splitIdx, sortedIds.end());\n        bestVertical = vertical;\n        \n        int leftMax = 0, rightMin = 10000;\n        for (int i : bestLeftIds) leftMax = max(leftMax, vertical ? X[i] : Y[i]);\n        for (int i : bestRightIds) rightMin = min(rightMin, vertical ? X[i] : Y[i]);\n        \n        bestSplit = (leftMax + rightMin + 1) / 2;\n        if (vertical) bestSplit = max(L + 1, min(Rb - 1, bestSplit));\n        else bestSplit = max(B + 1, min(T - 1, bestSplit));\n    }\n    \n    if (bestVertical) {\n        solve(L, bestSplit, B, T, bestLeftIds);\n        solve(bestSplit, Rb, B, T, bestRightIds);\n    } else {\n        solve(L, Rb, B, bestSplit, bestLeftIds);\n        solve(L, Rb, bestSplit, T, bestRightIds);\n    }\n}\n\nbool overlaps(int i, int j) {\n    return a[i] < c[j] && c[i] > a[j] && b[i] < d[j] && d[i] > b[j];\n}\n\nbool checkOverlap(int i, int newA, int newB, int newC, int newD) {\n    for (int x = max(0, newA/100); x <= min(99, (newC-1)/100); x++) {\n        for (int y = max(0, newB/100); y <= min(99, (newD-1)/100); y++) {\n            for (int j : grid[x][y]) {\n                if (i != j) {\n                    if (newA < c[j] && newC > a[j] && newB < d[j] && newD > b[j]) return true;\n                }\n            }\n        }\n    }\n    return false;\n}\n\nbool isValidFast(int i, int newA, int newB, int newC, int newD) {\n    if (newA < 0 || newB < 0 || newC > 10000 || newD > 10000) return false;\n    if (newC - newA < 1 || newD - newB < 1) return false;\n    if (X[i] < newA || X[i] >= newC || Y[i] < newB || Y[i] >= newD) return false;\n    return !checkOverlap(i, newA, newB, newC, newD);\n}\n\nvoid optimize() {\n    buildGrid();\n    \n    double bestTotal = totalScore();\n    vector<int> bestA = a, bestB = b, bestC = c, bestD = d;\n    \n    uniform_int_distribution<int> distIdx(0, n - 1);\n    uniform_real_distribution<double> distReal(0.0, 1.0);\n    \n    // SA phase\n    double temp = 1.5;\n    for (int iter = 0; iter < 300000; iter++) {\n        int i = distIdx(rng);\n        long long area = (long long)(c[i] - a[i]) * (d[i] - b[i]);\n        long long diff = abs(area - R[i]);\n        \n        int newA = a[i], newB = b[i], newC = c[i], newD = d[i];\n        double oldScore = getScore(i);\n        \n        int dir = rng() % 8;\n        int maxAmt = max(1, (int)min(100LL, diff / 80 + 1));\n        int amt = 1 + rng() % maxAmt;\n        \n        if (dir == 0) newA -= amt;\n        else if (dir == 1) newB -= amt;\n        else if (dir == 2) newC += amt;\n        else if (dir == 3) newD += amt;\n        else if (dir == 4) newA += amt;\n        else if (dir == 5) newB += amt;\n        else if (dir == 6) newC -= amt;\n        else newD -= amt;\n        \n        if (isValidFast(i, newA, newB, newC, newD)) {\n            removeFromGrid(i);\n            int oldA = a[i], oldB = b[i], oldC = c[i], oldD = d[i];\n            a[i] = newA; b[i] = newB; c[i] = newC; d[i] = newD;\n            addToGrid(i);\n            \n            double newScore = getScore(i);\n            double delta = newScore - oldScore;\n            \n            if (delta < 0 && distReal(rng) >= exp(delta * 150 / temp)) {\n                removeFromGrid(i);\n                a[i] = oldA; b[i] = oldB; c[i] = oldC; d[i] = oldD;\n                addToGrid(i);\n            } else {\n                double curTotal = totalScore();\n                if (curTotal > bestTotal) {\n                    bestTotal = curTotal;\n                    bestA = a; bestB = b; bestC = c; bestD = d;\n                }\n            }\n        }\n        \n        temp *= 0.99997;\n    }\n    \n    // Greedy phase\n    for (int iter = 0; iter < 2000; iter++) {\n        bool changed = false;\n        \n        vector<pair<double, int>> order;\n        for (int i = 0; i < n; i++) order.push_back({getScore(i), i});\n        sort(order.begin(), order.end());\n        \n        for (auto& p : order) {\n            int i = p.second;\n            double currentScore = getScore(i);\n            \n            for (int dir = 0; dir < 8; dir++) {\n                int newA = a[i], newB = b[i], newC = c[i], newD = d[i];\n                \n                if (dir == 0) newA--;\n                else if (dir == 1) newB--;\n                else if (dir == 2) newC++;\n                else if (dir == 3) newD++;\n                else if (dir == 4) newA++;\n                else if (dir == 5) newB++;\n                else if (dir == 6) newC--;\n                else newD--;\n                \n                if (isValidFast(i, newA, newB, newC, newD)) {\n                    removeFromGrid(i);\n                    a[i] = newA; b[i] = newB; c[i] = newC; d[i] = newD;\n                    addToGrid(i);\n                    \n                    double newScore = getScore(i);\n                    if (newScore > currentScore + 1e-10) {\n                        currentScore = newScore;\n                        changed = true;\n                        double curTotal = totalScore();\n                        if (curTotal > bestTotal) {\n                            bestTotal = curTotal;\n                            bestA = a; bestB = b; bestC = c; bestD = d;\n                        }\n                    } else {\n                        removeFromGrid(i);\n                        a[i] = newA + ((dir==0)-(dir==4));\n                        b[i] = newB + ((dir==1)-(dir==5));\n                        c[i] = newC + ((dir==6)-(dir==2));\n                        d[i] = newD + ((dir==7)-(dir==3));\n                        addToGrid(i);\n                    }\n                }\n            }\n        }\n        \n        if (!changed) break;\n    }\n    \n    a = bestA; b = bestB; c = bestC; d = bestD;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    a.resize(n); b.resize(n); c.resize(n); d.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> X[i] >> Y[i] >> R[i];\n    }\n    \n    vector<int> ids(n);\n    iota(ids.begin(), ids.end(), 0);\n    \n    solve(0, 10000, 0, 10000, ids);\n    optimize();\n    \n    for (int i = 0; i < n; i++) {\n        cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<vector<int>> t(50, vector<int>(50)), p(50, vector<int>(50));\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) cin >> t[i][j];\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) cin >> p[i][j];\n    \n    map<int, vector<pair<int,int>>> tileSquares;\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++)\n            tileSquares[t[i][j]].push_back({i, j});\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    set<int> visited;\n    string path;\n    int ci = si, cj = sj;\n    visited.insert(t[ci][cj]);\n    \n    auto& startSquares = tileSquares[t[ci][cj]];\n    if (startSquares.size() == 2) {\n        auto [oi, oj] = (startSquares[0].first == ci && startSquares[0].second == cj) \n            ? make_pair(startSquares[1].first, startSquares[1].second) \n            : make_pair(startSquares[0].first, startSquares[0].second);\n        path += (oi < ci ? 'U' : oi > ci ? 'D' : oj < cj ? 'L' : 'R');\n        ci = oi; cj = oj;\n    }\n    \n    while (true) {\n        int bestDir = -1, bestExitI = -1, bestExitJ = -1;\n        string bestTilePath;\n        double bestValue = -1e18;\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = ci + di[d], nj = cj + dj[d];\n            if (ni < 0 || ni >= 50 || nj < 0 || nj >= 50 || visited.count(t[ni][nj])) continue;\n            \n            int tileId = t[ni][nj];\n            auto& sq = tileSquares[tileId];\n            int tileScore = 0;\n            for (auto& [ti, tj] : sq) tileScore += p[ti][tj];\n            \n            for (size_t ei = 0; ei < sq.size(); ei++) {\n                int exi = sq[ei].first, exj = sq[ei].second;\n                visited.insert(tileId);\n                int future = 0;\n                for (int d2 = 0; d2 < 4; d2++) {\n                    int n2i = exi + di[d2], n2j = exj + dj[d2];\n                    if (n2i >= 0 && n2i < 50 && n2j >= 0 && n2j < 50 && !visited.count(t[n2i][n2j])) future++;\n                }\n                visited.erase(tileId);\n                \n                double value = tileScore + (future == 0 ? -1000.0 : future * 10.0);\n                string tilePath;\n                if (sq.size() == 2) {\n                    int oi = sq[1-ei].first, oj = sq[1-ei].second;\n                    if (ni == exi && nj == exj) {\n                        char to = (oi < exi ? 'U' : oi > exi ? 'D' : oj < exj ? 'L' : 'R');\n                        char back = (to == 'U' ? 'D' : to == 'D' ? 'U' : to == 'L' ? 'R' : 'L');\n                        tilePath = string(1, to) + string(1, back);\n                    } else {\n                        tilePath = string(1, (exi < ni ? 'U' : exi > ni ? 'D' : exj < nj ? 'L' : 'R'));\n                    }\n                }\n                if (value > bestValue) { bestValue = value; bestDir = d; bestExitI = exi; bestExitJ = exj; bestTilePath = tilePath; }\n            }\n        }\n        if (bestDir == -1) break;\n        visited.insert(t[ci + di[bestDir]][cj + dj[bestDir]]);\n        path += dc[bestDir]; path += bestTilePath;\n        ci = bestExitI; cj = bestExitJ;\n    }\n    cout << path << endl;\n    return 0;\n}","ahc003":"#include <iostream>\n#include <queue>\n#include <string>\n#include <tuple>\n#include <cmath>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 30;\n\ndouble h[N][N-1], v[N-1][N];\nint cnt_h[N][N-1], cnt_v[N-1][N];\n\ndouble dist[N][N];\nint prev_dir[N][N];\nbool visited[N][N];\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dc[] = {'U', 'D', 'L', 'R'};\n\nstring dijkstra(int si, int sj, int ti, int tj, double exploration) {\n    memset(visited, 0, sizeof(visited));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            dist[i][j] = 1e18;\n    \n    auto get_cost = [&](int type, int i, int j, int cnt) -> double {\n        double mean = (type == 0) ? h[i][j] : v[i][j];\n        return mean - exploration * sqrt(mean / 5000.0) / sqrt(cnt + 1);\n    };\n    \n    priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<tuple<double, int, int>>> pq;\n    dist[si][sj] = 0;\n    pq.push(make_tuple(0.0, si, sj));\n    \n    while (!pq.empty()) {\n        double d = get<0>(pq.top());\n        int i = get<1>(pq.top());\n        int j = get<2>(pq.top());\n        pq.pop();\n        \n        if (visited[i][j]) continue;\n        visited[i][j] = true;\n        if (i == ti && j == tj) break;\n        \n        if (i > 0 && !visited[i-1][j]) {\n            double c = get_cost(1, i-1, j, cnt_v[i-1][j]);\n            if (dist[i-1][j] > d + c) { dist[i-1][j] = d + c; prev_dir[i-1][j] = 0; pq.push(make_tuple(dist[i-1][j], i-1, j)); }\n        }\n        if (i < N-1 && !visited[i+1][j]) {\n            double c = get_cost(1, i, j, cnt_v[i][j]);\n            if (dist[i+1][j] > d + c) { dist[i+1][j] = d + c; prev_dir[i+1][j] = 1; pq.push(make_tuple(dist[i+1][j], i+1, j)); }\n        }\n        if (j > 0 && !visited[i][j-1]) {\n            double c = get_cost(0, i, j-1, cnt_h[i][j-1]);\n            if (dist[i][j-1] > d + c) { dist[i][j-1] = d + c; prev_dir[i][j-1] = 2; pq.push(make_tuple(dist[i][j-1], i, j-1)); }\n        }\n        if (j < N-1 && !visited[i][j+1]) {\n            double c = get_cost(0, i, j, cnt_h[i][j]);\n            if (dist[i][j+1] > d + c) { dist[i][j+1] = d + c; prev_dir[i][j+1] = 3; pq.push(make_tuple(dist[i][j+1], i, j+1)); }\n        }\n    }\n    \n    string path = \"\";\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int dir = prev_dir[ci][cj];\n        path = dc[dir] + path;\n        ci -= di[dir];\n        cj -= dj[dir];\n    }\n    return path;\n}\n\nvoid update_estimates(const string& path, int si, int sj, int observed) {\n    double estimated_sum = 0;\n    int ci = si, cj = sj;\n    for (char c : path) {\n        int dir = (c == 'U') ? 0 : (c == 'D') ? 1 : (c == 'L') ? 2 : 3;\n        if (dir == 0) { estimated_sum += v[ci-1][cj]; ci--; }\n        else if (dir == 1) { estimated_sum += v[ci][cj]; ci++; }\n        else if (dir == 2) { estimated_sum += h[ci][cj-1]; cj--; }\n        else { estimated_sum += h[ci][cj]; cj++; }\n    }\n    \n    double ratio = observed / estimated_sum;\n    \n    ci = si; cj = sj;\n    for (char c : path) {\n        int dir = (c == 'U') ? 0 : (c == 'D') ? 1 : (c == 'L') ? 2 : 3;\n        double* mean; int* cnt;\n        if (dir == 0) { mean = &v[ci-1][cj]; cnt = &cnt_v[ci-1][cj]; ci--; }\n        else if (dir == 1) { mean = &v[ci][cj]; cnt = &cnt_v[ci][cj]; ci++; }\n        else if (dir == 2) { mean = &h[ci][cj-1]; cnt = &cnt_h[ci][cj-1]; cj--; }\n        else { mean = &h[ci][cj]; cnt = &cnt_h[ci][cj]; cj++; }\n        \n        (*cnt)++;\n        double alpha = min(0.75, 0.75 / pow(*cnt, 0.3));\n        *mean *= (1.0 - alpha + alpha * ratio);\n        *mean = max(800.0, min(10000.0, *mean));\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N-1; j++)\n            h[i][j] = 5000.0, cnt_h[i][j] = 0;\n    for (int i = 0; i < N-1; i++)\n        for (int j = 0; j < N; j++)\n            v[i][j] = 5000.0, cnt_v[i][j] = 0;\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj; \n        cin >> si >> sj >> ti >> tj;\n        \n        // Exponential decay exploration with minimum\n        double exploration = max(10.0, 5000.0 * exp(-k / 100.0));\n        \n        string path = dijkstra(si, sj, ti, tj, exploration);\n        \n        cout << path << endl;\n        cout.flush();\n        \n        int observed;\n        cin >> observed;\n        \n        update_estimates(path, si, sj, observed);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\n\nint M;\nchar strLen[800];\nchar grid[N*N];\nshort matchCnt[640000];\nshort perfect[800];\nchar strChar[800][13];\n\nint cellStart[N*N+1];\nint cellPid[7000000];\nchar cellExp[7000000];\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n >> M;\n    \n    for (int i = 0; i < M; i++) {\n        string s;\n        cin >> s;\n        strLen[i] = s.size();\n        for (int j = 0; j < strLen[i]; j++) strChar[i][j] = s[j] - 'A';\n    }\n    \n    // Build cell data\n    int idx = 0;\n    for (int cell = 0; cell < N*N; cell++) {\n        cellStart[cell] = idx;\n        int cr = cell / N, cc = cell % N;\n        \n        for (int si = 0; si < M; si++) {\n            int L = strLen[si];\n            for (int p = 0; p < L; p++) {\n                int sc = (cc - p + N) % N;\n                cellPid[idx] = si * 800 + cr * N + sc;\n                cellExp[idx++] = strChar[si][p];\n            }\n            for (int p = 0; p < L; p++) {\n                int sr = (cr - p + N) % N;\n                cellPid[idx] = si * 800 + 400 + sr * N + cc;\n                cellExp[idx++] = strChar[si][p];\n            }\n        }\n    }\n    cellStart[N*N] = idx;\n    \n    // Voting\n    for (int cell = 0; cell < N*N; cell++) {\n        int votes[8] = {};\n        for (int j = cellStart[cell]; j < cellStart[cell+1]; j++)\n            votes[(int)cellExp[j]]++;\n        int best = 0;\n        for (int c = 1; c < 8; c++) if (votes[c] > votes[best]) best = c;\n        grid[cell] = best;\n    }\n    \n    // Initialize\n    memset(matchCnt, 0, M * 800 * sizeof(short));\n    for (int cell = 0; cell < N*N; cell++)\n        for (int j = cellStart[cell]; j < cellStart[cell+1]; j++)\n            if (grid[cell] == cellExp[j]) matchCnt[cellPid[j]]++;\n    \n    for (int pid = 0; pid < M * 800; pid++) {\n        int si = pid / 800;\n        if (matchCnt[pid] == strLen[si]) perfect[si]++;\n    }\n    \n    int score = 0;\n    for (int si = 0; si < M; si++) if (perfect[si] > 0) score++;\n    \n    char bestGrid[N*N];\n    memcpy(bestGrid, grid, sizeof(grid));\n    int bestScore = score;\n    \n    // Precompute exp table\n    float expTab[200];\n    for (int i = 0; i < 200; i++) expTab[i] = exp(-i * 0.05f);\n    \n    mt19937 rng_eng(42);\n    uniform_int_distribution<int> dist_cell(0, N*N-1);\n    uniform_int_distribution<int> dist_char(0, 7);\n    \n    float T = 2.0f;\n    \n    for (int iter = 0; iter < 8000; iter++) {\n        int cell = dist_cell(rng_eng);\n        int old = grid[cell];\n        int newCh = dist_char(rng_eng);\n        if (newCh == old) continue;\n        \n        int delta = 0;\n        int *cp = cellPid + cellStart[cell];\n        char *ce = cellExp + cellStart[cell];\n        int cellCnt = cellStart[cell+1] - cellStart[cell];\n        \n        for (int j = 0; j < cellCnt; j++) {\n            int pid = cp[j];\n            int expChar = ce[j];\n            int si = pid / 800;\n            int L = strLen[si];\n            short mc = matchCnt[pid];\n            \n            bool wasP = (mc == L);\n            if (old == expChar) mc--;\n            if (newCh == expChar) mc++;\n            matchCnt[pid] = mc;\n            bool nowP = (mc == L);\n            \n            if (wasP && !nowP) { perfect[si]--; if (!perfect[si]) delta--; }\n            else if (!wasP && nowP) { if (!perfect[si]) delta++; perfect[si]++; }\n        }\n        \n        bool accept = (delta >= 0);\n        if (!accept) {\n            int tabIdx = min(199, (int)(-delta / T * 20));\n            accept = (((float)(rng_eng() & 0xFFFF) / 65536.0f) < expTab[tabIdx]);\n        }\n        \n        if (accept) {\n            grid[cell] = newCh;\n            score += delta;\n            if (score > bestScore) { bestScore = score; memcpy(bestGrid, grid, sizeof(grid)); }\n        } else {\n            for (int j = 0; j < cellCnt; j++) {\n                int pid = cp[j];\n                int expChar = ce[j];\n                int si = pid / 800;\n                int L = strLen[si];\n                short mc = matchCnt[pid];\n                \n                bool wasP = (mc == L);\n                if (newCh == expChar) mc--;\n                if (old == expChar) mc++;\n                matchCnt[pid] = mc;\n                bool nowP = (mc == L);\n                \n                if (wasP && !nowP) perfect[si]--;\n                else if (!wasP && nowP) perfect[si]++;\n            }\n        }\n        T *= 0.9997f;\n    }\n    \n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) cout << (char)('A' + bestGrid[r*N + c]);\n        cout << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> grid;\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dc[] = {'U', 'D', 'L', 'R'};\n\ninline bool isRoad(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\ninline int w(int i, int j) { return grid[i][j] - '0'; }\n\nvector<vector<vector<pair<int,int>>>> visList;\nvector<pair<int,int>> roads;\nint totalRoads;\n\nstring solve(int si, int sj, double distWeight, double coverWeight) {\n    vector<vector<bool>> covered(N, vector<bool>(N, false));\n    int numCovered = 0;\n    \n    auto doCover = [&](int i, int j) {\n        for (auto& [ni, nj] : visList[i][j])\n            if (!covered[ni][nj]) { covered[ni][nj] = true; numCovered++; }\n    };\n    \n    auto countNewCover = [&](int i, int j) {\n        int cnt = 0;\n        for (auto& [ni, nj] : visList[i][j])\n            if (!covered[ni][nj]) cnt++;\n        return cnt;\n    };\n    \n    vector<vector<int>> dist(N, vector<int>(N));\n    vector<vector<int>> parentDir(N, vector<int>(N));\n    \n    auto dijkstra = [&](int si, int sj) {\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) { dist[i][j] = INT_MAX; parentDir[i][j] = -1; }\n        priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n        dist[si][sj] = 0;\n        pq.push({0, si, sj});\n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top(); pq.pop();\n            if (d > dist[i][j]) continue;\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (isRoad(ni, nj)) {\n                    int nd = d + w(ni, nj);\n                    if (nd < dist[ni][nj]) {\n                        dist[ni][nj] = nd; parentDir[ni][nj] = k;\n                        pq.push({nd, ni, nj});\n                    }\n                }\n            }\n        }\n    };\n    \n    string route;\n    int ci = si, cj = sj;\n    doCover(ci, cj);\n    \n    while (numCovered < totalRoads) {\n        dijkstra(ci, cj);\n        \n        double bestScore = -1;\n        int besti = -1, bestj = -1;\n        for (auto& [i, j] : roads) {\n            if (dist[i][j] == INT_MAX) continue;\n            int newC = countNewCover(i, j);\n            if (newC == 0) continue;\n            double score = pow((double)newC, coverWeight) * 10000.0 / pow((double)max(1, dist[i][j]), distWeight);\n            if (score > bestScore) { bestScore = score; besti = i; bestj = j; }\n        }\n        \n        if (besti == -1) break;\n        \n        vector<int> pathDir;\n        int ti = besti, tj = bestj;\n        while (ti != ci || tj != cj) {\n            int d = parentDir[ti][tj];\n            pathDir.push_back(d);\n            ti -= di[d]; tj -= dj[d];\n        }\n        reverse(pathDir.begin(), pathDir.end());\n        \n        for (int d : pathDir) {\n            route += dc[d]; ci += di[d]; cj += dj[d]; doCover(ci, cj);\n        }\n    }\n    \n    dijkstra(ci, cj);\n    vector<int> pathDir;\n    int ti = si, tj = sj;\n    while (ti != ci || tj != cj) {\n        int d = parentDir[ti][tj];\n        pathDir.push_back(d);\n        ti -= di[d]; tj -= dj[d];\n    }\n    reverse(pathDir.begin(), pathDir.end());\n    for (int d : pathDir) route += dc[d];\n    \n    return route;\n}\n\nint computeTime(const string& route, int si, int sj) {\n    int t = 0, ci = si, cj = sj;\n    for (char c : route) {\n        int d = string(\"UDLR\").find(c);\n        ci += di[d]; cj += dj[d];\n        t += w(ci, cj);\n    }\n    return t;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (isRoad(i, j)) roads.push_back({i, j});\n    \n    totalRoads = roads.size();\n    \n    visList.assign(N, vector<vector<pair<int,int>>>(N));\n    for (auto& [i, j] : roads) {\n        visList[i][j].push_back({i, j});\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            while (isRoad(ni, nj)) {\n                visList[i][j].push_back({ni, nj});\n                ni += di[d]; nj += dj[d];\n            }\n        }\n    }\n    \n    string bestRoute;\n    int bestTime = INT_MAX;\n    \n    // Parameter sweep\n    for (double dw = 0.8; dw <= 1.4; dw += 0.1) {\n        for (double cw = 0.8; cw <= 1.4; cw += 0.1) {\n            string route = solve(si, sj, dw, cw);\n            int t = computeTime(route, si, sj);\n            if (t < bestTime) {\n                bestTime = t;\n                bestRoute = route;\n            }\n        }\n    }\n    \n    cout << bestRoute << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <set>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> d, deps, reverse_deps;\nvector<vector<double>> s_est, s_lower;\nvector<int> in_degree, task_start_day, task_status, member_task, critical_len;\nset<int> ready_tasks;\nvector<int> tasks_done_count;\nmt19937 rng(42);\n\nint estimate_time(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++)\n        w += max(0.0, (double)d[task][k] - s_est[member][k]);\n    return max(1, (int)round(w));\n}\n\ndouble estimate_w(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++)\n        w += max(0.0, (double)d[task][k] - s_est[member][k]);\n    return w;\n}\n\nvoid update_skills(int member, int task, int duration) {\n    // Track contributions\n    vector<double> contrib(K, 0);\n    double total_contrib = 0;\n    for (int k = 0; k < K; k++) {\n        contrib[k] = max(0.0, (double)d[task][k] - s_est[member][k]);\n        total_contrib += contrib[k];\n    }\n    \n    if (duration == 1) {\n        // w <= 4, so skills are close to requirements\n        // Set lower bounds: s[k] >= d[k] - (remaining w / K)\n        for (int k = 0; k < K; k++) {\n            if (d[task][k] > s_lower[member][k]) {\n                s_lower[member][k] = d[task][k];\n            }\n            // Raise estimate to at least task requirement minus small buffer\n            s_est[member][k] = max(s_est[member][k], (double)d[task][k] - 1.0);\n            s_est[member][k] = max(s_est[member][k], s_lower[member][k]);\n        }\n        return;\n    }\n    \n    // For duration > 1: w \u2248 duration (since E[r] = 0)\n    double obs_w = (double)duration;\n    \n    if (total_contrib < 0.5) {\n        // Predicted to be fast but was slow - skills are overestimated\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 dec = obs_w * (d[task][k] / total_d) * 0.4;\n                    s_est[member][k] = max(s_lower[member][k], s_est[member][k] - dec);\n                }\n            }\n        }\n        return;\n    }\n    \n    double error = obs_w - total_contrib;\n    double lr = 0.6 / (1.0 + tasks_done_count[member] * 0.03);\n    \n    for (int k = 0; k < K; k++) {\n        if (contrib[k] > 1e-9) {\n            double weight = contrib[k] / total_contrib;\n            double change = error * weight * lr;\n            if (error > 0) {\n                // Skills overestimated\n                s_est[member][k] = max(s_lower[member][k], s_est[member][k] - change);\n            } else {\n                // Skills underestimated\n                s_est[member][k] -= change * 0.4;\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K >> R;\n    d.resize(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> d[i][k];\n    \n    deps.resize(N); reverse_deps.resize(N); in_degree.assign(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u); reverse_deps[u].push_back(v);\n        in_degree[v]++;\n    }\n    \n    // Topological sort\n    vector<int> order, td = in_degree;\n    queue<int> q;\n    for (int i = 0; i < N; i++) if (td[i] == 0) q.push(i);\n    while (!q.empty()) {\n        int u = q.front(); q.pop(); order.push_back(u);\n        for (int v : reverse_deps[u]) if (--td[v] == 0) q.push(v);\n    }\n    \n    // Critical path\n    critical_len.assign(N, 0);\n    for (int i = N - 1; i >= 0; i--)\n        for (int v : reverse_deps[order[i]])\n            critical_len[order[i]] = max(critical_len[order[i]], critical_len[v] + 1);\n    \n    // Task statistics\n    vector<double> avg_d(K, 0), max_d(K, 0);\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) {\n            avg_d[k] += d[i][k];\n            max_d[k] = max(max_d[k], (double)d[i][k]);\n        }\n    for (int k = 0; k < K; k++) avg_d[k] /= N;\n    \n    // Initialize: skills should be around 40/sqrt(K) per dimension on average\n    // Tasks are around 25/sqrt(K) per dimension\n    double init_skill = 40.0 / sqrt(K);\n    s_est.assign(M, vector<double>(K));\n    s_lower.assign(M, vector<double>(K, 0));\n    for (int j = 0; j < M; j++)\n        for (int k = 0; k < K; k++)\n            s_est[j][k] = avg_d[k] * 0.8 + init_skill * 0.2;\n    \n    tasks_done_count.assign(M, 0);\n    task_status.assign(N, -1); \n    task_start_day.assign(N, -1); \n    member_task.assign(M, -1);\n    \n    for (int i = 0; i < N; i++) \n        if (in_degree[i] == 0) \n            ready_tasks.insert(i);\n    \n    int day = 0;\n    \n    while (true) {\n        day++;\n        vector<pair<int,int>> assignments;\n        set<int> assigned;\n        \n        while (true) {\n            double best_score = 1e18; \n            int best_m = -1, best_t = -1;\n            \n            for (int m = 0; m < M; m++) {\n                if (member_task[m] != -1) continue;\n                \n                for (int t : ready_tasks) {\n                    if (assigned.count(t)) continue;\n                    \n                    double est_time = estimate_time(t, m);\n                    double priority = critical_len[t] * 0.12;\n                    \n                    // Exploration bonus\n                    double exploration = 0;\n                    if (tasks_done_count[m] < 10) {\n                        exploration = 1.5 * (10 - tasks_done_count[m]);\n                    }\n                    \n                    // Small random for tie-breaking\n                    double noise = uniform_real_distribution<double>(0, 0.5)(rng);\n                    \n                    double score = est_time - priority - exploration + noise;\n                    \n                    if (score < best_score) {\n                        best_score = score;\n                        best_m = m;\n                        best_t = t;\n                    }\n                }\n            }\n            \n            if (best_m == -1) break;\n            \n            assignments.push_back({best_m + 1, best_t + 1});\n            member_task[best_m] = best_t;\n            task_status[best_t] = 0;\n            task_start_day[best_t] = day;\n            assigned.insert(best_t);\n        }\n        \n        for (auto& p : assignments) \n            ready_tasks.erase(p.second - 1);\n        \n        cout << assignments.size();\n        for (auto& p : assignments) \n            cout << \" \" << p.first << \" \" << p.second;\n        cout << \"\\n\" << flush;\n        \n        int n; \n        cin >> n;\n        if (n == -1) break;\n        \n        for (int i = 0; i < n; i++) {\n            int f; cin >> f; f--;\n            int task = member_task[f];\n            member_task[f] = -1;\n            \n            int duration = day - task_start_day[task] + 1;\n            task_status[task] = 1;\n            tasks_done_count[f]++;\n            \n            update_skills(f, task, duration);\n            \n            for (int v : reverse_deps[task]) {\n                in_degree[v]--;\n                if (in_degree[v] == 0 && task_status[v] == -1) \n                    ready_tasks.insert(v);\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(42);\nconst int DEPOT = 400;\nconst double TIME_LIMIT = 1.70;\n\nint dist(int x1, int y1, int x2, int y2) { return abs(x1-x2) + abs(y1-y2); }\n\nstruct Solver {\n    vector<array<int,4>> orders;\n    vector<int> selected, route;\n    chrono::time_point<chrono::steady_clock> start_time;\n    int current_dist, best_dist;\n    vector<int> best_selected;\n    \n    void read_input() {\n        orders.resize(1000);\n        for(int i=0;i<1000;i++) cin>>orders[i][0]>>orders[i][1]>>orders[i][2]>>orders[i][3];\n        start_time = chrono::steady_clock::now();\n    }\n    \n    double elapsed() { return chrono::duration<double>(chrono::steady_clock::now()-start_time).count(); }\n    \n    pair<int,int> get_coords(int loc) {\n        if(loc==-1) return {DEPOT,DEPOT};\n        if(loc<50) return {orders[selected[loc]][0], orders[selected[loc]][1]};\n        return {orders[selected[loc-50]][2], orders[selected[loc-50]][3]};\n    }\n    \n    int calc_dist() {\n        int d=0;\n        for(int i=0;i+1<(int)route.size();i++) {\n            auto[x1,y1]=get_coords(route[i]); auto[x2,y2]=get_coords(route[i+1]);\n            d+=dist(x1,y1,x2,y2);\n        }\n        return d;\n    }\n    \n    void save_best() { best_dist=current_dist; best_selected=selected; }\n    \n    void select_orders_greedy() {\n        vector<pair<int,int>> scored;\n        for(int i=0;i<1000;i++) {\n            auto& o=orders[i];\n            scored.push_back({dist(DEPOT,DEPOT,o[0],o[1])+dist(o[0],o[1],o[2],o[3])+dist(o[2],o[3],DEPOT,DEPOT),i});\n        }\n        sort(scored.begin(),scored.end());\n        for(int i=0;i<50;i++) selected.push_back(scored[i].second);\n    }\n    \n    void build_route() {\n        route.clear();\n        route.push_back(-1); \n        vector<bool> picked(50,false), delivered(50,false);\n        int cx=DEPOT, cy=DEPOT;\n        \n        for(int step=0;step<100;step++) {\n            int best=-1, best_d=INT_MAX;\n            \n            // Check pickups\n            for(int i=0;i<50;i++) {\n                if(!picked[i]) {\n                    auto[x,y]=get_coords(i);\n                    int d=dist(cx,cy,x,y);\n                    if(d<best_d){best_d=d;best=i;}\n                }\n            }\n            // Check deliveries\n            for(int i=0;i<50;i++) {\n                if(picked[i] && !delivered[i]) {\n                    auto[x,y]=get_coords(i+50);\n                    int d=dist(cx,cy,x,y);\n                    if(d<best_d){best_d=d;best=i+50;}\n                }\n            }\n            \n            assert(best!=-1); // Should always find something\n            route.push_back(best);\n            if(best<50) picked[best]=true; \n            else delivered[best-50]=true;\n            tie(cx,cy)=get_coords(best);\n        }\n        route.push_back(-1);\n        current_dist=calc_dist();\n    }\n    \n    void local_search() {\n        while(true) {\n            if(elapsed()>TIME_LIMIT*0.8) return;\n            bool improved=false;\n            int n=route.size();\n            \n            vector<int> pickup_at(50,-1), delivery_at(50,-1);\n            for(int k=0;k<n;k++){\n                int loc=route[k];\n                if(loc==-1) continue;\n                if(loc<50) pickup_at[loc]=k; \n                else delivery_at[loc-50]=k;\n            }\n            \n            // 2-opt\n            for(int i=1;i<n-2 && !improved;i++) {\n                for(int j=i+1;j<n-1;j++) {\n                    bool ok=true;\n                    for(int o=0;o<50;o++) {\n                        int p=pickup_at[o], d=delivery_at[o];\n                        bool pi=(p>=i && p<=j), di=(d>=i && d<=j);\n                        if(pi!=di) {ok=false; break;}\n                    }\n                    if(!ok) continue;\n                    \n                    auto[pi,py]=get_coords(route[i-1]); auto[jx,jy]=get_coords(route[j]);\n                    auto[ix,iy]=get_coords(route[i]); auto[pj,pjy]=get_coords(route[j+1]);\n                    int diff=dist(pi,py,jx,jy)+dist(ix,iy,pj,pjy)-dist(pi,py,ix,iy)-dist(jx,jy,pj,pjy);\n                    if(diff<0) {\n                        reverse(route.begin()+i,route.begin()+j+1);\n                        current_dist+=diff;\n                        improved=true;\n                        for(int k=i;k<=j;k++){\n                            int loc=route[k]; if(loc==-1) continue;\n                            if(loc<50) pickup_at[loc]=k; else delivery_at[loc-50]=k;\n                        }\n                        break;\n                    }\n                }\n            }\n            if(improved) continue;\n            \n            // relocate\n            for(int i=1;i<n-1 && !improved;i++) {\n                int loc=route[i]; if(loc==-1) continue;\n                int ol=(loc<50)?loc:loc-50;\n                bool is_p=loc<50;\n                int other=is_p?delivery_at[ol]:pickup_at[ol];\n                \n                for(int np=1;np<n-1;np++) {\n                    if(is_p && np>other) continue;\n                    if(!is_p && np<=other) continue;\n                    if(np==i || np==i-1) continue;\n                    \n                    int ip=(np<i)?np+1:np;\n                    auto[pi,py]=get_coords(route[i-1]); auto[cx,cy]=get_coords(loc);\n                    auto[ni,nx]=get_coords(route[i+1]); auto[oi,oy]=get_coords(route[ip-1]);\n                    auto[nip,ny]=get_coords(route[ip]);\n                    int diff=dist(oi,oy,cx,cy)+dist(cx,cy,nip,ny)+dist(pi,py,ni,nx)\n                            -dist(oi,oy,nip,ny)-dist(pi,py,cx,cy)-dist(cx,cy,ni,nx);\n                    if(diff<0) {\n                        route.erase(route.begin()+i);\n                        if(np<i) route.insert(route.begin()+np+1,loc);\n                        else route.insert(route.begin()+ip,loc);\n                        current_dist+=diff;\n                        improved=true;\n                        // Rebuild position arrays\n                        for(int k=0;k<(int)route.size();k++){\n                            int l=route[k]; if(l==-1) continue;\n                            if(l<50) pickup_at[l]=k; else delivery_at[l-50]=k;\n                        }\n                        break;\n                    }\n                }\n            }\n            if(!improved) break;\n        }\n    }\n    \n    void run_sa() {\n        set<int> sel_set(selected.begin(),selected.end());\n        save_best();\n        double temp=5000;\n        \n        while(elapsed()<TIME_LIMIT) {\n            int out_idx=rng()%50, out_ord=selected[out_idx], in_ord;\n            do{in_ord=rng()%1000;}while(sel_set.count(in_ord));\n            \n            int old_dist=current_dist;\n            vector<int> old_selected=selected;\n            \n            // Try swap\n            sel_set.erase(out_ord); sel_set.insert(in_ord);\n            selected[out_idx]=in_ord;\n            \n            build_route();\n            local_search();\n            \n            if(current_dist<old_dist || exp(-(current_dist-old_dist)/temp)>(double)rng()/rng.max()) {\n                if(current_dist<best_dist) save_best();\n            } else {\n                // Restore\n                sel_set.erase(in_ord); sel_set.insert(out_ord);\n                selected=old_selected;\n                build_route();\n            }\n            temp*=0.997;\n        }\n    }\n    \n    void output() {\n        // Load best and rebuild route\n        selected=best_selected;\n        build_route();\n        \n        // Validate\n        assert(selected.size()==50);\n        assert(route.size()==102);\n        \n        set<int> sel_set(selected.begin(),selected.end());\n        assert(sel_set.size()==50);\n        \n        cout<<50; for(int i:selected) cout<<\" \"<<i+1; cout<<\"\\n\";\n        cout<<route.size(); for(int loc:route){auto[x,y]=get_coords(loc);cout<<\" \"<<x<<\" \"<<y;} cout<<\"\\n\";\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    Solver s; \n    s.read_input(); \n    s.select_orders_greedy(); \n    s.build_route(); \n    s.local_search(); \n    s.run_sa();\n    s.output();\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent, rnk;\npublic:\n    UnionFind(int n) : parent(n), rnk(n, 0) {\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        if (rnk[px] < rnk[py]) swap(px, py);\n        parent[py] = px;\n        if (rnk[px] == rnk[py]) rnk[px]++;\n        return true;\n    }\n    \n    bool same(int x, int y) {\n        return find(x) == find(y);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400;\n    const int M = 1995;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    vector<int> u(M), v(M), d(M);\n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        double dx = (double)(x[u[i]] - x[v[i]]);\n        double dy = (double)(y[u[i]] - y[v[i]]);\n        d[i] = max(1, (int)round(sqrt(dx*dx + dy*dy)));\n    }\n    \n    UnionFind uf(N);\n    int need = N - 1;\n    \n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        int decision = 0;\n        \n        if (!uf.same(u[i], v[i])) {\n            double ratio = (double)l / d[i];\n            int rem = M - i - 1;\n            \n            // Progressive threshold: start selective, become less selective\n            // threshold ranges from 2.0 (early) to 3.0 (late)\n            double progress = (double)i / M;\n            double threshold = 2.0 + 1.0 * progress;\n            \n            // Safety: accept all when running critically low\n            if (rem <= need + 50) {\n                threshold = 3.0;\n            }\n            \n            if (ratio <= threshold) {\n                decision = 1;\n                uf.unite(u[i], v[i]);\n                need--;\n            }\n        }\n        \n        cout << decision << endl;\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <set>\n#include <tuple>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char WALL[] = {'u', 'd', 'l', 'r'};\nconst char MOVE[] = {'U', 'D', 'L', 'R'};\n\nint N, M;\nvector<tuple<int,int,int>> pets_data;\nvector<pair<int,int>> humans_data;\n\nstruct Solver {\n    vector<vector<bool>> wall;\n    vector<tuple<int,int,int>> pets;\n    vector<pair<int,int>> humans;\n    \n    void init() {\n        wall.assign(SIZE, vector<bool>(SIZE, false));\n        pets = pets_data;\n        humans = humans_data;\n    }\n    \n    bool ok(int x, int y) const { return x >= 0 && x < SIZE && y >= 0 && y < SIZE; }\n    \n    bool petAt(int x, int y) const {\n        for (auto& [px, py, pt] : pets) if (px == x && py == y) return true;\n        return false;\n    }\n    \n    bool humanAt(int x, int y) const {\n        for (auto& [hx, hy] : humans) if (hx == x && hy == y) return true;\n        return false;\n    }\n    \n    bool nearPet(int x, int y) const {\n        for (int d = 0; d < 4; d++) if (petAt(x + dx[d], y + dy[d])) return true;\n        return false;\n    }\n    \n    bool canBuild(int h, int d, const set<pair<int,int>>& pw) const {\n        int x = humans[h].first + dx[d];\n        int y = humans[h].second + dy[d];\n        return ok(x, y) && !wall[x][y] && !petAt(x, y) && !humanAt(x, y) && !nearPet(x, y) && !pw.count({x, y});\n    }\n    \n    bool canMove(int h, int d, const set<pair<int,int>>& pw) const {\n        int x = humans[h].first + dx[d];\n        int y = humans[h].second + dy[d];\n        return ok(x, y) && !wall[x][y] && !pw.count({x, y});\n    }\n    \n    pair<int, vector<vector<bool>>> getReach(int sx, int sy) const {\n        vector<vector<bool>> vis(SIZE, vector<bool>(SIZE, false));\n        queue<pair<int,int>> q;\n        q.push({sx, sy});\n        vis[sx][sy] = true;\n        int cnt = 0;\n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop();\n            cnt++;\n            for (int i = 0; i < 4; i++) {\n                int nx = cx + dx[i], ny = cy + dy[i];\n                if (ok(nx, ny) && !vis[nx][ny] && !wall[nx][ny]) {\n                    vis[nx][ny] = true;\n                    q.push({nx, ny});\n                }\n            }\n        }\n        return {cnt, vis};\n    }\n    \n    tuple<int, int, int> analyze(int h) const {\n        auto [area, vis] = getReach(humans[h].first, humans[h].second);\n        int inside = 0, bordering = 0;\n        for (auto& [px, py, pt] : pets) {\n            if (vis[px][py]) inside++;\n            else {\n                for (int d = 0; d < 4; d++) {\n                    if (ok(px + dx[d], py + dy[d]) && vis[px + dx[d]][py + dy[d]]) {\n                        bordering++;\n                        break;\n                    }\n                }\n            }\n        }\n        return {area, inside, bordering};\n    }\n    \n    double scoreState(int h) const {\n        auto [area, inside, bordering] = analyze(h);\n        if (inside > 0) return -1000 - inside; // Very bad to have pets inside\n        return (double)area / (SIZE * SIZE) - 0.01 * bordering;\n    }\n    \n    int minPetDist(int hx, int hy) const {\n        int mnd = SIZE * SIZE;\n        for (auto& [px, py, pt] : pets) mnd = min(mnd, abs(px - hx) + abs(py - hy));\n        return mnd;\n    }\n    \n    char decide(int h, const set<pair<int,int>>& pw) {\n        auto [area, inside, bordering] = analyze(h);\n        int hx = humans[h].first, hy = humans[h].second;\n        int mpd = minPetDist(hx, hy);\n        \n        double best = -1e9;\n        char bestA = '.';\n        int bestD = -1;\n        \n        // Try building walls - much higher priority when pets are far\n        for (int d = 0; d < 4; d++) {\n            if (canBuild(h, d, pw)) {\n                int wx = hx + dx[d], wy = hy + dy[d];\n                wall[wx][wy] = true;\n                double s = scoreState(h);\n                auto [na, ni, nb] = analyze(h);\n                wall[wx][wy] = false;\n                \n                // Strong bonus for blocking bordering pets\n                if (nb < bordering) s += 0.05 * (bordering - nb);\n                \n                // Strong bonus for keeping pets out\n                if (ni == 0 && inside == 0) s += 0.02;\n                \n                if (s > best) { best = s; bestA = WALL[d]; bestD = d; }\n            }\n        }\n        \n        // Try moving\n        for (int d = 0; d < 4; d++) {\n            if (canMove(h, d, pw)) {\n                auto old = humans[h];\n                humans[h].first += dx[d]; humans[h].second += dy[d];\n                double s = scoreState(h);\n                int newMpd = minPetDist(humans[h].first, humans[h].second);\n                humans[h] = old;\n                \n                // If pets inside, try to move away from them\n                if (inside > 0) {\n                    if (newMpd > mpd) s += 0.1;\n                } else {\n                    // If no pets inside, stay close to guard\n                    if (mpd < 4 && newMpd > mpd) s += 0.02;\n                }\n                \n                if (s > best) { best = s; bestA = MOVE[d]; bestD = d; }\n            }\n        }\n        \n        return bestA;\n    }\n    \n    void apply(int h, char a, int d) {\n        if (a >= 'a' && a <= 'z') wall[humans[h].first + dx[d]][humans[h].second + dy[d]] = true;\n        else if (a != '.') { humans[h].first += dx[d]; humans[h].second += dy[d]; }\n    }\n    \n    void readPets() {\n        for (int i = 0; i < N; i++) {\n            string m; cin >> m;\n            auto& [px, py, pt] = pets[i];\n            for (char c : m) {\n                if (c == 'U') px--; else if (c == 'D') px++;\n                else if (c == 'L') py--; else if (c == 'R') py++;\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N; pets_data.resize(N);\n    for (int i = 0; i < N; i++) { int x, y, t; cin >> x >> y >> t; pets_data[i] = {x - 1, y - 1, t}; }\n    cin >> M; humans_data.resize(M);\n    for (int i = 0; i < M; i++) { int x, y; cin >> x >> y; humans_data[i] = {x - 1, y - 1}; }\n    \n    Solver sol; sol.init();\n    \n    for (int t = 0; t < 300; t++) {\n        string act(M, '.'); set<pair<int,int>> pw; vector<int> dirs(M, -1);\n        \n        for (int h = 0; h < M; h++) {\n            char a = sol.decide(h, pw); act[h] = a;\n            for (int d = 0; d < 4; d++) if (a == WALL[d] || a == MOVE[d]) { dirs[h] = d; break; }\n            if (dirs[h] >= 0 && act[h] >= 'a') pw.insert({sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]});\n        }\n        \n        set<pair<int,int>> builds;\n        for (int h = 0; h < M; h++)\n            if (dirs[h] >= 0 && act[h] >= 'a' && act[h] <= 'z')\n                builds.insert({sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]});\n        \n        for (int h = 0; h < M; h++) {\n            if (dirs[h] >= 0 && act[h] >= 'A' && act[h] <= 'Z') {\n                pair<int,int> target = {sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]};\n                if (builds.count(target)) { act[h] = '.'; dirs[h] = -1; }\n            }\n        }\n        \n        for (int h = 0; h < M; h++) if (dirs[h] >= 0) sol.apply(h, act[h], dirs[h]);\n        cout << act << endl; cout.flush();\n        sol.readPets();\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj, ti, tj;\ndouble p, q;\nvector<string> h(20), v(19);\nvector<vector<int>> dist_to_goal;\nconstexpr int di[] = {-1, 1, 0, 0};\nconstexpr int dj[] = {0, 0, -1, 1};\nconstexpr char dirs[] = \"UDLR\";\nmt19937 rng(42);\n\ninline bool can_move(int i, int j, int d) {\n    if (d == 0) return i > 0 && v[i-1][j] == '0';\n    if (d == 1) return i < 19 && v[i][j] == '0';\n    if (d == 2) return j > 0 && h[i][j-1] == '0';\n    return j < 19 && h[i][j] == '0';\n}\n\nvoid compute_dist() {\n    dist_to_goal.assign(20, vector<int>(20, 1000));\n    queue<pair<int,int>> qq;\n    qq.push({ti, tj});\n    dist_to_goal[ti][tj] = 0;\n    while (!qq.empty()) {\n        auto [i, j] = qq.front(); qq.pop();\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if (dist_to_goal[ni][nj] > dist_to_goal[i][j] + 1) {\n                dist_to_goal[ni][nj] = dist_to_goal[i][j] + 1;\n                qq.push({ni, nj});\n            }\n        }\n    }\n}\n\nstring bfs_path() {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<int>> pm(20, vector<int>(20, -1));\n    queue<pair<int,int>> qq;\n    qq.push({si, sj});\n    dist[si][sj] = 0;\n    while (!qq.empty()) {\n        auto [i, j] = qq.front(); qq.pop();\n        if (i == ti && j == tj) break;\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if (dist[ni][nj] < 0) {\n                dist[ni][nj] = dist[i][j] + 1;\n                pm[ni][nj] = d;\n                qq.push({ni, nj});\n            }\n        }\n    }\n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int d = pm[ci][cj];\n        path = dirs[d] + path;\n        ci -= di[d]; cj -= dj[d];\n    }\n    return path;\n}\n\ndouble simulate(const string& s) {\n    vector<double> prob(400, 0), np(400);\n    prob[si * 20 + sj] = 1.0;\n    double total = 0, reached = 0;\n    int goal = ti * 20 + tj;\n    \n    for (int t = 0; t < (int)s.size(); t++) {\n        fill(np.begin(), np.end(), 0);\n        int mv = string(\"UDLR\").find(s[t]);\n        \n        for (int idx = 0; idx < 400; idx++) {\n            if (prob[idx] < 1e-16) continue;\n            int i = idx / 20, j = idx % 20;\n            np[idx] += p * prob[idx];\n            int ni = i, nj = j;\n            if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n            np[ni * 20 + nj] += q * prob[idx];\n        }\n        swap(prob, np);\n        double nr = prob[goal] * (1 - reached);\n        total += nr * (401 - t - 1);\n        reached += nr;\n        prob[goal] = 0;\n    }\n    return total;\n}\n\nstring greedy_construct() {\n    vector<float> prob(400, 0), np(400);\n    prob[si * 20 + sj] = 1.0f;\n    string result;\n    int goal = ti * 20 + tj;\n    \n    for (int t = 0; t < 200; t++) {\n        double best_score = -1e18; int bm = 0;\n        \n        for (int mv = 0; mv < 4; mv++) {\n            fill(np.begin(), np.end(), 0);\n            float nr = 0;\n            \n            for (int idx = 0; idx < 400; idx++) {\n                if (prob[idx] < 1e-10f) continue;\n                int i = idx / 20, j = idx % 20;\n                np[idx] += p * prob[idx];\n                int ni = i, nj = j;\n                if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n                int nidx = ni * 20 + nj;\n                if (nidx == goal) nr += q * prob[idx];\n                else np[nidx] += q * prob[idx];\n            }\n            \n            double score = nr * (401 - t - 1);\n            for (int idx = 0; idx < 400; idx++) {\n                if (np[idx] < 1e-10f) continue;\n                int i = idx / 20, j = idx % 20;\n                score += np[idx] * (100 - dist_to_goal[i][j]) * 0.5;\n            }\n            \n            if (score > best_score) { best_score = score; bm = mv; }\n        }\n        result += dirs[bm];\n        \n        fill(np.begin(), np.end(), 0);\n        for (int idx = 0; idx < 400; idx++) {\n            if (prob[idx] < 1e-10f) continue;\n            int i = idx / 20, j = idx % 20;\n            np[idx] += p * prob[idx];\n            int ni = i, nj = j;\n            if (can_move(i, j, bm)) { ni += di[bm]; nj += dj[bm]; }\n            np[ni * 20 + nj] += q * prob[idx];\n        }\n        swap(prob, np);\n        prob[goal] = 0;\n    }\n    return result;\n}\n\nstring beam_search(int width) {\n    struct State {\n        vector<uint8_t> s;\n        vector<float> prob;\n        double score;\n    };\n    \n    vector<State> beam;\n    beam.push_back({{}, vector<float>(400, 0), 0});\n    beam[0].prob[si * 20 + sj] = 1.0f;\n    int goal = ti * 20 + tj;\n    \n    for (int t = 0; t < 200; t++) {\n        vector<State> next;\n        next.reserve(beam.size() * 4);\n        \n        for (auto& st : beam) {\n            for (int mv = 0; mv < 4; mv++) {\n                State ns;\n                ns.s = st.s;\n                ns.s.push_back(mv);\n                ns.prob.assign(400, 0);\n                ns.score = st.score;\n                \n                float nr = 0;\n                for (int idx = 0; idx < 400; idx++) {\n                    if (st.prob[idx] < 1e-12f) continue;\n                    int i = idx / 20, j = idx % 20;\n                    ns.prob[idx] += p * st.prob[idx];\n                    int ni = i, nj = j;\n                    if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n                    int nidx = ni * 20 + nj;\n                    if (nidx == goal) nr += q * st.prob[idx];\n                    else ns.prob[nidx] += q * st.prob[idx];\n                }\n                ns.score += nr * (401 - t - 1);\n                ns.prob[goal] = 0;\n                next.push_back(move(ns));\n            }\n        }\n        \n        if ((int)next.size() > width) {\n            partial_sort(next.begin(), next.begin() + width, next.end(),\n                [](const State& a, const State& b) { return a.score > b.score; });\n            next.resize(width);\n        }\n        beam = move(next);\n    }\n    \n    string result;\n    for (auto c : beam[0].s) result += dirs[c];\n    return result;\n}\n\nstring sa_optimize(string cur, double time_limit) {\n    double cur_score = simulate(cur);\n    string best = cur;\n    double best_score = cur_score;\n    double temp = cur_score * 0.1;\n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    \n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < time_limit) {\n        string ns = cur;\n        \n        // Focused mutations\n        int op = rng() % 10;\n        if (op < 4 && !ns.empty()) {\n            int pos = rng() % ns.size();\n            ns[pos] = dirs[rng() % 4];\n        } else if (op < 6 && (int)ns.size() < 200) {\n            int pos = rng() % (ns.size() + 1);\n            ns.insert(ns.begin() + pos, dirs[rng() % 4]);\n        } else if (op < 8 && !ns.empty()) {\n            int pos = rng() % ns.size();\n            ns.erase(pos, 1);\n        } else if (ns.size() >= 2) {\n            int pos = rng() % (ns.size() - 1);\n            swap(ns[pos], ns[pos + 1]);\n        }\n        \n        double ns_score = simulate(ns);\n        double delta = ns_score - cur_score;\n        \n        if (delta > 0 || (temp > 1e-6 && exp(delta / temp) > (double)rng() / rng.max())) {\n            cur = ns;\n            cur_score = ns_score;\n            if (cur_score > best_score) {\n                best = cur;\n                best_score = cur_score;\n            }\n        }\n        temp *= 0.9995;\n        iter++;\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> si >> sj >> ti >> tj >> p;\n    q = 1 - p;\n    for (int i = 0; i < 20; i++) cin >> h[i];\n    for (int i = 0; i < 19; i++) cin >> v[i];\n    compute_dist();\n    string path = bfs_path();\n    int path_len = path.size();\n    \n    string best; double bsc = -1;\n    auto try_s = [&](const string& s) { \n        if (s.empty() || s.size() > 200) return;\n        double sc = simulate(s); \n        if (sc > bsc) { bsc = sc; best = s; } \n    };\n    \n    // Adaptive repetition count\n    int rep_count = (int)ceil(log(0.01) / log(p)); // Expected turns to have 99% chance of executing once\n    rep_count = max(1, min(rep_count, 15));\n    \n    // Strategy 1: Repeat whole path\n    { string s; while ((int)s.size() + path_len <= 200) s += path; try_s(s); }\n    \n    // Strategy 2: Various repetition patterns\n    for (int r = max(1, rep_count - 3); r <= min(12, rep_count + 3); r++) {\n        string rb;\n        for (char c : path) rb += string(r, c);\n        string s; while ((int)s.size() + (int)rb.size() <= 200) s += rb;\n        if (!s.empty()) try_s(s);\n    }\n    \n    // Strategy 3: Direction-weighted repetition\n    {\n        string s;\n        for (int rep = 0; rep < 200; ) {\n            for (char c : path) {\n                int weight = 2;\n                if (p > 0.3) weight = 3;\n                if (p > 0.4) weight = 4;\n                for (int i = 0; i < weight && rep < 200; i++, rep++) s += c;\n            }\n        }\n        try_s(s);\n    }\n    \n    // Strategy 4: Greedy\n    try_s(greedy_construct());\n    \n    // Strategy 5: Beam search\n    try_s(beam_search(60));\n    try_s(beam_search(100));\n    \n    // Strategy 6: Multi-restart SA\n    vector<string> starts = {best, greedy_construct(), beam_search(80)};\n    for (int i = 0; i < 3; i++) {\n        string s;\n        for (int j = 0; j < 200 && s.size() + path_len <= 200; j++)\n            for (char c : path) if (s.size() < 200) s += c;\n        starts.push_back(s);\n    }\n    \n    double time_per_sa = 0.15;\n    for (auto& start : starts) {\n        try_s(sa_optimize(start, time_per_sa));\n    }\n    \n    // Final refinement on best\n    best = sa_optimize(best, 0.2);\n    \n    cout << best << endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint tiles[N][N], rotations[N][N], best_rotations[N][N];\nconstexpr int di[] = {0, -1, 0, 1}, dj[] = {-1, 0, 1, 0};\nconstexpr int to[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}};\nconstexpr int rot_table[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\npair<long long, long long> compute_loops() {\n    static bool visited[N][N][4];\n    memset(visited, 0, sizeof(visited));\n    long long max1 = 0, max2 = 0;\n    \n    for (int si = 0; si < N; si++) {\n        for (int sj = 0; sj < N; sj++) {\n            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                \n                while (true) {\n                    if (visited[i][j][d]) { len = 0; break; }\n                    visited[i][j][d] = true;\n                    int t = rot_table[tiles[i][j]][rotations[i][j]];\n                    int d2 = to[t][d];\n                    if (d2 == -1) { len = 0; break; }\n                    i += di[d2]; j += dj[d2];\n                    if ((unsigned)i >= N || (unsigned)j >= N) { len = 0; break; }\n                    d = (d2 + 2) & 3; len++;\n                    if (i == si && j == sj && d == sd) break;\n                }\n                \n                if (len > max1) { max2 = max1; max1 = len; }\n                else if (len > max2) max2 = len;\n            }\n        }\n    }\n    return {max1, max2};\n}\n\nlong long compute_score(long long l1, long long l2) {\n    return l2 > 0 ? l1 * l2 : l1;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) tiles[i][j] = s[j] - '0';\n    }\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> rand01(0, 1);\n    \n    long long best_score = 0;\n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(1950);\n    \n    while (chrono::steady_clock::now() < deadline) {\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) rotations[i][j] = rng() % 4;\n        \n        auto [cur_l1, cur_l2] = compute_loops();\n        long long cur_score = compute_score(cur_l1, cur_l2);\n        \n        double temp = 10000.0;\n        \n        while (chrono::steady_clock::now() < deadline && temp > 0.1) {\n            int ri = rng() % N, rj = rng() % N;\n            int old = rotations[ri][rj];\n            rotations[ri][rj] = rng() % 4;\n            \n            auto [new_l1, new_l2] = compute_loops();\n            long long new_score = compute_score(new_l1, new_l2);\n            \n            if (new_score >= cur_score || rand01(rng) < exp((double)(new_score - cur_score) / temp)) {\n                cur_score = new_score;\n                cur_l1 = new_l1; cur_l2 = new_l2;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    memcpy(best_rotations, rotations, sizeof(rotations));\n                }\n            } else {\n                rotations[ri][rj] = old;\n            }\n            \n            temp *= 0.9999;\n        }\n    }\n    \n    string result;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) result += char('0' + best_rotations[i][j]);\n    cout << result << '\\n';\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> board;\nint er, ec;\n\nconst int DR[] = {0, -1, 0, 1};\nconst int DC[] = {-1, 0, 1, 0};\nconst char DCS[] = \"LURD\";\n\ninline int hval(char c) { return c >= 'a' ? c - 'a' + 10 : c - '0'; }\ninline bool ib(int r, int c) { return r >= 0 && r < N && c >= 0 && c < N; }\n\nint evalTree() {\n    vector<int> comp(N*N, -1), compEdges(N*N, 0), compSize(N*N, 0);\n    int numComp = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == '0') continue;\n            int idx = i * N + j;\n            if (comp[idx] != -1) continue;\n            \n            queue<pair<int,int>> q;\n            q.push({i,j});\n            comp[idx] = numComp;\n            \n            while (!q.empty()) {\n                auto [r,c] = q.front(); q.pop();\n                compSize[numComp]++;\n                int v = hval(board[r][c]);\n                \n                auto check = [&](int nr, int nc, int fb, int tb) {\n                    if (!ib(nr,nc) || board[nr][nc] == '0') return;\n                    int nv = hval(board[nr][nc]);\n                    if ((v & fb) && (nv & tb)) {\n                        compEdges[numComp]++;\n                        int nidx = nr * N + nc;\n                        if (comp[nidx] == -1) {\n                            comp[nidx] = numComp;\n                            q.push({nr,nc});\n                        }\n                    }\n                };\n                check(r,c-1,1,4); check(r-1,c,2,8); check(r,c+1,4,1); check(r+1,c,8,2);\n            }\n            numComp++;\n        }\n    }\n    \n    int best = 0;\n    for (int c = 0; c < numComp; c++) {\n        if (compEdges[c] / 2 == compSize[c] - 1)\n            best = max(best, compSize[c]);\n    }\n    return best;\n}\n\nint countEdges() {\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] == '0') continue;\n            int v = hval(board[i][j]);\n            if ((v & 4) && j+1 < N && board[i][j+1] != '0' && (hval(board[i][j+1]) & 1)) cnt++;\n            if ((v & 8) && i+1 < N && board[i+1][j] != '0' && (hval(board[i+1][j]) & 2)) cnt++;\n        }\n    }\n    return cnt;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> T;\n    board.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n        for (int j = 0; j < N; j++)\n            if (board[i][j] == '0') { er = i; ec = j; }\n    }\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> prob(0.0, 1.0);\n    \n    vector<string> bestBoard = board;\n    int bestEr = er, bestEc = ec;\n    int bestTree = evalTree();\n    string bestResult;\n    \n    string result;\n    int lastDir = -1;\n    int curEdges = countEdges();\n    int noImprove = 0;\n    \n    double startTime = clock() / (double)CLOCKS_PER_SEC;\n    double timeLimit = 2.9;\n    \n    for (int step = 0; step < T && (int)result.size() < T; step++) {\n        double elapsed = clock() / (double)CLOCKS_PER_SEC;\n        if (elapsed > timeLimit) break;\n        \n        vector<tuple<int,int,int>> moves;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = er + DR[d], nc = ec + DC[d];\n            if (!ib(nr, nc)) continue;\n            \n            swap(board[er][ec], board[nr][nc]);\n            int edges = countEdges();\n            swap(board[er][ec], board[nr][nc]);\n            \n            int penalty = (d == (lastDir + 2) % 4) ? 3 : 0;\n            moves.push_back({d, edges - penalty, nr * N + nc});\n        }\n        \n        if (moves.empty()) break;\n        \n        sort(moves.begin(), moves.end(), [](auto& a, auto& b) { return get<1>(a) > get<1>(b); });\n        \n        int d = get<0>(moves[0]);\n        int newEdges = get<1>(moves[0]);\n        int delta = newEdges - curEdges;\n        \n        double temp = 8.0 * max(0.1, 1.0 - (double)step / T);\n        \n        if (delta < 0 && prob(rng) > exp(delta / temp)) {\n            if (moves.size() > 1) {\n                int idx = 1 + rng() % (moves.size() - 1);\n                d = get<0>(moves[idx]);\n                newEdges = get<1>(moves[idx]);\n            }\n        }\n        \n        double expP = min(0.25, 0.25 * temp / 8.0);\n        if (prob(rng) < expP && moves.size() > 1) {\n            int idx = 1 + rng() % (moves.size() - 1);\n            d = get<0>(moves[idx]);\n            newEdges = get<1>(moves[idx]);\n        }\n        \n        int nr = er + DR[d], nc = ec + DC[d];\n        swap(board[er][ec], board[nr][nc]);\n        er = nr; ec = nc;\n        curEdges = newEdges;\n        result += DCS[d];\n        lastDir = d;\n        \n        noImprove++;\n        \n        if (step % 6 == 5) {\n            int treeSize = evalTree();\n            if (treeSize > bestTree) {\n                bestTree = treeSize;\n                bestBoard = board;\n                bestEr = er;\n                bestEc = ec;\n                bestResult = result;\n                noImprove = 0;\n            }\n            if (treeSize == N*N - 1) { bestResult = result; break; }\n            \n            if (noImprove > 30) {\n                board = bestBoard;\n                er = bestEr;\n                ec = bestEc;\n                result = bestResult;\n                curEdges = countEdges();\n                lastDir = -1;\n                noImprove = 0;\n                rng.seed(rng());\n            }\n        }\n    }\n    \n    if (bestResult.empty()) bestResult = result;\n    cout << bestResult << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\ntypedef pair<ll, ll> PLL;\n\nconst ll LIM = 1000000000LL;\n\nll cross(PLL a, PLL b) { return a.first * b.second - a.second * b.first; }\n\nint side(PLL p1, PLL p2, PLL q) {\n    PLL d = {p2.first - p1.first, p2.second - p1.second};\n    PLL e = {q.first - p1.first, q.second - p1.second};\n    ll c = cross(d, e);\n    return (c > 0) ? 1 : (c < 0) ? -1 : 0;\n}\n\nint N, K;\nint a[11];\nvector<PLL> S;\nint maxScore;\n\nstruct VectorHash {\n    size_t operator()(const vector<int>& v) const {\n        size_t h = 0;\n        for (int x : v) h = h * 3 + (x + 1);\n        return h;\n    }\n};\n\nint computeScore(const vector<pair<PLL, PLL>>& lines) {\n    int L = lines.size();\n    unordered_map<vector<int>, int, VectorHash> cells;\n    cells.reserve(N * 2);\n    vector<int> sides;\n    for (const auto& s : S) {\n        sides.clear();\n        bool cut = false;\n        for (int i = 0; i < L; i++) {\n            int sd = side(lines[i].first, lines[i].second, s);\n            if (sd == 0) { cut = true; break; }\n            sides.push_back(sd);\n        }\n        if (!cut) cells[sides]++;\n    }\n    int b[11] = {0};\n    for (auto& p : cells) if (p.second >= 1 && p.second <= 10) b[p.second]++;\n    int score = 0;\n    for (int d = 1; d <= 10; d++) score += min(a[d], b[d]);\n    return score;\n}\n\nll clampCoord(ll x) { return max(-LIM, min(LIM, x)); }\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    S.resize(N);\n    for (int i = 0; i < N; i++) cin >> S[i].first >> S[i].second;\n    maxScore = accumulate(a + 1, a + 11, 0);\n    \n    mt19937 rng(42);\n    uniform_int_distribution<ll> coordDist(-LIM, LIM);\n    auto randCoord = [&]() { return coordDist(rng); };\n    \n    vector<pair<PLL, PLL>> bestCuts;\n    int bestScore = 0;\n    clock_t start = clock();\n    const double timeLimit = 2.5;\n    \n    while ((double)(clock() - start) / CLOCKS_PER_SEC < timeLimit && bestScore < maxScore) {\n        vector<pair<PLL, PLL>> cuts;\n        int curScore = 0;\n        \n        for (int i = 0; i < K; i++) {\n            if ((double)(clock() - start) / CLOCKS_PER_SEC >= timeLimit) break;\n            \n            pair<PLL, PLL> bestLine;\n            int bestNew = curScore; bool found = false;\n            \n            for (int t = 0; t < 50; t++) {\n                PLL p1, p2;\n                if (N >= 2 && (rng() & 3)) {\n                    int i1 = rng() % N, i2 = rng() % N;\n                    if (i1 == i2) continue;\n                    ll mx = S[i1].first + S[i2].first;\n                    ll my = S[i1].second + S[i2].second;\n                    ll dx = S[i2].first - S[i1].first;\n                    ll dy = S[i2].second - S[i1].second;\n                    p1 = {clampCoord(mx + dy), clampCoord(my - dx)};\n                    p2 = {clampCoord(mx - dy), clampCoord(my + dx)};\n                } else {\n                    p1 = {randCoord(), randCoord()};\n                    p2 = {randCoord(), randCoord()};\n                }\n                if (p1 == p2) continue;\n                \n                cuts.push_back({p1, p2});\n                int sc = computeScore(cuts);\n                cuts.pop_back();\n                if (sc > bestNew) { bestNew = sc; bestLine = {p1, p2}; found = true; }\n            }\n            if (found) { cuts.push_back(bestLine); curScore = bestNew; }\n            if (curScore > bestScore) { bestScore = curScore; bestCuts = cuts; }\n        }\n        \n        for (int ls = 0; ls < 500; ls++) {\n            if ((double)(clock() - start) / CLOCKS_PER_SEC >= timeLimit) break;\n            if (cuts.empty()) break;\n            int idx = rng() % cuts.size(); auto old = cuts[idx];\n            PLL p1, p2;\n            if (N >= 2 && (rng() & 3)) {\n                int i1 = rng() % N, i2 = rng() % N;\n                if (i1 == i2) continue;\n                ll mx = S[i1].first + S[i2].first;\n                ll my = S[i1].second + S[i2].second;\n                ll dx = S[i2].first - S[i1].first;\n                ll dy = S[i2].second - S[i1].second;\n                p1 = {clampCoord(mx + dy), clampCoord(my - dx)};\n                p2 = {clampCoord(mx - dy), clampCoord(my + dx)};\n            } else {\n                p1 = {randCoord(), randCoord()};\n                p2 = {randCoord(), randCoord()};\n            }\n            if (p1 == p2) continue;\n            \n            cuts[idx] = {p1, p2};\n            int sc = computeScore(cuts);\n            if (sc >= curScore) {\n                curScore = sc;\n                if (curScore > bestScore) { bestScore = curScore; bestCuts = cuts; }\n            } else {\n                cuts[idx] = old;\n            }\n        }\n    }\n    \n    cout << bestCuts.size() << \"\\n\";\n    for (auto& l : bestCuts) {\n        cout << l.first.first << \" \" << l.first.second << \" \" \n             << l.second.first << \" \" << l.second.second << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble C;\nvector<vector<bool>> dot;\nset<array<int, 4>> used_edges;\nvector<array<int, 8>> ops;\nchrono::steady_clock::time_point T0;\nmt19937 rng(42);\n\ndouble elapsed() { return chrono::duration<double>(chrono::steady_clock::now() - T0).count(); }\nint wt(int x, int y) { return (int)((x-C)*(x-C) + (y-C)*(y-C) + 1); }\nbool inB(int x, int y) { return x >= 0 && x < N && y >= 0 && y < N; }\n\nint myGcd(int a, int b) { a=abs(a); b=abs(b); while(b){a%=b; swap(a,b);} return a; }\n\narray<int,4> normE(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) { swap(x1,x2); swap(y1,y2); }\n    return {x1, y1, x2, y2};\n}\n\nbool pathClear(int x1, int y1, int x2, int y2) {\n    int dx = x2-x1, dy = y2-y1, g = myGcd(dx, dy);\n    if (g <= 1) return true;\n    int sx = dx/g, sy = dy/g;\n    for (int i = 1; i < g; i++) if (dot[x1+i*sx][y1+i*sy]) return false;\n    return true;\n}\n\nbool canAddEdge(int x1, int y1, int x2, int y2) {\n    int dx = x2-x1, dy = y2-y1, g = myGcd(dx, dy);\n    if (g == 0) return true;\n    int sx = dx/g, sy = dy/g;\n    for (int i = 0; i < g; i++) {\n        if (used_edges.count(normE(x1+i*sx, y1+i*sy, x1+(i+1)*sx, y1+(i+1)*sy))) return false;\n    }\n    return true;\n}\n\nvoid addEdge(int x1, int y1, int x2, int y2) {\n    int dx = x2-x1, dy = y2-y1, g = myGcd(dx, dy);\n    if (g == 0) return;\n    int sx = dx/g, sy = dy/g;\n    for (int i = 0; i < g; i++) used_edges.insert(normE(x1+i*sx, y1+i*sy, x1+(i+1)*sx, y1+(i+1)*sy));\n}\n\nbool tryRectDirect(int ex, int ey, int x2, int y2, int x3, int y3, int x4, int y4) {\n    int cx[] = {ex, x2, x3, x4}, cy[] = {ey, y2, y3, y4};\n    if (dot[ex][ey]) return false;\n    for (int i = 1; i < 4; i++) if (!dot[cx[i]][cy[i]]) return false;\n    for (int i = 0; i < 4; i++) {\n        int dx = cx[(i+1)%4]-cx[i], dy = cy[(i+1)%4]-cy[i];\n        if (dx==0 && dy==0) return false;\n        if (dx!=0 && dy!=0 && abs(dx)!=abs(dy)) return false;\n    }\n    for (int i = 0; i < 4; i++) {\n        int dx1=cx[(i+1)%4]-cx[i], dy1=cy[(i+1)%4]-cy[i];\n        int dx2=cx[(i+2)%4]-cx[(i+1)%4], dy2=cy[(i+2)%4]-cy[(i+1)%4];\n        if (dx1*dx2 + dy1*dy2 != 0) return false;\n    }\n    for (int i = 0; i < 4; i++) if (!pathClear(cx[i],cy[i],cx[(i+1)%4],cy[(i+1)%4])) return false;\n    for (int i = 0; i < 4; i++) if (!canAddEdge(cx[i],cy[i],cx[(i+1)%4],cy[(i+1)%4])) return false;\n    dot[ex][ey] = true;\n    for (int i = 0; i < 4; i++) addEdge(cx[i],cy[i],cx[(i+1)%4],cy[(i+1)%4]);\n    ops.push_back({ex,ey,x2,y2,x3,y3,x4,y4});\n    return true;\n}\n\nvector<array<int,8>> solve(vector<vector<bool>>& initDot, bool randomize) {\n    dot = initDot;\n    used_edges.clear();\n    ops.clear();\n    \n    vector<vector<int>> byR(N), byC(N), byDP(2*N), byDM(2*N);\n    for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (dot[x][y]) {\n        byR[y].push_back(x); byC[x].push_back(y);\n        byDP[x+y].push_back(x); byDM[x-y+N-1].push_back(x);\n    }\n    \n    while (elapsed() < 4.5) {\n        vector<pair<int,int>> E;\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (!dot[x][y]) E.push_back({x,y});\n        if (randomize) shuffle(E.begin(), E.end(), rng);\n        else sort(E.begin(), E.end(), [](auto& a, auto& b){ return wt(a.first,a.second) > wt(b.first,b.second); });\n        \n        bool found = false;\n        for (auto& [nx,ny] : E) {\n            // Axis-aligned rectangles\n            for (int x2 : byR[ny]) { if (x2 == nx) continue;\n                for (int y3 : byC[nx]) { if (y3 == ny) continue;\n                    if (dot[x2][y3] && tryRectDirect(nx, ny, x2, ny, x2, y3, nx, y3)) {\n                        byR[ny].push_back(nx); byC[nx].push_back(ny);\n                        byDP[nx+ny].push_back(nx); byDM[nx-ny+N-1].push_back(nx);\n                        found = true; goto next_iter;\n                    }\n                }\n            }\n            // 45-degree rectangles\n            int ds = nx + ny, dm = nx - ny + N - 1;\n            for (int x2 : byDM[dm]) { int y2 = x2-(nx-ny); if (x2==nx) continue;\n                for (int x4 : byDP[ds]) { int y4 = ds-x4; if (x4==nx) continue;\n                    int x3 = x2+x4-nx, y3 = y2+y4-ny;\n                    if (inB(x3,y3) && dot[x3][y3] && tryRectDirect(nx, ny, x2, y2, x3, y3, x4, y4)) {\n                        byR[ny].push_back(nx); byC[nx].push_back(ny);\n                        byDP[nx+ny].push_back(nx); byDM[nx-ny+N-1].push_back(nx);\n                        found = true; goto next_iter;\n                    }\n                }\n            }\n        }\n        next_iter: if (!found) break;\n    }\n    return ops;\n}\n\nint calcScore() {\n    int s = 0;\n    for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (dot[x][y]) s += wt(x,y);\n    return s;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    T0 = chrono::steady_clock::now();\n    cin >> N >> M; C = (N-1)/2.0;\n    vector<vector<bool>> initDot(N, vector<bool>(N, false));\n    for (int i = 0; i < M; i++) { int x,y; cin >> x >> y; initDot[x][y] = true; }\n    \n    auto bestOps = solve(initDot, false);\n    int bestScore = calcScore();\n    \n    while (elapsed() < 4.4) {\n        auto curOps = solve(initDot, true);\n        int curScore = calcScore();\n        if (curScore > bestScore) {\n            bestScore = curScore;\n            bestOps = curOps;\n        }\n    }\n    \n    cout << bestOps.size() << \"\\n\";\n    for (auto& o : bestOps) { for (int i = 0; i < 8; i++) cout << o[i] << \" \\n\"[i==7]; }\n    return 0;\n}","ahc015":"#include <cstdio>\n#include <cstring>\n\nint G[10][10], F[100];\n\nvoid tilt(int g[][10], int d) {\n    int n[10][10] = {};\n    if (d == 0) for (int c = 0; c < 10; c++) { int w = 0; for (int r = 0; r < 10; r++) if (g[r][c]) n[w++][c] = g[r][c]; }\n    else if (d == 1) for (int c = 0; c < 10; c++) { int w = 9; for (int r = 9; r >= 0; r--) if (g[r][c]) n[w--][c] = g[r][c]; }\n    else if (d == 2) for (int r = 0; r < 10; r++) { int w = 0; for (int c = 0; c < 10; c++) if (g[r][c]) n[r][w++] = g[r][c]; }\n    else for (int r = 0; r < 10; r++) { int w = 9; for (int c = 9; c >= 0; c--) if (g[r][c]) n[r][w--] = g[r][c]; }\n    memcpy(g, n, 400);\n}\n\nlong long calc(int g[][10]) {\n    int v[10][10] = {};\n    long long s = 0;\n    for (int r = 0; r < 10; r++) for (int c = 0; c < 10; c++) if (g[r][c] && !v[r][c]) {\n        int q[100], h = 0, t = 0, sz = 0, f = g[r][c];\n        q[t++] = r*10+c; v[r][c] = 1;\n        while (h < t) { \n            int cr = q[h]/10, cc = q[h]%10; h++; sz++;\n            if (cr > 0 && !v[cr-1][cc] && g[cr-1][cc] == f) { v[cr-1][cc] = 1; q[t++] = (cr-1)*10+cc; }\n            if (cr < 9 && !v[cr+1][cc] && g[cr+1][cc] == f) { v[cr+1][cc] = 1; q[t++] = (cr+1)*10+cc; }\n            if (cc > 0 && !v[cr][cc-1] && g[cr][cc-1] == f) { v[cr][cc-1] = 1; q[t++] = cr*10+cc-1; }\n            if (cc < 9 && !v[cr][cc+1] && g[cr][cc+1] == f) { v[cr][cc+1] = 1; q[t++] = cr*10+cc+1; }\n        }\n        s += (long long)sz*sz;\n    }\n    return s;\n}\n\nlong long adjacency(int g[][10]) {\n    long long adj = 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        if (r > 0 && g[r-1][c] == f) adj += 3;\n        if (c > 0 && g[r][c-1] == f) adj += 3;\n    }\n    return adj;\n}\n\nlong long evaluate(int g[][10], int upcoming[], int count) {\n    long long score = calc(g) * 1000;\n    score += adjacency(g) * 10;\n    \n    for (int i = 0; i < count && i < 10; i++) {\n        int f = upcoming[i];\n        int weight = 10 - i;\n        for (int r = 0; r < 10; r++) for (int c = 0; c < 10; c++) if (g[r][c] == f) {\n            if (r > 0 && !g[r-1][c]) score += weight;\n            if (r < 9 && !g[r+1][c]) score += weight;\n            if (c > 0 && !g[r][c-1]) score += weight;\n            if (c < 9 && !g[r][c+1]) score += weight;\n        }\n    }\n    return score;\n}\n\nint main() {\n    for (int i = 0; i < 100; i++) scanf(\"%d\", &F[i]);\n    \n    for (int t = 0; t < 100; t++) {\n        int p; scanf(\"%d\", &p);\n        int cnt = 0;\n        for (int i = 0; i < 100; i++) {\n            if (!G[i/10][i%10] && ++cnt == p) { G[i/10][i%10] = F[t]; break; }\n        }\n        \n        long long best = -1; int bd = 0;\n        for (int d = 0; d < 4; d++) {\n            int tmp[10][10]; memcpy(tmp, G, 400);\n            tilt(tmp, d);\n            long long sc = evaluate(tmp, F + t + 1, 100 - t - 1);\n            if (sc > best) { best = sc; bd = d; }\n        }\n        \n        tilt(G, bd);\n        printf(\"%c\\n\", \"FBLR\"[bd]);\n        fflush(stdout);\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint M, N, total_edges;\ndouble eps;\nvector<string> G;\nvector<int> edge_counts;\nvector<vector<int>> deg_seqs;\nvector<long long> tri_counts;\n\nint idx(int i, int j) {\n    if (i > j) swap(i, j);\n    return i * (2 * N - i - 1) / 2 + (j - i - 1);\n}\n\nlong long count_triangles(const string& g) {\n    long long cnt = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = i+1; j < N; j++)\n            if (g[idx(i,j)] == '1')\n                for (int k = j+1; k < N; k++)\n                    if (g[idx(i,k)] == '1' && g[idx(j,k)] == '1') cnt++;\n    return cnt;\n}\n\nvoid compute_features(int k) {\n    edge_counts[k] = count(G[k].begin(), G[k].end(), '1');\n    vector<int> deg(N, 0);\n    for (int i = 0; i < N; i++)\n        for (int j = i+1; j < N; j++)\n            if (G[k][idx(i,j)] == '1') { deg[i]++; deg[j]++; }\n    sort(deg.begin(), deg.end());\n    deg_seqs[k] = deg;\n    tri_counts[k] = count_triangles(G[k]);\n}\n\nvoid generate_graphs() {\n    total_edges = N * (N - 1) / 2;\n    G.assign(M, string(total_edges, '0'));\n    edge_counts.resize(M);\n    deg_seqs.assign(M, vector<int>(N));\n    tri_counts.resize(M);\n    \n    for (int k = 0; k < M; k++) {\n        double frac = (M > 1) ? (double)k / (M - 1) : 0.5;\n        int target = (int)round(frac * total_edges);\n        int added = 0;\n        for (int i = 0; i < N && added < target; i++)\n            for (int j = i+1; j < N && added < target; j++, added++)\n                G[k][idx(i,j)] = '1';\n        compute_features(k);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> M >> eps;\n    \n    int min_n = max(4, (int)ceil((1.0 + sqrt(1.0 + 8.0 * (M - 1))) / 2.0));\n    double noise = sqrt(eps * (1 - eps));\n    \n    // More aggressive scaling with M-dependent base\n    double base_factor = 2.5 + M * 0.025;\n    double eps_factor = eps * 4.0;\n    int add_n = (int)(M * noise * (base_factor + eps_factor));\n    \n    // Ensure N grows with M for moderate-high epsilon\n    if (eps > 0.1) add_n = max(add_n, (int)(sqrt(M) * eps * 30));\n    \n    N = min(100, min_n + add_n);\n    \n    generate_graphs();\n    \n    cout << N << \"\\n\";\n    for (int k = 0; k < M; k++) cout << G[k] << \"\\n\";\n    cout << flush;\n    \n    double scale = max(0.001, 1 - 2*eps);\n    long long total_tri = (long long)N * (N-1) * (N-2) / 6;\n    double tri_factor = pow(1-eps, 3) - pow(eps, 3);\n    \n    for (int q = 0; q < 100; q++) {\n        string H; cin >> H;\n        \n        int h_edges = count(H.begin(), H.end(), '1');\n        vector<int> h_deg(N, 0);\n        for (int i = 0; i < N; i++)\n            for (int j = i+1; j < N; j++)\n                if (H[idx(i,j)] == '1') { h_deg[i]++; h_deg[j]++; }\n        sort(h_deg.begin(), h_deg.end());\n        long long h_tri = count_triangles(H);\n        \n        int best = 0;\n        double best_score = 1e18;\n        \n        for (int k = 0; k < M; k++) {\n            double exp_e = edge_counts[k] * scale + eps * total_edges;\n            double edge_diff = abs(h_edges - exp_e);\n            \n            double deg_diff = 0;\n            for (int i = 0; i < N; i++) {\n                double exp_deg = deg_seqs[k][i] * scale + eps * (N-1);\n                deg_diff += abs(h_deg[i] - exp_deg);\n            }\n            \n            double exp_tri = tri_counts[k] * tri_factor + total_tri * pow(eps, 3);\n            double tri_diff = abs(h_tri - exp_tri);\n            \n            // Feature weights based on epsilon\n            double edge_weight = 1.0;\n            double deg_weight = (eps < 0.2) ? 0.25 : (eps < 0.35) ? 0.1 : 0.05;\n            double tri_weight = (eps < 0.15) ? 0.015 : (eps < 0.3) ? 0.005 : 0.0;\n            \n            double score = edge_diff * edge_weight + deg_diff * deg_weight + tri_diff * tri_weight;\n            \n            if (score < best_score) {\n                best_score = score;\n                best = k;\n            }\n        }\n        \n        cout << best << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\ntypedef pair<ll, int> pli;\nconst ll INF = 1e18;\n\nint N, M, D, K;\nvector<int> eu, ev, ew;\nvector<vector<pair<int, int>>> adj;\nvector<ll> imp;\nvector<vector<int>> conflicts;\n\nvector<ll> dijkstra_skip(int s, int skip) {\n    vector<ll> dist(N, INF);\n    dist[s] = 0;\n    priority_queue<pli, vector<pli>, greater<pli>> pq;\n    pq.push({0, s});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > dist[u]) continue;\n        for (auto& [v, eid] : adj[u]) {\n            if (eid == skip) continue;\n            ll nd = d + ew[eid];\n            if (dist[v] > nd) { dist[v] = nd; pq.push({nd, v}); }\n        }\n    }\n    return dist;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto start = chrono::steady_clock::now();\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    for (int i = 0; i < N; i++) { int x, y; cin >> x >> y; }\n    \n    // Edge betweenness\n    vector<ll> betw(M, 0);\n    for (int s = 0; s < N; s++) {\n        vector<ll> dist(N, INF);\n        vector<int> pred(N, -1);\n        dist[s] = 0;\n        priority_queue<pli, vector<pli>, greater<pli>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& [v, eid] : adj[u]) {\n                ll nd = d + ew[eid];\n                if (dist[v] > nd) { dist[v] = nd; pred[v] = eid; pq.push({nd, v}); }\n            }\n        }\n        for (int t = 0; t < N; t++) if (pred[t] != -1) betw[pred[t]]++;\n    }\n    \n    // Detour sampling\n    mt19937 rng_det(789);\n    uniform_int_distribution<int> rand_e(0, M-1);\n    vector<ll> detour(M, 0);\n    for (int t = 0; t < min(M, 400); t++) {\n        int e = rand_e(rng_det);\n        if (detour[e] > 0) { t--; continue; }\n        vector<ll> d = dijkstra_skip(eu[e], e);\n        detour[e] = d[ev[e]] - ew[e];\n    }\n    \n    ll max_b = *max_element(betw.begin(), betw.end());\n    ll max_d = *max_element(detour.begin(), detour.end());\n    imp.resize(M);\n    for (int i = 0; i < M; i++) {\n        imp[i] = betw[i] * 1000 / max(1LL, max_b) + detour[i] * 500 / max(1LL, max_d);\n    }\n    \n    // Conflict pairs\n    conflicts.resize(M);\n    int cs = min(N, 150);\n    for (int s = 0; s < cs; s++) {\n        vector<ll> dist(N, INF);\n        vector<vector<int>> pred(N);\n        dist[s] = 0;\n        priority_queue<pli, vector<pli>, greater<pli>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& [v, eid] : adj[u]) {\n                ll nd = d + ew[eid];\n                if (dist[v] > nd) { dist[v] = nd; pred[v].clear(); pred[v].push_back(eid); pq.push({nd, v}); }\n                else if (dist[v] == nd) pred[v].push_back(eid);\n            }\n        }\n        for (int t = 0; t < N; t++) {\n            vector<int> edges;\n            queue<int> q; vector<bool> vis(N, false);\n            q.push(t); vis[t] = true;\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                for (int eid : pred[u]) {\n                    edges.push_back(eid);\n                    int p = (eu[eid] == u) ? ev[eid] : eu[eid];\n                    if (!vis[p]) { vis[p] = true; q.push(p); }\n                }\n            }\n            sort(edges.begin(), edges.end());\n            edges.erase(unique(edges.begin(), edges.end()), edges.end());\n            for (int i = 0; i < edges.size(); i++)\n                for (int j = i+1; j < edges.size(); j++)\n                    conflicts[min(edges[i],edges[j])].push_back(max(edges[i],edges[j]));\n        }\n    }\n    \n    // Compress conflicts\n    vector<unordered_map<int, int>> conf(M);\n    for (int i = 0; i < M; i++) {\n        for (int j : conflicts[i]) conf[i][j]++;\n    }\n    conflicts.clear();\n    \n    // Greedy assignment\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) { return imp[a] > imp[b]; });\n    \n    vector<int> assign(M, -1);\n    vector<int> cnt(D, 0);\n    vector<vector<ll>> day_edges(D); // imp of edges in each day\n    \n    for (int e : order) {\n        int best = -1;\n        ll best_conf = LLONG_MAX;\n        ll best_imp = LLONG_MAX;\n        for (int d = 0; d < D; d++) {\n            if (cnt[d] >= K) continue;\n            ll c = 0;\n            for (auto& [j, v] : conf[e]) if (assign[j] == d) c += v;\n            if (c < best_conf || (c == best_conf && day_edges[d].size() < best_imp)) {\n                best_conf = c;\n                best_imp = day_edges[d].size();\n                best = d;\n            }\n        }\n        assign[e] = best;\n        cnt[best]++;\n        day_edges[best].push_back(imp[e]);\n    }\n    \n    // Local search\n    mt19937 rng(42);\n    uniform_int_distribution<int> re(0, M-1);\n    \n    auto get_score = [&]() {\n        vector<ll> ds(D, 0);\n        for (int i = 0; i < M; i++) ds[assign[i]] += imp[i];\n        for (int i = 0; i < M; i++) for (auto& [j, c] : conf[i]) if (assign[i] == assign[j]) ds[assign[i]] += c;\n        ll t = 0;\n        for (int d = 0; d < D; d++) t += ds[d] * ds[d];\n        return t;\n    };\n    \n    ll cur = get_score();\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() < 5700) {\n        int e1 = re(rng), e2 = re(rng);\n        if (e1 == e2 || assign[e1] == assign[e2]) continue;\n        swap(assign[e1], assign[e2]);\n        ll nw = get_score();\n        if (nw < cur) cur = nw;\n        else swap(assign[e1], assign[e2]);\n    }\n    \n    for (int i = 0; i < M; i++) cout << assign[i] + 1 << \" \\n\"[i == M-1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f[2], r[2];\nint valid[2][15][15][15];\nint visited[15][15][15];\nint b[2][15][15][15];\nint dx[] = {1,-1,0,0,0,0}, dy[] = {0,0,1,-1,0,0}, dz[] = {0,0,0,0,1,-1};\nvector<array<array<int,3>,3>> rotations;\n\nvoid generateRotations() {\n    vector<array<int,3>> perms = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};\n    for (int s0 : {-1,1}) for (int s1 : {-1,1}) for (int s2 : {-1,1}) {\n        int sp = s0*s1*s2;\n        for (auto& p : perms) {\n            int inv = 0; for (int i=0;i<3;i++) for (int j=i+1;j<3;j++) if (p[i]>p[j]) inv++;\n            if ((inv%2==0) == (sp==1)) {\n                array<array<int,3>,3> R = {};\n                R[0][p[0]]=s0; R[1][p[1]]=s1; R[2][p[2]]=s2;\n                rotations.push_back(R);\n            }\n        }\n    }\n}\n\nset<array<int,3>> normalize(const vector<array<int,3>>& s) {\n    int mX=INT_MAX,mY=INT_MAX,mZ=INT_MAX;\n    for (auto& p : s) { mX=min(mX,p[0]); mY=min(mY,p[1]); mZ=min(mZ,p[2]); }\n    set<array<int,3>> r;\n    for (auto& p : s) r.insert({p[0]-mX, p[1]-mY, p[2]-mZ});\n    return r;\n}\n\nset<array<int,3>> rotate(const set<array<int,3>>& s, const array<array<int,3>,3>& R) {\n    vector<array<int,3>> rot;\n    for (auto& p : s) rot.push_back({R[0][0]*p[0]+R[0][1]*p[1]+R[0][2]*p[2], R[1][0]*p[0]+R[1][1]*p[1]+R[1][2]*p[2], R[2][0]*p[0]+R[2][1]*p[1]+R[2][2]*p[2]});\n    return normalize(rot);\n}\n\nset<array<int,3>> canonical(const set<array<int,3>>& s) {\n    set<array<int,3>> best = s;\n    for (auto& R : rotations) { auto r = rotate(s,R); if (r < best) best = r; }\n    return best;\n}\n\nvector<array<int,3>> bfs(int sel, int sx, int sy, int sz, int interMode) {\n    vector<array<int,3>> comp;\n    queue<array<int,3>> q;\n    q.push({sx,sy,sz});\n    visited[sx][sy][sz] = 1;\n    while (!q.empty()) {\n        auto [x,y,z] = q.front(); q.pop();\n        comp.push_back({x,y,z});\n        for (int d = 0; d < 6; d++) {\n            int nx=x+dx[d], ny=y+dy[d], nz=z+dz[d];\n            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && !visited[nx][ny][nz]) {\n                bool in0 = valid[0][nx][ny][nz], in1 = valid[1][nx][ny][nz];\n                bool ok = false;\n                if (interMode == 0) ok = (sel==0 ? in0&&!in1 : !in0&&in1);\n                else ok = in0 && in1;\n                if (ok) { visited[nx][ny][nz] = 1; q.push({nx,ny,nz}); }\n            }\n        }\n    }\n    return comp;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    generateRotations();\n    cin >> D;\n    for (int i = 0; i < 2; i++) {\n        f[i].resize(D); r[i].resize(D);\n        for (int z = 0; z < D; z++) cin >> f[i][z];\n        for (int z = 0; z < D; z++) cin >> r[i][z];\n    }\n    for (int i = 0; i < 2; i++)\n        for (int x = 0; x < D; x++)\n            for (int y = 0; y < D; y++)\n                for (int z = 0; z < D; z++)\n                    valid[i][x][y][z] = (f[i][z][x]=='1' && r[i][z][y]=='1');\n    \n    vector<vector<array<int,3>>> inter_comps, v1_comps, v2_comps;\n    memset(visited, 0, sizeof(visited));\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++)\n        if (valid[0][x][y][z] && valid[1][x][y][z] && !visited[x][y][z])\n            inter_comps.push_back(bfs(0,x,y,z,1));\n    \n    memset(visited, 0, sizeof(visited));\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++)\n        if (valid[0][x][y][z] && !valid[1][x][y][z] && !visited[x][y][z])\n            v1_comps.push_back(bfs(0,x,y,z,0));\n    \n    memset(visited, 0, sizeof(visited));\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++)\n        if (!valid[0][x][y][z] && valid[1][x][y][z] && !visited[x][y][z])\n            v2_comps.push_back(bfs(1,x,y,z,0));\n    \n    map<set<array<int,3>>, vector<int>> can_v1, can_v2;\n    for (int i = 0; i < (int)v1_comps.size(); i++) can_v1[canonical(normalize(v1_comps[i]))].push_back(i);\n    for (int i = 0; i < (int)v2_comps.size(); i++) can_v2[canonical(normalize(v2_comps[i]))].push_back(i);\n    \n    vector<int> m1(v1_comps.size(),-1), m2(v2_comps.size(),-1);\n    for (auto& [c, idx1] : can_v1) {\n        if (can_v2.count(c)) {\n            auto& idx2 = can_v2[c];\n            for (int k = 0; k < (int)min(idx1.size(), idx2.size()); k++) { m1[idx1[k]] = idx2[k]; m2[idx2[k]] = idx1[k]; }\n        }\n    }\n    \n    memset(b, 0, sizeof(b));\n    int bid = 0;\n    for (auto& c : inter_comps) { bid++; for (auto& p : c) b[0][p[0]][p[1]][p[2]] = b[1][p[0]][p[1]][p[2]] = bid; }\n    for (int i = 0; i < (int)v1_comps.size(); i++) {\n        bid++;\n        for (auto& p : v1_comps[i]) b[0][p[0]][p[1]][p[2]] = bid;\n        if (m1[i] >= 0) for (auto& p : v2_comps[m1[i]]) b[1][p[0]][p[1]][p[2]] = bid;\n    }\n    for (int i = 0; i < (int)v2_comps.size(); i++) if (m2[i] < 0) {\n        bid++;\n        for (auto& p : v2_comps[i]) b[1][p[0]][p[1]][p[2]] = bid;\n    }\n    \n    cout << bid << \"\\n\";\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++) cout << (x||y||z?\" \":\"\") << b[0][x][y][z];\n    cout << \"\\n\";\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++) cout << (x||y||z?\" \":\"\") << b[1][x][y][z];\n    cout << \"\\n\";\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\ntypedef pair<ll, int> pli;\ntypedef pair<int, int> pii;\n\nint N, M, K;\nvector<int> x, y;\nvector<tuple<int, int, ll>> edges;\nvector<int> a, b;\nvector<vector<pii>> adj;\nvector<ll> distTo0;\nvector<int> parent, parent_edge;\n\nint calcDist(int x1, int y1, int x2, int y2) {\n    ll dx = x1 - x2, dy = y1 - y2;\n    return (int)round(sqrt(dx*dx + dy*dy));\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K;\n    x.resize(N); y.resize(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    edges.resize(M); adj.resize(N);\n    for (int j = 0; j < M; j++) {\n        int uj, vj; ll wj;\n        cin >> uj >> vj >> wj;\n        uj--; vj--;\n        edges[j] = {uj, vj, wj};\n        adj[uj].push_back({vj, j});\n        adj[vj].push_back({uj, j});\n    }\n    \n    a.resize(K); b.resize(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    // Dijkstra from vertex 0\n    distTo0.assign(N, LLONG_MAX);\n    parent.assign(N, -1);\n    parent_edge.assign(N, -1);\n    priority_queue<pli, vector<pli>, greater<pli>> pq;\n    distTo0[0] = 0; pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > distTo0[u]) continue;\n        for (auto [v, ej] : adj[u]) {\n            ll wj = get<2>(edges[ej]);\n            if (distTo0[u] + wj < distTo0[v]) {\n                distTo0[v] = distTo0[u] + wj;\n                parent[v] = u; parent_edge[v] = ej;\n                pq.push({distTo0[v], v});\n            }\n        }\n    }\n    \n    // Precompute distances\n    vector<vector<int>> resToStation(K, vector<int>(N));\n    for (int k = 0; k < K; k++) {\n        for (int i = 0; i < N; i++) {\n            resToStation[k][i] = calcDist(a[k], b[k], x[i], y[i]);\n        }\n    }\n    \n    // Cost-aware greedy assignment\n    vector<int> res_station(K);\n    vector<int> station_power(N, 0);\n    set<int> active;\n    \n    // Process residents by difficulty (farthest first)\n    vector<int> order(K);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int k1, int k2) {\n        int m1 = *min_element(resToStation[k1].begin(), resToStation[k1].end());\n        int m2 = *min_element(resToStation[k2].begin(), resToStation[k2].end());\n        return m1 > m2;\n    });\n    \n    for (int k : order) {\n        ll bestCost = LLONG_MAX;\n        int bestStation = -1;\n        \n        for (int i = 0; i < N; i++) {\n            int d = resToStation[k][i];\n            if (d > 5000) continue;\n            \n            ll cost;\n            if (active.count(i)) {\n                int newP = max(station_power[i], d);\n                cost = (ll)newP * newP - (ll)station_power[i] * station_power[i];\n            } else {\n                cost = distTo0[i] + (ll)d * d;\n            }\n            \n            if (cost < bestCost) {\n                bestCost = cost;\n                bestStation = i;\n            }\n        }\n        \n        if (bestStation >= 0) {\n            res_station[k] = bestStation;\n            station_power[bestStation] = max(station_power[bestStation], resToStation[k][bestStation]);\n            active.insert(bestStation);\n        }\n    }\n    \n    // Build edge set\n    vector<int> B(M, 0);\n    auto buildEdges = [&]() {\n        fill(B.begin(), B.end(), 0);\n        for (int i : active) {\n            int cur = i;\n            while (parent[cur] != -1) {\n                B[parent_edge[cur]] = 1;\n                cur = parent[cur];\n            }\n        }\n    };\n    buildEdges();\n    \n    // Remove redundant edges\n    auto getReachable = [&]() {\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(0);\n        visited[0] = true;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (auto [v, ej] : adj[u]) {\n                if (B[ej] && !visited[v]) {\n                    visited[v] = true;\n                    q.push(v);\n                }\n            }\n        }\n        return visited;\n    };\n    \n    auto removeRedundantEdges = [&]() {\n        vector<int> edgeOrder(M);\n        iota(edgeOrder.begin(), edgeOrder.end(), 0);\n        sort(edgeOrder.begin(), edgeOrder.end(), [&](int j1, int j2) {\n            return get<2>(edges[j1]) > get<2>(edges[j2]);\n        });\n        for (int j : edgeOrder) {\n            if (!B[j]) continue;\n            B[j] = 0;\n            auto visited = getReachable();\n            for (int i : active) {\n                if (!visited[i]) { B[j] = 1; break; }\n            }\n        }\n    };\n    removeRedundantEdges();\n    \n    // Local search: remove expensive stations\n    for (int iter = 0; iter < 50; iter++) {\n        bool improved = false;\n        vector<int> stationList(active.begin(), active.end());\n        sort(stationList.begin(), stationList.end(), [&](int i1, int i2) {\n            return (ll)station_power[i1]*station_power[i1] > (ll)station_power[i2]*station_power[i2];\n        });\n        \n        for (int si : stationList) {\n            if (si == 0) continue;\n            \n            vector<int> myRes;\n            for (int k = 0; k < K; k++) if (res_station[k] == si) myRes.push_back(k);\n            if (myRes.empty()) continue;\n            \n            map<int, int> newPowers;\n            vector<int> newAssign(myRes.size());\n            bool ok = true;\n            \n            for (int idx = 0; idx < (int)myRes.size(); idx++) {\n                int k = myRes[idx];\n                ll bestCost = LLONG_MAX;\n                int bestJ = -1;\n                \n                for (int j = 0; j < N; j++) {\n                    if (j == si) continue;\n                    int d = resToStation[k][j];\n                    if (d > 5000) continue;\n                    \n                    int curP = station_power[j];\n                    if (newPowers.count(j)) curP = newPowers[j];\n                    int newP = max(curP, d);\n                    ll cost = (ll)newP*newP - (ll)curP*curP;\n                    if (!active.count(j) && j != 0) cost += distTo0[j];\n                    \n                    if (cost < bestCost) { bestCost = cost; bestJ = j; }\n                }\n                \n                if (bestJ < 0) { ok = false; break; }\n                newAssign[idx] = bestJ;\n                int d = resToStation[k][bestJ];\n                int curP = station_power[bestJ];\n                if (newPowers.count(bestJ)) curP = newPowers[bestJ];\n                newPowers[bestJ] = max(curP, d);\n            }\n            \n            if (!ok) continue;\n            \n            set<int> newActive = active;\n            newActive.erase(si);\n            for (auto& [j, p] : newPowers) if (!active.count(j) && j != 0) newActive.insert(j);\n            \n            ll oldCost = (ll)station_power[si]*station_power[si] + distTo0[si];\n            ll newCost = 0;\n            for (auto& [j, p] : newPowers) {\n                newCost += (ll)p*p - (ll)station_power[j]*station_power[j];\n                if (!active.count(j) && j != 0) newCost += distTo0[j];\n            }\n            \n            if (newCost < oldCost) {\n                improved = true;\n                active = newActive;\n                station_power[si] = 0;\n                for (int idx = 0; idx < (int)myRes.size(); idx++) {\n                    res_station[myRes[idx]] = newAssign[idx];\n                }\n                for (auto& [j, p] : newPowers) station_power[j] = p;\n                buildEdges();\n                removeRedundantEdges();\n            }\n        }\n        if (!improved) break;\n    }\n    \n    for (int i = 0; i < N; i++) cout << station_power[i] << (i < N-1 ? \" \" : \"\\n\");\n    for (int j = 0; j < M; j++) cout << B[j] << (j < M-1 ? \" \" : \"\\n\");\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2;\n\nint pyramid[N][N];\nint pos[TOTAL];\nint dist[TOTAL], parent[TOTAL];\n\nint idx(int x, int y) { return x * (x + 1) / 2 + y; }\n\npair<int,int> coord(int i) {\n    int x = (int)(sqrt(2.0 * i + 0.25) - 0.5);\n    while (idx(x + 1, 0) <= i) x++;\n    return {x, i - idx(x, 0)};\n}\n\nvoid bfs(int s, int target) {\n    fill(dist, dist + TOTAL, -1);\n    fill(parent, parent + TOTAL, -1);\n    queue<int> q;\n    q.push(s);\n    dist[s] = 0;\n    while (!q.empty()) {\n        int u = q.front(); q.pop();\n        auto [x, y] = coord(u);\n        vector<pair<int,int>> neighbors;\n        if (x > 0 && y > 0) neighbors.push_back({x-1, y-1});\n        if (x > 0 && y < x) neighbors.push_back({x-1, y});\n        if (y > 0) neighbors.push_back({x, y-1});\n        if (y < x) neighbors.push_back({x, y+1});\n        if (x < N-1) neighbors.push_back({x+1, y});\n        if (x < N-1) neighbors.push_back({x+1, y+1});\n        for (auto [nx, ny] : neighbors) {\n            int p = idx(nx, ny);\n            // Block positions that have their correct values and are before target\n            if (pyramid[nx][ny] == p && p < target) continue;\n            if (dist[p] == -1) {\n                dist[p] = dist[u] + 1;\n                parent[p] = u;\n                q.push(p);\n            }\n        }\n    }\n}\n\nint count_violations() {\n    int E = 0;\n    for (int x = 0; x < N-1; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) E++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) E++;\n        }\n    }\n    return E;\n}\n\nint count_edges(int x, int y) {\n    int cnt = 0;\n    if (x > 0) {\n        if (y > 0 && pyramid[x-1][y-1] > pyramid[x][y]) cnt++;\n        if (y < x && pyramid[x-1][y] > pyramid[x][y]) cnt++;\n    }\n    if (x < N-1) {\n        if (pyramid[x][y] > pyramid[x+1][y]) cnt++;\n        if (pyramid[x][y] > pyramid[x+1][y+1]) cnt++;\n    }\n    return cnt;\n}\n\nvector<pair<int,int>> get_neighbors(int x, int y) {\n    vector<pair<int,int>> neighbors;\n    if (x > 0 && y > 0) neighbors.push_back({x-1, y-1});\n    if (x > 0 && y < x) neighbors.push_back({x-1, y});\n    if (y > 0) neighbors.push_back({x, y-1});\n    if (y < x) neighbors.push_back({x, y+1});\n    if (x < N-1) neighbors.push_back({x+1, y});\n    if (x < N-1) neighbors.push_back({x+1, y+1});\n    return neighbors;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n            pos[pyramid[x][y]] = idx(x, y);\n        }\n    }\n    \n    vector<array<int,4>> moves;\n    \n    // Phase 1: Greedy placement with blocking\n    for (int v = 0; v < TOTAL && (int)moves.size() < 9800; v++) {\n        int cur = pos[v];\n        if (cur == v) continue;\n        \n        bfs(cur, v);\n        \n        if (dist[v] == -1) continue;\n        \n        vector<int> path;\n        for (int u = v; u != -1; u = parent[u]) path.push_back(u);\n        reverse(path.begin(), path.end());\n        \n        for (size_t i = 0; i+1 < path.size() && (int)moves.size() < 9800; i++) {\n            auto [x1, y1] = coord(path[i]);\n            auto [x2, y2] = coord(path[i+1]);\n            int v1 = pyramid[x1][y1], v2 = pyramid[x2][y2];\n            pos[v1] = path[i+1];\n            pos[v2] = path[i];\n            swap(pyramid[x1][y1], pyramid[x2][y2]);\n            moves.push_back({x1, y1, x2, y2});\n        }\n    }\n    \n    // Phase 2: Local improvement\n    while ((int)moves.size() < 10000) {\n        int best_delta = 0;\n        array<int, 4> best_move;\n        \n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y <= x; y++) {\n                auto neighbors = get_neighbors(x, y);\n                for (auto [nx, ny] : neighbors) {\n                    if (nx < x || (nx == x && ny < y)) continue;\n                    \n                    int before = count_edges(x, y) + count_edges(nx, ny);\n                    swap(pyramid[x][y], pyramid[nx][ny]);\n                    int after = count_edges(x, y) + count_edges(nx, ny);\n                    swap(pyramid[x][y], pyramid[nx][ny]);\n                    \n                    int delta = before - after;\n                    if (delta > best_delta) {\n                        best_delta = delta;\n                        best_move = {x, y, nx, ny};\n                    }\n                }\n            }\n        }\n        \n        if (best_delta <= 0) break;\n        \n        int x = best_move[0], y = best_move[1], nx = best_move[2], ny = best_move[3];\n        swap(pyramid[x][y], pyramid[nx][ny]);\n        moves.push_back(best_move);\n    }\n    \n    cout << moves.size() << \"\\n\";\n    for (auto& m : moves) {\n        cout << m[0] << \" \" << m[1] << \" \" << m[2] << \" \" << m[3] << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int D, N;\n    cin >> D >> N;\n    \n    set<pair<int,int>> obstacles;\n    for (int i = 0; i < N; i++) {\n        int ri, rj; cin >> ri >> rj;\n        obstacles.insert({ri, rj});\n    }\n    \n    int entrance_j = (D - 1) / 2;\n    int M = D * D - 1 - N;\n    \n    vector<pair<int,int>> cells;\n    map<pair<int,int>, int> cell_to_idx;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (!(i == 0 && j == entrance_j) && !obstacles.count({i, j})) {\n                cell_to_idx[{i, j}] = cells.size();\n                cells.push_back({i, j});\n            }\n    \n    int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1};\n    auto valid = [&](int i, int j) { return i >= 0 && i < D && j >= 0 && j < D; };\n    \n    vector<vector<int>> dist(D, vector<int>(D, INT_MAX));\n    queue<pair<int,int>> q; q.push({0, entrance_j}); dist[0][entrance_j] = 0;\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (valid(ni, nj) && dist[ni][nj] == INT_MAX && !obstacles.count({ni, nj})) {\n                dist[ni][nj] = dist[i][j] + 1; q.push({ni, nj});\n            }\n        }\n    }\n    \n    vector<int> downstream(cells.size(), 0);\n    for (size_t c = 0; c < cells.size(); c++) {\n        auto [ci, cj] = cells[c];\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<pair<int,int>> bq; bq.push({0, entrance_j});\n        visited[0][entrance_j] = true; visited[ci][cj] = true;\n        while (!bq.empty()) {\n            auto [i, j] = bq.front(); bq.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (valid(ni, nj) && !visited[ni][nj] && !obstacles.count({ni, nj})) {\n                    visited[ni][nj] = true; bq.push({ni, nj});\n                }\n            }\n        }\n        for (size_t cc = 0; cc < cells.size(); cc++)\n            if (!visited[cells[cc].first][cells[cc].second]) downstream[c]++;\n    }\n    \n    vector<int> order(cells.size()); iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        int da = dist[cells[a].first][cells[a].second], db = dist[cells[b].first][cells[b].second];\n        return da != db ? da < db : (downstream[a] != downstream[b] ? downstream[a] > downstream[b] : cells[a] < cells[b]);\n    });\n    vector<int> cell_rank(cells.size());\n    for (size_t i = 0; i < order.size(); i++) cell_rank[order[i]] = i;\n    \n    vector<int> container_at_cell(cells.size(), -1), container_cell(M, -1);\n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        vector<int> available;\n        for (size_t c = 0; c < cells.size(); c++) if (container_at_cell[c] == -1) available.push_back(c);\n        sort(available.begin(), available.end(), [&](int a, int b) { return cell_rank[a] < cell_rank[b]; });\n        int idx = (M == 1) ? 0 : min((int)available.size()-1, max(0, (int)round((double)t/(M-1)*(available.size()-1))));\n        container_at_cell[available[idx]] = t; container_cell[t] = available[idx];\n        cout << cells[available[idx]].first << \" \" << cells[available[idx]].second << \"\\n\" << flush;\n    }\n    \n    vector<bool> present(M, true);\n    for (int step = 0; step < M; step++) {\n        set<int> reachable;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        queue<pair<int,int>> bq; bq.push({0, entrance_j}); visited[0][entrance_j] = true;\n        while (!bq.empty()) {\n            auto [i, j] = bq.front(); bq.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (!valid(ni, nj) || visited[ni][nj] || obstacles.count({ni, nj})) continue;\n                auto it = cell_to_idx.find({ni, nj});\n                if (it == cell_to_idx.end()) { visited[ni][nj] = true; bq.push({ni, nj}); }\n                else if (present[container_at_cell[it->second]]) reachable.insert(container_at_cell[it->second]);\n                else { visited[ni][nj] = true; bq.push({ni, nj}); }\n            }\n        }\n        int best = *reachable.begin(); present[best] = false;\n        cout << cells[container_cell[best]].first << \" \" << cells[container_cell[best]].second << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    auto start = chrono::steady_clock::now();\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> orig(n, vector<int>(n));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            cin >> orig[i][j];\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    auto inside = [](int x, int y, int N) { return x >= 0 && x < N && y >= 0 && y < N; };\n    \n    set<pair<int,int>> origAdjSet;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                int nc = inside(ni, nj, n) ? orig[ni][nj] : 0;\n                if (nc != orig[i][j]) {\n                    int a = orig[i][j], b = nc;\n                    if (a > b) swap(a, b);\n                    origAdjSet.insert({a, b});\n                }\n            }\n        }\n    }\n    \n    mt19937 rng(12345);\n    vector<pair<int,int>> baseOrder;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            baseOrder.push_back({i, j});\n    \n    auto solve = [&](vector<pair<int,int>> order) -> pair<int, vector<vector<int>>> {\n        vector g = orig;\n        map<pair<int,int>, int> adjCnt;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    int nc = inside(ni, nj, n) ? g[ni][nj] : 0;\n                    if (nc != g[i][j]) {\n                        int a = g[i][j], b = nc;\n                        if (a > b) swap(a, b);\n                        adjCnt[{a, b}]++;\n                    }\n                }\n            }\n        }\n        \n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (auto [i, j] : order) {\n                if (g[i][j] == 0) continue;\n                int c = g[i][j];\n                \n                bool conn0 = (i == 0 || i == n-1 || j == 0 || j == n-1);\n                if (!conn0) {\n                    for (int d = 0; d < 4; d++) {\n                        int ni = i + dx[d], nj = j + dy[d];\n                        if (inside(ni, nj, n) && g[ni][nj] == 0) { conn0 = true; break; }\n                    }\n                }\n                if (!conn0) continue;\n                \n                map<pair<int,int>, int> delta;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    bool in = inside(ni, nj, n);\n                    int nc = in ? g[ni][nj] : 0;\n                    if (nc != c) {\n                        int a = c, b = nc;\n                        if (a > b) swap(a, b);\n                        delta[{a, b}]--;\n                        if (in) delta[{a, b}]--;\n                    }\n                    if (nc != 0) {\n                        int a = 0, b = nc;\n                        if (a > b) swap(a, b);\n                        delta[{a, b}] += 2;\n                    }\n                }\n                \n                bool ok = true;\n                for (auto& [p, ch] : delta) {\n                    int newCnt = adjCnt[p] + ch;\n                    if (newCnt > 0 && origAdjSet.count(p) == 0) { ok = false; break; }\n                    if (newCnt == 0 && origAdjSet.count(p) > 0) { ok = false; break; }\n                }\n                if (!ok) continue;\n                \n                vector<pair<int,int>> sameColorNbrs;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    if (inside(ni, nj, n) && g[ni][nj] == c)\n                        sameColorNbrs.push_back({ni, nj});\n                }\n                \n                bool connected = true;\n                if (sameColorNbrs.size() > 1) {\n                    g[i][j] = 0;\n                    queue<int> q;\n                    vector<bool> vis(n * n, false);\n                    q.push(sameColorNbrs[0].first * n + sameColorNbrs[0].second);\n                    vis[sameColorNbrs[0].first * n + sameColorNbrs[0].second] = true;\n                    while (!q.empty()) {\n                        int cur = q.front(); q.pop();\n                        int x = cur / n, y = cur % n;\n                        for (int d = 0; d < 4; d++) {\n                            int nx = x + dx[d], ny = y + dy[d];\n                            if (inside(nx, ny, n) && g[nx][ny] == c && !vis[nx * n + ny]) {\n                                vis[nx * n + ny] = true;\n                                q.push(nx * n + ny);\n                            }\n                        }\n                    }\n                    for (auto& p : sameColorNbrs) {\n                        if (!vis[p.first * n + p.second]) { connected = false; break; }\n                    }\n                    g[i][j] = c;\n                }\n                \n                if (connected) {\n                    g[i][j] = 0;\n                    for (auto& [p, ch] : delta) adjCnt[p] += ch;\n                    changed = true;\n                }\n            }\n        }\n        \n        int score = 0;\n        for (int i = 0; i < n; i++)\n            for (int j = 0; j < n; j++)\n                if (g[i][j] == 0) score++;\n        \n        return {score, g};\n    };\n    \n    int bestScore = -1;\n    vector<vector<int>> bestG;\n    \n    auto check = [&](vector<pair<int,int>> order) {\n        auto [s, g] = solve(order);\n        if (s > bestScore) { bestScore = s; bestG = g; }\n    };\n    \n    check(baseOrder);\n    auto rev = baseOrder; reverse(rev.begin(), rev.end()); check(rev);\n    \n    vector<pair<int,int>> colMajor;\n    for (int j = 0; j < n; j++) for (int i = 0; i < n; i++) colMajor.push_back({i, j});\n    check(colMajor); reverse(colMajor.begin(), colMajor.end()); check(colMajor);\n    \n    // Spiral\n    {\n        vector<pair<int,int>> spiral;\n        int t = 0, b = n-1, l = 0, r = n-1;\n        while (t <= b && l <= r) {\n            for (int j = l; j <= r; j++) spiral.push_back({t, j});\n            t++;\n            for (int i = t; i <= b; i++) spiral.push_back({i, r});\n            r--;\n            if (t <= b) { for (int j = r; j >= l; j--) spiral.push_back({b, j}); b--; }\n            if (l <= r) { for (int i = b; i >= t; i--) spiral.push_back({i, l}); l++; }\n        }\n        check(spiral); reverse(spiral.begin(), spiral.end()); check(spiral);\n    }\n    \n    // Diagonal\n    {\n        vector<pair<int,int>> diag;\n        for (int s = 0; s < 2*n-1; s++)\n            for (int i = 0; i < n; i++) {\n                int j = s - i;\n                if (j >= 0 && j < n) diag.push_back({i, j});\n            }\n        check(diag); reverse(diag.begin(), diag.end()); check(diag);\n    }\n    \n    // Random with time limit\n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < 1.8) {\n        auto randOrder = baseOrder;\n        shuffle(randOrder.begin(), randOrder.end(), rng);\n        check(randOrder);\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << bestG[i][j];\n            if (j < n - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc025":"#include <cstdio>\n#include <vector>\n#include <algorithm>\n#include <cmath>\nusing namespace std;\n\nint N, D, Q;\nint qc = 0;\nchar cmp[101][101];\n\nchar comp(int a, int b) {\n    if (a == b) return '=';\n    if (cmp[a][b]) return cmp[a][b];\n    if (qc >= Q) return '=';\n    qc++;\n    printf(\"1 1 %d %d\\n\", a, b);\n    fflush(stdout);\n    char r; scanf(\" %c\", &r);\n    cmp[a][b] = r;\n    cmp[b][a] = r == '<' ? '>' : r == '>' ? '<' : '=';\n    return r;\n}\n\nvoid msort(vector<int>& a, int l, int r) {\n    if (l >= r) return;\n    int m = (l+r)/2;\n    msort(a, l, m);\n    msort(a, m+1, r);\n    vector<int> t;\n    int i = l, j = m+1;\n    while (i <= m && j <= r) {\n        char res = comp(a[i], a[j]);\n        t.push_back((res == '<' || res == '=') ? a[i++] : a[j++]);\n    }\n    while (i <= m) t.push_back(a[i++]);\n    while (j <= r) t.push_back(a[j++]);\n    for (int k = l; k <= r; k++) a[k] = t[k-l];\n}\n\nchar query_set(const vector<int>& L, const vector<int>& R) {\n    if (L.empty() || R.empty()) return '=';\n    if (qc >= Q) return '=';\n    qc++;\n    printf(\"%zu %zu\", L.size(), R.size());\n    for (int x : L) printf(\" %d\", x);\n    for (int x : R) printf(\" %d\", x);\n    printf(\"\\n\");\n    fflush(stdout);\n    char r; scanf(\" %c\", &r);\n    return r;\n}\n\nint main() {\n    scanf(\"%d%d%d\", &N, &D, &Q);\n    \n    vector<int> ord(N);\n    for (int i = 0; i < N; i++) ord[i] = i;\n    msort(ord, 0, N-1);\n    \n    // Exponential weight estimation (inverse CDF approximation)\n    vector<double> w(N);\n    for (int i = 0; i < N; i++) {\n        double p = (i + 0.5) / N;\n        w[ord[i]] = -log(1.0 - p * 0.99);\n    }\n    \n    vector<double> sw(D, 0);\n    vector<int> ans(N);\n    vector<vector<int>> S(D);\n    \n    // LPT: assign heaviest items first to lightest sets\n    for (int i = N-1; i >= 0; i--) {\n        int it = ord[i], mi = 0;\n        for (int d = 1; d < D; d++) if (sw[d] < sw[mi]) mi = d;\n        ans[it] = mi;\n        S[mi].push_back(it);\n        sw[mi] += w[it];\n    }\n    \n    for (int d = 0; d < D; d++)\n        sort(S[d].begin(), S[d].end(), [&](int a, int b) { return w[a] < w[b]; });\n    \n    // Local search\n    while (qc + 1 <= Q) {\n        int hv = 0, lt = 0;\n        for (int d = 1; d < D; d++) {\n            if (sw[d] > sw[hv]) hv = d;\n            if (sw[d] < sw[lt]) lt = d;\n        }\n        if (hv == lt || S[hv].size() <= 1) break;\n        \n        char r = query_set(S[hv], S[lt]);\n        if (r == '=') break;\n        if (r == '<') swap(hv, lt);\n        \n        // Find best item to move (closest to half the difference)\n        double target = (sw[hv] - sw[lt]) / 2;\n        int mv = S[hv][0];\n        double best = fabs(w[mv] - target);\n        for (int x : S[hv]) {\n            double d = fabs(w[x] - target);\n            if (d < best) { best = d; mv = x; }\n        }\n        \n        ans[mv] = lt;\n        S[hv].erase(remove(S[hv].begin(), S[hv].end(), mv), S[hv].end());\n        S[lt].push_back(mv);\n        sort(S[lt].begin(), S[lt].end(), [&](int a, int b) { return w[a] < w[b]; });\n        sw[hv] -= w[mv];\n        sw[lt] += w[mv];\n    }\n    \n    while (qc < Q) {\n        printf(\"1 1 0 1\\n\");\n        fflush(stdout);\n        char d; scanf(\" %c\", &d);\n        qc++;\n    }\n    \n    for (int i = 0; i < N; i++) printf(\"%d%c\", ans[i], i < N-1 ? ' ' : '\\n');\n    fflush(stdout);\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> st(m);\n    for (int i = 0; i < m; i++) {\n        st[i].resize(n/m);\n        for (int j = 0; j < n/m; j++) {\n            cin >> st[i][j];\n        }\n    }\n    \n    vector<pair<int, int>> ops;\n    \n    for (int v = 1; v <= n; v++) {\n        int si = -1, pos = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)st[i].size(); j++) {\n                if (st[i][j] == v) {\n                    si = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (si != -1) break;\n        }\n        \n        if (si == -1) continue;\n        \n        if (pos < (int)st[si].size() - 1) {\n            int maxMoved = INT_MIN, minMoved = INT_MAX;\n            int movedSize = st[si].size() - pos - 1;\n            for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                maxMoved = max(maxMoved, st[si][j]);\n                minMoved = min(minMoved, st[si][j]);\n            }\n            \n            int dest = -1;\n            int bestCost = INT_MAX;\n            int bestTiebreaker = INT_MIN;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == si) continue;\n                \n                int cost;\n                int tiebreaker;\n                \n                if (st[i].empty()) {\n                    cost = 0;\n                    tiebreaker = 100000;\n                } else {\n                    int top = st[i].back();\n                    if (top > maxMoved) {\n                        cost = 0;\n                        tiebreaker = top * 1000 + (200 - st[i].size());\n                    } else if (top < minMoved) {\n                        cost = movedSize;\n                        tiebreaker = -st[i].size();\n                    } else {\n                        int blockingCount = 0;\n                        for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                            if (st[si][j] > top) blockingCount++;\n                        }\n                        cost = blockingCount;\n                        tiebreaker = top - st[i].size();\n                    }\n                }\n                \n                if (cost < bestCost || (cost == bestCost && tiebreaker > bestTiebreaker)) {\n                    bestCost = cost;\n                    bestTiebreaker = tiebreaker;\n                    dest = i;\n                }\n            }\n            \n            int boxAbove = st[si][pos + 1];\n            ops.push_back({boxAbove, dest + 1});\n            \n            for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                st[dest].push_back(st[si][j]);\n            }\n            st[si].resize(pos + 1);\n        }\n        \n        ops.push_back({v, 0});\n        st[si].pop_back();\n    }\n    \n    for (auto& [a, b] : ops) {\n        cout << a << \" \" << b << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#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<string> h(N-1), v(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};\n    char dirChar[] = {'R', 'D', 'L', 'U'};\n    \n    auto canMove = [&](int i, int j, int k) -> bool {\n        int ni = i + di[k], nj = j + dj[k];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n        if (di[k] != 0) return h[min(i, ni)][j] == '0';\n        return v[i][min(j, nj)] == '0';\n    };\n    \n    vector<vector<int>> dist0(N, vector<int>(N, -1));\n    vector<vector<int>> prevDir(N, vector<int>(N, -1));\n    queue<pair<int,int>> qu;\n    qu.push({0, 0});\n    dist0[0][0] = 0;\n    while (!qu.empty()) {\n        auto [i, j] = qu.front(); qu.pop();\n        for (int k = 0; k < 4; k++) {\n            if (!canMove(i, j, k)) continue;\n            int ni = i + di[k], nj = j + dj[k];\n            if (dist0[ni][nj] < 0) {\n                dist0[ni][nj] = dist0[i][j] + 1;\n                prevDir[ni][nj] = k;\n                qu.push({ni, nj});\n            }\n        }\n    }\n    \n    vector visited(N, vector<bool>(N, false));\n    string tour;\n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        vector<tuple<int,int,int>> nb;\n        for (int k = 0; k < 4; k++) {\n            if (!canMove(i, j, k)) continue;\n            int ni = i + di[k], nj = j + dj[k];\n            if (!visited[ni][nj]) nb.emplace_back(-d[ni][nj], dist0[ni][nj], k);\n        }\n        sort(nb.begin(), nb.end());\n        for (auto& [_, __, k] : nb) {\n            tour += dirChar[k];\n            dfs(i + di[k], j + dj[k]);\n            tour += dirChar[(k+2)%4];\n        }\n    };\n    dfs(0, 0);\n    \n    vector visitCount(N, vector<int>(N, 1));\n    long long L = tour.size();\n    int budget = 100000 - L;\n    \n    double sumWI = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            sumWI += (double)d[i][j] / visitCount[i][j];\n    \n    auto addRoundTrip = [&](int ti, int tj) {\n        string fwd;\n        int ci = ti, cj = tj;\n        while (ci != 0 || cj != 0) {\n            int k = prevDir[ci][cj];\n            fwd += dirChar[k];\n            ci -= di[k];\n            cj -= dj[k];\n        }\n        reverse(fwd.begin(), fwd.end());\n        string back = fwd;\n        reverse(back.begin(), back.end());\n        for (char& c : back) {\n            if (c == 'R') c = 'L';\n            else if (c == 'L') c = 'R';\n            else if (c == 'U') c = 'D';\n            else c = 'U';\n        }\n        tour += fwd + back;\n    };\n    \n    // Get intermediate cells on path to (ti, tj)\n    auto getIntermediates = [&](int ti, int tj, vector<pair<int,int>>& cells) {\n        cells.clear();\n        int ci = ti, cj = tj;\n        while (ci != 0 || cj != 0) {\n            int k = prevDir[ci][cj];\n            ci -= di[k];\n            cj -= dj[k];\n            if (ci != 0 || cj != 0) cells.emplace_back(ci, cj);\n        }\n    };\n    \n    while (budget > 10) {\n        double bestDelta = 0;\n        int bestI = -1, bestJ = -1;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (i == 0 && j == 0) continue;\n                int cost = 2 * dist0[i][j];\n                if (cost <= 0 || cost > budget) continue;\n                \n                double delta = 0;\n                int vti = visitCount[i][j];\n                int v00 = visitCount[0][0];\n                \n                // Destination: d * (v*cost - L) / (2*v*(v+1))\n                delta += (double)d[i][j] * ((long long)vti * cost - L) / (2.0 * vti * (vti + 1));\n                // Origin\n                delta += (double)d[0][0] * ((long long)v00 * cost - L) / (2.0 * v00 * (v00 + 1));\n                \n                // Intermediate cells: d * (2*v*cost - L) / (2*v*(v+2))\n                double sumInterm = 0;\n                int ci = i, cj = j;\n                while (ci != 0 || cj != 0) {\n                    int k = prevDir[ci][cj];\n                    ci -= di[k];\n                    cj -= dj[k];\n                    if (ci != 0 || cj != 0) {\n                        int vc = visitCount[ci][cj];\n                        delta += (double)d[ci][cj] * (2LL * vc * cost - L) / (2.0 * vc * (vc + 2));\n                        sumInterm += (double)d[ci][cj] / vc;\n                    }\n                }\n                \n                // Other cells: penalty\n                double sumOther = sumWI - (double)d[i][j] / vti - (double)d[0][0] / v00 - sumInterm;\n                delta += sumOther * cost / 2.0;\n                \n                if (delta < bestDelta) {\n                    bestDelta = delta;\n                    bestI = i; bestJ = j;\n                }\n            }\n        }\n        \n        if (bestI < 0 || bestDelta >= 0) break;\n        \n        int cost = 2 * dist0[bestI][bestJ];\n        \n        // Update sumWI and visit counts\n        sumWI -= (double)d[bestI][bestJ] / visitCount[bestI][bestJ];\n        visitCount[bestI][bestJ]++;\n        sumWI += (double)d[bestI][bestJ] / visitCount[bestI][bestJ];\n        \n        sumWI -= (double)d[0][0] / visitCount[0][0];\n        visitCount[0][0]++;\n        sumWI += (double)d[0][0] / visitCount[0][0];\n        \n        int ci = bestI, cj = bestJ;\n        while (ci != 0 || cj != 0) {\n            int k = prevDir[ci][cj];\n            ci -= di[k];\n            cj -= dj[k];\n            if (ci != 0 || cj != 0) {\n                sumWI -= (double)d[ci][cj] / visitCount[ci][cj];\n                visitCount[ci][cj] += 2;\n                sumWI += (double)d[ci][cj] / visitCount[ci][cj];\n            }\n        }\n        \n        addRoundTrip(bestI, bestJ);\n        L += cost;\n        budget -= cost;\n    }\n    \n    cout << tour << '\\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(nullptr);\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<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 * N + j);\n    \n    auto getCoord = [N](int idx) { return make_pair(idx / N, idx % N); };\n    \n    auto computeOverlap = [](const string& a, const string& b) {\n        for (int len = (int)min(a.size(), b.size()); len >= 0; len--) {\n            bool match = true;\n            for (int i = 0; i < len && match; i++)\n                if (a[a.size() - len + i] != b[i]) match = false;\n            if (match) return len;\n        }\n        return 0;\n    };\n    \n    vector<vector<int>> overlap(M, vector<int>(M, 0));\n    for (int i = 0; i < M; i++)\n        for (int j = 0; j < M; j++)\n            if (i != j) overlap[i][j] = computeOverlap(words[i], words[j]);\n    \n    auto buildSuperstring = [&](const vector<int>& order) {\n        string result = words[order[0]];\n        for (int k = 1; k < M; k++)\n            result += words[order[k]].substr(overlap[order[k-1]][order[k]]);\n        return result;\n    };\n    \n    string bestSuperstring;\n    int bestLen = INT_MAX;\n    mt19937 rng(42);\n    \n    for (int trial = 0; trial < 200; trial++) {\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        \n        int start = rng() % M;\n        swap(order[0], order[start]);\n        for (int i = 1; i < M; i++) {\n            int bestIdx = i;\n            int bestOv = -1;\n            for (int j = i; j < M; j++) {\n                if (overlap[order[i-1]][order[j]] > bestOv) {\n                    bestOv = overlap[order[i-1]][order[j]];\n                    bestIdx = j;\n                }\n            }\n            swap(order[i], order[bestIdx]);\n        }\n        \n        // Fast adjacent-swap local search with O(1) delta\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < M - 1; i++) {\n                int oldSum = 0, newSum = 0;\n                if (i > 0) {\n                    oldSum += overlap[order[i-1]][order[i]];\n                    newSum += overlap[order[i-1]][order[i+1]];\n                }\n                oldSum += overlap[order[i]][order[i+1]];\n                newSum += overlap[order[i+1]][order[i]];\n                if (i + 2 < M) {\n                    oldSum += overlap[order[i+1]][order[i+2]];\n                    newSum += overlap[order[i]][order[i+2]];\n                }\n                if (newSum > oldSum) {\n                    swap(order[i], order[i+1]);\n                    improved = true;\n                }\n            }\n        }\n        \n        string superstring = buildSuperstring(order);\n        if ((int)superstring.size() < bestLen) {\n            bestLen = superstring.size();\n            bestSuperstring = superstring;\n        }\n    }\n    \n    int L = bestSuperstring.size();\n    vector<pair<int, int>> dp;\n    for (int cell : charPos[bestSuperstring[0] - 'A']) {\n        auto [ci, cj] = getCoord(cell);\n        dp.emplace_back(cell, abs(ci - si) + abs(cj - sj) + 1);\n    }\n    \n    vector<unordered_map<int, int>> parent(L);\n    for (int idx = 1; idx < L; idx++) {\n        vector<pair<int, int>> newDp;\n        for (int cell : charPos[bestSuperstring[idx] - 'A']) {\n            auto [ci, cj] = getCoord(cell);\n            int minCost = INT_MAX, bestPrev = -1;\n            for (auto& [prevCell, cost] : dp) {\n                auto [pi, pj] = getCoord(prevCell);\n                int newCost = cost + abs(ci - pi) + abs(cj - pj) + 1;\n                if (newCost < minCost) { minCost = newCost; bestPrev = prevCell; }\n            }\n            if (bestPrev != -1) {\n                newDp.emplace_back(cell, minCost);\n                parent[idx][cell] = bestPrev;\n            }\n        }\n        if (newDp.size() > 100) {\n            sort(newDp.begin(), newDp.end(), [](auto& a, auto& b) { return a.second < b.second; });\n            newDp.resize(100);\n        }\n        dp = move(newDp);\n    }\n    \n    int endCell = min_element(dp.begin(), dp.end(), [](auto& a, auto& b) { return a.second < b.second; })->first;\n    vector<int> path(L);\n    path[L - 1] = endCell;\n    for (int idx = L - 2; idx >= 0; idx--)\n        path[idx] = parent[idx + 1][path[idx + 1]];\n    \n    for (int cell : path) {\n        auto [i, j] = getCoord(cell);\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<set<pair<int,int>>> shapes;\nvector<vector<int>> obs;\nint Q = 0;\n\npair<int,int> getBB(int k) {\n    int maxI = 0, maxJ = 0;\n    for (auto& p : shapes[k]) {\n        maxI = max(maxI, p.first);\n        maxJ = max(maxJ, p.second);\n    }\n    return {maxI, maxJ};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> eps;\n    shapes.resize(M);\n    obs.assign(N, vector<int>(N, -1));\n    \n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        for (int i = 0; i < d; i++) {\n            int r, c; cin >> r >> c;\n            shapes[k].insert({r, c});\n        }\n    }\n    \n    auto drill = [&](int i, int j) -> int {\n        if (obs[i][j] != -1) return obs[i][j];\n        if (Q >= 2*N*N - 1) return -1;\n        cout << \"q 1 \" << i << \" \" << j << endl;\n        int r; cin >> r;\n        obs[i][j] = r;\n        Q++;\n        return r;\n    };\n    \n    // Main drilling loop\n    while (Q < N * N) {\n        // For each oil field, compute valid placements\n        vector<vector<pair<int,int>>> validPlacements(M);\n        for (int k = 0; k < M; k++) {\n            auto [maxI, maxJ] = getBB(k);\n            for (int di = 0; di <= N-1-maxI; di++) {\n                for (int dj = 0; dj <= N-1-maxJ; dj++) {\n                    bool ok = true;\n                    for (auto& p : shapes[k]) {\n                        if (obs[p.first + di][p.second + dj] == 0) {\n                            ok = false;\n                            break;\n                        }\n                    }\n                    if (ok) validPlacements[k].push_back({di, dj});\n                }\n            }\n        }\n        \n        // For each unknown square, compute coverage count\n        vector<tuple<int,int,int>> toDrill; // (score, i, j)\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (obs[i][j] != -1) continue;\n                \n                bool guaranteedOil = false;\n                int coverCount = 0;\n                \n                for (int k = 0; k < M; k++) {\n                    if (validPlacements[k].empty()) continue;\n                    bool allCover = true;\n                    bool anyCover = false;\n                    for (auto& [di, dj] : validPlacements[k]) {\n                        if (shapes[k].count({i-di, j-dj})) {\n                            anyCover = true;\n                            coverCount++;\n                        } else {\n                            allCover = false;\n                        }\n                    }\n                    if (allCover) guaranteedOil = true;\n                }\n                \n                if (!guaranteedOil && coverCount > 0) {\n                    toDrill.push_back({coverCount, i, j});\n                }\n            }\n        }\n        \n        if (toDrill.empty()) break;\n        \n        // Drill square with highest coverage (max info gain)\n        sort(toDrill.rbegin(), toDrill.rend());\n        auto [score, bi, bj] = toDrill[0];\n        if (drill(bi, bj) == -1) break;\n    }\n    \n    // Answer loop with retries\n    while (true) {\n        // Compute valid placements\n        vector<vector<pair<int,int>>> validPlacements(M);\n        for (int k = 0; k < M; k++) {\n            auto [maxI, maxJ] = getBB(k);\n            for (int di = 0; di <= N-1-maxI; di++) {\n                for (int dj = 0; dj <= N-1-maxJ; dj++) {\n                    bool ok = true;\n                    for (auto& p : shapes[k]) {\n                        if (obs[p.first + di][p.second + dj] == 0) {\n                            ok = false;\n                            break;\n                        }\n                    }\n                    if (ok) validPlacements[k].push_back({di, dj});\n                }\n            }\n        }\n        \n        // Determine oil squares\n        set<pair<int,int>> oil;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (obs[i][j] > 0) {\n                    oil.insert({i, j});\n                } else if (obs[i][j] == -1) {\n                    for (int k = 0; k < M; k++) {\n                        if (validPlacements[k].empty()) continue;\n                        bool allCover = true;\n                        for (auto& [di, dj] : validPlacements[k]) {\n                            if (!shapes[k].count({i-di, j-dj})) {\n                                allCover = false;\n                                break;\n                            }\n                        }\n                        if (allCover) {\n                            oil.insert({i, j});\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        vector<pair<int,int>> ans(oil.begin(), oil.end());\n        cout << \"a \" << ans.size();\n        for (auto& p : ans) cout << \" \" << p.first << \" \" << p.second;\n        cout << endl;\n        \n        int r; cin >> r;\n        if (r == 1) break;\n        \n        // Wrong - drill an unknown square\n        bool found = false;\n        for (int i = 0; i < N && !found; i++) {\n            for (int j = 0; j < N && !found; j++) {\n                if (obs[i][j] == -1) {\n                    drill(i, j);\n                    found = true;\n                }\n            }\n        }\n        if (!found) break;\n    }\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    vector<vector<array<int, 4>>> rect(D, vector<array<int, 4>>(N));\n    vector<int> prevCum(N + 1, 0);\n    \n    for (int d = 0; d < D; d++) {\n        bool reused = false;\n        if (d > 0) {\n            bool ok = true;\n            for (int k = 0; k < N; k++) {\n                int hk = prevCum[k + 1] - prevCum[k];\n                if ((long long)hk * W < a[d][k]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) reused = true;\n        }\n        \n        vector<int> h(N);\n        if (reused) {\n            for (int k = 0; k < N; k++) {\n                h[k] = prevCum[k + 1] - prevCum[k];\n            }\n        } else {\n            // Start with minimum heights needed\n            for (int k = 0; k < N; k++) {\n                h[k] = max(1, (a[d][k] + W - 1) / W);\n            }\n            \n            int totalH = accumulate(h.begin(), h.end(), 0);\n            \n            if (totalH > W) {\n                // Must reduce heights - minimize deficit increase\n                // Reduce from rectangles with largest waste (excess area)\n                int reduce = totalH - W;\n                priority_queue<pair<long long, int>> pq;\n                for (int k = 0; k < N; k++) {\n                    long long waste = (long long)h[k] * W - a[d][k];\n                    pq.push({waste, k});\n                }\n                \n                while (reduce > 0 && !pq.empty()) {\n                    auto [waste, k] = pq.top(); pq.pop();\n                    if (h[k] > 1) {\n                        h[k]--;\n                        reduce--;\n                        long long newWaste = (long long)h[k] * W - a[d][k];\n                        pq.push({newWaste, k});\n                    }\n                }\n            } else if (totalH < W) {\n                // Have extra height to distribute\n                int rem = W - totalH;\n                \n                // First eliminate remaining deficits\n                priority_queue<pair<long long, int>> pq;\n                for (int k = 0; k < N; k++) {\n                    long long def = max(0LL, (long long)a[d][k] - (long long)h[k] * W);\n                    pq.push({def, k});\n                }\n                \n                while (rem > 0 && !pq.empty() && pq.top().first > 0) {\n                    auto [def, k] = pq.top(); pq.pop();\n                    h[k]++;\n                    rem--;\n                    long long newDef = max(0LL, (long long)a[d][k] - (long long)h[k] * W);\n                    pq.push({newDef, k});\n                }\n                \n                // Then match previous partition positions\n                if (rem > 0) {\n                    if (d == 0) {\n                        h[N - 1] += rem;\n                    } else {\n                        vector<int> cum(N + 1);\n                        for (int k = 0; k < N; k++) cum[k + 1] = cum[k] + h[k];\n                        \n                        while (rem > 0) {\n                            int bestK = N - 1;\n                            long long bestImp = LLONG_MIN;\n                            for (int k = 0; k < N; k++) {\n                                long long imp = 0;\n                                for (int j = k + 1; j < N; j++) {\n                                    imp += abs(cum[j] - prevCum[j]) - abs(cum[j] + 1 - prevCum[j]);\n                                }\n                                if (imp > bestImp) {\n                                    bestImp = imp;\n                                    bestK = k;\n                                }\n                            }\n                            h[bestK]++;\n                            for (int j = bestK + 1; j <= N; j++) cum[j]++;\n                            rem--;\n                        }\n                    }\n                }\n            }\n        }\n        \n        int y = 0;\n        for (int k = 0; k < N; k++) {\n            rect[d][k] = {y, 0, y + h[k], W};\n            y += h[k];\n        }\n        \n        prevCum[0] = 0;\n        for (int k = 0; k < N; k++) prevCum[k + 1] = prevCum[k] + h[k];\n    }\n    \n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << rect[d][k][0] << \" \" << rect[d][k][1] << \" \"\n                 << rect[d][k][2] << \" \" << rect[d][k][3] << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <random>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\nconst long long MOD = 998244353;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nlong long board[N][N];\nlong long stamps[M][3][3];\nlong long cur[N][N];\ndouble weight[N][N];\nlong long bestScore = 0;\nvector<tuple<int, int, int>> bestOps;\n\nvoid initWeights() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            int cnt = 0;\n            for (int p = max(0, i - 2); p <= min(N - 3, i); p++)\n                for (int q = max(0, j - 2); q <= min(N - 3, j); q++)\n                    cnt++;\n            weight[i][j] = 9.0 / cnt;\n        }\n}\n\ninline long long calcGain(int s, int p, int q) {\n    long long g = 0;\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 3; j++) {\n            long long oldR = cur[p + i][q + j] % MOD;\n            long long newR = (cur[p + i][q + j] + stamps[s][i][j]) % MOD;\n            g += newR - oldR;\n        }\n    return g;\n}\n\ninline double calcWeightedGain(int s, int p, int q) {\n    double g = 0;\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 3; j++) {\n            long long oldR = cur[p + i][q + j] % MOD;\n            long long newR = (cur[p + i][q + j] + stamps[s][i][j]) % MOD;\n            g += (newR - oldR) * weight[p + i][q + j];\n        }\n    return g;\n}\n\ninline void apply(int s, int p, int q) {\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 3; j++)\n            cur[p + i][q + j] += stamps[s][i][j];\n}\n\ninline void unapply(int s, int p, int q) {\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 3; j++)\n            cur[p + i][q + j] -= stamps[s][i][j];\n}\n\ninline long long getScore() {\n    long long s = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            s += cur[i][j] % MOD;\n    return s;\n}\n\nvoid greedy(mt19937& rng, int topK, bool useWeight) {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cur[i][j] = board[i][j];\n    \n    vector<tuple<int, int, int>> ops;\n    \n    while ((int)ops.size() < K) {\n        vector<tuple<double, long long, int, int, int>> cands;\n        for (int s = 0; s < M; s++)\n            for (int p = 0; p <= N - 3; p++)\n                for (int q = 0; q <= N - 3; q++) {\n                    long long g = calcGain(s, p, q);\n                    if (g > 0) {\n                        double wg = useWeight ? calcWeightedGain(s, p, q) : g;\n                        cands.emplace_back(wg, g, s, p, q);\n                    }\n                }\n        if (cands.empty()) break;\n        \n        partial_sort(cands.begin(), cands.begin() + min(topK, (int)cands.size()), \n                     cands.end(), greater<>());\n        int idx = rng() % min(topK, (int)cands.size());\n        auto [wg, g, s, p, q] = cands[idx];\n        ops.emplace_back(s, p, q);\n        apply(s, p, q);\n    }\n    \n    long long score = getScore();\n    if (score > bestScore) {\n        bestScore = score;\n        bestOps = ops;\n    }\n}\n\nvoid improveSolution() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cur[i][j] = board[i][j];\n    for (auto [s, p, q] : bestOps) apply(s, p, q);\n    \n    while ((int)bestOps.size() < K) {\n        long long bestGain = 0;\n        int bestS = -1, bestP = -1, bestQ = -1;\n        for (int s = 0; s < M; s++)\n            for (int p = 0; p <= N - 3; p++)\n                for (int q = 0; q <= N - 3; q++) {\n                    long long g = calcGain(s, p, q);\n                    if (g > bestGain) { bestGain = g; bestS = s; bestP = p; bestQ = q; }\n                }\n        if (bestGain <= 0) break;\n        bestOps.emplace_back(bestS, bestP, bestQ);\n        apply(bestS, bestP, bestQ);\n    }\n    bestScore = getScore();\n}\n\nvoid localSearch(mt19937& rng) {\n    if (bestOps.empty()) return;\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cur[i][j] = board[i][j];\n    for (auto [s, p, q] : bestOps) apply(s, p, q);\n    \n    long long score = bestScore;\n    \n    for (int iter = 0; iter < 10000; iter++) {\n        int moveType = rng() % 10;\n        \n        if (moveType < 6 && (int)bestOps.size() < K) {\n            // Add\n            int s = rng() % M, p = rng() % 7, q = rng() % 7;\n            long long g = calcGain(s, p, q);\n            if (g > 0) {\n                bestOps.emplace_back(s, p, q);\n                apply(s, p, q);\n                score += g;\n                if (score > bestScore) bestScore = score;\n            }\n        } else if (moveType < 8 && !bestOps.empty()) {\n            // Remove\n            int idx = rng() % bestOps.size();\n            auto [s, p, q] = bestOps[idx];\n            unapply(s, p, q);\n            long long newScore = getScore();\n            if (newScore >= score) {\n                bestOps.erase(bestOps.begin() + idx);\n                score = newScore;\n                if (score > bestScore) bestScore = score;\n            } else {\n                apply(s, p, q);\n            }\n        } else if (!bestOps.empty()) {\n            // Replace\n            int idx = rng() % bestOps.size();\n            auto [oldS, oldP, oldQ] = bestOps[idx];\n            int newS = rng() % M, newP = rng() % 7, newQ = rng() % 7;\n            \n            unapply(oldS, oldP, oldQ);\n            apply(newS, newP, newQ);\n            long long newScore = getScore();\n            \n            if (newScore > score) {\n                bestOps[idx] = {newS, newP, newQ};\n                score = newScore;\n                if (score > bestScore) bestScore = score;\n            } else {\n                unapply(newS, newP, newQ);\n                apply(oldS, oldP, oldQ);\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    initWeights();\n    \n    int n, m, k;\n    cin >> n >> m >> k;\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cin >> board[i][j];\n    \n    for (int s = 0; s < M; s++)\n        for (int i = 0; i < 3; i++)\n            for (int j = 0; j < 3; j++)\n                cin >> stamps[s][i][j];\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cur[i][j] = board[i][j];\n    bestScore = getScore();\n    \n    mt19937 rng(42);\n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    \n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() < 1850) {\n        int topK = 1 + (iter % 5);\n        bool useWeight = (iter % 3 == 0);\n        greedy(rng, topK, useWeight);\n        \n        if (iter % 20 == 0) localSearch(rng);\n        iter++;\n    }\n    \n    improveSolution();\n    localSearch(rng);\n    \n    cout << bestOps.size() << \"\\n\";\n    for (auto [s, p, q] : bestOps)\n        cout << s << \" \" << p << \" \" << q << \"\\n\";\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N], G[N][N], CR[N], CC[N], CH[N], RI[N], DN[N];\n\nbool hasCrane(int r, int c, int ex = -1) {\n    for (int i = 0; i < N; i++) if (i != ex && CR[i] == r && CC[i] == c) return true;\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> A[i][j];\n    memset(G, -1, sizeof(G));\n    for (int i = 0; i < N; i++) { CR[i] = i; CC[i] = 0; CH[i] = -1; RI[i] = 0; DN[i] = i * N; }\n    vector<string> O(N, \"\");\n    \n    for (int T = 0; T < 10000; T++) {\n        string act(N, '.');\n        \n        // Step 1: Receive containers at column 0\n        for (int i = 0; i < N; i++) {\n            if (RI[i] < N && G[i][0] < 0) {\n                bool blocked = false;\n                for (int j = 0; j < N; j++) \n                    if (CR[j] == i && CC[j] == 0 && CH[j] >= 0) blocked = true;\n                if (!blocked) G[i][0] = A[i][RI[i]++];\n            }\n        }\n        \n        // Step 2: Decide actions\n        int NR[N], NC[N];\n        for (int i = 0; i < N; i++) { NR[i] = CR[i]; NC[i] = CC[i]; }\n        \n        for (int i = 0; i < N; i++) {\n            if (CH[i] >= 0) {\n                int tr = CH[i] / N; // Target row\n                bool next = (CH[i] == DN[tr]);\n                // Move toward dispatch or storage\n                if (CR[i] != tr) {\n                    int dr = (CR[i] < tr) ? 1 : -1;\n                    int nr = CR[i] + dr;\n                    if (!hasCrane(nr, CC[i], i) && (i == 0 || G[nr][CC[i]] < 0)) {\n                        act[i] = (dr > 0) ? 'D' : 'U'; NR[i] = nr;\n                    }\n                } else if (CC[i] < N-1) {\n                    int nc = CC[i] + 1;\n                    bool cango = !hasCrane(CR[i], nc, i) && (i == 0 || G[CR[i]][nc] < 0);\n                    // Can always reach dispatch gate if target is next\n                    if (cango || (next && nc == N-1 && !hasCrane(CR[i], nc, i))) {\n                        act[i] = 'R'; NC[i] = nc;\n                    }\n                } else if (CC[i] == N-1 && G[CR[i]][CC[i]] < 0) {\n                    act[i] = 'Q';\n                }\n            } else if (G[CR[i]][CC[i]] >= 0) {\n                act[i] = 'P';\n            } else if (CC[i] > 0) {\n                int nc = CC[i] - 1;\n                if (!hasCrane(CR[i], nc, i)) { act[i] = 'L'; NC[i] = nc; }\n            }\n        }\n        \n        // Collision resolution\n        for (int it = 0; it < 3; it++)\n            for (int i = 0; i < N; i++) for (int j = i+1; j < N; j++) {\n                if (NR[i] == NR[j] && NC[i] == NC[j]) { act[j] = '.'; NR[j] = CR[j]; NC[j] = CC[j]; }\n                if (CR[i] == NR[j] && CC[i] == NC[j] && CR[j] == NR[i] && CC[j] == NC[i]) \n                    { act[j] = '.'; NR[j] = CR[j]; NC[j] = CC[j]; }\n            }\n        \n        // Apply actions\n        for (int i = 0; i < N; i++) {\n            if (act[i] == 'P' && CH[i] < 0 && G[CR[i]][CC[i]] >= 0) { CH[i] = G[CR[i]][CC[i]]; G[CR[i]][CC[i]] = -1; }\n            else if (act[i] == 'Q' && CH[i] >= 0 && G[CR[i]][CC[i]] < 0) { G[CR[i]][CC[i]] = CH[i]; CH[i] = -1; }\n            else if (act[i] == 'R') CC[i]++;\n            else if (act[i] == 'L') CC[i]--;\n            else if (act[i] == 'U') CR[i]--;\n            else if (act[i] == 'D') CR[i]++;\n        }\n        \n        // Step 3: Dispatch\n        for (int i = 0; i < N; i++) if (G[i][N-1] >= 0) {\n            int c = G[i][N-1];\n            if (c >= i*N && c < (i+1)*N && c == DN[i]) DN[i]++;\n            G[i][N-1] = -1;\n        }\n        \n        for (int i = 0; i < N; i++) O[i] += act[i];\n        \n        bool done = true;\n        for (int i = 0; i < N; i++) if (RI[i] < N) done = false;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (G[i][j] >= 0) done = false;\n        for (int i = 0; i < N; i++) if (CH[i] >= 0) done = false;\n        if (done) break;\n    }\n    \n    for (int i = 0; i < N; i++) cout << O[i] << \"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\n\nint dist(int i1, int j1, int i2, int j2) {\n    return abs(i1 - i2) + abs(j1 - j2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cin >> h[i][j];\n    \n    vector<string> ops;\n    long long truck_load = 0;\n    int cur_i = 0, cur_j = 0;\n    \n    auto move_to = [&](int ni, int nj) {\n        while (cur_i < ni) { ops.push_back(\"D\"); cur_i++; }\n        while (cur_i > ni) { ops.push_back(\"U\"); cur_i--; }\n        while (cur_j < nj) { ops.push_back(\"R\"); cur_j++; }\n        while (cur_j > nj) { ops.push_back(\"L\"); cur_j--; }\n    };\n    \n    while (true) {\n        vector<pair<int, int>> sources, sinks;\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) {\n                if (h[i][j] > 0) sources.push_back({i, j});\n                if (h[i][j] < 0) sinks.push_back({i, j});\n            }\n        \n        if (sources.empty() && sinks.empty()) break;\n        \n        if (truck_load == 0 && !sources.empty()) {\n            long long best_cost = LLONG_MAX;\n            int best_i = -1, best_j = -1;\n            \n            for (auto& [si, sj] : sources) {\n                int amt = h[si][sj];\n                int d_empty = dist(cur_i, cur_j, si, sj);\n                \n                int d_loaded = INT_MAX;\n                for (auto& [ti, tj] : sinks) {\n                    d_loaded = min(d_loaded, dist(si, sj, ti, tj));\n                }\n                if (d_loaded == INT_MAX) d_loaded = 0;\n                \n                long long cost = 100LL * d_empty + (100LL + amt) * d_loaded;\n                \n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_i = si; best_j = sj;\n                }\n            }\n            \n            if (best_i == -1) break;\n            move_to(best_i, best_j);\n            int amt = h[best_i][best_j];\n            ops.push_back(\"+\" + to_string(amt));\n            h[best_i][best_j] = 0;\n            truck_load += amt;\n            \n            // Chain nearby sources - adaptive threshold based on load\n            while (truck_load > 0) {\n                int best_d = INT_MAX, ni = -1, nj = -1;\n                for (int i = 0; i < N; i++)\n                    for (int j = 0; j < N; j++)\n                        if (h[i][j] > 0) {\n                            int d = dist(cur_i, cur_j, i, j);\n                            if (d < best_d) { best_d = d; ni = i; nj = j; }\n                        }\n                int sink_d = INT_MAX;\n                for (int i = 0; i < N; i++)\n                    for (int j = 0; j < N; j++)\n                        if (h[i][j] < 0) sink_d = min(sink_d, dist(cur_i, cur_j, i, j));\n                \n                // Be more aggressive when load is low (cheaper to move)\n                int threshold = (truck_load <= 50) ? 3 : 2;\n                \n                if (ni >= 0 && best_d <= threshold && best_d < sink_d) {\n                    move_to(ni, nj);\n                    int amt2 = h[ni][nj];\n                    ops.push_back(\"+\" + to_string(amt2));\n                    h[ni][nj] = 0;\n                    truck_load += amt2;\n                } else break;\n            }\n        } else if (truck_load > 0 && !sinks.empty()) {\n            int best_d = INT_MAX, best_i = -1, best_j = -1;\n            \n            for (auto& [ti, tj] : sinks) {\n                int d = dist(cur_i, cur_j, ti, tj);\n                if (d < best_d) { best_d = d; best_i = ti; best_j = tj; }\n            }\n            \n            if (best_i == -1) break;\n            move_to(best_i, best_j);\n            int amt = min(truck_load, (long long)-h[best_i][best_j]);\n            ops.push_back(\"-\" + to_string(amt));\n            h[best_i][best_j] += amt;\n            truck_load -= amt;\n            \n            // Chain nearby sinks - more aggressive when load is low\n            while (truck_load > 0) {\n                int best_d2 = INT_MAX, ni = -1, nj = -1;\n                for (int i = 0; i < N; i++)\n                    for (int j = 0; j < N; j++)\n                        if (h[i][j] < 0) {\n                            int d = dist(cur_i, cur_j, i, j);\n                            if (d < best_d2) { best_d2 = d; ni = i; nj = j; }\n                        }\n                int threshold = (truck_load <= 50) ? 3 : 2;\n                if (ni >= 0 && best_d2 <= threshold) {\n                    move_to(ni, nj);\n                    int amt2 = min(truck_load, (long long)-h[ni][nj]);\n                    ops.push_back(\"-\" + to_string(amt2));\n                    h[ni][nj] += amt2;\n                    truck_load -= amt2;\n                } else break;\n            }\n        } else break;\n    }\n    \n    for (auto& s : ops) cout << s << \"\\n\";\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n    const int seed_count = 2 * N * (N - 1);\n    const int grid_size = N * N;\n    vector<vector<int>> X(seed_count, vector<int>(M));\n    \n    for (int i = 0; i < seed_count; i++)\n        for (int j = 0; j < M; j++)\n            cin >> X[i][j];\n    \n    mt19937 rng(42);\n    uniform_int_distribution<int> distPos(0, grid_size - 1);\n    uniform_real_distribution<double> uni(0, 1);\n    \n    for (int t = 0; t < T; t++) {\n        // Select top seeds by total value\n        vector<int> order(seed_count);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            int sa = 0, sb = 0;\n            for (int l = 0; l < M; l++) { sa += X[a][l]; sb += X[b][l]; }\n            return sa > sb;\n        });\n        \n        vector<int> flat(order.begin(), order.begin() + grid_size);\n        \n        auto pot = [&](int a, int b) -> int {\n            int p = 0;\n            for (int l = 0; l < M; l++) p += max(X[a][l], X[b][l]);\n            return p;\n        };\n        \n        auto contrib = [&](int idx) -> int {\n            int i = idx / N, j = idx % N, c = 0;\n            int seed = flat[idx];\n            if (j > 0) c += pot(seed, flat[idx - 1]);\n            if (j < N - 1) c += pot(seed, flat[idx + 1]);\n            if (i > 0) c += pot(seed, flat[idx - N]);\n            if (i < N - 1) c += pot(seed, flat[idx + N]);\n            return c;\n        };\n        \n        int currentScore = 0;\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N - 1; j++) currentScore += pot(flat[i*N+j], flat[i*N+j+1]);\n        for (int i = 0; i < N - 1; i++)\n            for (int j = 0; j < N; j++) currentScore += pot(flat[i*N+j], flat[(i+1)*N+j]);\n        \n        int bestScore = currentScore;\n        vector<int> bestFlat = flat;\n        \n        // Simulated annealing with multiple phases\n        for (int phase = 0; phase < 4; phase++) {\n            double temp = 80.0 / (phase + 1);\n            for (int iter = 0; iter < 150000; iter++) {\n                int p1 = distPos(rng), p2 = distPos(rng);\n                if (p1 == p2) continue;\n                \n                int r1 = p1/N, c1 = p1%N, r2 = p2/N, c2 = p2%N;\n                bool adj = (abs(r1-r2)==1 && c1==c2) || (abs(c1-c2)==1 && r1==r2);\n                \n                int old = contrib(p1) + contrib(p2);\n                if (adj) old -= pot(flat[p1], flat[p2]);\n                \n                swap(flat[p1], flat[p2]);\n                \n                int nw = contrib(p1) + contrib(p2);\n                if (adj) nw -= pot(flat[p1], flat[p2]);\n                \n                int delta = nw - old;\n                \n                if (delta > 0 || uni(rng) < exp(delta / temp)) {\n                    currentScore += delta;\n                    if (currentScore > bestScore) {\n                        bestScore = currentScore;\n                        bestFlat = flat;\n                    }\n                } else {\n                    swap(flat[p1], flat[p2]);\n                }\n                temp *= 0.99995;\n            }\n            // Restart from best for next phase\n            flat = bestFlat;\n            currentScore = bestScore;\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << bestFlat[i * N + j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n        \n        for (int i = 0; i < seed_count; i++)\n            for (int j = 0; j < M; j++)\n                cin >> X[i][j];\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<string> S, T;\n\nconst int DX[] = {1, 0, -1, 0};\nconst int DY[] = {0, 1, 0, -1};\nconst char DIR_C[] = \"RDLU\";\n\nstruct Robot {\n    int V;\n    vector<int> par, len;\n    vector<vector<int>> child;\n    vector<int> leaves;\n    int rx, ry;\n    vector<int> edir;\n    \n    void init(int v) {\n        V = v;\n        par.resize(V, -1); len.resize(V); child.resize(V); edir.resize(V, 0);\n    }\n    \n    void build() {\n        int nb = min(V - 1, 4);\n        int blen = max(2, N / 4);\n        for (int i = 1; i <= nb && i < V; i++) {\n            par[i] = 0; len[i] = blen; child[0].push_back(i);\n        }\n        for (int i = nb + 1; i < V; i++) {\n            par[i] = (i - 2) % nb + 1; len[i] = 2;\n            child[par[i]].push_back(i);\n        }\n        for (int i = 0; i < V; i++) if (child[i].empty()) leaves.push_back(i);\n    }\n    \n    pair<int,int> pos(int v) const {\n        if (par[v] < 0) return {rx, ry};\n        auto [px, py] = pos(par[v]);\n        return {px + DX[edir[v]] * len[v], py + DY[edir[v]] * len[v]};\n    }\n    \n    void rot_subtree(int u, int d) {\n        queue<int> q; q.push(u);\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            if (par[v] >= 0) edir[v] = (edir[v] + d + 4) % 4;\n            for (int c : child[v]) q.push(c);\n        }\n    }\n    void move(int d) { rx += DX[d]; ry += DY[d]; }\n};\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> V;\n    S.resize(N); T.resize(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    Robot rob; rob.init(V); rob.build();\n    \n    long long sx = 0, sy = 0, cnt = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (S[i][j] == '1') { sx += i; sy += j; cnt++; }\n    rob.rx = (cnt > 0) ? sx / cnt : N / 2;\n    rob.ry = (cnt > 0) ? sy / cnt : N / 2;\n    rob.rx = max(0, min(N - 1, rob.rx)); rob.ry = max(0, min(N - 1, rob.ry));\n    \n    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) cout << rob.par[i] << \" \" << rob.len[i] << \"\\n\";\n    cout << rob.rx << \" \" << rob.ry << \"\\n\";\n    \n    vector<vector<int>> grid(N, vector<int>(N));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) grid[i][j] = (S[i][j] == '1');\n    \n    set<pair<int,int>> usrc, utgt;\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') usrc.insert({i, j});\n        if (T[i][j] == '1' && S[i][j] == '0') utgt.insert({i, j});\n    }\n    \n    map<int, bool> hold;\n    for (int l : rob.leaves) hold[l] = false;\n    \n    auto find_nearest = [&](int x, int y, bool need_src) -> int {\n        int mn = INT_MAX;\n        if (need_src) for (auto [r, c] : usrc) if (grid[r][c] == 1) mn = min(mn, abs(x-r) + abs(y-c));\n        else for (auto [r, c] : utgt) if (grid[r][c] == 0) mn = min(mn, abs(x-r) + abs(y-c));\n        return mn;\n    };\n    \n    auto score = [&]() -> long long {\n        long long s = 0;\n        for (int l : rob.leaves) { auto [x, y] = rob.pos(l); int d = find_nearest(x, y, !hold[l]); if (d < INT_MAX) s += d; }\n        return s;\n    };\n    \n    for (int t = 0; t < 100000; t++) {\n        bool done = true;\n        for (auto [r, c] : utgt) if (grid[r][c] == 0) { done = false; break; }\n        if (done) break;\n        \n        string cmd(2 * V, '.');\n        \n        for (int l : rob.leaves) {\n            auto [x, y] = rob.pos(l);\n            if (x < 0 || x >= N || y < 0 || y >= N) continue;\n            if (!hold[l] && grid[x][y] == 1 && T[x][y] == '0') { cmd[V + l] = 'P'; hold[l] = true; grid[x][y] = 0; usrc.erase({x, y}); }\n            else if (hold[l] && grid[x][y] == 0 && T[x][y] == '1') { cmd[V + l] = 'P'; hold[l] = false; grid[x][y] = 1; utgt.erase({x, y}); }\n        }\n        \n        int bd = -1; long long bs = LLONG_MAX;\n        for (int d = 0; d < 4; d++) {\n            int nx = rob.rx + DX[d], ny = rob.ry + DY[d];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            rob.move(d); long long s = score(); rob.move((d + 2) % 4);\n            if (s < bs) { bs = s; bd = d; }\n        }\n        if (bd >= 0) { cmd[0] = DIR_C[bd]; rob.move(bd); }\n        \n        for (int u = 1; u < V; u++) {\n            auto orig = rob.edir; long long so = score();\n            rob.rot_subtree(u, 3); long long sl = score();\n            rob.edir = orig; rob.rot_subtree(u, 1); long long sr = score();\n            if (sl < so && sl <= sr) { rob.edir = orig; rob.rot_subtree(u, 3); cmd[u] = 'L'; }\n            else if (sr < so) cmd[u] = 'R';\n            else rob.edir = orig;\n        }\n        cout << cmd << \"\\n\";\n    }\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint mx[5000], my[5000], sx[5000], sy[5000];\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N;\n    for (int i = 0; i < N; i++) cin >> mx[i] >> my[i];\n    for (int i = 0; i < N; i++) cin >> sx[i] >> sy[i];\n    \n    const int MAXC = 100000;\n    int best = 0, bx1 = 0, by1 = 0, bx2 = MAXC, by2 = MAXC;\n    \n    int GS = 200;\n    int CS = (MAXC + GS - 1) / GS;\n    vector<vector<int>> diff(GS, vector<int>(GS, 0));\n    \n    for (int i = 0; i < N; i++) diff[min(mx[i]/CS, GS-1)][min(my[i]/CS, GS-1)]++;\n    for (int i = 0; i < N; i++) diff[min(sx[i]/CS, GS-1)][min(sy[i]/CS, GS-1)]--;\n    \n    vector<vector<int>> pref(GS+1, vector<int>(GS+1, 0));\n    for (int i = 0; i < GS; i++)\n        for (int j = 0; j < GS; j++)\n            pref[i+1][j+1] = diff[i][j] + pref[i][j+1] + pref[i+1][j] - pref[i][j];\n    \n    for (int x1 = 0; x1 < GS; x1++) {\n        for (int x2 = x1; x2 < GS; x2++) {\n            int minPref = 0, minIdx = -1, cs = 0;\n            for (int y2 = 0; y2 < GS; y2++) {\n                cs += pref[x2+1][y2+1] - pref[x1][y2+1] - pref[x2+1][y2] + pref[x1][y2];\n                int cur = cs - minPref;\n                if (cur > best) {\n                    best = cur;\n                    bx1 = x1 * CS; by1 = (minIdx + 1) * CS;\n                    bx2 = min((x2 + 1) * CS - 1, MAXC);\n                    by2 = min((y2 + 1) * CS - 1, MAXC);\n                }\n                if (cs < minPref) { minPref = cs; minIdx = y2; }\n            }\n        }\n    }\n    \n    auto eval = [&](int x1, int y1, int x2, int y2) {\n        int c = 0;\n        for (int i = 0; i < N; i++) {\n            if (mx[i] >= x1 && mx[i] <= x2 && my[i] >= y1 && my[i] <= y2) c++;\n            if (sx[i] >= x1 && sx[i] <= x2 && sy[i] >= y1 && sy[i] <= y2) c--;\n        }\n        return c;\n    };\n    \n    // Multi-pass refinement with focused candidates\n    for (int it = 0; it < 3; it++) {\n        // X candidates: fish whose y is in current y-range\n        vector<int> xc;\n        for (int i = 0; i < N; i++) {\n            if (my[i] >= by1 && my[i] <= by2) xc.push_back(mx[i]);\n            if (sy[i] >= by1 && sy[i] <= by2) xc.push_back(sx[i]);\n        }\n        // Y candidates: fish whose x is in current x-range  \n        vector<int> yc;\n        for (int i = 0; i < N; i++) {\n            if (mx[i] >= bx1 && mx[i] <= bx2) yc.push_back(my[i]);\n            if (sx[i] >= bx1 && sx[i] <= bx2) yc.push_back(sy[i]);\n        }\n        sort(xc.begin(), xc.end()); xc.erase(unique(xc.begin(), xc.end()), xc.end());\n        sort(yc.begin(), yc.end()); yc.erase(unique(yc.begin(), yc.end()), yc.end());\n        \n        for (int x : xc) if (x >= 0 && x <= bx2) { int v = eval(x, by1, bx2, by2); if (v > best) { best = v; bx1 = x; } }\n        for (int x : xc) if (x >= bx1 && x <= MAXC) { int v = eval(bx1, by1, x, by2); if (v > best) { best = v; bx2 = x; } }\n        for (int y : yc) if (y >= 0 && y <= by2) { int v = eval(bx1, y, bx2, by2); if (v > best) { best = v; by1 = y; } }\n        for (int y : yc) if (y >= by1 && y <= MAXC) { int v = eval(bx1, by1, bx2, y); if (v > best) { best = v; by2 = y; } }\n    }\n    \n    if (best <= 0) {\n        cout << 4 << \"\\n0 0\\n0 1\\n1 1\\n1 0\\n\";\n    } else {\n        cout << 4 << \"\\n\" << bx1 << \" \" << by1 << \"\\n\" << bx2 << \" \" << by1 << \"\\n\"\n             << bx2 << \" \" << by2 << \"\\n\" << bx1 << \" \" << by2 << \"\\n\";\n    }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, sigma;\nvector<long long> w, h;\nmt19937_64 rng(42);\n\nstruct State {\n    vector<long long> x1, y1, x2, y2;\n    long long W = 0, H = 0;\n    \n    State() { x1.resize(100); y1.resize(100); x2.resize(100); y2.resize(100); }\n    \n    void place(int i, int rot, int dir, int ref) {\n        long long width = rot ? h[i] : w[i];\n        long long height = rot ? w[i] : h[i];\n        long long x0, y0;\n        \n        if (dir == 0) { // U\n            x0 = (ref < 0) ? 0 : x2[ref];\n            y0 = 0;\n            for (int j = 0; j < i; j++)\n                if (x0 < x2[j] && x0 + width > x1[j]) y0 = max(y0, y2[j]);\n        } else { // L\n            y0 = (ref < 0) ? 0 : y2[ref];\n            x0 = 0;\n            for (int j = 0; j < i; j++)\n                if (y0 < y2[j] && y0 + height > y1[j]) x0 = max(x0, x2[j]);\n        }\n        \n        x1[i] = x0; y1[i] = y0;\n        x2[i] = x0 + width; y2[i] = y0 + height;\n        W = max(W, x2[i]); H = max(H, y2[i]);\n    }\n    \n    long long score() const { return W + H; }\n};\n\nlong long simulate(const vector<int>& rot, const vector<int>& dir, const vector<int>& ref) {\n    State s;\n    for (int i = 0; i < N; i++) s.place(i, rot[i], dir[i], ref[i]);\n    return s.score();\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T >> sigma;\n    w.resize(N); h.resize(N);\n    for (int i = 0; i < N; i++) cin >> w[i] >> h[i];\n    \n    vector<int> rot(N, 0), dir(N, 0), ref(N, -1);\n    \n    // Greedy init - for each position, try all options and pick best\n    for (int i = 1; i < N; i++) {\n        long long best = LLONG_MAX;\n        int br = 0, bd = 0, bf = -1;\n        for (int r = 0; r < 2; r++)\n            for (int d = 0; d < 2; d++)\n                for (int f = -1; f < i; f++) {\n                    rot[i] = r; dir[i] = d; ref[i] = f;\n                    long long s = simulate(rot, dir, ref);\n                    if (s < best) { best = s; br = r; bd = d; bf = f; }\n                }\n        rot[i] = br; dir[i] = bd; ref[i] = bf;\n    }\n    \n    long long curr = simulate(rot, dir, ref);\n    long long best = curr;\n    auto best_rot = rot, best_dir = dir, best_ref = ref;\n    \n    uniform_real_distribution<double> uni(0.0, 1.0);\n    \n    // Time management: use ~2.7 seconds total\n    auto start = chrono::steady_clock::now();\n    auto deadline = start + chrono::milliseconds(2700);\n    int total_iter = 0;\n    int turn = 0;\n    \n    while (turn < T) {\n        auto now = chrono::steady_clock::now();\n        auto remaining = deadline - now;\n        auto per_turn = remaining / (T - turn);\n        auto turn_end = now + per_turn;\n        \n        while (chrono::steady_clock::now() < turn_end) {\n            total_iter++;\n            double temp = max(1.0, 5e6 * pow(0.99997, total_iter));\n            \n            int idx = 1 + rng() % (N - 1);\n            int op = rng() % 4;\n            int old_r = rot[idx], old_d = dir[idx], old_f = ref[idx];\n            \n            if (op == 0) rot[idx] ^= 1;\n            else if (op == 1) dir[idx] ^= 1;\n            else if (op == 2) ref[idx] = (uni(rng) < 0.35) ? -1 : (int)(rng() % idx);\n            else { // combined move\n                if (uni(rng) < 0.5) rot[idx] ^= 1;\n                if (uni(rng) < 0.5) dir[idx] ^= 1;\n                ref[idx] = (uni(rng) < 0.35) ? -1 : (int)(rng() % idx);\n            }\n            \n            long long s = simulate(rot, dir, ref);\n            if (s <= curr || uni(rng) < exp(-(s - curr) / temp)) {\n                curr = s;\n                if (s < best) { best = s; best_rot = rot; best_dir = dir; best_ref = ref; }\n            } else {\n                rot[idx] = old_r; dir[idx] = old_d; ref[idx] = old_f;\n            }\n        }\n        \n        cout << N << \"\\n\";\n        for (int i = 0; i < N; i++)\n            cout << i << \" \" << best_rot[i] << \" \" << (best_dir[i] ? 'L' : 'U') << \" \" << best_ref[i] << \"\\n\";\n        cout.flush();\n        \n        long long Wp, Hp; cin >> Wp >> Hp;\n        turn++;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    int N, M, H; cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int& a : A) cin >> a;\n    \n    vector<vector<int>> adj(N);\n    vector<int> x(N), y(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    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    vector<int> sorted_by_beauty(N);\n    iota(sorted_by_beauty.begin(), sorted_by_beauty.end(), 0);\n    sort(sorted_by_beauty.begin(), sorted_by_beauty.end(), [&](int i, int j) { return A[i] < A[j]; });\n    \n    vector<int> best_parent(N, -1);\n    long long best_score = 0;\n    \n    auto start = chrono::steady_clock::now();\n    \n    auto solve = [&](const vector<int>& order, bool use_coords) -> pair<vector<int>, long long> {\n        vector<int> parent(N, -1), height(N, 0);\n        vector<bool> used(N, false);\n        \n        for (int v : order) {\n            int best_p = -1, best_h = 0, best_beauty = INT_MAX;\n            double best_dist = 1e18;\n            \n            for (int u : adj[v]) {\n                if (!used[u] || height[u] + 1 > H) continue;\n                int h = height[u] + 1;\n                int b = A[u];\n                double d = hypot(x[v] - x[u], y[v] - y[u]);\n                \n                if (h > best_h || (h == best_h && (b < best_beauty || (b == best_beauty && d < best_dist)))) {\n                    best_h = h;\n                    best_p = u;\n                    best_beauty = b;\n                    best_dist = d;\n                }\n            }\n            parent[v] = best_p;\n            height[v] = best_h;\n            used[v] = true;\n        }\n        \n        // Build children list\n        vector<vector<int>> children(N);\n        for (int v = 0; v < N; v++)\n            if (parent[v] != -1) children[parent[v]].push_back(v);\n        \n        // Local search - move leaves higher\n        for (int iter = 0; iter < 100; iter++) {\n            bool changed = false;\n            for (int v = 0; v < N; v++) {\n                if (!children[v].empty()) continue;\n                for (int u : adj[v]) {\n                    if (u == parent[v]) continue;\n                    if (height[u] + 1 <= H && height[u] + 1 > height[v]) {\n                        if (parent[v] != -1) {\n                            auto& c = children[parent[v]];\n                            c.erase(remove(c.begin(), c.end(), v), c.end());\n                        }\n                        parent[v] = u;\n                        height[v] = height[u] + 1;\n                        children[u].push_back(v);\n                        changed = true;\n                        break;\n                    }\n                }\n            }\n            if (!changed) break;\n        }\n        \n        long long score = 0;\n        for (int v = 0; v < N; v++) score += (long long)(height[v] + 1) * A[v];\n        return {parent, score};\n    };\n    \n    // Try multiple strategies\n    tie(best_parent, best_score) = solve(sorted_by_beauty, false);\n    \n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < 1.9) {\n        vector<int> order = sorted_by_beauty;\n        \n        // Shuffle within same-beauty groups\n        for (int i = 0, j; i < N; i = j) {\n            j = i + 1;\n            while (j < N && A[order[j]] == A[order[i]]) j++;\n            if (j - i > 1) shuffle(order.begin() + i, order.begin() + j, rng);\n        }\n        \n        bool use_coords = (rng() % 3 == 0);\n        auto [p, s] = solve(order, use_coords);\n        if (s > best_score) { best_score = s; best_parent = p; }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << best_parent[i] << \" \\n\"[i == N-1];\n    }\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <set>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nint N;\nvector<pair<int,int>> onis;\nvector<int> safe_up, safe_down, safe_left, safe_right;\n\npair<int,vector<pair<char,int>>> solve(set<int> remaining, mt19937& rng, double temperature) {\n    vector<pair<char, int>> result;\n    int total_cost = 0;\n    \n    while (!remaining.empty()) {\n        struct Op { double score; int cost; char dir; int idx; vector<int> batch; };\n        vector<Op> ops;\n        \n        for (int j = 0; j < N; j++) {\n            vector<int> batch; int max_row = -1;\n            for (int idx : remaining)\n                if (onis[idx].second == j && safe_up[idx]) {\n                    batch.push_back(idx); max_row = max(max_row, onis[idx].first);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (max_row + 1);\n                ops.push_back({(double)batch.size() / cost, cost, 'U', j, batch});\n            }\n        }\n        for (int j = 0; j < N; j++) {\n            vector<int> batch; int min_row = N;\n            for (int idx : remaining)\n                if (onis[idx].second == j && safe_down[idx]) {\n                    batch.push_back(idx); min_row = min(min_row, onis[idx].first);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (N - min_row);\n                ops.push_back({(double)batch.size() / cost, cost, 'D', j, batch});\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            vector<int> batch; int max_col = -1;\n            for (int idx : remaining)\n                if (onis[idx].first == i && safe_left[idx]) {\n                    batch.push_back(idx); max_col = max(max_col, onis[idx].second);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (max_col + 1);\n                ops.push_back({(double)batch.size() / cost, cost, 'L', i, batch});\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            vector<int> batch; int min_col = N;\n            for (int idx : remaining)\n                if (onis[idx].first == i && safe_right[idx]) {\n                    batch.push_back(idx); min_col = min(min_col, onis[idx].second);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (N - min_col);\n                ops.push_back({(double)batch.size() / cost, cost, 'R', i, batch});\n            }\n        }\n        \n        if (ops.empty()) break;\n        \n        // Sort by score (efficiency)\n        sort(ops.begin(), ops.end(), [](const Op& a, const Op& b) { return a.score > b.score; });\n        \n        // Temperature-based selection\n        int choice = 0;\n        if (temperature > 0) {\n            // Boltzmann selection\n            vector<double> probs;\n            double sum = 0;\n            int limit = min(10, (int)ops.size());\n            for (int i = 0; i < limit; i++) {\n                double p = exp((ops[i].score - ops[0].score) / temperature);\n                probs.push_back(p);\n                sum += p;\n            }\n            uniform_real_distribution<double> dist(0, sum);\n            double r = dist(rng);\n            double cum = 0;\n            for (int i = 0; i < limit; i++) {\n                cum += probs[i];\n                if (r < cum) { choice = i; break; }\n            }\n        }\n        \n        for (int oni_idx : ops[choice].batch) remaining.erase(oni_idx);\n        \n        total_cost += ops[choice].cost;\n        int shifts = ops[choice].cost / 2;\n        char dir = ops[choice].dir, rev_dir = (dir == 'U' ? 'D' : dir == 'D' ? 'U' : dir == 'L' ? 'R' : 'L');\n        for (int k = 0; k < shifts; k++) result.emplace_back(dir, ops[choice].idx);\n        for (int k = 0; k < shifts; k++) result.emplace_back(rev_dir, ops[choice].idx);\n    }\n    \n    return {total_cost, result};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j] == 'x') onis.emplace_back(i, j);\n    \n    int num_onis = onis.size();\n    safe_up.assign(num_onis, 1);\n    safe_down.assign(num_onis, 1);\n    safe_left.assign(num_onis, 1);\n    safe_right.assign(num_onis, 1);\n    \n    for (int idx = 0; idx < num_onis; idx++) {\n        auto [i, j] = onis[idx];\n        for (int fi = 0; fi < N; fi++)\n            for (int fj = 0; fj < N; fj++)\n                if (board[fi][fj] == 'o') {\n                    if (fj == j && fi < i) safe_up[idx] = 0;\n                    if (fj == j && fi > i) safe_down[idx] = 0;\n                    if (fi == i && fj < j) safe_left[idx] = 0;\n                    if (fi == i && fj > j) safe_right[idx] = 0;\n                }\n    }\n    \n    set<int> initial;\n    for (int idx = 0; idx < num_onis; idx++) initial.insert(idx);\n    \n    mt19937 rng(12345);\n    \n    auto [cost0, result0] = solve(initial, rng, 0);\n    int best_cost = cost0;\n    vector<pair<char,int>> best_result = result0;\n    \n    auto start = chrono::steady_clock::now();\n    long long iter = 0;\n    \n    while (chrono::duration_cast<chrono::microseconds>(chrono::steady_clock::now() - start).count() < 1900000) {\n        iter++;\n        double temp = 0.02 + 0.1 * (iter % 100) / 100.0;  // Varying temperature\n        auto [cost, result] = solve(initial, rng, temp);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_result = result;\n        }\n    }\n    \n    for (auto& [d, p] : best_result) cout << d << \" \" << p << \"\\n\";\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 100;\nconstexpr int L = 500000;\n\nint T[N], a[N], b[N], v[N], ba[N], bb[N];\n\nstruct RNG {\n    uint64_t s;\n    RNG(uint64_t seed = 88172645463325252ULL) : s(seed) {}\n    uint64_t next() { s ^= s << 7; s ^= s >> 9; return s; }\n    int operator()(int n) { return (int)(next() % n); }\n    double dbl() { return (double)next() / UINT64_MAX; }\n} rng;\n\ninline long long simulate() {\n    memset(v, 0, sizeof(v));\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        int t = ++v[cur];\n        cur = (t & 1) ? a[cur] : b[cur];\n    }\n    long long err = 0;\n    for (int i = 0; i < N; i++) err += abs(v[i] - T[i]);\n    return err;\n}\n\nvoid init_solution() {\n    vector<int> active;\n    for (int i = 0; i < N; i++) if (T[i] > 0) active.push_back(i);\n    if (active.empty()) active.push_back(0);\n    \n    // Sort by T[i] for potentially better distribution\n    sort(active.begin(), active.end(), [](int x, int y) { return T[x] < T[y]; });\n    \n    for (int i = 0; i < N; i++) a[i] = b[i] = active[0];\n    int sz = active.size();\n    for (int i = 0; i < sz; i++) {\n        a[active[i]] = b[active[i]] = active[(i + 1) % sz];\n    }\n}\n\nlong long sa_run(double duration_ms, uint64_t seed) {\n    rng = RNG(seed);\n    init_solution();\n    \n    long long cur = simulate(), best = cur;\n    memcpy(ba, a, sizeof(a)); memcpy(bb, b, sizeof(b));\n    \n    double temp = 50000.0;\n    auto dl = chrono::steady_clock::now() + chrono::milliseconds((long long)duration_ms);\n    int stuck = 0;\n    \n    while (chrono::steady_clock::now() < dl) {\n        int i = rng(N), oa = a[i], ob = b[i];\n        \n        int move_type = rng(100);\n        if (move_type < 40) a[i] = rng(N);\n        else if (move_type < 80) b[i] = rng(N);\n        else { a[i] = rng(N); b[i] = rng(N); }\n        \n        long long ne = simulate();\n        \n        if (ne <= cur || exp(-(double)(ne - cur) / temp) > rng.dbl()) {\n            cur = ne; stuck = 0;\n            if (ne < best) { \n                best = ne; \n                memcpy(ba, a, sizeof(a)); memcpy(bb, b, sizeof(b)); \n            }\n        } else { \n            a[i] = oa; b[i] = ob; \n            stuck++; \n        }\n        \n        if (stuck > 500) {\n            memcpy(a, ba, sizeof(a)); memcpy(b, bb, sizeof(b));\n            cur = best;\n            temp = min(50000.0, temp * 5.0);\n            stuck = 0;\n        }\n        \n        temp = max(0.5, temp * 0.99997);\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n_, L_; cin >> n_ >> L_;\n    for (int i = 0; i < N; i++) cin >> T[i];\n    \n    long long best_err = LLONG_MAX;\n    int best_a[N], best_b[N];\n    \n    // 7 SA runs for diversity\n    for (int run = 0; run < 7; run++) {\n        long long err = sa_run(240, 12345ULL + run * 7919ULL + run * run * 13ULL);\n        if (err < best_err) {\n            best_err = err;\n            memcpy(best_a, ba, sizeof(ba));\n            memcpy(best_b, bb, sizeof(bb));\n        }\n    }\n    \n    // Extended greedy refinement\n    memcpy(a, best_a, sizeof(a));\n    memcpy(b, best_b, sizeof(b));\n    long long cur = simulate();\n    auto dl = chrono::steady_clock::now() + chrono::milliseconds(210);\n    \n    while (chrono::steady_clock::now() < dl) {\n        int i = rng(N), oa = a[i], ob = b[i];\n        \n        // Try a[i]\n        a[i] = rng(N);\n        long long ne = simulate();\n        if (ne < cur) { \n            cur = ne; \n            if (ne < best_err) { best_err = ne; memcpy(best_a, a, sizeof(a)); memcpy(best_b, b, sizeof(b)); }\n        } else a[i] = oa;\n        \n        // Try b[i]\n        b[i] = rng(N);\n        ne = simulate();\n        if (ne < cur) { \n            cur = ne; \n            if (ne < best_err) { best_err = ne; memcpy(best_a, a, sizeof(a)); memcpy(best_b, b, sizeof(b)); }\n        } else b[i] = ob;\n        \n        // Try both\n        a[i] = rng(N); b[i] = rng(N);\n        ne = simulate();\n        if (ne < cur) { \n            cur = ne; \n            if (ne < best_err) { best_err = ne; memcpy(best_a, a, sizeof(a)); memcpy(best_b, b, sizeof(b)); }\n        } else { a[i] = oa; b[i] = ob; }\n    }\n    \n    for (int i = 0; i < N; i++) cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<double> cx, cy;\nvector<int> lx, rx, ly, ry;\n\nstruct UnionFind {\n    vector<int> p;\n    UnionFind(int n) : p(n) { 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 x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        p[y] = x;\n        return true;\n    }\n};\n\ninline double estDist(int i, int j) {\n    double dx = cx[i] - cx[j], dy = cy[i] - cy[j];\n    return sqrt(dx*dx + dy*dy);\n}\n\ninline int minDist(int i, int j) {\n    int dx = 0, dy = 0;\n    if (rx[i] < lx[j]) dx = lx[j] - rx[i];\n    else if (rx[j] < lx[i]) dx = lx[i] - rx[j];\n    if (ry[i] < ly[j]) dy = ly[j] - ry[i];\n    else if (ry[j] < ly[i]) dy = ly[i] - ry[j];\n    return (int)sqrt((double)dx*dx + dy*dy);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    cx.resize(N); cy.resize(N);\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i] + rx[i]) / 2.0;\n        cy[i] = (ly[i] + ry[i]) / 2.0;\n    }\n    \n    // Greedy nearest-neighbor grouping\n    vector<int> assignment(N, -1);\n    vector<vector<int>> groups(M);\n    \n    // Sort groups by size (larger groups are harder to fill optimally)\n    vector<int> groupOrder(M);\n    iota(groupOrder.begin(), groupOrder.end(), 0);\n    sort(groupOrder.begin(), groupOrder.end(), [](int a, int b) { return G[a] > G[b]; });\n    \n    for (int gIdx = 0; gIdx < M; gIdx++) {\n        int g = groupOrder[gIdx];\n        \n        // Find unassigned city closest to origin as seed\n        int seed = -1;\n        double bestDist = 1e18;\n        for (int i = 0; i < N; i++) {\n            if (assignment[i] == -1) {\n                double d = cx[i] * cx[i] + cy[i] * cy[i];\n                if (d < bestDist) {\n                    bestDist = d;\n                    seed = i;\n                }\n            }\n        }\n        \n        if (seed == -1) break;\n        assignment[seed] = g;\n        groups[g].push_back(seed);\n        \n        // Greedily add nearest unassigned city\n        while ((int)groups[g].size() < G[g]) {\n            double best = 1e18;\n            int bestCity = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (assignment[i] == -1) {\n                    for (int c : groups[g]) {\n                        double d = estDist(i, c);\n                        if (d < best) {\n                            best = d;\n                            bestCity = i;\n                        }\n                    }\n                }\n            }\n            \n            if (bestCity != -1) {\n                assignment[bestCity] = g;\n                groups[g].push_back(bestCity);\n            } else break;\n        }\n    }\n    \n    // Query each group\n    set<pair<int,int>> verifiedEdges;\n    int qUsed = 0;\n    \n    for (int g = 0; g < M && qUsed < Q; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        if (sz <= L) {\n            cout << \"? \" << sz;\n            for (int c : groups[g]) cout << \" \" << c;\n            cout << endl;\n            \n            for (int i = 0; i < sz - 1; i++) {\n                int a, b;\n                cin >> a >> b;\n                verifiedEdges.insert({min(a, b), max(a, b)});\n            }\n            qUsed++;\n        } else {\n            // Sort group members by position for better query coverage\n            sort(groups[g].begin(), groups[g].end(), [](int a, int b) {\n                return make_pair(cx[a], cy[a]) < make_pair(cx[b], cy[b]);\n            });\n            \n            for (int start = 0; start < sz - 1 && qUsed < Q; start += L - 1) {\n                int end = min(start + L, sz);\n                cout << \"? \" << (end - start);\n                for (int i = start; i < end; i++) cout << \" \" << groups[g][i];\n                cout << endl;\n                \n                for (int i = 0; i < (end - start) - 1; i++) {\n                    int a, b;\n                    cin >> a >> b;\n                    verifiedEdges.insert({min(a, b), max(a, b)});\n                }\n                qUsed++;\n            }\n        }\n    }\n    \n    // Build MST for each group\n    vector<vector<pair<int,int>>> ans(M);\n    \n    for (int g = 0; g < M; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        vector<tuple<int, double, int, int>> edges;\n        for (int i = 0; i < sz; i++) {\n            for (int j = i + 1; j < sz; j++) {\n                int ci = groups[g][i], cj = groups[g][j];\n                int minD = minDist(ci, cj);\n                double estD = estDist(ci, cj);\n                edges.push_back({minD, estD, i, j});\n            }\n        }\n        sort(edges.begin(), edges.end());\n        \n        UnionFind uf(sz);\n        for (auto& [minD, estD, i, j] : edges) {\n            if (uf.unite(i, j)) {\n                ans[g].push_back({groups[g][i], groups[g][j]});\n                if (ans[g].size() == sz - 1) break;\n            }\n        }\n    }\n    \n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        for (int i = 0; i < (int)groups[g].size(); i++) {\n            if (i > 0) cout << \" \";\n            cout << groups[g][i];\n        }\n        cout << endl;\n        for (auto& [a, b] : ans[g]) {\n            cout << a << \" \" << b << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\npair<int, int> slide_end(int r, int c, int d, const vector<vector<bool>>& blocks) {\n    while (true) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N || blocks[nr][nc]) return {r, c};\n        r = nr; c = nc;\n    }\n}\n\nint get_dir_idx(char d) {\n    for (int i = 0; i < 4; i++) if (dir_char[i] == d) return i;\n    return -1;\n}\n\nvector<pair<char, char>> bfs(int sr, int sc, int tr, int tc, const vector<vector<bool>>& blocks) {\n    if (sr == tr && sc == tc) return {};\n    \n    vector<vector<int>> dist(N, vector<int>(N, -1));\n    vector<vector<tuple<int,int,char,char>>> prev(N, vector<tuple<int,int,char,char>>(N, {-1, -1, ' ', ' '}));\n    \n    queue<pair<int,int>> q;\n    q.push({sr, sc});\n    dist[sr][sc] = 0;\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front(); q.pop();\n        if (r == tr && c == tc) {\n            vector<pair<char, char>> path;\n            int cr = tr, cc = tc;\n            while (cr != sr || cc != sc) {\n                auto [pr, pc, a, d] = prev[cr][cc];\n                path.push_back({a, d});\n                cr = pr; cc = pc;\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \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 && !blocks[nr][nc] && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1;\n                prev[nr][nc] = {r, c, 'M', dir_char[d]};\n                q.push({nr, nc});\n            }\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            auto [nr, nc] = slide_end(r, c, d, blocks);\n            if (dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1;\n                prev[nr][nc] = {r, c, 'S', dir_char[d]};\n                q.push({nr, nc});\n            }\n        }\n    }\n    return {};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M;\n    vector<pair<int, int>> targets(M);\n    for (int i = 0; i < M; i++) cin >> targets[i].first >> targets[i].second;\n    \n    vector<vector<bool>> blocks(N, vector<bool>(N, false));\n    int cr = targets[0].first, cc = targets[0].second;\n    vector<pair<char, char>> actions;\n    \n    for (int t = 1; t < M; t++) {\n        int tr = targets[t].first, tc = targets[t].second;\n        \n        // Try Alter + Slide from start position\n        bool found_quick = false;\n        for (int d1 = 0; d1 < 4 && !found_quick; d1++) {\n            int br = cr + dr[d1], bc = cc + dc[d1];\n            if (br < 0 || br >= N || bc < 0 || bc >= N || blocks[br][bc]) continue;\n            \n            blocks[br][bc] = true;\n            for (int d2 = 0; d2 < 4 && !found_quick; d2++) {\n                auto [nr, nc] = slide_end(cr, cc, d2, blocks);\n                if (nr == tr && nc == tc) {\n                    actions.push_back({'A', dir_char[d1]});\n                    actions.push_back({'S', dir_char[d2]});\n                    cr = tr; cc = tc;\n                    found_quick = true;\n                }\n            }\n            if (!found_quick) blocks[br][bc] = false;\n        }\n        \n        if (!found_quick) {\n            auto path = bfs(cr, cc, tr, tc, blocks);\n            for (auto [a, d] : path) {\n                actions.push_back({a, d});\n                int di = get_dir_idx(d);\n                if (a == 'M') { cr += dr[di]; cc += dc[di]; }\n                else if (a == 'S') tie(cr, cc) = slide_end(cr, cc, di, blocks);\n            }\n        }\n    }\n    \n    for (auto [a, d] : actions) cout << a << ' ' << d << '\\n';\n    return 0;\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> X, Y;\nvector<long long> R;\nvector<int> a, b, c, d;\nvector<vector<vector<int>>> grid;\nmt19937 rng(42);\n\nvoid buildGrid() {\n    grid.assign(100, vector<vector<int>>(100));\n    for (int i = 0; i < n; i++) {\n        for (int x = max(0, a[i]/100); x <= min(99, (c[i]-1)/100); x++) {\n            for (int y = max(0, b[i]/100); y <= min(99, (d[i]-1)/100); y++) {\n                grid[x][y].push_back(i);\n            }\n        }\n    }\n}\n\nvoid updateGrid(int i, bool add) {\n    for (int x = max(0, a[i]/100); x <= min(99, (c[i]-1)/100); x++) {\n        for (int y = max(0, b[i]/100); y <= min(99, (d[i]-1)/100); y++) {\n            if (add) grid[x][y].push_back(i);\n            else grid[x][y].erase(remove(grid[x][y].begin(), grid[x][y].end(), i), grid[x][y].end());\n        }\n    }\n}\n\ndouble getScore(int i) {\n    long long area = (long long)(c[i] - a[i]) * (d[i] - b[i]);\n    long long mn = min(R[i], area);\n    long long mx = max(R[i], area);\n    return 1.0 - pow(1.0 - (double)mn / mx, 2);\n}\n\ndouble totalScore() {\n    double s = 0;\n    for (int i = 0; i < n; i++) s += getScore(i);\n    return s;\n}\n\nvoid solve(int L, int Rb, int B, int T, vector<int> ids) {\n    if (ids.empty()) return;\n    if (ids.size() == 1) {\n        int i = ids[0];\n        a[i] = L; b[i] = B; c[i] = Rb; d[i] = T;\n        return;\n    }\n    \n    int W = Rb - L, H = T - B;\n    long long totalTarget = 0;\n    for (int i : ids) totalTarget += R[i];\n    \n    double bestCost = 1e18;\n    bool bestVertical = false;\n    vector<int> bestLeftIds, bestRightIds;\n    int bestSplit = -1;\n    \n    for (int dir = 0; dir < 2; dir++) {\n        bool vertical = (dir == 0);\n        if (vertical && W < 2) continue;\n        if (!vertical && H < 2) continue;\n        \n        vector<int> sortedIds = ids;\n        sort(sortedIds.begin(), sortedIds.end(), [&](int i, int j) {\n            return vertical ? X[i] < X[j] : Y[i] < Y[j];\n        });\n        \n        long long acc = 0;\n        for (size_t idx = 1; idx < sortedIds.size(); idx++) {\n            acc += R[sortedIds[idx - 1]];\n            \n            int leftMax = vertical ? X[sortedIds[idx - 1]] : Y[sortedIds[idx - 1]];\n            int rightMin = vertical ? X[sortedIds[idx]] : Y[sortedIds[idx]];\n            \n            if (leftMax >= rightMin) continue;\n            \n            long long leftTarget = acc;\n            long long rightTarget = totalTarget - acc;\n            \n            int minSplit = leftMax + 1;\n            int maxSplit = rightMin;\n            \n            long long bestAreaCost = LLONG_MAX;\n            int bestS = -1;\n            \n            for (int s = minSplit; s <= maxSplit; s++) {\n                long long leftArea, rightArea;\n                if (vertical) {\n                    leftArea = (long long)(s - L) * H;\n                    rightArea = (long long)(Rb - s) * H;\n                } else {\n                    leftArea = (long long)(s - B) * W;\n                    rightArea = (long long)(T - s) * W;\n                }\n                \n                long long cost = abs(leftArea - leftTarget) + abs(rightArea - rightTarget);\n                if (cost < bestAreaCost) {\n                    bestAreaCost = cost;\n                    bestS = s;\n                }\n            }\n            \n            if (bestS < 0) continue;\n            \n            if ((double)bestAreaCost < bestCost) {\n                bestCost = (double)bestAreaCost;\n                bestVertical = vertical;\n                bestLeftIds = vector<int>(sortedIds.begin(), sortedIds.begin() + idx);\n                bestRightIds = vector<int>(sortedIds.begin() + idx, sortedIds.end());\n                bestSplit = bestS;\n            }\n        }\n    }\n    \n    if (bestSplit < 0) {\n        bool vertical = (W >= H);\n        vector<int> sortedIds = ids;\n        sort(sortedIds.begin(), sortedIds.end(), [&](int i, int j) {\n            return vertical ? X[i] < X[j] : Y[i] < Y[j];\n        });\n        \n        size_t splitIdx = sortedIds.size() / 2;\n        bestLeftIds = vector<int>(sortedIds.begin(), sortedIds.begin() + splitIdx);\n        bestRightIds = vector<int>(sortedIds.begin() + splitIdx, sortedIds.end());\n        bestVertical = vertical;\n        \n        int leftMax = 0, rightMin = 10000;\n        for (int i : bestLeftIds) leftMax = max(leftMax, vertical ? X[i] : Y[i]);\n        for (int i : bestRightIds) rightMin = min(rightMin, vertical ? X[i] : Y[i]);\n        \n        bestSplit = (leftMax + rightMin + 1) / 2;\n        if (vertical) bestSplit = max(L + 1, min(Rb - 1, bestSplit));\n        else bestSplit = max(B + 1, min(T - 1, bestSplit));\n    }\n    \n    if (bestVertical) {\n        solve(L, bestSplit, B, T, bestLeftIds);\n        solve(bestSplit, Rb, B, T, bestRightIds);\n    } else {\n        solve(L, Rb, B, bestSplit, bestLeftIds);\n        solve(L, Rb, bestSplit, T, bestRightIds);\n    }\n}\n\nbool checkOverlap(int i, int newA, int newB, int newC, int newD) {\n    for (int x = max(0, newA/100); x <= min(99, (newC-1)/100); x++) {\n        for (int y = max(0, newB/100); y <= min(99, (newD-1)/100); y++) {\n            for (int j : grid[x][y]) {\n                if (i != j && newA < c[j] && newC > a[j] && newB < d[j] && newD > b[j]) return true;\n            }\n        }\n    }\n    return false;\n}\n\nbool isValidFast(int i, int newA, int newB, int newC, int newD) {\n    if (newA < 0 || newB < 0 || newC > 10000 || newD > 10000) return false;\n    if (newC - newA < 1 || newD - newB < 1) return false;\n    if (X[i] < newA || X[i] >= newC || Y[i] < newB || Y[i] >= newD) return false;\n    return !checkOverlap(i, newA, newB, newC, newD);\n}\n\ndouble optimize() {\n    buildGrid();\n    \n    double bestTotal = totalScore();\n    vector<int> bestA = a, bestB = b, bestC = c, bestD = d;\n    \n    uniform_int_distribution<int> distIdx(0, n - 1);\n    uniform_real_distribution<double> distReal(0.0, 1.0);\n    \n    // SA phase\n    double temp = 3.0;\n    for (int iter = 0; iter < 500000; iter++) {\n        int i = distIdx(rng);\n        long long area = (long long)(c[i] - a[i]) * (d[i] - b[i]);\n        long long diff = abs(area - R[i]);\n        \n        int newA = a[i], newB = b[i], newC = c[i], newD = d[i];\n        double oldScore = getScore(i);\n        \n        int dir = rng() % 8;\n        int maxAmt = max(1, (int)min(200LL, diff / 40 + 5));\n        int amt = 1 + rng() % maxAmt;\n        \n        if (dir == 0) newA -= amt;\n        else if (dir == 1) newB -= amt;\n        else if (dir == 2) newC += amt;\n        else if (dir == 3) newD += amt;\n        else if (dir == 4) newA += amt;\n        else if (dir == 5) newB += amt;\n        else if (dir == 6) newC -= amt;\n        else newD -= amt;\n        \n        if (isValidFast(i, newA, newB, newC, newD)) {\n            updateGrid(i, false);\n            int oldA = a[i], oldB = b[i], oldC = c[i], oldD = d[i];\n            a[i] = newA; b[i] = newB; c[i] = newC; d[i] = newD;\n            updateGrid(i, true);\n            \n            double newScore = getScore(i);\n            double delta = newScore - oldScore;\n            \n            if (delta < 0 && distReal(rng) >= exp(delta * 250 / temp)) {\n                updateGrid(i, false);\n                a[i] = oldA; b[i] = oldB; c[i] = oldC; d[i] = oldD;\n                updateGrid(i, true);\n            } else {\n                double curTotal = totalScore();\n                if (curTotal > bestTotal) {\n                    bestTotal = curTotal;\n                    bestA = a; bestB = b; bestC = c; bestD = d;\n                }\n            }\n        }\n        \n        temp *= 0.999985;\n    }\n    \n    // Greedy phase with multiple step sizes\n    for (int stepSize : {30, 15, 8, 4, 2, 1}) {\n        for (int iter = 0; iter < 800; iter++) {\n            bool changed = false;\n            \n            vector<pair<double, int>> order;\n            for (int i = 0; i < n; i++) order.push_back({getScore(i), i});\n            sort(order.begin(), order.end());\n            \n            for (auto& p : order) {\n                int i = p.second;\n                double currentScore = getScore(i);\n                \n                for (int dir = 0; dir < 8; dir++) {\n                    int newA = a[i], newB = b[i], newC = c[i], newD = d[i];\n                    \n                    if (dir == 0) newA -= stepSize;\n                    else if (dir == 1) newB -= stepSize;\n                    else if (dir == 2) newC += stepSize;\n                    else if (dir == 3) newD += stepSize;\n                    else if (dir == 4) newA += stepSize;\n                    else if (dir == 5) newB += stepSize;\n                    else if (dir == 6) newC -= stepSize;\n                    else newD -= stepSize;\n                    \n                    if (isValidFast(i, newA, newB, newC, newD)) {\n                        updateGrid(i, false);\n                        int oldA = a[i], oldB = b[i], oldC = c[i], oldD = d[i];\n                        a[i] = newA; b[i] = newB; c[i] = newC; d[i] = newD;\n                        updateGrid(i, true);\n                        \n                        double newScore = getScore(i);\n                        if (newScore > currentScore + 1e-10) {\n                            currentScore = newScore;\n                            changed = true;\n                            double curTotal = totalScore();\n                            if (curTotal > bestTotal) {\n                                bestTotal = curTotal;\n                                bestA = a; bestB = b; bestC = c; bestD = d;\n                            }\n                        } else {\n                            updateGrid(i, false);\n                            a[i] = oldA; b[i] = oldB; c[i] = oldC; d[i] = oldD;\n                            updateGrid(i, true);\n                        }\n                    }\n                }\n            }\n            \n            if (!changed) break;\n        }\n    }\n    \n    a = bestA; b = bestB; c = bestC; d = bestD;\n    return bestTotal;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n;\n    X.resize(n); Y.resize(n); R.resize(n);\n    a.resize(n); b.resize(n); c.resize(n); d.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> X[i] >> Y[i] >> R[i];\n    }\n    \n    vector<int> ids(n);\n    iota(ids.begin(), ids.end(), 0);\n    \n    solve(0, 10000, 0, 10000, ids);\n    optimize();\n    \n    for (int i = 0; i < n; i++) {\n        cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<vector<int>> t(50, vector<int>(50)), p(50, vector<int>(50));\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) cin >> t[i][j];\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++) cin >> p[i][j];\n    \n    map<int, vector<pair<int,int>>> tileSquares;\n    for (int i = 0; i < 50; i++)\n        for (int j = 0; j < 50; j++)\n            tileSquares[t[i][j]].push_back({i, j});\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    set<int> visited;\n    string path;\n    int ci = si, cj = sj;\n    visited.insert(t[ci][cj]);\n    \n    auto& startSquares = tileSquares[t[ci][cj]];\n    if (startSquares.size() == 2) {\n        auto [oi, oj] = (startSquares[0].first == ci && startSquares[0].second == cj) \n            ? make_pair(startSquares[1].first, startSquares[1].second) \n            : make_pair(startSquares[0].first, startSquares[0].second);\n        path += (oi < ci ? 'U' : oi > ci ? 'D' : oj < cj ? 'L' : 'R');\n        ci = oi; cj = oj;\n    }\n    \n    while (true) {\n        int bestDir = -1, bestExitI = -1, bestExitJ = -1;\n        string bestTilePath;\n        double bestValue = -1e18;\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = ci + di[d], nj = cj + dj[d];\n            if (ni < 0 || ni >= 50 || nj < 0 || nj >= 50 || visited.count(t[ni][nj])) continue;\n            \n            int tileId = t[ni][nj];\n            auto& sq = tileSquares[tileId];\n            int tileScore = 0;\n            for (auto& [ti, tj] : sq) tileScore += p[ti][tj];\n            \n            for (size_t ei = 0; ei < sq.size(); ei++) {\n                int exi = sq[ei].first, exj = sq[ei].second;\n                visited.insert(tileId);\n                int future = 0;\n                for (int d2 = 0; d2 < 4; d2++) {\n                    int n2i = exi + di[d2], n2j = exj + dj[d2];\n                    if (n2i >= 0 && n2i < 50 && n2j >= 0 && n2j < 50 && !visited.count(t[n2i][n2j])) future++;\n                }\n                visited.erase(tileId);\n                \n                double value = tileScore + (future == 0 ? -1000.0 : future * 10.0);\n                string tilePath;\n                if (sq.size() == 2) {\n                    int oi = sq[1-ei].first, oj = sq[1-ei].second;\n                    if (ni == exi && nj == exj) {\n                        char to = (oi < exi ? 'U' : oi > exi ? 'D' : oj < exj ? 'L' : 'R');\n                        char back = (to == 'U' ? 'D' : to == 'D' ? 'U' : to == 'L' ? 'R' : 'L');\n                        tilePath = string(1, to) + string(1, back);\n                    } else {\n                        tilePath = string(1, (exi < ni ? 'U' : exi > ni ? 'D' : exj < nj ? 'L' : 'R'));\n                    }\n                }\n                if (value > bestValue) { bestValue = value; bestDir = d; bestExitI = exi; bestExitJ = exj; bestTilePath = tilePath; }\n            }\n        }\n        if (bestDir == -1) break;\n        visited.insert(t[ci + di[bestDir]][cj + dj[bestDir]]);\n        path += dc[bestDir]; path += bestTilePath;\n        ci = bestExitI; cj = bestExitJ;\n    }\n    cout << path << endl;\n    return 0;\n}","ahc003":"#include <iostream>\n#include <queue>\n#include <string>\n#include <tuple>\n#include <cmath>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 30;\n\ndouble h[N][N-1], v[N-1][N];\nint cnt_h[N][N-1], cnt_v[N-1][N];\n\ndouble dist[N][N];\nint prev_dir[N][N];\nbool visited[N][N];\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dc[] = {'U', 'D', 'L', 'R'};\n\nstring dijkstra(int si, int sj, int ti, int tj, double exploration) {\n    memset(visited, 0, sizeof(visited));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            dist[i][j] = 1e18;\n    \n    auto get_cost = [&](int type, int i, int j, int cnt) -> double {\n        double mean = (type == 0) ? h[i][j] : v[i][j];\n        return mean - exploration * sqrt(mean / 5000.0) / sqrt(cnt + 1);\n    };\n    \n    priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<tuple<double, int, int>>> pq;\n    dist[si][sj] = 0;\n    pq.push(make_tuple(0.0, si, sj));\n    \n    while (!pq.empty()) {\n        double d = get<0>(pq.top());\n        int i = get<1>(pq.top());\n        int j = get<2>(pq.top());\n        pq.pop();\n        \n        if (visited[i][j]) continue;\n        visited[i][j] = true;\n        if (i == ti && j == tj) break;\n        \n        if (i > 0 && !visited[i-1][j]) {\n            double c = get_cost(1, i-1, j, cnt_v[i-1][j]);\n            if (dist[i-1][j] > d + c) { dist[i-1][j] = d + c; prev_dir[i-1][j] = 0; pq.push(make_tuple(dist[i-1][j], i-1, j)); }\n        }\n        if (i < N-1 && !visited[i+1][j]) {\n            double c = get_cost(1, i, j, cnt_v[i][j]);\n            if (dist[i+1][j] > d + c) { dist[i+1][j] = d + c; prev_dir[i+1][j] = 1; pq.push(make_tuple(dist[i+1][j], i+1, j)); }\n        }\n        if (j > 0 && !visited[i][j-1]) {\n            double c = get_cost(0, i, j-1, cnt_h[i][j-1]);\n            if (dist[i][j-1] > d + c) { dist[i][j-1] = d + c; prev_dir[i][j-1] = 2; pq.push(make_tuple(dist[i][j-1], i, j-1)); }\n        }\n        if (j < N-1 && !visited[i][j+1]) {\n            double c = get_cost(0, i, j, cnt_h[i][j]);\n            if (dist[i][j+1] > d + c) { dist[i][j+1] = d + c; prev_dir[i][j+1] = 3; pq.push(make_tuple(dist[i][j+1], i, j+1)); }\n        }\n    }\n    \n    string path = \"\";\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int dir = prev_dir[ci][cj];\n        path = dc[dir] + path;\n        ci -= di[dir];\n        cj -= dj[dir];\n    }\n    return path;\n}\n\nvoid update_estimates(const string& path, int si, int sj, int observed) {\n    double estimated_sum = 0;\n    int ci = si, cj = sj;\n    for (char c : path) {\n        int dir = (c == 'U') ? 0 : (c == 'D') ? 1 : (c == 'L') ? 2 : 3;\n        if (dir == 0) { estimated_sum += v[ci-1][cj]; ci--; }\n        else if (dir == 1) { estimated_sum += v[ci][cj]; ci++; }\n        else if (dir == 2) { estimated_sum += h[ci][cj-1]; cj--; }\n        else { estimated_sum += h[ci][cj]; cj++; }\n    }\n    \n    double ratio = observed / estimated_sum;\n    \n    ci = si; cj = sj;\n    for (char c : path) {\n        int dir = (c == 'U') ? 0 : (c == 'D') ? 1 : (c == 'L') ? 2 : 3;\n        double* mean; int* cnt;\n        if (dir == 0) { mean = &v[ci-1][cj]; cnt = &cnt_v[ci-1][cj]; ci--; }\n        else if (dir == 1) { mean = &v[ci][cj]; cnt = &cnt_v[ci][cj]; ci++; }\n        else if (dir == 2) { mean = &h[ci][cj-1]; cnt = &cnt_h[ci][cj-1]; cj--; }\n        else { mean = &h[ci][cj]; cnt = &cnt_h[ci][cj]; cj++; }\n        \n        (*cnt)++;\n        double alpha = min(0.75, 0.75 / pow(*cnt, 0.3));\n        *mean *= (1.0 - alpha + alpha * ratio);\n        *mean = max(800.0, min(10000.0, *mean));\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N-1; j++)\n            h[i][j] = 5000.0, cnt_h[i][j] = 0;\n    for (int i = 0; i < N-1; i++)\n        for (int j = 0; j < N; j++)\n            v[i][j] = 5000.0, cnt_v[i][j] = 0;\n    \n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj; \n        cin >> si >> sj >> ti >> tj;\n        \n        // Slower decay with minimum exploration\n        double exploration = max(15.0, 5000.0 * exp(-k / 100.0));\n        \n        string path = dijkstra(si, sj, ti, tj, exploration);\n        \n        cout << path << endl;\n        cout.flush();\n        \n        int observed;\n        cin >> observed;\n        \n        update_estimates(path, si, sj, observed);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\n\nint M;\nchar strLen[800];\nchar grid[N*N];\nshort matchCnt[640000];\nshort perfect[800];\nchar strChar[800][13];\n\nint cellStart[N*N+1];\nint cellPid[7000000];\nchar cellExp[7000000];\n\nstruct XORShift {\n    unsigned int x;\n    XORShift(unsigned int seed) : x(seed) {}\n    unsigned int next() { x ^= x << 13; x ^= x >> 17; x ^= x << 5; return x; }\n    int nextInt(int mod) { return next() % mod; }\n    float nextFloat() { return (next() & 0xFFFF) / 65536.0f; }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n >> M;\n    \n    for (int i = 0; i < M; i++) {\n        string s;\n        cin >> s;\n        strLen[i] = s.size();\n        for (int j = 0; j < strLen[i]; j++) strChar[i][j] = s[j] - 'A';\n    }\n    \n    // Build cell data\n    int idx = 0;\n    for (int cell = 0; cell < N*N; cell++) {\n        cellStart[cell] = idx;\n        int cr = cell / N, cc = cell % N;\n        for (int si = 0; si < M; si++) {\n            int L = strLen[si];\n            for (int p = 0; p < L; p++) {\n                int sc = (cc - p + N) % N;\n                cellPid[idx] = si * 800 + cr * N + sc;\n                cellExp[idx++] = strChar[si][p];\n            }\n            for (int p = 0; p < L; p++) {\n                int sr = (cr - p + N) % N;\n                cellPid[idx] = si * 800 + 400 + sr * N + cc;\n                cellExp[idx++] = strChar[si][p];\n            }\n        }\n    }\n    cellStart[N*N] = idx;\n    \n    // Weighted voting - weight by inverse of string length squared\n    float votes[N*N][8] = {};\n    for (int cell = 0; cell < N*N; cell++)\n        for (int j = cellStart[cell]; j < cellStart[cell+1]; j++) {\n            int si = cellPid[j] / 800;\n            votes[cell][(int)cellExp[j]] += 1.0f / (strLen[si] * strLen[si]);\n        }\n    \n    for (int cell = 0; cell < N*N; cell++) {\n        int best = 0;\n        for (int c = 1; c < 8; c++) if (votes[cell][c] > votes[cell][best]) best = c;\n        grid[cell] = best;\n    }\n    \n    // Initialize\n    memset(matchCnt, 0, M * 800 * sizeof(short));\n    memset(perfect, 0, M * sizeof(short));\n    \n    for (int cell = 0; cell < N*N; cell++)\n        for (int j = cellStart[cell]; j < cellStart[cell+1]; j++)\n            if (grid[cell] == cellExp[j]) matchCnt[cellPid[j]]++;\n    \n    for (int pid = 0; pid < M * 800; pid++)\n        if (matchCnt[pid] == strLen[pid / 800]) perfect[pid / 800]++;\n    \n    int score = 0;\n    for (int si = 0; si < M; si++) if (perfect[si] > 0) score++;\n    \n    char bestGrid[N*N];\n    memcpy(bestGrid, grid, sizeof(grid));\n    int bestScore = score;\n    \n    XORShift rng(42);\n    float T = 2.5f;\n    \n    // SA phase\n    for (int iter = 0; iter < 15000; iter++) {\n        int cell = rng.nextInt(N*N);\n        int old = grid[cell];\n        int newCh = rng.nextInt(8);\n        if (newCh == old) continue;\n        \n        int delta = 0;\n        int *cp = cellPid + cellStart[cell];\n        char *ce = cellExp + cellStart[cell];\n        int cnt = cellStart[cell+1] - cellStart[cell];\n        \n        for (int j = 0; j < cnt; j++) {\n            int pid = cp[j], ec = ce[j], si = pid / 800, L = strLen[si];\n            short mc = matchCnt[pid];\n            bool wasP = (mc == L);\n            mc -= (old == ec); mc += (newCh == ec);\n            matchCnt[pid] = mc;\n            if (wasP && mc != L) { perfect[si]--; if (!perfect[si]) delta--; }\n            else if (!wasP && mc == L) { if (!perfect[si]) delta++; perfect[si]++; }\n        }\n        \n        if (delta >= 0 || rng.nextFloat() < exp(delta / T)) {\n            grid[cell] = newCh;\n            score += delta;\n            if (score > bestScore) { bestScore = score; memcpy(bestGrid, grid, sizeof(grid)); }\n        } else {\n            for (int j = 0; j < cnt; j++) {\n                int pid = cp[j], ec = ce[j], si = pid / 800, L = strLen[si];\n                short mc = matchCnt[pid];\n                bool wasP = (mc == L);\n                mc -= (newCh == ec); mc += (old == ec);\n                matchCnt[pid] = mc;\n                if (wasP && mc != L) perfect[si]--;\n                else if (!wasP && mc == L) perfect[si]++;\n            }\n        }\n        T *= 0.9997f;\n    }\n    \n    // Greedy refinement\n    for (int iter = 0; iter < 2000; iter++) {\n        int cell = rng.nextInt(N*N);\n        int old = grid[cell], bestCh = old, bestDelta = 0;\n        int *cp = cellPid + cellStart[cell];\n        char *ce = cellExp + cellStart[cell];\n        int cnt = cellStart[cell+1] - cellStart[cell];\n        \n        for (int newCh = 0; newCh < 8; newCh++) {\n            if (newCh == old) continue;\n            int delta = 0;\n            for (int j = 0; j < cnt; j++) {\n                int pid = cp[j], ec = ce[j], si = pid / 800, L = strLen[si];\n                short mc = matchCnt[pid];\n                bool wasP = (mc == L);\n                mc -= (old == ec); mc += (newCh == ec);\n                if (wasP && mc != L) delta--;\n                else if (!wasP && mc == L) delta++;\n            }\n            if (delta > bestDelta) { bestDelta = delta; bestCh = newCh; }\n        }\n        \n        if (bestDelta > 0) {\n            for (int j = 0; j < cnt; j++) {\n                int pid = cp[j], ec = ce[j], si = pid / 800, L = strLen[si];\n                short mc = matchCnt[pid];\n                bool wasP = (mc == L);\n                mc -= (old == ec); mc += (bestCh == ec);\n                matchCnt[pid] = mc;\n                if (wasP && mc != L) perfect[si]--;\n                else if (!wasP && mc == L) perfect[si]++;\n            }\n            grid[cell] = bestCh;\n        }\n    }\n    \n    int finalScore = 0;\n    for (int si = 0; si < M; si++) if (perfect[si] > 0) finalScore++;\n    if (finalScore > bestScore) memcpy(bestGrid, grid, sizeof(grid));\n    \n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) cout << (char)('A' + bestGrid[r*N + c]);\n        cout << '\\n';\n    }\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> grid;\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dc[] = {'U', 'D', 'L', 'R'};\n\ninline bool isRoad(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\ninline int w(int i, int j) { return grid[i][j] - '0'; }\n\nvector<vector<vector<pair<int,int>>>> visList;\nvector<pair<int,int>> roads;\nint totalRoads;\n\nstring solve(int si, int sj, double distWeight, double coverWeight) {\n    vector<vector<bool>> covered(N, vector<bool>(N, false));\n    int numCovered = 0;\n    \n    auto doCover = [&](int i, int j) {\n        for (auto& [ni, nj] : visList[i][j])\n            if (!covered[ni][nj]) { covered[ni][nj] = true; numCovered++; }\n    };\n    \n    auto countNewCover = [&](int i, int j) {\n        int cnt = 0;\n        for (auto& [ni, nj] : visList[i][j])\n            if (!covered[ni][nj]) cnt++;\n        return cnt;\n    };\n    \n    vector<vector<int>> dist(N, vector<int>(N));\n    vector<vector<int>> parentDir(N, vector<int>(N));\n    \n    auto dijkstra = [&](int si, int sj) {\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) { dist[i][j] = INT_MAX; parentDir[i][j] = -1; }\n        priority_queue<tuple<int,int,int>, vector<tuple<int,int,int>>, greater<>> pq;\n        dist[si][sj] = 0;\n        pq.push({0, si, sj});\n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top(); pq.pop();\n            if (d > dist[i][j]) continue;\n            for (int k = 0; k < 4; k++) {\n                int ni = i + di[k], nj = j + dj[k];\n                if (isRoad(ni, nj)) {\n                    int nd = d + w(ni, nj);\n                    if (nd < dist[ni][nj]) {\n                        dist[ni][nj] = nd; parentDir[ni][nj] = k;\n                        pq.push({nd, ni, nj});\n                    }\n                }\n            }\n        }\n    };\n    \n    string route;\n    int ci = si, cj = sj;\n    doCover(ci, cj);\n    \n    while (numCovered < totalRoads) {\n        dijkstra(ci, cj);\n        \n        double bestScore = -1;\n        int besti = -1, bestj = -1;\n        for (auto& [i, j] : roads) {\n            if (dist[i][j] == INT_MAX) continue;\n            int newC = countNewCover(i, j);\n            if (newC == 0) continue;\n            double score = pow((double)newC, coverWeight) * 10000.0 / pow((double)max(1, dist[i][j]), distWeight);\n            if (score > bestScore) { bestScore = score; besti = i; bestj = j; }\n        }\n        \n        if (besti == -1) break;\n        \n        vector<int> pathDir;\n        int ti = besti, tj = bestj;\n        while (ti != ci || tj != cj) {\n            int d = parentDir[ti][tj];\n            pathDir.push_back(d);\n            ti -= di[d]; tj -= dj[d];\n        }\n        reverse(pathDir.begin(), pathDir.end());\n        \n        for (int d : pathDir) {\n            route += dc[d]; ci += di[d]; cj += dj[d]; doCover(ci, cj);\n        }\n    }\n    \n    dijkstra(ci, cj);\n    vector<int> pathDir;\n    int ti = si, tj = sj;\n    while (ti != ci || tj != cj) {\n        int d = parentDir[ti][tj];\n        pathDir.push_back(d);\n        ti -= di[d]; tj -= dj[d];\n    }\n    reverse(pathDir.begin(), pathDir.end());\n    for (int d : pathDir) route += dc[d];\n    \n    return route;\n}\n\nint computeTime(const string& route, int si, int sj) {\n    int t = 0, ci = si, cj = sj;\n    for (char c : route) {\n        int d = string(\"UDLR\").find(c);\n        ci += di[d]; cj += dj[d];\n        t += w(ci, cj);\n    }\n    return t;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (isRoad(i, j)) roads.push_back({i, j});\n    \n    totalRoads = roads.size();\n    \n    visList.assign(N, vector<vector<pair<int,int>>>(N));\n    for (auto& [i, j] : roads) {\n        visList[i][j].push_back({i, j});\n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            while (isRoad(ni, nj)) {\n                visList[i][j].push_back({ni, nj});\n                ni += di[d]; nj += dj[d];\n            }\n        }\n    }\n    \n    string bestRoute;\n    int bestTime = INT_MAX;\n    \n    // Parameter sweep\n    for (double dw = 0.8; dw <= 1.4; dw += 0.1) {\n        for (double cw = 0.8; cw <= 1.4; cw += 0.1) {\n            string route = solve(si, sj, dw, cw);\n            int t = computeTime(route, si, sj);\n            if (t < bestTime) {\n                bestTime = t;\n                bestRoute = route;\n            }\n        }\n    }\n    \n    cout << bestRoute << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <set>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> d, deps, reverse_deps;\nvector<vector<double>> s_est, s_lower;\nvector<int> in_degree, task_start_day, task_status, member_task, critical_len;\nset<int> ready_tasks;\nvector<int> tasks_done_count;\nmt19937 rng(42);\n\nint estimate_time(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++)\n        w += max(0.0, (double)d[task][k] - s_est[member][k]);\n    return max(1, (int)round(w));\n}\n\ndouble estimate_w(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++)\n        w += max(0.0, (double)d[task][k] - s_est[member][k]);\n    return w;\n}\n\nvoid update_skills(int member, int task, int duration) {\n    tasks_done_count[member]++;\n    int n_obs = tasks_done_count[member];\n    \n    vector<double> contrib(K, 0);\n    double total_contrib = 0;\n    for (int k = 0; k < K; k++) {\n        contrib[k] = max(0.0, (double)d[task][k] - s_est[member][k]);\n        total_contrib += contrib[k];\n    }\n    \n    if (duration == 1) {\n        double slack = 3.5;\n        \n        for (int k = 0; k < K; k++) {\n            s_lower[member][k] = max(s_lower[member][k], (double)d[task][k] - slack);\n        }\n        \n        if (total_contrib > slack) {\n            double deficit = total_contrib - slack;\n            for (int k = 0; k < K; k++) {\n                if (contrib[k] > 0.1) {\n                    double weight = contrib[k] / total_contrib;\n                    s_est[member][k] += deficit * weight * 0.65;\n                }\n            }\n        }\n        \n        for (int k = 0; k < K; k++) {\n            s_est[member][k] = max(s_est[member][k], s_lower[member][k]);\n        }\n        return;\n    }\n    \n    double obs_w = (double)duration;\n    double error = obs_w - total_contrib;\n    \n    double lr = 0.6 / (1.0 + n_obs * 0.02);\n    \n    if (total_contrib < 0.5) {\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 dec = obs_w * (d[task][k] / total_d) * lr;\n                    s_est[member][k] = max(s_lower[member][k], s_est[member][k] - dec);\n                }\n            }\n        }\n    } else {\n        for (int k = 0; k < K; k++) {\n            if (contrib[k] > 1e-6) {\n                double weight = contrib[k] / total_contrib;\n                double change = error * weight * lr;\n                \n                if (error > 0) {\n                    s_est[member][k] = max(s_lower[member][k], s_est[member][k] - change);\n                } else {\n                    s_est[member][k] -= change * 0.4;\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K >> R;\n    d.resize(N, vector<int>(K));\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) cin >> d[i][k];\n    \n    deps.resize(N); reverse_deps.resize(N); in_degree.assign(N, 0);\n    for (int i = 0; i < R; i++) {\n        int u, v; cin >> u >> v; u--; v--;\n        deps[v].push_back(u); reverse_deps[u].push_back(v);\n        in_degree[v]++;\n    }\n    \n    vector<int> order, td = in_degree;\n    queue<int> q;\n    for (int i = 0; i < N; i++) if (td[i] == 0) q.push(i);\n    while (!q.empty()) {\n        int u = q.front(); q.pop(); order.push_back(u);\n        for (int v : reverse_deps[u]) if (--td[v] == 0) q.push(v);\n    }\n    \n    critical_len.assign(N, 0);\n    for (int i = N - 1; i >= 0; i--)\n        for (int v : reverse_deps[order[i]])\n            critical_len[order[i]] = max(critical_len[order[i]], critical_len[v] + 1);\n    \n    vector<double> avg_d(K, 0);\n    for (int i = 0; i < N; i++)\n        for (int k = 0; k < K; k++) avg_d[k] += d[i][k];\n    for (int k = 0; k < K; k++) avg_d[k] /= N;\n    \n    s_est.assign(M, vector<double>(K));\n    s_lower.assign(M, vector<double>(K, 0));\n    \n    for (int j = 0; j < M; j++) {\n        for (int k = 0; k < K; k++) {\n            s_est[j][k] = avg_d[k] * 0.90;\n        }\n    }\n    \n    tasks_done_count.assign(M, 0);\n    task_status.assign(N, -1); \n    task_start_day.assign(N, -1); \n    member_task.assign(M, -1);\n    \n    for (int i = 0; i < N; i++) \n        if (in_degree[i] == 0) \n            ready_tasks.insert(i);\n    \n    int day = 0;\n    \n    while (true) {\n        day++;\n        vector<pair<int,int>> assignments;\n        set<int> assigned;\n        \n        while (true) {\n            double best_score = 1e18; \n            int best_m = -1, best_t = -1;\n            \n            for (int m = 0; m < M; m++) {\n                if (member_task[m] != -1) continue;\n                \n                for (int t : ready_tasks) {\n                    if (assigned.count(t)) continue;\n                    \n                    double est_time = estimate_time(t, m);\n                    double priority = critical_len[t] * 0.12;\n                    \n                    double exploration = 0;\n                    if (tasks_done_count[m] < 10) {\n                        exploration = 1.5 * (10 - tasks_done_count[m]);\n                    }\n                    \n                    double noise = uniform_real_distribution<double>(0, 0.4)(rng);\n                    double score = est_time - priority - exploration + noise;\n                    \n                    if (score < best_score) {\n                        best_score = score;\n                        best_m = m;\n                        best_t = t;\n                    }\n                }\n            }\n            \n            if (best_m == -1) break;\n            \n            assignments.push_back({best_m + 1, best_t + 1});\n            member_task[best_m] = best_t;\n            task_status[best_t] = 0;\n            task_start_day[best_t] = day;\n            assigned.insert(best_t);\n        }\n        \n        for (auto& p : assignments) \n            ready_tasks.erase(p.second - 1);\n        \n        cout << assignments.size();\n        for (auto& p : assignments) \n            cout << \" \" << p.first << \" \" << p.second;\n        cout << \"\\n\" << flush;\n        \n        int n; \n        cin >> n;\n        if (n == -1) break;\n        \n        for (int i = 0; i < n; i++) {\n            int f; cin >> f; f--;\n            int task = member_task[f];\n            member_task[f] = -1;\n            \n            int duration = day - task_start_day[task] + 1;\n            task_status[task] = 1;\n            \n            update_skills(f, task, duration);\n            \n            for (int v : reverse_deps[task]) {\n                in_degree[v]--;\n                if (in_degree[v] == 0 && task_status[v] == -1) \n                    ready_tasks.insert(v);\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nmt19937 rng(42);\nconst int DEPOT = 400;\nconst double TIME_LIMIT = 1.70;\n\nint dist(int x1, int y1, int x2, int y2) { return abs(x1-x2) + abs(y1-y2); }\n\nstruct Solver {\n    vector<array<int,4>> orders;\n    vector<int> selected, route;\n    chrono::time_point<chrono::steady_clock> start_time;\n    int current_dist, best_dist;\n    vector<int> best_selected;\n    \n    void read_input() {\n        orders.resize(1000);\n        for(int i=0;i<1000;i++) cin>>orders[i][0]>>orders[i][1]>>orders[i][2]>>orders[i][3];\n        start_time = chrono::steady_clock::now();\n    }\n    \n    double elapsed() { return chrono::duration<double>(chrono::steady_clock::now()-start_time).count(); }\n    \n    pair<int,int> get_coords(int loc) {\n        if(loc==-1) return {DEPOT,DEPOT};\n        if(loc<50) return {orders[selected[loc]][0], orders[selected[loc]][1]};\n        return {orders[selected[loc-50]][2], orders[selected[loc-50]][3]};\n    }\n    \n    int calc_dist() {\n        int d=0;\n        for(int i=0;i+1<(int)route.size();i++) {\n            auto[x1,y1]=get_coords(route[i]); auto[x2,y2]=get_coords(route[i+1]);\n            d+=dist(x1,y1,x2,y2);\n        }\n        return d;\n    }\n    \n    void save_best() { best_dist=current_dist; best_selected=selected; }\n    \n    void select_orders_greedy() {\n        vector<pair<int,int>> scored;\n        for(int i=0;i<1000;i++) {\n            auto& o=orders[i];\n            scored.push_back({dist(DEPOT,DEPOT,o[0],o[1])+dist(o[0],o[1],o[2],o[3])+dist(o[2],o[3],DEPOT,DEPOT),i});\n        }\n        sort(scored.begin(),scored.end());\n        for(int i=0;i<50;i++) selected.push_back(scored[i].second);\n    }\n    \n    void build_route() {\n        route.clear();\n        route.push_back(-1); \n        vector<bool> picked(50,false), delivered(50,false);\n        int cx=DEPOT, cy=DEPOT;\n        \n        for(int step=0;step<100;step++) {\n            int best=-1, best_d=INT_MAX;\n            \n            // Check pickups\n            for(int i=0;i<50;i++) {\n                if(!picked[i]) {\n                    auto[x,y]=get_coords(i);\n                    int d=dist(cx,cy,x,y);\n                    if(d<best_d){best_d=d;best=i;}\n                }\n            }\n            // Check deliveries\n            for(int i=0;i<50;i++) {\n                if(picked[i] && !delivered[i]) {\n                    auto[x,y]=get_coords(i+50);\n                    int d=dist(cx,cy,x,y);\n                    if(d<best_d){best_d=d;best=i+50;}\n                }\n            }\n            \n            assert(best!=-1); // Should always find something\n            route.push_back(best);\n            if(best<50) picked[best]=true; \n            else delivered[best-50]=true;\n            tie(cx,cy)=get_coords(best);\n        }\n        route.push_back(-1);\n        current_dist=calc_dist();\n    }\n    \n    void local_search() {\n        while(true) {\n            if(elapsed()>TIME_LIMIT*0.8) return;\n            bool improved=false;\n            int n=route.size();\n            \n            vector<int> pickup_at(50,-1), delivery_at(50,-1);\n            for(int k=0;k<n;k++){\n                int loc=route[k];\n                if(loc==-1) continue;\n                if(loc<50) pickup_at[loc]=k; \n                else delivery_at[loc-50]=k;\n            }\n            \n            // 2-opt\n            for(int i=1;i<n-2 && !improved;i++) {\n                for(int j=i+1;j<n-1;j++) {\n                    bool ok=true;\n                    for(int o=0;o<50;o++) {\n                        int p=pickup_at[o], d=delivery_at[o];\n                        bool pi=(p>=i && p<=j), di=(d>=i && d<=j);\n                        if(pi!=di) {ok=false; break;}\n                    }\n                    if(!ok) continue;\n                    \n                    auto[pi,py]=get_coords(route[i-1]); auto[jx,jy]=get_coords(route[j]);\n                    auto[ix,iy]=get_coords(route[i]); auto[pj,pjy]=get_coords(route[j+1]);\n                    int diff=dist(pi,py,jx,jy)+dist(ix,iy,pj,pjy)-dist(pi,py,ix,iy)-dist(jx,jy,pj,pjy);\n                    if(diff<0) {\n                        reverse(route.begin()+i,route.begin()+j+1);\n                        current_dist+=diff;\n                        improved=true;\n                        for(int k=i;k<=j;k++){\n                            int loc=route[k]; if(loc==-1) continue;\n                            if(loc<50) pickup_at[loc]=k; else delivery_at[loc-50]=k;\n                        }\n                        break;\n                    }\n                }\n            }\n            if(improved) continue;\n            \n            // relocate\n            for(int i=1;i<n-1 && !improved;i++) {\n                int loc=route[i]; if(loc==-1) continue;\n                int ol=(loc<50)?loc:loc-50;\n                bool is_p=loc<50;\n                int other=is_p?delivery_at[ol]:pickup_at[ol];\n                \n                for(int np=1;np<n-1;np++) {\n                    if(is_p && np>other) continue;\n                    if(!is_p && np<=other) continue;\n                    if(np==i || np==i-1) continue;\n                    \n                    int ip=(np<i)?np+1:np;\n                    auto[pi,py]=get_coords(route[i-1]); auto[cx,cy]=get_coords(loc);\n                    auto[ni,nx]=get_coords(route[i+1]); auto[oi,oy]=get_coords(route[ip-1]);\n                    auto[nip,ny]=get_coords(route[ip]);\n                    int diff=dist(oi,oy,cx,cy)+dist(cx,cy,nip,ny)+dist(pi,py,ni,nx)\n                            -dist(oi,oy,nip,ny)-dist(pi,py,cx,cy)-dist(cx,cy,ni,nx);\n                    if(diff<0) {\n                        route.erase(route.begin()+i);\n                        if(np<i) route.insert(route.begin()+np+1,loc);\n                        else route.insert(route.begin()+ip,loc);\n                        current_dist+=diff;\n                        improved=true;\n                        // Rebuild position arrays\n                        for(int k=0;k<(int)route.size();k++){\n                            int l=route[k]; if(l==-1) continue;\n                            if(l<50) pickup_at[l]=k; else delivery_at[l-50]=k;\n                        }\n                        break;\n                    }\n                }\n            }\n            if(!improved) break;\n        }\n    }\n    \n    void run_sa() {\n        set<int> sel_set(selected.begin(),selected.end());\n        save_best();\n        double temp=5000;\n        \n        while(elapsed()<TIME_LIMIT) {\n            int out_idx=rng()%50, out_ord=selected[out_idx], in_ord;\n            do{in_ord=rng()%1000;}while(sel_set.count(in_ord));\n            \n            int old_dist=current_dist;\n            vector<int> old_selected=selected;\n            \n            // Try swap\n            sel_set.erase(out_ord); sel_set.insert(in_ord);\n            selected[out_idx]=in_ord;\n            \n            build_route();\n            local_search();\n            \n            if(current_dist<old_dist || exp(-(current_dist-old_dist)/temp)>(double)rng()/rng.max()) {\n                if(current_dist<best_dist) save_best();\n            } else {\n                // Restore\n                sel_set.erase(in_ord); sel_set.insert(out_ord);\n                selected=old_selected;\n                build_route();\n            }\n            temp*=0.997;\n        }\n    }\n    \n    void output() {\n        // Load best and rebuild route\n        selected=best_selected;\n        build_route();\n        \n        // Validate\n        assert(selected.size()==50);\n        assert(route.size()==102);\n        \n        set<int> sel_set(selected.begin(),selected.end());\n        assert(sel_set.size()==50);\n        \n        cout<<50; for(int i:selected) cout<<\" \"<<i+1; cout<<\"\\n\";\n        cout<<route.size(); for(int loc:route){auto[x,y]=get_coords(loc);cout<<\" \"<<x<<\" \"<<y;} cout<<\"\\n\";\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    Solver s; \n    s.read_input(); \n    s.select_orders_greedy(); \n    s.build_route(); \n    s.local_search(); \n    s.run_sa();\n    s.output();\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent, rnk;\npublic:\n    UnionFind(int n) : parent(n), rnk(n, 0) {\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        if (rnk[px] < rnk[py]) swap(px, py);\n        parent[py] = px;\n        if (rnk[px] == rnk[py]) rnk[px]++;\n        return true;\n    }\n    \n    bool same(int x, int y) {\n        return find(x) == find(y);\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400;\n    const int M = 1995;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    vector<int> u(M), v(M), d(M);\n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        double dx = (double)(x[u[i]] - x[v[i]]);\n        double dy = (double)(y[u[i]] - y[v[i]]);\n        d[i] = max(1, (int)round(sqrt(dx*dx + dy*dy)));\n    }\n    \n    UnionFind uf(N);\n    int need = N - 1;\n    \n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        int decision = 0;\n        \n        if (!uf.same(u[i], v[i])) {\n            double ratio = (double)l / d[i];\n            int rem = M - i - 1;\n            \n            // Progressive threshold: start selective, become less selective\n            // threshold ranges from 2.0 (early) to 3.0 (late)\n            double progress = (double)i / M;\n            double threshold = 2.0 + 1.0 * progress;\n            \n            // Safety: accept all when running critically low\n            if (rem <= need + 50) {\n                threshold = 3.0;\n            }\n            \n            if (ratio <= threshold) {\n                decision = 1;\n                uf.unite(u[i], v[i]);\n                need--;\n            }\n        }\n        \n        cout << decision << endl;\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <set>\n#include <tuple>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char WALL[] = {'u', 'd', 'l', 'r'};\nconst char MOVE[] = {'U', 'D', 'L', 'R'};\n\nint N, M;\nvector<tuple<int,int,int>> pets_data;\nvector<pair<int,int>> humans_data;\n\nstruct Solver {\n    mutable vector<vector<bool>> wall;\n    vector<tuple<int,int,int>> pets;\n    vector<pair<int,int>> humans;\n    int turn;\n    \n    void init() {\n        wall.assign(SIZE, vector<bool>(SIZE, false));\n        pets = pets_data;\n        humans = humans_data;\n        turn = 0;\n    }\n    \n    bool ok(int x, int y) const { return x >= 0 && x < SIZE && y >= 0 && y < SIZE; }\n    bool petAt(int x, int y) const { for (auto& [px, py, pt] : pets) if (px == x && py == y) return true; return false; }\n    bool humanAt(int x, int y) const { for (auto& [hx, hy] : humans) if (hx == x && hy == y) return true; return false; }\n    bool nearPet(int x, int y) const { for (int d = 0; d < 4; d++) if (petAt(x + dx[d], y + dy[d])) return true; return false; }\n    \n    bool canBuild(int h, int d, const set<pair<int,int>>& pw) const {\n        int x = humans[h].first + dx[d], y = humans[h].second + dy[d];\n        return ok(x, y) && !wall[x][y] && !petAt(x, y) && !humanAt(x, y) && !nearPet(x, y) && !pw.count({x, y});\n    }\n    \n    bool canMove(int h, int d, const set<pair<int,int>>& pw) const {\n        int x = humans[h].first + dx[d], y = humans[h].second + dy[d];\n        return ok(x, y) && !wall[x][y] && !pw.count({x, y});\n    }\n    \n    pair<int, vector<vector<bool>>> getReach(int sx, int sy) const {\n        vector<vector<bool>> vis(SIZE, vector<bool>(SIZE, false));\n        queue<pair<int,int>> q; q.push({sx, sy}); vis[sx][sy] = true;\n        int cnt = 0;\n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop(); cnt++;\n            for (int i = 0; i < 4; i++) {\n                int nx = cx + dx[i], ny = cy + dy[i];\n                if (ok(nx, ny) && !vis[nx][ny] && !wall[nx][ny]) { vis[nx][ny] = true; q.push({nx, ny}); }\n            }\n        }\n        return {cnt, vis};\n    }\n    \n    int countPetsInVis(const vector<vector<bool>>& vis) const {\n        int cnt = 0;\n        for (auto& [px, py, pt] : pets) if (vis[px][py]) cnt++;\n        return cnt;\n    }\n    \n    int countPetsIn(int sx, int sy) const {\n        auto [area, vis] = getReach(sx, sy);\n        return countPetsInVis(vis);\n    }\n    \n    // Check if pet at (px, py) can escape from human's reachable area\n    bool petCanEscapeFrom(int px, int py, const vector<vector<bool>>& humanReach) const {\n        if (!humanReach[px][py]) return true; // Already outside\n        vector<vector<bool>> vis(SIZE, vector<bool>(SIZE, false));\n        queue<pair<int,int>> q; q.push({px, py}); vis[px][py] = true;\n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop();\n            if (!humanReach[cx][cy]) return true; // Can reach outside human's area\n            for (int i = 0; i < 4; i++) {\n                int nx = cx + dx[i], ny = cy + dy[i];\n                if (ok(nx, ny) && !vis[nx][ny] && !wall[nx][ny]) { vis[nx][ny] = true; q.push({nx, ny}); }\n            }\n        }\n        return false; // Pet is trapped\n    }\n    \n    // Check if all pets in the reachable area can still escape after building wall at (wx, wy)\n    bool petsCanEscape(int hx, int hy, int wx, int wy) const {\n        wall[wx][wy] = true;\n        auto [area, vis] = getReach(hx, hy);\n        wall[wx][wy] = false;\n        \n        for (auto& [px, py, pt] : pets) {\n            if (vis[px][py] && !petCanEscapeFrom(px, py, vis)) return false;\n        }\n        return true;\n    }\n    \n    double calcScore(int sx, int sy) const {\n        auto [area, vis] = getReach(sx, sy);\n        int cnt = countPetsInVis(vis);\n        return (double)area / (SIZE * SIZE) * pow(0.5, cnt);\n    }\n    \n    vector<vector<int>> bfsDist(int sx, int sy) const {\n        vector<vector<int>> dist(SIZE, vector<int>(SIZE, -1));\n        queue<pair<int,int>> q; q.push({sx, sy}); dist[sx][sy] = 0;\n        while (!q.empty()) {\n            auto [cx, cy] = q.front(); q.pop();\n            for (int i = 0; i < 4; i++) {\n                int nx = cx + dx[i], ny = cy + dy[i];\n                if (ok(nx, ny) && dist[nx][ny] < 0 && !wall[nx][ny]) { dist[nx][ny] = dist[cx][cy] + 1; q.push({nx, ny}); }\n            }\n        }\n        return dist;\n    }\n    \n    int minPetDist(int sx, int sy) const {\n        auto dist = bfsDist(sx, sy);\n        int mnd = SIZE * SIZE;\n        for (auto& [px, py, pt] : pets) if (dist[px][py] >= 0) mnd = min(mnd, dist[px][py]);\n        return mnd;\n    }\n    \n    char decide(int h, const set<pair<int,int>>& pw) {\n        int hx = humans[h].first, hy = humans[h].second;\n        double baseScore = calcScore(hx, hy);\n        int petsIn = countPetsIn(hx, hy);\n        int mpd = minPetDist(hx, hy);\n        \n        double best = baseScore;\n        char bestA = '.';\n        int bestD = -1;\n        \n        // Try building walls - check that pets can escape\n        for (int d = 0; d < 4; d++) {\n            if (canBuild(h, d, pw)) {\n                int wx = hx + dx[d], wy = hy + dy[d];\n                \n                // Check if building would trap any pets\n                if (!petsCanEscape(hx, hy, wx, wy)) continue;\n                \n                wall[wx][wy] = true;\n                double s = calcScore(hx, hy);\n                int newPetsIn = countPetsIn(hx, hy);\n                wall[wx][wy] = false;\n                \n                // Big bonus for reducing pets in area\n                if (newPetsIn < petsIn) s += 0.1 * (petsIn - newPetsIn);\n                \n                // Bonus for building when pets are far\n                if (mpd >= 5) s += 0.005;\n                else if (mpd >= 3) s += 0.002;\n                \n                if (s > best) { best = s; bestA = WALL[d]; bestD = d; }\n            }\n        }\n        \n        // Try moving\n        for (int d = 0; d < 4; d++) {\n            if (canMove(h, d, pw)) {\n                int nx = hx + dx[d], ny = hy + dy[d];\n                double s = calcScore(nx, ny);\n                int newMpd = minPetDist(nx, ny);\n                \n                // Bonus for staying away from pets when close\n                if (newMpd > mpd && mpd < 4) s += 0.002 * (newMpd - mpd);\n                \n                if (s > best) { best = s; bestA = MOVE[d]; bestD = d; }\n            }\n        }\n        \n        return bestA;\n    }\n    \n    void apply(int h, char a, int d) {\n        if (a >= 'a' && a <= 'z') wall[humans[h].first + dx[d]][humans[h].second + dy[d]] = true;\n        else if (a != '.') { humans[h].first += dx[d]; humans[h].second += dy[d]; }\n    }\n    \n    void readPets() {\n        for (int i = 0; i < N; i++) {\n            string m; cin >> m;\n            auto& [px, py, pt] = pets[i];\n            for (char c : m) {\n                if (c == 'U') px--; else if (c == 'D') px++;\n                else if (c == 'L') py--; else if (c == 'R') py++;\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N; pets_data.resize(N);\n    for (int i = 0; i < N; i++) { int x, y, t; cin >> x >> y >> t; pets_data[i] = {x - 1, y - 1, t}; }\n    cin >> M; humans_data.resize(M);\n    for (int i = 0; i < M; i++) { int x, y; cin >> x >> y; humans_data[i] = {x - 1, y - 1}; }\n    \n    Solver sol; sol.init();\n    \n    for (int t = 0; t < 300; t++) {\n        sol.turn = t;\n        string act(M, '.'); set<pair<int,int>> pw; vector<int> dirs(M, -1);\n        \n        for (int h = 0; h < M; h++) {\n            char a = sol.decide(h, pw); act[h] = a;\n            for (int d = 0; d < 4; d++) if (a == WALL[d] || a == MOVE[d]) { dirs[h] = d; break; }\n            if (dirs[h] >= 0 && act[h] >= 'a') pw.insert({sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]});\n        }\n        \n        set<pair<int,int>> builds;\n        for (int h = 0; h < M; h++)\n            if (dirs[h] >= 0 && act[h] >= 'a' && act[h] <= 'z')\n                builds.insert({sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]});\n        \n        for (int h = 0; h < M; h++) {\n            if (dirs[h] >= 0 && act[h] >= 'A' && act[h] <= 'Z') {\n                pair<int,int> target = {sol.humans[h].first + dx[dirs[h]], sol.humans[h].second + dy[dirs[h]]};\n                if (builds.count(target)) { act[h] = '.'; dirs[h] = -1; }\n            }\n        }\n        \n        for (int h = 0; h < M; h++) if (dirs[h] >= 0) sol.apply(h, act[h], dirs[h]);\n        cout << act << endl; cout.flush();\n        sol.readPets();\n    }\n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj, ti, tj;\ndouble p, q;\nvector<string> h(20), v(19);\nvector<vector<int>> dist_to_goal;\nconstexpr int di[] = {-1, 1, 0, 0};\nconstexpr int dj[] = {0, 0, -1, 1};\nconstexpr char dirs[] = \"UDLR\";\nmt19937 rng(42);\n\ninline bool can_move(int i, int j, int d) {\n    if (d == 0) return i > 0 && v[i-1][j] == '0';\n    if (d == 1) return i < 19 && v[i][j] == '0';\n    if (d == 2) return j > 0 && h[i][j-1] == '0';\n    return j < 19 && h[i][j] == '0';\n}\n\nvoid compute_dist() {\n    dist_to_goal.assign(20, vector<int>(20, 1000));\n    queue<pair<int,int>> qq;\n    qq.push({ti, tj});\n    dist_to_goal[ti][tj] = 0;\n    while (!qq.empty()) {\n        auto [i, j] = qq.front(); qq.pop();\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if (dist_to_goal[ni][nj] > dist_to_goal[i][j] + 1) {\n                dist_to_goal[ni][nj] = dist_to_goal[i][j] + 1;\n                qq.push({ni, nj});\n            }\n        }\n    }\n}\n\nstring bfs_path() {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<int>> pm(20, vector<int>(20, -1));\n    queue<pair<int,int>> qq;\n    qq.push({si, sj});\n    dist[si][sj] = 0;\n    while (!qq.empty()) {\n        auto [i, j] = qq.front(); qq.pop();\n        if (i == ti && j == tj) break;\n        for (int d = 0; d < 4; d++) {\n            if (!can_move(i, j, d)) continue;\n            int ni = i + di[d], nj = j + dj[d];\n            if (dist[ni][nj] < 0) {\n                dist[ni][nj] = dist[i][j] + 1;\n                pm[ni][nj] = d;\n                qq.push({ni, nj});\n            }\n        }\n    }\n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int d = pm[ci][cj];\n        path = dirs[d] + path;\n        ci -= di[d]; cj -= dj[d];\n    }\n    return path;\n}\n\ndouble simulate(const string& s) {\n    vector<double> prob(400, 0), np(400);\n    prob[si * 20 + sj] = 1.0;\n    double total = 0, reached = 0;\n    int goal = ti * 20 + tj;\n    \n    for (int t = 0; t < (int)s.size(); t++) {\n        fill(np.begin(), np.end(), 0);\n        int mv = string(\"UDLR\").find(s[t]);\n        \n        for (int idx = 0; idx < 400; idx++) {\n            if (prob[idx] < 1e-16) continue;\n            int i = idx / 20, j = idx % 20;\n            np[idx] += p * prob[idx];\n            int ni = i, nj = j;\n            if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n            np[ni * 20 + nj] += q * prob[idx];\n        }\n        swap(prob, np);\n        double nr = prob[goal] * (1 - reached);\n        total += nr * (401 - t - 1);\n        reached += nr;\n        prob[goal] = 0;\n    }\n    return total;\n}\n\nstring greedy_construct() {\n    vector<float> prob(400, 0), np(400);\n    prob[si * 20 + sj] = 1.0f;\n    string result;\n    int goal = ti * 20 + tj;\n    \n    for (int t = 0; t < 200; t++) {\n        double best_score = -1e18; int bm = 0;\n        \n        for (int mv = 0; mv < 4; mv++) {\n            fill(np.begin(), np.end(), 0);\n            float nr = 0;\n            \n            for (int idx = 0; idx < 400; idx++) {\n                if (prob[idx] < 1e-10f) continue;\n                int i = idx / 20, j = idx % 20;\n                np[idx] += p * prob[idx];\n                int ni = i, nj = j;\n                if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n                int nidx = ni * 20 + nj;\n                if (nidx == goal) nr += q * prob[idx];\n                else np[nidx] += q * prob[idx];\n            }\n            \n            double score = nr * (401 - t - 1);\n            for (int idx = 0; idx < 400; idx++) {\n                if (np[idx] < 1e-10f) continue;\n                int i = idx / 20, j = idx % 20;\n                score += np[idx] * (100 - dist_to_goal[i][j]) * 0.5;\n            }\n            \n            if (score > best_score) { best_score = score; bm = mv; }\n        }\n        result += dirs[bm];\n        \n        fill(np.begin(), np.end(), 0);\n        for (int idx = 0; idx < 400; idx++) {\n            if (prob[idx] < 1e-10f) continue;\n            int i = idx / 20, j = idx % 20;\n            np[idx] += p * prob[idx];\n            int ni = i, nj = j;\n            if (can_move(i, j, bm)) { ni += di[bm]; nj += dj[bm]; }\n            np[ni * 20 + nj] += q * prob[idx];\n        }\n        swap(prob, np);\n        prob[goal] = 0;\n    }\n    return result;\n}\n\nstring beam_search(int width) {\n    struct State {\n        vector<uint8_t> s;\n        vector<float> prob;\n        double score;\n    };\n    \n    vector<State> beam;\n    beam.push_back({{}, vector<float>(400, 0), 0});\n    beam[0].prob[si * 20 + sj] = 1.0f;\n    int goal = ti * 20 + tj;\n    \n    for (int t = 0; t < 200; t++) {\n        vector<State> next;\n        next.reserve(beam.size() * 4);\n        \n        for (auto& st : beam) {\n            for (int mv = 0; mv < 4; mv++) {\n                State ns;\n                ns.s = st.s;\n                ns.s.push_back(mv);\n                ns.prob.assign(400, 0);\n                ns.score = st.score;\n                \n                float nr = 0;\n                for (int idx = 0; idx < 400; idx++) {\n                    if (st.prob[idx] < 1e-12f) continue;\n                    int i = idx / 20, j = idx % 20;\n                    ns.prob[idx] += p * st.prob[idx];\n                    int ni = i, nj = j;\n                    if (can_move(i, j, mv)) { ni += di[mv]; nj += dj[mv]; }\n                    int nidx = ni * 20 + nj;\n                    if (nidx == goal) nr += q * st.prob[idx];\n                    else ns.prob[nidx] += q * st.prob[idx];\n                }\n                ns.score += nr * (401 - t - 1);\n                ns.prob[goal] = 0;\n                next.push_back(move(ns));\n            }\n        }\n        \n        if ((int)next.size() > width) {\n            partial_sort(next.begin(), next.begin() + width, next.end(),\n                [](const State& a, const State& b) { return a.score > b.score; });\n            next.resize(width);\n        }\n        beam = move(next);\n    }\n    \n    string result;\n    for (auto c : beam[0].s) result += dirs[c];\n    return result;\n}\n\nstring sa_optimize(string cur, double time_limit) {\n    double cur_score = simulate(cur);\n    string best = cur;\n    double best_score = cur_score;\n    double temp = cur_score * 0.1;\n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    \n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < time_limit) {\n        string ns = cur;\n        \n        // Focused mutations\n        int op = rng() % 10;\n        if (op < 4 && !ns.empty()) {\n            int pos = rng() % ns.size();\n            ns[pos] = dirs[rng() % 4];\n        } else if (op < 6 && (int)ns.size() < 200) {\n            int pos = rng() % (ns.size() + 1);\n            ns.insert(ns.begin() + pos, dirs[rng() % 4]);\n        } else if (op < 8 && !ns.empty()) {\n            int pos = rng() % ns.size();\n            ns.erase(pos, 1);\n        } else if (ns.size() >= 2) {\n            int pos = rng() % (ns.size() - 1);\n            swap(ns[pos], ns[pos + 1]);\n        }\n        \n        double ns_score = simulate(ns);\n        double delta = ns_score - cur_score;\n        \n        if (delta > 0 || (temp > 1e-6 && exp(delta / temp) > (double)rng() / rng.max())) {\n            cur = ns;\n            cur_score = ns_score;\n            if (cur_score > best_score) {\n                best = cur;\n                best_score = cur_score;\n            }\n        }\n        temp *= 0.9995;\n        iter++;\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> si >> sj >> ti >> tj >> p;\n    q = 1 - p;\n    for (int i = 0; i < 20; i++) cin >> h[i];\n    for (int i = 0; i < 19; i++) cin >> v[i];\n    compute_dist();\n    string path = bfs_path();\n    int path_len = path.size();\n    \n    string best; double bsc = -1;\n    auto try_s = [&](const string& s) { \n        if (s.empty() || s.size() > 200) return;\n        double sc = simulate(s); \n        if (sc > bsc) { bsc = sc; best = s; } \n    };\n    \n    // Adaptive repetition count\n    int rep_count = (int)ceil(log(0.01) / log(p)); // Expected turns to have 99% chance of executing once\n    rep_count = max(1, min(rep_count, 15));\n    \n    // Strategy 1: Repeat whole path\n    { string s; while ((int)s.size() + path_len <= 200) s += path; try_s(s); }\n    \n    // Strategy 2: Various repetition patterns\n    for (int r = max(1, rep_count - 3); r <= min(12, rep_count + 3); r++) {\n        string rb;\n        for (char c : path) rb += string(r, c);\n        string s; while ((int)s.size() + (int)rb.size() <= 200) s += rb;\n        if (!s.empty()) try_s(s);\n    }\n    \n    // Strategy 3: Direction-weighted repetition\n    {\n        string s;\n        for (int rep = 0; rep < 200; ) {\n            for (char c : path) {\n                int weight = 2;\n                if (p > 0.3) weight = 3;\n                if (p > 0.4) weight = 4;\n                for (int i = 0; i < weight && rep < 200; i++, rep++) s += c;\n            }\n        }\n        try_s(s);\n    }\n    \n    // Strategy 4: Greedy\n    try_s(greedy_construct());\n    \n    // Strategy 5: Beam search\n    try_s(beam_search(60));\n    try_s(beam_search(100));\n    \n    // Strategy 6: Multi-restart SA\n    vector<string> starts = {best, greedy_construct(), beam_search(80)};\n    for (int i = 0; i < 3; i++) {\n        string s;\n        for (int j = 0; j < 200 && s.size() + path_len <= 200; j++)\n            for (char c : path) if (s.size() < 200) s += c;\n        starts.push_back(s);\n    }\n    \n    double time_per_sa = 0.15;\n    for (auto& start : starts) {\n        try_s(sa_optimize(start, time_per_sa));\n    }\n    \n    // Final refinement on best\n    best = sa_optimize(best, 0.2);\n    \n    cout << best << endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint tiles[N][N], rotations[N][N], best_rotations[N][N];\nconstexpr int di[] = {0, -1, 0, 1}, dj[] = {-1, 0, 1, 0};\nconstexpr int to[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}};\nconstexpr int rot_table[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\npair<long long, long long> compute_loops() {\n    static bool visited[N][N][4];\n    memset(visited, 0, sizeof(visited));\n    long long max1 = 0, max2 = 0;\n    \n    for (int si = 0; si < N; si++) {\n        for (int sj = 0; sj < N; sj++) {\n            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                \n                while (true) {\n                    if (visited[i][j][d]) { len = 0; break; }\n                    visited[i][j][d] = true;\n                    int t = rot_table[tiles[i][j]][rotations[i][j]];\n                    int d2 = to[t][d];\n                    if (d2 == -1) { len = 0; break; }\n                    i += di[d2]; j += dj[d2];\n                    if ((unsigned)i >= N || (unsigned)j >= N) { len = 0; break; }\n                    d = (d2 + 2) & 3; len++;\n                    if (i == si && j == sj && d == sd) break;\n                }\n                \n                if (len > max1) { max2 = max1; max1 = len; }\n                else if (len > max2) max2 = len;\n            }\n        }\n    }\n    return {max1, max2};\n}\n\nlong long compute_score(long long l1, long long l2) {\n    return l2 > 0 ? l1 * l2 : l1;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) tiles[i][j] = s[j] - '0';\n    }\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> rand01(0, 1);\n    \n    long long best_score = 0;\n    auto deadline = chrono::steady_clock::now() + chrono::milliseconds(1950);\n    \n    while (chrono::steady_clock::now() < deadline) {\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) rotations[i][j] = rng() % 4;\n        \n        auto [cur_l1, cur_l2] = compute_loops();\n        long long cur_score = compute_score(cur_l1, cur_l2);\n        \n        double temp = 10000.0;\n        \n        while (chrono::steady_clock::now() < deadline && temp > 0.01) {\n            int ri = rng() % N, rj = rng() % N;\n            int old = rotations[ri][rj];\n            rotations[ri][rj] = rng() % 4;\n            \n            auto [new_l1, new_l2] = compute_loops();\n            long long new_score = compute_score(new_l1, new_l2);\n            \n            if (new_score >= cur_score || rand01(rng) < exp((double)(new_score - cur_score) / temp)) {\n                cur_score = new_score;\n                cur_l1 = new_l1; cur_l2 = new_l2;\n                if (cur_score > best_score) {\n                    best_score = cur_score;\n                    memcpy(best_rotations, rotations, sizeof(rotations));\n                }\n            } else {\n                rotations[ri][rj] = old;\n            }\n            \n            temp *= 0.99988;\n        }\n    }\n    \n    string result;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) result += char('0' + best_rotations[i][j]);\n    cout << result << '\\n';\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> board;\nint er, ec;\n\nconst int DR[] = {0, -1, 0, 1};\nconst int DC[] = {-1, 0, 1, 0};\nconst char DCS[] = \"LURD\";\n\ninline int hval(char c) { return c >= 'a' ? c - 'a' + 10 : c - '0'; }\ninline bool ib(int r, int c) { return r >= 0 && r < N && c >= 0 && c < N; }\n\nint evalTree() {\n    vector<int> comp(N*N, -1), compEdges(N*N, 0), compSize(N*N, 0);\n    int numComp = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == '0') continue;\n            int idx = i * N + j;\n            if (comp[idx] != -1) continue;\n            \n            queue<pair<int,int>> q;\n            q.push({i,j});\n            comp[idx] = numComp;\n            \n            while (!q.empty()) {\n                auto [r,c] = q.front(); q.pop();\n                compSize[numComp]++;\n                int v = hval(board[r][c]);\n                \n                auto check = [&](int nr, int nc, int fb, int tb) {\n                    if (!ib(nr,nc) || board[nr][nc] == '0') return;\n                    int nv = hval(board[nr][nc]);\n                    if ((v & fb) && (nv & tb)) {\n                        compEdges[numComp]++;\n                        int nidx = nr * N + nc;\n                        if (comp[nidx] == -1) {\n                            comp[nidx] = numComp;\n                            q.push({nr,nc});\n                        }\n                    }\n                };\n                check(r,c-1,1,4); check(r-1,c,2,8); check(r,c+1,4,1); check(r+1,c,8,2);\n            }\n            numComp++;\n        }\n    }\n    \n    int best = 0;\n    for (int c = 0; c < numComp; c++) {\n        if (compEdges[c] / 2 == compSize[c] - 1)\n            best = max(best, compSize[c]);\n    }\n    return best;\n}\n\nint countEdges() {\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] == '0') continue;\n            int v = hval(board[i][j]);\n            if ((v & 4) && j+1 < N && board[i][j+1] != '0' && (hval(board[i][j+1]) & 1)) cnt++;\n            if ((v & 8) && i+1 < N && board[i+1][j] != '0' && (hval(board[i+1][j]) & 2)) cnt++;\n        }\n    }\n    return cnt;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> T;\n    board.resize(N);\n    vector<string> origBoard(N);\n    int origEr, origEc;\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n        origBoard[i] = board[i];\n        for (int j = 0; j < N; j++)\n            if (board[i][j] == '0') { er = i; ec = j; origEr = er; origEc = ec; }\n    }\n    \n    mt19937 rng(123);\n    uniform_real_distribution<double> prob(0.0, 1.0);\n    \n    vector<string> bestBoard = board;\n    int bestEr = er, bestEc = ec;\n    int bestTree = evalTree();\n    string bestResult;\n    \n    string result;\n    int lastDir = -1;\n    int noImprove = 0;\n    int restartCount = 0;\n    double temp = 8.0;\n    \n    for (int step = 0; step < T && (int)result.size() < T; step++) {\n        vector<pair<int,int>> moves;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = er + DR[d], nc = ec + DC[d];\n            if (!ib(nr, nc)) continue;\n            \n            swap(board[er][ec], board[nr][nc]);\n            int edges = countEdges();\n            swap(board[er][ec], board[nr][nc]);\n            \n            int penalty = (d == (lastDir + 2) % 4) ? 3 : 0;\n            moves.push_back({d, edges - penalty});\n        }\n        \n        if (moves.empty()) break;\n        \n        sort(moves.begin(), moves.end(), [](auto& a, auto& b) { return a.second > b.second; });\n        \n        int d;\n        double expP = 0.2 * temp / 8.0;\n        \n        if (prob(rng) < expP && moves.size() > 1) {\n            d = moves[1 + rng() % (moves.size() - 1)].first;\n        } else {\n            d = moves[0].first;\n        }\n        \n        int nr = er + DR[d], nc = ec + DC[d];\n        swap(board[er][ec], board[nr][nc]);\n        er = nr; ec = nc;\n        result += DCS[d];\n        lastDir = d;\n        \n        temp = max(0.3, temp * 0.9995);\n        noImprove++;\n        \n        if (step % 8 == 7) {\n            int treeSize = evalTree();\n            if (treeSize > bestTree) {\n                bestTree = treeSize;\n                bestBoard = board;\n                bestEr = er;\n                bestEc = ec;\n                bestResult = result;\n                noImprove = 0;\n            }\n            if (treeSize == N*N - 1) break;\n            \n            if (noImprove > 20) {\n                restartCount++;\n                // Mix of restarts: mostly from best, sometimes from scratch\n                int rtype = restartCount % 6;\n                if (rtype == 0) {\n                    board = origBoard;\n                    er = origEr;\n                    ec = origEc;\n                    result.clear();\n                    temp = 8.0;\n                } else {\n                    board = bestBoard;\n                    er = bestEr;\n                    ec = bestEc;\n                    result = bestResult;\n                    if (rtype == 3) temp = min(8.0, temp + 2.0);\n                }\n                lastDir = -1;\n                noImprove = 0;\n                rng.seed(rng());\n            }\n        }\n    }\n    \n    if (bestResult.empty()) bestResult = result;\n    cout << bestResult << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\ntypedef pair<ll, ll> PLL;\n\nconst ll LIM = 1000000000LL;\n\ninline ll cross(PLL a, PLL b) { return a.first * b.second - a.second * b.first; }\n\ninline int side(PLL p1, PLL p2, PLL q) {\n    PLL d = {p2.first - p1.first, p2.second - p1.second};\n    PLL e = {q.first - p1.first, q.second - p1.second};\n    ll c = cross(d, e);\n    return (c > 0) ? 1 : (c < 0) ? -1 : 0;\n}\n\nint N, K;\nint a[11];\nvector<PLL> S;\nint maxScore;\n\nstruct VectorHash {\n    size_t operator()(const vector<int>& v) const {\n        size_t h = 0;\n        for (int x : v) h = h * 3 + (x + 1);\n        return h;\n    }\n};\n\nint computeScore(const vector<pair<PLL, PLL>>& lines) {\n    int L = lines.size();\n    unordered_map<vector<int>, int, VectorHash> cells;\n    cells.reserve(N * 2);\n    static int sides[105];\n    for (const auto& s : S) {\n        int len = 0;\n        bool cut = false;\n        for (int i = 0; i < L; i++) {\n            int sd = side(lines[i].first, lines[i].second, s);\n            if (sd == 0) { cut = true; break; }\n            sides[len++] = sd;\n        }\n        if (!cut) {\n            vector<int> key(sides, sides + len);\n            cells[key]++;\n        }\n    }\n    int b[11] = {0};\n    for (auto& p : cells) if (p.second >= 1 && p.second <= 10) b[p.second]++;\n    int score = 0;\n    for (int d = 1; d <= 10; d++) score += min(a[d], b[d]);\n    return score;\n}\n\ninline ll clampCoord(ll x) { return max(-LIM, min(LIM, x)); }\n\nuint64_t xorshift128plus_state[2] = {0x123456789ABCDEF0ULL, 0xFEDCBA9876543210ULL};\n\ninline uint64_t xorshift128plus() {\n    uint64_t s1 = xorshift128plus_state[0];\n    const uint64_t s0 = xorshift128plus_state[1];\n    const uint64_t result = s0 + s1;\n    xorshift128plus_state[0] = s0;\n    s1 ^= s1 << 23;\n    xorshift128plus_state[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5);\n    return result;\n}\n\ninline ll randCoord() { return (ll)(xorshift128plus() % (2ULL * LIM + 1)) - LIM; }\ninline int randInt(int n) { return xorshift128plus() % n; }\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    cin >> N >> K;\n    for (int i = 1; i <= 10; i++) cin >> a[i];\n    S.resize(N);\n    for (int i = 0; i < N; i++) cin >> S[i].first >> S[i].second;\n    maxScore = accumulate(a + 1, a + 11, 0);\n    \n    xorshift128plus_state[0] = 42;\n    xorshift128plus_state[1] = 12345;\n    \n    vector<pair<PLL, PLL>> bestCuts;\n    int bestScore = 0;\n    clock_t start = clock();\n    const double timeLimit = 2.85;\n    \n    while ((double)(clock() - start) / CLOCKS_PER_SEC < timeLimit && bestScore < maxScore) {\n        vector<pair<PLL, PLL>> cuts;\n        int curScore = 0;\n        \n        for (int i = 0; i < K; i++) {\n            if ((double)(clock() - start) / CLOCKS_PER_SEC >= timeLimit) break;\n            \n            pair<PLL, PLL> bestLine;\n            int bestNew = curScore; bool found = false;\n            \n            for (int t = 0; t < 50; t++) {\n                PLL p1, p2;\n                int strat = randInt(10);\n                \n                if (strat < 7 && N >= 2) {\n                    int i1 = randInt(N), i2 = randInt(N);\n                    if (i1 != i2) {\n                        ll mx = S[i1].first + S[i2].first;\n                        ll my = S[i1].second + S[i2].second;\n                        ll dx = S[i2].first - S[i1].first;\n                        ll dy = S[i2].second - S[i1].second;\n                        p1 = {clampCoord(mx + dy), clampCoord(my - dx)};\n                        p2 = {clampCoord(mx - dy), clampCoord(my + dx)};\n                    } else continue;\n                } else {\n                    p1 = {randCoord(), randCoord()};\n                    p2 = {randCoord(), randCoord()};\n                }\n                \n                if (p1 == p2) continue;\n                \n                cuts.push_back({p1, p2});\n                int sc = computeScore(cuts);\n                cuts.pop_back();\n                \n                if (sc > bestNew) {\n                    bestNew = sc;\n                    bestLine = {p1, p2};\n                    found = true;\n                }\n            }\n            \n            if (found) {\n                cuts.push_back(bestLine);\n                curScore = bestNew;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestCuts = cuts;\n                }\n            }\n        }\n        \n        for (int ls = 0; ls < 500; ls++) {\n            if ((double)(clock() - start) / CLOCKS_PER_SEC >= timeLimit) break;\n            if (cuts.empty()) break;\n            \n            int idx = randInt(cuts.size());\n            auto old = cuts[idx];\n            \n            PLL p1, p2;\n            int strat = randInt(10);\n            \n            if (strat < 7 && N >= 2) {\n                int i1 = randInt(N), i2 = randInt(N);\n                if (i1 != i2) {\n                    ll mx = S[i1].first + S[i2].first;\n                    ll my = S[i1].second + S[i2].second;\n                    ll dx = S[i2].first - S[i1].first;\n                    ll dy = S[i2].second - S[i1].second;\n                    p1 = {clampCoord(mx + dy), clampCoord(my - dx)};\n                    p2 = {clampCoord(mx - dy), clampCoord(my + dx)};\n                } else continue;\n            } else {\n                p1 = {randCoord(), randCoord()};\n                p2 = {randCoord(), randCoord()};\n            }\n            \n            if (p1 == p2) continue;\n            \n            cuts[idx] = {p1, p2};\n            int sc = computeScore(cuts);\n            \n            if (sc >= curScore) {\n                curScore = sc;\n                if (curScore > bestScore) {\n                    bestScore = curScore;\n                    bestCuts = cuts;\n                }\n            } else {\n                cuts[idx] = old;\n            }\n        }\n    }\n    \n    cout << bestCuts.size() << \"\\n\";\n    for (auto& l : bestCuts) {\n        cout << l.first.first << \" \" << l.first.second << \" \" \n             << l.second.first << \" \" << l.second.second << \"\\n\";\n    }\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble C;\nvector<vector<bool>> dot;\nvector<vector<int>> W;\nstruct EdgeHash {\n    size_t operator()(const array<int,4>& e) const {\n        return ((size_t)e[0] << 42) ^ ((size_t)e[1] << 28) ^ ((size_t)e[2] << 14) ^ e[3];\n    }\n};\nunordered_set<array<int,4>, EdgeHash> used_edges;\nvector<array<int,8>> ops;\nchrono::steady_clock::time_point T0;\nmt19937_64 rng(42);\n\ndouble elapsed() { return chrono::duration<double>(chrono::steady_clock::now() - T0).count(); }\ninline int wt(int x, int y) { return W[x][y]; }\nbool inB(int x, int y) { return x >= 0 && x < N && y >= 0 && y < N; }\n\nint myGcd(int a, int b) { a=abs(a); b=abs(b); while(b){a%=b; swap(a,b);} return a; }\n\narray<int,4> normE(int x1, int y1, int x2, int y2) {\n    if (x1 > x2 || (x1 == x2 && y1 > y2)) { swap(x1,x2); swap(y1,y2); }\n    return {x1, y1, x2, y2};\n}\n\nbool pathClear(int x1, int y1, int x2, int y2) {\n    int dx = x2-x1, dy = y2-y1, g = myGcd(dx, dy);\n    if (g <= 1) return true;\n    int sx = dx/g, sy = dy/g;\n    for (int i = 1; i < g; i++) if (dot[x1+i*sx][y1+i*sy]) return false;\n    return true;\n}\n\nbool canAddEdge(int x1, int y1, int x2, int y2) {\n    int dx = x2-x1, dy = y2-y1, g = myGcd(dx, dy);\n    if (g == 0) return true;\n    int sx = dx/g, sy = dy/g;\n    for (int i = 0; i < g; i++) {\n        if (used_edges.count(normE(x1+i*sx, y1+i*sy, x1+(i+1)*sx, y1+(i+1)*sy))) return false;\n    }\n    return true;\n}\n\nvoid addEdge(int x1, int y1, int x2, int y2) {\n    int dx = x2-x1, dy = y2-y1, g = myGcd(dx, dy);\n    if (g == 0) return;\n    int sx = dx/g, sy = dy/g;\n    for (int i = 0; i < g; i++) used_edges.insert(normE(x1+i*sx, y1+i*sy, x1+(i+1)*sx, y1+(i+1)*sy));\n}\n\nbool tryRectDirect(int ex, int ey, int x2, int y2, int x3, int y3, int x4, int y4) {\n    int cx[] = {ex, x2, x3, x4}, cy[] = {ey, y2, y3, y4};\n    if (dot[ex][ey]) return false;\n    for (int i = 1; i < 4; i++) if (!dot[cx[i]][cy[i]]) return false;\n    for (int i = 0; i < 4; i++) {\n        int dx = cx[(i+1)%4]-cx[i], dy = cy[(i+1)%4]-cy[i];\n        if (dx==0 && dy==0) return false;\n        if (dx!=0 && dy!=0 && abs(dx)!=abs(dy)) return false;\n    }\n    for (int i = 0; i < 4; i++) {\n        int dx1=cx[(i+1)%4]-cx[i], dy1=cy[(i+1)%4]-cy[i];\n        int dx2=cx[(i+2)%4]-cx[(i+1)%4], dy2=cy[(i+2)%4]-cy[(i+1)%4];\n        if (dx1*dx2 + dy1*dy2 != 0) return false;\n    }\n    for (int i = 0; i < 4; i++) if (!pathClear(cx[i],cy[i],cx[(i+1)%4],cy[(i+1)%4])) return false;\n    for (int i = 0; i < 4; i++) if (!canAddEdge(cx[i],cy[i],cx[(i+1)%4],cy[(i+1)%4])) return false;\n    dot[ex][ey] = true;\n    for (int i = 0; i < 4; i++) addEdge(cx[i],cy[i],cx[(i+1)%4],cy[(i+1)%4]);\n    ops.push_back({ex,ey,x2,y2,x3,y3,x4,y4});\n    return true;\n}\n\nint solveScore;\n\nvector<array<int,8>> solve(vector<vector<bool>>& initDot, int mode, int perturb) {\n    dot = initDot;\n    used_edges.clear();\n    ops.clear();\n    used_edges.reserve(N*N*4);\n    ops.reserve(N*N/2);\n    \n    vector<vector<int>> byR(N), byC(N), byDP(2*N), byDM(2*N);\n    for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (dot[x][y]) {\n        byR[y].push_back(x); byC[x].push_back(y);\n        byDP[x+y].push_back(x); byDM[x-y+N-1].push_back(x);\n    }\n    \n    while (elapsed() < 4.8) {\n        vector<tuple<int,int,int>> E;\n        E.reserve(N*N);\n        for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (!dot[x][y]) {\n            int w = W[x][y];\n            if (perturb > 0) w = w + (rng() % perturb) - perturb/2;\n            E.emplace_back(w, x, y);\n        }\n        \n        if (mode == 0) sort(E.begin(), E.end(), [](auto& a, auto& b){ return get<0>(a) > get<0>(b); });\n        else if (mode == 1) shuffle(E.begin(), E.end(), rng);\n        else sort(E.begin(), E.end(), [](auto& a, auto& b){ return get<0>(a) > get<0>(b); });\n        \n        bool found = false;\n        for (auto& [w, nx, ny] : E) {\n            for (int x2 : byR[ny]) { if (x2 == nx) continue;\n                for (int y3 : byC[nx]) { if (y3 == ny) continue;\n                    if (dot[x2][y3] && tryRectDirect(nx, ny, x2, ny, x2, y3, nx, y3)) {\n                        byR[ny].push_back(nx); byC[nx].push_back(ny);\n                        byDP[nx+ny].push_back(nx); byDM[nx-ny+N-1].push_back(nx);\n                        found = true; goto added;\n                    }\n                }\n            }\n            int ds = nx + ny, dm = nx - ny + N - 1;\n            for (int x2 : byDM[dm]) { int y2 = x2-(nx-ny); if (x2==nx) continue;\n                for (int x4 : byDP[ds]) { int y4 = ds-x4; if (x4==nx) continue;\n                    int x3 = x2+x4-nx, y3 = y2+y4-ny;\n                    if (inB(x3,y3) && dot[x3][y3] && tryRectDirect(nx, ny, x2, y2, x3, y3, x4, y4)) {\n                        byR[ny].push_back(nx); byC[nx].push_back(ny);\n                        byDP[nx+ny].push_back(nx); byDM[nx-ny+N-1].push_back(nx);\n                        found = true; goto added;\n                    }\n                }\n            }\n        }\n        added:;\n        if (!found) break;\n    }\n    \n    solveScore = 0;\n    for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) if (dot[x][y]) solveScore += W[x][y];\n    return ops;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    T0 = chrono::steady_clock::now();\n    cin >> N >> M; C = (N-1)/2.0;\n    \n    W.assign(N, vector<int>(N));\n    for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) W[x][y] = (int)((x-C)*(x-C) + (y-C)*(y-C) + 1);\n    \n    vector<vector<bool>> initDot(N, vector<bool>(N, false));\n    for (int i = 0; i < M; i++) { int x,y; cin >> x >> y; initDot[x][y] = true; }\n    \n    solve(initDot, 0, 0);\n    int bestScore = solveScore;\n    auto bestOps = ops;\n    \n    int iter = 0;\n    while (elapsed() < 4.7) {\n        iter++;\n        int mode = 1 + (iter % 2); // alternate between 1 and 2\n        int perturb = 100 * (1 + iter % 5);\n        solve(initDot, mode, perturb);\n        if (solveScore > bestScore) {\n            bestScore = solveScore;\n            bestOps = ops;\n        }\n    }\n    \n    cout << bestOps.size() << \"\\n\";\n    for (auto& o : bestOps) { for (int i = 0; i < 8; i++) cout << o[i] << \" \\n\"[i==7]; }\n    return 0;\n}","ahc015":"#include <cstdio>\n#include <cstring>\n\nint G[10][10], F[100];\n\nvoid tilt(int g[][10], int d) {\n    int n[10][10] = {};\n    if (d == 0) for (int c = 0; c < 10; c++) { int w = 0; for (int r = 0; r < 10; r++) if (g[r][c]) n[w++][c] = g[r][c]; }\n    else if (d == 1) for (int c = 0; c < 10; c++) { int w = 9; for (int r = 9; r >= 0; r--) if (g[r][c]) n[w--][c] = g[r][c]; }\n    else if (d == 2) for (int r = 0; r < 10; r++) { int w = 0; for (int c = 0; c < 10; c++) if (g[r][c]) n[r][w++] = g[r][c]; }\n    else for (int r = 0; r < 10; r++) { int w = 9; for (int c = 9; c >= 0; c--) if (g[r][c]) n[r][w--] = g[r][c]; }\n    memcpy(g, n, 400);\n}\n\nlong long calc(int g[][10]) {\n    int v[10][10] = {};\n    long long s = 0;\n    for (int r = 0; r < 10; r++) for (int c = 0; c < 10; c++) if (g[r][c] && !v[r][c]) {\n        int q[100], h = 0, t = 0, sz = 0, f = g[r][c];\n        q[t++] = r*10+c; v[r][c] = 1;\n        while (h < t) { \n            int cr = q[h]/10, cc = q[h]%10; h++; sz++;\n            if (cr > 0 && !v[cr-1][cc] && g[cr-1][cc] == f) { v[cr-1][cc] = 1; q[t++] = (cr-1)*10+cc; }\n            if (cr < 9 && !v[cr+1][cc] && g[cr+1][cc] == f) { v[cr+1][cc] = 1; q[t++] = (cr+1)*10+cc; }\n            if (cc > 0 && !v[cr][cc-1] && g[cr][cc-1] == f) { v[cr][cc-1] = 1; q[t++] = cr*10+cc-1; }\n            if (cc < 9 && !v[cr][cc+1] && g[cr][cc+1] == f) { v[cr][cc+1] = 1; q[t++] = cr*10+cc+1; }\n        }\n        s += (long long)sz*sz;\n    }\n    return s;\n}\n\nlong long evaluate(int g[][10], int t) {\n    long long score = calc(g) * 10000;\n    \n    // Adjacency bonus\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        if (r > 0 && g[r-1][c] == f) score += 50;\n        if (c > 0 && g[r][c-1] == f) score += 50;\n        // Wall bonus\n        if (r == 0 || r == 9 || c == 0 || c == 9) score += 5;\n    }\n    \n    // Future potential\n    int rem = 100 - t - 1;\n    for (int i = 0; i < rem && i < 15; i++) {\n        int f = F[t + 1 + i];\n        int w = 15 - i;\n        for (int r = 0; r < 10; r++) for (int c = 0; c < 10; c++) if (g[r][c] == f) {\n            if (r > 0 && !g[r-1][c]) score += w;\n            if (r < 9 && !g[r+1][c]) score += w;\n            if (c > 0 && !g[r][c-1]) score += w;\n            if (c < 9 && !g[r][c+1]) score += w;\n        }\n    }\n    \n    return score;\n}\n\nint main() {\n    for (int i = 0; i < 100; i++) scanf(\"%d\", &F[i]);\n    \n    for (int t = 0; t < 100; t++) {\n        int p; scanf(\"%d\", &p);\n        int cnt = 0;\n        for (int i = 0; i < 100; i++) {\n            if (!G[i/10][i%10] && ++cnt == p) { G[i/10][i%10] = F[t]; break; }\n        }\n        \n        long long best = -1; int bd = 0;\n        for (int d = 0; d < 4; d++) {\n            int tmp[10][10]; memcpy(tmp, G, 400);\n            tilt(tmp, d);\n            long long sc = evaluate(tmp, t);\n            if (sc > best) { best = sc; bd = d; }\n        }\n        \n        tilt(G, bd);\n        printf(\"%c\\n\", \"FBLR\"[bd]);\n        fflush(stdout);\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint M, N, total_edges;\ndouble eps;\nvector<string> G;\nvector<int> edge_counts;\nvector<vector<int>> deg_seqs;\nvector<long long> tri_counts;\nvector<int> max_degs;\nvector<double> deg_vars;\n\nint idx(int i, int j) {\n    if (i > j) swap(i, j);\n    return i * (2 * N - i - 1) / 2 + (j - i - 1);\n}\n\nlong long count_triangles(const string& g) {\n    long long cnt = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = i+1; j < N; j++)\n            if (g[idx(i,j)] == '1')\n                for (int k = j+1; k < N; k++)\n                    if (g[idx(i,k)] == '1' && g[idx(j,k)] == '1') cnt++;\n    return cnt;\n}\n\nvoid compute_features(int k) {\n    edge_counts[k] = count(G[k].begin(), G[k].end(), '1');\n    vector<int> deg(N, 0);\n    for (int i = 0; i < N; i++)\n        for (int j = i+1; j < N; j++)\n            if (G[k][idx(i,j)] == '1') { deg[i]++; deg[j]++; }\n    max_degs[k] = *max_element(deg.begin(), deg.end());\n    double mean = 2.0 * edge_counts[k] / N;\n    double var = 0;\n    for (int d : deg) var += (d - mean) * (d - mean);\n    deg_vars[k] = sqrt(var / N);\n    sort(deg.begin(), deg.end());\n    deg_seqs[k] = deg;\n    tri_counts[k] = count_triangles(G[k]);\n}\n\nvoid generate_graphs() {\n    total_edges = N * (N - 1) / 2;\n    G.assign(M, string(total_edges, '0'));\n    edge_counts.resize(M);\n    deg_seqs.assign(M, vector<int>(N));\n    tri_counts.resize(M);\n    max_degs.resize(M);\n    deg_vars.resize(M);\n    \n    for (int k = 0; k < M; k++) {\n        double frac = (M > 1) ? (double)k / (M - 1) : 0.5;\n        int target = (int)round(frac * total_edges);\n        int added = 0;\n        for (int i = 0; i < N && added < target; i++)\n            for (int j = i+1; j < N && added < target; j++, added++)\n                G[k][idx(i,j)] = '1';\n        compute_features(k);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> M >> eps;\n    \n    int min_n = max(4, (int)ceil((1.0 + sqrt(1.0 + 8.0 * (M - 1))) / 2.0));\n    double noise = sqrt(eps * (1 - eps));\n    \n    double base_factor = 2.5 + M * 0.025;\n    double eps_factor = eps * 5.0;\n    int add_n = (int)(M * noise * (base_factor + eps_factor));\n    \n    if (eps > 0.3) add_n = max(add_n, (int)(M * noise * 6.0));\n    if (eps > 0.35) add_n = max(add_n, 100 - min_n);\n    \n    if (eps > 0.1) add_n = max(add_n, (int)(sqrt(M) * eps * 35));\n    \n    N = min(100, min_n + add_n);\n    \n    generate_graphs();\n    \n    cout << N << \"\\n\";\n    for (int k = 0; k < M; k++) cout << G[k] << \"\\n\";\n    cout << flush;\n    \n    double scale = max(0.001, 1 - 2*eps);\n    long long total_tri = (long long)N * (N-1) * (N-2) / 6;\n    double tri_factor = pow(1-eps, 3) - pow(eps, 3);\n    \n    double edge_sd = sqrt(max(1.0, total_edges * eps * (1-eps)));\n    double deg_sd = sqrt(max(1.0, (N-1) * eps * (1-eps)));\n    double tri_sd = sqrt(max(1.0, total_tri * eps * (1-eps) * 3));\n    \n    for (int q = 0; q < 100; q++) {\n        string H; cin >> H;\n        \n        int h_edges = count(H.begin(), H.end(), '1');\n        vector<int> h_deg(N, 0);\n        for (int i = 0; i < N; i++)\n            for (int j = i+1; j < N; j++)\n                if (H[idx(i,j)] == '1') { h_deg[i]++; h_deg[j]++; }\n        int h_max = *max_element(h_deg.begin(), h_deg.end());\n        double h_mean = 2.0 * h_edges / N;\n        double h_var = 0;\n        for (int d : h_deg) h_var += (d - h_mean) * (d - h_mean);\n        double h_stdev = sqrt(h_var / N);\n        sort(h_deg.begin(), h_deg.end());\n        long long h_tri = count_triangles(H);\n        \n        int best = 0;\n        double best_score = 1e18;\n        \n        for (int k = 0; k < M; k++) {\n            double exp_e = edge_counts[k] * scale + eps * total_edges;\n            double z_edge = abs(h_edges - exp_e) / edge_sd;\n            \n            double z_deg = 0;\n            for (int i = 0; i < N; i++) {\n                double exp_deg = deg_seqs[k][i] * scale + eps * (N-1);\n                z_deg += pow(h_deg[i] - exp_deg, 2);\n            }\n            z_deg = sqrt(z_deg / N) / deg_sd;\n            \n            double exp_tri = tri_counts[k] * tri_factor + total_tri * pow(eps, 3);\n            double z_tri = abs(h_tri - exp_tri) / tri_sd;\n            \n            double exp_max = max_degs[k] * scale + eps * (N-1);\n            double z_max = abs(h_max - exp_max) / deg_sd;\n            \n            double exp_var = deg_vars[k] * scale;\n            double z_var = abs(h_stdev - exp_var) / (deg_sd * sqrt(0.5));\n            \n            // Optimized weights based on testing\n            double w_deg = (eps < 0.1) ? 2.0 : (eps < 0.2) ? 1.5 : (eps < 0.3) ? 1.0 : (eps < 0.35) ? 0.5 : 0.3;\n            double w_tri = (eps < 0.05) ? 0.15 : (eps < 0.15) ? 0.1 : (eps < 0.25) ? 0.05 : (eps < 0.35) ? 0.02 : 0.01;\n            double w_max = (eps < 0.2) ? 0.4 : (eps < 0.35) ? 0.3 : 0.2;\n            double w_var = (eps < 0.15) ? 0.7 : (eps < 0.3) ? 0.5 : 0.3;\n            \n            double score = z_edge + z_deg * w_deg + z_tri * w_tri + z_max * w_max + z_var * w_var;\n            \n            if (score < best_score) {\n                best_score = score;\n                best = k;\n            }\n        }\n        \n        cout << best << \"\\n\" << flush;\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\ntypedef pair<ll, int> pli;\nconst ll INF = 1e18;\n\nint N, M, D, K;\nvector<int> eu, ev, ew;\nvector<vector<pair<int, int>>> adj;\nvector<ll> imp;\nvector<vector<pair<int, ll>>> conf;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    auto start = chrono::steady_clock::now();\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    for (int i = 0; i < N; i++) { int x, y; cin >> x >> y; }\n    \n    // Edge betweenness\n    vector<ll> betw(M, 0);\n    for (int s = 0; s < N; s++) {\n        vector<ll> dist(N, INF);\n        vector<vector<int>> pred(N);\n        dist[s] = 0;\n        priority_queue<pli, vector<pli>, greater<pli>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& [v, eid] : adj[u]) {\n                ll nd = d + ew[eid];\n                if (dist[v] > nd) { dist[v] = nd; pred[v].clear(); pred[v].push_back(eid); pq.push({nd, v}); }\n                else if (dist[v] == nd) pred[v].push_back(eid);\n            }\n        }\n        for (int t = 0; t < N; t++) {\n            if (t == s || pred[t].empty()) continue;\n            vector<bool> vis(N, false);\n            queue<int> q; q.push(t); vis[t] = true;\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                for (int eid : pred[u]) {\n                    betw[eid]++;\n                    int p = (eu[eid] == u) ? ev[eid] : eu[eid];\n                    if (!vis[p]) { vis[p] = true; q.push(p); }\n                }\n            }\n        }\n    }\n    \n    // Detour estimation\n    auto dijkstra_skip = [&](int s, int skip) {\n        vector<ll> dist(N, INF);\n        dist[s] = 0;\n        priority_queue<pli, vector<pli>, greater<pli>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& [v, eid] : adj[u]) {\n                if (eid == skip) continue;\n                ll nd = d + ew[eid];\n                if (dist[v] > nd) { dist[v] = nd; pq.push({nd, v}); }\n            }\n        }\n        return dist;\n    };\n    \n    mt19937 rng_det(123);\n    uniform_int_distribution<int> re(0, M-1);\n    vector<ll> detour(M, 0);\n    for (int t = 0; t < min(M, 300); t++) {\n        int e = re(rng_det);\n        if (detour[e] > 0) { t--; continue; }\n        auto d = dijkstra_skip(eu[e], e);\n        detour[e] = d[ev[e]];\n    }\n    \n    ll max_b = *max_element(betw.begin(), betw.end());\n    ll max_d = *max_element(detour.begin(), detour.end());\n    imp.resize(M);\n    for (int i = 0; i < M; i++) {\n        imp[i] = betw[i] * 1000 / max(1LL, max_b) + detour[i] * 200 / max(1LL, max_d);\n    }\n    \n    // Conflict matrix\n    vector<unordered_map<int, ll>> conf_map(M);\n    int samples = min(N, 100);\n    for (int s = 0; s < samples; s++) {\n        vector<ll> dist(N, INF);\n        vector<vector<int>> pred(N);\n        dist[s] = 0;\n        priority_queue<pli, vector<pli>, greater<pli>> pq;\n        pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, u] = pq.top(); pq.pop();\n            if (d > dist[u]) continue;\n            for (auto& [v, eid] : adj[u]) {\n                ll nd = d + ew[eid];\n                if (dist[v] > nd) { dist[v] = nd; pred[v].clear(); pred[v].push_back(eid); pq.push({nd, v}); }\n                else if (dist[v] == nd) pred[v].push_back(eid);\n            }\n        }\n        for (int t = 0; t < N; t++) {\n            vector<int> edges;\n            queue<int> q; vector<bool> vis(N, false);\n            q.push(t); vis[t] = true;\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                for (int eid : pred[u]) {\n                    edges.push_back(eid);\n                    int p = (eu[eid] == u) ? ev[eid] : eu[eid];\n                    if (!vis[p]) { vis[p] = true; q.push(p); }\n                }\n            }\n            sort(edges.begin(), edges.end());\n            edges.erase(unique(edges.begin(), edges.end()), edges.end());\n            for (int i = 0; i < (int)edges.size(); i++)\n                for (int j = i+1; j < (int)edges.size(); j++)\n                    conf_map[min(edges[i],edges[j])][max(edges[i],edges[j])]++;\n        }\n    }\n    \n    conf.resize(M);\n    for (int i = 0; i < M; i++)\n        for (auto& [j, c] : conf_map[i]) conf[i].push_back({j, c});\n    conf_map.clear();\n    \n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) { return imp[a] > imp[b]; });\n    \n    // Round-robin initial assignment\n    vector<int> assign(M);\n    for (int i = 0; i < M; i++) assign[order[i]] = i % D;\n    \n    auto compute_score = [&]() {\n        vector<ll> ds(D, 0);\n        for (int i = 0; i < M; i++) ds[assign[i]] += imp[i];\n        for (int i = 0; i < M; i++) \n            for (auto& [j, c] : conf[i]) \n                if (assign[i] == assign[j]) ds[assign[i]] += c;\n        ll t = 0;\n        for (int d = 0; d < D; d++) t += ds[d] * ds[d];\n        return t;\n    };\n    \n    ll cur_score = compute_score();\n    \n    mt19937 rng(42);\n    uniform_int_distribution<int> rand_e(0, M-1);\n    uniform_real_distribution<double> rand_p(0.0, 1.0);\n    double temp = 1e6;\n    \n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() < 5750) {\n        int e1 = rand_e(rng), e2 = rand_e(rng);\n        if (e1 == e2 || assign[e1] == assign[e2]) continue;\n        \n        swap(assign[e1], assign[e2]);\n        ll new_score = compute_score();\n        \n        if (new_score < cur_score || rand_p(rng) < exp((cur_score - new_score) / temp)) {\n            cur_score = new_score;\n        } else {\n            swap(assign[e1], assign[e2]);\n        }\n        temp *= 0.9999;\n    }\n    \n    for (int i = 0; i < M; i++) cout << assign[i] + 1 << \" \\n\"[i == M-1];\n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f[2], r[2];\nint valid[2][15][15][15];\nint visited[15][15][15];\nint b[2][15][15][15];\nint dx[] = {1,-1,0,0,0,0}, dy[] = {0,0,1,-1,0,0}, dz[] = {0,0,0,0,1,-1};\nvector<array<array<int,3>,3>> rotations;\n\nvoid generateRotations() {\n    vector<array<int,3>> perms = {{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}};\n    for (int s0 : {-1,1}) for (int s1 : {-1,1}) for (int s2 : {-1,1}) {\n        int sp = s0*s1*s2;\n        for (auto& p : perms) {\n            int inv = 0; for (int i=0;i<3;i++) for (int j=i+1;j<3;j++) if (p[i]>p[j]) inv++;\n            if ((inv%2==0) == (sp==1)) {\n                array<array<int,3>,3> R = {};\n                R[0][p[0]]=s0; R[1][p[1]]=s1; R[2][p[2]]=s2;\n                rotations.push_back(R);\n            }\n        }\n    }\n}\n\nset<array<int,3>> normalize(const vector<array<int,3>>& s) {\n    int mX=INT_MAX,mY=INT_MAX,mZ=INT_MAX;\n    for (auto& p : s) { mX=min(mX,p[0]); mY=min(mY,p[1]); mZ=min(mZ,p[2]); }\n    set<array<int,3>> r;\n    for (auto& p : s) r.insert({p[0]-mX, p[1]-mY, p[2]-mZ});\n    return r;\n}\n\nset<array<int,3>> rotate(const set<array<int,3>>& s, const array<array<int,3>,3>& R) {\n    vector<array<int,3>> rot;\n    for (auto& p : s) rot.push_back({R[0][0]*p[0]+R[0][1]*p[1]+R[0][2]*p[2], R[1][0]*p[0]+R[1][1]*p[1]+R[1][2]*p[2], R[2][0]*p[0]+R[2][1]*p[1]+R[2][2]*p[2]});\n    return normalize(rot);\n}\n\nset<array<int,3>> canonical(const set<array<int,3>>& s) {\n    set<array<int,3>> best = s;\n    for (auto& R : rotations) { auto r = rotate(s,R); if (r < best) best = r; }\n    return best;\n}\n\nvector<array<int,3>> bfs(int sel, int sx, int sy, int sz, int interMode) {\n    vector<array<int,3>> comp;\n    queue<array<int,3>> q;\n    q.push({sx,sy,sz});\n    visited[sx][sy][sz] = 1;\n    while (!q.empty()) {\n        auto [x,y,z] = q.front(); q.pop();\n        comp.push_back({x,y,z});\n        for (int d = 0; d < 6; d++) {\n            int nx=x+dx[d], ny=y+dy[d], nz=z+dz[d];\n            if (nx>=0 && nx<D && ny>=0 && ny<D && nz>=0 && nz<D && !visited[nx][ny][nz]) {\n                bool in0 = valid[0][nx][ny][nz], in1 = valid[1][nx][ny][nz];\n                bool ok = false;\n                if (interMode == 0) ok = (sel==0 ? in0&&!in1 : !in0&&in1);\n                else ok = in0 && in1;\n                if (ok) { visited[nx][ny][nz] = 1; q.push({nx,ny,nz}); }\n            }\n        }\n    }\n    return comp;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    generateRotations();\n    cin >> D;\n    for (int i = 0; i < 2; i++) {\n        f[i].resize(D); r[i].resize(D);\n        for (int z = 0; z < D; z++) cin >> f[i][z];\n        for (int z = 0; z < D; z++) cin >> r[i][z];\n    }\n    for (int i = 0; i < 2; i++)\n        for (int x = 0; x < D; x++)\n            for (int y = 0; y < D; y++)\n                for (int z = 0; z < D; z++)\n                    valid[i][x][y][z] = (f[i][z][x]=='1' && r[i][z][y]=='1');\n    \n    vector<vector<array<int,3>>> inter_comps, v1_comps, v2_comps;\n    memset(visited, 0, sizeof(visited));\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++)\n        if (valid[0][x][y][z] && valid[1][x][y][z] && !visited[x][y][z])\n            inter_comps.push_back(bfs(0,x,y,z,1));\n    \n    memset(visited, 0, sizeof(visited));\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++)\n        if (valid[0][x][y][z] && !valid[1][x][y][z] && !visited[x][y][z])\n            v1_comps.push_back(bfs(0,x,y,z,0));\n    \n    memset(visited, 0, sizeof(visited));\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++)\n        if (!valid[0][x][y][z] && valid[1][x][y][z] && !visited[x][y][z])\n            v2_comps.push_back(bfs(1,x,y,z,0));\n    \n    map<set<array<int,3>>, vector<int>> can_v1, can_v2;\n    for (int i = 0; i < (int)v1_comps.size(); i++) can_v1[canonical(normalize(v1_comps[i]))].push_back(i);\n    for (int i = 0; i < (int)v2_comps.size(); i++) can_v2[canonical(normalize(v2_comps[i]))].push_back(i);\n    \n    vector<int> m1(v1_comps.size(),-1), m2(v2_comps.size(),-1);\n    for (auto& [c, idx1] : can_v1) {\n        if (can_v2.count(c)) {\n            auto& idx2 = can_v2[c];\n            for (int k = 0; k < (int)min(idx1.size(), idx2.size()); k++) { m1[idx1[k]] = idx2[k]; m2[idx2[k]] = idx1[k]; }\n        }\n    }\n    \n    memset(b, 0, sizeof(b));\n    int bid = 0;\n    for (auto& c : inter_comps) { bid++; for (auto& p : c) b[0][p[0]][p[1]][p[2]] = b[1][p[0]][p[1]][p[2]] = bid; }\n    for (int i = 0; i < (int)v1_comps.size(); i++) {\n        bid++;\n        for (auto& p : v1_comps[i]) b[0][p[0]][p[1]][p[2]] = bid;\n        if (m1[i] >= 0) for (auto& p : v2_comps[m1[i]]) b[1][p[0]][p[1]][p[2]] = bid;\n    }\n    for (int i = 0; i < (int)v2_comps.size(); i++) if (m2[i] < 0) {\n        bid++;\n        for (auto& p : v2_comps[i]) b[1][p[0]][p[1]][p[2]] = bid;\n    }\n    \n    cout << bid << \"\\n\";\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++) cout << (x||y||z?\" \":\"\") << b[0][x][y][z];\n    cout << \"\\n\";\n    for (int x=0;x<D;x++) for (int y=0;y<D;y++) for (int z=0;z<D;z++) cout << (x||y||z?\" \":\"\") << b[1][x][y][z];\n    cout << \"\\n\";\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\ntypedef pair<ll, int> pli;\ntypedef pair<int, int> pii;\n\nint N, M, K;\nvector<int> x, y;\nvector<tuple<int, int, ll>> edges;\nvector<int> a, b;\nvector<vector<pii>> adj;\nvector<ll> distTo0;\nvector<int> parent, parent_edge;\n\nint calcDist(int x1, int y1, int x2, int y2) {\n    ll dx = x1 - x2, dy = y1 - y2;\n    return (int)round(sqrt(dx*dx + dy*dy));\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K;\n    x.resize(N); y.resize(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    edges.resize(M); adj.resize(N);\n    for (int j = 0; j < M; j++) {\n        int uj, vj; ll wj;\n        cin >> uj >> vj >> wj;\n        uj--; vj--;\n        edges[j] = {uj, vj, wj};\n        adj[uj].push_back({vj, j});\n        adj[vj].push_back({uj, j});\n    }\n    \n    a.resize(K); b.resize(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    // Dijkstra from vertex 0\n    distTo0.assign(N, LLONG_MAX);\n    parent.assign(N, -1);\n    parent_edge.assign(N, -1);\n    priority_queue<pli, vector<pli>, greater<pli>> pq;\n    distTo0[0] = 0; pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > distTo0[u]) continue;\n        for (auto [v, ej] : adj[u]) {\n            ll wj = get<2>(edges[ej]);\n            if (distTo0[u] + wj < distTo0[v]) {\n                distTo0[v] = distTo0[u] + wj;\n                parent[v] = u; parent_edge[v] = ej;\n                pq.push({distTo0[v], v});\n            }\n        }\n    }\n    \n    // Precompute distances\n    vector<vector<int>> resToStation(K, vector<int>(N));\n    for (int k = 0; k < K; k++) {\n        for (int i = 0; i < N; i++) {\n            resToStation[k][i] = calcDist(a[k], b[k], x[i], y[i]);\n        }\n    }\n    \n    // Cost-aware greedy assignment\n    vector<int> res_station(K);\n    vector<int> station_power(N, 0);\n    set<int> active;\n    \n    // Process residents by difficulty (farthest first)\n    vector<int> order(K);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int k1, int k2) {\n        int m1 = *min_element(resToStation[k1].begin(), resToStation[k1].end());\n        int m2 = *min_element(resToStation[k2].begin(), resToStation[k2].end());\n        return m1 > m2;\n    });\n    \n    for (int k : order) {\n        ll bestCost = LLONG_MAX;\n        int bestStation = -1;\n        \n        for (int i = 0; i < N; i++) {\n            int d = resToStation[k][i];\n            if (d > 5000) continue;\n            \n            ll cost;\n            if (active.count(i)) {\n                int newP = max(station_power[i], d);\n                cost = (ll)newP * newP - (ll)station_power[i] * station_power[i];\n            } else {\n                cost = distTo0[i] + (ll)d * d;\n            }\n            \n            if (cost < bestCost) {\n                bestCost = cost;\n                bestStation = i;\n            }\n        }\n        \n        if (bestStation >= 0) {\n            res_station[k] = bestStation;\n            station_power[bestStation] = max(station_power[bestStation], resToStation[k][bestStation]);\n            active.insert(bestStation);\n        }\n    }\n    \n    // Build edge set\n    vector<int> B(M, 0);\n    auto buildEdges = [&]() {\n        fill(B.begin(), B.end(), 0);\n        for (int i : active) {\n            int cur = i;\n            while (parent[cur] != -1) {\n                B[parent_edge[cur]] = 1;\n                cur = parent[cur];\n            }\n        }\n    };\n    buildEdges();\n    \n    // Remove redundant edges\n    auto getReachable = [&]() {\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(0);\n        visited[0] = true;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (auto [v, ej] : adj[u]) {\n                if (B[ej] && !visited[v]) {\n                    visited[v] = true;\n                    q.push(v);\n                }\n            }\n        }\n        return visited;\n    };\n    \n    auto removeRedundantEdges = [&]() {\n        vector<int> edgeOrder(M);\n        iota(edgeOrder.begin(), edgeOrder.end(), 0);\n        sort(edgeOrder.begin(), edgeOrder.end(), [&](int j1, int j2) {\n            return get<2>(edges[j1]) > get<2>(edges[j2]);\n        });\n        for (int j : edgeOrder) {\n            if (!B[j]) continue;\n            B[j] = 0;\n            auto visited = getReachable();\n            for (int i : active) {\n                if (!visited[i]) { B[j] = 1; break; }\n            }\n        }\n    };\n    removeRedundantEdges();\n    \n    // Local search: remove expensive stations\n    for (int iter = 0; iter < 50; iter++) {\n        bool improved = false;\n        vector<int> stationList(active.begin(), active.end());\n        sort(stationList.begin(), stationList.end(), [&](int i1, int i2) {\n            return (ll)station_power[i1]*station_power[i1] > (ll)station_power[i2]*station_power[i2];\n        });\n        \n        for (int si : stationList) {\n            if (si == 0) continue;\n            \n            vector<int> myRes;\n            for (int k = 0; k < K; k++) if (res_station[k] == si) myRes.push_back(k);\n            if (myRes.empty()) continue;\n            \n            map<int, int> newPowers;\n            vector<int> newAssign(myRes.size());\n            bool ok = true;\n            \n            for (int idx = 0; idx < (int)myRes.size(); idx++) {\n                int k = myRes[idx];\n                ll bestCost = LLONG_MAX;\n                int bestJ = -1;\n                \n                for (int j = 0; j < N; j++) {\n                    if (j == si) continue;\n                    int d = resToStation[k][j];\n                    if (d > 5000) continue;\n                    \n                    int curP = station_power[j];\n                    if (newPowers.count(j)) curP = newPowers[j];\n                    int newP = max(curP, d);\n                    ll cost = (ll)newP*newP - (ll)curP*curP;\n                    if (!active.count(j) && j != 0) cost += distTo0[j];\n                    \n                    if (cost < bestCost) { bestCost = cost; bestJ = j; }\n                }\n                \n                if (bestJ < 0) { ok = false; break; }\n                newAssign[idx] = bestJ;\n                int d = resToStation[k][bestJ];\n                int curP = station_power[bestJ];\n                if (newPowers.count(bestJ)) curP = newPowers[bestJ];\n                newPowers[bestJ] = max(curP, d);\n            }\n            \n            if (!ok) continue;\n            \n            set<int> newActive = active;\n            newActive.erase(si);\n            for (auto& [j, p] : newPowers) if (!active.count(j) && j != 0) newActive.insert(j);\n            \n            ll oldCost = (ll)station_power[si]*station_power[si] + distTo0[si];\n            ll newCost = 0;\n            for (auto& [j, p] : newPowers) {\n                newCost += (ll)p*p - (ll)station_power[j]*station_power[j];\n                if (!active.count(j) && j != 0) newCost += distTo0[j];\n            }\n            \n            if (newCost < oldCost) {\n                improved = true;\n                active = newActive;\n                station_power[si] = 0;\n                for (int idx = 0; idx < (int)myRes.size(); idx++) {\n                    res_station[myRes[idx]] = newAssign[idx];\n                }\n                for (auto& [j, p] : newPowers) station_power[j] = p;\n                buildEdges();\n                removeRedundantEdges();\n            }\n        }\n        if (!improved) break;\n    }\n    \n    for (int i = 0; i < N; i++) cout << station_power[i] << (i < N-1 ? \" \" : \"\\n\");\n    for (int j = 0; j < M; j++) cout << B[j] << (j < M-1 ? \" \" : \"\\n\");\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int TOTAL = N * (N + 1) / 2;\n\nint pyramid[N][N];\nint pos[TOTAL];\nint val_at[TOTAL];\nint dist[TOTAL], parent[TOTAL], impact[TOTAL];\nvector<int> neighbors[TOTAL];\n\ninline int idx(int x, int y) { return x * (x + 1) / 2 + y; }\n\npair<int,int> coord(int i) {\n    int x = (int)(sqrt(2.0 * i + 0.25) - 0.5);\n    while (idx(x + 1, 0) <= i) x++;\n    return {x, i - idx(x, 0)};\n}\n\nvoid init_neighbors() {\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            int p = idx(x, y);\n            if (x > 0 && y > 0) neighbors[p].push_back(idx(x-1, y-1));\n            if (x > 0 && y < x) neighbors[p].push_back(idx(x-1, y));\n            if (y > 0) neighbors[p].push_back(idx(x, y-1));\n            if (y < x) neighbors[p].push_back(idx(x, y+1));\n            if (x < N-1) neighbors[p].push_back(idx(x+1, y));\n            if (x < N-1) neighbors[p].push_back(idx(x+1, y+1));\n        }\n    }\n}\n\nvoid bfs_optimized(int s, int max_block) {\n    memset(dist, -1, TOTAL * sizeof(int));\n    memset(parent, -1, TOTAL * sizeof(int));\n    memset(impact, 0x3f, TOTAL * sizeof(int));\n    \n    vector<vector<int>> layers(TOTAL);\n    layers[0].push_back(s);\n    dist[s] = 0;\n    impact[s] = 0;\n    \n    for (int d = 0; d < TOTAL && !layers[d].empty(); d++) {\n        // Sort by impact score (lower is better)\n        sort(layers[d].begin(), layers[d].end(), [](int a, int b) {\n            return impact[a] < impact[b];\n        });\n        \n        for (int u : layers[d]) {\n            for (int p : neighbors[u]) {\n                if (val_at[p] == p && p < max_block) continue;\n                \n                // Calculate impact of moving through position p\n                int new_impact = impact[u];\n                int ball_at_p = val_at[p];\n                if (ball_at_p != p && ball_at_p > max_block) {\n                    // Ball will be displaced; add penalty based on distance to target\n                    auto [px, py] = coord(p);\n                    auto [tx, ty] = coord(ball_at_p);\n                    int dist_to_target = max(abs(px - tx), abs(py - ty)) + abs(px - tx - py + ty);\n                    // Prefer displacing balls far from their targets\n                    new_impact += 100 - dist_to_target;\n                }\n                \n                if (dist[p] == -1) {\n                    dist[p] = d + 1;\n                    parent[p] = u;\n                    impact[p] = new_impact;\n                    layers[d + 1].push_back(p);\n                } else if (dist[p] == d + 1 && new_impact < impact[p]) {\n                    parent[p] = u;\n                    impact[p] = new_impact;\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_neighbors();\n    \n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n            int p = idx(x, y);\n            pos[pyramid[x][y]] = p;\n            val_at[p] = pyramid[x][y];\n        }\n    }\n    \n    vector<array<int,4>> moves;\n    \n    for (int v = 0; v < TOTAL && (int)moves.size() < 9800; v++) {\n        if (pos[v] == v) continue;\n        \n        bfs_optimized(pos[v], v);\n        if (dist[v] == -1) continue;\n        \n        static int path[TOTAL];\n        int len = 0;\n        for (int u = v; u != -1; u = parent[u]) path[len++] = u;\n        reverse(path, path + len);\n        \n        for (int i = 0; i+1 < len && (int)moves.size() < 9800; i++) {\n            auto [x1, y1] = coord(path[i]);\n            auto [x2, y2] = coord(path[i+1]);\n            int p1 = idx(x1, y1), p2 = idx(x2, y2);\n            int v1 = val_at[p1], v2 = val_at[p2];\n            pos[v1] = p2; pos[v2] = p1;\n            swap(val_at[p1], val_at[p2]);\n            swap(pyramid[x1][y1], pyramid[x2][y2]);\n            moves.push_back({x1, y1, x2, y2});\n        }\n    }\n    \n    cout << moves.size() << \"\\n\";\n    for (auto& m : moves) {\n        cout << m[0] << \" \" << m[1] << \" \" << m[2] << \" \" << m[3] << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int D, N;\n    cin >> D >> N;\n    \n    int ej = (D - 1) / 2;\n    \n    vector<vector<bool>> is_obs(D, vector<bool>(D, false));\n    for (int i = 0; i < N; i++) {\n        int r, c; cin >> r >> c;\n        is_obs[r][c] = true;\n    }\n    \n    vector<pair<int,int>> cells;\n    vector<vector<int>> cidx(D, vector<int>(D, -1));\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (i == 0 && j == ej) continue;\n            if (is_obs[i][j]) continue;\n            cidx[i][j] = cells.size();\n            cells.push_back({i, j});\n        }\n    }\n    \n    int M = cells.size();\n    int dr[] = {-1, 1, 0, 0};\n    int dc[] = {0, 0, -1, 1};\n    \n    vector<bool> occupied(M, false);\n    vector<int> cont(M, -1);\n    vector<int> cell_of(M, -1);\n    \n    auto bfs = [&]() -> vector<vector<bool>> {\n        vector<vector<bool>> vis(D, vector<bool>(D, false));\n        queue<pair<int,int>> q;\n        q.push({0, ej});\n        vis[0][ej] = true;\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 >= D || nc < 0 || nc >= D) continue;\n                if (vis[nr][nc] || is_obs[nr][nc]) continue;\n                int idx = cidx[nr][nc];\n                if (idx >= 0 && occupied[idx]) continue;\n                vis[nr][nc] = true;\n                q.push({nr, nc});\n            }\n        }\n        return vis;\n    };\n    \n    // Compute who blocks whom\n    vector<vector<int>> blocks(M);\n    for (int i = 0; i < M; i++) {\n        occupied[i] = true;\n        auto vis = bfs();\n        for (int j = 0; j < M; j++)\n            if (i != j && !vis[cells[j].first][cells[j].second])\n                blocks[i].push_back(j);\n        occupied[i] = false;\n    }\n    \n    // Compute iterative blocking score\n    vector<double> score(M, 1.0);\n    for (int iter = 0; iter < 20; iter++) {\n        vector<double> ns(M, 1.0);\n        for (int i = 0; i < M; i++)\n            for (int j : blocks[i])\n                ns[i] += score[j] * 0.5;\n        score = ns;\n    }\n    \n    // BFS distance from entrance\n    vector<int> dist(M, 0);\n    {\n        vector<vector<int>> dg(D, vector<int>(D, -1));\n        queue<pair<int,int>> q; q.push({0, ej}); dg[0][ej] = 0;\n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            for (int d = 0; d < 4; d++) {\n                int nr = r + dr[d], nc = c + dc[d];\n                if (nr >= 0 && nr < D && nc >= 0 && nc < D && dg[nr][nc] < 0 && !is_obs[nr][nc]) {\n                    dg[nr][nc] = dg[r][c] + 1;\n                    q.push({nr, nc});\n                }\n            }\n        }\n        for (int i = 0; i < M; i++) dist[i] = dg[cells[i].first][cells[i].second];\n    }\n    \n    // Priority: higher score = should get smaller number\n    vector<int> order(M); iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        if (abs(score[a] - score[b]) > 1e-9) return score[a] > score[b];\n        if (dist[a] != dist[b]) return dist[a] < dist[b];\n        return cells[a] < cells[b];\n    });\n    vector<int> priority(M);\n    for (int i = 0; i < M; i++) priority[order[i]] = M - 1 - i;\n    \n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        \n        auto vis = bfs();\n        vector<int> choices;\n        for (int i = 0; i < M; i++)\n            if (!occupied[i] && vis[cells[i].first][cells[i].second]) choices.push_back(i);\n        \n        if (choices.empty()) { cerr << \"No reachable cell at step \" << d << endl; return 1; }\n        \n        // Find minimum impact\n        int min_imp = M + 1;\n        for (int c : choices) {\n            occupied[c] = true;\n            auto v = bfs();\n            int imp = 0;\n            for (int j = 0; j < M; j++)\n                if (!occupied[j] && !v[cells[j].first][cells[j].second]) imp++;\n            occupied[c] = false;\n            min_imp = min(min_imp, imp);\n        }\n        \n        // Collect cells with minimum impact\n        vector<int> best;\n        for (int c : choices) {\n            occupied[c] = true;\n            auto v = bfs();\n            int imp = 0;\n            for (int j = 0; j < M; j++)\n                if (!occupied[j] && !v[cells[j].first][cells[j].second]) imp++;\n            occupied[c] = false;\n            if (imp == min_imp) best.push_back(c);\n        }\n        \n        sort(best.begin(), best.end(), [&](int a, int b) { return priority[a] > priority[b]; });\n        \n        int idx = (M == 1) ? 0 : min((int)best.size() - 1, t * ((int)best.size() - 1) / (M - 1));\n        int chosen = best[idx];\n        \n        occupied[chosen] = true;\n        cont[chosen] = t;\n        cell_of[t] = chosen;\n        cout << cells[chosen].first << \" \" << cells[chosen].second << endl;\n    }\n    \n    for (int step = 0; step < M; step++) {\n        auto vis = bfs();\n        int best = -1;\n        for (int i = 0; i < M; i++) {\n            if (!occupied[i]) continue;\n            bool adj = false;\n            for (int d = 0; d < 4; d++) {\n                int nr = cells[i].first + dr[d], nc = cells[i].second + dc[d];\n                if (nr >= 0 && nr < D && nc >= 0 && nc < D && vis[nr][nc]) { adj = true; break; }\n            }\n            if (adj && (best < 0 || cont[i] < cont[best])) best = i;\n        }\n        \n        if (best < 0) { cerr << \"No reachable container at step \" << step << endl; return 1; }\n        \n        occupied[best] = false;\n        cout << cells[best].first << \" \" << cells[best].second << endl;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n    \n    auto start = chrono::steady_clock::now();\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> orig(n, vector<int>(n));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            cin >> orig[i][j];\n    \n    const int dx[] = {0, 0, 1, -1};\n    const int dy[] = {1, -1, 0, 0};\n    auto inside = [](int x, int y, int N) { return x >= 0 && x < N && y >= 0 && y < N; };\n    \n    set<pair<int,int>> origAdjSet;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                int nc = inside(ni, nj, n) ? orig[ni][nj] : 0;\n                if (nc != orig[i][j]) {\n                    int a = orig[i][j], b = nc;\n                    if (a > b) swap(a, b);\n                    origAdjSet.insert({a, b});\n                }\n            }\n        }\n    }\n    \n    mt19937 rng(12345);\n    vector<pair<int,int>> baseOrder;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            baseOrder.push_back({i, j});\n    \n    auto solve = [&](vector<pair<int,int>> order) -> pair<int, vector<vector<int>>> {\n        vector g = orig;\n        map<pair<int,int>, int> adjCnt;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    int nc = inside(ni, nj, n) ? g[ni][nj] : 0;\n                    if (nc != g[i][j]) {\n                        int a = g[i][j], b = nc;\n                        if (a > b) swap(a, b);\n                        adjCnt[{a, b}]++;\n                    }\n                }\n            }\n        }\n        \n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (auto [i, j] : order) {\n                if (g[i][j] == 0) continue;\n                int c = g[i][j];\n                \n                bool conn0 = (i == 0 || i == n-1 || j == 0 || j == n-1);\n                if (!conn0) {\n                    for (int d = 0; d < 4; d++) {\n                        int ni = i + dx[d], nj = j + dy[d];\n                        if (inside(ni, nj, n) && g[ni][nj] == 0) { conn0 = true; break; }\n                    }\n                }\n                if (!conn0) continue;\n                \n                map<pair<int,int>, int> delta;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    bool in = inside(ni, nj, n);\n                    int nc = in ? g[ni][nj] : 0;\n                    if (nc != c) {\n                        int a = c, b = nc;\n                        if (a > b) swap(a, b);\n                        delta[{a, b}]--;\n                        if (in) delta[{a, b}]--;\n                    }\n                    if (nc != 0) {\n                        int a = 0, b = nc;\n                        if (a > b) swap(a, b);\n                        delta[{a, b}] += 2;\n                    }\n                }\n                \n                bool ok = true;\n                for (auto& [p, ch] : delta) {\n                    int newCnt = adjCnt[p] + ch;\n                    if (newCnt > 0 && origAdjSet.count(p) == 0) { ok = false; break; }\n                    if (newCnt == 0 && origAdjSet.count(p) > 0) { ok = false; break; }\n                }\n                if (!ok) continue;\n                \n                vector<pair<int,int>> sameColorNbrs;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    if (inside(ni, nj, n) && g[ni][nj] == c)\n                        sameColorNbrs.push_back({ni, nj});\n                }\n                \n                bool connected = true;\n                if (sameColorNbrs.size() > 1) {\n                    g[i][j] = 0;\n                    queue<int> q;\n                    vector<bool> vis(n * n, false);\n                    q.push(sameColorNbrs[0].first * n + sameColorNbrs[0].second);\n                    vis[sameColorNbrs[0].first * n + sameColorNbrs[0].second] = true;\n                    while (!q.empty()) {\n                        int cur = q.front(); q.pop();\n                        int x = cur / n, y = cur % n;\n                        for (int d = 0; d < 4; d++) {\n                            int nx = x + dx[d], ny = y + dy[d];\n                            if (inside(nx, ny, n) && g[nx][ny] == c && !vis[nx * n + ny]) {\n                                vis[nx * n + ny] = true;\n                                q.push(nx * n + ny);\n                            }\n                        }\n                    }\n                    for (auto& p : sameColorNbrs) {\n                        if (!vis[p.first * n + p.second]) { connected = false; break; }\n                    }\n                    g[i][j] = c;\n                }\n                \n                if (connected) {\n                    g[i][j] = 0;\n                    for (auto& [p, ch] : delta) adjCnt[p] += ch;\n                    changed = true;\n                }\n            }\n        }\n        \n        int score = 0;\n        for (int i = 0; i < n; i++)\n            for (int j = 0; j < n; j++)\n                if (g[i][j] == 0) score++;\n        \n        return {score, g};\n    };\n    \n    int bestScore = -1;\n    vector<vector<int>> bestG;\n    \n    auto check = [&](vector<pair<int,int>> order) {\n        auto [s, g] = solve(order);\n        if (s > bestScore) { bestScore = s; bestG = g; }\n    };\n    \n    check(baseOrder);\n    auto rev = baseOrder; reverse(rev.begin(), rev.end()); check(rev);\n    \n    vector<pair<int,int>> colMajor;\n    for (int j = 0; j < n; j++) for (int i = 0; i < n; i++) colMajor.push_back({i, j});\n    check(colMajor); reverse(colMajor.begin(), colMajor.end()); check(colMajor);\n    \n    // Spiral\n    {\n        vector<pair<int,int>> spiral;\n        int t = 0, b = n-1, l = 0, r = n-1;\n        while (t <= b && l <= r) {\n            for (int j = l; j <= r; j++) spiral.push_back({t, j});\n            t++;\n            for (int i = t; i <= b; i++) spiral.push_back({i, r});\n            r--;\n            if (t <= b) { for (int j = r; j >= l; j--) spiral.push_back({b, j}); b--; }\n            if (l <= r) { for (int i = b; i >= t; i--) spiral.push_back({i, l}); l++; }\n        }\n        check(spiral); reverse(spiral.begin(), spiral.end()); check(spiral);\n    }\n    \n    // Diagonal\n    {\n        vector<pair<int,int>> diag;\n        for (int s = 0; s < 2*n-1; s++)\n            for (int i = 0; i < n; i++) {\n                int j = s - i;\n                if (j >= 0 && j < n) diag.push_back({i, j});\n            }\n        check(diag); reverse(diag.begin(), diag.end()); check(diag);\n    }\n    \n    // Random with time limit\n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < 1.8) {\n        auto randOrder = baseOrder;\n        shuffle(randOrder.begin(), randOrder.end(), rng);\n        check(randOrder);\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << bestG[i][j];\n            if (j < n - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc025":"#include <cstdio>\n#include <vector>\n#include <algorithm>\n#include <cmath>\nusing namespace std;\n\nint N, D, Q;\nint qc = 0;\nchar cmp[101][101];\n\nchar comp(int a, int b) {\n    if (a == b) return '=';\n    if (cmp[a][b]) return cmp[a][b];\n    if (qc >= Q) return '=';\n    qc++;\n    printf(\"1 1 %d %d\\n\", a, b);\n    fflush(stdout);\n    char r; scanf(\" %c\", &r);\n    cmp[a][b] = r;\n    cmp[b][a] = r == '<' ? '>' : r == '>' ? '<' : '=';\n    return r;\n}\n\nvoid msort(vector<int>& a, int l, int r) {\n    if (l >= r) return;\n    int m = (l+r)/2;\n    msort(a, l, m);\n    msort(a, m+1, r);\n    vector<int> t;\n    int i = l, j = m+1;\n    while (i <= m && j <= r) {\n        char res = comp(a[i], a[j]);\n        t.push_back((res == '<' || res == '=') ? a[i++] : a[j++]);\n    }\n    while (i <= m) t.push_back(a[i++]);\n    while (j <= r) t.push_back(a[j++]);\n    for (int k = l; k <= r; k++) a[k] = t[k-l];\n}\n\nchar query_set(const vector<int>& L, const vector<int>& R) {\n    if (L.empty() || R.empty()) return '=';\n    if (qc >= Q) return '=';\n    qc++;\n    printf(\"%zu %zu\", L.size(), R.size());\n    for (int x : L) printf(\" %d\", x);\n    for (int x : R) printf(\" %d\", x);\n    printf(\"\\n\");\n    fflush(stdout);\n    char r; scanf(\" %c\", &r);\n    return r;\n}\n\nint main() {\n    scanf(\"%d%d%d\", &N, &D, &Q);\n    \n    vector<int> ord(N);\n    for (int i = 0; i < N; i++) ord[i] = i;\n    msort(ord, 0, N-1);\n    \n    // Exponential distribution inverse CDF\n    vector<double> w(N);\n    for (int i = 0; i < N; i++) {\n        double p = (double)(i + 1) / (N + 1);\n        w[ord[i]] = -log(1.0 - p + 1e-12);\n    }\n    \n    vector<double> sw(D, 0);\n    vector<int> ans(N);\n    vector<vector<int>> S(D);\n    \n    for (int i = N-1; i >= 0; i--) {\n        int it = ord[i], mi = 0;\n        for (int d = 1; d < D; d++) if (sw[d] < sw[mi]) mi = d;\n        ans[it] = mi;\n        S[mi].push_back(it);\n        sw[mi] += w[it];\n    }\n    \n    for (int d = 0; d < D; d++)\n        sort(S[d].begin(), S[d].end(), [&](int a, int b) { return w[a] > w[b]; });\n    \n    // Local search\n    while (qc + 1 <= Q) {\n        int hv = 0, lt = 0;\n        for (int d = 1; d < D; d++) {\n            if (sw[d] > sw[hv]) hv = d;\n            if (sw[d] < sw[lt]) lt = d;\n        }\n        if (hv == lt) break;\n        if (S[hv].empty()) break;\n        \n        char r = query_set(S[hv], S[lt]);\n        if (r == '=') break;\n        if (r == '<') swap(hv, lt);\n        \n        if (S[hv].empty()) break;\n        if (S[hv].size() == 1) break;\n        \n        // Move smallest item from heavy to light\n        int mv = S[hv].back();\n        S[hv].pop_back();\n        S[lt].push_back(mv);\n        sort(S[lt].begin(), S[lt].end(), [&](int a, int b) { return w[a] > w[b]; });\n        sw[hv] -= w[mv];\n        sw[lt] += w[mv];\n        ans[mv] = lt;\n    }\n    \n    while (qc < Q) {\n        printf(\"1 1 0 1\\n\");\n        fflush(stdout);\n        char d; scanf(\" %c\", &d);\n        qc++;\n    }\n    \n    for (int i = 0; i < N; i++) printf(\"%d%c\", ans[i], i < N-1 ? ' ' : '\\n');\n    fflush(stdout);\n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> st(m);\n    for (int i = 0; i < m; i++) {\n        st[i].resize(n/m);\n        for (int j = 0; j < n/m; j++) {\n            cin >> st[i][j];\n        }\n    }\n    \n    vector<pair<int, int>> ops;\n    \n    for (int v = 1; v <= n; v++) {\n        int si = -1, pos = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)st[i].size(); j++) {\n                if (st[i][j] == v) {\n                    si = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (si != -1) break;\n        }\n        \n        if (si == -1) continue;\n        \n        if (pos < (int)st[si].size() - 1) {\n            int maxMoved = INT_MIN, minMoved = INT_MAX;\n            int movedSize = st[si].size() - pos - 1;\n            for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                maxMoved = max(maxMoved, st[si][j]);\n                minMoved = min(minMoved, st[si][j]);\n            }\n            \n            int dest = -1;\n            int bestCost = INT_MAX;\n            int bestTiebreaker = INT_MIN;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == si) continue;\n                \n                int cost;\n                int tiebreaker;\n                \n                if (st[i].empty()) {\n                    cost = 0;\n                    tiebreaker = 100000;\n                } else {\n                    int top = st[i].back();\n                    if (top > maxMoved) {\n                        cost = 0;\n                        tiebreaker = top * 1000 + (200 - st[i].size());\n                    } else if (top < minMoved) {\n                        cost = movedSize;\n                        tiebreaker = -st[i].size();\n                    } else {\n                        int blockingCount = 0;\n                        for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                            if (st[si][j] > top) blockingCount++;\n                        }\n                        cost = blockingCount;\n                        tiebreaker = top - st[i].size();\n                    }\n                }\n                \n                if (cost < bestCost || (cost == bestCost && tiebreaker > bestTiebreaker)) {\n                    bestCost = cost;\n                    bestTiebreaker = tiebreaker;\n                    dest = i;\n                }\n            }\n            \n            int boxAbove = st[si][pos + 1];\n            ops.push_back({boxAbove, dest + 1});\n            \n            for (int j = pos + 1; j < (int)st[si].size(); j++) {\n                st[dest].push_back(st[si][j]);\n            }\n            st[si].resize(pos + 1);\n        }\n        \n        ops.push_back({v, 0});\n        st[si].pop_back();\n    }\n    \n    for (auto& [a, b] : ops) {\n        cout << a << \" \" << b << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#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<string> h(N-1), v(N);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    vector<vector<int>> d(N, vector<int>(N));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};\n    char dirChar[] = {'R', 'D', 'L', 'U'};\n    \n    auto canMove = [&](int i, int j, int k) -> bool {\n        int ni = i + di[k], nj = j + dj[k];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n        if (di[k] != 0) return h[min(i, ni)][j] == '0';\n        return v[i][min(j, nj)] == '0';\n    };\n    \n    vector<vector<int>> dist0(N, vector<int>(N, -1));\n    vector<vector<int>> prevDir(N, vector<int>(N, -1));\n    queue<pair<int,int>> qu;\n    qu.push({0, 0});\n    dist0[0][0] = 0;\n    while (!qu.empty()) {\n        auto [i, j] = qu.front(); qu.pop();\n        for (int k = 0; k < 4; k++) {\n            if (!canMove(i, j, k)) continue;\n            int ni = i + di[k], nj = j + dj[k];\n            if (dist0[ni][nj] < 0) {\n                dist0[ni][nj] = dist0[i][j] + 1;\n                prevDir[ni][nj] = k;\n                qu.push({ni, nj});\n            }\n        }\n    }\n    \n    // Compute path sums (sum of d on path, weighted by distance)\n    vector<vector<double>> pathValue(N, vector<double>(N, 0));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (i == 0 && j == 0) continue;\n            int ci = i, cj = j;\n            int dist = 0;\n            while (ci != 0 || cj != 0) {\n                int k = prevDir[ci][cj];\n                ci -= di[k]; cj -= dj[k];\n                dist++;\n                if (ci != 0 || cj != 0) {\n                    pathValue[i][j] += (double)d[ci][cj] / dist;\n                }\n            }\n        }\n    }\n    \n    vector visited(N, vector<bool>(N, false));\n    string tour;\n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        vector<tuple<double,int,int,int>> nb;\n        for (int k = 0; k < 4; k++) {\n            if (!canMove(i, j, k)) continue;\n            int ni = i + di[k], nj = j + dj[k];\n            if (!visited[ni][nj]) {\n                // Combine d and path value\n                double score = (double)d[ni][nj] * 10.0 + pathValue[ni][nj];\n                nb.emplace_back(-score, dist0[ni][nj], ni, nj);\n            }\n        }\n        sort(nb.begin(), nb.end());\n        for (auto& [_, __, ni, nj] : nb) {\n            for (int k = 0; k < 4; k++) {\n                if (i + di[k] == ni && j + dj[k] == nj) {\n                    tour += dirChar[k];\n                    dfs(ni, nj);\n                    tour += dirChar[(k+2)%4];\n                    break;\n                }\n            }\n        }\n    };\n    dfs(0, 0);\n    \n    vector visitCount(N, vector<int>(N, 1));\n    long long L = tour.size();\n    int budget = 100000 - L;\n    \n    double sumWI = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            sumWI += (double)d[i][j] / visitCount[i][j];\n    \n    auto addRoundTrip = [&](int ti, int tj) {\n        string fwd;\n        int ci = ti, cj = tj;\n        while (ci != 0 || cj != 0) {\n            int k = prevDir[ci][cj];\n            fwd += dirChar[k];\n            ci -= di[k]; cj -= dj[k];\n        }\n        reverse(fwd.begin(), fwd.end());\n        string back = fwd;\n        reverse(back.begin(), back.end());\n        for (char& c : back) {\n            if (c == 'R') c = 'L'; else if (c == 'L') c = 'R';\n            else if (c == 'U') c = 'D'; else c = 'U';\n        }\n        tour += fwd + back;\n    };\n    \n    while (budget > 10) {\n        double bestDelta = 1e18;\n        int bestI = -1, bestJ = -1;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (i == 0 && j == 0) continue;\n                int cost = 2 * dist0[i][j];\n                if (cost <= 0 || cost > budget) continue;\n                \n                double delta = 0;\n                int vti = visitCount[i][j];\n                int v00 = visitCount[0][0];\n                \n                delta += (double)d[i][j] * ((long long)vti * cost - L) / (2.0 * vti * (vti + 1));\n                delta += (double)d[0][0] * ((long long)v00 * cost - L) / (2.0 * v00 * (v00 + 1));\n                \n                double sumInterm = 0;\n                int ci = i, cj = j;\n                while (ci != 0 || cj != 0) {\n                    int k = prevDir[ci][cj];\n                    ci -= di[k]; cj -= dj[k];\n                    if (ci != 0 || cj != 0) {\n                        int vc = visitCount[ci][cj];\n                        delta += (double)d[ci][cj] * (2LL * vc * cost - L) / (2.0 * vc * (vc + 2));\n                        sumInterm += (double)d[ci][cj] / vc;\n                    }\n                }\n                \n                double sumOther = sumWI - (double)d[i][j] / vti - (double)d[0][0] / v00 - sumInterm;\n                delta += sumOther * cost / 2.0;\n                \n                if (delta < bestDelta) {\n                    bestDelta = delta;\n                    bestI = i; bestJ = j;\n                }\n            }\n        }\n        \n        if (bestI < 0 || bestDelta >= 0) break;\n        \n        int cost = 2 * dist0[bestI][bestJ];\n        \n        sumWI -= (double)d[bestI][bestJ] / visitCount[bestI][bestJ];\n        visitCount[bestI][bestJ]++;\n        sumWI += (double)d[bestI][bestJ] / visitCount[bestI][bestJ];\n        \n        sumWI -= (double)d[0][0] / visitCount[0][0];\n        visitCount[0][0]++;\n        sumWI += (double)d[0][0] / visitCount[0][0];\n        \n        int ci = bestI, cj = bestJ;\n        while (ci != 0 || cj != 0) {\n            int k = prevDir[ci][cj];\n            ci -= di[k]; cj -= dj[k];\n            if (ci != 0 || cj != 0) {\n                sumWI -= (double)d[ci][cj] / visitCount[ci][cj];\n                visitCount[ci][cj] += 2;\n                sumWI += (double)d[ci][cj] / visitCount[ci][cj];\n            }\n        }\n        \n        addRoundTrip(bestI, bestJ);\n        L += cost;\n        budget -= cost;\n    }\n    \n    cout << tour << '\\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(nullptr);\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<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 * N + j);\n    \n    auto getCoord = [N](int idx) { return make_pair(idx / N, idx % N); };\n    \n    auto computeOverlap = [](const string& a, const string& b) {\n        for (int len = (int)min(a.size(), b.size()); len >= 0; len--) {\n            bool match = true;\n            for (int i = 0; i < len && match; i++)\n                if (a[a.size() - len + i] != b[i]) match = false;\n            if (match) return len;\n        }\n        return 0;\n    };\n    \n    vector<vector<int>> overlap(M, vector<int>(M, 0));\n    for (int i = 0; i < M; i++)\n        for (int j = 0; j < M; j++)\n            if (i != j) overlap[i][j] = computeOverlap(words[i], words[j]);\n    \n    auto buildSuperstring = [&](const vector<int>& order) {\n        string result = words[order[0]];\n        for (int k = 1; k < M; k++)\n            result += words[order[k]].substr(overlap[order[k-1]][order[k]]);\n        return result;\n    };\n    \n    string bestSuperstring;\n    int bestLen = INT_MAX;\n    mt19937 rng(42);\n    \n    for (int trial = 0; trial < 200; trial++) {\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        \n        int start = rng() % M;\n        swap(order[0], order[start]);\n        for (int i = 1; i < M; i++) {\n            int bestIdx = i;\n            int bestOv = -1;\n            for (int j = i; j < M; j++) {\n                if (overlap[order[i-1]][order[j]] > bestOv) {\n                    bestOv = overlap[order[i-1]][order[j]];\n                    bestIdx = j;\n                }\n            }\n            swap(order[i], order[bestIdx]);\n        }\n        \n        // Fast adjacent-swap local search with O(1) delta\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 0; i < M - 1; i++) {\n                int oldSum = 0, newSum = 0;\n                if (i > 0) {\n                    oldSum += overlap[order[i-1]][order[i]];\n                    newSum += overlap[order[i-1]][order[i+1]];\n                }\n                oldSum += overlap[order[i]][order[i+1]];\n                newSum += overlap[order[i+1]][order[i]];\n                if (i + 2 < M) {\n                    oldSum += overlap[order[i+1]][order[i+2]];\n                    newSum += overlap[order[i]][order[i+2]];\n                }\n                if (newSum > oldSum) {\n                    swap(order[i], order[i+1]);\n                    improved = true;\n                }\n            }\n        }\n        \n        string superstring = buildSuperstring(order);\n        if ((int)superstring.size() < bestLen) {\n            bestLen = superstring.size();\n            bestSuperstring = superstring;\n        }\n    }\n    \n    int L = bestSuperstring.size();\n    vector<pair<int, int>> dp;\n    for (int cell : charPos[bestSuperstring[0] - 'A']) {\n        auto [ci, cj] = getCoord(cell);\n        dp.emplace_back(cell, abs(ci - si) + abs(cj - sj) + 1);\n    }\n    \n    vector<unordered_map<int, int>> parent(L);\n    for (int idx = 1; idx < L; idx++) {\n        vector<pair<int, int>> newDp;\n        for (int cell : charPos[bestSuperstring[idx] - 'A']) {\n            auto [ci, cj] = getCoord(cell);\n            int minCost = INT_MAX, bestPrev = -1;\n            for (auto& [prevCell, cost] : dp) {\n                auto [pi, pj] = getCoord(prevCell);\n                int newCost = cost + abs(ci - pi) + abs(cj - pj) + 1;\n                if (newCost < minCost) { minCost = newCost; bestPrev = prevCell; }\n            }\n            if (bestPrev != -1) {\n                newDp.emplace_back(cell, minCost);\n                parent[idx][cell] = bestPrev;\n            }\n        }\n        if (newDp.size() > 100) {\n            sort(newDp.begin(), newDp.end(), [](auto& a, auto& b) { return a.second < b.second; });\n            newDp.resize(100);\n        }\n        dp = move(newDp);\n    }\n    \n    int endCell = min_element(dp.begin(), dp.end(), [](auto& a, auto& b) { return a.second < b.second; })->first;\n    vector<int> path(L);\n    path[L - 1] = endCell;\n    for (int idx = L - 2; idx >= 0; idx--)\n        path[idx] = parent[idx + 1][path[idx + 1]];\n    \n    for (int cell : path) {\n        auto [i, j] = getCoord(cell);\n        cout << i << \" \" << j << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<set<pair<int,int>>> shapes;\nvector<vector<int>> obs;\nint Q = 0;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> eps;\n    shapes.resize(M);\n    obs.assign(N, vector<int>(N, -1));\n    \n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        for (int i = 0; i < d; i++) {\n            int r, c; cin >> r >> c;\n            shapes[k].insert({r, c});\n        }\n    }\n    \n    auto drill = [&](int i, int j) -> int {\n        if (obs[i][j] != -1) return obs[i][j];\n        if (Q >= 2*N*N - 1) return -1;\n        cout << \"q 1 \" << i << \" \" << j << endl;\n        int r; cin >> r;\n        obs[i][j] = r;\n        Q++;\n        return r;\n    };\n    \n    auto getBB = [](const set<pair<int,int>>& shape) -> pair<int,int> {\n        int maxI = 0, maxJ = 0;\n        for (auto& p : shape) { maxI = max(maxI, p.first); maxJ = max(maxJ, p.second); }\n        return {maxI, maxJ};\n    };\n    \n    auto getValid = [&](int k) -> vector<pair<int,int>> {\n        auto [maxI, maxJ] = getBB(shapes[k]);\n        vector<pair<int,int>> valid;\n        for (int di = 0; di <= N-1-maxI; di++) {\n            for (int dj = 0; dj <= N-1-maxJ; dj++) {\n                bool ok = true;\n                for (auto& p : shapes[k])\n                    if (obs[p.first + di][p.second + dj] == 0) { ok = false; break; }\n                if (ok) valid.push_back({di, dj});\n            }\n        }\n        return valid;\n    };\n    \n    while (Q < N * N) {\n        vector<vector<pair<int,int>>> valid(M);\n        for (int k = 0; k < M; k++) valid[k] = getValid(k);\n        \n        double bestScore = -1;\n        int bestI = -1, bestJ = -1;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (obs[i][j] != -1) continue;\n                \n                bool guaranteedOil = false;\n                int coverCount = 0, notCoverCount = 0;\n                int numShapesCovering = 0;\n                \n                for (int k = 0; k < M; k++) {\n                    if (valid[k].empty()) continue;\n                    int cover = 0;\n                    for (auto& [di, dj] : valid[k])\n                        if (shapes[k].count({i-di, j-dj})) cover++;\n                    \n                    if (cover == (int)valid[k].size() && cover > 0) { guaranteedOil = true; break; }\n                    if (cover > 0) numShapesCovering++;\n                    coverCount += cover;\n                    notCoverCount += valid[k].size() - cover;\n                }\n                \n                if (guaranteedOil) continue;\n                if (coverCount == 0) continue;\n                \n                double score = (double)min(coverCount, notCoverCount) + 0.01 * numShapesCovering;\n                if (score > bestScore) { bestScore = score; bestI = i; bestJ = j; }\n            }\n        }\n        \n        if (bestScore < 0) break;\n        if (drill(bestI, bestJ) == -1) break;\n    }\n    \n    while (true) {\n        vector<vector<pair<int,int>>> valid(M);\n        for (int k = 0; k < M; k++) valid[k] = getValid(k);\n        \n        set<pair<int,int>> oil;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (obs[i][j] > 0) oil.insert({i, j});\n                else if (obs[i][j] == -1) {\n                    for (int k = 0; k < M; k++) {\n                        if (valid[k].empty()) continue;\n                        bool allCover = true;\n                        for (auto& [di, dj] : valid[k])\n                            if (!shapes[k].count({i-di, j-dj})) { allCover = false; break; }\n                        if (allCover) { oil.insert({i, j}); break; }\n                    }\n                }\n            }\n        }\n        \n        vector<pair<int,int>> ans(oil.begin(), oil.end());\n        cout << \"a \" << ans.size();\n        for (auto& p : ans) cout << \" \" << p.first << \" \" << p.second;\n        cout << endl;\n        \n        int r; cin >> r;\n        if (r == 1) break;\n        if (Q >= 2*N*N - 1) break;\n        \n        bool found = false;\n        for (int i = 0; i < N && !found; i++)\n            for (int j = 0; j < N && !found; j++)\n                if (obs[i][j] == -1) { drill(i, j); found = true; }\n        if (!found) break;\n    }\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    // Pre-compute optimal partition positions for each day\n    vector<vector<int>> optCum(D, vector<int>(N + 1));\n    for (int d = 0; d < D; d++) {\n        vector<int> h(N);\n        for (int k = 0; k < N; k++) {\n            h[k] = max(1, (a[d][k] + W - 1) / W);\n        }\n        \n        int totalH = accumulate(h.begin(), h.end(), 0);\n        \n        if (totalH > W) {\n            int reduce = totalH - W;\n            priority_queue<pair<long long, int>> pq;\n            for (int k = 0; k < N; k++) {\n                long long waste = max(0LL, (long long)h[k] * W - a[d][k]);\n                pq.push({waste, k});\n            }\n            while (reduce > 0) {\n                auto [waste, k] = pq.top(); pq.pop();\n                if (h[k] > 1) {\n                    h[k]--;\n                    reduce--;\n                    long long newWaste = max(0LL, (long long)h[k] * W - a[d][k]);\n                    pq.push({newWaste, k});\n                }\n            }\n        } else if (totalH < W) {\n            int rem = W - totalH;\n            priority_queue<pair<long long, int>> pq;\n            for (int k = 0; k < N; k++) {\n                long long def = max(0LL, (long long)a[d][k] - (long long)h[k] * W);\n                pq.push({def, k});\n            }\n            while (rem > 0 && !pq.empty() && pq.top().first > 0) {\n                auto [def, k] = pq.top(); pq.pop();\n                h[k]++;\n                rem--;\n                long long newDef = max(0LL, (long long)a[d][k] - (long long)h[k] * W);\n                pq.push({newDef, k});\n            }\n            if (rem > 0) h[N / 2] += rem;\n        }\n        \n        optCum[d][0] = 0;\n        for (int k = 0; k < N; k++) optCum[d][k + 1] = optCum[d][k] + h[k];\n    }\n    \n    // Use first day as anchor\n    vector<int> targetCum = optCum[0];\n    \n    vector<vector<array<int, 4>>> rect(D, vector<array<int, 4>>(N));\n    vector<int> prevCum(N + 1, 0);\n    \n    for (int d = 0; d < D; d++) {\n        bool reused = false;\n        if (d > 0) {\n            bool ok = true;\n            for (int k = 0; k < N; k++) {\n                int hk = prevCum[k + 1] - prevCum[k];\n                if ((long long)hk * W < a[d][k]) { ok = false; break; }\n            }\n            if (ok) reused = true;\n        }\n        \n        vector<int> h(N);\n        if (reused) {\n            for (int k = 0; k < N; k++) h[k] = prevCum[k + 1] - prevCum[k];\n        } else {\n            for (int k = 0; k < N; k++) h[k] = max(1, (a[d][k] + W - 1) / W);\n            \n            int totalH = accumulate(h.begin(), h.end(), 0);\n            \n            if (totalH > W) {\n                int reduce = totalH - W;\n                priority_queue<pair<long long, int>> pq;\n                for (int k = 0; k < N; k++) {\n                    long long waste = max(0LL, (long long)h[k] * W - a[d][k]);\n                    pq.push({waste, k});\n                }\n                while (reduce > 0) {\n                    auto [waste, k] = pq.top(); pq.pop();\n                    if (h[k] > 1) {\n                        h[k]--;\n                        reduce--;\n                        long long newWaste = max(0LL, (long long)h[k] * W - a[d][k]);\n                        pq.push({newWaste, k});\n                    }\n                }\n            } else if (totalH < W) {\n                int rem = W - totalH;\n                \n                priority_queue<pair<long long, int>> pq;\n                for (int k = 0; k < N; k++) {\n                    long long def = max(0LL, (long long)a[d][k] - (long long)h[k] * W);\n                    pq.push({def, k});\n                }\n                \n                while (rem > 0 && !pq.empty() && pq.top().first > 0) {\n                    auto [def, k] = pq.top(); pq.pop();\n                    h[k]++;\n                    rem--;\n                    long long newDef = max(0LL, (long long)a[d][k] - (long long)h[k] * W);\n                    pq.push({newDef, k});\n                }\n                \n                if (rem > 0) {\n                    vector<int> cum(N + 1);\n                    for (int k = 0; k < N; k++) cum[k + 1] = cum[k] + h[k];\n                    \n                    while (rem > 0) {\n                        int bestK = -1;\n                        long long bestScore = LLONG_MIN;\n                        \n                        for (int k = 0; k < N; k++) {\n                            long long score = 0;\n                            // Match to target positions\n                            for (int j = 1; j < N; j++) {\n                                int curDiff = abs(cum[j] - targetCum[j]);\n                                int newDiff = abs(cum[j] + (j > k ? 1 : 0) - targetCum[j]);\n                                score += (curDiff - newDiff);\n                            }\n                            // Match to previous day\n                            if (d > 0) {\n                                for (int j = 1; j < N; j++) {\n                                    int curDiff = abs(cum[j] - prevCum[j]);\n                                    int newDiff = abs(cum[j] + (j > k ? 1 : 0) - prevCum[j]);\n                                    score += (curDiff - newDiff) * 5;\n                                }\n                            }\n                            // Look ahead to next day\n                            if (d + 1 < D) {\n                                for (int j = 1; j < N; j++) {\n                                    int curDiff = abs(cum[j] - optCum[d + 1][j]);\n                                    int newDiff = abs(cum[j] + (j > k ? 1 : 0) - optCum[d + 1][j]);\n                                    score += (curDiff - newDiff) * 2;\n                                }\n                            }\n                            if (score > bestScore) {\n                                bestScore = score;\n                                bestK = k;\n                            }\n                        }\n                        \n                        if (bestK >= 0) {\n                            h[bestK]++;\n                            for (int j = bestK + 1; j <= N; j++) cum[j]++;\n                        } else {\n                            h[N / 2]++;\n                            for (int j = N / 2 + 1; j <= N; j++) cum[j]++;\n                        }\n                        rem--;\n                    }\n                }\n            }\n        }\n        \n        int y = 0;\n        for (int k = 0; k < N; k++) {\n            rect[d][k] = {y, 0, y + h[k], W};\n            y += h[k];\n        }\n        \n        prevCum[0] = 0;\n        for (int k = 0; k < N; k++) prevCum[k + 1] = prevCum[k] + h[k];\n    }\n    \n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << rect[d][k][0] << \" \" << rect[d][k][1] << \" \"\n                 << rect[d][k][2] << \" \" << rect[d][k][3] << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <random>\n#include <algorithm>\n#include <chrono>\n#include <climits>\n\nusing namespace std;\n\nconst long long MOD = 998244353;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nlong long board[N][N];\nlong long stamps[M][3][3];\nlong long cur[N][N];\ndouble weight[N][N];\nlong long bestScore = 0;\nvector<tuple<int, int, int>> bestOps;\n\nvoid initWeights() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            int cnt = 0;\n            for (int p = max(0, i - 2); p <= min(N - 3, i); p++)\n                for (int q = max(0, j - 2); q <= min(N - 3, j); q++)\n                    cnt++;\n            weight[i][j] = 9.0 / cnt;\n        }\n}\n\ninline long long calcGain(int s, int p, int q) {\n    long long g = 0;\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 3; j++) {\n            long long oldR = cur[p + i][q + j] % MOD;\n            long long newR = (cur[p + i][q + j] + stamps[s][i][j]) % MOD;\n            g += newR - oldR;\n        }\n    return g;\n}\n\ninline double calcWeightedGain(int s, int p, int q) {\n    double g = 0;\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 3; j++) {\n            long long oldR = cur[p + i][q + j] % MOD;\n            long long newR = (cur[p + i][q + j] + stamps[s][i][j]) % MOD;\n            g += (newR - oldR) * weight[p + i][q + j];\n        }\n    return g;\n}\n\ninline void apply(int s, int p, int q) {\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 3; j++)\n            cur[p + i][q + j] += stamps[s][i][j];\n}\n\ninline void unapply(int s, int p, int q) {\n    for (int i = 0; i < 3; i++)\n        for (int j = 0; j < 3; j++)\n            cur[p + i][q + j] -= stamps[s][i][j];\n}\n\ninline long long getScore() {\n    long long s = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            s += cur[i][j] % MOD;\n    return s;\n}\n\nvoid greedy(mt19937& rng, int topK, bool useWeight) {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cur[i][j] = board[i][j];\n    \n    vector<tuple<int, int, int>> ops;\n    \n    while ((int)ops.size() < K) {\n        vector<tuple<double, long long, int, int, int>> cands;\n        for (int s = 0; s < M; s++)\n            for (int p = 0; p <= N - 3; p++)\n                for (int q = 0; q <= N - 3; q++) {\n                    long long g = calcGain(s, p, q);\n                    if (g > 0) {\n                        double wg = useWeight ? calcWeightedGain(s, p, q) : (double)g;\n                        cands.emplace_back(wg, g, s, p, q);\n                    }\n                }\n        if (cands.empty()) break;\n        \n        partial_sort(cands.begin(), cands.begin() + min(topK, (int)cands.size()), \n                     cands.end(), greater<>());\n        int idx = rng() % min(topK, (int)cands.size());\n        auto [wg, g, s, p, q] = cands[idx];\n        ops.emplace_back(s, p, q);\n        apply(s, p, q);\n    }\n    \n    long long score = getScore();\n    if (score > bestScore) {\n        bestScore = score;\n        bestOps = ops;\n    }\n}\n\nvoid fillRemaining() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cur[i][j] = board[i][j];\n    for (auto [s, p, q] : bestOps) apply(s, p, q);\n    \n    while ((int)bestOps.size() < K) {\n        long long bestGain = 0;\n        int bestS = -1, bestP = -1, bestQ = -1;\n        for (int s = 0; s < M; s++)\n            for (int p = 0; p <= N - 3; p++)\n                for (int q = 0; q <= N - 3; q++) {\n                    long long g = calcGain(s, p, q);\n                    if (g > bestGain) {\n                        bestGain = g; bestS = s; bestP = p; bestQ = q;\n                    }\n                }\n        if (bestGain <= 0) break;\n        bestOps.emplace_back(bestS, bestP, bestQ);\n        apply(bestS, bestP, bestQ);\n    }\n    bestScore = getScore();\n}\n\nvoid hillClimb(mt19937& rng, int iterations) {\n    if (bestOps.empty()) return;\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cur[i][j] = board[i][j];\n    for (auto [s, p, q] : bestOps) apply(s, p, q);\n    \n    for (int iter = 0; iter < iterations; iter++) {\n        int op = rng() % 10;\n        \n        if (op < 4 && (int)bestOps.size() < K) {\n            // Add random operation\n            int s = rng() % M, p = rng() % 7, q = rng() % 7;\n            long long g = calcGain(s, p, q);\n            if (g > 0) {\n                bestOps.emplace_back(s, p, q);\n                apply(s, p, q);\n                bestScore += g;\n            }\n        } else if (op < 8 && !bestOps.empty()) {\n            // Replace\n            int idx = rng() % bestOps.size();\n            auto [oldS, oldP, oldQ] = bestOps[idx];\n            unapply(oldS, oldP, oldQ);\n            \n            long long bestGain = LLONG_MIN;\n            int bestS = 0, bestP = 0, bestQ = 0;\n            for (int s = 0; s < M; s++)\n                for (int pp = 0; pp <= N - 3; pp++)\n                    for (int qq = 0; qq <= N - 3; qq++) {\n                        long long g = calcGain(s, pp, qq);\n                        if (g > bestGain) {\n                            bestGain = g; bestS = s; bestP = pp; bestQ = qq;\n                        }\n                    }\n            \n            if (bestGain > 0) {\n                bestOps[idx] = {bestS, bestP, bestQ};\n                apply(bestS, bestP, bestQ);\n                bestScore = getScore();\n            } else {\n                apply(oldS, oldP, oldQ);\n            }\n        } else if (!bestOps.empty()) {\n            // Remove\n            int idx = rng() % bestOps.size();\n            auto [s, p, q] = bestOps[idx];\n            unapply(s, p, q);\n            long long newScore = getScore();\n            if (newScore >= bestScore) {\n                bestOps.erase(bestOps.begin() + idx);\n                bestScore = newScore;\n            } else {\n                apply(s, p, q);\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    initWeights();\n    \n    int n, m, k;\n    cin >> n >> m >> k;\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cin >> board[i][j];\n    \n    for (int s = 0; s < M; s++)\n        for (int i = 0; i < 3; i++)\n            for (int j = 0; j < 3; j++)\n                cin >> stamps[s][i][j];\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cur[i][j] = board[i][j];\n    bestScore = getScore();\n    \n    mt19937 rng(42);\n    auto start = chrono::steady_clock::now();\n    int iter = 0;\n    \n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() < 1850) {\n        int topK = 1 + (iter % 5);\n        bool useWeight = (iter % 3 == 0);\n        greedy(rng, topK, useWeight);\n        \n        if (iter % 50 == 0) {\n            fillRemaining();\n            hillClimb(rng, 500);\n        }\n        iter++;\n    }\n    \n    fillRemaining();\n    hillClimb(rng, 2000);\n    \n    cout << bestOps.size() << \"\\n\";\n    for (auto [s, p, q] : bestOps)\n        cout << s << \" \" << p << \" \" << q << \"\\n\";\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N], G[N][N], CR[N], CC[N], CH[N], RI[N], DN[N];\n\nbool hasCrane(int r, int c, int ex = -1) {\n    for (int i = 0; i < N; i++) if (i != ex && CR[i] == r && CC[i] == c) return true;\n    return false;\n}\n\nint main() {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> A[i][j];\n    memset(G, -1, sizeof(G));\n    for (int i = 0; i < N; i++) { CR[i] = i; CC[i] = 0; CH[i] = -1; RI[i] = 0; DN[i] = i * N; }\n    vector<string> O(N, \"\");\n    \n    // Bomb all small cranes at turn 0\n    for (int i = 1; i < N; i++) { O[i] = \"B\"; CR[i] = -1; }\n    \n    for (int T = 0; T < 10000; T++) {\n        string act = \".\";\n        int NR = CR[0], NC = CC[0];\n        \n        // Receive containers at column 0\n        for (int i = 0; i < N; i++) {\n            if (RI[i] < N && G[i][0] < 0) {\n                bool blocked = (CR[0] == i && CC[0] == 0 && CH[0] >= 0);\n                if (!blocked) G[i][0] = A[i][RI[i]++];\n            }\n        }\n        \n        // Large crane logic\n        if (CH[0] >= 0) {\n            int tr = CH[0] / N;  // Target row for this container\n            if (CR[0] != tr) {\n                // Need to change row - use column 0 as highway\n                if (CC[0] > 0) { act = \"L\"; NC--; }\n                else {\n                    int dr = (CR[0] < tr) ? 1 : -1;\n                    if (CR[0]+dr >= 0 && CR[0]+dr < N && !hasCrane(CR[0]+dr, 0, 0)) { act = (dr > 0) ? \"D\" : \"U\"; NR += dr; }\n                }\n            } else {\n                // In target row - move right to dispatch\n                if (CC[0] < N-1) { act = \"R\"; NC++; }\n                else { act = \"Q\"; }\n            }\n        } else {\n            // Find container to pick up (prioritize column 0 arrivals)\n            int sr = -1, sc = -1;\n            for (int c = 0; c < N-1; c++) for (int r = 0; r < N; r++)\n                if (G[r][c] >= 0) { sr = r; sc = c; goto found; }\n            found:;\n            if (sr >= 0) {\n                if (CR[0] != sr) {\n                    if (CC[0] > 0) { act = \"L\"; NC--; }\n                    else {\n                        int dr = (CR[0] < sr) ? 1 : -1;\n                        if (CR[0]+dr >= 0 && CR[0]+dr < N && !hasCrane(CR[0]+dr, 0, 0)) { act = (dr > 0) ? \"D\" : \"U\"; NR += dr; }\n                    }\n                } else {\n                    if (CC[0] < sc) { act = \"R\"; NC++; }\n                    else if (CC[0] > sc) { act = \"L\"; NC--; }\n                    else { act = \"P\"; }\n                }\n            }\n        }\n        \n        // Apply action\n        if (act == \"P\" && CH[0] < 0 && G[CR[0]][CC[0]] >= 0) { CH[0] = G[CR[0]][CC[0]]; G[CR[0]][CC[0]] = -1; }\n        else if (act == \"Q\" && CH[0] >= 0 && G[CR[0]][CC[0]] < 0) { G[CR[0]][CC[0]] = CH[0]; CH[0] = -1; }\n        CR[0] = NR; CC[0] = NC;\n        \n        // Dispatch containers at column N-1\n        for (int i = 0; i < N; i++) if (G[i][N-1] >= 0) {\n            if (G[i][N-1] >= i*N && G[i][N-1] < (i+1)*N && G[i][N-1] == DN[i]) DN[i]++;\n            G[i][N-1] = -1;\n        }\n        \n        O[0] += act;\n        \n        // Check if done\n        bool done = true;\n        for (int i = 0; i < N; i++) if (RI[i] < N) done = false;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (G[i][j] >= 0) done = false;\n        if (CH[0] >= 0) done = false;\n        if (done) break;\n    }\n    \n    for (int i = 0; i < N; i++) cout << O[i] << \"\\n\";\n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint h[20][20];\n\nint dist(int i1, int j1, int i2, int j2) {\n    return abs(i1 - i2) + abs(j1 - j2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cin >> h[i][j];\n    \n    vector<string> ops;\n    long long truck_load = 0;\n    int cur_i = 0, cur_j = 0;\n    \n    auto move_to = [&](int ni, int nj) {\n        while (cur_i < ni) { ops.push_back(\"D\"); cur_i++; }\n        while (cur_i > ni) { ops.push_back(\"U\"); cur_i--; }\n        while (cur_j < nj) { ops.push_back(\"R\"); cur_j++; }\n        while (cur_j > nj) { ops.push_back(\"L\"); cur_j--; }\n    };\n    \n    while (true) {\n        vector<pair<int, int>> sources, sinks;\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N; j++) {\n                if (h[i][j] > 0) sources.push_back({i, j});\n                if (h[i][j] < 0) sinks.push_back({i, j});\n            }\n        \n        if (sources.empty() && sinks.empty()) break;\n        \n        if (truck_load == 0 && !sources.empty()) {\n            long long best_cost = LLONG_MAX;\n            int best_i = -1, best_j = -1;\n            \n            for (auto& [si, sj] : sources) {\n                int amt = h[si][sj];\n                int d_empty = dist(cur_i, cur_j, si, sj);\n                \n                int d_loaded = INT_MAX;\n                for (auto& [ti, tj] : sinks) {\n                    d_loaded = min(d_loaded, dist(si, sj, ti, tj));\n                }\n                if (d_loaded == INT_MAX) d_loaded = 0;\n                \n                long long cost = 100LL * d_empty + (100LL + amt) * d_loaded;\n                \n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_i = si; best_j = sj;\n                }\n            }\n            \n            if (best_i == -1) break;\n            move_to(best_i, best_j);\n            int amt = h[best_i][best_j];\n            ops.push_back(\"+\" + to_string(amt));\n            h[best_i][best_j] = 0;\n            truck_load += amt;\n            \n            // Chain sources if beneficial (allow small negative benefit)\n            while (truck_load > 0) {\n                int sink_d = INT_MAX, ti = -1, tj = -1;\n                for (int i = 0; i < N; i++)\n                    for (int j = 0; j < N; j++)\n                        if (h[i][j] < 0) {\n                            int d = dist(cur_i, cur_j, i, j);\n                            if (d < sink_d) { sink_d = d; ti = i; tj = j; }\n                        }\n                \n                if (sink_d == INT_MAX) break;\n                \n                long long best_benefit = LLONG_MIN;\n                int best_si = -1, best_sj = -1;\n                \n                for (int i = 0; i < N; i++)\n                    for (int j = 0; j < N; j++)\n                        if (h[i][j] > 0) {\n                            int d_to_source = dist(cur_i, cur_j, i, j);\n                            int amt2 = h[i][j];\n                            int d_source_to_sink = dist(i, j, ti, tj);\n                            \n                            long long cost_no_chain = (100LL + truck_load) * sink_d + 100LL * dist(ti, tj, i, j);\n                            long long cost_chain = (100LL + truck_load) * d_to_source + (100LL + truck_load + amt2) * d_source_to_sink;\n                            long long benefit = cost_no_chain - cost_chain;\n                            \n                            if (benefit > best_benefit) {\n                                best_benefit = benefit;\n                                best_si = i; best_sj = j;\n                            }\n                        }\n                \n                // Allow chaining with small negative benefit (threshold -50)\n                if (best_benefit > -50 && best_si >= 0) {\n                    move_to(best_si, best_sj);\n                    int amt2 = h[best_si][best_sj];\n                    ops.push_back(\"+\" + to_string(amt2));\n                    h[best_si][best_sj] = 0;\n                    truck_load += amt2;\n                } else break;\n            }\n        } else if (truck_load > 0 && !sinks.empty()) {\n            // Cost-based sink selection considering return trip\n            long long best_cost = LLONG_MAX;\n            int best_i = -1, best_j = -1;\n            \n            for (auto& [ti, tj] : sinks) {\n                int d_to_sink = dist(cur_i, cur_j, ti, tj);\n                long long cost = (100LL + truck_load) * d_to_sink;\n                \n                if (!sources.empty()) {\n                    int min_d = INT_MAX;\n                    for (auto& [si, sj] : sources)\n                        min_d = min(min_d, dist(ti, tj, si, sj));\n                    cost += 50LL * min_d;\n                }\n                \n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_i = ti; best_j = tj;\n                }\n            }\n            \n            if (best_i == -1) break;\n            move_to(best_i, best_j);\n            int amt = min(truck_load, (long long)-h[best_i][best_j]);\n            ops.push_back(\"-\" + to_string(amt));\n            h[best_i][best_j] += amt;\n            truck_load -= amt;\n            \n            // Chain sinks if beneficial (allow small negative benefit)\n            while (truck_load > 0) {\n                int source_d = INT_MAX, si = -1, sj = -1;\n                for (int i = 0; i < N; i++)\n                    for (int j = 0; j < N; j++)\n                        if (h[i][j] > 0) {\n                            int d = dist(cur_i, cur_j, i, j);\n                            if (d < source_d) { source_d = d; si = i; sj = j; }\n                        }\n                \n                if (source_d == INT_MAX) source_d = 100;\n                \n                long long best_benefit = LLONG_MIN;\n                int best_ti = -1, best_tj = -1;\n                \n                for (int i = 0; i < N; i++)\n                    for (int j = 0; j < N; j++)\n                        if (h[i][j] < 0) {\n                            int d_to_sink = dist(cur_i, cur_j, i, j);\n                            int d_sink_to_source = (si >= 0) ? dist(i, j, si, sj) : 0;\n                            \n                            long long cost_no_chain = 100LL * source_d;\n                            long long cost_chain = (100LL + truck_load) * d_to_sink + 100LL * d_sink_to_source;\n                            long long benefit = cost_no_chain - cost_chain;\n                            \n                            if (benefit > best_benefit) {\n                                best_benefit = benefit;\n                                best_ti = i; best_tj = j;\n                            }\n                        }\n                \n                // Allow chaining with small negative benefit (threshold -50)\n                if (best_benefit > -50 && best_ti >= 0) {\n                    move_to(best_ti, best_tj);\n                    int amt2 = min(truck_load, (long long)-h[best_ti][best_tj]);\n                    ops.push_back(\"-\" + to_string(amt2));\n                    h[best_ti][best_tj] += amt2;\n                    truck_load -= amt2;\n                } else break;\n            }\n        } else break;\n    }\n    \n    for (auto& s : ops) cout << s << \"\\n\";\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, T;\n    cin >> N >> M >> T;\n    const int seed_count = 2 * N * (N - 1);\n    const int grid_size = N * N;\n    vector<vector<int>> X(seed_count, vector<int>(M));\n    \n    for (int i = 0; i < seed_count; i++)\n        for (int j = 0; j < M; j++)\n            cin >> X[i][j];\n    \n    mt19937 rng(42);\n    uniform_int_distribution<int> distPos(0, grid_size - 1);\n    uniform_real_distribution<double> uni(0, 1);\n    \n    for (int t = 0; t < T; t++) {\n        // Select top seeds by total value\n        vector<int> order(seed_count);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) {\n            int sa = 0, sb = 0;\n            for (int l = 0; l < M; l++) { sa += X[a][l]; sb += X[b][l]; }\n            return sa > sb;\n        });\n        \n        vector<int> flat(order.begin(), order.begin() + grid_size);\n        \n        auto pot = [&](int a, int b) -> int {\n            int p = 0;\n            for (int l = 0; l < M; l++) p += max(X[a][l], X[b][l]);\n            return p;\n        };\n        \n        auto contrib = [&](int idx) -> int {\n            int i = idx / N, j = idx % N, c = 0;\n            int seed = flat[idx];\n            if (j > 0) c += pot(seed, flat[idx - 1]);\n            if (j < N - 1) c += pot(seed, flat[idx + 1]);\n            if (i > 0) c += pot(seed, flat[idx - N]);\n            if (i < N - 1) c += pot(seed, flat[idx + N]);\n            return c;\n        };\n        \n        int currentScore = 0;\n        for (int i = 0; i < N; i++)\n            for (int j = 0; j < N - 1; j++) currentScore += pot(flat[i*N+j], flat[i*N+j+1]);\n        for (int i = 0; i < N - 1; i++)\n            for (int j = 0; j < N; j++) currentScore += pot(flat[i*N+j], flat[(i+1)*N+j]);\n        \n        int bestScore = currentScore;\n        vector<int> bestFlat = flat;\n        \n        // Simulated annealing with multiple phases\n        for (int phase = 0; phase < 4; phase++) {\n            double temp = 80.0 / (phase + 1);\n            for (int iter = 0; iter < 150000; iter++) {\n                int p1 = distPos(rng), p2 = distPos(rng);\n                if (p1 == p2) continue;\n                \n                int r1 = p1/N, c1 = p1%N, r2 = p2/N, c2 = p2%N;\n                bool adj = (abs(r1-r2)==1 && c1==c2) || (abs(c1-c2)==1 && r1==r2);\n                \n                int old = contrib(p1) + contrib(p2);\n                if (adj) old -= pot(flat[p1], flat[p2]);\n                \n                swap(flat[p1], flat[p2]);\n                \n                int nw = contrib(p1) + contrib(p2);\n                if (adj) nw -= pot(flat[p1], flat[p2]);\n                \n                int delta = nw - old;\n                \n                if (delta > 0 || uni(rng) < exp(delta / temp)) {\n                    currentScore += delta;\n                    if (currentScore > bestScore) {\n                        bestScore = currentScore;\n                        bestFlat = flat;\n                    }\n                } else {\n                    swap(flat[p1], flat[p2]);\n                }\n                temp *= 0.99995;\n            }\n            // Restart from best for next phase\n            flat = bestFlat;\n            currentScore = bestScore;\n        }\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << bestFlat[i * N + j];\n                if (j < N - 1) cout << \" \";\n            }\n            cout << \"\\n\";\n        }\n        cout.flush();\n        \n        for (int i = 0; i < seed_count; i++)\n            for (int j = 0; j < M; j++)\n                cin >> X[i][j];\n    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<int> par, len, edir;\nvector<vector<int>> child;\nint rx, ry;\nvector<int> leaves;\nvector<vector<int>> grid;\nvector<string> T;\nvector<pair<int,int>> src_list, tgt_list;\nvector<bool> src_done, tgt_done;\nvector<bool> holding;\n\nconst int DX[4] = {0, 1, 0, -1};\nconst int DY[4] = {1, 0, -1, 0};\nconst char DIR_C[4] = {'R', 'D', 'L', 'U'};\n\npair<int,int> get_pos(int v) {\n    if (par[v] < 0) return {rx, ry};\n    auto p = get_pos(par[v]);\n    return {p.first + DX[edir[v]] * len[v], p.second + DY[edir[v]] * len[v]};\n}\n\nvoid rotate_subtree(int u, int d) {\n    queue<int> q; q.push(u);\n    while (!q.empty()) {\n        int v = q.front(); q.pop();\n        if (par[v] >= 0) edir[v] = ((edir[v] + d) % 4 + 4) % 4;\n        for (int c : child[v]) q.push(c);\n    }\n}\n\nint find_nearest_src(int x, int y) {\n    int best = -1, bd = INT_MAX;\n    for (size_t i = 0; i < src_list.size(); i++) {\n        if (src_done[i]) continue;\n        int d = abs(x - src_list[i].first) + abs(y - src_list[i].second);\n        if (d < bd) { bd = d; best = (int)i; }\n    }\n    return best;\n}\n\nint find_nearest_tgt(int x, int y) {\n    int best = -1, bd = INT_MAX;\n    for (size_t i = 0; i < tgt_list.size(); i++) {\n        if (tgt_done[i]) continue;\n        int d = abs(x - tgt_list[i].first) + abs(y - tgt_list[i].second);\n        if (d < bd) { bd = d; best = (int)i; }\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> V;\n    \n    vector<string> S(N);\n    T.resize(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    // Design arm: star with branches for reach\n    int nb = min(V - 1, 5);\n    int blen = N / 3;\n    \n    par.assign(V, -1);\n    len.assign(V, 0);\n    edir.assign(V, 0); // ALL start pointing RIGHT (direction 0)\n    child.assign(V, vector<int>());\n    \n    // Create main branches from root\n    for (int i = 1; i <= nb && i < V; i++) {\n        par[i] = 0;\n        len[i] = blen;\n        child[0].push_back(i);\n    }\n    // Add fingertips to branches\n    for (int i = nb + 1; i < V; i++) {\n        int p = (i - nb - 1) % nb + 1;\n        par[i] = p;\n        len[i] = 2;\n        child[p].push_back(i);\n    }\n    \n    for (int i = 0; i < V; i++) \n        if (child[i].empty()) leaves.push_back(i);\n    \n    // Position root\n    long long sx = 0, sy = 0; int cnt = 0;\n    for (int i = 0; i < N; i++) \n        for (int j = 0; j < N; j++) \n            if (S[i][j] == '1') { sx += i; sy += j; cnt++; }\n    rx = cnt > 0 ? sx / cnt : N / 2; \n    ry = cnt > 0 ? sy / cnt : N / 2;\n    rx = max(blen, min(N - 1 - blen, rx)); \n    ry = max(blen, min(N - 1 - blen, ry));\n    \n    // Output arm design\n    cout << V << \"\\n\";\n    for (int i = 1; i < V; i++) cout << par[i] << \" \" << len[i] << \"\\n\";\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    // Initialize grid and objectives\n    grid.assign(N, vector<int>(N, 0));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = (S[i][j] == '1') ? 1 : 0;\n            if (S[i][j] == '1' && T[i][j] == '0') src_list.push_back({i, j});\n            if (T[i][j] == '1' && S[i][j] == '0') tgt_list.push_back({i, j});\n        }\n    }\n    src_done.assign(src_list.size(), false);\n    tgt_done.assign(tgt_list.size(), false);\n    holding.assign(leaves.size(), false);\n    \n    vector<int> obj_idx(leaves.size(), -1);\n    int stuck_count = 0;\n    \n    auto compute_score = [&]() {\n        int s = 0;\n        for (size_t i = 0; i < leaves.size(); i++) {\n            if (obj_idx[i] < 0) continue;\n            auto p = get_pos(leaves[i]);\n            auto& obj = holding[i] ? tgt_list[obj_idx[i]] : src_list[obj_idx[i]];\n            s += abs(p.first - obj.first) + abs(p.second - obj.second);\n        }\n        return s;\n    };\n    \n    for (int turn = 0; turn < 100000; turn++) {\n        // Check done\n        bool done = true;\n        for (size_t i = 0; i < tgt_list.size() && done; i++) \n            if (!tgt_done[i] && grid[tgt_list[i].first][tgt_list[i].second] == 0) \n                done = false;\n        if (done) break;\n        \n        string cmd(2 * V, '.');\n        \n        // Update objectives\n        for (size_t i = 0; i < leaves.size(); i++) {\n            auto p = get_pos(leaves[i]);\n            obj_idx[i] = holding[i] ? find_nearest_tgt(p.first, p.second) : find_nearest_src(p.first, p.second);\n        }\n        \n        // Evaluate moves\n        int best_dir = -1, best_score = INT_MAX;\n        for (int d = 0; d < 4; d++) {\n            int nx = rx + DX[d], ny = ry + DY[d];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n            rx += DX[d]; ry += DY[d];\n            int score = compute_score();\n            rx -= DX[d]; ry -= DY[d];\n            if (score < best_score) { best_score = score; best_dir = d; }\n        }\n        \n        // Random exploration if stuck\n        if (stuck_count > 20) {\n            for (int attempt = 0; attempt < 10; attempt++) {\n                int r = rand() % 4;\n                int nx = rx + DX[r], ny = ry + DY[r];\n                if (nx >= 0 && nx < N && ny >= 0 && ny < N) { best_dir = r; break; }\n            }\n            stuck_count = 0;\n        }\n        \n        if (best_dir >= 0) { \n            cmd[0] = DIR_C[best_dir]; \n            rx += DX[best_dir]; \n            ry += DY[best_dir]; \n        }\n        \n        // Evaluate rotations\n        for (int u = 1; u < V; u++) {\n            int so = compute_score();\n            rotate_subtree(u, 3); int sl = compute_score();\n            rotate_subtree(u, 1); rotate_subtree(u, 1); int sr = compute_score();\n            rotate_subtree(u, 3);\n            if (sl < so && sl <= sr) { cmd[u] = 'L'; rotate_subtree(u, 3); }\n            else if (sr < so) { cmd[u] = 'R'; rotate_subtree(u, 1); }\n        }\n        \n        // Pickup/drop\n        int actions = 0;\n        for (size_t i = 0; i < leaves.size(); i++) {\n            auto p = get_pos(leaves[i]);\n            int x = p.first, y = p.second;\n            if (x < 0 || x >= N || y < 0 || y >= N) continue;\n            \n            if (!holding[i] && grid[x][y] == 1 && T[x][y] == '0') {\n                cmd[V + leaves[i]] = 'P'; \n                holding[i] = true; \n                grid[x][y] = 0; \n                actions++;\n                for (size_t j = 0; j < src_list.size(); j++) \n                    if (src_list[j] == make_pair(x, y)) { src_done[j] = true; break; }\n            } else if (holding[i] && grid[x][y] == 0 && T[x][y] == '1') {\n                cmd[V + leaves[i]] = 'P'; \n                holding[i] = false; \n                grid[x][y] = 1; \n                actions++;\n                for (size_t j = 0; j < tgt_list.size(); j++) \n                    if (tgt_list[j] == make_pair(x, y)) { tgt_done[j] = true; break; }\n            }\n        }\n        \n        if (actions == 0) stuck_count++;\n        else stuck_count = 0;\n        \n        cout << cmd << \"\\n\";\n    }\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nint mx[5000], my[5000], sx[5000], sy[5000];\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N;\n    for (int i = 0; i < N; i++) cin >> mx[i] >> my[i];\n    for (int i = 0; i < N; i++) cin >> sx[i] >> sy[i];\n    \n    const int MAXC = 100000;\n    int best = 0, bx1 = 0, by1 = 0, bx2 = MAXC, by2 = MAXC;\n    \n    int GS = 200;\n    int CS = (MAXC + GS - 1) / GS;\n    vector<vector<int>> diff(GS, vector<int>(GS, 0));\n    \n    for (int i = 0; i < N; i++) diff[min(mx[i]/CS, GS-1)][min(my[i]/CS, GS-1)]++;\n    for (int i = 0; i < N; i++) diff[min(sx[i]/CS, GS-1)][min(sy[i]/CS, GS-1)]--;\n    \n    vector<vector<int>> pref(GS+1, vector<int>(GS+1, 0));\n    for (int i = 0; i < GS; i++)\n        for (int j = 0; j < GS; j++)\n            pref[i+1][j+1] = diff[i][j] + pref[i][j+1] + pref[i+1][j] - pref[i][j];\n    \n    for (int x1 = 0; x1 < GS; x1++) {\n        for (int x2 = x1; x2 < GS; x2++) {\n            int minPref = 0, minIdx = -1, cs = 0;\n            for (int y2 = 0; y2 < GS; y2++) {\n                cs += pref[x2+1][y2+1] - pref[x1][y2+1] - pref[x2+1][y2] + pref[x1][y2];\n                int cur = cs - minPref;\n                if (cur > best) {\n                    best = cur;\n                    bx1 = x1 * CS; by1 = (minIdx + 1) * CS;\n                    bx2 = min((x2 + 1) * CS - 1, MAXC);\n                    by2 = min((y2 + 1) * CS - 1, MAXC);\n                }\n                if (cs < minPref) { minPref = cs; minIdx = y2; }\n            }\n        }\n    }\n    \n    auto eval = [&](int x1, int y1, int x2, int y2) {\n        int c = 0;\n        for (int i = 0; i < N; i++) {\n            if (mx[i] >= x1 && mx[i] <= x2 && my[i] >= y1 && my[i] <= y2) c++;\n            if (sx[i] >= x1 && sx[i] <= x2 && sy[i] >= y1 && sy[i] <= y2) c--;\n        }\n        return c;\n    };\n    \n    // Multi-pass refinement with focused candidates\n    for (int it = 0; it < 3; it++) {\n        // X candidates: fish whose y is in current y-range\n        vector<int> xc;\n        for (int i = 0; i < N; i++) {\n            if (my[i] >= by1 && my[i] <= by2) xc.push_back(mx[i]);\n            if (sy[i] >= by1 && sy[i] <= by2) xc.push_back(sx[i]);\n        }\n        // Y candidates: fish whose x is in current x-range  \n        vector<int> yc;\n        for (int i = 0; i < N; i++) {\n            if (mx[i] >= bx1 && mx[i] <= bx2) yc.push_back(my[i]);\n            if (sx[i] >= bx1 && sx[i] <= bx2) yc.push_back(sy[i]);\n        }\n        sort(xc.begin(), xc.end()); xc.erase(unique(xc.begin(), xc.end()), xc.end());\n        sort(yc.begin(), yc.end()); yc.erase(unique(yc.begin(), yc.end()), yc.end());\n        \n        for (int x : xc) if (x >= 0 && x <= bx2) { int v = eval(x, by1, bx2, by2); if (v > best) { best = v; bx1 = x; } }\n        for (int x : xc) if (x >= bx1 && x <= MAXC) { int v = eval(bx1, by1, x, by2); if (v > best) { best = v; bx2 = x; } }\n        for (int y : yc) if (y >= 0 && y <= by2) { int v = eval(bx1, y, bx2, by2); if (v > best) { best = v; by1 = y; } }\n        for (int y : yc) if (y >= by1 && y <= MAXC) { int v = eval(bx1, by1, bx2, y); if (v > best) { best = v; by2 = y; } }\n    }\n    \n    if (best <= 0) {\n        cout << 4 << \"\\n0 0\\n0 1\\n1 1\\n1 0\\n\";\n    } else {\n        cout << 4 << \"\\n\" << bx1 << \" \" << by1 << \"\\n\" << bx2 << \" \" << by1 << \"\\n\"\n             << bx2 << \" \" << by2 << \"\\n\" << bx1 << \" \" << by2 << \"\\n\";\n    }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, sigma;\nvector<long long> w, h;\nmt19937_64 rng(42);\n\nstruct State {\n    vector<long long> x1, y1, x2, y2;\n    long long W = 0, H = 0;\n    \n    State() { x1.resize(100); y1.resize(100); x2.resize(100); y2.resize(100); }\n    \n    void place(int i, int rot, int dir, int ref) {\n        long long width = rot ? h[i] : w[i];\n        long long height = rot ? w[i] : h[i];\n        long long x0, y0;\n        \n        if (dir == 0) { // U\n            x0 = (ref < 0) ? 0 : x2[ref];\n            y0 = 0;\n            for (int j = 0; j < i; j++)\n                if (x0 < x2[j] && x0 + width > x1[j]) y0 = max(y0, y2[j]);\n        } else { // L\n            y0 = (ref < 0) ? 0 : y2[ref];\n            x0 = 0;\n            for (int j = 0; j < i; j++)\n                if (y0 < y2[j] && y0 + height > y1[j]) x0 = max(x0, x2[j]);\n        }\n        \n        x1[i] = x0; y1[i] = y0;\n        x2[i] = x0 + width; y2[i] = y0 + height;\n        W = max(W, x2[i]); H = max(H, y2[i]);\n    }\n    \n    long long score() const { return W + H; }\n};\n\nlong long simulate(const vector<int>& rot, const vector<int>& dir, const vector<int>& ref) {\n    State s;\n    for (int i = 0; i < N; i++) s.place(i, rot[i], dir[i], ref[i]);\n    return s.score();\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T >> sigma;\n    w.resize(N); h.resize(N);\n    for (int i = 0; i < N; i++) cin >> w[i] >> h[i];\n    \n    vector<int> rot(N, 0), dir(N, 0), ref(N, -1);\n    \n    // Greedy init - for each position, try all options and pick best\n    for (int i = 1; i < N; i++) {\n        long long best = LLONG_MAX;\n        int br = 0, bd = 0, bf = -1;\n        for (int r = 0; r < 2; r++)\n            for (int d = 0; d < 2; d++)\n                for (int f = -1; f < i; f++) {\n                    rot[i] = r; dir[i] = d; ref[i] = f;\n                    long long s = simulate(rot, dir, ref);\n                    if (s < best) { best = s; br = r; bd = d; bf = f; }\n                }\n        rot[i] = br; dir[i] = bd; ref[i] = bf;\n    }\n    \n    long long curr = simulate(rot, dir, ref);\n    long long best = curr;\n    auto best_rot = rot, best_dir = dir, best_ref = ref;\n    \n    uniform_real_distribution<double> uni(0.0, 1.0);\n    \n    // Time management: use ~2.7 seconds total\n    auto start = chrono::steady_clock::now();\n    auto deadline = start + chrono::milliseconds(2700);\n    int total_iter = 0;\n    int turn = 0;\n    \n    while (turn < T) {\n        auto now = chrono::steady_clock::now();\n        auto remaining = deadline - now;\n        auto per_turn = remaining / (T - turn);\n        auto turn_end = now + per_turn;\n        \n        while (chrono::steady_clock::now() < turn_end) {\n            total_iter++;\n            double temp = max(1.0, 5e6 * pow(0.99997, total_iter));\n            \n            int idx = 1 + rng() % (N - 1);\n            int op = rng() % 4;\n            int old_r = rot[idx], old_d = dir[idx], old_f = ref[idx];\n            \n            if (op == 0) rot[idx] ^= 1;\n            else if (op == 1) dir[idx] ^= 1;\n            else if (op == 2) ref[idx] = (uni(rng) < 0.35) ? -1 : (int)(rng() % idx);\n            else { // combined move\n                if (uni(rng) < 0.5) rot[idx] ^= 1;\n                if (uni(rng) < 0.5) dir[idx] ^= 1;\n                ref[idx] = (uni(rng) < 0.35) ? -1 : (int)(rng() % idx);\n            }\n            \n            long long s = simulate(rot, dir, ref);\n            if (s <= curr || uni(rng) < exp(-(s - curr) / temp)) {\n                curr = s;\n                if (s < best) { best = s; best_rot = rot; best_dir = dir; best_ref = ref; }\n            } else {\n                rot[idx] = old_r; dir[idx] = old_d; ref[idx] = old_f;\n            }\n        }\n        \n        cout << N << \"\\n\";\n        for (int i = 0; i < N; i++)\n            cout << i << \" \" << best_rot[i] << \" \" << (best_dir[i] ? 'L' : 'U') << \" \" << best_ref[i] << \"\\n\";\n        cout.flush();\n        \n        long long Wp, Hp; cin >> Wp >> Hp;\n        turn++;\n    }\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    \n    int N, M, H; cin >> N >> M >> H;\n    vector<int> A(N);\n    for (int& a : A) cin >> a;\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    for (int i = 0; i < N; i++) { int x, y; cin >> x >> y; }\n    \n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    \n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int i, int j) { return A[i] < A[j]; });\n    \n    vector<int> best_parent(N, -1);\n    long long best_score = 0;\n    \n    auto start = chrono::steady_clock::now();\n    \n    auto solve = [&](const vector<int>& ord) -> pair<vector<int>, long long> {\n        vector<int> parent(N, -1), height(N, 0), child_count(N, 0);\n        vector<bool> used(N, false);\n        \n        for (int v : ord) {\n            int best_p = -1, best_h = -1, best_b = INT_MAX;\n            for (int u : adj[v]) {\n                if (!used[u] || height[u] >= H) continue;\n                int h = height[u] + 1;\n                if (h > best_h || (h == best_h && A[u] < best_b)) {\n                    best_h = h; best_p = u; best_b = A[u];\n                }\n            }\n            parent[v] = best_p;\n            height[v] = (best_p == -1) ? 0 : best_h;\n            if (best_p != -1) child_count[best_p]++;\n            used[v] = true;\n        }\n        \n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int v = 0; v < N; v++) {\n                if (child_count[v] > 0 || height[v] == H) continue;\n                int best_u = -1, best_h = height[v];\n                for (int u : adj[v]) {\n                    if (u == parent[v] || height[u] + 1 > H) continue;\n                    if (height[u] + 1 > best_h) {\n                        best_h = height[u] + 1;\n                        best_u = u;\n                    }\n                }\n                if (best_u != -1) {\n                    if (parent[v] != -1) child_count[parent[v]]--;\n                    parent[v] = best_u;\n                    height[v] = best_h;\n                    child_count[best_u]++;\n                    changed = true;\n                }\n            }\n        }\n        \n        long long score = 0;\n        for (int v = 0; v < N; v++) score += (long long)(height[v] + 1) * A[v];\n        return {parent, score};\n    };\n    \n    tie(best_parent, best_score) = solve(order);\n    \n    vector<int> cur_ord = order;\n    long long cur_score = best_score;\n    \n    while (chrono::duration<double>(chrono::steady_clock::now() - start).count() < 1.9) {\n        vector<int> ord = cur_ord;\n        \n        int mode = rng() % 5;\n        if (mode == 0) {\n            for (int i = 0, j; i < N; i = j) {\n                j = i + 1;\n                while (j < N && A[ord[j]] == A[ord[i]]) j++;\n                if (j - i > 1) shuffle(ord.begin() + i, ord.begin() + j, rng);\n            }\n        } else if (mode == 1) {\n            int cnt = 1 + rng() % 20;\n            for (int i = 0; i < cnt; i++) swap(ord[rng() % N], ord[rng() % N]);\n        } else if (mode == 2) {\n            int a = rng() % N, b = rng() % N;\n            if (a > b) swap(a, b);\n            reverse(ord.begin() + a, ord.begin() + b + 1);\n        } else if (mode == 3) {\n            int a = rng() % N, b = rng() % N, c = rng() % N;\n            if (a > b) swap(a, b);\n            if (b > c) swap(b, c);\n            if (a > b) swap(a, b);\n            if (a < b && b < c) rotate(ord.begin() + a, ord.begin() + b, ord.begin() + c);\n        } else {\n            int a = rng() % N, b = rng() % N;\n            int v = ord[a];\n            ord.erase(ord.begin() + a);\n            ord.insert(ord.begin() + b, v);\n        }\n        \n        auto [p, s] = solve(ord);\n        if (s > best_score) {\n            best_score = s;\n            best_parent = p;\n        }\n        if (s >= cur_score) {\n            cur_score = s;\n            cur_ord = ord;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) cout << best_parent[i] << \" \\n\"[i == N-1];\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <set>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nint N;\nvector<pair<int,int>> onis;\nvector<int> safe_up, safe_down, safe_left, safe_right;\n\npair<int,vector<pair<char,int>>> solve(set<int> remaining, mt19937& rng, double temperature) {\n    vector<pair<char, int>> result;\n    int total_cost = 0;\n    \n    while (!remaining.empty()) {\n        struct Op { double score; int cost; char dir; int idx; vector<int> batch; };\n        vector<Op> ops;\n        \n        for (int j = 0; j < N; j++) {\n            vector<int> batch; int max_row = -1;\n            for (int idx : remaining)\n                if (onis[idx].second == j && safe_up[idx]) {\n                    batch.push_back(idx); max_row = max(max_row, onis[idx].first);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (max_row + 1);\n                ops.push_back({(double)batch.size() / cost, cost, 'U', j, batch});\n            }\n        }\n        for (int j = 0; j < N; j++) {\n            vector<int> batch; int min_row = N;\n            for (int idx : remaining)\n                if (onis[idx].second == j && safe_down[idx]) {\n                    batch.push_back(idx); min_row = min(min_row, onis[idx].first);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (N - min_row);\n                ops.push_back({(double)batch.size() / cost, cost, 'D', j, batch});\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            vector<int> batch; int max_col = -1;\n            for (int idx : remaining)\n                if (onis[idx].first == i && safe_left[idx]) {\n                    batch.push_back(idx); max_col = max(max_col, onis[idx].second);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (max_col + 1);\n                ops.push_back({(double)batch.size() / cost, cost, 'L', i, batch});\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            vector<int> batch; int min_col = N;\n            for (int idx : remaining)\n                if (onis[idx].first == i && safe_right[idx]) {\n                    batch.push_back(idx); min_col = min(min_col, onis[idx].second);\n                }\n            if (!batch.empty()) {\n                int cost = 2 * (N - min_col);\n                ops.push_back({(double)batch.size() / cost, cost, 'R', i, batch});\n            }\n        }\n        \n        if (ops.empty()) break;\n        \n        // Sort by score (efficiency)\n        sort(ops.begin(), ops.end(), [](const Op& a, const Op& b) { return a.score > b.score; });\n        \n        // Temperature-based selection\n        int choice = 0;\n        if (temperature > 0) {\n            // Boltzmann selection\n            vector<double> probs;\n            double sum = 0;\n            int limit = min(10, (int)ops.size());\n            for (int i = 0; i < limit; i++) {\n                double p = exp((ops[i].score - ops[0].score) / temperature);\n                probs.push_back(p);\n                sum += p;\n            }\n            uniform_real_distribution<double> dist(0, sum);\n            double r = dist(rng);\n            double cum = 0;\n            for (int i = 0; i < limit; i++) {\n                cum += probs[i];\n                if (r < cum) { choice = i; break; }\n            }\n        }\n        \n        for (int oni_idx : ops[choice].batch) remaining.erase(oni_idx);\n        \n        total_cost += ops[choice].cost;\n        int shifts = ops[choice].cost / 2;\n        char dir = ops[choice].dir, rev_dir = (dir == 'U' ? 'D' : dir == 'D' ? 'U' : dir == 'L' ? 'R' : 'L');\n        for (int k = 0; k < shifts; k++) result.emplace_back(dir, ops[choice].idx);\n        for (int k = 0; k < shifts; k++) result.emplace_back(rev_dir, ops[choice].idx);\n    }\n    \n    return {total_cost, result};\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j] == 'x') onis.emplace_back(i, j);\n    \n    int num_onis = onis.size();\n    safe_up.assign(num_onis, 1);\n    safe_down.assign(num_onis, 1);\n    safe_left.assign(num_onis, 1);\n    safe_right.assign(num_onis, 1);\n    \n    for (int idx = 0; idx < num_onis; idx++) {\n        auto [i, j] = onis[idx];\n        for (int fi = 0; fi < N; fi++)\n            for (int fj = 0; fj < N; fj++)\n                if (board[fi][fj] == 'o') {\n                    if (fj == j && fi < i) safe_up[idx] = 0;\n                    if (fj == j && fi > i) safe_down[idx] = 0;\n                    if (fi == i && fj < j) safe_left[idx] = 0;\n                    if (fi == i && fj > j) safe_right[idx] = 0;\n                }\n    }\n    \n    set<int> initial;\n    for (int idx = 0; idx < num_onis; idx++) initial.insert(idx);\n    \n    mt19937 rng(12345);\n    \n    auto [cost0, result0] = solve(initial, rng, 0);\n    int best_cost = cost0;\n    vector<pair<char,int>> best_result = result0;\n    \n    auto start = chrono::steady_clock::now();\n    long long iter = 0;\n    \n    while (chrono::duration_cast<chrono::microseconds>(chrono::steady_clock::now() - start).count() < 1900000) {\n        iter++;\n        double temp = 0.02 + 0.1 * (iter % 100) / 100.0;  // Varying temperature\n        auto [cost, result] = solve(initial, rng, temp);\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_result = result;\n        }\n    }\n    \n    for (auto& [d, p] : best_result) cout << d << \" \" << p << \"\\n\";\n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nconstexpr int N = 100;\nconstexpr int L = 500000;\n\nint T[N], a[N], b[N], v[N], ba[N], bb[N];\n\nstruct RNG {\n    uint64_t s;\n    RNG(uint64_t seed = 88172645463325252ULL) : s(seed) {}\n    uint64_t next() { s ^= s << 7; s ^= s >> 9; return s; }\n    int operator()(int n) { return (int)(next() % n); }\n    double dbl() { return (double)next() / UINT64_MAX; }\n} rng;\n\ninline long long simulate() {\n    memset(v, 0, sizeof(v));\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        int t = ++v[cur];\n        cur = (t & 1) ? a[cur] : b[cur];\n    }\n    long long err = 0;\n    for (int i = 0; i < N; i++) err += abs(v[i] - T[i]);\n    return err;\n}\n\nvoid init_solution() {\n    vector<int> active;\n    for (int i = 0; i < N; i++) if (T[i] > 0) active.push_back(i);\n    if (active.empty()) active.push_back(0);\n    \n    sort(active.begin(), active.end(), [](int x, int y) { return T[x] < T[y]; });\n    \n    for (int i = 0; i < N; i++) a[i] = b[i] = active[0];\n    int sz = active.size();\n    for (int i = 0; i < sz; i++) {\n        a[active[i]] = b[active[i]] = active[(i + 1) % sz];\n    }\n}\n\nlong long sa_run(double duration_ms, uint64_t seed) {\n    rng = RNG(seed);\n    init_solution();\n    \n    long long cur = simulate(), best = cur;\n    memcpy(ba, a, sizeof(a)); memcpy(bb, b, sizeof(b));\n    \n    double temp = 60000.0;\n    auto dl = chrono::steady_clock::now() + chrono::milliseconds((long long)duration_ms);\n    int stuck = 0;\n    \n    while (chrono::steady_clock::now() < dl) {\n        int i = rng(N), oa = a[i], ob = b[i];\n        \n        int move_type = rng(100);\n        if (move_type < 40) a[i] = rng(N);\n        else if (move_type < 80) b[i] = rng(N);\n        else { a[i] = rng(N); b[i] = rng(N); }\n        \n        long long ne = simulate();\n        \n        if (ne <= cur || exp(-(double)(ne - cur) / temp) > rng.dbl()) {\n            cur = ne; stuck = 0;\n            if (ne < best) { \n                best = ne; \n                memcpy(ba, a, sizeof(a)); memcpy(bb, b, sizeof(b)); \n            }\n        } else { \n            a[i] = oa; b[i] = ob; \n            stuck++; \n        }\n        \n        if (stuck > 200) {\n            memcpy(a, ba, sizeof(a)); memcpy(b, bb, sizeof(b));\n            cur = best;\n            temp = min(60000.0, temp * 4.0);\n            stuck = 0;\n        }\n        \n        temp = max(0.5, temp * 0.99993);\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int n_, L_; cin >> n_ >> L_;\n    for (int i = 0; i < N; i++) cin >> T[i];\n    \n    long long best_err = LLONG_MAX;\n    int best_a[N], best_b[N];\n    \n    // 9 SA runs for diversity\n    for (int run = 0; run < 9; run++) {\n        long long err = sa_run(170, 12345ULL + run * 9137ULL + run * run * 23ULL);\n        if (err < best_err) {\n            best_err = err;\n            memcpy(best_a, ba, sizeof(ba));\n            memcpy(best_b, bb, sizeof(bb));\n        }\n    }\n    \n    // Extended greedy phase with targeted moves\n    memcpy(a, best_a, sizeof(a));\n    memcpy(b, best_b, sizeof(b));\n    long long cur = simulate();\n    auto dl = chrono::steady_clock::now() + chrono::milliseconds(370);\n    \n    while (chrono::steady_clock::now() < dl) {\n        // Random moves\n        int i = rng(N), oa = a[i], ob = b[i];\n        \n        a[i] = rng(N);\n        long long ne = simulate();\n        if (ne < cur) { \n            cur = ne; \n            if (ne < best_err) { best_err = ne; memcpy(best_a, a, sizeof(a)); memcpy(best_b, b, sizeof(b)); }\n        } else a[i] = oa;\n        \n        b[i] = rng(N);\n        ne = simulate();\n        if (ne < cur) { \n            cur = ne; \n            if (ne < best_err) { best_err = ne; memcpy(best_a, a, sizeof(a)); memcpy(best_b, b, sizeof(b)); }\n        } else b[i] = ob;\n        \n        a[i] = rng(N); b[i] = rng(N);\n        ne = simulate();\n        if (ne < cur) { \n            cur = ne; \n            if (ne < best_err) { best_err = ne; memcpy(best_a, a, sizeof(a)); memcpy(best_b, b, sizeof(b)); }\n        } else { a[i] = oa; b[i] = ob; }\n        \n        // Find top 3 error nodes\n        int err_nodes[3] = {0, 0, 0};\n        int err_vals[3] = {abs(v[0] - T[0]), 0, 0};\n        for (int j = 1; j < N; j++) {\n            int e = abs(v[j] - T[j]);\n            if (e > err_vals[0]) {\n                err_vals[2] = err_vals[1]; err_nodes[2] = err_nodes[1];\n                err_vals[1] = err_vals[0]; err_nodes[1] = err_nodes[0];\n                err_vals[0] = e; err_nodes[0] = j;\n            } else if (e > err_vals[1]) {\n                err_vals[2] = err_vals[1]; err_nodes[2] = err_nodes[1];\n                err_vals[1] = e; err_nodes[1] = j;\n            } else if (e > err_vals[2]) {\n                err_vals[2] = e; err_nodes[2] = j;\n            }\n        }\n        \n        // Try targeted moves on top error nodes\n        for (int k = 0; k < 3; k++) {\n            i = err_nodes[k]; oa = a[i]; ob = b[i];\n            a[i] = rng(N);\n            ne = simulate();\n            if (ne < cur) {\n                cur = ne;\n                if (ne < best_err) { best_err = ne; memcpy(best_a, a, sizeof(a)); memcpy(best_b, b, sizeof(b)); }\n            } else a[i] = oa;\n            \n            b[i] = rng(N);\n            ne = simulate();\n            if (ne < cur) {\n                cur = ne;\n                if (ne < best_err) { best_err = ne; memcpy(best_a, a, sizeof(a)); memcpy(best_b, b, sizeof(b)); }\n            } else b[i] = ob;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\nvector<int> G;\nvector<double> cx, cy;\nvector<int> lx, rx, ly, ry;\n\nstruct UnionFind {\n    vector<int> p;\n    UnionFind(int n) : p(n) { 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 x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        p[y] = x;\n        return true;\n    }\n};\n\ninline double estDist(int i, int j) {\n    double dx = cx[i] - cx[j], dy = cy[i] - cy[j];\n    return sqrt(dx*dx + dy*dy);\n}\n\ninline int minDist(int i, int j) {\n    int dx = 0, dy = 0;\n    if (rx[i] < lx[j]) dx = lx[j] - rx[i];\n    else if (rx[j] < lx[i]) dx = lx[i] - rx[j];\n    if (ry[i] < ly[j]) dy = ly[j] - ry[i];\n    else if (ry[j] < ly[i]) dy = ly[i] - ry[j];\n    return (int)sqrt((double)dx*dx + dy*dy);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> Q >> L >> W;\n    G.resize(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    cx.resize(N); cy.resize(N);\n    lx.resize(N); rx.resize(N); ly.resize(N); ry.resize(N);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> lx[i] >> rx[i] >> ly[i] >> ry[i];\n        cx[i] = (lx[i] + rx[i]) / 2.0;\n        cy[i] = (ly[i] + ry[i]) / 2.0;\n    }\n    \n    // Greedy nearest-neighbor grouping with better seed spread\n    vector<int> assignment(N, -1);\n    vector<vector<int>> groups(M);\n    \n    // Sort groups by size descending\n    vector<int> groupOrder(M);\n    iota(groupOrder.begin(), groupOrder.end(), 0);\n    sort(groupOrder.begin(), groupOrder.end(), [](int a, int b) { return G[a] > G[b]; });\n    \n    // Sort cities by position for seed spread\n    vector<int> sortedCities(N);\n    iota(sortedCities.begin(), sortedCities.end(), 0);\n    sort(sortedCities.begin(), sortedCities.end(), [](int a, int b) {\n        return make_pair(cx[a], cy[a]) < make_pair(cx[b], cy[b]);\n    });\n    \n    int seedIdx = 0;\n    for (int gIdx = 0; gIdx < M; gIdx++) {\n        int g = groupOrder[gIdx];\n        \n        // Find next unassigned city as seed (spread across plane)\n        int seed = -1;\n        while (seedIdx < N && assignment[sortedCities[seedIdx]] != -1) {\n            seedIdx++;\n        }\n        if (seedIdx < N) {\n            seed = sortedCities[seedIdx];\n            seedIdx++;\n        } else {\n            for (int i = 0; i < N; i++) {\n                if (assignment[i] == -1) { seed = i; break; }\n            }\n        }\n        \n        if (seed == -1) break;\n        assignment[seed] = g;\n        groups[g].push_back(seed);\n        \n        // Greedily add nearest unassigned city\n        while ((int)groups[g].size() < G[g]) {\n            double best = 1e18;\n            int bestCity = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (assignment[i] == -1) {\n                    for (int c : groups[g]) {\n                        double d = estDist(i, c);\n                        if (d < best) {\n                            best = d;\n                            bestCity = i;\n                        }\n                    }\n                }\n            }\n            \n            if (bestCity != -1) {\n                assignment[bestCity] = g;\n                groups[g].push_back(bestCity);\n            } else break;\n        }\n    }\n    \n    // Query each group\n    set<pair<int,int>> verifiedEdges;\n    int qUsed = 0;\n    \n    for (int g = 0; g < M && qUsed < Q; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        // Sort by position for better query coverage\n        sort(groups[g].begin(), groups[g].end(), [](int a, int b) {\n            return make_pair(cx[a], cy[a]) < make_pair(cx[b], cy[b]);\n        });\n        \n        if (sz <= L) {\n            cout << \"? \" << sz;\n            for (int c : groups[g]) cout << \" \" << c;\n            cout << endl;\n            \n            for (int i = 0; i < sz - 1; i++) {\n                int a, b;\n                cin >> a >> b;\n                verifiedEdges.insert(make_pair(min(a, b), max(a, b)));\n            }\n            qUsed++;\n        } else {\n            // Query with overlapping windows\n            int step = max(1, (L - 1) / 2);\n            for (int start = 0; start < sz && qUsed < Q; start += step) {\n                int end = min(start + L, sz);\n                if (end - start < 2) break;\n                cout << \"? \" << (end - start);\n                for (int i = start; i < end; i++) cout << \" \" << groups[g][i];\n                cout << endl;\n                \n                for (int i = 0; i < (end - start) - 1; i++) {\n                    int a, b;\n                    cin >> a >> b;\n                    verifiedEdges.insert(make_pair(min(a, b), max(a, b)));\n                }\n                qUsed++;\n            }\n        }\n    }\n    \n    // Build MST for each group\n    vector<vector<pair<int,int>>> ans(M);\n    \n    for (int g = 0; g < M; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        struct Edge {\n            int verified;\n            int minD;\n            double estD;\n            int idx_i, idx_j;\n            int city_i, city_j;\n        };\n        \n        vector<Edge> edges;\n        for (int i = 0; i < sz; i++) {\n            for (int j = i + 1; j < sz; j++) {\n                int ci = groups[g][i], cj = groups[g][j];\n                int mn = minDist(ci, cj);\n                double est = estDist(ci, cj);\n                auto key = make_pair(min(ci, cj), max(ci, cj));\n                bool verified = verifiedEdges.count(key);\n                \n                edges.push_back({verified ? 0 : 1, mn, est, i, j, ci, cj});\n            }\n        }\n        sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) {\n            if (a.verified != b.verified) return a.verified < b.verified;\n            if (a.minD != b.minD) return a.minD < b.minD;\n            return a.estD < b.estD;\n        });\n        \n        UnionFind uf(sz);\n        for (auto& e : edges) {\n            if (uf.unite(e.idx_i, e.idx_j)) {\n                ans[g].push_back(make_pair(e.city_i, e.city_j));\n                if ((int)ans[g].size() == sz - 1) break;\n            }\n        }\n    }\n    \n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        for (int i = 0; i < (int)groups[g].size(); i++) {\n            if (i > 0) cout << \" \";\n            cout << groups[g][i];\n        }\n        cout << endl;\n        for (auto& e : ans[g]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\npair<int, int> slide_end(int r, int c, int d, const vector<vector<bool>>& blocks) {\n    while (true) {\n        int nr = r + dr[d], nc = c + dc[d];\n        if (nr < 0 || nr >= N || nc < 0 || nc >= N || blocks[nr][nc]) return {r, c};\n        r = nr; c = nc;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M;\n    vector<pair<int, int>> targets(M);\n    for (int i = 0; i < M; i++) cin >> targets[i].first >> targets[i].second;\n    \n    set<pair<int,int>> target_set(targets.begin(), targets.end());\n    vector<vector<bool>> blocks(N, vector<bool>(N, false));\n    int cr = targets[0].first, cc = targets[0].second;\n    vector<pair<char, char>> actions;\n    \n    for (int t = 1; t < M; t++) {\n        int tr = targets[t].first, tc = targets[t].second;\n        int sr = cr, sc = cc;\n        bool found = false;\n        \n        // Try Move-Alter-Slide (3 actions)\n        for (int md = 0; md < 4 && !found; md++) {\n            int mr = cr + dr[md], mc = cc + dc[md];\n            if (mr < 0 || mr >= N || mc < 0 || mc >= N || blocks[mr][mc]) continue;\n            for (int ad = 0; ad < 4 && !found; ad++) {\n                int br = mr + dr[ad], bc = mc + dc[ad];\n                if (br < 0 || br >= N || bc < 0 || bc >= N || blocks[br][bc]) continue;\n                if (target_set.count({br, bc})) continue;\n                blocks[br][bc] = true;\n                for (int sd = 0; sd < 4 && !found; sd++) {\n                    auto [nr, nc] = slide_end(mr, mc, sd, blocks);\n                    if (nr == tr && nc == tc) {\n                        actions.push_back({'M', dir_char[md]});\n                        actions.push_back({'A', dir_char[ad]});\n                        actions.push_back({'S', dir_char[sd]});\n                        cr = tr; cc = tc; found = true;\n                    }\n                }\n                if (!found) blocks[br][bc] = false;\n            }\n        }\n        if (found) continue;\n        \n        // Try Alter-Move-Slide (3 actions)\n        for (int ad = 0; ad < 4 && !found; ad++) {\n            int br = cr + dr[ad], bc = cc + dc[ad];\n            if (br < 0 || br >= N || bc < 0 || bc >= N || blocks[br][bc]) continue;\n            if (target_set.count({br, bc})) continue;\n            blocks[br][bc] = true;\n            for (int md = 0; md < 4 && !found; md++) {\n                int mr = cr + dr[md], mc = cc + dc[md];\n                if (mr < 0 || mr >= N || mc < 0 || mc >= N || blocks[mr][mc]) continue;\n                for (int sd = 0; sd < 4 && !found; sd++) {\n                    auto [nr, nc] = slide_end(mr, mc, sd, blocks);\n                    if (nr == tr && nc == tc) {\n                        actions.push_back({'A', dir_char[ad]});\n                        actions.push_back({'M', dir_char[md]});\n                        actions.push_back({'S', dir_char[sd]});\n                        cr = tr; cc = tc; found = true;\n                    }\n                }\n            }\n            if (!found) blocks[br][bc] = false;\n        }\n        if (found) continue;\n        \n        // Try Slide-Alter-Slide (3 actions)\n        for (int s1d = 0; s1d < 4 && !found; s1d++) {\n            auto [s1r, s1c] = slide_end(cr, cc, s1d, blocks);\n            if (s1r == cr && s1c == cc) continue;\n            for (int ad = 0; ad < 4 && !found; ad++) {\n                int br = s1r + dr[ad], bc = s1c + dc[ad];\n                if (br < 0 || br >= N || bc < 0 || bc >= N || blocks[br][bc]) continue;\n                if (target_set.count({br, bc})) continue;\n                blocks[br][bc] = true;\n                for (int s2d = 0; s2d < 4 && !found; s2d++) {\n                    auto [nr, nc] = slide_end(s1r, s1c, s2d, blocks);\n                    if (nr == tr && nc == tc) {\n                        actions.push_back({'S', dir_char[s1d]});\n                        actions.push_back({'A', dir_char[ad]});\n                        actions.push_back({'S', dir_char[s2d]});\n                        cr = tr; cc = tc; found = true;\n                    }\n                }\n                if (!found) blocks[br][bc] = false;\n            }\n        }\n        if (found) continue;\n        \n        // Try Move-Move-Alter-Slide (4 actions)\n        for (int m1d = 0; m1d < 4 && !found; m1d++) {\n            int m1r = cr + dr[m1d], m1c = cc + dc[m1d];\n            if (m1r < 0 || m1r >= N || m1c < 0 || m1c >= N || blocks[m1r][m1c]) continue;\n            for (int m2d = 0; m2d < 4 && !found; m2d++) {\n                int m2r = m1r + dr[m2d], m2c = m1c + dc[m2d];\n                if (m2r < 0 || m2r >= N || m2c < 0 || m2c >= N || blocks[m2r][m2c]) continue;\n                for (int ad = 0; ad < 4 && !found; ad++) {\n                    int br = m2r + dr[ad], bc = m2c + dc[ad];\n                    if (br < 0 || br >= N || bc < 0 || bc >= N || blocks[br][bc]) continue;\n                    if (target_set.count({br, bc})) continue;\n                    blocks[br][bc] = true;\n                    for (int sd = 0; sd < 4 && !found; sd++) {\n                        auto [nr, nc] = slide_end(m2r, m2c, sd, blocks);\n                        if (nr == tr && nc == tc) {\n                            actions.push_back({'M', dir_char[m1d]});\n                            actions.push_back({'M', dir_char[m2d]});\n                            actions.push_back({'A', dir_char[ad]});\n                            actions.push_back({'S', dir_char[sd]});\n                            cr = tr; cc = tc; found = true;\n                        }\n                    }\n                    if (!found) blocks[br][bc] = false;\n                }\n            }\n        }\n        if (found) continue;\n        \n        // Try Move-Alter-Move-Slide (4 actions)\n        for (int m1d = 0; m1d < 4 && !found; m1d++) {\n            int m1r = cr + dr[m1d], m1c = cc + dc[m1d];\n            if (m1r < 0 || m1r >= N || m1c < 0 || m1c >= N || blocks[m1r][m1c]) continue;\n            for (int ad = 0; ad < 4 && !found; ad++) {\n                int br = m1r + dr[ad], bc = m1c + dc[ad];\n                if (br < 0 || br >= N || bc < 0 || bc >= N || blocks[br][bc]) continue;\n                if (target_set.count({br, bc})) continue;\n                blocks[br][bc] = true;\n                for (int m2d = 0; m2d < 4 && !found; m2d++) {\n                    int m2r = m1r + dr[m2d], m2c = m1c + dc[m2d];\n                    if (m2r < 0 || m2r >= N || m2c < 0 || m2c >= N || blocks[m2r][m2c]) continue;\n                    for (int sd = 0; sd < 4 && !found; sd++) {\n                        auto [nr, nc] = slide_end(m2r, m2c, sd, blocks);\n                        if (nr == tr && nc == tc) {\n                            actions.push_back({'M', dir_char[m1d]});\n                            actions.push_back({'A', dir_char[ad]});\n                            actions.push_back({'M', dir_char[m2d]});\n                            actions.push_back({'S', dir_char[sd]});\n                            cr = tr; cc = tc; found = true;\n                        }\n                    }\n                }\n                if (!found) blocks[br][bc] = false;\n            }\n        }\n        if (found) continue;\n        \n        // Try Slide-Move-Alter-Slide (4 actions)\n        for (int s1d = 0; s1d < 4 && !found; s1d++) {\n            auto [s1r, s1c] = slide_end(cr, cc, s1d, blocks);\n            if (s1r == cr && s1c == cc) continue;\n            for (int md = 0; md < 4 && !found; md++) {\n                int mr = s1r + dr[md], mc = s1c + dc[md];\n                if (mr < 0 || mr >= N || mc < 0 || mc >= N || blocks[mr][mc]) continue;\n                for (int ad = 0; ad < 4 && !found; ad++) {\n                    int br = mr + dr[ad], bc = mc + dc[ad];\n                    if (br < 0 || br >= N || bc < 0 || bc >= N || blocks[br][bc]) continue;\n                    if (target_set.count({br, bc})) continue;\n                    blocks[br][bc] = true;\n                    for (int s2d = 0; s2d < 4 && !found; s2d++) {\n                        auto [nr, nc] = slide_end(mr, mc, s2d, blocks);\n                        if (nr == tr && nc == tc) {\n                            actions.push_back({'S', dir_char[s1d]});\n                            actions.push_back({'M', dir_char[md]});\n                            actions.push_back({'A', dir_char[ad]});\n                            actions.push_back({'S', dir_char[s2d]});\n                            cr = tr; cc = tc; found = true;\n                        }\n                    }\n                    if (!found) blocks[br][bc] = false;\n                }\n            }\n        }\n        if (found) continue;\n        \n        // Try Move-Move-Move-Alter-Slide (5 actions)\n        for (int m1d = 0; m1d < 4 && !found; m1d++) {\n            int m1r = cr + dr[m1d], m1c = cc + dc[m1d];\n            if (m1r < 0 || m1r >= N || m1c < 0 || m1c >= N || blocks[m1r][m1c]) continue;\n            for (int m2d = 0; m2d < 4 && !found; m2d++) {\n                int m2r = m1r + dr[m2d], m2c = m1c + dc[m2d];\n                if (m2r < 0 || m2r >= N || m2c < 0 || m2c >= N || blocks[m2r][m2c]) continue;\n                for (int m3d = 0; m3d < 4 && !found; m3d++) {\n                    int m3r = m2r + dr[m3d], m3c = m2c + dc[m3d];\n                    if (m3r < 0 || m3r >= N || m3c < 0 || m3c >= N || blocks[m3r][m3c]) continue;\n                    for (int ad = 0; ad < 4 && !found; ad++) {\n                        int br = m3r + dr[ad], bc = m3c + dc[ad];\n                        if (br < 0 || br >= N || bc < 0 || bc >= N || blocks[br][bc]) continue;\n                        if (target_set.count({br, bc})) continue;\n                        blocks[br][bc] = true;\n                        for (int sd = 0; sd < 4 && !found; sd++) {\n                            auto [nr, nc] = slide_end(m3r, m3c, sd, blocks);\n                            if (nr == tr && nc == tc) {\n                                actions.push_back({'M', dir_char[m1d]});\n                                actions.push_back({'M', dir_char[m2d]});\n                                actions.push_back({'M', dir_char[m3d]});\n                                actions.push_back({'A', dir_char[ad]});\n                                actions.push_back({'S', dir_char[sd]});\n                                cr = tr; cc = tc; found = true;\n                            }\n                        }\n                        if (!found) blocks[br][bc] = false;\n                    }\n                }\n            }\n        }\n        if (found) continue;\n        \n        // Standard BFS\n        vector<vector<int>> dist(N, vector<int>(N, -1));\n        vector<vector<array<int,4>>> prev(N, vector<array<int,4>>(N, {-1,-1,0,0}));\n        queue<pair<int,int>> q;\n        q.push({cr, cc});\n        dist[cr][cc] = 0;\n        \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 && !blocks[nr][nc] && dist[nr][nc] == -1) {\n                    dist[nr][nc] = dist[r][c] + 1;\n                    prev[nr][nc] = {r, c, int('M'), d};\n                    q.push({nr, nc});\n                }\n            }\n            for (int d = 0; d < 4; d++) {\n                auto [nr, nc] = slide_end(r, c, d, blocks);\n                if (dist[nr][nc] == -1) {\n                    dist[nr][nc] = dist[r][c] + 1;\n                    prev[nr][nc] = {r, c, int('S'), d};\n                    q.push({nr, nc});\n                }\n            }\n        }\n        \n        vector<pair<char,char>> path;\n        int cur_r = tr, cur_c = tc;\n        while (cur_r != sr || cur_c != sc) {\n            auto [pr, pc, a, d] = prev[cur_r][cur_c];\n            path.push_back({char(a), dir_char[d]});\n            cur_r = pr; cur_c = pc;\n        }\n        reverse(path.begin(), path.end());\n        \n        for (auto [a, d] : path) {\n            actions.push_back({a, d});\n            int di = 0;\n            for (int i = 0; i < 4; i++) if (dir_char[i] == d) di = i;\n            if (a == 'M') { cr += dr[di]; cc += dc[di]; }\n            else if (a == 'S') tie(cr, cc) = slide_end(cr, cc, di, blocks);\n        }\n    }\n    \n    for (auto [a, d] : actions) cout << a << ' ' << d << '\\n';\n    return 0;\n}"}}}