{"model_name":"glm-5.1","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> x, y, r;\nvector<int> a, b, c, d;\n\nvoid solve(vector<int> indices, int left, int bottom, int right, int top) {\n    if (indices.empty()) return;\n    if (indices.size() == 1) {\n        int i = indices[0];\n        a[i] = left; b[i] = bottom; c[i] = right; d[i] = top;\n        return;\n    }\n    \n    long long total_r = 0;\n    for (int i : indices) total_r += r[i];\n    \n    int width = right - left;\n    int height = top - bottom;\n    \n    double best_score = 1e18;\n    bool use_vertical = true;\n    int best_k = -1;\n    int best_split = -1;\n    \n    // Try vertical splits\n    {\n        sort(indices.begin(), indices.end(), [](int i, int j) { return x[i] < x[j]; });\n        long long sum = 0;\n        for (int k = 1; k < (int)indices.size(); k++) {\n            sum += r[indices[k-1]];\n            if (x[indices[k-1]] >= x[indices[k]]) continue;\n            \n            int min_s = max(left + 1, x[indices[k-1]] + 1);\n            int max_s = min(right - 1, x[indices[k]]);\n            if (min_s > max_s) continue;\n            \n            long long ideal_s = left + (long long)width * sum / total_r;\n            int s = max(min_s, min(max_s, (int)ideal_s));\n            \n            double score = abs((double)sum / total_r - (double)(s - left) / width);\n            if (score < best_score) {\n                best_score = score;\n                use_vertical = true;\n                best_k = k;\n                best_split = s;\n            }\n        }\n    }\n    \n    // Try horizontal splits\n    {\n        sort(indices.begin(), indices.end(), [](int i, int j) { return y[i] < y[j]; });\n        long long sum = 0;\n        for (int k = 1; k < (int)indices.size(); k++) {\n            sum += r[indices[k-1]];\n            if (y[indices[k-1]] >= y[indices[k]]) continue;\n            \n            int min_s = max(bottom + 1, y[indices[k-1]] + 1);\n            int max_s = min(top - 1, y[indices[k]]);\n            if (min_s > max_s) continue;\n            \n            long long ideal_s = bottom + (long long)height * sum / total_r;\n            int s = max(min_s, min(max_s, (int)ideal_s));\n            \n            double score = abs((double)sum / total_r - (double)(s - bottom) / height);\n            if (score < best_score) {\n                best_score = score;\n                use_vertical = false;\n                best_k = k;\n                best_split = s;\n            }\n        }\n    }\n    \n    if (best_k == -1) {\n        int i = indices[0];\n        a[i] = left; b[i] = bottom; c[i] = right; d[i] = top;\n        return;\n    }\n    \n    if (use_vertical) {\n        sort(indices.begin(), indices.end(), [](int i, int j) { return x[i] < x[j]; });\n        vector<int> left_indices(indices.begin(), indices.begin() + best_k);\n        vector<int> right_indices(indices.begin() + best_k, indices.end());\n        solve(left_indices, left, bottom, best_split, top);\n        solve(right_indices, best_split, bottom, right, top);\n    } else {\n        sort(indices.begin(), indices.end(), [](int i, int j) { return y[i] < y[j]; });\n        vector<int> bottom_indices(indices.begin(), indices.begin() + best_k);\n        vector<int> top_indices(indices.begin() + best_k, indices.end());\n        solve(bottom_indices, left, bottom, right, best_split);\n        solve(top_indices, left, best_split, right, top);\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> indices(n);\n    iota(indices.begin(), indices.end(), 0);\n    \n    solve(indices, 0, 0, 10000, 10000);\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 <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 50;\nint si, sj;\nint t[N][N], p[N][N];\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir[] = {'U', 'D', 'L', 'R'};\nmt19937 rng(42);\n\nint tile_value[2500], max_tile_id = 0;\nstring best_path;\nlong long best_score;\n\nstring find_path(double temperature) {\n    bool square_visited[N][N] = {};\n    bool tile_visited[2500] = {};\n    string path;\n    int ci = si, cj = sj;\n    square_visited[ci][cj] = true;\n    tile_visited[t[ci][cj]] = true;\n    long long score = p[ci][cj];\n    \n    while (true) {\n        vector<pair<double, int>> candidates;\n        for (int d = 0; d < 4; d++) {\n            int ni = ci + di[d], nj = cj + dj[d];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (square_visited[ni][nj]) continue;\n            bool same_tile = (t[ni][nj] == t[ci][cj]);\n            if (same_tile || !tile_visited[t[ni][nj]]) {\n                double w = same_tile ? p[ni][nj] : tile_value[t[ni][nj]];\n                candidates.push_back({w, d});\n            }\n        }\n        if (candidates.empty()) break;\n        \n        double max_w = -1e18;\n        for (auto& [w, d] : candidates) max_w = max(max_w, w);\n        double total = 0;\n        for (auto& [w, d] : candidates) total += exp((w - max_w) / max(temperature, 0.01));\n        \n        double r = uniform_real_distribution<double>(0, total)(rng);\n        double cum = 0;\n        int chosen = candidates[0].second;\n        for (auto& [w, d] : candidates) {\n            cum += exp((w - max_w) / max(temperature, 0.01));\n            if (cum >= r) { chosen = d; break; }\n        }\n        \n        int ni = ci + di[chosen], nj = cj + dj[chosen];\n        square_visited[ni][nj] = true;\n        tile_visited[t[ni][nj]] = true;\n        score += p[ni][nj];\n        path += dir[chosen];\n        ci = ni; cj = nj;\n    }\n    \n    if (score > best_score) { best_score = score; best_path = path; }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> si >> sj;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) { cin >> t[i][j]; max_tile_id = max(max_tile_id, t[i][j]); }\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> p[i][j];\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) tile_value[t[i][j]] += p[i][j];\n    \n    best_score = 0;\n    auto start = chrono::high_resolution_clock::now();\n    int iter = 0;\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 1800) break;\n        double temperature = 10.0 * (1.0 - min(iter / 100000.0, 1.0)) + 0.1;\n        find_path(temperature);\n        iter++;\n    }\n    \n    cout << best_path << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\ndouble h_est[N][N-1], v_est[N-1][N];\nint h_count[N][N-1], v_count[N-1][N];\nint query_num = 0;\n\ndouble get_h_weight(int i, int j) {\n    double base = h_est[i][j];\n    double time_decay = max(0.0, 1.0 - query_num / 400.0);\n    double exploration = 80.0 * time_decay / sqrt(h_count[i][j] + 1);\n    return max(100.0, base - exploration);\n}\n\ndouble get_v_weight(int i, int j) {\n    double base = v_est[i][j];\n    double time_decay = max(0.0, 1.0 - query_num / 400.0);\n    double exploration = 80.0 * time_decay / sqrt(v_count[i][j] + 1);\n    return max(100.0, base - exploration);\n}\n\nstring dijkstra(int si, int sj, int ti, int tj) {\n    double dist[N][N]; pair<int,int> prev[N][N]; bool vis[N][N] = {};\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) dist[i][j] = 1e18;\n    dist[si][sj] = 0;\n    priority_queue<tuple<double,int,int>, vector<tuple<double,int,int>>, greater<>> pq;\n    pq.push({0, si, sj});\n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top(); pq.pop();\n        if (vis[i][j]) continue; vis[i][j] = true;\n        if (i == ti && j == tj) break;\n        if (i > 0 && !vis[i-1][j] && d + get_v_weight(i-1,j) < dist[i-1][j])\n            { dist[i-1][j] = d + get_v_weight(i-1,j); prev[i-1][j] = {i,j}; pq.push({dist[i-1][j],i-1,j}); }\n        if (i < N-1 && !vis[i+1][j] && d + get_v_weight(i,j) < dist[i+1][j])\n            { dist[i+1][j] = d + get_v_weight(i,j); prev[i+1][j] = {i,j}; pq.push({dist[i+1][j],i+1,j}); }\n        if (j > 0 && !vis[i][j-1] && d + get_h_weight(i,j-1) < dist[i][j-1])\n            { dist[i][j-1] = d + get_h_weight(i,j-1); prev[i][j-1] = {i,j}; pq.push({dist[i][j-1],i,j-1}); }\n        if (j < N-1 && !vis[i][j+1] && d + get_h_weight(i,j) < dist[i][j+1])\n            { dist[i][j+1] = d + get_h_weight(i,j); prev[i][j+1] = {i,j}; pq.push({dist[i][j+1],i,j+1}); }\n    }\n    string path; int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        auto [pi, pj] = prev[ci][cj];\n        if (pi == ci-1) path += 'D'; else if (pi == ci+1) path += 'U';\n        else if (pj == cj-1) path += 'R'; else path += 'L';\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvoid update(int si, int sj, const string& path, int observed) {\n    vector<pair<char,pair<int,int>>> edges;\n    int ci = si, cj = sj;\n    for (char c : path) {\n        if (c == 'U') { edges.push_back({'v',{ci-1,cj}}); ci--; }\n        else if (c == 'D') { edges.push_back({'v',{ci,cj}}); ci++; }\n        else if (c == 'L') { edges.push_back({'h',{ci,cj-1}}); cj--; }\n        else { edges.push_back({'h',{ci,cj}}); cj++; }\n    }\n    double pred = 0;\n    for (auto& [type, pos] : edges) {\n        auto [i, j] = pos;\n        pred += (type == 'h') ? h_est[i][j] : v_est[i][j];\n    }\n    double ratio = (double)observed / pred;\n    for (auto& [type, pos] : edges) {\n        auto [i, j] = pos;\n        if (type == 'h') {\n            double lr = 1.0 / (2 + h_count[i][j]++);\n            h_est[i][j] = max(100.0, min(20000.0, h_est[i][j] * ((1-lr) + lr*ratio)));\n        } else {\n            double lr = 1.0 / (2 + v_count[i][j]++);\n            v_est[i][j] = max(100.0, min(20000.0, v_est[i][j] * ((1-lr) + lr*ratio)));\n        }\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_est[i][j] = 5000.0; h_count[i][j] = 0; }\n    for (int i = 0; i < N-1; i++) for (int j = 0; j < N; j++) { v_est[i][j] = 5000.0; v_count[i][j] = 0; }\n    for (int k = 0; k < 1000; k++) {\n        query_num = k;\n        int si, sj, ti, tj; cin >> si >> sj >> ti >> tj;\n        string path = dijkstra(si, sj, ti, tj);\n        cout << path << endl;\n        int obs; cin >> obs;\n        update(si, sj, path, obs);\n    }\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for (int i = 0; i < M; i++) cin >> s[i];\n    \n    const int NUM_CHARS = 8;\n    mt19937 rng(42);\n    \n    // Initialize with uniform voting\n    vector<vector<double>> votes(N * N, vector<double>(NUM_CHARS, 0));\n    for (int m = 0; m < M; m++) {\n        int k = s[m].length();\n        double weight = 1.0 / (2.0 * N * N);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                for (int p = 0; p < k; p++) {\n                    votes[i * N + (j + p) % N][s[m][p] - 'A'] += weight;\n                    votes[((i + p) % N) * N + j][s[m][p] - 'A'] += weight;\n                }\n            }\n        }\n    }\n    \n    vector<string> mat(N, string(N, 'A'));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            double maxVote = 0;\n            char bestChar = 'A';\n            for (int c = 0; c < NUM_CHARS; c++) {\n                if (votes[i * N + j][c] > maxVote) {\n                    maxVote = votes[i * N + j][c];\n                    bestChar = 'A' + c;\n                }\n            }\n            mat[i][j] = bestChar;\n        }\n    }\n    \n    // Iterative refinement with weighted voting\n    for (int iter = 0; iter < 100; iter++) {\n        vector<vector<double>> newVotes(N * N, vector<double>(NUM_CHARS, 0));\n        \n        for (int m = 0; m < M; m++) {\n            int k = s[m].length();\n            \n            double totalScore = 0;\n            vector<double> scores(2 * N * N);\n            int idx = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    double scoreH = 0, scoreV = 0;\n                    for (int p = 0; p < k; p++) {\n                        if (mat[i][(j + p) % N] == s[m][p]) scoreH += 1;\n                        if (mat[(i + p) % N][j] == s[m][p]) scoreV += 1;\n                    }\n                    scores[idx++] = scoreH;\n                    scores[idx++] = scoreV;\n                    totalScore += scoreH + scoreV;\n                }\n            }\n            \n            if (totalScore < 0.01) continue;\n            \n            idx = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    double wH = scores[idx++] / totalScore;\n                    double wV = scores[idx++] / totalScore;\n                    \n                    for (int p = 0; p < k; p++) {\n                        newVotes[i * N + (j + p) % N][s[m][p] - 'A'] += wH;\n                        newVotes[((i + p) % N) * N + j][s[m][p] - 'A'] += wV;\n                    }\n                }\n            }\n        }\n        \n        bool changed = false;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                double maxVote = 0;\n                char bestChar = mat[i][j];\n                for (int c = 0; c < NUM_CHARS; c++) {\n                    if (newVotes[i * N + j][c] > maxVote) {\n                        maxVote = newVotes[i * N + j][c];\n                        bestChar = 'A' + c;\n                    }\n                }\n                if (mat[i][j] != bestChar) {\n                    mat[i][j] = bestChar;\n                    changed = true;\n                }\n            }\n        }\n        \n        if (!changed) break;\n    }\n    \n    for (int i = 0; i < N; i++) cout << mat[i] << '\\n';\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\n\nbool is_road(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\nint cost(int i, int j) { return grid[i][j] - '0'; }\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dir[] = {'U', 'D', 'L', 'R'};\n\nint char_to_idx(char c) {\n    if (c == 'U') return 0;\n    if (c == 'D') return 1;\n    if (c == 'L') return 2;\n    return 3;\n}\n\npair<vector<vector<int>>, vector<vector<int>>> dijkstra(int si, int sj) {\n    vector<vector<int>> dist(N, vector<int>(N, INT_MAX));\n    vector<vector<int>> prev(N, vector<int>(N, -1));\n    priority_queue<pair<int,pair<int,int>>, vector<pair<int,pair<int,int>>>, greater<>> pq;\n    dist[si][sj] = 0;\n    pq.push({0, {si, sj}});\n    while (!pq.empty()) {\n        auto [d, p] = pq.top(); pq.pop();\n        auto [i, j] = p;\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 (is_road(ni, nj)) {\n                int nd = d + cost(ni, nj);\n                if (nd < dist[ni][nj]) {\n                    dist[ni][nj] = nd;\n                    prev[ni][nj] = k;\n                    pq.push({nd, {ni, nj}});\n                }\n            }\n        }\n    }\n    return {dist, prev};\n}\n\nstring reconstruct_path(int si, int sj, int ti, int tj, const vector<vector<int>>& prev) {\n    if (si == ti && sj == tj) return \"\";\n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int k = prev[ci][cj];\n        if (k == -1) return \"\";\n        path += dir[k];\n        ci -= di[k]; cj -= dj[k];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nint mark_new_visible(int i, int j, vector<vector<bool>>& covered) {\n    int count = 0;\n    if (!covered[i][j]) { covered[i][j] = true; count++; }\n    for (int jj = j-1; jj >= 0 && is_road(i,jj); jj--)\n        if (!covered[i][jj]) { covered[i][jj] = true; count++; }\n    for (int jj = j+1; jj < N && is_road(i,jj); jj++)\n        if (!covered[i][jj]) { covered[i][jj] = true; count++; }\n    for (int ii = i-1; ii >= 0 && is_road(ii,j); ii--)\n        if (!covered[ii][j]) { covered[ii][j] = true; count++; }\n    for (int ii = i+1; ii < N && is_road(ii,j); ii++)\n        if (!covered[ii][j]) { covered[ii][j] = true; count++; }\n    return count;\n}\n\nint count_new_visible(int i, int j, const vector<vector<bool>>& covered) {\n    int count = 0;\n    if (!covered[i][j]) count++;\n    for (int jj = j-1; jj >= 0 && is_road(i,jj); jj--)\n        if (!covered[i][jj]) count++;\n    for (int jj = j+1; jj < N && is_road(i,jj); jj++)\n        if (!covered[i][jj]) count++;\n    for (int ii = i-1; ii >= 0 && is_road(ii,j); ii--)\n        if (!covered[ii][j]) count++;\n    for (int ii = i+1; ii < N && is_road(ii,j); ii++)\n        if (!covered[ii][j]) count++;\n    return count;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    int total_roads = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (is_road(i, j)) total_roads++;\n    \n    vector<vector<bool>> covered(N, vector<bool>(N, false));\n    string route;\n    int ci = si, cj = sj;\n    int covered_count = mark_new_visible(ci, cj, covered);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    \n    while (covered_count < total_roads) {\n        auto current_time = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count() > 2500) break;\n        \n        auto [dist, prev] = dijkstra(ci, cj);\n        int best_i = -1, best_j = -1;\n        double best_score = -1;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (!is_road(i, j) || dist[i][j] == INT_MAX) continue;\n                int new_vis = count_new_visible(i, j, covered);\n                if (new_vis == 0) continue;\n                double score = (double)new_vis / dist[i][j];\n                if (score > best_score) {\n                    best_score = score;\n                    best_i = i; best_j = j;\n                }\n            }\n        }\n        \n        if (best_i == -1) break;\n        \n        string path = reconstruct_path(ci, cj, best_i, best_j, prev);\n        for (char c : path) {\n            int k = char_to_idx(c);\n            ci += di[k]; cj += dj[k];\n            covered_count += mark_new_visible(ci, cj, covered);\n        }\n        route += path;\n    }\n    \n    auto [dist, prev] = dijkstra(ci, cj);\n    route += reconstruct_path(ci, cj, si, sj, prev);\n    \n    cout << route << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> d, deps, rev_deps;\nvector<vector<double>> skill_est, est_time_matrix;\nvector<vector<int>> skill_lb;\n\nvoid update_skills_for_member(int j) {\n    for (int i = 0; i < N; i++) {\n        double w = 0;\n        for (int k = 0; k < K; k++) w += max(0.0, (double)d[i][k] - skill_est[j][k]);\n        est_time_matrix[i][j] = max(1.0, w);\n    }\n}\n\nvoid update_skills(int j, int task, int time_taken) {\n    if (time_taken == 1) {\n        for (int k = 0; k < K; k++) {\n            skill_lb[j][k] = max(skill_lb[j][k], d[task][k]);\n            skill_est[j][k] = max(skill_est[j][k], (double)d[task][k]);\n        }\n    } else {\n        double est_w = (double)time_taken, cur_w = 0;\n        vector<int> deficient;\n        for (int k = 0; k < K; k++) {\n            double deficit = max(0.0, (double)d[task][k] - skill_est[j][k]);\n            if (deficit > 0) { cur_w += deficit; deficient.push_back(k); }\n        }\n        if (cur_w > 0) {\n            double ratio = est_w / cur_w;\n            for (int k : deficient) {\n                double deficit = d[task][k] - skill_est[j][k];\n                double new_skill = d[task][k] - deficit * ratio;\n                skill_est[j][k] = 0.7 * skill_est[j][k] + 0.3 * new_skill;\n                skill_est[j][k] = max((double)skill_lb[j][k], skill_est[j][k]);\n            }\n        } else {\n            double total_d = 0;\n            for (int k = 0; k < K; k++) total_d += d[task][k];\n            if (total_d > 0) for (int k = 0; k < K; k++)\n                skill_est[j][k] = max((double)skill_lb[j][k], skill_est[j][k] - est_w * d[task][k] / total_d);\n        }\n    }\n    update_skills_for_member(j);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> K >> R;\n    d.resize(N, vector<int>(K)); deps.resize(N); rev_deps.resize(N);\n    for (int i = 0; i < N; i++) for (int k = 0; k < K; k++) cin >> d[i][k];\n    for (int r = 0; r < R; r++) { int u, v; cin >> u >> v; u--; v--; deps[v].push_back(u); rev_deps[u].push_back(v); }\n    \n    vector<int> downstream(N, 0);\n    for (int i = N - 1; i >= 0; i--) for (int v : rev_deps[i]) downstream[i] += downstream[v] + 1;\n    \n    skill_est.resize(M, vector<double>(K, 30.0)); skill_lb.resize(M, vector<int>(K, 0));\n    est_time_matrix.resize(N, vector<double>(M, 1.0));\n    for (int j = 0; j < M; j++) update_skills_for_member(j);\n    \n    vector<int> task_start(N, -1), task_done(N, -1), member_task(M, -1), member_start_day(M, -1);\n    set<int> available_tasks; vector<int> deps_remaining(N);\n    for (int i = 0; i < N; i++) { deps_remaining[i] = deps[i].size(); if (!deps_remaining[i]) available_tasks.insert(i); }\n    \n    int current_day = 0;\n    while (true) {\n        current_day++;\n        vector<int> free_members;\n        for (int j = 0; j < M; j++) if (member_task[j] == -1) free_members.push_back(j);\n        \n        vector<pair<int,int>> assignments; set<int> used_members, used_tasks;\n        vector<int> sorted_avail(available_tasks.begin(), available_tasks.end());\n        sort(sorted_avail.begin(), sorted_avail.end(), [&](int a, int b) { return downstream[a] > downstream[b]; });\n        \n        for (int i : sorted_avail) {\n            if (used_members.size() >= free_members.size()) break;\n            double best_time = 1e18; int best_j = -1;\n            for (int j : free_members) if (!used_members.count(j) && est_time_matrix[i][j] < best_time)\n                { best_time = est_time_matrix[i][j]; best_j = j; }\n            if (best_j != -1) { assignments.push_back({best_j, i}); used_members.insert(best_j); used_tasks.insert(i); }\n        }\n        \n        cout << assignments.size();\n        for (auto [j, i] : assignments) {\n            cout << \" \" << (j+1) << \" \" << (i+1);\n            member_task[j] = i; member_start_day[j] = current_day; task_start[i] = current_day;\n            available_tasks.erase(i);\n        }\n        cout << endl;\n        \n        int n; cin >> n; if (n == -1) break;\n        for (int idx = 0; idx < n; idx++) {\n            int j; cin >> j; j--;\n            int i = member_task[j], time_taken = current_day - member_start_day[j] + 1;\n            task_done[i] = current_day; update_skills(j, i, time_taken); member_task[j] = -1;\n            for (int v : rev_deps[i]) { deps_remaining[v]--; if (!deps_remaining[v] && task_start[v] == -1) available_tasks.insert(v); }\n        }\n    }\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <climits>\n\nusing namespace std;\n\nconst int N = 1000, M = 50, CX = 400, CY = 400;\nint a[N], b[N], c[N], d[N];\n\nint dist(int x1, int y1, int x2, int y2) { return abs(x1-x2) + abs(y1-y2); }\n\nint main() {\n    for (int i = 0; i < N; i++) cin >> a[i] >> b[i] >> c[i] >> d[i];\n    \n    auto startTime = chrono::high_resolution_clock::now();\n    mt19937 rng(42);\n    \n    vector<pair<int,int>> scores;\n    for (int i = 0; i < N; i++) {\n        int cost = dist(CX,CY,a[i],b[i]) + dist(a[i],b[i],c[i],d[i]) + dist(c[i],d[i],CX,CY);\n        scores.push_back({cost, i});\n    }\n    sort(scores.begin(), scores.end());\n    \n    vector<int> orders(M);\n    vector<bool> isSelected(N, false);\n    for (int i = 0; i < M; i++) { orders[i] = scores[i].second; isSelected[orders[i]] = true; }\n    \n    vector<int> route(2*M);\n    \n    auto constructRoute = [&]() {\n        vector<bool> vR(M,false), vD(M,false);\n        int cx=CX, cy=CY;\n        for (int step=0; step<2*M; step++) {\n            int best=-1, bestD=INT_MAX;\n            for (int i=0; i<M; i++) {\n                if (!vR[i]) { int d2=dist(cx,cy,a[orders[i]],b[orders[i]]); if(d2<bestD){bestD=d2;best=i*2;} }\n                if (vR[i]&&!vD[i]) { int d2=dist(cx,cy,c[orders[i]],d[orders[i]]); if(d2<bestD){bestD=d2;best=i*2+1;} }\n            }\n            route[step]=best;\n            if (best%2==0) { vR[best/2]=true; cx=a[orders[best/2]]; cy=b[orders[best/2]]; }\n            else { vD[best/2]=true; cx=c[orders[best/2]]; cy=d[orders[best/2]]; }\n        }\n    };\n    \n    auto calcCost = [&]() {\n        int cost=0, x=CX, y=CY;\n        for (int i=0; i<2*M; i++) {\n            int ord=orders[route[i]/2]; bool isD=route[i]%2;\n            int nx=isD?c[ord]:a[ord], ny=isD?d[ord]:b[ord];\n            cost+=dist(x,y,nx,ny); x=nx; y=ny;\n        }\n        return cost+dist(x,y,CX,CY);\n    };\n    \n    auto isValid = [](const vector<int>& r) {\n        vector<int> rP(M), dP(M);\n        for (int i=0; i<2*M; i++) { if(r[i]%2==0) rP[r[i]/2]=i; else dP[r[i]/2]=i; }\n        for (int k=0; k<M; k++) if(rP[k]>dP[k]) return false;\n        return true;\n    };\n    \n    constructRoute();\n    int curCost=calcCost(), bestCost=curCost;\n    vector<int> bestRoute=route, bestOrders=orders;\n    double temp=500.0, cooling=0.99997;\n    \n    while (true) {\n        auto now=chrono::high_resolution_clock::now();\n        if (chrono::duration<double>(now-startTime).count()>1.8) break;\n        \n        int mt=rng()%10;\n        if (mt<5) {\n            int from=rng()%(2*M), to=rng()%(2*M);\n            if(from==to) continue;\n            vector<int> nr=route; int val=nr[from];\n            nr.erase(nr.begin()+from);\n            int ip=to>from?to-1:to;\n            nr.insert(nr.begin()+ip, val);\n            if(isValid(nr)) {\n                auto sr=route; route=nr; int nc=calcCost(); double d=nc-curCost;\n                if(d<0||(double)rng()/rng().max()<exp(-d/temp)) { curCost=nc; if(nc<bestCost){bestCost=nc;bestRoute=route;bestOrders=orders;} }\n                else route=sr;\n            }\n        } else if (mt<8) {\n            int ii=rng()%M, oi=rng()%N;\n            if(isSelected[oi]) continue;\n            int oo=orders[ii]; orders[ii]=oi; isSelected[oo]=false; isSelected[oi]=true;\n            constructRoute(); int nc=calcCost(); double d=nc-curCost;\n            if(d<0||(double)rng()/rng().max()<exp(-d/temp)) { curCost=nc; if(nc<bestCost){bestCost=nc;bestRoute=route;bestOrders=orders;} }\n            else { orders[ii]=oo; isSelected[oo]=true; isSelected[oi]=false; constructRoute(); }\n        } else {\n            int l=rng()%(2*M-1), r=l+1+rng()%(2*M-1-l);\n            bool valid=true;\n            for(int i=l;i<=r&&valid;i++) for(int j=i+1;j<=r&&valid;j++) if(route[i]/2==route[j]/2) valid=false;\n            if(valid) {\n                vector<int> nr=route; reverse(nr.begin()+l,nr.begin()+r+1);\n                auto sr=route; route=nr; int nc=calcCost(); double d=nc-curCost;\n                if(d<0||(double)rng()/rng().max()<exp(-d/temp)) { curCost=nc; if(nc<bestCost){bestCost=nc;bestRoute=route;bestOrders=orders;} }\n                else route=sr;\n            }\n        }\n        temp*=cooling;\n    }\n    \n    cout << M;\n    for(int i=0;i<M;i++) cout<<\" \"<<bestOrders[i]+1;\n    cout<<endl;\n    cout<<2*M+2<<\" \"<<CX<<\" \"<<CY;\n    for(int i=0;i<2*M;i++) {\n        int ord=bestOrders[bestRoute[i]/2]; bool isD=bestRoute[i]%2;\n        cout<<\" \"<<(isD?c[ord]:a[ord])<<\" \"<<(isD?d[ord]:b[ord]);\n    }\n    cout<<\" \"<<CX<<\" \"<<CY<<endl;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, rank_;\n    int components;\n    \n    UnionFind(int n) : parent(n), rank_(n, 0), components(n) {\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 (rank_[px] < rank_[py]) swap(px, py);\n        parent[py] = px;\n        if (rank_[px] == rank_[py]) rank_[px]++;\n        components--;\n        return true;\n    }\n    \n    bool connected(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, M = 1995;\n    vector<int> x(N), y(N);\n    vector<int> u(M), v(M);\n    vector<int> d(M);\n    \n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        double dist = sqrt((double)(x[u[i]] - x[v[i]]) * (x[u[i]] - x[v[i]]) + \n                           (double)(y[u[i]] - y[v[i]]) * (y[u[i]] - y[v[i]]));\n        d[i] = max(1, (int)round(dist));\n    }\n    \n    // Compute reference MST using d_i\n    vector<int> order(M);\n    for (int i = 0; i < M; i++) order[i] = i;\n    sort(order.begin(), order.end(), [&](int a, int b) { return d[a] < d[b]; });\n    \n    UnionFind refUF(N);\n    vector<bool> inRefMST(M, false);\n    for (int idx : order) {\n        if (refUF.unite(u[idx], v[idx])) {\n            inRefMST[idx] = true;\n        }\n    }\n    \n    // Process edges online\n    UnionFind uf(N);\n    \n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        int adopt = 0;\n        \n        if (!uf.connected(u[i], v[i])) {\n            double percentile = (double)(l - d[i]) / (2.0 * d[i]);\n            \n            int remaining = M - i - 1;\n            int needed = uf.components - 1;\n            \n            double threshold;\n            if (needed == 0) {\n                threshold = 0;\n            } else {\n                double safety = (double)remaining / needed;\n                if (safety >= 10) {\n                    threshold = 0.4;\n                } else if (safety >= 5) {\n                    threshold = 0.5;\n                } else if (safety >= 3) {\n                    threshold = 0.7;\n                } else if (safety >= 2) {\n                    threshold = 0.85;\n                } else {\n                    threshold = 1.0;\n                }\n            }\n            \n            // Edges in reference MST are more likely to be important\n            if (inRefMST[i]) {\n                threshold = min(1.0, threshold + 0.15);\n            }\n            \n            if (percentile <= threshold) {\n                adopt = 1;\n                uf.unite(u[i], v[i]);\n            }\n        }\n        \n        cout << adopt << endl;\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <cstring>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\n\nint N, M;\nvector<int> px, py, pt;\nvector<int> hx, hy;\nbool wall[SIZE][SIZE];\n\nbool inBounds(int x, int y) { return x >= 0 && x < SIZE && y >= 0 && y < SIZE; }\n\nbool petAdjacentTo(int x, int y, const vector<int>& ppx, const vector<int>& ppy) {\n    for (int i = 0; i < N; i++) {\n        if (ppx[i] == x && ppy[i] == y) return true;\n        for (int d = 0; d < 4; d++)\n            if (ppx[i] == x + dx[d] && ppy[i] == y + dy[d]) return true;\n    }\n    return false;\n}\n\nbool humanAt(int x, int y, const vector<int>& hhx, const vector<int>& hhy) {\n    for (int i = 0; i < M; i++)\n        if (hhx[i] == x && hhy[i] == y) return true;\n    return false;\n}\n\nvoid bfs(int sx, int sy, int dist[SIZE][SIZE]) {\n    memset(dist, -1, sizeof(int) * SIZE * SIZE);\n    queue<pair<int,int>> q;\n    dist[sx][sy] = 0;\n    q.push({sx, sy});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (inBounds(nx, ny) && !wall[nx][ny] && dist[nx][ny] == -1) {\n                dist[nx][ny] = dist[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n}\n\npair<int,int> countAreaAndPets(int sx, int sy) {\n    int dist[SIZE][SIZE];\n    bfs(sx, sy, dist);\n    int area = 0, pets = 0;\n    for (int i = 0; i < SIZE; i++)\n        for (int j = 0; j < SIZE; j++)\n            if (dist[i][j] >= 0) area++;\n    for (int i = 0; i < N; i++)\n        if (dist[px[i]][py[i]] >= 0) pets++;\n    return {area, pets};\n}\n\ndouble calcScore(int area, int nPets) { return (double)area / 900.0 * pow(2.0, -nPets); }\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    px.resize(N); py.resize(N); pt.resize(N);\n    for (int i = 0; i < N; i++) { cin >> px[i] >> py[i] >> pt[i]; px[i]--; py[i]--; }\n    cin >> M;\n    hx.resize(M); hy.resize(M);\n    for (int i = 0; i < M; i++) { cin >> hx[i] >> hy[i]; hx[i]--; hy[i]--; }\n    \n    memset(wall, false, sizeof(wall));\n    \n    for (int turn = 0; turn < 300; turn++) {\n        vector<int> startPx = px, startPy = py;\n        vector<int> startHx = hx, startHy = hy;\n        string actions(M, '.');\n        bool newWall[SIZE][SIZE] = {};\n        \n        for (int i = 0; i < M; i++) {\n            int myHx = startHx[i], myHy = startHy[i];\n            auto [curArea, curPets] = countAreaAndPets(myHx, myHy);\n            double curScore = calcScore(curArea, curPets);\n            char bestAction = '.';\n            double bestScore = curScore;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = myHx + dx[d], ny = myHy + dy[d];\n                if (inBounds(nx, ny) && !wall[nx][ny] && !newWall[nx][ny] &&\n                    !petAdjacentTo(nx, ny, startPx, startPy) && !humanAt(nx, ny, startHx, startHy)) {\n                    wall[nx][ny] = true;\n                    auto [newArea, newPets] = countAreaAndPets(myHx, myHy);\n                    wall[nx][ny] = false;\n                    double newScore = calcScore(newArea, newPets);\n                    if (newScore > bestScore) { bestScore = newScore; bestAction = \"udlr\"[d]; }\n                }\n            }\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = myHx + dx[d], ny = myHy + dy[d];\n                if (inBounds(nx, ny) && !wall[nx][ny] && !newWall[nx][ny]) {\n                    auto [newArea, newPets] = countAreaAndPets(nx, ny);\n                    double newScore = calcScore(newArea, newPets);\n                    if (newScore > bestScore) { bestScore = newScore; bestAction = \"UDLR\"[d]; }\n                }\n            }\n            \n            actions[i] = bestAction;\n            switch (actions[i]) {\n                case 'u': newWall[myHx-1][myHy] = true; wall[myHx-1][myHy] = true; break;\n                case 'd': newWall[myHx+1][myHy] = true; wall[myHx+1][myHy] = true; break;\n                case 'l': newWall[myHx][myHy-1] = true; wall[myHx][myHy-1] = true; break;\n                case 'r': newWall[myHx][myHy+1] = true; wall[myHx][myHy+1] = true; break;\n                case 'U': hx[i] = myHx - 1; hy[i] = myHy; break;\n                case 'D': hx[i] = myHx + 1; hy[i] = myHy; break;\n                case 'L': hx[i] = myHx; hy[i] = myHy - 1; break;\n                case 'R': hx[i] = myHx; hy[i] = myHy + 1; break;\n            }\n        }\n        \n        cout << actions << endl;\n        \n        for (int i = 0; i < N; i++) {\n            string move; cin >> move;\n            for (char c : move) {\n                if (c == 'U') px[i]--;\n                else if (c == 'D') px[i]++;\n                else if (c == 'L') py[i]--;\n                else if (c == 'R') py[i]++;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\nusing namespace std;\n\nint si, sj, ti, tj;\ndouble p;\nvector<string> h(20), v(19);\n\npair<int,int> move_pos(int i, int j, int d) {\n    int di[]={-1,1,0,0}, dj[]={0,0,-1,1};\n    int ni=i+di[d], nj=j+dj[d];\n    if(ni<0||ni>=20||nj<0||nj>=20) return {i,j};\n    if(d==0 && i>0 && v[i-1][j]=='1') return {i,j};\n    if(d==1 && v[i][j]=='1') return {i,j};\n    if(d==2 && j>0 && h[i][j-1]=='1') return {i,j};\n    if(d==3 && h[i][j]=='1') return {i,j};\n    return {ni,nj};\n}\n\ndouble compute_score(const string& s) {\n    vector<vector<double>> prob(20,vector<double>(20,0));\n    prob[si][sj]=1.0; double es=0;\n    for(int t=0;t<(int)s.size();t++){\n        int d=s[t]=='U'?0:s[t]=='D'?1:s[t]=='L'?2:3;\n        vector<vector<double>> np(20,vector<double>(20,0));\n        for(int i=0;i<20;i++) for(int j=0;j<20;j++){\n            if(prob[i][j]<1e-15) continue;\n            np[i][j]+=p*prob[i][j];\n            auto[ni,nj]=move_pos(i,j,d);\n            if(ni==ti&&nj==tj) es+=(1-p)*prob[i][j]*(401-(t+1));\n            else np[ni][nj]+=(1-p)*prob[i][j];\n        }\n        prob=np;\n    }\n    return es;\n}\n\nstring find_shortest_path() {\n    vector<vector<int>> dist(20,vector<int>(20,-1)), pdir(20,vector<int>(20,-1));\n    queue<pair<int,int>> q; q.push({si,sj}); 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(int d=0;d<4;d++){\n            auto[ni,nj]=move_pos(i,j,d);\n            if((ni!=i||nj!=j)&&dist[ni][nj]==-1){\n                dist[ni][nj]=dist[i][j]+1; pdir[ni][nj]=d; q.push({ni,nj});\n            }\n        }\n    }\n    string path; int i=ti,j=tj;\n    while(i!=si||j!=sj){\n        int d=pdir[i][j]; char c=\"UDLR\"[d]; path=c+path;\n        int di[]={-1,1,0,0},dj[]={0,0,-1,1}; i-=di[d]; j-=dj[d];\n    }\n    return path;\n}\n\nstring greedy_with_dp() {\n    const int L=200;\n    vector<vector<double>> f(400,vector<double>(L+2,0));\n    for(int t=L;t>=1;t--) for(int i=0;i<20;i++) for(int j=0;j<20;j++){\n        int idx=i*20+j;\n        if(i==ti&&j==tj) f[idx][t]=401-t;\n        else{ double best=0;\n            for(int d=0;d<4;d++){\n                auto[ni,nj]=move_pos(i,j,d); int nidx=ni*20+nj;\n                best=max(best,p*f[idx][t+1]+(1-p)*f[nidx][t+1]);\n            } f[idx][t]=best;\n        }\n    }\n    vector<double> prob(400,0); prob[si*20+sj]=1.0;\n    string result;\n    for(int t=1;t<=L;t++){\n        double bs=-1; int ba=0;\n        for(int d=0;d<4;d++){\n            vector<double> np(400,0); double rp=0;\n            for(int idx=0;idx<400;idx++){\n                if(prob[idx]<1e-15) continue;\n                int i=idx/20,j=idx%20; np[idx]+=p*prob[idx];\n                auto[ni,nj]=move_pos(i,j,d); int nidx=ni*20+nj;\n                if(ni==ti&&nj==tj) rp+=(1-p)*prob[idx];\n                else np[nidx]+=(1-p)*prob[idx];\n            }\n            double sc=rp*(401-t);\n            for(int idx=0;idx<400;idx++) sc+=np[idx]*f[idx][t+1];\n            if(sc>bs){bs=sc;ba=d;}\n        }\n        result+=\"UDLR\"[ba];\n        vector<double> np(400,0);\n        for(int idx=0;idx<400;idx++){\n            if(prob[idx]<1e-15) continue;\n            int i=idx/20,j=idx%20; np[idx]+=p*prob[idx];\n            auto[ni,nj]=move_pos(i,j,ba); int nidx=ni*20+nj;\n            if(ni!=ti||nj!=tj) np[nidx]+=(1-p)*prob[idx];\n        }\n        prob=np;\n    }\n    return result;\n}\n\nint main(){\n    ios_base::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    \n    string shortest=find_shortest_path();\n    string best_str; double best_score=-1;\n    \n    // Strategy 1: Repeat shortest path\n    {string s; while(s.size()+shortest.size()<=200) s+=shortest;\n     double sc=compute_score(s); if(sc>best_score){best_score=sc;best_str=s;}}\n    \n    // Strategy 2: Redundant moves\n    for(int r=2;r<=5;r++){\n        string s; for(char c:shortest) for(int k=0;k<r&&s.size()<200;k++) s+=c;\n        double sc=compute_score(s); if(sc>best_score){best_score=sc;best_str=s;}\n    }\n    \n    // Strategy 3: Greedy with DP\n    {string s=greedy_with_dp(); double sc=compute_score(s);\n     if(sc>best_score){best_score=sc;best_str=s;}}\n    \n    // Strategy 4: Shortest path + DR padding\n    {string s=shortest; while(s.size()<200){s+='D';if(s.size()<200)s+='R';}\n     double sc=compute_score(s); if(sc>best_score){best_score=sc;best_str=s;}}\n    \n    cout<<best_str<<endl;\n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint orig_tiles[N][N], rotations[N][N], current_tiles[N][N];\nconst int di[] = {0, -1, 0, 1}, dj[] = {-1, 0, 1, 0};\nconst int to_table[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 rotated_type[8][4];\n\nvoid init_rotated_type() {\n    for (int t = 0; t < 8; t++) {\n        rotated_type[t][0] = t;\n        int cur = t;\n        for (int r = 1; r < 4; r++) {\n            if (cur <= 3) cur = (cur + 1) % 4;\n            else if (cur == 4) cur = 5; else if (cur == 5) cur = 4;\n            else if (cur == 6) cur = 7; else cur = 6;\n            rotated_type[t][r] = cur;\n        }\n    }\n}\n\nvoid update_all_tiles() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            current_tiles[i][j] = rotated_type[orig_tiles[i][j]][rotations[i][j]];\n}\n\npair<int,int> compute_top2() {\n    static bool visited[N][N][4];\n    memset(visited, 0, sizeof(visited));\n    int max1 = 0, max2 = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int t = current_tiles[i][j];\n            for (int d = 0; d < 4; d++) {\n                if (visited[i][j][d] || to_table[t][d] == -1) { visited[i][j][d] = true; continue; }\n                int si = i, sj = j, sd = d, ci = i, cj = j, cd = d, length = 0;\n                while (true) {\n                    visited[ci][cj][cd] = true;\n                    int t2 = current_tiles[ci][cj], d2 = to_table[t2][cd];\n                    if (d2 == -1) break;\n                    int ni = ci + di[d2], nj = cj + dj[d2];\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n                    int nd = (d2 + 2) % 4; length++;\n                    if (ni == si && nj == sj && nd == sd) {\n                        if (length > max1) { max2 = max1; max1 = length; }\n                        else if (length > max2) max2 = length;\n                        break;\n                    }\n                    ci = ni; cj = nj; cd = nd;\n                }\n            }\n        }\n    }\n    return {max1, max2};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    init_rotated_type();\n    for (int i = 0; i < N; i++) { string s; cin >> s; for (int j = 0; j < N; j++) orig_tiles[i][j] = s[j] - '0'; }\n    \n    mt19937 rng(42);\n    long long global_best_score = 0; int global_best_rotations[N][N] = {};\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    for (int trial = 0; trial < 10; trial++) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration<double>(now - start_time).count() > 1.5) break;\n        \n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) rotations[i][j] = rng() % 4;\n        update_all_tiles();\n        \n        auto [m1, m2] = compute_top2();\n        long long cur_score = (long long)m1 * m2, best_score = cur_score;\n        int best_rotations[N][N]; memcpy(best_rotations, rotations, sizeof(rotations));\n        \n        uniform_int_distribution<int> pos_dist(0, N*N-1), rot_dist(0, 3);\n        uniform_real_distribution<double> prob_dist(0.0, 1.0);\n        \n        for (int iter = 0; iter < 30000; iter++) {\n            now = chrono::high_resolution_clock::now();\n            if (chrono::duration<double>(now - start_time).count() > 1.7) break;\n            double temp = 100.0 * pow(0.01, min((double)iter / 30000.0, 1.0));\n            \n            int idx = pos_dist(rng), i = idx / N, j = idx % N;\n            int old_rot = rotations[i][j], new_rot = rot_dist(rng);\n            if (old_rot == new_rot) continue;\n            \n            rotations[i][j] = new_rot;\n            current_tiles[i][j] = rotated_type[orig_tiles[i][j]][new_rot];\n            \n            auto [nm1, nm2] = compute_top2();\n            long long new_score = (long long)nm1 * nm2;\n            \n            if (new_score - cur_score > 0 || prob_dist(rng) < exp((double)(new_score - cur_score) / max(temp, 0.001))) {\n                cur_score = new_score;\n                if (cur_score > best_score) { best_score = cur_score; memcpy(best_rotations, rotations, sizeof(rotations)); }\n            } else { rotations[i][j] = old_rot; current_tiles[i][j] = rotated_type[orig_tiles[i][j]][old_rot]; }\n        }\n        if (best_score > global_best_score) { global_best_score = best_score; memcpy(global_best_rotations, best_rotations, sizeof(best_rotations)); }\n    }\n    \n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cout << global_best_rotations[i][j];\n    cout << endl;\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nint board[10][10];\nint er, ec;\n\nint compute_max_tree_size() {\n    vector<int> parent(N*N), sz(N*N, 0);\n    iota(parent.begin(), parent.end(), 0);\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j]) sz[i*N+j] = 1;\n    \n    function<int(int)> find = [&](int x) {\n        while (parent[x] != x) x = parent[x] = parent[parent[x]];\n        return x;\n    };\n    auto unite = [&](int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return;\n        if (sz[x] < sz[y]) swap(x, y);\n        parent[y] = x; sz[x] += sz[y];\n    };\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N-1; j++)\n            if (board[i][j] && board[i][j+1] && (board[i][j] & 4) && (board[i][j+1] & 1))\n                unite(i*N+j, i*N+j+1);\n    for (int i = 0; i < N-1; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j] && board[i+1][j] && (board[i][j] & 8) && (board[i+1][j] & 2))\n                unite(i*N+j, (i+1)*N+j);\n    \n    int mx = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j]) mx = max(mx, sz[find(i*N+j)]);\n    return mx;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> T;\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) {\n            char c = s[j];\n            board[i][j] = (c >= '0' && c <= '9') ? c - '0' : c - 'a' + 10;\n            if (!board[i][j]) { er = i; ec = j; }\n        }\n    }\n    \n    string moves;\n    int cur_sz = compute_max_tree_size(), best_sz = cur_sz;\n    size_t best_cnt = 0;\n    mt19937 rng(42);\n    int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};\n    char dc_c[] = {'U','D','L','R'};\n    auto start = chrono::high_resolution_clock::now();\n    int stale = 0;\n    \n    while ((int)moves.size() < T) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now-start).count() > 2800) break;\n        \n        int bd = -1, bns = cur_sz;\n        for (int d = 0; d < 4; d++) {\n            int nr = er+dr[d], nc = ec+dc[d];\n            if (nr<0||nr>=N||nc<0||nc>=N) continue;\n            swap(board[er][ec], board[nr][nc]);\n            int oe=er, oec=ec; er=nr; ec=nc;\n            int ns = compute_max_tree_size();\n            if (ns > bns) { bns = ns; bd = d; }\n            swap(board[er][ec], board[oe][oec]); er=oe; ec=oec;\n        }\n        \n        if (bd != -1) {\n            int nr=er+dr[bd], nc=ec+dc[bd];\n            swap(board[er][ec], board[nr][nc]); er=nr; ec=nc;\n            moves += dc_c[bd]; cur_sz = bns; stale = 0;\n            if (cur_sz > best_sz) { best_sz = cur_sz; best_cnt = moves.size(); }\n            if (cur_sz == N*N-1) break;\n        } else {\n            if (++stale > 3) {\n                for (int i = 0; i < 5 && (int)moves.size() < T; i++) {\n                    vector<int> v;\n                    for (int d = 0; d < 4; d++) {\n                        int nr=er+dr[d], nc=ec+dc[d];\n                        if (nr>=0&&nr<N&&nc>=0&&nc<N) v.push_back(d);\n                    }\n                    if (v.empty()) break;\n                    int d = v[rng()%v.size()], nr=er+dr[d], nc=ec+dc[d];\n                    swap(board[er][ec], board[nr][nc]); er=nr; ec=nc;\n                    moves += dc_c[d];\n                }\n                cur_sz = compute_max_tree_size();\n                if (cur_sz > best_sz) { best_sz = cur_sz; best_cnt = moves.size(); }\n                stale = 0;\n            } else break;\n        }\n    }\n    cout << moves.substr(0, best_cnt) << endl;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\n\nint N, K;\nint a[11];\nvector<ll> px, py;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> K;\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    px.resize(N); py.resize(N);\n    for (int i = 0; i < N; i++) cin >> px[i] >> py[i];\n    \n    vector<tuple<ll, ll, ll, ll>> output;\n    \n    auto compute_score = [&]() {\n        map<vector<int>, int> groups;\n        for (int i = 0; i < N; i++) {\n            vector<int> sig;\n            bool destroyed = false;\n            for (auto& [x1, y1, x2, y2] : output) {\n                ll la = y2 - y1, lb = x1 - x2, lc = x2*y1 - x1*y2;\n                ll val = la*px[i] + lb*py[i] + lc;\n                if (val == 0) { destroyed = true; break; }\n                sig.push_back(val > 0 ? 1 : -1);\n            }\n            if (!destroyed) groups[sig]++;\n        }\n        int pc[11] = {};\n        for (auto& [s, c] : groups) if (c >= 1 && c <= 10) pc[c]++;\n        int score = 0;\n        for (int d = 1; d <= 10; d++) score += min(a[d], pc[d]);\n        return score;\n    };\n    \n    auto start = chrono::steady_clock::now();\n    \n    for (int iter = 0; iter < K; iter++) {\n        if (chrono::duration<double>(chrono::steady_clock::now() - start).count() > 2.5) break;\n        \n        int cur_score = compute_score();\n        int max_score = 0;\n        for (int d = 1; d <= 10; d++) max_score += a[d];\n        if (cur_score == max_score) break;\n        \n        map<vector<int>, vector<int>> groups;\n        for (int i = 0; i < N; i++) {\n            vector<int> sig;\n            bool destroyed = false;\n            for (auto& [x1, y1, x2, y2] : output) {\n                ll la = y2 - y1, lb = x1 - x2, lc = x2*y1 - x1*y2;\n                ll val = la*px[i] + lb*py[i] + lc;\n                if (val == 0) { destroyed = true; break; }\n                sig.push_back(val > 0 ? 1 : -1);\n            }\n            if (!destroyed) groups[sig].push_back(i);\n        }\n        \n        int pc[11] = {};\n        for (auto& [s, m] : groups) { int sz = m.size(); if (sz >= 1 && sz <= 10) pc[sz]++; }\n        \n        tuple<ll,ll,ll,ll> best_line;\n        int best_score = cur_score;\n        bool found = false;\n        \n        for (auto& [sig, members] : groups) {\n            int sz = members.size();\n            if (sz <= 1) continue;\n            if (sz <= 10 && pc[sz] <= a[sz]) continue;\n            \n            int limit = min((int)members.size(), 20);\n            for (int ii = 0; ii < limit; ii++) {\n                for (int jj = ii+1; jj < limit; jj++) {\n                    int i = members[ii], j = members[jj];\n                    ll mx = (px[i]+px[j])/2, my = (py[i]+py[j])/2;\n                    ll dx = py[i]-py[j], dy = px[j]-px[i];\n                    ll x1 = mx, y1 = my, x2 = mx+dx, y2 = my+dy;\n                    if (x1 == x2 && y1 == y2) continue;\n                    \n                    output.push_back({x1,y1,x2,y2});\n                    int ns = compute_score();\n                    output.pop_back();\n                    if (ns > best_score) { best_score = ns; best_line = {x1,y1,x2,y2}; found = true; }\n                }\n            }\n        }\n        \n        mt19937 rng(42+iter);\n        for (int r = 0; r < 50; r++) {\n            ll x1 = rng()%20001-10000, y1 = rng()%20001-10000;\n            ll x2 = rng()%20001-10000, y2 = rng()%20001-10000;\n            if (x1==x2 && y1==y2) continue;\n            output.push_back({x1,y1,x2,y2});\n            int ns = compute_score();\n            output.pop_back();\n            if (ns > best_score) { best_score = ns; best_line = {x1,y1,x2,y2}; found = true; }\n        }\n        \n        if (found) output.push_back(best_line);\n        else break;\n    }\n    \n    cout << output.size() << endl;\n    for (auto& [x1,y1,x2,y2] : output) cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nvector<vector<bool>> has_dot;\nvector<array<int,8>> ops;\nmap<int,vector<pair<int,int>>> segs[4];\n\nint seg_type(int x1,int y1,int x2,int y2){\n    if(y1==y2)return 0;\n    if(x1==x2)return 1;\n    if(x2-x1==y2-y1)return 2;\n    return 3;\n}\nint line_id(int t,int x,int y){\n    if(t==0)return y;if(t==1)return x;\n    if(t==2)return x-y;return x+y;\n}\n\nbool check_overlap(int t,int lid,int s,int e){\n    if(s>e)swap(s,e);\n    auto it=segs[t].find(lid);\n    if(it==segs[t].end())return false;\n    for(auto&[a,b]:it->second){\n        int lo=min(a,b),hi=max(a,b);\n        if(max(s,lo)<min(e,hi))return true;\n    }\n    return false;\n}\nvoid add_seg(int t,int lid,int s,int e){segs[t][lid].push_back({s,e});}\n\nbool has_perim_overlap(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    int e[4][4]={{x1,y1,x2,y2},{x2,y2,x3,y3},{x3,y3,x4,y4},{x4,y4,x1,y1}};\n    for(int i=0;i<4;i++){\n        int t=seg_type(e[i][0],e[i][1],e[i][2],e[i][3]);\n        int lid=line_id(t,e[i][0],e[i][1]);\n        int s=(t<2)?(t==0?e[i][0]:e[i][1]):e[i][0];\n        int ee=(t<2)?(t==0?e[i][2]:e[i][3]):e[i][2];\n        if(check_overlap(t,lid,s,ee))return true;\n    }\n    return false;\n}\nvoid add_perim(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    int e[4][4]={{x1,y1,x2,y2},{x2,y2,x3,y3},{x3,y3,x4,y4},{x4,y4,x1,y1}};\n    for(int i=0;i<4;i++){\n        int t=seg_type(e[i][0],e[i][1],e[i][2],e[i][3]);\n        int lid=line_id(t,e[i][0],e[i][1]);\n        int s=(t<2)?(t==0?e[i][0]:e[i][1]):e[i][0];\n        int ee=(t<2)?(t==0?e[i][2]:e[i][3]):e[i][2];\n        add_seg(t,lid,s,ee);\n    }\n}\n\nbool dot_on_perim(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    set<pair<int,int>>corners={{x1,y1},{x2,y2},{x3,y3},{x4,y4}};\n    auto chk=[&](int ax,int ay,int bx,int by){\n        int dx=bx-ax,dy=by-ay,st=max(abs(dx),abs(dy));\n        if(!st)return false;\n        int sx=dx/st,sy=dy/st;\n        for(int i=1;i<st;i++){\n            int px=ax+i*sx,py=ay+i*sy;\n            if(!corners.count({px,py})&&has_dot[px][py])return true;\n        }\n        return false;\n    };\n    return chk(x1,y1,x2,y2)||chk(x2,y2,x3,y3)||chk(x3,y3,x4,y4)||chk(x4,y4,x1,y1);\n}\n\nbool valid(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    if(dot_on_perim(x1,y1,x2,y2,x3,y3,x4,y4))return false;\n    if(has_perim_overlap(x1,y1,x2,y2,x3,y3,x4,y4))return false;\n    return true;\n}\n\nvector<int> find_rect(int ex,int ey){\n    // Axis-aligned\n    for(int x2=0;x2<N;x2++)if(x2!=ex)\n        for(int y2=0;y2<N;y2++)if(y2!=ey)\n            if(has_dot[ex][y2]&&has_dot[x2][ey]&&has_dot[x2][y2])\n                if(valid(ex,ey,ex,y2,x2,y2,x2,ey))\n                    return {ex,ey,ex,y2,x2,y2,x2,ey};\n    \n    // Tilted orientation 1: V1->V2 (1,1), V2->V3 (1,-1)\n    auto try_tilt=[&](int v1x,int v1y,int v2x,int v2y,int v3x,int v3y,int v4x,int v4y){\n        if(v1x<0||v1x>=N||v1y<0||v1y>=N)return false;\n        if(v2x<0||v2x>=N||v2y<0||v2y>=N)return false;\n        if(v3x<0||v3x>=N||v3y<0||v3y>=N)return false;\n        if(v4x<0||v4x>=N||v4y<0||v4y>=N)return false;\n        if(!has_dot[v2x][v2y]||!has_dot[v3x][v3y]||!has_dot[v4x][v4y])return false;\n        return valid(v1x,v1y,v2x,v2y,v3x,v3y,v4x,v4y);\n    };\n    \n    for(int a=1;a<N;a++)for(int b=1;b<N;b++){\n        int v2x=ex+a,v2y=ey+a,v3x=ex+a+b,v3y=ey+a-b,v4x=ex+b,v4y=ey-b;\n        if(try_tilt(ex,ey,v2x,v2y,v3x,v3y,v4x,v4y))return {ex,ey,v2x,v2y,v3x,v3y,v4x,v4y};\n        \n        int u1x=ex-a,u1y=ey-a;v3x=ex+b;v3y=ey-b;v4x=ex-a+b;v4y=ey-a-b;\n        if(try_tilt(u1x,u1y,ex,ey,v3x,v3y,v4x,v4y))return {u1x,u1y,ex,ey,v3x,v3y,v4x,v4y};\n        \n        u1x=ex-a-b;u1y=ey-a+b;int u2x=ex-b,u2y=ey+b;v4x=ex-a;v4y=ey-a;\n        if(try_tilt(u1x,u1y,u2x,u2y,ex,ey,v4x,v4y))return {u1x,u1y,u2x,u2y,ex,ey,v4x,v4y};\n        \n        u1x=ex-b;u1y=ey+b;int u3x=ex+a,u3y=ey+a;v4x=ex-b+a;v4y=ey+b+a;\n        if(try_tilt(u1x,u1y,v4x,v4y,u3x,u3y,ex,ey))return {u1x,u1y,v4x,v4y,u3x,u3y,ex,ey};\n    }\n    \n    // Tilted orientation 2: V1->V2 (1,-1), V2->V3 (1,1)\n    for(int a=1;a<N;a++)for(int b=1;b<N;b++){\n        int v2x=ex+a,v2y=ey-a,v3x=ex+a+b,v3y=ey-a+b,v4x=ex+b,v4y=ey+b;\n        if(try_tilt(ex,ey,v2x,v2y,v3x,v3y,v4x,v4y))return {ex,ey,v2x,v2y,v3x,v3y,v4x,v4y};\n        \n        int u1x=ex-a,u1y=ey+a;v3x=ex+b;v3y=ey+b;v4x=ex-a+b;v4y=ey+a+b;\n        if(try_tilt(u1x,u1y,ex,ey,v3x,v3y,v4x,v4y))return {u1x,u1y,ex,ey,v3x,v3y,v4x,v4y};\n        \n        u1x=ex-a-b;u1y=ey+a-b;int u2x=ex-b,u2y=ey-b;v4x=ex-a;v4y=ey+a;\n        if(try_tilt(u1x,u1y,u2x,u2y,ex,ey,v4x,v4y))return {u1x,u1y,u2x,u2y,ex,ey,v4x,v4y};\n        \n        u1x=ex-b;u1y=ey-b;int u3x=ex+a,u3y=ey-a;v4x=ex-b+a;v4y=ey-b-a;\n        if(try_tilt(u1x,u1y,v4x,v4y,u3x,u3y,ex,ey))return {u1x,u1y,v4x,v4y,u3x,u3y,ex,ey};\n    }\n    return {};\n}\n\nint main(){\n    cin>>N>>M;\n    has_dot.assign(N,vector<bool>(N,false));\n    for(int i=0;i<M;i++){int x,y;cin>>x>>y;has_dot[x][y]=true;}\n    \n    double c=(N-1)/2.0;\n    bool found=true;\n    while(found){\n        found=false;\n        double best_w=-1;vector<int>best_r;\n        for(int x=0;x<N;x++)for(int y=0;y<N;y++){\n            if(has_dot[x][y])continue;\n            double w=(x-c)*(x-c)+(y-c)*(y-c)+1;\n            if(w<=best_w)continue;\n            auto r=find_rect(x,y);\n            if(!r.empty()){best_w=w;best_r=r;found=true;}\n        }\n        if(found){\n            int x1=best_r[0],y1=best_r[1],x2=best_r[2],y2=best_r[3];\n            int x3=best_r[4],y3=best_r[5],x4=best_r[6],y4=best_r[7];\n            has_dot[x1][y1]=true;\n            add_perim(x1,y1,x2,y2,x3,y3,x4,y4);\n            ops.push_back({x1,y1,x2,y2,x3,y3,x4,y4});\n        }\n    }\n    cout<<ops.size()<<endl;\n    for(auto&op:ops){\n        for(int i=0;i<8;i++)cout<<op[i]<<(i<7?\" \":\"\\n\");\n    }\n}","ahc015":"#include <iostream>\n#include <cstring>\n#include <queue>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nint f[101];\n\nvoid tilt(int d) {\n    if (d == 0) { // F (up)\n        for (int c = 0; c < N; c++) {\n            int write = 0;\n            for (int r = 0; r < N; r++) {\n                if (grid[r][c] != 0) {\n                    if (write != r) { grid[write][c] = grid[r][c]; grid[r][c] = 0; }\n                    write++;\n                }\n            }\n        }\n    } else if (d == 1) { // B (down)\n        for (int c = 0; c < N; c++) {\n            int write = N - 1;\n            for (int r = N - 1; r >= 0; r--) {\n                if (grid[r][c] != 0) {\n                    if (write != r) { grid[write][c] = grid[r][c]; grid[r][c] = 0; }\n                    write--;\n                }\n            }\n        }\n    } else if (d == 2) { // L (left)\n        for (int r = 0; r < N; r++) {\n            int write = 0;\n            for (int c = 0; c < N; c++) {\n                if (grid[r][c] != 0) {\n                    if (write != c) { grid[r][write] = grid[r][c]; grid[r][c] = 0; }\n                    write++;\n                }\n            }\n        }\n    } else { // R (right)\n        for (int r = 0; r < N; r++) {\n            int write = N - 1;\n            for (int c = N - 1; c >= 0; c--) {\n                if (grid[r][c] != 0) {\n                    if (write != c) { grid[r][write] = grid[r][c]; grid[r][c] = 0; }\n                    write--;\n                }\n            }\n        }\n    }\n}\n\nlong long calcScore() {\n    bool visited[N][N] = {};\n    long long score = 0;\n    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 (!visited[r][c] && grid[r][c] != 0) {\n                int flavor = grid[r][c], size = 0;\n                queue<pair<int,int>> q;\n                q.push({r, c}); visited[r][c] = true;\n                while (!q.empty()) {\n                    auto [cr, cc] = q.front(); q.pop(); size++;\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 && \n                            !visited[nr][nc] && grid[nr][nc] == flavor) {\n                            visited[nr][nc] = true; q.push({nr, nc});\n                        }\n                    }\n                }\n                score += (long long)size * size;\n            }\n        }\n    }\n    return score;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 1; i <= 100; i++) cin >> f[i];\n    memset(grid, 0, sizeof(grid));\n    \n    string dirs = \"FBLR\";\n    int priority[] = {3, 1, 2, 4}; // B=1, L=2 preferred for compactness\n    \n    for (int t = 1; t <= 100; t++) {\n        int p; cin >> p;\n        \n        int pos = 1, place_r = -1, place_c = -1;\n        for (int r = 0; r < N && place_r == -1; r++) {\n            for (int c = 0; c < N && place_r == -1; c++) {\n                if (grid[r][c] == 0) {\n                    if (pos == p) { place_r = r; place_c = c; }\n                    pos++;\n                }\n            }\n        }\n        grid[place_r][place_c] = f[t];\n        \n        int best_dir = 0; long long best_score = -1; int best_priority = 5;\n        int saved[N][N];\n        \n        for (int d = 0; d < 4; d++) {\n            memcpy(saved, grid, sizeof(grid));\n            tilt(d);\n            long long score = calcScore();\n            if (score > best_score || (score == best_score && priority[d] < best_priority)) {\n                best_score = score; best_priority = priority[d]; best_dir = d;\n            }\n            memcpy(grid, saved, sizeof(grid));\n        }\n        \n        tilt(best_dir);\n        cout << dirs[best_dir] << '\\n';\n        cout.flush();\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M; double eps;\n    cin >> M >> eps;\n    \n    int N = max(10, min(100, (int)(M * (0.5 + eps * 5) + 5)));\n    int maxE = N * (N - 1) / 2;\n    \n    mt19937 rng(42);\n    vector<string> graphs(M);\n    vector<int> edgeCounts(M);\n    vector<vector<int>> sortedDegrees(M);\n    \n    for (int k = 0; k < M; k++) {\n        int targetEdges = (M > 1) ? (int)((long long)k * maxE / (M - 1)) : maxE / 2;\n        \n        vector<int> perm(maxE);\n        iota(perm.begin(), perm.end(), 0);\n        shuffle(perm.begin(), perm.end(), rng);\n        \n        string g(maxE, '0');\n        for (int i = 0; i < targetEdges; i++) g[perm[i]] = '1';\n        graphs[k] = g;\n        edgeCounts[k] = targetEdges;\n        \n        vector<int> deg(N, 0);\n        int idx = 0;\n        for (int i = 0; i < N; i++)\n            for (int j = i + 1; j < N; j++)\n                if (g[idx++] == '1') { deg[i]++; deg[j]++; }\n        sort(deg.begin(), deg.end());\n        sortedDegrees[k] = deg;\n    }\n    \n    vector<double> expEdges(M);\n    vector<vector<double>> expDeg(M);\n    for (int k = 0; k < M; k++) {\n        expEdges[k] = edgeCounts[k] * (1 - 2 * eps) + maxE * eps;\n        expDeg[k].resize(N);\n        for (int i = 0; i < N; i++)\n            expDeg[k][i] = sortedDegrees[k][i] * (1 - 2 * eps) + (N - 1) * eps;\n    }\n    \n    cout << N << \"\\n\";\n    for (int k = 0; k < M; k++) cout << graphs[k] << \"\\n\";\n    cout.flush();\n    \n    double edgeVar = max(1.0, maxE * eps * (1 - eps));\n    double degVar = max(1.0, (N - 1) * eps * (1 - eps));\n    \n    for (int q = 0; q < 100; q++) {\n        string H; cin >> H;\n        int hEdges = count(H.begin(), H.end(), '1');\n        \n        vector<int> hDeg(N, 0);\n        int idx = 0;\n        for (int i = 0; i < N; i++)\n            for (int j = i + 1; j < N; j++)\n                if (H[idx++] == '1') { hDeg[i]++; hDeg[j]++; }\n        sort(hDeg.begin(), hDeg.end());\n        \n        int bestK = 0; double bestScore = -1e18;\n        for (int k = 0; k < M; k++) {\n            double score = 0;\n            double edgeDiff = hEdges - expEdges[k];\n            score -= edgeDiff * edgeDiff / (2 * edgeVar);\n            for (int i = 0; i < N; i++) {\n                double diff = hDeg[i] - expDeg[k][i];\n                score -= diff * diff / (2 * degVar);\n            }\n            if (score > bestScore) { bestScore = score; bestK = k; }\n        }\n        cout << bestK << \"\\n\";\n        cout.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\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n    \n    vector<int> u(M), v(M), w(M);\n    vector<vector<pair<int, int>>> adj(N);\n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i] >> w[i];\n        u[i]--; v[i]--;\n        adj[u[i]].push_back({i, v[i]});\n        adj[v[i]].push_back({i, u[i]});\n    }\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    // Build edge adjacency (edges sharing a vertex)\n    vector<vector<int>> edge_adj(M);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < (int)adj[i].size(); j++) {\n            for (int k = j + 1; k < (int)adj[i].size(); k++) {\n                edge_adj[adj[i][j].first].push_back(adj[i][k].first);\n                edge_adj[adj[i][k].first].push_back(adj[i][j].first);\n            }\n        }\n    }\n    \n    // Compute edge midpoints\n    vector<double> mx(M), my(M);\n    for (int i = 0; i < M; i++) {\n        mx[i] = (x[u[i]] + x[v[i]]) / 2.0;\n        my[i] = (y[u[i]] + y[v[i]]) / 2.0;\n    }\n    \n    // Sort by angle from center for geographic spreading\n    double cx = 500, cy = 500;\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    \n    sort(order.begin(), order.end(), [&](int a, int b) {\n        double ax = mx[a] - cx, ay = my[a] - cy;\n        double bx = mx[b] - cx, by = my[b] - cy;\n        double aa = atan2(ay, ax), ab = atan2(by, bx);\n        if (abs(aa - ab) > 1e-9) return aa < ab;\n        double da = ax*ax + ay*ay, db = bx*bx + by*by;\n        return da < db;\n    });\n    \n    // Greedy edge coloring with conflict avoidance\n    vector<int> r(M, -1);\n    vector<int> day_count(D, 0);\n    \n    for (int idx : order) {\n        vector<int> conflicts(D, 0);\n        for (int e : edge_adj[idx]) {\n            if (r[e] != -1) conflicts[r[e]]++;\n        }\n        \n        int best_day = -1;\n        double best_score = 1e18;\n        for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K) continue;\n            double score = day_count[d] * 10.0 + conflicts[d] * 100.0;\n            if (score < best_score) {\n                best_score = score;\n                best_day = d;\n            }\n        }\n        \n        if (best_day == -1) {\n            for (int d = 0; d < D; d++) {\n                if (day_count[d] < K && (best_day == -1 || day_count[d] < day_count[best_day])) {\n                    best_day = d;\n                }\n            }\n        }\n        \n        r[idx] = best_day;\n        day_count[best_day]++;\n    }\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        cout << r[i] + 1 << (i == M-1 ? \"\\n\" : \" \");\n    }\n    \n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <algorithm>\n#include <queue>\n#include <tuple>\n#include <climits>\nusing namespace std;\n\nint D;\nusing Point = tuple<int,int,int>;\nusing Array3D = vector<vector<vector<int>>>;\n\nvector<string> readSilhouette() {\n    vector<string> s(D);\n    for (int i = 0; i < D; i++) cin >> s[i];\n    return s;\n}\n\nArray3D buildObject(const vector<string>& f, const vector<string>& r) {\n    Array3D b(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for (int x = 0; x < D; x++)\n        for (int y = 0; y < D; y++)\n            for (int z = 0; z < D; z++)\n                if (f[z][x] == '1' && r[z][y] == '1') b[x][y][z] = 1;\n    return b;\n}\n\nvector<vector<Point>> findComponents(const Array3D& b) {\n    vector<vector<vector<bool>>> vis(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<Point>> comps;\n    const int dx[] = {1,-1,0,0,0,0}, dy[] = {0,0,1,-1,0,0}, dz[] = {0,0,0,0,1,-1};\n    for (int x = 0; x < D; x++) for (int y = 0; y < D; y++) for (int z = 0; z < D; z++) {\n        if (b[x][y][z] == 1 && !vis[x][y][z]) {\n            vector<Point> comp; queue<Point> q; q.push({x,y,z}); vis[x][y][z] = true;\n            while (!q.empty()) {\n                auto [cx,cy,cz] = q.front(); q.pop(); comp.push_back({cx,cy,cz});\n                for (int d = 0; d < 6; d++) {\n                    int nx=cx+dx[d], ny=cy+dy[d], nz=cz+dz[d];\n                    if (0<=nx&&nx<D&&0<=ny&&ny<D&&0<=nz&&nz<D&&b[nx][ny][nz]==1&&!vis[nx][ny][nz]) {\n                        vis[nx][ny][nz] = true; q.push({nx,ny,nz});\n                    }\n                }\n            }\n            comps.push_back(move(comp));\n        }\n    }\n    return comps;\n}\n\nPoint rotX(const Point& p) { auto [x,y,z]=p; return {x,-z,y}; }\nPoint rotY(const Point& p) { auto [x,y,z]=p; return {z,y,-x}; }\nPoint rotZ(const Point& p) { auto [x,y,z]=p; return {-y,x,z}; }\n\nvector<Point> canonicalForm(const vector<Point>& comp) {\n    vector<Point> best;\n    for (int r1 = 0; r1 < 4; r1++) for (int r2 = 0; r2 < 4; r2++) for (int r3 = 0; r3 < 4; r3++) {\n        vector<Point> rot;\n        for (auto p : comp) {\n            for (int i = 0; i < r1; i++) p = rotX(p);\n            for (int i = 0; i < r2; i++) p = rotY(p);\n            for (int i = 0; i < r3; i++) p = rotZ(p);\n            rot.push_back(p);\n        }\n        int minX=INT_MAX, minY=INT_MAX, minZ=INT_MAX;\n        for (auto [x,y,z] : rot) { minX=min(minX,x); minY=min(minY,y); minZ=min(minZ,z); }\n        for (auto& [x,y,z] : rot) { x-=minX; y-=minY; z-=minZ; }\n        sort(rot.begin(), rot.end());\n        if (best.empty() || rot < best) best = rot;\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> D;\n    vector<vector<string>> f(2), r(2);\n    for (int i = 0; i < 2; i++) { f[i] = readSilhouette(); r[i] = readSilhouette(); }\n    \n    Array3D b[2]; for (int i = 0; i < 2; i++) b[i] = buildObject(f[i], r[i]);\n    vector<vector<Point>> comp[2]; for (int i = 0; i < 2; i++) comp[i] = findComponents(b[i]);\n    \n    int n1 = comp[0].size(), n2 = comp[1].size();\n    vector<vector<Point>> canon1(n1), canon2(n2);\n    for (int i = 0; i < n1; i++) canon1[i] = canonicalForm(comp[0][i]);\n    for (int j = 0; j < n2; j++) canon2[j] = canonicalForm(comp[1][j]);\n    \n    vector<int> order1(n1); for (int i = 0; i < n1; i++) order1[i] = i;\n    sort(order1.begin(), order1.end(), [&](int a, int b) { return comp[0][a].size() > comp[0][b].size(); });\n    \n    vector<int> match1(n1,-1), match2(n2,-1); vector<bool> used2(n2, false);\n    for (int i : order1) for (int j = 0; j < n2; j++) {\n        if (!used2[j] && canon1[i] == canon2[j]) { match1[i]=j; match2[j]=i; used2[j]=true; break; }\n    }\n    \n    int nextId = 1; vector<int> id1(n1), id2(n2);\n    for (int i = 0; i < n1; i++) if (match1[i] != -1) { id1[i]=nextId; id2[match1[i]]=nextId; nextId++; }\n    for (int i = 0; i < n1; i++) if (match1[i] == -1) id1[i] = nextId++;\n    for (int j = 0; j < n2; j++) if (match2[j] == -1) id2[j] = nextId++;\n    \n    vector<int> out[2];\n    for (int i = 0; i < 2; i++) {\n        out[i].assign(D*D*D, 0);\n        for (int c = 0; c < (int)comp[i].size(); c++) {\n            int id = (i == 0) ? id1[c] : id2[c];\n            for (auto [x,y,z] : comp[i][c]) out[i][x*D*D + y*D + z] = id;\n        }\n    }\n    \n    cout << nextId - 1 << \"\\n\";\n    for (int i = 0; i < 2; i++) {\n        for (int j = 0; j < D*D*D; j++) { if (j) cout << \" \"; cout << out[i][j]; }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc020":"#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, K;\n    cin >> N >> M >> K;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<vector<pair<int, int>>> adj(N);\n    vector<int> u(M), v(M), w(M);\n    for (int j = 0; j < M; j++) {\n        cin >> u[j] >> v[j] >> w[j];\n        u[j]--; v[j]--;\n        adj[u[j]].push_back({v[j], j});\n        adj[v[j]].push_back({u[j], j});\n    }\n    \n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    vector<vector<double>> res_dist(K, vector<double>(N));\n    vector<vector<int>> closest(K);\n    for (int k = 0; k < K; k++) {\n        vector<pair<double, int>> dists;\n        for (int i = 0; i < N; i++) {\n            double dx = a[k] - x[i], dy = b[k] - y[i];\n            res_dist[k][i] = sqrt(dx*dx + dy*dy);\n            dists.push_back({res_dist[k][i], i});\n        }\n        sort(dists.begin(), dists.end());\n        for (int j = 0; j < min(10, N); j++) closest[k].push_back(dists[j].second);\n    }\n    \n    vector<long long> sp_dist(N, LLONG_MAX);\n    vector<int> parent(N, -1);\n    sp_dist[0] = 0;\n    priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;\n    pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d > sp_dist[v]) continue;\n        for (auto [to, eid] : adj[v]) {\n            if (sp_dist[v] + w[eid] < sp_dist[to]) {\n                sp_dist[to] = sp_dist[v] + w[eid];\n                parent[to] = v;\n                pq.push({sp_dist[to], to});\n            }\n        }\n    }\n    \n    vector<int> assignment(K);\n    for (int k = 0; k < K; k++) assignment[k] = closest[k][0];\n    \n    auto compute_P = [&]() {\n        vector<double> max_dist(N, 0);\n        for (int k = 0; k < K; k++)\n            max_dist[assignment[k]] = max(max_dist[assignment[k]], res_dist[k][assignment[k]]);\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; i++)\n            if (max_dist[i] > 0) P[i] = min((int)ceil(max_dist[i]), 5000);\n        return P;\n    };\n    \n    auto compute_B = [&](const vector<int>& P) {\n        vector<int> B(M, 0);\n        for (int i = 1; i < N; i++) {\n            if (P[i] > 0) {\n                int cur = i;\n                while (cur != 0) {\n                    int p = parent[cur];\n                    if (p == -1) break;\n                    for (auto& [to, eid] : adj[cur])\n                        if (to == p) { B[eid] = 1; break; }\n                    cur = p;\n                }\n            }\n        }\n        return B;\n    };\n    \n    auto compute_cost = [&](const vector<int>& P, const vector<int>& B) {\n        long long cost = 0;\n        for (int i = 0; i < N; i++) cost += (long long)P[i] * P[i];\n        for (int j = 0; j < M; j++) if (B[j]) cost += w[j];\n        return cost;\n    };\n    \n    vector<int> P = compute_P();\n    vector<int> B = compute_B(P);\n    long long cost = compute_cost(P, B);\n    \n    mt19937 rng(42);\n    uniform_real_distribution<> uniform(0.0, 1.0);\n    double start_temp = 1e7, end_temp = 1e1;\n    int max_iter = 150000;\n    \n    for (int iter = 0; iter < max_iter; iter++) {\n        double temp = start_temp * pow(end_temp / start_temp, (double)iter / max_iter);\n        int k = rng() % K;\n        int old_assign = assignment[k];\n        int new_assign = closest[k][rng() % closest[k].size()];\n        if (new_assign == old_assign) continue;\n        \n        assignment[k] = new_assign;\n        vector<int> new_P = compute_P();\n        vector<int> new_B = compute_B(new_P);\n        long long new_cost = compute_cost(new_P, new_B);\n        \n        long long delta = new_cost - cost;\n        if (delta < 0 || uniform(rng) < exp(-(double)delta / temp)) {\n            cost = new_cost; P = new_P; B = new_B;\n        } else {\n            assignment[k] = old_assign;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) cout << P[i] << (i < N-1 ? \" \" : \"\\n\");\n    for (int j = 0; j < M; j++) cout << B[j] << (j < M-1 ? \" \" : \"\\n\");\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint grid[N][N];\nint posVal[465][2];\nvector<array<int, 4>> swaps;\n\nvoid doSwap(int x1, int y1, int x2, int y2) {\n    int v1 = grid[x1][y1];\n    int v2 = grid[x2][y2];\n    swap(grid[x1][y1], grid[x2][y2]);\n    posVal[v1][0] = x2; posVal[v1][1] = y2;\n    posVal[v2][0] = x1; posVal[v2][1] = y1;\n    swaps.push_back({x1, y1, x2, y2});\n}\n\nint main() {\n    ios_base::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 >> grid[x][y];\n            posVal[grid[x][y]][0] = x;\n            posVal[grid[x][y]][1] = y;\n        }\n    }\n    \n    for (int v = 0; v < N * (N + 1) / 2 && (int)swaps.size() < 10000; v++) {\n        int tx = 0;\n        while ((tx + 1) * (tx + 2) / 2 <= v) tx++;\n        int ty = v - tx * (tx + 1) / 2;\n        \n        int cx = posVal[v][0], cy = posVal[v][1];\n        \n        while (cx != tx || cy != ty) {\n            int ddx = tx - cx, ddy = ty - cy;\n            \n            int nx, ny;\n            if (ddx > 0 && ddy > 0) {\n                nx = cx + 1; ny = cy + 1;\n            } else if (ddx > 0) {\n                nx = cx + 1; ny = cy;\n            } else if (ddx < 0 && ddy < 0) {\n                nx = cx - 1; ny = cy - 1;\n            } else if (ddx < 0) {\n                nx = cx - 1; ny = cy;\n            } else if (ddy > 0) {\n                nx = cx; ny = cy + 1;\n            } else {\n                nx = cx; ny = cy - 1;\n            }\n            \n            doSwap(cx, cy, nx, ny);\n            cx = nx; cy = ny;\n            \n            if ((int)swaps.size() >= 10000) break;\n        }\n    }\n    \n    cout << swaps.size() << \"\\n\";\n    for (auto& s : swaps) {\n        cout << s[0] << \" \" << s[1] << \" \" << s[2] << \" \" << s[3] << \"\\n\";\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <set>\n\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    vector<vector<bool>> is_obstacle(D, vector<bool>(D, false));\n    for (int i = 0; i < N; i++) {\n        int ri, rj;\n        cin >> ri >> rj;\n        is_obstacle[ri][rj] = true;\n    }\n    \n    int entrance_i = 0, entrance_j = (D - 1) / 2;\n    \n    vector<vector<int>> dist(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    q.push({entrance_i, entrance_j});\n    dist[entrance_i][entrance_j] = 0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    \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 (ni >= 0 && ni < D && nj >= 0 && nj < D && dist[ni][nj] == -1 && !is_obstacle[ni][nj]) {\n                dist[ni][nj] = dist[i][j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    vector<tuple<int, int, int>> cells;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (!(i == entrance_i && j == entrance_j) && !is_obstacle[i][j])\n                cells.push_back({dist[i][j], i, j});\n    \n    sort(cells.begin(), cells.end());\n    int M = cells.size();\n    \n    set<int> available_ranks;\n    for (int k = 0; k < M; k++) available_ranks.insert(k);\n    \n    vector<vector<int>> container_at(D, vector<int>(D, -1));\n    \n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        int target_rank = t;\n        \n        auto it = available_ranks.lower_bound(target_rank);\n        int best_rank = -1, best_diff = M + 1;\n        \n        if (it != available_ranks.end() && abs(*it - target_rank) < best_diff) {\n            best_diff = abs(*it - target_rank);\n            best_rank = *it;\n        }\n        if (it != available_ranks.begin()) {\n            --it;\n            if (abs(*it - target_rank) < best_diff) {\n                best_diff = abs(*it - target_rank);\n                best_rank = *it;\n            }\n        }\n        \n        available_ranks.erase(best_rank);\n        auto [dd, pi, pj] = cells[best_rank];\n        cout << pi << \" \" << pj << endl;\n        container_at[pi][pj] = t;\n    }\n    \n    vector<vector<bool>> is_empty(D, vector<bool>(D, false));\n    is_empty[entrance_i][entrance_j] = true;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (is_obstacle[i][j]) is_empty[i][j] = true;\n    \n    for (int iter = 0; iter < M; iter++) {\n        vector<vector<bool>> accessible(D, vector<bool>(D, false));\n        queue<pair<int, int>> bfs_q;\n        bfs_q.push({entrance_i, entrance_j});\n        accessible[entrance_i][entrance_j] = true;\n        \n        while (!bfs_q.empty()) {\n            auto [i, j] = bfs_q.front(); bfs_q.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D && !accessible[ni][nj] && is_empty[ni][nj]) {\n                    accessible[ni][nj] = true;\n                    bfs_q.push({ni, nj});\n                }\n            }\n        }\n        \n        int min_t = M + 1, min_i = -1, min_j = -1;\n        for (int i = 0; i < D; i++)\n            for (int j = 0; j < D; j++)\n                if (container_at[i][j] >= 0 && accessible[i][j] && container_at[i][j] < min_t) {\n                    min_t = container_at[i][j];\n                    min_i = i; min_j = j;\n                }\n        \n        cout << min_i << \" \" << min_j << endl;\n        is_empty[min_i][min_j] = true;\n        container_at[min_i][min_j] = -1;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\nconst int dx[] = {0, 0, 1, -1};\nconst int dy[] = {1, -1, 0, 0};\n\nint n, m;\nint grid[N][N], best_grid[N][N];\nint best_score;\nset<pair<int,int>> required_adj;\nint adj_cnt[M+1][M+1];\n\nbool valid(int x, int y) { return 0 <= x && x < n && 0 <= y && y < n; }\n\nvoid compute_init_adj() {\n    memset(adj_cnt, 0, sizeof(adj_cnt));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) {\n            if (j+1 < n && grid[i][j] != grid[i][j+1])\n                adj_cnt[min(grid[i][j],grid[i][j+1])][max(grid[i][j],grid[i][j+1])]++;\n            if (i+1 < n && grid[i][j] != grid[i+1][j])\n                adj_cnt[min(grid[i][j],grid[i+1][j])][max(grid[i][j],grid[i+1][j])]++;\n            if (i==0||i==n-1||j==0||j==n-1)\n                adj_cnt[0][grid[i][j]]++;\n        }\n    for (int a = 0; a <= m; a++)\n        for (int b = a; b <= m; b++)\n            if (adj_cnt[a][b] > 0) required_adj.insert({a,b});\n}\n\nbool check_c0_conn() {\n    bool has0 = false;\n    for (int i = 0; i < n && !has0; i++)\n        for (int j = 0; j < n && !has0; j++)\n            if (grid[i][j] == 0) has0 = true;\n    if (!has0) return true;\n    \n    vector<vector<bool>> vis(n, vector<bool>(n));\n    queue<pair<int,int>> q;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (grid[i][j] == 0 && (i==0||i==n-1||j==0||j==n-1))\n                { q.push({i,j}); vis[i][j] = true; }\n    \n    while (!q.empty()) {\n        auto [x,y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx=x+dx[d], ny=y+dy[d];\n            if (valid(nx,ny) && !vis[nx][ny] && grid[nx][ny]==0)\n                { vis[nx][ny] = true; q.push({nx,ny}); }\n        }\n    }\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (grid[i][j] == 0 && !vis[i][j]) return false;\n    return true;\n}\n\nbool can_change(int i, int j, int nc) {\n    int oc = grid[i][j];\n    if (oc == nc) return true;\n    if (nc != 0) {\n        bool found = false;\n        for (int d = 0; d < 4; d++) {\n            int ni=i+dx[d], nj=j+dy[d];\n            if (valid(ni,nj) && grid[ni][nj] == nc) { found = true; break; }\n        }\n        if (!found) return false;\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        if (valid(ni,nj)) {\n            int c = grid[ni][nj];\n            if (oc != c) delta[{min(oc,c),max(oc,c)}]--;\n            if (nc != c) delta[{min(nc,c),max(nc,c)}]++;\n        }\n    }\n    if (i==0||i==n-1||j==0||j==n-1) {\n        if (oc != 0) delta[{0,oc}]--;\n        if (nc != 0) delta[{0,nc}]++;\n    }\n    for (auto& [p,d] : delta) {\n        int ncnt = adj_cnt[p.first][p.second] + d;\n        if (ncnt > 0 && required_adj.find(p) == required_adj.end()) return false;\n        if (ncnt <= 0 && required_adj.find(p) != required_adj.end()) return false;\n    }\n    grid[i][j] = nc;\n    bool ok = check_c0_conn();\n    grid[i][j] = oc;\n    return ok;\n}\n\nvoid apply_change(int i, int j, int nc) {\n    int oc = grid[i][j];\n    for (int d = 0; d < 4; d++) {\n        int ni=i+dx[d], nj=j+dy[d];\n        if (valid(ni,nj)) {\n            int c = grid[ni][nj];\n            if (oc != c) adj_cnt[min(oc,c)][max(oc,c)]--;\n            if (nc != c) adj_cnt[min(nc,c)][max(nc,c)]++;\n        }\n    }\n    if (i==0||i==n-1||j==0||j==n-1) {\n        if (oc != 0) adj_cnt[0][oc]--;\n        if (nc != 0) adj_cnt[0][nc]++;\n    }\n    grid[i][j] = nc;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> n >> m;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) cin >> grid[i][j];\n    \n    compute_init_adj();\n    memcpy(best_grid, grid, sizeof(grid));\n    best_score = 2501;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (grid[i][j] == 0) best_score++;\n    \n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < n; i++)\n            for (int j = 0; j < n; j++)\n                if (grid[i][j] == 0) {\n                    for (int d = 0; d < 4; d++) {\n                        int ni=i+dx[d], nj=j+dy[d];\n                        if (valid(ni,nj) && grid[ni][nj] != 0)\n                            if (can_change(i, j, grid[ni][nj])) {\n                                apply_change(i, j, grid[ni][nj]);\n                                improved = true;\n                                break;\n                            }\n                    }\n                }\n    }\n    \n    int cnt0 = 0;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (grid[i][j] == 0) cnt0++;\n    if (cnt0+1 < best_score) {\n        best_score = cnt0+1;\n        memcpy(best_grid, grid, sizeof(grid));\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << best_grid[i][j];\n            if (j < n-1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\nint N, D, Q;\nint qc = 0;\nint cmp[105][105];\n\nchar query(int a, int b) {\n    if (cmp[a][b] != 0) return cmp[a][b] == 1 ? '>' : '<';\n    if (qc >= Q) return '=';\n    \n    qc++;\n    cout << \"1 1 \" << a << \" \" << b << endl;\n    char res;\n    cin >> res;\n    \n    if (res == '<') {\n        cmp[a][b] = -1;\n        cmp[b][a] = 1;\n    } else if (res == '>') {\n        cmp[a][b] = 1;\n        cmp[b][a] = -1;\n    }\n    return res;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    for (int i = 0; i < N; i++) items[i] = i;\n    \n    // Insertion sort using comparisons\n    for (int i = 1; i < N; i++) {\n        int j = i;\n        while (j > 0 && qc < Q) {\n            int a = items[j-1], b = items[j];\n            if (cmp[a][b] == 1) {\n                swap(items[j-1], items[j]);\n                j--;\n            } else if (cmp[a][b] == -1) {\n                break;\n            } else {\n                char res = query(a, b);\n                if (res == '>') {\n                    swap(items[j-1], items[j]);\n                    j--;\n                } else {\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Use remaining queries to verify sort\n    for (int i = 1; i < N && qc < Q; i++) {\n        if (cmp[items[i-1]][items[i]] == 0) {\n            query(items[i-1], items[i]);\n        }\n    }\n    \n    // Use remaining queries for random comparisons\n    mt19937 rng(42);\n    while (qc < Q) {\n        int x = rng() % N, y = rng() % N;\n        if (x != y && cmp[x][y] == 0) {\n            query(x, y);\n        }\n    }\n    \n    // Estimate weights using exponential distribution assumption\n    vector<double> est_weight(N);\n    for (int i = 0; i < N; i++) {\n        double p = (double)(i + 1) / (N + 1);\n        est_weight[items[i]] = -log(1.0 - p);\n    }\n    \n    // LPT partitioning: assign heaviest items first to lightest group\n    vector<double> group_weight(D, 0);\n    vector<int> assignment(N);\n    \n    for (int i = N - 1; i >= 0; i--) {\n        int item = items[i];\n        int min_group = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_weight[g] < group_weight[min_group]) {\n                min_group = g;\n            }\n        }\n        assignment[item] = min_group;\n        group_weight[min_group] += est_weight[item];\n    }\n    \n    // Output assignment\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n        }\n    }\n    \n    vector<int> box_stack(n + 1), box_pos(n + 1);\n    for (int i = 0; i < m; i++) {\n        for (int j = 0; j < (int)stacks[i].size(); j++) {\n            box_stack[stacks[i][j]] = i;\n            box_pos[stacks[i][j]] = j;\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    \n    for (int v = 1; v <= n; v++) {\n        int sid = box_stack[v], pos = box_pos[v];\n        \n        while ((int)stacks[sid].size() > pos + 1) {\n            int top_idx = stacks[sid].size() - 1;\n            int seg_start = top_idx;\n            \n            while (seg_start > pos + 1 && stacks[sid][seg_start - 1] > stacks[sid][seg_start])\n                seg_start--;\n            \n            int max_in_seg = stacks[sid][seg_start];\n            int dest = -1;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == sid) continue;\n                if (stacks[i].empty()) { dest = i; break; }\n            }\n            \n            if (dest == -1) {\n                int max_top = -1;\n                for (int i = 0; i < m; i++) {\n                    if (i == sid) continue;\n                    if (!stacks[i].empty() && stacks[i].back() > max_in_seg && stacks[i].back() > max_top) {\n                        max_top = stacks[i].back();\n                        dest = i;\n                    }\n                }\n            }\n            \n            if (dest == -1) {\n                int max_top = -1;\n                for (int i = 0; i < m; i++) {\n                    if (i == sid) continue;\n                    if (!stacks[i].empty() && stacks[i].back() > max_top) {\n                        max_top = stacks[i].back();\n                        dest = i;\n                    }\n                }\n            }\n            \n            if (dest == -1) dest = (sid + 1) % m;\n            \n            int u = stacks[sid][seg_start];\n            operations.push_back({u, dest + 1});\n            \n            vector<int> moved(stacks[sid].begin() + seg_start, stacks[sid].end());\n            stacks[sid].resize(seg_start);\n            stacks[dest].insert(stacks[dest].end(), moved.begin(), moved.end());\n            \n            for (int j = 0; j < (int)moved.size(); j++) {\n                box_stack[moved[j]] = dest;\n                box_pos[moved[j]] = stacks[dest].size() - moved.size() + j;\n            }\n        }\n        \n        operations.push_back({v, 0});\n        stacks[sid].pop_back();\n    }\n    \n    for (auto& op : operations) {\n        cout << op.first << \" \" << op.second << endl;\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\nchar dir_char[] = {'R', 'D', 'L', 'U'};\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + dx[dir], nj = j + dy[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (dir == 0 && v[i][j] == '1') return false;\n    if (dir == 1 && h[i][j] == '1') return false;\n    if (dir == 2 && v[i][nj] == '1') return false;\n    if (dir == 3 && h[ni][j] == '1') return false;\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    h.resize(N - 1); v.resize(N); d.resize(N, vector<int>(N));\n    for (int i = 0; i < N - 1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    vector<vector<int>> dist(N, vector<int>(N, -1)), prev_dir(N, vector<int>(N, -1));\n    queue<pair<int,int>> q; dist[0][0] = 0; q.push({0, 0});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            int ni = i + dx[dir], nj = j + dy[dir];\n            if (dist[ni][nj] == -1) { dist[ni][nj] = dist[i][j] + 1; prev_dir[ni][nj] = dir; q.push({ni, nj}); }\n        }\n    }\n    \n    string result;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        vector<pair<int, int>> neighbors;\n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            int ni = i + dx[dir], nj = j + dy[dir];\n            if (!visited[ni][nj]) neighbors.push_back({ni, nj});\n        }\n        sort(neighbors.begin(), neighbors.end(), [](auto& a, auto& b) { return d[a.first][a.second] > d[b.first][b.second]; });\n        for (auto [ni, nj] : neighbors) {\n            for (int dir = 0; dir < 4; dir++) {\n                if (i + dx[dir] == ni && j + dy[dir] == nj) {\n                    result += dir_char[dir]; dfs(ni, nj); result += dir_char[(dir + 2) % 4]; break;\n                }\n            }\n        }\n    };\n    dfs(0, 0);\n    \n    vector<int> visit_count(N * N, 0);\n    int ci = 0, cj = 0; visit_count[0]++;\n    for (char c : result) {\n        int dir = (c == 'R') ? 0 : (c == 'D') ? 1 : (c == 'L') ? 2 : 3;\n        ci += dx[dir]; cj += dy[dir]; visit_count[ci * N + cj]++;\n    }\n    \n    using Cell = tuple<double, int, int>;\n    priority_queue<Cell> pq;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (i == 0 && j == 0) continue;\n        int k = visit_count[i * N + j];\n        double cost = 2.0 * dist[i][j];\n        if (cost > 0) pq.push({(double)d[i][j] / (k * (k + 1)) / cost, i, j});\n    }\n    \n    while (!pq.empty() && result.size() < 100000) {\n        auto [p, i, j] = pq.top(); pq.pop();\n        int k = visit_count[i * N + j];\n        double cost = 2.0 * dist[i][j];\n        double new_p = (double)d[i][j] / (k * (k + 1)) / cost;\n        if (abs(new_p - p) > 1e-9) { pq.push({new_p, i, j}); continue; }\n        \n        string path_to, path_back;\n        int ci2 = i, cj2 = j;\n        while (ci2 != 0 || cj2 != 0) { int dir = prev_dir[ci2][cj2]; path_to += dir_char[dir]; ci2 -= dx[dir]; cj2 -= dy[dir]; }\n        reverse(path_to.begin(), path_to.end());\n        for (int k2 = path_to.size() - 1; k2 >= 0; k2--) {\n            char c = path_to[k2];\n            path_back += (c == 'R') ? 'L' : (c == 'D') ? 'U' : (c == 'L') ? 'R' : 'D';\n        }\n        string detour = path_to + path_back;\n        if (result.size() + detour.size() <= 100000) {\n            result += detour; visit_count[i * N + j]++;\n            int nk = visit_count[i * N + j];\n            pq.push({(double)d[i][j] / (nk * (nk + 1)) / cost, i, j});\n        }\n    }\n    \n    cout << result << endl;\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; cin >> N >> M;\n    int si, sj; cin >> si >> sj;\n    vector<string> A(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    vector<string> t(M);\n    for (int i = 0; i < M; i++) cin >> t[i];\n    \n    vector<vector<pair<int,int>>> charPos(26);\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            charPos[A[i][j] - 'A'].push_back({i, j});\n    \n    vector<vector<int>> overlap(M, vector<int>(M, 0));\n    for (int i = 0; i < M; i++)\n        for (int j = 0; j < M; j++) {\n            if (i == j) continue;\n            for (int len = 4; len >= 1; len--) {\n                bool match = true;\n                for (int k = 0; k < len; k++)\n                    if (t[i][5 - len + k] != t[j][k]) { match = false; break; }\n                if (match) { overlap[i][j] = len; break; }\n            }\n        }\n    \n    string bestSuper; int bestLen = INT_MAX;\n    for (int start = 0; start < M; start++) {\n        vector<bool> used(M, false);\n        vector<int> order; order.push_back(start); used[start] = true;\n        for (int step = 1; step < M; step++) {\n            int last = order.back(), best_next = -1, best_ov = -1;\n            for (int j = 0; j < M; j++)\n                if (!used[j] && overlap[last][j] > best_ov) { best_ov = overlap[last][j]; best_next = j; }\n            if (best_next == -1) for (int j = 0; j < M; j++) if (!used[j]) { best_next = j; break; }\n            order.push_back(best_next); used[best_next] = true;\n        }\n        string superstr = t[order[0]];\n        for (int i = 1; i < M; i++) superstr += t[order[i]].substr(overlap[order[i-1]][order[i]]);\n        if ((int)superstr.size() < bestLen) { bestLen = superstr.size(); bestSuper = superstr; }\n    }\n    \n    int L = bestSuper.size();\n    auto encode = [](int i, int j) { return i * 15 + j; };\n    auto decodeI = [](int c) { return c / 15; };\n    auto decodeJ = [](int c) { return c % 15; };\n    \n    const int INF = 1e9;\n    vector<vector<pair<int,int>>> dp(L + 1, vector<pair<int,int>>(225, {INF, -1}));\n    dp[0][encode(si, sj)] = {0, -1};\n    \n    for (int i = 0; i < L; i++) {\n        int cidx = bestSuper[i] - 'A';\n        vector<int> finite;\n        for (int q = 0; q < 225; q++) if (dp[i][q].first < INF) finite.push_back(q);\n        for (auto [pi, pj] : charPos[cidx]) {\n            int p = encode(pi, pj);\n            for (int q : finite) {\n                int qi = decodeI(q), qj = decodeJ(q);\n                int newCost = dp[i][q].first + abs(pi - qi) + abs(pj - qj) + 1;\n                if (newCost < dp[i + 1][p].first) dp[i + 1][p] = {newCost, q};\n            }\n        }\n    }\n    \n    int bestEnd = 0, bestCost = INF;\n    for (int p = 0; p < 225; p++)\n        if (dp[L][p].first < bestCost) { bestCost = dp[L][p].first; bestEnd = p; }\n    \n    vector<int> pathPos(L);\n    int curr = bestEnd;\n    for (int i = L - 1; i >= 0; i--) { pathPos[i] = curr; curr = dp[i + 1][curr].second; }\n    \n    for (int i = 0; i < L; i++)\n        cout << decodeI(pathPos[i]) << \" \" << decodeJ(pathPos[i]) << \"\\n\";\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<vector<pair<int,int>>> shapes;\nvector<int> max_di, max_dj;\nvector<vector<pair<int,int>>> positions;\nvector<vector<vector<pair<int,int>>>> pos_cells;\nint known[25][25];\nint query_count = 0;\nvector<vector<double>> w;\ndouble cov[25][25];\n\nint drill_cell(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int v; cin >> v;\n    known[i][j] = v;\n    query_count++;\n    return v;\n}\n\nint divine_cells(vector<pair<int,int>>& cells) {\n    int k = cells.size();\n    cout << \"q \" << k;\n    for (auto& [i, j] : cells) cout << \" \" << i << \" \" << j;\n    cout << endl;\n    cout.flush();\n    int v; cin >> v;\n    query_count++;\n    return v;\n}\n\nvoid submit_answer(vector<pair<int,int>>& cells) {\n    sort(cells.begin(), cells.end());\n    cells.erase(unique(cells.begin(), cells.end()), cells.end());\n    cout << \"a \" << cells.size();\n    for (auto& [i, j] : cells) cout << \" \" << i << \" \" << j;\n    cout << endl;\n    cout.flush();\n    int r; cin >> r;\n    if (r == 1) exit(0);\n}\n\nvoid update_coverage() {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cov[i][j] = 0;\n    for (int k = 0; k < M; k++) {\n        double total = accumulate(w[k].begin(), w[k].end(), 0.0);\n        if (total < 1e-10) continue;\n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            double wt = w[k][p] / total;\n            for (auto& [ci, cj] : pos_cells[k][p]) cov[ci][cj] += wt;\n        }\n    }\n}\n\nvoid update_divine(const vector<pair<int,int>>& qcells, int obs) {\n    int ksz = qcells.size();\n    set<pair<int,int>> cs(qcells.begin(), qcells.end());\n    for (int k = 0; k < M; k++) {\n        double others = 0;\n        for (int k2 = 0; k2 < M; k2++) if (k2 != k) {\n            double t2 = accumulate(w[k2].begin(), w[k2].end(), 0.0);\n            if (t2 < 1e-10) continue;\n            for (int p2 = 0; p2 < (int)positions[k2].size(); p2++) {\n                int cnt = 0;\n                for (auto& [ci, cj] : pos_cells[k2][p2]) if (cs.count({ci, cj})) cnt++;\n                others += w[k2][p2] / t2 * cnt;\n            }\n        }\n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            int cnt = 0;\n            for (auto& [ci, cj] : pos_cells[k][p]) if (cs.count({ci, cj})) cnt++;\n            double ev = others + cnt;\n            double mean = ksz * eps + ev * (1 - 2 * eps);\n            double var = ksz * eps * (1 - eps);\n            double diff = obs - mean;\n            w[k][p] *= exp(-diff * diff / (2 * var));\n        }\n        double total = accumulate(w[k].begin(), w[k].end(), 0.0);\n        if (total > 1e-10) for (auto& wp : w[k]) wp /= total;\n    }\n    update_coverage();\n}\n\nvoid update_drill(int i, int j, int obs) {\n    for (int k = 0; k < M; k++) {\n        double others = 0;\n        for (int k2 = 0; k2 < M; k2++) if (k2 != k) {\n            double t2 = accumulate(w[k2].begin(), w[k2].end(), 0.0);\n            if (t2 < 1e-10) continue;\n            for (int p2 = 0; p2 < (int)positions[k2].size(); p2++)\n                for (auto& [ci, cj] : pos_cells[k2][p2])\n                    if (ci == i && cj == j) { others += w[k2][p2] / t2; break; }\n        }\n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            bool covers = false;\n            for (auto& [ci, cj] : pos_cells[k][p]) if (ci == i && cj == j) { covers = true; break; }\n            double ev = others + (covers ? 1.0 : 0.0);\n            double diff = obs - ev;\n            double var = max(0.3, ev * 0.5);\n            w[k][p] *= exp(-diff * diff / (2 * var));\n        }\n        double total = accumulate(w[k].begin(), w[k].end(), 0.0);\n        if (total > 1e-10) for (auto& wp : w[k]) wp /= total;\n    }\n    update_coverage();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M >> eps;\n    shapes.resize(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int l = 0; l < d; l++) cin >> shapes[k][l].first >> shapes[k][l].second;\n    }\n    max_di.resize(M); max_dj.resize(M);\n    for (int k = 0; k < M; k++) {\n        max_di[k] = max_dj[k] = 0;\n        for (auto& [i, j] : shapes[k]) { max_di[k] = max(max_di[k], i); max_dj[k] = max(max_dj[k], j); }\n    }\n    for (int k = 0; k < M; k++) {\n        vector<pair<int,int>> pos;\n        vector<vector<pair<int,int>>> cells;\n        for (int di = 0; di <= N - 1 - max_di[k]; di++)\n            for (int dj = 0; dj <= N - 1 - max_dj[k]; dj++) {\n                pos.push_back({di, dj});\n                vector<pair<int,int>> c;\n                for (auto& [i, j] : shapes[k]) c.push_back({di + i, dj + j});\n                cells.push_back(c);\n            }\n        positions.push_back(pos);\n        pos_cells.push_back(cells);\n    }\n    memset(known, -1, sizeof(known));\n    for (int k = 0; k < M; k++) w.push_back(vector<double>(positions[k].size(), 1.0));\n    update_coverage();\n    \n    for (int i = 0; i < N && query_count < 2*N*N; i++) {\n        vector<pair<int,int>> cells;\n        for (int j = 0; j < N; j++) cells.push_back({i, j});\n        update_divine(cells, divine_cells(cells));\n    }\n    for (int j = 0; j < N && query_count < 2*N*N; j++) {\n        vector<pair<int,int>> cells;\n        for (int i = 0; i < N; i++) cells.push_back({i, j});\n        update_divine(cells, divine_cells(cells));\n    }\n    \n    while (query_count < 2*N*N - 1) {\n        int bi = -1, bj = -1; double bs = -1e9;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (known[i][j] >= 0) continue;\n            double p = 1.0 - exp(-cov[i][j]); p = max(0.01, min(0.99, p));\n            double ent = -p*log(p) - (1-p)*log(1-p);\n            if (ent > bs) { bs = ent; bi = i; bj = j; }\n        }\n        if (bi < 0) break;\n        update_drill(bi, bj, drill_cell(bi, bj));\n    }\n    \n    vector<pair<int,int>> ans;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (known[i][j] > 0) ans.push_back({i, j});\n        else if (known[i][j] < 0 && 1.0 - exp(-cov[i][j]) > 0.5) ans.push_back({i, j});\n    }\n    submit_answer(ans);\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\nint main() {\n    ios_base::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    // Compute max required heights across all days for zero deficit\n    vector<int> max_required_h(N, 0);\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            int min_h = (a[d][k] + W - 1) / W;\n            max_required_h[k] = max(max_required_h[k], min_h);\n        }\n    }\n    \n    long long total_max_h = accumulate(max_required_h.begin(), max_required_h.end(), 0LL);\n    \n    vector<int> fixed_h(N);\n    \n    if (total_max_h <= W) {\n        // Fixed heights work - zero deficit and zero partition changes\n        fixed_h = max_required_h;\n        int remaining = W - total_max_h;\n        // Distribute remaining space starting from largest strip\n        int k = N - 1;\n        while (remaining > 0) {\n            fixed_h[k]++;\n            remaining--;\n            k = (k - 1 + N) % N;\n        }\n    } else {\n        // Need to scale down - accept some deficit but still zero partition changes\n        for (int k = 0; k < N; k++) {\n            fixed_h[k] = max(1, (int)(max_required_h[k] * W / total_max_h));\n        }\n        int total_h = accumulate(fixed_h.begin(), fixed_h.end(), 0);\n        int k = N - 1;\n        while (total_h < W) {\n            fixed_h[k]++;\n            total_h++;\n            k = (k - 1 + N) % N;\n        }\n        while (total_h > W) {\n            for (int j = 0; j < N && total_h > W; j++) {\n                if (fixed_h[j] > 1) {\n                    fixed_h[j]--;\n                    total_h--;\n                }\n            }\n        }\n    }\n    \n    // Output using fixed heights\n    for (int d = 0; d < D; d++) {\n        int y = 0;\n        for (int k = 0; k < N; k++) {\n            cout << y << \" 0 \" << y + fixed_h[k] << \" \" << W << \"\\n\";\n            y += fixed_h[k];\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\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    vector<vector<long long>> bmod(N, vector<long long>(N));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cin >> bmod[i][j];\n    \n    vector<vector<vector<long long>>> s(M, vector<vector<long long>>(3, vector<long long>(3)));\n    for (int m = 0; m < M; m++)\n        for (int i = 0; i < 3; i++)\n            for (int j = 0; j < 3; j++)\n                cin >> s[m][i][j];\n    \n    vector<tuple<int, int, int>> ops;\n    \n    for (int k = 0; k < K; k++) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        long long best_delta = LLONG_MIN;\n        \n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    long long delta = 0;\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            long long new_mod = (bmod[p + i][q + j] + s[m][i][j]) % MOD;\n                            delta += new_mod - bmod[p + i][q + j];\n                        }\n                    }\n                    if (delta > best_delta) {\n                        best_delta = delta;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        if (best_delta <= 0) break;\n        \n        ops.push_back({best_m, best_p, best_q});\n        for (int i = 0; i < 3; i++)\n            for (int j = 0; j < 3; j++)\n                bmod[best_p + i][best_q + j] = (bmod[best_p + i][best_q + j] + s[best_m][i][j]) % MOD;\n    }\n    \n    cout << ops.size() << endl;\n    for (auto& [m, p, q] : ops)\n        cout << m << \" \" << p << \" \" << q << endl;\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <climits>\n#include <cstdlib>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N];\nint container_recv_row[N*N], container_recv_idx[N*N];\nbool container_dispatched[N*N];\n\nint next_expected(int gate) {\n    for (int j = 0; j < N; j++)\n        if (!container_dispatched[N * gate + j]) return N * gate + j;\n    return -1;\n}\n\nint main() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n            container_recv_row[A[i][j]] = i;\n            container_recv_idx[A[i][j]] = j;\n        }\n    fill(container_dispatched, container_dispatched + N*N, false);\n    \n    int grid[N][N]; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) grid[i][j] = -1;\n    int crane_r = 0, crane_c = 0, crane_holding = -1;\n    int next_receive[N] = {}, total_dispatched = 0;\n    vector<string> actions(N, \"\");\n    \n    for (int turn = 1; total_dispatched < N*N && turn < 10000; turn++) {\n        for (int i = 0; i < N; i++)\n            if (next_receive[i] < N && grid[i][0] == -1 && !(crane_r == i && crane_c == 0 && crane_holding != -1)) {\n                grid[i][0] = A[i][next_receive[i]++];\n            }\n        \n        char act = '.';\n        if (crane_holding != -1) {\n            int dr = crane_holding / N, exp = next_expected(dr);\n            int tr, tc;\n            if (exp != -1 && crane_holding == exp) { tr = dr; tc = N-1; }\n            else {\n                tr = tc = -1; int bd = INT_MAX;\n                for (int c = 1; c < N-1; c++) for (int r = 0; r < N; r++)\n                    if (grid[r][c] == -1) { int d = abs(crane_r-r)+abs(crane_c-c); if (d < bd) { bd=d; tr=r; tc=c; } }\n                if (tr == -1) { tr = dr; tc = N-1; }\n            }\n            if (crane_r == tr && crane_c == tc) { act = 'Q'; grid[tr][tc] = crane_holding; crane_holding = -1; }\n            else { if (crane_r < tr) { crane_r++; act='D'; } else if (crane_r > tr) { crane_r--; act='U'; } else if (crane_c < tc) { crane_c++; act='R'; } else { crane_c--; act='L'; } }\n        } else {\n            int bc = -1, bs = INT_MAX, br = -1, bcc = -1;\n            for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) {\n                if (grid[r][c] == -1 || container_dispatched[grid[r][c]]) continue;\n                int cont = grid[r][c], dr = cont / N, exp = next_expected(dr);\n                int dp = abs(crane_r-r)+abs(crane_c-c), sc;\n                if (exp != -1 && cont == exp) sc = dp + abs(r-dr)+abs(c-(N-1));\n                else {\n                    int mt = INT_MAX;\n                    for (int tc=1; tc<N-1; tc++) for (int tr=0; tr<N; tr++) if (grid[tr][tc]==-1) mt=min(mt,abs(r-tr)+abs(c-tc));\n                    sc = (mt == INT_MAX) ? INT_MAX : dp + mt + 500;\n                    if (c == 0 && next_receive[r] < N) sc -= 200;\n                }\n                if (sc < bs) { bs=sc; bc=cont; br=r; bcc=c; }\n            }\n            if (bc != -1 && bs < INT_MAX) {\n                if (crane_r == br && crane_c == bcc) { act='P'; crane_holding=bc; grid[br][bcc]=-1; }\n                else { if (crane_r<br) { crane_r++; act='D'; } else if (crane_r>br) { crane_r--; act='U'; } else if (crane_c<bcc) { crane_c++; act='R'; } else { crane_c--; act='L'; } }\n            }\n        }\n        actions[0] += act;\n        for (int i = 1; i < N; i++) actions[i] += (turn == 1 ? 'B' : '.');\n        \n        for (int i = 0; i < N; i++)\n            if (grid[i][N-1] != -1) { container_dispatched[grid[i][N-1]] = true; grid[i][N-1] = -1; total_dispatched++; }\n    }\n    \n    int ml = 0; for (int i = 0; i < N; i++) ml = max(ml, (int)actions[i].size());\n    for (int i = 0; i < N; i++) { while ((int)actions[i].size() < ml) actions[i] += '.'; cout << actions[i] << endl; }\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <climits>\n\nusing namespace std;\n\nconst int INF = 1e9;\n\nstruct Edge { int to, cap, cost, flow, rev; };\n\nclass MinCostFlow {\npublic:\n    int n;\n    vector<vector<Edge>> graph;\n    MinCostFlow(int n) : n(n), graph(n) {}\n    \n    void add_edge(int from, int to, int cap, int cost) {\n        graph[from].push_back({to, cap, cost, 0, (int)graph[to].size()});\n        graph[to].push_back({from, 0, -cost, 0, (int)graph[from].size() - 1});\n    }\n    \n    int min_cost_flow(int s, int t, int maxf) {\n        int res = 0;\n        vector<int> h(n), prevv(n), preve(n);\n        int flow = 0;\n        while (flow < maxf) {\n            priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;\n            vector<int> dist(n, INF);\n            dist[s] = 0;\n            pq.push({0, s});\n            while (!pq.empty()) {\n                auto [d, v] = pq.top(); pq.pop();\n                if (dist[v] < d) continue;\n                for (int i = 0; i < graph[v].size(); i++) {\n                    Edge& e = graph[v][i];\n                    if (e.cap > e.flow && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {\n                        dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];\n                        prevv[e.to] = v; preve[e.to] = i;\n                        pq.push({dist[e.to], e.to});\n                    }\n                }\n            }\n            if (dist[t] == INF) break;\n            for (int v = 0; v < n; v++) h[v] += dist[v];\n            int d = maxf - flow;\n            for (int v = t; v != s; v = prevv[v])\n                d = min(d, graph[prevv[v]][preve[v]].cap - graph[prevv[v]][preve[v]].flow);\n            flow += d; res += d * h[t];\n            for (int v = t; v != s; v = prevv[v]) {\n                Edge& e = graph[prevv[v]][preve[v]];\n                e.flow += d; graph[v][e.rev].flow -= d;\n            }\n        }\n        return res;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n    int n; cin >> n;\n    vector<vector<int>> h(n, vector<int>(n));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) cin >> h[i][j];\n    \n    vector<string> ops;\n    int r = 0, c = 0, load = 0;\n    int remaining = 0;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (h[i][j] > 0) remaining += h[i][j];\n    \n    while (ops.size() < 100000 && remaining > 0) {\n        if (h[r][c] > 0) {\n            ops.push_back(\"+\" + to_string(h[r][c]));\n            load += h[r][c]; remaining -= h[r][c]; h[r][c] = 0;\n        }\n        while (h[r][c] < 0 && load > 0) {\n            int d = min(load, -h[r][c]);\n            ops.push_back(\"-\" + to_string(d));\n            load -= d; h[r][c] += d;\n        }\n        if (remaining == 0) break;\n        \n        int best_r = -1, best_c = -1, best_dist = INT_MAX;\n        if (load > 0) {\n            for (int i = 0; i < n; i++)\n                for (int j = 0; j < n; j++)\n                    if (h[i][j] < 0) {\n                        int dist = abs(r - i) + abs(c - j);\n                        if (dist < best_dist) { best_dist = dist; best_r = i; best_c = j; }\n                    }\n        }\n        if (best_r == -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 dist = abs(r - i) + abs(c - j);\n                        if (dist < best_dist) { best_dist = dist; best_r = i; best_c = j; }\n                    }\n        }\n        if (best_r == -1) break;\n        \n        if (best_r < r) { r--; ops.push_back(\"U\"); }\n        else if (best_r > r) { r++; ops.push_back(\"D\"); }\n        else if (best_c < c) { c--; ops.push_back(\"L\"); }\n        else { c++; ops.push_back(\"R\"); }\n    }\n    \n    for (auto& op : ops) cout << op << \"\\n\";\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 6, M = 15;\n    const int SEED_COUNT = 2 * N * (N - 1);\n    const int GRID_SIZE = N * N;\n    \n    int n, m, t;\n    cin >> n >> m >> t;\n    \n    vector<vector<int>> X(SEED_COUNT, vector<int>(M));\n    for (int i = 0; i < SEED_COUNT; i++)\n        for (int j = 0; j < M; j++)\n            cin >> X[i][j];\n    \n    vector<pair<int,int>> edges;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N-1; j++)\n            edges.push_back({i*N+j, i*N+j+1});\n    for (int i = 0; i < N-1; i++)\n        for (int j = 0; j < N; j++)\n            edges.push_back({i*N+j, (i+1)*N+j});\n    \n    vector<vector<int>> posEdges(GRID_SIZE);\n    for (int e = 0; e < (int)edges.size(); e++) {\n        posEdges[edges[e].first].push_back(e);\n        posEdges[edges[e].second].push_back(e);\n    }\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> unif(0.0, 1.0);\n    \n    for (int turn = 0; turn < t; turn++) {\n        vector<int> values(SEED_COUNT);\n        for (int i = 0; i < SEED_COUNT; i++)\n            for (int j = 0; j < M; j++)\n                values[i] += X[i][j];\n        \n        vector<int> indices(SEED_COUNT);\n        iota(indices.begin(), indices.end(), 0);\n        sort(indices.begin(), indices.end(), [&](int a, int b) { return values[a] > values[b]; });\n        vector<int> selected(indices.begin(), indices.begin() + GRID_SIZE);\n        \n        vector<vector<int>> pot(GRID_SIZE, vector<int>(GRID_SIZE, 0));\n        for (int i = 0; i < GRID_SIZE; i++)\n            for (int j = i+1; j < GRID_SIZE; j++) {\n                int a = selected[i], b = selected[j];\n                for (int l = 0; l < M; l++)\n                    pot[i][j] += max(X[a][l], X[b][l]);\n                pot[j][i] = pot[i][j];\n            }\n        \n        vector<int> placement(GRID_SIZE);\n        iota(placement.begin(), placement.end(), 0);\n        \n        int currentScore = 0;\n        for (auto& [u,v] : edges)\n            currentScore += pot[placement[u]][placement[v]];\n        \n        int bestScore = currentScore;\n        vector<int> bestPlacement = placement;\n        \n        auto startTime = chrono::high_resolution_clock::now();\n        const double startTemp = 500.0, endTemp = 0.1;\n        \n        for (int iter = 0; iter < 10000000; iter++) {\n            auto now = chrono::high_resolution_clock::now();\n            auto elapsed = chrono::duration_cast<chrono::microseconds>(now - startTime).count();\n            if (elapsed > 180000) break;\n            \n            double progress = (double)elapsed / 180000.0;\n            double temp = startTemp * pow(endTemp / startTemp, progress);\n            \n            int i = rng() % GRID_SIZE, j = rng() % GRID_SIZE;\n            if (i == j) continue;\n            \n            int delta = 0;\n            for (int e : posEdges[i]) { auto& [u,v] = edges[e]; delta -= pot[placement[u]][placement[v]]; }\n            for (int e : posEdges[j]) { auto& [u,v] = edges[e]; delta -= pot[placement[u]][placement[v]]; }\n            \n            swap(placement[i], placement[j]);\n            \n            for (int e : posEdges[i]) { auto& [u,v] = edges[e]; delta += pot[placement[u]][placement[v]]; }\n            for (int e : posEdges[j]) { auto& [u,v] = edges[e]; delta += pot[placement[u]][placement[v]]; }\n            \n            if (delta >= 0 || unif(rng) < exp((double)delta / temp)) {\n                currentScore += delta;\n                if (currentScore > bestScore) { bestScore = currentScore; bestPlacement = placement; }\n            } else {\n                swap(placement[i], placement[j]);\n            }\n        }\n        \n        placement = bestPlacement;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << selected[placement[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;\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\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), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n    \n    int Vp = V;\n    vector<int> len(Vp, 1);\n    \n    cout << Vp << \"\\n\";\n    for (int i = 1; i < Vp; i++) cout << 0 << \" \" << len[i] << \"\\n\";\n    \n    int rx = N/2, ry = N/2;\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<vector<int>> grid(N, vector<int>(N)), target(N, vector<int>(N));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = s[i][j] - '0';\n            target[i][j] = t[i][j] - '0';\n        }\n    \n    vector<int> dir(Vp, 0);\n    vector<bool> holding(Vp, false);\n    vector<string> ops;\n    \n    auto addOp = [&](string op) { ops.push_back(op); };\n    \n    while (true) {\n        int sx=-1, sy=-1, best=INT_MAX;\n        for (int i=0; i<N; i++)\n            for (int j=0; j<N; j++)\n                if (grid[i][j] && !target[i][j]) {\n                    int d = abs(rx-i)+abs(ry-j);\n                    if (d < best) { best=d; sx=i; sy=j; }\n                }\n        if (sx==-1) break;\n        \n        int tx=-1, ty=-1; best=INT_MAX;\n        for (int i=0; i<N; i++)\n            for (int j=0; j<N; j++)\n                if (!grid[i][j] && target[i][j]) {\n                    int d = abs(sx-i)+abs(sy-j);\n                    if (d < best) { best=d; tx=i; ty=j; }\n                }\n        if (tx==-1) break;\n        \n        int f=1, L=len[f];\n        \n        int tRx, tRy, tDir; best=INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx=sx-dx[d]*L, ny=sy-dy[d]*L;\n            if (0<=nx&&nx<N&&0<=ny&&ny<N) {\n                int dist=abs(rx-nx)+abs(ry-ny);\n                if (dist<best) { best=dist; tRx=nx; tRy=ny; tDir=d; }\n            }\n        }\n        \n        while (rx!=tRx||ry!=tRy) {\n            string op(2*Vp, '.');\n            if (rx<tRx) { op[0]='D'; rx++; }\n            else if (rx>tRx) { op[0]='U'; rx--; }\n            else if (ry<tRy) { op[0]='R'; ry++; }\n            else { op[0]='L'; ry--; }\n            addOp(op);\n        }\n        \n        while (dir[f]!=tDir) {\n            string op(2*Vp, '.');\n            int diff=(tDir-dir[f]+4)%4;\n            if (diff<=2) { op[f]='R'; dir[f]=(dir[f]+1)%4; }\n            else { op[f]='L'; dir[f]=(dir[f]+3)%4; }\n            addOp(op);\n        }\n        \n        { string op(2*Vp, '.'); op[Vp+f]='P'; holding[f]=true; grid[sx][sy]=0; addOp(op); }\n        \n        best=INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx=tx-dx[d]*L, ny=ty-dy[d]*L;\n            if (0<=nx&&nx<N&&0<=ny&&ny<N) {\n                int dist=abs(rx-nx)+abs(ry-ny);\n                if (dist<best) { best=dist; tRx=nx; tRy=ny; tDir=d; }\n            }\n        }\n        \n        while (rx!=tRx||ry!=tRy) {\n            string op(2*Vp, '.');\n            if (rx<tRx) { op[0]='D'; rx++; }\n            else if (rx>tRx) { op[0]='U'; rx--; }\n            else if (ry<tRy) { op[0]='R'; ry++; }\n            else { op[0]='L'; ry--; }\n            addOp(op);\n        }\n        \n        while (dir[f]!=tDir) {\n            string op(2*Vp, '.');\n            int diff=(tDir-dir[f]+4)%4;\n            if (diff<=2) { op[f]='R'; dir[f]=(dir[f]+1)%4; }\n            else { op[f]='L'; dir[f]=(dir[f]+3)%4; }\n            addOp(op);\n        }\n        \n        { string op(2*Vp, '.'); op[Vp+f]='P'; holding[f]=false; grid[tx][ty]=1; addOp(op); }\n    }\n    \n    for (auto& op : ops) cout << op << \"\\n\";\n    return 0;\n}","ahc039":"#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;\n    cin >> N;\n    \n    vector<int> x(2*N), y(2*N);\n    for (int i = 0; i < 2*N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    int gridSize = 100;\n    int cellSize = 1001;\n    \n    vector<vector<int>> grid(gridSize, vector<int>(gridSize, 0));\n    for (int i = 0; i < 2*N; i++) {\n        int gx = min(x[i] / cellSize, gridSize - 1);\n        int gy = min(y[i] / cellSize, gridSize - 1);\n        grid[gx][gy] += (i < N) ? 1 : -1;\n    }\n    \n    vector<vector<int>> prefix(gridSize + 1, vector<int>(gridSize + 1, 0));\n    for (int i = 0; i < gridSize; i++) {\n        for (int j = 0; j < gridSize; j++) {\n            prefix[i + 1][j + 1] = grid[i][j] + prefix[i][j + 1] + prefix[i + 1][j] - prefix[i][j];\n        }\n    }\n    \n    auto gridRectScore = [&](int x1, int y1, int x2, int y2) -> int {\n        return prefix[x2 + 1][y2 + 1] - prefix[x1][y2 + 1] - prefix[x2 + 1][y1] + prefix[x1][y1];\n    };\n    \n    int bestGridScore = 0;\n    int bestGX1 = 0, bestGY1 = 0, bestGX2 = 0, bestGY2 = 0;\n    \n    for (int gx1 = 0; gx1 < gridSize; gx1++) {\n        for (int gx2 = gx1; gx2 < gridSize; gx2++) {\n            int bestY = 0, curY = 0;\n            int bestGY1c = 0, bestGY2c = -1;\n            int curGY1 = 0;\n            \n            for (int gy2 = 0; gy2 < gridSize; gy2++) {\n                curY += gridRectScore(gx1, gy2, gx2, gy2);\n                \n                if (curY > bestY) {\n                    bestY = curY;\n                    bestGY1c = curGY1;\n                    bestGY2c = gy2;\n                }\n                if (curY < 0) {\n                    curY = 0;\n                    curGY1 = gy2 + 1;\n                }\n            }\n            \n            if (bestY > bestGridScore) {\n                bestGridScore = bestY;\n                bestGX1 = gx1;\n                bestGX2 = gx2;\n                bestGY1 = bestGY1c;\n                bestGY2 = bestGY2c;\n            }\n        }\n    }\n    \n    int bestX1 = bestGX1 * cellSize;\n    int bestY1 = bestGY1 * cellSize;\n    int bestX2 = min((bestGX2 + 1) * cellSize - 1, 100000);\n    int bestY2 = min((bestGY2 + 1) * cellSize - 1, 100000);\n    \n    cout << 4 << endl;\n    if (bestGridScore > 0) {\n        cout << bestX1 << \" \" << bestY1 << endl;\n        cout << bestX2 << \" \" << bestY1 << endl;\n        cout << bestX2 << \" \" << bestY2 << endl;\n        cout << bestX1 << \" \" << bestY2 << endl;\n    } else {\n        cout << 50000 << \" \" << 50000 << endl;\n        cout << 50001 << \" \" << 50000 << endl;\n        cout << 50001 << \" \" << 50001 << endl;\n        cout << 50000 << \" \" << 50001 << endl;\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, sigma;\nvector<long long> w_obs, h_obs;\nvector<double> w_est, h_est;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> T >> sigma;\n    w_obs.resize(N); h_obs.resize(N);\n    w_est.resize(N); h_est.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w_obs[i] >> h_obs[i];\n        w_est[i] = w_obs[i];\n        h_est[i] = h_obs[i];\n    }\n    \n    mt19937 rng(42);\n    \n    for (int t = 0; t < T; t++) {\n        vector<int> px, py, pw, ph;\n        vector<tuple<int,int,char,int>> output;\n        \n        auto getW = [&]() { long long W=0; for(int i=0;i<(int)px.size();i++) W=max(W,(long long)px[i]+pw[i]); return W; };\n        auto getH = [&]() { long long H=0; for(int i=0;i<(int)py.size();i++) H=max(H,(long long)py[i]+ph[i]); return H; };\n        \n        auto addRect = [&](int rw, int rh, char d, int b) {\n            int rx, ry;\n            if (d == 'U') {\n                rx = (b == -1) ? 0 : px[b] + pw[b];\n                ry = 0;\n                for (int i = 0; i < (int)px.size(); i++)\n                    if (px[i] < rx + rw && px[i] + pw[i] > rx) ry = max(ry, py[i] + ph[i]);\n            } else {\n                ry = (b == -1) ? 0 : py[b] + ph[b];\n                rx = 0;\n                for (int i = 0; i < (int)py.size(); i++)\n                    if (py[i] < ry + rh && py[i] + ph[i] > ry) rx = max(rx, px[i] + pw[i]);\n            }\n            px.push_back(rx); py.push_back(ry); pw.push_back(rw); ph.push_back(rh);\n        };\n        \n        for (int i = 0; i < N; i++) {\n            long long best_score = LLONG_MAX;\n            int best_r = -1; char best_d = 'U'; int best_b = -1;\n            \n            long long cur_WH = getW() + getH();\n            long long skip_score = cur_WH + (long long)round(w_est[i] + h_est[i]);\n            best_score = skip_score;\n            \n            for (int r = 0; r < 2; r++) {\n                int rw = r ? (int)round(h_est[i]) : (int)round(w_est[i]);\n                int rh = r ? (int)round(w_est[i]) : (int)round(h_est[i]);\n                for (char d : {'U', 'L'}) {\n                    int max_b = min((int)px.size() - 1, 30);\n                    for (int b = -1; b <= max_b; b++) {\n                        auto spx=px, spy=py, spw=pw, sph=ph;\n                        addRect(rw, rh, d, b);\n                        long long place_score = getW() + getH();\n                        if (place_score < best_score) {\n                            best_score = place_score; best_r = r; best_d = d; best_b = b;\n                        }\n                        px=spx; py=spy; pw=spw; ph=sph;\n                    }\n                }\n            }\n            \n            if (best_r >= 0) {\n                int rw = best_r ? (int)round(h_est[i]) : (int)round(w_est[i]);\n                int rh = best_r ? (int)round(w_est[i]) : (int)round(h_est[i]);\n                addRect(rw, rh, best_d, best_b);\n                output.push_back({i, best_r, best_d, best_b});\n            }\n        }\n        \n        cout << output.size() << \"\\n\";\n        for (auto& [p, r, d, b] : output) cout << p << \" \" << r << \" \" << d << \" \" << b << \"\\n\";\n        cout.flush();\n        \n        int W_prime, H_prime;\n        cin >> W_prime >> H_prime;\n        \n        double W_pred = getW(), H_pred = getH();\n        double W_err = W_prime - W_pred, H_err = H_prime - H_pred;\n        int num_placed = px.size();\n        if (num_placed > 0) {\n            double lr = 0.2;\n            for (auto& [p, r, d, b] : output) {\n                int rw = r ? (int)round(h_est[p]) : (int)round(w_est[p]);\n                int rh = r ? (int)round(w_est[p]) : (int)round(h_est[p]);\n                double w_contrib = rw / (W_pred + 1);\n                double h_contrib = rh / (H_pred + 1);\n                w_est[p] += W_err * w_contrib * lr;\n                h_est[p] += H_err * h_contrib * lr;\n                w_est[p] = max(w_est[p], 1.0);\n                h_est[p] = max(h_est[p], 1.0);\n            }\n        }\n    }\n    return 0;\n}","ahc041":"#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, 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    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<int> parent(N, -1);\n    vector<int> height(N, 0);\n    \n    function<void(int, int)> update_h = [&](int v, int diff) {\n        height[v] += diff;\n        for (int u : adj[v]) {\n            if (parent[u] == v) update_h(u, diff);\n        }\n    };\n    \n    auto creates_cycle = [&](int v, int u) -> bool {\n        int curr = u;\n        while (curr != -1) {\n            if (curr == v) return true;\n            curr = parent[curr];\n        }\n        return false;\n    };\n    \n    function<long long(int)> subtree_sum = [&](int v) -> long long {\n        long long sum = A[v];\n        for (int u : adj[v]) {\n            if (parent[u] == v) sum += subtree_sum(u);\n        }\n        return sum;\n    };\n    \n    function<int(int)> max_subtree_h = [&](int v) -> int {\n        int max_h = height[v];\n        for (int u : adj[v]) {\n            if (parent[u] == v) {\n                max_h = max(max_h, max_subtree_h(u));\n            }\n        }\n        return max_h;\n    };\n    \n    while (true) {\n        long long best_gain = 0;\n        int best_v = -1, best_u = -1;\n        \n        for (int v = 0; v < N; v++) {\n            for (int u : adj[v]) {\n                if (u == parent[v]) continue;\n                \n                int new_h = height[u] + 1;\n                int diff = new_h - height[v];\n                if (diff <= 0) continue;\n                \n                int max_h = max_subtree_h(v);\n                if (max_h + diff > H) continue;\n                \n                if (creates_cycle(v, u)) continue;\n                \n                long long sum = subtree_sum(v);\n                long long gain = (long long)diff * sum;\n                \n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_v = v;\n                    best_u = u;\n                }\n            }\n        }\n        \n        if (best_v == -1) break;\n        \n        int new_h = height[best_u] + 1;\n        int diff = new_h - height[best_v];\n        parent[best_v] = best_u;\n        update_h(best_v, diff);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << parent[i] << (i == N-1 ? \"\\n\" : \" \");\n    }\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <map>\n#include <set>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N; cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    struct Oni { int i, j, id; bool up_safe, down_safe, left_safe, right_safe; };\n    vector<Oni> onis;\n    int id_counter = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 'x') {\n                Oni o{i, j, id_counter++, true, true, true, true};\n                for (int k = 0; k < i; k++) if (board[k][j] == 'o') { o.up_safe = false; break; }\n                for (int k = i+1; k < N; k++) if (board[k][j] == 'o') { o.down_safe = false; break; }\n                for (int k = 0; k < j; k++) if (board[i][k] == 'o') { o.left_safe = false; break; }\n                for (int k = j+1; k < N; k++) if (board[i][k] == 'o') { o.right_safe = false; break; }\n                onis.push_back(o);\n            }\n        }\n    }\n    \n    vector<char> oni_dir(onis.size());\n    for (auto& o : onis) {\n        char best_dir = 0; int best_cost = 1e9;\n        if (o.up_safe) { int c = o.i+1; if (c < best_cost) { best_cost = c; best_dir = 'U'; } }\n        if (o.down_safe) { int c = N-o.i; if (c < best_cost) { best_cost = c; best_dir = 'D'; } }\n        if (o.left_safe) { int c = o.j+1; if (c < best_cost) { best_cost = c; best_dir = 'L'; } }\n        if (o.right_safe) { int c = N-o.j; if (c < best_cost) { best_cost = c; best_dir = 'R'; } }\n        oni_dir[o.id] = best_dir;\n    }\n    \n    map<pair<char,int>, vector<int>> batches;\n    for (auto& o : onis) {\n        char dir = oni_dir[o.id];\n        int idx = (dir == 'L' || dir == 'R') ? o.i : o.j;\n        batches[{dir, idx}].push_back(o.id);\n    }\n    \n    set<int> removed;\n    vector<pair<char,int>> moves;\n    \n    for (char dir : {'U','D','L','R'}) {\n        for (int idx = 0; idx < N; idx++) {\n            auto key = make_pair(dir, idx);\n            if (batches.find(key) == batches.end()) continue;\n            \n            int max_dist = 0;\n            for (int oid : batches[key]) {\n                if (removed.count(oid)) continue;\n                auto& o = onis[oid];\n                int dist = (dir=='U') ? o.i+1 : (dir=='D') ? N-o.i : (dir=='L') ? o.j+1 : N-o.j;\n                max_dist = max(max_dist, dist);\n            }\n            if (max_dist == 0) continue;\n            \n            for (int k = 0; k < max_dist; k++) moves.push_back({dir, idx});\n            char opp = (dir=='U')?'D':(dir=='D')?'U':(dir=='L')?'R':'L';\n            for (int k = 0; k < max_dist; k++) moves.push_back({opp, idx});\n            \n            for (auto& o : onis) {\n                if (removed.count(o.id)) continue;\n                bool in_path = false;\n                if (dir=='U' && o.j==idx && o.i < max_dist) in_path = true;\n                else if (dir=='D' && o.j==idx && o.i >= N-max_dist) in_path = true;\n                else if (dir=='L' && o.i==idx && o.j < max_dist) in_path = true;\n                else if (dir=='R' && o.i==idx && o.j >= N-max_dist) in_path = true;\n                if (in_path) removed.insert(o.id);\n            }\n        }\n    }\n    \n    for (auto& [d, p] : moves) cout << d << \" \" << p << \"\\n\";\n    return 0;\n}","ahc044":"#include <iostream>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\nint N, L;\nint T[100];\nint a[100], b[100];\n\nunsigned int rng_state = 42;\nunsigned int rng() {\n    rng_state ^= rng_state << 13;\n    rng_state ^= rng_state >> 17;\n    rng_state ^= rng_state << 5;\n    return rng_state;\n}\n\nvoid simulate(int t[]) {\n    int count[100] = {0};\n    for (int i = 0; i < N; i++) t[i] = 0;\n    int current = 0;\n    for (int week = 0; week < L; week++) {\n        t[current]++;\n        count[current]++;\n        current = (count[current] & 1) ? a[current] : b[current];\n    }\n}\n\nint compute_error(int t[]) {\n    int error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(t[i] - T[i]);\n    }\n    return error;\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++) {\n        cin >> T[i];\n    }\n    \n    // Initial solution: cycle\n    for (int i = 0; i < N; i++) {\n        a[i] = (i + 1) % N;\n        b[i] = (i + 1) % N;\n    }\n    \n    int t[100];\n    simulate(t);\n    int error = compute_error(t);\n    int best_error = error;\n    int best_a[100], best_b[100];\n    for (int i = 0; i < N; i++) {\n        best_a[i] = a[i];\n        best_b[i] = b[i];\n    }\n    \n    auto start = chrono::high_resolution_clock::now();\n    \n    double temperature = 1000.0;\n    double cooling_rate = 0.99;\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.8) break;\n        \n        int i = rng() % N;\n        int old_ai = a[i], old_bi = b[i];\n        int new_val = rng() % N;\n        if (rng() & 1) {\n            a[i] = new_val;\n        } else {\n            b[i] = new_val;\n        }\n        \n        simulate(t);\n        int new_error = compute_error(t);\n        \n        double delta = new_error - error;\n        if (delta <= 0 || (double)(rng() % 10000) / 10000.0 < exp(-delta / temperature)) {\n            error = new_error;\n            if (error < best_error) {\n                best_error = error;\n                for (int j = 0; j < N; j++) {\n                    best_a[j] = a[j];\n                    best_b[j] = b[j];\n                }\n            }\n        } else {\n            a[i] = old_ai;\n            b[i] = old_bi;\n        }\n        \n        temperature *= cooling_rate;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, Q, L, W;\ndouble cx[800], cy[800], ddist[800][800];\nint qcnt = 0;\n\nvector<pair<int,int>> query(vector<int> v) {\n    if (qcnt >= Q || (int)v.size() < 2) return {};\n    qcnt++;\n    cout << \"? \" << v.size();\n    for (int x : v) cout << \" \" << x;\n    cout << endl;\n    vector<pair<int,int>> res(v.size() - 1);\n    for (auto& [a, b] : res) cin >> a >> b;\n    return res;\n}\n\nint par[800], rnk[800];\nvoid init_dsu() { iota(par, par + N, 0); fill(rnk, rnk + N, 0); }\nint find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }\nbool unite(int x, int y) {\n    x = find(x); y = find(y);\n    if (x == y) return false;\n    if (rnk[x] < rnk[y]) swap(x, y);\n    par[y] = x;\n    if (rnk[x] == rnk[y]) rnk[x]++;\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> Q >> L >> W;\n    vector<int> G(M);\n    for (int& g : G) cin >> g;\n    \n    for (int i = 0; i < N; i++) {\n        int a, b, c, d;\n        cin >> a >> b >> c >> d;\n        cx[i] = (a + b) / 2.0;\n        cy[i] = (c + d) / 2.0;\n    }\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            double dx = cx[i] - cx[j], dy = cy[i] - cy[j];\n            ddist[i][j] = sqrt(dx*dx + dy*dy);\n        }\n    \n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [](int a, int b) {\n        return make_pair(cx[a] + cy[a], cx[a]) < make_pair(cx[b] + cy[b], cx[b]);\n    });\n    \n    vector<vector<int>> grp(M);\n    for (int i = 0, p = 0; i < M; i++)\n        for (int j = 0; j < G[i]; j++)\n            grp[i].push_back(ord[p++]);\n    \n    vector<vector<pair<int,int>>> ans(M);\n    \n    for (int k = 0; k < M; k++) {\n        if (G[k] <= 1) continue;\n        \n        init_dsu();\n        if (G[k] <= L && qcnt < Q) {\n            ans[k] = query(grp[k]);\n            continue;\n        }\n        \n        set<int> conn;\n        vector<pair<int,int>> mst;\n        conn.insert(grp[k][0]);\n        \n        while (conn.size() < (size_t)G[k]) {\n            vector<pair<double,int>> cands;\n            for (int c : grp[k]) {\n                if (conn.count(c)) continue;\n                double md = 1e18;\n                for (int t : conn) md = min(md, ddist[c][t]);\n                cands.emplace_back(md, c);\n            }\n            sort(cands.begin(), cands.end());\n            if (cands.empty()) break;\n            \n            vector<int> qv;\n            vector<pair<double,int>> tree_sorted;\n            for (int t : conn) tree_sorted.emplace_back(ddist[t][cands[0].second], t);\n            sort(tree_sorted.begin(), tree_sorted.end());\n            int ntree = min((int)tree_sorted.size(), L / 2);\n            for (int i = 0; i < ntree; i++) qv.push_back(tree_sorted[i].second);\n            \n            int ncand = min((int)cands.size(), L - (int)qv.size());\n            for (int i = 0; i < ncand; i++) qv.push_back(cands[i].second);\n            \n            bool added = false;\n            if (qv.size() >= 2 && qcnt < Q) {\n                auto edges = query(qv);\n                for (auto& [a, b] : edges) {\n                    if (unite(a, b)) {\n                        mst.emplace_back(a, b);\n                        conn.insert(a); conn.insert(b);\n                        added = true;\n                    }\n                }\n            }\n            \n            if (!added) {\n                int c = cands[0].second;\n                double bd = 1e18; int bt = -1;\n                for (int t : conn) if (ddist[c][t] < bd) { bd = ddist[c][t]; bt = t; }\n                mst.emplace_back(c, bt);\n                unite(c, bt);\n                conn.insert(c);\n            }\n        }\n        ans[k] = mst;\n    }\n    \n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < G[k]; i++) cout << grp[k][i] << \" \\n\"[i==G[k]-1];\n        for (auto& [a, b] : ans[k]) cout << a << \" \" << b << \"\\n\";\n    }\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <set>\n#include <string>\n#include <queue>\n#include <algorithm>\n\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    \n    vector<pair<int, int>> targets(M);\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n    \n    set<pair<int, int>> blocks;\n    int cur_r = targets[0].first, cur_c = targets[0].second;\n    vector<pair<char, char>> all_actions;\n    \n    auto get_slide_dest = [&](int r, int c, char dir) -> pair<int, int> {\n        int dr = 0, dc = 0;\n        if (dir == 'U') dr = -1;\n        else if (dir == 'D') dr = 1;\n        else if (dir == 'L') dc = -1;\n        else dc = 1;\n        \n        int nr = r + dr, nc = c + dc;\n        while (nr >= 0 && nr < N && nc >= 0 && nc < N && blocks.count({nr, nc}) == 0) {\n            nr += dr;\n            nc += dc;\n        }\n        nr -= dr;\n        nc -= dc;\n        return {nr, nc};\n    };\n    \n    auto bfs = [&](int sr, int sc, int tr, int tc) -> vector<pair<char, char>> {\n        if (sr == tr && sc == tc) return {};\n        vector<vector<bool>> visited(N, vector<bool>(N, false));\n        vector<vector<pair<pair<int,int>, pair<char,char>>>> parent(N, vector<pair<pair<int,int>, pair<char,char>>>(N, {{-1,-1}, {' ', ' '}}));\n        \n        queue<pair<int,int>> q;\n        q.push({sr, sc});\n        visited[sr][sc] = true;\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 = r, cc = c;\n                while (parent[cr][cc].first.first != -1) {\n                    path.push_back(parent[cr][cc].second);\n                    auto [pr, pc] = parent[cr][cc].first;\n                    cr = pr; cc = pc;\n                }\n                reverse(path.begin(), path.end());\n                return path;\n            }\n            \n            for (char dir : {'U', 'D', 'L', 'R'}) {\n                int dr = 0, dc = 0;\n                if (dir == 'U') dr = -1;\n                else if (dir == 'D') dr = 1;\n                else if (dir == 'L') dc = -1;\n                else dc = 1;\n                \n                int nr = r + dr, nc = c + dc;\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && blocks.count({nr, nc}) == 0 && !visited[nr][nc]) {\n                    visited[nr][nc] = true;\n                    parent[nr][nc] = {{r, c}, {'M', dir}};\n                    q.push({nr, nc});\n                }\n            }\n            \n            for (char dir : {'U', 'D', 'L', 'R'}) {\n                auto [nr, nc] = get_slide_dest(r, c, dir);\n                if ((nr != r || nc != c) && !visited[nr][nc]) {\n                    visited[nr][nc] = true;\n                    parent[nr][nc] = {{r, c}, {'S', dir}};\n                    q.push({nr, nc});\n                }\n            }\n        }\n        return {};\n    };\n    \n    for (int t = 1; t < M; t++) {\n        int target_r = targets[t].first, target_c = targets[t].second;\n        auto path = bfs(cur_r, cur_c, target_r, target_c);\n        \n        for (auto [action, dir] : path) {\n            all_actions.push_back({action, dir});\n            if (action == 'M') {\n                int dr = 0, dc = 0;\n                if (dir == 'U') dr = -1;\n                else if (dir == 'D') dr = 1;\n                else if (dir == 'L') dc = -1;\n                else dc = 1;\n                cur_r += dr; cur_c += dc;\n            } else if (action == 'S') {\n                auto [nr, nc] = get_slide_dest(cur_r, cur_c, dir);\n                cur_r = nr; cur_c = nc;\n            }\n        }\n        \n        if (cur_r + 1 < N && blocks.count({cur_r + 1, cur_c}) == 0) {\n            blocks.insert({cur_r + 1, cur_c});\n            all_actions.push_back({'A', 'D'});\n        }\n        if (cur_c + 1 < N && blocks.count({cur_r, cur_c + 1}) == 0) {\n            blocks.insert({cur_r, cur_c + 1});\n            all_actions.push_back({'A', 'R'});\n        }\n    }\n    \n    for (auto& [a, d] : all_actions) {\n        cout << a << \" \" << d << \"\\n\";\n    }\n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> x, y, r;\nvector<int> a, b, c, d;\n\ndouble satisfaction(long long area, long long desired) {\n    if (area <= 0 || desired <= 0) return 0;\n    double ratio = (double)min(area, desired) / max(area, desired);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\ndouble estimate_satisfaction(long long area, long long total_r) {\n    if (area == 0 || total_r == 0) return 0;\n    double ratio = (double)min(area, total_r) / max(area, total_r);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\ndouble compute_score() {\n    double score = 0;\n    for (int i = 0; i < n; i++) {\n        long long area = (long long)(c[i] - a[i]) * (d[i] - b[i]);\n        score += satisfaction(area, r[i]);\n    }\n    return score;\n}\n\nvoid solve(vector<int> indices, int left, int bottom, int right, int top, mt19937& rng, int strategy, int depth = 0) {\n    if (indices.empty()) return;\n    if (indices.size() == 1) {\n        int i = indices[0];\n        a[i] = left; b[i] = bottom; c[i] = right; d[i] = top;\n        return;\n    }\n    \n    long long total_r = 0;\n    for (int i : indices) total_r += r[i];\n    \n    int width = right - left;\n    int height = top - bottom;\n    long long area = (long long)width * height;\n    \n    bool try_vertical = (strategy != 2), try_horizontal = (strategy != 1);\n    if (strategy == 1) { try_vertical = (depth % 2 == 0); try_horizontal = !try_vertical; }\n    else if (strategy == 2) { try_horizontal = (depth % 2 == 0); try_vertical = !try_horizontal; }\n    \n    struct Split { bool vertical; int k; int split_pos; double score; };\n    vector<Split> splits;\n    \n    auto try_splits = [&](bool vertical) {\n        vector<int>& coord = vertical ? x : y;\n        int lo = vertical ? left : bottom, hi = vertical ? right : top;\n        sort(indices.begin(), indices.end(), [&](int i, int j) { return coord[i] < coord[j]; });\n        long long sum = 0;\n        for (int k = 1; k < (int)indices.size(); k++) {\n            sum += r[indices[k-1]];\n            if (coord[indices[k-1]] >= coord[indices[k]]) continue;\n            int min_s = max(lo + 1, coord[indices[k-1]] + 1);\n            int max_s = min(hi - 1, coord[indices[k]]);\n            if (min_s > max_s) continue;\n            long long ideal_s = lo + (long long)(hi - lo) * sum / total_r;\n            int s = max(min_s, min(max_s, (int)ideal_s));\n            long long area1 = vertical ? (long long)(s - left) * height : (long long)width * (s - bottom);\n            long long area2 = area - area1;\n            double score = estimate_satisfaction(area1, sum) + estimate_satisfaction(area2, total_r - sum);\n            splits.push_back({vertical, k, s, score});\n        }\n    };\n    \n    if (try_vertical) try_splits(true);\n    if (try_horizontal) try_splits(false);\n    if (splits.empty()) { if (!try_vertical) try_splits(true); if (splits.empty() && !try_horizontal) try_splits(false); }\n    \n    if (splits.empty()) {\n        int i = indices[0];\n        a[i] = left; b[i] = bottom; c[i] = right; d[i] = top;\n        return;\n    }\n    \n    sort(splits.begin(), splits.end(), [](const Split& a, const Split& b) { return a.score > b.score; });\n    int num_top = min((int)splits.size(), 5);\n    uniform_int_distribution<int> dist(0, num_top - 1);\n    const Split& chosen = splits[dist(rng)];\n    \n    vector<int>& coord = chosen.vertical ? x : y;\n    sort(indices.begin(), indices.end(), [&](int i, int j) { return coord[i] < coord[j]; });\n    vector<int> sub1(indices.begin(), indices.begin() + chosen.k);\n    vector<int> sub2(indices.begin() + chosen.k, indices.end());\n    \n    if (chosen.vertical) {\n        solve(sub1, left, bottom, chosen.split_pos, top, rng, strategy, depth + 1);\n        solve(sub2, chosen.split_pos, bottom, right, top, rng, strategy, depth + 1);\n    } else {\n        solve(sub1, left, bottom, right, chosen.split_pos, rng, strategy, depth + 1);\n        solve(sub2, left, chosen.split_pos, right, top, rng, strategy, depth + 1);\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++) cin >> x[i] >> y[i] >> r[i];\n    \n    auto start_time = chrono::steady_clock::now();\n    vector<int> indices(n);\n    iota(indices.begin(), indices.end(), 0);\n    \n    vector<int> best_a(n), best_b(n), best_c(n), best_d(n);\n    double best_score = -1;\n    \n    for (unsigned seed = 0; ; seed++) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 4500) break;\n        \n        mt19937 rng(seed);\n        int strategy = seed % 3;\n        solve(indices, 0, 0, 10000, 10000, rng, strategy);\n        \n        double score = compute_score();\n        if (score > best_score) {\n            best_score = score;\n            best_a = a; best_b = b; best_c = c; best_d = d;\n        }\n    }\n    \n    a = best_a; b = best_b; c = best_c; d = best_d;\n    for (int i = 0; i < n; i++) cout << a[i] << \" \" << b[i] << \" \" << c[i] << \" \" << d[i] << \"\\n\";\n    \n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 50;\nint si, sj;\nint t[N][N], p[N][N];\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir[] = {'U', 'D', 'L', 'R'};\nmt19937 rng(42);\n\nint tile_value[2500], max_tile_id = 0;\nstring best_path;\nlong long best_score;\n\nstring find_path(double temperature) {\n    bool square_visited[N][N] = {};\n    bool tile_visited[2500] = {};\n    string path;\n    int ci = si, cj = sj;\n    square_visited[ci][cj] = true;\n    tile_visited[t[ci][cj]] = true;\n    long long score = p[ci][cj];\n    \n    while (true) {\n        vector<pair<double, int>> candidates;\n        for (int d = 0; d < 4; d++) {\n            int ni = ci + di[d], nj = cj + dj[d];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (square_visited[ni][nj]) continue;\n            bool same_tile = (t[ni][nj] == t[ci][cj]);\n            if (same_tile || !tile_visited[t[ni][nj]]) {\n                double w = same_tile ? p[ni][nj] : tile_value[t[ni][nj]];\n                candidates.push_back({w, d});\n            }\n        }\n        if (candidates.empty()) break;\n        \n        double max_w = -1e18;\n        for (auto& [w, d] : candidates) max_w = max(max_w, w);\n        double total = 0;\n        for (auto& [w, d] : candidates) total += exp((w - max_w) / max(temperature, 0.01));\n        \n        double r = uniform_real_distribution<double>(0, total)(rng);\n        double cum = 0;\n        int chosen = candidates[0].second;\n        for (auto& [w, d] : candidates) {\n            cum += exp((w - max_w) / max(temperature, 0.01));\n            if (cum >= r) { chosen = d; break; }\n        }\n        \n        int ni = ci + di[chosen], nj = cj + dj[chosen];\n        square_visited[ni][nj] = true;\n        tile_visited[t[ni][nj]] = true;\n        score += p[ni][nj];\n        path += dir[chosen];\n        ci = ni; cj = nj;\n    }\n    \n    if (score > best_score) { best_score = score; best_path = path; }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> si >> sj;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) { cin >> t[i][j]; max_tile_id = max(max_tile_id, t[i][j]); }\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> p[i][j];\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) tile_value[t[i][j]] += p[i][j];\n    \n    best_score = 0;\n    auto start = chrono::high_resolution_clock::now();\n    int iter = 0;\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 1800) break;\n        double temperature = 10.0 * (1.0 - min(iter / 100000.0, 1.0)) + 0.1;\n        find_path(temperature);\n        iter++;\n    }\n    \n    cout << best_path << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\ndouble row_h[N], col_v[N], row_h_var[N], col_v_var[N];\ndouble h_dev[N][N-1], v_dev[N-1][N], h_dev_var[N][N-1], v_dev_var[N-1][N];\nint query_num = 0;\n\ndouble get_h_est(int i, int j) { return row_h[i] + h_dev[i][j]; }\ndouble get_v_est(int i, int j) { return col_v[j] + v_dev[i][j]; }\n\ndouble get_h_weight(int i, int j) {\n    double est = get_h_est(i, j), sigma = sqrt(row_h_var[i] + h_dev_var[i][j]);\n    double td = max(0.0, 1.0 - query_num / 250.0);\n    return max(100.0, est - 0.5 * sigma * td);\n}\ndouble get_v_weight(int i, int j) {\n    double est = get_v_est(i, j), sigma = sqrt(col_v_var[j] + v_dev_var[i][j]);\n    double td = max(0.0, 1.0 - query_num / 250.0);\n    return max(100.0, est - 0.5 * sigma * td);\n}\n\nstring dijkstra(int si, int sj, int ti, int tj) {\n    double dist[N][N]; pair<int,int> prev[N][N]; bool vis[N][N] = {};\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) dist[i][j]=1e18;\n    dist[si][sj]=0;\n    priority_queue<tuple<double,int,int>,vector<tuple<double,int,int>>,greater<>> pq;\n    pq.push({0,si,sj});\n    while(!pq.empty()){\n        auto[d,i,j]=pq.top(); pq.pop();\n        if(vis[i][j]) continue; vis[i][j]=true;\n        if(i==ti&&j==tj) break;\n        if(i>0&&!vis[i-1][j]){double w=get_v_weight(i-1,j);if(d+w<dist[i-1][j]){dist[i-1][j]=d+w;prev[i-1][j]={i,j};pq.push({dist[i-1][j],i-1,j});}}\n        if(i<N-1&&!vis[i+1][j]){double w=get_v_weight(i,j);if(d+w<dist[i+1][j]){dist[i+1][j]=d+w;prev[i+1][j]={i,j};pq.push({dist[i+1][j],i+1,j});}}\n        if(j>0&&!vis[i][j-1]){double w=get_h_weight(i,j-1);if(d+w<dist[i][j-1]){dist[i][j-1]=d+w;prev[i][j-1]={i,j};pq.push({dist[i][j-1],i,j-1});}}\n        if(j<N-1&&!vis[i][j+1]){double w=get_h_weight(i,j);if(d+w<dist[i][j+1]){dist[i][j+1]=d+w;prev[i][j+1]={i,j};pq.push({dist[i][j+1],i,j+1});}}\n    }\n    string path; int ci=ti,cj=tj;\n    while(ci!=si||cj!=sj){auto[pi,pj]=prev[ci][cj];if(pi==ci-1)path+='D';else if(pi==ci+1)path+='U';else if(pj==cj-1)path+='R';else path+='L';ci=pi;cj=pj;}\n    reverse(path.begin(),path.end()); return path;\n}\n\nvoid update(int si, int sj, const string& path, int observed) {\n    struct E{char t;int i,j;}; vector<E> edges;\n    map<int,int> hr, vc;\n    int ci=si,cj=sj;\n    for(char c:path){\n        if(c=='U'){edges.push_back({'v',ci-1,cj});vc[cj]++;ci--;}\n        else if(c=='D'){edges.push_back({'v',ci,cj});vc[cj]++;ci++;}\n        else if(c=='L'){edges.push_back({'h',ci,cj-1});hr[ci]++;cj--;}\n        else{edges.push_back({'h',ci,cj});hr[ci]++;cj++;}\n    }\n    double pred=0;\n    for(auto&e:edges) pred+=(e.t=='h')?get_h_est(e.i,e.j):get_v_est(e.i,e.j);\n    double residual=observed-pred, obs_var=pred*pred/300.0;\n    double S=obs_var;\n    for(auto&[i,n]:hr) S+=n*n*row_h_var[i];\n    for(auto&[j,n]:vc) S+=n*n*col_v_var[j];\n    for(auto&e:edges) S+=(e.t=='h')?h_dev_var[e.i][e.j]:v_dev_var[e.i][e.j];\n    for(auto&[i,n]:hr){double K=row_h_var[i]*n/S;row_h[i]+=K*residual;row_h_var[i]*=(1-K*n);row_h[i]=max(500.0,min(15000.0,row_h[i]));row_h_var[i]=max(100.0,row_h_var[i]);}\n    for(auto&[j,n]:vc){double K=col_v_var[j]*n/S;col_v[j]+=K*residual;col_v_var[j]*=(1-K*n);col_v[j]=max(500.0,min(15000.0,col_v[j]));col_v_var[j]=max(100.0,col_v_var[j]);}\n    for(auto&e:edges){\n        double&dev=(e.t=='h')?h_dev[e.i][e.j]:v_dev[e.i][e.j];\n        double&dv=(e.t=='h')?h_dev_var[e.i][e.j]:v_dev_var[e.i][e.j];\n        double K=dv/S; dev+=K*residual; dv*=(1-K);\n        dev=max(-5000.0,min(5000.0,dev)); dv=max(100.0,dv);\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    for(int i=0;i<N;i++){row_h[i]=col_v[i]=5000.0;row_h_var[i]=col_v_var[i]=4000000.0;}\n    for(int i=0;i<N;i++) for(int j=0;j<N-1;j++){h_dev[i][j]=0.0;h_dev_var[i][j]=1500000.0;}\n    for(int i=0;i<N-1;i++) for(int j=0;j<N;j++){v_dev[i][j]=0.0;v_dev_var[i][j]=1500000.0;}\n    for(int k=0;k<1000;k++){\n        query_num=k; int si,sj,ti,tj; cin>>si>>sj>>ti>>tj;\n        string path=dijkstra(si,sj,ti,tj); cout<<path<<endl;\n        int obs; cin>>obs; update(si,sj,path,obs);\n    }\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for (int i = 0; i < M; i++) cin >> s[i];\n    \n    const int NUM_CHARS = 8;\n    mt19937 rng(42);\n    \n    // Initialize with uniform voting\n    vector<vector<double>> votes(N * N, vector<double>(NUM_CHARS, 0));\n    for (int m = 0; m < M; m++) {\n        int k = s[m].length();\n        double weight = 1.0 / (2.0 * N * N);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                for (int p = 0; p < k; p++) {\n                    votes[i * N + (j + p) % N][s[m][p] - 'A'] += weight;\n                    votes[((i + p) % N) * N + j][s[m][p] - 'A'] += weight;\n                }\n            }\n        }\n    }\n    \n    vector<string> mat(N, string(N, 'A'));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            double maxVote = 0;\n            char bestChar = 'A';\n            for (int c = 0; c < NUM_CHARS; c++) {\n                if (votes[i * N + j][c] > maxVote) {\n                    maxVote = votes[i * N + j][c];\n                    bestChar = 'A' + c;\n                }\n            }\n            mat[i][j] = bestChar;\n        }\n    }\n    \n    // Iterative refinement with weighted voting\n    for (int iter = 0; iter < 100; iter++) {\n        vector<vector<double>> newVotes(N * N, vector<double>(NUM_CHARS, 0));\n        \n        for (int m = 0; m < M; m++) {\n            int k = s[m].length();\n            \n            double totalScore = 0;\n            vector<double> scores(2 * N * N);\n            int idx = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    double scoreH = 0, scoreV = 0;\n                    for (int p = 0; p < k; p++) {\n                        if (mat[i][(j + p) % N] == s[m][p]) scoreH += 1;\n                        if (mat[(i + p) % N][j] == s[m][p]) scoreV += 1;\n                    }\n                    scores[idx++] = scoreH;\n                    scores[idx++] = scoreV;\n                    totalScore += scoreH + scoreV;\n                }\n            }\n            \n            if (totalScore < 0.01) continue;\n            \n            idx = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    double wH = scores[idx++] / totalScore;\n                    double wV = scores[idx++] / totalScore;\n                    \n                    for (int p = 0; p < k; p++) {\n                        newVotes[i * N + (j + p) % N][s[m][p] - 'A'] += wH;\n                        newVotes[((i + p) % N) * N + j][s[m][p] - 'A'] += wV;\n                    }\n                }\n            }\n        }\n        \n        bool changed = false;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                double maxVote = 0;\n                char bestChar = mat[i][j];\n                for (int c = 0; c < NUM_CHARS; c++) {\n                    if (newVotes[i * N + j][c] > maxVote) {\n                        maxVote = newVotes[i * N + j][c];\n                        bestChar = 'A' + c;\n                    }\n                }\n                if (mat[i][j] != bestChar) {\n                    mat[i][j] = bestChar;\n                    changed = true;\n                }\n            }\n        }\n        \n        if (!changed) break;\n    }\n    \n    for (int i = 0; i < N; i++) cout << mat[i] << '\\n';\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\nvector<vector<vector<pair<int,int>>>> vis_from;\nint total_roads;\n\nbool is_road(int i, int j) { return i>=0&&i<N&&j>=0&&j<N&&grid[i][j]!='#'; }\nint cell_cost(int i, int j) { return grid[i][j]-'0'; }\n\nconst int di[]={-1,1,0,0}, dj[]={0,0,-1,1};\nconst char dc[]={'U','D','L','R'};\n\nvoid precompute_visibility() {\n    vis_from.assign(N,vector<vector<pair<int,int>>>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) {\n        if(!is_road(i,j)) continue;\n        vis_from[i][j].push_back({i,j});\n        for(int jj=j-1;jj>=0&&is_road(i,jj);jj--) vis_from[i][j].push_back({i,jj});\n        for(int jj=j+1;jj<N&&is_road(i,jj);jj++) vis_from[i][j].push_back({i,jj});\n        for(int ii=i-1;ii>=0&&is_road(ii,j);ii--) vis_from[i][j].push_back({ii,j});\n        for(int ii=i+1;ii<N&&is_road(ii,j);ii++) vis_from[i][j].push_back({ii,j});\n    }\n}\n\npair<vector<vector<int>>,vector<vector<int>>> dijkstra(int si, int sj) {\n    vector<vector<int>> dist(N,vector<int>(N,INT_MAX)), prev(N,vector<int>(N,-1));\n    priority_queue<pair<int,pair<int,int>>,vector<pair<int,pair<int,int>>>,greater<>> pq;\n    dist[si][sj]=0; pq.push({0,{si,sj}});\n    while(!pq.empty()) {\n        auto [d,p]=pq.top(); pq.pop();\n        auto [i,j]=p;\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(is_road(ni,nj)) {\n                int nd=d+cell_cost(ni,nj);\n                if(nd<dist[ni][nj]) { dist[ni][nj]=nd; prev[ni][nj]=k; pq.push({nd,{ni,nj}}); }\n            }\n        }\n    }\n    return {dist,prev};\n}\n\nstring reconstruct(int si, int sj, int ti, int tj, const vector<vector<int>>& prev) {\n    if(si==ti&&sj==tj) return \"\";\n    string path; int ci=ti,cj=tj;\n    while(ci!=si||cj!=sj) { int k=prev[ci][cj]; if(k==-1) return \"\"; path+=dc[k]; ci-=di[k]; cj-=dj[k]; }\n    reverse(path.begin(),path.end()); return path;\n}\n\nstring build_greedy(double alpha, int& route_time) {\n    vector<vector<bool>> covered(N,vector<bool>(N,false));\n    auto mark=[&](int i,int j)->int {\n        int c=0; for(auto&[vi,vj]:vis_from[i][j]) if(!covered[vi][vj]){covered[vi][vj]=true;c++;} return c;\n    };\n    auto cnt_new=[&](int i,int j)->int {\n        int c=0; for(auto&[vi,vj]:vis_from[i][j]) if(!covered[vi][vj]) c++; return c;\n    };\n    string route; int ci=si,cj=sj,cc=mark(ci,cj); route_time=0;\n    while(cc<total_roads) {\n        auto [dist,prev]=dijkstra(ci,cj);\n        vector<tuple<double,int,int>> cands;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++) {\n            if(!is_road(i,j)||dist[i][j]==INT_MAX) continue;\n            int nv=cnt_new(i,j); if(nv==0) continue;\n            cands.emplace_back(pow((double)nv,alpha)/(double)dist[i][j],i,j);\n        }\n        if(cands.empty()) break;\n        sort(cands.begin(),cands.end(),greater<>());\n        int K=min((int)cands.size(),12);\n        int bi=-1,bj=-1; double bs=-1e18;\n        for(int c=0;c<K;c++) {\n            auto& [sc,ti,tj]=cands[c];\n            vector<pair<int,int>> pc; int pi=ti,pj=tj;\n            while(pi!=ci||pj!=cj) { pc.push_back({pi,pj}); int k=prev[pi][pj]; pi-=di[k]; pj-=dj[k]; }\n            auto tmp=covered; int nv=0;\n            for(auto&[pi2,pj2]:pc) for(auto&[vi,vj]:vis_from[pi2][pj2]) if(!tmp[vi][vj]){tmp[vi][vj]=true;nv++;}\n            double ps=nv>0?pow((double)nv,alpha)/(double)dist[ti][tj]:0;\n            if(ps>bs){bs=ps;bi=ti;bj=tj;}\n        }\n        if(bi==-1) break;\n        string path=reconstruct(ci,cj,bi,bj,prev);\n        for(char c:path) { int k=string(\"UDLR\").find(c); ci+=di[k];cj+=dj[k]; cc+=mark(ci,cj); route_time+=cell_cost(ci,cj); }\n        route+=path;\n    }\n    auto [dist,prev]=dijkstra(ci,cj);\n    string ret=reconstruct(ci,cj,si,sj,prev);\n    for(char c:ret) { int k=string(\"UDLR\").find(c); ci+=di[k];cj+=dj[k]; cc+=mark(ci,cj); route_time+=cell_cost(ci,cj); }\n    route+=ret;\n    route_time = 0; ci=si;cj=sj; for(char c:route){int k=string(\"UDLR\").find(c);ci+=di[k];cj+=dj[k];route_time+=cell_cost(ci,cj);}\n    return route;\n}\n\nstring build_tsp() {\n    vector<pair<int,int>> vps;\n    vector<bool> cc(N*N,false); int nc=0;\n    while(nc<total_roads) {\n        int bi=-1,bj=-1,bn=0;\n        for(int i=0;i<N;i++) for(int j=0;j<N;j++) {\n            if(!is_road(i,j)) continue; int nv=0;\n            for(auto&[vi,vj]:vis_from[i][j]) if(!cc[vi*N+vj]) nv++;\n            if(nv>bn){bn=nv;bi=i;bj=j;}\n        }\n        if(bn==0) break;\n        vps.push_back({bi,bj});\n        for(auto&[vi,vj]:vis_from[bi][bj]) if(!cc[vi*N+vj]){cc[vi*N+vj]=true;nc++;}\n    }\n    int M=vps.size(); if(M==0) return \"\";\n    vector<vector<int>> vpd(M,vector<int>(M,INT_MAX));\n    vector<int> s2v(M),v2s(M);\n    { auto [d,p]=dijkstra(si,sj); for(int k=0;k<M;k++) s2v[k]=d[vps[k].first][vps[k].second]; }\n    for(int k=0;k<M;k++) {\n        auto [d,p]=dijkstra(vps[k].first,vps[k].second);\n        v2s[k]=d[si][sj];\n        for(int l=0;l<M;l++) vpd[k][l]=d[vps[l].first][vps[l].second];\n    }\n    // Nearest-neighbor from multiple starts\n    vector<int> best_order; int best_td=INT_MAX;\n    for(int start=0;start<M;start+=max(1,M/5)) {\n        vector<int> ord; vector<bool> vis(M,false);\n        int cur=start; ord.push_back(cur); vis[cur]=true;\n        for(int s=1;s<M;s++) {\n            int nx=-1,nd=INT_MAX;\n            for(int k=0;k<M;k++){if(!vis[k]&&vpd[cur][k]<nd){nd=vpd[cur][k];nx=k;}}\n            if(nx==-1) break; ord.push_back(nx); vis[nx]=true; cur=nx;\n        }\n        // 2-opt\n        for(int it=0;it<50;it++) {\n            bool imp=false;\n            for(int i=0;i<M-1;i++) for(int j=i+2;j<M;j++) {\n                int d1=(i==0)?s2v[ord[i]]:vpd[ord[i-1]][ord[i]];\n                int d2=(j+1<M)?vpd[ord[j]][ord[j+1]]:v2s[ord[j]];\n                int d3=(i==0)?s2v[ord[j]]:vpd[ord[i-1]][ord[j]];\n                int d4=(j+1<M)?vpd[ord[i]][ord[j+1]]:v2s[ord[i]];\n                if(d3+d4<d1+d2) { reverse(ord.begin()+i,ord.begin()+j+1); imp=true; }\n            }\n            if(!imp) break;\n        }\n        int td=s2v[ord[0]];\n        for(int k=0;k<M-1;k++) td+=vpd[ord[k]][ord[k+1]];\n        td+=v2s[ord[M-1]];\n        if(td<best_td){best_td=td;best_order=ord;}\n    }\n    // Build route\n    vector<vector<bool>> covered(N,vector<bool>(N,false));\n    auto mark=[&](int i,int j)->int {\n        int c=0; for(auto&[vi,vj]:vis_from[i][j]) if(!covered[vi][vj]){covered[vi][vj]=true;c++;} return c;\n    };\n    string route; int ci=si,cj=sj,ccnt=mark(ci,cj);\n    for(int idx:best_order) {\n        auto [ti,tj]=vps[idx];\n        auto [d,p]=dijkstra(ci,cj);\n        string path=reconstruct(ci,cj,ti,tj,p);\n        for(char c:path){int k=string(\"UDLR\").find(c);ci+=di[k];cj+=dj[k];ccnt+=mark(ci,cj);}\n        route+=path;\n    }\n    { auto [d,p]=dijkstra(ci,cj); string ret=reconstruct(ci,cj,si,sj,p);\n      for(char c:ret){int k=string(\"UDLR\").find(c);ci+=di[k];cj+=dj[k];ccnt+=mark(ci,cj);} route+=ret; }\n    return route;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin>>N>>si>>sj; grid.resize(N); for(int i=0;i<N;i++) cin>>grid[i];\n    precompute_visibility();\n    total_roads=0; for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(is_road(i,j)) total_roads++;\n    auto st=chrono::high_resolution_clock::now();\n    string best_route; int best_time=INT_MAX;\n    for(double alpha:{0.5,0.75,1.0,1.25,1.5,1.75,2.0,2.5,3.0}) {\n        auto now=chrono::high_resolution_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-st).count()>2000) break;\n        int rt; auto route=build_greedy(alpha,rt);\n        if(rt<best_time&&rt>0){best_time=rt;best_route=route;}\n    }\n    auto now=chrono::high_resolution_clock::now();\n    if(chrono::duration_cast<chrono::milliseconds>(now-st).count()<2500) {\n        auto route=build_tsp();\n        if(!route.empty()) {\n            int ci=si,cj=sj,rt=0;\n            for(char c:route){int k=string(\"UDLR\").find(c);ci+=di[k];cj+=dj[k];rt+=cell_cost(ci,cj);}\n            if(rt<best_time){best_time=rt;best_route=route;}\n        }\n    }\n    if(best_route.empty()) { int rt; best_route=build_greedy(1.0,rt); }\n    cout<<best_route<<endl;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> d, deps, rev_deps;\nvector<vector<double>> skill_est;\nvector<vector<int>> skill_lb;\nvector<int> crit_path;\nvector<vector<pair<int,int>>> member_obs;\n\nvector<int> hungarian(const vector<vector<double>>& cost) {\n    int n = cost.size(), m = cost[0].size();\n    const double INF = 1e18;\n    vector<double> u(n+1,0), v(m+1,0);\n    vector<int> p(m+1,0), way(m+1,0);\n    for (int i = 1; i <= n; i++) {\n        p[0] = i; int j0 = 0;\n        vector<double> minv(m+1, INF);\n        vector<bool> used(m+1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], j1 = 0;\n            double delta = INF;\n            for (int j = 1; j <= m; j++) if (!used[j]) {\n                double cur = cost[i0-1][j-1] - u[i0] - v[j];\n                if (cur < minv[j]) { minv[j] = cur; way[j] = j0; }\n                if (minv[j] < delta) { delta = minv[j]; j1 = j; }\n            }\n            for (int j = 0; j <= m; j++) {\n                if (used[j]) { u[p[j]] += delta; v[j] -= delta; }\n                else minv[j] -= delta;\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do { int j1 = way[j0]; p[j0] = p[j1]; j0 = j1; } while (j0);\n    }\n    vector<int> asgn(n, -1);\n    for (int j = 1; j <= m; j++) if (p[j] > 0 && p[j] <= n) asgn[p[j]-1] = j-1;\n    return asgn;\n}\n\nvoid reestimate(int j) {\n    auto& ob = member_obs[j];\n    if (ob.empty()) return;\n    for (int k = 0; k < K; k++) skill_est[j][k] = max(skill_est[j][k], (double)skill_lb[j][k]);\n    for (int iter = 0; iter < 20; iter++) {\n        for (auto& [task, t] : ob) {\n            if (t == 1) continue;\n            double est_w = (double)t;\n            double td = 0;\n            for (int k = 0; k < K; k++) td += max(0.0, (double)d[task][k] - skill_est[j][k]);\n            if (td > 0) {\n                double ratio = est_w / td;\n                for (int k = 0; k < K; k++) {\n                    double def = max(0.0, (double)d[task][k] - skill_est[j][k]);\n                    if (def > 0) {\n                        double ns = d[task][k] - def * ratio;\n                        skill_est[j][k] = 0.85 * skill_est[j][k] + 0.15 * ns;\n                        skill_est[j][k] = max((double)skill_lb[j][k], skill_est[j][k]);\n                    }\n                }\n            } else {\n                double totd = 0;\n                for (int k = 0; k < K; k++) totd += d[task][k];\n                if (totd > 0) for (int k = 0; k < K; k++) if (d[task][k] > 0)\n                    skill_est[j][k] = max((double)skill_lb[j][k], skill_est[j][k] - est_w * d[task][k] / totd * 0.15);\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> K >> R;\n    d.resize(N, vector<int>(K)); deps.resize(N); rev_deps.resize(N);\n    for (int i = 0; i < N; i++) for (int k = 0; k < K; k++) cin >> d[i][k];\n    for (int r = 0; r < R; r++) { int u, v; cin >> u >> v; u--; v--; deps[v].push_back(u); rev_deps[u].push_back(v); }\n    crit_path.resize(N, 0);\n    for (int i = N-1; i >= 0; i--) for (int v : rev_deps[i]) crit_path[i] = max(crit_path[i], crit_path[v]+1);\n    skill_est.resize(M, vector<double>(K)); skill_lb.resize(M, vector<int>(K, 0)); member_obs.resize(M);\n    for (int k = 0; k < K; k++) {\n        vector<int> dk(N); for (int i = 0; i < N; i++) dk[i] = d[i][k];\n        sort(dk.begin(), dk.end());\n        double init = dk[N/2];\n        for (int j = 0; j < M; j++) skill_est[j][k] = init;\n    }\n    vector<int> task_start(N,-1), task_done(N,-1), member_task(M,-1), member_start_day(M,-1);\n    set<int> available_tasks; vector<int> deps_rem(N);\n    for (int i = 0; i < N; i++) { deps_rem[i] = deps[i].size(); if (!deps_rem[i]) available_tasks.insert(i); }\n    int current_day = 0;\n    while (true) {\n        current_day++;\n        vector<int> free_members;\n        for (int j = 0; j < M; j++) if (member_task[j] == -1) free_members.push_back(j);\n        int fm = free_members.size();\n        if (fm > 0 && !available_tasks.empty()) {\n            vector<int> av(available_tasks.begin(), available_tasks.end());\n            sort(av.begin(), av.end(), [&](int a, int b){ return crit_path[a] > crit_path[b]; });\n            int nr = min((int)av.size(), fm*4), na = max(nr, fm);\n            vector<vector<double>> cost(fm, vector<double>(na, 1e9));\n            for (int mi = 0; mi < fm; mi++) { int j = free_members[mi];\n                for (int ti = 0; ti < nr; ti++) { int i = av[ti];\n                    double w = 0; for (int k = 0; k < K; k++) w += max(0.0, (double)d[i][k]-skill_est[j][k]);\n                    cost[mi][ti] = max(1.0, w) - crit_path[i]*0.15;\n                }\n            }\n            auto asgn = hungarian(cost);\n            vector<pair<int,int>> assigns;\n            for (int mi = 0; mi < fm; mi++) { int ti = asgn[mi];\n                if (ti >= 0 && ti < nr) assigns.push_back({free_members[mi], av[ti]});\n            }\n            cout << assigns.size();\n            for (auto [j,i] : assigns) {\n                cout << \" \" << (j+1) << \" \" << (i+1);\n                member_task[j]=i; member_start_day[j]=current_day; task_start[i]=current_day;\n                available_tasks.erase(i);\n            }\n            cout << endl;\n        } else cout << 0 << endl;\n        int n; cin >> n; if (n == -1) break;\n        for (int idx = 0; idx < n; idx++) {\n            int j; cin >> j; j--;\n            int i = member_task[j], tt = current_day - member_start_day[j] + 1;\n            task_done[i] = current_day;\n            if (tt == 1) for (int k = 0; k < K; k++) {\n                skill_lb[j][k] = max(skill_lb[j][k], d[i][k]);\n                skill_est[j][k] = max(skill_est[j][k], (double)d[i][k]);\n            }\n            member_obs[j].push_back({i, tt});\n            int oc = member_obs[j].size();\n            if (oc <= 5 || oc % 5 == 0) reestimate(j);\n            member_task[j] = -1;\n            for (int v : rev_deps[i]) { deps_rem[v]--; if (!deps_rem[v] && task_start[v]==-1) available_tasks.insert(v); }\n        }\n    }\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <climits>\n#include <cstring>\n#include <utility>\n\nusing namespace std;\n\nconst int N = 1000, M = 50, CX = 400, CY = 400;\nint a[N], b[N], c[N], d[N];\n\ninline int dist(int x1, int y1, int x2, int y2) { return abs(x1-x2) + abs(y1-y2); }\n\nstruct Xor128 {\n    unsigned x = 123456789, y = 362436069, z = 521288629, w = 88675123;\n    unsigned next() {\n        unsigned t = x ^ (x << 11);\n        x = y; y = z; z = w;\n        return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));\n    }\n    double nextDouble() {\n        return next() / 4294967295.0;\n    }\n    int nextInt(int n) {\n        return next() % n;\n    }\n};\n\nXor128 rng;\n\nint route[100];\nint bestRouteArr[100];\nint orders[M];\nint bestOrders[M];\nbool isSelected[N];\n\nint calcCost() {\n    int cost = 0, x = CX, y = CY;\n    for (int i = 0; i < 2 * M; i++) {\n        int ord = orders[route[i] / 2]; \n        bool isD = route[i] % 2;\n        int nx = isD ? c[ord] : a[ord], ny = isD ? d[ord] : b[ord];\n        cost += dist(x, y, nx, ny); \n        x = nx; y = ny;\n    }\n    return cost + dist(x, y, CX, CY);\n}\n\nbool isValidForInsert(int ip) {\n    int k = route[ip] / 2;\n    bool isD = route[ip] % 2;\n    if (!isD) { // It's a restaurant\n        for (int i = ip + 1; i < 2 * M; i++) {\n            if (route[i] == k * 2 + 1) return true;\n        }\n        return false;\n    } else { // It's a delivery\n        for (int i = 0; i < ip; i++) {\n            if (route[i] == k * 2) return true;\n        }\n        return false;\n    }\n}\n\nvoid constructRoute() {\n    bool vR[M], vD[M];\n    memset(vR, 0, sizeof vR);\n    memset(vD, 0, sizeof vD);\n    int cx = CX, cy = CY;\n    for (int step = 0; step < 2 * M; step++) {\n        int best = -1, bestD = INT_MAX;\n        for (int i = 0; i < M; i++) {\n            if (!vR[i]) { \n                int d2 = dist(cx, cy, a[orders[i]], b[orders[i]]); \n                if (d2 < bestD) { bestD = d2; best = i * 2; } \n            }\n            if (vR[i] && !vD[i]) { \n                int d2 = dist(cx, cy, c[orders[i]], d[orders[i]]); \n                if (d2 < bestD) { bestD = d2; best = i * 2 + 1; } \n            }\n        }\n        route[step] = best;\n        if (best % 2 == 0) { vR[best / 2] = true; cx = a[orders[best / 2]]; cy = b[orders[best / 2]]; }\n        else { vD[best / 2] = true; cx = c[orders[best / 2]]; cy = d[orders[best / 2]]; }\n    }\n}\n\npair<int, int> getCoord(int idx) {\n    if (idx < 0 || idx >= 2 * M) return {CX, CY};\n    int ord = orders[route[idx] / 2];\n    bool isD = route[idx] % 2;\n    if (isD) return {c[ord], d[ord]};\n    else return {a[ord], b[ord]};\n}\n\nint distByIdx(int i, int j) {\n    auto [x1, y1] = getCoord(i);\n    auto [x2, y2] = getCoord(j);\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    for (int i = 0; i < N; i++) cin >> a[i] >> b[i] >> c[i] >> d[i];\n    \n    auto startTime = chrono::high_resolution_clock::now();\n    \n    vector<pair<int,int>> scores;\n    for (int i = 0; i < N; i++) {\n        int cost = dist(CX, CY, a[i], b[i]) + dist(a[i], b[i], c[i], d[i]) + dist(c[i], d[i], CX, CY);\n        scores.push_back({cost, i});\n    }\n    sort(scores.begin(), scores.end());\n    \n    for (int i = 0; i < M; i++) { orders[i] = scores[i].second; isSelected[orders[i]] = true; }\n    \n    constructRoute();\n    int curCost = calcCost(), bestCost = curCost;\n    memcpy(bestRouteArr, route, sizeof(route));\n    memcpy(bestOrders, orders, sizeof(orders));\n    \n    double temp = 100.0, cooling = 0.99999;\n    int iter = 0;\n    \n    while (true) {\n        if (iter % 1000 == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            if (chrono::duration<double>(now - startTime).count() > 1.8) break;\n        }\n        iter++;\n        \n        int mt = rng.nextInt(10);\n        if (mt < 5) {\n            int from = rng.nextInt(2 * M), to = rng.nextInt(2 * M);\n            if (from == to) continue;\n            \n            int savedRoute[100];\n            memcpy(savedRoute, route, sizeof(route));\n            \n            int val = route[from];\n            for (int i = from; i < 2 * M - 1; i++) route[i] = route[i + 1];\n            int ip = to > from ? to - 1 : to;\n            for (int i = 2 * M - 1; i > ip; i--) route[i] = route[i - 1];\n            route[ip] = val;\n            \n            if (isValidForInsert(ip)) {\n                int nc = calcCost(); double d = nc - curCost;\n                if (d < 0 || rng.nextDouble() < exp(-d / temp)) { \n                    curCost = nc; \n                    if (nc < bestCost) { \n                        bestCost = nc; \n                        memcpy(bestRouteArr, route, sizeof(route));\n                        memcpy(bestOrders, orders, sizeof(orders));\n                    } \n                } else {\n                    memcpy(route, savedRoute, sizeof(route));\n                }\n            } else {\n                memcpy(route, savedRoute, sizeof(route));\n            }\n        } else if (mt < 8) {\n            int ii = rng.nextInt(M), oi = rng.nextInt(N);\n            if (isSelected[oi]) continue;\n            \n            int savedOrders[50];\n            memcpy(savedOrders, orders, sizeof(orders));\n            int savedRoute[100];\n            memcpy(savedRoute, route, sizeof(route));\n            \n            int oo = orders[ii]; \n            orders[ii] = oi; \n            isSelected[oo] = false; \n            isSelected[oi] = true;\n            \n            constructRoute(); \n            int nc = calcCost(); \n            double d = nc - curCost;\n            if (d < 0 || rng.nextDouble() < exp(-d / temp)) { \n                curCost = nc; \n                if (nc < bestCost) { \n                    bestCost = nc; \n                    memcpy(bestRouteArr, route, sizeof(route));\n                    memcpy(bestOrders, orders, sizeof(orders));\n                } \n            } else { \n                memcpy(orders, savedOrders, sizeof(orders));\n                isSelected[oi] = false; \n                isSelected[oo] = true; \n                memcpy(route, savedRoute, sizeof(route));\n            }\n        } else {\n            int l = rng.nextInt(2 * M - 1), r = l + 1 + rng.nextInt(2 * M - 1 - l);\n            bool valid = true;\n            bool inSegment[50] = {false};\n            for (int i = l; i <= r; i++) {\n                int k = route[i] / 2;\n                if (inSegment[k]) { valid = false; break; }\n                inSegment[k] = true;\n            }\n            if (valid) {\n                int delta = distByIdx(l - 1, r) + distByIdx(l, r + 1) - distByIdx(l - 1, l) - distByIdx(r, r + 1);\n                int nc = curCost + delta;\n                double d = nc - curCost;\n                if (d < 0 || rng.nextDouble() < exp(-d / temp)) { \n                    reverse(route + l, route + r + 1);\n                    curCost = nc; \n                    if (nc < bestCost) { \n                        bestCost = nc; \n                        memcpy(bestRouteArr, route, sizeof(route));\n                        memcpy(bestOrders, orders, sizeof(orders));\n                    } \n                }\n            }\n        }\n        temp *= cooling;\n    }\n    \n    cout << M;\n    for(int i = 0; i < M; i++) cout << \" \" << bestOrders[i] + 1;\n    cout << endl;\n    cout << 2 * M + 2 << \" \" << CX << \" \" << CY;\n    for(int i = 0; i < 2 * M; i++) {\n        int ord = bestOrders[bestRouteArr[i] / 2]; bool isD = bestRouteArr[i] % 2;\n        cout << \" \" << (isD ? c[ord] : a[ord]) << \" \" << (isD ? d[ord] : b[ord]);\n    }\n    cout << \" \" << CX << \" \" << CY << endl;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, rank_;\n    int components;\n    \n    UnionFind(int n) : parent(n), rank_(n, 0), components(n) {\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 (rank_[px] < rank_[py]) swap(px, py);\n        parent[py] = px;\n        if (rank_[px] == rank_[py]) rank_[px]++;\n        components--;\n        return true;\n    }\n    \n    bool connected(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, M = 1995;\n    vector<int> x(N), y(N);\n    vector<int> u(M), v(M);\n    vector<int> d(M);\n    \n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        double dist = sqrt((double)(x[u[i]] - x[v[i]]) * (x[u[i]] - x[v[i]]) + \n                           (double)(y[u[i]] - y[v[i]]) * (y[u[i]] - y[v[i]]));\n        d[i] = max(1, (int)round(dist));\n    }\n    \n    // Compute reference MST using d_i\n    vector<int> order(M);\n    for (int i = 0; i < M; i++) order[i] = i;\n    sort(order.begin(), order.end(), [&](int a, int b) { return d[a] < d[b]; });\n    \n    UnionFind refUF(N);\n    vector<bool> inRefMST(M, false);\n    for (int idx : order) {\n        if (refUF.unite(u[idx], v[idx])) {\n            inRefMST[idx] = true;\n        }\n    }\n    \n    // Process edges online\n    UnionFind uf(N);\n    \n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        int adopt = 0;\n        \n        if (!uf.connected(u[i], v[i])) {\n            if (inRefMST[i]) {\n                // Always accept reference MST edges - guarantees connectivity\n                adopt = 1;\n                uf.unite(u[i], v[i]);\n            } else {\n                // Accept non-MST edges only if they're cheap enough\n                // to potentially replace expensive MST edges\n                double percentile = (double)(l - d[i]) / (2.0 * d[i]);\n                percentile = max(0.0, min(1.0, percentile));\n                \n                int remaining = M - i - 1;\n                int needed = uf.components - 1;\n                double safety = (needed > 0) ? (double)remaining / needed : 999.0;\n                \n                double threshold;\n                if (safety >= 5) threshold = 0.3;\n                else if (safety >= 3) threshold = 0.4;\n                else if (safety >= 2) threshold = 0.5;\n                else threshold = 0.65;\n                \n                if (percentile <= threshold) {\n                    adopt = 1;\n                    uf.unite(u[i], v[i]);\n                }\n            }\n        }\n        \n        cout << adopt << endl;\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <cstring>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\n\nint N, M;\nvector<int> px, py, pt;\nvector<int> hx, hy;\nbool wall[SIZE][SIZE];\n\nbool inBounds(int x, int y) { return x >= 0 && x < SIZE && y >= 0 && y < SIZE; }\n\nvoid bfs(int sx, int sy, int dist[SIZE][SIZE]) {\n    memset(dist, -1, sizeof(int) * SIZE * SIZE);\n    if (!inBounds(sx, sy) || wall[sx][sy]) return;\n    queue<pair<int,int>> q;\n    dist[sx][sy] = 0;\n    q.push({sx, sy});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (inBounds(nx, ny) && !wall[nx][ny] && dist[nx][ny] == -1) {\n                dist[nx][ny] = dist[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n}\n\ndouble petThreatWeight(int t) {\n    switch(t) { case 1: return 1.0; case 2: return 1.5; case 3: return 2.0; case 4: return 2.5; case 5: return 2.0; default: return 1.0; }\n}\n\ndouble computeScoreWithDist(int dist[SIZE][SIZE]) {\n    int area = 0;\n    double effectivePets = 0;\n    for (int i = 0; i < SIZE; i++)\n        for (int j = 0; j < SIZE; j++)\n            if (dist[i][j] >= 0) area++;\n    for (int i = 0; i < N; i++)\n        if (dist[px[i]][py[i]] >= 0) effectivePets += 1.0;\n\n    int boundaryDist[SIZE][SIZE];\n    memset(boundaryDist, -1, sizeof(int) * SIZE * SIZE);\n    queue<pair<int,int>> q;\n    for (int x = 0; x < SIZE; x++)\n        for (int y = 0; y < SIZE; y++)\n            if (dist[x][y] < 0 && !wall[x][y]) {\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (inBounds(nx, ny) && dist[nx][ny] >= 0) {\n                        if (boundaryDist[x][y] == -1) { boundaryDist[x][y] = 1; q.push({x, y}); }\n                        break;\n                    }\n                }\n            }\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (inBounds(nx, ny) && !wall[nx][ny] && boundaryDist[nx][ny] == -1 && dist[nx][ny] < 0) {\n                boundaryDist[nx][ny] = boundaryDist[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        if (dist[px[i]][py[i]] >= 0) continue;\n        int d = boundaryDist[px[i]][py[i]];\n        if (d >= 1 && d <= 10) effectivePets += petThreatWeight(pt[i]) * 0.2 * exp(-0.2 * d);\n    }\n    return (double)area / 900.0 * pow(2.0, -effectivePets);\n}\n\nbool petAdjacentTo(int x, int y, const vector<int>& ppx, const vector<int>& ppy) {\n    for (int i = 0; i < N; i++) {\n        if (ppx[i] == x && ppy[i] == y) return true;\n        for (int d = 0; d < 4; d++)\n            if (ppx[i] == x + dx[d] && ppy[i] == y + dy[d]) return true;\n    }\n    return false;\n}\n\nbool humanAt(int x, int y, const vector<int>& hhx, const vector<int>& hhy) {\n    for (int i = 0; i < M; i++) if (hhx[i] == x && hhy[i] == y) return true;\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N;\n    px.resize(N); py.resize(N); pt.resize(N);\n    for (int i = 0; i < N; i++) { cin >> px[i] >> py[i] >> pt[i]; px[i]--; py[i]--; }\n    cin >> M;\n    hx.resize(M); hy.resize(M);\n    for (int i = 0; i < M; i++) { cin >> hx[i] >> hy[i]; hx[i]--; hy[i]--; }\n    memset(wall, false, sizeof(wall));\n\n    for (int turn = 0; turn < 300; turn++) {\n        vector<int> startPx = px, startPy = py, startHx = hx, startHy = hy;\n        string actions(M, '.');\n        bool newWall[SIZE][SIZE] = {};\n\n        for (int i = 0; i < M; i++) {\n            int myHx = startHx[i], myHy = startHy[i];\n            int distBefore[SIZE][SIZE];\n            bfs(myHx, myHy, distBefore);\n            double bestScore = computeScoreWithDist(distBefore);\n            char bestAction = '.';\n\n            for (int d = 0; d < 4; d++) {\n                int wx = myHx + dx[d], wy = myHy + dy[d];\n                if (inBounds(wx, wy) && !wall[wx][wy] && !newWall[wx][wy] &&\n                    !petAdjacentTo(wx, wy, startPx, startPy) && !humanAt(wx, wy, startHx, startHy)) {\n                    wall[wx][wy] = true;\n                    int distAfter[SIZE][SIZE];\n                    bfs(myHx, myHy, distAfter);\n                    double newScore = computeScoreWithDist(distAfter);\n                    for (int j = 0; j < N; j++)\n                        if (distBefore[startPx[j]][startPy[j]] >= 0 && distAfter[startPx[j]][startPy[j]] < 0)\n                            newScore += 0.05;\n                    for (int dd = 0; dd < 4; dd++) {\n                        int nx = wx + dx[dd], ny = wy + dy[dd];\n                        if (!inBounds(nx, ny) || wall[nx][ny]) newScore += 0.003;\n                    }\n                    newScore += 0.001;\n                    wall[wx][wy] = false;\n                    if (newScore > bestScore) { bestScore = newScore; bestAction = \"udlr\"[d]; }\n                }\n            }\n            for (int d = 0; d < 4; d++) {\n                int nx = myHx + dx[d], ny = myHy + dy[d];\n                if (inBounds(nx, ny) && !wall[nx][ny] && !newWall[nx][ny]) {\n                    int distAfter[SIZE][SIZE];\n                    bfs(nx, ny, distAfter);\n                    double newScore = computeScoreWithDist(distAfter);\n                    if (newScore > bestScore) { bestScore = newScore; bestAction = \"UDLR\"[d]; }\n                }\n            }\n            actions[i] = bestAction;\n            switch (actions[i]) {\n                case 'u': newWall[myHx-1][myHy]=true; wall[myHx-1][myHy]=true; break;\n                case 'd': newWall[myHx+1][myHy]=true; wall[myHx+1][myHy]=true; break;\n                case 'l': newWall[myHx][myHy-1]=true; wall[myHx][myHy-1]=true; break;\n                case 'r': newWall[myHx][myHy+1]=true; wall[myHx][myHy+1]=true; break;\n                case 'U': hx[i]=myHx-1; hy[i]=myHy; break;\n                case 'D': hx[i]=myHx+1; hy[i]=myHy; break;\n                case 'L': hx[i]=myHx; hy[i]=myHy-1; break;\n                case 'R': hx[i]=myHx; hy[i]=myHy+1; break;\n            }\n        }\n        cout << actions << endl;\n        for (int i = 0; i < N; i++) {\n            string move; cin >> move;\n            for (char c : move) {\n                if (c=='U') px[i]--; else if (c=='D') px[i]++;\n                else if (c=='L') py[i]--; else if (c=='R') py[i]++;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <cstring>\nusing namespace std;\n\nint si,sj,ti,tj;double p;int ti_idx;\nint md[400][4];bool itm[400][4];double fv[400][202];int c2d[256];\n\nvoid init(const vector<string>& h,const vector<string>& v){\n    ti_idx=ti*20+tj;\n    int di[]={-1,1,0,0},dj[]={0,0,-1,1};\n    for(int i=0;i<20;i++)for(int j=0;j<20;j++){int idx=i*20+j;\n        for(int d=0;d<4;d++){int ni=i+di[d],nj=j+dj[d];bool bl=false;\n            if(ni<0||ni>=20||nj<0||nj>=20)bl=true;\n            else if(d==0&&i>0&&v[i-1][j]=='1')bl=true;\n            else if(d==1&&v[i][j]=='1')bl=true;\n            else if(d==2&&j>0&&h[i][j-1]=='1')bl=true;\n            else if(d==3&&h[i][j]=='1')bl=true;\n            if(bl){ni=i;nj=j;}md[idx][d]=ni*20+nj;itm[idx][d]=(ni==ti&&nj==tj);}}\n    memset(fv,0,sizeof(fv));\n    for(int t=200;t>=1;t--)for(int i=0;i<400;i++){\n        if(i==ti_idx)fv[i][t]=401-t;\n        else{double b=0;for(int d=0;d<4;d++)b=max(b,p*fv[i][t+1]+(1-p)*fv[md[i][d]][t+1]);fv[i][t]=b;}}\n}\n\ndouble score(const string& s){double pr[400]={},np[400];pr[si*20+sj]=1;double es=0;\n    for(int t=0;t<(int)s.size();t++){int d=c2d[(unsigned char)s[t]];memset(np,0,sizeof(np));\n        for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;np[i]+=p*pr[i];int ni=md[i][d];\n            if(itm[i][d])es+=(1-p)*pr[i]*(401-t-1);else np[ni]+=(1-p)*pr[i];}\n        memcpy(pr,np,sizeof(pr));}return es;}\n\nstring bfs_path(){int dist[20][20],pd[20][20];memset(dist,-1,sizeof(dist));\n    queue<pair<int,int>>q;q.push({si,sj});dist[si][sj]=0;\n    while(!q.empty()){auto[i,j]=q.front();q.pop();if(i==ti&&j==tj)break;\n        for(int d=0;d<4;d++){int ni=md[i*20+j][d]/20,nj=md[i*20+j][d]%20;\n            if((ni!=i||nj!=j)&&dist[ni][nj]==-1){dist[ni][nj]=dist[i][j]+1;pd[ni][nj]=d;q.push({ni,nj});}}}\n    string path;int ci=ti,cj=tj;int di[]={-1,1,0,0},dj[]={0,0,-1,1};\n    while(ci!=si||cj!=sj){int d=pd[ci][cj];path=\"UDLR\"[d]+path;ci-=di[d];cj-=dj[d];}return path;}\n\nstring greedy(){double pr[400]={},np[400];pr[si*20+sj]=1;string res;\n    for(int t=1;t<=200;t++){double bs=-1;int ba=0;\n        for(int d=0;d<4;d++){double rp=0;memset(np,0,sizeof(np));\n            for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;np[i]+=p*pr[i];\n                if(itm[i][d])rp+=(1-p)*pr[i];else np[md[i][d]]+=(1-p)*pr[i];}\n            double sc=rp*(401-t);for(int i=0;i<400;i++)sc+=np[i]*fv[i][t+1];\n            if(sc>bs){bs=sc;ba=d;}}\n        res+=\"UDLR\"[ba];memset(np,0,sizeof(np));\n        for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;np[i]+=p*pr[i];\n            if(!itm[i][ba])np[md[i][ba]]+=(1-p)*pr[i];}memcpy(pr,np,sizeof(pr));}return res;}\n\nstring beam(int B){struct S{double pr[400];double acc,te;string s;};\n    vector<S>bm(1);memset(bm[0].pr,0,sizeof(bm[0].pr));bm[0].pr[si*20+sj]=1;bm[0].acc=0;bm[0].te=0;\n    for(int i=0;i<400;i++)bm[0].te+=bm[0].pr[i]*fv[i][1];\n    for(int t=1;t<=200;t++){vector<pair<double,int>>sc;vector<S>cand;\n        for(int bi=0;bi<(int)bm.size();bi++){for(int d=0;d<4;d++){S ns;memset(ns.pr,0,sizeof(ns.pr));ns.acc=bm[bi].acc;\n            for(int i=0;i<400;i++){if(bm[bi].pr[i]<1e-18)continue;ns.pr[i]+=p*bm[bi].pr[i];\n                if(itm[i][d])ns.acc+=(1-p)*bm[bi].pr[i]*(401-t);else ns.pr[md[i][d]]+=(1-p)*bm[bi].pr[i];}\n            ns.s=bm[bi].s+\"UDLR\"[d];ns.te=ns.acc;for(int i=0;i<400;i++)ns.te+=ns.pr[i]*fv[i][t+1];\n            sc.push_back({ns.te,(int)cand.size()});cand.push_back(move(ns));}}\n        int k=min(B,(int)sc.size());\n        if((int)sc.size()>k)partial_sort(sc.begin(),sc.begin()+k,sc.end(),[](auto&a,auto&b){return a.first>b.first;});\n        vector<S>nb(k);for(int i=0;i<k;i++)nb[i]=move(cand[sc[i].second]);bm=move(nb);}\n    double bs=-1;string br;for(auto&st:bm){double s=score(st.s);if(s>bs){bs=s;br=st.s;}}return br;}\n\nvoid suffix_opt(string&best,double&bs){auto ts=[&](const string&s){double sc=score(s);if(sc>bs){bs=sc;best=s;}};\n    for(int k:vector<int>{50,100,150}){if(k>=(int)best.size())continue;\n        double pr[400]={};pr[si*20+sj]=1;\n        for(int t=0;t<k;t++){int d=c2d[(unsigned char)best[t]];double np[400]={};\n            for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;np[i]+=p*pr[i];\n                if(!itm[i][d])np[md[i][d]]+=(1-p)*pr[i];}memcpy(pr,np,sizeof(pr));}\n        string ns=best.substr(0,k);\n        for(int t=k+1;t<=200;t++){double bsc=-1;int ba=0;\n            for(int d=0;d<4;d++){double rp=0;double np[400]={};\n                for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;np[i]+=p*pr[i];\n                    if(itm[i][d])rp+=(1-p)*pr[i];else np[md[i][d]]+=(1-p)*pr[i];}\n                double sc=rp*(401-t);for(int i=0;i<400;i++)sc+=np[i]*fv[i][t+1];if(sc>bsc){bsc=sc;ba=d;}}\n            ns+=\"UDLR\"[ba];double np[400]={};\n            for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;np[i]+=p*pr[i];\n                if(!itm[i][ba])np[md[i][ba]]+=(1-p)*pr[i];}memcpy(pr,np,sizeof(pr));}\n        ts(ns);}}\n\nint main(){ios_base::sync_with_stdio(false);cin.tie(nullptr);\n    c2d['U']=0;c2d['D']=1;c2d['L']=2;c2d['R']=3;\n    cin>>si>>sj>>ti>>tj>>p;vector<string>h(20),v(19);\n    for(int i=0;i<20;i++)cin>>h[i];for(int i=0;i<19;i++)cin>>v[i];init(h,v);\n    string best;double bs=-1;auto ts=[&](const string&s){double sc=score(s);if(sc>bs){bs=sc;best=s;}};\n    string sp=bfs_path();\n    {string s;while((int)(s.size()+sp.size())<=200)s+=sp;ts(s);}\n    for(int r=2;r<=5;r++){string s;for(char c:sp)for(int k=0;k<r&&(int)s.size()<200;k++)s+=c;ts(s);}\n    ts(greedy());ts(beam(10));ts(beam(20));\n    suffix_opt(best,bs);\n    mt19937 rng(42);for(int it=0;it<500;it++){string ns=best;\n        int pos=uniform_int_distribution<int>(0,(int)ns.size()-1)(rng);\n        ns[pos]=\"UDLR\"[uniform_int_distribution<int>(0,3)(rng)];\n        double sc=score(ns);if(sc>bs){bs=sc;best=ns;}}\n    suffix_opt(best,bs);\n    for(int len=100;len<200;len+=25)ts(best.substr(0,len));\n    cout<<best<<endl;}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint orig_tiles[N][N], rotations[N][N], current_tiles[N][N];\nconst int di[] = {0, -1, 0, 1}, dj[] = {-1, 0, 1, 0};\nconst int to_table[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 rotated_type[8][4];\n\nvoid init_rotated_type() {\n    for (int t = 0; t < 8; t++) {\n        rotated_type[t][0] = t;\n        int cur = t;\n        for (int r = 1; r < 4; r++) {\n            if (cur <= 3) cur = (cur + 1) % 4;\n            else if (cur == 4) cur = 5; else if (cur == 5) cur = 4;\n            else if (cur == 6) cur = 7; else cur = 6;\n            rotated_type[t][r] = cur;\n        }\n    }\n}\n\nvoid update_all_tiles() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            current_tiles[i][j] = rotated_type[orig_tiles[i][j]][rotations[i][j]];\n}\n\npair<int,int> compute_top2() {\n    static bool visited[N][N][4];\n    memset(visited, 0, sizeof(visited));\n    int max1 = 0, max2 = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int t = current_tiles[i][j];\n            for (int d = 0; d < 4; d++) {\n                if (visited[i][j][d] || to_table[t][d] == -1) { visited[i][j][d] = true; continue; }\n                int si = i, sj = j, sd = d, ci = i, cj = j, cd = d, length = 0;\n                while (true) {\n                    visited[ci][cj][cd] = true;\n                    int t2 = current_tiles[ci][cj], d2 = to_table[t2][cd];\n                    if (d2 == -1) break;\n                    int ni = ci + di[d2], nj = cj + dj[d2];\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n                    int nd = (d2 + 2) % 4; length++;\n                    if (ni == si && nj == sj && nd == sd) {\n                        if (length > max1) { max2 = max1; max1 = length; }\n                        else if (length > max2) max2 = length;\n                        break;\n                    }\n                    ci = ni; cj = nj; cd = nd;\n                }\n            }\n        }\n    }\n    return {max1, max2};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    init_rotated_type();\n    for (int i = 0; i < N; i++) { string s; cin >> s; for (int j = 0; j < N; j++) orig_tiles[i][j] = s[j] - '0'; }\n    \n    mt19937 rng(42);\n    long long global_best_score = 0; int global_best_rotations[N][N] = {};\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    for (int trial = 0; trial < 10; trial++) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration<double>(now - start_time).count() > 1.5) break;\n        \n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) rotations[i][j] = rng() % 4;\n        update_all_tiles();\n        \n        auto [m1, m2] = compute_top2();\n        long long cur_score = (long long)m1 * m2, best_score = cur_score;\n        int best_rotations[N][N]; memcpy(best_rotations, rotations, sizeof(rotations));\n        \n        uniform_int_distribution<int> pos_dist(0, N*N-1), rot_dist(0, 3);\n        uniform_real_distribution<double> prob_dist(0.0, 1.0);\n        \n        for (int iter = 0; iter < 30000; iter++) {\n            now = chrono::high_resolution_clock::now();\n            if (chrono::duration<double>(now - start_time).count() > 1.7) break;\n            double temp = 100.0 * pow(0.01, min((double)iter / 30000.0, 1.0));\n            \n            int idx = pos_dist(rng), i = idx / N, j = idx % N;\n            int old_rot = rotations[i][j], new_rot = rot_dist(rng);\n            if (old_rot == new_rot) continue;\n            \n            rotations[i][j] = new_rot;\n            current_tiles[i][j] = rotated_type[orig_tiles[i][j]][new_rot];\n            \n            auto [nm1, nm2] = compute_top2();\n            long long new_score = (long long)nm1 * nm2;\n            \n            if (new_score - cur_score > 0 || prob_dist(rng) < exp((double)(new_score - cur_score) / max(temp, 0.001))) {\n                cur_score = new_score;\n                if (cur_score > best_score) { best_score = cur_score; memcpy(best_rotations, rotations, sizeof(rotations)); }\n            } else { rotations[i][j] = old_rot; current_tiles[i][j] = rotated_type[orig_tiles[i][j]][old_rot]; }\n        }\n        if (best_score > global_best_score) { global_best_score = best_score; memcpy(global_best_rotations, best_rotations, sizeof(best_rotations)); }\n    }\n    \n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cout << global_best_rotations[i][j];\n    cout << endl;\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nint board[10][10];\nint er, ec;\nint par[100], gsz[100];\n\nint find_root(int x) {\n    while (par[x] != x) x = par[x] = par[par[x]];\n    return x;\n}\n\nvoid unite(int x, int y) {\n    x = find_root(x); y = find_root(y);\n    if (x == y) return;\n    if (gsz[x] < gsz[y]) swap(x, y);\n    par[y] = x; gsz[x] += gsz[y];\n}\n\nint compute_max_tree_size() {\n    for (int i = 0; i < N*N; i++) { par[i] = i; gsz[i] = 0; }\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j]) gsz[i*N+j] = 1;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N-1; j++)\n            if (board[i][j] && board[i][j+1] && (board[i][j] & 4) && (board[i][j+1] & 1))\n                unite(i*N+j, i*N+j+1);\n    for (int i = 0; i < N-1; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j] && board[i+1][j] && (board[i][j] & 8) && (board[i+1][j] & 2))\n                unite(i*N+j, (i+1)*N+j);\n    int mx = 0;\n    for (int i = 0; i < N*N; i++) mx = max(mx, gsz[i]);\n    return mx;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> T;\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) {\n            char c = s[j];\n            board[i][j] = (c >= '0' && c <= '9') ? c - '0' : c - 'a' + 10;\n            if (!board[i][j]) { er = i; ec = j; }\n        }\n    }\n    \n    string moves; moves.reserve(T);\n    int cur_sz = compute_max_tree_size();\n    int best_sz = cur_sz, best_idx = 0;\n    mt19937 rng(42);\n    constexpr int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};\n    constexpr char dc_c[] = {'U','D','L','R'};\n    constexpr int rev_dir[] = {1,0,3,2};\n    int last_d = -1;\n    auto start = chrono::high_resolution_clock::now();\n    double temp = 2.5;\n    int no_improve = 0;\n    \n    while ((int)moves.size() < T) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now-start).count() > 2900) break;\n        \n        int ns[4];\n        for (int d = 0; d < 4; d++) {\n            int nr = er+dr[d], nc = ec+dc[d];\n            if (nr<0||nr>=N||nc<0||nc>=N) { ns[d] = -1; continue; }\n            swap(board[er][ec], board[nr][nc]);\n            int oer=er, oec=ec; er=nr; ec=nc;\n            ns[d] = compute_max_tree_size();\n            swap(board[er][ec], board[oer][oec]); er=oer; ec=oec;\n        }\n        \n        int best_d = -1, best_ns = -1;\n        for (int d = 0; d < 4; d++)\n            if (ns[d] > best_ns) { best_ns = ns[d]; best_d = d; }\n        if (best_d == -1) break;\n        \n        int chosen;\n        if (best_ns > cur_sz) {\n            chosen = best_d;\n            no_improve = 0;\n        } else {\n            no_improve++;\n            double delta = best_ns - cur_sz;\n            double prob = exp(delta / max(temp, 0.001));\n            if ((double)rng() / (double)UINT32_MAX < prob) {\n                chosen = best_d;\n            } else {\n                int valid[4], nv = 0;\n                for (int d = 0; d < 4; d++) {\n                    if (ns[d] < 0) continue;\n                    if (last_d >= 0 && d == rev_dir[last_d]) continue;\n                    valid[nv++] = d;\n                }\n                if (nv == 0)\n                    for (int d = 0; d < 4; d++)\n                        if (ns[d] >= 0) valid[nv++] = d;\n                if (nv == 0) break;\n                chosen = valid[rng() % nv];\n            }\n        }\n        \n        int nr = er+dr[chosen], nc = ec+dc[chosen];\n        swap(board[er][ec], board[nr][nc]);\n        er = nr; ec = nc;\n        moves += dc_c[chosen];\n        cur_sz = ns[chosen];\n        last_d = chosen;\n        \n        if (cur_sz > best_sz) { best_sz = cur_sz; best_idx = moves.size(); }\n        \n        temp *= 0.9997;\n        if (no_improve > 40) { temp = min(temp * 1.8, 6.0); no_improve = 20; }\n        if (best_sz == N*N-1) break;\n    }\n    \n    cout << moves.substr(0, best_idx) << endl;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\n\nint N, K;\nint a[11];\nvector<ll> px, py;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> K;\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    px.resize(N); py.resize(N);\n    for (int i = 0; i < N; i++) cin >> px[i] >> py[i];\n    \n    vector<array<ll, 4>> lines;\n    auto start = chrono::steady_clock::now();\n    \n    for (int iter = 0; iter < K; iter++) {\n        if (chrono::duration<double>(chrono::steady_clock::now() - start).count() > 2.0) break;\n        \n        map<vector<int>, vector<int>> groups;\n        for (int i = 0; i < N; i++) {\n            vector<int> sig; bool dead = false;\n            for (auto& L : lines) {\n                ll la = L[3]-L[1], lb = L[0]-L[2], lc = L[2]*L[1]-L[0]*L[3];\n                ll val = la*px[i] + lb*py[i] + lc;\n                if (val == 0) { dead = true; break; }\n                sig.push_back(val > 0 ? 1 : -1);\n            }\n            if (!dead) groups[sig].push_back(i);\n        }\n        \n        int pc[11] = {};\n        for (auto& [s, m] : groups) { int sz = m.size(); if (sz >= 1 && sz <= 10) pc[sz]++; }\n        int cur_score = 0;\n        for (int d = 1; d <= 10; d++) cur_score += min(a[d], pc[d]);\n        int max_score = 0;\n        for (int d = 1; d <= 10; d++) max_score += a[d];\n        if (cur_score == max_score) break;\n        \n        vector<pair<int, array<ll,4>>> cands;\n        auto try_line = [&](ll x1, ll y1, ll x2, ll y2) {\n            if (x1 == x2 && y1 == y2) return;\n            ll la = y2-y1, lb = x1-x2, lc = x2*y1-x1*y2;\n            int new_pc[11] = {};\n            for (auto& [sig, members] : groups) {\n                int pos = 0, neg = 0;\n                for (int i : members) {\n                    ll val = la*px[i] + lb*py[i] + lc;\n                    if (val > 0) pos++; else if (val < 0) neg++;\n                }\n                if (pos >= 1 && pos <= 10) new_pc[pos]++;\n                if (neg >= 1 && neg <= 10) new_pc[neg]++;\n            }\n            int score = 0;\n            for (int d = 1; d <= 10; d++) score += min(a[d], new_pc[d]);\n            cands.push_back({score, {x1, y1, x2, y2}});\n        };\n        \n        for (auto& [sig, members] : groups) {\n            int sz = members.size();\n            if (sz <= 1) continue;\n            if (sz <= 10 && pc[sz] <= a[sz]) continue;\n            int lim = min((int)members.size(), 20);\n            for (int ii = 0; ii < lim; ii++)\n                for (int jj = ii+1; jj < lim; jj++) {\n                    int i = members[ii], j = members[jj];\n                    ll sx = px[i]+px[j], sy = py[i]+py[j];\n                    ll dx = 2*(py[i]-py[j]), dy = 2*(px[j]-px[i]);\n                    try_line(sx, sy, sx+dx, sy+dy);\n                }\n            ll cx = 0, cy = 0;\n            for (int i : members) { cx += px[i]; cy += py[i]; }\n            for (int angle = 0; angle < 18; angle++) {\n                double a_rad = angle * M_PI / 9;\n                ll dx = (ll)round(10000*cos(a_rad)), dy = (ll)round(10000*sin(a_rad));\n                if (dx == 0 && dy == 0) continue;\n                try_line(cx, cy, cx + dx*sz, cy + dy*sz);\n            }\n        }\n        \n        mt19937 rng(iter*12345+67890);\n        for (int r = 0; r < 50; r++) {\n            ll x1 = rng()%20001-10000, y1 = rng()%20001-10000;\n            ll x2 = rng()%20001-10000, y2 = rng()%20001-10000;\n            try_line(x1, y1, x2, y2);\n        }\n        \n        if (cands.empty()) break;\n        int best = 0;\n        for (int i = 1; i < (int)cands.size(); i++)\n            if (cands[i].first > cands[best].first) best = i;\n        lines.push_back(cands[best].second);\n    }\n    \n    cout << lines.size() << \"\\n\";\n    for (auto& L : lines)\n        cout << L[0] << \" \" << L[1] << \" \" << L[2] << \" \" << L[3] << \"\\n\";\n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nvector<vector<bool>> has_dot;\nvector<array<int,8>> ops;\nmap<int,vector<pair<int,int>>> segs[4];\n\nint seg_type(int x1,int y1,int x2,int y2){\n    if(y1==y2)return 0;\n    if(x1==x2)return 1;\n    if(x2-x1==y2-y1)return 2;\n    return 3;\n}\nint line_id(int t,int x,int y){\n    if(t==0)return y;if(t==1)return x;\n    if(t==2)return x-y;return x+y;\n}\n\nbool check_overlap(int t,int lid,int s,int e){\n    if(s>e)swap(s,e);\n    auto it=segs[t].find(lid);\n    if(it==segs[t].end())return false;\n    for(auto&[a,b]:it->second){\n        int lo=min(a,b),hi=max(a,b);\n        if(max(s,lo)<min(e,hi))return true;\n    }\n    return false;\n}\nvoid add_seg(int t,int lid,int s,int e){segs[t][lid].push_back({s,e});}\n\nbool has_perim_overlap(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    int e[4][4]={{x1,y1,x2,y2},{x2,y2,x3,y3},{x3,y3,x4,y4},{x4,y4,x1,y1}};\n    for(int i=0;i<4;i++){\n        int t=seg_type(e[i][0],e[i][1],e[i][2],e[i][3]);\n        int lid=line_id(t,e[i][0],e[i][1]);\n        int s=(t<2)?(t==0?e[i][0]:e[i][1]):e[i][0];\n        int ee=(t<2)?(t==0?e[i][2]:e[i][3]):e[i][2];\n        if(check_overlap(t,lid,s,ee))return true;\n    }\n    return false;\n}\nvoid add_perim(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    int e[4][4]={{x1,y1,x2,y2},{x2,y2,x3,y3},{x3,y3,x4,y4},{x4,y4,x1,y1}};\n    for(int i=0;i<4;i++){\n        int t=seg_type(e[i][0],e[i][1],e[i][2],e[i][3]);\n        int lid=line_id(t,e[i][0],e[i][1]);\n        int s=(t<2)?(t==0?e[i][0]:e[i][1]):e[i][0];\n        int ee=(t<2)?(t==0?e[i][2]:e[i][3]):e[i][2];\n        add_seg(t,lid,s,ee);\n    }\n}\n\nbool dot_on_perim(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    set<pair<int,int>>corners={{x1,y1},{x2,y2},{x3,y3},{x4,y4}};\n    auto chk=[&](int ax,int ay,int bx,int by){\n        int dx=bx-ax,dy=by-ay,st=max(abs(dx),abs(dy));\n        if(!st)return false;\n        int sx=dx/st,sy=dy/st;\n        for(int i=1;i<st;i++){\n            int px=ax+i*sx,py=ay+i*sy;\n            if(!corners.count({px,py})&&has_dot[px][py])return true;\n        }\n        return false;\n    };\n    return chk(x1,y1,x2,y2)||chk(x2,y2,x3,y3)||chk(x3,y3,x4,y4)||chk(x4,y4,x1,y1);\n}\n\nbool valid(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    if(dot_on_perim(x1,y1,x2,y2,x3,y3,x4,y4))return false;\n    if(has_perim_overlap(x1,y1,x2,y2,x3,y3,x4,y4))return false;\n    return true;\n}\n\nvector<int> find_rect(int ex,int ey){\n    // Axis-aligned\n    for(int x2=0;x2<N;x2++)if(x2!=ex)\n        for(int y2=0;y2<N;y2++)if(y2!=ey)\n            if(has_dot[ex][y2]&&has_dot[x2][ey]&&has_dot[x2][y2])\n                if(valid(ex,ey,ex,y2,x2,y2,x2,ey))\n                    return {ex,ey,ex,y2,x2,y2,x2,ey};\n    \n    // Tilted orientation 1: V1->V2 (1,1), V2->V3 (1,-1)\n    auto try_tilt=[&](int v1x,int v1y,int v2x,int v2y,int v3x,int v3y,int v4x,int v4y){\n        if(v1x<0||v1x>=N||v1y<0||v1y>=N)return false;\n        if(v2x<0||v2x>=N||v2y<0||v2y>=N)return false;\n        if(v3x<0||v3x>=N||v3y<0||v3y>=N)return false;\n        if(v4x<0||v4x>=N||v4y<0||v4y>=N)return false;\n        if(!has_dot[v2x][v2y]||!has_dot[v3x][v3y]||!has_dot[v4x][v4y])return false;\n        return valid(v1x,v1y,v2x,v2y,v3x,v3y,v4x,v4y);\n    };\n    \n    for(int a=1;a<N;a++)for(int b=1;b<N;b++){\n        int v2x=ex+a,v2y=ey+a,v3x=ex+a+b,v3y=ey+a-b,v4x=ex+b,v4y=ey-b;\n        if(try_tilt(ex,ey,v2x,v2y,v3x,v3y,v4x,v4y))return {ex,ey,v2x,v2y,v3x,v3y,v4x,v4y};\n        \n        int u1x=ex-a,u1y=ey-a;v3x=ex+b;v3y=ey-b;v4x=ex-a+b;v4y=ey-a-b;\n        if(try_tilt(u1x,u1y,ex,ey,v3x,v3y,v4x,v4y))return {u1x,u1y,ex,ey,v3x,v3y,v4x,v4y};\n        \n        u1x=ex-a-b;u1y=ey-a+b;int u2x=ex-b,u2y=ey+b;v4x=ex-a;v4y=ey-a;\n        if(try_tilt(u1x,u1y,u2x,u2y,ex,ey,v4x,v4y))return {u1x,u1y,u2x,u2y,ex,ey,v4x,v4y};\n        \n        u1x=ex-b;u1y=ey+b;int u3x=ex+a,u3y=ey+a;v4x=ex-b+a;v4y=ey+b+a;\n        if(try_tilt(u1x,u1y,v4x,v4y,u3x,u3y,ex,ey))return {u1x,u1y,v4x,v4y,u3x,u3y,ex,ey};\n    }\n    \n    // Tilted orientation 2: V1->V2 (1,-1), V2->V3 (1,1)\n    for(int a=1;a<N;a++)for(int b=1;b<N;b++){\n        int v2x=ex+a,v2y=ey-a,v3x=ex+a+b,v3y=ey-a+b,v4x=ex+b,v4y=ey+b;\n        if(try_tilt(ex,ey,v2x,v2y,v3x,v3y,v4x,v4y))return {ex,ey,v2x,v2y,v3x,v3y,v4x,v4y};\n        \n        int u1x=ex-a,u1y=ey+a;v3x=ex+b;v3y=ey+b;v4x=ex-a+b;v4y=ey+a+b;\n        if(try_tilt(u1x,u1y,ex,ey,v3x,v3y,v4x,v4y))return {u1x,u1y,ex,ey,v3x,v3y,v4x,v4y};\n        \n        u1x=ex-a-b;u1y=ey+a-b;int u2x=ex-b,u2y=ey-b;v4x=ex-a;v4y=ey+a;\n        if(try_tilt(u1x,u1y,u2x,u2y,ex,ey,v4x,v4y))return {u1x,u1y,u2x,u2y,ex,ey,v4x,v4y};\n        \n        u1x=ex-b;u1y=ey-b;int u3x=ex+a,u3y=ey-a;v4x=ex-b+a;v4y=ey-b-a;\n        if(try_tilt(u1x,u1y,v4x,v4y,u3x,u3y,ex,ey))return {u1x,u1y,v4x,v4y,u3x,u3y,ex,ey};\n    }\n    return {};\n}\n\nint main(){\n    cin>>N>>M;\n    has_dot.assign(N,vector<bool>(N,false));\n    for(int i=0;i<M;i++){int x,y;cin>>x>>y;has_dot[x][y]=true;}\n    \n    double c=(N-1)/2.0;\n    bool found=true;\n    while(found){\n        found=false;\n        double best_w=-1;vector<int>best_r;\n        for(int x=0;x<N;x++)for(int y=0;y<N;y++){\n            if(has_dot[x][y])continue;\n            double w=(x-c)*(x-c)+(y-c)*(y-c)+1;\n            if(w<=best_w)continue;\n            auto r=find_rect(x,y);\n            if(!r.empty()){best_w=w;best_r=r;found=true;}\n        }\n        if(found){\n            int x1=best_r[0],y1=best_r[1],x2=best_r[2],y2=best_r[3];\n            int x3=best_r[4],y3=best_r[5],x4=best_r[6],y4=best_r[7];\n            has_dot[x1][y1]=true;\n            add_perim(x1,y1,x2,y2,x3,y3,x4,y4);\n            ops.push_back({x1,y1,x2,y2,x3,y3,x4,y4});\n        }\n    }\n    cout<<ops.size()<<endl;\n    for(auto&op:ops){\n        for(int i=0;i<8;i++)cout<<op[i]<<(i<7?\" \":\"\\n\");\n    }\n}","ahc015":"#include <iostream>\n#include <cstring>\n#include <queue>\n#include <vector>\n#include <random>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nint f[101];\nmt19937 rng(42);\n\nvoid tiltGrid(int g[N][N], int d) {\n    if (d == 0) {\n        for (int c = 0; c < N; c++) {\n            int w = 0;\n            for (int r = 0; r < N; r++) {\n                if (g[r][c]) { if (w != r) { g[w][c] = g[r][c]; g[r][c] = 0; } w++; }\n            }\n        }\n    } else if (d == 1) {\n        for (int c = 0; c < N; c++) {\n            int w = N - 1;\n            for (int r = N - 1; r >= 0; r--) {\n                if (g[r][c]) { if (w != r) { g[w][c] = g[r][c]; g[r][c] = 0; } w--; }\n            }\n        }\n    } else if (d == 2) {\n        for (int r = 0; r < N; r++) {\n            int w = 0;\n            for (int c = 0; c < N; c++) {\n                if (g[r][c]) { if (w != c) { g[r][w] = g[r][c]; g[r][c] = 0; } w++; }\n            }\n        }\n    } else {\n        for (int r = 0; r < N; r++) {\n            int w = N - 1;\n            for (int c = N - 1; c >= 0; c--) {\n                if (g[r][c]) { if (w != c) { g[r][w] = g[r][c]; g[r][c] = 0; } w--; }\n            }\n        }\n    }\n}\n\nlong long calcScore(int g[N][N]) {\n    bool visited[N][N] = {};\n    long long score = 0;\n    int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (!visited[r][c] && g[r][c]) {\n                int flavor = g[r][c], size = 0;\n                queue<pair<int,int>> q;\n                q.push({r, c}); visited[r][c] = true;\n                while (!q.empty()) {\n                    auto [cr, cc] = q.front(); q.pop(); size++;\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 && !visited[nr][nc] && g[nr][nc] == flavor) {\n                            visited[nr][nc] = true; q.push({nr, nc});\n                        }\n                    }\n                }\n                score += (long long)size * size;\n            }\n        }\n    }\n    return score;\n}\n\nlong long calcPotential(int g[N][N], int turn) {\n    if (turn >= 100) return 0;\n    int nextFlavor = f[turn + 1];\n    long long potential = 0;\n    int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (g[r][c] == 0) {\n                for (int d = 0; d < 4; d++) {\n                    int nr = r + dr[d], nc = c + dc[d];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && g[nr][nc] == nextFlavor) {\n                        potential++; break;\n                    }\n                }\n            }\n        }\n    }\n    // Also count adjacency within same flavor groups\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (g[r][c]) {\n                if (r + 1 < N && g[r+1][c] == g[r][c]) potential++;\n                if (c + 1 < N && g[r][c+1] == g[r][c]) potential++;\n            }\n        }\n    }\n    return potential;\n}\n\nlong long simulate(int start_t, int orig_g[N][N]) {\n    int g[N][N];\n    memcpy(g, orig_g, sizeof(g));\n    for (int t = start_t; t <= 100; t++) {\n        pair<int,int> empty_cells[100];\n        int cnt = 0;\n        for (int r = 0; r < N; r++)\n            for (int c = 0; c < N; c++)\n                if (g[r][c] == 0) empty_cells[cnt++] = {r, c};\n        if (cnt == 0) break;\n        int idx = rng() % cnt;\n        g[empty_cells[idx].first][empty_cells[idx].second] = f[t];\n        // Greedy tilt in simulation\n        long long best = -1; int best_d = 1;\n        int saved[N][N];\n        for (int d = 0; d < 4; d++) {\n            memcpy(saved, g, sizeof(g));\n            tiltGrid(g, d);\n            long long sc = calcScore(g);\n            if (sc > best) { best = sc; best_d = d; }\n            memcpy(g, saved, sizeof(g));\n        }\n        tiltGrid(g, best_d);\n    }\n    return calcScore(g);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 1; i <= 100; i++) cin >> f[i];\n    memset(grid, 0, sizeof(grid));\n    \n    string dirs = \"FBLR\";\n    int priority[] = {4, 1, 2, 3}; // B > L > R > F\n    \n    for (int t = 1; t <= 100; t++) {\n        int p; cin >> p;\n        int pos = 1, pr = -1, pc = -1;\n        for (int r = 0; r < N && pr == -1; r++)\n            for (int c = 0; c < N && pr == -1; c++)\n                if (grid[r][c] == 0) { if (pos == p) { pr = r; pc = c; } pos++; }\n        grid[pr][pc] = f[t];\n        \n        long long scores[4], pot[4];\n        int saved[N][N];\n        for (int d = 0; d < 4; d++) {\n            memcpy(saved, grid, sizeof(grid));\n            tiltGrid(grid, d);\n            scores[d] = calcScore(grid);\n            pot[d] = calcPotential(grid, t);\n            memcpy(grid, saved, sizeof(grid));\n        }\n        \n        long long maxScore = *max_element(scores, scores + 4);\n        vector<int> cands;\n        for (int d = 0; d < 4; d++) if (scores[d] == maxScore) cands.push_back(d);\n        \n        int best_dir;\n        if (cands.size() == 1) {\n            best_dir = cands[0];\n        } else {\n            // Use potential to narrow down\n            long long maxPot = -1;\n            for (int d : cands) maxPot = max(maxPot, pot[d]);\n            vector<int> cands2;\n            for (int d : cands) if (pot[d] == maxPot) cands2.push_back(d);\n            \n            if (cands2.size() == 1) {\n                best_dir = cands2[0];\n            } else if (t < 85) {\n                // Monte Carlo tiebreak\n                int num_sims = max(10, 50 - t / 3);\n                long long mc[4] = {};\n                for (int d : cands2) {\n                    int temp[N][N];\n                    memcpy(temp, grid, sizeof(grid));\n                    tiltGrid(temp, d);\n                    for (int s = 0; s < num_sims; s++) mc[d] += simulate(t + 1, temp);\n                }\n                best_dir = cands2[0];\n                for (int d : cands2) if (mc[d] > mc[best_dir]) best_dir = d;\n            } else {\n                best_dir = *min_element(cands2.begin(), cands2.end(), [&](int a, int b) { return priority[a] < priority[b]; });\n            }\n        }\n        \n        tiltGrid(grid, best_dir);\n        cout << dirs[best_dir] << '\\n';\n        cout.flush();\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M; double eps;\n    cin >> M >> eps;\n    \n    int N;\n    {\n        double f = sqrt(max(eps * (1.0 - eps), 0.001));\n        N = (int)round(2.5 * M * f + sqrt(2.0 * M) + 3);\n        N = max(4, min(100, N));\n    }\n    \n    int maxE = N * (N - 1) / 2;\n    mt19937 rng(42);\n    \n    auto eidx = [&](int i, int j) -> int {\n        if (i > j) swap(i, j);\n        return i * (2 * N - i - 1) / 2 + (j - i - 1);\n    };\n    \n    auto sortedDeg = [&](const string& g) -> vector<int> {\n        vector<int> d(N, 0);\n        for (int i = 0; i < N; i++)\n            for (int j = i + 1; j < N; j++) {\n                if (g[i * (2*N-i-1)/2 + (j-i-1)] == '1') { d[i]++; d[j]++; }\n            }\n        sort(d.begin(), d.end());\n        return d;\n    };\n    \n    int NC = min(2000, max(M * 10, 500));\n    vector<string> cands(NC, string(maxE, '0'));\n    vector<vector<int>> cdeg(NC);\n    \n    for (int c = 0; c < NC; c++) {\n        string g(maxE, '0');\n        if (c < NC / 3) {\n            double dens = (c + 1.0) / (NC / 3 + 1);\n            int te = max(0, min(maxE, (int)round(dens * maxE)));\n            vector<int> p(maxE); iota(p.begin(), p.end(), 0);\n            shuffle(p.begin(), p.end(), rng);\n            for (int i = 0; i < te; i++) g[p[i]] = '1';\n        } else if (c < 2 * NC / 3) {\n            int code = c - NC / 3;\n            vector<int> b(N, 0);\n            int numOnes = code / max(1, (NC / 3 / N)) + 1;\n            int offset = code % max(1, (NC / 3 / N));\n            for (int i = 0; i < min(numOnes, N); i++) {\n                int pos = (offset + i * (N / max(numOnes, 1))) % N;\n                b[pos] = 1;\n            }\n            for (int j = 0; j < N; j++)\n                if (b[j])\n                    for (int i = 0; i < j; i++)\n                        g[eidx(i, j)] = '1';\n        } else {\n            int code = c - 2 * NC / 3;\n            int cliqueSz = (code / max(1, NC / 3 / N)) + 1;\n            cliqueSz = min(cliqueSz, N);\n            int crossE = code % max(1, NC / 3 / N);\n            for (int i = 0; i < cliqueSz; i++)\n                for (int j = i + 1; j < cliqueSz; j++)\n                    g[eidx(i, j)] = '1';\n            int added = 0;\n            for (int i = 0; i < cliqueSz && added < crossE; i++)\n                for (int j = cliqueSz; j < N && added < crossE; j++) {\n                    g[eidx(i, j)] = '1'; added++;\n                }\n        }\n        cands[c] = g;\n        cdeg[c] = sortedDeg(g);\n    }\n    \n    vector<vector<double>> fp(NC, vector<double>(N));\n    for (int c = 0; c < NC; c++)\n        for (int i = 0; i < N; i++)\n            fp[c][i] = cdeg[c][i] * (1.0 - 2.0 * eps) + (N - 1) * eps;\n    \n    vector<int> sel;\n    vector<double> minD(NC, 1e18);\n    vector<bool> used(NC, false);\n    \n    sel.push_back(0); used[0] = true;\n    for (int c = 0; c < NC; c++) {\n        double d = 0;\n        for (int i = 0; i < N; i++) { double df = fp[c][i] - fp[0][i]; d += df * df; }\n        minD[c] = d;\n    }\n    \n    for (int k = 1; k < M; k++) {\n        int best = -1; double bestD = -1;\n        for (int c = 0; c < NC; c++) {\n            if (used[c]) continue;\n            if (minD[c] > bestD) { bestD = minD[c]; best = c; }\n        }\n        sel.push_back(best); used[best] = true;\n        for (int c = 0; c < NC; c++) {\n            if (used[c]) continue;\n            double d = 0;\n            for (int i = 0; i < N; i++) { double df = fp[c][i] - fp[best][i]; d += df * df; }\n            minD[c] = min(minD[c], d);\n        }\n    }\n    \n    // Precompute adjacency matrices for Hamming distance decoding\n    vector<vector<int>> adjM(M, vector<int>(maxE));\n    vector<vector<double>> gfp(M, vector<double>(N));\n    for (int k = 0; k < M; k++) {\n        gfp[k] = fp[sel[k]];\n        for (int e = 0; e < maxE; e++) adjM[k][e] = (cands[sel[k]][e] == '1') ? 1 : 0;\n    }\n    \n    cout << N << \"\\n\";\n    for (int k = 0; k < M; k++) cout << cands[sel[k]] << \"\\n\";\n    cout.flush();\n    \n    double dVar = max(1.0, (N - 1.0) * eps * (1.0 - eps));\n    \n    for (int q = 0; q < 100; q++) {\n        string H; cin >> H;\n        vector<int> hd = sortedDeg(H);\n        \n        // Primary: fingerprint distance\n        int bestK = 0; double bestS = -1e18;\n        for (int k = 0; k < M; k++) {\n            double s = 0;\n            for (int i = 0; i < N; i++) {\n                double diff = hd[i] - gfp[k][i];\n                s -= diff * diff / (2.0 * dVar);\n            }\n            if (s > bestS) { bestS = s; bestK = k; }\n        }\n        \n        cout << bestK << \"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\ntypedef long long ll;\ntypedef pair<ll, int> pli;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n    \n    vector<int> u(M), v(M), w(M);\n    vector<vector<pair<int, int>>> adj(N);\n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i] >> w[i];\n        u[i]--; v[i]--;\n        adj[u[i]].push_back({i, v[i]});\n        adj[v[i]].push_back({i, u[i]});\n    }\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    // Build edge adjacency (edges sharing a vertex)\n    vector<vector<int>> edge_adj(M);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < (int)adj[i].size(); j++) {\n            for (int k = j + 1; k < (int)adj[i].size(); k++) {\n                edge_adj[adj[i][j].first].push_back(adj[i][k].first);\n                edge_adj[adj[i][k].first].push_back(adj[i][j].first);\n            }\n        }\n    }\n    \n    // Compute edge midpoints\n    vector<double> mx(M), my(M);\n    for (int i = 0; i < M; i++) {\n        mx[i] = (x[u[i]] + x[v[i]]) / 2.0;\n        my[i] = (y[u[i]] + y[v[i]]) / 2.0;\n    }\n    \n    // Sort by angle from center for geographic spreading\n    double cx = 500, cy = 500;\n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    \n    sort(order.begin(), order.end(), [&](int a, int b) {\n        double ax = mx[a] - cx, ay = my[a] - cy;\n        double bx = mx[b] - cx, by = my[b] - cy;\n        double aa = atan2(ay, ax), ab = atan2(by, bx);\n        if (abs(aa - ab) > 1e-9) return aa < ab;\n        double da = ax*ax + ay*ay, db = bx*bx + by*by;\n        return da < db;\n    });\n    \n    // Greedy edge coloring with conflict avoidance\n    vector<int> r(M, -1);\n    vector<int> day_count(D, 0);\n    \n    for (int idx : order) {\n        vector<int> conflicts(D, 0);\n        for (int e : edge_adj[idx]) {\n            if (r[e] != -1) conflicts[r[e]]++;\n        }\n        \n        int best_day = -1;\n        double best_score = 1e18;\n        for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K) continue;\n            double score = day_count[d] * 10.0 + conflicts[d] * 100.0;\n            if (score < best_score) {\n                best_score = score;\n                best_day = d;\n            }\n        }\n        \n        if (best_day == -1) {\n            for (int d = 0; d < D; d++) {\n                if (day_count[d] < K && (best_day == -1 || day_count[d] < day_count[best_day])) {\n                    best_day = d;\n                }\n            }\n        }\n        \n        r[idx] = best_day;\n        day_count[best_day]++;\n    }\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        cout << r[i] + 1 << (i == M-1 ? \"\\n\" : \" \");\n    }\n    \n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <tuple>\n#include <climits>\n#include <map>\nusing namespace std;\n\nint D;\nusing Point = tuple<int,int,int>;\nusing Array3D = vector<vector<vector<int>>>;\n\nvector<string> readSilhouette() {\n    vector<string> s(D);\n    for (int i = 0; i < D; i++) cin >> s[i];\n    return s;\n}\n\nArray3D buildMaxFill(const vector<string>& f, const vector<string>& r) {\n    Array3D b(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for (int x = 0; x < D; x++)\n        for (int y = 0; y < D; y++)\n            for (int z = 0; z < D; z++)\n                if (f[z][x] == '1' && r[z][y] == '1') b[x][y][z] = 1;\n    return b;\n}\n\nvector<vector<Point>> findComponents(const Array3D& b) {\n    Array3D vis(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<Point>> comps;\n    const int dx[] = {1,-1,0,0,0,0}, dy[] = {0,0,1,-1,0,0}, dz[] = {0,0,0,0,1,-1};\n    for (int x = 0; x < D; x++) for (int y = 0; y < D; y++) for (int z = 0; z < D; z++) {\n        if (b[x][y][z] == 1 && !vis[x][y][z]) {\n            vector<Point> comp; queue<Point> q; q.push({x,y,z}); vis[x][y][z] = 1;\n            while (!q.empty()) {\n                auto [cx,cy,cz] = q.front(); q.pop(); comp.push_back({cx,cy,cz});\n                for (int d = 0; d < 6; d++) {\n                    int nx=cx+dx[d], ny=cy+dy[d], nz=cz+dz[d];\n                    if (0<=nx&&nx<D&&0<=ny&&ny<D&&0<=nz&&nz<D&&b[nx][ny][nz]==1&&!vis[nx][ny][nz]) {\n                        vis[nx][ny][nz] = 1; q.push({nx,ny,nz});\n                    }\n                }\n            }\n            comps.push_back(move(comp));\n        }\n    }\n    return comps;\n}\n\nPoint rotX(const Point& p) { auto [x,y,z]=p; return {x,-z,y}; }\nPoint rotY(const Point& p) { auto [x,y,z]=p; return {z,y,-x}; }\nPoint rotZ(const Point& p) { auto [x,y,z]=p; return {-y,x,z}; }\n\nvector<Point> applyRotation(const vector<Point>& comp, int r1, int r2, int r3) {\n    vector<Point> result;\n    for (auto p : comp) {\n        for (int i = 0; i < r1; i++) p = rotX(p);\n        for (int i = 0; i < r2; i++) p = rotY(p);\n        for (int i = 0; i < r3; i++) p = rotZ(p);\n        result.push_back(p);\n    }\n    int minX=INT_MAX, minY=INT_MAX, minZ=INT_MAX;\n    for (auto& [x,y,z] : result) { minX=min(minX,x); minY=min(minY,y); minZ=min(minZ,z); }\n    for (auto& [x,y,z] : result) { x-=minX; y-=minY; z-=minZ; }\n    sort(result.begin(), result.end());\n    return result;\n}\n\nvector<Point> canonicalForm(const vector<Point>& comp) {\n    vector<Point> best;\n    for (int r1 = 0; r1 < 4; r1++) for (int r2 = 0; r2 < 4; r2++) for (int r3 = 0; r3 < 4; r3++) {\n        vector<Point> rot = applyRotation(comp, r1, r2, r3);\n        if (best.empty() || rot < best) best = rot;\n    }\n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> D;\n    vector<vector<string>> f(2), r(2);\n    for (int i = 0; i < 2; i++) { f[i] = readSilhouette(); r[i] = readSilhouette(); }\n    \n    auto b0 = buildMaxFill(f[0], r[0]);\n    auto b1 = buildMaxFill(f[1], r[1]);\n    auto comps0 = findComponents(b0);\n    auto comps1 = findComponents(b1);\n    int n0 = comps0.size(), n1 = comps1.size();\n    \n    map<vector<Point>, vector<int>> canonMap1;\n    vector<vector<Point>> canon0(n0), canon1(n1);\n    for (int i = 0; i < n0; i++) canon0[i] = canonicalForm(comps0[i]);\n    for (int j = 0; j < n1; j++) { canon1[j] = canonicalForm(comps1[j]); canonMap1[canon1[j]].push_back(j); }\n    \n    vector<int> order0(n0); for (int i = 0; i < n0; i++) order0[i] = i;\n    sort(order0.begin(), order0.end(), [&](int a, int b) { return comps0[a].size() > comps0[b].size(); });\n    \n    vector<int> match0(n0, -1), match1(n1, -1);\n    vector<bool> used1(n1, false);\n    for (int i : order0) {\n        auto it = canonMap1.find(canon0[i]);\n        if (it != canonMap1.end()) {\n            for (int j : it->second) {\n                if (!used1[j]) { match0[i]=j; match1[j]=i; used1[j]=true; break; }\n            }\n        }\n    }\n    \n    vector<vector<vector<bool>>> matched0(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> matched1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    for (int i = 0; i < n0; i++) if (match0[i] != -1) {\n        for (auto [x,y,z] : comps0[i]) matched0[x][y][z] = true;\n        for (auto [x,y,z] : comps1[match0[i]]) matched1[x][y][z] = true;\n    }\n    \n    Array3D remIsect(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for (int x = 0; x < D; x++) for (int y = 0; y < D; y++) for (int z = 0; z < D; z++)\n        if (b0[x][y][z] && b1[x][y][z] && !matched0[x][y][z] && !matched1[x][y][z]) remIsect[x][y][z] = 1;\n    \n    auto sharedComps = findComponents(remIsect);\n    vector<vector<vector<bool>>> isSharedIsect(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    for (auto& comp : sharedComps) for (auto [x,y,z] : comp) isSharedIsect[x][y][z] = true;\n    \n    Array3D remUn0(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    Array3D remUn1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for (int x = 0; x < D; x++) for (int y = 0; y < D; y++) for (int z = 0; z < D; z++) {\n        if (b0[x][y][z] && !matched0[x][y][z] && !isSharedIsect[x][y][z]) remUn0[x][y][z] = 1;\n        if (b1[x][y][z] && !matched1[x][y][z] && !isSharedIsect[x][y][z]) remUn1[x][y][z] = 1;\n    }\n    auto unsharedComps0 = findComponents(remUn0);\n    auto unsharedComps1 = findComponents(remUn1);\n    \n    int nextId = 1;\n    vector<int> id0(n0, -1), id1(n1, -1);\n    for (int i = 0; i < n0; i++) if (match0[i] != -1) { id0[i] = nextId; id1[match0[i]] = nextId++; }\n    int nSI = sharedComps.size();\n    vector<int> sharedIsectId(nSI); for (int i = 0; i < nSI; i++) sharedIsectId[i] = nextId++;\n    int nU0 = unsharedComps0.size(), nU1 = unsharedComps1.size();\n    vector<int> unsharedId0(nU0), unsharedId1(nU1);\n    for (int i = 0; i < nU0; i++) unsharedId0[i] = nextId++;\n    for (int i = 0; i < nU1; i++) unsharedId1[i] = nextId++;\n    \n    vector<int> out0(D*D*D, 0), out1(D*D*D, 0);\n    for (int i = 0; i < n0; i++) if (match0[i] != -1)\n        for (auto [x,y,z] : comps0[i]) out0[x*D*D+y*D+z] = id0[i];\n    for (int j = 0; j < n1; j++) if (match1[j] != -1)\n        for (auto [x,y,z] : comps1[j]) out1[x*D*D+y*D+z] = id1[j];\n    for (int c = 0; c < nSI; c++) for (auto [x,y,z] : sharedComps[c]) {\n        out0[x*D*D+y*D+z] = sharedIsectId[c]; out1[x*D*D+y*D+z] = sharedIsectId[c];\n    }\n    for (int c = 0; c < nU0; c++) for (auto [x,y,z] : unsharedComps0[c]) out0[x*D*D+y*D+z] = unsharedId0[c];\n    for (int c = 0; c < nU1; c++) for (auto [x,y,z] : unsharedComps1[c]) out1[x*D*D+y*D+z] = unsharedId1[c];\n    \n    cout << nextId - 1 << \"\\n\";\n    for (int j = 0; j < D*D*D; j++) { if (j) cout << \" \"; cout << out0[j]; }\n    cout << \"\\n\";\n    for (int j = 0; j < D*D*D; j++) { if (j) cout << \" \"; cout << out1[j]; }\n    cout << \"\\n\";\n    return 0;\n}","ahc020":"#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, K;\n    cin >> N >> M >> K;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<vector<pair<int, int>>> adj(N);\n    vector<int> u(M), v(M), w(M);\n    for (int j = 0; j < M; j++) {\n        cin >> u[j] >> v[j] >> w[j];\n        u[j]--; v[j]--;\n        adj[u[j]].push_back({v[j], j});\n        adj[v[j]].push_back({u[j], j});\n    }\n    \n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    vector<vector<double>> res_dist(K, vector<double>(N));\n    vector<vector<int>> closest(K);\n    for (int k = 0; k < K; k++) {\n        vector<pair<double, int>> dists;\n        for (int i = 0; i < N; i++) {\n            double dx = a[k] - x[i], dy = b[k] - y[i];\n            res_dist[k][i] = sqrt(dx*dx + dy*dy);\n            dists.push_back({res_dist[k][i], i});\n        }\n        sort(dists.begin(), dists.end());\n        for (int j = 0; j < min(10, N); j++) closest[k].push_back(dists[j].second);\n    }\n    \n    vector<long long> sp_dist(N, LLONG_MAX);\n    vector<int> parent(N, -1);\n    sp_dist[0] = 0;\n    priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<>> pq;\n    pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, v] = pq.top(); pq.pop();\n        if (d > sp_dist[v]) continue;\n        for (auto [to, eid] : adj[v]) {\n            if (sp_dist[v] + w[eid] < sp_dist[to]) {\n                sp_dist[to] = sp_dist[v] + w[eid];\n                parent[to] = v;\n                pq.push({sp_dist[to], to});\n            }\n        }\n    }\n    \n    vector<int> assignment(K);\n    for (int k = 0; k < K; k++) assignment[k] = closest[k][0];\n    \n    auto compute_P = [&]() {\n        vector<double> max_dist(N, 0);\n        for (int k = 0; k < K; k++)\n            max_dist[assignment[k]] = max(max_dist[assignment[k]], res_dist[k][assignment[k]]);\n        vector<int> P(N, 0);\n        for (int i = 0; i < N; i++)\n            if (max_dist[i] > 0) P[i] = min((int)ceil(max_dist[i]), 5000);\n        return P;\n    };\n    \n    auto compute_B = [&](const vector<int>& P) {\n        vector<int> B(M, 0);\n        for (int i = 1; i < N; i++) {\n            if (P[i] > 0) {\n                int cur = i;\n                while (cur != 0) {\n                    int p = parent[cur];\n                    if (p == -1) break;\n                    for (auto& [to, eid] : adj[cur])\n                        if (to == p) { B[eid] = 1; break; }\n                    cur = p;\n                }\n            }\n        }\n        return B;\n    };\n    \n    auto compute_cost = [&](const vector<int>& P, const vector<int>& B) {\n        long long cost = 0;\n        for (int i = 0; i < N; i++) cost += (long long)P[i] * P[i];\n        for (int j = 0; j < M; j++) if (B[j]) cost += w[j];\n        return cost;\n    };\n    \n    vector<int> P = compute_P();\n    vector<int> B = compute_B(P);\n    long long cost = compute_cost(P, B);\n    \n    mt19937 rng(42);\n    uniform_real_distribution<> uniform(0.0, 1.0);\n    double start_temp = 1e7, end_temp = 1e1;\n    int max_iter = 150000;\n    \n    for (int iter = 0; iter < max_iter; iter++) {\n        double temp = start_temp * pow(end_temp / start_temp, (double)iter / max_iter);\n        int k = rng() % K;\n        int old_assign = assignment[k];\n        int new_assign = closest[k][rng() % closest[k].size()];\n        if (new_assign == old_assign) continue;\n        \n        assignment[k] = new_assign;\n        vector<int> new_P = compute_P();\n        vector<int> new_B = compute_B(new_P);\n        long long new_cost = compute_cost(new_P, new_B);\n        \n        long long delta = new_cost - cost;\n        if (delta < 0 || uniform(rng) < exp(-(double)delta / temp)) {\n            cost = new_cost; P = new_P; B = new_B;\n        } else {\n            assignment[k] = old_assign;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) cout << P[i] << (i < N-1 ? \" \" : \"\\n\");\n    for (int j = 0; j < M; j++) cout << B[j] << (j < M-1 ? \" \" : \"\\n\");\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint grid[N][N];\nvector<array<int, 4>> swaps;\n\nint main() {\n    ios_base::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 >> grid[x][y];\n    \n    auto siftDown = [&](int x, int y) {\n        while (x < N - 1) {\n            int lv = grid[x+1][y], rv = grid[x+1][y+1], cv = grid[x][y];\n            if (cv <= lv && cv <= rv) break;\n            if (lv <= rv) {\n                swap(grid[x][y], grid[x+1][y]);\n                swaps.push_back({x, y, x+1, y});\n                x++;\n            } else {\n                swap(grid[x][y], grid[x+1][y+1]);\n                swaps.push_back({x, y, x+1, y+1});\n                x++; y++;\n            }\n            if (swaps.size() >= 9999) return;\n        }\n    };\n    \n    // Heapify: bottom to top, full sift-down\n    for (int x = N - 2; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            siftDown(x, y);\n            if (swaps.size() >= 9999) goto done;\n        }\n    }\n    \n    // Iteratively fix remaining violations\n    // (caused by triangular grid's dual-parent structure)\n    for (int iter = 0; iter < 500; iter++) {\n        bool any = false;\n        for (int x = N - 2; x >= 0; x--) {\n            for (int y = 0; y <= x; y++) {\n                if (grid[x][y] > grid[x+1][y] || grid[x][y] > grid[x+1][y+1]) {\n                    any = true;\n                    // One-step fix: swap parent with smaller child\n                    if (grid[x+1][y] <= grid[x+1][y+1]) {\n                        swap(grid[x][y], grid[x+1][y]);\n                        swaps.push_back({x, y, x+1, y});\n                    } else {\n                        swap(grid[x][y], grid[x+1][y+1]);\n                        swaps.push_back({x, y, x+1, y+1});\n                    }\n                    if (swaps.size() >= 9999) goto done;\n                }\n            }\n        }\n        if (!any) break;\n    }\n    \ndone:\n    cout << swaps.size() << \"\\n\";\n    for (auto& s : swaps)\n        cout << s[0] << \" \" << s[1] << \" \" << s[2] << \" \" << s[3] << \"\\n\";\n    \n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <set>\n\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    vector<vector<bool>> is_obstacle(D, vector<bool>(D, false));\n    for (int i = 0; i < N; i++) {\n        int ri, rj;\n        cin >> ri >> rj;\n        is_obstacle[ri][rj] = true;\n    }\n    \n    int entrance_i = 0, entrance_j = (D - 1) / 2;\n    \n    vector<vector<int>> dist(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    q.push({entrance_i, entrance_j});\n    dist[entrance_i][entrance_j] = 0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    \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 (ni >= 0 && ni < D && nj >= 0 && nj < D && dist[ni][nj] == -1 && !is_obstacle[ni][nj]) {\n                dist[ni][nj] = dist[i][j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    vector<tuple<int, int, int>> cells;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (!(i == entrance_i && j == entrance_j) && !is_obstacle[i][j])\n                cells.push_back({dist[i][j], i, j});\n    \n    sort(cells.begin(), cells.end());\n    int M = cells.size();\n    \n    set<int> available_ranks;\n    for (int k = 0; k < M; k++) available_ranks.insert(k);\n    \n    vector<vector<int>> container_at(D, vector<int>(D, -1));\n    \n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        int target_rank = t;\n        \n        auto it = available_ranks.lower_bound(target_rank);\n        int best_rank = -1, best_diff = M + 1;\n        \n        if (it != available_ranks.end() && abs(*it - target_rank) < best_diff) {\n            best_diff = abs(*it - target_rank);\n            best_rank = *it;\n        }\n        if (it != available_ranks.begin()) {\n            --it;\n            if (abs(*it - target_rank) < best_diff) {\n                best_diff = abs(*it - target_rank);\n                best_rank = *it;\n            }\n        }\n        \n        available_ranks.erase(best_rank);\n        auto [dd, pi, pj] = cells[best_rank];\n        cout << pi << \" \" << pj << endl;\n        container_at[pi][pj] = t;\n    }\n    \n    vector<vector<bool>> is_empty(D, vector<bool>(D, false));\n    is_empty[entrance_i][entrance_j] = true;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (is_obstacle[i][j]) is_empty[i][j] = true;\n    \n    for (int iter = 0; iter < M; iter++) {\n        vector<vector<bool>> accessible(D, vector<bool>(D, false));\n        queue<pair<int, int>> bfs_q;\n        bfs_q.push({entrance_i, entrance_j});\n        accessible[entrance_i][entrance_j] = true;\n        \n        while (!bfs_q.empty()) {\n            auto [i, j] = bfs_q.front(); bfs_q.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D && !accessible[ni][nj] && is_empty[ni][nj]) {\n                    accessible[ni][nj] = true;\n                    bfs_q.push({ni, nj});\n                }\n            }\n        }\n        \n        int min_t = M + 1, min_i = -1, min_j = -1;\n        for (int i = 0; i < D; i++)\n            for (int j = 0; j < D; j++)\n                if (container_at[i][j] >= 0 && accessible[i][j] && container_at[i][j] < min_t) {\n                    min_t = container_at[i][j];\n                    min_i = i; min_j = j;\n                }\n        \n        cout << min_i << \" \" << min_j << endl;\n        is_empty[min_i][min_j] = true;\n        container_at[min_i][min_j] = -1;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\nconst int dx[] = {0, 0, 1, -1};\nconst int dy[] = {1, -1, 0, 0};\n\nint n, m;\nint grid[N][N], best_grid[N][N];\nint best_score;\nset<pair<int,int>> required_adj;\nint adj_cnt[M+1][M+1];\n\nbool valid(int x, int y) { return 0 <= x && x < n && 0 <= y && y < n; }\n\nvoid compute_init_adj() {\n    memset(adj_cnt, 0, sizeof(adj_cnt));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) {\n            if (j+1 < n && grid[i][j] != grid[i][j+1])\n                adj_cnt[min(grid[i][j],grid[i][j+1])][max(grid[i][j],grid[i][j+1])]++;\n            if (i+1 < n && grid[i][j] != grid[i+1][j])\n                adj_cnt[min(grid[i][j],grid[i+1][j])][max(grid[i][j],grid[i+1][j])]++;\n            if (i==0||i==n-1||j==0||j==n-1)\n                adj_cnt[0][grid[i][j]]++;\n        }\n    for (int a = 0; a <= m; a++)\n        for (int b = a; b <= m; b++)\n            if (adj_cnt[a][b] > 0) required_adj.insert({a,b});\n}\n\nbool check_c0_conn() {\n    bool has0 = false;\n    for (int i = 0; i < n && !has0; i++)\n        for (int j = 0; j < n && !has0; j++)\n            if (grid[i][j] == 0) has0 = true;\n    if (!has0) return true;\n    \n    vector<vector<bool>> vis(n, vector<bool>(n));\n    queue<pair<int,int>> q;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (grid[i][j] == 0 && (i==0||i==n-1||j==0||j==n-1))\n                { q.push({i,j}); vis[i][j] = true; }\n    \n    while (!q.empty()) {\n        auto [x,y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx=x+dx[d], ny=y+dy[d];\n            if (valid(nx,ny) && !vis[nx][ny] && grid[nx][ny]==0)\n                { vis[nx][ny] = true; q.push({nx,ny}); }\n        }\n    }\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (grid[i][j] == 0 && !vis[i][j]) return false;\n    return true;\n}\n\nbool can_change(int i, int j, int nc) {\n    int oc = grid[i][j];\n    if (oc == nc) return true;\n    if (nc != 0) {\n        bool found = false;\n        for (int d = 0; d < 4; d++) {\n            int ni=i+dx[d], nj=j+dy[d];\n            if (valid(ni,nj) && grid[ni][nj] == nc) { found = true; break; }\n        }\n        if (!found) return false;\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        if (valid(ni,nj)) {\n            int c = grid[ni][nj];\n            if (oc != c) delta[{min(oc,c),max(oc,c)}]--;\n            if (nc != c) delta[{min(nc,c),max(nc,c)}]++;\n        }\n    }\n    if (i==0||i==n-1||j==0||j==n-1) {\n        if (oc != 0) delta[{0,oc}]--;\n        if (nc != 0) delta[{0,nc}]++;\n    }\n    for (auto& [p,d] : delta) {\n        int ncnt = adj_cnt[p.first][p.second] + d;\n        if (ncnt > 0 && required_adj.find(p) == required_adj.end()) return false;\n        if (ncnt <= 0 && required_adj.find(p) != required_adj.end()) return false;\n    }\n    grid[i][j] = nc;\n    bool ok = check_c0_conn();\n    grid[i][j] = oc;\n    return ok;\n}\n\nvoid apply_change(int i, int j, int nc) {\n    int oc = grid[i][j];\n    for (int d = 0; d < 4; d++) {\n        int ni=i+dx[d], nj=j+dy[d];\n        if (valid(ni,nj)) {\n            int c = grid[ni][nj];\n            if (oc != c) adj_cnt[min(oc,c)][max(oc,c)]--;\n            if (nc != c) adj_cnt[min(nc,c)][max(nc,c)]++;\n        }\n    }\n    if (i==0||i==n-1||j==0||j==n-1) {\n        if (oc != 0) adj_cnt[0][oc]--;\n        if (nc != 0) adj_cnt[0][nc]++;\n    }\n    grid[i][j] = nc;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> n >> m;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) cin >> grid[i][j];\n    \n    compute_init_adj();\n    memcpy(best_grid, grid, sizeof(grid));\n    best_score = 2501;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (grid[i][j] == 0) best_score++;\n    \n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < n; i++)\n            for (int j = 0; j < n; j++)\n                if (grid[i][j] == 0) {\n                    for (int d = 0; d < 4; d++) {\n                        int ni=i+dx[d], nj=j+dy[d];\n                        if (valid(ni,nj) && grid[ni][nj] != 0)\n                            if (can_change(i, j, grid[ni][nj])) {\n                                apply_change(i, j, grid[ni][nj]);\n                                improved = true;\n                                break;\n                            }\n                    }\n                }\n    }\n    \n    int cnt0 = 0;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (grid[i][j] == 0) cnt0++;\n    if (cnt0+1 < best_score) {\n        best_score = cnt0+1;\n        memcpy(best_grid, grid, sizeof(grid));\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << best_grid[i][j];\n            if (j < n-1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\nint N, D, Q;\nint qc = 0;\nint cmp[105][105];\n\nchar query(int a, int b) {\n    if (cmp[a][b] != 0) return cmp[a][b] == 1 ? '>' : '<';\n    if (qc >= Q) return '=';\n    \n    qc++;\n    cout << \"1 1 \" << a << \" \" << b << endl;\n    char res;\n    cin >> res;\n    \n    if (res == '<') {\n        cmp[a][b] = -1;\n        cmp[b][a] = 1;\n    } else if (res == '>') {\n        cmp[a][b] = 1;\n        cmp[b][a] = -1;\n    }\n    return res;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    for (int i = 0; i < N; i++) items[i] = i;\n    \n    // Insertion sort using comparisons\n    for (int i = 1; i < N; i++) {\n        int j = i;\n        while (j > 0 && qc < Q) {\n            int a = items[j-1], b = items[j];\n            if (cmp[a][b] == 1) {\n                swap(items[j-1], items[j]);\n                j--;\n            } else if (cmp[a][b] == -1) {\n                break;\n            } else {\n                char res = query(a, b);\n                if (res == '>') {\n                    swap(items[j-1], items[j]);\n                    j--;\n                } else {\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Use remaining queries to verify sort\n    for (int i = 1; i < N && qc < Q; i++) {\n        if (cmp[items[i-1]][items[i]] == 0) {\n            query(items[i-1], items[i]);\n        }\n    }\n    \n    // Use remaining queries for random comparisons\n    mt19937 rng(42);\n    while (qc < Q) {\n        int x = rng() % N, y = rng() % N;\n        if (x != y && cmp[x][y] == 0) {\n            query(x, y);\n        }\n    }\n    \n    // Estimate weights using exponential distribution assumption\n    vector<double> est_weight(N);\n    for (int i = 0; i < N; i++) {\n        double p = (double)(i + 1) / (N + 1);\n        est_weight[items[i]] = -log(1.0 - p);\n    }\n    \n    // LPT partitioning: assign heaviest items first to lightest group\n    vector<double> group_weight(D, 0);\n    vector<int> assignment(N);\n    \n    for (int i = N - 1; i >= 0; i--) {\n        int item = items[i];\n        int min_group = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_weight[g] < group_weight[min_group]) {\n                min_group = g;\n            }\n        }\n        assignment[item] = min_group;\n        group_weight[min_group] += est_weight[item];\n    }\n    \n    // Output assignment\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n        }\n    }\n    \n    vector<int> box_stack(n + 1), box_pos(n + 1);\n    for (int i = 0; i < m; i++) {\n        for (int j = 0; j < (int)stacks[i].size(); j++) {\n            box_stack[stacks[i][j]] = i;\n            box_pos[stacks[i][j]] = j;\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    \n    for (int v = 1; v <= n; v++) {\n        int sid = box_stack[v], pos = box_pos[v];\n        int cur = (int)stacks[sid].size() - 1;\n        \n        while (cur > pos) {\n            int run_end = cur;\n            int run_start = cur;\n            \n            while (run_start > pos + 1 && stacks[sid][run_start - 1] > stacks[sid][run_start]) {\n                run_start--;\n            }\n            \n            int max_in_run = stacks[sid][run_start];\n            \n            int dest = -1;\n            int best_score = INT_MAX;\n            int best_secondary = INT_MIN;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == sid) continue;\n                \n                int score;\n                int secondary;\n                \n                if (stacks[i].empty()) {\n                    score = 0;\n                    secondary = -1;\n                } else {\n                    int top_val = stacks[i].back();\n                    if (top_val > max_in_run) {\n                        score = 0;\n                        secondary = -top_val;\n                    } else {\n                        score = 0;\n                        for (int j = run_start; j <= run_end; j++) {\n                            if (stacks[sid][j] > top_val) score++;\n                        }\n                        secondary = top_val;\n                    }\n                }\n                \n                if (score < best_score || (score == best_score && secondary > best_secondary)) {\n                    best_score = score;\n                    best_secondary = secondary;\n                    dest = i;\n                }\n            }\n            \n            if (dest == -1) dest = (sid + 1) % m;\n            \n            int u = stacks[sid][run_start];\n            operations.push_back({u, dest + 1});\n            \n            vector<int> moved(stacks[sid].begin() + run_start, stacks[sid].begin() + run_end + 1);\n            stacks[sid].resize(run_start);\n            stacks[dest].insert(stacks[dest].end(), moved.begin(), moved.end());\n            \n            for (int j = 0; j < (int)moved.size(); j++) {\n                box_stack[moved[j]] = dest;\n                box_pos[moved[j]] = stacks[dest].size() - moved.size() + j;\n            }\n            \n            cur = run_start - 1;\n        }\n        \n        operations.push_back({v, 0});\n        stacks[sid].pop_back();\n    }\n    \n    for (auto& op : operations) {\n        cout << op.first << \" \" << op.second << endl;\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\nchar dir_char[] = {'R', 'D', 'L', 'U'};\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + dx[dir], nj = j + dy[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (dir == 0 && v[i][j] == '1') return false;\n    if (dir == 1 && h[i][j] == '1') return false;\n    if (dir == 2 && v[i][nj] == '1') return false;\n    if (dir == 3 && h[ni][j] == '1') return false;\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    h.resize(N - 1); v.resize(N); d.resize(N, vector<int>(N));\n    for (int i = 0; i < N - 1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    vector<vector<int>> dist(N, vector<int>(N, -1)), prev_dir(N, vector<int>(N, -1));\n    queue<pair<int,int>> q; dist[0][0] = 0; q.push({0, 0});\n    while (!q.empty()) {\n        auto [i, j] = q.front(); q.pop();\n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            int ni = i + dx[dir], nj = j + dy[dir];\n            if (dist[ni][nj] == -1) { dist[ni][nj] = dist[i][j] + 1; prev_dir[ni][nj] = dir; q.push({ni, nj}); }\n        }\n    }\n    \n    string result;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        vector<pair<int, int>> neighbors;\n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            int ni = i + dx[dir], nj = j + dy[dir];\n            if (!visited[ni][nj]) neighbors.push_back({ni, nj});\n        }\n        sort(neighbors.begin(), neighbors.end(), [](auto& a, auto& b) { return d[a.first][a.second] > d[b.first][b.second]; });\n        for (auto [ni, nj] : neighbors) {\n            for (int dir = 0; dir < 4; dir++) {\n                if (i + dx[dir] == ni && j + dy[dir] == nj) {\n                    result += dir_char[dir]; dfs(ni, nj); result += dir_char[(dir + 2) % 4]; break;\n                }\n            }\n        }\n    };\n    dfs(0, 0);\n    \n    vector<int> visit_count(N * N, 0);\n    int ci = 0, cj = 0; visit_count[0]++;\n    for (char c : result) {\n        int dir = (c == 'R') ? 0 : (c == 'D') ? 1 : (c == 'L') ? 2 : 3;\n        ci += dx[dir]; cj += dy[dir]; visit_count[ci * N + cj]++;\n    }\n    \n    using Cell = tuple<double, int, int>;\n    priority_queue<Cell> pq;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (i == 0 && j == 0) continue;\n        int k = visit_count[i * N + j];\n        double cost = 2.0 * dist[i][j];\n        if (cost > 0) pq.push({(double)d[i][j] / (k * (k + 1)) / cost, i, j});\n    }\n    \n    while (!pq.empty() && result.size() < 100000) {\n        auto [p, i, j] = pq.top(); pq.pop();\n        int k = visit_count[i * N + j];\n        double cost = 2.0 * dist[i][j];\n        double new_p = (double)d[i][j] / (k * (k + 1)) / cost;\n        if (abs(new_p - p) > 1e-9) { pq.push({new_p, i, j}); continue; }\n        \n        string path_to, path_back;\n        int ci2 = i, cj2 = j;\n        while (ci2 != 0 || cj2 != 0) { int dir = prev_dir[ci2][cj2]; path_to += dir_char[dir]; ci2 -= dx[dir]; cj2 -= dy[dir]; }\n        reverse(path_to.begin(), path_to.end());\n        for (int k2 = path_to.size() - 1; k2 >= 0; k2--) {\n            char c = path_to[k2];\n            path_back += (c == 'R') ? 'L' : (c == 'D') ? 'U' : (c == 'L') ? 'R' : 'D';\n        }\n        string detour = path_to + path_back;\n        if (result.size() + detour.size() <= 100000) {\n            result += detour; visit_count[i * N + j]++;\n            int nk = visit_count[i * N + j];\n            pq.push({(double)d[i][j] / (nk * (nk + 1)) / cost, i, j});\n        }\n    }\n    \n    cout << result << endl;\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    int N,M; cin>>N>>M;\n    int si,sj; cin>>si>>sj;\n    vector<string> A(N);\n    for(int i=0;i<N;i++) cin>>A[i];\n    vector<string> t(M);\n    for(int i=0;i<M;i++) cin>>t[i];\n    \n    vector<vector<pair<int,int>>> cp(26);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cp[A[i][j]-'A'].push_back({i,j});\n    \n    vector<vector<int>> cd(26,vector<int>(26,0));\n    for(int c1=0;c1<26;c1++) for(int c2=0;c2<26;c2++){\n        int md=INT_MAX;\n        for(auto&[i1,j1]:cp[c1]) for(auto&[i2,j2]:cp[c2]) md=min(md,abs(i1-i2)+abs(j1-j2));\n        cd[c1][c2]=md;\n    }\n    \n    vector<vector<int>> ov(M,vector<int>(M,0));\n    for(int i=0;i<M;i++) for(int j=0;j<M;j++){ if(i==j) continue;\n        for(int l=4;l>=1;l--){ bool ok=true;\n            for(int k=0;k<l;k++) if(t[i][5-l+k]!=t[j][k]){ok=false;break;}\n            if(ok){ov[i][j]=l;break;}}\n    }\n    \n    auto buildS=[&](const vector<int>& o){ string s=t[o[0]];\n        for(int i=1;i<M;i++) s+=t[o[i]].substr(ov[o[i-1]][o[i]]); return s;};\n    \n    mt19937 rng(42);\n    auto greedyR=[&](int st)->vector<int>{ vector<int> o; o.push_back(st);\n        vector<bool> u(M,false); u[st]=true;\n        for(int s=1;s<M;s++){ int l=o.back(),bo=-1; vector<int> c;\n            for(int j=0;j<M;j++){ if(u[j]) continue;\n                if(ov[l][j]>bo){bo=ov[l][j];c.clear();c.push_back(j);}\n                else if(ov[l][j]==bo) c.push_back(j);}\n            o.push_back(c[rng()%c.size()]); u[o.back()]=true;} return o;};\n    \n    auto greedyK=[&](int st)->vector<int>{ vector<int> o; o.push_back(st);\n        vector<bool> u(M,false); u[st]=true;\n        for(int s=1;s<M;s++){ int l=o.back(),bo=-1,bd=INT_MAX,ch=-1;\n            for(int j=0;j<M;j++){ if(u[j]) continue; int v=ov[l][j];\n                int d=cd[t[l][4]-'A'][t[j][v]-'A'];\n                if(v>bo||(v==bo&&d<bd)){bo=v;bd=d;ch=j;}}\n            o.push_back(ch); u[ch]=true;} return o;};\n    \n    auto twoOpt=[&](vector<int> o)->vector<int>{ bool imp=true;\n        while(imp){ imp=false; for(int i=0;i<M-1;i++){\n            int os=0,ns=0;\n            if(i>0){os+=ov[o[i-1]][o[i]];ns+=ov[o[i-1]][o[i+1]];}\n            os+=ov[o[i]][o[i+1]];ns+=ov[o[i+1]][o[i]];\n            if(i+2<M){os+=ov[o[i+1]][o[i+2]];ns+=ov[o[i]][o[i+2]];}\n            if(ns>os){swap(o[i],o[i+1]);imp=true;}}} return o;};\n    \n    auto orOpt=[&](vector<int> o)->vector<int>{\n        for(int it=0;it<5;it++){ bool imp=false;\n            for(int i=0;i<M;i++){ int w=o[i],rd=0;\n                if(i>0) rd-=ov[o[i-1]][w]; if(i<M-1) rd-=ov[w][o[i+1]];\n                if(i>0&&i<M-1) rd+=ov[o[i-1]][o[i+1]];\n                vector<int> rm; for(int k=0;k<M;k++) if(k!=i) rm.push_back(o[k]);\n                int bd=0,bk=i;\n                for(int k=0;k<M;k++){ int id=0;\n                    if(k>0) id+=ov[rm[k-1]][w]; if(k<M-1) id+=ov[w][rm[k]];\n                    if(k>0&&k<M-1) id-=ov[rm[k-1]][rm[k]];\n                    if(rd+id>bd){bd=rd+id;bk=k;}}\n                if(bk!=i){ o.clear();\n                    for(int k=0;k<bk;k++) o.push_back(rm[k]); o.push_back(w);\n                    for(int k=bk;k<M-1;k++) o.push_back(rm[k]); imp=true;break;}}\n            if(!imp) break;} return o;};\n    \n    const int INF=1e9;\n    auto eval=[&](const string& s)->int{ int L=s.size();\n        vector<int> cur(225,INF); cur[si*15+sj]=0;\n        for(int i=0;i<L;i++){ vector<int> nx(225,INF); int ci=s[i]-'A';\n            for(int q=0;q<225;q++){ if(cur[q]>=INF) continue;\n                int qi=q/15,qj=q%15;\n                for(auto&[pi,pj]:cp[ci]){ int p=pi*15+pj;\n                    int nc=cur[q]+abs(pi-qi)+abs(pj-qj)+1;\n                    if(nc<nx[p]) nx[p]=nc;}}\n            cur=move(nx);}\n        return *min_element(cur.begin(),cur.end());};\n    \n    vector<pair<int,vector<int>>> cs;\n    for(int s=0;s<M;s++){ rng.seed(s*997+1); auto o=greedyR(s); o=twoOpt(o);\n        int tv=0; for(int i=1;i<M;i++) tv+=ov[o[i-1]][o[i]]; cs.push_back({5*M-tv,o});}\n    for(int s=0;s<M;s++){ auto o=greedyK(s); o=twoOpt(o);\n        int tv=0; for(int i=1;i<M;i++) tv+=ov[o[i-1]][o[i]]; cs.push_back({5*M-tv,o});}\n    for(int tr=0;tr<100;tr++){ rng.seed(tr*137+42); auto o=greedyR(rng()%M); o=twoOpt(o);\n        int tv=0; for(int i=1;i<M;i++) tv+=ov[o[i-1]][o[i]]; cs.push_back({5*M-tv,o});}\n    \n    sort(cs.begin(),cs.end());\n    string bs; int bc=INF;\n    int ec=min((int)cs.size(),30);\n    for(int i=0;i<ec;i++){ auto o=cs[i].second;\n        if(i<10){o=orOpt(o);o=twoOpt(o);}\n        string ss=buildS(o); int c=eval(ss);\n        if(c<bc){bc=c;bs=ss;}}\n    \n    int L=bs.size();\n    vector<vector<pair<int,int>>> dp(L+1,vector<pair<int,int>>(225,{INF,-1}));\n    dp[0][si*15+sj]={0,-1};\n    for(int i=0;i<L;i++){ int ci=bs[i]-'A';\n        for(int q=0;q<225;q++){ if(dp[i][q].first>=INF) continue;\n            int qi=q/15,qj=q%15;\n            for(auto&[pi,pj]:cp[ci]){ int p=pi*15+pj;\n                int nc=dp[i][q].first+abs(pi-qi)+abs(pj-qj)+1;\n                if(nc<dp[i+1][p].first) dp[i+1][p]={nc,q};}}}\n    \n    int be=0; bc=INF;\n    for(int p=0;p<225;p++) if(dp[L][p].first<bc){bc=dp[L][p].first;be=p;}\n    vector<int> pp(L); int cr=be;\n    for(int i=L-1;i>=0;i--){pp[i]=cr;cr=dp[i+1][cr].second;}\n    for(int i=0;i<L;i++) cout<<pp[i]/15<<\" \"<<pp[i]%15<<\"\\n\";\n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<vector<pair<int,int>>> shapes;\nvector<int> max_di, max_dj;\nvector<vector<pair<int,int>>> positions;\nvector<vector<vector<pair<int,int>>>> pos_cells;\nint known[25][25];\nint query_count = 0;\nvector<vector<double>> w;\ndouble cov[25][25];\n\nint drill_cell(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int v; cin >> v;\n    known[i][j] = v;\n    query_count++;\n    return v;\n}\n\nint divine_cells(vector<pair<int,int>>& cells) {\n    int k = cells.size();\n    cout << \"q \" << k;\n    for (auto& [i, j] : cells) cout << \" \" << i << \" \" << j;\n    cout << endl;\n    cout.flush();\n    int v; cin >> v;\n    query_count++;\n    return v;\n}\n\nvoid submit_answer(vector<pair<int,int>>& cells) {\n    sort(cells.begin(), cells.end());\n    cells.erase(unique(cells.begin(), cells.end()), cells.end());\n    cout << \"a \" << cells.size();\n    for (auto& [i, j] : cells) cout << \" \" << i << \" \" << j;\n    cout << endl;\n    cout.flush();\n    int r; cin >> r;\n    if (r == 1) exit(0);\n}\n\nvoid update_coverage() {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cov[i][j] = 0;\n    for (int k = 0; k < M; k++) {\n        double total = accumulate(w[k].begin(), w[k].end(), 0.0);\n        if (total < 1e-10) continue;\n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            double wt = w[k][p] / total;\n            for (auto& [ci, cj] : pos_cells[k][p]) cov[ci][cj] += wt;\n        }\n    }\n}\n\nvoid update_divine(const vector<pair<int,int>>& qcells, int obs) {\n    int ksz = qcells.size();\n    set<pair<int,int>> cs(qcells.begin(), qcells.end());\n    for (int k = 0; k < M; k++) {\n        double others = 0;\n        for (int k2 = 0; k2 < M; k2++) if (k2 != k) {\n            double t2 = accumulate(w[k2].begin(), w[k2].end(), 0.0);\n            if (t2 < 1e-10) continue;\n            for (int p2 = 0; p2 < (int)positions[k2].size(); p2++) {\n                int cnt = 0;\n                for (auto& [ci, cj] : pos_cells[k2][p2]) if (cs.count({ci, cj})) cnt++;\n                others += w[k2][p2] / t2 * cnt;\n            }\n        }\n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            int cnt = 0;\n            for (auto& [ci, cj] : pos_cells[k][p]) if (cs.count({ci, cj})) cnt++;\n            double ev = others + cnt;\n            double mean = ksz * eps + ev * (1 - 2 * eps);\n            double var = ksz * eps * (1 - eps);\n            double diff = obs - mean;\n            w[k][p] *= exp(-diff * diff / (2 * var));\n        }\n        double total = accumulate(w[k].begin(), w[k].end(), 0.0);\n        if (total > 1e-10) for (auto& wp : w[k]) wp /= total;\n    }\n    update_coverage();\n}\n\nvoid update_drill(int i, int j, int obs) {\n    for (int k = 0; k < M; k++) {\n        double others = 0;\n        for (int k2 = 0; k2 < M; k2++) if (k2 != k) {\n            double t2 = accumulate(w[k2].begin(), w[k2].end(), 0.0);\n            if (t2 < 1e-10) continue;\n            for (int p2 = 0; p2 < (int)positions[k2].size(); p2++)\n                for (auto& [ci, cj] : pos_cells[k2][p2])\n                    if (ci == i && cj == j) { others += w[k2][p2] / t2; break; }\n        }\n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            bool covers = false;\n            for (auto& [ci, cj] : pos_cells[k][p]) if (ci == i && cj == j) { covers = true; break; }\n            double ev = others + (covers ? 1.0 : 0.0);\n            double diff = obs - ev;\n            double var = max(0.3, ev * 0.5);\n            w[k][p] *= exp(-diff * diff / (2 * var));\n        }\n        double total = accumulate(w[k].begin(), w[k].end(), 0.0);\n        if (total > 1e-10) for (auto& wp : w[k]) wp /= total;\n    }\n    update_coverage();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M >> eps;\n    shapes.resize(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int l = 0; l < d; l++) cin >> shapes[k][l].first >> shapes[k][l].second;\n    }\n    max_di.resize(M); max_dj.resize(M);\n    for (int k = 0; k < M; k++) {\n        max_di[k] = max_dj[k] = 0;\n        for (auto& [i, j] : shapes[k]) { max_di[k] = max(max_di[k], i); max_dj[k] = max(max_dj[k], j); }\n    }\n    for (int k = 0; k < M; k++) {\n        vector<pair<int,int>> pos;\n        vector<vector<pair<int,int>>> cells;\n        for (int di = 0; di <= N - 1 - max_di[k]; di++)\n            for (int dj = 0; dj <= N - 1 - max_dj[k]; dj++) {\n                pos.push_back({di, dj});\n                vector<pair<int,int>> c;\n                for (auto& [i, j] : shapes[k]) c.push_back({di + i, dj + j});\n                cells.push_back(c);\n            }\n        positions.push_back(pos);\n        pos_cells.push_back(cells);\n    }\n    memset(known, -1, sizeof(known));\n    for (int k = 0; k < M; k++) w.push_back(vector<double>(positions[k].size(), 1.0));\n    update_coverage();\n    \n    for (int i = 0; i < N && query_count < 2*N*N; i++) {\n        vector<pair<int,int>> cells;\n        for (int j = 0; j < N; j++) cells.push_back({i, j});\n        update_divine(cells, divine_cells(cells));\n    }\n    for (int j = 0; j < N && query_count < 2*N*N; j++) {\n        vector<pair<int,int>> cells;\n        for (int i = 0; i < N; i++) cells.push_back({i, j});\n        update_divine(cells, divine_cells(cells));\n    }\n    \n    while (query_count < 2*N*N - 1) {\n        int bi = -1, bj = -1; double bs = -1e9;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (known[i][j] >= 0) continue;\n            double p = 1.0 - exp(-cov[i][j]); p = max(0.01, min(0.99, p));\n            double ent = -p*log(p) - (1-p)*log(1-p);\n            if (ent > bs) { bs = ent; bi = i; bj = j; }\n        }\n        if (bi < 0) break;\n        update_drill(bi, bj, drill_cell(bi, bj));\n    }\n    \n    vector<pair<int,int>> ans;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (known[i][j] > 0) ans.push_back({i, j});\n        else if (known[i][j] < 0 && 1.0 - exp(-cov[i][j]) > 0.5) ans.push_back({i, j});\n    }\n    submit_answer(ans);\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <climits>\nusing namespace std;\n\nint W, D, N;\nvector<vector<int>> a;\n\nvector<int> get_bounds(const vector<int>& h) {\n    vector<int> b; int y=0;\n    for(int k=0;k<N-1;k++){y+=h[k];b.push_back(y);}\n    return b;\n}\n\nlong long bound_changes(const vector<int>& b1, const vector<int>& b2) {\n    int i=0,j=0; long long c=0;\n    while(i<(int)b1.size()&&j<(int)b2.size()){\n        if(b1[i]==b2[j]){i++;j++;}\n        else if(b1[i]<b2[j]){c++;i++;}\n        else{c++;j++;}\n    }\n    c+=(int)b1.size()-i+(int)b2.size()-j;\n    return c;\n}\n\nlong long day_deficit(int d, const vector<int>& h) {\n    long long c=0;\n    for(int k=0;k<N;k++){int area=h[k]*W;if(a[d][k]>area)c+=100LL*(a[d][k]-area);}\n    return c;\n}\n\nvector<int> greedy_day(int d) {\n    vector<int> h(N,1); int rem=W-N;\n    while(rem>0){\n        int bk=-1; long long br=-1;\n        for(int k=0;k<N;k++){\n            int df=max(0,a[d][k]-h[k]*W);\n            int nd=max(0,a[d][k]-(h[k]+1)*W);\n            long long r=df-nd;\n            if(r>br||(r==br&&a[d][k]>(bk>=0?a[d][bk]:0))){br=r;bk=k;}\n        }\n        if(bk==-1)break;\n        h[bk]++;rem--;\n    }\n    return h;\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);cin.tie(nullptr);\n    cin>>W>>D>>N;\n    a.resize(D,vector<int>(N));\n    for(int d=0;d<D;d++)for(int k=0;k<N;k++)cin>>a[d][k];\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> uni(0,1);\n    \n    // Greedy fixed layout\n    vector<int> fixed_h(N,1);\n    {int rem=W-N;\n    while(rem>0){\n        int bk=-1;long long bs=-1;\n        for(int k=0;k<N;k++){\n            long long td=0,ntd=0;\n            for(int d=0;d<D;d++){td+=max(0,a[d][k]-fixed_h[k]*W);ntd+=max(0,a[d][k]-(fixed_h[k]+1)*W);}\n            long long s=td-ntd;\n            if(s>bs||(s==bs&&a[0][k]>(bk>=0?a[0][bk]:0))){bs=s;bk=k;}\n        }\n        if(bk==-1)break;fixed_h[bk]++;rem--;\n    }}\n    \n    // SA for fixed layout\n    {vector<int> ch=fixed_h;\n    long long cc=0;for(int d=0;d<D;d++)cc+=day_deficit(d,ch);\n    long long bc=cc;vector<int> bh=ch;\n    auto st=chrono::high_resolution_clock::now();\n    while(true){\n        auto nw=chrono::high_resolution_clock::now();\n        double el=chrono::duration<double>(nw-st).count();\n        if(el>1.0)break;\n        int k1=rng()%N,k2=rng()%N;\n        if(k1==k2||ch[k1]<=1)continue;\n        long long delta=0;\n        for(int d=0;d<D;d++){\n            delta+=100LL*(max(0,a[d][k1]-(ch[k1]-1)*W)-max(0,a[d][k1]-ch[k1]*W));\n            delta+=100LL*(max(0,a[d][k2]-(ch[k2]+1)*W)-max(0,a[d][k2]-ch[k2]*W));\n        }\n        double temp=5e6*max(1e-4,1.0-el/1.0);\n        if(delta<=0||exp(-(double)delta/temp)>uni(rng)){\n            ch[k1]--;ch[k2]++;cc+=delta;\n            if(cc<bc){bc=cc;bh=ch;}\n        }\n    }\n    fixed_h=bh;}\n    \n    // Per-day greedy\n    vector<vector<int>> heights(D);\n    for(int d=0;d<D;d++)heights[d]=greedy_day(d);\n    \n    // SA on full sequence starting from fixed\n    vector<vector<int>> cur_h(D,fixed_h);\n    auto total_cost=[&](const vector<vector<int>>& h)->long long{\n        long long c=0;\n        for(int d=0;d<D;d++)c+=day_deficit(d,h[d]);\n        for(int d=1;d<D;d++)c+=bound_changes(get_bounds(h[d-1]),get_bounds(h[d]))*W;\n        return c;\n    };\n    \n    long long cur_cost=total_cost(cur_h);\n    long long best_cost=cur_cost;\n    vector<vector<int>> best_h=cur_h;\n    \n    // Also check per-day greedy cost\n    {long long pc=total_cost(heights);\n    if(pc<best_cost){best_cost=pc;best_h=heights;cur_h=heights;cur_cost=pc;}}\n    \n    auto st=chrono::high_resolution_clock::now();\n    while(true){\n        auto nw=chrono::high_resolution_clock::now();\n        double el=chrono::duration<double>(nw-st).count();\n        if(el>1.8)break;\n        \n        int d=rng()%D;\n        int k1=rng()%N,k2=rng()%N;\n        if(k1==k2||cur_h[d][k1]<=1)continue;\n        \n        long long dd=0;\n        dd+=100LL*(max(0,a[d][k1]-(cur_h[d][k1]-1)*W)-max(0,a[d][k1]-cur_h[d][k1]*W));\n        dd+=100LL*(max(0,a[d][k2]-(cur_h[d][k2]+1)*W)-max(0,a[d][k2]-cur_h[d][k2]*W));\n        \n        vector<int> ob=get_bounds(cur_h[d]);\n        cur_h[d][k1]--;cur_h[d][k2]++;\n        vector<int> nb=get_bounds(cur_h[d]);\n        \n        long long pd=0;\n        if(d>0){vector<int> pb=get_bounds(cur_h[d-1]);pd+=(bound_changes(pb,nb)-bound_changes(pb,ob))*W;}\n        if(d<D-1){vector<int> nb2=get_bounds(cur_h[d+1]);pd+=(bound_changes(nb,nb2)-bound_changes(ob,nb2))*W;}\n        \n        long long delta=dd+pd;\n        double temp=5e6*max(1e-4,1.0-el/1.8);\n        if(delta<=0||exp(-(double)delta/temp)>uni(rng)){\n            cur_cost+=delta;\n            if(cur_cost<best_cost){best_cost=cur_cost;best_h=cur_h;}\n        }else{cur_h[d][k1]++;cur_h[d][k2]--;}\n    }\n    \n    for(int d=0;d<D;d++){\n        int y=0;\n        for(int k=0;k<N;k++){\n            cout<<y<<\" 0 \"<<y+best_h[d][k]<<\" \"<<W<<\"\\n\";\n            y+=best_h[d][k];\n        }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\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    vector<vector<long long>> a(N, vector<long long>(N));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            cin >> a[i][j];\n    \n    vector<vector<vector<long long>>> s(M, vector<vector<long long>>(3, vector<long long>(3)));\n    for (int m = 0; m < M; m++)\n        for (int i = 0; i < 3; i++)\n            for (int j = 0; j < 3; j++)\n                cin >> s[m][i][j];\n    \n    vector<vector<long long>> bmod = a;\n    vector<tuple<int, int, int>> ops;\n    \n    for (int k = 0; k < K; k++) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        long long best_delta = 0;\n        for (int m = 0; m < M; m++)\n            for (int p = 0; p <= N - 3; p++)\n                for (int q = 0; q <= N - 3; q++) {\n                    long long delta = 0;\n                    for (int i = 0; i < 3; i++)\n                        for (int j = 0; j < 3; j++) {\n                            long long nm = (bmod[p+i][q+j] + s[m][i][j]) % MOD;\n                            delta += nm - bmod[p+i][q+j];\n                        }\n                    if (delta > best_delta) { best_delta = delta; best_m = m; best_p = p; best_q = q; }\n                }\n        if (best_m == -1) break;\n        ops.push_back({best_m, best_p, best_q});\n        for (int i = 0; i < 3; i++)\n            for (int j = 0; j < 3; j++)\n                bmod[best_p+i][best_q+j] = (bmod[best_p+i][best_q+j] + s[best_m][i][j]) % MOD;\n    }\n    \n    long long score = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            score += bmod[i][j];\n    \n    long long best_score = score;\n    auto best_ops = ops;\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> uni(0.0, 1.0);\n    double start_temp = 2e9, end_temp = 1e5;\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 1.8) break;\n        double temp = start_temp * pow(end_temp / start_temp, elapsed / 1.8);\n        \n        int r = rng() % 100;\n        long long delta = 0;\n        int idx, new_m, new_p, new_q, old_m, old_p, old_q;\n        int move_type = 0;\n        \n        if (r < 8 && (int)ops.size() < K) {\n            move_type = 1;\n            new_m = rng() % M; new_p = rng() % (N-2); new_q = rng() % (N-2);\n            for (int i = 0; i < 3; i++)\n                for (int j = 0; j < 3; j++) {\n                    int ci = new_p+i, cj = new_q+j;\n                    long long nv = (bmod[ci][cj] + s[new_m][i][j]) % MOD;\n                    delta += nv - bmod[ci][cj];\n                }\n        } else if (r < 12 && (int)ops.size() > 0) {\n            move_type = 2;\n            idx = rng() % ops.size();\n            tie(old_m, old_p, old_q) = ops[idx];\n            for (int i = 0; i < 3; i++)\n                for (int j = 0; j < 3; j++) {\n                    int ci = old_p+i, cj = old_q+j;\n                    long long nv = (bmod[ci][cj] - s[old_m][i][j] + MOD) % MOD;\n                    delta += nv - bmod[ci][cj];\n                }\n        } else if ((int)ops.size() > 0) {\n            move_type = 3;\n            idx = rng() % ops.size();\n            tie(old_m, old_p, old_q) = ops[idx];\n            new_m = old_m; new_p = old_p; new_q = old_q;\n            int ch = rng() % 4;\n            if (ch == 0) new_m = rng() % M;\n            else if (ch == 1) new_p = rng() % (N-2);\n            else if (ch == 2) new_q = rng() % (N-2);\n            else { new_m = rng() % M; new_p = rng() % (N-2); new_q = rng() % (N-2); }\n            if (new_m == old_m && new_p == old_p && new_q == old_q) continue;\n            \n            long long saved[3][3];\n            for (int i = 0; i < 3; i++)\n                for (int j = 0; j < 3; j++) {\n                    int ci = old_p+i, cj = old_q+j;\n                    saved[i][j] = bmod[ci][cj];\n                    long long nv = (bmod[ci][cj] - s[old_m][i][j] + MOD) % MOD;\n                    delta += nv - bmod[ci][cj];\n                    bmod[ci][cj] = nv;\n                }\n            for (int i = 0; i < 3; i++)\n                for (int j = 0; j < 3; j++) {\n                    int ci = new_p+i, cj = new_q+j;\n                    long long nv = (bmod[ci][cj] + s[new_m][i][j]) % MOD;\n                    delta += nv - bmod[ci][cj];\n                }\n            for (int i = 0; i < 3; i++)\n                for (int j = 0; j < 3; j++)\n                    bmod[old_p+i][old_q+j] = saved[i][j];\n        } else continue;\n        \n        if (delta >= 0 || (delta / temp > -20 && uni(rng) < exp(delta / temp))) {\n            if (move_type == 1) {\n                for (int i = 0; i < 3; i++)\n                    for (int j = 0; j < 3; j++)\n                        bmod[new_p+i][new_q+j] = (bmod[new_p+i][new_q+j] + s[new_m][i][j]) % MOD;\n                ops.push_back({new_m, new_p, new_q});\n            } else if (move_type == 2) {\n                for (int i = 0; i < 3; i++)\n                    for (int j = 0; j < 3; j++)\n                        bmod[old_p+i][old_q+j] = (bmod[old_p+i][old_q+j] - s[old_m][i][j] + MOD) % MOD;\n                ops[idx] = ops.back(); ops.pop_back();\n            } else {\n                for (int i = 0; i < 3; i++)\n                    for (int j = 0; j < 3; j++)\n                        bmod[old_p+i][old_q+j] = (bmod[old_p+i][old_q+j] - s[old_m][i][j] + MOD) % MOD;\n                for (int i = 0; i < 3; i++)\n                    for (int j = 0; j < 3; j++)\n                        bmod[new_p+i][new_q+j] = (bmod[new_p+i][new_q+j] + s[new_m][i][j]) % MOD;\n                ops[idx] = {new_m, new_p, new_q};\n            }\n            score += delta;\n            if (score > best_score) { best_score = score; best_ops = ops; }\n        }\n    }\n    \n    cout << best_ops.size() << \"\\n\";\n    for (auto& [m, p, q] : best_ops)\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <climits>\n#include <cstdlib>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N];\nint container_recv_row[N*N], container_recv_idx[N*N];\nbool container_dispatched[N*N];\n\nint next_expected(int gate) {\n    for (int j = 0; j < N; j++)\n        if (!container_dispatched[N * gate + j]) return N * gate + j;\n    return -1;\n}\n\nint main() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n            container_recv_row[A[i][j]] = i;\n            container_recv_idx[A[i][j]] = j;\n        }\n    fill(container_dispatched, container_dispatched + N*N, false);\n    \n    int grid[N][N]; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) grid[i][j] = -1;\n    int crane_r = 0, crane_c = 0, crane_holding = -1;\n    int next_receive[N] = {}, total_dispatched = 0;\n    vector<string> actions(N, \"\");\n    \n    for (int turn = 1; total_dispatched < N*N && turn < 10000; turn++) {\n        for (int i = 0; i < N; i++)\n            if (next_receive[i] < N && grid[i][0] == -1 && !(crane_r == i && crane_c == 0 && crane_holding != -1)) {\n                grid[i][0] = A[i][next_receive[i]++];\n            }\n        \n        char act = '.';\n        if (crane_holding != -1) {\n            int dr = crane_holding / N, exp = next_expected(dr);\n            int tr, tc;\n            if (exp != -1 && crane_holding == exp) { tr = dr; tc = N-1; }\n            else {\n                tr = tc = -1; int bd = INT_MAX;\n                for (int c = 1; c < N-1; c++) for (int r = 0; r < N; r++)\n                    if (grid[r][c] == -1) { int d = abs(crane_r-r)+abs(crane_c-c); if (d < bd) { bd=d; tr=r; tc=c; } }\n                if (tr == -1) { tr = dr; tc = N-1; }\n            }\n            if (crane_r == tr && crane_c == tc) { act = 'Q'; grid[tr][tc] = crane_holding; crane_holding = -1; }\n            else { if (crane_r < tr) { crane_r++; act='D'; } else if (crane_r > tr) { crane_r--; act='U'; } else if (crane_c < tc) { crane_c++; act='R'; } else { crane_c--; act='L'; } }\n        } else {\n            int bc = -1, bs = INT_MAX, br = -1, bcc = -1;\n            for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) {\n                if (grid[r][c] == -1 || container_dispatched[grid[r][c]]) continue;\n                int cont = grid[r][c], dr = cont / N, exp = next_expected(dr);\n                int dp = abs(crane_r-r)+abs(crane_c-c), sc;\n                if (exp != -1 && cont == exp) sc = dp + abs(r-dr)+abs(c-(N-1));\n                else {\n                    int mt = INT_MAX;\n                    for (int tc=1; tc<N-1; tc++) for (int tr=0; tr<N; tr++) if (grid[tr][tc]==-1) mt=min(mt,abs(r-tr)+abs(c-tc));\n                    sc = (mt == INT_MAX) ? INT_MAX : dp + mt + 500;\n                    if (c == 0 && next_receive[r] < N) sc -= 200;\n                }\n                if (sc < bs) { bs=sc; bc=cont; br=r; bcc=c; }\n            }\n            if (bc != -1 && bs < INT_MAX) {\n                if (crane_r == br && crane_c == bcc) { act='P'; crane_holding=bc; grid[br][bcc]=-1; }\n                else { if (crane_r<br) { crane_r++; act='D'; } else if (crane_r>br) { crane_r--; act='U'; } else if (crane_c<bcc) { crane_c++; act='R'; } else { crane_c--; act='L'; } }\n            }\n        }\n        actions[0] += act;\n        for (int i = 1; i < N; i++) actions[i] += (turn == 1 ? 'B' : '.');\n        \n        for (int i = 0; i < N; i++)\n            if (grid[i][N-1] != -1) { container_dispatched[grid[i][N-1]] = true; grid[i][N-1] = -1; total_dispatched++; }\n    }\n    \n    int ml = 0; for (int i = 0; i < N; i++) ml = max(ml, (int)actions[i].size());\n    for (int i = 0; i < N; i++) { while ((int)actions[i].size() < ml) actions[i] += '.'; cout << actions[i] << endl; }\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <climits>\n#include <algorithm>\nusing namespace std;\ntypedef long long ll;\nconst ll INF = 1e18;\nstruct Edge { int to, rev; ll cap, cost; };\nstruct MinCostFlow {\n    int n; vector<vector<Edge>> graph; vector<ll> h; vector<int> pv, pe;\n    MinCostFlow(int n):n(n),graph(n),h(n,0),pv(n),pe(n){}\n    void add_edge(int f,int t,ll cap,ll cost){\n        graph[f].push_back({t,(int)graph[t].size(),cap,cost});\n        graph[t].push_back({f,(int)graph[f].size()-1,0,-cost});\n    }\n    ll min_cost_flow(int s,int t,ll mf){\n        ll res=0,flow=0;\n        while(flow<mf){\n            priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<>>pq;\n            vector<ll>dist(n,INF);dist[s]=0;pq.push({0,s});\n            while(!pq.empty()){\n                auto[d,v]=pq.top();pq.pop();\n                if(dist[v]<d)continue;\n                for(int i=0;i<(int)graph[v].size();i++){\n                    Edge&e=graph[v][i];\n                    if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){\n                        dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];\n                        pv[e.to]=v;pe[e.to]=i;pq.push({dist[e.to],e.to});\n                    }\n                }\n            }\n            if(dist[t]==INF)break;\n            for(int v=0;v<n;v++)h[v]+=dist[v];\n            ll d=mf-flow;\n            for(int v=t;v!=s;v=pv[v])d=min(d,graph[pv[v]][pe[v]].cap);\n            flow+=d;res+=d*h[t];\n            for(int v=t;v!=s;v=pv[v]){\n                Edge&e=graph[pv[v]][pe[v]];e.cap-=d;graph[v][e.rev].cap+=d;\n            }\n        }\n        return res;\n    }\n};\nint main(){\n    ios_base::sync_with_stdio(false);cin.tie(NULL);\n    int n;cin>>n;\n    vector<vector<int>>h(n,vector<int>(n));\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)cin>>h[i][j];\n    vector<pair<int,int>>sources,sinks;\n    vector<vector<int>>sid(n,vector<int>(n,-1)),kid(n,vector<int>(n,-1));\n    int tsup=0;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        if(h[i][j]>0){sid[i][j]=sources.size();sources.push_back({i,j});tsup+=h[i][j];}\n        else if(h[i][j]<0){kid[i][j]=sinks.size();sinks.push_back({i,j});}\n    }\n    int P=sources.size(),M=sinks.size();\n    int S=0,T=P+M+1;\n    MinCostFlow mcf(P+M+2);\n    for(int i=0;i<P;i++){auto[si,sj]=sources[i];mcf.add_edge(S,1+i,h[si][sj],0);}\n    for(int j=0;j<M;j++){auto[ti,tj]=sinks[j];mcf.add_edge(1+P+j,T,-h[ti][tj],0);}\n    for(int i=0;i<P;i++){auto[si,sj]=sources[i];\n        for(int j=0;j<M;j++){auto[ti,tj]=sinks[j];\n            ll d=abs(si-ti)+abs(sj-tj);\n            mcf.add_edge(1+i,1+P+j,min((ll)h[si][sj],(ll)-h[ti][tj]),d);\n        }\n    }\n    mcf.min_cost_flow(S,T,tsup);\n    vector<vector<int>>fa(P,vector<int>(M,0));\n    for(int i=0;i<P;i++)for(auto&e:mcf.graph[1+i])\n        if(e.to>=1+P&&e.to<1+P+M)fa[i][e.to-1-P]=(int)mcf.graph[e.to][e.rev].cap;\n    vector<int>snnd(P,0);\n    for(int i=0;i<P;i++){auto[si,sj]=sources[i];int best=INT_MAX;\n        for(int j=0;j<M;j++)if(fa[i][j]>0){auto[ti,tj]=sinks[j];best=min(best,abs(si-ti)+abs(sj-tj));}\n        snnd[i]=(best<INT_MAX)?best:0;\n    }\n    vector<string>ops;int r=0,c=0,load=0,rem=tsup;\n    auto cur=h;\n    while(ops.size()<100000&&(rem>0||load>0)){\n        if(cur[r][c]>0){ops.push_back(\"+\"+to_string(cur[r][c]));load+=cur[r][c];rem-=cur[r][c];cur[r][c]=0;}\n        while(cur[r][c]<0&&load>0){int d=min(load,-cur[r][c]);ops.push_back(\"-\"+to_string(d));load-=d;cur[r][c]+=d;}\n        if(rem==0&&load==0)break;\n        int br=-1,bc=-1;ll bcost=LLONG_MAX;\n        if(load>0){\n            for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(cur[i][j]<0){\n                int d=abs(r-i)+abs(c-j);ll cost=(ll)d*(100+load);\n                if(cost<bcost){bcost=cost;br=i;bc=j;}\n            }\n        }else{\n            for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(cur[i][j]>0){\n                int dt=abs(r-i)+abs(c-j);int s=sid[i][j];\n                int dd=(s>=0)?snnd[s]:20;\n                ll cost=(ll)dt*100+(ll)dd*(100+cur[i][j]);\n                if(cost<bcost){bcost=cost;br=i;bc=j;}\n            }\n        }\n        if(br==-1)break;\n        if(br<r){r--;ops.push_back(\"U\");}\n        else if(br>r){r++;ops.push_back(\"D\");}\n        else if(bc<c){c--;ops.push_back(\"L\");}\n        else{c++;ops.push_back(\"R\");}\n    }\n    for(auto&op:ops)cout<<op<<\"\\n\";\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 6, M = 15;\n    const int SEED_COUNT = 2 * N * (N - 1);\n    const int GRID_SIZE = N * N;\n    \n    int n, m, t;\n    cin >> n >> m >> t;\n    \n    vector<vector<int>> X(SEED_COUNT, vector<int>(M));\n    for (int i = 0; i < SEED_COUNT; i++)\n        for (int j = 0; j < M; j++)\n            cin >> X[i][j];\n    \n    vector<pair<int,int>> edges;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N-1; j++)\n            edges.push_back({i*N+j, i*N+j+1});\n    for (int i = 0; i < N-1; i++)\n        for (int j = 0; j < N; j++)\n            edges.push_back({i*N+j, (i+1)*N+j});\n    \n    vector<vector<int>> posEdges(GRID_SIZE);\n    for (int e = 0; e < (int)edges.size(); e++) {\n        posEdges[edges[e].first].push_back(e);\n        posEdges[edges[e].second].push_back(e);\n    }\n    \n    vector<int> posOrder(GRID_SIZE);\n    iota(posOrder.begin(), posOrder.end(), 0);\n    sort(posOrder.begin(), posOrder.end(), [](int a, int b) {\n        int da = (2*(a/6) - 5) * (2*(a/6) - 5) + (2*(a%6) - 5) * (2*(a%6) - 5);\n        int db = (2*(b/6) - 5) * (2*(b/6) - 5) + (2*(b%6) - 5) * (2*(b%6) - 5);\n        return da != db ? da < db : a < b;\n    });\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> unif(0.0, 1.0);\n    \n    for (int turn = 0; turn < t; turn++) {\n        vector<vector<int>> pot(SEED_COUNT, vector<int>(SEED_COUNT, 0));\n        for (int i = 0; i < SEED_COUNT; i++)\n            for (int j = i+1; j < SEED_COUNT; j++) {\n                for (int l = 0; l < M; l++)\n                    pot[i][j] += max(X[i][l], X[j][l]);\n                pot[j][i] = pot[i][j];\n            }\n        \n        vector<int> values(SEED_COUNT);\n        for (int i = 0; i < SEED_COUNT; i++)\n            for (int j = 0; j < M; j++)\n                values[i] += X[i][j];\n        \n        vector<int> order(SEED_COUNT);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), [&](int a, int b) { return values[a] > values[b]; });\n        \n        vector<int> grid(GRID_SIZE);\n        for (int i = 0; i < GRID_SIZE; i++)\n            grid[posOrder[i]] = order[i];\n        \n        vector<int> unplaced(order.begin() + GRID_SIZE, order.end());\n        vector<bool> isPlaced(SEED_COUNT, false);\n        for (int i = 0; i < GRID_SIZE; i++) isPlaced[order[i]] = true;\n        \n        int currentScore = 0;\n        for (auto& [u, v] : edges)\n            currentScore += pot[grid[u]][grid[v]];\n        \n        int bestScore = currentScore;\n        vector<int> bestGrid = grid;\n        \n        auto startTime = chrono::high_resolution_clock::now();\n        const double startTemp = 500.0, endTemp = 0.1;\n        \n        for (int iter = 0; iter < 10000000; iter++) {\n            auto now = chrono::high_resolution_clock::now();\n            auto elapsed = chrono::duration_cast<chrono::microseconds>(now - startTime).count();\n            if (elapsed > 180000) break;\n            \n            double progress = (double)elapsed / 180000.0;\n            double temp = startTemp * pow(endTemp / startTemp, progress);\n            \n            if (rng() % 5 != 0) {\n                int i = rng() % GRID_SIZE, j = rng() % GRID_SIZE;\n                if (i == j) continue;\n                \n                int delta = 0;\n                for (int e : posEdges[i]) { auto& [u,v] = edges[e]; delta -= pot[grid[u]][grid[v]]; }\n                for (int e : posEdges[j]) { auto& [u,v] = edges[e]; delta -= pot[grid[u]][grid[v]]; }\n                \n                swap(grid[i], grid[j]);\n                \n                for (int e : posEdges[i]) { auto& [u,v] = edges[e]; delta += pot[grid[u]][grid[v]]; }\n                for (int e : posEdges[j]) { auto& [u,v] = edges[e]; delta += pot[grid[u]][grid[v]]; }\n                \n                if (delta >= 0 || unif(rng) < exp((double)delta / temp)) {\n                    currentScore += delta;\n                    if (currentScore > bestScore) { bestScore = currentScore; bestGrid = grid; }\n                } else {\n                    swap(grid[i], grid[j]);\n                }\n            } else {\n                int pos = rng() % GRID_SIZE;\n                int old_seed = grid[pos];\n                int up_idx = rng() % unplaced.size();\n                int new_seed = unplaced[up_idx];\n                \n                int delta = 0;\n                for (int e : posEdges[pos]) { auto& [u,v] = edges[e]; delta -= pot[grid[u]][grid[v]]; }\n                \n                grid[pos] = new_seed;\n                \n                for (int e : posEdges[pos]) { auto& [u,v] = edges[e]; delta += pot[grid[u]][grid[v]]; }\n                \n                if (delta >= 0 || unif(rng) < exp((double)delta / temp)) {\n                    currentScore += delta;\n                    isPlaced[old_seed] = false;\n                    isPlaced[new_seed] = true;\n                    unplaced[up_idx] = old_seed;\n                    if (currentScore > bestScore) { bestScore = currentScore; bestGrid = grid; }\n                } else {\n                    grid[pos] = old_seed;\n                }\n            }\n        }\n        \n        grid = bestGrid;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << grid[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;\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\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), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n    \n    int Vp = V;\n    vector<int> len(Vp, 1);\n    \n    cout << Vp << \"\\n\";\n    for (int i = 1; i < Vp; i++) cout << 0 << \" \" << len[i] << \"\\n\";\n    \n    int rx = N/2, ry = N/2;\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<vector<int>> grid(N, vector<int>(N)), target(N, vector<int>(N));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = s[i][j] - '0';\n            target[i][j] = t[i][j] - '0';\n        }\n    \n    vector<int> dir(Vp, 0);\n    vector<bool> holding(Vp, false);\n    vector<string> ops;\n    \n    auto addOp = [&](string op) { ops.push_back(op); };\n    \n    while (true) {\n        int sx=-1, sy=-1, best=INT_MAX;\n        for (int i=0; i<N; i++)\n            for (int j=0; j<N; j++)\n                if (grid[i][j] && !target[i][j]) {\n                    int d = abs(rx-i)+abs(ry-j);\n                    if (d < best) { best=d; sx=i; sy=j; }\n                }\n        if (sx==-1) break;\n        \n        int tx=-1, ty=-1; best=INT_MAX;\n        for (int i=0; i<N; i++)\n            for (int j=0; j<N; j++)\n                if (!grid[i][j] && target[i][j]) {\n                    int d = abs(sx-i)+abs(sy-j);\n                    if (d < best) { best=d; tx=i; ty=j; }\n                }\n        if (tx==-1) break;\n        \n        int f=1, L=len[f];\n        \n        int tRx, tRy, tDir; best=INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx=sx-dx[d]*L, ny=sy-dy[d]*L;\n            if (0<=nx&&nx<N&&0<=ny&&ny<N) {\n                int dist=abs(rx-nx)+abs(ry-ny);\n                if (dist<best) { best=dist; tRx=nx; tRy=ny; tDir=d; }\n            }\n        }\n        \n        while (rx!=tRx||ry!=tRy) {\n            string op(2*Vp, '.');\n            if (rx<tRx) { op[0]='D'; rx++; }\n            else if (rx>tRx) { op[0]='U'; rx--; }\n            else if (ry<tRy) { op[0]='R'; ry++; }\n            else { op[0]='L'; ry--; }\n            addOp(op);\n        }\n        \n        while (dir[f]!=tDir) {\n            string op(2*Vp, '.');\n            int diff=(tDir-dir[f]+4)%4;\n            if (diff<=2) { op[f]='R'; dir[f]=(dir[f]+1)%4; }\n            else { op[f]='L'; dir[f]=(dir[f]+3)%4; }\n            addOp(op);\n        }\n        \n        { string op(2*Vp, '.'); op[Vp+f]='P'; holding[f]=true; grid[sx][sy]=0; addOp(op); }\n        \n        best=INT_MAX;\n        for (int d=0; d<4; d++) {\n            int nx=tx-dx[d]*L, ny=ty-dy[d]*L;\n            if (0<=nx&&nx<N&&0<=ny&&ny<N) {\n                int dist=abs(rx-nx)+abs(ry-ny);\n                if (dist<best) { best=dist; tRx=nx; tRy=ny; tDir=d; }\n            }\n        }\n        \n        while (rx!=tRx||ry!=tRy) {\n            string op(2*Vp, '.');\n            if (rx<tRx) { op[0]='D'; rx++; }\n            else if (rx>tRx) { op[0]='U'; rx--; }\n            else if (ry<tRy) { op[0]='R'; ry++; }\n            else { op[0]='L'; ry--; }\n            addOp(op);\n        }\n        \n        while (dir[f]!=tDir) {\n            string op(2*Vp, '.');\n            int diff=(tDir-dir[f]+4)%4;\n            if (diff<=2) { op[f]='R'; dir[f]=(dir[f]+1)%4; }\n            else { op[f]='L'; dir[f]=(dir[f]+3)%4; }\n            addOp(op);\n        }\n        \n        { string op(2*Vp, '.'); op[Vp+f]='P'; holding[f]=false; grid[tx][ty]=1; addOp(op); }\n    }\n    \n    for (auto& op : ops) cout << op << \"\\n\";\n    return 0;\n}","ahc039":"#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;\n    cin >> N;\n    \n    vector<int> x(2*N), y(2*N);\n    for (int i = 0; i < 2*N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    int gridSize = 100;\n    int cellSize = 1001;\n    \n    vector<vector<int>> grid(gridSize, vector<int>(gridSize, 0));\n    for (int i = 0; i < 2*N; i++) {\n        int gx = min(x[i] / cellSize, gridSize - 1);\n        int gy = min(y[i] / cellSize, gridSize - 1);\n        grid[gx][gy] += (i < N) ? 1 : -1;\n    }\n    \n    vector<vector<int>> prefix(gridSize + 1, vector<int>(gridSize + 1, 0));\n    for (int i = 0; i < gridSize; i++) {\n        for (int j = 0; j < gridSize; j++) {\n            prefix[i + 1][j + 1] = grid[i][j] + prefix[i][j + 1] + prefix[i + 1][j] - prefix[i][j];\n        }\n    }\n    \n    auto gridRectScore = [&](int x1, int y1, int x2, int y2) -> int {\n        return prefix[x2 + 1][y2 + 1] - prefix[x1][y2 + 1] - prefix[x2 + 1][y1] + prefix[x1][y1];\n    };\n    \n    int bestGridScore = 0;\n    int bestGX1 = 0, bestGY1 = 0, bestGX2 = 0, bestGY2 = 0;\n    \n    for (int gx1 = 0; gx1 < gridSize; gx1++) {\n        for (int gx2 = gx1; gx2 < gridSize; gx2++) {\n            int bestY = 0, curY = 0;\n            int bestGY1c = 0, bestGY2c = -1;\n            int curGY1 = 0;\n            \n            for (int gy2 = 0; gy2 < gridSize; gy2++) {\n                curY += gridRectScore(gx1, gy2, gx2, gy2);\n                \n                if (curY > bestY) {\n                    bestY = curY;\n                    bestGY1c = curGY1;\n                    bestGY2c = gy2;\n                }\n                if (curY < 0) {\n                    curY = 0;\n                    curGY1 = gy2 + 1;\n                }\n            }\n            \n            if (bestY > bestGridScore) {\n                bestGridScore = bestY;\n                bestGX1 = gx1;\n                bestGX2 = gx2;\n                bestGY1 = bestGY1c;\n                bestGY2 = bestGY2c;\n            }\n        }\n    }\n    \n    int bestX1 = bestGX1 * cellSize;\n    int bestY1 = bestGY1 * cellSize;\n    int bestX2 = min((bestGX2 + 1) * cellSize - 1, 100000);\n    int bestY2 = min((bestGY2 + 1) * cellSize - 1, 100000);\n    \n    cout << 4 << endl;\n    if (bestGridScore > 0) {\n        cout << bestX1 << \" \" << bestY1 << endl;\n        cout << bestX2 << \" \" << bestY1 << endl;\n        cout << bestX2 << \" \" << bestY2 << endl;\n        cout << bestX1 << \" \" << bestY2 << endl;\n    } else {\n        cout << 50000 << \" \" << 50000 << endl;\n        cout << 50001 << \" \" << 50000 << endl;\n        cout << 50001 << \" \" << 50001 << endl;\n        cout << 50000 << \" \" << 50001 << endl;\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T, sigma;\nvector<long long> w_obs, h_obs;\nvector<double> w_est, h_est;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> T >> sigma;\n    w_obs.resize(N); h_obs.resize(N);\n    w_est.resize(N); h_est.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w_obs[i] >> h_obs[i];\n        w_est[i] = w_obs[i];\n        h_est[i] = h_obs[i];\n    }\n    mt19937 rng(42);\n    for (int t = 0; t < T; t++) {\n        bool always_place = (t % 3 != 2);\n        bool use_noise = (t % 5 >= 3);\n        vector<long long> wc(N), hc(N);\n        for (int i = 0; i < N; i++) {\n            wc[i] = max(1LL, (long long)round(w_est[i]));\n            hc[i] = max(1LL, (long long)round(h_est[i]));\n            if (use_noise) {\n                wc[i] = max(1LL, wc[i] + (long long)(rng() % 4001) - 2000);\n                hc[i] = max(1LL, hc[i] + (long long)(rng() % 4001) - 2000);\n            }\n        }\n        vector<long long> px, py, pw, ph;\n        vector<int> placed_idx;\n        vector<tuple<int,int,char,int>> output;\n        long long curW = 0, curH = 0;\n        for (int i = 0; i < N; i++) {\n            long long best_score = LLONG_MAX;\n            int best_r = 0; char best_d = 'U'; int best_b = -1;\n            long long best_rx = 0, best_ry = 0;\n            long long skip_score = curW + curH + wc[i] + hc[i];\n            if (!always_place) best_score = skip_score;\n            int np = (int)px.size();\n            for (int r = 0; r < 2; r++) {\n                long long rw = r ? hc[i] : wc[i];\n                long long rh = r ? wc[i] : hc[i];\n                for (int b = -1; b < np; b++) {\n                    long long rx = (b < 0) ? 0 : px[b] + pw[b];\n                    long long ry = 0;\n                    for (int j = 0; j < np; j++)\n                        if (px[j] < rx + rw && px[j] + pw[j] > rx)\n                            ry = max(ry, py[j] + ph[j]);\n                    long long s = max(curW, rx + rw) + max(curH, ry + rh);\n                    if (s < best_score) { best_score=s; best_r=r; best_d='U'; best_b=b; best_rx=rx; best_ry=ry; }\n                }\n                for (int b = -1; b < np; b++) {\n                    long long ry = (b < 0) ? 0 : py[b] + ph[b];\n                    long long rx = 0;\n                    for (int j = 0; j < np; j++)\n                        if (py[j] < ry + rh && py[j] + ph[j] > ry)\n                            rx = max(rx, px[j] + pw[j]);\n                    long long s = max(curW, rx + rw) + max(curH, ry + rh);\n                    if (s < best_score) { best_score=s; best_r=r; best_d='L'; best_b=b; best_rx=rx; best_ry=ry; }\n                }\n            }\n            if (always_place || best_score < skip_score) {\n                long long rw = best_r ? hc[i] : wc[i];\n                long long rh = best_r ? wc[i] : hc[i];\n                px.push_back(best_rx); py.push_back(best_ry);\n                pw.push_back(rw); ph.push_back(rh);\n                placed_idx.push_back(i);\n                output.push_back({i, best_r, best_d, best_b});\n                curW = max(curW, best_rx + rw);\n                curH = max(curH, best_ry + rh);\n            }\n        }\n        cout << output.size() << \"\\n\";\n        for (auto& [p, r, d, b] : output)\n            cout << p << \" \" << r << \" \" << d << \" \" << b << \"\\n\";\n        cout.flush();\n        long long Wp, Hp;\n        cin >> Wp >> Hp;\n        double Werr = (double)(Wp - curW), Herr = (double)(Hp - curH);\n        if (!px.empty()) {\n            int rcnt = 0, bcnt = 0;\n            for (int j = 0; j < (int)px.size(); j++) {\n                if (px[j]+pw[j]==curW) rcnt++;\n                if (py[j]+ph[j]==curH) bcnt++;\n            }\n            double lr = 0.2;\n            for (int j = 0; j < (int)px.size(); j++) {\n                int orig = placed_idx[j]; bool rot = get<1>(output[j]);\n                if (px[j]+pw[j]==curW && rcnt>0) {\n                    double es = Werr/rcnt*lr;\n                    if (rot) h_est[orig]=max(1.0,h_est[orig]+es);\n                    else w_est[orig]=max(1.0,w_est[orig]+es);\n                }\n                if (py[j]+ph[j]==curH && bcnt>0) {\n                    double es = Herr/bcnt*lr;\n                    if (rot) w_est[orig]=max(1.0,w_est[orig]+es);\n                    else h_est[orig]=max(1.0,h_est[orig]+es);\n                }\n            }\n        }\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, H;\nvector<int> A;\nvector<vector<int>> adj;\nvector<int> X, Y;\n\nvoid improve(vector<int>& parent) {\n    vector<int> height(N, 0);\n    vector<long long> sub_sum(N);\n    vector<int> sub_max_h(N);\n    \n    auto recompute = [&]() {\n        vector<int> child_count(N, 0);\n        for (int v = 0; v < N; v++) {\n            if (parent[v] != -1) child_count[parent[v]]++;\n        }\n        queue<int> q;\n        for (int v = 0; v < N; v++) {\n            height[v] = (parent[v] == -1) ? 0 : -1;\n            sub_sum[v] = A[v];\n            sub_max_h[v] = 0;\n            if (child_count[v] == 0) q.push(v);\n        }\n        // Compute heights top-down\n        {\n            vector<int> topo;\n            queue<int> q2;\n            vector<int> cc2(N, 0);\n            for (int v = 0; v < N; v++) if (parent[v] != -1) cc2[parent[v]]++;\n            for (int v = 0; v < N; v++) if (cc2[v] == 0) q2.push(v);\n            while (!q2.empty()) {\n                int v = q2.front(); q2.pop();\n                topo.push_back(v);\n                if (parent[v] != -1) { cc2[parent[v]]--; if (cc2[parent[v]] == 0) q2.push(parent[v]); }\n            }\n            for (int i = topo.size() - 1; i >= 0; i--) {\n                int v = topo[i];\n                if (parent[v] == -1) height[v] = 0;\n                else height[v] = height[parent[v]] + 1;\n            }\n        }\n        for (int v = 0; v < N; v++) { sub_sum[v] = A[v]; sub_max_h[v] = height[v]; }\n        while (!q.empty()) {\n            int v = q.front(); q.pop();\n            int p = parent[v];\n            if (p != -1) {\n                sub_sum[p] += sub_sum[v];\n                sub_max_h[p] = max(sub_max_h[p], sub_max_h[v]);\n                child_count[p]--;\n                if (child_count[p] == 0) q.push(p);\n            }\n        }\n    };\n    \n    recompute();\n    \n    auto creates_cycle = [&](int v, int u) -> bool {\n        int curr = u;\n        while (curr != -1) { if (curr == v) return true; curr = parent[curr]; }\n        return false;\n    };\n    \n    auto update_heights = [&](int v, int delta) {\n        stack<int> st; st.push(v);\n        while (!st.empty()) {\n            int curr = st.top(); st.pop();\n            height[curr] += delta;\n            for (int u : adj[curr]) if (parent[u] == curr) st.push(u);\n        }\n    };\n    \n    while (true) {\n        long long best_gain = 0; int best_v = -1, best_u = -1;\n        for (int v = 0; v < N; v++) {\n            for (int u : adj[v]) {\n                if (u == parent[v]) continue;\n                int new_h = height[u] + 1;\n                int delta = new_h - height[v];\n                if (delta <= 0) continue;\n                if (sub_max_h[v] + delta > H) continue;\n                if (creates_cycle(v, u)) continue;\n                long long gain = (long long)delta * sub_sum[v];\n                if (gain > best_gain) { best_gain = gain; best_v = v; best_u = u; }\n            }\n        }\n        if (best_v == -1) break;\n        int delta = height[best_u] + 1 - height[best_v];\n        parent[best_v] = best_u;\n        update_heights(best_v, delta);\n        recompute();\n    }\n}\n\nlong long compute_score(const vector<int>& par) {\n    long long score = 0;\n    for (int v = 0; v < N; v++) {\n        int h = 0, curr = v;\n        while (par[curr] != -1) { curr = par[curr]; h++; }\n        score += (long long)(h + 1) * A[v];\n    }\n    return score;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M >> H;\n    A.resize(N);\n    for (int i = 0; i < N; i++) cin >> A[i];\n    adj.resize(N);\n    for (int i = 0; i < M; i++) { int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); }\n    X.resize(N); Y.resize(N);\n    for (int i = 0; i < N; i++) cin >> X[i] >> Y[i];\n    \n    long long best_score = 0;\n    vector<int> best_parent(N, -1);\n    \n    // Strategy 1: All roots + improve\n    { vector<int> p(N, -1); improve(p); long long s = compute_score(p); if (s > best_score) { best_score = s; best_parent = p; } }\n    \n    // Strategy 2: BFS from central vertices\n    {\n        vector<int> p(N, -1), h(N, 0); vector<bool> as(N, false);\n        vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a, int b) { return (X[a]-500)*(X[a]-500)+(Y[a]-500)*(Y[a]-500) < (X[b]-500)*(X[b]-500)+(Y[b]-500)*(Y[b]-500); });\n        for (int idx = 0; idx < N; idx++) {\n            int root = ord[idx]; if (as[root]) continue;\n            queue<int> q; q.push(root); as[root] = true; p[root] = -1; h[root] = 0;\n            while (!q.empty()) {\n                int u = q.front(); q.pop(); if (h[u] >= H) continue;\n                vector<int> ch; for (int v : adj[u]) if (!as[v]) ch.push_back(v);\n                sort(ch.begin(), ch.end(), [&](int a, int b) { return A[a] > A[b]; });\n                for (int v : ch) { if (as[v]) continue; as[v] = true; p[v] = u; h[v] = h[u]+1; q.push(v); }\n            }\n        }\n        improve(p); long long s = compute_score(p); if (s > best_score) { best_score = s; best_parent = p; }\n    }\n    \n    // Strategy 3: Build chains from high-beauty vertices\n    {\n        vector<int> p(N, -1), h(N, 0); vector<bool> as(N, false);\n        vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a, int b) { return A[a] > A[b]; });\n        for (int v : ord) {\n            if (as[v]) continue;\n            vector<int> dist(N, -1), par(N, -1); queue<int> q; q.push(v); dist[v] = 0;\n            int target = -1;\n            while (!q.empty()) {\n                int u = q.front(); q.pop();\n                if (dist[u] == H) { target = u; break; }\n                for (int w : adj[u]) if (!as[w] && dist[w] == -1) { dist[w] = dist[u]+1; par[w] = u; q.push(w); }\n            }\n            if (target == -1) for (int u = 0; u < N; u++) if (dist[u] > 0 && (target == -1 || dist[u] > dist[target])) target = u;\n            if (target != -1) {\n                vector<int> path; int curr = target;\n                while (true) { path.push_back(curr); if (curr == v) break; curr = par[curr]; }\n                for (int i = 0; i < (int)path.size(); i++) { as[path[i]] = true; p[path[i]] = (i==0)?-1:path[i-1]; h[path[i]] = i; }\n            } else { as[v] = true; p[v] = -1; h[v] = 0; }\n        }\n        improve(p); long long s = compute_score(p); if (s > best_score) { best_score = s; best_parent = p; }\n    }\n    \n    // Strategy 4: BFS from low-beauty roots with high-beauty priority\n    {\n        vector<int> p(N, -1), h(N, 0); vector<bool> as(N, false);\n        vector<int> ord(N); iota(ord.begin(), ord.end(), 0);\n        sort(ord.begin(), ord.end(), [&](int a, int b) { return A[a] < A[b]; });\n        int nr = max(1, N / (H + 1));\n        priority_queue<pair<int,int>> pq; // (-height, -beauty)\n        for (int i = 0; i < nr && i < N; i++) { int v = ord[i]; as[v] = true; p[v] = -1; h[v] = 0; pq.push({0, -A[v]}); }\n        // Rebuild with vertex indices\n        priority_queue<tuple<int,int,int>> pq2;\n        for (int i = 0; i < nr && i < N; i++) { int v = ord[i]; pq2.push({0, -A[v], v}); }\n        while (!pq2.empty()) {\n            auto [nh, nb, u] = pq2.top(); pq2.pop();\n            if (h[u] >= H) continue;\n            vector<int> ch; for (int v : adj[u]) if (!as[v]) ch.push_back(v);\n            sort(ch.begin(), ch.end(), [&](int a, int b) { return A[a] > A[b]; });\n            for (int v : ch) { if (as[v]) continue; as[v] = true; p[v] = u; h[v] = h[u]+1; pq2.push({-h[v], -A[v], v}); }\n        }\n        for (int v = 0; v < N; v++) if (!as[v]) { as[v] = true; p[v] = -1; h[v] = 0; }\n        improve(p); long long s = compute_score(p); if (s > best_score) { best_score = s; best_parent = p; }\n    }\n    \n    for (int i = 0; i < N; i++) cout << best_parent[i] << (i == N-1 ? \"\\n\" : \" \");\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <map>\n#include <algorithm>\nusing namespace std;\n\nint main() {\n    int N; cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    vector<string> initial_board = board;\n    \n    vector<pair<char,int>> moves;\n    \n    auto shift = [&](char dir, int idx) {\n        if (dir == 'L') {\n            for (int j = 0; j < N-1; j++) board[idx][j] = board[idx][j+1];\n            board[idx][N-1] = '.';\n        } else if (dir == 'R') {\n            for (int j = N-1; j > 0; j--) board[idx][j] = board[idx][j-1];\n            board[idx][0] = '.';\n        } else if (dir == 'U') {\n            for (int i = 0; i < N-1; i++) board[i][idx] = board[i+1][idx];\n            board[N-1][idx] = '.';\n        } else {\n            for (int i = N-1; i > 0; i--) board[i][idx] = board[i-1][idx];\n            board[0][idx] = '.';\n        }\n        moves.push_back({dir, idx});\n    };\n    \n    // Phase 1: Greedy without shift-backs\n    bool greedy_ok = true;\n    while (true) {\n        int best_cost = N + 2;\n        int best_idx = -1;\n        char best_dir = 0;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] != 'x') continue;\n                {bool s=true; for(int k=0;k<j;k++) if(board[i][k]=='o'){s=false;break;} if(s&&j+1<best_cost){best_cost=j+1;best_idx=i;best_dir='L';}}\n                {bool s=true; for(int k=j+1;k<N;k++) if(board[i][k]=='o'){s=false;break;} if(s&&N-j<best_cost){best_cost=N-j;best_idx=i;best_dir='R';}}\n                {bool s=true; for(int k=0;k<i;k++) if(board[k][j]=='o'){s=false;break;} if(s&&i+1<best_cost){best_cost=i+1;best_idx=j;best_dir='U';}}\n                {bool s=true; for(int k=i+1;k<N;k++) if(board[k][j]=='o'){s=false;break;} if(s&&N-i<best_cost){best_cost=N-i;best_idx=j;best_dir='D';}}\n            }\n        }\n        \n        if (best_dir == 0) {\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j] == 'x') greedy_ok = false;\n            break;\n        }\n        for (int k = 0; k < best_cost; k++) shift(best_dir, best_idx);\n    }\n    \n    // Phase 2: Fallback - batch with shift-backs if greedy got stuck\n    if (!greedy_ok) {\n        board = initial_board;\n        moves.clear();\n        \n        struct Oni { int i, j, id; };\n        vector<Oni> onis;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j] == 'x') onis.push_back({i, j, (int)onis.size()});\n        \n        map<pair<char,int>, vector<int>> batches;\n        for (auto& o : onis) {\n            bool us=true,ds=true,ls=true,rs=true;\n            for(int k=0;k<o.i;k++) if(board[k][o.j]=='o'){us=false;break;}\n            for(int k=o.i+1;k<N;k++) if(board[k][o.j]=='o'){ds=false;break;}\n            for(int k=0;k<o.j;k++) if(board[o.i][k]=='o'){ls=false;break;}\n            for(int k=o.j+1;k<N;k++) if(board[o.i][k]=='o'){rs=false;break;}\n            char bd=0; int bc=1e9;\n            if(us){int c=o.i+1;if(c<bc){bc=c;bd='U';}}\n            if(ds){int c=N-o.i;if(c<bc){bc=c;bd='D';}}\n            if(ls){int c=o.j+1;if(c<bc){bc=c;bd='L';}}\n            if(rs){int c=N-o.j;if(c<bc){bc=c;bd='R';}}\n            if(bd){int idx=(bd=='L'||bd=='R')?o.i:o.j; batches[{bd,idx}].push_back(o.id);}\n        }\n        \n        set<int> removed;\n        for (char dir : {'U','D','L','R'}) {\n            for (int idx = 0; idx < N; idx++) {\n                auto key = make_pair(dir, idx);\n                if (batches.find(key) == batches.end()) continue;\n                int md = 0;\n                for (int oid : batches[key]) { if(removed.count(oid)) continue; auto& o=onis[oid]; int d=(dir=='U')?o.i+1:(dir=='D')?N-o.i:(dir=='L')?o.j+1:N-o.j; md=max(md,d); }\n                if (md == 0) continue;\n                for (int k = 0; k < md; k++) shift(dir, idx);\n                char opp = (dir=='U')?'D':(dir=='D')?'U':(dir=='L')?'R':'L';\n                for (int k = 0; k < md; k++) shift(opp, idx);\n                for (auto& o : onis) { if(removed.count(o.id)) continue; bool ip=false;\n                    if(dir=='U'&&o.j==idx&&o.i<md) ip=true;\n                    else if(dir=='D'&&o.j==idx&&o.i>=N-md) ip=true;\n                    else if(dir=='L'&&o.i==idx&&o.j<md) ip=true;\n                    else if(dir=='R'&&o.i==idx&&o.j>=N-md) ip=true;\n                    if(ip) removed.insert(o.id); }\n            }\n        }\n    }\n    \n    for (auto& [d, p] : moves) cout << d << \" \" << p << \"\\n\";\n    return 0;\n}","ahc044":"#include <iostream>\n#include <cmath>\n#include <chrono>\n#include <cstring>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nint N, L;\nint T[100];\nint a[100], b[100];\nint best_a[100], best_b[100];\nint best_error = INT_MAX;\n\nuint64_t rng_state = 1234567890123456789ULL;\nuint64_t rng64() {\n    rng_state ^= rng_state >> 12;\n    rng_state ^= rng_state << 25;\n    rng_state ^= rng_state >> 27;\n    return rng_state * 2685821657736338717ULL;\n}\n\nint simulate(int ai[], int bi[]) {\n    int count[100] = {}, ti[100] = {};\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        ti[cur]++;\n        count[cur]++;\n        cur = (count[cur] & 1) ? ai[cur] : bi[cur];\n    }\n    int err = 0;\n    for (int i = 0; i < N; i++) err += abs(ti[i] - T[i]);\n    return err;\n}\n\nvoid try_init(int ai[], int bi[]) {\n    int err = simulate(ai, bi);\n    if (err < best_error) {\n        best_error = err;\n        memcpy(best_a, ai, sizeof(int) * N);\n        memcpy(best_b, bi, sizeof(int) * N);\n    }\n}\n\nvoid greedy_init(int ai[], int bi[], bool avoid_self) {\n    int rem[100]; memcpy(rem, T, sizeof(T));\n    int cnt[100] = {};\n    bool as[100] = {}, bs[100] = {};\n    memset(ai, 0, sizeof(int) * N);\n    memset(bi, 0, sizeof(int) * N);\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        rem[cur]--;\n        cnt[cur]++;\n        if (cnt[cur] & 1) {\n            if (!as[cur]) {\n                int best = -1;\n                for (int j = 0; j < N; j++) {\n                    if (avoid_self && j == cur) continue;\n                    if (best == -1 || rem[j] > rem[best]) best = j;\n                }\n                if (best == -1) best = (cur + 1) % N;\n                ai[cur] = best; as[cur] = true;\n            }\n            cur = ai[cur];\n        } else {\n            if (!bs[cur]) {\n                int best = -1;\n                for (int j = 0; j < N; j++) {\n                    if (avoid_self && j == cur) continue;\n                    if (best == -1 || rem[j] > rem[best]) best = j;\n                }\n                if (best == -1) best = (cur + 1) % N;\n                bi[cur] = best; bs[cur] = true;\n            }\n            cur = bi[cur];\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> L;\n    for (int i = 0; i < N; i++) cin >> T[i];\n    \n    int ai[100], bi[100];\n    \n    // Init 1: Simple cycle\n    for (int i = 0; i < N; i++) { ai[i] = (i+1)%N; bi[i] = (i+1)%N; }\n    try_init(ai, bi);\n    \n    // Init 2: Greedy (allow self-loops)\n    greedy_init(ai, bi, false);\n    try_init(ai, bi);\n    \n    // Init 3: Greedy (avoid self-loops)\n    greedy_init(ai, bi, true);\n    try_init(ai, bi);\n    \n    // Init 4: Flow-based\n    {\n        struct Src { int emp; int flow; bool odd; };\n        Src srcs[200];\n        for (int i = 0; i < N; i++) {\n            srcs[2*i] = {i, (T[i]+1)/2, true};\n            srcs[2*i+1] = {i, T[i]/2, false};\n        }\n        sort(srcs, srcs+2*N, [](const Src& a, const Src& b) { return a.flow > b.flow; });\n        int dem[100]; memcpy(dem, T, sizeof(T));\n        for (int s = 0; s < 2*N; s++) {\n            int best = 0;\n            for (int j = 1; j < N; j++) if (dem[j] > dem[best]) best = j;\n            if (srcs[s].odd) ai[srcs[s].emp] = best;\n            else bi[srcs[s].emp] = best;\n            dem[best] -= srcs[s].flow;\n        }\n        try_init(ai, bi);\n    }\n    \n    // Use best init for SA\n    memcpy(a, best_a, sizeof(a));\n    memcpy(b, best_b, sizeof(b));\n    int error = best_error;\n    \n    auto start = chrono::high_resolution_clock::now();\n    double temp = max(50.0, error / 80.0);\n    double cool = 0.993;\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration<double>(now - start).count() > 1.85) break;\n        \n        int i = rng64() % N;\n        bool is_a = rng64() & 1;\n        int old = is_a ? a[i] : b[i];\n        int nv = rng64() % N;\n        if (is_a) a[i] = nv; else b[i] = nv;\n        \n        int ne = simulate(a, b);\n        double delta = ne - error;\n        if (delta <= 0 || (double)(rng64() & 0xFFFFF) / 1048576.0 < exp(-delta / temp)) {\n            error = ne;\n            if (error < best_error) {\n                best_error = error;\n                memcpy(best_a, a, sizeof(a));\n                memcpy(best_b, b, sizeof(b));\n            }\n        } else {\n            if (is_a) a[i] = old; else b[i] = old;\n        }\n        temp *= cool;\n    }\n    \n    for (int i = 0; i < N; i++)\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nuint64_t xy2d(int n, int x, int y) {\n    uint64_t d = 0;\n    for (int s = n/2; s > 0; s /= 2) {\n        int rx = (x & s) > 0;\n        int ry = (y & s) > 0;\n        d += (uint64_t)s * s * ((3 * rx) ^ ry);\n        if (ry == 0) {\n            if (rx == 1) { x = s-1 - x; y = s-1 - y; }\n            swap(x, y);\n        }\n    }\n    return d;\n}\n\nint N, M, Q, L, W;\ndouble cx[800], cy[800], ddist[800][800];\nint qcnt = 0;\n\nvector<pair<int,int>> query(vector<int>& v) {\n    if (qcnt >= Q || (int)v.size() < 2) return {};\n    qcnt++;\n    cout << \"? \" << v.size();\n    for (int x : v) cout << \" \" << x;\n    cout << endl;\n    vector<pair<int,int>> res(v.size() - 1);\n    for (auto& [a, b] : res) cin >> a >> b;\n    return res;\n}\n\nint par[800], rnk[800];\nvoid init_dsu() { iota(par, par + N, 0); fill(rnk, rnk + N, 0); }\nint find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }\nbool unite(int x, int y) {\n    x = find(x); y = find(y);\n    if (x == y) return false;\n    if (rnk[x] < rnk[y]) swap(x, y);\n    par[y] = x;\n    if (rnk[x] == rnk[y]) rnk[x]++;\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> Q >> L >> W;\n    vector<int> G(M);\n    for (int& g : G) cin >> g;\n    \n    for (int i = 0; i < N; i++) {\n        int a, b, c, d;\n        cin >> a >> b >> c >> d;\n        cx[i] = (a + b) / 2.0;\n        cy[i] = (c + d) / 2.0;\n    }\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            double dx = cx[i] - cx[j], dy = cy[i] - cy[j];\n            ddist[i][j] = sqrt(dx*dx + dy*dy);\n        }\n    \n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [](int a, int b) {\n        return xy2d(32768, (int)cx[a], (int)cy[a]) < xy2d(32768, (int)cx[b], (int)cy[b]);\n    });\n    \n    vector<vector<int>> grp(M);\n    for (int i = 0, p = 0; i < M; i++)\n        for (int j = 0; j < G[i]; j++)\n            grp[i].push_back(ord[p++]);\n    \n    vector<vector<pair<int,int>>> ans(M);\n    \n    for (int k = 0; k < M; k++) {\n        if (G[k] <= 1) continue;\n        \n        init_dsu();\n        if (G[k] <= L && qcnt < Q) {\n            ans[k] = query(grp[k]);\n            continue;\n        }\n        \n        set<int> conn;\n        vector<pair<int,int>> mst;\n        conn.insert(grp[k][0]);\n        \n        while (conn.size() < (size_t)G[k] && qcnt < Q) {\n            vector<pair<double,int>> cands;\n            for (int c : grp[k]) {\n                if (conn.count(c)) continue;\n                double md = 1e18;\n                for (int t : conn) md = min(md, ddist[c][t]);\n                cands.emplace_back(md, c);\n            }\n            if (cands.empty()) break;\n            sort(cands.begin(), cands.end());\n            \n            int ncand = min((int)cands.size(), L - 1);\n            vector<pair<double,int>> tree_sorted;\n            for (int t : conn) {\n                double md = 1e18;\n                for (int i = 0; i < ncand; i++) md = min(md, ddist[t][cands[i].second]);\n                tree_sorted.emplace_back(md, t);\n            }\n            sort(tree_sorted.begin(), tree_sorted.end());\n            \n            int ntree = min((int)tree_sorted.size(), L - ncand);\n            vector<int> qv;\n            for (int i = 0; i < ntree; i++) qv.push_back(tree_sorted[i].second);\n            for (int i = 0; i < ncand; i++) qv.push_back(cands[i].second);\n            \n            auto edges = query(qv);\n            for (auto& [a, b] : edges) {\n                if (unite(a, b)) {\n                    mst.emplace_back(a, b);\n                    conn.insert(a);\n                    conn.insert(b);\n                }\n            }\n        }\n        \n        vector<tuple<double,int,int>> edges;\n        for (int i = 0; i < G[k]; i++)\n            for (int j = i + 1; j < G[k]; j++)\n                edges.emplace_back(ddist[grp[k][i]][grp[k][j]], grp[k][i], grp[k][j]);\n        sort(edges.begin(), edges.end());\n        \n        for (auto& [d, a, b] : edges) {\n            if (unite(a, b)) {\n                mst.emplace_back(a, b);\n                conn.insert(a);\n                conn.insert(b);\n            }\n            if (conn.size() == (size_t)G[k]) break;\n        }\n        \n        ans[k] = mst;\n    }\n    \n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < G[k]; i++) cout << grp[k][i] << \" \\n\"[i==G[k]-1];\n        for (auto& [a, b] : ans[k]) cout << a << \" \" << b << \"\\n\";\n    }\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <set>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <cstring>\n\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    \n    vector<pair<int, int>> targets(M);\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n    \n    set<pair<int, int>> blocks;\n    int cur_r = targets[0].first, cur_c = targets[0].second;\n    vector<pair<char, char>> all_actions;\n    \n    const int dr[] = {-1, 1, 0, 0};\n    const int dc[] = {0, 0, -1, 1};\n    const char dir_chars[] = {'U', 'D', 'L', 'R'};\n    \n    set<pair<int, int>> future_targets;\n    for (int i = 1; i < M; i++) future_targets.insert(targets[i]);\n    \n    auto get_slide_dest = [&](int r, int c, int d) -> pair<int, int> {\n        int nr = r + dr[d], nc = c + dc[d];\n        while (nr >= 0 && nr < N && nc >= 0 && nc < N && blocks.count({nr, nc}) == 0) {\n            nr += dr[d]; nc += dc[d];\n        }\n        nr -= dr[d]; nc -= dc[d];\n        return {nr, nc};\n    };\n    \n    auto bfs = [&](int sr, int sc, int tr, int tc) -> vector<tuple<char,char,int,int>> {\n        if (sr == tr && sc == tc) return {};\n        vector<vector<int>> dist(N, vector<int>(N, -1));\n        vector<vector<tuple<int,int,char,char>>> parent(N, vector<tuple<int,int,char,char>>(N, {-1,-1,' ',' '}));\n        queue<pair<int,int>> q;\n        q.push({sr, sc}); dist[sr][sc] = 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 < N && nc >= 0 && nc < N && blocks.count({nr, nc}) == 0 && dist[nr][nc] == -1) {\n                    dist[nr][nc] = dist[r][c] + 1;\n                    parent[nr][nc] = {r, c, 'M', dir_chars[d]};\n                    if (nr == tr && nc == tc) goto found;\n                    q.push({nr, nc});\n                }\n                auto [snr, snc] = get_slide_dest(r, c, d);\n                if ((snr != r || snc != c) && dist[snr][snc] == -1) {\n                    dist[snr][snc] = dist[r][c] + 1;\n                    parent[snr][snc] = {r, c, 'S', dir_chars[d]};\n                    if (snr == tr && snc == tc) goto found;\n                    q.push({snr, snc});\n                }\n            }\n        }\n        return {};\n    found:\n        vector<tuple<char,char,int,int>> path;\n        int cr = tr, cc = tc;\n        while (true) {\n            auto [pr, pc, act, dir] = parent[cr][cc];\n            if (pr == -1) break;\n            path.push_back({act, dir, cr, cc});\n            cr = pr; cc = pc;\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n    \n    auto execute_path = [&](vector<tuple<char,char,int,int>>& path) {\n        for (auto& [act, dir, nr, nc] : path) {\n            all_actions.push_back({act, dir});\n            cur_r = nr; cur_c = nc;\n        }\n    };\n    \n    for (int t = 1; t < M; t++) {\n        future_targets.erase(targets[t]);\n        int tr = targets[t].first, tc = targets[t].second;\n        \n        // Remove block on target if present\n        if (blocks.count({tr, tc})) {\n            for (int d = 0; d < 4; d++) {\n                int ar = tr + dr[d], ac = tc + dc[d];\n                if (ar >= 0 && ar < N && ac >= 0 && ac < N && blocks.count({ar, ac}) == 0) {\n                    auto path_adj = bfs(cur_r, cur_c, ar, ac);\n                    if (!path_adj.empty()) {\n                        execute_path(path_adj);\n                        char adir;\n                        if (d == 0) adir = 'D';\n                        else if (d == 1) adir = 'U';\n                        else if (d == 2) adir = 'R';\n                        else adir = 'L';\n                        blocks.erase({tr, tc});\n                        all_actions.push_back({'A', adir});\n                        break;\n                    }\n                }\n            }\n        }\n        \n        auto path = bfs(cur_r, cur_c, tr, tc);\n        execute_path(path);\n        \n        // Place block at best adjacent position for future slides\n        // Prefer positions on grid lines (rows/cols divisible by 5)\n        int best_d = -1, best_score = -1;\n        for (int d = 0; d < 4; d++) {\n            int br = cur_r + dr[d], bc = cur_c + dc[d];\n            if (br < 0 || br >= N || bc < 0 || bc >= N) continue;\n            if (blocks.count({br, bc})) continue;\n            if (future_targets.count({br, bc})) continue;\n            int score = 0;\n            if (br % 5 == 0) score += 2;\n            if (bc % 5 == 0) score += 2;\n            // Prefer placing below or right for downward/rightward slide stops\n            if (d == 1) score += 1;\n            if (d == 3) score += 1;\n            if (score > best_score) { best_score = score; best_d = d; }\n        }\n        if (best_d != -1) {\n            int br = cur_r + dr[best_d], bc = cur_c + dc[best_d];\n            blocks.insert({br, bc});\n            all_actions.push_back({'A', dir_chars[best_d]});\n        }\n    }\n    \n    for (auto& [a, d] : all_actions) {\n        cout << a << \" \" << d << \"\\n\";\n    }\n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> x, y, r;\nvector<int> ra, rb, rc, rd;\n\ndouble satisfaction(long long s, long long rv) {\n    if (s <= 0 || rv <= 0) return 0;\n    double ratio = (double)min(s, rv) / max(s, rv);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\ndouble compute_score() {\n    double score = 0;\n    for (int i = 0; i < n; i++)\n        score += satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]), r[i]);\n    return score;\n}\n\nstruct TNode {\n    bool is_leaf;\n    int company;\n    bool vertical;\n    int split_k;\n    vector<int> items;\n    int lc, rc_node;\n};\nvector<TNode> tree;\nvector<int> split_offset;\n\nint build_tree(vector<int> items, mt19937& rng) {\n    int idx = tree.size();\n    tree.push_back({});\n    if (items.size() == 1) {\n        tree[idx] = {true, items[0], false, 0, items, -1, -1};\n        return idx;\n    }\n    long long total_r = 0;\n    for (int i : items) total_r += r[i];\n    bool best_vert = true; int best_k = -1; double best_score = -1e18;\n    for (int dir = 0; dir < 2; dir++) {\n        bool vert = (dir == 0);\n        auto sorted = items;\n        sort(sorted.begin(), sorted.end(), [&](int i, int j) { return vert ? x[i] < x[j] : y[i] < y[j]; });\n        auto& coord = vert ? x : y;\n        long long sum = 0;\n        for (int k = 1; k < (int)sorted.size(); k++) {\n            sum += r[sorted[k-1]];\n            if (coord[sorted[k-1]] >= coord[sorted[k]]) continue;\n            double score = -abs((double)sum/total_r - 0.5) + uniform_real_distribution<double>(0,0.02)(rng);\n            if (score > best_score) { best_score = score; best_vert = vert; best_k = k; }\n        }\n    }\n    if (best_k < 0) { tree[idx] = {true, items[0], false, 0, items, -1, -1}; return idx; }\n    sort(items.begin(), items.end(), [&](int i, int j) { return best_vert ? x[i] < x[j] : y[i] < y[j]; });\n    vector<int> li(items.begin(), items.begin()+best_k), ri(items.begin()+best_k, items.end());\n    int lc = build_tree(li, rng), rc2 = build_tree(ri, rng);\n    tree[idx] = {false, -1, best_vert, best_k, items, lc, rc2};\n    return idx;\n}\n\nvoid compute_rects(int idx, int L, int B, int R, int T) {\n    if (tree[idx].is_leaf) { int i = tree[idx].company; ra[i]=L; rb[i]=B; rc[i]=R; rd[i]=T; return; }\n    auto& items = tree[idx].items;\n    long long total_r=0, left_r=0;\n    for (int j=0; j<(int)items.size(); j++) { total_r+=r[items[j]]; if(j<tree[idx].split_k) left_r+=r[items[j]]; }\n    auto& coord = tree[idx].vertical ? x : y;\n    int maxL = coord[items[tree[idx].split_k-1]], minR = coord[items[tree[idx].split_k]];\n    int lo = tree[idx].vertical ? L : B, hi = tree[idx].vertical ? R : T;\n    long long ideal = lo + (long long)(hi-lo)*left_r/total_r;\n    int sp = (int)ideal + split_offset[idx];\n    sp = max(sp, maxL+1); sp = min(sp, minR); sp = max(sp, lo+1); sp = min(sp, hi-1);\n    if (tree[idx].vertical) { compute_rects(tree[idx].lc, L, B, sp, T); compute_rects(tree[idx].rc_node, sp, B, R, T); }\n    else { compute_rects(tree[idx].lc, L, B, R, sp); compute_rects(tree[idx].rc_node, L, sp, R, T); }\n}\n\nvoid post_process_offsets(int root) {\n    split_offset.assign(tree.size(), 0);\n    compute_rects(root, 0, 0, 10000, 10000);\n    double best = compute_score();\n    vector<int> internal;\n    for (int i=0; i<(int)tree.size(); i++) if(!tree[i].is_leaf) internal.push_back(i);\n    for (int round=0; round<50; round++) {\n        bool improved = false;\n        for (int idx : internal) {\n            for (int d : {-50,-20,-10,-5,-2,-1,1,2,5,10,20,50}) {\n                split_offset[idx] += d;\n                compute_rects(root, 0, 0, 10000, 10000);\n                double ns = compute_score();\n                if (ns > best+1e-12) { best=ns; improved=true; }\n                else split_offset[idx] -= d;\n            }\n        }\n        if (!improved) break;\n    }\n    compute_rects(root, 0, 0, 10000, 10000);\n}\n\nvoid post_process_expand() {\n    for (int round=0; round<100; round++) {\n        bool any=false;\n        for (int i=0; i<n; i++) {\n            auto try_expand = [&](int& val, int delta, int limit, bool is_x, bool is_lo, auto check_overlap) {\n                while (true) {\n                    int nv = val + delta;\n                    if ((delta>0 && nv>limit)||(delta<0 && nv<limit)) break;\n                    if (is_lo && is_x && nv > x[i]) break;\n                    if (is_lo && !is_x && nv > y[i]) break;\n                    if (!is_lo && is_x && nv <= x[i]) break;\n                    if (!is_lo && !is_x && nv <= y[i]) break;\n                    int old=val; val=nv;\n                    bool overlap=false;\n                    for (int j=0;j<n;j++){if(j==i)continue;if(check_overlap(j)){overlap=true;break;}}\n                    if(overlap){val=old;break;}\n                    long long na=(long long)(rc[i]-ra[i])*(rd[i]-rb[i]);\n                    if(satisfaction(na,r[i])<=satisfaction((long long)(rc[i]-ra[i]+(is_x&&!is_lo?delta:(is_x&&is_lo?-delta:0)))*(rd[i]-rb[i]+(!is_x&&!is_lo?delta:(!is_x&&is_lo?-delta:0))),r[i])+1e-12){val=old;break;}\n                    any=true;\n                }\n            };\n            long long ca=(long long)(rc[i]-ra[i])*(rd[i]-rb[i]);\n            // Shrink oversized first\n            if(ca>r[i]){\n                while((long long)(rc[i]-ra[i])*(rd[i]-rb[i])>r[i]&&rc[i]-1>x[i]){int nc=rc[i]-1;long long na=(long long)(nc-ra[i])*(rd[i]-rb[i]);if(satisfaction(na,r[i])>satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]),r[i])+1e-12){rc[i]=nc;any=true;}else break;}\n                while((long long)(rc[i]-ra[i])*(rd[i]-rb[i])>r[i]&&ra[i]+1<=x[i]){int na2=ra[i]+1;long long na=(long long)(rc[i]-na2)*(rd[i]-rb[i]);if(satisfaction(na,r[i])>satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]),r[i])+1e-12){ra[i]=na2;any=true;}else break;}\n                while((long long)(rc[i]-ra[i])*(rd[i]-rb[i])>r[i]&&rd[i]-1>y[i]){int nd=rd[i]-1;long long na=(long long)(rc[i]-ra[i])*(nd-rb[i]);if(satisfaction(na,r[i])>satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]),r[i])+1e-12){rd[i]=nd;any=true;}else break;}\n                while((long long)(rc[i]-ra[i])*(rd[i]-rb[i])>r[i]&&rb[i]+1<=y[i]){int nb=rb[i]+1;long long na=(long long)(rc[i]-ra[i])*(rd[i]-nb);if(satisfaction(na,r[i])>satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]),r[i])+1e-12){rb[i]=nb;any=true;}else break;}\n            }\n            // Expand undersized\n            if((long long)(rc[i]-ra[i])*(rd[i]-rb[i])<r[i]){\n                auto chk=[&](int j){return ra[i]<rc[j]&&rc[i]>ra[j]&&rb[i]<rd[j]&&rd[i]>rb[j];};\n                while(rc[i]<10000){int nc=rc[i]+1;bool ov=false;for(int j=0;j<n;j++){if(j==i)continue;if(ra[i]<rc[j]&&nc>ra[j]&&rb[i]<rd[j]&&rd[i]>rb[j]){ov=true;break;}}if(ov)break;long long na=(long long)(nc-ra[i])*(rd[i]-rb[i]);if(satisfaction(na,r[i])<=satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]),r[i]))break;rc[i]=nc;any=true;}\n                while(ra[i]>0&&ra[i]-1<=x[i]){int na2=ra[i]-1;bool ov=false;for(int j=0;j<n;j++){if(j==i)continue;if(na2<rc[j]&&rc[i]>ra[j]&&rb[i]<rd[j]&&rd[i]>rb[j]){ov=true;break;}}if(ov)break;long long na=(long long)(rc[i]-na2)*(rd[i]-rb[i]);if(satisfaction(na,r[i])<=satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]),r[i]))break;ra[i]=na2;any=true;}\n                while(rd[i]<10000){int nd=rd[i]+1;bool ov=false;for(int j=0;j<n;j++){if(j==i)continue;if(ra[i]<rc[j]&&rc[i]>ra[j]&&rb[i]<rd[j]&&nd>rb[j]){ov=true;break;}}if(ov)break;long long na=(long long)(rc[i]-ra[i])*(nd-rb[i]);if(satisfaction(na,r[i])<=satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]),r[i]))break;rd[i]=nd;any=true;}\n                while(rb[i]>0&&rb[i]-1<=y[i]){int nb=rb[i]-1;bool ov=false;for(int j=0;j<n;j++){if(j==i)continue;if(ra[i]<rc[j]&&rc[i]>ra[j]&&nb<rd[j]&&rd[i]>rb[j]){ov=true;break;}}if(ov)break;long long na=(long long)(rc[i]-ra[i])*(rd[i]-nb);if(satisfaction(na,r[i])<=satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]),r[i]))break;rb[i]=nb;any=true;}\n            }\n        }\n        if(!any)break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> n; x.resize(n); y.resize(n); r.resize(n); ra.resize(n); rb.resize(n); rc.resize(n); rd.resize(n);\n    for (int i=0;i<n;i++) cin >> x[i] >> y[i] >> r[i];\n    auto start = chrono::steady_clock::now();\n    vector<int> indices(n); iota(indices.begin(), indices.end(), 0);\n    vector<int> ba(n),bb(n),bc(n),bd(n); double bs=-1;\n    for (unsigned seed=0;;seed++) {\n        if (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now()-start).count()>4200) break;\n        tree.clear(); mt19937 rng(seed);\n        int root = build_tree(indices, rng);\n        post_process_offsets(root);\n        post_process_expand();\n        double s = compute_score();\n        if (s>bs) { bs=s; ba=ra; bb=rb; bc=rc; bd=rd; }\n    }\n    ra=ba; rb=bb; rc=bc; rd=bd;\n    for (int i=0;i<n;i++) cout << ra[i]<<\" \"<<rb[i]<<\" \"<<rc[i]<<\" \"<<rd[i]<<\"\\n\";\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 50;\nint si, sj;\nint t[N][N], p[N][N];\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir[] = {'U', 'D', 'L', 'R'};\nmt19937 rng(42);\n\nint tile_value[2500], max_tile_id = 0;\nstring best_path;\nlong long best_score;\n\nstring find_path(double temperature) {\n    bool square_visited[N][N] = {};\n    bool tile_visited[2500] = {};\n    string path;\n    int ci = si, cj = sj;\n    square_visited[ci][cj] = true;\n    tile_visited[t[ci][cj]] = true;\n    long long score = p[ci][cj];\n    \n    while (true) {\n        vector<pair<double, int>> candidates;\n        for (int d = 0; d < 4; d++) {\n            int ni = ci + di[d], nj = cj + dj[d];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (square_visited[ni][nj]) continue;\n            bool same_tile = (t[ni][nj] == t[ci][cj]);\n            if (same_tile || !tile_visited[t[ni][nj]]) {\n                double w = same_tile ? p[ni][nj] : tile_value[t[ni][nj]];\n                candidates.push_back({w, d});\n            }\n        }\n        if (candidates.empty()) break;\n        \n        double max_w = -1e18;\n        for (auto& [w, d] : candidates) max_w = max(max_w, w);\n        double total = 0;\n        for (auto& [w, d] : candidates) total += exp((w - max_w) / max(temperature, 0.01));\n        \n        double r = uniform_real_distribution<double>(0, total)(rng);\n        double cum = 0;\n        int chosen = candidates[0].second;\n        for (auto& [w, d] : candidates) {\n            cum += exp((w - max_w) / max(temperature, 0.01));\n            if (cum >= r) { chosen = d; break; }\n        }\n        \n        int ni = ci + di[chosen], nj = cj + dj[chosen];\n        square_visited[ni][nj] = true;\n        tile_visited[t[ni][nj]] = true;\n        score += p[ni][nj];\n        path += dir[chosen];\n        ci = ni; cj = nj;\n    }\n    \n    if (score > best_score) { best_score = score; best_path = path; }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> si >> sj;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) { cin >> t[i][j]; max_tile_id = max(max_tile_id, t[i][j]); }\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> p[i][j];\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) tile_value[t[i][j]] += p[i][j];\n    \n    best_score = 0;\n    auto start = chrono::high_resolution_clock::now();\n    int iter = 0;\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 1800) break;\n        double temperature = 10.0 * (1.0 - min(iter / 100000.0, 1.0)) + 0.1;\n        find_path(temperature);\n        iter++;\n    }\n    \n    cout << best_path << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\ndouble row_h[N], col_v[N], row_h_var[N], col_v_var[N];\ndouble h_dev[N][N-1], v_dev[N-1][N], h_dev_var[N][N-1], v_dev_var[N-1][N];\nmt19937 rng(42);\nnormal_distribution<double> norm_dist(0, 1);\n\ndouble get_h_est(int i, int j) { return row_h[i] + h_dev[i][j]; }\ndouble get_v_est(int i, int j) { return col_v[j] + v_dev[i][j]; }\n\npair<string,double> dijkstra_with_cost(int si, int sj, int ti, int tj, double temperature) {\n    double hw[N][N-1], vw[N-1][N];\n    for(int i=0; i<N; i++) {\n        for(int j=0; j<N-1; j++){\n            double rh = row_h[i] + temperature * sqrt(max(1.0, row_h_var[i])) * norm_dist(rng);\n            double hd = h_dev[i][j] + temperature * sqrt(max(1.0, h_dev_var[i][j])) * norm_dist(rng);\n            hw[i][j] = max(100.0, min(20000.0, rh + hd));\n        }\n    }\n    for(int i=0; i<N-1; i++) {\n        for(int j=0; j<N; j++){\n            double cv = col_v[j] + temperature * sqrt(max(1.0, col_v_var[j])) * norm_dist(rng);\n            double vd = v_dev[i][j] + temperature * sqrt(max(1.0, v_dev_var[i][j])) * norm_dist(rng);\n            vw[i][j] = max(100.0, min(20000.0, cv + vd));\n        }\n    }\n    \n    double dist[N][N];\n    pair<int,int> prev_node[N][N];\n    bool vis[N][N] = {};\n    for(int i=0; i<N; i++) for(int j=0; j<N; j++) dist[i][j] = 1e18;\n    dist[si][sj] = 0;\n    \n    priority_queue<tuple<double,int,int>, vector<tuple<double,int,int>>, greater<>> pq;\n    pq.push({0, si, sj});\n    \n    while(!pq.empty()){\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        if(vis[i][j]) continue;\n        vis[i][j] = true;\n        if(i==ti && j==tj) break;\n        \n        if(i > 0 && !vis[i-1][j]) {\n            double w = vw[i-1][j];\n            if(d + w < dist[i-1][j]) {\n                dist[i-1][j] = d + w;\n                prev_node[i-1][j] = {i, j};\n                pq.push({dist[i-1][j], i-1, j});\n            }\n        }\n        if(i < N-1 && !vis[i+1][j]) {\n            double w = vw[i][j];\n            if(d + w < dist[i+1][j]) {\n                dist[i+1][j] = d + w;\n                prev_node[i+1][j] = {i, j};\n                pq.push({dist[i+1][j], i+1, j});\n            }\n        }\n        if(j > 0 && !vis[i][j-1]) {\n            double w = hw[i][j-1];\n            if(d + w < dist[i][j-1]) {\n                dist[i][j-1] = d + w;\n                prev_node[i][j-1] = {i, j};\n                pq.push({dist[i][j-1], i, j-1});\n            }\n        }\n        if(j < N-1 && !vis[i][j+1]) {\n            double w = hw[i][j];\n            if(d + w < dist[i][j+1]) {\n                dist[i][j+1] = d + w;\n                prev_node[i][j+1] = {i, j};\n                pq.push({dist[i][j+1], i, j+1});\n            }\n        }\n    }\n    \n    string path;\n    double mean_cost = 0;\n    int ci = ti, cj = tj;\n    while(ci != si || cj != sj){\n        auto [pi, pj] = prev_node[ci][cj];\n        if(pi == ci-1) {\n            path += 'D';\n            mean_cost += get_v_est(ci-1, cj);\n        } else if(pi == ci+1) {\n            path += 'U';\n            mean_cost += get_v_est(ci, cj);\n        } else if(pj == cj-1) {\n            path += 'R';\n            mean_cost += get_h_est(ci, cj-1);\n        } else {\n            path += 'L';\n            mean_cost += get_h_est(ci, cj);\n        }\n        ci = pi;\n        cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return {path, mean_cost};\n}\n\nvoid update(int si, int sj, const string& path, int observed) {\n    struct E { char t; int i, j; };\n    vector<E> edges;\n    map<int,int> hr, vc;\n    int ci = si, cj = sj;\n    for(char c : path){\n        if(c == 'U') { edges.push_back({'v', ci-1, cj}); vc[cj]++; ci--; }\n        else if(c == 'D') { edges.push_back({'v', ci, cj}); vc[cj]++; ci++; }\n        else if(c == 'L') { edges.push_back({'h', ci, cj-1}); hr[ci]++; cj--; }\n        else { edges.push_back({'h', ci, cj}); hr[ci]++; cj++; }\n    }\n    double pred = 0;\n    for(auto& e : edges) {\n        pred += (e.t == 'h') ? get_h_est(e.i, e.j) : get_v_est(e.i, e.j);\n    }\n    double residual = observed - pred;\n    double obs_var = pred * pred / 300.0;\n    double S = obs_var;\n    for(auto& [i, n] : hr) S += n * n * row_h_var[i];\n    for(auto& [j, n] : vc) S += n * n * col_v_var[j];\n    for(auto& e : edges) S += (e.t == 'h') ? h_dev_var[e.i][e.j] : v_dev_var[e.i][e.j];\n    \n    for(auto& [i, n] : hr) {\n        double K = row_h_var[i] * n / S;\n        row_h[i] += K * residual;\n        row_h_var[i] *= (1 - K * n);\n        row_h[i] = max(500.0, min(15000.0, row_h[i]));\n        row_h_var[i] = max(100.0, row_h_var[i]);\n    }\n    for(auto& [j, n] : vc) {\n        double K = col_v_var[j] * n / S;\n        col_v[j] += K * residual;\n        col_v_var[j] *= (1 - K * n);\n        col_v[j] = max(500.0, min(15000.0, col_v[j]));\n        col_v_var[j] = max(100.0, col_v_var[j]);\n    }\n    for(auto& e : edges){\n        double& dev = (e.t == 'h') ? h_dev[e.i][e.j] : v_dev[e.i][e.j];\n        double& dv = (e.t == 'h') ? h_dev_var[e.i][e.j] : v_dev_var[e.i][e.j];\n        double K = dv / S;\n        dev += K * residual;\n        dv *= (1 - K);\n        dev = max(-5000.0, min(5000.0, dev));\n        dv = max(100.0, dv);\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for(int i=0; i<N; i++) {\n        row_h[i] = col_v[i] = 5000.0;\n        row_h_var[i] = col_v_var[i] = 5000000.0;\n    }\n    for(int i=0; i<N; i++) {\n        for(int j=0; j<N-1; j++) {\n            h_dev[i][j] = 0.0;\n            h_dev_var[i][j] = 2000000.0;\n        }\n    }\n    for(int i=0; i<N-1; i++) {\n        for(int j=0; j<N; j++) {\n            v_dev[i][j] = 0.0;\n            v_dev_var[i][j] = 2000000.0;\n        }\n    }\n    \n    for(int k=0; k<1000; k++){\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        double temperature = max(0.0, 1.0 - k / 300.0);\n        string best_path;\n        double best_cost = 1e18;\n        int trials = (temperature > 0.01) ? 5 : 1;\n        \n        for(int t=0; t<trials; t++){\n            auto [path, cost] = dijkstra_with_cost(si, sj, ti, tj, temperature);\n            if(cost < best_cost) {\n                best_cost = cost;\n                best_path = path;\n            }\n        }\n        \n        cout << best_path << endl;\n        int obs;\n        cin >> obs;\n        update(si, sj, best_path, obs);\n    }\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <array>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for (int m = 0; m < M; m++) cin >> s[m];\n    \n    const int NUM_CHARS = 8;\n    mt19937 rng(42);\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    vector<int> slen(M);\n    for (int m = 0; m < M; m++) slen[m] = s[m].length();\n    \n    // Fast EM phase using direct probability products\n    vector<array<double, 8>> charProb(N * N);\n    for (int i = 0; i < N * N; i++) for (int c = 0; c < NUM_CHARS; c++) charProb[i][c] = 1.0 / NUM_CHARS;\n    \n    for (int iter = 0; iter < 15; iter++) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration<double>(now - start_time).count() > 0.4) break;\n        \n        vector<array<double, 8>> newProb(N * N);\n        for (int i = 0; i < N * N; i++) newProb[i].fill(0);\n        \n        for (int m = 0; m < M; m++) {\n            int k = slen[m];\n            double maxW = 0;\n            vector<double> weights(2 * N * N);\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    double wH = 1.0, wV = 1.0;\n                    for (int p = 0; p < k; p++) {\n                        wH *= charProb[i * N + (j + p) % N][s[m][p] - 'A'];\n                        wV *= charProb[((i + p) % N) * N + j][s[m][p] - 'A'];\n                    }\n                    weights[2 * (i * N + j)] = wH;\n                    weights[2 * (i * N + j) + 1] = wV;\n                    if (wH > maxW) maxW = wH;\n                    if (wV > maxW) maxW = wV;\n                }\n            }\n            \n            if (maxW < 1e-300) continue;\n            double sumW = 0;\n            for (int pi = 0; pi < 2 * N * N; pi++) {\n                weights[pi] /= maxW;\n                sumW += weights[pi];\n            }\n            if (sumW < 1e-300) continue;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    double wH = weights[2 * (i * N + j)] / sumW;\n                    double wV = weights[2 * (i * N + j) + 1] / sumW;\n                    for (int p = 0; p < k; p++) {\n                        newProb[i * N + (j + p) % N][s[m][p] - 'A'] += wH;\n                        newProb[((i + p) % N) * N + j][s[m][p] - 'A'] += wV;\n                    }\n                }\n            }\n        }\n        \n        for (int i = 0; i < N * N; i++) {\n            double sum = 0;\n            for (int c = 0; c < NUM_CHARS; c++) sum += newProb[i][c];\n            if (sum > 0) {\n                for (int c = 0; c < NUM_CHARS; c++) newProb[i][c] = max(newProb[i][c] / sum, 1e-3);\n                double sum2 = 0;\n                for (int c = 0; c < NUM_CHARS; c++) sum2 += newProb[i][c];\n                for (int c = 0; c < NUM_CHARS; c++) newProb[i][c] /= sum2;\n            } else {\n                for (int c = 0; c < NUM_CHARS; c++) newProb[i][c] = 1.0 / NUM_CHARS;\n            }\n        }\n        charProb = move(newProb);\n    }\n    \n    vector<string> mat(N, string(N, 'A'));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            double maxP = 0; char best = 'A';\n            for (int c = 0; c < NUM_CHARS; c++) if (charProb[i * N + j][c] > maxP) { maxP = charProb[i * N + j][c]; best = 'A' + c; }\n            mat[i][j] = best;\n        }\n    \n    // Initial match counts\n    vector<vector<int8_t>> matchCount(M, vector<int8_t>(2 * N * N));\n    for (int m = 0; m < M; m++) {\n        int k = slen[m];\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int cH = 0, cV = 0;\n                for (int p = 0; p < k; p++) {\n                    if (mat[i][(j + p) % N] == s[m][p]) cH++;\n                    if (mat[(i + p) % N][j] == s[m][p]) cV++;\n                }\n                matchCount[m][2 * (i * N + j)] = cH;\n                matchCount[m][2 * (i * N + j) + 1] = cV;\n            }\n        }\n    }\n    \n    vector<int16_t> fullMatchCount(M, 0);\n    int totalMatched = 0;\n    for (int m = 0; m < M; m++) {\n        int k = slen[m];\n        for (int pi = 0; pi < 2 * N * N; pi++) if (matchCount[m][pi] == k) fullMatchCount[m]++;\n        if (fullMatchCount[m] > 0) totalMatched++;\n    }\n    \n    int bestMatched = totalMatched;\n    vector<string> bestMat = mat;\n    \n    // Lightning Fast SA Phase\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start_time).count();\n        if (elapsed > 2.8) break;\n        \n        double temp = 1.5 * (1.0 - elapsed / 3.0) + 0.1;\n        \n        int ci = rng() % N, cj = rng() % N;\n        char oldC = mat[ci][cj];\n        char newC;\n        if (rng() % 4 == 0 && totalMatched == M) {\n            newC = '.';\n        } else {\n            newC = 'A' + rng() % NUM_CHARS;\n        }\n        if (newC == oldC) continue;\n        \n        int deltaDots = (newC == '.' && oldC != '.') ? 1 : ((newC != '.' && oldC == '.') ? -1 : 0);\n        \n        int deltaMatched = 0;\n        for (int m = 0; m < M; m++) {\n            int k = slen[m];\n            int oldFMC = fullMatchCount[m];\n            const char* sm = s[m].c_str();\n            int baseH = 2 * ci * N;\n            int baseV = 2 * cj + 1;\n            for (int p = 0; p < k; p++) {\n                int delta = (newC == sm[p]) - (oldC == sm[p]);\n                if (delta) {\n                    int sj = cj - p; if (sj < 0) sj += N;\n                    int piH = baseH + 2 * sj;\n                    int oldV = matchCount[m][piH];\n                    int newV = oldV + delta;\n                    matchCount[m][piH] = newV;\n                    if (oldV == k) fullMatchCount[m]--;\n                    else if (newV == k) fullMatchCount[m]++;\n\n                    int si = ci - p; if (si < 0) si += N;\n                    int piV = 2 * si * N + baseV;\n                    oldV = matchCount[m][piV];\n                    newV = oldV + delta;\n                    matchCount[m][piV] = newV;\n                    if (oldV == k) fullMatchCount[m]--;\n                    else if (newV == k) fullMatchCount[m]++;\n                }\n            }\n            if (oldFMC == 0 && fullMatchCount[m] > 0) deltaMatched++;\n            else if (oldFMC > 0 && fullMatchCount[m] == 0) deltaMatched--;\n        }\n        \n        bool accept = false;\n        if (deltaMatched > 0) accept = true;\n        else if (deltaMatched == 0) {\n            if (deltaDots > 0) accept = true;\n            else if (deltaDots == 0) accept = (rng() % 2 == 0);\n            else accept = (rng() % 10000 < (int)(exp(-1.0 / temp) * 10000));\n        } else {\n            accept = (rng() % 10000 < (int)(exp((double)deltaMatched / temp) * 10000));\n        }\n        \n        if (accept) {\n            mat[ci][cj] = newC;\n            totalMatched += deltaMatched;\n            if (totalMatched > bestMatched) {\n                bestMatched = totalMatched;\n                bestMat = mat;\n            }\n        } else {\n            // Symmetric Revert\n            for (int m = 0; m < M; m++) {\n                int k = slen[m];\n                const char* sm = s[m].c_str();\n                int baseH = 2 * ci * N;\n                int baseV = 2 * cj + 1;\n                for (int p = 0; p < k; p++) {\n                    int delta = (newC == sm[p]) - (oldC == sm[p]);\n                    if (delta) {\n                        int sj = cj - p; if (sj < 0) sj += N;\n                        int piH = baseH + 2 * sj;\n                        int curV = matchCount[m][piH];\n                        matchCount[m][piH] = curV - delta;\n                        if (curV - delta == k) fullMatchCount[m]++;\n                        else if (curV == k) fullMatchCount[m]--;\n\n                        int si = ci - p; if (si < 0) si += N;\n                        int piV = 2 * si * N + baseV;\n                        curV = matchCount[m][piV];\n                        matchCount[m][piV] = curV - delta;\n                        if (curV - delta == k) fullMatchCount[m]++;\n                        else if (curV == k) fullMatchCount[m]--;\n                    }\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) cout << bestMat[i] << '\\n';\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\nvector<vector<vector<pair<int,int>>>> vis_from;\nint total_roads;\nbitset<4800> road_mask;\n\nbool is_road(int i, int j) { return i>=0&&i<N&&j>=0&&j<N&&grid[i][j]!='#'; }\nint cell_cost(int i, int j) { return grid[i][j]-'0'; }\n\nconst int di[]={-1,1,0,0}, dj[]={0,0,-1,1};\nconst char dc[]={'U','D','L','R'};\n\nint char_to_idx(char c) {\n    if(c=='U') return 0;\n    if(c=='D') return 1;\n    if(c=='L') return 2;\n    return 3;\n}\n\nvoid precompute_visibility() {\n    vis_from.assign(N, vector<vector<pair<int,int>>>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) {\n        if(!is_road(i,j)) continue;\n        road_mask[i*N+j] = 1;\n        vis_from[i][j].push_back({i,j});\n        for(int jj=j-1;jj>=0&&is_road(i,jj);jj--) vis_from[i][j].push_back({i,jj});\n        for(int jj=j+1;jj<N&&is_road(i,jj);jj++) vis_from[i][j].push_back({i,jj});\n        for(int ii=i-1;ii>=0&&is_road(ii,j);ii--) vis_from[i][j].push_back({ii,j});\n        for(int ii=i+1;ii<N&&is_road(ii,j);ii++) vis_from[i][j].push_back({ii,j});\n    }\n}\n\npair<vector<vector<int>>, vector<vector<int>>> dijkstra(int si, int sj) {\n    vector<vector<int>> dist(N, vector<int>(N, INT_MAX)), prev(N, vector<int>(N, -1));\n    priority_queue<pair<int,pair<int,int>>, vector<pair<int,pair<int,int>>>, greater<>> pq;\n    dist[si][sj] = 0; pq.push({0, {si, sj}});\n    while(!pq.empty()) {\n        auto [d, p] = pq.top(); pq.pop();\n        auto [i, j] = p;\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(is_road(ni, nj)) {\n                int nd = d + cell_cost(ni, nj);\n                if(nd < dist[ni][nj]) { dist[ni][nj] = nd; prev[ni][nj] = k; pq.push({nd, {ni, nj}}); }\n            }\n        }\n    }\n    return {dist, prev};\n}\n\nstring reconstruct(int si, int sj, int ti, int tj, const vector<vector<int>>& prev) {\n    if(si==ti && sj==tj) return \"\";\n    string path; int ci=ti, cj=tj;\n    while(ci!=si || cj!=sj) { int k=prev[ci][cj]; if(k==-1) return \"\"; path+=dc[k]; ci-=di[k]; cj-=dj[k]; }\n    reverse(path.begin(), path.end()); return path;\n}\n\nvector<pair<int,int>> build_greedy(double alpha) {\n    vector<vector<bool>> covered(N, vector<bool>(N, false));\n    auto mark = [&](int i, int j)->int {\n        int c=0; for(auto& [vi, vj] : vis_from[i][j]) if(!covered[vi][vj]){covered[vi][vj]=true;c++;} return c;\n    };\n    vector<pair<int,int>> targets;\n    int ci = si, cj = sj, cc = mark(ci, cj);\n    \n    while(cc < total_roads) {\n        auto [dist, prev] = dijkstra(ci, cj);\n        vector<vector<vector<pair<int,int>>>> children(N, vector<vector<pair<int,int>>>(N));\n        for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) {\n            if(prev[i][j] != -1) {\n                int pi = i - di[prev[i][j]], pj = j - dj[prev[i][j]];\n                children[pi][pj].push_back({i, j});\n            }\n        }\n        \n        vector<double> scores(N*N, -1.0);\n        int current_nv = 0;\n        vector<pair<int,int>> changes;\n        vector<vector<bool>> tmp = covered;\n        \n        function<void(int, int)> dfs = [&](int ui, int uj) {\n            int sz = changes.size();\n            for(auto& [vi, vj] : vis_from[ui][uj]) {\n                if(!tmp[vi][vj]) { tmp[vi][vj] = true; changes.push_back({vi, vj}); current_nv++; }\n            }\n            if(current_nv > 0 && dist[ui][uj] > 0) scores[ui*N+uj] = pow((double)current_nv, alpha) / (double)dist[ui][uj];\n            for(auto& [vi, vj] : children[ui][uj]) dfs(vi, vj);\n            while(changes.size() > sz) { auto [vi, vj] = changes.back(); tmp[vi][vj] = false; changes.pop_back(); current_nv--; }\n        };\n        dfs(ci, cj);\n        \n        int best_idx = -1; double best_score = -1e18;\n        for(int i=0; i<N*N; ++i) if(scores[i] > best_score) { best_score = scores[i]; best_idx = i; }\n        if(best_idx == -1) break;\n        \n        int bi = best_idx / N, bj = best_idx % N;\n        targets.push_back({bi, bj});\n        string path = reconstruct(ci, cj, bi, bj, prev);\n        for(char c : path) { int k = char_to_idx(c); ci += di[k]; cj += dj[k]; cc += mark(ci, cj); }\n    }\n    return targets;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> si >> sj; grid.resize(N); for(int i=0;i<N;i++) cin >> grid[i];\n    precompute_visibility();\n    total_roads = road_mask.count();\n    auto st = chrono::high_resolution_clock::now();\n    \n    set<pair<int,int>> pool_set;\n    pool_set.insert({si, sj});\n    vector<double> alphas = {0.5, 1.0, 1.5, 2.5};\n    for(double alpha : alphas) { auto targets = build_greedy(alpha); for(auto& t : targets) pool_set.insert(t); }\n    \n    mt19937 rng(1337);\n    vector<pair<int,int>> roads;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(is_road(i,j)) roads.push_back({i,j});\n    for(int i=0; i<50; ++i) pool_set.insert(roads[rng() % roads.size()]);\n    \n    vector<pair<int,int>> T(pool_set.begin(), pool_set.end());\n    int M = T.size(), S = -1;\n    for(int i=0; i<M; ++i) if(T[i].first == si && T[i].second == sj) S = i;\n    \n    vector<vector<int>> d(M, vector<int>(M, INT_MAX));\n    vector<vector<bitset<4800>>> path_vis(M, vector<bitset<4800>>(M));\n    vector<vector<vector<int>>> all_prev(M, vector<vector<int>>(N, vector<int>(N, -1)));\n    \n    for(int u=0; u<M; ++u) {\n        auto [dist, prev] = dijkstra(T[u].first, T[u].second);\n        all_prev[u] = prev;\n        for(int v=0; v<M; ++v) {\n            d[u][v] = dist[T[v].first][T[v].second];\n            bitset<4800> bs;\n            for(auto& [vi, vj] : vis_from[T[u].first][T[u].second]) bs[vi*N+vj] = 1;\n            int ci = T[v].first, cj = T[v].second;\n            while(ci != T[u].first || cj != T[u].second) {\n                for(auto& [vi, vj] : vis_from[ci][cj]) bs[vi*N+vj] = 1;\n                int k = prev[ci][cj]; ci -= di[k]; cj -= dj[k];\n            }\n            path_vis[u][v] = bs;\n        }\n    }\n    \n    auto evaluate_seq = [&](const vector<int>& seq) -> pair<bool, int> {\n        if(seq.empty()) { bitset<4800> vis = path_vis[S][S]; return {(vis & road_mask).count() == total_roads, 0}; }\n        int cost = d[S][seq[0]] + d[seq.back()][S];\n        bitset<4800> vis = path_vis[S][seq[0]] | path_vis[seq.back()][S];\n        for(int i=0; i+1<(int)seq.size(); ++i) { cost += d[seq[i]][seq[i+1]]; vis |= path_vis[seq[i]][seq[i+1]]; }\n        return {(vis & road_mask).count() == total_roads, cost};\n    };\n    \n    vector<int> best_greedy_seq; int best_greedy_cost = INT_MAX;\n    for(double alpha : alphas) {\n        auto targets = build_greedy(alpha);\n        vector<int> seq; for(auto& t : targets) for(int i=0; i<M; ++i) if(T[i] == t) { seq.push_back(i); break; }\n        auto [valid, cost] = evaluate_seq(seq);\n        if(valid && cost < best_greedy_cost) { best_greedy_cost = cost; best_greedy_seq = seq; }\n    }\n    \n    vector<int> cur_seq = best_greedy_seq, best_seq = best_greedy_seq;\n    int cur_cost = best_greedy_cost, best_cost = best_greedy_cost;\n    if(cur_seq.empty() || !evaluate_seq(cur_seq).first) { cur_seq.clear(); for(int i=0; i<20; ++i) cur_seq.push_back(rng() % M); auto [v, c] = evaluate_seq(cur_seq); cur_cost = v ? c : INT_MAX; }\n    \n    double T_sa = 1000.0;\n    mt19937 rng_sa(12345);\n    uniform_real_distribution<double> dist01(0.0, 1.0);\n    \n    while(true) {\n        auto now = chrono::high_resolution_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now - st).count() > 2800) break;\n        vector<int> new_seq = cur_seq;\n        int op = rng_sa() % 5;\n        if(op == 0 && new_seq.size() >= 2) { int l = rng_sa() % new_seq.size(), r = rng_sa() % new_seq.size(); if(l > r) swap(l, r); reverse(new_seq.begin() + l, new_seq.begin() + r + 1); }\n        else if(op == 1 && new_seq.size() >= 2) { int i = rng_sa() % new_seq.size(), j = rng_sa() % new_seq.size(); swap(new_seq[i], new_seq[j]); }\n        else if(op == 2 && new_seq.size() > 1) { int i = rng_sa() % new_seq.size(); new_seq.erase(new_seq.begin() + i); }\n        else if(op == 3) { int x = rng_sa() % M, i = rng_sa() % (new_seq.size() + 1); new_seq.insert(new_seq.begin() + i, x); }\n        else if(op == 4 && new_seq.size() > 0) { int i = rng_sa() % new_seq.size(), x = rng_sa() % M; new_seq[i] = x; }\n        \n        auto [valid, new_cost] = evaluate_seq(new_seq);\n        if(valid) {\n            double delta = new_cost - cur_cost;\n            if(delta < 0 || dist01(rng_sa) < exp(-delta / T_sa)) { cur_seq = new_seq; cur_cost = new_cost; if(new_cost < best_cost) { best_cost = new_cost; best_seq = new_seq; } }\n        }\n        T_sa *= 0.9999;\n    }\n    \n    string final_route;\n    if(!best_seq.empty()) {\n        int ci = si, cj = sj;\n        for(int idx=0; idx<(int)best_seq.size(); ++idx) {\n            int u = (idx == 0) ? S : best_seq[idx-1], v = best_seq[idx];\n            final_route += reconstruct(T[u].first, T[u].second, T[v].first, T[v].second, all_prev[u]);\n        }\n        final_route += reconstruct(T[best_seq.back()].first, T[best_seq.back()].second, si, sj, all_prev[best_seq.back()]);\n    }\n    cout << final_route << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> d, deps, rev_deps;\nvector<vector<double>> skill_est;\nvector<double> crit_path;\nvector<int> task_start, task_done;\nvector<vector<pair<int,int>>> member_obs;\n\nvector<int> hungarian(const vector<vector<double>>& cost) {\n    int n = cost.size(), m = cost[0].size();\n    const double INF = 1e18;\n    vector<double> u(n+1,0), v(m+1,0);\n    vector<int> p(m+1,0), way(m+1,0);\n    for (int i = 1; i <= n; i++) {\n        p[0] = i; int j0 = 0;\n        vector<double> minv(m+1, INF);\n        vector<bool> used(m+1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], j1 = 0;\n            double delta = INF;\n            for (int j = 1; j <= m; j++) if (!used[j]) {\n                double cur = cost[i0-1][j-1] - u[i0] - v[j];\n                if (cur < minv[j]) { minv[j] = cur; way[j] = j0; }\n                if (minv[j] < delta) { delta = minv[j]; j1 = j; }\n            }\n            for (int j = 0; j <= m; j++) {\n                if (used[j]) { u[p[j]] += delta; v[j] -= delta; }\n                else minv[j] -= delta;\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do { int j1 = way[j0]; p[j0] = p[j1]; j0 = j1; } while (j0);\n    }\n    vector<int> asgn(n, -1);\n    for (int j = 1; j <= m; j++) if (p[j] > 0 && p[j] <= n) asgn[p[j]-1] = j-1;\n    return asgn;\n}\n\nvoid recompute_crit_path() {\n    vector<double> et(N);\n    for (int i = 0; i < N; ++i) {\n        if (task_done[i] != -1) { et[i] = 0; continue; }\n        if (task_start[i] != -1) { et[i] = 0.1; continue; } // Already started, will finish soon\n        double min_w = 1e9;\n        for (int j = 0; j < M; ++j) {\n            double w = 0;\n            for (int k = 0; k < K; ++k) w += max(0.0, (double)d[i][k] - skill_est[j][k]);\n            min_w = min(min_w, w);\n        }\n        et[i] = max(1.0, min_w);\n    }\n    for (int i = N - 1; i >= 0; i--) {\n        crit_path[i] = et[i];\n        for (int v : rev_deps[i]) crit_path[i] = max(crit_path[i], et[i] + crit_path[v]);\n    }\n}\n\nvoid reestimate(int j) {\n    auto& ob = member_obs[j];\n    if (ob.empty()) return;\n    for (int iter = 0; iter < 30; ++iter) {\n        for (auto& [task, t] : ob) {\n            double w_pred = 0;\n            for (int k = 0; k < K; ++k) w_pred += max(0.0, (double)d[task][k] - skill_est[j][k]);\n            \n            if (t == 1) {\n                if (w_pred > 0) {\n                    for (int k = 0; k < K; ++k) {\n                        if (d[task][k] > skill_est[j][k]) {\n                            skill_est[j][k] += 0.3 * (d[task][k] - skill_est[j][k]);\n                        }\n                    }\n                }\n            } else {\n                double target_w = t;\n                double diff = w_pred - target_w;\n                if (abs(diff) < 0.5) continue;\n                \n                if (w_pred > 0) {\n                    for (int k = 0; k < K; ++k) {\n                        if (d[task][k] > skill_est[j][k]) {\n                            skill_est[j][k] += 0.3 * diff * (d[task][k] - skill_est[j][k]) / w_pred;\n                        }\n                    }\n                } else { \n                    double sum_d = 0;\n                    for (int k = 0; k < K; ++k) sum_d += d[task][k];\n                    if (sum_d > 0) {\n                        for (int k = 0; k < K; ++k) {\n                            skill_est[j][k] += 0.3 * diff * d[task][k] / sum_d;\n                        }\n                    }\n                }\n            }\n        }\n        for (auto& [task, t] : ob) {\n            if (t == 1) {\n                for (int k = 0; k < K; ++k) {\n                    skill_est[j][k] = max(skill_est[j][k], (double)d[task][k]);\n                }\n            }\n        }\n        for (int k = 0; k < K; ++k) skill_est[j][k] = max(0.0, skill_est[j][k]);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> K >> R;\n    d.resize(N, vector<int>(K)); deps.resize(N); rev_deps.resize(N);\n    for (int i = 0; i < N; i++) for (int k = 0; k < K; k++) cin >> d[i][k];\n    for (int r = 0; r < R; r++) { int u, v; cin >> u >> v; u--; v--; deps[v].push_back(u); rev_deps[u].push_back(v); }\n    \n    crit_path.resize(N, 0); task_start.resize(N, -1); task_done.resize(N, -1);\n    skill_est.resize(M, vector<double>(K)); member_obs.resize(M);\n    \n    for (int k = 0; k < K; k++) {\n        vector<int> dk(N); for (int i = 0; i < N; i++) dk[i] = d[i][k];\n        sort(dk.begin(), dk.end());\n        double init = dk[N/2] * 1.5;\n        for (int j = 0; j < M; j++) skill_est[j][k] = init;\n    }\n    \n    vector<int> member_task(M, -1), member_start_day(M, -1);\n    set<int> available_tasks; vector<int> deps_rem(N);\n    for (int i = 0; i < N; i++) { deps_rem[i] = deps[i].size(); if (!deps_rem[i]) available_tasks.insert(i); }\n    \n    int current_day = 0;\n    while (true) {\n        current_day++;\n        recompute_crit_path();\n        \n        vector<int> free_members;\n        for (int j = 0; j < M; j++) if (member_task[j] == -1) free_members.push_back(j);\n        int fm = free_members.size();\n        \n        if (fm > 0 && !available_tasks.empty()) {\n            vector<int> av(available_tasks.begin(), available_tasks.end());\n            sort(av.begin(), av.end(), [&](int a, int b){ return crit_path[a] > crit_path[b]; });\n            \n            int nr = min((int)av.size(), fm * 5);\n            int na = max(nr, fm);\n            vector<vector<double>> cost(fm, vector<double>(na, 1e9));\n            for (int mi = 0; mi < fm; mi++) { \n                int j = free_members[mi];\n                for (int ti = 0; ti < nr; ti++) { \n                    int i = av[ti];\n                    double w = 0; for (int k = 0; k < K; k++) w += max(0.0, (double)d[i][k]-skill_est[j][k]);\n                    cost[mi][ti] = max(1.0, w);\n                }\n            }\n            auto asgn = hungarian(cost);\n            vector<pair<int,int>> assigns;\n            for (int mi = 0; mi < fm; mi++) { \n                int ti = asgn[mi];\n                if (ti >= 0 && ti < nr) assigns.push_back({free_members[mi], av[ti]});\n            }\n            \n            cout << assigns.size();\n            for (auto [j,i] : assigns) {\n                cout << \" \" << (j+1) << \" \" << (i+1);\n                member_task[j]=i; member_start_day[j]=current_day; task_start[i]=current_day;\n                available_tasks.erase(i);\n            }\n            cout << endl;\n        } else cout << 0 << endl;\n        \n        int n; cin >> n; if (n == -1) break;\n        for (int idx = 0; idx < n; idx++) {\n            int j; cin >> j; j--;\n            int i = member_task[j], tt = current_day - member_start_day[j] + 1;\n            task_done[i] = current_day;\n            member_obs[j].push_back({i, tt});\n            reestimate(j);\n            member_task[j] = -1;\n            for (int v : rev_deps[i]) { \n                deps_rem[v]--; \n                if (deps_rem[v] == 0 && task_start[v] == -1 && task_done[v] == -1) available_tasks.insert(v); \n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <climits>\n#include <cstring>\n#include <utility>\n\nusing namespace std;\n\nconst int N = 1000, M = 50, CX = 400, CY = 400;\nint a[N], b[N], c[N], d[N];\n\ninline int dist(int x1, int y1, int x2, int y2) { return abs(x1-x2) + abs(y1-y2); }\n\nstruct Xor128 {\n    unsigned x = 123456789, y = 362436069, z = 521288629, w = 88675123;\n    unsigned next() {\n        unsigned t = x ^ (x << 11);\n        x = y; y = z; z = w;\n        return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));\n    }\n    double nextDouble() {\n        return next() / 4294967295.0;\n    }\n    int nextInt(int n) {\n        return next() % n;\n    }\n};\n\nXor128 rng;\n\nint route[100];\nint bestRouteArr[100];\nint orders[M];\nint bestOrders[M];\nbool isSelected[N];\n\nint calcCost() {\n    int cost = 0, x = CX, y = CY;\n    for (int i = 0; i < 2 * M; i++) {\n        int ord = orders[route[i] / 2]; \n        bool isD = route[i] % 2;\n        int nx = isD ? c[ord] : a[ord], ny = isD ? d[ord] : b[ord];\n        cost += dist(x, y, nx, ny); \n        x = nx; y = ny;\n    }\n    return cost + dist(x, y, CX, CY);\n}\n\nbool isValidForInsert(int ip) {\n    int k = route[ip] / 2;\n    bool isD = route[ip] % 2;\n    if (!isD) { // It's a restaurant\n        for (int i = ip + 1; i < 2 * M; i++) {\n            if (route[i] == k * 2 + 1) return true;\n        }\n        return false;\n    } else { // It's a delivery\n        for (int i = 0; i < ip; i++) {\n            if (route[i] == k * 2) return true;\n        }\n        return false;\n    }\n}\n\nvoid constructRoute() {\n    bool vR[M], vD[M];\n    memset(vR, 0, sizeof vR);\n    memset(vD, 0, sizeof vD);\n    int cx = CX, cy = CY;\n    for (int step = 0; step < 2 * M; step++) {\n        int best = -1, bestD = INT_MAX;\n        for (int i = 0; i < M; i++) {\n            if (!vR[i]) { \n                int d2 = dist(cx, cy, a[orders[i]], b[orders[i]]); \n                if (d2 < bestD) { bestD = d2; best = i * 2; } \n            }\n            if (vR[i] && !vD[i]) { \n                int d2 = dist(cx, cy, c[orders[i]], d[orders[i]]); \n                if (d2 < bestD) { bestD = d2; best = i * 2 + 1; } \n            }\n        }\n        route[step] = best;\n        if (best % 2 == 0) { vR[best / 2] = true; cx = a[orders[best / 2]]; cy = b[orders[best / 2]]; }\n        else { vD[best / 2] = true; cx = c[orders[best / 2]]; cy = d[orders[best / 2]]; }\n    }\n}\n\npair<int, int> getCoord(int idx) {\n    if (idx < 0 || idx >= 2 * M) return {CX, CY};\n    int ord = orders[route[idx] / 2];\n    bool isD = route[idx] % 2;\n    if (isD) return {c[ord], d[ord]};\n    else return {a[ord], b[ord]};\n}\n\nint distByIdx(int i, int j) {\n    auto [x1, y1] = getCoord(i);\n    auto [x2, y2] = getCoord(j);\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    for (int i = 0; i < N; i++) cin >> a[i] >> b[i] >> c[i] >> d[i];\n    \n    auto startTime = chrono::high_resolution_clock::now();\n    \n    vector<pair<int,int>> scores;\n    for (int i = 0; i < N; i++) {\n        int cost = dist(CX, CY, a[i], b[i]) + dist(a[i], b[i], c[i], d[i]) + dist(c[i], d[i], CX, CY);\n        scores.push_back({cost, i});\n    }\n    sort(scores.begin(), scores.end());\n    \n    for (int i = 0; i < M; i++) { orders[i] = scores[i].second; isSelected[orders[i]] = true; }\n    \n    constructRoute();\n    int curCost = calcCost(), bestCost = curCost;\n    memcpy(bestRouteArr, route, sizeof(route));\n    memcpy(bestOrders, orders, sizeof(orders));\n    \n    double temp = 100.0, cooling = 0.99999;\n    int iter = 0;\n    \n    while (true) {\n        if (iter % 1000 == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            if (chrono::duration<double>(now - startTime).count() > 1.8) break;\n        }\n        iter++;\n        \n        int mt = rng.nextInt(10);\n        if (mt < 5) {\n            int from = rng.nextInt(2 * M), to = rng.nextInt(2 * M);\n            if (from == to) continue;\n            \n            int savedRoute[100];\n            memcpy(savedRoute, route, sizeof(route));\n            \n            int val = route[from];\n            for (int i = from; i < 2 * M - 1; i++) route[i] = route[i + 1];\n            int ip = to > from ? to - 1 : to;\n            for (int i = 2 * M - 1; i > ip; i--) route[i] = route[i - 1];\n            route[ip] = val;\n            \n            if (isValidForInsert(ip)) {\n                int nc = calcCost(); double d = nc - curCost;\n                if (d < 0 || rng.nextDouble() < exp(-d / temp)) { \n                    curCost = nc; \n                    if (nc < bestCost) { \n                        bestCost = nc; \n                        memcpy(bestRouteArr, route, sizeof(route));\n                        memcpy(bestOrders, orders, sizeof(orders));\n                    } \n                } else {\n                    memcpy(route, savedRoute, sizeof(route));\n                }\n            } else {\n                memcpy(route, savedRoute, sizeof(route));\n            }\n        } else if (mt < 8) {\n            int ii = rng.nextInt(M), oi = rng.nextInt(N);\n            if (isSelected[oi]) continue;\n            \n            int savedOrders[50];\n            memcpy(savedOrders, orders, sizeof(orders));\n            int savedRoute[100];\n            memcpy(savedRoute, route, sizeof(route));\n            \n            int oo = orders[ii]; \n            orders[ii] = oi; \n            isSelected[oo] = false; \n            isSelected[oi] = true;\n            \n            constructRoute(); \n            int nc = calcCost(); \n            double d = nc - curCost;\n            if (d < 0 || rng.nextDouble() < exp(-d / temp)) { \n                curCost = nc; \n                if (nc < bestCost) { \n                    bestCost = nc; \n                    memcpy(bestRouteArr, route, sizeof(route));\n                    memcpy(bestOrders, orders, sizeof(orders));\n                } \n            } else { \n                memcpy(orders, savedOrders, sizeof(orders));\n                isSelected[oi] = false; \n                isSelected[oo] = true; \n                memcpy(route, savedRoute, sizeof(route));\n            }\n        } else {\n            int l = rng.nextInt(2 * M - 1), r = l + 1 + rng.nextInt(2 * M - 1 - l);\n            bool valid = true;\n            bool inSegment[50] = {false};\n            for (int i = l; i <= r; i++) {\n                int k = route[i] / 2;\n                if (inSegment[k]) { valid = false; break; }\n                inSegment[k] = true;\n            }\n            if (valid) {\n                int delta = distByIdx(l - 1, r) + distByIdx(l, r + 1) - distByIdx(l - 1, l) - distByIdx(r, r + 1);\n                int nc = curCost + delta;\n                double d = nc - curCost;\n                if (d < 0 || rng.nextDouble() < exp(-d / temp)) { \n                    reverse(route + l, route + r + 1);\n                    curCost = nc; \n                    if (nc < bestCost) { \n                        bestCost = nc; \n                        memcpy(bestRouteArr, route, sizeof(route));\n                        memcpy(bestOrders, orders, sizeof(orders));\n                    } \n                }\n            }\n        }\n        temp *= cooling;\n    }\n    \n    cout << M;\n    for(int i = 0; i < M; i++) cout << \" \" << bestOrders[i] + 1;\n    cout << endl;\n    cout << 2 * M + 2 << \" \" << CX << \" \" << CY;\n    for(int i = 0; i < 2 * M; i++) {\n        int ord = bestOrders[bestRouteArr[i] / 2]; bool isD = bestRouteArr[i] % 2;\n        cout << \" \" << (isD ? c[ord] : a[ord]) << \" \" << (isD ? d[ord] : b[ord]);\n    }\n    cout << \" \" << CX << \" \" << CY << endl;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, rank_;\n    int components;\n    \n    UnionFind(int n) : parent(n), rank_(n, 0), components(n) {\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 (rank_[px] < rank_[py]) swap(px, py);\n        parent[py] = px;\n        if (rank_[px] == rank_[py]) rank_[px]++;\n        components--;\n        return true;\n    }\n    \n    bool connected(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, M = 1995;\n    vector<int> x(N), y(N);\n    vector<int> u(M), v(M);\n    vector<int> d(M);\n    \n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        double dist = sqrt((double)(x[u[i]] - x[v[i]]) * (x[u[i]] - x[v[i]]) + \n                           (double)(y[u[i]] - y[v[i]]) * (y[u[i]] - y[v[i]]));\n        d[i] = max(1, (int)round(dist));\n    }\n    \n    // Compute reference MST using d_i\n    vector<int> order(M);\n    for (int i = 0; i < M; i++) order[i] = i;\n    sort(order.begin(), order.end(), [&](int a, int b) { return d[a] < d[b]; });\n    \n    UnionFind refUF(N);\n    vector<bool> inRefMST(M, false);\n    for (int idx : order) {\n        if (refUF.unite(u[idx], v[idx])) {\n            inRefMST[idx] = true;\n        }\n    }\n    \n    // Process edges online\n    UnionFind uf(N);\n    \n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        int adopt = 0;\n        \n        if (!uf.connected(u[i], v[i])) {\n            if (inRefMST[i]) {\n                // Always accept reference MST edges - guarantees connectivity\n                adopt = 1;\n                uf.unite(u[i], v[i]);\n            } else {\n                // Accept non-MST edges only if they're cheap enough\n                // to potentially replace expensive MST edges\n                double percentile = (double)(l - d[i]) / (2.0 * d[i]);\n                percentile = max(0.0, min(1.0, percentile));\n                \n                int remaining = M - i - 1;\n                int needed = uf.components - 1;\n                double safety = (needed > 0) ? (double)remaining / needed : 999.0;\n                \n                double threshold;\n                if (safety >= 5) threshold = 0.3;\n                else if (safety >= 3) threshold = 0.4;\n                else if (safety >= 2) threshold = 0.5;\n                else threshold = 0.65;\n                \n                if (percentile <= threshold) {\n                    adopt = 1;\n                    uf.unite(u[i], v[i]);\n                }\n            }\n        }\n        \n        cout << adopt << endl;\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <cstring>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\n\nint N, M;\nvector<int> px, py, pt;\nvector<int> hx, hy;\nbool wall[SIZE][SIZE];\n\nbool inBounds(int x, int y) { return x >= 0 && x < SIZE && y >= 0 && y < SIZE; }\n\nvoid bfs(int sx, int sy, int dist[SIZE][SIZE]) {\n    memset(dist, -1, sizeof(int) * SIZE * SIZE);\n    if (!inBounds(sx, sy) || wall[sx][sy]) return;\n    queue<pair<int,int>> q;\n    dist[sx][sy] = 0;\n    q.push({sx, sy});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (inBounds(nx, ny) && !wall[nx][ny] && dist[nx][ny] == -1) {\n                dist[nx][ny] = dist[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n}\n\ndouble petThreatWeight(int t) {\n    switch(t) { case 1: return 1.0; case 2: return 1.5; case 3: return 2.0; case 4: return 2.5; case 5: return 2.0; default: return 1.0; }\n}\n\ndouble computeScoreWithDist(int dist[SIZE][SIZE]) {\n    int area = 0;\n    double effectivePets = 0;\n    for (int i = 0; i < SIZE; i++)\n        for (int j = 0; j < SIZE; j++)\n            if (dist[i][j] >= 0) area++;\n    for (int i = 0; i < N; i++)\n        if (dist[px[i]][py[i]] >= 0) effectivePets += 1.0;\n\n    int boundaryDist[SIZE][SIZE];\n    memset(boundaryDist, -1, sizeof(int) * SIZE * SIZE);\n    queue<pair<int,int>> q;\n    for (int x = 0; x < SIZE; x++)\n        for (int y = 0; y < SIZE; y++)\n            if (dist[x][y] < 0 && !wall[x][y]) {\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (inBounds(nx, ny) && dist[nx][ny] >= 0) {\n                        if (boundaryDist[x][y] == -1) { boundaryDist[x][y] = 1; q.push({x, y}); }\n                        break;\n                    }\n                }\n            }\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (inBounds(nx, ny) && !wall[nx][ny] && boundaryDist[nx][ny] == -1 && dist[nx][ny] < 0) {\n                boundaryDist[nx][ny] = boundaryDist[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        if (dist[px[i]][py[i]] >= 0) continue;\n        int d = boundaryDist[px[i]][py[i]];\n        if (d >= 1 && d <= 10) effectivePets += petThreatWeight(pt[i]) * 0.2 * exp(-0.2 * d);\n    }\n    return (double)area / 900.0 * pow(2.0, -effectivePets);\n}\n\nbool petAdjacentTo(int x, int y, const vector<int>& ppx, const vector<int>& ppy) {\n    for (int i = 0; i < N; i++) {\n        if (ppx[i] == x && ppy[i] == y) return true;\n        for (int d = 0; d < 4; d++)\n            if (ppx[i] == x + dx[d] && ppy[i] == y + dy[d]) return true;\n    }\n    return false;\n}\n\nbool humanAt(int x, int y, const vector<int>& hhx, const vector<int>& hhy) {\n    for (int i = 0; i < M; i++) if (hhx[i] == x && hhy[i] == y) return true;\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N;\n    px.resize(N); py.resize(N); pt.resize(N);\n    for (int i = 0; i < N; i++) { cin >> px[i] >> py[i] >> pt[i]; px[i]--; py[i]--; }\n    cin >> M;\n    hx.resize(M); hy.resize(M);\n    for (int i = 0; i < M; i++) { cin >> hx[i] >> hy[i]; hx[i]--; hy[i]--; }\n    memset(wall, false, sizeof(wall));\n\n    for (int turn = 0; turn < 300; turn++) {\n        vector<int> startPx = px, startPy = py, startHx = hx, startHy = hy;\n        string actions(M, '.');\n        bool newWall[SIZE][SIZE] = {};\n\n        for (int i = 0; i < M; i++) {\n            int myHx = startHx[i], myHy = startHy[i];\n            int distBefore[SIZE][SIZE];\n            bfs(myHx, myHy, distBefore);\n            double bestScore = computeScoreWithDist(distBefore);\n            char bestAction = '.';\n\n            for (int d = 0; d < 4; d++) {\n                int wx = myHx + dx[d], wy = myHy + dy[d];\n                if (inBounds(wx, wy) && !wall[wx][wy] && !newWall[wx][wy] &&\n                    !petAdjacentTo(wx, wy, startPx, startPy) && !humanAt(wx, wy, startHx, startHy)) {\n                    wall[wx][wy] = true;\n                    int distAfter[SIZE][SIZE];\n                    bfs(myHx, myHy, distAfter);\n                    double newScore = computeScoreWithDist(distAfter);\n                    for (int j = 0; j < N; j++)\n                        if (distBefore[startPx[j]][startPy[j]] >= 0 && distAfter[startPx[j]][startPy[j]] < 0)\n                            newScore += 0.05;\n                    for (int dd = 0; dd < 4; dd++) {\n                        int nx = wx + dx[dd], ny = wy + dy[dd];\n                        if (!inBounds(nx, ny) || wall[nx][ny]) newScore += 0.003;\n                    }\n                    newScore += 0.001;\n                    wall[wx][wy] = false;\n                    if (newScore > bestScore) { bestScore = newScore; bestAction = \"udlr\"[d]; }\n                }\n            }\n            for (int d = 0; d < 4; d++) {\n                int nx = myHx + dx[d], ny = myHy + dy[d];\n                if (inBounds(nx, ny) && !wall[nx][ny] && !newWall[nx][ny]) {\n                    int distAfter[SIZE][SIZE];\n                    bfs(nx, ny, distAfter);\n                    double newScore = computeScoreWithDist(distAfter);\n                    if (newScore > bestScore) { bestScore = newScore; bestAction = \"UDLR\"[d]; }\n                }\n            }\n            actions[i] = bestAction;\n            switch (actions[i]) {\n                case 'u': newWall[myHx-1][myHy]=true; wall[myHx-1][myHy]=true; break;\n                case 'd': newWall[myHx+1][myHy]=true; wall[myHx+1][myHy]=true; break;\n                case 'l': newWall[myHx][myHy-1]=true; wall[myHx][myHy-1]=true; break;\n                case 'r': newWall[myHx][myHy+1]=true; wall[myHx][myHy+1]=true; break;\n                case 'U': hx[i]=myHx-1; hy[i]=myHy; break;\n                case 'D': hx[i]=myHx+1; hy[i]=myHy; break;\n                case 'L': hx[i]=myHx; hy[i]=myHy-1; break;\n                case 'R': hx[i]=myHx; hy[i]=myHy+1; break;\n            }\n        }\n        cout << actions << endl;\n        for (int i = 0; i < N; i++) {\n            string move; cin >> move;\n            for (char c : move) {\n                if (c=='U') px[i]--; else if (c=='D') px[i]++;\n                else if (c=='L') py[i]--; else if (c=='R') py[i]++;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <cstring>\nusing namespace std;\nint si,sj,ti,tj;double p;int ti_idx;\nint md[400][4];double fv[400][202];int c2d[256];\n\nvoid init(){\n    vector<string>h(20),v(19);for(int i=0;i<20;i++)cin>>h[i];for(int i=0;i<19;i++)cin>>v[i];\n    ti_idx=ti*20+tj;int di[]={-1,1,0,0},dj[]={0,0,-1,1};\n    for(int i=0;i<20;i++)for(int j=0;j<20;j++){int idx=i*20+j;\n        for(int d=0;d<4;d++){int ni=i+di[d],nj=j+dj[d];bool bl=(ni<0||ni>=20||nj<0||nj>=20);\n            if(!bl){if(d==0&&v[i-1][j]=='1')bl=true;else if(d==1&&v[i][j]=='1')bl=true;\n                else if(d==2&&h[i][j-1]=='1')bl=true;else if(d==3&&h[i][j]=='1')bl=true;}\n            if(bl){ni=i;nj=j;}md[idx][d]=ni*20+nj;}}\n    memset(fv,0,sizeof(fv));\n    for(int t=200;t>=1;t--)for(int idx=0;idx<400;idx++){\n        if(idx==ti_idx){fv[idx][t]=401-t;continue;}\n        double b=0;for(int d=0;d<4;d++)b=max(b,p*fv[idx][t+1]+(1-p)*fv[md[idx][d]][t+1]);fv[idx][t]=b;}}\n\ndouble compute_score(const string&s){\n    double pr[400]={},np[400];pr[si*20+sj]=1;double es=0;\n    for(int t=0;t<(int)s.size();t++){int d=c2d[(unsigned char)s[t]];memset(np,0,sizeof(np));\n        for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;\n            if(i==ti_idx)continue;\n            np[i]+=p*pr[i];int ni=md[i][d];\n            if(ni==ti_idx)es+=(1-p)*pr[i]*(401-t-1);\n            else np[ni]+=(1-p)*pr[i];}\n        memcpy(pr,np,sizeof(pr));}return es;}\n\nstring bfs_path(){int dist[400],pdir[400];memset(dist,-1,sizeof(dist));\n    queue<int>q;int start=si*20+sj;q.push(start);dist[start]=0;\n    while(!q.empty()){int idx=q.front();q.pop();if(idx==ti_idx)break;\n        for(int d=0;d<4;d++){int ni=md[idx][d];if(ni!=idx&&dist[ni]==-1){dist[ni]=dist[idx]+1;pdir[ni]=d;q.push(ni);}}}\n    string path;int idx=ti_idx;int di[]={-1,1,0,0},dj[]={0,0,-1,1};\n    while(idx!=start){int d=pdir[idx];path=string(1,\"UDLR\"[d])+path;idx=(idx/20-di[d])*20+(idx%20-dj[d]);}return path;}\n\nstring greedy(){double pr[400]={};pr[si*20+sj]=1;string res;\n    for(int t=1;t<=200;t++){double bsc=-1;int ba=0;\n        for(int d=0;d<4;d++){double rp=0;double np[400]={};\n            for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;\n                if(i==ti_idx)continue;np[i]+=p*pr[i];int ni=md[i][d];\n                if(ni==ti_idx)rp+=(1-p)*pr[i];else np[ni]+=(1-p)*pr[i];}\n            double sc=rp*(401-t);for(int i=0;i<400;i++)sc+=np[i]*fv[i][t+1];\n            if(sc>bsc){bsc=sc;ba=d;}}\n        res+=\"UDLR\"[ba];double np[400]={};\n        for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;\n            if(i==ti_idx)continue;np[i]+=p*pr[i];int ni=md[i][ba];\n            if(ni!=ti_idx)np[ni]+=(1-p)*pr[i];}memcpy(pr,np,sizeof(pr));}return res;}\n\nstring beam_search(int B){\n    struct S{double pr[400];double acc;string s;};\n    vector<S>beam(1);memset(beam[0].pr,0,sizeof(beam[0].pr));beam[0].pr[si*20+sj]=1;beam[0].acc=0;beam[0].s=\"\";\n    for(int t=1;t<=200;t++){vector<pair<double,int>>scores;vector<S>cand;\n        for(int bi=0;bi<(int)beam.size();bi++){for(int d=0;d<4;d++){\n            S ns;memset(ns.pr,0,sizeof(ns.pr));ns.acc=beam[bi].acc;ns.s=beam[bi].s+(char)(\"UDLR\"[d]);\n            for(int i=0;i<400;i++){if(beam[bi].pr[i]<1e-18)continue;\n                if(i==ti_idx)continue;ns.pr[i]+=p*beam[bi].pr[i];int ni=md[i][d];\n                if(ni==ti_idx)ns.acc+=(1-p)*beam[bi].pr[i]*(401-t);\n                else ns.pr[ni]+=(1-p)*beam[bi].pr[i];}\n            double h=ns.acc;for(int i=0;i<400;i++){if(ns.pr[i]<1e-18)continue;h+=ns.pr[i]*fv[i][t+1];}\n            scores.emplace_back(h,(int)cand.size());cand.push_back(move(ns));}}\n        int k=min(B,(int)scores.size());\n        if((int)scores.size()>k)partial_sort(scores.begin(),scores.begin()+k,scores.end(),[](auto&a,auto&b){return a.first>b.first;});\n        vector<S>nb(k);for(int i=0;i<k;i++)nb[i]=move(cand[scores[i].second]);beam=move(nb);}\n    sort(beam.begin(),beam.end(),[](auto&a,auto&b){return a.acc>b.acc;});\n    double bsc=-1;string br;int ec=min(20,(int)beam.size());\n    for(int i=0;i<ec;i++){double sc=compute_score(beam[i].s);if(sc>bsc){bsc=sc;br=beam[i].s;}}return br;}\n\nvoid suffix_opt(string&best,double&bs){\n    for(int k=5;k<200;k+=5){if(k>=(int)best.size())continue;\n        double pr[400]={};pr[si*20+sj]=1;\n        for(int t=0;t<k;t++){int d=c2d[(unsigned char)best[t]];double np[400]={};\n            for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;\n                if(i==ti_idx)continue;np[i]+=p*pr[i];int ni=md[i][d];\n                if(ni!=ti_idx)np[ni]+=(1-p)*pr[i];}memcpy(pr,np,sizeof(pr));}\n        string ns=best.substr(0,k);\n        for(int t=k+1;t<=200;t++){double bsc2=-1;int ba=0;\n            for(int d=0;d<4;d++){double rp=0;double np[400]={};\n                for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;\n                    if(i==ti_idx)continue;np[i]+=p*pr[i];int ni=md[i][d];\n                    if(ni==ti_idx)rp+=(1-p)*pr[i];else np[ni]+=(1-p)*pr[i];}\n                double sc=rp*(401-t);for(int i=0;i<400;i++)sc+=np[i]*fv[i][t+1];\n                if(sc>bsc2){bsc2=sc;ba=d;}}\n            ns+=\"UDLR\"[ba];double np[400]={};\n            for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;\n                if(i==ti_idx)continue;np[i]+=p*pr[i];int ni=md[i][ba];\n                if(ni!=ti_idx)np[ni]+=(1-p)*pr[i];}memcpy(pr,np,sizeof(pr));}\n        double sc=compute_score(ns);if(sc>bs){bs=sc;best=ns;}}}\n\nvoid coordinate_descent(string& best, double& bs) {\n    double pr_arr[201][400];\n    memset(pr_arr[0], 0, sizeof(pr_arr[0]));\n    pr_arr[0][si*20+sj] = 1.0;\n    for(int t=0; t<(int)best.size(); ++t) {\n        memset(pr_arr[t+1], 0, sizeof(pr_arr[t+1]));\n        int d = c2d[(unsigned char)best[t]];\n        for(int i=0; i<400; ++i) {\n            if(pr_arr[t][i] < 1e-18) continue;\n            if(i == ti_idx) continue;\n            pr_arr[t+1][i] += p * pr_arr[t][i];\n            int ni = md[i][d];\n            if(ni == ti_idx) continue;\n            pr_arr[t+1][ni] += (1-p) * pr_arr[t][i];\n        }\n    }\n    for(int pos=0; pos<(int)best.size(); ++pos) {\n        double bsc = -1; int ba = c2d[(unsigned char)best[pos]];\n        for(int d=0; d<4; ++d) {\n            double pr_next[400]; memset(pr_next, 0, sizeof(pr_next));\n            double es = 0;\n            for(int i=0; i<400; ++i) {\n                if(pr_arr[pos][i] < 1e-18) continue;\n                if(i == ti_idx) continue;\n                pr_next[i] += p * pr_arr[pos][i];\n                int ni = md[i][d];\n                if(ni == ti_idx) es += (1-p) * pr_arr[pos][i] * (401 - (pos+1));\n                else pr_next[ni] += (1-p) * pr_arr[pos][i];\n            }\n            double pr_curr[400]; memcpy(pr_curr, pr_next, sizeof(pr_next));\n            for(int t=pos+1; t<(int)best.size(); ++t) {\n                double np[400]; memset(np, 0, sizeof(np));\n                int dd = c2d[(unsigned char)best[t]];\n                for(int i=0; i<400; ++i) {\n                    if(pr_curr[i] < 1e-18) continue;\n                    if(i == ti_idx) continue;\n                    np[i] += p * pr_curr[i];\n                    int ni = md[i][dd];\n                    if(ni == ti_idx) es += (1-p) * pr_curr[i] * (401 - (t+1));\n                    else np[ni] += (1-p) * pr_curr[i];\n                }\n                memcpy(pr_curr, np, sizeof(np));\n            }\n            if(es > bsc) { bsc = es; ba = d; }\n        }\n        if(c2d[(unsigned char)best[pos]] != ba) {\n            best[pos] = \"UDLR\"[ba];\n            for(int t=pos; t<(int)best.size(); ++t) {\n                memset(pr_arr[t+1], 0, sizeof(pr_arr[t+1]));\n                int d2 = c2d[(unsigned char)best[t]];\n                for(int i=0; i<400; ++i) {\n                    if(pr_arr[t][i] < 1e-18) continue;\n                    if(i == ti_idx) continue;\n                    pr_arr[t+1][i] += p * pr_arr[t][i];\n                    int ni = md[i][d2];\n                    if(ni == ti_idx) continue;\n                    pr_arr[t+1][ni] += (1-p) * pr_arr[t][i];\n                }\n            }\n        }\n    }\n    double sc = compute_score(best); if(sc > bs) bs = sc;\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);cin.tie(nullptr);\n    c2d['U']=0;c2d['D']=1;c2d['L']=2;c2d['R']=3;\n    cin>>si>>sj>>ti>>tj>>p;init();\n    string best;double bs=-1;\n    auto ts=[&](const string&s){double sc=compute_score(s);if(sc>bs){bs=sc;best=s;}};\n    string sp=bfs_path();\n    {string s;while((int)(s.size()+sp.size())<=200)s+=sp;ts(s);}\n    for(int r=2;r<=5;r++){string s;for(char c:sp)for(int k=0;k<r&&(int)s.size()<200;k++)s+=c;ts(s);}\n    ts(greedy());ts(beam_search(50));ts(beam_search(30));\n    suffix_opt(best,bs);\n    for(int i=0;i<3;++i)coordinate_descent(best,bs);\n    for(int len=100;len<=200;len+=10){if(len<(int)best.size()){string ns=best.substr(0,len);double sc=compute_score(ns);if(sc>bs){bs=sc;best=ns;}}}\n    cout<<best<<endl;return 0;}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint orig[N][N], cur[N][N], rot[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 rt[8][4]={{0,1,2,3},{1,2,3,0},{2,3,0,1},{3,0,1,2},{4,5,4,5},{5,4,5,4},{6,7,6,7},{7,6,7,6}};\n\nmap<int, int> cycle_counts;\n\nint vm[N][N][4]; \nunsigned int vcnt=0;\n\nvoid init_cycle_counts() {\n    cycle_counts.clear();\n    ++vcnt;\n    if (vcnt == 0) { memset(vm, 0, sizeof(vm)); vcnt = 1; }\n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) {\n        int t = cur[i][j];\n        for (int d=0; d<4; d++) {\n            if (vm[i][j][d] == vcnt || to[t][d] == -1) continue;\n            int si=i, sj=j, sd=d, ci=i, cj=j, cd=d, len=0;\n            bool is_cycle = false;\n            while (true) {\n                vm[ci][cj][cd] = vcnt;\n                int t2 = cur[ci][cj];\n                int d2 = to[t2][cd];\n                if (d2 == -1) break;\n                int ni = ci + di[d2], nj = cj + dj[d2];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n                len++;\n                int nd = (d2 + 2) % 4;\n                if (ni == si && nj == sj && nd == sd) { is_cycle = true; break; }\n                if (vm[ni][nj][nd] == vcnt) break;\n                ci = ni; cj = nj; cd = nd;\n            }\n            if (is_cycle) {\n                cycle_counts[len]++;\n            }\n        }\n    }\n}\n\nvoid update_tile(int i, int j, int new_t) {\n    int old_t = cur[i][j];\n    if (old_t == new_t) return;\n\n    // 1. Remove old cycles\n    bool visited_old[4] = {false, false, false, false};\n    for (int d = 0; d < 4; d++) {\n        if (visited_old[d] || to[old_t][d] == -1) continue;\n        int len = 0;\n        int ci = i, cj = j, cd = d;\n        bool is_cycle = false;\n        while (true) {\n            int t2 = (ci == i && cj == j) ? old_t : cur[ci][cj];\n            int d2 = to[t2][cd];\n            if (d2 == -1) break;\n            if (ci == i && cj == j) { visited_old[cd] = true; visited_old[d2] = true; }\n            int ni = ci + di[d2], nj = cj + dj[d2];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n            len++;\n            int nd = (d2 + 2) % 4;\n            if (ni == i && nj == j && nd == d) { is_cycle = true; break; }\n            if (len > 900) break;\n            ci = ni; cj = nj; cd = nd;\n        }\n        if (is_cycle) {\n            cycle_counts[len]--;\n            if (cycle_counts[len] == 0) cycle_counts.erase(len);\n        }\n    }\n\n    // 2. Add new cycles\n    cur[i][j] = new_t;\n    bool visited_new[4] = {false, false, false, false};\n    for (int d = 0; d < 4; d++) {\n        if (visited_new[d] || to[new_t][d] == -1) continue;\n        int len = 0;\n        int ci = i, cj = j, cd = d;\n        bool is_cycle = false;\n        while (true) {\n            int t2 = (ci == i && cj == j) ? new_t : cur[ci][cj];\n            int d2 = to[t2][cd];\n            if (d2 == -1) break;\n            if (ci == i && cj == j) { visited_new[cd] = true; visited_new[d2] = true; }\n            int ni = ci + di[d2], nj = cj + dj[d2];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n            len++;\n            int nd = (d2 + 2) % 4;\n            if (ni == i && nj == j && nd == d) { is_cycle = true; break; }\n            if (len > 900) break;\n            ci = ni; cj = nj; cd = nd;\n        }\n        if (is_cycle) {\n            cycle_counts[len]++;\n        }\n    }\n}\n\nlong long get_score() {\n    if (cycle_counts.empty()) return 0;\n    auto it = cycle_counts.rbegin();\n    int L1 = it->first;\n    if (it->second >= 2) return (long long)L1 * L1;\n    if (cycle_counts.size() == 1) return 0;\n    int L2 = next(it)->first;\n    return (long long)L1 * L2;\n}\n\nint lmatch(int i, int j) {\n    int t = cur[i][j], m = 0;\n    for (int d = 0; d < 4; d++) {\n        if (to[t][d] == -1) continue;\n        int ni = i + di[d], nj = j + dj[d];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n        if (to[cur[ni][nj]][(d + 2) % 4] != -1) m++;\n    }\n    return m;\n}\n\nvoid greedy_match() {\n    for (int pass = 0; pass < 10; pass++) {\n        bool ch = false;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            int br = rot[i][j], bm = lmatch(i, j);\n            for (int r = 0; r < 4; r++) {\n                if (r == rot[i][j]) continue;\n                cur[i][j] = rt[orig[i][j]][r];\n                int m = lmatch(i, j);\n                if (m > bm) { bm = m; br = r; ch = true; }\n            }\n            rot[i][j] = br; cur[i][j] = rt[orig[i][j]][br];\n        }\n        if (!ch) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    for (int i = 0; i < N; i++) { string s; cin >> s; for (int j = 0; j < N; j++) orig[i][j] = s[j] - '0'; }\n    mt19937 rng(42);\n    long long gbest = 0; int grot[N][N] = {};\n    auto t0 = chrono::steady_clock::now();\n    bool have_best = false;\n\n    for (int trial = 0; ; trial++) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - t0).count();\n        if (elapsed > 1.5) break;\n\n        if (have_best && trial % 2 == 1) {\n            memcpy(rot, grot, sizeof(rot));\n            int np = 20 + rng() % 80;\n            for (int k = 0; k < np; k++) { int i = rng() % N, j = rng() % N; rot[i][j] = rng() % 4; }\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cur[i][j] = rt[orig[i][j]][rot[i][j]];\n            greedy_match();\n        } else {\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) { rot[i][j] = rng() % 4; cur[i][j] = rt[orig[i][j]][rot[i][j]]; }\n            greedy_match();\n        }\n\n        init_cycle_counts();\n        long long current_score = get_score();\n        long long best_score = current_score;\n        int brot[N][N]; memcpy(brot, rot, sizeof(rot));\n\n        for (int iter = 0; ; iter++) {\n            if (iter % 10000 == 0) {\n                if (chrono::duration<double>(chrono::steady_clock::now() - t0).count() > 1.7) break;\n            }\n            double frac = min(iter / 1000000.0, 1.0);\n            double temp = 5000.0 * pow(0.001, frac);\n            int idx = rng() % 900, i = idx / N, j = idx % N;\n            int old_r = rot[i][j];\n            int new_r = rng() % 4;\n            if (old_r == new_r) continue;\n            int new_t = rt[orig[i][j]][new_r];\n            if (new_t == cur[i][j]) continue;\n\n            update_tile(i, j, new_t);\n            long long new_score = get_score();\n            long long diff = new_score - current_score;\n\n            if (diff >= 0) {\n                current_score = new_score;\n                rot[i][j] = new_r;\n                if (current_score > best_score) {\n                    best_score = current_score;\n                    memcpy(brot, rot, sizeof(rot));\n                }\n            } else if ((double)(rng() & 0xFFFF) / 65536.0 < exp((double)diff / temp)) {\n                current_score = new_score;\n                rot[i][j] = new_r;\n            } else {\n                update_tile(i, j, rt[orig[i][j]][old_r]);\n                rot[i][j] = old_r;\n            }\n        }\n\n        if (best_score > gbest) {\n            gbest = best_score;\n            memcpy(grot, brot, sizeof(grot));\n            have_best = true;\n        }\n    }\n\n    // Final local search on global best\n    memcpy(rot, grot, sizeof(rot));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cur[i][j] = rt[orig[i][j]][rot[i][j]];\n    init_cycle_counts();\n    long long current_score = get_score();\n\n    for (int pass = 0; pass < 10; pass++) {\n        bool imp = false;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            int old_t = cur[i][j];\n            int best_new_t = old_t;\n            long long best_local_score = current_score;\n            int best_new_r = rot[i][j];\n\n            for (int r = 0; r < 4; r++) {\n                int new_t = rt[orig[i][j]][r];\n                if (new_t == old_t) continue;\n                update_tile(i, j, new_t);\n                long long new_score = get_score();\n                if (new_score > best_local_score) {\n                    best_local_score = new_score;\n                    best_new_t = new_t;\n                    best_new_r = r;\n                }\n                update_tile(i, j, old_t); // revert\n            }\n\n            if (best_new_t != old_t) {\n                update_tile(i, j, best_new_t);\n                rot[i][j] = best_new_r;\n                current_score = best_local_score;\n                imp = true;\n            }\n        }\n        if (!imp) break;\n    }\n\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cout << rot[i][j];\n    cout << endl;\n\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nint board[10][10];\nint er, ec;\n\nint par[100], gsz[100];\nint find_root(int x) { while (par[x] != x) x = par[x] = par[par[x]]; return x; }\nvoid unite(int x, int y) {\n    x = find_root(x); y = find_root(y);\n    if (x == y) return;\n    if (gsz[x] < gsz[y]) swap(x, y);\n    par[y] = x; gsz[x] += gsz[y];\n}\n\npair<int,int> compute() {\n    for (int i = 0; i < N*N; i++) { par[i] = i; gsz[i] = (board[i/N][i%N] ? 1 : 0); }\n    int conn = 0;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N-1; j++)\n            if (board[i][j] && board[i][j+1] && (board[i][j] & 4) && (board[i][j+1] & 1))\n                { unite(i*N+j, i*N+j+1); conn++; }\n    for (int i = 0; i < N-1; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j] && board[i+1][j] && (board[i][j] & 8) && (board[i+1][j] & 2))\n                { unite(i*N+j, (i+1)*N+j); conn++; }\n    // Count edges per component for acyclicity check\n    int cedge[100] = {};\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N-1; j++)\n            if (board[i][j] && board[i][j+1] && (board[i][j] & 4) && (board[i][j+1] & 1))\n                cedge[find_root(i*N+j)]++;\n    for (int i = 0; i < N-1; i++)\n        for (int j = 0; j < N; j++)\n            if (board[i][j] && board[i+1][j] && (board[i][j] & 8) && (board[i+1][j] & 2))\n                cedge[find_root(i*N+j)]++;\n    int mx = 0;\n    for (int i = 0; i < N*N; i++)\n        if (board[i/N][i%N] && find_root(i) == i) {\n            // Tree = connected component without cycles (edges = vertices - 1)\n            if (cedge[i] == gsz[i] - 1)\n                mx = max(mx, gsz[i]);\n        }\n    return {mx, conn};\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> T;\n    for (int i = 0; i < N; i++) {\n        string s; cin >> s;\n        for (int j = 0; j < N; j++) {\n            char c = s[j];\n            board[i][j] = (c >= '0' && c <= '9') ? c - '0' : c - 'a' + 10;\n            if (!board[i][j]) { er = i; ec = j; }\n        }\n    }\n    \n    constexpr int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};\n    constexpr char dc_c[] = {'U','D','L','R'};\n    constexpr int rev_dir[] = {1,0,3,2};\n    \n    string moves; moves.reserve(T);\n    auto [init_mx, init_conn] = compute();\n    int best_mx = init_mx; size_t best_idx = 0;\n    mt19937 rng(42);\n    int last_d = -1;\n    double temp = 3.0;\n    int stale = 0;\n    auto start = chrono::high_resolution_clock::now();\n    \n    while ((int)moves.size() < T) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now-start).count() > 2900) break;\n        \n        int ns_mx[4], ns_conn[4];\n        for (int d = 0; d < 4; d++) {\n            int nr = er+dr[d], nc = ec+dc[d];\n            if (nr<0||nr>=N||nc<0||nc>=N) { ns_mx[d] = -1; ns_conn[d] = -1; continue; }\n            swap(board[er][ec], board[nr][nc]);\n            int oer=er, oec=ec; er=nr; ec=nc;\n            auto [mx, conn] = compute();\n            ns_mx[d] = mx; ns_conn[d] = conn;\n            swap(board[er][ec], board[oer][oec]); er=oer; ec=oec;\n        }\n        \n        long long ns_val[4];\n        for (int d = 0; d < 4; d++)\n            ns_val[d] = (ns_mx[d] < 0) ? -1e18 : (long long)ns_mx[d] * 100000LL + ns_conn[d] * 100LL;\n        \n        int bd = -1; long long bv = -1e18;\n        for (int d = 0; d < 4; d++)\n            if (ns_val[d] > bv) { bv = ns_val[d]; bd = d; }\n        if (bd == -1) break;\n        \n        long long cur_val = (long long)init_mx * 100000LL + init_conn * 100LL;\n        // Recompute current from actual state\n        auto [cur_mx, cur_conn] = compute();\n        cur_val = (long long)cur_mx * 100000LL + cur_conn * 100LL;\n        \n        int chosen;\n        if (bv > cur_val) {\n            chosen = bd;\n            stale = 0;\n        } else {\n            stale++;\n            double delta = (double)(bv - cur_val);\n            double prob = exp(delta / max(temp, 0.01));\n            if ((double)rng() / (double)UINT32_MAX < prob) {\n                chosen = bd;\n            } else {\n                // Random walk - longer when stuck\n                int walk_len = (stale > 30) ? 15 : 5;\n                for (int w = 0; w < walk_len && (int)moves.size() < T; w++) {\n                    int valid[4], nv = 0;\n                    for (int d = 0; d < 4; d++) {\n                        int nr = er+dr[d], nc = ec+dc[d];\n                        if (nr<0||nr>=N||nc<0||nc>=N) continue;\n                        if (last_d >= 0 && d == rev_dir[last_d]) continue;\n                        valid[nv++] = d;\n                    }\n                    if (!nv)\n                        for (int d = 0; d < 4; d++) {\n                            int nr = er+dr[d], nc = ec+dc[d];\n                            if (nr>=0&&nr<N&&nc>=0&&nc<N) valid[nv++] = d;\n                        }\n                    if (!nv) goto done;\n                    chosen = valid[rng() % nv];\n                    int nr = er+dr[chosen], nc = ec+dc[chosen];\n                    swap(board[er][ec], board[nr][nc]); er=nr; ec=nc;\n                    moves += dc_c[chosen]; last_d = chosen;\n                }\n                auto [mx2, conn2] = compute();\n                if (mx2 > best_mx) { best_mx = mx2; best_idx = moves.size(); }\n                init_mx = mx2; init_conn = conn2;\n                continue;\n            }\n        }\n        \n        int nr = er+dr[chosen], nc = ec+dc[chosen];\n        swap(board[er][ec], board[nr][nc]); er=nr; ec=nc;\n        moves += dc_c[chosen]; last_d = chosen;\n        init_mx = ns_mx[chosen]; init_conn = ns_conn[chosen];\n        \n        if (init_mx > best_mx) { best_mx = init_mx; best_idx = moves.size(); stale = 0; }\n        \n        temp *= 0.9997;\n        if (stale > 50) { temp = min(temp * 2.0, 10.0); stale = 25; }\n        if (best_mx == N*N-1) break;\n    }\n    done:\n    cout << moves.substr(0, best_idx) << endl;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\n\nint N, K;\nint a[11];\nvector<ll> px, py;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> K;\n    for (int d = 1; d <= 10; d++) cin >> a[d];\n    px.resize(N); py.resize(N);\n    for (int i = 0; i < N; i++) cin >> px[i] >> py[i];\n    \n    vector<array<ll, 4>> lines;\n    auto start = chrono::steady_clock::now();\n    \n    for (int iter = 0; iter < K; iter++) {\n        if (chrono::duration<double>(chrono::steady_clock::now() - start).count() > 2.0) break;\n        \n        map<vector<int>, vector<int>> groups;\n        for (int i = 0; i < N; i++) {\n            vector<int> sig; bool dead = false;\n            for (auto& L : lines) {\n                ll la = L[3]-L[1], lb = L[0]-L[2], lc = L[2]*L[1]-L[0]*L[3];\n                ll val = la*px[i] + lb*py[i] + lc;\n                if (val == 0) { dead = true; break; }\n                sig.push_back(val > 0 ? 1 : -1);\n            }\n            if (!dead) groups[sig].push_back(i);\n        }\n        \n        int pc[11] = {};\n        for (auto& [s, m] : groups) { int sz = m.size(); if (sz >= 1 && sz <= 10) pc[sz]++; }\n        int cur_score = 0;\n        for (int d = 1; d <= 10; d++) cur_score += min(a[d], pc[d]);\n        int max_score = 0;\n        for (int d = 1; d <= 10; d++) max_score += a[d];\n        if (cur_score == max_score) break;\n        \n        vector<pair<int, array<ll,4>>> cands;\n        auto try_line = [&](ll x1, ll y1, ll x2, ll y2) {\n            if (x1 == x2 && y1 == y2) return;\n            ll la = y2-y1, lb = x1-x2, lc = x2*y1-x1*y2;\n            int new_pc[11] = {};\n            for (auto& [sig, members] : groups) {\n                int pos = 0, neg = 0;\n                for (int i : members) {\n                    ll val = la*px[i] + lb*py[i] + lc;\n                    if (val > 0) pos++; else if (val < 0) neg++;\n                }\n                if (pos >= 1 && pos <= 10) new_pc[pos]++;\n                if (neg >= 1 && neg <= 10) new_pc[neg]++;\n            }\n            int score = 0;\n            for (int d = 1; d <= 10; d++) score += min(a[d], new_pc[d]);\n            cands.push_back({score, {x1, y1, x2, y2}});\n        };\n        \n        for (auto& [sig, members] : groups) {\n            int sz = members.size();\n            if (sz <= 1) continue;\n            if (sz <= 10 && pc[sz] <= a[sz]) continue;\n            int lim = min((int)members.size(), 20);\n            for (int ii = 0; ii < lim; ii++)\n                for (int jj = ii+1; jj < lim; jj++) {\n                    int i = members[ii], j = members[jj];\n                    ll sx = px[i]+px[j], sy = py[i]+py[j];\n                    ll dx = 2*(py[i]-py[j]), dy = 2*(px[j]-px[i]);\n                    try_line(sx, sy, sx+dx, sy+dy);\n                }\n            ll cx = 0, cy = 0;\n            for (int i : members) { cx += px[i]; cy += py[i]; }\n            for (int angle = 0; angle < 18; angle++) {\n                double a_rad = angle * M_PI / 9;\n                ll dx = (ll)round(10000*cos(a_rad)), dy = (ll)round(10000*sin(a_rad));\n                if (dx == 0 && dy == 0) continue;\n                try_line(cx, cy, cx + dx*sz, cy + dy*sz);\n            }\n        }\n        \n        mt19937 rng(iter*12345+67890);\n        for (int r = 0; r < 50; r++) {\n            ll x1 = rng()%20001-10000, y1 = rng()%20001-10000;\n            ll x2 = rng()%20001-10000, y2 = rng()%20001-10000;\n            try_line(x1, y1, x2, y2);\n        }\n        \n        if (cands.empty()) break;\n        int best = 0;\n        for (int i = 1; i < (int)cands.size(); i++)\n            if (cands[i].first > cands[best].first) best = i;\n        lines.push_back(cands[best].second);\n    }\n    \n    cout << lines.size() << \"\\n\";\n    for (auto& L : lines)\n        cout << L[0] << \" \" << L[1] << \" \" << L[2] << \" \" << L[3] << \"\\n\";\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <map>\n#include <numeric>\n#include <algorithm>\n#include <array>\n\nusing namespace std;\n\nint N, M;\nvector<vector<bool>> has_dot;\nvector<array<int,8>> ops;\nmap<int, vector<pair<int,int>>> segs[4];\n\nvector<int> dots_y[65];\nvector<int> dots_x[65];\nvector<int> pt_idx[65];\nvector<pair<int,int>> existing_dots;\n\nset<int> candidates;\nvector<pair<double, pair<int,int>>> empty_pts_vec;\n\nint seg_type(int x1,int y1,int x2,int y2){\n    if(y1==y2)return 0;\n    if(x1==x2)return 1;\n    if(x2-x1==y2-y1)return 2;\n    return 3;\n}\nint line_id(int t,int x,int y){\n    if(t==0)return y;\n    if(t==1)return x;\n    if(t==2)return x-y;\n    return x+y;\n}\nint line_coord(int t,int x,int y){\n    if(t==0||t==2||t==3)return x;\n    return y;\n}\n\nbool check_overlap(int t,int lid,int s,int e){\n    if(s>e)swap(s,e);\n    auto it=segs[t].find(lid);\n    if(it==segs[t].end())return false;\n    for(auto& seg : it->second){\n        int lo=min(seg.first,seg.second);\n        int hi=max(seg.first,seg.second);\n        if(max(s,lo)<min(e,hi))return true;\n    }\n    return false;\n}\nvoid add_seg(int t,int lid,int s,int e){\n    segs[t][lid].push_back({s,e});\n}\n\nbool has_perim_overlap(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    int e[4][4]={{x1,y1,x2,y2},{x2,y2,x3,y3},{x3,y3,x4,y4},{x4,y4,x1,y1}};\n    for(int i=0;i<4;i++){\n        int t=seg_type(e[i][0],e[i][1],e[i][2],e[i][3]);\n        int lid=line_id(t,e[i][0],e[i][1]);\n        int s=line_coord(t,e[i][0],e[i][1]);\n        int ee=line_coord(t,e[i][2],e[i][3]);\n        if(check_overlap(t,lid,s,ee))return true;\n    }\n    return false;\n}\nvoid add_perim(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    int e[4][4]={{x1,y1,x2,y2},{x2,y2,x3,y3},{x3,y3,x4,y4},{x4,y4,x1,y1}};\n    for(int i=0;i<4;i++){\n        int t=seg_type(e[i][0],e[i][1],e[i][2],e[i][3]);\n        int lid=line_id(t,e[i][0],e[i][1]);\n        int s=line_coord(t,e[i][0],e[i][1]);\n        int ee=line_coord(t,e[i][2],e[i][3]);\n        add_seg(t,lid,s,ee);\n    }\n}\n\nbool dot_on_perim(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    set<pair<int,int>> corners={{x1,y1},{x2,y2},{x3,y3},{x4,y4}};\n    auto chk=[&](int ax,int ay,int bx,int by){\n        int dx=bx-ax, dy=by-ay;\n        int g=gcd(abs(dx),abs(dy));\n        if(g==0)return false;\n        int sx=dx/g, sy=dy/g;\n        for(int i=1;i<g;i++){\n            int px=ax+i*sx, py=ay+i*sy;\n            if(!corners.count({px,py}) && has_dot[px][py]) return true;\n        }\n        return false;\n    };\n    return chk(x1,y1,x2,y2)||chk(x2,y2,x3,y3)||chk(x3,y3,x4,y4)||chk(x4,y4,x1,y1);\n}\n\nbool valid_rect(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    if(dot_on_perim(x1,y1,x2,y2,x3,y3,x4,y4))return false;\n    if(has_perim_overlap(x1,y1,x2,y2,x3,y3,x4,y4))return false;\n    return true;\n}\n\narray<int,8> find_rect(int ex, int ey) {\n    // Axis-aligned\n    for (int y1 : dots_y[ex]) {\n        for (int x1 : dots_x[ey]) {\n            if (has_dot[x1][y1]) {\n                if (valid_rect(ex, ey, ex, y1, x1, y1, x1, ey)) {\n                    return {ex, ey, ex, y1, x1, y1, x1, ey};\n                }\n            }\n        }\n    }\n    \n    // Tilted 1 (same row for V1, V3)\n    for (int x3 : dots_x[ey]) {\n        int diff = x3 - ex;\n        if (diff % 2 != 0) continue;\n        int cx = (ex + x3) / 2;\n        int dy = diff / 2;\n        int y2 = ey + dy;\n        int y4 = ey - dy;\n        if (y2 >= 0 && y2 < N && y4 >= 0 && y4 < N && has_dot[cx][y2] && has_dot[cx][y4]) {\n            if (valid_rect(ex, ey, cx, y2, x3, ey, cx, y4)) {\n                return {ex, ey, cx, y2, x3, ey, cx, y4};\n            }\n        }\n    }\n    \n    // Tilted 2 (same col for V1, V3)\n    for (int y3 : dots_y[ex]) {\n        int diff = y3 - ey;\n        if (diff % 2 != 0) continue;\n        int cy = (ey + y3) / 2;\n        int dx = diff / 2;\n        int x2 = ex + dx;\n        int x4 = ex - dx;\n        if (x2 >= 0 && x2 < N && x4 >= 0 && x4 < N && has_dot[x2][cy] && has_dot[x4][cy]) {\n            if (valid_rect(ex, ey, x2, cy, ex, y3, x4, cy)) {\n                return {ex, ey, x2, cy, ex, y3, x4, cy};\n            }\n        }\n    }\n    \n    return {-1};\n}\n\nvoid add_cand(int x, int y) {\n    if (x >= 0 && x < N && y >= 0 && y < N && !has_dot[x][y]) {\n        int idx = pt_idx[x][y];\n        if (idx != -1) {\n            candidates.insert(idx);\n        }\n    }\n}\n\nvoid add_candidates(int x, int y) {\n    for (auto [x2, y2] : existing_dots) {\n        if ((x % 2) != (x2 % 2)) continue;\n        if ((y % 2) != (y2 % 2)) continue;\n        \n        int cx = (x + x2) / 2;\n        int cy = (y + y2) / 2;\n        \n        int dx = (y2 - y) / 2;\n        int dy = (x2 - x) / 2;\n        \n        int va_x = cx - dx;\n        int va_y = cy - dy;\n        int vb_x = cx + dx;\n        int vb_y = cy + dy;\n        \n        bool valid_a = (va_x >= 0 && va_x < N && va_y >= 0 && va_y < N);\n        bool valid_b = (vb_x >= 0 && vb_x < N && vb_y >= 0 && vb_y < N);\n        \n        if (valid_a && valid_b) {\n            if ((va_x == x && va_y == y) || (va_x == x2 && va_y == y2)) continue;\n            \n            bool dot_a = has_dot[va_x][va_y];\n            bool dot_b = has_dot[vb_x][vb_y];\n            \n            if (dot_a && !dot_b) {\n                add_cand(vb_x, vb_y);\n            } else if (!dot_a && dot_b) {\n                add_cand(va_x, va_y);\n            }\n        }\n    }\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M;\n    has_dot.assign(N, vector<bool>(N, false));\n    \n    double c = (N - 1) / 2.0;\n    \n    for(int i=0;i<N;++i) pt_idx[i].resize(N, -1);\n    \n    vector<pair<int,int>> initial_dots(M);\n    for(int i=0;i<M;i++){\n        int x, y;\n        cin >> x >> y;\n        has_dot[x][y] = true;\n        dots_y[x].push_back(y);\n        dots_x[y].push_back(x);\n        initial_dots[i] = {x, y};\n    }\n    \n    for(int x=0;x<N;x++){\n        for(int y=0;y<N;y++){\n            if(!has_dot[x][y]){\n                double w = (x-c)*(x-c) + (y-c)*(y-c) + 1;\n                empty_pts_vec.push_back({-w, {x, y}});\n            }\n        }\n    }\n    \n    sort(empty_pts_vec.begin(), empty_pts_vec.end());\n    \n    for(size_t i=0; i<empty_pts_vec.size(); ++i) {\n        auto [w, p] = empty_pts_vec[i];\n        pt_idx[p.first][p.second] = i;\n    }\n    \n    for(auto [x, y] : initial_dots) {\n        existing_dots.push_back({x, y});\n    }\n    \n    for (auto [x, y] : initial_dots) {\n        add_candidates(x, y);\n    }\n    \n    while (!candidates.empty()) {\n        int best_idx = *candidates.begin();\n        auto [w, p] = empty_pts_vec[best_idx];\n        auto [x, y] = p;\n        \n        auto r = find_rect(x, y);\n        if (r[0] != -1) {\n            has_dot[x][y] = true;\n            dots_y[x].push_back(y);\n            dots_x[y].push_back(x);\n            existing_dots.push_back({x, y});\n            add_perim(r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]);\n            ops.push_back(array<int,8>{r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]});\n            candidates.erase(best_idx);\n            pt_idx[x][y] = -1;\n            add_candidates(x, y);\n        } else {\n            candidates.erase(best_idx);\n        }\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for(auto& op : ops){\n        for(int i=0;i<8;i++){\n            cout << op[i] << (i<7?\" \":\"\\n\");\n        }\n    }\n    \n    return 0;\n}","ahc015":"#include <iostream>\n#include <cstring>\n#include <queue>\n#include <vector>\n#include <random>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nint f[101];\nmt19937 rng(42);\n\nvoid tiltGrid(int g[N][N], int d) {\n    if (d == 0) {\n        for (int c = 0; c < N; c++) {\n            int w = 0;\n            for (int r = 0; r < N; r++) {\n                if (g[r][c]) { if (w != r) { g[w][c] = g[r][c]; g[r][c] = 0; } w++; }\n            }\n        }\n    } else if (d == 1) {\n        for (int c = 0; c < N; c++) {\n            int w = N - 1;\n            for (int r = N - 1; r >= 0; r--) {\n                if (g[r][c]) { if (w != r) { g[w][c] = g[r][c]; g[r][c] = 0; } w--; }\n            }\n        }\n    } else if (d == 2) {\n        for (int r = 0; r < N; r++) {\n            int w = 0;\n            for (int c = 0; c < N; c++) {\n                if (g[r][c]) { if (w != c) { g[r][w] = g[r][c]; g[r][c] = 0; } w++; }\n            }\n        }\n    } else {\n        for (int r = 0; r < N; r++) {\n            int w = N - 1;\n            for (int c = N - 1; c >= 0; c--) {\n                if (g[r][c]) { if (w != c) { g[r][w] = g[r][c]; g[r][c] = 0; } w--; }\n            }\n        }\n    }\n}\n\nlong long calcScore(int g[N][N]) {\n    bool visited[N][N] = {};\n    long long score = 0;\n    int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (!visited[r][c] && g[r][c]) {\n                int flavor = g[r][c], size = 0;\n                queue<pair<int,int>> q;\n                q.push({r, c}); visited[r][c] = true;\n                while (!q.empty()) {\n                    auto [cr, cc] = q.front(); q.pop(); size++;\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 && !visited[nr][nc] && g[nr][nc] == flavor) {\n                            visited[nr][nc] = true; q.push({nr, nc});\n                        }\n                    }\n                }\n                score += (long long)size * size;\n            }\n        }\n    }\n    return score;\n}\n\nlong long calcPotential(int g[N][N], int turn) {\n    if (turn >= 100) return 0;\n    int nextFlavor = f[turn + 1];\n    long long potential = 0;\n    int dr[] = {-1, 1, 0, 0}, dc[] = {0, 0, -1, 1};\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (g[r][c] == 0) {\n                for (int d = 0; d < 4; d++) {\n                    int nr = r + dr[d], nc = c + dc[d];\n                    if (nr >= 0 && nr < N && nc >= 0 && nc < N && g[nr][nc] == nextFlavor) {\n                        potential++; break;\n                    }\n                }\n            }\n        }\n    }\n    // Also count adjacency within same flavor groups\n    for (int r = 0; r < N; r++) {\n        for (int c = 0; c < N; c++) {\n            if (g[r][c]) {\n                if (r + 1 < N && g[r+1][c] == g[r][c]) potential++;\n                if (c + 1 < N && g[r][c+1] == g[r][c]) potential++;\n            }\n        }\n    }\n    return potential;\n}\n\nlong long simulate(int start_t, int orig_g[N][N]) {\n    int g[N][N];\n    memcpy(g, orig_g, sizeof(g));\n    for (int t = start_t; t <= 100; t++) {\n        pair<int,int> empty_cells[100];\n        int cnt = 0;\n        for (int r = 0; r < N; r++)\n            for (int c = 0; c < N; c++)\n                if (g[r][c] == 0) empty_cells[cnt++] = {r, c};\n        if (cnt == 0) break;\n        int idx = rng() % cnt;\n        g[empty_cells[idx].first][empty_cells[idx].second] = f[t];\n        // Greedy tilt in simulation\n        long long best = -1; int best_d = 1;\n        int saved[N][N];\n        for (int d = 0; d < 4; d++) {\n            memcpy(saved, g, sizeof(g));\n            tiltGrid(g, d);\n            long long sc = calcScore(g);\n            if (sc > best) { best = sc; best_d = d; }\n            memcpy(g, saved, sizeof(g));\n        }\n        tiltGrid(g, best_d);\n    }\n    return calcScore(g);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 1; i <= 100; i++) cin >> f[i];\n    memset(grid, 0, sizeof(grid));\n    \n    string dirs = \"FBLR\";\n    int priority[] = {4, 1, 2, 3}; // B > L > R > F\n    \n    for (int t = 1; t <= 100; t++) {\n        int p; cin >> p;\n        int pos = 1, pr = -1, pc = -1;\n        for (int r = 0; r < N && pr == -1; r++)\n            for (int c = 0; c < N && pr == -1; c++)\n                if (grid[r][c] == 0) { if (pos == p) { pr = r; pc = c; } pos++; }\n        grid[pr][pc] = f[t];\n        \n        long long scores[4], pot[4];\n        int saved[N][N];\n        for (int d = 0; d < 4; d++) {\n            memcpy(saved, grid, sizeof(grid));\n            tiltGrid(grid, d);\n            scores[d] = calcScore(grid);\n            pot[d] = calcPotential(grid, t);\n            memcpy(grid, saved, sizeof(grid));\n        }\n        \n        long long maxScore = *max_element(scores, scores + 4);\n        vector<int> cands;\n        for (int d = 0; d < 4; d++) if (scores[d] == maxScore) cands.push_back(d);\n        \n        int best_dir;\n        if (cands.size() == 1) {\n            best_dir = cands[0];\n        } else {\n            // Use potential to narrow down\n            long long maxPot = -1;\n            for (int d : cands) maxPot = max(maxPot, pot[d]);\n            vector<int> cands2;\n            for (int d : cands) if (pot[d] == maxPot) cands2.push_back(d);\n            \n            if (cands2.size() == 1) {\n                best_dir = cands2[0];\n            } else if (t < 85) {\n                // Monte Carlo tiebreak\n                int num_sims = max(10, 50 - t / 3);\n                long long mc[4] = {};\n                for (int d : cands2) {\n                    int temp[N][N];\n                    memcpy(temp, grid, sizeof(grid));\n                    tiltGrid(temp, d);\n                    for (int s = 0; s < num_sims; s++) mc[d] += simulate(t + 1, temp);\n                }\n                best_dir = cands2[0];\n                for (int d : cands2) if (mc[d] > mc[best_dir]) best_dir = d;\n            } else {\n                best_dir = *min_element(cands2.begin(), cands2.end(), [&](int a, int b) { return priority[a] < priority[b]; });\n            }\n        }\n        \n        tiltGrid(grid, best_dir);\n        cout << dirs[best_dir] << '\\n';\n        cout.flush();\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M; double eps;\n    cin >> M >> eps;\n    \n    int N;\n    {\n        double f = sqrt(max(eps * (1.0 - eps), 0.001));\n        N = (int)round(2.5 * M * f + sqrt(2.0 * M) + 3);\n        N = max(4, min(100, N));\n    }\n    \n    int maxE = N * (N - 1) / 2;\n    mt19937 rng(42);\n    \n    auto eidx = [&](int i, int j) -> int {\n        if (i > j) swap(i, j);\n        return i * (2 * N - i - 1) / 2 + (j - i - 1);\n    };\n    \n    auto sortedDeg = [&](const string& g) -> vector<int> {\n        vector<int> d(N, 0);\n        for (int i = 0; i < N; i++)\n            for (int j = i + 1; j < N; j++) {\n                if (g[i * (2*N-i-1)/2 + (j-i-1)] == '1') { d[i]++; d[j]++; }\n            }\n        sort(d.begin(), d.end());\n        return d;\n    };\n    \n    int NC = min(2000, max(M * 10, 500));\n    vector<string> cands(NC, string(maxE, '0'));\n    vector<vector<int>> cdeg(NC);\n    \n    for (int c = 0; c < NC; c++) {\n        string g(maxE, '0');\n        if (c < NC / 3) {\n            double dens = (c + 1.0) / (NC / 3 + 1);\n            int te = max(0, min(maxE, (int)round(dens * maxE)));\n            vector<int> p(maxE); iota(p.begin(), p.end(), 0);\n            shuffle(p.begin(), p.end(), rng);\n            for (int i = 0; i < te; i++) g[p[i]] = '1';\n        } else if (c < 2 * NC / 3) {\n            int code = c - NC / 3;\n            vector<int> b(N, 0);\n            int numOnes = code / max(1, (NC / 3 / N)) + 1;\n            int offset = code % max(1, (NC / 3 / N));\n            for (int i = 0; i < min(numOnes, N); i++) {\n                int pos = (offset + i * (N / max(numOnes, 1))) % N;\n                b[pos] = 1;\n            }\n            for (int j = 0; j < N; j++)\n                if (b[j])\n                    for (int i = 0; i < j; i++)\n                        g[eidx(i, j)] = '1';\n        } else {\n            int code = c - 2 * NC / 3;\n            int cliqueSz = (code / max(1, NC / 3 / N)) + 1;\n            cliqueSz = min(cliqueSz, N);\n            int crossE = code % max(1, NC / 3 / N);\n            for (int i = 0; i < cliqueSz; i++)\n                for (int j = i + 1; j < cliqueSz; j++)\n                    g[eidx(i, j)] = '1';\n            int added = 0;\n            for (int i = 0; i < cliqueSz && added < crossE; i++)\n                for (int j = cliqueSz; j < N && added < crossE; j++) {\n                    g[eidx(i, j)] = '1'; added++;\n                }\n        }\n        cands[c] = g;\n        cdeg[c] = sortedDeg(g);\n    }\n    \n    vector<vector<double>> fp(NC, vector<double>(N));\n    for (int c = 0; c < NC; c++)\n        for (int i = 0; i < N; i++)\n            fp[c][i] = cdeg[c][i] * (1.0 - 2.0 * eps) + (N - 1) * eps;\n    \n    vector<int> sel;\n    vector<double> minD(NC, 1e18);\n    vector<bool> used(NC, false);\n    \n    sel.push_back(0); used[0] = true;\n    for (int c = 0; c < NC; c++) {\n        double d = 0;\n        for (int i = 0; i < N; i++) { double df = fp[c][i] - fp[0][i]; d += df * df; }\n        minD[c] = d;\n    }\n    \n    for (int k = 1; k < M; k++) {\n        int best = -1; double bestD = -1;\n        for (int c = 0; c < NC; c++) {\n            if (used[c]) continue;\n            if (minD[c] > bestD) { bestD = minD[c]; best = c; }\n        }\n        sel.push_back(best); used[best] = true;\n        for (int c = 0; c < NC; c++) {\n            if (used[c]) continue;\n            double d = 0;\n            for (int i = 0; i < N; i++) { double df = fp[c][i] - fp[best][i]; d += df * df; }\n            minD[c] = min(minD[c], d);\n        }\n    }\n    \n    // Precompute adjacency matrices for Hamming distance decoding\n    vector<vector<int>> adjM(M, vector<int>(maxE));\n    vector<vector<double>> gfp(M, vector<double>(N));\n    for (int k = 0; k < M; k++) {\n        gfp[k] = fp[sel[k]];\n        for (int e = 0; e < maxE; e++) adjM[k][e] = (cands[sel[k]][e] == '1') ? 1 : 0;\n    }\n    \n    cout << N << \"\\n\";\n    for (int k = 0; k < M; k++) cout << cands[sel[k]] << \"\\n\";\n    cout.flush();\n    \n    double dVar = max(1.0, (N - 1.0) * eps * (1.0 - eps));\n    \n    for (int q = 0; q < 100; q++) {\n        string H; cin >> H;\n        vector<int> hd = sortedDeg(H);\n        \n        // Primary: fingerprint distance\n        int bestK = 0; double bestS = -1e18;\n        for (int k = 0; k < M; k++) {\n            double s = 0;\n            for (int i = 0; i < N; i++) {\n                double diff = hd[i] - gfp[k][i];\n                s -= diff * diff / (2.0 * dVar);\n            }\n            if (s > bestS) { bestS = s; bestK = k; }\n        }\n        \n        cout << bestK << \"\\n\";\n        cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\ntypedef pair<ll,int> pli;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,D,K; cin>>N>>M>>D>>K;\n    vector<int> u(M),v(M),w(M);\n    vector<vector<pair<int,int>>> adj(N);\n    for(int i=0;i<M;i++){cin>>u[i]>>v[i]>>w[i];u[i]--;v[i]--;adj[u[i]].push_back({i,v[i]});adj[v[i]].push_back({i,u[i]});}\n    vector<int> x(N),y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n\n    int S=min(N,100);\n    vector<double> betw(M,0);\n    for(int si=0;si<S;si++){\n        int s=(ll)si*N/S;\n        vector<ll> dist(N,LLONG_MAX);vector<int> pe(N,-1);\n        dist[s]=0;priority_queue<pli,vector<pli>,greater<pli>> pq;pq.push({0,s});\n        while(!pq.empty()){auto[d,nd]=pq.top();pq.pop();if(d>dist[nd])continue;for(auto[ei,nx]:adj[nd]){ll nd2=d+w[ei];if(nd2<dist[nx]){dist[nx]=nd2;pe[nx]=ei;pq.push({nd2,nx});}}}\n        vector<int> ss(N,1);vector<vector<int>> ch(N);\n        for(int t=0;t<N;t++){if(t==s||pe[t]==-1)continue;int o=(u[pe[t]]==t)?v[pe[t]]:u[pe[t]];ch[o].push_back(t);}\n        vector<int> ord={s};for(int i=0;i<(int)ord.size();i++)for(int c:ch[ord[i]])ord.push_back(c);\n        for(int i=(int)ord.size()-1;i>0;i--){int nd=ord[i];int o=(u[pe[nd]]==nd)?v[pe[nd]]:u[pe[nd]];ss[o]+=ss[nd];}\n        for(int t=0;t<N;t++){if(t==s||pe[t]==-1)continue;betw[pe[t]]+=ss[t];}\n    }\n\n    vector<vector<ll>> apsp(N,vector<ll>(N,LLONG_MAX));\n    for(int s=0;s<N;s++){apsp[s][s]=0;priority_queue<pli,vector<pli>,greater<pli>> pq;pq.push({0,s});\n    while(!pq.empty()){auto[d,nd]=pq.top();pq.pop();if(d>apsp[s][nd])continue;for(auto[ei,nx]:adj[nd]){ll nd2=d+w[ei];if(nd2<apsp[s][nx]){apsp[s][nx]=nd2;pq.push({nd2,nx});}}}}\n\n    vector<ll> det(M,0);\n    for(int ei=0;ei<M;ei++){ll best=LLONG_MAX;for(auto[ej,an]:adj[u[ei]]){if(ej==ei)continue;if(apsp[an][v[ei]]<LLONG_MAX)best=min(best,(ll)w[ej]+apsp[an][v[ei]]);}for(auto[ej,bn]:adj[v[ei]]){if(ej==ei)continue;if(apsp[bn][u[ei]]<LLONG_MAX)best=min(best,(ll)w[ej]+apsp[bn][u[ei]]);}if(best<LLONG_MAX)det[ei]=max(0LL,best-apsp[u[ei]][v[ei]]);}\n\n    vector<double> impact(M);\n    for(int i=0;i<M;i++) impact[i]=betw[i]*(double)det[i];\n\n    vector<vector<int>> conflicts(M);\n    vector<ll> dist(N);vector<int> pe(N);\n    for(int ei=0;ei<M;ei++){\n        fill(dist.begin(),dist.end(),LLONG_MAX);fill(pe.begin(),pe.end(),-1);\n        dist[u[ei]]=0;priority_queue<pli,vector<pli>,greater<pli>> pq;pq.push({0,u[ei]});\n        while(!pq.empty()){auto[d,nd]=pq.top();pq.pop();if(d>dist[nd])continue;for(auto[ej,nx]:adj[nd]){if(ej==ei)continue;ll nd2=d+w[ej];if(nd2<dist[nx]){dist[nx]=nd2;pe[nx]=ej;pq.push({nd2,nx});}}}\n        if(dist[v[ei]]<LLONG_MAX){int cur=v[ei];while(cur!=u[ei]&&pe[cur]!=-1){int e=pe[cur];conflicts[ei].push_back(e);int other=(u[e]==cur)?v[e]:u[e];cur=other;}}\n    }\n    for(int ei=0;ei<M;ei++)for(int ej:conflicts[ei])conflicts[ej].push_back(ei);\n    for(int i=0;i<N;i++)for(int j=0;j<(int)adj[i].size();j++)for(int k=j+1;k<(int)adj[i].size();k++){int ej=adj[i][j].first,ek=adj[i][k].first;conflicts[ej].push_back(ek);conflicts[ek].push_back(ej);}\n    for(int i=0;i<M;i++){sort(conflicts[i].begin(),conflicts[i].end());conflicts[i].erase(unique(conflicts[i].begin(),conflicts[i].end()),conflicts[i].end());}\n\n    vector<int> order(M);iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),[&](int a,int b){return impact[a]>impact[b];});\n\n    vector<int> r(M,-1),dc(D,0);vector<double> day_imp(D,0);\n    for(int ei:order){\n        double bs=1e18;int bd=-1;\n        for(int d=0;d<D;d++){if(dc[d]>=K)continue;double sc=0;for(int ej:conflicts[ei])if(r[ej]==d)sc+=impact[ei]*impact[ej];sc+=day_imp[d]*1e-4;if(sc<bs){bs=sc;bd=d;}}\n        if(bd==-1)for(int d=0;d<D;d++)if(dc[d]<K&&(bd==-1||dc[d]<dc[bd]))bd=d;\n        r[ei]=bd;dc[bd]++;day_imp[bd]+=impact[ei];\n    }\n\n    auto t0=chrono::high_resolution_clock::now();mt19937 rng(42);\n    while(true){auto now=chrono::high_resolution_clock::now();if(chrono::duration<double>(now-t0).count()>5.0)break;\n    int ei=rng()%M;int od=r[ei];double cs=0;for(int ej:conflicts[ei])if(r[ej]==od)cs+=impact[ei]*impact[ej];\n    int bd=-1;double bi=0;for(int d=0;d<D;d++){if(d==od||dc[d]>=K)continue;double ns=0;for(int ej:conflicts[ei])if(r[ej]==d)ns+=impact[ei]*impact[ej];double imp=cs-ns+((day_imp[od]-impact[ei])-(day_imp[d]+impact[ei]))*1e-4;if(imp>bi){bi=imp;bd=d;}}\n    if(bd!=-1){r[ei]=bd;dc[od]--;dc[bd]++;day_imp[od]-=impact[ei];day_imp[bd]+=impact[ei];}}\n\n    for(int i=0;i<M;i++)cout<<r[i]+1<<\" \\n\"[i==M-1];\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <tuple>\n#include <climits>\n#include <map>\n#include <set>\n#include <chrono>\nusing namespace std;\nint D;\nusing Point=tuple<int,int,int>;\nusing Array3D=vector<vector<vector<int>>>;\n\nchrono::high_resolution_clock::time_point start_time;\n\nvector<string> readSil(){vector<string>s(D);for(int i=0;i<D;i++)cin>>s[i];return s;}\nArray3D buildMF(const vector<string>&f,const vector<string>&r){Array3D b(D,vector<vector<int>>(D,vector<int>(D,0)));for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)if(f[z][x]=='1'&&r[z][y]=='1')b[x][y][z]=1;return b;}\n\nvector<vector<Point>> findComp(const Array3D&b){\n    Array3D vis(D,vector<vector<int>>(D,vector<int>(D,0)));vector<vector<Point>>cs;\n    const int dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};\n    for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n        if(b[x][y][z]&&!vis[x][y][z]){vector<Point>c;queue<Point>q;q.push({x,y,z});vis[x][y][z]=1;\n            while(!q.empty()){auto[cx,cy,cz]=q.front();q.pop();c.push_back({cx,cy,cz});\n                for(int d=0;d<6;d++){int nx=cx+dx[d],ny=cy+dy[d],nz=cz+dz[d];\n                    if(0<=nx&&nx<D&&0<=ny&&ny<D&&0<=nz&&nz<D&&b[nx][ny][nz]&&!vis[nx][ny][nz]){vis[nx][ny][nz]=1;q.push({nx,ny,nz});}}}\n            cs.push_back(move(c));}}\n    return cs;\n}\n\nvector<vector<vector<int>>> genRots(){\n    vector<vector<vector<int>>>rots;int B[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};\n    for(int i=0;i<6;i++)for(int j=0;j<6;j++){if(i/2==j/2)continue;int cr[3];\n        cr[0]=B[i][1]*B[j][2]-B[i][2]*B[j][1];cr[1]=B[i][2]*B[j][0]-B[i][0]*B[j][2];cr[2]=B[i][0]*B[j][1]-B[i][1]*B[j][0];\n        int dt=B[i][0]*(B[j][1]*cr[2]-B[j][2]*cr[1])-B[i][1]*(B[j][0]*cr[2]-B[j][2]*cr[0])+B[i][2]*(B[j][0]*cr[1]-B[j][1]*cr[0]);\n        if(dt!=1)continue;rots.push_back({{B[i][0],B[i][1],B[i][2]},{B[j][0],B[j][1],B[j][2]},{cr[0],cr[1],cr[2]}});}\n    return rots;\n}\n\nPoint appR(const vector<vector<int>>&M,const Point&p){auto[x,y,z]=p;return{M[0][0]*x+M[0][1]*y+M[0][2]*z,M[1][0]*x+M[1][1]*y+M[1][2]*z,M[2][0]*x+M[2][1]*y+M[2][2]*z};}\n\nvector<Point>canon(const vector<Point>&comp,const vector<vector<vector<int>>>&rots){vector<Point>best;for(auto&M:rots){vector<Point>r;for(auto&p:comp)r.push_back(appR(M,p));int mX=INT_MAX,mY=INT_MAX,mZ=INT_MAX;for(auto&[x,y,z]:r){mX=min(mX,x);mY=min(mY,y);mZ=min(mZ,z);}for(auto&[x,y,z]:r){x-=mX;y-=mY;z-=mZ;}sort(r.begin(),r.end());if(best.empty()||r<best)best=r;}return best;}\n\nvector<vector<Point>> findSubComp(const vector<Point>&vox){set<Point>vs(vox.begin(),vox.end());map<Point,int>vis;vector<vector<Point>>cs;const int dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};for(auto&p:vox){if(vis.count(p))continue;vector<Point>c;queue<Point>q;q.push(p);vis[p]=1;while(!q.empty()){auto[cx,cy,cz]=q.front();q.pop();c.push_back({cx,cy,cz});for(int d=0;d<6;d++){Point np={cx+dx[d],cy+dy[d],cz+dz[d]};if(vs.count(np)&&!vis.count(np)){vis[np]=1;q.push(np);}}}cs.push_back(move(c));}return cs;}\n\nvoid doPartial(Array3D& asrc, Array3D& atgt, const Array3D& bsrc, const Array3D& btgt, const vector<vector<vector<int>>>& rots, int& nextId) {\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 5000) break;\n        \n        Array3D us(D, vector<vector<int>>(D, vector<int>(D, 0)));\n        for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) \n            if(bsrc[x][y][z] && !asrc[x][y][z]) us[x][y][z]=1;\n        \n        auto srcC = findComp(us);\n        sort(srcC.begin(), srcC.end(), [](auto& a, auto& b){return a.size() > b.size();});\n        \n        bool found_match = false;\n        for (auto& comp : srcC) {\n            if (comp.size() < 2) continue;\n            \n            vector<Point> tuv;\n            for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) \n                if(btgt[x][y][z] && !atgt[x][y][z]) tuv.push_back({x,y,z});\n            if (tuv.empty()) return;\n            \n            int bestO = 1, bestRi = -1, bestTx = 0, bestTy = 0, bestTz = 0;\n            const int OFF = 15, S = 30;\n            \n            for (int ri = 0; ri < (int)rots.size(); ri++) {\n                vector<Point> rot;\n                for (auto& p : comp) rot.push_back(appR(rots[ri], p));\n                int mX=INT_MAX, mY=INT_MAX, mZ=INT_MAX;\n                for (auto& [x,y,z] : rot) { mX=min(mX,x); mY=min(mY,y); mZ=min(mZ,z); }\n                for (auto& [x,y,z] : rot) { x-=mX; y-=mY; z-=mZ; }\n                \n                vector<int> tc(S*S*S, 0);\n                for (auto& [sx,sy,sz] : rot) \n                    for (auto& [px,py,pz] : tuv) {\n                        int kx = px-sx + OFF, ky = py-sy + OFF, kz = pz-sz + OFF;\n                        tc[kx + ky*S + kz*S*S]++;\n                    }\n                for (int kz=0; kz<S; kz++) for (int ky=0; ky<S; ky++) for (int kx=0; kx<S; kx++) {\n                    int cnt = tc[kx + ky*S + kz*S*S];\n                    if (cnt > bestO) { bestO = cnt; bestRi = ri; bestTx = kx-OFF; bestTy = ky-OFF; bestTz = kz-OFF; }\n                }\n            }\n            \n            if (bestRi != -1) {\n                vector<Point> rot;\n                for (auto& p : comp) rot.push_back(appR(rots[bestRi], p));\n                int mX=INT_MAX, mY=INT_MAX, mZ=INT_MAX;\n                for (auto& [x,y,z] : rot) { mX=min(mX,x); mY=min(mY,y); mZ=min(mZ,z); }\n                for (auto& [x,y,z] : rot) { x-=mX; y-=mY; z-=mZ; }\n                \n                vector<Point> so, to;\n                for (int i=0; i<(int)comp.size(); i++) {\n                    auto [rx,ry,rz] = rot[i];\n                    int tx=rx+bestTx, ty=ry+bestTy, tz=rz+bestTz;\n                    if (0<=tx&&tx<D && 0<=ty&&ty<D && 0<=tz&&tz<D && btgt[tx][ty][tz] && !atgt[tx][ty][tz]) {\n                        so.push_back(comp[i]); to.push_back({tx,ty,tz});\n                    }\n                }\n                auto scs = findSubComp(so);\n                map<Point, int> s2i; for (int i=0; i<(int)so.size(); i++) s2i[so[i]] = i;\n                \n                for (auto& sc : scs) {\n                    if (sc.size() < 2) continue;\n                    found_match = true;\n                    int id = nextId++;\n                    for (auto& p : sc) {\n                        int i = s2i[p];\n                        auto [sx,sy,sz] = so[i]; auto [tx,ty,tz] = to[i];\n                        asrc[sx][sy][sz] = id; atgt[tx][ty][tz] = id;\n                    }\n                }\n            }\n            if (found_match) break;\n        }\n        if (!found_match) break;\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    start_time = chrono::high_resolution_clock::now();\n    cin >> D;\n    vector<vector<string>> f(2), r(2);\n    for (int i = 0; i < 2; i++) { f[i] = readSil(); r[i] = readSil(); }\n    \n    auto rots = genRots();\n    auto b0 = buildMF(f[0], r[0]), b1 = buildMF(f[1], r[1]);\n    Array3D a0(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    Array3D a1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    int nid = 1;\n    \n    auto c0 = findComp(b0), c1 = findComp(b1);\n    int n0 = c0.size(), n1 = c1.size();\n    map<vector<Point>, vector<int>> cm1;\n    for (int j=0; j<n1; j++) cm1[canon(c1[j], rots)].push_back(j);\n    \n    vector<int> o0(n0); for (int i=0; i<n0; i++) o0[i] = i;\n    sort(o0.begin(), o0.end(), [&](int a, int b){return c0[a].size() > c0[b].size();});\n    \n    vector<bool> u1(n1, false);\n    for (int i : o0) {\n        auto cn = canon(c0[i], rots);\n        auto it = cm1.find(cn);\n        if (it != cm1.end()) for (int j : it->second) if (!u1[j]) {\n            int id = nid++;\n            for (auto [x,y,z] : c0[i]) a0[x][y][z] = id;\n            for (auto [x,y,z] : c1[j]) a1[x][y][z] = id;\n            u1[j] = true; break;\n        }\n    }\n    \n    doPartial(a0, a1, b0, b1, rots, nid);\n    doPartial(a1, a0, b1, b0, rots, nid);\n    \n    Array3D u0(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    Array3D un1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (b0[x][y][z] && !a0[x][y][z]) u0[x][y][z] = 1;\n        if (b1[x][y][z] && !a1[x][y][z]) un1[x][y][z] = 1;\n    }\n    \n    Array3D isct(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++)\n        if(u0[x][y][z] && un1[x][y][z]) isct[x][y][z] = 1;\n    for (auto& c : findComp(isct)) {\n        int id = nid++;\n        for (auto [x,y,z] : c) { a0[x][y][z] = id; a1[x][y][z] = id; u0[x][y][z] = 0; un1[x][y][z] = 0; }\n    }\n    \n    for (auto& c : findComp(u0)) { int id = nid++; for (auto [x,y,z] : c) a0[x][y][z] = id; }\n    for (auto& c : findComp(un1)) { int id = nid++; for (auto [x,y,z] : c) a1[x][y][z] = id; }\n    \n    cout << nid - 1 << \"\\n\";\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) { if(x||y||z) cout<<\" \"; cout<<a0[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++) { if(x||y||z) cout<<\" \"; cout<<a1[x][y][z]; }\n    cout << \"\\n\";\n    return 0;\n}","ahc020":"#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, K;\n    cin >> N >> M >> K;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<vector<pair<int, int>>> adj(N);\n    vector<int> eu(M), ev(M), ew(M);\n    for (int j = 0; j < M; j++) {\n        cin >> eu[j] >> ev[j] >> ew[j];\n        eu[j]--; ev[j]--;\n        adj[eu[j]].push_back({ev[j], j});\n        adj[ev[j]].push_back({eu[j], j});\n    }\n    \n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    const int PMAX = 5000;\n    const long long PMAXSQ = (long long)PMAX * PMAX;\n    \n    vector<vector<long long>> rsq(K, vector<long long>(N));\n    for (int k = 0; k < K; k++)\n        for (int i = 0; i < N; i++) {\n            long long dx = a[k] - x[i], dy = b[k] - y[i];\n            rsq[k][i] = dx * dx + dy * dy;\n        }\n    \n    // Only include vertices within P_MAX range\n    vector<vector<int>> clo(K);\n    for (int k = 0; k < K; k++) {\n        vector<pair<long long, int>> v;\n        for (int i = 0; i < N; i++)\n            if (rsq[k][i] <= PMAXSQ) v.push_back({rsq[k][i], i});\n        sort(v.begin(), v.end());\n        for (int j = 0; j < min(15, (int)v.size()); j++)\n            clo[k].push_back(v[j].second);\n    }\n    \n    // Dijkstra from vertex 0\n    vector<long long> sp(N, LLONG_MAX);\n    vector<int> par(N, -1), pe(N, -1);\n    sp[0] = 0;\n    priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n    pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > sp[u]) continue;\n        for (auto [v, e] : adj[u])\n            if (sp[u] + ew[e] < sp[v]) {\n                sp[v] = sp[u] + ew[e];\n                par[v] = u; pe[v] = e;\n                pq.push({sp[v], v});\n            }\n    }\n    \n    vector<vector<int>> pth(N);\n    for (int i = 1; i < N; i++) {\n        int c = i;\n        while (c) { pth[i].push_back(pe[c]); c = par[c]; }\n    }\n    \n    auto calcP = [PMAX](long long sq) -> int {\n        if (sq <= 0) return 0;\n        int p = max(1, (int)ceil(sqrt((double)sq) - 1e-9));\n        while ((long long)p * p < sq) p++;\n        return min(p, PMAX);\n    };\n    \n    // Initial assignment: closest vertex\n    vector<int> asgn(K);\n    vector<vector<int>> vr(N);\n    vector<long long> vmx(N, 0);\n    for (int k = 0; k < K; k++) {\n        asgn[k] = clo[k][0];\n        vr[asgn[k]].push_back(k);\n        vmx[asgn[k]] = max(vmx[asgn[k]], rsq[k][asgn[k]]);\n    }\n    \n    vector<int> P(N);\n    long long pcost = 0;\n    for (int i = 0; i < N; i++) { P[i] = calcP(vmx[i]); pcost += (long long)P[i] * P[i]; }\n    \n    vector<int> eref(M, 0);\n    long long ecost = 0;\n    for (int i = 1; i < N; i++)\n        if (P[i] > 0)\n            for (int e : pth[i]) { if (!eref[e]) ecost += ew[e]; eref[e]++; }\n    \n    long long cost = pcost + ecost;\n    vector<int> best_P = P, best_asgn = asgn, best_eref = eref;\n    long long best_cost = cost;\n    \n    mt19937 rng(42);\n    uniform_real_distribution<> unif(0.0, 1.0);\n    auto t0 = chrono::high_resolution_clock::now();\n    \n    for (int it = 0; ; it++) {\n        double el = chrono::duration<double>(chrono::high_resolution_clock::now() - t0).count();\n        if (el > 1.5) break;\n        double temp = 3e6 * pow(0.001, el / 1.5);\n        \n        int k = rng() % K;\n        int ov = asgn[k];\n        int nv = clo[k][rng() % clo[k].size()];\n        if (nv == ov) continue;\n        \n        long long nmx_ov = 0;\n        for (int r : vr[ov]) if (r != k) nmx_ov = max(nmx_ov, rsq[r][ov]);\n        int nPov = calcP(nmx_ov);\n        long long nmx_nv = max(vmx[nv], rsq[k][nv]);\n        int nPnv = calcP(nmx_nv);\n        \n        long long dpc = (long long)nPov * nPov - (long long)P[ov] * P[ov]\n                      + (long long)nPnv * nPnv - (long long)P[nv] * P[nv];\n        \n        long long old_ecost = ecost;\n        if (P[ov] > 0 && nPov == 0)\n            for (int e : pth[ov]) { eref[e]--; if (!eref[e]) ecost -= ew[e]; }\n        if (P[nv] == 0 && nPnv > 0)\n            for (int e : pth[nv]) { if (!eref[e]) ecost += ew[e]; eref[e]++; }\n        \n        long long nc = pcost + dpc + ecost;\n        if (nc < cost || unif(rng) < exp(-(double)(nc - cost) / temp)) {\n            vr[ov].erase(find(vr[ov].begin(), vr[ov].end(), k));\n            vr[nv].push_back(k);\n            vmx[ov] = nmx_ov; vmx[nv] = nmx_nv;\n            P[ov] = nPov; P[nv] = nPnv;\n            pcost += dpc; asgn[k] = nv; cost = nc;\n            if (cost < best_cost) {\n                best_cost = cost; best_P = P; best_asgn = asgn; best_eref = eref;\n            }\n        } else {\n            // Revert edge changes\n            if (P[nv] == 0 && nPnv > 0)\n                for (int e : pth[nv]) { eref[e]--; if (!eref[e]) ecost -= ew[e]; }\n            if (P[ov] > 0 && nPov == 0)\n                for (int e : pth[ov]) { if (!eref[e]) ecost += ew[e]; eref[e]++; }\n        }\n    }\n    \n    // Restore best state\n    P = best_P; asgn = best_asgn; eref = best_eref;\n    pcost = 0; for (int i = 0; i < N; i++) pcost += (long long)P[i] * P[i];\n    ecost = 0; for (int j = 0; j < M; j++) if (eref[j] > 0) ecost += ew[j];\n    \n    // Steiner tree via SPH (Shortest Path Heuristic)\n    vector<int> terms = {0};\n    for (int i = 1; i < N; i++) if (P[i] > 0) terms.push_back(i);\n    int T = terms.size();\n    \n    if (T > 1) {\n        vector<bool> in_tree(N, false);\n        in_tree[0] = true;\n        \n        set<int> rem;\n        for (int t = 1; t < T; t++) rem.insert(terms[t]);\n        \n        vector<int> neref(M, 0);\n        long long necost = 0;\n        \n        while (!rem.empty()) {\n            vector<long long> dist(N, LLONG_MAX);\n            vector<int> prev(N, -1), preve(N, -1);\n            priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq2;\n            for (int v = 0; v < N; v++) if (in_tree[v]) { dist[v] = 0; pq2.push({0, v}); }\n            while (!pq2.empty()) {\n                auto [d, u] = pq2.top(); pq2.pop();\n                if (d > dist[u]) continue;\n                for (auto [v, e] : adj[u])\n                    if (dist[u] + ew[e] < dist[v]) {\n                        dist[v] = dist[u] + ew[e];\n                        prev[v] = u; preve[v] = e;\n                        pq2.push({dist[v], v});\n                    }\n            }\n            \n            long long bd = LLONG_MAX; int bt = -1;\n            for (int t : rem) if (dist[t] < bd) { bd = dist[t]; bt = t; }\n            \n            int v = bt;\n            while (v != -1 && !in_tree[v]) {\n                int e = preve[v];\n                if (!neref[e]) necost += ew[e];\n                neref[e]++;\n                in_tree[v] = true;\n                v = prev[v];\n            }\n            rem.erase(bt);\n        }\n        \n        if (necost < ecost) { eref = neref; ecost = necost; }\n    }\n    \n    for (int i = 0; i < N; i++) cout << P[i] << \" \\n\"[i == N - 1];\n    for (int j = 0; j < M; j++) cout << (eref[j] > 0 ? 1 : 0) << \" \\n\"[j == M - 1];\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint grid[N][N];\nvector<array<int, 4>> swaps;\n\nint main() {\n    ios_base::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 >> grid[x][y];\n    \n    auto siftDown = [&](int x, int y) {\n        while (x < N - 1) {\n            int lv = grid[x+1][y], rv = grid[x+1][y+1], cv = grid[x][y];\n            if (cv <= lv && cv <= rv) break;\n            if (lv <= rv) {\n                swap(grid[x][y], grid[x+1][y]);\n                swaps.push_back({x, y, x+1, y});\n                x++;\n            } else {\n                swap(grid[x][y], grid[x+1][y+1]);\n                swaps.push_back({x, y, x+1, y+1});\n                x++; y++;\n            }\n            if (swaps.size() >= 9999) return;\n        }\n    };\n    \n    // Heapify: bottom to top, full sift-down\n    for (int x = N - 2; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            siftDown(x, y);\n            if (swaps.size() >= 9999) goto done;\n        }\n    }\n    \n    // Iteratively fix remaining violations\n    // (caused by triangular grid's dual-parent structure)\n    for (int iter = 0; iter < 500; iter++) {\n        bool any = false;\n        for (int x = N - 2; x >= 0; x--) {\n            for (int y = 0; y <= x; y++) {\n                if (grid[x][y] > grid[x+1][y] || grid[x][y] > grid[x+1][y+1]) {\n                    any = true;\n                    // One-step fix: swap parent with smaller child\n                    if (grid[x+1][y] <= grid[x+1][y+1]) {\n                        swap(grid[x][y], grid[x+1][y]);\n                        swaps.push_back({x, y, x+1, y});\n                    } else {\n                        swap(grid[x][y], grid[x+1][y+1]);\n                        swaps.push_back({x, y, x+1, y+1});\n                    }\n                    if (swaps.size() >= 9999) goto done;\n                }\n            }\n        }\n        if (!any) break;\n    }\n    \ndone:\n    cout << swaps.size() << \"\\n\";\n    for (auto& s : swaps)\n        cout << s[0] << \" \" << s[1] << \" \" << s[2] << \" \" << s[3] << \"\\n\";\n    \n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <set>\n\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    vector<vector<bool>> is_obstacle(D, vector<bool>(D, false));\n    for (int i = 0; i < N; i++) {\n        int ri, rj;\n        cin >> ri >> rj;\n        is_obstacle[ri][rj] = true;\n    }\n    \n    int entrance_i = 0, entrance_j = (D - 1) / 2;\n    \n    // Precompute distances from entrance\n    vector<vector<int>> dist(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    q.push({entrance_i, entrance_j});\n    dist[entrance_i][entrance_j] = 0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    \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 (ni >= 0 && ni < D && nj >= 0 && nj < D && dist[ni][nj] == -1 && !is_obstacle[ni][nj]) {\n                dist[ni][nj] = dist[i][j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    int M = 0;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (!(i == entrance_i && j == entrance_j) && !is_obstacle[i][j])\n                M++;\n                \n    struct Cell {\n        int i, j;\n        int dist;\n        int current_degree;\n        bool removed;\n        int rank;\n    };\n    \n    vector<Cell> C(M);\n    vector<vector<int>> cell_index(D, vector<int>(D, -1));\n    \n    int idx = 0;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (!(i == entrance_i && j == entrance_j) && !is_obstacle[i][j]) {\n                C[idx].i = i;\n                C[idx].j = j;\n                C[idx].dist = dist[i][j];\n                C[idx].removed = false;\n                cell_index[i][j] = idx;\n                idx++;\n            }\n        }\n    }\n    \n    // Calculate internal degrees (only counting valid container neighbors)\n    for (int k = 0; k < M; k++) {\n        C[k].current_degree = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = C[k].i + di[d], nj = C[k].j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && cell_index[ni][nj] != -1) {\n                C[k].current_degree++;\n            }\n        }\n    }\n    \n    // Peeling algorithm to assign topological removal ranks\n    priority_queue<tuple<int, int, int, int>, vector<tuple<int, int, int, int>>, greater<tuple<int, int, int, int>>> pq;\n    \n    for (int k = 0; k < M; k++) {\n        if (C[k].current_degree <= 1) {\n            pq.push({C[k].dist, C[k].i, C[k].j, k});\n        }\n    }\n    \n    int current_rank = 0;\n    int removed_count = 0;\n    \n    while (removed_count < M) {\n        if (pq.empty()) {\n            // Break cycle by picking the remaining cell closest to the entrance\n            int best_k = -1;\n            for (int k = 0; k < M; k++) {\n                if (!C[k].removed) {\n                    if (best_k == -1 || tie(C[k].dist, C[k].i, C[k].j) < tie(C[best_k].dist, C[best_k].i, C[best_k].j)) {\n                        best_k = k;\n                    }\n                }\n            }\n            pq.push({C[best_k].dist, C[best_k].i, C[best_k].j, best_k});\n        }\n        \n        auto [d, i, j, k] = pq.top();\n        pq.pop();\n        \n        if (C[k].removed) continue;\n        \n        C[k].rank = current_rank++;\n        C[k].removed = true;\n        removed_count++;\n        \n        for (int dd = 0; dd < 4; dd++) {\n            int ni = C[k].i + di[dd], nj = C[k].j + dj[dd];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && cell_index[ni][nj] != -1) {\n                int nk = cell_index[ni][nj];\n                if (!C[nk].removed) {\n                    C[nk].current_degree--;\n                    if (C[nk].current_degree <= 1) {\n                        pq.push({C[nk].dist, C[nk].i, C[nk].j, nk});\n                    }\n                }\n            }\n        }\n    }\n    \n    // Placement phase\n    set<pair<int, int>> available_cells; // (Rank, index in C)\n    for (int k = 0; k < M; k++) {\n        available_cells.insert({C[k].rank, k});\n    }\n    \n    vector<vector<int>> container_at(D, vector<int>(D, -1));\n    vector<vector<bool>> is_empty(D, vector<bool>(D, true));\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (is_obstacle[i][j]) is_empty[i][j] = false;\n    \n    auto is_safe = [&](int exclude_i, int exclude_j) {\n        vector<vector<bool>> reachable(D, vector<bool>(D, false));\n        queue<pair<int, int>> bfs_q;\n        bfs_q.push({entrance_i, entrance_j});\n        reachable[entrance_i][entrance_j] = true;\n        int visited_count = 1; // includes entrance\n        \n        while (!bfs_q.empty()) {\n            auto [i, j] = bfs_q.front(); bfs_q.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D && !reachable[ni][nj] && is_empty[ni][nj] && !(ni == exclude_i && nj == exclude_j)) {\n                    reachable[ni][nj] = true;\n                    bfs_q.push({ni, nj});\n                    visited_count++;\n                }\n            }\n        }\n        return visited_count == (int)available_cells.size();\n    };\n    \n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        \n        vector<int> safe_indices;\n        for (auto& p : available_cells) {\n            int k = p.second;\n            if (is_safe(C[k].i, C[k].j)) {\n                safe_indices.push_back(k);\n            }\n        }\n        \n        int best_k = -1;\n        int best_diff = M + 1;\n        \n        auto it = lower_bound(safe_indices.begin(), safe_indices.end(), t, [&](int k, int val) {\n            return C[k].rank < val;\n        });\n        \n        if (it != safe_indices.end()) {\n            int diff = abs(C[*it].rank - t);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_k = *it;\n            } else if (diff == best_diff && C[*it].rank > C[best_k].rank) {\n                best_k = *it;\n            }\n        }\n        if (it != safe_indices.begin()) {\n            --it;\n            int diff = abs(C[*it].rank - t);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_k = *it;\n            } else if (diff == best_diff && C[*it].rank > C[best_k].rank) {\n                best_k = *it;\n            }\n        }\n        \n        available_cells.erase({C[best_k].rank, best_k});\n        cout << C[best_k].i << \" \" << C[best_k].j << endl;\n        container_at[C[best_k].i][C[best_k].j] = t;\n        is_empty[C[best_k].i][C[best_k].j] = false;\n    }\n    \n    // Transport phase: Greedily remove the smallest numbered accessible container\n    for (int iter = 0; iter < M; iter++) {\n        vector<vector<bool>> reachable(D, vector<bool>(D, false));\n        queue<pair<int, int>> bfs_q;\n        bfs_q.push({entrance_i, entrance_j});\n        reachable[entrance_i][entrance_j] = true;\n        \n        while (!bfs_q.empty()) {\n            auto [i, j] = bfs_q.front(); bfs_q.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D && !reachable[ni][nj] && is_empty[ni][nj]) {\n                    reachable[ni][nj] = true;\n                    bfs_q.push({ni, nj});\n                }\n            }\n        }\n        \n        int min_t = M + 1, min_i = -1, min_j = -1;\n        for (int i = 0; i < D; i++)\n            for (int j = 0; j < D; j++)\n                if (container_at[i][j] >= 0) {\n                    bool acc = false;\n                    for (int d = 0; d < 4; d++) {\n                        int ni = i + di[d], nj = j + dj[d];\n                        if (ni >= 0 && ni < D && nj >= 0 && nj < D && is_empty[ni][nj] && reachable[ni][nj]) {\n                            acc = true;\n                            break;\n                        }\n                    }\n                    if (acc && container_at[i][j] < min_t) {\n                        min_t = container_at[i][j];\n                        min_i = i; min_j = j;\n                    }\n                }\n        \n        cout << min_i << \" \" << min_j << endl;\n        is_empty[min_i][min_j] = true;\n        container_at[min_i][min_j] = -1;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int M = 100;\nconst int dx[] = {0, 0, 1, -1};\nconst int dy[] = {1, -1, 0, 0};\n\nint n, m;\nint grid[N][N], best_grid[N][N];\nint best_score;\nset<pair<int,int>> required_adj;\nint adj_cnt[M+1][M+1];\n\nbool valid(int x, int y) { return 0 <= x && x < n && 0 <= y && y < n; }\n\nvoid compute_init_adj() {\n    memset(adj_cnt, 0, sizeof(adj_cnt));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) {\n            if (j+1 < n && grid[i][j] != grid[i][j+1])\n                adj_cnt[min(grid[i][j],grid[i][j+1])][max(grid[i][j],grid[i][j+1])]++;\n            if (i+1 < n && grid[i][j] != grid[i+1][j])\n                adj_cnt[min(grid[i][j],grid[i+1][j])][max(grid[i][j],grid[i+1][j])]++;\n            if (i==0||i==n-1||j==0||j==n-1)\n                adj_cnt[0][grid[i][j]]++;\n        }\n    for (int a = 0; a <= m; a++)\n        for (int b = a; b <= m; b++)\n            if (adj_cnt[a][b] > 0) required_adj.insert({a,b});\n}\n\nbool check_c0_conn() {\n    bool has0 = false;\n    for (int i = 0; i < n && !has0; i++)\n        for (int j = 0; j < n && !has0; j++)\n            if (grid[i][j] == 0) has0 = true;\n    if (!has0) return true;\n    \n    vector<vector<bool>> vis(n, vector<bool>(n));\n    queue<pair<int,int>> q;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (grid[i][j] == 0 && (i==0||i==n-1||j==0||j==n-1))\n                { q.push({i,j}); vis[i][j] = true; }\n    \n    while (!q.empty()) {\n        auto [x,y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx=x+dx[d], ny=y+dy[d];\n            if (valid(nx,ny) && !vis[nx][ny] && grid[nx][ny]==0)\n                { vis[nx][ny] = true; q.push({nx,ny}); }\n        }\n    }\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (grid[i][j] == 0 && !vis[i][j]) return false;\n    return true;\n}\n\nbool can_change(int i, int j, int nc) {\n    int oc = grid[i][j];\n    if (oc == nc) return true;\n    if (nc != 0) {\n        bool found = false;\n        for (int d = 0; d < 4; d++) {\n            int ni=i+dx[d], nj=j+dy[d];\n            if (valid(ni,nj) && grid[ni][nj] == nc) { found = true; break; }\n        }\n        if (!found) return false;\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        if (valid(ni,nj)) {\n            int c = grid[ni][nj];\n            if (oc != c) delta[{min(oc,c),max(oc,c)}]--;\n            if (nc != c) delta[{min(nc,c),max(nc,c)}]++;\n        }\n    }\n    if (i==0||i==n-1||j==0||j==n-1) {\n        if (oc != 0) delta[{0,oc}]--;\n        if (nc != 0) delta[{0,nc}]++;\n    }\n    for (auto& [p,d] : delta) {\n        int ncnt = adj_cnt[p.first][p.second] + d;\n        if (ncnt > 0 && required_adj.find(p) == required_adj.end()) return false;\n        if (ncnt <= 0 && required_adj.find(p) != required_adj.end()) return false;\n    }\n    grid[i][j] = nc;\n    bool ok = check_c0_conn();\n    grid[i][j] = oc;\n    return ok;\n}\n\nvoid apply_change(int i, int j, int nc) {\n    int oc = grid[i][j];\n    for (int d = 0; d < 4; d++) {\n        int ni=i+dx[d], nj=j+dy[d];\n        if (valid(ni,nj)) {\n            int c = grid[ni][nj];\n            if (oc != c) adj_cnt[min(oc,c)][max(oc,c)]--;\n            if (nc != c) adj_cnt[min(nc,c)][max(nc,c)]++;\n        }\n    }\n    if (i==0||i==n-1||j==0||j==n-1) {\n        if (oc != 0) adj_cnt[0][oc]--;\n        if (nc != 0) adj_cnt[0][nc]++;\n    }\n    grid[i][j] = nc;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> n >> m;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) cin >> grid[i][j];\n    \n    compute_init_adj();\n    memcpy(best_grid, grid, sizeof(grid));\n    best_score = 2501;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (grid[i][j] == 0) best_score++;\n    \n    bool improved = true;\n    while (improved) {\n        improved = false;\n        for (int i = 0; i < n; i++)\n            for (int j = 0; j < n; j++)\n                if (grid[i][j] == 0) {\n                    for (int d = 0; d < 4; d++) {\n                        int ni=i+dx[d], nj=j+dy[d];\n                        if (valid(ni,nj) && grid[ni][nj] != 0)\n                            if (can_change(i, j, grid[ni][nj])) {\n                                apply_change(i, j, grid[ni][nj]);\n                                improved = true;\n                                break;\n                            }\n                    }\n                }\n    }\n    \n    int cnt0 = 0;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (grid[i][j] == 0) cnt0++;\n    if (cnt0+1 < best_score) {\n        best_score = cnt0+1;\n        memcpy(best_grid, grid, sizeof(grid));\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << best_grid[i][j];\n            if (j < n-1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\nint N, D, Q;\nint qc = 0;\nint cmp[105][105];\n\nchar do_query(int a, int b) {\n    if (cmp[a][b] == -1) return '<';\n    if (cmp[a][b] == 1) return '>';\n    if (cmp[a][b] == 2) return '=';\n    if (qc >= Q) return '=';\n    qc++;\n    cout << \"1 1 \" << a << \" \" << b << endl;\n    char res; cin >> res;\n    if (res == '<') { cmp[a][b] = -1; cmp[b][a] = 1; }\n    else if (res == '>') { cmp[a][b] = 1; cmp[b][a] = -1; }\n    else if (res == '=') { cmp[a][b] = 2; cmp[b][a] = 2; }\n    return res;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    for (int i = 0; i < N; i++) items[i] = i;\n    \n    // Heap Sort to prioritize finding heavy items\n    // Build max-heap\n    for (int i = 1; i < N; i++) {\n        int cur = i;\n        while (cur > 0) {\n            int par = (cur - 1) / 2;\n            char res = do_query(items[cur], items[par]);\n            if (res == '>') {\n                swap(items[cur], items[par]);\n                cur = par;\n            } else {\n                break;\n            }\n        }\n    }\n    \n    // Extract max\n    for (int i = N - 1; i > 0; i--) {\n        swap(items[0], items[i]);\n        int cur = 0;\n        while (true) {\n            int left = 2 * cur + 1;\n            int right = 2 * cur + 2;\n            int largest = cur;\n            if (left < i) {\n                char res = do_query(items[left], items[largest]);\n                if (res == '>') largest = left;\n            }\n            if (right < i) {\n                char res = do_query(items[right], items[largest]);\n                if (res == '>') largest = right;\n            }\n            if (largest != cur) {\n                swap(items[cur], items[largest]);\n                cur = largest;\n            } else {\n                break;\n            }\n        }\n    }\n    \n    // Transitive closure\n    for (int k = 0; k < N; k++)\n        for (int i = 0; i < N; i++) { if (!cmp[i][k]) continue;\n            for (int j = 0; j < N; j++) { if (!cmp[k][j]) continue;\n                if (cmp[i][k]==1 && cmp[k][j]==1 && !cmp[i][j]) { cmp[i][j]=1; cmp[j][i]=-1; }\n                else if (cmp[i][k]==1 && cmp[k][j]==2 && !cmp[i][j]) { cmp[i][j]=1; cmp[j][i]=-1; }\n                else if (cmp[i][k]==2 && cmp[k][j]==1 && !cmp[i][j]) { cmp[i][j]=1; cmp[j][i]=-1; }\n                else if (cmp[i][k]==2 && cmp[k][j]==2 && !cmp[i][j]) { cmp[i][j]=2; cmp[j][i]=2; }\n            }\n        }\n    \n    // Sort by wins\n    vector<int> wins(N, 0);\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (cmp[i][j]==1) wins[i]++;\n    sort(items.begin(), items.end(), [&](int a, int b){ return wins[a]!=wins[b] ? wins[a]<wins[b] : a<b; });\n    \n    // Use remaining queries: adjacent pairs\n    for (int i = 1; i < N && qc < Q; i++) if (!cmp[items[i-1]][items[i]]) do_query(items[i-1], items[i]);\n    // Heavy items\n    for (int i = max(0, N-3*D); i < N && qc < Q; i++)\n        for (int j = i+1; j < N && qc < Q; j++) if (!cmp[items[i]][items[j]]) do_query(items[i], items[j]);\n    // All pairs\n    for (int i = 0; i < N && qc < Q; i++)\n        for (int j = i+1; j < N && qc < Q; j++) if (!cmp[items[i]][items[j]]) do_query(items[i], items[j]);\n        \n    // Waste remaining queries to ensure exactly Q queries are output\n    while (qc < Q) {\n        cout << \"1 1 0 1\" << endl;\n        char res; cin >> res;\n        qc++;\n    }\n    \n    // Transitive closure again\n    for (int k = 0; k < N; k++)\n        for (int i = 0; i < N; i++) { if (!cmp[i][k]) continue;\n            for (int j = 0; j < N; j++) { if (!cmp[k][j]) continue;\n                if (cmp[i][k]==1 && cmp[k][j]==1 && !cmp[i][j]) { cmp[i][j]=1; cmp[j][i]=-1; }\n                else if (cmp[i][k]==1 && cmp[k][j]==2 && !cmp[i][j]) { cmp[i][j]=1; cmp[j][i]=-1; }\n                else if (cmp[i][k]==2 && cmp[k][j]==1 && !cmp[i][j]) { cmp[i][j]=1; cmp[j][i]=-1; }\n                else if (cmp[i][k]==2 && cmp[k][j]==2 && !cmp[i][j]) { cmp[i][j]=2; cmp[j][i]=2; }\n            }\n        }\n        \n    // Sort by wins again\n    for (int i = 0; i < N; i++) { wins[i]=0; for (int j = 0; j < N; j++) if (cmp[i][j]==1) wins[i]++; }\n    sort(items.begin(), items.end(), [&](int a, int b){ return wins[a]!=wins[b] ? wins[a]<wins[b] : a<b; });\n    \n    // Estimate weights\n    vector<double> ew(N);\n    for (int i = 0; i < N; i++) { double p = (double)(i+1)/(N+1); ew[items[i]] = -log(1.0-p); }\n    \n    // LPT partitioning\n    vector<double> gw(D, 0); vector<int> asgn(N);\n    for (int i = N-1; i >= 0; i--) {\n        int item = items[i], mg = 0;\n        for (int g = 1; g < D; g++) if (gw[g] < gw[mg]) mg = g;\n        asgn[item] = mg; gw[mg] += ew[item];\n    }\n    \n    // SA + Hill climbing\n    mt19937 rng(42); uniform_real_distribution<double> ud(0,1);\n    double temp = 5000.0;\n    for (int it = 0; it < 1000000; it++) {\n        temp *= 0.999995;\n        if (rng() % 2 == 0) {\n            int i = rng()%N, j = rng()%N;\n            if (asgn[i]==asgn[j]) continue;\n            int gi=asgn[i], gj=asgn[j];\n            double osq = gw[gi]*gw[gi]+gw[gj]*gw[gj];\n            double ngi = gw[gi]-ew[i]+ew[j], ngj = gw[gj]-ew[j]+ew[i];\n            double nsq = ngi*ngi+ngj*ngj, delta = nsq-osq;\n            if (delta < 0 || (temp > 1e-8 && exp(-delta/temp) > ud(rng))) { gw[gi]=ngi; gw[gj]=ngj; asgn[i]=gj; asgn[j]=gi; }\n        } else {\n            int i = rng()%N;\n            int gi = asgn[i];\n            int gj = rng()%D;\n            if (gi == gj) continue;\n            if (gw[gi] - ew[i] < 1e-9) continue;\n            double osq = gw[gi]*gw[gi]+gw[gj]*gw[gj];\n            double ngi = gw[gi]-ew[i], ngj = gw[gj]+ew[i];\n            double nsq = ngi*ngi+ngj*ngj, delta = nsq-osq;\n            if (delta < 0 || (temp > 1e-8 && exp(-delta/temp) > ud(rng))) { gw[gi]=ngi; gw[gj]=ngj; asgn[i]=gj; }\n        }\n    }\n    for (int it = 0; it < 1000000; it++) {\n        if (rng() % 2 == 0) {\n            int i = rng()%N, j = rng()%N;\n            if (asgn[i]==asgn[j]) continue;\n            int gi=asgn[i], gj=asgn[j];\n            double osq = gw[gi]*gw[gi]+gw[gj]*gw[gj];\n            double ngi = gw[gi]-ew[i]+ew[j], ngj = gw[gj]-ew[j]+ew[i];\n            double nsq = ngi*ngi+ngj*ngj;\n            if (nsq < osq - 1e-10) { gw[gi]=ngi; gw[gj]=ngj; asgn[i]=gj; asgn[j]=gi; }\n        } else {\n            int i = rng()%N;\n            int gi = asgn[i];\n            int gj = rng()%D;\n            if (gi == gj) continue;\n            if (gw[gi] - ew[i] < 1e-9) continue;\n            double osq = gw[gi]*gw[gi]+gw[gj]*gw[gj];\n            double ngi = gw[gi]-ew[i], ngj = gw[gj]+ew[i];\n            double nsq = ngi*ngi+ngj*ngj;\n            if (nsq < osq - 1e-10) { gw[gi]=ngi; gw[gj]=ngj; asgn[i]=gj; }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) cout << asgn[i] << \" \\n\"[i==N-1];\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++)\n            cin >> stacks[i][j];\n    }\n    \n    vector<int> box_stack(n + 1), box_pos(n + 1);\n    for (int i = 0; i < m; i++)\n        for (int j = 0; j < (int)stacks[i].size(); j++) {\n            box_stack[stacks[i][j]] = i;\n            box_pos[stacks[i][j]] = j;\n        }\n    \n    vector<pair<int, int>> operations;\n    const int INV_COST = 4;\n    const int EMPTY_COST = 5;\n    \n    for (int v = 1; v <= n; v++) {\n        int sid = box_stack[v], pos = box_pos[v];\n        int k = (int)stacks[sid].size() - 1 - pos;\n        \n        if (k == 0) {\n            operations.push_back({v, 0});\n            stacks[sid].pop_back();\n            continue;\n        }\n        \n        vector<int> A(stacks[sid].begin() + pos + 1, stacks[sid].end());\n        \n        vector<int> dp(k + 1, INT_MAX);\n        vector<int> par(k + 1);\n        dp[0] = 0;\n        \n        for (int i = 1; i <= k; i++) {\n            for (int j = 1; j <= i; j++) {\n                int int_inv = 0;\n                for (int s = i - j; s < i; s++)\n                    for (int t = s + 1; t < i; t++)\n                        if (A[s] < A[t]) int_inv++;\n                \n                int best_dest_cost = INT_MAX;\n                for (int d = 0; d < m; d++) {\n                    if (d == sid) continue;\n                    int ext_inv = 0, empty_pen = 0;\n                    if (stacks[d].empty()) empty_pen = EMPTY_COST;\n                    else {\n                        int top_val = stacks[d].back();\n                        for (int s = i - j; s < i; s++)\n                            if (A[s] > top_val) ext_inv++;\n                    }\n                    best_dest_cost = min(best_dest_cost, INV_COST * (int_inv + ext_inv) + empty_pen);\n                }\n                \n                int cost = dp[i - j] + (j + 1) + best_dest_cost;\n                if (cost < dp[i]) { dp[i] = cost; par[i] = j; }\n            }\n        }\n        \n        vector<int> chunks;\n        for (int cur = k; cur > 0; cur -= par[cur])\n            chunks.push_back(par[cur]);\n        \n        for (int cs : chunks) {\n            int off = stacks[sid].size() - cs;\n            int best_dest = -1, best_priority = 4, best_subscore = INT_MAX;\n            \n            for (int d = 0; d < m; d++) {\n                if (d == sid) continue;\n                int ext_inv = 0;\n                bool is_empty = stacks[d].empty();\n                int top_val = is_empty ? 0 : stacks[d].back();\n                \n                if (!is_empty)\n                    for (int s = off; s < (int)stacks[sid].size(); s++)\n                        if (stacks[sid][s] > top_val) ext_inv++;\n                \n                int priority, subscore;\n                if (ext_inv == 0 && !is_empty) { priority = 1; subscore = top_val; }\n                else if (ext_inv == 0) { priority = 2; subscore = 0; }\n                else { priority = 3; subscore = ext_inv * 1000 - top_val; }\n                \n                if (priority < best_priority || (priority == best_priority && subscore < best_subscore)) {\n                    best_priority = priority; best_subscore = subscore; best_dest = d;\n                }\n            }\n            \n            if (best_dest == -1) best_dest = (sid + 1) % m;\n            \n            int u = stacks[sid][off];\n            operations.push_back({u, best_dest + 1});\n            \n            vector<int> moved(stacks[sid].begin() + off, stacks[sid].end());\n            stacks[sid].resize(off);\n            stacks[best_dest].insert(stacks[best_dest].end(), moved.begin(), moved.end());\n            \n            for (int j = 0; j < (int)moved.size(); j++) {\n                box_stack[moved[j]] = best_dest;\n                box_pos[moved[j]] = stacks[best_dest].size() - moved.size() + j;\n            }\n        }\n        \n        operations.push_back({v, 0});\n        stacks[sid].pop_back();\n    }\n    \n    for (auto& op : operations)\n        cout << op.first << \" \" << op.second << endl;\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\nchar dir_char[] = {'R', 'D', 'L', 'U'};\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + dx[dir], nj = j + dy[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (dir == 0 && v[i][j] == '1') return false;\n    if (dir == 1 && h[i][j] == '1') return false;\n    if (dir == 2 && v[i][nj] == '1') return false;\n    if (dir == 3 && h[ni][j] == '1') return false;\n    return true;\n}\n\nint get_dir(char c) {\n    if (c == 'R') return 0;\n    if (c == 'D') return 1;\n    if (c == 'L') return 2;\n    return 3; // 'U'\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    h.resize(N - 1); v.resize(N); d.resize(N, vector<int>(N));\n    for (int i = 0; i < N - 1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    int total_cells = N * N;\n    vector<int> all_dist(total_cells * total_cells, -1);\n    vector<int> all_prev_dir(total_cells * total_cells, -1);\n\n    auto get_dist = [&](int si, int sj, int ei, int ej) -> int& {\n        return all_dist[(si * N + sj) * total_cells + (ei * N + ej)];\n    };\n    auto get_prev = [&](int si, int sj, int ei, int ej) -> int& {\n        return all_prev_dir[(si * N + sj) * total_cells + (ei * N + ej)];\n    };\n\n    // Precompute BFS from all cells\n    for (int si = 0; si < N; ++si) {\n        for (int sj = 0; sj < N; ++sj) {\n            queue<pair<int,int>> q;\n            get_dist(si, sj, si, sj) = 0;\n            q.push({si, sj});\n            while (!q.empty()) {\n                auto [ci, cj] = q.front(); q.pop();\n                for (int dir = 0; dir < 4; dir++) {\n                    if (!can_move(ci, cj, dir)) continue;\n                    int ni = ci + dx[dir], nj = cj + dy[dir];\n                    if (get_dist(si, sj, ni, nj) == -1) { \n                        get_dist(si, sj, ni, nj) = get_dist(si, sj, ci, cj) + 1; \n                        get_prev(si, sj, ni, nj) = (dir + 2) % 4; // Direction to go BACK\n                        q.push({ni, nj}); \n                    }\n                }\n            }\n        }\n    }\n\n    auto get_path = [&](int si, int sj, int ei, int ej) -> string {\n        string path_back;\n        int ci = ei, cj = ej;\n        while (ci != si || cj != sj) {\n            int dir = get_prev(si, sj, ci, cj);\n            path_back += dir_char[dir];\n            ci += dx[dir];\n            cj += dy[dir];\n        }\n        string path_to;\n        for (int k = (int)path_back.size() - 1; k >= 0; --k) {\n            char c = path_back[k];\n            if (c == 'R') path_to += 'L';\n            else if (c == 'D') path_to += 'U';\n            else if (c == 'L') path_to += 'R';\n            else path_to += 'D';\n        }\n        return path_to;\n    };\n    \n    // Build DFS tour\n    string base_tour;\n    base_tour.reserve(N * N * 2);\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            int ni = i + dx[dir], nj = j + dy[dir];\n            if (!visited[ni][nj]) {\n                base_tour += dir_char[dir];\n                dfs(ni, nj);\n                base_tour += dir_char[(dir + 2) % 4];\n            }\n        }\n    };\n    dfs(0, 0);\n    \n    int L = base_tour.size();\n    vector<pair<int,int>> positions(L + 1);\n    positions[0] = {0, 0};\n    for (int t = 0; t < L; t++) {\n        int dir = get_dir(base_tour[t]);\n        positions[t+1] = {positions[t].first + dx[dir], positions[t].second + dy[dir]};\n    }\n    \n    // Find closest insertion point on base tour for detours\n    vector<int> best_step(N * N, 0), best_cost(N * N, INT_MAX);\n    for (int t = 0; t < L; t++) {\n        auto [pi, pj] = positions[t];\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (pi == i && pj == j) continue;\n            int cost = 2 * get_dist(pi, pj, i, j);\n            if (cost < best_cost[i * N + j]) { best_cost[i * N + j] = cost; best_step[i * N + j] = t; }\n        }\n    }\n    \n    // Correctly calculate visits per cycle (t=0 to L-1)\n    vector<int> visit_count(N * N, 0);\n    for (int t = 0; t < L; t++) { auto [i, j] = positions[t]; visit_count[i * N + j]++; }\n    \n    double S_factor = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) S_factor += (double)d[i][j] / visit_count[i * N + j];\n    \n    using Cell = tuple<double, int, int>;\n    priority_queue<Cell> pq;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (i == 0 && j == 0) continue;\n        int k = visit_count[i * N + j], cost = best_cost[i * N + j];\n        if (cost == 0 || cost >= INT_MAX) continue;\n        pq.push({(double)d[i][j] / ((long long)k * (k + 1)) / cost, i, j});\n    }\n    \n    struct Detour { int step; int i; int j; };\n    vector<Detour> detours;\n    int current_L = L;\n    \n    while (!pq.empty() && current_L < 100000) {\n        auto [p, i, j] = pq.top(); pq.pop();\n        int k = visit_count[i * N + j], cost = best_cost[i * N + j];\n        if (cost >= INT_MAX) continue;\n        double new_p = (double)d[i][j] / ((long long)k * (k + 1)) / cost;\n        if (abs(new_p - p) > 1e-9) { pq.push({new_p, i, j}); continue; }\n        \n        if (current_L + cost > 100000) continue;\n        \n        // Benefit-cost check\n        double benefit = (double)d[i][j] * (current_L + cost) / ((long long)k * (k + 1));\n        double detour_cost_val = (double)cost * S_factor;\n        if (benefit <= detour_cost_val) break; // No more beneficial detours possible\n        \n        int step = best_step[i * N + j];\n        \n        detours.push_back({step, i, j});\n        current_L += cost;\n        S_factor -= (double)d[i][j] / k;\n        visit_count[i * N + j]++;\n        S_factor += (double)d[i][j] / visit_count[i * N + j];\n        int nk = visit_count[i * N + j];\n        pq.push({(double)d[i][j] / ((long long)nk * (nk + 1)) / cost, i, j});\n    }\n    \n    sort(detours.begin(), detours.end(), [](const auto& a, const auto& b) { return a.step < b.step; });\n    \n    string result;\n    result.reserve(100000);\n    int detour_idx = 0;\n    for (int t = 0; t <= L; t++) {\n        while (detour_idx < (int)detours.size() && detours[detour_idx].step == t) {\n            auto [step, i, j] = detours[detour_idx];\n            auto [pi, pj] = positions[step];\n            string path_to = get_path(pi, pj, i, j);\n            string path_back;\n            for (int k2 = (int)path_to.size() - 1; k2 >= 0; k2--) {\n                char c = path_to[k2];\n                path_back += (c == 'R') ? 'L' : (c == 'D') ? 'U' : (c == 'L') ? 'R' : 'D';\n            }\n            result += path_to;\n            result += path_back;\n            detour_idx++;\n        }\n        if (t < L) result += base_tour[t];\n    }\n    \n    cout << result << endl;\n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\nint main(){\n    ios_base::sync_with_stdio(false);cin.tie(nullptr);\n    int N,M;cin>>N>>M;int si,sj;cin>>si>>sj;\n    vector<string> A(N);for(int i=0;i<N;i++)cin>>A[i];\n    vector<string> t(M);for(int i=0;i<M;i++)cin>>t[i];\n    vector<vector<pair<int,int>>> cp(26);\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)cp[A[i][j]-'A'].push_back({i,j});\n    vector<vector<int>> cd(26,vector<int>(26,0));\n    for(int c1=0;c1<26;c1++)for(int c2=0;c2<26;c2++){int md=INT_MAX;\n        for(auto&[i1,j1]:cp[c1])for(auto&[i2,j2]:cp[c2])md=min(md,abs(i1-i2)+abs(j1-j2));cd[c1][c2]=md;}\n    vector<vector<int>> ov(M,vector<int>(M,0));\n    for(int i=0;i<M;i++)for(int j=0;j<M;j++){if(i==j)continue;\n        for(int l=4;l>=1;l--){bool ok=true;for(int k=0;k<l;k++)if(t[i][5-l+k]!=t[j][k]){ok=false;break;}\n            if(ok){ov[i][j]=l;break;}}}\n    auto buildS=[&](const vector<int>&o)->string{string s=t[o[0]];\n        for(int i=1;i<(int)o.size();i++){int mx=min(5,(int)s.size()),a=0;\n            for(int l=mx;l>=1;l--){bool ok=true;for(int k=0;k<l;k++)if(s[s.size()-l+k]!=t[o[i]][k]){ok=false;break;}\n                if(ok){a=l;break;}}s+=t[o[i]].substr(a);}return s;};\n    auto totalOv=[&](const vector<int>&o)->int{int tv=0;for(int i=1;i<(int)o.size();i++)tv+=ov[o[i-1]][o[i]];return tv;};\n    mt19937 rng(42);\n    auto greedyR=[&](int st,unsigned seed)->vector<int>{mt19937 lr(seed);vector<int>o;o.push_back(st);\n        vector<bool>u(M,false);u[st]=true;for(int s=1;s<M;s++){int l=o.back(),bo=-1;vector<int>c;\n            for(int j=0;j<M;j++){if(u[j])continue;if(ov[l][j]>bo){bo=ov[l][j];c.clear();c.push_back(j);}\n                else if(ov[l][j]==bo)c.push_back(j);}o.push_back(c[lr()%c.size()]);u[o.back()]=true;}return o;};\n    auto twoOpt=[&](vector<int>o)->vector<int>{bool imp=true;while(imp){imp=false;\n        for(int i=0;i<M-1;i++){int os=0,ns=0;if(i>0){os+=ov[o[i-1]][o[i]];ns+=ov[o[i-1]][o[i+1]];}\n            os+=ov[o[i]][o[i+1]];ns+=ov[o[i+1]][o[i]];if(i+2<M){os+=ov[o[i+1]][o[i+2]];ns+=ov[o[i]][o[i+2]];}\n            if(ns>os){swap(o[i],o[i+1]);imp=true;}}}return o;};\n    auto orOpt=[&](vector<int>o)->vector<int>{for(int it=0;it<10;it++){bool imp=false;\n        for(int i=0;i<M;i++){int w=o[i],rd=0;if(i>0)rd-=ov[o[i-1]][w];if(i<M-1)rd-=ov[w][o[i+1]];\n            if(i>0&&i<M-1)rd+=ov[o[i-1]][o[i+1]];auto gr=[&](int k)->int{return(k<i)?o[k]:o[k+1];};\n            int bd=0,bk=i;for(int j=0;j<=M-1;j++){if(j==i)continue;int id=0;int C=(j>0)?gr(j-1):-1,D=(j<M-1)?gr(j):-1;\n                if(C!=-1)id+=ov[C][w];if(D!=-1)id+=ov[w][D];if(C!=-1&&D!=-1)id-=ov[C][D];\n                if(rd+id>bd){bd=rd+id;bk=j;}}\n            if(bk!=i){vector<int>rm;for(int k=0;k<M;k++)if(k!=i)rm.push_back(o[k]);o.clear();\n                for(int k=0;k<bk;k++)o.push_back(rm[k]);o.push_back(w);for(int k=bk;k<M-1;k++)o.push_back(rm[k]);imp=true;break;}}\n        if(!imp)break;}return o;};\n    auto sa=[&](vector<int>o,unsigned seed)->vector<int>{int curOv=totalOv(o);int bestOv=curOv;auto bestO=o;\n        mt19937 saRng(seed);uniform_int_distribution<int>distI(0,M-1);uniform_real_distribution<double>distD(0.0,1.0);\n        double temp=3.0;for(int it=0;it<500000;it++){temp*=0.99999;int i=distI(saRng);int w=o[i];\n            int rd=0;if(i>0)rd-=ov[o[i-1]][w];if(i<M-1)rd-=ov[w][o[i+1]];if(i>0&&i<M-1)rd+=ov[o[i-1]][o[i+1]];\n            int j=distI(saRng);if(j==i)continue;\n            auto gr=[&](int k)->int{return(k<i)?o[k]:o[k+1];};\n            int C=(j>0)?gr(j-1):-1,D=(j<M-1)?gr(j):-1;int id=0;\n            if(C!=-1)id+=ov[C][w];if(D!=-1)id+=ov[w][D];if(C!=-1&&D!=-1)id-=ov[C][D];int delta=rd+id;\n            if(delta>0||distD(saRng)<exp((double)delta/max(temp,0.001))){\n                o.erase(o.begin()+i);o.insert(o.begin()+j,w);curOv+=delta;\n                if(curOv>bestOv){bestOv=curOv;bestO=o;}}}return bestO;};\n    auto hc=[&](const string&s)->int{int cost=s.size();for(int i=0;i<(int)s.size()-1;i++)cost+=cd[s[i]-'A'][s[i+1]-'A'];return cost;};\n    vector<pair<int,vector<int>>>cs;\n    for(int s=0;s<M;s++)for(int seed=0;seed<5;seed++){auto o=greedyR(s,s*997+seed*137+1);o=twoOpt(o);\n        int tv=totalOv(o);cs.push_back({5*M-tv,o});}\n    sort(cs.begin(),cs.end());\n    vector<pair<int,string>>eval;\n    int topN=min((int)cs.size(),30);\n    for(int i=0;i<topN;i++){auto o=cs[i].second;o=orOpt(o);o=twoOpt(o);string ss=buildS(o);eval.push_back({hc(ss),ss});}\n    int saN=min((int)cs.size(),10);\n    for(int i=0;i<saN;i++){auto o=cs[i].second;o=sa(o,i*12345+1);o=twoOpt(o);o=orOpt(o);o=twoOpt(o);\n        string ss=buildS(o);eval.push_back({hc(ss),ss});}\n    sort(eval.begin(),eval.end());eval.erase(unique(eval.begin(),eval.end(),[](auto&a,auto&b){return a.second==b.second;}),eval.end());\n    const int INF=1e9;auto dpEval=[&](const string&s)->int{int L=s.size();vector<int>cur(225,INF);cur[si*15+sj]=0;\n        for(int i=0;i<L;i++){vector<int>nx(225,INF);int ci=s[i]-'A';for(int q=0;q<225;q++){if(cur[q]>=INF)continue;\n            int qi=q/15,qj=q%15;for(auto&[pi,pj]:cp[ci]){int p=pi*15+pj;int nc=cur[q]+abs(pi-qi)+abs(pj-qj)+1;\n                if(nc<nx[p])nx[p]=nc;}}cur=move(nx);}return*min_element(cur.begin(),cur.end());};\n    string bs;int bc=INF;int dpN=min((int)eval.size(),25);\n    for(int i=0;i<dpN;i++){int c=dpEval(eval[i].second);if(c<bc){bc=c;bs=eval[i].second;}}\n    int L=bs.size();vector<vector<pair<int,int>>>dp(L+1,vector<pair<int,int>>(225,{INF,-1}));dp[0][si*15+sj]={0,-1};\n    for(int i=0;i<L;i++){int ci=bs[i]-'A';for(int q=0;q<225;q++){if(dp[i][q].first>=INF)continue;\n        int qi=q/15,qj=q%15;for(auto&[pi,pj]:cp[ci]){int p=pi*15+pj;int nc=dp[i][q].first+abs(pi-qi)+abs(pj-qj)+1;\n            if(nc<dp[i+1][p].first)dp[i+1][p]={nc,q};}}}\n    int be=0;bc=INF;for(int p=0;p<225;p++)if(dp[L][p].first<bc){bc=dp[L][p].first;be=p;}\n    vector<int>pp(L);int cr=be;for(int i=L-1;i>=0;i--){pp[i]=cr;cr=dp[i+1][cr].second;}\n    for(int i=0;i<L;i++)cout<<pp[i]/15<<\" \"<<pp[i]%15<<\"\\n\";return 0;}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<vector<pair<int,int>>> shapes;\nvector<int> max_di, max_dj;\nvector<vector<pair<int,int>>> positions;\nvector<vector<vector<pair<int,int>>>> pos_cells;\nvector<vector<vector<int>>> cell_pos;\nint known[25][25];\nint query_count = 0;\nvector<vector<double>> lw;\ndouble cov_val[25][25];\ndouble prob_oil_val[25][25];\n\nint drill_cell(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int v; cin >> v;\n    known[i][j] = v;\n    query_count++;\n    return v;\n}\n\nint divine_cells(vector<pair<int,int>>& cells) {\n    int k = cells.size();\n    cout << \"q \" << k;\n    for (auto& [i, j] : cells) cout << \" \" << i << \" \" << j;\n    cout << endl;\n    cout.flush();\n    int v; cin >> v;\n    query_count++;\n    return v;\n}\n\nbool submit_answer(vector<pair<int,int>>& cells) {\n    sort(cells.begin(), cells.end());\n    cells.erase(unique(cells.begin(), cells.end()), cells.end());\n    cout << \"a \" << cells.size();\n    for (auto& [i, j] : cells) cout << \" \" << i << \" \" << j;\n    cout << endl;\n    cout.flush();\n    int r; cin >> r;\n    if (r == 0) query_count++; // Wrong answer costs 1 operation\n    return r == 1;\n}\n\nvoid compute_prob_and_cov() {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        cov_val[i][j] = 0;\n        prob_oil_val[i][j] = 1.0;\n    }\n    for (int k = 0; k < M; k++) {\n        double mx = *max_element(lw[k].begin(), lw[k].end());\n        double total = 0;\n        for (int p = 0; p < (int)positions[k].size(); p++) total += exp(lw[k][p] - mx);\n        if (total < 1e-30) continue;\n        vector<double> cc(N * N, 0);\n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            double wt = exp(lw[k][p] - mx) / total;\n            for (auto& [ci, cj] : pos_cells[k][p]) cc[ci * N + cj] += wt;\n        }\n        for (int idx = 0; idx < N * N; idx++) {\n            cov_val[idx / N][idx % N] += cc[idx];\n            prob_oil_val[idx / N][idx % N] *= (1.0 - cc[idx]);\n        }\n    }\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n        prob_oil_val[i][j] = 1.0 - prob_oil_val[i][j];\n}\n\nvoid update_divine(const vector<pair<int,int>>& qcells, int obs) {\n    int ksz = qcells.size();\n    double sigma2 = ksz * eps * (1 - eps);\n    int Q = qcells.size();\n    \n    vector<double> mx_arr(M), total_arr(M);\n    for (int k = 0; k < M; k++) {\n        mx_arr[k] = *max_element(lw[k].begin(), lw[k].end());\n        total_arr[k] = 0;\n        for (int p = 0; p < (int)positions[k].size(); p++) total_arr[k] += exp(lw[k][p] - mx_arr[k]);\n    }\n    \n    vector<vector<double>> fc(M, vector<double>(Q, 0.0));\n    for (int k = 0; k < M; k++) {\n        if (total_arr[k] < 1e-30) continue;\n        for (int q = 0; q < Q; q++) {\n            auto& [i, j] = qcells[q];\n            double covers = 0;\n            for (int p : cell_pos[k][i * N + j]) covers += exp(lw[k][p] - mx_arr[k]);\n            fc[k][q] = covers / total_arr[k];\n        }\n    }\n    \n    for (int k = 0; k < M; k++) {\n        double S_others = 0;\n        for (int q = 0; q < Q; q++) {\n            for (int k2 = 0; k2 < M; k2++) {\n                if (k2 != k) S_others += fc[k2][q];\n            }\n        }\n        \n        double var_others = 0;\n        for (int k2 = 0; k2 < M; k2++) {\n            if (k2 == k || total_arr[k2] < 1e-30) continue;\n            \n            vector<double> joint_q(Q * Q, 0.0);\n            vector<int> idx(Q, 0);\n            for (int p = 0; p < (int)positions[k2].size(); p++) {\n                double wt = exp(lw[k2][p] - mx_arr[k2]) / total_arr[k2];\n                vector<int> covered_q;\n                for (int q = 0; q < Q; q++) {\n                    auto& [i, j] = qcells[q];\n                    const auto& cp = cell_pos[k2][i * N + j];\n                    while (idx[q] < (int)cp.size() && cp[idx[q]] < p) idx[q]++;\n                    if (idx[q] < (int)cp.size() && cp[idx[q]] == p) {\n                        covered_q.push_back(q);\n                    }\n                }\n                for (int q1_idx = 0; q1_idx < (int)covered_q.size(); q1_idx++) {\n                    for (int q2_idx = q1_idx; q2_idx < (int)covered_q.size(); q2_idx++) {\n                        joint_q[covered_q[q1_idx] * Q + covered_q[q2_idx]] += wt;\n                    }\n                }\n            }\n            for (int q1 = 0; q1 < Q; q1++) {\n                var_others += fc[k2][q1] * (1.0 - fc[k2][q1]);\n                for (int q2 = q1 + 1; q2 < Q; q2++) {\n                    double cov = joint_q[q1 * Q + q2] - fc[k2][q1] * fc[k2][q2];\n                    var_others += 2 * cov;\n                }\n            }\n        }\n        \n        double total_var = sigma2 + var_others * (1 - 2 * eps) * (1 - 2 * eps);\n        if (total_var < sigma2) total_var = sigma2; // Safety clamp\n        \n        vector<int> pos_cnt(positions[k].size(), 0);\n        for (int q = 0; q < Q; q++) {\n            auto& [i, j] = qcells[q];\n            for (int p : cell_pos[k][i * N + j]) pos_cnt[p]++;\n        }\n        \n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            double ev = S_others + pos_cnt[p];\n            double mean = ksz * eps + ev * (1 - 2 * eps);\n            double diff = obs - mean;\n            lw[k][p] += -diff * diff / (2 * total_var);\n        }\n        double mx = *max_element(lw[k].begin(), lw[k].end());\n        for (auto& l : lw[k]) l -= mx;\n    }\n    compute_prob_and_cov();\n}\n\nvoid update_drill(int i, int j, int obs) {\n    if (obs == 0) {\n        for (int k = 0; k < M; k++) {\n            for (int p : cell_pos[k][i * N + j]) {\n                lw[k][p] = -1e9; // Completely eliminate positions covering a known 0-cell\n            }\n            double mx = *max_element(lw[k].begin(), lw[k].end());\n            for (auto& l : lw[k]) l -= mx;\n        }\n    } else if (obs == M) {\n        for (int k = 0; k < M; k++) {\n            const auto& cp = cell_pos[k][i * N + j];\n            for (int p = 0; p < (int)positions[k].size(); p++) {\n                if (!binary_search(cp.begin(), cp.end(), p)) lw[k][p] = -1e9;\n            }\n            double mx = *max_element(lw[k].begin(), lw[k].end());\n            for (auto& l : lw[k]) l -= mx;\n        }\n    } else {\n        vector<double> fc(M, 0.0);\n        vector<double> mx_arr(M), total_arr(M);\n        for (int k = 0; k < M; k++) {\n            mx_arr[k] = *max_element(lw[k].begin(), lw[k].end());\n            total_arr[k] = 0;\n            for (int p = 0; p < (int)positions[k].size(); p++) total_arr[k] += exp(lw[k][p] - mx_arr[k]);\n            if (total_arr[k] < 1e-30) { fc[k] = 0; continue; }\n            double covers = 0;\n            for (int p : cell_pos[k][i * N + j]) covers += exp(lw[k][p] - mx_arr[k]);\n            fc[k] = covers / total_arr[k];\n        }\n        \n        for (int k = 0; k < M; k++) {\n            double others = 0;\n            double var_others = 0;\n            for (int k2 = 0; k2 < M; k2++) {\n                if (k2 == k) continue;\n                others += fc[k2];\n                var_others += fc[k2] * (1.0 - fc[k2]);\n            }\n            \n            double var_o = max(0.1, var_others);\n            const auto& cp = cell_pos[k][i * N + j];\n            \n            for (int p = 0; p < (int)positions[k].size(); p++) {\n                double covers = binary_search(cp.begin(), cp.end(), p) ? 1.0 : 0.0;\n                double diff;\n                if (covers > 0.5) {\n                    diff = obs - 1.0 - others;\n                } else {\n                    diff = obs - others;\n                }\n                lw[k][p] += -diff * diff / (2 * var_o);\n            }\n            double mx = *max_element(lw[k].begin(), lw[k].end());\n            for (auto& l : lw[k]) l -= mx;\n        }\n    }\n    compute_prob_and_cov();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M >> eps;\n    shapes.resize(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int l = 0; l < d; l++) cin >> shapes[k][l].first >> shapes[k][l].second;\n    }\n    max_di.resize(M); max_dj.resize(M);\n    for (int k = 0; k < M; k++) {\n        max_di[k] = max_dj[k] = 0;\n        for (auto& [i, j] : shapes[k]) { max_di[k] = max(max_di[k], i); max_dj[k] = max(max_dj[k], j); }\n    }\n    cell_pos.resize(M, vector<vector<int>>(N * N));\n    for (int k = 0; k < M; k++) {\n        vector<pair<int,int>> pos;\n        vector<vector<pair<int,int>>> cells;\n        int pidx = 0;\n        for (int di = 0; di <= N - 1 - max_di[k]; di++)\n            for (int dj = 0; dj <= N - 1 - max_dj[k]; dj++) {\n                pos.push_back({di, dj});\n                vector<pair<int,int>> c;\n                for (auto& [i, j] : shapes[k]) {\n                    int ci = di + i, cj = dj + j;\n                    c.push_back({ci, cj});\n                    cell_pos[k][ci * N + cj].push_back(pidx);\n                }\n                cells.push_back(c);\n                pidx++;\n            }\n        positions.push_back(pos);\n        pos_cells.push_back(cells);\n    }\n    memset(known, -1, sizeof(known));\n    for (int k = 0; k < M; k++) lw.push_back(vector<double>(positions[k].size(), 0.0));\n    compute_prob_and_cov();\n    \n    for (int i = 0; i < N && query_count < 2*N*N - 1; i++) {\n        vector<pair<int,int>> cells;\n        for (int j = 0; j < N; j++) cells.push_back({i, j});\n        update_divine(cells, divine_cells(cells));\n    }\n    for (int j = 0; j < N && query_count < 2*N*N - 1; j++) {\n        vector<pair<int,int>> cells;\n        for (int i = 0; i < N; i++) cells.push_back({i, j});\n        update_divine(cells, divine_cells(cells));\n    }\n    if (eps <= 0.1) {\n        int B = max(4, N / 3);\n        int S = max(2, B / 2);\n        for (int r1 = 0; r1 < N && query_count < 2*N*N - 1; r1 += S)\n            for (int c1 = 0; c1 < N && query_count < 2*N*N - 1; c1 += S) {\n                vector<pair<int,int>> cells;\n                for (int i = r1; i < min(N, r1 + B); i++)\n                    for (int j = c1; j < min(N, c1 + B); j++)\n                        cells.push_back({i, j});\n                if (cells.size() >= 2) update_divine(cells, divine_cells(cells));\n            }\n    }\n    \n    bool last_answer_wrong = false;\n    while (query_count < 2*N*N) {\n        double exp_err = 0;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (known[i][j] >= 0) continue;\n            double p = prob_oil_val[i][j];\n            exp_err += min(p, 1 - p);\n        }\n        if ((exp_err < 0.7 || query_count >= 2*N*N - 1) && !last_answer_wrong) {\n            vector<pair<int,int>> ans;\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n                if (known[i][j] > 0) ans.push_back({i, j});\n                else if (known[i][j] < 0 && prob_oil_val[i][j] > 0.5) ans.push_back({i, j});\n            }\n            if (submit_answer(ans)) return 0;\n            last_answer_wrong = true;\n        } else {\n            if (query_count >= 2*N*N - 1) break;\n            int bi = -1, bj = -1; double bent = -1;\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n                if (known[i][j] >= 0) continue;\n                double p = max(0.001, min(0.999, prob_oil_val[i][j]));\n                double ent = -p*log(p) - (1-p)*log(1-p);\n                if (ent > bent) { bent = ent; bi = i; bj = j; }\n            }\n            if (bi < 0) break;\n            update_drill(bi, bj, drill_cell(bi, bj));\n            last_answer_wrong = false;\n        }\n    }\n    \n    if (query_count < 2*N*N) {\n        vector<pair<int,int>> ans;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (known[i][j] > 0) ans.push_back({i, j});\n            else if (known[i][j] < 0 && prob_oil_val[i][j] > 0.5) ans.push_back({i, j});\n        }\n        submit_answer(ans);\n    }\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <climits>\nusing namespace std;\n\nint W, D, N;\nvector<vector<int>> a;\n\nlong long day_def(int d, const vector<int>& h) {\n    long long c = 0;\n    for (int k = 0; k < N; k++) {\n        int area = h[k] * W;\n        if (a[d][k] > area) c += 100LL * (a[d][k] - area);\n    }\n    return c;\n}\n\nvoid get_bounds(const vector<int>& h, vector<int>& b) {\n    b.resize(N - 1);\n    int y = 0;\n    for (int k = 0; k < N - 1; k++) { y += h[k]; b[k] = y; }\n}\n\nlong long bound_diff(const vector<int>& b1, const vector<int>& b2) {\n    int i = 0, j = 0; long long c = 0;\n    while (i < (int)b1.size() && j < (int)b2.size()) {\n        if (b1[i] == b2[j]) { i++; j++; }\n        else if (b1[i] < b2[j]) { c++; i++; }\n        else { c++; j++; }\n    }\n    c += (int)b1.size() - i + (int)b2.size() - j;\n    return c;\n}\n\nvector<int> greedy_day(int d) {\n    vector<int> h(N, 1);\n    int rem = W - N;\n    while (rem > 0) {\n        int bk = -1; long long br = -1;\n        for (int k = 0; k < N; k++) {\n            int df = max(0, a[d][k] - h[k] * W);\n            int nd = max(0, a[d][k] - (h[k] + 1) * W);\n            long long r = df - nd;\n            if (r > br || (r == br && bk >= 0 && a[d][k] > a[d][bk])) { br = r; bk = k; }\n        }\n        if (bk == -1 || br == 0) {\n            int mx = -1; for (int k = 0; k < N; k++) if (a[d][k] > mx) { mx = a[d][k]; bk = k; }\n        }\n        if (bk == -1) break;\n        h[bk]++; rem--;\n    }\n    return h;\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> W >> D >> N;\n    a.resize(D, vector<int>(N));\n    for (int d = 0; d < D; d++) for (int k = 0; k < N; k++) cin >> a[d][k];\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> uni(0, 1);\n    \n    vector<int> fixed_h(N, 1);\n    { int rem = W - N;\n      while (rem > 0) {\n        int bk = -1; long long bs = -1;\n        for (int k = 0; k < N; k++) {\n            long long td = 0, ntd = 0;\n            for (int d = 0; d < D; d++) { td += max(0, a[d][k] - fixed_h[k] * W); ntd += max(0, a[d][k] - (fixed_h[k] + 1) * W); }\n            long long s = td - ntd;\n            if (s > bs) { bs = s; bk = k; }\n        }\n        if (bk == -1) break; fixed_h[bk]++; rem--;\n      }\n    }\n    \n    { vector<int> ch = fixed_h;\n      long long cc = 0; for (int d = 0; d < D; d++) cc += day_def(d, ch);\n      long long bc = cc; vector<int> bh = ch;\n      auto st = chrono::high_resolution_clock::now();\n      while (true) {\n        auto nw = chrono::high_resolution_clock::now();\n        double el = chrono::duration<double>(nw - st).count();\n        if (el > 0.25) break;\n        int k1 = rng() % N, k2 = rng() % N;\n        if (k1 == k2 || ch[k1] <= 1) continue;\n        long long delta = 0;\n        for (int d = 0; d < D; d++) {\n            delta += 100LL * (max(0, a[d][k1] - (ch[k1] - 1) * W) - max(0, a[d][k1] - ch[k1] * W));\n            delta += 100LL * (max(0, a[d][k2] - (ch[k2] + 1) * W) - max(0, a[d][k2] - ch[k2] * W));\n        }\n        double temp = 5e6 * max(1e-4, 1.0 - el / 0.25);\n        if (delta <= 0 || exp(-(double)delta / temp) > uni(rng)) {\n            ch[k1]--; ch[k2]++; cc += delta;\n            if (cc < bc) { bc = cc; bh = ch; }\n        }\n      }\n      fixed_h = bh;\n    }\n    \n    vector<vector<vector<int>>> cands(D);\n    vector<vector<long long>> cdef(D);\n    vector<vector<vector<int>>> cbnd(D);\n    \n    for (int d = 0; d < D; d++) {\n        vector<int> min_h(N);\n        int sum_min = 0;\n        for (int k = 0; k < N; k++) {\n            min_h[k] = (a[d][k] + W - 1) / W;\n            sum_min += min_h[k];\n        }\n        int extra = W - sum_min;\n        \n        if (extra >= 0) {\n            cands[d].push_back(min_h);\n            for (int k = 0; k < N; k++) {\n                if (extra > 0) {\n                    vector<int> h = min_h; h[k] += extra;\n                    cands[d].push_back(h);\n                }\n            }\n            int num_random = max(15, extra / 5);\n            for (int i = 0; i < num_random; i++) {\n                vector<int> h = min_h; int rem = extra;\n                while (rem > 0) { h[rng() % N]++; rem--; }\n                cands[d].push_back(h);\n            }\n        } else {\n            vector<int> ch = min_h; int rem = -extra;\n            while (rem > 0) {\n                int bk = -1; long long min_inc = LLONG_MAX;\n                for (int k = 0; k < N; k++) {\n                    if (ch[k] > 1) {\n                        int od = max(0, a[d][k] - ch[k] * W); int nd = max(0, a[d][k] - (ch[k] - 1) * W);\n                        if (nd - od < min_inc) { min_inc = nd - od; bk = k; }\n                    }\n                }\n                if (bk == -1) break; ch[bk]--; rem--;\n            }\n            cands[d].push_back(ch);\n            for (int k = 0; k < N; k++) {\n                if (min_h[k] > 1) {\n                    vector<int> h = min_h; h[k]--; int r2 = -extra - 1;\n                    while (r2 > 0) {\n                        int bk2 = -1; long long min_inc2 = LLONG_MAX;\n                        for (int j = 0; j < N; j++) {\n                            if (h[j] > 1) {\n                                int od = max(0, a[d][j] - h[j] * W); int nd = max(0, a[d][j] - (h[j] - 1) * W);\n                                if (nd - od < min_inc2) { min_inc2 = nd - od; bk2 = j; }\n                            }\n                        }\n                        if (bk2 == -1) break; h[bk2]--; r2--;\n                    }\n                    cands[d].push_back(h);\n                }\n            }\n            for (int i = 0; i < 15; i++) {\n                vector<int> h = min_h; int rem = -extra;\n                while (rem > 0) { int k = rng() % N; if (h[k] > 1) { h[k]--; rem--; } }\n                cands[d].push_back(h);\n            }\n        }\n        \n        cands[d].push_back(fixed_h);\n        cands[d].push_back(greedy_day(d));\n        \n        sort(cands[d].begin(), cands[d].end());\n        cands[d].erase(unique(cands[d].begin(), cands[d].end()), cands[d].end());\n    }\n    \n    vector<int> ksz(D); int maxK = 0;\n    for (int d = 0; d < D; d++) { ksz[d] = cands[d].size(); maxK = max(maxK, ksz[d]); }\n    vector<vector<long long>> dp(D, vector<long long>(maxK, LLONG_MAX));\n    vector<vector<int>> par(D, vector<int>(maxK, -1));\n    \n    for (int d = 0; d < D; d++) {\n        cdef[d].resize(ksz[d]); cbnd[d].resize(ksz[d]);\n        for (int i = 0; i < ksz[d]; i++) { cdef[d][i] = day_def(d, cands[d][i]); get_bounds(cands[d][i], cbnd[d][i]); }\n    }\n    \n    for (int k = 0; k < ksz[0]; k++) dp[0][k] = cdef[0][k];\n    for (int d = 1; d < D; d++)\n        for (int k = 0; k < ksz[d]; k++)\n            for (int j = 0; j < ksz[d-1]; j++) {\n                if (dp[d-1][j] == LLONG_MAX) continue;\n                long long cost = dp[d-1][j] + bound_diff(cbnd[d-1][j], cbnd[d][k]) * W + cdef[d][k];\n                if (cost < dp[d][k]) { dp[d][k] = cost; par[d][k] = j; }\n            }\n            \n    long long best_dp = LLONG_MAX; int best_k = -1;\n    for (int k = 0; k < ksz[D-1]; k++) if (dp[D-1][k] < best_dp) { best_dp = dp[D-1][k]; best_k = k; }\n    vector<vector<int>> dp_res(D);\n    { int ck = best_k; for (int d = D-1; d >= 0; d--) { dp_res[d] = cands[d][ck]; ck = par[d][ck]; } }\n    \n    vector<vector<int>> cur_h = dp_res;\n    vector<vector<int>> cur_bnd(D);\n    vector<long long> pc_cache(D, 0);\n    for (int d = 0; d < D; d++) get_bounds(cur_h[d], cur_bnd[d]);\n    for (int d = 1; d < D; d++) pc_cache[d] = bound_diff(cur_bnd[d-1], cur_bnd[d]) * W;\n    \n    long long cur_cost = 0;\n    for (int d = 0; d < D; d++) cur_cost += day_def(d, cur_h[d]);\n    for (int d = 1; d < D; d++) cur_cost += pc_cache[d];\n    \n    { long long fc = 0; for (int d = 0; d < D; d++) fc += day_def(d, fixed_h);\n      if (fc < cur_cost) {\n          cur_h.assign(D, fixed_h);\n          for (int d = 0; d < D; d++) get_bounds(cur_h[d], cur_bnd[d]);\n          for (int d = 1; d < D; d++) pc_cache[d] = bound_diff(cur_bnd[d-1], cur_bnd[d]) * W;\n          cur_cost = fc;\n      }\n    }\n    long long best_cost = cur_cost; vector<vector<int>> best_h = cur_h;\n    \n    auto st = chrono::high_resolution_clock::now();\n    while (true) {\n        auto nw = chrono::high_resolution_clock::now();\n        double el = chrono::duration<double>(nw - st).count();\n        if (el > 2.5) break;\n        int d = rng() % D, k1 = rng() % N, k2 = rng() % N;\n        if (k1 == k2 || cur_h[d][k1] <= 1) continue;\n        long long dd = 100LL * (max(0, a[d][k1] - (cur_h[d][k1] - 1) * W) - max(0, a[d][k1] - cur_h[d][k1] * W))\n                      + 100LL * (max(0, a[d][k2] - (cur_h[d][k2] + 1) * W) - max(0, a[d][k2] - cur_h[d][k2] * W));\n        cur_h[d][k1]--; cur_h[d][k2]++;\n        int lo = min(k1, k2), hi = max(k1, k2);\n        int dsign = (k1 < k2) ? -1 : 1;\n        for (int i = lo; i < hi; i++) cur_bnd[d][i] += dsign;\n        long long npd = (d > 0 ? bound_diff(cur_bnd[d-1], cur_bnd[d]) * W : 0)\n                       + (d < D-1 ? bound_diff(cur_bnd[d], cur_bnd[d+1]) * W : 0);\n        long long opd = (d > 0 ? pc_cache[d] : 0) + (d < D-1 ? pc_cache[d+1] : 0);\n        long long delta = dd + npd - opd;\n        double temp = 5e6 * max(1e-4, 1.0 - el / 2.5);\n        if (delta <= 0 || exp(-(double)delta / temp) > uni(rng)) {\n            cur_cost += delta;\n            if (d > 0) pc_cache[d] = bound_diff(cur_bnd[d-1], cur_bnd[d]) * W;\n            if (d < D-1) pc_cache[d+1] = bound_diff(cur_bnd[d], cur_bnd[d+1]) * W;\n            if (cur_cost < best_cost) { best_cost = cur_cost; best_h = cur_h; }\n        } else {\n            cur_h[d][k1]++; cur_h[d][k2]--;\n            for (int i = lo; i < hi; i++) cur_bnd[d][i] -= dsign;\n        }\n    }\n    \n    for (int d = 0; d < D; d++) {\n        int y = 0;\n        for (int k = 0; k < N; k++) { cout << y << \" 0 \" << y + best_h[d][k] << \" \" << W << \"\\n\"; y += best_h[d][k]; }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nlong long bmod[81];\nlong long s_val[180];\nint ops[81];\nint op_p[81];\nint op_q[81];\nint L = 0;\n\nstruct FastRNG {\n    unsigned long long x = 123456789, y = 362436069, z = 521288629;\n    unsigned long long operator()() {\n        unsigned long long t;\n        x ^= x << 16;\n        x ^= x >> 5;\n        x ^= x << 1;\n        t = x;\n        x = y;\n        y = z;\n        z = t ^ x ^ y;\n        return z;\n    }\n};\n\nFastRNG rng;\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 < 81; i++) cin >> bmod[i];\n    \n    for (int m = 0; m < M; m++)\n        for (int i = 0; i < 9; i++)\n            cin >> s_val[m * 9 + i];\n            \n    // Greedy Initialization\n    for (int k = 0; k < K; k++) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        long long best_delta = 0;\n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p < 7; p++) {\n                for (int q = 0; q < 7; q++) {\n                    long long delta = 0;\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            int u = (p + i) * 9 + (q + j);\n                            long long nv = bmod[u] + s_val[m * 9 + i * 3 + j];\n                            if (nv >= MOD) nv -= MOD;\n                            delta += nv - bmod[u];\n                        }\n                    }\n                    if (delta > best_delta) {\n                        best_delta = delta;\n                        best_m = m; best_p = p; best_q = q;\n                    }\n                }\n            }\n        }\n        if (best_delta <= 0) break;\n        ops[L] = best_m; op_p[L] = best_p; op_q[L] = best_q;\n        L++;\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                int u = (best_p + i) * 9 + (best_q + j);\n                long long nv = bmod[u] + s_val[best_m * 9 + i * 3 + j];\n                if (nv >= MOD) nv -= MOD;\n                bmod[u] = nv;\n            }\n        }\n    }\n    \n    long long score = 0;\n    for (int i = 0; i < 81; i++) score += bmod[i];\n    \n    long long best_score = score;\n    int best_L = L;\n    int best_ops[81], best_op_p[81], best_op_q[81];\n    memcpy(best_ops, ops, L * sizeof(int));\n    memcpy(best_op_p, op_p, L * sizeof(int));\n    memcpy(best_op_q, op_q, L * sizeof(int));\n    \n    double start_temp = 2e9, end_temp = 1e5;\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    int iter = 0;\n    while (true) {\n        iter++;\n        if (iter % 10000 == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - start_time).count();\n            if (elapsed > 1.8) break;\n        }\n        \n        double temp = start_temp * pow(end_temp / start_temp, min(1.0, chrono::duration<double>(chrono::high_resolution_clock::now() - start_time).count() / 1.8));\n        \n        int move_type = rng() % 100;\n        long long delta = 0;\n        \n        if (move_type < 8 && L < K) {\n            int new_m = rng() % M;\n            int new_p = rng() % 7;\n            int new_q = rng() % 7;\n            \n            long long old_score = 0;\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) old_score += bmod[(new_p + i) * 9 + (new_q + j)];\n            \n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (new_p + i) * 9 + (new_q + j);\n                long long nv = bmod[u] + s_val[new_m * 9 + i * 3 + j];\n                if (nv >= MOD) nv -= MOD;\n                bmod[u] = nv;\n            }\n            \n            long long new_score = 0;\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) new_score += bmod[(new_p + i) * 9 + (new_q + j)];\n            \n            delta = new_score - old_score;\n            \n            if (delta >= 0 || (delta / temp > -20 && exp(delta / temp) > (double)(rng() % 1000000) / 1000000.0)) {\n                ops[L] = new_m; op_p[L] = new_p; op_q[L] = new_q;\n                L++;\n                score += delta;\n                if (score > best_score) {\n                    best_score = score; best_L = L;\n                    memcpy(best_ops, ops, L * sizeof(int));\n                    memcpy(best_op_p, op_p, L * sizeof(int));\n                    memcpy(best_op_q, op_q, L * sizeof(int));\n                }\n            } else {\n                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                    int u = (new_p + i) * 9 + (new_q + j);\n                    long long nv = bmod[u] - s_val[new_m * 9 + i * 3 + j];\n                    if (nv < 0) nv += MOD;\n                    bmod[u] = nv;\n                }\n            }\n        } else if (move_type < 12 && L > 0) {\n            int idx = rng() % L;\n            int old_m = ops[idx], old_p = op_p[idx], old_q = op_q[idx];\n            \n            long long old_score = 0;\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) old_score += bmod[(old_p + i) * 9 + (old_q + j)];\n            \n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (old_p + i) * 9 + (old_q + j);\n                long long nv = bmod[u] - s_val[old_m * 9 + i * 3 + j];\n                if (nv < 0) nv += MOD;\n                bmod[u] = nv;\n            }\n            \n            long long new_score = 0;\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) new_score += bmod[(old_p + i) * 9 + (old_q + j)];\n            \n            delta = new_score - old_score;\n            \n            if (delta >= 0 || (delta / temp > -20 && exp(delta / temp) > (double)(rng() % 1000000) / 1000000.0)) {\n                ops[idx] = ops[L - 1]; op_p[idx] = op_p[L - 1]; op_q[idx] = op_q[L - 1];\n                L--;\n                score += delta;\n                if (score > best_score) {\n                    best_score = score; best_L = L;\n                    memcpy(best_ops, ops, L * sizeof(int));\n                    memcpy(best_op_p, op_p, L * sizeof(int));\n                    memcpy(best_op_q, op_q, L * sizeof(int));\n                }\n            } else {\n                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                    int u = (old_p + i) * 9 + (old_q + j);\n                    long long nv = bmod[u] + s_val[old_m * 9 + i * 3 + j];\n                    if (nv >= MOD) nv -= MOD;\n                    bmod[u] = nv;\n                }\n            }\n        } else if (L > 0) {\n            int idx = rng() % L;\n            int old_m = ops[idx], old_p = op_p[idx], old_q = op_q[idx];\n            \n            int r = rng() % 5;\n            int new_m = old_m, new_p = old_p, new_q = old_q;\n            if (r == 0) new_m = rng() % M;\n            else if (r == 1) new_p = rng() % 7;\n            else if (r == 2) new_q = rng() % 7;\n            else if (r == 3) { new_p = rng() % 7; new_q = rng() % 7; }\n            else { new_m = rng() % M; new_p = rng() % 7; new_q = rng() % 7; }\n            \n            if (new_m == old_m && new_p == old_p && new_q == old_q) continue;\n            \n            bool affected[81] = {false};\n            int affected_list[18];\n            int affected_count = 0;\n            \n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (old_p + i) * 9 + (old_q + j);\n                if (!affected[u]) {\n                    affected[u] = true;\n                    affected_list[affected_count++] = u;\n                }\n            }\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (new_p + i) * 9 + (new_q + j);\n                if (!affected[u]) {\n                    affected[u] = true;\n                    affected_list[affected_count++] = u;\n                }\n            }\n            \n            long long old_score = 0;\n            for (int k = 0; k < affected_count; k++) old_score += bmod[affected_list[k]];\n            \n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (old_p + i) * 9 + (old_q + j);\n                long long nv = bmod[u] - s_val[old_m * 9 + i * 3 + j];\n                if (nv < 0) nv += MOD;\n                bmod[u] = nv;\n            }\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (new_p + i) * 9 + (new_q + j);\n                long long nv = bmod[u] + s_val[new_m * 9 + i * 3 + j];\n                if (nv >= MOD) nv -= MOD;\n                bmod[u] = nv;\n            }\n            \n            long long new_score = 0;\n            for (int k = 0; k < affected_count; k++) new_score += bmod[affected_list[k]];\n            \n            delta = new_score - old_score;\n            \n            if (delta >= 0 || (delta / temp > -20 && exp(delta / temp) > (double)(rng() % 1000000) / 1000000.0)) {\n                ops[idx] = new_m; op_p[idx] = new_p; op_q[idx] = new_q;\n                score += delta;\n                if (score > best_score) {\n                    best_score = score; best_L = L;\n                    memcpy(best_ops, ops, L * sizeof(int));\n                    memcpy(best_op_p, op_p, L * sizeof(int));\n                    memcpy(best_op_q, op_q, L * sizeof(int));\n                }\n            } else {\n                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                    int u = (new_p + i) * 9 + (new_q + j);\n                    long long nv = bmod[u] - s_val[new_m * 9 + i * 3 + j];\n                    if (nv < 0) nv += MOD;\n                    bmod[u] = nv;\n                }\n                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                    int u = (old_p + i) * 9 + (old_q + j);\n                    long long nv = bmod[u] + s_val[old_m * 9 + i * 3 + j];\n                    if (nv >= MOD) nv -= MOD;\n                    bmod[u] = nv;\n                }\n            }\n            for (int k = 0; k < affected_count; k++) affected[affected_list[k]] = false;\n        }\n    }\n    \n    cout << best_L << \"\\n\";\n    for (int i = 0; i < best_L; i++)\n        cout << best_ops[i] << \" \" << best_op_p[i] << \" \" << best_op_q[i] << \"\\n\";\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <cstdlib>\n#include <climits>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N], grid[N][N];\nbool dispatched[N*N];\nint nxt_recv[N];\nint cr, cc, ch;\nint total_disp;\nvector<string> acts(N);\n\nint next_exp(int g) {\n    for (int j = 0; j < N; j++)\n        if (!dispatched[N*g+j]) return N*g+j;\n    return -1;\n}\n\nchar move_toward(int& r, int& c, int tr, int tc) {\n    if (r < tr) { r++; return 'D'; }\n    if (r > tr) { r--; return 'U'; }\n    if (c < tc) { c++; return 'R'; }\n    if (c > tc) { c--; return 'L'; }\n    return '.';\n}\n\nint main() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> A[i][j];\n    \n    memset(grid, -1, sizeof(grid));\n    fill(dispatched, dispatched+N*N, false);\n    fill(nxt_recv, nxt_recv+N, 0);\n    cr = cc = 0; ch = -1; total_disp = 0;\n    \n    // Turn 0: bomb small cranes\n    for (int i = 0; i < N; i++) acts[i] += (i ? 'B' : '.');\n    for (int i = 0; i < N; i++)\n        if (nxt_recv[i] < N) grid[i][0] = A[i][nxt_recv[i]++];\n    \n    for (int t = 1; total_disp < N*N && (int)acts[0].size() < 9999; t++) {\n        for (int i = 0; i < N; i++)\n            if (nxt_recv[i] < N && grid[i][0] == -1 && !(cr==i && cc==0 && ch!=-1))\n                grid[i][0] = A[i][nxt_recv[i]++];\n        \n        char a = '.';\n        if (ch >= 0) {\n            int g = ch/N, e = next_exp(g);\n            int tr, tc;\n            if (e >= 0 && e == ch) {\n                tr = g; tc = N-1;\n            } else {\n                tr = tc = -1;\n                int bd = INT_MAX;\n                for (int c = 1; c < N-1; c++)\n                    for (int r = 0; r < N; r++)\n                        if (grid[r][c] == -1) {\n                            int d = abs(cr-r)+abs(cc-c)+abs(r-g)*3;\n                            if (d < bd) { bd=d; tr=r; tc=c; }\n                        }\n                if (tr == -1) { tr = g; tc = N-1; }\n            }\n            if (cr==tr && cc==tc) { a='Q'; grid[tr][tc]=ch; ch=-1; }\n            else a = move_toward(cr, cc, tr, tc);\n        } else {\n            int bc=-1, bs=INT_MAX, br=-1, bcc=-1;\n            for (int r = 0; r < N; r++)\n                for (int c = 0; c < N; c++) {\n                    if (grid[r][c] < 0) continue;\n                    int co=grid[r][c], g=co/N, e=next_exp(g);\n                    int d = abs(cr-r)+abs(cc-c), s;\n                    if (e >= 0 && e == co) s = -5000+d;\n                    else if (c==0 && nxt_recv[r]<N) {\n                        int nc=A[r][nxt_recv[r]], ng=nc/N, ne=next_exp(ng);\n                        s = (ne>=0 && ne==nc) ? -3000+d : -1000+d;\n                    } else if (c==0) s = -500+d;\n                    else s = d+500;\n                    if (s<bs) { bs=s; bc=co; br=r; bcc=c; }\n                }\n            if (bc>=0) {\n                if (cr==br && cc==bcc) { a='P'; ch=bc; grid[br][bcc]=-1; }\n                else a = move_toward(cr, cc, br, bcc);\n            }\n        }\n        \n        acts[0] += a;\n        for (int i = 1; i < N; i++) acts[i] += '.';\n        \n        for (int i = 0; i < N; i++)\n            if (grid[i][N-1]>=0) { dispatched[grid[i][N-1]]=true; grid[i][N-1]=-1; total_disp++; }\n    }\n    \n    int ml = 0;\n    for (int i = 0; i < N; i++) ml = max(ml, (int)acts[i].size());\n    for (int i = 0; i < N; i++) {\n        while ((int)acts[i].size() < ml) acts[i] += '.';\n        cout << acts[i] << endl;\n    }\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <climits>\n#include <algorithm>\nusing namespace std;\ntypedef long long ll;\nconst ll INF = 1e18;\nstruct Edge { int to, rev; ll cap, cost; };\nstruct MinCostFlow {\n    int n; vector<vector<Edge>> graph; vector<ll> h; vector<int> pv, pe;\n    MinCostFlow(int n):n(n),graph(n),h(n,0),pv(n),pe(n){}\n    void add_edge(int f,int t,ll cap,ll cost){\n        graph[f].push_back({t,(int)graph[t].size(),cap,cost});\n        graph[t].push_back({f,(int)graph[f].size()-1,0,-cost});\n    }\n    ll min_cost_flow(int s,int t,ll mf){\n        ll res=0,flow=0;\n        while(flow<mf){\n            priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<>>pq;\n            vector<ll>dist(n,INF);dist[s]=0;pq.push({0,s});\n            while(!pq.empty()){\n                auto[d,v]=pq.top();pq.pop();\n                if(dist[v]<d)continue;\n                for(int i=0;i<(int)graph[v].size();i++){\n                    Edge&e=graph[v][i];\n                    if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){\n                        dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];\n                        pv[e.to]=v;pe[e.to]=i;pq.push({dist[e.to],e.to});\n                    }\n                }\n            }\n            if(dist[t]==INF)break;\n            for(int v=0;v<n;v++)h[v]+=dist[v];\n            ll d=mf-flow;\n            for(int v=t;v!=s;v=pv[v])d=min(d,graph[pv[v]][pe[v]].cap);\n            flow+=d;res+=d*h[t];\n            for(int v=t;v!=s;v=pv[v]){\n                Edge&e=graph[pv[v]][pe[v]];e.cap-=d;graph[v][e.rev].cap+=d;\n            }\n        }\n        return res;\n    }\n};\nint main(){\n    ios_base::sync_with_stdio(false);cin.tie(NULL);\n    int n;cin>>n;\n    vector<vector<int>>h(n,vector<int>(n));\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)cin>>h[i][j];\n    vector<pair<int,int>>sources,sinks;\n    vector<vector<int>>sid(n,vector<int>(n,-1)),kid(n,vector<int>(n,-1));\n    int tsup=0;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        if(h[i][j]>0){sid[i][j]=sources.size();sources.push_back({i,j});tsup+=h[i][j];}\n        else if(h[i][j]<0){kid[i][j]=sinks.size();sinks.push_back({i,j});}\n    }\n    int P=sources.size(),M=sinks.size();\n    int S=0,T=P+M+1;\n    MinCostFlow mcf(P+M+2);\n    for(int i=0;i<P;i++){auto[si,sj]=sources[i];mcf.add_edge(S,1+i,h[si][sj],0);}\n    for(int j=0;j<M;j++){auto[ti,tj]=sinks[j];mcf.add_edge(1+P+j,T,-h[ti][tj],0);}\n    for(int i=0;i<P;i++){auto[si,sj]=sources[i];\n        for(int j=0;j<M;j++){auto[ti,tj]=sinks[j];\n            ll d=abs(si-ti)+abs(sj-tj);\n            mcf.add_edge(1+i,1+P+j,min((ll)h[si][sj],(ll)-h[ti][tj]),d);\n        }\n    }\n    mcf.min_cost_flow(S,T,tsup);\n    vector<vector<int>>fa(P,vector<int>(M,0));\n    for(int i=0;i<P;i++)for(auto&e:mcf.graph[1+i])\n        if(e.to>=1+P&&e.to<1+P+M)fa[i][e.to-1-P]=(int)mcf.graph[e.to][e.rev].cap;\n    vector<int>snnd(P,0);\n    for(int i=0;i<P;i++){auto[si,sj]=sources[i];int best=INT_MAX;\n        for(int j=0;j<M;j++)if(fa[i][j]>0){auto[ti,tj]=sinks[j];best=min(best,abs(si-ti)+abs(sj-tj));}\n        snnd[i]=(best<INT_MAX)?best:0;\n    }\n    vector<string>ops;int r=0,c=0,load=0,rem=tsup;\n    auto cur=h;\n    while(ops.size()<100000&&(rem>0||load>0)){\n        if(cur[r][c]>0){ops.push_back(\"+\"+to_string(cur[r][c]));load+=cur[r][c];rem-=cur[r][c];cur[r][c]=0;}\n        while(cur[r][c]<0&&load>0){int d=min(load,-cur[r][c]);ops.push_back(\"-\"+to_string(d));load-=d;cur[r][c]+=d;}\n        if(rem==0&&load==0)break;\n        int br=-1,bc=-1;ll bcost=LLONG_MAX;\n        if(load>0){\n            for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(cur[i][j]<0){\n                int d=abs(r-i)+abs(c-j);ll cost=(ll)d*(100+load);\n                if(cost<bcost){bcost=cost;br=i;bc=j;}\n            }\n        }else{\n            for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(cur[i][j]>0){\n                int dt=abs(r-i)+abs(c-j);int s=sid[i][j];\n                int dd=(s>=0)?snnd[s]:20;\n                ll cost=(ll)dt*100+(ll)dd*(100+cur[i][j]);\n                if(cost<bcost){bcost=cost;br=i;bc=j;}\n            }\n        }\n        if(br==-1)break;\n        if(br<r){r--;ops.push_back(\"U\");}\n        else if(br>r){r++;ops.push_back(\"D\");}\n        else if(bc<c){c--;ops.push_back(\"L\");}\n        else{c++;ops.push_back(\"R\");}\n    }\n    for(auto&op:ops)cout<<op<<\"\\n\";\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <numeric>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 6, M = 15;\n    const int SEED_COUNT = 2 * N * (N - 1);\n    const int GRID_SIZE = N * N;\n    \n    int n, m, t;\n    cin >> n >> m >> t;\n    \n    vector<vector<int>> X(SEED_COUNT, vector<int>(M));\n    for (int i = 0; i < SEED_COUNT; i++)\n        for (int j = 0; j < M; j++)\n            cin >> X[i][j];\n    \n    vector<pair<int,int>> edges;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N-1; j++)\n            edges.push_back({i*N+j, i*N+j+1});\n    for (int i = 0; i < N-1; i++)\n        for (int j = 0; j < N; j++)\n            edges.push_back({i*N+j, (i+1)*N+j});\n    \n    const int NUM_EDGES = (int)edges.size();\n    \n    vector<vector<int>> posEdges(GRID_SIZE);\n    vector<vector<int>> posNeighbors(GRID_SIZE);\n    for (int e = 0; e < NUM_EDGES; e++) {\n        posEdges[edges[e].first].push_back(e);\n        posEdges[edges[e].second].push_back(e);\n        posNeighbors[edges[e].first].push_back(edges[e].second);\n        posNeighbors[edges[e].second].push_back(edges[e].first);\n    }\n    \n    vector<int> posOrder(GRID_SIZE);\n    iota(posOrder.begin(), posOrder.end(), 0);\n    sort(posOrder.begin(), posOrder.end(), [](int a, int b) {\n        int ra = a / N, ca = a % N;\n        int rb = b / N, cb = b % N;\n        int da = abs(2*ra - (2*N-2)) + abs(2*ca - (2*N-2));\n        int db = abs(2*rb - (2*N-2)) + abs(2*cb - (2*N-2));\n        if (da != db) return da < db;\n        return a < b;\n    });\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> unif(0.0, 1.0);\n    \n    for (int turn = 0; turn < t; turn++) {\n        vector<int> values(SEED_COUNT, 0);\n        for (int i = 0; i < SEED_COUNT; i++)\n            for (int j = 0; j < M; j++)\n                values[i] += X[i][j];\n        \n        vector<vector<int>> pot(SEED_COUNT, vector<int>(SEED_COUNT, 0));\n        for (int i = 0; i < SEED_COUNT; i++)\n            for (int j = i+1; j < SEED_COUNT; j++) {\n                for (int l = 0; l < M; l++)\n                    pot[i][j] += max(X[i][l], X[j][l]);\n                pot[j][i] = pot[i][j];\n            }\n        \n        // Greedy initial placement\n        vector<int> grid(GRID_SIZE, -1);\n        vector<bool> used(SEED_COUNT, false);\n        \n        for (int pos : posOrder) {\n            int bestSeed = -1;\n            int bestScore = -1;\n            \n            for (int s = 0; s < SEED_COUNT; s++) {\n                if (used[s]) continue;\n                int score = 0;\n                for (int npos : posNeighbors[pos]) {\n                    if (grid[npos] != -1) {\n                        score += pot[s][grid[npos]];\n                    }\n                }\n                if (score == 0) score = values[s];\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestSeed = s;\n                }\n            }\n            \n            grid[pos] = bestSeed;\n            used[bestSeed] = true;\n        }\n        \n        vector<int> unplaced;\n        for (int i = 0; i < SEED_COUNT; i++)\n            if (!used[i]) unplaced.push_back(i);\n        \n        int currentScore = 0;\n        for (int e = 0; e < NUM_EDGES; e++)\n            currentScore += pot[grid[edges[e].first]][grid[edges[e].second]];\n        \n        int bestScore = currentScore;\n        vector<int> bestGrid = grid;\n        \n        auto startTime = chrono::high_resolution_clock::now();\n        const double startTemp = 500.0, endTemp = 0.1;\n        double temp = startTemp;\n        \n        for (int iter = 0; iter < 10000000; iter++) {\n            if (iter % 10000 == 0) {\n                auto now = chrono::high_resolution_clock::now();\n                auto elapsed = chrono::duration_cast<chrono::microseconds>(now - startTime).count();\n                if (elapsed > 180000) break;\n                double progress = (double)elapsed / 180000.0;\n                temp = startTemp * pow(endTemp / startTemp, progress);\n            }\n            \n            if (rng() % 5 != 0) {\n                int i = rng() % GRID_SIZE, j = rng() % GRID_SIZE;\n                if (i == j) continue;\n                \n                int delta = 0;\n                for (int e : posEdges[i]) delta -= pot[grid[edges[e].first]][grid[edges[e].second]];\n                for (int e : posEdges[j]) delta -= pot[grid[edges[e].first]][grid[edges[e].second]];\n                \n                swap(grid[i], grid[j]);\n                \n                for (int e : posEdges[i]) delta += pot[grid[edges[e].first]][grid[edges[e].second]];\n                for (int e : posEdges[j]) delta += pot[grid[edges[e].first]][grid[edges[e].second]];\n                \n                if (delta >= 0 || (temp > 0.5 && unif(rng) < exp((double)delta / temp))) {\n                    currentScore += delta;\n                    if (currentScore > bestScore) { bestScore = currentScore; bestGrid = grid; }\n                } else {\n                    swap(grid[i], grid[j]);\n                }\n            } else {\n                int pos = rng() % GRID_SIZE;\n                int old_seed = grid[pos];\n                int up_idx = rng() % (int)unplaced.size();\n                int new_seed = unplaced[up_idx];\n                \n                int delta = 0;\n                for (int e : posEdges[pos]) delta -= pot[grid[edges[e].first]][grid[edges[e].second]];\n                \n                grid[pos] = new_seed;\n                \n                for (int e : posEdges[pos]) delta += pot[grid[edges[e].first]][grid[edges[e].second]];\n                \n                if (delta >= 0 || (temp > 0.5 && unif(rng) < exp((double)delta / temp))) {\n                    currentScore += delta;\n                    used[old_seed] = false;\n                    used[new_seed] = true;\n                    unplaced[up_idx] = old_seed;\n                    if (currentScore > bestScore) { bestScore = currentScore; bestGrid = grid; }\n                } else {\n                    grid[pos] = old_seed;\n                }\n            }\n        }\n        \n        grid = bestGrid;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << grid[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;\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\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), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n    \n    int Vp = V;\n    vector<int> len(Vp, 1);\n    for (int i = 1; i < Vp; i++) {\n        len[i] = ((i - 1) % (N / 2)) + 1;\n    }\n    \n    cout << Vp << \"\\n\";\n    for (int i = 1; i < Vp; i++) cout << 0 << \" \" << len[i] << \"\\n\";\n    \n    vector<vector<int>> grid(N, vector<int>(N)), target(N, vector<int>(N));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = s[i][j] - '0';\n            target[i][j] = t[i][j] - '0';\n        }\n    \n    vector<pair<int,int>> sources, targets;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] && !target[i][j]) sources.push_back({i, j});\n            if (!grid[i][j] && target[i][j]) targets.push_back({i, j});\n        }\n    \n    int Mm = sources.size();\n    \n    vector<int> match(Mm, -1);\n    vector<tuple<int,int,int>> pairs;\n    for (int i = 0; i < Mm; i++)\n        for (int j = 0; j < Mm; j++)\n            pairs.push_back({abs(sources[i].first - targets[j].first) + \n                            abs(sources[i].second - targets[j].second), i, j});\n    sort(pairs.begin(), pairs.end());\n    \n    vector<bool> sused(Mm, false), tused(Mm, false);\n    for (auto& [d, i, j] : pairs) {\n        if (!sused[i] && !tused[j]) {\n            match[i] = j; sused[i] = true; tused[j] = true;\n        }\n    }\n    \n    int rx, ry;\n    if (Mm > 0) {\n        long long sum_x = 0, sum_y = 0;\n        for (int i = 0; i < Mm; i++) {\n            sum_x += sources[i].first;\n            sum_y += sources[i].second;\n        }\n        rx = sum_x / Mm;\n        ry = sum_y / Mm;\n    } else {\n        rx = N / 2; ry = N / 2;\n    }\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<int> dir(Vp, 0);\n    vector<bool> available_s(Mm, true);\n    vector<int> finger_state(Vp, 0); // 0: IDLE, 1: TO_SOURCE, 2: TO_TARGET\n    vector<int> finger_task(Vp, -1);\n    vector<int> f_target_x(Vp), f_target_y(Vp), f_target_dir(Vp);\n    vector<string> ops;\n    \n    auto dist_to_source = [&](int rx, int ry, int f, int s_idx) {\n        int sx = sources[s_idx].first, sy = sources[s_idx].second;\n        int best_dist = INT_MAX;\n        for (int d = 0; d < 4; d++) {\n            int nx = sx - dx[d] * len[f], ny = sy - dy[d] * len[f];\n            if (0 <= nx && nx < N && 0 <= ny && ny < N) {\n                int dist = abs(rx - nx) + abs(ry - ny);\n                int rot = min((dir[f] - d + 4) % 4, (d - dir[f] + 4) % 4);\n                int cost = max(dist, rot);\n                if (cost < best_dist) best_dist = cost;\n            }\n        }\n        return best_dist;\n    };\n    \n    auto get_best_source_station = [&](int rx, int ry, int f, int s_idx) {\n        int sx = sources[s_idx].first, sy = sources[s_idx].second;\n        int best_dist = INT_MAX, best_nx = -1, best_ny = -1, best_dir = -1;\n        for (int d = 0; d < 4; d++) {\n            int nx = sx - dx[d] * len[f], ny = sy - dy[d] * len[f];\n            if (0 <= nx && nx < N && 0 <= ny && ny < N) {\n                int dist = abs(rx - nx) + abs(ry - ny);\n                int rot = min((dir[f] - d + 4) % 4, (d - dir[f] + 4) % 4);\n                int cost = max(dist, rot);\n                if (cost < best_dist) {\n                    best_dist = cost; best_nx = nx; best_ny = ny; best_dir = d;\n                }\n            }\n        }\n        return make_tuple(best_nx, best_ny, best_dir);\n    };\n    \n    auto get_best_target_station = [&](int rx, int ry, int f, int t_idx) {\n        int tx = targets[t_idx].first, ty = targets[t_idx].second;\n        int best_dist = INT_MAX, best_nx = -1, best_ny = -1, best_dir = -1;\n        for (int d = 0; d < 4; d++) {\n            int nx = tx - dx[d] * len[f], ny = ty - dy[d] * len[f];\n            if (0 <= nx && nx < N && 0 <= ny && ny < N) {\n                int dist = abs(rx - nx) + abs(ry - ny);\n                int rot = min((dir[f] - d + 4) % 4, (d - dir[f] + 4) % 4);\n                int cost = max(dist, rot);\n                if (cost < best_dist) {\n                    best_dist = cost; best_nx = nx; best_ny = ny; best_dir = d;\n                }\n            }\n        }\n        return make_tuple(best_nx, best_ny, best_dir);\n    };\n    \n    // Initial assignments\n    for (int f = 1; f < Vp; f++) {\n        int min_d = INT_MAX, best_s = -1;\n        for (int i = 0; i < Mm; i++) {\n            if (!available_s[i]) continue;\n            int d = dist_to_source(rx, ry, f, i);\n            if (d < min_d) { min_d = d; best_s = i; }\n        }\n        if (best_s != -1) {\n            finger_state[f] = 1;\n            finger_task[f] = best_s;\n            available_s[best_s] = false;\n            tie(f_target_x[f], f_target_y[f], f_target_dir[f]) = get_best_source_station(rx, ry, f, best_s);\n        }\n    }\n    \n    while (true) {\n        int best_dist = INT_MAX;\n        int best_f = -1;\n        for (int f = 1; f < Vp; f++) {\n            if (finger_state[f] == 0) continue;\n            int dist = abs(rx - f_target_x[f]) + abs(ry - f_target_y[f]);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_f = f;\n            }\n        }\n        \n        if (best_f == -1) {\n            bool any_available = false;\n            for (int i = 0; i < Mm; i++) if (available_s[i]) any_available = true;\n            if (!any_available) break;\n            \n            for (int f = 1; f < Vp; f++) {\n                if (finger_state[f] == 0) {\n                    int min_d = INT_MAX, best_s = -1;\n                    for (int i = 0; i < Mm; i++) {\n                        if (!available_s[i]) continue;\n                        int d = dist_to_source(rx, ry, f, i);\n                        if (d < min_d) { min_d = d; best_s = i; }\n                    }\n                    if (best_s != -1) {\n                        finger_state[f] = 1;\n                        finger_task[f] = best_s;\n                        available_s[best_s] = false;\n                        tie(f_target_x[f], f_target_y[f], f_target_dir[f]) = get_best_source_station(rx, ry, f, best_s);\n                    }\n                }\n            }\n            continue;\n        }\n        \n        string op(2 * Vp, '.');\n        if (rx < f_target_x[best_f]) { op[0] = 'D'; rx++; }\n        else if (rx > f_target_x[best_f]) { op[0] = 'U'; rx--; }\n        else if (ry < f_target_y[best_f]) { op[0] = 'R'; ry++; }\n        else if (ry > f_target_y[best_f]) { op[0] = 'L'; ry--; }\n        \n        for (int f = 1; f < Vp; f++) {\n            if (finger_state[f] == 0) continue;\n            if (dir[f] != f_target_dir[f]) {\n                int diff = (f_target_dir[f] - dir[f] + 4) % 4;\n                if (diff <= 2) { op[f] = 'R'; dir[f] = (dir[f] + 1) % 4; }\n                else { op[f] = 'L'; dir[f] = (dir[f] + 3) % 4; }\n            }\n        }\n        \n        for (int f = 1; f < Vp; f++) {\n            if (finger_state[f] == 0) continue;\n            if (rx == f_target_x[f] && ry == f_target_y[f] && dir[f] == f_target_dir[f]) {\n                op[Vp + f] = 'P';\n                if (finger_state[f] == 1) {\n                    int s_idx = finger_task[f];\n                    grid[sources[s_idx].first][sources[s_idx].second] = 0;\n                    finger_state[f] = 2;\n                    int t_idx = match[s_idx];\n                    tie(f_target_x[f], f_target_y[f], f_target_dir[f]) = get_best_target_station(rx, ry, f, t_idx);\n                } else {\n                    int s_idx = finger_task[f];\n                    int t_idx = match[s_idx];\n                    grid[targets[t_idx].first][targets[t_idx].second] = 1;\n                    finger_state[f] = 0;\n                    \n                    int min_d = INT_MAX, best_s = -1;\n                    for (int i = 0; i < Mm; i++) {\n                        if (!available_s[i]) continue;\n                        int d = dist_to_source(rx, ry, f, i);\n                        if (d < min_d) { min_d = d; best_s = i; }\n                    }\n                    if (best_s != -1) {\n                        finger_state[f] = 1;\n                        finger_task[f] = best_s;\n                        available_s[best_s] = false;\n                        tie(f_target_x[f], f_target_y[f], f_target_dir[f]) = get_best_source_station(rx, ry, f, best_s);\n                    }\n                }\n            }\n        }\n        \n        ops.push_back(op);\n    }\n    \n    for (auto& op : ops) cout << op << \"\\n\";\n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; cin >> N;\n    vector<int> fx(2*N), fy(2*N);\n    for (int i = 0; i < 2*N; i++) cin >> fx[i] >> fy[i];\n    \n    auto scoreRect = [&](int x1, int y1, int x2, int y2) {\n        int s = 0;\n        for (int i = 0; i < 2*N; i++) {\n            if (x1 <= fx[i] && fx[i] <= x2 && y1 <= fy[i] && fy[i] <= y2)\n                s += (i < N) ? 1 : -1;\n        }\n        return s;\n    };\n    \n    int GS = 100, CS = 1001;\n    vector<vector<int>> grid(GS, vector<int>(GS, 0));\n    for (int i = 0; i < 2*N; i++) {\n        grid[min(fx[i]/CS,GS-1)][min(fy[i]/CS,GS-1)] += (i < N) ? 1 : -1;\n    }\n    vector<vector<int>> pf(GS+1, vector<int>(GS+1, 0));\n    for (int i = 0; i < GS; i++)\n        for (int j = 0; j < GS; j++)\n            pf[i+1][j+1] = grid[i][j] + pf[i][j+1] + pf[i+1][j] - pf[i][j];\n    auto gs = [&](int x1, int y1, int x2, int y2) {\n        return pf[x2+1][y2+1] - pf[x1][y2+1] - pf[x2+1][y1] + pf[x1][y1];\n    };\n    \n    int bestGS = 0, bgx1=0, bgy1=0, bgx2=0, bgy2=0;\n    for (int gx1 = 0; gx1 < GS; gx1++) {\n        for (int gx2 = gx1; gx2 < GS; gx2++) {\n            int cur=0, best=0, cy1=0, by1=0, by2=-1;\n            for (int gy2 = 0; gy2 < GS; gy2++) {\n                cur += gs(gx1, gy2, gx2, gy2);\n                if (cur > best) { best = cur; by1 = cy1; by2 = gy2; }\n                if (cur < 0) { cur = 0; cy1 = gy2+1; }\n            }\n            if (best > bestGS) { bestGS=best; bgx1=gx1; bgy1=by1; bgx2=gx2; bgy2=by2; }\n        }\n    }\n    \n    int rx1=bgx1*CS, ry1=bgy1*CS, rx2=min((bgx2+1)*CS-1,100000), ry2=min((bgy2+1)*CS-1,100000);\n    \n    for (int iter = 0; iter < 20; iter++) {\n        bool improved = false;\n        for (int dim = 0; dim < 2; dim++) {\n            vector<pair<int,int>> ev;\n            for (int i = 0; i < 2*N; i++) {\n                bool inside = (dim==0) ? (rx1<=fx[i]&&fx[i]<=rx2) : (ry1<=fy[i]&&fy[i]<=ry2);\n                if (inside) ev.push_back({(dim==0)?fy[i]:fx[i], (i<N)?1:-1});\n            }\n            sort(ev.begin(), ev.end());\n            int bs=INT_MIN, b1=(dim==0)?ry1:rx1, b2=(dim==0)?ry2:rx2;\n            int mp=0, mpi=-1, pfx=0;\n            for (int j = 0; j <= (int)ev.size(); j++) {\n                int s = pfx - mp;\n                if (s > bs) {\n                    bs = s;\n                    int v1 = (mpi==-1) ? 0 : ev[mpi].first;\n                    int v2 = (j==(int)ev.size()) ? 100000 : ev[j-1].first;\n                    b1 = v1; b2 = v2;\n                }\n                if (pfx < mp) { mp = pfx; mpi = j; }\n                if (j < (int)ev.size()) pfx += ev[j].second;\n            }\n            if (dim==0) { ry1=b1; ry2=b2; } else { rx1=b1; rx2=b2; }\n        }\n    }\n    \n    int sc = scoreRect(rx1, ry1, rx2, ry2);\n    if (sc <= 0) {\n        cout << 4 << \"\\n50000 50000\\n50001 50000\\n50001 50001\\n50000 50001\\n\";\n    } else {\n        cout << 4 << \"\\n\" << rx1 << \" \" << ry1 << \"\\n\"\n             << rx2 << \" \" << ry1 << \"\\n\"\n             << rx2 << \" \" << ry2 << \"\\n\"\n             << rx1 << \" \" << ry2 << \"\\n\";\n    }\n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\nint N,T,sigma;\nvector<long long>w_obs,h_obs;\nvector<double>w_est,h_est;\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    cin>>N>>T>>sigma;\n    w_obs.resize(N);h_obs.resize(N);w_est.resize(N);h_est.resize(N);\n    for(int i=0;i<N;i++){cin>>w_obs[i]>>h_obs[i];w_est[i]=w_obs[i];h_est[i]=h_obs[i];}\n    mt19937 rng(42);\n    auto start=chrono::steady_clock::now();\n    for(int t=0;t<T;t++){\n        auto now=chrono::steady_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-start).count()>2700)break;\n        vector<long long>wc(N),hc(N);\n        for(int i=0;i<N;i++){wc[i]=max(1LL,(long long)round(w_est[i]));hc[i]=max(1LL,(long long)round(h_est[i]));}\n        vector<long long>px,py,pw,ph;vector<int>plc;vector<tuple<int,int,char,int>>out;\n        long long cW=0,cH=0;\n        bool doRow=(t==0&&T>=20),doCol=(t==1&&T>=20);\n        if(doRow){\n            for(int i=0;i<N;i++){\n                long long rw=wc[i],rh=hc[i],rx=(i==0)?0:px[i-1]+pw[i-1],ry=0LL;\n                px.push_back(rx);py.push_back(ry);pw.push_back(rw);ph.push_back(rh);plc.push_back(i);\n                out.push_back({i,0,'U',(i==0)?-1:(i-1)});cW=max(cW,rx+rw);cH=max(cH,ry+rh);\n            }\n        }else if(doCol){\n            for(int i=0;i<N;i++){\n                long long rw=wc[i],rh=hc[i],ry=(i==0)?0:py[i-1]+ph[i-1],rx=0LL;\n                px.push_back(rx);py.push_back(ry);pw.push_back(rw);ph.push_back(rh);plc.push_back(i);\n                out.push_back({i,0,'L',(i==0)?-1:(i-1)});cW=max(cW,rx+rw);cH=max(cH,ry+rh);\n            }\n        }else{\n            int strat=t%5;bool addN=(t%7>=5);\n            if(addN)for(int i=0;i<N;i++){wc[i]=max(1LL,wc[i]+(long long)(rng()%2001)-1000);hc[i]=max(1LL,hc[i]+(long long)(rng()%2001)-1000);}\n            for(int i=0;i<N;i++){\n                long long bs=LLONG_MAX;int br=0;char bd='U';int bb=-1;long long brx=0,bry=0;\n                int np=(int)px.size();\n                for(int r=0;r<2;r++){\n                    long long rw=r?hc[i]:wc[i],rh=r?wc[i]:hc[i];\n                    for(int b=-1;b<np;b++){\n                        {long long rx=(b<0)?0:px[b]+pw[b],ry=0;\n                         for(int j=0;j<np;j++)if(px[j]<rx+rw&&px[j]+pw[j]>rx)ry=max(ry,py[j]+ph[j]);\n                         long long nW=max(cW,rx+rw),nH=max(cH,ry+rh),s=nW+nH;\n                         if(strat==1)s+=abs(nW-nH)/2;else if(strat==2)s+=abs(nW-nH);else if(strat==3){long long w=nW*nH-cW*cH-rw*rh;s+=w/500;}else if(strat==4)s=max(nW,nH)*2;\n                         if(s<bs){bs=s;br=r;bd='U';bb=b;brx=rx;bry=ry;}}\n                        {long long ry=(b<0)?0:py[b]+ph[b],rx=0;\n                         for(int j=0;j<np;j++)if(py[j]<ry+rh&&py[j]+ph[j]>ry)rx=max(rx,px[j]+pw[j]);\n                         long long nW=max(cW,rx+rw),nH=max(cH,ry+rh),s=nW+nH;\n                         if(strat==1)s+=abs(nW-nH)/2;else if(strat==2)s+=abs(nW-nH);else if(strat==3){long long w=nW*nH-cW*cH-rw*rh;s+=w/500;}else if(strat==4)s=max(nW,nH)*2;\n                         if(s<bs){bs=s;br=r;bd='L';bb=b;brx=rx;bry=ry;}}\n                    }\n                }\n                long long rw=br?hc[i]:wc[i],rh=br?wc[i]:hc[i];\n                px.push_back(brx);py.push_back(bry);pw.push_back(rw);ph.push_back(rh);plc.push_back(i);\n                out.push_back({i,br,bd,bb});cW=max(cW,brx+rw);cH=max(cH,bry+rh);\n            }\n        }\n        cout<<out.size()<<\"\\n\";\n        for(auto&[p,r,d,b]:out)cout<<p<<\" \"<<r<<\" \"<<d<<\" \"<<b<<\"\\n\";\n        cout.flush();\n        long long Wp,Hp;cin>>Wp>>Hp;\n        if(doRow){double ws=0;for(int i=0;i<N;i++)ws+=w_est[i];double c=(ws-Wp)/(N+1);for(int i=0;i<N;i++)w_est[i]=max(1.0,w_est[i]-c);}\n        else if(doCol){double hs=0;for(int i=0;i<N;i++)hs+=h_est[i];double c=(hs-Hp)/(N+1);for(int i=0;i<N;i++)h_est[i]=max(1.0,h_est[i]-c);}\n        else{\n            double We=(double)(Wp-cW),He=(double)(Hp-cH);int rc=0,bc=0;\n            long long margin=2*sigma;\n            for(int j=0;j<(int)px.size();j++){if(px[j]+pw[j]>=cW-margin)rc++;if(py[j]+ph[j]>=cH-margin)bc++;}\n            double lr=0.12;\n            for(int j=0;j<(int)px.size();j++){\n                int o=plc[j];bool rot=get<1>(out[j]);\n                if(px[j]+pw[j]>=cW-margin&&rc>0){double es=We/rc*lr;if(rot)h_est[o]=max(1.0,h_est[o]+es);else w_est[o]=max(1.0,w_est[o]+es);}\n                if(py[j]+ph[j]>=cH-margin&&bc>0){double es=He/bc*lr;if(rot)w_est[o]=max(1.0,w_est[o]+es);else h_est[o]=max(1.0,h_est[o]+es);}\n            }\n        }\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\nint N,M,H;\nvector<int>A;\nvector<vector<int>>adj;\nmt19937 rng(42);\nchrono::steady_clock::time_point T0;\ndouble el(){return chrono::duration<double>(chrono::steady_clock::now()-T0).count();}\nstruct State{\nvector<int>parent,height;vector<long long>sub_sum;vector<int>sub_max_h;long long score;\nvoid recompute(){\nvector<int>deg(N);for(int v=0;v<N;v++)if(parent[v]!=-1)deg[parent[v]]++;\nqueue<int>q;for(int v=0;v<N;v++)if(deg[v]==0)q.push(v);vector<int>ord;\nwhile(!q.empty()){int v=q.front();q.pop();ord.push_back(v);if(parent[v]!=-1&&--deg[parent[v]]==0)q.push(parent[v]);}\nfor(int v:ord)height[v]=(parent[v]==-1)?0:height[parent[v]]+1;\nfill(sub_sum.begin(),sub_sum.end(),0);fill(sub_max_h.begin(),sub_max_h.end(),0);\nfor(int v:ord){sub_sum[v]+=A[v];sub_max_h[v]=max(sub_max_h[v],height[v]);\nif(parent[v]!=-1){sub_sum[parent[v]]+=sub_sum[v];sub_max_h[parent[v]]=max(sub_max_h[parent[v]],sub_max_h[v]);}}\nscore=0;for(int v=0;v<N;v++)score+=(long long)(height[v]+1)*A[v];}\nbool cyc(int v,int np){if(np==-1)return false;for(int c=np;c!=-1;c=parent[c])if(c==v)return true;return false;}\nvoid init(const vector<int>&p){parent=p;height.resize(N);sub_sum.resize(N);sub_max_h.resize(N);recompute();}\n};\nvoid greedy(State&st){\nwhile(true){long long bg=0;int bv=-1,bu=-1;\nfor(int v=0;v<N;v++)for(int u:adj[v]){if(u==st.parent[v])continue;\nint nh=st.height[u]+1,d=nh-st.height[v];if(d<=0||st.sub_max_h[v]+d>H||st.cyc(v,u))continue;\nlong long g=(long long)d*st.sub_sum[v];if(g>bg){bg=g;bv=v;bu=u;}}\nif(bv==-1)break;st.parent[bv]=bu;st.recompute();}}\nvector<int>mbfs(const vector<int>&ro,bool bb){\nvector<int>p(N,-1),h(N,0);vector<bool>vis(N);\nfor(int r:ro){if(vis[r])continue;queue<int>q;q.push(r);vis[r]=true;\nwhile(!q.empty()){int u=q.front();q.pop();if(h[u]>=H)continue;\nvector<int>nb=adj[u];if(bb)sort(nb.begin(),nb.end(),[](int a,int b){return A[a]>A[b];});\nelse shuffle(nb.begin(),nb.end(),rng);\nfor(int v:nb){if(vis[v])continue;vis[v]=true;p[v]=u;h[v]=h[u]+1;q.push(v);}}}return p;}\nvector<int>mdfs(const vector<int>&ro){\nvector<int>p(N,-1),h(N,0);vector<bool>vis(N);\nfor(int r:ro){if(vis[r])continue;vis[r]=true;\nfunction<void(int)>dfs=[&](int u){if(h[u]>=H)return;\nvector<int>nb=adj[u];sort(nb.begin(),nb.end(),[](int a,int b){return A[a]>A[b];});\nfor(int v:nb){if(vis[v])continue;vis[v]=true;p[v]=u;h[v]=h[u]+1;dfs(v);}};dfs(r);}return p;}\nvector<int>mchain(){\nvector<int>p(N,-1);vector<bool>used(N);vector<int>ord(N);iota(ord.begin(),ord.end(),0);\nsort(ord.begin(),ord.end(),[](int a,int b){return A[a]>A[b];});\nfor(int v:ord){if(used[v])continue;vector<int>dist(N,-1),par(N,-1);queue<int>q;\nq.push(v);dist[v]=0;int t=v;while(!q.empty()){int u=q.front();q.pop();\nif(dist[u]>dist[t])t=u;if(dist[u]==H)continue;\nfor(int w:adj[u])if(!used[w]&&dist[w]==-1){dist[w]=dist[u]+1;par[w]=u;q.push(w);}}\nvector<int>path;for(int c=t;;c=par[c]){path.push_back(c);if(c==v)break;}\nfor(int i=0;i<(int)path.size();i++){used[path[i]]=true;p[path[i]]=(i==0)?-1:path[i-1];}}return p;}\nvoid sa(vector<int>&par,long long&bs,double et){\nvector<int>ht(N);\nauto rh=[&](){vector<int>deg(N);for(int v=0;v<N;v++)if(par[v]!=-1)deg[par[v]]++;\nqueue<int>q;for(int v=0;v<N;v++)if(deg[v]==0)q.push(v);vector<int>o;\nwhile(!q.empty()){int v=q.front();q.pop();o.push_back(v);if(par[v]!=-1&&--deg[par[v]]==0)q.push(par[v]);}\nfor(int v:o)ht[v]=(par[v]==-1)?0:ht[par[v]]+1;};rh();\nauto cc=[&](int v,int np)->bool{if(np==-1)return false;for(int c=np;c!=-1;c=par[c])if(c==v)return true;return false;};\nlong long cs=0;for(int v=0;v<N;v++)cs+=(long long)(ht[v]+1)*A[v];\nlong long lb=cs;vector<int>bp=par;double ss=el();double dur=max(.001,et-ss);\nuniform_real_distribution<double>uf(0,1);\nfor(int it=0;;it++){double t=el();if(t>et)break;double T=2000.0*pow(0.001,(t-ss)/dur);\nint v=rng()%N;if(adj[v].empty())continue;int np;\nif(rng()%50==0)np=-1;else np=adj[v][rng()%adj[v].size()];\nif(np==par[v]||cc(v,np))continue;int nh=(np==-1)?0:ht[np]+1,d=nh-ht[v];\nif(d==0)continue;long long sm=0;int mh=0;\nstack<int>stk;stk.push(v);while(!stk.empty()){int u=stk.top();stk.pop();sm+=A[u];mh=max(mh,ht[u]);\nfor(int w:adj[u])if(par[w]==u)stk.push(w);}\nif(mh+d>H)continue;long long g=(long long)d*sm;\nif(g>0||uf(rng)<exp((double)g/T)){par[v]=np;stk.push(v);while(!stk.empty()){int u=stk.top();stk.pop();ht[u]+=d;\nfor(int w:adj[u])if(par[w]==u)stk.push(w);}cs+=g;if(cs>lb){lb=cs;bp=par;}}}\npar=bp;rh();bs=0;for(int v=0;v<N;v++)bs+=(long long)(ht[v]+1)*A[v];}\nint main(){ios_base::sync_with_stdio(false);cin.tie(nullptr);T0=chrono::steady_clock::now();\ncin>>N>>M>>H;A.resize(N);for(int i=0;i<N;i++)cin>>A[i];adj.resize(N);\nfor(int i=0;i<M;i++){int u,v;cin>>u>>v;adj[u].push_back(v);adj[v].push_back(u);}\nvector<int>X(N),Y(N);for(int i=0;i<N;i++)cin>>X[i]>>Y[i];\nlong long bs=0;vector<int>bp(N,-1);auto ts=[&](const vector<int>&p){State st;st.init(p);greedy(st);\nif(st.score>bs){bs=st.score;bp=st.parent;}};\nts(vector<int>(N,-1));\n{vector<int>o(N);iota(o.begin(),o.end(),0);sort(o.begin(),o.end(),[](int a,int b){return A[a]<A[b];});\nts(mbfs(o,true));ts(mdfs(o));}\nts(mchain());\n{vector<int>o(N);iota(o.begin(),o.end(),0);sort(o.begin(),o.end(),[&](int a,int b){\nreturn(X[a]-500)*(X[a]-500)+(Y[a]-500)*(Y[a]-500)<(X[b]-500)*(X[b]-500)+(Y[b]-500)*(Y[b]-500);});\nts(mbfs(o,true));ts(mdfs(o));}\n{vector<int>o(N);iota(o.begin(),o.end(),0);sort(o.begin(),o.end(),[](int a,int b){return A[a]<A[b];});\nint nr=max(1,N/(H+1));vector<int>roots(o.begin(),o.begin()+min(nr,N));\nts(mbfs(roots,true));ts(mdfs(roots));}\nint tr=0;while(el()<0.6){vector<int>o(N);iota(o.begin(),o.end(),0);shuffle(o.begin(),o.end(),rng);\nif(tr%3==0)ts(mbfs(o,true));else if(tr%3==1)ts(mbfs(o,false));else ts(mdfs(o));tr++;}\nlong long ss;sa(bp,ss,1.7);ts(bp);\nfor(int i=0;i<N;i++)cout<<bp[i]<<(i==N-1?\"\\n\":\" \");return 0;}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <map>\n#include <algorithm>\nusing namespace std;\n\nint main() {\n    int N; cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    vector<string> initial_board = board;\n    \n    vector<pair<char,int>> moves;\n    \n    auto shift = [&](char dir, int idx) {\n        if (dir == 'L') {\n            for (int j = 0; j < N-1; j++) board[idx][j] = board[idx][j+1];\n            board[idx][N-1] = '.';\n        } else if (dir == 'R') {\n            for (int j = N-1; j > 0; j--) board[idx][j] = board[idx][j-1];\n            board[idx][0] = '.';\n        } else if (dir == 'U') {\n            for (int i = 0; i < N-1; i++) board[i][idx] = board[i+1][idx];\n            board[N-1][idx] = '.';\n        } else {\n            for (int i = N-1; i > 0; i--) board[i][idx] = board[i-1][idx];\n            board[0][idx] = '.';\n        }\n        moves.push_back({dir, idx});\n    };\n    \n    // Phase 1: Greedy without shift-backs\n    bool greedy_ok = true;\n    while (true) {\n        int best_cost = N + 2;\n        int best_idx = -1;\n        char best_dir = 0;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] != 'x') continue;\n                {bool s=true; for(int k=0;k<j;k++) if(board[i][k]=='o'){s=false;break;} if(s&&j+1<best_cost){best_cost=j+1;best_idx=i;best_dir='L';}}\n                {bool s=true; for(int k=j+1;k<N;k++) if(board[i][k]=='o'){s=false;break;} if(s&&N-j<best_cost){best_cost=N-j;best_idx=i;best_dir='R';}}\n                {bool s=true; for(int k=0;k<i;k++) if(board[k][j]=='o'){s=false;break;} if(s&&i+1<best_cost){best_cost=i+1;best_idx=j;best_dir='U';}}\n                {bool s=true; for(int k=i+1;k<N;k++) if(board[k][j]=='o'){s=false;break;} if(s&&N-i<best_cost){best_cost=N-i;best_idx=j;best_dir='D';}}\n            }\n        }\n        \n        if (best_dir == 0) {\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j] == 'x') greedy_ok = false;\n            break;\n        }\n        for (int k = 0; k < best_cost; k++) shift(best_dir, best_idx);\n    }\n    \n    // Phase 2: Fallback - batch with shift-backs if greedy got stuck\n    if (!greedy_ok) {\n        board = initial_board;\n        moves.clear();\n        \n        struct Oni { int i, j, id; };\n        vector<Oni> onis;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (board[i][j] == 'x') onis.push_back({i, j, (int)onis.size()});\n        \n        map<pair<char,int>, vector<int>> batches;\n        for (auto& o : onis) {\n            bool us=true,ds=true,ls=true,rs=true;\n            for(int k=0;k<o.i;k++) if(board[k][o.j]=='o'){us=false;break;}\n            for(int k=o.i+1;k<N;k++) if(board[k][o.j]=='o'){ds=false;break;}\n            for(int k=0;k<o.j;k++) if(board[o.i][k]=='o'){ls=false;break;}\n            for(int k=o.j+1;k<N;k++) if(board[o.i][k]=='o'){rs=false;break;}\n            char bd=0; int bc=1e9;\n            if(us){int c=o.i+1;if(c<bc){bc=c;bd='U';}}\n            if(ds){int c=N-o.i;if(c<bc){bc=c;bd='D';}}\n            if(ls){int c=o.j+1;if(c<bc){bc=c;bd='L';}}\n            if(rs){int c=N-o.j;if(c<bc){bc=c;bd='R';}}\n            if(bd){int idx=(bd=='L'||bd=='R')?o.i:o.j; batches[{bd,idx}].push_back(o.id);}\n        }\n        \n        set<int> removed;\n        for (char dir : {'U','D','L','R'}) {\n            for (int idx = 0; idx < N; idx++) {\n                auto key = make_pair(dir, idx);\n                if (batches.find(key) == batches.end()) continue;\n                int md = 0;\n                for (int oid : batches[key]) { if(removed.count(oid)) continue; auto& o=onis[oid]; int d=(dir=='U')?o.i+1:(dir=='D')?N-o.i:(dir=='L')?o.j+1:N-o.j; md=max(md,d); }\n                if (md == 0) continue;\n                for (int k = 0; k < md; k++) shift(dir, idx);\n                char opp = (dir=='U')?'D':(dir=='D')?'U':(dir=='L')?'R':'L';\n                for (int k = 0; k < md; k++) shift(opp, idx);\n                for (auto& o : onis) { if(removed.count(o.id)) continue; bool ip=false;\n                    if(dir=='U'&&o.j==idx&&o.i<md) ip=true;\n                    else if(dir=='D'&&o.j==idx&&o.i>=N-md) ip=true;\n                    else if(dir=='L'&&o.i==idx&&o.j<md) ip=true;\n                    else if(dir=='R'&&o.i==idx&&o.j>=N-md) ip=true;\n                    if(ip) removed.insert(o.id); }\n            }\n        }\n    }\n    \n    for (auto& [d, p] : moves) cout << d << \" \" << p << \"\\n\";\n    return 0;\n}","ahc044":"#include <iostream>\n#include <cmath>\n#include <chrono>\n#include <cstring>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nint N, L;\nint T[100];\nint a[100], b[100];\nint best_a[100], best_b[100];\nint best_error = INT_MAX;\n\nuint64_t rng_state = 1234567890123456789ULL;\nuint64_t rng64() {\n    rng_state ^= rng_state >> 12;\n    rng_state ^= rng_state << 25;\n    rng_state ^= rng_state >> 27;\n    return rng_state * 2685821657736338717ULL;\n}\n\nint simulate(int ai[], int bi[]) {\n    int count[100] = {}, ti[100] = {};\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        ti[cur]++;\n        count[cur]++;\n        cur = (count[cur] & 1) ? ai[cur] : bi[cur];\n    }\n    int err = 0;\n    for (int i = 0; i < N; i++) err += abs(ti[i] - T[i]);\n    return err;\n}\n\nvoid try_init(int ai[], int bi[]) {\n    int err = simulate(ai, bi);\n    if (err < best_error) {\n        best_error = err;\n        memcpy(best_a, ai, sizeof(int) * N);\n        memcpy(best_b, bi, sizeof(int) * N);\n    }\n}\n\nvoid greedy_init(int ai[], int bi[], bool avoid_self) {\n    int rem[100]; memcpy(rem, T, sizeof(T));\n    int cnt[100] = {};\n    bool as[100] = {}, bs[100] = {};\n    memset(ai, 0, sizeof(int) * N);\n    memset(bi, 0, sizeof(int) * N);\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        rem[cur]--;\n        cnt[cur]++;\n        if (cnt[cur] & 1) {\n            if (!as[cur]) {\n                int best = -1;\n                for (int j = 0; j < N; j++) {\n                    if (avoid_self && j == cur) continue;\n                    if (best == -1 || rem[j] > rem[best]) best = j;\n                }\n                if (best == -1) best = (cur + 1) % N;\n                ai[cur] = best; as[cur] = true;\n            }\n            cur = ai[cur];\n        } else {\n            if (!bs[cur]) {\n                int best = -1;\n                for (int j = 0; j < N; j++) {\n                    if (avoid_self && j == cur) continue;\n                    if (best == -1 || rem[j] > rem[best]) best = j;\n                }\n                if (best == -1) best = (cur + 1) % N;\n                bi[cur] = best; bs[cur] = true;\n            }\n            cur = bi[cur];\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> L;\n    for (int i = 0; i < N; i++) cin >> T[i];\n    \n    int ai[100], bi[100];\n    \n    // Init 1: Simple cycle\n    for (int i = 0; i < N; i++) { ai[i] = (i+1)%N; bi[i] = (i+1)%N; }\n    try_init(ai, bi);\n    \n    // Init 2: Greedy (allow self-loops)\n    greedy_init(ai, bi, false);\n    try_init(ai, bi);\n    \n    // Init 3: Greedy (avoid self-loops)\n    greedy_init(ai, bi, true);\n    try_init(ai, bi);\n    \n    // Init 4: Flow-based\n    {\n        struct Src { int emp; int flow; bool odd; };\n        Src srcs[200];\n        for (int i = 0; i < N; i++) {\n            srcs[2*i] = {i, (T[i]+1)/2, true};\n            srcs[2*i+1] = {i, T[i]/2, false};\n        }\n        sort(srcs, srcs+2*N, [](const Src& a, const Src& b) { return a.flow > b.flow; });\n        int dem[100]; memcpy(dem, T, sizeof(T));\n        for (int s = 0; s < 2*N; s++) {\n            int best = 0;\n            for (int j = 1; j < N; j++) if (dem[j] > dem[best]) best = j;\n            if (srcs[s].odd) ai[srcs[s].emp] = best;\n            else bi[srcs[s].emp] = best;\n            dem[best] -= srcs[s].flow;\n        }\n        try_init(ai, bi);\n    }\n    \n    // Use best init for SA\n    memcpy(a, best_a, sizeof(a));\n    memcpy(b, best_b, sizeof(b));\n    int error = best_error;\n    \n    auto start = chrono::high_resolution_clock::now();\n    double temp = max(50.0, error / 80.0);\n    double cool = 0.993;\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration<double>(now - start).count() > 1.85) break;\n        \n        int i = rng64() % N;\n        bool is_a = rng64() & 1;\n        int old = is_a ? a[i] : b[i];\n        int nv = rng64() % N;\n        if (is_a) a[i] = nv; else b[i] = nv;\n        \n        int ne = simulate(a, b);\n        double delta = ne - error;\n        if (delta <= 0 || (double)(rng64() & 0xFFFFF) / 1048576.0 < exp(-delta / temp)) {\n            error = ne;\n            if (error < best_error) {\n                best_error = error;\n                memcpy(best_a, a, sizeof(a));\n                memcpy(best_b, b, sizeof(b));\n            }\n        } else {\n            if (is_a) a[i] = old; else b[i] = old;\n        }\n        temp *= cool;\n    }\n    \n    for (int i = 0; i < N; i++)\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nuint64_t xy2d(int n, int x, int y) {\n    uint64_t d = 0;\n    for (int s = n/2; s > 0; s /= 2) {\n        int rx = (x & s) > 0;\n        int ry = (y & s) > 0;\n        d += (uint64_t)s * s * ((3 * rx) ^ ry);\n        if (ry == 0) {\n            if (rx == 1) { x = s-1 - x; y = s-1 - y; }\n            swap(x, y);\n        }\n    }\n    return d;\n}\n\nint N, M, Q, L, W;\ndouble cx[800], cy[800], ddist[800][800];\nint qcnt = 0;\n\nvector<pair<int,int>> query(vector<int>& v) {\n    if (qcnt >= Q || (int)v.size() < 2) return {};\n    qcnt++;\n    cout << \"? \" << v.size();\n    for (int x : v) cout << \" \" << x;\n    cout << endl;\n    vector<pair<int,int>> res(v.size() - 1);\n    for (auto& [a, b] : res) cin >> a >> b;\n    return res;\n}\n\nint par[800], rnk[800];\nvoid init_dsu() { iota(par, par + N, 0); fill(rnk, rnk + N, 0); }\nint find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }\nbool unite(int x, int y) {\n    x = find(x); y = find(y);\n    if (x == y) return false;\n    if (rnk[x] < rnk[y]) swap(x, y);\n    par[y] = x;\n    if (rnk[x] == rnk[y]) rnk[x]++;\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    mt19937 rng(1337);\n    \n    cin >> N >> M >> Q >> L >> W;\n    vector<int> G(M);\n    for (int& g : G) cin >> g;\n    \n    for (int i = 0; i < N; i++) {\n        int a, b, c, d;\n        cin >> a >> b >> c >> d;\n        cx[i] = (a + b) / 2.0;\n        cy[i] = (c + d) / 2.0;\n    }\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            double dx = cx[i] - cx[j], dy = cy[i] - cy[j];\n            ddist[i][j] = sqrt(dx*dx + dy*dy);\n        }\n    \n    vector<uint64_t> hilbert_idx(N);\n    for(int i=0; i<N; ++i) hilbert_idx[i] = xy2d(32768, (int)cx[i], (int)cy[i]);\n    \n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a, int b) {\n        return hilbert_idx[a] < hilbert_idx[b];\n    });\n    \n    vector<double> cut_cost(N, 0.0);\n    for (int j = 1; j < N; j++) {\n        cut_cost[j] = ddist[ord[j-1]][ord[j]];\n    }\n    \n    vector<int> p(M);\n    iota(p.begin(), p.end(), 0);\n    \n    if (M <= 20) {\n        vector<double> dp(1 << M, -1.0);\n        dp[0] = 0.0;\n        for (int mask = 0; mask < (1 << M); mask++) {\n            if (dp[mask] < -0.5) continue;\n            int s = 0;\n            for (int i = 0; i < M; i++) if (mask & (1 << i)) s += G[i];\n            for (int i = 0; i < M; i++) {\n                if (!(mask & (1 << i))) {\n                    int next_mask = mask | (1 << i);\n                    int next_s = s + G[i];\n                    double cost = dp[mask] + (next_s < N ? cut_cost[next_s] : 0.0);\n                    if (cost > dp[next_mask]) dp[next_mask] = cost;\n                }\n            }\n        }\n        int mask = (1 << M) - 1;\n        for (int k = M - 1; k >= 0; k--) {\n            int s = 0;\n            for (int i = 0; i < M; i++) if (mask & (1 << i)) s += G[i];\n            for (int i = 0; i < M; i++) {\n                if (mask & (1 << i)) {\n                    int prev_mask = mask ^ (1 << i);\n                    double cost = dp[prev_mask] + (s < N ? cut_cost[s] : 0.0);\n                    if (abs(cost - dp[mask]) < 1e-9) {\n                        p[k] = i;\n                        mask = prev_mask;\n                        break;\n                    }\n                }\n            }\n        }\n    } else {\n        sort(p.begin(), p.end(), [&](int a, int b) { return G[a] > G[b]; });\n        vector<int> prefix(M);\n        int s = 0;\n        for (int i = 0; i < M; i++) { s += G[p[i]]; prefix[i] = s; }\n        \n        double current_cost = 0.0;\n        for (int i = 0; i < M - 1; i++) current_cost += cut_cost[prefix[i]];\n        \n        for (int iter = 0; iter < 1000000; iter++) {\n            int i = rng() % M;\n            int j = rng() % M;\n            if (i == j) continue;\n            if (i > j) swap(i, j);\n            \n            double old_cost = 0.0;\n            for (int k = i; k < j; k++) old_cost += cut_cost[prefix[k]];\n            \n            swap(p[i], p[j]);\n            int s_prev = (i == 0 ? 0 : prefix[i-1]);\n            double new_cost = 0.0;\n            for (int k = i; k < j; k++) {\n                s_prev += G[p[k]];\n                new_cost += cut_cost[s_prev];\n            }\n            \n            if (new_cost > old_cost) {\n                s_prev = (i == 0 ? 0 : prefix[i-1]);\n                for (int k = i; k < j; k++) {\n                    s_prev += G[p[k]];\n                    prefix[k] = s_prev;\n                }\n                current_cost += (new_cost - old_cost);\n            } else {\n                swap(p[i], p[j]);\n            }\n        }\n    }\n    \n    vector<vector<int>> grp(M);\n    int curr = 0;\n    for (int k = 0; k < M; k++) {\n        int group_idx = p[k];\n        int sz = G[group_idx];\n        for (int j = 0; j < sz; j++) {\n            grp[group_idx].push_back(ord[curr++]);\n        }\n    }\n    \n    vector<int> proc_order(M);\n    iota(proc_order.begin(), proc_order.end(), 0);\n    sort(proc_order.begin(), proc_order.end(), [&](int a, int b) {\n        return G[a] < G[b];\n    });\n    \n    vector<vector<pair<int,int>>> ans(M);\n    \n    for (int k : proc_order) {\n        int G_size = grp[k].size();\n        if (G_size <= 1) continue;\n        \n        init_dsu();\n        vector<pair<int,int>> mst;\n        \n        if (G_size <= L) {\n            if (qcnt < Q) mst = query(grp[k]);\n        } else {\n            int start = 0;\n            while (start < G_size) {\n                int end = min(start + L, G_size);\n                if (end - start < 2) break;\n                vector<int> qv(grp[k].begin() + start, grp[k].begin() + end);\n                if (qcnt < Q) {\n                    auto edges = query(qv);\n                    for (auto& [a, b] : edges) {\n                        if (unite(a, b)) {\n                            mst.emplace_back(a, b);\n                        }\n                    }\n                } else {\n                    break;\n                }\n                start += L - 1;\n            }\n        }\n        \n        if (mst.size() < (size_t)G_size - 1) {\n            vector<tuple<double,int,int>> edges;\n            for (int i = 0; i < G_size; i++)\n                for (int j = i + 1; j < G_size; j++)\n                    edges.emplace_back(ddist[grp[k][i]][grp[k][j]], grp[k][i], grp[k][j]);\n            sort(edges.begin(), edges.end());\n            for (auto& [d, a, b] : edges) {\n                if (unite(a, b)) {\n                    mst.emplace_back(a, b);\n                }\n                if (mst.size() == (size_t)G_size - 1) break;\n            }\n        }\n        ans[k] = mst;\n    }\n    \n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < (int)grp[k].size(); i++) cout << grp[k][i] << \" \\n\"[i==(int)grp[k].size()-1];\n        for (auto& [a, b] : ans[k]) cout << a << \" \" << b << \"\\n\";\n    }\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <set>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <climits>\n#include <cstring>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\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    bool block_grid[20][20] = {};\n    int cur_r = targets[0].first, cur_c = targets[0].second;\n    vector<pair<char,char>> actions;\n    \n    const int DR[] = {-1, 1, 0, 0};\n    const int DC[] = {0, 0, -1, 1};\n    const char DIR_CHAR[] = {'U', 'D', 'L', 'R'};\n    const char ALTER_TOWARD[] = {'D', 'U', 'R', 'L'};\n    \n    bool is_target[20][20] = {};\n    for (auto& [r, c] : targets) is_target[r][c] = true;\n    \n    auto slide_fn = [&](int r, int c, int d) -> pair<int,int> {\n        int nr = r + DR[d], nc = c + DC[d];\n        while (nr >= 0 && nr < N && nc >= 0 && nc < N && !block_grid[nr][nc]) {\n            nr += DR[d]; nc += DC[d];\n        }\n        return {nr - DR[d], nc - DC[d]};\n    };\n    \n    auto bfs = [&](int sr, int sc, int tr, int tc) -> vector<tuple<char,char,int,int>> {\n        if (sr == tr && sc == tc) return {};\n        int dist[20][20]; memset(dist, -1, sizeof(dist));\n        int pr[20][20], pc[20][20], pa[20][20], pd[20][20];\n        memset(pr, -1, sizeof(pr)); memset(pc, -1, sizeof(pc));\n        \n        queue<pair<int,int>> q;\n        q.push({sr, sc}); dist[sr][sc] = 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 < N && nc >= 0 && nc < N && !block_grid[nr][nc] && dist[nr][nc] < 0) {\n                    dist[nr][nc] = dist[r][c] + 1;\n                    pr[nr][nc] = r; pc[nr][nc] = c; pa[nr][nc] = 0; pd[nr][nc] = d;\n                    if (nr == tr && nc == tc) goto found;\n                    q.push({nr, nc});\n                }\n                auto [snr, snc] = slide_fn(r, c, d);\n                if ((snr != r || snc != c) && dist[snr][snc] < 0) {\n                    dist[snr][snc] = dist[r][c] + 1;\n                    pr[snr][snc] = r; pc[snr][snc] = c; pa[snr][snc] = 1; pd[snr][snc] = d;\n                    if (snr == tr && snc == tc) goto found;\n                    q.push({snr, snc});\n                }\n            }\n        }\n        return {};\n    found:\n        vector<tuple<char,char,int,int>> path;\n        int cr = tr, cc = tc;\n        while (cr != sr || cc != sc) {\n            path.push_back({pa[cr][cc] ? 'S' : 'M', DIR_CHAR[pd[cr][cc]], cr, cc});\n            int rr = pr[cr][cc], rc = pc[cr][cc]; cr = rr; cc = rc;\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n    \n    auto is_connected = [&]() -> bool {\n        int sr = -1, sc = -1, fc = 0;\n        for (int r = 0; r < N; r++)\n            for (int c = 0; c < N; c++)\n                if (!block_grid[r][c]) { fc++; if (sr < 0) { sr = r; sc = c; } }\n        if (fc == 0) return true;\n        bool vis[20][20] = {};\n        queue<pair<int,int>> q;\n        q.push({sr, sc}); vis[sr][sc] = true; int cnt = 1;\n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            for (int d = 0; d < 4; d++) {\n                int nr = r + DR[d], nc = c + DC[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !block_grid[nr][nc] && !vis[nr][nc]) {\n                    vis[nr][nc] = true; cnt++; q.push({nr, nc});\n                }\n            }\n        }\n        return cnt == fc;\n    };\n    \n    auto can_place = [&](int br, int bc, int t) -> bool {\n        if (br < 0 || br >= N || bc < 0 || bc >= N) return false;\n        if (block_grid[br][bc]) return false;\n        if (is_target[br][bc]) return false;\n        block_grid[br][bc] = true;\n        bool ok = is_connected();\n        if (ok) {\n            for (int f = t + 1; f < M && ok; f++) {\n                int ftr = targets[f].first, ftc = targets[f].second;\n                if (block_grid[ftr][ftc]) { ok = false; break; }\n                int bn = 0, vn = 0;\n                for (int d = 0; d < 4; d++) {\n                    int nr = ftr + DR[d], nc = ftc + DC[d];\n                    if (nr < 0 || nr >= N || nc < 0 || nc >= N) continue;\n                    vn++; if (block_grid[nr][nc]) bn++;\n                }\n                if (vn > 0 && bn >= vn) ok = false;\n            }\n        }\n        block_grid[br][bc] = false;\n        return ok;\n    };\n    \n    for (int t = 1; t < M; t++) {\n        int tr = targets[t].first, tc = targets[t].second;\n        \n        if (block_grid[tr][tc]) {\n            int best_d = -1, best_len = INT_MAX;\n            vector<tuple<char,char,int,int>> best_p;\n            for (int d = 0; d < 4; d++) {\n                int ar = tr + DR[d], ac = tc + DC[d];\n                if (ar < 0 || ar >= N || ac < 0 || ac >= N) continue;\n                if (block_grid[ar][ac]) continue;\n                auto p = bfs(cur_r, cur_c, ar, ac);\n                if (!p.empty() && (int)p.size() < best_len) {\n                    best_len = p.size(); best_d = d; best_p = move(p);\n                }\n            }\n            if (best_d >= 0) {\n                for (auto& [a, dir, nr, nc] : best_p) {\n                    actions.push_back({a, dir}); cur_r = nr; cur_c = nc;\n                }\n                block_grid[tr][tc] = false;\n                actions.push_back({'A', ALTER_TOWARD[best_d]});\n            }\n        }\n        \n        auto path = bfs(cur_r, cur_c, tr, tc);\n        for (auto& [a, dir, nr, nc] : path) {\n            actions.push_back({a, dir}); cur_r = nr; cur_c = nc;\n        }\n        \n        int placed = 0;\n        for (int d : {1, 3, 0, 2}) {\n            if (placed >= 2) break;\n            int br = cur_r + DR[d], bc = cur_c + DC[d];\n            if (can_place(br, bc, t)) {\n                block_grid[br][bc] = true;\n                actions.push_back({'A', DIR_CHAR[d]});\n                placed++;\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, r;\nvector<int> ra, rb, rc, rd;\n\ninline double satisfaction(long long s, long long rv) {\n    if (s <= 0 || rv <= 0) return 0;\n    double ratio = (double)min(s, rv) / max(s, rv);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\ndouble compute_score() {\n    double s = 0;\n    for (int i = 0; i < n; i++)\n        s += satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]), r[i]);\n    return s;\n}\n\nstruct TNode {\n    bool is_leaf; int company; bool vertical; int split_k;\n    vector<int> items; int lc, rc_node;\n    long long total_r, left_r; int maxL, minR;\n    int bL, bB, bR, bT;\n};\nvector<TNode> tree;\nvector<int> split_offset;\n\nint build_tree(vector<int> items, mt19937& rng, int strategy) {\n    int idx = tree.size();\n    tree.push_back({});\n    if (items.size() == 1) {\n        tree[idx] = {true, items[0], false, 0, items, -1, -1, (long long)r[items[0]], 0LL, 0, 0, 0,0,0,0};\n        return idx;\n    }\n    long long total_r = 0;\n    for (int i : items) total_r += r[i];\n    struct Cand { bool vert; int k; double score; };\n    vector<Cand> cands;\n    for (int dir = 0; dir < 2; dir++) {\n        bool vert = (dir == 0);\n        auto sorted = items;\n        sort(sorted.begin(), sorted.end(), [&](int i, int j) { return vert ? x[i] < x[j] : y[i] < y[j]; });\n        auto& coord = vert ? x : y;\n        long long sum = 0;\n        for (int k = 1; k < (int)sorted.size(); k++) {\n            sum += r[sorted[k-1]];\n            if (coord[sorted[k-1]] >= coord[sorted[k]]) continue;\n            double r_ratio = (double)sum / total_r;\n            double score;\n            switch(strategy % 9) {\n                case 0: score = -abs(r_ratio-0.5)*2; break;\n                case 1: score = (vert?0.5:-0.5)-abs(r_ratio-0.5); break;\n                case 2: score = (!vert?0.5:-0.5)-abs(r_ratio-0.5); break;\n                case 3: { int gap = coord[sorted[k]]-coord[sorted[k-1]]; score = gap*0.002-abs(r_ratio-0.5); break; }\n                case 4: score = uniform_real_distribution<double>(0,1)(rng); break;\n                case 5: score = -abs(r_ratio-0.5); break;\n                case 6: score = -abs(r_ratio-0.5)*0.5+uniform_real_distribution<double>(0,0.3)(rng); break;\n                case 7: score = -abs(r_ratio-0.5)*0.1+uniform_real_distribution<double>(0,0.5)(rng); break;\n                case 8: score = (vert?-0.2:0.2)-abs(r_ratio-0.5)*0.5+uniform_real_distribution<double>(0,0.2)(rng); break;\n            }\n            score += uniform_real_distribution<double>(0,0.05)(rng);\n            cands.push_back({vert, k, score});\n        }\n    }\n    if (cands.empty()) {\n        tree[idx] = {true, items[0], false, 0, items, -1, -1, (long long)r[items[0]], 0LL, 0, 0, 0,0,0,0};\n        return idx;\n    }\n    sort(cands.begin(), cands.end(), [](const Cand& a, const Cand& b) { return a.score > b.score; });\n    int top = min((int)cands.size(), 5);\n    uniform_int_distribution<int> dist(0, top-1);\n    const Cand& ch = cands[dist(rng)];\n    sort(items.begin(), items.end(), [&](int i, int j) { return ch.vert ? x[i]<x[j] : y[i]<y[j]; });\n    long long left_r = 0;\n    for (int k = 0; k < ch.k; k++) left_r += r[items[k]];\n    auto& coord = ch.vert ? x : y;\n    int mxL = coord[items[ch.k-1]], mnR = coord[items[ch.k]];\n    vector<int> li(items.begin(), items.begin()+ch.k), ri(items.begin()+ch.k, items.end());\n    int lc = build_tree(li, rng, strategy), rc2 = build_tree(ri, rng, strategy);\n    tree[idx] = {false, -1, ch.vert, ch.k, items, lc, rc2, total_r, left_r, mxL, mnR, 0,0,0,0};\n    return idx;\n}\n\nvoid compute_rects(int idx, int L, int B, int R, int T) {\n    if (tree[idx].is_leaf) { int i = tree[idx].company; ra[i]=L; rb[i]=B; rc[i]=R; rd[i]=T; return; }\n    int lo = tree[idx].vertical ? L : B, hi = tree[idx].vertical ? R : T;\n    long long ideal = lo + (long long)(hi-lo)*tree[idx].left_r/tree[idx].total_r;\n    int sp = (int)ideal + split_offset[idx];\n    sp = max(sp, tree[idx].maxL+1); sp = min(sp, tree[idx].minR);\n    sp = max(sp, lo+1); sp = min(sp, hi-1);\n    if (tree[idx].vertical) { compute_rects(tree[idx].lc,L,B,sp,T); compute_rects(tree[idx].rc_node,sp,B,R,T); }\n    else { compute_rects(tree[idx].lc,L,B,R,sp); compute_rects(tree[idx].rc_node,L,sp,R,T); }\n}\n\nvoid update_subtree(int idx) {\n    if (tree[idx].is_leaf) { int i = tree[idx].company; ra[i]=tree[idx].bL; rb[i]=tree[idx].bB; rc[i]=tree[idx].bR; rd[i]=tree[idx].bT; return; }\n    int L=tree[idx].bL, B=tree[idx].bB, R=tree[idx].bR, T=tree[idx].bT;\n    int lo = tree[idx].vertical ? L : B, hi = tree[idx].vertical ? R : T;\n    long long ideal = lo + (long long)(hi-lo)*tree[idx].left_r/tree[idx].total_r;\n    int sp = (int)ideal + split_offset[idx];\n    sp = max(sp, tree[idx].maxL+1); sp = min(sp, tree[idx].minR);\n    sp = max(sp, lo+1); sp = min(sp, hi-1);\n    int lc = tree[idx].lc, rc2 = tree[idx].rc_node;\n    if (tree[idx].vertical) {\n        tree[lc].bL=L; tree[lc].bB=B; tree[lc].bR=sp; tree[lc].bT=T;\n        tree[rc2].bL=sp; tree[rc2].bB=B; tree[rc2].bR=R; tree[rc2].bT=T;\n    } else {\n        tree[lc].bL=L; tree[lc].bB=B; tree[lc].bR=R; tree[lc].bT=sp;\n        tree[rc2].bL=L; tree[rc2].bB=sp; tree[rc2].bR=R; tree[rc2].bT=T;\n    }\n    update_subtree(lc); update_subtree(rc2);\n}\n\nvoid full_update(int root) { tree[root].bL=0; tree[root].bB=0; tree[root].bR=10000; tree[root].bT=10000; update_subtree(root); }\n\ndouble subtree_score(int idx) {\n    double s = 0;\n    for (int i : tree[idx].items) s += satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]), r[i]);\n    return s;\n}\n\nvoid optimize_offsets(int root) {\n    split_offset.assign(tree.size(), 0);\n    compute_rects(root, 0, 0, 10000, 10000);\n    double best = compute_score();\n    vector<int> internal;\n    for (int i = 0; i < (int)tree.size(); i++) if (!tree[i].is_leaf) internal.push_back(i);\n    for (int round = 0; round < 15; round++) {\n        bool improved = false;\n        for (int idx : internal) {\n            for (int d : {-1000,-500,-200,-100,-50,-20,-10,-5,-2,-1,1,2,5,10,20,50,100,200,500,1000}) {\n                split_offset[idx] += d;\n                compute_rects(root, 0, 0, 10000, 10000);\n                bool valid = true;\n                for (int i = 0; i < n && valid; i++) if (ra[i]>x[i]||rc[i]<=x[i]||rb[i]>y[i]||rd[i]<=y[i]) valid = false;\n                if (valid) { double ns = compute_score(); if (ns > best+1e-12) { best=ns; improved=true; continue; } }\n                split_offset[idx] -= d;\n            }\n        }\n        if (!improved) break;\n    }\n    compute_rects(root, 0, 0, 10000, 10000);\n}\n\nvoid sa_offsets(int root, unsigned sa_seed, int max_iter) {\n    full_update(root);\n    vector<int> internal;\n    for (int i = 0; i < (int)tree.size(); i++) if (!tree[i].is_leaf) internal.push_back(i);\n    if (internal.empty()) return;\n    double cur = compute_score(), best = cur;\n    vector<int> best_off = split_offset;\n    mt19937 rng(sa_seed);\n    uniform_int_distribution<int> idist(0, (int)internal.size()-1);\n    uniform_real_distribution<double> adist(0, 1);\n    double temp = 0.03;\n    for (int iter = 0; iter < max_iter; iter++) {\n        int idx = internal[idist(rng)];\n        int d;\n        if (iter < max_iter/5) d = uniform_int_distribution<int>(-500,500)(rng);\n        else if (iter < max_iter*2/5) d = uniform_int_distribution<int>(-100,100)(rng);\n        else if (iter < max_iter*4/5) d = uniform_int_distribution<int>(-10,10)(rng);\n        else d = uniform_int_distribution<int>(-3,3)(rng);\n        if (!d) continue;\n        double old_s = subtree_score(idx);\n        split_offset[idx] += d;\n        update_subtree(idx);\n        bool valid = true;\n        for (int i : tree[idx].items) if (ra[i]>x[i]||rc[i]<=x[i]||rb[i]>y[i]||rd[i]<=y[i]) { valid = false; break; }\n        if (!valid) { split_offset[idx] -= d; update_subtree(idx); continue; }\n        double new_s = subtree_score(idx);\n        double diff = new_s - old_s;\n        if (diff > 0 || adist(rng) < exp(diff/temp)) { cur += diff; if (cur > best) { best = cur; best_off = split_offset; } }\n        else { split_offset[idx] -= d; update_subtree(idx); }\n        temp *= 0.99997;\n    }\n    split_offset = best_off; full_update(root);\n}\n\nvoid post_process() {\n    for (int i = 0; i < n; i++) {\n        while (true) {\n            long long area = (long long)(rc[i]-ra[i])*(rd[i]-rb[i]);\n            if (area <= r[i]) break;\n            double cs = satisfaction(area, r[i]);\n            int bd=-1,bdr=0; double bs=cs;\n            auto try_s = [&](int dim, int dir) {\n                int na=ra[i],nb=rb[i],nc=rc[i],nd=rd[i];\n                if(dim==0&&dir==1)nc--;else if(dim==0&&dir==-1)na++;\n                else if(dim==1&&dir==1)nd--;else nb++;\n                if(na>x[i]||nc<=x[i]||nb>y[i]||nd<=y[i])return;\n                if(nc-na<1||nd-nb<1)return;\n                double ns=satisfaction((long long)(nc-na)*(nd-nb),r[i]);\n                if(ns>bs+1e-12){bs=ns;bd=dim;bdr=dir;}\n            };\n            try_s(0,1);try_s(0,-1);try_s(1,1);try_s(1,-1);\n            if(bd<0)break;\n            if(bd==0&&bdr==1)rc[i]--;else if(bd==0&&bdr==-1)ra[i]++;\n            else if(bd==1&&bdr==1)rd[i]--;else rb[i]++;\n        }\n    }\n    for (int step : {500,200,100,50,20,10,5,2,1}) {\n        bool any = true;\n        while (any) {\n            any = false;\n            vector<pair<double,int>> order;\n            for (int i = 0; i < n; i++) {\n                long long area = (long long)(rc[i]-ra[i])*(rd[i]-rb[i]);\n                if (area < r[i]) order.push_back({-(1.0-satisfaction(area,r[i])), i});\n            }\n            sort(order.begin(), order.end());\n            for (auto& [_, i] : order) {\n                long long area = (long long)(rc[i]-ra[i])*(rd[i]-rb[i]);\n                if (area >= r[i]) continue;\n                double cs = satisfaction(area, r[i]);\n                auto try_e = [&](int dim, int dir) -> bool {\n                    int na=ra[i],nb=rb[i],nc=rc[i],nd=rd[i];\n                    if(dim==0&&dir==1)nc+=step;else if(dim==0&&dir==-1)na-=step;\n                    else if(dim==1&&dir==1)nd+=step;else nb-=step;\n                    if(na<0||nc>10000||nb<0||nd>10000)return false;\n                    if(na>x[i]||nc<=x[i]||nb>y[i]||nd<=y[i])return false;\n                    for(int j=0;j<n;j++){if(j==i)continue;if(na<rc[j]&&nc>ra[j]&&nb<rd[j]&&nd>rb[j])return false;}\n                    double ns=satisfaction((long long)(nc-na)*(nd-nb),r[i]);\n                    if(ns>cs+1e-12){ra[i]=na;rb[i]=nb;rc[i]=nc;rd[i]=nd;return true;}\n                    return false;\n                };\n                if(try_e(0,1)||try_e(0,-1)||try_e(1,1)||try_e(1,-1))any=true;\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> n; x.resize(n); y.resize(n); r.resize(n); ra.resize(n); rb.resize(n); rc.resize(n); rd.resize(n);\n    for (int i = 0; i < n; i++) cin >> x[i] >> y[i] >> r[i];\n    auto start = chrono::steady_clock::now();\n    vector<int> indices(n); iota(indices.begin(), indices.end(), 0);\n    vector<int> ba(n),bb(n),bc(n),bd(n); double bs=-1;\n\n    // Phase 1: Try many seeds with greedy + post-process\n    vector<pair<double, unsigned>> candidates;\n    for (unsigned seed = 0; ; seed++) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now-start).count()>2200) break;\n        tree.clear(); mt19937 rng(seed);\n        int root = build_tree(indices, rng, seed % 9);\n        optimize_offsets(root);\n        post_process();\n        double s = compute_score();\n        candidates.push_back({s, seed});\n        if (s > bs) { bs=s; ba=ra; bb=rb; bc=rc; bd=rd; }\n    }\n\n    // Phase 2: SA on top candidates\n    sort(candidates.rbegin(), candidates.rend());\n    int top_k = min((int)candidates.size(), 8);\n    for (int ci = 0; ci < top_k; ci++) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now-start).count()>4600) break;\n        unsigned seed = candidates[ci].second;\n        tree.clear(); mt19937 rng(seed);\n        int root = build_tree(indices, rng, seed % 9);\n        optimize_offsets(root);\n        sa_offsets(root, seed * 7919 + 42, 200000);\n        post_process();\n        double s = compute_score();\n        if (s > bs) { bs=s; ba=ra; bb=rb; bc=rc; bd=rd; }\n    }\n\n    ra=ba; rb=bb; rc=bc; rd=bd;\n    for (int i = 0; i < n; i++) cout << ra[i]<<\" \"<<rb[i]<<\" \"<<rc[i]<<\" \"<<rd[i]<<\"\\n\";\n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <algorithm>\n#include <chrono>\n#include <cstring>\n\nusing namespace std;\n\nconst int N = 50;\nint si, sj;\nint t[N][N], p[N][N];\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir[] = {'U', 'D', 'L', 'R'};\nmt19937 rng(42);\n\nint tile_value[2500], max_tile_id = 0;\nstring best_path;\nlong long best_score;\n\nstring find_path(double temperature) {\n    bool square_visited[N][N] = {};\n    bool tile_visited[2500] = {};\n    string path;\n    int ci = si, cj = sj;\n    square_visited[ci][cj] = true;\n    tile_visited[t[ci][cj]] = true;\n    long long score = p[ci][cj];\n    \n    while (true) {\n        vector<pair<double, int>> candidates;\n        for (int d = 0; d < 4; d++) {\n            int ni = ci + di[d], nj = cj + dj[d];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            if (square_visited[ni][nj]) continue;\n            bool same_tile = (t[ni][nj] == t[ci][cj]);\n            if (same_tile || !tile_visited[t[ni][nj]]) {\n                double w = same_tile ? p[ni][nj] : tile_value[t[ni][nj]];\n                candidates.push_back({w, d});\n            }\n        }\n        if (candidates.empty()) break;\n        \n        double max_w = -1e18;\n        for (auto& [w, d] : candidates) max_w = max(max_w, w);\n        double total = 0;\n        for (auto& [w, d] : candidates) total += exp((w - max_w) / max(temperature, 0.01));\n        \n        double r = uniform_real_distribution<double>(0, total)(rng);\n        double cum = 0;\n        int chosen = candidates[0].second;\n        for (auto& [w, d] : candidates) {\n            cum += exp((w - max_w) / max(temperature, 0.01));\n            if (cum >= r) { chosen = d; break; }\n        }\n        \n        int ni = ci + di[chosen], nj = cj + dj[chosen];\n        square_visited[ni][nj] = true;\n        tile_visited[t[ni][nj]] = true;\n        score += p[ni][nj];\n        path += dir[chosen];\n        ci = ni; cj = nj;\n    }\n    \n    if (score > best_score) { best_score = score; best_path = path; }\n    return path;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> si >> sj;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) { cin >> t[i][j]; max_tile_id = max(max_tile_id, t[i][j]); }\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> p[i][j];\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) tile_value[t[i][j]] += p[i][j];\n    \n    best_score = 0;\n    auto start = chrono::high_resolution_clock::now();\n    int iter = 0;\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > 1800) break;\n        double temperature = 10.0 * (1.0 - min(iter / 100000.0, 1.0)) + 0.1;\n        find_path(temperature);\n        iter++;\n    }\n    \n    cout << best_path << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\ndouble row_h[N], col_v[N], row_h_var[N], col_v_var[N];\ndouble h_dev[N][N-1], v_dev[N-1][N], h_dev_var[N][N-1], v_dev_var[N-1][N];\nmt19937 rng(42);\nnormal_distribution<double> norm_dist(0, 1);\n\ndouble get_h_est(int i, int j) { return row_h[i] + h_dev[i][j]; }\ndouble get_v_est(int i, int j) { return col_v[j] + v_dev[i][j]; }\ndouble get_h_var(int i, int j) { return row_h_var[i] + h_dev_var[i][j]; }\ndouble get_v_var(int i, int j) { return col_v_var[j] + v_dev_var[i][j]; }\n\ntuple<string,double,double> dijkstra_with_cost(int si, int sj, int ti, int tj, double temperature) {\n    double hw[N][N-1], vw[N-1][N];\n    for(int i=0; i<N; i++) {\n        double rh = row_h[i] + temperature * sqrt(max(1.0, row_h_var[i])) * norm_dist(rng);\n        for(int j=0; j<N-1; j++){\n            double hd = h_dev[i][j] + temperature * sqrt(max(1.0, h_dev_var[i][j])) * norm_dist(rng);\n            hw[i][j] = max(100.0, min(20000.0, rh + hd));\n        }\n    }\n    for(int j=0; j<N; j++) {\n        double cv = col_v[j] + temperature * sqrt(max(1.0, col_v_var[j])) * norm_dist(rng);\n        for(int i=0; i<N-1; i++){\n            double vd = v_dev[i][j] + temperature * sqrt(max(1.0, v_dev_var[i][j])) * norm_dist(rng);\n            vw[i][j] = max(100.0, min(20000.0, cv + vd));\n        }\n    }\n    double dist[N][N]; pair<int,int> prev_node[N][N]; bool vis[N][N] = {};\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) dist[i][j]=1e18;\n    dist[si][sj]=0;\n    priority_queue<tuple<double,int,int>,vector<tuple<double,int,int>>,greater<>> pq;\n    pq.push({0,si,sj});\n    while(!pq.empty()){\n        auto[d,i,j]=pq.top(); pq.pop();\n        if(vis[i][j]) continue; vis[i][j]=true;\n        if(i==ti&&j==tj) break;\n        if(i>0&&!vis[i-1][j]){double w=vw[i-1][j];if(d+w<dist[i-1][j]){dist[i-1][j]=d+w;prev_node[i-1][j]={i,j};pq.push({dist[i-1][j],i-1,j});}}\n        if(i<N-1&&!vis[i+1][j]){double w=vw[i][j];if(d+w<dist[i+1][j]){dist[i+1][j]=d+w;prev_node[i+1][j]={i,j};pq.push({dist[i+1][j],i+1,j});}}\n        if(j>0&&!vis[i][j-1]){double w=hw[i][j-1];if(d+w<dist[i][j-1]){dist[i][j-1]=d+w;prev_node[i][j-1]={i,j};pq.push({dist[i][j-1],i,j-1});}}\n        if(j<N-1&&!vis[i][j+1]){double w=hw[i][j];if(d+w<dist[i][j+1]){dist[i][j+1]=d+w;prev_node[i][j+1]={i,j};pq.push({dist[i][j+1],i,j+1});}}\n    }\n    string path; double mean_cost=0, path_var=0; int ci=ti,cj=tj;\n    while(ci!=si||cj!=sj){\n        auto[pi,pj]=prev_node[ci][cj];\n        if(pi==ci-1){path+='D';mean_cost+=get_v_est(ci-1,cj);path_var+=get_v_var(ci-1,cj);}\n        else if(pi==ci+1){path+='U';mean_cost+=get_v_est(ci,cj);path_var+=get_v_var(ci,cj);}\n        else if(pj==cj-1){path+='R';mean_cost+=get_h_est(ci,cj-1);path_var+=get_h_var(ci,cj-1);}\n        else{path+='L';mean_cost+=get_h_est(ci,cj);path_var+=get_h_var(ci,cj);}\n        ci=pi; cj=pj;\n    }\n    reverse(path.begin(),path.end());\n    return {path, mean_cost, path_var};\n}\n\nvoid update(int si, int sj, const string& path, int observed) {\n    struct E{char t;int i,j;}; vector<E> edges;\n    map<int,int> hr, vc; int ci=si,cj=sj;\n    for(char c:path){\n        if(c=='U'){edges.push_back({'v',ci-1,cj});vc[cj]++;ci--;}\n        else if(c=='D'){edges.push_back({'v',ci,cj});vc[cj]++;ci++;}\n        else if(c=='L'){edges.push_back({'h',ci,cj-1});hr[ci]++;cj--;}\n        else{edges.push_back({'h',ci,cj});hr[ci]++;cj++;}\n    }\n    double pred=0;\n    for(auto&e:edges) pred+=(e.t=='h')?get_h_est(e.i,e.j):get_v_est(e.i,e.j);\n    double residual=observed-pred, obs_var=pred*pred/300.0, S=obs_var;\n    for(auto&[i,n]:hr) S+=n*n*row_h_var[i];\n    for(auto&[j,n]:vc) S+=n*n*col_v_var[j];\n    for(auto&e:edges) S+=(e.t=='h')?h_dev_var[e.i][e.j]:v_dev_var[e.i][e.j];\n    for(auto&[i,n]:hr){\n        double K=row_h_var[i]*n/S;row_h[i]+=K*residual;row_h_var[i]*=(1-K*n);\n        row_h[i]=max(500.0,min(15000.0,row_h[i]));row_h_var[i]=max(100.0,row_h_var[i]);\n    }\n    for(auto&[j,n]:vc){\n        double K=col_v_var[j]*n/S;col_v[j]+=K*residual;col_v_var[j]*=(1-K*n);\n        col_v[j]=max(500.0,min(15000.0,col_v[j]));col_v_var[j]=max(100.0,col_v_var[j]);\n    }\n    for(auto&e:edges){\n        double&dev=(e.t=='h')?h_dev[e.i][e.j]:v_dev[e.i][e.j];\n        double&dv=(e.t=='h')?h_dev_var[e.i][e.j]:v_dev_var[e.i][e.j];\n        double K=dv/S;dev+=K*residual;dv*=(1-K);\n        dev=max(-5000.0,min(5000.0,dev));dv=max(100.0,dv);\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    for(int i=0;i<N;i++){row_h[i]=col_v[i]=5000.0;row_h_var[i]=col_v_var[i]=5000000.0;}\n    for(int i=0;i<N;i++) for(int j=0;j<N-1;j++){h_dev[i][j]=0.0;h_dev_var[i][j]=2000000.0;}\n    for(int i=0;i<N-1;i++) for(int j=0;j<N;j++){v_dev[i][j]=0.0;v_dev_var[i][j]=2000000.0;}\n    for(int k=0;k<1000;k++){\n        int si,sj,ti,tj;cin>>si>>sj>>ti>>tj;\n        double temperature=max(0.0,1.0-k/300.0);\n        double decay=max(0.0,1.0-k/400.0);\n        string best_path;double best_eval=1e18;\n        for(int t=0;t<5;t++){\n            auto[path,cost,pvar]=dijkstra_with_cost(si,sj,ti,tj,temperature);\n            double eval=cost-0.15*sqrt(pvar)*decay;\n            if(eval<best_eval){best_eval=eval;best_path=path;}\n        }\n        cout<<best_path<<endl;\n        int obs;cin>>obs;update(si,sj,best_path,obs);\n    }\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <array>\n\nusing namespace std;\n\nstruct Entry {\n    uint16_t m, pi;\n};\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    vector<string> s(M);\n    for (int m = 0; m < M; m++) cin >> s[m];\n    \n    const int NUM_CHARS = 8;\n    mt19937 rng(42);\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    vector<int> slen(M);\n    for (int m = 0; m < M; m++) slen[m] = s[m].length();\n    \n    // Fast Frequency Voting Initialization\n    vector<array<int, 8>> votes(N * N, {0});\n    for (int m = 0; m < M; m++) {\n        int k = slen[m];\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                for (int p = 0; p < k; p++) {\n                    votes[i * N + (j + p) % N][s[m][p] - 'A']++;\n                    votes[((i + p) % N) * N + j][s[m][p] - 'A']++;\n                }\n            }\n        }\n    }\n    \n    vector<string> mat(N, string(N, 'A'));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int maxVote = 0; char best = 'A';\n            for (int c = 0; c < NUM_CHARS; c++) {\n                if (votes[i * N + j][c] > maxVote) { maxVote = votes[i * N + j][c]; best = 'A' + c; }\n            }\n            mat[i][j] = best;\n        }\n    }\n    \n    // Build Character-Based Adjacency Lists\n    vector<Entry> adj[400][8];\n    for (int m = 0; m < M; m++) {\n        int k = slen[m];\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int piH = 2 * (i * N + j);\n                for (int p = 0; p < k; p++) adj[i * N + (j + p) % N][s[m][p] - 'A'].push_back({(uint16_t)m, (uint16_t)piH});\n                int piV = 2 * (i * N + j) + 1;\n                for (int p = 0; p < k; p++) adj[((i + p) % N) * N + j][s[m][p] - 'A'].push_back({(uint16_t)m, (uint16_t)piV});\n            }\n        }\n    }\n    \n    // Match Counts\n    vector<int8_t> matchCount(M * 800, 0);\n    vector<int16_t> fullMatchCount(M, 0);\n    int totalMatched = 0, numDots = 0;\n    \n    auto recompute = [&]() {\n        numDots = 0;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (mat[i][j] == '.') numDots++;\n        for (int m = 0; m < M; m++) {\n            int k = slen[m]; fullMatchCount[m] = 0;\n            int base = m * 800;\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n                int cH = 0, cV = 0;\n                for (int p = 0; p < k; p++) { if (mat[i][(j+p)%N] == s[m][p]) cH++; if (mat[(i+p)%N][j] == s[m][p]) cV++; }\n                matchCount[base + 2*(i*N+j)] = cH; matchCount[base + 2*(i*N+j)+1] = cV;\n                if (cH == k) fullMatchCount[m]++; if (cV == k) fullMatchCount[m]++;\n            }\n        }\n        totalMatched = 0;\n        for (int m = 0; m < M; m++) if (fullMatchCount[m] > 0) totalMatched++;\n    };\n    \n    recompute();\n    int bestMatched = totalMatched, bestDots = -1;\n    vector<string> bestMat = mat;\n    if (totalMatched == M) bestDots = numDots;\n    \n    // SA Phase\n    int stepCount = 0;\n    while (true) {\n        stepCount++;\n        if ((stepCount & 0xFFF) == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            if (chrono::duration<double>(now - start_time).count() > 2.8) break;\n        }\n        double temp = 3.0 * max(0.0, 1.0 - chrono::duration<double>(chrono::high_resolution_clock::now() - start_time).count() / 3.0) + 0.05;\n        \n        // 5% String-level move to force unmatched strings\n        if (rng() % 100 < 5 && totalMatched < M) {\n            int m = rng() % M;\n            int tries = 0;\n            while (fullMatchCount[m] > 0 && tries < 10) { m = rng() % M; tries++; }\n            if (fullMatchCount[m] > 0) goto cell_move;\n            \n            {\n                int k = slen[m], bestMC = -1, bestPi = -1;\n                int base = m * 800;\n                for (int pi = 0; pi < 2 * N * N; pi++) if (matchCount[base + pi] > bestMC) { bestMC = matchCount[base + pi]; bestPi = pi; }\n                if (bestPi < 0) goto cell_move;\n                \n                int dir = bestPi % 2, ij = bestPi / 2, si = ij / N, sj = ij % N;\n                int deltaMatched = 0, deltaDots = 0;\n                char oldChars[13];\n                \n                for (int p = 0; p < k; p++) {\n                    int ci2 = dir == 0 ? si : (si + p) % N, cj2 = dir == 0 ? (sj + p) % N : sj;\n                    int idx2 = ci2 * N + cj2;\n                    oldChars[p] = mat[ci2][cj2];\n                    char newC2 = s[m][p];\n                    if (oldChars[p] == newC2) continue;\n                    \n                    if (oldChars[p] != '.') {\n                        for (auto& e : adj[idx2][oldChars[p] - 'A']) {\n                            int m2 = e.m, pi2 = e.pi, k2 = slen[m2], base2 = m2 * 800;\n                            int8_t oldMC = matchCount[base2 + pi2];\n                            int8_t newMC = oldMC - 1;\n                            matchCount[base2 + pi2] = newMC;\n                            if (oldMC == k2) { if (fullMatchCount[m2] == 1) deltaMatched--; fullMatchCount[m2]--; }\n                        }\n                    } else { deltaDots--; }\n                    \n                    for (auto& e : adj[idx2][newC2 - 'A']) {\n                        int m2 = e.m, pi2 = e.pi, k2 = slen[m2], base2 = m2 * 800;\n                        int8_t oldMC = matchCount[base2 + pi2];\n                        int8_t newMC = oldMC + 1;\n                        matchCount[base2 + pi2] = newMC;\n                        if (newMC == k2) { if (fullMatchCount[m2] == 0) deltaMatched++; fullMatchCount[m2]++; }\n                    }\n                    mat[ci2][cj2] = newC2;\n                }\n                \n                bool accept;\n                if (deltaMatched > 0) accept = true;\n                else if (deltaMatched == 0) accept = true;\n                else if (totalMatched == M && totalMatched + deltaMatched < M) accept = false;\n                else accept = (rng() % 10000 < (int)(exp((double)deltaMatched / temp) * 10000));\n                \n                if (accept) {\n                    totalMatched += deltaMatched; numDots += deltaDots;\n                    if (totalMatched > bestMatched || (totalMatched == M && numDots > bestDots)) {\n                        bestMatched = totalMatched; bestMat = mat; if (totalMatched == M) bestDots = numDots;\n                    }\n                } else {\n                    for (int p = k - 1; p >= 0; p--) {\n                        int ci2 = dir == 0 ? si : (si + p) % N, cj2 = dir == 0 ? (sj + p) % N : sj;\n                        int idx2 = ci2 * N + cj2;\n                        char newC2 = s[m][p], oldC2 = oldChars[p];\n                        if (oldC2 == newC2) continue;\n                        for (auto& e : adj[idx2][newC2 - 'A']) { int m2 = e.m, pi2 = e.pi, k2 = slen[m2]; int8_t curMC = matchCount[m2*800+pi2]; matchCount[m2*800+pi2] = curMC - 1; if (curMC == k2) fullMatchCount[m2]--; }\n                        if (oldC2 != '.') { for (auto& e : adj[idx2][oldC2 - 'A']) { int m2 = e.m, pi2 = e.pi, k2 = slen[m2]; int8_t curMC = matchCount[m2*800+pi2]; matchCount[m2*800+pi2] = curMC + 1; if (curMC + 1 == k2) fullMatchCount[m2]++; } }\n                        mat[ci2][cj2] = oldC2;\n                    }\n                }\n            }\n            continue;\n        }\n        \n        cell_move:\n        int ci = rng() % N, cj = rng() % N;\n        int idx = ci * N + cj;\n        char oldC = mat[ci][cj];\n        char newC;\n        if (totalMatched == M && (rng() % 2 == 0)) newC = '.';\n        else newC = 'A' + rng() % NUM_CHARS;\n        if (newC == oldC) continue;\n        \n        int deltaMatched = 0;\n        int deltaDots = (newC == '.' && oldC != '.') ? 1 : ((newC != '.' && oldC == '.') ? -1 : 0);\n        \n        if (oldC != '.') {\n            for (auto& e : adj[idx][oldC - 'A']) {\n                int m = e.m, pi = e.pi, k = slen[m], base = m * 800;\n                int8_t oldMC = matchCount[base + pi];\n                int8_t newMC = oldMC - 1;\n                matchCount[base + pi] = newMC;\n                if (oldMC == k) { if (fullMatchCount[m] == 1) deltaMatched--; fullMatchCount[m]--; }\n            }\n        }\n        if (newC != '.') {\n            for (auto& e : adj[idx][newC - 'A']) {\n                int m = e.m, pi = e.pi, k = slen[m], base = m * 800;\n                int8_t oldMC = matchCount[base + pi];\n                int8_t newMC = oldMC + 1;\n                matchCount[base + pi] = newMC;\n                if (newMC == k) { if (fullMatchCount[m] == 0) deltaMatched++; fullMatchCount[m]++; }\n            }\n        }\n        \n        bool accept;\n        if (deltaMatched > 0) accept = true;\n        else if (deltaMatched == 0) accept = (deltaDots > 0) || (rng() % 2 == 0);\n        else if (totalMatched == M && totalMatched + deltaMatched < M) accept = false;\n        else accept = (rng() % 10000 < (int)(exp((double)deltaMatched / temp) * 10000));\n        \n        if (accept) {\n            mat[ci][cj] = newC; totalMatched += deltaMatched; numDots += deltaDots;\n            if (totalMatched > bestMatched || (totalMatched == M && numDots > bestDots)) {\n                bestMatched = totalMatched; bestMat = mat; if (totalMatched == M) bestDots = numDots;\n            }\n        } else {\n            if (newC != '.') { for (auto& e : adj[idx][newC - 'A']) { int m = e.m, pi = e.pi, k = slen[m]; int8_t curMC = matchCount[m*800+pi]; matchCount[m*800+pi] = curMC - 1; if (curMC == k) fullMatchCount[m]--; } }\n            if (oldC != '.') { for (auto& e : adj[idx][oldC - 'A']) { int m = e.m, pi = e.pi, k = slen[m]; int8_t curMC = matchCount[m*800+pi]; matchCount[m*800+pi] = curMC + 1; if (curMC + 1 == k) fullMatchCount[m]++; } }\n        }\n    }\n    \n    mat = bestMat; recompute();\n    \n    // Greedy Repair\n    for (int rep = 0; rep < 3; rep++) {\n        bool anyImproved = false;\n        for (int m = 0; m < M; m++) {\n            if (fullMatchCount[m] > 0) continue;\n            int k = slen[m], bestMC = -1, bestPi = -1, base = m * 800;\n            for (int pi = 0; pi < 2 * N * N; pi++) if (matchCount[base + pi] > bestMC) { bestMC = matchCount[base + pi]; bestPi = pi; }\n            if (bestPi < 0) continue;\n            int dir = bestPi % 2, ij = bestPi / 2, si = ij / N, sj = ij % N;\n            int deltaMatched = 0, deltaDots = 0;\n            for (int p = 0; p < k; p++) {\n                int ci2 = dir == 0 ? si : (si + p) % N, cj2 = dir == 0 ? (sj + p) % N : sj;\n                int idx2 = ci2 * N + cj2; char oldC2 = mat[ci2][cj2], newC2 = s[m][p];\n                if (oldC2 == newC2) continue;\n                if (oldC2 == '.') deltaDots--;\n                if (oldC2 != '.') { for (auto& e : adj[idx2][oldC2 - 'A']) { int m2 = e.m, pi2 = e.pi, k2 = slen[m2]; int8_t oMC = matchCount[m2*800+pi2]; matchCount[m2*800+pi2] = oMC - 1; if (oMC == k2) { if (fullMatchCount[m2] == 1) deltaMatched--; fullMatchCount[m2]--; } } }\n                for (auto& e : adj[idx2][newC2 - 'A']) { int m2 = e.m, pi2 = e.pi, k2 = slen[m2]; int8_t oMC = matchCount[m2*800+pi2]; matchCount[m2*800+pi2] = oMC + 1; if (oMC + 1 == k2) { if (fullMatchCount[m2] == 0) deltaMatched++; fullMatchCount[m2]++; } }\n                mat[ci2][cj2] = newC2;\n            }\n            totalMatched += deltaMatched; numDots += deltaDots;\n            if (deltaMatched > 0) anyImproved = true;\n        }\n        if (totalMatched > bestMatched || (totalMatched == M && numDots > bestDots)) { bestMatched = totalMatched; bestMat = mat; if (totalMatched == M) bestDots = numDots; }\n        if (!anyImproved) break;\n    }\n    \n    mat = bestMat; recompute();\n    \n    // Dot Maximization\n    if (totalMatched == M) {\n        for (int ci = 0; ci < N; ci++) {\n            for (int cj = 0; cj < N; cj++) {\n                if (mat[ci][cj] == '.') continue;\n                char oldC2 = mat[ci][cj]; int deltaMatched = 0, idx2 = ci * N + cj;\n                for (auto& e : adj[idx2][oldC2 - 'A']) { int m = e.m, pi = e.pi, k = slen[m]; if (matchCount[m*800+pi] == k) { if (fullMatchCount[m] == 1) deltaMatched--; } }\n                if (deltaMatched == 0) {\n                    for (auto& e : adj[idx2][oldC2 - 'A']) { int m = e.m, pi = e.pi, k = slen[m]; matchCount[m*800+pi]--; if (matchCount[m*800+pi] + 1 == k) fullMatchCount[m]--; }\n                    mat[ci][cj] = '.'; numDots++;\n                }\n            }\n        }\n        if (numDots > bestDots) { bestDots = numDots; bestMat = mat; }\n    }\n    \n    for (int i = 0; i < N; i++) cout << bestMat[i] << '\\n';\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\nvector<vector<vector<pair<int,int>>>> vis_from;\nint total_roads;\nbitset<4800> road_mask;\n\nbool is_road(int i, int j) { return i>=0&&i<N&&j>=0&&j<N&&grid[i][j]!='#'; }\nint cell_cost(int i, int j) { return grid[i][j]-'0'; }\n\nconst int di[]={-1,1,0,0}, dj[]={0,0,-1,1};\nconst char dc[]={'U','D','L','R'};\n\nint char_to_idx(char c) {\n    if(c=='U') return 0;\n    if(c=='D') return 1;\n    if(c=='L') return 2;\n    return 3;\n}\n\nvoid precompute_visibility() {\n    vis_from.assign(N, vector<vector<pair<int,int>>>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) {\n        if(!is_road(i,j)) continue;\n        road_mask[i*N+j] = 1;\n        vis_from[i][j].push_back({i,j});\n        for(int jj=j-1;jj>=0&&is_road(i,jj);jj--) vis_from[i][j].push_back({i,jj});\n        for(int jj=j+1;jj<N&&is_road(i,jj);jj++) vis_from[i][j].push_back({i,jj});\n        for(int ii=i-1;ii>=0&&is_road(ii,j);ii--) vis_from[i][j].push_back({ii,j});\n        for(int ii=i+1;ii<N&&is_road(ii,j);ii++) vis_from[i][j].push_back({ii,j});\n    }\n}\n\npair<vector<vector<int>>, vector<vector<int>>> dijkstra(int si, int sj) {\n    vector<vector<int>> dist(N, vector<int>(N, INT_MAX)), prev(N, vector<int>(N, -1));\n    priority_queue<pair<int,pair<int,int>>, vector<pair<int,pair<int,int>>>, greater<>> pq;\n    dist[si][sj] = 0; pq.push({0, {si, sj}});\n    while(!pq.empty()) {\n        auto [d, p] = pq.top(); pq.pop();\n        auto [i, j] = p;\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(is_road(ni, nj)) {\n                int nd = d + cell_cost(ni, nj);\n                if(nd < dist[ni][nj]) { dist[ni][nj] = nd; prev[ni][nj] = k; pq.push({nd, {ni, nj}}); }\n            }\n        }\n    }\n    return {dist, prev};\n}\n\nstring reconstruct(int si, int sj, int ti, int tj, const vector<vector<int>>& prev) {\n    if(si==ti && sj==tj) return \"\";\n    string path; int ci=ti, cj=tj;\n    while(ci!=si || cj!=sj) { int k=prev[ci][cj]; if(k==-1) return \"\"; path+=dc[k]; ci-=di[k]; cj-=dj[k]; }\n    reverse(path.begin(), path.end()); return path;\n}\n\nvector<pair<int,int>> build_greedy(double alpha) {\n    vector<vector<bool>> covered(N, vector<bool>(N, false));\n    auto mark = [&](int i, int j)->int {\n        int c=0; for(auto& [vi, vj] : vis_from[i][j]) if(!covered[vi][vj]){covered[vi][vj]=true;c++;} return c;\n    };\n    vector<pair<int,int>> targets;\n    int ci = si, cj = sj, cc = mark(ci, cj);\n    \n    while(cc < total_roads) {\n        auto [dist, prev] = dijkstra(ci, cj);\n        vector<vector<vector<pair<int,int>>>> children(N, vector<vector<pair<int,int>>>(N));\n        for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) {\n            if(prev[i][j] != -1) {\n                int pi = i - di[prev[i][j]], pj = j - dj[prev[i][j]];\n                children[pi][pj].push_back({i, j});\n            }\n        }\n        \n        vector<double> scores(N*N, -1.0);\n        int current_nv = 0;\n        vector<pair<int,int>> changes;\n        vector<vector<bool>> tmp = covered;\n        \n        function<void(int, int)> dfs = [&](int ui, int uj) {\n            int sz = changes.size();\n            for(auto& [vi, vj] : vis_from[ui][uj]) {\n                if(!tmp[vi][vj]) { tmp[vi][vj] = true; changes.push_back({vi, vj}); current_nv++; }\n            }\n            if(current_nv > 0 && dist[ui][uj] > 0) scores[ui*N+uj] = pow((double)current_nv, alpha) / (double)dist[ui][uj];\n            for(auto& [vi, vj] : children[ui][uj]) dfs(vi, vj);\n            while(changes.size() > sz) { auto [vi, vj] = changes.back(); tmp[vi][vj] = false; changes.pop_back(); current_nv--; }\n        };\n        dfs(ci, cj);\n        \n        int best_idx = -1; double best_score = -1e18;\n        for(int i=0; i<N*N; ++i) if(scores[i] > best_score) { best_score = scores[i]; best_idx = i; }\n        if(best_idx == -1) break;\n        \n        int bi = best_idx / N, bj = best_idx % N;\n        targets.push_back({bi, bj});\n        string path = reconstruct(ci, cj, bi, bj, prev);\n        for(char c : path) { int k = char_to_idx(c); ci += di[k]; cj += dj[k]; cc += mark(ci, cj); }\n    }\n    return targets;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> si >> sj; grid.resize(N); for(int i=0;i<N;i++) cin >> grid[i];\n    precompute_visibility();\n    total_roads = road_mask.count();\n    auto st = chrono::high_resolution_clock::now();\n    \n    set<pair<int,int>> pool_set;\n    pool_set.insert({si, sj});\n    vector<double> alphas = {0.5, 1.0, 1.5, 2.5};\n    for(double alpha : alphas) { auto targets = build_greedy(alpha); for(auto& t : targets) pool_set.insert(t); }\n    \n    mt19937 rng(1337);\n    vector<pair<int,int>> roads;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(is_road(i,j)) roads.push_back({i,j});\n    for(int i=0; i<50; ++i) pool_set.insert(roads[rng() % roads.size()]);\n    \n    vector<pair<int,int>> T(pool_set.begin(), pool_set.end());\n    int M = T.size(), S = -1;\n    for(int i=0; i<M; ++i) if(T[i].first == si && T[i].second == sj) S = i;\n    \n    vector<vector<int>> d(M, vector<int>(M, INT_MAX));\n    vector<vector<bitset<4800>>> path_vis(M, vector<bitset<4800>>(M));\n    vector<vector<vector<int>>> all_prev(M, vector<vector<int>>(N, vector<int>(N, -1)));\n    \n    for(int u=0; u<M; ++u) {\n        auto [dist, prev] = dijkstra(T[u].first, T[u].second);\n        all_prev[u] = prev;\n        for(int v=0; v<M; ++v) {\n            d[u][v] = dist[T[v].first][T[v].second];\n            bitset<4800> bs;\n            for(auto& [vi, vj] : vis_from[T[u].first][T[u].second]) bs[vi*N+vj] = 1;\n            int ci = T[v].first, cj = T[v].second;\n            while(ci != T[u].first || cj != T[u].second) {\n                for(auto& [vi, vj] : vis_from[ci][cj]) bs[vi*N+vj] = 1;\n                int k = prev[ci][cj]; ci -= di[k]; cj -= dj[k];\n            }\n            path_vis[u][v] = bs;\n        }\n    }\n    \n    auto evaluate_seq = [&](const vector<int>& seq) -> pair<bool, int> {\n        if(seq.empty()) { bitset<4800> vis = path_vis[S][S]; return {(vis & road_mask).count() == total_roads, 0}; }\n        int cost = d[S][seq[0]] + d[seq.back()][S];\n        bitset<4800> vis = path_vis[S][seq[0]] | path_vis[seq.back()][S];\n        for(int i=0; i+1<(int)seq.size(); ++i) { cost += d[seq[i]][seq[i+1]]; vis |= path_vis[seq[i]][seq[i+1]]; }\n        return {(vis & road_mask).count() == total_roads, cost};\n    };\n    \n    vector<int> best_greedy_seq; int best_greedy_cost = INT_MAX;\n    for(double alpha : alphas) {\n        auto targets = build_greedy(alpha);\n        vector<int> seq; for(auto& t : targets) for(int i=0; i<M; ++i) if(T[i] == t) { seq.push_back(i); break; }\n        auto [valid, cost] = evaluate_seq(seq);\n        if(valid && cost < best_greedy_cost) { best_greedy_cost = cost; best_greedy_seq = seq; }\n    }\n    \n    vector<int> cur_seq = best_greedy_seq, best_seq = best_greedy_seq;\n    int cur_cost = best_greedy_cost, best_cost = best_greedy_cost;\n    if(cur_seq.empty() || !evaluate_seq(cur_seq).first) { cur_seq.clear(); for(int i=0; i<20; ++i) cur_seq.push_back(rng() % M); auto [v, c] = evaluate_seq(cur_seq); cur_cost = v ? c : INT_MAX; }\n    \n    double T_sa = 1000.0;\n    mt19937 rng_sa(12345);\n    uniform_real_distribution<double> dist01(0.0, 1.0);\n    \n    while(true) {\n        auto now = chrono::high_resolution_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now - st).count() > 2800) break;\n        vector<int> new_seq = cur_seq;\n        int op = rng_sa() % 5;\n        if(op == 0 && new_seq.size() >= 2) { int l = rng_sa() % new_seq.size(), r = rng_sa() % new_seq.size(); if(l > r) swap(l, r); reverse(new_seq.begin() + l, new_seq.begin() + r + 1); }\n        else if(op == 1 && new_seq.size() >= 2) { int i = rng_sa() % new_seq.size(), j = rng_sa() % new_seq.size(); swap(new_seq[i], new_seq[j]); }\n        else if(op == 2 && new_seq.size() > 1) { int i = rng_sa() % new_seq.size(); new_seq.erase(new_seq.begin() + i); }\n        else if(op == 3) { int x = rng_sa() % M, i = rng_sa() % (new_seq.size() + 1); new_seq.insert(new_seq.begin() + i, x); }\n        else if(op == 4 && new_seq.size() > 0) { int i = rng_sa() % new_seq.size(), x = rng_sa() % M; new_seq[i] = x; }\n        \n        auto [valid, new_cost] = evaluate_seq(new_seq);\n        if(valid) {\n            double delta = new_cost - cur_cost;\n            if(delta < 0 || dist01(rng_sa) < exp(-delta / T_sa)) { cur_seq = new_seq; cur_cost = new_cost; if(new_cost < best_cost) { best_cost = new_cost; best_seq = new_seq; } }\n        }\n        T_sa *= 0.9999;\n    }\n    \n    string final_route;\n    if(!best_seq.empty()) {\n        int ci = si, cj = sj;\n        for(int idx=0; idx<(int)best_seq.size(); ++idx) {\n            int u = (idx == 0) ? S : best_seq[idx-1], v = best_seq[idx];\n            final_route += reconstruct(T[u].first, T[u].second, T[v].first, T[v].second, all_prev[u]);\n        }\n        final_route += reconstruct(T[best_seq.back()].first, T[best_seq.back()].second, si, sj, all_prev[best_seq.back()]);\n    }\n    cout << final_route << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> d, deps, rev_deps;\nvector<vector<double>> skill_est;\nvector<double> crit_path;\nvector<int> task_start, task_done;\nvector<vector<pair<int,int>>> member_obs;\n\nvector<int> hungarian(const vector<vector<double>>& cost) {\n    int n = cost.size(), m = cost[0].size();\n    const double INF = 1e18;\n    vector<double> u(n+1,0), v(m+1,0);\n    vector<int> p(m+1,0), way(m+1,0);\n    for (int i = 1; i <= n; i++) {\n        p[0] = i; int j0 = 0;\n        vector<double> minv(m+1, INF);\n        vector<bool> used(m+1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], j1 = 0;\n            double delta = INF;\n            for (int j = 1; j <= m; j++) if (!used[j]) {\n                double cur = cost[i0-1][j-1] - u[i0] - v[j];\n                if (cur < minv[j]) { minv[j] = cur; way[j] = j0; }\n                if (minv[j] < delta) { delta = minv[j]; j1 = j; }\n            }\n            for (int j = 0; j <= m; j++) {\n                if (used[j]) { u[p[j]] += delta; v[j] -= delta; }\n                else minv[j] -= delta;\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do { int j1 = way[j0]; p[j0] = p[j1]; j0 = j1; } while (j0);\n    }\n    vector<int> asgn(n, -1);\n    for (int j = 1; j <= m; j++) if (p[j] > 0 && p[j] <= n) asgn[p[j]-1] = j-1;\n    return asgn;\n}\n\nvoid recompute_crit_path() {\n    vector<double> et(N);\n    for (int i = 0; i < N; ++i) {\n        if (task_done[i] != -1) { et[i] = 0; continue; }\n        if (task_start[i] != -1) { et[i] = 0.1; continue; } // Already started, will finish soon\n        double min_w = 1e9;\n        for (int j = 0; j < M; ++j) {\n            double w = 0;\n            for (int k = 0; k < K; ++k) w += max(0.0, (double)d[i][k] - skill_est[j][k]);\n            min_w = min(min_w, w);\n        }\n        et[i] = max(1.0, min_w);\n    }\n    for (int i = N - 1; i >= 0; i--) {\n        crit_path[i] = et[i];\n        for (int v : rev_deps[i]) crit_path[i] = max(crit_path[i], et[i] + crit_path[v]);\n    }\n}\n\nvoid reestimate(int j) {\n    auto& ob = member_obs[j];\n    if (ob.empty()) return;\n    for (int iter = 0; iter < 30; ++iter) {\n        for (auto& [task, t] : ob) {\n            double w_pred = 0;\n            for (int k = 0; k < K; ++k) w_pred += max(0.0, (double)d[task][k] - skill_est[j][k]);\n            \n            if (t == 1) {\n                if (w_pred > 0) {\n                    for (int k = 0; k < K; ++k) {\n                        if (d[task][k] > skill_est[j][k]) {\n                            skill_est[j][k] += 0.3 * (d[task][k] - skill_est[j][k]);\n                        }\n                    }\n                }\n            } else {\n                double target_w = t;\n                double diff = w_pred - target_w;\n                if (abs(diff) < 0.5) continue;\n                \n                if (w_pred > 0) {\n                    for (int k = 0; k < K; ++k) {\n                        if (d[task][k] > skill_est[j][k]) {\n                            skill_est[j][k] += 0.3 * diff * (d[task][k] - skill_est[j][k]) / w_pred;\n                        }\n                    }\n                } else { \n                    double sum_d = 0;\n                    for (int k = 0; k < K; ++k) sum_d += d[task][k];\n                    if (sum_d > 0) {\n                        for (int k = 0; k < K; ++k) {\n                            skill_est[j][k] += 0.3 * diff * d[task][k] / sum_d;\n                        }\n                    }\n                }\n            }\n        }\n        for (auto& [task, t] : ob) {\n            if (t == 1) {\n                for (int k = 0; k < K; ++k) {\n                    skill_est[j][k] = max(skill_est[j][k], (double)d[task][k]);\n                }\n            }\n        }\n        for (int k = 0; k < K; ++k) skill_est[j][k] = max(0.0, skill_est[j][k]);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> K >> R;\n    d.resize(N, vector<int>(K)); deps.resize(N); rev_deps.resize(N);\n    for (int i = 0; i < N; i++) for (int k = 0; k < K; k++) cin >> d[i][k];\n    for (int r = 0; r < R; r++) { int u, v; cin >> u >> v; u--; v--; deps[v].push_back(u); rev_deps[u].push_back(v); }\n    \n    crit_path.resize(N, 0); task_start.resize(N, -1); task_done.resize(N, -1);\n    skill_est.resize(M, vector<double>(K)); member_obs.resize(M);\n    \n    for (int k = 0; k < K; k++) {\n        vector<int> dk(N); for (int i = 0; i < N; i++) dk[i] = d[i][k];\n        sort(dk.begin(), dk.end());\n        double init = dk[N/2] * 1.5;\n        for (int j = 0; j < M; j++) skill_est[j][k] = init;\n    }\n    \n    vector<int> member_task(M, -1), member_start_day(M, -1);\n    set<int> available_tasks; vector<int> deps_rem(N);\n    for (int i = 0; i < N; i++) { deps_rem[i] = deps[i].size(); if (!deps_rem[i]) available_tasks.insert(i); }\n    \n    int current_day = 0;\n    while (true) {\n        current_day++;\n        recompute_crit_path();\n        \n        vector<int> free_members;\n        for (int j = 0; j < M; j++) if (member_task[j] == -1) free_members.push_back(j);\n        int fm = free_members.size();\n        \n        if (fm > 0 && !available_tasks.empty()) {\n            vector<int> av(available_tasks.begin(), available_tasks.end());\n            sort(av.begin(), av.end(), [&](int a, int b){ return crit_path[a] > crit_path[b]; });\n            \n            int nr = min((int)av.size(), fm * 5);\n            int na = max(nr, fm);\n            vector<vector<double>> cost(fm, vector<double>(na, 1e9));\n            for (int mi = 0; mi < fm; mi++) { \n                int j = free_members[mi];\n                for (int ti = 0; ti < nr; ti++) { \n                    int i = av[ti];\n                    double w = 0; for (int k = 0; k < K; k++) w += max(0.0, (double)d[i][k]-skill_est[j][k]);\n                    cost[mi][ti] = max(1.0, w);\n                }\n            }\n            auto asgn = hungarian(cost);\n            vector<pair<int,int>> assigns;\n            for (int mi = 0; mi < fm; mi++) { \n                int ti = asgn[mi];\n                if (ti >= 0 && ti < nr) assigns.push_back({free_members[mi], av[ti]});\n            }\n            \n            cout << assigns.size();\n            for (auto [j,i] : assigns) {\n                cout << \" \" << (j+1) << \" \" << (i+1);\n                member_task[j]=i; member_start_day[j]=current_day; task_start[i]=current_day;\n                available_tasks.erase(i);\n            }\n            cout << endl;\n        } else cout << 0 << endl;\n        \n        int n; cin >> n; if (n == -1) break;\n        for (int idx = 0; idx < n; idx++) {\n            int j; cin >> j; j--;\n            int i = member_task[j], tt = current_day - member_start_day[j] + 1;\n            task_done[i] = current_day;\n            member_obs[j].push_back({i, tt});\n            reestimate(j);\n            member_task[j] = -1;\n            for (int v : rev_deps[i]) { \n                deps_rem[v]--; \n                if (deps_rem[v] == 0 && task_start[v] == -1 && task_done[v] == -1) available_tasks.insert(v); \n            }\n        }\n    }\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <climits>\n#include <cstring>\n#include <utility>\n\nusing namespace std;\n\nconst int N = 1000, M = 50, CX = 400, CY = 400;\nint a[N], b[N], c[N], d[N];\n\ninline int dist(int x1, int y1, int x2, int y2) { return abs(x1-x2) + abs(y1-y2); }\n\nstruct Xor128 {\n    unsigned x = 123456789, y = 362436069, z = 521288629, w = 88675123;\n    unsigned next() {\n        unsigned t = x ^ (x << 11);\n        x = y; y = z; z = w;\n        return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));\n    }\n    double nextDouble() {\n        return next() / 4294967295.0;\n    }\n    int nextInt(int n) {\n        return next() % n;\n    }\n};\n\nXor128 rng;\n\nint route[100];\nint bestRouteArr[100];\nint orders[M];\nint bestOrders[M];\nbool isSelected[N];\n\nint calcCost() {\n    int cost = 0, x = CX, y = CY;\n    for (int i = 0; i < 2 * M; i++) {\n        int ord = orders[route[i] / 2]; \n        bool isD = route[i] % 2;\n        int nx = isD ? c[ord] : a[ord], ny = isD ? d[ord] : b[ord];\n        cost += dist(x, y, nx, ny); \n        x = nx; y = ny;\n    }\n    return cost + dist(x, y, CX, CY);\n}\n\nbool isValidForInsert(int ip) {\n    int k = route[ip] / 2;\n    bool isD = route[ip] % 2;\n    if (!isD) { // It's a restaurant\n        for (int i = ip + 1; i < 2 * M; i++) {\n            if (route[i] == k * 2 + 1) return true;\n        }\n        return false;\n    } else { // It's a delivery\n        for (int i = 0; i < ip; i++) {\n            if (route[i] == k * 2) return true;\n        }\n        return false;\n    }\n}\n\nvoid constructRoute() {\n    bool vR[M], vD[M];\n    memset(vR, 0, sizeof vR);\n    memset(vD, 0, sizeof vD);\n    int cx = CX, cy = CY;\n    for (int step = 0; step < 2 * M; step++) {\n        int best = -1, bestD = INT_MAX;\n        for (int i = 0; i < M; i++) {\n            if (!vR[i]) { \n                int d2 = dist(cx, cy, a[orders[i]], b[orders[i]]); \n                if (d2 < bestD) { bestD = d2; best = i * 2; } \n            }\n            if (vR[i] && !vD[i]) { \n                int d2 = dist(cx, cy, c[orders[i]], d[orders[i]]); \n                if (d2 < bestD) { bestD = d2; best = i * 2 + 1; } \n            }\n        }\n        route[step] = best;\n        if (best % 2 == 0) { vR[best / 2] = true; cx = a[orders[best / 2]]; cy = b[orders[best / 2]]; }\n        else { vD[best / 2] = true; cx = c[orders[best / 2]]; cy = d[orders[best / 2]]; }\n    }\n}\n\npair<int, int> getCoord(int idx) {\n    if (idx < 0 || idx >= 2 * M) return {CX, CY};\n    int ord = orders[route[idx] / 2];\n    bool isD = route[idx] % 2;\n    if (isD) return {c[ord], d[ord]};\n    else return {a[ord], b[ord]};\n}\n\nint distByIdx(int i, int j) {\n    auto [x1, y1] = getCoord(i);\n    auto [x2, y2] = getCoord(j);\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    for (int i = 0; i < N; i++) cin >> a[i] >> b[i] >> c[i] >> d[i];\n    \n    auto startTime = chrono::high_resolution_clock::now();\n    \n    vector<pair<int,int>> scores;\n    for (int i = 0; i < N; i++) {\n        int cost = dist(CX, CY, a[i], b[i]) + dist(a[i], b[i], c[i], d[i]) + dist(c[i], d[i], CX, CY);\n        scores.push_back({cost, i});\n    }\n    sort(scores.begin(), scores.end());\n    \n    for (int i = 0; i < M; i++) { orders[i] = scores[i].second; isSelected[orders[i]] = true; }\n    \n    constructRoute();\n    int curCost = calcCost(), bestCost = curCost;\n    memcpy(bestRouteArr, route, sizeof(route));\n    memcpy(bestOrders, orders, sizeof(orders));\n    \n    double temp = 100.0, cooling = 0.99999;\n    int iter = 0;\n    \n    while (true) {\n        if (iter % 1000 == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            if (chrono::duration<double>(now - startTime).count() > 1.8) break;\n        }\n        iter++;\n        \n        int mt = rng.nextInt(10);\n        if (mt < 5) {\n            int from = rng.nextInt(2 * M), to = rng.nextInt(2 * M);\n            if (from == to) continue;\n            \n            int savedRoute[100];\n            memcpy(savedRoute, route, sizeof(route));\n            \n            int val = route[from];\n            for (int i = from; i < 2 * M - 1; i++) route[i] = route[i + 1];\n            int ip = to > from ? to - 1 : to;\n            for (int i = 2 * M - 1; i > ip; i--) route[i] = route[i - 1];\n            route[ip] = val;\n            \n            if (isValidForInsert(ip)) {\n                int nc = calcCost(); double d = nc - curCost;\n                if (d < 0 || rng.nextDouble() < exp(-d / temp)) { \n                    curCost = nc; \n                    if (nc < bestCost) { \n                        bestCost = nc; \n                        memcpy(bestRouteArr, route, sizeof(route));\n                        memcpy(bestOrders, orders, sizeof(orders));\n                    } \n                } else {\n                    memcpy(route, savedRoute, sizeof(route));\n                }\n            } else {\n                memcpy(route, savedRoute, sizeof(route));\n            }\n        } else if (mt < 8) {\n            int ii = rng.nextInt(M), oi = rng.nextInt(N);\n            if (isSelected[oi]) continue;\n            \n            int savedOrders[50];\n            memcpy(savedOrders, orders, sizeof(orders));\n            int savedRoute[100];\n            memcpy(savedRoute, route, sizeof(route));\n            \n            int oo = orders[ii]; \n            orders[ii] = oi; \n            isSelected[oo] = false; \n            isSelected[oi] = true;\n            \n            constructRoute(); \n            int nc = calcCost(); \n            double d = nc - curCost;\n            if (d < 0 || rng.nextDouble() < exp(-d / temp)) { \n                curCost = nc; \n                if (nc < bestCost) { \n                    bestCost = nc; \n                    memcpy(bestRouteArr, route, sizeof(route));\n                    memcpy(bestOrders, orders, sizeof(orders));\n                } \n            } else { \n                memcpy(orders, savedOrders, sizeof(orders));\n                isSelected[oi] = false; \n                isSelected[oo] = true; \n                memcpy(route, savedRoute, sizeof(route));\n            }\n        } else {\n            int l = rng.nextInt(2 * M - 1), r = l + 1 + rng.nextInt(2 * M - 1 - l);\n            bool valid = true;\n            bool inSegment[50] = {false};\n            for (int i = l; i <= r; i++) {\n                int k = route[i] / 2;\n                if (inSegment[k]) { valid = false; break; }\n                inSegment[k] = true;\n            }\n            if (valid) {\n                int delta = distByIdx(l - 1, r) + distByIdx(l, r + 1) - distByIdx(l - 1, l) - distByIdx(r, r + 1);\n                int nc = curCost + delta;\n                double d = nc - curCost;\n                if (d < 0 || rng.nextDouble() < exp(-d / temp)) { \n                    reverse(route + l, route + r + 1);\n                    curCost = nc; \n                    if (nc < bestCost) { \n                        bestCost = nc; \n                        memcpy(bestRouteArr, route, sizeof(route));\n                        memcpy(bestOrders, orders, sizeof(orders));\n                    } \n                }\n            }\n        }\n        temp *= cooling;\n    }\n    \n    cout << M;\n    for(int i = 0; i < M; i++) cout << \" \" << bestOrders[i] + 1;\n    cout << endl;\n    cout << 2 * M + 2 << \" \" << CX << \" \" << CY;\n    for(int i = 0; i < 2 * M; i++) {\n        int ord = bestOrders[bestRouteArr[i] / 2]; bool isD = bestRouteArr[i] % 2;\n        cout << \" \" << (isD ? c[ord] : a[ord]) << \" \" << (isD ? d[ord] : b[ord]);\n    }\n    cout << \" \" << CX << \" \" << CY << endl;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, rank_;\n    int components;\n    \n    UnionFind(int n) : parent(n), rank_(n, 0), components(n) {\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 (rank_[px] < rank_[py]) swap(px, py);\n        parent[py] = px;\n        if (rank_[px] == rank_[py]) rank_[px]++;\n        components--;\n        return true;\n    }\n    \n    bool connected(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, M = 1995;\n    vector<int> x(N), y(N);\n    vector<int> u(M), v(M);\n    vector<int> d(M);\n    \n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        double dist = sqrt((double)(x[u[i]] - x[v[i]]) * (x[u[i]] - x[v[i]]) + \n                           (double)(y[u[i]] - y[v[i]]) * (y[u[i]] - y[v[i]]));\n        d[i] = max(1, (int)round(dist));\n    }\n    \n    // Compute reference MST using d_i\n    vector<int> order(M);\n    for (int i = 0; i < M; i++) order[i] = i;\n    sort(order.begin(), order.end(), [&](int a, int b) { return d[a] < d[b]; });\n    \n    UnionFind refUF(N);\n    vector<bool> inRefMST(M, false);\n    for (int idx : order) {\n        if (refUF.unite(u[idx], v[idx])) {\n            inRefMST[idx] = true;\n        }\n    }\n    \n    // Process edges online\n    UnionFind uf(N);\n    \n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        int adopt = 0;\n        \n        if (!uf.connected(u[i], v[i])) {\n            if (inRefMST[i]) {\n                // Always accept reference MST edges - guarantees connectivity\n                adopt = 1;\n                uf.unite(u[i], v[i]);\n            } else {\n                // Accept non-MST edges only if they're cheap enough\n                // to potentially replace expensive MST edges\n                double percentile = (double)(l - d[i]) / (2.0 * d[i]);\n                percentile = max(0.0, min(1.0, percentile));\n                \n                int remaining = M - i - 1;\n                int needed = uf.components - 1;\n                double safety = (needed > 0) ? (double)remaining / needed : 999.0;\n                \n                double threshold;\n                if (safety >= 5) threshold = 0.3;\n                else if (safety >= 3) threshold = 0.4;\n                else if (safety >= 2) threshold = 0.5;\n                else threshold = 0.65;\n                \n                if (percentile <= threshold) {\n                    adopt = 1;\n                    uf.unite(u[i], v[i]);\n                }\n            }\n        }\n        \n        cout << adopt << endl;\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <cstring>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\n\nint N, M;\nvector<int> px, py, pt;\nvector<int> hx, hy;\nbool wall[SIZE][SIZE];\n\nbool inBounds(int x, int y) { return x >= 0 && x < SIZE && y >= 0 && y < SIZE; }\n\nvoid bfs(int sx, int sy, int dist[SIZE][SIZE]) {\n    memset(dist, -1, sizeof(int) * SIZE * SIZE);\n    if (!inBounds(sx, sy) || wall[sx][sy]) return;\n    queue<pair<int,int>> q;\n    dist[sx][sy] = 0;\n    q.push({sx, sy});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (inBounds(nx, ny) && !wall[nx][ny] && dist[nx][ny] == -1) {\n                dist[nx][ny] = dist[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n}\n\ndouble petThreatWeight(int t) {\n    switch(t) { case 1: return 1.0; case 2: return 1.5; case 3: return 2.0; case 4: return 2.5; case 5: return 2.0; default: return 1.0; }\n}\n\ndouble computeScoreWithDist(int dist[SIZE][SIZE]) {\n    int area = 0;\n    double effectivePets = 0;\n    for (int i = 0; i < SIZE; i++)\n        for (int j = 0; j < SIZE; j++)\n            if (dist[i][j] >= 0) area++;\n    for (int i = 0; i < N; i++)\n        if (dist[px[i]][py[i]] >= 0) effectivePets += 1.0;\n\n    int boundaryDist[SIZE][SIZE];\n    memset(boundaryDist, -1, sizeof(int) * SIZE * SIZE);\n    queue<pair<int,int>> q;\n    for (int x = 0; x < SIZE; x++)\n        for (int y = 0; y < SIZE; y++)\n            if (dist[x][y] < 0 && !wall[x][y]) {\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (inBounds(nx, ny) && dist[nx][ny] >= 0) {\n                        if (boundaryDist[x][y] == -1) { boundaryDist[x][y] = 1; q.push({x, y}); }\n                        break;\n                    }\n                }\n            }\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (inBounds(nx, ny) && !wall[nx][ny] && boundaryDist[nx][ny] == -1 && dist[nx][ny] < 0) {\n                boundaryDist[nx][ny] = boundaryDist[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        if (dist[px[i]][py[i]] >= 0) continue;\n        int d = boundaryDist[px[i]][py[i]];\n        if (d >= 1 && d <= 10) effectivePets += petThreatWeight(pt[i]) * 0.2 * exp(-0.2 * d);\n    }\n    return (double)area / 900.0 * pow(2.0, -effectivePets);\n}\n\nbool petAdjacentTo(int x, int y, const vector<int>& ppx, const vector<int>& ppy) {\n    for (int i = 0; i < N; i++) {\n        if (ppx[i] == x && ppy[i] == y) return true;\n        for (int d = 0; d < 4; d++)\n            if (ppx[i] == x + dx[d] && ppy[i] == y + dy[d]) return true;\n    }\n    return false;\n}\n\nbool humanAt(int x, int y, const vector<int>& hhx, const vector<int>& hhy) {\n    for (int i = 0; i < M; i++) if (hhx[i] == x && hhy[i] == y) return true;\n    return false;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N;\n    px.resize(N); py.resize(N); pt.resize(N);\n    for (int i = 0; i < N; i++) { cin >> px[i] >> py[i] >> pt[i]; px[i]--; py[i]--; }\n    cin >> M;\n    hx.resize(M); hy.resize(M);\n    for (int i = 0; i < M; i++) { cin >> hx[i] >> hy[i]; hx[i]--; hy[i]--; }\n    memset(wall, false, sizeof(wall));\n\n    for (int turn = 0; turn < 300; turn++) {\n        vector<int> startPx = px, startPy = py, startHx = hx, startHy = hy;\n        string actions(M, '.');\n        bool newWall[SIZE][SIZE] = {};\n\n        for (int i = 0; i < M; i++) {\n            int myHx = startHx[i], myHy = startHy[i];\n            int distBefore[SIZE][SIZE];\n            bfs(myHx, myHy, distBefore);\n            double bestScore = computeScoreWithDist(distBefore);\n            char bestAction = '.';\n\n            for (int d = 0; d < 4; d++) {\n                int wx = myHx + dx[d], wy = myHy + dy[d];\n                if (inBounds(wx, wy) && !wall[wx][wy] && !newWall[wx][wy] &&\n                    !petAdjacentTo(wx, wy, startPx, startPy) && !humanAt(wx, wy, startHx, startHy)) {\n                    wall[wx][wy] = true;\n                    int distAfter[SIZE][SIZE];\n                    bfs(myHx, myHy, distAfter);\n                    double newScore = computeScoreWithDist(distAfter);\n                    for (int j = 0; j < N; j++)\n                        if (distBefore[startPx[j]][startPy[j]] >= 0 && distAfter[startPx[j]][startPy[j]] < 0)\n                            newScore += 0.05;\n                    for (int dd = 0; dd < 4; dd++) {\n                        int nx = wx + dx[dd], ny = wy + dy[dd];\n                        if (!inBounds(nx, ny) || wall[nx][ny]) newScore += 0.003;\n                    }\n                    newScore += 0.001;\n                    wall[wx][wy] = false;\n                    if (newScore > bestScore) { bestScore = newScore; bestAction = \"udlr\"[d]; }\n                }\n            }\n            for (int d = 0; d < 4; d++) {\n                int nx = myHx + dx[d], ny = myHy + dy[d];\n                if (inBounds(nx, ny) && !wall[nx][ny] && !newWall[nx][ny]) {\n                    int distAfter[SIZE][SIZE];\n                    bfs(nx, ny, distAfter);\n                    double newScore = computeScoreWithDist(distAfter);\n                    if (newScore > bestScore) { bestScore = newScore; bestAction = \"UDLR\"[d]; }\n                }\n            }\n            actions[i] = bestAction;\n            switch (actions[i]) {\n                case 'u': newWall[myHx-1][myHy]=true; wall[myHx-1][myHy]=true; break;\n                case 'd': newWall[myHx+1][myHy]=true; wall[myHx+1][myHy]=true; break;\n                case 'l': newWall[myHx][myHy-1]=true; wall[myHx][myHy-1]=true; break;\n                case 'r': newWall[myHx][myHy+1]=true; wall[myHx][myHy+1]=true; break;\n                case 'U': hx[i]=myHx-1; hy[i]=myHy; break;\n                case 'D': hx[i]=myHx+1; hy[i]=myHy; break;\n                case 'L': hx[i]=myHx; hy[i]=myHy-1; break;\n                case 'R': hx[i]=myHx; hy[i]=myHy+1; break;\n            }\n        }\n        cout << actions << endl;\n        for (int i = 0; i < N; i++) {\n            string move; cin >> move;\n            for (char c : move) {\n                if (c=='U') px[i]--; else if (c=='D') px[i]++;\n                else if (c=='L') py[i]--; else if (c=='R') py[i]++;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <cstring>\n#include <array>\n#include <random>\nusing namespace std;\nint si,sj,ti,tj;double p;int ti_idx;\nint md[400][4];double fv[400][202];int c2d[256];\nmt19937 rng(42);\n\nvoid init(){\n    vector<string>h(20),v(19);for(int i=0;i<20;i++)cin>>h[i];for(int i=0;i<19;i++)cin>>v[i];\n    ti_idx=ti*20+tj;int di[]={-1,1,0,0},dj[]={0,0,-1,1};\n    for(int i=0;i<20;i++)for(int j=0;j<20;j++){int idx=i*20+j;\n        for(int d=0;d<4;d++){int ni=i+di[d],nj=j+dj[d];bool bl=(ni<0||ni>=20||nj<0||nj>=20);\n            if(!bl){if(d==0&&v[i-1][j]=='1')bl=true;else if(d==1&&v[i][j]=='1')bl=true;\n                else if(d==2&&h[i][j-1]=='1')bl=true;else if(d==3&&h[i][j]=='1')bl=true;}\n            if(bl){ni=i;nj=j;}md[idx][d]=ni*20+nj;}}\n    memset(fv,0,sizeof(fv));\n    for(int t=200;t>=1;t--)for(int idx=0;idx<400;idx++){\n        if(idx==ti_idx){fv[idx][t]=0;continue;}\n        double b=0;for(int d=0;d<4;d++){int ni=md[idx][d];\n            double sc=p*fv[idx][t+1];if(ni==ti_idx)sc+=(1-p)*(401-t);else sc+=(1-p)*fv[ni][t+1];\n            b=max(b,sc);}fv[idx][t]=b;}}\n\ndouble compute_score(const string&s){\n    double pr[400]={},np[400];pr[si*20+sj]=1;double es=0;\n    for(int t=0;t<(int)s.size();t++){int d=c2d[(unsigned char)s[t]];memset(np,0,sizeof(np));\n        for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;\n            if(i==ti_idx)continue;\n            np[i]+=p*pr[i];int ni=md[i][d];\n            if(ni==ti_idx)es+=(1-p)*pr[i]*(400-t);else np[ni]+=(1-p)*pr[i];}\n        memcpy(pr,np,sizeof(pr));}return es;}\n\nstring bfs_path(){int dist[400],pdir[400];memset(dist,-1,sizeof(dist));\n    queue<int>q;int start=si*20+sj;q.push(start);dist[start]=0;\n    while(!q.empty()){int idx=q.front();q.pop();if(idx==ti_idx)break;\n        for(int d=0;d<4;d++){int ni=md[idx][d];if(ni!=idx&&dist[ni]==-1){dist[ni]=dist[idx]+1;pdir[ni]=d;q.push(ni);}}}\n    string path;int idx=ti_idx;int di[]={-1,1,0,0},dj[]={0,0,-1,1};\n    while(idx!=start){int d=pdir[idx];path=string(1,\"UDLR\"[d])+path;idx=(idx/20-di[d])*20+(idx%20-dj[d]);}return path;}\n\nstring greedy(){double pr[400]={};pr[si*20+sj]=1;string res;\n    for(int t=1;t<=200;t++){double bsc=-1;int ba=0;\n        for(int d=0;d<4;d++){double rp=0;double np[400]={};\n            for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;\n                if(i==ti_idx)continue;np[i]+=p*pr[i];int ni=md[i][d];\n                if(ni==ti_idx)rp+=(1-p)*pr[i];else np[ni]+=(1-p)*pr[i];}\n            double sc=rp*(401-t);for(int i=0;i<400;i++)sc+=np[i]*fv[i][t+1];\n            if(sc>bsc){bsc=sc;ba=d;}}\n        res+=\"UDLR\"[ba];double np[400]={};\n        for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;\n            if(i==ti_idx)continue;np[i]+=p*pr[i];int ni=md[i][ba];\n            if(ni!=ti_idx)np[ni]+=(1-p)*pr[i];}memcpy(pr,np,sizeof(pr));}return res;}\n\nstring beam_search(int B, double noise=0.0){\n    vector<double> pr_flat(B * 400, 0.0);\n    vector<double> acc(B, 0.0);\n    vector<array<uint8_t, 200>> act(B);\n    int cur_B = 1;\n    pr_flat[si*20+sj] = 1.0;\n\n    for(int t=0; t<200; ++t){\n        vector<pair<double, pair<int, int>>> scores;\n        scores.reserve(cur_B * 4);\n        for(int i=0; i<cur_B; ++i){\n            double* p_pr = pr_flat.data() + i * 400;\n            for(int d=0; d<4; ++d){\n                double h = acc[i];\n                for(int j=0; j<400; ++j){\n                    if(p_pr[j] < 1e-18) continue;\n                    if(j == ti_idx) continue;\n                    h += p * p_pr[j] * fv[j][t+2];\n                    int ni = md[j][d];\n                    if(ni == ti_idx) h += (1-p) * p_pr[j] * (400-t);\n                    else h += (1-p) * p_pr[j] * fv[ni][t+2];\n                }\n                if(noise > 0) h += uniform_real_distribution<double>(-noise, noise)(rng);\n                scores.push_back({h, {i, d}});\n            }\n        }\n        int next_B = min(B, (int)scores.size());\n        if(next_B == 0) break;\n        if(next_B < (int)scores.size()) {\n            nth_element(scores.begin(), scores.begin() + next_B - 1, scores.end(), [](const auto& a, const auto& b){\n                return a.first > b.first;\n            });\n        }\n\n        vector<double> npr_flat(next_B * 400, 0.0);\n        vector<double> nacc(next_B, 0.0);\n        vector<array<uint8_t, 200>> nact(next_B);\n\n        for(int k=0; k<next_B; ++k){\n            int i = scores[k].second.first;\n            int d = scores[k].second.second;\n            nacc[k] = acc[i];\n            nact[k] = act[i];\n            nact[k][t] = d;\n            double* p_npr = npr_flat.data() + k * 400;\n            double* p_opr = pr_flat.data() + i * 400;\n            for(int j=0; j<400; ++j){\n                double pr = p_opr[j];\n                if(pr < 1e-18) continue;\n                if(j == ti_idx) continue;\n                p_npr[j] += pr * p;\n                int ni = md[j][d];\n                if(ni == ti_idx) nacc[k] += pr * (1-p) * (400-t);\n                else p_npr[ni] += pr * (1-p);\n            }\n        }\n        pr_flat = move(npr_flat);\n        acc = move(nacc);\n        act = move(nact);\n        cur_B = next_B;\n    }\n\n    double bsc=-1;string br;\n    for(int i=0;i<cur_B;i++){\n        if(acc[i] > bsc) {\n            bsc = acc[i];\n            br = \"\";\n            for(int t=0;t<200;++t) br += \"UDLR\"[act[i][t]];\n        }\n    }\n    return br;\n}\n\nstring suffix_opt(string s) {\n    for(int k=5; k<200; k+=5) {\n        if(k >= (int)s.size()) continue;\n        double pr[400] = {}; pr[si*20+sj] = 1;\n        for(int t=0; t<k; t++) {\n            int d = c2d[(unsigned char)s[t]];\n            double np[400] = {};\n            for(int i=0; i<400; ++i) {\n                if(pr[i] < 1e-18) continue;\n                if(i == ti_idx) continue;\n                np[i] += p * pr[i];\n                int ni = md[i][d];\n                if(ni != ti_idx) np[ni] += (1-p) * pr[i];\n            }\n            memcpy(pr, np, sizeof(pr));\n        }\n        string ns = s.substr(0, k);\n        for(int t=k; t<200; t++) {\n            double bsc2 = -1; int ba = 0;\n            for(int d=0; d<4; d++) {\n                double rp = 0; double np[400] = {};\n                for(int i=0; i<400; ++i) {\n                    if(pr[i] < 1e-18) continue;\n                    if(i == ti_idx) continue;\n                    np[i] += p * pr[i];\n                    int ni = md[i][d];\n                    if(ni == ti_idx) rp += (1-p) * pr[i];\n                    else np[ni] += (1-p) * pr[i];\n                }\n                double sc = rp * (400 - t);\n                for(int i=0; i<400; ++i) sc += np[i] * fv[i][t+2];\n                if(sc > bsc2) { bsc2 = sc; ba = d; }\n            }\n            ns += \"UDLR\"[ba];\n            double np[400] = {};\n            for(int i=0; i<400; ++i) {\n                if(pr[i] < 1e-18) continue;\n                if(i == ti_idx) continue;\n                np[i] += p * pr[i];\n                int ni = md[i][ba];\n                if(ni != ti_idx) np[ni] += (1-p) * pr[i];\n            }\n            memcpy(pr, np, sizeof(pr));\n        }\n        s = ns;\n    }\n    return s;\n}\n\nvoid coordinate_descent(string& best) {\n    int L = best.size();\n    double pr_arr[201][400];\n    double W[201][400];\n    \n    memset(pr_arr[0], 0, sizeof(pr_arr[0]));\n    pr_arr[0][si*20+sj] = 1.0;\n    for(int t=0; t<L; ++t) {\n        memset(pr_arr[t+1], 0, sizeof(pr_arr[t+1]));\n        int d = c2d[(unsigned char)best[t]];\n        for(int i=0; i<400; ++i) {\n            if(pr_arr[t][i] < 1e-18) continue;\n            if(i == ti_idx) continue;\n            pr_arr[t+1][i] += p * pr_arr[t][i];\n            int ni = md[i][d];\n            if(ni == ti_idx) continue;\n            pr_arr[t+1][ni] += (1-p) * pr_arr[t][i];\n        }\n    }\n    \n    for(int i=0; i<400; ++i) W[L][i] = 0;\n    for(int t=L-1; t>=0; --t) {\n        int d = c2d[(unsigned char)best[t]];\n        for(int i=0; i<400; ++i) {\n            if(i == ti_idx) { W[t][i] = 0; continue; }\n            double val = p * W[t+1][i];\n            int ni = md[i][d];\n            if(ni == ti_idx) val += (1-p) * (400 - t);\n            else val += (1-p) * W[t+1][ni];\n            W[t][i] = val;\n        }\n    }\n    \n    for(int pass=0; pass<50; ++pass) {\n        bool changed = false;\n        for(int pos=0; pos<L; ++pos) {\n            double current_score = 0;\n            for(int i=0; i<400; ++i) {\n                if(pr_arr[pos][i] < 1e-18) continue;\n                current_score += pr_arr[pos][i] * W[pos][i];\n            }\n            \n            double best_new_score = current_score;\n            int best_d = c2d[(unsigned char)best[pos]];\n            \n            for(int d=0; d<4; ++d) {\n                if(d == c2d[(unsigned char)best[pos]]) continue;\n                double new_score = 0;\n                for(int i=0; i<400; ++i) {\n                    if(pr_arr[pos][i] < 1e-18) continue;\n                    double val = p * W[pos+1][i];\n                    int ni = md[i][d];\n                    if(ni == ti_idx) val += (1-p) * (400 - pos);\n                    else val += (1-p) * W[pos+1][ni];\n                    new_score += pr_arr[pos][i] * val;\n                }\n                if(new_score > best_new_score + 1e-9) {\n                    best_new_score = new_score;\n                    best_d = d;\n                }\n            }\n            \n            if(best_d != c2d[(unsigned char)best[pos]]) {\n                changed = true;\n                best[pos] = \"UDLR\"[best_d];\n                \n                for(int t=pos; t<L; ++t) {\n                    memset(pr_arr[t+1], 0, sizeof(pr_arr[t+1]));\n                    int dd = c2d[(unsigned char)best[t]];\n                    for(int i=0; i<400; ++i) {\n                        if(pr_arr[t][i] < 1e-18) continue;\n                        if(i == ti_idx) continue;\n                        pr_arr[t+1][i] += p * pr_arr[t][i];\n                        int ni = md[i][dd];\n                        if(ni == ti_idx) continue;\n                        pr_arr[t+1][ni] += (1-p) * pr_arr[t][i];\n                    }\n                }\n                \n                int dd = c2d[(unsigned char)best[pos]];\n                for(int i=0; i<400; ++i) {\n                    if(i == ti_idx) { W[pos][i] = 0; continue; }\n                    double val = p * W[pos+1][i];\n                    int ni = md[i][dd];\n                    if(ni == ti_idx) val += (1-p) * (400 - pos);\n                    else val += (1-p) * W[pos+1][ni];\n                    W[pos][i] = val;\n                }\n            }\n        }\n        if(!changed) break;\n        \n        for(int t=L-1; t>=0; --t) {\n            int dd = c2d[(unsigned char)best[t]];\n            for(int i=0; i<400; ++i) {\n                if(i == ti_idx) { W[t][i] = 0; continue; }\n                double val = p * W[t+1][i];\n                int ni = md[i][dd];\n                if(ni == ti_idx) val += (1-p) * (400 - t);\n                else val += (1-p) * W[t+1][ni];\n                W[t][i] = val;\n            }\n        }\n    }\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);cin.tie(nullptr);\n    c2d['U']=0;c2d['D']=1;c2d['L']=2;c2d['R']=3;\n    cin>>si>>sj>>ti>>tj>>p;init();\n    string best; double bs = -1;\n    \n    auto optimize = [&](string s) {\n        s = suffix_opt(s);\n        coordinate_descent(s);\n        double sc = compute_score(s);\n        if(sc > bs) { bs = sc; best = s; }\n    };\n    \n    string sp = bfs_path();\n    {string s; while((int)(s.size()+sp.size())<=200) s+=sp; optimize(s);}\n    for(int r=2; r<=5; r++) {string s; for(char c:sp) for(int k=0; k<r&&(int)s.size()<200; k++) s+=c; optimize(s);}\n    \n    optimize(greedy());\n    optimize(beam_search(300, 0));\n    optimize(beam_search(100, 2.0));\n    \n    for(int i=0; i<5; ++i) {\n        string s = best;\n        for(int j=0; j<20; ++j) {\n            int pos = uniform_int_distribution<int>(0, 199)(rng);\n            s[pos] = \"UDLR\"[uniform_int_distribution<int>(0, 3)(rng)];\n        }\n        optimize(s);\n    }\n    \n    for(int i=0; i<3; ++i) {\n        string s = best;\n        s = suffix_opt(s);\n        coordinate_descent(s);\n        double sc = compute_score(s);\n        if(sc > bs) { bs = sc; best = s; }\n    }\n    \n    for(int len=50; len<=200; len+=10) {\n        if(len < (int)best.size()) {\n            string ns = best.substr(0, len);\n            double sc = compute_score(ns);\n            if(sc > bs) { bs = sc; best = ns; }\n        }\n    }\n    \n    cout<<best<<endl;return 0;}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint orig[N][N], cur[N][N], rot[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 rt[8][4]={{0,1,2,3},{1,2,3,0},{2,3,0,1},{3,0,1,2},{4,5,4,5},{5,4,5,4},{6,7,6,7},{7,6,7,6}};\n\nint cycle_counts[2002] = {};\nset<int> active_lengths;\nlong long total_loop_edges = 0;\n\nint vm[N][N][4]; \nunsigned int vcnt=0;\n\nvoid update_cycle_counts(int len, int delta) {\n    if (delta == 1) {\n        if (cycle_counts[len] == 0) active_lengths.insert(len);\n        cycle_counts[len]++;\n        total_loop_edges += len;\n    } else {\n        cycle_counts[len]--;\n        total_loop_edges -= len;\n        if (cycle_counts[len] == 0) active_lengths.erase(len);\n    }\n}\n\nvoid init_cycle_counts() {\n    memset(cycle_counts, 0, sizeof(cycle_counts));\n    active_lengths.clear();\n    total_loop_edges = 0;\n    \n    ++vcnt;\n    if (vcnt == 0) { memset(vm, 0, sizeof(vm)); vcnt = 1; }\n    \n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) {\n        int t = cur[i][j];\n        for (int d=0; d<4; d++) {\n            if (vm[i][j][d] == vcnt || to[t][d] == -1) continue;\n            int si=i, sj=j, sd=d, ci=i, cj=j, cd=d, len=0;\n            bool is_cycle = false;\n            while (true) {\n                vm[ci][cj][cd] = vcnt;\n                int t2 = cur[ci][cj];\n                int d2 = to[t2][cd];\n                if (d2 == -1) break;\n                int ni = ci + di[d2], nj = cj + dj[d2];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n                len++;\n                int nd = (d2 + 2) % 4;\n                if (ni == si && nj == sj && nd == sd) { is_cycle = true; break; }\n                if (vm[ni][nj][nd] == vcnt) break;\n                if (len > 2000) break;\n                ci = ni; cj = nj; cd = nd;\n            }\n            if (is_cycle) {\n                update_cycle_counts(len, 1);\n            }\n        }\n    }\n}\n\nvoid update_tile(int i, int j, int new_t) {\n    int old_t = cur[i][j];\n    if (old_t == new_t) return;\n\n    bool visited_old[4] = {false, false, false, false};\n    for (int d = 0; d < 4; d++) {\n        if (visited_old[d] || to[old_t][d] == -1) continue;\n        int len = 0;\n        int ci = i, cj = j, cd = d;\n        bool is_cycle = false;\n        while (true) {\n            int t2 = (ci == i && cj == j) ? old_t : cur[ci][cj];\n            int d2 = to[t2][cd];\n            if (d2 == -1) break;\n            if (ci == i && cj == j) { visited_old[cd] = true; visited_old[d2] = true; }\n            int ni = ci + di[d2], nj = cj + dj[d2];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n            len++;\n            int nd = (d2 + 2) % 4;\n            if (ni == i && nj == j && nd == d) { is_cycle = true; break; }\n            if (len > 2000) break;\n            ci = ni; cj = nj; cd = nd;\n        }\n        if (is_cycle) {\n            update_cycle_counts(len, -1);\n        }\n    }\n\n    cur[i][j] = new_t;\n    bool visited_new[4] = {false, false, false, false};\n    for (int d = 0; d < 4; d++) {\n        if (visited_new[d] || to[new_t][d] == -1) continue;\n        int len = 0;\n        int ci = i, cj = j, cd = d;\n        bool is_cycle = false;\n        while (true) {\n            int t2 = (ci == i && cj == j) ? new_t : cur[ci][cj];\n            int d2 = to[t2][cd];\n            if (d2 == -1) break;\n            if (ci == i && cj == j) { visited_new[cd] = true; visited_new[d2] = true; }\n            int ni = ci + di[d2], nj = cj + dj[d2];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n            len++;\n            int nd = (d2 + 2) % 4;\n            if (ni == i && nj == j && nd == d) { is_cycle = true; break; }\n            if (len > 2000) break;\n            ci = ni; cj = nj; cd = nd;\n        }\n        if (is_cycle) {\n            update_cycle_counts(len, 1);\n        }\n    }\n}\n\nlong long get_score() {\n    if (active_lengths.empty()) return 0;\n    auto it = active_lengths.rbegin();\n    int L1 = *it;\n    if (cycle_counts[L1] >= 2) return (long long)L1 * L1;\n    if (active_lengths.size() == 1) return 0;\n    int L2 = *next(it);\n    return (long long)L1 * L2;\n}\n\nlong long get_sa_energy() {\n    if (active_lengths.empty()) return 0;\n    auto it = active_lengths.rbegin();\n    int L1 = *it;\n    \n    if (cycle_counts[L1] >= 2) {\n        return (long long)L1 * L1 * 1000 + total_loop_edges;\n    }\n    if (active_lengths.size() == 1) {\n        return total_loop_edges;\n    }\n    int L2 = *next(it);\n    return (long long)L1 * L2 * 1000 + total_loop_edges;\n}\n\nint lmatch(int i, int j) {\n    int t = cur[i][j], m = 0;\n    for (int d = 0; d < 4; d++) {\n        if (to[t][d] == -1) continue;\n        int ni = i + di[d], nj = j + dj[d];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n        if (to[cur[ni][nj]][(d + 2) % 4] != -1) m++;\n    }\n    return m;\n}\n\nvoid greedy_match() {\n    for (int pass = 0; pass < 10; pass++) {\n        bool ch = false;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            int br = rot[i][j], bm = lmatch(i, j);\n            for (int r = 0; r < 4; r++) {\n                if (r == rot[i][j]) continue;\n                cur[i][j] = rt[orig[i][j]][r];\n                int m = lmatch(i, j);\n                if (m > bm) { bm = m; br = r; ch = true; }\n            }\n            rot[i][j] = br; cur[i][j] = rt[orig[i][j]][br];\n        }\n        if (!ch) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    for (int i = 0; i < N; i++) { string s; cin >> s; for (int j = 0; j < N; j++) orig[i][j] = s[j] - '0'; }\n    mt19937 rng(42);\n    long long gbest = 0; int grot[N][N] = {};\n    auto t0 = chrono::steady_clock::now();\n    bool have_best = false;\n\n    for (int trial = 0; ; trial++) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - t0).count();\n        if (elapsed > 1.5) break;\n\n        if (have_best && trial % 2 == 1) {\n            memcpy(rot, grot, sizeof(rot));\n            int np = 20 + rng() % 80;\n            for (int k = 0; k < np; k++) { int i = rng() % N, j = rng() % N; rot[i][j] = rng() % 4; }\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cur[i][j] = rt[orig[i][j]][rot[i][j]];\n            greedy_match();\n        } else {\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) { rot[i][j] = rng() % 4; cur[i][j] = rt[orig[i][j]][rot[i][j]]; }\n            greedy_match();\n        }\n\n        init_cycle_counts();\n        long long current_energy = get_sa_energy();\n        long long best_score = get_score();\n        int brot[N][N]; memcpy(brot, rot, sizeof(rot));\n\n        for (int iter = 0; ; iter++) {\n            if (iter % 10000 == 0) {\n                if (chrono::duration<double>(chrono::steady_clock::now() - t0).count() > 1.7) break;\n            }\n            double frac = min(iter / 2000000.0, 1.0);\n            double temp = 50000.0 * pow(0.00002, frac);\n            int idx = (rng() >> 2) % 900, i = idx / N, j = idx % N;\n            int old_r = rot[i][j];\n            int new_r = (rng() >> 12) & 3;\n            if (old_r == new_r) continue;\n            int new_t = rt[orig[i][j]][new_r];\n            if (new_t == cur[i][j]) continue;\n\n            update_tile(i, j, new_t);\n            long long new_energy = get_sa_energy();\n            long long diff = new_energy - current_energy;\n\n            if (diff >= 0 || (double)(rng() & 0xFFFF) / 65536.0 < exp((double)diff / temp)) {\n                current_energy = new_energy;\n                rot[i][j] = new_r;\n                long long true_score = get_score();\n                if (true_score > best_score) {\n                    best_score = true_score;\n                    memcpy(brot, rot, sizeof(rot));\n                }\n            } else {\n                update_tile(i, j, rt[orig[i][j]][old_r]);\n                rot[i][j] = old_r;\n            }\n        }\n\n        if (best_score > gbest) {\n            gbest = best_score;\n            memcpy(grot, brot, sizeof(grot));\n            have_best = true;\n        }\n    }\n\n    memcpy(rot, grot, sizeof(rot));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cur[i][j] = rt[orig[i][j]][rot[i][j]];\n    init_cycle_counts();\n    long long current_score = get_score();\n\n    for (int pass = 0; pass < 10; pass++) {\n        bool imp = false;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            int old_t = cur[i][j];\n            int best_new_t = old_t;\n            long long best_local_score = current_score;\n            int best_new_r = rot[i][j];\n\n            for (int r = 0; r < 4; r++) {\n                int new_t = rt[orig[i][j]][r];\n                if (new_t == old_t) continue;\n                update_tile(i, j, new_t);\n                long long new_score = get_score();\n                if (new_score > best_local_score) {\n                    best_local_score = new_score;\n                    best_new_t = new_t;\n                    best_new_r = r;\n                }\n                update_tile(i, j, old_t);\n            }\n\n            if (best_new_t != old_t) {\n                update_tile(i, j, best_new_t);\n                rot[i][j] = best_new_r;\n                current_score = best_local_score;\n                imp = true;\n            }\n        }\n        if (!imp) break;\n    }\n\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cout << rot[i][j];\n    cout << endl;\n\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N,T,board[10][10],init_board[10][10],er,ec,init_er,init_ec;\nint target[10][10],tile_count[16];\nconst int DR[]={-1,1,0,0},DC[]={0,0,-1,1};\nconst int BS[]={2,8,1,4},BN[]={8,2,4,1};\nconst char DC_C[]={'U','D','L','R'};\nconst int REV[]={1,0,3,2};\n\nvoid gen_target(mt19937& rng,int skip_r,int skip_c){\n    vector<tuple<unsigned,int,int>> el;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(i==skip_r&&j==skip_c)continue;\n        if(i+1<N&&!(i+1==skip_r&&j==skip_c))el.push_back({rng(),i*N+j,(i+1)*N+j});\n        if(j+1<N&&!(i==skip_r&&j+1==skip_c))el.push_back({rng(),i*N+j,i*N+j+1});\n    }\n    sort(el.begin(),el.end());\n    vector<int> par(N*N),rnk(N*N,0);iota(par.begin(),par.end(),0);\n    function<int(int)> f=[&](int x)->int{return par[x]==x?x:par[x]=f(par[x]);};\n    memset(target,0,sizeof(target));\n    for(auto&[w,u,v]:el){\n        int pu=f(u),pv=f(v);\n        if(pu!=pv){\n            int r1=u/N,c1=u%N,r2=v/N,c2=v%N;\n            if(r2==r1+1){target[r1][c1]|=8;target[r2][c2]|=2;}\n            else{target[r1][c1]|=4;target[r2][c2]|=1;}\n            if(rnk[pu]<rnk[pv])swap(pu,pv);\n            par[pv]=pu;if(rnk[pu]==rnk[pv])rnk[pu]++;\n        }\n    }\n}\n\nint match_ub(){\n    int need[16]={};\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(target[i][j])need[target[i][j]]++;\n    int total=0;\n    for(int t=1;t<16;t++){\n        if(!need[t])continue;int avail=0;\n        for(int s=1;s<16;s++)if((s&t)==t)avail+=tile_count[s];\n        total+=min(avail,need[t]);\n    }\n    return total;\n}\n\nint par2[100],sz2[100],edg2[100];\nint find2(int x){while(par2[x]!=x)x=par2[x]=par2[par2[x]];return x;}\nvoid unite2(int x,int y){x=find2(x);y=find2(y);if(x==y){edg2[x]++;return;}if(sz2[x]<sz2[y])swap(x,y);par2[y]=x;sz2[x]+=sz2[y];edg2[x]+=edg2[y]+1;}\n\nint max_tree(){\n    for(int i=0;i<N*N;i++){par2[i]=i;sz2[i]=board[i/N][i%N]?1:0;edg2[i]=0;}\n    for(int i=0;i<N;i++)for(int j=0;j<N-1;j++)\n        if(board[i][j]&&board[i][j+1]&&(board[i][j]&4)&&(board[i][j+1]&1))unite2(i*N+j,i*N+j+1);\n    for(int i=0;i<N-1;i++)for(int j=0;j<N;j++)\n        if(board[i][j]&&board[i+1][j]&&(board[i][j]&8)&&(board[i+1][j]&2))unite2(i*N+j,(i+1)*N+j);\n    int mx=0;for(int i=0;i<N*N;i++)if(board[i/N][i%N]&&find2(i)==i&&edg2[i]==sz2[i]-1)mx=max(mx,sz2[i]);return mx;\n}\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    cin>>N>>T;\n    memset(tile_count,0,sizeof(tile_count));\n    for(int i=0;i<N;i++){string s;cin>>s;for(int j=0;j<N;j++){char c=s[j];board[i][j]=(c>='0'&&c<='9')?c-'0':c-'a'+10;if(board[i][j])tile_count[board[i][j]]++;else{init_er=i;init_ec=j;}}}\n    memcpy(init_board,board,sizeof(board));er=init_er;ec=init_ec;\n    int gbm=max_tree();string gbm_moves;\n    auto start=chrono::high_resolution_clock::now();\n    for(int trial=0;;trial++){\n        auto now=chrono::high_resolution_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-start).count()>2800)break;\n        mt19937 rng(42+trial*137);\n        int skip_r=rng()%N,skip_c=rng()%N;\n        gen_target(rng,skip_r,skip_c);\n        int ub=match_ub();if(ub<gbm+2)continue;\n        memcpy(board,init_board,sizeof(board));er=init_er;ec=init_ec;\n        int cm=0,cc=0,tc=0;\n        for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(board[i][j]&&target[i][j]&&(board[i][j]&target[i][j])==target[i][j])cm++;\n        for(int i=0;i<N;i++)for(int j=0;j<N-1;j++){\n            if(board[i][j]&&board[i][j+1]&&(board[i][j]&4)&&(board[i][j+1]&1)){cc++;if((target[i][j]&4)&&(target[i][j+1]&1))tc++;}\n        }\n        for(int i=0;i<N-1;i++)for(int j=0;j<N;j++){\n            if(board[i][j]&&board[i+1][j]&&(board[i][j]&8)&&(board[i+1][j]&2)){cc++;if((target[i][j]&8)&&(target[i+1][j]&2))tc++;}\n        }\n        string mv;mv.reserve(T);int bm=0;size_t bi=0;int ld=-1;double temp=2.0;int stale=0,chk=0;\n        while((int)mv.size()<T){\n            auto now2=chrono::high_resolution_clock::now();\n            if(chrono::duration_cast<chrono::milliseconds>(now2-start).count()>2800)break;\n            long long dv[4];\n            for(int d=0;d<4;d++){\n                int nr=er+DR[d],nc=ec+DC[d];\n                if(nr<0||nr>=N||nc<0||nc>=N){dv[d]=-1e18;continue;}\n                int X=board[nr][nc];\n                int dm=0;\n                if(target[nr][nc]&&(X&target[nr][nc])==target[nr][nc])dm--;\n                if(target[er][ec]&&(X&target[er][ec])==target[er][ec])dm++;\n                int dtc=0,dxc=0;\n                for(int dd=0;dd<4;dd++){\n                    int r=er+DR[dd],c=ec+DC[dd];\n                    if(r>=0&&r<N&&c>=0&&c<N&&!(r==nr&&c==nc)){int nb=board[r][c];if(nb&&(X&BS[dd])&&(nb&BN[dd])){if(target[er][ec]&BS[dd])dtc++;else dxc++;}}\n                    r=nr+DR[dd];c=nc+DC[dd];\n                    if(r>=0&&r<N&&c>=0&&c<N&&!(r==er&&c==ec)){int nb=board[r][c];if(nb&&(X&BS[dd])&&(nb&BN[dd])){if(target[nr][nc]&BS[dd])dtc--;else dxc--;}}\n                }\n                dv[d]=(long long)dm*1000+dtc*200+dxc*30;\n            }\n            int bd=-1;long long bv=-1e18;for(int d=0;d<4;d++)if(dv[d]>bv){bv=dv[d];bd=d;}\n            if(bd==-1)break;\n            int ch;\n            if(bv>0){ch=bd;stale=0;}\n            else{stale++;double delta=(double)bv/1000.0;if(exp(delta/max(temp,0.01))>(double)rng()/(double)UINT32_MAX)ch=bd;\n            else{int v[4],nv=0;for(int d=0;d<4;d++){if(dv[d]<=-1e18)continue;if(ld>=0&&d==REV[ld])continue;v[nv++]=d;}\n            if(!nv)for(int d=0;d<4;d++)if(dv[d]>-1e18)v[nv++]=d;if(!nv)break;ch=v[rng()%nv];}}\n            int nr=er+DR[ch],nc=ec+DC[ch],X=board[nr][nc];\n            if(target[nr][nc]&&(X&target[nr][nc])==target[nr][nc])cm--;\n            if(target[er][ec]&&(X&target[er][ec])==target[er][ec])cm++;\n            for(int dd=0;dd<4;dd++){\n                int r=er+DR[dd],c=ec+DC[dd];\n                if(r>=0&&r<N&&c>=0&&c<N&&!(r==nr&&c==nc)){int nb=board[r][c];if(nb&&(X&BS[dd])&&(nb&BN[dd])){cc++;if(target[er][ec]&BS[dd])tc++;}}\n                r=nr+DR[dd];c=nc+DC[dd];\n                if(r>=0&&r<N&&c>=0&&c<N&&!(r==er&&c==ec)){int nb=board[r][c];if(nb&&(X&BS[dd])&&(nb&BN[dd])){cc--;if(target[nr][nc]&BS[dd])tc--;}}\n            }\n            swap(board[er][ec],board[nr][nc]);er=nr;ec=nc;mv+=DC_C[ch];ld=ch;\n            if(++chk>=150){chk=0;int mx=max_tree();if(mx>bm){bm=mx;bi=mv.size();stale=0;}if(mx==N*N-1)break;}\n            temp*=0.99998;if(stale>400){temp=min(temp*2.5,8.0);stale=200;}\n        }\n        int mx=max_tree();if(mx>bm){bm=mx;bi=mv.size();}\n        if(bm>gbm){gbm=bm;gbm_moves=mv.substr(0,bi);}\n        if(gbm==N*N-1)break;\n    }\n    cout<<gbm_moves<<'\\n';\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\n\nint N, K;\nint a_arr[11];\nvector<ll> px, py;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> K;\n    for (int d = 1; d <= 10; d++) cin >> a_arr[d];\n    px.resize(N); py.resize(N);\n    for (int i = 0; i < N; i++) cin >> px[i] >> py[i];\n    \n    auto start = chrono::steady_clock::now();\n    \n    struct Line { ll la, lb, lc, p1x, p1y, p2x, p2y; };\n    vector<Line> lines;\n    \n    auto compute_groups = [&]() {\n        int nl = lines.size();\n        vector<pair<vector<int>, int>> entries;\n        entries.reserve(N);\n        for (int i = 0; i < N; i++) {\n            vector<int> sig; sig.reserve(nl);\n            bool dead = false;\n            for (int j = 0; j < nl; j++) {\n                ll val = lines[j].la*px[i] + lines[j].lb*py[i] + lines[j].lc;\n                if (val == 0) { dead = true; break; }\n                sig.push_back(val > 0 ? 1 : -1);\n            }\n            if (!dead) entries.push_back({move(sig), i});\n        }\n        sort(entries.begin(), entries.end());\n        vector<pair<vector<int>, vector<int>>> groups;\n        for (int i = 0; i < (int)entries.size(); ) {\n            int j = i; vector<int> members;\n            while (j < (int)entries.size() && entries[j].first == entries[i].first)\n                members.push_back(entries[j++].second);\n            groups.push_back({entries[i].first, move(members)});\n            i = j;\n        }\n        return groups;\n    };\n    \n    auto score_groups = [&](auto& groups) {\n        int pc[11] = {};\n        for (auto& [sig, mem] : groups) { int sz = mem.size(); if (sz >= 1 && sz <= 10) pc[sz]++; }\n        int s = 0; for (int d = 1; d <= 10; d++) s += min(a_arr[d], pc[d]); return s;\n    };\n    \n    auto eval_line = [&](ll la, ll lb, ll lc, auto& groups) {\n        int pc[11] = {};\n        for (auto& [sig, mem] : groups) {\n            int pos = 0, neg = 0;\n            for (int i : mem) {\n                ll val = la*px[i] + lb*py[i] + lc;\n                if (val > 0) pos++; else if (val < 0) neg++;\n            }\n            if (pos >= 1 && pos <= 10) pc[pos]++;\n            if (neg >= 1 && neg <= 10) pc[neg]++;\n        }\n        int s = 0; for (int d = 1; d <= 10; d++) s += min(a_arr[d], pc[d]); return s;\n    };\n    \n    auto make_sep = [&](int i, int j) -> Line {\n        ll dx = py[i] - py[j], dy = px[j] - px[i];\n        ll g = __gcd(abs(dx), abs(dy)); if (g > 0) { dx /= g; dy /= g; }\n        ll mx = px[i] + px[j], my = py[i] + py[j];\n        for (int r = 0; r < 4; r++) {\n            ll cx = (mx + (r & 1)) / 2, cy = (my + ((r >> 1) & 1)) / 2;\n            ll la = dy, lb = -dx, lc = -dy*cx + dx*cy;\n            ll vi = la*px[i]+lb*py[i]+lc, vj = la*px[j]+lb*py[j]+lc;\n            if (vi != 0 && vj != 0 && (vi > 0) != (vj > 0))\n                return {la, lb, lc, cx, cy, cx+dx, cy+dy};\n        }\n        ll cx = mx/2, cy = my/2;\n        ll la = dy, lb = -dx, lc = -dy*cx + dx*cy;\n        return {la, lb, lc, cx, cy, cx+dx, cy+dy};\n    };\n    \n    auto make_through = [&](ll cx, ll cy, ll dx, ll dy) -> Line {\n        ll g = __gcd(abs(dx), abs(dy)); if (g > 0) { dx /= g; dy /= g; }\n        if (dx == 0 && dy == 0) dx = 1;\n        ll la = dy, lb = -dx, lc = -dy*cx + dx*cy;\n        return {la, lb, lc, cx, cy, cx+dx, cy+dy};\n    };\n    \n    auto gen_cands = [&](auto& groups, bool all = false) {\n        int pc[11] = {};\n        for (auto& [sig, mem] : groups) { int sz = mem.size(); if (sz >= 1 && sz <= 10) pc[sz]++; }\n        vector<Line> cands;\n        set<tuple<ll,ll,ll>> seen;\n        auto add = [&](Line l) {\n            ll a=l.la, b=l.lb, c=l.lc;\n            ll g = __gcd(__gcd(abs(a),abs(b)),abs(c));\n            if(g>0){a/=g;b/=g;c/=g;}\n            if(a<0||(a==0&&b<0)||(a==0&&b==0&&c<0)){a=-a;b=-b;c=-c;}\n            if(seen.insert({a,b,c}).second) cands.push_back(l);\n        };\n        for (auto& [sig, mem] : groups) {\n            int sz = mem.size();\n            if (sz <= 1) continue;\n            if (!all && sz <= 10 && pc[sz] <= a_arr[sz]) continue;\n            int lim = min((int)mem.size(), 12);\n            for (int ii = 0; ii < lim; ii++)\n                for (int jj = ii+1; jj < lim; jj++)\n                    add(make_sep(mem[ii], mem[jj]));\n            ll cx = 0, cy = 0;\n            for (int i : mem) { cx += px[i]; cy += py[i]; }\n            cx /= sz; cy /= sz;\n            for (int ag = 0; ag < 12; ag++) {\n                double ar = ag*M_PI/6;\n                ll ddx = (ll)round(10000*cos(ar)), ddy = (ll)round(10000*sin(ar));\n                if (ddx || ddy) add(make_through(cx, cy, ddx, ddy));\n            }\n            for (int ii = 0; ii < min(lim,5); ii++)\n                for (int jj = ii+1; jj < min(lim,5); jj++) {\n                    ll mx2 = (px[mem[ii]]+px[mem[jj]])/2, my2 = (py[mem[ii]]+py[mem[jj]])/2;\n                    for (int ag = 0; ag < 6; ag++) {\n                        double ar = ag*M_PI/3;\n                        ll ddx = (ll)round(10000*cos(ar)), ddy = (ll)round(10000*sin(ar));\n                        if (ddx || ddy) add(make_through(mx2, my2, ddx, ddy));\n                    }\n                }\n        }\n        return cands;\n    };\n    \n    for (int iter = 0; iter < K; iter++) {\n        if (chrono::duration<double>(chrono::steady_clock::now()-start).count() > 1.2) break;\n        auto groups = compute_groups();\n        int cs = score_groups(groups);\n        int mx = 0; for(int d=1;d<=10;d++) mx += a_arr[d];\n        if (cs == mx) break;\n        auto cands = gen_cands(groups);\n        if (cands.empty()) break;\n        int bs = cs, bi = -1;\n        for (int i = 0; i < (int)cands.size(); i++) {\n            int s = eval_line(cands[i].la, cands[i].lb, cands[i].lc, groups);\n            if (s > bs) { bs = s; bi = i; }\n        }\n        if (bi >= 0) lines.push_back(cands[bi]);\n        else {\n            int max_sz = 1, max_i = -1;\n            for (int i = 0; i < (int)groups.size(); i++)\n                if ((int)groups[i].second.size() > max_sz) { max_sz = groups[i].second.size(); max_i = i; }\n            if (max_sz > 1 && (int)lines.size() < K)\n                lines.push_back(make_sep(groups[max_i].second[0], groups[max_i].second[1]));\n            else break;\n        }\n    }\n    \n    mt19937 rng(42);\n    int ni = 0;\n    while (chrono::duration<double>(chrono::steady_clock::now()-start).count() < 2.8) {\n        int nl = lines.size();\n        if (nl == 0) break;\n        int idx = rng() % nl;\n        auto old = lines[idx];\n        lines[idx] = lines.back(); lines.pop_back();\n        auto groups = compute_groups();\n        int cs = score_groups(groups);\n        auto cands = gen_cands(groups);\n        cands.push_back(old);\n        int bs = cs, bi = -1;\n        for (int i = 0; i < (int)cands.size(); i++) {\n            int s = eval_line(cands[i].la, cands[i].lb, cands[i].lc, groups);\n            if (s > bs) { bs = s; bi = i; }\n        }\n        if (bi >= 0) lines.push_back(cands[bi]); else lines.push_back(old);\n        if (bs > cs) ni = 0; else ni++;\n        if (ni > 300) break;\n        if ((int)lines.size() < K) {\n            groups = compute_groups(); cs = score_groups(groups);\n            cands = gen_cands(groups, true);\n            bs = cs; bi = -1;\n            for (int i = 0; i < (int)cands.size(); i++) {\n                int s = eval_line(cands[i].la, cands[i].lb, cands[i].lc, groups);\n                if (s > bs) { bs = s; bi = i; }\n            }\n            if (bi >= 0) { lines.push_back(cands[bi]); ni = 0; }\n        }\n    }\n    \n    cout << lines.size() << \"\\n\";\n    for (auto& l : lines)\n        cout << l.p1x << \" \" << l.p1y << \" \" << l.p2x << \" \" << l.p2y << \"\\n\";\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <map>\n#include <numeric>\n#include <algorithm>\n#include <array>\n\nusing namespace std;\n\nint N, M;\nvector<vector<bool>> has_dot;\nvector<array<int,8>> ops;\nmap<int, set<pair<int,int>>> segs[4];\n\nvector<int> dots_y[65];\nvector<int> dots_x[65];\nvector<int> dots_u[130];\nvector<int> dots_v[130];\nvector<int> pt_idx[65];\nvector<pair<int,int>> existing_dots;\n\nset<int> candidates;\nvector<pair<double, pair<int,int>>> empty_pts_vec;\n\nint seg_type(int x1,int y1,int x2,int y2){\n    if(y1==y2)return 0;\n    if(x1==x2)return 1;\n    if(x2-x1==y2-y1)return 2;\n    return 3;\n}\nint line_id(int t,int x,int y){\n    if(t==0)return y;\n    if(t==1)return x;\n    if(t==2)return x-y;\n    return x+y;\n}\nint line_coord(int t,int x,int y){\n    if(t==0||t==2||t==3)return x;\n    return y;\n}\n\nbool check_overlap(int t, int lid, int s, int e) {\n    if (s > e) swap(s, e);\n    auto it = segs[t].find(lid);\n    if (it == segs[t].end()) return false;\n    auto& st = it->second;\n    auto jt = st.upper_bound({s, 1e9});\n    if (jt != st.begin()) {\n        auto kt = prev(jt);\n        if (kt->second > s) return true;\n    }\n    if (jt != st.end()) {\n        if (jt->first < e) return true;\n    }\n    return false;\n}\n\nvoid add_seg(int t, int lid, int s, int e) {\n    if (s > e) swap(s, e);\n    auto& st = segs[t][lid];\n    auto it = st.upper_bound({s, 1e9});\n    if (it != st.begin()) {\n        auto kt = prev(it);\n        if (kt->second >= s) {\n            s = min(s, kt->first);\n            e = max(e, kt->second);\n            st.erase(kt);\n        }\n    }\n    it = st.upper_bound({s, 1e9});\n    while (it != st.end() && it->first <= e) {\n        e = max(e, it->second);\n        it = st.erase(it);\n    }\n    st.insert({s, e});\n}\n\nbool has_perim_overlap(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    int e[4][4]={{x1,y1,x2,y2},{x2,y2,x3,y3},{x3,y3,x4,y4},{x4,y4,x1,y1}};\n    for(int i=0;i<4;i++){\n        int t=seg_type(e[i][0],e[i][1],e[i][2],e[i][3]);\n        int lid=line_id(t,e[i][0],e[i][1]);\n        int s=line_coord(t,e[i][0],e[i][1]);\n        int ee=line_coord(t,e[i][2],e[i][3]);\n        if(check_overlap(t,lid,s,ee))return true;\n    }\n    return false;\n}\nvoid add_perim(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    int e[4][4]={{x1,y1,x2,y2},{x2,y2,x3,y3},{x3,y3,x4,y4},{x4,y4,x1,y1}};\n    for(int i=0;i<4;i++){\n        int t=seg_type(e[i][0],e[i][1],e[i][2],e[i][3]);\n        int lid=line_id(t,e[i][0],e[i][1]);\n        int s=line_coord(t,e[i][0],e[i][1]);\n        int ee=line_coord(t,e[i][2],e[i][3]);\n        add_seg(t,lid,s,ee);\n    }\n}\n\nbool dot_on_perim(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    set<pair<int,int>> corners={{x1,y1},{x2,y2},{x3,y3},{x4,y4}};\n    auto chk=[&](int ax,int ay,int bx,int by){\n        int dx=bx-ax, dy=by-ay;\n        int g=gcd(abs(dx),abs(dy));\n        if(g==0)return false;\n        int sx=dx/g, sy=dy/g;\n        for(int i=1;i<g;i++){\n            int px=ax+i*sx, py=ay+i*sy;\n            if(!corners.count({px,py}) && has_dot[px][py]) return true;\n        }\n        return false;\n    };\n    return chk(x1,y1,x2,y2)||chk(x2,y2,x3,y3)||chk(x3,y3,x4,y4)||chk(x4,y4,x1,y1);\n}\n\nbool valid_rect(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    if(dot_on_perim(x1,y1,x2,y2,x3,y3,x4,y4))return false;\n    if(has_perim_overlap(x1,y1,x2,y2,x3,y3,x4,y4))return false;\n    return true;\n}\n\narray<int,8> find_best_rect(int ex, int ey) {\n    int best_cost = 1e9;\n    array<int,8> best_r = {-1};\n    \n    auto update = [&](array<int,8> r, int cost) {\n        if (cost < best_cost) {\n            best_cost = cost;\n            best_r = r;\n        }\n    };\n    \n    // Axis-aligned\n    for (int y1 : dots_x[ex]) {\n        for (int x1 : dots_y[ey]) {\n            if (has_dot[x1][y1]) {\n                if (valid_rect(ex, ey, ex, y1, x1, y1, x1, ey)) {\n                    int cost = abs(x1 - ex) + abs(y1 - ey);\n                    update({ex, ey, ex, y1, x1, y1, x1, ey}, cost);\n                }\n            }\n        }\n    }\n    \n    // 45 degree inclined (using u, v space)\n    int eu = ex + ey;\n    int ev = ex - ey;\n    \n    for (int v2 : dots_u[eu]) {\n        if ((eu + v2) % 2 != 0) continue;\n        int x3 = (eu + v2) / 2;\n        int y3 = (eu - v2) / 2;\n        if (x3 < 0 || x3 >= N || y3 < 0 || y3 >= N) continue;\n        \n        for (int u2 : dots_v[ev + N]) {\n            if ((u2 + ev) % 2 != 0) continue;\n            int x4 = (u2 + ev) / 2;\n            int y4 = (u2 - ev) / 2;\n            if (x4 < 0 || x4 >= N || y4 < 0 || y4 >= N) continue;\n            \n            int x2 = (u2 + v2) / 2;\n            int y2 = (u2 - v2) / 2;\n            if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N) continue;\n            \n            if (has_dot[x2][y2]) {\n                if (valid_rect(ex, ey, x3, y3, x2, y2, x4, y4)) {\n                    int cost = abs(u2 - eu) + abs(v2 - ev);\n                    update({ex, ey, x3, y3, x2, y2, x4, y4}, cost);\n                }\n            }\n        }\n    }\n    \n    return best_r;\n}\n\nvoid add_cand(int x, int y) {\n    if (x >= 0 && x < N && y >= 0 && y < N && !has_dot[x][y]) {\n        int idx = pt_idx[x][y];\n        if (idx != -1) {\n            candidates.insert(idx);\n        }\n    }\n}\n\nvoid add_candidates(int x, int y) {\n    int u = x + y;\n    int v = x - y;\n    \n    for (auto [x2, y2] : existing_dots) {\n        // Axis-aligned check\n        if (x != x2 && y != y2) {\n            bool c1 = (y2 >= 0 && y2 < N);\n            bool c2 = (x2 >= 0 && x2 < N);\n            if (c1 && c2 && has_dot[x][y2] && !has_dot[x2][y]) add_cand(x2, y);\n            if (c1 && c2 && has_dot[x2][y] && !has_dot[x][y2]) add_cand(x, y2);\n        }\n        \n        // 45 degree inclined check\n        int u2 = x2 + y2;\n        int v2 = x2 - y2;\n        \n        if (u != u2 && v != v2) {\n            if ((u + v2) % 2 == 0 && (u2 + v) % 2 == 0) {\n                int x3 = (u + v2) / 2;\n                int y3 = (u - v2) / 2;\n                int x4 = (u2 + v) / 2;\n                int y4 = (u2 - v) / 2;\n                \n                if (x3 >= 0 && x3 < N && y3 >= 0 && y3 < N &&\n                    x4 >= 0 && x4 < N && y4 >= 0 && y4 < N) {\n                    if (has_dot[x3][y3] && !has_dot[x4][y4]) add_cand(x4, y4);\n                    if (has_dot[x4][y4] && !has_dot[x3][y3]) add_cand(x3, y3);\n                }\n            }\n        }\n    }\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M;\n    has_dot.assign(N, vector<bool>(N, false));\n    \n    double c = (N - 1) / 2.0;\n    \n    for(int i=0;i<N;++i) pt_idx[i].resize(N, -1);\n    \n    vector<pair<int,int>> initial_dots(M);\n    for(int i=0;i<M;i++){\n        int x, y;\n        cin >> x >> y;\n        has_dot[x][y] = true;\n        dots_x[x].push_back(y);\n        dots_y[y].push_back(x);\n        int u = x + y;\n        int v = x - y;\n        dots_u[u].push_back(v);\n        dots_v[v + N].push_back(u);\n        initial_dots[i] = {x, y};\n    }\n    \n    for(int x=0;x<N;x++){\n        for(int y=0;y<N;y++){\n            if(!has_dot[x][y]){\n                double w = (x-c)*(x-c) + (y-c)*(y-c) + 1;\n                empty_pts_vec.push_back({-w, {x, y}});\n            }\n        }\n    }\n    \n    sort(empty_pts_vec.begin(), empty_pts_vec.end());\n    \n    for(size_t i=0; i<empty_pts_vec.size(); ++i) {\n        auto [w, p] = empty_pts_vec[i];\n        pt_idx[p.first][p.second] = i;\n    }\n    \n    for(auto [x, y] : initial_dots) {\n        existing_dots.push_back({x, y});\n    }\n    \n    for (auto [x, y] : initial_dots) {\n        add_candidates(x, y);\n    }\n    \n    while (!candidates.empty()) {\n        int best_idx = *candidates.begin();\n        auto [w, p] = empty_pts_vec[best_idx];\n        auto [x, y] = p;\n        \n        auto r = find_best_rect(x, y);\n        if (r[0] != -1) {\n            has_dot[x][y] = true;\n            dots_x[x].push_back(y);\n            dots_y[y].push_back(x);\n            int u = x + y;\n            int v = x - y;\n            dots_u[u].push_back(v);\n            dots_v[v + N].push_back(u);\n            existing_dots.push_back({x, y});\n            \n            add_perim(r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]);\n            ops.push_back(array<int,8>{r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]});\n            candidates.erase(best_idx);\n            pt_idx[x][y] = -1;\n            add_candidates(x, y);\n        } else {\n            candidates.erase(best_idx);\n        }\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for(auto& op : ops){\n        for(int i=0;i<8;i++){\n            cout << op[i] << (i<7?\" \":\"\\n\");\n        }\n    }\n    \n    return 0;\n}","ahc015":"#include <iostream>\n#include <cstring>\n#include <queue>\n#include <algorithm>\n#include <random>\n#include <vector>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nint flavors[101];\nmt19937 rng(42);\n\nvoid applyTilt(int g[N][N], int d) {\n    if (d == 0) { for (int c = 0; c < N; c++) { int w = 0; for (int r = 0; r < N; r++) if (g[r][c]) { if (w != r) { g[w][c] = g[r][c]; g[r][c] = 0; } w++; } } }\n    else if (d == 1) { for (int c = 0; c < N; c++) { int w = N-1; for (int r = N-1; r >= 0; r--) if (g[r][c]) { if (w != r) { g[w][c] = g[r][c]; g[r][c] = 0; } w--; } } }\n    else if (d == 2) { for (int r = 0; r < N; r++) { int w = 0; for (int c = 0; c < N; c++) if (g[r][c]) { if (w != c) { g[r][w] = g[r][c]; g[r][c] = 0; } w++; } } }\n    else { for (int r = 0; r < N; r++) { int w = N-1; for (int c = N-1; c >= 0; c--) if (g[r][c]) { if (w != c) { g[r][w] = g[r][c]; g[r][c] = 0; } w--; } } }\n}\n\nint getScore(int g[N][N]) {\n    bool vis[N][N] = {}; int s = 0;\n    constexpr int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};\n    int q[N*N], fr, bk;\n    for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) {\n        if (!vis[r][c] && g[r][c]) {\n            int fl = g[r][c], sz = 0; fr = 0; bk = 0;\n            q[bk++] = r*N+c; vis[r][c] = true;\n            while (fr < bk) { int id = q[fr++], cr = id/N, cc = id%N; sz++;\n                for (int d = 0; d < 4; d++) { 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]==fl) { vis[nr][nc]=true; q[bk++]=nr*N+nc; } } }\n            s += sz*sz;\n        }\n    }\n    return s;\n}\n\nint getAdj(int g[N][N]) {\n    int cnt = 0;\n    for (int r = 0; r < N; r++) for (int c = 0; c < N; c++)\n        if (g[r][c]) { if (r+1<N&&g[r+1][c]==g[r][c]) cnt++; if (c+1<N&&g[r][c+1]==g[r][c]) cnt++; }\n    return cnt;\n}\n\nlong long compute1Ply(int orig[N][N], int turn) {\n    if (turn >= 100) return getScore(orig);\n    int nf = flavors[turn + 1];\n    long long total = 0; int count = 0;\n    int g[N][N]; memcpy(g, orig, sizeof(g));\n    int saved[N][N];\n    for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) {\n        if (g[r][c] == 0) {\n            g[r][c] = nf;\n            int bestS = 0;\n            for (int d = 0; d < 4; d++) {\n                memcpy(saved, g, sizeof(saved));\n                applyTilt(g, d);\n                int s = getScore(g);\n                bestS = max(bestS, s);\n                memcpy(g, saved, sizeof(saved));\n            }\n            total += bestS;\n            g[r][c] = 0;\n            count++;\n        }\n    }\n    return count > 0 ? total / count : getScore(orig);\n}\n\nlong long runMC(int startT, int base[N][N]) {\n    int sim[N][N]; memcpy(sim, base, sizeof(sim));\n    for (int t = startT; t <= 100; t++) {\n        int er[100], ec[100], cnt = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (!sim[r][c]) { er[cnt] = r; ec[cnt] = c; cnt++; }\n        if (!cnt) break;\n        int idx = rng() % cnt;\n        sim[er[idx]][ec[idx]] = flavors[t];\n        int bestS = -1, bestD = 0, sv[N][N];\n        for (int d = 0; d < 4; d++) { memcpy(sv, sim, sizeof(sv)); applyTilt(sim, d); int s = getScore(sim); if (s > bestS) { bestS = s; bestD = d; } memcpy(sim, sv, sizeof(sv)); }\n        applyTilt(sim, bestD);\n    }\n    return getScore(sim);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    for (int i = 1; i <= 100; i++) cin >> flavors[i];\n    memset(grid, 0, sizeof(grid));\n    const char dirChars[] = \"FBLR\";\n    const int dirPrio[] = {4, 1, 2, 3};\n    \n    for (int t = 1; t <= 100; t++) {\n        int p; cin >> p;\n        int pos = 1;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (!grid[r][c]) { if (pos == p) { grid[r][c] = flavors[t]; goto placed; } pos++; }\n        placed:;\n        \n        int scores[4], adjs[4];\n        int saved[N][N]; memcpy(saved, grid, sizeof(grid));\n        for (int d = 0; d < 4; d++) {\n            applyTilt(grid, d);\n            scores[d] = getScore(grid);\n            adjs[d] = getAdj(grid);\n            memcpy(grid, saved, sizeof(grid));\n        }\n        \n        int maxScore = *max_element(scores, scores + 4);\n        vector<int> tied; for (int d = 0; d < 4; d++) if (scores[d] == maxScore) tied.push_back(d);\n        \n        int bestDir;\n        if (tied.size() == 1) {\n            bestDir = tied[0];\n        } else {\n            long long ply1[4] = {};\n            for (int d : tied) {\n                applyTilt(grid, d);\n                ply1[d] = compute1Ply(grid, t);\n                memcpy(grid, saved, sizeof(grid));\n            }\n            long long maxPly = -1; for (int d : tied) maxPly = max(maxPly, ply1[d]);\n            vector<int> tied2; for (int d : tied) if (ply1[d] == maxPly) tied2.push_back(d);\n            \n            if (tied2.size() == 1) {\n                bestDir = tied2[0];\n            } else {\n                int maxAdj = -1; for (int d : tied2) maxAdj = max(maxAdj, adjs[d]);\n                vector<int> tied3; for (int d : tied2) if (adjs[d] == maxAdj) tied3.push_back(d);\n                \n                if (tied3.size() == 1) {\n                    bestDir = tied3[0];\n                } else if (t >= 40) {\n                    int numSims = max(3, min(10, (100 - t) / 5));\n                    long long mcBest = -1; bestDir = tied3[0];\n                    for (int d : tied3) {\n                        int tmp[N][N]; memcpy(tmp, grid, sizeof(grid)); applyTilt(tmp, d);\n                        long long total = 0;\n                        for (int s = 0; s < numSims; s++) total += runMC(t + 1, tmp);\n                        if (total > mcBest) { mcBest = total; bestDir = d; }\n                    }\n                } else {\n                    bestDir = tied3[0];\n                    for (int d : tied3) if (dirPrio[d] < dirPrio[bestDir]) bestDir = d;\n                }\n            }\n        }\n        \n        applyTilt(grid, bestDir);\n        cout << dirChars[bestDir] << '\\n'; cout.flush();\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M; double eps;\n    cin >> M >> eps;\n    \n    // Phase 1: Find best N\n    double bestScore = -1e18;\n    int bestN = max(5, (int)ceil(log2(max(M,2))) + 2);\n    \n    vector<int> tryN;\n    for (int n = 4; n <= 15; n++) tryN.push_back(n);\n    for (int n = 18; n <= 40; n += 3) tryN.push_back(n);\n    for (int n = 45; n <= 80; n += 5) tryN.push_back(n);\n    for (int n = 90; n <= 100; n += 10) tryN.push_back(n);\n    \n    for (int Nt : tryN) {\n        double dVD = max(1.0, (Nt - 1.0) * eps * (1.0 - eps));\n        double dVE = max(1.0, (double)(Nt * (Nt - 1) / 2) * eps * (1.0 - eps));\n        \n        int NCt = min(4000, (Nt - 1 <= 20) ? (1 << (Nt - 1)) : 4000);\n        if (NCt < M) continue;\n        \n        vector<vector<double>> fps(NCt, vector<double>(Nt + 1));\n        for (int c = 0; c < NCt; ++c) {\n            auto& fp = fps[c];\n            vector<double> exp_deg(Nt, (Nt - 1.0) * eps);\n            int edges = 0;\n            int maxEt = Nt * (Nt - 1) / 2;\n            \n            if (Nt - 1 <= 13) {\n                for (int j = 1; j < Nt; ++j) {\n                    if ((c >> (j - 1)) & 1) {\n                        edges += j;\n                        for (int i = 0; i < j; ++i) exp_deg[i] += (1.0 - 2.0 * eps);\n                        exp_deg[j] += j * (1.0 - 2.0 * eps);\n                    }\n                }\n            } else {\n                uint64_t state = (uint64_t)c * 0x9e3779b97f4a7c15ULL + 12345;\n                for (int j = 1; j < Nt; ++j) {\n                    state = state * 6364136223846793005ULL + 1442695040888963407ULL;\n                    if ((state >> 33) & 1) {\n                        edges += j;\n                        for (int i = 0; i < j; ++i) exp_deg[i] += (1.0 - 2.0 * eps);\n                        exp_deg[j] += j * (1.0 - 2.0 * eps);\n                    }\n                }\n            }\n            sort(exp_deg.begin(), exp_deg.end());\n            fp[0] = edges * (1.0 - 2.0 * eps) + maxEt * eps;\n            for (int i = 0; i < Nt; ++i) fp[i + 1] = exp_deg[i];\n        }\n        \n        vector<bool> used(NCt, false);\n        vector<double> minD(NCt, 1e18);\n        used[0] = true;\n        for (int c = 1; c < NCt; ++c) {\n            double d = (fps[c][0] - fps[0][0]); d = d * d / dVE;\n            for (int i = 1; i <= Nt; ++i) { double df = fps[c][i] - fps[0][i]; d += df * df / dVD; }\n            minD[c] = d;\n        }\n        \n        double dMin = 1e18;\n        bool ok = true;\n        for (int k = 1; k < M; ++k) {\n            int best = -1; double bestD = -1;\n            for (int c = 0; c < NCt; ++c) if (!used[c] && minD[c] > bestD) { bestD = minD[c]; best = c; }\n            if (best < 0) { ok = false; break; }\n            used[best] = true; dMin = min(dMin, bestD);\n            for (int c = 0; c < NCt; ++c) {\n                if (used[c]) continue;\n                double d = (fps[c][0] - fps[best][0]); d = d * d / dVE;\n                for (int i = 1; i <= Nt; ++i) { double df = fps[c][i] - fps[best][i]; d += df * df / dVD; }\n                minD[c] = min(minD[c], d);\n            }\n        }\n        if (!ok || dMin <= 0) continue;\n        \n        double pErr = (eps < 0.005) ? 1e-15 : max(1e-15, min(0.5, (M - 1.0) * 0.5 * erfc(sqrt(dMin / 8.0))));\n        double estScore = pow(0.9, 100.0 * pErr) / Nt;\n        if (estScore > bestScore) { bestScore = estScore; bestN = Nt; }\n    }\n    \n    // Phase 2: Generate M graphs for chosen N\n    int N = bestN;\n    int maxE = N * (N - 1) / 2;\n    double dVD = max(1.0, (N - 1.0) * eps * (1.0 - eps));\n    double dVE = max(1.0, (double)maxE * eps * (1.0 - eps));\n    \n    int NC = min(4000, (N - 1 <= 13) ? (1 << (N - 1)) : 4000);\n    if (NC < M) NC = M;\n    \n    auto eidx = [&](int i, int j) -> int { if (i > j) swap(i, j); return i * (2 * N - i - 1) / 2 + (j - i - 1); };\n    \n    vector<vector<double>> fps(NC, vector<double>(N + 1));\n    for (int c = 0; c < NC; ++c) {\n        auto& fp = fps[c];\n        vector<double> exp_deg(N, (N - 1.0) * eps);\n        int edges = 0;\n        \n        if (N - 1 <= 13) {\n            for (int j = 1; j < N; ++j) {\n                if ((c >> (j - 1)) & 1) {\n                    edges += j;\n                    for (int i = 0; i < j; ++i) exp_deg[i] += (1.0 - 2.0 * eps);\n                    exp_deg[j] += j * (1.0 - 2.0 * eps);\n                }\n            }\n        } else {\n            uint64_t state = (uint64_t)c * 0x9e3779b97f4a7c15ULL + 12345;\n            for (int j = 1; j < N; ++j) {\n                state = state * 6364136223846793005ULL + 1442695040888963407ULL;\n                if ((state >> 33) & 1) {\n                    edges += j;\n                    for (int i = 0; i < j; ++i) exp_deg[i] += (1.0 - 2.0 * eps);\n                    exp_deg[j] += j * (1.0 - 2.0 * eps);\n                }\n            }\n        }\n        sort(exp_deg.begin(), exp_deg.end());\n        fp[0] = edges * (1.0 - 2.0 * eps) + maxE * eps;\n        for (int i = 0; i < N; ++i) fp[i + 1] = exp_deg[i];\n    }\n    \n    vector<int> sel;\n    vector<double> minD(NC, 1e18);\n    vector<bool> used(NC, false);\n    \n    sel.push_back(0); used[0] = true;\n    for (int c = 1; c < NC; ++c) {\n        double d = (fps[c][0] - fps[0][0]); d = d * d / dVE;\n        for (int i = 1; i <= N; ++i) { double df = fps[c][i] - fps[0][i]; d += df * df / dVD; }\n        minD[c] = d;\n    }\n    \n    for (int k = 1; k < M; ++k) {\n        int best = -1; double bestD = -1;\n        for (int c = 0; c < NC; ++c) if (!used[c] && minD[c] > bestD) { bestD = minD[c]; best = c; }\n        if (best < 0) break;\n        sel.push_back(best); used[best] = true;\n        for (int c = 0; c < NC; ++c) {\n            if (used[c]) continue;\n            double d = (fps[c][0] - fps[best][0]); d = d * d / dVE;\n            for (int i = 1; i <= N; ++i) { double df = fps[c][i] - fps[best][i]; d += df * df / dVD; }\n            minD[c] = min(minD[c], d);\n        }\n    }\n    while ((int)sel.size() < M) sel.push_back(0);\n    \n    cout << N << \"\\n\";\n    for (int k = 0; k < M; ++k) {\n        int c = sel[k];\n        string g(maxE, '0');\n        if (N - 1 <= 13) {\n            for (int j = 1; j < N; ++j) {\n                if ((c >> (j - 1)) & 1) {\n                    for (int i = 0; i < j; ++i) g[eidx(i, j)] = '1';\n                }\n            }\n        } else {\n            uint64_t state = (uint64_t)c * 0x9e3779b97f4a7c15ULL + 12345;\n            for (int j = 1; j < N; ++j) {\n                state = state * 6364136223846793005ULL + 1442695040888963407ULL;\n                if ((state >> 33) & 1) {\n                    for (int i = 0; i < j; ++i) g[eidx(i, j)] = '1';\n                }\n            }\n        }\n        cout << g << \"\\n\";\n    }\n    cout.flush();\n    \n    vector<vector<double>> gefp(M, vector<double>(N + 1));\n    for (int k = 0; k < M; ++k) gefp[k] = fps[sel[k]];\n    \n    for (int q = 0; q < 100; ++q) {\n        string H; cin >> H;\n        int hEdges = count(H.begin(), H.end(), '1');\n        vector<int> hd(N, 0);\n        for (int i = 0; i < N; ++i) for (int j = i + 1; j < N; ++j)\n            if (H[eidx(i, j)] == '1') { hd[i]++; hd[j]++; }\n        sort(hd.begin(), hd.end());\n        \n        int bestK = 0; double bestDist = 1e18;\n        for (int k = 0; k < M; ++k) {\n            double dist = (hEdges - gefp[k][0]); dist = dist * dist / dVE;\n            for (int i = 1; i <= N; ++i) { double diff = hd[i - 1] - gefp[k][i]; dist += diff * diff / dVD; }\n            if (dist < bestDist) { bestDist = dist; bestK = k; }\n        }\n        cout << bestK << \"\\n\"; cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\ntypedef pair<ll,int> pli;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,D,K; cin>>N>>M>>D>>K;\n    vector<int> u(M),v(M),w(M);\n    vector<vector<pair<int,int>>> adj(N);\n    for(int i=0;i<M;i++){cin>>u[i]>>v[i]>>w[i];u[i]--;v[i]--;adj[u[i]].push_back({i,v[i]});adj[v[i]].push_back({i,u[i]});}\n    vector<int> x(N),y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n\n    int S=min(N,100);\n    vector<double> betw(M,0);\n    for(int si=0;si<S;si++){\n        int s=(ll)si*N/S;\n        vector<ll> dist(N,LLONG_MAX);vector<int> pe(N,-1);\n        dist[s]=0;priority_queue<pli,vector<pli>,greater<pli>> pq;pq.push({0,s});\n        while(!pq.empty()){auto[d,nd]=pq.top();pq.pop();if(d>dist[nd])continue;for(auto[ei,nx]:adj[nd]){ll nd2=d+w[ei];if(nd2<dist[nx]){dist[nx]=nd2;pe[nx]=ei;pq.push({nd2,nx});}}}\n        vector<int> ss(N,1);vector<vector<int>> ch(N);\n        for(int t=0;t<N;t++){if(t==s||pe[t]==-1)continue;int o=(u[pe[t]]==t)?v[pe[t]]:u[pe[t]];ch[o].push_back(t);}\n        vector<int> ord={s};for(int i=0;i<(int)ord.size();i++)for(int c:ch[ord[i]])ord.push_back(c);\n        for(int i=(int)ord.size()-1;i>0;i--){int nd=ord[i];int o=(u[pe[nd]]==nd)?v[pe[nd]]:u[pe[nd]];ss[o]+=ss[nd];}\n        for(int t=0;t<N;t++){if(t==s||pe[t]==-1)continue;betw[pe[t]]+=ss[t];}\n    }\n\n    vector<vector<ll>> apsp(N,vector<ll>(N,LLONG_MAX));\n    for(int s=0;s<N;s++){apsp[s][s]=0;priority_queue<pli,vector<pli>,greater<pli>> pq;pq.push({0,s});\n    while(!pq.empty()){auto[d,nd]=pq.top();pq.pop();if(d>apsp[s][nd])continue;for(auto[ei,nx]:adj[nd]){ll nd2=d+w[ei];if(nd2<apsp[s][nx]){apsp[s][nx]=nd2;pq.push({nd2,nx});}}}}\n\n    vector<ll> det(M,0);\n    for(int ei=0;ei<M;ei++){ll best=LLONG_MAX;for(auto[ej,an]:adj[u[ei]]){if(ej==ei)continue;if(apsp[an][v[ei]]<LLONG_MAX)best=min(best,(ll)w[ej]+apsp[an][v[ei]]);}for(auto[ej,bn]:adj[v[ei]]){if(ej==ei)continue;if(apsp[bn][u[ei]]<LLONG_MAX)best=min(best,(ll)w[ej]+apsp[bn][u[ei]]);}if(best<LLONG_MAX)det[ei]=max(0LL,best-apsp[u[ei]][v[ei]]);}\n\n    vector<double> impact(M);\n    for(int i=0;i<M;i++) impact[i]=betw[i]*(double)det[i];\n\n    vector<vector<int>> conflicts(M);\n    vector<ll> dist(N);vector<int> pe(N);\n    for(int ei=0;ei<M;ei++){\n        fill(dist.begin(),dist.end(),LLONG_MAX);fill(pe.begin(),pe.end(),-1);\n        dist[u[ei]]=0;priority_queue<pli,vector<pli>,greater<pli>> pq;pq.push({0,u[ei]});\n        while(!pq.empty()){auto[d,nd]=pq.top();pq.pop();if(d>dist[nd])continue;for(auto[ej,nx]:adj[nd]){if(ej==ei)continue;ll nd2=d+w[ej];if(nd2<dist[nx]){dist[nx]=nd2;pe[nx]=ej;pq.push({nd2,nx});}}}\n        if(dist[v[ei]]<LLONG_MAX){int cur=v[ei];while(cur!=u[ei]&&pe[cur]!=-1){int e=pe[cur];conflicts[ei].push_back(e);int other=(u[e]==cur)?v[e]:u[e];cur=other;}}\n    }\n    for(int ei=0;ei<M;ei++)for(int ej:conflicts[ei])conflicts[ej].push_back(ei);\n    for(int i=0;i<N;i++)for(int j=0;j<(int)adj[i].size();j++)for(int k=j+1;k<(int)adj[i].size();k++){int ej=adj[i][j].first,ek=adj[i][k].first;conflicts[ej].push_back(ek);conflicts[ek].push_back(ej);}\n    for(int i=0;i<M;i++){sort(conflicts[i].begin(),conflicts[i].end());conflicts[i].erase(unique(conflicts[i].begin(),conflicts[i].end()),conflicts[i].end());}\n\n    vector<int> order(M);iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),[&](int a,int b){return impact[a]>impact[b];});\n\n    vector<int> r(M,-1),dc(D,0);vector<double> day_imp(D,0);\n    for(int ei:order){\n        double bs=1e18;int bd=-1;\n        for(int d=0;d<D;d++){if(dc[d]>=K)continue;double sc=0;for(int ej:conflicts[ei])if(r[ej]==d)sc+=impact[ei]*impact[ej];sc+=day_imp[d]*1e-4;if(sc<bs){bs=sc;bd=d;}}\n        if(bd==-1)for(int d=0;d<D;d++)if(dc[d]<K&&(bd==-1||dc[d]<dc[bd]))bd=d;\n        r[ei]=bd;dc[bd]++;day_imp[bd]+=impact[ei];\n    }\n\n    auto t0=chrono::high_resolution_clock::now();mt19937 rng(42);\n    while(true){auto now=chrono::high_resolution_clock::now();if(chrono::duration<double>(now-t0).count()>5.0)break;\n    int ei=rng()%M;int od=r[ei];double cs=0;for(int ej:conflicts[ei])if(r[ej]==od)cs+=impact[ei]*impact[ej];\n    int bd=-1;double bi=0;for(int d=0;d<D;d++){if(d==od||dc[d]>=K)continue;double ns=0;for(int ej:conflicts[ei])if(r[ej]==d)ns+=impact[ei]*impact[ej];double imp=cs-ns+((day_imp[od]-impact[ei])-(day_imp[d]+impact[ei]))*1e-4;if(imp>bi){bi=imp;bd=d;}}\n    if(bd!=-1){r[ei]=bd;dc[od]--;dc[bd]++;day_imp[od]-=impact[ei];day_imp[bd]+=impact[ei];}}\n\n    for(int i=0;i<M;i++)cout<<r[i]+1<<\" \\n\"[i==M-1];\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <tuple>\n#include <climits>\n#include <chrono>\n#include <set>\n#include <map>\nusing namespace std;\nint D;\nusing Point=tuple<int,int,int>;\nusing Array3D=vector<vector<vector<int>>>;\n\nchrono::high_resolution_clock::time_point start_time;\n\nvector<string> readSil(){vector<string>s(D);for(int i=0;i<D;i++)cin>>s[i];return s;}\nArray3D buildMF(const vector<string>&f,const vector<string>&r){Array3D b(D,vector<vector<int>>(D,vector<int>(D,0)));for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)if(f[z][x]=='1'&&r[z][y]=='1')b[x][y][z]=1;return b;}\n\nvector<vector<Point>> findComp(const Array3D&b){\n    Array3D vis(D,vector<vector<int>>(D,vector<int>(D,0)));vector<vector<Point>>cs;\n    const int dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};\n    for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n        if(b[x][y][z]&&!vis[x][y][z]){vector<Point>c;queue<Point>q;q.push({x,y,z});vis[x][y][z]=1;\n            while(!q.empty()){auto[cx,cy,cz]=q.front();q.pop();c.push_back({cx,cy,cz});\n                for(int d=0;d<6;d++){int nx=cx+dx[d],ny=cy+dy[d],nz=cz+dz[d];\n                    if(0<=nx&&nx<D&&0<=ny&&ny<D&&0<=nz&&nz<D&&b[nx][ny][nz]&&!vis[nx][ny][nz]){vis[nx][ny][nz]=1;q.push({nx,ny,nz});}}}\n            cs.push_back(move(c));}}\n    return cs;\n}\n\nvector<vector<vector<int>>> genRots(){\n    vector<vector<vector<int>>>rots;int B[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};\n    for(int i=0;i<6;i++)for(int j=0;j<6;j++){if(i/2==j/2)continue;int cr[3];\n        cr[0]=B[i][1]*B[j][2]-B[i][2]*B[j][1];cr[1]=B[i][2]*B[j][0]-B[i][0]*B[j][2];cr[2]=B[i][0]*B[j][1]-B[i][1]*B[j][0];\n        int dt=B[i][0]*(B[j][1]*cr[2]-B[j][2]*cr[1])-B[i][1]*(B[j][0]*cr[2]-B[j][2]*cr[0])+B[i][2]*(B[j][0]*cr[1]-B[j][1]*cr[0]);\n        if(dt!=1)continue;rots.push_back({{B[i][0],B[i][1],B[i][2]},{B[j][0],B[j][1],B[j][2]},{cr[0],cr[1],cr[2]}});}\n    return rots;\n}\n\nPoint appR(const vector<vector<int>>&M,const Point&p){auto[x,y,z]=p;return{M[0][0]*x+M[0][1]*y+M[0][2]*z,M[1][0]*x+M[1][1]*y+M[1][2]*z,M[2][0]*x+M[2][1]*y+M[2][2]*z};}\n\nvector<Point>canon(const vector<Point>&comp,const vector<vector<vector<int>>>&rots){vector<Point>best;for(auto&M:rots){vector<Point>r;for(auto&p:comp)r.push_back(appR(M,p));int mX=INT_MAX,mY=INT_MAX,mZ=INT_MAX;for(auto&[x,y,z]:r){mX=min(mX,x);mY=min(mY,y);mZ=min(mZ,z);}for(auto&[x,y,z]:r){x-=mX;y-=mY;z-=mZ;}sort(r.begin(),r.end());if(best.empty()||r<best)best=r;}return best;}\n\nvector<vector<Point>> findSubComp(const vector<Point>&vox){set<Point>vs(vox.begin(),vox.end());map<Point,int>vis;vector<vector<Point>>cs;const int dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};for(auto&p:vox){if(vis.count(p))continue;vector<Point>c;queue<Point>q;q.push(p);vis[p]=1;while(!q.empty()){auto[cx,cy,cz]=q.front();q.pop();c.push_back({cx,cy,cz});for(int d=0;d<6;d++){Point np={cx+dx[d],cy+dy[d],cz+dz[d]};if(vs.count(np)&&!vis.count(np)){vis[np]=1;q.push(np);}}}cs.push_back(move(c));}return cs;}\n\nvoid doPartial(Array3D& a0, Array3D& a1, const Array3D& b0, const Array3D& b1, const vector<vector<vector<int>>>& rots, int& nextId) {\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 5000) break;\n        \n        Array3D U0(D, vector<vector<int>>(D, vector<int>(D, 0)));\n        Array3D U1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n        vector<Point> P1;\n        for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n            if (b0[x][y][z] && !a0[x][y][z]) { U0[x][y][z] = 1; }\n            if (b1[x][y][z] && !a1[x][y][z]) { U1[x][y][z] = 1; P1.push_back({x,y,z}); }\n        }\n        if (P1.empty()) break;\n        \n        auto comps0 = findComp(U0);\n        sort(comps0.begin(), comps0.end(), [](auto& a, auto& b){return a.size() > b.size();});\n        \n        bool found_match = false;\n        for (auto& comp : comps0) {\n            if (comp.size() < 2) break;\n            int bestO = 1, bestRi = -1, bestTx = 0, bestTy = 0, bestTz = 0;\n            const int OFF = 15, S = 30;\n            vector<int> tc(S*S*S);\n            \n            for (int ri = 0; ri < 24; ri++) {\n                vector<Point> rot;\n                for (auto& p : comp) rot.push_back(appR(rots[ri], p));\n                int mX=INT_MAX, mY=INT_MAX, mZ=INT_MAX;\n                for (auto& [x,y,z] : rot) { mX=min(mX,x); mY=min(mY,y); mZ=min(mZ,z); }\n                for (auto& [x,y,z] : rot) { x-=mX; y-=mY; z-=mZ; }\n                \n                fill(tc.begin(), tc.end(), 0);\n                for (auto& [sx,sy,sz] : rot) \n                    for (auto& [px,py,pz] : P1) {\n                        int kx = px-sx + OFF, ky = py-sy + OFF, kz = pz-sz + OFF;\n                        tc[kx + ky*S + kz*S*S]++;\n                    }\n                for (int kz=0; kz<S; kz++) for (int ky=0; ky<S; ky++) for (int kx=0; kx<S; kx++) {\n                    int cnt = tc[kx + ky*S + kz*S*S];\n                    if (cnt > bestO) { bestO = cnt; bestRi = ri; bestTx = kx-OFF; bestTy = ky-OFF; bestTz = kz-OFF; }\n                }\n                if (bestO == comp.size()) break;\n            }\n            \n            if (bestRi != -1) {\n                vector<Point> rot;\n                for (auto& p : comp) rot.push_back(appR(rots[bestRi], p));\n                int mX=INT_MAX, mY=INT_MAX, mZ=INT_MAX;\n                for (auto& [x,y,z] : rot) { mX=min(mX,x); mY=min(mY,y); mZ=min(mZ,z); }\n                for (auto& [x,y,z] : rot) { x-=mX; y-=mY; z-=mZ; }\n                \n                vector<Point> so, to;\n                for (int i=0; i<(int)comp.size(); i++) {\n                    auto [rx,ry,rz] = rot[i];\n                    int tx=rx+bestTx, ty=ry+bestTy, tz=rz+bestTz;\n                    if (0<=tx&&tx<D && 0<=ty&&ty<D && 0<=tz&&tz<D && U1[tx][ty][tz]) {\n                        so.push_back(comp[i]); to.push_back({tx,ty,tz});\n                    }\n                }\n                auto scs = findSubComp(so);\n                map<Point, int> s2i; for (int i=0; i<(int)so.size(); i++) s2i[so[i]] = i;\n                \n                for (auto& sc : scs) {\n                    if (sc.size() < 2) continue;\n                    found_match = true;\n                    int id = nextId++;\n                    for (auto& p : sc) {\n                        int i = s2i[p];\n                        auto [sx,sy,sz] = so[i]; auto [tx,ty,tz] = to[i];\n                        a0[sx][sy][sz] = id; a1[tx][ty][tz] = id;\n                    }\n                }\n                if (found_match) break;\n            }\n        }\n        if (!found_match) break;\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    start_time = chrono::high_resolution_clock::now();\n    cin >> D;\n    vector<vector<string>> f(2), r(2);\n    for (int i = 0; i < 2; i++) { f[i] = readSil(); r[i] = readSil(); }\n    \n    auto rots = genRots();\n    auto b0 = buildMF(f[0], r[0]), b1 = buildMF(f[1], r[1]);\n    Array3D a0(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    Array3D a1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    int nid = 1;\n    \n    auto c0 = findComp(b0), c1 = findComp(b1);\n    int n0 = c0.size(), n1 = c1.size();\n    map<vector<Point>, vector<int>> cm1;\n    for (int j=0; j<n1; j++) cm1[canon(c1[j], rots)].push_back(j);\n    \n    vector<int> o0(n0); for (int i=0; i<n0; i++) o0[i] = i;\n    sort(o0.begin(), o0.end(), [&](int a, int b){return c0[a].size() > c0[b].size();});\n    \n    vector<bool> u1(n1, false);\n    for (int i : o0) {\n        auto cn = canon(c0[i], rots);\n        auto it = cm1.find(cn);\n        if (it != cm1.end()) for (int j : it->second) if (!u1[j]) {\n            int id = nid++;\n            for (auto [x,y,z] : c0[i]) a0[x][y][z] = id;\n            for (auto [x,y,z] : c1[j]) a1[x][y][z] = id;\n            u1[j] = true; break;\n        }\n    }\n    \n    doPartial(a0, a1, b0, b1, rots, nid);\n    doPartial(a1, a0, b1, b0, rots, nid);\n    \n    Array3D U0(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    Array3D U1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (b0[x][y][z] && !a0[x][y][z]) U0[x][y][z] = 1;\n        if (b1[x][y][z] && !a1[x][y][z]) U1[x][y][z] = 1;\n    }\n    Array3D isct(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++)\n        if(U0[x][y][z] && U1[x][y][z]) isct[x][y][z] = 1;\n    for (auto& c : findComp(isct)) {\n        int id = nid++;\n        for (auto [x,y,z] : c) { a0[x][y][z] = id; a1[x][y][z] = id; U0[x][y][z] = 0; U1[x][y][z] = 0; }\n    }\n    \n    for (auto& c : findComp(U0)) { int id = nid++; for (auto [x,y,z] : c) a0[x][y][z] = id; }\n    for (auto& c : findComp(U1)) { int id = nid++; for (auto [x,y,z] : c) a1[x][y][z] = id; }\n    \n    map<int, vector<Point>> blocks0, blocks1;\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (a0[x][y][z]) blocks0[a0[x][y][z]].push_back({x,y,z});\n        if (a1[x][y][z]) blocks1[a1[x][y][z]].push_back({x,y,z});\n    }\n    \n    set<int> ids_in_1;\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) if (a1[x][y][z]) ids_in_1.insert(a1[x][y][z]);\n    \n    set<int> shared_ids;\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) if (a0[x][y][z] && ids_in_1.count(a0[x][y][z])) shared_ids.insert(a0[x][y][z]);\n    \n    map<vector<Point>, vector<int>> canon_unshared1;\n    for (auto& [id, pts] : blocks1) {\n        if (!shared_ids.count(id)) {\n            auto cn = canon(pts, rots);\n            canon_unshared1[cn].push_back(id);\n        }\n    }\n    \n    for (auto& [id0, pts0] : blocks0) {\n        if (!shared_ids.count(id0)) {\n            auto cn = canon(pts0, rots);\n            auto it = canon_unshared1.find(cn);\n            if (it != canon_unshared1.end()) {\n                int id1 = it->second.back();\n                it->second.pop_back();\n                if (it->second.empty()) canon_unshared1.erase(it);\n                for (auto [x,y,z] : blocks1[id1]) a1[x][y][z] = id0;\n            }\n        }\n    }\n    \n    map<int, int> id_remap;\n    int next_remap_id = 1;\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (a0[x][y][z] && !id_remap.count(a0[x][y][z])) id_remap[a0[x][y][z]] = next_remap_id++;\n    }\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (a1[x][y][z] && !id_remap.count(a1[x][y][z])) id_remap[a1[x][y][z]] = next_remap_id++;\n    }\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (a0[x][y][z]) a0[x][y][z] = id_remap[a0[x][y][z]];\n        if (a1[x][y][z]) a1[x][y][z] = id_remap[a1[x][y][z]];\n    }\n    \n    cout << next_remap_id - 1 << \"\\n\";\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) { if(x||y||z) cout<<\" \"; cout<<a0[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++) { if(x||y||z) cout<<\" \"; cout<<a1[x][y][z]; }\n    cout << \"\\n\";\n    return 0;\n}","ahc020":"#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, K;\n    cin >> N >> M >> K;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<vector<pair<int, int>>> adj(N);\n    vector<int> eu(M), ev(M), ew(M);\n    for (int j = 0; j < M; j++) {\n        cin >> eu[j] >> ev[j] >> ew[j];\n        eu[j]--; ev[j]--;\n        adj[eu[j]].push_back({ev[j], j});\n        adj[ev[j]].push_back({eu[j], j});\n    }\n    \n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    const int PMAX = 5000;\n    const long long PMAXSQ = (long long)PMAX * PMAX;\n    \n    vector<vector<long long>> rsq(K, vector<long long>(N));\n    for (int k = 0; k < K; k++)\n        for (int i = 0; i < N; i++) {\n            long long dx = a[k] - x[i], dy = b[k] - y[i];\n            rsq[k][i] = dx * dx + dy * dy;\n        }\n    \n    vector<vector<int>> clo(K);\n    for (int k = 0; k < K; k++) {\n        vector<pair<long long, int>> v;\n        for (int i = 0; i < N; i++)\n            if (rsq[k][i] <= PMAXSQ) v.push_back({rsq[k][i], i});\n        sort(v.begin(), v.end());\n        for (int j = 0; j < min(25, (int)v.size()); j++)\n            clo[k].push_back(v[j].second);\n    }\n    \n    // Dijkstra from vertex 0\n    vector<long long> sp(N, LLONG_MAX);\n    vector<int> par(N, -1), pe(N, -1);\n    sp[0] = 0;\n    priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n    pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > sp[u]) continue;\n        for (auto [v, e] : adj[u])\n            if (sp[u] + ew[e] < sp[v]) {\n                sp[v] = sp[u] + ew[e];\n                par[v] = u; pe[v] = e;\n                pq.push({sp[v], v});\n            }\n    }\n    \n    vector<vector<int>> pth(N);\n    for (int i = 1; i < N; i++) {\n        int c = i;\n        while (c) { pth[i].push_back(pe[c]); c = par[c]; }\n    }\n    \n    auto calcP = [](long long sq) -> int {\n        if (sq <= 0) return 0;\n        int p = max(1, (int)ceil(sqrt((double)sq) - 1e-9));\n        while ((long long)p * p < sq) p++;\n        return min(p, 5000);\n    };\n    \n    // State with swap-and-pop vectors\n    vector<int> asgn(K);\n    vector<vector<int>> vr(N);\n    vector<long long> vmx(N, 0);\n    for (int k = 0; k < K; k++) {\n        asgn[k] = clo[k][0];\n        vr[asgn[k]].push_back(k);\n        vmx[asgn[k]] = max(vmx[asgn[k]], rsq[k][asgn[k]]);\n    }\n    \n    vector<int> P(N);\n    long long pcost = 0;\n    for (int i = 0; i < N; i++) { P[i] = calcP(vmx[i]); pcost += (long long)P[i] * P[i]; }\n    \n    vector<int> eref(M, 0);\n    long long ecost = 0;\n    for (int i = 1; i < N; i++)\n        if (P[i] > 0)\n            for (int e : pth[i]) { if (!eref[e]) ecost += ew[e]; eref[e]++; }\n    \n    long long cost = pcost + ecost;\n    vector<int> best_P = P, best_asgn = asgn;\n    long long best_cost = cost;\n    \n    mt19937 rng(42);\n    uniform_real_distribution<> unif(0.0, 1.0);\n    auto t0 = chrono::high_resolution_clock::now();\n    \n    // SA Phase 1: resident reassignment with SPT cost\n    while (true) {\n        double el = chrono::duration<double>(chrono::high_resolution_clock::now() - t0).count();\n        if (el > 1.6) break;\n        double temp = 8e6 * pow(1e-5, el / 1.6);\n        \n        int k = rng() % K;\n        int ov = asgn[k];\n        int nv = clo[k][rng() % clo[k].size()];\n        if (nv == ov) continue;\n        \n        long long nmx_ov = vmx[ov];\n        if (rsq[k][ov] == vmx[ov]) {\n            nmx_ov = 0;\n            for (int r : vr[ov]) if (r != k) nmx_ov = max(nmx_ov, rsq[r][ov]);\n        }\n        int nPov = calcP(nmx_ov);\n        long long nmx_nv = max(vmx[nv], rsq[k][nv]);\n        int nPnv = calcP(nmx_nv);\n        \n        long long dpc = (long long)nPov * nPov - (long long)P[ov] * P[ov]\n                      + (long long)nPnv * nPnv - (long long)P[nv] * P[nv];\n        \n        if (P[ov] > 0 && nPov == 0)\n            for (int e : pth[ov]) { eref[e]--; if (!eref[e]) ecost -= ew[e]; }\n        if (P[nv] == 0 && nPnv > 0)\n            for (int e : pth[nv]) { if (!eref[e]) ecost += ew[e]; eref[e]++; }\n        \n        long long nc = pcost + dpc + ecost;\n        if (nc < cost || unif(rng) < exp(-(double)(nc - cost) / temp)) {\n            // Swap-and-pop removal from vr[ov]\n            auto it = find(vr[ov].begin(), vr[ov].end(), k);\n            *it = vr[ov].back(); vr[ov].pop_back();\n            vr[nv].push_back(k);\n            vmx[ov] = nmx_ov; vmx[nv] = nmx_nv;\n            P[ov] = nPov; P[nv] = nPnv;\n            pcost += dpc; asgn[k] = nv; cost = nc;\n            if (cost < best_cost) {\n                best_cost = cost; best_P = P; best_asgn = asgn;\n            }\n        } else {\n            if (P[nv] == 0 && nPnv > 0)\n                for (int e : pth[nv]) { eref[e]--; if (!eref[e]) ecost -= ew[e]; }\n            if (P[ov] > 0 && nPov == 0)\n                for (int e : pth[ov]) { if (!eref[e]) ecost += ew[e]; eref[e]++; }\n        }\n    }\n    \n    // Restore best state\n    asgn = best_asgn;\n    for (int i = 0; i < N; i++) vr[i].clear();\n    fill(vmx.begin(), vmx.end(), 0);\n    for (int k = 0; k < K; k++) {\n        vr[asgn[k]].push_back(k);\n        vmx[asgn[k]] = max(vmx[asgn[k]], rsq[k][asgn[k]]);\n    }\n    for (int i = 0; i < N; i++) P[i] = calcP(vmx[i]);\n    pcost = 0; for (int i = 0; i < N; i++) pcost += (long long)P[i] * P[i];\n    \n    // Limited vertex deactivation with SPH cost\n    auto compute_sph = [&](const vector<int>& P_arr) -> pair<long long, vector<int>> {\n        vector<int> act;\n        for (int i = 0; i < N; i++) if (P_arr[i] > 0) act.push_back(i);\n        if (act.empty()) return {0, vector<int>(M, 0)};\n        \n        vector<int> B(M, 0);\n        vector<bool> in_tree(N, false);\n        in_tree[0] = true;\n        set<int> rem(act.begin(), act.end());\n        rem.erase(0);\n        long long ec = 0;\n        \n        while (!rem.empty()) {\n            vector<long long> d(N, LLONG_MAX);\n            vector<int> prev(N, -1), preve(N, -1);\n            priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq2;\n            for (int v = 0; v < N; v++) if (in_tree[v]) { d[v] = 0; pq2.push({0, v}); }\n            while (!pq2.empty()) {\n                auto [dd, u] = pq2.top(); pq2.pop();\n                if (dd > d[u]) continue;\n                for (auto [v, e] : adj[u])\n                    if (d[u] + ew[e] < d[v]) {\n                        d[v] = d[u] + ew[e];\n                        prev[v] = u; preve[v] = e;\n                        pq2.push({d[v], v});\n                    }\n            }\n            long long bd = LLONG_MAX; int bt = -1;\n            for (int t : rem) if (d[t] < bd) { bd = d[t]; bt = t; }\n            int v = bt;\n            while (v != -1 && !in_tree[v]) {\n                B[preve[v]] = 1;\n                in_tree[v] = true;\n                v = prev[v];\n            }\n            ec += bd;\n            rem.erase(bt);\n        }\n        return {ec, B};\n    };\n    \n    // Try deactivating each non-zero vertex once\n    for (int pass = 0; pass < 2; pass++) {\n        bool improved = false;\n        for (int v = 1; v < N; v++) {\n            if (P[v] == 0 || vr[v].empty()) continue;\n            \n            // Find reassignment for each resident of v\n            vector<pair<int, int>> reassigns;\n            bool feasible = true;\n            for (int k : vr[v]) {\n                int best_nv = -1;\n                for (int nv : clo[k]) {\n                    if (nv != v && P[nv] > 0) { best_nv = nv; break; }\n                }\n                if (best_nv == -1) { feasible = false; break; }\n                reassigns.push_back({k, best_nv});\n            }\n            if (!feasible) continue;\n            \n            // Compute new P\n            vector<int> nP = P;\n            vector<long long> nvmx = vmx;\n            nP[v] = 0; nvmx[v] = 0;\n            for (auto [k, nv] : reassigns)\n                nvmx[nv] = max(nvmx[nv], rsq[k][nv]);\n            for (int i = 0; i < N; i++) nP[i] = calcP(nvmx[i]);\n            \n            long long npc = 0;\n            for (int i = 0; i < N; i++) npc += (long long)nP[i] * nP[i];\n            \n            auto [nec, nB] = compute_sph(nP);\n            \n            long long old_total;\n            { auto [oec, oB] = compute_sph(P); old_total = pcost + oec; }\n            \n            if (npc + nec < old_total) {\n                for (auto [k, nv] : reassigns) {\n                    auto it = find(vr[asgn[k]].begin(), vr[asgn[k]].end(), k);\n                    *it = vr[asgn[k]].back(); vr[asgn[k]].pop_back();\n                    asgn[k] = nv;\n                    vr[nv].push_back(k);\n                }\n                vr[v].clear();\n                P = nP; vmx = nvmx; pcost = npc;\n                improved = true;\n            }\n        }\n        if (!improved) break;\n    }\n    \n    // Final SPH tree\n    auto [final_ec, final_B] = compute_sph(P);\n    \n    for (int i = 0; i < N; i++) cout << P[i] << \" \\n\"[i == N - 1];\n    for (int j = 0; j < M; j++) cout << final_B[j] << \" \\n\"[j == M - 1];\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint grid[N][N];\nvector<array<int, 4>> swaps;\n\nint main() {\n    ios_base::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 >> grid[x][y];\n    \n    auto siftDown = [&](int x, int y) {\n        while (x < N - 1) {\n            int lv = grid[x+1][y], rv = grid[x+1][y+1], cv = grid[x][y];\n            if (cv <= lv && cv <= rv) break;\n            if (lv <= rv) {\n                swap(grid[x][y], grid[x+1][y]);\n                swaps.push_back({x, y, x+1, y});\n                x++;\n            } else {\n                swap(grid[x][y], grid[x+1][y+1]);\n                swaps.push_back({x, y, x+1, y+1});\n                x++; y++;\n            }\n            if (swaps.size() >= 9999) return;\n        }\n    };\n    \n    // Heapify: bottom to top, full sift-down\n    for (int x = N - 2; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            siftDown(x, y);\n            if (swaps.size() >= 9999) goto done;\n        }\n    }\n    \n    // Iteratively fix remaining violations\n    // (caused by triangular grid's dual-parent structure)\n    for (int iter = 0; iter < 500; iter++) {\n        bool any = false;\n        for (int x = N - 2; x >= 0; x--) {\n            for (int y = 0; y <= x; y++) {\n                if (grid[x][y] > grid[x+1][y] || grid[x][y] > grid[x+1][y+1]) {\n                    any = true;\n                    // One-step fix: swap parent with smaller child\n                    if (grid[x+1][y] <= grid[x+1][y+1]) {\n                        swap(grid[x][y], grid[x+1][y]);\n                        swaps.push_back({x, y, x+1, y});\n                    } else {\n                        swap(grid[x][y], grid[x+1][y+1]);\n                        swaps.push_back({x, y, x+1, y+1});\n                    }\n                    if (swaps.size() >= 9999) goto done;\n                }\n            }\n        }\n        if (!any) break;\n    }\n    \ndone:\n    cout << swaps.size() << \"\\n\";\n    for (auto& s : swaps)\n        cout << s[0] << \" \" << s[1] << \" \" << s[2] << \" \" << s[3] << \"\\n\";\n    \n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <set>\n\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    vector<vector<bool>> is_obstacle(D, vector<bool>(D, false));\n    for (int i = 0; i < N; i++) {\n        int ri, rj;\n        cin >> ri >> rj;\n        is_obstacle[ri][rj] = true;\n    }\n    \n    int entrance_i = 0, entrance_j = (D - 1) / 2;\n    \n    // Precompute distances from entrance\n    vector<vector<int>> dist(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    q.push({entrance_i, entrance_j});\n    dist[entrance_i][entrance_j] = 0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    \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 (ni >= 0 && ni < D && nj >= 0 && nj < D && dist[ni][nj] == -1 && !is_obstacle[ni][nj]) {\n                dist[ni][nj] = dist[i][j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    int M = 0;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (!(i == entrance_i && j == entrance_j) && !is_obstacle[i][j])\n                M++;\n                \n    struct Cell {\n        int i, j;\n        int dist;\n        int current_degree;\n        bool removed;\n        int rank;\n    };\n    \n    vector<Cell> C(M);\n    vector<vector<int>> cell_index(D, vector<int>(D, -1));\n    \n    int idx = 0;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (!(i == entrance_i && j == entrance_j) && !is_obstacle[i][j]) {\n                C[idx].i = i;\n                C[idx].j = j;\n                C[idx].dist = dist[i][j];\n                C[idx].removed = false;\n                cell_index[i][j] = idx;\n                idx++;\n            }\n        }\n    }\n    \n    // Calculate internal degrees (only counting valid container neighbors)\n    for (int k = 0; k < M; k++) {\n        C[k].current_degree = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = C[k].i + di[d], nj = C[k].j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && cell_index[ni][nj] != -1) {\n                C[k].current_degree++;\n            }\n        }\n    }\n    \n    // Peeling algorithm to assign topological removal ranks\n    priority_queue<tuple<int, int, int, int>, vector<tuple<int, int, int, int>>, greater<tuple<int, int, int, int>>> pq;\n    \n    for (int k = 0; k < M; k++) {\n        if (C[k].current_degree <= 1) {\n            pq.push({C[k].dist, C[k].i, C[k].j, k});\n        }\n    }\n    \n    int current_rank = 0;\n    int removed_count = 0;\n    \n    while (removed_count < M) {\n        if (pq.empty()) {\n            // Break cycle by picking the remaining cell closest to the entrance\n            int best_k = -1;\n            for (int k = 0; k < M; k++) {\n                if (!C[k].removed) {\n                    if (best_k == -1 || tie(C[k].dist, C[k].i, C[k].j) < tie(C[best_k].dist, C[best_k].i, C[best_k].j)) {\n                        best_k = k;\n                    }\n                }\n            }\n            pq.push({C[best_k].dist, C[best_k].i, C[best_k].j, best_k});\n        }\n        \n        auto [d, i, j, k] = pq.top();\n        pq.pop();\n        \n        if (C[k].removed) continue;\n        \n        C[k].rank = current_rank++;\n        C[k].removed = true;\n        removed_count++;\n        \n        for (int dd = 0; dd < 4; dd++) {\n            int ni = C[k].i + di[dd], nj = C[k].j + dj[dd];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && cell_index[ni][nj] != -1) {\n                int nk = cell_index[ni][nj];\n                if (!C[nk].removed) {\n                    C[nk].current_degree--;\n                    if (C[nk].current_degree <= 1) {\n                        pq.push({C[nk].dist, C[nk].i, C[nk].j, nk});\n                    }\n                }\n            }\n        }\n    }\n    \n    // Placement phase\n    set<pair<int, int>> available_cells; // (Rank, index in C)\n    for (int k = 0; k < M; k++) {\n        available_cells.insert({C[k].rank, k});\n    }\n    \n    vector<vector<int>> container_at(D, vector<int>(D, -1));\n    vector<vector<bool>> is_empty(D, vector<bool>(D, true));\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (is_obstacle[i][j]) is_empty[i][j] = false;\n    \n    auto is_safe = [&](int exclude_i, int exclude_j) {\n        vector<vector<bool>> reachable(D, vector<bool>(D, false));\n        queue<pair<int, int>> bfs_q;\n        bfs_q.push({entrance_i, entrance_j});\n        reachable[entrance_i][entrance_j] = true;\n        int visited_count = 1; // includes entrance\n        \n        while (!bfs_q.empty()) {\n            auto [i, j] = bfs_q.front(); bfs_q.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D && !reachable[ni][nj] && is_empty[ni][nj] && !(ni == exclude_i && nj == exclude_j)) {\n                    reachable[ni][nj] = true;\n                    bfs_q.push({ni, nj});\n                    visited_count++;\n                }\n            }\n        }\n        return visited_count == (int)available_cells.size();\n    };\n    \n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        \n        vector<int> safe_indices;\n        for (auto& p : available_cells) {\n            int k = p.second;\n            if (is_safe(C[k].i, C[k].j)) {\n                safe_indices.push_back(k);\n            }\n        }\n        \n        int best_k = -1;\n        int best_diff = M + 1;\n        \n        auto it = lower_bound(safe_indices.begin(), safe_indices.end(), t, [&](int k, int val) {\n            return C[k].rank < val;\n        });\n        \n        if (it != safe_indices.end()) {\n            int diff = abs(C[*it].rank - t);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_k = *it;\n            } else if (diff == best_diff && C[*it].rank > C[best_k].rank) {\n                best_k = *it;\n            }\n        }\n        if (it != safe_indices.begin()) {\n            --it;\n            int diff = abs(C[*it].rank - t);\n            if (diff < best_diff) {\n                best_diff = diff;\n                best_k = *it;\n            } else if (diff == best_diff && C[*it].rank > C[best_k].rank) {\n                best_k = *it;\n            }\n        }\n        \n        available_cells.erase({C[best_k].rank, best_k});\n        cout << C[best_k].i << \" \" << C[best_k].j << endl;\n        container_at[C[best_k].i][C[best_k].j] = t;\n        is_empty[C[best_k].i][C[best_k].j] = false;\n    }\n    \n    // Transport phase: Greedily remove the smallest numbered accessible container\n    for (int iter = 0; iter < M; iter++) {\n        vector<vector<bool>> reachable(D, vector<bool>(D, false));\n        queue<pair<int, int>> bfs_q;\n        bfs_q.push({entrance_i, entrance_j});\n        reachable[entrance_i][entrance_j] = true;\n        \n        while (!bfs_q.empty()) {\n            auto [i, j] = bfs_q.front(); bfs_q.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D && !reachable[ni][nj] && is_empty[ni][nj]) {\n                    reachable[ni][nj] = true;\n                    bfs_q.push({ni, nj});\n                }\n            }\n        }\n        \n        int min_t = M + 1, min_i = -1, min_j = -1;\n        for (int i = 0; i < D; i++)\n            for (int j = 0; j < D; j++)\n                if (container_at[i][j] >= 0) {\n                    bool acc = false;\n                    for (int d = 0; d < 4; d++) {\n                        int ni = i + di[d], nj = j + dj[d];\n                        if (ni >= 0 && ni < D && nj >= 0 && nj < D && is_empty[ni][nj] && reachable[ni][nj]) {\n                            acc = true;\n                            break;\n                        }\n                    }\n                    if (acc && container_at[i][j] < min_t) {\n                        min_t = container_at[i][j];\n                        min_i = i; min_j = j;\n                    }\n                }\n        \n        cout << min_i << \" \" << min_j << endl;\n        is_empty[min_i][min_j] = true;\n        container_at[min_i][min_j] = -1;\n    }\n    \n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <cstring>\n#include <chrono>\n#include <random>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 50, M = 100;\nconst int dx[] = {0, 0, 1, -1};\nconst int dy[] = {1, -1, 0, 0};\n\nint n, m;\nint grid[N][N], best_grid[N][N];\nint bestE = -1;\nint ac[M+1][M+1];\nbool is_req[M+1][M+1];\nint color_cnt[M+1];\nmt19937 rng(42);\n\nint vis[N][N];\nint timer = 0;\n\nbool ok(int x, int y) { return 0 <= x && x < n && 0 <= y && y < n; }\n\nvoid cadj() {\n    memset(ac, 0, sizeof(ac));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) {\n            if (j + 1 < n && grid[i][j] != grid[i][j+1])\n                ac[min(grid[i][j], grid[i][j+1])][max(grid[i][j], grid[i][j+1])]++;\n            if (i + 1 < n && grid[i][j] != grid[i+1][j])\n                ac[min(grid[i][j], grid[i+1][j])][max(grid[i][j], grid[i+1][j])]++;\n            if ((i == 0 || i == n - 1 || j == 0 || j == n - 1) && grid[i][j] != 0)\n                ac[0][grid[i][j]]++;\n        }\n}\n\nvoid creq() {\n    memset(is_req, 0, sizeof(is_req));\n    cadj();\n    for (int a = 0; a <= m; a++)\n        for (int b = a; b <= m; b++)\n            if (ac[a][b] > 0) is_req[a][b] = true;\n}\n\nbool check_c_connect(int i, int j, int c) {\n    if (color_cnt[c] == 1) return false;\n    if (color_cnt[c] == 2) return true;\n    \n    vector<pair<int,int>> oc_neighs;\n    for (int d = 0; d < 4; d++) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ok(ni, nj) && grid[ni][nj] == c) oc_neighs.push_back({ni, nj});\n    }\n    if (oc_neighs.size() <= 1) return true;\n    \n    timer++;\n    queue<pair<int,int>> q;\n    q.push(oc_neighs[0]);\n    vis[oc_neighs[0].first][oc_neighs[0].second] = timer;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (ok(nx, ny) && vis[nx][ny] != timer && grid[nx][ny] == c && !(nx == i && ny == j)) {\n                vis[nx][ny] = timer;\n                q.push({nx, ny});\n            }\n        }\n    }\n    for (size_t k = 1; k < oc_neighs.size(); k++)\n        if (vis[oc_neighs[k].first][oc_neighs[k].second] != timer) return false;\n    return true;\n}\n\nbool check_0_connect(int i, int j) {\n    vector<pair<int,int>> zero_neighs;\n    for (int d = 0; d < 4; d++) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ok(ni, nj) && grid[ni][nj] == 0) zero_neighs.push_back({ni, nj});\n    }\n    if (zero_neighs.empty()) return true;\n    \n    timer++;\n    queue<pair<int,int>> q;\n    q.push(zero_neighs[0]);\n    vis[zero_neighs[0].first][zero_neighs[0].second] = timer;\n    bool reached_bnd = (zero_neighs[0].first == 0 || zero_neighs[0].first == n - 1 || zero_neighs[0].second == 0 || zero_neighs[0].second == n - 1);\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (ok(nx, ny) && vis[nx][ny] != timer && grid[nx][ny] == 0 && !(nx == i && ny == j)) {\n                vis[nx][ny] = timer;\n                q.push({nx, ny});\n                if (nx == 0 || nx == n - 1 || ny == 0 || ny == n - 1) reached_bnd = true;\n            }\n        }\n    }\n    if (!reached_bnd) return false;\n    for (size_t k = 1; k < zero_neighs.size(); k++)\n        if (vis[zero_neighs[k].first][zero_neighs[k].second] != timer) return false;\n    return true;\n}\n\nbool is_valid_move(int i, int j, int nc) {\n    int oc = grid[i][j];\n    if (oc == nc) return false;\n    \n    pair<int,int> deltas[10];\n    int d_vals[10] = {0};\n    int d_cnt = 0;\n    \n    for (int d = 0; d < 4; d++) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ok(ni, nj)) {\n            int nb = grid[ni][nj];\n            if (oc != nb) {\n                pair<int,int> p = {min(oc, nb), max(oc, nb)};\n                bool found = false;\n                for(int k=0; k<d_cnt; k++) if(deltas[k]==p) { d_vals[k]--; found=true; break; }\n                if(!found) { deltas[d_cnt]=p; d_vals[d_cnt]=-1; d_cnt++; }\n            }\n            if (nc != nb) {\n                pair<int,int> p = {min(nc, nb), max(nc, nb)};\n                bool found = false;\n                for(int k=0; k<d_cnt; k++) if(deltas[k]==p) { d_vals[k]++; found=true; break; }\n                if(!found) { deltas[d_cnt]=p; d_vals[d_cnt]=1; d_cnt++; }\n            }\n        }\n    }\n    bool is_bnd = (i == 0 || i == n - 1 || j == 0 || j == n - 1);\n    if (is_bnd) {\n        if (oc != 0) {\n            pair<int,int> p = {0, oc};\n            bool found = false;\n            for(int k=0; k<d_cnt; k++) if(deltas[k]==p) { d_vals[k]--; found=true; break; }\n            if(!found) { deltas[d_cnt]=p; d_vals[d_cnt]=-1; d_cnt++; }\n        }\n        if (nc != 0) {\n            pair<int,int> p = {0, nc};\n            bool found = false;\n            for(int k=0; k<d_cnt; k++) if(deltas[k]==p) { d_vals[k]++; found=true; break; }\n            if(!found) { deltas[d_cnt]=p; d_vals[d_cnt]=1; d_cnt++; }\n        }\n    }\n    \n    for(int k=0; k<d_cnt; k++) {\n        int ncnt = ac[deltas[k].first][deltas[k].second] + d_vals[k];\n        if (ncnt > 0 && !is_req[deltas[k].first][deltas[k].second]) return false;\n        if (ncnt <= 0 && is_req[deltas[k].first][deltas[k].second]) return false;\n    }\n    \n    if (oc != 0) { if (!check_c_connect(i, j, oc)) return false; }\n    else { if (!check_0_connect(i, j)) return false; }\n    \n    if (nc != 0) {\n        bool has_nc = false;\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ok(ni, nj) && grid[ni][nj] == nc) has_nc = true;\n        }\n        if (!has_nc) return false;\n    } else {\n        bool adj_to_0 = is_bnd;\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ok(ni, nj) && grid[ni][nj] == 0) adj_to_0 = true;\n        }\n        if (!adj_to_0) return false;\n    }\n    return true;\n}\n\nvoid apply_move(int i, int j, int nc) {\n    int oc = grid[i][j];\n    for (int d = 0; d < 4; d++) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ok(ni, nj)) {\n            int nb = grid[ni][nj];\n            if (oc != nb) ac[min(oc, nb)][max(oc, nb)]--;\n            if (nc != nb) ac[min(nc, nb)][max(nc, nb)]++;\n        }\n    }\n    if (i == 0 || i == n - 1 || j == 0 || j == n - 1) {\n        if (oc != 0) ac[0][oc]--;\n        if (nc != 0) ac[0][nc]++;\n    }\n    grid[i][j] = nc;\n    color_cnt[oc]--;\n    color_cnt[nc]++;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> n >> m;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) cin >> grid[i][j];\n    \n    memset(color_cnt, 0, sizeof(color_cnt));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) color_cnt[grid[i][j]]++;\n            \n    creq();\n    \n    int E = 0;\n    bestE = E;\n    memcpy(best_grid, grid, sizeof(grid));\n    \n    auto start = chrono::high_resolution_clock::now();\n    \n    uniform_int_distribution<int> cell_dist(0, n * n - 1);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    double T = 3.0;\n    double prob_accept_worse = exp(-1.0 / T);\n    \n    long long iterations = 0;\n    while (true) {\n        if (iterations % 1000 == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > 1.8) break;\n            T = max(0.01, 3.0 * (1.0 - elapsed / 1.8));\n            prob_accept_worse = exp(-1.0 / T);\n        }\n        iterations++;\n        \n        int idx = cell_dist(rng);\n        int i = idx / n;\n        int j = idx % n;\n        int oc = grid[i][j];\n        \n        int options[5];\n        int opt_cnt = 0;\n        if (oc != 0) options[opt_cnt++] = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ok(ni, nj) && grid[ni][nj] != oc) {\n                bool already = false;\n                for(int k=0; k<opt_cnt; k++) if(options[k]==grid[ni][nj]) already=true;\n                if(!already) options[opt_cnt++] = grid[ni][nj];\n            }\n        }\n        if (opt_cnt == 0) continue;\n        uniform_int_distribution<int> opt_dist(0, opt_cnt - 1);\n        int nc = options[opt_dist(rng)];\n        \n        if (is_valid_move(i, j, nc)) {\n            int delta_E = (nc == 0 ? 1 : (oc == 0 ? -1 : 0));\n            if (delta_E >= 0 || prob_dist(rng) < prob_accept_worse) {\n                apply_move(i, j, nc);\n                E += delta_E;\n                if (E > bestE) {\n                    bestE = E;\n                    memcpy(best_grid, grid, sizeof(grid));\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << best_grid[i][j];\n            if (j < n - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\nint N, D, Q;\nint qc = 0;\nint cmp[105][105];\n\nchar do_query(int a, int b) {\n    if (cmp[a][b] == -1) return '<';\n    if (cmp[a][b] == 1) return '>';\n    if (cmp[a][b] == 2) return '=';\n    if (qc >= Q) return '=';\n    qc++;\n    cout << \"1 1 \" << a << \" \" << b << endl;\n    char res; cin >> res;\n    if (res == '<') { cmp[a][b] = -1; cmp[b][a] = 1; }\n    else if (res == '>') { cmp[a][b] = 1; cmp[b][a] = -1; }\n    else if (res == '=') { cmp[a][b] = 2; cmp[b][a] = 2; }\n    return res;\n}\n\nchar do_query_sets(const vector<int>& L, const vector<int>& R) {\n    if (L.empty() || R.empty()) return '=';\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    char res; cin >> res;\n    qc++;\n    return res;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    for (int i = 0; i < N; i++) items[i] = i;\n    \n    // Phase 1: Heap Sort to find heavy items efficiently\n    for (int i = 1; i < N && qc < Q; i++) {\n        int cur = i;\n        while (cur > 0 && qc < Q) {\n            int par = (cur - 1) / 2;\n            char res = do_query(items[cur], items[par]);\n            if (res == '>') { swap(items[cur], items[par]); cur = par; }\n            else break;\n        }\n    }\n    for (int i = N - 1; i > 0 && qc < Q; i--) {\n        swap(items[0], items[i]);\n        int cur = 0;\n        while (qc < Q) {\n            int l = 2 * cur + 1, r = 2 * cur + 2, largest = cur;\n            if (l < i) { if (do_query(items[l], items[largest]) == '>') largest = l; }\n            if (r < i) { if (do_query(items[r], items[largest]) == '>') largest = r; }\n            if (largest != cur) { swap(items[cur], items[largest]); cur = largest; }\n            else break;\n        }\n    }\n    \n    // Phase 2: Initial LPT Assignment\n    vector<double> ew(N);\n    double cur_ew = 0;\n    for (int i = 0; i < N; i++) { cur_ew += 1.0 / (N - i); ew[items[i]] = cur_ew; }\n    \n    vector<double> sum_g(D, 0);\n    vector<vector<int>> group_items(D);\n    vector<int> asgn(N);\n    \n    for (int i = N - 1; i >= 0; i--) {\n        int item = items[i], mg = 0;\n        for (int g = 1; g < D; g++) if (sum_g[g] < sum_g[mg]) mg = g;\n        asgn[item] = mg; sum_g[mg] += ew[item]; group_items[mg].push_back(item);\n    }\n    \n    // Phase 3: Exact Local Search with Real Queries\n    while (qc < Q) {\n        int A = 0; bool abort = false;\n        for (int g = 1; g < D; g++) {\n            if (qc >= Q) { abort = true; break; }\n            if (do_query_sets(group_items[g], group_items[A]) == '>') A = g;\n        }\n        if (abort) break;\n        \n        int B = 0;\n        for (int g = 1; g < D; g++) {\n            if (qc >= Q) { abort = true; break; }\n            if (do_query_sets(group_items[g], group_items[B]) == '<') B = g;\n        }\n        if (abort) break;\n        if (A == B) break;\n        \n        vector<int>& items_A = group_items[A];\n        vector<int>& items_B = group_items[B];\n        bool improved = false;\n        \n        // Try single moves from A to B\n        sort(items_A.begin(), items_A.end(), [&](int x, int y){ return ew[x] < ew[y]; });\n        for (int idx = 0; idx < min(5, (int)items_A.size()); idx++) {\n            if ((int)items_A.size() <= 1) break;\n            int i = items_A[idx];\n            vector<int> L = items_B;\n            vector<int> R = items_A;\n            R.erase(find(R.begin(), R.end(), i));\n            \n            if (qc >= Q) break;\n            char res = do_query_sets(L, R);\n            if (res == '<' || res == '=') {\n                items_A.erase(find(items_A.begin(), items_A.end(), i));\n                items_B.push_back(i); asgn[i] = B;\n                sum_g[A] -= ew[i]; sum_g[B] += ew[i];\n                improved = true; break;\n            }\n        }\n        \n        if (!improved) {\n            // Try swaps between A and B\n            if (items_A.size() > 1 && items_B.size() > 1) {\n                sort(items_A.begin(), items_A.end(), [&](int x, int y){ return ew[x] > ew[y]; });\n                sort(items_B.begin(), items_B.end(), [&](int x, int y){ return ew[x] < ew[y]; });\n                for (int idx_i = 0; idx_i < min(5, (int)items_A.size()) && !improved; idx_i++) {\n                    for (int idx_j = 0; idx_j < min(5, (int)items_B.size()); idx_j++) {\n                        int i = items_A[idx_i], j = items_B[idx_j];\n                        if (cmp[i][j] != 1) { if (qc >= Q) { abort = true; break; } if (do_query(i, j) != '>') continue; }\n                        \n                        vector<int> L = items_B; L.erase(find(L.begin(), L.end(), j));\n                        vector<int> R = items_A; R.erase(find(R.begin(), R.end(), i));\n                        \n                        if (qc >= Q) { abort = true; break; }\n                        char res = do_query_sets(L, R);\n                        if (res == '<' || res == '=') {\n                            items_A.erase(find(items_A.begin(), items_A.end(), i));\n                            items_A.push_back(j);\n                            items_B.erase(find(items_B.begin(), items_B.end(), j));\n                            items_B.push_back(i);\n                            asgn[i] = B; asgn[j] = A;\n                            sum_g[A] += ew[j] - ew[i]; sum_g[B] += ew[i] - ew[j];\n                            improved = true; break;\n                        }\n                    }\n                    if (abort) break;\n                }\n            }\n        }\n        if (!improved || abort) break;\n    }\n    \n    // Waste remaining queries safely\n    while (qc < Q) { cout << \"1 1 0 1\" << endl; char res; cin >> res; qc++; }\n    \n    for (int i = 0; i < N; i++) cout << asgn[i] << \" \\n\"[i==N-1];\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++)\n            cin >> stacks[i][j];\n    }\n    \n    vector<int> box_stack(n + 1), box_pos(n + 1);\n    for (int i = 0; i < m; i++)\n        for (int j = 0; j < (int)stacks[i].size(); j++) {\n            box_stack[stacks[i][j]] = i;\n            box_pos[stacks[i][j]] = j;\n        }\n    \n    vector<pair<int, int>> operations;\n    const int INV_COST = 4;\n    const int EMPTY_COST = 5;\n    \n    for (int v = 1; v <= n; v++) {\n        int sid = box_stack[v], pos = box_pos[v];\n        int k = (int)stacks[sid].size() - 1 - pos;\n        \n        if (k == 0) {\n            operations.push_back({v, 0});\n            stacks[sid].pop_back();\n            continue;\n        }\n        \n        vector<int> A(stacks[sid].begin() + pos + 1, stacks[sid].end());\n        \n        vector<int> dp(k + 1, INT_MAX);\n        vector<int> par(k + 1);\n        dp[0] = 0;\n        \n        for (int i = 1; i <= k; i++) {\n            for (int j = 1; j <= i; j++) {\n                int int_inv = 0;\n                for (int s = i - j; s < i; s++)\n                    for (int t = s + 1; t < i; t++)\n                        if (A[s] < A[t]) int_inv++;\n                \n                int best_dest_cost = INT_MAX;\n                for (int d = 0; d < m; d++) {\n                    if (d == sid) continue;\n                    int ext_inv = 0, empty_pen = 0;\n                    if (stacks[d].empty()) empty_pen = EMPTY_COST;\n                    else {\n                        int top_val = stacks[d].back();\n                        for (int s = i - j; s < i; s++)\n                            if (A[s] > top_val) ext_inv++;\n                    }\n                    best_dest_cost = min(best_dest_cost, INV_COST * (int_inv + ext_inv) + empty_pen);\n                }\n                \n                int cost = dp[i - j] + (j + 1) + best_dest_cost;\n                if (cost < dp[i]) { dp[i] = cost; par[i] = j; }\n            }\n        }\n        \n        vector<int> chunks;\n        for (int cur = k; cur > 0; cur -= par[cur])\n            chunks.push_back(par[cur]);\n        \n        for (int cs : chunks) {\n            int off = stacks[sid].size() - cs;\n            int best_dest = -1, best_priority = 4, best_subscore = INT_MAX;\n            \n            for (int d = 0; d < m; d++) {\n                if (d == sid) continue;\n                int ext_inv = 0;\n                bool is_empty = stacks[d].empty();\n                int top_val = is_empty ? 0 : stacks[d].back();\n                \n                if (!is_empty)\n                    for (int s = off; s < (int)stacks[sid].size(); s++)\n                        if (stacks[sid][s] > top_val) ext_inv++;\n                \n                int priority, subscore;\n                if (ext_inv == 0 && !is_empty) { priority = 1; subscore = top_val; }\n                else if (ext_inv == 0) { priority = 2; subscore = 0; }\n                else { priority = 3; subscore = ext_inv * 1000 - top_val; }\n                \n                if (priority < best_priority || (priority == best_priority && subscore < best_subscore)) {\n                    best_priority = priority; best_subscore = subscore; best_dest = d;\n                }\n            }\n            \n            if (best_dest == -1) best_dest = (sid + 1) % m;\n            \n            int u = stacks[sid][off];\n            operations.push_back({u, best_dest + 1});\n            \n            vector<int> moved(stacks[sid].begin() + off, stacks[sid].end());\n            stacks[sid].resize(off);\n            stacks[best_dest].insert(stacks[best_dest].end(), moved.begin(), moved.end());\n            \n            for (int j = 0; j < (int)moved.size(); j++) {\n                box_stack[moved[j]] = best_dest;\n                box_pos[moved[j]] = stacks[best_dest].size() - moved.size() + j;\n            }\n        }\n        \n        operations.push_back({v, 0});\n        stacks[sid].pop_back();\n    }\n    \n    for (auto& op : operations)\n        cout << op.first << \" \" << op.second << endl;\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\nchar dir_char[] = {'R', 'D', 'L', 'U'};\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + dx[dir], nj = j + dy[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (dir == 0 && v[i][j] == '1') return false;\n    if (dir == 1 && h[i][j] == '1') return false;\n    if (dir == 2 && v[i][nj] == '1') return false;\n    if (dir == 3 && h[ni][j] == '1') return false;\n    return true;\n}\n\nint get_dir(char c) {\n    if (c == 'R') return 0;\n    if (c == 'D') return 1;\n    if (c == 'L') return 2;\n    return 3; // 'U'\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    h.resize(N - 1); v.resize(N); d.resize(N, vector<int>(N));\n    for (int i = 0; i < N - 1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    int total_cells = N * N;\n    vector<int> all_dist(total_cells * total_cells, -1);\n    vector<int> all_prev_dir(total_cells * total_cells, -1);\n\n    auto get_dist = [&](int si, int sj, int ei, int ej) -> int& {\n        return all_dist[(si * N + sj) * total_cells + (ei * N + ej)];\n    };\n    auto get_prev = [&](int si, int sj, int ei, int ej) -> int& {\n        return all_prev_dir[(si * N + sj) * total_cells + (ei * N + ej)];\n    };\n\n    // Precompute BFS from all cells\n    for (int si = 0; si < N; ++si) {\n        for (int sj = 0; sj < N; ++sj) {\n            queue<pair<int,int>> q;\n            get_dist(si, sj, si, sj) = 0;\n            q.push({si, sj});\n            while (!q.empty()) {\n                auto [ci, cj] = q.front(); q.pop();\n                for (int dir = 0; dir < 4; dir++) {\n                    if (!can_move(ci, cj, dir)) continue;\n                    int ni = ci + dx[dir], nj = cj + dy[dir];\n                    if (get_dist(si, sj, ni, nj) == -1) { \n                        get_dist(si, sj, ni, nj) = get_dist(si, sj, ci, cj) + 1; \n                        get_prev(si, sj, ni, nj) = (dir + 2) % 4; // Direction to go BACK\n                        q.push({ni, nj}); \n                    }\n                }\n            }\n        }\n    }\n\n    auto get_path = [&](int si, int sj, int ei, int ej) -> string {\n        string path_back;\n        int ci = ei, cj = ej;\n        while (ci != si || cj != sj) {\n            int dir = get_prev(si, sj, ci, cj);\n            path_back += dir_char[dir];\n            ci += dx[dir];\n            cj += dy[dir];\n        }\n        string path_to;\n        for (int k = (int)path_back.size() - 1; k >= 0; --k) {\n            char c = path_back[k];\n            if (c == 'R') path_to += 'L';\n            else if (c == 'D') path_to += 'U';\n            else if (c == 'L') path_to += 'R';\n            else path_to += 'D';\n        }\n        return path_to;\n    };\n    \n    // Build DFS tour\n    string base_tour;\n    base_tour.reserve(N * N * 2);\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            int ni = i + dx[dir], nj = j + dy[dir];\n            if (!visited[ni][nj]) {\n                base_tour += dir_char[dir];\n                dfs(ni, nj);\n                base_tour += dir_char[(dir + 2) % 4];\n            }\n        }\n    };\n    dfs(0, 0);\n    \n    int L = base_tour.size();\n    vector<pair<int,int>> positions(L + 1);\n    positions[0] = {0, 0};\n    for (int t = 0; t < L; t++) {\n        int dir = get_dir(base_tour[t]);\n        positions[t+1] = {positions[t].first + dx[dir], positions[t].second + dy[dir]};\n    }\n    \n    // Find closest insertion point on base tour for detours\n    vector<int> best_step(N * N, 0), best_cost(N * N, INT_MAX);\n    for (int t = 0; t < L; t++) {\n        auto [pi, pj] = positions[t];\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (pi == i && pj == j) continue;\n            int cost = 2 * get_dist(pi, pj, i, j);\n            if (cost < best_cost[i * N + j]) { best_cost[i * N + j] = cost; best_step[i * N + j] = t; }\n        }\n    }\n    \n    // Correctly calculate visits per cycle (t=0 to L-1)\n    vector<int> visit_count(N * N, 0);\n    for (int t = 0; t < L; t++) { auto [i, j] = positions[t]; visit_count[i * N + j]++; }\n    \n    double S_factor = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) S_factor += (double)d[i][j] / visit_count[i * N + j];\n    \n    using Cell = tuple<double, int, int>;\n    priority_queue<Cell> pq;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (i == 0 && j == 0) continue;\n        int k = visit_count[i * N + j], cost = best_cost[i * N + j];\n        if (cost == 0 || cost >= INT_MAX) continue;\n        pq.push({(double)d[i][j] / ((long long)k * (k + 1)) / cost, i, j});\n    }\n    \n    struct Detour { int step; int i; int j; };\n    vector<Detour> detours;\n    int current_L = L;\n    \n    while (!pq.empty() && current_L < 100000) {\n        auto [p, i, j] = pq.top(); pq.pop();\n        int k = visit_count[i * N + j], cost = best_cost[i * N + j];\n        if (cost >= INT_MAX) continue;\n        double new_p = (double)d[i][j] / ((long long)k * (k + 1)) / cost;\n        if (abs(new_p - p) > 1e-9) { pq.push({new_p, i, j}); continue; }\n        \n        if (current_L + cost > 100000) continue;\n        \n        // Benefit-cost check\n        double benefit = (double)d[i][j] * (current_L + cost) / ((long long)k * (k + 1));\n        double detour_cost_val = (double)cost * S_factor;\n        if (benefit <= detour_cost_val) break; // No more beneficial detours possible\n        \n        int step = best_step[i * N + j];\n        \n        detours.push_back({step, i, j});\n        current_L += cost;\n        S_factor -= (double)d[i][j] / k;\n        visit_count[i * N + j]++;\n        S_factor += (double)d[i][j] / visit_count[i * N + j];\n        int nk = visit_count[i * N + j];\n        pq.push({(double)d[i][j] / ((long long)nk * (nk + 1)) / cost, i, j});\n    }\n    \n    sort(detours.begin(), detours.end(), [](const auto& a, const auto& b) { return a.step < b.step; });\n    \n    string result;\n    result.reserve(100000);\n    int detour_idx = 0;\n    for (int t = 0; t <= L; t++) {\n        while (detour_idx < (int)detours.size() && detours[detour_idx].step == t) {\n            auto [step, i, j] = detours[detour_idx];\n            auto [pi, pj] = positions[step];\n            string path_to = get_path(pi, pj, i, j);\n            string path_back;\n            for (int k2 = (int)path_to.size() - 1; k2 >= 0; k2--) {\n                char c = path_to[k2];\n                path_back += (c == 'R') ? 'L' : (c == 'D') ? 'U' : (c == 'L') ? 'R' : 'D';\n            }\n            result += path_to;\n            result += path_back;\n            detour_idx++;\n        }\n        if (t < L) result += base_tour[t];\n    }\n    \n    cout << result << endl;\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    int N,M; cin>>N>>M;\n    int si,sj; cin>>si>>sj;\n    vector<string> A(N);\n    for(int i=0;i<N;i++) cin>>A[i];\n    vector<string> t(M);\n    for(int i=0;i<M;i++) cin>>t[i];\n    vector<vector<pair<int,int>>> cp(26);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cp[A[i][j]-'A'].push_back({i,j});\n    vector<vector<int>> cd(26,vector<int>(26,0));\n    for(int c1=0;c1<26;c1++) for(int c2=0;c2<26;c2++){\n        int md=INT_MAX;\n        for(auto&[i1,j1]:cp[c1]) for(auto&[i2,j2]:cp[c2]) md=min(md,abs(i1-i2)+abs(j1-j2));\n        cd[c1][c2]=md;\n    }\n    vector<vector<int>> ov(M,vector<int>(M,0));\n    for(int i=0;i<M;i++) for(int j=0;j<M;j++){ if(i==j) continue;\n        for(int l=4;l>=1;l--){ bool ok=true; for(int k=0;k<l;k++) if(t[i][5-l+k]!=t[j][k]){ok=false;break;}\n            if(ok){ov[i][j]=l;break;}}}\n    vector<vector<int>> fail(M,vector<int>(6,0));\n    for(int k=0;k<M;k++) for(int i=2;i<=5;i++){ int f=fail[k][i-1];\n        while(f>0&&t[k][f]!=t[k][i-1]) f=fail[k][f]; if(t[k][f]==t[k][i-1]) f++; fail[k][i]=f;}\n    auto buildS=[&](const vector<int>&o)->string{ string s=t[o[0]];\n        for(int i=1;i<(int)o.size();i++){ int mx=min(5,(int)s.size()),a=0;\n            for(int l=mx;l>=1;l--){ bool ok=true; for(int k=0;k<l;k++) if(s[s.size()-l+k]!=t[o[i]][k]){ok=false;break;}\n                if(ok){a=l;break;}} s+=t[o[i]].substr(a);} return s;};\n    auto totalOv=[&](const vector<int>&o)->int{ int tv=0; for(int i=1;i<(int)o.size();i++) tv+=ov[o[i-1]][o[i]]; return tv;};\n    mt19937 rng(42);\n    auto greedyR=[&](int st,unsigned seed)->vector<int>{ mt19937 lr(seed); vector<int>o; o.push_back(st);\n        vector<bool>u(M,false); u[st]=true; for(int s=1;s<M;s++){ int l=o.back(),bo=-1; vector<int>c;\n            for(int j=0;j<M;j++){ if(u[j]) continue; if(ov[l][j]>bo){bo=ov[l][j];c.clear();c.push_back(j);}\n                else if(ov[l][j]==bo) c.push_back(j);} o.push_back(c[lr()%c.size()]); u[o.back()]=true;} return o;};\n    auto twoOpt=[&](vector<int>o)->vector<int>{ bool imp=true; while(imp){ imp=false;\n        for(int i=0;i<M-1;i++){ int os=0,ns=0; if(i>0){os+=ov[o[i-1]][o[i]];ns+=ov[o[i-1]][o[i+1]];}\n            os+=ov[o[i]][o[i+1]]; ns+=ov[o[i+1]][o[i]]; if(i+2<M){os+=ov[o[i+1]][o[i+2]];ns+=ov[o[i]][o[i+2]];}\n            if(ns>os){swap(o[i],o[i+1]);imp=true;}}} return o;};\n    auto orOpt=[&](vector<int>o)->vector<int>{ for(int it=0;it<10;it++){ bool imp=false;\n        for(int i=0;i<M;i++){ int w=o[i],rd=0; if(i>0) rd-=ov[o[i-1]][w]; if(i<M-1) rd-=ov[w][o[i+1]];\n            if(i>0&&i<M-1) rd+=ov[o[i-1]][o[i+1]]; auto gr=[&](int k)->int{return(k<i)?o[k]:o[k+1];};\n            int bd=0,bk=i; for(int j=0;j<=M-1;j++){ if(j==i) continue; int id=0;\n                int C=(j>0)?gr(j-1):-1,D=(j<M-1)?gr(j):-1; if(C!=-1) id+=ov[C][w]; if(D!=-1) id+=ov[w][D];\n                if(C!=-1&&D!=-1) id-=ov[C][D]; if(rd+id>bd){bd=rd+id;bk=j;}}\n            if(bk!=i){ vector<int>rm; for(int k=0;k<M;k++) if(k!=i) rm.push_back(o[k]); o.clear();\n                for(int k=0;k<bk;k++) o.push_back(rm[k]); o.push_back(w); for(int k=bk;k<M-1;k++) o.push_back(rm[k]);\n                imp=true;break;}} if(!imp) break;} return o;};\n    auto sa=[&](vector<int>o,unsigned seed)->vector<int>{ int curOv=totalOv(o); int bestOv=curOv; auto bestO=o;\n        mt19937 saRng(seed); uniform_int_distribution<int>distI(0,M-1); uniform_real_distribution<double>distD(0.0,1.0);\n        double temp=3.0; for(int it=0;it<300000;it++){ temp*=0.99998;\n            if(saRng()%3==0){ int i=distI(saRng),j=distI(saRng); if(i==j) continue; int w=o[i],rd=0;\n                if(i>0) rd-=ov[o[i-1]][w]; if(i<M-1) rd-=ov[w][o[i+1]]; if(i>0&&i<M-1) rd+=ov[o[i-1]][o[i+1]];\n                auto gr=[&](int k)->int{return(k<i)?o[k]:o[k+1];}; int C=(j>0)?gr(j-1):-1,D=(j<M-1)?gr(j):-1; int id=0;\n                if(C!=-1) id+=ov[C][w]; if(D!=-1) id+=ov[w][D]; if(C!=-1&&D!=-1) id-=ov[C][D]; int delta=rd+id;\n                if(delta>0||distD(saRng)<exp((double)delta/max(temp,0.001))){ o.erase(o.begin()+i); o.insert(o.begin()+j,w);\n                    curOv+=delta; if(curOv>bestOv){bestOv=curOv;bestO=o;}}}\n            else{ int i=distI(saRng),j=distI(saRng); if(i==j) continue; if(i>j) swap(i,j); int delta=0;\n                if(j==i+1){ if(i>0){delta-=ov[o[i-1]][o[i]];delta+=ov[o[i-1]][o[j]];}\n                    delta-=ov[o[i]][o[j]]; delta+=ov[o[j]][o[i]]; if(j+1<M){delta-=ov[o[j]][o[j+1]];delta+=ov[o[i]][o[j+1]];}}\n                else{ if(i>0){delta-=ov[o[i-1]][o[i]];delta+=ov[o[i-1]][o[j]];}\n                    if(i+1<M){delta-=ov[o[i]][o[i+1]];delta+=ov[o[j]][o[i+1]];}\n                    if(j>0){delta-=ov[o[j-1]][o[j]];delta+=ov[o[j-1]][o[i]];}\n                    if(j+1<M){delta-=ov[o[j]][o[j+1]];delta+=ov[o[i]][o[j+1]];}}\n                if(delta>0||distD(saRng)<exp((double)delta/max(temp,0.001))){ swap(o[i],o[j]); curOv+=delta;\n                    if(curOv>bestOv){bestOv=curOv;bestO=o;}}}} return bestO;};\n    const int INF=1e9;\n    auto dpStep=[&](const vector<int>&cur, vector<int>& nx, char c){ \n        fill(nx.begin(), nx.end(), INF); int ci=c-'A';\n        for(int q=0;q<225;q++){ if(cur[q]>=INF) continue; int qi=q/15,qj=q%15;\n            for(auto&[pi,pj]:cp[ci]){ int p=pi*15+pj; int nc=cur[q]+abs(pi-qi)+abs(pj-qj)+1; if(nc<nx[p]) nx[p]=nc;}}\n    };\n    auto dpGreedy=[&](int forceFirst)->string{ \n        vector<int>cur(225,INF), nx(225); cur[si*15+sj]=0; string S; vector<bool>used(M,false);\n        if(forceFirst>=0){ for(char c:t[forceFirst]) { dpStep(cur, nx, c); swap(cur, nx); } S+=t[forceFirst]; used[forceFirst]=true;}\n        for(int step=(forceFirst>=0?1:0);step<M;step++){ vector<pair<double,int>>cands;\n            for(int j=0;j<M;j++){ if(used[j]) continue; int mx=min(5,(int)S.size()),a=0;\n                for(int l=mx;l>=1;l--){ bool ok=true; for(int k=0;k<l;k++) if(S[S.size()-l+k]!=t[j][k]){ok=false;break;}\n                    if(ok){a=l;break;}} double hcost=(5-a)*10.0;\n                if(!S.empty()) hcost+=cd[S.back()-'A'][t[j][a]-'A']; else hcost+=cd[A[si][sj]-'A'][t[j][0]-'A'];\n                cands.push_back({hcost,j});} sort(cands.begin(),cands.end());\n            int topK=min(15,(int)cands.size()); int bestWord=-1,bestCost=INF; vector<int>bestNx(225); string bestExt;\n            for(int k=0;k<topK;k++){ int j=cands[k].second; int mx=min(5,(int)S.size()),a=0;\n                for(int l=mx;l>=1;l--){ bool ok=true; for(int kk=0;kk<l;kk++) if(S[S.size()-l+kk]!=t[j][kk]){ok=false;break;}\n                    if(ok){a=l;break;}} string ext=t[j].substr(a); auto tmpCur=cur;\n                for(char c:ext) { dpStep(tmpCur, nx, c); swap(tmpCur, nx); }\n                int cost=*min_element(tmpCur.begin(),tmpCur.end()); \n                if(cost<bestCost){bestCost=cost;bestWord=j;swap(bestNx,tmpCur);bestExt=ext;}}\n            S+=bestExt; used[bestWord]=true; swap(cur, bestNx);} return S;};\n    auto charGreedy=[&](double w1,double w2,double w3)->string{ vector<int>ml(M,0); vector<bool>matched(M,false); int nm=0;\n        string S; int ci=si,cj=sj; while(nm<M&&S.size()<5000){ int bchar=-1,bpi=-1,bpj=-1; double bscore=-1e18;\n            for(int c=0;c<26;c++){ int md=INT_MAX,pi=-1,pj=-1; for(auto&[i,j]:cp[c]){int d=abs(i-ci)+abs(j-cj);if(d<md){md=d;pi=i;pj=j;}}\n                int comp=0; double adv=0; for(int k=0;k<M;k++){ if(matched[k]) continue; int l=ml[k];\n                    while(l>0&&t[k][l]!=('A'+c)) l=fail[k][l]; if(t[k][l]==('A'+c)) l++;\n                    if(l==5) comp++; else if(l>ml[k]) adv+=(l-ml[k]);}\n                double score=comp*w1+adv*w2-md*w3; if(score>bscore){bscore=score;bchar=c;bpi=pi;bpj=pj;}}\n            S+=('A'+bchar); ci=bpi; cj=bpj;\n            for(int k=0;k<M;k++){ if(matched[k]) continue; int l=ml[k];\n                while(l>0&&t[k][l]!=('A'+bchar)) l=fail[k][l]; if(t[k][l]==('A'+bchar)) l++; ml[k]=l;\n                if(l==5){matched[k]=true;nm++;}}} return S;};\n    auto dpCharGreedy=[&]()->string{ \n        vector<int>cur(225,INF), nx(225), bestNx(225); cur[si*15+sj]=0; string S;\n        vector<int>ml(M,0); vector<bool>matched(M,false); int nm=0;\n        while(nm<M&&S.size()<5000){ int bchar=-1; int bestComp=-1,bestAdv=-1,bestCost=INF;\n            for(int c=0;c<26;c++){ dpStep(cur, nx, 'A'+c); int cost=*min_element(nx.begin(),nx.end());\n                int comp=0,adv=0; for(int k=0;k<M;k++){ if(matched[k]) continue; int l=ml[k];\n                    while(l>0&&t[k][l]!=('A'+c)) l=fail[k][l]; if(t[k][l]==('A'+c)) l++;\n                    if(l==5) comp++; else if(l>ml[k]) adv+=(l-ml[k]);}\n                bool better=false; if(comp>bestComp) better=true; else if(comp==bestComp){if(cost<bestCost) better=true; else if(cost==bestCost&&adv>bestAdv) better=true;}\n                if(better){bestComp=comp;bestAdv=adv;bestCost=cost;bchar=c;swap(bestNx,nx);}}\n            S+=('A'+bchar); swap(cur,bestNx);\n            for(int k=0;k<M;k++){ if(matched[k]) continue; int l=ml[k];\n                while(l>0&&t[k][l]!=('A'+bchar)) l=fail[k][l]; if(t[k][l]==('A'+bchar)) l++; ml[k]=l;\n                if(l==5){matched[k]=true;nm++;}}} return S;};\n    vector<string>candidates; vector<pair<int,vector<int>>>cs;\n    for(int s=0;s<M;s++){auto o=greedyR(s,s*997+1);o=twoOpt(o);cs.push_back({5*M-totalOv(o),o});}\n    sort(cs.begin(),cs.end()); cs.erase(unique(cs.begin(),cs.end(),[](auto&a,auto&b){return a.second==b.second;}),cs.end());\n    int topN=min((int)cs.size(),20); for(int i=0;i<topN;i++){ auto o=cs[i].second; o=orOpt(o); o=twoOpt(o); candidates.push_back(buildS(o));}\n    int saN=min((int)cs.size(),5); for(int i=0;i<saN;i++) for(int r=0;r<2;r++){ auto o=cs[i].second;\n        o=sa(o,i*12345+r*54321+1); o=twoOpt(o); candidates.push_back(buildS(o));}\n    for(int s=0;s<10;s++) candidates.push_back(dpGreedy(s));\n    candidates.push_back(dpGreedy(-1));\n    candidates.push_back(charGreedy(100,20,3)); candidates.push_back(charGreedy(200,30,5)); candidates.push_back(charGreedy(50,10,2));\n    candidates.push_back(dpCharGreedy());\n    auto dpEval=[&](const string&s)->int{ int L=s.size(); vector<int>cur(225,INF), nx(225); cur[si*15+sj]=0;\n        for(int i=0;i<L;i++){ dpStep(cur, nx, s[i]); swap(cur, nx);} return *min_element(cur.begin(),cur.end());};\n    string bs; int bc=INF; for(auto&ss:candidates){ int c=dpEval(ss); if(c<bc){bc=c;bs=ss;}}\n    int L=bs.size(); vector<vector<pair<int,int>>>dp(L+1,vector<pair<int,int>>(225,{INF,-1})); dp[0][si*15+sj]={0,-1};\n    for(int i=0;i<L;i++){ int ci=bs[i]-'A'; for(int q=0;q<225;q++){ if(dp[i][q].first>=INF) continue; int qi=q/15,qj=q%15;\n        for(auto&[pi,pj]:cp[ci]){ int p=pi*15+pj; int nc=dp[i][q].first+abs(pi-qi)+abs(pj-qj)+1;\n            if(nc<dp[i+1][p].first) dp[i+1][p]={nc,q};}}}\n    int be=0; bc=INF; for(int p=0;p<225;p++) if(dp[L][p].first<bc){bc=dp[L][p].first;be=p;}\n    vector<int>pp(L); int cr=be; for(int i=L-1;i>=0;i--){pp[i]=cr;cr=dp[i+1][cr].second;}\n    for(int i=0;i<L;i++) cout<<pp[i]/15<<\" \"<<pp[i]%15<<\"\\n\"; return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\nvector<vector<pair<int,int>>> shapes;\nvector<int> max_di, max_dj;\nvector<vector<pair<int,int>>> positions;\nvector<vector<vector<pair<int,int>>>> pos_cells;\nvector<vector<vector<int>>> cell_pos;\nint known[25][25];\nint query_count = 0;\nvector<vector<double>> lw;\ndouble cov_val[25][25];\ndouble prob_oil_val[25][25];\n\nint drill_cell(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int v; cin >> v;\n    known[i][j] = v;\n    query_count++;\n    return v;\n}\n\nint divine_cells(vector<pair<int,int>>& cells) {\n    int k = cells.size();\n    cout << \"q \" << k;\n    for (auto& [i, j] : cells) cout << \" \" << i << \" \" << j;\n    cout << endl;\n    cout.flush();\n    int v; cin >> v;\n    query_count++;\n    return v;\n}\n\nbool submit_answer(vector<pair<int,int>>& cells) {\n    sort(cells.begin(), cells.end());\n    cells.erase(unique(cells.begin(), cells.end()), cells.end());\n    cout << \"a \" << cells.size();\n    for (auto& [i, j] : cells) cout << \" \" << i << \" \" << j;\n    cout << endl;\n    cout.flush();\n    int r; cin >> r;\n    if (r == 0) query_count++; // Wrong answer costs 1 operation\n    return r == 1;\n}\n\nvoid compute_prob_and_cov() {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        cov_val[i][j] = 0;\n        prob_oil_val[i][j] = 1.0;\n    }\n    for (int k = 0; k < M; k++) {\n        double mx = -1e9;\n        for (auto& l : lw[k]) { if (l > mx) mx = l; }\n        double total = 0;\n        double wt_arr[600];\n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            wt_arr[p] = exp(lw[k][p] - mx);\n            total += wt_arr[p];\n        }\n        if (total < 1e-30) continue;\n        for (int p = 0; p < (int)positions[k].size(); p++) wt_arr[p] /= total;\n        \n        double cc_arr[450];\n        memset(cc_arr, 0, sizeof(double) * N * N);\n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            double wt = wt_arr[p];\n            for (auto& [ci, cj] : pos_cells[k][p]) cc_arr[ci * N + cj] += wt;\n        }\n        for (int idx = 0; idx < N * N; idx++) {\n            cov_val[idx / N][idx % N] += cc_arr[idx];\n            prob_oil_val[idx / N][idx % N] *= (1.0 - cc_arr[idx]);\n        }\n    }\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)\n        prob_oil_val[i][j] = 1.0 - prob_oil_val[i][j];\n}\n\nvoid update_divine(const vector<pair<int,int>>& qcells, int obs) {\n    int ksz = qcells.size();\n    double sigma2 = ksz * eps * (1 - eps);\n    \n    bool in_Q[25][25];\n    memset(in_Q, 0, sizeof(in_Q));\n    for (auto& [i, j] : qcells) in_Q[i][j] = true;\n    \n    double S_Q = 0;\n    for (auto& [i, j] : qcells) S_Q += cov_val[i][j];\n    \n    for (int k = 0; k < M; k++) {\n        double mx = -1e9;\n        for (auto& l : lw[k]) { if (l > mx) mx = l; }\n        double total = 0;\n        double wt_arr[600];\n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            wt_arr[p] = exp(lw[k][p] - mx);\n            total += wt_arr[p];\n        }\n        if (total < 1e-30) continue;\n        for (int p = 0; p < (int)positions[k].size(); p++) wt_arr[p] /= total;\n        \n        int pos_cnt[600];\n        double S_k = 0;\n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            int cnt = 0;\n            for (auto& [ci, cj] : pos_cells[k][p]) {\n                if (in_Q[ci][cj]) cnt++;\n            }\n            pos_cnt[p] = cnt;\n            S_k += wt_arr[p] * cnt;\n        }\n        \n        double S_others = S_Q - S_k;\n        double var_others = max(S_others * 1.5, 0.5); // Fast and reasonable approximation\n        \n        double total_var = sigma2 + var_others * (1 - 2 * eps) * (1 - 2 * eps);\n        if (total_var < sigma2) total_var = sigma2;\n        \n        for (int p = 0; p < (int)positions[k].size(); p++) {\n            double ev = S_others + pos_cnt[p];\n            double mean = ksz * eps + ev * (1 - 2 * eps);\n            double diff = obs - mean;\n            double penalty = diff * diff / (2 * total_var);\n            if (penalty > 15.0) penalty = 15.0; // Cap to prevent catastrophic drops\n            lw[k][p] += -penalty;\n        }\n        mx = -1e9;\n        for (auto& l : lw[k]) { if (l > mx) mx = l; }\n        if (mx > -1e8) {\n            for (auto& l : lw[k]) l -= mx;\n        }\n    }\n    compute_prob_and_cov();\n}\n\nvoid update_drill(int i, int j, int obs) {\n    if (obs == 0) {\n        for (int k = 0; k < M; k++) {\n            for (int p : cell_pos[k][i * N + j]) {\n                lw[k][p] = -1e9; \n            }\n            double mx = -1e9;\n            for (auto& l : lw[k]) { if (l > mx) mx = l; }\n            if (mx > -1e8) {\n                for (auto& l : lw[k]) l -= mx;\n            }\n        }\n    } else if (obs == M) {\n        for (int k = 0; k < M; k++) {\n            bool covers_arr[600];\n            memset(covers_arr, 0, sizeof(bool) * positions[k].size());\n            for (int p : cell_pos[k][i * N + j]) covers_arr[p] = true;\n            for (int p = 0; p < (int)positions[k].size(); p++) {\n                if (!covers_arr[p]) lw[k][p] = -1e9;\n            }\n            double mx = -1e9;\n            for (auto& l : lw[k]) { if (l > mx) mx = l; }\n            if (mx > -1e8) {\n                for (auto& l : lw[k]) l -= mx;\n            }\n        }\n    } else {\n        double fc_arr[25];\n        double S_total = cov_val[i][j];\n        for (int k = 0; k < M; k++) {\n            double mx = -1e9;\n            for (auto& l : lw[k]) { if (l > mx) mx = l; }\n            double total = 0;\n            for (int p = 0; p < (int)positions[k].size(); p++) total += exp(lw[k][p] - mx);\n            if (total < 1e-30) { fc_arr[k] = 0; continue; }\n            double covers = 0;\n            for (int p : cell_pos[k][i * N + j]) covers += exp(lw[k][p] - mx);\n            fc_arr[k] = covers / total;\n        }\n        \n        for (int k = 0; k < M; k++) {\n            double others = S_total - fc_arr[k];\n            double var_others = max(0.3, others * 1.5);\n            bool covers_arr[600];\n            memset(covers_arr, 0, sizeof(bool) * positions[k].size());\n            for (int p : cell_pos[k][i * N + j]) covers_arr[p] = true;\n            \n            for (int p = 0; p < (int)positions[k].size(); p++) {\n                double diff = covers_arr[p] ? obs - 1.0 - others : obs - others;\n                double penalty = diff * diff / (2 * var_others);\n                if (penalty > 15.0) penalty = 15.0;\n                lw[k][p] += -penalty;\n            }\n            double mx = -1e9;\n            for (auto& l : lw[k]) { if (l > mx) mx = l; }\n            if (mx > -1e8) {\n                for (auto& l : lw[k]) l -= mx;\n            }\n        }\n    }\n    compute_prob_and_cov();\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M >> eps;\n    shapes.resize(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int l = 0; l < d; l++) cin >> shapes[k][l].first >> shapes[k][l].second;\n    }\n    max_di.resize(M); max_dj.resize(M);\n    for (int k = 0; k < M; k++) {\n        max_di[k] = max_dj[k] = 0;\n        for (auto& [i, j] : shapes[k]) { max_di[k] = max(max_di[k], i); max_dj[k] = max(max_dj[k], j); }\n    }\n    cell_pos.resize(M, vector<vector<int>>(N * N));\n    for (int k = 0; k < M; k++) {\n        vector<pair<int,int>> pos;\n        vector<vector<pair<int,int>>> cells;\n        int pidx = 0;\n        for (int di = 0; di <= N - 1 - max_di[k]; di++)\n            for (int dj = 0; dj <= N - 1 - max_dj[k]; dj++) {\n                pos.push_back({di, dj});\n                vector<pair<int,int>> c;\n                for (auto& [i, j] : shapes[k]) {\n                    int ci = di + i, cj = dj + j;\n                    c.push_back({ci, cj});\n                    cell_pos[k][ci * N + cj].push_back(pidx);\n                }\n                cells.push_back(c);\n                pidx++;\n            }\n        positions.push_back(pos);\n        pos_cells.push_back(cells);\n    }\n    memset(known, -1, sizeof(known));\n    for (int k = 0; k < M; k++) lw.push_back(vector<double>(positions[k].size(), 0.0));\n    compute_prob_and_cov();\n    \n    for (int i = 0; i < N && query_count < 2*N*N - 1; i++) {\n        vector<pair<int,int>> cells;\n        for (int j = 0; j < N; j++) cells.push_back({i, j});\n        update_divine(cells, divine_cells(cells));\n    }\n    for (int j = 0; j < N && query_count < 2*N*N - 1; j++) {\n        vector<pair<int,int>> cells;\n        for (int i = 0; i < N; i++) cells.push_back({i, j});\n        update_divine(cells, divine_cells(cells));\n    }\n    \n    int targeted_queries = 0;\n    while (query_count < N * N && targeted_queries < 50) {\n        int best_k = -1;\n        double max_ent = -1;\n        for (int k = 0; k < M; k++) {\n            double total = 0;\n            for (int p = 0; p < (int)positions[k].size(); p++) total += exp(lw[k][p]);\n            if (total < 1e-30) continue;\n            double ent = 0;\n            for (int p = 0; p < (int)positions[k].size(); p++) {\n                double prob = exp(lw[k][p]) / total;\n                if (prob > 1e-9 && prob < 1 - 1e-9) ent -= prob * log(prob);\n            }\n            if (ent > max_ent) { max_ent = ent; best_k = k; }\n        }\n        if (best_k == -1 || max_ent < 0.5) break;\n        if (eps > 0.1 && max_ent < 2.0) break;\n        \n        int best_p = max_element(lw[best_k].begin(), lw[best_k].end()) - lw[best_k].begin();\n        vector<pair<int,int>> qcells = pos_cells[best_k][best_p];\n        if (qcells.size() >= 2) {\n            update_divine(qcells, divine_cells(qcells));\n            targeted_queries++;\n        } else break;\n    }\n    \n    bool last_answer_wrong = false;\n    while (query_count < 2*N*N) {\n        double exp_err = 0;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (known[i][j] >= 0) continue;\n            double p = prob_oil_val[i][j];\n            exp_err += min(p, 1 - p);\n        }\n        if ((exp_err < 0.7 || query_count >= 2*N*N - 1) && !last_answer_wrong) {\n            vector<pair<int,int>> ans;\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n                if (known[i][j] > 0) ans.push_back({i, j});\n                else if (known[i][j] < 0 && prob_oil_val[i][j] > 0.5) ans.push_back({i, j});\n            }\n            if (submit_answer(ans)) return 0;\n            last_answer_wrong = true;\n        } else {\n            if (query_count >= 2*N*N - 1) break;\n            int bi = -1, bj = -1; double bent = -1;\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n                if (known[i][j] >= 0) continue;\n                double p = max(0.001, min(0.999, prob_oil_val[i][j]));\n                double ent = -p*log(p) - (1-p)*log(1-p);\n                if (ent > bent) { bent = ent; bi = i; bj = j; }\n            }\n            if (bi < 0) break;\n            update_drill(bi, bj, drill_cell(bi, bj));\n            last_answer_wrong = false;\n        }\n    }\n    \n    vector<pair<int,int>> ans;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (known[i][j] > 0) ans.push_back({i, j});\n        else if (known[i][j] < 0 && prob_oil_val[i][j] > 0.5) ans.push_back({i, j});\n    }\n    submit_answer(ans);\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <climits>\nusing namespace std;\n\nint W, D, N;\nvector<vector<int>> a;\n\nlong long day_def(int d, const vector<int>& h) {\n    long long c = 0;\n    for (int k = 0; k < N; k++) {\n        int area = h[k] * W;\n        if (a[d][k] > area) c += 100LL * (a[d][k] - area);\n    }\n    return c;\n}\n\nvoid get_bounds(const vector<int>& h, vector<int>& b) {\n    b.resize(N - 1);\n    int y = 0;\n    for (int k = 0; k < N - 1; k++) { y += h[k]; b[k] = y; }\n}\n\nlong long bound_diff(const vector<int>& b1, const vector<int>& b2) {\n    int i = 0, j = 0; long long c = 0;\n    while (i < (int)b1.size() && j < (int)b2.size()) {\n        if (b1[i] == b2[j]) { i++; j++; }\n        else if (b1[i] < b2[j]) { c++; i++; }\n        else { c++; j++; }\n    }\n    c += (int)b1.size() - i + (int)b2.size() - j;\n    return c;\n}\n\nvector<int> greedy_day(int d) {\n    vector<int> h(N, 1);\n    int rem = W - N;\n    while (rem > 0) {\n        int bk = -1; long long br = -1;\n        for (int k = 0; k < N; k++) {\n            int df = max(0, a[d][k] - h[k] * W);\n            int nd = max(0, a[d][k] - (h[k] + 1) * W);\n            long long r = df - nd;\n            if (r > br || (r == br && bk >= 0 && a[d][k] > a[d][bk])) { br = r; bk = k; }\n        }\n        if (bk == -1 || br == 0) {\n            int mx = -1; for (int k = 0; k < N; k++) if (a[d][k] > mx) { mx = a[d][k]; bk = k; }\n        }\n        if (bk == -1) break;\n        h[bk]++; rem--;\n    }\n    return h;\n}\n\nvector<int> adjust_toward(int d, vector<int> h, int max_iter=300) {\n    for (int iter = 0; iter < max_iter; iter++) {\n        int bk = -1; long long br = -1;\n        for (int k = 0; k < N; k++) {\n            int df = max(0, a[d][k] - h[k] * W);\n            int nd = max(0, a[d][k] - (h[k] + 1) * W);\n            long long r = df - nd;\n            if (r > br) { br = r; bk = k; }\n        }\n        if (bk == -1 || br == 0) break;\n        int bk2 = -1; long long min_inc = LLONG_MAX;\n        for (int k = 0; k < N; k++) {\n            if (h[k] > 1 && k != bk) {\n                int od = max(0, a[d][k] - h[k] * W); int nd = max(0, a[d][k] - (h[k] - 1) * W);\n                if (nd - od < min_inc) { min_inc = nd - od; bk2 = k; }\n            }\n        }\n        if (bk2 == -1) break;\n        h[bk]++; h[bk2]--;\n    }\n    return h;\n}\n\n// Morph from source layout toward target layout, recording intermediate candidates\nvector<vector<int>> morph_candidates(int d, const vector<int>& src, const vector<int>& tgt, int max_steps=20) {\n    vector<vector<int>> result;\n    vector<int> h = src;\n    vector<int> src_b, tgt_b;\n    get_bounds(src, src_b);\n    get_bounds(tgt, tgt_b);\n    \n    result.push_back(h);\n    \n    for (int step = 0; step < max_steps; step++) {\n        // Find the boundary with the largest difference from target\n        int best_b = -1, best_diff = 0;\n        for (int b = 0; b < N-1; b++) {\n            int diff = tgt_b[b] - src_b[b];\n            if (abs(diff) > abs(best_diff)) { best_diff = diff; best_b = b; }\n        }\n        if (best_b == -1 || best_diff == 0) break;\n        \n        int dir = (best_diff > 0) ? 1 : -1;\n        // Move boundary best_b by dir\n        int k1 = (dir > 0) ? best_b + 1 : best_b;\n        int k2 = (dir > 0) ? best_b : best_b + 1;\n        \n        if (h[k1] <= 1) break;\n        h[k1]--; h[k2]++;\n        src_b[best_b] += dir;\n        \n        // Adjust toward optimal for day d\n        h = adjust_toward(d, h, 5);\n        get_bounds(h, src_b);\n        \n        result.push_back(h);\n    }\n    \n    return result;\n}\n\nlong long total_cost(const vector<vector<int>>& h) {\n    long long c = 0;\n    for (int d = 0; d < D; d++) c += day_def(d, h[d]);\n    for (int d = 1; d < D; d++) {\n        vector<int> b1, b2;\n        get_bounds(h[d-1], b1); get_bounds(h[d], b2);\n        c += bound_diff(b1, b2) * W;\n    }\n    return c;\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> W >> D >> N;\n    a.resize(D, vector<int>(N));\n    for (int d = 0; d < D; d++) for (int k = 0; k < N; k++) cin >> a[d][k];\n    \n    mt19937 rng(42);\n    uniform_real_distribution<double> uni(0, 1);\n    \n    // Fixed layout\n    vector<int> fixed_h(N, 1);\n    { int rem = W - N;\n      while (rem > 0) {\n        int bk = -1; long long bs = -1;\n        for (int k = 0; k < N; k++) {\n            long long td = 0, ntd = 0;\n            for (int d = 0; d < D; d++) { td += max(0, a[d][k] - fixed_h[k] * W); ntd += max(0, a[d][k] - (fixed_h[k] + 1) * W); }\n            long long s = td - ntd;\n            if (s > bs) { bs = s; bk = k; }\n        }\n        if (bk == -1) break; fixed_h[bk]++; rem--;\n      }\n    }\n    \n    // Fixed layout SA\n    { vector<int> ch = fixed_h;\n      long long cc = 0; for (int d = 0; d < D; d++) cc += day_def(d, ch);\n      long long bc = cc; vector<int> bh = ch;\n      auto st = chrono::high_resolution_clock::now();\n      while (true) {\n        auto nw = chrono::high_resolution_clock::now();\n        double el = chrono::duration<double>(nw - st).count();\n        if (el > 0.05) break;\n        int k1 = rng() % N, k2 = rng() % N;\n        if (k1 == k2 || ch[k1] <= 1) continue;\n        long long delta = 0;\n        for (int d = 0; d < D; d++) {\n            delta += 100LL * (max(0, a[d][k1] - (ch[k1] - 1) * W) - max(0, a[d][k1] - ch[k1] * W));\n            delta += 100LL * (max(0, a[d][k2] - (ch[k2] + 1) * W) - max(0, a[d][k2] - ch[k2] * W));\n        }\n        double temp = 5e6 * max(1e-4, 1.0 - el / 0.05);\n        if (delta <= 0 || exp(-(double)delta / temp) > uni(rng)) {\n            ch[k1]--; ch[k2]++; cc += delta;\n            if (cc < bc) { bc = cc; bh = ch; }\n        }\n      }\n      fixed_h = bh;\n    }\n    \n    // Per-day greedy\n    vector<vector<int>> greedy_seq(D);\n    for (int d = 0; d < D; d++) greedy_seq[d] = greedy_day(d);\n    \n    // Generate candidates per day\n    vector<vector<vector<int>>> cands(D);\n    \n    for (int d = 0; d < D; d++) {\n        // Core candidates\n        cands[d].push_back(greedy_seq[d]);\n        cands[d].push_back(fixed_h);\n        cands[d].push_back(adjust_toward(d, fixed_h));\n        \n        // Min height candidates\n        vector<int> min_h(N);\n        int sum_min = 0;\n        for (int k = 0; k < N; k++) {\n            min_h[k] = (a[d][k] + W - 1) / W;\n            sum_min += min_h[k];\n        }\n        int extra = W - sum_min;\n        \n        if (extra >= 0) {\n            vector<int> h = min_h;\n            for (int k = 0; k < N && extra > 0; k++) { h[k] += extra; cands[d].push_back(adjust_toward(d, h)); h[k] -= extra; }\n            for (int i = 0; i < 20; i++) {\n                vector<int> hh = min_h; int rem = extra;\n                while (rem > 0) { hh[rng() % N]++; rem--; }\n                cands[d].push_back(adjust_toward(d, hh));\n            }\n        } else {\n            vector<int> ch = min_h; int rem = -extra;\n            while (rem > 0) {\n                int bk = -1; long long min_inc = LLONG_MAX;\n                for (int k = 0; k < N; k++) {\n                    if (ch[k] > 1) {\n                        int od = max(0, a[d][k] - ch[k] * W); int nd = max(0, a[d][k] - (ch[k] - 1) * W);\n                        if (nd - od < min_inc) { min_inc = nd - od; bk = k; }\n                    }\n                }\n                if (bk == -1) break; ch[bk]--; rem--;\n            }\n            cands[d].push_back(adjust_toward(d, ch));\n            for (int k = 0; k < N; k++) {\n                if (min_h[k] > 1) {\n                    vector<int> h = min_h; h[k]--;\n                    cands[d].push_back(adjust_toward(d, h, -extra));\n                }\n            }\n        }\n        \n        // Morph candidates from/to adjacent days\n        for (int dd = max(0, d-3); dd <= min(D-1, d+3); dd++) {\n            if (dd == d) continue;\n            auto morphed = morph_candidates(d, greedy_seq[d], greedy_seq[dd], 30);\n            for (auto& h : morphed) cands[d].push_back(h);\n            morphed = morph_candidates(d, greedy_seq[dd], greedy_seq[d], 30);\n            for (auto& h : morphed) cands[d].push_back(h);\n            \n            // Random perturbations from adjacent day's greedy\n            for (int i = 0; i < 5; i++) {\n                vector<int> h = greedy_seq[dd];\n                int rem = 5 + rng() % 10;\n                for (int j = 0; j < rem; j++) {\n                    int k1 = rng() % N, k2 = rng() % N;\n                    if (k1 != k2 && h[k1] > 1) { h[k1]--; h[k2]++; }\n                }\n                cands[d].push_back(adjust_toward(d, h, 50));\n            }\n        }\n        \n        // Morph from fixed layout\n        auto morphed = morph_candidates(d, fixed_h, greedy_seq[d], 30);\n        for (auto& h : morphed) cands[d].push_back(h);\n        \n        // Validate and deduplicate\n        vector<vector<int>> valid_cands;\n        for (auto& c : cands[d]) {\n            if ((int)c.size() != N) continue;\n            bool ok = true; int sum = 0;\n            for (int k = 0; k < N; k++) { if (c[k] < 1) { ok = false; break; } sum += c[k]; }\n            if (ok && sum == W) valid_cands.push_back(c);\n        }\n        cands[d] = valid_cands;\n        \n        sort(cands[d].begin(), cands[d].end());\n        cands[d].erase(unique(cands[d].begin(), cands[d].end()), cands[d].end());\n        \n        if ((int)cands[d].size() > 150) {\n            sort(cands[d].begin(), cands[d].end(), [&](const vector<int>& x, const vector<int>& y) {\n                return day_def(d, x) < day_def(d, y);\n            });\n            cands[d].resize(150);\n        }\n    }\n    \n    // DP\n    vector<int> ksz(D); int maxK = 0;\n    for (int d = 0; d < D; d++) { ksz[d] = cands[d].size(); maxK = max(maxK, ksz[d]); }\n    vector<vector<long long>> dp(D, vector<long long>(maxK, LLONG_MAX));\n    vector<vector<int>> par(D, vector<int>(maxK, -1));\n    vector<vector<long long>> cdef(D);\n    vector<vector<vector<int>>> cbnd(D);\n    \n    for (int d = 0; d < D; d++) {\n        cdef[d].resize(ksz[d]); cbnd[d].resize(ksz[d]);\n        for (int i = 0; i < ksz[d]; i++) { cdef[d][i] = day_def(d, cands[d][i]); get_bounds(cands[d][i], cbnd[d][i]); }\n    }\n    \n    for (int k = 0; k < ksz[0]; k++) dp[0][k] = cdef[0][k];\n    for (int d = 1; d < D; d++)\n        for (int k = 0; k < ksz[d]; k++)\n            for (int j = 0; j < ksz[d-1]; j++) {\n                if (dp[d-1][j] == LLONG_MAX) continue;\n                long long cost = dp[d-1][j] + bound_diff(cbnd[d-1][j], cbnd[d][k]) * W + cdef[d][k];\n                if (cost < dp[d][k]) { dp[d][k] = cost; par[d][k] = j; }\n            }\n    \n    long long best_dp = LLONG_MAX; int best_k = -1;\n    for (int k = 0; k < ksz[D-1]; k++) if (dp[D-1][k] < best_dp) { best_dp = dp[D-1][k]; best_k = k; }\n    vector<vector<int>> dp_res(D);\n    { int ck = best_k; for (int d = D-1; d >= 0; d--) { dp_res[d] = cands[d][ck]; ck = par[d][ck]; } }\n    \n    // SA\n    auto sa_run = [&](vector<vector<int>> cur_h, double time_limit, int seed) -> pair<long long, vector<vector<int>>> {\n        mt19937 local_rng(seed);\n        uniform_real_distribution<double> local_uni(0, 1);\n        \n        vector<vector<int>> cur_bnd(D);\n        vector<long long> pc_cache(D, 0);\n        for (int d = 0; d < D; d++) get_bounds(cur_h[d], cur_bnd[d]);\n        for (int d = 1; d < D; d++) pc_cache[d] = bound_diff(cur_bnd[d-1], cur_bnd[d]) * W;\n        \n        long long cur_cost = 0;\n        for (int d = 0; d < D; d++) cur_cost += day_def(d, cur_h[d]);\n        for (int d = 1; d < D; d++) cur_cost += pc_cache[d];\n        \n        long long best_cost = cur_cost;\n        vector<vector<int>> best_h = cur_h;\n        \n        auto st = chrono::high_resolution_clock::now();\n        long long iters = 0; double el = 0;\n        while (true) {\n            if (++iters % 5000 == 0) {\n                auto nw = chrono::high_resolution_clock::now();\n                el = chrono::duration<double>(nw - st).count();\n                if (el > time_limit) break;\n            }\n            \n            int move_type = local_rng() % 25;\n            \n            if (move_type < 18) {\n                int d = local_rng() % D, k1 = local_rng() % N, k2 = local_rng() % N;\n                if (k1 == k2 || cur_h[d][k1] <= 1) continue;\n                \n                long long dd = 100LL * (max(0, a[d][k1] - (cur_h[d][k1] - 1) * W) - max(0, a[d][k1] - cur_h[d][k1] * W))\n                              + 100LL * (max(0, a[d][k2] - (cur_h[d][k2] + 1) * W) - max(0, a[d][k2] - cur_h[d][k2] * W));\n                \n                cur_h[d][k1]--; cur_h[d][k2]++;\n                int lo = min(k1, k2), hi = max(k1, k2);\n                int dsign = (k1 < k2) ? -1 : 1;\n                for (int i = lo; i < hi; i++) cur_bnd[d][i] += dsign;\n                \n                long long npd = (d > 0 ? bound_diff(cur_bnd[d-1], cur_bnd[d]) * W : 0)\n                               + (d < D-1 ? bound_diff(cur_bnd[d], cur_bnd[d+1]) * W : 0);\n                long long opd = (d > 0 ? pc_cache[d] : 0) + (d < D-1 ? pc_cache[d+1] : 0);\n                long long delta = dd + npd - opd;\n                \n                double temp = 5e6 * max(1e-4, 1.0 - el / time_limit);\n                if (delta <= 0 || exp(-(double)delta / temp) > local_uni(local_rng)) {\n                    cur_cost += delta;\n                    if (d > 0) pc_cache[d] = bound_diff(cur_bnd[d-1], cur_bnd[d]) * W;\n                    if (d < D-1) pc_cache[d+1] = bound_diff(cur_bnd[d], cur_bnd[d+1]) * W;\n                    if (cur_cost < best_cost) { best_cost = cur_cost; best_h = cur_h; }\n                } else {\n                    cur_h[d][k1]++; cur_h[d][k2]--;\n                    for (int i = lo; i < hi; i++) cur_bnd[d][i] -= dsign;\n                }\n            } else if (move_type < 22) {\n                if (D < 2) continue;\n                int d = 1 + local_rng() % (D - 1);\n                int b = local_rng() % (N - 1);\n                int dir = (cur_bnd[d][b] < cur_bnd[d-1][b]) ? 1 : -1;\n                if (cur_bnd[d][b] == cur_bnd[d-1][b]) continue;\n                \n                int k1, k2;\n                if (dir > 0) { k1 = b + 1; k2 = b; } else { k1 = b; k2 = b + 1; }\n                if (cur_h[d][k1] <= 1) continue;\n                \n                long long dd = 100LL * (max(0, a[d][k1] - (cur_h[d][k1] - 1) * W) - max(0, a[d][k1] - cur_h[d][k1] * W))\n                              + 100LL * (max(0, a[d][k2] - (cur_h[d][k2] + 1) * W) - max(0, a[d][k2] - cur_h[d][k2] * W));\n                \n                cur_h[d][k1]--; cur_h[d][k2]++;\n                cur_bnd[d][b] += dir;\n                \n                long long npd = (d > 0 ? bound_diff(cur_bnd[d-1], cur_bnd[d]) * W : 0)\n                               + (d < D-1 ? bound_diff(cur_bnd[d], cur_bnd[d+1]) * W : 0);\n                long long opd = (d > 0 ? pc_cache[d] : 0) + (d < D-1 ? pc_cache[d+1] : 0);\n                long long delta = dd + npd - opd;\n                \n                double temp = 5e6 * max(1e-4, 1.0 - el / time_limit);\n                if (delta <= 0 || exp(-(double)delta / temp) > local_uni(local_rng)) {\n                    cur_cost += delta;\n                    if (d > 0) pc_cache[d] = bound_diff(cur_bnd[d-1], cur_bnd[d]) * W;\n                    if (d < D-1) pc_cache[d+1] = bound_diff(cur_bnd[d], cur_bnd[d+1]) * W;\n                    if (cur_cost < best_cost) { best_cost = cur_cost; best_h = cur_h; }\n                } else {\n                    cur_h[d][k1]++; cur_h[d][k2]--;\n                    cur_bnd[d][b] -= dir;\n                }\n            } else if (move_type < 24) {\n                int d = local_rng() % D, k1 = local_rng() % N, k2 = local_rng() % N;\n                if (k1 == k2) continue;\n                int units = 2 + local_rng() % 4;\n                if (cur_h[d][k1] <= units) continue;\n                \n                long long dd = 100LL * (max(0, a[d][k1] - (cur_h[d][k1] - units) * W) - max(0, a[d][k1] - cur_h[d][k1] * W))\n                              + 100LL * (max(0, a[d][k2] - (cur_h[d][k2] + units) * W) - max(0, a[d][k2] - cur_h[d][k2] * W));\n                \n                cur_h[d][k1] -= units; cur_h[d][k2] += units;\n                int lo = min(k1, k2), hi = max(k1, k2);\n                int dsign = (k1 < k2) ? -1 : 1;\n                for (int i = lo; i < hi; i++) cur_bnd[d][i] += dsign * units;\n                \n                long long npd = (d > 0 ? bound_diff(cur_bnd[d-1], cur_bnd[d]) * W : 0)\n                               + (d < D-1 ? bound_diff(cur_bnd[d], cur_bnd[d+1]) * W : 0);\n                long long opd = (d > 0 ? pc_cache[d] : 0) + (d < D-1 ? pc_cache[d+1] : 0);\n                long long delta = dd + npd - opd;\n                \n                double temp = 5e6 * max(1e-4, 1.0 - el / time_limit);\n                if (delta <= 0 || exp(-(double)delta / temp) > local_uni(local_rng)) {\n                    cur_cost += delta;\n                    if (d > 0) pc_cache[d] = bound_diff(cur_bnd[d-1], cur_bnd[d]) * W;\n                    if (d < D-1) pc_cache[d+1] = bound_diff(cur_bnd[d], cur_bnd[d+1]) * W;\n                    if (cur_cost < best_cost) { best_cost = cur_cost; best_h = cur_h; }\n                } else {\n                    cur_h[d][k1] += units; cur_h[d][k2] -= units;\n                    for (int i = lo; i < hi; i++) cur_bnd[d][i] -= dsign * units;\n                }\n            } else {\n                if (D < 2) continue;\n                int d = local_rng() % (D - 1);\n                int b = local_rng() % (N - 1);\n                int dir = (local_rng() % 2) ? 1 : -1;\n                \n                int k1_d = (dir > 0) ? b : b + 1;\n                int k2_d = (dir > 0) ? b + 1 : b;\n                \n                bool can_d = (dir > 0) ? (cur_h[d][b] > 1) : (cur_h[d][b+1] > 1);\n                bool can_d1 = (dir > 0) ? (cur_h[d+1][b] > 1) : (cur_h[d+1][b+1] > 1);\n                if (!can_d || !can_d1) continue;\n                \n                long long dd = 100LL * (max(0, a[d][k1_d] - (cur_h[d][k1_d] - 1) * W) - max(0, a[d][k1_d] - cur_h[d][k1_d] * W))\n                              + 100LL * (max(0, a[d][k2_d] - (cur_h[d][k2_d] + 1) * W) - max(0, a[d][k2_d] - cur_h[d][k2_d] * W))\n                              + 100LL * (max(0, a[d+1][k1_d] - (cur_h[d+1][k1_d] - 1) * W) - max(0, a[d+1][k1_d] - cur_h[d+1][k1_d] * W))\n                              + 100LL * (max(0, a[d+1][k2_d] - (cur_h[d+1][k2_d] + 1) * W) - max(0, a[d+1][k2_d] - cur_h[d+1][k2_d] * W));\n                \n                cur_h[d][k1_d]--; cur_h[d][k2_d]++;\n                cur_h[d+1][k1_d]--; cur_h[d+1][k2_d]++;\n                cur_bnd[d][b] -= dir;\n                cur_bnd[d+1][b] -= dir;\n                \n                long long npd = 0;\n                if (d > 0) npd += bound_diff(cur_bnd[d-1], cur_bnd[d]) * W;\n                npd += bound_diff(cur_bnd[d], cur_bnd[d+1]) * W;\n                if (d+1 < D-1) npd += bound_diff(cur_bnd[d+1], cur_bnd[d+2]) * W;\n                \n                long long opd = 0;\n                if (d > 0) opd += pc_cache[d];\n                opd += pc_cache[d+1];\n                if (d+1 < D-1) opd += pc_cache[d+2];\n                \n                long long delta = dd + npd - opd;\n                double temp = 5e6 * max(1e-4, 1.0 - el / time_limit);\n                if (delta <= 0 || exp(-(double)delta / temp) > local_uni(local_rng)) {\n                    cur_cost += delta;\n                    if (d > 0) pc_cache[d] = bound_diff(cur_bnd[d-1], cur_bnd[d]) * W;\n                    pc_cache[d+1] = bound_diff(cur_bnd[d], cur_bnd[d+1]) * W;\n                    if (d+1 < D-1) pc_cache[d+2] = bound_diff(cur_bnd[d+1], cur_bnd[d+2]) * W;\n                    if (cur_cost < best_cost) { best_cost = cur_cost; best_h = cur_h; }\n                } else {\n                    cur_h[d][k1_d]++; cur_h[d][k2_d]--;\n                    cur_h[d+1][k1_d]++; cur_h[d+1][k2_d]++;\n                    cur_bnd[d][b] += dir;\n                    cur_bnd[d+1][b] += dir;\n                }\n            }\n        }\n        return {best_cost, best_h};\n    };\n    \n    // Try multiple starting points\n    vector<pair<long long, vector<vector<int>>>> starts;\n    starts.push_back({total_cost(dp_res), dp_res});\n    starts.push_back({total_cost(vector<vector<int>>(D, fixed_h)), vector<vector<int>>(D, fixed_h)});\n    starts.push_back({total_cost(greedy_seq), greedy_seq});\n    sort(starts.begin(), starts.end());\n    \n    long long global_best_cost = starts[0].first;\n    vector<vector<int>> global_best_h = starts[0].second;\n    \n    auto total_st = chrono::high_resolution_clock::now();\n    double time_budget = 2.7;\n    \n    for (int s = 0; s < min(3, (int)starts.size()); s++) {\n        auto nw = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(nw - total_st).count();\n        if (elapsed > time_budget - 0.05) break;\n        double remaining = time_budget - elapsed - 0.05;\n        double alloc = remaining / max(1, min(3, (int)starts.size()) - s);\n        \n        auto [cost, h] = sa_run(starts[s].second, alloc, 42 + s * 1000);\n        if (cost < global_best_cost) {\n            global_best_cost = cost;\n            global_best_h = h;\n        }\n    }\n    \n    for (int d = 0; d < D; d++) {\n        int y = 0;\n        for (int k = 0; k < N; k++) { cout << y << \" 0 \" << y + global_best_h[d][k] << \" \" << W << \"\\n\"; y += global_best_h[d][k]; }\n    }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nlong long bmod[81];\nlong long a[81];\nlong long s_val[180];\nint ops[81];\nint op_p[81];\nint op_q[81];\nint L = 0;\n\nint best_ops[81], best_op_p[81], best_op_q[81];\nint best_L = 0;\nlong long best_total_score = 0;\n\nlong long best_score[9][10];\nlong long best_counts[9][10][20];\nlong long current_counts[20];\n\nstruct FastRNG {\n    unsigned long long x = 123456789, y = 362436069, z = 521288629;\n    unsigned long long operator()() {\n        unsigned long long t;\n        x ^= x << 16; x ^= x >> 5; x ^= x << 1;\n        t = x; x = y; y = z; z = t ^ x ^ y;\n        return z;\n    }\n};\n\nFastRNG rng;\n\nvoid dfs(int m, int remaining_ops, long long current_values[9], int used_ops, int subgrid_idx) {\n    long long score = 0;\n    for (int i = 0; i < 9; i++) score += current_values[i];\n    if (score > best_score[subgrid_idx][used_ops]) {\n        best_score[subgrid_idx][used_ops] = score;\n        memcpy(best_counts[subgrid_idx][used_ops], current_counts, sizeof(current_counts));\n    }\n    \n    if (remaining_ops == 0 || m == 20) return;\n\n    dfs(m + 1, remaining_ops, current_values, used_ops, subgrid_idx);\n\n    for (int i = 1; i <= remaining_ops; i++) {\n        current_counts[m]++;\n        for (int j = 0; j < 9; j++) {\n            current_values[j] += s_val[m * 9 + j];\n            if (current_values[j] >= MOD) current_values[j] -= MOD;\n        }\n        dfs(m + 1, remaining_ops - i, current_values, used_ops + i, subgrid_idx);\n    }\n    for (int i = 1; i <= remaining_ops; i++) {\n        current_counts[m]--;\n        for (int j = 0; j < 9; j++) {\n            current_values[j] -= s_val[m * 9 + j];\n            if (current_values[j] < 0) current_values[j] += MOD;\n        }\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 < 81; i++) cin >> a[i];\n    for (int m = 0; m < 20; m++)\n        for (int i = 0; i < 9; i++)\n            cin >> s_val[m * 9 + i];\n            \n    auto start_time = chrono::high_resolution_clock::now();\n    \n    // Phase 1: Exhaustive search for optimal independent subgrid configurations\n    for (int j = 0; j < 9; j++) {\n        int pj = (j / 3) * 3;\n        int qj = (j % 3) * 3;\n        long long initial_values[9];\n        for (int i = 0; i < 3; i++) {\n            for (int jj = 0; jj < 3; jj++) {\n                initial_values[i * 3 + jj] = a[(pj + i) * 9 + (qj + jj)];\n            }\n        }\n        memset(current_counts, 0, sizeof(current_counts));\n        memset(best_score[j], 0, sizeof(best_score[j]));\n        dfs(0, 9, initial_values, 0, j);\n    }\n    \n    // Phase 2: Knapsack DP to distribute operations optimally\n    long long dp[10][82];\n    int choice[10][82];\n    memset(dp, -1, sizeof(dp));\n    dp[0][0] = 0;\n    for (int i = 0; i < 9; i++) {\n        for (int k = 0; k <= 81; k++) {\n            if (dp[i][k] < 0) continue;\n            for (int kj = 0; kj <= 9; kj++) {\n                if (k + kj <= 81) {\n                    if (dp[i][k] + best_score[i][kj] > dp[i+1][k+kj]) {\n                        dp[i+1][k+kj] = dp[i][k] + best_score[i][kj];\n                        choice[i+1][k+kj] = kj;\n                    }\n                }\n            }\n        }\n    }\n    \n    long long max_total_score = 0;\n    int best_total_k = 0;\n    for (int k = 0; k <= 81; k++) {\n        if (dp[9][k] > max_total_score) {\n            max_total_score = dp[9][k];\n            best_total_k = k;\n        }\n    }\n    \n    int current_k = best_total_k;\n    int optimal_k[9];\n    for (int i = 8; i >= 0; i--) {\n        int kj = choice[i+1][current_k];\n        optimal_k[i] = kj;\n        current_k -= kj;\n    }\n    \n    // Build initial board and operations array from DP results\n    for (int i = 0; i < 81; i++) bmod[i] = a[i];\n    L = 0;\n    for (int j = 0; j < 9; j++) {\n        int pj = (j / 3) * 3;\n        int qj = (j % 3) * 3;\n        int kj = optimal_k[j];\n        for (int m = 0; m < 20; m++) {\n            for (int c = 0; c < best_counts[j][kj][m]; c++) {\n                ops[L] = m;\n                op_p[L] = pj;\n                op_q[L] = qj;\n                for (int i = 0; i < 3; i++) {\n                    for (int jj = 0; jj < 3; jj++) {\n                        int u = (pj + i) * 9 + (qj + jj);\n                        long long nv = bmod[u] + s_val[m * 9 + i * 3 + jj];\n                        if (nv >= MOD) nv -= MOD;\n                        bmod[u] = nv;\n                    }\n                }\n                L++;\n            }\n        }\n    }\n    \n    long long score = 0;\n    for (int i = 0; i < 81; i++) score += bmod[i];\n    \n    best_total_score = score;\n    best_L = L;\n    memcpy(best_ops, ops, L * sizeof(int));\n    memcpy(best_op_p, op_p, L * sizeof(int));\n    memcpy(best_op_q, op_q, L * sizeof(int));\n    \n    // Phase 3: Simulated Annealing for overlapping synergies\n    double start_temp = 1e10, end_temp = 1e4;\n    auto sa_start_time = chrono::high_resolution_clock::now();\n    double sa_time_limit = 1.9 - chrono::duration<double>(sa_start_time - start_time).count();\n    \n    int iter = 0;\n    while (true) {\n        iter++;\n        if (iter % 10000 == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - sa_start_time).count();\n            if (elapsed > sa_time_limit) break;\n        }\n        \n        double temp = start_temp * pow(end_temp / start_temp, min(1.0, chrono::duration<double>(chrono::high_resolution_clock::now() - sa_start_time).count() / sa_time_limit));\n        \n        int move_type = rng() % 100;\n        long long delta = 0;\n        \n        if (move_type < 20 && L < K) {\n            int new_m = rng() % 20;\n            int new_p = rng() % 7;\n            int new_q = rng() % 7;\n            \n            long long old_score = 0;\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) old_score += bmod[(new_p + i) * 9 + (new_q + j)];\n            \n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (new_p + i) * 9 + (new_q + j);\n                long long nv = bmod[u] + s_val[new_m * 9 + i * 3 + j];\n                if (nv >= MOD) nv -= MOD;\n                bmod[u] = nv;\n            }\n            \n            long long new_score = 0;\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) new_score += bmod[(new_p + i) * 9 + (new_q + j)];\n            \n            delta = new_score - old_score;\n            \n            if (delta >= 0 || (delta / temp > -20 && exp(delta / temp) > (double)(rng() % 1000000) / 1000000.0)) {\n                ops[L] = new_m; op_p[L] = new_p; op_q[L] = new_q;\n                L++;\n                score += delta;\n                if (score > best_total_score) {\n                    best_total_score = score; best_L = L;\n                    memcpy(best_ops, ops, L * sizeof(int));\n                    memcpy(best_op_p, op_p, L * sizeof(int));\n                    memcpy(best_op_q, op_q, L * sizeof(int));\n                }\n            } else {\n                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                    int u = (new_p + i) * 9 + (new_q + j);\n                    long long nv = bmod[u] - s_val[new_m * 9 + i * 3 + j];\n                    if (nv < 0) nv += MOD;\n                    bmod[u] = nv;\n                }\n            }\n        } else if (move_type < 30 && L > 0) {\n            int idx = rng() % L;\n            int old_m = ops[idx], old_p = op_p[idx], old_q = op_q[idx];\n            \n            long long old_score = 0;\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) old_score += bmod[(old_p + i) * 9 + (old_q + j)];\n            \n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (old_p + i) * 9 + (old_q + j);\n                long long nv = bmod[u] - s_val[old_m * 9 + i * 3 + j];\n                if (nv < 0) nv += MOD;\n                bmod[u] = nv;\n            }\n            \n            long long new_score = 0;\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) new_score += bmod[(old_p + i) * 9 + (old_q + j)];\n            \n            delta = new_score - old_score;\n            \n            if (delta >= 0 || (delta / temp > -20 && exp(delta / temp) > (double)(rng() % 1000000) / 1000000.0)) {\n                ops[idx] = ops[L - 1]; op_p[idx] = op_p[L - 1]; op_q[idx] = op_q[L - 1];\n                L--;\n                score += delta;\n                if (score > best_total_score) {\n                    best_total_score = score; best_L = L;\n                    memcpy(best_ops, ops, L * sizeof(int));\n                    memcpy(best_op_p, op_p, L * sizeof(int));\n                    memcpy(best_op_q, op_q, L * sizeof(int));\n                }\n            } else {\n                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                    int u = (old_p + i) * 9 + (old_q + j);\n                    long long nv = bmod[u] + s_val[old_m * 9 + i * 3 + j];\n                    if (nv >= MOD) nv -= MOD;\n                    bmod[u] = nv;\n                }\n            }\n        } else if (L > 0) {\n            int idx = rng() % L;\n            int old_m = ops[idx], old_p = op_p[idx], old_q = op_q[idx];\n            \n            int r = rng() % 5;\n            int new_m = old_m, new_p = old_p, new_q = old_q;\n            if (r == 0) new_m = rng() % 20;\n            else if (r == 1) new_p = rng() % 7;\n            else if (r == 2) new_q = rng() % 7;\n            else if (r == 3) { new_p = rng() % 7; new_q = rng() % 7; }\n            else { new_m = rng() % 20; new_p = rng() % 7; new_q = rng() % 7; }\n            \n            if (new_m == old_m && new_p == old_p && new_q == old_q) continue;\n            \n            bool affected[81] = {false};\n            int affected_list[18];\n            int affected_count = 0;\n            \n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (old_p + i) * 9 + (old_q + j);\n                if (!affected[u]) { affected[u] = true; affected_list[affected_count++] = u; }\n            }\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (new_p + i) * 9 + (new_q + j);\n                if (!affected[u]) { affected[u] = true; affected_list[affected_count++] = u; }\n            }\n            \n            long long old_score = 0;\n            for (int k = 0; k < affected_count; k++) old_score += bmod[affected_list[k]];\n            \n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (old_p + i) * 9 + (old_q + j);\n                long long nv = bmod[u] - s_val[old_m * 9 + i * 3 + j];\n                if (nv < 0) nv += MOD;\n                bmod[u] = nv;\n            }\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (new_p + i) * 9 + (new_q + j);\n                long long nv = bmod[u] + s_val[new_m * 9 + i * 3 + j];\n                if (nv >= MOD) nv -= MOD;\n                bmod[u] = nv;\n            }\n            \n            long long new_score = 0;\n            for (int k = 0; k < affected_count; k++) new_score += bmod[affected_list[k]];\n            \n            delta = new_score - old_score;\n            \n            if (delta >= 0 || (delta / temp > -20 && exp(delta / temp) > (double)(rng() % 1000000) / 1000000.0)) {\n                ops[idx] = new_m; op_p[idx] = new_p; op_q[idx] = new_q;\n                score += delta;\n                if (score > best_total_score) {\n                    best_total_score = score; best_L = L;\n                    memcpy(best_ops, ops, L * sizeof(int));\n                    memcpy(best_op_p, op_p, L * sizeof(int));\n                    memcpy(best_op_q, op_q, L * sizeof(int));\n                }\n            } else {\n                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                    int u = (new_p + i) * 9 + (new_q + j);\n                    long long nv = bmod[u] - s_val[new_m * 9 + i * 3 + j];\n                    if (nv < 0) nv += MOD;\n                    bmod[u] = nv;\n                }\n                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                    int u = (old_p + i) * 9 + (old_q + j);\n                    long long nv = bmod[u] + s_val[old_m * 9 + i * 3 + j];\n                    if (nv >= MOD) nv -= MOD;\n                    bmod[u] = nv;\n                }\n            }\n            for (int k = 0; k < affected_count; k++) affected[affected_list[k]] = false;\n        }\n    }\n    \n    cout << best_L << \"\\n\";\n    for (int i = 0; i < best_L; i++)\n        cout << best_ops[i] << \" \" << best_op_p[i] << \" \" << best_op_q[i] << \"\\n\";\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <climits>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N], grid[N][N];\nbool dispatched[N*N];\nint nxt_recv[N];\nint lr, lc, lh;\nint total_disp;\n\nint next_exp(int g) {\n    for (int j = 0; j < N; j++)\n        if (!dispatched[N*g+j]) return N*g+j;\n    return -1;\n}\n\nint main() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> A[i][j];\n    \n    memset(grid, -1, sizeof(grid));\n    fill(dispatched, dispatched+N*N, false);\n    fill(nxt_recv, nxt_recv+N, 0);\n    lr = 0; lc = 0; lh = -1; total_disp = 0;\n    \n    vector<string> acts(N);\n    // Turn 0: bomb small cranes to prevent deadlocks\n    for (int i = 0; i < N; i++) acts[i] += (i ? 'B' : '.');\n    \n    // Receive turn 0\n    for (int i = 0; i < N; i++)\n        if (nxt_recv[i] < N) grid[i][0] = A[i][nxt_recv[i]++];\n    \n    for (int t = 1; total_disp < N*N && (int)acts[0].size() < 9999; t++) {\n        // Step 1: Receive\n        for (int i = 0; i < N; i++) {\n            if (nxt_recv[i] < N && grid[i][0] == -1 && !(lr == i && lc == 0 && lh >= 0)) {\n                grid[i][0] = A[i][nxt_recv[i]++];\n            }\n        }\n        \n        // Step 2: Large crane action\n        char act = '.';\n        if (lh >= 0) {\n            // Holding: Deliver directly to the correct dispatch gate\n            int g = lh / N;\n            int tr = g, tc = N - 1;\n            \n            if (lr == tr && lc == tc) {\n                act = 'Q'; \n                grid[tr][tc] = lh; \n                lh = -1;\n            } else {\n                if (lr < tr) { lr++; act = 'D'; }\n                else if (lr > tr) { lr--; act = 'U'; }\n                else if (lc < tc) { lc++; act = 'R'; }\n                else { lc--; act = 'L'; }\n            }\n        } else {\n            // Not holding: Pick up the best available container\n            int bc = -1, bs = INT_MAX, br = -1, bcc = -1;\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    if (grid[r][c] < 0) continue;\n                    int co = grid[r][c], g = co / N, e = next_exp(g);\n                    int d = abs(lr - r) + abs(lc - c);\n                    int s;\n                    \n                    if (e >= 0 && e == co) s = -10000 + d; // Expected container (minimizes M1)\n                    else if (c == 0 && nxt_recv[r] < N) {\n                        int nc = A[r][nxt_recv[r]], ng = nc / N, ne = next_exp(ng);\n                        s = (ne >= 0 && ne == nc) ? -5000 + d : -1000 + d; // Blocks expected container\n                    } else if (c == 0) {\n                        s = -500 + d; // Blocks receiving gate\n                    } else {\n                        s = d + 500; // Other (shouldn't exist in this strategy)\n                    }\n                    \n                    if (s < bs) { bs = s; bc = co; br = r; bcc = c; }\n                }\n            }\n            \n            if (bc >= 0) {\n                if (lr == br && lc == bcc) {\n                    act = 'P'; \n                    lh = bc; \n                    grid[br][bcc] = -1;\n                } else {\n                    if (lr < br) { lr++; act = 'D'; }\n                    else if (lr > br) { lr--; act = 'U'; }\n                    else if (lc < bcc) { lc++; act = 'R'; }\n                    else { lc--; act = 'L'; }\n                }\n            }\n        }\n        \n        acts[0] += act;\n        for (int i = 1; i < N; i++) acts[i] += '.';\n        \n        // Step 3: Dispatch\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] >= 0) {\n                dispatched[grid[i][N-1]] = true;\n                grid[i][N-1] = -1;\n                total_disp++;\n            }\n        }\n    }\n    \n    int ml = 0;\n    for (int i = 0; i < N; i++) ml = max(ml, (int)acts[i].size());\n    for (int i = 0; i < N; i++) {\n        while ((int)acts[i].size() < ml) acts[i] += '.';\n        cout << acts[i] << endl;\n    }\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <climits>\n#include <algorithm>\nusing namespace std;\ntypedef long long ll;\nconst ll INF = 1e18;\nstruct Edge { int to, rev; ll cap, cost; };\nstruct MinCostFlow {\n    int n; vector<vector<Edge>> graph; vector<ll> h; vector<int> pv, pe;\n    MinCostFlow(int n):n(n),graph(n),h(n,0),pv(n),pe(n){}\n    void add_edge(int f,int t,ll cap,ll cost){\n        graph[f].push_back({t,(int)graph[t].size(),cap,cost});\n        graph[t].push_back({f,(int)graph[f].size()-1,0,-cost});\n    }\n    ll min_cost_flow(int s,int t,ll mf){\n        ll res=0,flow=0;\n        while(flow<mf){\n            priority_queue<pair<ll,int>,vector<pair<ll,int>>,greater<>>pq;\n            vector<ll>dist(n,INF);dist[s]=0;pq.push({0,s});\n            while(!pq.empty()){\n                auto[d,v]=pq.top();pq.pop();\n                if(dist[v]<d)continue;\n                for(int i=0;i<(int)graph[v].size();i++){\n                    Edge&e=graph[v][i];\n                    if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){\n                        dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];\n                        pv[e.to]=v;pe[e.to]=i;pq.push({dist[e.to],e.to});\n                    }\n                }\n            }\n            if(dist[t]==INF)break;\n            for(int v=0;v<n;v++)h[v]+=dist[v];\n            ll d=mf-flow;\n            for(int v=t;v!=s;v=pv[v])d=min(d,graph[pv[v]][pe[v]].cap);\n            flow+=d;res+=d*h[t];\n            for(int v=t;v!=s;v=pv[v]){\n                Edge&e=graph[pv[v]][pe[v]];e.cap-=d;graph[v][e.rev].cap+=d;\n            }\n        }\n        return res;\n    }\n};\nint main(){\n    ios_base::sync_with_stdio(false);cin.tie(NULL);\n    int n;cin>>n;\n    vector<vector<int>>h(n,vector<int>(n));\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++)cin>>h[i][j];\n    vector<pair<int,int>>sources,sinks;\n    vector<vector<int>>sid(n,vector<int>(n,-1)),kid(n,vector<int>(n,-1));\n    int tsup=0;\n    for(int i=0;i<n;i++)for(int j=0;j<n;j++){\n        if(h[i][j]>0){sid[i][j]=sources.size();sources.push_back({i,j});tsup+=h[i][j];}\n        else if(h[i][j]<0){kid[i][j]=sinks.size();sinks.push_back({i,j});}\n    }\n    int P=sources.size(),M=sinks.size();\n    int S=0,T=P+M+1;\n    MinCostFlow mcf(P+M+2);\n    for(int i=0;i<P;i++){auto[si,sj]=sources[i];mcf.add_edge(S,1+i,h[si][sj],0);}\n    for(int j=0;j<M;j++){auto[ti,tj]=sinks[j];mcf.add_edge(1+P+j,T,-h[ti][tj],0);}\n    for(int i=0;i<P;i++){auto[si,sj]=sources[i];\n        for(int j=0;j<M;j++){auto[ti,tj]=sinks[j];\n            ll d=abs(si-ti)+abs(sj-tj);\n            mcf.add_edge(1+i,1+P+j,min((ll)h[si][sj],(ll)-h[ti][tj]),d);\n        }\n    }\n    mcf.min_cost_flow(S,T,tsup);\n    vector<vector<int>>fa(P,vector<int>(M,0));\n    for(int i=0;i<P;i++)for(auto&e:mcf.graph[1+i])\n        if(e.to>=1+P&&e.to<1+P+M)fa[i][e.to-1-P]=(int)mcf.graph[e.to][e.rev].cap;\n    vector<int>snnd(P,0);\n    for(int i=0;i<P;i++){auto[si,sj]=sources[i];int best=INT_MAX;\n        for(int j=0;j<M;j++)if(fa[i][j]>0){auto[ti,tj]=sinks[j];best=min(best,abs(si-ti)+abs(sj-tj));}\n        snnd[i]=(best<INT_MAX)?best:0;\n    }\n    vector<string>ops;int r=0,c=0,load=0,rem=tsup;\n    auto cur=h;\n    while(ops.size()<100000&&(rem>0||load>0)){\n        if(cur[r][c]>0){ops.push_back(\"+\"+to_string(cur[r][c]));load+=cur[r][c];rem-=cur[r][c];cur[r][c]=0;}\n        while(cur[r][c]<0&&load>0){int d=min(load,-cur[r][c]);ops.push_back(\"-\"+to_string(d));load-=d;cur[r][c]+=d;}\n        if(rem==0&&load==0)break;\n        int br=-1,bc=-1;ll bcost=LLONG_MAX;\n        if(load>0){\n            for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(cur[i][j]<0){\n                int d=abs(r-i)+abs(c-j);ll cost=(ll)d*(100+load);\n                if(cost<bcost){bcost=cost;br=i;bc=j;}\n            }\n        }else{\n            for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(cur[i][j]>0){\n                int dt=abs(r-i)+abs(c-j);int s=sid[i][j];\n                int dd=(s>=0)?snnd[s]:20;\n                ll cost=(ll)dt*100+(ll)dd*(100+cur[i][j]);\n                if(cost<bcost){bcost=cost;br=i;bc=j;}\n            }\n        }\n        if(br==-1)break;\n        if(br<r){r--;ops.push_back(\"U\");}\n        else if(br>r){r++;ops.push_back(\"D\");}\n        else if(bc<c){c--;ops.push_back(\"L\");}\n        else{c++;ops.push_back(\"R\");}\n    }\n    for(auto&op:ops)cout<<op<<\"\\n\";\n}","ahc035":"#include <iostream>\n#include <algorithm>\n#include <numeric>\n#include <chrono>\n#include <cstring>\n#include <cmath>\n\nusing namespace std;\n\nstruct RNG {\n    unsigned long long s[2];\n    RNG() : s{0x123456789ABCDEF0ULL, 0xFEDCBA9876543210ULL} {}\n    unsigned long long next() {\n        unsigned long long s1 = s[0]; unsigned long long s0 = s[1];\n        unsigned long long result = s0 + s1;\n        s[0] = s0; s1 ^= s1 << 23;\n        s[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5);\n        return result;\n    }\n    int nextInt(int n) { return (int)(next() % (unsigned long long)n); }\n    double nextDouble() { return (double)(next() >> 11) * 0x1.0p-53; }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    const int N=6,M=15,SC=60,GS=36,NE=60;\n    int n,mm,t; cin>>n>>mm>>t;\n    int X[SC][M];\n    for(int i=0;i<SC;i++) for(int j=0;j<M;j++) cin>>X[i][j];\n    int eu[NE],ev[NE]; int ei=0;\n    for(int i=0;i<N;i++) for(int j=0;j<N-1;j++){eu[ei]=i*N+j;ev[ei]=i*N+j+1;ei++;}\n    for(int i=0;i<N-1;i++) for(int j=0;j<N;j++){eu[ei]=i*N+j;ev[ei]=(i+1)*N+j;ei++;}\n    int pec[GS],pel[GS][4],pnc[GS],pnl[GS][4];\n    memset(pec,0,sizeof(pec)); memset(pnc,0,sizeof(pnc));\n    for(int e=0;e<NE;e++){\n        pel[eu[e]][pec[eu[e]]++]=e; pel[ev[e]][pec[ev[e]]++]=e;\n        pnl[eu[e]][pnc[eu[e]]++]=ev[e]; pnl[ev[e]][pnc[ev[e]]++]=eu[e];\n    }\n    int po[GS]; iota(po,po+GS,0);\n    sort(po,po+GS,[](int a,int b){\n        int da=abs(2*(a/N)-5)+abs(2*(a%N)-5), db=abs(2*(b/N)-5)+abs(2*(b%N)-5);\n        return da!=db?da<db:a<b;\n    });\n    const int EXP_SZ=10001; double expT[EXP_SZ];\n    for(int i=0;i<EXP_SZ;i++) expT[i]=exp(-(double)i/100.0);\n    RNG rng;\n    for(int turn=0;turn<t;turn++){\n        int val[SC]={}; for(int i=0;i<SC;i++) for(int j=0;j<M;j++) val[i]+=X[i][j];\n        int pot[SC][SC]={};\n        for(int i=0;i<SC;i++) for(int j=i+1;j<SC;j++){\n            int s=0; for(int l=0;l<M;l++) s+=max(X[i][l],X[j][l]);\n            pot[i][j]=pot[j][i]=s;\n        }\n        int bestGrid[GS],bestScore=-1; bool bestUsed[SC]={}; int bestUn[SC-GS]; int bestUnc=0;\n        for(int strategy=0;strategy<2;strategy++){\n            int grid[GS]; bool used[SC]={}; bool pf[GS]={};\n            if(strategy==0){\n                for(int idx=0;idx<GS;idx++){\n                    int pos=po[idx]; int bs=-1,bsc=-1;\n                    for(int s=0;s<SC;s++){\n                        if(used[s])continue;\n                        int sc=0;\n                        for(int ni=0;ni<pnc[pos];ni++){int np=pnl[pos][ni];if(pf[np])sc+=pot[s][grid[np]];}\n                        if(sc==0) sc=val[s];\n                        if(sc>bsc){bsc=sc;bs=s;}\n                    }\n                    grid[pos]=bs;used[bs]=true;pf[pos]=true;\n                }\n            } else {\n                int ba=0,bb=1,bp=pot[0][1];\n                for(int i=0;i<SC;i++) for(int j=i+1;j<SC;j++) if(pot[i][j]>bp){bp=pot[i][j];ba=i;bb=j;}\n                grid[14]=ba;used[ba]=true;pf[14]=true; grid[15]=bb;used[bb]=true;pf[15]=true;\n                for(int idx=0;idx<GS;idx++){\n                    int pos=po[idx]; if(pf[pos])continue; int bs=-1,bsc=-1;\n                    for(int s=0;s<SC;s++){\n                        if(used[s])continue;\n                        int sc=0;\n                        for(int ni=0;ni<pnc[pos];ni++){int np=pnl[pos][ni];if(pf[np])sc+=pot[s][grid[np]];}\n                        if(sc==0) sc=val[s];\n                        if(sc>bsc){bsc=sc;bs=s;}\n                    }\n                    grid[pos]=bs;used[bs]=true;pf[pos]=true;\n                }\n            }\n            int sc=0; for(int e=0;e<NE;e++) sc+=pot[grid[eu[e]]][grid[ev[e]]];\n            if(sc>bestScore){bestScore=sc;memcpy(bestGrid,grid,sizeof(grid));\n                memcpy(bestUsed,used,sizeof(used));bestUnc=0;\n                for(int i=0;i<SC;i++) if(!used[i]) bestUn[bestUnc++]=i;}\n        }\n        int grid[GS]; memcpy(grid,bestGrid,sizeof(grid));\n        bool used[SC]; memcpy(used,bestUsed,sizeof(used));\n        int un[SC-GS]; int unc=bestUnc; memcpy(un,bestUn,sizeof(int)*unc);\n        int cs=bestScore,bs=cs; int bg[GS]; memcpy(bg,grid,sizeof(grid));\n        auto st=chrono::high_resolution_clock::now(); double invT=1.0/500.0;\n        for(int iter=0;iter<200000000;iter++){\n            if((iter&0x3FFF)==0){\n                auto el=chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now()-st).count();\n                if(el>180000)break;\n                double p=(double)el/180000.0; double tmp=500.0*pow(0.1/500.0,p); invT=1.0/tmp;\n            }\n            if(rng.next()&3){\n                int i=rng.nextInt(GS),j=rng.nextInt(GS); if(i==j)continue;\n                int delta=0;\n                for(int k=0;k<pec[i];k++){int e=pel[i][k];delta-=pot[grid[eu[e]]][grid[ev[e]]];}\n                for(int k=0;k<pec[j];k++){int e=pel[j][k];delta-=pot[grid[eu[e]]][grid[ev[e]]];}\n                swap(grid[i],grid[j]);\n                for(int k=0;k<pec[i];k++){int e=pel[i][k];delta+=pot[grid[eu[e]]][grid[ev[e]]];}\n                for(int k=0;k<pec[j];k++){int e=pel[j][k];delta+=pot[grid[eu[e]]][grid[ev[e]]];}\n                if(delta>=0){cs+=delta;if(cs>bs){bs=cs;memcpy(bg,grid,sizeof(grid));}}\n                else{int idx=(int)(-delta*invT*100.0);\n                    if(idx<EXP_SZ&&rng.nextDouble()<expT[idx]){cs+=delta;if(cs>bs){bs=cs;memcpy(bg,grid,sizeof(grid));}}\n                    else swap(grid[i],grid[j]);}\n            } else {\n                int pos=rng.nextInt(GS); int os=grid[pos]; int ui=rng.nextInt(unc); int ns=un[ui];\n                int delta=0;\n                for(int k=0;k<pec[pos];k++){int e=pel[pos][k];delta-=pot[grid[eu[e]]][grid[ev[e]]];}\n                grid[pos]=ns;\n                for(int k=0;k<pec[pos];k++){int e=pel[pos][k];delta+=pot[grid[eu[e]]][grid[ev[e]]];}\n                if(delta>=0){cs+=delta;used[os]=false;used[ns]=true;un[ui]=os;\n                    if(cs>bs){bs=cs;memcpy(bg,grid,sizeof(grid));}}\n                else{int idx=(int)(-delta*invT*100.0);\n                    if(idx<EXP_SZ&&rng.nextDouble()<expT[idx]){cs+=delta;used[os]=false;used[ns]=true;un[ui]=os;\n                        if(cs>bs){bs=cs;memcpy(bg,grid,sizeof(grid));}}\n                    else grid[pos]=os;}\n            }\n        }\n        memcpy(grid,bg,sizeof(grid));\n        for(int i=0;i<N;i++){for(int j=0;j<N;j++){cout<<grid[i*N+j];if(j<N-1)cout<<\" \";}cout<<\"\\n\";}\n        cout.flush();\n        for(int i=0;i<SC;i++) for(int j=0;j<M;j++) cin>>X[i][j];\n    }\n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\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), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n    \n    int Vp = V;\n    vector<int> len(Vp, 1);\n    int idx = 1;\n    for (int l = 1; idx < Vp; l++) {\n        int cnt = (l <= 3) ? 2 : 1;\n        for (int k = 0; k < cnt && idx < Vp; k++) {\n            len[idx++] = min(l, N / 2);\n        }\n    }\n    \n    cout << Vp << \"\\n\";\n    for (int i = 1; i < Vp; i++) cout << 0 << \" \" << len[i] << \"\\n\";\n    \n    vector<vector<int>> grid(N, vector<int>(N)), target(N, vector<int>(N));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = s[i][j] - '0';\n            target[i][j] = t[i][j] - '0';\n        }\n    \n    vector<pair<int,int>> sources, targets;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] && !target[i][j]) sources.push_back({i, j});\n            if (!grid[i][j] && target[i][j]) targets.push_back({i, j});\n        }\n    \n    int Mm = sources.size();\n    if (Mm == 0) {\n        cout << N/2 << \" \" << N/2 << \"\\n\";\n        return 0;\n    }\n    \n    // Cluster sources\n    vector<int> s_cluster(Mm, -1);\n    int num_s_clusters = 0;\n    for (int i = 0; i < Mm; i++) {\n        if (s_cluster[i] != -1) continue;\n        queue<int> q; q.push(i); s_cluster[i] = num_s_clusters;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v = 0; v < Mm; v++) {\n                if (s_cluster[v] != -1) continue;\n                if (abs(sources[u].first - sources[v].first) + abs(sources[u].second - sources[v].second) <= 6) {\n                    s_cluster[v] = num_s_clusters; q.push(v);\n                }\n            }\n        }\n        num_s_clusters++;\n    }\n\n    // Cluster targets\n    vector<int> t_cluster(Mm, -1);\n    int num_t_clusters = 0;\n    for (int i = 0; i < Mm; i++) {\n        if (t_cluster[i] != -1) continue;\n        queue<int> q; q.push(i); t_cluster[i] = num_t_clusters;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v = 0; v < Mm; v++) {\n                if (t_cluster[v] != -1) continue;\n                if (abs(targets[u].first - targets[v].first) + abs(targets[u].second - targets[v].second) <= 6) {\n                    t_cluster[v] = num_t_clusters; q.push(v);\n                }\n            }\n        }\n        num_t_clusters++;\n    }\n    \n    vector<pair<long long, long long>> s_center(num_s_clusters, {0, 0});\n    vector<int> s_count(num_s_clusters, 0);\n    for (int i = 0; i < Mm; i++) {\n        s_center[s_cluster[i]].first += sources[i].first;\n        s_center[s_cluster[i]].second += sources[i].second;\n        s_count[s_cluster[i]]++;\n    }\n    for (int i = 0; i < num_s_clusters; i++) { s_center[i].first /= s_count[i]; s_center[i].second /= s_count[i]; }\n    \n    vector<pair<long long, long long>> t_center(num_t_clusters, {0, 0});\n    vector<int> t_count(num_t_clusters, 0);\n    for (int i = 0; i < Mm; i++) {\n        t_center[t_cluster[i]].first += targets[i].first;\n        t_center[t_cluster[i]].second += targets[i].second;\n        t_count[t_cluster[i]]++;\n    }\n    for (int i = 0; i < num_t_clusters; i++) { t_center[i].first /= t_count[i]; t_center[i].second /= t_count[i]; }\n    \n    vector<int> cluster_match(num_s_clusters, -1);\n    vector<bool> t_cluster_used(num_t_clusters, false);\n    vector<int> s_cluster_order(num_s_clusters);\n    iota(s_cluster_order.begin(), s_cluster_order.end(), 0);\n    sort(s_cluster_order.begin(), s_cluster_order.end(), [&](int a, int b) { return s_count[a] > s_count[b]; });\n    \n    for (int i : s_cluster_order) {\n        long long best_dist = 1e18; int best_t = -1;\n        for (int j = 0; j < num_t_clusters; j++) {\n            if (t_cluster_used[j]) continue;\n            long long dist = abs(s_center[i].first - t_center[j].first) + abs(s_center[i].second - t_center[j].second);\n            if (dist < best_dist) { best_dist = dist; best_t = j; }\n        }\n        if (best_t != -1) { cluster_match[i] = best_t; t_cluster_used[best_t] = true; }\n    }\n    \n    vector<int> match(Mm, -1);\n    vector<bool> sused(Mm, false), tused(Mm, false);\n    \n    for (int i = 0; i < num_s_clusters; i++) {\n        if (cluster_match[i] == -1) continue;\n        int j = cluster_match[i];\n        vector<int> s_indices, t_indices;\n        for (int k = 0; k < Mm; k++) {\n            if (s_cluster[k] == i) s_indices.push_back(k);\n            if (t_cluster[k] == j) t_indices.push_back(k);\n        }\n        vector<tuple<int,int,int>> pairs;\n        for (int si : s_indices) {\n            for (int ti : t_indices) {\n                if (tused[ti]) continue;\n                pairs.push_back({abs(sources[si].first - targets[ti].first) + abs(sources[si].second - targets[ti].second), si, ti});\n            }\n        }\n        sort(pairs.begin(), pairs.end());\n        for (auto& [d, si, ti] : pairs) {\n            if (!sused[si] && !tused[ti]) { match[si] = ti; sused[si] = true; tused[ti] = true; }\n        }\n    }\n    \n    vector<tuple<int,int,int>> pairs;\n    for (int i = 0; i < Mm; i++) {\n        if (sused[i]) continue;\n        for (int j = 0; j < Mm; j++) {\n            if (tused[j]) continue;\n            pairs.push_back({abs(sources[i].first - targets[j].first) + abs(sources[i].second - targets[j].second), i, j});\n        }\n    }\n    sort(pairs.begin(), pairs.end());\n    for (auto& [d, i, j] : pairs) {\n        if (!sused[i] && !tused[j]) { match[i] = j; sused[i] = true; tused[j] = true; }\n    }\n    \n    int best_cluster = max_element(s_count.begin(), s_count.end()) - s_count.begin();\n    int rx = s_center[best_cluster].first;\n    int ry = s_center[best_cluster].second;\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<int> dir(Vp, 0);\n    vector<bool> available_s(Mm, true);\n    vector<int> finger_state(Vp, 0); // 0: IDLE, 1: TO_SOURCE, 2: TO_TARGET\n    vector<int> finger_task(Vp, -1);\n    vector<int> f_target_x(Vp), f_target_y(Vp), f_target_dir(Vp);\n    vector<string> ops;\n    \n    auto get_best_station = [&](int rx, int ry, int f, int cell_x, int cell_y) {\n        int best_cost = INT_MAX, best_nx = -1, best_ny = -1, best_dir = -1;\n        for (int d = 0; d < 4; d++) {\n            int nx = cell_x - dx[d] * len[f], ny = cell_y - dy[d] * len[f];\n            if (0 <= nx && nx < N && 0 <= ny && ny < N) {\n                int dist = abs(rx - nx) + abs(ry - ny);\n                int rot = min((dir[f] - d + 4) % 4, (d - dir[f] + 4) % 4);\n                int cost = max(dist, rot) * 10 + rot;\n                if (cost < best_cost) { best_cost = cost; best_nx = nx; best_ny = ny; best_dir = d; }\n            }\n        }\n        return make_tuple(best_nx, best_ny, best_dir, best_cost);\n    };\n    \n    while (true) {\n        bool any_idle = false;\n        for (int f = 1; f < Vp; f++) if (finger_state[f] == 0) { any_idle = true; break; }\n        \n        if (any_idle) {\n            int min_dist_to_pending = INT_MAX;\n            for (int f2 = 1; f2 < Vp; f2++) {\n                if (finger_state[f2] != 0) {\n                    int d = abs(rx - f_target_x[f2]) + abs(ry - f_target_y[f2]);\n                    min_dist_to_pending = min(min_dist_to_pending, d);\n                }\n            }\n            int max_accept_dist = (min_dist_to_pending == INT_MAX) ? INT_MAX : min_dist_to_pending + N / 2;\n\n            for (int f = 1; f < Vp; f++) {\n                if (finger_state[f] == 0) {\n                    int min_d = INT_MAX, best_s = -1, b_nx, b_ny, b_dir;\n                    for (int i = 0; i < Mm; i++) {\n                        if (!available_s[i]) continue;\n                        auto [nx, ny, d, cost] = get_best_station(rx, ry, f, sources[i].first, sources[i].second);\n                        if (cost < min_d && cost <= max_accept_dist) {\n                            min_d = cost; best_s = i; b_nx = nx; b_ny = ny; b_dir = d;\n                        }\n                    }\n                    if (best_s != -1) {\n                        finger_state[f] = 1; finger_task[f] = best_s; available_s[best_s] = false;\n                        f_target_x[f] = b_nx; f_target_y[f] = b_ny; f_target_dir[f] = b_dir;\n                    }\n                }\n            }\n        }\n\n        bool any_pending = false, any_available = false;\n        for (int f = 1; f < Vp; f++) if (finger_state[f] != 0) any_pending = true;\n        for (int i = 0; i < Mm; i++) if (available_s[i]) any_available = true;\n        if (!any_pending && !any_available) break;\n\n        int best_dist = INT_MAX, best_f = -1;\n        for (int f = 1; f < Vp; f++) {\n            if (finger_state[f] == 0) continue;\n            int dist = abs(rx - f_target_x[f]) + abs(ry - f_target_y[f]);\n            if (dist < best_dist) { best_dist = dist; best_f = f; }\n        }\n\n        string op(2 * Vp, '.');\n        if (best_f != -1) {\n            if (rx < f_target_x[best_f]) { op[0] = 'D'; rx++; }\n            else if (rx > f_target_x[best_f]) { op[0] = 'U'; rx--; }\n            else if (ry < f_target_y[best_f]) { op[0] = 'R'; ry++; }\n            else if (ry > f_target_y[best_f]) { op[0] = 'L'; ry--; }\n        }\n\n        for (int f = 1; f < Vp; f++) {\n            if (finger_state[f] == 0) continue;\n            if (dir[f] != f_target_dir[f]) {\n                int diff = (f_target_dir[f] - dir[f] + 4) % 4;\n                if (diff <= 2) { op[f] = 'R'; dir[f] = (dir[f] + 1) % 4; }\n                else { op[f] = 'L'; dir[f] = (dir[f] + 3) % 4; }\n            }\n        }\n\n        for (int f = 1; f < Vp; f++) {\n            if (finger_state[f] == 0) continue;\n            if (rx == f_target_x[f] && ry == f_target_y[f] && dir[f] == f_target_dir[f]) {\n                op[Vp + f] = 'P';\n                if (finger_state[f] == 1) {\n                    int s_idx = finger_task[f];\n                    grid[sources[s_idx].first][sources[s_idx].second] = 0;\n                    finger_state[f] = 2;\n                    auto [nx, ny, d, cost] = get_best_station(rx, ry, f, targets[match[s_idx]].first, targets[match[s_idx]].second);\n                    f_target_x[f] = nx; f_target_y[f] = ny; f_target_dir[f] = d;\n                } else {\n                    int s_idx = finger_task[f]; int t_idx = match[s_idx];\n                    grid[targets[t_idx].first][targets[t_idx].second] = 1;\n                    finger_state[f] = 0;\n                }\n            }\n        }\n        ops.push_back(op);\n    }\n    \n    for (auto& op : ops) cout << op << \"\\n\";\n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct GridRect { int score, x1, y1, x2, y2; };\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; cin >> N;\n    vector<int> fx(2*N), fy(2*N), val(2*N);\n    for (int i = 0; i < 2*N; i++) {\n        cin >> fx[i] >> fy[i];\n        val[i] = (i < N) ? 1 : -1;\n    }\n    \n    int GS = 700, CS = 143;\n    vector<vector<int>> grid(GS, vector<int>(GS, 0));\n    for (int i = 0; i < 2*N; i++) {\n        int gx = min(fx[i] / CS, GS - 1);\n        int gy = min(fy[i] / CS, GS - 1);\n        grid[gx][gy] += val[i];\n    }\n    \n    vector<GridRect> grid_rects;\n    for (int gx1 = 0; gx1 < GS; gx1++) {\n        vector<int> col_sums(GS, 0);\n        for (int gx2 = gx1; gx2 < GS; gx2++) {\n            for (int gy = 0; gy < GS; gy++) {\n                col_sums[gy] += grid[gx2][gy];\n            }\n            int cur = 0, best = 0, cy1 = 0, by1 = 0, by2 = -1;\n            for (int gy2 = 0; gy2 < GS; gy2++) {\n                cur += col_sums[gy2];\n                if (cur > best) { best = cur; by1 = cy1; by2 = gy2; }\n                if (cur < 0) { cur = 0; cy1 = gy2 + 1; }\n            }\n            if (best > 0) grid_rects.push_back({best, gx1, by1, gx2, by2});\n        }\n    }\n    sort(grid_rects.begin(), grid_rects.end(), [](const GridRect& a, const GridRect& b) { return a.score > b.score; });\n    \n    int best_exact_score = 0;\n    int final_x1 = 0, final_y1 = 0, final_x2 = 0, final_y2 = 0;\n    for (int k = 0; k < min(20, (int)grid_rects.size()); k++) {\n        int bestX1 = grid_rects[k].x1 * CS;\n        int bestY1 = grid_rects[k].y1 * CS;\n        int bestX2 = min((grid_rects[k].x2 + 1) * CS, 100000);\n        int bestY2 = min((grid_rects[k].y2 + 1) * CS, 100000);\n        \n        for (int iter = 0; iter < 20; iter++) {\n            for (int dim = 0; dim < 2; dim++) {\n                vector<pair<int, int>> ev;\n                for (int i = 0; i < 2 * N; i++) {\n                    bool inside = (dim == 0) ? (fx[i] >= bestX1 && fx[i] <= bestX2) : (fy[i] >= bestY1 && fy[i] <= bestY2);\n                    if (inside) ev.push_back({(dim == 0) ? fy[i] : fx[i], val[i]});\n                }\n                sort(ev.begin(), ev.end());\n                \n                // Group coordinates to fix the 1D overestimation bug\n                vector<pair<int, int>> ev_unique;\n                for (int i = 0; i < (int)ev.size(); i++) {\n                    if (i > 0 && ev[i].first == ev[i-1].first) {\n                        ev_unique.back().second += ev[i].second;\n                    } else {\n                        ev_unique.push_back(ev[i]);\n                    }\n                }\n                \n                int bs = -1000000000, b1 = (dim == 0) ? bestY1 : bestX1, b2 = (dim == 0) ? bestY2 : bestX2;\n                int mp = 0, mpi = -1, pfx = 0;\n                for (int j = 0; j <= (int)ev_unique.size(); j++) {\n                    int s = pfx - mp;\n                    if (s > bs) {\n                        bs = s;\n                        b1 = (mpi == -1) ? 0 : ev_unique[mpi].first;\n                        b2 = (j == (int)ev_unique.size()) ? 100000 : ev_unique[j - 1].first;\n                    }\n                    if (pfx < mp) {\n                        mp = pfx;\n                        mpi = j;\n                    }\n                    if (j < (int)ev_unique.size()) pfx += ev_unique[j].second;\n                }\n                \n                if (dim == 0) { bestY1 = b1; bestY2 = b2; } else { bestX1 = b1; bestX2 = b2; }\n            }\n        }\n        \n        int current_score = 0;\n        for (int i = 0; i < 2 * N; i++) {\n            if (fx[i] >= bestX1 && fx[i] <= bestX2 && fy[i] >= bestY1 && fy[i] <= bestY2) {\n                current_score += val[i];\n            }\n        }\n        \n        if (current_score > best_exact_score) {\n            best_exact_score = current_score;\n            final_x1 = bestX1; final_y1 = bestY1;\n            final_x2 = bestX2; final_y2 = bestY2;\n        }\n    }\n    \n    if (best_exact_score > 0) {\n        cout << 4 << \"\\n\" << final_x1 << \" \" << final_y1 << \"\\n\"\n             << final_x2 << \" \" << final_y1 << \"\\n\"\n             << final_x2 << \" \" << final_y2 << \"\\n\"\n             << final_x1 << \" \" << final_y2 << \"\\n\";\n    } else {\n        cout << 4 << \"\\n50000 50000\\n50001 50000\\n50001 50001\\n50000 50001\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\nint N,T,sigma;\nvector<long long>w_obs,h_obs;\nvector<double>w_est,h_est;\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    cin>>N>>T>>sigma;\n    w_obs.resize(N);h_obs.resize(N);w_est.resize(N);h_est.resize(N);\n    for(int i=0;i<N;i++){cin>>w_obs[i]>>h_obs[i];w_est[i]=w_obs[i];h_est[i]=h_obs[i];}\n    mt19937 rng(42);\n    auto start=chrono::steady_clock::now();\n    for(int t=0;t<T;t++){\n        auto now=chrono::steady_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-start).count()>2700)break;\n        vector<long long>wc(N),hc(N);\n        for(int i=0;i<N;i++){wc[i]=max(1LL,(long long)round(w_est[i]));hc[i]=max(1LL,(long long)round(h_est[i]));}\n        vector<long long>px,py,pw,ph;vector<int>plc;vector<tuple<int,int,char,int>>out;\n        long long cW=0,cH=0;\n        bool doRow=(t==0&&T>=20),doCol=(t==1&&T>=20);\n        if(doRow){\n            for(int i=0;i<N;i++){\n                long long rw=wc[i],rh=hc[i],rx=(i==0)?0:px[i-1]+pw[i-1],ry=0LL;\n                px.push_back(rx);py.push_back(ry);pw.push_back(rw);ph.push_back(rh);plc.push_back(i);\n                out.push_back({i,0,'U',(i==0)?-1:(i-1)});cW=max(cW,rx+rw);cH=max(cH,ry+rh);\n            }\n        }else if(doCol){\n            for(int i=0;i<N;i++){\n                long long rw=wc[i],rh=hc[i],ry=(i==0)?0:py[i-1]+ph[i-1],rx=0LL;\n                px.push_back(rx);py.push_back(ry);pw.push_back(rw);ph.push_back(rh);plc.push_back(i);\n                out.push_back({i,0,'L',(i==0)?-1:(i-1)});cW=max(cW,rx+rw);cH=max(cH,ry+rh);\n            }\n        }else{\n            int strat=t%5;bool addN=(t%7>=5);\n            if(addN)for(int i=0;i<N;i++){wc[i]=max(1LL,wc[i]+(long long)(rng()%2001)-1000);hc[i]=max(1LL,hc[i]+(long long)(rng()%2001)-1000);}\n            for(int i=0;i<N;i++){\n                long long bs=LLONG_MAX;int br=0;char bd='U';int bb=-1;long long brx=0,bry=0;\n                int np=(int)px.size();\n                for(int r=0;r<2;r++){\n                    long long rw=r?hc[i]:wc[i],rh=r?wc[i]:hc[i];\n                    for(int b=-1;b<np;b++){\n                        {long long rx=(b<0)?0:px[b]+pw[b],ry=0;\n                         for(int j=0;j<np;j++)if(px[j]<rx+rw&&px[j]+pw[j]>rx)ry=max(ry,py[j]+ph[j]);\n                         long long nW=max(cW,rx+rw),nH=max(cH,ry+rh),s=nW+nH;\n                         if(strat==1)s+=abs(nW-nH)/2;else if(strat==2)s+=abs(nW-nH);else if(strat==3){long long w=nW*nH-cW*cH-rw*rh;s+=w/500;}else if(strat==4)s=max(nW,nH)*2;\n                         if(s<bs){bs=s;br=r;bd='U';bb=b;brx=rx;bry=ry;}}\n                        {long long ry=(b<0)?0:py[b]+ph[b],rx=0;\n                         for(int j=0;j<np;j++)if(py[j]<ry+rh&&py[j]+ph[j]>ry)rx=max(rx,px[j]+pw[j]);\n                         long long nW=max(cW,rx+rw),nH=max(cH,ry+rh),s=nW+nH;\n                         if(strat==1)s+=abs(nW-nH)/2;else if(strat==2)s+=abs(nW-nH);else if(strat==3){long long w=nW*nH-cW*cH-rw*rh;s+=w/500;}else if(strat==4)s=max(nW,nH)*2;\n                         if(s<bs){bs=s;br=r;bd='L';bb=b;brx=rx;bry=ry;}}\n                    }\n                }\n                long long rw=br?hc[i]:wc[i],rh=br?wc[i]:hc[i];\n                px.push_back(brx);py.push_back(bry);pw.push_back(rw);ph.push_back(rh);plc.push_back(i);\n                out.push_back({i,br,bd,bb});cW=max(cW,brx+rw);cH=max(cH,bry+rh);\n            }\n        }\n        cout<<out.size()<<\"\\n\";\n        for(auto&[p,r,d,b]:out)cout<<p<<\" \"<<r<<\" \"<<d<<\" \"<<b<<\"\\n\";\n        cout.flush();\n        long long Wp,Hp;cin>>Wp>>Hp;\n        if(doRow){double ws=0;for(int i=0;i<N;i++)ws+=w_est[i];double c=(ws-Wp)/(N+1);for(int i=0;i<N;i++)w_est[i]=max(1.0,w_est[i]-c);}\n        else if(doCol){double hs=0;for(int i=0;i<N;i++)hs+=h_est[i];double c=(hs-Hp)/(N+1);for(int i=0;i<N;i++)h_est[i]=max(1.0,h_est[i]-c);}\n        else{\n            double We=(double)(Wp-cW),He=(double)(Hp-cH);int rc=0,bc=0;\n            long long margin=2*sigma;\n            for(int j=0;j<(int)px.size();j++){if(px[j]+pw[j]>=cW-margin)rc++;if(py[j]+ph[j]>=cH-margin)bc++;}\n            double lr=0.12;\n            for(int j=0;j<(int)px.size();j++){\n                int o=plc[j];bool rot=get<1>(out[j]);\n                if(px[j]+pw[j]>=cW-margin&&rc>0){double es=We/rc*lr;if(rot)h_est[o]=max(1.0,h_est[o]+es);else w_est[o]=max(1.0,w_est[o]+es);}\n                if(py[j]+ph[j]>=cH-margin&&bc>0){double es=He/bc*lr;if(rot)w_est[o]=max(1.0,w_est[o]+es);else h_est[o]=max(1.0,h_est[o]+es);}\n            }\n        }\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\nint N,M,H;\nvector<int>A;\nvector<vector<int>>adj;\nmt19937 rng(42);\nchrono::steady_clock::time_point T0;\ndouble el(){return chrono::duration<double>(chrono::steady_clock::now()-T0).count();}\nstruct State{\nvector<int>parent,height;vector<long long>sub_sum;vector<int>sub_max_h;long long score;\nvoid recompute(){\nvector<int>deg(N);for(int v=0;v<N;v++)if(parent[v]!=-1)deg[parent[v]]++;\nqueue<int>q;for(int v=0;v<N;v++)if(deg[v]==0)q.push(v);vector<int>ord;\nwhile(!q.empty()){int v=q.front();q.pop();ord.push_back(v);if(parent[v]!=-1&&--deg[parent[v]]==0)q.push(parent[v]);}\nfor(int v:ord)height[v]=(parent[v]==-1)?0:height[parent[v]]+1;\nfill(sub_sum.begin(),sub_sum.end(),0);fill(sub_max_h.begin(),sub_max_h.end(),0);\nfor(int v:ord){sub_sum[v]+=A[v];sub_max_h[v]=max(sub_max_h[v],height[v]);\nif(parent[v]!=-1){sub_sum[parent[v]]+=sub_sum[v];sub_max_h[parent[v]]=max(sub_max_h[parent[v]],sub_max_h[v]);}}\nscore=0;for(int v=0;v<N;v++)score+=(long long)(height[v]+1)*A[v];}\nbool cyc(int v,int np){if(np==-1)return false;for(int c=np;c!=-1;c=parent[c])if(c==v)return true;return false;}\nvoid init(const vector<int>&p){parent=p;height.resize(N);sub_sum.resize(N);sub_max_h.resize(N);recompute();}\n};\nvoid greedy(State&st){\nwhile(true){long long bg=0;int bv=-1,bu=-1;\nfor(int v=0;v<N;v++)for(int u:adj[v]){if(u==st.parent[v])continue;\nint nh=st.height[u]+1,d=nh-st.height[v];if(d<=0||st.sub_max_h[v]+d>H||st.cyc(v,u))continue;\nlong long g=(long long)d*st.sub_sum[v];if(g>bg){bg=g;bv=v;bu=u;}}\nif(bv==-1)break;st.parent[bv]=bu;st.recompute();}}\nvector<int>mbfs(const vector<int>&ro,bool bb){\nvector<int>p(N,-1),h(N,0);vector<bool>vis(N);\nfor(int r:ro){if(vis[r])continue;queue<int>q;q.push(r);vis[r]=true;\nwhile(!q.empty()){int u=q.front();q.pop();if(h[u]>=H)continue;\nvector<int>nb=adj[u];if(bb)sort(nb.begin(),nb.end(),[](int a,int b){return A[a]>A[b];});\nelse shuffle(nb.begin(),nb.end(),rng);\nfor(int v:nb){if(vis[v])continue;vis[v]=true;p[v]=u;h[v]=h[u]+1;q.push(v);}}}return p;}\nvector<int>mdfs(const vector<int>&ro){\nvector<int>p(N,-1),h(N,0);vector<bool>vis(N);\nfor(int r:ro){if(vis[r])continue;vis[r]=true;\nfunction<void(int)>dfs=[&](int u){if(h[u]>=H)return;\nvector<int>nb=adj[u];sort(nb.begin(),nb.end(),[](int a,int b){return A[a]>A[b];});\nfor(int v:nb){if(vis[v])continue;vis[v]=true;p[v]=u;h[v]=h[u]+1;dfs(v);}};dfs(r);}return p;}\nvector<int>mchain(){\nvector<int>p(N,-1);vector<bool>used(N);vector<int>ord(N);iota(ord.begin(),ord.end(),0);\nsort(ord.begin(),ord.end(),[](int a,int b){return A[a]>A[b];});\nfor(int v:ord){if(used[v])continue;vector<int>dist(N,-1),par(N,-1);queue<int>q;\nq.push(v);dist[v]=0;int t=v;while(!q.empty()){int u=q.front();q.pop();\nif(dist[u]>dist[t])t=u;if(dist[u]==H)continue;\nfor(int w:adj[u])if(!used[w]&&dist[w]==-1){dist[w]=dist[u]+1;par[w]=u;q.push(w);}}\nvector<int>path;for(int c=t;;c=par[c]){path.push_back(c);if(c==v)break;}\nfor(int i=0;i<(int)path.size();i++){used[path[i]]=true;p[path[i]]=(i==0)?-1:path[i-1];}}return p;}\nvoid sa(vector<int>&par,long long&bs,double et){\nvector<int>ht(N);\nauto rh=[&](){vector<int>deg(N);for(int v=0;v<N;v++)if(par[v]!=-1)deg[par[v]]++;\nqueue<int>q;for(int v=0;v<N;v++)if(deg[v]==0)q.push(v);vector<int>o;\nwhile(!q.empty()){int v=q.front();q.pop();o.push_back(v);if(par[v]!=-1&&--deg[par[v]]==0)q.push(par[v]);}\nfor(int v:o)ht[v]=(par[v]==-1)?0:ht[par[v]]+1;};rh();\nauto cc=[&](int v,int np)->bool{if(np==-1)return false;for(int c=np;c!=-1;c=par[c])if(c==v)return true;return false;};\nlong long cs=0;for(int v=0;v<N;v++)cs+=(long long)(ht[v]+1)*A[v];\nlong long lb=cs;vector<int>bp=par;double ss=el();double dur=max(.001,et-ss);\nuniform_real_distribution<double>uf(0,1);\nfor(int it=0;;it++){double t=el();if(t>et)break;double T=2000.0*pow(0.001,(t-ss)/dur);\nint v=rng()%N;if(adj[v].empty())continue;int np;\nif(rng()%50==0)np=-1;else np=adj[v][rng()%adj[v].size()];\nif(np==par[v]||cc(v,np))continue;int nh=(np==-1)?0:ht[np]+1,d=nh-ht[v];\nif(d==0)continue;long long sm=0;int mh=0;\nstack<int>stk;stk.push(v);while(!stk.empty()){int u=stk.top();stk.pop();sm+=A[u];mh=max(mh,ht[u]);\nfor(int w:adj[u])if(par[w]==u)stk.push(w);}\nif(mh+d>H)continue;long long g=(long long)d*sm;\nif(g>0||uf(rng)<exp((double)g/T)){par[v]=np;stk.push(v);while(!stk.empty()){int u=stk.top();stk.pop();ht[u]+=d;\nfor(int w:adj[u])if(par[w]==u)stk.push(w);}cs+=g;if(cs>lb){lb=cs;bp=par;}}}\npar=bp;rh();bs=0;for(int v=0;v<N;v++)bs+=(long long)(ht[v]+1)*A[v];}\nint main(){ios_base::sync_with_stdio(false);cin.tie(nullptr);T0=chrono::steady_clock::now();\ncin>>N>>M>>H;A.resize(N);for(int i=0;i<N;i++)cin>>A[i];adj.resize(N);\nfor(int i=0;i<M;i++){int u,v;cin>>u>>v;adj[u].push_back(v);adj[v].push_back(u);}\nvector<int>X(N),Y(N);for(int i=0;i<N;i++)cin>>X[i]>>Y[i];\nlong long bs=0;vector<int>bp(N,-1);auto ts=[&](const vector<int>&p){State st;st.init(p);greedy(st);\nif(st.score>bs){bs=st.score;bp=st.parent;}};\nts(vector<int>(N,-1));\n{vector<int>o(N);iota(o.begin(),o.end(),0);sort(o.begin(),o.end(),[](int a,int b){return A[a]<A[b];});\nts(mbfs(o,true));ts(mdfs(o));}\nts(mchain());\n{vector<int>o(N);iota(o.begin(),o.end(),0);sort(o.begin(),o.end(),[&](int a,int b){\nreturn(X[a]-500)*(X[a]-500)+(Y[a]-500)*(Y[a]-500)<(X[b]-500)*(X[b]-500)+(Y[b]-500)*(Y[b]-500);});\nts(mbfs(o,true));ts(mdfs(o));}\n{vector<int>o(N);iota(o.begin(),o.end(),0);sort(o.begin(),o.end(),[](int a,int b){return A[a]<A[b];});\nint nr=max(1,N/(H+1));vector<int>roots(o.begin(),o.begin()+min(nr,N));\nts(mbfs(roots,true));ts(mdfs(roots));}\nint tr=0;while(el()<0.6){vector<int>o(N);iota(o.begin(),o.end(),0);shuffle(o.begin(),o.end(),rng);\nif(tr%3==0)ts(mbfs(o,true));else if(tr%3==1)ts(mbfs(o,false));else ts(mdfs(o));tr++;}\nlong long ss;sa(bp,ss,1.7);ts(bp);\nfor(int i=0;i<N;i++)cout<<bp[i]<<(i==N-1?\"\\n\":\" \");return 0;}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <map>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nint N;\nvector<string> initial_board;\n\nvoid apply_shift(vector<string>& b, char dir, int idx) {\n    if (dir == 'L') { for (int j=0;j<N-1;j++) b[idx][j]=b[idx][j+1]; b[idx][N-1]='.'; }\n    else if (dir == 'R') { for (int j=N-1;j>0;j--) b[idx][j]=b[idx][j-1]; b[idx][0]='.'; }\n    else if (dir == 'U') { for (int i=0;i<N-1;i++) b[i][idx]=b[i+1][idx]; b[N-1][idx]='.'; }\n    else { for (int i=N-1;i>0;i--) b[i][idx]=b[i-1][idx]; b[0][idx]='.'; }\n}\n\nstruct MoveInfo { char dir; int idx; int amount; double ratio; int oni_removed; };\n\nvector<MoveInfo> get_candidates(const vector<string>& b) {\n    vector<MoveInfo> cands;\n    for (int i=0;i<N;i++) {\n        int L=N; for(int j=0;j<N;j++) if(b[i][j]=='o'){L=j;break;}\n        int cnt=0,mx=-1; for(int j=0;j<L;j++) if(b[i][j]=='x'){cnt++;mx=j;}\n        if(cnt>0) cands.push_back(MoveInfo{'L',i,mx+1,(double)cnt/(mx+1),cnt});\n        int R=0; for(int j=N-1;j>=0;j--) if(b[i][j]=='o'){R=j+1;break;}\n        cnt=0; int mn_r=N; for(int j=R;j<N;j++) if(b[i][j]=='x'){cnt++;mn_r=j;}\n        if(cnt>0) cands.push_back(MoveInfo{'R',i,N-mn_r,(double)cnt/(N-mn_r),cnt});\n    }\n    for (int j=0;j<N;j++) {\n        int U=N; for(int i=0;i<N;i++) if(b[i][j]=='o'){U=i;break;}\n        int cnt=0,mx=-1; for(int i=0;i<U;i++) if(b[i][j]=='x'){cnt++;mx=i;}\n        if(cnt>0) cands.push_back(MoveInfo{'U',j,mx+1,(double)cnt/(mx+1),cnt});\n        int D=0; for(int i=N-1;i>=0;i--) if(b[i][j]=='o'){D=i+1;break;}\n        cnt=0; int mn_c=N; for(int i=D;i<N;i++) if(b[i][j]=='x'){cnt++;mn_c=i;}\n        if(cnt>0) cands.push_back(MoveInfo{'D',j,N-mn_c,(double)cnt/(N-mn_c),cnt});\n    }\n    return cands;\n}\n\nint count_stuck(const vector<string>& b) {\n    int stuck=0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(b[i][j]=='x') {\n        bool us=true,ds=true,ls=true,rs=true;\n        for(int k=0;k<i;k++) if(b[k][j]=='o'){us=false;break;}\n        for(int k=i+1;k<N;k++) if(b[k][j]=='o'){ds=false;break;}\n        for(int k=0;k<j;k++) if(b[i][k]=='o'){ls=false;break;}\n        for(int k=j+1;k<N;k++) if(b[i][k]=='o'){rs=false;break;}\n        if(!(us||ds||ls||rs)) stuck++;\n    }\n    return stuck;\n}\n\nint safety_score(const vector<string>& b) {\n    int score=0;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(b[i][j]=='x') {\n        bool us=true,ds=true,ls=true,rs=true;\n        for(int k=0;k<i;k++) if(b[k][j]=='o'){us=false;break;}\n        for(int k=i+1;k<N;k++) if(b[k][j]=='o'){ds=false;break;}\n        for(int k=0;k<j;k++) if(b[i][k]=='o'){ls=false;break;}\n        for(int k=j+1;k<N;k++) if(b[i][k]=='o'){rs=false;break;}\n        int s=us+ds+ls+rs; if(s==0) score-=100000; else score+=s*s;\n    }\n    return score;\n}\n\nint count_oni(const vector<string>& b) { int c=0; for(auto& r:b) for(char ch:r) if(ch=='x') c++; return c; }\n\nstruct State { vector<string> board; vector<pair<char,int>> moves; int cost; int oni_count; double score; };\n\npair<vector<pair<char,int>>,bool> run_beam(int beam_width) {\n    vector<State> beam;\n    beam.push_back({initial_board, {}, 0, count_oni(initial_board), 0.0});\n    while(true) {\n        vector<State> next_beam;\n        for(auto& state : beam) {\n            if(state.oni_count == 0) return {state.moves, true};\n            auto cands = get_candidates(state.board);\n            if(cands.empty()) continue;\n            sort(cands.begin(), cands.end(), [](const MoveInfo& a, const MoveInfo& b){return a.ratio > b.ratio;});\n            int base_s = safety_score(state.board);\n            for(int t=0; t<min(beam_width*2,(int)cands.size()); t++) {\n                auto nb = state.board;\n                for(int k=0;k<cands[t].amount;k++) apply_shift(nb, cands[t].dir, cands[t].idx);\n                int st = count_stuck(nb);\n                if(st > 0) continue;\n                int no = count_oni(nb);\n                auto nm = state.moves;\n                for(int k=0;k<cands[t].amount;k++) nm.push_back({cands[t].dir, cands[t].idx});\n                int nc = state.cost + cands[t].amount;\n                int sd = safety_score(nb) - base_s;\n                double ns = -no * 10000.0 - nc + sd * 0.01;\n                next_beam.push_back({nb, nm, nc, no, ns});\n            }\n        }\n        if(next_beam.empty()) break;\n        sort(next_beam.begin(), next_beam.end(), [](const State& a, const State& b){return a.score > b.score;});\n        if((int)next_beam.size() > beam_width) next_beam.resize(beam_width);\n        beam = next_beam;\n    }\n    sort(beam.begin(), beam.end(), [](const State& a, const State& b){return a.oni_count < b.oni_count || (a.oni_count == b.oni_count && a.cost < b.cost);});\n    return {beam[0].moves, beam[0].oni_count == 0};\n}\n\npair<vector<pair<char,int>>,bool> run_greedy(int strategy, mt19937& rng) {\n    vector<string> b=initial_board; vector<pair<char,int>> moves;\n    while(true) {\n        int oc=count_oni(b); if(oc==0) return {moves,true};\n        auto cands=get_candidates(b); if(cands.empty()) return {moves,false};\n        if(strategy==0) sort(cands.begin(),cands.end(),[](const MoveInfo& a,const MoveInfo& b){return a.ratio>b.ratio;});\n        else if(strategy==1) sort(cands.begin(),cands.end(),[](const MoveInfo& a,const MoveInfo& b){return a.oni_removed>b.oni_removed||(a.oni_removed==b.oni_removed&&a.amount<b.amount);});\n        else if(strategy==2) sort(cands.begin(),cands.end(),[](const MoveInfo& a,const MoveInfo& b){return a.amount<b.amount||(a.amount==b.amount&&a.ratio>b.ratio);});\n        else shuffle(cands.begin(),cands.end(),rng);\n        int best_t=0,best_stuck=N*N; double best_eff=-1e9; int base_s=safety_score(b);\n        int cl=min(15,(int)cands.size());\n        for(int t=0;t<cl;t++) {\n            auto sim=b; for(int k=0;k<cands[t].amount;k++) apply_shift(sim,cands[t].dir,cands[t].idx);\n            int st=count_stuck(sim); if(st>0&&best_stuck==0) continue;\n            int sd=safety_score(sim)-base_s; double ef=cands[t].ratio+sd*0.01;\n            if(st<best_stuck||(st==best_stuck&&ef>best_eff)){best_stuck=st;best_t=t;best_eff=ef;}\n            if(st==0&&cands[t].ratio>=1.0) break;\n        }\n        for(int k=0;k<cands[best_t].amount;k++){apply_shift(b,cands[best_t].dir,cands[best_t].idx);moves.push_back({cands[best_t].dir,cands[best_t].idx});}\n    }\n}\n\nvector<pair<char,int>> batch_fallback() {\n    vector<string> b=initial_board; vector<pair<char,int>> moves;\n    auto shift=[&](char d,int i){apply_shift(b,d,i);moves.push_back({d,i});};\n    struct Oni{int i,j;}; vector<Oni> onis;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(b[i][j]=='x') onis.push_back({i,j});\n    map<pair<char,int>,vector<int>> batches;\n    for(int id=0;id<(int)onis.size();id++){\n        auto& o=onis[id]; bool us=true,ds=true,ls=true,rs=true;\n        for(int k=0;k<o.i;k++) if(b[k][o.j]=='o'){us=false;break;}\n        for(int k=o.i+1;k<N;k++) if(b[k][o.j]=='o'){ds=false;break;}\n        for(int k=0;k<o.j;k++) if(b[o.i][k]=='o'){ls=false;break;}\n        for(int k=o.j+1;k<N;k++) if(b[o.i][k]=='o'){rs=false;break;}\n        char bd=0;int bc=1e9;\n        if(us){int c=o.i+1;if(c<bc){bc=c;bd='U';}} if(ds){int c=N-o.i;if(c<bc){bc=c;bd='D';}}\n        if(ls){int c=o.j+1;if(c<bc){bc=c;bd='L';}} if(rs){int c=N-o.j;if(c<bc){bc=c;bd='R';}}\n        if(bd){int idx=(bd=='L'||bd=='R')?o.i:o.j; batches[{bd,idx}].push_back(id);}\n    }\n    for(int i=0;i<N;i++){\n        auto lit=batches.find({'L',i}),rit=batches.find({'R',i});\n        int Lv=0,Rv=0;\n        if(lit!=batches.end()) for(int id:lit->second) Lv=max(Lv,onis[id].j+1);\n        if(rit!=batches.end()) for(int id:rit->second) Rv=max(Rv,N-onis[id].j);\n        if(Lv>0&&Rv>0){if(2*Lv+Rv<=Lv+2*Rv){for(int k=0;k<Lv;k++) shift('L',i);for(int k=0;k<Lv+Rv;k++) shift('R',i);}else{for(int k=0;k<Rv;k++) shift('R',i);for(int k=0;k<Rv+Lv;k++) shift('L',i);}}\n        else if(Lv>0){for(int k=0;k<Lv;k++) shift('L',i);for(int k=0;k<Lv;k++) shift('R',i);}\n        else if(Rv>0){for(int k=0;k<Rv;k++) shift('R',i);for(int k=0;k<Rv;k++) shift('L',i);}\n    }\n    for(int j=0;j<N;j++){\n        auto uit=batches.find({'U',j}),dit=batches.find({'D',j});\n        int Uv=0,Dv=0;\n        if(uit!=batches.end()) for(int id:uit->second) Uv=max(Uv,onis[id].i+1);\n        if(dit!=batches.end()) for(int id:dit->second) Dv=max(Dv,N-onis[id].i);\n        if(Uv>0&&Dv>0){if(2*Uv+Dv<=Uv+2*Dv){for(int k=0;k<Uv;k++) shift('U',j);for(int k=0;k<Uv+Dv;k++) shift('D',j);}else{for(int k=0;k<Dv;k++) shift('D',j);for(int k=0;k<Dv+Uv;k++) shift('U',j);}}\n        else if(Uv>0){for(int k=0;k<Uv;k++) shift('U',j);for(int k=0;k<Uv;k++) shift('D',j);}\n        else if(Dv>0){for(int k=0;k<Dv;k++) shift('D',j);for(int k=0;k<Dv;k++) shift('U',j);}\n    }\n    return moves;\n}\n\nint main() {\n    cin>>N; initial_board.resize(N);\n    for(int i=0;i<N;i++) cin>>initial_board[i];\n    mt19937 rng(42); vector<pair<char,int>> best_moves; int best_cost=1e9;\n    auto start=chrono::high_resolution_clock::now();\n    auto [bm,bs]=run_beam(10); if(bs&&(int)bm.size()<best_cost){best_cost=bm.size();best_moves=bm;}\n    bool done=false;\n    for(int s=0;s<4&&!done;s++) for(int t=0;t<30&&!done;t++){\n        rng.seed(42+s*1000+t); auto [m,ok]=run_greedy(s,rng);\n        if(ok&&(int)m.size()<best_cost){best_cost=m.size();best_moves=m;}\n        if(chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()-start).count()>1500) done=true;\n    }\n    if(best_moves.empty()) best_moves=batch_fallback();\n    for(auto& [d,p]:best_moves) cout<<d<<\" \"<<p<<\"\\n\";\n    return 0;\n}","ahc044":"#include <iostream>\n#include <cmath>\n#include <chrono>\n#include <cstring>\n#include <algorithm>\n#include <climits>\n#include <vector>\n#include <numeric>\n\nusing namespace std;\n\nint N, L;\nint T[100];\nint a[100], b[100];\nint best_a[100], best_b[100];\nint best_error = INT_MAX;\nint t_global[100];\nint next_node[2][100];\n\nuint64_t rng_state = 1234567890123456789ULL;\nuint64_t rng64() {\n    rng_state ^= rng_state >> 12;\n    rng_state ^= rng_state << 25;\n    rng_state ^= rng_state >> 27;\n    return rng_state * 2685821657736338717ULL;\n}\n\nvoid update_next_node() {\n    for (int i = 0; i < N; i++) {\n        next_node[0][i] = a[i];\n        next_node[1][i] = b[i];\n    }\n}\n\nint simulate(int ti[]) {\n    memset(ti, 0, sizeof(int) * N);\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        int c = ++ti[cur];\n        cur = next_node[c & 1][cur];\n    }\n    int err = 0;\n    for (int i = 0; i < N; i++) err += abs(ti[i] - T[i]);\n    return err;\n}\n\nvoid try_init(int ai[], int bi[]) {\n    memcpy(a, ai, sizeof(a));\n    memcpy(b, bi, sizeof(b));\n    update_next_node();\n    int err = simulate(t_global);\n    if (err < best_error) {\n        best_error = err;\n        memcpy(best_a, a, sizeof(a));\n        memcpy(best_b, b, sizeof(b));\n    }\n}\n\nvoid greedy_init(int ai[], int bi[], bool avoid_same) {\n    int dem[100]; memcpy(dem, T, sizeof(T));\n    int cnt[100] = {};\n    bool a_ch[100] = {}, b_ch[100] = {};\n    for(int i=0; i<N; i++) { ai[i] = (i+1)%N; bi[i] = (i+1)%N; }\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        cnt[cur]++;\n        if (cnt[cur] & 1) {\n            if (!a_ch[cur]) {\n                int best = -1;\n                for (int j = 0; j < N; j++) {\n                    if (j == cur) continue;\n                    if (avoid_same && b_ch[cur] && j == bi[cur]) continue;\n                    if (T[j] == 0 && dem[j] <= 0) continue;\n                    if (best == -1 || dem[j] > dem[best] || (dem[j] == dem[best] && T[j] > T[best])) best = j;\n                }\n                ai[cur] = best; a_ch[cur] = true;\n                dem[best] -= (T[cur] + 1) / 2;\n            }\n            cur = ai[cur];\n        } else {\n            if (!b_ch[cur]) {\n                int best = -1;\n                for (int j = 0; j < N; j++) {\n                    if (j == cur) continue;\n                    if (avoid_same && a_ch[cur] && j == ai[cur]) continue;\n                    if (T[j] == 0 && dem[j] <= 0) continue;\n                    if (best == -1 || dem[j] > dem[best] || (dem[j] == dem[best] && T[j] > T[best])) best = j;\n                }\n                bi[cur] = best; b_ch[cur] = true;\n                dem[best] -= T[cur] / 2;\n            }\n            cur = bi[cur];\n        }\n    }\n}\n\nvoid flow_sa(int ai[], int bi[]) {\n    int flow_in[100] = {};\n    for(int i=0; i<N; i++) {\n        if(T[i] == 0) continue;\n        flow_in[ai[i]] += (T[i] + 1) / 2;\n        flow_in[bi[i]] += T[i] / 2;\n    }\n\n    int current_flow_error = 0;\n    for(int i=0; i<N; i++) current_flow_error += abs(flow_in[i] - T[i]);\n\n    double flow_temp = 1000.0;\n    for(int iter = 0; iter < 2000000; iter++) {\n        if (current_flow_error == 0) break;\n        \n        int i = rng64() % N;\n        if (T[i] == 0) continue;\n        bool is_a = rng64() & 1;\n        int old_dest = is_a ? ai[i] : bi[i];\n        int new_dest = rng64() % N;\n        if (new_dest == old_dest || T[new_dest] == 0) continue;\n        \n        int delta_flow = is_a ? (T[i] + 1) / 2 : T[i] / 2;\n        \n        int old_err_old = abs(flow_in[old_dest] - T[old_dest]);\n        int old_err_new = abs(flow_in[new_dest] - T[new_dest]);\n        \n        int new_flow_old = flow_in[old_dest] - delta_flow;\n        int new_flow_new = flow_in[new_dest] + delta_flow;\n        \n        int new_err_old = abs(new_flow_old - T[old_dest]);\n        int new_err_new = abs(new_flow_new - T[new_dest]);\n        \n        int delta_err = (new_err_old + new_err_new) - (old_err_old + old_err_new);\n        if (new_dest == i) delta_err += 100;\n        if (is_a && new_dest == bi[i]) delta_err += 50;\n        if (!is_a && new_dest == ai[i]) delta_err += 50;\n        \n        if (delta_err <= 0 || (double)(rng64() & 0xFFFF) / 65536.0 < exp(-(double)delta_err / flow_temp)) {\n            if (is_a) ai[i] = new_dest; else bi[i] = new_dest;\n            flow_in[old_dest] = new_flow_old;\n            flow_in[new_dest] = new_flow_new;\n            current_flow_error += delta_err;\n        }\n        flow_temp *= 0.9999;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> L;\n    for (int i = 0; i < N; i++) cin >> T[i];\n    \n    int ai[100], bi[100];\n    \n    for (int i = 0; i < N; i++) { ai[i] = (i+1)%N; bi[i] = (i+1)%N; }\n    try_init(ai, bi);\n    \n    greedy_init(ai, bi, true);\n    try_init(ai, bi);\n    \n    greedy_init(ai, bi, false);\n    try_init(ai, bi);\n    \n    memcpy(ai, best_a, sizeof(ai));\n    memcpy(bi, best_b, sizeof(bi));\n    flow_sa(ai, bi);\n    try_init(ai, bi);\n    \n    memcpy(a, best_a, sizeof(a));\n    memcpy(b, best_b, sizeof(b));\n    update_next_node();\n    int error = simulate(t_global);\n    best_error = error;\n    \n    int order[100];\n    iota(order, order + N, 0);\n    sort(order, order + N, [](int x, int y) { return T[x] < T[y]; });\n    int rank_of[100];\n    for (int i = 0; i < N; i++) rank_of[order[i]] = i;\n    \n    vector<int> nodes_by_T[10001];\n    for(int i=0; i<N; i++) if(T[i] > 0) nodes_by_T[T[i]].push_back(i);\n    \n    double start_temp = max(500.0, (double)error / 20.0);\n    auto start = chrono::high_resolution_clock::now();\n    \n    while(true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.85) break;\n        \n        double temp = start_temp * (1.0 - elapsed / 1.85);\n        if (temp < 0.01) temp = 0.01;\n        \n        int old_a[100], old_b[100], old_t_global[100];\n        memcpy(old_a, a, sizeof(a));\n        memcpy(old_b, b, sizeof(b));\n        memcpy(old_t_global, t_global, sizeof(t_global));\n        \n        int move_type = rng64() % 5;\n        int i = -1, j = -1;\n        \n        if (move_type == 0) {\n            i = rng64() % N;\n            while(T[i] == 0) i = rng64() % N;\n            swap(a[i], b[i]);\n        } else if (move_type < 4) {\n            i = rng64() % N;\n            while(T[i] == 0) i = rng64() % N;\n            \n            if (nodes_by_T[T[i]].size() > 1) {\n                j = nodes_by_T[T[i]][rng64() % nodes_by_T[T[i]].size()];\n                while(j == i) j = nodes_by_T[T[i]][rng64() % nodes_by_T[T[i]].size()];\n            } else {\n                int delta_rank = (rng64() % 5) - 2;\n                int new_rank = max(0, min(N - 1, rank_of[i] + delta_rank));\n                j = order[new_rank];\n                int attempts = 0;\n                while(T[j] == 0 || j == i) {\n                    new_rank = (new_rank + 1) % N;\n                    j = order[new_rank];\n                    if (++attempts > N) break;\n                }\n                if (j == i || T[j] == 0) continue;\n            }\n            \n            if (move_type == 1) swap(a[i], a[j]);\n            else if (move_type == 2) swap(b[i], b[j]);\n            else swap(a[i], b[j]);\n        } else {\n            i = rng64() % N;\n            while(T[i] == 0) i = rng64() % N;\n            bool is_a = rng64() & 1;\n            int nv = rng64() % N;\n            while(T[nv] == 0) nv = rng64() % N;\n            if (is_a) a[i] = nv; else b[i] = nv;\n        }\n        \n        update_next_node();\n        int new_error = simulate(t_global);\n        double delta = new_error - error;\n        \n        if (delta <= 0 || (double)(rng64() & 0xFFFF) / 65536.0 < exp(-delta / temp)) {\n            error = new_error;\n            if (error < best_error) {\n                best_error = error;\n                memcpy(best_a, a, sizeof(a));\n                memcpy(best_b, b, sizeof(b));\n            }\n        } else {\n            memcpy(a, old_a, sizeof(a));\n            memcpy(b, old_b, sizeof(b));\n            memcpy(t_global, old_t_global, sizeof(t_global));\n        }\n    }\n    \n    for (int i = 0; i < N; i++)\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nuint64_t xy2d(int n, int x, int y) {\n    uint64_t d = 0;\n    for (int s = n/2; s > 0; s /= 2) {\n        int rx = (x & s) > 0;\n        int ry = (y & s) > 0;\n        d += (uint64_t)s * s * ((3 * rx) ^ ry);\n        if (ry == 0) {\n            if (rx == 1) { x = s-1 - x; y = s-1 - y; }\n            swap(x, y);\n        }\n    }\n    return d;\n}\n\nint N, M, Q, L, W;\ndouble cx[800], cy[800], ddist[800][800];\nint qcnt = 0;\n\nvector<pair<int,int>> query(vector<int>& v) {\n    if (qcnt >= Q || (int)v.size() < 2) return {};\n    qcnt++;\n    cout << \"? \" << v.size();\n    for (int x : v) cout << \" \" << x;\n    cout << endl;\n    vector<pair<int,int>> res(v.size() - 1);\n    for (auto& [a, b] : res) cin >> a >> b;\n    return res;\n}\n\nint par[800], rnk[800];\nvoid init_dsu() { iota(par, par + N, 0); fill(rnk, rnk + N, 0); }\nint find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }\nbool unite(int x, int y) {\n    x = find(x); y = find(y);\n    if (x == y) return false;\n    if (rnk[x] < rnk[y]) swap(x, y);\n    par[y] = x;\n    if (rnk[x] == rnk[y]) rnk[x]++;\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    mt19937 rng(1337);\n    \n    cin >> N >> M >> Q >> L >> W;\n    vector<int> G(M);\n    for (int& g : G) cin >> g;\n    \n    for (int i = 0; i < N; i++) {\n        int a, b, c, d;\n        cin >> a >> b >> c >> d;\n        cx[i] = (a + b) / 2.0;\n        cy[i] = (c + d) / 2.0;\n    }\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            double dx = cx[i] - cx[j], dy = cy[i] - cy[j];\n            ddist[i][j] = sqrt(dx*dx + dy*dy);\n        }\n    \n    vector<uint64_t> hilbert_idx(N);\n    for(int i=0; i<N; ++i) hilbert_idx[i] = xy2d(32768, (int)cx[i], (int)cy[i]);\n    \n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [&](int a, int b) {\n        return hilbert_idx[a] < hilbert_idx[b];\n    });\n    \n    vector<double> cut_cost(N, 0.0);\n    for (int j = 1; j < N; j++) {\n        cut_cost[j] = ddist[ord[j-1]][ord[j]];\n    }\n    \n    vector<int> p(M);\n    iota(p.begin(), p.end(), 0);\n    \n    if (M <= 20) {\n        vector<double> dp(1 << M, -1.0);\n        dp[0] = 0.0;\n        for (int mask = 0; mask < (1 << M); mask++) {\n            if (dp[mask] < -0.5) continue;\n            int s = 0;\n            for (int i = 0; i < M; i++) if (mask & (1 << i)) s += G[i];\n            for (int i = 0; i < M; i++) {\n                if (!(mask & (1 << i))) {\n                    int next_mask = mask | (1 << i);\n                    int next_s = s + G[i];\n                    double cost = dp[mask] + (next_s < N ? cut_cost[next_s] : 0.0);\n                    if (cost > dp[next_mask]) dp[next_mask] = cost;\n                }\n            }\n        }\n        int mask = (1 << M) - 1;\n        for (int k = M - 1; k >= 0; k--) {\n            int s = 0;\n            for (int i = 0; i < M; i++) if (mask & (1 << i)) s += G[i];\n            for (int i = 0; i < M; i++) {\n                if (mask & (1 << i)) {\n                    int prev_mask = mask ^ (1 << i);\n                    double cost = dp[prev_mask] + (s < N ? cut_cost[s] : 0.0);\n                    if (abs(cost - dp[mask]) < 1e-9) {\n                        p[k] = i;\n                        mask = prev_mask;\n                        break;\n                    }\n                }\n            }\n        }\n    } else {\n        sort(p.begin(), p.end(), [&](int a, int b) { return G[a] > G[b]; });\n        vector<int> prefix(M);\n        int s = 0;\n        for (int i = 0; i < M; i++) { s += G[p[i]]; prefix[i] = s; }\n        \n        double current_cost = 0.0;\n        for (int i = 0; i < M - 1; i++) current_cost += cut_cost[prefix[i]];\n        \n        for (int iter = 0; iter < 1000000; iter++) {\n            int i = rng() % M;\n            int j = rng() % M;\n            if (i == j) continue;\n            if (i > j) swap(i, j);\n            \n            double old_cost = 0.0;\n            for (int k = i; k < j; k++) old_cost += cut_cost[prefix[k]];\n            \n            swap(p[i], p[j]);\n            int s_prev = (i == 0 ? 0 : prefix[i-1]);\n            double new_cost = 0.0;\n            for (int k = i; k < j; k++) {\n                s_prev += G[p[k]];\n                new_cost += cut_cost[s_prev];\n            }\n            \n            if (new_cost > old_cost) {\n                s_prev = (i == 0 ? 0 : prefix[i-1]);\n                for (int k = i; k < j; k++) {\n                    s_prev += G[p[k]];\n                    prefix[k] = s_prev;\n                }\n                current_cost += (new_cost - old_cost);\n            } else {\n                swap(p[i], p[j]);\n            }\n        }\n    }\n    \n    vector<vector<int>> grp(M);\n    int curr = 0;\n    for (int k = 0; k < M; k++) {\n        int group_idx = p[k];\n        int sz = G[group_idx];\n        for (int j = 0; j < sz; j++) {\n            grp[group_idx].push_back(ord[curr++]);\n        }\n    }\n    \n    vector<int> proc_order(M);\n    iota(proc_order.begin(), proc_order.end(), 0);\n    sort(proc_order.begin(), proc_order.end(), [&](int a, int b) {\n        return G[a] < G[b];\n    });\n    \n    vector<vector<pair<int,int>>> ans(M);\n    \n    for (int k : proc_order) {\n        int G_size = grp[k].size();\n        if (G_size <= 1) continue;\n        \n        init_dsu();\n        vector<pair<int,int>> mst;\n        \n        if (G_size <= L) {\n            if (qcnt < Q) mst = query(grp[k]);\n        } else {\n            int start = 0;\n            while (start < G_size) {\n                int end = min(start + L, G_size);\n                if (end - start < 2) break;\n                vector<int> qv(grp[k].begin() + start, grp[k].begin() + end);\n                if (qcnt < Q) {\n                    auto edges = query(qv);\n                    for (auto& [a, b] : edges) {\n                        if (unite(a, b)) {\n                            mst.emplace_back(a, b);\n                        }\n                    }\n                } else {\n                    break;\n                }\n                start += L - 1;\n            }\n        }\n        \n        if (mst.size() < (size_t)G_size - 1) {\n            vector<tuple<double,int,int>> edges;\n            for (int i = 0; i < G_size; i++)\n                for (int j = i + 1; j < G_size; j++)\n                    edges.emplace_back(ddist[grp[k][i]][grp[k][j]], grp[k][i], grp[k][j]);\n            sort(edges.begin(), edges.end());\n            for (auto& [d, a, b] : edges) {\n                if (unite(a, b)) {\n                    mst.emplace_back(a, b);\n                }\n                if (mst.size() == (size_t)G_size - 1) break;\n            }\n        }\n        ans[k] = mst;\n    }\n    \n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < (int)grp[k].size(); i++) cout << grp[k][i] << \" \\n\"[i==(int)grp[k].size()-1];\n        for (auto& [a, b] : ans[k]) cout << a << \" \" << b << \"\\n\";\n    }\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <set>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <cstring>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\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    bool block_grid[20][20] = {};\n    int cur_r = targets[0].first, cur_c = targets[0].second;\n    vector<pair<char,char>> actions;\n    \n    const int DR[] = {-1, 1, 0, 0};\n    const int DC[] = {0, 0, -1, 1};\n    const char DIR_CHAR[] = {'U', 'D', 'L', 'R'};\n    int dir_map[256];\n    dir_map['U'] = 0; dir_map['D'] = 1; dir_map['L'] = 2; dir_map['R'] = 3;\n    \n    bool is_target[20][20] = {};\n    for (auto& [r, c] : targets) is_target[r][c] = true;\n    \n    int dist[20][20][21][21];\n    short pr[20][20][21][21];\n    short pc[20][20][21][21];\n    char pa[20][20][21][21];\n    char pd[20][20][21][21];\n    short pf[20][20][21][21];\n    short pg[20][20][21][21];\n    \n    struct State { short r, c, ar, ac; };\n    State q_arr[176400];\n    \n    auto is_block_fn = [&](int r, int c, int ar, int ac) {\n        if (ar != 20 && r == ar && c == ac) return !block_grid[r][c];\n        return block_grid[r][c];\n    };\n    \n    auto bfs = [&](int sr, int sc, int tr, int tc) -> vector<tuple<char,char,int,int>> {\n        if (sr == tr && sc == tc && !block_grid[sr][sc]) return {};\n        \n        memset(dist, -1, sizeof(dist));\n        int q_sz = 0;\n        q_arr[q_sz++] = {(short)sr, (short)sc, 20, 20};\n        dist[sr][sc][20][20] = 0;\n        \n        int found_ar = -1, found_ac = -1;\n        \n        for (int i = 0; i < q_sz; ++i) {\n            auto [r, c, ar, ac] = q_arr[i];\n            int d = dist[r][c][ar][ac];\n            \n            if (r == tr && c == tc && !is_block_fn(r, c, ar, ac)) {\n                found_ar = ar; found_ac = ac;\n                goto found;\n            }\n            \n            for (int dir = 0; dir < 4; ++dir) {\n                int nr = r + DR[dir], nc = c + DC[dir];\n                \n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !is_block_fn(nr, nc, ar, ac)) {\n                    if (dist[nr][nc][ar][ac] == -1) {\n                        dist[nr][nc][ar][ac] = d + 1;\n                        pr[nr][nc][ar][ac] = r; pc[nr][nc][ar][ac] = c;\n                        pa[nr][nc][ar][ac] = 0; pd[nr][nc][ar][ac] = dir;\n                        pf[nr][nc][ar][ac] = ar; pg[nr][nc][ar][ac] = ac;\n                        q_arr[q_sz++] = {(short)nr, (short)nc, (short)ar, (short)ac};\n                    }\n                }\n                \n                int snr = r, snc = c;\n                while (true) {\n                    int nnr = snr + DR[dir], nnc = snc + DC[dir];\n                    if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || is_block_fn(nnr, nnc, ar, ac)) break;\n                    snr = nnr; snc = nnc;\n                }\n                if (snr != r || snc != c) {\n                    if (dist[snr][snc][ar][ac] == -1) {\n                        dist[snr][snc][ar][ac] = d + 1;\n                        pr[snr][snc][ar][ac] = r; pc[snr][snc][ar][ac] = c;\n                        pa[snr][snc][ar][ac] = 1; pd[snr][snc][ar][ac] = dir;\n                        pf[snr][snc][ar][ac] = ar; pg[snr][snc][ar][ac] = ac;\n                        q_arr[q_sz++] = {(short)snr, (short)snc, (short)ar, (short)ac};\n                    }\n                }\n                \n                if (ar == 20) {\n                    int br = nr, bc = nc;\n                    if (br >= 0 && br < N && bc >= 0 && bc < N && block_grid[br][bc]) {\n                        int nar = br, nac = bc;\n                        if (dist[r][c][nar][nac] == -1) {\n                            dist[r][c][nar][nac] = d + 1;\n                            pr[r][c][nar][nac] = r; pc[r][c][nar][nac] = c;\n                            pa[r][c][nar][nac] = 2; pd[r][c][nar][nac] = dir;\n                            pf[r][c][nar][nac] = 20; pg[r][c][nar][nac] = 20;\n                            q_arr[q_sz++] = {(short)r, (short)c, (short)nar, (short)nac};\n                        }\n                    }\n                }\n            }\n        }\n        return {};\n    found:\n        vector<tuple<char,char,int,int>> path;\n        int cr = tr, cc = tc, car = found_ar, cac = found_ac;\n        while (cr != sr || cc != sc || car != 20 || cac != 20) {\n            int act = pa[cr][cc][car][cac];\n            int dir = pd[cr][cc][car][cac];\n            int par = pf[cr][cc][car][cac];\n            int pac = pg[cr][cc][car][cac];\n            int prr = pr[cr][cc][car][cac];\n            int prc = pc[cr][cc][car][cac];\n            \n            path.push_back({act == 0 ? 'M' : (act == 1 ? 'S' : 'A'), DIR_CHAR[dir], cr, cc});\n            cr = prr; cc = prc; car = par; cac = pac;\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n    \n    auto is_connected = [&]() -> bool {\n        int sr = -1, sc = -1, fc = 0;\n        for (int r = 0; r < N; r++)\n            for (int c = 0; c < N; c++)\n                if (!block_grid[r][c]) { fc++; if (sr < 0) { sr = r; sc = c; } }\n        if (fc == 0) return true;\n        bool vis[20][20] = {};\n        queue<pair<int,int>> q;\n        q.push({sr, sc}); vis[sr][sc] = true; int cnt = 1;\n        while (!q.empty()) {\n            auto [r, c] = q.front(); q.pop();\n            for (int d = 0; d < 4; d++) {\n                int nr = r + DR[d], nc = c + DC[d];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !block_grid[nr][nc] && !vis[nr][nc]) {\n                    vis[nr][nc] = true; cnt++; q.push({nr, nc});\n                }\n            }\n        }\n        return cnt == fc;\n    };\n    \n    auto can_place = [&](int br, int bc) -> bool {\n        if (br < 0 || br >= N || bc < 0 || bc >= N) return false;\n        if (block_grid[br][bc]) return false;\n        if (is_target[br][bc]) return false;\n        block_grid[br][bc] = true;\n        bool ok = is_connected();\n        block_grid[br][bc] = false;\n        return ok;\n    };\n    \n    for (int t = 1; t < M; t++) {\n        int tr = targets[t].first, tc = targets[t].second;\n        auto path = bfs(cur_r, cur_c, tr, tc);\n        for (auto& [act, dir, nr, nc] : path) {\n            actions.push_back({act, dir});\n            if (act == 'A') {\n                int d = dir_map[dir];\n                int br = cur_r + DR[d], bc = cur_c + DC[d];\n                block_grid[br][bc] = !block_grid[br][bc];\n            } else if (act == 'M') {\n                int d = dir_map[dir];\n                cur_r += DR[d]; cur_c += DC[d];\n            } else {\n                int d = dir_map[dir];\n                int snr = cur_r, snc = cur_c;\n                while(true) {\n                    int nnr = snr + DR[d], nnc = snc + DC[d];\n                    if(nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || block_grid[nnr][nnc]) break;\n                    snr = nnr; snc = nnc;\n                }\n                cur_r = snr; cur_c = snc;\n            }\n        }\n        \n        for (int d : {1, 3}) {\n            int br = cur_r + DR[d], bc = cur_c + DC[d];\n            if (can_place(br, bc)) {\n                block_grid[br][bc] = true;\n                actions.push_back({'A', DIR_CHAR[d]});\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, r;\nvector<int> ra, rb, rc, rd;\n\ninline double satisfaction(long long s, long long rv) {\n    if (s <= 0 || rv <= 0) return 0;\n    double ratio = (double)min(s, rv) / max(s, rv);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\ndouble compute_score() {\n    double s = 0;\n    for (int i = 0; i < n; i++)\n        s += satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]), r[i]);\n    return s;\n}\n\nstruct TNode {\n    bool is_leaf; int company; bool vertical; int split_k;\n    vector<int> items; int lc, rc_node;\n    long long total_r, left_r; int maxL, minR;\n    int bL, bB, bR, bT;\n};\nvector<TNode> tree;\nvector<int> split_offset;\n\nint build_tree(vector<int> items, int L, int B, int R, int T, mt19937& rng, int strategy) {\n    int idx = tree.size();\n    tree.push_back({});\n    if (items.size() == 1) {\n        tree[idx] = {true, items[0], false, 0, items, -1, -1, (long long)r[items[0]], 0LL, 0, 0, L,B,R,T};\n        return idx;\n    }\n    int W = R-L, H = T-B;\n    long long total_area = (long long)W*H, total_r = 0;\n    for (int i : items) total_r += r[i];\n    struct Cand { bool vert; int k; double score; };\n    vector<Cand> cands;\n    for (int dir = 0; dir < 2; dir++) {\n        bool vert = (dir == 0);\n        if (vert && W <= 2) continue;\n        if (!vert && H <= 2) continue;\n        auto sorted = items;\n        sort(sorted.begin(), sorted.end(), [&](int i, int j) { return vert ? x[i]<x[j] : y[i]<y[j]; });\n        auto& coord = vert ? x : y;\n        long long sum = 0;\n        for (int k = 1; k < (int)sorted.size(); k++) {\n            sum += r[sorted[k-1]];\n            if (coord[sorted[k-1]] >= coord[sorted[k]]) continue;\n            int mxL = coord[sorted[k-1]], mnR = coord[sorted[k]];\n            int lo = vert?L:B, hi = vert?R:T;\n            int sp_lo = max(lo+1, mxL+1), sp_hi = min(hi-1, mnR);\n            if (sp_lo > sp_hi) continue;\n            long long ideal = lo + (long long)(hi-lo)*sum/total_r;\n            int sp = max(sp_lo, min(sp_hi, (int)ideal));\n            long long area1 = vert ? (long long)(sp-L)*H : (long long)W*(sp-B);\n            long long area2 = total_area - area1;\n            double sat = satisfaction(area1, sum) + satisfaction(area2, total_r-sum);\n            double noise;\n            switch(strategy%6) {\n                case 0: noise = uniform_real_distribution<double>(0,0.01)(rng); break;\n                case 1: noise = uniform_real_distribution<double>(0,0.1)(rng); break;\n                case 2: noise = uniform_real_distribution<double>(0,0.5)(rng); break;\n                case 3: noise = uniform_real_distribution<double>(0,1.0)(rng); break;\n                case 4: sat = -abs((double)sum/total_r-0.5); noise = uniform_real_distribution<double>(0,0.05)(rng); break;\n                case 5: sat *= 0.5; noise = uniform_real_distribution<double>(0,0.5)(rng); break;\n            }\n            cands.push_back({vert, k, sat + noise});\n        }\n    }\n    if (cands.empty()) {\n        tree[idx] = {true, items[0], false, 0, items, -1, -1, (long long)r[items[0]], 0LL, 0, 0, L,B,R,T};\n        return idx;\n    }\n    sort(cands.begin(), cands.end(), [](const Cand& a, const Cand& b) { return a.score > b.score; });\n    int top = min((int)cands.size(), 3);\n    uniform_int_distribution<int> dist(0, top-1);\n    const Cand& ch = cands[dist(rng)];\n    sort(items.begin(), items.end(), [&](int i, int j) { return ch.vert ? x[i]<x[j] : y[i]<y[j]; });\n    long long left_r = 0;\n    for (int k = 0; k < ch.k; k++) left_r += r[items[k]];\n    auto& coord = ch.vert ? x : y;\n    int mxL = coord[items[ch.k-1]], mnR = coord[items[ch.k]];\n    int lo = ch.vert?L:B, hi = ch.vert?R:T;\n    long long ideal = lo + (long long)(hi-lo)*left_r/total_r;\n    int sp = max(max(lo+1, mxL+1), min(min(hi-1, mnR), (int)ideal));\n    vector<int> li(items.begin(), items.begin()+ch.k), ri(items.begin()+ch.k, items.end());\n    int lc, rc2;\n    if (ch.vert) { lc = build_tree(li,L,B,sp,T,rng,strategy); rc2 = build_tree(ri,sp,B,R,T,rng,strategy); }\n    else { lc = build_tree(li,L,B,R,sp,rng,strategy); rc2 = build_tree(ri,L,sp,R,T,rng,strategy); }\n    tree[idx] = {false, -1, ch.vert, ch.k, items, lc, rc2, total_r, left_r, mxL, mnR, L,B,R,T};\n    return idx;\n}\n\nvoid compute_rects(int idx, int L, int B, int R, int T) {\n    if (tree[idx].is_leaf) { int i = tree[idx].company; ra[i]=L; rb[i]=B; rc[i]=R; rd[i]=T; return; }\n    int lo = tree[idx].vertical ? L : B, hi = tree[idx].vertical ? R : T;\n    long long ideal = lo + (long long)(hi-lo)*tree[idx].left_r/tree[idx].total_r;\n    int sp = (int)ideal + split_offset[idx];\n    sp = max(sp, tree[idx].maxL+1); sp = min(sp, tree[idx].minR);\n    sp = max(sp, lo+1); sp = min(sp, hi-1);\n    if (tree[idx].vertical) { compute_rects(tree[idx].lc,L,B,sp,T); compute_rects(tree[idx].rc_node,sp,B,R,T); }\n    else { compute_rects(tree[idx].lc,L,B,R,sp); compute_rects(tree[idx].rc_node,L,sp,R,T); }\n}\n\nvoid update_subtree(int idx) {\n    if (tree[idx].is_leaf) { int i = tree[idx].company; ra[i]=tree[idx].bL; rb[i]=tree[idx].bB; rc[i]=tree[idx].bR; rd[i]=tree[idx].bT; return; }\n    int L=tree[idx].bL, B=tree[idx].bB, R=tree[idx].bR, T=tree[idx].bT;\n    int lo = tree[idx].vertical ? L : B, hi = tree[idx].vertical ? R : T;\n    long long ideal = lo + (long long)(hi-lo)*tree[idx].left_r/tree[idx].total_r;\n    int sp = (int)ideal + split_offset[idx];\n    sp = max(sp, tree[idx].maxL+1); sp = min(sp, tree[idx].minR);\n    sp = max(sp, lo+1); sp = min(sp, hi-1);\n    int lc = tree[idx].lc, rc2 = tree[idx].rc_node;\n    if (tree[idx].vertical) {\n        tree[lc].bL=L; tree[lc].bB=B; tree[lc].bR=sp; tree[lc].bT=T;\n        tree[rc2].bL=sp; tree[rc2].bB=B; tree[rc2].bR=R; tree[rc2].bT=T;\n    } else {\n        tree[lc].bL=L; tree[lc].bB=B; tree[lc].bR=R; tree[lc].bT=sp;\n        tree[rc2].bL=L; tree[rc2].bB=sp; tree[rc2].bR=R; tree[rc2].bT=T;\n    }\n    update_subtree(lc); update_subtree(rc2);\n}\n\nvoid full_update(int root) { tree[root].bL=0; tree[root].bB=0; tree[root].bR=10000; tree[root].bT=10000; update_subtree(root); }\n\ndouble subtree_score(int idx) {\n    double s = 0;\n    for (int i : tree[idx].items) s += satisfaction((long long)(rc[i]-ra[i])*(rd[i]-rb[i]), r[i]);\n    return s;\n}\n\nvoid optimize_offsets(int root) {\n    split_offset.assign(tree.size(), 0);\n    compute_rects(root, 0, 0, 10000, 10000);\n    double best = compute_score();\n    vector<int> internal;\n    for (int i = 0; i < (int)tree.size(); i++) if (!tree[i].is_leaf) internal.push_back(i);\n    for (int round = 0; round < 15; round++) {\n        bool improved = false;\n        for (int idx : internal) {\n            for (int d : {-1000,-500,-200,-100,-50,-20,-10,-5,-2,-1,1,2,5,10,20,50,100,200,500,1000}) {\n                split_offset[idx] += d;\n                compute_rects(root, 0, 0, 10000, 10000);\n                bool valid = true;\n                for (int i = 0; i < n && valid; i++) if (ra[i]>x[i]||rc[i]<=x[i]||rb[i]>y[i]||rd[i]<=y[i]) valid = false;\n                if (valid) { double ns = compute_score(); if (ns > best+1e-12) { best=ns; improved=true; continue; } }\n                split_offset[idx] -= d;\n            }\n        }\n        if (!improved) break;\n    }\n    compute_rects(root, 0, 0, 10000, 10000);\n}\n\nvoid sa_offsets(int root, unsigned sa_seed, int max_iter) {\n    full_update(root);\n    vector<int> internal;\n    for (int i = 0; i < (int)tree.size(); i++) if (!tree[i].is_leaf) internal.push_back(i);\n    if (internal.empty()) return;\n    double cur = compute_score(), best = cur;\n    vector<int> best_off = split_offset;\n    mt19937 rng(sa_seed);\n    uniform_int_distribution<int> idist(0, (int)internal.size()-1);\n    uniform_real_distribution<double> adist(0, 1);\n    double temp = 0.03;\n    for (int iter = 0; iter < max_iter; iter++) {\n        int idx = internal[idist(rng)];\n        int d;\n        if (iter < max_iter/5) d = uniform_int_distribution<int>(-500,500)(rng);\n        else if (iter < max_iter*2/5) d = uniform_int_distribution<int>(-100,100)(rng);\n        else if (iter < max_iter*4/5) d = uniform_int_distribution<int>(-10,10)(rng);\n        else d = uniform_int_distribution<int>(-3,3)(rng);\n        if (!d) continue;\n        double old_s = subtree_score(idx);\n        split_offset[idx] += d;\n        update_subtree(idx);\n        bool valid = true;\n        for (int i : tree[idx].items) if (ra[i]>x[i]||rc[i]<=x[i]||rb[i]>y[i]||rd[i]<=y[i]) { valid = false; break; }\n        if (!valid) { split_offset[idx] -= d; update_subtree(idx); continue; }\n        double new_s = subtree_score(idx);\n        double diff = new_s - old_s;\n        if (diff > 0 || adist(rng) < exp(diff/temp)) { cur += diff; if (cur > best) { best = cur; best_off = split_offset; } }\n        else { split_offset[idx] -= d; update_subtree(idx); }\n        temp *= 0.99997;\n    }\n    split_offset = best_off; full_update(root);\n}\n\nvoid post_process() {\n    for (int i = 0; i < n; i++) {\n        while (true) {\n            long long area = (long long)(rc[i]-ra[i])*(rd[i]-rb[i]);\n            if (area <= r[i]) break;\n            double cs = satisfaction(area, r[i]);\n            int bd=-1,bdr=0; double bs=cs;\n            auto try_s = [&](int dim, int dir) {\n                int na=ra[i],nb=rb[i],nc=rc[i],nd=rd[i];\n                if(dim==0&&dir==1)nc--;else if(dim==0&&dir==-1)na++;\n                else if(dim==1&&dir==1)nd--;else nb++;\n                if(na>x[i]||nc<=x[i]||nb>y[i]||nd<=y[i])return;\n                if(nc-na<1||nd-nb<1)return;\n                double ns=satisfaction((long long)(nc-na)*(nd-nb),r[i]);\n                if(ns>bs+1e-12){bs=ns;bd=dim;bdr=dir;}\n            };\n            try_s(0,1);try_s(0,-1);try_s(1,1);try_s(1,-1);\n            if(bd<0)break;\n            if(bd==0&&bdr==1)rc[i]--;else if(bd==0&&bdr==-1)ra[i]++;\n            else if(bd==1&&bdr==1)rd[i]--;else rb[i]++;\n        }\n    }\n    for (int step : {1000,500,200,100,50,20,10,5,2,1}) {\n        bool any = true;\n        while (any) {\n            any = false;\n            vector<pair<double,int>> order;\n            for (int i = 0; i < n; i++) {\n                long long area = (long long)(rc[i]-ra[i])*(rd[i]-rb[i]);\n                if (area < r[i]) order.push_back({-(1.0-satisfaction(area,r[i])), i});\n            }\n            sort(order.begin(), order.end());\n            for (auto& [_, i] : order) {\n                long long area = (long long)(rc[i]-ra[i])*(rd[i]-rb[i]);\n                if (area >= r[i]) continue;\n                double cs = satisfaction(area, r[i]);\n                auto try_e = [&](int dim, int dir) -> bool {\n                    int na=ra[i],nb=rb[i],nc=rc[i],nd=rd[i];\n                    if(dim==0&&dir==1)nc+=step;else if(dim==0&&dir==-1)na-=step;\n                    else if(dim==1&&dir==1)nd+=step;else nb-=step;\n                    if(na<0||nc>10000||nb<0||nd>10000)return false;\n                    if(na>x[i]||nc<=x[i]||nb>y[i]||nd<=y[i])return false;\n                    for(int j=0;j<n;j++){if(j==i)continue;if(na<rc[j]&&nc>ra[j]&&nb<rd[j]&&nd>rb[j])return false;}\n                    double ns=satisfaction((long long)(nc-na)*(nd-nb),r[i]);\n                    if(ns>cs+1e-12){ra[i]=na;rb[i]=nb;rc[i]=nc;rd[i]=nd;return true;}\n                    return false;\n                };\n                if(try_e(0,1)||try_e(0,-1)||try_e(1,1)||try_e(1,-1))any=true;\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> n; x.resize(n); y.resize(n); r.resize(n); ra.resize(n); rb.resize(n); rc.resize(n); rd.resize(n);\n    for (int i = 0; i < n; i++) cin >> x[i] >> y[i] >> r[i];\n    auto start = chrono::steady_clock::now();\n    vector<int> indices(n); iota(indices.begin(), indices.end(), 0);\n    vector<int> ba(n),bb(n),bc(n),bd(n); double bs=-1;\n    vector<pair<double,unsigned>> candidates;\n    \n    for (unsigned seed = 0; ; seed++) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now-start).count()>2000) break;\n        tree.clear(); split_offset.clear(); mt19937 rng(seed);\n        int root = build_tree(indices, 0, 0, 10000, 10000, rng, seed%6);\n        optimize_offsets(root);\n        post_process();\n        double s = compute_score();\n        candidates.push_back({s, seed});\n        if (s > bs) { bs=s; ba=ra; bb=rb; bc=rc; bd=rd; }\n    }\n    \n    sort(candidates.rbegin(), candidates.rend());\n    int top_k = min((int)candidates.size(), 10);\n    for (int ci = 0; ci < top_k; ci++) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now-start).count()>4600) break;\n        unsigned seed = candidates[ci].second;\n        tree.clear(); split_offset.clear(); mt19937 rng(seed);\n        int root = build_tree(indices, 0, 0, 10000, 10000, rng, seed%6);\n        optimize_offsets(root);\n        sa_offsets(root, seed*7919+42, 300000);\n        post_process();\n        double s = compute_score();\n        if (s > bs) { bs=s; ba=ra; bb=rb; bc=rc; bd=rd; }\n    }\n    \n    ra=ba; rb=bb; rc=bc; rd=bd;\n    for (int i = 0; i < n; i++) cout << ra[i]<<\" \"<<rb[i]<<\" \"<<rc[i]<<\" \"<<rd[i]<<\"\\n\";\n    return 0;\n}","ahc002":"#include <iostream>\n#include <string>\n#include <cstring>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nconst int N = 50;\nint si, sj;\nint T[N][N], P[N][N], tile_total[2500];\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dc[] = {'U', 'D', 'L', 'R'};\n\nmt19937 rng(42);\nint vis[N][N], tused_arr[2500];\nchar path_buf[3000];\nint best_len = 0;\nchar best_buf[3000];\nlong long best_score = -1;\n\nint extend_path(int ci, int cj, long long& score, int start_len, int eps_x10000, int exit_w_x10, int w2_w_x10, int val_w_x10) {\n    int len = start_len;\n    while (true) {\n        int cands[4], nc = 0;\n        int nv_arr[4], ex_arr[4], mne_arr[4];\n        for (int d = 0; d < 4; d++) {\n            int ni = ci+dx[d], nj = cj+dy[d];\n            if (ni<0||ni>=N||nj<0||nj>=N) continue;\n            if (vis[ni][nj]) continue;\n            if (tused_arr[T[ni][nj]]) continue;\n            \n            vis[ni][nj] = 1; tused_arr[T[ni][nj]] = 1;\n            int ex = 0, mne = 4;\n            for (int dd = 0; dd < 4; dd++) {\n                int ni2 = ni+dx[dd], nj2 = nj+dy[dd];\n                if (ni2<0||ni2>=N||nj2<0||nj2>=N) continue;\n                if (vis[ni2][nj2]) continue;\n                if (tused_arr[T[ni2][nj2]]) continue;\n                ex++;\n                vis[ni2][nj2] = 1; tused_arr[T[ni2][nj2]] = 1;\n                int ne = 0;\n                for (int ddd = 0; ddd < 4; ddd++) {\n                    int ni3 = ni2+dx[ddd], nj3 = nj2+dy[ddd];\n                    if (ni3<0||ni3>=N||nj3<0||nj3>=N) continue;\n                    if (vis[ni3][nj3]) continue;\n                    if (tused_arr[T[ni3][nj3]]) continue;\n                    ne++;\n                }\n                vis[ni2][nj2] = 0; tused_arr[T[ni2][nj2]] = 0;\n                if (ne < mne) mne = ne;\n            }\n            vis[ni][nj] = 0; tused_arr[T[ni][nj]] = 0;\n            \n            cands[nc] = d;\n            ex_arr[nc] = ex;\n            mne_arr[nc] = mne;\n            nv_arr[nc] = 2 * P[ni][nj] - tile_total[T[ni][nj]];\n            nc++;\n        }\n        if (nc == 0) break;\n        \n        int chosen;\n        if (nc > 1 && (int)(rng() % 10000) < eps_x10000) {\n            chosen = cands[rng() % nc];\n        } else {\n            int bi = 0;\n            long long bev = (long long)val_w_x10 * nv_arr[0] + (long long)exit_w_x10 * ex_arr[0] + (long long)w2_w_x10 * mne_arr[0];\n            if (ex_arr[0] == 0) bev -= 100000000;\n            else if (ex_arr[0] == 1 && mne_arr[0] == 0) bev -= 50000000;\n            for (int i = 1; i < nc; i++) {\n                long long ev = (long long)val_w_x10 * nv_arr[i] + (long long)exit_w_x10 * ex_arr[i] + (long long)w2_w_x10 * mne_arr[i];\n                if (ex_arr[i] == 0) ev -= 100000000;\n                else if (ex_arr[i] == 1 && mne_arr[i] == 0) ev -= 50000000;\n                if (ev > bev) { bev = ev; bi = i; }\n            }\n            chosen = cands[bi];\n        }\n        \n        int ni = ci+dx[chosen], nj = cj+dy[chosen];\n        vis[ni][nj] = 1; tused_arr[T[ni][nj]] = 1;\n        score += P[ni][nj];\n        path_buf[len++] = dc[chosen];\n        ci = ni; cj = nj;\n    }\n    return len;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> si >> sj;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> T[i][j];\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> P[i][j];\n    \n    memset(tile_total, 0, sizeof(tile_total));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) tile_total[T[i][j]] += P[i][j];\n    \n    auto start_time = chrono::steady_clock::now();\n    \n    for (int iter = 0; ; iter++) {\n        if (iter % 200 == 0) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration_cast<chrono::milliseconds>(now - start_time).count() > 1700) break;\n        }\n        \n        int eps_x10000 = 100 + rng() % 400;\n        int exit_w_x10 = -(30 + rng() % 250);\n        int w2_w_x10 = -(10 + rng() % 120);\n        int val_w_x10 = 1 + rng() % 10;\n        \n        int new_len;\n        long long new_score;\n        \n        if (best_len == 0 || iter % 3 == 0) {\n            memset(vis, 0, sizeof(vis));\n            memset(tused_arr, 0, sizeof(tused_arr));\n            vis[si][sj] = 1; tused_arr[T[si][sj]] = 1;\n            new_score = P[si][sj];\n            new_len = extend_path(si, sj, new_score, 0, eps_x10000, exit_w_x10, w2_w_x10, val_w_x10);\n        } else {\n            int cut;\n            int r = rng() % 10;\n            if (r < 2) cut = 0;\n            else if (r < 5) cut = rng() % (best_len + 1);\n            else cut = max(0, best_len - 1 - (int)(rng() % 80));\n            \n            for (int k = 0; k < cut; k++) path_buf[k] = best_buf[k];\n            \n            memset(vis, 0, sizeof(vis));\n            memset(tused_arr, 0, sizeof(tused_arr));\n            int ci = si, cj = sj;\n            vis[ci][cj] = 1; tused_arr[T[ci][cj]] = 1;\n            new_score = P[ci][cj];\n            for (int k = 0; k < cut; k++) {\n                int d = (path_buf[k]=='U')?0:(path_buf[k]=='D')?1:(path_buf[k]=='L')?2:3;\n                ci += dx[d]; cj += dy[d];\n                vis[ci][cj] = 1; tused_arr[T[ci][cj]] = 1;\n                new_score += P[ci][cj];\n            }\n            \n            new_len = extend_path(ci, cj, new_score, cut, eps_x10000, exit_w_x10, w2_w_x10, val_w_x10);\n        }\n        \n        if (new_score > best_score) {\n            best_score = new_score;\n            best_len = new_len;\n            memcpy(best_buf, path_buf, new_len);\n        }\n    }\n    \n    for (int i = 0; i < best_len; i++) cout << best_buf[i];\n    cout << endl;\n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\ndouble row_h[N], col_v[N], row_h_var[N], col_v_var[N];\ndouble h_dev[N][N-1], v_dev[N-1][N], h_dev_var[N][N-1], v_dev_var[N-1][N];\nmt19937 rng(42);\nnormal_distribution<double> norm_dist(0, 1);\n\ndouble get_h_est(int i, int j) { return row_h[i] + h_dev[i][j]; }\ndouble get_v_est(int i, int j) { return col_v[j] + v_dev[i][j]; }\n\npair<string,double> dijkstra_with_cost(int si, int sj, int ti, int tj, double temperature) {\n    double hw[N][N-1], vw[N-1][N];\n    for(int i=0; i<N; i++) {\n        double rh = row_h[i] + temperature * sqrt(max(1.0, row_h_var[i])) * norm_dist(rng);\n        for(int j=0; j<N-1; j++){\n            double hd = h_dev[i][j] + temperature * sqrt(max(1.0, h_dev_var[i][j])) * norm_dist(rng);\n            hw[i][j] = max(100.0, min(20000.0, rh + hd));\n        }\n    }\n    for(int j=0; j<N; j++) {\n        double cv = col_v[j] + temperature * sqrt(max(1.0, col_v_var[j])) * norm_dist(rng);\n        for(int i=0; i<N-1; i++){\n            double vd = v_dev[i][j] + temperature * sqrt(max(1.0, v_dev_var[i][j])) * norm_dist(rng);\n            vw[i][j] = max(100.0, min(20000.0, cv + vd));\n        }\n    }\n    double dist[N][N]; pair<int,int> prev_node[N][N]; bool vis[N][N] = {};\n    for(int i=0; i<N; i++) for(int j=0; j<N; j++) dist[i][j] = 1e18;\n    dist[si][sj] = 0;\n    priority_queue<tuple<double,int,int>, vector<tuple<double,int,int>>, greater<tuple<double,int,int>>> pq;\n    pq.push(make_tuple(0.0, si, sj));\n    while(!pq.empty()){\n        auto [d, i, j] = pq.top(); pq.pop();\n        if(vis[i][j]) continue; vis[i][j] = true;\n        if(i==ti && j==tj) break;\n        if(i > 0 && !vis[i-1][j]) { double w = vw[i-1][j]; if(d+w < dist[i-1][j]) { dist[i-1][j] = d+w; prev_node[i-1][j] = {i,j}; pq.push(make_tuple(dist[i-1][j], i-1, j)); } }\n        if(i < N-1 && !vis[i+1][j]) { double w = vw[i][j]; if(d+w < dist[i+1][j]) { dist[i+1][j] = d+w; prev_node[i+1][j] = {i,j}; pq.push(make_tuple(dist[i+1][j], i+1, j)); } }\n        if(j > 0 && !vis[i][j-1]) { double w = hw[i][j-1]; if(d+w < dist[i][j-1]) { dist[i][j-1] = d+w; prev_node[i][j-1] = {i,j}; pq.push(make_tuple(dist[i][j-1], i, j-1)); } }\n        if(j < N-1 && !vis[i][j+1]) { double w = hw[i][j]; if(d+w < dist[i][j+1]) { dist[i][j+1] = d+w; prev_node[i][j+1] = {i,j}; pq.push(make_tuple(dist[i][j+1], i, j+1)); } }\n    }\n    string path; double mean_cost = 0; int ci = ti, cj = tj;\n    while(ci != si || cj != sj){\n        auto [pi, pj] = prev_node[ci][cj];\n        if(pi == ci-1) { path += 'D'; mean_cost += get_v_est(ci-1, cj); }\n        else if(pi == ci+1) { path += 'U'; mean_cost += get_v_est(ci, cj); }\n        else if(pj == cj-1) { path += 'R'; mean_cost += get_h_est(ci, cj-1); }\n        else { path += 'L'; mean_cost += get_h_est(ci, cj); }\n        ci = pi; cj = pj;\n    }\n    reverse(path.begin(), path.end());\n    return {path, mean_cost};\n}\n\nvoid update(int si, int sj, const string& path, int observed) {\n    struct E { char t; int i, j; }; vector<E> edges;\n    map<int,int> hr, vc; int ci = si, cj = sj;\n    for(char c : path){\n        if(c == 'U') { edges.push_back({'v', ci-1, cj}); vc[cj]++; ci--; }\n        else if(c == 'D') { edges.push_back({'v', ci, cj}); vc[cj]++; ci++; }\n        else if(c == 'L') { edges.push_back({'h', ci, cj-1}); hr[ci]++; cj--; }\n        else { edges.push_back({'h', ci, cj}); hr[ci]++; cj++; }\n    }\n    double pred = 0;\n    for(auto& e : edges) pred += (e.t == 'h') ? get_h_est(e.i, e.j) : get_v_est(e.i, e.j);\n    double residual = observed - pred;\n    double obs_var = pred * pred / 300.0;\n    double S = obs_var;\n    for(auto& [i, n] : hr) S += n * n * row_h_var[i];\n    for(auto& [j, n] : vc) S += n * n * col_v_var[j];\n    for(auto& e : edges) S += (e.t == 'h') ? h_dev_var[e.i][e.j] : v_dev_var[e.i][e.j];\n    for(auto& [i, n] : hr) {\n        double K = row_h_var[i] * n / S; row_h[i] += K * residual; row_h_var[i] *= (1 - K * n);\n        row_h[i] = max(500.0, min(15000.0, row_h[i])); row_h_var[i] = max(100.0, row_h_var[i]);\n    }\n    for(auto& [j, n] : vc) {\n        double K = col_v_var[j] * n / S; col_v[j] += K * residual; col_v_var[j] *= (1 - K * n);\n        col_v[j] = max(500.0, min(15000.0, col_v[j])); col_v_var[j] = max(100.0, col_v_var[j]);\n    }\n    for(auto& e : edges){\n        double& dev = (e.t == 'h') ? h_dev[e.i][e.j] : v_dev[e.i][e.j];\n        double& dv = (e.t == 'h') ? h_dev_var[e.i][e.j] : v_dev_var[e.i][e.j];\n        double K = dv / S; dev += K * residual; dv *= (1 - K);\n        dev = max(-5000.0, min(5000.0, dev)); dv = max(100.0, dv);\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    for(int i=0; i<N; i++) { row_h[i] = col_v[i] = 5000.0; row_h_var[i] = col_v_var[i] = 5000000.0; }\n    for(int i=0; i<N; i++) for(int j=0; j<N-1; j++) { h_dev[i][j] = 0.0; h_dev_var[i][j] = 2000000.0; }\n    for(int i=0; i<N-1; i++) for(int j=0; j<N; j++) { v_dev[i][j] = 0.0; v_dev_var[i][j] = 2000000.0; }\n    for(int k=0; k<1000; k++){\n        int si, sj, ti, tj; cin >> si >> sj >> ti >> tj;\n        double temperature = max(0.0, 1.0 - k / 350.0);\n        string best_path; double best_cost = 1e18;\n        for(int t=0; t<5; t++){\n            auto [path, cost] = dijkstra_with_cost(si, sj, ti, tj, temperature);\n            if(cost < best_cost) { best_cost = cost; best_path = path; }\n        }\n        cout << best_path << endl;\n        int obs; cin >> obs; update(si, sj, best_path, obs);\n    }\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <array>\n\nusing namespace std;\n\nstruct Entry {\n    uint16_t m, pi;\n};\n\nint N, M;\nvector<string> s;\nvector<int> slen;\nvector<Entry> adj[400][8];\nvector<int8_t> matchCount;\nvector<int16_t> fullMatchCount;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M;\n    s.resize(M);\n    for (int m = 0; m < M; m++) cin >> s[m];\n    \n    const int NUM_CHARS = 8;\n    mt19937 rng(42);\n    auto start_time = chrono::high_resolution_clock::now();\n    \n    slen.resize(M);\n    for (int m = 0; m < M; m++) slen[m] = s[m].length();\n    \n    // Fast EM Initialization\n    vector<array<double, 8>> charProb(N * N);\n    for (int i = 0; i < N * N; i++) for (int c = 0; c < NUM_CHARS; c++) charProb[i][c] = 1.0 / NUM_CHARS;\n    \n    for (int iter = 0; iter < 30; iter++) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration<double>(now - start_time).count() > 0.15) break;\n        \n        vector<array<double, 8>> newProb(N * N);\n        for (int i = 0; i < N * N; i++) newProb[i].fill(0);\n        \n        for (int m = 0; m < M; m++) {\n            int k = slen[m];\n            vector<double> weights(2 * N * N);\n            double maxW = 0;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    double wH = 1.0, wV = 1.0;\n                    for (int p = 0; p < k; p++) {\n                        wH *= charProb[i * N + (j + p) % N][s[m][p] - 'A'];\n                        wV *= charProb[((i + p) % N) * N + j][s[m][p] - 'A'];\n                    }\n                    weights[2 * (i * N + j)] = wH;\n                    weights[2 * (i * N + j) + 1] = wV;\n                    if (wH > maxW) maxW = wH;\n                    if (wV > maxW) maxW = wV;\n                }\n            }\n            \n            if (maxW < 1e-300) continue;\n            double sumW = 0;\n            for (int pi = 0; pi < 2 * N * N; pi++) { weights[pi] /= maxW; sumW += weights[pi]; }\n            if (sumW < 1e-300) continue;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    double wH = weights[2 * (i * N + j)] / sumW;\n                    double wV = weights[2 * (i * N + j) + 1] / sumW;\n                    for (int p = 0; p < k; p++) {\n                        newProb[i * N + (j + p) % N][s[m][p] - 'A'] += wH;\n                        newProb[((i + p) % N) * N + j][s[m][p] - 'A'] += wV;\n                    }\n                }\n            }\n        }\n        \n        for (int i = 0; i < N * N; i++) {\n            double sum = 0;\n            for (int c = 0; c < NUM_CHARS; c++) sum += newProb[i][c];\n            if (sum > 0) {\n                for (int c = 0; c < NUM_CHARS; c++) newProb[i][c] = max(newProb[i][c] / sum, 1e-4);\n                double sum2 = 0;\n                for (int c = 0; c < NUM_CHARS; c++) sum2 += newProb[i][c];\n                for (int c = 0; c < NUM_CHARS; c++) newProb[i][c] /= sum2;\n            } else {\n                for (int c = 0; c < NUM_CHARS; c++) newProb[i][c] = 1.0 / NUM_CHARS;\n            }\n        }\n        charProb = move(newProb);\n    }\n    \n    vector<string> mat(N, string(N, 'A'));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            double maxP = 0; char best = 'A';\n            for (int c = 0; c < NUM_CHARS; c++) if (charProb[i * N + j][c] > maxP) { maxP = charProb[i * N + j][c]; best = 'A' + c; }\n            mat[i][j] = best;\n        }\n    }\n    \n    // Build Character-Based Adjacency Lists\n    for (int m = 0; m < M; m++) {\n        int k = slen[m];\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int piH = 2 * (i * N + j);\n                for (int p = 0; p < k; p++) adj[i * N + (j + p) % N][s[m][p] - 'A'].push_back({(uint16_t)m, (uint16_t)piH});\n                int piV = 2 * (i * N + j) + 1;\n                for (int p = 0; p < k; p++) adj[((i + p) % N) * N + j][s[m][p] - 'A'].push_back({(uint16_t)m, (uint16_t)piV});\n            }\n        }\n    }\n    \n    // Match Counts\n    matchCount.resize(M * 800, 0);\n    fullMatchCount.resize(M, 0);\n    int totalMatched = 0, numDots = 0;\n    \n    auto recompute = [&]() {\n        numDots = 0;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (mat[i][j] == '.') numDots++;\n        for (int m = 0; m < M; m++) {\n            int k = slen[m]; fullMatchCount[m] = 0;\n            int base = m * 800;\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n                int cH = 0, cV = 0;\n                for (int p = 0; p < k; p++) { if (mat[i][(j+p)%N] == s[m][p]) cH++; if (mat[(i+p)%N][j] == s[m][p]) cV++; }\n                matchCount[base + 2*(i*N+j)] = cH; matchCount[base + 2*(i*N+j)+1] = cV;\n                if (cH == k) fullMatchCount[m]++; if (cV == k) fullMatchCount[m]++;\n            }\n        }\n        totalMatched = 0;\n        for (int m = 0; m < M; m++) if (fullMatchCount[m] > 0) totalMatched++;\n    };\n    \n    recompute();\n    int bestMatched = totalMatched, bestDots = -1;\n    vector<string> bestMat = mat;\n    if (totalMatched == M) bestDots = numDots;\n    \n    // SA Phase\n    int stepCount = 0;\n    double lastTime = chrono::duration<double>(chrono::high_resolution_clock::now() - start_time).count();\n    \n    while (true) {\n        stepCount++;\n        if ((stepCount & 0xFFF) == 0) {\n            lastTime = chrono::duration<double>(chrono::high_resolution_clock::now() - start_time).count();\n            if (lastTime > 2.7) break;\n        }\n        double temp = 1.5 * max(0.0, 1.0 - lastTime / 2.8) + 0.01;\n        \n        int ci = -1, cj = -1;\n        char newC;\n        int moveType = rng() % 100;\n        \n        // 15% Multi-cell string-level move\n        if (moveType < 15 && totalMatched < M) {\n            int start_m = rng() % M;\n            int m = -1;\n            for (int t = 0; t < M; t++) {\n                int rm = (start_m + t) % M;\n                if (fullMatchCount[rm] == 0) { m = rm; break; }\n            }\n            if (m != -1) {\n                int k = slen[m], bestMC = -1, bestPi = -1, base = m * 800;\n                for (int pi = 0; pi < 2 * N * N; pi++) if (matchCount[base + pi] > bestMC) { bestMC = matchCount[base + pi]; bestPi = pi; }\n                if (bestPi != -1) {\n                    int dir = bestPi % 2, ij = bestPi / 2, si = ij / N, sj = ij % N;\n                    int deltaMatched = 0, deltaDots = 0;\n                    char oldChars[13];\n                    \n                    for (int p = 0; p < k; p++) {\n                        int ci2 = dir == 0 ? si : (si + p) % N, cj2 = dir == 0 ? (sj + p) % N : sj;\n                        int idx2 = ci2 * N + cj2;\n                        oldChars[p] = mat[ci2][cj2];\n                        newC = s[m][p];\n                        if (oldChars[p] == newC) continue;\n                        if (oldChars[p] == '.') deltaDots--;\n                        if (oldChars[p] != '.') { for (auto& e : adj[idx2][oldChars[p] - 'A']) { int m2 = e.m, pi2 = e.pi, k2 = slen[m2]; int8_t oMC = matchCount[m2*800+pi2]; matchCount[m2*800+pi2] = oMC - 1; if (oMC == k2) { if (fullMatchCount[m2] == 1) deltaMatched--; fullMatchCount[m2]--; } } }\n                        if (newC != '.') { for (auto& e : adj[idx2][newC - 'A']) { int m2 = e.m, pi2 = e.pi, k2 = slen[m2]; int8_t oMC = matchCount[m2*800+pi2]; matchCount[m2*800+pi2] = oMC + 1; if (oMC + 1 == k2) { if (fullMatchCount[m2] == 0) deltaMatched++; fullMatchCount[m2]++; } } }\n                        mat[ci2][cj2] = newC;\n                    }\n                    \n                    bool accept = false;\n                    if (deltaMatched > 0) accept = true;\n                    else if (deltaMatched == 0) accept = (rng() % 2 == 0);\n                    else if (totalMatched == M && totalMatched + deltaMatched < M) accept = false;\n                    else accept = (rng() % 10000 < (int)(exp((double)deltaMatched / temp) * 10000));\n\n                    if (accept) {\n                        totalMatched += deltaMatched; numDots += deltaDots;\n                        if (totalMatched > bestMatched || (totalMatched == M && numDots > bestDots)) { bestMatched = totalMatched; bestMat = mat; if (totalMatched == M) bestDots = numDots; }\n                    } else {\n                        for (int p = k - 1; p >= 0; p--) {\n                            int ci2 = dir == 0 ? si : (si + p) % N, cj2 = dir == 0 ? (sj + p) % N : sj;\n                            int idx2 = ci2 * N + cj2;\n                            char nc = s[m][p], oc = oldChars[p];\n                            if (oc == nc) continue;\n                            if (nc != '.') { for (auto& e : adj[idx2][nc - 'A']) { int m2 = e.m, pi2 = e.pi, k2 = slen[m2]; int8_t curMC = matchCount[m2*800+pi2]; matchCount[m2*800+pi2] = curMC - 1; if (curMC == k2) fullMatchCount[m2]--; } }\n                            if (oc != '.') { for (auto& e : adj[idx2][oc - 'A']) { int m2 = e.m, pi2 = e.pi, k2 = slen[m2]; int8_t curMC = matchCount[m2*800+pi2]; matchCount[m2*800+pi2] = curMC + 1; if (curMC + 1 == k2) fullMatchCount[m2]++; } }\n                            mat[ci2][cj2] = oc;\n                        }\n                    }\n                }\n                continue;\n            }\n        } else if (moveType < 50 && totalMatched < M) {\n            // 35% Targeted single-cell move\n            int start_m = rng() % M;\n            int m = -1;\n            for (int t = 0; t < M; t++) {\n                int rm = (start_m + t) % M;\n                if (fullMatchCount[rm] == 0) { m = rm; break; }\n            }\n            if (m != -1) {\n                int k = slen[m];\n                int bestMC = -1, bestPi = -1, base = m * 800;\n                for (int pi = 0; pi < 2 * N * N; pi++) if (matchCount[base + pi] > bestMC) { bestMC = matchCount[base + pi]; bestPi = pi; }\n                \n                if (bestPi != -1) {\n                    int dir = bestPi % 2, ij = bestPi / 2, si = ij / N, sj = ij % N;\n                    int mis[13]; int numMis = 0;\n                    for (int p = 0; p < k; p++) {\n                        int ci2 = dir == 0 ? si : (si + p) % N, cj2 = dir == 0 ? (sj + p) % N : sj;\n                        if (mat[ci2][cj2] != s[m][p]) mis[numMis++] = p;\n                    }\n                    if (numMis > 0) {\n                        int p = mis[rng() % numMis];\n                        ci = dir == 0 ? si : (si + p) % N;\n                        cj = dir == 0 ? (sj + p) % N : sj;\n                        newC = s[m][p];\n                    }\n                }\n            }\n        }\n        \n        if (ci == -1) {\n            ci = rng() % N; cj = rng() % N;\n            char oldC = mat[ci][cj];\n            if (totalMatched == M && (rng() % 2 == 0)) {\n                newC = '.';\n            } else {\n                if (rng() % 10 < 7) {\n                    int r = rng() % 8;\n                    bool found = false;\n                    for (int t = 0; t < 8; t++) {\n                        int c = (r + t) % 8;\n                        if (!adj[ci * N + cj][c].empty() && 'A' + c != oldC) {\n                            newC = 'A' + c; found = true; break;\n                        }\n                    }\n                    if (!found) {\n                        newC = 'A' + rng() % 7;\n                        if (newC >= oldC) newC++;\n                    }\n                } else {\n                    newC = 'A' + rng() % 7;\n                    if (newC >= oldC) newC++;\n                }\n            }\n        }\n        \n        // Single-cell SA evaluation\n        int idx = ci * N + cj;\n        char oldC = mat[ci][cj];\n        if (newC == oldC) continue;\n        \n        int deltaMatched = 0;\n        int deltaDots = (newC == '.' && oldC != '.') ? 1 : ((newC != '.' && oldC == '.') ? -1 : 0);\n        \n        if (oldC != '.') {\n            for (auto& e : adj[idx][oldC - 'A']) {\n                int m = e.m, pi = e.pi, k = slen[m];\n                if (matchCount[m*800+pi] == k) {\n                    if (fullMatchCount[m] == 1) deltaMatched--;\n                    fullMatchCount[m]--;\n                }\n                matchCount[m*800+pi]--;\n            }\n        }\n        if (newC != '.') {\n            for (auto& e : adj[idx][newC - 'A']) {\n                int m = e.m, pi = e.pi, k = slen[m];\n                matchCount[m*800+pi]++;\n                if (matchCount[m*800+pi] == k) {\n                    if (fullMatchCount[m] == 0) deltaMatched++;\n                    fullMatchCount[m]++;\n                }\n            }\n        }\n        \n        bool accept = false;\n        if (deltaMatched > 0) accept = true;\n        else if (deltaMatched == 0) {\n            if (totalMatched == M) {\n                if (deltaDots > 0) accept = true;\n                else if (deltaDots == 0) accept = (rng() % 2 == 0);\n                else accept = (rng() % 10000 < (int)(exp((double)deltaDots / temp) * 10000));\n            } else {\n                accept = (rng() % 2 == 0);\n            }\n        }\n        else if (totalMatched == M && totalMatched + deltaMatched < M) accept = false;\n        else accept = (rng() % 10000 < (int)(exp((double)deltaMatched / temp) * 10000));\n        \n        if (accept) {\n            mat[ci][cj] = newC; totalMatched += deltaMatched; numDots += deltaDots;\n            if (totalMatched > bestMatched || (totalMatched == M && numDots > bestDots)) { bestMatched = totalMatched; bestMat = mat; if (totalMatched == M) bestDots = numDots; }\n        } else {\n            if (newC != '.') { for (auto& e : adj[idx][newC - 'A']) { int m = e.m, pi = e.pi, k = slen[m]; int8_t curMC = matchCount[m*800+pi]; matchCount[m*800+pi] = curMC - 1; if (curMC == k) fullMatchCount[m]--; } }\n            if (oldC != '.') { for (auto& e : adj[idx][oldC - 'A']) { int m = e.m, pi = e.pi, k = slen[m]; int8_t curMC = matchCount[m*800+pi]; matchCount[m*800+pi] = curMC + 1; if (curMC + 1 == k) fullMatchCount[m]++; } }\n        }\n    }\n    \n    mat = bestMat; recompute();\n    \n    // Greedy Repair\n    for (int rep = 0; rep < 5; rep++) {\n        bool anyImproved = false;\n        for (int m = 0; m < M; m++) {\n            if (fullMatchCount[m] > 0) continue;\n            int k = slen[m], bestMC = -1, bestPi = -1, base = m * 800;\n            for (int pi = 0; pi < 2 * N * N; pi++) if (matchCount[base + pi] > bestMC) { bestMC = matchCount[base + pi]; bestPi = pi; }\n            if (bestPi < 0) continue;\n            int dir = bestPi % 2, ij = bestPi / 2, si = ij / N, sj = ij % N;\n            int deltaMatched = 0, deltaDots = 0;\n            char oldChars[13];\n            \n            for (int p = 0; p < k; p++) {\n                int ci2 = dir == 0 ? si : (si + p) % N, cj2 = dir == 0 ? (sj + p) % N : sj;\n                int idx2 = ci2 * N + cj2;\n                oldChars[p] = mat[ci2][cj2];\n                char nc = s[m][p];\n                if (oldChars[p] == nc) continue;\n                if (oldChars[p] == '.') deltaDots--;\n                if (oldChars[p] != '.') { for (auto& e : adj[idx2][oldChars[p] - 'A']) { int m2 = e.m, pi2 = e.pi, k2 = slen[m2]; int8_t oMC = matchCount[m2*800+pi2]; matchCount[m2*800+pi2] = oMC - 1; if (oMC == k2) { if (fullMatchCount[m2] == 1) deltaMatched--; fullMatchCount[m2]--; } } }\n                if (nc != '.') { for (auto& e : adj[idx2][nc - 'A']) { int m2 = e.m, pi2 = e.pi, k2 = slen[m2]; int8_t oMC = matchCount[m2*800+pi2]; matchCount[m2*800+pi2] = oMC + 1; if (oMC + 1 == k2) { if (fullMatchCount[m2] == 0) deltaMatched++; fullMatchCount[m2]++; } } }\n                mat[ci2][cj2] = nc;\n            }\n            if (deltaMatched > 0) {\n                totalMatched += deltaMatched; numDots += deltaDots;\n                anyImproved = true;\n            } else {\n                for (int p = k - 1; p >= 0; p--) {\n                    int ci2 = dir == 0 ? si : (si + p) % N, cj2 = dir == 0 ? (sj + p) % N : sj;\n                    int idx2 = ci2 * N + cj2;\n                    char nc = s[m][p], oc = oldChars[p];\n                    if (oc == nc) continue;\n                    if (nc != '.') { for (auto& e : adj[idx2][nc - 'A']) { int m2 = e.m, pi2 = e.pi, k2 = slen[m2]; int8_t curMC = matchCount[m2*800+pi2]; matchCount[m2*800+pi2] = curMC - 1; if (curMC == k2) fullMatchCount[m2]--; } }\n                    if (oc != '.') { for (auto& e : adj[idx2][oc - 'A']) { int m2 = e.m, pi2 = e.pi, k2 = slen[m2]; int8_t curMC = matchCount[m2*800+pi2]; matchCount[m2*800+pi2] = curMC + 1; if (curMC + 1 == k2) fullMatchCount[m2]++; } }\n                    mat[ci2][cj2] = oc;\n                }\n            }\n        }\n        if (totalMatched > bestMatched || (totalMatched == M && numDots > bestDots)) { bestMatched = totalMatched; bestMat = mat; if (totalMatched == M) bestDots = numDots; }\n        if (!anyImproved) break;\n    }\n    \n    mat = bestMat; recompute();\n    \n    // Dot Maximization\n    if (totalMatched == M) {\n        while (true) {\n            int prevDots = numDots;\n            for (int ci = 0; ci < N; ci++) {\n                for (int cj = 0; cj < N; cj++) {\n                    if (mat[ci][cj] == '.') continue;\n                    char oldC2 = mat[ci][cj]; int idx2 = ci * N + cj;\n                    int deltaM = 0;\n                    for (auto& e : adj[idx2][oldC2 - 'A']) {\n                        int m2 = e.m, pi2 = e.pi, k2 = slen[m2];\n                        if (matchCount[m2*800+pi2] == k2) {\n                            if (fullMatchCount[m2] == 1) deltaM--;\n                        }\n                    }\n                    if (deltaM == 0) {\n                        mat[ci][cj] = '.';\n                        numDots++;\n                        for (auto& e : adj[idx2][oldC2 - 'A']) {\n                            int m2 = e.m, pi2 = e.pi, k2 = slen[m2];\n                            int8_t oldMC = matchCount[m2*800+pi2];\n                            matchCount[m2*800+pi2] = oldMC - 1;\n                            if (oldMC == k2) fullMatchCount[m2]--;\n                        }\n                    }\n                }\n            }\n            if (numDots == prevDots) break;\n        }\n        if (numDots > bestDots) { bestDots = numDots; bestMat = mat; }\n    }\n    \n    for (int i = 0; i < N; i++) cout << bestMat[i] << '\\n';\n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\nint total_roads;\n\nbool is_road(int i, int j) { return i>=0&&i<N&&j>=0&&j<N&&grid[i][j]!='#'; }\nint cell_cost(int i, int j) { return grid[i][j]-'0'; }\n\nconst int di[]={-1,1,0,0}, dj[]={0,0,-1,1};\nconst char dc[]={'U','D','L','R'};\n\nvector<vector<bitset<4800>>> vis_from_bit;\n\nvoid precompute_visibility() {\n    vis_from_bit.assign(N, vector<bitset<4800>>(N));\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) {\n        if(!is_road(i,j)) continue;\n        for(int jj=j;jj>=0&&is_road(i,jj);jj--) vis_from_bit[i][j][i*N+jj] = 1;\n        for(int jj=j+1;jj<N&&is_road(i,jj);jj++) vis_from_bit[i][j][i*N+jj] = 1;\n        for(int ii=i-1;ii>=0&&is_road(ii,j);ii--) vis_from_bit[i][j][ii*N+j] = 1;\n        for(int ii=i+1;ii<N&&is_road(ii,j);ii++) vis_from_bit[i][j][ii*N+j] = 1;\n    }\n}\n\npair<vector<vector<int>>, vector<vector<int>>> dijkstra(int si, int sj) {\n    vector<vector<int>> dist(N, vector<int>(N, INT_MAX)), prev(N, vector<int>(N, -1));\n    priority_queue<pair<int,pair<int,int>>, vector<pair<int,pair<int,int>>>, greater<>> pq;\n    dist[si][sj] = 0; pq.push({0, {si, sj}});\n    while(!pq.empty()) {\n        auto [d, p] = pq.top(); pq.pop();\n        auto [i, j] = p;\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(is_road(ni, nj)) {\n                int nd = d + cell_cost(ni, nj);\n                if(nd < dist[ni][nj]) { dist[ni][nj] = nd; prev[ni][nj] = k; pq.push({nd, {ni, nj}}); }\n            }\n        }\n    }\n    return {dist, prev};\n}\n\nstring reconstruct(int si, int sj, int ti, int tj, const vector<vector<int>>& prev) {\n    if(si==ti && sj==tj) return \"\";\n    string path; int ci=ti, cj=tj;\n    while(ci!=si || cj!=sj) { int k=prev[ci][cj]; if(k==-1) return \"\"; path+=dc[k]; ci-=di[k]; cj-=dj[k]; }\n    reverse(path.begin(), path.end()); return path;\n}\n\nvector<pair<int,int>> build_greedy(double alpha) {\n    bitset<4800> covered = vis_from_bit[si][sj];\n    vector<pair<int,int>> targets;\n    int ci = si, cj = sj;\n    \n    while(covered.count() < total_roads) {\n        auto [dist, prev] = dijkstra(ci, cj);\n        vector<pair<int,int>> nodes;\n        for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) {\n            if(dist[i][j] < INT_MAX) nodes.push_back({dist[i][j], i*N+j});\n        }\n        sort(nodes.begin(), nodes.end());\n        \n        vector<vector<bitset<4800>>> tree_acc(N, vector<bitset<4800>>(N));\n        double best_score = -1e-9; int best_idx = -1; bitset<4800> best_acc;\n        \n        for(auto& [d_val, idx] : nodes) {\n            int i = idx / N, j = idx % N;\n            if(i == ci && j == cj) {\n                tree_acc[i][j] = vis_from_bit[i][j];\n            } else if(prev[i][j] != -1) {\n                int pi = i - di[prev[i][j]], pj = j - dj[prev[i][j]];\n                tree_acc[i][j] = tree_acc[pi][pj] | vis_from_bit[i][j];\n            }\n            \n            bitset<4800> diff = tree_acc[i][j] & ~covered;\n            int new_bits = diff.count();\n            \n            if(new_bits > 0 && dist[i][j] > 0) {\n                double score = pow((double)new_bits, alpha) / (double)dist[i][j];\n                if(score > best_score) { best_score = score; best_idx = idx; best_acc = tree_acc[i][j]; }\n            }\n        }\n        \n        if(best_idx == -1) break;\n        int bi = best_idx / N, bj = best_idx % N;\n        targets.push_back({bi, bj});\n        covered |= best_acc;\n        ci = bi; cj = bj;\n    }\n    return targets;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> si >> sj; grid.resize(N); for(int i=0;i<N;i++) cin >> grid[i];\n    precompute_visibility();\n    total_roads = 0; for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(is_road(i,j)) total_roads++;\n    \n    mt19937 rng(1337);\n    set<pair<int,int>> pool_set;\n    pool_set.insert({si, sj});\n    \n    vector<vector<pair<int,int>>> greedy_targets;\n    for(double alpha : {0.5, 0.8, 1.0, 1.5, 2.0, 3.0}) {\n        auto targets = build_greedy(alpha);\n        greedy_targets.push_back(targets);\n        for(auto& t : targets) pool_set.insert(t);\n    }\n    \n    vector<pair<int,int>> all_roads;\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) if(is_road(i,j)) all_roads.push_back({i,j});\n    shuffle(all_roads.begin(), all_roads.end(), rng);\n    for(int i=0; i<min((int)all_roads.size(), 100); ++i) pool_set.insert(all_roads[i]);\n    \n    if (pool_set.size() > 150) {\n        vector<pair<int,int>> T_tmp(pool_set.begin(), pool_set.end());\n        shuffle(T_tmp.begin(), T_tmp.end(), rng);\n        pool_set.clear();\n        pool_set.insert({si, sj});\n        for(auto& targets : greedy_targets) for(auto& t : targets) pool_set.insert(t);\n        for(auto& p : T_tmp) {\n            if(pool_set.size() >= 150) break;\n            pool_set.insert(p);\n        }\n    }\n    \n    vector<pair<int,int>> T(pool_set.begin(), pool_set.end());\n    int M = T.size(), S = -1;\n    map<pair<int,int>, int> to_idx;\n    for(int i=0; i<M; ++i) { to_idx[T[i]] = i; if(T[i].first == si && T[i].second == sj) S = i; }\n    \n    vector<vector<int>> d(M, vector<int>(M, INT_MAX));\n    vector<vector<bitset<4800>>> path_vis(M, vector<bitset<4800>>(M));\n    vector<vector<vector<int>>> all_prev(M, vector<vector<int>>(N, vector<int>(N, -1)));\n    \n    for(int u=0; u<M; ++u) {\n        auto [dist, prev] = dijkstra(T[u].first, T[u].second);\n        all_prev[u] = prev;\n        for(int v=0; v<M; ++v) {\n            d[u][v] = dist[T[v].first][T[v].second];\n            if(d[u][v] == INT_MAX) { path_vis[u][v].reset(); continue; }\n            bitset<4800> bs = vis_from_bit[T[u].first][T[u].second];\n            int ci = T[v].first, cj = T[v].second;\n            while(ci != T[u].first || cj != T[u].second) {\n                bs |= vis_from_bit[ci][cj];\n                int k = prev[ci][cj]; \n                ci -= di[k]; cj -= dj[k];\n            }\n            path_vis[u][v] = bs;\n        }\n    }\n    \n    auto evaluate = [&](const vector<int>& seq) -> pair<long long, int> {\n        if(seq.empty()) {\n            bitset<4800> cov = vis_from_bit[si][sj];\n            int missing = total_roads - cov.count();\n            return {(long long)1e8 * missing, missing};\n        }\n        if(d[S][seq[0]] == INT_MAX || d[seq.back()][S] == INT_MAX) return {1e18, total_roads};\n        long long cost = d[S][seq[0]] + d[seq.back()][S];\n        bitset<4800> cov = path_vis[S][seq[0]] | path_vis[seq.back()][S];\n        for(int i=0; i+1<(int)seq.size(); ++i) {\n            if(d[seq[i]][seq[i+1]] == INT_MAX) return {1e18, total_roads};\n            cost += d[seq[i]][seq[i+1]];\n            cov |= path_vis[seq[i]][seq[i+1]];\n        }\n        int missing = total_roads - cov.count();\n        return {cost + (long long)1e8 * missing, missing};\n    };\n    \n    vector<int> cur_seq;\n    long long min_init_cost = 1e18;\n    \n    auto try_init = [&](vector<int> seq) {\n        auto [cost, missing] = evaluate(seq);\n        if(missing == 0 && cost < min_init_cost) {\n            min_init_cost = cost;\n            cur_seq = seq;\n        }\n    };\n    \n    for(auto& targets : greedy_targets) {\n        vector<int> seq; \n        bool valid = true;\n        for(auto& t : targets) {\n            if(to_idx.count(t)) seq.push_back(to_idx[t]);\n            else { valid = false; break; }\n        }\n        if(valid) try_init(seq);\n    }\n    \n    long long cur_cost = min_init_cost;\n    \n    if(min_init_cost >= 1e18) {\n        bitset<4800> covered = vis_from_bit[si][sj];\n        int cur = S; vector<bool> used(M, false);\n        cur_seq.clear();\n        while(covered.count() < total_roads) {\n            int best_j = -1; int best_new = -1;\n            for(int j=0; j<M; ++j) {\n                if(used[j] || d[cur][j] == INT_MAX) continue;\n                bitset<4800> diff = path_vis[cur][j] & ~covered;\n                int cnt = diff.count();\n                if(cnt > best_new) { best_new = cnt; best_j = j; }\n            }\n            if(best_new <= 0) break;\n            cur_seq.push_back(best_j);\n            covered |= path_vis[cur][best_j];\n            cur = best_j; used[best_j] = true;\n        }\n        auto [cost, missing] = evaluate(cur_seq);\n        cur_cost = cost;\n    }\n    \n    auto best_seq = cur_seq; long long best_cost = cur_cost;\n    \n    double T_start = 1000.0, T_end = 0.1;\n    auto start_sa = chrono::high_resolution_clock::now();\n    double time_limit_sa = 2500.0;\n    mt19937 rng_sa(12345); uniform_real_distribution<double> dist01(0.0, 1.0);\n    \n    while(true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration_cast<chrono::microseconds>(now - start_sa).count() / 1000.0;\n        if(elapsed > time_limit_sa) break;\n        double T_sa = T_start * pow(T_end / T_start, elapsed / time_limit_sa);\n        \n        int op = rng_sa() % 4;\n        bool applied = false;\n        \n        if (op == 0 && cur_seq.size() >= 2) {\n            int l = rng_sa() % cur_seq.size(), r = rng_sa() % cur_seq.size();\n            if(l > r) swap(l, r); if(l == r) continue;\n            reverse(cur_seq.begin() + l, cur_seq.begin() + r + 1);\n            auto [new_cost, new_missing] = evaluate(cur_seq);\n            if(new_cost < 1e18) {\n                double delta = new_cost - cur_cost;\n                if(delta < 0 || dist01(rng_sa) < exp(-delta / T_sa)) {\n                    cur_cost = new_cost; applied = true;\n                    if(new_missing == 0 && new_cost < best_cost) { best_cost = new_cost; best_seq = cur_seq; }\n                }\n            }\n            if(!applied) reverse(cur_seq.begin() + l, cur_seq.begin() + r + 1);\n        } else if (op == 1 && cur_seq.size() > 1) {\n            int i = rng_sa() % cur_seq.size();\n            int val = cur_seq[i];\n            cur_seq.erase(cur_seq.begin() + i);\n            auto [new_cost, new_missing] = evaluate(cur_seq);\n            if(new_cost < 1e18) {\n                double delta = new_cost - cur_cost;\n                if(delta < 0 || dist01(rng_sa) < exp(-delta / T_sa)) {\n                    cur_cost = new_cost; applied = true;\n                    if(new_missing == 0 && new_cost < best_cost) { best_cost = new_cost; best_seq = cur_seq; }\n                }\n            }\n            if(!applied) cur_seq.insert(cur_seq.begin() + i, val);\n        } else if (op == 2) {\n            int x = rng_sa() % M, i = rng_sa() % (cur_seq.size() + 1);\n            cur_seq.insert(cur_seq.begin() + i, x);\n            auto [new_cost, new_missing] = evaluate(cur_seq);\n            if(new_cost < 1e18) {\n                double delta = new_cost - cur_cost;\n                if(delta < 0 || dist01(rng_sa) < exp(-delta / T_sa)) {\n                    cur_cost = new_cost; applied = true;\n                    if(new_missing == 0 && new_cost < best_cost) { best_cost = new_cost; best_seq = cur_seq; }\n                }\n            }\n            if(!applied) cur_seq.erase(cur_seq.begin() + i);\n        } else if (op == 3 && cur_seq.size() > 0) {\n            int i = rng_sa() % cur_seq.size(), x = rng_sa() % M;\n            int old_val = cur_seq[i];\n            cur_seq[i] = x;\n            auto [new_cost, new_missing] = evaluate(cur_seq);\n            if(new_cost < 1e18) {\n                double delta = new_cost - cur_cost;\n                if(delta < 0 || dist01(rng_sa) < exp(-delta / T_sa)) {\n                    cur_cost = new_cost; applied = true;\n                    if(new_missing == 0 && new_cost < best_cost) { best_cost = new_cost; best_seq = cur_seq; }\n                }\n            }\n            if(!applied) cur_seq[i] = old_val;\n        }\n    }\n    \n    auto generate_final_route = [&](const vector<int>& seq) -> string {\n        string route;\n        if (seq.empty()) return route;\n        for (int idx = 0; idx < (int)seq.size(); ++idx) {\n            int u = (idx == 0) ? S : seq[idx - 1], v = seq[idx];\n            route += reconstruct(T[u].first, T[u].second, T[v].first, T[v].second, all_prev[u]);\n        }\n        route += reconstruct(T[seq.back()].first, T[seq.back()].second, T[S].first, T[S].second, all_prev[seq.back()]);\n        return route;\n    };\n    \n    cout << generate_final_route(best_seq) << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> d, deps, rev_deps;\nvector<vector<double>> skill_est;\nvector<double> crit_path;\nvector<int> task_start, task_done;\nvector<vector<pair<int,int>>> member_obs;\n\nvector<int> hungarian(const vector<vector<double>>& cost) {\n    int n = cost.size(), m = cost[0].size();\n    const double INF = 1e18;\n    vector<double> u(n+1,0), v(m+1,0);\n    vector<int> p(m+1,0), way(m+1,0);\n    for (int i = 1; i <= n; i++) {\n        p[0] = i; int j0 = 0;\n        vector<double> minv(m+1, INF);\n        vector<bool> used(m+1, false);\n        do {\n            used[j0] = true;\n            int i0 = p[j0], j1 = 0;\n            double delta = INF;\n            for (int j = 1; j <= m; j++) if (!used[j]) {\n                double cur = cost[i0-1][j-1] - u[i0] - v[j];\n                if (cur < minv[j]) { minv[j] = cur; way[j] = j0; }\n                if (minv[j] < delta) { delta = minv[j]; j1 = j; }\n            }\n            for (int j = 0; j <= m; j++) {\n                if (used[j]) { u[p[j]] += delta; v[j] -= delta; }\n                else minv[j] -= delta;\n            }\n            j0 = j1;\n        } while (p[j0] != 0);\n        do { int j1 = way[j0]; p[j0] = p[j1]; j0 = j1; } while (j0);\n    }\n    vector<int> asgn(n, -1);\n    for (int j = 1; j <= m; j++) if (p[j] > 0 && p[j] <= n) asgn[p[j]-1] = j-1;\n    return asgn;\n}\n\nvoid recompute_crit_path() {\n    vector<double> et(N);\n    for (int i = 0; i < N; ++i) {\n        if (task_done[i] != -1) { et[i] = 0; continue; }\n        if (task_start[i] != -1) { et[i] = 0.1; continue; } // Already started, will finish soon\n        double min_w = 1e9;\n        for (int j = 0; j < M; ++j) {\n            double w = 0;\n            for (int k = 0; k < K; ++k) w += max(0.0, (double)d[i][k] - skill_est[j][k]);\n            min_w = min(min_w, w);\n        }\n        et[i] = max(1.0, min_w);\n    }\n    for (int i = N - 1; i >= 0; i--) {\n        crit_path[i] = et[i];\n        for (int v : rev_deps[i]) crit_path[i] = max(crit_path[i], et[i] + crit_path[v]);\n    }\n}\n\nvoid reestimate(int j) {\n    auto& ob = member_obs[j];\n    if (ob.empty()) return;\n    for (int iter = 0; iter < 30; ++iter) {\n        for (auto& [task, t] : ob) {\n            double w_pred = 0;\n            for (int k = 0; k < K; ++k) w_pred += max(0.0, (double)d[task][k] - skill_est[j][k]);\n            \n            if (t == 1) {\n                if (w_pred > 0) {\n                    for (int k = 0; k < K; ++k) {\n                        if (d[task][k] > skill_est[j][k]) {\n                            skill_est[j][k] += 0.3 * (d[task][k] - skill_est[j][k]);\n                        }\n                    }\n                }\n            } else {\n                double target_w = t;\n                double diff = w_pred - target_w;\n                if (abs(diff) < 0.5) continue;\n                \n                if (w_pred > 0) {\n                    for (int k = 0; k < K; ++k) {\n                        if (d[task][k] > skill_est[j][k]) {\n                            skill_est[j][k] += 0.3 * diff * (d[task][k] - skill_est[j][k]) / w_pred;\n                        }\n                    }\n                } else { \n                    double sum_d = 0;\n                    for (int k = 0; k < K; ++k) sum_d += d[task][k];\n                    if (sum_d > 0) {\n                        for (int k = 0; k < K; ++k) {\n                            skill_est[j][k] += 0.3 * diff * d[task][k] / sum_d;\n                        }\n                    }\n                }\n            }\n        }\n        for (auto& [task, t] : ob) {\n            if (t == 1) {\n                for (int k = 0; k < K; ++k) {\n                    skill_est[j][k] = max(skill_est[j][k], (double)d[task][k]);\n                }\n            }\n        }\n        for (int k = 0; k < K; ++k) skill_est[j][k] = max(0.0, skill_est[j][k]);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N >> M >> K >> R;\n    d.resize(N, vector<int>(K)); deps.resize(N); rev_deps.resize(N);\n    for (int i = 0; i < N; i++) for (int k = 0; k < K; k++) cin >> d[i][k];\n    for (int r = 0; r < R; r++) { int u, v; cin >> u >> v; u--; v--; deps[v].push_back(u); rev_deps[u].push_back(v); }\n    \n    crit_path.resize(N, 0); task_start.resize(N, -1); task_done.resize(N, -1);\n    skill_est.resize(M, vector<double>(K)); member_obs.resize(M);\n    \n    for (int k = 0; k < K; k++) {\n        vector<int> dk(N); for (int i = 0; i < N; i++) dk[i] = d[i][k];\n        sort(dk.begin(), dk.end());\n        double init = dk[N/2] * 1.5;\n        for (int j = 0; j < M; j++) skill_est[j][k] = init;\n    }\n    \n    vector<int> member_task(M, -1), member_start_day(M, -1);\n    set<int> available_tasks; vector<int> deps_rem(N);\n    for (int i = 0; i < N; i++) { deps_rem[i] = deps[i].size(); if (!deps_rem[i]) available_tasks.insert(i); }\n    \n    int current_day = 0;\n    while (true) {\n        current_day++;\n        recompute_crit_path();\n        \n        vector<int> free_members;\n        for (int j = 0; j < M; j++) if (member_task[j] == -1) free_members.push_back(j);\n        int fm = free_members.size();\n        \n        if (fm > 0 && !available_tasks.empty()) {\n            vector<int> av(available_tasks.begin(), available_tasks.end());\n            sort(av.begin(), av.end(), [&](int a, int b){ return crit_path[a] > crit_path[b]; });\n            \n            int nr = min((int)av.size(), fm * 5);\n            int na = max(nr, fm);\n            vector<vector<double>> cost(fm, vector<double>(na, 1e9));\n            for (int mi = 0; mi < fm; mi++) { \n                int j = free_members[mi];\n                for (int ti = 0; ti < nr; ti++) { \n                    int i = av[ti];\n                    double w = 0; for (int k = 0; k < K; k++) w += max(0.0, (double)d[i][k]-skill_est[j][k]);\n                    cost[mi][ti] = max(1.0, w);\n                }\n            }\n            auto asgn = hungarian(cost);\n            vector<pair<int,int>> assigns;\n            for (int mi = 0; mi < fm; mi++) { \n                int ti = asgn[mi];\n                if (ti >= 0 && ti < nr) assigns.push_back({free_members[mi], av[ti]});\n            }\n            \n            cout << assigns.size();\n            for (auto [j,i] : assigns) {\n                cout << \" \" << (j+1) << \" \" << (i+1);\n                member_task[j]=i; member_start_day[j]=current_day; task_start[i]=current_day;\n                available_tasks.erase(i);\n            }\n            cout << endl;\n        } else cout << 0 << endl;\n        \n        int n; cin >> n; if (n == -1) break;\n        for (int idx = 0; idx < n; idx++) {\n            int j; cin >> j; j--;\n            int i = member_task[j], tt = current_day - member_start_day[j] + 1;\n            task_done[i] = current_day;\n            member_obs[j].push_back({i, tt});\n            reestimate(j);\n            member_task[j] = -1;\n            for (int v : rev_deps[i]) { \n                deps_rem[v]--; \n                if (deps_rem[v] == 0 && task_start[v] == -1 && task_done[v] == -1) available_tasks.insert(v); \n            }\n        }\n    }\n    return 0;\n}","ahc006":"#pragma GCC optimize(\"O3\")\n#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <climits>\n#include <cstring>\n#include <utility>\n\nusing namespace std;\n\nconst int N = 1000, M = 50, CX = 400, CY = 400;\nint a[N], b[N], c[N], d[N];\n\ninline int dist(int x1, int y1, int x2, int y2) { return abs(x1-x2) + abs(y1-y2); }\n\nstruct Xor128 {\n    unsigned x = 123456789, y = 362436069, z = 521288629, w = 88675123;\n    unsigned next() {\n        unsigned t = x ^ (x << 11);\n        x = y; y = z; z = w;\n        return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));\n    }\n    int nextInt(int n) { return next() % n; }\n};\n\nXor128 rng;\n\nint route[100];\nint bestRouteArr[100];\nint orders[M];\nint bestOrders[M];\nbool isSelected[N];\nint pos[2000];\nint X[100], Y[100];\n\nvector<int> unselected;\n\nint calcCost() {\n    int cost = abs(CX - X[0]) + abs(CY - Y[0]);\n    for (int i = 0; i < 2 * M - 1; i++) cost += abs(X[i] - X[i+1]) + abs(Y[i] - Y[i+1]);\n    cost += abs(X[2*M-1] - CX) + abs(Y[2*M-1] - CY);\n    return cost;\n}\n\nvoid constructRoute() {\n    bool vR[50], vD[50];\n    memset(vR, 0, sizeof vR); memset(vD, 0, sizeof vD);\n    int cx = CX, cy = CY;\n    for (int step = 0; step < 2 * M; step++) {\n        int best = -1, bestD = INT_MAX;\n        for (int i = 0; i < M; i++) {\n            if (!vR[i]) { int d2 = dist(cx, cy, a[orders[i]], b[orders[i]]); if (d2 < bestD) { bestD = d2; best = i * 2; } }\n            if (vR[i] && !vD[i]) { int d2 = dist(cx, cy, c[orders[i]], d[orders[i]]); if (d2 < bestD) { bestD = d2; best = i * 2 + 1; } }\n        }\n        route[step] = orders[best / 2] * 2 + (best % 2);\n        pos[route[step]] = step;\n        if (best % 2 == 0) { vR[best / 2] = true; X[step] = a[orders[best / 2]]; Y[step] = b[orders[best / 2]]; cx = X[step]; cy = Y[step]; }\n        else { vD[best / 2] = true; X[step] = c[orders[best / 2]]; Y[step] = d[orders[best / 2]]; cx = X[step]; cy = Y[step]; }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n    for (int i = 0; i < N; i++) cin >> a[i] >> b[i] >> c[i] >> d[i];\n    \n    auto startTime = chrono::high_resolution_clock::now();\n    vector<pair<int,int>> scores;\n    for (int i = 0; i < N; i++) {\n        int cost = dist(CX, CY, a[i], b[i]) + dist(a[i], b[i], c[i], d[i]) + dist(c[i], d[i], CX, CY);\n        scores.push_back({cost, i});\n    }\n    sort(scores.begin(), scores.end());\n    for (int i = 0; i < M; i++) { orders[i] = scores[i].second; isSelected[orders[i]] = true; }\n    unselected.reserve(N);\n    for (int i = 0; i < N; i++) if (!isSelected[i]) unselected.push_back(i);\n    \n    constructRoute();\n    int curCost = calcCost(), bestCost = curCost;\n    memcpy(bestRouteArr, route, sizeof(route)); memcpy(bestOrders, orders, sizeof(orders));\n    \n    auto getC = [&](int i) -> pair<int,int> { if (i < 0 || i >= 2 * M) return {CX, CY}; return {X[i], Y[i]}; };\n    \n    int iter = 0;\n    double temp = 2000.0;\n    while (true) {\n        if (iter % 1000 == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - startTime).count();\n            if (elapsed > 1.8) break;\n            temp = 2000.0 * exp(-5.0 * (elapsed / 1.8));\n        }\n        iter++;\n        auto accept = [&](int Delta) { \n            if (Delta <= 0) return true; \n            if (Delta >= (int)(temp * 20)) return false;\n            unsigned int threshold = (unsigned int)(4294967295.0 * exp(-(double)Delta / temp)); \n            return rng.next() < threshold; \n        };\n        int mt = rng.nextInt(100);\n        \n        if (mt < 15) { // Insert Move 15%\n            int from = rng.nextInt(2 * M);\n            int ip = rng.nextInt(2 * M + 1);\n            if (ip == from || ip == from + 1) continue;\n            int ins = ip > from ? ip - 1 : ip;\n            \n            int Vx = X[from], Vy = Y[from];\n            int sx[103], sy[103];\n            sx[0] = CX; sy[0] = CY;\n            int s_idx = 1;\n            for (int idx = 0; idx < 2 * M; idx++) {\n                if (idx == from) continue;\n                sx[s_idx] = X[idx]; sy[s_idx] = Y[idx]; s_idx++;\n            }\n            sx[s_idx] = CX; sy[s_idx] = CY;\n            \n            int Delta1 = dist(sx[ins], sy[ins], Vx, Vy) + dist(Vx, Vy, sx[ins+1], sy[ins+1]) - dist(sx[ins], sy[ins], sx[ins+1], sy[ins+1]);\n            \n            auto [p_from_1_x, p_from_1_y] = getC(from - 1); \n            auto [p_from1_x, p_from1_y] = getC(from + 1);\n            int Delta2 = dist(p_from_1_x, p_from_1_y, p_from1_x, p_from1_y) - (dist(p_from_1_x, p_from_1_y, X[from], Y[from]) + dist(X[from], Y[from], p_from1_x, p_from1_y));\n            \n            int Delta = Delta1 + Delta2;\n            int p_counterpart = pos[route[from] ^ 1];\n            int p_other_new = p_counterpart - (p_counterpart > from ? 1 : 0);\n            bool valid = true;\n            if (route[from] % 2 == 0) { if (ins > p_other_new) valid = false; }\n            else { if (ins <= p_other_new) valid = false; }\n            \n            if (valid && accept(Delta)) {\n                curCost += Delta;\n                int val = route[from];\n                for (int i = from; i < 2 * M - 1; i++) { route[i] = route[i+1]; X[i] = X[i+1]; Y[i] = Y[i+1]; pos[route[i]] = i; }\n                for (int i = 2 * M - 1; i > ins; i--) { route[i] = route[i-1]; X[i] = X[i-1]; Y[i] = Y[i-1]; pos[route[i]] = i; }\n                route[ins] = val; X[ins] = Vx; Y[ins] = Vy; pos[val] = ins;\n                if (curCost < bestCost) { bestCost = curCost; memcpy(bestRouteArr, route, sizeof(route)); memcpy(bestOrders, orders, sizeof(orders)); }\n            }\n        } else if (mt < 35) { // Smart Order Swap 20%\n            int k_idx = rng.nextInt(M); int k = orders[k_idx];\n            if (unselected.empty()) continue;\n            int p1 = pos[k*2], p2 = pos[k*2+1]; if (p1 > p2) swap(p1, p2);\n            int savings = 0;\n            if (p2 == p1 + 1) {\n                auto [xm1, ym1] = getC(p1-1); auto [xp2, yp2] = getC(p2+1);\n                savings = dist(xm1, ym1, X[p1], Y[p1]) + dist(X[p1], Y[p1], X[p2], Y[p2]) + dist(X[p2], Y[p2], xp2, yp2) - dist(xm1, ym1, xp2, yp2);\n            } else {\n                auto [xm1, ym1] = getC(p1-1); auto [xp1, yp1] = getC(p1+1);\n                auto [xm2, ym2] = getC(p2-1); auto [xp2, yp2] = getC(p2+1);\n                savings = (dist(xm1, ym1, X[p1], Y[p1]) + dist(X[p1], Y[p1], xp1, yp1) - dist(xm1, ym1, xp1, yp1))\n                        + (dist(xm2, ym2, X[p2], Y[p2]) + dist(X[p2], Y[p2], xp2, yp2) - dist(xm2, ym2, xp2, yp2));\n            }\n            int shrunk_X[100], shrunk_Y[100], shrunk_route[100]; int s_idx = 0;\n            for (int idx = 0; idx < 2 * M; idx++) { if (idx == p1 || idx == p2) continue; shrunk_route[s_idx] = route[idx]; shrunk_X[s_idx] = X[idx]; shrunk_Y[s_idx] = Y[idx]; s_idx++; }\n            \n            int sx[103], sy[103];\n            sx[0] = CX; sy[0] = CY;\n            for (int i = 0; i < s_idx; i++) { sx[i+1] = shrunk_X[i]; sy[i+1] = shrunk_Y[i]; }\n            sx[s_idx+1] = CX; sy[s_idx+1] = CY;\n\n            int best_us_idx = -1, best_new_k = -1, best_Delta = 1e9, best_ins_i = -1, best_ins_j = -1;\n            int trials = min(5, (int)unselected.size());\n            for(int t = 0; t < trials; t++) {\n                int us_idx = rng.nextInt(unselected.size()); int new_k = unselected[us_idx];\n                int X_new1 = a[new_k], Y_new1 = b[new_k], X_new2 = c[new_k], Y_new2 = d[new_k];\n                int cost_D[103];\n                for (int j = 0; j <= s_idx; j++) { cost_D[j] = dist(sx[j], sy[j], X_new2, Y_new2) + dist(X_new2, Y_new2, sx[j+1], sy[j+1]) - dist(sx[j], sy[j], sx[j+1], sy[j+1]); }\n                int min_cost_D_from[103], min_idx_D_from[103];\n                min_cost_D_from[s_idx + 1] = 1e9; min_idx_D_from[s_idx + 1] = -1;\n                for (int j = s_idx; j >= 0; j--) { if (cost_D[j] < min_cost_D_from[j + 1]) { min_cost_D_from[j] = cost_D[j]; min_idx_D_from[j] = j; } else { min_cost_D_from[j] = min_cost_D_from[j + 1]; min_idx_D_from[j] = min_idx_D_from[j + 1]; } }\n                int current_best_cost = 1e9, current_best_i = -1, current_best_j = -1;\n                for (int i = 0; i <= s_idx; i++) {\n                    int cost_P = dist(sx[i], sy[i], X_new1, Y_new1) + dist(X_new1, Y_new1, sx[i+1], sy[i+1]) - dist(sx[i], sy[i], sx[i+1], sy[i+1]);\n                    int cost_same = cost_P + dist(X_new1, Y_new1, X_new2, Y_new2) + dist(X_new2, Y_new2, sx[i+1], sy[i+1]) - dist(X_new1, Y_new1, sx[i+1], sy[i+1]);\n                    if (cost_same < current_best_cost) { current_best_cost = cost_same; current_best_i = i; current_best_j = i; }\n                    if (i + 1 <= s_idx) { int cost_next = cost_P + cost_D[i+1]; if (cost_next < current_best_cost) { current_best_cost = cost_next; current_best_i = i; current_best_j = i + 1; } }\n                    if (i + 2 <= s_idx) { int cost_far = cost_P + min_cost_D_from[i + 2]; if (cost_far < current_best_cost) { current_best_cost = cost_far; current_best_i = i; current_best_j = min_idx_D_from[i + 2]; } }\n                }\n                int Delta = current_best_cost - savings;\n                if(Delta < best_Delta) { best_Delta = Delta; best_us_idx = us_idx; best_new_k = new_k; best_ins_i = current_best_i; best_ins_j = current_best_j; }\n            }\n            if (accept(best_Delta)) {\n                curCost += best_Delta;\n                int new_k = best_new_k, us_idx = best_us_idx;\n                int X_new1 = a[new_k], Y_new1 = b[new_k], X_new2 = c[new_k], Y_new2 = d[new_k];\n                int new_route[100], new_X[100], new_Y[100]; int n_idx = 0;\n                for (int idx = 0; idx < s_idx; idx++) {\n                    if (idx == best_ins_i) { new_route[n_idx] = new_k * 2; new_X[n_idx] = X_new1; new_Y[n_idx] = Y_new1; n_idx++; }\n                    if (idx == best_ins_j) { new_route[n_idx] = new_k * 2 + 1; new_X[n_idx] = X_new2; new_Y[n_idx] = Y_new2; n_idx++; }\n                    new_route[n_idx] = shrunk_route[idx]; new_X[n_idx] = shrunk_X[idx]; new_Y[n_idx] = shrunk_Y[idx]; n_idx++;\n                }\n                if (s_idx == best_ins_i) { new_route[n_idx] = new_k * 2; new_X[n_idx] = X_new1; new_Y[n_idx] = Y_new1; n_idx++; }\n                if (s_idx == best_ins_j) { new_route[n_idx] = new_k * 2 + 1; new_X[n_idx] = X_new2; new_Y[n_idx] = Y_new2; n_idx++; }\n                \n                memcpy(route, new_route, sizeof(route)); memcpy(X, new_X, sizeof(X)); memcpy(Y, new_Y, sizeof(Y));\n                for (int idx = 0; idx < 2 * M; idx++) pos[route[idx]] = idx;\n                isSelected[k] = false; isSelected[new_k] = true; orders[k_idx] = new_k;\n                unselected[us_idx] = unselected.back(); unselected.pop_back(); unselected.push_back(k);\n                if (curCost < bestCost) { bestCost = curCost; memcpy(bestRouteArr, route, sizeof(route)); memcpy(bestOrders, orders, sizeof(orders)); }\n            }\n        } else if (mt < 50) { // Order Re-insert 15%\n            int k_idx = rng.nextInt(M); int k = orders[k_idx];\n            int p1 = pos[k*2], p2 = pos[k*2+1]; if (p1 > p2) swap(p1, p2);\n            int savings = 0;\n            if (p2 == p1 + 1) {\n                auto [xm1, ym1] = getC(p1-1); auto [xp2, yp2] = getC(p2+1);\n                savings = dist(xm1, ym1, X[p1], Y[p1]) + dist(X[p1], Y[p1], X[p2], Y[p2]) + dist(X[p2], Y[p2], xp2, yp2) - dist(xm1, ym1, xp2, yp2);\n            } else {\n                auto [xm1, ym1] = getC(p1-1); auto [xp1, yp1] = getC(p1+1);\n                auto [xm2, ym2] = getC(p2-1); auto [xp2, yp2] = getC(p2+1);\n                savings = (dist(xm1, ym1, X[p1], Y[p1]) + dist(X[p1], Y[p1], xp1, yp1) - dist(xm1, ym1, xp1, yp1))\n                        + (dist(xm2, ym2, X[p2], Y[p2]) + dist(X[p2], Y[p2], xp2, yp2) - dist(xm2, ym2, xp2, yp2));\n            }\n            int shrunk_X[100], shrunk_Y[100], shrunk_route[100]; int s_idx = 0;\n            for (int idx = 0; idx < 2 * M; idx++) { if (idx == p1 || idx == p2) continue; shrunk_route[s_idx] = route[idx]; shrunk_X[s_idx] = X[idx]; shrunk_Y[s_idx] = Y[idx]; s_idx++; }\n            \n            int sx[103], sy[103];\n            sx[0] = CX; sy[0] = CY;\n            for (int i = 0; i < s_idx; i++) { sx[i+1] = shrunk_X[i]; sy[i+1] = shrunk_Y[i]; }\n            sx[s_idx+1] = CX; sy[s_idx+1] = CY;\n            \n            int X_new1 = a[k], Y_new1 = b[k], X_new2 = c[k], Y_new2 = d[k];\n            int cost_D[103];\n            for (int j = 0; j <= s_idx; j++) { cost_D[j] = dist(sx[j], sy[j], X_new2, Y_new2) + dist(X_new2, Y_new2, sx[j+1], sy[j+1]) - dist(sx[j], sy[j], sx[j+1], sy[j+1]); }\n            int min_cost_D_from[103], min_idx_D_from[103];\n            min_cost_D_from[s_idx + 1] = 1e9; min_idx_D_from[s_idx + 1] = -1;\n            for (int j = s_idx; j >= 0; j--) { if (cost_D[j] < min_cost_D_from[j + 1]) { min_cost_D_from[j] = cost_D[j]; min_idx_D_from[j] = j; } else { min_cost_D_from[j] = min_cost_D_from[j + 1]; min_idx_D_from[j] = min_idx_D_from[j + 1]; } }\n            int best_cost = 1e9, best_ins_i = -1, best_ins_j = -1;\n            for (int i = 0; i <= s_idx; i++) {\n                int cost_P = dist(sx[i], sy[i], X_new1, Y_new1) + dist(X_new1, Y_new1, sx[i+1], sy[i+1]) - dist(sx[i], sy[i], sx[i+1], sy[i+1]);\n                int cost_same = cost_P + dist(X_new1, Y_new1, X_new2, Y_new2) + dist(X_new2, Y_new2, sx[i+1], sy[i+1]) - dist(X_new1, Y_new1, sx[i+1], sy[i+1]);\n                if (cost_same < best_cost) { best_cost = cost_same; best_ins_i = i; best_ins_j = i; }\n                if (i + 1 <= s_idx) { int cost_next = cost_P + cost_D[i+1]; if (cost_next < best_cost) { best_cost = cost_next; best_ins_i = i; best_ins_j = i + 1; } }\n                if (i + 2 <= s_idx) { int cost_far = cost_P + min_cost_D_from[i + 2]; if (cost_far < best_cost) { best_cost = cost_far; best_ins_i = i; best_ins_j = min_idx_D_from[i + 2]; } }\n            }\n            int Delta = best_cost - savings;\n            if (accept(Delta)) {\n                curCost += Delta;\n                int new_route[100], new_X[100], new_Y[100]; int n_idx = 0;\n                for (int idx = 0; idx < s_idx; idx++) {\n                    if (idx == best_ins_i) { new_route[n_idx] = k * 2; new_X[n_idx] = X_new1; new_Y[n_idx] = Y_new1; n_idx++; }\n                    if (idx == best_ins_j) { new_route[n_idx] = k * 2 + 1; new_X[n_idx] = X_new2; new_Y[n_idx] = Y_new2; n_idx++; }\n                    new_route[n_idx] = shrunk_route[idx]; new_X[n_idx] = shrunk_X[idx]; new_Y[n_idx] = shrunk_Y[idx]; n_idx++;\n                }\n                if (s_idx == best_ins_i) { new_route[n_idx] = k * 2; new_X[n_idx] = X_new1; new_Y[n_idx] = Y_new1; n_idx++; }\n                if (s_idx == best_ins_j) { new_route[n_idx] = k * 2 + 1; new_X[n_idx] = X_new2; new_Y[n_idx] = Y_new2; n_idx++; }\n                \n                memcpy(route, new_route, sizeof(route)); memcpy(X, new_X, sizeof(X)); memcpy(Y, new_Y, sizeof(Y));\n                for (int idx = 0; idx < 2 * M; idx++) pos[route[idx]] = idx;\n                if (curCost < bestCost) { bestCost = curCost; memcpy(bestRouteArr, route, sizeof(route)); memcpy(bestOrders, orders, sizeof(orders)); }\n            }\n        } else if (mt < 65) { // Order Swap Move 15%\n            int k1_idx = rng.nextInt(M); int k2_idx = rng.nextInt(M - 1); if (k2_idx >= k1_idx) k2_idx++;\n            int k1 = orders[k1_idx], k2 = orders[k2_idx];\n            int p1 = pos[k1*2], p2 = pos[k1*2+1];\n            int p3 = pos[k2*2], p4 = pos[k2*2+1];\n            int min_p = min({p1, p2, p3, p4});\n            int max_p = max({p1, p2, p3, p4});\n            \n            int old_cost = 0;\n            for (int i = min_p - 1; i <= max_p; i++) {\n                auto [x1, y1] = getC(i);\n                auto [x2, y2] = getC(i+1);\n                old_cost += dist(x1, y1, x2, y2);\n            }\n            \n            route[p1] = k2*2; X[p1] = a[k2]; Y[p1] = b[k2];\n            route[p2] = k2*2+1; X[p2] = c[k2]; Y[p2] = d[k2];\n            route[p3] = k1*2; X[p3] = a[k1]; Y[p3] = b[k1];\n            route[p4] = k1*2+1; X[p4] = c[k1]; Y[p4] = d[k1];\n            pos[k1*2] = p3; pos[k1*2+1] = p4;\n            pos[k2*2] = p1; pos[k2*2+1] = p2;\n            \n            int new_cost = 0;\n            for (int i = min_p - 1; i <= max_p; i++) {\n                auto [x1, y1] = getC(i);\n                auto [x2, y2] = getC(i+1);\n                new_cost += dist(x1, y1, x2, y2);\n            }\n            \n            int Delta = new_cost - old_cost;\n            if (accept(Delta)) {\n                curCost += Delta;\n                swap(orders[k1_idx], orders[k2_idx]);\n                if (curCost < bestCost) { bestCost = curCost; memcpy(bestRouteArr, route, sizeof(route)); memcpy(bestOrders, orders, sizeof(orders)); }\n            } else {\n                route[p1] = k1*2; X[p1] = a[k1]; Y[p1] = b[k1];\n                route[p2] = k1*2+1; X[p2] = c[k1]; Y[p2] = d[k1];\n                route[p3] = k2*2; X[p3] = a[k2]; Y[p3] = b[k2];\n                route[p4] = k2*2+1; X[p4] = c[k2]; Y[p4] = d[k2];\n                pos[k1*2] = p1; pos[k1*2+1] = p2;\n                pos[k2*2] = p3; pos[k2*2+1] = p4;\n            }\n        } else if (mt < 75) { // Route Swap 10%\n            int i = rng.nextInt(2 * M), j = rng.nextInt(2 * M - 1); if (j >= i) j++; if (i > j) swap(i, j);\n            int u = route[i], v = route[j]; if (u == (v ^ 1)) continue;\n            bool valid = true;\n            if (u % 2 == 0) { if (pos[u ^ 1] <= j) valid = false; } \n            else { if (pos[u ^ 1] > j) valid = false; }\n            if (v % 2 == 0) { if (pos[v ^ 1] <= i) valid = false; } \n            else { if (pos[v ^ 1] > i) valid = false; }\n            if (!valid) continue;\n            auto [xim1, yim1] = getC(i - 1);\n            auto [xj1, yj1] = getC(j + 1);\n            int Delta = 0;\n            if (j == i + 1) {\n                Delta = (dist(xim1, yim1, X[j], Y[j]) + dist(X[j], Y[j], X[i], Y[i]) + dist(X[i], Y[i], xj1, yj1)) - (dist(xim1, yim1, X[i], Y[i]) + dist(X[i], Y[i], X[j], Y[j]) + dist(X[j], Y[j], xj1, yj1));\n            } else {\n                auto [xi1, yi1] = getC(i + 1);\n                auto [xjm1, yjm1] = getC(j - 1);\n                Delta = (dist(xim1, yim1, X[j], Y[j]) + dist(X[j], Y[j], xi1, yi1) + dist(xjm1, yjm1, X[i], Y[i]) + dist(X[i], Y[i], xj1, yj1)) - (dist(xim1, yim1, X[i], Y[i]) + dist(X[i], Y[i], xi1, yi1) + dist(xjm1, yjm1, X[j], Y[j]) + dist(X[j], Y[j], xj1, yj1));\n            }\n            if (accept(Delta)) {\n                curCost += Delta; swap(route[i], route[j]); swap(X[i], X[j]); swap(Y[i], Y[j]); pos[route[i]] = i; pos[route[j]] = j;\n                if (curCost < bestCost) { bestCost = curCost; memcpy(bestRouteArr, route, sizeof(route)); memcpy(bestOrders, orders, sizeof(orders)); }\n            }\n        } else { // 2-opt 25%\n            int l = rng.nextInt(2 * M - 1), r = l + 1 + rng.nextInt(2 * M - 1 - l);\n            bool valid = true; for (int i = l; i <= r; i++) { int p_other = pos[route[i] ^ 1]; if (p_other >= l && p_other <= r) { valid = false; break; } }\n            if (valid) {\n                auto [xl1, yl1] = getC(l - 1); auto [xl, yl] = getC(l); auto [xr, yr] = getC(r); auto [xr1, yr1] = getC(r + 1);\n                int Delta = (dist(xl1, yl1, xr, yr) + dist(xl, yl, xr1, yr1)) - (dist(xl1, yl1, xl, yl) + dist(xr, yr, xr1, yr1));\n                if (accept(Delta)) {\n                    curCost += Delta; reverse(route + l, route + r + 1); reverse(X + l, X + r + 1); reverse(Y + l, Y + r + 1);\n                    for (int i = l; i <= r; i++) pos[route[i]] = i;\n                    if (curCost < bestCost) { bestCost = curCost; memcpy(bestRouteArr, route, sizeof(route)); memcpy(bestOrders, orders, sizeof(orders)); }\n                }\n            }\n        }\n    }\n    \n    cout << M; for(int i = 0; i < M; i++) cout << \" \" << bestOrders[i] + 1; cout << endl;\n    int bestX_arr[100], bestY_arr[100];\n    for (int i = 0; i < 2 * M; i++) { int node = bestRouteArr[i]; int k = node / 2; if (node % 2 == 0) { bestX_arr[i] = a[k]; bestY_arr[i] = b[k]; } else { bestX_arr[i] = c[k]; bestY_arr[i] = d[k]; } }\n    cout << 2 * M + 2 << \" \" << CX << \" \" << CY;\n    for(int i = 0; i < 2 * M; i++) cout << \" \" << bestX_arr[i] << \" \" << bestY_arr[i];\n    cout << \" \" << CX << \" \" << CY << endl;\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nstruct UnionFind {\n    vector<int> parent, rank_;\n    int components;\n    \n    UnionFind(int n) : parent(n), rank_(n, 0), components(n) {\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 (rank_[px] < rank_[py]) swap(px, py);\n        parent[py] = px;\n        if (rank_[px] == rank_[py]) rank_[px]++;\n        components--;\n        return true;\n    }\n    \n    bool connected(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, M = 1995;\n    vector<int> x(N), y(N);\n    vector<int> u(M), v(M);\n    vector<int> d(M);\n    \n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    for (int i = 0; i < M; i++) {\n        cin >> u[i] >> v[i];\n        double dist = sqrt((double)(x[u[i]] - x[v[i]]) * (x[u[i]] - x[v[i]]) + \n                           (double)(y[u[i]] - y[v[i]]) * (y[u[i]] - y[v[i]]));\n        d[i] = max(1, (int)round(dist));\n    }\n    \n    // Compute reference MST using d_i\n    vector<int> order(M);\n    for (int i = 0; i < M; i++) order[i] = i;\n    sort(order.begin(), order.end(), [&](int a, int b) { return d[a] < d[b]; });\n    \n    UnionFind refUF(N);\n    vector<bool> inRefMST(M, false);\n    for (int idx : order) {\n        if (refUF.unite(u[idx], v[idx])) {\n            inRefMST[idx] = true;\n        }\n    }\n    \n    // Process edges online\n    UnionFind uf(N);\n    \n    for (int i = 0; i < M; i++) {\n        int l;\n        cin >> l;\n        \n        int adopt = 0;\n        \n        if (!uf.connected(u[i], v[i])) {\n            if (inRefMST[i]) {\n                // Always accept reference MST edges - guarantees connectivity\n                adopt = 1;\n                uf.unite(u[i], v[i]);\n            } else {\n                // Accept non-MST edges only if they're cheap enough\n                // to potentially replace expensive MST edges\n                double percentile = (double)(l - d[i]) / (2.0 * d[i]);\n                percentile = max(0.0, min(1.0, percentile));\n                \n                int remaining = M - i - 1;\n                int needed = uf.components - 1;\n                double safety = (needed > 0) ? (double)remaining / needed : 999.0;\n                \n                double threshold;\n                if (safety >= 5) threshold = 0.3;\n                else if (safety >= 3) threshold = 0.4;\n                else if (safety >= 2) threshold = 0.5;\n                else threshold = 0.65;\n                \n                if (percentile <= threshold) {\n                    adopt = 1;\n                    uf.unite(u[i], v[i]);\n                }\n            }\n        }\n        \n        cout << adopt << endl;\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <cstring>\n\nusing namespace std;\n\nconst int SIZE = 30;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\n\nint N, M;\nvector<int> px, py, pt;\nvector<int> hx, hy;\nbool wall[SIZE][SIZE];\n\nbool inBounds(int x, int y) { return x >= 0 && x < SIZE && y >= 0 && y < SIZE; }\n\nvoid bfs(int sx, int sy, int dist[SIZE][SIZE]) {\n    memset(dist, -1, sizeof(int) * SIZE * SIZE);\n    if (!inBounds(sx, sy) || wall[sx][sy]) return;\n    queue<pair<int,int>> q;\n    dist[sx][sy] = 0;\n    q.push({sx, sy});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (inBounds(nx, ny) && !wall[nx][ny] && dist[nx][ny] == -1) {\n                dist[nx][ny] = dist[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n}\n\ndouble petThreatWeight(int t) {\n    switch(t) { case 1: return 1.0; case 2: return 1.5; case 3: return 2.0; case 4: return 2.5; case 5: return 2.0; default: return 1.0; }\n}\n\ndouble petSpeed(int t) {\n    switch(t) { case 1: return 1.0; case 2: return 2.0; case 3: return 3.0; case 4: return 2.0; case 5: return 2.0; default: return 1.0; }\n}\n\nbool petAdjacentTo(int x, int y, const vector<int>& ppx, const vector<int>& ppy) {\n    for (int i = 0; i < N; i++) {\n        if (ppx[i] == x && ppy[i] == y) return true;\n        for (int d = 0; d < 4; d++)\n            if (ppx[i] == x + dx[d] && ppy[i] == y + dy[d]) return true;\n    }\n    return false;\n}\n\nbool humanAt(int x, int y, const vector<int>& hhx, const vector<int>& hhy) {\n    for (int i = 0; i < M; i++)\n        if (hhx[i] == x && hhy[i] == y) return true;\n    return false;\n}\n\ndouble computeScoreWithDist(int dist[SIZE][SIZE]) {\n    int area = 0;\n    double effectivePets = 0;\n    bool enclosed = true;\n    \n    for (int i = 0; i < SIZE; i++)\n        for (int j = 0; j < SIZE; j++)\n            if (dist[i][j] >= 0) {\n                area++;\n                if (enclosed) {\n                    for (int d = 0; d < 4; d++) {\n                        int ni = i + dx[d], nj = j + dy[d];\n                        if (inBounds(ni, nj) && !wall[ni][nj] && dist[ni][nj] < 0) {\n                            enclosed = false; break;\n                        }\n                    }\n                }\n            }\n    \n    for (int i = 0; i < N; i++)\n        if (dist[px[i]][py[i]] >= 0) effectivePets += 1.0;\n\n    if (enclosed && effectivePets > 0) effectivePets += 20.0;\n\n    int boundaryDist[SIZE][SIZE];\n    memset(boundaryDist, -1, sizeof(int) * SIZE * SIZE);\n    queue<pair<int,int>> q;\n    for (int x = 0; x < SIZE; x++)\n        for (int y = 0; y < SIZE; y++)\n            if (dist[x][y] < 0 && !wall[x][y]) {\n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dx[d], ny = y + dy[d];\n                    if (inBounds(nx, ny) && dist[nx][ny] >= 0) {\n                        if (boundaryDist[x][y] == -1) { boundaryDist[x][y] = 1; q.push({x, y}); }\n                        break;\n                    }\n                }\n            }\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (inBounds(nx, ny) && !wall[nx][ny] && boundaryDist[nx][ny] == -1 && dist[nx][ny] < 0) {\n                boundaryDist[nx][ny] = boundaryDist[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (dist[px[i]][py[i]] >= 0) continue;\n        int d = boundaryDist[px[i]][py[i]];\n        if (d >= 1) effectivePets += petThreatWeight(pt[i]) * 0.2 * exp(-0.25 * d);\n    }\n    \n    return (double)area / 900.0 * pow(2.0, -effectivePets);\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> N;\n    px.resize(N); py.resize(N); pt.resize(N);\n    for (int i = 0; i < N; i++) { cin >> px[i] >> py[i] >> pt[i]; px[i]--; py[i]--; }\n    cin >> M;\n    hx.resize(M); hy.resize(M);\n    for (int i = 0; i < M; i++) { cin >> hx[i] >> hy[i]; hx[i]--; hy[i]--; }\n    memset(wall, false, sizeof(wall));\n\n    for (int turn = 0; turn < 300; turn++) {\n        vector<int> startPx = px, startPy = py, startHx = hx, startHy = hy;\n        string actions(M, '.');\n        bool newWall[SIZE][SIZE] = {};\n\n        for (int i = 0; i < M; i++) {\n            int myHx = startHx[i], myHy = startHy[i];\n            int distBefore[SIZE][SIZE];\n            bfs(myHx, myHy, distBefore);\n            double curScore = computeScoreWithDist(distBefore);\n            \n            char bestAction = '.';\n            double bestScore = curScore;\n\n            for (int d = 0; d < 4; d++) {\n                int wx = myHx + dx[d], wy = myHy + dy[d];\n                if (inBounds(wx, wy) && !wall[wx][wy] && !newWall[wx][wy] &&\n                    !petAdjacentTo(wx, wy, startPx, startPy) && !humanAt(wx, wy, startHx, startHy)) {\n                    wall[wx][wy] = true;\n                    int distAfter[SIZE][SIZE];\n                    bfs(myHx, myHy, distAfter);\n                    double newScore = computeScoreWithDist(distAfter);\n                    \n                    bool separated = false;\n                    for (int j = 0; j < N; j++)\n                        if (distBefore[px[j]][py[j]] >= 0 && distAfter[px[j]][py[j]] < 0) {\n                            newScore += 0.12;\n                            separated = true;\n                        }\n                    \n                    if (separated) {\n                        for (int dd = 0; dd < 4; dd++) {\n                            int nx = wx + dx[dd], ny = wy + dy[dd];\n                            if (!inBounds(nx, ny) || wall[nx][ny] || newWall[nx][ny]) newScore += 0.002;\n                        }\n                    }\n                    \n                    for (int j = 0; j < N; j++) {\n                        if (distBefore[px[j]][py[j]] >= 0) {\n                            int hDist = abs(myHx - px[j]) + abs(myHy - py[j]);\n                            int wDistPet = abs(wx - px[j]) + abs(wy - py[j]);\n                            int wDistHuman = abs(wx - myHx) + abs(wy - myHy);\n                            if (wDistHuman + wDistPet <= hDist + 2)\n                                newScore += 0.025;\n                        }\n                    }\n                    \n                    for (int j = 0; j < N; j++) {\n                        if (distBefore[px[j]][py[j]] < 0) {\n                            int wDistPet = abs(wx - px[j]) + abs(wy - py[j]);\n                            if (wDistPet <= 4) newScore += 0.012 * (5 - wDistPet);\n                        }\n                    }\n                    \n                    wall[wx][wy] = false;\n                    if (newScore > bestScore) { bestScore = newScore; bestAction = \"udlr\"[d]; }\n                }\n            }\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = myHx + dx[d], ny = myHy + dy[d];\n                if (inBounds(nx, ny) && !wall[nx][ny] && !newWall[nx][ny]) {\n                    int distAfter[SIZE][SIZE];\n                    bfs(nx, ny, distAfter);\n                    double newScore = computeScoreWithDist(distAfter);\n                    if (newScore > bestScore) { bestScore = newScore; bestAction = \"UDLR\"[d]; }\n                }\n            }\n            \n            if (bestAction == '.') {\n                double bestUrgency = -1e9;\n                int bestTargetX = -1, bestTargetY = -1;\n                \n                for (int x = 0; x < SIZE; x++)\n                    for (int y = 0; y < SIZE; y++)\n                        if (distBefore[x][y] < 0 && !wall[x][y] && !newWall[x][y]) {\n                            bool adjToRegion = false;\n                            int minHDist = 999;\n                            for (int dd = 0; dd < 4; dd++) {\n                                int nx = x + dx[dd], ny = y + dy[dd];\n                                if (inBounds(nx, ny) && distBefore[nx][ny] >= 0) {\n                                    adjToRegion = true;\n                                    minHDist = min(minHDist, distBefore[nx][ny] + 1);\n                                }\n                            }\n                            if (!adjToRegion) continue;\n                            if (petAdjacentTo(x, y, startPx, startPy)) continue;\n                            \n                            double minPetArrival = 1e9;\n                            for (int j = 0; j < N; j++) {\n                                if (distBefore[startPx[j]][startPy[j]] >= 0) continue;\n                                double arrival = (abs(startPx[j] - x) + abs(startPy[j] - y)) / petSpeed(pt[j]);\n                                minPetArrival = min(minPetArrival, arrival);\n                            }\n                            \n                            double urgency = -minPetArrival * 8 - minHDist;\n                            if (urgency > bestUrgency) {\n                                bestUrgency = urgency;\n                                int tx = -1, ty = -1, td = 999;\n                                for (int dd = 0; dd < 4; dd++) {\n                                    int nx = x + dx[dd], ny = y + dy[dd];\n                                    if (inBounds(nx, ny) && distBefore[nx][ny] >= 0 && distBefore[nx][ny] < td) {\n                                        td = distBefore[nx][ny]; tx = nx; ty = ny;\n                                    }\n                                }\n                                bestTargetX = tx; bestTargetY = ty;\n                            }\n                        }\n                \n                if (bestTargetX >= 0) {\n                    int bestMoveDist = abs(myHx - bestTargetX) + abs(myHy - bestTargetY);\n                    char bestMove = '.';\n                    for (int d = 0; d < 4; d++) {\n                        int nx = myHx + dx[d], ny = myHy + dy[d];\n                        if (inBounds(nx, ny) && !wall[nx][ny] && !newWall[nx][ny]) {\n                            int dist = abs(nx - bestTargetX) + abs(ny - bestTargetY);\n                            if (dist < bestMoveDist) { bestMoveDist = dist; bestMove = \"UDLR\"[d]; }\n                        }\n                    }\n                    if (bestMove != '.') bestAction = bestMove;\n                }\n                \n                if (bestAction == '.') {\n                    int boundaryDist2[SIZE][SIZE];\n                    int firstDir[SIZE][SIZE];\n                    memset(boundaryDist2, -1, sizeof(int) * SIZE * SIZE);\n                    memset(firstDir, -1, sizeof(int) * SIZE * SIZE);\n                    queue<pair<int,int>> q;\n                    \n                    for (int x = 0; x < SIZE; x++)\n                        for (int y = 0; y < SIZE; y++)\n                            if (distBefore[x][y] >= 0) {\n                                bool isBd = false;\n                                for (int dd = 0; dd < 4; dd++) {\n                                    int nnx = x + dx[dd], nny = y + dy[dd];\n                                    if (!inBounds(nnx, nny) || wall[nnx][nny]) isBd = true;\n                                }\n                                if (isBd) { boundaryDist2[x][y] = 0; q.push({x, y}); }\n                            }\n                    \n                    while (!q.empty()) {\n                        auto [x, y] = q.front(); q.pop();\n                        for (int dd = 0; dd < 4; dd++) {\n                            int nnx = x + dx[dd], nny = y + dy[dd];\n                            if (inBounds(nnx, nny) && !wall[nnx][nny] && boundaryDist2[nnx][nny] == -1 && distBefore[nnx][nny] >= 0) {\n                                boundaryDist2[nnx][nny] = boundaryDist2[x][y] + 1;\n                                if (boundaryDist2[x][y] == 0) {\n                                    if (x == nnx-1) firstDir[nnx][nny] = 0;\n                                    else if (x == nnx+1) firstDir[nnx][nny] = 1;\n                                    else if (y == nny-1) firstDir[nnx][nny] = 2;\n                                    else firstDir[nnx][nny] = 3;\n                                } else firstDir[nnx][nny] = firstDir[x][y];\n                                q.push({nnx, nny});\n                            }\n                        }\n                    }\n                    \n                    if (boundaryDist2[myHx][myHy] > 0 && firstDir[myHx][myHy] >= 0) {\n                        int dd = firstDir[myHx][myHy];\n                        int nnx = myHx + dx[dd], nny = myHy + dy[dd];\n                        if (inBounds(nnx, nny) && !wall[nnx][nny] && !newWall[nnx][nny])\n                            bestAction = \"UDLR\"[dd];\n                    }\n                }\n            }\n            \n            actions[i] = bestAction;\n            switch (actions[i]) {\n                case 'u': newWall[myHx-1][myHy]=true; wall[myHx-1][myHy]=true; break;\n                case 'd': newWall[myHx+1][myHy]=true; wall[myHx+1][myHy]=true; break;\n                case 'l': newWall[myHx][myHy-1]=true; wall[myHx][myHy-1]=true; break;\n                case 'r': newWall[myHx][myHy+1]=true; wall[myHx][myHy+1]=true; break;\n                case 'U': hx[i]=myHx-1; hy[i]=myHy; break;\n                case 'D': hx[i]=myHx+1; hy[i]=myHy; break;\n                case 'L': hx[i]=myHx; hy[i]=myHy-1; break;\n                case 'R': hx[i]=myHx; hy[i]=myHy+1; break;\n            }\n        }\n        \n        cout << actions << endl;\n        for (int i = 0; i < N; i++) {\n            string move; cin >> move;\n            for (char c : move) {\n                if (c=='U') px[i]--; else if (c=='D') px[i]++;\n                else if (c=='L') py[i]--; else if (c=='R') py[i]++;\n            }\n        }\n    }\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <cstring>\n#include <array>\n#include <random>\nusing namespace std;\nint si,sj,ti,tj;double p;int ti_idx;\nint md[400][4];double fv[400][202];int c2d[256];\nmt19937 rng(42);\n\ndouble pr_arr[201][400];\ndouble W[201][400];\n\nvoid init(){\n    vector<string>h(20),v(19);for(int i=0;i<20;i++)cin>>h[i];for(int i=0;i<19;i++)cin>>v[i];\n    ti_idx=ti*20+tj;int di[]={-1,1,0,0},dj[]={0,0,-1,1};\n    for(int i=0;i<20;i++)for(int j=0;j<20;j++){int idx=i*20+j;\n        for(int d=0;d<4;d++){int ni=i+di[d],nj=j+dj[d];bool bl=(ni<0||ni>=20||nj<0||nj>=20);\n            if(!bl){if(d==0&&i>0&&v[i-1][j]=='1')bl=true;else if(d==1&&v[i][j]=='1')bl=true;\n                else if(d==2&&j>0&&h[i][j-1]=='1')bl=true;else if(d==3&&h[i][j]=='1')bl=true;}\n            if(bl){ni=i;nj=j;}md[idx][d]=ni*20+nj;}}\n    memset(fv,0,sizeof(fv));\n    for(int t=200;t>=1;t--)for(int idx=0;idx<400;idx++){\n        if(idx==ti_idx){fv[idx][t]=0;continue;}\n        double b=0;for(int d=0;d<4;d++){int ni=md[idx][d];\n            double sc=p*fv[idx][t+1];if(ni==ti_idx)sc+=(1-p)*(401-t);else sc+=(1-p)*fv[ni][t+1];\n            b=max(b,sc);}fv[idx][t]=b;}}\n\ndouble compute_score(const string&s){\n    double pr[400]={},np[400];pr[si*20+sj]=1;double es=0;\n    for(int t=0;t<(int)s.size();t++){int d=c2d[(unsigned char)s[t]];memset(np,0,sizeof(np));\n        for(int i=0;i<400;i++){if(pr[i]<1e-18)continue;\n            if(i==ti_idx)continue;\n            np[i]+=p*pr[i];int ni=md[i][d];\n            if(ni==ti_idx)es+=(1-p)*pr[i]*(400-t);else np[ni]+=(1-p)*pr[i];}\n        memcpy(pr,np,sizeof(pr));}return es;}\n\nstring bfs_path(){int dist[400],pdir[400];memset(dist,-1,sizeof(dist));\n    queue<int>q;int start=si*20+sj;q.push(start);dist[start]=0;\n    while(!q.empty()){int idx=q.front();q.pop();if(idx==ti_idx)break;\n        for(int d=0;d<4;d++){int ni=md[idx][d];if(ni!=idx&&dist[ni]==-1){dist[ni]=dist[idx]+1;pdir[ni]=d;q.push(ni);}}}\n    string path;int idx=ti_idx;int di[]={-1,1,0,0},dj[]={0,0,-1,1};\n    while(idx!=start){int d=pdir[idx];path=string(1,\"UDLR\"[d])+path;idx=(idx/20-di[d])*20+(idx%20-dj[d]);}return path;}\n\nstring beam_search(int B, double noise=0.0){\n    vector<double> pr_flat(B * 400, 0.0);\n    vector<double> acc(B, 0.0);\n    vector<array<uint8_t, 200>> act(B);\n    int cur_B = 1;\n    pr_flat[si*20+sj] = 1.0;\n\n    for(int t=0; t<200; ++t){\n        vector<pair<double, pair<int, int>>> scores;\n        scores.reserve(cur_B * 4);\n        for(int i=0; i<cur_B; ++i){\n            double* p_pr = pr_flat.data() + i * 400;\n            double base_h = acc[i];\n            for(int j=0; j<400; ++j) {\n                if(j == ti_idx) continue;\n                base_h += p * p_pr[j] * fv[j][t+2];\n            }\n            for(int d=0; d<4; ++d){\n                double h = base_h;\n                double q = 1 - p;\n                for(int j=0; j<400; ++j){\n                    if(j == ti_idx) continue;\n                    double pr_j = p_pr[j];\n                    if(pr_j < 1e-18) continue;\n                    int ni = md[j][d];\n                    if(ni == ti_idx) h += q * pr_j * (400-t);\n                    else h += q * pr_j * fv[ni][t+2];\n                }\n                if(noise > 0) h += uniform_real_distribution<double>(-noise, noise)(rng);\n                scores.push_back({h, {i, d}});\n            }\n        }\n        int next_B = min(B, (int)scores.size());\n        if(next_B == 0) break;\n        if(next_B < (int)scores.size()) {\n            nth_element(scores.begin(), scores.begin() + next_B - 1, scores.end(), [](const auto& a, const auto& b){\n                return a.first > b.first;\n            });\n        }\n\n        vector<double> npr_flat(next_B * 400, 0.0);\n        vector<double> nacc(next_B, 0.0);\n        vector<array<uint8_t, 200>> nact(next_B);\n\n        for(int k=0; k<next_B; ++k){\n            int i = scores[k].second.first;\n            int d = scores[k].second.second;\n            nacc[k] = acc[i];\n            nact[k] = act[i];\n            nact[k][t] = d;\n            double* p_npr = npr_flat.data() + k * 400;\n            double* p_opr = pr_flat.data() + i * 400;\n            for(int j=0; j<400; ++j){\n                if(j == ti_idx) continue;\n                double pr = p_opr[j];\n                p_npr[j] += pr * p;\n                int ni = md[j][d];\n                if(ni == ti_idx) nacc[k] += pr * (1-p) * (400-t);\n                else p_npr[ni] += pr * (1-p);\n            }\n        }\n        pr_flat = move(npr_flat);\n        acc = move(nacc);\n        act = move(nact);\n        cur_B = next_B;\n    }\n\n    double bsc=-1;string br;\n    for(int i=0;i<cur_B;i++){\n        if(acc[i] > bsc) {\n            bsc = acc[i];\n            br = \"\";\n            for(int t=0;t<200;++t) br += \"UDLR\"[act[i][t]];\n        }\n    }\n    return br;\n}\n\nvoid coordinate_descent(string& best) {\n    int L = best.size();\n    \n    for(int pass=0; pass<50; ++pass) {\n        memset(pr_arr[0], 0, sizeof(pr_arr[0]));\n        pr_arr[0][si*20+sj] = 1.0;\n        for(int t=0; t<L; ++t) {\n            memset(pr_arr[t+1], 0, sizeof(pr_arr[t+1]));\n            int dd = c2d[(unsigned char)best[t]];\n            for(int i=0; i<400; ++i) {\n                if(i == ti_idx) continue;\n                double pr = pr_arr[t][i];\n                pr_arr[t+1][i] += pr * p;\n                int ni = md[i][dd];\n                if(ni != ti_idx) pr_arr[t+1][ni] += pr * (1-p);\n            }\n        }\n        \n        for(int i=0; i<400; ++i) W[L][i] = 0;\n        for(int t=L-1; t>=0; --t) {\n            int dd = c2d[(unsigned char)best[t]];\n            for(int i=0; i<400; ++i) {\n                if(i == ti_idx) { W[t][i] = 0; continue; }\n                double val = p * W[t+1][i];\n                int ni = md[i][dd];\n                if(ni == ti_idx) val += (1-p) * (400 - t);\n                else val += (1-p) * W[t+1][ni];\n                W[t][i] = val;\n            }\n        }\n        \n        bool changed = false;\n        for(int pos=L-1; pos>=0; --pos) {\n            int current_d = c2d[(unsigned char)best[pos]];\n            double current_score = 0;\n            for(int i=0; i<400; ++i) {\n                if(i == ti_idx) continue;\n                double pr_i = pr_arr[pos][i];\n                if(pr_i < 1e-18) continue;\n                double val = p * W[pos+1][i];\n                int ni = md[i][current_d];\n                if(ni == ti_idx) val += (1-p) * (400 - pos);\n                else val += (1-p) * W[pos+1][ni];\n                current_score += pr_i * val;\n            }\n            \n            double best_new_score = current_score;\n            int best_d = current_d;\n            \n            for(int d=0; d<4; ++d) {\n                if(d == current_d) continue;\n                double new_score = 0;\n                for(int i=0; i<400; ++i) {\n                    if(i == ti_idx) continue;\n                    double pr_i = pr_arr[pos][i];\n                    if(pr_i < 1e-18) continue;\n                    double val = p * W[pos+1][i];\n                    int ni = md[i][d];\n                    if(ni == ti_idx) val += (1-p) * (400 - pos);\n                    else val += (1-p) * W[pos+1][ni];\n                    new_score += pr_i * val;\n                }\n                if(new_score > best_new_score + 1e-9) {\n                    best_new_score = new_score;\n                    best_d = d;\n                }\n            }\n            \n            if(best_d != current_d) {\n                changed = true;\n                best[pos] = \"UDLR\"[best_d];\n            }\n            \n            int final_d = c2d[(unsigned char)best[pos]];\n            for(int i=0; i<400; ++i) {\n                if(i == ti_idx) { W[pos][i] = 0; continue; }\n                double val = p * W[pos+1][i];\n                int ni = md[i][final_d];\n                if(ni == ti_idx) val += (1-p) * (400 - pos);\n                else val += (1-p) * W[pos+1][ni];\n                W[pos][i] = val;\n            }\n        }\n        if(!changed) break;\n    }\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);cin.tie(nullptr);\n    c2d['U']=0;c2d['D']=1;c2d['L']=2;c2d['R']=3;\n    cin>>si>>sj>>ti>>tj>>p;init();\n    string best; double bs = 0;\n    \n    auto optimize = [&](string s) {\n        if(s.size() < 200) {\n            double pr[400] = {}; pr[si*20+sj] = 1;\n            for(char c : s) {\n                int d = c2d[(unsigned char)c];\n                double np[400] = {};\n                for(int i=0; i<400; ++i) { if(pr[i]<1e-18) continue; if(i==ti_idx) continue; np[i] += p*pr[i]; int ni=md[i][d]; if(ni!=ti_idx) np[ni]+=(1-p)*pr[i]; }\n                memcpy(pr, np, sizeof(pr));\n            }\n            for(int t=s.size(); t<200; t++) {\n                double bsc2 = -1; int ba = 0;\n                for(int d=0; d<4; d++) {\n                    double rp = 0; double np[400] = {};\n                    for(int i=0; i<400; ++i) { if(pr[i]<1e-18) continue; if(i==ti_idx) continue; np[i] += p*pr[i]; int ni=md[i][d]; if(ni==ti_idx) rp+=(1-p)*pr[i]; else np[ni]+=(1-p)*pr[i]; }\n                    double sc = rp * (400 - t); for(int i=0; i<400; ++i) sc += np[i] * fv[i][t+2];\n                    if(sc > bsc2) { bsc2 = sc; ba = d; }\n                }\n                s += \"UDLR\"[ba];\n                double np[400] = {};\n                for(int i=0; i<400; ++i) { if(pr[i]<1e-18) continue; if(i==ti_idx) continue; np[i] += p*pr[i]; int ni=md[i][ba]; if(ni!=ti_idx) np[ni]+=(1-p)*pr[i]; }\n                memcpy(pr, np, sizeof(pr));\n            }\n        }\n        coordinate_descent(s);\n        double sc = compute_score(s);\n        if(sc > bs) { bs = sc; best = s; }\n    };\n    \n    string sp = bfs_path();\n    optimize(sp);\n    \n    for(int r=2; r<=5; r++) {\n        string s;\n        for(int i=0; i<sp.size(); ++i) {\n            for(int k=0; k<r; ++k) {\n                if(s.size() < 200) s += sp[i];\n            }\n        }\n        optimize(s);\n    }\n    \n    optimize(\"\");\n    optimize(beam_search(500, 0));\n    optimize(beam_search(300, 1.0));\n    optimize(beam_search(200, 2.0));\n    optimize(beam_search(200, 5.0));\n    optimize(beam_search(200, 10.0));\n    \n    for(int i=0; i<50; ++i) {\n        string s = best;\n        int num_mutations = uniform_int_distribution<int>(1, 5)(rng);\n        for(int j=0; j<num_mutations; ++j) {\n            int pos = uniform_int_distribution<int>(0, 199)(rng);\n            s[pos] = \"UDLR\"[uniform_int_distribution<int>(0, 3)(rng)];\n        }\n        optimize(s);\n    }\n    \n    for(int i=0; i<30; ++i) {\n        string s = best;\n        int pos = uniform_int_distribution<int>(0, 180)(rng);\n        int len = uniform_int_distribution<int>(5, 20)(rng);\n        for(int j=pos; j<min(200, pos+len); ++j) s[j] = \"UDLR\"[uniform_int_distribution<int>(0, 3)(rng)];\n        optimize(s);\n    }\n    \n    cout<<best<<endl;return 0;}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint orig[N][N], cur[N][N], rot[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 rt[8][4]={{0,1,2,3},{1,2,3,0},{2,3,0,1},{3,0,1,2},{4,5,4,5},{5,4,5,4},{6,7,6,7},{7,6,7,6}};\n\nint cycle_counts[2002] = {};\nset<int> active_lengths;\nlong long total_loop_edges = 0;\n\nint vm[N][N][4]; \nunsigned int vcnt=0;\n\nvoid update_cycle_counts(int len, int delta) {\n    if (delta == 1) {\n        if (cycle_counts[len] == 0) active_lengths.insert(len);\n        cycle_counts[len]++;\n        total_loop_edges += len;\n    } else {\n        cycle_counts[len]--;\n        total_loop_edges -= len;\n        if (cycle_counts[len] == 0) active_lengths.erase(len);\n    }\n}\n\nvoid init_cycle_counts() {\n    memset(cycle_counts, 0, sizeof(cycle_counts));\n    active_lengths.clear();\n    total_loop_edges = 0;\n    \n    ++vcnt;\n    if (vcnt == 0) { memset(vm, 0, sizeof(vm)); vcnt = 1; }\n    \n    for (int i=0; i<N; i++) for (int j=0; j<N; j++) {\n        int t = cur[i][j];\n        for (int d=0; d<4; d++) {\n            if (vm[i][j][d] == vcnt || to[t][d] == -1) continue;\n            int si=i, sj=j, sd=d, ci=i, cj=j, cd=d, len=0;\n            bool is_cycle = false;\n            while (true) {\n                vm[ci][cj][cd] = vcnt;\n                int t2 = cur[ci][cj];\n                int d2 = to[t2][cd];\n                if (d2 == -1) break;\n                int ni = ci + di[d2], nj = cj + dj[d2];\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n                len++;\n                int nd = (d2 + 2) % 4;\n                if (ni == si && nj == sj && nd == sd) { is_cycle = true; break; }\n                if (vm[ni][nj][nd] == vcnt) break;\n                if (len > 2000) break;\n                ci = ni; cj = nj; cd = nd;\n            }\n            if (is_cycle) {\n                update_cycle_counts(len, 1);\n            }\n        }\n    }\n}\n\nvoid update_tile(int i, int j, int new_t) {\n    int old_t = cur[i][j];\n    if (old_t == new_t) return;\n\n    bool visited_old[4] = {false, false, false, false};\n    for (int d = 0; d < 4; d++) {\n        if (visited_old[d] || to[old_t][d] == -1) continue;\n        int len = 0;\n        int ci = i, cj = j, cd = d;\n        bool is_cycle = false;\n        while (true) {\n            int t2 = (ci == i && cj == j) ? old_t : cur[ci][cj];\n            int d2 = to[t2][cd];\n            if (d2 == -1) break;\n            if (ci == i && cj == j) { visited_old[cd] = true; visited_old[d2] = true; }\n            int ni = ci + di[d2], nj = cj + dj[d2];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n            len++;\n            int nd = (d2 + 2) % 4;\n            if (ni == i && nj == j && nd == d) { is_cycle = true; break; }\n            if (len > 2000) break;\n            ci = ni; cj = nj; cd = nd;\n        }\n        if (is_cycle) {\n            update_cycle_counts(len, -1);\n        }\n    }\n\n    cur[i][j] = new_t;\n    bool visited_new[4] = {false, false, false, false};\n    for (int d = 0; d < 4; d++) {\n        if (visited_new[d] || to[new_t][d] == -1) continue;\n        int len = 0;\n        int ci = i, cj = j, cd = d;\n        bool is_cycle = false;\n        while (true) {\n            int t2 = (ci == i && cj == j) ? new_t : cur[ci][cj];\n            int d2 = to[t2][cd];\n            if (d2 == -1) break;\n            if (ci == i && cj == j) { visited_new[cd] = true; visited_new[d2] = true; }\n            int ni = ci + di[d2], nj = cj + dj[d2];\n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) break;\n            len++;\n            int nd = (d2 + 2) % 4;\n            if (ni == i && nj == j && nd == d) { is_cycle = true; break; }\n            if (len > 2000) break;\n            ci = ni; cj = nj; cd = nd;\n        }\n        if (is_cycle) {\n            update_cycle_counts(len, 1);\n        }\n    }\n}\n\nlong long get_score() {\n    if (active_lengths.empty()) return 0;\n    auto it = active_lengths.rbegin();\n    int L1 = *it;\n    if (cycle_counts[L1] >= 2) return (long long)L1 * L1;\n    if (active_lengths.size() == 1) return 0;\n    int L2 = *next(it);\n    return (long long)L1 * L2;\n}\n\nlong long get_sa_energy() {\n    if (active_lengths.empty()) return 0;\n    auto it = active_lengths.rbegin();\n    int L1 = *it;\n    \n    if (cycle_counts[L1] >= 2) {\n        return (long long)L1 * L1 * 1000 + total_loop_edges;\n    }\n    if (active_lengths.size() == 1) {\n        return total_loop_edges;\n    }\n    int L2 = *next(it);\n    return (long long)L1 * L2 * 1000 + total_loop_edges;\n}\n\nint lmatch(int i, int j) {\n    int t = cur[i][j], m = 0;\n    for (int d = 0; d < 4; d++) {\n        if (to[t][d] == -1) continue;\n        int ni = i + di[d], nj = j + dj[d];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n        if (to[cur[ni][nj]][(d + 2) % 4] != -1) m++;\n    }\n    return m;\n}\n\nvoid greedy_match() {\n    for (int pass = 0; pass < 10; pass++) {\n        bool ch = false;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            int br = rot[i][j], bm = lmatch(i, j);\n            for (int r = 0; r < 4; r++) {\n                if (r == rot[i][j]) continue;\n                cur[i][j] = rt[orig[i][j]][r];\n                int m = lmatch(i, j);\n                if (m > bm) { bm = m; br = r; ch = true; }\n            }\n            rot[i][j] = br; cur[i][j] = rt[orig[i][j]][br];\n        }\n        if (!ch) break;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(0);\n    for (int i = 0; i < N; i++) { string s; cin >> s; for (int j = 0; j < N; j++) orig[i][j] = s[j] - '0'; }\n    mt19937 rng(42);\n    long long gbest = 0; int grot[N][N] = {};\n    auto t0 = chrono::steady_clock::now();\n    bool have_best = false;\n\n    for (int trial = 0; ; trial++) {\n        double elapsed = chrono::duration<double>(chrono::steady_clock::now() - t0).count();\n        if (elapsed > 1.5) break;\n\n        if (have_best && trial % 2 == 1) {\n            memcpy(rot, grot, sizeof(rot));\n            int np = 20 + rng() % 80;\n            for (int k = 0; k < np; k++) { int i = rng() % N, j = rng() % N; rot[i][j] = rng() % 4; }\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cur[i][j] = rt[orig[i][j]][rot[i][j]];\n            greedy_match();\n        } else {\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) { rot[i][j] = rng() % 4; cur[i][j] = rt[orig[i][j]][rot[i][j]]; }\n            greedy_match();\n        }\n\n        init_cycle_counts();\n        long long current_energy = get_sa_energy();\n        long long best_score = get_score();\n        int brot[N][N]; memcpy(brot, rot, sizeof(rot));\n\n        for (int iter = 0; ; iter++) {\n            if (iter % 10000 == 0) {\n                if (chrono::duration<double>(chrono::steady_clock::now() - t0).count() > 1.7) break;\n            }\n            double frac = min(iter / 2000000.0, 1.0);\n            double temp = 50000.0 * pow(0.00002, frac);\n            int idx = (rng() >> 2) % 900, i = idx / N, j = idx % N;\n            int old_r = rot[i][j];\n            int new_r = (rng() >> 12) & 3;\n            if (old_r == new_r) continue;\n            int new_t = rt[orig[i][j]][new_r];\n            if (new_t == cur[i][j]) continue;\n\n            update_tile(i, j, new_t);\n            long long new_energy = get_sa_energy();\n            long long diff = new_energy - current_energy;\n\n            if (diff >= 0 || (double)(rng() & 0xFFFF) / 65536.0 < exp((double)diff / temp)) {\n                current_energy = new_energy;\n                rot[i][j] = new_r;\n                long long true_score = get_score();\n                if (true_score > best_score) {\n                    best_score = true_score;\n                    memcpy(brot, rot, sizeof(rot));\n                }\n            } else {\n                update_tile(i, j, rt[orig[i][j]][old_r]);\n                rot[i][j] = old_r;\n            }\n        }\n\n        if (best_score > gbest) {\n            gbest = best_score;\n            memcpy(grot, brot, sizeof(grot));\n            have_best = true;\n        }\n    }\n\n    memcpy(rot, grot, sizeof(rot));\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cur[i][j] = rt[orig[i][j]][rot[i][j]];\n    init_cycle_counts();\n    long long current_score = get_score();\n\n    for (int pass = 0; pass < 10; pass++) {\n        bool imp = false;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            int old_t = cur[i][j];\n            int best_new_t = old_t;\n            long long best_local_score = current_score;\n            int best_new_r = rot[i][j];\n\n            for (int r = 0; r < 4; r++) {\n                int new_t = rt[orig[i][j]][r];\n                if (new_t == old_t) continue;\n                update_tile(i, j, new_t);\n                long long new_score = get_score();\n                if (new_score > best_local_score) {\n                    best_local_score = new_score;\n                    best_new_t = new_t;\n                    best_new_r = r;\n                }\n                update_tile(i, j, old_t);\n            }\n\n            if (best_new_t != old_t) {\n                update_tile(i, j, best_new_t);\n                rot[i][j] = best_new_r;\n                current_score = best_local_score;\n                imp = true;\n            }\n        }\n        if (!imp) break;\n    }\n\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cout << rot[i][j];\n    cout << endl;\n\n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N,T,board[10][10],init_board[10][10],er,ec,init_er,init_ec;\nint target[10][10],tile_count[16];\nint best_board[10][10],best_er_b,best_ec_b;\nconst int DR[]={-1,1,0,0},DC[]={0,0,-1,1};\nconst int BS[]={2,8,1,4},BN[]={8,2,4,1};\nconst char DC_C[]={'U','D','L','R'};\nconst int REV[]={1,0,3,2};\n\nint par2[100],sz2[100],edg2[100];\nint find2(int x){while(par2[x]!=x)x=par2[x]=par2[par2[x]];return x;}\nvoid unite2(int x,int y){\n    x=find2(x);y=find2(y);\n    if(x==y){edg2[x]++;return;}\n    if(sz2[x]<sz2[y])swap(x,y);\n    par2[y]=x;sz2[x]+=sz2[y];edg2[x]+=edg2[y]+1;\n}\nint max_tree(){\n    for(int i=0;i<N*N;i++){par2[i]=i;sz2[i]=board[i/N][i%N]?1:0;edg2[i]=0;}\n    for(int i=0;i<N;i++)for(int j=0;j<N-1;j++)\n        if(board[i][j]&&board[i][j+1]&&(board[i][j]&4)&&(board[i][j+1]&1))unite2(i*N+j,i*N+j+1);\n    for(int i=0;i<N-1;i++)for(int j=0;j<N;j++)\n        if(board[i][j]&&board[i+1][j]&&(board[i][j]&8)&&(board[i+1][j]&2))unite2(i*N+j,(i+1)*N+j);\n    int mx=0;\n    for(int i=0;i<N*N;i++)if(board[i/N][i%N]&&find2(i)==i&&edg2[i]==sz2[i]-1)mx=max(mx,sz2[i]);\n    return mx;\n}\n\nvoid gen_target(mt19937& rng,int skip_r,int skip_c){\n    vector<tuple<unsigned,int,int>> el;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++){\n        if(i==skip_r&&j==skip_c)continue;\n        if(i+1<N&&!(i+1==skip_r&&j==skip_c))el.push_back({rng(),i*N+j,(i+1)*N+j});\n        if(j+1<N&&!(i==skip_r&&j+1==skip_c))el.push_back({rng(),i*N+j,i*N+j+1});\n    }\n    sort(el.begin(),el.end());\n    vector<int> par(N*N),rnk(N*N,0);iota(par.begin(),par.end(),0);\n    function<int(int)> f=[&](int x)->int{return par[x]==x?x:par[x]=f(par[x]);};\n    memset(target,0,sizeof(target));\n    for(auto&[w,u,v]:el){\n        int pu=f(u),pv=f(v);\n        if(pu!=pv){\n            int r1=u/N,c1=u%N,r2=v/N,c2=v%N;\n            if(r2==r1+1){target[r1][c1]|=8;target[r2][c2]|=2;}\n            else{target[r1][c1]|=4;target[r2][c2]|=1;}\n            if(rnk[pu]<rnk[pv])swap(pu,pv);\n            par[pv]=pu;\n            if(rnk[pu]==rnk[pv])rnk[pu]++;\n        }\n    }\n}\n\nint match_ub(){\n    int need[16]={};\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(target[i][j])need[target[i][j]]++;\n    int total=0;\n    for(int t=1;t<16;t++){\n        if(!need[t])continue;int avail=0;\n        for(int s=1;s<16;s++)if((s&t)==t)avail+=tile_count[s];\n        total+=min(avail,need[t]);\n    }\n    return total;\n}\n\nvoid recompute(int&cm,int&cc,int&tc){\n    cm=cc=tc=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)\n        if(board[i][j]&&target[i][j]&&(board[i][j]&target[i][j])==target[i][j])cm++;\n    for(int i=0;i<N;i++)for(int j=0;j<N-1;j++){\n        if(board[i][j]&&board[i][j+1]&&(board[i][j]&4)&&(board[i][j+1]&1)){\n            cc++;if((target[i][j]&4)&&(target[i][j+1]&1))tc++;\n        }\n    }\n    for(int i=0;i<N-1;i++)for(int j=0;j<N;j++){\n        if(board[i][j]&&board[i+1][j]&&(board[i][j]&8)&&(board[i+1][j]&2)){\n            cc++;if((target[i][j]&8)&&(target[i+1][j]&2))tc++;\n        }\n    }\n}\n\nvoid apply_move(int d,int&cm,int&cc,int&tc){\n    int nr=er+DR[d],nc=ec+DC[d],X=board[nr][nc];\n    if(target[nr][nc]&&(X&target[nr][nc])==target[nr][nc])cm--;\n    if(target[er][ec]&&(X&target[er][ec])==target[er][ec])cm++;\n    for(int dd=0;dd<4;dd++){\n        int r=er+DR[dd],c=ec+DC[dd];\n        if(r>=0&&r<N&&c>=0&&c<N&&!(r==nr&&c==nc)){\n            int nb=board[r][c];\n            if(nb&&(X&BS[dd])&&(nb&BN[dd])){cc++;if((target[er][ec]&BS[dd])&&(target[r][c]&BN[dd]))tc++;}\n        }\n        r=nr+DR[dd];c=nc+DC[dd];\n        if(r>=0&&r<N&&c>=0&&c<N&&!(r==er&&c==ec)){\n            int nb=board[r][c];\n            if(nb&&(X&BS[dd])&&(nb&BN[dd])){cc--;if((target[nr][nc]&BS[dd])&&(target[r][c]&BN[dd]))tc--;}\n        }\n    }\n    swap(board[er][ec],board[nr][nc]);er=nr;ec=nc;\n}\n\nvoid save_best(int b[10][10],int& ber,int& bec){\n    memcpy(b,board,sizeof(board));ber=er;bec=ec;\n}\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    cin>>N>>T;memset(tile_count,0,sizeof(tile_count));\n    for(int i=0;i<N;i++){string s;cin>>s;for(int j=0;j<N;j++){char c=s[j];board[i][j]=(c>='0'&&c<='9')?c-'0':c-'a'+10;if(board[i][j])tile_count[board[i][j]]++;else{init_er=i;init_ec=j;}}}\n    memcpy(init_board,board,sizeof(board));er=init_er;ec=init_ec;\n    int gbm=max_tree();string gbm_moves;\n    memcpy(best_board,init_board,sizeof(init_board));best_er_b=init_er;best_ec_b=init_ec;\n    auto start=chrono::high_resolution_clock::now();\n\n    // Phase 1: SA from initial board\n    for(int trial=0;;trial++){\n        auto now=chrono::high_resolution_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-start).count()>1800)break;\n        mt19937 rng(42+trial*137);\n        memcpy(board,init_board,sizeof(board));er=init_er;ec=init_ec;\n        int skip_r=rng()%N,skip_c=rng()%N;\n        gen_target(rng,skip_r,skip_c);\n        if(match_ub()<gbm+2)continue;\n        int cm,cc,tc;recompute(cm,cc,tc);\n        string mv;mv.reserve(T);\n        int bm=0;size_t bi=0;int ld=-1,stale=0,chk=0;\n        int max_steps=min(T,600+trial%4*200);\n        double cool=pow(0.03/3.0,1.0/max_steps),temp=3.0;\n        int tb[10][10],tber,tbec;save_best(tb,tber,tbec);\n\n        while((int)mv.size()<max_steps){\n            if(++chk%100==0){auto now2=chrono::high_resolution_clock::now();if(chrono::duration_cast<chrono::milliseconds>(now2-start).count()>1800)break;}\n            long long dv[4];\n            for(int d=0;d<4;d++){\n                int nr=er+DR[d],nc=ec+DC[d];\n                if(nr<0||nr>=N||nc<0||nc>=N){dv[d]=-1e18;continue;}\n                int X=board[nr][nc],dm=0;\n                if(target[nr][nc]&&(X&target[nr][nc])==target[nr][nc])dm--;\n                if(target[er][ec]&&(X&target[er][ec])==target[er][ec])dm++;\n                int dcc=0,dtc=0;\n                for(int dd=0;dd<4;dd++){\n                    int r=er+DR[dd],c=ec+DC[dd];\n                    if(r>=0&&r<N&&c>=0&&c<N&&!(r==nr&&c==nc)){int nb=board[r][c];if(nb&&(X&BS[dd])&&(nb&BN[dd])){dcc++;if((target[er][ec]&BS[dd])&&(target[r][c]&BN[dd]))dtc++;}}\n                    r=nr+DR[dd];c=nc+DC[dd];\n                    if(r>=0&&r<N&&c>=0&&c<N&&!(r==er&&c==ec)){int nb=board[r][c];if(nb&&(X&BS[dd])&&(nb&BN[dd])){dcc--;if((target[nr][nc]&BS[dd])&&(target[r][c]&BN[dd]))dtc--;}}\n                }\n                dv[d]=(long long)dm*500+(long long)dtc*1000-(long long)(dcc-dtc)*200;\n            }\n            int bd=-1;long long bv=-1e18;for(int d=0;d<4;d++)if(dv[d]>bv){bv=dv[d];bd=d;}\n            if(bd==-1)break;int ch;\n            if(bv>0){ch=bd;stale=0;}\n            else{stale++;double delta=(double)bv/1000.0;\n                if(exp(delta/max(temp,0.01))>(double)rng()/(double)UINT32_MAX)ch=bd;\n                else{int v[4],nv=0;for(int d=0;d<4;d++){if(dv[d]<=-1e18)continue;if(ld>=0&&d==REV[ld])continue;v[nv++]=d;}\n                if(!nv)for(int d=0;d<4;d++)if(dv[d]>-1e18)v[nv++]=d;if(!nv)break;ch=v[rng()%nv];}}\n            apply_move(ch,cm,cc,tc);mv+=DC_C[ch];ld=ch;\n            if(chk%25==0){int mx=max_tree();if(mx>bm){bm=mx;bi=mv.size();stale=0;save_best(tb,tber,tbec);}if(mx==N*N-1)break;}\n            temp*=cool;\n            if(stale>250){\n                for(int w=0;w<15&&(int)mv.size()<max_steps;w++){\n                    int v[4],nv=0;for(int d=0;d<4;d++){int nr2=er+DR[d],nc2=ec+DC[d];if(nr2>=0&&nr2<N&&nc2>=0&&nc2<N){if(ld>=0&&d==REV[ld])continue;v[nv++]=d;}}\n                    if(!nv)for(int d=0;d<4;d++){int nr2=er+DR[d],nc2=ec+DC[d];if(nr2>=0&&nr2<N&&nc2>=0&&nc2<N)v[nv++]=d;}\n                    if(!nv)break;int d=v[rng()%nv];apply_move(d,cm,cc,tc);mv+=DC_C[d];ld=d;\n                }\n                recompute(cm,cc,tc);stale=0;temp=max(temp,2.0);\n                int mx=max_tree();if(mx>bm){bm=mx;bi=mv.size();save_best(tb,tber,tbec);}\n            }\n        }\n        {int mx=max_tree();if(mx>bm){bm=mx;bi=mv.size();save_best(tb,tber,tbec);}}\n        if(bm>gbm){gbm=bm;gbm_moves=mv.substr(0,bi);memcpy(best_board,tb,sizeof(tb));best_er_b=tber;best_ec_b=tbec;}\n        if(gbm==N*N-1)break;\n    }\n\n    // Phase 2: SA from best state with actual empty position\n    for(int trial2=0;;trial2++){\n        auto now=chrono::high_resolution_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-start).count()>2850)break;\n        mt19937 rng2(77777+trial2*137);\n        memcpy(board,best_board,sizeof(best_board));er=best_er_b;ec=best_ec_b;\n        // Use actual empty square position for target generation\n        int skip_r=best_er_b,skip_c=best_ec_b;\n        if(trial2%3==0){skip_r=rng2()%N;skip_c=rng2()%N;}\n        gen_target(rng2,skip_r,skip_c);\n        if(match_ub()<gbm+2)continue;\n        int cm,cc,tc;recompute(cm,cc,tc);\n        int max_s2=min(T-(int)gbm_moves.size(),400);\n        if(max_s2<=0)break;\n        string mv2;mv2.reserve(max_s2);\n        int bm2=gbm;size_t bi2=0;int ld2=-1,stale2=0,chk2=0;\n        double cool2=pow(0.02/2.0,1.0/max(max_s2,1)),temp2=2.0;\n        int tb2[10][10],tber2,tbec2;save_best(tb2,tber2,tbec2);\n\n        while((int)mv2.size()<max_s2){\n            if(++chk2%50==0){auto now2=chrono::high_resolution_clock::now();if(chrono::duration_cast<chrono::milliseconds>(now2-start).count()>2850)break;}\n            long long dv[4];\n            for(int d=0;d<4;d++){\n                int nr=er+DR[d],nc=ec+DC[d];\n                if(nr<0||nr>=N||nc<0||nc>=N){dv[d]=-1e18;continue;}\n                int X=board[nr][nc],dm=0;\n                if(target[nr][nc]&&(X&target[nr][nc])==target[nr][nc])dm--;\n                if(target[er][ec]&&(X&target[er][ec])==target[er][ec])dm++;\n                int dcc=0,dtc=0;\n                for(int dd=0;dd<4;dd++){\n                    int r=er+DR[dd],c=ec+DC[dd];\n                    if(r>=0&&r<N&&c>=0&&c<N&&!(r==nr&&c==nc)){int nb=board[r][c];if(nb&&(X&BS[dd])&&(nb&BN[dd])){dcc++;if((target[er][ec]&BS[dd])&&(target[r][c]&BN[dd]))dtc++;}}\n                    r=nr+DR[dd];c=nc+DC[dd];\n                    if(r>=0&&r<N&&c>=0&&c<N&&!(r==er&&c==ec)){int nb=board[r][c];if(nb&&(X&BS[dd])&&(nb&BN[dd])){dcc--;if((target[nr][nc]&BS[dd])&&(target[r][c]&BN[dd]))dtc--;}}\n                }\n                dv[d]=(long long)dm*500+(long long)dtc*1200-(long long)(dcc-dtc)*300;\n            }\n            int bd=-1;long long bv=-1e18;for(int d=0;d<4;d++)if(dv[d]>bv){bv=dv[d];bd=d;}\n            if(bd==-1)break;int ch;\n            if(bv>0){ch=bd;stale2=0;}\n            else{stale2++;double delta=(double)bv/1000.0;\n                if(exp(delta/max(temp2,0.01))>(double)rng2()/(double)UINT32_MAX)ch=bd;\n                else{int v[4],nv=0;for(int d=0;d<4;d++){if(dv[d]<=-1e18)continue;if(ld2>=0&&d==REV[ld2])continue;v[nv++]=d;}\n                if(!nv)for(int d=0;d<4;d++)if(dv[d]>-1e18)v[nv++]=d;if(!nv)break;ch=v[rng2()%nv];}}\n            apply_move(ch,cm,cc,tc);mv2+=DC_C[ch];ld2=ch;\n            if(chk2%20==0){int mx=max_tree();if(mx>bm2){bm2=mx;bi2=mv2.size();stale2=0;save_best(tb2,tber2,tbec2);}if(mx==N*N-1)break;}\n            temp2*=cool2;\n            if(stale2>200){\n                for(int w=0;w<12&&(int)mv2.size()<max_s2;w++){\n                    int v[4],nv=0;for(int d=0;d<4;d++){int nr2=er+DR[d],nc2=ec+DC[d];if(nr2>=0&&nr2<N&&nc2>=0&&nc2<N){if(ld2>=0&&d==REV[ld2])continue;v[nv++]=d;}}\n                    if(!nv)for(int d=0;d<4;d++){int nr2=er+DR[d],nc2=ec+DC[d];if(nr2>=0&&nr2<N&&nc2>=0&&nc2<N)v[nv++]=d;}\n                    if(!nv)break;int d=v[rng2()%nv];apply_move(d,cm,cc,tc);mv2+=DC_C[d];ld2=d;\n                }\n                recompute(cm,cc,tc);stale2=0;temp2=max(temp2,1.5);\n                int mx=max_tree();if(mx>bm2){bm2=mx;bi2=mv2.size();save_best(tb2,tber2,tbec2);}\n            }\n        }\n        {int mx=max_tree();if(mx>bm2){bm2=mx;bi2=mv2.size();save_best(tb2,tber2,tbec2);}}\n        if(bm2>gbm){gbm=bm2;gbm_moves+=mv2.substr(0,bi2);memcpy(best_board,tb2,sizeof(tb2));best_er_b=tber2;best_ec_b=tbec2;}\n        if(gbm==N*N-1)break;\n    }\n\n    if((int)gbm_moves.size()>T)gbm_moves=gbm_moves.substr(0,T);\n    cout<<gbm_moves<<'\\n';\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\n\nint N, K;\nint a_arr[11];\nvector<ll> px, py;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> K;\n    for (int d = 1; d <= 10; d++) cin >> a_arr[d];\n    px.resize(N); py.resize(N);\n    for (int i = 0; i < N; i++) cin >> px[i] >> py[i];\n    \n    auto start = chrono::steady_clock::now();\n    \n    struct Line { ll la, lb, lc, p1x, p1y, p2x, p2y; };\n    vector<Line> lines, best_lines;\n    int best_overall = 0;\n    \n    auto make_line = [&](ll x1, ll y1, ll x2, ll y2) -> Line {\n        if (x1 == x2 && y1 == y2) x2++;\n        return {y2-y1, x1-x2, x2*y1-x1*y2, x1, y1, x2, y2};\n    };\n    \n    auto make_sep = [&](int i, int j) -> Line {\n        ll dx = py[i]-py[j], dy = px[j]-px[i];\n        ll g = __gcd(abs(dx), abs(dy)); if(g>0){dx/=g;dy/=g;}\n        if(dx==0&&dy==0) dx=1;\n        ll mx2=px[i]+px[j], my2=py[i]+py[j];\n        for(int r=0;r<4;r++){\n            ll cx=(mx2+(r&1))/2, cy=(my2+((r>>1)&1))/2;\n            Line l=make_line(cx,cy,cx+dx,cy+dy);\n            ll vi=l.la*px[i]+l.lb*py[i]+l.lc, vj=l.la*px[j]+l.lb*py[j]+l.lc;\n            if(vi!=0&&vj!=0&&(vi>0)!=(vj>0)) return l;\n        }\n        return make_line(mx2/2,my2/2,mx2/2+dx,my2/2+dy);\n    };\n    \n    auto compute_gm = [&]() -> vector<vector<int>> {\n        int nl = lines.size();\n        map<pair<ll,ll>,int> smap;\n        vector<vector<int>> gm;\n        for(int i=0;i<N;i++){\n            ll h1=0,h2=0; bool dead=false;\n            for(int j=0;j<nl;j++){\n                ll val=lines[j].la*px[i]+lines[j].lb*py[i]+lines[j].lc;\n                if(val==0){dead=true;break;}\n                if(val>0){if(j<64)h1|=1LL<<j;else h2|=1LL<<(j-64);}\n            }\n            if(!dead){\n                auto[it,ins]=smap.insert({{h1,h2},(int)gm.size()});\n                if(ins) gm.push_back({});\n                gm[it->second].push_back(i);\n            }\n        }\n        return gm;\n    };\n    \n    auto score_gm = [&](vector<vector<int>>& gm) -> int {\n        int pc[11]={};\n        for(auto& m:gm){int sz=m.size();if(sz>=1&&sz<=10)pc[sz]++;}\n        int s=0; for(int d=1;d<=10;d++) s+=min(a_arr[d],pc[d]); return s;\n    };\n    \n    auto eval_cand = [&](Line& l, vector<vector<int>>& gm) -> int {\n        int pc[11]={};\n        for(auto& m:gm){\n            int pos=0,neg=0;\n            for(int i:m){\n                ll val=l.la*px[i]+l.lb*py[i]+l.lc;\n                if(val>0)pos++;else if(val<0)neg++;\n            }\n            if(pos>=1&&pos<=10)pc[pos]++;\n            if(neg>=1&&neg<=10)pc[neg]++;\n        }\n        int s=0; for(int d=1;d<=10;d++) s+=min(a_arr[d],pc[d]); return s;\n    };\n    \n    auto gen_cands = [&](vector<vector<int>>& gm, int max_cands=400) -> vector<Line> {\n        int pc[11]={};\n        for(auto& m:gm){int sz=m.size();if(sz>=1&&sz<=10)pc[sz]++;}\n        vector<Line> cands;\n        set<tuple<ll,ll,ll>> seen;\n        auto add=[&](Line l){\n            if((int)cands.size()>=max_cands) return;\n            ll a=l.la,b=l.lb,c=l.lc;\n            ll g=__gcd(__gcd(abs(a),abs(b)),abs(c));\n            if(g>0){a/=g;b/=g;c/=g;}\n            if(a<0||(a==0&&b<0)||(a==0&&b==0&&c<0)){a=-a;b=-b;c=-c;}\n            if(seen.insert({a,b,c}).second) cands.push_back(l);\n        };\n        // Sort groups by priority\n        vector<pair<int,int>> order;\n        for(int i=0;i<(int)gm.size();i++){\n            int sz=gm[i].size();\n            if(sz<=1) continue;\n            bool need=(sz>10)||(sz<=10&&pc[sz]>a_arr[sz]);\n            if(!need) for(int p=1;p<sz;p++){\n                int n=sz-p;\n                if((p<=10&&pc[p]<a_arr[p])||(n<=10&&pc[n]<a_arr[n])){need=true;break;}\n            }\n            if(need) order.push_back({-sz,i});\n        }\n        sort(order.begin(),order.end());\n        for(auto& [_,gi]:order){\n            auto& m=gm[gi];\n            int sz=m.size();\n            int lim=min((int)m.size(),10);\n            for(int ii=0;ii<lim&&(int)cands.size()<max_cands;ii++)\n                for(int jj=ii+1;jj<lim&&(int)cands.size()<max_cands;jj++)\n                    add(make_sep(m[ii],m[jj]));\n            ll cx=0,cy=0;\n            for(int i:m){cx+=px[i];cy+=py[i];}\n            cx/=sz;cy/=sz;\n            for(int ag=0;ag<12&&(int)cands.size()<max_cands;ag++){\n                double ar=ag*M_PI/6;\n                ll ddx=(ll)round(10000*cos(ar)),ddy=(ll)round(10000*sin(ar));\n                if(ddx||ddy) add(make_line(cx,cy,cx+ddx,cy+ddy));\n            }\n            for(int ii=0;ii<min(lim,5)&&(int)cands.size()<max_cands;ii++)\n                for(int jj=ii+1;jj<min(lim,5)&&(int)cands.size()<max_cands;jj++){\n                    ll mx2=(px[m[ii]]+px[m[jj]])/2,my2=(py[m[ii]]+py[m[jj]])/2;\n                    for(int ag=0;ag<6&&(int)cands.size()<max_cands;ag++){\n                        double ar=ag*M_PI/3;\n                        ll ddx=(ll)round(10000*cos(ar)),ddy=(ll)round(10000*sin(ar));\n                        if(ddx||ddy) add(make_line(mx2,my2,mx2+ddx,my2+ddy));\n                    }\n                }\n            if((int)cands.size()>=max_cands) break;\n        }\n        return cands;\n    };\n    \n    // Phase 1: Greedy\n    for(int iter=0;iter<K;iter++){\n        if(chrono::duration<double>(chrono::steady_clock::now()-start).count()>0.8) break;\n        auto gm=compute_gm();\n        int cs=score_gm(gm);\n        if(cs>best_overall){best_overall=cs;best_lines=lines;}\n        int mx=0;for(int d=1;d<=10;d++)mx+=a_arr[d];\n        if(cs==mx) break;\n        auto cands=gen_cands(gm,400);\n        if(cands.empty()) break;\n        int bs=cs,bi=-1;\n        for(int i=0;i<(int)cands.size();i++){\n            int s=eval_cand(cands[i],gm);\n            if(s>bs){bs=s;bi=i;}\n        }\n        if(bi>=0) lines.push_back(cands[bi]);\n        else {\n            int max_sz=1,max_i=-1;\n            for(int i=0;i<(int)gm.size();i++)\n                if((int)gm[i].size()>max_sz){max_sz=gm[i].size();max_i=i;}\n            if(max_sz>1&&(int)lines.size()<K)\n                lines.push_back(make_sep(gm[max_i][0],gm[max_i][1]));\n            else break;\n        }\n    }\n    \n    {auto gm=compute_gm();int s=score_gm(gm);if(s>best_overall){best_overall=s;best_lines=lines;}}\n    \n    // Phase 2: Local search\n    mt19937 rng(42);\n    int no_imp=0;\n    while(chrono::duration<double>(chrono::steady_clock::now()-start).count()<2.85){\n        int nl=lines.size();\n        if(nl==0) break;\n        bool improved=false;\n        \n        // Try adding a line\n        if((int)lines.size()<K&&(rng()%3!=0)){\n            auto gm=compute_gm();\n            int cs=score_gm(gm);\n            auto cands=gen_cands(gm,300);\n            if(!cands.empty()){\n                int bs=cs,bi=-1;\n                for(int i=0;i<(int)cands.size();i++){\n                    int s=eval_cand(cands[i],gm);\n                    if(s>bs){bs=s;bi=i;}\n                }\n                if(bi>=0){lines.push_back(cands[bi]);improved=true;}\n            }\n        }\n        \n        // Try replacing a line\n        if(!improved&&nl>0){\n            int idx=rng()%nl;\n            auto old=lines[idx];\n            lines[idx]=lines.back();lines.pop_back();\n            auto gm=compute_gm();\n            int cs=score_gm(gm);\n            auto cands=gen_cands(gm,300);\n            cands.push_back(old);\n            int bs=cs,bi=(int)cands.size()-1;\n            for(int i=0;i<(int)cands.size()-1;i++){\n                int s=eval_cand(cands[i],gm);\n                if(s>bs){bs=s;bi=i;}\n            }\n            lines.push_back(cands[bi]);\n            if(bs>cs) improved=true;\n        }\n        \n        auto gm=compute_gm();\n        int ns=score_gm(gm);\n        if(ns>best_overall){best_overall=ns;best_lines=lines;no_imp=0;}\n        else if(improved) no_imp=0;\n        else no_imp++;\n        \n        if(no_imp>60){\n            lines=best_lines;\n            int nl2=lines.size();\n            if(nl2>3){\n                int rc=2+rng()%4;\n                shuffle(lines.begin(),lines.end(),rng);\n                lines.resize(max(0,(int)lines.size()-rc));\n                for(int iter2=0;iter2<rc+8&&(int)lines.size()<K;iter2++){\n                    if(chrono::duration<double>(chrono::steady_clock::now()-start).count()>2.85) break;\n                    auto gm2=compute_gm();\n                    int cs2=score_gm(gm2);\n                    auto cands2=gen_cands(gm2,300);\n                    if(cands2.empty()) break;\n                    int bs2=cs2,bi2=-1;\n                    for(int i=0;i<(int)cands2.size();i++){\n                        int s=eval_cand(cands2[i],gm2);\n                        if(s>bs2){bs2=s;bi2=i;}\n                    }\n                    if(bi2>=0) lines.push_back(cands2[bi2]);\n                    else break;\n                }\n                gm=compute_gm();ns=score_gm(gm);\n                if(ns>best_overall){best_overall=ns;best_lines=lines;}\n            }\n            no_imp=0;\n        }\n    }\n    \n    lines=best_lines;\n    cout<<lines.size()<<\"\\n\";\n    for(auto& l:lines) cout<<l.p1x<<\" \"<<l.p1y<<\" \"<<l.p2x<<\" \"<<l.p2y<<\"\\n\";\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <map>\n#include <numeric>\n#include <algorithm>\n#include <array>\n\nusing namespace std;\n\nint N, M;\nvector<vector<bool>> has_dot;\nvector<array<int,8>> ops;\nmap<int, set<pair<int,int>>> segs[4];\n\nvector<int> dots_y[65];\nvector<int> dots_x[65];\nvector<int> dots_u[130];\nvector<int> dots_v[130];\nvector<int> pt_idx[65];\nvector<pair<int,int>> existing_dots;\n\nset<int> candidates;\nvector<pair<int, pair<int,int>>> empty_pts_vec;\n\nint seg_type(int x1,int y1,int x2,int y2){\n    if(y1==y2)return 0;\n    if(x1==x2)return 1;\n    if(x2-x1==y2-y1)return 2;\n    return 3;\n}\nint line_id(int t,int x,int y){\n    if(t==0)return y;\n    if(t==1)return x;\n    if(t==2)return x-y;\n    return x+y;\n}\nint line_coord(int t,int x,int y){\n    if(t==0||t==2||t==3)return x;\n    return y;\n}\n\nbool check_overlap(int t, int lid, int s, int e) {\n    if (s > e) swap(s, e);\n    auto it = segs[t].find(lid);\n    if (it == segs[t].end()) return false;\n    auto& st = it->second;\n    auto jt = st.upper_bound({s, 1e9});\n    if (jt != st.begin()) {\n        auto kt = prev(jt);\n        if (kt->second > s) return true;\n    }\n    if (jt != st.end()) {\n        if (jt->first < e) return true;\n    }\n    return false;\n}\n\nvoid add_seg(int t, int lid, int s, int e) {\n    if (s > e) swap(s, e);\n    auto& st = segs[t][lid];\n    auto it = st.upper_bound({s, 1e9});\n    if (it != st.begin()) {\n        auto kt = prev(it);\n        if (kt->second >= s) {\n            s = min(s, kt->first);\n            e = max(e, kt->second);\n            st.erase(kt);\n        }\n    }\n    it = st.upper_bound({s, 1e9});\n    while (it != st.end() && it->first <= e) {\n        e = max(e, it->second);\n        it = st.erase(it);\n    }\n    st.insert({s, e});\n}\n\nbool has_perim_overlap(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    int e[4][4]={{x1,y1,x2,y2},{x2,y2,x3,y3},{x3,y3,x4,y4},{x4,y4,x1,y1}};\n    for(int i=0;i<4;i++){\n        int t=seg_type(e[i][0],e[i][1],e[i][2],e[i][3]);\n        int lid=line_id(t,e[i][0],e[i][1]);\n        int s=line_coord(t,e[i][0],e[i][1]);\n        int ee=line_coord(t,e[i][2],e[i][3]);\n        if(check_overlap(t,lid,s,ee))return true;\n    }\n    return false;\n}\n\nvoid add_perim(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){\n    int e[4][4]={{x1,y1,x2,y2},{x2,y2,x3,y3},{x3,y3,x4,y4},{x4,y4,x1,y1}};\n    for(int i=0;i<4;i++){\n        int t=seg_type(e[i][0],e[i][1],e[i][2],e[i][3]);\n        int lid=line_id(t,e[i][0],e[i][1]);\n        int s=line_coord(t,e[i][0],e[i][1]);\n        int ee=line_coord(t,e[i][2],e[i][3]);\n        add_seg(t,lid,s,ee);\n    }\n}\n\nbool valid_rect_axis(int ex, int ey, int x1, int y1) {\n    for (int px = min(ex, x1) + 1; px < max(ex, x1); ++px) {\n        if (has_dot[px][ey]) return false;\n        if (has_dot[px][y1]) return false;\n    }\n    for (int py = min(ey, y1) + 1; py < max(ey, y1); ++py) {\n        if (has_dot[ex][py]) return false;\n        if (has_dot[x1][py]) return false;\n    }\n    if (has_perim_overlap(ex, ey, ex, y1, x1, y1, x1, ey)) return false;\n    return true;\n}\n\nbool valid_rect_45(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {\n    auto chk = [&](int ax, int ay, int bx, int by) {\n        int dx = (bx > ax) ? 1 : -1;\n        int dy = (by > ay) ? 1 : -1;\n        int steps = abs(bx - ax);\n        for (int i = 1; i < steps; ++i) {\n            int px = ax + i * dx;\n            int py = ay + i * dy;\n            if (has_dot[px][py]) return true;\n        }\n        return false;\n    };\n    if (chk(x1, y1, x2, y2) || chk(x2, y2, x3, y3) || chk(x3, y3, x4, y4) || chk(x4, y4, x1, y1)) return false;\n    if (has_perim_overlap(x1, y1, x2, y2, x3, y3, x4, y4)) return false;\n    return true;\n}\n\nvector<int> sorted_by_dist(const vector<int>& v, int center) {\n    vector<int> res = v;\n    sort(res.begin(), res.end(), [&](int a, int b) {\n        return abs(a - center) < abs(b - center);\n    });\n    return res;\n}\n\npair<array<int,8>, int> find_best_rect(int ex, int ey) {\n    int best_cost = 1e9;\n    array<int,8> best_r = {-1};\n    \n    auto ys = sorted_by_dist(dots_x[ex], ey);\n    auto xs = sorted_by_dist(dots_y[ey], ex);\n    \n    for (int y1 : ys) {\n        int cost_y = abs(y1 - ey);\n        if (cost_y >= best_cost) break;\n        for (int x1 : xs) {\n            int cost_x = abs(x1 - ex);\n            int cost = cost_y + cost_x;\n            if (cost >= best_cost) break;\n            if (has_dot[x1][y1]) {\n                if (valid_rect_axis(ex, ey, x1, y1)) {\n                    best_cost = cost;\n                    best_r = {ex, ey, ex, y1, x1, y1, x1, ey};\n                }\n            }\n        }\n    }\n    \n    int eu = ex + ey;\n    int ev = ex - ey;\n    auto vs = sorted_by_dist(dots_u[eu], ev);\n    auto us = sorted_by_dist(dots_v[ev + N], eu);\n    \n    for (int v2 : vs) {\n        if ((eu + v2) % 2 != 0) continue;\n        int xp2 = (eu + v2) / 2;\n        int yp2 = (eu - v2) / 2;\n        if (xp2 < 0 || xp2 >= N || yp2 < 0 || yp2 >= N) continue;\n        int cost_v = abs(v2 - ev);\n        if (cost_v >= best_cost) break;\n        \n        for (int u3 : us) {\n            if ((u3 + ev) % 2 != 0) continue;\n            int xp4 = (u3 + ev) / 2;\n            int yp4 = (u3 - ev) / 2;\n            if (xp4 < 0 || xp4 >= N || yp4 < 0 || yp4 >= N) continue;\n            \n            int xp3 = (u3 + v2) / 2;\n            int yp3 = (u3 - v2) / 2;\n            if (xp3 < 0 || xp3 >= N || yp3 < 0 || yp3 >= N) continue;\n            \n            int cost_u = abs(u3 - eu);\n            int cost = cost_v + cost_u;\n            if (cost >= best_cost) break;\n            \n            if (has_dot[xp3][yp3]) {\n                if (valid_rect_45(ex, ey, xp2, yp2, xp3, yp3, xp4, yp4)) {\n                    best_cost = cost;\n                    best_r = {ex, ey, xp2, yp2, xp3, yp3, xp4, yp4};\n                }\n            }\n        }\n    }\n    \n    return {best_r, best_cost};\n}\n\nvoid add_cand(int x, int y) {\n    if (x >= 0 && x < N && y >= 0 && y < N && !has_dot[x][y]) {\n        int idx = pt_idx[x][y];\n        if (idx != -1) {\n            candidates.insert(idx);\n        }\n    }\n}\n\nvoid add_cand_uv(int u, int v) {\n    if ((u + v) % 2 != 0) return;\n    int x = (u + v) / 2;\n    int y = (u - v) / 2;\n    add_cand(x, y);\n}\n\nvoid add_candidates(int x, int y) {\n    int u = x + y;\n    int v = x - y;\n    \n    for (int ex : dots_y[y]) {\n        for (int ey : dots_x[x]) {\n            add_cand(ex, ey); // Opposite axis-aligned\n        }\n    }\n    for (int ex2 : dots_y[y]) {\n        for (int ey : dots_x[ex2]) {\n            add_cand(x, ey); // Adjacent axis-aligned, share x\n        }\n    }\n    for (int ey2 : dots_x[x]) {\n        for (int ex : dots_y[ey2]) {\n            add_cand(ex, y); // Adjacent axis-aligned, share y\n        }\n    }\n    \n    for (int eu : dots_v[v + N]) {\n        for (int ev : dots_u[u]) {\n            add_cand_uv(eu, ev); // Opposite 45-degree\n        }\n    }\n    for (int eu2 : dots_v[v + N]) {\n        for (int ev : dots_u[eu2]) {\n            add_cand_uv(u, ev); // Adjacent 45-degree, share u\n        }\n    }\n    for (int ev2 : dots_u[u]) {\n        for (int eu : dots_v[ev2 + N]) {\n            add_cand_uv(eu, v); // Adjacent 45-degree, share v\n        }\n    }\n}\n\nint main(){\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    cin >> N >> M;\n    has_dot.assign(N, vector<bool>(N, false));\n    \n    int c = (N - 1) / 2;\n    \n    for(int i=0;i<N;++i) pt_idx[i].resize(N, -1);\n    \n    vector<pair<int,int>> initial_dots(M);\n    for(int i=0;i<M;i++){\n        int x, y;\n        cin >> x >> y;\n        has_dot[x][y] = true;\n        dots_x[x].push_back(y);\n        dots_y[y].push_back(x);\n        int u = x + y;\n        int v = x - y;\n        dots_u[u].push_back(v);\n        dots_v[v + N].push_back(u);\n        initial_dots[i] = {x, y};\n    }\n    \n    for(int x=0;x<N;x++){\n        for(int y=0;y<N;y++){\n            if(!has_dot[x][y]){\n                int w = (x-c)*(x-c) + (y-c)*(y-c) + 1;\n                empty_pts_vec.push_back({-w, {x, y}});\n            }\n        }\n    }\n    \n    sort(empty_pts_vec.begin(), empty_pts_vec.end());\n    \n    for(size_t i=0; i<empty_pts_vec.size(); ++i) {\n        auto [w, p] = empty_pts_vec[i];\n        pt_idx[p.first][p.second] = i;\n    }\n    \n    for(auto [x, y] : initial_dots) {\n        existing_dots.push_back({x, y});\n    }\n    \n    for (auto [x, y] : initial_dots) {\n        add_candidates(x, y);\n    }\n    \n    while (!candidates.empty()) {\n        int best_idx = *candidates.begin();\n        auto [w, p] = empty_pts_vec[best_idx];\n        auto [x, y] = p;\n        \n        auto [r, cost] = find_best_rect(x, y);\n        if (r[0] != -1) {\n            has_dot[x][y] = true;\n            dots_x[x].push_back(y);\n            dots_y[y].push_back(x);\n            int u = x + y;\n            int v = x - y;\n            dots_u[u].push_back(v);\n            dots_v[v + N].push_back(u);\n            existing_dots.push_back({x, y});\n            \n            add_perim(r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7]);\n            ops.push_back(r);\n            candidates.erase(best_idx);\n            pt_idx[x][y] = -1;\n            add_candidates(x, y);\n        } else {\n            candidates.erase(best_idx);\n        }\n    }\n    \n    cout << ops.size() << \"\\n\";\n    for(auto& op : ops){\n        for(int i=0;i<8;i++){\n            cout << op[i] << (i<7?\" \":\"\\n\");\n        }\n    }\n    \n    return 0;\n}","ahc015":"#include <iostream>\n#include <cstring>\n#include <queue>\n#include <algorithm>\n#include <random>\n#include <vector>\n\nusing namespace std;\n\nconst int N = 10;\nint grid[N][N];\nint flavors[101];\nmt19937 rng(42);\n\nvoid applyTilt(int g[N][N], int d) {\n    if (d == 0) { for (int c = 0; c < N; c++) { int w = 0; for (int r = 0; r < N; r++) if (g[r][c]) { if (w != r) { g[w][c] = g[r][c]; g[r][c] = 0; } w++; } } }\n    else if (d == 1) { for (int c = 0; c < N; c++) { int w = N-1; for (int r = N-1; r >= 0; r--) if (g[r][c]) { if (w != r) { g[w][c] = g[r][c]; g[r][c] = 0; } w--; } } }\n    else if (d == 2) { for (int r = 0; r < N; r++) { int w = 0; for (int c = 0; c < N; c++) if (g[r][c]) { if (w != c) { g[r][w] = g[r][c]; g[r][c] = 0; } w++; } } }\n    else { for (int r = 0; r < N; r++) { int w = N-1; for (int c = N-1; c >= 0; c--) if (g[r][c]) { if (w != c) { g[r][w] = g[r][c]; g[r][c] = 0; } w--; } } }\n}\n\nint getScore(int g[N][N]) {\n    bool vis[N][N] = {}; int s = 0;\n    constexpr int dr[] = {-1,1,0,0}, dc[] = {0,0,-1,1};\n    int q[N*N], fr, bk;\n    for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) {\n        if (!vis[r][c] && g[r][c]) {\n            int fl = g[r][c], sz = 0; fr = 0; bk = 0;\n            q[bk++] = r*N+c; vis[r][c] = true;\n            while (fr < bk) { int id = q[fr++], cr = id/N, cc = id%N; sz++;\n                for (int d = 0; d < 4; d++) { 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]==fl) { vis[nr][nc]=true; q[bk++]=nr*N+nc; } } }\n            s += sz*sz;\n        }\n    }\n    return s;\n}\n\nint getAdj(int g[N][N]) {\n    int cnt = 0;\n    for (int r = 0; r < N; r++) for (int c = 0; c < N; c++)\n        if (g[r][c]) { if (r+1<N&&g[r+1][c]==g[r][c]) cnt++; if (c+1<N&&g[r][c+1]==g[r][c]) cnt++; }\n    return cnt;\n}\n\nlong long compute1Ply(int orig[N][N], int turn) {\n    if (turn >= 100) return getScore(orig);\n    int nf = flavors[turn + 1];\n    long long total = 0; int count = 0;\n    int g[N][N]; memcpy(g, orig, sizeof(g));\n    int saved[N][N];\n    for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) {\n        if (g[r][c] == 0) {\n            g[r][c] = nf;\n            int bestS = 0;\n            for (int d = 0; d < 4; d++) {\n                memcpy(saved, g, sizeof(saved));\n                applyTilt(g, d);\n                int s = getScore(g);\n                bestS = max(bestS, s);\n                memcpy(g, saved, sizeof(saved));\n            }\n            total += bestS;\n            g[r][c] = 0;\n            count++;\n        }\n    }\n    return count > 0 ? total / count : getScore(orig);\n}\n\nlong long runMC(int startT, int base[N][N]) {\n    int sim[N][N]; memcpy(sim, base, sizeof(sim));\n    for (int t = startT; t <= 100; t++) {\n        int er[100], ec[100], cnt = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (!sim[r][c]) { er[cnt] = r; ec[cnt] = c; cnt++; }\n        if (!cnt) break;\n        int idx = rng() % cnt;\n        sim[er[idx]][ec[idx]] = flavors[t];\n        int bestS = -1, bestD = 0, sv[N][N];\n        for (int d = 0; d < 4; d++) { memcpy(sv, sim, sizeof(sv)); applyTilt(sim, d); int s = getScore(sim); if (s > bestS) { bestS = s; bestD = d; } memcpy(sim, sv, sizeof(sv)); }\n        applyTilt(sim, bestD);\n    }\n    return getScore(sim);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    for (int i = 1; i <= 100; i++) cin >> flavors[i];\n    memset(grid, 0, sizeof(grid));\n    const char dirChars[] = \"FBLR\";\n    const int dirPrio[] = {4, 1, 2, 3};\n    \n    for (int t = 1; t <= 100; t++) {\n        int p; cin >> p;\n        int pos = 1;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (!grid[r][c]) { if (pos == p) { grid[r][c] = flavors[t]; goto placed; } pos++; }\n        placed:;\n        \n        int scores[4], adjs[4];\n        int saved[N][N]; memcpy(saved, grid, sizeof(grid));\n        for (int d = 0; d < 4; d++) {\n            applyTilt(grid, d);\n            scores[d] = getScore(grid);\n            adjs[d] = getAdj(grid);\n            memcpy(grid, saved, sizeof(grid));\n        }\n        \n        int maxScore = *max_element(scores, scores + 4);\n        vector<int> tied; for (int d = 0; d < 4; d++) if (scores[d] == maxScore) tied.push_back(d);\n        \n        int bestDir;\n        if (tied.size() == 1) {\n            bestDir = tied[0];\n        } else {\n            long long ply1[4] = {};\n            for (int d : tied) {\n                applyTilt(grid, d);\n                ply1[d] = compute1Ply(grid, t);\n                memcpy(grid, saved, sizeof(grid));\n            }\n            long long maxPly = -1; for (int d : tied) maxPly = max(maxPly, ply1[d]);\n            vector<int> tied2; for (int d : tied) if (ply1[d] == maxPly) tied2.push_back(d);\n            \n            if (tied2.size() == 1) {\n                bestDir = tied2[0];\n            } else {\n                int maxAdj = -1; for (int d : tied2) maxAdj = max(maxAdj, adjs[d]);\n                vector<int> tied3; for (int d : tied2) if (adjs[d] == maxAdj) tied3.push_back(d);\n                \n                if (tied3.size() == 1) {\n                    bestDir = tied3[0];\n                } else if (t >= 40) {\n                    int numSims = max(3, min(10, (100 - t) / 5));\n                    long long mcBest = -1; bestDir = tied3[0];\n                    for (int d : tied3) {\n                        int tmp[N][N]; memcpy(tmp, grid, sizeof(grid)); applyTilt(tmp, d);\n                        long long total = 0;\n                        for (int s = 0; s < numSims; s++) total += runMC(t + 1, tmp);\n                        if (total > mcBest) { mcBest = total; bestDir = d; }\n                    }\n                } else {\n                    bestDir = tied3[0];\n                    for (int d : tied3) if (dirPrio[d] < dirPrio[bestDir]) bestDir = d;\n                }\n            }\n        }\n        \n        applyTilt(grid, bestDir);\n        cout << dirChars[bestDir] << '\\n'; cout.flush();\n    }\n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nuint64_t sm64(uint64_t x) {\n    x += 0x9e3779b97f4a7c15ULL;\n    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9ULL;\n    x = (x ^ (x >> 27)) * 0x94d049bb133111ebULL;\n    return x ^ (x >> 31);\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M; double eps;\n    cin >> M >> eps;\n    \n    auto genFp = [&](int N, int code) -> vector<double> {\n        int maxE = N*(N-1)/2;\n        vector<double> ed(N, (N-1.0)*eps);\n        int edges = 0;\n        if (N <= 14) {\n            for(int j=1; j<N; j++){\n                if((code >> (j-1)) & 1){\n                    edges += j;\n                    for(int i=0; i<j; i++) ed[i] += (1.0-2.0*eps);\n                    ed[j] += j*(1.0-2.0*eps);\n                }\n            }\n        } else {\n            uint64_t h1 = sm64(code);\n            uint64_t h2 = sm64(code + 0x9e3779b97f4a7c15ULL);\n            for(int j=1; j<N; j++){\n                bool bj = (j <= 64) ? ((h1 >> (j-1)) & 1) : ((h2 >> (j-65)) & 1);\n                if(bj){\n                    edges += j;\n                    for(int i=0; i<j; i++) ed[i] += (1.0-2.0*eps);\n                    ed[j] += j*(1.0-2.0*eps);\n                }\n            }\n        }\n        sort(ed.begin(), ed.end());\n        vector<double> fp(N+1);\n        fp[0] = edges*(1.0-2.0*eps) + maxE*eps;\n        for(int i=0; i<N; i++) fp[i+1] = ed[i];\n        return fp;\n    };\n    \n    auto distFp = [](const vector<double>& a, const vector<double>& b, double dVE, double dVD, int N) -> double {\n        double d = (a[0]-b[0]); d = d*d/dVE;\n        for(int i=1; i<=N; i++){ double df = a[i]-b[i]; d += df*df/dVD; }\n        return d;\n    };\n    \n    auto evaluateN = [&](int Nt) -> double {\n        double dVD = max(0.001, (Nt-1.0)*eps*(1.0-eps));\n        double dVE = max(0.001, (double)(Nt*(Nt-1)/2)*eps*(1.0-eps));\n        int NCt = (Nt <= 14) ? min(4000, (1 << (Nt-1))) : 4000;\n        if(NCt < M) return -1e18;\n        \n        vector<vector<double>> fps(NCt);\n        for(int c=0; c<NCt; c++) fps[c] = genFp(Nt, c);\n        \n        vector<bool> used(NCt, false);\n        vector<double> minD(NCt, 1e18);\n        used[0] = true;\n        for(int c=1; c<NCt; c++) minD[c] = distFp(fps[c], fps[0], dVE, dVD, Nt);\n        \n        double dMin = 1e18;\n        for(int k=1; k<M; k++){\n            int best = -1; double bestD = -1;\n            for(int c=0; c<NCt; c++) if(!used[c] && minD[c] > bestD){ bestD = minD[c]; best = c; }\n            if(best < 0) return -1e18;\n            used[best] = true; dMin = min(dMin, bestD);\n            for(int c=0; c<NCt; c++){\n                if(used[c]) continue;\n                minD[c] = min(minD[c], distFp(fps[c], fps[best], dVE, dVD, Nt));\n            }\n        }\n        if(dMin <= 0) return -1e18;\n        \n        double pErr = (eps < 0.005) ? 1e-15 : max(1e-15, min(0.5, (M-1.0)*0.5*erfc(sqrt(dMin)/(2.0*sqrt(2.0)))));\n        return pow(0.9, 100.0*pErr) / Nt;\n    };\n    \n    double bestScore = -1e18;\n    int bestN = max(5, (int)ceil(log2(max(M,2))) + 2);\n    \n    for(int n=4; n<=20; n++){ double s=evaluateN(n); if(s>bestScore){bestScore=s;bestN=n;} }\n    for(int n=21; n<=40; n+=2){ double s=evaluateN(n); if(s>bestScore){bestScore=s;bestN=n;} }\n    for(int n=44; n<=70; n+=4){ double s=evaluateN(n); if(s>bestScore){bestScore=s;bestN=n;} }\n    for(int n=75; n<=100; n+=5){ double s=evaluateN(n); if(s>bestScore){bestScore=s;bestN=n;} }\n    for(int n=max(4,bestN-3); n<=min(100,bestN+3); n++){ double s=evaluateN(n); if(s>bestScore){bestScore=s;bestN=n;} }\n    \n    int N = bestN;\n    int maxE = N*(N-1)/2;\n    double dVD = max(0.001, (N-1.0)*eps*(1.0-eps));\n    double dVE = max(0.001, (double)maxE*eps*(1.0-eps));\n    auto eidx = [&](int i, int j)->int{ if(i>j) swap(i,j); return i*(2*N-i-1)/2+(j-i-1); };\n    \n    int NC = (N <= 14) ? (1 << (N-1)) : 15000;\n    vector<vector<double>> cfp(NC);\n    for(int c=0; c<NC; c++) cfp[c] = genFp(N, c);\n    \n    vector<int> sel; vector<double> minD(NC, 1e18); vector<bool> used(NC, false);\n    sel.push_back(0); used[0] = true;\n    for(int c=1; c<NC; c++) minD[c] = distFp(cfp[c], cfp[0], dVE, dVD, N);\n    for(int k=1; k<M; k++){\n        int best=-1; double bestD=-1;\n        for(int c=0; c<NC; c++) if(!used[c] && minD[c]>bestD){bestD=minD[c];best=c;}\n        if(best<0) break;\n        sel.push_back(best); used[best]=true;\n        for(int c=0; c<NC; c++){ if(used[c]) continue; minD[c]=min(minD[c], distFp(cfp[c], cfp[best], dVE, dVD, N)); }\n    }\n    while((int)sel.size() < M) sel.push_back(0);\n    \n    cout << N << \"\\n\";\n    for(int k=0; k<M; k++){\n        int c = sel[k]; string g(maxE, '0');\n        if(N <= 14){\n            for(int j=1; j<N; j++){\n                if((c >> (j-1)) & 1) for(int i=0; i<j; i++) g[eidx(i,j)] = '1';\n            }\n        } else {\n            uint64_t h1 = sm64(c), h2 = sm64(c + 0x9e3779b97f4a7c15ULL);\n            for(int j=1; j<N; j++){\n                bool bj = (j <= 64) ? ((h1 >> (j-1)) & 1) : ((h2 >> (j-65)) & 1);\n                if(bj) for(int i=0; i<j; i++) g[eidx(i,j)] = '1';\n            }\n        }\n        cout << g << \"\\n\";\n    }\n    cout.flush();\n    \n    vector<vector<double>> gefp(M, vector<double>(N+1));\n    for(int k=0; k<M; k++) gefp[k] = cfp[sel[k]];\n    \n    for(int q=0; q<100; q++){\n        string H; cin >> H;\n        int hE = count(H.begin(), H.end(), '1');\n        vector<int> hd(N, 0);\n        for(int i=0; i<N; i++) for(int j=i+1; j<N; j++) if(H[eidx(i,j)]=='1'){hd[i]++;hd[j]++;}\n        sort(hd.begin(), hd.end());\n        int bestK=0; double bestDist=1e18;\n        for(int k=0; k<M; k++){\n            double dist = (double)(hE-gefp[k][0]); dist=dist*dist/dVE;\n            for(int i=1; i<=N; i++){ double diff=hd[i-1]-gefp[k][i]; dist+=diff*diff/dVD; }\n            if(dist<bestDist){bestDist=dist;bestK=k;}\n        }\n        cout << bestK << \"\\n\"; cout.flush();\n    }\n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\ntypedef long long ll;\ntypedef pair<ll,int> pli;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N,M,D,K; cin>>N>>M>>D>>K;\n    vector<int> u(M),v(M),w(M);\n    vector<vector<pair<int,int>>> adj(N);\n    for(int i=0;i<M;i++){cin>>u[i]>>v[i]>>w[i];u[i]--;v[i]--;adj[u[i]].push_back({i,v[i]});adj[v[i]].push_back({i,u[i]});}\n    vector<int> x(N),y(N);\n    for(int i=0;i<N;i++) cin>>x[i]>>y[i];\n\n    int S=min(N,100);\n    vector<double> betw(M,0);\n    for(int si=0;si<S;si++){\n        int s=(ll)si*N/S;\n        vector<ll> dist(N,LLONG_MAX);vector<int> pe(N,-1);\n        dist[s]=0;priority_queue<pli,vector<pli>,greater<pli>> pq;pq.push({0,s});\n        while(!pq.empty()){auto[d,nd]=pq.top();pq.pop();if(d>dist[nd])continue;for(auto[ei,nx]:adj[nd]){ll nd2=d+w[ei];if(nd2<dist[nx]){dist[nx]=nd2;pe[nx]=ei;pq.push({nd2,nx});}}}\n        vector<int> ss(N,1);vector<vector<int>> ch(N);\n        for(int t=0;t<N;t++){if(t==s||pe[t]==-1)continue;int o=(u[pe[t]]==t)?v[pe[t]]:u[pe[t]];ch[o].push_back(t);}\n        vector<int> ord={s};for(int i=0;i<(int)ord.size();i++)for(int c:ch[ord[i]])ord.push_back(c);\n        for(int i=(int)ord.size()-1;i>0;i--){int nd=ord[i];int o=(u[pe[nd]]==nd)?v[pe[nd]]:u[pe[nd]];ss[o]+=ss[nd];}\n        for(int t=0;t<N;t++){if(t==s||pe[t]==-1)continue;betw[pe[t]]+=ss[t];}\n    }\n\n    vector<vector<ll>> apsp(N,vector<ll>(N,LLONG_MAX));\n    for(int s=0;s<N;s++){apsp[s][s]=0;priority_queue<pli,vector<pli>,greater<pli>> pq;pq.push({0,s});\n    while(!pq.empty()){auto[d,nd]=pq.top();pq.pop();if(d>apsp[s][nd])continue;for(auto[ei,nx]:adj[nd]){ll nd2=d+w[ei];if(nd2<apsp[s][nx]){apsp[s][nx]=nd2;pq.push({nd2,nx});}}}}\n\n    vector<ll> det(M,0);\n    for(int ei=0;ei<M;ei++){ll best=LLONG_MAX;for(auto[ej,an]:adj[u[ei]]){if(ej==ei)continue;if(apsp[an][v[ei]]<LLONG_MAX)best=min(best,(ll)w[ej]+apsp[an][v[ei]]);}for(auto[ej,bn]:adj[v[ei]]){if(ej==ei)continue;if(apsp[bn][u[ei]]<LLONG_MAX)best=min(best,(ll)w[ej]+apsp[bn][u[ei]]);}if(best<LLONG_MAX)det[ei]=max(0LL,best-apsp[u[ei]][v[ei]]);}\n\n    vector<double> impact(M);\n    for(int i=0;i<M;i++) impact[i]=betw[i]*(double)det[i];\n\n    vector<vector<int>> conflicts(M);\n    vector<ll> dist(N);vector<int> pe(N);\n    for(int ei=0;ei<M;ei++){\n        fill(dist.begin(),dist.end(),LLONG_MAX);fill(pe.begin(),pe.end(),-1);\n        dist[u[ei]]=0;priority_queue<pli,vector<pli>,greater<pli>> pq;pq.push({0,u[ei]});\n        while(!pq.empty()){auto[d,nd]=pq.top();pq.pop();if(d>dist[nd])continue;for(auto[ej,nx]:adj[nd]){if(ej==ei)continue;ll nd2=d+w[ej];if(nd2<dist[nx]){dist[nx]=nd2;pe[nx]=ej;pq.push({nd2,nx});}}}\n        if(dist[v[ei]]<LLONG_MAX){int cur=v[ei];while(cur!=u[ei]&&pe[cur]!=-1){int e=pe[cur];conflicts[ei].push_back(e);int other=(u[e]==cur)?v[e]:u[e];cur=other;}}\n    }\n    for(int ei=0;ei<M;ei++)for(int ej:conflicts[ei])conflicts[ej].push_back(ei);\n    for(int i=0;i<N;i++)for(int j=0;j<(int)adj[i].size();j++)for(int k=j+1;k<(int)adj[i].size();k++){int ej=adj[i][j].first,ek=adj[i][k].first;conflicts[ej].push_back(ek);conflicts[ek].push_back(ej);}\n    for(int i=0;i<M;i++){sort(conflicts[i].begin(),conflicts[i].end());conflicts[i].erase(unique(conflicts[i].begin(),conflicts[i].end()),conflicts[i].end());}\n\n    vector<int> order(M);iota(order.begin(),order.end(),0);\n    sort(order.begin(),order.end(),[&](int a,int b){return impact[a]>impact[b];});\n\n    vector<int> r(M,-1),dc(D,0);vector<double> day_imp(D,0);\n    for(int ei:order){\n        double bs=1e18;int bd=-1;\n        for(int d=0;d<D;d++){if(dc[d]>=K)continue;double sc=0;for(int ej:conflicts[ei])if(r[ej]==d)sc+=impact[ei]*impact[ej];sc+=day_imp[d]*1e-4;if(sc<bs){bs=sc;bd=d;}}\n        if(bd==-1)for(int d=0;d<D;d++)if(dc[d]<K&&(bd==-1||dc[d]<dc[bd]))bd=d;\n        r[ei]=bd;dc[bd]++;day_imp[bd]+=impact[ei];\n    }\n\n    auto t0=chrono::high_resolution_clock::now();mt19937 rng(42);\n    while(true){auto now=chrono::high_resolution_clock::now();if(chrono::duration<double>(now-t0).count()>5.0)break;\n    int ei=rng()%M;int od=r[ei];double cs=0;for(int ej:conflicts[ei])if(r[ej]==od)cs+=impact[ei]*impact[ej];\n    int bd=-1;double bi=0;for(int d=0;d<D;d++){if(d==od||dc[d]>=K)continue;double ns=0;for(int ej:conflicts[ei])if(r[ej]==d)ns+=impact[ei]*impact[ej];double imp=cs-ns+((day_imp[od]-impact[ei])-(day_imp[d]+impact[ei]))*1e-4;if(imp>bi){bi=imp;bd=d;}}\n    if(bd!=-1){r[ei]=bd;dc[od]--;dc[bd]++;day_imp[od]-=impact[ei];day_imp[bd]+=impact[ei];}}\n\n    for(int i=0;i<M;i++)cout<<r[i]+1<<\" \\n\"[i==M-1];\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <tuple>\n#include <climits>\n#include <chrono>\n#include <set>\n#include <map>\nusing namespace std;\nint D;\nusing Point=tuple<int,int,int>;\nusing Array3D=vector<vector<vector<int>>>;\n\nchrono::high_resolution_clock::time_point start_time;\n\nvector<string> readSil(){vector<string>s(D);for(int i=0;i<D;i++)cin>>s[i];return s;}\nArray3D buildMF(const vector<string>&f,const vector<string>&r){Array3D b(D,vector<vector<int>>(D,vector<int>(D,0)));for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++)if(f[z][x]=='1'&&r[z][y]=='1')b[x][y][z]=1;return b;}\n\nvector<vector<Point>> findComp(const Array3D&b){\n    Array3D vis(D,vector<vector<int>>(D,vector<int>(D,0)));vector<vector<Point>>cs;\n    const int dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};\n    for(int x=0;x<D;x++)for(int y=0;y<D;y++)for(int z=0;z<D;z++){\n        if(b[x][y][z]&&!vis[x][y][z]){vector<Point>c;queue<Point>q;q.push({x,y,z});vis[x][y][z]=1;\n            while(!q.empty()){auto[cx,cy,cz]=q.front();q.pop();c.push_back({cx,cy,cz});\n                for(int d=0;d<6;d++){int nx=cx+dx[d],ny=cy+dy[d],nz=cz+dz[d];\n                    if(0<=nx&&nx<D&&0<=ny&&ny<D&&0<=nz&&nz<D&&b[nx][ny][nz]&&!vis[nx][ny][nz]){vis[nx][ny][nz]=1;q.push({nx,ny,nz});}}}\n            cs.push_back(move(c));}}\n    return cs;\n}\n\nvector<vector<Point>> findSubComp(const vector<Point>& vox){\n    Array3D vs(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    Array3D vis(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for(auto& [x,y,z] : vox) vs[x][y][z] = 1;\n    vector<vector<Point>> cs;\n    const int dx[]={1,-1,0,0,0,0},dy[]={0,0,1,-1,0,0},dz[]={0,0,0,0,1,-1};\n    for(auto& [x,y,z] : vox){\n        if(vis[x][y][z]) continue;\n        vector<Point> c; queue<Point> q; q.push({x,y,z}); vis[x][y][z] = 1;\n        while(!q.empty()){\n            auto [cx,cy,cz] = q.front(); q.pop(); c.push_back({cx,cy,cz});\n            for(int d=0;d<6;d++){\n                int nx=cx+dx[d], ny=cy+dy[d], nz=cz+dz[d];\n                if(0<=nx&&nx<D&&0<=ny&&ny<D&&0<=nz&&nz<D&&vs[nx][ny][nz]&&!vis[nx][ny][nz]){\n                    vis[nx][ny][nz]=1; q.push({nx,ny,nz});\n                }\n            }\n        }\n        cs.push_back(move(c));\n    }\n    return cs;\n}\n\nvector<vector<vector<int>>> genRots(){\n    vector<vector<vector<int>>>rots;int B[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};\n    for(int i=0;i<6;i++)for(int j=0;j<6;j++){if(i/2==j/2)continue;int cr[3];\n        cr[0]=B[i][1]*B[j][2]-B[i][2]*B[j][1];cr[1]=B[i][2]*B[j][0]-B[i][0]*B[j][2];cr[2]=B[i][0]*B[j][1]-B[i][1]*B[j][0];\n        int dt=B[i][0]*(B[j][1]*cr[2]-B[j][2]*cr[1])-B[i][1]*(B[j][0]*cr[2]-B[j][2]*cr[0])+B[i][2]*(B[j][0]*cr[1]-B[j][1]*cr[0]);\n        if(dt!=1)continue;rots.push_back({{B[i][0],B[i][1],B[i][2]},{B[j][0],B[j][1],B[j][2]},{cr[0],cr[1],cr[2]}});}\n    return rots;\n}\n\nPoint appR(const vector<vector<int>>&M,const Point&p){auto[x,y,z]=p;return{M[0][0]*x+M[0][1]*y+M[0][2]*z,M[1][0]*x+M[1][1]*y+M[1][2]*z,M[2][0]*x+M[2][1]*y+M[2][2]*z};}\n\nvector<Point>canon(const vector<Point>&comp,const vector<vector<vector<int>>>&rots){vector<Point>best;for(auto&M:rots){vector<Point>r;for(auto&p:comp)r.push_back(appR(M,p));int mX=INT_MAX,mY=INT_MAX,mZ=INT_MAX;for(auto&[x,y,z]:r){mX=min(mX,x);mY=min(mY,y);mZ=min(mZ,z);}for(auto&[x,y,z]:r){x-=mX;y-=mY;z-=mZ;}sort(r.begin(),r.end());if(best.empty()||r<best)best=r;}return best;}\n\nvoid doExactMatch(Array3D& a0, Array3D& a1, const Array3D& b0, const Array3D& b1, const vector<vector<vector<int>>>& rots, int& nextId) {\n    Array3D U0(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    Array3D U1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (b0[x][y][z] && !a0[x][y][z]) U0[x][y][z] = 1;\n        if (b1[x][y][z] && !a1[x][y][z]) U1[x][y][z] = 1;\n    }\n    auto c0 = findComp(U0), c1 = findComp(U1);\n    int n0 = c0.size(), n1 = c1.size();\n    map<vector<Point>, vector<int>> cm1;\n    for (int j=0; j<n1; j++) cm1[canon(c1[j], rots)].push_back(j);\n    \n    vector<int> o0(n0); for (int i=0; i<n0; i++) o0[i] = i;\n    sort(o0.begin(), o0.end(), [&](int a, int b){return c0[a].size() > c0[b].size();});\n    \n    vector<bool> u1(n1, false);\n    for (int i : o0) {\n        auto cn = canon(c0[i], rots);\n        auto it = cm1.find(cn);\n        if (it != cm1.end()) for (int j : it->second) if (!u1[j]) {\n            int id = nextId++;\n            for (auto [x,y,z] : c0[i]) a0[x][y][z] = id;\n            for (auto [x,y,z] : c1[j]) a1[x][y][z] = id;\n            u1[j] = true; break;\n        }\n    }\n}\n\nbool doOneGlobalPartial(Array3D& a0, Array3D& a1, const Array3D& b0, const Array3D& b1, const vector<vector<vector<int>>>& rots, int& nextId) {\n    Array3D U0(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    Array3D U1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<Point> P1;\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (b0[x][y][z] && !a0[x][y][z]) U0[x][y][z] = 1;\n        if (b1[x][y][z] && !a1[x][y][z]) { U1[x][y][z] = 1; P1.push_back({x,y,z}); }\n    }\n    if (P1.empty()) return false;\n    \n    auto comps0 = findComp(U0);\n    if (comps0.empty()) return false;\n    sort(comps0.begin(), comps0.end(), [](auto& a, auto& b){return a.size() > b.size();});\n    \n    int bestO = 1, bestRi = -1, bestTx = 0, bestTy = 0, bestTz = 0;\n    int bestCompIdx = -1;\n    vector<vector<Point>> rotsComp(comps0.size());\n    \n    const int OFF = 30, S = 61;\n    vector<int> tc(S*S*S, 0);\n    \n    for (int c_idx = 0; c_idx < (int)comps0.size(); c_idx++) {\n        auto& comp = comps0[c_idx];\n        if (comp.size() <= bestO) break;\n        \n        for (int ri = 0; ri < 24; ri++) {\n            vector<Point> rot;\n            for (auto& p : comp) rot.push_back(appR(rots[ri], p));\n            int mX=INT_MAX, mY=INT_MAX, mZ=INT_MAX;\n            for (auto& [x,y,z] : rot) { mX=min(mX,x); mY=min(mY,y); mZ=min(mZ,z); }\n            for (auto& [x,y,z] : rot) { x-=mX; y-=mY; z-=mZ; }\n            \n            fill(tc.begin(), tc.end(), 0);\n            int local_max = 0, local_tx = 0, local_ty = 0, local_tz = 0;\n            for (auto& [sx,sy,sz] : rot) \n                for (auto& [px,py,pz] : P1) {\n                    int kx = px-sx + OFF, ky = py-sy + OFF, kz = pz-sz + OFF;\n                    int idx = kx + ky*S + kz*S*S;\n                    tc[idx]++;\n                    if (tc[idx] > local_max) {\n                        local_max = tc[idx]; local_tx = kx - OFF; local_ty = ky - OFF; local_tz = kz - OFF;\n                    }\n                }\n            if (local_max > bestO) {\n                bestO = local_max; bestRi = ri;\n                bestTx = local_tx; bestTy = local_ty; bestTz = local_tz;\n                bestCompIdx = c_idx;\n                rotsComp[c_idx] = rot;\n                if (bestO == comp.size()) break;\n            }\n        }\n    }\n    \n    if (bestCompIdx != -1) {\n        auto& comp = comps0[bestCompIdx];\n        auto& rot = rotsComp[bestCompIdx];\n        \n        vector<Point> so, to;\n        for (int i=0; i<(int)comp.size(); i++) {\n            auto [rx,ry,rz] = rot[i];\n            int tx=rx+bestTx, ty=ry+bestTy, tz=rz+bestTz;\n            if (0<=tx&&tx<D && 0<=ty&&ty<D && 0<=tz&&tz<D && U1[tx][ty][tz]) {\n                so.push_back(comp[i]); to.push_back({tx,ty,tz});\n            }\n        }\n        auto scs = findSubComp(so);\n        int best_sc_idx = -1;\n        for (int i = 0; i < (int)scs.size(); i++) {\n            if (scs[i].size() >= 2) {\n                if (best_sc_idx == -1 || scs[i].size() > scs[best_sc_idx].size()) {\n                    best_sc_idx = i;\n                }\n            }\n        }\n        \n        if (best_sc_idx != -1) {\n            map<Point, int> s2i; for (int i=0; i<(int)so.size(); i++) s2i[so[i]] = i;\n            int id = nextId++;\n            for (auto& p : scs[best_sc_idx]) {\n                int i = s2i[p];\n                auto [sx,sy,sz] = so[i]; auto [tx,ty,tz] = to[i];\n                a0[sx][sy][sz] = id; a1[tx][ty][tz] = id;\n            }\n            return true;\n        }\n    }\n    return false;\n}\n\nvoid doSimpleIntersection(Array3D& a0, Array3D& a1, const Array3D& b0, const Array3D& b1, int& nextId) {\n    Array3D U0(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    Array3D U1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (b0[x][y][z] && !a0[x][y][z]) U0[x][y][z] = 1;\n        if (b1[x][y][z] && !a1[x][y][z]) U1[x][y][z] = 1;\n    }\n    Array3D isct(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++)\n        if(U0[x][y][z] && U1[x][y][z]) isct[x][y][z] = 1;\n    for (auto& c : findComp(isct)) {\n        int id = nextId++;\n        for (auto [x,y,z] : c) { a0[x][y][z] = id; a1[x][y][z] = id; U0[x][y][z] = 0; U1[x][y][z] = 0; }\n    }\n}\n\nint main(){\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    start_time = chrono::high_resolution_clock::now();\n    cin >> D;\n    vector<vector<string>> f(2), r(2);\n    for (int i = 0; i < 2; i++) { f[i] = readSil(); r[i] = readSil(); }\n    \n    auto rots = genRots();\n    auto b0 = buildMF(f[0], r[0]), b1 = buildMF(f[1], r[1]);\n    Array3D a0(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    Array3D a1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    int nid = 1;\n    \n    doExactMatch(a0, a1, b0, b1, rots, nid);\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start_time).count() < 4500) {\n        bool changed = doOneGlobalPartial(a0, a1, b0, b1, rots, nid);\n        if (changed) { doExactMatch(a0, a1, b0, b1, rots, nid); continue; }\n        changed = doOneGlobalPartial(a1, a0, b1, b0, rots, nid);\n        if (changed) { doExactMatch(a0, a1, b0, b1, rots, nid); continue; }\n        break;\n    }\n    doSimpleIntersection(a0, a1, b0, b1, nid);\n    doExactMatch(a0, a1, b0, b1, rots, nid);\n    \n    Array3D U0(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    Array3D U1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (b0[x][y][z] && !a0[x][y][z]) U0[x][y][z] = 1;\n        if (b1[x][y][z] && !a1[x][y][z]) U1[x][y][z] = 1;\n    }\n    for (auto& c : findComp(U0)) { int id = nid++; for (auto [x,y,z] : c) a0[x][y][z] = id; }\n    for (auto& c : findComp(U1)) { int id = nid++; for (auto [x,y,z] : c) a1[x][y][z] = id; }\n    \n    map<int, int> id_remap;\n    int next_remap_id = 1;\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (a0[x][y][z] && !id_remap.count(a0[x][y][z])) id_remap[a0[x][y][z]] = next_remap_id++;\n    }\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (a1[x][y][z] && !id_remap.count(a1[x][y][z])) id_remap[a1[x][y][z]] = next_remap_id++;\n    }\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) {\n        if (a0[x][y][z]) a0[x][y][z] = id_remap[a0[x][y][z]];\n        if (a1[x][y][z]) a1[x][y][z] = id_remap[a1[x][y][z]];\n    }\n    \n    cout << next_remap_id - 1 << \"\\n\";\n    for(int x=0;x<D;x++) for(int y=0;y<D;y++) for(int z=0;z<D;z++) { if(x||y||z) cout<<\" \"; cout<<a0[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++) { if(x||y||z) cout<<\" \"; cout<<a1[x][y][z]; }\n    cout << \"\\n\";\n    return 0;\n}","ahc020":"#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, K;\n    cin >> N >> M >> K;\n    \n    vector<int> x(N), y(N);\n    for (int i = 0; i < N; i++) cin >> x[i] >> y[i];\n    \n    vector<vector<pair<int, int>>> adj(N);\n    vector<int> eu(M), ev(M), ew(M);\n    for (int j = 0; j < M; j++) {\n        cin >> eu[j] >> ev[j] >> ew[j];\n        eu[j]--; ev[j]--;\n        adj[eu[j]].push_back({ev[j], j});\n        adj[ev[j]].push_back({eu[j], j});\n    }\n    \n    vector<int> a(K), b(K);\n    for (int k = 0; k < K; k++) cin >> a[k] >> b[k];\n    \n    const int PMAX = 5000;\n    const long long PMAXSQ = (long long)PMAX * PMAX;\n    \n    vector<vector<long long>> rsq(K, vector<long long>(N));\n    for (int k = 0; k < K; k++)\n        for (int i = 0; i < N; i++) {\n            long long dx = a[k] - x[i], dy = b[k] - y[i];\n            rsq[k][i] = dx * dx + dy * dy;\n        }\n    \n    vector<vector<int>> clo(K);\n    for (int k = 0; k < K; k++) {\n        vector<pair<long long, int>> v;\n        for (int i = 0; i < N; i++)\n            if (rsq[k][i] <= PMAXSQ) v.push_back({rsq[k][i], i});\n        sort(v.begin(), v.end());\n        int cnt = min(30, (int)v.size());\n        clo[k].resize(cnt);\n        for (int j = 0; j < cnt; j++) clo[k][j] = v[j].second;\n    }\n    \n    vector<long long> sp(N, LLONG_MAX);\n    vector<int> par(N, -1), pe(N, -1);\n    sp[0] = 0;\n    priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n    pq.push({0, 0});\n    while (!pq.empty()) {\n        auto [d, u] = pq.top(); pq.pop();\n        if (d > sp[u]) continue;\n        for (auto [v, e] : adj[u])\n            if (sp[u] + ew[e] < sp[v]) {\n                sp[v] = sp[u] + ew[e]; par[v] = u; pe[v] = e;\n                pq.push({sp[v], v});\n            }\n    }\n    \n    vector<vector<int>> pth(N);\n    for (int i = 1; i < N; i++) {\n        int c = i;\n        while (c) { pth[i].push_back(pe[c]); c = par[c]; }\n    }\n    \n    auto calcP = [](long long sq) -> int {\n        if (sq <= 0) return 0;\n        int p = max(1, (int)ceil(sqrt((double)sq) - 1e-9));\n        while ((long long)p * p < sq) p++;\n        return min(p, 5000);\n    };\n    \n    auto compute_sph = [&](const vector<int>& P_arr) -> pair<long long, vector<int>> {\n        vector<int> act;\n        for (int i = 0; i < N; i++) if (P_arr[i] > 0) act.push_back(i);\n        if (act.empty()) return {0, vector<int>(M, 0)};\n        vector<int> B(M, 0);\n        vector<bool> in_tree(N, false);\n        in_tree[0] = true;\n        set<int> rem(act.begin(), act.end());\n        rem.erase(0);\n        long long ec = 0;\n        while (!rem.empty()) {\n            vector<long long> d(N, LLONG_MAX);\n            vector<int> prev(N, -1), preve(N, -1);\n            priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq2;\n            for (int v = 0; v < N; v++) if (in_tree[v]) { d[v] = 0; pq2.push({0, v}); }\n            while (!pq2.empty()) {\n                auto [dd, u] = pq2.top(); pq2.pop();\n                if (dd > d[u]) continue;\n                for (auto [v, e] : adj[u])\n                    if (d[u] + ew[e] < d[v]) {\n                        d[v] = d[u] + ew[e]; prev[v] = u; preve[v] = e;\n                        pq2.push({d[v], v});\n                    }\n            }\n            long long bd = LLONG_MAX; int bt = -1;\n            for (int t : rem) if (d[t] < bd) { bd = d[t]; bt = t; }\n            int v = bt;\n            while (v != -1 && !in_tree[v]) { B[preve[v]] = 1; in_tree[v] = true; v = prev[v]; }\n            ec += bd; rem.erase(bt);\n        }\n        return {ec, B};\n    };\n    \n    vector<int> asgn(K);\n    vector<vector<int>> vr(N);\n    vector<int> pos_in_vr(K);\n    vector<long long> vmx(N, 0);\n    \n    for (int k = 0; k < K; k++) {\n        asgn[k] = clo[k][0];\n        pos_in_vr[k] = vr[asgn[k]].size();\n        vr[asgn[k]].push_back(k);\n        vmx[asgn[k]] = max(vmx[asgn[k]], rsq[k][asgn[k]]);\n    }\n    \n    vector<int> P(N);\n    long long pcost = 0;\n    for (int i = 0; i < N; i++) { P[i] = calcP(vmx[i]); pcost += (long long)P[i] * P[i]; }\n    \n    vector<int> eref(M, 0);\n    long long ecost = 0;\n    for (int i = 1; i < N; i++)\n        if (P[i] > 0)\n            for (int e : pth[i]) { if (!eref[e]) ecost += ew[e]; eref[e]++; }\n    \n    long long cost = pcost + ecost;\n    vector<int> best_asgn = asgn;\n    long long best_cost = cost;\n    \n    mt19937 rng(42);\n    uniform_real_distribution<> unif(0.0, 1.0);\n    auto t0 = chrono::high_resolution_clock::now();\n    \n    while (true) {\n        double el = chrono::duration<double>(chrono::high_resolution_clock::now() - t0).count();\n        if (el > 1.4) break;\n        double temp = 5e6 * pow(0.01, el / 1.4);\n        \n        int k = rng() % K;\n        int ov = asgn[k];\n        int nv = clo[k][rng() % clo[k].size()];\n        if (nv == ov) continue;\n        \n        long long nmx_ov = vmx[ov];\n        if (rsq[k][ov] == vmx[ov]) {\n            nmx_ov = 0;\n            for (int r : vr[ov]) if (r != k) nmx_ov = max(nmx_ov, rsq[r][ov]);\n        }\n        int nPov = calcP(nmx_ov);\n        long long nmx_nv = max(vmx[nv], rsq[k][nv]);\n        int nPnv = calcP(nmx_nv);\n        \n        long long dpc = (long long)nPov*nPov - (long long)P[ov]*P[ov]\n                      + (long long)nPnv*nPnv - (long long)P[nv]*P[nv];\n        \n        long long dec = 0;\n        if (P[ov] > 0 && nPov == 0)\n            for (int e : pth[ov]) { eref[e]--; if (!eref[e]) dec -= ew[e]; }\n        if (P[nv] == 0 && nPnv > 0)\n            for (int e : pth[nv]) { if (!eref[e]) dec += ew[e]; eref[e]++; }\n        \n        long long nc = cost + dpc + dec;\n        if (nc < cost || unif(rng) < exp(-(double)(nc - cost) / temp)) {\n            int pk = pos_in_vr[k];\n            if (pk < (int)vr[ov].size() - 1) {\n                int last = vr[ov].back();\n                vr[ov][pk] = last; pos_in_vr[last] = pk;\n            }\n            vr[ov].pop_back();\n            pos_in_vr[k] = vr[nv].size();\n            vr[nv].push_back(k);\n            vmx[ov] = nmx_ov; vmx[nv] = nmx_nv;\n            P[ov] = nPov; P[nv] = nPnv;\n            pcost += dpc; ecost += dec; asgn[k] = nv; cost = nc;\n            if (cost < best_cost) { best_cost = cost; best_asgn = asgn; }\n        } else {\n            if (P[nv] == 0 && nPnv > 0) for (int e : pth[nv]) eref[e]--;\n            if (P[ov] > 0 && nPov == 0) for (int e : pth[ov]) eref[e]++;\n        }\n    }\n    \n    // Restore best state\n    asgn = best_asgn;\n    for (int i = 0; i < N; i++) vr[i].clear();\n    fill(vmx.begin(), vmx.end(), 0);\n    for (int k = 0; k < K; k++) {\n        pos_in_vr[k] = vr[asgn[k]].size();\n        vr[asgn[k]].push_back(k);\n        vmx[asgn[k]] = max(vmx[asgn[k]], rsq[k][asgn[k]]);\n    }\n    for (int i = 0; i < N; i++) P[i] = calcP(vmx[i]);\n    pcost = 0;\n    for (int i = 0; i < N; i++) pcost += (long long)P[i]*P[i];\n    \n    // Greedy power optimization (no deactivation) BEFORE deactivation\n    {\n        bool gimproved = true;\n        while (gimproved) {\n            gimproved = false;\n            for (int k = 0; k < K; k++) {\n                int ov = asgn[k];\n                if (P[ov] == 0) continue;\n                long long best_saving = 0; int best_nv = -1;\n                for (int nv : clo[k]) {\n                    if (nv == ov || P[nv] == 0) continue;\n                    long long nmx_ov2 = vmx[ov];\n                    if (rsq[k][ov] == vmx[ov]) {\n                        nmx_ov2 = 0;\n                        for (int r : vr[ov]) if (r != k) nmx_ov2 = max(nmx_ov2, rsq[r][ov]);\n                    }\n                    int nPov2 = calcP(nmx_ov2);\n                    if (nPov2 == 0) continue;\n                    long long nmx_nv2 = max(vmx[nv], rsq[k][nv]);\n                    int nPnv2 = calcP(nmx_nv2);\n                    long long old_c = (long long)P[ov]*P[ov] + (long long)P[nv]*P[nv];\n                    long long new_c = (long long)nPov2*nPov2 + (long long)nPnv2*nPnv2;\n                    if (new_c < old_c && old_c - new_c > best_saving) {\n                        best_saving = old_c - new_c; best_nv = nv;\n                    }\n                }\n                if (best_nv != -1) {\n                    int pk = pos_in_vr[k];\n                    if (pk < (int)vr[ov].size() - 1) {\n                        int last = vr[ov].back();\n                        vr[ov][pk] = last; pos_in_vr[last] = pk;\n                    }\n                    vr[ov].pop_back();\n                    pos_in_vr[k] = vr[best_nv].size();\n                    vr[best_nv].push_back(k);\n                    if (rsq[k][ov] == vmx[ov]) {\n                        vmx[ov] = 0;\n                        for (int r : vr[ov]) vmx[ov] = max(vmx[ov], rsq[r][ov]);\n                    }\n                    P[ov] = calcP(vmx[ov]);\n                    vmx[best_nv] = max(vmx[best_nv], rsq[k][best_nv]);\n                    P[best_nv] = calcP(vmx[best_nv]);\n                    asgn[k] = best_nv; gimproved = true;\n                }\n            }\n        }\n        pcost = 0;\n        for (int i = 0; i < N; i++) pcost += (long long)P[i]*P[i];\n    }\n    \n    // SPH vertex deactivation (ordered by sp[v] descending)\n    auto [sph_ec, sph_B] = compute_sph(P);\n    long long cur_total = pcost + sph_ec;\n    \n    vector<int> deact_order;\n    for (int v = 1; v < N; v++) if (P[v] > 0) deact_order.push_back(v);\n    sort(deact_order.begin(), deact_order.end(), [&](int a, int b) { return sp[a] > sp[b]; });\n    \n    for (int pass = 0; pass < 5; pass++) {\n        bool improved = false;\n        for (int v : deact_order) {\n            if (P[v] == 0 || vr[v].empty()) continue;\n            vector<pair<int, int>> reassigns;\n            bool feasible = true;\n            for (int k : vr[v]) {\n                long long best_inc = LLONG_MAX; int best_nv = -1;\n                for (int nv : clo[k]) if (nv != v && P[nv] > 0) {\n                    long long nmx = max(vmx[nv], rsq[k][nv]);\n                    int nPnv = calcP(nmx);\n                    long long inc = (long long)nPnv*nPnv - (long long)P[nv]*P[nv];\n                    if (inc < best_inc) { best_inc = inc; best_nv = nv; }\n                }\n                if (best_nv == -1) { feasible = false; break; }\n                reassigns.push_back({k, best_nv});\n            }\n            if (!feasible) continue;\n            vector<long long> nvmx = vmx; nvmx[v] = 0;\n            for (auto& [k, nv] : reassigns) nvmx[nv] = max(nvmx[nv], rsq[k][nv]);\n            vector<int> nP(N); long long npc = 0;\n            for (int i = 0; i < N; i++) { nP[i] = calcP(nvmx[i]); npc += (long long)nP[i]*nP[i]; }\n            auto [nec, nB] = compute_sph(nP);\n            if (npc + nec < cur_total) {\n                for (auto& [k, nv] : reassigns) {\n                    int pk = pos_in_vr[k];\n                    if (pk < (int)vr[asgn[k]].size() - 1) {\n                        int last = vr[asgn[k]].back();\n                        vr[asgn[k]][pk] = last; pos_in_vr[last] = pk;\n                    }\n                    vr[asgn[k]].pop_back();\n                    asgn[k] = nv; pos_in_vr[k] = vr[nv].size(); vr[nv].push_back(k);\n                }\n                vr[v].clear(); P = nP; vmx = nvmx; pcost = npc;\n                cur_total = npc + nec; sph_B = nB; improved = true;\n            }\n        }\n        if (!improved) break;\n    }\n    \n    // Final greedy power optimization (no deactivation)\n    {\n        bool gimproved = true;\n        while (gimproved) {\n            gimproved = false;\n            for (int k = 0; k < K; k++) {\n                int ov = asgn[k];\n                if (P[ov] == 0) continue;\n                long long best_saving = 0; int best_nv = -1;\n                for (int nv : clo[k]) {\n                    if (nv == ov || P[nv] == 0) continue;\n                    long long nmx_ov2 = vmx[ov];\n                    if (rsq[k][ov] == vmx[ov]) {\n                        nmx_ov2 = 0;\n                        for (int r : vr[ov]) if (r != k) nmx_ov2 = max(nmx_ov2, rsq[r][ov]);\n                    }\n                    int nPov2 = calcP(nmx_ov2);\n                    if (nPov2 == 0) continue;\n                    long long nmx_nv2 = max(vmx[nv], rsq[k][nv]);\n                    int nPnv2 = calcP(nmx_nv2);\n                    long long old_c = (long long)P[ov]*P[ov] + (long long)P[nv]*P[nv];\n                    long long new_c = (long long)nPov2*nPov2 + (long long)nPnv2*nPnv2;\n                    if (new_c < old_c && old_c - new_c > best_saving) {\n                        best_saving = old_c - new_c; best_nv = nv;\n                    }\n                }\n                if (best_nv != -1) {\n                    int pk = pos_in_vr[k];\n                    if (pk < (int)vr[ov].size() - 1) {\n                        int last = vr[ov].back();\n                        vr[ov][pk] = last; pos_in_vr[last] = pk;\n                    }\n                    vr[ov].pop_back();\n                    pos_in_vr[k] = vr[best_nv].size();\n                    vr[best_nv].push_back(k);\n                    if (rsq[k][ov] == vmx[ov]) {\n                        vmx[ov] = 0;\n                        for (int r : vr[ov]) vmx[ov] = max(vmx[ov], rsq[r][ov]);\n                    }\n                    P[ov] = calcP(vmx[ov]);\n                    vmx[best_nv] = max(vmx[best_nv], rsq[k][best_nv]);\n                    P[best_nv] = calcP(vmx[best_nv]);\n                    asgn[k] = best_nv; gimproved = true;\n                }\n            }\n        }\n    }\n    \n    tie(sph_ec, sph_B) = compute_sph(P);\n    for (int i = 0; i < N; i++) cout << P[i] << \" \\n\"[i == N-1];\n    for (int j = 0; j < M; j++) cout << sph_B[j] << \" \\n\"[j == M-1];\n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint grid[N][N];\nvector<array<int, 4>> swaps;\n\nint main() {\n    ios_base::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 >> grid[x][y];\n    \n    auto siftDown = [&](int x, int y) {\n        while (x < N - 1) {\n            int lv = grid[x+1][y], rv = grid[x+1][y+1], cv = grid[x][y];\n            if (cv <= lv && cv <= rv) break;\n            if (lv <= rv) {\n                swap(grid[x][y], grid[x+1][y]);\n                swaps.push_back({x, y, x+1, y});\n                x++;\n            } else {\n                swap(grid[x][y], grid[x+1][y+1]);\n                swaps.push_back({x, y, x+1, y+1});\n                x++; y++;\n            }\n            if (swaps.size() >= 9999) return;\n        }\n    };\n    \n    // Heapify: bottom to top, full sift-down\n    for (int x = N - 2; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            siftDown(x, y);\n            if (swaps.size() >= 9999) goto done;\n        }\n    }\n    \n    // Iteratively fix remaining violations\n    // (caused by triangular grid's dual-parent structure)\n    for (int iter = 0; iter < 500; iter++) {\n        bool any = false;\n        for (int x = N - 2; x >= 0; x--) {\n            for (int y = 0; y <= x; y++) {\n                if (grid[x][y] > grid[x+1][y] || grid[x][y] > grid[x+1][y+1]) {\n                    any = true;\n                    // One-step fix: swap parent with smaller child\n                    if (grid[x+1][y] <= grid[x+1][y+1]) {\n                        swap(grid[x][y], grid[x+1][y]);\n                        swaps.push_back({x, y, x+1, y});\n                    } else {\n                        swap(grid[x][y], grid[x+1][y+1]);\n                        swaps.push_back({x, y, x+1, y+1});\n                    }\n                    if (swaps.size() >= 9999) goto done;\n                }\n            }\n        }\n        if (!any) break;\n    }\n    \ndone:\n    cout << swaps.size() << \"\\n\";\n    for (auto& s : swaps)\n        cout << s[0] << \" \" << s[1] << \" \" << s[2] << \" \" << s[3] << \"\\n\";\n    \n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <set>\n\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    vector<vector<bool>> is_obstacle(D, vector<bool>(D, false));\n    for (int i = 0; i < N; i++) {\n        int ri, rj;\n        cin >> ri >> rj;\n        is_obstacle[ri][rj] = true;\n    }\n    \n    int entrance_i = 0, entrance_j = (D - 1) / 2;\n    \n    // Compute shortest path distance from entrance avoiding obstacles\n    vector<vector<int>> dist(D, vector<int>(D, -1));\n    queue<pair<int, int>> q;\n    q.push({entrance_i, entrance_j});\n    dist[entrance_i][entrance_j] = 0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    \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 (ni >= 0 && ni < D && nj >= 0 && nj < D && dist[ni][nj] == -1 && !is_obstacle[ni][nj]) {\n                dist[ni][nj] = dist[i][j] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    int M = 0;\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (!(i == entrance_i && j == entrance_j) && !is_obstacle[i][j])\n                M++;\n                \n    struct Cell { int i, j, dist, degree, rank; };\n    vector<Cell> C(M);\n    vector<vector<int>> cell_index(D, vector<int>(D, -1));\n    \n    int idx = 0;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (!(i == entrance_i && j == entrance_j) && !is_obstacle[i][j]) {\n                C[idx].i = i; C[idx].j = j; C[idx].dist = dist[i][j];\n                cell_index[i][j] = idx++;\n            }\n        }\n    }\n    \n    // Calculate internal degrees (only counting valid container neighbors)\n    for (int k = 0; k < M; k++) {\n        C[k].degree = 0;\n        for (int d = 0; d < 4; d++) {\n            int ni = C[k].i + di[d], nj = C[k].j + dj[d];\n            if (ni >= 0 && ni < D && nj >= 0 && nj < D && cell_index[ni][nj] != -1) {\n                C[k].degree++;\n            }\n        }\n    }\n    \n    // Sort primarily by BFS distance, then by degree descending (hubs first), then coordinates\n    sort(C.begin(), C.end(), [&](const Cell& a, const Cell& b) {\n        if (a.dist != b.dist) return a.dist < b.dist;\n        if (a.degree != b.degree) return a.degree > b.degree;\n        if (a.i != b.i) return a.i < b.i;\n        return a.j < b.j;\n    });\n    \n    for (int k = 0; k < M; k++) C[k].rank = k;\n    \n    set<int> available_cells_set;\n    for (int k = 0; k < M; k++) available_cells_set.insert(k);\n    \n    vector<vector<int>> container_at(D, vector<int>(D, -1));\n    vector<vector<bool>> is_empty(D, vector<bool>(D, true));\n    for (int i = 0; i < D; i++)\n        for (int j = 0; j < D; j++)\n            if (is_obstacle[i][j]) is_empty[i][j] = false;\n            \n    for (int d = 0; d < M; d++) {\n        int t; cin >> t;\n        \n        // Find Articulation Points dynamically using Tarjan's Algorithm\n        int dfs_timer = 0;\n        vector<vector<int>> tin(D, vector<int>(D, -1)), low(D, vector<int>(D, -1));\n        vector<vector<bool>> is_ap(D, vector<bool>(D, false));\n        \n        auto dfs = [&](auto& self, int i, int j, int pi, int pj) -> void {\n            tin[i][j] = low[i][j] = dfs_timer++;\n            int children = 0;\n            for (int dd = 0; dd < 4; dd++) {\n                int ni = i + di[dd], nj = j + dj[dd];\n                if (ni < 0 || ni >= D || nj < 0 || nj >= D || !is_empty[ni][nj]) continue;\n                if (tin[ni][nj] == -1) {\n                    self(self, ni, nj, i, j);\n                    low[i][j] = min(low[i][j], low[ni][nj]);\n                    if (low[ni][nj] >= tin[i][j] && (pi != -1 || pj != -1)) is_ap[i][j] = true;\n                    children++;\n                } else if (!(ni == pi && nj == pj)) {\n                    low[i][j] = min(low[i][j], tin[ni][nj]);\n                }\n            }\n            if (pi == -1 && pj == -1 && children > 1) is_ap[i][j] = true;\n        };\n        dfs(dfs, entrance_i, entrance_j, -1, -1);\n        \n        // Filter Safe Cells and Find Best Match based on BFS Rank\n        vector<pair<int, int>> safe_with_rank; // {rank, index in C}\n        for (int k : available_cells_set) {\n            if (available_cells_set.size() == 1 || !is_ap[C[k].i][C[k].j]) {\n                safe_with_rank.push_back({C[k].rank, k});\n            }\n        }\n        sort(safe_with_rank.begin(), safe_with_rank.end());\n        \n        int best_k = -1, best_diff = M + 1, best_rank = -1;\n        int target_rank = t;\n        auto it = lower_bound(safe_with_rank.begin(), safe_with_rank.end(), make_pair(target_rank, -1));\n        \n        if (it != safe_with_rank.end()) {\n            int diff = abs(it->first - target_rank);\n            if (diff < best_diff || (diff == best_diff && it->first > best_rank)) {\n                best_diff = diff; best_k = it->second; best_rank = it->first;\n            }\n        }\n        if (it != safe_with_rank.begin()) {\n            --it; int diff = abs(it->first - target_rank);\n            if (diff < best_diff || (diff == best_diff && it->first > best_rank)) {\n                best_diff = diff; best_k = it->second; best_rank = it->first;\n            }\n        }\n        \n        if (best_k == -1) { best_k = *available_cells_set.begin(); best_rank = C[best_k].rank; }\n        \n        available_cells_set.erase(best_k);\n        cout << C[best_k].i << \" \" << C[best_k].j << endl;\n        container_at[C[best_k].i][C[best_k].j] = t;\n        is_empty[C[best_k].i][C[best_k].j] = false;\n    }\n    \n    // Transport phase: Greedily remove the smallest numbered accessible container\n    for (int iter = 0; iter < M; iter++) {\n        vector<vector<bool>> reachable(D, vector<bool>(D, false));\n        queue<pair<int, int>> bfs_q;\n        bfs_q.push({entrance_i, entrance_j});\n        reachable[entrance_i][entrance_j] = true;\n        while (!bfs_q.empty()) {\n            auto [i, j] = bfs_q.front(); bfs_q.pop();\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d], nj = j + dj[d];\n                if (ni >= 0 && ni < D && nj >= 0 && nj < D && !reachable[ni][nj] && is_empty[ni][nj]) {\n                    reachable[ni][nj] = true; bfs_q.push({ni, nj});\n                }\n            }\n        }\n        int min_t = M + 1, min_i = -1, min_j = -1;\n        for (int i = 0; i < D; i++)\n            for (int j = 0; j < D; j++)\n                if (container_at[i][j] >= 0) {\n                    bool acc = false;\n                    for (int d = 0; d < 4; d++) { int ni = i + di[d], nj = j + dj[d]; if (ni >= 0 && ni < D && nj >= 0 && nj < D && is_empty[ni][nj] && reachable[ni][nj]) { acc = true; break; } }\n                    if (acc && container_at[i][j] < min_t) { min_t = container_at[i][j]; min_i = i; min_j = j; }\n                }\n        cout << min_i << \" \" << min_j << endl;\n        is_empty[min_i][min_j] = true; container_at[min_i][min_j] = -1;\n    }\n    \n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <cstring>\n#include <chrono>\n#include <random>\n#include <cmath>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nconst int N = 50, M = 100;\nconst int dx[] = {0, 0, 1, -1};\nconst int dy[] = {1, -1, 0, 0};\n\nint n, m;\nint grid[N][N], orig[N][N], best_grid[N][N];\nint bestE = -1;\nint ac[M+1][M+1], orig_ac[M+1][M+1];\nbool is_req[M+1][M+1];\nbool is_interior[M+1];\nint color_cnt[M+1], orig_color_cnt[M+1];\nmt19937 rng(42);\n\nint vis[N][N];\nint timer = 0;\nint bfs_q_x[N*N];\nint bfs_q_y[N*N];\n\nbool ok(int x, int y) { return 0 <= x && x < n && 0 <= y && y < n; }\n\nvoid creq() {\n    memset(ac, 0, sizeof(ac));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) {\n            if (j + 1 < n && orig[i][j] != orig[i][j+1])\n                ac[min(orig[i][j], orig[i][j+1])][max(orig[i][j], orig[i][j+1])]++;\n            if (i + 1 < n && orig[i][j] != orig[i+1][j])\n                ac[min(orig[i][j], orig[i+1][j])][max(orig[i][j], orig[i+1][j])]++;\n            if (i == 0) ac[0][orig[i][j]]++;\n            if (i == n - 1) ac[0][orig[i][j]]++;\n            if (j == 0) ac[0][orig[i][j]]++;\n            if (j == n - 1) ac[0][orig[i][j]]++;\n        }\n    memset(is_req, 0, sizeof(is_req));\n    for (int a = 0; a <= m; a++)\n        for (int b = a; b <= m; b++)\n            if (ac[a][b] > 0) is_req[a][b] = true;\n    memcpy(orig_ac, ac, sizeof(ac));\n    \n    memset(is_interior, true, sizeof(is_interior));\n    is_interior[0] = false;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++)\n            if (i == 0 || i == n - 1 || j == 0 || j == n - 1)\n                is_interior[orig[i][j]] = false;\n}\n\nbool is_articulation_point(int i, int j, int c) {\n    if (color_cnt[c] <= 2) return false;\n    \n    int c_neighs_x[4], c_neighs_y[4];\n    int c_neighs_cnt = 0;\n    for (int d = 0; d < 4; d++) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ok(ni, nj) && grid[ni][nj] == c) {\n            c_neighs_x[c_neighs_cnt] = ni;\n            c_neighs_y[c_neighs_cnt] = nj;\n            c_neighs_cnt++;\n        }\n    }\n    if (c_neighs_cnt <= 1) return false;\n    \n    if (timer == INT_MAX) { memset(vis, 0, sizeof(vis)); timer = 1; }\n    timer++;\n    int head = 0, tail = 0;\n    bfs_q_x[tail] = c_neighs_x[0];\n    bfs_q_y[tail] = c_neighs_y[0];\n    tail++;\n    vis[c_neighs_x[0]][c_neighs_y[0]] = timer;\n    \n    int found_count = 1;\n    bool found[4] = {false};\n    found[0] = true;\n    \n    while (head < tail) {\n        int x = bfs_q_x[head];\n        int y = bfs_q_y[head];\n        head++;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (ok(nx, ny) && vis[nx][ny] != timer && grid[nx][ny] == c && !(nx == i && ny == j)) {\n                vis[nx][ny] = timer;\n                bfs_q_x[tail] = nx;\n                bfs_q_y[tail] = ny;\n                tail++;\n                for (int k = 1; k < c_neighs_cnt; k++) {\n                    if (nx == c_neighs_x[k] && ny == c_neighs_y[k] && !found[k]) {\n                        found[k] = true;\n                        found_count++;\n                    }\n                }\n                if (found_count == c_neighs_cnt) return false;\n            }\n        }\n    }\n    return true;\n}\n\nbool check_0_connect(int i, int j) {\n    int zero_neighs_x[4], zero_neighs_y[4];\n    int zero_neighs_cnt = 0;\n    for (int d = 0; d < 4; d++) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ok(ni, nj) && grid[ni][nj] == 0) {\n            zero_neighs_x[zero_neighs_cnt] = ni;\n            zero_neighs_y[zero_neighs_cnt] = nj;\n            zero_neighs_cnt++;\n        }\n    }\n    if (zero_neighs_cnt == 0) return true;\n    \n    if (timer == INT_MAX) { memset(vis, 0, sizeof(vis)); timer = 1; }\n    timer++;\n    int head = 0, tail = 0;\n    bfs_q_x[tail] = zero_neighs_x[0];\n    bfs_q_y[tail] = zero_neighs_y[0];\n    tail++;\n    vis[zero_neighs_x[0]][zero_neighs_y[0]] = timer;\n    bool reached_bnd = (zero_neighs_x[0] == 0 || zero_neighs_x[0] == n - 1 || zero_neighs_y[0] == 0 || zero_neighs_y[0] == n - 1);\n    \n    while (head < tail) {\n        int x = bfs_q_x[head];\n        int y = bfs_q_y[head];\n        head++;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (ok(nx, ny) && vis[nx][ny] != timer && grid[nx][ny] == 0 && !(nx == i && ny == j)) {\n                vis[nx][ny] = timer;\n                bfs_q_x[tail] = nx;\n                bfs_q_y[tail] = ny;\n                tail++;\n                if (nx == 0 || nx == n - 1 || ny == 0 || ny == n - 1) reached_bnd = true;\n            }\n        }\n    }\n    if (!reached_bnd) return false;\n    for (int k = 1; k < zero_neighs_cnt; k++) {\n        if (vis[zero_neighs_x[k]][zero_neighs_y[k]] != timer) return false;\n    }\n    return true;\n}\n\nbool is_valid_move(int i, int j, int nc) {\n    int oc = grid[i][j];\n    if (oc == nc) return false;\n    \n    if (nc == 0 && is_interior[oc]) return false;\n    \n    if (nc == 0) {\n        bool adj_to_zero = (i == 0 || i == n - 1 || j == 0 || j == n - 1);\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ok(ni, nj) && grid[ni][nj] == 0) adj_to_zero = true;\n        }\n        if (!adj_to_zero) return false;\n    } else {\n        bool has_nc = false;\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ok(ni, nj) && grid[ni][nj] == nc) has_nc = true;\n        }\n        if (!has_nc) return false;\n    }\n    \n    int deltas_arr_a[10], deltas_arr_b[10];\n    int d_vals[10] = {0};\n    int d_cnt = 0;\n    \n    for (int d = 0; d < 4; d++) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ok(ni, nj)) {\n            int nb = grid[ni][nj];\n            if (oc != nb) {\n                int a = min(oc, nb), b = max(oc, nb);\n                bool found = false;\n                for(int k=0; k<d_cnt; k++) if(deltas_arr_a[k]==a && deltas_arr_b[k]==b) { d_vals[k]--; found=true; break; }\n                if(!found) { deltas_arr_a[d_cnt]=a; deltas_arr_b[d_cnt]=b; d_vals[d_cnt]=-1; d_cnt++; }\n            }\n            if (nc != nb) {\n                int a = min(nc, nb), b = max(nc, nb);\n                bool found = false;\n                for(int k=0; k<d_cnt; k++) if(deltas_arr_a[k]==a && deltas_arr_b[k]==b) { d_vals[k]++; found=true; break; }\n                if(!found) { deltas_arr_a[d_cnt]=a; deltas_arr_b[d_cnt]=b; d_vals[d_cnt]=1; d_cnt++; }\n            }\n        }\n    }\n    \n    int bnd_cnt = 0;\n    if (i == 0) bnd_cnt++;\n    if (i == n - 1) bnd_cnt++;\n    if (j == 0) bnd_cnt++;\n    if (j == n - 1) bnd_cnt++;\n    \n    if (bnd_cnt > 0) {\n        if (oc != 0) {\n            int a = 0, b = oc;\n            bool found = false;\n            for(int k=0; k<d_cnt; k++) if(deltas_arr_a[k]==a && deltas_arr_b[k]==b) { d_vals[k] -= bnd_cnt; found=true; break; }\n            if(!found) { deltas_arr_a[d_cnt]=a; deltas_arr_b[d_cnt]=b; d_vals[d_cnt]=-bnd_cnt; d_cnt++; }\n        }\n        if (nc != 0) {\n            int a = 0, b = nc;\n            bool found = false;\n            for(int k=0; k<d_cnt; k++) if(deltas_arr_a[k]==a && deltas_arr_b[k]==b) { d_vals[k] += bnd_cnt; found=true; break; }\n            if(!found) { deltas_arr_a[d_cnt]=a; deltas_arr_b[d_cnt]=b; d_vals[d_cnt]=bnd_cnt; d_cnt++; }\n        }\n    }\n    \n    for(int k=0; k<d_cnt; k++) {\n        int a = deltas_arr_a[k], b = deltas_arr_b[k];\n        int delta = d_vals[k];\n        if (ac[a][b] + delta == 0 && is_req[a][b]) return false;\n        if (ac[a][b] + delta > 0 && !is_req[a][b]) return false;\n    }\n    \n    if (oc != 0) {\n        if (color_cnt[oc] == 1) return false;\n        if (is_articulation_point(i, j, oc)) return false;\n    } else {\n        if (!check_0_connect(i, j)) return false;\n    }\n    \n    return true;\n}\n\nvoid apply_move(int i, int j, int nc) {\n    int oc = grid[i][j];\n    for (int d = 0; d < 4; d++) {\n        int ni = i + dx[d], nj = j + dy[d];\n        if (ok(ni, nj)) {\n            int nb = grid[ni][nj];\n            if (oc != nb) ac[min(oc, nb)][max(oc, nb)]--;\n            if (nc != nb) ac[min(nc, nb)][max(nc, nb)]++;\n        }\n    }\n    int bnd_cnt = 0;\n    if (i == 0) bnd_cnt++;\n    if (i == n - 1) bnd_cnt++;\n    if (j == 0) bnd_cnt++;\n    if (j == n - 1) bnd_cnt++;\n    if (bnd_cnt > 0) {\n        if (oc != 0) ac[0][oc] -= bnd_cnt;\n        if (nc != 0) ac[0][nc] += bnd_cnt;\n    }\n    grid[i][j] = nc;\n    color_cnt[oc]--;\n    color_cnt[nc]++;\n}\n\nint main() {\n    ios::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> n >> m;\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) {\n            cin >> orig[i][j];\n        }\n    \n    memset(orig_color_cnt, 0, sizeof(orig_color_cnt));\n    for (int i = 0; i < n; i++)\n        for (int j = 0; j < n; j++) orig_color_cnt[orig[i][j]]++;\n            \n    creq();\n    \n    memcpy(grid, orig, sizeof(grid));\n    memcpy(ac, orig_ac, sizeof(ac));\n    memcpy(color_cnt, orig_color_cnt, sizeof(color_cnt));\n    \n    int E = 0;\n    bestE = 0;\n    memcpy(best_grid, grid, sizeof(grid));\n    \n    vector<int> active_cells;\n    vector<bool> is_active(n * n, false);\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            bool active = (i == 0 || i == n - 1 || j == 0 || j == n - 1);\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ok(ni, nj) && grid[i][j] != grid[ni][nj]) active = true;\n            }\n            if (active) {\n                int idx = i * n + j;\n                active_cells.push_back(idx);\n                is_active[idx] = true;\n            }\n        }\n    }\n    \n    auto start = chrono::high_resolution_clock::now();\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    \n    long long iterations = 0;\n    double T = 0.5;\n    double elapsed = 0.0;\n    \n    while (true) {\n        if (iterations % 10000 == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > 1.8) break;\n            T = max(0.1, 0.5 - 0.4 * (elapsed / 1.8));\n        }\n        iterations++;\n        \n        if (active_cells.empty()) break;\n        int idx = active_cells[rng() % active_cells.size()];\n        int i = idx / n, j = idx % n;\n        \n        bool active = (i == 0 || i == n - 1 || j == 0 || j == n - 1);\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d], nj = j + dy[d];\n            if (ok(ni, nj) && grid[i][j] != grid[ni][nj]) { active = true; break; }\n        }\n        if (!active) continue;\n        \n        int oc = grid[i][j];\n        \n        int nc = -1;\n        if (oc == 0) {\n            int options[5]; int opt_cnt = 0;\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ok(ni, nj) && grid[ni][nj] != 0) {\n                    options[opt_cnt++] = grid[ni][nj];\n                }\n            }\n            if (opt_cnt > 0) nc = options[rng() % opt_cnt];\n        } else {\n            bool can_be_zero = !is_interior[oc];\n            if (can_be_zero) {\n                bool adj_to_zero = (i == 0 || i == n - 1 || j == 0 || j == n - 1);\n                if (!adj_to_zero) {\n                    for (int d = 0; d < 4; d++) {\n                        int ni = i + dx[d], nj = j + dy[d];\n                        if (ok(ni, nj) && grid[ni][nj] == 0) { adj_to_zero = true; break; }\n                    }\n                }\n                if (!adj_to_zero) can_be_zero = false;\n            }\n            \n            if (can_be_zero) {\n                if (rng() % 10 < 8) {\n                    nc = 0;\n                } else {\n                    int options[5]; int opt_cnt = 0;\n                    for (int d = 0; d < 4; d++) {\n                        int ni = i + dx[d], nj = j + dy[d];\n                        if (ok(ni, nj) && grid[ni][nj] != oc && grid[ni][nj] != 0) {\n                            options[opt_cnt++] = grid[ni][nj];\n                        }\n                    }\n                    if (opt_cnt > 0) nc = options[rng() % opt_cnt];\n                    else nc = 0;\n                }\n            } else {\n                int options[5]; int opt_cnt = 0;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    if (ok(ni, nj) && grid[ni][nj] != oc && grid[ni][nj] != 0) {\n                        options[opt_cnt++] = grid[ni][nj];\n                    }\n                }\n                if (opt_cnt > 0) nc = options[rng() % opt_cnt];\n            }\n        }\n        \n        if (nc != -1 && oc != nc) {\n            if (is_valid_move(i, j, nc)) {\n                int delta_E = (nc == 0 ? 1 : (oc == 0 ? -1 : 0));\n                double prob_accept = 1.0;\n                if (delta_E < 0) {\n                    prob_accept = exp(delta_E / T);\n                }\n                if (prob_dist(rng) < prob_accept) {\n                    apply_move(i, j, nc);\n                    E += delta_E;\n                    if (E > bestE) {\n                        bestE = E;\n                        memcpy(best_grid, grid, sizeof(grid));\n                    }\n                    \n                    auto update_active = [&](int x, int y) {\n                        int nidx = x * n + y;\n                        bool nactive = (x == 0 || x == n - 1 || y == 0 || y == n - 1);\n                        for (int dd = 0; dd < 4; dd++) {\n                            int nx = x + dx[dd], ny = y + dy[dd];\n                            if (ok(nx, ny) && grid[x][y] != grid[nx][ny]) { nactive = true; break; }\n                        }\n                        if (nactive && !is_active[nidx]) {\n                            active_cells.push_back(nidx);\n                            is_active[nidx] = true;\n                        }\n                    };\n                    \n                    update_active(i, j);\n                    for (int d = 0; d < 4; d++) {\n                        int ni = i + dx[d], nj = j + dy[d];\n                        if (ok(ni, nj)) {\n                            update_active(ni, nj);\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << best_grid[i][j];\n            if (j < n - 1) cout << \" \";\n        }\n        cout << \"\\n\";\n    }\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\nint N, D, Q;\nint qc = 0;\nint cmp[105][105];\n\nchar do_query(int a, int b) {\n    if (cmp[a][b] == -1) return '<';\n    if (cmp[a][b] == 1) return '>';\n    if (cmp[a][b] == 2) return '=';\n    if (qc >= Q) return '=';\n    qc++;\n    cout << \"1 1 \" << a << \" \" << b << endl;\n    char res; cin >> res;\n    if (res == '<') { cmp[a][b] = -1; cmp[b][a] = 1; }\n    else if (res == '>') { cmp[a][b] = 1; cmp[b][a] = -1; }\n    else if (res == '=') { cmp[a][b] = 2; cmp[b][a] = 2; }\n    return res;\n}\n\nchar do_query_sets(const vector<int>& L, const vector<int>& R) {\n    if (L.empty() || R.empty()) return '=';\n    cout << L.size() << \" \" << R.size();\n    for (int x : L) cout << \" \" << x;\n    for (int x : R) cout << \" \" << x;\n    cout << endl;\n    char res; cin >> res;\n    qc++;\n    return res;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    for (int i = 0; i < N; i++) items[i] = i;\n    \n    // Phase 1: Heap Sort to find heavy items efficiently\n    for (int i = 1; i < N && qc < Q; i++) {\n        int cur = i;\n        while (cur > 0 && qc < Q) {\n            int par = (cur - 1) / 2;\n            char res = do_query(items[cur], items[par]);\n            if (res == '>') { swap(items[cur], items[par]); cur = par; }\n            else break;\n        }\n    }\n    for (int i = N - 1; i > 0 && qc < Q; i--) {\n        swap(items[0], items[i]);\n        int cur = 0;\n        while (qc < Q) {\n            int l = 2 * cur + 1, r = 2 * cur + 2, largest = cur;\n            if (l < i) { if (do_query(items[l], items[largest]) == '>') largest = l; }\n            if (r < i) { if (do_query(items[r], items[largest]) == '>') largest = r; }\n            if (largest != cur) { swap(items[cur], items[largest]); cur = largest; }\n            else break;\n        }\n    }\n    \n    // Phase 2: Initial LPT Assignment\n    vector<double> ew(N);\n    double cur_ew = 0;\n    for (int i = 0; i < N; i++) { cur_ew += 1.0 / (N - i); ew[items[i]] = cur_ew; }\n    \n    vector<double> sum_g(D, 0);\n    vector<vector<int>> group_items(D);\n    vector<int> asgn(N);\n    \n    for (int i = N - 1; i >= 0; i--) {\n        int item = items[i], mg = 0;\n        for (int g = 1; g < D; g++) if (sum_g[g] < sum_g[mg]) mg = g;\n        asgn[item] = mg; sum_g[mg] += ew[item]; group_items[mg].push_back(item);\n    }\n    \n    // Phase 3: Exact Local Search with Real Queries\n    while (qc < Q) {\n        int A = 0; bool abort = false;\n        for (int g = 1; g < D; g++) {\n            if (qc >= Q) { abort = true; break; }\n            if (do_query_sets(group_items[g], group_items[A]) == '>') A = g;\n        }\n        if (abort) break;\n        \n        int B = 0;\n        for (int g = 1; g < D; g++) {\n            if (qc >= Q) { abort = true; break; }\n            if (do_query_sets(group_items[g], group_items[B]) == '<') B = g;\n        }\n        if (abort) break;\n        if (A == B) break;\n        \n        vector<int>& items_A = group_items[A];\n        vector<int>& items_B = group_items[B];\n        bool improved = false;\n        \n        // Try single moves from A to B\n        sort(items_A.begin(), items_A.end(), [&](int x, int y){ return ew[x] < ew[y]; });\n        for (int idx = 0; idx < min(5, (int)items_A.size()); idx++) {\n            if ((int)items_A.size() <= 1) break;\n            int i = items_A[idx];\n            vector<int> L = items_B;\n            vector<int> R = items_A;\n            R.erase(find(R.begin(), R.end(), i));\n            \n            if (qc >= Q) break;\n            char res = do_query_sets(L, R);\n            if (res == '<' || res == '=') {\n                items_A.erase(find(items_A.begin(), items_A.end(), i));\n                items_B.push_back(i); asgn[i] = B;\n                sum_g[A] -= ew[i]; sum_g[B] += ew[i];\n                improved = true; break;\n            }\n        }\n        \n        if (!improved) {\n            // Try swaps between A and B\n            if (items_A.size() > 1 && items_B.size() > 1) {\n                sort(items_A.begin(), items_A.end(), [&](int x, int y){ return ew[x] > ew[y]; });\n                sort(items_B.begin(), items_B.end(), [&](int x, int y){ return ew[x] < ew[y]; });\n                for (int idx_i = 0; idx_i < min(5, (int)items_A.size()) && !improved; idx_i++) {\n                    for (int idx_j = 0; idx_j < min(5, (int)items_B.size()); idx_j++) {\n                        int i = items_A[idx_i], j = items_B[idx_j];\n                        if (cmp[i][j] != 1) { if (qc >= Q) { abort = true; break; } if (do_query(i, j) != '>') continue; }\n                        \n                        vector<int> L = items_B; L.erase(find(L.begin(), L.end(), j));\n                        vector<int> R = items_A; R.erase(find(R.begin(), R.end(), i));\n                        \n                        if (qc >= Q) { abort = true; break; }\n                        char res = do_query_sets(L, R);\n                        if (res == '<' || res == '=') {\n                            items_A.erase(find(items_A.begin(), items_A.end(), i));\n                            items_A.push_back(j);\n                            items_B.erase(find(items_B.begin(), items_B.end(), j));\n                            items_B.push_back(i);\n                            asgn[i] = B; asgn[j] = A;\n                            sum_g[A] += ew[j] - ew[i]; sum_g[B] += ew[i] - ew[j];\n                            improved = true; break;\n                        }\n                    }\n                    if (abort) break;\n                }\n            }\n        }\n        if (!improved || abort) break;\n    }\n    \n    // Waste remaining queries safely\n    while (qc < Q) { cout << \"1 1 0 1\" << endl; char res; cin >> res; qc++; }\n    \n    for (int i = 0; i < N; i++) cout << asgn[i] << \" \\n\"[i==N-1];\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nint n, m;\nvector<vector<int>> init_stacks;\n\npair<int, vector<pair<int,int>>> solve(int nezi_ord, int inv_ord) {\n    vector<vector<int>> stacks = init_stacks;\n    vector<int> box_stack(n + 1), box_pos(n + 1);\n    for (int i = 0; i < m; i++)\n        for (int j = 0; j < (int)stacks[i].size(); j++) {\n            box_stack[stacks[i][j]] = i;\n            box_pos[stacks[i][j]] = j;\n        }\n    \n    int total_energy = 0;\n    vector<pair<int,int>> ops;\n    \n    for (int v = 1; v <= n; v++) {\n        int sid = box_stack[v], pos = box_pos[v];\n        \n        while ((int)stacks[sid].size() > pos + 1) {\n            int top_idx = stacks[sid].size() - 1;\n            \n            int run_start = top_idx;\n            while (run_start > pos + 1 && stacks[sid][run_start - 1] > stacks[sid][run_start])\n                run_start--;\n            \n            int max_in_run = stacks[sid][run_start];\n            for (int s = run_start + 1; s <= top_idx; s++)\n                max_in_run = max(max_in_run, stacks[sid][s]);\n            \n            bool has_ne_zi = false;\n            for (int d = 0; d < m; d++) {\n                if (d == sid || stacks[d].empty()) continue;\n                if (stacks[d].back() > max_in_run) { has_ne_zi = true; break; }\n            }\n            \n            bool has_empty = false;\n            for (int d = 0; d < m; d++)\n                if (d != sid && stacks[d].empty()) { has_empty = true; break; }\n            \n            int chunk_start;\n            \n            if (has_ne_zi) {\n                chunk_start = run_start;\n            } else {\n                chunk_start = -1;\n                for (int cs = run_start + 1; cs <= top_idx; cs++) {\n                    int cmax = stacks[sid][cs];\n                    for (int s = cs + 1; s <= top_idx; s++)\n                        cmax = max(cmax, stacks[sid][s]);\n                    \n                    bool found = false;\n                    for (int d = 0; d < m; d++) {\n                        if (d == sid || stacks[d].empty()) continue;\n                        if (stacks[d].back() > cmax) { found = true; break; }\n                    }\n                    if (found) { chunk_start = cs; break; }\n                }\n                \n                if (chunk_start == -1 && has_empty) chunk_start = run_start;\n                \n                if (chunk_start == -1) {\n                    for (int cs = run_start + 1; cs <= top_idx; cs++) {\n                        int cmax = stacks[sid][cs];\n                        for (int s = cs + 1; s <= top_idx; s++)\n                            cmax = max(cmax, stacks[sid][s]);\n                        \n                        bool found = false;\n                        for (int d = 0; d < m; d++) {\n                            if (d == sid) continue;\n                            if (stacks[d].empty() || stacks[d].back() > cmax) { found = true; break; }\n                        }\n                        if (found) { chunk_start = cs; break; }\n                    }\n                }\n                \n                if (chunk_start == -1) chunk_start = run_start;\n            }\n            \n            int chunk_size = top_idx - chunk_start + 1;\n            int chunk_max = stacks[sid][chunk_start];\n            for (int s = chunk_start + 1; s <= top_idx; s++)\n                chunk_max = max(chunk_max, stacks[sid][s]);\n            \n            int dest = -1;\n            int bp = 4, bs = INT_MAX;\n            \n            for (int d = 0; d < m; d++) {\n                if (d == sid) continue;\n                int p, sub;\n                if (stacks[d].empty()) {\n                    bool ne_zi = false;\n                    for (int d2 = 0; d2 < m; d2++) {\n                        if (d2 == sid || stacks[d2].empty()) continue;\n                        if (stacks[d2].back() > chunk_max) { ne_zi = true; break; }\n                    }\n                    p = ne_zi ? 2 : 1;\n                    sub = 0;\n                } else {\n                    int td = stacks[d].back();\n                    if (td > chunk_max) {\n                        p = 0;\n                        sub = nezi_ord ? -td : td;\n                    } else {\n                        int ca = 0;\n                        for (int s = chunk_start; s <= top_idx; s++)\n                            if (stacks[sid][s] > td) ca++;\n                        p = 3;\n                        sub = ca * 1000 + (inv_ord ? td : -td);\n                    }\n                }\n                if (p < bp || (p == bp && sub < bs)) { bp = p; bs = sub; dest = d; }\n            }\n            if (dest == -1) dest = (sid + 1) % m;\n            \n            int u = stacks[sid][chunk_start];\n            ops.push_back({u, dest + 1});\n            total_energy += chunk_size + 1;\n            \n            vector<int> moved(stacks[sid].begin() + chunk_start, stacks[sid].end());\n            stacks[sid].resize(chunk_start);\n            stacks[dest].insert(stacks[dest].end(), moved.begin(), moved.end());\n            \n            for (int j = 0; j < (int)moved.size(); j++) {\n                box_stack[moved[j]] = dest;\n                box_pos[moved[j]] = stacks[dest].size() - moved.size() + j;\n            }\n        }\n        \n        ops.push_back({v, 0});\n        stacks[sid].pop_back();\n    }\n    \n    return {total_energy, ops};\n}\n\nint main() {\n    cin >> n >> m;\n    init_stacks.resize(m);\n    for (int i = 0; i < m; i++) {\n        init_stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++)\n            cin >> init_stacks[i][j];\n    }\n    \n    int best_energy = INT_MAX;\n    vector<pair<int,int>> best_ops;\n    \n    for (int nezi = 0; nezi < 2; nezi++) {\n        for (int inv = 0; inv < 2; inv++) {\n            auto [energy, ops] = solve(nezi, inv);\n            if (energy < best_energy) {\n                best_energy = energy;\n                best_ops = ops;\n            }\n        }\n    }\n    \n    for (auto& op : best_ops)\n        cout << op.first << \" \" << op.second << endl;\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\nchar dir_char[] = {'R', 'D', 'L', 'U'};\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + dx[dir], nj = j + dy[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    if (dir == 0 && v[i][j] == '1') return false;\n    if (dir == 1 && h[i][j] == '1') return false;\n    if (dir == 2 && v[i][nj] == '1') return false;\n    if (dir == 3 && h[ni][j] == '1') return false;\n    return true;\n}\n\nint get_dir(char c) {\n    if (c == 'R') return 0;\n    if (c == 'D') return 1;\n    if (c == 'L') return 2;\n    return 3; // 'U'\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N;\n    h.resize(N - 1); v.resize(N); d.resize(N, vector<int>(N));\n    for (int i = 0; i < N - 1; i++) cin >> h[i];\n    for (int i = 0; i < N; i++) cin >> v[i];\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> d[i][j];\n    \n    int total_cells = N * N;\n    vector<int> all_dist(total_cells * total_cells, -1);\n    vector<int> all_prev_dir(total_cells * total_cells, -1);\n\n    auto get_dist = [&](int si, int sj, int ei, int ej) -> int& {\n        return all_dist[(si * N + sj) * total_cells + (ei * N + ej)];\n    };\n    auto get_prev = [&](int si, int sj, int ei, int ej) -> int& {\n        return all_prev_dir[(si * N + sj) * total_cells + (ei * N + ej)];\n    };\n\n    // Precompute BFS from all cells\n    for (int si = 0; si < N; ++si) {\n        for (int sj = 0; sj < N; ++sj) {\n            queue<pair<int,int>> q;\n            get_dist(si, sj, si, sj) = 0;\n            q.push({si, sj});\n            while (!q.empty()) {\n                auto [ci, cj] = q.front(); q.pop();\n                for (int dir = 0; dir < 4; dir++) {\n                    if (!can_move(ci, cj, dir)) continue;\n                    int ni = ci + dx[dir], nj = cj + dy[dir];\n                    if (get_dist(si, sj, ni, nj) == -1) { \n                        get_dist(si, sj, ni, nj) = get_dist(si, sj, ci, cj) + 1; \n                        get_prev(si, sj, ni, nj) = (dir + 2) % 4; // Direction to go BACK\n                        q.push({ni, nj}); \n                    }\n                }\n            }\n        }\n    }\n\n    auto get_path = [&](int si, int sj, int ei, int ej) -> string {\n        string path_back;\n        int ci = ei, cj = ej;\n        while (ci != si || cj != sj) {\n            int dir = get_prev(si, sj, ci, cj);\n            path_back += dir_char[dir];\n            ci += dx[dir];\n            cj += dy[dir];\n        }\n        string path_to;\n        for (int k = (int)path_back.size() - 1; k >= 0; --k) {\n            char c = path_back[k];\n            if (c == 'R') path_to += 'L';\n            else if (c == 'D') path_to += 'U';\n            else if (c == 'L') path_to += 'R';\n            else path_to += 'D';\n        }\n        return path_to;\n    };\n    \n    // Build DFS tour\n    string base_tour;\n    base_tour.reserve(N * N * 2);\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            int ni = i + dx[dir], nj = j + dy[dir];\n            if (!visited[ni][nj]) {\n                base_tour += dir_char[dir];\n                dfs(ni, nj);\n                base_tour += dir_char[(dir + 2) % 4];\n            }\n        }\n    };\n    dfs(0, 0);\n    \n    int L = base_tour.size();\n    vector<pair<int,int>> positions(L + 1);\n    positions[0] = {0, 0};\n    for (int t = 0; t < L; t++) {\n        int dir = get_dir(base_tour[t]);\n        positions[t+1] = {positions[t].first + dx[dir], positions[t].second + dy[dir]};\n    }\n    \n    // Find closest insertion point on base tour for detours\n    vector<int> best_step(N * N, 0), best_cost(N * N, INT_MAX);\n    for (int t = 0; t < L; t++) {\n        auto [pi, pj] = positions[t];\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (pi == i && pj == j) continue;\n            int cost = 2 * get_dist(pi, pj, i, j);\n            if (cost < best_cost[i * N + j]) { best_cost[i * N + j] = cost; best_step[i * N + j] = t; }\n        }\n    }\n    \n    // Correctly calculate visits per cycle (t=0 to L-1)\n    vector<int> visit_count(N * N, 0);\n    for (int t = 0; t < L; t++) { auto [i, j] = positions[t]; visit_count[i * N + j]++; }\n    \n    double S_factor = 0;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) S_factor += (double)d[i][j] / visit_count[i * N + j];\n    \n    using Cell = tuple<double, int, int>;\n    priority_queue<Cell> pq;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (i == 0 && j == 0) continue;\n        int k = visit_count[i * N + j], cost = best_cost[i * N + j];\n        if (cost == 0 || cost >= INT_MAX) continue;\n        pq.push({(double)d[i][j] / ((long long)k * (k + 1)) / cost, i, j});\n    }\n    \n    struct Detour { int step; int i; int j; };\n    vector<Detour> detours;\n    int current_L = L;\n    \n    while (!pq.empty() && current_L < 100000) {\n        auto [p, i, j] = pq.top(); pq.pop();\n        int k = visit_count[i * N + j], cost = best_cost[i * N + j];\n        if (cost >= INT_MAX) continue;\n        double new_p = (double)d[i][j] / ((long long)k * (k + 1)) / cost;\n        if (abs(new_p - p) > 1e-9) { pq.push({new_p, i, j}); continue; }\n        \n        if (current_L + cost > 100000) continue;\n        \n        // Benefit-cost check\n        double benefit = (double)d[i][j] * (current_L + cost) / ((long long)k * (k + 1));\n        double detour_cost_val = (double)cost * S_factor;\n        if (benefit <= detour_cost_val) break; // No more beneficial detours possible\n        \n        int step = best_step[i * N + j];\n        \n        detours.push_back({step, i, j});\n        current_L += cost;\n        S_factor -= (double)d[i][j] / k;\n        visit_count[i * N + j]++;\n        S_factor += (double)d[i][j] / visit_count[i * N + j];\n        int nk = visit_count[i * N + j];\n        pq.push({(double)d[i][j] / ((long long)nk * (nk + 1)) / cost, i, j});\n    }\n    \n    sort(detours.begin(), detours.end(), [](const auto& a, const auto& b) { return a.step < b.step; });\n    \n    string result;\n    result.reserve(100000);\n    int detour_idx = 0;\n    for (int t = 0; t <= L; t++) {\n        while (detour_idx < (int)detours.size() && detours[detour_idx].step == t) {\n            auto [step, i, j] = detours[detour_idx];\n            auto [pi, pj] = positions[step];\n            string path_to = get_path(pi, pj, i, j);\n            string path_back;\n            for (int k2 = (int)path_to.size() - 1; k2 >= 0; k2--) {\n                char c = path_to[k2];\n                path_back += (c == 'R') ? 'L' : (c == 'D') ? 'U' : (c == 'L') ? 'R' : 'D';\n            }\n            result += path_to;\n            result += path_back;\n            detour_idx++;\n        }\n        if (t < L) result += base_tour[t];\n    }\n    \n    cout << result << endl;\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    int N,M; cin>>N>>M;\n    int si,sj; cin>>si>>sj;\n    vector<string> A(N);\n    for(int i=0;i<N;i++) cin>>A[i];\n    vector<string> t(M);\n    for(int i=0;i<M;i++) cin>>t[i];\n    vector<vector<pair<int,int>>> cp(26);\n    for(int i=0;i<N;i++) for(int j=0;j<N;j++) cp[A[i][j]-'A'].push_back({i,j});\n    vector<vector<int>> cd(26,vector<int>(26,0));\n    for(int c1=0;c1<26;c1++) for(int c2=0;c2<26;c2++){\n        int md=INT_MAX;\n        for(auto&[i1,j1]:cp[c1]) for(auto&[i2,j2]:cp[c2]) md=min(md,abs(i1-i2)+abs(j1-j2));\n        cd[c1][c2]=md;\n    }\n    vector<vector<int>> ov(M,vector<int>(M,0));\n    for(int i=0;i<M;i++) for(int j=0;j<M;j++){ if(i==j) continue;\n        for(int l=4;l>=1;l--){ bool ok=true; for(int k=0;k<l;k++) if(t[i][5-l+k]!=t[j][k]){ok=false;break;}\n            if(ok){ov[i][j]=l;break;}}}\n    vector<vector<int>> fail(M,vector<int>(6,0));\n    for(int k=0;k<M;k++) for(int i=2;i<=5;i++){ int f=fail[k][i-1];\n        while(f>0&&t[k][f]!=t[k][i-1]) f=fail[k][f]; if(t[k][f]==t[k][i-1]) f++; fail[k][i]=f;}\n    auto buildS=[&](const vector<int>&o)->string{ string s=t[o[0]];\n        for(int i=1;i<(int)o.size();i++){ int mx=min(5,(int)s.size()),a=0;\n            for(int l=mx;l>=1;l--){ bool ok=true; for(int k=0;k<l;k++) if(s[s.size()-l+k]!=t[o[i]][k]){ok=false;break;}\n                if(ok){a=l;break;}} s+=t[o[i]].substr(a);} return s;};\n    auto totalOv=[&](const vector<int>&o)->int{ int tv=0; for(int i=1;i<(int)o.size();i++) tv+=ov[o[i-1]][o[i]]; return tv;};\n    mt19937 rng(42);\n    auto greedyR=[&](int st,unsigned seed)->vector<int>{ mt19937 lr(seed); vector<int>o; o.push_back(st);\n        vector<bool>u(M,false); u[st]=true; for(int s=1;s<M;s++){ int l=o.back(),bo=-1; vector<int>c;\n            for(int j=0;j<M;j++){ if(u[j]) continue; if(ov[l][j]>bo){bo=ov[l][j];c.clear();c.push_back(j);}\n                else if(ov[l][j]==bo) c.push_back(j);} o.push_back(c[lr()%c.size()]); u[o.back()]=true;} return o;};\n    auto twoOpt=[&](vector<int>o)->vector<int>{ bool imp=true; while(imp){ imp=false;\n        for(int i=0;i<M-1;i++){ int os=0,ns=0; if(i>0){os+=ov[o[i-1]][o[i]];ns+=ov[o[i-1]][o[i+1]];}\n            os+=ov[o[i]][o[i+1]]; ns+=ov[o[i+1]][o[i]]; if(i+2<M){os+=ov[o[i+1]][o[i+2]];ns+=ov[o[i]][o[i+2]];}\n            if(ns>os){swap(o[i],o[i+1]);imp=true;}}} return o;};\n    auto orOpt=[&](vector<int>o)->vector<int>{ for(int it=0;it<10;it++){ bool imp=false;\n        for(int i=0;i<M;i++){ int w=o[i],rd=0; if(i>0) rd-=ov[o[i-1]][w]; if(i<M-1) rd-=ov[w][o[i+1]];\n            if(i>0&&i<M-1) rd+=ov[o[i-1]][o[i+1]]; auto gr=[&](int k)->int{return(k<i)?o[k]:o[k+1];};\n            int bd=0,bk=i; for(int j=0;j<=M-1;j++){ if(j==i) continue; int id=0;\n                int C=(j>0)?gr(j-1):-1,D=(j<M-1)?gr(j):-1; if(C!=-1) id+=ov[C][w]; if(D!=-1) id+=ov[w][D];\n                if(C!=-1&&D!=-1) id-=ov[C][D]; if(rd+id>bd){bd=rd+id;bk=j;}}\n            if(bk!=i){ vector<int>rm; for(int k=0;k<M;k++) if(k!=i) rm.push_back(o[k]); o.clear();\n                for(int k=0;k<bk;k++) o.push_back(rm[k]); o.push_back(w); for(int k=bk;k<M-1;k++) o.push_back(rm[k]);\n                imp=true;break;}} if(!imp) break;} return o;};\n    auto sa=[&](vector<int>o,unsigned seed)->vector<int>{ int curOv=totalOv(o); int bestOv=curOv; auto bestO=o;\n        mt19937 saRng(seed); uniform_int_distribution<int>distI(0,M-1); uniform_real_distribution<double>distD(0.0,1.0);\n        double temp=3.0; for(int it=0;it<300000;it++){ temp*=0.99998;\n            if(saRng()%3==0){ int i=distI(saRng),j=distI(saRng); if(i==j) continue; int w=o[i],rd=0;\n                if(i>0) rd-=ov[o[i-1]][w]; if(i<M-1) rd-=ov[w][o[i+1]]; if(i>0&&i<M-1) rd+=ov[o[i-1]][o[i+1]];\n                auto gr=[&](int k)->int{return(k<i)?o[k]:o[k+1];}; int C=(j>0)?gr(j-1):-1,D=(j<M-1)?gr(j):-1; int id=0;\n                if(C!=-1) id+=ov[C][w]; if(D!=-1) id+=ov[w][D]; if(C!=-1&&D!=-1) id-=ov[C][D]; int delta=rd+id;\n                if(delta>0||distD(saRng)<exp((double)delta/max(temp,0.001))){ o.erase(o.begin()+i); o.insert(o.begin()+j,w);\n                    curOv+=delta; if(curOv>bestOv){bestOv=curOv;bestO=o;}}}\n            else{ int i=distI(saRng),j=distI(saRng); if(i==j) continue; if(i>j) swap(i,j); int delta=0;\n                if(j==i+1){ if(i>0){delta-=ov[o[i-1]][o[i]];delta+=ov[o[i-1]][o[j]];}\n                    delta-=ov[o[i]][o[j]]; delta+=ov[o[j]][o[i]]; if(j+1<M){delta-=ov[o[j]][o[j+1]];delta+=ov[o[i]][o[j+1]];}}\n                else{ if(i>0){delta-=ov[o[i-1]][o[i]];delta+=ov[o[i-1]][o[j]];}\n                    if(i+1<M){delta-=ov[o[i]][o[i+1]];delta+=ov[o[j]][o[i+1]];}\n                    if(j>0){delta-=ov[o[j-1]][o[j]];delta+=ov[o[j-1]][o[i]];}\n                    if(j+1<M){delta-=ov[o[j]][o[j+1]];delta+=ov[o[i]][o[j+1]];}}\n                if(delta>0||distD(saRng)<exp((double)delta/max(temp,0.001))){ swap(o[i],o[j]); curOv+=delta;\n                    if(curOv>bestOv){bestOv=curOv;bestO=o;}}}} return bestO;};\n    const int INF=1e9;\n    auto dpStep=[&](const vector<int>&cur, vector<int>& nx, char c){ \n        fill(nx.begin(), nx.end(), INF); int ci=c-'A';\n        for(int q=0;q<225;q++){ if(cur[q]>=INF) continue; int qi=q/15,qj=q%15;\n            for(auto&[pi,pj]:cp[ci]){ int p=pi*15+pj; int nc=cur[q]+abs(pi-qi)+abs(pj-qj)+1; if(nc<nx[p]) nx[p]=nc;}}\n    };\n    auto dpGreedy=[&](int forceFirst)->string{ \n        vector<int>cur(225,INF), nx(225); cur[si*15+sj]=0; string S; vector<bool>used(M,false);\n        if(forceFirst>=0){ for(char c:t[forceFirst]) { dpStep(cur, nx, c); swap(cur, nx); } S+=t[forceFirst]; used[forceFirst]=true;}\n        for(int step=(forceFirst>=0?1:0);step<M;step++){ vector<pair<double,int>>cands;\n            for(int j=0;j<M;j++){ if(used[j]) continue; int mx=min(5,(int)S.size()),a=0;\n                for(int l=mx;l>=1;l--){ bool ok=true; for(int k=0;k<l;k++) if(S[S.size()-l+k]!=t[j][k]){ok=false;break;}\n                    if(ok){a=l;break;}} double hcost=(5-a)*10.0;\n                if(!S.empty()) hcost+=cd[S.back()-'A'][t[j][a]-'A']; else hcost+=cd[A[si][sj]-'A'][t[j][0]-'A'];\n                cands.push_back({hcost,j});} sort(cands.begin(),cands.end());\n            int topK=min(15,(int)cands.size()); int bestWord=-1,bestCost=INF; vector<int>bestNx(225); string bestExt;\n            for(int k=0;k<topK;k++){ int j=cands[k].second; int mx=min(5,(int)S.size()),a=0;\n                for(int l=mx;l>=1;l--){ bool ok=true; for(int kk=0;kk<l;kk++) if(S[S.size()-l+kk]!=t[j][kk]){ok=false;break;}\n                    if(ok){a=l;break;}} string ext=t[j].substr(a); auto tmpCur=cur;\n                for(char c:ext) { dpStep(tmpCur, nx, c); swap(tmpCur, nx); }\n                int cost=*min_element(tmpCur.begin(),tmpCur.end()); \n                if(cost<bestCost){bestCost=cost;bestWord=j;swap(bestNx,tmpCur);bestExt=ext;}}\n            S+=bestExt; used[bestWord]=true; swap(cur, bestNx);} return S;};\n    auto charGreedy=[&](double w1,double w2,double w3)->string{ vector<int>ml(M,0); vector<bool>matched(M,false); int nm=0;\n        string S; int ci=si,cj=sj; while(nm<M&&S.size()<5000){ int bchar=-1,bpi=-1,bpj=-1; double bscore=-1e18;\n            for(int c=0;c<26;c++){ int md=INT_MAX,pi=-1,pj=-1; for(auto&[i,j]:cp[c]){int d=abs(i-ci)+abs(j-cj);if(d<md){md=d;pi=i;pj=j;}}\n                int comp=0; double adv=0; for(int k=0;k<M;k++){ if(matched[k]) continue; int l=ml[k];\n                    while(l>0&&t[k][l]!=('A'+c)) l=fail[k][l]; if(t[k][l]==('A'+c)) l++;\n                    if(l==5) comp++; else if(l>ml[k]) adv+=(l-ml[k]);}\n                double score=comp*w1+adv*w2-md*w3; if(score>bscore){bscore=score;bchar=c;bpi=pi;bpj=pj;}}\n            S+=('A'+bchar); ci=bpi; cj=bpj;\n            for(int k=0;k<M;k++){ if(matched[k]) continue; int l=ml[k];\n                while(l>0&&t[k][l]!=('A'+bchar)) l=fail[k][l]; if(t[k][l]==('A'+bchar)) l++; ml[k]=l;\n                if(l==5){matched[k]=true;nm++;}}} return S;};\n    auto dpCharGreedy=[&]()->string{ \n        vector<int>cur(225,INF), nx(225), bestNx(225); cur[si*15+sj]=0; string S;\n        vector<int>ml(M,0); vector<bool>matched(M,false); int nm=0;\n        while(nm<M&&S.size()<5000){ int bchar=-1; int bestComp=-1,bestAdv=-1,bestCost=INF;\n            for(int c=0;c<26;c++){ dpStep(cur, nx, 'A'+c); int cost=*min_element(nx.begin(),nx.end());\n                int comp=0,adv=0; for(int k=0;k<M;k++){ if(matched[k]) continue; int l=ml[k];\n                    while(l>0&&t[k][l]!=('A'+c)) l=fail[k][l]; if(t[k][l]==('A'+c)) l++;\n                    if(l==5) comp++; else if(l>ml[k]) adv+=(l-ml[k]);}\n                bool better=false; if(comp>bestComp) better=true; else if(comp==bestComp){if(cost<bestCost) better=true; else if(cost==bestCost&&adv>bestAdv) better=true;}\n                if(better){bestComp=comp;bestAdv=adv;bestCost=cost;bchar=c;swap(bestNx,nx);}}\n            S+=('A'+bchar); swap(cur,bestNx);\n            for(int k=0;k<M;k++){ if(matched[k]) continue; int l=ml[k];\n                while(l>0&&t[k][l]!=('A'+bchar)) l=fail[k][l]; if(t[k][l]==('A'+bchar)) l++; ml[k]=l;\n                if(l==5){matched[k]=true;nm++;}}} return S;};\n    vector<string>candidates; vector<pair<int,vector<int>>>cs;\n    for(int s=0;s<M;s++){auto o=greedyR(s,s*997+1);o=twoOpt(o);cs.push_back({5*M-totalOv(o),o});}\n    sort(cs.begin(),cs.end()); cs.erase(unique(cs.begin(),cs.end(),[](auto&a,auto&b){return a.second==b.second;}),cs.end());\n    int topN=min((int)cs.size(),20); for(int i=0;i<topN;i++){ auto o=cs[i].second; o=orOpt(o); o=twoOpt(o); candidates.push_back(buildS(o));}\n    int saN=min((int)cs.size(),5); for(int i=0;i<saN;i++) for(int r=0;r<2;r++){ auto o=cs[i].second;\n        o=sa(o,i*12345+r*54321+1); o=twoOpt(o); candidates.push_back(buildS(o));}\n    for(int s=0;s<10;s++) candidates.push_back(dpGreedy(s));\n    candidates.push_back(dpGreedy(-1));\n    candidates.push_back(charGreedy(100,20,3)); candidates.push_back(charGreedy(200,30,5)); candidates.push_back(charGreedy(50,10,2));\n    candidates.push_back(dpCharGreedy());\n    auto dpEval=[&](const string&s)->int{ int L=s.size(); vector<int>cur(225,INF), nx(225); cur[si*15+sj]=0;\n        for(int i=0;i<L;i++){ dpStep(cur, nx, s[i]); swap(cur, nx);} return *min_element(cur.begin(),cur.end());};\n    string bs; int bc=INF; for(auto&ss:candidates){ int c=dpEval(ss); if(c<bc){bc=c;bs=ss;}}\n    int L=bs.size(); vector<vector<pair<int,int>>>dp(L+1,vector<pair<int,int>>(225,{INF,-1})); dp[0][si*15+sj]={0,-1};\n    for(int i=0;i<L;i++){ int ci=bs[i]-'A'; for(int q=0;q<225;q++){ if(dp[i][q].first>=INF) continue; int qi=q/15,qj=q%15;\n        for(auto&[pi,pj]:cp[ci]){ int p=pi*15+pj; int nc=dp[i][q].first+abs(pi-qi)+abs(pj-qj)+1;\n            if(nc<dp[i+1][p].first) dp[i+1][p]={nc,q};}}}\n    int be=0; bc=INF; for(int p=0;p<225;p++) if(dp[L][p].first<bc){bc=dp[L][p].first;be=p;}\n    vector<int>pp(L); int cr=be; for(int i=L-1;i>=0;i--){pp[i]=cr;cr=dp[i+1][cr].second;}\n    for(int i=0;i<L;i++) cout<<pp[i]/15<<\" \"<<pp[i]%15<<\"\\n\"; return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_POS = 500;\n\nint N, M;\ndouble eps;\nvector<vector<pair<int,int>>> shapes;\nvector<int> max_di, max_dj;\nvector<vector<pair<int,int>>> positions;\nvector<vector<vector<pair<int,int>>>> pos_cells;\nvector<vector<vector<int>>> cell_pos;\nint known[25][25];\nint query_count = 0;\ndouble current_cost = 0.0;\nvector<vector<double>> lw;\ndouble cov_val[25][25];\ndouble prob_oil_val[25][25];\n\nint drill_cell(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << '\\n';\n    cout.flush();\n    int v; cin >> v;\n    known[i][j] = v;\n    query_count++;\n    current_cost += 1.0;\n    return v;\n}\n\nint divine_cells(vector<pair<int,int>>& cells) {\n    int k = cells.size();\n    cout << \"q \" << k;\n    for (auto& [i, j] : cells) cout << \" \" << i << \" \" << j;\n    cout << '\\n';\n    cout.flush();\n    int v; cin >> v;\n    query_count++;\n    current_cost += 1.0 / sqrt(k);\n    return v;\n}\n\nbool submit_answer(vector<pair<int,int>>& cells) {\n    sort(cells.begin(), cells.end());\n    cells.erase(unique(cells.begin(), cells.end()), cells.end());\n    cout << \"a \" << cells.size();\n    for (auto& [i, j] : cells) cout << \" \" << i << \" \" << j;\n    cout << '\\n';\n    cout.flush();\n    int r; cin >> r;\n    if (r == 0) {\n        query_count++;\n        current_cost += 1.0;\n    }\n    return r == 1;\n}\n\nvoid normalize_weights(int k) {\n    double mx = -1e9;\n    int sz = positions[k].size();\n    for (int p = 0; p < sz; p++) if (lw[k][p] > mx) mx = lw[k][p];\n    double total = 0;\n    for (int p = 0; p < sz; p++) {\n        if (lw[k][p] > mx - 50.0) total += exp(lw[k][p] - mx);\n    }\n    if (total < 1e-30) {\n        for (int p = 0; p < sz; p++) lw[k][p] = 0.0;\n    } else {\n        for (int p = 0; p < sz; p++) {\n            if (lw[k][p] < mx - 50.0) lw[k][p] = -1e9;\n            else lw[k][p] -= mx;\n        }\n    }\n}\n\nvoid compute_prob_and_cov() {\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        cov_val[i][j] = 0;\n        prob_oil_val[i][j] = 1.0;\n    }\n    for (int k = 0; k < M; k++) {\n        double mx = -1e9;\n        int sz = positions[k].size();\n        for (int p = 0; p < sz; p++) if (lw[k][p] > mx) mx = lw[k][p];\n        double total = 0;\n        double wt[MAX_POS];\n        for (int p = 0; p < sz; p++) {\n            wt[p] = exp(lw[k][p] - mx);\n            total += wt[p];\n        }\n        if (total < 1e-30) continue;\n        for (int p = 0; p < sz; p++) {\n            double w = wt[p] / total;\n            if (w < 1e-9) continue;\n            for (auto& [ci, cj] : pos_cells[k][p]) {\n                cov_val[ci][cj] += w;\n                prob_oil_val[ci][cj] *= max(0.0, 1.0 - w);\n            }\n        }\n    }\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (known[i][j] >= 0) {\n            cov_val[i][j] = known[i][j];\n            prob_oil_val[i][j] = (known[i][j] > 0 ? 1.0 : 0.0);\n        } else {\n            prob_oil_val[i][j] = 1.0 - prob_oil_val[i][j];\n        }\n    }\n}\n\nvoid update_divine(const vector<pair<int,int>>& qcells, int obs) {\n    int ksz = qcells.size();\n    double sigma2 = ksz * eps * (1 - eps);\n    \n    int cnts[25][MAX_POS];\n    for (int k = 0; k < M; k++) {\n        memset(cnts[k], 0, sizeof(int) * positions[k].size());\n        for (auto& [i, j] : qcells) {\n            for (int p : cell_pos[k][i * N + j]) {\n                cnts[k][p]++;\n            }\n        }\n    }\n    \n    double E_X[25], Var_X[25];\n    for (int k = 0; k < M; k++) {\n        double mx = -1e9;\n        int sz = positions[k].size();\n        for (int p = 0; p < sz; p++) if (lw[k][p] > mx) mx = lw[k][p];\n        double total = 0;\n        double wt[MAX_POS];\n        for (int p = 0; p < sz; p++) {\n            wt[p] = exp(lw[k][p] - mx);\n            total += wt[p];\n        }\n        if (total < 1e-30) { E_X[k] = 0; Var_X[k] = 0; continue; }\n        \n        double EX = 0, EX2 = 0;\n        for (int p = 0; p < sz; p++) {\n            wt[p] /= total;\n            double c = cnts[k][p];\n            EX += wt[p] * c;\n            EX2 += wt[p] * c * c;\n        }\n        E_X[k] = EX;\n        Var_X[k] = EX2 - EX * EX;\n        if (Var_X[k] < 0) Var_X[k] = 0;\n    }\n    \n    double total_E = 0, total_Var = 0;\n    for (int k = 0; k < M; k++) {\n        total_E += E_X[k];\n        total_Var += Var_X[k];\n    }\n    \n    for (int k = 0; k < M; k++) {\n        double S_others = total_E - E_X[k];\n        double Var_others = total_Var - Var_X[k];\n        if (Var_others < 0) Var_others = 0;\n        \n        double total_var = sigma2 + Var_others * (1 - 2 * eps) * (1 - 2 * eps);\n        if (total_var < sigma2) total_var = sigma2;\n        \n        int sz = positions[k].size();\n        for (int p = 0; p < sz; p++) {\n            double ev = S_others + cnts[k][p];\n            double mean = ksz * eps + ev * (1 - 2 * eps);\n            double diff = obs - mean;\n            double penalty = diff * diff / (2 * total_var);\n            if (penalty > 10.0) penalty = 10.0;\n            lw[k][p] += -penalty;\n        }\n        normalize_weights(k);\n    }\n    compute_prob_and_cov();\n}\n\nvoid update_drill(int i, int j, int obs) {\n    if (obs == 0) {\n        for (int k = 0; k < M; k++) {\n            for (int p : cell_pos[k][i * N + j]) lw[k][p] = -1e9;\n            normalize_weights(k);\n        }\n    } else if (obs == M) {\n        for (int k = 0; k < M; k++) {\n            for (int p = 0; p < (int)positions[k].size(); p++) {\n                if (!binary_search(cell_pos[k][i * N + j].begin(), cell_pos[k][i * N + j].end(), p)) {\n                    lw[k][p] = -1e9;\n                }\n            }\n            normalize_weights(k);\n        }\n    } else {\n        double fc_arr[25];\n        for (int k = 0; k < M; k++) {\n            double mx = -1e9;\n            int sz = positions[k].size();\n            for (int p = 0; p < sz; p++) if (lw[k][p] > mx) mx = lw[k][p];\n            double total = 0;\n            double wt[MAX_POS];\n            for (int p = 0; p < sz; p++) {\n                wt[p] = exp(lw[k][p] - mx);\n                total += wt[p];\n            }\n            if (total < 1e-30) { fc_arr[k] = 0; continue; }\n            double covers = 0;\n            for (int p : cell_pos[k][i * N + j]) covers += wt[p];\n            fc_arr[k] = covers / total;\n        }\n        \n        for (int k = 0; k < M; k++) {\n            double P[25];\n            memset(P, 0, sizeof(P));\n            P[0] = 1.0;\n            for (int m = 0; m < M; m++) {\n                if (m == k) continue;\n                double p_m = max(0.0, min(1.0, fc_arr[m]));\n                double q_m = 1.0 - p_m;\n                for (int jj = M - 1; jj >= 0; jj--) {\n                    P[jj] = P[jj] * q_m + (jj > 0 ? P[jj-1] * p_m : 0.0);\n                }\n            }\n            \n            int sz = positions[k].size();\n            for (int p = 0; p < sz; p++) {\n                bool covers = binary_search(cell_pos[k][i * N + j].begin(), cell_pos[k][i * N + j].end(), p);\n                int base = covers ? 1 : 0;\n                double likelihood = 0.0;\n                if (obs - base >= 0 && obs - base < M) {\n                    likelihood = P[obs - base];\n                }\n                if (likelihood < 1e-9) likelihood = 1e-9;\n                double penalty = -log(likelihood);\n                if (penalty > 10.0) penalty = 10.0;\n                lw[k][p] += -penalty;\n            }\n            normalize_weights(k);\n        }\n    }\n    compute_prob_and_cov();\n}\n\nvector<pair<int,int>> get_answer() {\n    vector<pair<int,int>> ans;\n    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n        if (known[i][j] > 0) ans.push_back({i, j});\n        else if (known[i][j] < 0 && prob_oil_val[i][j] > 0.5) ans.push_back({i, j});\n    }\n    sort(ans.begin(), ans.end());\n    return ans;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> M >> eps;\n    shapes.resize(M);\n    for (int k = 0; k < M; k++) {\n        int d; cin >> d;\n        shapes[k].resize(d);\n        for (int l = 0; l < d; l++) cin >> shapes[k][l].first >> shapes[k][l].second;\n    }\n    max_di.resize(M); max_dj.resize(M);\n    for (int k = 0; k < M; k++) {\n        max_di[k] = max_dj[k] = 0;\n        for (auto& [i, j] : shapes[k]) { max_di[k] = max(max_di[k], i); max_dj[k] = max(max_dj[k], j); }\n    }\n    cell_pos.resize(M, vector<vector<int>>(N * N));\n    for (int k = 0; k < M; k++) {\n        vector<pair<int,int>> pos;\n        vector<vector<pair<int,int>>> cells;\n        int pidx = 0;\n        for (int di = 0; di <= N - 1 - max_di[k]; di++)\n            for (int dj = 0; dj <= N - 1 - max_dj[k]; dj++) {\n                pos.push_back({di, dj});\n                vector<pair<int,int>> c;\n                for (auto& [i, j] : shapes[k]) {\n                    int ci = di + i, cj = dj + j;\n                    c.push_back({ci, cj});\n                    cell_pos[k][ci * N + cj].push_back(pidx);\n                }\n                cells.push_back(c);\n                pidx++;\n            }\n        positions.push_back(pos);\n        pos_cells.push_back(cells);\n    }\n    memset(known, -1, sizeof(known));\n    for (int k = 0; k < M; k++) lw.push_back(vector<double>(positions[k].size(), 0.0));\n    compute_prob_and_cov();\n    \n    for (int i = 0; i < N && query_count < 2*N*N - 1; i++) {\n        vector<pair<int,int>> cells;\n        for (int j = 0; j < N; j++) if (known[i][j] < 0) cells.push_back({i, j});\n        if (cells.size() >= 2) update_divine(cells, divine_cells(cells));\n        else if (cells.size() == 1) update_drill(cells[0].first, cells[0].second, drill_cell(cells[0].first, cells[0].second));\n    }\n    for (int j = 0; j < N && query_count < 2*N*N - 1; j++) {\n        vector<pair<int,int>> cells;\n        for (int i = 0; i < N; i++) if (known[i][j] < 0) cells.push_back({i, j});\n        if (cells.size() >= 2) update_divine(cells, divine_cells(cells));\n        else if (cells.size() == 1) update_drill(cells[0].first, cells[0].second, drill_cell(cells[0].first, cells[0].second));\n    }\n    \n    int targeted_count = 0;\n    while (query_count < 2*N*N - 1 && targeted_count < 30) {\n        int best_k = -1; double max_ent = -1;\n        for (int k = 0; k < M; k++) {\n            double mx = -1e9;\n            for (auto& l : lw[k]) if (l > mx) mx = l;\n            double total = 0;\n            for (int p = 0; p < (int)positions[k].size(); p++) total += exp(lw[k][p] - mx);\n            if (total < 1e-30) continue;\n            double ent = 0;\n            for (int p = 0; p < (int)positions[k].size(); p++) {\n                double prob = exp(lw[k][p] - mx) / total;\n                if (prob > 1e-9 && prob < 1 - 1e-9) ent -= prob * log(prob);\n            }\n            if (ent > max_ent) { max_ent = ent; best_k = k; }\n        }\n        if (best_k == -1 || max_ent < 0.1) break;\n        \n        int best_p = max_element(lw[best_k].begin(), lw[best_k].end()) - lw[best_k].begin();\n        if (lw[best_k][best_p] < -1e8) break;\n        vector<pair<int,int>> qcells;\n        for (auto& cell : pos_cells[best_k][best_p]) {\n            if (known[cell.first][cell.second] < 0) qcells.push_back(cell);\n        }\n        if (qcells.size() >= 2) {\n            update_divine(qcells, divine_cells(qcells));\n            targeted_count++;\n        } else if (qcells.size() == 1) {\n            update_drill(qcells[0].first, qcells[0].second, drill_cell(qcells[0].first, qcells[0].second));\n            targeted_count++;\n        } else break;\n    }\n    \n    vector<pair<int,int>> last_ans;\n    while (query_count < 2 * N * N - 1) {\n        double exp_err = 0;\n        for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n            if (known[i][j] >= 0) continue;\n            double p = prob_oil_val[i][j];\n            exp_err += min(p, 1 - p);\n        }\n        \n        vector<pair<int,int>> ans = get_answer();\n        \n        bool should_answer = (exp_err < 1.0 || query_count >= 2 * N * N - 1);\n        \n        if (should_answer && ans != last_ans) {\n            if (submit_answer(ans)) return 0;\n            last_ans = ans;\n        }\n        \n        if (!should_answer || ans == last_ans) {\n            int bi = -1, bj = -1; double bent = -1;\n            for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) {\n                if (known[i][j] >= 0) continue;\n                double p = max(0.001, min(0.999, prob_oil_val[i][j]));\n                double ent = -p*log(p) - (1-p)*log(1-p);\n                if (ent > bent) { bent = ent; bi = i; bj = j; }\n            }\n            if (bi < 0) break;\n            update_drill(bi, bj, drill_cell(bi, bj));\n        }\n    }\n    \n    if (query_count < 2 * N * N) {\n        vector<pair<int,int>> final_ans = get_answer();\n        submit_answer(final_ans);\n    }\n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <climits>\nusing namespace std;\n\nint W, D, N;\nvector<vector<int>> a;\n\nlong long day_def(int d, const vector<int>& h) {\n    long long c = 0;\n    for (int k = 0; k < N; k++) { int area = h[k] * W; if (a[d][k] > area) c += 100LL * (a[d][k] - area); }\n    return c;\n}\n\nvoid get_bounds(const vector<int>& h, vector<int>& b) {\n    b.resize(N - 1); int y = 0;\n    for (int k = 0; k < N - 1; k++) { y += h[k]; b[k] = y; }\n}\n\nlong long bound_diff(const vector<int>& b1, const vector<int>& b2) {\n    int i = 0, j = 0; long long c = 0;\n    while (i < (int)b1.size() && j < (int)b2.size()) {\n        if (b1[i] == b2[j]) { i++; j++; } else if (b1[i] < b2[j]) { c++; i++; } else { c++; j++; }\n    }\n    c += (int)b1.size() - i + (int)b2.size() - j; return c;\n}\n\nvector<int> greedy_day(int d) {\n    vector<int> h(N, 1); int rem = W - N;\n    while (rem > 0) {\n        int bk = -1; long long br = -1;\n        for (int k = 0; k < N; k++) { int df = max(0, a[d][k] - h[k] * W); int nd = max(0, a[d][k] - (h[k] + 1) * W); long long r = df - nd;\n            if (r > br || (r == br && bk >= 0 && a[d][k] > a[d][bk])) { br = r; bk = k; } }\n        if (bk == -1 || br == 0) { int mx = -1; for (int k = 0; k < N; k++) if (a[d][k] > mx) { mx = a[d][k]; bk = k; } }\n        if (bk == -1) break; h[bk]++; rem--;\n    }\n    return h;\n}\n\nvector<int> adjust_toward(int d, vector<int> h, int max_iter=300) {\n    for (int iter = 0; iter < max_iter; iter++) {\n        int bk = -1; long long br = -1;\n        for (int k = 0; k < N; k++) { int df = max(0, a[d][k] - h[k] * W); int nd = max(0, a[d][k] - (h[k] + 1) * W); long long r = df - nd; if (r > br) { br = r; bk = k; } }\n        if (bk == -1 || br == 0) break;\n        int bk2 = -1; long long min_inc = LLONG_MAX;\n        for (int k = 0; k < N; k++) { if (h[k] > 1 && k != bk) { int od = max(0, a[d][k] - h[k] * W); int nd = max(0, a[d][k] - (h[k] - 1) * W); if (nd - od < min_inc) { min_inc = nd - od; bk2 = k; } } }\n        if (bk2 == -1) break; h[bk]++; h[bk2]--;\n    }\n    return h;\n}\n\nlong long total_cost(const vector<vector<int>>& h) {\n    long long c = 0;\n    for (int d = 0; d < D; d++) c += day_def(d, h[d]);\n    for (int d = 1; d < D; d++) { vector<int> b1, b2; get_bounds(h[d-1], b1); get_bounds(h[d], b2); c += bound_diff(b1, b2) * W; }\n    return c;\n}\n\nint main(){\n    ios_base::sync_with_stdio(false); cin.tie(nullptr);\n    cin >> W >> D >> N;\n    a.resize(D, vector<int>(N));\n    for (int d = 0; d < D; d++) for (int k = 0; k < N; k++) cin >> a[d][k];\n    \n    mt19937 rng(42); uniform_real_distribution<double> uni(0, 1);\n    \n    vector<int> fixed_h(N, 1);\n    { int rem = W - N; while (rem > 0) { int bk = -1; long long bs = -1;\n      for (int k = 0; k < N; k++) { long long td = 0, ntd = 0; for (int d = 0; d < D; d++) { td += max(0, a[d][k] - fixed_h[k] * W); ntd += max(0, a[d][k] - (fixed_h[k] + 1) * W); } if (td - ntd > bs) { bs = td - ntd; bk = k; } }\n      if (bk == -1) break; fixed_h[bk]++; rem--; } }\n    \n    { vector<int> ch = fixed_h; long long cc = 0; for (int d = 0; d < D; d++) cc += day_def(d, ch);\n      long long bc = cc; auto st = chrono::steady_clock::now();\n      for (int it = 0; it < 200000; it++) { if (it % 20000 == 0) { double el = chrono::duration<double>(chrono::steady_clock::now() - st).count(); if (el > 0.05) break; }\n        int k1 = (int)(rng() % N), k2 = (int)(rng() % N); if (k1 == k2 || ch[k1] <= 1) continue;\n        long long delta = 0; for (int d = 0; d < D; d++) { delta += 100LL*(max(0,a[d][k1]-(ch[k1]-1)*W)-max(0,a[d][k1]-ch[k1]*W)); delta += 100LL*(max(0,a[d][k2]-(ch[k2]+1)*W)-max(0,a[d][k2]-ch[k2]*W)); }\n        double el = chrono::duration<double>(chrono::steady_clock::now() - st).count();\n        double temp = 5e6*max(1e-4,1.0-el/0.05); if (delta <= 0 || exp(-(double)delta/temp) > uni(rng)) { ch[k1]--; ch[k2]++; cc += delta; if (cc < bc) { bc = cc; fixed_h = ch; } } } }\n    \n    vector<vector<int>> greedy_seq(D);\n    for (int d = 0; d < D; d++) greedy_seq[d] = greedy_day(d);\n    \n    auto gen_cands = [&](bool use_dp_res, const vector<vector<int>>& dp_res) {\n        vector<vector<vector<int>>> cands(D);\n        for (int d = 0; d < D; d++) {\n            cands[d].push_back(greedy_seq[d]);\n            cands[d].push_back(fixed_h);\n            cands[d].push_back(adjust_toward(d, fixed_h));\n            \n            for (int dd = max(0, d-3); dd <= min(D-1, d+3); dd++) {\n                if (dd == d) continue;\n                cands[d].push_back(adjust_toward(d, greedy_seq[dd]));\n                for (int i = 0; i < 3; i++) {\n                    vector<int> h = greedy_seq[dd]; int rem = 2 + (int)(rng() % 8);\n                    for (int j = 0; j < rem; j++) { int k1 = (int)(rng()%N), k2 = (int)(rng()%N); if (k1!=k2 && h[k1]>1) { h[k1]--; h[k2]++; } }\n                    cands[d].push_back(adjust_toward(d, h, 50));\n                }\n            }\n            \n            // Morph from adjacent greedy\n            for (int dd : {d-1, d+1}) {\n                if (dd < 0 || dd >= D) continue;\n                vector<int> h = greedy_seq[dd];\n                vector<int> src_b, tgt_b;\n                get_bounds(greedy_seq[dd], src_b);\n                get_bounds(greedy_seq[d], tgt_b);\n                for (int step = 0; step < 25; step++) {\n                    int best_b = -1, best_diff = 0;\n                    for (int b = 0; b < N-1; b++) { int diff = tgt_b[b] - src_b[b]; if (abs(diff) > abs(best_diff)) { best_diff = diff; best_b = b; } }\n                    if (best_b == -1 || best_diff == 0) break;\n                    int dir = (best_diff > 0) ? 1 : -1;\n                    int kd = (dir > 0) ? best_b + 1 : best_b;\n                    int ki = (dir > 0) ? best_b : best_b + 1;\n                    if (h[kd] <= 1) break;\n                    h[kd]--; h[ki]++; src_b[best_b] += dir;\n                    h = adjust_toward(d, h, 3);\n                    get_bounds(h, src_b);\n                    cands[d].push_back(h);\n                }\n            }\n            \n            // Add DP result as candidate\n            if (use_dp_res) {\n                cands[d].push_back(dp_res[d]);\n                // Also adjust DP result of adjacent days\n                for (int dd : {d-1, d+1}) {\n                    if (dd < 0 || dd >= D) continue;\n                    cands[d].push_back(adjust_toward(d, dp_res[dd]));\n                }\n            }\n            \n            // Common boundary positions\n            {\n                vector<vector<int>> all_bnds(D);\n                for (int dd = 0; dd < D; dd++) get_bounds(greedy_seq[dd], all_bnds[dd]);\n                for (int b = 0; b < N-1; b++) {\n                    vector<int> positions;\n                    for (int dd = 0; dd < D; dd++) positions.push_back(all_bnds[dd][b]);\n                    sort(positions.begin(), positions.end());\n                    // Try median position\n                    int med = positions[D/2];\n                    vector<int> h = greedy_seq[d];\n                    vector<int> hb; get_bounds(h, hb);\n                    int shift = med - hb[b];\n                    if (shift != 0 && b+1 < N && h[b] + shift >= 1 && h[b+1] - shift >= 1) {\n                        h[b] += shift; h[b+1] -= shift;\n                        cands[d].push_back(adjust_toward(d, h, 20));\n                    }\n                }\n            }\n            \n            vector<int> min_h(N); int sum_min = 0;\n            for (int k = 0; k < N; k++) { min_h[k] = (a[d][k] + W - 1) / W; sum_min += min_h[k]; }\n            int extra = W - sum_min;\n            if (extra >= 0) { cands[d].push_back(adjust_toward(d, min_h)); }\n            else {\n                vector<int> ch = min_h; int rem = -extra;\n                while (rem > 0) { int bk = -1; long long mi = LLONG_MAX; for (int k = 0; k < N; k++) if (ch[k]>1) { int od=max(0,a[d][k]-ch[k]*W),nd=max(0,a[d][k]-(ch[k]-1)*W); if(nd-od<mi){mi=nd-od;bk=k;} } if(bk==-1)break;ch[bk]--;rem--; }\n                cands[d].push_back(adjust_toward(d, ch));\n            }\n            \n            vector<vector<int>> valid; for (auto& c : cands[d]) { if ((int)c.size()!=N) continue; bool ok=true; int s=0; for(int k=0;k<N;k++){if(c[k]<1){ok=false;break;}s+=c[k];} if(ok&&s==W) valid.push_back(c); }\n            cands[d] = valid; sort(cands[d].begin(), cands[d].end()); cands[d].erase(unique(cands[d].begin(), cands[d].end()), cands[d].end());\n            if ((int)cands[d].size() > 120) { sort(cands[d].begin(), cands[d].end(), [&](const vector<int>& x, const vector<int>& y) { return day_def(d, x) < day_def(d, y); }); cands[d].resize(120); }\n        }\n        return cands;\n    };\n    \n    // First DP pass\n    auto cands = gen_cands(false, vector<vector<int>>());\n    \n    auto run_dp = [&](vector<vector<vector<int>>>& cands) -> vector<vector<int>> {\n        vector<int> ksz(D); int maxK = 0;\n        for (int d = 0; d < D; d++) { ksz[d] = cands[d].size(); maxK = max(maxK, ksz[d]); }\n        vector<vector<long long>> dp(D, vector<long long>(maxK, LLONG_MAX)); vector<vector<int>> par(D, vector<int>(maxK, -1));\n        vector<vector<long long>> cdef(D); vector<vector<vector<int>>> cbnd(D);\n        for (int d = 0; d < D; d++) { cdef[d].resize(ksz[d]); cbnd[d].resize(ksz[d]); for (int i = 0; i < ksz[d]; i++) { cdef[d][i] = day_def(d, cands[d][i]); get_bounds(cands[d][i], cbnd[d][i]); } }\n        for (int k = 0; k < ksz[0]; k++) dp[0][k] = cdef[0][k];\n        for (int d = 1; d < D; d++) for (int k = 0; k < ksz[d]; k++) for (int j = 0; j < ksz[d-1]; j++) { if (dp[d-1][j] == LLONG_MAX) continue; long long cost = dp[d-1][j] + bound_diff(cbnd[d-1][j], cbnd[d][k]) * W + cdef[d][k]; if (cost < dp[d][k]) { dp[d][k] = cost; par[d][k] = j; } }\n        long long best_dp = LLONG_MAX; int best_k = -1;\n        for (int k = 0; k < ksz[D-1]; k++) if (dp[D-1][k] < best_dp) { best_dp = dp[D-1][k]; best_k = k; }\n        vector<vector<int>> res(D); { int ck = best_k; for (int d = D-1; d >= 0; d--) { res[d] = cands[d][ck]; ck = par[d][ck]; } }\n        return res;\n    };\n    \n    auto dp_res = run_dp(cands);\n    \n    // Second DP pass with DP result as candidates\n    {\n        auto cands2 = gen_cands(true, dp_res);\n        auto dp_res2 = run_dp(cands2);\n        if (total_cost(dp_res2) < total_cost(dp_res)) dp_res = dp_res2;\n    }\n    \n    auto sa_run = [&](vector<vector<int>> cur_h, double time_limit, int seed) -> pair<long long, vector<vector<int>>> {\n        mt19937 lr(seed); uniform_real_distribution<double> lu(0, 1);\n        vector<vector<int>> cb(D); vector<long long> pc(D, 0);\n        for (int d = 0; d < D; d++) get_bounds(cur_h[d], cb[d]);\n        for (int d = 1; d < D; d++) pc[d] = bound_diff(cb[d-1], cb[d]) * W;\n        long long cc = 0; for (int d = 0; d < D; d++) cc += day_def(d, cur_h[d]); for (int d = 1; d < D; d++) cc += pc[d];\n        long long bc = cc; vector<vector<int>> bh = cur_h;\n        auto st = chrono::steady_clock::now(); long long it = 0; double el = 0;\n        while (true) { \n            if (++it % 5000 == 0) { el = chrono::duration<double>(chrono::steady_clock::now() - st).count(); if (el > time_limit) break; }\n            int mt = (int)(lr() % 100);\n            if (mt < 25) {\n                int d=(int)(lr()%D), b=(int)(lr()%(N-1)), dir = (lr()%2)?1:-1;\n                int kd = (dir>0)?b+1:b, ki = (dir>0)?b:b+1;\n                if (cur_h[d][kd] <= 1) continue;\n                long long dd = 100LL*(max(0,a[d][kd]-(cur_h[d][kd]-1)*W)-max(0,a[d][kd]-cur_h[d][kd]*W)) + 100LL*(max(0,a[d][ki]-(cur_h[d][ki]+1)*W)-max(0,a[d][ki]-cur_h[d][ki]*W));\n                cur_h[d][kd]--; cur_h[d][ki]++; cb[d][b] += dir;\n                long long npd = (d>0?bound_diff(cb[d-1],cb[d])*W:0) + (d<D-1?bound_diff(cb[d],cb[d+1])*W:0);\n                long long opd = (d>0?pc[d]:0) + (d<D-1?pc[d+1]:0);\n                long long delta = dd + npd - opd;\n                double temp = 3e6*max(1e-5,1.0-el/time_limit);\n                if (delta <= 0 || exp(-(double)delta/temp) > lu(lr)) { cc += delta; if(d>0)pc[d]=bound_diff(cb[d-1],cb[d])*W; if(d<D-1)pc[d+1]=bound_diff(cb[d],cb[d+1])*W; if(cc<bc){bc=cc;bh=cur_h;} }\n                else { cur_h[d][kd]++; cur_h[d][ki]--; cb[d][b] -= dir; }\n            } else if (mt < 50) {\n                if(D<2) continue;\n                int d=1+(int)(lr()%(D-1)), b=(int)(lr()%(N-1));\n                int diff=cb[d-1][b]-cb[d][b]; if(diff==0)continue; int dir=(diff>0)?1:-1;\n                int kd=(dir>0)?b+1:b, ki=(dir>0)?b:b+1; if(cur_h[d][kd]<=1)continue;\n                long long dd=100LL*(max(0,a[d][kd]-(cur_h[d][kd]-1)*W)-max(0,a[d][kd]-cur_h[d][kd]*W))+100LL*(max(0,a[d][ki]-(cur_h[d][ki]+1)*W)-max(0,a[d][ki]-cur_h[d][ki]*W));\n                cur_h[d][kd]--;cur_h[d][ki]++;cb[d][b]+=dir;\n                long long npd=(d>0?bound_diff(cb[d-1],cb[d])*W:0)+(d<D-1?bound_diff(cb[d],cb[d+1])*W:0);\n                long long opd=(d>0?pc[d]:0)+(d<D-1?pc[d+1]:0); long long delta=dd+npd-opd;\n                double temp=3e6*max(1e-5,1.0-el/time_limit);\n                if(delta<=0||exp(-(double)delta/temp)>lu(lr)){cc+=delta;if(d>0)pc[d]=bound_diff(cb[d-1],cb[d])*W;if(d<D-1)pc[d+1]=bound_diff(cb[d],cb[d+1])*W;if(cc<bc){bc=cc;bh=cur_h;}}\n                else{cur_h[d][kd]++;cur_h[d][ki]--;cb[d][b]-=dir;}\n            } else if (mt < 65) {\n                int d=(int)(lr()%D), k1=(int)(lr()%N), k2=(int)(lr()%N); if(k1==k2||cur_h[d][k1]<=1) continue;\n                long long dd = 100LL*(max(0,a[d][k1]-(cur_h[d][k1]-1)*W)-max(0,a[d][k1]-cur_h[d][k1]*W)) + 100LL*(max(0,a[d][k2]-(cur_h[d][k2]+1)*W)-max(0,a[d][k2]-cur_h[d][k2]*W));\n                cur_h[d][k1]--; cur_h[d][k2]++; int lo=min(k1,k2),hi=max(k1,k2); int ds=(k1<k2)?-1:1; for(int i=lo;i<hi;i++)cb[d][i]+=ds;\n                long long npd=(d>0?bound_diff(cb[d-1],cb[d])*W:0)+(d<D-1?bound_diff(cb[d],cb[d+1])*W:0);\n                long long opd=(d>0?pc[d]:0)+(d<D-1?pc[d+1]:0); long long delta=dd+npd-opd;\n                double temp=3e6*max(1e-5,1.0-el/time_limit);\n                if(delta<=0||exp(-(double)delta/temp)>lu(lr)){cc+=delta;if(d>0)pc[d]=bound_diff(cb[d-1],cb[d])*W;if(d<D-1)pc[d+1]=bound_diff(cb[d],cb[d+1])*W;if(cc<bc){bc=cc;bh=cur_h;}}\n                else{cur_h[d][k1]++;cur_h[d][k2]--;for(int i=lo;i<hi;i++)cb[d][i]-=ds;}\n            } else if (mt < 80) {\n                if(D<2) continue;\n                int d=1+(int)(lr()%(D-1)), b=(int)(lr()%(N-1));\n                int target=cb[d-1][b]; int cur=cb[d][b]; int shift=target-cur; if(shift==0)continue;\n                int u=min(abs(shift), 3+(int)(lr()%5)); int dir=(shift>0)?1:-1;\n                int kd=(dir>0)?b+1:b, ki=(dir>0)?b:b+1;\n                if(cur_h[d][kd]<=u)continue;\n                long long dd=100LL*(max(0,a[d][kd]-(cur_h[d][kd]-u)*W)-max(0,a[d][kd]-cur_h[d][kd]*W))+100LL*(max(0,a[d][ki]-(cur_h[d][ki]+u)*W)-max(0,a[d][ki]-cur_h[d][ki]*W));\n                cur_h[d][kd]-=u;cur_h[d][ki]+=u;cb[d][b]+=dir*u;\n                long long npd=(d>0?bound_diff(cb[d-1],cb[d])*W:0)+(d<D-1?bound_diff(cb[d],cb[d+1])*W:0);\n                long long opd=(d>0?pc[d]:0)+(d<D-1?pc[d+1]:0); long long delta=dd+npd-opd;\n                double temp=3e6*max(1e-5,1.0-el/time_limit);\n                if(delta<=0||exp(-(double)delta/temp)>lu(lr)){cc+=delta;if(d>0)pc[d]=bound_diff(cb[d-1],cb[d])*W;if(d<D-1)pc[d+1]=bound_diff(cb[d],cb[d+1])*W;if(cc<bc){bc=cc;bh=cur_h;}}\n                else{cur_h[d][kd]+=u;cur_h[d][ki]-=u;cb[d][b]-=dir*u;}\n            } else if (mt < 92) {\n                int d=(int)(lr()%D),k1=(int)(lr()%N),k2=(int)(lr()%N); if(k1==k2)continue; int u=2+(int)(lr()%4); if(cur_h[d][k1]<=u)continue;\n                long long dd=100LL*(max(0,a[d][k1]-(cur_h[d][k1]-u)*W)-max(0,a[d][k1]-cur_h[d][k1]*W))+100LL*(max(0,a[d][k2]-(cur_h[d][k2]+u)*W)-max(0,a[d][k2]-cur_h[d][k2]*W));\n                cur_h[d][k1]-=u;cur_h[d][k2]+=u; int lo=min(k1,k2),hi=max(k1,k2); int ds=(k1<k2)?-1:1; for(int i=lo;i<hi;i++)cb[d][i]+=ds*u;\n                long long npd=(d>0?bound_diff(cb[d-1],cb[d])*W:0)+(d<D-1?bound_diff(cb[d],cb[d+1])*W:0);\n                long long opd=(d>0?pc[d]:0)+(d<D-1?pc[d+1]:0); long long delta=dd+npd-opd;\n                double temp=3e6*max(1e-5,1.0-el/time_limit);\n                if(delta<=0||exp(-(double)delta/temp)>lu(lr)){cc+=delta;if(d>0)pc[d]=bound_diff(cb[d-1],cb[d])*W;if(d<D-1)pc[d+1]=bound_diff(cb[d],cb[d+1])*W;if(cc<bc){bc=cc;bh=cur_h;}}\n                else{cur_h[d][k1]+=u;cur_h[d][k2]-=u;for(int i=lo;i<hi;i++)cb[d][i]-=ds*u;}\n            } else {\n                if(D<2) continue;\n                int d=(int)(lr()%(D-1)), b=(int)(lr()%(N-1));\n                int diff=cb[d+1][b]-cb[d][b]; if(diff==0)continue;\n                int dir_d=(diff>0)?1:-1; int dir_d1=-dir_d;\n                int kd_d=(dir_d>0)?b+1:b, ki_d=(dir_d>0)?b:b+1;\n                int kd_d1=(dir_d1>0)?b+1:b, ki_d1=(dir_d1>0)?b:b+1;\n                if(cur_h[d][kd_d]<=1||cur_h[d+1][kd_d1]<=1)continue;\n                long long dd=100LL*(max(0,a[d][kd_d]-(cur_h[d][kd_d]-1)*W)-max(0,a[d][kd_d]-cur_h[d][kd_d]*W))+100LL*(max(0,a[d][ki_d]-(cur_h[d][ki_d]+1)*W)-max(0,a[d][ki_d]-cur_h[d][ki_d]*W));\n                dd+=100LL*(max(0,a[d+1][kd_d1]-(cur_h[d+1][kd_d1]-1)*W)-max(0,a[d+1][kd_d1]-cur_h[d+1][kd_d1]*W))+100LL*(max(0,a[d+1][ki_d1]-(cur_h[d+1][ki_d1]+1)*W)-max(0,a[d+1][ki_d1]-cur_h[d+1][ki_d1]*W));\n                cur_h[d][kd_d]--;cur_h[d][ki_d]++;cb[d][b]+=dir_d;\n                cur_h[d+1][kd_d1]--;cur_h[d+1][ki_d1]++;cb[d+1][b]+=dir_d1;\n                long long npd=0; if(d>0)npd+=bound_diff(cb[d-1],cb[d])*W; npd+=bound_diff(cb[d],cb[d+1])*W; if(d+1<D-1)npd+=bound_diff(cb[d+1],cb[d+2])*W;\n                long long opd=0; if(d>0)opd+=pc[d]; opd+=pc[d+1]; if(d+1<D-1)opd+=pc[d+2];\n                long long delta=dd+npd-opd; double temp=3e6*max(1e-5,1.0-el/time_limit);\n                if(delta<=0||exp(-(double)delta/temp)>lu(lr)){cc+=delta;if(d>0)pc[d]=bound_diff(cb[d-1],cb[d])*W;pc[d+1]=bound_diff(cb[d],cb[d+1])*W;if(d+1<D-1)pc[d+2]=bound_diff(cb[d+1],cb[d+2])*W;if(cc<bc){bc=cc;bh=cur_h;}}\n                else{cur_h[d][kd_d]++;cur_h[d][ki_d]--;cb[d][b]-=dir_d;cur_h[d+1][kd_d1]++;cur_h[d+1][ki_d1]--;cb[d+1][b]-=dir_d1;}\n            }\n        }\n        return {bc, bh};\n    };\n    \n    vector<pair<long long, vector<vector<int>>>> starts;\n    starts.push_back({total_cost(dp_res), dp_res});\n    starts.push_back({total_cost(vector<vector<int>>(D, fixed_h)), vector<vector<int>>(D, fixed_h)});\n    starts.push_back({total_cost(greedy_seq), greedy_seq});\n    sort(starts.begin(), starts.end());\n    \n    long long gbc = starts[0].first; vector<vector<int>> gbh = starts[0].second;\n    auto tst = chrono::steady_clock::now(); double tb = 2.8;\n    \n    for (int s = 0; s < min(3, (int)starts.size()); s++) {\n        double el = chrono::duration<double>(chrono::steady_clock::now() - tst).count();\n        double al = (s == 0) ? tb * 0.85 : tb * 0.10;\n        if (el + al > tb) al = tb - el;\n        if (al < 0.03) break;\n        auto [cost, h] = sa_run(starts[s].second, al, 42 + s * 7919);\n        if (cost < gbc) { gbc = cost; gbh = h; }\n    }\n    \n    for (int d = 0; d < D; d++) { int y = 0; for (int k = 0; k < N; k++) { cout << y << \" 0 \" << y + gbh[d][k] << \" \" << W << \"\\n\"; y += gbh[d][k]; } }\n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nlong long bmod[81];\nlong long a[81];\nlong long s_val[180];\nint ops[81];\nint op_p[81];\nint op_q[81];\nint L = 0;\n\nint best_ops[81], best_op_p[81], best_op_q[81];\nint best_L = 0;\nlong long best_total_score = 0;\n\nlong long best_score[9][10];\nlong long best_counts[9][10][20];\nlong long current_counts[20];\n\nstruct FastRNG {\n    unsigned long long x = 123456789, y = 362436069, z = 521288629;\n    unsigned long long operator()() {\n        unsigned long long t;\n        x ^= x << 16; x ^= x >> 5; x ^= x << 1;\n        t = x; x = y; y = z; z = t ^ x ^ y;\n        return z;\n    }\n};\n\nFastRNG rng;\n\nvoid dfs(int m, int remaining_ops, long long current_values[9], int used_ops, int subgrid_idx) {\n    long long score = 0;\n    for (int i = 0; i < 9; i++) score += current_values[i];\n    if (score > best_score[subgrid_idx][used_ops]) {\n        best_score[subgrid_idx][used_ops] = score;\n        memcpy(best_counts[subgrid_idx][used_ops], current_counts, sizeof(current_counts));\n    }\n    \n    if (remaining_ops == 0 || m == 20) return;\n\n    dfs(m + 1, remaining_ops, current_values, used_ops, subgrid_idx);\n\n    for (int i = 1; i <= remaining_ops; i++) {\n        current_counts[m]++;\n        for (int j = 0; j < 9; j++) {\n            current_values[j] += s_val[m * 9 + j];\n            if (current_values[j] >= MOD) current_values[j] -= MOD;\n        }\n        dfs(m + 1, remaining_ops - i, current_values, used_ops + i, subgrid_idx);\n    }\n    for (int i = 1; i <= remaining_ops; i++) {\n        current_counts[m]--;\n        for (int j = 0; j < 9; j++) {\n            current_values[j] -= s_val[m * 9 + j];\n            if (current_values[j] < 0) current_values[j] += MOD;\n        }\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 < 81; i++) cin >> a[i];\n    for (int m = 0; m < 20; m++)\n        for (int i = 0; i < 9; i++)\n            cin >> s_val[m * 9 + i];\n            \n    auto start_time = chrono::high_resolution_clock::now();\n    \n    // Phase 1: Exhaustive search for optimal independent subgrid configurations\n    for (int j = 0; j < 9; j++) {\n        int pj = (j / 3) * 3;\n        int qj = (j % 3) * 3;\n        long long initial_values[9];\n        for (int i = 0; i < 3; i++) {\n            for (int jj = 0; jj < 3; jj++) {\n                initial_values[i * 3 + jj] = a[(pj + i) * 9 + (qj + jj)];\n            }\n        }\n        memset(current_counts, 0, sizeof(current_counts));\n        memset(best_score[j], 0, sizeof(best_score[j]));\n        dfs(0, 9, initial_values, 0, j);\n    }\n    \n    // Phase 2: Knapsack DP to distribute operations optimally\n    long long dp[10][82];\n    int choice[10][82];\n    memset(dp, -1, sizeof(dp));\n    dp[0][0] = 0;\n    for (int i = 0; i < 9; i++) {\n        for (int k = 0; k <= 81; k++) {\n            if (dp[i][k] < 0) continue;\n            for (int kj = 0; kj <= 9; kj++) {\n                if (k + kj <= 81) {\n                    if (dp[i][k] + best_score[i][kj] > dp[i+1][k+kj]) {\n                        dp[i+1][k+kj] = dp[i][k] + best_score[i][kj];\n                        choice[i+1][k+kj] = kj;\n                    }\n                }\n            }\n        }\n    }\n    \n    long long max_total_score = 0;\n    int best_total_k = 0;\n    for (int k = 0; k <= 81; k++) {\n        if (dp[9][k] > max_total_score) {\n            max_total_score = dp[9][k];\n            best_total_k = k;\n        }\n    }\n    \n    int current_k = best_total_k;\n    int optimal_k[9];\n    for (int i = 8; i >= 0; i--) {\n        int kj = choice[i+1][current_k];\n        optimal_k[i] = kj;\n        current_k -= kj;\n    }\n    \n    // Build initial board and operations array from DP results\n    for (int i = 0; i < 81; i++) bmod[i] = a[i];\n    L = 0;\n    for (int j = 0; j < 9; j++) {\n        int pj = (j / 3) * 3;\n        int qj = (j % 3) * 3;\n        int kj = optimal_k[j];\n        for (int m = 0; m < 20; m++) {\n            for (int c = 0; c < best_counts[j][kj][m]; c++) {\n                ops[L] = m;\n                op_p[L] = pj;\n                op_q[L] = qj;\n                for (int i = 0; i < 3; i++) {\n                    for (int jj = 0; jj < 3; jj++) {\n                        int u = (pj + i) * 9 + (qj + jj);\n                        long long nv = bmod[u] + s_val[m * 9 + i * 3 + jj];\n                        if (nv >= MOD) nv -= MOD;\n                        bmod[u] = nv;\n                    }\n                }\n                L++;\n            }\n        }\n    }\n    \n    long long score = 0;\n    for (int i = 0; i < 81; i++) score += bmod[i];\n    \n    best_total_score = score;\n    best_L = L;\n    memcpy(best_ops, ops, L * sizeof(int));\n    memcpy(best_op_p, op_p, L * sizeof(int));\n    memcpy(best_op_q, op_q, L * sizeof(int));\n    \n    // Phase 3: Simulated Annealing for overlapping synergies\n    double start_temp = 1e10, end_temp = 1e4;\n    auto sa_start_time = chrono::high_resolution_clock::now();\n    double sa_time_limit = 1.9 - chrono::duration<double>(sa_start_time - start_time).count();\n    \n    int iter = 0;\n    while (true) {\n        iter++;\n        if (iter % 10000 == 0) {\n            auto now = chrono::high_resolution_clock::now();\n            double elapsed = chrono::duration<double>(now - sa_start_time).count();\n            if (elapsed > sa_time_limit) break;\n        }\n        \n        double temp = start_temp * pow(end_temp / start_temp, min(1.0, chrono::duration<double>(chrono::high_resolution_clock::now() - sa_start_time).count() / sa_time_limit));\n        \n        int move_type = rng() % 100;\n        long long delta = 0;\n        \n        if (move_type < 20 && L < K) {\n            int new_m = rng() % 20;\n            int new_p = rng() % 7;\n            int new_q = rng() % 7;\n            \n            long long old_score = 0;\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) old_score += bmod[(new_p + i) * 9 + (new_q + j)];\n            \n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (new_p + i) * 9 + (new_q + j);\n                long long nv = bmod[u] + s_val[new_m * 9 + i * 3 + j];\n                if (nv >= MOD) nv -= MOD;\n                bmod[u] = nv;\n            }\n            \n            long long new_score = 0;\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) new_score += bmod[(new_p + i) * 9 + (new_q + j)];\n            \n            delta = new_score - old_score;\n            \n            if (delta >= 0 || (delta / temp > -20 && exp(delta / temp) > (double)(rng() % 1000000) / 1000000.0)) {\n                ops[L] = new_m; op_p[L] = new_p; op_q[L] = new_q;\n                L++;\n                score += delta;\n                if (score > best_total_score) {\n                    best_total_score = score; best_L = L;\n                    memcpy(best_ops, ops, L * sizeof(int));\n                    memcpy(best_op_p, op_p, L * sizeof(int));\n                    memcpy(best_op_q, op_q, L * sizeof(int));\n                }\n            } else {\n                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                    int u = (new_p + i) * 9 + (new_q + j);\n                    long long nv = bmod[u] - s_val[new_m * 9 + i * 3 + j];\n                    if (nv < 0) nv += MOD;\n                    bmod[u] = nv;\n                }\n            }\n        } else if (move_type < 30 && L > 0) {\n            int idx = rng() % L;\n            int old_m = ops[idx], old_p = op_p[idx], old_q = op_q[idx];\n            \n            long long old_score = 0;\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) old_score += bmod[(old_p + i) * 9 + (old_q + j)];\n            \n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (old_p + i) * 9 + (old_q + j);\n                long long nv = bmod[u] - s_val[old_m * 9 + i * 3 + j];\n                if (nv < 0) nv += MOD;\n                bmod[u] = nv;\n            }\n            \n            long long new_score = 0;\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) new_score += bmod[(old_p + i) * 9 + (old_q + j)];\n            \n            delta = new_score - old_score;\n            \n            if (delta >= 0 || (delta / temp > -20 && exp(delta / temp) > (double)(rng() % 1000000) / 1000000.0)) {\n                ops[idx] = ops[L - 1]; op_p[idx] = op_p[L - 1]; op_q[idx] = op_q[L - 1];\n                L--;\n                score += delta;\n                if (score > best_total_score) {\n                    best_total_score = score; best_L = L;\n                    memcpy(best_ops, ops, L * sizeof(int));\n                    memcpy(best_op_p, op_p, L * sizeof(int));\n                    memcpy(best_op_q, op_q, L * sizeof(int));\n                }\n            } else {\n                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                    int u = (old_p + i) * 9 + (old_q + j);\n                    long long nv = bmod[u] + s_val[old_m * 9 + i * 3 + j];\n                    if (nv >= MOD) nv -= MOD;\n                    bmod[u] = nv;\n                }\n            }\n        } else if (L > 0) {\n            int idx = rng() % L;\n            int old_m = ops[idx], old_p = op_p[idx], old_q = op_q[idx];\n            \n            int r = rng() % 5;\n            int new_m = old_m, new_p = old_p, new_q = old_q;\n            if (r == 0) new_m = rng() % 20;\n            else if (r == 1) new_p = rng() % 7;\n            else if (r == 2) new_q = rng() % 7;\n            else if (r == 3) { new_p = rng() % 7; new_q = rng() % 7; }\n            else { new_m = rng() % 20; new_p = rng() % 7; new_q = rng() % 7; }\n            \n            if (new_m == old_m && new_p == old_p && new_q == old_q) continue;\n            \n            bool affected[81] = {false};\n            int affected_list[18];\n            int affected_count = 0;\n            \n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (old_p + i) * 9 + (old_q + j);\n                if (!affected[u]) { affected[u] = true; affected_list[affected_count++] = u; }\n            }\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (new_p + i) * 9 + (new_q + j);\n                if (!affected[u]) { affected[u] = true; affected_list[affected_count++] = u; }\n            }\n            \n            long long old_score = 0;\n            for (int k = 0; k < affected_count; k++) old_score += bmod[affected_list[k]];\n            \n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (old_p + i) * 9 + (old_q + j);\n                long long nv = bmod[u] - s_val[old_m * 9 + i * 3 + j];\n                if (nv < 0) nv += MOD;\n                bmod[u] = nv;\n            }\n            for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                int u = (new_p + i) * 9 + (new_q + j);\n                long long nv = bmod[u] + s_val[new_m * 9 + i * 3 + j];\n                if (nv >= MOD) nv -= MOD;\n                bmod[u] = nv;\n            }\n            \n            long long new_score = 0;\n            for (int k = 0; k < affected_count; k++) new_score += bmod[affected_list[k]];\n            \n            delta = new_score - old_score;\n            \n            if (delta >= 0 || (delta / temp > -20 && exp(delta / temp) > (double)(rng() % 1000000) / 1000000.0)) {\n                ops[idx] = new_m; op_p[idx] = new_p; op_q[idx] = new_q;\n                score += delta;\n                if (score > best_total_score) {\n                    best_total_score = score; best_L = L;\n                    memcpy(best_ops, ops, L * sizeof(int));\n                    memcpy(best_op_p, op_p, L * sizeof(int));\n                    memcpy(best_op_q, op_q, L * sizeof(int));\n                }\n            } else {\n                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                    int u = (new_p + i) * 9 + (new_q + j);\n                    long long nv = bmod[u] - s_val[new_m * 9 + i * 3 + j];\n                    if (nv < 0) nv += MOD;\n                    bmod[u] = nv;\n                }\n                for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {\n                    int u = (old_p + i) * 9 + (old_q + j);\n                    long long nv = bmod[u] + s_val[old_m * 9 + i * 3 + j];\n                    if (nv >= MOD) nv -= MOD;\n                    bmod[u] = nv;\n                }\n            }\n            for (int k = 0; k < affected_count; k++) affected[affected_list[k]] = false;\n        }\n    }\n    \n    cout << best_L << \"\\n\";\n    for (int i = 0; i < best_L; i++)\n        cout << best_ops[i] << \" \" << best_op_p[i] << \" \" << best_op_q[i] << \"\\n\";\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cstring>\n#include <climits>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N], grid[N][N];\nbool dispatched[N*N];\nint nxt_recv[N];\nint lr, lc, lh;\nint total_disp;\n\nint next_exp(int g) {\n    for (int j = 0; j < N; j++)\n        if (!dispatched[N*g+j]) return N*g+j;\n    return -1;\n}\n\nint main() {\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) cin >> A[i][j];\n    \n    memset(grid, -1, sizeof(grid));\n    fill(dispatched, dispatched+N*N, false);\n    fill(nxt_recv, nxt_recv+N, 0);\n    lr = 0; lc = 0; lh = -1; total_disp = 0;\n    \n    vector<string> acts(N);\n    // Turn 0: bomb small cranes to prevent deadlocks\n    for (int i = 0; i < N; i++) acts[i] += (i ? 'B' : '.');\n    \n    // Receive turn 0\n    for (int i = 0; i < N; i++)\n        if (nxt_recv[i] < N) grid[i][0] = A[i][nxt_recv[i]++];\n    \n    for (int t = 1; total_disp < N*N && (int)acts[0].size() < 9999; t++) {\n        // Step 1: Receive\n        for (int i = 0; i < N; i++) {\n            if (nxt_recv[i] < N && grid[i][0] == -1 && !(lr == i && lc == 0 && lh >= 0)) {\n                grid[i][0] = A[i][nxt_recv[i]++];\n            }\n        }\n        \n        // Step 2: Large crane action\n        char act = '.';\n        if (lh >= 0) {\n            // Holding: Deliver directly to the correct dispatch gate\n            int g = lh / N;\n            int tr = g, tc = N - 1;\n            \n            if (lr == tr && lc == tc) {\n                act = 'Q'; \n                grid[tr][tc] = lh; \n                lh = -1;\n            } else {\n                if (lr < tr) { lr++; act = 'D'; }\n                else if (lr > tr) { lr--; act = 'U'; }\n                else if (lc < tc) { lc++; act = 'R'; }\n                else { lc--; act = 'L'; }\n            }\n        } else {\n            // Not holding: Pick up the best available container\n            int bc = -1, bs = INT_MAX, br = -1, bcc = -1;\n            for (int r = 0; r < N; r++) {\n                for (int c = 0; c < N; c++) {\n                    if (grid[r][c] < 0) continue;\n                    int co = grid[r][c], g = co / N, e = next_exp(g);\n                    int d = abs(lr - r) + abs(lc - c);\n                    int s;\n                    \n                    if (e >= 0 && e == co) s = -10000 + d; // Expected container (minimizes M1)\n                    else if (c == 0 && nxt_recv[r] < N) {\n                        int nc = A[r][nxt_recv[r]], ng = nc / N, ne = next_exp(ng);\n                        s = (ne >= 0 && ne == nc) ? -5000 + d : -1000 + d; // Blocks expected container\n                    } else if (c == 0) {\n                        s = -500 + d; // Blocks receiving gate\n                    } else {\n                        s = d + 500; // Other (shouldn't exist in this strategy)\n                    }\n                    \n                    if (s < bs) { bs = s; bc = co; br = r; bcc = c; }\n                }\n            }\n            \n            if (bc >= 0) {\n                if (lr == br && lc == bcc) {\n                    act = 'P'; \n                    lh = bc; \n                    grid[br][bcc] = -1;\n                } else {\n                    if (lr < br) { lr++; act = 'D'; }\n                    else if (lr > br) { lr--; act = 'U'; }\n                    else if (lc < bcc) { lc++; act = 'R'; }\n                    else { lc--; act = 'L'; }\n                }\n            }\n        }\n        \n        acts[0] += act;\n        for (int i = 1; i < N; i++) acts[i] += '.';\n        \n        // Step 3: Dispatch\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] >= 0) {\n                dispatched[grid[i][N-1]] = true;\n                grid[i][N-1] = -1;\n                total_disp++;\n            }\n        }\n    }\n    \n    int ml = 0;\n    for (int i = 0; i < N; i++) ml = max(ml, (int)acts[i].size());\n    for (int i = 0; i < N; i++) {\n        while ((int)acts[i].size() < ml) acts[i] += '.';\n        cout << acts[i] << endl;\n    }\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <climits>\n#include <algorithm>\nusing namespace std;\ntypedef long long ll;\n\nstruct Edge { int to, rev; ll cap, cost; };\n\nvoid add_edge(vector<vector<Edge>>& g, int f, int t, ll cap, ll cost) {\n    g[f].push_back({t, (int)g[t].size(), cap, cost});\n    g[t].push_back({f, (int)g[f].size() - 1, 0, -cost});\n}\n\nll min_cost_flow(vector<vector<Edge>>& g, int s, int t, ll mf) {\n    int n = g.size();\n    vector<ll> h(n, 0);\n    ll res = 0, flow = 0;\n    while (flow < mf) {\n        priority_queue<pair<ll,int>, vector<pair<ll,int>>, greater<>> pq;\n        vector<ll> dist(n, 1e18);\n        vector<int> pv(n), pe(n);\n        dist[s] = 0; pq.push({0, s});\n        while (!pq.empty()) {\n            auto [d, v] = pq.top(); pq.pop();\n            if (dist[v] < d) continue;\n            for (int i = 0; i < (int)g[v].size(); i++) {\n                Edge& e = g[v][i];\n                if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {\n                    dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];\n                    pv[e.to] = v; pe[e.to] = i;\n                    pq.push({dist[e.to], e.to});\n                }\n            }\n        }\n        if (dist[t] == 1e18) break;\n        for (int v = 0; v < n; v++) if (dist[v] < 1e18) h[v] += dist[v];\n        ll d = mf - flow;\n        for (int v = t; v != s; v = pv[v]) d = min(d, g[pv[v]][pe[v]].cap);\n        flow += d; res += d * h[t];\n        for (int v = t; v != s; v = pv[v]) {\n            Edge& e = g[pv[v]][pe[v]]; e.cap -= d;\n            g[v][e.rev].cap += d;\n        }\n    }\n    return res;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(NULL);\n    int n; cin >> n;\n    vector<vector<int>> H(n, vector<int>(n));\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) cin >> H[i][j];\n    \n    auto h = H;\n    \n    vector<pair<int,int>> src, snk;\n    vector<vector<int>> sid(n, vector<int>(n, -1)), kid(n, vector<int>(n, -1));\n    for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {\n        if (H[i][j] > 0) { sid[i][j] = src.size(); src.push_back({i, j}); }\n        else if (H[i][j] < 0) { kid[i][j] = snk.size(); snk.push_back({i, j}); }\n    }\n    int P = src.size(), M = snk.size();\n    \n    vector<vector<int>> flow(P, vector<int>(M, 0));\n    if (P > 0 && M > 0) {\n        int S = 0, T = P + M + 1;\n        vector<vector<Edge>> g(P + M + 2);\n        int total_supply = 0;\n        for (int i = 0; i < P; i++) {\n            add_edge(g, S, 1 + i, H[src[i].first][src[i].second], 0);\n            total_supply += H[src[i].first][src[i].second];\n        }\n        for (int j = 0; j < M; j++) add_edge(g, 1 + P + j, T, -H[snk[j].first][snk[j].second], 0);\n        for (int i = 0; i < P; i++) {\n            auto [si, sj] = src[i];\n            for (int j = 0; j < M; j++) {\n                auto [ti, tj] = snk[j];\n                ll d = abs(si - ti) + abs(sj - tj);\n                add_edge(g, 1 + i, 1 + P + j, H[src[i].first][src[i].second], d);\n            }\n        }\n        min_cost_flow(g, S, T, total_supply);\n        for (int i = 0; i < P; i++)\n            for (auto& e : g[1 + i])\n                if (e.to >= 1 + P && e.to < 1 + P + M)\n                    flow[i][e.to - 1 - P] = (int)g[e.to][e.rev].cap;\n    }\n    \n    vector<vector<pair<int,int>>> src_snks(P);\n    for (int i = 0; i < P; i++) {\n        auto [si, sj] = src[i];\n        for (int j = 0; j < M; j++) {\n            if (flow[i][j] > 0) {\n                auto [ti, tj] = snk[j];\n                int d = abs(si - ti) + abs(sj - tj);\n                src_snks[i].push_back({d, j});\n            }\n        }\n        sort(src_snks[i].begin(), src_snks[i].end());\n    }\n\n    auto trip_cost = [&](int i, int r, int c) -> ll {\n        auto [si, sj] = src[i];\n        int soil = H[si][sj];\n        if (soil <= 0) return LLONG_MAX;\n        ll cost = (ll)(abs(r-si)+abs(c-sj)) * 100 + soil;\n        int cur_load = soil, cr = si, cc = sj;\n        for (auto& [d0, j] : src_snks[i]) {\n            if (cur_load <= 0) break;\n            auto [ti, tj] = snk[j];\n            int dd = abs(cr-ti)+abs(cc-tj);\n            int amt = min(flow[i][j], cur_load);\n            cost += (ll)dd * (100 + cur_load) + amt;\n            cur_load -= amt; cr = ti; cc = tj;\n        }\n        if (cur_load > 0) cost += (ll)40 * (100 + cur_load) + cur_load;\n        return cost;\n    };\n    \n    vector<int> src_rem(P);\n    for (int i = 0; i < P; i++) src_rem[i] = H[src[i].first][src[i].second];\n    \n    vector<string> ops;\n    int r = 0, c = 0, load = 0, cur_src = -1;\n    \n    while (ops.size() < 100000) {\n        if (h[r][c] > 0 && sid[r][c] >= 0 && src_rem[sid[r][c]] > 0) {\n            int s = sid[r][c];\n            ops.push_back(\"+\" + to_string(h[r][c]));\n            load += h[r][c]; src_rem[s] = 0; h[r][c] = 0; cur_src = s;\n        }\n        while (h[r][c] < 0 && load > 0) {\n            int d = min(load, -h[r][c]);\n            ops.push_back(\"-\" + to_string(d));\n            load -= d; h[r][c] += d;\n        }\n        \n        bool any_left = false;\n        for (int i = 0; i < P; i++) if (src_rem[i] > 0) any_left = true;\n        for (int i = 0; i < n && !any_left; i++) for (int j = 0; j < n && !any_left; j++) if (h[i][j] != 0) any_left = true;\n        if (!any_left && load == 0) break;\n\n        int br = -1, bc = -1; ll bcost = LLONG_MAX;\n        if (load > 0) {\n            for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) if (h[i][j] < 0) {\n                int d = abs(r - i) + abs(c - j);\n                int absorb = min(-h[i][j], load);\n                ll cost = (ll)d * (100 + load) - 30LL * absorb;\n                if (cost < bcost) { bcost = cost; br = i; bc = j; }\n            }\n        } else {\n            cur_src = -1;\n            for (int i = 0; i < P; i++) {\n                if (src_rem[i] <= 0) continue;\n                ll cost = trip_cost(i, r, c);\n                if (cost < bcost) { bcost = cost; br = src[i].first; bc = src[i].second; cur_src = i; }\n            }\n            if (br == -1) {\n                for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) if (h[i][j] != 0) {\n                    int d = abs(r - i) + abs(c - j);\n                    ll cost = (ll)d * 100;\n                    if (cost < bcost) { bcost = cost; br = i; bc = j; }\n                }\n            }\n        }\n        if (br == -1) break;\n        if (br < r) { r--; ops.push_back(\"U\"); }\n        else if (br > r) { r++; ops.push_back(\"D\"); }\n        else if (bc < c) { c--; ops.push_back(\"L\"); }\n        else { c++; ops.push_back(\"R\"); }\n    }\n    for (auto& op : ops) cout << op << \"\\n\";\n}","ahc035":"#include <iostream>\n#include <algorithm>\n#include <numeric>\n#include <chrono>\n#include <cstring>\n#include <cmath>\n\nusing namespace std;\n\nstruct RNG {\n    unsigned long long s[2];\n    RNG(unsigned long long s1=0x123456789ABCDEF0ULL,unsigned long long s2=0xFEDCBA9876543210ULL):s{s1,s2}{}\n    unsigned long long next(){unsigned long long s1=s[0],s0=s[1],r=s0+s1;s[0]=s0;s1^=s1<<23;s[1]=s1^s0^(s1>>18)^(s0>>5);return r;}\n    int nextInt(int n){return (int)(next()%(unsigned long long)n);}\n    double nextDouble(){return (double)(next()>>11)*0x1.0p-53;}\n};\n\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    const int N=6,M=15,SC=60,GS=36,NE=60;\n    int n,mm,t;cin>>n>>mm>>t;\n    int X[SC][M];for(int i=0;i<SC;i++)for(int j=0;j<M;j++)cin>>X[i][j];\n    int eu[NE],ev[NE],ei=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N-1;j++){eu[ei]=i*N+j;ev[ei]=i*N+j+1;ei++;}\n    for(int i=0;i<N-1;i++)for(int j=0;j<N;j++){eu[ei]=i*N+j;ev[ei]=(i+1)*N+j;ei++;}\n    int pec[GS],pel[GS][4],pnc[GS],pnl[GS][4];\n    memset(pec,0,sizeof(pec));memset(pnc,0,sizeof(pnc));\n    for(int e=0;e<NE;e++){pel[eu[e]][pec[eu[e]]++]=e;pel[ev[e]][pec[ev[e]]++]=e;pnl[eu[e]][pnc[eu[e]]++]=ev[e];pnl[ev[e]][pnc[ev[e]]++]=eu[e];}\n    int po[GS];iota(po,po+GS,0);\n    sort(po,po+GS,[](int a,int b){int da=abs(2*(a/N)-5)+abs(2*(a%N)-5),db=abs(2*(b/N)-5)+abs(2*(b%N)-5);return da!=db?da<db:a<b;});\n    const int EXP_SZ=10001;double expT[EXP_SZ];for(int i=0;i<EXP_SZ;i++)expT[i]=exp(-(double)i/100.0);\n    RNG rng;\n    \n    for(int turn=0;turn<t;turn++){\n        int val[SC]={};for(int i=0;i<SC;i++)for(int j=0;j<M;j++)val[i]+=X[i][j];\n        int pot[SC][SC]={};\n        for(int i=0;i<SC;i++)for(int j=i+1;j<SC;j++){int s=0;for(int l=0;l<M;l++)s+=max(X[i][l],X[j][l]);pot[i][j]=pot[j][i]=s;}\n        \n        int bestGrid[GS],bestScore=-1;bool bestUsed[SC]={};int bestUn[SC-GS],bestUnc=0;\n        \n        auto trySol=[&](int g[GS]){int sc=0;for(int e=0;e<NE;e++)sc+=pot[g[eu[e]]][g[ev[e]]];if(sc>bestScore){bestScore=sc;memcpy(bestGrid,g,sizeof(int)*GS);memset(bestUsed,0,sizeof(bestUsed));for(int i=0;i<GS;i++)bestUsed[g[i]]=true;bestUnc=0;for(int i=0;i<SC;i++)if(!bestUsed[i])bestUn[bestUnc++]=i;}};\n        \n        auto greedyFill=[&](int g[GS],bool u[SC],bool pf[GS],int order[GS]){\n            for(int idx=0;idx<GS;idx++){int pos=order[idx];if(pf[pos])continue;int bs=-1,bsc=-1;\n                for(int s=0;s<SC;s++){if(u[s])continue;int sc=0;for(int ni=0;ni<pnc[pos];ni++){int np=pnl[pos][ni];if(pf[np])sc+=pot[s][g[np]];}if(sc==0)sc=val[s];if(sc>bsc){bsc=sc;bs=s;}}\n                g[pos]=bs;u[bs]=true;pf[pos]=true;}\n        };\n        \n        // Strategy 0: center-first greedy\n        {int g[GS]={};bool u[SC]={};bool pf[GS]={};greedyFill(g,u,pf,po);trySol(g);}\n        // Strategy 1: best-pair-first greedy\n        {int g[GS]={};bool u[SC]={};bool pf[GS]={};\n            int ba=0,bb=1,bp=pot[0][1];for(int i=0;i<SC;i++)for(int j=i+1;j<SC;j++)if(pot[i][j]>bp){bp=pot[i][j];ba=i;bb=j;}\n            g[14]=ba;u[ba]=true;pf[14]=true;g[15]=bb;u[bb]=true;pf[15]=true;greedyFill(g,u,pf,po);trySol(g);}\n        // Strategy 2: value-sorted placement\n        {int g[GS];int ss[SC];iota(ss,ss+SC,0);sort(ss,ss+SC,[&](int a,int b){return val[a]>val[b];});for(int i=0;i<GS;i++)g[po[i]]=ss[i];trySol(g);}\n        // Strategy 3-7: random greedy\n        for(int strat=0;strat<5;strat++){int order[GS];iota(order,order+GS,0);RNG tmpRng(turn*1000+strat+200);for(int i=GS-1;i>0;i--){int j=tmpRng.nextInt(i+1);swap(order[i],order[j]);}int g[GS]={};bool u[SC]={};bool pf[GS]={};greedyFill(g,u,pf,order);trySol(g);}\n        \n        // Phase 1: SA with 500->10 over 80ms\n        {\n            int grid[GS];memcpy(grid,bestGrid,sizeof(int)*GS);\n            bool used[SC];memcpy(used,bestUsed,sizeof(bool)*SC);\n            int un[SC-GS];int unc=bestUnc;memcpy(un,bestUn,sizeof(int)*unc);\n            int cs=bestScore,bs=cs;int bg[GS];memcpy(bg,grid,sizeof(int)*GS);\n            auto st=chrono::high_resolution_clock::now();double invT=1.0/500.0;\n            for(int iter=0;iter<200000000;iter++){\n                if((iter&0x3FFF)==0){auto el=chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now()-st).count();if(el>80000)break;double p=(double)el/180000.0;double tmp=500.0*pow(10.0/500.0,p);invT=1.0/tmp;}\n                if(rng.next()%5>0){int i=rng.nextInt(GS),j=rng.nextInt(GS);if(i==j)continue;int delta=0;for(int k=0;k<pec[i];k++){int e=pel[i][k];delta-=pot[grid[eu[e]]][grid[ev[e]]];}for(int k=0;k<pec[j];k++){int e=pel[j][k];delta-=pot[grid[eu[e]]][grid[ev[e]]];}swap(grid[i],grid[j]);for(int k=0;k<pec[i];k++){int e=pel[i][k];delta+=pot[grid[eu[e]]][grid[ev[e]]];}for(int k=0;k<pec[j];k++){int e=pel[j][k];delta+=pot[grid[eu[e]]][grid[ev[e]]];}if(delta>=0){cs+=delta;if(cs>bs){bs=cs;memcpy(bg,grid,sizeof(int)*GS);}}else{int idx=(int)((double)(-delta)*invT*100.0);if(idx<EXP_SZ&&rng.nextDouble()<expT[idx]){cs+=delta;if(cs>bs){bs=cs;memcpy(bg,grid,sizeof(int)*GS);}}else swap(grid[i],grid[j]);}}\n                else{int pos=rng.nextInt(GS);int ui=rng.nextInt(unc);int ns=un[ui],os=grid[pos];int delta=0;for(int k=0;k<pec[pos];k++){int e=pel[pos][k];delta-=pot[grid[eu[e]]][grid[ev[e]]];}grid[pos]=ns;for(int k=0;k<pec[pos];k++){int e=pel[pos][k];delta+=pot[grid[eu[e]]][grid[ev[e]]];}if(delta>=0){cs+=delta;used[os]=false;used[ns]=true;un[ui]=os;if(cs>bs){bs=cs;memcpy(bg,grid,sizeof(int)*GS);}}else{int idx=(int)((double)(-delta)*invT*100.0);if(idx<EXP_SZ&&rng.nextDouble()<expT[idx]){cs+=delta;used[os]=false;used[ns]=true;un[ui]=os;if(cs>bs){bs=cs;memcpy(bg,grid,sizeof(int)*GS);}}else grid[pos]=os;}}\n            }\n            if(bs>bestScore){bestScore=bs;memcpy(bestGrid,bg,sizeof(int)*GS);memset(bestUsed,0,sizeof(bestUsed));for(int i=0;i<GS;i++)bestUsed[bestGrid[i]]=true;bestUnc=0;for(int i=0;i<SC;i++)if(!bestUsed[i])bestUn[bestUnc++]=i;}\n        }\n        \n        // Phase 2: restart from best, SA 100->0.1 over 100ms\n        {\n            int grid[GS];memcpy(grid,bestGrid,sizeof(int)*GS);\n            bool used[SC];memset(used,0,sizeof(used));for(int i=0;i<GS;i++)used[grid[i]]=true;\n            int un[SC-GS];int unc=0;for(int i=0;i<SC;i++)if(!used[i])un[unc++]=i;\n            int cs=bestScore,bs=cs;int bg[GS];memcpy(bg,grid,sizeof(int)*GS);\n            auto st=chrono::high_resolution_clock::now();double invT=1.0/100.0;\n            for(int iter=0;iter<200000000;iter++){\n                if((iter&0x3FFF)==0){auto el=chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now()-st).count();if(el>100000)break;double p=(double)el/180000.0;double tmp=100.0*pow(0.1/100.0,p);invT=1.0/tmp;}\n                if(rng.next()%5>0){int i=rng.nextInt(GS),j=rng.nextInt(GS);if(i==j)continue;int delta=0;for(int k=0;k<pec[i];k++){int e=pel[i][k];delta-=pot[grid[eu[e]]][grid[ev[e]]];}for(int k=0;k<pec[j];k++){int e=pel[j][k];delta-=pot[grid[eu[e]]][grid[ev[e]]];}swap(grid[i],grid[j]);for(int k=0;k<pec[i];k++){int e=pel[i][k];delta+=pot[grid[eu[e]]][grid[ev[e]]];}for(int k=0;k<pec[j];k++){int e=pel[j][k];delta+=pot[grid[eu[e]]][grid[ev[e]]];}if(delta>=0){cs+=delta;if(cs>bs){bs=cs;memcpy(bg,grid,sizeof(int)*GS);}}else{int idx=(int)((double)(-delta)*invT*100.0);if(idx<EXP_SZ&&rng.nextDouble()<expT[idx]){cs+=delta;if(cs>bs){bs=cs;memcpy(bg,grid,sizeof(int)*GS);}}else swap(grid[i],grid[j]);}}\n                else{int pos=rng.nextInt(GS);int ui=rng.nextInt(unc);int ns=un[ui],os=grid[pos];int delta=0;for(int k=0;k<pec[pos];k++){int e=pel[pos][k];delta-=pot[grid[eu[e]]][grid[ev[e]]];}grid[pos]=ns;for(int k=0;k<pec[pos];k++){int e=pel[pos][k];delta+=pot[grid[eu[e]]][grid[ev[e]]];}if(delta>=0){cs+=delta;used[os]=false;used[ns]=true;un[ui]=os;if(cs>bs){bs=cs;memcpy(bg,grid,sizeof(int)*GS);}}else{int idx=(int)((double)(-delta)*invT*100.0);if(idx<EXP_SZ&&rng.nextDouble()<expT[idx]){cs+=delta;used[os]=false;used[ns]=true;un[ui]=os;if(cs>bs){bs=cs;memcpy(bg,grid,sizeof(int)*GS);}}else grid[pos]=os;}}\n            }\n            if(bs>bestScore){bestScore=bs;memcpy(bestGrid,bg,sizeof(int)*GS);}\n        }\n        \n        for(int i=0;i<N;i++){for(int j=0;j<N;j++){cout<<bestGrid[i*N+j];if(j<N-1)cout<<\" \";}cout<<\"\\n\";}\n        cout.flush();for(int i=0;i<SC;i++)for(int j=0;j<M;j++)cin>>X[i][j];\n    }return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\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), t(N);\n    for (int i = 0; i < N; i++) cin >> s[i];\n    for (int i = 0; i < N; i++) cin >> t[i];\n    \n    int Vp = V;\n    vector<int> len(Vp, 1);\n    int idx = 1;\n    for (int l = 1; idx < Vp; l++) {\n        int cnt = (l <= 2 && Vp >= 10) ? 2 : 1;\n        for (int k = 0; k < cnt && idx < Vp; k++) {\n            len[idx++] = min(l, N / 2);\n        }\n    }\n    \n    cout << Vp << \"\\n\";\n    for (int i = 1; i < Vp; i++) cout << 0 << \" \" << len[i] << \"\\n\";\n    \n    vector<vector<int>> grid(N, vector<int>(N)), target(N, vector<int>(N));\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = s[i][j] - '0';\n            target[i][j] = t[i][j] - '0';\n        }\n    \n    vector<pair<int,int>> sources, targets;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] && !target[i][j]) sources.push_back({i, j});\n            if (!grid[i][j] && target[i][j]) targets.push_back({i, j});\n        }\n    \n    int Mm = sources.size();\n    if (Mm == 0) {\n        cout << N/2 << \" \" << N/2 << \"\\n\";\n        return 0;\n    }\n    \n    // Cluster sources\n    vector<int> s_cluster(Mm, -1);\n    int num_s_clusters = 0;\n    for (int i = 0; i < Mm; i++) {\n        if (s_cluster[i] != -1) continue;\n        queue<int> q; q.push(i); s_cluster[i] = num_s_clusters;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v = 0; v < Mm; v++) {\n                if (s_cluster[v] != -1) continue;\n                if (abs(sources[u].first - sources[v].first) + abs(sources[u].second - sources[v].second) <= 6) {\n                    s_cluster[v] = num_s_clusters; q.push(v);\n                }\n            }\n        }\n        num_s_clusters++;\n    }\n\n    // Cluster targets\n    vector<int> t_cluster(Mm, -1);\n    int num_t_clusters = 0;\n    for (int i = 0; i < Mm; i++) {\n        if (t_cluster[i] != -1) continue;\n        queue<int> q; q.push(i); t_cluster[i] = num_t_clusters;\n        while (!q.empty()) {\n            int u = q.front(); q.pop();\n            for (int v = 0; v < Mm; v++) {\n                if (t_cluster[v] != -1) continue;\n                if (abs(targets[u].first - targets[v].first) + abs(targets[u].second - targets[v].second) <= 6) {\n                    t_cluster[v] = num_t_clusters; q.push(v);\n                }\n            }\n        }\n        num_t_clusters++;\n    }\n    \n    vector<pair<long long, long long>> s_center(num_s_clusters, {0, 0});\n    vector<int> s_count(num_s_clusters, 0);\n    for (int i = 0; i < Mm; i++) {\n        s_center[s_cluster[i]].first += sources[i].first;\n        s_center[s_cluster[i]].second += sources[i].second;\n        s_count[s_cluster[i]]++;\n    }\n    for (int i = 0; i < num_s_clusters; i++) { s_center[i].first /= s_count[i]; s_center[i].second /= s_count[i]; }\n    \n    vector<pair<long long, long long>> t_center(num_t_clusters, {0, 0});\n    vector<int> t_count(num_t_clusters, 0);\n    for (int i = 0; i < Mm; i++) {\n        t_center[t_cluster[i]].first += targets[i].first;\n        t_center[t_cluster[i]].second += targets[i].second;\n        t_count[t_cluster[i]]++;\n    }\n    for (int i = 0; i < num_t_clusters; i++) { t_center[i].first /= t_count[i]; t_center[i].second /= t_count[i]; }\n    \n    vector<int> cluster_match(num_s_clusters, -1);\n    vector<bool> t_cluster_used(num_t_clusters, false);\n    vector<int> s_cluster_order(num_s_clusters);\n    iota(s_cluster_order.begin(), s_cluster_order.end(), 0);\n    sort(s_cluster_order.begin(), s_cluster_order.end(), [&](int a, int b) { return s_count[a] > s_count[b]; });\n    \n    for (int i : s_cluster_order) {\n        long long best_dist = 1e18; int best_t = -1;\n        for (int j = 0; j < num_t_clusters; j++) {\n            if (t_cluster_used[j]) continue;\n            long long dist = abs(s_center[i].first - t_center[j].first) + abs(s_center[i].second - t_center[j].second);\n            if (dist < best_dist) { best_dist = dist; best_t = j; }\n        }\n        if (best_t != -1) { cluster_match[i] = best_t; t_cluster_used[best_t] = true; }\n    }\n    \n    vector<int> match(Mm, -1);\n    vector<bool> sused(Mm, false), tused(Mm, false);\n    \n    for (int i = 0; i < num_s_clusters; i++) {\n        if (cluster_match[i] == -1) continue;\n        int j = cluster_match[i];\n        vector<int> s_indices, t_indices;\n        for (int k = 0; k < Mm; k++) {\n            if (s_cluster[k] == i) s_indices.push_back(k);\n            if (t_cluster[k] == j) t_indices.push_back(k);\n        }\n        vector<tuple<int,int,int>> pairs;\n        for (int si : s_indices) {\n            for (int ti : t_indices) {\n                if (tused[ti]) continue;\n                pairs.push_back({abs(sources[si].first - targets[ti].first) + abs(sources[si].second - targets[ti].second), si, ti});\n            }\n        }\n        sort(pairs.begin(), pairs.end());\n        for (auto& [d, si, ti] : pairs) {\n            if (!sused[si] && !tused[ti]) { match[si] = ti; sused[si] = true; tused[ti] = true; }\n        }\n    }\n    \n    vector<tuple<int,int,int>> pairs;\n    for (int i = 0; i < Mm; i++) {\n        if (sused[i]) continue;\n        for (int j = 0; j < Mm; j++) {\n            if (tused[j]) continue;\n            pairs.push_back({abs(sources[i].first - targets[j].first) + abs(sources[i].second - targets[j].second), i, j});\n        }\n    }\n    sort(pairs.begin(), pairs.end());\n    for (auto& [d, i, j] : pairs) {\n        if (!sused[i] && !tused[j]) { match[i] = j; sused[i] = true; tused[j] = true; }\n    }\n    \n    int best_cluster = max_element(s_count.begin(), s_count.end()) - s_count.begin();\n    int rx = s_center[best_cluster].first;\n    int ry = s_center[best_cluster].second;\n    cout << rx << \" \" << ry << \"\\n\";\n    \n    vector<int> dir(Vp, 0);\n    vector<bool> available_s(Mm, true);\n    vector<int> finger_state(Vp, 0); // 0: IDLE, 1: TO_SOURCE, 2: TO_TARGET\n    vector<int> finger_task(Vp, -1);\n    vector<int> f_target_x(Vp), f_target_y(Vp), f_target_dir(Vp);\n    vector<string> ops;\n    \n    auto get_best_station = [&](int rx, int ry, int f, int cell_x, int cell_y) {\n        int best_cost = INT_MAX, best_nx = -1, best_ny = -1, best_dir = -1;\n        for (int d = 0; d < 4; d++) {\n            int nx = cell_x - dx[d] * len[f], ny = cell_y - dy[d] * len[f];\n            if (0 <= nx && nx < N && 0 <= ny && ny < N) {\n                int dist = abs(rx - nx) + abs(ry - ny);\n                int rot = min((dir[f] - d + 4) % 4, (d - dir[f] + 4) % 4);\n                int cost = max(dist, rot);\n                if (cost < best_cost) { best_cost = cost; best_nx = nx; best_ny = ny; best_dir = d; }\n            }\n        }\n        return make_tuple(best_nx, best_ny, best_dir, best_cost);\n    };\n    \n    while (true) {\n        // 1. Update target stations dynamically based on current root position\n        for (int f = 1; f < Vp; f++) {\n            if (finger_state[f] == 1) {\n                int s_idx = finger_task[f];\n                auto [nx, ny, d, cost] = get_best_station(rx, ry, f, sources[s_idx].first, sources[s_idx].second);\n                if (nx != -1) { f_target_x[f] = nx; f_target_y[f] = ny; f_target_dir[f] = d; }\n            } else if (finger_state[f] == 2) {\n                int t_idx = match[finger_task[f]];\n                auto [nx, ny, d, cost] = get_best_station(rx, ry, f, targets[t_idx].first, targets[t_idx].second);\n                if (nx != -1) { f_target_x[f] = nx; f_target_y[f] = ny; f_target_dir[f] = d; }\n            }\n        }\n\n        // 2. Assign idle fingers\n        bool any_idle = false;\n        for (int f = 1; f < Vp; f++) if (finger_state[f] == 0) { any_idle = true; break; }\n        \n        if (any_idle) {\n            int min_cost_to_pending = INT_MAX;\n            for (int f2 = 1; f2 < Vp; f2++) {\n                if (finger_state[f2] != 0) {\n                    int dist = abs(rx - f_target_x[f2]) + abs(ry - f_target_y[f2]);\n                    int rot = min((dir[f2] - f_target_dir[f2] + 4) % 4, (f_target_dir[f2] - dir[f2] + 4) % 4);\n                    int cost = max(dist, rot);\n                    min_cost_to_pending = min(min_cost_to_pending, cost);\n                }\n            }\n            int max_accept_cost = (min_cost_to_pending == INT_MAX) ? INT_MAX : min_cost_to_pending + 6;\n\n            for (int f = 1; f < Vp; f++) {\n                if (finger_state[f] == 0) {\n                    int min_cost = INT_MAX, best_s = -1, b_nx, b_ny, b_dir;\n                    for (int i = 0; i < Mm; i++) {\n                        if (!available_s[i]) continue;\n                        auto [nx, ny, d, cost] = get_best_station(rx, ry, f, sources[i].first, sources[i].second);\n                        if (cost < min_cost && cost <= max_accept_cost) {\n                            min_cost = cost; best_s = i; b_nx = nx; b_ny = ny; b_dir = d;\n                        }\n                    }\n                    if (best_s != -1) {\n                        finger_state[f] = 1; finger_task[f] = best_s; available_s[best_s] = false;\n                        f_target_x[f] = b_nx; f_target_y[f] = b_ny; f_target_dir[f] = b_dir;\n                    }\n                }\n            }\n        }\n\n        // 3. Check if any finger is at its target station (must stay to execute action)\n        bool must_stay = false;\n        for (int f = 1; f < Vp; f++) {\n            if (finger_state[f] != 0) {\n                int dist = abs(rx - f_target_x[f]) + abs(ry - f_target_y[f]);\n                int rot = min((dir[f] - f_target_dir[f] + 4) % 4, (f_target_dir[f] - dir[f] + 4) % 4);\n                if (dist == 0 && rot == 0) {\n                    must_stay = true;\n                    break;\n                }\n            }\n        }\n\n        // 4. Find best move (Greedy TSP towards the most urgent station)\n        int best_f = -1;\n        int min_cost = INT_MAX;\n        for (int f = 1; f < Vp; f++) {\n            if (finger_state[f] == 0) continue;\n            int dist = abs(rx - f_target_x[f]) + abs(ry - f_target_y[f]);\n            int rot = min((dir[f] - f_target_dir[f] + 4) % 4, (f_target_dir[f] - dir[f] + 4) % 4);\n            int cost = max(dist, rot);\n            if (cost < min_cost) {\n                min_cost = cost;\n                best_f = f;\n            }\n        }\n\n        int best_move = 0;\n        if (!must_stay && best_f != -1) {\n            if (rx < f_target_x[best_f]) best_move = 1; // D\n            else if (rx > f_target_x[best_f]) best_move = 2; // U\n            else if (ry < f_target_y[best_f]) best_move = 3; // R\n            else if (ry > f_target_y[best_f]) best_move = 4; // L\n        }\n\n        // 5. Construct operation string\n        string op(2 * Vp, '.');\n        if (best_move == 1) { op[0] = 'D'; rx++; }\n        else if (best_move == 2) { op[0] = 'U'; rx--; }\n        else if (best_move == 3) { op[0] = 'R'; ry++; }\n        else if (best_move == 4) { op[0] = 'L'; ry--; }\n\n        for (int f = 1; f < Vp; f++) {\n            if (finger_state[f] == 0) continue;\n            if (dir[f] != f_target_dir[f]) {\n                int diff = (f_target_dir[f] - dir[f] + 4) % 4;\n                if (diff <= 2) { op[f] = 'R'; dir[f] = (dir[f] + 1) % 4; }\n                else { op[f] = 'L'; dir[f] = (dir[f] + 3) % 4; }\n            }\n        }\n\n        for (int f = 1; f < Vp; f++) {\n            if (finger_state[f] == 0) continue;\n            if (rx == f_target_x[f] && ry == f_target_y[f] && dir[f] == f_target_dir[f]) {\n                op[Vp + f] = 'P';\n                if (finger_state[f] == 1) {\n                    int s_idx = finger_task[f];\n                    grid[sources[s_idx].first][sources[s_idx].second] = 0;\n                    finger_state[f] = 2;\n                } else {\n                    int s_idx = finger_task[f]; int t_idx = match[s_idx];\n                    grid[targets[t_idx].first][targets[t_idx].second] = 1;\n                    finger_state[f] = 0;\n                }\n            }\n        }\n        ops.push_back(op);\n\n        // 6. Check termination\n        bool any_pending = false, any_available = false;\n        for (int f = 1; f < Vp; f++) if (finger_state[f] != 0) any_pending = true;\n        for (int i = 0; i < Mm; i++) if (available_s[i]) any_available = true;\n        if (!any_pending && !any_available) break;\n    }\n    \n    for (auto& op : ops) cout << op << \"\\n\";\n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct GridRect { int score, x1, y1, x2, y2; };\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N; cin >> N;\n    vector<int> fx(2*N), fy(2*N), val(2*N);\n    for (int i = 0; i < 2*N; i++) {\n        cin >> fx[i] >> fy[i];\n        val[i] = (i < N) ? 1 : -1;\n    }\n    \n    int GS = 700, CS = 143;\n    vector<vector<int>> grid(GS, vector<int>(GS, 0));\n    for (int i = 0; i < 2*N; i++) {\n        int gx = min(fx[i] / CS, GS - 1);\n        int gy = min(fy[i] / CS, GS - 1);\n        grid[gx][gy] += val[i];\n    }\n    \n    vector<GridRect> grid_rects;\n    for (int gx1 = 0; gx1 < GS; gx1++) {\n        vector<int> col_sums(GS, 0);\n        for (int gx2 = gx1; gx2 < GS; gx2++) {\n            for (int gy = 0; gy < GS; gy++) {\n                col_sums[gy] += grid[gx2][gy];\n            }\n            int cur = 0, best = 0, cy1 = 0, by1 = 0, by2 = -1;\n            for (int gy2 = 0; gy2 < GS; gy2++) {\n                cur += col_sums[gy2];\n                if (cur > best) { best = cur; by1 = cy1; by2 = gy2; }\n                if (cur < 0) { cur = 0; cy1 = gy2 + 1; }\n            }\n            if (best > 0) grid_rects.push_back({best, gx1, by1, gx2, by2});\n        }\n    }\n    sort(grid_rects.begin(), grid_rects.end(), [](const GridRect& a, const GridRect& b) { return a.score > b.score; });\n    \n    int best_exact_score = 0;\n    int final_x1 = 0, final_y1 = 0, final_x2 = 0, final_y2 = 0;\n    for (int k = 0; k < min(20, (int)grid_rects.size()); k++) {\n        int bestX1 = grid_rects[k].x1 * CS;\n        int bestY1 = grid_rects[k].y1 * CS;\n        int bestX2 = min((grid_rects[k].x2 + 1) * CS, 100000);\n        int bestY2 = min((grid_rects[k].y2 + 1) * CS, 100000);\n        \n        for (int iter = 0; iter < 20; iter++) {\n            for (int dim = 0; dim < 2; dim++) {\n                vector<pair<int, int>> ev;\n                for (int i = 0; i < 2 * N; i++) {\n                    bool inside = (dim == 0) ? (fx[i] >= bestX1 && fx[i] <= bestX2) : (fy[i] >= bestY1 && fy[i] <= bestY2);\n                    if (inside) ev.push_back({(dim == 0) ? fy[i] : fx[i], val[i]});\n                }\n                sort(ev.begin(), ev.end());\n                \n                // Group coordinates to fix the 1D overestimation bug\n                vector<pair<int, int>> ev_unique;\n                for (int i = 0; i < (int)ev.size(); i++) {\n                    if (i > 0 && ev[i].first == ev[i-1].first) {\n                        ev_unique.back().second += ev[i].second;\n                    } else {\n                        ev_unique.push_back(ev[i]);\n                    }\n                }\n                \n                int bs = -1000000000, b1 = (dim == 0) ? bestY1 : bestX1, b2 = (dim == 0) ? bestY2 : bestX2;\n                int mp = 0, mpi = -1, pfx = 0;\n                for (int j = 0; j <= (int)ev_unique.size(); j++) {\n                    int s = pfx - mp;\n                    if (s > bs) {\n                        bs = s;\n                        b1 = (mpi == -1) ? 0 : ev_unique[mpi].first;\n                        b2 = (j == (int)ev_unique.size()) ? 100000 : ev_unique[j - 1].first;\n                    }\n                    if (pfx < mp) {\n                        mp = pfx;\n                        mpi = j;\n                    }\n                    if (j < (int)ev_unique.size()) pfx += ev_unique[j].second;\n                }\n                \n                if (dim == 0) { bestY1 = b1; bestY2 = b2; } else { bestX1 = b1; bestX2 = b2; }\n            }\n        }\n        \n        int current_score = 0;\n        for (int i = 0; i < 2 * N; i++) {\n            if (fx[i] >= bestX1 && fx[i] <= bestX2 && fy[i] >= bestY1 && fy[i] <= bestY2) {\n                current_score += val[i];\n            }\n        }\n        \n        if (current_score > best_exact_score) {\n            best_exact_score = current_score;\n            final_x1 = bestX1; final_y1 = bestY1;\n            final_x2 = bestX2; final_y2 = bestY2;\n        }\n    }\n    \n    if (best_exact_score > 0) {\n        cout << 4 << \"\\n\" << final_x1 << \" \" << final_y1 << \"\\n\"\n             << final_x2 << \" \" << final_y1 << \"\\n\"\n             << final_x2 << \" \" << final_y2 << \"\\n\"\n             << final_x1 << \" \" << final_y2 << \"\\n\";\n    } else {\n        cout << 4 << \"\\n50000 50000\\n50001 50000\\n50001 50001\\n50000 50001\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\nint N,T,sigma;\nvector<long long>w_obs,h_obs;\nvector<double>w_est,h_est;\nint main(){\n    ios::sync_with_stdio(false);cin.tie(nullptr);\n    cin>>N>>T>>sigma;\n    w_obs.resize(N);h_obs.resize(N);w_est.resize(N);h_est.resize(N);\n    for(int i=0;i<N;i++){cin>>w_obs[i]>>h_obs[i];w_est[i]=w_obs[i];h_est[i]=h_obs[i];}\n    mt19937 rng(42);\n    auto start=chrono::steady_clock::now();\n    int ne=(T>=20)?4:(T>=8?2:0);\n    for(int t=0;t<T;t++){\n        auto now=chrono::steady_clock::now();\n        if(chrono::duration_cast<chrono::milliseconds>(now-start).count()>2700)break;\n        vector<long long>wc(N),hc(N);\n        for(int i=0;i<N;i++){wc[i]=max(1LL,(long long)round(w_est[i]));hc[i]=max(1LL,(long long)round(h_est[i]));}\n        vector<long long>px,py,pw,ph;vector<int>plc;vector<tuple<int,int,char,int>>out;\n        long long cW=0,cH=0;\n        bool is_est=(t<ne);\n        if(is_est){\n            bool ir=(t%2==0),iro=(ne>=4&&t>=2);\n            for(int i=0;i<N;i++){\n                long long rw=iro?hc[i]:wc[i],rh=iro?wc[i]:hc[i];\n                if(ir){long long rx=(i==0)?0:px.back()+pw.back();px.push_back(rx);py.push_back(0);cW=rx+rw;cH=max(cH,rh);}\n                else{long long ry=(i==0)?0:py.back()+ph.back();px.push_back(0);py.push_back(ry);cW=max(cW,rw);cH=ry+rh;}\n                pw.push_back(rw);ph.push_back(rh);plc.push_back(i);\n                out.push_back({i,iro?1:0,ir?'U':'L',(i==0)?-1:(i-1)});\n            }\n        }else{\n            int ot=t-ne;int strat=ot%10;\n            bool addN=(ot<20&&ot%5==4);\n            if(addN)for(int i=0;i<N;i++){wc[i]=max(1LL,wc[i]+(long long)(rng()%4001)-2000);hc[i]=max(1LL,hc[i]+(long long)(rng()%4001)-2000);}\n            for(int i=0;i<N;i++){\n                long long bs=LLONG_MAX;int br=0;char bd='U';int bb=-1;long long brx=0,bry=0;\n                int np=(int)px.size();\n                for(int r=0;r<2;r++){\n                    long long rw=r?hc[i]:wc[i],rh=r?wc[i]:hc[i];\n                    for(int b=-1;b<np;b++){\n                        {long long rx=(b<0)?0:px[b]+pw[b],ry=0;\n                         for(int j=0;j<np;j++)if(px[j]<rx+rw&&px[j]+pw[j]>rx)ry=max(ry,py[j]+ph[j]);\n                         long long nW=max(cW,rx+rw),nH=max(cH,ry+rh),s=nW+nH;\n                         switch(strat){\n                             case 1:s+=abs(nW-nH)/4;break;case 2:s+=abs(nW-nH)/2;break;\n                             case 3:s+=abs(nW-nH);break;case 4:s=max(nW,nH)*2;break;\n                             case 5:s=nW*3+nH;break;case 6:s=nW+nH*3;break;\n                             case 7:s+=abs(nW-nH)*3/4;break;case 8:s+=abs(nW-nH)/8;break;\n                             case 9:{long long w=nW*nH;for(int j=0;j<np;j++)w-=pw[j]*ph[j];w-=rw*rh;s+=w/500;break;}\n                         }\n                         if(s<bs){bs=s;br=r;bd='U';bb=b;brx=rx;bry=ry;}}\n                        {long long ry=(b<0)?0:py[b]+ph[b],rx=0;\n                         for(int j=0;j<np;j++)if(py[j]<ry+rh&&py[j]+ph[j]>ry)rx=max(rx,px[j]+pw[j]);\n                         long long nW=max(cW,rx+rw),nH=max(cH,ry+rh),s=nW+nH;\n                         switch(strat){\n                             case 1:s+=abs(nW-nH)/4;break;case 2:s+=abs(nW-nH)/2;break;\n                             case 3:s+=abs(nW-nH);break;case 4:s=max(nW,nH)*2;break;\n                             case 5:s=nW*3+nH;break;case 6:s=nW+nH*3;break;\n                             case 7:s+=abs(nW-nH)*3/4;break;case 8:s+=abs(nW-nH)/8;break;\n                             case 9:{long long w=nW*nH;for(int j=0;j<np;j++)w-=pw[j]*ph[j];w-=rw*rh;s+=w/500;break;}\n                         }\n                         if(s<bs){bs=s;br=r;bd='L';bb=b;brx=rx;bry=ry;}}\n                    }\n                }\n                long long rw=br?hc[i]:wc[i],rh=br?wc[i]:hc[i];\n                px.push_back(brx);py.push_back(bry);pw.push_back(rw);ph.push_back(rh);\n                plc.push_back(i);out.push_back({i,br,bd,bb});cW=max(cW,brx+rw);cH=max(cH,bry+rh);\n            }\n        }\n        cout<<out.size()<<\"\\n\";\n        for(auto&[p,r,d,b]:out)cout<<p<<\" \"<<r<<\" \"<<d<<\" \"<<b<<\"\\n\";\n        cout.flush();\n        long long Wp,Hp;cin>>Wp>>Hp;\n        if(is_est){\n            bool ir=(t%2==0),iro=(ne>=4&&t>=2);\n            if(ir){\n                double ws=0;for(int i=0;i<N;i++)ws+=(iro?h_est[i]:w_est[i]);\n                double c=(ws-Wp)/N;\n                for(int i=0;i<N;i++){if(iro)h_est[i]=max(1.0,h_est[i]-c);else w_est[i]=max(1.0,w_est[i]-c);}\n                vector<pair<double,int>>vh;for(int i=0;i<N;i++)vh.push_back({iro?w_est[i]:h_est[i],i});\n                sort(vh.rbegin(),vh.rend());\n                double herr=max(-(double)(3*sigma),min((double)(3*sigma),(double)(Hp-cH)));\n                for(int k=0;k<min(3,N);k++){double wt=(k==0)?0.12:(k==1)?0.05:0.02;if(iro)w_est[vh[k].second]=max(1.0,w_est[vh[k].second]+herr*wt);else h_est[vh[k].second]=max(1.0,h_est[vh[k].second]+herr*wt);}\n            }else{\n                double hs=0;for(int i=0;i<N;i++)hs+=(iro?w_est[i]:h_est[i]);\n                double c=(hs-Hp)/N;\n                for(int i=0;i<N;i++){if(iro)w_est[i]=max(1.0,w_est[i]-c);else h_est[i]=max(1.0,h_est[i]-c);}\n                vector<pair<double,int>>vw;for(int i=0;i<N;i++)vw.push_back({iro?h_est[i]:w_est[i],i});\n                sort(vw.rbegin(),vw.rend());\n                double werr=max(-(double)(3*sigma),min((double)(3*sigma),(double)(Wp-cW)));\n                for(int k=0;k<min(3,N);k++){double wt=(k==0)?0.12:(k==1)?0.05:0.02;if(iro)h_est[vw[k].second]=max(1.0,h_est[vw[k].second]+werr*wt);else w_est[vw[k].second]=max(1.0,w_est[vw[k].second]+werr*wt);}\n            }\n        }else{\n            double We=max(-(double)(3*sigma),min((double)(3*sigma),(double)(Wp-cW)));\n            double He=max(-(double)(3*sigma),min((double)(3*sigma),(double)(Hp-cH)));\n            int ot=t-ne;int rc=0,bc=0;\n            for(int j=0;j<(int)px.size();j++){if(px[j]+pw[j]==cW)rc++;if(py[j]+ph[j]==cH)bc++;}\n            double lr=0.12+0.18*min(1.0,(double)ot/25.0);\n            for(int j=0;j<(int)px.size();j++){\n                int o=plc[j];bool rot=get<1>(out[j]);\n                if(px[j]+pw[j]==cW&&rc>0){double es=We/rc*lr;if(rot)h_est[o]=max(1.0,h_est[o]+es);else w_est[o]=max(1.0,w_est[o]+es);}\n                if(py[j]+ph[j]==cH&&bc>0){double es=He/bc*lr;if(rot)w_est[o]=max(1.0,w_est[o]+es);else h_est[o]=max(1.0,h_est[o]+es);}\n            }\n            double glr=0.05;\n            for(int i=0;i<N;i++){w_est[i]=max(1.0,w_est[i]+We/N*glr);h_est[i]=max(1.0,h_est[i]+He/N*glr);}\n        }\n    }\n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\nint N, M, H;\nvector<int> A;\nvector<vector<int>> adj;\nmt19937 rng(42);\nchrono::steady_clock::time_point T0;\ndouble el() { return chrono::duration<double>(chrono::steady_clock::now() - T0).count(); }\n\nstruct State {\n    vector<int> parent, height, sub_max_h, q, deg;\n    vector<long long> sub_sum;\n    long long score;\n\n    void recompute() {\n        int head = 0, tail = 0;\n        for (int i = 0; i < N; i++) deg[i] = 0;\n        for (int i = 0; i < N; i++) if (parent[i] != -1) deg[parent[i]]++;\n        for (int i = 0; i < N; i++) if (deg[i] == 0) q[tail++] = i;\n        while (head < tail) { \n            int v = q[head++]; \n            if (parent[v] != -1) { \n                deg[parent[v]]--; \n                if (deg[parent[v]] == 0) q[tail++] = parent[v]; \n            }\n        }\n        for (int i = tail - 1; i >= 0; i--) {\n            int v = q[i]; \n            height[v] = (parent[v] == -1) ? 0 : height[parent[v]] + 1; \n            sub_sum[v] = A[v]; sub_max_h[v] = height[v]; \n        }\n        score = 0;\n        for (int i = 0; i < tail; i++) {\n            int v = q[i]; \n            if (parent[v] != -1) { \n                sub_sum[parent[v]] += sub_sum[v]; \n                sub_max_h[parent[v]] = max(sub_max_h[parent[v]], sub_max_h[v]); \n            }\n            score += (long long)(height[v] + 1) * A[v];\n        }\n    }\n    \n    bool creates_cycle(int v, int np) { \n        if (np == -1) return false; \n        for (int c = np; c != -1; c = parent[c]) if (c == v) return true; \n        return false; \n    }\n    \n    void apply_move(int v, int np) {\n        int op = parent[v]; parent[v] = np;\n        int delta = (np == -1) ? -height[v] : (height[np] + 1 - height[v]);\n        if (delta != 0) { \n            vector<int> stk; stk.push_back(v); \n            while (!stk.empty()) { \n                int u = stk.back(); stk.pop_back(); \n                height[u] += delta; \n                sub_max_h[u] += delta; \n                for (int c : adj[u]) if (parent[c] == u) stk.push_back(c); \n            } \n        }\n        vector<int> ancs; \n        for (int c = op; c != -1; c = parent[c]) ancs.push_back(c); \n        for (int c = np; c != -1; c = parent[c]) ancs.push_back(c);\n        sort(ancs.begin(), ancs.end(), [this](int a, int b) { return height[a] > height[b]; }); \n        ancs.erase(unique(ancs.begin(), ancs.end()), ancs.end());\n        for (int c : ancs) { \n            sub_sum[c] = A[c]; sub_max_h[c] = height[c]; \n            for (int ch : adj[c]) if (parent[ch] == c) { \n                sub_sum[c] += sub_sum[ch]; \n                sub_max_h[c] = max(sub_max_h[c], sub_max_h[ch]); \n            } \n        }\n    }\n    \n    void init(const vector<int>& p) {\n        parent = p; height.resize(N); sub_sum.resize(N); sub_max_h.resize(N); q.resize(N); deg.resize(N);\n        recompute();\n    }\n};\n\nvoid greedy(State& st) { \n    while (true) { \n        long long bg = 0; int bv = -1, bu = -1; \n        for (int v = 0; v < N; v++) for (int u : adj[v]) { \n            if (u == st.parent[v]) continue; \n            if (st.creates_cycle(v, u)) continue;\n            int nh = st.height[u] + 1, d = nh - st.height[v]; \n            if (d <= 0 || st.sub_max_h[v] + d > H) continue; \n            long long g = (long long)d * st.sub_sum[v]; \n            if (g > bg) { bg = g; bv = v; bu = u; } \n        } \n        if (bv == -1) break; \n        st.parent[bv] = bu;\n        st.recompute();\n    } \n}\n\nvoid sa(State& st, double et) { \n    double ss = el(); double dur = max(0.001, et - ss); \n    uniform_real_distribution<double> uf(0, 1); \n    long long lb = st.score; vector<int> bp = st.parent; \n    double T = 5000.0;\n    for (int it = 0; ; it++) { \n        if (it % 1000 == 0) { \n            double t = el(); if (t > et) break; \n            T = 5000.0 * exp(-20.0 * (t - ss) / dur); \n            st.recompute();\n        }\n        int v = rng() % N; \n        int np;\n        if (rng() % 20 == 0) np = -1;\n        else { if (adj[v].empty()) continue; np = adj[v][rng() % adj[v].size()]; }\n        \n        if (np == st.parent[v]) continue; \n        if (st.creates_cycle(v, np)) continue;\n        \n        int nh = (np == -1) ? 0 : st.height[np] + 1; \n        int d = nh - st.height[v]; \n        if (st.sub_max_h[v] + d > H) continue; \n        \n        long long g = (long long)d * st.sub_sum[v]; \n        if (g > 0 || uf(rng) < exp((double)g / T)) { \n            st.apply_move(v, np); \n            st.score += g; \n            if (st.score > lb) { lb = st.score; bp = st.parent; } \n        } \n    } \n    st.parent = bp; st.recompute();\n}\n\nvector<int> bfs_sol(const vector<int>& ro, bool by_b) { vector<int> p(N, -1), h(N, 0); vector<bool> vis(N); for (int r : ro) { if (vis[r]) continue; queue<int> q; q.push(r); vis[r] = true; p[r] = -1; h[r] = 0; while (!q.empty()) { int u = q.front(); q.pop(); if (h[u] >= H) continue; vector<int> nb = adj[u]; if (by_b) sort(nb.begin(), nb.end(), [](int a, int b) { return A[a] < A[b]; }); else shuffle(nb.begin(), nb.end(), rng); for (int v : nb) { if (vis[v]) continue; vis[v] = true; p[v] = u; h[v] = h[u] + 1; q.push(v); } } } return p; }\nvector<int> dfs_sol(const vector<int>& ro) { vector<int> p(N, -1), h(N, 0); vector<bool> vis(N); for (int r : ro) { if (vis[r]) continue; vis[r] = true; p[r] = -1; h[r] = 0; function<void(int)> dfs = [&](int u) { if (h[u] >= H) return; vector<int> nb = adj[u]; sort(nb.begin(), nb.end(), [](int a, int b) { return A[a] < A[b]; }); for (int v : nb) { if (vis[v]) continue; vis[v] = true; p[v] = u; h[v] = h[u] + 1; dfs(v); } }; dfs(r); } return p; }\nvector<int> chain_sol() { vector<int> p(N, -1); vector<bool> used(N); vector<int> ord(N); iota(ord.begin(), ord.end(), 0); sort(ord.begin(), ord.end(), [](int a, int b) { return A[a] > A[b]; }); for (int v : ord) { if (used[v]) continue; vector<int> dist(N, -1), par(N, -1); queue<int> q; q.push(v); dist[v] = 0; int tgt = v; while (!q.empty()) { int u = q.front(); q.pop(); if (dist[u] > dist[tgt]) tgt = u; if (dist[u] == H) continue; for (int w : adj[u]) if (!used[w] && dist[w] == -1) { dist[w] = dist[u] + 1; par[w] = u; q.push(w); } } vector<int> path; for (int c = tgt;; c = par[c]) { path.push_back(c); if (c == v) break; } for (int i = 0; i < (int)path.size(); i++) { used[path[i]] = true; p[path[i]] = (i == 0) ? -1 : path[i - 1]; } } return p; }\n\nint main() {\n    ios_base::sync_with_stdio(false); cin.tie(nullptr); T0 = chrono::steady_clock::now();\n    cin >> N >> M >> H; A.resize(N); for (int i = 0; i < N; i++) cin >> A[i]; adj.resize(N);\n    for (int i = 0; i < M; i++) { int u, v; cin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); }\n    vector<int> X(N), Y(N); for (int i = 0; i < N; i++) cin >> X[i] >> Y[i];\n    long long bs = 0; vector<int> bp(N, -1); State st;\n    auto try_sol = [&](const vector<int>& p) { st.init(p); greedy(st); if (st.score > bs) { bs = st.score; bp = st.parent; } };\n    try_sol(vector<int>(N, -1));\n    { vector<int> o(N); iota(o.begin(), o.end(), 0); sort(o.begin(), o.end(), [](int a, int b) { return A[a] < A[b]; }); try_sol(bfs_sol(o, true)); try_sol(dfs_sol(o)); }\n    try_sol(chain_sol());\n    { vector<int> o(N); iota(o.begin(), o.end(), 0); sort(o.begin(), o.end(), [&](int a, int b) { return (X[a]-500)*(X[a]-500)+(Y[a]-500)*(Y[a]-500) < (X[b]-500)*(X[b]-500)+(Y[b]-500)*(Y[b]-500); }); try_sol(bfs_sol(o, true)); try_sol(dfs_sol(o)); }\n    while (el() < 0.4) { vector<int> o(N); iota(o.begin(), o.end(), 0); shuffle(o.begin(), o.end(), rng); if (rng() % 2) try_sol(bfs_sol(o, rng() % 2)); else try_sol(dfs_sol(o)); }\n    st.init(bp); sa(st, 1.6); greedy(st); if (st.score > bs) { bs = st.score; bp = st.parent; }\n    for (int i = 0; i < N; i++) cout << bp[i] << (i == N - 1 ? \"\\n\" : \" \");\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <random>\n#include <chrono>\nusing namespace std;\n\nint N;\nvector<string> initial_board;\n\nvoid apply_shift(vector<string>& b, char dir, int idx) {\n    if(dir=='L'){for(int j=0;j<N-1;j++)b[idx][j]=b[idx][j+1];b[idx][N-1]='.';}\n    else if(dir=='R'){for(int j=N-1;j>0;j--)b[idx][j]=b[idx][j-1];b[idx][0]='.';}\n    else if(dir=='U'){for(int i=0;i<N-1;i++)b[i][idx]=b[i+1][idx];b[N-1][idx]='.';}\n    else{for(int i=N-1;i>0;i--)b[i][idx]=b[i-1][idx];b[0][idx]='.';}\n}\n\nstruct MoveInfo{char dir;int idx;int amount;double ratio;int oni_removed;};\n\nvector<MoveInfo> get_candidates(const vector<string>& b){\n    vector<MoveInfo> cands;\n    for(int i=0;i<N;i++){\n        int L=N;for(int j=0;j<N;j++)if(b[i][j]=='o'){L=j;break;}\n        if(L>0){int cnt=0,mx=-1;for(int j=0;j<L;j++)if(b[i][j]=='x'){cnt++;mx=j;}\n        if(cnt>0)cands.push_back(MoveInfo{'L',i,mx+1,(double)cnt/(mx+1),cnt});}\n        int R=0;for(int j=N-1;j>=0;j--)if(b[i][j]=='o'){R=j+1;break;}\n        if(R<N){int cnt=0,lo=N;for(int j=R;j<N;j++)if(b[i][j]=='x'){cnt++;if(lo==N)lo=j;}\n        if(cnt>0)cands.push_back(MoveInfo{'R',i,N-lo,(double)cnt/(N-lo),cnt});}\n    }\n    for(int j=0;j<N;j++){\n        int U=N;for(int i=0;i<N;i++)if(b[i][j]=='o'){U=i;break;}\n        if(U>0){int cnt=0,mx=-1;for(int i=0;i<U;i++)if(b[i][j]=='x'){cnt++;mx=i;}\n        if(cnt>0)cands.push_back(MoveInfo{'U',j,mx+1,(double)cnt/(mx+1),cnt});}\n        int D=0;for(int i=N-1;i>=0;i--)if(b[i][j]=='o'){D=i+1;break;}\n        if(D<N){int cnt=0,lo=N;for(int i=D;i<N;i++)if(b[i][j]=='x'){cnt++;if(lo==N)lo=i;}\n        if(cnt>0)cands.push_back(MoveInfo{'D',j,N-lo,(double)cnt/(N-lo),cnt});}\n    }\n    return cands;\n}\n\nint count_oni(const vector<string>& b){int c=0;for(auto&r:b)for(char ch:r)if(ch=='x')c++;return c;}\n\npair<int,double> compute_safety(const vector<string>& b){\n    int stuck=0;double score=0;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(b[i][j]=='x'){\n        int dirs=0;bool us=true,ds=true,ls=true,rs=true;\n        for(int k=0;k<i;k++)if(b[k][j]=='o'){us=false;break;}\n        for(int k=i+1;k<N;k++)if(b[k][j]=='o'){ds=false;break;}\n        for(int k=0;k<j;k++)if(b[i][k]=='o'){ls=false;break;}\n        for(int k=j+1;k<N;k++)if(b[i][k]=='o'){rs=false;break;}\n        dirs=us+ds+ls+rs;if(dirs==0)stuck++;else score+=dirs*dirs;\n    }\n    return {stuck,score};\n}\n\n// Batch approach from current board state with combined shifts\nvector<pair<char,int>> batch_from_board(const vector<string>& board_in){\n    vector<string> b=board_in;\n    vector<pair<char,int>> moves;\n    auto shift=[&](char d,int i){apply_shift(b,d,i);moves.push_back({d,i});};\n    struct Oni{int i,j;};vector<Oni> onis;\n    for(int i=0;i<N;i++)for(int j=0;j<N;j++)if(b[i][j]=='x')onis.push_back({i,j});\n    if(onis.empty())return moves;\n    \n    // For each Oni, find all safe directions and their costs\n    vector<vector<pair<char,int>>> oni_dirs(onis.size());\n    for(int id=0;id<(int)onis.size();id++){\n        auto& o=onis[id];bool us=true,ds=true,ls=true,rs=true;\n        for(int k=0;k<o.i;k++)if(b[k][o.j]=='o'){us=false;break;}\n        for(int k=o.i+1;k<N;k++)if(b[k][o.j]=='o'){ds=false;break;}\n        for(int k=0;k<o.j;k++)if(b[o.i][k]=='o'){ls=false;break;}\n        for(int k=o.j+1;k<N;k++)if(b[o.i][k]=='o'){rs=false;break;}\n        if(us){oni_dirs[id].push_back({'U',o.i+1});}\n        if(ds){oni_dirs[id].push_back({'D',N-o.i});}\n        if(ls){oni_dirs[id].push_back({'L',o.j+1});}\n        if(rs){oni_dirs[id].push_back({'R',N-o.j});}\n    }\n    \n    // Assign each Oni to cheapest direction\n    vector<char> assign(onis.size(),0);\n    for(int id=0;id<(int)onis.size();id++){\n        char bd=0;int bc=1e9;\n        for(auto& kv:oni_dirs[id])if(kv.second<bc){bc=kv.second;bd=kv.first;}\n        assign[id]=bd;\n    }\n    \n    // Compute batch requirements\n    auto compute_batches=[&](){\n        map<pair<char,int>,int> mx_map;\n        for(int id=0;id<(int)onis.size();id++){\n            char d=assign[id];if(!d)continue;\n            int idx=(d=='L'||d=='R')?onis[id].i:onis[id].j;\n            for(auto& kv:oni_dirs[id])if(kv.first==d){\n                auto key=make_pair(d,idx);mx_map[key]=max(mx_map[key],kv.second);break;\n            }\n        }\n        return mx_map;\n    };\n    \n    // Local search to minimize total moves (considering combined shifts)\n    auto compute_total=[&](){\n        auto mx_map=compute_batches();\n        int total=0;\n        for(int i=0;i<N;i++){\n            int Lv=0,Rv=0;\n            if(mx_map.count({'L',i}))Lv=mx_map[{'L',i}];\n            if(mx_map.count({'R',i}))Rv=mx_map[{'R',i}];\n            if(Lv>0&&Rv>0)total+=min(2*Lv+Rv,Lv+2*Rv);\n            else total+=2*(Lv+Rv);\n        }\n        for(int j=0;j<N;j++){\n            int Uv=0,Dv=0;\n            if(mx_map.count({'U',j}))Uv=mx_map[{'U',j}];\n            if(mx_map.count({'D',j}))Dv=mx_map[{'D',j}];\n            if(Uv>0&&Dv>0)total+=min(2*Uv+Dv,Uv+2*Dv);\n            else total+=2*(Uv+Dv);\n        }\n        return total;\n    };\n    \n    for(int iter=0;iter<200;iter++){\n        bool improved=false;\n        for(int id=0;id<(int)onis.size();id++){\n            if(oni_dirs[id].size()<=1)continue;\n            int old_c=compute_total();\n            char old_d=assign[id];\n            for(auto& kv:oni_dirs[id]){\n                if(kv.first==old_d)continue;\n                assign[id]=kv.first;\n                int new_c=compute_total();\n                if(new_c<old_c){improved=true;old_c=new_c;}\n                else assign[id]=old_d;\n            }\n        }\n        if(!improved)break;\n    }\n    \n    auto mx_map=compute_batches();\n    for(int i=0;i<N;i++){\n        int Lv=0,Rv=0;\n        if(mx_map.count({'L',i}))Lv=mx_map[{'L',i}];\n        if(mx_map.count({'R',i}))Rv=mx_map[{'R',i}];\n        if(Lv>0&&Rv>0){\n            if(2*Lv+Rv<=Lv+2*Rv){for(int k=0;k<Lv;k++)shift('L',i);for(int k=0;k<Lv+Rv;k++)shift('R',i);}\n            else{for(int k=0;k<Rv;k++)shift('R',i);for(int k=0;k<Rv+Lv;k++)shift('L',i);}\n        } else if(Lv>0){for(int k=0;k<Lv;k++)shift('L',i);for(int k=0;k<Lv;k++)shift('R',i);}\n        else if(Rv>0){for(int k=0;k<Rv;k++)shift('R',i);for(int k=0;k<Rv;k++)shift('L',i);}\n    }\n    for(int j=0;j<N;j++){\n        int Uv=0,Dv=0;\n        if(mx_map.count({'U',j}))Uv=mx_map[{'U',j}];\n        if(mx_map.count({'D',j}))Dv=mx_map[{'D',j}];\n        if(Uv>0&&Dv>0){\n            if(2*Uv+Dv<=Uv+2*Dv){for(int k=0;k<Uv;k++)shift('U',j);for(int k=0;k<Uv+Dv;k++)shift('D',j);}\n            else{for(int k=0;k<Dv;k++)shift('D',j);for(int k=0;k<Dv+Uv;k++)shift('U',j);}\n        } else if(Uv>0){for(int k=0;k<Uv;k++)shift('U',j);for(int k=0;k<Uv;k++)shift('D',j);}\n        else if(Dv>0){for(int k=0;k<Dv;k++)shift('D',j);for(int k=0;k<Dv;k++)shift('U',j);}\n    }\n    return moves;\n}\n\npair<vector<pair<char,int>>,bool> run_greedy(int strategy,mt19937& rng){\n    vector<string> b=initial_board;vector<pair<char,int>> moves;\n    while(true){\n        int oc=count_oni(b);if(oc==0)return {moves,true};\n        auto cands=get_candidates(b);\n        if(cands.empty()){\n            // Phase 2: batch for remaining from current state\n            auto bm=batch_from_board(b);\n            moves.insert(moves.end(),bm.begin(),bm.end());\n            return {moves,count_oni(b)==0};\n        }\n        if(strategy==0)sort(cands.begin(),cands.end(),[](const MoveInfo&a,const MoveInfo&b){return a.ratio>b.ratio;});\n        else if(strategy==1)sort(cands.begin(),cands.end(),[](const MoveInfo&a,const MoveInfo&b){return a.oni_removed>b.oni_removed||(a.oni_removed==b.oni_removed&&a.amount<b.amount);});\n        else if(strategy==2)sort(cands.begin(),cands.end(),[](const MoveInfo&a,const MoveInfo&b){return a.amount<b.amount||(a.amount==b.amount&&a.ratio>b.ratio);});\n        else shuffle(cands.begin(),cands.end(),rng);\n        auto[base_stuck,base_safety]=compute_safety(b);\n        int best_t=-1;double best_score=-1e18;\n        int cl=min(20,(int)cands.size());\n        for(int t=0;t<cl;t++){\n            auto sim=b;for(int k=0;k<cands[t].amount;k++)apply_shift(sim,cands[t].dir,cands[t].idx);\n            auto[st,sc]=compute_safety(sim);\n            double delta=sc-base_safety;\n            double score=cands[t].ratio*100+delta*0.5-st*10000;\n            if(score>best_score){best_score=score;best_t=t;}\n        }\n        if(best_t<0)return {moves,false};\n        for(int k=0;k<cands[best_t].amount;k++){apply_shift(b,cands[best_t].dir,cands[best_t].idx);moves.push_back({cands[best_t].dir,cands[best_t].idx});}\n    }\n}\n\nint main(){\n    cin>>N;initial_board.resize(N);\n    for(int i=0;i<N;i++)cin>>initial_board[i];\n    mt19937 rng(42);vector<pair<char,int>> best_moves;int best_cost=1e9;\n    auto start=chrono::high_resolution_clock::now();\n    bool done=false;\n    for(int s=0;s<4&&!done;s++)for(int t=0;t<300&&!done;t++){\n        rng.seed(42+s*1000+t);auto[m,ok]=run_greedy(s,rng);\n        if(ok&&(int)m.size()<best_cost){best_cost=m.size();best_moves=m;}\n        if(chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()-start).count()>1800)done=true;\n    }\n    // Also try pure batch\n    auto bm=batch_from_board(initial_board);if((int)bm.size()<best_cost){best_cost=bm.size();best_moves=bm;}\n    for(auto&[d,p]:best_moves)cout<<d<<\" \"<<p<<\"\\n\";\n    return 0;\n}","ahc044":"#include <iostream>\n#include <cmath>\n#include <chrono>\n#include <cstring>\n#include <algorithm>\n#include <climits>\n#include <vector>\n#include <numeric>\n\nusing namespace std;\n\nint N, L;\nint T[100];\nint a[100], b[100];\nint best_a[100], best_b[100];\nint best_error = INT_MAX;\nint t_global[100];\nint next_node[2][100];\n\nuint64_t rng_state = 1234567890123456789ULL;\nuint64_t rng64() {\n    rng_state ^= rng_state >> 12;\n    rng_state ^= rng_state << 25;\n    rng_state ^= rng_state >> 27;\n    return rng_state * 2685821657736338717ULL;\n}\n\nvoid update_next_node() {\n    for (int i = 0; i < N; i++) {\n        next_node[0][i] = a[i];\n        next_node[1][i] = b[i];\n    }\n}\n\nint simulate(int ti[]) {\n    memset(ti, 0, sizeof(int) * N);\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        int c = ++ti[cur];\n        cur = next_node[c & 1][cur];\n    }\n    int err = 0;\n    for (int i = 0; i < N; i++) err += abs(ti[i] - T[i]);\n    return err;\n}\n\nvoid try_init(int ai[], int bi[]) {\n    memcpy(a, ai, sizeof(a));\n    memcpy(b, bi, sizeof(b));\n    update_next_node();\n    int err = simulate(t_global);\n    if (err < best_error) {\n        best_error = err;\n        memcpy(best_a, a, sizeof(a));\n        memcpy(best_b, b, sizeof(b));\n    }\n}\n\nvoid greedy_init(int ai[], int bi[], bool avoid_same) {\n    int dem[100]; memcpy(dem, T, sizeof(T));\n    int cnt[100] = {};\n    bool a_ch[100] = {}, b_ch[100] = {};\n    for(int i=0; i<N; i++) { ai[i] = (i+1)%N; bi[i] = (i+1)%N; }\n    int cur = 0;\n    for (int w = 0; w < L; w++) {\n        cnt[cur]++;\n        if (cnt[cur] & 1) {\n            if (!a_ch[cur]) {\n                int best = -1;\n                for (int j = 0; j < N; j++) {\n                    if (j == cur) continue;\n                    if (avoid_same && b_ch[cur] && j == bi[cur]) continue;\n                    if (T[j] == 0 && dem[j] <= 0) continue;\n                    if (best == -1 || dem[j] > dem[best] || (dem[j] == dem[best] && T[j] > T[best])) best = j;\n                }\n                ai[cur] = best; a_ch[cur] = true;\n                dem[best] -= (T[cur] + 1) / 2;\n            }\n            cur = ai[cur];\n        } else {\n            if (!b_ch[cur]) {\n                int best = -1;\n                for (int j = 0; j < N; j++) {\n                    if (j == cur) continue;\n                    if (avoid_same && a_ch[cur] && j == ai[cur]) continue;\n                    if (T[j] == 0 && dem[j] <= 0) continue;\n                    if (best == -1 || dem[j] > dem[best] || (dem[j] == dem[best] && T[j] > T[best])) best = j;\n                }\n                bi[cur] = best; b_ch[cur] = true;\n                dem[best] -= T[cur] / 2;\n            }\n            cur = bi[cur];\n        }\n    }\n}\n\nvoid flow_sa(int ai[], int bi[]) {\n    int flow_in[100] = {};\n    for(int i=0; i<N; i++) {\n        if(T[i] == 0) continue;\n        flow_in[ai[i]] += (T[i] + 1) / 2;\n        flow_in[bi[i]] += T[i] / 2;\n    }\n\n    int current_flow_error = 0;\n    for(int i=0; i<N; i++) current_flow_error += abs(flow_in[i] - T[i]);\n\n    double flow_temp = 1000.0;\n    for(int iter = 0; iter < 2000000; iter++) {\n        if (current_flow_error == 0) break;\n        \n        int i = rng64() % N;\n        if (T[i] == 0) continue;\n        bool is_a = rng64() & 1;\n        int old_dest = is_a ? ai[i] : bi[i];\n        int new_dest = rng64() % N;\n        if (new_dest == old_dest || T[new_dest] == 0) continue;\n        \n        int delta_flow = is_a ? (T[i] + 1) / 2 : T[i] / 2;\n        \n        int old_err_old = abs(flow_in[old_dest] - T[old_dest]);\n        int old_err_new = abs(flow_in[new_dest] - T[new_dest]);\n        \n        int new_flow_old = flow_in[old_dest] - delta_flow;\n        int new_flow_new = flow_in[new_dest] + delta_flow;\n        \n        int new_err_old = abs(new_flow_old - T[old_dest]);\n        int new_err_new = abs(new_flow_new - T[new_dest]);\n        \n        int delta_err = (new_err_old + new_err_new) - (old_err_old + old_err_new);\n        if (new_dest == i) delta_err += 100;\n        if (is_a && new_dest == bi[i]) delta_err += 50;\n        if (!is_a && new_dest == ai[i]) delta_err += 50;\n        \n        if (delta_err <= 0 || (double)(rng64() & 0xFFFF) / 65536.0 < exp(-(double)delta_err / flow_temp)) {\n            if (is_a) ai[i] = new_dest; else bi[i] = new_dest;\n            flow_in[old_dest] = new_flow_old;\n            flow_in[new_dest] = new_flow_new;\n            current_flow_error += delta_err;\n        }\n        flow_temp *= 0.9999;\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    cin >> N >> L;\n    for (int i = 0; i < N; i++) cin >> T[i];\n    \n    int ai[100], bi[100];\n    \n    for (int i = 0; i < N; i++) { ai[i] = (i+1)%N; bi[i] = (i+1)%N; }\n    try_init(ai, bi);\n    \n    greedy_init(ai, bi, true);\n    try_init(ai, bi);\n    \n    greedy_init(ai, bi, false);\n    try_init(ai, bi);\n    \n    memcpy(ai, best_a, sizeof(ai));\n    memcpy(bi, best_b, sizeof(bi));\n    flow_sa(ai, bi);\n    try_init(ai, bi);\n    \n    memcpy(a, best_a, sizeof(a));\n    memcpy(b, best_b, sizeof(b));\n    update_next_node();\n    int error = simulate(t_global);\n    best_error = error;\n    \n    int order[100];\n    iota(order, order + N, 0);\n    sort(order, order + N, [](int x, int y) { return T[x] < T[y]; });\n    int rank_of[100];\n    for (int i = 0; i < N; i++) rank_of[order[i]] = i;\n    \n    vector<int> nodes_by_T[10001];\n    for(int i=0; i<N; i++) if(T[i] > 0) nodes_by_T[T[i]].push_back(i);\n    \n    double start_temp = max(500.0, (double)error / 20.0);\n    auto start = chrono::high_resolution_clock::now();\n    \n    while(true) {\n        auto now = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.85) break;\n        \n        double temp = start_temp * (1.0 - elapsed / 1.85);\n        if (temp < 0.01) temp = 0.01;\n        \n        int old_a[100], old_b[100], old_t_global[100];\n        memcpy(old_a, a, sizeof(a));\n        memcpy(old_b, b, sizeof(b));\n        memcpy(old_t_global, t_global, sizeof(t_global));\n        \n        int move_type = rng64() % 5;\n        int i = -1, j = -1;\n        \n        if (move_type == 0) {\n            i = rng64() % N;\n            while(T[i] == 0) i = rng64() % N;\n            swap(a[i], b[i]);\n        } else if (move_type < 4) {\n            i = rng64() % N;\n            while(T[i] == 0) i = rng64() % N;\n            \n            if (nodes_by_T[T[i]].size() > 1) {\n                j = nodes_by_T[T[i]][rng64() % nodes_by_T[T[i]].size()];\n                while(j == i) j = nodes_by_T[T[i]][rng64() % nodes_by_T[T[i]].size()];\n            } else {\n                int delta_rank = (rng64() % 5) - 2;\n                int new_rank = max(0, min(N - 1, rank_of[i] + delta_rank));\n                j = order[new_rank];\n                int attempts = 0;\n                while(T[j] == 0 || j == i) {\n                    new_rank = (new_rank + 1) % N;\n                    j = order[new_rank];\n                    if (++attempts > N) break;\n                }\n                if (j == i || T[j] == 0) continue;\n            }\n            \n            if (move_type == 1) swap(a[i], a[j]);\n            else if (move_type == 2) swap(b[i], b[j]);\n            else swap(a[i], b[j]);\n        } else {\n            i = rng64() % N;\n            while(T[i] == 0) i = rng64() % N;\n            bool is_a = rng64() & 1;\n            int nv = rng64() % N;\n            while(T[nv] == 0) nv = rng64() % N;\n            if (is_a) a[i] = nv; else b[i] = nv;\n        }\n        \n        update_next_node();\n        int new_error = simulate(t_global);\n        double delta = new_error - error;\n        \n        if (delta <= 0 || (double)(rng64() & 0xFFFF) / 65536.0 < exp(-delta / temp)) {\n            error = new_error;\n            if (error < best_error) {\n                best_error = error;\n                memcpy(best_a, a, sizeof(a));\n                memcpy(best_b, b, sizeof(b));\n            }\n        } else {\n            memcpy(a, old_a, sizeof(a));\n            memcpy(b, old_b, sizeof(b));\n            memcpy(t_global, old_t_global, sizeof(t_global));\n        }\n    }\n    \n    for (int i = 0; i < N; i++)\n        cout << best_a[i] << \" \" << best_b[i] << \"\\n\";\n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nuint64_t xy2d(int n, int x, int y) {\n    uint64_t d = 0;\n    for (int s = n/2; s > 0; s /= 2) {\n        int rx = (x & s) > 0;\n        int ry = (y & s) > 0;\n        d += (uint64_t)s * s * ((3 * rx) ^ ry);\n        if (ry == 0) {\n            if (rx == 1) { x = s-1 - x; y = s-1 - y; }\n            swap(x, y);\n        }\n    }\n    return d;\n}\n\nint N, M, Q, L, W;\ndouble cx[800], cy[800], ddist[800][800];\nint idist[800][800];\nint qcnt = 0;\n\nvector<pair<int,int>> query(vector<int>& v) {\n    if (qcnt >= Q || (int)v.size() < 2) return {};\n    qcnt++;\n    cout << \"? \" << v.size();\n    for (int x : v) cout << \" \" << x;\n    cout << endl;\n    vector<pair<int,int>> res(v.size() - 1);\n    for (auto& [a, b] : res) cin >> a >> b;\n    return res;\n}\n\nint par[800], rnk[800];\nvoid init_dsu() { iota(par, par + N, 0); fill(rnk, rnk + N, 0); }\nint find(int x) { return par[x] == x ? x : par[x] = find(par[x]); }\nbool unite(int x, int y) {\n    x = find(x); y = find(y);\n    if (x == y) return false;\n    if (rnk[x] < rnk[y]) swap(x, y);\n    par[y] = x;\n    if (rnk[x] == rnk[y]) rnk[x]++;\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    mt19937 rng(1337);\n    \n    cin >> N >> M >> Q >> L >> W;\n    vector<int> G(M);\n    for (int& g : G) cin >> g;\n    \n    for (int i = 0; i < N; i++) {\n        int a, b, c, d;\n        cin >> a >> b >> c >> d;\n        cx[i] = (a + b) / 2.0;\n        cy[i] = (c + d) / 2.0;\n    }\n    \n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++) {\n            double dx = cx[i] - cx[j], dy = cy[i] - cy[j];\n            ddist[i][j] = sqrt(dx*dx + dy*dy);\n            idist[i][j] = (int)floor(sqrt(dx*dx + dy*dy));\n        }\n    \n    vector<int> ord(N);\n    iota(ord.begin(), ord.end(), 0);\n    sort(ord.begin(), ord.end(), [](int a, int b) {\n        return xy2d(32768, (int)cx[a], (int)cy[a]) < xy2d(32768, (int)cx[b], (int)cy[b]);\n    });\n    \n    vector<int> cut_cost(N, 0);\n    for (int j = 1; j < N; j++) {\n        cut_cost[j] = idist[ord[j-1]][ord[j]];\n    }\n    \n    vector<int> p(M);\n    iota(p.begin(), p.end(), 0);\n    \n    if (M <= 20) {\n        vector<int> dp(1 << M, -1);\n        dp[0] = 0;\n        for (int mask = 0; mask < (1 << M); mask++) {\n            if (dp[mask] < 0) continue;\n            int s = 0;\n            for (int i = 0; i < M; i++) if (mask & (1 << i)) s += G[i];\n            for (int i = 0; i < M; i++) {\n                if (!(mask & (1 << i))) {\n                    int next_mask = mask | (1 << i);\n                    int next_s = s + G[i];\n                    int cost = dp[mask] + (next_s < N ? cut_cost[next_s] : 0);\n                    if (cost > dp[next_mask]) dp[next_mask] = cost;\n                }\n            }\n        }\n        int mask = (1 << M) - 1;\n        for (int k = M - 1; k >= 0; k--) {\n            int s = 0;\n            for (int i = 0; i < M; i++) if (mask & (1 << i)) s += G[i];\n            for (int i = 0; i < M; i++) {\n                if (mask & (1 << i)) {\n                    int prev_mask = mask ^ (1 << i);\n                    int cost = dp[prev_mask] + (s < N ? cut_cost[s] : 0);\n                    if (cost == dp[mask]) {\n                        p[k] = i;\n                        mask = prev_mask;\n                        break;\n                    }\n                }\n            }\n        }\n    } else {\n        sort(p.begin(), p.end(), [&](int a, int b) { return G[a] > G[b]; });\n        vector<int> prefix(M);\n        int s = 0;\n        for (int i = 0; i < M; i++) { s += G[p[i]]; prefix[i] = s; }\n        \n        if (M > 1) {\n            for (int iter = 0; iter < 2500000; iter++) {\n                int i = rng() % M;\n                int len = (iter < 2000000) ? 1 : (rng() % 5 + 1);\n                int j = min(i + len, M - 1);\n                if (i == j) continue;\n                \n                long long old_cost = 0;\n                for (int kk = i; kk < j; kk++) old_cost += cut_cost[prefix[kk]];\n                \n                swap(p[i], p[j]);\n                int s_prev = (i == 0 ? 0 : prefix[i-1]);\n                long long new_cost = 0;\n                for (int kk = i; kk < j; kk++) {\n                    s_prev += G[p[kk]];\n                    new_cost += cut_cost[s_prev];\n                }\n                \n                if (new_cost > old_cost) {\n                    s_prev = (i == 0 ? 0 : prefix[i-1]);\n                    for (int kk = i; kk < j; kk++) {\n                        s_prev += G[p[kk]];\n                        prefix[kk] = s_prev;\n                    }\n                } else {\n                    swap(p[i], p[j]);\n                }\n            }\n        }\n    }\n    \n    vector<vector<int>> grp(M);\n    int curr = 0;\n    for (int k = 0; k < M; k++) {\n        int group_idx = p[k];\n        int sz = G[group_idx];\n        for (int j = 0; j < sz; j++) {\n            grp[group_idx].push_back(ord[curr++]);\n        }\n    }\n    \n    vector<int> proc_order(M);\n    iota(proc_order.begin(), proc_order.end(), 0);\n    sort(proc_order.begin(), proc_order.end(), [&](int a, int b) {\n        if (G[a] <= L && G[b] > L) return true;\n        if (G[a] > L && G[b] <= L) return false;\n        if (G[a] <= L && G[b] <= L) return G[a] < G[b];\n        return G[a] > G[b];\n    });\n    \n    vector<vector<pair<int,int>>> ans(M);\n    \n    for (int k : proc_order) {\n        int G_size = grp[k].size();\n        if (G_size <= 1) continue;\n        \n        init_dsu();\n        vector<pair<int,int>> mst;\n        \n        vector<tuple<int,int,int>> est_edges;\n        for (int i = 0; i < G_size; i++)\n            for (int j = i + 1; j < G_size; j++) {\n                int u = grp[k][i], v = grp[k][j];\n                est_edges.emplace_back(idist[u][v], min(u, v), max(u, v));\n            }\n        sort(est_edges.begin(), est_edges.end());\n        \n        vector<int> par_l(G_size);\n        iota(par_l.begin(), par_l.end(), 0);\n        auto find_l = [&](auto& self, int x) -> int {\n            return par_l[x] == x ? x : par_l[x] = self(self, par_l[x]);\n        };\n        \n        vector<vector<int>> adj_local(G_size);\n        map<int, int> local_id;\n        for (int i = 0; i < G_size; ++i) local_id[grp[k][i]] = i;\n        \n        for (auto& [d, a, b] : est_edges) {\n            int la = local_id[a], lb = local_id[b];\n            int ra = find_l(find_l, la), rb = find_l(find_l, lb);\n            if (ra != rb) {\n                par_l[ra] = rb;\n                adj_local[la].push_back(lb);\n                adj_local[lb].push_back(la);\n            }\n        }\n        \n        if (G_size <= L) {\n            if (qcnt < Q) mst = query(grp[k]);\n        } else {\n            int root = 0;\n            vector<int> parent_local(G_size, -1);\n            vector<int> order;\n            queue<int> q_bfs;\n            q_bfs.push(root);\n            parent_local[root] = root;\n            while(!q_bfs.empty()) {\n                int u = q_bfs.front(); q_bfs.pop();\n                order.push_back(u);\n                for(int v : adj_local[u]) {\n                    if(v != parent_local[u]) {\n                        parent_local[v] = u;\n                        q_bfs.push(v);\n                    }\n                }\n            }\n            \n            vector<vector<int>> chunks_local_ids;\n            int target_size = max(2, L / 2);\n            \n            function<vector<int>(int)> decomp = [&](int u) -> vector<int> {\n                vector<int> nodes_without_u;\n                for (int v : adj_local[u]) {\n                    if (v == parent_local[u]) continue;\n                    auto sub_nodes = decomp(v);\n                    for (int x : sub_nodes) nodes_without_u.push_back(x);\n                }\n                \n                if ((int)nodes_without_u.size() >= target_size) {\n                    int ptr = 0;\n                    while (ptr + target_size <= (int)nodes_without_u.size()) {\n                        vector<int> chunk_local_ids;\n                        for (int i = 0; i < target_size; ++i) {\n                            chunk_local_ids.push_back(nodes_without_u[ptr + i]);\n                        }\n                        chunk_local_ids.push_back(u);\n                        chunks_local_ids.push_back(chunk_local_ids);\n                        ptr += target_size;\n                    }\n                    \n                    vector<int> remaining;\n                    for (int i = ptr; i < (int)nodes_without_u.size(); ++i) {\n                        remaining.push_back(nodes_without_u[i]);\n                    }\n                    remaining.push_back(u);\n                    return remaining;\n                } else {\n                    nodes_without_u.push_back(u);\n                    return nodes_without_u;\n                }\n            };\n            \n            auto remaining = decomp(root);\n            if ((int)remaining.size() > 1) {\n                chunks_local_ids.push_back(remaining);\n            }\n            \n            vector<vector<int>> chunks;\n            for (auto& chunk_local_ids : chunks_local_ids) {\n                vector<int> chunk;\n                for (int x : chunk_local_ids) chunk.push_back(grp[k][x]);\n                \n                vector<bool> in_chunk_set(N, false);\n                for (int x : chunk) in_chunk_set[x] = true;\n                \n                vector<double> min_dist_to_chunk(N, 1e18);\n                for (int c : grp[k]) {\n                    if (in_chunk_set[c]) continue;\n                    for (int x : chunk) min_dist_to_chunk[c] = min(min_dist_to_chunk[c], ddist[c][x]);\n                }\n                \n                priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq_crossing;\n                for (int u_local : chunk_local_ids) {\n                    for (int v_local : adj_local[u_local]) {\n                        int u = grp[k][u_local], v = grp[k][v_local];\n                        if (!in_chunk_set[v]) {\n                            pq_crossing.push({idist[u][v], v});\n                        }\n                    }\n                }\n                \n                while ((int)chunk.size() < L) {\n                    bool added = false;\n                    while (!pq_crossing.empty()) {\n                        auto [d, v] = pq_crossing.top();\n                        pq_crossing.pop();\n                        if (!in_chunk_set[v]) {\n                            chunk.push_back(v);\n                            in_chunk_set[v] = true;\n                            for (int w_local : adj_local[local_id[v]]) {\n                                int w = grp[k][w_local];\n                                if (!in_chunk_set[w]) {\n                                    pq_crossing.push({idist[v][w], w});\n                                }\n                            }\n                            added = true;\n                            break;\n                        }\n                    }\n                    \n                    if (!added) {\n                        double min_d = 1e18; int best = -1;\n                        for (int c : grp[k]) {\n                            if (in_chunk_set[c]) continue;\n                            if (min_dist_to_chunk[c] < min_d) {\n                                min_d = min_dist_to_chunk[c];\n                                best = c;\n                            }\n                        }\n                        if (best == -1) break;\n                        chunk.push_back(best);\n                        in_chunk_set[best] = true;\n                        for (int c : grp[k]) {\n                            if (!in_chunk_set[c]) {\n                                min_dist_to_chunk[c] = min(min_dist_to_chunk[c], ddist[c][best]);\n                            }\n                        }\n                    }\n                }\n                chunks.push_back(chunk);\n            }\n            \n            for (auto& chunk : chunks) {\n                if (qcnt >= Q) break;\n                auto edges = query(chunk);\n                for (auto& [a, b] : edges) {\n                    if (unite(a, b)) {\n                        mst.emplace_back(a, b);\n                    }\n                }\n            }\n        }\n        \n        if (mst.size() < (size_t)G_size - 1) {\n            for (auto& [d, a, b] : est_edges) {\n                if (unite(a, b)) {\n                    mst.emplace_back(a, b);\n                }\n                if (mst.size() == (size_t)G_size - 1) break;\n            }\n        }\n        ans[k] = mst;\n    }\n    \n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int i = 0; i < (int)grp[k].size(); i++) cout << grp[k][i] << \" \\n\"[i==(int)grp[k].size()-1];\n        for (auto& [a, b] : ans[k]) cout << min(a, b) << \" \" << max(a, b) << \"\\n\";\n    }\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <set>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <cstring>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    int N, M;\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    bool block_grid[20][20] = {};\n    int cur_r = targets[0].first, cur_c = targets[0].second;\n    vector<pair<char,char>> actions;\n    \n    const int DR[] = {-1, 1, 0, 0};\n    const int DC[] = {0, 0, -1, 1};\n    const char DIR_CHAR[] = {'U', 'D', 'L', 'R'};\n    int dir_map[256];\n    dir_map['U'] = 0; dir_map['D'] = 1; dir_map['L'] = 2; dir_map['R'] = 3;\n    \n    bool is_target[20][20] = {};\n    for (auto& [r, c] : targets) is_target[r][c] = true;\n    \n    int vis0[20][20];\n    int dist0[20][20];\n    int cur_token0 = 0;\n    \n    auto bfs_dist_0_flip = [&](int sr, int sc, int tr, int tc) -> int {\n        if (sr == tr && sc == tc) return 0;\n        cur_token0++;\n        pair<int,int> q_arr[400];\n        int q_sz = 0;\n        q_arr[q_sz++] = {sr, sc}; \n        vis0[sr][sc] = cur_token0; \n        dist0[sr][sc] = 0;\n        for (int i = 0; i < q_sz; ++i) {\n            auto [r, c] = q_arr[i];\n            int d = dist0[r][c];\n            for (int dir = 0; dir < 4; ++dir) {\n                int nr = r + DR[dir], nc = c + DC[dir];\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N && !block_grid[nr][nc] && vis0[nr][nc] != cur_token0) {\n                    vis0[nr][nc] = cur_token0; \n                    dist0[nr][nc] = d + 1;\n                    if (nr == tr && nc == tc) return d + 1; \n                    q_arr[q_sz++] = {nr, nc};\n                }\n                int snr = r, snc = c;\n                while (true) { \n                    int nnr = snr + DR[dir], nnc = snc + DC[dir]; \n                    if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || block_grid[nnr][nnc]) break; \n                    snr = nnr; snc = nnc; \n                }\n                if (vis0[snr][snc] != cur_token0) {\n                    vis0[snr][snc] = cur_token0; \n                    dist0[snr][snc] = d + 1;\n                    if (snr == tr && snc == tc) return d + 1; \n                    q_arr[q_sz++] = {snr, snc};\n                }\n            }\n        }\n        return 1e9;\n    };\n\n    auto bfs_0_flip = [&](int sr, int sc, int tr, int tc) -> vector<pair<char,char>> {\n        if (sr == tr && sc == tc) return {};\n        int dist[20][20]; memset(dist, -1, sizeof(dist));\n        int pr[20][20], pc[20][20]; memset(pr, -1, sizeof(pr)); memset(pc, -1, sizeof(pc));\n        char pa[20][20], pd[20][20]; memset(pa, 0, sizeof(pa)); memset(pd, 0, sizeof(pd));\n        \n        pair<int,int> q_arr[400];\n        int q_sz = 0;\n        q_arr[q_sz++] = {sr, sc}; dist[sr][sc] = 0;\n        \n        for (int i = 0; i < q_sz; ++i) {\n            auto [r, c] = q_arr[i];\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 && !block_grid[nr][nc] && dist[nr][nc] == -1) {\n                    dist[nr][nc] = dist[r][c] + 1;\n                    pr[nr][nc] = r; pc[nr][nc] = c; pa[nr][nc] = 0; pd[nr][nc] = d;\n                    if (nr == tr && nc == tc) goto found;\n                    q_arr[q_sz++] = {nr, nc};\n                }\n                int snr = r, snc = c;\n                while (true) {\n                    int nnr = snr + DR[d], nnc = snc + DC[d];\n                    if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || block_grid[nnr][nnc]) break;\n                    snr = nnr; snc = nnc;\n                }\n                if (dist[snr][snc] == -1) {\n                    dist[snr][snc] = dist[r][c] + 1;\n                    pr[snr][snc] = r; pc[snr][snc] = c; pa[snr][snc] = 1; pd[snr][snc] = d;\n                    if (snr == tr && snc == tc) goto found;\n                    q_arr[q_sz++] = {snr, snc};\n                }\n            }\n        }\n        return {};\n    found:\n        vector<pair<char,char>> path;\n        int cr = tr, cc = tc;\n        while (cr != sr || cc != sc) {\n            path.push_back({pa[cr][cc] ? 'S' : 'M', DIR_CHAR[pd[cr][cc]]});\n            int rr = pr[cr][cc], rc = pc[cr][cc]; cr = rr; cc = rc;\n        }\n        reverse(path.begin(), path.end());\n        return path;\n    };\n    \n    auto is_connected = [&]() -> bool {\n        int sr = -1, sc = -1, fc = 0;\n        for (int r = 0; r < N; r++) for (int c = 0; c < N; c++) if (!block_grid[r][c]) { fc++; if (sr < 0) { sr = r; sc = c; } }\n        if (fc == 0) return true;\n        bool vis_c[20][20] = {}; \n        pair<int,int> q_arr[400];\n        int q_sz = 0;\n        q_arr[q_sz++] = {sr, sc}; vis_c[sr][sc] = true; int cnt = 1;\n        for (int i = 0; i < q_sz; ++i) {\n            auto [r, c] = q_arr[i];\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 && !block_grid[nr][nc] && !vis_c[nr][nc]) { \n                    vis_c[nr][nc] = true; cnt++; q_arr[q_sz++] = {nr, nc}; \n                } \n            }\n        }\n        return cnt == fc;\n    };\n    \n    auto can_place = [&](int br, int bc) -> bool {\n        if (br < 0 || br >= N || bc < 0 || bc >= N || block_grid[br][bc] || is_target[br][bc]) return false;\n        block_grid[br][bc] = true; bool ok = is_connected(); block_grid[br][bc] = false; return ok;\n    };\n    \n    auto place_blocks = [&](int t_start) {\n        is_target[cur_r][cur_c] = false;\n        for (int iter = 0; iter < 4; ++iter) {\n            int best_d = -1, best_benefit = -1e9;\n            for (int d = 0; d < 4; d++) {\n                int br = cur_r + DR[d], bc = cur_c + DC[d];\n                if (can_place(br, bc)) {\n                    int total_benefit = 0; int cr = cur_r, cc = cur_c;\n                    for (int k = t_start; k < M; ++k) {\n                        int orig = bfs_dist_0_flip(cr, cc, targets[k].first, targets[k].second);\n                        block_grid[br][bc] = true; \n                        int new_d = bfs_dist_0_flip(cr, cc, targets[k].first, targets[k].second); \n                        block_grid[br][bc] = false;\n                        total_benefit += orig - new_d; \n                        cr = targets[k].first; cc = targets[k].second;\n                    }\n                    if (total_benefit > best_benefit) {\n                        best_benefit = total_benefit;\n                        best_d = d;\n                    }\n                }\n            }\n            if (best_d != -1 && best_benefit >= 2) { \n                int br = cur_r + DR[best_d], bc = cur_c + DC[best_d]; \n                block_grid[br][bc] = true; \n                actions.push_back({'A', DIR_CHAR[best_d]}); \n            } else break;\n        }\n    };\n    \n    place_blocks(1);\n    \n    for (int t = 1; t < M; t++) {\n        int tr = targets[t].first, tc = targets[t].second;\n        auto path = bfs_0_flip(cur_r, cur_c, tr, tc);\n        for (auto& [act, dir] : path) {\n            actions.push_back({act, dir});\n            if (act == 'M') {\n                int d = dir_map[dir];\n                cur_r += DR[d]; cur_c += DC[d];\n            } else {\n                int d = dir_map[dir];\n                int snr = cur_r, snc = cur_c;\n                while (true) {\n                    int nnr = snr + DR[d], nnc = snc + DC[d];\n                    if (nnr < 0 || nnr >= N || nnc < 0 || nnc >= N || block_grid[nnr][nnc]) break;\n                    snr = nnr; snc = nnc;\n                }\n                cur_r = snr; cur_c = snc;\n            }\n        }\n        place_blocks(t + 1);\n    }\n    \n    for (auto& [a, d] : actions) cout << a << \" \" << d << \"\\n\";\n    return 0;\n}"}}}