{"model_name":"claude-4.5-sonnet","codes":{"1":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> x, y;\nvector<long long> r;\nvector<array<int, 4>> result;\n\nvoid solve(vector<int> ids, int x1, int y1, int x2, int y2) {\n    if (ids.empty()) return;\n    \n    if (ids.size() == 1) {\n        result[ids[0]] = {x1, y1, x2, y2};\n        return;\n    }\n    \n    // Calculate total desired area for this partition\n    long long total_r = 0;\n    for (int id : ids) total_r += r[id];\n    \n    // Choose split direction based on rectangle aspect ratio\n    if (x2 - x1 >= y2 - y1) {\n        // Vertical split - sort by x coordinate\n        sort(ids.begin(), ids.end(), [](int i, int j) {\n            return x[i] < x[j];\n        });\n        \n        // Split at median to ensure both partitions are non-empty\n        int mid = ids.size() / 2;\n        \n        // Calculate desired area for left partition\n        long long left_r = 0;\n        for (int i = 0; i < mid; i++) {\n            left_r += r[ids[i]];\n        }\n        \n        // Calculate split position proportional to area\n        int split_x = x1 + (long long)(x2 - x1) * left_r / total_r;\n        \n        // Ensure split is valid: all left points must have x < split_x\n        // and all right points must have x >= split_x (since rectangle is [a,b,c,d) where a<=x<c)\n        split_x = max(split_x, x[ids[mid-1]] + 1);\n        split_x = min(split_x, x[ids[mid]] + 1);\n        split_x = max(x1 + 1, min(x2 - 1, split_x));\n        \n        vector<int> left(ids.begin(), ids.begin() + mid);\n        vector<int> right(ids.begin() + mid, ids.end());\n        \n        solve(left, x1, y1, split_x, y2);\n        solve(right, split_x, y1, x2, y2);\n    } else {\n        // Horizontal split - sort by y coordinate\n        sort(ids.begin(), ids.end(), [](int i, int j) {\n            return y[i] < y[j];\n        });\n        \n        int mid = ids.size() / 2;\n        \n        long long top_r = 0;\n        for (int i = 0; i < mid; i++) {\n            top_r += r[ids[i]];\n        }\n        \n        int split_y = y1 + (long long)(y2 - y1) * top_r / total_r;\n        split_y = max(split_y, y[ids[mid-1]] + 1);\n        split_y = min(split_y, y[ids[mid]] + 1);\n        split_y = max(y1 + 1, min(y2 - 1, split_y));\n        \n        vector<int> top(ids.begin(), ids.begin() + mid);\n        vector<int> bottom(ids.begin() + mid, ids.end());\n        \n        solve(top, x1, y1, x2, split_y);\n        solve(bottom, x1, split_y, x2, y2);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n;\n    x.resize(n);\n    y.resize(n);\n    r.resize(n);\n    result.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> x[i] >> y[i] >> r[i];\n    }\n    \n    vector<int> all_ids(n);\n    iota(all_ids.begin(), all_ids.end(), 0);\n    \n    solve(all_ids, 0, 0, 10000, 10000);\n    \n    for (int i = 0; i < n; i++) {\n        cout << result[i][0] << \" \" << result[i][1] << \" \" \n             << result[i][2] << \" \" << result[i][3] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nmap<int, vector<pair<int,int>>> tile_squares;\nmap<int, int> tile_value;\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < 50 && y >= 0 && y < 50;\n}\n\nint main() {\n    cin >> si >> sj;\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> t[i][j];\n            tile_squares[t[i][j]].push_back({i, j});\n        }\n    }\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> p[i][j];\n            tile_value[t[i][j]] += p[i][j];\n        }\n    }\n    \n    bool visited_tile[2500] = {};\n    bool visited_square[50][50] = {};\n    string path = \"\";\n    int x = si, y = sj;\n    visited_tile[t[x][y]] = true;\n    visited_square[x][y] = true;\n    \n    while (true) {\n        int current_tile = t[x][y];\n        \n        // First priority: visit other squares of current tile\n        int best_dir = -1;\n        int best_value = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (!in_bounds(nx, ny)) continue;\n            if (visited_square[nx][ny]) continue;\n            \n            int next_tile = t[nx][ny];\n            \n            if (next_tile == current_tile) {\n                if (best_dir == -1 || p[nx][ny] > best_value) {\n                    best_value = p[nx][ny];\n                    best_dir = d;\n                }\n            }\n        }\n        \n        // Second priority: move to new tile with highest total value\n        if (best_dir == -1) {\n            int best_tile_value = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                \n                if (!in_bounds(nx, ny)) continue;\n                if (visited_square[nx][ny]) continue;\n                \n                int next_tile = t[nx][ny];\n                \n                if (visited_tile[next_tile]) continue;\n                \n                if (tile_value[next_tile] > best_tile_value) {\n                    best_tile_value = tile_value[next_tile];\n                    best_dir = d;\n                }\n            }\n        }\n        \n        if (best_dir == -1) break;\n        \n        int nx = x + dx[best_dir];\n        int ny = y + dy[best_dir];\n        \n        path += dir_char[best_dir];\n        visited_square[nx][ny] = true;\n        visited_tile[t[nx][ny]] = true;\n        \n        x = nx;\n        y = ny;\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst double INF = 1e18;\nconst double DEFAULT_WEIGHT = 5000.0;\nconst double ALPHA = 0.3;\n\ndouble h[N][N], v[N][N]; // h[i][j]: (i,j)->(i,j+1), v[i][j]: (i,j)->(i+1,j)\n\nvoid init_weights() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            h[i][j] = DEFAULT_WEIGHT;\n            v[i][j] = DEFAULT_WEIGHT;\n        }\n    }\n}\n\npair<double, vector<pair<int,int>>> dijkstra(int si, int sj, int ti, int tj) {\n    vector<vector<double>> dist(N, vector<double>(N, INF));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    priority_queue<pair<double, pair<int,int>>, \n                   vector<pair<double, pair<int,int>>>,\n                   greater<>> pq;\n    \n    dist[si][sj] = 0;\n    pq.push({0, {si, sj}});\n    \n    while (!pq.empty()) {\n        auto [d, pos] = pq.top();\n        pq.pop();\n        auto [i, j] = pos;\n        \n        if (d > dist[i][j]) continue;\n        \n        if (i > 0 && dist[i][j] + v[i-1][j] < dist[i-1][j]) {\n            dist[i-1][j] = dist[i][j] + v[i-1][j];\n            parent[i-1][j] = {i, j};\n            pq.push({dist[i-1][j], {i-1, j}});\n        }\n        if (i < N-1 && dist[i][j] + v[i][j] < dist[i+1][j]) {\n            dist[i+1][j] = dist[i][j] + v[i][j];\n            parent[i+1][j] = {i, j};\n            pq.push({dist[i+1][j], {i+1, j}});\n        }\n        if (j > 0 && dist[i][j] + h[i][j-1] < dist[i][j-1]) {\n            dist[i][j-1] = dist[i][j] + h[i][j-1];\n            parent[i][j-1] = {i, j};\n            pq.push({dist[i][j-1], {i, j-1}});\n        }\n        if (j < N-1 && dist[i][j] + h[i][j] < dist[i][j+1]) {\n            dist[i][j+1] = dist[i][j] + h[i][j];\n            parent[i][j+1] = {i, j};\n            pq.push({dist[i][j+1], {i, j+1}});\n        }\n    }\n    \n    vector<pair<int,int>> path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        path.push_back({ci, cj});\n        auto [pi, pj] = parent[ci][cj];\n        if (pi == -1) break;\n        ci = pi;\n        cj = pj;\n    }\n    path.push_back({si, sj});\n    reverse(path.begin(), path.end());\n    \n    return {dist[ti][tj], path};\n}\n\nstring path_to_string(const vector<pair<int,int>>& path) {\n    string result;\n    for (int i = 1; i < path.size(); i++) {\n        int di = path[i].first - path[i-1].first;\n        int dj = path[i].second - path[i-1].second;\n        if (di == -1) result += 'U';\n        else if (di == 1) result += 'D';\n        else if (dj == -1) result += 'L';\n        else result += 'R';\n    }\n    return result;\n}\n\nvoid update_weights(const vector<pair<int,int>>& path, double measured, double estimated) {\n    if (path.size() <= 1) return;\n    \n    int num_edges = path.size() - 1;\n    double error = measured - estimated;\n    double correction = error / num_edges;\n    \n    for (int i = 1; i < path.size(); i++) {\n        int pi = path[i-1].first, pj = path[i-1].second;\n        int ci = path[i].first, cj = path[i].second;\n        \n        if (pi == ci) {\n            int j = min(pj, cj);\n            h[pi][j] += ALPHA * correction;\n            h[pi][j] = max(100.0, min(10000.0, h[pi][j]));\n        } else {\n            int i = min(pi, ci);\n            v[i][pj] += ALPHA * correction;\n            v[i][pj] = max(100.0, min(10000.0, v[i][pj]));\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_weights();\n    \n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        auto [estimated_len, path] = dijkstra(si, sj, ti, tj);\n        string path_str = path_to_string(path);\n        \n        cout << path_str << endl;\n        cout.flush();\n        \n        int measured;\n        cin >> measured;\n        \n        update_weights(path, measured, estimated_len);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nvector<string> strings;\nchar matrix[20][20];\n\nbool isSubsequence(const string& s) {\n    int k = s.length();\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            bool ok = true;\n            for (int p = 0; p < k; p++) {\n                if (matrix[i][(j + p) % N] != s[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return true;\n            \n            ok = true;\n            for (int p = 0; p < k; p++) {\n                if (matrix[(i + p) % N][j] != s[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return true;\n        }\n    }\n    return false;\n}\n\nint countConflicts(const string& s, int i, int j, int d) {\n    int k = s.length();\n    int conflicts = 0;\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        if (matrix[ni][nj] != '.' && matrix[ni][nj] != s[p]) {\n            conflicts++;\n        }\n    }\n    return conflicts;\n}\n\nvoid place(const string& s, int i, int j, int d) {\n    int k = s.length();\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        matrix[ni][nj] = s[p];\n    }\n}\n\nint main() {\n    cin >> N >> M;\n    strings.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            matrix[i][j] = '.';\n        }\n    }\n    \n    // Multiple passes with increasing conflict tolerance\n    for (int maxConflicts = 0; maxConflicts <= 2; maxConflicts++) {\n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        \n        // Sort by length (longer strings first)\n        sort(order.begin(), order.end(), [](int a, int b) {\n            return strings[a].length() > strings[b].length();\n        });\n        \n        for (int idx : order) {\n            const string& s = strings[idx];\n            \n            if (isSubsequence(s)) continue;\n            \n            int bestI = -1, bestJ = -1, bestD = -1;\n            int minConflicts = INT_MAX;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    for (int d = 0; d < 2; d++) {\n                        int conflicts = countConflicts(s, i, j, d);\n                        if (conflicts < minConflicts) {\n                            minConflicts = conflicts;\n                            bestI = i;\n                            bestJ = j;\n                            bestD = d;\n                        }\n                    }\n                }\n            }\n            \n            if (minConflicts <= maxConflicts && bestI != -1) {\n                place(s, bestI, bestJ, bestD);\n            }\n        }\n    }\n    \n    // Fill remaining dots with 'A'\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (matrix[i][j] == '.') {\n                matrix[i][j] = 'A';\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << matrix[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\n\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nbool is_valid(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\nset<pair<int,int>> get_visible(int i, int j) {\n    set<pair<int,int>> vis;\n    vis.insert({i, j});\n    // Horizontal visibility\n    for (int jj = j-1; jj >= 0 && grid[i][jj] != '#'; jj--) vis.insert({i, jj});\n    for (int jj = j+1; jj < N && grid[i][jj] != '#'; jj++) vis.insert({i, jj});\n    // Vertical visibility\n    for (int ii = i-1; ii >= 0 && grid[ii][j] != '#'; ii--) vis.insert({ii, j});\n    for (int ii = i+1; ii < N && grid[ii][j] != '#'; ii++) vis.insert({ii, j});\n    return vis;\n}\n\nstring bfs_path(int si, int sj, int ti, int tj) {\n    if (si == ti && sj == tj) return \"\";\n    \n    map<pair<int,int>, pair<pair<int,int>, int>> parent;\n    queue<pair<int,int>> q;\n    q.push({si, sj});\n    parent[{si, sj}] = {{-1, -1}, -1};\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        if (i == ti && j == tj) {\n            string path;\n            auto curr = make_pair(ti, tj);\n            while (parent[curr].second != -1) {\n                path += dir_char[parent[curr].second];\n                curr = parent[curr].first;\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = i + di[d], nj = j + dj[d];\n            if (is_valid(ni, nj) && parent.find({ni, nj}) == parent.end()) {\n                parent[{ni, nj}] = {{i, j}, d};\n                q.push({ni, nj});\n            }\n        }\n    }\n    return \"\";\n}\n\nint main() {\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    vector<pair<int,int>> roads;\n    set<pair<int,int>> all_roads;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                roads.push_back({i, j});\n                all_roads.insert({i, j});\n            }\n        }\n    }\n    \n    // Precompute visibility\n    map<pair<int,int>, set<pair<int,int>>> visible_from;\n    for (auto& [i, j] : roads) {\n        visible_from[{i, j}] = get_visible(i, j);\n    }\n    \n    set<pair<int,int>> covered = visible_from[{si, sj}];\n    string result;\n    int ci = si, cj = sj;\n    \n    // Greedy: visit positions that maximize new coverage\n    while (covered.size() < all_roads.size()) {\n        int best_new = 0;\n        pair<int,int> best_pos = {ci, cj};\n        \n        for (auto& [ri, rj] : roads) {\n            int new_count = 0;\n            for (auto& sq : visible_from[{ri, rj}]) {\n                if (covered.find(sq) == covered.end()) new_count++;\n            }\n            if (new_count > best_new) {\n                best_new = new_count;\n                best_pos = {ri, rj};\n            }\n        }\n        \n        if (best_new == 0) break;\n        \n        string path = bfs_path(ci, cj, best_pos.first, best_pos.second);\n        result += path;\n        ci = best_pos.first;\n        cj = best_pos.second;\n        \n        for (auto& sq : visible_from[{ci, cj}]) covered.insert(sq);\n    }\n    \n    result += bfs_path(ci, cj, si, sj);\n    cout << result << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <map>\n#include <cmath>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> task_diff;\nvector<vector<int>> task_deps;\nvector<int> task_status; // -1: not started, 0: running, 1: done\nvector<vector<double>> member_skill;\nvector<int> member_task;\nmap<int, int> start_day_map;\n\nbool can_start(int task) {\n    if (task_status[task] != -1) return false;\n    for (int dep : task_deps[task]) {\n        if (task_status[dep] != 1) return false;\n    }\n    return true;\n}\n\ndouble estimate_time(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++) {\n        w += max(0.0, task_diff[task][k] - member_skill[member][k]);\n    }\n    return (w < 0.5) ? 1.0 : w + 1.0;\n}\n\nvoid update_skill(int member, int task, int days) {\n    if (days == 1) {\n        // w=0, so member has all required skills\n        for (int k = 0; k < K; k++) {\n            member_skill[member][k] = max(member_skill[member][k], \n                                         (double)task_diff[task][k]);\n        }\n    }\n}\n\nint main() {\n    cin >> N >> M >> K >> R;\n    \n    task_diff.resize(N, vector<int>(K));\n    task_deps.resize(N);\n    task_status.resize(N, -1);\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> task_diff[i][j];\n        }\n    }\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        task_deps[v].push_back(u);\n    }\n    \n    member_skill.resize(M, vector<double>(K, 30.0));\n    member_task.resize(M, -1);\n    \n    int day = 0;\n    \n    while (true) {\n        day++;\n        \n        vector<int> available;\n        for (int i = 0; i < N; i++) {\n            if (can_start(i)) available.push_back(i);\n        }\n        \n        vector<int> idle;\n        for (int i = 0; i < M; i++) {\n            if (member_task[i] == -1) idle.push_back(i);\n        }\n        \n        vector<pair<int, int>> assign;\n        \n        for (int m : idle) {\n            if (available.empty()) break;\n            \n            int best = -1;\n            double best_score = 1e9;\n            \n            for (int t : available) {\n                double score = estimate_time(t, m);\n                if (score < best_score) {\n                    best_score = score;\n                    best = t;\n                }\n            }\n            \n            if (best != -1) {\n                assign.push_back({m, best});\n                member_task[m] = best;\n                task_status[best] = 0;\n                start_day_map[m] = day;\n                available.erase(remove(available.begin(), available.end(), best),\n                              available.end());\n            }\n        }\n        \n        cout << assign.size();\n        for (auto [m, t] : assign) {\n            cout << \" \" << (m + 1) << \" \" << (t + 1);\n        }\n        cout << endl;\n        cout.flush();\n        \n        int n;\n        cin >> n;\n        if (n == -1) break;\n        \n        for (int i = 0; i < n; i++) {\n            int m;\n            cin >> m;\n            m--;\n            int t = member_task[m];\n            int days = day - start_day_map[m] + 1;\n            task_status[t] = 1;\n            member_task[m] = -1;\n            update_skill(m, t, days);\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <chrono>\n\nusing namespace std;\n\nstruct Order {\n    int id;\n    int ax, ay, cx, cy;\n};\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nclass Solution {\npublic:\n    vector<Order> orders;\n    vector<int> selected_orders;\n    vector<pair<int, int>> route;\n    \n    void read_input() {\n        orders.resize(1000);\n        for (int i = 0; i < 1000; i++) {\n            orders[i].id = i;\n            cin >> orders[i].ax >> orders[i].ay >> orders[i].cx >> orders[i].cy;\n        }\n    }\n    \n    void select_orders_by_proximity() {\n        // Score each order by total distance involved\n        vector<pair<int, int>> scores;\n        for (int i = 0; i < 1000; i++) {\n            // Distance from office to pickup\n            int dist_from_office = manhattan(400, 400, orders[i].ax, orders[i].ay);\n            // Distance from delivery to office\n            int dist_to_office = manhattan(orders[i].cx, orders[i].cy, 400, 400);\n            // Distance from pickup to delivery\n            int pickup_delivery = manhattan(orders[i].ax, orders[i].ay, orders[i].cx, orders[i].cy);\n            \n            int total_score = dist_from_office + dist_to_office + pickup_delivery;\n            scores.push_back({total_score, i});\n        }\n        \n        // Select 50 orders with minimum total distance\n        sort(scores.begin(), scores.end());\n        selected_orders.clear();\n        for (int i = 0; i < 50; i++) {\n            selected_orders.push_back(scores[i].second);\n        }\n    }\n    \n    void construct_route_greedy() {\n        route.clear();\n        route.push_back({400, 400}); // Start at office\n        \n        set<int> need_pickup(selected_orders.begin(), selected_orders.end());\n        set<int> need_delivery;\n        \n        int cx = 400, cy = 400; // Current position\n        \n        // Greedy nearest neighbor with precedence constraints\n        while (!need_pickup.empty() || !need_delivery.empty()) {\n            int best_idx = -1;\n            int best_dist = 2000000;\n            bool is_pickup = false;\n            \n            // Check all pickups\n            for (int idx : need_pickup) {\n                int d = manhattan(cx, cy, orders[idx].ax, orders[idx].ay);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = true;\n                }\n            }\n            \n            // Check all deliveries (only for already picked up orders)\n            for (int idx : need_delivery) {\n                int d = manhattan(cx, cy, orders[idx].cx, orders[idx].cy);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = false;\n                }\n            }\n            \n            // Move to best location\n            if (is_pickup) {\n                route.push_back({orders[best_idx].ax, orders[best_idx].ay});\n                cx = orders[best_idx].ax;\n                cy = orders[best_idx].ay;\n                need_pickup.erase(best_idx);\n                need_delivery.insert(best_idx);\n            } else {\n                route.push_back({orders[best_idx].cx, orders[best_idx].cy});\n                cx = orders[best_idx].cx;\n                cy = orders[best_idx].cy;\n                need_delivery.erase(best_idx);\n            }\n        }\n        \n        route.push_back({400, 400}); // Return to office\n    }\n    \n    void output() {\n        cout << selected_orders.size();\n        for (int idx : selected_orders) {\n            cout << \" \" << (idx + 1); // Convert to 1-indexed\n        }\n        cout << \"\\n\";\n        \n        cout << route.size();\n        for (auto [x, y] : route) {\n            cout << \" \" << x << \" \" << y;\n        }\n        cout << \"\\n\";\n        cout.flush();\n    }\n    \n    void solve() {\n        read_input();\n        select_orders_by_proximity();\n        construct_route_greedy();\n        output();\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.solve();\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent, rank;\npublic:\n    UnionFind(int n) : parent(n), rank(n, 0) {\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    \n    int find(int x) {\n        return parent[x] == x ? x : parent[x] = find(parent[x]);\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400, M = 1995;\n    \n    vector<pair<int,int>> coord(N);\n    for (auto& [x, y] : coord) cin >> x >> y;\n    \n    vector<pair<int,int>> edge(M);\n    vector<int> dist(M);\n    \n    for (int i = 0; i < M; i++) {\n        auto& [u, v] = edge[i];\n        cin >> u >> v;\n        int dx = coord[u].first - coord[v].first;\n        int dy = coord[u].second - coord[v].second;\n        dist[i] = round(sqrt(dx*dx + dy*dy));\n    }\n    \n    UnionFind uf(N);\n    int cnt = 0;\n    \n    for (int i = 0; i < M; i++) {\n        int len;\n        cin >> len;\n        \n        auto [u, v] = edge[i];\n        int d = dist[i];\n        \n        bool ok = false;\n        if (uf.find(u) != uf.find(v)) {\n            int need = N - 1 - cnt;\n            int left = M - i;\n            \n            double r = (double)len / d;\n            double th;\n            \n            // Adaptive threshold based on safety margin\n            if (left <= need * 1.2) {\n                th = 3.0;  // Emergency mode: accept anything\n            } else if (left <= need * 2.0) {\n                th = 2.3;  // Getting tight\n            } else if (left <= need * 3.0) {\n                th = 1.9;  // Moderate selectivity\n            } else {\n                th = 1.7;  // Plenty of room: be selective\n            }\n            \n            ok = (r <= th);\n        }\n        \n        cout << (ok ? \"1\" : \"0\") << \"\\n\" << flush;\n        if (ok) {\n            uf.unite(u, v);\n            cnt++;\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Pos {\n    int x, y;\n    bool operator<(const Pos& o) const {\n        return x < o.x || (x == o.x && y < o.y);\n    }\n};\n\nint N, M;\nvector<Pos> pets, humans;\nvector<int> pet_types;\nbool grid[32][32];\nset<Pos> pet_set;\n\nvoid init() {\n    cin >> N;\n    pets.resize(N);\n    pet_types.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pet_types[i];\n        pet_set.insert(pets[i]);\n    }\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n    \n    for (int i = 0; i <= 31; i++)\n        for (int j = 0; j <= 31; j++)\n            grid[i][j] = (i >= 1 && i <= 30 && j >= 1 && j <= 30);\n}\n\nbool is_adjacent_to_pet(int x, int y) {\n    return pet_set.count({x-1, y}) || pet_set.count({x+1, y}) ||\n           pet_set.count({x, y-1}) || pet_set.count({x, y+1});\n}\n\nbool has_entity(int x, int y) {\n    if (pet_set.count({x, y})) return true;\n    for (auto& h : humans)\n        if (h.x == x && h.y == y) return true;\n    return false;\n}\n\nint main() {\n    init();\n    \n    // Find safe corner farthest from pets\n    int tx = 15, ty = 15;\n    double max_dist = 0;\n    for (int cx : {8, 22}) {\n        for (int cy : {8, 22}) {\n            double dist = 0;\n            for (auto& p : pets)\n                dist += abs(p.x - cx) + abs(p.y - cy);\n            if (dist > max_dist) {\n                max_dist = dist;\n                tx = cx; ty = cy;\n            }\n        }\n    }\n    \n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n        \n        // Calculate center of humans\n        int cx = 0, cy = 0;\n        for (auto& h : humans) { cx += h.x; cy += h.y; }\n        cx /= M; cy /= M;\n        \n        for (int i = 0; i < M; i++) {\n            int x = humans[i].x, y = humans[i].y;\n            bool acted = false;\n            \n            // Try building walls in expanding square pattern\n            vector<pair<int,int>> dirs = {{-1,0},{1,0},{0,-1},{0,1}};\n            string wall = \"udlr\", move = \"UDLR\";\n            \n            // Prioritize building walls on perimeter\n            int best_d = -1;\n            int max_score = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = x + dirs[d].first;\n                int ny = y + dirs[d].second;\n                \n                if (nx >= 1 && nx <= 30 && ny >= 1 && ny <= 30 &&\n                    grid[nx][ny] && !has_entity(nx, ny) && !is_adjacent_to_pet(nx, ny)) {\n                    \n                    // Score: prefer positions farther from center (perimeter)\n                    int score = abs(nx - cx) + abs(ny - cy);\n                    if (score > max_score) {\n                        max_score = score;\n                        best_d = d;\n                    }\n                }\n            }\n            \n            if (best_d >= 0) {\n                actions[i] = wall[best_d];\n                int nx = x + dirs[best_d].first;\n                int ny = y + dirs[best_d].second;\n                grid[nx][ny] = false;\n                acted = true;\n            }\n            \n            // Move toward target if far away and early in game\n            if (!acted && turn < 50) {\n                int dx = (x < tx) ? 1 : (x > tx) ? -1 : 0;\n                int dy = (y < ty) ? 1 : (y > ty) ? -1 : 0;\n                \n                if (dx && grid[x+dx][y]) {\n                    actions[i] = (dx < 0) ? 'U' : 'D';\n                    humans[i].x += dx;\n                } else if (dy && grid[x][y+dy]) {\n                    actions[i] = (dy < 0) ? 'L' : 'R';\n                    humans[i].y += dy;\n                }\n            }\n        }\n        \n        cout << actions << endl;\n        cout.flush();\n        \n        // Update pet positions\n        pet_set.clear();\n        for (int i = 0; i < N; i++) {\n            string mov;\n            cin >> mov;\n            for (char c : mov) {\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n            pet_set.insert(pets[i]);\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    if (si == ti && sj == tj) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    // BFS to find shortest path\n    queue<tuple<int,int,string>> q;\n    vector<vector<bool>> visited(20, vector<bool>(20, false));\n    q.push({si, sj, \"\"});\n    visited[si][sj] = true;\n    \n    string path = \"\";\n    while (!q.empty()) {\n        auto [i, j, cur_path] = q.front();\n        q.pop();\n        \n        if (i == ti && j == tj) {\n            path = cur_path;\n            break;\n        }\n        \n        // Try all 4 directions\n        if (i < 19 && v[i][j] == '0' && !visited[i+1][j]) {\n            visited[i+1][j] = true;\n            q.push({i+1, j, cur_path + \"D\"});\n        }\n        if (j < 19 && h[i][j] == '0' && !visited[i][j+1]) {\n            visited[i][j+1] = true;\n            q.push({i, j+1, cur_path + \"R\"});\n        }\n        if (i > 0 && v[i-1][j] == '0' && !visited[i-1][j]) {\n            visited[i-1][j] = true;\n            q.push({i-1, j, cur_path + \"U\"});\n        }\n        if (j > 0 && h[i][j-1] == '0' && !visited[i][j-1]) {\n            visited[i][j-1] = true;\n            q.push({i, j-1, cur_path + \"L\"});\n        }\n    }\n    \n    // Count moves\n    int cnt_U = 0, cnt_D = 0, cnt_L = 0, cnt_R = 0;\n    for (char c : path) {\n        if (c == 'U') cnt_U++;\n        else if (c == 'D') cnt_D++;\n        else if (c == 'L') cnt_L++;\n        else if (c == 'R') cnt_R++;\n    }\n    \n    // Determine repetition factor\n    int L = path.length();\n    int max_repeat = 200 / max(1, L);\n    \n    int repeat;\n    if (p <= 0.15) repeat = min(max_repeat, 3);\n    else if (p <= 0.25) repeat = min(max_repeat, 4);\n    else if (p <= 0.35) repeat = min(max_repeat, 5);\n    else if (p <= 0.45) repeat = min(max_repeat, 6);\n    else repeat = min(max_repeat, 7);\n    \n    repeat = max(1, repeat);\n    \n    // Multiply counts\n    cnt_U *= repeat;\n    cnt_D *= repeat;\n    cnt_L *= repeat;\n    cnt_R *= repeat;\n    \n    // Interleave moves\n    string result = \"\";\n    while (result.length() < 200 && (cnt_U + cnt_D + cnt_L + cnt_R > 0)) {\n        if (cnt_D > 0) { result += 'D'; cnt_D--; }\n        if (cnt_R > 0 && result.length() < 200) { result += 'R'; cnt_R--; }\n        if (cnt_U > 0 && result.length() < 200) { result += 'U'; cnt_U--; }\n        if (cnt_L > 0 && result.length() < 200) { result += 'L'; cnt_L--; }\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nint di[4] = {0, -1, 0, 1};\nint dj[4] = {-1, 0, 1, 0};\n\nint to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\nint rotateTile(int tile, int rot) {\n    rot = rot % 4;\n    for (int i = 0; i < rot; i++) {\n        if (tile <= 3) {\n            tile = (tile + 1) % 4;\n        } else if (tile <= 5) {\n            tile = (tile == 4) ? 5 : 4;\n        } else {\n            tile = (tile == 6) ? 7 : 6;\n        }\n    }\n    return tile;\n}\n\nint getLoopLength(int si, int sj, int sd, const vector<vector<int>>& current) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    while (length <= 2000) {\n        int tile = current[i][j];\n        int d2 = to[tile][d];\n        if (d2 == -1) return 0;\n        \n        i += di[d2];\n        j += dj[d2];\n        if (i < 0 || i >= N || j < 0 || j >= N) return 0;\n        \n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (i == si && j == sj && d == sd) return length;\n    }\n    return 0;\n}\n\nlong long calculateScore(const vector<vector<int>>& current) {\n    vector<int> loops;\n    vector<vector<vector<bool>>> visited(N, vector<vector<bool>>(N, vector<bool>(4, false)));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (visited[i][j][d]) continue;\n                \n                int len = getLoopLength(i, j, d, current);\n                if (len > 0) {\n                    loops.push_back(len);\n                    \n                    int ii = i, jj = j, dd = d;\n                    for (int step = 0; step < len; step++) {\n                        visited[ii][jj][dd] = true;\n                        int tile = current[ii][jj];\n                        int d2 = to[tile][dd];\n                        ii += di[d2];\n                        jj += dj[d2];\n                        dd = (d2 + 2) % 4;\n                    }\n                }\n            }\n        }\n    }\n    \n    sort(loops.rbegin(), loops.rend());\n    \n    if (loops.size() < 2) return 0;\n    return (long long)loops[0] * loops[1];\n}\n\nint main() {\n    auto start = chrono::steady_clock::now();\n    \n    vector<string> tiles(N);\n    for (int i = 0; i < N; i++) {\n        cin >> tiles[i];\n    }\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n    \n    vector<vector<int>> rotation(N, vector<int>(N));\n    vector<vector<int>> current(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            rotation[i][j] = gen() % 4;\n            int tile = tiles[i][j] - '0';\n            current[i][j] = rotateTile(tile, rotation[i][j]);\n        }\n    }\n    \n    long long currentScore = calculateScore(current);\n    long long bestScore = currentScore;\n    vector<vector<int>> bestRotation = rotation;\n    \n    double temp = 100.0;\n    double coolingRate = 0.99995;\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.8) break;\n        \n        int i = gen() % N;\n        int j = gen() % N;\n        int oldRot = rotation[i][j];\n        int newRot = gen() % 4;\n        \n        if (oldRot == newRot) continue;\n        \n        rotation[i][j] = newRot;\n        int tile = tiles[i][j] - '0';\n        current[i][j] = rotateTile(tile, newRot);\n        \n        long long score = calculateScore(current);\n        long long delta = score - currentScore;\n        \n        if (delta > 0 || dis(gen) < exp(delta / temp)) {\n            currentScore = score;\n            if (score > bestScore) {\n                bestScore = score;\n                bestRotation = rotation;\n            }\n        } else {\n            rotation[i][j] = oldRot;\n            current[i][j] = rotateTile(tile, oldRot);\n        }\n        \n        temp *= coolingRate;\n    }\n    \n    string output;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            output += ('0' + bestRotation[i][j]);\n        }\n    }\n    cout << output << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> board;\nint empty_i, empty_j;\n\nvoid find_empty() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == '0') {\n                empty_i = i;\n                empty_j = j;\n                return;\n            }\n        }\n    }\n}\n\nint get_tile(int i, int j) {\n    if (i < 0 || i >= N || j < 0 || j >= N) return -1;\n    char c = board[i][j];\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\nint calculate_tree_size() {\n    vector<int> parent(N * N);\n    iota(parent.begin(), parent.end(), 0);\n    \n    function<int(int)> find = [&](int x) {\n        return parent[x] == x ? x : parent[x] = find(parent[x]);\n    };\n    \n    auto unite = [&](int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x != y) parent[x] = y;\n    };\n    \n    // Check vertical connections\n    for (int i = 0; i < N - 1; i++) {\n        for (int j = 0; j < N; j++) {\n            int t1 = get_tile(i, j);\n            int t2 = get_tile(i + 1, j);\n            if (t1 > 0 && t2 > 0 && (t1 & 8) && (t2 & 2)) {\n                unite(i * N + j, (i + 1) * N + j);\n            }\n        }\n    }\n    \n    // Check horizontal connections\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N - 1; j++) {\n            int t1 = get_tile(i, j);\n            int t2 = get_tile(i, j + 1);\n            if (t1 > 0 && t2 > 0 && (t1 & 4) && (t2 & 1)) {\n                unite(i * N + j, i * N + j + 1);\n            }\n        }\n    }\n    \n    // Count components and detect cycles\n    map<int, vector<int>> components;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (get_tile(i, j) > 0) {\n                components[find(i * N + j)].push_back(i * N + j);\n            }\n        }\n    }\n    \n    int max_tree_size = 0;\n    for (auto& [root, nodes] : components) {\n        int edges = 0;\n        for (int node : nodes) {\n            int i = node / N, j = node % N;\n            int t = get_tile(i, j);\n            if (i + 1 < N) {\n                int t2 = get_tile(i + 1, j);\n                if (t2 > 0 && (t & 8) && (t2 & 2) && find((i+1)*N+j) == root) {\n                    edges++;\n                }\n            }\n            if (j + 1 < N) {\n                int t2 = get_tile(i, j + 1);\n                if (t2 > 0 && (t & 4) && (t2 & 1) && find(i*N+j+1) == root) {\n                    edges++;\n                }\n            }\n        }\n        \n        if (edges == (int)nodes.size() - 1) {\n            max_tree_size = max(max_tree_size, (int)nodes.size());\n        }\n    }\n    \n    return max_tree_size;\n}\n\nbool can_move(char dir) {\n    if (dir == 'U') return empty_i > 0;\n    if (dir == 'D') return empty_i < N - 1;\n    if (dir == 'L') return empty_j > 0;\n    if (dir == 'R') return empty_j < N - 1;\n    return false;\n}\n\nvoid make_move(char dir) {\n    int ni = empty_i, nj = empty_j;\n    if (dir == 'U') ni--;\n    else if (dir == 'D') ni++;\n    else if (dir == 'L') nj--;\n    else if (dir == 'R') nj++;\n    \n    swap(board[empty_i][empty_j], board[ni][nj]);\n    empty_i = ni;\n    empty_j = nj;\n}\n\nint main() {\n    cin >> N >> T;\n    board.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    find_empty();\n    \n    string moves = \"\";\n    int current_score = calculate_tree_size();\n    \n    string dirs = \"UDLR\";\n    char last_move = ' ';\n    \n    mt19937 rng(42);\n    \n    for (int iter = 0; iter < T * 2; iter++) {\n        if (moves.length() >= T) break;\n        if (current_score == N * N - 1) break;\n        \n        vector<pair<int, char>> candidates;\n        \n        for (char dir : dirs) {\n            if (last_move == 'U' && dir == 'D') continue;\n            if (last_move == 'D' && dir == 'U') continue;\n            if (last_move == 'L' && dir == 'R') continue;\n            if (last_move == 'R' && dir == 'L') continue;\n            \n            if (!can_move(dir)) continue;\n            \n            auto old_board = board;\n            int old_i = empty_i, old_j = empty_j;\n            make_move(dir);\n            int new_score = calculate_tree_size();\n            \n            candidates.push_back({new_score, dir});\n            \n            board = old_board;\n            empty_i = old_i;\n            empty_j = old_j;\n        }\n        \n        if (candidates.empty()) break;\n        \n        sort(candidates.rbegin(), candidates.rend());\n        \n        char best_dir = candidates[0].second;\n        int best_score = candidates[0].first;\n        \n        if (best_score >= current_score || (best_score >= current_score - 2 && rng() % 100 < 10)) {\n            make_move(best_dir);\n            moves += best_dir;\n            current_score = best_score;\n            last_move = best_dir;\n        } else {\n            break;\n        }\n    }\n    \n    cout << moves << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, K;\n    cin >> N >> K;\n    \n    vector<int> a(11);\n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    \n    vector<pair<int, int>> points(N);\n    for (int i = 0; i < N; i++) {\n        cin >> points[i].first >> points[i].second;\n    }\n    \n    // Sort strawberries by angle around origin\n    sort(points.begin(), points.end(), [](const auto& p1, const auto& p2) {\n        return atan2(p1.second, p1.first) < atan2(p2.second, p2.first);\n    });\n    \n    // Create priority list: (demand count, size)\n    vector<pair<int, int>> priority;\n    for (int d = 1; d <= 10; d++) {\n        if (a[d] > 0) {\n            priority.push_back({a[d], d});\n        }\n    }\n    sort(priority.rbegin(), priority.rend()); // Highest demand first\n    \n    // Greedy partitioning\n    vector<int> remaining_demand = a;\n    vector<int> partition;\n    int pos = 0;\n    \n    while (pos < N) {\n        int chosen_size = N - pos; // Default: use all remaining\n        \n        // Try to find a size with remaining demand that fits\n        for (auto [demand, size] : priority) {\n            if (remaining_demand[size] > 0 && pos + size <= N) {\n                chosen_size = size;\n                break;\n            }\n        }\n        \n        // If no good match, try any size that has demand\n        if (chosen_size > 10 || remaining_demand[chosen_size] == 0) {\n            for (int d = 10; d >= 1; d--) {\n                if (remaining_demand[d] > 0 && pos + d <= N) {\n                    chosen_size = d;\n                    break;\n                }\n            }\n        }\n        \n        // Ensure we don't exceed available strawberries\n        chosen_size = min(chosen_size, N - pos);\n        \n        partition.push_back(chosen_size);\n        if (chosen_size <= 10 && remaining_demand[chosen_size] > 0) {\n            remaining_demand[chosen_size]--;\n        }\n        pos += chosen_size;\n    }\n    \n    // Generate radial cuts between partition boundaries\n    vector<array<long long, 4>> cuts;\n    int cumulative = 0;\n    \n    for (int size : partition) {\n        cumulative += size;\n        \n        if (cumulative < N && cuts.size() < K) {\n            auto [x1, y1] = points[cumulative - 1];\n            auto [x2, y2] = points[cumulative];\n            \n            double a1 = atan2(y1, x1);\n            double a2 = atan2(y2, x2);\n            double mid = (a1 + a2) / 2.0;\n            \n            // Handle angle wrap-around (when crossing from +\u03c0 to -\u03c0)\n            if (a2 - a1 < -M_PI) {\n                mid += M_PI;\n            } else if (a2 - a1 > M_PI) {\n                mid -= M_PI;\n            }\n            \n            // Create line from origin through the midpoint angle\n            long long qx = llround(1e9 * cos(mid));\n            long long qy = llround(1e9 * sin(mid));\n            \n            cuts.push_back({0, 0, qx, qy});\n        }\n    }\n    \n    // Output\n    cout << cuts.size() << '\\n';\n    for (auto [px, py, qx, qy] : cuts) {\n        cout << px << ' ' << py << ' ' << qx << ' ' << qy << '\\n';\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\nint N, M;\nset<pair<int,int>> dots;\nvector<vector<int>> operations;\nset<vector<int>> usedEdges;\n\n// Check if 4 points form a rectangle and return ordered points\nbool checkAndOrderRect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, \n                       vector<int>& ordered) {\n    vector<pair<int,int>> pts = {{x1,y1}, {x2,y2}, {x3,y3}, {x4,y4}};\n    \n    // Calculate all pairwise squared distances\n    vector<long long> dists;\n    for (int i = 0; i < 4; i++) {\n        for (int j = i + 1; j < 4; j++) {\n            long long dx = pts[i].first - pts[j].first;\n            long long dy = pts[i].second - pts[j].second;\n            dists.push_back(dx * dx + dy * dy);\n        }\n    }\n    sort(dists.begin(), dists.end());\n    \n    // Rectangle: 4 equal sides, 2 equal diagonals\n    if (!(dists[0] == dists[1] && dists[1] == dists[2] && dists[2] == dists[3] &&\n          dists[4] == dists[5] && dists[3] > 0 && dists[3] < dists[4])) {\n        return false;\n    }\n    \n    // Find ordering: start with pt 0, find neighbors\n    vector<vector<int>> adj(4);\n    for (int i = 0; i < 4; i++) {\n        for (int j = i + 1; j < 4; j++) {\n            long long dx = pts[i].first - pts[j].first;\n            long long dy = pts[i].second - pts[j].second;\n            long long d = dx * dx + dy * dy;\n            if (d == dists[0]) { // side length\n                adj[i].push_back(j);\n                adj[j].push_back(i);\n            }\n        }\n    }\n    \n    // Order: 0 -> neighbor1 -> opposite corner -> neighbor2 -> back to 0\n    vector<int> order = {0};\n    order.push_back(adj[0][0]);\n    int next = (adj[order[1]][0] == 0) ? adj[order[1]][1] : adj[order[1]][0];\n    order.push_back(next);\n    next = (adj[order[2]][0] == order[1]) ? adj[order[2]][1] : adj[order[2]][0];\n    order.push_back(next);\n    \n    ordered = {pts[order[0]].first, pts[order[0]].second,\n               pts[order[1]].first, pts[order[1]].second,\n               pts[order[2]].first, pts[order[2]].second,\n               pts[order[3]].first, pts[order[3]].second};\n    return true;\n}\n\nbool hasIntermediateDots(int x1, int y1, int x2, int y2) {\n    int dx = x2 - x1;\n    int dy = y2 - y1;\n    int g = __gcd(abs(dx), abs(dy));\n    if (g <= 1) return false;\n    \n    dx /= g;\n    dy /= g;\n    \n    for (int i = 1; i < g; i++) {\n        int x = x1 + dx * i;\n        int y = y1 + dy * i;\n        if (dots.count({x, y})) return true;\n    }\n    return false;\n}\n\nbool tryAddDot(int x1, int y1) {\n    if (dots.count({x1, y1})) return false;\n    if (x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) return false;\n    \n    vector<pair<int,int>> dotVec(dots.begin(), dots.end());\n    int n = dotVec.size();\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = i + 1; j < n; j++) {\n            for (int k = j + 1; k < n; k++) {\n                int x2 = dotVec[i].first, y2 = dotVec[i].second;\n                int x3 = dotVec[j].first, y3 = dotVec[j].second;\n                int x4 = dotVec[k].first, y4 = dotVec[k].second;\n                \n                vector<int> ordered;\n                if (!checkAndOrderRect(x1, y1, x2, y2, x3, y3, x4, y4, ordered)) {\n                    continue;\n                }\n                \n                // Check perimeter for intermediate dots\n                bool valid = true;\n                for (int e = 0; e < 4; e++) {\n                    int ex1 = ordered[e*2], ey1 = ordered[e*2+1];\n                    int ex2 = ordered[(e*2+2)%8], ey2 = ordered[(e*2+3)%8];\n                    if (hasIntermediateDots(ex1, ey1, ex2, ey2)) {\n                        valid = false;\n                        break;\n                    }\n                }\n                \n                if (!valid) continue;\n                \n                // Check edge overlap (simplified)\n                vector<int> edgeKey;\n                for (int e = 0; e < 4; e++) {\n                    vector<int> edge = {ordered[e*2], ordered[e*2+1], \n                                       ordered[(e*2+2)%8], ordered[(e*2+3)%8]};\n                    if (edge[0] > edge[2] || (edge[0] == edge[2] && edge[1] > edge[3])) {\n                        swap(edge[0], edge[2]);\n                        swap(edge[1], edge[3]);\n                    }\n                    if (usedEdges.count(edge)) {\n                        valid = false;\n                        break;\n                    }\n                }\n                \n                if (!valid) continue;\n                \n                // Add the dot\n                dots.insert({x1, y1});\n                operations.push_back(ordered);\n                \n                // Mark edges as used\n                for (int e = 0; e < 4; e++) {\n                    vector<int> edge = {ordered[e*2], ordered[e*2+1], \n                                       ordered[(e*2+2)%8], ordered[(e*2+3)%8]};\n                    if (edge[0] > edge[2] || (edge[0] == edge[2] && edge[1] > edge[3])) {\n                        swap(edge[0], edge[2]);\n                        swap(edge[1], edge[3]);\n                    }\n                    usedEdges.insert(edge);\n                }\n                \n                return true;\n            }\n        }\n    }\n    \n    return false;\n}\n\nint main() {\n    cin >> N >> M;\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        dots.insert({x, y});\n    }\n    \n    auto start = chrono::steady_clock::now();\n    \n    // Iteratively try to add dots\n    for (int iter = 0; iter < 10000; iter++) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration<double>(now - start).count() > 4.5) break;\n        \n        bool added = false;\n        for (int x = 0; x < N && !added; x++) {\n            for (int y = 0; y < N && !added; y++) {\n                if (tryAddDot(x, y)) {\n                    added = true;\n                }\n            }\n        }\n        \n        if (!added) break;\n    }\n    \n    cout << operations.size() << endl;\n    for (auto& op : operations) {\n        for (int i = 0; i < 8; i++) {\n            if (i > 0) cout << \" \";\n            cout << op[i];\n        }\n        cout << endl;\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nint board[N][N];\nint flavors[100];\n\nvoid tilt(int b[N][N], char dir) {\n    if (dir == 'F') { // Forward (up)\n        for (int j = 0; j < N; j++) {\n            int pos = 0;\n            for (int i = 0; i < N; i++) {\n                if (b[i][j] > 0) {\n                    if (i != pos) {\n                        b[pos][j] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos++;\n                }\n            }\n        }\n    } else if (dir == 'B') { // Backward (down)\n        for (int j = 0; j < N; j++) {\n            int pos = N - 1;\n            for (int i = N - 1; i >= 0; i--) {\n                if (b[i][j] > 0) {\n                    if (i != pos) {\n                        b[pos][j] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos--;\n                }\n            }\n        }\n    } else if (dir == 'L') { // Left\n        for (int i = 0; i < N; i++) {\n            int pos = 0;\n            for (int j = 0; j < N; j++) {\n                if (b[i][j] > 0) {\n                    if (j != pos) {\n                        b[i][pos] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos++;\n                }\n            }\n        }\n    } else { // Right\n        for (int i = 0; i < N; i++) {\n            int pos = N - 1;\n            for (int j = N - 1; j >= 0; j--) {\n                if (b[i][j] > 0) {\n                    if (j != pos) {\n                        b[i][pos] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos--;\n                }\n            }\n        }\n    }\n}\n\nint calcScore(int b[N][N]) {\n    bool vis[N][N] = {};\n    int score = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] > 0 && !vis[i][j]) {\n                int flavor = b[i][j];\n                int size = 0;\n                queue<pair<int,int>> q;\n                q.push({i, j});\n                vis[i][j] = true;\n                \n                while (!q.empty()) {\n                    auto [ci, cj] = q.front();\n                    q.pop();\n                    size++;\n                    \n                    int di[] = {-1, 1, 0, 0};\n                    int dj[] = {0, 0, -1, 1};\n                    for (int d = 0; d < 4; d++) {\n                        int ni = ci + di[d];\n                        int nj = cj + dj[d];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N &&\n                            !vis[ni][nj] && b[ni][nj] == flavor) {\n                            vis[ni][nj] = true;\n                            q.push({ni, nj});\n                        }\n                    }\n                }\n                \n                score += size * size;\n            }\n        }\n    }\n    \n    return score;\n}\n\nchar chooseBest() {\n    char dirs[] = {'F', 'B', 'L', 'R'};\n    int best = -1;\n    char bestDir = 'F';\n    \n    for (char dir : dirs) {\n        int temp[N][N];\n        memcpy(temp, board, sizeof(board));\n        tilt(temp, dir);\n        int s = calcScore(temp);\n        \n        if (s > best) {\n            best = s;\n            bestDir = dir;\n        }\n    }\n    \n    return bestDir;\n}\n\nint main() {\n    for (int i = 0; i < 100; i++) {\n        cin >> flavors[i];\n    }\n    \n    memset(board, 0, sizeof(board));\n    \n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n        p--;\n        \n        int cnt = 0;\n        bool placed = false;\n        for (int i = 0; i < N && !placed; i++) {\n            for (int j = 0; j < N && !placed; j++) {\n                if (board[i][j] == 0) {\n                    if (cnt == p) {\n                        board[i][j] = flavors[t];\n                        placed = true;\n                    }\n                    cnt++;\n                }\n            }\n        }\n        \n        char dir = chooseBest();\n        cout << dir << endl;\n        cout.flush();\n        \n        tilt(board, dir);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint M;\ndouble eps;\nint N;\n\nclass Graph {\npublic:\n    int n;\n    vector<vector<int>> adj;\n    \n    Graph(int n = 0) : n(n), adj(n, vector<int>(n, 0)) {}\n    \n    string to_string() const {\n        string s;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                s += (adj[i][j] ? '1' : '0');\n            }\n        }\n        return s;\n    }\n    \n    void from_string(const string& s) {\n        int idx = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                adj[i][j] = adj[j][i] = (s[idx++] == '1');\n            }\n        }\n    }\n    \n    vector<int> get_features() const {\n        vector<int> features;\n        \n        // Edge count\n        int edges = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                edges += adj[i][j];\n            }\n        }\n        features.push_back(edges);\n        \n        // Sorted degree sequence\n        vector<int> degrees(n, 0);\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                degrees[i] += adj[i][j];\n            }\n        }\n        sort(degrees.begin(), degrees.end());\n        for (int d : degrees) features.push_back(d);\n        \n        // Triangle count\n        int triangles = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                if (!adj[i][j]) continue;\n                for (int k = j + 1; k < n; k++) {\n                    if (adj[i][k] && adj[j][k]) triangles++;\n                }\n            }\n        }\n        features.push_back(triangles);\n        \n        return features;\n    }\n};\n\nvector<Graph> graphs;\nvector<vector<int>> graph_features;\n\nint compute_distance(const vector<int>& f1, const vector<int>& f2) {\n    int dist = 0;\n    // Edge count difference (heavily weighted)\n    dist += abs(f1[0] - f2[0]) * 10;\n    \n    // Degree sequence differences\n    int n = min(f1.size(), f2.size()) - 1;\n    for (int i = 1; i < (int)n; i++) {\n        dist += abs(f1[i] - f2[i]);\n    }\n    \n    // Triangle count difference\n    dist += abs(f1.back() - f2.back()) * 5;\n    \n    return dist;\n}\n\nvoid generate_graphs() {\n    // Adaptive N selection\n    if (eps <= 0.05) {\n        N = 10;\n    } else if (eps <= 0.15) {\n        N = 15;\n    } else if (eps <= 0.25) {\n        N = 20;\n    } else if (eps <= 0.35) {\n        N = 30;\n    } else {\n        N = 40;\n    }\n    \n    // Ensure we have enough space to distinguish M graphs\n    N = max(N, (int)ceil(sqrt(2.0 * M)) + 4);\n    N = min(N, 100);\n    \n    graphs.resize(M, Graph(N));\n    \n    int max_edges = N * (N - 1) / 2;\n    \n    for (int k = 0; k < M; k++) {\n        // Linearly space edge counts\n        int target_edges = (k * max_edges) / M;\n        \n        // Add edges sequentially to create distinct patterns\n        int added = 0;\n        for (int i = 0; i < N && added < target_edges; i++) {\n            for (int j = i + 1; j < N && added < target_edges; j++) {\n                graphs[k].adj[i][j] = graphs[k].adj[j][i] = 1;\n                added++;\n            }\n        }\n    }\n    \n    // Precompute features\n    graph_features.resize(M);\n    for (int k = 0; k < M; k++) {\n        graph_features[k] = graphs[k].get_features();\n    }\n}\n\nint decode_graph(const Graph& h) {\n    auto h_features = h.get_features();\n    \n    int best = 0;\n    int min_dist = INT_MAX;\n    \n    for (int k = 0; k < M; k++) {\n        int dist = compute_distance(h_features, graph_features[k]);\n        if (dist < min_dist) {\n            min_dist = dist;\n            best = k;\n        }\n    }\n    \n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> M >> eps;\n    \n    generate_graphs();\n    \n    cout << N << \"\\n\";\n    for (const auto& g : graphs) {\n        cout << g.to_string() << \"\\n\";\n    }\n    cout.flush();\n    \n    for (int q = 0; q < 100; q++) {\n        string s;\n        cin >> s;\n        \n        Graph h(N);\n        h.from_string(s);\n        \n        int t = decode_graph(h);\n        cout << t << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long INF = 1e9;\n\nint N, M, D, K;\nvector<array<int, 3>> edges; // u, v, w\nvector<int> degree;\n\nstruct EdgeInfo {\n    int id;\n    double score;\n};\n\nint main() {\n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    degree.resize(N);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i][0] >> edges[i][1] >> edges[i][2];\n        edges[i][0]--; edges[i][1]--; // 0-indexed\n        degree[edges[i][0]]++;\n        degree[edges[i][1]]++;\n    }\n    \n    // Skip coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Calculate edge importance score\n    vector<EdgeInfo> edge_info(M);\n    for (int i = 0; i < M; i++) {\n        int u = edges[i][0];\n        int v = edges[i][1];\n        long long w = edges[i][2];\n        \n        // Higher score = more important edge\n        // Consider: low degree endpoints (potential bridges), high weight\n        double degree_score = 1.0 / (degree[u] * degree[v]);\n        double weight_score = (double)w / 1000000.0;\n        \n        edge_info[i].id = i;\n        edge_info[i].score = degree_score * 100 + weight_score;\n    }\n    \n    // Sort by importance (descending)\n    sort(edge_info.begin(), edge_info.end(), \n         [](const EdgeInfo& a, const EdgeInfo& b) {\n             return a.score > b.score;\n         });\n    \n    // Assign edges to days using round-robin on sorted list\n    // This distributes important edges evenly across days\n    vector<int> assignment(M);\n    vector<int> day_count(D + 1, 0);\n    \n    for (int i = 0; i < M; i++) {\n        int edge_id = edge_info[i].id;\n        \n        // Find day with minimum assignments\n        int best_day = 1;\n        for (int d = 2; d <= D; d++) {\n            if (day_count[d] < day_count[best_day]) {\n                best_day = d;\n            }\n        }\n        \n        assignment[edge_id] = best_day;\n        day_count[best_day]++;\n    }\n    \n    // Add some randomization for diversity\n    random_device rd;\n    mt19937 gen(rd());\n    \n    // Randomly swap some assignments\n    int num_swaps = min(100, M / 10);\n    for (int iter = 0; iter < num_swaps; iter++) {\n        int i = gen() % M;\n        int j = gen() % M;\n        if (i != j) {\n            swap(assignment[i], assignment[j]);\n        }\n    }\n    \n    // Output (1-indexed days)\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i];\n        if (i < M - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f1, r1, f2, r2;\n\nbool isOccupied(int x, int y, int z, const vector<string>& f, const vector<string>& r) {\n    return f[z][x] == '1' && r[z][y] == '1';\n}\n\n// BFS to find connected component\nset<tuple<int,int,int>> getComponent(tuple<int,int,int> start, \n                                      set<tuple<int,int,int>>& available) {\n    set<tuple<int,int,int>> component;\n    queue<tuple<int,int,int>> q;\n    q.push(start);\n    available.erase(start);\n    component.insert(start);\n    \n    int dx[] = {1, -1, 0, 0, 0, 0};\n    int dy[] = {0, 0, 1, -1, 0, 0};\n    int dz[] = {0, 0, 0, 0, 1, -1};\n    \n    while (!q.empty()) {\n        auto [x, y, z] = q.front();\n        q.pop();\n        \n        for (int i = 0; i < 6; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            int nz = z + dz[i];\n            auto next = make_tuple(nx, ny, nz);\n            \n            if (available.count(next)) {\n                available.erase(next);\n                component.insert(next);\n                q.push(next);\n            }\n        }\n    }\n    \n    return component;\n}\n\nint main() {\n    cin >> D;\n    f1.resize(D); r1.resize(D); f2.resize(D); r2.resize(D);\n    \n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n    \n    // Get occupied cells for both configurations\n    set<tuple<int,int,int>> occ1, occ2;\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 (isOccupied(x, y, z, f1, r1)) {\n                    occ1.insert({x, y, z});\n                }\n                if (isOccupied(x, y, z, f2, r2)) {\n                    occ2.insert({x, y, z});\n                }\n            }\n        }\n    }\n    \n    // Create blocks from connected components\n    vector<set<tuple<int,int,int>>> blocks1, blocks2;\n    \n    auto available1 = occ1;\n    while (!available1.empty()) {\n        auto start = *available1.begin();\n        auto component = getComponent(start, available1);\n        blocks1.push_back(component);\n    }\n    \n    auto available2 = occ2;\n    while (!available2.empty()) {\n        auto start = *available2.begin();\n        auto component = getComponent(start, available2);\n        blocks2.push_back(component);\n    }\n    \n    // Assign block IDs\n    vector<vector<vector<int>>> b1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> b2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    \n    int nextId = 1;\n    \n    for (auto& block : blocks1) {\n        int id = nextId++;\n        for (auto [x, y, z] : block) {\n            b1[x][y][z] = id;\n        }\n    }\n    \n    for (auto& block : blocks2) {\n        int id = nextId++;\n        for (auto [x, y, z] : block) {\n            b2[x][y][z] = id;\n        }\n    }\n    \n    // Output\n    cout << nextId - 1 << endl;\n    \n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            for (int z = 0; z < D; z++) {\n                if (x > 0 || y > 0 || z > 0) cout << \" \";\n                cout << b1[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n    \n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            for (int z = 0; z < D; z++) {\n                if (x > 0 || y > 0 || z > 0) cout << \" \";\n                cout << b2[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<long long> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    struct Edge {\n        int u, v, id;\n        long long w;\n    };\n    \n    vector<Edge> edges(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--; edges[i].v--;\n        edges[i].id = i;\n    }\n    \n    vector<long long> a(K), b(K);\n    for (int i = 0; i < K; i++) {\n        cin >> a[i] >> b[i];\n    }\n    \n    auto dist = [](long long x1, long long y1, long long x2, long long y2) {\n        long long dx = x1 - x2;\n        long long dy = y1 - y2;\n        return sqrt((double)(dx * dx + dy * dy));\n    };\n    \n    // Build MST using Kruskal's algorithm\n    vector<Edge> sorted_edges = edges;\n    sort(sorted_edges.begin(), sorted_edges.end(), [](const Edge& a, const Edge& b) {\n        return a.w < b.w;\n    });\n    \n    vector<int> parent(N);\n    iota(parent.begin(), parent.end(), 0);\n    \n    function<int(int)> find = [&](int v) {\n        return parent[v] == v ? v : parent[v] = find(parent[v]);\n    };\n    \n    vector<int> edge_on(M, 0);\n    \n    for (const Edge& e : sorted_edges) {\n        int pu = find(e.u), pv = find(e.v);\n        if (pu != pv) {\n            parent[pu] = pv;\n            edge_on[e.id] = 1;\n        }\n    }\n    \n    // Build adjacency list for MST\n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        if (edge_on[i]) {\n            adj[edges[i].u].push_back(edges[i].v);\n            adj[edges[i].v].push_back(edges[i].u);\n        }\n    }\n    \n    // Find reachable vertices from vertex 0\n    vector<bool> reachable(N, false);\n    queue<int> q;\n    q.push(0);\n    reachable[0] = true;\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        for (int v : adj[u]) {\n            if (!reachable[v]) {\n                reachable[v] = true;\n                q.push(v);\n            }\n        }\n    }\n    \n    // For each resident, find closest reachable vertex and set power\n    vector<int> P(N, 0);\n    \n    for (int k = 0; k < K; k++) {\n        int best_v = 0;\n        double best_d = dist(a[k], b[k], x[0], y[0]);\n        \n        for (int i = 0; i < N; i++) {\n            if (!reachable[i]) continue;\n            double d = dist(a[k], b[k], x[i], y[i]);\n            if (d < best_d) {\n                best_d = d;\n                best_v = i;\n            }\n        }\n        \n        P[best_v] = max(P[best_v], min(5000, (int)ceil(best_d)));\n    }\n    \n    // Output solution\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << P[i];\n    }\n    cout << \"\\n\";\n    \n    for (int i = 0; i < M; i++) {\n        if (i > 0) cout << \" \";\n        cout << edge_on[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <tuple>\nusing namespace std;\n\nconst int N = 30;\nconst int MAX_OPS = 9900;\n\nvector<vector<int>> pyramid;\nvector<tuple<int,int,int,int>> operations;\n\nvoid swap_balls(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    operations.push_back({x1, y1, x2, y2});\n}\n\nint count_violations() {\n    int count = 0;\n    for (int x = 0; x < N-1; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) count++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) count++;\n        }\n    }\n    return count;\n}\n\nvoid sink(int x, int y) {\n    while (x < N-1 && operations.size() < MAX_OPS) {\n        int current = pyramid[x][y];\n        int left_child = pyramid[x+1][y];\n        int right_child = pyramid[x+1][y+1];\n        \n        if (current <= left_child && current <= right_child) {\n            break;\n        }\n        \n        if (left_child < right_child) {\n            swap_balls(x, y, x+1, y);\n            x++;\n        } else {\n            swap_balls(x, y, x+1, y+1);\n            x++;\n            y++;\n        }\n    }\n}\n\nvoid solve() {\n    // Phase 1: Initial heapify from bottom to top\n    for (int x = N-2; x >= 0 && operations.size() < MAX_OPS; x--) {\n        for (int y = 0; y <= x && operations.size() < MAX_OPS; y++) {\n            sink(x, y);\n        }\n    }\n    \n    // Phase 2: Fix remaining violations with multiple passes\n    for (int pass = 0; pass < 50 && operations.size() < MAX_OPS; pass++) {\n        if (count_violations() == 0) break;\n        \n        for (int x = 0; x < N-1 && operations.size() < MAX_OPS; x++) {\n            for (int y = 0; y <= x && operations.size() < MAX_OPS; y++) {\n                int current = pyramid[x][y];\n                int left_child = pyramid[x+1][y];\n                int right_child = pyramid[x+1][y+1];\n                \n                if (current > left_child || current > right_child) {\n                    sink(x, y);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    pyramid.resize(N);\n    for (int x = 0; x < N; x++) {\n        pyramid[x].resize(x+1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    solve();\n    \n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int D = 9;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\n\nint N;\nbool obstacle[D][D];\nint container[D][D];\nconst int entrance_x = 0;\nconst int entrance_y = 4;\nvector<vector<int>> dist_from_entrance;\n\nbool isValid(int x, int y) {\n    return x >= 0 && x < D && y >= 0 && y < D;\n}\n\nset<pair<int,int>> getReachable() {\n    set<pair<int,int>> reachable;\n    queue<pair<int,int>> q;\n    q.push({entrance_x, entrance_y});\n    reachable.insert({entrance_x, entrance_y});\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (isValid(nx, ny) && !obstacle[nx][ny] && \n                container[nx][ny] == -1 && \n                reachable.find({nx, ny}) == reachable.end()) {\n                reachable.insert({nx, ny});\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return reachable;\n}\n\nvoid calcDistances() {\n    dist_from_entrance.assign(D, vector<int>(D, -1));\n    queue<pair<int,int>> q;\n    q.push({entrance_x, entrance_y});\n    dist_from_entrance[entrance_x][entrance_y] = 0;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (isValid(nx, ny) && !obstacle[nx][ny] && dist_from_entrance[nx][ny] == -1) {\n                dist_from_entrance[nx][ny] = dist_from_entrance[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n}\n\nint main() {\n    int D_input;\n    cin >> D_input >> N;\n    \n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            obstacle[i][j] = false;\n            container[i][j] = -1;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        obstacle[x][y] = true;\n    }\n    \n    calcDistances();\n    \n    int max_dist = 0;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (dist_from_entrance[i][j] > max_dist) {\n                max_dist = dist_from_entrance[i][j];\n            }\n        }\n    }\n    \n    int total_containers = D * D - 1 - N;\n    \n    // Placement phase\n    for (int d = 0; d < total_containers; d++) {\n        int t;\n        cin >> t;\n        \n        set<pair<int,int>> reachable = getReachable();\n        \n        // Map container number to target distance\n        double ratio = (double)t / max(1, total_containers - 1);\n        int target_dist = 1 + (int)(ratio * (max_dist - 1));\n        \n        // Find reachable cell closest to target distance\n        pair<int,int> chosen = {-1, -1};\n        int min_diff = 1000000;\n        \n        for (auto [x, y] : reachable) {\n            if (container[x][y] == -1 && (x != entrance_x || y != entrance_y)) {\n                int cell_dist = dist_from_entrance[x][y];\n                int diff = abs(cell_dist - target_dist);\n                if (diff < min_diff || \n                    (diff == min_diff && chosen.first != -1 && \n                     cell_dist < dist_from_entrance[chosen.first][chosen.second])) {\n                    min_diff = diff;\n                    chosen = {x, y};\n                }\n            }\n        }\n        \n        container[chosen.first][chosen.second] = t;\n        cout << chosen.first << \" \" << chosen.second << endl;\n        cout.flush();\n    }\n    \n    // Retrieval phase: always pick smallest accessible\n    for (int i = 0; i < total_containers; i++) {\n        set<pair<int,int>> reachable = getReachable();\n        \n        int min_num = total_containers;\n        pair<int,int> min_pos = {-1, -1};\n        \n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (container[x][y] >= 0 && reachable.count({x, y})) {\n                    if (container[x][y] < min_num) {\n                        min_num = container[x][y];\n                        min_pos = {x, y};\n                    }\n                }\n            }\n        }\n        \n        cout << min_pos.first << \" \" << min_pos.second << endl;\n        container[min_pos.first][min_pos.second] = -1;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nvector<vector<int>> original;\nvector<set<int>> adj;\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\n\nvoid readInput() {\n    cin >> n >> m;\n    original.assign(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> original[i][j];\n        }\n    }\n}\n\nvoid buildAdjacency() {\n    adj.assign(m + 1, set<int>());\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c = original[i][j];\n            if (i == 0 || i == n-1 || j == 0 || j == n-1) {\n                adj[c].insert(0);\n                adj[0].insert(c);\n            }\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int nc = original[ni][nj];\n                    if (c != nc) {\n                        adj[c].insert(nc);\n                    }\n                }\n            }\n        }\n    }\n}\n\nvoid createCompactMap() {\n    vector<vector<int>> result(n, vector<int>(n, 0));\n    map<int, vector<pair<int,int>>> wardCells;\n    set<int> placed;\n    \n    // Start from center\n    int cx = n / 2, cy = n / 2;\n    result[cx][cy] = 1;\n    wardCells[1].push_back({cx, cy});\n    placed.insert(1);\n    \n    queue<int> q;\n    q.push(1);\n    \n    while (!q.empty()) {\n        int ward = q.front();\n        q.pop();\n        \n        // Place neighbors\n        for (int neighbor : adj[ward]) {\n            if (neighbor == 0 || placed.count(neighbor)) continue;\n            \n            // Try to place adjacent to current ward\n            bool found = false;\n            for (auto [wx, wy] : wardCells[ward]) {\n                for (int d = 0; d < 4 && !found; d++) {\n                    int nx = wx + dx[d];\n                    int ny = wy + dy[d];\n                    if (nx >= 0 && nx < n && ny >= 0 && ny < n && result[nx][ny] == 0) {\n                        result[nx][ny] = neighbor;\n                        wardCells[neighbor].push_back({nx, ny});\n                        placed.insert(neighbor);\n                        q.push(neighbor);\n                        found = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n}\n\nint main() {\n    readInput();\n    buildAdjacency();\n    createCompactMap();\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint query_count = 0;\n\nchar query(vector<int> L, vector<int> R) {\n    query_count++;\n    cout << L.size() << \" \" << R.size();\n    for(int x : L) cout << \" \" << x;\n    for(int x : R) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\nvoid mergeSort(vector<int>& arr, int l, int r) {\n    if(l >= r) return;\n    \n    int mid = (l + r) / 2;\n    mergeSort(arr, l, mid);\n    mergeSort(arr, mid+1, r);\n    \n    vector<int> temp;\n    int i = l, j = mid+1;\n    while(i <= mid && j <= r) {\n        if(query_count >= Q - 2*N) {\n            temp.push_back(arr[i++]);\n            continue;\n        }\n        \n        char result = query({arr[i]}, {arr[j]});\n        if(result != '>') {\n            temp.push_back(arr[i++]);\n        } else {\n            temp.push_back(arr[j++]);\n        }\n    }\n    while(i <= mid) temp.push_back(arr[i++]);\n    while(j <= r) temp.push_back(arr[j++]);\n    \n    for(int i = 0; i < temp.size(); i++) {\n        arr[l + i] = temp[i];\n    }\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    // Sort items by weight using merge sort\n    mergeSort(items, 0, N-1);\n    \n    // Assign to groups using greedy with estimated weights\n    vector<int> assignment(N);\n    vector<long long> group_weight(D, 0);\n    \n    // Assign from heaviest to lightest to currently lightest group\n    for(int i = N-1; i >= 0; i--) {\n        int min_group = min_element(group_weight.begin(), group_weight.end()) - group_weight.begin();\n        assignment[items[i]] = min_group;\n        group_weight[min_group] += (i + 1); // Estimated weight\n    }\n    \n    // Output final assignment\n    for(int i = 0; i < N; i++) {\n        if(i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    \n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n/m);\n        for (int j = 0; j < n/m; j++) {\n            cin >> stacks[i][j];\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    \n    for (int target = 1; target <= n; target++) {\n        // Find where target box is\n        int stack_id = -1, pos = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == target) {\n                    stack_id = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (stack_id != -1) break;\n        }\n        \n        // If not at top, move boxes above it\n        if (pos < (int)stacks[stack_id].size() - 1) {\n            int move_box = stacks[stack_id][pos + 1];\n            \n            // Find best destination stack\n            int best_stack = -1;\n            int best_score = -1;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == stack_id) continue;\n                \n                int score = 0;\n                if (stacks[i].empty()) {\n                    score = 1000000; // Highest priority\n                } else {\n                    // Prefer stacks with larger top values (extracted later)\n                    // Prefer stacks with smaller sizes (more flexibility)\n                    score = stacks[i].back() * 100 - stacks[i].size();\n                }\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_stack = i;\n                }\n            }\n            \n            operations.push_back({move_box, best_stack + 1}); // 1-indexed\n            \n            // Update stacks\n            vector<int> moved_boxes;\n            for (int i = pos + 1; i < (int)stacks[stack_id].size(); i++) {\n                moved_boxes.push_back(stacks[stack_id][i]);\n            }\n            stacks[stack_id].resize(pos + 1);\n            \n            for (int box : moved_boxes) {\n                stacks[best_stack].push_back(box);\n            }\n        }\n        \n        // Now target is at top, carry it out\n        operations.push_back({target, 0});\n        stacks[stack_id].pop_back();\n    }\n    \n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\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;\n\nconst int di[] = {0, 1, 0, -1};\nconst int dj[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir];\n    int nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    if (dir == 0) return v[i][j] == '0';\n    else if (dir == 1) return h[i][j] == '0';\n    else if (dir == 2) return v[i][j-1] == '0';\n    else return h[i-1][j] == '0';\n}\n\nstring find_path(int si, int sj, int ti, int tj) {\n    if (si == ti && sj == tj) return \"\";\n    \n    vector<vector<int>> dist(N, vector<int>(N, -1));\n    vector<vector<int>> parent_dir(N, vector<int>(N, -1));\n    queue<pair<int, int>> q;\n    \n    q.push({si, sj});\n    dist[si][sj] = 0;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            \n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            \n            if (dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                parent_dir[ni][nj] = dir;\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    if (dist[ti][tj] == -1) return \"\";\n    \n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int dir = parent_dir[ci][cj];\n        path += dir_char[dir];\n        ci -= di[dir];\n        cj -= dj[dir];\n    }\n    \n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstring build_tour() {\n    const int MAX_LEN = 99000;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    string route;\n    \n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        \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 + di[dir];\n            int nj = j + dj[dir];\n            if (!visited[ni][nj]) {\n                neighbors.push_back({-d[ni][nj], dir});\n            }\n        }\n        \n        sort(neighbors.begin(), neighbors.end());\n        \n        for (auto [_, dir] : neighbors) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            \n            if (!visited[ni][nj]) {\n                route += dir_char[dir];\n                dfs(ni, nj);\n                route += dir_char[(dir + 2) % 4];\n            }\n        }\n    };\n    \n    dfs(0, 0);\n    \n    // Add extra visits to high-value cells\n    vector<tuple<int, int, int>> cells;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cells.push_back({d[i][j], i, j});\n        }\n    }\n    sort(cells.rbegin(), cells.rend());\n    \n    int ci = 0, cj = 0;\n    for (auto [dval, ti, tj] : cells) {\n        if (route.length() >= MAX_LEN) break;\n        \n        string path1 = find_path(ci, cj, ti, tj);\n        string path2 = find_path(ti, tj, ci, cj);\n        \n        int cost = path1.length() + path2.length();\n        if (route.length() + cost <= MAX_LEN) {\n            route += path1 + path2;\n        }\n    }\n    \n    // Return to origin\n    route += find_path(ci, cj, 0, 0);\n    \n    return route;\n}\n\nint main() {\n    cin >> N;\n    \n    h.resize(N-1);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    \n    v.resize(N);\n    for (int i = 0; i < N; i++) cin >> v[i];\n    \n    d.resize(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> d[i][j];\n        }\n    }\n    \n    cout << build_tour() << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint si, sj;\nvector<string> grid;\nvector<string> targets;\nmap<char, vector<pair<int,int>>> char_positions;\n\n// Compute overlap between end of s1 and start of s2\nint overlap(const string& s1, const string& s2) {\n    int maxLen = min((int)s1.length(), (int)s2.length());\n    for (int len = maxLen; len >= 1; len--) {\n        if (s1.substr(s1.length() - len) == s2.substr(0, len)) {\n            return len;\n        }\n    }\n    return 0;\n}\n\n// Find closest grid position containing character c\npair<int,int> findClosest(char c, int curI, int curJ) {\n    auto& positions = char_positions[c];\n    int bestDist = INT_MAX;\n    pair<int,int> best = positions[0];\n    \n    for (auto& pos : positions) {\n        int dist = abs(pos.first - curI) + abs(pos.second - curJ);\n        if (dist < bestDist) {\n            bestDist = dist;\n            best = pos;\n        }\n    }\n    return best;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M;\n    cin >> si >> sj;\n    \n    grid.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    targets.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i];\n    }\n    \n    // Build character position map\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            char_positions[grid[i][j]].push_back({i, j});\n        }\n    }\n    \n    // Precompute all pairwise overlaps\n    vector<vector<int>> ovl(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) {\n                ovl[i][j] = overlap(targets[i], targets[j]);\n            }\n        }\n    }\n    \n    // Greedy construction: build optimal order\n    vector<bool> used(M, false);\n    vector<int> order;\n    \n    // Start with string having best total outgoing overlaps\n    int current = 0;\n    int maxSum = -1;\n    for (int i = 0; i < M; i++) {\n        int sum = 0;\n        for (int j = 0; j < M; j++) {\n            sum += ovl[i][j];\n        }\n        if (sum > maxSum) {\n            maxSum = sum;\n            current = i;\n        }\n    }\n    \n    order.push_back(current);\n    used[current] = true;\n    \n    // Greedily add strings with maximum overlap\n    for (int iter = 1; iter < M; iter++) {\n        int bestNext = -1;\n        int bestOvl = -1;\n        \n        for (int i = 0; i < M; i++) {\n            if (!used[i] && ovl[current][i] > bestOvl) {\n                bestOvl = ovl[current][i];\n                bestNext = i;\n            }\n        }\n        \n        if (bestNext == -1) {\n            for (int i = 0; i < M; i++) {\n                if (!used[i]) {\n                    bestNext = i;\n                    break;\n                }\n            }\n        }\n        \n        if (bestNext == -1) break;\n        \n        order.push_back(bestNext);\n        used[bestNext] = true;\n        current = bestNext;\n    }\n    \n    // Build superstring\n    string result = targets[order[0]];\n    for (int i = 1; i < order.size(); i++) {\n        int prev = order[i-1];\n        int curr = order[i];\n        int o = ovl[prev][curr];\n        if (o > 0) {\n            result += targets[curr].substr(o);\n        } else {\n            result += targets[curr];\n        }\n    }\n    \n    // Navigate grid and output path\n    int curI = si, curJ = sj;\n    \n    for (char c : result) {\n        auto pos = findClosest(c, curI, curJ);\n        cout << pos.first << \" \" << pos.second << \"\\n\";\n        curI = pos.first;\n        curJ = pos.second;\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>>> fields;\nint query_count = 0;\n\nint query(const vector<pair<int,int>>& cells) {\n    cout << \"q \" << cells.size();\n    for (auto [i, j] : cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    query_count++;\n    \n    int result;\n    cin >> result;\n    return result;\n}\n\nint drill(int i, int j) {\n    return query({{i, j}});\n}\n\nbool answer(const set<pair<int,int>>& cells) {\n    cout << \"a \" << cells.size();\n    for (auto [i, j] : cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    int result;\n    cin >> result;\n    return result == 1;\n}\n\nint main() {\n    cin >> N >> M >> eps;\n    fields.resize(M);\n    \n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        fields[k].resize(d);\n        for (int i = 0; i < d; i++) {\n            cin >> fields[k][i].first >> fields[k][i].second;\n        }\n    }\n    \n    vector<vector<double>> estimate(N, vector<double>(N, 0.0));\n    vector<vector<int>> drilled(N, vector<int>(N, -1));\n    \n    // Phase 1: Query entire grid multiple times for baseline\n    double total = 0;\n    int num_full = 30;\n    for (int q = 0; q < num_full; q++) {\n        vector<pair<int,int>> all;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                all.push_back({i, j});\n            }\n        }\n        total += query(all);\n    }\n    double avg_per_cell = total / (num_full * N * N);\n    \n    // Phase 2: Query rows and columns\n    vector<double> row_est(N), col_est(N);\n    for (int i = 0; i < N; i++) {\n        vector<pair<int,int>> row;\n        for (int j = 0; j < N; j++) row.push_back({i, j});\n        row_est[i] = query(row) / (double)N;\n    }\n    \n    for (int j = 0; j < N; j++) {\n        vector<pair<int,int>> col;\n        for (int i = 0; i < N; i++) col.push_back({i, j});\n        col_est[j] = query(col) / (double)N;\n    }\n    \n    // Combine estimates\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            estimate[i][j] = (row_est[i] + col_est[j]) / 2.0;\n        }\n    }\n    \n    // Phase 3: Query smaller blocks for refinement\n    int block_size = max(2, N/3);\n    for (int bi = 0; bi < N; bi += block_size) {\n        for (int bj = 0; bj < N; bj += block_size) {\n            vector<pair<int,int>> block;\n            for (int i = bi; i < min(N, bi+block_size); i++) {\n                for (int j = bj; j < min(N, bj+block_size); j++) {\n                    block.push_back({i, j});\n                }\n            }\n            if (block.size() >= 2) {\n                double block_avg = query(block) / (double)block.size();\n                for (auto [i, j] : block) {\n                    estimate[i][j] = (estimate[i][j] + block_avg) / 2.0;\n                }\n            }\n        }\n    }\n    \n    // Phase 4: Drill uncertain squares\n    set<pair<int,int>> has_oil;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (estimate[i][j] > 0.4 || query_count >= 600) {\n                int v = drill(i, j);\n                drilled[i][j] = v;\n                if (v > 0) has_oil.insert({i, j});\n            }\n        }\n    }\n    \n    // Make answer\n    if (!answer(has_oil)) {\n        // If wrong, drill remaining squares\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (drilled[i][j] < 0) {\n                    int v = drill(i, j);\n                    if (v > 0) has_oil.insert({i, j});\n                }\n            }\n        }\n        answer(has_oil);\n    }\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\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    // Find maximum area needed for each reservation position across all days\n    vector<long long> max_area(N);\n    for (int k = 0; k < N; k++) {\n        for (int d = 0; d < D; d++) {\n            max_area[k] = max(max_area[k], (long long)a[d][k]);\n        }\n    }\n    \n    // Allocate horizontal strips proportionally to max requirements\n    long long total = accumulate(max_area.begin(), max_area.end(), 0LL);\n    \n    vector<int> row_pos(N + 1);\n    row_pos[0] = 0;\n    \n    // Distribute rows proportionally\n    for (int k = 0; k < N; k++) {\n        long long cumsum = accumulate(max_area.begin(), max_area.begin() + k + 1, 0LL);\n        row_pos[k + 1] = (int)((cumsum * W + total / 2) / total);  // Round to nearest\n    }\n    row_pos[N] = W;  // Ensure last position is exactly W\n    \n    // Ensure each strip has at least height 1 if area > 0\n    for (int k = 0; k < N; k++) {\n        if (max_area[k] > 0 && row_pos[k + 1] <= row_pos[k]) {\n            row_pos[k + 1] = row_pos[k] + 1;\n        }\n    }\n    \n    // Output same rectangles for all days\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << row_pos[k] << \" 0 \" << row_pos[k + 1] << \" \" << W << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353LL;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nlong long board[N][N];\nlong long stamps[M][3][3];\n\nlong long calculate_improvement(int m, int p, int q) {\n    long long improvement = 0;\n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            int row = p + i;\n            int col = q + j;\n            long long remainder = board[row][col] % MOD;\n            long long stamp_val = stamps[m][i][j];\n            long long new_remainder = (remainder + stamp_val) % MOD;\n            improvement += new_remainder - remainder;\n        }\n    }\n    return improvement;\n}\n\nvoid apply_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            board[p + i][q + j] += stamps[m][i][j];\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 < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    for (int stamp = 0; stamp < M; stamp++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[stamp][i][j];\n            }\n        }\n    }\n    \n    vector<tuple<int, int, int>> operations;\n    \n    for (int op = 0; op < K; op++) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        long long best_improvement = 0;\n        \n        for (int stamp = 0; stamp < M; stamp++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    long long improvement = calculate_improvement(stamp, p, q);\n                    if (improvement > best_improvement) {\n                        best_improvement = improvement;\n                        best_m = stamp;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        if (best_m == -1 || best_improvement <= 0) {\n            break;\n        }\n        \n        apply_stamp(best_m, best_p, best_q);\n        operations.push_back({best_m, best_p, best_q});\n    }\n    \n    cout << operations.size() << endl;\n    for (auto [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << endl;\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N];\n\nstruct State {\n    int grid[N][N];\n    pair<int,int> crane_pos[N];\n    int crane_carry[N];\n    int next_container[N];\n    \n    State() {\n        memset(grid, -1, sizeof(grid));\n        for (int i = 0; i < N; i++) {\n            crane_pos[i] = {i, 0};\n            crane_carry[i] = -1;\n            next_container[i] = 0;\n        }\n    }\n    \n    int target_row(int container) {\n        return container / N;\n    }\n    \n    void place_containers() {\n        for (int i = 0; i < N; i++) {\n            if (next_container[i] < N && grid[i][0] == -1) {\n                bool blocked = false;\n                for (int c = 0; c < N; c++) {\n                    if (crane_pos[c] == make_pair(i, 0) && crane_carry[c] != -1) {\n                        blocked = true;\n                    }\n                }\n                if (!blocked) {\n                    grid[i][0] = A[i][next_container[i]];\n                    next_container[i]++;\n                }\n            }\n        }\n    }\n    \n    void dispatch_containers() {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                grid[i][N-1] = -1;\n            }\n        }\n    }\n    \n    void apply_action(int crane_id, char action) {\n        auto& pos = crane_pos[crane_id];\n        \n        if (action == 'P') {\n            crane_carry[crane_id] = grid[pos.first][pos.second];\n            grid[pos.first][pos.second] = -1;\n        } else if (action == 'Q') {\n            grid[pos.first][pos.second] = crane_carry[crane_id];\n            crane_carry[crane_id] = -1;\n        } else if (action == 'U') {\n            pos.first--;\n        } else if (action == 'D') {\n            pos.first++;\n        } else if (action == 'L') {\n            pos.second--;\n        } else if (action == 'R') {\n            pos.second++;\n        }\n    }\n};\n\nint main() {\n    int n;\n    cin >> n;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    State state;\n    vector<string> commands(N);\n    \n    for (int turn = 0; turn < 1000; turn++) {\n        state.place_containers();\n        \n        vector<char> actions(N, '.');\n        \n        for (int i = 0; i < N; i++) {\n            auto [r, c] = state.crane_pos[i];\n            \n            if (state.crane_carry[i] == -1) {\n                // Not carrying\n                if (state.grid[r][c] != -1) {\n                    actions[i] = 'P';\n                } else if (c > 0) {\n                    actions[i] = 'L';\n                }\n            } else {\n                // Carrying container\n                int container = state.crane_carry[i];\n                int target_r = state.target_row(container);\n                \n                if (r != target_r) {\n                    // Move to correct row first\n                    actions[i] = (r < target_r) ? 'D' : 'U';\n                } else if (c < N-1) {\n                    // Move right to dispatch gate\n                    actions[i] = 'R';\n                } else {\n                    // At dispatch gate, release\n                    actions[i] = 'Q';\n                }\n            }\n        }\n        \n        // Apply actions\n        for (int i = 0; i < N; i++) {\n            commands[i] += actions[i];\n            state.apply_action(i, actions[i]);\n        }\n        \n        state.dispatch_containers();\n        \n        // Check if done\n        bool done = true;\n        for (int i = 0; i < N; i++) {\n            if (state.next_container[i] < N || state.crane_carry[i] != -1) {\n                done = false;\n            }\n        }\n        if (done) {\n            bool has_containers = false;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (state.grid[i][j] != -1) has_containers = true;\n                }\n            }\n            if (!has_containers) break;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << commands[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\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++) {\n            cin >> h[i][j];\n        }\n    }\n    \n    vector<string> operations;\n    int cur_r = 0, cur_c = 0;\n    int load = 0;\n    \n    const int MAX_PASSES = 10;\n    for (int pass = 0; pass < MAX_PASSES; pass++) {\n        // Generate snake path\n        vector<pair<int, int>> path;\n        for (int i = 0; i < N; i++) {\n            if (i % 2 == 0) {\n                for (int j = 0; j < N; j++) {\n                    path.push_back({i, j});\n                }\n            } else {\n                for (int j = N - 1; j >= 0; j--) {\n                    path.push_back({i, j});\n                }\n            }\n        }\n        \n        bool all_zero = true;\n        for (auto [tr, tc] : path) {\n            if (operations.size() >= 99000) break;\n            \n            // Move to (tr, tc)\n            while (cur_r < tr) {\n                operations.push_back(\"D\");\n                cur_r++;\n            }\n            while (cur_r > tr) {\n                operations.push_back(\"U\");\n                cur_r--;\n            }\n            while (cur_c < tc) {\n                operations.push_back(\"R\");\n                cur_c++;\n            }\n            while (cur_c > tc) {\n                operations.push_back(\"L\");\n                cur_c--;\n            }\n            \n            // Adjust height at (tr, tc)\n            if (h[tr][tc] > 0) {\n                operations.push_back(\"+\" + to_string(h[tr][tc]));\n                load += h[tr][tc];\n                h[tr][tc] = 0;\n            } else if (h[tr][tc] < 0) {\n                int unload_amount = min(-h[tr][tc], load);\n                if (unload_amount > 0) {\n                    operations.push_back(\"-\" + to_string(unload_amount));\n                    load -= unload_amount;\n                    h[tr][tc] += unload_amount;\n                }\n                if (h[tr][tc] != 0) {\n                    all_zero = false;\n                }\n            }\n        }\n        \n        if (all_zero && load == 0) break;\n        if (operations.size() >= 99000) break;\n        \n        // Move back to (0, 0) for next pass\n        while (cur_r > 0) {\n            operations.push_back(\"U\");\n            cur_r--;\n        }\n        while (cur_c > 0) {\n            operations.push_back(\"L\");\n            cur_c--;\n        }\n    }\n    \n    for (const auto& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <set>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> X(seed_count, vector<int>(M));\n    \n    // Read initial seeds\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    \n    for (int t = 0; t < T; t++) {\n        // Calculate total value for each seed\n        vector<pair<int, int>> seed_values;\n        for (int i = 0; i < seed_count; i++) {\n            int value = accumulate(X[i].begin(), X[i].end(), 0);\n            seed_values.push_back({value, i});\n        }\n        sort(seed_values.rbegin(), seed_values.rend());\n        \n        // Select seeds: prioritize champions and high-value seeds\n        set<int> selected_set;\n        \n        // Add seeds with maximum value for each criterion\n        for (int l = 0; l < M; l++) {\n            int max_val = -1;\n            int best_seed = 0;\n            for (int i = 0; i < seed_count; i++) {\n                if (X[i][l] > max_val) {\n                    max_val = X[i][l];\n                    best_seed = i;\n                }\n            }\n            selected_set.insert(best_seed);\n        }\n        \n        // Fill remaining slots with highest total value seeds\n        for (auto [val, id] : seed_values) {\n            if (selected_set.size() >= N * N) break;\n            selected_set.insert(id);\n        }\n        \n        vector<int> selected_seeds(selected_set.begin(), selected_set.end());\n        \n        // Place seeds in grid\n        vector<vector<int>> A(N, vector<int>(N));\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                A[i][j] = selected_seeds[idx++];\n            }\n        }\n        \n        // Output grid\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << A[i][j];\n                if (j < N - 1) cout << \" \";\n                else cout << endl;\n            }\n        }\n        cout.flush();\n        \n        // Read new seeds\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    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<pair<int,int>> sources, targets;\n\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\nchar dir_char[] = {'R', 'D', 'L', 'U'};\n\nstruct State {\n    int root_x, root_y;\n    vector<int> dir;\n    vector<bool> holding;\n    int num_v;\n    vector<int> parent;\n    vector<int> length;\n    vector<bool> is_leaf;\n    \n    vector<pair<int,int>> get_positions() {\n        vector<pair<int,int>> pos(num_v);\n        pos[0] = {root_x, root_y};\n        for (int i = 1; i < num_v; i++) {\n            int p = parent[i];\n            pos[i] = {pos[p].first + dx[dir[i]] * length[i], \n                     pos[p].second + dy[dir[i]] * length[i]};\n        }\n        return pos;\n    }\n    \n    string make_command(char move, vector<char> rots, vector<char> actions) {\n        string s(2 * num_v, '.');\n        s[0] = move;\n        for (int i = 1; i < num_v; i++) {\n            s[i] = rots[i-1];\n        }\n        for (int i = 0; i < num_v; i++) {\n            s[num_v + i] = actions[i];\n        }\n        return s;\n    }\n};\n\nint main() {\n    cin >> N >> M >> V;\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            if (s[j] == '1') {\n                sources.push_back({i, j});\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            if (s[j] == '1') {\n                targets.push_back({i, j});\n            }\n        }\n    }\n    \n    State state;\n    state.num_v = 2;\n    state.parent = {-1, 0};\n    state.length = {0, 1};\n    state.dir = {0, 0};\n    state.is_leaf = {false, true};\n    state.holding.resize(state.num_v, false);\n    state.root_x = 0;\n    state.root_y = 0;\n    \n    cout << state.num_v << endl;\n    for (int i = 1; i < state.num_v; i++) {\n        cout << state.parent[i] << \" \" << state.length[i] << endl;\n    }\n    cout << state.root_x << \" \" << state.root_y << endl;\n    \n    vector<string> commands;\n    set<pair<int,int>> remaining_sources(sources.begin(), sources.end());\n    set<pair<int,int>> remaining_targets(targets.begin(), targets.end());\n    \n    while (!remaining_sources.empty() && commands.size() < 90000) {\n        auto pos = state.get_positions();\n        int leaf = 1;\n        \n        if (state.holding[leaf]) break;\n        \n        pair<int,int> nearest_src = *remaining_sources.begin();\n        int min_dist = INT_MAX;\n        for (auto src : remaining_sources) {\n            int d = abs(pos[leaf].first - src.first) + abs(pos[leaf].second - src.second);\n            if (d < min_dist) {\n                min_dist = d;\n                nearest_src = src;\n            }\n        }\n        \n        while (pos[leaf] != nearest_src && commands.size() < 90000) {\n            char move = '.';\n            \n            if (pos[leaf].first < nearest_src.first && state.root_x + 1 < N) {\n                move = 'D';\n                state.root_x++;\n            } else if (pos[leaf].first > nearest_src.first && state.root_x > 0) {\n                move = 'U';\n                state.root_x--;\n            } else if (pos[leaf].second < nearest_src.second && state.root_y + 1 < N) {\n                move = 'R';\n                state.root_y++;\n            } else if (pos[leaf].second > nearest_src.second && state.root_y > 0) {\n                move = 'L';\n                state.root_y--;\n            }\n            \n            commands.push_back(state.make_command(move, vector<char>(state.num_v-1, '.'), vector<char>(state.num_v, '.')));\n            pos = state.get_positions();\n        }\n        \n        if (pos[leaf] == nearest_src) {\n            vector<char> actions(state.num_v, '.');\n            actions[leaf] = 'P';\n            commands.push_back(state.make_command('.', vector<char>(state.num_v-1, '.'), actions));\n            state.holding[leaf] = true;\n            remaining_sources.erase(nearest_src);\n            \n            pair<int,int> nearest_tgt = *remaining_targets.begin();\n            min_dist = INT_MAX;\n            for (auto tgt : remaining_targets) {\n                int d = abs(pos[leaf].first - tgt.first) + abs(pos[leaf].second - tgt.second);\n                if (d < min_dist) {\n                    min_dist = d;\n                    nearest_tgt = tgt;\n                }\n            }\n            \n            while (pos[leaf] != nearest_tgt && commands.size() < 90000) {\n                char move = '.';\n                \n                if (pos[leaf].first < nearest_tgt.first && state.root_x + 1 < N) {\n                    move = 'D';\n                    state.root_x++;\n                } else if (pos[leaf].first > nearest_tgt.first && state.root_x > 0) {\n                    move = 'U';\n                    state.root_x--;\n                } else if (pos[leaf].second < nearest_tgt.second && state.root_y + 1 < N) {\n                    move = 'R';\n                    state.root_y++;\n                } else if (pos[leaf].second > nearest_tgt.second && state.root_y > 0) {\n                    move = 'L';\n                    state.root_y--;\n                }\n                \n                commands.push_back(state.make_command(move, vector<char>(state.num_v-1, '.'), vector<char>(state.num_v, '.')));\n                pos = state.get_positions();\n            }\n            \n            if (pos[leaf] == nearest_tgt) {\n                actions.assign(state.num_v, '.');\n                actions[leaf] = 'P';\n                commands.push_back(state.make_command('.', vector<char>(state.num_v-1, '.'), actions));\n                state.holding[leaf] = false;\n                remaining_targets.erase(nearest_tgt);\n            }\n        }\n    }\n    \n    for (const auto& cmd : commands) {\n        cout << cmd << endl;\n    }\n    \n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nint N;\nvector<pair<int,int>> mackerels, sardines;\n\nint calcScore(int x1, int y1, int x2, int y2) {\n    if (x1 > x2) swap(x1, x2);\n    if (y1 > y2) swap(y1, y2);\n    \n    int mac = 0, sar = 0;\n    for (auto [x, y] : mackerels) {\n        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) mac++;\n    }\n    for (auto [x, y] : sardines) {\n        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) sar++;\n    }\n    return mac - sar;\n}\n\nint main() {\n    cin >> N;\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        mackerels.push_back({x, y});\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        sardines.push_back({x, y});\n    }\n    \n    int bestScore = 0;\n    int bx1 = 0, by1 = 0, bx2 = 100000, by2 = 100000;\n    \n    mt19937 rng(12345);\n    uniform_int_distribution<int> dist(0, N-1);\n    \n    // Try rectangles around each mackerel with different sizes\n    for (int i = 0; i < N; i++) {\n        auto [cx, cy] = mackerels[i];\n        \n        for (int sz = 500; sz <= 25000; sz += 500) {\n            int x1 = max(0, cx - sz);\n            int y1 = max(0, cy - sz);\n            int x2 = min(100000, cx + sz);\n            int y2 = min(100000, cy + sz);\n            \n            int score = calcScore(x1, y1, x2, y2);\n            if (score > bestScore) {\n                bestScore = score;\n                bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n            }\n        }\n    }\n    \n    // Random sampling: try pairs of mackerels as opposite corners\n    for (int iter = 0; iter < 50000; iter++) {\n        int i = dist(rng);\n        int j = dist(rng);\n        \n        int x1 = mackerels[i].first;\n        int y1 = mackerels[i].second;\n        int x2 = mackerels[j].first;\n        int y2 = mackerels[j].second;\n        \n        int score = calcScore(x1, y1, x2, y2);\n        if (score > bestScore) {\n            bestScore = score;\n            bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n        }\n    }\n    \n    // Local search: fine-tune boundaries\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        \n        for (int delta = -1000; delta <= 1000; delta += 50) {\n            if (delta == 0) continue;\n            \n            int nx1 = max(0, min(100000, bx1 + delta));\n            int score = calcScore(nx1, by1, bx2, by2);\n            if (score > bestScore) {\n                bestScore = score;\n                bx1 = nx1;\n                improved = true;\n            }\n            \n            int nx2 = max(0, min(100000, bx2 + delta));\n            score = calcScore(bx1, by1, nx2, by2);\n            if (score > bestScore) {\n                bestScore = score;\n                bx2 = nx2;\n                improved = true;\n            }\n            \n            int ny1 = max(0, min(100000, by1 + delta));\n            score = calcScore(bx1, ny1, bx2, by2);\n            if (score > bestScore) {\n                bestScore = score;\n                by1 = ny1;\n                improved = true;\n            }\n            \n            int ny2 = max(0, min(100000, by2 + delta));\n            score = calcScore(bx1, by1, bx2, ny2);\n            if (score > bestScore) {\n                bestScore = score;\n                by2 = ny2;\n                improved = true;\n            }\n        }\n    }\n    \n    if (bx1 > bx2) swap(bx1, bx2);\n    if (by1 > by2) swap(by1, by2);\n    \n    cout << 4 << endl;\n    cout << bx1 << \" \" << by1 << endl;\n    cout << bx2 << \" \" << by1 << endl;\n    cout << bx2 << \" \" << by2 << endl;\n    cout << bx1 << \" \" << by2 << endl;\n    \n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, T;\n    long long sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<pair<long long, long long>> rects(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].first >> rects[i].second;\n    }\n    \n    mt19937 rng(42);\n    \n    for (int turn = 0; turn < T; turn++) {\n        cout << N << endl;\n        \n        // Estimate dimensions as we place rectangles\n        long long est_w = 0, est_h = 0;\n        \n        for (int i = 0; i < N; i++) {\n            long long w = rects[i].first;\n            long long h = rects[i].second;\n            \n            int r = 0;\n            char d;\n            int b;\n            \n            if (i == 0) {\n                // First rectangle at origin\n                r = (h > w) ? 1 : 0;\n                if (r) swap(w, h);\n                d = 'U';\n                b = -1;\n                est_w = w;\n                est_h = h;\n            } else {\n                // Choose strategy based on turn\n                int strategy = turn % 6;\n                \n                switch (strategy) {\n                    case 0: // Horizontal layout - minimize height\n                        r = (h > w) ? 1 : 0;\n                        if (r) swap(w, h);\n                        d = 'U';\n                        b = i - 1;\n                        est_w += w;\n                        est_h = max(est_h, h);\n                        break;\n                        \n                    case 1: // Vertical layout - minimize width\n                        r = (w > h) ? 1 : 0;\n                        if (r) swap(w, h);\n                        d = 'L';\n                        b = -1;\n                        est_h += h;\n                        est_w = max(est_w, w);\n                        break;\n                        \n                    case 2: // Balanced - keep W \u2248 H\n                        if (est_w < est_h) {\n                            // Box is taller, extend width\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            // Box is wider, extend height\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 3: // Grid pattern\n                        if (i % 3 == 1) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = (i >= 2) ? i - 2 : -1;\n                        }\n                        break;\n                        \n                    case 4: // Alternating\n                        if (i % 2 == 1) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                        }\n                        break;\n                        \n                    default: // Random\n                        r = uniform_int_distribution<>(0, 1)(rng);\n                        if (r) swap(w, h);\n                        d = (uniform_int_distribution<>(0, 1)(rng) ? 'U' : 'L');\n                        b = uniform_int_distribution<>(-1, i - 1)(rng);\n                        break;\n                }\n            }\n            \n            cout << i << \" \" << r << \" \" << d << \" \" << b << endl;\n        }\n        cout.flush();\n        \n        long long W, H;\n        cin >> W >> H;\n    }\n    \n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\nint main() {\n    int N, M, H;\n    cin >> N >> M >> H;\n    \n    vector<int> A(N);\n    for (int i = 0; i < N; i++) {\n        cin >> A[i];\n    }\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    // Skip coordinates (not needed for algorithm)\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    vector<int> parent(N, -1);\n    vector<bool> assigned(N, false);\n    \n    // Build trees greedily\n    while (true) {\n        // Find unassigned vertex with minimum beauty as root\n        int root = -1;\n        for (int i = 0; i < N; i++) {\n            if (!assigned[i]) {\n                if (root == -1 || A[i] < A[root]) {\n                    root = i;\n                }\n            }\n        }\n        \n        if (root == -1) break;\n        \n        // BFS from root to build tree\n        queue<pair<int, int>> q; // (vertex, height)\n        q.push({root, 0});\n        assigned[root] = true;\n        parent[root] = -1;\n        \n        while (!q.empty()) {\n            int u = q.front().first;\n            int h = q.front().second;\n            q.pop();\n            \n            if (h >= H) continue; // Reached max height\n            \n            // Collect unassigned neighbors\n            vector<int> neighbors;\n            for (int v : adj[u]) {\n                if (!assigned[v]) {\n                    neighbors.push_back(v);\n                }\n            }\n            \n            // Sort neighbors by beauty (descending) to prioritize high beauty\n            sort(neighbors.begin(), neighbors.end(), [&A](int a, int b) {\n                return A[a] > A[b];\n            });\n            \n            // Add neighbors to tree\n            for (int v : neighbors) {\n                if (!assigned[v]) {\n                    assigned[v] = true;\n                    parent[v] = u;\n                    q.push({v, h + 1});\n                }\n            }\n        }\n    }\n    \n    // Output parent array\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << parent[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    vector<pair<char, int>> moves;\n    \n    // Find all Oni positions\n    vector<pair<int,int>> oni_positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 'x') {\n                oni_positions.push_back({i, j});\n            }\n        }\n    }\n    \n    // For each Oni, find the safe direction with minimum distance\n    for (auto [oi, oj] : oni_positions) {\n        int best_dist = N + 1;\n        char best_dir = ' ';\n        int best_pos = 0;\n        \n        // Check upward (no Fukunokami above)\n        bool safe_up = true;\n        for (int i = 0; i < oi; i++) {\n            if (board[i][oj] == 'o') {\n                safe_up = false;\n                break;\n            }\n        }\n        if (safe_up) {\n            int dist = oi + 1;\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_dir = 'U';\n                best_pos = oj;\n            }\n        }\n        \n        // Check downward\n        bool safe_down = true;\n        for (int i = oi + 1; i < N; i++) {\n            if (board[i][oj] == 'o') {\n                safe_down = false;\n                break;\n            }\n        }\n        if (safe_down) {\n            int dist = N - oi;\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_dir = 'D';\n                best_pos = oj;\n            }\n        }\n        \n        // Check leftward\n        bool safe_left = true;\n        for (int j = 0; j < oj; j++) {\n            if (board[oi][j] == 'o') {\n                safe_left = false;\n                break;\n            }\n        }\n        if (safe_left) {\n            int dist = oj + 1;\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_dir = 'L';\n                best_pos = oi;\n            }\n        }\n        \n        // Check rightward\n        bool safe_right = true;\n        for (int j = oj + 1; j < N; j++) {\n            if (board[oi][j] == 'o') {\n                safe_right = false;\n                break;\n            }\n        }\n        if (safe_right) {\n            int dist = N - oj;\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_dir = 'R';\n                best_pos = oi;\n            }\n        }\n        \n        // Apply the best direction (shift out, then shift back)\n        if (best_dir == 'U' || best_dir == 'D') {\n            char reverse = (best_dir == 'U') ? 'D' : 'U';\n            for (int t = 0; t < best_dist; t++) {\n                moves.push_back({best_dir, best_pos});\n            }\n            for (int t = 0; t < best_dist; t++) {\n                moves.push_back({reverse, best_pos});\n            }\n        } else {\n            char reverse = (best_dir == 'L') ? 'R' : 'L';\n            for (int t = 0; t < best_dist; t++) {\n                moves.push_back({best_dir, best_pos});\n            }\n            for (int t = 0; t < best_dist; t++) {\n                moves.push_back({reverse, best_pos});\n            }\n        }\n    }\n    \n    // Output moves\n    for (auto [dir, pos] : moves) {\n        cout << dir << \" \" << pos << endl;\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, L;\nvector<int> T;\n\nlong long simulate(const vector<int>& a, const vector<int>& b) {\n    vector<int> count(N, 0);\n    int current = 0;\n    count[0] = 1;\n    \n    for (int week = 1; week < L; week++) {\n        int t = count[current];\n        if (t & 1) {\n            current = a[current];\n        } else {\n            current = b[current];\n        }\n        count[current]++;\n    }\n    \n    long long error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(count[i] - T[i]);\n    }\n    return error;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> L;\n    T.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> prob(0.0, 1.0);\n    \n    vector<int> best_a(N), best_b(N);\n    long long best_error = LLONG_MAX;\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    double time_limit = 1.9;\n    \n    // Precompute sorted targets for weighted initialization\n    vector<pair<int, int>> sorted_T;\n    for (int i = 0; i < N; i++) {\n        sorted_T.push_back({T[i], i});\n    }\n    sort(sorted_T.rbegin(), sorted_T.rend());\n    \n    while (true) {\n        auto current_time = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed > time_limit) break;\n        \n        // Initialize with weighted random (favor high-target employees)\n        vector<int> a(N), b(N);\n        for (int i = 0; i < N; i++) {\n            int idx1 = gen() % min(40, N);\n            int idx2 = gen() % min(40, N);\n            a[i] = sorted_T[idx1].second;\n            b[i] = sorted_T[idx2].second;\n        }\n        \n        long long error = simulate(a, b);\n        if (error < best_error) {\n            best_error = error;\n            best_a = a;\n            best_b = b;\n        }\n        \n        // Hill climbing local search\n        int no_improve = 0;\n        while (no_improve < 1000) {\n            current_time = chrono::high_resolution_clock::now();\n            elapsed = chrono::duration<double>(current_time - start_time).count();\n            if (elapsed > time_limit) break;\n            \n            int i = gen() % N;\n            int new_val = gen() % N;\n            \n            int old_val;\n            bool modify_a = gen() % 2;\n            if (modify_a) {\n                old_val = a[i];\n                a[i] = new_val;\n            } else {\n                old_val = b[i];\n                b[i] = new_val;\n            }\n            \n            long long new_error = simulate(a, b);\n            \n            if (new_error < error) {\n                error = new_error;\n                no_improve = 0;\n                if (error < best_error) {\n                    best_error = error;\n                    best_a = a;\n                    best_b = b;\n                }\n            } else {\n                if (modify_a) {\n                    a[i] = old_val;\n                } else {\n                    b[i] = old_val;\n                }\n                no_improve++;\n            }\n        }\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 <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent;\npublic:\n    UnionFind(int n) : parent(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        parent[px] = py;\n        return true;\n    }\n};\n\nint main() {\n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<pair<double, double>> pos(N);\n    for (int i = 0; i < N; i++) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        pos[i] = {(lx + rx) / 2.0, (ly + ry) / 2.0};\n    }\n    \n    // Sort cities by position\n    vector<int> order(N);\n    for (int i = 0; i < N; i++) order[i] = i;\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return pos[a] < pos[b];\n    });\n    \n    // Create groups\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < G[i]; j++) {\n            groups[i].push_back(order[idx++]);\n        }\n    }\n    \n    // Get edges for each group\n    vector<vector<pair<int, int>>> edges(M);\n    \n    for (int k = 0; k < M; k++) {\n        if (G[k] == 1) continue;\n        \n        if (G[k] <= L) {\n            // Query entire group\n            cout << \"? \" << G[k];\n            for (int c : groups[k]) cout << \" \" << c;\n            cout << endl;\n            cout.flush();\n            \n            for (int i = 0; i < G[k] - 1; i++) {\n                int u, v;\n                cin >> u >> v;\n                edges[k].push_back({u, v});\n            }\n        } else {\n            // Use sliding window with Union-Find\n            UnionFind uf(N);\n            \n            for (int i = 0; i + 1 < G[k]; i += 2) {\n                int sz = min(3, G[k] - i);\n                \n                cout << \"? \" << sz;\n                for (int j = 0; j < sz; j++) {\n                    cout << \" \" << groups[k][i + j];\n                }\n                cout << endl;\n                cout.flush();\n                \n                for (int j = 0; j < sz - 1; j++) {\n                    int u, v;\n                    cin >> u >> v;\n                    if (uf.unite(u, v)) {\n                        edges[k].push_back({u, v});\n                    }\n                }\n            }\n            \n            // Ensure connectivity\n            for (int i = 0; i + 1 < G[k] && (int)edges[k].size() < G[k] - 1; i++) {\n                if (uf.unite(groups[k][i], groups[k][i + 1])) {\n                    edges[k].push_back({groups[k][i], groups[k][i + 1]});\n                }\n            }\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int c : groups[k]) cout << c << \" \";\n        cout << endl;\n        for (auto [u, v] : edges[k]) {\n            cout << u << \" \" << v << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\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    int cur_r = targets[0].first;\n    int cur_c = targets[0].second;\n    \n    // Visit each target in order\n    for (int i = 1; i < M; i++) {\n        int target_r = targets[i].first;\n        int target_c = targets[i].second;\n        \n        // Move vertically first\n        while (cur_r != target_r) {\n            if (cur_r < target_r) {\n                cout << \"M D\\n\";\n                cur_r++;\n            } else {\n                cout << \"M U\\n\";\n                cur_r--;\n            }\n        }\n        \n        // Then move horizontally\n        while (cur_c != target_c) {\n            if (cur_c < target_c) {\n                cout << \"M R\\n\";\n                cur_c++;\n            } else {\n                cout << \"M L\\n\";\n                cur_c--;\n            }\n        }\n    }\n    \n    return 0;\n}"},"2":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> x, y;\nvector<long long> r;\nvector<array<int, 4>> result;\n\nvoid solve(vector<int> ids, int x1, int y1, int x2, int y2) {\n    if (ids.empty()) return;\n    \n    if (ids.size() == 1) {\n        result[ids[0]] = {x1, y1, x2, y2};\n        return;\n    }\n    \n    long long total_r = 0;\n    for (int id : ids) total_r += r[id];\n    \n    if (x2 - x1 >= y2 - y1) {\n        // Vertical split\n        sort(ids.begin(), ids.end(), [](int i, int j) {\n            return x[i] < x[j];\n        });\n        \n        // Find best split index that minimizes area imbalance\n        int best_mid = 1;\n        double best_score = 1e18;\n        \n        for (int mid = 1; mid < ids.size(); mid++) {\n            long long left_r = 0;\n            for (int i = 0; i < mid; i++) left_r += r[ids[i]];\n            long long right_r = total_r - left_r;\n            \n            // Calculate ideal and constrained split position\n            int ideal_split = x1 + (long long)(x2 - x1) * left_r / total_r;\n            \n            // Ensure point constraints are satisfied\n            int min_split = max(x1 + 1, x[ids[mid-1]] + 1);\n            int max_split = min(x2 - 1, x[ids[mid]] + 1);\n            \n            if (min_split > max_split) continue;\n            \n            int split_x = max(min_split, min(max_split, ideal_split));\n            \n            // Calculate area-to-desired ratio deviation\n            long long left_area = (long long)(split_x - x1) * (y2 - y1);\n            long long right_area = (long long)(x2 - split_x) * (y2 - y1);\n            \n            double ratio_left = (double)left_area / left_r;\n            double ratio_right = (double)right_area / right_r;\n            double score = abs(ratio_left - ratio_right);\n            \n            if (score < best_score) {\n                best_score = score;\n                best_mid = mid;\n            }\n        }\n        \n        int mid = best_mid;\n        long long left_r = 0;\n        for (int i = 0; i < mid; i++) left_r += r[ids[i]];\n        \n        int ideal_split = x1 + (long long)(x2 - x1) * left_r / total_r;\n        int min_split = max(x1 + 1, x[ids[mid-1]] + 1);\n        int max_split = min(x2 - 1, x[ids[mid]] + 1);\n        int split_x = max(min_split, min(max_split, ideal_split));\n        \n        vector<int> left(ids.begin(), ids.begin() + mid);\n        vector<int> right(ids.begin() + mid, ids.end());\n        \n        solve(left, x1, y1, split_x, y2);\n        solve(right, split_x, y1, x2, y2);\n    } else {\n        // Horizontal split\n        sort(ids.begin(), ids.end(), [](int i, int j) {\n            return y[i] < y[j];\n        });\n        \n        int best_mid = 1;\n        double best_score = 1e18;\n        \n        for (int mid = 1; mid < ids.size(); mid++) {\n            long long top_r = 0;\n            for (int i = 0; i < mid; i++) top_r += r[ids[i]];\n            long long bottom_r = total_r - top_r;\n            \n            int ideal_split = y1 + (long long)(y2 - y1) * top_r / total_r;\n            \n            int min_split = max(y1 + 1, y[ids[mid-1]] + 1);\n            int max_split = min(y2 - 1, y[ids[mid]] + 1);\n            \n            if (min_split > max_split) continue;\n            \n            int split_y = max(min_split, min(max_split, ideal_split));\n            \n            long long top_area = (long long)(x2 - x1) * (split_y - y1);\n            long long bottom_area = (long long)(x2 - x1) * (y2 - split_y);\n            \n            double ratio_top = (double)top_area / top_r;\n            double ratio_bottom = (double)bottom_area / bottom_r;\n            double score = abs(ratio_top - ratio_bottom);\n            \n            if (score < best_score) {\n                best_score = score;\n                best_mid = mid;\n            }\n        }\n        \n        int mid = best_mid;\n        long long top_r = 0;\n        for (int i = 0; i < mid; i++) top_r += r[ids[i]];\n        \n        int ideal_split = y1 + (long long)(y2 - y1) * top_r / total_r;\n        int min_split = max(y1 + 1, y[ids[mid-1]] + 1);\n        int max_split = min(y2 - 1, y[ids[mid]] + 1);\n        int split_y = max(min_split, min(max_split, ideal_split));\n        \n        vector<int> top(ids.begin(), ids.begin() + mid);\n        vector<int> bottom(ids.begin() + mid, ids.end());\n        \n        solve(top, x1, y1, x2, split_y);\n        solve(bottom, x1, split_y, x2, y2);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n;\n    x.resize(n);\n    y.resize(n);\n    r.resize(n);\n    result.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> x[i] >> y[i] >> r[i];\n    }\n    \n    vector<int> all_ids(n);\n    iota(all_ids.begin(), all_ids.end(), 0);\n    \n    solve(all_ids, 0, 0, 10000, 10000);\n    \n    for (int i = 0; i < n; i++) {\n        cout << result[i][0] << \" \" << result[i][1] << \" \" \n             << result[i][2] << \" \" << result[i][3] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nmap<int, vector<pair<int,int>>> tile_squares;\nmap<int, int> tile_value;\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < 50 && y >= 0 && y < 50;\n}\n\nint main() {\n    cin >> si >> sj;\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> t[i][j];\n            tile_squares[t[i][j]].push_back({i, j});\n        }\n    }\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> p[i][j];\n            tile_value[t[i][j]] += p[i][j];\n        }\n    }\n    \n    bool visited_tile[2500] = {};\n    bool visited_square[50][50] = {};\n    string path = \"\";\n    int x = si, y = sj;\n    visited_tile[t[x][y]] = true;\n    visited_square[x][y] = true;\n    \n    while (true) {\n        int current_tile = t[x][y];\n        \n        // First priority: visit other squares of current tile\n        int best_dir = -1;\n        int best_value = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (!in_bounds(nx, ny)) continue;\n            if (visited_square[nx][ny]) continue;\n            \n            int next_tile = t[nx][ny];\n            \n            if (next_tile == current_tile) {\n                if (best_dir == -1 || p[nx][ny] > best_value) {\n                    best_value = p[nx][ny];\n                    best_dir = d;\n                }\n            }\n        }\n        \n        // Second priority: move to new tile with highest total value\n        if (best_dir == -1) {\n            int best_tile_value = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                \n                if (!in_bounds(nx, ny)) continue;\n                if (visited_square[nx][ny]) continue;\n                \n                int next_tile = t[nx][ny];\n                \n                if (visited_tile[next_tile]) continue;\n                \n                if (tile_value[next_tile] > best_tile_value) {\n                    best_tile_value = tile_value[next_tile];\n                    best_dir = d;\n                }\n            }\n        }\n        \n        if (best_dir == -1) break;\n        \n        int nx = x + dx[best_dir];\n        int ny = y + dy[best_dir];\n        \n        path += dir_char[best_dir];\n        visited_square[nx][ny] = true;\n        visited_tile[t[nx][ny]] = true;\n        \n        x = nx;\n        y = ny;\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst double INF = 1e18;\nconst double DEFAULT_WEIGHT = 5000.0;\n\ndouble h[N][N], v[N][N];\nint h_count[N][N], v_count[N][N];\n\nvoid init_weights() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            h[i][j] = DEFAULT_WEIGHT;\n            v[i][j] = DEFAULT_WEIGHT;\n            h_count[i][j] = 0;\n            v_count[i][j] = 0;\n        }\n    }\n}\n\npair<double, vector<pair<int,int>>> dijkstra(int si, int sj, int ti, int tj) {\n    vector<vector<double>> dist(N, vector<double>(N, INF));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    priority_queue<pair<double, pair<int,int>>, \n                   vector<pair<double, pair<int,int>>>,\n                   greater<>> pq;\n    \n    dist[si][sj] = 0;\n    pq.push({0, {si, sj}});\n    \n    while (!pq.empty()) {\n        auto [d, pos] = pq.top();\n        pq.pop();\n        auto [i, j] = pos;\n        \n        if (d > dist[i][j]) continue;\n        \n        if (i > 0 && dist[i][j] + v[i-1][j] < dist[i-1][j]) {\n            dist[i-1][j] = dist[i][j] + v[i-1][j];\n            parent[i-1][j] = {i, j};\n            pq.push({dist[i-1][j], {i-1, j}});\n        }\n        if (i < N-1 && dist[i][j] + v[i][j] < dist[i+1][j]) {\n            dist[i+1][j] = dist[i][j] + v[i][j];\n            parent[i+1][j] = {i, j};\n            pq.push({dist[i+1][j], {i+1, j}});\n        }\n        if (j > 0 && dist[i][j] + h[i][j-1] < dist[i][j-1]) {\n            dist[i][j-1] = dist[i][j] + h[i][j-1];\n            parent[i][j-1] = {i, j};\n            pq.push({dist[i][j-1], {i, j-1}});\n        }\n        if (j < N-1 && dist[i][j] + h[i][j] < dist[i][j+1]) {\n            dist[i][j+1] = dist[i][j] + h[i][j];\n            parent[i][j+1] = {i, j};\n            pq.push({dist[i][j+1], {i, j+1}});\n        }\n    }\n    \n    vector<pair<int,int>> path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        path.push_back({ci, cj});\n        auto [pi, pj] = parent[ci][cj];\n        if (pi == -1) break;\n        ci = pi;\n        cj = pj;\n    }\n    path.push_back({si, sj});\n    reverse(path.begin(), path.end());\n    \n    return {dist[ti][tj], path};\n}\n\nstring path_to_string(const vector<pair<int,int>>& path) {\n    string result;\n    for (int i = 1; i < path.size(); i++) {\n        int di = path[i].first - path[i-1].first;\n        int dj = path[i].second - path[i-1].second;\n        if (di == -1) result += 'U';\n        else if (di == 1) result += 'D';\n        else if (dj == -1) result += 'L';\n        else result += 'R';\n    }\n    return result;\n}\n\nvoid update_weights(const vector<pair<int,int>>& path, double measured, double estimated, int query_num) {\n    if (path.size() <= 1) return;\n    \n    // Calculate uncertainty for each edge (inverse of confidence)\n    vector<double> uncertainties;\n    double total_uncertainty = 0;\n    \n    for (int i = 1; i < path.size(); i++) {\n        int pi = path[i-1].first, pj = path[i-1].second;\n        int ci = path[i].first, cj = path[i].second;\n        \n        double uncertainty;\n        if (pi == ci) {\n            int j = min(pj, cj);\n            uncertainty = 1.0 / (1.0 + h_count[pi][j]);\n        } else {\n            int ii = min(pi, ci);\n            uncertainty = 1.0 / (1.0 + v_count[ii][pj]);\n        }\n        uncertainties.push_back(uncertainty);\n        total_uncertainty += uncertainty;\n    }\n    \n    double error = measured - estimated;\n    \n    // Adaptive learning rate: aggressive early, conservative later\n    double base_alpha = 0.5 * exp(-query_num / 300.0) + 0.15;\n    \n    for (int i = 1; i < path.size(); i++) {\n        int pi = path[i-1].first, pj = path[i-1].second;\n        int ci = path[i].first, cj = path[i].second;\n        \n        // Distribute error proportional to uncertainty\n        double weight = uncertainties[i-1] / total_uncertainty;\n        double correction = base_alpha * error * weight;\n        \n        if (pi == ci) {\n            int j = min(pj, cj);\n            h_count[pi][j]++;\n            h[pi][j] += correction;\n            h[pi][j] = max(1000.0, min(9000.0, h[pi][j]));\n        } else {\n            int ii = min(pi, ci);\n            v_count[ii][pj]++;\n            v[ii][pj] += correction;\n            v[ii][pj] = max(1000.0, min(9000.0, v[ii][pj]));\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_weights();\n    \n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        auto [estimated_len, path] = dijkstra(si, sj, ti, tj);\n        string path_str = path_to_string(path);\n        \n        cout << path_str << endl;\n        cout.flush();\n        \n        int measured;\n        cin >> measured;\n        \n        update_weights(path, measured, estimated_len, q);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nvector<string> strings;\nchar matrix[20][20];\nchar best_matrix[20][20];\n\nbool isSubsequence(const string& s) {\n    int k = s.length();\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            bool ok = true;\n            for (int p = 0; p < k; p++) {\n                if (matrix[i][(j + p) % N] != s[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return true;\n            \n            ok = true;\n            for (int p = 0; p < k; p++) {\n                if (matrix[(i + p) % N][j] != s[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return true;\n        }\n    }\n    return false;\n}\n\nint countMatched() {\n    int count = 0;\n    for (const auto& s : strings) {\n        if (isSubsequence(s)) count++;\n    }\n    return count;\n}\n\nint countConflicts(const string& s, int i, int j, int d) {\n    int k = s.length();\n    int conflicts = 0;\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        if (matrix[ni][nj] != '.' && matrix[ni][nj] != s[p]) {\n            conflicts++;\n        }\n    }\n    return conflicts;\n}\n\nint countMatching(const string& s, int i, int j, int d) {\n    int k = s.length();\n    int matching = 0;\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        if (matrix[ni][nj] == s[p]) {\n            matching++;\n        }\n    }\n    return matching;\n}\n\nvoid place(const string& s, int i, int j, int d) {\n    int k = s.length();\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        matrix[ni][nj] = s[p];\n    }\n}\n\nint main() {\n    cin >> N >> M;\n    strings.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    int best_score = 0;\n    \n    // Multiple random restarts\n    for (int restart = 0; restart < 10; restart++) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                matrix[i][j] = '.';\n            }\n        }\n        \n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        \n        if (restart == 0) {\n            // First try: longest first\n            sort(order.begin(), order.end(), [](int a, int b) {\n                return strings[a].length() > strings[b].length();\n            });\n        } else {\n            // Random shuffle for diversity\n            random_shuffle(order.begin(), order.end());\n        }\n        \n        // Greedy placement with increasing conflict tolerance\n        for (int maxConflicts = 0; maxConflicts <= 2; maxConflicts++) {\n            for (int idx : order) {\n                const string& s = strings[idx];\n                if (isSubsequence(s)) continue;\n                \n                int bestI = -1, bestJ = -1, bestD = -1;\n                int minConflicts = INT_MAX;\n                int maxMatching = -1;\n                \n                for (int i = 0; i < N; i++) {\n                    for (int j = 0; j < N; j++) {\n                        for (int d = 0; d < 2; d++) {\n                            int conflicts = countConflicts(s, i, j, d);\n                            int matching = countMatching(s, i, j, d);\n                            \n                            if (conflicts < minConflicts || \n                                (conflicts == minConflicts && matching > maxMatching)) {\n                                minConflicts = conflicts;\n                                maxMatching = matching;\n                                bestI = i;\n                                bestJ = j;\n                                bestD = d;\n                            }\n                        }\n                    }\n                }\n                \n                if (minConflicts <= maxConflicts && bestI != -1) {\n                    place(s, bestI, bestJ, bestD);\n                }\n            }\n        }\n        \n        // Smart dot filling\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (matrix[i][j] == '.') {\n                    int bestChar = 'A';\n                    int bestCount = 0;\n                    \n                    for (char c = 'A'; c <= 'H'; c++) {\n                        matrix[i][j] = c;\n                        int count = countMatched();\n                        if (count > bestCount) {\n                            bestCount = count;\n                            bestChar = c;\n                        }\n                    }\n                    matrix[i][j] = bestChar;\n                }\n            }\n        }\n        \n        int score = countMatched();\n        if (score > best_score) {\n            best_score = score;\n            memcpy(best_matrix, matrix, sizeof(matrix));\n        }\n    }\n    \n    memcpy(matrix, best_matrix, sizeof(matrix));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << matrix[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\n\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nbool is_valid(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\nset<pair<int,int>> get_visible(int i, int j) {\n    set<pair<int,int>> vis;\n    vis.insert({i, j});\n    for (int jj = j-1; jj >= 0 && grid[i][jj] != '#'; jj--) vis.insert({i, jj});\n    for (int jj = j+1; jj < N && grid[i][jj] != '#'; jj++) vis.insert({i, jj});\n    for (int ii = i-1; ii >= 0 && grid[ii][j] != '#'; ii--) vis.insert({ii, j});\n    for (int ii = i+1; ii < N && grid[ii][j] != '#'; ii++) vis.insert({ii, j});\n    return vis;\n}\n\nmap<pair<int,int>, int> dijkstra_dist(int si, int sj) {\n    map<pair<int,int>, int> dist;\n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    pq.push({0, si, sj});\n    dist[{si, sj}] = 0;\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        if (dist.count({i,j}) && d > dist[{i, j}]) continue;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (is_valid(ni, nj)) {\n                int nd = d + (grid[ni][nj] - '0');\n                if (!dist.count({ni, nj}) || nd < dist[{ni, nj}]) {\n                    dist[{ni, nj}] = nd;\n                    pq.push({nd, ni, nj});\n                }\n            }\n        }\n    }\n    return dist;\n}\n\nstring reconstruct_path(int si, int sj, int ti, int tj) {\n    if (si == ti && sj == tj) return \"\";\n    \n    map<pair<int,int>, pair<pair<int,int>, int>> parent;\n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    pq.push({0, si, sj});\n    parent[{si, sj}] = {{-1, -1}, -1};\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        if (i == ti && j == tj) {\n            string path;\n            auto curr = make_pair(ti, tj);\n            while (parent[curr].second != -1) {\n                path += dir_char[parent[curr].second];\n                curr = parent[curr].first;\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (is_valid(ni, nj) && !parent.count({ni, nj})) {\n                parent[{ni, nj}] = {{i, j}, dir};\n                int nd = d + (grid[ni][nj] - '0');\n                pq.push({nd, ni, nj});\n            }\n        }\n    }\n    return \"\";\n}\n\nint main() {\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    vector<pair<int,int>> roads;\n    set<pair<int,int>> all_roads;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                roads.push_back({i, j});\n                all_roads.insert({i, j});\n            }\n        }\n    }\n    \n    map<pair<int,int>, set<pair<int,int>>> visible_from;\n    for (auto& [i, j] : roads) {\n        visible_from[{i, j}] = get_visible(i, j);\n    }\n    \n    // Calculate coverage count for each square (importance metric)\n    map<pair<int,int>, int> coverage_count;\n    for (auto& sq : all_roads) {\n        for (auto& [pos, vis] : visible_from) {\n            if (vis.count(sq)) coverage_count[sq]++;\n        }\n    }\n    \n    set<pair<int,int>> covered = visible_from[{si, sj}];\n    vector<pair<int,int>> tour = {{si, sj}};\n    \n    // Greedy with cost-benefit and importance weighting\n    while (covered.size() < all_roads.size()) {\n        auto dist = dijkstra_dist(tour.back().first, tour.back().second);\n        \n        double best_score = -1e9;\n        pair<int,int> best_pos = tour.back();\n        \n        for (auto& [ri, rj] : roads) {\n            int new_count = 0;\n            double importance = 0;\n            for (auto& sq : visible_from[{ri, rj}]) {\n                if (!covered.count(sq)) {\n                    new_count++;\n                    // Weight by rarity - squares visible from fewer positions are more important\n                    importance += 1.0 / max(1, coverage_count[sq]);\n                }\n            }\n            if (new_count > 0 && dist.count({ri, rj})) {\n                int cost = dist[{ri, rj}];\n                // Score combines coverage importance and travel efficiency\n                double score = (importance * 10.0) / (cost + 1.0);\n                if (score > best_score) {\n                    best_score = score;\n                    best_pos = {ri, rj};\n                }\n            }\n        }\n        \n        if (best_score <= -1e8) break;\n        \n        tour.push_back(best_pos);\n        for (auto& sq : visible_from[best_pos]) covered.insert(sq);\n    }\n    \n    // Build path through tour\n    string result;\n    for (int i = 0; i < (int)tour.size() - 1; i++) {\n        result += reconstruct_path(tour[i].first, tour[i].second, \n                                   tour[i+1].first, tour[i+1].second);\n    }\n    result += reconstruct_path(tour.back().first, tour.back().second, si, sj);\n    \n    cout << result << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <map>\n#include <cmath>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> task_diff;\nvector<vector<int>> task_deps;\nvector<int> task_status; // -1: not started, 0: running, 1: done\nvector<vector<double>> member_skill;\nvector<int> member_task;\nmap<int, int> start_day_map;\n\nbool can_start(int task) {\n    if (task_status[task] != -1) return false;\n    for (int dep : task_deps[task]) {\n        if (task_status[dep] != 1) return false;\n    }\n    return true;\n}\n\ndouble estimate_time(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++) {\n        w += max(0.0, task_diff[task][k] - member_skill[member][k]);\n    }\n    return (w < 0.5) ? 1.0 : w + 1.0;\n}\n\nvoid update_skill(int member, int task, int days) {\n    if (days == 1) {\n        // w=0, so member has all required skills\n        for (int k = 0; k < K; k++) {\n            member_skill[member][k] = max(member_skill[member][k], \n                                         (double)task_diff[task][k]);\n        }\n    }\n}\n\nint main() {\n    cin >> N >> M >> K >> R;\n    \n    task_diff.resize(N, vector<int>(K));\n    task_deps.resize(N);\n    task_status.resize(N, -1);\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> task_diff[i][j];\n        }\n    }\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        task_deps[v].push_back(u);\n    }\n    \n    member_skill.resize(M, vector<double>(K, 30.0));\n    member_task.resize(M, -1);\n    \n    int day = 0;\n    \n    while (true) {\n        day++;\n        \n        vector<int> available;\n        for (int i = 0; i < N; i++) {\n            if (can_start(i)) available.push_back(i);\n        }\n        \n        vector<int> idle;\n        for (int i = 0; i < M; i++) {\n            if (member_task[i] == -1) idle.push_back(i);\n        }\n        \n        vector<pair<int, int>> assign;\n        \n        for (int m : idle) {\n            if (available.empty()) break;\n            \n            int best = -1;\n            double best_score = 1e9;\n            \n            for (int t : available) {\n                double score = estimate_time(t, m);\n                if (score < best_score) {\n                    best_score = score;\n                    best = t;\n                }\n            }\n            \n            if (best != -1) {\n                assign.push_back({m, best});\n                member_task[m] = best;\n                task_status[best] = 0;\n                start_day_map[m] = day;\n                available.erase(remove(available.begin(), available.end(), best),\n                              available.end());\n            }\n        }\n        \n        cout << assign.size();\n        for (auto [m, t] : assign) {\n            cout << \" \" << (m + 1) << \" \" << (t + 1);\n        }\n        cout << endl;\n        cout.flush();\n        \n        int n;\n        cin >> n;\n        if (n == -1) break;\n        \n        for (int i = 0; i < n; i++) {\n            int m;\n            cin >> m;\n            m--;\n            int t = member_task[m];\n            int days = day - start_day_map[m] + 1;\n            task_status[t] = 1;\n            member_task[m] = -1;\n            update_skill(m, t, days);\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <chrono>\n\nusing namespace std;\n\nstruct Order {\n    int id;\n    int ax, ay, cx, cy;\n};\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nclass Solution {\npublic:\n    vector<Order> orders;\n    \n    void read_input() {\n        orders.resize(1000);\n        for (int i = 0; i < 1000; i++) {\n            orders[i].id = i;\n            cin >> orders[i].ax >> orders[i].ay >> orders[i].cx >> orders[i].cy;\n        }\n    }\n    \n    int calc_cost(const vector<pair<int, int>>& route) {\n        int cost = 0;\n        for (size_t i = 1; i < route.size(); i++) {\n            cost += manhattan(route[i-1].first, route[i-1].second, route[i].first, route[i].second);\n        }\n        return cost;\n    }\n    \n    double score_order(int idx, double w1, double w2) {\n        double d_pickup = manhattan(400, 400, orders[idx].ax, orders[idx].ay);\n        double d_delivery = manhattan(400, 400, orders[idx].cx, orders[idx].cy);\n        double d_pd = manhattan(orders[idx].ax, orders[idx].ay, orders[idx].cx, orders[idx].cy);\n        return (d_pickup + d_delivery) * w1 + d_pd * w2;\n    }\n    \n    vector<int> select_orders(double w1, double w2) {\n        vector<pair<double, int>> scores;\n        for (int i = 0; i < 1000; i++) {\n            scores.push_back({score_order(i, w1, w2), i});\n        }\n        sort(scores.begin(), scores.end());\n        \n        vector<int> selected;\n        for (int i = 0; i < 50; i++) {\n            selected.push_back(scores[i].second);\n        }\n        return selected;\n    }\n    \n    vector<pair<int, int>> construct_route(const vector<int>& selected) {\n        vector<pair<int, int>> route;\n        route.push_back({400, 400});\n        \n        set<int> need_pickup(selected.begin(), selected.end());\n        set<int> picked_up;\n        \n        int cx = 400, cy = 400;\n        \n        while (!need_pickup.empty() || !picked_up.empty()) {\n            int best_idx = -1;\n            int best_dist = 2000000;\n            bool is_pickup = false;\n            \n            for (int idx : need_pickup) {\n                int d = manhattan(cx, cy, orders[idx].ax, orders[idx].ay);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = true;\n                }\n            }\n            \n            for (int idx : picked_up) {\n                int d = manhattan(cx, cy, orders[idx].cx, orders[idx].cy);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = false;\n                }\n            }\n            \n            if (is_pickup) {\n                route.push_back({orders[best_idx].ax, orders[best_idx].ay});\n                cx = orders[best_idx].ax;\n                cy = orders[best_idx].ay;\n                need_pickup.erase(best_idx);\n                picked_up.insert(best_idx);\n            } else {\n                route.push_back({orders[best_idx].cx, orders[best_idx].cy});\n                cx = orders[best_idx].cx;\n                cy = orders[best_idx].cy;\n                picked_up.erase(best_idx);\n            }\n        }\n        \n        route.push_back({400, 400});\n        return route;\n    }\n    \n    void solve() {\n        read_input();\n        \n        int best_cost = 2000000000;\n        vector<int> best_selected;\n        vector<pair<int, int>> best_route;\n        \n        // Try multiple parameter combinations\n        vector<pair<double, double>> params = {\n            {0.5, 0.5}, {0.6, 0.4}, {0.7, 0.3}, {0.8, 0.2},\n            {0.4, 0.6}, {0.5, 0.4}, {0.6, 0.5}, {0.55, 0.45}\n        };\n        \n        for (auto [w1, w2] : params) {\n            vector<int> selected = select_orders(w1, w2);\n            vector<pair<int, int>> route = construct_route(selected);\n            int cost = calc_cost(route);\n            \n            if (cost < best_cost) {\n                best_cost = cost;\n                best_selected = selected;\n                best_route = route;\n            }\n        }\n        \n        cout << best_selected.size();\n        for (int idx : best_selected) {\n            cout << \" \" << (idx + 1);\n        }\n        cout << \"\\n\";\n        \n        cout << best_route.size();\n        for (auto [x, y] : best_route) {\n            cout << \" \" << x << \" \" << y;\n        }\n        cout << \"\\n\";\n        cout.flush();\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.solve();\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent, rank;\npublic:\n    UnionFind(int n) : parent(n), rank(n, 0) {\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    \n    int find(int x) {\n        return parent[x] == x ? x : parent[x] = find(parent[x]);\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400, M = 1995;\n    \n    vector<pair<int,int>> coord(N);\n    for (auto& [x, y] : coord) cin >> x >> y;\n    \n    vector<pair<int,int>> edge(M);\n    vector<int> dist(M);\n    \n    for (int i = 0; i < M; i++) {\n        auto& [u, v] = edge[i];\n        cin >> u >> v;\n        int dx = coord[u].first - coord[v].first;\n        int dy = coord[u].second - coord[v].second;\n        dist[i] = round(sqrt(dx*dx + dy*dy));\n    }\n    \n    UnionFind uf(N);\n    int cnt = 0;\n    \n    for (int i = 0; i < M; i++) {\n        int len;\n        cin >> len;\n        \n        auto [u, v] = edge[i];\n        int d = dist[i];\n        \n        bool ok = false;\n        if (uf.find(u) != uf.find(v)) {\n            int need = N - 1 - cnt;\n            int left = M - i;\n            \n            double r = (double)len / d;\n            double th;\n            \n            // Adaptive threshold based on safety margin\n            if (left <= need * 1.2) {\n                th = 3.0;  // Emergency mode: accept anything\n            } else if (left <= need * 2.0) {\n                th = 2.3;  // Getting tight\n            } else if (left <= need * 3.0) {\n                th = 1.9;  // Moderate selectivity\n            } else {\n                th = 1.7;  // Plenty of room: be selective\n            }\n            \n            ok = (r <= th);\n        }\n        \n        cout << (ok ? \"1\" : \"0\") << \"\\n\" << flush;\n        if (ok) {\n            uf.unite(u, v);\n            cnt++;\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Pos {\n    int x, y;\n    bool operator<(const Pos& o) const {\n        if (x != o.x) return x < o.x;\n        return y < o.y;\n    }\n};\n\nint N, M;\nvector<Pos> pets, humans;\nvector<int> pet_types;\nbool grid[32][32];\nset<Pos> pet_set;\n\nvoid init() {\n    cin >> N;\n    pets.resize(N);\n    pet_types.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pet_types[i];\n        pet_set.insert(pets[i]);\n    }\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n    \n    for (int i = 0; i <= 31; i++)\n        for (int j = 0; j <= 31; j++)\n            grid[i][j] = (i >= 1 && i <= 30 && j >= 1 && j <= 30);\n}\n\nbool is_adjacent_to_pet(int x, int y) {\n    return pet_set.count({x-1, y}) || pet_set.count({x+1, y}) ||\n           pet_set.count({x, y-1}) || pet_set.count({x, y+1});\n}\n\nbool in_bounds(int x, int y) {\n    return x >= 1 && x <= 30 && y >= 1 && y <= 30;\n}\n\nbool can_build_wall(int x, int y, const set<Pos>& human_set) {\n    if (!in_bounds(x, y)) return false;\n    if (!grid[x][y]) return false;\n    if (pet_set.count({x, y})) return false;\n    if (human_set.count({x, y})) return false;\n    if (is_adjacent_to_pet(x, y)) return false;\n    return true;\n}\n\nint main() {\n    init();\n    \n    // Find safe corner farthest from pets\n    int tx = 15, ty = 15;\n    double max_dist = 0;\n    for (int cx : {5, 25}) {\n        for (int cy : {5, 25}) {\n            double dist = 0;\n            for (const auto& p : pets)\n                dist += abs(p.x - cx) + abs(p.y - cy);\n            if (dist > max_dist) {\n                max_dist = dist;\n                tx = cx; ty = cy;\n            }\n        }\n    }\n    \n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n        \n        // Create a set of all current human positions at START of turn\n        set<Pos> human_set;\n        for (const auto& h : humans) {\n            human_set.insert(h);\n        }\n        \n        // Decide actions for all humans - collect walls first\n        set<Pos> walls_to_build;\n        \n        for (int i = 0; i < M; i++) {\n            int x = humans[i].x, y = humans[i].y;\n            \n            bool acted = false;\n            \n            vector<pair<int,int>> dirs = {{-1,0},{1,0},{0,-1},{0,1}};\n            string wall = \"udlr\";\n            \n            // Try to build walls around current position\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dirs[d].first;\n                int ny = y + dirs[d].second;\n                \n                if (can_build_wall(nx, ny, human_set)) {\n                    actions[i] = wall[d];\n                    walls_to_build.insert({nx, ny});\n                    acted = true;\n                    break;\n                }\n            }\n            \n            // If can't build, try to move toward target (early turns only)\n            if (!acted && turn < 30) {\n                string move = \"UDLR\";\n                \n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dirs[d].first;\n                    int ny = y + dirs[d].second;\n                    \n                    // Move closer to target\n                    int curr_dist = abs(x - tx) + abs(y - ty);\n                    int new_dist = abs(nx - tx) + abs(ny - ty);\n                    \n                    if (new_dist < curr_dist && in_bounds(nx, ny) && grid[nx][ny] && \n                        !walls_to_build.count({nx, ny})) {\n                        actions[i] = move[d];\n                        acted = true;\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // Apply all walls atomically\n        for (const auto& w : walls_to_build) {\n            grid[w.x][w.y] = false;\n        }\n        \n        // Apply all moves atomically\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'U') humans[i].x--;\n            else if (a == 'D') humans[i].x++;\n            else if (a == 'L') humans[i].y--;\n            else if (a == 'R') humans[i].y++;\n        }\n        \n        cout << actions << endl;\n        cout.flush();\n        \n        // Read and update pet positions\n        pet_set.clear();\n        for (int i = 0; i < N; i++) {\n            string mov;\n            cin >> mov;\n            for (char c : mov) {\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n            pet_set.insert(pets[i]);\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    if (si == ti && sj == tj) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    // BFS to find shortest path\n    queue<tuple<int,int,string>> q;\n    vector<vector<bool>> visited(20, vector<bool>(20, false));\n    q.push({si, sj, \"\"});\n    visited[si][sj] = true;\n    \n    string path = \"\";\n    while (!q.empty()) {\n        auto [i, j, cur_path] = q.front();\n        q.pop();\n        \n        if (i == ti && j == tj) {\n            path = cur_path;\n            break;\n        }\n        \n        // Try all 4 directions in consistent order\n        if (i < 19 && v[i][j] == '0' && !visited[i+1][j]) {\n            visited[i+1][j] = true;\n            q.push({i+1, j, cur_path + \"D\"});\n        }\n        if (j < 19 && h[i][j] == '0' && !visited[i][j+1]) {\n            visited[i][j+1] = true;\n            q.push({i, j+1, cur_path + \"R\"});\n        }\n        if (i > 0 && v[i-1][j] == '0' && !visited[i-1][j]) {\n            visited[i-1][j] = true;\n            q.push({i-1, j, cur_path + \"U\"});\n        }\n        if (j > 0 && h[i][j-1] == '0' && !visited[i][j-1]) {\n            visited[i][j-1] = true;\n            q.push({i, j-1, cur_path + \"L\"});\n        }\n    }\n    \n    if (path.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    // Simply repeat the shortest path to maximize robustness\n    // Use the full 200 character budget\n    string result = \"\";\n    while (result.length() + path.length() <= 200) {\n        result += path;\n    }\n    \n    // Fill remaining space with partial path\n    int remaining = 200 - result.length();\n    if (remaining > 0 && remaining < path.length()) {\n        result += path.substr(0, remaining);\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nint di[4] = {0, -1, 0, 1};\nint dj[4] = {-1, 0, 1, 0};\n\nint to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\nint rotateTile(int tile, int rot) {\n    rot = rot % 4;\n    for (int i = 0; i < rot; i++) {\n        if (tile <= 3) {\n            tile = (tile + 1) % 4;\n        } else if (tile <= 5) {\n            tile = (tile == 4) ? 5 : 4;\n        } else {\n            tile = (tile == 6) ? 7 : 6;\n        }\n    }\n    return tile;\n}\n\nint getLoopLength(int si, int sj, int sd, const vector<vector<int>>& current) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    while (length <= 2000) {\n        int tile = current[i][j];\n        int d2 = to[tile][d];\n        if (d2 == -1) return 0;\n        \n        i += di[d2];\n        j += dj[d2];\n        if (i < 0 || i >= N || j < 0 || j >= N) return 0;\n        \n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (i == si && j == sj && d == sd) return length;\n    }\n    return 0;\n}\n\nlong long calculateScore(const vector<vector<int>>& current) {\n    vector<int> loops;\n    vector<vector<vector<bool>>> visited(N, vector<vector<bool>>(N, vector<bool>(4, false)));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (visited[i][j][d]) continue;\n                \n                int len = getLoopLength(i, j, d, current);\n                if (len > 0) {\n                    loops.push_back(len);\n                    \n                    int ii = i, jj = j, dd = d;\n                    for (int step = 0; step < len; step++) {\n                        visited[ii][jj][dd] = true;\n                        int tile = current[ii][jj];\n                        int d2 = to[tile][dd];\n                        ii += di[d2];\n                        jj += dj[d2];\n                        dd = (d2 + 2) % 4;\n                    }\n                }\n            }\n        }\n    }\n    \n    sort(loops.rbegin(), loops.rend());\n    \n    if (loops.size() < 2) return 0;\n    return (long long)loops[0] * loops[1];\n}\n\nint main() {\n    auto start = chrono::steady_clock::now();\n    \n    vector<string> tiles(N);\n    for (int i = 0; i < N; i++) {\n        cin >> tiles[i];\n    }\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n    \n    vector<vector<int>> rotation(N, vector<int>(N));\n    vector<vector<int>> current(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            rotation[i][j] = gen() % 4;\n            int tile = tiles[i][j] - '0';\n            current[i][j] = rotateTile(tile, rotation[i][j]);\n        }\n    }\n    \n    long long currentScore = calculateScore(current);\n    long long bestScore = currentScore;\n    vector<vector<int>> bestRotation = rotation;\n    \n    double temp = 100.0;\n    double coolingRate = 0.99995;\n    \n    while (true) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.8) break;\n        \n        int i = gen() % N;\n        int j = gen() % N;\n        int oldRot = rotation[i][j];\n        int newRot = gen() % 4;\n        \n        if (oldRot == newRot) continue;\n        \n        rotation[i][j] = newRot;\n        int tile = tiles[i][j] - '0';\n        current[i][j] = rotateTile(tile, newRot);\n        \n        long long score = calculateScore(current);\n        long long delta = score - currentScore;\n        \n        if (delta > 0 || dis(gen) < exp(delta / temp)) {\n            currentScore = score;\n            if (score > bestScore) {\n                bestScore = score;\n                bestRotation = rotation;\n            }\n        } else {\n            rotation[i][j] = oldRot;\n            current[i][j] = rotateTile(tile, oldRot);\n        }\n        \n        temp *= coolingRate;\n    }\n    \n    string output;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            output += ('0' + bestRotation[i][j]);\n        }\n    }\n    cout << output << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> board;\nint empty_i, empty_j;\n\nvoid find_empty() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == '0') {\n                empty_i = i;\n                empty_j = j;\n                return;\n            }\n        }\n    }\n}\n\nint get_tile(int i, int j) {\n    if (i < 0 || i >= N || j < 0 || j >= N) return -1;\n    char c = board[i][j];\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\nint calculate_tree_size() {\n    vector<int> parent(N * N);\n    iota(parent.begin(), parent.end(), 0);\n    \n    function<int(int)> find = [&](int x) {\n        return parent[x] == x ? x : parent[x] = find(parent[x]);\n    };\n    \n    auto unite = [&](int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x != y) parent[x] = y;\n    };\n    \n    // Check vertical connections\n    for (int i = 0; i < N - 1; i++) {\n        for (int j = 0; j < N; j++) {\n            int t1 = get_tile(i, j);\n            int t2 = get_tile(i + 1, j);\n            if (t1 > 0 && t2 > 0 && (t1 & 8) && (t2 & 2)) {\n                unite(i * N + j, (i + 1) * N + j);\n            }\n        }\n    }\n    \n    // Check horizontal connections\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N - 1; j++) {\n            int t1 = get_tile(i, j);\n            int t2 = get_tile(i, j + 1);\n            if (t1 > 0 && t2 > 0 && (t1 & 4) && (t2 & 1)) {\n                unite(i * N + j, i * N + j + 1);\n            }\n        }\n    }\n    \n    // Count components and detect cycles\n    map<int, vector<int>> components;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (get_tile(i, j) > 0) {\n                components[find(i * N + j)].push_back(i * N + j);\n            }\n        }\n    }\n    \n    int max_tree_size = 0;\n    for (auto& [root, nodes] : components) {\n        int edges = 0;\n        for (int node : nodes) {\n            int i = node / N, j = node % N;\n            int t = get_tile(i, j);\n            if (i + 1 < N) {\n                int t2 = get_tile(i + 1, j);\n                if (t2 > 0 && (t & 8) && (t2 & 2) && find((i+1)*N+j) == root) {\n                    edges++;\n                }\n            }\n            if (j + 1 < N) {\n                int t2 = get_tile(i, j + 1);\n                if (t2 > 0 && (t & 4) && (t2 & 1) && find(i*N+j+1) == root) {\n                    edges++;\n                }\n            }\n        }\n        \n        if (edges == (int)nodes.size() - 1) {\n            max_tree_size = max(max_tree_size, (int)nodes.size());\n        }\n    }\n    \n    return max_tree_size;\n}\n\nbool can_move(char dir) {\n    if (dir == 'U') return empty_i > 0;\n    if (dir == 'D') return empty_i < N - 1;\n    if (dir == 'L') return empty_j > 0;\n    if (dir == 'R') return empty_j < N - 1;\n    return false;\n}\n\nvoid make_move(char dir) {\n    int ni = empty_i, nj = empty_j;\n    if (dir == 'U') ni--;\n    else if (dir == 'D') ni++;\n    else if (dir == 'L') nj--;\n    else if (dir == 'R') nj++;\n    \n    swap(board[empty_i][empty_j], board[ni][nj]);\n    empty_i = ni;\n    empty_j = nj;\n}\n\nint main() {\n    cin >> N >> T;\n    board.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    find_empty();\n    \n    string moves = \"\";\n    int current_score = calculate_tree_size();\n    \n    string dirs = \"UDLR\";\n    char last_move = ' ';\n    \n    mt19937 rng(42);\n    \n    for (int iter = 0; iter < T * 2; iter++) {\n        if (moves.length() >= T) break;\n        if (current_score == N * N - 1) break;\n        \n        vector<pair<int, char>> candidates;\n        \n        for (char dir : dirs) {\n            if (last_move == 'U' && dir == 'D') continue;\n            if (last_move == 'D' && dir == 'U') continue;\n            if (last_move == 'L' && dir == 'R') continue;\n            if (last_move == 'R' && dir == 'L') continue;\n            \n            if (!can_move(dir)) continue;\n            \n            auto old_board = board;\n            int old_i = empty_i, old_j = empty_j;\n            make_move(dir);\n            int new_score = calculate_tree_size();\n            \n            candidates.push_back({new_score, dir});\n            \n            board = old_board;\n            empty_i = old_i;\n            empty_j = old_j;\n        }\n        \n        if (candidates.empty()) break;\n        \n        sort(candidates.rbegin(), candidates.rend());\n        \n        char best_dir = candidates[0].second;\n        int best_score = candidates[0].first;\n        \n        if (best_score >= current_score || (best_score >= current_score - 2 && rng() % 100 < 10)) {\n            make_move(best_dir);\n            moves += best_dir;\n            current_score = best_score;\n            last_move = best_dir;\n        } else {\n            break;\n        }\n    }\n    \n    cout << moves << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, K;\n    cin >> N >> K;\n    \n    vector<int> a(11);\n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    \n    vector<pair<int, int>> points(N);\n    for (int i = 0; i < N; i++) {\n        cin >> points[i].first >> points[i].second;\n    }\n    \n    // Sort strawberries by angle around origin\n    sort(points.begin(), points.end(), [](const auto& p1, const auto& p2) {\n        return atan2(p1.second, p1.first) < atan2(p2.second, p2.first);\n    });\n    \n    // Create priority list: (demand count, size)\n    vector<pair<int, int>> priority;\n    for (int d = 1; d <= 10; d++) {\n        if (a[d] > 0) {\n            priority.push_back({a[d], d});\n        }\n    }\n    sort(priority.rbegin(), priority.rend()); // Highest demand first\n    \n    // Greedy partitioning\n    vector<int> remaining_demand = a;\n    vector<int> partition;\n    int pos = 0;\n    \n    while (pos < N) {\n        int chosen_size = N - pos; // Default: use all remaining\n        \n        // Try to find a size with remaining demand that fits\n        for (auto [demand, size] : priority) {\n            if (remaining_demand[size] > 0 && pos + size <= N) {\n                chosen_size = size;\n                break;\n            }\n        }\n        \n        // If no good match, try any size that has demand\n        if (chosen_size > 10 || remaining_demand[chosen_size] == 0) {\n            for (int d = 10; d >= 1; d--) {\n                if (remaining_demand[d] > 0 && pos + d <= N) {\n                    chosen_size = d;\n                    break;\n                }\n            }\n        }\n        \n        // Ensure we don't exceed available strawberries\n        chosen_size = min(chosen_size, N - pos);\n        \n        partition.push_back(chosen_size);\n        if (chosen_size <= 10 && remaining_demand[chosen_size] > 0) {\n            remaining_demand[chosen_size]--;\n        }\n        pos += chosen_size;\n    }\n    \n    // Generate radial cuts between partition boundaries\n    vector<array<long long, 4>> cuts;\n    int cumulative = 0;\n    \n    for (int size : partition) {\n        cumulative += size;\n        \n        if (cumulative < N && cuts.size() < K) {\n            auto [x1, y1] = points[cumulative - 1];\n            auto [x2, y2] = points[cumulative];\n            \n            double a1 = atan2(y1, x1);\n            double a2 = atan2(y2, x2);\n            double mid = (a1 + a2) / 2.0;\n            \n            // Handle angle wrap-around (when crossing from +\u03c0 to -\u03c0)\n            if (a2 - a1 < -M_PI) {\n                mid += M_PI;\n            } else if (a2 - a1 > M_PI) {\n                mid -= M_PI;\n            }\n            \n            // Create line from origin through the midpoint angle\n            long long qx = llround(1e9 * cos(mid));\n            long long qy = llround(1e9 * sin(mid));\n            \n            cuts.push_back({0, 0, qx, qy});\n        }\n    }\n    \n    // Output\n    cout << cuts.size() << '\\n';\n    for (auto [px, py, qx, qy] : cuts) {\n        cout << px << ' ' << py << ' ' << qx << ' ' << qy << '\\n';\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\nint N, M;\nset<pair<int,int>> dots;\nvector<vector<int>> operations;\nset<vector<int>> usedEdges;\n\n// Check if 4 points form a rectangle and return ordered points\nbool checkAndOrderRect(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, \n                       vector<int>& ordered) {\n    vector<pair<int,int>> pts = {{x1,y1}, {x2,y2}, {x3,y3}, {x4,y4}};\n    \n    // Calculate all pairwise squared distances\n    vector<long long> dists;\n    for (int i = 0; i < 4; i++) {\n        for (int j = i + 1; j < 4; j++) {\n            long long dx = pts[i].first - pts[j].first;\n            long long dy = pts[i].second - pts[j].second;\n            dists.push_back(dx * dx + dy * dy);\n        }\n    }\n    sort(dists.begin(), dists.end());\n    \n    // Rectangle: 4 equal sides, 2 equal diagonals\n    if (!(dists[0] == dists[1] && dists[1] == dists[2] && dists[2] == dists[3] &&\n          dists[4] == dists[5] && dists[3] > 0 && dists[3] < dists[4])) {\n        return false;\n    }\n    \n    // Find ordering: start with pt 0, find neighbors\n    vector<vector<int>> adj(4);\n    for (int i = 0; i < 4; i++) {\n        for (int j = i + 1; j < 4; j++) {\n            long long dx = pts[i].first - pts[j].first;\n            long long dy = pts[i].second - pts[j].second;\n            long long d = dx * dx + dy * dy;\n            if (d == dists[0]) { // side length\n                adj[i].push_back(j);\n                adj[j].push_back(i);\n            }\n        }\n    }\n    \n    // Order: 0 -> neighbor1 -> opposite corner -> neighbor2 -> back to 0\n    vector<int> order = {0};\n    order.push_back(adj[0][0]);\n    int next = (adj[order[1]][0] == 0) ? adj[order[1]][1] : adj[order[1]][0];\n    order.push_back(next);\n    next = (adj[order[2]][0] == order[1]) ? adj[order[2]][1] : adj[order[2]][0];\n    order.push_back(next);\n    \n    ordered = {pts[order[0]].first, pts[order[0]].second,\n               pts[order[1]].first, pts[order[1]].second,\n               pts[order[2]].first, pts[order[2]].second,\n               pts[order[3]].first, pts[order[3]].second};\n    return true;\n}\n\nbool hasIntermediateDots(int x1, int y1, int x2, int y2) {\n    int dx = x2 - x1;\n    int dy = y2 - y1;\n    int g = __gcd(abs(dx), abs(dy));\n    if (g <= 1) return false;\n    \n    dx /= g;\n    dy /= g;\n    \n    for (int i = 1; i < g; i++) {\n        int x = x1 + dx * i;\n        int y = y1 + dy * i;\n        if (dots.count({x, y})) return true;\n    }\n    return false;\n}\n\nbool tryAddDot(int x1, int y1) {\n    if (dots.count({x1, y1})) return false;\n    if (x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) return false;\n    \n    vector<pair<int,int>> dotVec(dots.begin(), dots.end());\n    int n = dotVec.size();\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = i + 1; j < n; j++) {\n            for (int k = j + 1; k < n; k++) {\n                int x2 = dotVec[i].first, y2 = dotVec[i].second;\n                int x3 = dotVec[j].first, y3 = dotVec[j].second;\n                int x4 = dotVec[k].first, y4 = dotVec[k].second;\n                \n                vector<int> ordered;\n                if (!checkAndOrderRect(x1, y1, x2, y2, x3, y3, x4, y4, ordered)) {\n                    continue;\n                }\n                \n                // Check perimeter for intermediate dots\n                bool valid = true;\n                for (int e = 0; e < 4; e++) {\n                    int ex1 = ordered[e*2], ey1 = ordered[e*2+1];\n                    int ex2 = ordered[(e*2+2)%8], ey2 = ordered[(e*2+3)%8];\n                    if (hasIntermediateDots(ex1, ey1, ex2, ey2)) {\n                        valid = false;\n                        break;\n                    }\n                }\n                \n                if (!valid) continue;\n                \n                // Check edge overlap (simplified)\n                vector<int> edgeKey;\n                for (int e = 0; e < 4; e++) {\n                    vector<int> edge = {ordered[e*2], ordered[e*2+1], \n                                       ordered[(e*2+2)%8], ordered[(e*2+3)%8]};\n                    if (edge[0] > edge[2] || (edge[0] == edge[2] && edge[1] > edge[3])) {\n                        swap(edge[0], edge[2]);\n                        swap(edge[1], edge[3]);\n                    }\n                    if (usedEdges.count(edge)) {\n                        valid = false;\n                        break;\n                    }\n                }\n                \n                if (!valid) continue;\n                \n                // Add the dot\n                dots.insert({x1, y1});\n                operations.push_back(ordered);\n                \n                // Mark edges as used\n                for (int e = 0; e < 4; e++) {\n                    vector<int> edge = {ordered[e*2], ordered[e*2+1], \n                                       ordered[(e*2+2)%8], ordered[(e*2+3)%8]};\n                    if (edge[0] > edge[2] || (edge[0] == edge[2] && edge[1] > edge[3])) {\n                        swap(edge[0], edge[2]);\n                        swap(edge[1], edge[3]);\n                    }\n                    usedEdges.insert(edge);\n                }\n                \n                return true;\n            }\n        }\n    }\n    \n    return false;\n}\n\nint main() {\n    cin >> N >> M;\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        dots.insert({x, y});\n    }\n    \n    auto start = chrono::steady_clock::now();\n    \n    // Iteratively try to add dots\n    for (int iter = 0; iter < 10000; iter++) {\n        auto now = chrono::steady_clock::now();\n        if (chrono::duration<double>(now - start).count() > 4.5) break;\n        \n        bool added = false;\n        for (int x = 0; x < N && !added; x++) {\n            for (int y = 0; y < N && !added; y++) {\n                if (tryAddDot(x, y)) {\n                    added = true;\n                }\n            }\n        }\n        \n        if (!added) break;\n    }\n    \n    cout << operations.size() << endl;\n    for (auto& op : operations) {\n        for (int i = 0; i < 8; i++) {\n            if (i > 0) cout << \" \";\n            cout << op[i];\n        }\n        cout << endl;\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nint board[N][N];\nint flavors[100];\n\nvoid tilt(int b[N][N], char dir) {\n    if (dir == 'F') {\n        for (int j = 0; j < N; j++) {\n            int pos = 0;\n            for (int i = 0; i < N; i++) {\n                if (b[i][j] > 0) {\n                    if (i != pos) {\n                        b[pos][j] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos++;\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < N; j++) {\n            int pos = N - 1;\n            for (int i = N - 1; i >= 0; i--) {\n                if (b[i][j] > 0) {\n                    if (i != pos) {\n                        b[pos][j] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos--;\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < N; i++) {\n            int pos = 0;\n            for (int j = 0; j < N; j++) {\n                if (b[i][j] > 0) {\n                    if (j != pos) {\n                        b[i][pos] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos++;\n                }\n            }\n        }\n    } else {\n        for (int i = 0; i < N; i++) {\n            int pos = N - 1;\n            for (int j = N - 1; j >= 0; j--) {\n                if (b[i][j] > 0) {\n                    if (j != pos) {\n                        b[i][pos] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos--;\n                }\n            }\n        }\n    }\n}\n\ndouble calcEvaluation(int b[N][N], int turn) {\n    bool vis[N][N] = {};\n    double score = 0;\n    \n    // Connectivity score (main objective)\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] > 0 && !vis[i][j]) {\n                int flavor = b[i][j];\n                int size = 0;\n                queue<pair<int,int>> q;\n                q.push({i, j});\n                vis[i][j] = true;\n                \n                while (!q.empty()) {\n                    auto [ci, cj] = q.front();\n                    q.pop();\n                    size++;\n                    \n                    int di[] = {-1, 1, 0, 0};\n                    int dj[] = {0, 0, -1, 1};\n                    for (int d = 0; d < 4; d++) {\n                        int ni = ci + di[d];\n                        int nj = cj + dj[d];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N &&\n                            !vis[ni][nj] && b[ni][nj] == flavor) {\n                            vis[ni][nj] = true;\n                            q.push({ni, nj});\n                        }\n                    }\n                }\n                \n                score += size * size;\n            }\n        }\n    }\n    \n    // Compactness bonus - reward keeping same flavors close together\n    double compactWeight = max(0.0, (50.0 - turn) / 50.0) * 2.0; // More important early game\n    \n    for (int f = 1; f <= 3; f++) {\n        vector<pair<int,int>> positions;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (b[i][j] == f) {\n                    positions.push_back({i, j});\n                }\n            }\n        }\n        \n        if (positions.size() > 1) {\n            // Calculate center of mass\n            double sumI = 0, sumJ = 0;\n            for (auto [i, j] : positions) {\n                sumI += i;\n                sumJ += j;\n            }\n            double avgI = sumI / positions.size();\n            double avgJ = sumJ / positions.size();\n            \n            // Calculate average distance from center\n            double totalDist = 0;\n            for (auto [i, j] : positions) {\n                totalDist += abs(i - avgI) + abs(j - avgJ);\n            }\n            \n            // Penalize spread (lower distance is better)\n            score -= totalDist * compactWeight;\n        }\n    }\n    \n    // Adjacent same-flavor bonus\n    int adjacentCount = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] > 0) {\n                if (i + 1 < N && b[i+1][j] == b[i][j]) adjacentCount++;\n                if (j + 1 < N && b[i][j+1] == b[i][j]) adjacentCount++;\n            }\n        }\n    }\n    score += adjacentCount * 5.0;\n    \n    return score;\n}\n\nchar chooseBest(int turn) {\n    char dirs[] = {'F', 'B', 'L', 'R'};\n    double best = -1e9;\n    char bestDir = 'F';\n    \n    for (char dir : dirs) {\n        int temp[N][N];\n        memcpy(temp, board, sizeof(board));\n        tilt(temp, dir);\n        double score = calcEvaluation(temp, turn);\n        \n        if (score > best) {\n            best = score;\n            bestDir = dir;\n        }\n    }\n    \n    return bestDir;\n}\n\nint main() {\n    for (int i = 0; i < 100; i++) {\n        cin >> flavors[i];\n    }\n    \n    memset(board, 0, sizeof(board));\n    \n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n        p--;\n        \n        int cnt = 0;\n        bool placed = false;\n        for (int i = 0; i < N && !placed; i++) {\n            for (int j = 0; j < N && !placed; j++) {\n                if (board[i][j] == 0) {\n                    if (cnt == p) {\n                        board[i][j] = flavors[t];\n                        placed = true;\n                    }\n                    cnt++;\n                }\n            }\n        }\n        \n        char dir = chooseBest(t);\n        cout << dir << endl;\n        cout.flush();\n        \n        tilt(board, dir);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint M;\ndouble eps;\nint N;\n\nclass Graph {\npublic:\n    int n;\n    vector<vector<int>> adj;\n    \n    Graph(int n = 0) : n(n), adj(n, vector<int>(n, 0)) {}\n    \n    string to_string() const {\n        string s;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                s += (adj[i][j] ? '1' : '0');\n            }\n        }\n        return s;\n    }\n    \n    void from_string(const string& s) {\n        int idx = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                adj[i][j] = adj[j][i] = (s[idx++] == '1');\n            }\n        }\n    }\n    \n    vector<int> get_features() const {\n        vector<int> features;\n        \n        // Edge count\n        int edges = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                edges += adj[i][j];\n            }\n        }\n        features.push_back(edges);\n        \n        // Sorted degree sequence\n        vector<int> degrees(n, 0);\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                degrees[i] += adj[i][j];\n            }\n        }\n        sort(degrees.begin(), degrees.end());\n        for (int d : degrees) features.push_back(d);\n        \n        // Triangle count\n        int triangles = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                if (!adj[i][j]) continue;\n                for (int k = j + 1; k < n; k++) {\n                    if (adj[i][k] && adj[j][k]) triangles++;\n                }\n            }\n        }\n        features.push_back(triangles);\n        \n        return features;\n    }\n};\n\nvector<Graph> graphs;\nvector<vector<int>> graph_features;\n\nint compute_distance(const vector<int>& f1, const vector<int>& f2) {\n    int dist = 0;\n    // Edge count difference (heavily weighted)\n    dist += abs(f1[0] - f2[0]) * 10;\n    \n    // Degree sequence differences\n    int n = min(f1.size(), f2.size()) - 1;\n    for (int i = 1; i < (int)n; i++) {\n        dist += abs(f1[i] - f2[i]);\n    }\n    \n    // Triangle count difference\n    dist += abs(f1.back() - f2.back()) * 5;\n    \n    return dist;\n}\n\nvoid generate_graphs() {\n    // Adaptive N selection\n    if (eps <= 0.05) {\n        N = 10;\n    } else if (eps <= 0.15) {\n        N = 15;\n    } else if (eps <= 0.25) {\n        N = 20;\n    } else if (eps <= 0.35) {\n        N = 30;\n    } else {\n        N = 40;\n    }\n    \n    // Ensure we have enough space to distinguish M graphs\n    N = max(N, (int)ceil(sqrt(2.0 * M)) + 4);\n    N = min(N, 100);\n    \n    graphs.resize(M, Graph(N));\n    \n    int max_edges = N * (N - 1) / 2;\n    \n    for (int k = 0; k < M; k++) {\n        // Linearly space edge counts\n        int target_edges = (k * max_edges) / M;\n        \n        // Add edges sequentially to create distinct patterns\n        int added = 0;\n        for (int i = 0; i < N && added < target_edges; i++) {\n            for (int j = i + 1; j < N && added < target_edges; j++) {\n                graphs[k].adj[i][j] = graphs[k].adj[j][i] = 1;\n                added++;\n            }\n        }\n    }\n    \n    // Precompute features\n    graph_features.resize(M);\n    for (int k = 0; k < M; k++) {\n        graph_features[k] = graphs[k].get_features();\n    }\n}\n\nint decode_graph(const Graph& h) {\n    auto h_features = h.get_features();\n    \n    int best = 0;\n    int min_dist = INT_MAX;\n    \n    for (int k = 0; k < M; k++) {\n        int dist = compute_distance(h_features, graph_features[k]);\n        if (dist < min_dist) {\n            min_dist = dist;\n            best = k;\n        }\n    }\n    \n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> M >> eps;\n    \n    generate_graphs();\n    \n    cout << N << \"\\n\";\n    for (const auto& g : graphs) {\n        cout << g.to_string() << \"\\n\";\n    }\n    cout.flush();\n    \n    for (int q = 0; q < 100; q++) {\n        string s;\n        cin >> s;\n        \n        Graph h(N);\n        h.from_string(s);\n        \n        int t = decode_graph(h);\n        cout << t << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long INF = 1e9;\n\nint N, M, D, K;\nvector<array<int, 3>> edges;\nvector<vector<pair<int, int>>> graph; // (neighbor, edge_id)\nvector<int> degree;\n\n// Dijkstra with edge tracking\npair<vector<long long>, vector<int>> dijkstra_track(int src) {\n    vector<long long> dist(N, INF);\n    vector<int> edge_count(M, 0);\n    priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n    \n    dist[src] = 0;\n    pq.push({0, src});\n    \n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        \n        if (d > dist[u]) continue;\n        \n        for (auto [v, eid] : graph[u]) {\n            long long w = edges[eid][2];\n            if (dist[u] + w < dist[v]) {\n                dist[v] = dist[u] + w;\n                pq.push({dist[v], v});\n            }\n        }\n    }\n    \n    // Count edges on shortest paths\n    for (int u = 0; u < N; u++) {\n        if (dist[u] >= INF) continue;\n        for (auto [v, eid] : graph[u]) {\n            long long w = edges[eid][2];\n            if (dist[u] + w == dist[v]) {\n                edge_count[eid]++;\n            }\n        }\n    }\n    \n    return {dist, edge_count};\n}\n\nint main() {\n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    graph.resize(N);\n    degree.resize(N);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i][0] >> edges[i][1] >> edges[i][2];\n        edges[i][0]--; edges[i][1]--;\n        \n        graph[edges[i][0]].push_back({edges[i][1], i});\n        graph[edges[i][1]].push_back({edges[i][0], i});\n        \n        degree[edges[i][0]]++;\n        degree[edges[i][1]]++;\n    }\n    \n    // Skip coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Count edge usage in shortest paths (betweenness)\n    vector<long long> edge_usage(M, 0);\n    \n    // Sample sources to estimate betweenness\n    int sample_size = min(N, 150);\n    for (int iter = 0; iter < sample_size; iter++) {\n        int src = (iter * N) / sample_size;\n        auto [dist, edge_count] = dijkstra_track(src);\n        \n        for (int i = 0; i < M; i++) {\n            edge_usage[i] += edge_count[i];\n        }\n    }\n    \n    // Calculate composite importance score\n    vector<pair<double, int>> edge_scores;\n    for (int i = 0; i < M; i++) {\n        int u = edges[i][0];\n        int v = edges[i][1];\n        \n        // Higher usage = more critical\n        double usage_score = (double)edge_usage[i];\n        \n        // Low degree = potential bottleneck\n        double degree_score = 1000.0 / (degree[u] * degree[v]);\n        \n        // High weight = longer detour if removed\n        double weight_score = (double)edges[i][2] / 10000.0;\n        \n        double score = usage_score * 100 + degree_score * 50 + weight_score * 10;\n        edge_scores.push_back({score, i});\n    }\n    \n    // Sort by importance (descending)\n    sort(edge_scores.begin(), edge_scores.end(), greater<>());\n    \n    // Greedy assignment: distribute important edges across days\n    vector<int> assignment(M);\n    vector<int> day_count(D + 1, 0);\n    \n    for (auto [score, edge_id] : edge_scores) {\n        // Find day with minimum assignments (balance load)\n        int best_day = 1;\n        for (int d = 1; d <= D; d++) {\n            if (day_count[d] < day_count[best_day]) {\n                best_day = d;\n            }\n        }\n        \n        assignment[edge_id] = best_day;\n        day_count[best_day]++;\n    }\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i];\n        if (i < M - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f1, r1, f2, r2;\n\nbool isOccupied(int x, int y, int z, const vector<string>& f, const vector<string>& r) {\n    return f[z][x] == '1' && r[z][y] == '1';\n}\n\nset<tuple<int,int,int>> getComponent(tuple<int,int,int> start, \n                                      set<tuple<int,int,int>>& available) {\n    set<tuple<int,int,int>> component;\n    queue<tuple<int,int,int>> q;\n    q.push(start);\n    available.erase(start);\n    component.insert(start);\n    \n    int dx[] = {1, -1, 0, 0, 0, 0};\n    int dy[] = {0, 0, 1, -1, 0, 0};\n    int dz[] = {0, 0, 0, 0, 1, -1};\n    \n    while (!q.empty()) {\n        auto [x, y, z] = q.front();\n        q.pop();\n        \n        for (int i = 0; i < 6; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            int nz = z + dz[i];\n            auto next = make_tuple(nx, ny, nz);\n            \n            if (available.count(next)) {\n                available.erase(next);\n                component.insert(next);\n                q.push(next);\n            }\n        }\n    }\n    \n    return component;\n}\n\nint main() {\n    cin >> D;\n    f1.resize(D); r1.resize(D); f2.resize(D); r2.resize(D);\n    \n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n    \n    // Get occupied cells for both configurations\n    set<tuple<int,int,int>> occ1, occ2;\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 (isOccupied(x, y, z, f1, r1)) occ1.insert({x, y, z});\n                if (isOccupied(x, y, z, f2, r2)) occ2.insert({x, y, z});\n            }\n        }\n    }\n    \n    // Find common positions (occupied in both configs)\n    set<tuple<int,int,int>> common;\n    for (auto pos : occ1) {\n        if (occ2.count(pos)) {\n            common.insert(pos);\n        }\n    }\n    \n    // Create shared blocks from common positions\n    vector<set<tuple<int,int,int>>> sharedBlocks;\n    auto availableCommon = common;\n    while (!availableCommon.empty()) {\n        auto start = *availableCommon.begin();\n        sharedBlocks.push_back(getComponent(start, availableCommon));\n    }\n    \n    // Create unique blocks for config 1\n    set<tuple<int,int,int>> unique1;\n    for (auto pos : occ1) {\n        if (!common.count(pos)) unique1.insert(pos);\n    }\n    \n    vector<set<tuple<int,int,int>>> blocks1;\n    auto available1 = unique1;\n    while (!available1.empty()) {\n        auto start = *available1.begin();\n        blocks1.push_back(getComponent(start, available1));\n    }\n    \n    // Create unique blocks for config 2\n    set<tuple<int,int,int>> unique2;\n    for (auto pos : occ2) {\n        if (!common.count(pos)) unique2.insert(pos);\n    }\n    \n    vector<set<tuple<int,int,int>>> blocks2;\n    auto available2 = unique2;\n    while (!available2.empty()) {\n        auto start = *available2.begin();\n        blocks2.push_back(getComponent(start, available2));\n    }\n    \n    // Assign block IDs\n    vector<vector<vector<int>>> b1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> b2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    \n    int nextId = 1;\n    \n    // Assign shared blocks (used in both configurations)\n    for (auto& block : sharedBlocks) {\n        int id = nextId++;\n        for (auto [x, y, z] : block) {\n            b1[x][y][z] = id;\n            b2[x][y][z] = id;\n        }\n    }\n    \n    // Assign unique blocks for config 1\n    for (auto& block : blocks1) {\n        int id = nextId++;\n        for (auto [x, y, z] : block) {\n            b1[x][y][z] = id;\n        }\n    }\n    \n    // Assign unique blocks for config 2\n    for (auto& block : blocks2) {\n        int id = nextId++;\n        for (auto [x, y, z] : block) {\n            b2[x][y][z] = id;\n        }\n    }\n    \n    // Output\n    cout << nextId - 1 << endl;\n    \n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            for (int z = 0; z < D; z++) {\n                if (x > 0 || y > 0 || z > 0) cout << \" \";\n                cout << b1[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n    \n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            for (int z = 0; z < D; z++) {\n                if (x > 0 || y > 0 || z > 0) cout << \" \";\n                cout << b2[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<long long> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    struct Edge {\n        int u, v, id;\n        long long w;\n    };\n    \n    vector<Edge> edges(M);\n    map<pair<int,int>, int> edge_map;\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--; edges[i].v--;\n        edges[i].id = i;\n        edge_map[{min(edges[i].u, edges[i].v), max(edges[i].u, edges[i].v)}] = i;\n    }\n    \n    vector<long long> a(K), b(K);\n    for (int i = 0; i < K; i++) {\n        cin >> a[i] >> b[i];\n    }\n    \n    auto dist = [](long long x1, long long y1, long long x2, long long y2) {\n        long long dx = x1 - x2;\n        long long dy = y1 - y2;\n        return sqrt((double)(dx * dx + dy * dy));\n    };\n    \n    // Build MST\n    vector<Edge> sorted_edges = edges;\n    sort(sorted_edges.begin(), sorted_edges.end(), [](const Edge& a, const Edge& b) {\n        return a.w < b.w;\n    });\n    \n    vector<int> parent(N);\n    iota(parent.begin(), parent.end(), 0);\n    \n    function<int(int)> find = [&](int v) {\n        return parent[v] == v ? v : parent[v] = find(parent[v]);\n    };\n    \n    set<int> active_vertices;\n    active_vertices.insert(0);\n    vector<vector<pair<int, long long>>> tree_adj(N);\n    \n    for (const Edge& e : sorted_edges) {\n        int pu = find(e.u), pv = find(e.v);\n        if (pu != pv) {\n            parent[pu] = pv;\n            active_vertices.insert(e.u);\n            active_vertices.insert(e.v);\n            tree_adj[e.u].push_back({e.v, e.w});\n            tree_adj[e.v].push_back({e.u, e.w});\n        }\n    }\n    \n    // Initial assignment of residents to vertices\n    vector<int> P(N, 0);\n    vector<vector<int>> assigned_residents(N);\n    \n    for (int k = 0; k < K; k++) {\n        int best_v = 0;\n        double best_d = dist(a[k], b[k], x[0], y[0]);\n        \n        for (int i : active_vertices) {\n            double d = dist(a[k], b[k], x[i], y[i]);\n            if (d < best_d) {\n                best_d = d;\n                best_v = i;\n            }\n        }\n        \n        int required = min(5000, (int)ceil(best_d));\n        P[best_v] = max(P[best_v], required);\n        assigned_residents[best_v].push_back(k);\n    }\n    \n    // Prune expensive leaves iteratively\n    for (int iter = 0; iter < 10; iter++) {\n        bool changed = false;\n        \n        for (int v : vector<int>(active_vertices.begin(), active_vertices.end())) {\n            if (v == 0 || active_vertices.find(v) == active_vertices.end()) continue;\n            \n            // Check if leaf\n            int degree = 0;\n            int parent_v = -1;\n            long long edge_cost = 0;\n            \n            for (auto [u, w] : tree_adj[v]) {\n                if (active_vertices.find(u) != active_vertices.end()) {\n                    degree++;\n                    parent_v = u;\n                    edge_cost = w;\n                }\n            }\n            \n            if (degree != 1) continue;\n            \n            // Cost of this vertex\n            long long vertex_cost = (long long)P[v] * P[v] + edge_cost;\n            \n            // Try reassigning residents\n            long long reassign_cost = 0;\n            vector<pair<int, int>> reassignments; // (resident_k, new_vertex)\n            \n            for (int k : assigned_residents[v]) {\n                int best_alt = -1;\n                int best_power = 5001;\n                \n                for (int i : active_vertices) {\n                    if (i == v) continue;\n                    double d = dist(a[k], b[k], x[i], y[i]);\n                    int req = min(5000, (int)ceil(d));\n                    if (req < best_power) {\n                        best_power = req;\n                        best_alt = i;\n                    }\n                }\n                \n                if (best_alt == -1) goto skip_vertex;\n                \n                int old_power = P[best_alt];\n                int new_power = max(old_power, best_power);\n                reassign_cost += (long long)new_power * new_power - (long long)old_power * old_power;\n                reassignments.push_back({k, best_alt});\n            }\n            \n            if (reassign_cost < vertex_cost) {\n                // Remove vertex v\n                active_vertices.erase(v);\n                P[v] = 0;\n                \n                // Reassign residents\n                for (auto [k, new_v] : reassignments) {\n                    double d = dist(a[k], b[k], x[new_v], y[new_v]);\n                    P[new_v] = max(P[new_v], min(5000, (int)ceil(d)));\n                    assigned_residents[new_v].push_back(k);\n                }\n                assigned_residents[v].clear();\n                \n                changed = true;\n            }\n            \n            skip_vertex:;\n        }\n        \n        if (!changed) break;\n    }\n    \n    // Build final tree and output\n    vector<int> edge_on(M, 0);\n    \n    // BFS from 0 to mark edges\n    vector<bool> visited(N, false);\n    queue<int> q;\n    q.push(0);\n    visited[0] = true;\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        \n        for (auto [v, w] : tree_adj[u]) {\n            if (!visited[v] && active_vertices.find(v) != active_vertices.end()) {\n                visited[v] = true;\n                q.push(v);\n                \n                auto it = edge_map.find({min(u, v), max(u, v)});\n                if (it != edge_map.end()) {\n                    edge_on[it->second] = 1;\n                }\n            }\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << P[i];\n    }\n    cout << \"\\n\";\n    \n    for (int i = 0; i < M; i++) {\n        if (i > 0) cout << \" \";\n        cout << edge_on[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <tuple>\nusing namespace std;\n\nconst int N = 30;\nconst int MAX_OPS = 9900;\n\nvector<vector<int>> pyramid;\nvector<tuple<int,int,int,int>> operations;\n\nvoid swap_balls(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    operations.push_back({x1, y1, x2, y2});\n}\n\nint count_violations() {\n    int count = 0;\n    for (int x = 0; x < N-1; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) count++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) count++;\n        }\n    }\n    return count;\n}\n\nvoid sink(int x, int y) {\n    while (x < N-1 && operations.size() < MAX_OPS) {\n        int current = pyramid[x][y];\n        int left_child = pyramid[x+1][y];\n        int right_child = pyramid[x+1][y+1];\n        \n        if (current <= left_child && current <= right_child) {\n            break;\n        }\n        \n        if (left_child < right_child) {\n            swap_balls(x, y, x+1, y);\n            x++;\n        } else {\n            swap_balls(x, y, x+1, y+1);\n            x++;\n            y++;\n        }\n    }\n}\n\nvoid solve() {\n    // Phase 1: Initial heapify from bottom to top\n    for (int x = N-2; x >= 0 && operations.size() < MAX_OPS; x--) {\n        for (int y = 0; y <= x && operations.size() < MAX_OPS; y++) {\n            sink(x, y);\n        }\n    }\n    \n    // Phase 2: Fix remaining violations with multiple passes\n    for (int pass = 0; pass < 50 && operations.size() < MAX_OPS; pass++) {\n        if (count_violations() == 0) break;\n        \n        for (int x = 0; x < N-1 && operations.size() < MAX_OPS; x++) {\n            for (int y = 0; y <= x && operations.size() < MAX_OPS; y++) {\n                int current = pyramid[x][y];\n                int left_child = pyramid[x+1][y];\n                int right_child = pyramid[x+1][y+1];\n                \n                if (current > left_child || current > right_child) {\n                    sink(x, y);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    pyramid.resize(N);\n    for (int x = 0; x < N; x++) {\n        pyramid[x].resize(x+1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    solve();\n    \n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int D = 9;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\n\nint N;\nbool obstacle[D][D];\nint container[D][D];\nconst int entrance_x = 0;\nconst int entrance_y = 4;\nvector<vector<int>> dist_from_entrance;\n\nbool isValid(int x, int y) {\n    return x >= 0 && x < D && y >= 0 && y < D;\n}\n\nset<pair<int,int>> getReachable() {\n    set<pair<int,int>> reachable;\n    queue<pair<int,int>> q;\n    q.push({entrance_x, entrance_y});\n    reachable.insert({entrance_x, entrance_y});\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (isValid(nx, ny) && !obstacle[nx][ny] && \n                container[nx][ny] == -1 && \n                reachable.find({nx, ny}) == reachable.end()) {\n                reachable.insert({nx, ny});\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return reachable;\n}\n\nvoid calcDistances() {\n    dist_from_entrance.assign(D, vector<int>(D, -1));\n    queue<pair<int,int>> q;\n    q.push({entrance_x, entrance_y});\n    dist_from_entrance[entrance_x][entrance_y] = 0;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (isValid(nx, ny) && !obstacle[nx][ny] && dist_from_entrance[nx][ny] == -1) {\n                dist_from_entrance[nx][ny] = dist_from_entrance[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n}\n\nint main() {\n    int D_input;\n    cin >> D_input >> N;\n    \n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            obstacle[i][j] = false;\n            container[i][j] = -1;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        obstacle[x][y] = true;\n    }\n    \n    calcDistances();\n    \n    int max_dist = 0;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (dist_from_entrance[i][j] > max_dist) {\n                max_dist = dist_from_entrance[i][j];\n            }\n        }\n    }\n    \n    int total_containers = D * D - 1 - N;\n    \n    // Placement phase\n    for (int d = 0; d < total_containers; d++) {\n        int t;\n        cin >> t;\n        \n        set<pair<int,int>> reachable = getReachable();\n        \n        // Map container number to target distance\n        double ratio = (double)t / max(1, total_containers - 1);\n        int target_dist = 1 + (int)(ratio * (max_dist - 1));\n        \n        // Find reachable cell closest to target distance\n        pair<int,int> chosen = {-1, -1};\n        int min_diff = 1000000;\n        \n        for (auto [x, y] : reachable) {\n            if (container[x][y] == -1 && (x != entrance_x || y != entrance_y)) {\n                int cell_dist = dist_from_entrance[x][y];\n                int diff = abs(cell_dist - target_dist);\n                if (diff < min_diff || \n                    (diff == min_diff && chosen.first != -1 && \n                     cell_dist < dist_from_entrance[chosen.first][chosen.second])) {\n                    min_diff = diff;\n                    chosen = {x, y};\n                }\n            }\n        }\n        \n        container[chosen.first][chosen.second] = t;\n        cout << chosen.first << \" \" << chosen.second << endl;\n        cout.flush();\n    }\n    \n    // Retrieval phase: always pick smallest accessible\n    for (int i = 0; i < total_containers; i++) {\n        set<pair<int,int>> reachable = getReachable();\n        \n        int min_num = total_containers;\n        pair<int,int> min_pos = {-1, -1};\n        \n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (container[x][y] >= 0 && reachable.count({x, y})) {\n                    if (container[x][y] < min_num) {\n                        min_num = container[x][y];\n                        min_pos = {x, y};\n                    }\n                }\n            }\n        }\n        \n        cout << min_pos.first << \" \" << min_pos.second << endl;\n        container[min_pos.first][min_pos.second] = -1;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nvector<vector<int>> original;\nvector<set<int>> adj;\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\n\nvoid readInput() {\n    cin >> n >> m;\n    original.assign(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> original[i][j];\n        }\n    }\n}\n\nvoid buildAdjacency() {\n    adj.assign(m + 1, set<int>());\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c = original[i][j];\n            if (i == 0 || i == n-1 || j == 0 || j == n-1) {\n                adj[c].insert(0);\n                adj[0].insert(c);\n            }\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int nc = original[ni][nj];\n                    if (c != nc) {\n                        adj[c].insert(nc);\n                    }\n                }\n            }\n        }\n    }\n}\n\nvoid createCompactMap() {\n    vector<vector<int>> result(n, vector<int>(n, 0));\n    map<int, vector<pair<int,int>>> wardCells;\n    set<int> placed;\n    \n    // Start from center\n    int cx = n / 2, cy = n / 2;\n    result[cx][cy] = 1;\n    wardCells[1].push_back({cx, cy});\n    placed.insert(1);\n    \n    queue<int> q;\n    q.push(1);\n    \n    while (!q.empty()) {\n        int ward = q.front();\n        q.pop();\n        \n        // Place neighbors\n        for (int neighbor : adj[ward]) {\n            if (neighbor == 0 || placed.count(neighbor)) continue;\n            \n            // Try to place adjacent to current ward\n            bool found = false;\n            for (auto [wx, wy] : wardCells[ward]) {\n                for (int d = 0; d < 4 && !found; d++) {\n                    int nx = wx + dx[d];\n                    int ny = wy + dy[d];\n                    if (nx >= 0 && nx < n && ny >= 0 && ny < n && result[nx][ny] == 0) {\n                        result[nx][ny] = neighbor;\n                        wardCells[neighbor].push_back({nx, ny});\n                        placed.insert(neighbor);\n                        q.push(neighbor);\n                        found = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n}\n\nint main() {\n    readInput();\n    buildAdjacency();\n    createCompactMap();\n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint query_count = 0;\n\nchar query(vector<int> L, vector<int> R) {\n    query_count++;\n    cout << L.size() << \" \" << R.size();\n    for(int x : L) cout << \" \" << x;\n    for(int x : R) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\nvoid mergeSort(vector<int>& arr, int l, int r) {\n    if(l >= r) return;\n    \n    int mid = (l + r) / 2;\n    mergeSort(arr, l, mid);\n    mergeSort(arr, mid+1, r);\n    \n    vector<int> temp;\n    int i = l, j = mid+1;\n    while(i <= mid && j <= r) {\n        if(query_count >= Q - 2*N) {\n            temp.push_back(arr[i++]);\n            continue;\n        }\n        \n        char result = query({arr[i]}, {arr[j]});\n        if(result != '>') {\n            temp.push_back(arr[i++]);\n        } else {\n            temp.push_back(arr[j++]);\n        }\n    }\n    while(i <= mid) temp.push_back(arr[i++]);\n    while(j <= r) temp.push_back(arr[j++]);\n    \n    for(int i = 0; i < temp.size(); i++) {\n        arr[l + i] = temp[i];\n    }\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    // Sort items by weight using merge sort\n    mergeSort(items, 0, N-1);\n    \n    // Assign to groups using greedy with estimated weights\n    vector<int> assignment(N);\n    vector<long long> group_weight(D, 0);\n    \n    // Assign from heaviest to lightest to currently lightest group\n    for(int i = N-1; i >= 0; i--) {\n        int min_group = min_element(group_weight.begin(), group_weight.end()) - group_weight.begin();\n        assignment[items[i]] = min_group;\n        group_weight[min_group] += (i + 1); // Estimated weight\n    }\n    \n    // Output final assignment\n    for(int i = 0; i < N; i++) {\n        if(i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    \n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n/m);\n        for (int j = 0; j < n/m; j++) {\n            cin >> stacks[i][j];\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    \n    for (int target = 1; target <= n; target++) {\n        // Find where target box is\n        int stack_id = -1, pos = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == target) {\n                    stack_id = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (stack_id != -1) break;\n        }\n        \n        // If not at top, move boxes above it\n        if (pos < (int)stacks[stack_id].size() - 1) {\n            int move_box = stacks[stack_id][pos + 1];\n            \n            // Get all boxes we're moving\n            vector<int> moving_boxes;\n            for (int i = pos + 1; i < (int)stacks[stack_id].size(); i++) {\n                moving_boxes.push_back(stacks[stack_id][i]);\n            }\n            int max_moving = *max_element(moving_boxes.begin(), moving_boxes.end());\n            int min_moving = *min_element(moving_boxes.begin(), moving_boxes.end());\n            \n            // Find best destination stack\n            int best_stack = -1;\n            double best_score = -1e18;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == stack_id) continue;\n                \n                double score = 0;\n                if (stacks[i].empty()) {\n                    // Empty stack is best - no conflicts possible\n                    score = 1e12;\n                } else {\n                    bool is_safe = true;\n                    int conflicts = 0;\n                    \n                    // Check if destination is \"safe\" for all moving boxes\n                    // Safe means: all boxes in destination > min of moving boxes\n                    // This ensures moved boxes won't need to be moved again\n                    for (int box : stacks[i]) {\n                        if (box < min_moving) {\n                            is_safe = false;\n                            conflicts++;\n                        }\n                    }\n                    \n                    if (is_safe) {\n                        // Destination is safe - moved boxes are \"parked\" until their turn\n                        score = 1e10;\n                        // Among safe destinations, prefer smaller stacks\n                        score -= stacks[i].size() * 10000;\n                        // Prefer stacks with smaller max value (more flexibility)\n                        int max_in_dest = *max_element(stacks[i].begin(), stacks[i].end());\n                        score -= max_in_dest * 100;\n                    } else {\n                        // Not safe - moved boxes will likely be moved again\n                        // Heavy penalty based on number of conflicting boxes\n                        score = -conflicts * 1e8;\n                        // Among unsafe destinations, prefer larger top value\n                        score += stacks[i].back() * 1000;\n                        // Prefer smaller total size\n                        score -= stacks[i].size() * 100;\n                    }\n                }\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_stack = i;\n                }\n            }\n            \n            operations.push_back({move_box, best_stack + 1}); // 1-indexed\n            \n            // Update stacks\n            stacks[stack_id].resize(pos + 1);\n            \n            for (int box : moving_boxes) {\n                stacks[best_stack].push_back(box);\n            }\n        }\n        \n        // Now target is at top, carry it out\n        operations.push_back({target, 0});\n        stacks[stack_id].pop_back();\n    }\n    \n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\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;\n\nconst int di[] = {0, 1, 0, -1};\nconst int dj[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir];\n    int nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    if (dir == 0) return v[i][j] == '0';\n    else if (dir == 1) return h[i][j] == '0';\n    else if (dir == 2) return v[i][j-1] == '0';\n    else return h[i-1][j] == '0';\n}\n\nstring find_path(int si, int sj, int ti, int tj) {\n    if (si == ti && sj == tj) return \"\";\n    \n    vector<vector<int>> dist(N, vector<int>(N, -1));\n    vector<vector<int>> parent_dir(N, vector<int>(N, -1));\n    queue<pair<int, int>> q;\n    \n    q.push({si, sj});\n    dist[si][sj] = 0;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            \n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            \n            if (dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                parent_dir[ni][nj] = dir;\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    if (dist[ti][tj] == -1) return \"\";\n    \n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int dir = parent_dir[ci][cj];\n        path += dir_char[dir];\n        ci -= di[dir];\n        cj -= dj[dir];\n    }\n    \n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstring build_tour() {\n    const int MAX_LEN = 99000;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    string route;\n    \n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        \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 + di[dir];\n            int nj = j + dj[dir];\n            if (!visited[ni][nj]) {\n                neighbors.push_back({-d[ni][nj], dir});\n            }\n        }\n        \n        sort(neighbors.begin(), neighbors.end());\n        \n        for (auto [_, dir] : neighbors) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            \n            if (!visited[ni][nj]) {\n                route += dir_char[dir];\n                dfs(ni, nj);\n                route += dir_char[(dir + 2) % 4];\n            }\n        }\n    };\n    \n    dfs(0, 0);\n    \n    // Add extra visits to high-value cells\n    vector<tuple<int, int, int>> cells;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cells.push_back({d[i][j], i, j});\n        }\n    }\n    sort(cells.rbegin(), cells.rend());\n    \n    int ci = 0, cj = 0;\n    for (auto [dval, ti, tj] : cells) {\n        if (route.length() >= MAX_LEN) break;\n        \n        string path1 = find_path(ci, cj, ti, tj);\n        string path2 = find_path(ti, tj, ci, cj);\n        \n        int cost = path1.length() + path2.length();\n        if (route.length() + cost <= MAX_LEN) {\n            route += path1 + path2;\n        }\n    }\n    \n    // Return to origin\n    route += find_path(ci, cj, 0, 0);\n    \n    return route;\n}\n\nint main() {\n    cin >> N;\n    \n    h.resize(N-1);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    \n    v.resize(N);\n    for (int i = 0; i < N; i++) cin >> v[i];\n    \n    d.resize(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> d[i][j];\n        }\n    }\n    \n    cout << build_tour() << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint si, sj;\nvector<string> grid;\nvector<string> targets;\nmap<char, vector<pair<int,int>>> char_positions;\n\nint overlap(const string& s1, const string& s2) {\n    int maxLen = min((int)s1.length(), (int)s2.length());\n    for (int len = maxLen; len >= 1; len--) {\n        if (s1.substr(s1.length() - len) == s2.substr(0, len)) {\n            return len;\n        }\n    }\n    return 0;\n}\n\nbool checkComplete(const string& s, const vector<string>& targets) {\n    for (const auto& t : targets) {\n        if (s.find(t) == string::npos) return false;\n    }\n    return true;\n}\n\npair<int,int> findClosest(char c, int curI, int curJ) {\n    auto& positions = char_positions[c];\n    int bestDist = INT_MAX;\n    pair<int,int> best = positions[0];\n    \n    for (auto& pos : positions) {\n        int dist = abs(pos.first - curI) + abs(pos.second - curJ);\n        if (dist < bestDist) {\n            bestDist = dist;\n            best = pos;\n        }\n    }\n    return best;\n}\n\n// Look ahead to choose better position\npair<int,int> findBestPosition(char c, int curI, int curJ, const string& text, int pos) {\n    auto& positions = char_positions[c];\n    if (positions.size() == 1) return positions[0];\n    \n    int bestScore = INT_MAX;\n    pair<int,int> best = positions[0];\n    int lookAhead = min(3, (int)text.length() - pos - 1);\n    \n    for (auto& p : positions) {\n        int score = abs(p.first - curI) + abs(p.second - curJ);\n        \n        // Look ahead\n        int tmpI = p.first, tmpJ = p.second;\n        for (int i = 1; i <= lookAhead; i++) {\n            auto nextPos = findClosest(text[pos + i], tmpI, tmpJ);\n            score += abs(nextPos.first - tmpI) + abs(nextPos.second - tmpJ);\n            tmpI = nextPos.first;\n            tmpJ = nextPos.second;\n        }\n        \n        if (score < bestScore) {\n            bestScore = score;\n            best = p;\n        }\n    }\n    return best;\n}\n\nstring buildSuperstring(int startIdx) {\n    vector<vector<int>> ovl(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) ovl[i][j] = overlap(targets[i], targets[j]);\n        }\n    }\n    \n    vector<bool> used(M, false);\n    string result = targets[startIdx];\n    used[startIdx] = true;\n    int current = startIdx;\n    \n    for (int iter = 1; iter < M; iter++) {\n        int bestNext = -1;\n        int bestScore = -1;\n        \n        // Find best next string\n        for (int i = 0; i < M; i++) {\n            if (used[i]) continue;\n            \n            // Check if already contained\n            if (result.find(targets[i]) != string::npos) {\n                used[i] = true;\n                continue;\n            }\n            \n            // Score based on overlap\n            int score = ovl[current][i];\n            if (score > bestScore) {\n                bestScore = score;\n                bestNext = i;\n            }\n        }\n        \n        if (bestNext == -1) {\n            // Add any remaining string not yet covered\n            for (int i = 0; i < M; i++) {\n                if (!used[i] && result.find(targets[i]) == string::npos) {\n                    bestNext = i;\n                    break;\n                }\n            }\n        }\n        \n        if (bestNext == -1) break;\n        \n        int o = ovl[current][bestNext];\n        if (o > 0) {\n            result += targets[bestNext].substr(o);\n        } else {\n            result += targets[bestNext];\n        }\n        \n        used[bestNext] = true;\n        current = bestNext;\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> si >> sj;\n    \n    grid.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    targets.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i];\n    }\n    \n    // Build character position map\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            char_positions[grid[i][j]].push_back({i, j});\n        }\n    }\n    \n    // Precompute overlaps to find good starting points\n    vector<vector<int>> ovl(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) ovl[i][j] = overlap(targets[i], targets[j]);\n        }\n    }\n    \n    // Find top candidates by total outgoing overlap\n    vector<pair<int,int>> candidates;\n    for (int i = 0; i < M; i++) {\n        int total = 0;\n        for (int j = 0; j < M; j++) {\n            total += ovl[i][j];\n        }\n        candidates.push_back({total, i});\n    }\n    sort(candidates.rbegin(), candidates.rend());\n    \n    // Try top candidates\n    string bestResult;\n    int bestLen = INT_MAX;\n    \n    for (int t = 0; t < min(20, M); t++) {\n        string result = buildSuperstring(candidates[t].second);\n        if (checkComplete(result, targets) && result.length() < bestLen) {\n            bestLen = result.length();\n            bestResult = result;\n        }\n    }\n    \n    if (bestResult.empty()) {\n        bestResult = buildSuperstring(0);\n    }\n    \n    // Navigate with look-ahead\n    int curI = si, curJ = sj;\n    for (int i = 0; i < bestResult.length(); i++) {\n        auto pos = findBestPosition(bestResult[i], curI, curJ, bestResult, i);\n        cout << pos.first << \" \" << pos.second << \"\\n\";\n        curI = pos.first;\n        curJ = pos.second;\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>>> fields;\nint query_count = 0;\n\nint query(const vector<pair<int,int>>& cells) {\n    cout << \"q \" << cells.size();\n    for (auto [i, j] : cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    query_count++;\n    \n    int result;\n    cin >> result;\n    return result;\n}\n\nint drill(int i, int j) {\n    return query({{i, j}});\n}\n\nbool answer(const set<pair<int,int>>& cells) {\n    cout << \"a \" << cells.size();\n    for (auto [i, j] : cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    int result;\n    cin >> result;\n    return result == 1;\n}\n\nint main() {\n    cin >> N >> M >> eps;\n    fields.resize(M);\n    \n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        fields[k].resize(d);\n        for (int i = 0; i < d; i++) {\n            cin >> fields[k][i].first >> fields[k][i].second;\n        }\n    }\n    \n    vector<vector<double>> estimate(N, vector<double>(N, 0.0));\n    vector<vector<int>> drilled(N, vector<int>(N, -1));\n    \n    // Phase 1: Query entire grid multiple times for baseline\n    double total = 0;\n    int num_full = 30;\n    for (int q = 0; q < num_full; q++) {\n        vector<pair<int,int>> all;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                all.push_back({i, j});\n            }\n        }\n        total += query(all);\n    }\n    double avg_per_cell = total / (num_full * N * N);\n    \n    // Phase 2: Query rows and columns\n    vector<double> row_est(N), col_est(N);\n    for (int i = 0; i < N; i++) {\n        vector<pair<int,int>> row;\n        for (int j = 0; j < N; j++) row.push_back({i, j});\n        row_est[i] = query(row) / (double)N;\n    }\n    \n    for (int j = 0; j < N; j++) {\n        vector<pair<int,int>> col;\n        for (int i = 0; i < N; i++) col.push_back({i, j});\n        col_est[j] = query(col) / (double)N;\n    }\n    \n    // Combine estimates\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            estimate[i][j] = (row_est[i] + col_est[j]) / 2.0;\n        }\n    }\n    \n    // Phase 3: Query smaller blocks for refinement\n    int block_size = max(2, N/3);\n    for (int bi = 0; bi < N; bi += block_size) {\n        for (int bj = 0; bj < N; bj += block_size) {\n            vector<pair<int,int>> block;\n            for (int i = bi; i < min(N, bi+block_size); i++) {\n                for (int j = bj; j < min(N, bj+block_size); j++) {\n                    block.push_back({i, j});\n                }\n            }\n            if (block.size() >= 2) {\n                double block_avg = query(block) / (double)block.size();\n                for (auto [i, j] : block) {\n                    estimate[i][j] = (estimate[i][j] + block_avg) / 2.0;\n                }\n            }\n        }\n    }\n    \n    // Phase 4: Drill uncertain squares\n    set<pair<int,int>> has_oil;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (estimate[i][j] > 0.4 || query_count >= 600) {\n                int v = drill(i, j);\n                drilled[i][j] = v;\n                if (v > 0) has_oil.insert({i, j});\n            }\n        }\n    }\n    \n    // Make answer\n    if (!answer(has_oil)) {\n        // If wrong, drill remaining squares\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (drilled[i][j] < 0) {\n                    int v = drill(i, j);\n                    if (v > 0) has_oil.insert({i, j});\n                }\n            }\n        }\n        answer(has_oil);\n    }\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\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    // Process each day independently\n    for (int d = 0; d < D; d++) {\n        // Calculate minimum height needed for each reservation\n        vector<int> heights(N);\n        long long total_height = 0;\n        \n        for (int k = 0; k < N; k++) {\n            // Each strip spans full width W\n            // Height needed: ceil(area / W)\n            heights[k] = max(1, (a[d][k] + W - 1) / W);\n            total_height += heights[k];\n        }\n        \n        vector<int> row_pos(N + 1);\n        row_pos[0] = 0;\n        \n        if (total_height <= W) {\n            // Can fit all strips exactly\n            for (int k = 0; k < N; k++) {\n                row_pos[k + 1] = row_pos[k] + heights[k];\n            }\n        } else {\n            // Need to compress - distribute proportionally\n            long long cumsum = 0;\n            for (int k = 0; k < N; k++) {\n                cumsum += heights[k];\n                row_pos[k + 1] = (int)((cumsum * W) / total_height);\n            }\n        }\n        \n        // Ensure last position is exactly W\n        row_pos[N] = W;\n        \n        // Ensure each strip has at least height 1\n        for (int k = 0; k < N; k++) {\n            if (row_pos[k + 1] <= row_pos[k]) {\n                row_pos[k + 1] = row_pos[k] + 1;\n            }\n        }\n        \n        // Output rectangles for this day\n        for (int k = 0; k < N; k++) {\n            cout << row_pos[k] << \" 0 \" << row_pos[k + 1] << \" \" << W << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353LL;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nlong long board[N][N];\nlong long stamps[M][3][3];\n\nstruct Evaluation {\n    long long improvement;\n    int wraparounds;\n    int stamp, p, q;\n    \n    bool operator<(const Evaluation& other) const {\n        // First prioritize by improvement\n        if (improvement != other.improvement) {\n            return improvement > other.improvement;\n        }\n        // Then prefer fewer wraparounds\n        return wraparounds < other.wraparounds;\n    }\n};\n\nEvaluation evaluate_stamp(int m, int p, int q) {\n    Evaluation eval;\n    eval.stamp = m;\n    eval.p = p;\n    eval.q = q;\n    eval.improvement = 0;\n    eval.wraparounds = 0;\n    \n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            int row = p + i;\n            int col = q + j;\n            long long remainder = board[row][col] % MOD;\n            long long stamp_val = stamps[m][i][j];\n            \n            if (remainder + stamp_val >= MOD) {\n                eval.wraparounds++;\n            }\n            \n            long long new_remainder = (remainder + stamp_val) % MOD;\n            eval.improvement += new_remainder - remainder;\n        }\n    }\n    return eval;\n}\n\nvoid apply_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            board[p + i][q + j] += stamps[m][i][j];\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 < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    for (int stamp = 0; stamp < M; stamp++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[stamp][i][j];\n            }\n        }\n    }\n    \n    vector<tuple<int, int, int>> operations;\n    \n    // Phase 1: Strongly prefer operations with no wraparounds\n    for (int op = 0; op < K; op++) {\n        vector<Evaluation> candidates;\n        \n        for (int stamp = 0; stamp < M; stamp++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    Evaluation eval = evaluate_stamp(stamp, p, q);\n                    if (eval.improvement > 0) {\n                        candidates.push_back(eval);\n                    }\n                }\n            }\n        }\n        \n        if (candidates.empty()) break;\n        \n        // Sort by our custom comparison (improvement first, then wraparounds)\n        sort(candidates.begin(), candidates.end());\n        \n        // In early operations, strongly avoid wraparounds\n        int choice_idx = 0;\n        if (op < K / 2) {\n            // Try to find best option with no wraparounds\n            for (int i = 0; i < min(10, (int)candidates.size()); i++) {\n                if (candidates[i].wraparounds == 0) {\n                    choice_idx = i;\n                    break;\n                }\n            }\n        }\n        \n        Evaluation best = candidates[choice_idx];\n        apply_stamp(best.stamp, best.p, best.q);\n        operations.push_back({best.stamp, best.p, best.q});\n    }\n    \n    cout << operations.size() << endl;\n    for (auto [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << endl;\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N];\n\nstruct State {\n    int grid[N][N];\n    pair<int,int> crane_pos[N];\n    int crane_carry[N];\n    int next_container[N];\n    \n    State() {\n        memset(grid, -1, sizeof(grid));\n        for (int i = 0; i < N; i++) {\n            crane_pos[i] = {i, 0};\n            crane_carry[i] = -1;\n            next_container[i] = 0;\n        }\n    }\n    \n    int target_row(int container) {\n        return container / N;\n    }\n    \n    void place_containers() {\n        for (int i = 0; i < N; i++) {\n            if (next_container[i] < N && grid[i][0] == -1) {\n                bool blocked = false;\n                for (int c = 0; c < N; c++) {\n                    if (crane_pos[c] == make_pair(i, 0) && crane_carry[c] != -1) {\n                        blocked = true;\n                    }\n                }\n                if (!blocked) {\n                    grid[i][0] = A[i][next_container[i]];\n                    next_container[i]++;\n                }\n            }\n        }\n    }\n    \n    void dispatch_containers() {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                grid[i][N-1] = -1;\n            }\n        }\n    }\n    \n    void apply_action(int crane_id, char action) {\n        auto& pos = crane_pos[crane_id];\n        \n        if (action == 'P') {\n            crane_carry[crane_id] = grid[pos.first][pos.second];\n            grid[pos.first][pos.second] = -1;\n        } else if (action == 'Q') {\n            grid[pos.first][pos.second] = crane_carry[crane_id];\n            crane_carry[crane_id] = -1;\n        } else if (action == 'U') {\n            pos.first--;\n        } else if (action == 'D') {\n            pos.first++;\n        } else if (action == 'L') {\n            pos.second--;\n        } else if (action == 'R') {\n            pos.second++;\n        }\n    }\n};\n\nint main() {\n    int n;\n    cin >> n;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    State state;\n    vector<string> commands(N);\n    \n    for (int turn = 0; turn < 1000; turn++) {\n        state.place_containers();\n        \n        vector<char> actions(N, '.');\n        \n        for (int i = 0; i < N; i++) {\n            auto [r, c] = state.crane_pos[i];\n            \n            if (state.crane_carry[i] == -1) {\n                // Not carrying\n                if (state.grid[r][c] != -1) {\n                    actions[i] = 'P';\n                } else if (c > 0) {\n                    actions[i] = 'L';\n                }\n            } else {\n                // Carrying container\n                int container = state.crane_carry[i];\n                int target_r = state.target_row(container);\n                \n                if (r != target_r) {\n                    // Move to correct row first\n                    actions[i] = (r < target_r) ? 'D' : 'U';\n                } else if (c < N-1) {\n                    // Move right to dispatch gate\n                    actions[i] = 'R';\n                } else {\n                    // At dispatch gate, release\n                    actions[i] = 'Q';\n                }\n            }\n        }\n        \n        // Apply actions\n        for (int i = 0; i < N; i++) {\n            commands[i] += actions[i];\n            state.apply_action(i, actions[i]);\n        }\n        \n        state.dispatch_containers();\n        \n        // Check if done\n        bool done = true;\n        for (int i = 0; i < N; i++) {\n            if (state.next_container[i] < N || state.crane_carry[i] != -1) {\n                done = false;\n            }\n        }\n        if (done) {\n            bool has_containers = false;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (state.grid[i][j] != -1) has_containers = true;\n                }\n            }\n            if (!has_containers) break;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << commands[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<vector<int>> h;\nvector<string> operations;\nint cur_r = 0, cur_c = 0;\nint load = 0;\n\nint manhattan(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\nvoid moveTo(int tr, int tc) {\n    while (cur_r < tr && operations.size() < 99000) {\n        operations.push_back(\"D\");\n        cur_r++;\n    }\n    while (cur_r > tr && operations.size() < 99000) {\n        operations.push_back(\"U\");\n        cur_r--;\n    }\n    while (cur_c < tc && operations.size() < 99000) {\n        operations.push_back(\"R\");\n        cur_c++;\n    }\n    while (cur_c > tc && operations.size() < 99000) {\n        operations.push_back(\"L\");\n        cur_c--;\n    }\n}\n\nint main() {\n    cin >> N;\n    h.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n        }\n    }\n    \n    // Greedy nearest-neighbor approach\n    while (operations.size() < 95000) {\n        // Find nearest positive cell from current position\n        int pos_r = -1, pos_c = -1;\n        int min_dist = INT_MAX;\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 = manhattan(cur_r, cur_c, i, j);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        pos_r = i;\n                        pos_c = j;\n                    }\n                }\n            }\n        }\n        \n        if (pos_r == -1) break; // No more positive cells\n        \n        // Move to and load from positive cell\n        moveTo(pos_r, pos_c);\n        if (operations.size() >= 95000) break;\n        \n        int load_amt = h[pos_r][pos_c];\n        operations.push_back(\"+\" + to_string(load_amt));\n        load += load_amt;\n        h[pos_r][pos_c] = 0;\n        \n        // Distribute load to nearest negative cells\n        while (load > 0 && operations.size() < 95000) {\n            // Find nearest negative cell\n            int neg_r = -1, neg_c = -1;\n            min_dist = INT_MAX;\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 = manhattan(cur_r, cur_c, i, j);\n                        if (dist < min_dist) {\n                            min_dist = dist;\n                            neg_r = i;\n                            neg_c = j;\n                        }\n                    }\n                }\n            }\n            \n            if (neg_r == -1) break; // No more negative cells\n            \n            // Move to and unload at negative cell\n            moveTo(neg_r, neg_c);\n            if (operations.size() >= 95000) break;\n            \n            int unload_amt = min(load, -h[neg_r][neg_c]);\n            operations.push_back(\"-\" + to_string(unload_amt));\n            load -= unload_amt;\n            h[neg_r][neg_c] += unload_amt;\n        }\n    }\n    \n    for (const auto& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <set>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> X(seed_count, vector<int>(M));\n    \n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> X[i][j];\n        }\n    }\n    \n    for (int t = 0; t < T; t++) {\n        // Find max for each criterion\n        vector<int> max_val(M, 0);\n        for (int l = 0; l < M; l++) {\n            for (int i = 0; i < seed_count; i++) {\n                max_val[l] = max(max_val[l], X[i][l]);\n            }\n        }\n        \n        // Find seeds that are near-champions (>=90% of max) for any criterion\n        set<int> important_seeds;\n        for (int l = 0; l < M; l++) {\n            int threshold = max_val[l] * 9 / 10;\n            for (int i = 0; i < seed_count; i++) {\n                if (X[i][l] >= threshold) {\n                    important_seeds.insert(i);\n                }\n            }\n        }\n        \n        // Calculate total values\n        vector<pair<int, int>> seed_values;\n        for (int i = 0; i < seed_count; i++) {\n            int total = accumulate(X[i].begin(), X[i].end(), 0);\n            seed_values.push_back({total, i});\n        }\n        sort(seed_values.rbegin(), seed_values.rend());\n        \n        // Select seeds: prioritize important seeds by their total value\n        set<int> selected;\n        \n        // Add important seeds sorted by total value\n        vector<pair<int, int>> important_by_value;\n        for (int s : important_seeds) {\n            int total = accumulate(X[s].begin(), X[s].end(), 0);\n            important_by_value.push_back({total, s});\n        }\n        sort(important_by_value.rbegin(), important_by_value.rend());\n        \n        for (auto [val, s] : important_by_value) {\n            if (selected.size() >= N * N) break;\n            selected.insert(s);\n        }\n        \n        // Fill remaining slots with best seeds by total value\n        for (auto [val, s] : seed_values) {\n            if (selected.size() >= N * N) break;\n            selected.insert(s);\n        }\n        \n        // Convert to vector and sort by total value\n        vector<int> selected_seeds(selected.begin(), selected.end());\n        sort(selected_seeds.begin(), selected_seeds.end(), [&](int a, int b) {\n            int val_a = accumulate(X[a].begin(), X[a].end(), 0);\n            int val_b = accumulate(X[b].begin(), X[b].end(), 0);\n            return val_a > val_b;\n        });\n        \n        // Create position list sorted by number of neighbors (descending)\n        vector<pair<int, pair<int, int>>> positions;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int neighbors = 0;\n                if (i > 0) neighbors++;\n                if (i < N-1) neighbors++;\n                if (j > 0) neighbors++;\n                if (j < N-1) neighbors++;\n                positions.push_back({neighbors, {i, j}});\n            }\n        }\n        sort(positions.rbegin(), positions.rend());\n        \n        // Place best seeds in positions with most neighbors\n        vector<vector<int>> A(N, vector<int>(N));\n        for (int idx = 0; idx < N * N; idx++) {\n            A[positions[idx].second.first][positions[idx].second.second] = selected_seeds[idx];\n        }\n        \n        // Output\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << A[i][j];\n                if (j < N - 1) cout << \" \";\n                else cout << endl;\n            }\n        }\n        cout.flush();\n        \n        // Read new seeds\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    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<vector<int>> grid_current;\nvector<vector<int>> grid_target;\n\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\n\nstruct State {\n    int root_x, root_y;\n    int num_v;\n    vector<int> parent;\n    vector<int> length;\n    vector<bool> is_leaf;\n    vector<bool> holding;\n    \n    vector<pair<int,int>> get_positions() {\n        vector<pair<int,int>> pos(num_v);\n        pos[0] = {root_x, root_y};\n        for (int i = 1; i < num_v; i++) {\n            int p = parent[i];\n            pos[i] = {pos[p].first + dx[0] * length[i], \n                     pos[p].second + dy[0] * length[i]};\n        }\n        return pos;\n    }\n    \n    string make_command(char move, vector<char> rots, vector<char> actions) {\n        string s(2 * num_v, '.');\n        s[0] = move;\n        for (int i = 1; i < num_v; i++) {\n            s[i] = rots[i-1];\n        }\n        for (int i = 0; i < num_v; i++) {\n            s[num_v + i] = actions[i];\n        }\n        return s;\n    }\n};\n\nint main() {\n    cin >> N >> M >> V;\n    \n    grid_current.resize(N, vector<int>(N, 0));\n    grid_target.resize(N, vector<int>(N, 0));\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            if (s[j] == '1') {\n                grid_current[i][j] = 1;\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            if (s[j] == '1') {\n                grid_target[i][j] = 1;\n            }\n        }\n    }\n    \n    State state;\n    state.num_v = 2;\n    state.parent = {-1, 0};\n    state.length = {0, 1};\n    state.is_leaf = {false, true};\n    state.holding.resize(state.num_v, false);\n    state.root_x = 0;\n    state.root_y = 0;\n    \n    cout << state.num_v << endl;\n    for (int i = 1; i < state.num_v; i++) {\n        cout << state.parent[i] << \" \" << state.length[i] << endl;\n    }\n    cout << state.root_x << \" \" << state.root_y << endl;\n    \n    vector<string> commands;\n    int leaf = 1;\n    \n    while (commands.size() < 90000) {\n        auto pos = state.get_positions();\n        \n        if (!state.holding[leaf]) {\n            // Find a takoyaki not at its target position\n            pair<int,int> best_src = {-1, -1};\n            int min_dist = INT_MAX;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    // Pick only takoyaki that are NOT at target positions\n                    if (grid_current[i][j] == 1 && grid_target[i][j] == 0) {\n                        int d = abs(pos[leaf].first - i) + abs(pos[leaf].second - j);\n                        if (d < min_dist) {\n                            min_dist = d;\n                            best_src = {i, j};\n                        }\n                    }\n                }\n            }\n            \n            if (best_src.first == -1) break; // No more takoyaki to move\n            \n            // Move to source\n            while (pos[leaf] != best_src && commands.size() < 90000) {\n                char move = '.';\n                \n                if (pos[leaf].first < best_src.first && state.root_x + 1 < N) {\n                    move = 'D';\n                    state.root_x++;\n                } else if (pos[leaf].first > best_src.first && state.root_x > 0) {\n                    move = 'U';\n                    state.root_x--;\n                } else if (pos[leaf].second < best_src.second && state.root_y + 1 < N) {\n                    move = 'R';\n                    state.root_y++;\n                } else if (pos[leaf].second > best_src.second && state.root_y > 0) {\n                    move = 'L';\n                    state.root_y--;\n                }\n                \n                commands.push_back(state.make_command(move, vector<char>(state.num_v-1, '.'), vector<char>(state.num_v, '.')));\n                pos = state.get_positions();\n            }\n            \n            // Pick up if at correct position and takoyaki exists\n            if (pos[leaf] == best_src && grid_current[best_src.first][best_src.second] == 1) {\n                vector<char> actions(state.num_v, '.');\n                actions[leaf] = 'P';\n                commands.push_back(state.make_command('.', vector<char>(state.num_v-1, '.'), actions));\n                state.holding[leaf] = true;\n                grid_current[best_src.first][best_src.second] = 0;\n            }\n        } else {\n            // Find empty target position\n            pair<int,int> best_tgt = {-1, -1};\n            int min_dist = INT_MAX;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    // Place only on empty target positions\n                    if (grid_target[i][j] == 1 && grid_current[i][j] == 0) {\n                        int d = abs(pos[leaf].first - i) + abs(pos[leaf].second - j);\n                        if (d < min_dist) {\n                            min_dist = d;\n                            best_tgt = {i, j};\n                        }\n                    }\n                }\n            }\n            \n            if (best_tgt.first == -1) break; // No more empty targets\n            \n            // Move to target\n            while (pos[leaf] != best_tgt && commands.size() < 90000) {\n                char move = '.';\n                \n                if (pos[leaf].first < best_tgt.first && state.root_x + 1 < N) {\n                    move = 'D';\n                    state.root_x++;\n                } else if (pos[leaf].first > best_tgt.first && state.root_x > 0) {\n                    move = 'U';\n                    state.root_x--;\n                } else if (pos[leaf].second < best_tgt.second && state.root_y + 1 < N) {\n                    move = 'R';\n                    state.root_y++;\n                } else if (pos[leaf].second > best_tgt.second && state.root_y > 0) {\n                    move = 'L';\n                    state.root_y--;\n                }\n                \n                commands.push_back(state.make_command(move, vector<char>(state.num_v-1, '.'), vector<char>(state.num_v, '.')));\n                pos = state.get_positions();\n            }\n            \n            // Place if at correct position and target is empty\n            if (pos[leaf] == best_tgt && grid_current[best_tgt.first][best_tgt.second] == 0) {\n                vector<char> actions(state.num_v, '.');\n                actions[leaf] = 'P';\n                commands.push_back(state.make_command('.', vector<char>(state.num_v-1, '.'), actions));\n                state.holding[leaf] = false;\n                grid_current[best_tgt.first][best_tgt.second] = 1;\n            }\n        }\n    }\n    \n    for (const auto& cmd : commands) {\n        cout << cmd << endl;\n    }\n    \n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n\nusing namespace std;\n\nint N;\nvector<pair<int,int>> mackerels, sardines;\n\nint calcScore(int x1, int y1, int x2, int y2) {\n    if (x1 > x2) swap(x1, x2);\n    if (y1 > y2) swap(y1, y2);\n    \n    int mac = 0, sar = 0;\n    for (auto [x, y] : mackerels) {\n        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) mac++;\n    }\n    for (auto [x, y] : sardines) {\n        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) sar++;\n    }\n    return mac - sar;\n}\n\nint main() {\n    cin >> N;\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        mackerels.push_back({x, y});\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        sardines.push_back({x, y});\n    }\n    \n    int bestScore = 0;\n    int bx1 = 0, by1 = 0, bx2 = 100000, by2 = 100000;\n    \n    mt19937 rng(12345);\n    uniform_int_distribution<int> dist(0, N-1);\n    \n    // Try rectangles around some mackerels with different sizes\n    for (int iter = 0; iter < 200; iter++) {\n        int idx = dist(rng);\n        auto [cx, cy] = mackerels[idx];\n        \n        for (int sz = 3000; sz <= 20000; sz += 5000) {\n            int x1 = max(0, cx - sz);\n            int y1 = max(0, cy - sz);\n            int x2 = min(100000, cx + sz);\n            int y2 = min(100000, cy + sz);\n            \n            int score = calcScore(x1, y1, x2, y2);\n            if (score > bestScore) {\n                bestScore = score;\n                bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n            }\n        }\n    }\n    \n    // Random sampling: try pairs of mackerels as opposite corners\n    for (int iter = 0; iter < 1000; iter++) {\n        int i = dist(rng);\n        int j = dist(rng);\n        \n        int x1 = mackerels[i].first;\n        int y1 = mackerels[i].second;\n        int x2 = mackerels[j].first;\n        int y2 = mackerels[j].second;\n        \n        int score = calcScore(x1, y1, x2, y2);\n        if (score > bestScore) {\n            bestScore = score;\n            bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n        }\n    }\n    \n    // Local search: fine-tune boundaries\n    for (int ls_iter = 0; ls_iter < 3; ls_iter++) {\n        bool improved = false;\n        \n        for (int delta : {-3000, -1000, -300, 300, 1000, 3000}) {\n            int nx1 = max(0, min(100000, bx1 + delta));\n            int score = calcScore(nx1, by1, bx2, by2);\n            if (score > bestScore) {\n                bestScore = score;\n                bx1 = nx1;\n                improved = true;\n            }\n            \n            int nx2 = max(0, min(100000, bx2 + delta));\n            score = calcScore(bx1, by1, nx2, by2);\n            if (score > bestScore) {\n                bestScore = score;\n                bx2 = nx2;\n                improved = true;\n            }\n            \n            int ny1 = max(0, min(100000, by1 + delta));\n            score = calcScore(bx1, ny1, bx2, by2);\n            if (score > bestScore) {\n                bestScore = score;\n                by1 = ny1;\n                improved = true;\n            }\n            \n            int ny2 = max(0, min(100000, by2 + delta));\n            score = calcScore(bx1, by1, bx2, ny2);\n            if (score > bestScore) {\n                bestScore = score;\n                by2 = ny2;\n                improved = true;\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    if (bx1 > bx2) swap(bx1, bx2);\n    if (by1 > by2) swap(by1, by2);\n    \n    cout << 4 << endl;\n    cout << bx1 << \" \" << by1 << endl;\n    cout << bx2 << \" \" << by1 << endl;\n    cout << bx2 << \" \" << by2 << endl;\n    cout << bx1 << \" \" << by2 << endl;\n    \n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, T;\n    long long sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<pair<long long, long long>> rects(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].first >> rects[i].second;\n    }\n    \n    mt19937 rng(42);\n    \n    for (int turn = 0; turn < T; turn++) {\n        cout << N << endl;\n        \n        // Estimate dimensions as we place rectangles\n        long long est_w = 0, est_h = 0;\n        \n        for (int i = 0; i < N; i++) {\n            long long w = rects[i].first;\n            long long h = rects[i].second;\n            \n            int r = 0;\n            char d;\n            int b;\n            \n            if (i == 0) {\n                // First rectangle at origin\n                r = (h > w) ? 1 : 0;\n                if (r) swap(w, h);\n                d = 'U';\n                b = -1;\n                est_w = w;\n                est_h = h;\n            } else {\n                // Choose strategy based on turn\n                int strategy = turn % 6;\n                \n                switch (strategy) {\n                    case 0: // Horizontal layout - minimize height\n                        r = (h > w) ? 1 : 0;\n                        if (r) swap(w, h);\n                        d = 'U';\n                        b = i - 1;\n                        est_w += w;\n                        est_h = max(est_h, h);\n                        break;\n                        \n                    case 1: // Vertical layout - minimize width\n                        r = (w > h) ? 1 : 0;\n                        if (r) swap(w, h);\n                        d = 'L';\n                        b = -1;\n                        est_h += h;\n                        est_w = max(est_w, w);\n                        break;\n                        \n                    case 2: // Balanced - keep W \u2248 H\n                        if (est_w < est_h) {\n                            // Box is taller, extend width\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            // Box is wider, extend height\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 3: // Grid pattern\n                        if (i % 3 == 1) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = (i >= 2) ? i - 2 : -1;\n                        }\n                        break;\n                        \n                    case 4: // Alternating\n                        if (i % 2 == 1) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                        }\n                        break;\n                        \n                    default: // Random\n                        r = uniform_int_distribution<>(0, 1)(rng);\n                        if (r) swap(w, h);\n                        d = (uniform_int_distribution<>(0, 1)(rng) ? 'U' : 'L');\n                        b = uniform_int_distribution<>(-1, i - 1)(rng);\n                        break;\n                }\n            }\n            \n            cout << i << \" \" << r << \" \" << d << \" \" << b << endl;\n        }\n        cout.flush();\n        \n        long long W, H;\n        cin >> W >> H;\n    }\n    \n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint N, M, H;\nvector<int> A;\nvector<vector<int>> adj;\nvector<int> parent;\nvector<bool> assigned;\n\nvoid dfs(int u, int depth) {\n    if (depth >= H) return;\n    \n    // Collect unassigned neighbors\n    vector<int> neighbors;\n    for (int v : adj[u]) {\n        if (!assigned[v]) {\n            neighbors.push_back(v);\n        }\n    }\n    \n    // Sort by beauty descending - high beauty vertices first\n    sort(neighbors.begin(), neighbors.end(), [](int a, int b) {\n        return A[a] > A[b];\n    });\n    \n    // DFS into each neighbor (processes highest beauty first, going deep)\n    for (int v : neighbors) {\n        if (!assigned[v]) {\n            assigned[v] = true;\n            parent[v] = u;\n            dfs(v, depth + 1);\n        }\n    }\n}\n\nint main() {\n    cin >> N >> M >> H;\n    \n    A.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> A[i];\n    }\n    \n    adj.resize(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    // Skip coordinates\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    parent.resize(N, -1);\n    assigned.resize(N, false);\n    \n    // Build trees greedily\n    while (true) {\n        int root = -1;\n        double best_score = 1e9;\n        \n        // Find best root: low beauty with high connectivity to unassigned high-beauty vertices\n        for (int i = 0; i < N; i++) {\n            if (!assigned[i]) {\n                double neighbor_beauty_sum = 0;\n                int neighbor_count = 0;\n                \n                for (int j : adj[i]) {\n                    if (!assigned[j]) {\n                        neighbor_beauty_sum += A[j];\n                        neighbor_count++;\n                    }\n                }\n                \n                // Score: prioritize low beauty roots with high-beauty neighbors\n                // Lower score is better\n                double score = A[i] * 100.0 - neighbor_beauty_sum;\n                \n                if (root == -1 || score < best_score) {\n                    root = i;\n                    best_score = score;\n                }\n            }\n        }\n        \n        if (root == -1) break;\n        \n        assigned[root] = true;\n        parent[root] = -1;\n        dfs(root, 0);\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << parent[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    vector<pair<char, int>> moves;\n    \n    // Find all Oni positions\n    vector<pair<int,int>> oni_positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 'x') {\n                oni_positions.push_back({i, j});\n            }\n        }\n    }\n    \n    // For each Oni, find the safe direction with minimum distance\n    for (auto [oi, oj] : oni_positions) {\n        int best_dist = N + 1;\n        char best_dir = ' ';\n        int best_pos = 0;\n        \n        // Check upward (no Fukunokami above)\n        bool safe_up = true;\n        for (int i = 0; i < oi; i++) {\n            if (board[i][oj] == 'o') {\n                safe_up = false;\n                break;\n            }\n        }\n        if (safe_up) {\n            int dist = oi + 1;\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_dir = 'U';\n                best_pos = oj;\n            }\n        }\n        \n        // Check downward\n        bool safe_down = true;\n        for (int i = oi + 1; i < N; i++) {\n            if (board[i][oj] == 'o') {\n                safe_down = false;\n                break;\n            }\n        }\n        if (safe_down) {\n            int dist = N - oi;\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_dir = 'D';\n                best_pos = oj;\n            }\n        }\n        \n        // Check leftward\n        bool safe_left = true;\n        for (int j = 0; j < oj; j++) {\n            if (board[oi][j] == 'o') {\n                safe_left = false;\n                break;\n            }\n        }\n        if (safe_left) {\n            int dist = oj + 1;\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_dir = 'L';\n                best_pos = oi;\n            }\n        }\n        \n        // Check rightward\n        bool safe_right = true;\n        for (int j = oj + 1; j < N; j++) {\n            if (board[oi][j] == 'o') {\n                safe_right = false;\n                break;\n            }\n        }\n        if (safe_right) {\n            int dist = N - oj;\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_dir = 'R';\n                best_pos = oi;\n            }\n        }\n        \n        // Apply the best direction (shift out, then shift back)\n        if (best_dir == 'U' || best_dir == 'D') {\n            char reverse = (best_dir == 'U') ? 'D' : 'U';\n            for (int t = 0; t < best_dist; t++) {\n                moves.push_back({best_dir, best_pos});\n            }\n            for (int t = 0; t < best_dist; t++) {\n                moves.push_back({reverse, best_pos});\n            }\n        } else {\n            char reverse = (best_dir == 'L') ? 'R' : 'L';\n            for (int t = 0; t < best_dist; t++) {\n                moves.push_back({best_dir, best_pos});\n            }\n            for (int t = 0; t < best_dist; t++) {\n                moves.push_back({reverse, best_pos});\n            }\n        }\n    }\n    \n    // Output moves\n    for (auto [dir, pos] : moves) {\n        cout << dir << \" \" << pos << endl;\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, L;\nvector<int> T;\n\nlong long simulate(const vector<int>& a, const vector<int>& b, vector<int>& count) {\n    count.assign(N, 0);\n    int current = 0;\n    count[0] = 1;\n    \n    for (int week = 1; week < L; week++) {\n        int t = count[current];\n        if (t & 1) {\n            current = a[current];\n        } else {\n            current = b[current];\n        }\n        count[current]++;\n    }\n    \n    long long error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(count[i] - T[i]);\n    }\n    return error;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> L;\n    T.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    mt19937 gen(19937);\n    uniform_int_distribution<> dist_n(0, N-1);\n    \n    // Proper weighted distribution based on targets\n    vector<double> weights(N);\n    for (int i = 0; i < N; i++) {\n        weights[i] = T[i] + 1.0;\n    }\n    discrete_distribution<> weighted_dist(weights.begin(), weights.end());\n    \n    vector<int> best_a(N), best_b(N);\n    long long best_error = LLONG_MAX;\n    vector<int> count(N);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    double time_limit = 1.85;\n    \n    while (true) {\n        auto current_time = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed > time_limit) break;\n        \n        // Initialize with weighted distribution\n        vector<int> a(N), b(N);\n        for (int i = 0; i < N; i++) {\n            a[i] = weighted_dist(gen);\n            b[i] = weighted_dist(gen);\n        }\n        \n        long long error = simulate(a, b, count);\n        \n        // Hill climbing with multiple strategies\n        int no_improve = 0;\n        \n        while (no_improve < 3000) {\n            current_time = chrono::high_resolution_clock::now();\n            elapsed = chrono::duration<double>(current_time - start_time).count();\n            if (elapsed > time_limit) break;\n            \n            // Choose modification strategy\n            int strategy = gen() % 4;\n            \n            int i, new_val;\n            bool modify_a = gen() % 2;\n            int old_val;\n            \n            if (strategy == 0) {\n                // Weighted random\n                i = dist_n(gen);\n                new_val = weighted_dist(gen);\n            } else if (strategy == 1) {\n                // Target fix: redirect from over-assigned to under-assigned\n                int max_over = -1, max_over_diff = 0;\n                int max_under = -1, max_under_diff = 0;\n                \n                for (int j = 0; j < N; j++) {\n                    if (count[j] > T[j] && count[j] - T[j] > max_over_diff) {\n                        max_over_diff = count[j] - T[j];\n                        max_over = j;\n                    }\n                    if (T[j] > count[j] && T[j] - count[j] > max_under_diff) {\n                        max_under_diff = T[j] - count[j];\n                        max_under = j;\n                    }\n                }\n                \n                if (max_over >= 0 && max_under >= 0) {\n                    i = max_over;\n                    new_val = max_under;\n                } else {\n                    i = dist_n(gen);\n                    new_val = weighted_dist(gen);\n                }\n            } else if (strategy == 2) {\n                // Random employee pointing to under-assigned\n                i = dist_n(gen);\n                int max_under = -1, max_under_diff = 0;\n                for (int j = 0; j < N; j++) {\n                    if (T[j] > count[j] && T[j] - count[j] > max_under_diff) {\n                        max_under_diff = T[j] - count[j];\n                        max_under = j;\n                    }\n                }\n                new_val = (max_under >= 0) ? max_under : weighted_dist(gen);\n            } else {\n                // Uniform random for diversity\n                i = dist_n(gen);\n                new_val = dist_n(gen);\n            }\n            \n            old_val = modify_a ? a[i] : b[i];\n            \n            if (modify_a) {\n                a[i] = new_val;\n            } else {\n                b[i] = new_val;\n            }\n            \n            long long new_error = simulate(a, b, count);\n            \n            if (new_error < error) {\n                error = new_error;\n                no_improve = 0;\n                \n                if (error < best_error) {\n                    best_error = error;\n                    best_a = a;\n                    best_b = b;\n                }\n            } else {\n                if (modify_a) {\n                    a[i] = old_val;\n                } else {\n                    b[i] = old_val;\n                }\n                no_improve++;\n            }\n        }\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 <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent;\npublic:\n    UnionFind(int n) : parent(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        parent[px] = py;\n        return true;\n    }\n};\n\n// Z-order curve (Morton code) for better 2D spatial locality\nlong long morton_code(int x, int y) {\n    long long z = 0;\n    for (int i = 0; i < 20; i++) {\n        z |= ((long long)((x >> i) & 1) << (2 * i + 1));\n        z |= ((long long)((y >> i) & 1) << (2 * i));\n    }\n    return z;\n}\n\nint main() {\n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<pair<double, double>> pos(N);\n    for (int i = 0; i < N; i++) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        pos[i] = {(lx + rx) / 2.0, (ly + ry) / 2.0};\n    }\n    \n    // Sort cities by Z-order curve for better 2D locality\n    vector<int> order(N);\n    for (int i = 0; i < N; i++) order[i] = i;\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        int xa = (int)pos[a].first, ya = (int)pos[a].second;\n        int xb = (int)pos[b].first, yb = (int)pos[b].second;\n        return morton_code(xa, ya) < morton_code(xb, yb);\n    });\n    \n    // Create groups\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < G[i]; j++) {\n            groups[i].push_back(order[idx++]);\n        }\n    }\n    \n    // Get edges for each group\n    vector<vector<pair<int, int>>> edges(M);\n    int queries_used = 0;\n    \n    for (int k = 0; k < M; k++) {\n        if (G[k] == 1) continue;\n        \n        vector<pair<int, int>> candidate_edges;\n        \n        if (G[k] <= L && queries_used < Q) {\n            // Query entire group - get exact MST\n            cout << \"? \" << G[k];\n            for (int c : groups[k]) cout << \" \" << c;\n            cout << endl;\n            cout.flush();\n            queries_used++;\n            \n            for (int i = 0; i < G[k] - 1; i++) {\n                int u, v;\n                cin >> u >> v;\n                candidate_edges.push_back({u, v});\n            }\n        } else {\n            // Use overlapping sliding windows\n            int window_size = L;\n            int step = max(1, L / 2); // 50% overlap for better coverage\n            \n            for (int i = 0; i < G[k] && queries_used < Q; ) {\n                int sz = min(window_size, G[k] - i);\n                if (sz < 2) break;\n                \n                cout << \"? \" << sz;\n                for (int j = 0; j < sz; j++) {\n                    cout << \" \" << groups[k][i + j];\n                }\n                cout << endl;\n                cout.flush();\n                queries_used++;\n                \n                for (int j = 0; j < sz - 1; j++) {\n                    int u, v;\n                    cin >> u >> v;\n                    candidate_edges.push_back({u, v});\n                }\n                \n                if (i + sz >= G[k]) break;\n                i += step;\n            }\n        }\n        \n        // Build spanning tree from candidate edges using Union-Find\n        UnionFind uf(N);\n        for (auto [u, v] : candidate_edges) {\n            if (uf.unite(u, v)) {\n                edges[k].push_back({u, v});\n            }\n        }\n        \n        // Ensure full connectivity by adding fallback edges\n        for (int i = 0; i + 1 < G[k] && (int)edges[k].size() < G[k] - 1; i++) {\n            if (uf.unite(groups[k][i], groups[k][i + 1])) {\n                edges[k].push_back({groups[k][i], groups[k][i + 1]});\n            }\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int c : groups[k]) cout << c << \" \";\n        cout << endl;\n        for (auto [u, v] : edges[k]) {\n            cout << u << \" \" << v << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\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    int cur_r = targets[0].first;\n    int cur_c = targets[0].second;\n    \n    // Visit each target in order\n    for (int i = 1; i < M; i++) {\n        int target_r = targets[i].first;\n        int target_c = targets[i].second;\n        \n        // Move vertically first\n        while (cur_r != target_r) {\n            if (cur_r < target_r) {\n                cout << \"M D\\n\";\n                cur_r++;\n            } else {\n                cout << \"M U\\n\";\n                cur_r--;\n            }\n        }\n        \n        // Then move horizontally\n        while (cur_c != target_c) {\n            if (cur_c < target_c) {\n                cout << \"M R\\n\";\n                cur_c++;\n            } else {\n                cout << \"M L\\n\";\n                cur_c--;\n            }\n        }\n    }\n    \n    return 0;\n}"},"4":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> x, y;\nvector<long long> r;\nvector<array<int, 4>> result;\n\ndouble calc_satisfaction(int id) {\n    auto [a, b, c, d] = result[id];\n    if (x[id] < a || x[id] >= c || y[id] < b || y[id] >= d) return 0;\n    long long s = (long long)(c - a) * (d - b);\n    double ratio = (double)min(r[id], s) / max(r[id], s);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\nvoid solve(vector<int> ids, int x1, int y1, int x2, int y2) {\n    if (ids.empty()) return;\n    \n    if (ids.size() == 1) {\n        result[ids[0]] = {x1, y1, x2, y2};\n        return;\n    }\n    \n    long long total_r = 0;\n    for (int id : ids) total_r += r[id];\n    \n    if (x2 - x1 >= y2 - y1) {\n        sort(ids.begin(), ids.end(), [](int i, int j) {\n            return x[i] < x[j];\n        });\n        \n        int best_mid = 1;\n        double best_score = 1e18;\n        \n        for (int mid = 1; mid < ids.size(); mid++) {\n            long long left_r = 0;\n            for (int i = 0; i < mid; i++) left_r += r[ids[i]];\n            long long right_r = total_r - left_r;\n            \n            int min_split = max(x1 + 1, x[ids[mid-1]] + 1);\n            int max_split = min(x2 - 1, x[ids[mid]] + 1);\n            if (min_split > max_split) continue;\n            \n            // Try multiple split positions and choose the best\n            double best_split_score = 1e18;\n            int best_split_x = min_split;\n            \n            int ideal_split = x1 + (long long)(x2 - x1) * left_r / total_r;\n            ideal_split = max(min_split, min(max_split, ideal_split));\n            \n            for (int split_x : {min_split, max_split, ideal_split}) {\n                if (split_x < min_split || split_x > max_split) continue;\n                \n                long long left_area = (long long)(split_x - x1) * (y2 - y1);\n                long long right_area = (long long)(x2 - split_x) * (y2 - y1);\n                \n                // Calculate expected satisfaction loss\n                double loss_left = (left_area - left_r) * (left_area - left_r) / \n                                  (double)max(left_area, left_r) / max(left_area, left_r);\n                double loss_right = (right_area - right_r) * (right_area - right_r) / \n                                   (double)max(right_area, right_r) / max(right_area, right_r);\n                double split_score = loss_left + loss_right;\n                \n                if (split_score < best_split_score) {\n                    best_split_score = split_score;\n                    best_split_x = split_x;\n                }\n            }\n            \n            if (best_split_score < best_score) {\n                best_score = best_split_score;\n                best_mid = mid;\n            }\n        }\n        \n        int mid = best_mid;\n        long long left_r = 0;\n        for (int i = 0; i < mid; i++) left_r += r[ids[i]];\n        \n        int min_split = max(x1 + 1, x[ids[mid-1]] + 1);\n        int max_split = min(x2 - 1, x[ids[mid]] + 1);\n        int ideal_split = x1 + (long long)(x2 - x1) * left_r / total_r;\n        int split_x = max(min_split, min(max_split, ideal_split));\n        \n        vector<int> left(ids.begin(), ids.begin() + mid);\n        vector<int> right(ids.begin() + mid, ids.end());\n        \n        solve(left, x1, y1, split_x, y2);\n        solve(right, split_x, y1, x2, y2);\n    } else {\n        sort(ids.begin(), ids.end(), [](int i, int j) {\n            return y[i] < y[j];\n        });\n        \n        int best_mid = 1;\n        double best_score = 1e18;\n        \n        for (int mid = 1; mid < ids.size(); mid++) {\n            long long top_r = 0;\n            for (int i = 0; i < mid; i++) top_r += r[ids[i]];\n            long long bottom_r = total_r - top_r;\n            \n            int min_split = max(y1 + 1, y[ids[mid-1]] + 1);\n            int max_split = min(y2 - 1, y[ids[mid]] + 1);\n            if (min_split > max_split) continue;\n            \n            int ideal_split = y1 + (long long)(y2 - y1) * top_r / total_r;\n            ideal_split = max(min_split, min(max_split, ideal_split));\n            \n            double best_split_score = 1e18;\n            \n            for (int split_y : {min_split, max_split, ideal_split}) {\n                if (split_y < min_split || split_y > max_split) continue;\n                \n                long long top_area = (long long)(x2 - x1) * (split_y - y1);\n                long long bottom_area = (long long)(x2 - x1) * (y2 - split_y);\n                \n                double loss_top = (top_area - top_r) * (top_area - top_r) / \n                                 (double)max(top_area, top_r) / max(top_area, top_r);\n                double loss_bottom = (bottom_area - bottom_r) * (bottom_area - bottom_r) / \n                                    (double)max(bottom_area, bottom_r) / max(bottom_area, bottom_r);\n                double split_score = loss_top + loss_bottom;\n                \n                if (split_score < best_split_score) {\n                    best_split_score = split_score;\n                }\n            }\n            \n            if (best_split_score < best_score) {\n                best_score = best_split_score;\n                best_mid = mid;\n            }\n        }\n        \n        int mid = best_mid;\n        long long top_r = 0;\n        for (int i = 0; i < mid; i++) top_r += r[ids[i]];\n        \n        int min_split = max(y1 + 1, y[ids[mid-1]] + 1);\n        int max_split = min(y2 - 1, y[ids[mid]] + 1);\n        int ideal_split = y1 + (long long)(y2 - y1) * top_r / total_r;\n        int split_y = max(min_split, min(max_split, ideal_split));\n        \n        vector<int> top(ids.begin(), ids.begin() + mid);\n        vector<int> bottom(ids.begin() + mid, ids.end());\n        \n        solve(top, x1, y1, x2, split_y);\n        solve(bottom, x1, split_y, x2, y2);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n;\n    x.resize(n);\n    y.resize(n);\n    r.resize(n);\n    result.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> x[i] >> y[i] >> r[i];\n    }\n    \n    vector<int> all_ids(n);\n    iota(all_ids.begin(), all_ids.end(), 0);\n    \n    solve(all_ids, 0, 0, 10000, 10000);\n    \n    for (int i = 0; i < n; i++) {\n        cout << result[i][0] << \" \" << result[i][1] << \" \" \n             << result[i][2] << \" \" << result[i][3] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nmap<int, vector<pair<int,int>>> tile_squares;\nmap<int, int> tile_value;\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < 50 && y >= 0 && y < 50;\n}\n\nint main() {\n    cin >> si >> sj;\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> t[i][j];\n            tile_squares[t[i][j]].push_back({i, j});\n        }\n    }\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> p[i][j];\n            tile_value[t[i][j]] += p[i][j];\n        }\n    }\n    \n    bool visited_tile[2500] = {};\n    bool visited_square[50][50] = {};\n    string path = \"\";\n    int x = si, y = sj;\n    visited_tile[t[x][y]] = true;\n    visited_square[x][y] = true;\n    \n    while (true) {\n        int current_tile = t[x][y];\n        \n        // First priority: visit other squares of current tile\n        int best_dir = -1;\n        int best_value = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (!in_bounds(nx, ny)) continue;\n            if (visited_square[nx][ny]) continue;\n            \n            int next_tile = t[nx][ny];\n            \n            if (next_tile == current_tile) {\n                if (best_dir == -1 || p[nx][ny] > best_value) {\n                    best_value = p[nx][ny];\n                    best_dir = d;\n                }\n            }\n        }\n        \n        // Second priority: move to new tile with highest total value\n        if (best_dir == -1) {\n            int best_tile_value = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                \n                if (!in_bounds(nx, ny)) continue;\n                if (visited_square[nx][ny]) continue;\n                \n                int next_tile = t[nx][ny];\n                \n                if (visited_tile[next_tile]) continue;\n                \n                if (tile_value[next_tile] > best_tile_value) {\n                    best_tile_value = tile_value[next_tile];\n                    best_dir = d;\n                }\n            }\n        }\n        \n        if (best_dir == -1) break;\n        \n        int nx = x + dx[best_dir];\n        int ny = y + dy[best_dir];\n        \n        path += dir_char[best_dir];\n        visited_square[nx][ny] = true;\n        visited_tile[t[nx][ny]] = true;\n        \n        x = nx;\n        y = ny;\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst double INF = 1e18;\nconst double DEFAULT_WEIGHT = 5000.0;\n\ndouble h[N][N], v[N][N];\nint h_count[N][N], v_count[N][N];\nvector<double> h_observations[N][N], v_observations[N][N];\n\nvoid init_weights() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            h[i][j] = DEFAULT_WEIGHT;\n            v[i][j] = DEFAULT_WEIGHT;\n            h_count[i][j] = 0;\n            v_count[i][j] = 0;\n        }\n    }\n}\n\npair<double, vector<pair<int,int>>> dijkstra(int si, int sj, int ti, int tj) {\n    vector<vector<double>> dist(N, vector<double>(N, INF));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    priority_queue<pair<double, pair<int,int>>, \n                   vector<pair<double, pair<int,int>>>,\n                   greater<>> pq;\n    \n    dist[si][sj] = 0;\n    pq.push({0, {si, sj}});\n    \n    while (!pq.empty()) {\n        auto [d, pos] = pq.top();\n        pq.pop();\n        auto [i, j] = pos;\n        \n        if (d > dist[i][j]) continue;\n        \n        if (i > 0 && dist[i][j] + v[i-1][j] < dist[i-1][j]) {\n            dist[i-1][j] = dist[i][j] + v[i-1][j];\n            parent[i-1][j] = {i, j};\n            pq.push({dist[i-1][j], {i-1, j}});\n        }\n        if (i < N-1 && dist[i][j] + v[i][j] < dist[i+1][j]) {\n            dist[i+1][j] = dist[i][j] + v[i][j];\n            parent[i+1][j] = {i, j};\n            pq.push({dist[i+1][j], {i+1, j}});\n        }\n        if (j > 0 && dist[i][j] + h[i][j-1] < dist[i][j-1]) {\n            dist[i][j-1] = dist[i][j] + h[i][j-1];\n            parent[i][j-1] = {i, j};\n            pq.push({dist[i][j-1], {i, j-1}});\n        }\n        if (j < N-1 && dist[i][j] + h[i][j] < dist[i][j+1]) {\n            dist[i][j+1] = dist[i][j] + h[i][j];\n            parent[i][j+1] = {i, j};\n            pq.push({dist[i][j+1], {i, j+1}});\n        }\n    }\n    \n    vector<pair<int,int>> path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        path.push_back({ci, cj});\n        auto [pi, pj] = parent[ci][cj];\n        if (pi == -1) break;\n        ci = pi;\n        cj = pj;\n    }\n    path.push_back({si, sj});\n    reverse(path.begin(), path.end());\n    \n    return {dist[ti][tj], path};\n}\n\nstring path_to_string(const vector<pair<int,int>>& path) {\n    string result;\n    for (int i = 1; i < path.size(); i++) {\n        int di = path[i].first - path[i-1].first;\n        int dj = path[i].second - path[i-1].second;\n        if (di == -1) result += 'U';\n        else if (di == 1) result += 'D';\n        else if (dj == -1) result += 'L';\n        else result += 'R';\n    }\n    return result;\n}\n\nvoid apply_row_column_smoothing(int query_num) {\n    // Only smooth unobserved or low-confidence edges\n    // Horizontal edges - smooth within rows\n    for (int i = 0; i < N; i++) {\n        vector<double> observed_vals;\n        for (int j = 0; j < N-1; j++) {\n            if (h_count[i][j] >= 2) {\n                observed_vals.push_back(h[i][j]);\n            }\n        }\n        if (observed_vals.size() >= 3) {\n            sort(observed_vals.begin(), observed_vals.end());\n            double median = observed_vals[observed_vals.size() / 2];\n            \n            for (int j = 0; j < N-1; j++) {\n                if (h_count[i][j] == 0) {\n                    h[i][j] = median;\n                } else if (h_count[i][j] == 1) {\n                    h[i][j] = 0.7 * h[i][j] + 0.3 * median;\n                }\n            }\n        }\n    }\n    \n    // Vertical edges - smooth within columns\n    for (int j = 0; j < N; j++) {\n        vector<double> observed_vals;\n        for (int i = 0; i < N-1; i++) {\n            if (v_count[i][j] >= 2) {\n                observed_vals.push_back(v[i][j]);\n            }\n        }\n        if (observed_vals.size() >= 3) {\n            sort(observed_vals.begin(), observed_vals.end());\n            double median = observed_vals[observed_vals.size() / 2];\n            \n            for (int i = 0; i < N-1; i++) {\n                if (v_count[i][j] == 0) {\n                    v[i][j] = median;\n                } else if (v_count[i][j] == 1) {\n                    v[i][j] = 0.7 * v[i][j] + 0.3 * median;\n                }\n            }\n        }\n    }\n}\n\nvoid update_weights(const vector<pair<int,int>>& path, double measured, double estimated, int query_num) {\n    if (path.size() <= 1) return;\n    \n    // Calculate uncertainty for each edge\n    vector<double> uncertainties;\n    double total_uncertainty = 0;\n    \n    for (int i = 1; i < path.size(); i++) {\n        int pi = path[i-1].first, pj = path[i-1].second;\n        int ci = path[i].first, cj = path[i].second;\n        \n        double uncertainty;\n        if (pi == ci) {\n            int j = min(pj, cj);\n            uncertainty = 1.0 / (1.0 + h_count[pi][j]);\n        } else {\n            int ii = min(pi, ci);\n            uncertainty = 1.0 / (1.0 + v_count[ii][pj]);\n        }\n        uncertainties.push_back(uncertainty);\n        total_uncertainty += uncertainty;\n    }\n    \n    double error = measured - estimated;\n    \n    // Adaptive learning rate with slower decay\n    double base_alpha = 0.7 * exp(-query_num / 300.0) + 0.1;\n    \n    for (int i = 1; i < path.size(); i++) {\n        int pi = path[i-1].first, pj = path[i-1].second;\n        int ci = path[i].first, cj = path[i].second;\n        \n        double weight = uncertainties[i-1] / total_uncertainty;\n        double correction = base_alpha * error * weight;\n        \n        if (pi == ci) {\n            int j = min(pj, cj);\n            h_count[pi][j]++;\n            \n            // For edges observed multiple times, use moving average\n            if (h_count[pi][j] > 1) {\n                double new_estimate = h[pi][j] + correction;\n                h_observations[pi][j].push_back(new_estimate);\n                \n                // Robust averaging: drop outliers if we have enough samples\n                if (h_observations[pi][j].size() >= 5) {\n                    vector<double> sorted_obs = h_observations[pi][j];\n                    sort(sorted_obs.begin(), sorted_obs.end());\n                    // Trimmed mean: drop top and bottom 20%\n                    int trim = sorted_obs.size() / 5;\n                    double sum = 0;\n                    for (int k = trim; k < sorted_obs.size() - trim; k++) {\n                        sum += sorted_obs[k];\n                    }\n                    h[pi][j] = sum / (sorted_obs.size() - 2 * trim);\n                } else {\n                    h[pi][j] = new_estimate;\n                }\n            } else {\n                h[pi][j] += correction;\n                h_observations[pi][j].push_back(h[pi][j]);\n            }\n            h[pi][j] = max(1000.0, min(9000.0, h[pi][j]));\n        } else {\n            int ii = min(pi, ci);\n            v_count[ii][pj]++;\n            \n            if (v_count[ii][pj] > 1) {\n                double new_estimate = v[ii][pj] + correction;\n                v_observations[ii][pj].push_back(new_estimate);\n                \n                if (v_observations[ii][pj].size() >= 5) {\n                    vector<double> sorted_obs = v_observations[ii][pj];\n                    sort(sorted_obs.begin(), sorted_obs.end());\n                    int trim = sorted_obs.size() / 5;\n                    double sum = 0;\n                    for (int k = trim; k < sorted_obs.size() - trim; k++) {\n                        sum += sorted_obs[k];\n                    }\n                    v[ii][pj] = sum / (sorted_obs.size() - 2 * trim);\n                } else {\n                    v[ii][pj] = new_estimate;\n                }\n            } else {\n                v[ii][pj] += correction;\n                v_observations[ii][pj].push_back(v[ii][pj]);\n            }\n            v[ii][pj] = max(1000.0, min(9000.0, v[ii][pj]));\n        }\n    }\n    \n    // Apply smoothing every 30 queries\n    if (query_num % 30 == 29 && query_num < 900) {\n        apply_row_column_smoothing(query_num);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_weights();\n    \n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        auto [estimated_len, path] = dijkstra(si, sj, ti, tj);\n        string path_str = path_to_string(path);\n        \n        cout << path_str << endl;\n        cout.flush();\n        \n        int measured;\n        cin >> measured;\n        \n        update_weights(path, measured, estimated_len, q);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nvector<string> strings;\nchar matrix[20][20];\nchar best_matrix[20][20];\n\nbool isSubsequence(const string& s) {\n    int k = s.length();\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            bool ok = true;\n            for (int p = 0; p < k; p++) {\n                if (matrix[i][(j + p) % N] != s[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return true;\n            \n            ok = true;\n            for (int p = 0; p < k; p++) {\n                if (matrix[(i + p) % N][j] != s[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return true;\n        }\n    }\n    return false;\n}\n\nint countMatched() {\n    int count = 0;\n    for (const auto& s : strings) {\n        if (isSubsequence(s)) count++;\n    }\n    return count;\n}\n\nint countConflicts(const string& s, int i, int j, int d) {\n    int k = s.length();\n    int conflicts = 0;\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        if (matrix[ni][nj] != '.' && matrix[ni][nj] != s[p]) {\n            conflicts++;\n        }\n    }\n    return conflicts;\n}\n\nint countMatching(const string& s, int i, int j, int d) {\n    int k = s.length();\n    int matching = 0;\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        if (matrix[ni][nj] == s[p]) {\n            matching++;\n        }\n    }\n    return matching;\n}\n\nvoid place(const string& s, int i, int j, int d) {\n    int k = s.length();\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        matrix[ni][nj] = s[p];\n    }\n}\n\nint main() {\n    cin >> N >> M;\n    strings.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    int best_score = 0;\n    \n    // Multiple random restarts\n    for (int restart = 0; restart < 10; restart++) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                matrix[i][j] = '.';\n            }\n        }\n        \n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        \n        if (restart == 0) {\n            // First try: longest first\n            sort(order.begin(), order.end(), [](int a, int b) {\n                return strings[a].length() > strings[b].length();\n            });\n        } else {\n            // Random shuffle for diversity\n            random_shuffle(order.begin(), order.end());\n        }\n        \n        // Greedy placement with increasing conflict tolerance\n        for (int maxConflicts = 0; maxConflicts <= 2; maxConflicts++) {\n            for (int idx : order) {\n                const string& s = strings[idx];\n                if (isSubsequence(s)) continue;\n                \n                int bestI = -1, bestJ = -1, bestD = -1;\n                int minConflicts = INT_MAX;\n                int maxMatching = -1;\n                \n                for (int i = 0; i < N; i++) {\n                    for (int j = 0; j < N; j++) {\n                        for (int d = 0; d < 2; d++) {\n                            int conflicts = countConflicts(s, i, j, d);\n                            int matching = countMatching(s, i, j, d);\n                            \n                            if (conflicts < minConflicts || \n                                (conflicts == minConflicts && matching > maxMatching)) {\n                                minConflicts = conflicts;\n                                maxMatching = matching;\n                                bestI = i;\n                                bestJ = j;\n                                bestD = d;\n                            }\n                        }\n                    }\n                }\n                \n                if (minConflicts <= maxConflicts && bestI != -1) {\n                    place(s, bestI, bestJ, bestD);\n                }\n            }\n        }\n        \n        // Smart dot filling\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (matrix[i][j] == '.') {\n                    int bestChar = 'A';\n                    int bestCount = 0;\n                    \n                    for (char c = 'A'; c <= 'H'; c++) {\n                        matrix[i][j] = c;\n                        int count = countMatched();\n                        if (count > bestCount) {\n                            bestCount = count;\n                            bestChar = c;\n                        }\n                    }\n                    matrix[i][j] = bestChar;\n                }\n            }\n        }\n        \n        int score = countMatched();\n        if (score > best_score) {\n            best_score = score;\n            memcpy(best_matrix, matrix, sizeof(matrix));\n        }\n    }\n    \n    memcpy(matrix, best_matrix, sizeof(matrix));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << matrix[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\n\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nbool is_valid(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\nset<pair<int,int>> get_visible(int i, int j) {\n    set<pair<int,int>> vis;\n    vis.insert({i, j});\n    for (int jj = j-1; jj >= 0 && grid[i][jj] != '#'; jj--) vis.insert({i, jj});\n    for (int jj = j+1; jj < N && grid[i][jj] != '#'; jj++) vis.insert({i, jj});\n    for (int ii = i-1; ii >= 0 && grid[ii][j] != '#'; ii--) vis.insert({ii, j});\n    for (int ii = i+1; ii < N && grid[ii][j] != '#'; ii++) vis.insert({ii, j});\n    return vis;\n}\n\nmap<pair<int,int>, int> dijkstra_dist(int si, int sj) {\n    map<pair<int,int>, int> dist;\n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    pq.push({0, si, sj});\n    dist[{si, sj}] = 0;\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        if (dist.count({i,j}) && d > dist[{i, j}]) continue;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (is_valid(ni, nj)) {\n                int nd = d + (grid[ni][nj] - '0');\n                if (!dist.count({ni, nj}) || nd < dist[{ni, nj}]) {\n                    dist[{ni, nj}] = nd;\n                    pq.push({nd, ni, nj});\n                }\n            }\n        }\n    }\n    return dist;\n}\n\nstring reconstruct_path(int si, int sj, int ti, int tj) {\n    if (si == ti && sj == tj) return \"\";\n    \n    map<pair<int,int>, pair<pair<int,int>, int>> parent;\n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    pq.push({0, si, sj});\n    parent[{si, sj}] = {{-1, -1}, -1};\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        if (i == ti && j == tj) {\n            string path;\n            auto curr = make_pair(ti, tj);\n            while (parent[curr].second != -1) {\n                path += dir_char[parent[curr].second];\n                curr = parent[curr].first;\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (is_valid(ni, nj) && !parent.count({ni, nj})) {\n                parent[{ni, nj}] = {{i, j}, dir};\n                int nd = d + (grid[ni][nj] - '0');\n                pq.push({nd, ni, nj});\n            }\n        }\n    }\n    return \"\";\n}\n\nint main() {\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    vector<pair<int,int>> roads;\n    set<pair<int,int>> all_roads;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                roads.push_back({i, j});\n                all_roads.insert({i, j});\n            }\n        }\n    }\n    \n    map<pair<int,int>, set<pair<int,int>>> visible_from;\n    for (auto& [i, j] : roads) {\n        visible_from[{i, j}] = get_visible(i, j);\n    }\n    \n    // Calculate coverage count for each square (importance metric)\n    map<pair<int,int>, int> coverage_count;\n    for (auto& sq : all_roads) {\n        for (auto& [pos, vis] : visible_from) {\n            if (vis.count(sq)) coverage_count[sq]++;\n        }\n    }\n    \n    set<pair<int,int>> covered = visible_from[{si, sj}];\n    vector<pair<int,int>> tour = {{si, sj}};\n    \n    // Greedy with cost-benefit and importance weighting\n    while (covered.size() < all_roads.size()) {\n        auto dist = dijkstra_dist(tour.back().first, tour.back().second);\n        \n        double best_score = -1e9;\n        pair<int,int> best_pos = tour.back();\n        \n        for (auto& [ri, rj] : roads) {\n            int new_count = 0;\n            double importance = 0;\n            for (auto& sq : visible_from[{ri, rj}]) {\n                if (!covered.count(sq)) {\n                    new_count++;\n                    // Weight by rarity - squares visible from fewer positions are more important\n                    importance += 1.0 / max(1, coverage_count[sq]);\n                }\n            }\n            if (new_count > 0 && dist.count({ri, rj})) {\n                int cost = dist[{ri, rj}];\n                // Score combines coverage importance and travel efficiency\n                double score = (importance * 10.0) / (cost + 1.0);\n                if (score > best_score) {\n                    best_score = score;\n                    best_pos = {ri, rj};\n                }\n            }\n        }\n        \n        if (best_score <= -1e8) break;\n        \n        tour.push_back(best_pos);\n        for (auto& sq : visible_from[best_pos]) covered.insert(sq);\n    }\n    \n    // Build path through tour\n    string result;\n    for (int i = 0; i < (int)tour.size() - 1; i++) {\n        result += reconstruct_path(tour[i].first, tour[i].second, \n                                   tour[i+1].first, tour[i+1].second);\n    }\n    result += reconstruct_path(tour.back().first, tour.back().second, si, sj);\n    \n    cout << result << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <map>\n#include <cmath>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> task_diff;\nvector<vector<int>> task_deps;\nvector<vector<int>> task_dependents;\nvector<int> task_status;\nvector<vector<double>> member_skill;\nvector<int> member_task;\nvector<int> start_day_map;\nvector<int> num_pending_deps;\n\nbool can_start(int task) {\n    return task_status[task] == -1 && num_pending_deps[task] == 0;\n}\n\ndouble estimate_time(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++) {\n        w += max(0.0, task_diff[task][k] - member_skill[member][k]);\n    }\n    return max(1.0, w);\n}\n\nvoid update_skill(int member, int task, int days) {\n    if (days == 1) {\n        // Perfect match - member has all required skills\n        for (int k = 0; k < K; k++) {\n            member_skill[member][k] = max(member_skill[member][k], \n                                         (double)task_diff[task][k]);\n        }\n    } else if (days <= 4) {\n        // Good performance - partially update skills\n        for (int k = 0; k < K; k++) {\n            if (task_diff[task][k] > 0) {\n                member_skill[member][k] = max(member_skill[member][k], \n                                             task_diff[task][k] - 2.0);\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K >> R;\n    \n    task_diff.resize(N, vector<int>(K));\n    task_deps.resize(N);\n    task_dependents.resize(N);\n    task_status.resize(N, -1);\n    num_pending_deps.resize(N, 0);\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> task_diff[i][j];\n        }\n    }\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        task_deps[v].push_back(u);\n        task_dependents[u].push_back(v);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        num_pending_deps[i] = task_deps[i].size();\n    }\n    \n    member_skill.resize(M, vector<double>(K, 30.0));\n    member_task.resize(M, -1);\n    start_day_map.resize(M);\n    \n    int day = 0;\n    \n    while (true) {\n        day++;\n        \n        // Find available tasks\n        vector<int> available;\n        available.reserve(N);\n        for (int i = 0; i < N; i++) {\n            if (can_start(i)) {\n                available.push_back(i);\n            }\n        }\n        \n        // Find idle members\n        vector<int> idle;\n        idle.reserve(M);\n        for (int i = 0; i < M; i++) {\n            if (member_task[i] == -1) {\n                idle.push_back(i);\n            }\n        }\n        \n        vector<pair<int, int>> assign;\n        assign.reserve(min(available.size(), idle.size()));\n        vector<bool> task_used(N, false);\n        \n        // Greedy assignment: for each member, find best available task\n        for (int m : idle) {\n            if (available.empty()) break;\n            \n            int best_task = -1;\n            double best_time = 1e9;\n            \n            for (int t : available) {\n                if (task_used[t]) continue;\n                double est = estimate_time(t, m);\n                if (est < best_time) {\n                    best_time = est;\n                    best_task = t;\n                }\n            }\n            \n            if (best_task != -1) {\n                assign.push_back({m, best_task});\n                member_task[m] = best_task;\n                task_status[best_task] = 0;\n                task_used[best_task] = true;\n                start_day_map[m] = day;\n            }\n        }\n        \n        cout << assign.size();\n        for (auto [m, t] : assign) {\n            cout << \" \" << (m + 1) << \" \" << (t + 1);\n        }\n        cout << \"\\n\";\n        cout.flush();\n        \n        int n;\n        cin >> n;\n        if (n == -1) break;\n        \n        for (int i = 0; i < n; i++) {\n            int m;\n            cin >> m;\n            m--;\n            \n            int t = member_task[m];\n            int days = day - start_day_map[m] + 1;\n            \n            task_status[t] = 1;\n            member_task[m] = -1;\n            \n            // Update dependencies\n            for (int dep : task_dependents[t]) {\n                num_pending_deps[dep]--;\n            }\n            \n            update_skill(m, t, days);\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <chrono>\n\nusing namespace std;\n\nstruct Order {\n    int id;\n    int ax, ay, cx, cy;\n};\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nclass Solution {\npublic:\n    vector<Order> orders;\n    chrono::high_resolution_clock::time_point start_time;\n    \n    void read_input() {\n        orders.resize(1000);\n        for (int i = 0; i < 1000; i++) {\n            orders[i].id = i;\n            cin >> orders[i].ax >> orders[i].ay >> orders[i].cx >> orders[i].cy;\n        }\n        start_time = chrono::high_resolution_clock::now();\n    }\n    \n    double elapsed_ms() {\n        auto now = chrono::high_resolution_clock::now();\n        return chrono::duration<double, milli>(now - start_time).count();\n    }\n    \n    int calc_cost(const vector<pair<int, int>>& route) {\n        int cost = 0;\n        for (size_t i = 1; i < route.size(); i++) {\n            cost += manhattan(route[i-1].first, route[i-1].second, route[i].first, route[i].second);\n        }\n        return cost;\n    }\n    \n    double score_order(int idx, double w1, double w2, double w3) {\n        double d_pickup = manhattan(400, 400, orders[idx].ax, orders[idx].ay);\n        double d_delivery = manhattan(400, 400, orders[idx].cx, orders[idx].cy);\n        double d_pd = manhattan(orders[idx].ax, orders[idx].ay, orders[idx].cx, orders[idx].cy);\n        \n        int mx = (orders[idx].ax + orders[idx].cx) / 2;\n        int my = (orders[idx].ay + orders[idx].cy) / 2;\n        double d_center = manhattan(400, 400, mx, my);\n        \n        return d_pickup * w1 + d_delivery * w1 + d_pd * w2 + d_center * w3;\n    }\n    \n    vector<int> select_orders(double w1, double w2, double w3) {\n        vector<pair<double, int>> scores;\n        for (int i = 0; i < 1000; i++) {\n            scores.push_back({score_order(i, w1, w2, w3), i});\n        }\n        sort(scores.begin(), scores.end());\n        \n        vector<int> selected;\n        for (int i = 0; i < 50; i++) {\n            selected.push_back(scores[i].second);\n        }\n        return selected;\n    }\n    \n    vector<pair<int, int>> construct_route_greedy(const vector<int>& selected) {\n        vector<pair<int, int>> route;\n        route.push_back({400, 400});\n        \n        set<int> need_pickup(selected.begin(), selected.end());\n        set<int> picked_up;\n        \n        int cx = 400, cy = 400;\n        \n        while (!need_pickup.empty() || !picked_up.empty()) {\n            int best_idx = -1;\n            int best_dist = 2000000;\n            bool is_pickup = false;\n            \n            for (int idx : need_pickup) {\n                int d = manhattan(cx, cy, orders[idx].ax, orders[idx].ay);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = true;\n                }\n            }\n            \n            for (int idx : picked_up) {\n                int d = manhattan(cx, cy, orders[idx].cx, orders[idx].cy);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = false;\n                }\n            }\n            \n            if (is_pickup) {\n                route.push_back({orders[best_idx].ax, orders[best_idx].ay});\n                cx = orders[best_idx].ax;\n                cy = orders[best_idx].ay;\n                need_pickup.erase(best_idx);\n                picked_up.insert(best_idx);\n            } else {\n                route.push_back({orders[best_idx].cx, orders[best_idx].cy});\n                cx = orders[best_idx].cx;\n                cy = orders[best_idx].cy;\n                picked_up.erase(best_idx);\n            }\n        }\n        \n        route.push_back({400, 400});\n        return route;\n    }\n    \n    vector<pair<int, int>> construct_route_paired(const vector<int>& selected, int threshold) {\n        vector<pair<int, int>> route;\n        route.push_back({400, 400});\n        \n        set<int> need_pickup(selected.begin(), selected.end());\n        set<int> picked_up;\n        \n        int cx = 400, cy = 400;\n        \n        while (!need_pickup.empty() || !picked_up.empty()) {\n            int best_idx = -1;\n            int best_dist = 2000000;\n            bool is_pickup = false;\n            \n            for (int idx : need_pickup) {\n                int d = manhattan(cx, cy, orders[idx].ax, orders[idx].ay);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = true;\n                }\n            }\n            \n            for (int idx : picked_up) {\n                int d = manhattan(cx, cy, orders[idx].cx, orders[idx].cy);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = false;\n                }\n            }\n            \n            if (is_pickup) {\n                route.push_back({orders[best_idx].ax, orders[best_idx].ay});\n                cx = orders[best_idx].ax;\n                cy = orders[best_idx].ay;\n                need_pickup.erase(best_idx);\n                \n                int d_to_delivery = manhattan(cx, cy, orders[best_idx].cx, orders[best_idx].cy);\n                if (d_to_delivery <= threshold) {\n                    route.push_back({orders[best_idx].cx, orders[best_idx].cy});\n                    cx = orders[best_idx].cx;\n                    cy = orders[best_idx].cy;\n                } else {\n                    picked_up.insert(best_idx);\n                }\n            } else {\n                route.push_back({orders[best_idx].cx, orders[best_idx].cy});\n                cx = orders[best_idx].cx;\n                cy = orders[best_idx].cy;\n                picked_up.erase(best_idx);\n            }\n        }\n        \n        route.push_back({400, 400});\n        return route;\n    }\n    \n    // Simple local search: try swapping adjacent same-type operations\n    vector<pair<int, int>> optimize_swaps(vector<pair<int, int>> route, const vector<int>& selected) {\n        map<pair<int,int>, int> loc_to_pickup, loc_to_delivery;\n        for (int idx : selected) {\n            loc_to_pickup[{orders[idx].ax, orders[idx].ay}] = idx;\n            loc_to_delivery[{orders[idx].cx, orders[idx].cy}] = idx;\n        }\n        \n        bool improved = true;\n        int iterations = 0;\n        while (improved && iterations < 50 && elapsed_ms() < 1800) {\n            improved = false;\n            iterations++;\n            \n            for (size_t i = 1; i + 1 < route.size() - 1; i++) {\n                // Try swapping adjacent positions that are both deliveries\n                bool is_delivery_i = loc_to_delivery.count(route[i]);\n                bool is_delivery_i1 = loc_to_delivery.count(route[i+1]);\n                \n                if (is_delivery_i && is_delivery_i1) {\n                    int cost_before = manhattan(route[i-1].first, route[i-1].second, route[i].first, route[i].second) +\n                                     manhattan(route[i].first, route[i].second, route[i+1].first, route[i+1].second) +\n                                     manhattan(route[i+1].first, route[i+1].second, route[i+2].first, route[i+2].second);\n                    \n                    int cost_after = manhattan(route[i-1].first, route[i-1].second, route[i+1].first, route[i+1].second) +\n                                    manhattan(route[i+1].first, route[i+1].second, route[i].first, route[i].second) +\n                                    manhattan(route[i].first, route[i].second, route[i+2].first, route[i+2].second);\n                    \n                    if (cost_after < cost_before) {\n                        swap(route[i], route[i+1]);\n                        improved = true;\n                    }\n                }\n            }\n        }\n        \n        return route;\n    }\n    \n    void solve() {\n        read_input();\n        \n        int best_cost = 2000000000;\n        vector<int> best_selected;\n        vector<pair<int, int>> best_route;\n        \n        // More comprehensive parameter search\n        for (double w1 = 0.15; w1 <= 0.95 && elapsed_ms() < 1500; w1 += 0.05) {\n            for (double w3 = 0.0; w3 <= 0.4; w3 += 0.05) {\n                double w2 = 1.0 - w1 - w3;\n                if (w2 < 0) continue;\n                \n                vector<int> selected = select_orders(w1, w2, w3);\n                \n                // Try greedy construction\n                vector<pair<int, int>> route1 = construct_route_greedy(selected);\n                int cost1 = calc_cost(route1);\n                if (cost1 < best_cost) {\n                    best_cost = cost1;\n                    best_selected = selected;\n                    best_route = route1;\n                }\n                \n                // Try paired construction with different thresholds\n                for (int threshold : {80, 120, 160, 200, 250, 300}) {\n                    vector<pair<int, int>> route2 = construct_route_paired(selected, threshold);\n                    int cost2 = calc_cost(route2);\n                    if (cost2 < best_cost) {\n                        best_cost = cost2;\n                        best_selected = selected;\n                        best_route = route2;\n                    }\n                }\n            }\n        }\n        \n        // Apply local optimization\n        if (elapsed_ms() < 1800) {\n            best_route = optimize_swaps(best_route, best_selected);\n        }\n        \n        cout << best_selected.size();\n        for (int idx : best_selected) {\n            cout << \" \" << (idx + 1);\n        }\n        cout << \"\\n\";\n        \n        cout << best_route.size();\n        for (auto [x, y] : best_route) {\n            cout << \" \" << x << \" \" << y;\n        }\n        cout << \"\\n\";\n        cout.flush();\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.solve();\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent, rank;\npublic:\n    UnionFind(int n) : parent(n), rank(n, 0) {\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    \n    int find(int x) {\n        return parent[x] == x ? x : parent[x] = find(parent[x]);\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400, M = 1995;\n    \n    vector<pair<int,int>> coord(N);\n    for (auto& [x, y] : coord) cin >> x >> y;\n    \n    vector<pair<int,int>> edge(M);\n    vector<int> dist(M);\n    \n    for (int i = 0; i < M; i++) {\n        auto& [u, v] = edge[i];\n        cin >> u >> v;\n        int dx = coord[u].first - coord[v].first;\n        int dy = coord[u].second - coord[v].second;\n        dist[i] = round(sqrt(dx*dx + dy*dy));\n    }\n    \n    UnionFind uf(N);\n    int cnt = 0;\n    \n    for (int i = 0; i < M; i++) {\n        int len;\n        cin >> len;\n        \n        auto [u, v] = edge[i];\n        int d = dist[i];\n        \n        bool ok = false;\n        if (uf.find(u) != uf.find(v)) {\n            int need = N - 1 - cnt;\n            int left = M - i;\n            \n            double r = (double)len / d;\n            double th;\n            \n            // Adaptive threshold based on safety margin\n            if (left <= need * 1.2) {\n                th = 3.0;  // Emergency mode: accept anything\n            } else if (left <= need * 2.0) {\n                th = 2.3;  // Getting tight\n            } else if (left <= need * 3.0) {\n                th = 1.9;  // Moderate selectivity\n            } else {\n                th = 1.7;  // Plenty of room: be selective\n            }\n            \n            ok = (r <= th);\n        }\n        \n        cout << (ok ? \"1\" : \"0\") << \"\\n\" << flush;\n        if (ok) {\n            uf.unite(u, v);\n            cnt++;\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Pos {\n    int x, y;\n    bool operator<(const Pos& o) const {\n        if (x != o.x) return x < o.x;\n        return y < o.y;\n    }\n};\n\nint N, M;\nvector<Pos> pets, humans;\nvector<int> pet_types;\nbool grid[32][32];\nset<Pos> pet_set;\n\nvoid init() {\n    cin >> N;\n    pets.resize(N);\n    pet_types.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pet_types[i];\n        pet_set.insert(pets[i]);\n    }\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n    \n    for (int i = 0; i <= 31; i++)\n        for (int j = 0; j <= 31; j++)\n            grid[i][j] = (i >= 1 && i <= 30 && j >= 1 && j <= 30);\n}\n\nbool is_adjacent_to_pet(int x, int y) {\n    return pet_set.count({x-1, y}) || pet_set.count({x+1, y}) ||\n           pet_set.count({x, y-1}) || pet_set.count({x, y+1});\n}\n\nbool in_bounds(int x, int y) {\n    return x >= 1 && x <= 30 && y >= 1 && y <= 30;\n}\n\nbool can_build_wall(int x, int y, const set<Pos>& human_set) {\n    if (!in_bounds(x, y)) return false;\n    if (!grid[x][y]) return false;\n    if (pet_set.count({x, y})) return false;\n    if (human_set.count({x, y})) return false;\n    if (is_adjacent_to_pet(x, y)) return false;\n    return true;\n}\n\nint main() {\n    init();\n    \n    // Find safe corner farthest from pets\n    int tx = 15, ty = 15;\n    double max_dist = 0;\n    for (int cx : {5, 25}) {\n        for (int cy : {5, 25}) {\n            double dist = 0;\n            for (const auto& p : pets)\n                dist += abs(p.x - cx) + abs(p.y - cy);\n            if (dist > max_dist) {\n                max_dist = dist;\n                tx = cx; ty = cy;\n            }\n        }\n    }\n    \n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n        \n        // Create a set of all current human positions at START of turn\n        set<Pos> human_set;\n        for (const auto& h : humans) {\n            human_set.insert(h);\n        }\n        \n        // Decide actions for all humans - collect walls first\n        set<Pos> walls_to_build;\n        \n        for (int i = 0; i < M; i++) {\n            int x = humans[i].x, y = humans[i].y;\n            \n            bool acted = false;\n            \n            vector<pair<int,int>> dirs = {{-1,0},{1,0},{0,-1},{0,1}};\n            string wall = \"udlr\";\n            \n            // Try to build walls around current position\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dirs[d].first;\n                int ny = y + dirs[d].second;\n                \n                if (can_build_wall(nx, ny, human_set)) {\n                    actions[i] = wall[d];\n                    walls_to_build.insert({nx, ny});\n                    acted = true;\n                    break;\n                }\n            }\n            \n            // If can't build, try to move toward target (early turns only)\n            if (!acted && turn < 30) {\n                string move = \"UDLR\";\n                \n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dirs[d].first;\n                    int ny = y + dirs[d].second;\n                    \n                    // Move closer to target\n                    int curr_dist = abs(x - tx) + abs(y - ty);\n                    int new_dist = abs(nx - tx) + abs(ny - ty);\n                    \n                    if (new_dist < curr_dist && in_bounds(nx, ny) && grid[nx][ny] && \n                        !walls_to_build.count({nx, ny})) {\n                        actions[i] = move[d];\n                        acted = true;\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // Apply all walls atomically\n        for (const auto& w : walls_to_build) {\n            grid[w.x][w.y] = false;\n        }\n        \n        // Apply all moves atomically\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'U') humans[i].x--;\n            else if (a == 'D') humans[i].x++;\n            else if (a == 'L') humans[i].y--;\n            else if (a == 'R') humans[i].y++;\n        }\n        \n        cout << actions << endl;\n        cout.flush();\n        \n        // Read and update pet positions\n        pet_set.clear();\n        for (int i = 0; i < N; i++) {\n            string mov;\n            cin >> mov;\n            for (char c : mov) {\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n            pet_set.insert(pets[i]);\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    if (si == ti && sj == tj) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    // BFS to find shortest path\n    queue<tuple<int,int,string>> q;\n    vector<vector<bool>> visited(20, vector<bool>(20, false));\n    q.push({si, sj, \"\"});\n    visited[si][sj] = true;\n    \n    string path = \"\";\n    while (!q.empty()) {\n        auto [i, j, cur_path] = q.front();\n        q.pop();\n        \n        if (i == ti && j == tj) {\n            path = cur_path;\n            break;\n        }\n        \n        // Try all 4 directions in consistent order\n        if (i < 19 && v[i][j] == '0' && !visited[i+1][j]) {\n            visited[i+1][j] = true;\n            q.push({i+1, j, cur_path + \"D\"});\n        }\n        if (j < 19 && h[i][j] == '0' && !visited[i][j+1]) {\n            visited[i][j+1] = true;\n            q.push({i, j+1, cur_path + \"R\"});\n        }\n        if (i > 0 && v[i-1][j] == '0' && !visited[i-1][j]) {\n            visited[i-1][j] = true;\n            q.push({i-1, j, cur_path + \"U\"});\n        }\n        if (j > 0 && h[i][j-1] == '0' && !visited[i][j-1]) {\n            visited[i][j-1] = true;\n            q.push({i, j-1, cur_path + \"L\"});\n        }\n    }\n    \n    if (path.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    // Simply repeat the shortest path to maximize robustness\n    // Use the full 200 character budget\n    string result = \"\";\n    while (result.length() + path.length() <= 200) {\n        result += path;\n    }\n    \n    // Fill remaining space with partial path\n    int remaining = 200 - result.length();\n    if (remaining > 0 && remaining < path.length()) {\n        result += path.substr(0, remaining);\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nint di[4] = {0, -1, 0, 1};\nint dj[4] = {-1, 0, 1, 0};\n\nint to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\nint rotateTile(int tile, int rot) {\n    rot = rot % 4;\n    for (int i = 0; i < rot; i++) {\n        if (tile <= 3) tile = (tile + 1) % 4;\n        else if (tile <= 5) tile = (tile == 4) ? 5 : 4;\n        else tile = (tile == 6) ? 7 : 6;\n    }\n    return tile;\n}\n\nint getLoopLength(int si, int sj, int sd, const vector<vector<int>>& current) {\n    int i = si, j = sj, d = sd, length = 0;\n    while (length <= 2000) {\n        int tile = current[i][j];\n        int d2 = to[tile][d];\n        if (d2 == -1) return 0;\n        i += di[d2]; j += dj[d2];\n        if (i < 0 || i >= N || j < 0 || j >= N) return 0;\n        d = (d2 + 2) % 4;\n        length++;\n        if (i == si && j == sj && d == sd) return length;\n    }\n    return 0;\n}\n\nlong long calculateScore(const vector<vector<int>>& current) {\n    vector<int> loops;\n    vector<vector<vector<bool>>> visited(N, vector<vector<bool>>(N, vector<bool>(4, false)));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (visited[i][j][d]) continue;\n                int len = getLoopLength(i, j, d, current);\n                if (len > 0) {\n                    loops.push_back(len);\n                    int ii = i, jj = j, dd = d;\n                    for (int step = 0; step < len; step++) {\n                        visited[ii][jj][dd] = true;\n                        int tile = current[ii][jj];\n                        int d2 = to[tile][dd];\n                        ii += di[d2]; jj += dj[d2];\n                        dd = (d2 + 2) % 4;\n                    }\n                }\n            }\n        }\n    }\n    sort(loops.rbegin(), loops.rend());\n    if (loops.size() < 2) return 0;\n    return (long long)loops[0] * loops[1];\n}\n\nint main() {\n    auto start = chrono::steady_clock::now();\n    vector<string> tiles(N);\n    for (int i = 0; i < N; i++) cin >> tiles[i];\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n    \n    vector<vector<int>> bestRotation(N, vector<int>(N));\n    long long bestScore = 0;\n    \n    // Phase 1: Simulated annealing with multiple starts (1.4 seconds)\n    for (int trial = 0; trial < 4; trial++) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.4) break;\n        \n        vector<vector<int>> rotation(N, vector<int>(N));\n        vector<vector<int>> current(N, vector<int>(N));\n        \n        // Different initialization patterns\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (trial == 0) rotation[i][j] = gen() % 4;\n                else if (trial == 1) rotation[i][j] = 0;\n                else if (trial == 2) rotation[i][j] = (i + j) % 4;\n                else rotation[i][j] = ((i/5) + (j/5)) % 4;\n                current[i][j] = rotateTile(tiles[i][j] - '0', rotation[i][j]);\n            }\n        }\n        \n        long long currentScore = calculateScore(current);\n        if (currentScore > bestScore) {\n            bestScore = currentScore;\n            bestRotation = rotation;\n        }\n        \n        double temp = 80.0;\n        int iterations = 0;\n        \n        while (true) {\n            iterations++;\n            if (iterations % 500 == 0) {\n                now = chrono::steady_clock::now();\n                elapsed = chrono::duration<double>(now - start).count();\n                if (elapsed > 1.4) break;\n                double progress = elapsed / 1.4;\n                temp = 80.0 * pow(0.001, progress);\n            }\n            \n            // Occasionally change 2 adjacent tiles together\n            int numChanges = (dis(gen) < 0.9) ? 1 : 2;\n            vector<tuple<int,int,int>> changes;\n            \n            int si = gen() % N, sj = gen() % N;\n            for (int c = 0; c < numChanges; c++) {\n                int i = si, j = sj;\n                if (c == 1) {\n                    // Pick adjacent tile\n                    int dir = gen() % 4;\n                    i += di[dir];\n                    j += dj[dir];\n                    if (i < 0 || i >= N || j < 0 || j >= N) continue;\n                }\n                \n                int oldRot = rotation[i][j];\n                int newRot = gen() % 4;\n                if (oldRot != newRot) {\n                    changes.push_back({i, j, oldRot});\n                    rotation[i][j] = newRot;\n                    current[i][j] = rotateTile(tiles[i][j] - '0', newRot);\n                }\n            }\n            \n            if (changes.empty()) continue;\n            \n            long long score = calculateScore(current);\n            \n            if (score > currentScore || dis(gen) < exp((score - currentScore) / temp)) {\n                currentScore = score;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestRotation = rotation;\n                }\n            } else {\n                for (auto [i, j, oldRot] : changes) {\n                    rotation[i][j] = oldRot;\n                    current[i][j] = rotateTile(tiles[i][j] - '0', oldRot);\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Intensive greedy hill climbing (remaining time)\n    auto now = chrono::steady_clock::now();\n    double elapsed = chrono::duration<double>(now - start).count();\n    \n    if (elapsed < 1.96) {\n        vector<vector<int>> current(N, vector<int>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                current[i][j] = rotateTile(tiles[i][j] - '0', bestRotation[i][j]);\n            }\n        }\n        \n        // Multiple passes until no improvement\n        bool improved = true;\n        int passes = 0;\n        while (improved && passes < 5) {\n            improved = false;\n            passes++;\n            \n            vector<pair<int,int>> positions;\n            for (int i = 0; i < N; i++)\n                for (int j = 0; j < N; j++)\n                    positions.push_back({i, j});\n            shuffle(positions.begin(), positions.end(), gen);\n            \n            for (auto [i, j] : positions) {\n                now = chrono::steady_clock::now();\n                if (chrono::duration<double>(now - start).count() > 1.97) break;\n                \n                int oldRot = bestRotation[i][j];\n                long long bestLocalScore = bestScore;\n                int bestLocalRot = oldRot;\n                \n                for (int r = 0; r < 4; r++) {\n                    if (r == oldRot) continue;\n                    current[i][j] = rotateTile(tiles[i][j] - '0', r);\n                    long long score = calculateScore(current);\n                    if (score > bestLocalScore) {\n                        bestLocalScore = score;\n                        bestLocalRot = r;\n                    }\n                }\n                \n                if (bestLocalRot != oldRot) {\n                    bestRotation[i][j] = bestLocalRot;\n                    current[i][j] = rotateTile(tiles[i][j] - '0', bestLocalRot);\n                    bestScore = bestLocalScore;\n                    improved = true;\n                } else {\n                    current[i][j] = rotateTile(tiles[i][j] - '0', oldRot);\n                }\n            }\n            \n            now = chrono::steady_clock::now();\n            if (chrono::duration<double>(now - start).count() > 1.96) break;\n        }\n    }\n    \n    string output;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            output += ('0' + bestRotation[i][j]);\n    cout << output << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> board;\nint empty_i, empty_j;\n\nvoid find_empty() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == '0') {\n                empty_i = i;\n                empty_j = j;\n                return;\n            }\n        }\n    }\n}\n\nint get_tile(int i, int j) {\n    if (i < 0 || i >= N || j < 0 || j >= N) return -1;\n    char c = board[i][j];\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\nint calculate_tree_size() {\n    vector<int> parent(N * N);\n    iota(parent.begin(), parent.end(), 0);\n    \n    function<int(int)> find = [&](int x) {\n        return parent[x] == x ? x : parent[x] = find(parent[x]);\n    };\n    \n    for (int i = 0; i < N - 1; i++) {\n        for (int j = 0; j < N; j++) {\n            int t1 = get_tile(i, j);\n            int t2 = get_tile(i + 1, j);\n            if (t1 > 0 && t2 > 0 && (t1 & 8) && (t2 & 2)) {\n                int p1 = find(i * N + j), p2 = find((i + 1) * N + j);\n                if (p1 != p2) parent[p1] = p2;\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N - 1; j++) {\n            int t1 = get_tile(i, j);\n            int t2 = get_tile(i, j + 1);\n            if (t1 > 0 && t2 > 0 && (t1 & 4) && (t2 & 1)) {\n                int p1 = find(i * N + j), p2 = find(i * N + j + 1);\n                if (p1 != p2) parent[p1] = p2;\n            }\n        }\n    }\n    \n    map<int, vector<int>> components;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (get_tile(i, j) > 0) {\n                components[find(i * N + j)].push_back(i * N + j);\n            }\n        }\n    }\n    \n    int max_tree_size = 0;\n    for (auto& [root, nodes] : components) {\n        int edges = 0;\n        for (int node : nodes) {\n            int i = node / N, j = node % N;\n            int t = get_tile(i, j);\n            if (i + 1 < N && get_tile(i+1, j) > 0 && (t & 8) && (get_tile(i+1, j) & 2) && find((i+1)*N+j) == root) edges++;\n            if (j + 1 < N && get_tile(i, j+1) > 0 && (t & 4) && (get_tile(i, j+1) & 1) && find(i*N+j+1) == root) edges++;\n        }\n        if (edges == (int)nodes.size() - 1) {\n            max_tree_size = max(max_tree_size, (int)nodes.size());\n        }\n    }\n    \n    return max_tree_size;\n}\n\nbool can_move(char dir) {\n    if (dir == 'U') return empty_i > 0;\n    if (dir == 'D') return empty_i < N - 1;\n    if (dir == 'L') return empty_j > 0;\n    if (dir == 'R') return empty_j < N - 1;\n    return false;\n}\n\nvoid make_move(char dir) {\n    int ni = empty_i, nj = empty_j;\n    if (dir == 'U') ni--;\n    else if (dir == 'D') ni++;\n    else if (dir == 'L') nj--;\n    else if (dir == 'R') nj++;\n    swap(board[empty_i][empty_j], board[ni][nj]);\n    empty_i = ni;\n    empty_j = nj;\n}\n\nchar opposite(char dir) {\n    if (dir == 'U') return 'D';\n    if (dir == 'D') return 'U';\n    if (dir == 'L') return 'R';\n    return 'L';\n}\n\nint main() {\n    cin >> N >> T;\n    board.resize(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    find_empty();\n    \n    mt19937 rng(42);\n    string moves = \"\";\n    \n    char last = ' ';\n    int no_improve = 0;\n    \n    while ((int)moves.length() < T) {\n        int current_score = calculate_tree_size();\n        if (current_score == N * N - 1) break;\n        \n        vector<char> valid;\n        for (char d : {'U','D','L','R'}) {\n            if (last != ' ' && d == opposite(last)) continue;\n            if (can_move(d)) valid.push_back(d);\n        }\n        if (valid.empty()) break;\n        \n        vector<pair<int,char>> opts;\n        for (char d : valid) {\n            auto ob = board; int oi = empty_i, oj = empty_j;\n            make_move(d);\n            opts.push_back({calculate_tree_size(), d});\n            board = ob; empty_i = oi; empty_j = oj;\n        }\n        sort(opts.rbegin(), opts.rend());\n        \n        char sel;\n        if (opts[0].first >= current_score) {\n            sel = opts[0].second;\n            no_improve = (opts[0].first == current_score) ? no_improve + 1 : 0;\n        } else {\n            if (no_improve > 30 || rng() % 100 < 10) {\n                sel = valid[rng() % valid.size()];\n                no_improve++;\n            } else {\n                no_improve++;\n                if (no_improve > 100) break;\n                continue;\n            }\n        }\n        \n        make_move(sel);\n        moves += sel;\n        last = sel;\n    }\n    \n    cout << moves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, K;\n    cin >> N >> K;\n    \n    vector<int> a(11);\n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    \n    vector<pair<int, int>> points(N);\n    for (int i = 0; i < N; i++) {\n        cin >> points[i].first >> points[i].second;\n    }\n    \n    // Sort strawberries by angle around origin\n    sort(points.begin(), points.end(), [](const auto& p1, const auto& p2) {\n        return atan2(p1.second, p1.first) < atan2(p2.second, p2.first);\n    });\n    \n    // Create priority list: (demand count, size)\n    vector<pair<int, int>> priority;\n    for (int d = 1; d <= 10; d++) {\n        if (a[d] > 0) {\n            priority.push_back({a[d], d});\n        }\n    }\n    sort(priority.rbegin(), priority.rend()); // Highest demand first\n    \n    // Greedy partitioning\n    vector<int> remaining_demand = a;\n    vector<int> partition;\n    int pos = 0;\n    \n    while (pos < N) {\n        int chosen_size = N - pos; // Default: use all remaining\n        \n        // Try to find a size with remaining demand that fits\n        for (auto [demand, size] : priority) {\n            if (remaining_demand[size] > 0 && pos + size <= N) {\n                chosen_size = size;\n                break;\n            }\n        }\n        \n        // If no good match, try any size that has demand\n        if (chosen_size > 10 || remaining_demand[chosen_size] == 0) {\n            for (int d = 10; d >= 1; d--) {\n                if (remaining_demand[d] > 0 && pos + d <= N) {\n                    chosen_size = d;\n                    break;\n                }\n            }\n        }\n        \n        // Ensure we don't exceed available strawberries\n        chosen_size = min(chosen_size, N - pos);\n        \n        partition.push_back(chosen_size);\n        if (chosen_size <= 10 && remaining_demand[chosen_size] > 0) {\n            remaining_demand[chosen_size]--;\n        }\n        pos += chosen_size;\n    }\n    \n    // Generate radial cuts between partition boundaries\n    vector<array<long long, 4>> cuts;\n    int cumulative = 0;\n    \n    for (int size : partition) {\n        cumulative += size;\n        \n        if (cumulative < N && cuts.size() < K) {\n            auto [x1, y1] = points[cumulative - 1];\n            auto [x2, y2] = points[cumulative];\n            \n            double a1 = atan2(y1, x1);\n            double a2 = atan2(y2, x2);\n            double mid = (a1 + a2) / 2.0;\n            \n            // Handle angle wrap-around (when crossing from +\u03c0 to -\u03c0)\n            if (a2 - a1 < -M_PI) {\n                mid += M_PI;\n            } else if (a2 - a1 > M_PI) {\n                mid -= M_PI;\n            }\n            \n            // Create line from origin through the midpoint angle\n            long long qx = llround(1e9 * cos(mid));\n            long long qy = llround(1e9 * sin(mid));\n            \n            cuts.push_back({0, 0, qx, qy});\n        }\n    }\n    \n    // Output\n    cout << cuts.size() << '\\n';\n    for (auto [px, py, qx, qy] : cuts) {\n        cout << px << ' ' << py << ' ' << qx << ' ' << qy << '\\n';\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <chrono>\n\nusing namespace std;\n\nint N, M;\nset<pair<int,int>> dots;\nvector<vector<int>> operations;\nset<pair<pair<int,int>, pair<int,int>>> usedUnitSegments;\n\nbool hasIntermediateDots(int x1, int y1, int x2, int y2) {\n    int dx = x2 - x1;\n    int dy = y2 - y1;\n    int g = __gcd(abs(dx), abs(dy));\n    if (g <= 1) return false;\n    \n    dx /= g;\n    dy /= g;\n    \n    for (int i = 1; i < g; i++) {\n        if (dots.count({x1 + dx * i, y1 + dy * i})) return true;\n    }\n    return false;\n}\n\nvector<pair<pair<int,int>, pair<int,int>>> getUnitSegments(int x1, int y1, int x2, int y2) {\n    vector<pair<pair<int,int>, pair<int,int>>> segments;\n    \n    int dx = x2 - x1;\n    int dy = y2 - y1;\n    int g = __gcd(abs(dx), abs(dy));\n    \n    if (g == 0) return segments;\n    \n    dx /= g;\n    dy /= g;\n    \n    for (int i = 0; i < g; i++) {\n        int ax = x1 + dx * i;\n        int ay = y1 + dy * i;\n        int bx = x1 + dx * (i + 1);\n        int by = y1 + dy * (i + 1);\n        \n        auto p1 = make_pair(ax, ay);\n        auto p2 = make_pair(bx, by);\n        if (p1 > p2) swap(p1, p2);\n        \n        segments.push_back({p1, p2});\n    }\n    \n    return segments;\n}\n\nbool isValidRectangleOrder(const vector<int>& pts) {\n    int vx1 = pts[2] - pts[0], vy1 = pts[3] - pts[1];\n    int vx2 = pts[4] - pts[2], vy2 = pts[5] - pts[3];\n    int vx3 = pts[6] - pts[4], vy3 = pts[7] - pts[5];\n    int vx4 = pts[0] - pts[6], vy4 = pts[1] - pts[7];\n    \n    if (vx1 != -vx3 || vy1 != -vy3) return false;\n    if (vx2 != -vx4 || vy2 != -vy4) return false;\n    if (vx1 * vx2 + vy1 * vy2 != 0) return false;\n    \n    bool axisAligned = (vx1 == 0 || vy1 == 0) && (vx2 == 0 || vy2 == 0);\n    bool rotated45 = (abs(vx1) == abs(vy1)) && (abs(vx2) == abs(vy2)) && vx1 != 0 && vx2 != 0;\n    \n    return axisAligned || rotated45;\n}\n\nbool tryAddDot(int x1, int y1) {\n    if (dots.count({x1, y1}) || x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) {\n        return false;\n    }\n    \n    vector<pair<int,int>> dotVec(dots.begin(), dots.end());\n    int n = dotVec.size();\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = i + 1; j < n; j++) {\n            for (int k = j + 1; k < n; k++) {\n                int x2 = dotVec[i].first, y2 = dotVec[i].second;\n                int x3 = dotVec[j].first, y3 = dotVec[j].second;\n                int x4 = dotVec[k].first, y4 = dotVec[k].second;\n                \n                vector<vector<int>> perms = {\n                    {x1, y1, x2, y2, x3, y3, x4, y4},\n                    {x1, y1, x2, y2, x4, y4, x3, y3},\n                    {x1, y1, x3, y3, x2, y2, x4, y4},\n                    {x1, y1, x3, y3, x4, y4, x2, y2},\n                    {x1, y1, x4, y4, x2, y2, x3, y3},\n                    {x1, y1, x4, y4, x3, y3, x2, y2}\n                };\n                \n                for (auto& perm : perms) {\n                    if (!isValidRectangleOrder(perm)) continue;\n                    \n                    bool valid = true;\n                    vector<pair<pair<int,int>, pair<int,int>>> allSegments;\n                    \n                    for (int e = 0; e < 4; e++) {\n                        int ex1 = perm[e*2], ey1 = perm[e*2+1];\n                        int ex2 = perm[(e*2+2)%8], ey2 = perm[(e*2+3)%8];\n                        \n                        if (hasIntermediateDots(ex1, ey1, ex2, ey2)) {\n                            valid = false;\n                            break;\n                        }\n                        \n                        auto segments = getUnitSegments(ex1, ey1, ex2, ey2);\n                        for (auto& seg : segments) {\n                            if (usedUnitSegments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                            allSegments.push_back(seg);\n                        }\n                        if (!valid) break;\n                    }\n                    \n                    if (!valid) continue;\n                    \n                    dots.insert({x1, y1});\n                    operations.push_back(perm);\n                    for (auto& seg : allSegments) {\n                        usedUnitSegments.insert(seg);\n                    }\n                    \n                    return true;\n                }\n            }\n        }\n    }\n    \n    return false;\n}\n\nint main() {\n    cin >> N >> M;\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        dots.insert({x, y});\n    }\n    \n    auto start = chrono::steady_clock::now();\n    \n    double c = (N - 1) / 2.0;\n    vector<pair<double, pair<int,int>>> candidates;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y < N; y++) {\n            if (!dots.count({x, y})) {\n                double dist = (x - c) * (x - c) + (y - c) * (y - c);\n                candidates.push_back({dist, {x, y}});\n            }\n        }\n    }\n    sort(candidates.begin(), candidates.end());\n    \n    for (int iter = 0; iter < 10; iter++) {\n        bool added = false;\n        for (auto& cand : candidates) {\n            auto now = chrono::steady_clock::now();\n            if (chrono::duration<double>(now - start).count() > 4.5) goto done;\n            \n            if (tryAddDot(cand.second.first, cand.second.second)) {\n                added = true;\n            }\n        }\n        if (!added) break;\n    }\n    \n    done:\n    cout << operations.size() << endl;\n    for (auto& op : operations) {\n        for (int i = 0; i < 8; i++) {\n            if (i > 0) cout << \" \";\n            cout << op[i];\n        }\n        cout << endl;\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nint board[N][N];\nint flavors[100];\n\nvoid tilt(int b[N][N], char dir) {\n    if (dir == 'F') {\n        for (int j = 0; j < N; j++) {\n            int pos = 0;\n            for (int i = 0; i < N; i++) {\n                if (b[i][j] > 0) {\n                    if (i != pos) {\n                        b[pos][j] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos++;\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < N; j++) {\n            int pos = N - 1;\n            for (int i = N - 1; i >= 0; i--) {\n                if (b[i][j] > 0) {\n                    if (i != pos) {\n                        b[pos][j] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos--;\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < N; i++) {\n            int pos = 0;\n            for (int j = 0; j < N; j++) {\n                if (b[i][j] > 0) {\n                    if (j != pos) {\n                        b[i][pos] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos++;\n                }\n            }\n        }\n    } else {\n        for (int i = 0; i < N; i++) {\n            int pos = N - 1;\n            for (int j = N - 1; j >= 0; j--) {\n                if (b[i][j] > 0) {\n                    if (j != pos) {\n                        b[i][pos] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos--;\n                }\n            }\n        }\n    }\n}\n\ndouble calcEvaluation(int b[N][N], int turn) {\n    bool vis[N][N] = {};\n    double score = 0;\n    \n    // Connectivity score (main objective)\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] > 0 && !vis[i][j]) {\n                int flavor = b[i][j];\n                int size = 0;\n                queue<pair<int,int>> q;\n                q.push({i, j});\n                vis[i][j] = true;\n                \n                while (!q.empty()) {\n                    auto [ci, cj] = q.front();\n                    q.pop();\n                    size++;\n                    \n                    int di[] = {-1, 1, 0, 0};\n                    int dj[] = {0, 0, -1, 1};\n                    for (int d = 0; d < 4; d++) {\n                        int ni = ci + di[d];\n                        int nj = cj + dj[d];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N &&\n                            !vis[ni][nj] && b[ni][nj] == flavor) {\n                            vis[ni][nj] = true;\n                            q.push({ni, nj});\n                        }\n                    }\n                }\n                \n                score += size * size;\n            }\n        }\n    }\n    \n    // Compactness bonus - reward keeping same flavors close together\n    double compactWeight = max(0.0, (50.0 - turn) / 50.0) * 2.0; // More important early game\n    \n    for (int f = 1; f <= 3; f++) {\n        vector<pair<int,int>> positions;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (b[i][j] == f) {\n                    positions.push_back({i, j});\n                }\n            }\n        }\n        \n        if (positions.size() > 1) {\n            // Calculate center of mass\n            double sumI = 0, sumJ = 0;\n            for (auto [i, j] : positions) {\n                sumI += i;\n                sumJ += j;\n            }\n            double avgI = sumI / positions.size();\n            double avgJ = sumJ / positions.size();\n            \n            // Calculate average distance from center\n            double totalDist = 0;\n            for (auto [i, j] : positions) {\n                totalDist += abs(i - avgI) + abs(j - avgJ);\n            }\n            \n            // Penalize spread (lower distance is better)\n            score -= totalDist * compactWeight;\n        }\n    }\n    \n    // Adjacent same-flavor bonus\n    int adjacentCount = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] > 0) {\n                if (i + 1 < N && b[i+1][j] == b[i][j]) adjacentCount++;\n                if (j + 1 < N && b[i][j+1] == b[i][j]) adjacentCount++;\n            }\n        }\n    }\n    score += adjacentCount * 5.0;\n    \n    return score;\n}\n\nchar chooseBest(int turn) {\n    char dirs[] = {'F', 'B', 'L', 'R'};\n    double best = -1e9;\n    char bestDir = 'F';\n    \n    for (char dir : dirs) {\n        int temp[N][N];\n        memcpy(temp, board, sizeof(board));\n        tilt(temp, dir);\n        double score = calcEvaluation(temp, turn);\n        \n        if (score > best) {\n            best = score;\n            bestDir = dir;\n        }\n    }\n    \n    return bestDir;\n}\n\nint main() {\n    for (int i = 0; i < 100; i++) {\n        cin >> flavors[i];\n    }\n    \n    memset(board, 0, sizeof(board));\n    \n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n        p--;\n        \n        int cnt = 0;\n        bool placed = false;\n        for (int i = 0; i < N && !placed; i++) {\n            for (int j = 0; j < N && !placed; j++) {\n                if (board[i][j] == 0) {\n                    if (cnt == p) {\n                        board[i][j] = flavors[t];\n                        placed = true;\n                    }\n                    cnt++;\n                }\n            }\n        }\n        \n        char dir = chooseBest(t);\n        cout << dir << endl;\n        cout.flush();\n        \n        tilt(board, dir);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint M;\ndouble eps;\nint N;\n\nclass Graph {\npublic:\n    int n;\n    vector<vector<int>> adj;\n    \n    Graph(int n = 0) : n(n), adj(n, vector<int>(n, 0)) {}\n    \n    string to_string() const {\n        string s;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                s += (adj[i][j] ? '1' : '0');\n            }\n        }\n        return s;\n    }\n    \n    void from_string(const string& s) {\n        int idx = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                adj[i][j] = adj[j][i] = (s[idx++] == '1');\n            }\n        }\n    }\n    \n    vector<int> get_features() const {\n        vector<int> features;\n        \n        // Edge count\n        int edges = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                edges += adj[i][j];\n            }\n        }\n        features.push_back(edges);\n        \n        // Sorted degree sequence\n        vector<int> degrees(n, 0);\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                degrees[i] += adj[i][j];\n            }\n        }\n        sort(degrees.begin(), degrees.end());\n        for (int d : degrees) features.push_back(d);\n        \n        // Triangle count\n        int triangles = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                if (!adj[i][j]) continue;\n                for (int k = j + 1; k < n; k++) {\n                    if (adj[i][k] && adj[j][k]) triangles++;\n                }\n            }\n        }\n        features.push_back(triangles);\n        \n        return features;\n    }\n};\n\nvector<Graph> graphs;\nvector<vector<int>> graph_features;\n\nint compute_distance(const vector<int>& f1, const vector<int>& f2) {\n    int dist = 0;\n    // Edge count difference (heavily weighted)\n    dist += abs(f1[0] - f2[0]) * 10;\n    \n    // Degree sequence differences\n    int n = min(f1.size(), f2.size()) - 1;\n    for (int i = 1; i < (int)n; i++) {\n        dist += abs(f1[i] - f2[i]);\n    }\n    \n    // Triangle count difference\n    dist += abs(f1.back() - f2.back()) * 5;\n    \n    return dist;\n}\n\nvoid generate_graphs() {\n    // Adaptive N selection\n    if (eps <= 0.05) {\n        N = 10;\n    } else if (eps <= 0.15) {\n        N = 15;\n    } else if (eps <= 0.25) {\n        N = 20;\n    } else if (eps <= 0.35) {\n        N = 30;\n    } else {\n        N = 40;\n    }\n    \n    // Ensure we have enough space to distinguish M graphs\n    N = max(N, (int)ceil(sqrt(2.0 * M)) + 4);\n    N = min(N, 100);\n    \n    graphs.resize(M, Graph(N));\n    \n    int max_edges = N * (N - 1) / 2;\n    \n    for (int k = 0; k < M; k++) {\n        // Linearly space edge counts\n        int target_edges = (k * max_edges) / M;\n        \n        // Add edges sequentially to create distinct patterns\n        int added = 0;\n        for (int i = 0; i < N && added < target_edges; i++) {\n            for (int j = i + 1; j < N && added < target_edges; j++) {\n                graphs[k].adj[i][j] = graphs[k].adj[j][i] = 1;\n                added++;\n            }\n        }\n    }\n    \n    // Precompute features\n    graph_features.resize(M);\n    for (int k = 0; k < M; k++) {\n        graph_features[k] = graphs[k].get_features();\n    }\n}\n\nint decode_graph(const Graph& h) {\n    auto h_features = h.get_features();\n    \n    int best = 0;\n    int min_dist = INT_MAX;\n    \n    for (int k = 0; k < M; k++) {\n        int dist = compute_distance(h_features, graph_features[k]);\n        if (dist < min_dist) {\n            min_dist = dist;\n            best = k;\n        }\n    }\n    \n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> M >> eps;\n    \n    generate_graphs();\n    \n    cout << N << \"\\n\";\n    for (const auto& g : graphs) {\n        cout << g.to_string() << \"\\n\";\n    }\n    cout.flush();\n    \n    for (int q = 0; q < 100; q++) {\n        string s;\n        cin >> s;\n        \n        Graph h(N);\n        h.from_string(s);\n        \n        int t = decode_graph(h);\n        cout << t << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long INF = 1e9;\n\nint N, M, D, K;\nvector<array<int, 3>> edges;\nvector<vector<int>> graph; // adjacency list of edge ids\nvector<int> degree;\n\nint main() {\n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    graph.resize(N);\n    degree.resize(N);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i][0] >> edges[i][1] >> edges[i][2];\n        edges[i][0]--; edges[i][1]--;\n        \n        graph[edges[i][0]].push_back(i);\n        graph[edges[i][1]].push_back(i);\n        \n        degree[edges[i][0]]++;\n        degree[edges[i][1]]++;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Calculate edge importance\n    vector<pair<double, int>> edge_scores;\n    for (int i = 0; i < M; i++) {\n        int u = edges[i][0];\n        int v = edges[i][1];\n        long long w = edges[i][2];\n        \n        // Lower degree = more critical (potential bridge)\n        double degree_factor = 1.0 / (degree[u] * degree[v]);\n        \n        // Higher weight = more impact when removed\n        double weight_factor = (double)w / 1000000.0;\n        \n        // Combined score (higher = more important)\n        double score = degree_factor * 100.0 + weight_factor;\n        \n        edge_scores.push_back({score, i});\n    }\n    \n    // Sort by importance (descending)\n    sort(edge_scores.begin(), edge_scores.end(), greater<>());\n    \n    // Greedy assignment with adjacency awareness\n    vector<int> assignment(M, 0);\n    vector<vector<int>> day_edges(D + 1);\n    vector<set<int>> day_vertices(D + 1);\n    \n    for (auto [score, eid] : edge_scores) {\n        int u = edges[eid][0];\n        int v = edges[eid][1];\n        \n        // Find best day for this edge\n        int best_day = 1;\n        int best_cost = INT_MAX;\n        \n        for (int d = 1; d <= D; d++) {\n            // Cost: number of edges + penalty for adjacent edges\n            int cost = day_edges[d].size();\n            \n            // Penalty for sharing vertices (indicates adjacent edges)\n            int vertex_penalty = 0;\n            if (day_vertices[d].count(u)) vertex_penalty += 3;\n            if (day_vertices[d].count(v)) vertex_penalty += 3;\n            \n            cost += vertex_penalty;\n            \n            if (cost < best_cost) {\n                best_cost = cost;\n                best_day = d;\n            }\n        }\n        \n        assignment[eid] = best_day;\n        day_edges[best_day].push_back(eid);\n        day_vertices[best_day].insert(u);\n        day_vertices[best_day].insert(v);\n    }\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i];\n        if (i < M - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f1, r1, f2, r2;\n\nbool isOccupied(int x, int y, int z, const vector<string>& f, const vector<string>& r) {\n    return f[z][x] == '1' && r[z][y] == '1';\n}\n\nset<tuple<int,int,int>> getComponent(tuple<int,int,int> start, \n                                      set<tuple<int,int,int>>& available) {\n    set<tuple<int,int,int>> component;\n    queue<tuple<int,int,int>> q;\n    q.push(start);\n    available.erase(start);\n    component.insert(start);\n    \n    int dx[] = {1, -1, 0, 0, 0, 0};\n    int dy[] = {0, 0, 1, -1, 0, 0};\n    int dz[] = {0, 0, 0, 0, 1, -1};\n    \n    while (!q.empty()) {\n        auto [x, y, z] = q.front();\n        q.pop();\n        \n        for (int i = 0; i < 6; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            int nz = z + dz[i];\n            auto next = make_tuple(nx, ny, nz);\n            \n            if (available.count(next)) {\n                available.erase(next);\n                component.insert(next);\n                q.push(next);\n            }\n        }\n    }\n    \n    return component;\n}\n\nint main() {\n    cin >> D;\n    f1.resize(D); r1.resize(D); f2.resize(D); r2.resize(D);\n    \n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n    \n    // Get occupied cells for both configurations\n    set<tuple<int,int,int>> occ1, occ2;\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 (isOccupied(x, y, z, f1, r1)) occ1.insert({x, y, z});\n                if (isOccupied(x, y, z, f2, r2)) occ2.insert({x, y, z});\n            }\n        }\n    }\n    \n    // Find common positions (occupied in both configs)\n    set<tuple<int,int,int>> common;\n    for (auto pos : occ1) {\n        if (occ2.count(pos)) {\n            common.insert(pos);\n        }\n    }\n    \n    // Create shared blocks from common positions\n    vector<set<tuple<int,int,int>>> sharedBlocks;\n    auto availableCommon = common;\n    while (!availableCommon.empty()) {\n        auto start = *availableCommon.begin();\n        sharedBlocks.push_back(getComponent(start, availableCommon));\n    }\n    \n    // Create unique blocks for config 1\n    set<tuple<int,int,int>> unique1;\n    for (auto pos : occ1) {\n        if (!common.count(pos)) unique1.insert(pos);\n    }\n    \n    vector<set<tuple<int,int,int>>> blocks1;\n    auto available1 = unique1;\n    while (!available1.empty()) {\n        auto start = *available1.begin();\n        blocks1.push_back(getComponent(start, available1));\n    }\n    \n    // Create unique blocks for config 2\n    set<tuple<int,int,int>> unique2;\n    for (auto pos : occ2) {\n        if (!common.count(pos)) unique2.insert(pos);\n    }\n    \n    vector<set<tuple<int,int,int>>> blocks2;\n    auto available2 = unique2;\n    while (!available2.empty()) {\n        auto start = *available2.begin();\n        blocks2.push_back(getComponent(start, available2));\n    }\n    \n    // Assign block IDs\n    vector<vector<vector<int>>> b1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> b2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    \n    int nextId = 1;\n    \n    // Assign shared blocks (used in both configurations)\n    for (auto& block : sharedBlocks) {\n        int id = nextId++;\n        for (auto [x, y, z] : block) {\n            b1[x][y][z] = id;\n            b2[x][y][z] = id;\n        }\n    }\n    \n    // Assign unique blocks for config 1\n    for (auto& block : blocks1) {\n        int id = nextId++;\n        for (auto [x, y, z] : block) {\n            b1[x][y][z] = id;\n        }\n    }\n    \n    // Assign unique blocks for config 2\n    for (auto& block : blocks2) {\n        int id = nextId++;\n        for (auto [x, y, z] : block) {\n            b2[x][y][z] = id;\n        }\n    }\n    \n    // Output\n    cout << nextId - 1 << endl;\n    \n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            for (int z = 0; z < D; z++) {\n                if (x > 0 || y > 0 || z > 0) cout << \" \";\n                cout << b1[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n    \n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            for (int z = 0; z < D; z++) {\n                if (x > 0 || y > 0 || z > 0) cout << \" \";\n                cout << b2[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<long long> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    struct Edge {\n        int u, v, id;\n        long long w;\n    };\n    \n    vector<Edge> edges(M);\n    map<pair<int,int>, int> edge_map;\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--; edges[i].v--;\n        edges[i].id = i;\n        edge_map[{min(edges[i].u, edges[i].v), max(edges[i].u, edges[i].v)}] = i;\n    }\n    \n    vector<long long> a(K), b(K);\n    for (int i = 0; i < K; i++) {\n        cin >> a[i] >> b[i];\n    }\n    \n    auto dist = [](long long x1, long long y1, long long x2, long long y2) {\n        long long dx = x1 - x2;\n        long long dy = y1 - y2;\n        return sqrt((double)(dx * dx + dy * dy));\n    };\n    \n    // Count residents closest to each vertex (for prioritization)\n    vector<int> closest_count(N, 0);\n    for (int k = 0; k < K; k++) {\n        int best_v = 0;\n        double best_d = dist(a[k], b[k], x[0], y[0]);\n        for (int i = 1; i < N; i++) {\n            double d = dist(a[k], b[k], x[i], y[i]);\n            if (d < best_d) {\n                best_d = d;\n                best_v = i;\n            }\n        }\n        closest_count[best_v]++;\n    }\n    \n    // Build MST with importance weighting\n    vector<Edge> sorted_edges = edges;\n    sort(sorted_edges.begin(), sorted_edges.end(), [&](const Edge& a, const Edge& b) {\n        // Prioritize edges to important vertices\n        double wa = (double)a.w / (1.0 + 0.1 * (closest_count[a.u] + closest_count[a.v]));\n        double wb = (double)b.w / (1.0 + 0.1 * (closest_count[b.u] + closest_count[b.v]));\n        return wa < wb;\n    });\n    \n    vector<int> parent(N);\n    iota(parent.begin(), parent.end(), 0);\n    \n    function<int(int)> find = [&](int v) {\n        return parent[v] == v ? v : parent[v] = find(parent[v]);\n    };\n    \n    set<int> active_vertices;\n    active_vertices.insert(0);\n    vector<vector<pair<int, long long>>> tree_adj(N);\n    \n    for (const Edge& e : sorted_edges) {\n        int pu = find(e.u), pv = find(e.v);\n        if (pu != pv) {\n            parent[pu] = pv;\n            active_vertices.insert(e.u);\n            active_vertices.insert(e.v);\n            tree_adj[e.u].push_back({e.v, e.w});\n            tree_adj[e.v].push_back({e.u, e.w});\n        }\n    }\n    \n    auto get_reachable = [&]() {\n        set<int> reachable;\n        queue<int> q;\n        q.push(0);\n        reachable.insert(0);\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (auto [v, w] : tree_adj[u]) {\n                if (active_vertices.count(v) && !reachable.count(v)) {\n                    reachable.insert(v);\n                    q.push(v);\n                }\n            }\n        }\n        return reachable;\n    };\n    \n    auto compute_cost = [&](const set<int>& vertices) {\n        vector<int> P(N, 0);\n        \n        for (int k = 0; k < K; k++) {\n            int best_v = -1;\n            double best_d = 1e18;\n            \n            for (int v : vertices) {\n                double d = dist(a[k], b[k], x[v], y[v]);\n                if (d < best_d) {\n                    best_d = d;\n                    best_v = v;\n                }\n            }\n            \n            if (best_v != -1) {\n                int required = min(5000, (int)ceil(best_d));\n                P[best_v] = max(P[best_v], required);\n            }\n        }\n        \n        long long cost = 0;\n        for (int v : vertices) {\n            cost += (long long)P[v] * P[v];\n        }\n        \n        return make_pair(cost, P);\n    };\n    \n    // Aggressive pruning with subtree consideration\n    for (int iter = 0; iter < 30; iter++) {\n        bool changed = false;\n        auto reachable = get_reachable();\n        \n        for (int v : vector<int>(active_vertices.begin(), active_vertices.end())) {\n            if (v == 0 || !active_vertices.count(v) || !reachable.count(v)) continue;\n            \n            // Find parent and children\n            int parent_v = -1;\n            long long parent_cost = 0;\n            vector<int> children;\n            \n            for (auto [u, w] : tree_adj[v]) {\n                if (!active_vertices.count(u)) continue;\n                \n                bool is_parent = false;\n                queue<int> bfs;\n                set<int> visited;\n                bfs.push(u);\n                visited.insert(u);\n                visited.insert(v);\n                \n                while (!bfs.empty() && !is_parent) {\n                    int cur = bfs.front();\n                    bfs.pop();\n                    if (cur == 0) {\n                        is_parent = true;\n                        break;\n                    }\n                    for (auto [nxt, _] : tree_adj[cur]) {\n                        if (active_vertices.count(nxt) && !visited.count(nxt)) {\n                            visited.insert(nxt);\n                            bfs.push(nxt);\n                        }\n                    }\n                }\n                \n                if (is_parent) {\n                    parent_v = u;\n                    parent_cost = w;\n                } else {\n                    children.push_back(u);\n                }\n            }\n            \n            // Try removing this vertex and its subtree\n            if (children.empty()) {\n                auto [old_cost, old_P] = compute_cost(reachable);\n                \n                active_vertices.erase(v);\n                auto new_reachable = get_reachable();\n                auto [new_cost, new_P] = compute_cost(new_reachable);\n                \n                if (new_cost + parent_cost < old_cost) {\n                    changed = true;\n                } else {\n                    active_vertices.insert(v);\n                }\n            }\n        }\n        \n        if (!changed) break;\n    }\n    \n    // Final assignment with exact power calculation\n    auto reachable = get_reachable();\n    vector<int> P(N, 0);\n    \n    for (int k = 0; k < K; k++) {\n        int best_v = 0;\n        double best_d = dist(a[k], b[k], x[0], y[0]);\n        \n        for (int v : reachable) {\n            double d = dist(a[k], b[k], x[v], y[v]);\n            if (d < best_d) {\n                best_d = d;\n                best_v = v;\n            }\n        }\n        \n        int required = min(5000, (int)ceil(best_d));\n        P[best_v] = max(P[best_v], required);\n    }\n    \n    // Build output\n    vector<int> edge_on(M, 0);\n    vector<bool> visited(N, false);\n    queue<int> q;\n    q.push(0);\n    visited[0] = true;\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        \n        for (auto [v, w] : tree_adj[u]) {\n            if (!visited[v] && active_vertices.count(v)) {\n                visited[v] = true;\n                q.push(v);\n                \n                auto it = edge_map.find({min(u, v), max(u, v)});\n                if (it != edge_map.end()) {\n                    edge_on[it->second] = 1;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << P[i];\n    }\n    cout << \"\\n\";\n    \n    for (int i = 0; i < M; i++) {\n        if (i > 0) cout << \" \";\n        cout << edge_on[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <tuple>\nusing namespace std;\n\nconst int N = 30;\nconst int MAX_OPS = 9900;\n\nvector<vector<int>> pyramid;\nvector<tuple<int,int,int,int>> operations;\n\nvoid swap_balls(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    operations.push_back({x1, y1, x2, y2});\n}\n\nint count_violations() {\n    int count = 0;\n    for (int x = 0; x < N-1; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) count++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) count++;\n        }\n    }\n    return count;\n}\n\nvoid sink(int x, int y) {\n    while (x < N-1 && operations.size() < MAX_OPS) {\n        int current = pyramid[x][y];\n        int left_child = pyramid[x+1][y];\n        int right_child = pyramid[x+1][y+1];\n        \n        if (current <= left_child && current <= right_child) {\n            break;\n        }\n        \n        if (left_child < right_child) {\n            swap_balls(x, y, x+1, y);\n            x++;\n        } else {\n            swap_balls(x, y, x+1, y+1);\n            x++;\n            y++;\n        }\n    }\n}\n\nvoid solve() {\n    // Phase 1: Initial heapify from bottom to top\n    for (int x = N-2; x >= 0 && operations.size() < MAX_OPS; x--) {\n        for (int y = 0; y <= x && operations.size() < MAX_OPS; y++) {\n            sink(x, y);\n        }\n    }\n    \n    // Phase 2: Fix remaining violations with multiple passes\n    for (int pass = 0; pass < 50 && operations.size() < MAX_OPS; pass++) {\n        if (count_violations() == 0) break;\n        \n        for (int x = 0; x < N-1 && operations.size() < MAX_OPS; x++) {\n            for (int y = 0; y <= x && operations.size() < MAX_OPS; y++) {\n                int current = pyramid[x][y];\n                int left_child = pyramid[x+1][y];\n                int right_child = pyramid[x+1][y+1];\n                \n                if (current > left_child || current > right_child) {\n                    sink(x, y);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    pyramid.resize(N);\n    for (int x = 0; x < N; x++) {\n        pyramid[x].resize(x+1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    solve();\n    \n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int D = 9;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\n\nint N;\nbool obstacle[D][D];\nint container[D][D];\nconst int entrance_x = 0;\nconst int entrance_y = 4;\nvector<vector<int>> dist_from_entrance;\n\nbool isValid(int x, int y) {\n    return x >= 0 && x < D && y >= 0 && y < D;\n}\n\nset<pair<int,int>> getReachable() {\n    set<pair<int,int>> reachable;\n    queue<pair<int,int>> q;\n    q.push({entrance_x, entrance_y});\n    reachable.insert({entrance_x, entrance_y});\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (isValid(nx, ny) && !obstacle[nx][ny] && \n                container[nx][ny] == -1 && \n                reachable.find({nx, ny}) == reachable.end()) {\n                reachable.insert({nx, ny});\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return reachable;\n}\n\nvoid calcDistances() {\n    dist_from_entrance.assign(D, vector<int>(D, -1));\n    queue<pair<int,int>> q;\n    q.push({entrance_x, entrance_y});\n    dist_from_entrance[entrance_x][entrance_y] = 0;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (isValid(nx, ny) && !obstacle[nx][ny] && dist_from_entrance[nx][ny] == -1) {\n                dist_from_entrance[nx][ny] = dist_from_entrance[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n}\n\nint main() {\n    int D_input;\n    cin >> D_input >> N;\n    \n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            obstacle[i][j] = false;\n            container[i][j] = -1;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        obstacle[x][y] = true;\n    }\n    \n    calcDistances();\n    \n    int max_dist = 0;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (dist_from_entrance[i][j] > max_dist) {\n                max_dist = dist_from_entrance[i][j];\n            }\n        }\n    }\n    \n    int total_containers = D * D - 1 - N;\n    \n    // Placement phase\n    for (int d = 0; d < total_containers; d++) {\n        int t;\n        cin >> t;\n        \n        set<pair<int,int>> reachable = getReachable();\n        \n        // Map container number to target distance\n        double ratio = (double)t / max(1, total_containers - 1);\n        int target_dist = 1 + (int)(ratio * (max_dist - 1));\n        \n        // Find reachable cell closest to target distance\n        pair<int,int> chosen = {-1, -1};\n        int min_diff = 1000000;\n        \n        for (auto [x, y] : reachable) {\n            if (container[x][y] == -1 && (x != entrance_x || y != entrance_y)) {\n                int cell_dist = dist_from_entrance[x][y];\n                int diff = abs(cell_dist - target_dist);\n                if (diff < min_diff || \n                    (diff == min_diff && chosen.first != -1 && \n                     cell_dist < dist_from_entrance[chosen.first][chosen.second])) {\n                    min_diff = diff;\n                    chosen = {x, y};\n                }\n            }\n        }\n        \n        container[chosen.first][chosen.second] = t;\n        cout << chosen.first << \" \" << chosen.second << endl;\n        cout.flush();\n    }\n    \n    // Retrieval phase: always pick smallest accessible\n    for (int i = 0; i < total_containers; i++) {\n        set<pair<int,int>> reachable = getReachable();\n        \n        int min_num = total_containers;\n        pair<int,int> min_pos = {-1, -1};\n        \n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (container[x][y] >= 0 && reachable.count({x, y})) {\n                    if (container[x][y] < min_num) {\n                        min_num = container[x][y];\n                        min_pos = {x, y};\n                    }\n                }\n            }\n        }\n        \n        cout << min_pos.first << \" \" << min_pos.second << endl;\n        container[min_pos.first][min_pos.second] = -1;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nvector<vector<int>> grid;\nset<pair<int,int>> required_adj;\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\n\nvoid buildAdj(vector<vector<int>>& g, set<pair<int,int>>& adj_pairs) {\n    adj_pairs.clear();\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c = g[i][j];\n            if (i == 0 || i == n-1 || j == 0 || j == n-1) {\n                if (c != 0) adj_pairs.insert({0, c});\n            }\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int nc = g[ni][nj];\n                    if (c != nc) {\n                        adj_pairs.insert({min(c, nc), max(c, nc)});\n                    }\n                }\n            }\n        }\n    }\n}\n\nbool isConnected(vector<vector<int>>& g, int color) {\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (g[i][j] == color) cells.push_back({i, j});\n        }\n    }\n    \n    if (cells.empty()) return true;\n    \n    if (color == 0) {\n        // For color 0: all cells must reach the boundary\n        set<pair<int,int>> reachable;\n        queue<pair<int,int>> bfs;\n        \n        for (auto [i, j] : cells) {\n            if (i == 0 || i == n-1 || j == 0 || j == n-1) {\n                bfs.push({i, j});\n                reachable.insert({i, j});\n            }\n        }\n        \n        while (!bfs.empty()) {\n            auto [x, y] = bfs.front();\n            bfs.pop();\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx >= 0 && nx < n && ny >= 0 && ny < n && \n                    g[nx][ny] == 0 && !reachable.count({nx, ny})) {\n                    reachable.insert({nx, ny});\n                    bfs.push({nx, ny});\n                }\n            }\n        }\n        return reachable.size() == cells.size();\n    }\n    \n    set<pair<int,int>> visited;\n    queue<pair<int,int>> bfs;\n    bfs.push(cells[0]);\n    visited.insert(cells[0]);\n    \n    while (!bfs.empty()) {\n        auto [x, y] = bfs.front();\n        bfs.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < n && ny >= 0 && ny < n && \n                g[nx][ny] == color && !visited.count({nx, ny})) {\n                visited.insert({nx, ny});\n                bfs.push({nx, ny});\n            }\n        }\n    }\n    return visited.size() == cells.size();\n}\n\nint main() {\n    cin >> n >> m;\n    grid.assign(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n        }\n    }\n    \n    buildAdj(grid, required_adj);\n    auto result = grid;\n    \n    // Iteratively try to remove cells\n    for (int iter = 0; iter < 3; iter++) {\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int i = 1; i < n-1; i++) {\n                for (int j = 1; j < n-1; j++) {\n                    if (result[i][j] == 0) continue;\n                    \n                    int color = result[i][j];\n                    result[i][j] = 0;\n                    \n                    // Quick check: is this color still connected?\n                    if (!isConnected(result, color) || !isConnected(result, 0)) {\n                        result[i][j] = color;\n                        continue;\n                    }\n                    \n                    // Check adjacencies\n                    set<pair<int,int>> new_adj;\n                    buildAdj(result, new_adj);\n                    \n                    if (new_adj == required_adj) {\n                        changed = true;\n                    } else {\n                        result[i][j] = color;\n                    }\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint query_count = 0;\n\nchar do_query(int a, int b) {\n    query_count++;\n    cout << \"1 1 \" << a << \" \" << b << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\nvoid merge(vector<int>& items, int left, int mid, int right, int query_budget) {\n    vector<int> temp;\n    int i = left, j = mid + 1;\n    \n    while(i <= mid && j <= right) {\n        if(query_count >= query_budget) {\n            // Out of queries, append in arbitrary order\n            while(i <= mid) temp.push_back(items[i++]);\n            while(j <= right) temp.push_back(items[j++]);\n            break;\n        }\n        \n        char result = do_query(items[i], items[j]);\n        if(result != '>') {\n            temp.push_back(items[i++]);\n        } else {\n            temp.push_back(items[j++]);\n        }\n    }\n    \n    while(i <= mid) temp.push_back(items[i++]);\n    while(j <= right) temp.push_back(items[j++]);\n    \n    for(int k = 0; k < temp.size(); k++) {\n        items[left + k] = temp[k];\n    }\n}\n\nvoid mergeSort(vector<int>& items, int left, int right, int query_budget) {\n    if(left >= right || query_count >= query_budget) return;\n    \n    int mid = (left + right) / 2;\n    mergeSort(items, left, mid, query_budget);\n    mergeSort(items, mid + 1, right, query_budget);\n    merge(items, left, mid, right, query_budget);\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    // Reserve some queries for dummy usage and sort with the rest\n    int query_budget = Q - 10;\n    mergeSort(items, 0, N - 1, query_budget);\n    \n    // Use all remaining queries (must use exactly Q)\n    while(query_count < Q) {\n        do_query(0, 1);\n    }\n    \n    // Assign items to groups using greedy from heaviest to lightest\n    vector<int> assignment(N);\n    vector<long long> group_weight(D, 0);\n    \n    for(int i = N-1; i >= 0; 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[items[i]] = min_group;\n        group_weight[min_group] += (N - i);\n    }\n    \n    // Output final assignment\n    for(int i = 0; i < N; i++) {\n        if(i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Simulate k future extractions and return energy cost\nint simulate_future(vector<vector<int>> stacks, int m, int start_target, int k) {\n    int energy = 0;\n    \n    for (int target = start_target; target < min(start_target + k, 201); target++) {\n        int stack_id = -1, pos = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == target) {\n                    stack_id = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (stack_id != -1) break;\n        }\n        \n        if (pos < (int)stacks[stack_id].size() - 1) {\n            int num = stacks[stack_id].size() - pos - 1;\n            energy += num + 1;\n            \n            // Use greedy heuristic for simulation\n            int best = -1;\n            for (int i = 0; i < m; i++) {\n                if (i != stack_id) {\n                    if (stacks[i].empty()) {\n                        best = i;\n                        break;\n                    }\n                    if (best == -1) best = i;\n                }\n            }\n            \n            vector<int> moved(stacks[stack_id].begin() + pos + 1, \n                            stacks[stack_id].end());\n            stacks[stack_id].resize(pos + 1);\n            for (int x : moved) stacks[best].push_back(x);\n        }\n        \n        stacks[stack_id].pop_back();\n    }\n    \n    return energy;\n}\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    \n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n/m);\n        for (int j = 0; j < n/m; j++) {\n            cin >> stacks[i][j];\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    \n    for (int target = 1; target <= n; target++) {\n        int stack_id = -1, pos = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == target) {\n                    stack_id = i;\n                    pos = j;\n                    break;\n                }\n            }\n            if (stack_id != -1) break;\n        }\n        \n        if (pos < (int)stacks[stack_id].size() - 1) {\n            vector<int> moving;\n            for (int i = pos + 1; i < (int)stacks[stack_id].size(); i++) {\n                moving.push_back(stacks[stack_id][i]);\n            }\n            int min_mov = *min_element(moving.begin(), moving.end());\n            \n            int best_dest = -1;\n            int best_cost = 1e9;\n            \n            // Try each destination and simulate\n            for (int dest = 0; dest < m; dest++) {\n                if (dest == stack_id) continue;\n                \n                auto sim = stacks;\n                sim[stack_id].resize(pos + 1);\n                for (int x : moving) sim[dest].push_back(x);\n                \n                // Immediate cost\n                int imm_cost = moving.size() + 1;\n                \n                // Future cost (simulate next 15 moves)\n                int fut_cost = simulate_future(sim, m, target + 1, 15);\n                \n                // Bonus for safe placement (no simulation needed)\n                int bonus = 0;\n                if (stacks[dest].empty()) {\n                    bonus = -50;  // Prefer empty\n                } else {\n                    int min_dest = *min_element(stacks[dest].begin(), stacks[dest].end());\n                    if (min_dest >= min_mov) {\n                        bonus = -30;  // Prefer safe\n                    }\n                }\n                \n                int total = imm_cost + fut_cost + bonus;\n                \n                if (total < best_cost) {\n                    best_cost = total;\n                    best_dest = dest;\n                }\n            }\n            \n            operations.push_back({stacks[stack_id][pos + 1], best_dest + 1});\n            \n            stacks[stack_id].resize(pos + 1);\n            for (int x : moving) {\n                stacks[best_dest].push_back(x);\n            }\n        }\n        \n        operations.push_back({target, 0});\n        stacks[stack_id].pop_back();\n    }\n    \n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\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;\n\nconst int di[] = {0, 1, 0, -1};\nconst int dj[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir];\n    int nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    if (dir == 0) return v[i][j] == '0';\n    else if (dir == 1) return h[i][j] == '0';\n    else if (dir == 2) return v[i][j-1] == '0';\n    else return h[i-1][j] == '0';\n}\n\nstring find_path(int si, int sj, int ti, int tj) {\n    if (si == ti && sj == tj) return \"\";\n    \n    vector<vector<int>> dist(N, vector<int>(N, -1));\n    vector<vector<int>> parent_dir(N, vector<int>(N, -1));\n    queue<pair<int, int>> q;\n    \n    q.push({si, sj});\n    dist[si][sj] = 0;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            \n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            \n            if (dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                parent_dir[ni][nj] = dir;\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    if (dist[ti][tj] == -1) return \"\";\n    \n    string path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        int dir = parent_dir[ci][cj];\n        path += dir_char[dir];\n        ci -= di[dir];\n        cj -= dj[dir];\n    }\n    \n    reverse(path.begin(), path.end());\n    return path;\n}\n\nstring build_tour() {\n    const int MAX_LEN = 99000;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    string route;\n    \n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        \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 + di[dir];\n            int nj = j + dj[dir];\n            if (!visited[ni][nj]) {\n                neighbors.push_back({-d[ni][nj], dir});\n            }\n        }\n        \n        sort(neighbors.begin(), neighbors.end());\n        \n        for (auto [_, dir] : neighbors) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            \n            if (!visited[ni][nj]) {\n                route += dir_char[dir];\n                dfs(ni, nj);\n                route += dir_char[(dir + 2) % 4];\n            }\n        }\n    };\n    \n    dfs(0, 0);\n    \n    // Add extra visits to high-value cells\n    vector<tuple<int, int, int>> cells;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cells.push_back({d[i][j], i, j});\n        }\n    }\n    sort(cells.rbegin(), cells.rend());\n    \n    int ci = 0, cj = 0;\n    for (auto [dval, ti, tj] : cells) {\n        if (route.length() >= MAX_LEN) break;\n        \n        string path1 = find_path(ci, cj, ti, tj);\n        string path2 = find_path(ti, tj, ci, cj);\n        \n        int cost = path1.length() + path2.length();\n        if (route.length() + cost <= MAX_LEN) {\n            route += path1 + path2;\n        }\n    }\n    \n    // Return to origin\n    route += find_path(ci, cj, 0, 0);\n    \n    return route;\n}\n\nint main() {\n    cin >> N;\n    \n    h.resize(N-1);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    \n    v.resize(N);\n    for (int i = 0; i < N; i++) cin >> v[i];\n    \n    d.resize(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> d[i][j];\n        }\n    }\n    \n    cout << build_tour() << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint si, sj;\nvector<string> grid;\nvector<string> targets;\nmap<char, vector<pair<int,int>>> char_positions;\n\nint overlap(const string& s1, const string& s2) {\n    int maxLen = min((int)s1.length(), (int)s2.length());\n    for (int len = maxLen; len >= 1; len--) {\n        if (s1.substr(s1.length() - len) == s2.substr(0, len)) {\n            return len;\n        }\n    }\n    return 0;\n}\n\nbool contains(const string& s, const string& target) {\n    return s.find(target) != string::npos;\n}\n\nbool checkComplete(const string& s) {\n    for (const auto& t : targets) {\n        if (!contains(s, t)) return false;\n    }\n    return true;\n}\n\npair<int,int> findClosest(char c, int curI, int curJ) {\n    auto& positions = char_positions[c];\n    int bestDist = INT_MAX;\n    pair<int,int> best = positions[0];\n    \n    for (auto& pos : positions) {\n        int dist = abs(pos.first - curI) + abs(pos.second - curJ);\n        if (dist < bestDist) {\n            bestDist = dist;\n            best = pos;\n        }\n    }\n    return best;\n}\n\npair<int,int> findBestPosition(char c, int curI, int curJ, const string& text, int pos) {\n    auto& positions = char_positions[c];\n    if (positions.size() == 1) return positions[0];\n    \n    int bestScore = INT_MAX;\n    pair<int,int> best = positions[0];\n    int lookAhead = min(8, (int)text.length() - pos - 1);\n    \n    for (auto& p : positions) {\n        int score = abs(p.first - curI) + abs(p.second - curJ);\n        \n        int tmpI = p.first, tmpJ = p.second;\n        for (int i = 1; i <= lookAhead; i++) {\n            auto nextPos = findClosest(text[pos + i], tmpI, tmpJ);\n            score += abs(nextPos.first - tmpI) + abs(nextPos.second - tmpJ);\n            tmpI = nextPos.first;\n            tmpJ = nextPos.second;\n        }\n        \n        if (score < bestScore) {\n            bestScore = score;\n            best = p;\n        }\n    }\n    return best;\n}\n\nint calculateCost(const string& text) {\n    int cost = 0;\n    int curI = si, curJ = sj;\n    \n    for (char c : text) {\n        auto pos = findClosest(c, curI, curJ);\n        cost += abs(pos.first - curI) + abs(pos.second - curJ) + 1;\n        curI = pos.first;\n        curJ = pos.second;\n    }\n    return cost;\n}\n\nstring greedyConstruct(int startIdx, const vector<vector<int>>& ovl) {\n    vector<bool> used(M, false);\n    string result = targets[startIdx];\n    used[startIdx] = true;\n    int current = startIdx;\n    \n    while (true) {\n        for (int i = 0; i < M; i++) {\n            if (!used[i] && contains(result, targets[i])) {\n                used[i] = true;\n            }\n        }\n        \n        int bestNext = -1;\n        int bestScore = -1;\n        \n        for (int i = 0; i < M; i++) {\n            if (used[i]) continue;\n            int score = ovl[current][i];\n            if (score > bestScore) {\n                bestScore = score;\n                bestNext = i;\n            }\n        }\n        \n        if (bestNext == -1) break;\n        \n        int o = ovl[current][bestNext];\n        if (o > 0) {\n            result += targets[bestNext].substr(o);\n        } else {\n            result += targets[bestNext];\n        }\n        \n        used[bestNext] = true;\n        current = bestNext;\n    }\n    \n    return result;\n}\n\nstring greedyBidirectional(int startIdx, const vector<vector<int>>& ovl) {\n    vector<bool> used(M, false);\n    string left = \"\", right = targets[startIdx];\n    used[startIdx] = true;\n    int leftIdx = -1, rightIdx = startIdx;\n    \n    for (int iter = 1; iter < M; iter++) {\n        string current = left + right;\n        for (int i = 0; i < M; i++) {\n            if (!used[i] && contains(current, targets[i])) {\n                used[i] = true;\n            }\n        }\n        \n        int bestRight = -1, scoreRight = -1;\n        if (rightIdx != -1) {\n            for (int i = 0; i < M; i++) {\n                if (!used[i] && ovl[rightIdx][i] > scoreRight) {\n                    scoreRight = ovl[rightIdx][i];\n                    bestRight = i;\n                }\n            }\n        }\n        \n        int bestLeft = -1, scoreLeft = -1;\n        if (leftIdx != -1) {\n            for (int i = 0; i < M; i++) {\n                if (!used[i] && ovl[i][leftIdx] > scoreLeft) {\n                    scoreLeft = ovl[i][leftIdx];\n                    bestLeft = i;\n                }\n            }\n        } else {\n            for (int i = 0; i < M; i++) {\n                if (!used[i] && ovl[i][startIdx] > scoreLeft) {\n                    scoreLeft = ovl[i][startIdx];\n                    bestLeft = i;\n                }\n            }\n        }\n        \n        if (bestRight == -1 && bestLeft == -1) break;\n        \n        if (scoreRight >= scoreLeft && bestRight != -1) {\n            int o = ovl[rightIdx][bestRight];\n            right += (o > 0) ? targets[bestRight].substr(o) : targets[bestRight];\n            used[bestRight] = true;\n            rightIdx = bestRight;\n        } else if (bestLeft != -1) {\n            int baseIdx = (leftIdx == -1) ? startIdx : leftIdx;\n            int o = ovl[bestLeft][baseIdx];\n            left = (o > 0) ? targets[bestLeft].substr(0, targets[bestLeft].length() - o) + left \n                           : targets[bestLeft] + left;\n            used[bestLeft] = true;\n            leftIdx = bestLeft;\n        }\n    }\n    \n    return left + right;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> si >> sj;\n    \n    grid.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    targets.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i];\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            char_positions[grid[i][j]].push_back({i, j});\n        }\n    }\n    \n    vector<vector<int>> ovl(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) {\n                ovl[i][j] = overlap(targets[i], targets[j]);\n            }\n        }\n    }\n    \n    vector<pair<int,int>> candidates;\n    for (int i = 0; i < M; i++) {\n        int total = 0;\n        for (int j = 0; j < M; j++) {\n            total += ovl[i][j] + ovl[j][i];\n        }\n        candidates.push_back({total, i});\n    }\n    sort(candidates.rbegin(), candidates.rend());\n    \n    string bestResult;\n    int bestCost = INT_MAX;\n    \n    // Try forward greedy\n    for (int t = 0; t < min(30, M); t++) {\n        string result = greedyConstruct(candidates[t].second, ovl);\n        if (checkComplete(result)) {\n            int cost = calculateCost(result);\n            if (cost < bestCost) {\n                bestCost = cost;\n                bestResult = result;\n            }\n        }\n    }\n    \n    // Try bidirectional\n    for (int t = 0; t < min(15, M); t++) {\n        string result = greedyBidirectional(candidates[t].second, ovl);\n        if (checkComplete(result)) {\n            int cost = calculateCost(result);\n            if (cost < bestCost) {\n                bestCost = cost;\n                bestResult = result;\n            }\n        }\n    }\n    \n    if (bestResult.empty()) {\n        bestResult = greedyConstruct(0, ovl);\n    }\n    \n    int curI = si, curJ = sj;\n    for (int i = 0; i < bestResult.length(); i++) {\n        auto pos = findBestPosition(bestResult[i], curI, curJ, bestResult, i);\n        cout << pos.first << \" \" << pos.second << \"\\n\";\n        curI = pos.first;\n        curJ = pos.second;\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>>> fields;\nint query_count = 0;\n\nint query(const vector<pair<int,int>>& cells) {\n    cout << \"q \" << cells.size();\n    for (auto [i, j] : cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    query_count++;\n    \n    int result;\n    cin >> result;\n    return result;\n}\n\nint drill(int i, int j) {\n    return query({{i, j}});\n}\n\nbool answer(const set<pair<int,int>>& cells) {\n    cout << \"a \" << cells.size();\n    for (auto [i, j] : cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    int result;\n    cin >> result;\n    return result == 1;\n}\n\nint main() {\n    cin >> N >> M >> eps;\n    fields.resize(M);\n    \n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        fields[k].resize(d);\n        for (int i = 0; i < d; i++) {\n            cin >> fields[k][i].first >> fields[k][i].second;\n        }\n    }\n    \n    vector<vector<double>> estimate(N, vector<double>(N, 0.0));\n    vector<vector<int>> drilled(N, vector<int>(N, -1));\n    \n    // Phase 1: Query entire grid multiple times for baseline\n    double total = 0;\n    int num_full = 30;\n    for (int q = 0; q < num_full; q++) {\n        vector<pair<int,int>> all;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                all.push_back({i, j});\n            }\n        }\n        total += query(all);\n    }\n    double avg_per_cell = total / (num_full * N * N);\n    \n    // Phase 2: Query rows and columns\n    vector<double> row_est(N), col_est(N);\n    for (int i = 0; i < N; i++) {\n        vector<pair<int,int>> row;\n        for (int j = 0; j < N; j++) row.push_back({i, j});\n        row_est[i] = query(row) / (double)N;\n    }\n    \n    for (int j = 0; j < N; j++) {\n        vector<pair<int,int>> col;\n        for (int i = 0; i < N; i++) col.push_back({i, j});\n        col_est[j] = query(col) / (double)N;\n    }\n    \n    // Combine estimates\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            estimate[i][j] = (row_est[i] + col_est[j]) / 2.0;\n        }\n    }\n    \n    // Phase 3: Query smaller blocks for refinement\n    int block_size = max(2, N/3);\n    for (int bi = 0; bi < N; bi += block_size) {\n        for (int bj = 0; bj < N; bj += block_size) {\n            vector<pair<int,int>> block;\n            for (int i = bi; i < min(N, bi+block_size); i++) {\n                for (int j = bj; j < min(N, bj+block_size); j++) {\n                    block.push_back({i, j});\n                }\n            }\n            if (block.size() >= 2) {\n                double block_avg = query(block) / (double)block.size();\n                for (auto [i, j] : block) {\n                    estimate[i][j] = (estimate[i][j] + block_avg) / 2.0;\n                }\n            }\n        }\n    }\n    \n    // Phase 4: Drill uncertain squares\n    set<pair<int,int>> has_oil;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (estimate[i][j] > 0.4 || query_count >= 600) {\n                int v = drill(i, j);\n                drilled[i][j] = v;\n                if (v > 0) has_oil.insert({i, j});\n            }\n        }\n    }\n    \n    // Make answer\n    if (!answer(has_oil)) {\n        // If wrong, drill remaining squares\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (drilled[i][j] < 0) {\n                    int v = drill(i, j);\n                    if (v > 0) has_oil.insert({i, j});\n                }\n            }\n        }\n        answer(has_oil);\n    }\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\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    auto compute_layout = [&](const vector<int>& areas) {\n        vector<int> heights(N);\n        int total_height = 0;\n        \n        for (int k = 0; k < N; k++) {\n            heights[k] = max(1, (areas[k] + W - 1) / W);\n            total_height += heights[k];\n        }\n        \n        vector<int> row_pos(N + 1);\n        row_pos[0] = 0;\n        \n        if (total_height <= W) {\n            for (int k = 0; k < N; k++) {\n                row_pos[k + 1] = row_pos[k] + heights[k];\n            }\n        } else {\n            long long cumsum = 0;\n            for (int k = 0; k < N; k++) {\n                cumsum += heights[k];\n                row_pos[k + 1] = (int)((cumsum * W) / total_height);\n            }\n        }\n        \n        row_pos[N] = W;\n        \n        for (int k = 0; k < N; k++) {\n            if (row_pos[k + 1] <= row_pos[k]) {\n                row_pos[k + 1] = row_pos[k] + 1;\n            }\n        }\n        \n        return row_pos;\n    };\n    \n    auto calc_shortage = [&](const vector<int>& layout, const vector<int>& areas) {\n        long long shortage = 0;\n        for (int k = 0; k < N; k++) {\n            int area = (layout[k + 1] - layout[k]) * W;\n            if (area < areas[k]) {\n                shortage += areas[k] - area;\n            }\n        }\n        return shortage;\n    };\n    \n    auto calc_partition_cost = [&](const vector<int>& layout1, const vector<int>& layout2) {\n        int cost = 0;\n        for (int i = 1; i < N; i++) {\n            if (layout1[i] != layout2[i]) {\n                cost += W;  // horizontal line of length W changed\n            }\n        }\n        return cost;\n    };\n    \n    vector<vector<int>> layouts(D);\n    \n    // Day 0: compute optimal layout\n    layouts[0] = compute_layout(a[0]);\n    \n    // Days 1+: decide whether to reuse or change\n    for (int d = 1; d < D; d++) {\n        vector<int> new_layout = compute_layout(a[d]);\n        \n        long long reuse_shortage = calc_shortage(layouts[d - 1], a[d]);\n        long long new_shortage = calc_shortage(new_layout, a[d]);\n        long long partition_cost = calc_partition_cost(layouts[d - 1], new_layout);\n        \n        long long reuse_cost = 100 * reuse_shortage;\n        long long new_cost = 100 * new_shortage + partition_cost;\n        \n        if (reuse_cost <= new_cost) {\n            layouts[d] = layouts[d - 1];\n        } else {\n            layouts[d] = new_layout;\n        }\n    }\n    \n    // Output\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << layouts[d][k] << \" 0 \" << layouts[d][k + 1] << \" \" << W << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353LL;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nlong long board[N][N];\nlong long stamps[M][3][3];\n\ndouble evaluate_stamp_score(int m, int p, int q, int operation_num) {\n    double score = 0.0;\n    int wraparounds = 0;\n    double total_gap_reduction = 0.0;\n    \n    double progress = (double)operation_num / K;\n    \n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            int row = p + i;\n            int col = q + j;\n            long long remainder = board[row][col] % MOD;\n            long long stamp_val = stamps[m][i][j];\n            long long new_remainder = (remainder + stamp_val) % MOD;\n            long long improvement = new_remainder - remainder;\n            \n            // Calculate gaps from MOD-1\n            long long gap_before = (MOD - 1) - remainder;\n            long long gap_after = (MOD - 1) - new_remainder;\n            \n            double cell_score = (double)improvement;\n            \n            if (remainder + stamp_val < MOD) {\n                // No wraparound - this is the ideal case\n                double gap_ratio = (double)gap_before / (double)MOD;\n                \n                // Strongly boost operations that fill large gaps\n                if (gap_ratio > 0.6) {\n                    cell_score *= 1.8;\n                } else if (gap_ratio > 0.4) {\n                    cell_score *= 1.5;\n                } else if (gap_ratio > 0.25) {\n                    cell_score *= 1.3;\n                } else if (gap_ratio > 0.1) {\n                    cell_score *= 1.15;\n                }\n                \n                // Track gap reduction\n                total_gap_reduction += (gap_before - gap_after);\n            } else {\n                // Wraparound occurred\n                wraparounds++;\n                \n                // Penalty depends on progress and how close we were to MOD\n                double proximity_to_mod = (double)remainder / (double)MOD;\n                \n                if (progress < 0.4) {\n                    // Early stage: avoid wraparounds on cells far from MOD\n                    if (proximity_to_mod < 0.8) {\n                        cell_score *= 0.25;\n                    } else {\n                        cell_score *= 0.5;\n                    }\n                } else if (progress < 0.7) {\n                    // Middle stage: moderate penalty\n                    cell_score *= 0.6;\n                } else {\n                    // Late stage: lighter penalty (might need to use remaining ops)\n                    cell_score *= 0.75;\n                }\n            }\n            \n            score += cell_score;\n        }\n    }\n    \n    // Bonus for significant gap reduction across the 3x3 region\n    if (total_gap_reduction > 0) {\n        double gap_bonus = min(0.2, total_gap_reduction / (9.0 * MOD));\n        score *= (1.0 + gap_bonus);\n    }\n    \n    // Progressive penalty for wraparounds\n    if (wraparounds >= 7) {\n        score *= 0.4;\n    } else if (wraparounds >= 5) {\n        score *= 0.65;\n    } else if (wraparounds >= 3) {\n        score *= 0.85;\n    }\n    \n    return score;\n}\n\nvoid apply_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            board[p + i][q + j] += stamps[m][i][j];\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 < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    for (int stamp = 0; stamp < M; stamp++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[stamp][i][j];\n            }\n        }\n    }\n    \n    vector<tuple<int, int, int>> operations;\n    \n    for (int op = 0; op < K; op++) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        double best_score = -1e18;\n        \n        for (int stamp = 0; stamp < M; stamp++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    double score = evaluate_stamp_score(stamp, p, q, op);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_m = stamp;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // Only stop if score is extremely negative\n        if (best_score < -MOD * 2.0) {\n            break;\n        }\n        \n        apply_stamp(best_m, best_p, best_q);\n        operations.push_back({best_m, best_p, best_q});\n    }\n    \n    cout << operations.size() << endl;\n    for (auto [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << endl;\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N];\n\nstruct State {\n    int grid[N][N];\n    pair<int,int> crane_pos[N];\n    int crane_carry[N];\n    int next_container[N];\n    \n    State() {\n        memset(grid, -1, sizeof(grid));\n        for (int i = 0; i < N; i++) {\n            crane_pos[i] = {i, 0};\n            crane_carry[i] = -1;\n            next_container[i] = 0;\n        }\n    }\n    \n    int target_row(int container) {\n        return container / N;\n    }\n    \n    void place_containers() {\n        for (int i = 0; i < N; i++) {\n            if (next_container[i] < N && grid[i][0] == -1) {\n                bool blocked = false;\n                for (int c = 0; c < N; c++) {\n                    if (crane_pos[c] == make_pair(i, 0) && crane_carry[c] != -1) {\n                        blocked = true;\n                    }\n                }\n                if (!blocked) {\n                    grid[i][0] = A[i][next_container[i]];\n                    next_container[i]++;\n                }\n            }\n        }\n    }\n    \n    void dispatch_containers() {\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                grid[i][N-1] = -1;\n            }\n        }\n    }\n    \n    void apply_action(int crane_id, char action) {\n        auto& pos = crane_pos[crane_id];\n        \n        if (action == 'P') {\n            crane_carry[crane_id] = grid[pos.first][pos.second];\n            grid[pos.first][pos.second] = -1;\n        } else if (action == 'Q') {\n            grid[pos.first][pos.second] = crane_carry[crane_id];\n            crane_carry[crane_id] = -1;\n        } else if (action == 'U') {\n            pos.first--;\n        } else if (action == 'D') {\n            pos.first++;\n        } else if (action == 'L') {\n            pos.second--;\n        } else if (action == 'R') {\n            pos.second++;\n        }\n    }\n};\n\nint main() {\n    int n;\n    cin >> n;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    State state;\n    vector<string> commands(N);\n    \n    for (int turn = 0; turn < 1000; turn++) {\n        state.place_containers();\n        \n        vector<char> actions(N, '.');\n        \n        for (int i = 0; i < N; i++) {\n            auto [r, c] = state.crane_pos[i];\n            \n            if (state.crane_carry[i] == -1) {\n                // Not carrying\n                if (state.grid[r][c] != -1) {\n                    actions[i] = 'P';\n                } else if (c > 0) {\n                    actions[i] = 'L';\n                }\n            } else {\n                // Carrying container\n                int container = state.crane_carry[i];\n                int target_r = state.target_row(container);\n                \n                if (r != target_r) {\n                    // Move to correct row first\n                    actions[i] = (r < target_r) ? 'D' : 'U';\n                } else if (c < N-1) {\n                    // Move right to dispatch gate\n                    actions[i] = 'R';\n                } else {\n                    // At dispatch gate, release\n                    actions[i] = 'Q';\n                }\n            }\n        }\n        \n        // Apply actions\n        for (int i = 0; i < N; i++) {\n            commands[i] += actions[i];\n            state.apply_action(i, actions[i]);\n        }\n        \n        state.dispatch_containers();\n        \n        // Check if done\n        bool done = true;\n        for (int i = 0; i < N; i++) {\n            if (state.next_container[i] < N || state.crane_carry[i] != -1) {\n                done = false;\n            }\n        }\n        if (done) {\n            bool has_containers = false;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (state.grid[i][j] != -1) has_containers = true;\n                }\n            }\n            if (!has_containers) break;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << commands[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<vector<int>> h;\nvector<string> operations;\nint cur_r = 0, cur_c = 0;\nint load = 0;\n\nint manhattan(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\nvoid moveTo(int tr, int tc) {\n    while (cur_r < tr && operations.size() < 99000) {\n        operations.push_back(\"D\");\n        cur_r++;\n    }\n    while (cur_r > tr && operations.size() < 99000) {\n        operations.push_back(\"U\");\n        cur_r--;\n    }\n    while (cur_c < tc && operations.size() < 99000) {\n        operations.push_back(\"R\");\n        cur_c++;\n    }\n    while (cur_c > tc && operations.size() < 99000) {\n        operations.push_back(\"L\");\n        cur_c--;\n    }\n}\n\nint main() {\n    cin >> N;\n    h.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n        }\n    }\n    \n    // Greedy nearest-neighbor approach (version 2 with minor improvement)\n    while (operations.size() < 95000) {\n        // Find nearest positive cell from current position\n        int pos_r = -1, pos_c = -1;\n        int min_dist = INT_MAX;\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 = manhattan(cur_r, cur_c, i, j);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        pos_r = i;\n                        pos_c = j;\n                    }\n                }\n            }\n        }\n        \n        if (pos_r == -1) break; // No more positive cells\n        \n        // Move to and load from positive cell\n        moveTo(pos_r, pos_c);\n        if (operations.size() >= 95000) break;\n        \n        int load_amt = h[pos_r][pos_c];\n        operations.push_back(\"+\" + to_string(load_amt));\n        load += load_amt;\n        h[pos_r][pos_c] = 0;\n        \n        // Distribute load to nearest negative cells\n        // Prefer cells that can take more load to reduce stops\n        while (load > 0 && operations.size() < 95000) {\n            int neg_r = -1, neg_c = -1;\n            int best_score = INT_MAX;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (h[i][j] < 0) {\n                        int dist = manhattan(cur_r, cur_c, i, j);\n                        int can_deliver = min(load, -h[i][j]);\n                        // Score: prefer closer cells, but also prefer cells that take more\n                        // Multiply distance by 100 to give priority to amount delivered\n                        int score = dist * 100 - can_deliver;\n                        \n                        if (score < best_score) {\n                            best_score = score;\n                            neg_r = i;\n                            neg_c = j;\n                        }\n                    }\n                }\n            }\n            \n            if (neg_r == -1) break; // No more negative cells\n            \n            // Move to and unload at negative cell\n            moveTo(neg_r, neg_c);\n            if (operations.size() >= 95000) break;\n            \n            int unload_amt = min(load, -h[neg_r][neg_c]);\n            operations.push_back(\"-\" + to_string(unload_amt));\n            load -= unload_amt;\n            h[neg_r][neg_c] += unload_amt;\n        }\n    }\n    \n    for (const auto& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <set>\n#include <map>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> X(seed_count, vector<int>(M));\n    \n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> X[i][j];\n        }\n    }\n    \n    for (int t = 0; t < T; t++) {\n        // Find max for each criterion\n        vector<int> max_val(M, 0);\n        for (int l = 0; l < M; l++) {\n            for (int i = 0; i < seed_count; i++) {\n                max_val[l] = max(max_val[l], X[i][l]);\n            }\n        }\n        \n        // Count near-champions for each criterion (rarity analysis)\n        vector<int> near_max_count(M, 0);\n        for (int l = 0; l < M; l++) {\n            int threshold = max_val[l] * 88 / 100; // 88% threshold\n            for (int i = 0; i < seed_count; i++) {\n                if (X[i][l] >= threshold) {\n                    near_max_count[l]++;\n                }\n            }\n        }\n        \n        // Must-include: top 2 for each criterion (redundancy)\n        set<int> must_include;\n        for (int l = 0; l < M; l++) {\n            vector<pair<int, int>> vals;\n            for (int i = 0; i < seed_count; i++) {\n                vals.push_back({X[i][l], i});\n            }\n            sort(vals.rbegin(), vals.rend());\n            for (int i = 0; i < min(3, (int)vals.size()); i++) {\n                must_include.insert(vals[i].second);\n            }\n        }\n        \n        // Score remaining seeds\n        vector<pair<double, int>> seed_scores;\n        for (int i = 0; i < seed_count; i++) {\n            if (must_include.count(i)) continue;\n            \n            int total = accumulate(X[i].begin(), X[i].end(), 0);\n            double score = total;\n            \n            // Bonus for rare excellence\n            for (int l = 0; l < M; l++) {\n                if (max_val[l] > 0 && X[i][l] >= max_val[l] * 88 / 100) {\n                    // Higher bonus if this criterion is rare\n                    if (near_max_count[l] <= 5) {\n                        score += 500.0 / near_max_count[l];\n                    } else {\n                        score += 100.0;\n                    }\n                }\n            }\n            \n            seed_scores.push_back({score, i});\n        }\n        sort(seed_scores.rbegin(), seed_scores.rend());\n        \n        // Combine must-include and scored seeds\n        set<int> selected;\n        for (int s : must_include) {\n            selected.insert(s);\n        }\n        for (auto [score, s] : seed_scores) {\n            if (selected.size() >= N * N) break;\n            selected.insert(s);\n        }\n        \n        // Convert to vector and sort by total value\n        vector<int> selected_vec(selected.begin(), selected.end());\n        sort(selected_vec.begin(), selected_vec.end(), [&](int a, int b) {\n            int val_a = accumulate(X[a].begin(), X[a].end(), 0);\n            int val_b = accumulate(X[b].begin(), X[b].end(), 0);\n            return val_a > val_b;\n        });\n        \n        // Position priority: center positions get most breeding opportunities\n        vector<pair<int, pair<int, int>>> positions;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int neighbors = 0;\n                if (i > 0) neighbors++;\n                if (i < N-1) neighbors++;\n                if (j > 0) neighbors++;\n                if (j < N-1) neighbors++;\n                // Slightly prefer actual center\n                int dist_to_center = abs(i - N/2) + abs(j - N/2);\n                positions.push_back({neighbors * 100 - dist_to_center, {i, j}});\n            }\n        }\n        sort(positions.rbegin(), positions.rend());\n        \n        // Place seeds\n        vector<vector<int>> A(N, vector<int>(N));\n        for (int idx = 0; idx < N * N; idx++) {\n            A[positions[idx].second.first][positions[idx].second.second] = selected_vec[idx];\n        }\n        \n        // Output\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << A[i][j];\n                if (j < N - 1) cout << \" \";\n                else cout << endl;\n            }\n        }\n        cout.flush();\n        \n        // Read new seeds\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    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<vector<int>> grid_current;\nvector<vector<int>> grid_target;\n\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\n\nstruct State {\n    int root_x, root_y;\n    int num_v;\n    vector<int> parent;\n    vector<int> length;\n    vector<bool> is_leaf;\n    vector<bool> holding;\n    \n    vector<pair<int,int>> get_positions() {\n        vector<pair<int,int>> pos(num_v);\n        pos[0] = {root_x, root_y};\n        for (int i = 1; i < num_v; i++) {\n            int p = parent[i];\n            pos[i] = {pos[p].first + dx[0] * length[i], \n                     pos[p].second + dy[0] * length[i]};\n        }\n        return pos;\n    }\n    \n    string make_command(char move, vector<char> rots, vector<char> actions) {\n        string s(2 * num_v, '.');\n        s[0] = move;\n        for (int i = 1; i < num_v; i++) {\n            s[i] = rots[i-1];\n        }\n        for (int i = 0; i < num_v; i++) {\n            s[num_v + i] = actions[i];\n        }\n        return s;\n    }\n};\n\nint main() {\n    cin >> N >> M >> V;\n    \n    grid_current.resize(N, vector<int>(N, 0));\n    grid_target.resize(N, vector<int>(N, 0));\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            if (s[j] == '1') {\n                grid_current[i][j] = 1;\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            if (s[j] == '1') {\n                grid_target[i][j] = 1;\n            }\n        }\n    }\n    \n    State state;\n    state.num_v = 2;\n    state.parent = {-1, 0};\n    state.length = {0, 1};\n    state.is_leaf = {false, true};\n    state.holding.resize(state.num_v, false);\n    state.root_x = 0;\n    state.root_y = 0;\n    \n    cout << state.num_v << endl;\n    for (int i = 1; i < state.num_v; i++) {\n        cout << state.parent[i] << \" \" << state.length[i] << endl;\n    }\n    cout << state.root_x << \" \" << state.root_y << endl;\n    \n    vector<string> commands;\n    int leaf = 1;\n    \n    while (commands.size() < 90000) {\n        auto pos = state.get_positions();\n        \n        if (!state.holding[leaf]) {\n            // Find a takoyaki not at its target position\n            pair<int,int> best_src = {-1, -1};\n            int min_dist = INT_MAX;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    // Pick only takoyaki that are NOT at target positions\n                    if (grid_current[i][j] == 1 && grid_target[i][j] == 0) {\n                        int d = abs(pos[leaf].first - i) + abs(pos[leaf].second - j);\n                        if (d < min_dist) {\n                            min_dist = d;\n                            best_src = {i, j};\n                        }\n                    }\n                }\n            }\n            \n            if (best_src.first == -1) break; // No more takoyaki to move\n            \n            // Move to source\n            while (pos[leaf] != best_src && commands.size() < 90000) {\n                char move = '.';\n                \n                if (pos[leaf].first < best_src.first && state.root_x + 1 < N) {\n                    move = 'D';\n                    state.root_x++;\n                } else if (pos[leaf].first > best_src.first && state.root_x > 0) {\n                    move = 'U';\n                    state.root_x--;\n                } else if (pos[leaf].second < best_src.second && state.root_y + 1 < N) {\n                    move = 'R';\n                    state.root_y++;\n                } else if (pos[leaf].second > best_src.second && state.root_y > 0) {\n                    move = 'L';\n                    state.root_y--;\n                }\n                \n                commands.push_back(state.make_command(move, vector<char>(state.num_v-1, '.'), vector<char>(state.num_v, '.')));\n                pos = state.get_positions();\n            }\n            \n            // Pick up if at correct position and takoyaki exists\n            if (pos[leaf] == best_src && grid_current[best_src.first][best_src.second] == 1) {\n                vector<char> actions(state.num_v, '.');\n                actions[leaf] = 'P';\n                commands.push_back(state.make_command('.', vector<char>(state.num_v-1, '.'), actions));\n                state.holding[leaf] = true;\n                grid_current[best_src.first][best_src.second] = 0;\n            }\n        } else {\n            // Find empty target position\n            pair<int,int> best_tgt = {-1, -1};\n            int min_dist = INT_MAX;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    // Place only on empty target positions\n                    if (grid_target[i][j] == 1 && grid_current[i][j] == 0) {\n                        int d = abs(pos[leaf].first - i) + abs(pos[leaf].second - j);\n                        if (d < min_dist) {\n                            min_dist = d;\n                            best_tgt = {i, j};\n                        }\n                    }\n                }\n            }\n            \n            if (best_tgt.first == -1) break; // No more empty targets\n            \n            // Move to target\n            while (pos[leaf] != best_tgt && commands.size() < 90000) {\n                char move = '.';\n                \n                if (pos[leaf].first < best_tgt.first && state.root_x + 1 < N) {\n                    move = 'D';\n                    state.root_x++;\n                } else if (pos[leaf].first > best_tgt.first && state.root_x > 0) {\n                    move = 'U';\n                    state.root_x--;\n                } else if (pos[leaf].second < best_tgt.second && state.root_y + 1 < N) {\n                    move = 'R';\n                    state.root_y++;\n                } else if (pos[leaf].second > best_tgt.second && state.root_y > 0) {\n                    move = 'L';\n                    state.root_y--;\n                }\n                \n                commands.push_back(state.make_command(move, vector<char>(state.num_v-1, '.'), vector<char>(state.num_v, '.')));\n                pos = state.get_positions();\n            }\n            \n            // Place if at correct position and target is empty\n            if (pos[leaf] == best_tgt && grid_current[best_tgt.first][best_tgt.second] == 0) {\n                vector<char> actions(state.num_v, '.');\n                actions[leaf] = 'P';\n                commands.push_back(state.make_command('.', vector<char>(state.num_v-1, '.'), actions));\n                state.holding[leaf] = false;\n                grid_current[best_tgt.first][best_tgt.second] = 1;\n            }\n        }\n    }\n    \n    for (const auto& cmd : commands) {\n        cout << cmd << endl;\n    }\n    \n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint N;\nvector<pair<int,int>> mackerels, sardines;\n\nint calcScore(int x1, int y1, int x2, int y2) {\n    if (x1 > x2) swap(x1, x2);\n    if (y1 > y2) swap(y1, y2);\n    \n    int mac = 0, sar = 0;\n    for (auto [x, y] : mackerels) {\n        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) mac++;\n    }\n    for (auto [x, y] : sardines) {\n        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) sar++;\n    }\n    return mac - sar;\n}\n\nvoid tryUpdate(int x1, int y1, int x2, int y2, int& bestScore, int& bx1, int& by1, int& bx2, int& by2) {\n    int score = calcScore(x1, y1, x2, y2);\n    if (score > bestScore) {\n        bestScore = score;\n        bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n    }\n}\n\nvoid localSearch(int& bx1, int& by1, int& bx2, int& by2, int& bestScore, const vector<int>& deltas) {\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        \n        for (int delta : deltas) {\n            int nx1 = max(0, min(100000, bx1 + delta));\n            if (nx1 != bx1) {\n                int score = calcScore(nx1, by1, bx2, by2);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bx1 = nx1;\n                    improved = true;\n                }\n            }\n            \n            int nx2 = max(0, min(100000, bx2 + delta));\n            if (nx2 != bx2) {\n                int score = calcScore(bx1, by1, nx2, by2);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bx2 = nx2;\n                    improved = true;\n                }\n            }\n            \n            int ny1 = max(0, min(100000, by1 + delta));\n            if (ny1 != by1) {\n                int score = calcScore(bx1, ny1, bx2, by2);\n                if (score > bestScore) {\n                    bestScore = score;\n                    by1 = ny1;\n                    improved = true;\n                }\n            }\n            \n            int ny2 = max(0, min(100000, by2 + delta));\n            if (ny2 != by2) {\n                int score = calcScore(bx1, by1, bx2, ny2);\n                if (score > bestScore) {\n                    bestScore = score;\n                    by2 = ny2;\n                    improved = true;\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    cin >> N;\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        mackerels.push_back({x, y});\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        sardines.push_back({x, y});\n    }\n    \n    int bestScore = 0;\n    int bx1 = 0, by1 = 0, bx2 = 100000, by2 = 100000;\n    \n    mt19937 rng(20240101);\n    uniform_int_distribution<int> dist(0, N-1);\n    \n    // Strategy 1: Systematic grid search for good starting regions\n    for (int gx = 10000; gx <= 90000; gx += 20000) {\n        for (int gy = 10000; gy <= 90000; gy += 20000) {\n            for (int sz : {5000, 10000, 15000, 20000}) {\n                int x1 = max(0, gx - sz);\n                int y1 = max(0, gy - sz);\n                int x2 = min(100000, gx + sz);\n                int y2 = min(100000, gy + sz);\n                \n                tryUpdate(x1, y1, x2, y2, bestScore, bx1, by1, bx2, by2);\n            }\n        }\n    }\n    \n    // Strategy 2: Multi-scale rectangles centered on mackerels\n    vector<int> scales = {1000, 2000, 3000, 4000, 5000, 7000, 9000, 12000, 15000, 18000, 22000, 27000};\n    for (int iter = 0; iter < 150; iter++) {\n        int idx = dist(rng);\n        auto [cx, cy] = mackerels[idx];\n        \n        for (int sz : scales) {\n            int x1 = max(0, cx - sz);\n            int y1 = max(0, cy - sz);\n            int x2 = min(100000, cx + sz);\n            int y2 = min(100000, cy + sz);\n            \n            tryUpdate(x1, y1, x2, y2, bestScore, bx1, by1, bx2, by2);\n        }\n    }\n    \n    // Strategy 3: Rectangles from pairs of mackerels (corners)\n    for (int iter = 0; iter < 500; iter++) {\n        int i = dist(rng);\n        int j = dist(rng);\n        \n        tryUpdate(mackerels[i].first, mackerels[i].second, \n                 mackerels[j].first, mackerels[j].second,\n                 bestScore, bx1, by1, bx2, by2);\n    }\n    \n    // Strategy 4: Bounding boxes of random subsets\n    uniform_int_distribution<int> subset_size(5, 100);\n    for (int iter = 0; iter < 100; iter++) {\n        int k = subset_size(rng);\n        int minX = 100000, maxX = 0, minY = 100000, maxY = 0;\n        \n        for (int j = 0; j < k; j++) {\n            int idx = dist(rng);\n            auto [x, y] = mackerels[idx];\n            minX = min(minX, x);\n            maxX = max(maxX, x);\n            minY = min(minY, y);\n            maxY = max(maxY, y);\n        }\n        \n        // Try the bounding box and slight expansions/contractions\n        for (int margin : {-3000, -1000, 0, 1000, 3000}) {\n            int x1 = max(0, minX + margin);\n            int x2 = min(100000, maxX - margin);\n            int y1 = max(0, minY + margin);\n            int y2 = min(100000, maxY - margin);\n            \n            tryUpdate(x1, y1, x2, y2, bestScore, bx1, by1, bx2, by2);\n        }\n    }\n    \n    // Strategy 5: Asymmetric rectangles (different offsets in each direction)\n    uniform_int_distribution<int> size_dist(1000, 25000);\n    for (int iter = 0; iter < 150; iter++) {\n        int idx = dist(rng);\n        auto [cx, cy] = mackerels[idx];\n        \n        int dx1 = size_dist(rng);\n        int dx2 = size_dist(rng);\n        int dy1 = size_dist(rng);\n        int dy2 = size_dist(rng);\n        \n        int x1 = max(0, cx - dx1);\n        int x2 = min(100000, cx + dx2);\n        int y1 = max(0, cy - dy1);\n        int y2 = min(100000, cy + dy2);\n        \n        tryUpdate(x1, y1, x2, y2, bestScore, bx1, by1, bx2, by2);\n    }\n    \n    // Multi-stage local search: coarse to fine\n    vector<int> coarse_deltas = {-10000, -5000, -2000, 2000, 5000, 10000};\n    localSearch(bx1, by1, bx2, by2, bestScore, coarse_deltas);\n    \n    vector<int> medium_deltas = {-1000, -500, -200, 200, 500, 1000};\n    localSearch(bx1, by1, bx2, by2, bestScore, medium_deltas);\n    \n    vector<int> fine_deltas = {-100, -50, -20, -10, -5, -1, 1, 5, 10, 20, 50, 100};\n    localSearch(bx1, by1, bx2, by2, bestScore, fine_deltas);\n    \n    if (bx1 > bx2) swap(bx1, bx2);\n    if (by1 > by2) swap(by1, by2);\n    \n    cout << 4 << endl;\n    cout << bx1 << \" \" << by1 << endl;\n    cout << bx2 << \" \" << by1 << endl;\n    cout << bx2 << \" \" << by2 << endl;\n    cout << bx1 << \" \" << by2 << endl;\n    \n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, T;\n    long long sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<pair<long long, long long>> rects(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].first >> rects[i].second;\n    }\n    \n    mt19937 rng(42);\n    \n    for (int turn = 0; turn < T; turn++) {\n        cout << N << endl;\n        \n        // Estimate dimensions as we place rectangles\n        long long est_w = 0, est_h = 0;\n        \n        for (int i = 0; i < N; i++) {\n            long long w = rects[i].first;\n            long long h = rects[i].second;\n            \n            int r = 0;\n            char d;\n            int b;\n            \n            if (i == 0) {\n                // First rectangle at origin\n                r = (h > w) ? 1 : 0;\n                if (r) swap(w, h);\n                d = 'U';\n                b = -1;\n                est_w = w;\n                est_h = h;\n            } else {\n                // Choose strategy based on turn\n                int strategy = turn % 6;\n                \n                switch (strategy) {\n                    case 0: // Horizontal layout - minimize height\n                        r = (h > w) ? 1 : 0;\n                        if (r) swap(w, h);\n                        d = 'U';\n                        b = i - 1;\n                        est_w += w;\n                        est_h = max(est_h, h);\n                        break;\n                        \n                    case 1: // Vertical layout - minimize width\n                        r = (w > h) ? 1 : 0;\n                        if (r) swap(w, h);\n                        d = 'L';\n                        b = -1;\n                        est_h += h;\n                        est_w = max(est_w, w);\n                        break;\n                        \n                    case 2: // Balanced - keep W \u2248 H\n                        if (est_w < est_h) {\n                            // Box is taller, extend width\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            // Box is wider, extend height\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 3: // Grid pattern\n                        if (i % 3 == 1) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = (i >= 2) ? i - 2 : -1;\n                        }\n                        break;\n                        \n                    case 4: // Alternating\n                        if (i % 2 == 1) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                        }\n                        break;\n                        \n                    default: // Random\n                        r = uniform_int_distribution<>(0, 1)(rng);\n                        if (r) swap(w, h);\n                        d = (uniform_int_distribution<>(0, 1)(rng) ? 'U' : 'L');\n                        b = uniform_int_distribution<>(-1, i - 1)(rng);\n                        break;\n                }\n            }\n            \n            cout << i << \" \" << r << \" \" << d << \" \" << b << endl;\n        }\n        cout.flush();\n        \n        long long W, H;\n        cin >> W >> H;\n    }\n    \n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n\nusing namespace std;\n\nint N, M, H;\nvector<int> A;\nvector<vector<int>> adj;\nvector<int> parent;\nvector<bool> assigned;\n\n// Aggressive DFS that prioritizes depth\nvoid dfs(int u, int depth, vector<int>& path) {\n    path.push_back(u);\n    \n    if (depth >= H) {\n        path.pop_back();\n        return;\n    }\n    \n    // Collect unassigned neighbors\n    vector<int> neighbors;\n    for (int v : adj[u]) {\n        if (!assigned[v]) {\n            neighbors.push_back(v);\n        }\n    }\n    \n    // Sort by beauty descending\n    sort(neighbors.begin(), neighbors.end(), [](int a, int b) {\n        return A[a] > A[b];\n    });\n    \n    // Process highest beauty neighbor first with full depth\n    for (int v : neighbors) {\n        if (!assigned[v]) {\n            assigned[v] = true;\n            parent[v] = u;\n            dfs(v, depth + 1, path);\n        }\n    }\n    \n    path.pop_back();\n}\n\n// Evaluate how good a root candidate is\ndouble evaluate_root(int root) {\n    // BFS to find reachable high-beauty vertices\n    set<int> reachable;\n    vector<int> queue = {root};\n    reachable.insert(root);\n    \n    for (int dist = 0; dist < H && !queue.empty(); dist++) {\n        vector<int> next_queue;\n        for (int u : queue) {\n            for (int v : adj[u]) {\n                if (!assigned[v] && reachable.find(v) == reachable.end()) {\n                    reachable.insert(v);\n                    next_queue.push_back(v);\n                }\n            }\n        }\n        queue = next_queue;\n    }\n    \n    // Calculate potential\n    double potential = 0;\n    for (int v : reachable) {\n        if (v != root) {\n            potential += A[v];\n        }\n    }\n    \n    // Prefer low beauty roots with high potential\n    return A[root] * 150.0 - potential;\n}\n\nint main() {\n    cin >> N >> M >> H;\n    \n    A.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> A[i];\n    }\n    \n    adj.resize(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    parent.resize(N, -1);\n    assigned.resize(N, false);\n    \n    // Build trees greedily\n    while (true) {\n        int root = -1;\n        double best_score = 1e9;\n        \n        // Evaluate all unassigned vertices as potential roots\n        for (int i = 0; i < N; i++) {\n            if (!assigned[i]) {\n                double score = evaluate_root(i);\n                if (root == -1 || score < best_score) {\n                    root = i;\n                    best_score = score;\n                }\n            }\n        }\n        \n        if (root == -1) break;\n        \n        assigned[root] = true;\n        parent[root] = -1;\n        vector<int> path;\n        dfs(root, 0, path);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << parent[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    vector<pair<char, int>> moves;\n    vector<vector<bool>> removed(N, vector<bool>(N, false));\n    \n    // Find all Oni positions\n    vector<pair<int,int>> oni_positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 'x') {\n                oni_positions.push_back({i, j});\n            }\n        }\n    }\n    \n    // Helper functions to check safe directions\n    auto can_remove_up = [&](int i, int j) {\n        for (int ii = 0; ii < i; ii++) {\n            if (board[ii][j] == 'o') return false;\n        }\n        return true;\n    };\n    \n    auto can_remove_down = [&](int i, int j) {\n        for (int ii = i + 1; ii < N; ii++) {\n            if (board[ii][j] == 'o') return false;\n        }\n        return true;\n    };\n    \n    auto can_remove_left = [&](int i, int j) {\n        for (int jj = 0; jj < j; jj++) {\n            if (board[i][jj] == 'o') return false;\n        }\n        return true;\n    };\n    \n    auto can_remove_right = [&](int i, int j) {\n        for (int jj = j + 1; jj < N; jj++) {\n            if (board[i][jj] == 'o') return false;\n        }\n        return true;\n    };\n    \n    auto count_safe_dirs = [&](int i, int j) {\n        int cnt = 0;\n        if (can_remove_up(i, j)) cnt++;\n        if (can_remove_down(i, j)) cnt++;\n        if (can_remove_left(i, j)) cnt++;\n        if (can_remove_right(i, j)) cnt++;\n        return cnt;\n    };\n    \n    // Greedy: prioritize constrained Oni, then maximize efficiency\n    while (true) {\n        double best_score = -1;\n        char best_dir = ' ';\n        int best_pos = -1;\n        vector<pair<int,int>> best_targets;\n        int best_cost = 0;\n        int best_min_dirs = 5; // Track minimum flexibility in batch\n        \n        // Try all columns for upward removal\n        for (int j = 0; j < N; j++) {\n            int max_dist = 0;\n            vector<pair<int,int>> targets;\n            int min_dirs = 5;\n            for (auto [i, jj] : oni_positions) {\n                if (jj == j && !removed[i][jj] && can_remove_up(i, jj)) {\n                    targets.push_back({i, jj});\n                    max_dist = max(max_dist, i + 1);\n                    min_dirs = min(min_dirs, count_safe_dirs(i, jj));\n                }\n            }\n            if (!targets.empty()) {\n                int cost = 2 * max_dist;\n                double score = (double)targets.size() / cost;\n                // Prioritize: 1) constrained Oni (fewer safe directions), 2) better efficiency\n                if (min_dirs < best_min_dirs || (min_dirs == best_min_dirs && score > best_score)) {\n                    best_score = score;\n                    best_dir = 'U';\n                    best_pos = j;\n                    best_targets = targets;\n                    best_cost = cost;\n                    best_min_dirs = min_dirs;\n                }\n            }\n        }\n        \n        // Try all columns for downward removal\n        for (int j = 0; j < N; j++) {\n            int max_dist = 0;\n            vector<pair<int,int>> targets;\n            int min_dirs = 5;\n            for (auto [i, jj] : oni_positions) {\n                if (jj == j && !removed[i][jj] && can_remove_down(i, jj)) {\n                    targets.push_back({i, jj});\n                    max_dist = max(max_dist, N - i);\n                    min_dirs = min(min_dirs, count_safe_dirs(i, jj));\n                }\n            }\n            if (!targets.empty()) {\n                int cost = 2 * max_dist;\n                double score = (double)targets.size() / cost;\n                if (min_dirs < best_min_dirs || (min_dirs == best_min_dirs && score > best_score)) {\n                    best_score = score;\n                    best_dir = 'D';\n                    best_pos = j;\n                    best_targets = targets;\n                    best_cost = cost;\n                    best_min_dirs = min_dirs;\n                }\n            }\n        }\n        \n        // Try all rows for leftward removal\n        for (int i = 0; i < N; i++) {\n            int max_dist = 0;\n            vector<pair<int,int>> targets;\n            int min_dirs = 5;\n            for (auto [ii, j] : oni_positions) {\n                if (ii == i && !removed[ii][j] && can_remove_left(ii, j)) {\n                    targets.push_back({ii, j});\n                    max_dist = max(max_dist, j + 1);\n                    min_dirs = min(min_dirs, count_safe_dirs(ii, j));\n                }\n            }\n            if (!targets.empty()) {\n                int cost = 2 * max_dist;\n                double score = (double)targets.size() / cost;\n                if (min_dirs < best_min_dirs || (min_dirs == best_min_dirs && score > best_score)) {\n                    best_score = score;\n                    best_dir = 'L';\n                    best_pos = i;\n                    best_targets = targets;\n                    best_cost = cost;\n                    best_min_dirs = min_dirs;\n                }\n            }\n        }\n        \n        // Try all rows for rightward removal\n        for (int i = 0; i < N; i++) {\n            int max_dist = 0;\n            vector<pair<int,int>> targets;\n            int min_dirs = 5;\n            for (auto [ii, j] : oni_positions) {\n                if (ii == i && !removed[ii][j] && can_remove_right(ii, j)) {\n                    targets.push_back({ii, j});\n                    max_dist = max(max_dist, N - j);\n                    min_dirs = min(min_dirs, count_safe_dirs(ii, j));\n                }\n            }\n            if (!targets.empty()) {\n                int cost = 2 * max_dist;\n                double score = (double)targets.size() / cost;\n                if (min_dirs < best_min_dirs || (min_dirs == best_min_dirs && score > best_score)) {\n                    best_score = score;\n                    best_dir = 'R';\n                    best_pos = i;\n                    best_targets = targets;\n                    best_cost = cost;\n                    best_min_dirs = min_dirs;\n                }\n            }\n        }\n        \n        if (best_targets.empty()) break;\n        \n        // Execute best operation\n        int dist = best_cost / 2;\n        for (int t = 0; t < dist; t++) {\n            moves.push_back({best_dir, best_pos});\n        }\n        char reverse = (best_dir == 'U') ? 'D' : (best_dir == 'D') ? 'U' : (best_dir == 'L') ? 'R' : 'L';\n        for (int t = 0; t < dist; t++) {\n            moves.push_back({reverse, best_pos});\n        }\n        \n        // Mark as removed\n        for (auto [i, j] : best_targets) {\n            removed[i][j] = true;\n        }\n    }\n    \n    // Output moves\n    for (auto [dir, pos] : moves) {\n        cout << dir << \" \" << pos << endl;\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, L;\nvector<int> T;\n\nlong long simulate(const vector<int>& a, const vector<int>& b, vector<int>& count) {\n    count.assign(N, 0);\n    int current = 0;\n    count[0] = 1;\n    \n    for (int week = 1; week < L; week++) {\n        int t = count[current];\n        if (t & 1) {\n            current = a[current];\n        } else {\n            current = b[current];\n        }\n        count[current]++;\n    }\n    \n    long long error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(count[i] - T[i]);\n    }\n    return error;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> L;\n    T.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    mt19937 gen(19937);\n    uniform_int_distribution<> dist_n(0, N-1);\n    \n    // Proper weighted distribution based on targets\n    vector<double> weights(N);\n    for (int i = 0; i < N; i++) {\n        weights[i] = T[i] + 1.0;\n    }\n    discrete_distribution<> weighted_dist(weights.begin(), weights.end());\n    \n    vector<int> best_a(N), best_b(N);\n    long long best_error = LLONG_MAX;\n    vector<int> count(N);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    double time_limit = 1.85;\n    \n    while (true) {\n        auto current_time = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed > time_limit) break;\n        \n        // Initialize with weighted distribution\n        vector<int> a(N), b(N);\n        for (int i = 0; i < N; i++) {\n            a[i] = weighted_dist(gen);\n            b[i] = weighted_dist(gen);\n        }\n        \n        long long error = simulate(a, b, count);\n        \n        // Hill climbing with multiple strategies\n        int no_improve = 0;\n        \n        while (no_improve < 3000) {\n            current_time = chrono::high_resolution_clock::now();\n            elapsed = chrono::duration<double>(current_time - start_time).count();\n            if (elapsed > time_limit) break;\n            \n            // Choose modification strategy\n            int strategy = gen() % 4;\n            \n            int i, new_val;\n            bool modify_a = gen() % 2;\n            int old_val;\n            \n            if (strategy == 0) {\n                // Weighted random\n                i = dist_n(gen);\n                new_val = weighted_dist(gen);\n            } else if (strategy == 1) {\n                // Target fix: redirect from over-assigned to under-assigned\n                int max_over = -1, max_over_diff = 0;\n                int max_under = -1, max_under_diff = 0;\n                \n                for (int j = 0; j < N; j++) {\n                    if (count[j] > T[j] && count[j] - T[j] > max_over_diff) {\n                        max_over_diff = count[j] - T[j];\n                        max_over = j;\n                    }\n                    if (T[j] > count[j] && T[j] - count[j] > max_under_diff) {\n                        max_under_diff = T[j] - count[j];\n                        max_under = j;\n                    }\n                }\n                \n                if (max_over >= 0 && max_under >= 0) {\n                    i = max_over;\n                    new_val = max_under;\n                } else {\n                    i = dist_n(gen);\n                    new_val = weighted_dist(gen);\n                }\n            } else if (strategy == 2) {\n                // Random employee pointing to under-assigned\n                i = dist_n(gen);\n                int max_under = -1, max_under_diff = 0;\n                for (int j = 0; j < N; j++) {\n                    if (T[j] > count[j] && T[j] - count[j] > max_under_diff) {\n                        max_under_diff = T[j] - count[j];\n                        max_under = j;\n                    }\n                }\n                new_val = (max_under >= 0) ? max_under : weighted_dist(gen);\n            } else {\n                // Uniform random for diversity\n                i = dist_n(gen);\n                new_val = dist_n(gen);\n            }\n            \n            old_val = modify_a ? a[i] : b[i];\n            \n            if (modify_a) {\n                a[i] = new_val;\n            } else {\n                b[i] = new_val;\n            }\n            \n            long long new_error = simulate(a, b, count);\n            \n            if (new_error < error) {\n                error = new_error;\n                no_improve = 0;\n                \n                if (error < best_error) {\n                    best_error = error;\n                    best_a = a;\n                    best_b = b;\n                }\n            } else {\n                if (modify_a) {\n                    a[i] = old_val;\n                } else {\n                    b[i] = old_val;\n                }\n                no_improve++;\n            }\n        }\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 <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent;\npublic:\n    UnionFind(int n) : parent(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        parent[px] = py;\n        return true;\n    }\n    \n    bool connected(int x, int y) {\n        return find(x) == find(y);\n    }\n};\n\nlong long morton_code(int x, int y) {\n    long long z = 0;\n    for (int i = 0; i < 20; i++) {\n        z |= ((long long)((x >> i) & 1) << (2 * i + 1));\n        z |= ((long long)((y >> i) & 1) << (2 * i));\n    }\n    return z;\n}\n\ndouble dist_sq(pair<double, double> a, pair<double, double> b) {\n    double dx = a.first - b.first;\n    double dy = a.second - b.second;\n    return dx * dx + dy * dy;\n}\n\nvector<int> reorder_by_proximity(vector<int>& cities, vector<pair<double, double>>& pos) {\n    int n = cities.size();\n    if (n <= 2) return cities;\n    \n    vector<bool> used(n, false);\n    vector<int> result;\n    result.reserve(n);\n    \n    result.push_back(cities[0]);\n    used[0] = true;\n    \n    for (int i = 1; i < n; i++) {\n        int last_city = result.back();\n        int best_idx = -1;\n        double best_dist = 1e18;\n        \n        for (int j = 0; j < n; j++) {\n            if (!used[j]) {\n                double d = dist_sq(pos[last_city], pos[cities[j]]);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = j;\n                }\n            }\n        }\n        \n        result.push_back(cities[best_idx]);\n        used[best_idx] = true;\n    }\n    \n    return result;\n}\n\nint main() {\n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<pair<double, double>> pos(N);\n    for (int i = 0; i < N; i++) {\n        int lx, rx, ly, ry;\n        cin >> lx >> rx >> ly >> ry;\n        pos[i] = {(lx + rx) / 2.0, (ly + ry) / 2.0};\n    }\n    \n    // Z-order sorting\n    vector<int> order(N);\n    for (int i = 0; i < N; i++) order[i] = i;\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        int xa = (int)pos[a].first, ya = (int)pos[a].second;\n        int xb = (int)pos[b].first, yb = (int)pos[b].second;\n        return morton_code(xa, ya) < morton_code(xb, yb);\n    });\n    \n    // Create and reorder groups\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < G[i]; j++) {\n            groups[i].push_back(order[idx++]);\n        }\n        groups[i] = reorder_by_proximity(groups[i], pos);\n    }\n    \n    // Allocate queries based on group sizes\n    vector<int> queries_per_group(M, 0);\n    int budget = Q;\n    for (int i = 0; i < M; i++) {\n        if (G[i] <= 1) continue;\n        if (G[i] <= L) {\n            queries_per_group[i] = 1;\n            budget--;\n        }\n    }\n    \n    // Distribute remaining budget to large groups\n    for (int i = 0; i < M && budget > 0; i++) {\n        if (G[i] > L) {\n            int needed = (G[i] + L - 1) / (L / 2);\n            int allocated = min(needed, budget);\n            queries_per_group[i] = allocated;\n            budget -= allocated;\n        }\n    }\n    \n    vector<vector<pair<int, int>>> edges(M);\n    \n    for (int k = 0; k < M; k++) {\n        if (G[k] == 1) continue;\n        \n        set<pair<int, int>> candidate_edges;\n        \n        if (G[k] <= L) {\n            // Single query for exact MST\n            cout << \"? \" << G[k];\n            for (int c : groups[k]) cout << \" \" << c;\n            cout << endl;\n            cout.flush();\n            \n            for (int i = 0; i < G[k] - 1; i++) {\n                int u, v;\n                cin >> u >> v;\n                if (u > v) swap(u, v);\n                candidate_edges.insert({u, v});\n            }\n        } else if (queries_per_group[k] > 0) {\n            // Anchor-based queries for better coverage\n            int num_queries = queries_per_group[k];\n            int spacing = max(1, G[k] / (num_queries + 1));\n            \n            for (int q = 0; q < num_queries; q++) {\n                int anchor = min((q + 1) * spacing, G[k] - 1);\n                int start = max(0, anchor - L/2);\n                int end = min(G[k], start + L);\n                start = max(0, end - L);\n                int sz = end - start;\n                \n                if (sz < 2) continue;\n                \n                cout << \"? \" << sz;\n                for (int j = start; j < end; j++) {\n                    cout << \" \" << groups[k][j];\n                }\n                cout << endl;\n                cout.flush();\n                \n                for (int j = 0; j < sz - 1; j++) {\n                    int u, v;\n                    cin >> u >> v;\n                    if (u > v) swap(u, v);\n                    candidate_edges.insert({u, v});\n                }\n            }\n        }\n        \n        // Build spanning tree\n        UnionFind uf(N);\n        for (auto [u, v] : candidate_edges) {\n            if (uf.unite(u, v)) {\n                edges[k].push_back({u, v});\n            }\n        }\n        \n        // Hybrid fallback: try nearby pairs first, then all pairs\n        vector<pair<double, pair<int, int>>> fallback_edges;\n        for (int i = 0; i < G[k]; i++) {\n            for (int j = i + 1; j < G[k]; j++) {\n                int u = groups[k][i], v = groups[k][j];\n                if (!uf.connected(u, v)) {\n                    double d = dist_sq(pos[u], pos[v]);\n                    fallback_edges.push_back({d, {u, v}});\n                }\n            }\n        }\n        \n        sort(fallback_edges.begin(), fallback_edges.end());\n        \n        for (auto [d, edge] : fallback_edges) {\n            if ((int)edges[k].size() >= G[k] - 1) break;\n            auto [u, v] = edge;\n            if (uf.unite(u, v)) {\n                edges[k].push_back({u, v});\n            }\n        }\n    }\n    \n    // Output\n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int c : groups[k]) cout << c << \" \";\n        cout << endl;\n        for (auto [u, v] : edges[k]) {\n            cout << u << \" \" << v << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\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    int cur_r = targets[0].first;\n    int cur_c = targets[0].second;\n    \n    vector<pair<string, string>> actions;\n    \n    auto add = [&](string act, string dir) {\n        actions.push_back({act, dir});\n    };\n    \n    // Visit each target in order\n    for (int i = 1; i < M; i++) {\n        int target_r = targets[i].first;\n        int target_c = targets[i].second;\n        \n        // Move vertically with edge slide optimization\n        if (cur_r != target_r) {\n            int move_cost = abs(target_r - cur_r);\n            int slide_cost = INT_MAX;\n            \n            if (target_r > cur_r) {\n                // Moving down: try sliding to bottom edge\n                int edge = N - 1;\n                slide_cost = 1 + (edge - target_r);\n            } else {\n                // Moving up: try sliding to top edge\n                int edge = 0;\n                slide_cost = 1 + (target_r - edge);\n            }\n            \n            if (slide_cost < move_cost) {\n                // Use slide to edge\n                if (target_r > cur_r) {\n                    add(\"S\", \"D\");\n                    cur_r = N - 1;\n                } else {\n                    add(\"S\", \"U\");\n                    cur_r = 0;\n                }\n            }\n            \n            // Move remaining distance\n            while (cur_r != target_r) {\n                if (cur_r < target_r) {\n                    add(\"M\", \"D\");\n                    cur_r++;\n                } else {\n                    add(\"M\", \"U\");\n                    cur_r--;\n                }\n            }\n        }\n        \n        // Move horizontally with edge slide optimization\n        if (cur_c != target_c) {\n            int move_cost = abs(target_c - cur_c);\n            int slide_cost = INT_MAX;\n            \n            if (target_c > cur_c) {\n                // Moving right: try sliding to right edge\n                int edge = N - 1;\n                slide_cost = 1 + (edge - target_c);\n            } else {\n                // Moving left: try sliding to left edge\n                int edge = 0;\n                slide_cost = 1 + (target_c - edge);\n            }\n            \n            if (slide_cost < move_cost) {\n                // Use slide to edge\n                if (target_c > cur_c) {\n                    add(\"S\", \"R\");\n                    cur_c = N - 1;\n                } else {\n                    add(\"S\", \"L\");\n                    cur_c = 0;\n                }\n            }\n            \n            // Move remaining distance\n            while (cur_c != target_c) {\n                if (cur_c < target_c) {\n                    add(\"M\", \"R\");\n                    cur_c++;\n                } else {\n                    add(\"M\", \"L\");\n                    cur_c--;\n                }\n            }\n        }\n    }\n    \n    for (auto& [act, dir] : actions) {\n        cout << act << \" \" << dir << \"\\n\";\n    }\n    \n    return 0;\n}"},"8":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> x, y;\nvector<long long> r;\nvector<array<int, 4>> result;\n\ndouble calc_satisfaction(long long area, long long desired) {\n    double ratio = (double)min(area, desired) / max(area, desired);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\nvoid solve(vector<int> ids, int x1, int y1, int x2, int y2) {\n    if (ids.empty()) return;\n    \n    if (ids.size() == 1) {\n        result[ids[0]] = {x1, y1, x2, y2};\n        return;\n    }\n    \n    long long total_r = 0;\n    for (int id : ids) total_r += r[id];\n    \n    if (x2 - x1 >= y2 - y1) {\n        sort(ids.begin(), ids.end(), [](int i, int j) {\n            return x[i] < x[j];\n        });\n        \n        int best_mid = 1;\n        int best_split_x = x1 + 1;\n        double best_score = -1e18;\n        \n        for (int mid = 1; mid < (int)ids.size(); mid++) {\n            long long left_r = 0;\n            for (int i = 0; i < mid; i++) left_r += r[ids[i]];\n            long long right_r = total_r - left_r;\n            \n            int min_split = max(x1 + 1, x[ids[mid-1]] + 1);\n            int max_split = min(x2 - 1, x[ids[mid]] + 1);\n            if (min_split > max_split) continue;\n            \n            int ideal = x1 + (long long)(x2 - x1) * left_r / total_r;\n            ideal = max(min_split, min(max_split, ideal));\n            \n            set<int> candidates = {min_split, max_split, ideal};\n            // Sample around ideal position\n            for (int delta = -20; delta <= 20; delta++) {\n                int pos = ideal + delta;\n                if (pos >= min_split && pos <= max_split) {\n                    candidates.insert(pos);\n                }\n            }\n            \n            for (int split_x : candidates) {\n                long long left_area = (long long)(split_x - x1) * (y2 - y1);\n                long long right_area = (long long)(x2 - split_x) * (y2 - y1);\n                \n                // Use actual satisfaction formula\n                double sat_left = calc_satisfaction(left_area, left_r);\n                double sat_right = calc_satisfaction(right_area, right_r);\n                \n                // Weight by number of companies (final score is average)\n                double score = sat_left * mid + sat_right * (ids.size() - mid);\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_mid = mid;\n                    best_split_x = split_x;\n                }\n            }\n        }\n        \n        vector<int> left(ids.begin(), ids.begin() + best_mid);\n        vector<int> right(ids.begin() + best_mid, ids.end());\n        \n        solve(left, x1, y1, best_split_x, y2);\n        solve(right, best_split_x, y1, x2, y2);\n    } else {\n        sort(ids.begin(), ids.end(), [](int i, int j) {\n            return y[i] < y[j];\n        });\n        \n        int best_mid = 1;\n        int best_split_y = y1 + 1;\n        double best_score = -1e18;\n        \n        for (int mid = 1; mid < (int)ids.size(); mid++) {\n            long long top_r = 0;\n            for (int i = 0; i < mid; i++) top_r += r[ids[i]];\n            long long bottom_r = total_r - top_r;\n            \n            int min_split = max(y1 + 1, y[ids[mid-1]] + 1);\n            int max_split = min(y2 - 1, y[ids[mid]] + 1);\n            if (min_split > max_split) continue;\n            \n            int ideal = y1 + (long long)(y2 - y1) * top_r / total_r;\n            ideal = max(min_split, min(max_split, ideal));\n            \n            set<int> candidates = {min_split, max_split, ideal};\n            for (int delta = -20; delta <= 20; delta++) {\n                int pos = ideal + delta;\n                if (pos >= min_split && pos <= max_split) {\n                    candidates.insert(pos);\n                }\n            }\n            \n            for (int split_y : candidates) {\n                long long top_area = (long long)(x2 - x1) * (split_y - y1);\n                long long bottom_area = (long long)(x2 - x1) * (y2 - split_y);\n                \n                double sat_top = calc_satisfaction(top_area, top_r);\n                double sat_bottom = calc_satisfaction(bottom_area, bottom_r);\n                \n                double score = sat_top * mid + sat_bottom * (ids.size() - mid);\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_mid = mid;\n                    best_split_y = split_y;\n                }\n            }\n        }\n        \n        vector<int> top(ids.begin(), ids.begin() + best_mid);\n        vector<int> bottom(ids.begin() + best_mid, ids.end());\n        \n        solve(top, x1, y1, x2, best_split_y);\n        solve(bottom, x1, best_split_y, x2, y2);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n;\n    x.resize(n);\n    y.resize(n);\n    r.resize(n);\n    result.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> x[i] >> y[i] >> r[i];\n    }\n    \n    vector<int> all_ids(n);\n    iota(all_ids.begin(), all_ids.end(), 0);\n    \n    solve(all_ids, 0, 0, 10000, 10000);\n    \n    for (int i = 0; i < n; i++) {\n        cout << result[i][0] << \" \" << result[i][1] << \" \" \n             << result[i][2] << \" \" << result[i][3] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nmap<int, vector<pair<int,int>>> tile_squares;\nmap<int, int> tile_value;\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < 50 && y >= 0 && y < 50;\n}\n\nint main() {\n    cin >> si >> sj;\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> t[i][j];\n            tile_squares[t[i][j]].push_back({i, j});\n        }\n    }\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> p[i][j];\n            tile_value[t[i][j]] += p[i][j];\n        }\n    }\n    \n    bool visited_tile[2500] = {};\n    bool visited_square[50][50] = {};\n    string path = \"\";\n    int x = si, y = sj;\n    visited_tile[t[x][y]] = true;\n    visited_square[x][y] = true;\n    \n    while (true) {\n        int current_tile = t[x][y];\n        \n        // First priority: visit other squares of current tile\n        int best_dir = -1;\n        int best_value = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (!in_bounds(nx, ny)) continue;\n            if (visited_square[nx][ny]) continue;\n            \n            int next_tile = t[nx][ny];\n            \n            if (next_tile == current_tile) {\n                if (best_dir == -1 || p[nx][ny] > best_value) {\n                    best_value = p[nx][ny];\n                    best_dir = d;\n                }\n            }\n        }\n        \n        // Second priority: move to new tile with highest total value\n        if (best_dir == -1) {\n            int best_tile_value = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                \n                if (!in_bounds(nx, ny)) continue;\n                if (visited_square[nx][ny]) continue;\n                \n                int next_tile = t[nx][ny];\n                \n                if (visited_tile[next_tile]) continue;\n                \n                if (tile_value[next_tile] > best_tile_value) {\n                    best_tile_value = tile_value[next_tile];\n                    best_dir = d;\n                }\n            }\n        }\n        \n        if (best_dir == -1) break;\n        \n        int nx = x + dx[best_dir];\n        int ny = y + dy[best_dir];\n        \n        path += dir_char[best_dir];\n        visited_square[nx][ny] = true;\n        visited_tile[t[nx][ny]] = true;\n        \n        x = nx;\n        y = ny;\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst double INF = 1e18;\nconst double DEFAULT_WEIGHT = 5000.0;\n\ndouble h[N][N], v[N][N];\nint h_count[N][N], v_count[N][N];\nvector<double> h_observations[N][N], v_observations[N][N];\n\nvoid init_weights() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            h[i][j] = DEFAULT_WEIGHT;\n            v[i][j] = DEFAULT_WEIGHT;\n            h_count[i][j] = 0;\n            v_count[i][j] = 0;\n        }\n    }\n}\n\npair<double, vector<pair<int,int>>> dijkstra(int si, int sj, int ti, int tj) {\n    vector<vector<double>> dist(N, vector<double>(N, INF));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    priority_queue<pair<double, pair<int,int>>, \n                   vector<pair<double, pair<int,int>>>,\n                   greater<>> pq;\n    \n    dist[si][sj] = 0;\n    pq.push({0, {si, sj}});\n    \n    while (!pq.empty()) {\n        auto [d, pos] = pq.top();\n        pq.pop();\n        auto [i, j] = pos;\n        \n        if (d > dist[i][j]) continue;\n        \n        if (i > 0 && dist[i][j] + v[i-1][j] < dist[i-1][j]) {\n            dist[i-1][j] = dist[i][j] + v[i-1][j];\n            parent[i-1][j] = {i, j};\n            pq.push({dist[i-1][j], {i-1, j}});\n        }\n        if (i < N-1 && dist[i][j] + v[i][j] < dist[i+1][j]) {\n            dist[i+1][j] = dist[i][j] + v[i][j];\n            parent[i+1][j] = {i, j};\n            pq.push({dist[i+1][j], {i+1, j}});\n        }\n        if (j > 0 && dist[i][j] + h[i][j-1] < dist[i][j-1]) {\n            dist[i][j-1] = dist[i][j] + h[i][j-1];\n            parent[i][j-1] = {i, j};\n            pq.push({dist[i][j-1], {i, j-1}});\n        }\n        if (j < N-1 && dist[i][j] + h[i][j] < dist[i][j+1]) {\n            dist[i][j+1] = dist[i][j] + h[i][j];\n            parent[i][j+1] = {i, j};\n            pq.push({dist[i][j+1], {i, j+1}});\n        }\n    }\n    \n    vector<pair<int,int>> path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        path.push_back({ci, cj});\n        auto [pi, pj] = parent[ci][cj];\n        if (pi == -1) break;\n        ci = pi;\n        cj = pj;\n    }\n    path.push_back({si, sj});\n    reverse(path.begin(), path.end());\n    \n    return {dist[ti][tj], path};\n}\n\nstring path_to_string(const vector<pair<int,int>>& path) {\n    string result;\n    for (int i = 1; i < path.size(); i++) {\n        int di = path[i].first - path[i-1].first;\n        int dj = path[i].second - path[i-1].second;\n        if (di == -1) result += 'U';\n        else if (di == 1) result += 'D';\n        else if (dj == -1) result += 'L';\n        else result += 'R';\n    }\n    return result;\n}\n\nvoid apply_row_column_smoothing(int query_num) {\n    // Only smooth unobserved or low-confidence edges\n    // Horizontal edges - smooth within rows\n    for (int i = 0; i < N; i++) {\n        vector<double> observed_vals;\n        for (int j = 0; j < N-1; j++) {\n            if (h_count[i][j] >= 2) {\n                observed_vals.push_back(h[i][j]);\n            }\n        }\n        if (observed_vals.size() >= 3) {\n            sort(observed_vals.begin(), observed_vals.end());\n            double median = observed_vals[observed_vals.size() / 2];\n            \n            for (int j = 0; j < N-1; j++) {\n                if (h_count[i][j] == 0) {\n                    h[i][j] = median;\n                } else if (h_count[i][j] == 1) {\n                    h[i][j] = 0.7 * h[i][j] + 0.3 * median;\n                }\n            }\n        }\n    }\n    \n    // Vertical edges - smooth within columns\n    for (int j = 0; j < N; j++) {\n        vector<double> observed_vals;\n        for (int i = 0; i < N-1; i++) {\n            if (v_count[i][j] >= 2) {\n                observed_vals.push_back(v[i][j]);\n            }\n        }\n        if (observed_vals.size() >= 3) {\n            sort(observed_vals.begin(), observed_vals.end());\n            double median = observed_vals[observed_vals.size() / 2];\n            \n            for (int i = 0; i < N-1; i++) {\n                if (v_count[i][j] == 0) {\n                    v[i][j] = median;\n                } else if (v_count[i][j] == 1) {\n                    v[i][j] = 0.7 * v[i][j] + 0.3 * median;\n                }\n            }\n        }\n    }\n}\n\nvoid update_weights(const vector<pair<int,int>>& path, double measured, double estimated, int query_num) {\n    if (path.size() <= 1) return;\n    \n    // Calculate uncertainty for each edge\n    vector<double> uncertainties;\n    double total_uncertainty = 0;\n    \n    for (int i = 1; i < path.size(); i++) {\n        int pi = path[i-1].first, pj = path[i-1].second;\n        int ci = path[i].first, cj = path[i].second;\n        \n        double uncertainty;\n        if (pi == ci) {\n            int j = min(pj, cj);\n            uncertainty = 1.0 / (1.0 + h_count[pi][j]);\n        } else {\n            int ii = min(pi, ci);\n            uncertainty = 1.0 / (1.0 + v_count[ii][pj]);\n        }\n        uncertainties.push_back(uncertainty);\n        total_uncertainty += uncertainty;\n    }\n    \n    double error = measured - estimated;\n    \n    // Adaptive learning rate with slower decay\n    double base_alpha = 0.7 * exp(-query_num / 300.0) + 0.1;\n    \n    for (int i = 1; i < path.size(); i++) {\n        int pi = path[i-1].first, pj = path[i-1].second;\n        int ci = path[i].first, cj = path[i].second;\n        \n        double weight = uncertainties[i-1] / total_uncertainty;\n        double correction = base_alpha * error * weight;\n        \n        if (pi == ci) {\n            int j = min(pj, cj);\n            h_count[pi][j]++;\n            \n            // For edges observed multiple times, use moving average\n            if (h_count[pi][j] > 1) {\n                double new_estimate = h[pi][j] + correction;\n                h_observations[pi][j].push_back(new_estimate);\n                \n                // Robust averaging: drop outliers if we have enough samples\n                if (h_observations[pi][j].size() >= 5) {\n                    vector<double> sorted_obs = h_observations[pi][j];\n                    sort(sorted_obs.begin(), sorted_obs.end());\n                    // Trimmed mean: drop top and bottom 20%\n                    int trim = sorted_obs.size() / 5;\n                    double sum = 0;\n                    for (int k = trim; k < sorted_obs.size() - trim; k++) {\n                        sum += sorted_obs[k];\n                    }\n                    h[pi][j] = sum / (sorted_obs.size() - 2 * trim);\n                } else {\n                    h[pi][j] = new_estimate;\n                }\n            } else {\n                h[pi][j] += correction;\n                h_observations[pi][j].push_back(h[pi][j]);\n            }\n            h[pi][j] = max(1000.0, min(9000.0, h[pi][j]));\n        } else {\n            int ii = min(pi, ci);\n            v_count[ii][pj]++;\n            \n            if (v_count[ii][pj] > 1) {\n                double new_estimate = v[ii][pj] + correction;\n                v_observations[ii][pj].push_back(new_estimate);\n                \n                if (v_observations[ii][pj].size() >= 5) {\n                    vector<double> sorted_obs = v_observations[ii][pj];\n                    sort(sorted_obs.begin(), sorted_obs.end());\n                    int trim = sorted_obs.size() / 5;\n                    double sum = 0;\n                    for (int k = trim; k < sorted_obs.size() - trim; k++) {\n                        sum += sorted_obs[k];\n                    }\n                    v[ii][pj] = sum / (sorted_obs.size() - 2 * trim);\n                } else {\n                    v[ii][pj] = new_estimate;\n                }\n            } else {\n                v[ii][pj] += correction;\n                v_observations[ii][pj].push_back(v[ii][pj]);\n            }\n            v[ii][pj] = max(1000.0, min(9000.0, v[ii][pj]));\n        }\n    }\n    \n    // Apply smoothing every 30 queries\n    if (query_num % 30 == 29 && query_num < 900) {\n        apply_row_column_smoothing(query_num);\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_weights();\n    \n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        auto [estimated_len, path] = dijkstra(si, sj, ti, tj);\n        string path_str = path_to_string(path);\n        \n        cout << path_str << endl;\n        cout.flush();\n        \n        int measured;\n        cin >> measured;\n        \n        update_weights(path, measured, estimated_len, q);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nvector<string> strings;\nchar matrix[20][20];\nchar best_matrix[20][20];\n\nbool isSubsequence(const string& s) {\n    int k = s.length();\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            bool ok = true;\n            for (int p = 0; p < k; p++) {\n                if (matrix[i][(j + p) % N] != s[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return true;\n            \n            ok = true;\n            for (int p = 0; p < k; p++) {\n                if (matrix[(i + p) % N][j] != s[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return true;\n        }\n    }\n    return false;\n}\n\nint countMatched() {\n    int count = 0;\n    for (const auto& s : strings) {\n        if (isSubsequence(s)) count++;\n    }\n    return count;\n}\n\nint countConflicts(const string& s, int i, int j, int d) {\n    int k = s.length();\n    int conflicts = 0;\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        if (matrix[ni][nj] != '.' && matrix[ni][nj] != s[p]) {\n            conflicts++;\n        }\n    }\n    return conflicts;\n}\n\nint countMatching(const string& s, int i, int j, int d) {\n    int k = s.length();\n    int matching = 0;\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        if (matrix[ni][nj] == s[p]) {\n            matching++;\n        }\n    }\n    return matching;\n}\n\nvoid place(const string& s, int i, int j, int d) {\n    int k = s.length();\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        matrix[ni][nj] = s[p];\n    }\n}\n\nint main() {\n    cin >> N >> M;\n    strings.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    int best_score = 0;\n    \n    // Multiple random restarts\n    for (int restart = 0; restart < 10; restart++) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                matrix[i][j] = '.';\n            }\n        }\n        \n        vector<int> order(M);\n        iota(order.begin(), order.end(), 0);\n        \n        if (restart == 0) {\n            // First try: longest first\n            sort(order.begin(), order.end(), [](int a, int b) {\n                return strings[a].length() > strings[b].length();\n            });\n        } else {\n            // Random shuffle for diversity\n            random_shuffle(order.begin(), order.end());\n        }\n        \n        // Greedy placement with increasing conflict tolerance\n        for (int maxConflicts = 0; maxConflicts <= 2; maxConflicts++) {\n            for (int idx : order) {\n                const string& s = strings[idx];\n                if (isSubsequence(s)) continue;\n                \n                int bestI = -1, bestJ = -1, bestD = -1;\n                int minConflicts = INT_MAX;\n                int maxMatching = -1;\n                \n                for (int i = 0; i < N; i++) {\n                    for (int j = 0; j < N; j++) {\n                        for (int d = 0; d < 2; d++) {\n                            int conflicts = countConflicts(s, i, j, d);\n                            int matching = countMatching(s, i, j, d);\n                            \n                            if (conflicts < minConflicts || \n                                (conflicts == minConflicts && matching > maxMatching)) {\n                                minConflicts = conflicts;\n                                maxMatching = matching;\n                                bestI = i;\n                                bestJ = j;\n                                bestD = d;\n                            }\n                        }\n                    }\n                }\n                \n                if (minConflicts <= maxConflicts && bestI != -1) {\n                    place(s, bestI, bestJ, bestD);\n                }\n            }\n        }\n        \n        // Smart dot filling\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (matrix[i][j] == '.') {\n                    int bestChar = 'A';\n                    int bestCount = 0;\n                    \n                    for (char c = 'A'; c <= 'H'; c++) {\n                        matrix[i][j] = c;\n                        int count = countMatched();\n                        if (count > bestCount) {\n                            bestCount = count;\n                            bestChar = c;\n                        }\n                    }\n                    matrix[i][j] = bestChar;\n                }\n            }\n        }\n        \n        int score = countMatched();\n        if (score > best_score) {\n            best_score = score;\n            memcpy(best_matrix, matrix, sizeof(matrix));\n        }\n    }\n    \n    memcpy(matrix, best_matrix, sizeof(matrix));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << matrix[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\n\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nbool is_valid(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\nset<pair<int,int>> get_visible(int i, int j) {\n    set<pair<int,int>> vis;\n    vis.insert({i, j});\n    for (int jj = j-1; jj >= 0 && grid[i][jj] != '#'; jj--) vis.insert({i, jj});\n    for (int jj = j+1; jj < N && grid[i][jj] != '#'; jj++) vis.insert({i, jj});\n    for (int ii = i-1; ii >= 0 && grid[ii][j] != '#'; ii--) vis.insert({ii, j});\n    for (int ii = i+1; ii < N && grid[ii][j] != '#'; ii++) vis.insert({ii, j});\n    return vis;\n}\n\nmap<pair<int,int>, int> dijkstra_dist(int si, int sj) {\n    map<pair<int,int>, int> dist;\n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    pq.push({0, si, sj});\n    dist[{si, sj}] = 0;\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        if (dist.count({i,j}) && d > dist[{i, j}]) continue;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (is_valid(ni, nj)) {\n                int nd = d + (grid[ni][nj] - '0');\n                if (!dist.count({ni, nj}) || nd < dist[{ni, nj}]) {\n                    dist[{ni, nj}] = nd;\n                    pq.push({nd, ni, nj});\n                }\n            }\n        }\n    }\n    return dist;\n}\n\nstring reconstruct_path(int si, int sj, int ti, int tj) {\n    if (si == ti && sj == tj) return \"\";\n    \n    map<pair<int,int>, pair<pair<int,int>, int>> parent;\n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    pq.push({0, si, sj});\n    parent[{si, sj}] = {{-1, -1}, -1};\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        if (i == ti && j == tj) {\n            string path;\n            auto curr = make_pair(ti, tj);\n            while (parent[curr].second != -1) {\n                path += dir_char[parent[curr].second];\n                curr = parent[curr].first;\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (is_valid(ni, nj) && !parent.count({ni, nj})) {\n                parent[{ni, nj}] = {{i, j}, dir};\n                int nd = d + (grid[ni][nj] - '0');\n                pq.push({nd, ni, nj});\n            }\n        }\n    }\n    return \"\";\n}\n\nint main() {\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    vector<pair<int,int>> roads;\n    set<pair<int,int>> all_roads;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                roads.push_back({i, j});\n                all_roads.insert({i, j});\n            }\n        }\n    }\n    \n    map<pair<int,int>, set<pair<int,int>>> visible_from;\n    for (auto& [i, j] : roads) {\n        visible_from[{i, j}] = get_visible(i, j);\n    }\n    \n    map<pair<int,int>, int> coverage_count;\n    for (auto& sq : all_roads) {\n        for (auto& [pos, vis] : visible_from) {\n            if (vis.count(sq)) coverage_count[sq]++;\n        }\n    }\n    \n    // Step 1: Greedy selection of positions to visit\n    set<pair<int,int>> covered = visible_from[{si, sj}];\n    vector<pair<int,int>> selected_positions = {{si, sj}};\n    \n    while (covered.size() < all_roads.size()) {\n        auto dist = dijkstra_dist(selected_positions.back().first, selected_positions.back().second);\n        \n        double best_score = -1e9;\n        pair<int,int> best_pos = selected_positions.back();\n        \n        for (auto& [ri, rj] : roads) {\n            int new_count = 0;\n            double importance = 0;\n            for (auto& sq : visible_from[{ri, rj}]) {\n                if (!covered.count(sq)) {\n                    new_count++;\n                    importance += 1.0 / max(1, coverage_count[sq]);\n                }\n            }\n            if (new_count > 0 && dist.count({ri, rj})) {\n                int cost = dist[{ri, rj}];\n                double score = (importance * 10.0) / (cost + 1.0);\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_pos = {ri, rj};\n                }\n            }\n        }\n        \n        if (best_score <= -1e8) break;\n        \n        selected_positions.push_back(best_pos);\n        for (auto& sq : visible_from[best_pos]) covered.insert(sq);\n    }\n    \n    // Step 2: Reorder positions using nearest neighbor (only if tour is long enough)\n    vector<pair<int,int>> tour;\n    if (selected_positions.size() > 3) {\n        set<pair<int,int>> unvisited(selected_positions.begin() + 1, selected_positions.end());\n        tour = {{si, sj}};\n        auto curr = make_pair(si, sj);\n        \n        while (!unvisited.empty()) {\n            auto dist = dijkstra_dist(curr.first, curr.second);\n            int best_dist = INT_MAX;\n            pair<int,int> best_pos = curr;\n            \n            for (auto& pos : unvisited) {\n                if (dist.count(pos) && dist[pos] < best_dist) {\n                    best_dist = dist[pos];\n                    best_pos = pos;\n                }\n            }\n            \n            tour.push_back(best_pos);\n            unvisited.erase(best_pos);\n            curr = best_pos;\n        }\n    } else {\n        tour = selected_positions;\n    }\n    \n    // Build path through tour\n    string result;\n    for (int i = 0; i < (int)tour.size() - 1; i++) {\n        result += reconstruct_path(tour[i].first, tour[i].second, \n                                   tour[i+1].first, tour[i+1].second);\n    }\n    result += reconstruct_path(tour.back().first, tour.back().second, si, sj);\n    \n    cout << result << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <map>\n#include <cmath>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> task_diff;\nvector<vector<int>> task_deps;\nvector<vector<int>> task_dependents;\nvector<int> task_status;\nvector<vector<double>> member_skill;\nvector<int> member_task;\nvector<int> start_day_map;\nvector<int> num_pending_deps;\nvector<int> task_urgency;\nvector<int> member_completed_count;\nint day_counter = 0;\n\nvoid calculate_urgency() {\n    task_urgency.resize(N, 0);\n    \n    // BFS from leaves to roots\n    vector<int> out_degree(N, 0);\n    for (int i = 0; i < N; i++) {\n        out_degree[i] = task_dependents[i].size();\n    }\n    \n    queue<int> q;\n    for (int i = 0; i < N; i++) {\n        if (out_degree[i] == 0) {\n            q.push(i);\n            task_urgency[i] = 0;\n        }\n    }\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        \n        for (int v : task_deps[u]) {\n            task_urgency[v] = max(task_urgency[v], task_urgency[u] + 1);\n            out_degree[v]--;\n            if (out_degree[v] == 0) {\n                q.push(v);\n            }\n        }\n    }\n}\n\nbool can_start(int task) {\n    return task_status[task] == -1 && num_pending_deps[task] == 0;\n}\n\ndouble estimate_time(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++) {\n        w += max(0.0, task_diff[task][k] - member_skill[member][k]);\n    }\n    return max(1.0, w);\n}\n\nvoid update_skill(int member, int task, int days) {\n    member_completed_count[member]++;\n    \n    // Adaptive learning: learn faster early, more conservative later\n    double base_rate = 1.0 / sqrt(1.0 + member_completed_count[member] * 0.2);\n    \n    if (days == 1) {\n        // Perfect match - member has all required skills\n        for (int k = 0; k < K; k++) {\n            member_skill[member][k] = max(member_skill[member][k], \n                                         (double)task_diff[task][k]);\n        }\n    } else {\n        // Estimate w \u2248 days - 1 (with noise \u00b13)\n        double min_w = max(0.0, days - 4.0);\n        double max_w = max(0.0, days + 2.0);\n        \n        double current_w = 0;\n        for (int k = 0; k < K; k++) {\n            current_w += max(0.0, task_diff[task][k] - member_skill[member][k]);\n        }\n        \n        if (current_w > max_w) {\n            // We significantly underestimated - learn aggressively\n            for (int k = 0; k < K; k++) {\n                double diff = task_diff[task][k] - member_skill[member][k];\n                if (diff > 0) {\n                    member_skill[member][k] += diff * base_rate * 0.6;\n                }\n            }\n        } else if (current_w > min_w && days <= 5) {\n            // Good match zone - learn moderately\n            for (int k = 0; k < K; k++) {\n                double diff = task_diff[task][k] - member_skill[member][k];\n                if (diff > 0) {\n                    member_skill[member][k] += diff * base_rate * 0.3;\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K >> R;\n    \n    task_diff.resize(N, vector<int>(K));\n    task_deps.resize(N);\n    task_dependents.resize(N);\n    task_status.resize(N, -1);\n    num_pending_deps.resize(N, 0);\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> task_diff[i][j];\n        }\n    }\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        task_deps[v].push_back(u);\n        task_dependents[u].push_back(v);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        num_pending_deps[i] = task_deps[i].size();\n    }\n    \n    calculate_urgency();\n    \n    // Better initial skill estimates\n    vector<double> avg_skill(K, 0.0);\n    for (int i = 0; i < N; i++) {\n        for (int k = 0; k < K; k++) {\n            avg_skill[k] += task_diff[i][k];\n        }\n    }\n    for (int k = 0; k < K; k++) {\n        avg_skill[k] /= N;\n    }\n    \n    member_skill.resize(M, avg_skill);\n    member_task.resize(M, -1);\n    start_day_map.resize(M);\n    member_completed_count.resize(M, 0);\n    \n    while (true) {\n        day_counter++;\n        \n        vector<int> available;\n        available.reserve(N);\n        for (int i = 0; i < N; i++) {\n            if (can_start(i)) {\n                available.push_back(i);\n            }\n        }\n        \n        // Sort by urgency (depth in dependency tree)\n        sort(available.begin(), available.end(), [](int a, int b) {\n            if (task_urgency[a] != task_urgency[b]) {\n                return task_urgency[a] > task_urgency[b];\n            }\n            return task_dependents[a].size() > task_dependents[b].size();\n        });\n        \n        vector<int> idle;\n        idle.reserve(M);\n        for (int i = 0; i < M; i++) {\n            if (member_task[i] == -1) {\n                idle.push_back(i);\n            }\n        }\n        \n        vector<pair<int, int>> assign;\n        assign.reserve(min(available.size(), idle.size()));\n        vector<bool> member_used(M, false);\n        \n        // For each task (by priority), find best member\n        for (int t : available) {\n            int best_member = -1;\n            double best_score = 1e9;\n            \n            for (int m : idle) {\n                if (member_used[m]) continue;\n                \n                double est_time = estimate_time(t, m);\n                \n                // Exploration bonus: encourage learning in early phase\n                double exploration_bonus = 0;\n                if (day_counter <= 50 && member_completed_count[m] < 5) {\n                    exploration_bonus = -1.0;\n                }\n                \n                double score = est_time + exploration_bonus;\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_member = m;\n                }\n            }\n            \n            if (best_member != -1) {\n                assign.push_back({best_member, t});\n                member_task[best_member] = t;\n                task_status[t] = 0;\n                member_used[best_member] = true;\n                start_day_map[best_member] = day_counter;\n            }\n        }\n        \n        cout << assign.size();\n        for (auto [m, t] : assign) {\n            cout << \" \" << (m + 1) << \" \" << (t + 1);\n        }\n        cout << \"\\n\";\n        cout.flush();\n        \n        int n;\n        cin >> n;\n        if (n == -1) break;\n        \n        for (int i = 0; i < n; i++) {\n            int m;\n            cin >> m;\n            m--;\n            \n            int t = member_task[m];\n            int days = day_counter - start_day_map[m] + 1;\n            \n            task_status[t] = 1;\n            member_task[m] = -1;\n            \n            for (int dep : task_dependents[t]) {\n                num_pending_deps[dep]--;\n            }\n            \n            update_skill(m, t, days);\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <chrono>\n\nusing namespace std;\n\nstruct Order {\n    int id;\n    int ax, ay, cx, cy;\n};\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nclass Solution {\npublic:\n    vector<Order> orders;\n    chrono::high_resolution_clock::time_point start_time;\n    \n    void read_input() {\n        orders.resize(1000);\n        for (int i = 0; i < 1000; i++) {\n            orders[i].id = i;\n            cin >> orders[i].ax >> orders[i].ay >> orders[i].cx >> orders[i].cy;\n        }\n        start_time = chrono::high_resolution_clock::now();\n    }\n    \n    double elapsed_ms() {\n        auto now = chrono::high_resolution_clock::now();\n        return chrono::duration<double, milli>(now - start_time).count();\n    }\n    \n    int calc_cost(const vector<pair<int, int>>& route) {\n        int cost = 0;\n        for (size_t i = 1; i < route.size(); i++) {\n            cost += manhattan(route[i-1].first, route[i-1].second, route[i].first, route[i].second);\n        }\n        return cost;\n    }\n    \n    double score_order(int idx, double w1, double w2, double w3, double w4) {\n        double d_pickup = manhattan(400, 400, orders[idx].ax, orders[idx].ay);\n        double d_delivery = manhattan(400, 400, orders[idx].cx, orders[idx].cy);\n        double d_pd = manhattan(orders[idx].ax, orders[idx].ay, orders[idx].cx, orders[idx].cy);\n        \n        int mx = (orders[idx].ax + orders[idx].cx) / 2;\n        int my = (orders[idx].ay + orders[idx].cy) / 2;\n        double d_center = manhattan(400, 400, mx, my);\n        \n        double compactness = d_pd / max(1.0, (d_pickup + d_delivery) * 0.5);\n        \n        return d_pickup * w1 + d_delivery * w1 + d_pd * w2 + d_center * w3 - compactness * w4 * 100;\n    }\n    \n    vector<int> select_orders(double w1, double w2, double w3, double w4) {\n        vector<pair<double, int>> scores;\n        for (int i = 0; i < 1000; i++) {\n            scores.push_back({score_order(i, w1, w2, w3, w4), i});\n        }\n        sort(scores.begin(), scores.end());\n        \n        vector<int> selected;\n        for (int i = 0; i < 50; i++) {\n            selected.push_back(scores[i].second);\n        }\n        return selected;\n    }\n    \n    vector<pair<int, int>> construct_route_greedy(const vector<int>& selected) {\n        vector<pair<int, int>> route;\n        route.push_back({400, 400});\n        \n        set<int> need_pickup(selected.begin(), selected.end());\n        set<int> picked_up;\n        \n        int cx = 400, cy = 400;\n        \n        while (!need_pickup.empty() || !picked_up.empty()) {\n            int best_idx = -1;\n            int best_dist = 2000000;\n            bool is_pickup = false;\n            \n            for (int idx : need_pickup) {\n                int d = manhattan(cx, cy, orders[idx].ax, orders[idx].ay);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = true;\n                }\n            }\n            \n            for (int idx : picked_up) {\n                int d = manhattan(cx, cy, orders[idx].cx, orders[idx].cy);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = false;\n                }\n            }\n            \n            if (is_pickup) {\n                route.push_back({orders[best_idx].ax, orders[best_idx].ay});\n                cx = orders[best_idx].ax;\n                cy = orders[best_idx].ay;\n                need_pickup.erase(best_idx);\n                picked_up.insert(best_idx);\n            } else {\n                route.push_back({orders[best_idx].cx, orders[best_idx].cy});\n                cx = orders[best_idx].cx;\n                cy = orders[best_idx].cy;\n                picked_up.erase(best_idx);\n            }\n        }\n        \n        route.push_back({400, 400});\n        return route;\n    }\n    \n    vector<pair<int, int>> construct_route_paired(const vector<int>& selected, int threshold) {\n        vector<pair<int, int>> route;\n        route.push_back({400, 400});\n        \n        set<int> need_pickup(selected.begin(), selected.end());\n        set<int> picked_up;\n        \n        int cx = 400, cy = 400;\n        \n        while (!need_pickup.empty() || !picked_up.empty()) {\n            int best_idx = -1;\n            int best_dist = 2000000;\n            bool is_pickup = false;\n            \n            for (int idx : need_pickup) {\n                int d = manhattan(cx, cy, orders[idx].ax, orders[idx].ay);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = true;\n                }\n            }\n            \n            for (int idx : picked_up) {\n                int d = manhattan(cx, cy, orders[idx].cx, orders[idx].cy);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = false;\n                }\n            }\n            \n            if (is_pickup) {\n                route.push_back({orders[best_idx].ax, orders[best_idx].ay});\n                cx = orders[best_idx].ax;\n                cy = orders[best_idx].ay;\n                need_pickup.erase(best_idx);\n                \n                int d_to_delivery = manhattan(cx, cy, orders[best_idx].cx, orders[best_idx].cy);\n                if (d_to_delivery <= threshold) {\n                    route.push_back({orders[best_idx].cx, orders[best_idx].cy});\n                    cx = orders[best_idx].cx;\n                    cy = orders[best_idx].cy;\n                } else {\n                    picked_up.insert(best_idx);\n                }\n            } else {\n                route.push_back({orders[best_idx].cx, orders[best_idx].cy});\n                cx = orders[best_idx].cx;\n                cy = orders[best_idx].cy;\n                picked_up.erase(best_idx);\n            }\n        }\n        \n        route.push_back({400, 400});\n        return route;\n    }\n    \n    void solve() {\n        read_input();\n        \n        int best_cost = 2000000000;\n        vector<int> best_selected;\n        vector<pair<int, int>> best_route;\n        \n        // Comprehensive parameter search - NO OPTIMIZATION PHASE\n        for (double w1 = 0.1; w1 <= 0.95 && elapsed_ms() < 1900; w1 += 0.05) {\n            for (double w3 = 0.0; w3 <= 0.45 && elapsed_ms() < 1900; w3 += 0.05) {\n                for (double w4 = 0.0; w4 <= 0.25 && elapsed_ms() < 1900; w4 += 0.05) {\n                    double w2 = 1.0 - w1 - w3 - w4;\n                    if (w2 < -0.01 || w2 > 1.01) continue;\n                    \n                    vector<int> selected = select_orders(w1, w2, w3, w4);\n                    \n                    // Try greedy construction\n                    vector<pair<int, int>> route1 = construct_route_greedy(selected);\n                    int cost1 = calc_cost(route1);\n                    if (cost1 < best_cost) {\n                        best_cost = cost1;\n                        best_selected = selected;\n                        best_route = route1;\n                    }\n                    \n                    // Try paired construction with varied thresholds\n                    for (int threshold : {50, 70, 90, 110, 140, 170, 210, 250, 300, 360, 430}) {\n                        if (elapsed_ms() >= 1900) break;\n                        vector<pair<int, int>> route2 = construct_route_paired(selected, threshold);\n                        int cost2 = calc_cost(route2);\n                        if (cost2 < best_cost) {\n                            best_cost = cost2;\n                            best_selected = selected;\n                            best_route = route2;\n                        }\n                    }\n                }\n            }\n        }\n        \n        cout << best_selected.size();\n        for (int idx : best_selected) {\n            cout << \" \" << (idx + 1);\n        }\n        cout << \"\\n\";\n        \n        cout << best_route.size();\n        for (auto [x, y] : best_route) {\n            cout << \" \" << x << \" \" << y;\n        }\n        cout << \"\\n\";\n        cout.flush();\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.solve();\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent, rank;\npublic:\n    UnionFind(int n) : parent(n), rank(n, 0) {\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    \n    int find(int x) {\n        return parent[x] == x ? x : parent[x] = find(parent[x]);\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400, M = 1995;\n    \n    vector<pair<int,int>> coord(N);\n    for (auto& [x, y] : coord) cin >> x >> y;\n    \n    vector<pair<int,int>> edge(M);\n    vector<int> dist(M);\n    \n    for (int i = 0; i < M; i++) {\n        auto& [u, v] = edge[i];\n        cin >> u >> v;\n        int dx = coord[u].first - coord[v].first;\n        int dy = coord[u].second - coord[v].second;\n        dist[i] = round(sqrt(dx*dx + dy*dy));\n    }\n    \n    UnionFind uf(N);\n    int cnt = 0;\n    \n    for (int i = 0; i < M; i++) {\n        int len;\n        cin >> len;\n        \n        auto [u, v] = edge[i];\n        int d = dist[i];\n        \n        bool ok = false;\n        if (uf.find(u) != uf.find(v)) {\n            int need = N - 1 - cnt;  // edges still needed\n            int left = M - i;         // edges left INCLUDING this one\n            \n            double r = (double)len / d;\n            \n            // Extremely conservative: prioritize connectivity above optimization\n            if (left <= need * 10) {\n                // Danger zone: accept everything that connects different components\n                ok = true;\n            } else if (left <= need * 20) {\n                // Low safety: only reject terrible edges\n                ok = (r <= 2.85);\n            } else if (left <= need * 30) {\n                // Moderate safety: be quite lenient\n                ok = (r <= 2.75);\n            } else {\n                // High safety: can be somewhat selective but still careful\n                ok = (r <= 2.6);\n            }\n        }\n        \n        cout << (ok ? \"1\" : \"0\") << \"\\n\" << flush;\n        if (ok) {\n            uf.unite(u, v);\n            cnt++;\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Pos {\n    int x, y;\n    bool operator<(const Pos& o) const {\n        if (x != o.x) return x < o.x;\n        return y < o.y;\n    }\n};\n\nint N, M;\nvector<Pos> pets, humans;\nvector<int> pet_types;\nbool grid[32][32];\nset<Pos> pet_set;\n\nvoid init() {\n    cin >> N;\n    pets.resize(N);\n    pet_types.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pet_types[i];\n        pet_set.insert(pets[i]);\n    }\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n    \n    for (int i = 0; i <= 31; i++)\n        for (int j = 0; j <= 31; j++)\n            grid[i][j] = (i >= 1 && i <= 30 && j >= 1 && j <= 30);\n}\n\nbool is_adjacent_to_pet(int x, int y) {\n    return pet_set.count({x-1, y}) || pet_set.count({x+1, y}) ||\n           pet_set.count({x, y-1}) || pet_set.count({x, y+1});\n}\n\nbool in_bounds(int x, int y) {\n    return x >= 1 && x <= 30 && y >= 1 && y <= 30;\n}\n\nbool can_build_wall(int x, int y, const set<Pos>& human_set) {\n    if (!in_bounds(x, y)) return false;\n    if (!grid[x][y]) return false;\n    if (pet_set.count({x, y})) return false;\n    if (human_set.count({x, y})) return false;\n    if (is_adjacent_to_pet(x, y)) return false;\n    return true;\n}\n\nint manhattan(const Pos& a, const Pos& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// Calculate bounding box of humans\nvoid get_human_bounds(int& min_x, int& max_x, int& min_y, int& max_y) {\n    min_x = 31, max_x = 0, min_y = 31, max_y = 0;\n    for (const auto& h : humans) {\n        min_x = min(min_x, h.x);\n        max_x = max(max_x, h.x);\n        min_y = min(min_y, h.y);\n        max_y = max(max_y, h.y);\n    }\n}\n\n// Get priority for building a wall at this position\nint get_wall_priority(int x, int y, const set<Pos>& walls_to_build, int turn) {\n    int priority = 0;\n    \n    // Strong preference for walls connected to existing walls\n    int wall_neighbors = 0;\n    if (!grid[x-1][y] || walls_to_build.count({x-1, y})) wall_neighbors++;\n    if (!grid[x+1][y] || walls_to_build.count({x+1, y})) wall_neighbors++;\n    if (!grid[x][y-1] || walls_to_build.count({x, y-1})) wall_neighbors++;\n    if (!grid[x][y+1] || walls_to_build.count({x, y+1})) wall_neighbors++;\n    \n    priority += wall_neighbors * 100;\n    \n    // Calculate distance from human bounding box\n    int min_x, max_x, min_y, max_y;\n    get_human_bounds(min_x, max_x, min_y, max_y);\n    \n    // Expand the box by a margin based on turn\n    int margin = min(4, turn / 30); // Gradually expand\n    min_x -= margin;\n    max_x += margin;\n    min_y -= margin;\n    max_y += margin;\n    \n    // Check if on perimeter of expanded box\n    bool on_perimeter = (x == min_x || x == max_x || y == min_y || y == max_y);\n    if (on_perimeter) {\n        priority += 500; // High priority for perimeter\n    }\n    \n    // Check if on second layer\n    bool on_second = (x == min_x-1 || x == max_x+1 || y == min_y-1 || y == max_y+1);\n    if (on_second) {\n        priority += 300;\n    }\n    \n    return priority;\n}\n\nint main() {\n    init();\n    \n    // Find safe corner - farthest from all pets\n    int best_cx = 15, best_cy = 15;\n    double max_total_dist = 0;\n    \n    for (int cx : {7, 15, 23}) {\n        for (int cy : {7, 15, 23}) {\n            double total_dist = 0;\n            for (const auto& p : pets) {\n                total_dist += manhattan({cx, cy}, p);\n            }\n            if (total_dist > max_total_dist) {\n                max_total_dist = total_dist;\n                best_cx = cx;\n                best_cy = cy;\n            }\n        }\n    }\n    \n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n        \n        set<Pos> human_set;\n        for (const auto& h : humans) {\n            human_set.insert(h);\n        }\n        \n        vector<pair<int,int>> dirs = {{-1,0},{1,0},{0,-1},{0,1}};\n        string wall_chars = \"udlr\";\n        string move_chars = \"UDLR\";\n        \n        // PHASE 1: Decide wall building\n        set<Pos> walls_to_build;\n        vector<int> wall_dir(M, -1);\n        \n        for (int i = 0; i < M; i++) {\n            int x = humans[i].x, y = humans[i].y;\n            \n            int best_d = -1;\n            int best_priority = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = x + dirs[d].first;\n                int ny = y + dirs[d].second;\n                \n                if (can_build_wall(nx, ny, human_set) && !walls_to_build.count({nx, ny})) {\n                    int priority = get_wall_priority(nx, ny, walls_to_build, turn);\n                    \n                    if (priority > best_priority) {\n                        best_priority = priority;\n                        best_d = d;\n                    }\n                }\n            }\n            \n            if (best_d >= 0) {\n                wall_dir[i] = best_d;\n                int nx = x + dirs[best_d].first;\n                int ny = y + dirs[best_d].second;\n                walls_to_build.insert({nx, ny});\n            }\n        }\n        \n        // PHASE 2: Movement for non-builders\n        for (int i = 0; i < M; i++) {\n            if (wall_dir[i] >= 0) {\n                actions[i] = wall_chars[wall_dir[i]];\n                continue;\n            }\n            \n            // Move toward safe zone (first 40 turns)\n            if (turn < 40) {\n                int x = humans[i].x, y = humans[i].y;\n                \n                int best_d = -1;\n                int curr_dist = manhattan({x, y}, {best_cx, best_cy});\n                \n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dirs[d].first;\n                    int ny = y + dirs[d].second;\n                    \n                    if (!in_bounds(nx, ny)) continue;\n                    if (!grid[nx][ny]) continue;\n                    if (walls_to_build.count({nx, ny})) continue;\n                    \n                    int new_dist = manhattan({nx, ny}, {best_cx, best_cy});\n                    \n                    if (new_dist < curr_dist) {\n                        best_d = d;\n                        break;\n                    }\n                }\n                \n                if (best_d >= 0) {\n                    actions[i] = move_chars[best_d];\n                }\n            }\n        }\n        \n        // Apply walls\n        for (const auto& w : walls_to_build) {\n            grid[w.x][w.y] = false;\n        }\n        \n        // Apply movements\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'U') humans[i].x--;\n            else if (a == 'D') humans[i].x++;\n            else if (a == 'L') humans[i].y--;\n            else if (a == 'R') humans[i].y++;\n        }\n        \n        cout << actions << endl;\n        cout.flush();\n        \n        // Read pets\n        pet_set.clear();\n        for (int i = 0; i < N; i++) {\n            string mov;\n            cin >> mov;\n            for (char c : mov) {\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n            pet_set.insert(pets[i]);\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    if (si == ti && sj == tj) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    // BFS to find shortest path\n    // Try directions in order that prefers moving toward target\n    queue<tuple<int,int,string>> q;\n    vector<vector<bool>> visited(20, vector<bool>(20, false));\n    q.push({si, sj, \"\"});\n    visited[si][sj] = true;\n    \n    string path = \"\";\n    while (!q.empty()) {\n        auto [i, j, cur_path] = q.front();\n        q.pop();\n        \n        if (i == ti && j == tj) {\n            path = cur_path;\n            break;\n        }\n        \n        // Try directions preferring movement toward target\n        // This helps find more direct paths when multiple shortest paths exist\n        vector<tuple<int,int,char>> moves;\n        \n        if (i < 19 && v[i][j] == '0' && !visited[i+1][j]) {\n            moves.push_back({i+1, j, 'D'});\n        }\n        if (j < 19 && h[i][j] == '0' && !visited[i][j+1]) {\n            moves.push_back({i, j+1, 'R'});\n        }\n        if (i > 0 && v[i-1][j] == '0' && !visited[i-1][j]) {\n            moves.push_back({i-1, j, 'U'});\n        }\n        if (j > 0 && h[i][j-1] == '0' && !visited[i][j-1]) {\n            moves.push_back({i, j-1, 'L'});\n        }\n        \n        // Sort moves to prefer those moving toward target\n        sort(moves.begin(), moves.end(), [&](auto& a, auto& b) {\n            int dist_a = abs(get<0>(a) - ti) + abs(get<1>(a) - tj);\n            int dist_b = abs(get<0>(b) - ti) + abs(get<1>(b) - tj);\n            return dist_a < dist_b;\n        });\n        \n        for (auto [ni, nj, dir] : moves) {\n            visited[ni][nj] = true;\n            q.push({ni, nj, cur_path + dir});\n        }\n    }\n    \n    if (path.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    // Simply repeat the shortest path to fill the 200 character budget\n    // This maximizes robustness while allowing early termination when office is reached\n    string result = \"\";\n    while (result.length() + path.length() <= 200) {\n        result += path;\n    }\n    \n    // Fill remaining space with partial path\n    int remaining = 200 - result.length();\n    if (remaining > 0 && remaining < path.length()) {\n        result += path.substr(0, remaining);\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nint di[4] = {0, -1, 0, 1};\nint dj[4] = {-1, 0, 1, 0};\n\nint to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\nint rotateTile(int tile, int rot) {\n    rot = rot % 4;\n    for (int i = 0; i < rot; i++) {\n        if (tile <= 3) tile = (tile + 1) % 4;\n        else if (tile <= 5) tile = (tile == 4) ? 5 : 4;\n        else tile = (tile == 6) ? 7 : 6;\n    }\n    return tile;\n}\n\nint getLoopLength(int si, int sj, int sd, const vector<vector<int>>& current) {\n    int i = si, j = sj, d = sd, length = 0;\n    while (length <= 2000) {\n        int tile = current[i][j];\n        int d2 = to[tile][d];\n        if (d2 == -1) return 0;\n        i += di[d2]; j += dj[d2];\n        if (i < 0 || i >= N || j < 0 || j >= N) return 0;\n        d = (d2 + 2) % 4;\n        length++;\n        if (i == si && j == sj && d == sd) return length;\n    }\n    return 0;\n}\n\nlong long calculateScore(const vector<vector<int>>& current) {\n    vector<int> loops;\n    vector<vector<vector<bool>>> visited(N, vector<vector<bool>>(N, vector<bool>(4, false)));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (visited[i][j][d]) continue;\n                int len = getLoopLength(i, j, d, current);\n                if (len > 0) {\n                    loops.push_back(len);\n                    int ii = i, jj = j, dd = d;\n                    for (int step = 0; step < len; step++) {\n                        visited[ii][jj][dd] = true;\n                        int tile = current[ii][jj];\n                        int d2 = to[tile][dd];\n                        ii += di[d2]; jj += dj[d2];\n                        dd = (d2 + 2) % 4;\n                    }\n                }\n            }\n        }\n    }\n    sort(loops.rbegin(), loops.rend());\n    if (loops.size() < 2) return 0;\n    return (long long)loops[0] * loops[1];\n}\n\nint main() {\n    auto start = chrono::steady_clock::now();\n    vector<string> tiles(N);\n    for (int i = 0; i < N; i++) cin >> tiles[i];\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n    \n    vector<vector<int>> bestRotation(N, vector<int>(N));\n    long long bestScore = 0;\n    \n    // Phase 1: Simulated annealing with multiple starts (1.4 seconds)\n    for (int trial = 0; trial < 4; trial++) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.4) break;\n        \n        vector<vector<int>> rotation(N, vector<int>(N));\n        vector<vector<int>> current(N, vector<int>(N));\n        \n        // Different initialization patterns\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (trial == 0) rotation[i][j] = gen() % 4;\n                else if (trial == 1) rotation[i][j] = 0;\n                else if (trial == 2) rotation[i][j] = (i + j) % 4;\n                else rotation[i][j] = ((i/5) + (j/5)) % 4;\n                current[i][j] = rotateTile(tiles[i][j] - '0', rotation[i][j]);\n            }\n        }\n        \n        long long currentScore = calculateScore(current);\n        if (currentScore > bestScore) {\n            bestScore = currentScore;\n            bestRotation = rotation;\n        }\n        \n        double temp = 80.0;\n        int iterations = 0;\n        \n        while (true) {\n            iterations++;\n            if (iterations % 500 == 0) {\n                now = chrono::steady_clock::now();\n                elapsed = chrono::duration<double>(now - start).count();\n                if (elapsed > 1.4) break;\n                double progress = elapsed / 1.4;\n                temp = 80.0 * pow(0.001, progress);\n            }\n            \n            // Occasionally change 2 adjacent tiles together\n            int numChanges = (dis(gen) < 0.9) ? 1 : 2;\n            vector<tuple<int,int,int>> changes;\n            \n            int si = gen() % N, sj = gen() % N;\n            for (int c = 0; c < numChanges; c++) {\n                int i = si, j = sj;\n                if (c == 1) {\n                    // Pick adjacent tile\n                    int dir = gen() % 4;\n                    i += di[dir];\n                    j += dj[dir];\n                    if (i < 0 || i >= N || j < 0 || j >= N) continue;\n                }\n                \n                int oldRot = rotation[i][j];\n                int newRot = gen() % 4;\n                if (oldRot != newRot) {\n                    changes.push_back({i, j, oldRot});\n                    rotation[i][j] = newRot;\n                    current[i][j] = rotateTile(tiles[i][j] - '0', newRot);\n                }\n            }\n            \n            if (changes.empty()) continue;\n            \n            long long score = calculateScore(current);\n            \n            if (score > currentScore || dis(gen) < exp((score - currentScore) / temp)) {\n                currentScore = score;\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestRotation = rotation;\n                }\n            } else {\n                for (auto [i, j, oldRot] : changes) {\n                    rotation[i][j] = oldRot;\n                    current[i][j] = rotateTile(tiles[i][j] - '0', oldRot);\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Intensive greedy hill climbing (remaining time)\n    auto now = chrono::steady_clock::now();\n    double elapsed = chrono::duration<double>(now - start).count();\n    \n    if (elapsed < 1.96) {\n        vector<vector<int>> current(N, vector<int>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                current[i][j] = rotateTile(tiles[i][j] - '0', bestRotation[i][j]);\n            }\n        }\n        \n        // Multiple passes until no improvement\n        bool improved = true;\n        int passes = 0;\n        while (improved && passes < 5) {\n            improved = false;\n            passes++;\n            \n            vector<pair<int,int>> positions;\n            for (int i = 0; i < N; i++)\n                for (int j = 0; j < N; j++)\n                    positions.push_back({i, j});\n            shuffle(positions.begin(), positions.end(), gen);\n            \n            for (auto [i, j] : positions) {\n                now = chrono::steady_clock::now();\n                if (chrono::duration<double>(now - start).count() > 1.97) break;\n                \n                int oldRot = bestRotation[i][j];\n                long long bestLocalScore = bestScore;\n                int bestLocalRot = oldRot;\n                \n                for (int r = 0; r < 4; r++) {\n                    if (r == oldRot) continue;\n                    current[i][j] = rotateTile(tiles[i][j] - '0', r);\n                    long long score = calculateScore(current);\n                    if (score > bestLocalScore) {\n                        bestLocalScore = score;\n                        bestLocalRot = r;\n                    }\n                }\n                \n                if (bestLocalRot != oldRot) {\n                    bestRotation[i][j] = bestLocalRot;\n                    current[i][j] = rotateTile(tiles[i][j] - '0', bestLocalRot);\n                    bestScore = bestLocalScore;\n                    improved = true;\n                } else {\n                    current[i][j] = rotateTile(tiles[i][j] - '0', oldRot);\n                }\n            }\n            \n            now = chrono::steady_clock::now();\n            if (chrono::duration<double>(now - start).count() > 1.96) break;\n        }\n    }\n    \n    string output;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            output += ('0' + bestRotation[i][j]);\n    cout << output << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> board;\nint empty_i, empty_j;\nchrono::steady_clock::time_point start_time;\n\ndouble elapsed_ms() {\n    return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n}\n\nvoid find_empty() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == '0') {\n                empty_i = i;\n                empty_j = j;\n                return;\n            }\n        }\n    }\n}\n\nint get_tile(int i, int j) {\n    if (i < 0 || i >= N || j < 0 || j >= N) return -1;\n    char c = board[i][j];\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\ntuple<int, int, int> evaluate_board() {\n    vector<int> parent(N * N);\n    iota(parent.begin(), parent.end(), 0);\n    \n    function<int(int)> find = [&](int x) {\n        return parent[x] == x ? x : parent[x] = find(parent[x]);\n    };\n    \n    int potential = 0;\n    int mismatches = 0;\n    \n    for (int i = 0; i < N - 1; i++) {\n        for (int j = 0; j < N; j++) {\n            int t1 = get_tile(i, j);\n            int t2 = get_tile(i + 1, j);\n            if (t1 > 0 && t2 > 0) {\n                bool t1_down = (t1 & 8);\n                bool t2_up = (t2 & 2);\n                if (t1_down && t2_up) {\n                    int p1 = find(i * N + j), p2 = find((i + 1) * N + j);\n                    if (p1 != p2) parent[p1] = p2;\n                } else if (t1_down != t2_up) {\n                    if (t1_down || t2_up) potential++;\n                    else mismatches++;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N - 1; j++) {\n            int t1 = get_tile(i, j);\n            int t2 = get_tile(i, j + 1);\n            if (t1 > 0 && t2 > 0) {\n                bool t1_right = (t1 & 4);\n                bool t2_left = (t2 & 1);\n                if (t1_right && t2_left) {\n                    int p1 = find(i * N + j), p2 = find(i * N + j + 1);\n                    if (p1 != p2) parent[p1] = p2;\n                } else if (t1_right != t2_left) {\n                    if (t1_right || t2_left) potential++;\n                    else mismatches++;\n                }\n            }\n        }\n    }\n    \n    map<int, vector<int>> components;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (get_tile(i, j) > 0) {\n                components[find(i * N + j)].push_back(i * N + j);\n            }\n        }\n    }\n    \n    int max_tree_size = 0;\n    for (auto& [root, nodes] : components) {\n        int edges = 0;\n        for (int node : nodes) {\n            int i = node / N, j = node % N;\n            int t = get_tile(i, j);\n            if (i + 1 < N && get_tile(i+1, j) > 0 && (t & 8) && (get_tile(i+1, j) & 2) && find((i+1)*N+j) == root) edges++;\n            if (j + 1 < N && get_tile(i, j+1) > 0 && (t & 4) && (get_tile(i, j+1) & 1) && find(i*N+j+1) == root) edges++;\n        }\n        if (edges == (int)nodes.size() - 1) {\n            max_tree_size = max(max_tree_size, (int)nodes.size());\n        }\n    }\n    \n    return {max_tree_size, potential, -mismatches};\n}\n\nbool can_move(char dir) {\n    if (dir == 'U') return empty_i > 0;\n    if (dir == 'D') return empty_i < N - 1;\n    if (dir == 'L') return empty_j > 0;\n    if (dir == 'R') return empty_j < N - 1;\n    return false;\n}\n\nvoid make_move(char dir) {\n    int ni = empty_i, nj = empty_j;\n    if (dir == 'U') ni--;\n    else if (dir == 'D') ni++;\n    else if (dir == 'L') nj--;\n    else if (dir == 'R') nj++;\n    swap(board[empty_i][empty_j], board[ni][nj]);\n    empty_i = ni;\n    empty_j = nj;\n}\n\nchar opposite(char dir) {\n    if (dir == 'U') return 'D';\n    if (dir == 'D') return 'U';\n    if (dir == 'L') return 'R';\n    return 'L';\n}\n\nint main() {\n    start_time = chrono::steady_clock::now();\n    \n    cin >> N >> T;\n    board.resize(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    find_empty();\n    \n    mt19937 rng(42);\n    string moves = \"\";\n    char last = ' ';\n    int stagnant = 0;\n    int best_ever = 0;\n    \n    while ((int)moves.length() < T && elapsed_ms() < 2900) {\n        auto [current_score, current_potential, current_mismatch] = evaluate_board();\n        if (current_score == N * N - 1) break;\n        \n        if (current_score > best_ever) {\n            best_ever = current_score;\n            stagnant = 0;\n        } else {\n            stagnant++;\n        }\n        \n        vector<char> valid;\n        for (char d : {'U','D','L','R'}) {\n            if (last != ' ' && d == opposite(last)) continue;\n            if (can_move(d)) valid.push_back(d);\n        }\n        if (valid.empty()) break;\n        \n        // Phase-based strategy\n        double progress = (double)moves.length() / T;\n        double rand_prob = 0.08;\n        \n        if (progress < 0.15) {\n            rand_prob = 0.35;  // Early exploration\n        } else if (progress < 0.4) {\n            rand_prob = 0.15;  // Middle optimization\n        } else {\n            rand_prob = 0.08;  // Late exploitation\n        }\n        \n        // Stagnation-based adaptation\n        if (stagnant > 300) rand_prob = 0.75;\n        else if (stagnant > 200) rand_prob = 0.55;\n        else if (stagnant > 120) rand_prob = 0.35;\n        else if (stagnant > 70) rand_prob = max(rand_prob, 0.20);\n        \n        vector<tuple<int, int, int, char>> opts;\n        \n        // Occasionally do 2-step lookahead\n        bool deep_search = (stagnant > 80 && stagnant % 40 == 0 && elapsed_ms() < 2500);\n        \n        for (char d : valid) {\n            auto ob = board; int oi = empty_i, oj = empty_j;\n            make_move(d);\n            \n            if (deep_search) {\n                int best_s2 = -1, best_p2 = -1, best_m2 = -1000;\n                for (char d2 : {'U','D','L','R'}) {\n                    if (d2 == opposite(d) || !can_move(d2)) continue;\n                    auto ob2 = board; int oi2 = empty_i, oj2 = empty_j;\n                    make_move(d2);\n                    auto [s2, p2, m2] = evaluate_board();\n                    if (s2 > best_s2 || (s2 == best_s2 && p2 > best_p2) || \n                        (s2 == best_s2 && p2 == best_p2 && m2 > best_m2)) {\n                        best_s2 = s2; best_p2 = p2; best_m2 = m2;\n                    }\n                    board = ob2; empty_i = oi2; empty_j = oj2;\n                }\n                if (best_s2 >= 0) {\n                    opts.push_back({best_s2, best_p2, best_m2, d});\n                }\n            } else {\n                auto [s, p, m] = evaluate_board();\n                opts.push_back({s, p, m, d});\n            }\n            \n            board = ob; empty_i = oi; empty_j = oj;\n        }\n        \n        sort(opts.rbegin(), opts.rend());\n        \n        char sel;\n        auto [best_s, best_p, best_m, best_c] = opts[0];\n        \n        if (best_s > current_score || \n           (best_s == current_score && best_p > current_potential) ||\n           (best_s == current_score && best_p == current_potential && best_m > current_mismatch)) {\n            sel = best_c;\n        } else if (rng() % 1000 < rand_prob * 1000) {\n            if (rng() % 100 < 50 && opts.size() > 1) {\n                sel = get<3>(opts[min(1, (int)opts.size()-1)]);\n            } else {\n                sel = valid[rng() % valid.size()];\n            }\n        } else {\n            sel = best_c;\n        }\n        \n        make_move(sel);\n        moves += sel;\n        last = sel;\n        \n        // More frequent but shorter shakes\n        if (stagnant > 250 && stagnant % 100 == 0 && (int)moves.length() < T - 30) {\n            int shake_len = min(15, T - (int)moves.length());\n            for (int shake = 0; shake < shake_len; shake++) {\n                vector<char> v;\n                for (char d : {'U','D','L','R'}) {\n                    if (d != opposite(last) && can_move(d)) v.push_back(d);\n                }\n                if (!v.empty()) {\n                    char r = v[rng() % v.size()];\n                    make_move(r);\n                    moves += r;\n                    last = r;\n                }\n            }\n            stagnant = 0;\n        }\n    }\n    \n    cout << moves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, K;\n    cin >> N >> K;\n    \n    vector<int> a(11);\n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    \n    vector<pair<int, int>> points(N);\n    for (int i = 0; i < N; i++) {\n        cin >> points[i].first >> points[i].second;\n    }\n    \n    // Sort strawberries by angle around origin\n    sort(points.begin(), points.end(), [](const auto& p1, const auto& p2) {\n        return atan2(p1.second, p1.first) < atan2(p2.second, p2.first);\n    });\n    \n    // Create priority list: (demand count, size)\n    vector<pair<int, int>> priority;\n    for (int d = 1; d <= 10; d++) {\n        if (a[d] > 0) {\n            priority.push_back({a[d], d});\n        }\n    }\n    sort(priority.rbegin(), priority.rend()); // Highest demand first\n    \n    // Greedy partitioning\n    vector<int> remaining_demand = a;\n    vector<int> partition;\n    int pos = 0;\n    \n    while (pos < N) {\n        int chosen_size = N - pos; // Default: use all remaining\n        \n        // Try to find a size with remaining demand that fits\n        for (auto [demand, size] : priority) {\n            if (remaining_demand[size] > 0 && pos + size <= N) {\n                chosen_size = size;\n                break;\n            }\n        }\n        \n        // If no good match, try any size that has demand\n        if (chosen_size > 10 || remaining_demand[chosen_size] == 0) {\n            for (int d = 10; d >= 1; d--) {\n                if (remaining_demand[d] > 0 && pos + d <= N) {\n                    chosen_size = d;\n                    break;\n                }\n            }\n        }\n        \n        // Ensure we don't exceed available strawberries\n        chosen_size = min(chosen_size, N - pos);\n        \n        partition.push_back(chosen_size);\n        if (chosen_size <= 10 && remaining_demand[chosen_size] > 0) {\n            remaining_demand[chosen_size]--;\n        }\n        pos += chosen_size;\n    }\n    \n    // Generate radial cuts between partition boundaries\n    vector<array<long long, 4>> cuts;\n    int cumulative = 0;\n    \n    for (int size : partition) {\n        cumulative += size;\n        \n        if (cumulative < N && cuts.size() < K) {\n            auto [x1, y1] = points[cumulative - 1];\n            auto [x2, y2] = points[cumulative];\n            \n            double a1 = atan2(y1, x1);\n            double a2 = atan2(y2, x2);\n            double mid = (a1 + a2) / 2.0;\n            \n            // Handle angle wrap-around (when crossing from +\u03c0 to -\u03c0)\n            if (a2 - a1 < -M_PI) {\n                mid += M_PI;\n            } else if (a2 - a1 > M_PI) {\n                mid -= M_PI;\n            }\n            \n            // Create line from origin through the midpoint angle\n            long long qx = llround(1e9 * cos(mid));\n            long long qy = llround(1e9 * sin(mid));\n            \n            cuts.push_back({0, 0, qx, qy});\n        }\n    }\n    \n    // Output\n    cout << cuts.size() << '\\n';\n    for (auto [px, py, qx, qy] : cuts) {\n        cout << px << ' ' << py << ' ' << qx << ' ' << qy << '\\n';\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint N, M;\nset<pair<int,int>> dots;\nvector<vector<int>> operations;\nset<pair<pair<int,int>, pair<int,int>>> usedUnitSegments;\nmt19937 rng(314159);\n\ndouble getWeight(int x, int y) {\n    double c = (N - 1) / 2.0;\n    return (x - c) * (x - c) + (y - c) * (y - c) + 1;\n}\n\nbool hasIntermediateDots(int x1, int y1, int x2, int y2) {\n    int dx = x2 - x1;\n    int dy = y2 - y1;\n    int g = __gcd(abs(dx), abs(dy));\n    if (g <= 1) return false;\n    \n    dx /= g;\n    dy /= g;\n    \n    for (int i = 1; i < g; i++) {\n        if (dots.count({x1 + dx * i, y1 + dy * i})) return true;\n    }\n    return false;\n}\n\nvector<pair<pair<int,int>, pair<int,int>>> getUnitSegments(int x1, int y1, int x2, int y2) {\n    vector<pair<pair<int,int>, pair<int,int>>> segments;\n    int dx = x2 - x1, dy = y2 - y1;\n    int g = __gcd(abs(dx), abs(dy));\n    if (g == 0) return segments;\n    \n    dx /= g;\n    dy /= g;\n    \n    for (int i = 0; i < g; i++) {\n        auto p1 = make_pair(x1 + dx * i, y1 + dy * i);\n        auto p2 = make_pair(x1 + dx * (i + 1), y1 + dy * (i + 1));\n        if (p1 > p2) swap(p1, p2);\n        segments.push_back({p1, p2});\n    }\n    return segments;\n}\n\nbool isValidRectangleOrder(const vector<int>& pts) {\n    int vx1 = pts[2] - pts[0], vy1 = pts[3] - pts[1];\n    int vx2 = pts[4] - pts[2], vy2 = pts[5] - pts[3];\n    int vx3 = pts[6] - pts[4], vy3 = pts[7] - pts[5];\n    int vx4 = pts[0] - pts[6], vy4 = pts[1] - pts[7];\n    \n    if (vx1 != -vx3 || vy1 != -vy3) return false;\n    if (vx2 != -vx4 || vy2 != -vy4) return false;\n    if (vx1 * vx2 + vy1 * vy2 != 0) return false;\n    \n    bool axisAligned = (vx1 == 0 || vy1 == 0) && (vx2 == 0 || vy2 == 0);\n    bool rotated45 = (abs(vx1) == abs(vy1)) && (abs(vx2) == abs(vy2)) && vx1 != 0 && vx2 != 0;\n    \n    return axisAligned || rotated45;\n}\n\nint getRectArea(const vector<int>& pts) {\n    int vx1 = pts[2] - pts[0], vy1 = pts[3] - pts[1];\n    int vx2 = pts[4] - pts[2], vy2 = pts[5] - pts[3];\n    return abs(vx1 * vy2 - vx2 * vy1);\n}\n\nbool tryAddDot(int x1, int y1, int maxDots) {\n    if (dots.count({x1, y1}) || x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) {\n        return false;\n    }\n    \n    vector<pair<int,int>> dotVec(dots.begin(), dots.end());\n    int n = dotVec.size();\n    \n    if (n > maxDots) {\n        shuffle(dotVec.begin(), dotVec.end(), rng);\n        dotVec.resize(maxDots);\n    }\n    n = dotVec.size();\n    \n    // Store candidates with (area, -weight, perm) for sorting\n    vector<pair<pair<int, double>, vector<int>>> candidates;\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = i + 1; j < n; j++) {\n            for (int k = j + 1; k < n; k++) {\n                int x2 = dotVec[i].first, y2 = dotVec[i].second;\n                int x3 = dotVec[j].first, y3 = dotVec[j].second;\n                int x4 = dotVec[k].first, y4 = dotVec[k].second;\n                \n                vector<vector<int>> perms = {\n                    {x1, y1, x2, y2, x3, y3, x4, y4},\n                    {x1, y1, x2, y2, x4, y4, x3, y3},\n                    {x1, y1, x3, y3, x2, y2, x4, y4},\n                    {x1, y1, x3, y3, x4, y4, x2, y2},\n                    {x1, y1, x4, y4, x2, y2, x3, y3},\n                    {x1, y1, x4, y4, x3, y3, x2, y2}\n                };\n                \n                for (auto& perm : perms) {\n                    if (!isValidRectangleOrder(perm)) continue;\n                    \n                    bool valid = true;\n                    vector<pair<pair<int,int>, pair<int,int>>> allSegments;\n                    \n                    for (int e = 0; e < 4; e++) {\n                        int ex1 = perm[e*2], ey1 = perm[e*2+1];\n                        int ex2 = perm[(e*2+2)%8], ey2 = perm[(e*2+3)%8];\n                        \n                        if (hasIntermediateDots(ex1, ey1, ex2, ey2)) {\n                            valid = false;\n                            break;\n                        }\n                        \n                        auto segments = getUnitSegments(ex1, ey1, ex2, ey2);\n                        for (auto& seg : segments) {\n                            if (usedUnitSegments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                            allSegments.push_back(seg);\n                        }\n                        if (!valid) break;\n                    }\n                    \n                    if (valid) {\n                        int area = getRectArea(perm);\n                        double weight = getWeight(x1, y1);\n                        // Primary: small area, Secondary: high weight (low distance from center)\n                        candidates.push_back({{area, -weight}, perm});\n                    }\n                }\n            }\n        }\n    }\n    \n    if (candidates.empty()) return false;\n    \n    sort(candidates.begin(), candidates.end());\n    vector<int> perm = candidates[0].second;\n    \n    vector<pair<pair<int,int>, pair<int,int>>> allSegments;\n    for (int e = 0; e < 4; e++) {\n        int ex1 = perm[e*2], ey1 = perm[e*2+1];\n        int ex2 = perm[(e*2+2)%8], ey2 = perm[(e*2+3)%8];\n        auto segments = getUnitSegments(ex1, ey1, ex2, ey2);\n        for (auto& seg : segments) allSegments.push_back(seg);\n    }\n    \n    dots.insert({x1, y1});\n    operations.push_back(perm);\n    for (auto& seg : allSegments) usedUnitSegments.insert(seg);\n    \n    return true;\n}\n\nint main() {\n    cin >> N >> M;\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        dots.insert({x, y});\n    }\n    \n    auto start = chrono::steady_clock::now();\n    double c = (N - 1) / 2.0;\n    \n    for (int pass = 0; pass < 40; pass++) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 4.75) break;\n        \n        vector<pair<double, pair<int,int>>> candidates;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (!dots.count({x, y})) {\n                    double dist = (x - c) * (x - c) + (y - c) * (y - c);\n                    double noise = (rng() % 1000) * 0.0005;\n                    candidates.push_back({dist + noise, {x, y}});\n                }\n            }\n        }\n        \n        sort(candidates.begin(), candidates.end());\n        \n        bool added = false;\n        // Adaptive: check more positions in early passes\n        int checkLimit = min((int)candidates.size(), max(200, 400 - pass * 5));\n        \n        for (int i = 0; i < checkLimit; i++) {\n            now = chrono::steady_clock::now();\n            elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > 4.75) goto done;\n            \n            // Adaptive search depth\n            int searchDepth = 100 + min(100, pass * 4);\n            if (tryAddDot(candidates[i].second.first, candidates[i].second.second, searchDepth)) {\n                added = true;\n            }\n        }\n        \n        if (!added) break;\n    }\n    \n    done:\n    cout << operations.size() << endl;\n    for (auto& op : operations) {\n        for (int i = 0; i < 8; i++) {\n            if (i > 0) cout << \" \";\n            cout << op[i];\n        }\n        cout << endl;\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nint board[N][N];\nint flavors[100];\n\nvoid tilt(int b[N][N], char dir) {\n    if (dir == 'F') {\n        for (int j = 0; j < N; j++) {\n            int pos = 0;\n            for (int i = 0; i < N; i++) {\n                if (b[i][j] > 0) {\n                    if (i != pos) {\n                        b[pos][j] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos++;\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < N; j++) {\n            int pos = N - 1;\n            for (int i = N - 1; i >= 0; i--) {\n                if (b[i][j] > 0) {\n                    if (i != pos) {\n                        b[pos][j] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos--;\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < N; i++) {\n            int pos = 0;\n            for (int j = 0; j < N; j++) {\n                if (b[i][j] > 0) {\n                    if (j != pos) {\n                        b[i][pos] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos++;\n                }\n            }\n        }\n    } else {\n        for (int i = 0; i < N; i++) {\n            int pos = N - 1;\n            for (int j = N - 1; j >= 0; j--) {\n                if (b[i][j] > 0) {\n                    if (j != pos) {\n                        b[i][pos] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos--;\n                }\n            }\n        }\n    }\n}\n\ndouble calcEvaluation(int b[N][N], int turn) {\n    bool vis[N][N] = {};\n    double score = 0;\n    int numComponents = 0;\n    \n    // Calculate connectivity score (main objective)\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] > 0 && !vis[i][j]) {\n                int flavor = b[i][j];\n                int size = 0;\n                queue<pair<int,int>> q;\n                q.push({i, j});\n                vis[i][j] = true;\n                \n                while (!q.empty()) {\n                    auto [ci, cj] = q.front();\n                    q.pop();\n                    size++;\n                    \n                    int di[] = {-1, 1, 0, 0};\n                    int dj[] = {0, 0, -1, 1};\n                    for (int d = 0; d < 4; d++) {\n                        int ni = ci + di[d];\n                        int nj = cj + dj[d];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N &&\n                            !vis[ni][nj] && b[ni][nj] == flavor) {\n                            vis[ni][nj] = true;\n                            q.push({ni, nj});\n                        }\n                    }\n                }\n                \n                score += size * size;\n                numComponents++;\n            }\n        }\n    }\n    \n    // Adjacent same-flavor bonus\n    int adjacentCount = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] > 0) {\n                if (i + 1 < N && b[i+1][j] == b[i][j]) adjacentCount++;\n                if (j + 1 < N && b[i][j+1] == b[i][j]) adjacentCount++;\n            }\n        }\n    }\n    score += adjacentCount * 8.0;\n    \n    // Component penalty\n    score -= numComponents * 2.0;\n    \n    // Future-weighted compactness guidance\n    double progress = (double)turn / 100.0;\n    if (progress < 0.6) {\n        double baseWeight = (0.6 - progress) * 0.08;\n        \n        // Count remaining candies of each flavor\n        int remaining[4] = {};\n        for (int t = turn + 1; t < 100; t++) {\n            remaining[flavors[t]]++;\n        }\n        \n        for (int f = 1; f <= 3; f++) {\n            vector<pair<int,int>> positions;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (b[i][j] == f) {\n                        positions.push_back({i, j});\n                    }\n                }\n            }\n            \n            if (positions.size() > 2) {\n                int minI = N, maxI = 0, minJ = N, maxJ = 0;\n                for (auto [i, j] : positions) {\n                    minI = min(minI, i);\n                    maxI = max(maxI, i);\n                    minJ = min(minJ, j);\n                    maxJ = max(maxJ, j);\n                }\n                \n                int area = (maxI - minI + 1) * (maxJ - minJ + 1);\n                double density = (double)positions.size() / area;\n                \n                // Weight by how many more candies of this flavor we'll see\n                double futureWeight = 1.0 + (double)remaining[f] / 20.0; // More remaining = higher weight\n                \n                score += density * 50.0 * baseWeight * futureWeight;\n            }\n        }\n    }\n    \n    return score;\n}\n\nchar chooseBest(int turn) {\n    char dirs[] = {'F', 'B', 'L', 'R'};\n    double best = -1e18;\n    char bestDir = 'F';\n    \n    for (char dir : dirs) {\n        int temp[N][N];\n        memcpy(temp, board, sizeof(board));\n        tilt(temp, dir);\n        double score = calcEvaluation(temp, turn);\n        \n        if (score > best) {\n            best = score;\n            bestDir = dir;\n        }\n    }\n    \n    return bestDir;\n}\n\nint main() {\n    for (int i = 0; i < 100; i++) {\n        cin >> flavors[i];\n    }\n    \n    memset(board, 0, sizeof(board));\n    \n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n        p--;\n        \n        int cnt = 0;\n        bool placed = false;\n        for (int i = 0; i < N && !placed; i++) {\n            for (int j = 0; j < N && !placed; j++) {\n                if (board[i][j] == 0) {\n                    if (cnt == p) {\n                        board[i][j] = flavors[t];\n                        placed = true;\n                    }\n                    cnt++;\n                }\n            }\n        }\n        \n        char dir = chooseBest(t);\n        cout << dir << endl;\n        cout.flush();\n        \n        tilt(board, dir);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint M;\ndouble eps;\nint N;\n\nclass Graph {\npublic:\n    int n;\n    vector<vector<int>> adj;\n    \n    Graph(int n = 0) : n(n), adj(n, vector<int>(n, 0)) {}\n    \n    string to_string() const {\n        string s;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                s += (adj[i][j] ? '1' : '0');\n            }\n        }\n        return s;\n    }\n    \n    void from_string(const string& s) {\n        int idx = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                adj[i][j] = adj[j][i] = (s[idx++] == '1');\n            }\n        }\n    }\n    \n    int count_components() const {\n        vector<bool> visited(n, false);\n        int components = 0;\n        \n        function<void(int)> dfs = [&](int u) {\n            visited[u] = true;\n            for (int v = 0; v < n; v++) {\n                if (adj[u][v] && !visited[v]) {\n                    dfs(v);\n                }\n            }\n        };\n        \n        for (int i = 0; i < n; i++) {\n            if (!visited[i]) {\n                dfs(i);\n                components++;\n            }\n        }\n        return components;\n    }\n    \n    vector<double> get_features() const {\n        vector<double> features;\n        \n        // 1. Edge count\n        int edges = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                edges += adj[i][j];\n            }\n        }\n        features.push_back(edges);\n        \n        // 2. Degree statistics\n        vector<int> degrees(n, 0);\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                degrees[i] += adj[i][j];\n            }\n        }\n        \n        // Max degree\n        int max_deg = *max_element(degrees.begin(), degrees.end());\n        features.push_back(max_deg);\n        \n        // Min degree\n        int min_deg = *min_element(degrees.begin(), degrees.end());\n        features.push_back(min_deg);\n        \n        // Degree variance\n        double mean_deg = accumulate(degrees.begin(), degrees.end(), 0.0) / n;\n        double variance = 0;\n        for (int d : degrees) {\n            variance += (d - mean_deg) * (d - mean_deg);\n        }\n        variance /= n;\n        features.push_back(variance);\n        \n        // Sorted degree sequence (top degrees only to save space)\n        sort(degrees.begin(), degrees.end(), greater<int>());\n        for (int i = 0; i < min(n, 15); i++) {\n            features.push_back(degrees[i]);\n        }\n        \n        // 3. Connected components\n        int components = count_components();\n        features.push_back(components);\n        \n        // 4. Triangle count\n        int triangles = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                if (!adj[i][j]) continue;\n                for (int k = j + 1; k < n; k++) {\n                    if (adj[i][k] && adj[j][k]) triangles++;\n                }\n            }\n        }\n        features.push_back(triangles);\n        \n        // 5. 4-cliques (only for smaller graphs)\n        if (n <= 25) {\n            int cliques4 = 0;\n            for (int i = 0; i < n; i++) {\n                for (int j = i + 1; j < n; j++) {\n                    if (!adj[i][j]) continue;\n                    for (int k = j + 1; k < n; k++) {\n                        if (!adj[i][k] || !adj[j][k]) continue;\n                        for (int l = k + 1; l < n; l++) {\n                            if (adj[i][l] && adj[j][l] && adj[k][l]) cliques4++;\n                        }\n                    }\n                }\n            }\n            features.push_back(cliques4);\n        }\n        \n        return features;\n    }\n};\n\nvector<Graph> graphs;\nvector<vector<double>> graph_features;\n\ndouble compute_distance(const vector<double>& f1, const vector<double>& f2) {\n    double dist = 0;\n    int idx = 0;\n    \n    // 1. Edge count - weight inversely to noise\n    double edge_weight = 10.0 / max(0.05, eps);\n    dist += abs(f1[idx] - f2[idx]) * edge_weight;\n    idx++;\n    \n    // 2. Max degree\n    double max_deg_weight = 8.0 / max(0.05, eps);\n    dist += abs(f1[idx] - f2[idx]) * max_deg_weight;\n    idx++;\n    \n    // 3. Min degree\n    double min_deg_weight = 5.0 / max(0.05, eps);\n    dist += abs(f1[idx] - f2[idx]) * min_deg_weight;\n    idx++;\n    \n    // 4. Degree variance\n    double var_weight = 2.0;\n    dist += abs(f1[idx] - f2[idx]) * var_weight;\n    idx++;\n    \n    // 5. Top degree sequence\n    double deg_weight = 1.5;\n    for (int i = 0; i < min(N, 15) && idx < (int)min(f1.size(), f2.size()); i++, idx++) {\n        dist += abs(f1[idx] - f2[idx]) * deg_weight;\n    }\n    \n    // 6. Connected components - very robust\n    double comp_weight = 15.0;\n    if (idx < (int)min(f1.size(), f2.size())) {\n        dist += abs(f1[idx] - f2[idx]) * comp_weight;\n        idx++;\n    }\n    \n    // 7. Triangle count\n    double tri_weight = 5.0 / max(0.1, eps);\n    if (idx < (int)min(f1.size(), f2.size())) {\n        dist += abs(f1[idx] - f2[idx]) * tri_weight;\n        idx++;\n    }\n    \n    // 8. 4-clique count\n    double clique_weight = 3.0 / max(0.1, eps);\n    if (idx < (int)min(f1.size(), f2.size())) {\n        dist += abs(f1[idx] - f2[idx]) * clique_weight;\n        idx++;\n    }\n    \n    return dist;\n}\n\nvoid generate_graphs() {\n    // Use proven N values from V1\n    if (eps <= 0.05) {\n        N = 10;\n    } else if (eps <= 0.15) {\n        N = 15;\n    } else if (eps <= 0.25) {\n        N = 20;\n    } else if (eps <= 0.35) {\n        N = 30;\n    } else {\n        N = 40;\n    }\n    \n    // Ensure sufficient capacity\n    N = max(N, (int)ceil(sqrt(2.0 * M)) + 4);\n    N = min(N, 100);\n    \n    graphs.resize(M, Graph(N));\n    int max_edges = N * (N - 1) / 2;\n    \n    // Optimized power curve considering both M and eps\n    double base_power = 1.0;\n    if (M > 50) {\n        base_power += 0.15; // More separation for large M\n    }\n    double eps_factor = min(0.25, eps * 0.7);\n    double power = base_power + eps_factor;\n    \n    for (int k = 0; k < M; k++) {\n        double ratio = (double)k / max(1, M - 1);\n        double scaled = pow(ratio, power);\n        int target_edges = (int)(scaled * max_edges);\n        \n        // Add edges sequentially\n        int added = 0;\n        for (int i = 0; i < N && added < target_edges; i++) {\n            for (int j = i + 1; j < N && added < target_edges; j++) {\n                graphs[k].adj[i][j] = graphs[k].adj[j][i] = 1;\n                added++;\n            }\n        }\n    }\n    \n    // Precompute features\n    graph_features.resize(M);\n    for (int k = 0; k < M; k++) {\n        graph_features[k] = graphs[k].get_features();\n    }\n}\n\nint decode_graph(const Graph& h) {\n    auto h_features = h.get_features();\n    \n    int best = 0;\n    double min_dist = 1e18;\n    \n    for (int k = 0; k < M; k++) {\n        double dist = compute_distance(h_features, graph_features[k]);\n        if (dist < min_dist) {\n            min_dist = dist;\n            best = k;\n        }\n    }\n    \n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> M >> eps;\n    \n    generate_graphs();\n    \n    cout << N << \"\\n\";\n    for (const auto& g : graphs) {\n        cout << g.to_string() << \"\\n\";\n    }\n    cout.flush();\n    \n    for (int q = 0; q < 100; q++) {\n        string s;\n        cin >> s;\n        \n        Graph h(N);\n        h.from_string(s);\n        \n        int t = decode_graph(h);\n        cout << t << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, D, K;\nvector<array<int, 3>> edges;\nvector<vector<int>> graph;\nvector<int> degree;\n\nint main() {\n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    graph.resize(N);\n    degree.resize(N);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i][0] >> edges[i][1] >> edges[i][2];\n        edges[i][0]--; edges[i][1]--;\n        \n        graph[edges[i][0]].push_back(i);\n        graph[edges[i][1]].push_back(i);\n        \n        degree[edges[i][0]]++;\n        degree[edges[i][1]]++;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Calculate edge importance\n    vector<pair<double, int>> edge_scores;\n    for (int i = 0; i < M; i++) {\n        int u = edges[i][0];\n        int v = edges[i][1];\n        long long w = edges[i][2];\n        \n        double degree_factor = 1.0 / (degree[u] * degree[v]);\n        double weight_factor = (double)w / 1000000.0;\n        double score = degree_factor * 100.0 + weight_factor;\n        \n        edge_scores.push_back({score, i});\n    }\n    \n    sort(edge_scores.begin(), edge_scores.end(), greater<>());\n    \n    // Greedy assignment with degree-aware penalties\n    vector<int> assignment(M, 0);\n    vector<vector<int>> day_edges(D + 1);\n    vector<map<int, int>> day_vertex_edges(D + 1); // count edges per vertex per day\n    \n    for (auto [score, eid] : edge_scores) {\n        int u = edges[eid][0];\n        int v = edges[eid][1];\n        \n        int best_day = 1;\n        double best_cost = 1e18;\n        \n        for (int d = 1; d <= D; d++) {\n            double cost = day_edges[d].size();\n            \n            // Penalty scaled by vertex degree and existing edge count\n            // Lower degree vertices are more critical, so higher penalty\n            if (day_vertex_edges[d].count(u)) {\n                double base_penalty = 20.0 / degree[u];\n                cost += base_penalty * (1 + day_vertex_edges[d][u] * 0.5);\n            }\n            if (day_vertex_edges[d].count(v)) {\n                double base_penalty = 20.0 / degree[v];\n                cost += base_penalty * (1 + day_vertex_edges[d][v] * 0.5);\n            }\n            \n            if (cost < best_cost) {\n                best_cost = cost;\n                best_day = d;\n            }\n        }\n        \n        assignment[eid] = best_day;\n        day_edges[best_day].push_back(eid);\n        day_vertex_edges[best_day][u]++;\n        day_vertex_edges[best_day][v]++;\n    }\n    \n    // Light hill-climbing: try swapping edges between days\n    for (int iter = 0; iter < 500; iter++) {\n        int d1 = 1 + (iter % D);\n        int d2 = 1 + ((iter + D/2) % D);\n        if (d1 == d2 || day_edges[d1].empty() || day_edges[d2].empty()) continue;\n        \n        // Try swapping random edges\n        int idx1 = iter % day_edges[d1].size();\n        int idx2 = iter % day_edges[d2].size();\n        int e1 = day_edges[d1][idx1];\n        int e2 = day_edges[d2][idx2];\n        \n        // Quick heuristic: prefer swaps that reduce vertex overlap\n        set<int> v1 = {edges[e1][0], edges[e1][1]};\n        set<int> v2 = {edges[e2][0], edges[e2][1]};\n        \n        int overlap_before = 0, overlap_after = 0;\n        for (int e : day_edges[d1]) {\n            if (e != e1) {\n                if (v1.count(edges[e][0]) || v1.count(edges[e][1])) overlap_before++;\n                if (v2.count(edges[e][0]) || v2.count(edges[e][1])) overlap_after++;\n            }\n        }\n        for (int e : day_edges[d2]) {\n            if (e != e2) {\n                if (v2.count(edges[e][0]) || v2.count(edges[e][1])) overlap_before++;\n                if (v1.count(edges[e][0]) || v1.count(edges[e][1])) overlap_after++;\n            }\n        }\n        \n        if (overlap_after < overlap_before) {\n            swap(assignment[e1], assignment[e2]);\n            day_edges[d1][idx1] = e2;\n            day_edges[d2][idx2] = e1;\n        }\n    }\n    \n    for (int i = 0; i < M; i++) {\n        cout << assignment[i];\n        if (i < M - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f1, r1, f2, r2;\n\nbool isOccupied(int x, int y, int z, const vector<string>& f, const vector<string>& r) {\n    return f[z][x] == '1' && r[z][y] == '1';\n}\n\nset<tuple<int,int,int>> getComponent(tuple<int,int,int> start, \n                                      set<tuple<int,int,int>>& available) {\n    set<tuple<int,int,int>> component;\n    queue<tuple<int,int,int>> q;\n    q.push(start);\n    available.erase(start);\n    component.insert(start);\n    \n    int dx[] = {1, -1, 0, 0, 0, 0};\n    int dy[] = {0, 0, 1, -1, 0, 0};\n    int dz[] = {0, 0, 0, 0, 1, -1};\n    \n    while (!q.empty()) {\n        auto [x, y, z] = q.front();\n        q.pop();\n        \n        for (int i = 0; i < 6; i++) {\n            int nx = x + dx[i];\n            int ny = y + dy[i];\n            int nz = z + dz[i];\n            auto next = make_tuple(nx, ny, nz);\n            \n            if (available.count(next)) {\n                available.erase(next);\n                component.insert(next);\n                q.push(next);\n            }\n        }\n    }\n    \n    return component;\n}\n\nint main() {\n    cin >> D;\n    f1.resize(D); r1.resize(D); f2.resize(D); r2.resize(D);\n    \n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n    \n    // Get occupied cells for both configurations\n    set<tuple<int,int,int>> occ1, occ2;\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 (isOccupied(x, y, z, f1, r1)) occ1.insert({x, y, z});\n                if (isOccupied(x, y, z, f2, r2)) occ2.insert({x, y, z});\n            }\n        }\n    }\n    \n    // Find common positions (occupied in both configs)\n    set<tuple<int,int,int>> common;\n    for (auto pos : occ1) {\n        if (occ2.count(pos)) {\n            common.insert(pos);\n        }\n    }\n    \n    // Create shared blocks from common positions\n    vector<set<tuple<int,int,int>>> sharedBlocks;\n    auto availableCommon = common;\n    while (!availableCommon.empty()) {\n        auto start = *availableCommon.begin();\n        sharedBlocks.push_back(getComponent(start, availableCommon));\n    }\n    \n    // Create unique blocks for config 1\n    set<tuple<int,int,int>> unique1;\n    for (auto pos : occ1) {\n        if (!common.count(pos)) unique1.insert(pos);\n    }\n    \n    vector<set<tuple<int,int,int>>> blocks1;\n    auto available1 = unique1;\n    while (!available1.empty()) {\n        auto start = *available1.begin();\n        blocks1.push_back(getComponent(start, available1));\n    }\n    \n    // Create unique blocks for config 2\n    set<tuple<int,int,int>> unique2;\n    for (auto pos : occ2) {\n        if (!common.count(pos)) unique2.insert(pos);\n    }\n    \n    vector<set<tuple<int,int,int>>> blocks2;\n    auto available2 = unique2;\n    while (!available2.empty()) {\n        auto start = *available2.begin();\n        blocks2.push_back(getComponent(start, available2));\n    }\n    \n    // Assign block IDs\n    vector<vector<vector<int>>> b1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> b2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    \n    int nextId = 1;\n    \n    // Assign shared blocks (used in both configurations)\n    for (auto& block : sharedBlocks) {\n        int id = nextId++;\n        for (auto [x, y, z] : block) {\n            b1[x][y][z] = id;\n            b2[x][y][z] = id;\n        }\n    }\n    \n    // Assign unique blocks for config 1\n    for (auto& block : blocks1) {\n        int id = nextId++;\n        for (auto [x, y, z] : block) {\n            b1[x][y][z] = id;\n        }\n    }\n    \n    // Assign unique blocks for config 2\n    for (auto& block : blocks2) {\n        int id = nextId++;\n        for (auto [x, y, z] : block) {\n            b2[x][y][z] = id;\n        }\n    }\n    \n    // Output\n    cout << nextId - 1 << endl;\n    \n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            for (int z = 0; z < D; z++) {\n                if (x > 0 || y > 0 || z > 0) cout << \" \";\n                cout << b1[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n    \n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            for (int z = 0; z < D; z++) {\n                if (x > 0 || y > 0 || z > 0) cout << \" \";\n                cout << b2[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<long long> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    struct Edge {\n        int u, v, id;\n        long long w;\n    };\n    \n    vector<Edge> edges(M);\n    map<pair<int,int>, int> edge_map;\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--; edges[i].v--;\n        edges[i].id = i;\n        edge_map[{min(edges[i].u, edges[i].v), max(edges[i].u, edges[i].v)}] = i;\n    }\n    \n    vector<long long> a(K), b(K);\n    for (int i = 0; i < K; i++) {\n        cin >> a[i] >> b[i];\n    }\n    \n    auto dist = [](long long x1, long long y1, long long x2, long long y2) {\n        long long dx = x1 - x2;\n        long long dy = y1 - y2;\n        return sqrt((double)(dx * dx + dy * dy));\n    };\n    \n    // Build MST\n    vector<Edge> sorted_edges = edges;\n    sort(sorted_edges.begin(), sorted_edges.end(), [](const Edge& a, const Edge& b) {\n        return a.w < b.w;\n    });\n    \n    vector<int> parent(N);\n    iota(parent.begin(), parent.end(), 0);\n    \n    function<int(int)> find = [&](int v) {\n        return parent[v] == v ? v : parent[v] = find(parent[v]);\n    };\n    \n    set<int> active_vertices;\n    active_vertices.insert(0);\n    vector<vector<pair<int, long long>>> tree_adj(N);\n    \n    for (const Edge& e : sorted_edges) {\n        int pu = find(e.u), pv = find(e.v);\n        if (pu != pv) {\n            parent[pu] = pv;\n            active_vertices.insert(e.u);\n            active_vertices.insert(e.v);\n            tree_adj[e.u].push_back({e.v, e.w});\n            tree_adj[e.v].push_back({e.u, e.w});\n        }\n    }\n    \n    auto get_reachable = [&]() {\n        set<int> reachable;\n        queue<int> q;\n        q.push(0);\n        reachable.insert(0);\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (auto [v, w] : tree_adj[u]) {\n                if (active_vertices.count(v) && !reachable.count(v)) {\n                    reachable.insert(v);\n                    q.push(v);\n                }\n            }\n        }\n        return reachable;\n    };\n    \n    auto compute_assignment = [&](const set<int>& vertices) {\n        vector<int> P(N, 0);\n        vector<int> assignment(K, -1);\n        \n        for (int k = 0; k < K; k++) {\n            int best_v = -1;\n            double best_d = 1e18;\n            \n            for (int v : vertices) {\n                double d = dist(a[k], b[k], x[v], y[v]);\n                if (d < best_d) {\n                    best_d = d;\n                    best_v = v;\n                }\n            }\n            \n            if (best_v != -1 && best_d <= 5000) {\n                int required = (int)ceil(best_d);\n                P[best_v] = max(P[best_v], required);\n                assignment[k] = best_v;\n            }\n        }\n        return make_pair(P, assignment);\n    };\n    \n    auto verify_coverage = [&](const set<int>& vertices, const vector<int>& powers) {\n        for (int k = 0; k < K; k++) {\n            bool covered = false;\n            for (int v : vertices) {\n                double d = dist(a[k], b[k], x[v], y[v]);\n                if (d <= powers[v]) {\n                    covered = true;\n                    break;\n                }\n            }\n            if (!covered) return false;\n        }\n        return true;\n    };\n    \n    auto [P, assignment] = compute_assignment(active_vertices);\n    \n    // Smart pruning with cost/benefit analysis\n    for (int iter = 0; iter < 30; iter++) {\n        bool changed = false;\n        auto reachable = get_reachable();\n        \n        vector<tuple<double, int>> candidates;\n        \n        for (int v : reachable) {\n            if (v == 0) continue;\n            \n            int degree = 0;\n            long long edge_cost = 0;\n            \n            for (auto [u, w] : tree_adj[v]) {\n                if (active_vertices.count(u) && reachable.count(u)) {\n                    degree++;\n                    edge_cost = w;\n                    if (degree > 1) break;\n                }\n            }\n            \n            if (degree != 1) continue;\n            \n            long long vertex_cost = (long long)P[v] * P[v] + edge_cost;\n            int resident_count = count(assignment.begin(), assignment.end(), v);\n            \n            double ratio = (double)vertex_cost / max(1, resident_count);\n            candidates.push_back({ratio, v});\n        }\n        \n        sort(candidates.begin(), candidates.end(), greater<>());\n        \n        for (auto [ratio, v] : candidates) {\n            if (!active_vertices.count(v)) continue;\n            \n            set<int> test_vertices = active_vertices;\n            test_vertices.erase(v);\n            \n            auto [test_P, test_assignment] = compute_assignment(test_vertices);\n            \n            if (!verify_coverage(test_vertices, test_P)) continue;\n            \n            long long old_cost = 0, new_cost = 0;\n            for (int u : active_vertices) {\n                old_cost += (long long)P[u] * P[u];\n            }\n            for (int u : test_vertices) {\n                new_cost += (long long)test_P[u] * test_P[u];\n            }\n            \n            // Add edge costs\n            for (auto [u, w] : tree_adj[v]) {\n                if (active_vertices.count(u) && reachable.count(u)) {\n                    old_cost += w;\n                }\n            }\n            \n            if (new_cost < old_cost) {\n                active_vertices = test_vertices;\n                P = test_P;\n                assignment = test_assignment;\n                changed = true;\n                break;\n            }\n        }\n        \n        if (!changed) break;\n    }\n    \n    // Optimize assignments\n    for (int iter = 0; iter < 10; iter++) {\n        bool improved = false;\n        auto reachable = get_reachable();\n        \n        for (int k = 0; k < K; k++) {\n            int cur_v = assignment[k];\n            if (cur_v == -1) continue;\n            \n            for (int new_v : reachable) {\n                if (new_v == cur_v) continue;\n                \n                double d = dist(a[k], b[k], x[new_v], y[new_v]);\n                if (d > 5000) continue;\n                \n                vector<int> test_P = P;\n                \n                // Recompute power for cur_v\n                test_P[cur_v] = 0;\n                for (int k2 = 0; k2 < K; k2++) {\n                    if (assignment[k2] == cur_v && k2 != k) {\n                        double d2 = dist(a[k2], b[k2], x[cur_v], y[cur_v]);\n                        test_P[cur_v] = max(test_P[cur_v], (int)ceil(d2));\n                    }\n                }\n                \n                test_P[new_v] = max(test_P[new_v], (int)ceil(d));\n                \n                long long old_cost = (long long)P[cur_v] * P[cur_v] + (long long)P[new_v] * P[new_v];\n                long long new_cost = (long long)test_P[cur_v] * test_P[cur_v] + (long long)test_P[new_v] * test_P[new_v];\n                \n                if (new_cost < old_cost) {\n                    P = test_P;\n                    assignment[k] = new_v;\n                    improved = true;\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Final verification\n    auto reachable = get_reachable();\n    if (!verify_coverage(reachable, P)) {\n        auto [safe_P, safe_assignment] = compute_assignment(reachable);\n        P = safe_P;\n    }\n    \n    // Build output\n    vector<int> edge_on(M, 0);\n    vector<bool> visited(N, false);\n    queue<int> q;\n    q.push(0);\n    visited[0] = true;\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        \n        for (auto [v, w] : tree_adj[u]) {\n            if (!visited[v] && active_vertices.count(v)) {\n                visited[v] = true;\n                q.push(v);\n                \n                auto it = edge_map.find({min(u, v), max(u, v)});\n                if (it != edge_map.end()) {\n                    edge_on[it->second] = 1;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << P[i];\n    }\n    cout << \"\\n\";\n    \n    for (int i = 0; i < M; i++) {\n        if (i > 0) cout << \" \";\n        cout << edge_on[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <tuple>\nusing namespace std;\n\nconst int N = 30;\nconst int MAX_OPS = 9900;\n\nvector<vector<int>> pyramid;\nvector<tuple<int,int,int,int>> operations;\n\nvoid swap_balls(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    operations.push_back({x1, y1, x2, y2});\n}\n\nint count_violations() {\n    int count = 0;\n    for (int x = 0; x < N-1; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) count++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) count++;\n        }\n    }\n    return count;\n}\n\nvoid sink(int x, int y) {\n    while (x < N-1 && operations.size() < MAX_OPS) {\n        int current = pyramid[x][y];\n        int left_child = pyramid[x+1][y];\n        int right_child = pyramid[x+1][y+1];\n        \n        if (current <= left_child && current <= right_child) {\n            break;\n        }\n        \n        if (left_child < right_child) {\n            swap_balls(x, y, x+1, y);\n            x++;\n        } else {\n            swap_balls(x, y, x+1, y+1);\n            x++;\n            y++;\n        }\n    }\n}\n\nvoid solve() {\n    // Phase 1: Initial heapify from bottom to top\n    for (int x = N-2; x >= 0 && operations.size() < MAX_OPS; x--) {\n        for (int y = 0; y <= x && operations.size() < MAX_OPS; y++) {\n            sink(x, y);\n        }\n    }\n    \n    // Phase 2: Fix remaining violations with multiple passes\n    for (int pass = 0; pass < 50 && operations.size() < MAX_OPS; pass++) {\n        if (count_violations() == 0) break;\n        \n        for (int x = 0; x < N-1 && operations.size() < MAX_OPS; x++) {\n            for (int y = 0; y <= x && operations.size() < MAX_OPS; y++) {\n                int current = pyramid[x][y];\n                int left_child = pyramid[x+1][y];\n                int right_child = pyramid[x+1][y+1];\n                \n                if (current > left_child || current > right_child) {\n                    sink(x, y);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    pyramid.resize(N);\n    for (int x = 0; x < N; x++) {\n        pyramid[x].resize(x+1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    solve();\n    \n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int D = 9;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\n\nint N;\nbool obstacle[D][D];\nint container[D][D];\nconst int entrance_x = 0;\nconst int entrance_y = 4;\nvector<vector<int>> dist_from_entrance;\n\nbool isValid(int x, int y) {\n    return x >= 0 && x < D && y >= 0 && y < D;\n}\n\nset<pair<int,int>> getReachable() {\n    set<pair<int,int>> reachable;\n    queue<pair<int,int>> q;\n    q.push({entrance_x, entrance_y});\n    reachable.insert({entrance_x, entrance_y});\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (isValid(nx, ny) && !obstacle[nx][ny] && \n                container[nx][ny] == -1 && \n                reachable.find({nx, ny}) == reachable.end()) {\n                reachable.insert({nx, ny});\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return reachable;\n}\n\nvoid calcDistances() {\n    dist_from_entrance.assign(D, vector<int>(D, -1));\n    queue<pair<int,int>> q;\n    q.push({entrance_x, entrance_y});\n    dist_from_entrance[entrance_x][entrance_y] = 0;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (isValid(nx, ny) && !obstacle[nx][ny] && dist_from_entrance[nx][ny] == -1) {\n                dist_from_entrance[nx][ny] = dist_from_entrance[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n}\n\nint main() {\n    int D_input;\n    cin >> D_input >> N;\n    \n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            obstacle[i][j] = false;\n            container[i][j] = -1;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        obstacle[x][y] = true;\n    }\n    \n    calcDistances();\n    \n    int max_dist = 0;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (dist_from_entrance[i][j] > max_dist) {\n                max_dist = dist_from_entrance[i][j];\n            }\n        }\n    }\n    \n    int total_containers = D * D - 1 - N;\n    \n    // Placement phase\n    for (int d = 0; d < total_containers; d++) {\n        int t;\n        cin >> t;\n        \n        set<pair<int,int>> reachable = getReachable();\n        \n        // Map container number to target distance\n        double ratio = (double)t / max(1, total_containers - 1);\n        int target_dist = 1 + (int)(ratio * (max_dist - 1));\n        \n        // Find reachable cell closest to target distance\n        pair<int,int> chosen = {-1, -1};\n        int min_diff = 1000000;\n        \n        for (auto [x, y] : reachable) {\n            if (container[x][y] == -1 && (x != entrance_x || y != entrance_y)) {\n                int cell_dist = dist_from_entrance[x][y];\n                int diff = abs(cell_dist - target_dist);\n                if (diff < min_diff || \n                    (diff == min_diff && chosen.first != -1 && \n                     cell_dist < dist_from_entrance[chosen.first][chosen.second])) {\n                    min_diff = diff;\n                    chosen = {x, y};\n                }\n            }\n        }\n        \n        container[chosen.first][chosen.second] = t;\n        cout << chosen.first << \" \" << chosen.second << endl;\n        cout.flush();\n    }\n    \n    // Retrieval phase: always pick smallest accessible\n    for (int i = 0; i < total_containers; i++) {\n        set<pair<int,int>> reachable = getReachable();\n        \n        int min_num = total_containers;\n        pair<int,int> min_pos = {-1, -1};\n        \n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (container[x][y] >= 0 && reachable.count({x, y})) {\n                    if (container[x][y] < min_num) {\n                        min_num = container[x][y];\n                        min_pos = {x, y};\n                    }\n                }\n            }\n        }\n        \n        cout << min_pos.first << \" \" << min_pos.second << endl;\n        container[min_pos.first][min_pos.second] = -1;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n, m;\nvector<vector<int>> grid;\nset<pair<int,int>> required_adj;\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\n\nvoid buildAdj(vector<vector<int>>& g, set<pair<int,int>>& adj_pairs) {\n    adj_pairs.clear();\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c = g[i][j];\n            if (i == 0 || i == n-1 || j == 0 || j == n-1) {\n                if (c != 0) adj_pairs.insert({0, c});\n            }\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                    int nc = g[ni][nj];\n                    if (c != nc) {\n                        adj_pairs.insert({min(c, nc), max(c, nc)});\n                    }\n                }\n            }\n        }\n    }\n}\n\nbool isConnected(vector<vector<int>>& g, int color) {\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (g[i][j] == color) cells.push_back({i, j});\n        }\n    }\n    \n    if (cells.empty()) return true;\n    \n    if (color == 0) {\n        // For color 0: all cells must reach the boundary\n        set<pair<int,int>> reachable;\n        queue<pair<int,int>> bfs;\n        \n        for (auto [i, j] : cells) {\n            if (i == 0 || i == n-1 || j == 0 || j == n-1) {\n                bfs.push({i, j});\n                reachable.insert({i, j});\n            }\n        }\n        \n        while (!bfs.empty()) {\n            auto [x, y] = bfs.front();\n            bfs.pop();\n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d], ny = y + dy[d];\n                if (nx >= 0 && nx < n && ny >= 0 && ny < n && \n                    g[nx][ny] == 0 && !reachable.count({nx, ny})) {\n                    reachable.insert({nx, ny});\n                    bfs.push({nx, ny});\n                }\n            }\n        }\n        return reachable.size() == cells.size();\n    }\n    \n    set<pair<int,int>> visited;\n    queue<pair<int,int>> bfs;\n    bfs.push(cells[0]);\n    visited.insert(cells[0]);\n    \n    while (!bfs.empty()) {\n        auto [x, y] = bfs.front();\n        bfs.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < n && ny >= 0 && ny < n && \n                g[nx][ny] == color && !visited.count({nx, ny})) {\n                visited.insert({nx, ny});\n                bfs.push({nx, ny});\n            }\n        }\n    }\n    return visited.size() == cells.size();\n}\n\nint main() {\n    cin >> n >> m;\n    grid.assign(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n        }\n    }\n    \n    buildAdj(grid, required_adj);\n    auto result = grid;\n    \n    // Iteratively try to remove cells\n    for (int iter = 0; iter < 3; iter++) {\n        bool changed = true;\n        while (changed) {\n            changed = false;\n            for (int i = 1; i < n-1; i++) {\n                for (int j = 1; j < n-1; j++) {\n                    if (result[i][j] == 0) continue;\n                    \n                    int color = result[i][j];\n                    result[i][j] = 0;\n                    \n                    // Quick check: is this color still connected?\n                    if (!isConnected(result, color) || !isConnected(result, 0)) {\n                        result[i][j] = color;\n                        continue;\n                    }\n                    \n                    // Check adjacencies\n                    set<pair<int,int>> new_adj;\n                    buildAdj(result, new_adj);\n                    \n                    if (new_adj == required_adj) {\n                        changed = true;\n                    } else {\n                        result[i][j] = color;\n                    }\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint query_count = 0;\n\nchar do_query(vector<int> L, vector<int> R) {\n    query_count++;\n    cout << L.size() << \" \" << R.size();\n    for(int x : L) cout << \" \" << x;\n    for(int x : R) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\nvoid merge(vector<int>& items, int left, int mid, int right, int query_budget) {\n    vector<int> temp;\n    int i = left, j = mid + 1;\n    \n    while(i <= mid && j <= right) {\n        if(query_count >= query_budget) {\n            while(i <= mid) temp.push_back(items[i++]);\n            while(j <= right) temp.push_back(items[j++]);\n            break;\n        }\n        \n        char result = do_query({items[i]}, {items[j]});\n        if(result != '>') {\n            temp.push_back(items[i++]);\n        } else {\n            temp.push_back(items[j++]);\n        }\n    }\n    \n    while(i <= mid) temp.push_back(items[i++]);\n    while(j <= right) temp.push_back(items[j++]);\n    \n    for(int k = 0; k < temp.size(); k++) {\n        items[left + k] = temp[k];\n    }\n}\n\nvoid mergeSort(vector<int>& items, int left, int right, int query_budget) {\n    if(left >= right || query_count >= query_budget) return;\n    \n    int mid = (left + right) / 2;\n    mergeSort(items, left, mid, query_budget);\n    mergeSort(items, mid + 1, right, query_budget);\n    merge(items, left, mid, right, query_budget);\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    // Use most queries for sorting\n    int sort_budget = Q - 20;\n    mergeSort(items, 0, N - 1, sort_budget);\n    \n    // Estimate weights using exponential distribution\n    vector<double> weight_est(N);\n    for(int i = 0; i < N; i++) {\n        double q = (i + 0.5) / N;\n        weight_est[items[i]] = -log(1.0 - q) * 100000.0;\n    }\n    \n    // Greedy assignment: add each item to currently lightest group\n    vector<int> assignment(N);\n    vector<vector<int>> groups(D);\n    vector<double> group_weight(D, 0.0);\n    \n    for(int i = N-1; i >= 0; i--) {\n        int min_g = min_element(group_weight.begin(), group_weight.end()) - group_weight.begin();\n        assignment[items[i]] = min_g;\n        groups[min_g].push_back(items[i]);\n        group_weight[min_g] += weight_est[items[i]];\n    }\n    \n    // Light refinement: only try moves that seem very beneficial\n    for(int round = 0; round < 3 && query_count < Q - 1; round++) {\n        int max_g = max_element(group_weight.begin(), group_weight.end()) - group_weight.begin();\n        int min_g = min_element(group_weight.begin(), group_weight.end()) - group_weight.begin();\n        \n        double imbalance = group_weight[max_g] - group_weight[min_g];\n        if(imbalance < 1000 || groups[max_g].size() <= 1) break;\n        \n        // Find lightest item in heavy group\n        int best_item = -1;\n        double best_weight = 1e18;\n        for(int item : groups[max_g]) {\n            if(weight_est[item] < best_weight) {\n                best_weight = weight_est[item];\n                best_item = item;\n            }\n        }\n        \n        if(best_item == -1) break;\n        \n        // Only move if estimated improvement is significant\n        double new_max = group_weight[max_g] - weight_est[best_item];\n        double new_min = group_weight[min_g] + weight_est[best_item];\n        double new_imbalance = abs(new_max - new_min);\n        \n        if(new_imbalance >= imbalance * 0.8) break; // Not worth it\n        \n        // Verify with query\n        vector<int> heavy_without, light_with;\n        for(int x : groups[max_g]) {\n            if(x != best_item) heavy_without.push_back(x);\n        }\n        for(int x : groups[min_g]) {\n            light_with.push_back(x);\n        }\n        light_with.push_back(best_item);\n        \n        if(!heavy_without.empty()) {\n            char result = do_query(heavy_without, light_with);\n            \n            if(result != '>') {\n                // Move\n                groups[max_g].erase(find(groups[max_g].begin(), groups[max_g].end(), best_item));\n                groups[min_g].push_back(best_item);\n                assignment[best_item] = min_g;\n                group_weight[max_g] -= weight_est[best_item];\n                group_weight[min_g] += weight_est[best_item];\n            }\n        }\n    }\n    \n    // Use remaining queries\n    while(query_count < Q) {\n        do_query({0}, {1});\n    }\n    \n    // Output\n    for(int i = 0; i < N; i++) {\n        if(i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\n// Calculate cascading conflict cost for a destination\ndouble calculate_cascade_cost(const vector<int>& dest_stack, const vector<int>& moving_boxes, int current_target) {\n    if (dest_stack.empty()) return 0;\n    \n    int min_moving = *min_element(moving_boxes.begin(), moving_boxes.end());\n    \n    double total_cost = 0;\n    \n    // For each box in destination that will cause conflict\n    for (int i = 0; i < (int)dest_stack.size(); i++) {\n        if (dest_stack[i] < min_moving) {\n            // This box will need to be extracted before our moved boxes\n            // Calculate the \"cascade depth\" - how many boxes are involved\n            int boxes_above = dest_stack.size() - i;\n            int extraction_distance = dest_stack[i] - current_target;\n            \n            // Quadratic penalty for depth, linear for distance\n            double cascade_factor = boxes_above * boxes_above * extraction_distance * 0.3;\n            total_cost += cascade_factor;\n            \n            // Additional penalty if multiple conflicts\n            if (i > 0) {\n                // Deeper conflicts compound\n                total_cost += i * i * 10;\n            }\n        }\n    }\n    \n    return total_cost;\n}\n\n// Improved simulation\nint simulate_future(vector<vector<int>> stacks, int m, int start, int depth) {\n    int energy = 0;\n    \n    for (int t = start; t < min(start + depth, 201); t++) {\n        int sid = -1, p = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == t) {\n                    sid = i; p = j; break;\n                }\n            }\n            if (sid != -1) break;\n        }\n        \n        if (p < (int)stacks[sid].size() - 1) {\n            vector<int> mov;\n            for (int i = p + 1; i < (int)stacks[sid].size(); i++) {\n                mov.push_back(stacks[sid][i]);\n            }\n            energy += mov.size() + 1;\n            \n            int best = -1;\n            double best_sc = -1e18;\n            int min_m = *min_element(mov.begin(), mov.end());\n            \n            // Count empty stacks for strategic use\n            int empty_count = 0;\n            for (int i = 0; i < m; i++) {\n                if (stacks[i].empty()) empty_count++;\n            }\n            \n            for (int i = 0; i < m; i++) {\n                if (i == sid) continue;\n                \n                double sc = 0;\n                \n                if (stacks[i].empty()) {\n                    // Reserve some empty stacks for emergency\n                    if (empty_count <= 2) {\n                        sc = 1e11; // Very high priority\n                    } else {\n                        sc = 1e10;\n                    }\n                } else {\n                    double cascade = calculate_cascade_cost(stacks[i], mov, t);\n                    \n                    if (cascade < 0.1) {\n                        // No conflicts - safe placement\n                        sc = 1e9 - stacks[i].size() * 50;\n                    } else {\n                        // Has conflicts\n                        sc = -cascade * 100 - stacks[i].size() * 10;\n                    }\n                }\n                \n                if (sc > best_sc) {\n                    best_sc = sc;\n                    best = i;\n                }\n            }\n            \n            stacks[sid].resize(p + 1);\n            for (int x : mov) stacks[best].push_back(x);\n        }\n        stacks[sid].pop_back();\n    }\n    \n    return energy;\n}\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<pair<int, int>> operations;\n    \n    for (int target = 1; target <= n; target++) {\n        int stack_id = -1, pos = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == target) {\n                    stack_id = i; pos = j; break;\n                }\n            }\n            if (stack_id != -1) break;\n        }\n        \n        if (pos < (int)stacks[stack_id].size() - 1) {\n            vector<int> moving;\n            for (int i = pos + 1; i < (int)stacks[stack_id].size(); i++) {\n                moving.push_back(stacks[stack_id][i]);\n            }\n            \n            int best_dest = -1;\n            double best_total = 1e18;\n            \n            // Count empty stacks\n            int empty_stacks = 0;\n            for (int i = 0; i < m; i++) {\n                if (stacks[i].empty()) empty_stacks++;\n            }\n            \n            for (int dest = 0; dest < m; dest++) {\n                if (dest == stack_id) continue;\n                \n                auto s1 = stacks;\n                s1[stack_id].resize(pos + 1);\n                for (int x : moving) s1[dest].push_back(x);\n                \n                double immediate_cost = moving.size() + 1;\n                \n                // Calculate cascade cost\n                double cascade = calculate_cascade_cost(stacks[dest], moving, target);\n                \n                // Future simulation (deeper lookahead)\n                double future_cost = simulate_future(s1, m, target + 1, 35);\n                \n                // Strategic bonuses\n                double bonus = 0;\n                if (stacks[dest].empty()) {\n                    // Keep some empty for emergencies\n                    if (empty_stacks <= 2) {\n                        bonus = -100;\n                    } else if (empty_stacks <= 4) {\n                        bonus = -80;\n                    } else {\n                        bonus = -60;\n                    }\n                } else if (cascade < 0.1) {\n                    // Safe placement (no cascading conflicts)\n                    bonus = -50;\n                }\n                \n                double total = immediate_cost + future_cost + cascade * 0.8 + bonus;\n                \n                if (total < best_total) {\n                    best_total = total;\n                    best_dest = dest;\n                }\n            }\n            \n            operations.push_back({stacks[stack_id][pos + 1], best_dest + 1});\n            stacks[stack_id].resize(pos + 1);\n            for (int x : moving) stacks[best_dest].push_back(x);\n        }\n        \n        operations.push_back({target, 0});\n        stacks[stack_id].pop_back();\n    }\n    \n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\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;\n\nconst int di[] = {0, 1, 0, -1};\nconst int dj[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir];\n    int nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    if (dir == 0) return v[i][j] == '0';\n    else if (dir == 1) return h[i][j] == '0';\n    else if (dir == 2) return v[i][j-1] == '0';\n    else return h[i-1][j] == '0';\n}\n\nvoid update_visits(const string& path, vector<vector<int>>& visits) {\n    int ci = 0, cj = 0;\n    visits[0][0]++;\n    \n    for (char c : path) {\n        int dir = (c == 'R' ? 0 : c == 'D' ? 1 : c == 'L' ? 2 : 3);\n        ci += di[dir];\n        cj += dj[dir];\n        visits[ci][cj]++;\n    }\n}\n\npair<vector<vector<int>>, vector<vector<int>>> bfs_from(int si, int sj) {\n    vector<vector<int>> dist(N, vector<int>(N, 1e9));\n    vector<vector<int>> parent_dir(N, vector<int>(N, -1));\n    queue<pair<int, int>> q;\n    \n    q.push({si, sj});\n    dist[si][sj] = 0;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            \n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            \n            if (dist[ni][nj] > dist[i][j] + 1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                parent_dir[ni][nj] = dir;\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    return {dist, parent_dir};\n}\n\npair<string, vector<pair<int,int>>> reconstruct_path_with_cells(int si, int sj, int ti, int tj, vector<vector<int>>& parent_dir) {\n    if (si == ti && sj == tj) return {\"\", {{si, sj}}};\n    \n    string path;\n    vector<pair<int,int>> cells;\n    \n    int ci = ti, cj = tj;\n    cells.push_back({ti, tj});\n    \n    while (ci != si || cj != sj) {\n        int dir = parent_dir[ci][cj];\n        path += dir_char[dir];\n        ci -= di[dir];\n        cj -= dj[dir];\n        cells.push_back({ci, cj});\n    }\n    \n    reverse(path.begin(), path.end());\n    reverse(cells.begin(), cells.end());\n    return {path, cells};\n}\n\ndouble compute_score(int L, const vector<vector<int>>& visits) {\n    double score = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (visits[i][j] > 0) {\n                score += (double)d[i][j] * L / (2.0 * visits[i][j]);\n            }\n        }\n    }\n    return score;\n}\n\nstring build_tour() {\n    const int MAX_LEN = 100000;\n    \n    // Build basic DFS tour\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    string route;\n    \n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        \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 + di[dir];\n            int nj = j + dj[dir];\n            if (!visited[ni][nj]) {\n                neighbors.push_back({-d[ni][nj], dir});\n            }\n        }\n        \n        sort(neighbors.begin(), neighbors.end());\n        \n        for (auto [_, dir] : neighbors) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            \n            if (!visited[ni][nj]) {\n                route += dir_char[dir];\n                dfs(ni, nj);\n                route += dir_char[(dir + 2) % 4];\n            }\n        }\n    };\n    \n    dfs(0, 0);\n    \n    // Track visit counts\n    vector<vector<int>> visit_counts(N, vector<int>(N, 0));\n    update_visits(route, visit_counts);\n    \n    // Precompute paths from origin\n    auto [dist_from_origin, parent_from_origin] = bfs_from(0, 0);\n    \n    map<pair<int,int>, pair<string, vector<pair<int,int>>>> path_data;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (dist_from_origin[i][j] < 1e9 && dist_from_origin[i][j] <= 250) {\n                path_data[{i, j}] = reconstruct_path_with_cells(0, 0, i, j, parent_from_origin);\n            }\n        }\n    }\n    \n    // Greedy optimization with score-based selection\n    while (route.length() < MAX_LEN - 50) {\n        double best_improvement = 0;\n        int best_i = -1, best_j = -1;\n        \n        int L_current = route.length();\n        double current_score = compute_score(L_current, visit_counts);\n        \n        for (auto& [dest, data] : path_data) {\n            auto [i, j] = dest;\n            auto& [path, cells] = data;\n            \n            int detour_len = 2 * path.length();\n            if (detour_len == 0 || route.length() + detour_len > MAX_LEN) continue;\n            \n            // Simulate adding this detour\n            int L_new = L_current + detour_len;\n            \n            auto temp_visits = visit_counts;\n            for (auto [pi, pj] : cells) {\n                temp_visits[pi][pj] += 2;\n            }\n            \n            double new_score = compute_score(L_new, temp_visits);\n            double improvement = current_score - new_score;\n            \n            if (improvement > best_improvement) {\n                best_improvement = improvement;\n                best_i = i;\n                best_j = j;\n            }\n        }\n        \n        if (best_i == -1 || best_improvement <= 0) break;\n        \n        // Add the best detour\n        auto& [path_to, cells] = path_data[{best_i, best_j}];\n        string path_back = path_to;\n        reverse(path_back.begin(), path_back.end());\n        for (char& c : path_back) {\n            if (c == 'U') c = 'D';\n            else if (c == 'D') c = 'U';\n            else if (c == 'L') c = 'R';\n            else if (c == 'R') c = 'L';\n        }\n        \n        route += path_to + path_back;\n        \n        // Update visit counts\n        for (auto [pi, pj] : cells) {\n            visit_counts[pi][pj] += 2;\n        }\n    }\n    \n    return route;\n}\n\nint main() {\n    cin >> N;\n    \n    h.resize(N-1);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    \n    v.resize(N);\n    for (int i = 0; i < N; i++) cin >> v[i];\n    \n    d.resize(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> d[i][j];\n        }\n    }\n    \n    cout << build_tour() << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint si, sj;\nvector<string> grid;\nvector<string> targets;\nmap<char, vector<pair<int,int>>> char_positions;\nvector<vector<int>> ovl;\n\nint overlap(const string& s1, const string& s2) {\n    int maxLen = min((int)s1.length(), (int)s2.length());\n    for (int len = maxLen; len >= 1; len--) {\n        if (s1.substr(s1.length() - len) == s2.substr(0, len)) {\n            return len;\n        }\n    }\n    return 0;\n}\n\nbool contains(const string& s, const string& target) {\n    return s.find(target) != string::npos;\n}\n\nbool checkComplete(const string& s) {\n    for (const auto& t : targets) {\n        if (!contains(s, t)) return false;\n    }\n    return true;\n}\n\npair<int,int> findClosest(char c, int curI, int curJ) {\n    auto& positions = char_positions[c];\n    int bestDist = INT_MAX;\n    pair<int,int> best = positions[0];\n    \n    for (auto& pos : positions) {\n        int dist = abs(pos.first - curI) + abs(pos.second - curJ);\n        if (dist < bestDist) {\n            bestDist = dist;\n            best = pos;\n        }\n    }\n    return best;\n}\n\npair<int,int> findBestPosition(char c, int curI, int curJ, const string& text, int pos) {\n    auto& positions = char_positions[c];\n    if (positions.size() == 1) return positions[0];\n    \n    int bestScore = INT_MAX;\n    pair<int,int> best = positions[0];\n    int lookAhead = min(9, (int)text.length() - pos - 1);\n    \n    for (auto& p : positions) {\n        int score = abs(p.first - curI) + abs(p.second - curJ);\n        \n        int tmpI = p.first, tmpJ = p.second;\n        for (int i = 1; i <= lookAhead; i++) {\n            auto nextPos = findClosest(text[pos + i], tmpI, tmpJ);\n            score += abs(nextPos.first - tmpI) + abs(nextPos.second - tmpJ);\n            tmpI = nextPos.first;\n            tmpJ = nextPos.second;\n        }\n        \n        if (score < bestScore) {\n            bestScore = score;\n            best = p;\n        }\n    }\n    return best;\n}\n\nint estimateCost(const string& text) {\n    int cost = 0;\n    int curI = si, curJ = sj;\n    \n    for (char c : text) {\n        auto pos = findClosest(c, curI, curJ);\n        cost += abs(pos.first - curI) + abs(pos.second - curJ) + 1;\n        curI = pos.first;\n        curJ = pos.second;\n    }\n    return cost;\n}\n\nint calculateCost(const string& text) {\n    int cost = 0;\n    int curI = si, curJ = sj;\n    \n    for (int i = 0; i < text.length(); i++) {\n        auto pos = findBestPosition(text[i], curI, curJ, text, i);\n        cost += abs(pos.first - curI) + abs(pos.second - curJ) + 1;\n        curI = pos.first;\n        curJ = pos.second;\n    }\n    return cost;\n}\n\nstring greedyBuild(int startIdx) {\n    vector<bool> contained(M, false);\n    string result = targets[startIdx];\n    contained[startIdx] = true;\n    \n    for (int i = 0; i < M; i++) {\n        if (!contained[i] && contains(result, targets[i])) {\n            contained[i] = true;\n        }\n    }\n    \n    int current = startIdx;\n    \n    while (true) {\n        int bestNext = -1;\n        int bestOverlap = -1;\n        int bestLength = INT_MAX;\n        \n        for (int i = 0; i < M; i++) {\n            if (contained[i]) continue;\n            \n            int o = ovl[current][i];\n            int len = targets[i].length();\n            \n            // Prioritize overlap, then shorter strings for tie-breaking\n            if (o > bestOverlap || (o == bestOverlap && len < bestLength)) {\n                bestOverlap = o;\n                bestLength = len;\n                bestNext = i;\n            }\n        }\n        \n        if (bestNext == -1) break;\n        \n        int o = ovl[current][bestNext];\n        result += (o > 0) ? targets[bestNext].substr(o) : targets[bestNext];\n        \n        contained[bestNext] = true;\n        current = bestNext;\n        \n        for (int i = 0; i < M; i++) {\n            if (!contained[i] && contains(result, targets[i])) {\n                contained[i] = true;\n            }\n        }\n    }\n    \n    return result;\n}\n\nstring reverseGreedyBuild(int startIdx) {\n    vector<bool> contained(M, false);\n    string result = targets[startIdx];\n    contained[startIdx] = true;\n    \n    for (int i = 0; i < M; i++) {\n        if (!contained[i] && contains(result, targets[i])) {\n            contained[i] = true;\n        }\n    }\n    \n    int current = startIdx;\n    \n    while (true) {\n        int bestPrev = -1;\n        int bestOverlap = -1;\n        \n        for (int i = 0; i < M; i++) {\n            if (contained[i]) continue;\n            \n            int o = ovl[i][current];\n            if (o > bestOverlap) {\n                bestOverlap = o;\n                bestPrev = i;\n            }\n        }\n        \n        if (bestPrev == -1) break;\n        \n        int o = ovl[bestPrev][current];\n        result = (o > 0) ? targets[bestPrev].substr(0, targets[bestPrev].length() - o) + result : targets[bestPrev] + result;\n        \n        contained[bestPrev] = true;\n        current = bestPrev;\n        \n        for (int i = 0; i < M; i++) {\n            if (!contained[i] && contains(result, targets[i])) {\n                contained[i] = true;\n            }\n        }\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> si >> sj;\n    \n    grid.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    targets.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i];\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            char_positions[grid[i][j]].push_back({i, j});\n        }\n    }\n    \n    ovl.assign(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) {\n                ovl[i][j] = overlap(targets[i], targets[j]);\n            }\n        }\n    }\n    \n    // Strategy 1: Bidirectional overlap\n    vector<pair<int,int>> candidates1;\n    for (int i = 0; i < M; i++) {\n        int total = 0;\n        for (int j = 0; j < M; j++) {\n            total += ovl[i][j] + ovl[j][i];\n        }\n        candidates1.push_back({total, i});\n    }\n    sort(candidates1.rbegin(), candidates1.rend());\n    \n    // Strategy 2: Outgoing overlap\n    vector<pair<int,int>> candidates2;\n    for (int i = 0; i < M; i++) {\n        int total = 0;\n        for (int j = 0; j < M; j++) {\n            total += ovl[i][j];\n        }\n        candidates2.push_back({total, i});\n    }\n    sort(candidates2.rbegin(), candidates2.rend());\n    \n    // Strategy 3: Incoming overlap (for reverse)\n    vector<pair<int,int>> candidates3;\n    for (int i = 0; i < M; i++) {\n        int total = 0;\n        for (int j = 0; j < M; j++) {\n            total += ovl[j][i];\n        }\n        candidates3.push_back({total, i});\n    }\n    sort(candidates3.rbegin(), candidates3.rend());\n    \n    // Strategy 4: Contains others\n    vector<pair<int,int>> candidates4;\n    for (int i = 0; i < M; i++) {\n        int count = 0;\n        for (int j = 0; j < M; j++) {\n            if (i != j && contains(targets[i], targets[j])) {\n                count++;\n            }\n        }\n        candidates4.push_back({count, i});\n    }\n    sort(candidates4.rbegin(), candidates4.rend());\n    \n    set<int> candidateSet;\n    for (int i = 0; i < min(12, M); i++) {\n        candidateSet.insert(candidates1[i].second);\n        candidateSet.insert(candidates2[i].second);\n        candidateSet.insert(candidates3[i].second);\n        candidateSet.insert(candidates4[i].second);\n    }\n    \n    vector<pair<string, int>> candidateResults;\n    \n    // Forward construction\n    for (int idx : candidateSet) {\n        string result = greedyBuild(idx);\n        if (checkComplete(result)) {\n            int cost = estimateCost(result);\n            candidateResults.push_back({result, cost});\n        }\n    }\n    \n    // Reverse construction for top candidates\n    for (int i = 0; i < min(8, (int)candidates3.size()); i++) {\n        string result = reverseGreedyBuild(candidates3[i].second);\n        if (checkComplete(result)) {\n            int cost = estimateCost(result);\n            candidateResults.push_back({result, cost});\n        }\n    }\n    \n    sort(candidateResults.begin(), candidateResults.end(), \n         [](const auto& a, const auto& b) { return a.second < b.second; });\n    \n    string bestResult;\n    int bestCost = INT_MAX;\n    \n    for (int i = 0; i < min(20, (int)candidateResults.size()); i++) {\n        int cost = calculateCost(candidateResults[i].first);\n        if (cost < bestCost) {\n            bestCost = cost;\n            bestResult = candidateResults[i].first;\n        }\n    }\n    \n    if (bestResult.empty()) {\n        bestResult = greedyBuild(0);\n    }\n    \n    int curI = si, curJ = sj;\n    for (int i = 0; i < bestResult.length(); i++) {\n        auto pos = findBestPosition(bestResult[i], curI, curJ, bestResult, i);\n        cout << pos.first << \" \" << pos.second << \"\\n\";\n        curI = pos.first;\n        curJ = pos.second;\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>>> fields;\nint query_count = 0;\n\nint query(const vector<pair<int,int>>& cells) {\n    cout << \"q \" << cells.size();\n    for (auto [i, j] : cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    query_count++;\n    \n    int result;\n    cin >> result;\n    return result;\n}\n\nint drill(int i, int j) {\n    return query({{i, j}});\n}\n\nbool answer(const set<pair<int,int>>& cells) {\n    cout << \"a \" << cells.size();\n    for (auto [i, j] : cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    int result;\n    cin >> result;\n    return result == 1;\n}\n\nint main() {\n    cin >> N >> M >> eps;\n    fields.resize(M);\n    \n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        fields[k].resize(d);\n        for (int i = 0; i < d; i++) {\n            cin >> fields[k][i].first >> fields[k][i].second;\n        }\n    }\n    \n    vector<vector<double>> estimate(N, vector<double>(N, 0.0));\n    vector<vector<int>> drilled(N, vector<int>(N, -1));\n    \n    // Phase 1: Query entire grid multiple times for baseline\n    double total = 0;\n    int num_full = 30;\n    for (int q = 0; q < num_full; q++) {\n        vector<pair<int,int>> all;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                all.push_back({i, j});\n            }\n        }\n        total += query(all);\n    }\n    double avg_per_cell = total / (num_full * N * N);\n    \n    // Phase 2: Query rows and columns\n    vector<double> row_est(N), col_est(N);\n    for (int i = 0; i < N; i++) {\n        vector<pair<int,int>> row;\n        for (int j = 0; j < N; j++) row.push_back({i, j});\n        row_est[i] = query(row) / (double)N;\n    }\n    \n    for (int j = 0; j < N; j++) {\n        vector<pair<int,int>> col;\n        for (int i = 0; i < N; i++) col.push_back({i, j});\n        col_est[j] = query(col) / (double)N;\n    }\n    \n    // Combine estimates\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            estimate[i][j] = (row_est[i] + col_est[j]) / 2.0;\n        }\n    }\n    \n    // Phase 3: Query smaller blocks for refinement\n    int block_size = max(2, N/3);\n    for (int bi = 0; bi < N; bi += block_size) {\n        for (int bj = 0; bj < N; bj += block_size) {\n            vector<pair<int,int>> block;\n            for (int i = bi; i < min(N, bi+block_size); i++) {\n                for (int j = bj; j < min(N, bj+block_size); j++) {\n                    block.push_back({i, j});\n                }\n            }\n            if (block.size() >= 2) {\n                double block_avg = query(block) / (double)block.size();\n                for (auto [i, j] : block) {\n                    estimate[i][j] = (estimate[i][j] + block_avg) / 2.0;\n                }\n            }\n        }\n    }\n    \n    // Phase 4: Drill uncertain squares\n    set<pair<int,int>> has_oil;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (estimate[i][j] > 0.4 || query_count >= 600) {\n                int v = drill(i, j);\n                drilled[i][j] = v;\n                if (v > 0) has_oil.insert({i, j});\n            }\n        }\n    }\n    \n    // Make answer\n    if (!answer(has_oil)) {\n        // If wrong, drill remaining squares\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (drilled[i][j] < 0) {\n                    int v = drill(i, j);\n                    if (v > 0) has_oil.insert({i, j});\n                }\n            }\n        }\n        answer(has_oil);\n    }\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\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    auto compute_layout = [&](const vector<int>& areas) {\n        vector<int> heights(N);\n        long long total_height = 0;\n        \n        for (int k = 0; k < N; k++) {\n            heights[k] = max(1, (areas[k] + W - 1) / W);\n            total_height += heights[k];\n        }\n        \n        vector<int> row_pos(N + 1);\n        row_pos[0] = 0;\n        \n        if (total_height <= W) {\n            // Can fit all strips exactly\n            for (int k = 0; k < N; k++) {\n                row_pos[k + 1] = row_pos[k] + heights[k];\n            }\n        } else {\n            // Need compression - allocate proportional to areas directly\n            long long total_area = 0;\n            for (int k = 0; k < N; k++) {\n                total_area += areas[k];\n            }\n            \n            long long cumsum = 0;\n            for (int k = 0; k < N; k++) {\n                cumsum += areas[k];\n                row_pos[k + 1] = (int)((cumsum * W) / total_area);\n            }\n        }\n        \n        row_pos[N] = W;\n        \n        // Ensure each strip has at least height 1\n        for (int k = 0; k < N; k++) {\n            if (row_pos[k + 1] <= row_pos[k]) {\n                row_pos[k + 1] = row_pos[k] + 1;\n            }\n        }\n        \n        return row_pos;\n    };\n    \n    auto calc_shortage = [&](const vector<int>& layout, const vector<int>& areas) {\n        long long shortage = 0;\n        for (int k = 0; k < N; k++) {\n            long long area = (long long)(layout[k + 1] - layout[k]) * W;\n            if (area < areas[k]) {\n                shortage += areas[k] - area;\n            }\n        }\n        return shortage;\n    };\n    \n    auto calc_partition_cost = [&](const vector<int>& layout1, const vector<int>& layout2) {\n        long long cost = 0;\n        for (int i = 1; i < N; i++) {\n            if (layout1[i] != layout2[i]) {\n                cost += W;\n            }\n        }\n        return cost;\n    };\n    \n    vector<vector<int>> layouts(D);\n    \n    // Day 0: compute optimal layout\n    layouts[0] = compute_layout(a[0]);\n    \n    // Days 1+: decide whether to reuse or change\n    for (int d = 1; d < D; d++) {\n        vector<int> new_layout = compute_layout(a[d]);\n        \n        long long reuse_shortage = calc_shortage(layouts[d - 1], a[d]);\n        long long new_shortage = calc_shortage(new_layout, a[d]);\n        long long partition_cost = calc_partition_cost(layouts[d - 1], new_layout);\n        \n        long long reuse_cost = 100 * reuse_shortage;\n        long long new_cost = 100 * new_shortage + partition_cost;\n        \n        // Add small bias to prefer stability (avoid changing for marginal gains)\n        if (reuse_cost <= new_cost + W) {  // Allow W units of margin\n            layouts[d] = layouts[d - 1];\n        } else {\n            layouts[d] = new_layout;\n        }\n    }\n    \n    // Output\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << layouts[d][k] << \" 0 \" << layouts[d][k + 1] << \" \" << W << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353LL;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nlong long board[N][N];\nlong long stamps[M][3][3];\n\ndouble evaluate_stamp_score(int m, int p, int q, int operation_num) {\n    double score = 0.0;\n    int wraparounds = 0;\n    long long raw_improvement = 0;\n    \n    double progress = (double)operation_num / K;\n    \n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            int row = p + i;\n            int col = q + j;\n            long long remainder = board[row][col] % MOD;\n            long long stamp_val = stamps[m][i][j];\n            long long new_remainder = (remainder + stamp_val) % MOD;\n            long long improvement = new_remainder - remainder;\n            \n            raw_improvement += improvement;\n            \n            double cell_score = (double)improvement;\n            \n            // Gap-based multiplier\n            long long gap = (MOD - 1) - remainder;\n            double gap_ratio = (double)gap / (double)MOD;\n            \n            if (remainder + stamp_val < MOD) {\n                // No wraparound - apply gap-based boost\n                if (gap_ratio > 0.65) {\n                    cell_score *= 1.9;\n                } else if (gap_ratio > 0.45) {\n                    cell_score *= 1.6;\n                } else if (gap_ratio > 0.3) {\n                    cell_score *= 1.4;\n                } else if (gap_ratio > 0.15) {\n                    cell_score *= 1.2;\n                }\n            } else {\n                // Wraparound - adaptive penalty based on progress\n                wraparounds++;\n                \n                if (progress < 0.3) {\n                    // Early: moderate penalty\n                    cell_score *= 0.4;\n                } else if (progress < 0.6) {\n                    // Middle: lighter penalty\n                    cell_score *= 0.6;\n                } else {\n                    // Late: very light penalty (we need to use operations)\n                    cell_score *= 0.8;\n                }\n            }\n            \n            score += cell_score;\n        }\n    }\n    \n    // Wraparound penalty - but not too harsh\n    if (wraparounds >= 6) {\n        score *= 0.7;\n    } else if (wraparounds >= 4) {\n        score *= 0.85;\n    }\n    \n    // In late game, if raw improvement is positive, boost score\n    if (progress > 0.7 && raw_improvement > 0) {\n        score *= 1.1;\n    }\n    \n    return score;\n}\n\nvoid apply_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            board[p + i][q + j] += stamps[m][i][j];\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 < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    for (int stamp = 0; stamp < M; stamp++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[stamp][i][j];\n            }\n        }\n    }\n    \n    vector<tuple<int, int, int>> operations;\n    \n    for (int op = 0; op < K; op++) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        double best_score = -1e18;\n        \n        for (int stamp = 0; stamp < M; stamp++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    double score = evaluate_stamp_score(stamp, p, q, op);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_m = stamp;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // More lenient stopping - only stop if very negative\n        // In late game, be even more lenient\n        double threshold = (op > K * 0.8) ? -MOD * 0.5 : -MOD * 1.5;\n        \n        if (best_score < threshold) {\n            break;\n        }\n        \n        apply_stamp(best_m, best_p, best_q);\n        operations.push_back({best_m, best_p, best_q});\n    }\n    \n    cout << operations.size() << endl;\n    for (auto [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << endl;\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N];\n\nint main() {\n    int n;\n    cin >> n;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    int grid[N][N];\n    memset(grid, -1, sizeof(grid));\n    \n    pair<int,int> crane_pos[N];\n    int crane_carry[N];\n    bool crane_active[N];\n    int next_container[N];\n    \n    for (int i = 0; i < N; i++) {\n        crane_pos[i] = {i, 0};\n        crane_carry[i] = -1;\n        crane_active[i] = true;\n        next_container[i] = 0;\n    }\n    \n    vector<string> commands(N);\n    \n    auto target_row = [](int container) { return container / N; };\n    \n    auto get_new_pos = [](pair<int,int> pos, char action) -> pair<int,int> {\n        if (action == 'U') pos.first--;\n        else if (action == 'D') pos.first++;\n        else if (action == 'L') pos.second--;\n        else if (action == 'R') pos.second++;\n        return pos;\n    };\n    \n    for (int turn = 0; turn < 5000; turn++) {\n        // Step 1: Place containers\n        for (int i = 0; i < N; i++) {\n            if (next_container[i] < N && grid[i][0] == -1) {\n                bool blocked = false;\n                for (int c = 0; c < N; c++) {\n                    if (crane_active[c] && crane_pos[c] == make_pair(i, 0) && crane_carry[c] != -1) {\n                        blocked = true;\n                    }\n                }\n                if (!blocked) {\n                    grid[i][0] = A[i][next_container[i]];\n                    next_container[i]++;\n                }\n            }\n        }\n        \n        // Step 2: Plan crane actions\n        vector<char> actions(N, '.');\n        \n        for (int i = 0; i < N; i++) {\n            if (!crane_active[i]) continue;\n            \n            auto [r, c] = crane_pos[i];\n            int home_r = i;\n            \n            if (crane_carry[i] == -1) {\n                // Not carrying - pick up or return to home\n                if (grid[r][c] != -1) {\n                    actions[i] = 'P';\n                } else {\n                    // Return to home row at column 0 to pick up containers\n                    if (r != home_r) {\n                        actions[i] = (r < home_r) ? 'D' : 'U';\n                    } else if (c > 1) {\n                        // Move back towards column 0, but leave some space\n                        actions[i] = 'L';\n                    } else if (c == 1) {\n                        // At column 1, decide whether to go to column 0\n                        if (next_container[home_r] < N) {\n                            // More containers coming, go to column 0\n                            actions[i] = 'L';\n                        }\n                    }\n                    // Otherwise stay at column 0 or 1 waiting\n                }\n            } else {\n                // Carrying - deliver to target\n                int container = crane_carry[i];\n                int target_r = target_row(container);\n                \n                // Move to target row first, then move right\n                if (r != target_r) {\n                    actions[i] = (r < target_r) ? 'D' : 'U';\n                } else if (c < N-1) {\n                    actions[i] = 'R';\n                } else {\n                    actions[i] = 'Q';\n                }\n            }\n        }\n        \n        // Step 3: Resolve conflicts\n        for (int iter = 0; iter < 50; iter++) {\n            bool changed = false;\n            \n            vector<pair<int,int>> new_pos(N);\n            for (int i = 0; i < N; i++) {\n                new_pos[i] = get_new_pos(crane_pos[i], actions[i]);\n            }\n            \n            // Check bounds\n            for (int i = 0; i < N; i++) {\n                if (!crane_active[i]) continue;\n                char act = actions[i];\n                if (act != 'U' && act != 'D' && act != 'L' && act != 'R') continue;\n                \n                auto [r, c] = new_pos[i];\n                if (r < 0 || r >= N || c < 0 || c >= N) {\n                    actions[i] = '.';\n                    changed = true;\n                }\n            }\n            if (changed) continue;\n            \n            // Small cranes with containers can't move to squares with containers\n            for (int i = 1; i < N; i++) {\n                if (!crane_active[i]) continue;\n                if (crane_carry[i] == -1) continue;\n                char act = actions[i];\n                if (act != 'U' && act != 'D' && act != 'L' && act != 'R') continue;\n                \n                auto [r, c] = new_pos[i];\n                if (grid[r][c] != -1) {\n                    actions[i] = '.';\n                    changed = true;\n                }\n            }\n            if (changed) continue;\n            \n            // Same destination collisions\n            map<pair<int,int>, vector<int>> dest_map;\n            for (int i = 0; i < N; i++) {\n                if (crane_active[i]) {\n                    dest_map[new_pos[i]].push_back(i);\n                }\n            }\n            \n            for (auto& [pos, cranes_list] : dest_map) {\n                if (cranes_list.size() > 1) {\n                    int stationary = -1;\n                    for (int c : cranes_list) {\n                        if (crane_pos[c] == pos) {\n                            stationary = c;\n                            break;\n                        }\n                    }\n                    \n                    if (stationary != -1) {\n                        for (int c : cranes_list) {\n                            if (c != stationary && actions[c] != '.') {\n                                actions[c] = '.';\n                                changed = true;\n                            }\n                        }\n                    } else {\n                        int keep = cranes_list[0];\n                        for (int c : cranes_list) {\n                            bool c_carry = (crane_carry[c] != -1);\n                            bool keep_carry = (crane_carry[keep] != -1);\n                            if (c_carry > keep_carry || (c_carry == keep_carry && c < keep)) {\n                                keep = c;\n                            }\n                        }\n                        for (int c : cranes_list) {\n                            if (c != keep && actions[c] != '.') {\n                                actions[c] = '.';\n                                changed = true;\n                            }\n                        }\n                    }\n                }\n            }\n            if (changed) continue;\n            \n            // Position swaps\n            for (int i = 0; i < N; i++) {\n                if (!crane_active[i]) continue;\n                for (int j = i+1; j < N; j++) {\n                    if (!crane_active[j]) continue;\n                    \n                    if (new_pos[i] == crane_pos[j] && new_pos[j] == crane_pos[i]) {\n                        actions[j] = '.';\n                        changed = true;\n                    }\n                }\n            }\n            if (changed) continue;\n            \n            break;\n        }\n        \n        // Step 4: Apply actions\n        for (int i = 0; i < N; i++) {\n            commands[i] += actions[i];\n            \n            if (!crane_active[i]) continue;\n            \n            if (actions[i] == 'P') {\n                crane_carry[i] = grid[crane_pos[i].first][crane_pos[i].second];\n                grid[crane_pos[i].first][crane_pos[i].second] = -1;\n            } else if (actions[i] == 'Q') {\n                grid[crane_pos[i].first][crane_pos[i].second] = crane_carry[i];\n                crane_carry[i] = -1;\n            } else if (actions[i] == 'B') {\n                crane_active[i] = false;\n            } else if (actions[i] != '.') {\n                crane_pos[i] = get_new_pos(crane_pos[i], actions[i]);\n            }\n        }\n        \n        // Step 5: Dispatch containers\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                grid[i][N-1] = -1;\n            }\n        }\n        \n        // Check if done\n        bool all_done = true;\n        for (int i = 0; i < N; i++) {\n            if (next_container[i] < N || crane_carry[i] != -1) {\n                all_done = false;\n            }\n        }\n        if (all_done) {\n            bool has_containers = false;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (grid[i][j] != -1) has_containers = true;\n                }\n            }\n            if (!has_containers) break;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << commands[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<vector<int>> h;\nvector<string> operations;\nint cur_r = 0, cur_c = 0;\nint load = 0;\n\nint manhattan(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\nvoid moveTo(int tr, int tc) {\n    while (cur_r < tr && operations.size() < 99000) {\n        operations.push_back(\"D\");\n        cur_r++;\n    }\n    while (cur_r > tr && operations.size() < 99000) {\n        operations.push_back(\"U\");\n        cur_r--;\n    }\n    while (cur_c < tc && operations.size() < 99000) {\n        operations.push_back(\"R\");\n        cur_c++;\n    }\n    while (cur_c > tc && operations.size() < 99000) {\n        operations.push_back(\"L\");\n        cur_c--;\n    }\n}\n\nint main() {\n    cin >> N;\n    h.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n        }\n    }\n    \n    // Greedy nearest-neighbor approach (version 2 with minor improvement)\n    while (operations.size() < 95000) {\n        // Find nearest positive cell from current position\n        int pos_r = -1, pos_c = -1;\n        int min_dist = INT_MAX;\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 = manhattan(cur_r, cur_c, i, j);\n                    if (dist < min_dist) {\n                        min_dist = dist;\n                        pos_r = i;\n                        pos_c = j;\n                    }\n                }\n            }\n        }\n        \n        if (pos_r == -1) break; // No more positive cells\n        \n        // Move to and load from positive cell\n        moveTo(pos_r, pos_c);\n        if (operations.size() >= 95000) break;\n        \n        int load_amt = h[pos_r][pos_c];\n        operations.push_back(\"+\" + to_string(load_amt));\n        load += load_amt;\n        h[pos_r][pos_c] = 0;\n        \n        // Distribute load to nearest negative cells\n        // Prefer cells that can take more load to reduce stops\n        while (load > 0 && operations.size() < 95000) {\n            int neg_r = -1, neg_c = -1;\n            int best_score = INT_MAX;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (h[i][j] < 0) {\n                        int dist = manhattan(cur_r, cur_c, i, j);\n                        int can_deliver = min(load, -h[i][j]);\n                        // Score: prefer closer cells, but also prefer cells that take more\n                        // Multiply distance by 100 to give priority to amount delivered\n                        int score = dist * 100 - can_deliver;\n                        \n                        if (score < best_score) {\n                            best_score = score;\n                            neg_r = i;\n                            neg_c = j;\n                        }\n                    }\n                }\n            }\n            \n            if (neg_r == -1) break; // No more negative cells\n            \n            // Move to and unload at negative cell\n            moveTo(neg_r, neg_c);\n            if (operations.size() >= 95000) break;\n            \n            int unload_amt = min(load, -h[neg_r][neg_c]);\n            operations.push_back(\"-\" + to_string(unload_amt));\n            load -= unload_amt;\n            h[neg_r][neg_c] += unload_amt;\n        }\n    }\n    \n    for (const auto& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <set>\n#include <queue>\n#include <map>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> X(seed_count, vector<int>(M));\n    \n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> X[i][j];\n        }\n    }\n    \n    for (int t = 0; t < T; t++) {\n        // Find max for each criterion\n        vector<int> max_val(M, 0);\n        for (int l = 0; l < M; l++) {\n            for (int i = 0; i < seed_count; i++) {\n                max_val[l] = max(max_val[l], X[i][l]);\n            }\n        }\n        \n        // Count near-champions for each criterion\n        vector<int> near_max_count(M, 0);\n        for (int l = 0; l < M; l++) {\n            int threshold = max_val[l] * 88 / 100;\n            for (int i = 0; i < seed_count; i++) {\n                if (X[i][l] >= threshold) {\n                    near_max_count[l]++;\n                }\n            }\n        }\n        \n        // Must-include: top 3 for each criterion\n        set<int> must_include;\n        for (int l = 0; l < M; l++) {\n            vector<pair<int, int>> vals;\n            for (int i = 0; i < seed_count; i++) {\n                vals.push_back({X[i][l], i});\n            }\n            sort(vals.rbegin(), vals.rend());\n            for (int i = 0; i < min(3, (int)vals.size()); i++) {\n                must_include.insert(vals[i].second);\n            }\n        }\n        \n        // Score remaining seeds\n        vector<pair<double, int>> seed_scores;\n        for (int i = 0; i < seed_count; i++) {\n            if (must_include.count(i)) continue;\n            \n            int total = accumulate(X[i].begin(), X[i].end(), 0);\n            double score = total;\n            \n            for (int l = 0; l < M; l++) {\n                if (max_val[l] > 0 && X[i][l] >= max_val[l] * 88 / 100) {\n                    if (near_max_count[l] <= 3) {\n                        score += 600.0 / (near_max_count[l] + 1);\n                    } else if (near_max_count[l] <= 6) {\n                        score += 200.0 / near_max_count[l];\n                    } else {\n                        score += 50.0;\n                    }\n                }\n            }\n            \n            seed_scores.push_back({score, i});\n        }\n        sort(seed_scores.rbegin(), seed_scores.rend());\n        \n        // Combine must-include and scored seeds\n        set<int> selected;\n        for (int s : must_include) {\n            selected.insert(s);\n        }\n        for (auto [score, s] : seed_scores) {\n            if (selected.size() >= N * N) break;\n            selected.insert(s);\n        }\n        \n        vector<int> selected_vec(selected.begin(), selected.end());\n        \n        // Sort by balanced rarity + value score\n        sort(selected_vec.begin(), selected_vec.end(), [&](int a, int b) {\n            double score_a = 0, score_b = 0;\n            for (int l = 0; l < M; l++) {\n                if (max_val[l] > 0 && X[a][l] >= max_val[l] * 88 / 100) {\n                    score_a += 900.0 / (near_max_count[l] + 1);\n                }\n                if (max_val[l] > 0 && X[b][l] >= max_val[l] * 88 / 100) {\n                    score_b += 900.0 / (near_max_count[l] + 1);\n                }\n            }\n            // Increased value weight from 0.1 to 0.4 for better balance\n            score_a += accumulate(X[a].begin(), X[a].end(), 0) * 0.4;\n            score_b += accumulate(X[b].begin(), X[b].end(), 0) * 0.4;\n            return score_a > score_b;\n        });\n        \n        // Identify seed specialties\n        vector<set<int>> specialties(seed_count);\n        for (int i : selected_vec) {\n            for (int l = 0; l < M; l++) {\n                if (max_val[l] > 0 && X[i][l] >= max_val[l] * 88 / 100) {\n                    specialties[i].insert(l);\n                }\n            }\n        }\n        \n        // Greedy placement with quality-weighted complementarity\n        vector<vector<int>> A(N, vector<int>(N, -1));\n        set<int> placed;\n        \n        A[N/2][N/2] = selected_vec[0];\n        placed.insert(selected_vec[0]);\n        \n        queue<pair<int,int>> q;\n        q.push({N/2, N/2});\n        vector<vector<bool>> visited(N, vector<bool>(N, false));\n        visited[N/2][N/2] = true;\n        \n        int dx[] = {-1, 1, 0, 0};\n        int dy[] = {0, 0, -1, 1};\n        \n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                \n                if (nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny]) {\n                    visited[nx][ny] = true;\n                    q.push({nx, ny});\n                    \n                    int best_seed = -1;\n                    double best_score = -1e9;\n                    \n                    for (int s : selected_vec) {\n                        if (placed.count(s)) continue;\n                        \n                        // Increased base value weight for more emphasis on quality\n                        double comp_score = accumulate(X[s].begin(), X[s].end(), 0) * 1.3;\n                        \n                        map<int, int> neighbor_max;\n                        int neighbor_count = 0;\n                        for (int dd = 0; dd < 4; dd++) {\n                            int nnx = nx + dx[dd];\n                            int nny = ny + dy[dd];\n                            if (nnx >= 0 && nnx < N && nny >= 0 && nny < N && A[nnx][nny] != -1) {\n                                neighbor_count++;\n                                int ns = A[nnx][nny];\n                                for (int l = 0; l < M; l++) {\n                                    if (X[ns][l] >= max_val[l] * 88 / 100) {\n                                        neighbor_max[l] = max(neighbor_max[l], X[ns][l]);\n                                    }\n                                }\n                            }\n                        }\n                        \n                        // Quality-weighted complementarity bonuses\n                        for (int l : specialties[s]) {\n                            // Quality factor: how close to maximum (0.88 to 1.0)\n                            double quality = max_val[l] > 0 ? (double)X[s][l] / max_val[l] : 0;\n                            \n                            if (neighbor_max.find(l) == neighbor_max.end()) {\n                                // Unique specialty - quality-weighted bonus\n                                comp_score += 150 * quality;\n                                // Rarity bonus also quality-weighted\n                                if (near_max_count[l] <= 3) {\n                                    comp_score += 120 * quality;\n                                } else if (near_max_count[l] <= 6) {\n                                    comp_score += 60 * quality;\n                                }\n                            } else if (X[s][l] > neighbor_max[l]) {\n                                // Better than neighbors\n                                comp_score += 50 * quality;\n                            }\n                        }\n                        \n                        comp_score += neighbor_count * 10;\n                        \n                        if (comp_score > best_score) {\n                            best_score = comp_score;\n                            best_seed = s;\n                        }\n                    }\n                    \n                    if (best_seed != -1) {\n                        A[nx][ny] = best_seed;\n                        placed.insert(best_seed);\n                    }\n                }\n            }\n        }\n        \n        // Fill remaining positions\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (A[i][j] == -1) {\n                    for (int s : selected_vec) {\n                        if (!placed.count(s)) {\n                            A[i][j] = s;\n                            placed.insert(s);\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Output\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << A[i][j];\n                if (j < N - 1) cout << \" \";\n                else cout << endl;\n            }\n        }\n        cout.flush();\n        \n        // Read new seeds\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    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<vector<int>> grid_current;\nvector<vector<int>> grid_target;\n\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\nchar dir_name[] = {'R', 'D', 'L', 'U'};\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nstruct State {\n    int root_x, root_y;\n    int edge_dir; // 0=R, 1=D, 2=L, 3=U\n    bool holding;\n    \n    pair<int,int> get_leaf() {\n        return {root_x + dx[edge_dir], root_y + dy[edge_dir]};\n    }\n    \n    string make_cmd(char move, char rot, char action) {\n        string s = \"....\";\n        s[0] = move;\n        s[1] = rot;\n        s[3] = action;\n        return s;\n    }\n};\n\nvoid move_root_to(State& state, int tx, int ty, vector<string>& cmds) {\n    while ((state.root_x != tx || state.root_y != ty) && cmds.size() < 95000) {\n        char move = '.';\n        \n        if (state.root_x < tx && state.root_x + 1 < N) {\n            move = 'D';\n            state.root_x++;\n        } else if (state.root_x > tx && state.root_x > 0) {\n            move = 'U';\n            state.root_x--;\n        } else if (state.root_y < ty && state.root_y + 1 < N) {\n            move = 'R';\n            state.root_y++;\n        } else if (state.root_y > ty && state.root_y > 0) {\n            move = 'L';\n            state.root_y--;\n        } else {\n            break; // Can't move\n        }\n        \n        cmds.push_back(state.make_cmd(move, '.', '.'));\n    }\n}\n\nvoid rotate_to_dir(State& state, int target_dir, vector<string>& cmds) {\n    while (state.edge_dir != target_dir && cmds.size() < 95000) {\n        int diff = (target_dir - state.edge_dir + 4) % 4;\n        \n        if (diff == 1 || diff == 3) {\n            // Decide which rotation is shorter\n            char rot = (diff == 1) ? 'R' : 'L';\n            state.edge_dir = (state.edge_dir + (diff == 1 ? 1 : 3)) % 4;\n            cmds.push_back(state.make_cmd('.', rot, '.'));\n        } else if (diff == 2) {\n            // Either way works, choose R\n            state.edge_dir = (state.edge_dir + 1) % 4;\n            cmds.push_back(state.make_cmd('.', 'R', '.'));\n        } else {\n            break;\n        }\n    }\n}\n\nbool reach_position(State& state, int tx, int ty, vector<string>& cmds) {\n    // Find which direction to approach from\n    vector<pair<int,int>> candidates;\n    for (int d = 0; d < 4; d++) {\n        int rx = tx - dx[d];\n        int ry = ty - dy[d];\n        if (in_bounds(rx, ry)) {\n            candidates.push_back({rx, ry});\n        }\n    }\n    \n    if (candidates.empty()) return false;\n    \n    // Choose closest candidate\n    int best_idx = 0;\n    int best_dist = abs(state.root_x - candidates[0].first) + abs(state.root_y - candidates[0].second);\n    for (int i = 1; i < candidates.size(); i++) {\n        int d = abs(state.root_x - candidates[i].first) + abs(state.root_y - candidates[i].second);\n        if (d < best_dist) {\n            best_dist = d;\n            best_idx = i;\n        }\n    }\n    \n    int rx = candidates[best_idx].first;\n    int ry = candidates[best_idx].second;\n    \n    // Move root to this position\n    move_root_to(state, rx, ry, cmds);\n    \n    // Rotate to point at target\n    int needed_dir = -1;\n    for (int d = 0; d < 4; d++) {\n        if (rx + dx[d] == tx && ry + dy[d] == ty) {\n            needed_dir = d;\n            break;\n        }\n    }\n    \n    if (needed_dir == -1) return false;\n    \n    rotate_to_dir(state, needed_dir, cmds);\n    \n    auto [lx, ly] = state.get_leaf();\n    return (lx == tx && ly == ty && in_bounds(lx, ly));\n}\n\nint main() {\n    cin >> N >> M >> V;\n    \n    grid_current.resize(N, vector<int>(N, 0));\n    grid_target.resize(N, vector<int>(N, 0));\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            grid_current[i][j] = (s[j] == '1');\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            grid_target[i][j] = (s[j] == '1');\n        }\n    }\n    \n    State state;\n    state.root_x = 0;\n    state.root_y = 0;\n    state.edge_dir = 0;\n    state.holding = false;\n    \n    cout << \"2\\n\";\n    cout << \"0 1\\n\";\n    cout << state.root_x << \" \" << state.root_y << \"\\n\";\n    \n    vector<string> cmds;\n    \n    // Collect all tasks\n    vector<pair<pair<int,int>, pair<int,int>>> tasks;\n    set<pair<int,int>> used_targets;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid_current[i][j] && !grid_target[i][j]) {\n                // Find best target\n                int best_dist = INT_MAX;\n                pair<int,int> best_tgt = {-1, -1};\n                \n                for (int ti = 0; ti < N; ti++) {\n                    for (int tj = 0; tj < N; tj++) {\n                        if (grid_target[ti][tj] && !grid_current[ti][tj] &&\n                            used_targets.find({ti, tj}) == used_targets.end()) {\n                            int d = abs(i - ti) + abs(j - tj);\n                            if (d < best_dist) {\n                                best_dist = d;\n                                best_tgt = {ti, tj};\n                            }\n                        }\n                    }\n                }\n                \n                if (best_tgt.first != -1) {\n                    tasks.push_back({{i, j}, best_tgt});\n                    used_targets.insert(best_tgt);\n                }\n            }\n        }\n    }\n    \n    // Execute tasks\n    for (auto [src, tgt] : tasks) {\n        if (cmds.size() >= 90000) break;\n        \n        // Go to source\n        if (reach_position(state, src.first, src.second, cmds)) {\n            auto [lx, ly] = state.get_leaf();\n            if (lx == src.first && ly == src.second && grid_current[lx][ly]) {\n                cmds.push_back(state.make_cmd('.', '.', 'P'));\n                state.holding = true;\n                grid_current[lx][ly] = 0;\n                \n                // Go to target\n                if (reach_position(state, tgt.first, tgt.second, cmds)) {\n                    auto [lx2, ly2] = state.get_leaf();\n                    if (lx2 == tgt.first && ly2 == tgt.second && !grid_current[lx2][ly2]) {\n                        cmds.push_back(state.make_cmd('.', '.', 'P'));\n                        state.holding = false;\n                        grid_current[lx2][ly2] = 1;\n                    }\n                }\n            }\n        }\n    }\n    \n    for (const auto& cmd : cmds) {\n        cout << cmd << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint N;\nvector<pair<int,int>> mackerels, sardines;\n\nint calcScore(int x1, int y1, int x2, int y2) {\n    if (x1 > x2) swap(x1, x2);\n    if (y1 > y2) swap(y1, y2);\n    \n    int mac = 0, sar = 0;\n    for (auto [x, y] : mackerels) {\n        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) mac++;\n    }\n    for (auto [x, y] : sardines) {\n        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) sar++;\n    }\n    return mac - sar;\n}\n\nvoid tryUpdate(int x1, int y1, int x2, int y2, int& bestScore, int& bx1, int& by1, int& bx2, int& by2) {\n    int score = calcScore(x1, y1, x2, y2);\n    if (score > bestScore) {\n        bestScore = score;\n        bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n    }\n}\n\n// Simulated annealing - critical for escaping local optima\nvoid simulatedAnnealingSearch(int& bx1, int& by1, int& bx2, int& by2, int& bestScore, mt19937& rng) {\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    uniform_int_distribution<int> delta_dist(-6000, 6000);\n    uniform_int_distribution<int> side_dist(0, 3);\n    \n    int x1 = bx1, x2 = bx2, y1 = by1, y2 = by2;\n    int currentScore = bestScore;\n    \n    double temperature = 1200.0;\n    const double cooling = 0.965;\n    \n    for (int iter = 0; iter < 600; iter++) {\n        int side = side_dist(rng);\n        int delta = delta_dist(rng);\n        \n        int nx1 = x1, nx2 = x2, ny1 = y1, ny2 = y2;\n        \n        if (side == 0) nx1 = max(0, min(100000, x1 + delta));\n        else if (side == 1) nx2 = max(0, min(100000, x2 + delta));\n        else if (side == 2) ny1 = max(0, min(100000, y1 + delta));\n        else ny2 = max(0, min(100000, y2 + delta));\n        \n        int newScore = calcScore(nx1, ny1, nx2, ny2);\n        \n        if (newScore > currentScore || prob_dist(rng) < exp((newScore - currentScore) / temperature)) {\n            x1 = nx1; x2 = nx2; y1 = ny1; y2 = ny2;\n            currentScore = newScore;\n            \n            if (currentScore > bestScore) {\n                bestScore = currentScore;\n                bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n            }\n        }\n        \n        temperature *= cooling;\n    }\n}\n\n// Fine-grained local search\nvoid fineLocalSearch(int& bx1, int& by1, int& bx2, int& by2, int& bestScore) {\n    for (int iterations = 0; iterations < 20; iterations++) {\n        bool improved = false;\n        \n        for (int delta : {-2000, -1000, -500, -200, -100, -50, -20, -10, -5, -2, -1, \n                          1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000}) {\n            int nx1 = max(0, min(100000, bx1 + delta));\n            if (nx1 != bx1) {\n                int score = calcScore(nx1, by1, bx2, by2);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bx1 = nx1;\n                    improved = true;\n                }\n            }\n            \n            int nx2 = max(0, min(100000, bx2 + delta));\n            if (nx2 != bx2) {\n                int score = calcScore(bx1, by1, nx2, by2);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bx2 = nx2;\n                    improved = true;\n                }\n            }\n            \n            int ny1 = max(0, min(100000, by1 + delta));\n            if (ny1 != by1) {\n                int score = calcScore(bx1, ny1, bx2, by2);\n                if (score > bestScore) {\n                    bestScore = score;\n                    by1 = ny1;\n                    improved = true;\n                }\n            }\n            \n            int ny2 = max(0, min(100000, by2 + delta));\n            if (ny2 != by2) {\n                int score = calcScore(bx1, by1, bx2, ny2);\n                if (score > bestScore) {\n                    bestScore = score;\n                    by2 = ny2;\n                    improved = true;\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n}\n\n// Density-based search\nvoid densitySearch(int& bestScore, int& bx1, int& by1, int& bx2, int& by2) {\n    const int GRID = 5000;\n    const int CELLS = 21;\n    \n    vector<vector<int>> density(CELLS, vector<int>(CELLS, 0));\n    \n    for (auto [x, y] : mackerels) {\n        density[x / GRID][y / GRID]++;\n    }\n    \n    vector<pair<int, pair<int,int>>> cells;\n    for (int i = 0; i < CELLS; i++) {\n        for (int j = 0; j < CELLS; j++) {\n            if (density[i][j] > 0) {\n                cells.push_back({density[i][j], {i, j}});\n            }\n        }\n    }\n    \n    sort(cells.rbegin(), cells.rend());\n    \n    for (int k = 0; k < min(50, (int)cells.size()); k++) {\n        int ci = cells[k].second.first;\n        int cj = cells[k].second.second;\n        \n        int cx = ci * GRID + GRID / 2;\n        int cy = cj * GRID + GRID / 2;\n        \n        for (int sz : {1000, 2000, 3500, 5000, 7000, 10000, 13000, 17000, 21000, 26000}) {\n            tryUpdate(max(0, cx - sz), max(0, cy - sz), \n                     min(100000, cx + sz), min(100000, cy + sz),\n                     bestScore, bx1, by1, bx2, by2);\n        }\n    }\n}\n\n// Greedy expansion\nvoid greedyExpand(int& bestScore, int& bx1, int& by1, int& bx2, int& by2, mt19937& rng) {\n    uniform_int_distribution<int> dist(0, N-1);\n    \n    for (int trial = 0; trial < 35; trial++) {\n        auto [sx, sy] = mackerels[dist(rng)];\n        \n        int x1 = sx, x2 = sx, y1 = sy, y2 = sy;\n        int current_score = 1;\n        \n        for (int step = 0; step < 55; step++) {\n            int best_score = current_score;\n            int best_dir = -1, best_amt = 0;\n            \n            for (int dir = 0; dir < 4; dir++) {\n                for (int amt : {200, 500, 1000, 2000, 3500, 5500, 8500, 12000, 17000}) {\n                    int nx1 = x1, nx2 = x2, ny1 = y1, ny2 = y2;\n                    \n                    if (dir == 0) nx1 = max(0, x1 - amt);\n                    else if (dir == 1) nx2 = min(100000, x2 + amt);\n                    else if (dir == 2) ny1 = max(0, y1 - amt);\n                    else ny2 = min(100000, y2 + amt);\n                    \n                    int score = calcScore(nx1, ny1, nx2, ny2);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = dir;\n                        best_amt = amt;\n                    }\n                }\n            }\n            \n            if (best_dir == -1) break;\n            \n            if (best_dir == 0) x1 = max(0, x1 - best_amt);\n            else if (best_dir == 1) x2 = min(100000, x2 + best_amt);\n            else if (best_dir == 2) y1 = max(0, y1 - best_amt);\n            else y2 = min(100000, y2 + best_amt);\n            \n            current_score = best_score;\n        }\n        \n        if (current_score > bestScore) {\n            bestScore = current_score;\n            bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n        }\n    }\n}\n\nint main() {\n    cin >> N;\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        mackerels.push_back({x, y});\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        sardines.push_back({x, y});\n    }\n    \n    int bestScore = 0;\n    int bx1 = 0, by1 = 0, bx2 = 100000, by2 = 100000;\n    \n    mt19937 rng(20240515);  // Back to Version 5's seed\n    uniform_int_distribution<int> dist(0, N-1);\n    \n    // Phase 1: Density-based search\n    densitySearch(bestScore, bx1, by1, bx2, by2);\n    \n    // Phase 2: Greedy expansion\n    greedyExpand(bestScore, bx1, by1, bx2, by2, rng);\n    \n    // Phase 3: Multi-scale centered rectangles\n    vector<int> scales = {700, 1400, 2400, 3500, 5000, 7000, 9500, 12500, 16000, 20000, 25000, 31000};\n    for (int iter = 0; iter < 350; iter++) {\n        auto [cx, cy] = mackerels[dist(rng)];\n        \n        for (int sz : scales) {\n            tryUpdate(max(0, cx - sz), max(0, cy - sz), \n                     min(100000, cx + sz), min(100000, cy + sz),\n                     bestScore, bx1, by1, bx2, by2);\n        }\n    }\n    \n    // Phase 4: Pair-based rectangles\n    for (int iter = 0; iter < 950; iter++) {\n        int i = dist(rng);\n        int j = dist(rng);\n        \n        tryUpdate(mackerels[i].first, mackerels[i].second, \n                 mackerels[j].first, mackerels[j].second,\n                 bestScore, bx1, by1, bx2, by2);\n    }\n    \n    // Phase 5: Bounding boxes of subsets\n    uniform_int_distribution<int> subset_size(5, 220);\n    for (int iter = 0; iter < 280; iter++) {\n        int k = subset_size(rng);\n        int minX = 100000, maxX = 0, minY = 100000, maxY = 0;\n        \n        for (int j = 0; j < k; j++) {\n            auto [x, y] = mackerels[dist(rng)];\n            minX = min(minX, x);\n            maxX = max(maxX, x);\n            minY = min(minY, y);\n            maxY = max(maxY, y);\n        }\n        \n        for (int margin : {-9000, -6000, -3500, -1500, -500, 0, 500, 1500, 3500, 6000, 9000}) {\n            tryUpdate(max(0, minX + margin), max(0, minY + margin),\n                     min(100000, maxX - margin), min(100000, maxY - margin),\n                     bestScore, bx1, by1, bx2, by2);\n        }\n    }\n    \n    // Phase 6: Asymmetric rectangles\n    uniform_int_distribution<int> size_dist(300, 32000);\n    for (int iter = 0; iter < 320; iter++) {\n        auto [cx, cy] = mackerels[dist(rng)];\n        \n        tryUpdate(max(0, cx - size_dist(rng)), max(0, cy - size_dist(rng)),\n                 min(100000, cx + size_dist(rng)), min(100000, cy + size_dist(rng)),\n                 bestScore, bx1, by1, bx2, by2);\n    }\n    \n    // Phase 7: Simulated annealing (CRITICAL - was missing in Version 6)\n    simulatedAnnealingSearch(bx1, by1, bx2, by2, bestScore, rng);\n    \n    // Phase 8: Final fine-grained local search\n    fineLocalSearch(bx1, by1, bx2, by2, bestScore);\n    \n    if (bx1 > bx2) swap(bx1, bx2);\n    if (by1 > by2) swap(by1, by2);\n    \n    cout << 4 << endl;\n    cout << bx1 << \" \" << by1 << endl;\n    cout << bx2 << \" \" << by1 << endl;\n    cout << bx2 << \" \" << by2 << endl;\n    cout << bx1 << \" \" << by2 << endl;\n    \n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, T;\n    long long sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<pair<long long, long long>> rects(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].first >> rects[i].second;\n    }\n    \n    mt19937 rng(42);\n    \n    for (int turn = 0; turn < T; turn++) {\n        cout << N << endl;\n        \n        // Estimate dimensions as we place rectangles\n        long long est_w = 0, est_h = 0;\n        \n        for (int i = 0; i < N; i++) {\n            long long w = rects[i].first;\n            long long h = rects[i].second;\n            \n            int r = 0;\n            char d;\n            int b;\n            \n            if (i == 0) {\n                // First rectangle at origin\n                r = (h > w) ? 1 : 0;\n                if (r) swap(w, h);\n                d = 'U';\n                b = -1;\n                est_w = w;\n                est_h = h;\n            } else {\n                // Choose strategy based on turn\n                int strategy = turn % 6;\n                \n                switch (strategy) {\n                    case 0: // Horizontal layout - minimize height\n                        r = (h > w) ? 1 : 0;\n                        if (r) swap(w, h);\n                        d = 'U';\n                        b = i - 1;\n                        est_w += w;\n                        est_h = max(est_h, h);\n                        break;\n                        \n                    case 1: // Vertical layout - minimize width\n                        r = (w > h) ? 1 : 0;\n                        if (r) swap(w, h);\n                        d = 'L';\n                        b = -1;\n                        est_h += h;\n                        est_w = max(est_w, w);\n                        break;\n                        \n                    case 2: // Balanced - keep W \u2248 H\n                        if (est_w < est_h) {\n                            // Box is taller, extend width\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            // Box is wider, extend height\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 3: // Grid pattern\n                        if (i % 3 == 1) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = (i >= 2) ? i - 2 : -1;\n                        }\n                        break;\n                        \n                    case 4: // Alternating\n                        if (i % 2 == 1) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                        }\n                        break;\n                        \n                    default: // Random\n                        r = uniform_int_distribution<>(0, 1)(rng);\n                        if (r) swap(w, h);\n                        d = (uniform_int_distribution<>(0, 1)(rng) ? 'U' : 'L');\n                        b = uniform_int_distribution<>(-1, i - 1)(rng);\n                        break;\n                }\n            }\n            \n            cout << i << \" \" << r << \" \" << d << \" \" << b << endl;\n        }\n        cout.flush();\n        \n        long long W, H;\n        cin >> W >> H;\n    }\n    \n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n\nusing namespace std;\n\nint N, M, H;\nvector<int> A;\nvector<vector<int>> adj;\nvector<int> parent;\nvector<bool> assigned;\n\n// Aggressive DFS that prioritizes depth\nvoid dfs(int u, int depth, vector<int>& path) {\n    path.push_back(u);\n    \n    if (depth >= H) {\n        path.pop_back();\n        return;\n    }\n    \n    // Collect unassigned neighbors\n    vector<int> neighbors;\n    for (int v : adj[u]) {\n        if (!assigned[v]) {\n            neighbors.push_back(v);\n        }\n    }\n    \n    // Sort by beauty descending\n    sort(neighbors.begin(), neighbors.end(), [](int a, int b) {\n        return A[a] > A[b];\n    });\n    \n    // Process highest beauty neighbor first with full depth\n    for (int v : neighbors) {\n        if (!assigned[v]) {\n            assigned[v] = true;\n            parent[v] = u;\n            dfs(v, depth + 1, path);\n        }\n    }\n    \n    path.pop_back();\n}\n\n// Evaluate how good a root candidate is\ndouble evaluate_root(int root) {\n    // BFS to find reachable high-beauty vertices\n    set<int> reachable;\n    vector<int> queue = {root};\n    reachable.insert(root);\n    \n    for (int dist = 0; dist < H && !queue.empty(); dist++) {\n        vector<int> next_queue;\n        for (int u : queue) {\n            for (int v : adj[u]) {\n                if (!assigned[v] && reachable.find(v) == reachable.end()) {\n                    reachable.insert(v);\n                    next_queue.push_back(v);\n                }\n            }\n        }\n        queue = next_queue;\n    }\n    \n    // Calculate potential\n    double potential = 0;\n    for (int v : reachable) {\n        if (v != root) {\n            potential += A[v];\n        }\n    }\n    \n    // Prefer low beauty roots with high potential\n    return A[root] * 150.0 - potential;\n}\n\nint main() {\n    cin >> N >> M >> H;\n    \n    A.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> A[i];\n    }\n    \n    adj.resize(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    parent.resize(N, -1);\n    assigned.resize(N, false);\n    \n    // Build trees greedily\n    while (true) {\n        int root = -1;\n        double best_score = 1e9;\n        \n        // Evaluate all unassigned vertices as potential roots\n        for (int i = 0; i < N; i++) {\n            if (!assigned[i]) {\n                double score = evaluate_root(i);\n                if (root == -1 || score < best_score) {\n                    root = i;\n                    best_score = score;\n                }\n            }\n        }\n        \n        if (root == -1) break;\n        \n        assigned[root] = true;\n        parent[root] = -1;\n        vector<int> path;\n        dfs(root, 0, path);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << parent[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <tuple>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    vector<pair<char, int>> moves;\n    vector<vector<bool>> removed(N, vector<bool>(N, false));\n    \n    vector<pair<int,int>> oni_positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 'x') {\n                oni_positions.push_back({i, j});\n            }\n        }\n    }\n    \n    auto can_remove_up = [&](int i, int j) {\n        for (int ii = 0; ii < i; ii++) {\n            if (board[ii][j] == 'o') return false;\n        }\n        return true;\n    };\n    \n    auto can_remove_down = [&](int i, int j) {\n        for (int ii = i + 1; ii < N; ii++) {\n            if (board[ii][j] == 'o') return false;\n        }\n        return true;\n    };\n    \n    auto can_remove_left = [&](int i, int j) {\n        for (int jj = 0; jj < j; jj++) {\n            if (board[i][jj] == 'o') return false;\n        }\n        return true;\n    };\n    \n    auto can_remove_right = [&](int i, int j) {\n        for (int jj = j + 1; jj < N; jj++) {\n            if (board[i][jj] == 'o') return false;\n        }\n        return true;\n    };\n    \n    auto count_safe_dirs = [&](int i, int j) {\n        int cnt = 0;\n        if (can_remove_up(i, j)) cnt++;\n        if (can_remove_down(i, j)) cnt++;\n        if (can_remove_left(i, j)) cnt++;\n        if (can_remove_right(i, j)) cnt++;\n        return cnt;\n    };\n    \n    auto get_min_cost = [&](int i, int j) {\n        int min_cost = 1e9;\n        if (can_remove_up(i, j)) min_cost = min(min_cost, i + 1);\n        if (can_remove_down(i, j)) min_cost = min(min_cost, N - i);\n        if (can_remove_left(i, j)) min_cost = min(min_cost, j + 1);\n        if (can_remove_right(i, j)) min_cost = min(min_cost, N - j);\n        return min_cost;\n    };\n    \n    // Score: (is_far_from_edge, min_constraint, -efficiency, cost)\n    using ScoreTuple = tuple<bool, int, double, int>;\n    \n    while (true) {\n        ScoreTuple best_score = {true, 5, -1e9, (int)1e9};\n        char best_dir = ' ';\n        int best_pos = -1;\n        vector<pair<int,int>> best_targets;\n        int best_cost = 0;\n        \n        // Try upward\n        for (int j = 0; j < N; j++) {\n            int max_dist = 0;\n            vector<pair<int,int>> targets;\n            int min_dirs = 5;\n            bool has_close = false;\n            \n            for (auto [i, jj] : oni_positions) {\n                if (jj == j && !removed[i][jj] && can_remove_up(i, jj)) {\n                    int dist_up = i + 1;\n                    int min_alt_cost = get_min_cost(i, jj);\n                    \n                    // Include in batch only if upward is reasonable compared to alternatives\n                    // or if this is the only safe direction\n                    if (dist_up <= min_alt_cost * 1.5 || count_safe_dirs(i, jj) == 1) {\n                        targets.push_back({i, jj});\n                        max_dist = max(max_dist, dist_up);\n                        min_dirs = min(min_dirs, count_safe_dirs(i, jj));\n                        if (dist_up <= 2) has_close = true;\n                    }\n                }\n            }\n            \n            if (!targets.empty()) {\n                int cost = 2 * max_dist;\n                double efficiency = (double)targets.size() / cost;\n                bool far = (max_dist > 2);\n                ScoreTuple score = {far, min_dirs, -efficiency, cost};\n                if (score < best_score) {\n                    best_score = score;\n                    best_dir = 'U';\n                    best_pos = j;\n                    best_targets = targets;\n                    best_cost = cost;\n                }\n            }\n        }\n        \n        // Try downward\n        for (int j = 0; j < N; j++) {\n            int max_dist = 0;\n            vector<pair<int,int>> targets;\n            int min_dirs = 5;\n            bool has_close = false;\n            \n            for (auto [i, jj] : oni_positions) {\n                if (jj == j && !removed[i][jj] && can_remove_down(i, jj)) {\n                    int dist_down = N - i;\n                    int min_alt_cost = get_min_cost(i, jj);\n                    \n                    if (dist_down <= min_alt_cost * 1.5 || count_safe_dirs(i, jj) == 1) {\n                        targets.push_back({i, jj});\n                        max_dist = max(max_dist, dist_down);\n                        min_dirs = min(min_dirs, count_safe_dirs(i, jj));\n                        if (dist_down <= 2) has_close = true;\n                    }\n                }\n            }\n            \n            if (!targets.empty()) {\n                int cost = 2 * max_dist;\n                double efficiency = (double)targets.size() / cost;\n                bool far = (max_dist > 2);\n                ScoreTuple score = {far, min_dirs, -efficiency, cost};\n                if (score < best_score) {\n                    best_score = score;\n                    best_dir = 'D';\n                    best_pos = j;\n                    best_targets = targets;\n                    best_cost = cost;\n                }\n            }\n        }\n        \n        // Try leftward\n        for (int i = 0; i < N; i++) {\n            int max_dist = 0;\n            vector<pair<int,int>> targets;\n            int min_dirs = 5;\n            bool has_close = false;\n            \n            for (auto [ii, j] : oni_positions) {\n                if (ii == i && !removed[ii][j] && can_remove_left(ii, j)) {\n                    int dist_left = j + 1;\n                    int min_alt_cost = get_min_cost(ii, j);\n                    \n                    if (dist_left <= min_alt_cost * 1.5 || count_safe_dirs(ii, j) == 1) {\n                        targets.push_back({ii, j});\n                        max_dist = max(max_dist, dist_left);\n                        min_dirs = min(min_dirs, count_safe_dirs(ii, j));\n                        if (dist_left <= 2) has_close = true;\n                    }\n                }\n            }\n            \n            if (!targets.empty()) {\n                int cost = 2 * max_dist;\n                double efficiency = (double)targets.size() / cost;\n                bool far = (max_dist > 2);\n                ScoreTuple score = {far, min_dirs, -efficiency, cost};\n                if (score < best_score) {\n                    best_score = score;\n                    best_dir = 'L';\n                    best_pos = i;\n                    best_targets = targets;\n                    best_cost = cost;\n                }\n            }\n        }\n        \n        // Try rightward\n        for (int i = 0; i < N; i++) {\n            int max_dist = 0;\n            vector<pair<int,int>> targets;\n            int min_dirs = 5;\n            bool has_close = false;\n            \n            for (auto [ii, j] : oni_positions) {\n                if (ii == i && !removed[ii][j] && can_remove_right(ii, j)) {\n                    int dist_right = N - j;\n                    int min_alt_cost = get_min_cost(ii, j);\n                    \n                    if (dist_right <= min_alt_cost * 1.5 || count_safe_dirs(ii, j) == 1) {\n                        targets.push_back({ii, j});\n                        max_dist = max(max_dist, dist_right);\n                        min_dirs = min(min_dirs, count_safe_dirs(ii, j));\n                        if (dist_right <= 2) has_close = true;\n                    }\n                }\n            }\n            \n            if (!targets.empty()) {\n                int cost = 2 * max_dist;\n                double efficiency = (double)targets.size() / cost;\n                bool far = (max_dist > 2);\n                ScoreTuple score = {far, min_dirs, -efficiency, cost};\n                if (score < best_score) {\n                    best_score = score;\n                    best_dir = 'R';\n                    best_pos = i;\n                    best_targets = targets;\n                    best_cost = cost;\n                }\n            }\n        }\n        \n        if (best_targets.empty()) break;\n        \n        int dist = best_cost / 2;\n        for (int t = 0; t < dist; t++) {\n            moves.push_back({best_dir, best_pos});\n        }\n        char reverse = (best_dir == 'U') ? 'D' : (best_dir == 'D') ? 'U' : (best_dir == 'L') ? 'R' : 'L';\n        for (int t = 0; t < dist; t++) {\n            moves.push_back({reverse, best_pos});\n        }\n        \n        for (auto [i, j] : best_targets) {\n            removed[i][j] = true;\n        }\n    }\n    \n    for (auto [dir, pos] : moves) {\n        cout << dir << \" \" << pos << endl;\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, L;\nvector<int> T;\n\nlong long simulate(const vector<int>& a, const vector<int>& b, vector<int>& count) {\n    count.assign(N, 0);\n    int current = 0;\n    count[0] = 1;\n    \n    for (int week = 1; week < L; week++) {\n        int t = count[current];\n        if (t & 1) {\n            current = a[current];\n        } else {\n            current = b[current];\n        }\n        count[current]++;\n    }\n    \n    long long error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(count[i] - T[i]);\n    }\n    return error;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> L;\n    T.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    mt19937 gen(12345);\n    uniform_int_distribution<> dist_n(0, N-1);\n    \n    vector<double> weights(N);\n    for (int i = 0; i < N; i++) {\n        weights[i] = T[i] + 1.0;\n    }\n    discrete_distribution<> weighted_dist(weights.begin(), weights.end());\n    \n    vector<int> best_a(N), best_b(N);\n    long long best_error = LLONG_MAX;\n    vector<int> count(N);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    double time_limit = 1.85;\n    \n    while (true) {\n        auto current_time = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed > time_limit) break;\n        \n        // Initialize with weighted distribution\n        vector<int> a(N), b(N);\n        for (int i = 0; i < N; i++) {\n            a[i] = weighted_dist(gen);\n            b[i] = weighted_dist(gen);\n        }\n        \n        long long error = simulate(a, b, count);\n        \n        if (error < best_error) {\n            best_error = error;\n            best_a = a;\n            best_b = b;\n        }\n        \n        // Hill climbing\n        int no_improve = 0;\n        int patience = 3500;  // Slightly increased\n        \n        while (no_improve < patience) {\n            current_time = chrono::high_resolution_clock::now();\n            elapsed = chrono::duration<double>(current_time - start_time).count();\n            if (elapsed > time_limit) break;\n            \n            int strategy = gen() % 4;\n            \n            int i, new_val;\n            bool modify_a = gen() % 2;\n            int old_val;\n            \n            if (strategy == 0) {\n                // Weighted random (25%)\n                i = dist_n(gen);\n                new_val = weighted_dist(gen);\n            } else if (strategy == 1) {\n                // Over to under (25%)\n                int max_over = -1, max_over_diff = 0;\n                int max_under = -1, max_under_diff = 0;\n                \n                for (int j = 0; j < N; j++) {\n                    if (count[j] > T[j] && count[j] - T[j] > max_over_diff) {\n                        max_over_diff = count[j] - T[j];\n                        max_over = j;\n                    }\n                    if (T[j] > count[j] && T[j] - count[j] > max_under_diff) {\n                        max_under_diff = T[j] - count[j];\n                        max_under = j;\n                    }\n                }\n                \n                if (max_over >= 0 && max_under >= 0) {\n                    i = max_over;\n                    new_val = max_under;\n                } else {\n                    i = dist_n(gen);\n                    new_val = weighted_dist(gen);\n                }\n            } else if (strategy == 2) {\n                // Random to under (25%)\n                i = dist_n(gen);\n                int max_under = -1, max_under_diff = 0;\n                for (int j = 0; j < N; j++) {\n                    if (T[j] > count[j] && T[j] - count[j] > max_under_diff) {\n                        max_under_diff = T[j] - count[j];\n                        max_under = j;\n                    }\n                }\n                new_val = (max_under >= 0) ? max_under : weighted_dist(gen);\n            } else {\n                // Uniform random (25%)\n                i = dist_n(gen);\n                new_val = dist_n(gen);\n            }\n            \n            old_val = modify_a ? a[i] : b[i];\n            \n            if (modify_a) {\n                a[i] = new_val;\n            } else {\n                b[i] = new_val;\n            }\n            \n            long long new_error = simulate(a, b, count);\n            \n            if (new_error < error) {\n                error = new_error;\n                no_improve = 0;\n                \n                if (error < best_error) {\n                    best_error = error;\n                    best_a = a;\n                    best_b = b;\n                }\n            } else {\n                if (modify_a) {\n                    a[i] = old_val;\n                } else {\n                    b[i] = old_val;\n                }\n                no_improve++;\n            }\n        }\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 <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <queue>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent, rank_;\npublic:\n    UnionFind(int n) : parent(n), rank_(n, 0) {\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        if (rank_[px] < rank_[py]) swap(px, py);\n        parent[py] = px;\n        if (rank_[px] == rank_[py]) rank_[px]++;\n        return true;\n    }\n    \n    bool connected(int x, int y) {\n        return find(x) == find(y);\n    }\n};\n\nstruct Rect {\n    int lx, rx, ly, ry;\n    double cx, cy;\n};\n\nlong long morton_code(int x, int y) {\n    long long z = 0;\n    for (int i = 0; i < 20; i++) {\n        z |= ((long long)((x >> i) & 1) << (2 * i + 1));\n        z |= ((long long)((y >> i) & 1) << (2 * i));\n    }\n    return z;\n}\n\ndouble dist_sq(double x1, double y1, double x2, double y2) {\n    double dx = x1 - x2, dy = y1 - y2;\n    return dx * dx + dy * dy;\n}\n\ndouble min_dist_sq(const Rect& a, const Rect& b) {\n    double dx = max(0, max(a.lx - b.rx, b.lx - a.rx));\n    double dy = max(0, max(a.ly - b.ry, b.ly - a.ry));\n    return dx * dx + dy * dy;\n}\n\nvector<vector<int>> cluster_cities(int N, int M, vector<int>& G, vector<Rect>& rects) {\n    // Start with Z-order curve sorting (deterministic)\n    vector<int> order(N);\n    for (int i = 0; i < N; i++) order[i] = i;\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        int xa = (int)rects[a].cx, ya = (int)rects[a].cy;\n        int xb = (int)rects[b].cx, yb = (int)rects[b].cy;\n        return morton_code(xa, ya) < morton_code(xb, yb);\n    });\n    \n    // Initial grouping\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < G[i]; j++) {\n            groups[i].push_back(order[idx++]);\n        }\n    }\n    \n    // K-means refinement (deterministic initialization from above)\n    vector<pair<double, double>> centroids(M);\n    for (int i = 0; i < M; i++) {\n        double cx = 0, cy = 0;\n        for (int city : groups[i]) {\n            cx += rects[city].cx;\n            cy += rects[city].cy;\n        }\n        centroids[i] = {cx / groups[i].size(), cy / groups[i].size()};\n    }\n    \n    // K-means iterations\n    for (int iter = 0; iter < 10; iter++) {\n        vector<priority_queue<pair<double, int>>> candidates(M);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < M; j++) {\n                double d = dist_sq(rects[i].cx, rects[i].cy, centroids[j].first, centroids[j].second);\n                candidates[j].push({-d, i});\n            }\n        }\n        \n        for (int i = 0; i < M; i++) groups[i].clear();\n        vector<bool> assigned(N, false);\n        \n        for (int i = 0; i < M; i++) {\n            while ((int)groups[i].size() < G[i] && !candidates[i].empty()) {\n                int city = candidates[i].top().second;\n                candidates[i].pop();\n                if (!assigned[city]) {\n                    groups[i].push_back(city);\n                    assigned[city] = true;\n                }\n            }\n        }\n        \n        // Update centroids\n        for (int i = 0; i < M; i++) {\n            if (groups[i].empty()) continue;\n            double cx = 0, cy = 0;\n            for (int city : groups[i]) {\n                cx += rects[city].cx;\n                cy += rects[city].cy;\n            }\n            centroids[i] = {cx / groups[i].size(), cy / groups[i].size()};\n        }\n    }\n    \n    // Reorder within groups using nearest neighbor\n    for (int i = 0; i < M; i++) {\n        if (groups[i].size() <= 2) continue;\n        \n        vector<bool> used(groups[i].size(), false);\n        vector<int> ordered;\n        ordered.push_back(groups[i][0]);\n        used[0] = true;\n        \n        while ((int)ordered.size() < (int)groups[i].size()) {\n            int last = ordered.back();\n            int best_idx = -1;\n            double best_dist = 1e18;\n            \n            for (int j = 0; j < (int)groups[i].size(); j++) {\n                if (!used[j]) {\n                    double d = dist_sq(rects[last].cx, rects[last].cy, \n                                     rects[groups[i][j]].cx, rects[groups[i][j]].cy);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best_idx = j;\n                    }\n                }\n            }\n            \n            ordered.push_back(groups[i][best_idx]);\n            used[best_idx] = true;\n        }\n        \n        groups[i] = ordered;\n    }\n    \n    return groups;\n}\n\nint main() {\n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<Rect> rects(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].lx >> rects[i].rx >> rects[i].ly >> rects[i].ry;\n        rects[i].cx = (rects[i].lx + rects[i].rx) / 2.0;\n        rects[i].cy = (rects[i].ly + rects[i].ry) / 2.0;\n    }\n    \n    auto groups = cluster_cities(N, M, G, rects);\n    \n    // Smart query allocation\n    vector<int> queries_per_group(M, 0);\n    int budget = Q;\n    \n    // Allocate to groups <= L\n    for (int i = 0; i < M; i++) {\n        if (G[i] >= 2 && G[i] <= L && budget > 0) {\n            queries_per_group[i] = 1;\n            budget--;\n        }\n    }\n    \n    // Allocate to large groups proportionally\n    int total_large = 0;\n    for (int i = 0; i < M; i++) {\n        if (G[i] > L) total_large += G[i];\n    }\n    \n    for (int i = 0; i < M && budget > 0; i++) {\n        if (G[i] > L) {\n            int base_queries = (G[i] + L - 2) / (L - 1);\n            int allocated = min(base_queries, budget);\n            queries_per_group[i] = allocated;\n            budget -= allocated;\n        }\n    }\n    \n    vector<vector<pair<int, int>>> edges(M);\n    \n    for (int k = 0; k < M; k++) {\n        if (G[k] == 1) continue;\n        \n        set<pair<int, int>> candidate_edges;\n        \n        if (G[k] <= L && queries_per_group[k] > 0) {\n            cout << \"? \" << G[k];\n            for (int c : groups[k]) cout << \" \" << c;\n            cout << endl;\n            cout.flush();\n            \n            for (int i = 0; i < G[k] - 1; i++) {\n                int u, v;\n                cin >> u >> v;\n                if (u > v) swap(u, v);\n                candidate_edges.insert({u, v});\n            }\n        } else if (queries_per_group[k] > 0) {\n            // Sliding window with overlap\n            int num_queries = queries_per_group[k];\n            int step = max(1, (G[k] - L + num_queries) / num_queries);\n            \n            for (int q = 0; q < num_queries; q++) {\n                int start = q * step;\n                if (start >= G[k]) break;\n                int end = min(start + L, G[k]);\n                start = max(0, end - L);\n                int sz = end - start;\n                \n                if (sz < 2) continue;\n                \n                cout << \"? \" << sz;\n                for (int j = start; j < end; j++) {\n                    cout << \" \" << groups[k][j];\n                }\n                cout << endl;\n                cout.flush();\n                \n                for (int j = 0; j < sz - 1; j++) {\n                    int u, v;\n                    cin >> u >> v;\n                    if (u > v) swap(u, v);\n                    candidate_edges.insert({u, v});\n                }\n            }\n        }\n        \n        // Build MST from candidates\n        UnionFind uf(N);\n        for (auto [u, v] : candidate_edges) {\n            if (uf.unite(u, v)) {\n                edges[k].push_back({u, v});\n            }\n        }\n        \n        // Smart fallback with minimum distance estimation\n        if ((int)edges[k].size() < G[k] - 1) {\n            vector<pair<double, pair<int, int>>> fallback;\n            \n            for (int i = 0; i < G[k]; i++) {\n                for (int j = i + 1; j < G[k]; j++) {\n                    int u = groups[k][i], v = groups[k][j];\n                    if (!uf.connected(u, v)) {\n                        double d = min_dist_sq(rects[u], rects[v]);\n                        fallback.push_back({d, {u, v}});\n                    }\n                }\n            }\n            \n            sort(fallback.begin(), fallback.end());\n            \n            for (auto [d, edge] : fallback) {\n                if ((int)edges[k].size() >= G[k] - 1) break;\n                auto [u, v] = edge;\n                if (uf.unite(u, v)) {\n                    edges[k].push_back({u, v});\n                }\n            }\n        }\n    }\n    \n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int c : groups[k]) cout << c << \" \";\n        cout << endl;\n        for (auto [u, v] : edges[k]) {\n            cout << u << \" \" << v << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\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    int cur_r = targets[0].first;\n    int cur_c = targets[0].second;\n    \n    vector<pair<string, string>> actions;\n    \n    auto add = [&](string act, string dir) {\n        actions.push_back({act, dir});\n    };\n    \n    // Visit each target in order\n    for (int i = 1; i < M; i++) {\n        int target_r = targets[i].first;\n        int target_c = targets[i].second;\n        \n        // Move vertically with edge slide optimization\n        if (cur_r != target_r) {\n            int move_cost = abs(target_r - cur_r);\n            int slide_cost = INT_MAX;\n            \n            if (target_r > cur_r) {\n                // Moving down: try sliding to bottom edge\n                int edge = N - 1;\n                slide_cost = 1 + (edge - target_r);\n            } else {\n                // Moving up: try sliding to top edge\n                int edge = 0;\n                slide_cost = 1 + (target_r - edge);\n            }\n            \n            if (slide_cost < move_cost) {\n                // Use slide to edge\n                if (target_r > cur_r) {\n                    add(\"S\", \"D\");\n                    cur_r = N - 1;\n                } else {\n                    add(\"S\", \"U\");\n                    cur_r = 0;\n                }\n            }\n            \n            // Move remaining distance\n            while (cur_r != target_r) {\n                if (cur_r < target_r) {\n                    add(\"M\", \"D\");\n                    cur_r++;\n                } else {\n                    add(\"M\", \"U\");\n                    cur_r--;\n                }\n            }\n        }\n        \n        // Move horizontally with edge slide optimization\n        if (cur_c != target_c) {\n            int move_cost = abs(target_c - cur_c);\n            int slide_cost = INT_MAX;\n            \n            if (target_c > cur_c) {\n                // Moving right: try sliding to right edge\n                int edge = N - 1;\n                slide_cost = 1 + (edge - target_c);\n            } else {\n                // Moving left: try sliding to left edge\n                int edge = 0;\n                slide_cost = 1 + (target_c - edge);\n            }\n            \n            if (slide_cost < move_cost) {\n                // Use slide to edge\n                if (target_c > cur_c) {\n                    add(\"S\", \"R\");\n                    cur_c = N - 1;\n                } else {\n                    add(\"S\", \"L\");\n                    cur_c = 0;\n                }\n            }\n            \n            // Move remaining distance\n            while (cur_c != target_c) {\n                if (cur_c < target_c) {\n                    add(\"M\", \"R\");\n                    cur_c++;\n                } else {\n                    add(\"M\", \"L\");\n                    cur_c--;\n                }\n            }\n        }\n    }\n    \n    for (auto& [act, dir] : actions) {\n        cout << act << \" \" << dir << \"\\n\";\n    }\n    \n    return 0;\n}"},"16":{"ahc001":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n;\nvector<int> x, y;\nvector<long long> r;\nvector<array<int, 4>> result;\n\ndouble calc_satisfaction_for_area(long long area, long long desired) {\n    double ratio = (double)min(area, desired) / max(area, desired);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\nstruct SplitResult {\n    int mid;\n    int split_pos;\n    double score;\n};\n\nSplitResult find_best_vertical_split(const vector<int>& ids, int x1, int y1, int x2, int y2) {\n    long long total_r = 0;\n    for (int id : ids) total_r += r[id];\n    \n    vector<int> sorted_ids = ids;\n    sort(sorted_ids.begin(), sorted_ids.end(), [](int i, int j) {\n        return x[i] < x[j];\n    });\n    \n    int best_mid = 1;\n    int best_split_x = x1 + 1;\n    double best_score = -1e18;\n    \n    for (int mid = 1; mid < (int)sorted_ids.size(); mid++) {\n        long long left_r = 0;\n        for (int i = 0; i < mid; i++) left_r += r[sorted_ids[i]];\n        long long right_r = total_r - left_r;\n        \n        int min_split = max(x1 + 1, x[sorted_ids[mid-1]] + 1);\n        int max_split = min(x2 - 1, x[sorted_ids[mid]] + 1);\n        if (min_split > max_split) continue;\n        \n        int ideal = x1 + (long long)(x2 - x1) * left_r / total_r;\n        ideal = max(min_split, min(max_split, ideal));\n        \n        set<int> candidates;\n        \n        // Exhaustive search for ranges up to 60\n        if (max_split - min_split <= 60) {\n            for (int pos = min_split; pos <= max_split; pos++) {\n                candidates.insert(pos);\n            }\n        } else {\n            candidates = {min_split, max_split, ideal};\n            \n            // Very wide sampling around ideal\n            for (int delta = 1; delta <= 40; delta++) {\n                int pos1 = ideal + delta;\n                int pos2 = ideal - delta;\n                if (pos1 >= min_split && pos1 <= max_split) candidates.insert(pos1);\n                if (pos2 >= min_split && pos2 <= max_split) candidates.insert(pos2);\n            }\n            \n            // Aggressive boundary sampling\n            for (int offset = 1; offset <= 10; offset++) {\n                if (min_split + offset <= max_split) candidates.insert(min_split + offset);\n                if (max_split - offset >= min_split) candidates.insert(max_split - offset);\n            }\n            \n            // Sample at 10%, 20%, 30%, ..., 90% positions\n            for (int pct = 10; pct <= 90; pct += 10) {\n                int pos = min_split + (long long)(max_split - min_split) * pct / 100;\n                candidates.insert(pos);\n            }\n        }\n        \n        for (int split_x : candidates) {\n            long long left_area = (long long)(split_x - x1) * (y2 - y1);\n            long long right_area = (long long)(x2 - split_x) * (y2 - y1);\n            \n            double sat_left = calc_satisfaction_for_area(left_area, left_r);\n            double sat_right = calc_satisfaction_for_area(right_area, right_r);\n            \n            double score = sat_left * mid + sat_right * (sorted_ids.size() - mid);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_mid = mid;\n                best_split_x = split_x;\n            }\n        }\n    }\n    \n    return {best_mid, best_split_x, best_score};\n}\n\nSplitResult find_best_horizontal_split(const vector<int>& ids, int x1, int y1, int x2, int y2) {\n    long long total_r = 0;\n    for (int id : ids) total_r += r[id];\n    \n    vector<int> sorted_ids = ids;\n    sort(sorted_ids.begin(), sorted_ids.end(), [](int i, int j) {\n        return y[i] < y[j];\n    });\n    \n    int best_mid = 1;\n    int best_split_y = y1 + 1;\n    double best_score = -1e18;\n    \n    for (int mid = 1; mid < (int)sorted_ids.size(); mid++) {\n        long long top_r = 0;\n        for (int i = 0; i < mid; i++) top_r += r[sorted_ids[i]];\n        long long bottom_r = total_r - top_r;\n        \n        int min_split = max(y1 + 1, y[sorted_ids[mid-1]] + 1);\n        int max_split = min(y2 - 1, y[sorted_ids[mid]] + 1);\n        if (min_split > max_split) continue;\n        \n        int ideal = y1 + (long long)(y2 - y1) * top_r / total_r;\n        ideal = max(min_split, min(max_split, ideal));\n        \n        set<int> candidates;\n        \n        if (max_split - min_split <= 60) {\n            for (int pos = min_split; pos <= max_split; pos++) {\n                candidates.insert(pos);\n            }\n        } else {\n            candidates = {min_split, max_split, ideal};\n            \n            for (int delta = 1; delta <= 40; delta++) {\n                int pos1 = ideal + delta;\n                int pos2 = ideal - delta;\n                if (pos1 >= min_split && pos1 <= max_split) candidates.insert(pos1);\n                if (pos2 >= min_split && pos2 <= max_split) candidates.insert(pos2);\n            }\n            \n            for (int offset = 1; offset <= 10; offset++) {\n                if (min_split + offset <= max_split) candidates.insert(min_split + offset);\n                if (max_split - offset >= min_split) candidates.insert(max_split - offset);\n            }\n            \n            for (int pct = 10; pct <= 90; pct += 10) {\n                int pos = min_split + (long long)(max_split - min_split) * pct / 100;\n                candidates.insert(pos);\n            }\n        }\n        \n        for (int split_y : candidates) {\n            long long top_area = (long long)(x2 - x1) * (split_y - y1);\n            long long bottom_area = (long long)(x2 - x1) * (y2 - split_y);\n            \n            double sat_top = calc_satisfaction_for_area(top_area, top_r);\n            double sat_bottom = calc_satisfaction_for_area(bottom_area, bottom_r);\n            \n            double score = sat_top * mid + sat_bottom * (sorted_ids.size() - mid);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_mid = mid;\n                best_split_y = split_y;\n            }\n        }\n    }\n    \n    return {best_mid, best_split_y, best_score};\n}\n\nvoid solve(vector<int> ids, int x1, int y1, int x2, int y2) {\n    if (ids.empty()) return;\n    \n    if (ids.size() == 1) {\n        result[ids[0]] = {x1, y1, x2, y2};\n        return;\n    }\n    \n    auto v_result = find_best_vertical_split(ids, x1, y1, x2, y2);\n    auto h_result = find_best_horizontal_split(ids, x1, y1, x2, y2);\n    \n    if (v_result.score >= h_result.score) {\n        vector<int> sorted_ids = ids;\n        sort(sorted_ids.begin(), sorted_ids.end(), [](int i, int j) {\n            return x[i] < x[j];\n        });\n        \n        vector<int> left(sorted_ids.begin(), sorted_ids.begin() + v_result.mid);\n        vector<int> right(sorted_ids.begin() + v_result.mid, sorted_ids.end());\n        \n        solve(left, x1, y1, v_result.split_pos, y2);\n        solve(right, v_result.split_pos, y1, x2, y2);\n    } else {\n        vector<int> sorted_ids = ids;\n        sort(sorted_ids.begin(), sorted_ids.end(), [](int i, int j) {\n            return y[i] < y[j];\n        });\n        \n        vector<int> top(sorted_ids.begin(), sorted_ids.begin() + h_result.mid);\n        vector<int> bottom(sorted_ids.begin() + h_result.mid, sorted_ids.end());\n        \n        solve(top, x1, y1, x2, h_result.split_pos);\n        solve(bottom, x1, h_result.split_pos, x2, y2);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> n;\n    x.resize(n);\n    y.resize(n);\n    r.resize(n);\n    result.resize(n);\n    \n    for (int i = 0; i < n; i++) {\n        cin >> x[i] >> y[i] >> r[i];\n    }\n    \n    vector<int> all_ids(n);\n    iota(all_ids.begin(), all_ids.end(), 0);\n    \n    solve(all_ids, 0, 0, 10000, 10000);\n    \n    for (int i = 0; i < n; i++) {\n        cout << result[i][0] << \" \" << result[i][1] << \" \" \n             << result[i][2] << \" \" << result[i][3] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nint si, sj;\nint t[50][50];\nint p[50][50];\nmap<int, vector<pair<int,int>>> tile_squares;\nmap<int, int> tile_value;\n\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < 50 && y >= 0 && y < 50;\n}\n\nint main() {\n    cin >> si >> sj;\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> t[i][j];\n            tile_squares[t[i][j]].push_back({i, j});\n        }\n    }\n    \n    for (int i = 0; i < 50; i++) {\n        for (int j = 0; j < 50; j++) {\n            cin >> p[i][j];\n            tile_value[t[i][j]] += p[i][j];\n        }\n    }\n    \n    bool visited_tile[2500] = {};\n    bool visited_square[50][50] = {};\n    string path = \"\";\n    int x = si, y = sj;\n    visited_tile[t[x][y]] = true;\n    visited_square[x][y] = true;\n    \n    while (true) {\n        int current_tile = t[x][y];\n        \n        // First priority: visit other squares of current tile\n        int best_dir = -1;\n        int best_value = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (!in_bounds(nx, ny)) continue;\n            if (visited_square[nx][ny]) continue;\n            \n            int next_tile = t[nx][ny];\n            \n            if (next_tile == current_tile) {\n                if (best_dir == -1 || p[nx][ny] > best_value) {\n                    best_value = p[nx][ny];\n                    best_dir = d;\n                }\n            }\n        }\n        \n        // Second priority: move to new tile with highest total value\n        if (best_dir == -1) {\n            int best_tile_value = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                \n                if (!in_bounds(nx, ny)) continue;\n                if (visited_square[nx][ny]) continue;\n                \n                int next_tile = t[nx][ny];\n                \n                if (visited_tile[next_tile]) continue;\n                \n                if (tile_value[next_tile] > best_tile_value) {\n                    best_tile_value = tile_value[next_tile];\n                    best_dir = d;\n                }\n            }\n        }\n        \n        if (best_dir == -1) break;\n        \n        int nx = x + dx[best_dir];\n        int ny = y + dy[best_dir];\n        \n        path += dir_char[best_dir];\n        visited_square[nx][ny] = true;\n        visited_tile[t[nx][ny]] = true;\n        \n        x = nx;\n        y = ny;\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst double INF = 1e18;\nconst double DEFAULT_WEIGHT = 5000.0;\n\ndouble h[N][N], v[N][N];\nint h_count[N][N], v_count[N][N];\n\nvoid init_weights() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            h[i][j] = DEFAULT_WEIGHT;\n            v[i][j] = DEFAULT_WEIGHT;\n            h_count[i][j] = 0;\n            v_count[i][j] = 0;\n        }\n    }\n}\n\npair<double, vector<pair<int,int>>> dijkstra(int si, int sj, int ti, int tj) {\n    vector<vector<double>> dist(N, vector<double>(N, INF));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    priority_queue<pair<double, pair<int,int>>, \n                   vector<pair<double, pair<int,int>>>,\n                   greater<>> pq;\n    \n    dist[si][sj] = 0;\n    pq.push({0, {si, sj}});\n    \n    while (!pq.empty()) {\n        auto [d, pos] = pq.top();\n        pq.pop();\n        auto [i, j] = pos;\n        \n        if (d > dist[i][j]) continue;\n        \n        if (i > 0 && dist[i][j] + v[i-1][j] < dist[i-1][j]) {\n            dist[i-1][j] = dist[i][j] + v[i-1][j];\n            parent[i-1][j] = {i, j};\n            pq.push({dist[i-1][j], {i-1, j}});\n        }\n        if (i < N-1 && dist[i][j] + v[i][j] < dist[i+1][j]) {\n            dist[i+1][j] = dist[i][j] + v[i][j];\n            parent[i+1][j] = {i, j};\n            pq.push({dist[i+1][j], {i+1, j}});\n        }\n        if (j > 0 && dist[i][j] + h[i][j-1] < dist[i][j-1]) {\n            dist[i][j-1] = dist[i][j] + h[i][j-1];\n            parent[i][j-1] = {i, j};\n            pq.push({dist[i][j-1], {i, j-1}});\n        }\n        if (j < N-1 && dist[i][j] + h[i][j] < dist[i][j+1]) {\n            dist[i][j+1] = dist[i][j] + h[i][j];\n            parent[i][j+1] = {i, j};\n            pq.push({dist[i][j+1], {i, j+1}});\n        }\n    }\n    \n    vector<pair<int,int>> path;\n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        path.push_back({ci, cj});\n        auto [pi, pj] = parent[ci][cj];\n        if (pi == -1) break;\n        ci = pi;\n        cj = pj;\n    }\n    path.push_back({si, sj});\n    reverse(path.begin(), path.end());\n    \n    return {dist[ti][tj], path};\n}\n\nstring path_to_string(const vector<pair<int,int>>& path) {\n    string result;\n    for (int i = 1; i < path.size(); i++) {\n        int di = path[i].first - path[i-1].first;\n        int dj = path[i].second - path[i-1].second;\n        if (di == -1) result += 'U';\n        else if (di == 1) result += 'D';\n        else if (dj == -1) result += 'L';\n        else result += 'R';\n    }\n    return result;\n}\n\nvoid apply_row_column_smoothing() {\n    for (int i = 0; i < N; i++) {\n        vector<double> observed_vals;\n        for (int j = 0; j < N-1; j++) {\n            if (h_count[i][j] >= 2) {\n                observed_vals.push_back(h[i][j]);\n            }\n        }\n        if (observed_vals.size() >= 3) {\n            sort(observed_vals.begin(), observed_vals.end());\n            double median = observed_vals[observed_vals.size() / 2];\n            \n            for (int j = 0; j < N-1; j++) {\n                if (h_count[i][j] == 0) {\n                    h[i][j] = median;\n                } else if (h_count[i][j] == 1) {\n                    h[i][j] = 0.7 * h[i][j] + 0.3 * median;\n                }\n            }\n        }\n    }\n    \n    for (int j = 0; j < N; j++) {\n        vector<double> observed_vals;\n        for (int i = 0; i < N-1; i++) {\n            if (v_count[i][j] >= 2) {\n                observed_vals.push_back(v[i][j]);\n            }\n        }\n        if (observed_vals.size() >= 3) {\n            sort(observed_vals.begin(), observed_vals.end());\n            double median = observed_vals[observed_vals.size() / 2];\n            \n            for (int i = 0; i < N-1; i++) {\n                if (v_count[i][j] == 0) {\n                    v[i][j] = median;\n                } else if (v_count[i][j] == 1) {\n                    v[i][j] = 0.7 * v[i][j] + 0.3 * median;\n                }\n            }\n        }\n    }\n}\n\nvoid update_weights(const vector<pair<int,int>>& path, double measured, double estimated, int query_num) {\n    if (path.size() <= 1) return;\n    \n    vector<double> uncertainties;\n    double total_uncertainty = 0;\n    \n    for (int i = 1; i < path.size(); i++) {\n        int pi = path[i-1].first, pj = path[i-1].second;\n        int ci = path[i].first, cj = path[i].second;\n        \n        double uncertainty;\n        if (pi == ci) {\n            int j = min(pj, cj);\n            uncertainty = 1.0 / (1.0 + h_count[pi][j]);\n        } else {\n            int ii = min(pi, ci);\n            uncertainty = 1.0 / (1.0 + v_count[ii][pj]);\n        }\n        uncertainties.push_back(uncertainty);\n        total_uncertainty += uncertainty;\n    }\n    \n    double error = measured - estimated;\n    // Slightly slower decay for better late-stage learning\n    double base_alpha = 0.7 * exp(-query_num / 320.0) + 0.1;\n    \n    for (int i = 1; i < path.size(); i++) {\n        int pi = path[i-1].first, pj = path[i-1].second;\n        int ci = path[i].first, cj = path[i].second;\n        \n        double weight = uncertainties[i-1] / total_uncertainty;\n        double correction = base_alpha * error * weight;\n        \n        if (pi == ci) {\n            int j = min(pj, cj);\n            h_count[pi][j]++;\n            h[pi][j] += correction;\n            h[pi][j] = max(1000.0, min(9000.0, h[pi][j]));\n        } else {\n            int ii = min(pi, ci);\n            v_count[ii][pj]++;\n            v[ii][pj] += correction;\n            v[ii][pj] = max(1000.0, min(9000.0, v[ii][pj]));\n        }\n    }\n    \n    if (query_num % 30 == 29 && query_num < 900) {\n        apply_row_column_smoothing();\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    init_weights();\n    \n    for (int q = 0; q < 1000; q++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        auto [estimated_len, path] = dijkstra(si, sj, ti, tj);\n        string path_str = path_to_string(path);\n        \n        cout << path_str << endl;\n        cout.flush();\n        \n        int measured;\n        cin >> measured;\n        \n        update_weights(path, measured, estimated_len, q);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nvector<string> strings;\nchar matrix[20][20];\nchar best_matrix[20][20];\nint best_score = 0;\n\nbool isSubsequence(const string& s) {\n    int k = s.length();\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            bool ok = true;\n            for (int p = 0; p < k; p++) {\n                if (matrix[i][(j + p) % N] != s[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return true;\n            \n            ok = true;\n            for (int p = 0; p < k; p++) {\n                if (matrix[(i + p) % N][j] != s[p]) {\n                    ok = false;\n                    break;\n                }\n            }\n            if (ok) return true;\n        }\n    }\n    return false;\n}\n\nint countMatched() {\n    int count = 0;\n    for (int i = 0; i < M; i++) {\n        if (isSubsequence(strings[i])) count++;\n    }\n    return count;\n}\n\nvector<int> getUnmatchedIndices() {\n    vector<int> unmatched;\n    for (int i = 0; i < M; i++) {\n        if (!isSubsequence(strings[i])) {\n            unmatched.push_back(i);\n        }\n    }\n    return unmatched;\n}\n\nint countConflicts(const string& s, int i, int j, int d) {\n    int k = s.length();\n    int conflicts = 0;\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        if (matrix[ni][nj] != '.' && matrix[ni][nj] != s[p]) {\n            conflicts++;\n        }\n    }\n    return conflicts;\n}\n\nint countMatching(const string& s, int i, int j, int d) {\n    int k = s.length();\n    int matching = 0;\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        if (matrix[ni][nj] == s[p]) {\n            matching++;\n        }\n    }\n    return matching;\n}\n\nvoid place(const string& s, int i, int j, int d) {\n    int k = s.length();\n    for (int p = 0; p < k; p++) {\n        int ni = (d == 0) ? i : (i + p) % N;\n        int nj = (d == 0) ? (j + p) % N : j;\n        matrix[ni][nj] = s[p];\n    }\n}\n\nvoid weightedVoteFillDots() {\n    int votes[20][20][8];\n    memset(votes, 0, sizeof(votes));\n    \n    for (int idx = 0; idx < M; idx++) {\n        const string& s = strings[idx];\n        int k = s.length();\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                for (int d = 0; d < 2; d++) {\n                    int conflicts = countConflicts(s, i, j, d);\n                    \n                    if (conflicts <= 1) {\n                        int weight = (conflicts == 0) ? 2 : 1;\n                        for (int p = 0; p < k; p++) {\n                            int ni = (d == 0) ? i : (i + p) % N;\n                            int nj = (d == 0) ? (j + p) % N : j;\n                            if (matrix[ni][nj] == '.') {\n                                votes[ni][nj][s[p] - 'A'] += weight;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (matrix[i][j] == '.') {\n                int maxVotes = -1;\n                char bestChar = 'A';\n                \n                for (int c = 0; c < 8; c++) {\n                    if (votes[i][j][c] > maxVotes) {\n                        maxVotes = votes[i][j][c];\n                        bestChar = 'A' + c;\n                    }\n                }\n                \n                matrix[i][j] = bestChar;\n            }\n        }\n    }\n}\n\nvoid tryRestart(int restart_id, mt19937& rng) {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            matrix[i][j] = '.';\n        }\n    }\n    \n    vector<int> order(M);\n    iota(order.begin(), order.end(), 0);\n    \n    if (restart_id == 0) {\n        sort(order.begin(), order.end(), [](int a, int b) {\n            return strings[a].length() > strings[b].length();\n        });\n    } else if (restart_id % 3 == 1) {\n        sort(order.begin(), order.end(), [](int a, int b) {\n            return strings[a].length() < strings[b].length();\n        });\n    } else {\n        shuffle(order.begin(), order.end(), rng);\n    }\n    \n    vector<bool> matched(M, false);\n    int maxConflictLimit = (restart_id % 5 == 0) ? 3 : 2;\n    \n    for (int maxConflicts = 0; maxConflicts <= maxConflictLimit; maxConflicts++) {\n        for (int idx : order) {\n            if (matched[idx]) continue;\n            \n            const string& s = strings[idx];\n            \n            int bestI = -1, bestJ = -1, bestD = -1;\n            int minConflicts = INT_MAX;\n            int maxMatching = -1;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    for (int d = 0; d < 2; d++) {\n                        int conflicts = countConflicts(s, i, j, d);\n                        if (conflicts > maxConflicts) continue;\n                        \n                        int matching = countMatching(s, i, j, d);\n                        \n                        if (conflicts < minConflicts || \n                            (conflicts == minConflicts && matching > maxMatching)) {\n                            minConflicts = conflicts;\n                            maxMatching = matching;\n                            bestI = i;\n                            bestJ = j;\n                            bestD = d;\n                        }\n                    }\n                }\n            }\n            \n            if (minConflicts <= maxConflicts && bestI != -1) {\n                place(s, bestI, bestJ, bestD);\n                matched[idx] = true;\n            }\n        }\n    }\n    \n    weightedVoteFillDots();\n    \n    int score = countMatched();\n    if (score > best_score) {\n        best_score = score;\n        memcpy(best_matrix, matrix, sizeof(matrix));\n    }\n}\n\nvoid targetedLocalSearch(mt19937& rng, int iterations) {\n    uniform_int_distribution<int> dist_pos(0, N-1);\n    uniform_int_distribution<int> dist_char(0, 7);\n    \n    int current_score = countMatched();\n    auto unmatched = getUnmatchedIndices();\n    \n    // Build hotspot map from unmatched strings\n    int hotspots[20][20];\n    memset(hotspots, 0, sizeof(hotspots));\n    \n    for (int idx : unmatched) {\n        const string& s = strings[idx];\n        int k = s.length();\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                for (int d = 0; d < 2; d++) {\n                    if (countConflicts(s, i, j, d) <= 2) {\n                        for (int p = 0; p < k; p++) {\n                            int ni = (d == 0) ? i : (i + p) % N;\n                            int nj = (d == 0) ? (j + p) % N : j;\n                            hotspots[ni][nj]++;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Collect high-priority cells\n    vector<pair<int, pair<int, int>>> candidates;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (hotspots[i][j] > 0) {\n                candidates.push_back({hotspots[i][j], {i, j}});\n            }\n        }\n    }\n    sort(candidates.rbegin(), candidates.rend());\n    \n    // Try modifying hotspot cells\n    for (int iter = 0; iter < iterations && iter < (int)candidates.size() * 8; iter++) {\n        int cell_idx = iter / 8;\n        if (cell_idx >= (int)candidates.size()) break;\n        \n        int i = candidates[cell_idx].second.first;\n        int j = candidates[cell_idx].second.second;\n        char old_char = matrix[i][j];\n        char new_char = 'A' + (iter % 8);\n        \n        if (old_char == new_char) continue;\n        \n        matrix[i][j] = new_char;\n        int new_score = countMatched();\n        \n        if (new_score >= current_score) {\n            current_score = new_score;\n            if (new_score > best_score) {\n                best_score = new_score;\n                memcpy(best_matrix, matrix, sizeof(matrix));\n            }\n        } else {\n            matrix[i][j] = old_char;\n        }\n    }\n}\n\nvoid randomLocalSearch(mt19937& rng, int iterations) {\n    uniform_int_distribution<int> dist_pos(0, N-1);\n    uniform_int_distribution<int> dist_char(0, 7);\n    \n    int current_score = countMatched();\n    \n    for (int iter = 0; iter < iterations; iter++) {\n        int i = dist_pos(rng);\n        int j = dist_pos(rng);\n        char old_char = matrix[i][j];\n        char new_char = 'A' + dist_char(rng);\n        \n        if (old_char == new_char) continue;\n        \n        matrix[i][j] = new_char;\n        int new_score = countMatched();\n        \n        if (new_score >= current_score) {\n            current_score = new_score;\n            if (new_score > best_score) {\n                best_score = new_score;\n                memcpy(best_matrix, matrix, sizeof(matrix));\n            }\n        } else {\n            matrix[i][j] = old_char;\n        }\n    }\n}\n\nint main() {\n    cin >> N >> M;\n    strings.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    unsigned int seed = M;\n    for (const auto& s : strings) {\n        for (char c : s) {\n            seed = seed * 31 + c;\n        }\n    }\n    \n    mt19937 rng(seed);\n    auto start_time = chrono::steady_clock::now();\n    \n    // Fewer restarts, more local search\n    for (int restart = 0; restart < 15; restart++) {\n        tryRestart(restart, rng);\n        \n        auto current_time = chrono::steady_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n        if (elapsed > 1800) break;\n    }\n    \n    auto current_time = chrono::steady_clock::now();\n    auto elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n    \n    if (elapsed < 2700) {\n        memcpy(matrix, best_matrix, sizeof(matrix));\n        \n        // Targeted search first\n        int time_for_targeted = min(300, (int)(2700 - elapsed) / 3);\n        targetedLocalSearch(rng, time_for_targeted);\n        \n        current_time = chrono::steady_clock::now();\n        elapsed = chrono::duration_cast<chrono::milliseconds>(current_time - start_time).count();\n        \n        // Random search with remaining time\n        if (elapsed < 2700) {\n            int remaining_time = 2700 - elapsed;\n            int iterations = remaining_time / 2;\n            randomLocalSearch(rng, iterations);\n        }\n    }\n    \n    memcpy(matrix, best_matrix, sizeof(matrix));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << matrix[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\n\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nbool is_valid(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\nset<pair<int,int>> get_visible(int i, int j) {\n    set<pair<int,int>> vis;\n    vis.insert({i, j});\n    for (int jj = j-1; jj >= 0 && grid[i][jj] != '#'; jj--) vis.insert({i, jj});\n    for (int jj = j+1; jj < N && grid[i][jj] != '#'; jj++) vis.insert({i, jj});\n    for (int ii = i-1; ii >= 0 && grid[ii][j] != '#'; ii--) vis.insert({ii, j});\n    for (int ii = i+1; ii < N && grid[ii][j] != '#'; ii++) vis.insert({ii, j});\n    return vis;\n}\n\nmap<pair<int,int>, int> dijkstra_dist(int si, int sj) {\n    map<pair<int,int>, int> dist;\n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    pq.push({0, si, sj});\n    dist[{si, sj}] = 0;\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        if (dist.count({i,j}) && d > dist[{i, j}]) continue;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (is_valid(ni, nj)) {\n                int nd = d + (grid[ni][nj] - '0');\n                if (!dist.count({ni, nj}) || nd < dist[{ni, nj}]) {\n                    dist[{ni, nj}] = nd;\n                    pq.push({nd, ni, nj});\n                }\n            }\n        }\n    }\n    return dist;\n}\n\nstring reconstruct_path(int si, int sj, int ti, int tj) {\n    if (si == ti && sj == tj) return \"\";\n    \n    map<pair<int,int>, pair<pair<int,int>, int>> parent;\n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    pq.push({0, si, sj});\n    parent[{si, sj}] = {{-1, -1}, -1};\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        if (i == ti && j == tj) {\n            string path;\n            auto curr = make_pair(ti, tj);\n            while (parent[curr].second != -1) {\n                path += dir_char[parent[curr].second];\n                curr = parent[curr].first;\n            }\n            reverse(path.begin(), path.end());\n            return path;\n        }\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int ni = i + di[dir], nj = j + dj[dir];\n            if (is_valid(ni, nj) && !parent.count({ni, nj})) {\n                parent[{ni, nj}] = {{i, j}, dir};\n                int nd = d + (grid[ni][nj] - '0');\n                pq.push({nd, ni, nj});\n            }\n        }\n    }\n    return \"\";\n}\n\nint main() {\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    vector<pair<int,int>> roads;\n    set<pair<int,int>> all_roads;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] != '#') {\n                roads.push_back({i, j});\n                all_roads.insert({i, j});\n            }\n        }\n    }\n    \n    map<pair<int,int>, set<pair<int,int>>> visible_from;\n    for (auto& [i, j] : roads) {\n        visible_from[{i, j}] = get_visible(i, j);\n    }\n    \n    map<pair<int,int>, int> coverage_count;\n    for (auto& sq : all_roads) {\n        for (auto& [pos, vis] : visible_from) {\n            if (vis.count(sq)) coverage_count[sq]++;\n        }\n    }\n    \n    // Step 1: Adaptive greedy selection\n    set<pair<int,int>> covered = visible_from[{si, sj}];\n    vector<pair<int,int>> selected_positions = {{si, sj}};\n    \n    while (covered.size() < all_roads.size()) {\n        auto dist = dijkstra_dist(selected_positions.back().first, selected_positions.back().second);\n        \n        // Adaptive importance weight based on coverage progress\n        double progress = (double)covered.size() / all_roads.size();\n        double importance_weight = (progress < 0.7) ? 15.0 : 8.0;\n        \n        double best_score = -1e9;\n        pair<int,int> best_pos = selected_positions.back();\n        \n        for (auto& [ri, rj] : roads) {\n            int new_count = 0;\n            double importance = 0;\n            for (auto& sq : visible_from[{ri, rj}]) {\n                if (!covered.count(sq)) {\n                    new_count++;\n                    importance += 1.0 / max(1, coverage_count[sq]);\n                }\n            }\n            if (new_count > 0 && dist.count({ri, rj})) {\n                int cost = dist[{ri, rj}];\n                double score = (importance * importance_weight) / (cost + 1.0);\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_pos = {ri, rj};\n                }\n            }\n        }\n        \n        if (best_score <= -1e8) break;\n        \n        selected_positions.push_back(best_pos);\n        for (auto& sq : visible_from[best_pos]) covered.insert(sq);\n    }\n    \n    // Step 2: Nearest neighbor reordering\n    vector<pair<int,int>> tour;\n    if (selected_positions.size() > 3) {\n        set<pair<int,int>> unvisited(selected_positions.begin() + 1, selected_positions.end());\n        tour = {{si, sj}};\n        auto curr = make_pair(si, sj);\n        \n        while (!unvisited.empty()) {\n            auto dist = dijkstra_dist(curr.first, curr.second);\n            int best_dist = INT_MAX;\n            pair<int,int> best_pos = curr;\n            \n            for (auto& pos : unvisited) {\n                if (dist.count(pos) && dist[pos] < best_dist) {\n                    best_dist = dist[pos];\n                    best_pos = pos;\n                }\n            }\n            \n            tour.push_back(best_pos);\n            unvisited.erase(best_pos);\n            curr = best_pos;\n        }\n    } else {\n        tour = selected_positions;\n    }\n    \n    // Step 3: Comprehensive local optimization\n    if (tour.size() >= 4) {\n        map<pair<pair<int,int>, pair<int,int>>, int> dist_cache;\n        for (auto& p1 : tour) {\n            auto dist = dijkstra_dist(p1.first, p1.second);\n            for (auto& p2 : tour) {\n                if (dist.count(p2)) {\n                    dist_cache[{p1, p2}] = dist[p2];\n                }\n            }\n        }\n        \n        // Thorough local search with all techniques\n        for (int round = 0; round < 20; round++) {\n            bool improved = false;\n            \n            // 2-opt\n            for (int i = 1; i < (int)tour.size() - 2; i++) {\n                for (int j = i + 1; j < (int)tour.size() - 1; j++) {\n                    int old_cost = dist_cache[{tour[i-1], tour[i]}] + dist_cache[{tour[j], tour[j+1]}];\n                    int new_cost = dist_cache[{tour[i-1], tour[j]}] + dist_cache[{tour[i], tour[j+1]}];\n                    \n                    if (new_cost < old_cost) {\n                        reverse(tour.begin() + i, tour.begin() + j + 1);\n                        improved = true;\n                    }\n                }\n            }\n            \n            // 1-node Or-opt\n            for (int i = 1; i < (int)tour.size() - 1 && !improved; i++) {\n                int remove_cost = dist_cache[{tour[i-1], tour[i]}] + dist_cache[{tour[i], tour[i+1]}];\n                int after_remove = dist_cache[{tour[i-1], tour[i+1]}];\n                \n                for (int j = 1; j < (int)tour.size() - 1; j++) {\n                    if (abs(i - j) <= 1) continue;\n                    \n                    int insert_cost = dist_cache[{tour[j], tour[i]}] + dist_cache[{tour[i], tour[j+1]}];\n                    int before_insert = dist_cache[{tour[j], tour[j+1]}];\n                    \n                    if (after_remove + insert_cost < remove_cost + before_insert) {\n                        auto node = tour[i];\n                        tour.erase(tour.begin() + i);\n                        if (j > i) j--;\n                        tour.insert(tour.begin() + j + 1, node);\n                        improved = true;\n                        break;\n                    }\n                }\n                if (improved) break;\n            }\n            \n            // 2-node Or-opt\n            for (int i = 1; i < (int)tour.size() - 2 && !improved; i++) {\n                int remove_cost = dist_cache[{tour[i-1], tour[i]}] + \n                                 dist_cache[{tour[i], tour[i+1]}] + \n                                 dist_cache[{tour[i+1], tour[i+2]}];\n                int after_remove = dist_cache[{tour[i-1], tour[i+2]}];\n                \n                for (int j = 1; j < (int)tour.size() - 2; j++) {\n                    if (abs(i - j) <= 2) continue;\n                    \n                    int insert_cost = dist_cache[{tour[j], tour[i]}] + \n                                     dist_cache[{tour[i], tour[i+1]}] + \n                                     dist_cache[{tour[i+1], tour[j+1]}];\n                    int before_insert = dist_cache[{tour[j], tour[j+1]}];\n                    \n                    if (after_remove + insert_cost < remove_cost + before_insert) {\n                        auto node1 = tour[i];\n                        auto node2 = tour[i+1];\n                        tour.erase(tour.begin() + i, tour.begin() + i + 2);\n                        if (j > i) j -= 2;\n                        tour.insert(tour.begin() + j + 1, node2);\n                        tour.insert(tour.begin() + j + 1, node1);\n                        improved = true;\n                        break;\n                    }\n                }\n                if (improved) break;\n            }\n            \n            if (!improved) break;\n        }\n    }\n    \n    // Build path\n    string result;\n    for (int i = 0; i < (int)tour.size() - 1; i++) {\n        result += reconstruct_path(tour[i].first, tour[i].second, \n                                   tour[i+1].first, tour[i+1].second);\n    }\n    result += reconstruct_path(tour.back().first, tour.back().second, si, sj);\n    \n    cout << result << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <map>\n#include <cmath>\nusing namespace std;\n\nint N, M, K, R;\nvector<vector<int>> task_diff;\nvector<vector<int>> task_deps;\nvector<vector<int>> task_dependents;\nvector<int> task_status;\nvector<vector<double>> member_skill;\nvector<int> member_task;\nvector<int> start_day_map;\nvector<int> num_pending_deps;\nvector<int> task_urgency;\nvector<int> member_completed_count;\nint day_counter = 0;\n\nvoid calculate_urgency() {\n    task_urgency.resize(N, 0);\n    \n    // BFS from leaves to roots\n    vector<int> out_degree(N, 0);\n    for (int i = 0; i < N; i++) {\n        out_degree[i] = task_dependents[i].size();\n    }\n    \n    queue<int> q;\n    for (int i = 0; i < N; i++) {\n        if (out_degree[i] == 0) {\n            q.push(i);\n            task_urgency[i] = 0;\n        }\n    }\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        \n        for (int v : task_deps[u]) {\n            task_urgency[v] = max(task_urgency[v], task_urgency[u] + 1);\n            out_degree[v]--;\n            if (out_degree[v] == 0) {\n                q.push(v);\n            }\n        }\n    }\n}\n\nbool can_start(int task) {\n    return task_status[task] == -1 && num_pending_deps[task] == 0;\n}\n\ndouble estimate_time(int task, int member) {\n    double w = 0;\n    for (int k = 0; k < K; k++) {\n        w += max(0.0, task_diff[task][k] - member_skill[member][k]);\n    }\n    return max(1.0, w);\n}\n\nvoid update_skill(int member, int task, int days) {\n    member_completed_count[member]++;\n    \n    // Adaptive learning: learn faster early, more conservative later\n    double base_rate = 1.0 / sqrt(1.0 + member_completed_count[member] * 0.2);\n    \n    if (days == 1) {\n        // Perfect match - member has all required skills\n        for (int k = 0; k < K; k++) {\n            member_skill[member][k] = max(member_skill[member][k], \n                                         (double)task_diff[task][k]);\n        }\n    } else {\n        // Estimate w \u2248 days - 1 (with noise \u00b13)\n        double min_w = max(0.0, days - 4.0);\n        double max_w = max(0.0, days + 2.0);\n        \n        double current_w = 0;\n        for (int k = 0; k < K; k++) {\n            current_w += max(0.0, task_diff[task][k] - member_skill[member][k]);\n        }\n        \n        if (current_w > max_w) {\n            // We significantly underestimated - learn aggressively\n            for (int k = 0; k < K; k++) {\n                double diff = task_diff[task][k] - member_skill[member][k];\n                if (diff > 0) {\n                    member_skill[member][k] += diff * base_rate * 0.6;\n                }\n            }\n        } else if (current_w > min_w && days <= 5) {\n            // Good match zone - learn moderately\n            for (int k = 0; k < K; k++) {\n                double diff = task_diff[task][k] - member_skill[member][k];\n                if (diff > 0) {\n                    member_skill[member][k] += diff * base_rate * 0.3;\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> K >> R;\n    \n    task_diff.resize(N, vector<int>(K));\n    task_deps.resize(N);\n    task_dependents.resize(N);\n    task_status.resize(N, -1);\n    num_pending_deps.resize(N, 0);\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> task_diff[i][j];\n        }\n    }\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        task_deps[v].push_back(u);\n        task_dependents[u].push_back(v);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        num_pending_deps[i] = task_deps[i].size();\n    }\n    \n    calculate_urgency();\n    \n    // Better initial skill estimates\n    vector<double> avg_skill(K, 0.0);\n    for (int i = 0; i < N; i++) {\n        for (int k = 0; k < K; k++) {\n            avg_skill[k] += task_diff[i][k];\n        }\n    }\n    for (int k = 0; k < K; k++) {\n        avg_skill[k] /= N;\n    }\n    \n    member_skill.resize(M, avg_skill);\n    member_task.resize(M, -1);\n    start_day_map.resize(M);\n    member_completed_count.resize(M, 0);\n    \n    while (true) {\n        day_counter++;\n        \n        vector<int> available;\n        available.reserve(N);\n        for (int i = 0; i < N; i++) {\n            if (can_start(i)) {\n                available.push_back(i);\n            }\n        }\n        \n        // Sort by urgency (depth in dependency tree)\n        sort(available.begin(), available.end(), [](int a, int b) {\n            if (task_urgency[a] != task_urgency[b]) {\n                return task_urgency[a] > task_urgency[b];\n            }\n            return task_dependents[a].size() > task_dependents[b].size();\n        });\n        \n        vector<int> idle;\n        idle.reserve(M);\n        for (int i = 0; i < M; i++) {\n            if (member_task[i] == -1) {\n                idle.push_back(i);\n            }\n        }\n        \n        vector<pair<int, int>> assign;\n        assign.reserve(min(available.size(), idle.size()));\n        vector<bool> member_used(M, false);\n        \n        // For each task (by priority), find best member\n        for (int t : available) {\n            int best_member = -1;\n            double best_score = 1e9;\n            \n            for (int m : idle) {\n                if (member_used[m]) continue;\n                \n                double est_time = estimate_time(t, m);\n                \n                // Exploration bonus: encourage learning in early phase\n                double exploration_bonus = 0;\n                if (day_counter <= 50 && member_completed_count[m] < 5) {\n                    exploration_bonus = -1.0;\n                }\n                \n                double score = est_time + exploration_bonus;\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_member = m;\n                }\n            }\n            \n            if (best_member != -1) {\n                assign.push_back({best_member, t});\n                member_task[best_member] = t;\n                task_status[t] = 0;\n                member_used[best_member] = true;\n                start_day_map[best_member] = day_counter;\n            }\n        }\n        \n        cout << assign.size();\n        for (auto [m, t] : assign) {\n            cout << \" \" << (m + 1) << \" \" << (t + 1);\n        }\n        cout << \"\\n\";\n        cout.flush();\n        \n        int n;\n        cin >> n;\n        if (n == -1) break;\n        \n        for (int i = 0; i < n; i++) {\n            int m;\n            cin >> m;\n            m--;\n            \n            int t = member_task[m];\n            int days = day_counter - start_day_map[m] + 1;\n            \n            task_status[t] = 1;\n            member_task[m] = -1;\n            \n            for (int dep : task_dependents[t]) {\n                num_pending_deps[dep]--;\n            }\n            \n            update_skill(m, t, days);\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <chrono>\n\nusing namespace std;\n\nstruct Order {\n    int id;\n    int ax, ay, cx, cy;\n};\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nclass Solution {\npublic:\n    vector<Order> orders;\n    chrono::high_resolution_clock::time_point start_time;\n    \n    void read_input() {\n        orders.resize(1000);\n        for (int i = 0; i < 1000; i++) {\n            orders[i].id = i;\n            cin >> orders[i].ax >> orders[i].ay >> orders[i].cx >> orders[i].cy;\n        }\n        start_time = chrono::high_resolution_clock::now();\n    }\n    \n    double elapsed_ms() {\n        auto now = chrono::high_resolution_clock::now();\n        return chrono::duration<double, milli>(now - start_time).count();\n    }\n    \n    int calc_cost(const vector<pair<int, int>>& route) {\n        int cost = 0;\n        for (size_t i = 1; i < route.size(); i++) {\n            cost += manhattan(route[i-1].first, route[i-1].second, route[i].first, route[i].second);\n        }\n        return cost;\n    }\n    \n    double score_order(int idx, double w1, double w2, double w3, double w4, double w5) {\n        double d_pickup = manhattan(400, 400, orders[idx].ax, orders[idx].ay);\n        double d_delivery = manhattan(400, 400, orders[idx].cx, orders[idx].cy);\n        double d_pd = manhattan(orders[idx].ax, orders[idx].ay, orders[idx].cx, orders[idx].cy);\n        \n        int mx = (orders[idx].ax + orders[idx].cx) / 2;\n        int my = (orders[idx].ay + orders[idx].cy) / 2;\n        double d_center = manhattan(400, 400, mx, my);\n        \n        double compactness = d_pd / max(1.0, (d_pickup + d_delivery) * 0.5);\n        double avg_dist = (d_pickup + d_delivery) / 2.0;\n        \n        return d_pickup * w1 + d_delivery * w1 + d_pd * w2 + d_center * w3 - compactness * w4 * 100 + avg_dist * w5;\n    }\n    \n    vector<int> select_orders(double w1, double w2, double w3, double w4, double w5) {\n        vector<pair<double, int>> scores;\n        for (int i = 0; i < 1000; i++) {\n            scores.push_back({score_order(i, w1, w2, w3, w4, w5), i});\n        }\n        sort(scores.begin(), scores.end());\n        \n        vector<int> selected;\n        for (int i = 0; i < 50; i++) {\n            selected.push_back(scores[i].second);\n        }\n        return selected;\n    }\n    \n    vector<pair<int, int>> construct_route_greedy(const vector<int>& selected) {\n        vector<pair<int, int>> route;\n        route.push_back({400, 400});\n        \n        set<int> need_pickup(selected.begin(), selected.end());\n        set<int> picked_up;\n        \n        int cx = 400, cy = 400;\n        \n        while (!need_pickup.empty() || !picked_up.empty()) {\n            int best_idx = -1;\n            int best_dist = 2000000;\n            bool is_pickup = false;\n            \n            for (int idx : need_pickup) {\n                int d = manhattan(cx, cy, orders[idx].ax, orders[idx].ay);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = true;\n                }\n            }\n            \n            for (int idx : picked_up) {\n                int d = manhattan(cx, cy, orders[idx].cx, orders[idx].cy);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = false;\n                }\n            }\n            \n            if (is_pickup) {\n                route.push_back({orders[best_idx].ax, orders[best_idx].ay});\n                cx = orders[best_idx].ax;\n                cy = orders[best_idx].ay;\n                need_pickup.erase(best_idx);\n                picked_up.insert(best_idx);\n            } else {\n                route.push_back({orders[best_idx].cx, orders[best_idx].cy});\n                cx = orders[best_idx].cx;\n                cy = orders[best_idx].cy;\n                picked_up.erase(best_idx);\n            }\n        }\n        \n        route.push_back({400, 400});\n        return route;\n    }\n    \n    vector<pair<int, int>> construct_route_paired(const vector<int>& selected, int threshold) {\n        vector<pair<int, int>> route;\n        route.push_back({400, 400});\n        \n        set<int> need_pickup(selected.begin(), selected.end());\n        set<int> picked_up;\n        \n        int cx = 400, cy = 400;\n        \n        while (!need_pickup.empty() || !picked_up.empty()) {\n            int best_idx = -1;\n            int best_dist = 2000000;\n            bool is_pickup = false;\n            \n            for (int idx : need_pickup) {\n                int d = manhattan(cx, cy, orders[idx].ax, orders[idx].ay);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = true;\n                }\n            }\n            \n            for (int idx : picked_up) {\n                int d = manhattan(cx, cy, orders[idx].cx, orders[idx].cy);\n                if (d < best_dist) {\n                    best_dist = d;\n                    best_idx = idx;\n                    is_pickup = false;\n                }\n            }\n            \n            if (is_pickup) {\n                route.push_back({orders[best_idx].ax, orders[best_idx].ay});\n                cx = orders[best_idx].ax;\n                cy = orders[best_idx].ay;\n                need_pickup.erase(best_idx);\n                \n                int d_to_delivery = manhattan(cx, cy, orders[best_idx].cx, orders[best_idx].cy);\n                if (d_to_delivery <= threshold) {\n                    route.push_back({orders[best_idx].cx, orders[best_idx].cy});\n                    cx = orders[best_idx].cx;\n                    cy = orders[best_idx].cy;\n                } else {\n                    picked_up.insert(best_idx);\n                }\n            } else {\n                route.push_back({orders[best_idx].cx, orders[best_idx].cy});\n                cx = orders[best_idx].cx;\n                cy = orders[best_idx].cy;\n                picked_up.erase(best_idx);\n            }\n        }\n        \n        route.push_back({400, 400});\n        return route;\n    }\n    \n    void solve() {\n        read_input();\n        \n        int best_cost = 2000000000;\n        vector<int> best_selected;\n        vector<pair<int, int>> best_route;\n        \n        // Optimized 2-phase search - proven best approach\n        \n        // Phase 1: Efficient coarse exploration (0-900ms)\n        for (double w1 = 0.05; w1 <= 1.0 && elapsed_ms() < 900; w1 += 0.05) {\n            for (double w3 = 0.0; w3 <= 0.6 && elapsed_ms() < 900; w3 += 0.05) {\n                for (double w4 = 0.0; w4 <= 0.35 && elapsed_ms() < 900; w4 += 0.05) {\n                    for (double w5 = -0.2; w5 <= 0.2 && elapsed_ms() < 900; w5 += 0.1) {\n                        double w2 = 1.0 - w1 - w3 - w4 - w5;\n                        if (w2 < -0.05 || w2 > 1.05) continue;\n                        \n                        vector<int> selected = select_orders(w1, w2, w3, w4, w5);\n                        \n                        vector<pair<int, int>> route1 = construct_route_greedy(selected);\n                        int cost1 = calc_cost(route1);\n                        if (cost1 < best_cost) {\n                            best_cost = cost1;\n                            best_selected = selected;\n                            best_route = route1;\n                        }\n                        \n                        for (int threshold : {30, 60, 100, 150, 210, 280, 370, 480, 610}) {\n                            if (elapsed_ms() >= 900) break;\n                            vector<pair<int, int>> route2 = construct_route_paired(selected, threshold);\n                            int cost2 = calc_cost(route2);\n                            if (cost2 < best_cost) {\n                                best_cost = cost2;\n                                best_selected = selected;\n                                best_route = route2;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Phase 2: Intensive fine search (900-1960ms)\n        for (double w1 = 0.05; w1 <= 1.0 && elapsed_ms() < 1960; w1 += 0.025) {\n            for (double w3 = 0.0; w3 <= 0.65 && elapsed_ms() < 1960; w3 += 0.025) {\n                for (double w4 = 0.0; w4 <= 0.4 && elapsed_ms() < 1960; w4 += 0.025) {\n                    for (double w5 = -0.25; w5 <= 0.25 && elapsed_ms() < 1960; w5 += 0.125) {\n                        double w2 = 1.0 - w1 - w3 - w4 - w5;\n                        if (w2 < -0.05 || w2 > 1.05) continue;\n                        \n                        vector<int> selected = select_orders(w1, w2, w3, w4, w5);\n                        \n                        vector<pair<int, int>> route1 = construct_route_greedy(selected);\n                        int cost1 = calc_cost(route1);\n                        if (cost1 < best_cost) {\n                            best_cost = cost1;\n                            best_selected = selected;\n                            best_route = route1;\n                        }\n                        \n                        // Comprehensive threshold coverage\n                        for (int threshold : {22, 38, 54, 72, 92, 114, 139, 167, 198, 233, 272, 316, 366, 423, 487, 560, 643, 738, 848}) {\n                            if (elapsed_ms() >= 1960) break;\n                            vector<pair<int, int>> route2 = construct_route_paired(selected, threshold);\n                            int cost2 = calc_cost(route2);\n                            if (cost2 < best_cost) {\n                                best_cost = cost2;\n                                best_selected = selected;\n                                best_route = route2;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        cout << best_selected.size();\n        for (int idx : best_selected) {\n            cout << \" \" << (idx + 1);\n        }\n        cout << \"\\n\";\n        \n        cout << best_route.size();\n        for (auto [x, y] : best_route) {\n            cout << \" \" << x << \" \" << y;\n        }\n        cout << \"\\n\";\n        cout.flush();\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.solve();\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent, rank;\npublic:\n    UnionFind(int n) : parent(n), rank(n, 0) {\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    \n    int find(int x) {\n        return parent[x] == x ? x : parent[x] = find(parent[x]);\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (rank[x] < rank[y]) swap(x, y);\n        parent[y] = x;\n        if (rank[x] == rank[y]) rank[x]++;\n        return true;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400, M = 1995;\n    \n    vector<pair<int,int>> coord(N);\n    for (auto& [x, y] : coord) cin >> x >> y;\n    \n    vector<pair<int,int>> edge(M);\n    vector<int> dist(M);\n    \n    for (int i = 0; i < M; i++) {\n        auto& [u, v] = edge[i];\n        cin >> u >> v;\n        int dx = coord[u].first - coord[v].first;\n        int dy = coord[u].second - coord[v].second;\n        dist[i] = round(sqrt(dx*dx + dy*dy));\n    }\n    \n    UnionFind uf(N);\n    int cnt = 0;\n    \n    for (int i = 0; i < M; i++) {\n        int len;\n        cin >> len;\n        \n        auto [u, v] = edge[i];\n        int d = dist[i];\n        \n        bool ok = false;\n        if (uf.find(u) != uf.find(v)) {\n            int need = N - 1 - cnt;\n            int left = M - i;\n            \n            double r = (double)len / d;\n            double safety = (double)left / need;\n            \n            // Proven stable thresholds\n            double th;\n            if (safety <= 10) {\n                th = 999.9;  // Accept everything\n            } else if (safety <= 20) {\n                th = 2.85;\n            } else if (safety <= 30) {\n                th = 2.75;\n            } else if (safety <= 50) {\n                th = 2.6;\n            } else {\n                th = 2.5;\n            }\n            \n            // Multi-tier short edge bonus - prefer low absolute cost edges\n            ok = (r <= th) || \n                 (safety > 10 && len <= 60) ||  // Very short edges\n                 (safety > 12 && len <= 100);   // Short edges\n        }\n        \n        cout << (ok ? \"1\" : \"0\") << \"\\n\" << flush;\n        if (ok) {\n            uf.unite(u, v);\n            cnt++;\n        }\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Pos {\n    int x, y;\n    bool operator<(const Pos& o) const {\n        if (x != o.x) return x < o.x;\n        return y < o.y;\n    }\n};\n\nint N, M;\nvector<Pos> pets, humans;\nvector<int> pet_types;\nbool grid[32][32];\nset<Pos> pet_set;\n\nvoid init() {\n    cin >> N;\n    pets.resize(N);\n    pet_types.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pet_types[i];\n        pet_set.insert(pets[i]);\n    }\n    cin >> M;\n    humans.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n    \n    for (int i = 0; i <= 31; i++)\n        for (int j = 0; j <= 31; j++)\n            grid[i][j] = (i >= 1 && i <= 30 && j >= 1 && j <= 30);\n}\n\nbool is_adjacent_to_pet(int x, int y) {\n    return pet_set.count({x-1, y}) || pet_set.count({x+1, y}) ||\n           pet_set.count({x, y-1}) || pet_set.count({x, y+1});\n}\n\nbool in_bounds(int x, int y) {\n    return x >= 1 && x <= 30 && y >= 1 && y <= 30;\n}\n\nbool can_build_wall(int x, int y, const set<Pos>& human_set) {\n    if (!in_bounds(x, y)) return false;\n    if (!grid[x][y]) return false;\n    if (pet_set.count({x, y})) return false;\n    if (human_set.count({x, y})) return false;\n    if (is_adjacent_to_pet(x, y)) return false;\n    return true;\n}\n\nint manhattan(const Pos& a, const Pos& b) {\n    return abs(a.x - b.x) + abs(a.y - b.y);\n}\n\n// Calculate bounding box of humans\nvoid get_human_bounds(int& min_x, int& max_x, int& min_y, int& max_y) {\n    min_x = 31, max_x = 0, min_y = 31, max_y = 0;\n    for (const auto& h : humans) {\n        min_x = min(min_x, h.x);\n        max_x = max(max_x, h.x);\n        min_y = min(min_y, h.y);\n        max_y = max(max_y, h.y);\n    }\n}\n\n// Get priority for building a wall at this position\nint get_wall_priority(int x, int y, const set<Pos>& walls_to_build, int turn) {\n    int priority = 0;\n    \n    // Strong preference for walls connected to existing walls\n    int wall_neighbors = 0;\n    if (!grid[x-1][y] || walls_to_build.count({x-1, y})) wall_neighbors++;\n    if (!grid[x+1][y] || walls_to_build.count({x+1, y})) wall_neighbors++;\n    if (!grid[x][y-1] || walls_to_build.count({x, y-1})) wall_neighbors++;\n    if (!grid[x][y+1] || walls_to_build.count({x, y+1})) wall_neighbors++;\n    \n    priority += wall_neighbors * 100;\n    \n    // Calculate distance from human bounding box\n    int min_x, max_x, min_y, max_y;\n    get_human_bounds(min_x, max_x, min_y, max_y);\n    \n    // Expand the box by a margin based on turn\n    int margin = min(4, turn / 30); // Gradually expand\n    min_x -= margin;\n    max_x += margin;\n    min_y -= margin;\n    max_y += margin;\n    \n    // Check if on perimeter of expanded box\n    bool on_perimeter = (x == min_x || x == max_x || y == min_y || y == max_y);\n    if (on_perimeter) {\n        priority += 500; // High priority for perimeter\n    }\n    \n    // Check if on second layer\n    bool on_second = (x == min_x-1 || x == max_x+1 || y == min_y-1 || y == max_y+1);\n    if (on_second) {\n        priority += 300;\n    }\n    \n    return priority;\n}\n\nint main() {\n    init();\n    \n    // Find safe corner - farthest from all pets\n    int best_cx = 15, best_cy = 15;\n    double max_total_dist = 0;\n    \n    for (int cx : {7, 15, 23}) {\n        for (int cy : {7, 15, 23}) {\n            double total_dist = 0;\n            for (const auto& p : pets) {\n                total_dist += manhattan({cx, cy}, p);\n            }\n            if (total_dist > max_total_dist) {\n                max_total_dist = total_dist;\n                best_cx = cx;\n                best_cy = cy;\n            }\n        }\n    }\n    \n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n        \n        set<Pos> human_set;\n        for (const auto& h : humans) {\n            human_set.insert(h);\n        }\n        \n        vector<pair<int,int>> dirs = {{-1,0},{1,0},{0,-1},{0,1}};\n        string wall_chars = \"udlr\";\n        string move_chars = \"UDLR\";\n        \n        // PHASE 1: Decide wall building\n        set<Pos> walls_to_build;\n        vector<int> wall_dir(M, -1);\n        \n        for (int i = 0; i < M; i++) {\n            int x = humans[i].x, y = humans[i].y;\n            \n            int best_d = -1;\n            int best_priority = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = x + dirs[d].first;\n                int ny = y + dirs[d].second;\n                \n                if (can_build_wall(nx, ny, human_set) && !walls_to_build.count({nx, ny})) {\n                    int priority = get_wall_priority(nx, ny, walls_to_build, turn);\n                    \n                    if (priority > best_priority) {\n                        best_priority = priority;\n                        best_d = d;\n                    }\n                }\n            }\n            \n            if (best_d >= 0) {\n                wall_dir[i] = best_d;\n                int nx = x + dirs[best_d].first;\n                int ny = y + dirs[best_d].second;\n                walls_to_build.insert({nx, ny});\n            }\n        }\n        \n        // PHASE 2: Movement for non-builders\n        for (int i = 0; i < M; i++) {\n            if (wall_dir[i] >= 0) {\n                actions[i] = wall_chars[wall_dir[i]];\n                continue;\n            }\n            \n            // Move toward safe zone (first 40 turns)\n            if (turn < 40) {\n                int x = humans[i].x, y = humans[i].y;\n                \n                int best_d = -1;\n                int curr_dist = manhattan({x, y}, {best_cx, best_cy});\n                \n                for (int d = 0; d < 4; d++) {\n                    int nx = x + dirs[d].first;\n                    int ny = y + dirs[d].second;\n                    \n                    if (!in_bounds(nx, ny)) continue;\n                    if (!grid[nx][ny]) continue;\n                    if (walls_to_build.count({nx, ny})) continue;\n                    \n                    int new_dist = manhattan({nx, ny}, {best_cx, best_cy});\n                    \n                    if (new_dist < curr_dist) {\n                        best_d = d;\n                        break;\n                    }\n                }\n                \n                if (best_d >= 0) {\n                    actions[i] = move_chars[best_d];\n                }\n            }\n        }\n        \n        // Apply walls\n        for (const auto& w : walls_to_build) {\n            grid[w.x][w.y] = false;\n        }\n        \n        // Apply movements\n        for (int i = 0; i < M; i++) {\n            char a = actions[i];\n            if (a == 'U') humans[i].x--;\n            else if (a == 'D') humans[i].x++;\n            else if (a == 'L') humans[i].y--;\n            else if (a == 'R') humans[i].y++;\n        }\n        \n        cout << actions << endl;\n        cout.flush();\n        \n        // Read pets\n        pet_set.clear();\n        for (int i = 0; i < N; i++) {\n            string mov;\n            cin >> mov;\n            for (char c : mov) {\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n            pet_set.insert(pets[i]);\n        }\n    }\n    \n    return 0;\n}","ahc009":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    if (si == ti && sj == tj) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    // BFS to find shortest path\n    queue<tuple<int,int,string>> q;\n    vector<vector<bool>> visited(20, vector<bool>(20, false));\n    q.push({si, sj, \"\"});\n    visited[si][sj] = true;\n    \n    string path = \"\";\n    while (!q.empty()) {\n        auto [i, j, cur_path] = q.front();\n        q.pop();\n        \n        if (i == ti && j == tj) {\n            path = cur_path;\n            break;\n        }\n        \n        vector<tuple<int,int,char>> moves;\n        \n        if (i < 19 && v[i][j] == '0' && !visited[i+1][j]) {\n            moves.push_back({i+1, j, 'D'});\n        }\n        if (j < 19 && h[i][j] == '0' && !visited[i][j+1]) {\n            moves.push_back({i, j+1, 'R'});\n        }\n        if (i > 0 && v[i-1][j] == '0' && !visited[i-1][j]) {\n            moves.push_back({i-1, j, 'U'});\n        }\n        if (j > 0 && h[i][j-1] == '0' && !visited[i][j-1]) {\n            moves.push_back({i, j-1, 'L'});\n        }\n        \n        sort(moves.begin(), moves.end(), [&](auto& a, auto& b) {\n            int dist_a = abs(get<0>(a) - ti) + abs(get<1>(a) - tj);\n            int dist_b = abs(get<0>(b) - ti) + abs(get<1>(b) - tj);\n            if (dist_a != dist_b) return dist_a < dist_b;\n            return get<2>(a) < get<2>(b);\n        });\n        \n        for (auto [ni, nj, dir] : moves) {\n            visited[ni][nj] = true;\n            q.push({ni, nj, cur_path + dir});\n        }\n    }\n    \n    if (path.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    // Count primary moves in the path\n    int cnt_d = 0, cnt_r = 0, cnt_u = 0, cnt_l = 0;\n    for (char c : path) {\n        if (c == 'D') cnt_d++;\n        else if (c == 'R') cnt_r++;\n        else if (c == 'U') cnt_u++;\n        else if (c == 'L') cnt_l++;\n    }\n    \n    // Strategy: Fill most of the budget with path repetitions,\n    // then add corrective moves weighted towards the goal\n    string result = \"\";\n    int path_len = path.length();\n    \n    // Use ~180 chars for path repetitions\n    while (result.length() + path_len <= 180) {\n        result += path;\n    }\n    \n    // Use remaining ~20 chars for corrective moves\n    // Add extra moves in the dominant directions to help recover from errors\n    int remaining = 200 - result.length();\n    string correction = \"\";\n    \n    // Build correction string with bias toward primary directions\n    for (int i = 0; i < remaining && correction.length() < remaining; i++) {\n        // Cycle through moves with emphasis on the main directions\n        if (cnt_d > 0 && correction.length() < remaining) {\n            correction += 'D';\n        }\n        if (cnt_r > 0 && correction.length() < remaining) {\n            correction += 'R';\n        }\n        if (cnt_u > 0 && correction.length() < remaining) {\n            correction += 'U';\n        }\n        if (cnt_l > 0 && correction.length() < remaining) {\n            correction += 'L';\n        }\n    }\n    \n    result += correction;\n    \n    // Trim to exactly 200 if we went over\n    if (result.length() > 200) {\n        result = result.substr(0, 200);\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nint di[4] = {0, -1, 0, 1};\nint dj[4] = {-1, 0, 1, 0};\n\nint to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1},\n};\n\nint rotateTile(int tile, int rot) {\n    rot = rot % 4;\n    for (int i = 0; i < rot; i++) {\n        if (tile <= 3) tile = (tile + 1) % 4;\n        else if (tile <= 5) tile = (tile == 4) ? 5 : 4;\n        else tile = (tile == 6) ? 7 : 6;\n    }\n    return tile;\n}\n\nint getLoopLength(int si, int sj, int sd, const vector<vector<int>>& current) {\n    int i = si, j = sj, d = sd, length = 0;\n    while (length <= 2000) {\n        int tile = current[i][j];\n        int d2 = to[tile][d];\n        if (d2 == -1) return 0;\n        i += di[d2]; j += dj[d2];\n        if (i < 0 || i >= N || j < 0 || j >= N) return 0;\n        d = (d2 + 2) % 4;\n        length++;\n        if (i == si && j == sj && d == sd) return length;\n    }\n    return 0;\n}\n\nlong long calculateScore(const vector<vector<int>>& current) {\n    vector<int> loops;\n    vector<vector<vector<bool>>> visited(N, vector<vector<bool>>(N, vector<bool>(4, false)));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (visited[i][j][d]) continue;\n                int len = getLoopLength(i, j, d, current);\n                if (len > 0) {\n                    loops.push_back(len);\n                    int ii = i, jj = j, dd = d;\n                    for (int step = 0; step < len; step++) {\n                        visited[ii][jj][dd] = true;\n                        int tile = current[ii][jj];\n                        int d2 = to[tile][dd];\n                        ii += di[d2]; jj += dj[d2];\n                        dd = (d2 + 2) % 4;\n                    }\n                }\n            }\n        }\n    }\n    sort(loops.rbegin(), loops.rend());\n    if (loops.size() < 2) return 0;\n    return (long long)loops[0] * loops[1];\n}\n\nint main() {\n    auto start = chrono::steady_clock::now();\n    vector<string> tiles(N);\n    for (int i = 0; i < N; i++) cin >> tiles[i];\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n    \n    vector<vector<int>> bestRotation(N, vector<int>(N));\n    long long bestScore = 0;\n    \n    // Phase 1: SA with 4 diverse initializations - EXACT 7560 parameters\n    for (int trial = 0; trial < 4; trial++) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 1.38) break;\n        \n        vector<vector<int>> rotation(N, vector<int>(N));\n        vector<vector<int>> current(N, vector<int>(N));\n        \n        // Same 4 initialization patterns as 7560\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (trial == 0) rotation[i][j] = gen() % 4;\n                else if (trial == 1) rotation[i][j] = 0;\n                else if (trial == 2) rotation[i][j] = (i + j) % 4;\n                else rotation[i][j] = ((i/5) + (j/5)) % 4;\n                current[i][j] = rotateTile(tiles[i][j] - '0', rotation[i][j]);\n            }\n        }\n        \n        long long currentScore = calculateScore(current);\n        if (currentScore > bestScore) {\n            bestScore = currentScore;\n            bestRotation = rotation;\n        }\n        \n        double temp = 80.0;  // Exact from 7560\n        int iterations = 0;\n        int noImprovementCount = 0;\n        long long trialBestScore = currentScore;\n        \n        while (true) {\n            iterations++;\n            if (iterations % 1000 == 0) {  // Exact from 7560\n                now = chrono::steady_clock::now();\n                elapsed = chrono::duration<double>(now - start).count();\n                if (elapsed > 1.38) break;\n                double progress = elapsed / 1.38;\n                temp = 80.0 * pow(0.001, progress);  // Exact from 7560\n                \n                // NEW: Restart mechanism if stuck\n                if (noImprovementCount > 5000 && currentScore < trialBestScore * 0.5) {\n                    for (int i = 0; i < N; i++) {\n                        for (int j = 0; j < N; j++) {\n                            rotation[i][j] = gen() % 4;\n                            current[i][j] = rotateTile(tiles[i][j] - '0', rotation[i][j]);\n                        }\n                    }\n                    currentScore = calculateScore(current);\n                    noImprovementCount = 0;\n                }\n            }\n            \n            // Same move strategy as 7560: mostly single, 10% adjacent\n            vector<tuple<int,int,int>> changes;\n            int i = gen() % N, j = gen() % N;\n            int oldRot = rotation[i][j];\n            int newRot = gen() % 4;\n            \n            if (oldRot != newRot) {\n                changes.push_back({i, j, oldRot});\n                rotation[i][j] = newRot;\n                current[i][j] = rotateTile(tiles[i][j] - '0', newRot);\n            }\n            \n            // 10% chance for adjacent - exact from 7560\n            if (dis(gen) < 0.1) {\n                int dir = gen() % 4;\n                int ni = i + di[dir], nj = j + dj[dir];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    int oldRot2 = rotation[ni][nj];\n                    int newRot2 = gen() % 4;\n                    if (oldRot2 != newRot2) {\n                        changes.push_back({ni, nj, oldRot2});\n                        rotation[ni][nj] = newRot2;\n                        current[ni][nj] = rotateTile(tiles[ni][nj] - '0', newRot2);\n                    }\n                }\n            }\n            \n            if (changes.empty()) continue;\n            \n            long long score = calculateScore(current);\n            \n            if (score > currentScore || dis(gen) < exp((score - currentScore) / temp)) {\n                currentScore = score;\n                if (score > trialBestScore) {\n                    trialBestScore = score;\n                    noImprovementCount = 0;\n                }\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestRotation = rotation;\n                }\n            } else {\n                for (auto [i, j, oldRot] : changes) {\n                    rotation[i][j] = oldRot;\n                    current[i][j] = rotateTile(tiles[i][j] - '0', oldRot);\n                }\n                noImprovementCount++;\n            }\n        }\n    }\n    \n    // Phase 2: Extended greedy optimization\n    auto now = chrono::steady_clock::now();\n    double elapsed = chrono::duration<double>(now - start).count();\n    \n    if (elapsed < 1.94) {\n        vector<vector<int>> current(N, vector<int>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                current[i][j] = rotateTile(tiles[i][j] - '0', bestRotation[i][j]);\n            }\n        }\n        \n        // Extended: 8 passes instead of 6\n        bool improved = true;\n        int passes = 0;\n        while (improved && passes < 8) {\n            improved = false;\n            passes++;\n            \n            vector<pair<int,int>> positions;\n            for (int i = 0; i < N; i++)\n                for (int j = 0; j < N; j++)\n                    positions.push_back({i, j});\n            shuffle(positions.begin(), positions.end(), gen);\n            \n            for (auto [i, j] : positions) {\n                now = chrono::steady_clock::now();\n                if (chrono::duration<double>(now - start).count() > 1.975) break;\n                \n                int oldRot = bestRotation[i][j];\n                long long bestLocalScore = bestScore;\n                int bestLocalRot = oldRot;\n                \n                for (int r = 0; r < 4; r++) {\n                    current[i][j] = rotateTile(tiles[i][j] - '0', r);\n                    long long score = calculateScore(current);\n                    if (score > bestLocalScore) {\n                        bestLocalScore = score;\n                        bestLocalRot = r;\n                    }\n                }\n                \n                if (bestLocalRot != oldRot) {\n                    bestRotation[i][j] = bestLocalRot;\n                    current[i][j] = rotateTile(tiles[i][j] - '0', bestLocalRot);\n                    bestScore = bestLocalScore;\n                    improved = true;\n                } else {\n                    current[i][j] = rotateTile(tiles[i][j] - '0', oldRot);\n                }\n            }\n            \n            now = chrono::steady_clock::now();\n            if (chrono::duration<double>(now - start).count() > 1.94) break;\n        }\n    }\n    \n    string output;\n    for (int i = 0; i < N; i++)\n        for (int j = 0; j < N; j++)\n            output += ('0' + bestRotation[i][j]);\n    cout << output << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<string> board;\nint empty_i, empty_j;\nchrono::steady_clock::time_point start_time;\n\ndouble elapsed_ms() {\n    return chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count();\n}\n\nvoid find_empty() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == '0') {\n                empty_i = i;\n                empty_j = j;\n                return;\n            }\n        }\n    }\n}\n\nint get_tile(int i, int j) {\n    if (i < 0 || i >= N || j < 0 || j >= N) return -1;\n    char c = board[i][j];\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\ntuple<int, int, int, int> evaluate_board() {\n    vector<int> parent(N * N);\n    iota(parent.begin(), parent.end(), 0);\n    \n    function<int(int)> find = [&](int x) {\n        return parent[x] == x ? x : parent[x] = find(parent[x]);\n    };\n    \n    int potential = 0;\n    int mismatches = 0;\n    \n    for (int i = 0; i < N - 1; i++) {\n        for (int j = 0; j < N; j++) {\n            int t1 = get_tile(i, j);\n            int t2 = get_tile(i + 1, j);\n            if (t1 > 0 && t2 > 0) {\n                bool t1_down = (t1 & 8);\n                bool t2_up = (t2 & 2);\n                if (t1_down && t2_up) {\n                    int p1 = find(i * N + j), p2 = find((i + 1) * N + j);\n                    if (p1 != p2) parent[p1] = p2;\n                } else if (t1_down != t2_up) {\n                    if (t1_down || t2_up) potential++;\n                    else mismatches++;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N - 1; j++) {\n            int t1 = get_tile(i, j);\n            int t2 = get_tile(i, j + 1);\n            if (t1 > 0 && t2 > 0) {\n                bool t1_right = (t1 & 4);\n                bool t2_left = (t2 & 1);\n                if (t1_right && t2_left) {\n                    int p1 = find(i * N + j), p2 = find(i * N + j + 1);\n                    if (p1 != p2) parent[p1] = p2;\n                } else if (t1_right != t2_left) {\n                    if (t1_right || t2_left) potential++;\n                    else mismatches++;\n                }\n            }\n        }\n    }\n    \n    set<int> roots;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (get_tile(i, j) > 0) {\n                roots.insert(find(i * N + j));\n            }\n        }\n    }\n    int num_components = roots.size();\n    \n    map<int, vector<int>> components;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (get_tile(i, j) > 0) {\n                components[find(i * N + j)].push_back(i * N + j);\n            }\n        }\n    }\n    \n    int max_tree_size = 0;\n    for (auto& [root, nodes] : components) {\n        int edges = 0;\n        for (int node : nodes) {\n            int i = node / N, j = node % N;\n            int t = get_tile(i, j);\n            if (i + 1 < N && get_tile(i+1, j) > 0 && (t & 8) && (get_tile(i+1, j) & 2) && find((i+1)*N+j) == root) edges++;\n            if (j + 1 < N && get_tile(i, j+1) > 0 && (t & 4) && (get_tile(i, j+1) & 1) && find(i*N+j+1) == root) edges++;\n        }\n        if (edges == (int)nodes.size() - 1) {\n            max_tree_size = max(max_tree_size, (int)nodes.size());\n        }\n    }\n    \n    return {max_tree_size, -num_components, potential, -mismatches};\n}\n\nbool can_move(char dir) {\n    if (dir == 'U') return empty_i > 0;\n    if (dir == 'D') return empty_i < N - 1;\n    if (dir == 'L') return empty_j > 0;\n    if (dir == 'R') return empty_j < N - 1;\n    return false;\n}\n\nvoid make_move(char dir) {\n    int ni = empty_i, nj = empty_j;\n    if (dir == 'U') ni--;\n    else if (dir == 'D') ni++;\n    else if (dir == 'L') nj--;\n    else if (dir == 'R') nj++;\n    swap(board[empty_i][empty_j], board[ni][nj]);\n    empty_i = ni;\n    empty_j = nj;\n}\n\nchar opposite(char dir) {\n    if (dir == 'U') return 'D';\n    if (dir == 'D') return 'U';\n    if (dir == 'L') return 'R';\n    return 'L';\n}\n\nint main() {\n    start_time = chrono::steady_clock::now();\n    \n    cin >> N >> T;\n    board.resize(N);\n    for (int i = 0; i < N; i++) cin >> board[i];\n    \n    find_empty();\n    \n    mt19937 rng(42);\n    string moves = \"\";\n    char last = ' ';\n    int stagnant = 0;\n    int best_ever = 0;\n    \n    while ((int)moves.length() < T && elapsed_ms() < 2900) {\n        auto [current_score, current_comp, current_potential, current_mismatch] = evaluate_board();\n        if (current_score == N * N - 1) break;\n        \n        if (current_score > best_ever) {\n            best_ever = current_score;\n            stagnant = 0;\n        } else {\n            stagnant++;\n        }\n        \n        vector<char> valid;\n        for (char d : {'U','D','L','R'}) {\n            if (last != ' ' && d == opposite(last)) continue;\n            if (can_move(d)) valid.push_back(d);\n        }\n        if (valid.empty()) break;\n        \n        double progress = (double)moves.length() / T;\n        double rand_prob = 0.08;\n        \n        if (progress < 0.12) {\n            rand_prob = 0.28;  // Moderate early exploration\n        } else if (progress < 0.35) {\n            rand_prob = 0.12;\n        } else if (progress < 0.65) {\n            rand_prob = 0.08;\n        } else {\n            rand_prob = 0.05;  // Very conservative late\n        }\n        \n        if (stagnant > 350) rand_prob = max(rand_prob, 0.65);\n        else if (stagnant > 250) rand_prob = max(rand_prob, 0.48);\n        else if (stagnant > 150) rand_prob = max(rand_prob, 0.32);\n        else if (stagnant > 80) rand_prob = max(rand_prob, 0.18);\n        \n        vector<tuple<int, int, int, int, char>> opts;\n        \n        for (char d : valid) {\n            auto ob = board; int oi = empty_i, oj = empty_j;\n            make_move(d);\n            auto [s, c, p, m] = evaluate_board();\n            opts.push_back({s, c, p, m, d});\n            board = ob; empty_i = oi; empty_j = oj;\n        }\n        \n        sort(opts.rbegin(), opts.rend());\n        \n        char sel;\n        auto [best_s, best_c, best_p, best_m, best_ch] = opts[0];\n        \n        if (best_s > current_score || \n           (best_s == current_score && best_c > current_comp) ||\n           (best_s == current_score && best_c == current_comp && best_p > current_potential) ||\n           (best_s == current_score && best_c == current_comp && best_p == current_potential && best_m > current_mismatch)) {\n            sel = best_ch;\n        } else if (rng() % 10000 < rand_prob * 10000) {\n            if (rng() % 100 < 60 && opts.size() > 1) {\n                sel = get<4>(opts[1]);\n            } else {\n                sel = valid[rng() % valid.size()];\n            }\n        } else {\n            sel = best_ch;\n        }\n        \n        make_move(sel);\n        moves += sel;\n        last = sel;\n        \n        if (stagnant > 280 && stagnant % 140 == 0 && (int)moves.length() < T - 15) {\n            int shake_len = min(8, T - (int)moves.length());\n            for (int shake = 0; shake < shake_len; shake++) {\n                vector<char> v;\n                for (char d : {'U','D','L','R'}) {\n                    if (d != opposite(last) && can_move(d)) v.push_back(d);\n                }\n                if (!v.empty()) {\n                    char r = v[rng() % v.size()];\n                    make_move(r);\n                    moves += r;\n                    last = r;\n                }\n            }\n            stagnant = 0;\n        }\n    }\n    \n    cout << moves << endl;\n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, K;\n    cin >> N >> K;\n    \n    vector<int> a(11);\n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    \n    vector<pair<int, int>> points(N);\n    for (int i = 0; i < N; i++) {\n        cin >> points[i].first >> points[i].second;\n    }\n    \n    // Sort by angle\n    sort(points.begin(), points.end(), [](const auto& p1, const auto& p2) {\n        return atan2(p1.second, p1.first) < atan2(p2.second, p2.first);\n    });\n    \n    // Greedy with 2-step lookahead\n    auto solve_lookahead = [&]() {\n        vector<int> remaining = a;\n        vector<int> partition;\n        int pos = 0;\n        \n        while (pos < N) {\n            int best_size = 1;\n            int best_future_score = -1000;\n            \n            // Try each possible first size\n            for (int size1 = 1; size1 <= min(10, N - pos); size1++) {\n                int score1 = (size1 <= 10 && remaining[size1] > 0) ? 1 : 0;\n                \n                // Look ahead to second piece\n                int future_score = score1;\n                if (pos + size1 < N) {\n                    auto temp_remaining = remaining;\n                    if (size1 <= 10 && temp_remaining[size1] > 0) {\n                        temp_remaining[size1]--;\n                    }\n                    \n                    // Try best second size\n                    int best_size2_score = 0;\n                    for (int size2 = 1; size2 <= min(10, N - pos - size1); size2++) {\n                        if (size2 <= 10 && temp_remaining[size2] > 0) {\n                            best_size2_score = 1;\n                            break;\n                        }\n                    }\n                    future_score += best_size2_score;\n                }\n                \n                // Tie-break: prefer sizes with more remaining demand\n                int tiebreak = (size1 <= 10) ? remaining[size1] : 0;\n                int total_score = future_score * 1000 + tiebreak;\n                \n                if (total_score > best_future_score) {\n                    best_future_score = total_score;\n                    best_size = size1;\n                }\n            }\n            \n            partition.push_back(best_size);\n            if (best_size <= 10 && remaining[best_size] > 0) {\n                remaining[best_size]--;\n            }\n            pos += best_size;\n        }\n        \n        // Calculate final score\n        int score = 0;\n        auto temp = a;\n        for (int sz : partition) {\n            if (sz <= 10 && temp[sz] > 0) {\n                temp[sz]--;\n                score++;\n            }\n        }\n        \n        return make_pair(score, partition);\n    };\n    \n    // Original greedy\n    auto solve_greedy = [&]() {\n        vector<pair<int, int>> priority;\n        for (int d = 1; d <= 10; d++) {\n            if (a[d] > 0) priority.push_back({a[d], d});\n        }\n        sort(priority.rbegin(), priority.rend());\n        \n        vector<int> remaining = a;\n        vector<int> partition;\n        int pos = 0, score = 0;\n        \n        while (pos < N) {\n            int chosen = -1;\n            for (auto [cnt, size] : priority) {\n                if (remaining[size] > 0 && pos + size <= N) {\n                    chosen = size;\n                    break;\n                }\n            }\n            if (chosen == -1) {\n                for (int sz = 1; sz <= min(10, N-pos); sz++) {\n                    if (remaining[sz] > 0) { chosen = sz; break; }\n                }\n            }\n            if (chosen == -1) chosen = min(10, N-pos);\n            \n            partition.push_back(chosen);\n            if (chosen <= 10 && remaining[chosen] > 0) {\n                remaining[chosen]--;\n                score++;\n            }\n            pos += chosen;\n        }\n        return make_pair(score, partition);\n    };\n    \n    int best_score = -1;\n    vector<int> best_partition;\n    vector<pair<int,int>> best_points;\n    \n    // Try multiple rotations with both strategies\n    int num_tries = min(N, 40);\n    for (int offset = 0; offset < num_tries; offset++) {\n        vector<pair<int, int>> rotated(N);\n        for (int i = 0; i < N; i++) {\n            rotated[i] = points[(i + offset) % N];\n        }\n        \n        // Try lookahead greedy\n        auto [score1, partition1] = solve_lookahead();\n        if (score1 > best_score) {\n            best_score = score1;\n            best_partition = partition1;\n            best_points = rotated;\n        }\n        \n        // Try original greedy\n        auto [score2, partition2] = solve_greedy();\n        if (score2 > best_score) {\n            best_score = score2;\n            best_partition = partition2;\n            best_points = rotated;\n        }\n    }\n    \n    // Generate cuts\n    vector<array<long long, 4>> cuts;\n    int cumulative = 0;\n    \n    for (int size : best_partition) {\n        cumulative += size;\n        \n        if (cumulative < N && (int)cuts.size() < K) {\n            auto [x1, y1] = best_points[cumulative - 1];\n            auto [x2, y2] = best_points[cumulative];\n            \n            double a1 = atan2(y1, x1);\n            double a2 = atan2(y2, x2);\n            double mid = (a1 + a2) / 2.0;\n            \n            if (a2 - a1 < -M_PI) {\n                mid += M_PI;\n            } else if (a2 - a1 > M_PI) {\n                mid -= M_PI;\n            }\n            \n            long long qx = llround(1e9 * cos(mid));\n            long long qy = llround(1e9 * sin(mid));\n            \n            cuts.push_back({0, 0, qx, qy});\n        }\n    }\n    \n    cout << cuts.size() << '\\n';\n    for (auto [px, py, qx, qy] : cuts) {\n        cout << px << ' ' << py << ' ' << qx << ' ' << qy << '\\n';\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <chrono>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint N, M;\nset<pair<int,int>> dots;\nvector<vector<int>> operations;\nset<pair<pair<int,int>, pair<int,int>>> usedUnitSegments;\nmt19937 rng(271828);\n\ndouble getWeight(int x, int y) {\n    double c = (N - 1) / 2.0;\n    return (x - c) * (x - c) + (y - c) * (y - c) + 1;\n}\n\ndouble getDist(int x1, int y1, int x2, int y2) {\n    return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));\n}\n\nbool hasIntermediateDots(int x1, int y1, int x2, int y2) {\n    int dx = x2 - x1;\n    int dy = y2 - y1;\n    int g = __gcd(abs(dx), abs(dy));\n    if (g <= 1) return false;\n    \n    dx /= g;\n    dy /= g;\n    \n    for (int i = 1; i < g; i++) {\n        if (dots.count({x1 + dx * i, y1 + dy * i})) return true;\n    }\n    return false;\n}\n\nvector<pair<pair<int,int>, pair<int,int>>> getUnitSegments(int x1, int y1, int x2, int y2) {\n    vector<pair<pair<int,int>, pair<int,int>>> segments;\n    int dx = x2 - x1, dy = y2 - y1;\n    int g = __gcd(abs(dx), abs(dy));\n    if (g == 0) return segments;\n    \n    dx /= g;\n    dy /= g;\n    \n    for (int i = 0; i < g; i++) {\n        auto p1 = make_pair(x1 + dx * i, y1 + dy * i);\n        auto p2 = make_pair(x1 + dx * (i + 1), y1 + dy * (i + 1));\n        if (p1 > p2) swap(p1, p2);\n        segments.push_back({p1, p2});\n    }\n    return segments;\n}\n\nbool isValidRectangleOrder(const vector<int>& pts) {\n    int vx1 = pts[2] - pts[0], vy1 = pts[3] - pts[1];\n    int vx2 = pts[4] - pts[2], vy2 = pts[5] - pts[3];\n    int vx3 = pts[6] - pts[4], vy3 = pts[7] - pts[5];\n    int vx4 = pts[0] - pts[6], vy4 = pts[1] - pts[7];\n    \n    if (vx1 != -vx3 || vy1 != -vy3) return false;\n    if (vx2 != -vx4 || vy2 != -vy4) return false;\n    if (vx1 * vx2 + vy1 * vy2 != 0) return false;\n    \n    bool axisAligned = (vx1 == 0 || vy1 == 0) && (vx2 == 0 || vy2 == 0);\n    bool rotated45 = (abs(vx1) == abs(vy1)) && (abs(vx2) == abs(vy2)) && vx1 != 0 && vx2 != 0;\n    \n    return axisAligned || rotated45;\n}\n\nint getRectArea(const vector<int>& pts) {\n    int vx1 = pts[2] - pts[0], vy1 = pts[3] - pts[1];\n    int vx2 = pts[4] - pts[2], vy2 = pts[5] - pts[3];\n    return abs(vx1 * vy2 - vx2 * vy1);\n}\n\nint getRectPerimeter(const vector<int>& pts) {\n    int perim = 0;\n    for (int e = 0; e < 4; e++) {\n        int dx = pts[(e*2+2)%8] - pts[e*2];\n        int dy = pts[(e*2+3)%8] - pts[e*2+1];\n        int g = __gcd(abs(dx), abs(dy));\n        perim += g;\n    }\n    return perim;\n}\n\nbool tryAddDot(int x1, int y1, int maxDots) {\n    if (dots.count({x1, y1}) || x1 < 0 || x1 >= N || y1 < 0 || y1 >= N) {\n        return false;\n    }\n    \n    vector<pair<int,int>> dotVec(dots.begin(), dots.end());\n    \n    // Sort dots by distance to target position (prefer nearby dots)\n    vector<pair<double, pair<int,int>>> sortedDots;\n    for (auto& d : dotVec) {\n        double dist = getDist(x1, y1, d.first, d.second);\n        sortedDots.push_back({dist, d});\n    }\n    sort(sortedDots.begin(), sortedDots.end());\n    \n    int n = min(maxDots, (int)sortedDots.size());\n    dotVec.clear();\n    for (int i = 0; i < n; i++) {\n        dotVec.push_back(sortedDots[i].second);\n    }\n    \n    // Add some random dots for diversity\n    if (n < (int)sortedDots.size()) {\n        int extra = min(20, (int)sortedDots.size() - n);\n        for (int i = 0; i < extra; i++) {\n            int idx = n + (rng() % (sortedDots.size() - n));\n            dotVec.push_back(sortedDots[idx].second);\n        }\n    }\n    n = dotVec.size();\n    \n    // Store candidates with (area, perimeter, -weight) for sorting\n    vector<pair<pair<int, pair<int, double>>, vector<int>>> candidates;\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = i + 1; j < n; j++) {\n            for (int k = j + 1; k < n; k++) {\n                int x2 = dotVec[i].first, y2 = dotVec[i].second;\n                int x3 = dotVec[j].first, y3 = dotVec[j].second;\n                int x4 = dotVec[k].first, y4 = dotVec[k].second;\n                \n                vector<vector<int>> perms = {\n                    {x1, y1, x2, y2, x3, y3, x4, y4},\n                    {x1, y1, x2, y2, x4, y4, x3, y3},\n                    {x1, y1, x3, y3, x2, y2, x4, y4},\n                    {x1, y1, x3, y3, x4, y4, x2, y2},\n                    {x1, y1, x4, y4, x2, y2, x3, y3},\n                    {x1, y1, x4, y4, x3, y3, x2, y2}\n                };\n                \n                for (auto& perm : perms) {\n                    if (!isValidRectangleOrder(perm)) continue;\n                    \n                    bool valid = true;\n                    vector<pair<pair<int,int>, pair<int,int>>> allSegments;\n                    \n                    for (int e = 0; e < 4; e++) {\n                        int ex1 = perm[e*2], ey1 = perm[e*2+1];\n                        int ex2 = perm[(e*2+2)%8], ey2 = perm[(e*2+3)%8];\n                        \n                        if (hasIntermediateDots(ex1, ey1, ex2, ey2)) {\n                            valid = false;\n                            break;\n                        }\n                        \n                        auto segments = getUnitSegments(ex1, ey1, ex2, ey2);\n                        for (auto& seg : segments) {\n                            if (usedUnitSegments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                            allSegments.push_back(seg);\n                        }\n                        if (!valid) break;\n                    }\n                    \n                    if (valid) {\n                        int area = getRectArea(perm);\n                        int perim = getRectPerimeter(perm);\n                        double weight = getWeight(x1, y1);\n                        // Prioritize: small area, short perimeter, high weight (low distance)\n                        candidates.push_back({{area, {perim, -weight}}, perm});\n                        \n                        // Early exit if we found a very small rectangle\n                        if (area <= 4 && candidates.size() >= 1) {\n                            goto found_good;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    found_good:\n    if (candidates.empty()) return false;\n    \n    sort(candidates.begin(), candidates.end());\n    vector<int> perm = candidates[0].second;\n    \n    vector<pair<pair<int,int>, pair<int,int>>> allSegments;\n    for (int e = 0; e < 4; e++) {\n        int ex1 = perm[e*2], ey1 = perm[e*2+1];\n        int ex2 = perm[(e*2+2)%8], ey2 = perm[(e*2+3)%8];\n        auto segments = getUnitSegments(ex1, ey1, ex2, ey2);\n        for (auto& seg : segments) allSegments.push_back(seg);\n    }\n    \n    dots.insert({x1, y1});\n    operations.push_back(perm);\n    for (auto& seg : allSegments) usedUnitSegments.insert(seg);\n    \n    return true;\n}\n\nint main() {\n    cin >> N >> M;\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        dots.insert({x, y});\n    }\n    \n    auto start = chrono::steady_clock::now();\n    double c = (N - 1) / 2.0;\n    \n    for (int pass = 0; pass < 50; pass++) {\n        auto now = chrono::steady_clock::now();\n        double elapsed = chrono::duration<double>(now - start).count();\n        if (elapsed > 4.75) break;\n        \n        vector<pair<double, pair<int,int>>> candidates;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (!dots.count({x, y})) {\n                    double dist = (x - c) * (x - c) + (y - c) * (y - c);\n                    // Gradual increase in randomization\n                    double noise = (rng() % 1000) * 0.0003 * (1 + pass * 0.05);\n                    candidates.push_back({dist + noise, {x, y}});\n                }\n            }\n        }\n        \n        sort(candidates.begin(), candidates.end());\n        \n        bool added = false;\n        int addedCount = 0;\n        // Check more positions in early passes\n        int checkLimit = min((int)candidates.size(), max(150, 350 - pass * 4));\n        \n        for (int i = 0; i < checkLimit; i++) {\n            now = chrono::steady_clock::now();\n            elapsed = chrono::duration<double>(now - start).count();\n            if (elapsed > 4.75) goto done;\n            \n            // Gradually increase search depth\n            int searchDepth = 80 + min(120, pass * 3);\n            if (tryAddDot(candidates[i].second.first, candidates[i].second.second, searchDepth)) {\n                added = true;\n                addedCount++;\n            }\n        }\n        \n        // Early stopping if making very little progress\n        if (addedCount < 3 && pass > 10) break;\n        if (!added) break;\n    }\n    \n    done:\n    cout << operations.size() << endl;\n    for (auto& op : operations) {\n        for (int i = 0; i < 8; i++) {\n            if (i > 0) cout << \" \";\n            cout << op[i];\n        }\n        cout << endl;\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nint board[N][N];\nint flavors[100];\n\nvoid tilt(int b[N][N], char dir) {\n    if (dir == 'F') {\n        for (int j = 0; j < N; j++) {\n            int pos = 0;\n            for (int i = 0; i < N; i++) {\n                if (b[i][j] > 0) {\n                    if (i != pos) {\n                        b[pos][j] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos++;\n                }\n            }\n        }\n    } else if (dir == 'B') {\n        for (int j = 0; j < N; j++) {\n            int pos = N - 1;\n            for (int i = N - 1; i >= 0; i--) {\n                if (b[i][j] > 0) {\n                    if (i != pos) {\n                        b[pos][j] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos--;\n                }\n            }\n        }\n    } else if (dir == 'L') {\n        for (int i = 0; i < N; i++) {\n            int pos = 0;\n            for (int j = 0; j < N; j++) {\n                if (b[i][j] > 0) {\n                    if (j != pos) {\n                        b[i][pos] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos++;\n                }\n            }\n        }\n    } else {\n        for (int i = 0; i < N; i++) {\n            int pos = N - 1;\n            for (int j = N - 1; j >= 0; j--) {\n                if (b[i][j] > 0) {\n                    if (j != pos) {\n                        b[i][pos] = b[i][j];\n                        b[i][j] = 0;\n                    }\n                    pos--;\n                }\n            }\n        }\n    }\n}\n\n// Evaluate how friendly the board is for receiving a specific flavor\ndouble evaluateReceptiveness(int b[N][N], int targetFlavor) {\n    double score = 0;\n    \n    // Count empty cells adjacent to same flavor\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] == 0) {\n                int adjacentSameFlavor = 0;\n                int di[] = {-1, 1, 0, 0};\n                int dj[] = {0, 0, -1, 1};\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + di[d];\n                    int nj = j + dj[d];\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N &&\n                        b[ni][nj] == targetFlavor) {\n                        adjacentSameFlavor++;\n                    }\n                }\n                // Empty cells near target flavor are valuable\n                score += adjacentSameFlavor * adjacentSameFlavor; // Quadratic bonus\n            }\n        }\n    }\n    \n    return score;\n}\n\ndouble calcEvaluation(int b[N][N], int turn) {\n    bool vis[N][N] = {};\n    double score = 0;\n    int numComponents = 0;\n    \n    // Calculate connectivity score (main objective)\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] > 0 && !vis[i][j]) {\n                int flavor = b[i][j];\n                int size = 0;\n                queue<pair<int,int>> q;\n                q.push({i, j});\n                vis[i][j] = true;\n                \n                while (!q.empty()) {\n                    auto [ci, cj] = q.front();\n                    q.pop();\n                    size++;\n                    \n                    int di[] = {-1, 1, 0, 0};\n                    int dj[] = {0, 0, -1, 1};\n                    for (int d = 0; d < 4; d++) {\n                        int ni = ci + di[d];\n                        int nj = cj + dj[d];\n                        if (ni >= 0 && ni < N && nj >= 0 && nj < N &&\n                            !vis[ni][nj] && b[ni][nj] == flavor) {\n                            vis[ni][nj] = true;\n                            q.push({ni, nj});\n                        }\n                    }\n                }\n                \n                score += size * size;\n                numComponents++;\n            }\n        }\n    }\n    \n    // Adjacent same-flavor bonus\n    int adjacentCount = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] > 0) {\n                if (i + 1 < N && b[i+1][j] == b[i][j]) adjacentCount++;\n                if (j + 1 < N && b[i][j+1] == b[i][j]) adjacentCount++;\n            }\n        }\n    }\n    score += adjacentCount * 8.0;\n    \n    // Component penalty\n    score -= numComponents * 2.0;\n    \n    // Future-weighted compactness guidance\n    double progress = (double)turn / 100.0;\n    if (progress < 0.6) {\n        double baseWeight = (0.6 - progress) * 0.08;\n        \n        // Count remaining candies of each flavor\n        int remaining[4] = {};\n        for (int t = turn + 1; t < 100; t++) {\n            remaining[flavors[t]]++;\n        }\n        \n        for (int f = 1; f <= 3; f++) {\n            vector<pair<int,int>> positions;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (b[i][j] == f) {\n                        positions.push_back({i, j});\n                    }\n                }\n            }\n            \n            if (positions.size() > 2) {\n                int minI = N, maxI = 0, minJ = N, maxJ = 0;\n                for (auto [i, j] : positions) {\n                    minI = min(minI, i);\n                    maxI = max(maxI, i);\n                    minJ = min(minJ, j);\n                    maxJ = max(maxJ, j);\n                }\n                \n                int area = (maxI - minI + 1) * (maxJ - minJ + 1);\n                double density = (double)positions.size() / area;\n                \n                double futureWeight = 1.0 + (double)remaining[f] / 20.0;\n                \n                score += density * 50.0 * baseWeight * futureWeight;\n            }\n        }\n    }\n    \n    // Look-ahead: evaluate receptiveness for next candy\n    if (turn < 99 && progress < 0.8) {\n        int nextFlavor = flavors[turn + 1];\n        double receptiveness = evaluateReceptiveness(b, nextFlavor);\n        score += receptiveness * 0.8; // Gentle bonus\n    }\n    \n    return score;\n}\n\nchar chooseBest(int turn) {\n    char dirs[] = {'F', 'B', 'L', 'R'};\n    double best = -1e18;\n    char bestDir = 'F';\n    \n    for (char dir : dirs) {\n        int temp[N][N];\n        memcpy(temp, board, sizeof(board));\n        tilt(temp, dir);\n        double score = calcEvaluation(temp, turn);\n        \n        if (score > best) {\n            best = score;\n            bestDir = dir;\n        }\n    }\n    \n    return bestDir;\n}\n\nint main() {\n    for (int i = 0; i < 100; i++) {\n        cin >> flavors[i];\n    }\n    \n    memset(board, 0, sizeof(board));\n    \n    for (int t = 0; t < 100; t++) {\n        int p;\n        cin >> p;\n        p--;\n        \n        int cnt = 0;\n        bool placed = false;\n        for (int i = 0; i < N && !placed; i++) {\n            for (int j = 0; j < N && !placed; j++) {\n                if (board[i][j] == 0) {\n                    if (cnt == p) {\n                        board[i][j] = flavors[t];\n                        placed = true;\n                    }\n                    cnt++;\n                }\n            }\n        }\n        \n        char dir = chooseBest(t);\n        cout << dir << endl;\n        cout.flush();\n        \n        tilt(board, dir);\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nint M;\ndouble eps;\nint N;\n\nclass Graph {\npublic:\n    int n;\n    vector<vector<int>> adj;\n    \n    Graph(int n = 0) : n(n), adj(n, vector<int>(n, 0)) {}\n    \n    string to_string() const {\n        string s;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                s += (adj[i][j] ? '1' : '0');\n            }\n        }\n        return s;\n    }\n    \n    void from_string(const string& s) {\n        int idx = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                adj[i][j] = adj[j][i] = (s[idx++] == '1');\n            }\n        }\n    }\n    \n    vector<int> get_features() const {\n        vector<int> features;\n        \n        // 1. Edge count - most robust\n        int edges = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                edges += adj[i][j];\n            }\n        }\n        features.push_back(edges);\n        \n        // 2. Degree sequence - DESCENDING for sequential patterns\n        vector<int> degrees(n, 0);\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                degrees[i] += adj[i][j];\n            }\n        }\n        sort(degrees.begin(), degrees.end(), greater<int>());\n        for (int d : degrees) features.push_back(d);\n        \n        // 3. Triangle count\n        int triangles = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                if (!adj[i][j]) continue;\n                for (int k = j + 1; k < n; k++) {\n                    if (adj[i][k] && adj[j][k]) triangles++;\n                }\n            }\n        }\n        features.push_back(triangles);\n        \n        // 4. Square count (4-cycles) - complementary to triangles\n        int squares = 0;\n        if (n <= 30) {  // Only for smaller graphs to avoid TLE\n            for (int i = 0; i < n; i++) {\n                for (int j = i + 1; j < n; j++) {\n                    if (!adj[i][j]) continue;\n                    for (int k = j + 1; k < n; k++) {\n                        if (adj[i][k]) continue;  // Not a triangle\n                        if (!adj[j][k]) continue;\n                        for (int l = k + 1; l < n; l++) {\n                            if (adj[i][l] && adj[k][l] && !adj[j][l]) {\n                                squares++;\n                            }\n                        }\n                    }\n                }\n            }\n            features.push_back(squares);\n        }\n        \n        // 5. 4-cliques (only for very small graphs)\n        if (n <= 20) {\n            int cliques4 = 0;\n            for (int i = 0; i < n; i++) {\n                for (int j = i + 1; j < n; j++) {\n                    if (!adj[i][j]) continue;\n                    for (int k = j + 1; k < n; k++) {\n                        if (!adj[i][k] || !adj[j][k]) continue;\n                        for (int l = k + 1; l < n; l++) {\n                            if (adj[i][l] && adj[j][l] && adj[k][l]) cliques4++;\n                        }\n                    }\n                }\n            }\n            features.push_back(cliques4);\n        }\n        \n        return features;\n    }\n};\n\nvector<Graph> graphs;\nvector<vector<int>> graph_features;\n\nint compute_distance(const vector<int>& f1, const vector<int>& f2) {\n    int dist = 0;\n    \n    // Edge count - dominant weight, scaled by noise\n    double edge_weight = 15.0 / max(0.08, eps);\n    dist += abs(f1[0] - f2[0]) * edge_weight;\n    \n    // Degree sequence - more weight on top degrees\n    for (int i = 1; i <= N && i < (int)min(f1.size(), f2.size()); i++) {\n        double deg_weight = 1.0;\n        if (i <= 3) deg_weight = 2.0;  // Top 3 degrees more important\n        else if (i <= 7) deg_weight = 1.5;\n        dist += abs(f1[i] - f2[i]) * deg_weight;\n    }\n    \n    // Triangle count\n    if ((int)f1.size() > N + 1) {\n        double tri_weight = 7.0 / max(0.1, eps);\n        dist += abs(f1[N + 1] - f2[N + 1]) * tri_weight;\n    }\n    \n    // Square count\n    if (N <= 30 && (int)f1.size() > N + 2 && (int)f2.size() > N + 2) {\n        double sq_weight = 3.0 / max(0.15, eps);\n        dist += abs(f1[N + 2] - f2[N + 2]) * sq_weight;\n    }\n    \n    // 4-clique count\n    int clique_idx = (N <= 30) ? N + 3 : N + 2;\n    if (N <= 20 && (int)f1.size() > clique_idx && (int)f2.size() > clique_idx) {\n        double clique_weight = 5.0 / max(0.12, eps);\n        dist += abs(f1[clique_idx] - f2[clique_idx]) * clique_weight;\n    }\n    \n    return dist;\n}\n\nvoid generate_graphs() {\n    // Proven N values\n    if (eps <= 0.05) {\n        N = 10;\n    } else if (eps <= 0.15) {\n        N = 15;\n    } else if (eps <= 0.25) {\n        N = 20;\n    } else if (eps <= 0.35) {\n        N = 30;\n    } else {\n        N = 40;\n    }\n    \n    // Ensure sufficient capacity\n    N = max(N, (int)ceil(sqrt(2.0 * M)) + 4);\n    N = min(N, 100);\n    \n    graphs.resize(M, Graph(N));\n    int max_edges = N * (N - 1) / 2;\n    \n    // Refined continuous power curve\n    double m_ratio = (M - 10.0) / 90.0;  // 0 to 1 as M: 10\u2192100\n    double e_ratio = min(eps / 0.3, 1.0);  // 0 to 1 as eps: 0\u21920.3\n    \n    // Conservative power: 1.0 to 1.25\n    double power = 1.0 + 0.15 * m_ratio + 0.1 * e_ratio;\n    power = min(power, 1.25);  // Safety cap\n    \n    for (int k = 0; k < M; k++) {\n        double ratio = (double)k / max(1, M - 1);\n        double scaled = pow(ratio, power);\n        int target_edges = (int)(scaled * max_edges);\n        \n        // Sequential edge addition\n        int added = 0;\n        for (int i = 0; i < N && added < target_edges; i++) {\n            for (int j = i + 1; j < N && added < target_edges; j++) {\n                graphs[k].adj[i][j] = graphs[k].adj[j][i] = 1;\n                added++;\n            }\n        }\n    }\n    \n    // Precompute features\n    graph_features.resize(M);\n    for (int k = 0; k < M; k++) {\n        graph_features[k] = graphs[k].get_features();\n    }\n}\n\nint decode_graph(const Graph& h) {\n    auto h_features = h.get_features();\n    \n    int best = 0;\n    int min_dist = INT_MAX;\n    \n    for (int k = 0; k < M; k++) {\n        int dist = compute_distance(h_features, graph_features[k]);\n        if (dist < min_dist) {\n            min_dist = dist;\n            best = k;\n        }\n    }\n    \n    return best;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> M >> eps;\n    \n    generate_graphs();\n    \n    cout << N << \"\\n\";\n    for (const auto& g : graphs) {\n        cout << g.to_string() << \"\\n\";\n    }\n    cout.flush();\n    \n    for (int q = 0; q < 100; q++) {\n        string s;\n        cin >> s;\n        \n        Graph h(N);\n        h.from_string(s);\n        \n        int t = decode_graph(h);\n        cout << t << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, D, K;\nvector<array<int, 3>> edges;\nvector<vector<int>> graph;\nvector<int> degree;\n\nint main() {\n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    graph.resize(N);\n    degree.resize(N);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i][0] >> edges[i][1] >> edges[i][2];\n        edges[i][0]--; edges[i][1]--;\n        \n        graph[edges[i][0]].push_back(i);\n        graph[edges[i][1]].push_back(i);\n        \n        degree[edges[i][0]]++;\n        degree[edges[i][1]]++;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Calculate edge importance\n    vector<pair<double, int>> edge_scores;\n    for (int i = 0; i < M; i++) {\n        int u = edges[i][0];\n        int v = edges[i][1];\n        long long w = edges[i][2];\n        \n        double degree_factor = 1.0 / (degree[u] * degree[v]);\n        double weight_factor = (double)w / 1000000.0;\n        double score = degree_factor * 100.0 + weight_factor;\n        \n        edge_scores.push_back({score, i});\n    }\n    \n    sort(edge_scores.begin(), edge_scores.end(), greater<>());\n    \n    // Greedy assignment with degree-aware penalties\n    vector<int> assignment(M, 0);\n    vector<vector<int>> day_edges(D + 1);\n    vector<map<int, int>> day_vertex_edges(D + 1);\n    \n    for (auto [score, eid] : edge_scores) {\n        int u = edges[eid][0];\n        int v = edges[eid][1];\n        \n        int best_day = 1;\n        double best_cost = 1e18;\n        \n        for (int d = 1; d <= D; d++) {\n            double cost = day_edges[d].size();\n            \n            if (day_vertex_edges[d].count(u)) {\n                double base_penalty = 20.0 / degree[u];\n                cost += base_penalty * (1 + day_vertex_edges[d][u] * 0.5);\n            }\n            if (day_vertex_edges[d].count(v)) {\n                double base_penalty = 20.0 / degree[v];\n                cost += base_penalty * (1 + day_vertex_edges[d][v] * 0.5);\n            }\n            \n            if (cost < best_cost) {\n                best_cost = cost;\n                best_day = d;\n            }\n        }\n        \n        assignment[eid] = best_day;\n        day_edges[best_day].push_back(eid);\n        day_vertex_edges[best_day][u]++;\n        day_vertex_edges[best_day][v]++;\n    }\n    \n    // Light hill-climbing: try swapping edges between days\n    for (int iter = 0; iter < 800; iter++) {\n        int d1 = 1 + (iter % D);\n        int d2 = 1 + ((iter * 7 + 3) % D);\n        if (d1 == d2 || day_edges[d1].empty() || day_edges[d2].empty()) continue;\n        \n        int idx1 = (iter * 13) % day_edges[d1].size();\n        int idx2 = (iter * 17) % day_edges[d2].size();\n        int e1 = day_edges[d1][idx1];\n        int e2 = day_edges[d2][idx2];\n        \n        set<int> v1 = {edges[e1][0], edges[e1][1]};\n        set<int> v2 = {edges[e2][0], edges[e2][1]};\n        \n        int overlap_before = 0, overlap_after = 0;\n        for (int e : day_edges[d1]) {\n            if (e != e1) {\n                if (v1.count(edges[e][0]) || v1.count(edges[e][1])) overlap_before++;\n                if (v2.count(edges[e][0]) || v2.count(edges[e][1])) overlap_after++;\n            }\n        }\n        for (int e : day_edges[d2]) {\n            if (e != e2) {\n                if (v2.count(edges[e][0]) || v2.count(edges[e][1])) overlap_before++;\n                if (v1.count(edges[e][0]) || v1.count(edges[e][1])) overlap_after++;\n            }\n        }\n        \n        if (overlap_after < overlap_before) {\n            swap(assignment[e1], assignment[e2]);\n            day_edges[d1][idx1] = e2;\n            day_edges[d2][idx2] = e1;\n        }\n    }\n    \n    for (int i = 0; i < M; i++) {\n        cout << assignment[i];\n        if (i < M - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f1, r1, f2, r2;\n\nbool isOccupied(int x, int y, int z, const vector<string>& f, const vector<string>& r) {\n    return f[z][x] == '1' && r[z][y] == '1';\n}\n\n// BFS with size limit to create smaller, more uniform blocks\nset<tuple<int,int,int>> getComponentLimited(tuple<int,int,int> start, \n                                             set<tuple<int,int,int>>& available,\n                                             int maxSize) {\n    set<tuple<int,int,int>> component;\n    queue<tuple<int,int,int>> q;\n    q.push(start);\n    available.erase(start);\n    component.insert(start);\n    \n    int dx[] = {1, -1, 0, 0, 0, 0};\n    int dy[] = {0, 0, 1, -1, 0, 0};\n    int dz[] = {0, 0, 0, 0, 1, -1};\n    \n    while (!q.empty() && (int)component.size() < maxSize) {\n        auto [x, y, z] = q.front();\n        q.pop();\n        \n        for (int i = 0; i < 6; i++) {\n            int nx = x + dx[i], ny = y + dy[i], nz = z + dz[i];\n            auto next = make_tuple(nx, ny, nz);\n            if (available.count(next)) {\n                available.erase(next);\n                component.insert(next);\n                q.push(next);\n                if ((int)component.size() >= maxSize) break;\n            }\n        }\n    }\n    return component;\n}\n\nset<tuple<int,int,int>> normalize(const set<tuple<int,int,int>>& block) {\n    if (block.empty()) return block;\n    int minX = 1e9, minY = 1e9, minZ = 1e9;\n    for (auto [x, y, z] : block) {\n        minX = min(minX, x); minY = min(minY, y); minZ = min(minZ, z);\n    }\n    set<tuple<int,int,int>> result;\n    for (auto [x, y, z] : block) {\n        result.insert({x - minX, y - minY, z - minZ});\n    }\n    return result;\n}\n\nset<tuple<int,int,int>> rotateX(const set<tuple<int,int,int>>& block) {\n    set<tuple<int,int,int>> result;\n    for (auto [x, y, z] : block) result.insert({x, -z, y});\n    return normalize(result);\n}\n\nset<tuple<int,int,int>> rotateY(const set<tuple<int,int,int>>& block) {\n    set<tuple<int,int,int>> result;\n    for (auto [x, y, z] : block) result.insert({z, y, -x});\n    return normalize(result);\n}\n\nset<tuple<int,int,int>> rotateZ(const set<tuple<int,int,int>>& block) {\n    set<tuple<int,int,int>> result;\n    for (auto [x, y, z] : block) result.insert({-y, x, z});\n    return normalize(result);\n}\n\nset<tuple<int,int,int>> getCanonical(const set<tuple<int,int,int>>& block) {\n    set<set<tuple<int,int,int>>> allRotations;\n    auto current = normalize(block);\n    \n    for (int i = 0; i < 4; i++) {\n        allRotations.insert(current);\n        allRotations.insert(rotateY(current));\n        allRotations.insert(rotateY(rotateY(current)));\n        allRotations.insert(rotateY(rotateY(rotateY(current))));\n        current = rotateX(current);\n    }\n    current = rotateZ(normalize(block));\n    for (int i = 0; i < 4; i++) {\n        allRotations.insert(current);\n        current = rotateY(current);\n    }\n    current = rotateZ(rotateZ(rotateZ(normalize(block))));\n    for (int i = 0; i < 4; i++) {\n        allRotations.insert(current);\n        current = rotateY(current);\n    }\n    \n    return *allRotations.begin();\n}\n\nint main() {\n    cin >> D;\n    f1.resize(D); r1.resize(D); f2.resize(D); r2.resize(D);\n    \n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n    \n    set<tuple<int,int,int>> occ1, occ2;\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 (isOccupied(x, y, z, f1, r1)) occ1.insert({x, y, z});\n                if (isOccupied(x, y, z, f2, r2)) occ2.insert({x, y, z});\n            }\n        }\n    }\n    \n    // Position-based sharing\n    set<tuple<int,int,int>> common;\n    for (auto pos : occ1) {\n        if (occ2.count(pos)) common.insert(pos);\n    }\n    \n    vector<set<tuple<int,int,int>>> sharedBlocks;\n    auto availCommon = common;\n    while (!availCommon.empty()) {\n        sharedBlocks.push_back(getComponentLimited(*availCommon.begin(), availCommon, 1000));\n    }\n    \n    // Unique regions - create smaller blocks for better matching\n    set<tuple<int,int,int>> unique1, unique2;\n    for (auto pos : occ1) if (!common.count(pos)) unique1.insert(pos);\n    for (auto pos : occ2) if (!common.count(pos)) unique2.insert(pos);\n    \n    // Use smaller max size to create more uniform blocks\n    int maxBlockSize = min(D * 2, 10);\n    \n    vector<set<tuple<int,int,int>>> blocks1, blocks2;\n    auto avail1 = unique1;\n    while (!avail1.empty()) {\n        blocks1.push_back(getComponentLimited(*avail1.begin(), avail1, maxBlockSize));\n    }\n    auto avail2 = unique2;\n    while (!avail2.empty()) {\n        blocks2.push_back(getComponentLimited(*avail2.begin(), avail2, maxBlockSize));\n    }\n    \n    // Shape matching\n    map<set<tuple<int,int,int>>, vector<int>> shape1, shape2;\n    for (int i = 0; i < blocks1.size(); i++) {\n        shape1[getCanonical(blocks1[i])].push_back(i);\n    }\n    for (int i = 0; i < blocks2.size(); i++) {\n        shape2[getCanonical(blocks2[i])].push_back(i);\n    }\n    \n    vector<int> match1(blocks1.size(), -1), match2(blocks2.size(), -1);\n    \n    // Match all blocks with same shape\n    vector<pair<int, set<tuple<int,int,int>>>> shapesWithVol;\n    for (auto& [shape, indices] : shape1) {\n        if (shape2.count(shape) && !indices.empty()) {\n            int vol = blocks1[indices[0]].size();\n            shapesWithVol.push_back({vol, shape});\n        }\n    }\n    sort(shapesWithVol.rbegin(), shapesWithVol.rend());\n    \n    for (auto [vol, shape] : shapesWithVol) {\n        auto& idx1 = shape1[shape];\n        auto& idx2 = shape2[shape];\n        int pairs = min(idx1.size(), idx2.size());\n        for (int p = 0; p < pairs; p++) {\n            if (match1[idx1[p]] == -1 && match2[idx2[p]] == -1) {\n                match1[idx1[p]] = idx2[p];\n                match2[idx2[p]] = idx1[p];\n            }\n        }\n    }\n    \n    // Build output\n    vector<vector<vector<int>>> b1(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    vector<vector<vector<int>>> b2(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    \n    int nextId = 1;\n    \n    for (auto& block : sharedBlocks) {\n        int id = nextId++;\n        for (auto [x, y, z] : block) {\n            b1[x][y][z] = b2[x][y][z] = id;\n        }\n    }\n    \n    for (int i = 0; i < blocks1.size(); i++) {\n        if (match1[i] != -1) {\n            int id = nextId++;\n            for (auto [x, y, z] : blocks1[i]) b1[x][y][z] = id;\n            for (auto [x, y, z] : blocks2[match1[i]]) b2[x][y][z] = id;\n        }\n    }\n    \n    for (int i = 0; i < blocks1.size(); i++) {\n        if (match1[i] == -1) {\n            int id = nextId++;\n            for (auto [x, y, z] : blocks1[i]) b1[x][y][z] = id;\n        }\n    }\n    \n    for (int i = 0; i < blocks2.size(); i++) {\n        if (match2[i] == -1) {\n            int id = nextId++;\n            for (auto [x, y, z] : blocks2[i]) b2[x][y][z] = id;\n        }\n    }\n    \n    cout << nextId - 1 << endl;\n    \n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            for (int z = 0; z < D; z++) {\n                if (x > 0 || y > 0 || z > 0) cout << \" \";\n                cout << b1[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n    \n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            for (int z = 0; z < D; z++) {\n                if (x > 0 || y > 0 || z > 0) cout << \" \";\n                cout << b2[x][y][z];\n            }\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    auto start_time = chrono::steady_clock::now();\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<long long> x(N), y(N);\n    for (int i = 0; i < N; i++) {\n        cin >> x[i] >> y[i];\n    }\n    \n    struct Edge {\n        int u, v, id;\n        long long w;\n    };\n    \n    vector<Edge> edges(M);\n    map<pair<int,int>, int> edge_map;\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--; edges[i].v--;\n        edges[i].id = i;\n        edge_map[{min(edges[i].u, edges[i].v), max(edges[i].u, edges[i].v)}] = i;\n    }\n    \n    vector<long long> a(K), b(K);\n    for (int i = 0; i < K; i++) {\n        cin >> a[i] >> b[i];\n    }\n    \n    auto get_time = [&]() {\n        auto current = chrono::steady_clock::now();\n        return chrono::duration_cast<chrono::milliseconds>(current - start_time).count();\n    };\n    \n    auto dist = [](long long x1, long long y1, long long x2, long long y2) {\n        long long dx = x1 - x2;\n        long long dy = y1 - y2;\n        return sqrt((double)(dx * dx + dy * dy));\n    };\n    \n    // Build MST\n    vector<Edge> sorted_edges = edges;\n    sort(sorted_edges.begin(), sorted_edges.end(), [](const Edge& a, const Edge& b) {\n        return a.w < b.w;\n    });\n    \n    vector<int> uf_parent(N);\n    iota(uf_parent.begin(), uf_parent.end(), 0);\n    \n    function<int(int)> uf_find = [&](int v) {\n        return uf_parent[v] == v ? v : uf_parent[v] = uf_find(uf_parent[v]);\n    };\n    \n    set<int> active_vertices;\n    active_vertices.insert(0);\n    vector<vector<pair<int, long long>>> tree_adj(N);\n    \n    for (const Edge& e : sorted_edges) {\n        int pu = uf_find(e.u), pv = uf_find(e.v);\n        if (pu != pv) {\n            uf_parent[pu] = pv;\n            active_vertices.insert(e.u);\n            active_vertices.insert(e.v);\n            tree_adj[e.u].push_back({e.v, e.w});\n            tree_adj[e.v].push_back({e.u, e.w});\n        }\n    }\n    \n    auto get_reachable = [&]() {\n        set<int> reachable;\n        queue<int> q;\n        q.push(0);\n        reachable.insert(0);\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (auto [v, w] : tree_adj[u]) {\n                if (active_vertices.count(v) && !reachable.count(v)) {\n                    reachable.insert(v);\n                    q.push(v);\n                }\n            }\n        }\n        return reachable;\n    };\n    \n    auto compute_assignment = [&](const set<int>& vertices) {\n        vector<int> P(N, 0);\n        vector<int> assignment(K, -1);\n        \n        for (int k = 0; k < K; k++) {\n            int best_v = -1;\n            double best_d = 1e18;\n            \n            for (int v : vertices) {\n                double d = dist(a[k], b[k], x[v], y[v]);\n                if (d < best_d) {\n                    best_d = d;\n                    best_v = v;\n                }\n            }\n            \n            if (best_v != -1 && best_d <= 5000) {\n                int required = (int)ceil(best_d);\n                P[best_v] = max(P[best_v], required);\n                assignment[k] = best_v;\n            }\n        }\n        return make_pair(P, assignment);\n    };\n    \n    auto verify_coverage = [&](const set<int>& vertices, const vector<int>& powers) {\n        for (int k = 0; k < K; k++) {\n            bool covered = false;\n            for (int v : vertices) {\n                double d = dist(a[k], b[k], x[v], y[v]);\n                if (d <= powers[v]) {\n                    covered = true;\n                    break;\n                }\n            }\n            if (!covered) return false;\n        }\n        return true;\n    };\n    \n    auto [P, assignment] = compute_assignment(active_vertices);\n    \n    // Phase 1: Smart pruning\n    int no_improve_count = 0;\n    for (int iter = 0; iter < 100 && get_time() < 1400; iter++) {\n        bool changed = false;\n        auto reachable = get_reachable();\n        \n        vector<tuple<double, int>> candidates;\n        \n        for (int v : reachable) {\n            if (v == 0) continue;\n            \n            int degree = 0;\n            long long edge_cost = 0;\n            \n            for (auto [u, w] : tree_adj[v]) {\n                if (active_vertices.count(u) && reachable.count(u)) {\n                    degree++;\n                    edge_cost = w;\n                    if (degree > 1) break;\n                }\n            }\n            \n            if (degree != 1) continue;\n            \n            long long vertex_cost = (long long)P[v] * P[v] + edge_cost;\n            int resident_count = count(assignment.begin(), assignment.end(), v);\n            \n            double ratio = (double)vertex_cost / max(1, resident_count);\n            candidates.push_back({ratio, v});\n        }\n        \n        sort(candidates.begin(), candidates.end(), greater<>());\n        \n        for (auto [ratio, v] : candidates) {\n            if (!active_vertices.count(v)) continue;\n            \n            set<int> test_vertices = active_vertices;\n            test_vertices.erase(v);\n            \n            auto [test_P, test_assignment] = compute_assignment(test_vertices);\n            \n            if (!verify_coverage(test_vertices, test_P)) continue;\n            \n            long long old_cost = 0, new_cost = 0;\n            for (int u : active_vertices) {\n                old_cost += (long long)P[u] * P[u];\n            }\n            for (int u : test_vertices) {\n                new_cost += (long long)test_P[u] * test_P[u];\n            }\n            \n            for (auto [u, w] : tree_adj[v]) {\n                if (active_vertices.count(u) && reachable.count(u)) {\n                    old_cost += w;\n                }\n            }\n            \n            if (new_cost < old_cost) {\n                active_vertices = test_vertices;\n                P = test_P;\n                assignment = test_assignment;\n                changed = true;\n                no_improve_count = 0;\n                break;\n            }\n        }\n        \n        if (!changed) {\n            no_improve_count++;\n            if (no_improve_count >= 3) break;\n        }\n    }\n    \n    // Phase 2: Assignment optimization (15 iterations instead of 10)\n    if (get_time() < 1800) {\n        auto reachable = get_reachable();\n        \n        vector<vector<int>> residents_of(N);\n        for (int k = 0; k < K; k++) {\n            if (assignment[k] != -1) {\n                residents_of[assignment[k]].push_back(k);\n            }\n        }\n        \n        for (int iter = 0; iter < 15 && get_time() < 1900; iter++) {\n            bool improved = false;\n            \n            for (int k = 0; k < K; k++) {\n                int cur_v = assignment[k];\n                if (cur_v == -1) continue;\n                \n                for (int new_v : reachable) {\n                    if (new_v == cur_v) continue;\n                    \n                    double d = dist(a[k], b[k], x[new_v], y[new_v]);\n                    if (d > 5000) continue;\n                    \n                    int old_power_cur = P[cur_v];\n                    int new_power_cur = 0;\n                    for (int k2 : residents_of[cur_v]) {\n                        if (k2 != k) {\n                            double d2 = dist(a[k2], b[k2], x[cur_v], y[cur_v]);\n                            new_power_cur = max(new_power_cur, (int)ceil(d2));\n                        }\n                    }\n                    \n                    int old_power_new = P[new_v];\n                    int new_power_new = max(old_power_new, (int)ceil(d));\n                    \n                    long long cost_delta = ((long long)new_power_cur * new_power_cur + (long long)new_power_new * new_power_new)\n                                          - ((long long)old_power_cur * old_power_cur + (long long)old_power_new * old_power_new);\n                    \n                    if (cost_delta < 0) {\n                        P[cur_v] = new_power_cur;\n                        P[new_v] = new_power_new;\n                        assignment[k] = new_v;\n                        \n                        auto it = std::find(residents_of[cur_v].begin(), residents_of[cur_v].end(), k);\n                        residents_of[cur_v].erase(it);\n                        residents_of[new_v].push_back(k);\n                        \n                        improved = true;\n                        break;\n                    }\n                }\n            }\n            \n            if (!improved) break;\n        }\n    }\n    \n    // Phase 3: Power micro-optimization\n    if (get_time() < 1950) {\n        auto reachable = get_reachable();\n        for (int v : reachable) {\n            if (P[v] == 0) continue;\n            \n            // Try reducing power by 1\n            for (int delta = 1; delta <= min(10, P[v]); delta++) {\n                int test_power = P[v] - delta;\n                bool all_covered = true;\n                \n                for (int k = 0; k < K; k++) {\n                    if (assignment[k] == v) {\n                        double d = dist(a[k], b[k], x[v], y[v]);\n                        if (d > test_power) {\n                            all_covered = false;\n                            break;\n                        }\n                    }\n                }\n                \n                if (all_covered) {\n                    P[v] = test_power;\n                } else {\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Final power minimization\n    auto reachable = get_reachable();\n    for (int v : reachable) {\n        P[v] = 0;\n    }\n    \n    for (int k = 0; k < K; k++) {\n        if (assignment[k] != -1) {\n            double d = dist(a[k], b[k], x[assignment[k]], y[assignment[k]]);\n            P[assignment[k]] = max(P[assignment[k]], (int)ceil(d));\n        }\n    }\n    \n    // Final verification\n    if (!verify_coverage(reachable, P)) {\n        auto [safe_P, safe_assignment] = compute_assignment(reachable);\n        P = safe_P;\n    }\n    \n    // Build output\n    vector<int> edge_on(M, 0);\n    vector<bool> visited(N, false);\n    queue<int> q;\n    q.push(0);\n    visited[0] = true;\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        \n        for (auto [v, w] : tree_adj[u]) {\n            if (!visited[v] && active_vertices.count(v)) {\n                visited[v] = true;\n                q.push(v);\n                \n                auto it = edge_map.find({min(u, v), max(u, v)});\n                if (it != edge_map.end()) {\n                    edge_on[it->second] = 1;\n                }\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << P[i];\n    }\n    cout << \"\\n\";\n    \n    for (int i = 0; i < M; i++) {\n        if (i > 0) cout << \" \";\n        cout << edge_on[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <tuple>\nusing namespace std;\n\nconst int N = 30;\nconst int MAX_OPS = 9900;\n\nvector<vector<int>> pyramid;\nvector<tuple<int,int,int,int>> operations;\n\nvoid swap_balls(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    operations.push_back({x1, y1, x2, y2});\n}\n\nint count_violations() {\n    int count = 0;\n    for (int x = 0; x < N-1; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) count++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) count++;\n        }\n    }\n    return count;\n}\n\nvoid sink(int x, int y) {\n    while (x < N-1 && operations.size() < MAX_OPS) {\n        int current = pyramid[x][y];\n        int left_child = pyramid[x+1][y];\n        int right_child = pyramid[x+1][y+1];\n        \n        if (current <= left_child && current <= right_child) {\n            break;\n        }\n        \n        if (left_child < right_child) {\n            swap_balls(x, y, x+1, y);\n            x++;\n        } else {\n            swap_balls(x, y, x+1, y+1);\n            x++;\n            y++;\n        }\n    }\n}\n\nvoid solve() {\n    // Phase 1: Initial heapify from bottom to top\n    for (int x = N-2; x >= 0 && operations.size() < MAX_OPS; x--) {\n        for (int y = 0; y <= x && operations.size() < MAX_OPS; y++) {\n            sink(x, y);\n        }\n    }\n    \n    // Phase 2: Fix remaining violations with multiple passes\n    for (int pass = 0; pass < 50 && operations.size() < MAX_OPS; pass++) {\n        if (count_violations() == 0) break;\n        \n        for (int x = 0; x < N-1 && operations.size() < MAX_OPS; x++) {\n            for (int y = 0; y <= x && operations.size() < MAX_OPS; y++) {\n                int current = pyramid[x][y];\n                int left_child = pyramid[x+1][y];\n                int right_child = pyramid[x+1][y+1];\n                \n                if (current > left_child || current > right_child) {\n                    sink(x, y);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    pyramid.resize(N);\n    for (int x = 0; x < N; x++) {\n        pyramid[x].resize(x+1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    solve();\n    \n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int D = 9;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\n\nint N;\nbool obstacle[D][D];\nint container[D][D];\nconst int entrance_x = 0;\nconst int entrance_y = 4;\nvector<vector<int>> dist_from_entrance;\n\nbool isValid(int x, int y) {\n    return x >= 0 && x < D && y >= 0 && y < D;\n}\n\nset<pair<int,int>> getReachable() {\n    set<pair<int,int>> reachable;\n    queue<pair<int,int>> q;\n    q.push({entrance_x, entrance_y});\n    reachable.insert({entrance_x, entrance_y});\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (isValid(nx, ny) && !obstacle[nx][ny] && \n                container[nx][ny] == -1 && \n                reachable.find({nx, ny}) == reachable.end()) {\n                reachable.insert({nx, ny});\n                q.push({nx, ny});\n            }\n        }\n    }\n    \n    return reachable;\n}\n\nvoid calcDistances() {\n    dist_from_entrance.assign(D, vector<int>(D, -1));\n    queue<pair<int,int>> q;\n    q.push({entrance_x, entrance_y});\n    dist_from_entrance[entrance_x][entrance_y] = 0;\n    \n    while (!q.empty()) {\n        auto [x, y] = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            \n            if (isValid(nx, ny) && !obstacle[nx][ny] && dist_from_entrance[nx][ny] == -1) {\n                dist_from_entrance[nx][ny] = dist_from_entrance[x][y] + 1;\n                q.push({nx, ny});\n            }\n        }\n    }\n}\n\nint main() {\n    int D_input;\n    cin >> D_input >> N;\n    \n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            obstacle[i][j] = false;\n            container[i][j] = -1;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        obstacle[x][y] = true;\n    }\n    \n    calcDistances();\n    \n    int max_dist = 0;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (dist_from_entrance[i][j] > max_dist) {\n                max_dist = dist_from_entrance[i][j];\n            }\n        }\n    }\n    \n    int total_containers = D * D - 1 - N;\n    \n    // Placement phase\n    for (int d = 0; d < total_containers; d++) {\n        int t;\n        cin >> t;\n        \n        set<pair<int,int>> reachable = getReachable();\n        \n        // Map container number to target distance\n        double ratio = (double)t / max(1, total_containers - 1);\n        int target_dist = 1 + (int)(ratio * (max_dist - 1));\n        \n        // Find reachable cell closest to target distance\n        pair<int,int> chosen = {-1, -1};\n        int min_diff = 1000000;\n        \n        for (auto [x, y] : reachable) {\n            if (container[x][y] == -1 && (x != entrance_x || y != entrance_y)) {\n                int cell_dist = dist_from_entrance[x][y];\n                int diff = abs(cell_dist - target_dist);\n                if (diff < min_diff || \n                    (diff == min_diff && chosen.first != -1 && \n                     cell_dist < dist_from_entrance[chosen.first][chosen.second])) {\n                    min_diff = diff;\n                    chosen = {x, y};\n                }\n            }\n        }\n        \n        container[chosen.first][chosen.second] = t;\n        cout << chosen.first << \" \" << chosen.second << endl;\n        cout.flush();\n    }\n    \n    // Retrieval phase: always pick smallest accessible\n    for (int i = 0; i < total_containers; i++) {\n        set<pair<int,int>> reachable = getReachable();\n        \n        int min_num = total_containers;\n        pair<int,int> min_pos = {-1, -1};\n        \n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (container[x][y] >= 0 && reachable.count({x, y})) {\n                    if (container[x][y] < min_num) {\n                        min_num = container[x][y];\n                        min_pos = {x, y};\n                    }\n                }\n            }\n        }\n        \n        cout << min_pos.first << \" \" << min_pos.second << endl;\n        container[min_pos.first][min_pos.second] = -1;\n    }\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint n = 50, m;\nvector<vector<int>> grid;\nint dx[] = {-1, 1, 0, 0};\nint dy[] = {0, 0, -1, 1};\n\nset<pair<int,int>> getAdj(vector<vector<int>>& g) {\n    set<pair<int,int>> adj;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            int c = g[i][j];\n            if (i == 0 || i == n-1 || j == 0 || j == n-1) {\n                if (c != 0) adj.insert({0, c});\n            }\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni >= 0 && ni < n && nj >= 0 && nj < n && g[ni][nj] != c) {\n                    adj.insert({min(c, g[ni][nj]), max(c, g[ni][nj])});\n                }\n            }\n        }\n    }\n    return adj;\n}\n\nbool isConnected(vector<vector<int>>& g, int color) {\n    vector<pair<int,int>> cells;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (g[i][j] == color) cells.push_back({i,j});\n        }\n    }\n    if (cells.empty()) return true;\n    \n    queue<pair<int,int>> q;\n    set<pair<int,int>> vis;\n    \n    if (color == 0) {\n        for (auto [i,j] : cells) {\n            if (i==0||i==n-1||j==0||j==n-1) {\n                q.push({i,j}); vis.insert({i,j});\n            }\n        }\n    } else {\n        q.push(cells[0]); vis.insert(cells[0]);\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 (nx>=0 && nx<n && ny>=0 && ny<n && g[nx][ny]==color && !vis.count({nx,ny})) {\n                vis.insert({nx,ny}); q.push({nx,ny});\n            }\n        }\n    }\n    return vis.size() == cells.size();\n}\n\nint main() {\n    cin >> n >> m;\n    grid.assign(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n        }\n    }\n    \n    auto origAdj = getAdj(grid);\n    \n    // Find which wards are adjacent to 0\n    set<int> adjTo0;\n    for (auto [c1, c2] : origAdj) {\n        if (c1 == 0) adjTo0.insert(c2);\n        if (c2 == 0) adjTo0.insert(c1);\n    }\n    \n    auto result = grid;\n    \n    // Only remove cells where ALL neighbors are already adjacent to 0\n    for (int iter = 0; iter < 50; iter++) {\n        bool changed = false;\n        \n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (result[i][j] == 0) continue;\n                \n                int color = result[i][j];\n                \n                // Check if all neighbors are adjacent to 0\n                bool allNeighborsOk = true;\n                set<int> neighbors;\n                for (int d = 0; d < 4; d++) {\n                    int ni = i + dx[d], nj = j + dy[d];\n                    if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                        int nc = result[ni][nj];\n                        if (nc != 0 && !adjTo0.count(nc)) {\n                            allNeighborsOk = false;\n                            break;\n                        }\n                        neighbors.insert(nc);\n                    }\n                }\n                \n                if (!allNeighborsOk) continue;\n                \n                // Try removing\n                result[i][j] = 0;\n                \n                if (!isConnected(result, color) || !isConnected(result, 0) || getAdj(result) != origAdj) {\n                    result[i][j] = color;\n                } else {\n                    changed = true;\n                }\n            }\n        }\n        \n        if (!changed) break;\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << (j?\" \":\"\") << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nint query_count = 0;\n\nchar do_query(vector<int> L, vector<int> R) {\n    query_count++;\n    cout << L.size() << \" \" << R.size();\n    for(int x : L) cout << \" \" << x;\n    for(int x : R) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\nvoid merge(vector<int>& items, int left, int mid, int right, int query_budget) {\n    vector<int> temp;\n    int i = left, j = mid + 1;\n    \n    while(i <= mid && j <= right) {\n        if(query_count >= query_budget) {\n            while(i <= mid) temp.push_back(items[i++]);\n            while(j <= right) temp.push_back(items[j++]);\n            break;\n        }\n        \n        char result = do_query({items[i]}, {items[j]});\n        if(result != '>') {\n            temp.push_back(items[i++]);\n        } else {\n            temp.push_back(items[j++]);\n        }\n    }\n    \n    while(i <= mid) temp.push_back(items[i++]);\n    while(j <= right) temp.push_back(items[j++]);\n    \n    for(int k = 0; k < temp.size(); k++) {\n        items[left + k] = temp[k];\n    }\n}\n\nvoid mergeSort(vector<int>& items, int left, int right, int query_budget) {\n    if(left >= right || query_count >= query_budget) return;\n    \n    int mid = (left + right) / 2;\n    mergeSort(items, left, mid, query_budget);\n    mergeSort(items, mid + 1, right, query_budget);\n    merge(items, left, mid, right, query_budget);\n}\n\nint main() {\n    cin >> N >> D >> Q;\n    \n    vector<int> items(N);\n    iota(items.begin(), items.end(), 0);\n    \n    // Conservative refinement budget\n    int sort_budget = Q - 25;\n    mergeSort(items, 0, N - 1, sort_budget);\n    \n    // Estimate weights using exponential distribution\n    vector<double> weight_est(N);\n    for(int i = 0; i < N; i++) {\n        double q = (i + 0.5) / N;\n        weight_est[items[i]] = -log(1.0 - q) * 100000.0;\n    }\n    \n    // Greedy assignment\n    vector<int> assignment(N);\n    vector<vector<int>> groups(D);\n    vector<double> group_weight(D, 0.0);\n    \n    for(int i = N-1; i >= 0; i--) {\n        int min_g = min_element(group_weight.begin(), group_weight.end()) - group_weight.begin();\n        assignment[items[i]] = min_g;\n        groups[min_g].push_back(items[i]);\n        group_weight[min_g] += weight_est[items[i]];\n    }\n    \n    // Conservative refinement: only when very beneficial\n    for(int round = 0; round < 4 && query_count < Q - 1; round++) {\n        int max_g = max_element(group_weight.begin(), group_weight.end()) - group_weight.begin();\n        int min_g = min_element(group_weight.begin(), group_weight.end()) - group_weight.begin();\n        \n        if(groups[max_g].size() <= 1) break;\n        \n        double imbalance = group_weight[max_g] - group_weight[min_g];\n        if(imbalance < 1000) break; // Only refine significant imbalances\n        \n        // Find item that creates best balance\n        int best_item = -1;\n        double best_new_diff = 1e18;\n        \n        for(int item : groups[max_g]) {\n            double new_max = group_weight[max_g] - weight_est[item];\n            double new_min = group_weight[min_g] + weight_est[item];\n            double new_diff = abs(new_max - new_min);\n            \n            if(new_diff < best_new_diff) {\n                best_new_diff = new_diff;\n                best_item = item;\n            }\n        }\n        \n        // Only move if substantial improvement (20%+)\n        if(best_item == -1 || best_new_diff >= imbalance * 0.8) break;\n        \n        // Verify with query\n        vector<int> heavy_without, light_with;\n        for(int x : groups[max_g]) {\n            if(x != best_item) heavy_without.push_back(x);\n        }\n        for(int x : groups[min_g]) {\n            light_with.push_back(x);\n        }\n        light_with.push_back(best_item);\n        \n        if(heavy_without.empty()) break;\n        \n        char result = do_query(heavy_without, light_with);\n        \n        if(result != '>') {\n            // Move\n            groups[max_g].erase(find(groups[max_g].begin(), groups[max_g].end(), best_item));\n            groups[min_g].push_back(best_item);\n            assignment[best_item] = min_g;\n            group_weight[max_g] -= weight_est[best_item];\n            group_weight[min_g] += weight_est[best_item];\n        } else {\n            // Estimates are unreliable, stop\n            break;\n        }\n    }\n    \n    // Use remaining queries\n    while(query_count < Q) {\n        do_query({0}, {1});\n    }\n    \n    // Output\n    for(int i = 0; i < N; i++) {\n        if(i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\ndouble calculate_cascade_cost(const vector<int>& dest_stack, const vector<int>& moving_boxes, int current_target) {\n    if (dest_stack.empty()) return 0;\n    \n    int min_moving = *min_element(moving_boxes.begin(), moving_boxes.end());\n    double total_cost = 0;\n    \n    for (int i = 0; i < (int)dest_stack.size(); i++) {\n        if (dest_stack[i] < min_moving) {\n            int boxes_above = dest_stack.size() - i;\n            int extraction_distance = dest_stack[i] - current_target;\n            double cascade_factor = boxes_above * boxes_above * extraction_distance * 0.3;\n            total_cost += cascade_factor;\n            \n            if (i > 0) {\n                total_cost += i * i * 10;\n            }\n        }\n    }\n    \n    return total_cost;\n}\n\nint simulate_future(vector<vector<int>> stacks, int m, int start, int depth) {\n    int energy = 0;\n    \n    for (int t = start; t < min(start + depth, 201); t++) {\n        int sid = -1, p = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == t) {\n                    sid = i; p = j; break;\n                }\n            }\n            if (sid != -1) break;\n        }\n        \n        if (p < (int)stacks[sid].size() - 1) {\n            vector<int> mov;\n            for (int i = p + 1; i < (int)stacks[sid].size(); i++) {\n                mov.push_back(stacks[sid][i]);\n            }\n            energy += mov.size() + 1;\n            \n            int empty_count = 0;\n            for (int i = 0; i < m; i++) {\n                if (stacks[i].empty()) empty_count++;\n            }\n            \n            int best = -1;\n            double best_sc = -1e18;\n            int min_m = *min_element(mov.begin(), mov.end());\n            \n            for (int i = 0; i < m; i++) {\n                if (i == sid) continue;\n                \n                double sc = 0;\n                \n                if (stacks[i].empty()) {\n                    if (empty_count <= 2) {\n                        sc = 1e11;\n                    } else {\n                        sc = 1e10;\n                    }\n                } else {\n                    double cascade = calculate_cascade_cost(stacks[i], mov, t);\n                    \n                    if (cascade < 0.1) {\n                        sc = 1e9 - stacks[i].size() * 50;\n                    } else {\n                        sc = -cascade * 100 - stacks[i].size() * 10;\n                    }\n                }\n                \n                if (sc > best_sc) {\n                    best_sc = sc;\n                    best = i;\n                }\n            }\n            \n            stacks[sid].resize(p + 1);\n            for (int x : mov) stacks[best].push_back(x);\n        }\n        stacks[sid].pop_back();\n    }\n    \n    return energy;\n}\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<pair<int, int>> operations;\n    \n    for (int target = 1; target <= n; target++) {\n        int stack_id = -1, pos = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == target) {\n                    stack_id = i; pos = j; break;\n                }\n            }\n            if (stack_id != -1) break;\n        }\n        \n        if (pos < (int)stacks[stack_id].size() - 1) {\n            vector<int> moving;\n            for (int i = pos + 1; i < (int)stacks[stack_id].size(); i++) {\n                moving.push_back(stacks[stack_id][i]);\n            }\n            \n            int empty_stacks = 0;\n            for (int i = 0; i < m; i++) {\n                if (stacks[i].empty()) empty_stacks++;\n            }\n            \n            // Collect all evaluations\n            vector<tuple<double, int, double, double>> candidates; // (total, dest, cascade, future)\n            \n            for (int dest = 0; dest < m; dest++) {\n                if (dest == stack_id) continue;\n                \n                auto s1 = stacks;\n                s1[stack_id].resize(pos + 1);\n                for (int x : moving) s1[dest].push_back(x);\n                \n                double immediate_cost = moving.size() + 1;\n                double cascade = calculate_cascade_cost(stacks[dest], moving, target);\n                double future_cost = simulate_future(s1, m, target + 1, 35);\n                \n                double bonus = 0;\n                if (stacks[dest].empty()) {\n                    if (empty_stacks <= 2) {\n                        bonus = -100;\n                    } else if (empty_stacks <= 4) {\n                        bonus = -80;\n                    } else {\n                        bonus = -60;\n                    }\n                } else if (cascade < 0.1) {\n                    bonus = -50;\n                }\n                \n                double total = immediate_cost + future_cost + cascade * 0.8 + bonus;\n                candidates.push_back({total, dest, cascade, future_cost});\n            }\n            \n            // Sort by total cost\n            sort(candidates.begin(), candidates.end());\n            \n            // Best option\n            int best_dest = get<1>(candidates[0]);\n            double best_cost = get<0>(candidates[0]);\n            \n            // Tie-breaking: if top 2 are very close, use secondary criteria\n            if (candidates.size() >= 2) {\n                double second_cost = get<0>(candidates[1]);\n                \n                // If difference is small (< 2 energy units)\n                if (second_cost - best_cost < 2.0) {\n                    int dest0 = get<1>(candidates[0]);\n                    int dest1 = get<1>(candidates[1]);\n                    double casc0 = get<2>(candidates[0]);\n                    double casc1 = get<2>(candidates[1]);\n                    \n                    // Prefer the one with lower cascade (more stable)\n                    if (casc1 < casc0 - 5.0) {\n                        best_dest = dest1;\n                    }\n                    // If both are safe, prefer smaller stack\n                    else if (casc0 < 0.1 && casc1 < 0.1) {\n                        if (stacks[dest1].size() < stacks[dest0].size()) {\n                            best_dest = dest1;\n                        }\n                    }\n                }\n            }\n            \n            operations.push_back({stacks[stack_id][pos + 1], best_dest + 1});\n            stacks[stack_id].resize(pos + 1);\n            for (int x : moving) stacks[best_dest].push_back(x);\n        }\n        \n        operations.push_back({target, 0});\n        stacks[stack_id].pop_back();\n    }\n    \n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\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;\n\nconst int di[] = {0, 1, 0, -1};\nconst int dj[] = {1, 0, -1, 0};\nconst char dir_char[] = {'R', 'D', 'L', 'U'};\n\nbool can_move(int i, int j, int dir) {\n    int ni = i + di[dir];\n    int nj = j + dj[dir];\n    if (ni < 0 || ni >= N || nj < 0 || nj >= N) return false;\n    \n    if (dir == 0) return v[i][j] == '0';\n    else if (dir == 1) return h[i][j] == '0';\n    else if (dir == 2) return v[i][j-1] == '0';\n    else return h[i-1][j] == '0';\n}\n\nvector<vector<int>> simulate_visits(const string& route) {\n    vector<vector<int>> visits(N, vector<int>(N, 0));\n    int ci = 0, cj = 0;\n    visits[0][0]++;\n    \n    for (char c : route) {\n        int dir = (c == 'R' ? 0 : c == 'D' ? 1 : c == 'L' ? 2 : 3);\n        ci += di[dir];\n        cj += dj[dir];\n        visits[ci][cj]++;\n    }\n    return visits;\n}\n\npair<vector<vector<int>>, vector<vector<int>>> bfs_from(int si, int sj) {\n    vector<vector<int>> dist(N, vector<int>(N, 1e9));\n    vector<vector<int>> parent_dir(N, vector<int>(N, -1));\n    queue<pair<int, int>> q;\n    \n    q.push({si, sj});\n    dist[si][sj] = 0;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            \n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            \n            if (dist[ni][nj] > dist[i][j] + 1) {\n                dist[ni][nj] = dist[i][j] + 1;\n                parent_dir[ni][nj] = dir;\n                q.push({ni, nj});\n            }\n        }\n    }\n    return {dist, parent_dir};\n}\n\npair<string, vector<pair<int,int>>> reconstruct_path_with_cells(int si, int sj, int ti, int tj, vector<vector<int>>& parent_dir) {\n    if (si == ti && sj == tj) return {\"\", {{si, sj}}};\n    \n    string path;\n    vector<pair<int,int>> cells;\n    \n    int ci = ti, cj = tj;\n    cells.push_back({ti, tj});\n    \n    while (ci != si || cj != sj) {\n        int dir = parent_dir[ci][cj];\n        path += dir_char[dir];\n        ci -= di[dir];\n        cj -= dj[dir];\n        cells.push_back({ci, cj});\n    }\n    \n    reverse(path.begin(), path.end());\n    reverse(cells.begin(), cells.end());\n    return {path, cells};\n}\n\ndouble compute_score(int L, const vector<vector<int>>& visits) {\n    double score = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (visits[i][j] > 0) {\n                score += (double)d[i][j] * L / (2.0 * visits[i][j]);\n            }\n        }\n    }\n    return score;\n}\n\nstring build_initial_tour(int strategy) {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    string route;\n    \n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        \n        vector<pair<double, int>> neighbors;\n        for (int dir = 0; dir < 4; dir++) {\n            if (!can_move(i, j, dir)) continue;\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            if (!visited[ni][nj]) {\n                double score;\n                \n                if (strategy == 0) {\n                    score = -d[ni][nj];\n                } else if (strategy == 1) {\n                    score = -d[ni][nj] + (dir <= 1 ? -0.5 : 0.5);\n                } else if (strategy == 2) {\n                    score = -d[ni][nj] + (dir >= 2 ? -0.5 : 0.5);\n                } else if (strategy == 3) {\n                    double dist = sqrt((ni)*(ni) + (nj)*(nj));\n                    score = -d[ni][nj] - dist * 10;\n                } else if (strategy == 4) {\n                    double dist = sqrt((ni)*(ni) + (nj)*(nj));\n                    score = -d[ni][nj] + dist * 10;\n                } else if (strategy == 5) {\n                    score = -d[ni][nj] * (1.0 + 0.1 * dir);\n                } else if (strategy == 6) {\n                    // Value + Manhattan distance from origin\n                    score = -d[ni][nj] - (abs(ni) + abs(nj)) * 5;\n                } else if (strategy == 7) {\n                    // Value - Manhattan distance (prefer close to origin)\n                    score = -d[ni][nj] + (abs(ni) + abs(nj)) * 5;\n                } else if (strategy == 8) {\n                    // Weighted: 80% value, 20% distance\n                    double dist = sqrt((ni-i)*(ni-i) + (nj-j)*(nj-j));\n                    score = -d[ni][nj] * 0.8 - dist * 100;\n                } else if (strategy == 9) {\n                    // Square root of value (compress dynamic range)\n                    score = -sqrt((double)d[ni][nj]) * 30;\n                } else if (strategy == 10) {\n                    // Log of value\n                    score = -log((double)d[ni][nj] + 1) * 100;\n                } else {\n                    // Quadrant preference: prefer bottom-right\n                    score = -d[ni][nj] - (ni + nj) * 3;\n                }\n                \n                neighbors.push_back({score, dir});\n            }\n        }\n        \n        sort(neighbors.begin(), neighbors.end());\n        \n        for (auto [_, dir] : neighbors) {\n            int ni = i + di[dir];\n            int nj = j + dj[dir];\n            \n            if (!visited[ni][nj]) {\n                route += dir_char[dir];\n                dfs(ni, nj);\n                route += dir_char[(dir + 2) % 4];\n            }\n        }\n    };\n    \n    dfs(0, 0);\n    return route;\n}\n\nstring optimize_tour(string route) {\n    const int MAX_LEN = 100000;\n    \n    auto visit_counts = simulate_visits(route);\n    auto [dist_from_origin, parent_from_origin] = bfs_from(0, 0);\n    \n    map<pair<int,int>, pair<string, vector<pair<int,int>>>> path_data;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (dist_from_origin[i][j] < 1e9) {\n                path_data[{i, j}] = reconstruct_path_with_cells(0, 0, i, j, parent_from_origin);\n            }\n        }\n    }\n    \n    while (route.length() < MAX_LEN - 50) {\n        double best_improvement = 0;\n        int best_i = -1, best_j = -1;\n        \n        int L_current = route.length();\n        double current_score = compute_score(L_current, visit_counts);\n        \n        for (auto& [dest, data] : path_data) {\n            auto [i, j] = dest;\n            auto& [path, cells] = data;\n            \n            int detour_len = 2 * path.length();\n            if (detour_len == 0 || route.length() + detour_len > MAX_LEN) continue;\n            \n            int L_new = L_current + detour_len;\n            auto temp_visits = visit_counts;\n            for (auto [pi, pj] : cells) {\n                temp_visits[pi][pj] += 2;\n            }\n            \n            double new_score = compute_score(L_new, temp_visits);\n            double improvement = current_score - new_score;\n            \n            if (improvement > best_improvement) {\n                best_improvement = improvement;\n                best_i = i;\n                best_j = j;\n            }\n        }\n        \n        if (best_i == -1 || best_improvement <= 0) break;\n        \n        auto& [path_to, cells] = path_data[{best_i, best_j}];\n        string path_back = path_to;\n        reverse(path_back.begin(), path_back.end());\n        for (char& c : path_back) {\n            if (c == 'U') c = 'D';\n            else if (c == 'D') c = 'U';\n            else if (c == 'L') c = 'R';\n            else if (c == 'R') c = 'L';\n        }\n        \n        route += path_to + path_back;\n        \n        for (auto [pi, pj] : cells) {\n            visit_counts[pi][pj] += 2;\n        }\n    }\n    \n    return route;\n}\n\nstring build_tour() {\n    string best_route;\n    double best_score = 1e18;\n    \n    // Try 12 different strategies\n    for (int strategy = 0; strategy < 12; strategy++) {\n        string initial = build_initial_tour(strategy);\n        string optimized = optimize_tour(initial);\n        \n        auto visits = simulate_visits(optimized);\n        double score = compute_score(optimized.length(), visits);\n        \n        if (score < best_score) {\n            best_score = score;\n            best_route = optimized;\n        }\n    }\n    \n    return best_route;\n}\n\nint main() {\n    cin >> N;\n    \n    h.resize(N-1);\n    for (int i = 0; i < N-1; i++) cin >> h[i];\n    \n    v.resize(N);\n    for (int i = 0; i < N; i++) cin >> v[i];\n    \n    d.resize(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> d[i][j];\n        }\n    }\n    \n    cout << build_tour() << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\nint si, sj;\nvector<string> grid;\nvector<string> targets;\nmap<char, vector<pair<int,int>>> char_positions;\nvector<vector<int>> ovl;\n\nint overlap(const string& s1, const string& s2) {\n    int maxLen = min((int)s1.length(), (int)s2.length());\n    for (int len = maxLen; len >= 1; len--) {\n        if (s1.substr(s1.length() - len) == s2.substr(0, len)) {\n            return len;\n        }\n    }\n    return 0;\n}\n\nbool contains(const string& s, const string& target) {\n    return s.find(target) != string::npos;\n}\n\nbool checkComplete(const string& s) {\n    for (const auto& t : targets) {\n        if (!contains(s, t)) return false;\n    }\n    return true;\n}\n\npair<int,int> findClosest(char c, int curI, int curJ) {\n    auto& positions = char_positions[c];\n    int bestDist = INT_MAX;\n    pair<int,int> best = positions[0];\n    \n    for (auto& pos : positions) {\n        int dist = abs(pos.first - curI) + abs(pos.second - curJ);\n        if (dist < bestDist) {\n            bestDist = dist;\n            best = pos;\n        }\n    }\n    return best;\n}\n\npair<int,int> findBestPosition(char c, int curI, int curJ, const string& text, int pos) {\n    auto& positions = char_positions[c];\n    if (positions.size() == 1) return positions[0];\n    \n    int bestScore = INT_MAX;\n    pair<int,int> best = positions[0];\n    int lookAhead = min(12, (int)text.length() - pos - 1);\n    \n    for (auto& p : positions) {\n        int score = abs(p.first - curI) + abs(p.second - curJ);\n        \n        int tmpI = p.first, tmpJ = p.second;\n        for (int i = 1; i <= lookAhead; i++) {\n            auto nextPos = findClosest(text[pos + i], tmpI, tmpJ);\n            score += abs(nextPos.first - tmpI) + abs(nextPos.second - tmpJ);\n            tmpI = nextPos.first;\n            tmpJ = nextPos.second;\n        }\n        \n        if (score < bestScore) {\n            bestScore = score;\n            best = p;\n        }\n    }\n    return best;\n}\n\nint estimateCost(const string& text) {\n    int cost = 0;\n    int curI = si, curJ = sj;\n    \n    for (char c : text) {\n        auto pos = findClosest(c, curI, curJ);\n        cost += abs(pos.first - curI) + abs(pos.second - curJ) + 1;\n        curI = pos.first;\n        curJ = pos.second;\n    }\n    return cost;\n}\n\nint calculateCost(const string& text) {\n    int cost = 0;\n    int curI = si, curJ = sj;\n    \n    for (int i = 0; i < text.length(); i++) {\n        auto pos = findBestPosition(text[i], curI, curJ, text, i);\n        cost += abs(pos.first - curI) + abs(pos.second - curJ) + 1;\n        curI = pos.first;\n        curJ = pos.second;\n    }\n    return cost;\n}\n\nstruct BeamState {\n    string text;\n    vector<bool> contained;\n    int lastIdx;\n    double score;\n    \n    bool operator<(const BeamState& other) const {\n        return score > other.score;\n    }\n};\n\nstring beamSearch(int startIdx, int beamWidth = 8) {\n    priority_queue<BeamState> beam;\n    \n    BeamState initial;\n    initial.text = targets[startIdx];\n    initial.contained.assign(M, false);\n    initial.contained[startIdx] = true;\n    initial.lastIdx = startIdx;\n    \n    for (int i = 0; i < M; i++) {\n        if (contains(initial.text, targets[i])) {\n            initial.contained[i] = true;\n        }\n    }\n    \n    int covered = count(initial.contained.begin(), initial.contained.end(), true);\n    initial.score = covered * 150.0 - initial.text.length() * 0.3;\n    \n    beam.push(initial);\n    \n    while (!beam.empty()) {\n        vector<BeamState> newBeam;\n        \n        int processed = 0;\n        while (!beam.empty() && processed < beamWidth) {\n            BeamState current = beam.top();\n            beam.pop();\n            processed++;\n            \n            bool allCovered = true;\n            for (int i = 0; i < M; i++) {\n                if (!current.contained[i]) {\n                    allCovered = false;\n                    break;\n                }\n            }\n            \n            if (allCovered) {\n                return current.text;\n            }\n            \n            vector<pair<double, int>> candidates;\n            for (int i = 0; i < M; i++) {\n                if (current.contained[i]) continue;\n                \n                int o = ovl[current.lastIdx][i];\n                int secondary = 0;\n                for (int j = 0; j < M; j++) {\n                    if (!current.contained[j] && j != i) {\n                        secondary += ovl[i][j];\n                    }\n                }\n                \n                double candidateScore = o * 25.0 + secondary * 1.5;\n                candidates.push_back({candidateScore, i});\n            }\n            \n            sort(candidates.rbegin(), candidates.rend());\n            \n            for (int k = 0; k < min(4, (int)candidates.size()); k++) {\n                int nextIdx = candidates[k].second;\n                \n                BeamState next;\n                int o = ovl[current.lastIdx][nextIdx];\n                next.text = current.text + (o > 0 ? targets[nextIdx].substr(o) : targets[nextIdx]);\n                next.contained = current.contained;\n                next.contained[nextIdx] = true;\n                next.lastIdx = nextIdx;\n                \n                for (int i = 0; i < M; i++) {\n                    if (!next.contained[i] && contains(next.text, targets[i])) {\n                        next.contained[i] = true;\n                    }\n                }\n                \n                int covered = count(next.contained.begin(), next.contained.end(), true);\n                next.score = covered * 150.0 - next.text.length() * 0.3;\n                \n                newBeam.push_back(next);\n            }\n        }\n        \n        sort(newBeam.begin(), newBeam.end());\n        beam = priority_queue<BeamState>();\n        for (int i = 0; i < min(beamWidth, (int)newBeam.size()); i++) {\n            beam.push(newBeam[i]);\n        }\n    }\n    \n    return targets[startIdx];\n}\n\nstring greedyBuild(int startIdx) {\n    vector<bool> contained(M, false);\n    string result = targets[startIdx];\n    contained[startIdx] = true;\n    \n    for (int i = 0; i < M; i++) {\n        if (!contained[i] && contains(result, targets[i])) {\n            contained[i] = true;\n        }\n    }\n    \n    int current = startIdx;\n    \n    while (true) {\n        int bestNext = -1;\n        int bestOverlap = -1;\n        int bestSecondary = -1;\n        int bestTertiary = INT_MAX;\n        \n        for (int i = 0; i < M; i++) {\n            if (contained[i]) continue;\n            \n            int o = ovl[current][i];\n            int secondary = 0;\n            for (int j = 0; j < M; j++) {\n                if (!contained[j] && j != i) {\n                    secondary += ovl[i][j];\n                }\n            }\n            int tertiary = targets[i].length();\n            \n            if (o > bestOverlap || \n                (o == bestOverlap && secondary > bestSecondary) ||\n                (o == bestOverlap && secondary == bestSecondary && tertiary < bestTertiary)) {\n                bestOverlap = o;\n                bestSecondary = secondary;\n                bestTertiary = tertiary;\n                bestNext = i;\n            }\n        }\n        \n        if (bestNext == -1) break;\n        \n        int o = ovl[current][bestNext];\n        result += (o > 0) ? targets[bestNext].substr(o) : targets[bestNext];\n        contained[bestNext] = true;\n        current = bestNext;\n        \n        for (int i = 0; i < M; i++) {\n            if (!contained[i] && contains(result, targets[i])) {\n                contained[i] = true;\n            }\n        }\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> si >> sj;\n    \n    grid.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    targets.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i];\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            char_positions[grid[i][j]].push_back({i, j});\n        }\n    }\n    \n    ovl.assign(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) {\n                ovl[i][j] = overlap(targets[i], targets[j]);\n            }\n        }\n    }\n    \n    // Multiple selection strategies for diversity\n    vector<pair<int,int>> candidates1;\n    for (int i = 0; i < M; i++) {\n        int total = 0;\n        for (int j = 0; j < M; j++) {\n            total += ovl[i][j] + ovl[j][i];\n        }\n        candidates1.push_back({total, i});\n    }\n    sort(candidates1.rbegin(), candidates1.rend());\n    \n    // Outgoing overlap priority\n    vector<pair<int,int>> candidates2;\n    for (int i = 0; i < M; i++) {\n        int total = 0;\n        for (int j = 0; j < M; j++) {\n            total += ovl[i][j];\n        }\n        candidates2.push_back({total, i});\n    }\n    sort(candidates2.rbegin(), candidates2.rend());\n    \n    set<int> candidateSet;\n    // Top 18 from bidirectional\n    for (int i = 0; i < min(18, M); i++) {\n        candidateSet.insert(candidates1[i].second);\n    }\n    // Top 5 from outgoing\n    for (int i = 0; i < min(5, M); i++) {\n        candidateSet.insert(candidates2[i].second);\n    }\n    \n    // Random diversity\n    for (int seed = 0; seed < 22; seed++) {\n        mt19937 rng(seed * 1234);\n        uniform_int_distribution<int> dist(0, M-1);\n        candidateSet.insert(dist(rng));\n    }\n    \n    vector<pair<string, int>> candidateResults;\n    \n    int beamCount = 0;\n    for (int idx : candidateSet) {\n        if (beamCount < 18) {\n            string result = beamSearch(idx, 8);\n            if (checkComplete(result)) {\n                int cost = estimateCost(result);\n                candidateResults.push_back({result, cost});\n            }\n            beamCount++;\n        }\n        \n        string result = greedyBuild(idx);\n        if (checkComplete(result)) {\n            int cost = estimateCost(result);\n            candidateResults.push_back({result, cost});\n        }\n    }\n    \n    sort(candidateResults.begin(), candidateResults.end(), \n         [](const auto& a, const auto& b) { return a.second < b.second; });\n    \n    string bestResult;\n    int bestCost = INT_MAX;\n    \n    for (int i = 0; i < min(45, (int)candidateResults.size()); i++) {\n        int cost = calculateCost(candidateResults[i].first);\n        if (cost < bestCost) {\n            bestCost = cost;\n            bestResult = candidateResults[i].first;\n        }\n    }\n    \n    if (bestResult.empty()) {\n        bestResult = greedyBuild(0);\n    }\n    \n    int curI = si, curJ = sj;\n    for (int i = 0; i < bestResult.length(); i++) {\n        auto pos = findBestPosition(bestResult[i], curI, curJ, bestResult, i);\n        cout << pos.first << \" \" << pos.second << \"\\n\";\n        curI = pos.first;\n        curJ = pos.second;\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>>> fields;\nint query_count = 0;\n\nint query(const vector<pair<int,int>>& cells) {\n    cout << \"q \" << cells.size();\n    for (auto [i, j] : cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    query_count++;\n    \n    int result;\n    cin >> result;\n    return result;\n}\n\nint drill(int i, int j) {\n    return query({{i, j}});\n}\n\nbool answer(const set<pair<int,int>>& cells) {\n    cout << \"a \" << cells.size();\n    for (auto [i, j] : cells) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    \n    int result;\n    cin >> result;\n    return result == 1;\n}\n\nint main() {\n    cin >> N >> M >> eps;\n    fields.resize(M);\n    \n    for (int k = 0; k < M; k++) {\n        int d;\n        cin >> d;\n        fields[k].resize(d);\n        for (int i = 0; i < d; i++) {\n            cin >> fields[k][i].first >> fields[k][i].second;\n        }\n    }\n    \n    vector<vector<double>> estimate(N, vector<double>(N, 0.0));\n    vector<vector<int>> drilled(N, vector<int>(N, -1));\n    \n    // Phase 1: Query entire grid multiple times for baseline\n    double total = 0;\n    int num_full = 30;\n    for (int q = 0; q < num_full; q++) {\n        vector<pair<int,int>> all;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                all.push_back({i, j});\n            }\n        }\n        total += query(all);\n    }\n    double avg_per_cell = total / (num_full * N * N);\n    \n    // Phase 2: Query rows and columns\n    vector<double> row_est(N), col_est(N);\n    for (int i = 0; i < N; i++) {\n        vector<pair<int,int>> row;\n        for (int j = 0; j < N; j++) row.push_back({i, j});\n        row_est[i] = query(row) / (double)N;\n    }\n    \n    for (int j = 0; j < N; j++) {\n        vector<pair<int,int>> col;\n        for (int i = 0; i < N; i++) col.push_back({i, j});\n        col_est[j] = query(col) / (double)N;\n    }\n    \n    // Combine estimates\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            estimate[i][j] = (row_est[i] + col_est[j]) / 2.0;\n        }\n    }\n    \n    // Phase 3: Query smaller blocks for refinement\n    int block_size = max(2, N/3);\n    for (int bi = 0; bi < N; bi += block_size) {\n        for (int bj = 0; bj < N; bj += block_size) {\n            vector<pair<int,int>> block;\n            for (int i = bi; i < min(N, bi+block_size); i++) {\n                for (int j = bj; j < min(N, bj+block_size); j++) {\n                    block.push_back({i, j});\n                }\n            }\n            if (block.size() >= 2) {\n                double block_avg = query(block) / (double)block.size();\n                for (auto [i, j] : block) {\n                    estimate[i][j] = (estimate[i][j] + block_avg) / 2.0;\n                }\n            }\n        }\n    }\n    \n    // Phase 4: Drill uncertain squares\n    set<pair<int,int>> has_oil;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (estimate[i][j] > 0.4 || query_count >= 600) {\n                int v = drill(i, j);\n                drilled[i][j] = v;\n                if (v > 0) has_oil.insert({i, j});\n            }\n        }\n    }\n    \n    // Make answer\n    if (!answer(has_oil)) {\n        // If wrong, drill remaining squares\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (drilled[i][j] < 0) {\n                    int v = drill(i, j);\n                    if (v > 0) has_oil.insert({i, j});\n                }\n            }\n        }\n        answer(has_oil);\n    }\n    \n    return 0;\n}","ahc031":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\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    auto compute_layout = [&](const vector<int>& areas, bool use_area_based = false) {\n        vector<int> heights(N);\n        long long total_height = 0;\n        long long total_area = 0;\n        \n        for (int k = 0; k < N; k++) {\n            heights[k] = max(1, (areas[k] + W - 1) / W);\n            total_height += heights[k];\n            total_area += areas[k];\n        }\n        \n        vector<int> row_pos(N + 1);\n        row_pos[0] = 0;\n        \n        if (total_height <= W) {\n            for (int k = 0; k < N; k++) {\n                row_pos[k + 1] = row_pos[k] + heights[k];\n            }\n        } else {\n            if (use_area_based && total_area > 0) {\n                long long cumsum = 0;\n                for (int k = 0; k < N; k++) {\n                    cumsum += areas[k];\n                    row_pos[k + 1] = (int)((cumsum * W) / total_area);\n                }\n            } else {\n                long long cumsum = 0;\n                for (int k = 0; k < N; k++) {\n                    cumsum += heights[k];\n                    row_pos[k + 1] = (int)((cumsum * W) / total_height);\n                }\n            }\n        }\n        \n        row_pos[N] = W;\n        \n        for (int k = 0; k < N; k++) {\n            if (row_pos[k + 1] <= row_pos[k]) {\n                row_pos[k + 1] = row_pos[k] + 1;\n            }\n        }\n        \n        return row_pos;\n    };\n    \n    auto calc_shortage = [&](const vector<int>& layout, const vector<int>& areas) {\n        long long shortage = 0;\n        for (int k = 0; k < N; k++) {\n            long long area = (long long)(layout[k + 1] - layout[k]) * W;\n            if (area < areas[k]) {\n                shortage += areas[k] - area;\n            }\n        }\n        return shortage;\n    };\n    \n    auto calc_partition_cost = [&](const vector<int>& layout1, const vector<int>& layout2) {\n        long long cost = 0;\n        for (int i = 1; i < N; i++) {\n            if (layout1[i] != layout2[i]) {\n                cost += W;\n            }\n        }\n        return cost;\n    };\n    \n    set<vector<int>> unique_layouts;\n    \n    // 1. Per-day layouts\n    for (int d = 0; d < D; d++) {\n        unique_layouts.insert(compute_layout(a[d], false));\n        unique_layouts.insert(compute_layout(a[d], true));\n    }\n    \n    // 2. Aggregated statistics\n    vector<int> max_areas(N), mean_areas(N), median_areas(N);\n    for (int k = 0; k < N; k++) {\n        long long sum = 0;\n        vector<int> vals;\n        for (int d = 0; d < D; d++) {\n            max_areas[k] = max(max_areas[k], a[d][k]);\n            sum += a[d][k];\n            vals.push_back(a[d][k]);\n        }\n        mean_areas[k] = (sum + D - 1) / D;\n        sort(vals.begin(), vals.end());\n        median_areas[k] = vals[D / 2];\n    }\n    unique_layouts.insert(compute_layout(max_areas, false));\n    unique_layouts.insert(compute_layout(max_areas, true));\n    unique_layouts.insert(compute_layout(mean_areas, false));\n    unique_layouts.insert(compute_layout(mean_areas, true));\n    unique_layouts.insert(compute_layout(median_areas, false));\n    unique_layouts.insert(compute_layout(median_areas, true));\n    \n    // 3. Fine percentiles\n    for (int p = 1; p <= 19; p++) {\n        double frac = p / 20.0;\n        vector<int> percentile_areas(N);\n        for (int k = 0; k < N; k++) {\n            vector<int> vals;\n            for (int d = 0; d < D; d++) vals.push_back(a[d][k]);\n            sort(vals.begin(), vals.end());\n            int idx = min((int)(frac * D), D - 1);\n            percentile_areas[k] = vals[idx];\n        }\n        unique_layouts.insert(compute_layout(percentile_areas, false));\n        unique_layouts.insert(compute_layout(percentile_areas, true));\n    }\n    \n    // 4. Overlapping windows with multiple sizes\n    for (int window = 2; window <= min(25, D); window++) {\n        int step = max(1, window / 4);\n        for (int start = 0; start <= D - window; start += step) {\n            vector<int> avg_areas(N), max_win_areas(N);\n            for (int k = 0; k < N; k++) {\n                long long sum = 0;\n                for (int d = start; d < start + window; d++) {\n                    sum += a[d][k];\n                    max_win_areas[k] = max(max_win_areas[k], a[d][k]);\n                }\n                avg_areas[k] = (sum + window - 1) / window;\n            }\n            unique_layouts.insert(compute_layout(avg_areas, false));\n            unique_layouts.insert(compute_layout(avg_areas, true));\n            unique_layouts.insert(compute_layout(max_win_areas, false));\n            unique_layouts.insert(compute_layout(max_win_areas, true));\n        }\n    }\n    \n    // 5. Exponentially weighted recent days\n    for (int center = 5; center < D - 5; center += 3) {\n        vector<int> weighted_areas(N);\n        for (int k = 0; k < N; k++) {\n            double total_weight = 0;\n            double weighted_sum = 0;\n            for (int d = 0; d < D; d++) {\n                double weight = exp(-abs(d - center) / 5.0);\n                weighted_sum += a[d][k] * weight;\n                total_weight += weight;\n            }\n            weighted_areas[k] = (int)((weighted_sum + total_weight - 1) / total_weight);\n        }\n        unique_layouts.insert(compute_layout(weighted_areas, false));\n        unique_layouts.insert(compute_layout(weighted_areas, true));\n    }\n    \n    vector<vector<int>> candidates(unique_layouts.begin(), unique_layouts.end());\n    int K = candidates.size();\n    \n    // DP\n    vector<vector<long long>> dp(D, vector<long long>(K, 1e18));\n    vector<vector<int>> parent(D, vector<int>(K, -1));\n    \n    for (int k = 0; k < K; k++) {\n        dp[0][k] = 100 * calc_shortage(candidates[k], a[0]);\n    }\n    \n    for (int d = 1; d < D; d++) {\n        for (int k = 0; k < K; k++) {\n            long long shortage_cost = 100 * calc_shortage(candidates[k], a[d]);\n            \n            for (int prev_k = 0; prev_k < K; prev_k++) {\n                long long partition_cost = (prev_k == k) ? 0 : calc_partition_cost(candidates[prev_k], candidates[k]);\n                long long total = dp[d-1][prev_k] + shortage_cost + partition_cost;\n                \n                if (total < dp[d][k]) {\n                    dp[d][k] = total;\n                    parent[d][k] = prev_k;\n                }\n            }\n        }\n    }\n    \n    int best_k = 0;\n    for (int k = 1; k < K; k++) {\n        if (dp[D-1][k] < dp[D-1][best_k]) {\n            best_k = k;\n        }\n    }\n    \n    vector<int> chosen(D);\n    chosen[D-1] = best_k;\n    for (int d = D-1; d > 0; d--) {\n        chosen[d-1] = parent[d][chosen[d]];\n    }\n    \n    // Output\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << candidates[chosen[d]][k] << \" 0 \" << candidates[chosen[d]][k + 1] << \" \" << W << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353LL;\nconst int N = 9;\nconst int M = 20;\nconst int K = 81;\n\nlong long board[N][N];\nlong long stamps[M][3][3];\n\ndouble evaluate_stamp_score(int m, int p, int q, int operation_num) {\n    double score = 0.0;\n    int wraparounds = 0;\n    long long raw_improvement = 0;\n    \n    double progress = (double)operation_num / K;\n    \n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            int row = p + i;\n            int col = q + j;\n            long long remainder = board[row][col] % MOD;\n            long long stamp_val = stamps[m][i][j];\n            long long new_remainder = (remainder + stamp_val) % MOD;\n            long long improvement = new_remainder - remainder;\n            \n            raw_improvement += improvement;\n            \n            double cell_score = (double)improvement;\n            \n            // Gap-based multiplier\n            long long gap = (MOD - 1) - remainder;\n            double gap_ratio = (double)gap / (double)MOD;\n            \n            if (remainder + stamp_val < MOD) {\n                // No wraparound - apply gap-based boost\n                if (gap_ratio > 0.65) {\n                    cell_score *= 1.9;\n                } else if (gap_ratio > 0.45) {\n                    cell_score *= 1.6;\n                } else if (gap_ratio > 0.3) {\n                    cell_score *= 1.4;\n                } else if (gap_ratio > 0.15) {\n                    cell_score *= 1.2;\n                }\n            } else {\n                // Wraparound - adaptive penalty based on progress\n                wraparounds++;\n                \n                if (progress < 0.3) {\n                    // Early: moderate penalty\n                    cell_score *= 0.4;\n                } else if (progress < 0.6) {\n                    // Middle: lighter penalty\n                    cell_score *= 0.6;\n                } else {\n                    // Late: very light penalty (we need to use operations)\n                    cell_score *= 0.8;\n                }\n            }\n            \n            score += cell_score;\n        }\n    }\n    \n    // Wraparound penalty - but not too harsh\n    if (wraparounds >= 6) {\n        score *= 0.7;\n    } else if (wraparounds >= 4) {\n        score *= 0.85;\n    }\n    \n    // In late game, if raw improvement is positive, boost score\n    if (progress > 0.7 && raw_improvement > 0) {\n        score *= 1.1;\n    }\n    \n    return score;\n}\n\nvoid apply_stamp(int m, int p, int q) {\n    for (int i = 0; i < 3; i++) {\n        for (int j = 0; j < 3; j++) {\n            board[p + i][q + j] += stamps[m][i][j];\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 < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    for (int stamp = 0; stamp < M; stamp++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[stamp][i][j];\n            }\n        }\n    }\n    \n    vector<tuple<int, int, int>> operations;\n    \n    for (int op = 0; op < K; op++) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        double best_score = -1e18;\n        \n        for (int stamp = 0; stamp < M; stamp++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    double score = evaluate_stamp_score(stamp, p, q, op);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_m = stamp;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // More lenient stopping - only stop if very negative\n        // In late game, be even more lenient\n        double threshold = (op > K * 0.8) ? -MOD * 0.5 : -MOD * 1.5;\n        \n        if (best_score < threshold) {\n            break;\n        }\n        \n        apply_stamp(best_m, best_p, best_q);\n        operations.push_back({best_m, best_p, best_q});\n    }\n    \n    cout << operations.size() << endl;\n    for (auto [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << endl;\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nint A[N][N];\n\nint main() {\n    int n;\n    cin >> n;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    int grid[N][N];\n    memset(grid, -1, sizeof(grid));\n    \n    pair<int,int> crane_pos = {0, 0};\n    int crane_carry = -1;\n    int next_container[N];\n    int next_to_dispatch[N]; // Track next expected container for each dispatch row\n    \n    for (int i = 0; i < N; i++) {\n        next_container[i] = 0;\n        next_to_dispatch[i] = N * i; // Row i expects N*i, N*i+1, ...\n    }\n    \n    vector<string> commands(N, \"B\");\n    commands[0] = \"\";\n    \n    auto get_new_pos = [](pair<int,int> pos, char action) -> pair<int,int> {\n        if (action == 'U') pos.first--;\n        else if (action == 'D') pos.first++;\n        else if (action == 'L') pos.second--;\n        else if (action == 'R') pos.second++;\n        return pos;\n    };\n    \n    for (int turn = 0; turn < 5000; turn++) {\n        // Step 1: Place containers\n        for (int i = 0; i < N; i++) {\n            if (next_container[i] < N && grid[i][0] == -1) {\n                bool blocked = (crane_pos == make_pair(i, 0) && crane_carry != -1);\n                if (!blocked) {\n                    grid[i][0] = A[i][next_container[i]];\n                    next_container[i]++;\n                }\n            }\n        }\n        \n        // Step 2: Plan action\n        char action = '.';\n        auto [r, c] = crane_pos;\n        \n        if (crane_carry == -1) {\n            if (grid[r][c] != -1) {\n                action = 'P';\n            } else {\n                // Find best container based on dispatch sequence\n                int best_score = 1000000;\n                int best_r = -1, best_c = -1;\n                \n                for (int i = 0; i < N; i++) {\n                    for (int j = 0; j < N; j++) {\n                        if (grid[i][j] != -1) {\n                            int container_num = grid[i][j];\n                            int target_row = container_num / N;\n                            int physical_dist = abs(r - i) + abs(c - j);\n                            \n                            // Priority: how far is this from being \"next\" in sequence?\n                            int sequence_dist = container_num - next_to_dispatch[target_row];\n                            \n                            // Strongly prefer containers that are next or close to next\n                            // Weight sequence much higher than physical distance\n                            int score = sequence_dist * 100 + physical_dist;\n                            \n                            if (score < best_score) {\n                                best_score = score;\n                                best_r = i;\n                                best_c = j;\n                            }\n                        }\n                    }\n                }\n                \n                if (best_r != -1) {\n                    if (r != best_r) {\n                        action = (r < best_r) ? 'D' : 'U';\n                    } else if (c != best_c) {\n                        action = (c < best_c) ? 'R' : 'L';\n                    }\n                }\n            }\n        } else {\n            // Carrying - deliver\n            int container = crane_carry;\n            int target_r = container / N;\n            \n            if (r != target_r) {\n                action = (r < target_r) ? 'D' : 'U';\n            } else if (c < N-1) {\n                action = 'R';\n            } else {\n                action = 'Q';\n            }\n        }\n        \n        commands[0] += action;\n        \n        // Step 3: Apply action\n        if (action == 'P') {\n            crane_carry = grid[r][c];\n            grid[r][c] = -1;\n        } else if (action == 'Q') {\n            grid[r][c] = crane_carry;\n            crane_carry = -1;\n        } else if (action != '.') {\n            crane_pos = get_new_pos(crane_pos, action);\n        }\n        \n        // Step 4: Dispatch and update tracking\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                int dispatched = grid[i][N-1];\n                int target_row = dispatched / N;\n                \n                // Update next expected if this was dispatched correctly\n                if (target_row == i && dispatched == next_to_dispatch[i]) {\n                    next_to_dispatch[i]++;\n                }\n                \n                grid[i][N-1] = -1;\n            }\n        }\n        \n        // Check if done\n        bool all_done = true;\n        for (int i = 0; i < N; i++) {\n            if (next_container[i] < N || crane_carry != -1) {\n                all_done = false;\n            }\n        }\n        if (all_done) {\n            bool has_containers = false;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (grid[i][j] != -1) has_containers = true;\n                }\n            }\n            if (!has_containers) break;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << commands[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<vector<int>> h;\nvector<string> operations;\nint cur_r = 0, cur_c = 0;\nint load = 0;\n\nint manhattan(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\nvoid moveTo(int tr, int tc) {\n    while (cur_r < tr && operations.size() < 99000) {\n        operations.push_back(\"D\");\n        cur_r++;\n    }\n    while (cur_r > tr && operations.size() < 99000) {\n        operations.push_back(\"U\");\n        cur_r--;\n    }\n    while (cur_c < tc && operations.size() < 99000) {\n        operations.push_back(\"R\");\n        cur_c++;\n    }\n    while (cur_c > tc && operations.size() < 99000) {\n        operations.push_back(\"L\");\n        cur_c--;\n    }\n}\n\n// Check if there's a nearby positive cell within radius r\nbool hasNearbyPositive(int row, int col, int r) {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (h[i][j] > 0 && manhattan(row, col, i, j) <= r) {\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nint main() {\n    cin >> N;\n    h.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> h[i][j];\n        }\n    }\n    \n    while (operations.size() < 95000) {\n        if (load == 0) {\n            // Find nearest positive cell\n            int pos_r = -1, pos_c = -1;\n            int min_dist = INT_MAX;\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 = manhattan(cur_r, cur_c, i, j);\n                        if (dist < min_dist) {\n                            min_dist = dist;\n                            pos_r = i;\n                            pos_c = j;\n                        }\n                    }\n                }\n            }\n            \n            if (pos_r == -1) break;\n            \n            // Move to positive cell\n            moveTo(pos_r, pos_c);\n            if (operations.size() >= 95000) break;\n            \n            // Load from it\n            int amt = h[pos_r][pos_c];\n            operations.push_back(\"+\" + to_string(amt));\n            load += amt;\n            h[pos_r][pos_c] = 0;\n            \n            // Opportunistically load from nearby positive cells (cluster processing)\n            for (int radius = 1; radius <= 3 && operations.size() < 94000; radius++) {\n                bool found = false;\n                for (int i = 0; i < N; i++) {\n                    for (int j = 0; j < N; j++) {\n                        if (h[i][j] > 0 && manhattan(cur_r, cur_c, i, j) == radius) {\n                            // Move to this nearby positive cell\n                            moveTo(i, j);\n                            if (operations.size() >= 94000) break;\n                            \n                            amt = h[i][j];\n                            operations.push_back(\"+\" + to_string(amt));\n                            load += amt;\n                            h[i][j] = 0;\n                            found = true;\n                            break;\n                        }\n                    }\n                    if (found) break;\n                }\n                if (!found) break; // No more cells at this radius\n            }\n            \n        } else {\n            // Deliver using greedy approach\n            int neg_r = -1, neg_c = -1;\n            long long best_score = LLONG_MAX;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (h[i][j] < 0) {\n                        int dist = manhattan(cur_r, cur_c, i, j);\n                        int can_deliver = min(load, -h[i][j]);\n                        long long score = (long long)dist * 100 - can_deliver;\n                        \n                        if (score < best_score) {\n                            best_score = score;\n                            neg_r = i;\n                            neg_c = j;\n                        }\n                    }\n                }\n            }\n            \n            if (neg_r == -1) break;\n            \n            moveTo(neg_r, neg_c);\n            if (operations.size() >= 95000) break;\n            \n            int amt = min(load, -h[neg_r][neg_c]);\n            operations.push_back(\"-\" + to_string(amt));\n            load -= amt;\n            h[neg_r][neg_c] += amt;\n        }\n    }\n    \n    for (const auto& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <set>\n#include <queue>\n#include <map>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> X(seed_count, vector<int>(M));\n    \n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> X[i][j];\n        }\n    }\n    \n    for (int t = 0; t < T; t++) {\n        // Find max for each criterion\n        vector<int> max_val(M, 0);\n        for (int l = 0; l < M; l++) {\n            for (int i = 0; i < seed_count; i++) {\n                max_val[l] = max(max_val[l], X[i][l]);\n            }\n        }\n        \n        // 88% threshold\n        vector<int> near_max_count(M, 0);\n        for (int l = 0; l < M; l++) {\n            int threshold = max_val[l] * 88 / 100;\n            for (int i = 0; i < seed_count; i++) {\n                if (X[i][l] >= threshold) {\n                    near_max_count[l]++;\n                }\n            }\n        }\n        \n        // Must-include: top 3 for each criterion\n        set<int> must_include;\n        for (int l = 0; l < M; l++) {\n            vector<pair<int, int>> vals;\n            for (int i = 0; i < seed_count; i++) {\n                vals.push_back({X[i][l], i});\n            }\n            sort(vals.rbegin(), vals.rend());\n            for (int i = 0; i < min(3, (int)vals.size()); i++) {\n                must_include.insert(vals[i].second);\n            }\n        }\n        \n        // Score remaining seeds\n        vector<pair<double, int>> seed_scores;\n        for (int i = 0; i < seed_count; i++) {\n            if (must_include.count(i)) continue;\n            \n            int total = accumulate(X[i].begin(), X[i].end(), 0);\n            double score = total;\n            \n            for (int l = 0; l < M; l++) {\n                if (max_val[l] > 0 && X[i][l] >= max_val[l] * 88 / 100) {\n                    if (near_max_count[l] <= 3) {\n                        score += 600.0 / (near_max_count[l] + 1);\n                    } else if (near_max_count[l] <= 6) {\n                        score += 200.0 / near_max_count[l];\n                    } else {\n                        score += 50.0;\n                    }\n                }\n            }\n            \n            seed_scores.push_back({score, i});\n        }\n        sort(seed_scores.rbegin(), seed_scores.rend());\n        \n        // Combine must-include and scored seeds\n        set<int> selected;\n        for (int s : must_include) {\n            selected.insert(s);\n        }\n        for (auto [score, s] : seed_scores) {\n            if (selected.size() >= N * N) break;\n            selected.insert(s);\n        }\n        \n        vector<int> selected_vec(selected.begin(), selected.end());\n        \n        // Rarity-first sorting with fine-tuned value weight\n        sort(selected_vec.begin(), selected_vec.end(), [&](int a, int b) {\n            double score_a = 0, score_b = 0;\n            for (int l = 0; l < M; l++) {\n                if (max_val[l] > 0 && X[a][l] >= max_val[l] * 88 / 100) {\n                    score_a += 1000.0 / (near_max_count[l] + 1);\n                }\n                if (max_val[l] > 0 && X[b][l] >= max_val[l] * 88 / 100) {\n                    score_b += 1000.0 / (near_max_count[l] + 1);\n                }\n            }\n            // Middle ground: 0.23 (between 0.22 and 0.24)\n            score_a += accumulate(X[a].begin(), X[a].end(), 0) * 0.23;\n            score_b += accumulate(X[b].begin(), X[b].end(), 0) * 0.23;\n            return score_a > score_b;\n        });\n        \n        // Identify seed specialties\n        vector<set<int>> specialties(seed_count);\n        for (int i : selected_vec) {\n            for (int l = 0; l < M; l++) {\n                if (max_val[l] > 0 && X[i][l] >= max_val[l] * 88 / 100) {\n                    specialties[i].insert(l);\n                }\n            }\n        }\n        \n        // Placement with proven neighbor bonus\n        vector<vector<int>> A(N, vector<int>(N, -1));\n        set<int> placed;\n        \n        A[N/2][N/2] = selected_vec[0];\n        placed.insert(selected_vec[0]);\n        \n        queue<pair<int,int>> q;\n        q.push({N/2, N/2});\n        vector<vector<bool>> visited(N, vector<bool>(N, false));\n        visited[N/2][N/2] = true;\n        \n        int dx[] = {-1, 1, 0, 0};\n        int dy[] = {0, 0, -1, 1};\n        \n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                \n                if (nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny]) {\n                    visited[nx][ny] = true;\n                    q.push({nx, ny});\n                    \n                    int best_seed = -1;\n                    double best_score = -1e9;\n                    \n                    for (int s : selected_vec) {\n                        if (placed.count(s)) continue;\n                        \n                        double comp_score = accumulate(X[s].begin(), X[s].end(), 0);\n                        \n                        map<int, int> neighbor_max;\n                        int neighbor_count = 0;\n                        for (int dd = 0; dd < 4; dd++) {\n                            int nnx = nx + dx[dd];\n                            int nny = ny + dy[dd];\n                            if (nnx >= 0 && nnx < N && nny >= 0 && nny < N && A[nnx][nny] != -1) {\n                                neighbor_count++;\n                                int ns = A[nnx][nny];\n                                for (int l = 0; l < M; l++) {\n                                    if (X[ns][l] >= max_val[l] * 88 / 100) {\n                                        neighbor_max[l] = max(neighbor_max[l], X[ns][l]);\n                                    }\n                                }\n                            }\n                        }\n                        \n                        // Proven complementarity formula\n                        for (int l : specialties[s]) {\n                            if (neighbor_max.find(l) == neighbor_max.end()) {\n                                comp_score += 200;\n                                if (near_max_count[l] <= 3) {\n                                    comp_score += 150;\n                                } else if (near_max_count[l] <= 6) {\n                                    comp_score += 80;\n                                }\n                            } else if (X[s][l] > neighbor_max[l]) {\n                                comp_score += 40;\n                            }\n                        }\n                        \n                        // Keep proven value: 12\n                        comp_score += neighbor_count * 12;\n                        \n                        if (comp_score > best_score) {\n                            best_score = comp_score;\n                            best_seed = s;\n                        }\n                    }\n                    \n                    if (best_seed != -1) {\n                        A[nx][ny] = best_seed;\n                        placed.insert(best_seed);\n                    }\n                }\n            }\n        }\n        \n        // Fill remaining positions\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (A[i][j] == -1) {\n                    for (int s : selected_vec) {\n                        if (!placed.count(s)) {\n                            A[i][j] = s;\n                            placed.insert(s);\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Output\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << A[i][j];\n                if (j < N - 1) cout << \" \";\n                else cout << endl;\n            }\n        }\n        cout.flush();\n        \n        // Read new seeds\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    }\n    \n    return 0;\n}","ahc038":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M, V;\nvector<vector<int>> grid_current;\nvector<vector<int>> grid_target;\n\nint dx[] = {0, 1, 0, -1};\nint dy[] = {1, 0, -1, 0};\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nstruct State {\n    int root_x, root_y;\n    int edge_dir;\n    bool holding;\n    int arm_length;\n    \n    pair<int,int> get_leaf() {\n        return {root_x + dx[edge_dir] * arm_length, root_y + dy[edge_dir] * arm_length};\n    }\n    \n    string make_cmd(char move, char rot, char action) {\n        string s = \"....\";\n        s[0] = move;\n        s[1] = rot;\n        s[3] = action;\n        return s;\n    }\n};\n\nvoid move_root_to(State& state, int tx, int ty, vector<string>& cmds) {\n    while ((state.root_x != tx || state.root_y != ty) && cmds.size() < 95000) {\n        char move = '.';\n        \n        if (state.root_x < tx && state.root_x + 1 < N) {\n            move = 'D';\n            state.root_x++;\n        } else if (state.root_x > tx && state.root_x > 0) {\n            move = 'U';\n            state.root_x--;\n        } else if (state.root_y < ty && state.root_y + 1 < N) {\n            move = 'R';\n            state.root_y++;\n        } else if (state.root_y > ty && state.root_y > 0) {\n            move = 'L';\n            state.root_y--;\n        } else {\n            break;\n        }\n        \n        cmds.push_back(state.make_cmd(move, '.', '.'));\n    }\n}\n\nvoid rotate_to_dir(State& state, int target_dir, vector<string>& cmds) {\n    while (state.edge_dir != target_dir && cmds.size() < 95000) {\n        int diff = (target_dir - state.edge_dir + 4) % 4;\n        \n        if (diff == 1) {\n            state.edge_dir = (state.edge_dir + 1) % 4;\n            cmds.push_back(state.make_cmd('.', 'R', '.'));\n        } else if (diff == 3) {\n            state.edge_dir = (state.edge_dir + 3) % 4;\n            cmds.push_back(state.make_cmd('.', 'L', '.'));\n        } else if (diff == 2) {\n            state.edge_dir = (state.edge_dir + 1) % 4;\n            cmds.push_back(state.make_cmd('.', 'R', '.'));\n        } else {\n            break;\n        }\n    }\n}\n\nbool reach_position(State& state, int tx, int ty, vector<string>& cmds) {\n    vector<tuple<int,int,int,int>> candidates;\n    \n    for (int d = 0; d < 4; d++) {\n        int rx = tx - dx[d] * state.arm_length;\n        int ry = ty - dy[d] * state.arm_length;\n        if (in_bounds(rx, ry)) {\n            int move_dist = abs(state.root_x - rx) + abs(state.root_y - ry);\n            int rot_diff = (d - state.edge_dir + 4) % 4;\n            int rot_cost = min(rot_diff, 4 - rot_diff);\n            candidates.push_back({rx, ry, d, move_dist + rot_cost});\n        }\n    }\n    \n    if (candidates.empty()) return false;\n    \n    sort(candidates.begin(), candidates.end(), [](auto& a, auto& b) {\n        return get<3>(a) < get<3>(b);\n    });\n    \n    auto [rx, ry, needed_dir, _] = candidates[0];\n    \n    move_root_to(state, rx, ry, cmds);\n    rotate_to_dir(state, needed_dir, cmds);\n    \n    auto [lx, ly] = state.get_leaf();\n    return (lx == tx && ly == ty && in_bounds(lx, ly));\n}\n\nint calc_tour_cost(const vector<pair<pair<int,int>, pair<int,int>>>& tour, int arm_len) {\n    if (tour.empty()) return 0;\n    int cost = tour[0].first.first + tour[0].first.second;\n    for (int i = 0; i < tour.size(); i++) {\n        // Cost for pickup + move to target + place\n        cost += abs(tour[i].first.first - tour[i].second.first) + \n                abs(tour[i].first.second - tour[i].second.second);\n        // Add rotation cost estimate\n        cost += 2; // Approximate rotation cost\n        \n        if (i + 1 < tour.size()) {\n            cost += abs(tour[i].second.first - tour[i+1].first.first) +\n                    abs(tour[i].second.second - tour[i+1].first.second);\n        }\n    }\n    // Factor in arm length benefit (longer arms save moves)\n    cost = cost * 10 / (10 + arm_len);\n    return cost;\n}\n\nvoid improve_2opt(vector<pair<pair<int,int>, pair<int,int>>>& tour) {\n    bool improved = true;\n    for (int iter = 0; iter < 200 && improved; iter++) {\n        improved = false;\n        for (int i = 0; i < (int)tour.size() - 1; i++) {\n            for (int j = i + 2; j < tour.size(); j++) {\n                int cost_before = 0, cost_after = 0;\n                \n                cost_before += abs(tour[i].second.first - tour[i+1].first.first) +\n                              abs(tour[i].second.second - tour[i+1].first.second);\n                if (j + 1 < tour.size()) {\n                    cost_before += abs(tour[j].second.first - tour[j+1].first.first) +\n                                  abs(tour[j].second.second - tour[j+1].first.second);\n                }\n                \n                cost_after += abs(tour[i].second.first - tour[j].first.first) +\n                             abs(tour[i].second.second - tour[j].first.second);\n                if (j + 1 < tour.size()) {\n                    cost_after += abs(tour[i+1].second.first - tour[j+1].first.first) +\n                                 abs(tour[i+1].second.second - tour[j+1].first.second);\n                }\n                \n                if (cost_after < cost_before) {\n                    reverse(tour.begin() + i + 1, tour.begin() + j + 1);\n                    improved = true;\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    cin >> N >> M >> V;\n    \n    grid_current.resize(N, vector<int>(N, 0));\n    grid_target.resize(N, vector<int>(N, 0));\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            grid_current[i][j] = (s[j] == '1');\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            grid_target[i][j] = (s[j] == '1');\n        }\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_current[i][j] && !grid_target[i][j]) {\n                sources.push_back({i, j});\n            }\n            if (grid_target[i][j] && !grid_current[i][j]) {\n                targets.push_back({i, j});\n            }\n        }\n    }\n    \n    // Greedy assignment\n    vector<pair<pair<int,int>, pair<int,int>>> tasks;\n    set<int> used_targets;\n    \n    for (auto src : sources) {\n        int best_idx = -1;\n        int best_dist = INT_MAX;\n        \n        for (int i = 0; i < targets.size(); i++) {\n            if (used_targets.count(i)) continue;\n            int d = abs(src.first - targets[i].first) + abs(src.second - targets[i].second);\n            if (d < best_dist) {\n                best_dist = d;\n                best_idx = i;\n            }\n        }\n        \n        if (best_idx != -1) {\n            tasks.push_back({src, targets[best_idx]});\n            used_targets.insert(best_idx);\n        }\n    }\n    \n    // Try different arm lengths to find best\n    int best_overall_arm = max(1, min((N + 3) / 4, N - 1));\n    int best_overall_cost = INT_MAX;\n    vector<pair<pair<int,int>, pair<int,int>>> best_overall_tour;\n    \n    for (int arm_len_trial : {max(1, (N+2)/4), max(1, (N+3)/4), max(1, (N+4)/4)}) {\n        if (arm_len_trial >= N) continue;\n        \n        vector<pair<pair<int,int>, pair<int,int>>> best_tour;\n        int best_cost = INT_MAX;\n        \n        int num_trials = 20;\n        for (int start_trial = 0; start_trial < num_trials; start_trial++) {\n            vector<pair<pair<int,int>, pair<int,int>>> tour;\n            vector<bool> used(tasks.size(), false);\n            \n            int current = start_trial % tasks.size();\n            tour.push_back(tasks[current]);\n            used[current] = true;\n            auto last = tasks[current].second;\n            \n            while (tour.size() < tasks.size()) {\n                int next = -1;\n                int min_dist = INT_MAX;\n                \n                for (int i = 0; i < tasks.size(); i++) {\n                    if (used[i]) continue;\n                    int d = abs(tasks[i].first.first - last.first) + \n                           abs(tasks[i].first.second - last.second);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        next = i;\n                    }\n                }\n                \n                if (next == -1) break;\n                tour.push_back(tasks[next]);\n                used[next] = true;\n                last = tasks[next].second;\n            }\n            \n            improve_2opt(tour);\n            \n            int cost = calc_tour_cost(tour, arm_len_trial);\n            if (cost < best_cost) {\n                best_cost = cost;\n                best_tour = tour;\n            }\n        }\n        \n        if (best_cost < best_overall_cost) {\n            best_overall_cost = best_cost;\n            best_overall_tour = best_tour;\n            best_overall_arm = arm_len_trial;\n        }\n    }\n    \n    tasks = best_overall_tour;\n    \n    State state;\n    state.arm_length = best_overall_arm;\n    \n    state.root_x = 0;\n    state.root_y = 0;\n    if (!tasks.empty()) {\n        state.root_x = max(0, min(N-1, tasks[0].first.first - state.arm_length));\n        state.root_y = max(0, min(N-1, tasks[0].first.second));\n    }\n    \n    state.edge_dir = 0;\n    state.holding = false;\n    \n    cout << \"2\\n\";\n    cout << \"0 \" << state.arm_length << \"\\n\";\n    cout << state.root_x << \" \" << state.root_y << \"\\n\";\n    \n    vector<string> cmds;\n    \n    for (auto [src, tgt] : tasks) {\n        if (cmds.size() >= 90000) break;\n        \n        if (reach_position(state, src.first, src.second, cmds)) {\n            auto [lx, ly] = state.get_leaf();\n            if (lx == src.first && ly == src.second && grid_current[lx][ly]) {\n                cmds.push_back(state.make_cmd('.', '.', 'P'));\n                state.holding = true;\n                grid_current[lx][ly] = 0;\n                \n                if (reach_position(state, tgt.first, tgt.second, cmds)) {\n                    auto [lx2, ly2] = state.get_leaf();\n                    if (lx2 == tgt.first && ly2 == tgt.second && !grid_current[lx2][ly2]) {\n                        cmds.push_back(state.make_cmd('.', '.', 'P'));\n                        state.holding = false;\n                        grid_current[lx2][ly2] = 1;\n                    }\n                }\n            }\n        }\n    }\n    \n    for (const auto& cmd : cmds) {\n        cout << cmd << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint N;\nvector<pair<int,int>> mackerels, sardines;\n\nint calcScore(int x1, int y1, int x2, int y2) {\n    if (x1 > x2) swap(x1, x2);\n    if (y1 > y2) swap(y1, y2);\n    \n    int mac = 0, sar = 0;\n    for (auto [x, y] : mackerels) {\n        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) mac++;\n    }\n    for (auto [x, y] : sardines) {\n        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) sar++;\n    }\n    return mac - sar;\n}\n\nvoid tryUpdate(int x1, int y1, int x2, int y2, int& bestScore, int& bx1, int& by1, int& bx2, int& by2) {\n    int score = calcScore(x1, y1, x2, y2);\n    if (score > bestScore) {\n        bestScore = score;\n        bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n    }\n}\n\n// Simulated annealing - keep it stable with proven parameters\nvoid multiStartSA(int& bx1, int& by1, int& bx2, int& by2, int& bestScore, mt19937& rng) {\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    uniform_int_distribution<int> delta_dist(-6000, 6000);\n    uniform_int_distribution<int> side_dist(0, 3);\n    \n    // 3 restarts - sweet spot from Version 8\n    for (int restart = 0; restart < 3; restart++) {\n        int x1 = bx1, x2 = bx2, y1 = by1, y2 = by2;\n        int currentScore = bestScore;\n        \n        double temperature = 1000.0 + restart * 300;\n        const double cooling = 0.97;\n        \n        for (int iter = 0; iter < 400; iter++) {\n            int side = side_dist(rng);\n            int delta = delta_dist(rng);\n            \n            int nx1 = x1, nx2 = x2, ny1 = y1, ny2 = y2;\n            \n            if (side == 0) nx1 = max(0, min(100000, x1 + delta));\n            else if (side == 1) nx2 = max(0, min(100000, x2 + delta));\n            else if (side == 2) ny1 = max(0, min(100000, y1 + delta));\n            else ny2 = max(0, min(100000, y2 + delta));\n            \n            int newScore = calcScore(nx1, ny1, nx2, ny2);\n            \n            if (newScore > currentScore || prob_dist(rng) < exp((newScore - currentScore) / temperature)) {\n                x1 = nx1; x2 = nx2; y1 = ny1; y2 = ny2;\n                currentScore = newScore;\n                \n                if (currentScore > bestScore) {\n                    bestScore = currentScore;\n                    bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n                }\n            }\n            \n            temperature *= cooling;\n        }\n    }\n}\n\n// Fine-grained local search\nvoid fineLocalSearch(int& bx1, int& by1, int& bx2, int& by2, int& bestScore) {\n    for (int iterations = 0; iterations < 25; iterations++) {\n        bool improved = false;\n        \n        for (int delta : {-3000, -1500, -700, -300, -150, -70, -30, -15, -7, -3, -1, \n                          1, 3, 7, 15, 30, 70, 150, 300, 700, 1500, 3000}) {\n            int nx1 = max(0, min(100000, bx1 + delta));\n            if (nx1 != bx1) {\n                int score = calcScore(nx1, by1, bx2, by2);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bx1 = nx1;\n                    improved = true;\n                }\n            }\n            \n            int nx2 = max(0, min(100000, bx2 + delta));\n            if (nx2 != bx2) {\n                int score = calcScore(bx1, by1, nx2, by2);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bx2 = nx2;\n                    improved = true;\n                }\n            }\n            \n            int ny1 = max(0, min(100000, by1 + delta));\n            if (ny1 != by1) {\n                int score = calcScore(bx1, ny1, bx2, by2);\n                if (score > bestScore) {\n                    bestScore = score;\n                    by1 = ny1;\n                    improved = true;\n                }\n            }\n            \n            int ny2 = max(0, min(100000, by2 + delta));\n            if (ny2 != by2) {\n                int score = calcScore(bx1, by1, bx2, ny2);\n                if (score > bestScore) {\n                    bestScore = score;\n                    by2 = ny2;\n                    improved = true;\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n}\n\n// Density-based search\nvoid densitySearch(int& bestScore, int& bx1, int& by1, int& bx2, int& by2) {\n    const int GRID = 5000;\n    const int CELLS = 21;\n    \n    vector<vector<int>> density(CELLS, vector<int>(CELLS, 0));\n    \n    for (auto [x, y] : mackerels) {\n        density[x / GRID][y / GRID]++;\n    }\n    \n    vector<pair<int, pair<int,int>>> cells;\n    for (int i = 0; i < CELLS; i++) {\n        for (int j = 0; j < CELLS; j++) {\n            if (density[i][j] > 0) {\n                cells.push_back({density[i][j], {i, j}});\n            }\n        }\n    }\n    \n    sort(cells.rbegin(), cells.rend());\n    \n    for (int k = 0; k < min(55, (int)cells.size()); k++) {\n        int ci = cells[k].second.first;\n        int cj = cells[k].second.second;\n        \n        int cx = ci * GRID + GRID / 2;\n        int cy = cj * GRID + GRID / 2;\n        \n        for (int sz : {800, 1600, 2800, 4200, 6000, 8500, 11500, 15000, 19000, 24000, 30000}) {\n            tryUpdate(max(0, cx - sz), max(0, cy - sz), \n                     min(100000, cx + sz), min(100000, cy + sz),\n                     bestScore, bx1, by1, bx2, by2);\n        }\n    }\n}\n\n// Enhanced greedy expansion\nvoid greedyExpand(int& bestScore, int& bx1, int& by1, int& bx2, int& by2, mt19937& rng) {\n    uniform_int_distribution<int> dist(0, N-1);\n    \n    for (int trial = 0; trial < 30; trial++) {\n        auto [sx, sy] = mackerels[dist(rng)];\n        \n        int x1 = sx, x2 = sx, y1 = sy, y2 = sy;\n        int current_score = 1;\n        \n        for (int step = 0; step < 60; step++) {\n            int best_score = current_score;\n            int best_dir = -1, best_amt = 0;\n            \n            for (int dir = 0; dir < 4; dir++) {\n                for (int amt : {150, 400, 900, 1800, 3200, 5500, 9000, 14000, 20000}) {\n                    int nx1 = x1, nx2 = x2, ny1 = y1, ny2 = y2;\n                    \n                    if (dir == 0) nx1 = max(0, x1 - amt);\n                    else if (dir == 1) nx2 = min(100000, x2 + amt);\n                    else if (dir == 2) ny1 = max(0, y1 - amt);\n                    else ny2 = min(100000, y2 + amt);\n                    \n                    int score = calcScore(nx1, ny1, nx2, ny2);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = dir;\n                        best_amt = amt;\n                    }\n                }\n            }\n            \n            if (best_dir == -1) break;\n            \n            if (best_dir == 0) x1 = max(0, x1 - best_amt);\n            else if (best_dir == 1) x2 = min(100000, x2 + best_amt);\n            else if (best_dir == 2) y1 = max(0, y1 - best_amt);\n            else y2 = min(100000, y2 + best_amt);\n            \n            current_score = best_score;\n        }\n        \n        if (current_score > bestScore) {\n            bestScore = current_score;\n            bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n        }\n    }\n    \n    // From density centers\n    const int GRID = 5000, CELLS = 21;\n    vector<vector<int>> density(CELLS, vector<int>(CELLS, 0));\n    for (auto [x, y] : mackerels) {\n        density[x / GRID][y / GRID]++;\n    }\n    \n    vector<pair<int, pair<int,int>>> cells;\n    for (int i = 0; i < CELLS; i++) {\n        for (int j = 0; j < CELLS; j++) {\n            if (density[i][j] > 0) {\n                cells.push_back({density[i][j], {i, j}});\n            }\n        }\n    }\n    sort(cells.rbegin(), cells.rend());\n    \n    for (int k = 0; k < min(12, (int)cells.size()); k++) {\n        int sx = cells[k].second.first * GRID + GRID/2;\n        int sy = cells[k].second.second * GRID + GRID/2;\n        \n        int x1 = sx, x2 = sx, y1 = sy, y2 = sy;\n        int current_score = calcScore(x1, y1, x2, y2);\n        \n        for (int step = 0; step < 55; step++) {\n            int best_score = current_score;\n            int best_dir = -1, best_amt = 0;\n            \n            for (int dir = 0; dir < 4; dir++) {\n                for (int amt : {120, 350, 850, 1800, 3500, 6500, 11000, 18000}) {\n                    int nx1 = x1, nx2 = x2, ny1 = y1, ny2 = y2;\n                    \n                    if (dir == 0) nx1 = max(0, x1 - amt);\n                    else if (dir == 1) nx2 = min(100000, x2 + amt);\n                    else if (dir == 2) ny1 = max(0, y1 - amt);\n                    else ny2 = min(100000, y2 + amt);\n                    \n                    int score = calcScore(nx1, ny1, nx2, ny2);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_dir = dir;\n                        best_amt = amt;\n                    }\n                }\n            }\n            \n            if (best_dir == -1) break;\n            \n            if (best_dir == 0) x1 = max(0, x1 - best_amt);\n            else if (best_dir == 1) x2 = min(100000, x2 + best_amt);\n            else if (best_dir == 2) y1 = max(0, y1 - best_amt);\n            else y2 = min(100000, y2 + best_amt);\n            \n            current_score = best_score;\n        }\n        \n        if (current_score > bestScore) {\n            bestScore = current_score;\n            bx1 = x1; by1 = y1; bx2 = x2; by2 = y2;\n        }\n    }\n}\n\nint main() {\n    cin >> N;\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        mackerels.push_back({x, y});\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n        sardines.push_back({x, y});\n    }\n    \n    int bestScore = 0;\n    int bx1 = 0, by1 = 0, bx2 = 100000, by2 = 100000;\n    \n    mt19937 rng(20240515);\n    uniform_int_distribution<int> dist(0, N-1);\n    \n    // Phase 1: Density-based search\n    densitySearch(bestScore, bx1, by1, bx2, by2);\n    \n    // Phase 2: Enhanced greedy expansion\n    greedyExpand(bestScore, bx1, by1, bx2, by2, rng);\n    \n    // Phase 3: Multi-scale centered rectangles\n    vector<int> scales = {500, 1000, 1800, 2800, 4000, 5500, 7500, 10000, 13000, 17000, 21500, 27000, 33000};\n    for (int iter = 0; iter < 420; iter++) {\n        auto [cx, cy] = mackerels[dist(rng)];\n        \n        for (int sz : scales) {\n            tryUpdate(max(0, cx - sz), max(0, cy - sz), \n                     min(100000, cx + sz), min(100000, cy + sz),\n                     bestScore, bx1, by1, bx2, by2);\n        }\n    }\n    \n    // Phase 4: Pair-based rectangles\n    for (int iter = 0; iter < 1050; iter++) {\n        int i = dist(rng);\n        int j = dist(rng);\n        \n        tryUpdate(mackerels[i].first, mackerels[i].second, \n                 mackerels[j].first, mackerels[j].second,\n                 bestScore, bx1, by1, bx2, by2);\n    }\n    \n    // Phase 5: Bounding boxes of subsets\n    uniform_int_distribution<int> subset_size(3, 250);\n    for (int iter = 0; iter < 320; iter++) {\n        int k = subset_size(rng);\n        int minX = 100000, maxX = 0, minY = 100000, maxY = 0;\n        \n        for (int j = 0; j < k; j++) {\n            auto [x, y] = mackerels[dist(rng)];\n            minX = min(minX, x);\n            maxX = max(maxX, x);\n            minY = min(minY, y);\n            maxY = max(maxY, y);\n        }\n        \n        for (int margin : {-10000, -7000, -4500, -2500, -1000, -300, 0, 300, 1000, 2500, 4500, 7000, 10000}) {\n            tryUpdate(max(0, minX + margin), max(0, minY + margin),\n                     min(100000, maxX - margin), min(100000, maxY - margin),\n                     bestScore, bx1, by1, bx2, by2);\n        }\n    }\n    \n    // Phase 6: Asymmetric rectangles\n    uniform_int_distribution<int> size_dist(200, 35000);\n    for (int iter = 0; iter < 370; iter++) {\n        auto [cx, cy] = mackerels[dist(rng)];\n        \n        tryUpdate(max(0, cx - size_dist(rng)), max(0, cy - size_dist(rng)),\n                 min(100000, cx + size_dist(rng)), min(100000, cy + size_dist(rng)),\n                 bestScore, bx1, by1, bx2, by2);\n    }\n    \n    // Phase 7: Multi-start simulated annealing (3 restarts - proven sweet spot)\n    multiStartSA(bx1, by1, bx2, by2, bestScore, rng);\n    \n    // Phase 8: Final fine-grained local search\n    fineLocalSearch(bx1, by1, bx2, by2, bestScore);\n    \n    if (bx1 > bx2) swap(bx1, bx2);\n    if (by1 > by2) swap(by1, by2);\n    \n    cout << 4 << endl;\n    cout << bx1 << \" \" << by1 << endl;\n    cout << bx2 << \" \" << by1 << endl;\n    cout << bx2 << \" \" << by2 << endl;\n    cout << bx1 << \" \" << by2 << endl;\n    \n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, T;\n    long long sigma;\n    cin >> N >> T >> sigma;\n    \n    vector<pair<long long, long long>> rects(N);\n    long long total_area = 0;\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].first >> rects[i].second;\n        total_area += rects[i].first * rects[i].second;\n    }\n    \n    long long target_dim = (long long)sqrt(total_area);\n    \n    mt19937 rng(42);\n    \n    for (int turn = 0; turn < T; turn++) {\n        cout << N << endl;\n        \n        long long est_w = 0, est_h = 0;\n        \n        for (int i = 0; i < N; i++) {\n            long long w = rects[i].first;\n            long long h = rects[i].second;\n            \n            int r = 0;\n            char d;\n            int b;\n            \n            if (i == 0) {\n                r = (h > w) ? 1 : 0;\n                if (r) swap(w, h);\n                d = 'U';\n                b = -1;\n                est_w = w;\n                est_h = h;\n            } else {\n                int strategy = turn % 24;\n                \n                switch (strategy) {\n                    case 0: // Horizontal strip\n                        r = (h > w) ? 1 : 0;\n                        if (r) swap(w, h);\n                        d = 'U';\n                        b = i - 1;\n                        est_w += w;\n                        est_h = max(est_h, h);\n                        break;\n                        \n                    case 1: // Vertical strip\n                        r = (w > h) ? 1 : 0;\n                        if (r) swap(w, h);\n                        d = 'L';\n                        b = -1;\n                        est_h += h;\n                        est_w = max(est_w, w);\n                        break;\n                        \n                    case 2: // Balanced (W \u2248 H)\n                        if (est_w < est_h) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 3: // Grid (every 3)\n                        if (i % 3 == 1) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = (i >= 2) ? i - 2 : -1;\n                        }\n                        break;\n                        \n                    case 4: // Alternating (every 2)\n                        if (i % 2 == 1) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                        }\n                        break;\n                        \n                    // Area-based strategies (10 variations)\n                    case 5: // 0.7x\n                        if (est_w < target_dim * 0.7 && est_w <= est_h) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 6: // 0.8x\n                        if (est_w < target_dim * 0.8 && est_w <= est_h) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 7: // 0.9x\n                        if (est_w < target_dim * 0.9 && est_w <= est_h) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 8: // 1.0x\n                        if (est_w < target_dim && est_w <= est_h) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 9: // 1.1x\n                        if (est_w < target_dim * 1.1 && est_w <= est_h) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 10: // 1.2x\n                        if (est_w < target_dim * 1.2 && est_w <= est_h) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 11: // 1.3x\n                        if (est_w < target_dim * 1.3 && est_w <= est_h) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 12: // 1.4x\n                        if (est_w < target_dim * 1.4 && est_w <= est_h) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 13: // 1.5x\n                        if (est_w < target_dim * 1.5 && est_w <= est_h) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    case 14: // 0.75x\n                        if (est_w < target_dim * 0.75 && est_w <= est_h) {\n                            r = (h > w) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'U';\n                            b = i - 1;\n                            est_w += w;\n                            est_h = max(est_h, h);\n                        } else {\n                            r = (w > h) ? 1 : 0;\n                            if (r) swap(w, h);\n                            d = 'L';\n                            b = -1;\n                            est_h += h;\n                            est_w = max(est_w, w);\n                        }\n                        break;\n                        \n                    // Sqrt-grid strategies (9 variations)\n                    case 15: // 0.6x\n                        {\n                            int cols = max(2, (int)(sqrt(N) * 0.6));\n                            if (i % cols == 0 && i > 0) {\n                                r = (w > h) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'L';\n                                b = (i >= cols) ? i - cols : -1;\n                            } else {\n                                r = (h > w) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'U';\n                                b = (i > 0) ? i - 1 : -1;\n                            }\n                        }\n                        break;\n                        \n                    case 16: // 0.75x\n                        {\n                            int cols = max(2, (int)(sqrt(N) * 0.75));\n                            if (i % cols == 0 && i > 0) {\n                                r = (w > h) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'L';\n                                b = (i >= cols) ? i - cols : -1;\n                            } else {\n                                r = (h > w) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'U';\n                                b = (i > 0) ? i - 1 : -1;\n                            }\n                        }\n                        break;\n                        \n                    case 17: // 0.9x\n                        {\n                            int cols = max(2, (int)(sqrt(N) * 0.9));\n                            if (i % cols == 0 && i > 0) {\n                                r = (w > h) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'L';\n                                b = (i >= cols) ? i - cols : -1;\n                            } else {\n                                r = (h > w) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'U';\n                                b = (i > 0) ? i - 1 : -1;\n                            }\n                        }\n                        break;\n                        \n                    case 18: // 1.0x\n                        {\n                            int cols = max(2, (int)sqrt(N));\n                            if (i % cols == 0 && i > 0) {\n                                r = (w > h) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'L';\n                                b = (i >= cols) ? i - cols : -1;\n                            } else {\n                                r = (h > w) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'U';\n                                b = (i > 0) ? i - 1 : -1;\n                            }\n                        }\n                        break;\n                        \n                    case 19: // 1.1x\n                        {\n                            int cols = max(2, (int)(sqrt(N) * 1.1));\n                            if (i % cols == 0 && i > 0) {\n                                r = (w > h) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'L';\n                                b = (i >= cols) ? i - cols : -1;\n                            } else {\n                                r = (h > w) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'U';\n                                b = (i > 0) ? i - 1 : -1;\n                            }\n                        }\n                        break;\n                        \n                    case 20: // 1.25x\n                        {\n                            int cols = max(2, (int)(sqrt(N) * 1.25));\n                            if (i % cols == 0 && i > 0) {\n                                r = (w > h) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'L';\n                                b = (i >= cols) ? i - cols : -1;\n                            } else {\n                                r = (h > w) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'U';\n                                b = (i > 0) ? i - 1 : -1;\n                            }\n                        }\n                        break;\n                        \n                    case 21: // 1.4x\n                        {\n                            int cols = max(2, (int)(sqrt(N) * 1.4));\n                            if (i % cols == 0 && i > 0) {\n                                r = (w > h) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'L';\n                                b = (i >= cols) ? i - cols : -1;\n                            } else {\n                                r = (h > w) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'U';\n                                b = (i > 0) ? i - 1 : -1;\n                            }\n                        }\n                        break;\n                        \n                    case 22: // 1.6x\n                        {\n                            int cols = max(2, (int)(sqrt(N) * 1.6));\n                            if (i % cols == 0 && i > 0) {\n                                r = (w > h) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'L';\n                                b = (i >= cols) ? i - cols : -1;\n                            } else {\n                                r = (h > w) ? 1 : 0;\n                                if (r) swap(w, h);\n                                d = 'U';\n                                b = (i > 0) ? i - 1 : -1;\n                            }\n                        }\n                        break;\n                        \n                    default: // Random\n                        r = uniform_int_distribution<>(0, 1)(rng);\n                        if (r) swap(w, h);\n                        d = (uniform_int_distribution<>(0, 1)(rng) ? 'U' : 'L');\n                        b = uniform_int_distribution<>(-1, i - 1)(rng);\n                        break;\n                }\n            }\n            \n            cout << i << \" \" << r << \" \" << d << \" \" << b << endl;\n        }\n        cout.flush();\n        \n        long long W, H;\n        cin >> W >> H;\n    }\n    \n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <queue>\n#include <set>\n\nusing namespace std;\n\nint N, M, H;\nvector<int> A;\nvector<vector<int>> adj;\nvector<int> parent;\nvector<bool> assigned;\n\nvoid dfs(int u, int depth) {\n    if (depth >= H) return;\n    \n    vector<int> neighbors;\n    for (int v : adj[u]) {\n        if (!assigned[v]) {\n            neighbors.push_back(v);\n        }\n    }\n    \n    // Enhanced lookahead with up to 4 levels\n    sort(neighbors.begin(), neighbors.end(), [&](int a, int b) {\n        double score_a = A[a];\n        double score_b = A[b];\n        \n        // Aggressive adaptive lookahead weight\n        double lookahead_weight = 0.3 + 0.4 * (H - depth) / (double)H;\n        \n        // 1-step lookahead\n        set<int> visited_a, visited_b;\n        visited_a.insert(u);\n        visited_a.insert(a);\n        visited_b.insert(u);\n        visited_b.insert(b);\n        \n        for (int x : adj[a]) {\n            if (!assigned[x] && x != u) {\n                score_a += A[x] * lookahead_weight;\n                visited_a.insert(x);\n                \n                // 2-step lookahead\n                for (int y : adj[x]) {\n                    if (!assigned[y] && visited_a.find(y) == visited_a.end()) {\n                        score_a += A[y] * lookahead_weight * 0.35;\n                        visited_a.insert(y);\n                        \n                        // 3-step lookahead\n                        if (depth < H - 2) {\n                            for (int z : adj[y]) {\n                                if (!assigned[z] && visited_a.find(z) == visited_a.end()) {\n                                    score_a += A[z] * lookahead_weight * 0.15;\n                                    \n                                    // 4-step lookahead (very light, only when lots of depth left)\n                                    if (depth < H - 3) {\n                                        for (int w : adj[z]) {\n                                            if (!assigned[w] && visited_a.find(w) == visited_a.end()) {\n                                                score_a += A[w] * lookahead_weight * 0.08;\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        for (int x : adj[b]) {\n            if (!assigned[x] && x != u) {\n                score_b += A[x] * lookahead_weight;\n                visited_b.insert(x);\n                \n                // 2-step lookahead\n                for (int y : adj[x]) {\n                    if (!assigned[y] && visited_b.find(y) == visited_b.end()) {\n                        score_b += A[y] * lookahead_weight * 0.35;\n                        visited_b.insert(y);\n                        \n                        // 3-step lookahead\n                        if (depth < H - 2) {\n                            for (int z : adj[y]) {\n                                if (!assigned[z] && visited_b.find(z) == visited_b.end()) {\n                                    score_b += A[z] * lookahead_weight * 0.15;\n                                    \n                                    // 4-step lookahead (very light, only when lots of depth left)\n                                    if (depth < H - 3) {\n                                        for (int w : adj[z]) {\n                                            if (!assigned[w] && visited_b.find(w) == visited_b.end()) {\n                                                score_b += A[w] * lookahead_weight * 0.08;\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        return score_a > score_b;\n    });\n    \n    for (int v : neighbors) {\n        if (!assigned[v]) {\n            assigned[v] = true;\n            parent[v] = u;\n            dfs(v, depth + 1);\n        }\n    }\n}\n\ndouble evaluate_root(int root) {\n    queue<pair<int, int>> q;\n    q.push({root, 0});\n    set<int> reachable;\n    reachable.insert(root);\n    \n    while (!q.empty()) {\n        auto [u, d] = q.front();\n        q.pop();\n        \n        if (d < H) {\n            for (int v : adj[u]) {\n                if (!assigned[v] && reachable.find(v) == reachable.end()) {\n                    reachable.insert(v);\n                    q.push({v, d + 1});\n                }\n            }\n        }\n    }\n    \n    double potential = 0;\n    for (int v : reachable) {\n        if (v != root) {\n            potential += A[v];\n        }\n    }\n    \n    return A[root] * 150.0 - potential;\n}\n\nint main() {\n    cin >> N >> M >> H;\n    \n    A.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> A[i];\n    }\n    \n    adj.resize(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    parent.resize(N, -1);\n    assigned.resize(N, false);\n    \n    while (true) {\n        int root = -1;\n        double best_score = 1e9;\n        \n        for (int i = 0; i < N; i++) {\n            if (!assigned[i]) {\n                double score = evaluate_root(i);\n                if (root == -1 || score < best_score) {\n                    root = i;\n                    best_score = score;\n                }\n            }\n        }\n        \n        if (root == -1) break;\n        \n        assigned[root] = true;\n        parent[root] = -1;\n        dfs(root, 0);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << parent[i];\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <tuple>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    vector<string> board(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    vector<pair<char, int>> moves;\n    vector<vector<bool>> removed(N, vector<bool>(N, false));\n    \n    vector<pair<int,int>> oni_positions;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 'x') {\n                oni_positions.push_back({i, j});\n            }\n        }\n    }\n    \n    auto can_remove_up = [&](int i, int j) {\n        for (int ii = 0; ii < i; ii++) {\n            if (board[ii][j] == 'o') return false;\n        }\n        return true;\n    };\n    \n    auto can_remove_down = [&](int i, int j) {\n        for (int ii = i + 1; ii < N; ii++) {\n            if (board[ii][j] == 'o') return false;\n        }\n        return true;\n    };\n    \n    auto can_remove_left = [&](int i, int j) {\n        for (int jj = 0; jj < j; jj++) {\n            if (board[i][jj] == 'o') return false;\n        }\n        return true;\n    };\n    \n    auto can_remove_right = [&](int i, int j) {\n        for (int jj = j + 1; jj < N; jj++) {\n            if (board[i][jj] == 'o') return false;\n        }\n        return true;\n    };\n    \n    auto count_safe_dirs = [&](int i, int j) {\n        int cnt = 0;\n        if (can_remove_up(i, j)) cnt++;\n        if (can_remove_down(i, j)) cnt++;\n        if (can_remove_left(i, j)) cnt++;\n        if (can_remove_right(i, j)) cnt++;\n        return cnt;\n    };\n    \n    auto get_min_cost = [&](int i, int j) {\n        int min_cost = 1e9;\n        if (can_remove_up(i, j)) min_cost = min(min_cost, i + 1);\n        if (can_remove_down(i, j)) min_cost = min(min_cost, N - i);\n        if (can_remove_left(i, j)) min_cost = min(min_cost, j + 1);\n        if (can_remove_right(i, j)) min_cost = min(min_cost, N - j);\n        return min_cost;\n    };\n    \n    // Score: (is_far_from_edge, min_constraint, -efficiency, cost)\n    using ScoreTuple = tuple<bool, int, double, int>;\n    \n    while (true) {\n        ScoreTuple best_score = {true, 5, -1e9, (int)1e9};\n        char best_dir = ' ';\n        int best_pos = -1;\n        vector<pair<int,int>> best_targets;\n        int best_cost = 0;\n        \n        // Try upward\n        for (int j = 0; j < N; j++) {\n            int max_dist = 0;\n            vector<pair<int,int>> targets;\n            int min_dirs = 5;\n            bool has_close = false;\n            \n            for (auto [i, jj] : oni_positions) {\n                if (jj == j && !removed[i][jj] && can_remove_up(i, jj)) {\n                    int dist_up = i + 1;\n                    int min_alt_cost = get_min_cost(i, jj);\n                    \n                    // Include in batch only if upward is reasonable compared to alternatives\n                    // or if this is the only safe direction\n                    if (dist_up <= min_alt_cost * 1.5 || count_safe_dirs(i, jj) == 1) {\n                        targets.push_back({i, jj});\n                        max_dist = max(max_dist, dist_up);\n                        min_dirs = min(min_dirs, count_safe_dirs(i, jj));\n                        if (dist_up <= 2) has_close = true;\n                    }\n                }\n            }\n            \n            if (!targets.empty()) {\n                int cost = 2 * max_dist;\n                double efficiency = (double)targets.size() / cost;\n                bool far = (max_dist > 2);\n                ScoreTuple score = {far, min_dirs, -efficiency, cost};\n                if (score < best_score) {\n                    best_score = score;\n                    best_dir = 'U';\n                    best_pos = j;\n                    best_targets = targets;\n                    best_cost = cost;\n                }\n            }\n        }\n        \n        // Try downward\n        for (int j = 0; j < N; j++) {\n            int max_dist = 0;\n            vector<pair<int,int>> targets;\n            int min_dirs = 5;\n            bool has_close = false;\n            \n            for (auto [i, jj] : oni_positions) {\n                if (jj == j && !removed[i][jj] && can_remove_down(i, jj)) {\n                    int dist_down = N - i;\n                    int min_alt_cost = get_min_cost(i, jj);\n                    \n                    if (dist_down <= min_alt_cost * 1.5 || count_safe_dirs(i, jj) == 1) {\n                        targets.push_back({i, jj});\n                        max_dist = max(max_dist, dist_down);\n                        min_dirs = min(min_dirs, count_safe_dirs(i, jj));\n                        if (dist_down <= 2) has_close = true;\n                    }\n                }\n            }\n            \n            if (!targets.empty()) {\n                int cost = 2 * max_dist;\n                double efficiency = (double)targets.size() / cost;\n                bool far = (max_dist > 2);\n                ScoreTuple score = {far, min_dirs, -efficiency, cost};\n                if (score < best_score) {\n                    best_score = score;\n                    best_dir = 'D';\n                    best_pos = j;\n                    best_targets = targets;\n                    best_cost = cost;\n                }\n            }\n        }\n        \n        // Try leftward\n        for (int i = 0; i < N; i++) {\n            int max_dist = 0;\n            vector<pair<int,int>> targets;\n            int min_dirs = 5;\n            bool has_close = false;\n            \n            for (auto [ii, j] : oni_positions) {\n                if (ii == i && !removed[ii][j] && can_remove_left(ii, j)) {\n                    int dist_left = j + 1;\n                    int min_alt_cost = get_min_cost(ii, j);\n                    \n                    if (dist_left <= min_alt_cost * 1.5 || count_safe_dirs(ii, j) == 1) {\n                        targets.push_back({ii, j});\n                        max_dist = max(max_dist, dist_left);\n                        min_dirs = min(min_dirs, count_safe_dirs(ii, j));\n                        if (dist_left <= 2) has_close = true;\n                    }\n                }\n            }\n            \n            if (!targets.empty()) {\n                int cost = 2 * max_dist;\n                double efficiency = (double)targets.size() / cost;\n                bool far = (max_dist > 2);\n                ScoreTuple score = {far, min_dirs, -efficiency, cost};\n                if (score < best_score) {\n                    best_score = score;\n                    best_dir = 'L';\n                    best_pos = i;\n                    best_targets = targets;\n                    best_cost = cost;\n                }\n            }\n        }\n        \n        // Try rightward\n        for (int i = 0; i < N; i++) {\n            int max_dist = 0;\n            vector<pair<int,int>> targets;\n            int min_dirs = 5;\n            bool has_close = false;\n            \n            for (auto [ii, j] : oni_positions) {\n                if (ii == i && !removed[ii][j] && can_remove_right(ii, j)) {\n                    int dist_right = N - j;\n                    int min_alt_cost = get_min_cost(ii, j);\n                    \n                    if (dist_right <= min_alt_cost * 1.5 || count_safe_dirs(ii, j) == 1) {\n                        targets.push_back({ii, j});\n                        max_dist = max(max_dist, dist_right);\n                        min_dirs = min(min_dirs, count_safe_dirs(ii, j));\n                        if (dist_right <= 2) has_close = true;\n                    }\n                }\n            }\n            \n            if (!targets.empty()) {\n                int cost = 2 * max_dist;\n                double efficiency = (double)targets.size() / cost;\n                bool far = (max_dist > 2);\n                ScoreTuple score = {far, min_dirs, -efficiency, cost};\n                if (score < best_score) {\n                    best_score = score;\n                    best_dir = 'R';\n                    best_pos = i;\n                    best_targets = targets;\n                    best_cost = cost;\n                }\n            }\n        }\n        \n        if (best_targets.empty()) break;\n        \n        int dist = best_cost / 2;\n        for (int t = 0; t < dist; t++) {\n            moves.push_back({best_dir, best_pos});\n        }\n        char reverse = (best_dir == 'U') ? 'D' : (best_dir == 'D') ? 'U' : (best_dir == 'L') ? 'R' : 'L';\n        for (int t = 0; t < dist; t++) {\n            moves.push_back({reverse, best_pos});\n        }\n        \n        for (auto [i, j] : best_targets) {\n            removed[i][j] = true;\n        }\n    }\n    \n    for (auto [dir, pos] : moves) {\n        cout << dir << \" \" << pos << endl;\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, L;\nvector<int> T;\n\nlong long simulate(const vector<int>& a, const vector<int>& b, vector<int>& count) {\n    count.assign(N, 0);\n    int current = 0;\n    count[0] = 1;\n    \n    for (int week = 1; week < L; week++) {\n        int t = count[current];\n        if (t & 1) {\n            current = a[current];\n        } else {\n            current = b[current];\n        }\n        count[current]++;\n    }\n    \n    long long error = 0;\n    for (int i = 0; i < N; i++) {\n        error += abs(count[i] - T[i]);\n    }\n    return error;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> L;\n    T.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    mt19937 gen(12345);\n    uniform_int_distribution<> dist_n(0, N-1);\n    \n    vector<double> weights(N);\n    for (int i = 0; i < N; i++) {\n        weights[i] = T[i] + 1.0;\n    }\n    discrete_distribution<> weighted_dist(weights.begin(), weights.end());\n    \n    vector<int> best_a(N), best_b(N);\n    long long best_error = LLONG_MAX;\n    vector<int> count(N);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    double time_limit = 1.97;  // Increased from 1.96, very close to limit\n    \n    while (true) {\n        auto current_time = chrono::high_resolution_clock::now();\n        double elapsed = chrono::duration<double>(current_time - start_time).count();\n        if (elapsed > time_limit) break;\n        \n        // Initialize with weighted distribution\n        vector<int> a(N), b(N);\n        for (int i = 0; i < N; i++) {\n            a[i] = weighted_dist(gen);\n            b[i] = weighted_dist(gen);\n        }\n        \n        long long error = simulate(a, b, count);\n        \n        if (error < best_error) {\n            best_error = error;\n            best_a = a;\n            best_b = b;\n        }\n        \n        // Hill climbing\n        int no_improve = 0;\n        int patience = 6000;  // Increased from 5500\n        \n        while (no_improve < patience) {\n            current_time = chrono::high_resolution_clock::now();\n            elapsed = chrono::duration<double>(current_time - start_time).count();\n            if (elapsed > time_limit) break;\n            \n            int strategy = gen() % 4;\n            \n            int i, new_val;\n            bool modify_a = gen() % 2;\n            int old_val;\n            \n            if (strategy == 0) {\n                // Weighted random (25%)\n                i = dist_n(gen);\n                new_val = weighted_dist(gen);\n            } else if (strategy == 1) {\n                // Over to under (25%)\n                int max_over = -1, max_over_diff = 0;\n                int max_under = -1, max_under_diff = 0;\n                \n                for (int j = 0; j < N; j++) {\n                    if (count[j] > T[j] && count[j] - T[j] > max_over_diff) {\n                        max_over_diff = count[j] - T[j];\n                        max_over = j;\n                    }\n                    if (T[j] > count[j] && T[j] - count[j] > max_under_diff) {\n                        max_under_diff = T[j] - count[j];\n                        max_under = j;\n                    }\n                }\n                \n                if (max_over >= 0 && max_under >= 0) {\n                    i = max_over;\n                    new_val = max_under;\n                } else {\n                    i = dist_n(gen);\n                    new_val = weighted_dist(gen);\n                }\n            } else if (strategy == 2) {\n                // Random to under (25%)\n                i = dist_n(gen);\n                int max_under = -1, max_under_diff = 0;\n                for (int j = 0; j < N; j++) {\n                    if (T[j] > count[j] && T[j] - count[j] > max_under_diff) {\n                        max_under_diff = T[j] - count[j];\n                        max_under = j;\n                    }\n                }\n                new_val = (max_under >= 0) ? max_under : weighted_dist(gen);\n            } else {\n                // Uniform random (25%)\n                i = dist_n(gen);\n                new_val = dist_n(gen);\n            }\n            \n            old_val = modify_a ? a[i] : b[i];\n            \n            if (modify_a) {\n                a[i] = new_val;\n            } else {\n                b[i] = new_val;\n            }\n            \n            long long new_error = simulate(a, b, count);\n            \n            if (new_error < error) {\n                error = new_error;\n                no_improve = 0;\n                \n                if (error < best_error) {\n                    best_error = error;\n                    best_a = a;\n                    best_b = b;\n                }\n            } else {\n                if (modify_a) {\n                    a[i] = old_val;\n                } else {\n                    b[i] = old_val;\n                }\n                no_improve++;\n            }\n        }\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 <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <queue>\n\nusing namespace std;\n\nclass UnionFind {\n    vector<int> parent, rank_;\npublic:\n    UnionFind(int n) : parent(n), rank_(n, 0) {\n        for (int i = 0; i < n; i++) parent[i] = i;\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        if (rank_[px] < rank_[py]) swap(px, py);\n        parent[py] = px;\n        if (rank_[px] == rank_[py]) rank_[px]++;\n        return true;\n    }\n    \n    bool connected(int x, int y) {\n        return find(x) == find(y);\n    }\n};\n\nstruct Rect {\n    int lx, rx, ly, ry;\n    double cx, cy;\n};\n\nlong long morton_code(int x, int y) {\n    long long z = 0;\n    for (int i = 0; i < 20; i++) {\n        z |= ((long long)((x >> i) & 1) << (2 * i + 1));\n        z |= ((long long)((y >> i) & 1) << (2 * i));\n    }\n    return z;\n}\n\ndouble dist_sq(double x1, double y1, double x2, double y2) {\n    double dx = x1 - x2, dy = y1 - y2;\n    return dx * dx + dy * dy;\n}\n\ndouble min_dist_sq(const Rect& a, const Rect& b) {\n    double dx = max(0, max(a.lx - b.rx, b.lx - a.rx));\n    double dy = max(0, max(a.ly - b.ry, b.ly - a.ry));\n    return dx * dx + dy * dy;\n}\n\nvector<vector<int>> cluster_cities(int N, int M, vector<int>& G, vector<Rect>& rects) {\n    // Start with Z-order curve sorting (deterministic)\n    vector<int> order(N);\n    for (int i = 0; i < N; i++) order[i] = i;\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        int xa = (int)rects[a].cx, ya = (int)rects[a].cy;\n        int xb = (int)rects[b].cx, yb = (int)rects[b].cy;\n        return morton_code(xa, ya) < morton_code(xb, yb);\n    });\n    \n    // Initial grouping\n    vector<vector<int>> groups(M);\n    int idx = 0;\n    for (int i = 0; i < M; i++) {\n        for (int j = 0; j < G[i]; j++) {\n            groups[i].push_back(order[idx++]);\n        }\n    }\n    \n    // K-means refinement (deterministic initialization from above)\n    vector<pair<double, double>> centroids(M);\n    for (int i = 0; i < M; i++) {\n        double cx = 0, cy = 0;\n        for (int city : groups[i]) {\n            cx += rects[city].cx;\n            cy += rects[city].cy;\n        }\n        centroids[i] = {cx / groups[i].size(), cy / groups[i].size()};\n    }\n    \n    // K-means iterations\n    for (int iter = 0; iter < 10; iter++) {\n        vector<priority_queue<pair<double, int>>> candidates(M);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < M; j++) {\n                double d = dist_sq(rects[i].cx, rects[i].cy, centroids[j].first, centroids[j].second);\n                candidates[j].push({-d, i});\n            }\n        }\n        \n        for (int i = 0; i < M; i++) groups[i].clear();\n        vector<bool> assigned(N, false);\n        \n        for (int i = 0; i < M; i++) {\n            while ((int)groups[i].size() < G[i] && !candidates[i].empty()) {\n                int city = candidates[i].top().second;\n                candidates[i].pop();\n                if (!assigned[city]) {\n                    groups[i].push_back(city);\n                    assigned[city] = true;\n                }\n            }\n        }\n        \n        // Update centroids\n        for (int i = 0; i < M; i++) {\n            if (groups[i].empty()) continue;\n            double cx = 0, cy = 0;\n            for (int city : groups[i]) {\n                cx += rects[city].cx;\n                cy += rects[city].cy;\n            }\n            centroids[i] = {cx / groups[i].size(), cy / groups[i].size()};\n        }\n    }\n    \n    // Reorder within groups using nearest neighbor\n    for (int i = 0; i < M; i++) {\n        if (groups[i].size() <= 2) continue;\n        \n        vector<bool> used(groups[i].size(), false);\n        vector<int> ordered;\n        ordered.push_back(groups[i][0]);\n        used[0] = true;\n        \n        while ((int)ordered.size() < (int)groups[i].size()) {\n            int last = ordered.back();\n            int best_idx = -1;\n            double best_dist = 1e18;\n            \n            for (int j = 0; j < (int)groups[i].size(); j++) {\n                if (!used[j]) {\n                    double d = dist_sq(rects[last].cx, rects[last].cy, \n                                     rects[groups[i][j]].cx, rects[groups[i][j]].cy);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best_idx = j;\n                    }\n                }\n            }\n            \n            ordered.push_back(groups[i][best_idx]);\n            used[best_idx] = true;\n        }\n        \n        groups[i] = ordered;\n    }\n    \n    return groups;\n}\n\nint main() {\n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<Rect> rects(N);\n    for (int i = 0; i < N; i++) {\n        cin >> rects[i].lx >> rects[i].rx >> rects[i].ly >> rects[i].ry;\n        rects[i].cx = (rects[i].lx + rects[i].rx) / 2.0;\n        rects[i].cy = (rects[i].ly + rects[i].ry) / 2.0;\n    }\n    \n    auto groups = cluster_cities(N, M, G, rects);\n    \n    // Smart query allocation\n    vector<int> queries_per_group(M, 0);\n    int budget = Q;\n    \n    // Allocate to groups <= L\n    for (int i = 0; i < M; i++) {\n        if (G[i] >= 2 && G[i] <= L && budget > 0) {\n            queries_per_group[i] = 1;\n            budget--;\n        }\n    }\n    \n    // Allocate to large groups proportionally\n    int total_large = 0;\n    for (int i = 0; i < M; i++) {\n        if (G[i] > L) total_large += G[i];\n    }\n    \n    for (int i = 0; i < M && budget > 0; i++) {\n        if (G[i] > L) {\n            int base_queries = (G[i] + L - 2) / (L - 1);\n            int allocated = min(base_queries, budget);\n            queries_per_group[i] = allocated;\n            budget -= allocated;\n        }\n    }\n    \n    vector<vector<pair<int, int>>> edges(M);\n    \n    for (int k = 0; k < M; k++) {\n        if (G[k] == 1) continue;\n        \n        set<pair<int, int>> candidate_edges;\n        \n        if (G[k] <= L && queries_per_group[k] > 0) {\n            cout << \"? \" << G[k];\n            for (int c : groups[k]) cout << \" \" << c;\n            cout << endl;\n            cout.flush();\n            \n            for (int i = 0; i < G[k] - 1; i++) {\n                int u, v;\n                cin >> u >> v;\n                if (u > v) swap(u, v);\n                candidate_edges.insert({u, v});\n            }\n        } else if (queries_per_group[k] > 0) {\n            // Sliding window with overlap\n            int num_queries = queries_per_group[k];\n            int step = max(1, (G[k] - L + num_queries) / num_queries);\n            \n            for (int q = 0; q < num_queries; q++) {\n                int start = q * step;\n                if (start >= G[k]) break;\n                int end = min(start + L, G[k]);\n                start = max(0, end - L);\n                int sz = end - start;\n                \n                if (sz < 2) continue;\n                \n                cout << \"? \" << sz;\n                for (int j = start; j < end; j++) {\n                    cout << \" \" << groups[k][j];\n                }\n                cout << endl;\n                cout.flush();\n                \n                for (int j = 0; j < sz - 1; j++) {\n                    int u, v;\n                    cin >> u >> v;\n                    if (u > v) swap(u, v);\n                    candidate_edges.insert({u, v});\n                }\n            }\n        }\n        \n        // Build MST from candidates\n        UnionFind uf(N);\n        for (auto [u, v] : candidate_edges) {\n            if (uf.unite(u, v)) {\n                edges[k].push_back({u, v});\n            }\n        }\n        \n        // Smart fallback with minimum distance estimation\n        if ((int)edges[k].size() < G[k] - 1) {\n            vector<pair<double, pair<int, int>>> fallback;\n            \n            for (int i = 0; i < G[k]; i++) {\n                for (int j = i + 1; j < G[k]; j++) {\n                    int u = groups[k][i], v = groups[k][j];\n                    if (!uf.connected(u, v)) {\n                        double d = min_dist_sq(rects[u], rects[v]);\n                        fallback.push_back({d, {u, v}});\n                    }\n                }\n            }\n            \n            sort(fallback.begin(), fallback.end());\n            \n            for (auto [d, edge] : fallback) {\n                if ((int)edges[k].size() >= G[k] - 1) break;\n                auto [u, v] = edge;\n                if (uf.unite(u, v)) {\n                    edges[k].push_back({u, v});\n                }\n            }\n        }\n    }\n    \n    cout << \"!\" << endl;\n    for (int k = 0; k < M; k++) {\n        for (int c : groups[k]) cout << c << \" \";\n        cout << endl;\n        for (auto [u, v] : edges[k]) {\n            cout << u << \" \" << v << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\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    int cur_r = targets[0].first;\n    int cur_c = targets[0].second;\n    \n    vector<pair<string, string>> actions;\n    \n    auto add = [&](string act, string dir) {\n        actions.push_back({act, dir});\n    };\n    \n    // Visit each target in order\n    for (int i = 1; i < M; i++) {\n        int target_r = targets[i].first;\n        int target_c = targets[i].second;\n        \n        // Move vertically with edge slide optimization\n        if (cur_r != target_r) {\n            int move_cost = abs(target_r - cur_r);\n            int slide_cost = INT_MAX;\n            \n            if (target_r > cur_r) {\n                // Moving down: try sliding to bottom edge\n                int edge = N - 1;\n                slide_cost = 1 + (edge - target_r);\n            } else {\n                // Moving up: try sliding to top edge\n                int edge = 0;\n                slide_cost = 1 + (target_r - edge);\n            }\n            \n            if (slide_cost < move_cost) {\n                // Use slide to edge\n                if (target_r > cur_r) {\n                    add(\"S\", \"D\");\n                    cur_r = N - 1;\n                } else {\n                    add(\"S\", \"U\");\n                    cur_r = 0;\n                }\n            }\n            \n            // Move remaining distance\n            while (cur_r != target_r) {\n                if (cur_r < target_r) {\n                    add(\"M\", \"D\");\n                    cur_r++;\n                } else {\n                    add(\"M\", \"U\");\n                    cur_r--;\n                }\n            }\n        }\n        \n        // Move horizontally with edge slide optimization\n        if (cur_c != target_c) {\n            int move_cost = abs(target_c - cur_c);\n            int slide_cost = INT_MAX;\n            \n            if (target_c > cur_c) {\n                // Moving right: try sliding to right edge\n                int edge = N - 1;\n                slide_cost = 1 + (edge - target_c);\n            } else {\n                // Moving left: try sliding to left edge\n                int edge = 0;\n                slide_cost = 1 + (target_c - edge);\n            }\n            \n            if (slide_cost < move_cost) {\n                // Use slide to edge\n                if (target_c > cur_c) {\n                    add(\"S\", \"R\");\n                    cur_c = N - 1;\n                } else {\n                    add(\"S\", \"L\");\n                    cur_c = 0;\n                }\n            }\n            \n            // Move remaining distance\n            while (cur_c != target_c) {\n                if (cur_c < target_c) {\n                    add(\"M\", \"R\");\n                    cur_c++;\n                } else {\n                    add(\"M\", \"L\");\n                    cur_c--;\n                }\n            }\n        }\n    }\n    \n    for (auto& [act, dir] : actions) {\n        cout << act << \" \" << dir << \"\\n\";\n    }\n    \n    return 0;\n}"}}}